From d56b453891fdbd5bd2a68a8aaa438ec3ccb687b9 Mon Sep 17 00:00:00 2001 From: libretroadmin Date: Thu, 8 Oct 2026 13:09:58 +0200 Subject: [PATCH] Replace zlib, zstd, libchdr, libzip and libpng with libretro-common Deflate, zlib and gzip streams go through rinflate and rdeflate, zstd through rzstd, CHD images through rchd, zip archives through rzip_archive and PNG through rpng. The bundled libraries, their build glue and the system-library options are gone; adler32 and uncompress keep zlib's ABI for the prebuilt FFmpeg archives that still call them. libretro-common is one CMake library that the core, the headless tool and the unit tests all link. The reads take shorter paths on the way. CHD decodes straight from the loader's reads and a range of blocks at a time, and a file read at any alignment decodes into place; CSO keeps one inflate stream instead of one per block; a plain ISO serves a file read with one read of its exact bytes; a stored zip member is read in place and a deflated one through restart points rather than a copy of the whole image in memory; zip members decode into the caller's buffer; sequential reads through the frontend's VFS skip the seek, which also keeps its buffering. libretro/test reads one image as ISO, CSO, CHD and zip through the block devices, boots each, and checks the codecs against Python-made vectors; a CI job runs it. --- .github/workflows/build.yml | 30 + .gitmodules | 6 - CMakeLists.txt | 310 +- Common/CMakeLists.txt | 14 +- Common/Data/Encoding/Compression.cpp | 179 +- Common/Data/Encoding/Compression.h | 23 +- Common/Data/Format/PNGLoad.cpp | 255 +- Common/Data/Format/PNGLoad.h | 10 + Common/Data/Format/ZIMLoad.cpp | 54 +- Common/Data/Format/ZIMSave.cpp | 61 +- Common/File/VFS/ZipFileReader.cpp | 463 +- Common/File/VFS/ZipFileReader.h | 62 +- Common/Render/AtlasGen.cpp | 1 - Common/Render/TextureAtlas.cpp | 6 +- Common/Serialize/Serializer.cpp | 25 +- Core/CMakeLists.txt | 8 +- Core/Debugger/SymbolMap.cpp | 118 +- .../WebSocket/GPUBufferSubscriber.cpp | 90 +- Core/FileLoaders/LocalFileLoader.cpp | 14 +- Core/FileLoaders/LocalFileLoader.h | 1 + Core/FileLoaders/ZipFileLoader.cpp | 196 +- Core/FileLoaders/ZipFileLoader.h | 36 +- Core/FileSystems/BlockDevices.cpp | 342 +- Core/FileSystems/BlockDevices.h | 20 +- Core/FileSystems/ISOFileSystem.cpp | 59 +- Core/HLE/sceAdler.cpp | 8 +- Core/HLE/sceDeflt.cpp | 43 +- Core/HLE/sceKernelModule.cpp | 29 +- Core/HLE/scePauth.cpp | 1 - Core/Loaders.cpp | 61 +- Core/Loaders.h | 2 +- Core/Reporting.cpp | 6 +- Core/Screenshot.cpp | 25 +- Core/Util/GameManager.cpp | 177 +- Core/Util/GameManager.h | 12 +- Core/Util/PSARUnpack.cpp | 9 +- GPU/CMakeLists.txt | 18 +- GPU/Common/ReplacedTexture.cpp | 47 +- GPU/Common/TextureReplacer.cpp | 1 - GPU/Debugger/Playback.cpp | 6 +- GPU/Debugger/Record.cpp | 7 +- ext/CMakeLists.txt | 7 - ext/basis_universal/CMakeLists.txt | 9 +- ext/basis_universal/basisu_transcoder.cpp | 8 +- ext/libchdr | 1 - ext/libchdr-build/CMakeLists.txt | 36 - ext/libchdr.vcxproj | 314 - ext/libchdr.vcxproj.filters | 102 - ext/libpng17/CMakeLists.txt | 43 - ext/libpng17/arm/arm_init.c | 135 - ext/libpng17/arm/filter_neon.S | 253 - ext/libpng17/arm/filter_neon_intrinsics.c | 395 - ext/libpng17/arm/neon.h | 124 - ext/libpng17/png.c | 3782 ------- ext/libpng17/png.h | 4252 -------- ext/libpng17/pngchunk.h | 50 - ext/libpng17/pngconf.h | 632 -- ext/libpng17/pngdebug.h | 150 - ext/libpng17/pngerror.c | 1123 -- ext/libpng17/pngget.c | 1206 --- ext/libpng17/pnginfo.h | 251 - ext/libpng17/pnglibconf.h | 213 - ext/libpng17/pngmem.c | 269 - ext/libpng17/pngpread.c | 866 -- ext/libpng17/pngpriv.h | 2270 ---- ext/libpng17/pngread.c | 4185 -------- ext/libpng17/pngrio.c | 114 - ext/libpng17/pngrtran.c | 6823 ------------ ext/libpng17/pngrutil.c | 4792 --------- ext/libpng17/pngset.c | 1674 --- ext/libpng17/pngstruct.h | 777 -- ext/libpng17/pngtest.c | 2086 ---- ext/libpng17/pngtrans.c | 3760 ------- ext/libpng17/pngwio.c | 146 - ext/libpng17/pngwrite.c | 2193 ---- ext/libpng17/pngwtran.c | 148 - ext/libpng17/pngwutil.c | 5054 --------- ext/libzip/Android.mk | 136 - ext/libzip/CMakeLists.txt | 135 - ext/libzip/compat.h | 194 - ext/libzip/config.h | 65 - ext/libzip/libzip.la | 41 - ext/libzip/zip.h | 479 - ext/libzip/zip_add.c | 49 - ext/libzip/zip_add_dir.c | 44 - ext/libzip/zip_add_entry.c | 80 - ext/libzip/zip_algorithm_deflate.c | 250 - ext/libzip/zip_buffer.c | 324 - ext/libzip/zip_close.c | 703 -- ext/libzip/zip_delete.c | 68 - ext/libzip/zip_dir_add.c | 92 - ext/libzip/zip_dirent.c | 1163 -- ext/libzip/zip_discard.c | 80 - ext/libzip/zip_entry.c | 51 - ext/libzip/zip_err_str.c | 84 - ext/libzip/zip_error.c | 150 - ext/libzip/zip_error_clear.c | 44 - ext/libzip/zip_error_get.c | 54 - ext/libzip/zip_error_get_sys_type.c | 44 - ext/libzip/zip_error_strerror.c | 83 - ext/libzip/zip_error_to_str.c | 66 - ext/libzip/zip_extra_field.c | 426 - ext/libzip/zip_extra_field_api.c | 355 - ext/libzip/zip_fclose.c | 54 - ext/libzip/zip_fdopen.c | 86 - ext/libzip/zip_file_add.c | 52 - ext/libzip/zip_file_error_clear.c | 44 - ext/libzip/zip_file_error_get.c | 41 - ext/libzip/zip_file_get_comment.c | 55 - ext/libzip/zip_file_get_external_attributes.c | 50 - ext/libzip/zip_file_get_offset.c | 117 - ext/libzip/zip_file_rename.c | 67 - ext/libzip/zip_file_replace.c | 105 - ext/libzip/zip_file_set_comment.c | 101 - ext/libzip/zip_file_set_encryption.c | 116 - ext/libzip/zip_file_set_external_attributes.c | 82 - ext/libzip/zip_file_set_mtime.c | 68 - ext/libzip/zip_file_strerror.c | 41 - ext/libzip/zip_fopen.c | 46 - ext/libzip/zip_fopen_encrypted.c | 46 - ext/libzip/zip_fopen_index.c | 41 - ext/libzip/zip_fopen_index_encrypted.c | 83 - ext/libzip/zip_fread.c | 62 - ext/libzip/zip_fseek.c | 51 - ext/libzip/zip_ftell.c | 54 - ext/libzip/zip_get_archive_comment.c | 58 - ext/libzip/zip_get_archive_flag.c | 45 - .../zip_get_encryption_implementation.c | 62 - ext/libzip/zip_get_file_comment.c | 50 - ext/libzip/zip_get_name.c | 58 - ext/libzip/zip_get_num_entries.c | 52 - ext/libzip/zip_get_num_files.c | 51 - ext/libzip/zip_hash.c | 410 - ext/libzip/zip_io_util.c | 134 - ext/libzip/zip_libzip_version.c | 41 - ext/libzip/zip_memdup.c | 56 - ext/libzip/zip_mkstempm.c | 93 - ext/libzip/zip_name_locate.c | 92 - ext/libzip/zip_new.c | 73 - ext/libzip/zip_open.c | 849 -- ext/libzip/zip_pkware.c | 112 - ext/libzip/zip_progress.c | 293 - ext/libzip/zip_random_unix.c | 104 - ext/libzip/zip_random_uwp.c | 82 - ext/libzip/zip_random_win32.c | 81 - ext/libzip/zip_rename.c | 42 - ext/libzip/zip_replace.c | 42 - ext/libzip/zip_set_archive_comment.c | 80 - ext/libzip/zip_set_archive_flag.c | 65 - ext/libzip/zip_set_default_password.c | 58 - ext/libzip/zip_set_file_comment.c | 46 - ext/libzip/zip_set_file_compression.c | 91 - ext/libzip/zip_set_name.c | 157 - ext/libzip/zip_source_accept_empty.c | 52 - ext/libzip/zip_source_begin_write.c | 52 - ext/libzip/zip_source_begin_write_cloning.c | 52 - ext/libzip/zip_source_buffer.c | 620 -- ext/libzip/zip_source_call.c | 68 - ext/libzip/zip_source_close.c | 57 - ext/libzip/zip_source_commit_write.c | 63 - ext/libzip/zip_source_compress.c | 389 - ext/libzip/zip_source_crc.c | 197 - ext/libzip/zip_source_error.c | 46 - ext/libzip/zip_source_file.h | 90 - ext/libzip/zip_source_file_common.c | 378 - ext/libzip/zip_source_file_stdio.c | 208 - ext/libzip/zip_source_file_stdio.h | 47 - ext/libzip/zip_source_file_stdio_named.c | 313 - ext/libzip/zip_source_file_win32.c | 230 - ext/libzip/zip_source_file_win32.h | 83 - ext/libzip/zip_source_file_win32_ansi.c | 81 - ext/libzip/zip_source_file_win32_named.c | 266 - ext/libzip/zip_source_file_win32_utf16.c | 139 - ext/libzip/zip_source_file_win32_utf8.c | 74 - ext/libzip/zip_source_free.c | 71 - ext/libzip/zip_source_function.c | 97 - ext/libzip/zip_source_get_file_attributes.c | 104 - ext/libzip/zip_source_is_deleted.c | 41 - ext/libzip/zip_source_layered.c | 67 - ext/libzip/zip_source_open.c | 75 - ext/libzip/zip_source_pkware_decode.c | 221 - ext/libzip/zip_source_pkware_encode.c | 249 - ext/libzip/zip_source_read.c | 90 - ext/libzip/zip_source_remove.c | 60 - ext/libzip/zip_source_rollback_write.c | 46 - ext/libzip/zip_source_seek.c | 95 - ext/libzip/zip_source_seek_write.c | 51 - ext/libzip/zip_source_stat.c | 62 - ext/libzip/zip_source_supports.c | 65 - ext/libzip/zip_source_tell.c | 49 - ext/libzip/zip_source_tell_write.c | 46 - ext/libzip/zip_source_window.c | 294 - ext/libzip/zip_source_write.c | 46 - ext/libzip/zip_source_zip.c | 56 - ext/libzip/zip_source_zip_new.c | 191 - ext/libzip/zip_stat.c | 46 - ext/libzip/zip_stat_index.c | 80 - ext/libzip/zip_stat_init.c | 83 - ext/libzip/zip_strerror.c | 41 - ext/libzip/zip_string.c | 178 - ext/libzip/zip_unchange.c | 93 - ext/libzip/zip_unchange_all.c | 54 - ext/libzip/zip_unchange_archive.c | 51 - ext/libzip/zip_unchange_data.c | 53 - ext/libzip/zip_utf-8.c | 226 - ext/libzip/zipconf.h | 48 - ext/libzip/zipint.h | 601 -- ext/libzstd.vcxproj | 341 - ext/zlib/CMakeLists.txt | 218 - ext/zlib/LICENSE | 22 - ext/zlib/README | 117 - ext/zlib/adler32.c | 164 - ext/zlib/compress.c | 75 - ext/zlib/crc32.c | 1049 -- ext/zlib/crc32.h | 9446 ----------------- ext/zlib/deflate.c | 2139 ---- ext/zlib/deflate.h | 377 - ext/zlib/gzclose.c | 23 - ext/zlib/gzguts.h | 216 - ext/zlib/gzlib.c | 582 - ext/zlib/gzread.c | 602 -- ext/zlib/gzwrite.c | 631 -- ext/zlib/infback.c | 628 -- ext/zlib/inffast.c | 320 - ext/zlib/inffast.h | 11 - ext/zlib/inffixed.h | 94 - ext/zlib/inflate.c | 1526 --- ext/zlib/inflate.h | 126 - ext/zlib/inftrees.c | 299 - ext/zlib/inftrees.h | 62 - ext/zlib/trees.c | 1117 -- ext/zlib/trees.h | 128 - ext/zlib/uncompr.c | 85 - ext/zlib/zconf.h | 543 - ext/zlib/zlib.h | 1938 ---- ext/zlib/zlib.vcxproj | 281 - ext/zlib/zlib.vcxproj.filters | 33 - ext/zlib/zutil.c | 299 - ext/zlib/zutil.h | 254 - ext/zstd | 1 - ext/zstd-build/CMakeLists.txt | 51 - headless/Compare.cpp | 20 +- libretro/CMakeLists.txt | 22 - libretro/Makefile | 18 +- libretro/Makefile.common | 258 +- libretro/test/.gitignore | 4 + libretro/test/blocktest.cpp | 68 + libretro/test/codectest.cpp | 139 + libretro/test/lrtest.c | 282 + libretro/test/make_vectors.py | 121 + libretro/test/run.sh | 29 + unittest/TestZipSlip.cpp | 50 +- 252 files changed, 1751 insertions(+), 91370 deletions(-) delete mode 160000 ext/libchdr delete mode 100644 ext/libchdr-build/CMakeLists.txt delete mode 100644 ext/libchdr.vcxproj delete mode 100644 ext/libchdr.vcxproj.filters delete mode 100644 ext/libpng17/CMakeLists.txt delete mode 100644 ext/libpng17/arm/arm_init.c delete mode 100644 ext/libpng17/arm/filter_neon.S delete mode 100644 ext/libpng17/arm/filter_neon_intrinsics.c delete mode 100644 ext/libpng17/arm/neon.h delete mode 100644 ext/libpng17/png.c delete mode 100644 ext/libpng17/png.h delete mode 100644 ext/libpng17/pngchunk.h delete mode 100644 ext/libpng17/pngconf.h delete mode 100644 ext/libpng17/pngdebug.h delete mode 100644 ext/libpng17/pngerror.c delete mode 100644 ext/libpng17/pngget.c delete mode 100644 ext/libpng17/pnginfo.h delete mode 100644 ext/libpng17/pnglibconf.h delete mode 100644 ext/libpng17/pngmem.c delete mode 100644 ext/libpng17/pngpread.c delete mode 100644 ext/libpng17/pngpriv.h delete mode 100644 ext/libpng17/pngread.c delete mode 100644 ext/libpng17/pngrio.c delete mode 100644 ext/libpng17/pngrtran.c delete mode 100644 ext/libpng17/pngrutil.c delete mode 100644 ext/libpng17/pngset.c delete mode 100644 ext/libpng17/pngstruct.h delete mode 100644 ext/libpng17/pngtest.c delete mode 100644 ext/libpng17/pngtrans.c delete mode 100644 ext/libpng17/pngwio.c delete mode 100644 ext/libpng17/pngwrite.c delete mode 100644 ext/libpng17/pngwtran.c delete mode 100644 ext/libpng17/pngwutil.c delete mode 100644 ext/libzip/Android.mk delete mode 100644 ext/libzip/CMakeLists.txt delete mode 100644 ext/libzip/compat.h delete mode 100644 ext/libzip/config.h delete mode 100644 ext/libzip/libzip.la delete mode 100644 ext/libzip/zip.h delete mode 100644 ext/libzip/zip_add.c delete mode 100644 ext/libzip/zip_add_dir.c delete mode 100644 ext/libzip/zip_add_entry.c delete mode 100644 ext/libzip/zip_algorithm_deflate.c delete mode 100644 ext/libzip/zip_buffer.c delete mode 100644 ext/libzip/zip_close.c delete mode 100644 ext/libzip/zip_delete.c delete mode 100644 ext/libzip/zip_dir_add.c delete mode 100644 ext/libzip/zip_dirent.c delete mode 100644 ext/libzip/zip_discard.c delete mode 100644 ext/libzip/zip_entry.c delete mode 100644 ext/libzip/zip_err_str.c delete mode 100644 ext/libzip/zip_error.c delete mode 100644 ext/libzip/zip_error_clear.c delete mode 100644 ext/libzip/zip_error_get.c delete mode 100644 ext/libzip/zip_error_get_sys_type.c delete mode 100644 ext/libzip/zip_error_strerror.c delete mode 100644 ext/libzip/zip_error_to_str.c delete mode 100644 ext/libzip/zip_extra_field.c delete mode 100644 ext/libzip/zip_extra_field_api.c delete mode 100644 ext/libzip/zip_fclose.c delete mode 100644 ext/libzip/zip_fdopen.c delete mode 100644 ext/libzip/zip_file_add.c delete mode 100644 ext/libzip/zip_file_error_clear.c delete mode 100644 ext/libzip/zip_file_error_get.c delete mode 100644 ext/libzip/zip_file_get_comment.c delete mode 100644 ext/libzip/zip_file_get_external_attributes.c delete mode 100644 ext/libzip/zip_file_get_offset.c delete mode 100644 ext/libzip/zip_file_rename.c delete mode 100644 ext/libzip/zip_file_replace.c delete mode 100644 ext/libzip/zip_file_set_comment.c delete mode 100644 ext/libzip/zip_file_set_encryption.c delete mode 100644 ext/libzip/zip_file_set_external_attributes.c delete mode 100644 ext/libzip/zip_file_set_mtime.c delete mode 100644 ext/libzip/zip_file_strerror.c delete mode 100644 ext/libzip/zip_fopen.c delete mode 100644 ext/libzip/zip_fopen_encrypted.c delete mode 100644 ext/libzip/zip_fopen_index.c delete mode 100644 ext/libzip/zip_fopen_index_encrypted.c delete mode 100644 ext/libzip/zip_fread.c delete mode 100644 ext/libzip/zip_fseek.c delete mode 100644 ext/libzip/zip_ftell.c delete mode 100644 ext/libzip/zip_get_archive_comment.c delete mode 100644 ext/libzip/zip_get_archive_flag.c delete mode 100644 ext/libzip/zip_get_encryption_implementation.c delete mode 100644 ext/libzip/zip_get_file_comment.c delete mode 100644 ext/libzip/zip_get_name.c delete mode 100644 ext/libzip/zip_get_num_entries.c delete mode 100644 ext/libzip/zip_get_num_files.c delete mode 100644 ext/libzip/zip_hash.c delete mode 100644 ext/libzip/zip_io_util.c delete mode 100644 ext/libzip/zip_libzip_version.c delete mode 100644 ext/libzip/zip_memdup.c delete mode 100644 ext/libzip/zip_mkstempm.c delete mode 100644 ext/libzip/zip_name_locate.c delete mode 100644 ext/libzip/zip_new.c delete mode 100644 ext/libzip/zip_open.c delete mode 100644 ext/libzip/zip_pkware.c delete mode 100644 ext/libzip/zip_progress.c delete mode 100644 ext/libzip/zip_random_unix.c delete mode 100644 ext/libzip/zip_random_uwp.c delete mode 100644 ext/libzip/zip_random_win32.c delete mode 100644 ext/libzip/zip_rename.c delete mode 100644 ext/libzip/zip_replace.c delete mode 100644 ext/libzip/zip_set_archive_comment.c delete mode 100644 ext/libzip/zip_set_archive_flag.c delete mode 100644 ext/libzip/zip_set_default_password.c delete mode 100644 ext/libzip/zip_set_file_comment.c delete mode 100644 ext/libzip/zip_set_file_compression.c delete mode 100644 ext/libzip/zip_set_name.c delete mode 100644 ext/libzip/zip_source_accept_empty.c delete mode 100644 ext/libzip/zip_source_begin_write.c delete mode 100644 ext/libzip/zip_source_begin_write_cloning.c delete mode 100644 ext/libzip/zip_source_buffer.c delete mode 100644 ext/libzip/zip_source_call.c delete mode 100644 ext/libzip/zip_source_close.c delete mode 100644 ext/libzip/zip_source_commit_write.c delete mode 100644 ext/libzip/zip_source_compress.c delete mode 100644 ext/libzip/zip_source_crc.c delete mode 100644 ext/libzip/zip_source_error.c delete mode 100644 ext/libzip/zip_source_file.h delete mode 100644 ext/libzip/zip_source_file_common.c delete mode 100644 ext/libzip/zip_source_file_stdio.c delete mode 100644 ext/libzip/zip_source_file_stdio.h delete mode 100644 ext/libzip/zip_source_file_stdio_named.c delete mode 100644 ext/libzip/zip_source_file_win32.c delete mode 100644 ext/libzip/zip_source_file_win32.h delete mode 100644 ext/libzip/zip_source_file_win32_ansi.c delete mode 100644 ext/libzip/zip_source_file_win32_named.c delete mode 100644 ext/libzip/zip_source_file_win32_utf16.c delete mode 100644 ext/libzip/zip_source_file_win32_utf8.c delete mode 100644 ext/libzip/zip_source_free.c delete mode 100644 ext/libzip/zip_source_function.c delete mode 100644 ext/libzip/zip_source_get_file_attributes.c delete mode 100644 ext/libzip/zip_source_is_deleted.c delete mode 100644 ext/libzip/zip_source_layered.c delete mode 100644 ext/libzip/zip_source_open.c delete mode 100644 ext/libzip/zip_source_pkware_decode.c delete mode 100644 ext/libzip/zip_source_pkware_encode.c delete mode 100644 ext/libzip/zip_source_read.c delete mode 100644 ext/libzip/zip_source_remove.c delete mode 100644 ext/libzip/zip_source_rollback_write.c delete mode 100644 ext/libzip/zip_source_seek.c delete mode 100644 ext/libzip/zip_source_seek_write.c delete mode 100644 ext/libzip/zip_source_stat.c delete mode 100644 ext/libzip/zip_source_supports.c delete mode 100644 ext/libzip/zip_source_tell.c delete mode 100644 ext/libzip/zip_source_tell_write.c delete mode 100644 ext/libzip/zip_source_window.c delete mode 100644 ext/libzip/zip_source_write.c delete mode 100644 ext/libzip/zip_source_zip.c delete mode 100644 ext/libzip/zip_source_zip_new.c delete mode 100644 ext/libzip/zip_stat.c delete mode 100644 ext/libzip/zip_stat_index.c delete mode 100644 ext/libzip/zip_stat_init.c delete mode 100644 ext/libzip/zip_strerror.c delete mode 100644 ext/libzip/zip_string.c delete mode 100644 ext/libzip/zip_unchange.c delete mode 100644 ext/libzip/zip_unchange_all.c delete mode 100644 ext/libzip/zip_unchange_archive.c delete mode 100644 ext/libzip/zip_unchange_data.c delete mode 100644 ext/libzip/zip_utf-8.c delete mode 100644 ext/libzip/zipconf.h delete mode 100644 ext/libzip/zipint.h delete mode 100644 ext/libzstd.vcxproj delete mode 100644 ext/zlib/CMakeLists.txt delete mode 100644 ext/zlib/LICENSE delete mode 100644 ext/zlib/README delete mode 100644 ext/zlib/adler32.c delete mode 100644 ext/zlib/compress.c delete mode 100644 ext/zlib/crc32.c delete mode 100644 ext/zlib/crc32.h delete mode 100644 ext/zlib/deflate.c delete mode 100644 ext/zlib/deflate.h delete mode 100644 ext/zlib/gzclose.c delete mode 100644 ext/zlib/gzguts.h delete mode 100644 ext/zlib/gzlib.c delete mode 100644 ext/zlib/gzread.c delete mode 100644 ext/zlib/gzwrite.c delete mode 100644 ext/zlib/infback.c delete mode 100644 ext/zlib/inffast.c delete mode 100644 ext/zlib/inffast.h delete mode 100644 ext/zlib/inffixed.h delete mode 100644 ext/zlib/inflate.c delete mode 100644 ext/zlib/inflate.h delete mode 100644 ext/zlib/inftrees.c delete mode 100644 ext/zlib/inftrees.h delete mode 100644 ext/zlib/trees.c delete mode 100644 ext/zlib/trees.h delete mode 100644 ext/zlib/uncompr.c delete mode 100644 ext/zlib/zconf.h delete mode 100644 ext/zlib/zlib.h delete mode 100644 ext/zlib/zlib.vcxproj delete mode 100644 ext/zlib/zlib.vcxproj.filters delete mode 100644 ext/zlib/zutil.c delete mode 100644 ext/zlib/zutil.h delete mode 160000 ext/zstd delete mode 100644 ext/zstd-build/CMakeLists.txt create mode 100644 libretro/test/.gitignore create mode 100644 libretro/test/blocktest.cpp create mode 100644 libretro/test/codectest.cpp create mode 100644 libretro/test/lrtest.c create mode 100755 libretro/test/make_vectors.py create mode 100755 libretro/test/run.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1cc971666c..298bd644b6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -93,6 +93,36 @@ jobs: shell: msys2 {0} run: make -C libretro -f Makefile -j4 platform=win + # Reads the same disc image as ISO, CSO (two frame sizes), CHD (every codec and two hunk sizes) + # and zipped (stored and deflated) through the core's own block devices and compares every + # block, boots each one, and checks the deflate, zstd, PNG and zip code against vectors made by + # Python's zlib, zstandard and Pillow. + test-libretro-images: + runs-on: ubuntu-26.04 + timeout-minutes: 60 + steps: + - uses: actions/checkout@v7 + with: + submodules: recursive + + - name: Install dependencies + run: | + sudo apt-get update -y -qq + sudo apt-get install -y libgl1-mesa-dev mame-tools genisoimage zip python3-pil python3-zstandard + + - name: Setup ccache + uses: hendrikmuhs/ccache-action@f09c25b45002a07be2955cbe52e8cee55643f89d # v1.2.24 + with: + key: test-libretro-images + + - name: Build the core and the checks + run: | + export PATH="/usr/lib/ccache:$PATH" + make -C libretro -f Makefile -j4 test-tools + + - name: Run the checks + run: libretro/test/run.sh + build: name: build (${{ matrix.id }}) strategy: diff --git a/.gitmodules b/.gitmodules index e7cdec5e8d..8759dedce4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,9 +22,6 @@ [submodule "ext/miniupnp"] path = ext/miniupnp url = https://github.com/miniupnp/miniupnp.git -[submodule "zstd"] - path = ext/zstd - url = https://github.com/facebook/zstd.git [submodule "SDL/macOS"] path = SDL/macOS url = https://github.com/hrydgard/ppsspp-mac-sdl @@ -38,9 +35,6 @@ [submodule "ext/rcheevos"] path = ext/rcheevos url = https://github.com/RetroAchievements/rcheevos.git -[submodule "ext/libchdr"] - path = ext/libchdr - url = https://github.com/rtissera/libchdr.git [submodule "ext/libadrenotools"] path = ext/libadrenotools url = https://github.com/bylaws/libadrenotools.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 291b570fe6..dc240c732e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -199,12 +199,7 @@ option(USE_SYSTEM_SNAPPY "Dynamically link against system snappy" ${USE_SYSTEM_S option(USE_SYSTEM_FFMPEG "Dynamically link against system FFMPEG" ${USE_SYSTEM_FFMPEG}) option(BUILD_BUNDLED_FFMPEG "Build bundled ffmpeg module" ${BUILD_BUNDLED_FFMPEG}) option(USE_SYSTEM_FREETYPE "Dynamically link against system freetype" ${USE_SYSTEM_FREETYPE}) -option(USE_SYSTEM_LIBCHDR "Dynamically link against system libchdr" ${USE_SYSTEM_LIBCHDR}) -option(USE_SYSTEM_LIBZIP "Dynamically link against system libzip" ${USE_SYSTEM_LIBZIP}) - -option(USE_SYSTEM_LIBPNG "Dynamically link against system libpng" ON) option(USE_SYSTEM_RAPIDJSON "Build using system rapidjson" ${USE_SYSTEM_RAPIDJSON}) -option(USE_SYSTEM_ZSTD "Dynamically link against system zstd" ${USE_SYSTEM_ZSTD}) option(USE_SYSTEM_MINIUPNPC "Dynamically link against system miniUPnPc" ${USE_SYSTEM_MINIUPNPC}) option(USE_ASAN "Use address sanitizer" OFF) option(USE_UBSAN "Use undefined behaviour sanitizer" OFF) @@ -228,7 +223,6 @@ endif() if(WEBOS) set(USING_X11_VULKAN OFF) set(USING_GLES2 ON) - set(USE_SYSTEM_ZSTD OFF) if(CMAKE_CXX_COMPILER MATCHES "arm") set(ARMV7 ON) endif() @@ -430,9 +424,6 @@ if(ARM64) endif() if(NOT MSVC) - # NEON optimizations in libpng17 seem to cause PNG load errors, see #14485. - add_compile_definitions(PNG_ARM_NEON_OPT=0) - add_compile_options(-Wall -Werror=return-type -Wno-unused-function -Wno-sign-compare -Wno-unused-but-set-variable "$<$:-Wno-reorder>" -Wno-unknown-pragmas -Wno-unused-value -Wno-unused-variable -Wno-error=incompatible-pointer-types) if(NOT CLANG) # This one is very useful but has many false positives. @@ -573,6 +564,48 @@ macro(setup_target_project TargetName ProjectDir) endforeach() endmacro() +# libretro-common, as one library everything links: the VFS, threading and codecs. +# The headless test tools link it as well as the core. +add_library(libretro-common STATIC + libretro/libretro-common/compat/compat_posix_string.c + libretro/libretro-common/compat/fopen_utf8.c + libretro/libretro-common/compat/compat_strl.c + libretro/libretro-common/encodings/encoding_crc32.c + libretro/libretro-common/encodings/encoding_deflate.c + libretro/libretro-common/encodings/encoding_huffman.c + libretro/libretro-common/encodings/encoding_rzstd.c + libretro/libretro-common/encodings/encoding_utf.c + libretro/libretro-common/features/features_cpu.c + libretro/libretro-common/file/file_path.c + libretro/libretro-common/file/file_path_io.c + libretro/libretro-common/formats/7z/r7z_lzma.c + libretro/libretro-common/formats/chd/rchd.c + libretro/libretro-common/formats/flac/rflac.c + libretro/libretro-common/formats/png/rpng.c + libretro/libretro-common/formats/png/rpng_encode.c + libretro/libretro-common/formats/zip/rzip_archive.c + libretro/libretro-common/queues/retro_spsc.c + libretro/libretro-common/queues/retro_waitable_spsc.c + libretro/libretro-common/rthreads/retro_asym_eventcount.c + libretro/libretro-common/rthreads/retro_eventcount.c + libretro/libretro-common/rthreads/retro_procbarrier.c + libretro/libretro-common/rthreads/rthreads.c + libretro/libretro-common/rthreads/tpool.c + libretro/libretro-common/streams/file_stream.c + libretro/libretro-common/streams/file_stream_transforms.c + libretro/libretro-common/streams/interface_stream.c + libretro/libretro-common/streams/memory_stream.c + libretro/libretro-common/streams/trans_stream.c + libretro/libretro-common/streams/trans_stream_deflate.c + libretro/libretro-common/streams/trans_stream_pipe.c + libretro/libretro-common/string/rstrtod.c + libretro/libretro-common/time/rtime.c + libretro/libretro-common/vfs/vfs_implementation.c) +target_include_directories(libretro-common PUBLIC libretro/libretro-common/include) +target_compile_definitions(libretro-common PUBLIC HAVE_RZSTD HAVE_RFLAC + HAVE_RCHD_DEFLATE HAVE_RCHD_LZMA HAVE_RCHD_FLAC HAVE_RCHD_ZSTD) +target_link_libraries(libretro-common Threads::Threads) + add_subdirectory(ext) include_directories(ext/OpenXR-SDK/include) @@ -668,249 +701,6 @@ if(USE_FFMPEG) endif() endif(USE_FFMPEG) -find_package(ZLIB) -if(ZLIB_FOUND AND NOT ANDROID) - include_directories(${ZLIB_INCLUDE_DIR}) - add_compile_definitions(SHARED_ZLIB) -else() - add_library(zlib STATIC - ext/zlib/adler32.c - ext/zlib/compress.c - ext/zlib/crc32.c - ext/zlib/crc32.h - ext/zlib/deflate.c - ext/zlib/deflate.h - ext/zlib/gzclose.c - ext/zlib/gzguts.h - ext/zlib/gzlib.c - ext/zlib/gzread.c - ext/zlib/gzwrite.c - ext/zlib/infback.c - ext/zlib/inffast.c - ext/zlib/inffast.h - ext/zlib/inffixed.h - ext/zlib/inflate.c - ext/zlib/inflate.h - ext/zlib/inftrees.c - ext/zlib/inftrees.h - ext/zlib/trees.c - ext/zlib/trees.h - ext/zlib/uncompr.c - ext/zlib/zconf.h - ext/zlib/zlib.h - ext/zlib/zutil.c - ext/zlib/zutil.h - ) - include_directories(ext/zlib) - set(ZLIB_LIBRARY zlib) -endif() - -if(NOT MSVC) - # These can be fast even for debug. - target_compile_options(udis86 PRIVATE "-O2") - target_compile_options(cityhash PRIVATE "-O2") - if(NOT ZLIB_FOUND) - target_compile_options(zlib PRIVATE "-O2") - endif() -endif() - - -find_package(LIBZIP) -if(LIBZIP_FOUND AND USE_SYSTEM_LIBZIP) - include_directories(${LIBZIP_INCLUDE_DIRS}) - add_compile_definitions(SHARED_LIBZIP) -else() - add_library(libzip STATIC - ext/libzip/zip_add.c - ext/libzip/zip_add_dir.c - ext/libzip/zip_add_entry.c - ext/libzip/zip_algorithm_deflate.c - ext/libzip/zip_buffer.c - ext/libzip/zip_close.c - ext/libzip/zip_delete.c - ext/libzip/zip_dir_add.c - ext/libzip/zip_dirent.c - ext/libzip/zip_discard.c - ext/libzip/zip_entry.c - ext/libzip/zip_error.c - ext/libzip/zip_error_clear.c - ext/libzip/zip_error_get.c - ext/libzip/zip_error_get_sys_type.c - ext/libzip/zip_error_strerror.c - ext/libzip/zip_error_to_str.c - ext/libzip/zip_extra_field.c - ext/libzip/zip_extra_field_api.c - ext/libzip/zip_fclose.c - ext/libzip/zip_fdopen.c - ext/libzip/zip_file_add.c - ext/libzip/zip_file_error_clear.c - ext/libzip/zip_file_error_get.c - ext/libzip/zip_file_get_comment.c - ext/libzip/zip_file_get_external_attributes.c - ext/libzip/zip_file_get_offset.c - ext/libzip/zip_file_rename.c - ext/libzip/zip_file_replace.c - ext/libzip/zip_file_set_comment.c - ext/libzip/zip_file_set_encryption.c - ext/libzip/zip_file_set_external_attributes.c - ext/libzip/zip_file_set_mtime.c - ext/libzip/zip_file_strerror.c - ext/libzip/zip_fopen.c - ext/libzip/zip_fopen_encrypted.c - ext/libzip/zip_fopen_index.c - ext/libzip/zip_fopen_index_encrypted.c - ext/libzip/zip_fread.c - ext/libzip/zip_fseek.c - ext/libzip/zip_ftell.c - ext/libzip/zip_get_archive_comment.c - ext/libzip/zip_get_archive_flag.c - ext/libzip/zip_get_encryption_implementation.c - ext/libzip/zip_get_file_comment.c - ext/libzip/zip_get_name.c - ext/libzip/zip_get_num_entries.c - ext/libzip/zip_get_num_files.c - ext/libzip/zip_hash.c - ext/libzip/zip_io_util.c - ext/libzip/zip_libzip_version.c - ext/libzip/zip_memdup.c - ext/libzip/zip_name_locate.c - ext/libzip/zip_new.c - ext/libzip/zip_open.c - ext/libzip/zip_pkware.c - ext/libzip/zip_progress.c - ext/libzip/zip_rename.c - ext/libzip/zip_replace.c - ext/libzip/zip_set_archive_comment.c - ext/libzip/zip_set_archive_flag.c - ext/libzip/zip_set_default_password.c - ext/libzip/zip_set_file_comment.c - ext/libzip/zip_set_file_compression.c - ext/libzip/zip_set_name.c - ext/libzip/zip_source_accept_empty.c - ext/libzip/zip_source_begin_write.c - ext/libzip/zip_source_begin_write_cloning.c - ext/libzip/zip_source_buffer.c - ext/libzip/zip_source_call.c - ext/libzip/zip_source_close.c - ext/libzip/zip_source_commit_write.c - ext/libzip/zip_source_compress.c - ext/libzip/zip_source_crc.c - ext/libzip/zip_source_error.c - ext/libzip/zip_source_file_common.c - ext/libzip/zip_source_file_stdio.c - ext/libzip/zip_source_free.c - ext/libzip/zip_source_function.c - ext/libzip/zip_source_get_file_attributes.c - ext/libzip/zip_source_is_deleted.c - ext/libzip/zip_source_layered.c - ext/libzip/zip_source_open.c - ext/libzip/zip_source_pkware_decode.c - ext/libzip/zip_source_pkware_encode.c - ext/libzip/zip_source_read.c - ext/libzip/zip_source_remove.c - ext/libzip/zip_source_rollback_write.c - ext/libzip/zip_source_seek.c - ext/libzip/zip_source_seek_write.c - ext/libzip/zip_source_stat.c - ext/libzip/zip_source_supports.c - ext/libzip/zip_source_tell.c - ext/libzip/zip_source_tell_write.c - ext/libzip/zip_source_window.c - ext/libzip/zip_source_write.c - ext/libzip/zip_source_zip.c - ext/libzip/zip_source_zip_new.c - ext/libzip/zip_stat.c - ext/libzip/zip_stat_index.c - ext/libzip/zip_stat_init.c - ext/libzip/zip_strerror.c - ext/libzip/zip_string.c - ext/libzip/zip_unchange.c - ext/libzip/zip_unchange_all.c - ext/libzip/zip_unchange_archive.c - ext/libzip/zip_unchange_data.c - ext/libzip/zip_utf-8.c - ext/libzip/zip_err_str.c - ) - if(WIN32) - target_compile_options(libzip PRIVATE $<$:-Wno-incompatible-function-pointer-types> $<$:-Wno-incompatible-pointer-types>) - target_sources(libzip PRIVATE - ext/libzip/zip_source_file_win32.c - ext/libzip/zip_source_file_win32_named.c - ext/libzip/zip_source_file_win32_utf16.c - ext/libzip/zip_source_file_win32_utf8.c - ) - if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore) - target_sources(libzip PRIVATE ext/libzip/zip_random_uwp.c) - else() - target_sources(libzip PRIVATE ext/libzip/zip_source_file_win32_ansi.c ext/libzip/zip_random_win32.c) - endif() - else() - target_sources(libzip PRIVATE - ext/libzip/zip_mkstempm.c - ext/libzip/zip_source_file_stdio_named.c - ext/libzip/zip_random_unix.c - ) - endif() - target_compile_definitions(libzip PRIVATE HAVE_STDBOOL_H) - include_directories(ext/libzip) - set(LIBZIP_LIBRARY libzip) -endif() - -# Android and iOS require at least libpng17. -if(ANDROID OR IOS) - set(PNG_REQUIRED_VERSION 1.7) -else() - set(PNG_REQUIRED_VERSION 1.6) -endif() - -if(USE_SYSTEM_LIBPNG) - find_package(PNG ${PNG_REQUIRED_VERSION}) -endif() -if(PNG_FOUND) - include_directories(${PNG_INCLUDE_DIRS}) -else() - if(ARM) - set(PNG_ARM_INCLUDES - ext/libpng17/arm/arm_init.c - ext/libpng17/arm/filter_neon.S - ext/libpng17/arm/filter_neon_intrinsics.c - ) - elseif(ARM64) - set(PNG_ARM_INCLUDES - ext/libpng17/arm/arm_init.c - ext/libpng17/arm/filter_neon_intrinsics.c - ) - endif() - add_library(png17 STATIC - ext/libpng17/pngconf.h - ext/libpng17/pngdebug.h - ext/libpng17/png.c - ext/libpng17/png.h - ext/libpng17/pngerror.c - ext/libpng17/pngget.c - ext/libpng17/pnginfo.h - ext/libpng17/pnglibconf.h - ext/libpng17/pngmem.c - ext/libpng17/pngpread.c - ext/libpng17/pngpriv.h - ext/libpng17/pngread.c - ext/libpng17/pngrio.c - ext/libpng17/pngrtran.c - ext/libpng17/pngrutil.c - ext/libpng17/pngset.c - ext/libpng17/pngstruct.h - ext/libpng17/pngtrans.c - ext/libpng17/pngwio.c - ext/libpng17/pngwrite.c - ext/libpng17/pngwtran.c - ext/libpng17/pngwutil.c - ${PNG_ARM_INCLUDES} - ) - set(PNG_LIBRARIES png17) - include_directories(ext/libpng17) -endif() - - set(targetExtra) set(targetExtraLibs) @@ -1115,22 +905,6 @@ endif() add_subdirectory(Common) -if(USE_SYSTEM_ZSTD) - find_package(ZSTD REQUIRED) -else() - add_subdirectory(ext/zstd-build) - include_directories(ext/zstd/lib) -endif() - -if(USE_SYSTEM_LIBCHDR) - find_package(PkgConfig) - if(PkgConfig_FOUND) - pkg_check_modules(libchdr_PKGCONFIG IMPORTED_TARGET libchdr) - endif() -else() - include_directories(ext/libchdr/include) -endif() - add_subdirectory(GPU) add_subdirectory(Core) diff --git a/Common/CMakeLists.txt b/Common/CMakeLists.txt index a6fd04639f..2b09523d37 100644 --- a/Common/CMakeLists.txt +++ b/Common/CMakeLists.txt @@ -353,10 +353,6 @@ add_library(Common STATIC ${CMAKE_SOURCE_DIR}/ext/jpge/jpge.h ) -if(LIBRETRO) - target_include_directories(Common PRIVATE ${CMAKE_SOURCE_DIR}/libretro/libretro-common/include) -endif() - setup_target_project(Common Common) if(IOS) @@ -389,15 +385,7 @@ if(WIN32) target_link_libraries(Common winmm dsound dxguid d2d1 dwrite d3d11 Version dbghelp) endif() -target_link_libraries(Common ${LIBZIP_LIBRARY} 7zip ${PNG_LIBRARIES} basis_universal ${ZLIB_LIBRARY} pugixml vma gason udis86 ${RT_LIB} ${ATOMIC_LIB}) - -# ZIMLoad.cpp/ZIMSave.cpp, Serializer.cpp, and Render/TextureAtlas.cpp call directly into zstd. -if(USE_SYSTEM_ZSTD) - target_include_directories(Common PRIVATE ${ZSTD_INCLUDE_DIR}) - target_link_libraries(Common ${ZSTD_LIBRARY}) -else() - target_link_libraries(Common libzstd_static) -endif() +target_link_libraries(Common 7zip basis_universal pugixml vma gason udis86 libretro-common ${RT_LIB} ${ATOMIC_LIB}) # Common/GPU/ShaderTranslation.cpp and Common/GPU/Vulkan/VulkanContext.cpp call directly into # glslang/spirv-cross, so Common needs to declare this dependency itself rather than relying on diff --git a/Common/Data/Encoding/Compression.cpp b/Common/Data/Encoding/Compression.cpp index c348ed9313..8d53405ba2 100644 --- a/Common/Data/Encoding/Compression.cpp +++ b/Common/Data/Encoding/Compression.cpp @@ -1,100 +1,113 @@ -// Little utility functions for data compression. -// Taken from http://panthema.net/2007/0328-ZLibString.html - - -#include -#include #include -#include +#include +#include "Common/Data/Encoding/Compression.h" #include "Common/Log.h" -/** Compress a STL string using zlib with given compression level and return -* the binary data. */ -bool compress_string(const std::string& str, std::string *dest, int compressionlevel) { - z_stream zs; // z_stream is zlib's control structure - memset(&zs, 0, sizeof(zs)); +int64_t InflateBuffer(void *stream, int windowBits, const uint8_t *in, size_t inLen, uint8_t *out, size_t outLen, size_t *consumed) { + rinflate_reset(stream, windowBits); + rinflate_set_in(stream, in, inLen); + rinflate_set_out(stream, out, outLen); + size_t rd = 0, wr = 0; + // One call runs until the stream ends or a buffer runs out. + const int status = rinflate_process(stream, &rd, &wr); + if (consumed) + *consumed = rd; + return status == RDEFLATE_PROCESS_END ? (int64_t)wr : -1; +} - if (deflateInit(&zs, compressionlevel) != Z_OK) { - ERROR_LOG(Log::IO, "deflateInit failed while compressing."); - return false; - } +int64_t InflateBuffer(int windowBits, const uint8_t *in, size_t inLen, uint8_t *out, size_t outLen, size_t *consumed) { + void *stream = rinflate_new(windowBits); + if (!stream) + return -1; + const int64_t result = InflateBuffer(stream, windowBits, in, inLen, out, outLen, consumed); + rinflate_free(stream); + return result; +} - zs.next_in = (Bytef*)str.data(); - zs.avail_in = (uInt)str.size(); // set the z_stream's input - - int ret; - char outbuffer[32768]; - std::string outstring; - - // retrieve the compressed bytes blockwise - do { - zs.next_out = reinterpret_cast(outbuffer); - zs.avail_out = sizeof(outbuffer); - - ret = deflate(&zs, Z_FINISH); - - if (outstring.size() < zs.total_out) { - // append the block to the output string - outstring.append(outbuffer, - zs.total_out - outstring.size()); +uint32_t Adler32(uint32_t adler, const uint8_t *buf, size_t len) { + // 5552 is the most bytes that can be summed before the 32-bit sums overflow. + uint32_t a = adler & 0xFFFF, b = adler >> 16; + while (len > 0) { + size_t n = len < 5552 ? len : 5552; + len -= n; + while (n--) { + a += *buf++; + b += a; } - } while (ret == Z_OK); - - deflateEnd(&zs); - - if (ret != Z_STREAM_END) { // an error occurred that was not EOF - ERROR_LOG(Log::IO, "Exception during zlib compression: (%d): %s", ret, zs.msg); - return false; + a %= 65521; + b %= 65521; } + return (b << 16) | a; +} - *dest = outstring; +// Runs a stream to its end, growing *dest as output arrives. +template +static bool RunToEnd(void *stream, std::string *dest, size_t initial, Process process, SetOut setOut) { + std::string out; + out.resize(initial < 4096 ? 4096 : initial); + size_t used = 0; + for (;;) { + setOut(stream, (uint8_t *)&out[used], out.size() - used); + size_t rd = 0, wr = 0; + const int status = process(stream, &rd, &wr); + used += wr; + if (status == RDEFLATE_PROCESS_END) + break; + if (status != RDEFLATE_PROCESS_NEXT) + return false; + if (used == out.size()) + out.resize(out.size() * 2); + else if (rd == 0 && wr == 0) + return false; // input ran out before the end of the stream + } + out.resize(used); + *dest = std::move(out); return true; } -/** Decompress an STL string using zlib and return the original data. */ -bool decompress_string(const std::string& str, std::string *dest) { - if (!str.size()) +bool compress_string(const std::string &str, std::string *dest, int compressionlevel, int windowBits) { + void *stream = rdeflate_new(compressionlevel, windowBits); + if (!stream) return false; - - z_stream zs; // z_stream is zlib's control structure - memset(&zs, 0, sizeof(zs)); - - // modification by hrydgard: inflateInit2, 16+MAXWBITS makes it read gzip data too - if (inflateInit2(&zs, 32+MAX_WBITS) != Z_OK) { - ERROR_LOG(Log::IO, "inflateInit failed while decompressing."); + rdeflate_set_in(stream, (const uint8_t *)str.data(), str.size()); + rdeflate_finish(stream); + const bool ok = RunToEnd(stream, dest, str.size() / 2 + 64, rdeflate_process, rdeflate_set_out); + rdeflate_free(stream); + if (!ok) + ERROR_LOG(Log::IO, "deflate failed while compressing."); + return ok; +} + +bool decompress_string(const std::string &str, std::string *dest) { + if (str.empty()) return false; - } - - zs.next_in = (Bytef*)str.data(); - zs.avail_in = (uInt)str.size(); - - int ret; - char outbuffer[32768]; - std::string outstring; - - // get the decompressed bytes blockwise using repeated calls to inflate - do { - zs.next_out = reinterpret_cast(outbuffer); - zs.avail_out = sizeof(outbuffer); - - ret = inflate(&zs, 0); - - if (outstring.size() < zs.total_out) { - outstring.append(outbuffer, - zs.total_out - outstring.size()); - } - - } while (ret == Z_OK); - - inflateEnd(&zs); - - if (ret != Z_STREAM_END) { // an error occurred that was not EOF - ERROR_LOG(Log::IO, "Exception during zlib decompression: (%i) %s", ret, zs.msg); + void *stream = rinflate_new(47); + if (!stream) return false; - } - - *dest = outstring; - return true; + rinflate_set_in(stream, (const uint8_t *)str.data(), str.size()); + // rinflate_set_out treats each new window as following the last, so growing works. + const bool ok = RunToEnd(stream, dest, str.size() * 4, rinflate_process, rinflate_set_out); + rinflate_free(stream); + if (!ok) + ERROR_LOG(Log::IO, "inflate failed while decompressing."); + return ok; +} + +// The prebuilt FFmpeg archives were linked against zlib and still call these two +// (adler32 in the MOV/MXF demuxers, uncompress for compressed ID3v2 frames). +// zlib's own ABI, so those archives resolve against libretro-common's inflate. +extern "C" unsigned long adler32(unsigned long adler, const unsigned char *buf, unsigned int len) { + if (!buf) + return 1; + return Adler32((uint32_t)adler, buf, len); +} + +extern "C" int uncompress(unsigned char *dest, unsigned long *destLen, const unsigned char *source, unsigned long sourceLen) { + const int64_t produced = InflateBuffer(15, source, sourceLen, dest, *destLen); + if (produced < 0) + return -3; // Z_DATA_ERROR + *destLen = (unsigned long)produced; + return 0; // Z_OK } diff --git a/Common/Data/Encoding/Compression.h b/Common/Data/Encoding/Compression.h index 5323b8f549..ecca0d6ff3 100644 --- a/Common/Data/Encoding/Compression.h +++ b/Common/Data/Encoding/Compression.h @@ -1,7 +1,24 @@ #pragma once +#include +#include #include -// inflate/deflate convenience wrapper. Uses zlib. -bool compress_string(const std::string& str, std::string *dest, int compressionlevel = 9); -bool decompress_string(const std::string& str, std::string *dest); +// zlib-family codecs on libretro-common's rinflate/rdeflate. +// windowBits follow zlib: -15 raw deflate, 15 zlib, 31 gzip, 47 zlib or gzip. + +// Decodes one complete stream into out[0..outLen). Returns the bytes produced, or -1 +// if the stream is bad, truncated, or doesn't fit. *consumed receives the input used. +int64_t InflateBuffer(int windowBits, const uint8_t *in, size_t inLen, uint8_t *out, size_t outLen, size_t *consumed = nullptr); + +// The same through a stream from rinflate_new(), reset here; for callers that decode +// many small streams and shouldn't allocate for each one. +int64_t InflateBuffer(void *stream, int windowBits, const uint8_t *in, size_t inLen, uint8_t *out, size_t outLen, size_t *consumed = nullptr); + +// RFC 1950 Adler-32, zlib's adler32() (start with 1). +uint32_t Adler32(uint32_t adler, const uint8_t *buf, size_t len); + +// Whole-string helpers. compress_string writes zlib by default (31 for gzip); +// decompress_string accepts zlib or gzip. +bool compress_string(const std::string &str, std::string *dest, int compressionlevel = 9, int windowBits = 15); +bool decompress_string(const std::string &str, std::string *dest); diff --git a/Common/Data/Format/PNGLoad.cpp b/Common/Data/Format/PNGLoad.cpp index 7294d049dd..b54c1d73b3 100644 --- a/Common/Data/Format/PNGLoad.cpp +++ b/Common/Data/Format/PNGLoad.cpp @@ -2,7 +2,11 @@ #include #include #include -#include + +#include +#include +#include // RETRO_VFS_FILE_ACCESS_* +#include #include "Common/Data/Format/PNGLoad.h" #include "Common/Log.h" @@ -11,136 +15,56 @@ // *image_data_ptr should be deleted with free() // return value of 1 == success. int pngLoad(const char *file, int *pwidth, int *pheight, unsigned char **image_data_ptr) { - png_image png; - memset(&png, 0, sizeof(png)); - png.version = PNG_IMAGE_VERSION; - - png_image_begin_read_from_file(&png, file); - - if (PNG_IMAGE_FAILED(png)) - { - WARN_LOG(Log::IO, "pngLoad: %s (%s)", png.message, file); - *image_data_ptr = nullptr; + *image_data_ptr = nullptr; + std::string data; + if (!File::ReadBinaryFileToString(Path(file), &data) || data.empty()) { + WARN_LOG(Log::IO, "pngLoad: can't read %s", file); return 0; } - *pwidth = png.width; - *pheight = png.height; - png.format = PNG_FORMAT_RGBA; - - int stride = PNG_IMAGE_ROW_STRIDE(png); - *image_data_ptr = (unsigned char *)malloc(PNG_IMAGE_SIZE(png)); - png_image_finish_read(&png, NULL, *image_data_ptr, stride, NULL); - return 1; + return pngLoadPtr((const unsigned char *)data.data(), data.size(), pwidth, pheight, image_data_ptr); } -// Custom error handler -void pngErrorHandler(png_structp png_ptr, png_const_charp error_msg) { - ERROR_LOG(Log::System, "libpng error: %s\n", error_msg); - longjmp(png_jmpbuf(png_ptr), 1); -} - -void pngWarningHandler(png_structp png_ptr, png_const_charp warning_msg) { - DEBUG_LOG(Log::System, "libpng warning: %s\n", warning_msg); -} - -struct PngReadContext { - const unsigned char *ptr; - size_t remaining; -}; - - int pngLoadPtr(const unsigned char *input_ptr, size_t input_len, int *pwidth, int *pheight, unsigned char **image_data_ptr, int maxWidth, int maxHeight) { - png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, pngErrorHandler, pngWarningHandler); - if (!png) { + *image_data_ptr = nullptr; + if (input_len < sizeof(PNGHeaderPeek)) return 0; - } - if (input_len == 0) { + + // Reject images larger than the caller's limits before anything is allocated, + // so attacker-controlled dimensions can't drive a huge allocation. + PNGHeaderPeek peek; + memcpy(&peek, input_ptr, sizeof(peek)); + if (!peek.IsValidPNGHeader() || peek.Width() > maxWidth || peek.Height() > maxHeight) { + DEBUG_LOG(Log::IO, "PNG rejected: %dx%d (max %dx%d)", peek.Width(), peek.Height(), maxWidth, maxHeight); return 0; } - // Ignore incorrect sRGB profiles - png_set_option(png, PNG_SKIP_sRGB_CHECK_PROFILE, PNG_OPTION_ON); - png_set_benign_errors(png, PNG_OPTION_ON); - - png_infop info = png_create_info_struct(png); - if (!info) { - png_destroy_read_struct(&png, NULL, NULL); + rpng_t *rpng = rpng_alloc(); + if (!rpng) return 0; - } - - if (setjmp(png_jmpbuf(png))) { - png_destroy_read_struct(&png, &info, NULL); - if (*image_data_ptr) { - free(*image_data_ptr); - *image_data_ptr = NULL; + // rpng only reads through this pointer. + uint32_t *data = nullptr; + unsigned w = 0, h = 0; + int ret = IMAGE_PROCESS_ERROR; + if (rpng_set_buf_ptr(rpng, (void *)input_ptr, input_len) && rpng_start(rpng)) { + while (rpng_iterate_image(rpng)) { } - return 0; - } - - PngReadContext readContext = {input_ptr, input_len}; - - png_set_read_fn(png, &readContext, [](png_structp png_ptr, png_bytep outBytes, png_size_t byteCountToRead) { - PngReadContext *ctx = (PngReadContext *)png_get_io_ptr(png_ptr); - if (byteCountToRead > ctx->remaining) { - // This triggers the longjmp to your pngErrorHandler - png_error(png_ptr, "Read past end of buffer"); - return; + if (rpng_is_valid(rpng)) { + // RGBA byte order, which is what everything here wants. + do { + ret = rpng_process_image(rpng, (void **)&data, input_len, &w, &h, true); + } while (ret == IMAGE_PROCESS_NEXT); } - - memcpy(outBytes, ctx->ptr, byteCountToRead); - ctx->ptr += byteCountToRead; - ctx->remaining -= byteCountToRead; - }); - - png_read_info(png, info); - - const int color_type = png_get_color_type(png, info); - png_set_strip_16(png); - png_set_packing(png); - if (color_type == PNG_COLOR_TYPE_GRAY) - png_set_expand_gray_1_2_4_to_8(png); - if (color_type == PNG_COLOR_TYPE_PALETTE) { - png_set_palette_to_rgb(png); - } else if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { - png_set_gray_to_rgb(png); } + rpng_free(rpng); - if (png_get_valid(png, info, PNG_INFO_tRNS)) - png_set_tRNS_to_alpha(png); - // Force 8-bit RGBA format - png_set_filler(png, 0xFF, PNG_FILLER_AFTER); - png_set_interlace_handling(png); - // Ignore the file's gamma correction - png_set_gamma(png, 1.0, 1.0); - - png_read_update_info(png, info); - - *pwidth = png_get_image_width(png, info); - *pheight = png_get_image_height(png, info); - - // Reject images larger than the caller's limits to avoid decompression - // bombs (attacker-controlled dimensions would otherwise drive a huge - // allocation here). - if (*pwidth > maxWidth || *pheight > maxHeight) { - DEBUG_LOG(Log::IO, "PNG too large: %dx%d (max %dx%d)", *pwidth, *pheight, maxWidth, maxHeight); - png_destroy_read_struct(&png, &info, NULL); + if (ret != IMAGE_PROCESS_END || !data || (int)w != peek.Width() || (int)h != peek.Height()) { + free(data); + ERROR_LOG(Log::IO, "PNG decode failed"); return 0; } - - size_t row_bytes = png_get_rowbytes(png, info); - *image_data_ptr = (unsigned char *)malloc(row_bytes * (*pheight)); - if (!*image_data_ptr) { - png_destroy_read_struct(&png, &info, NULL); - return 0; - } - - std::vector row_pointers(*pheight); - for (int y = 0; y < *pheight; y++) { - row_pointers[y] = *image_data_ptr + y * row_bytes; - } - - png_read_image(png, row_pointers.data()); - png_destroy_read_struct(&png, &info, NULL); + *pwidth = (int)w; + *pheight = (int)h; + *image_data_ptr = (unsigned char *)data; return 1; } @@ -159,64 +83,57 @@ bool PNGHeaderPeek::IsValidPNGHeader() const { return true; } -bool pngSave(const Path &filename, const void *buffer, int w, int h, int bytesPerPixel) { - png_bytepp row_ptrs = nullptr; - - FILE *fp = File::OpenCFile(filename, "wb"); - if (!fp) { - ERROR_LOG(Log::IO, "Unable to open png file for writing: %s", filename.c_str()); - return false; - } - - png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, pngErrorHandler, pngWarningHandler); - if (png_ptr == nullptr) { - fclose(fp); - ERROR_LOG(Log::IO, "PNG encode failed."); - return false; - } - - png_infop info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == nullptr) { - png_destroy_write_struct(&png_ptr, nullptr); - fclose(fp); - ERROR_LOG(Log::IO, "PNG encode failed."); - return false; - } - - if (setjmp(png_jmpbuf(png_ptr))) { - if (row_ptrs != nullptr) { - png_free(png_ptr, row_ptrs); +// rpng's encoder writes to an intfstream; a memory one sized past the worst case +// holds the whole file, which then goes out in one write. +bool pngEncode(std::vector *out, const void *buffer, int w, int h, PNGFormat format) { + const uint8_t *src = (const uint8_t *)buffer; + std::vector bgr; + enum rpng_pixfmt fmt; + int bpp; + switch (format) { + case PNGFormat::RGBA8888: fmt = RPNG_PIXFMT_RGBA32; bpp = 4; break; + // ARGB32 as 32-bit words is B, G, R, A in memory on little-endian hosts. + case PNGFormat::BGRA8888: fmt = RPNG_PIXFMT_ARGB32; bpp = 4; break; + case PNGFormat::RGB888: + default: + // rpng takes 24-bit pixels as BGR. + bgr.resize((size_t)w * h * 3); + for (size_t i = 0; i < bgr.size(); i += 3) { + bgr[i + 0] = src[i + 2]; + bgr[i + 1] = src[i + 1]; + bgr[i + 2] = src[i + 0]; } - png_destroy_write_struct(&png_ptr, &info_ptr); - fclose(fp); - - // Should we even do this? - File::Delete(filename); - - ERROR_LOG(Log::IO, "PNG encode failed."); + src = bgr.data(); + fmt = RPNG_PIXFMT_BGR24; + bpp = 3; + break; + } + const size_t raw = (size_t)w * h * bpp; + const size_t bound = raw + raw / 16 + (size_t)h * 8 + 4096; + out->resize(bound); + intfstream_t *stream = intfstream_open_memory(out->data(), RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE, bound); + if (!stream) { + out->clear(); return false; } + const bool ok = rpng_save_image_stream_fmt(src, stream, w, h, w * bpp, fmt, nullptr); + const int64_t written = intfstream_get_ptr(stream); + intfstream_close(stream); + free(stream); + if (!ok || written <= 0) { + out->clear(); + return false; + } + out->resize((size_t)written); + return true; +} - png_set_write_fn(png_ptr, fp, [](png_structp png_ptr, png_bytep data, png_size_t size) { - if (fwrite(data, 1, size, (FILE *)png_get_io_ptr(png_ptr)) < size) { - png_error(png_ptr, "Failed to write to file."); - } - }, [](png_structp png_ptr) { - fflush((FILE *)png_get_io_ptr(png_ptr)); - }); - - png_set_IHDR(png_ptr, info_ptr, w, h, 8, bytesPerPixel == 3 ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - - row_ptrs = (png_bytepp)png_malloc(png_ptr, (png_alloc_size_t)h * (png_alloc_size_t)sizeof(png_bytep)); - for (png_alloc_size_t i = 0; i < h; ++i) { - row_ptrs[i] = (png_bytep)buffer + (png_alloc_size_t)w * (png_alloc_size_t)bytesPerPixel * i; +bool pngSave(const Path &filename, const void *buffer, int w, int h, int bytesPerPixel) { + std::vector png; + if (!pngEncode(&png, buffer, w, h, bytesPerPixel == 4 ? PNGFormat::RGBA8888 : PNGFormat::RGB888) || + !File::WriteDataToFile(false, png.data(), png.size(), filename)) { + ERROR_LOG(Log::IO, "PNG encode failed: %s", filename.c_str()); + return false; } - png_set_rows(png_ptr, info_ptr, row_ptrs); - - png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, nullptr); - - png_free(png_ptr, row_ptrs); - png_destroy_write_struct(&png_ptr, &info_ptr); - fclose(fp); return true; } diff --git a/Common/Data/Format/PNGLoad.h b/Common/Data/Format/PNGLoad.h index 4bd7f3c2b5..560216548f 100644 --- a/Common/Data/Format/PNGLoad.h +++ b/Common/Data/Format/PNGLoad.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "Common/BitSet.h" #include "Common/File/Path.h" @@ -34,4 +35,13 @@ struct PNGHeaderPeek { int Height() const { return swap32(be_height); } }; +// bytesPerPixel 4 is RGBA8888, 3 is RGB888. bool pngSave(const Path &filename, const void *buffer, int w, int h, int bytesPerPixel); + +enum class PNGFormat { + RGBA8888, + BGRA8888, + RGB888, +}; +// Tightly packed pixels in, a complete PNG file out. +bool pngEncode(std::vector *out, const void *buffer, int w, int h, PNGFormat format = PNGFormat::RGBA8888); diff --git a/Common/Data/Format/ZIMLoad.cpp b/Common/Data/Format/ZIMLoad.cpp index 0113a46d71..fb1a9f26ab 100644 --- a/Common/Data/Format/ZIMLoad.cpp +++ b/Common/Data/Format/ZIMLoad.cpp @@ -2,54 +2,15 @@ #include #include #include -#include +#include -#include "zlib.h" +#include "Common/Data/Encoding/Compression.h" #include "Common/Log.h" #include "Common/Data/Format/ZIMLoad.h" #include "Common/Math/math_util.h" #include "Common/File/VFS/VFS.h" -int ezuncompress(unsigned char* pDest, long* pnDestLen, const unsigned char* pSrc, long nSrcLen) { - z_stream stream; - stream.next_in = (Bytef*)pSrc; - stream.avail_in = (uInt)nSrcLen; - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != (uLong)nSrcLen) return Z_BUF_ERROR; - - uInt destlen = (uInt)*pnDestLen; - if ((uLong)destlen != (uLong)*pnDestLen) return Z_BUF_ERROR; - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - - int err = inflateInit(&stream); - if (err != Z_OK) return err; - - int nExtraChunks = 0; - do { - stream.next_out = pDest; - stream.avail_out = destlen; - err = inflate(&stream, Z_FINISH); - if (err == Z_STREAM_END ) - break; - if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) - err = Z_DATA_ERROR; - if (err != Z_BUF_ERROR) { - inflateEnd(&stream); - return err; - } - nExtraChunks += 1; - } while (stream.avail_out == 0); - - *pnDestLen = stream.total_out; - - err = inflateEnd(&stream); - if (err != Z_OK) return err; - - return nExtraChunks ? Z_BUF_ERROR : Z_OK; -} - int LoadZIMPtr(const uint8_t *zim, size_t datasize, int *width, int *height, int *flags, uint8_t **image) { if (datasize < 16) { ERROR_LOG(Log::IO, "ZIM file is too small"); @@ -139,10 +100,9 @@ int LoadZIMPtr(const uint8_t *zim, size_t datasize, int *width, int *height, int } if (*flags & ZIM_ZLIB_COMPRESSED) { - long outlen = (long)total_data_size; - int retcode = ezuncompress(*image, &outlen, (unsigned char *)(zim + 16), (long)payload_size); - if (Z_OK != retcode) { - ERROR_LOG(Log::IO, "ZIM zlib format decompression failed: %d", retcode); + const int64_t outlen = InflateBuffer(15, zim + 16, (size_t)payload_size, *image, (size_t)total_data_size); + if (outlen < 0) { + ERROR_LOG(Log::IO, "ZIM zlib format decompression failed"); free(*image); *image = 0; return 0; @@ -152,8 +112,8 @@ int LoadZIMPtr(const uint8_t *zim, size_t datasize, int *width, int *height, int ERROR_LOG(Log::IO, "Wrong size data in ZIM: %i vs %i", (int)outlen, (int)total_data_size); } } else if (*flags & ZIM_ZSTD_COMPRESSED) { - size_t outlen = ZSTD_decompress(*image, total_data_size, zim + 16, payload_size); - if (outlen != (size_t)total_data_size) { + size_t outlen = 0; + if (rzstd_decode(*image, total_data_size, zim + 16, payload_size, &outlen) != RZSTD_PROCESS_END || outlen != (size_t)total_data_size) { ERROR_LOG(Log::IO, "ZIM zstd format decompression failed: %lld", (long long)outlen); free(*image); *image = 0; diff --git a/Common/Data/Format/ZIMSave.cpp b/Common/Data/Format/ZIMSave.cpp index 0abe0a40da..5a21549606 100644 --- a/Common/Data/Format/ZIMSave.cpp +++ b/Common/Data/Format/ZIMSave.cpp @@ -1,9 +1,11 @@ #include #include #include -#include +#include -#include "zlib.h" +#include + +#include "Common/Data/Encoding/Compression.h" #include "Common/Log.h" #include "Common/Data/Format/ZIMLoad.h" @@ -24,48 +26,6 @@ static unsigned int log2i(unsigned int val) { } -int ezcompress(unsigned char* pDest, long* pnDestLen, const unsigned char* pSrc, long nSrcLen, int compressLevel) { - z_stream stream; - int err; - - int nExtraChunks; - uInt destlen; - - stream.next_in = (Bytef*)pSrc; - stream.avail_in = (uInt)nSrcLen; -#ifdef MAXSEG_64K - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != nSrcLen) return Z_BUF_ERROR; -#endif - destlen = (uInt)*pnDestLen; - if ((uLong)destlen != (uLong)*pnDestLen) return Z_BUF_ERROR; - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit(&stream, compressLevel); - if (err != Z_OK) return err; - nExtraChunks = 0; - do { - stream.next_out = pDest; - stream.avail_out = destlen; - err = deflate(&stream, Z_FINISH); - if (err == Z_STREAM_END ) - break; - if (err != Z_OK) { - deflateEnd(&stream); - return err; - } - nExtraChunks += 1; - } while (stream.avail_out == 0); - - *pnDestLen = stream.total_out; - - err = deflateEnd(&stream); - if (err != Z_OK) return err; - - return nExtraChunks ? Z_BUF_ERROR : Z_OK; -} inline int clamp16(int x) { if (x < 0) return 0; if (x > 15) return 15; return x; } inline int clamp32(int x) { if (x < 0) return 0; if (x > 31) return 31; return x; } @@ -194,19 +154,16 @@ void SaveZIM(FILE *f, int width, int height, int pitch, int flags, const uint8_t int data_size; Convert(image_data, width, height, pitch, flags, &data, &data_size); if (flags & ZIM_ZLIB_COMPRESSED) { - long dest_len = data_size * 2; - uint8_t *dest = new uint8_t[dest_len]; - if (Z_OK == ezcompress(dest, &dest_len, data, data_size, compressLevel == 0 ? Z_DEFAULT_COMPRESSION : compressLevel)) { - fwrite(dest, 1, dest_len, f); + std::string dest; + if (compress_string(std::string((const char *)data, data_size), &dest, compressLevel == 0 ? 6 : compressLevel)) { + fwrite(dest.data(), 1, dest.size(), f); } else { ERROR_LOG(Log::IO, "Zlib compression failed.\n"); } - delete [] dest; } else if (flags & ZIM_ZSTD_COMPRESSED) { - size_t dest_len = ZSTD_compressBound(data_size); + size_t dest_len = rzstd_compress_bound(data_size); uint8_t *dest = new uint8_t[dest_len]; - dest_len = ZSTD_compress(dest, dest_len, data, data_size, compressLevel == 0 ? 22 : compressLevel); - if (!ZSTD_isError(dest_len)) { + if (rzstd_encode(dest, dest_len, data, data_size, compressLevel == 0 ? 9 : compressLevel, &dest_len) == RZSTD_PROCESS_END) { fwrite(dest, 1, dest_len, f); } else { ERROR_LOG(Log::IO, "Zlib compression failed.\n"); diff --git a/Common/File/VFS/ZipFileReader.cpp b/Common/File/VFS/ZipFileReader.cpp index 83655bc989..316d5fd12a 100644 --- a/Common/File/VFS/ZipFileReader.cpp +++ b/Common/File/VFS/ZipFileReader.cpp @@ -3,12 +3,11 @@ #include // for sort #include #include +#include -#ifdef SHARED_LIBZIP -#include -#else -#include "ext/libzip/zip.h" -#endif +#include +#include +#include #include "Common/Common.h" #include "Common/Log.h" @@ -19,13 +18,55 @@ // malicious zip can't drive an implausible (or, near UINT64_MAX, wrapping) allocation. static constexpr uint64_t MAX_ZIP_ENTRY_SIZE = 1ULL << 32; // 4GB, generous for any real asset. -ZipContainer::ZipContainer() noexcept : sourceData_(nullptr), zip_(nullptr) {} - -ZipContainer::ZipContainer(const Path &path) : sourceData_(new SourceData {path, nullptr}), zip_(nullptr) { - zip_source_t *source = zip_source_function_create(SourceCallback, sourceData_, nullptr); - if (source != nullptr && (zip_ = zip_open_from_source(source, ZIP_RDONLY, nullptr)) == nullptr) { - zip_source_free(source); +static std::string AsciiLower(std::string_view s) { + std::string out(s); + for (char &c : out) { + if (c >= 'A' && c <= 'Z') + c += 'a' - 'A'; } + return out; +} + +// Heap-allocated so the context rzip holds survives moves of the container. +struct ZipFileSource { + FILE *file; +}; + +ZipContainer::ZipContainer(const Path &path) { + FILE *file = File::OpenCFile(path, "rb"); + if (!file) + return; + const int64_t size = File::GetFileSize(file); + source_ = new ZipFileSource{ file }; + read_ = &FileRead; + userdata_ = source_; + if (size > 0) + Open((uint64_t)size); + if (!zip_) + close(); +} + +ZipContainer::ZipContainer(ReadFunc read, void *userdata, uint64_t size) : read_(read), userdata_(userdata) { + Open(size); +} + +void ZipContainer::Open(uint64_t size) { + rzip_archive_t *zip = nullptr; + if (rzip_archive_open(&zip, nullptr, size, read_, userdata_) != RZIP_OK) + return; + zip_ = zip; + // One pass to make name lookups cheap. First of any duplicates wins, like libzip. + const uint32_t count = rzip_archive_num_entries(zip_); + lowerIndex_.reserve(count); + for (uint32_t i = 0; i < count; i++) + lowerIndex_.emplace(AsciiLower(rzip_archive_entry(zip_, i)->name), (int)i); +} + +int64_t ZipContainer::FileRead(void *userdata, uint64_t off, void *dst, size_t len) { + FILE *file = ((ZipFileSource *)userdata)->file; + if (File::Fseek(file, (int64_t)off, SEEK_SET) != 0) + return -1; + return (int64_t)fread(dst, 1, len, file); } ZipContainer::ZipContainer(ZipContainer &&other) noexcept { @@ -33,10 +74,14 @@ ZipContainer::ZipContainer(ZipContainer &&other) noexcept { } ZipContainer &ZipContainer::operator=(ZipContainer &&other) noexcept { - sourceData_ = other.sourceData_; - zip_ = other.zip_; - other.sourceData_ = nullptr; - other.zip_ = nullptr; + if (this == &other) + return *this; + close(); + std::swap(zip_, other.zip_); + std::swap(source_, other.source_); + std::swap(read_, other.read_); + std::swap(userdata_, other.userdata_); + lowerIndex_ = std::move(other.lowerIndex_); return *this; } @@ -45,109 +90,132 @@ ZipContainer::~ZipContainer() { } void ZipContainer::close() noexcept { - if (zip_ != nullptr) { - zip_close(zip_); + if (zip_) { + rzip_archive_close(zip_); zip_ = nullptr; } - delete sourceData_; - sourceData_ = nullptr; -} - -ZipContainer::operator zip_t *() const noexcept { - return zip_; -} - -zip_int64_t ZipContainer::SourceCallback(void *userdata, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { - SourceData &sourceData = *(SourceData *)userdata; - - switch (cmd) { - case ZIP_SOURCE_SUPPORTS: - return zip_source_make_command_bitmap( - ZIP_SOURCE_SUPPORTS, - ZIP_SOURCE_OPEN, - ZIP_SOURCE_READ, - ZIP_SOURCE_CLOSE, - ZIP_SOURCE_STAT, - ZIP_SOURCE_ERROR, - ZIP_SOURCE_SEEK, - ZIP_SOURCE_TELL, - -1); - - case ZIP_SOURCE_OPEN: - { - FILE *newFile = File::OpenCFile(sourceData.path, "rb"); - if (newFile == nullptr) { - return -1; - } - sourceData.file = newFile; - return 0; - } - - case ZIP_SOURCE_READ: - { - size_t n = fread(data, 1, len, sourceData.file); - return ferror(sourceData.file) ? -1 : n; - } - - case ZIP_SOURCE_CLOSE: - fclose(sourceData.file); - sourceData.file = nullptr; - return 0; - - case ZIP_SOURCE_STAT: - if (sourceData.file == nullptr) { - zip_stat_t *stat = (zip_stat_t *)data; - zip_stat_init(stat); - stat->valid = 0; - } else { - int64_t pos = File::Ftell(sourceData.file); - if (pos == -1) { - return -1; - } - if (File::Fseek(sourceData.file, 0, SEEK_END) != 0) { - return -1; - } - int64_t size = File::Ftell(sourceData.file); - if (size != pos && File::Fseek(sourceData.file, pos, SEEK_SET) != 0) { - return -1; - } - zip_stat_t *stat = (zip_stat_t *)data; - zip_stat_init(stat); - stat->valid = ZIP_STAT_SIZE; - stat->size = size; - } - return 0; - - case ZIP_SOURCE_ERROR: - return ZIP_ER_INTERNAL; - - case ZIP_SOURCE_SEEK: - { - zip_source_args_seek_t *args = (zip_source_args_seek_t *)data; - if (args == nullptr) { - return -1; - } - return File::Fseek(sourceData.file, args->offset, args->whence) ? -1 : 0; - } - - case ZIP_SOURCE_TELL: - return File::Ftell(sourceData.file); - - default: - return -1; + if (source_) { + fclose(source_->file); + delete source_; + source_ = nullptr; } + read_ = nullptr; + userdata_ = nullptr; + lowerIndex_.clear(); +} + +int ZipContainer::NumEntries() const { + return zip_ ? (int)rzip_archive_num_entries(zip_) : 0; +} + +const char *ZipContainer::Name(int index) const { + const rzip_entry_t *e = zip_ ? rzip_archive_entry(zip_, (uint32_t)index) : nullptr; + return e ? e->name : nullptr; +} + +uint64_t ZipContainer::Size(int index) const { + const rzip_entry_t *e = zip_ ? rzip_archive_entry(zip_, (uint32_t)index) : nullptr; + return e ? e->size : 0; +} + +bool ZipContainer::IsDirectory(int index) const { + const rzip_entry_t *e = zip_ ? rzip_archive_entry(zip_, (uint32_t)index) : nullptr; + return e && e->is_dir; +} + +int ZipContainer::Find(std::string_view name, bool nocase) const { + if (!zip_) + return -1; + auto it = lowerIndex_.find(AsciiLower(name)); + if (it == lowerIndex_.end()) + return -1; + if (!nocase && name != Name(it->second)) + return rzip_archive_find(zip_, std::string(name).c_str()); + return it->second; +} + +bool ZipContainer::ExtractInto(int index, uint8_t *dst, size_t dstSize) const { + if (!zip_) + return false; + size_t len = 0; + return rzip_archive_extract_into(zip_, (uint32_t)index, dst, dstSize, &len) == RZIP_OK && len == Size(index); +} + +bool ZipContainer::ExtractTo(int index, const std::function &sink) const { + const rzip_entry_t *e = zip_ ? rzip_archive_entry(zip_, (uint32_t)index) : nullptr; + if (!e || (e->method != RZIP_METHOD_STORED && e->method != RZIP_METHOD_DEFLATE)) + return false; + const size_t CHUNK = 256 * 1024; + std::vector in(CHUNK); + uint32_t crc = 0; + uint64_t total = 0; + uint64_t inPos = 0; + if (e->method == RZIP_METHOD_STORED) { + while (inPos < e->csize) { + const size_t n = (size_t)std::min(CHUNK, e->csize - inPos); + if (read_(userdata_, e->data_off + inPos, in.data(), n) != (int64_t)n) + return false; + inPos += n; + crc = encoding_crc32(crc, in.data(), n); + total += n; + if (!sink(in.data(), n)) + return false; + } + return total == e->size && crc == e->crc; + } + + void *inf = rinflate_new(-15); + if (!inf) + return false; + std::vector out(CHUNK); + bool done = false, ok = true; + while (ok && !done && inPos < e->csize) { + const size_t n = (size_t)std::min(CHUNK, e->csize - inPos); + if (read_(userdata_, e->data_off + inPos, in.data(), n) != (int64_t)n) { + ok = false; + break; + } + inPos += n; + rinflate_set_in(inf, in.data(), n); + for (;;) { + rinflate_set_out(inf, out.data(), CHUNK); + size_t rd = 0, wr = 0; + const int status = rinflate_process(inf, &rd, &wr); + if (wr) { + crc = encoding_crc32(crc, out.data(), wr); + total += wr; + if (!sink(out.data(), wr)) { + ok = false; + break; + } + } + if (status == RDEFLATE_PROCESS_END) { + done = true; + break; + } + if (status != RDEFLATE_PROCESS_NEXT) { + ok = false; + break; + } + // Room left over means this piece of input is used up. + if (wr < CHUNK) + break; + } + } + rinflate_free(inf); + return ok && done && total == e->size && crc == e->crc; } ZipFileReader *ZipFileReader::Create(const Path &zipFile, std::string_view inZipPath, bool logErrors) { // The inZipPath is supposed to be a folder, and internally in this class, we suffix - // folder paths with '/', matching how the zip library works. + // folder paths with '/', matching how zip files name things. std::string path(inZipPath); if (!path.empty() && path.back() != '/') { path.push_back('/'); } ZipContainer zip(zipFile); - if (zip == nullptr) { + if (!zip) { if (logErrors) { ERROR_LOG(Log::IO, "Failed to open %s as a zip file", zipFile.c_str()); } @@ -165,32 +233,30 @@ ZipFileReader::~ZipFileReader() { uint8_t *ZipFileReader::ReadFile(std::string_view path, size_t *size) { std::string temp_path = join(inZipPath_, path); - std::lock_guard guard(lock_); - // Figure out the file size first. TODO: Can this part be done without locking the mutex? - struct zip_stat zstat; - int retval = zip_stat(zip_file_, temp_path.c_str(), ZIP_FL_NOCASE | ZIP_FL_UNCHANGED, &zstat); - if (retval != 0) { + const int index = zip_file_.Find(temp_path); + if (index < 0) { ERROR_LOG(Log::IO, "Error opening %s from ZIP", temp_path.c_str()); return 0; } - // Sanity check the declared size before trusting it for an allocation - a corrupt - // or malicious zip could claim a huge (even ~UINT64_MAX, which would wrap the +1 - // below to 0) size here. - if (zstat.size > MAX_ZIP_ENTRY_SIZE) { - ERROR_LOG(Log::IO, "Zip entry %s claims an implausible size (%llu), refusing to read", temp_path.c_str(), (unsigned long long)zstat.size); + const uint64_t entrySize = zip_file_.Size(index); + // Sanity check the declared size before trusting it for an allocation. + if (entrySize > MAX_ZIP_ENTRY_SIZE) { + ERROR_LOG(Log::IO, "Zip entry %s claims an implausible size (%llu), refusing to read", temp_path.c_str(), (unsigned long long)entrySize); return 0; } - zip_file *file = zip_fopen_index(zip_file_, zstat.index, ZIP_FL_NOCASE | ZIP_FL_UNCHANGED); - if (!file) { - ERROR_LOG(Log::IO, "Error opening %s from ZIP", temp_path.c_str()); + uint8_t *contents = new uint8_t[entrySize + 1]; + bool ok; + { + std::lock_guard guard(lock_); + ok = zip_file_.ExtractInto(index, contents, (size_t)entrySize); + } + if (!ok) { + ERROR_LOG(Log::IO, "Error reading %s from ZIP", temp_path.c_str()); + delete[] contents; return 0; } - uint8_t *contents = new uint8_t[zstat.size + 1]; - zip_fread(file, contents, zstat.size); - zip_fclose(file); - contents[zstat.size] = 0; - - *size = zstat.size; + contents[entrySize] = 0; + *size = (size_t)entrySize; return contents; } @@ -228,8 +294,6 @@ bool ZipFileReader::GetFileListing(std::string_view orig_path, std::vectorclear(); - // INFO_LOG(Log::IO, "Zip: Listing '%s'", orig_path); - const std::string relativePath = path.substr(inZipPath_.size()); listing->reserve(directories.size() + files.size()); @@ -242,7 +306,6 @@ bool ZipFileReader::GetFileListing(std::string_view orig_path, std::vectorpush_back(info); } @@ -259,7 +322,6 @@ bool ZipFileReader::GetFileListing(std::string_view orig_path, std::vectorpush_back(info); } @@ -271,11 +333,11 @@ bool ZipFileReader::GetFileListing(std::string_view orig_path, std::vector &files, std::set &directories) { _dbg_assert_(path.empty() || path.back() == '/'); - std::lock_guard guard(lock_); - int numFiles = zip_get_num_files(zip_file_); + // The directory is parsed at open and never changes, so this needs no lock. + const int numFiles = zip_file_.NumEntries(); bool anyPrefixMatched = false; for (int i = 0; i < numFiles; i++) { - const char* name = zip_get_name(zip_file_, i, 0); + const char *name = zip_file_.Name(i); if (!name) continue; // shouldn't happen, I think if (startsWith(name, path)) { @@ -303,7 +365,6 @@ bool ZipFileReader::GetZipListings(const std::string &path, std::setisWritable = false; info->size = 0; - { - std::lock_guard guard(lock_); - if (0 != zip_stat(zip_file_, temp_path.c_str(), ZIP_FL_NOCASE | ZIP_FL_UNCHANGED, &zstat)) { - // ZIP files do not have real directories, so we'll end up here if we - // try to stat one. For now that's fine. - info->exists = false; - return false; - } + const int index = zip_file_.Find(temp_path); + if (index < 0) { + // ZIP files do not have real directories, so we'll end up here if we + // try to stat one. For now that's fine. + info->exists = false; + return false; } // Zips usually don't contain directory entries, but they may. - if ((zstat.valid & ZIP_STAT_NAME) != 0 && zstat.name && zstat.name[0] != '\0') { - info->isDirectory = zstat.name[strlen(zstat.name) - 1] == '/'; - } - if ((zstat.valid & ZIP_STAT_SIZE) != 0) { - info->size = zstat.size; - } - + info->isDirectory = zip_file_.IsDirectory(index); + info->size = zip_file_.Size(index); info->fullName = Path(path); info->exists = true; return true; @@ -339,19 +393,19 @@ public: int zi; }; +// Members are decoded whole: straight into the caller's buffer when the first +// read asks for all of it, which is how files are read here, else into data. class ZipFileReaderOpenFile : public VFSOpenFile { public: - ~ZipFileReaderOpenFile() { - // Needs to be closed properly and unlocked. - _dbg_assert_(zf == nullptr); - } ZipFileReaderFileReference *reference; - zip_file_t *zf = nullptr; + size_t size = 0; + size_t pos = 0; + bool decoded = false; + std::vector data; }; VFSFileReference *ZipFileReader::GetFile(std::string_view path) { - std::string p(path); - int zi = zip_name_locate(zip_file_, p.c_str(), ZIP_FL_NOCASE); // this is EXPENSIVE + int zi = zip_file_.Find(path); if (zi < 0) { // Not found. return nullptr; @@ -363,16 +417,9 @@ VFSFileReference *ZipFileReader::GetFile(std::string_view path) { bool ZipFileReader::GetFileInfo(VFSFileReference *vfsReference, File::FileInfo *fileInfo) { ZipFileReaderFileReference *reference = (ZipFileReaderFileReference *)vfsReference; - // If you crash here, you called this while having the lock held by having the file open. - // Don't do that, check the info before you open the file. - zip_stat_t zstat; - if (zip_stat_index(zip_file_, reference->zi, 0, &zstat) != 0) - return false; *fileInfo = File::FileInfo{}; - fileInfo->size = 0; - if (zstat.valid & ZIP_STAT_SIZE) - fileInfo->size = zstat.size; - return zstat.size; + fileInfo->size = zip_file_.Size(reference->zi); + return fileInfo->size != 0; } void ZipFileReader::ReleaseFile(VFSFileReference *vfsReference) { @@ -383,93 +430,83 @@ void ZipFileReader::ReleaseFile(VFSFileReference *vfsReference) { VFSOpenFile *ZipFileReader::OpenFileForRead(VFSFileReference *vfsReference, size_t *size) { ZipFileReaderFileReference *reference = (ZipFileReaderFileReference *)vfsReference; + *size = 0; + const uint64_t entrySize = zip_file_.Size(reference->zi); + if (entrySize > MAX_ZIP_ENTRY_SIZE) { + WARN_LOG(Log::G3D, "File with index %d in zip has an implausible size", reference->zi); + return nullptr; + } ZipFileReaderOpenFile *openFile = new ZipFileReaderOpenFile(); openFile->reference = reference; - *size = 0; - // We only allow one file to be open for read concurrently. It's possible that this can be improved, - // especially if we only access by index like this. - lock_.lock(); - zip_stat_t zstat; - if (zip_stat_index(zip_file_, reference->zi, 0, &zstat) != 0) { - lock_.unlock(); - delete openFile; - return nullptr; - } - - openFile->zf = zip_fopen_index(zip_file_, reference->zi, 0); - if (!openFile->zf) { - WARN_LOG(Log::G3D, "File with index %d not found in zip", reference->zi); - lock_.unlock(); - delete openFile; - return nullptr; - } - - *size = zstat.size; - // Intentionally leaving the mutex locked, will be closed in CloseFile. + openFile->size = (size_t)entrySize; + *size = openFile->size; return openFile; } void ZipFileReader::Rewind(VFSOpenFile *vfsOpenFile) { ZipFileReaderOpenFile *file = (ZipFileReaderOpenFile *)vfsOpenFile; _assert_(file); - // Unless the zip file is compressed, can't seek directly, so we re-open. - // This version of libzip doesn't even have zip_file_is_seekable(), should probably upgrade. - zip_fclose(file->zf); - file->zf = zip_fopen_index(zip_file_, file->reference->zi, 0); - _dbg_assert_(file->zf != nullptr); + file->pos = 0; } size_t ZipFileReader::Read(VFSOpenFile *vfsOpenFile, void *buffer, size_t length) { ZipFileReaderOpenFile *file = (ZipFileReaderOpenFile *)vfsOpenFile; _assert_(file); - _dbg_assert_(file->zf != nullptr); - return zip_fread(file->zf, buffer, length); + if (file->pos >= file->size) + return 0; + if (!file->decoded && file->pos == 0 && length >= file->size) { + // The whole member in one read: decode it where it's going. + std::lock_guard guard(lock_); + if (!zip_file_.ExtractInto(file->reference->zi, (uint8_t *)buffer, file->size)) + return 0; + file->pos = file->size; + return file->size; + } + if (!file->decoded) { + file->data.resize(file->size); + std::lock_guard guard(lock_); + if (!zip_file_.ExtractInto(file->reference->zi, file->data.data(), file->size)) + return 0; + file->decoded = true; + } + const size_t n = std::min(length, file->size - file->pos); + memcpy(buffer, file->data.data() + file->pos, n); + file->pos += n; + return n; } void ZipFileReader::CloseFile(VFSOpenFile *vfsOpenFile) { ZipFileReaderOpenFile *file = (ZipFileReaderOpenFile *)vfsOpenFile; _assert_(file); - _dbg_assert_(file->zf != nullptr); - zip_fclose(file->zf); - file->zf = nullptr; - vfsOpenFile = nullptr; - lock_.unlock(); delete file; } bool ReadSingleFileFromZip(Path zipFile, const char *path, std::string *data, std::mutex *mutex) { ZipContainer zip(zipFile); - if (zip == nullptr) { + if (!zip) { return false; } - struct zip_stat zstat; - if (zip_stat(zip, path, ZIP_FL_NOCASE | ZIP_FL_UNCHANGED, &zstat) != 0) { + const int index = zip.Find(path); + if (index < 0) { return false; } - if (zstat.size > MAX_ZIP_ENTRY_SIZE) { - ERROR_LOG(Log::IO, "Zip entry %s claims an implausible size (%llu), refusing to read", path, (unsigned long long)zstat.size); + const uint64_t size = zip.Size(index); + if (size > MAX_ZIP_ENTRY_SIZE) { + ERROR_LOG(Log::IO, "Zip entry %s claims an implausible size (%llu), refusing to read", path, (unsigned long long)size); return false; } - zip_file *file = zip_fopen_index(zip, zstat.index, ZIP_FL_UNCHANGED); - if (!file) { + std::string contents; + contents.resize((size_t)size); + if (!zip.ExtractInto(index, (uint8_t *)&contents[0], contents.size())) { return false; } if (mutex) { mutex->lock(); } - data->resize(zstat.size); - if (zip_fread(file, data->data(), zstat.size) != zstat.size) { - if (mutex) { - mutex->unlock(); - } - data->resize(0); - zip_fclose(file); - return false; - } + data->swap(contents); if (mutex) { mutex->unlock(); } - zip_fclose(file); return true; } diff --git a/Common/File/VFS/ZipFileReader.h b/Common/File/VFS/ZipFileReader.h index c2779d6a3b..10f25a8e50 100644 --- a/Common/File/VFS/ZipFileReader.h +++ b/Common/File/VFS/ZipFileReader.h @@ -1,40 +1,62 @@ #pragma once -#ifdef SHARED_LIBZIP -#include -#else -#include "ext/libzip/zip.h" -#endif - +#include +#include #include #include #include +#include +#include #include #include "Common/File/VFS/VFS.h" #include "Common/File/FileUtil.h" #include "Common/File/Path.h" +struct rzip_archive; +struct ZipFileSource; + +// A zip archive read with libretro-common's rzip_archive. The bytes come through +// a positioned read: from a file opened here, or from the caller's own source. class ZipContainer { public: - ZipContainer() noexcept; - ZipContainer(const Path &path); + // Positioned read of len bytes at off; returns bytes read, or negative on error. + typedef int64_t (*ReadFunc)(void *userdata, uint64_t off, void *dst, size_t len); + + ZipContainer() noexcept {} + explicit ZipContainer(const Path &path); + ZipContainer(ReadFunc read, void *userdata, uint64_t size); ~ZipContainer(); ZipContainer(const ZipContainer &) = delete; - ZipContainer(ZipContainer &&) noexcept; + ZipContainer(ZipContainer &&other) noexcept; ZipContainer &operator=(const ZipContainer &) = delete; - ZipContainer &operator=(ZipContainer &&) noexcept; + ZipContainer &operator=(ZipContainer &&other) noexcept; void close() noexcept; - operator zip_t *() const noexcept; + + explicit operator bool() const noexcept { return zip_ != nullptr; } + rzip_archive *Raw() const noexcept { return zip_; } + + int NumEntries() const; + const char *Name(int index) const; + uint64_t Size(int index) const; + bool IsDirectory(int index) const; + // Exact match, or ASCII case-insensitive when nocase is set. -1 if absent. + int Find(std::string_view name, bool nocase = true) const; + // The member decoded straight into dst, which has room for Size(index) bytes. + bool ExtractInto(int index, uint8_t *dst, size_t dstSize) const; + // The member decoded a piece at a time, each piece handed to sink as it comes out + // (sink returns false to stop), for members too big to hold. The CRC is checked. + bool ExtractTo(int index, const std::function &sink) const; private: - struct SourceData { - Path path; - FILE *file; - } *sourceData_; - zip_t *zip_; + void Open(uint64_t size); + static int64_t FileRead(void *userdata, uint64_t off, void *dst, size_t len); - static zip_int64_t SourceCallback(void *userdata, void *data, zip_uint64_t len, zip_source_cmd_t cmd); + rzip_archive *zip_ = nullptr; + ZipFileSource *source_ = nullptr; + ReadFunc read_ = nullptr; + void *userdata_ = nullptr; + std::unordered_map lowerIndex_; }; class ZipFileReader : public VFSBackend { @@ -42,7 +64,7 @@ public: static ZipFileReader *Create(const Path &zipFile, std::string_view inZipPath, bool logErrors = true); ~ZipFileReader(); - bool IsValid() const { return zip_file_ != nullptr; } + bool IsValid() const { return (bool)zip_file_; } // use delete[] on the returned value. uint8_t *ReadFile(std::string_view path, size_t *size) override; @@ -68,7 +90,7 @@ public: } private: - ZipFileReader(ZipContainer &&zip, const Path &zipPath, const std::string &inZipPath) : zip_file_(std::move(zip)), zipPath_(zipPath), inZipPath_(inZipPath) {} + ZipFileReader(ZipContainer &&zip, const Path &zipPath, const std::string &inZipPath) : zip_file_(std::move(zip)), inZipPath_(inZipPath), zipPath_(zipPath) {} // Path has to be either an empty string, or a string ending with a /. bool GetZipListings(const std::string &path, std::set &files, std::set &directories); @@ -79,5 +101,5 @@ private: }; // When you just want a single file from a ZIP, and don't care about accurate error reporting, use this. -// The buffer should be free'd with free. Mutex will be locked while updating data, if non-null. +// Mutex will be locked while updating data, if non-null. bool ReadSingleFileFromZip(Path zipFile, const char *path, std::string *data, std::mutex *mutex); diff --git a/Common/Render/AtlasGen.cpp b/Common/Render/AtlasGen.cpp index 9ebae1f570..28acab66d4 100644 --- a/Common/Render/AtlasGen.cpp +++ b/Common/Render/AtlasGen.cpp @@ -1,6 +1,5 @@ #include -#include #include #include #include diff --git a/Common/Render/TextureAtlas.cpp b/Common/Render/TextureAtlas.cpp index 627dd89c96..e75f7cfda1 100644 --- a/Common/Render/TextureAtlas.cpp +++ b/Common/Render/TextureAtlas.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include "Common/Log.h" #include "Common/Render/TextureAtlas.h" @@ -39,7 +39,9 @@ public: offset_ += sizeof(uint32_t); _dbg_assert_(offset_ + compressed_size <= size_); - ZSTD_decompress(t, sizeof(T) * count, data_ + offset_, compressed_size); + size_t wrote = 0; + if (rzstd_decode((uint8_t *)t, sizeof(T) * count, data_ + offset_, compressed_size, &wrote) != RZSTD_PROCESS_END) + memset((void *)t, 0, sizeof(T) * count); offset_ += compressed_size; } return t; diff --git a/Common/Serialize/Serializer.cpp b/Common/Serialize/Serializer.cpp index b222d60be9..0d13caceed 100644 --- a/Common/Serialize/Serializer.cpp +++ b/Common/Serialize/Serializer.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" @@ -433,10 +433,10 @@ CChunkFileReader::Error CChunkFileReader::LoadFile(const Path &filename, std::st auto status = snappy_uncompress((const char *)buffer, sz, (char *)uncomp_buffer, &uncomp_size); success = status == SNAPPY_OK; } else if (SerializeCompressType(header.Compress) == SerializeCompressType::ZSTD) { - size_t status = ZSTD_decompress((char *)uncomp_buffer, uncomp_size, (const char *)buffer, sz); - success = !ZSTD_isError(status); + size_t wrote = 0; + success = rzstd_decode(uncomp_buffer, uncomp_size, buffer, sz, &wrote) == RZSTD_PROCESS_END; if (success) { - uncomp_size = status; + uncomp_size = wrote; } } else { ERROR_LOG(Log::SaveState, "ChunkReader: Unexpected compression type %d", header.Compress); @@ -491,7 +491,7 @@ CChunkFileReader::Error CChunkFileReader::SaveFile(const Path &filename, const s write_len = snappy_max_compressed_length(sz); break; case SerializeCompressType::ZSTD: - write_len = ZSTD_compressBound(sz); + write_len = rzstd_compress_bound(sz); break; } u8 *compressed_buffer = write_len == 0 ? nullptr : (u8 *)malloc(write_len); @@ -512,20 +512,7 @@ CChunkFileReader::Error CChunkFileReader::SaveFile(const Path &filename, const s success = snappy_compress((const char *)buffer, sz, (char *)compressed_buffer, &write_len) == SNAPPY_OK; break; case SerializeCompressType::ZSTD: - { - auto ctx = ZSTD_createCCtx(); - if (!ctx) { - success = false; - } else { - // TODO: If free disk space is low, we could max this out to 22? - ZSTD_CCtx_setParameter(ctx, ZSTD_c_compressionLevel, ZSTD_CLEVEL_DEFAULT); - ZSTD_CCtx_setParameter(ctx, ZSTD_c_checksumFlag, 1); - ZSTD_CCtx_setPledgedSrcSize(ctx, sz); - write_len = ZSTD_compress2(ctx, compressed_buffer, write_len, buffer, sz); - success = !ZSTD_isError(write_len); - } - ZSTD_freeCCtx(ctx); - } + success = rzstd_encode(compressed_buffer, write_len, buffer, sz, 3, &write_len) == RZSTD_PROCESS_END; break; } diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index 31726d525c..4bc481a7c2 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -721,10 +721,6 @@ if((MACOSX OR IOS) AND NOT LIBRETRO) PROPERTIES COMPILE_FLAGS -fobjc-arc) endif() -if(LIBRETRO) - target_include_directories(Core PRIVATE ${CMAKE_SOURCE_DIR}/libretro/libretro-common/include) -endif() - set(CoreExtraLibs) if(ANDROID) list(APPEND CoreExtraLibs android) @@ -735,7 +731,7 @@ endif() list(APPEND CoreExtraLibs armips) -target_link_libraries(Core GPU Common chdr kirk cityhash sfmt19937 xbrz xxhash rcheevos at3_standalone lua +target_link_libraries(Core GPU Common libretro-common kirk cityhash sfmt19937 xbrz xxhash rcheevos at3_standalone lua aemu_postoffice_client ${CoreExtraLibs} ${CMAKE_DL_LIBS}) # Winsock @@ -762,7 +758,6 @@ if(FFmpeg_FOUND) FFmpeg::avutil FFmpeg::swresample FFmpeg::swscale - ${ZLIB_LIBRARY} ) elseif(BUILD_BUNDLED_FFMPEG) target_compile_definitions(Core PRIVATE USE_FFMPEG=1) @@ -773,7 +768,6 @@ elseif(BUILD_BUNDLED_FFMPEG) avutil swresample swscale - ${ZLIB_LIBRARY} ) endif() diff --git a/Core/Debugger/SymbolMap.cpp b/Core/Debugger/SymbolMap.cpp index a82a1f1ccf..c74bb3ffc1 100644 --- a/Core/Debugger/SymbolMap.cpp +++ b/Core/Debugger/SymbolMap.cpp @@ -34,7 +34,7 @@ #include #include -#include "zlib.h" +#include "Common/Data/Encoding/Compression.h" #include "ext/armips/Core/Assembler.h" @@ -82,31 +82,32 @@ void SymbolMap::Clear() { bool SymbolMap::LoadSymbolMap(const Path &filename) { Clear(); - // TODO(scoped): Use gzdopen instead. - -#if defined(_WIN32) && defined(UNICODE) - gzFile f = gzopen_w(filename.ToWString().c_str(), "r"); -#else - gzFile f = gzopen(filename.c_str(), "r"); -#endif - - if (f == Z_NULL) + // The map may be gzipped (bCompressSymbols) or plain text. + std::string contents; + if (!File::ReadBinaryFileToString(filename, &contents)) return false; - - //char temp[256]; - //fgets(temp,255,f); //.text section layout - //fgets(temp,255,f); // Starting Virtual - //fgets(temp,255,f); // address Size address - //fgets(temp,255,f); // ----------------------- + if (contents.size() >= 2 && (u8)contents[0] == 0x1f && (u8)contents[1] == 0x8b) { + std::string plain; + if (!decompress_string(contents, &plain)) + return false; + contents.swap(plain); + } + size_t pos = 0; bool started = false; bool hasModules = false; - while (!gzeof(f)) { + while (pos < contents.size()) { char line[512], temp[256] = {0}; - char *p = gzgets(f, line, 512); - if (p == NULL) - break; + size_t end = contents.find('\n', pos); + if (end == std::string::npos) + end = contents.size(); + const size_t len = std::min(end - pos, sizeof(line) - 1); + memcpy(line, contents.data() + pos, len); + line[len] = '\0'; + pos = end + 1; + if (len == 0) + continue; // Chop any newlines off. for (size_t i = strlen(line) - 1; i > 0; i--) { @@ -205,7 +206,6 @@ bool SymbolMap::LoadSymbolMap(const Path &filename) { } } } - gzclose(f); activeNeedUpdate_ = true; SortSymbols(); return started; @@ -233,81 +233,13 @@ bool SymbolMap::SaveSymbolMap(const Path &filename) const { std::string data; buf.TakeAll(&data); - FILE *file = File::OpenCFile(filename, "wb"); - if (file == nullptr) { - return false; - } if (g_Config.bCompressSymbols) { - uInt out_size = 4096; - Bytef *out_data = (Bytef *)std::malloc(out_size); - if (out_data == nullptr) { - fclose(file); + std::string compressed; + if (!compress_string(data, &compressed, 9, 31)) return false; - } - z_stream strm; - strm.zalloc = nullptr; - strm.zfree = nullptr; - strm.opaque = nullptr; - if (deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY) != Z_OK) { - std::free(out_data); - fclose(file); - return false; - } - strm.next_in = (Bytef *)data.data(); - strm.avail_in = (u32)data.size(); - strm.next_out = out_data; - strm.avail_out = out_size; - int flush = Z_NO_FLUSH; - for (;;) { - int status = deflate(&strm, flush); - switch (status) { - case Z_OK: - case Z_STREAM_END: - if (strm.avail_out != out_size) { - fwrite(out_data, 1, out_size - strm.avail_out, file); - } - break; - case Z_BUF_ERROR: - { - std::free(out_data); - uInt new_out_size = 2 * out_size; - if (new_out_size < out_size) { - deflateEnd(&strm); - fclose(file); - return false; - } - out_size = new_out_size; - out_data = (Bytef *)std::malloc(out_size); - if (out_data == nullptr) { - deflateEnd(&strm); - fclose(file); - return false; - } - } - break; - default: - deflateEnd(&strm); - std::free(out_data); - fclose(file); - return false; - } - if (status == Z_STREAM_END) { - break; - } - if (strm.avail_in == 0) { - flush = Z_FINISH; - } - strm.next_out = out_data; - strm.avail_out = out_size; - } - deflateEnd(&strm); - std::free(out_data); - } else { - // Just plain write it. - fwrite(data.data(), 1, data.size(), file); + data.swap(compressed); } - fclose(file); - return true; + return File::WriteDataToFile(false, data.data(), data.size(), filename); } bool SymbolMap::LoadNocashSym(const Path &filename) { diff --git a/Core/Debugger/WebSocket/GPUBufferSubscriber.cpp b/Core/Debugger/WebSocket/GPUBufferSubscriber.cpp index 89e7e14033..3be410ffee 100644 --- a/Core/Debugger/WebSocket/GPUBufferSubscriber.cpp +++ b/Core/Debugger/WebSocket/GPUBufferSubscriber.cpp @@ -16,8 +16,9 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include -#include -#include +#include + +#include "Common/Data/Format/PNGLoad.h" #include "Common/Data/Encoding/Base64.h" #include "Common/StringUtils.h" #include "Core/Debugger/WebSocket/GPUBufferSubscriber.h" @@ -61,22 +62,13 @@ static bool StreamBufferToDataURI(DebuggerRequest &req, const GPUDebugBuffer &bu h = totalPixels / w; } - png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if (!png_ptr) { - req.Fail("Internal error setting up PNG encoder (png_ptr)"); + std::vector png; + const bool encoded = pngEncode(&png, buffer, w, h, includeAlpha ? PNGFormat::RGBA8888 : PNGFormat::RGB888); + delete [] flipbuffer; + if (!encoded) { + req.Fail("Internal error encoding PNG"); return false; } - png_infop info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_write_struct(&png_ptr, nullptr); - req.Fail("Internal error setting up PNG encoder (info_ptr)"); - return false; - } - - // Speed. Wireless N should give 35 KB/ms. For most devices, zlib/filters will cost more. - png_set_compression_strategy(png_ptr, Z_RLE); - png_set_compression_level(png_ptr, 1); - png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_FILTER_NONE); auto &json = req.Respond(); json.writeInt("width", w); @@ -88,68 +80,12 @@ static bool StreamBufferToDataURI(DebuggerRequest &req, const GPUDebugBuffer &bu // Start a value... json.writeRaw("uri", ""); req.Flush(); - // Now we'll write it directly to the stream. + // Now we'll write it directly to the stream, in pieces that are a multiple of 3 bytes + // so the base64 has no padding until the end. req.ws->AddFragment(false, "\"data:image/png;base64,"); - - struct Context { - DebuggerRequest *req; - uint8_t buf[3]; - size_t bufSize; - }; - Context ctx = { &req, {}, 0 }; - - auto write = [](png_structp png_ptr, png_bytep data, png_size_t length) { - auto ctx = (Context *)png_get_io_ptr(png_ptr); - auto &req = *ctx->req; - - // If we buffered some bytes, fill to 3 bytes for a clean base64 encode. - // This way we don't have padding. - while (length > 0 && ctx->bufSize > 0 && ctx->bufSize != 3) { - ctx->buf[ctx->bufSize++] = data[0]; - data++; - length--; - } - - if (ctx->bufSize == 3) { - req.ws->AddFragment(false, Base64Encode(ctx->buf, ctx->bufSize)); - ctx->bufSize = 0; - } - _assert_(ctx->bufSize == 0 || length == 0); - - // Save bytes that would result in padding for next time. - size_t toBuffer = length % 3; - for (size_t i = 0; i < toBuffer; ++i) { - ctx->buf[i] = data[length - toBuffer + i]; - ctx->bufSize++; - } - - if (length > toBuffer) { - req.ws->AddFragment(false, Base64Encode(data, length - toBuffer)); - } - }; - auto flush = [](png_structp png_ptr) { - // Nothing, just here to prevent stdio flush. - }; - - png_bytep *row_pointers = new png_bytep[h]; - u32 stride = includeAlpha ? w * 4 : w * 3; - for (u32 i = 0; i < h; ++i) { - row_pointers[i] = (u8 *)buffer + stride * i; - } - - png_set_write_fn(png_ptr, &ctx, write, flush); - int colorType = includeAlpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB; - png_set_IHDR(png_ptr, info_ptr, w, h, 8, colorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - png_set_rows(png_ptr, info_ptr, row_pointers); - png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, nullptr); - - png_destroy_write_struct(&png_ptr, &info_ptr); - delete [] row_pointers; - delete [] flipbuffer; - - if (ctx.bufSize > 0) { - req.ws->AddFragment(false, Base64Encode(ctx.buf, ctx.bufSize)); - ctx.bufSize = 0; + const size_t piece = 3 * 16384; + for (size_t pos = 0; pos < png.size(); pos += piece) { + req.ws->AddFragment(false, Base64Encode(png.data() + pos, std::min(piece, png.size() - pos))); } // End the string. diff --git a/Core/FileLoaders/LocalFileLoader.cpp b/Core/FileLoaders/LocalFileLoader.cpp index 889c30d47e..ca05cbbb13 100644 --- a/Core/FileLoaders/LocalFileLoader.cpp +++ b/Core/FileLoaders/LocalFileLoader.cpp @@ -187,8 +187,18 @@ size_t LocalFileLoader::ReadAt(s64 absolutePos, size_t bytes, size_t count, void #if defined(HAVE_LIBRETRO_VFS) std::lock_guard guard(readLock_); - File::Fseek(file_, absolutePos, SEEK_SET); - return fread(data, bytes, count, file_); + // The VFS has no positioned read. Only seek when the read isn't sequential: + // a seek also throws away whatever the frontend's stream had buffered. + if (filePos_ != absolutePos) { + if (File::Fseek(file_, absolutePos, SEEK_SET) != 0) { + filePos_ = -1; + return 0; + } + filePos_ = absolutePos; + } + const size_t done = fread(data, 1, bytes * count, file_); + filePos_ = done == bytes * count ? filePos_ + (s64)done : -1; + return done / bytes; #elif PPSSPP_PLATFORM(SWITCH) // Toolchain has no fancy IO API. We must lock. std::lock_guard guard(readLock_); diff --git a/Core/FileLoaders/LocalFileLoader.h b/Core/FileLoaders/LocalFileLoader.h index ae0cb60cd8..785d5b5917 100644 --- a/Core/FileLoaders/LocalFileLoader.h +++ b/Core/FileLoaders/LocalFileLoader.h @@ -46,6 +46,7 @@ public: private: #ifdef HAVE_LIBRETRO_VFS FILE *file_ = nullptr; + s64 filePos_ = -1; // where file_ is; -1 when unknown #elif !defined(_WIN32) void DetectSizeFd(); int fd_ = -1; diff --git a/Core/FileLoaders/ZipFileLoader.cpp b/Core/FileLoaders/ZipFileLoader.cpp index 2411f68770..0436251fa8 100644 --- a/Core/FileLoaders/ZipFileLoader.cpp +++ b/Core/FileLoaders/ZipFileLoader.cpp @@ -1,69 +1,46 @@ -#ifdef SHARED_LIBZIP -#include -#else -#include "ext/libzip/zip.h" -#endif +#include #include "Core/FileLoaders/LocalFileLoader.h" #include "Core/FileLoaders/ZipFileLoader.h" +int64_t ZipFileLoader::BackendRead(void *userdata, uint64_t off, void *dst, size_t len) { + FileLoader *backend = (FileLoader *)userdata; + return (int64_t)backend->ReadAt((s64)off, len, dst); +} + ZipFileLoader::ZipFileLoader(FileLoader *sourceLoader) - : ProxiedFileLoader(sourceLoader), zipArchive_(nullptr) { + : ProxiedFileLoader(sourceLoader) { if (!backend_ || !backend_->Exists() || backend_->IsDirectory()) { return; } - - zip_error_t error{}; - zip_source_t* zipSource = zip_source_function_create([](void* userdata, void* data, zip_uint64_t len, zip_source_cmd_t cmd) -> zip_int64_t { - ZipFileLoader *loader = (ZipFileLoader *)userdata; - return loader->ZipSourceCallback(data, len, cmd); - }, this, &error); - if (!zipSource) { - ERROR_LOG(Log::IO, "Failed to create ZIP source: %s", zip_error_strerror(&error)); - return; - } - - zipArchive_ = zip_open_from_source(zipSource, ZIP_RDONLY, &error); - if (!zipArchive_) { - ERROR_LOG(Log::IO, "Failed to open ZIP archive: %s", zip_error_strerror(&error)); - zip_source_free(zipSource); - // zipArchive_ is already nullptr here. + zip_ = ZipContainer(&BackendRead, backend_, (uint64_t)backend_->FileSize()); + if (!zip_) { + ERROR_LOG(Log::IO, "Failed to open ZIP archive: %s", backend_->GetPath().c_str()); } } ZipFileLoader::~ZipFileLoader() { - if (dataFile_) { - zip_fclose(dataFile_); - } - if (zipArchive_) { - zip_discard(zipArchive_); - } - if (data_) { - free(data_); + if (seek_) { + rzip_seek_free(seek_); } } bool ZipFileLoader::Initialize(int fileIndex) { - _dbg_assert_(!data_); + _dbg_assert_(!initialized_); - if (!zipArchive_) { + if (!zip_) { ERROR_LOG(Log::IO, "Cannot initialize: ZIP archive is null"); return false; } - struct zip_stat zstat; - int retval = zip_stat_index(zipArchive_, fileIndex, ZIP_FL_NOCASE | ZIP_FL_UNCHANGED, &zstat); - if (retval < 0) { - return false; - } - const char *name = zip_get_name(zipArchive_, fileIndex, ZIP_FL_NOCASE | ZIP_FL_UNCHANGED); - if (!name) { - ERROR_LOG(Log::IO, "Failed to get name for file index %d", fileIndex); + const rzip_entry_t *entry = rzip_archive_entry(zip_.Raw(), (uint32_t)fileIndex); + if (!entry) { + ERROR_LOG(Log::IO, "Failed to get file index %d", fileIndex); return false; } // Callers (Identify_File and friends) compare against lowercase extensions, like // Path::GetFileExtension returns. Not using tolower to avoid the Turkish I problem. - fileExtension_ = KeepIncludingLast(name, '.'); + fileExtension_ = KeepIncludingLast(entry->name, '.'); for (size_t i = 0; i < fileExtension_.size(); i++) { char c = fileExtension_[i]; if (c >= 'A' && c <= 'Z') { @@ -71,32 +48,27 @@ bool ZipFileLoader::Initialize(int fileIndex) { } } - _dbg_assert_(zstat.index == fileIndex); - dataFileSize_ = zstat.size; - dataFile_ = zip_fopen_index(zipArchive_, zstat.index, ZIP_FL_UNCHANGED); - if (!dataFile_) { - ERROR_LOG(Log::IO, "Failed to open file index %d from ZIP", fileIndex); - return false; - } - - // Handle zero-size files - if (dataFileSize_ == 0) { - data_ = nullptr; - return true; - } - - data_ = (u8 *)malloc(dataFileSize_); - if (!data_) { - ERROR_LOG(Log::IO, "Failed to allocate %lld bytes for ZIP file data", (long long)dataFileSize_); - zip_fclose(dataFile_); - dataFile_ = nullptr; - return false; + dataFileSize_ = (s64)entry->size; + if (entry->method == RZIP_METHOD_STORED) { + if (entry->csize != entry->size) { + ERROR_LOG(Log::IO, "Stored ZIP member %d has mismatched sizes", fileIndex); + return false; + } + stored_ = true; + dataOffset_ = entry->data_off; + } else { + seek_ = rzip_seek_new(zip_.Raw(), (uint32_t)fileIndex, 0); + if (!seek_) { + ERROR_LOG(Log::IO, "Can't read ZIP member %d (method %u)", fileIndex, entry->method); + return false; + } } + initialized_ = true; return true; } size_t ZipFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags) { - if (!dataFile_ || absolutePos < 0 || absolutePos >= dataFileSize_) { + if (!initialized_ || absolutePos < 0 || absolutePos >= dataFileSize_) { return 0; } @@ -104,90 +76,24 @@ size_t ZipFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags fl bytes = dataFileSize_ - absolutePos; } - // Decompress until the requested point, filling up data_ as we go. TODO: Do on thread. - while (dataReadPos_ < absolutePos + (s64)bytes) { - int remaining = BLOCK_SIZE; - if (dataReadPos_ + remaining > dataFileSize_) { - remaining = (int)(dataFileSize_ - dataReadPos_); - } - zip_int64_t retval = zip_fread(dataFile_, data_ + dataReadPos_, remaining); - if (retval < 0) { - ERROR_LOG(Log::IO, "zip_fread failed with error code %lld", (long long)retval); - return 0; - } - if (retval != remaining) { - ERROR_LOG(Log::IO, "zip_fread: expected %d bytes, got %lld", remaining, (long long)retval); - return 0; - } - dataReadPos_ += retval; + if (stored_) { + return backend_->ReadAt((s64)dataOffset_ + absolutePos, bytes, data, flags); } - // Perform the read. - memcpy(data, data_ + absolutePos, bytes); + // Index on until the range is covered, then decode from the nearest point. + const uint64_t end = (uint64_t)absolutePos + bytes; + while (rzip_seek_covered(seek_) < end) { + const int state = rzip_seek_build(seek_, end); + if (state < 0) { + ERROR_LOG(Log::IO, "ZIP member is corrupt (%d)", state); + return 0; + } + if (state == 1) + break; + } + if (rzip_seek_read(seek_, (uint64_t)absolutePos, (uint8_t *)data, bytes) != RZIP_OK) { + ERROR_LOG(Log::IO, "ZIP read failed at %lld", (long long)absolutePos); + return 0; + } return bytes; } - -zip_int64_t ZipFileLoader::ZipSourceCallback(void *data, zip_uint64_t len, zip_source_cmd_t cmd) { - switch (cmd) { - case ZIP_SOURCE_OPEN: - { - zipReadPos_ = 0; - return 0; - } - case ZIP_SOURCE_READ: - { - size_t readBytes = backend_->ReadAt(zipReadPos_, len, data); - zipReadPos_ += readBytes; - return static_cast(readBytes); - } - case ZIP_SOURCE_SEEK: - { - if (len < sizeof(zip_source_args_seek_t)) { - return -1; - } - const zip_source_args_seek_t *seekArgs = (const zip_source_args_seek_t *)data; - zip_int64_t new_offset; - switch (seekArgs->whence) { - case SEEK_SET: - new_offset = seekArgs->offset; - break; - case SEEK_CUR: - new_offset = zipReadPos_ + seekArgs->offset; - break; - case SEEK_END: - new_offset = backend_->FileSize() + seekArgs->offset; - break; - default: - return -1; - } - if (new_offset < 0 || new_offset > backend_->FileSize()) { - return -1; - } - zipReadPos_ = new_offset; - return 0; - } - case ZIP_SOURCE_TELL: - return zipReadPos_; - case ZIP_SOURCE_CLOSE: - return 0; - case ZIP_SOURCE_STAT: - { - if (len < sizeof(zip_stat_t)) { - return -1; - } - zip_stat_t* st = static_cast(data); - zip_stat_init(st); - st->valid = ZIP_STAT_SIZE; - st->size = static_cast(backend_->FileSize()); - return sizeof(zip_stat_t); - } - case ZIP_SOURCE_ERROR: - return -1; - case ZIP_SOURCE_FREE: - return 0; - case ZIP_SOURCE_SUPPORTS: - return zip_source_make_command_bitmap(ZIP_SOURCE_READ, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_OPEN, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, -1); - default: - return -1; - } -} diff --git a/Core/FileLoaders/ZipFileLoader.h b/Core/FileLoaders/ZipFileLoader.h index cc7c394fd7..ad474e687c 100644 --- a/Core/FileLoaders/ZipFileLoader.h +++ b/Core/FileLoaders/ZipFileLoader.h @@ -1,34 +1,32 @@ #pragma once -#include - -#ifdef SHARED_LIBZIP -#include -#else -#include "ext/libzip/zip.h" -#endif - #include "Common/CommonTypes.h" #include "Common/Log.h" #include "Common/File/Path.h" +#include "Common/File/VFS/ZipFileReader.h" #include "Common/StringUtils.h" #include "Core/Loaders.h" +struct rzip_seek; + // Exposes a single (chosen) file from a zip file as another file loader. // Useful in a bunch of possible chains. +// A stored member is read straight from the backend at its offset. A deflated one +// goes through an rzip_seek index, built as far as reads reach: restart points +// every megabyte and a few decoded spans, instead of the whole member in memory. class ZipFileLoader : public ProxiedFileLoader { public: ZipFileLoader(FileLoader *sourceLoader); ~ZipFileLoader() override; - zip_t *GetZip() const { - return zipArchive_; + const ZipContainer &GetZip() const { + return zip_; } bool Initialize(int fileIndex); bool Exists() override { - return dataFile_ != nullptr; + return initialized_; } bool IsDirectory() override { @@ -53,17 +51,13 @@ public: } private: - zip_int64_t ZipSourceCallback(void* data, zip_uint64_t len, zip_source_cmd_t cmd); + static int64_t BackendRead(void *userdata, uint64_t off, void *dst, size_t len); - enum { - BLOCK_SIZE = 65536, - }; - zip_t *zipArchive_ = nullptr; - s64 zipReadPos_ = 0; - - zip_file_t *dataFile_ = nullptr; - uint8_t *data_ = nullptr; // malloc/free - s64 dataReadPos_ = 0; + ZipContainer zip_; + bool initialized_ = false; + bool stored_ = false; + u64 dataOffset_ = 0; // stored members: where the bytes start in the zip + struct rzip_seek *seek_ = nullptr; // deflated members s64 dataFileSize_ = 0; std::string fileExtension_; }; diff --git a/Core/FileSystems/BlockDevices.cpp b/Core/FileSystems/BlockDevices.cpp index 68d9469860..b872e1b14d 100644 --- a/Core/FileSystems/BlockDevices.cpp +++ b/Core/FileSystems/BlockDevices.cpp @@ -33,9 +33,11 @@ #include "Core/FileSystems/BlockDevices.h" #include "Core/FileSystems/ISOFileSystem.h" #include "Core/Util/PathUtil.h" -#include "libchdr/chd.h" +#include -#include "zlib.h" +#include + +#include "Common/Data/Encoding/Compression.h" #include "ext/libkirk/amctrl.h" #include "ext/libkirk/kirk_engine.h" @@ -321,6 +323,51 @@ bool FileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached) { return true; } +bool BlockDevice::ReadBytes(u64 offset, size_t len, u8 *out) { + const size_t blockSize = GetBlockSize(); + u32 block = (u32)(offset / blockSize); + const size_t skip = (size_t)(offset % blockSize); + bool ok = true; + if (skip != 0 && len > 0) { + u8 sector[2048]; + const size_t n = std::min(len, blockSize - skip); + // A failed read must not hand out uninitialized stack. + if (!ReadBlock(block++, sector)) { + memset(sector, 0, sizeof(sector)); + ok = false; + } + memcpy(out, sector + skip, n); + out += n; + len -= n; + } + if (len >= blockSize) { + const u32 count = (u32)(len / blockSize); + ok = ReadBlocks(block, count, out) && ok; + block += count; + out += (size_t)count * blockSize; + len -= (size_t)count * blockSize; + } + if (len > 0) { + u8 sector[2048]; + if (!ReadBlock(block, sector)) { + memset(sector, 0, sizeof(sector)); + ok = false; + } + memcpy(out, sector, len); + } + return ok; +} + +bool FileBlockDevice::ReadBytes(u64 offset, size_t len, u8 *out) { + // A plain image is the bytes themselves: one read, no sector staging. + const size_t got = fileLoader_->ReadAt(offset, len, out); + if (got < len) { + memset(out + got, 0, len - got); + return false; + } + return true; +} + bool FileBlockDevice::ReadBlocks(u32 minBlock, int count, u8 *outPtr) { size_t retval = fileLoader_->ReadAt((u64)minBlock * (u64)GetBlockSize(), 2048, count, outPtr); if (retval != (size_t)count) { @@ -608,6 +655,7 @@ CISOFileBlockDevice::CISOFileBlockDevice(FileLoader *fileLoader) readBufferSize = CSO_READ_BUFFER_SIZE; readBuffer = new u8[readBufferSize]; zlibBuffer = new u8[frameSize + (1u << indexShift)]; + inflate_ = rinflate_new(-15); zlibBufferFrame = numFrames; const u32 indexSize = (u32)indexSize64; @@ -662,6 +710,8 @@ CISOFileBlockDevice::~CISOFileBlockDevice() delete [] index; delete [] readBuffer; delete [] zlibBuffer; + if (inflate_) + rinflate_free(inflate_); } bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached) @@ -676,7 +726,6 @@ bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached) const u32 idx = index[frameNumber]; const u32 indexPos = idx & 0x7FFFFFFF; const u32 nextIndexPos = index[frameNumber + 1] & 0x7FFFFFFF; - z_stream z{}; const u64 compressedReadPos = (u64)indexPos << indexShift; const u64 compressedReadEnd = (u64)nextIndexPos << indexShift; @@ -700,35 +749,17 @@ bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached) } else { const u32 readSize = (u32)fileLoader_->ReadAt(compressedReadPos, 1, compressedReadSize, readBuffer, flags); - z.zalloc = Z_NULL; - z.zfree = Z_NULL; - z.opaque = Z_NULL; - if (inflateInit2(&z, -15) != Z_OK) { - ERROR_LOG(Log::Loader, "GetBlockSize() ERROR: %s\n", (z.msg) ? z.msg : "?"); + // A one-block frame inflates straight into the caller's buffer. + u8 *dst = frameSize == (u32)GetBlockSize() ? outPtr : zlibBuffer; + const int64_t produced = inflate_ ? InflateBuffer(inflate_, -15, readBuffer, readSize, dst, frameSize) : -1; + if (produced != (int64_t)frameSize) { + ERROR_LOG(Log::Loader, "block %d: inflate failed (%d of %d bytes)", blockNumber, (int)produced, frameSize); NotifyReadError(); - return false; - } - z.avail_in = readSize; - z.next_out = frameSize == (u32)GetBlockSize() ? outPtr : zlibBuffer; - z.avail_out = frameSize; - z.next_in = readBuffer; - - int status = inflate(&z, Z_FINISH); - if (status != Z_STREAM_END) { - ERROR_LOG(Log::Loader, "block %d: inflate : %s[%d]\n", blockNumber, (z.msg) ? z.msg : "error", status); - NotifyReadError(); - inflateEnd(&z); + if (dst == zlibBuffer) + zlibBufferFrame = numFrames; // partly overwritten memset(outPtr, 0, GetBlockSize()); return false; } - if (z.total_out != frameSize) { - ERROR_LOG(Log::Loader, "block %d: block size error %d != %d\n", blockNumber, (u32)z.total_out, frameSize); - NotifyReadError(); - inflateEnd(&z); - memset(outPtr, 0, GetBlockSize()); - return false; - } - inflateEnd(&z); if (frameSize != (u32)GetBlockSize()) { zlibBufferFrame = frameNumber; @@ -758,9 +789,8 @@ bool CISOFileBlockDevice::ReadBlocks(u32 minBlock, int count, u8 *outPtr) { const u32 afterLastIndexPos = index[lastFrameNumber + 1] & 0x7FFFFFFF; const u64 totalReadEnd = (u64)afterLastIndexPos << indexShift; - z_stream z{}; - if (inflateInit2(&z, -15) != Z_OK) { - ERROR_LOG(Log::Loader, "Unable to initialize inflate: %s\n", (z.msg) ? z.msg : "?"); + if (!inflate_) { + ERROR_LOG(Log::Loader, "Unable to initialize inflate"); return false; } @@ -803,34 +833,26 @@ bool CISOFileBlockDevice::ReadBlocks(u32 minBlock, int count, u8 *outPtr) { if (plain) { memcpy(outPtr, rawBuffer + frameBlockOffset * GetBlockSize(), frameBlocks * GetBlockSize()); } else { - z.avail_in = frameReadSize; - z.next_out = frameBlocks == blocksPerFrame ? outPtr : zlibBuffer; - z.avail_out = frameSize; - z.next_in = rawBuffer; - - int status = inflate(&z, Z_FINISH); - if (status != Z_STREAM_END) { - ERROR_LOG(Log::Loader, "Inflate frame %d: failed - %s[%d]\n", frame, (z.msg) ? z.msg : "error", status); - NotifyReadError(); - memset(outPtr, 0, frameBlocks * GetBlockSize()); - } else if (z.total_out != frameSize) { - ERROR_LOG(Log::Loader, "Inflate frame %d: block size error %d != %d\n", frame, (u32)z.total_out, frameSize); + // Whole frames inflate straight into the caller's buffer. + u8 *dst = frameBlocks == blocksPerFrame ? outPtr : zlibBuffer; + const int64_t produced = InflateBuffer(inflate_, -15, rawBuffer, frameReadSize, dst, frameSize); + if (produced != (int64_t)frameSize) { + ERROR_LOG(Log::Loader, "Inflate frame %d: failed (%d of %d bytes)", frame, (int)produced, frameSize); NotifyReadError(); + if (dst == zlibBuffer) + zlibBufferFrame = numFrames; // partly overwritten memset(outPtr, 0, frameBlocks * GetBlockSize()); } else if (frameBlocks != blocksPerFrame) { memcpy(outPtr, zlibBuffer + frameBlockOffset * GetBlockSize(), frameBlocks * GetBlockSize()); // In case we end up reusing it in a single read later. zlibBufferFrame = frame; } - - inflateReset(&z); } block += frameBlocks; outPtr += frameBlocks * GetBlockSize(); } - inflateEnd(&z); return true; } @@ -1051,172 +1073,118 @@ bool NPDRMDemoBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached) return true; } -struct CHDImpl { - chd_file *chd = nullptr; - const chd_header *header = nullptr; -}; +// rchd does no I/O: it names the byte ranges it needs and is fed them. +// Those ranges go straight from the loader into one scratch buffer the +// decoder borrows, so a hunk's compressed bytes are never copied twice. +static bool CHDServe(rchd_t *chd, FileLoader *loader, std::vector &scratch, const rchd_request_t &req, bool borrow) { + if (req.source != RCHD_SOURCE_SELF) + return false; + if (scratch.size() < req.length) + scratch.resize(req.length); + const size_t got = loader->ReadAt(req.offset, req.length, scratch.data()); + if (got == 0) + return false; + if (borrow) + return rchd_feed_borrow(chd, req.offset, req.source, scratch.data(), got) == RCHD_OK; + return rchd_feed(chd, scratch.data(), got) == RCHD_OK; +} -struct ExtendedCoreFile { - core_file core; // Must be the first struct member, for some tricky pointer casts. - uint64_t seekPos; -}; +static const char *CHDErrorString(int err) { + switch (err) { + case RCHD_ERROR_DATA: return "invalid data"; + case RCHD_ERROR_PARAM: return "invalid parameter"; + case RCHD_ERROR_MEM: return "out of memory"; + case RCHD_ERROR_UNSUPPORTED: return "unsupported format"; + case RCHD_ERROR_CRC: return "checksum mismatch"; + case RCHD_ERROR_NO_PARENT: return "parent CHD not supported"; + case RCHD_ERROR_STATE: return "invalid state"; + default: return "error"; + } +} CHDFileBlockDevice::CHDFileBlockDevice(FileLoader *fileLoader) - : BlockDevice(fileLoader), impl_(new CHDImpl()) { - Path paths[8]; - paths[0] = fileLoader->GetPath(); - int depth = 0; - - core_file_ = new ExtendedCoreFile(); - core_file_->core.argp = fileLoader; - core_file_->core.fsize = [](core_file *file) -> uint64_t { - FileLoader *loader = (FileLoader *)file->argp; - return loader->FileSize(); - }; - core_file_->core.fseek = [](core_file *file, int64_t offset, int seekType) -> int { - ExtendedCoreFile *coreFile = (ExtendedCoreFile *)file; - switch (seekType) { - case SEEK_SET: - coreFile->seekPos = offset; - break; - case SEEK_CUR: - coreFile->seekPos += offset; - break; - case SEEK_END: - { - FileLoader *loader = (FileLoader *)file->argp; - coreFile->seekPos = loader->FileSize() + offset; - break; - } - default: - break; - } - return 0; - }; - core_file_->core.fread = [](void *out_data, size_t size, size_t count, core_file *file) { - ExtendedCoreFile *coreFile = (ExtendedCoreFile *)file; - FileLoader *loader = (FileLoader *)file->argp; - uint64_t totalSize = size * count; - loader->ReadAt(coreFile->seekPos, totalSize, out_data); - coreFile->seekPos += totalSize; - return size * count; - }; - core_file_->core.fclose = [](core_file *file) { - ExtendedCoreFile *coreFile = (ExtendedCoreFile *)file; - delete coreFile; - return 0; - }; - - /* - // TODO: Support parent/child CHD files. - - // Default, in case of failure - numBlocks = 0; - - chd_header childHeader; - - chd_error err = chd_read_header(paths[0].c_str(), &childHeader); - if (err != CHDERR_NONE) { - ERROR_LOG(Log::Loader, "Error loading CHD header for '%s': %s", paths[0].c_str(), chd_error_string(err)); - NotifyReadError(); + : BlockDevice(fileLoader) { + chd_ = rchd_new(); + if (!chd_) { + errorString_ = "CHD error: out of memory"; return; } - // static const UINT8 nullsha1[CHD_SHA1_BYTES] = { 0 }; - if (memcmp(nullsha1, childHeader.parentsha1, sizeof(childHeader.sha1)) != 0) { - chd_header parentHeader; - - // Look for parent CHD in current directory - Path chdDir = paths[0].NavigateUp(); - - std::vector files; - if (File::GetFilesInDir(chdDir, &files)) { - parentHeader.length = 0; - - for (const auto &file : files) { - std::string extension = file.fullName.GetFileExtension(); - if (extension != ".chd") { - continue; - } - - if (chd_read_header(filepath.c_str(), &parentHeader) == CHDERR_NONE && - memcmp(parentHeader.sha1, childHeader.parentsha1, sizeof(parentHeader.sha1)) == 0) { - // ERROR_LOG(Log::Loader, "Checking '%s'", filepath.c_str()); - paths[++depth] = filepath; - break; - } - } - - // Check if parentHeader was opened - if (parentHeader.length == 0) { - ERROR_LOG(Log::Loader, "Error loading CHD '%s': parents not found", fileLoader->GetPath().c_str()); - NotifyReadError(); - return; - } - memcpy(childHeader.parentsha1, parentHeader.parentsha1, sizeof(childHeader.parentsha1)); - } while (memcmp(nullsha1, childHeader.parentsha1, sizeof(childHeader.sha1)) != 0); + int err; + rchd_request_t req; + while ((err = rchd_open_step(chd_, &req)) == RCHD_PENDING) { + if (!CHDServe(chd_, fileLoader, scratch_, req, false)) { + err = req.source == RCHD_SOURCE_SELF ? RCHD_ERROR_DATA : RCHD_ERROR_NO_PARENT; + break; + } } - */ - - chd_file *file = nullptr; - chd_error err = chd_open_core_file(&core_file_->core, CHD_OPEN_READ, NULL, &file); - if (err != CHDERR_NONE) { - errorString_ = StringFromFormat("CHD error: %s: %s", paths[depth].c_str(), chd_error_string(err)); + const rchd_info_t *info = err == RCHD_OK ? rchd_info(chd_) : nullptr; + if (info && info->has_parent) + err = RCHD_ERROR_NO_PARENT; + if (!info || err != RCHD_OK || info->unit_bytes != (u32)GetBlockSize()) { + if (err == RCHD_OK) + err = RCHD_ERROR_UNSUPPORTED; + errorString_ = StringFromFormat("CHD error: %s: %s", fileLoader->GetPath().c_str(), CHDErrorString(err)); + rchd_free(chd_); + chd_ = nullptr; return; } - impl_->chd = file; - impl_->header = chd_get_header(impl_->chd); - - readBuffer = new u8[impl_->header->hunkbytes]; - currentHunk = -1; - blocksPerHunk = impl_->header->hunkbytes / impl_->header->unitbytes; - numBlocks = impl_->header->unitcount; - + numBlocks = (u32)(info->logical_bytes / info->unit_bytes); _dbg_assert_(errorString_.empty()); } CHDFileBlockDevice::~CHDFileBlockDevice() { - if (impl_->chd) { - chd_close(impl_->chd); - delete[] readBuffer; - } + rchd_free(chd_); } bool CHDFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached) { - if (!impl_->chd) { - ERROR_LOG(Log::Loader, "ReadBlock: CHD not open. %s", fileLoader_->GetPath().c_str()); - return false; - } - if ((u32)blockNumber >= numBlocks) { - memset(outPtr, 0, GetBlockSize()); - return false; - } - u32 hunk = blockNumber / blocksPerHunk; - u32 blockInHunk = blockNumber % blocksPerHunk; + return ReadBlocks((u32)blockNumber, 1, outPtr); +} - if (currentHunk != hunk) { - chd_error err = chd_read(impl_->chd, hunk, readBuffer); - if (err != CHDERR_NONE) { - ERROR_LOG(Log::Loader, "CHD read failed: %d %d %s", blockNumber, hunk, chd_error_string(err)); - NotifyReadError(); +bool CHDFileBlockDevice::ReadRange(u64 offset, size_t len, u8 *out) { + int err = rchd_read_begin(chd_, offset, out, len); + rchd_request_t req; + if (err == RCHD_OK) { + while ((err = rchd_read_step(chd_, &req)) == RCHD_PENDING) { + if (!CHDServe(chd_, fileLoader_, scratch_, req, true)) { + err = RCHD_ERROR_DATA; + break; + } } - currentHunk = hunk; } - memcpy(outPtr, readBuffer + blockInHunk * impl_->header->unitbytes, GetBlockSize()); + if (err != RCHD_OK) { + ERROR_LOG(Log::Loader, "CHD read failed at %llu (%d bytes): %s", (unsigned long long)offset, (int)len, CHDErrorString(err)); + NotifyReadError(); + return false; + } return true; } +bool CHDFileBlockDevice::ReadBytes(u64 offset, size_t len, u8 *out) { + // rchd addresses bytes, so a file read decodes straight into place. + if (!chd_ || offset + len > (u64)numBlocks * GetBlockSize()) + return BlockDevice::ReadBytes(offset, len, out); + return ReadRange(offset, len, out); +} + bool CHDFileBlockDevice::ReadBlocks(u32 minBlock, int count, u8 *outPtr) { - if (minBlock >= numBlocks) { - memset(outPtr, 0, GetBlockSize() * count); + const size_t blockSize = GetBlockSize(); + if (!chd_) { + ERROR_LOG(Log::Loader, "ReadBlocks: CHD not open. %s", fileLoader_->GetPath().c_str()); + memset(outPtr, 0, blockSize * count); return false; } - - for (int i = 0; i < count; i++) { - if (!ReadBlock(minBlock + i, outPtr + i * GetBlockSize())) { - return false; - } + if (minBlock >= numBlocks || count <= 0) { + memset(outPtr, 0, blockSize * std::max(count, 0)); + return false; } - return true; + // The tail past the image reads as zeros, like the other devices. + const u32 avail = std::min((u32)count, numBlocks - minBlock); + if (avail < (u32)count) + memset(outPtr + avail * blockSize, 0, (count - avail) * blockSize); + + if (!ReadRange((u64)minBlock * blockSize, avail * blockSize, outPtr)) + return false; + return avail == (u32)count; } diff --git a/Core/FileSystems/BlockDevices.h b/Core/FileSystems/BlockDevices.h index 826134c0b0..d3f45ae67d 100644 --- a/Core/FileSystems/BlockDevices.h +++ b/Core/FileSystems/BlockDevices.h @@ -25,6 +25,7 @@ #include #include +#include #include "Common/CommonTypes.h" @@ -46,6 +47,10 @@ public: } return true; } + // Bytes [offset, offset + len) of the image, at any alignment. The default reads the + // partial blocks at either end through a sector buffer; devices that can address bytes + // read straight into out instead. + virtual bool ReadBytes(u64 offset, size_t len, u8 *out); int constexpr GetBlockSize() const { return 2048;} // forced, it cannot be changed by subclasses. If a subclass uses bigger blocks internally, it must cache and virtualize. virtual u32 GetNumBlocks() const = 0; virtual u64 GetUncompressedSize() const { @@ -80,6 +85,7 @@ private: size_t readBufferSize = 0; u8 *zlibBuffer = nullptr; u32 zlibBufferFrame = 0; + void *inflate_ = nullptr; // one rinflate stream, reset per frame u8 indexShift = 0; u8 blockShift = 0; u32 frameSize = 0; @@ -94,6 +100,7 @@ public: ~FileBlockDevice(); bool ReadBlock(int blockNumber, u8 *outPtr, bool uncached = false) override; bool ReadBlocks(u32 minBlock, int count, u8 *outPtr) override; + bool ReadBytes(u64 offset, size_t len, u8 *out) override; u32 GetNumBlocks() const override {return (u32)(filesize_ / GetBlockSize());} bool IsDisc() const override { return true; } u64 GetUncompressedSize() const override { @@ -194,9 +201,7 @@ private: KirkState kirk_{}; }; -struct CHDImpl; - -struct ExtendedCoreFile; +struct rchd; class CHDFileBlockDevice : public BlockDevice { public: @@ -204,14 +209,13 @@ public: ~CHDFileBlockDevice(); bool ReadBlock(int blockNumber, u8 *outPtr, bool uncached = false) override; bool ReadBlocks(u32 minBlock, int count, u8 *outPtr) override; + bool ReadBytes(u64 offset, size_t len, u8 *out) override; u32 GetNumBlocks() const override { return numBlocks; } bool IsDisc() const override { return true; } private: - struct ExtendedCoreFile *core_file_ = nullptr; - std::unique_ptr impl_; - u8 *readBuffer = nullptr; - u32 currentHunk = 0; - u32 blocksPerHunk = 0; + bool ReadRange(u64 offset, size_t len, u8 *out); + struct rchd *chd_ = nullptr; + std::vector scratch_; // compressed bytes, borrowed by the decoder u32 numBlocks = 0; }; diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index aae8acc549..bb3244930d 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -520,22 +520,7 @@ int ISOFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outd int block = (u16)desc.firstLETableSector; u32 size = Memory::ClampValidSizeAt(outdataPtr, (u32)desc.pathTableLength); u8 *out = Memory::GetPointerWriteRangeOrException(outdataPtr, size); - - int blocks = size / blockDevice->GetBlockSize(); - blockDevice->ReadBlocks(block, blocks, out); - size -= blocks * blockDevice->GetBlockSize(); - out += blocks * blockDevice->GetBlockSize(); - - // The remaining (or, usually, only) partial sector. - if (size > 0) { - u8 temp[2048]; - // `blocks` whole sectors starting at `block` were already consumed by - // ReadBlocks() above, so the trailing partial sector is the next one. - if (!blockDevice->ReadBlock(block + blocks, temp)) { - memset(temp, 0, sizeof(temp)); - } - memcpy(out, temp, size); - } + blockDevice->ReadBytes((u64)block * blockDevice->GetBlockSize(), size, out); return 0; } } @@ -617,44 +602,10 @@ size_t ISOFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size, int &usec) { } // Okay, we have size and position, let's rock. - const int firstBlockOffset = positionOnIso & 2047; - const int firstBlockSize = firstBlockOffset == 0 ? 0 : (int)std::min(size, 2048LL - firstBlockOffset); - const int lastBlockSize = (size - firstBlockSize) & 2047; - const s64 middleSize = size - firstBlockSize - lastBlockSize; - _dbg_assert_((middleSize & 2047) == 0); - - u32 secNum = (u32)(positionOnIso / 2048); - u8 theSector[2048]; - - if ((middleSize & 2047) != 0) { - ERROR_LOG(Log::FileSystem, "Remaining size should be aligned"); - } - - const u8 *const start = pointer; - if (firstBlockSize > 0) { - // theSector is uninitialized stack memory, so on a failed read we must not copy it out - - // that would hand host stack contents to the game. - if (!blockDevice->ReadBlock(secNum++, theSector)) { - memset(theSector, 0, sizeof(theSector)); - } - memcpy(pointer, theSector + firstBlockOffset, firstBlockSize); - pointer += firstBlockSize; - } - if (middleSize > 0) { - const u32 middleSectors = (u32)(middleSize / 2048); - blockDevice->ReadBlocks(secNum, middleSectors, pointer); - secNum += middleSectors; - pointer += middleSize; - } - if (lastBlockSize > 0) { - if (!blockDevice->ReadBlock(secNum++, theSector)) { - memset(theSector, 0, sizeof(theSector)); - } - memcpy(pointer, theSector, lastBlockSize); - pointer += lastBlockSize; - } - - size_t totalBytes = pointer - start; + blockDevice->ReadBytes(positionOnIso, (size_t)size, pointer); + // The sector after the last one touched, for the seek-time estimate. + const u32 secNum = (u32)(size > 0 ? (positionOnIso + size + 2047) / 2048 : positionOnIso / 2048); + const size_t totalBytes = (size_t)size; if (abs((int)lastReadBlock_ - (int)secNum) > 100) { // This is an estimate, sometimes it takes 1+ seconds, but it definitely takes time. usec = 100000; diff --git a/Core/HLE/sceAdler.cpp b/Core/HLE/sceAdler.cpp index 3632116b8a..e3b10d345d 100644 --- a/Core/HLE/sceAdler.cpp +++ b/Core/HLE/sceAdler.cpp @@ -15,11 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#ifdef SHARED_ZLIB -#include -#else -#include "../ext/zlib/zlib.h" -#endif +#include "Common/Data/Encoding/Compression.h" #include "sceAdler.h" #include "Common/Log.h" @@ -34,7 +30,7 @@ static u32 sceAdler32(u32 adler, u32 data, u32 datalen) { INFO_LOG(Log::sceMisc, "sceAdler32(adler=%08x, data=%08x, datalen=%08x)", adler, data, datalen); u8 *buf = Memory::GetPointerWriteUnchecked(data); - u32 ret = adler32(adler, buf, datalen); + u32 ret = Adler32(adler, buf, datalen); return ret; } diff --git a/Core/HLE/sceDeflt.cpp b/Core/HLE/sceDeflt.cpp index 4f1aa57769..1681c725ec 100644 --- a/Core/HLE/sceDeflt.cpp +++ b/Core/HLE/sceDeflt.cpp @@ -15,9 +15,10 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "zlib.h" +#include #include "Common/CommonTypes.h" +#include "Common/Data/Encoding/Compression.h" #include "Core/Debugger/MemBlockInfo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" @@ -35,49 +36,41 @@ static int CommonDecompress(int windowBits, u32 OutBuffer, int OutBufferLength, return hleLogError(Log::HLE, 0, "bad crc32 address"); } - z_stream stream{}; u8 *outBufferPtr = Memory::GetPointerWriteOrException(OutBuffer); - stream.next_in = (Bytef*)Memory::GetPointerOrException(InBuffer); + const u8 *inBufferPtr = Memory::GetPointerOrException(InBuffer); // We don't know the available length, just let it use as much as it wants. - stream.avail_in = (uInt)Memory::ClampValidSizeAt(InBuffer, Memory::g_MemorySize); - stream.next_out = outBufferPtr; - stream.avail_out = (uInt)OutBufferLength; + const size_t inAvail = Memory::ClampValidSizeAt(InBuffer, Memory::g_MemorySize); + const size_t outAvail = OutBufferLength > 0 ? Memory::ClampValidSizeAt(OutBuffer, (u32)OutBufferLength) : 0; - int err = inflateInit2(&stream, windowBits); - if (err != Z_OK) { - return hleLogError(Log::HLE, 0, "inflateInit2 failed %08x", err); - } - err = inflate(&stream, Z_FINISH); - inflateEnd(&stream); - - if (err != Z_STREAM_END) { - return hleLogError(Log::HLE, 0, "inflate failed %08x", err); + size_t totalIn = 0; + const int64_t totalOut = InflateBuffer(windowBits, inBufferPtr, inAvail, outBufferPtr, outAvail, &totalIn); + if (totalOut < 0) { + return hleLogError(Log::HLE, 0, "inflate failed"); } if (crc32Addr.IsValid()) { - uLong crc = crc32(0L, Z_NULL, 0); - *crc32Addr = crc32(crc, outBufferPtr, stream.total_out); + *crc32Addr = encoding_crc32(0, outBufferPtr, (size_t)totalOut); } - if (MemBlockInfoDetailed(stream.total_in, stream.total_out)) { + if (MemBlockInfoDetailed((u32)totalIn, (u32)totalOut)) { char tagData[128]; - size_t tagSize = FormatMemWriteTagAt(tagData, sizeof(tagData), "sceDeflt/", InBuffer, stream.total_in); - NotifyMemInfo(MemBlockFlags::READ, InBuffer, stream.total_in, tagData, tagSize); - NotifyMemInfo(MemBlockFlags::WRITE, OutBuffer, stream.total_out, tagData, tagSize); + size_t tagSize = FormatMemWriteTagAt(tagData, sizeof(tagData), "sceDeflt/", InBuffer, (u32)totalIn); + NotifyMemInfo(MemBlockFlags::READ, InBuffer, (u32)totalIn, tagData, tagSize); + NotifyMemInfo(MemBlockFlags::WRITE, OutBuffer, (u32)totalOut, tagData, tagSize); } - return hleLogDebug(Log::HLE, stream.total_out); + return hleLogDebug(Log::HLE, (int)totalOut); } static int sceDeflateDecompress(u32 OutBuffer, int OutBufferLength, u32 InBuffer, u32 Crc32Addr) { - return CommonDecompress(-MAX_WBITS, OutBuffer, OutBufferLength, InBuffer, Crc32Addr); + return CommonDecompress(-15, OutBuffer, OutBufferLength, InBuffer, Crc32Addr); } static int sceGzipDecompress(u32 OutBuffer, int OutBufferLength, u32 InBuffer, u32 Crc32Addr) { - return CommonDecompress(16 + MAX_WBITS, OutBuffer, OutBufferLength, InBuffer, Crc32Addr); + return CommonDecompress(31, OutBuffer, OutBufferLength, InBuffer, Crc32Addr); } static int sceZlibDecompress(u32 OutBuffer, int OutBufferLength, u32 InBuffer, u32 Crc32Addr) { - return CommonDecompress(MAX_WBITS, OutBuffer, OutBufferLength, InBuffer, Crc32Addr); + return CommonDecompress(15, OutBuffer, OutBufferLength, InBuffer, Crc32Addr); } const HLEFunction sceDeflt[] = { diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 25ecff5425..9070461ec0 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -18,7 +18,9 @@ #include #include -#include "zlib.h" +#include + +#include "Common/Data/Encoding/Compression.h" #include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Serialize/Serializer.h" @@ -1051,29 +1053,12 @@ static bool KernelImportModuleFuncs(PSPModule *module, u32 *firstImportStubAddr, } static int gzipDecompress(u8 *OutBuffer, int OutBufferLength, u8 *InBuffer) { - int err; - z_stream stream; - u8 *outBufferPtr; - - outBufferPtr = OutBuffer; - stream.next_in = InBuffer; - stream.avail_in = (uInt)OutBufferLength; - stream.next_out = outBufferPtr; - stream.avail_out = (uInt)OutBufferLength; - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - err = inflateInit2(&stream, 16+MAX_WBITS); - if (err != Z_OK) { - return -1; - } - err = inflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { + const int64_t produced = InflateBuffer(31, InBuffer, (size_t)OutBufferLength, OutBuffer, (size_t)OutBufferLength); + if (produced < 0) { ERROR_LOG(Log::Loader, "gzipDecompress: Didn't reach the end of the input, output buffer too small?"); - inflateEnd(&stream); return -2; } - inflateEnd(&stream); - return stream.total_out; + return (int)produced; } static void parsePrxLibInfo(const u8* ptr, u32 headerSize) { @@ -1304,7 +1289,7 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load loadedModules.insert(module->GetUID()); memset(&module->nm, 0, sizeof(module->nm)); - module->crc = crc32(0, ptr, (uInt)elfSize); + module->crc = encoding_crc32(0, ptr, elfSize); module->nm.modid = module->GetUID(); bool reportedModule = false; diff --git a/Core/HLE/scePauth.cpp b/Core/HLE/scePauth.cpp index 34fc16c345..696eeff82d 100644 --- a/Core/HLE/scePauth.cpp +++ b/Core/HLE/scePauth.cpp @@ -15,7 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "zlib.h" #include #include "Core/MemMap.h" diff --git a/Core/Loaders.cpp b/Core/Loaders.cpp index 287789bea1..a2698dea6b 100644 --- a/Core/Loaders.cpp +++ b/Core/Loaders.cpp @@ -388,7 +388,7 @@ bool UmdReplace(const Path &filepath, FileLoader **fileLoader, std::string &erro // Close the return value with ZipClose (if non-null, of course). ZipContainer ZipOpenPath(const Path &fileName) { ZipContainer z(fileName); - if (z == nullptr) { + if (!z) { ERROR_LOG(Log::HLE, "Failed to open ZIP file '%s'", fileName.c_str()); } return z; @@ -438,43 +438,23 @@ inline char asciitolower(char in) { // i.e. straight from an untrusted file. static const u64 MAX_ZIP_EXTRACT_TO_MEMORY_SIZE = 16 * 1024 * 1024; -static bool ZipExtractFileToMemory(struct zip *z, int fileIndex, std::string *data) { - zip_stat_t zstat{}; - if (zip_stat_index(z, fileIndex, 0, &zstat) != 0) { - ERROR_LOG(Log::HLE, "zip_stat_index failed for file %d in zip", fileIndex); - return false; - } - if (!(zstat.valid & ZIP_STAT_SIZE)) { - ERROR_LOG(Log::HLE, "No size for file %d in zip", fileIndex); - return false; - } - if (zstat.size == 0) { +static bool ZipExtractFileToMemory(const ZipContainer &z, int fileIndex, std::string *data) { + const u64 size = z.Size(fileIndex); + if (size == 0) { data->clear(); return true; } - if (zstat.size > MAX_ZIP_EXTRACT_TO_MEMORY_SIZE) { - ERROR_LOG(Log::HLE, "Refusing to extract file %d from zip: declared size %llu is implausible", fileIndex, (unsigned long long)zstat.size); + if (size > MAX_ZIP_EXTRACT_TO_MEMORY_SIZE) { + ERROR_LOG(Log::HLE, "Refusing to extract file %d from zip: declared size %llu is implausible", fileIndex, (unsigned long long)size); return false; } - - size_t readSize = (size_t)zstat.size; - data->resize(readSize); - - zip_file *zf = zip_fopen_index(z, fileIndex, 0); - if (!zf) { - ERROR_LOG(Log::HLE, "Failed to zip_fopen_index file %d from zip", fileIndex); + data->resize((size_t)size); + if (!z.ExtractInto(fileIndex, (uint8_t *)&(*data)[0], data->size())) { + ERROR_LOG(Log::HLE, "Failed to read %d bytes from zip - archive corrupt?", (int)size); + data->clear(); return false; } - - zip_int64_t retval = zip_fread(zf, data->data(), readSize); - zip_fclose(zf); - - if (retval < 0 || retval < (int)readSize) { - ERROR_LOG(Log::HLE, "Failed to read %d bytes from zip (%d) - archive corrupt?", (int)readSize, (int)retval); - return false; - } else { - return true; - } + return true; } // TODO: Make this generic and handle all the things. @@ -495,16 +475,15 @@ bool DetectArchiveContents(VFSInterface *vfs, ZipFileInfo *info) { return false; } -void DetectZipFileContents(zip_t *z, ZipFileInfo *info) { +void DetectZipFileContents(const ZipContainer &z, ZipFileInfo *info) { info->archiveType = ArchiveType::ZIP; - int numFiles = zip_get_num_files(z); - if (numFiles < 0) { + if (!z) { // Broken zip archive? ERROR_LOG(Log::HLE, "Failed to get the file count of zip file"); info->contents = ZipFileContents::UNKNOWN; return; } - _dbg_assert_(numFiles >= 0); + const int numFiles = z.NumEntries(); // Verify that this is a PSP zip file with the correct layout. We also try // to detect simple zipped ISO files, those we'll just "install" to the current @@ -528,11 +507,10 @@ void DetectZipFileContents(zip_t *z, ZipFileInfo *info) { // TODO: It might be cleaner to write separate detection functions, but this big loop doing it all at once // is quite convenient and makes it easy to add shared heuristics. for (int i = 0; i < numFiles; i++) { - const char *fn = zip_get_name(z, i, 0); - - zip_stat_t stat{}; - zip_stat_index(z, i, 0, &stat); - totalFileSize += stat.size; + const char *fn = z.Name(i); + if (!fn) + continue; + totalFileSize += z.Size(i); std::string fileName(fn); if (endsWith(fileName, "/")) { @@ -599,9 +577,6 @@ void DetectZipFileContents(zip_t *z, ZipFileInfo *info) { if (sfo.HasKey("TITLE")) { info->gameTitle = sfo.GetValueString("TITLE"); info->savedataTitle = sfo.GetValueString("SAVEDATA_TITLE"); - char buff[20]; - strftime(buff, 20, "%Y-%m-%d %H:%M:%S", localtime(&stat.mtime)); - info->mTime = buff; info->savedataDetails = sfo.GetValueString("SAVEDATA_DETAIL"); info->savedataDir = sfo.GetValueString("SAVEDATA_DIRECTORY"); // should also be parsable from the path. hasParamSFO = true; diff --git a/Core/Loaders.h b/Core/Loaders.h index a9d86dea99..76e2006a88 100644 --- a/Core/Loaders.h +++ b/Core/Loaders.h @@ -206,5 +206,5 @@ struct ZipFileInfo { ZipContainer ZipOpenPath(const Path &fileName); void ZipClose(ZipContainer &z); -void DetectZipFileContents(zip_t *z, ZipFileInfo *info); +void DetectZipFileContents(const ZipContainer &z, ZipFileInfo *info); bool DetectArchiveContents(VFSInterface *vfs, ZipFileInfo *info); diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index 2a767cdcf1..d3a583d58d 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -28,7 +28,7 @@ // for crc32 extern "C" { -#include "zlib.h" +#include } #include "Core/Reporting.h" @@ -108,7 +108,7 @@ namespace Reporting static u32 CalculateCRC(BlockDevice *blockDevice, std::atomic *cancel) { auto ga = GetI18NCategory(I18NCat::GAME); - u32 crc = crc32(0, Z_NULL, 0); + u32 crc = 0; u8 block[2048]; u32 numBlocks = blockDevice->GetNumBlocks(); @@ -122,7 +122,7 @@ namespace Reporting g_OSD.RemoveProgressBar("crc", false, 0.0f); return 0; } - crc = crc32(crc, block, 2048); + crc = encoding_crc32(crc, block, 2048); g_OSD.SetProgressBar("crc", std::string(ga->T("Calculate CRC")), 0.0f, (float)numBlocks, (float)i, 0.5f); } diff --git a/Core/Screenshot.cpp b/Core/Screenshot.cpp index 38662b2a72..3e69ad7275 100644 --- a/Core/Screenshot.cpp +++ b/Core/Screenshot.cpp @@ -19,7 +19,6 @@ #include -#include #include "ext/jpge/jpge.h" #include "Common/Data/Convert/ColorConv.h" @@ -453,30 +452,12 @@ bool Save8888RGBAScreenshot(const Path &filename, const u8 *buffer, int w, int h } bool Save8888RGBAScreenshot(std::vector &bufferPNG, const u8 *bufferRGBA8888, int w, int h) { - png_image png{}; - png.version = PNG_IMAGE_VERSION; - png.format = PNG_FORMAT_RGBA; - png.width = w; - png.height = h; - - png_alloc_size_t allocSize = bufferPNG.size(); - int result = png_image_write_to_memory(&png, allocSize == 0 ? nullptr : bufferPNG.data(), &allocSize, 0, bufferRGBA8888, w * 4, nullptr); - bool success = result != 0 && png.warning_or_error <= 1; - if (!success && allocSize != bufferPNG.size()) { - bufferPNG.resize(allocSize); - png.warning_or_error = 0; - result = png_image_write_to_memory(&png, bufferPNG.data(), &allocSize, 0, bufferRGBA8888, w * 4, nullptr); - success = result != 0 && png.warning_or_error <= 1; - } - if (success) - bufferPNG.resize(allocSize); - png_image_free(&png); - - if (!success) { + if (!pngEncode(&bufferPNG, bufferRGBA8888, w, h)) { ERROR_LOG(Log::IO, "Buffering screenshot to PNG produced errors."); bufferPNG.clear(); + return false; } - return success; + return true; } void TakeUserScreenshot() { diff --git a/Core/Util/GameManager.cpp b/Core/Util/GameManager.cpp index 628d4882bc..d8b8f10014 100644 --- a/Core/Util/GameManager.cpp +++ b/Core/Util/GameManager.cpp @@ -24,11 +24,6 @@ #include #include #include -#ifdef SHARED_LIBZIP -#include -#else -#include "ext/libzip/zip.h" -#endif #ifdef _WIN32 #include "Common/CommonWindows.h" @@ -177,16 +172,15 @@ void GameManager::Update() { } } -bool ZipCanExtractWithoutOverwrite(struct zip *z, const Path &destination, int stripChars, int maxOkFiles) { - int numFiles = zip_get_num_files(z); +bool ZipCanExtractWithoutOverwrite(const ZipContainer &z, const Path &destination, int stripChars, int maxOkFiles) { + int numFiles = z.NumEntries(); if (numFiles > maxOkFiles && maxOkFiles >= 0) { // Ignore the check, just assume we can't. return false; } for (int i = 0; i < numFiles; i++) { - const char *fn = zip_get_name(z, i, 0); + const char *fn = z.Name(i); if (!fn) { - // zip_get_name() returns NULL on a corrupted central directory entry. continue; } if (endsWith(fn, "/")) { @@ -202,23 +196,12 @@ bool ZipCanExtractWithoutOverwrite(struct zip *z, const Path &destination, int s return true; } -static std::string ZipReadFileByIndex(struct zip *z, int file_index) { - struct zip_stat zstat; - zip_stat_init(&zstat); - if (zip_stat_index(z, file_index, 0, &zstat) != 0) { - return {}; - } +static std::string ZipReadFileByIndex(const ZipContainer &z, int file_index) { std::string buffer; - buffer.resize(zstat.size); - zip_file *zf = zip_fopen_index(z, file_index, 0); - if (!zf) { + buffer.resize((size_t)z.Size(file_index)); + if (buffer.empty() || !z.ExtractInto(file_index, (uint8_t *)&buffer[0], buffer.size())) { return {}; } - if (zip_fread(zf, &buffer[0], buffer.size()) != (zip_int64_t)zstat.size) { - zip_fclose(zf); - return {}; - } - zip_fclose(zf); return buffer; } @@ -454,17 +437,15 @@ void GameManager::InstallZipContents(ZipFileTask task) { } } -bool GameManager::DetectTexturePackDest(struct zip *z, int iniIndex, Path &dest) { +bool GameManager::DetectTexturePackDest(const ZipContainer &z, int iniIndex, Path &dest) { auto iz = GetI18NCategory(I18NCat::INSTALLZIP); - struct zip_stat zstat; - zip_stat_init(&zstat); - if (zip_stat_index(z, iniIndex, 0, &zstat) != 0) { + if (iniIndex < 0 || iniIndex >= z.NumEntries()) { SetInstallError(iz->T("Zip archive corrupt")); return false; } - if (zstat.size >= 32 * 1024 * 1024) { + if (z.Size(iniIndex) >= 32 * 1024 * 1024) { SetInstallError(iz->T("Texture pack doesn't support install")); return false; } @@ -590,84 +571,47 @@ std::string GameManager::GetISOGameID(FileLoader *loader) const { return sfo.GetValueString("DISC_ID"); } -bool GameManager::ExtractFile(struct zip *z, int file_index, const Path &outFilename, int64_t *bytesCopied, int64_t allBytes, int64_t maxTotalSize) { - struct zip_stat zstat; - zip_stat_init(&zstat); - if (zip_stat_index(z, file_index, 0, &zstat) != 0) { - ERROR_LOG(Log::HLE, "Failed to stat file by index (%d) (%s)", file_index, outFilename.c_str()); - return false; - } - size_t size = zstat.size; - zip_file *zf = zip_fopen_index(z, file_index, 0); - if (!zf) { - ERROR_LOG(Log::HLE, "Failed to open file by index (%d) (%s)", file_index, outFilename.c_str()); - return false; - } - +bool GameManager::ExtractFile(const ZipContainer &z, int file_index, const Path &outFilename, int64_t *bytesCopied, int64_t allBytes, int64_t maxTotalSize) { + const size_t size = (size_t)z.Size(file_index); FILE *f = File::OpenCFile(outFilename, "wb"); - if (f) { - // Don't spam the log. - if (file_index < 10) { - INFO_LOG(Log::HLE, "Writing %d bytes to '%s'", (int)size, outFilename.c_str()); - } - size_t pos = 0; - const size_t blockSize = 1024 * 128; - u8 *buffer = new u8[blockSize]; - while (pos < size) { - size_t readSize = std::min(blockSize, size - pos); - // Stop before the total would exceed the limit (zip bomb), even - // if the declared sizes in the archive were inaccurate. - if (*bytesCopied > maxTotalSize || readSize > maxTotalSize - *bytesCopied) { - ERROR_LOG(Log::HLE, "Bailing: zip contents too large, limit %d", (int)maxTotalSize); - delete[] buffer; - fclose(f); - zip_fclose(zf); - File::Delete(outFilename); - return false; - } - zip_int64_t retval = zip_fread(zf, buffer, readSize); - if (retval < 0 || (size_t)retval < readSize) { - ERROR_LOG(Log::HLE, "Failed to read %d bytes from zip (%d) - archive corrupt?", (int)readSize, (int)retval); - delete[] buffer; - fclose(f); - zip_fclose(zf); - File::Delete(outFilename); - return false; - } - size_t written = fwrite(buffer, 1, readSize, f); - if (written != readSize) { - ERROR_LOG(Log::HLE, "Wrote %d bytes out of %d - Disk full?", (int)written, (int)readSize); - delete[] buffer; - fclose(f); - zip_fclose(zf); - File::Delete(outFilename); - return false; - } - pos += readSize; - - *bytesCopied += readSize; - installProgress_ = (float)*bytesCopied / (float)allBytes; - } - - zip_fclose(zf); - fclose(f); - - // Copy the mtime, too. May not be possible on Android? - if (zstat.mtime) { - File::ChangeMTime(outFilename, zstat.mtime); - } - delete[] buffer; - return true; - } else { + if (!f) { auto iz = GetI18NCategory(I18NCat::INSTALLZIP); g_OSD.Show(OSDType::MESSAGE_ERROR, iz->T("Installation failed"), outFilename.ToVisualString()); ERROR_LOG(Log::HLE, "Failed to open file for writing: %s", outFilename.c_str()); return false; } + // Don't spam the log. + if (file_index < 10) { + INFO_LOG(Log::HLE, "Writing %d bytes to '%s'", (int)size, outFilename.c_str()); + } + // Each decoded piece goes straight to the file. + const bool ok = z.ExtractTo(file_index, [&](const uint8_t *data, size_t len) { + // Stop before the total would exceed the limit (zip bomb), even + // if the declared sizes in the archive were inaccurate. + if (*bytesCopied > maxTotalSize || (int64_t)len > maxTotalSize - *bytesCopied) { + ERROR_LOG(Log::HLE, "Bailing: zip contents too large, limit %d", (int)maxTotalSize); + return false; + } + const size_t written = fwrite(data, 1, len, f); + if (written != len) { + ERROR_LOG(Log::HLE, "Wrote %d bytes out of %d - Disk full?", (int)written, (int)len); + return false; + } + *bytesCopied += len; + installProgress_ = (float)*bytesCopied / (float)allBytes; + return true; + }); + fclose(f); + if (!ok) { + ERROR_LOG(Log::HLE, "Failed to extract file by index (%d) (%s) - archive corrupt?", file_index, outFilename.c_str()); + File::Delete(outFilename); + return false; + } + return true; } // Doesn't care what it is, just extracts the whole ZIP to the requested location. -bool GameManager::ExtractZipContents(struct zip *z, const Path &dest, const ZipFileInfo &info, bool allowRoot, int64_t maxTotalSize) { +bool GameManager::ExtractZipContents(const ZipContainer &z, const Path &dest, const ZipFileInfo &info, bool allowRoot, int64_t maxTotalSize) { int64_t allBytes = 0; int64_t bytesCopied = 0; @@ -704,9 +648,8 @@ bool GameManager::ExtractZipContents(struct zip *z, const Path &dest, const ZipF std::vector createdFiles; for (int i = 0; i < info.numFiles; i++) { // Let's count the directories as the first 10%. - const char *fn = zip_get_name(z, i, 0); + const char *fn = z.Name(i); if (!fn) { - // zip_get_name() returns NULL on a corrupted central directory entry. continue; } std::string zippedName = fn; @@ -733,17 +676,15 @@ bool GameManager::ExtractZipContents(struct zip *z, const Path &dest, const ZipF createdDirs.insert(outPath); } if (!isDir && fileAllowed(fn)) { - struct zip_stat zstat; - if (zip_stat_index(z, i, 0, &zstat) >= 0) { - // Guard against zip bombs: the total declared size must not - // exceed the limit. Check before adding to avoid overflow. - if ((int64_t)zstat.size > maxTotalSize || allBytes > maxTotalSize - (int64_t)zstat.size) { - ERROR_LOG(Log::HLE, "Bailing: zip contents too large (%d bytes), limit %d", (int)allBytes, (int)maxTotalSize); - SetInstallError(sy->T("Too large")); - goto bail; - } - allBytes += (int64_t)zstat.size; + const int64_t entrySize = (int64_t)z.Size(i); + // Guard against zip bombs: the total declared size must not + // exceed the limit. Check before adding to avoid overflow. + if (entrySize > maxTotalSize || allBytes > maxTotalSize - entrySize) { + ERROR_LOG(Log::HLE, "Bailing: zip contents too large (%d bytes), limit %d", (int)allBytes, (int)maxTotalSize); + SetInstallError(sy->T("Too large")); + goto bail; } + allBytes += entrySize; } g_OSD.SetProgressBar("install", di->T("Installing..."), 0.0f, info.numFiles, (i + 1) * 0.1f, 0.1f); } @@ -752,9 +693,8 @@ bool GameManager::ExtractZipContents(struct zip *z, const Path &dest, const ZipF // Now, loop through again in a second pass, writing files. for (int i = 0; i < info.numFiles; i++) { - const char *fn = zip_get_name(z, i, 0); + const char *fn = z.Name(i); if (!fn) { - // zip_get_name() returns NULL on a corrupted central directory entry. continue; } // Note that we do NOT write files that are not in a directory, to avoid random @@ -845,11 +785,10 @@ bool GameManager::InstallMemstickZip(const Path &zipfile, const Path &dest, cons return true; } -bool GameManager::InstallZippedISO(struct zip *z, int isoFileIndex, const Path &destDir) { +bool GameManager::InstallZippedISO(const ZipContainer &z, int isoFileIndex, const Path &destDir) { // Let's place the output file in the currently selected Games directory. - const char *fnPtr = zip_get_name(z, isoFileIndex, 0); + const char *fnPtr = z.Name(isoFileIndex); if (!fnPtr) { - // zip_get_name() returns NULL on a corrupted central directory entry. return false; } std::string fn = fnPtr; @@ -859,16 +798,12 @@ bool GameManager::InstallZippedISO(struct zip *z, int isoFileIndex, const Path & } else { nameOffset++; } - size_t allBytes = 1; - struct zip_stat zstat; - zip_stat_init(&zstat); - if (zip_stat_index(z, isoFileIndex, 0, &zstat) >= 0) { - allBytes += zstat.size; - } + const size_t isoSize = (size_t)z.Size(isoFileIndex); + size_t allBytes = 1 + isoSize; std::string name = fn.substr(nameOffset); - INFO_LOG(Log::IO, "Name in zip: %s size: %d", name.c_str(), (int)zstat.size); + INFO_LOG(Log::IO, "Name in zip: %s size: %d", name.c_str(), (int)isoSize); if (startsWith(name, "._")) { // Not sure why Apple seems to add this when zipping file? diff --git a/Core/Util/GameManager.h b/Core/Util/GameManager.h index 556e5c30eb..45e02fb8f7 100644 --- a/Core/Util/GameManager.h +++ b/Core/Util/GameManager.h @@ -42,7 +42,7 @@ struct ZipFileTask { bool deleteAfter; }; -struct zip; +class ZipContainer; class FileLoader; class Path; struct ZipFileInfo; @@ -94,19 +94,19 @@ public: // Extracts the contents of an open zip archive into dest. Exposed for testing. // maxTotalSize limits the total decompressed size (zip bomb protection). - bool ExtractZipContents(struct zip *z, const Path &dest, const ZipFileInfo &info, bool allowRoot, int64_t maxTotalSize = 0x100000000ULL); + bool ExtractZipContents(const ZipContainer &z, const Path &dest, const ZipFileInfo &info, bool allowRoot, int64_t maxTotalSize = 0x100000000ULL); private: void InstallZipContents(ZipFileTask task); void InstallPkgContents(Path pkgPath, bool deleteAfter); bool InstallMemstickZip(const Path &zipFile, const Path &dest, const ZipFileInfo &info); - bool InstallZippedISO(struct zip *z, int isoFileIndex, const Path &destDir); + bool InstallZippedISO(const ZipContainer &z, int isoFileIndex, const Path &destDir); void UninstallGame(const std::string &name); void InstallDone(); - bool ExtractFile(struct zip *z, int file_index, const Path &outFilename, int64_t *bytesCopied, int64_t allBytes, int64_t maxTotalSize = 0x100000000ULL); - bool DetectTexturePackDest(struct zip *z, int iniIndex, Path &dest); + bool ExtractFile(const ZipContainer &z, int file_index, const Path &outFilename, int64_t *bytesCopied, int64_t allBytes, int64_t maxTotalSize = 0x100000000ULL); + bool DetectTexturePackDest(const ZipContainer &z, int iniIndex, Path &dest); void SetInstallError(std::string_view err); bool InstallInProgress() const { return installThread_.joinable(); } @@ -126,4 +126,4 @@ private: extern GameManager g_GameManager; -bool ZipCanExtractWithoutOverwrite(struct zip *z, const Path &destination, int stripChars, int maxOkFiles); +bool ZipCanExtractWithoutOverwrite(const ZipContainer &z, const Path &destination, int stripChars, int maxOkFiles); diff --git a/Core/Util/PSARUnpack.cpp b/Core/Util/PSARUnpack.cpp index 6f7d1d1c5d..135a99f20d 100644 --- a/Core/Util/PSARUnpack.cpp +++ b/Core/Util/PSARUnpack.cpp @@ -20,7 +20,7 @@ #include #include -#include "zlib.h" +#include "Common/Data/Encoding/Compression.h" #include "Common/Data/Text/I18n.h" #include "Common/File/DirListing.h" @@ -721,10 +721,9 @@ void PSARReader::EnsureContents() { entryCompression_ = DetectCompression(block2_.data(), decoded); if (entryCompression_ == PSARCompression::Zlib) { entryData_.resize(contentExpandedSize_); - uLongf destLen = contentExpandedSize_; - const int zResult = uncompress(entryData_.data(), &destLen, block2_.data(), decoded); - if (zResult != Z_OK || destLen != contentExpandedSize_) { - WARN_LOG(Log::Loader, "PSAR: inflate failed for '%s' (%d)", entryName_.c_str(), zResult); + const int64_t destLen = InflateBuffer(15, block2_.data(), (size_t)decoded, entryData_.data(), entryData_.size()); + if (destLen != (int64_t)contentExpandedSize_) { + WARN_LOG(Log::Loader, "PSAR: inflate failed for '%s' (%d)", entryName_.c_str(), (int)destLen); entryData_.clear(); } } diff --git a/GPU/CMakeLists.txt b/GPU/CMakeLists.txt index 2c48ce1ff7..73a4084573 100644 --- a/GPU/CMakeLists.txt +++ b/GPU/CMakeLists.txt @@ -199,21 +199,9 @@ set(GPU_SOURCES add_library(GPU OBJECT ${GPU_SOURCES}) target_compile_features(GPU PUBLIC cxx_std_17) -if(LIBRETRO) - target_include_directories(GPU PRIVATE ${CMAKE_SOURCE_DIR}/libretro/libretro-common/include) -endif() - setup_target_project(GPU GPU) # The only direct external dependencies of GPU/ itself (as opposed to Common/GPU/*, which -# already carries its own GL/Vulkan loader abstractions): raw gl*() calls in GPU/GLES, direct -# ZSTD_compress/decompress calls in GPU/Debugger/Record.cpp and Playback.cpp, and Playback.cpp -# also calls snappy_uncompress() directly. -target_link_libraries(GPU PUBLIC ${OPENGL_LIBRARIES} ${X11_LIBRARIES} Ext::Snappy) - -if(USE_SYSTEM_ZSTD) - target_include_directories(GPU PRIVATE ${ZSTD_INCLUDE_DIR}) - target_link_libraries(GPU PUBLIC ${ZSTD_LIBRARY}) -else() - target_link_libraries(GPU PUBLIC libzstd_static) -endif() +# already carries its own GL/Vulkan loader abstractions): raw gl*() calls in GPU/GLES, rzstd +# calls in GPU/Debugger/Record.cpp and Playback.cpp, and snappy_uncompress() in Playback.cpp. +target_link_libraries(GPU PUBLIC ${OPENGL_LIBRARIES} ${X11_LIBRARIES} Ext::Snappy libretro-common) diff --git a/GPU/Common/ReplacedTexture.cpp b/GPU/Common/ReplacedTexture.cpp index 2c823d86b6..aa07bedbfe 100644 --- a/GPU/Common/ReplacedTexture.cpp +++ b/GPU/Common/ReplacedTexture.cpp @@ -19,7 +19,6 @@ #include "ppsspp_config.h" -#include #include "ext/basis_universal/basisu_transcoder.h" #include "ext/basis_universal/basisu_file_headers.h" @@ -725,48 +724,32 @@ ReplacedTexture::LoadLevelResult ReplacedTexture::LoadLevelData(VFSFileReference return LoadLevelResult::CONTINUE; } else if (imageType == ReplacedImageType::PNG) { - png_image png = {}; - png.version = PNG_IMAGE_VERSION; - std::string pngdata; pngdata.resize(fileSize); pngdata.resize(vfs_->Read(openFile, &pngdata[0], fileSize)); vfs_->CloseFile(openFile); - if (!png_image_begin_read_from_memory(&png, &pngdata[0], pngdata.size())) { - ERROR_LOG(Log::TexReplacement, "Could not load texture replacement info: %s - %s (zip)", filename.c_str(), png.message); - return LoadLevelResult::LOAD_ERROR; - } - if (png.width > (uint32_t)level.w || png.height > (uint32_t)level.h) { - ERROR_LOG(Log::TexReplacement, "Texture replacement changed since header read: %s", filename.c_str()); - png_image_free(&png); - return LoadLevelResult::LOAD_ERROR; - } - bool checkedAlpha = false; - if ((png.format & PNG_FORMAT_FLAG_ALPHA) == 0) { - // Well, we know for sure it doesn't have alpha. - if (mipLevel == 0) { - alphaStatus_ = TextureAlpha::Solid; - } - checkedAlpha = true; + int w = 0, h = 0; + unsigned char *image = nullptr; + if (!pngLoadPtr((const unsigned char *)pngdata.data(), pngdata.size(), &w, &h, &image, level.w, level.h)) { + ERROR_LOG(Log::TexReplacement, "Could not load texture replacement: %s", filename.c_str()); + return LoadLevelResult::LOAD_ERROR; } - png.format = PNG_FORMAT_RGBA; std::vector &out = data_[mipLevel]; out.resize(level.w * level.h * 4); - if (!png_image_finish_read(&png, nullptr, &out[0], level.w * 4, nullptr)) { - ERROR_LOG(Log::TexReplacement, "Could not load texture replacement: %s - %s", filename.c_str(), png.message); - out.resize(0); - return LoadLevelResult::LOAD_ERROR; + if (w == level.w) { + memcpy(&out[0], image, (size_t)w * 4 * h); + } else { + for (int y = 0; y < h; ++y) + memcpy(&out[(size_t)level.w * 4 * y], image + (size_t)w * 4 * y, (size_t)w * 4); } - png_image_free(&png); + free(image); - if (!checkedAlpha) { - // This will only check the hashed bits. - const TextureAlpha res = CheckAlpha32Rect((u32 *)&out[0], level.w, png.width, png.height, 0xFF000000); - if (res == TextureAlpha::Any || mipLevel == 0) { - alphaStatus_ = res; - } + // This will only check the hashed bits. + const TextureAlpha res = CheckAlpha32Rect((u32 *)&out[0], level.w, w, h, 0xFF000000); + if (res == TextureAlpha::Any || mipLevel == 0) { + alphaStatus_ = res; } levels_.push_back(level); diff --git a/GPU/Common/TextureReplacer.cpp b/GPU/Common/TextureReplacer.cpp index aa36770b69..32efa907c0 100644 --- a/GPU/Common/TextureReplacer.cpp +++ b/GPU/Common/TextureReplacer.cpp @@ -19,7 +19,6 @@ #include #include -#include #include "ext/basis_universal/basisu_transcoder.h" #include "ext/xxhash.h" diff --git a/GPU/Debugger/Playback.cpp b/GPU/Debugger/Playback.cpp index 501c638728..7a01871fa7 100644 --- a/GPU/Debugger/Playback.cpp +++ b/GPU/Debugger/Playback.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include "Common/Profiler/Profiler.h" #include "Common/CommonTypes.h" @@ -1082,8 +1082,8 @@ static bool ReadCompressed(u32 fp, void *dest, size_t sz, uint32_t version) { size_t real_size = sz; if (version < 5) snappy_uncompress((const char *)compressed, compressed_size, (char *)dest, &real_size); - else - real_size = ZSTD_decompress(dest, real_size, compressed, compressed_size); + else if (rzstd_decode((uint8_t *)dest, sz, compressed, compressed_size, &real_size) != RZSTD_PROCESS_END) + real_size = 0; delete[] compressed; return real_size == sz; diff --git a/GPU/Debugger/Record.cpp b/GPU/Debugger/Record.cpp index 52b34733cc..a0e64730c6 100644 --- a/GPU/Debugger/Record.cpp +++ b/GPU/Debugger/Record.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include "Common/CommonTypes.h" #include "Common/File/FileUtil.h" @@ -169,9 +169,10 @@ bool Recorder::BeginRecording() { } static void WriteCompressed(FILE *fp, const void *p, size_t sz) { - size_t compressed_size = ZSTD_compressBound(sz); + size_t compressed_size = rzstd_compress_bound(sz); u8 *compressed = new u8[compressed_size]; - compressed_size = ZSTD_compress(compressed, compressed_size, p, sz, 6); + if (rzstd_encode(compressed, compressed_size, (const u8 *)p, sz, 6, &compressed_size) != RZSTD_PROCESS_END) + compressed_size = 0; u32 write_size = (u32)compressed_size; fwrite(&write_size, sizeof(write_size), 1, fp); diff --git a/ext/CMakeLists.txt b/ext/CMakeLists.txt index 2a348880a8..0c9d1e5ba1 100644 --- a/ext/CMakeLists.txt +++ b/ext/CMakeLists.txt @@ -14,9 +14,6 @@ set(ENABLE_GLSLANG_BINARIES OFF CACHE BOOL "let's not build binaries we don't ne set(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS ON CACHE BOOL "let's not use exceptions" FORCE) set(ENABLE_SPVREMAPPER OFF CACHE BOOL "we don't need spvremapper" FORCE) -# not really needed since we currently bypass the official cmakelists... -set(ZLIB_BUILD_EXAMPLES OFF CACHE BOOL "we don't need zlib examples" FORCE) - # This is really a workaround for an NDK 20 compiler issue (PPSSPP issue #12105), but shouldn't hurt. if(ANDROID) set(ENABLE_HLSL OFF CACHE BOOL "let's not build HLSL support we don't need" FORCE) @@ -93,10 +90,6 @@ if(USE_DISCORD AND NOT IOS AND NOT LIBRETRO) add_subdirectory(discord-rpc-build) endif() -if(NOT USE_SYSTEM_LIBCHDR) - add_subdirectory(libchdr-build) -endif() - if(BUILD_BUNDLED_FFMPEG) add_subdirectory(ffmpeg-build) endif() diff --git a/ext/basis_universal/CMakeLists.txt b/ext/basis_universal/CMakeLists.txt index 9390370746..49c8705d47 100644 --- a/ext/basis_universal/CMakeLists.txt +++ b/ext/basis_universal/CMakeLists.txt @@ -19,10 +19,5 @@ add_library(basis_universal STATIC basisu_transcoder_uastc.h ) -# basisu_transcoder.cpp calls ZSTD_decompress()/ZSTD_isError() directly for KTX2 supercompression. -if(USE_SYSTEM_ZSTD) - target_include_directories(basis_universal PRIVATE ${ZSTD_INCLUDE_DIR}) - target_link_libraries(basis_universal ${ZSTD_LIBRARY}) -else() - target_link_libraries(basis_universal libzstd_static) -endif() +# KTX2 supercompression goes through libretro-common's rzstd. +target_link_libraries(basis_universal libretro-common) diff --git a/ext/basis_universal/basisu_transcoder.cpp b/ext/basis_universal/basisu_transcoder.cpp index c698861f3b..2a7304e2d8 100644 --- a/ext/basis_universal/basisu_transcoder.cpp +++ b/ext/basis_universal/basisu_transcoder.cpp @@ -154,8 +154,8 @@ #if BASISD_SUPPORT_KTX2 // If BASISD_SUPPORT_KTX2_ZSTD is 0, UASTC files compressed with Zstd cannot be loaded. #if BASISD_SUPPORT_KTX2_ZSTD - // We only use two Zstd API's: ZSTD_decompress() and ZSTD_isError() - #include + // Zstd comes from libretro-common's rzstd. + #include #endif #endif @@ -17236,8 +17236,8 @@ namespace basist if (m_header.m_supercompression_scheme == KTX2_SS_ZSTANDARD) { #if BASISD_SUPPORT_KTX2_ZSTD - size_t actualUncompSize = ZSTD_decompress(uncomp_data.data(), (size_t)uncomp_size, pComp_data, (size_t)comp_size); - if (ZSTD_isError(actualUncompSize)) + size_t actualUncompSize = 0; + if (rzstd_decode(uncomp_data.data(), (size_t)uncomp_size, pComp_data, (size_t)comp_size, &actualUncompSize) != RZSTD_PROCESS_END) { BASISU_DEVEL_ERROR("ktx2_transcoder::decompress_level_data: Zstd decompression failed, file is invalid or corrupted\n"); return false; diff --git a/ext/libchdr b/ext/libchdr deleted file mode 160000 index 8bba7745d7..0000000000 --- a/ext/libchdr +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8bba7745d758627258b315997a860039244cedaf diff --git a/ext/libchdr-build/CMakeLists.txt b/ext/libchdr-build/CMakeLists.txt deleted file mode 100644 index bde9ed8a4c..0000000000 --- a/ext/libchdr-build/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -cmake_minimum_required (VERSION 3.10.0) -project (chdr) - -set(LZMA_DIR ../libchdr/deps/lzma-24.05/src) -set(SRC_DIR ../libchdr/src) - -include_directories(../libchdr/deps/lzma-24.05/include) -include_directories(../libchdr/include) -include_directories(../zlib) -include_directories(../zstd/lib) - -add_definitions(-DZ7_ST) - -# Hack - CpuArch.c has a workaround that we reuse. -add_definitions(-D__SWITCH__) - -set(ALL_SOURCE_FILES - ${LZMA_DIR}/Alloc.c - ${LZMA_DIR}/Bra.c - ${LZMA_DIR}/Bra86.c - ${LZMA_DIR}/BraIA64.c - ${LZMA_DIR}/CpuArch.c - ${LZMA_DIR}/Delta.c - ${LZMA_DIR}/LzFind.c - ${LZMA_DIR}/LzmaDec.c - ${LZMA_DIR}/LzmaEnc.c - ${LZMA_DIR}/Lzma86Dec.c - ${LZMA_DIR}/Sort.c - ${SRC_DIR}/libchdr_bitstream.c - ${SRC_DIR}/libchdr_cdrom.c - ${SRC_DIR}/libchdr_chd.c - ${SRC_DIR}/libchdr_flac.c - ${SRC_DIR}/libchdr_huffman.c - ) - -add_library(chdr STATIC ${ALL_SOURCE_FILES}) diff --git a/ext/libchdr.vcxproj b/ext/libchdr.vcxproj deleted file mode 100644 index 61cc575292..0000000000 --- a/ext/libchdr.vcxproj +++ /dev/null @@ -1,314 +0,0 @@ - - - - - Debug - ARM64 - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {956F1F48-B612-46D8-89EE-96996DCD9383} - Win32Proj - libchdr - libchdr_static - Unicode - StaticLibrary - $(SolutionDir)..\ext\libchdr\bin\$(Platform)_$(Configuration)\ - $(SolutionDir)..\ext\libchdr\bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ - 10.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - $(DefaultPlatformToolset) - - - true - $(DefaultPlatformToolset) - - - true - $(DefaultPlatformToolset) - - - false - true - $(DefaultPlatformToolset) - - - false - true - $(DefaultPlatformToolset) - - - false - true - $(DefaultPlatformToolset) - - - - - - - - - - - - - - - - - - - true - $(IncludePath);$(SolutionDir)..\ext\libchdr\include;$(UniversalCRT_IncludePath); - false - - - true - $(IncludePath);$(SolutionDir)..\ext\libchdr\include;$(UniversalCRT_IncludePath); - false - - - false - $(IncludePath);$(SolutionDir)..\ext\libchdr\include;$(UniversalCRT_IncludePath); - false - - - false - $(IncludePath);$(SolutionDir)..\ext\libchdr\include;$(UniversalCRT_IncludePath); - false - - - - $(OutDir)$(TargetName).pdb - - - - - - - Level4 - Z7_ST;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - true - ProgramDatabase - false - libchdr\include;libchdr\deps\lzma-24.05\include;zlib;zstd\lib; - - - Windows - true - MachineX86 - - - - - - - Level4 - Z7_ST;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug - true - ProgramDatabase - false - libchdr\include;libchdr\deps\lzma-24.05\include;zlib;zstd\lib; - - - Windows - true - - - - - - - Level4 - Z7_ST;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug - true - ProgramDatabase - false - libchdr\include;libchdr\deps\lzma-24.05\include;zlib;zstd\lib; - - - Windows - true - - - - - Level4 - - - MaxSpeed - true - true - Z7_ST;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - false - MultiThreaded - true - ProgramDatabase - AnySuitable - Speed - true - false - StreamingSIMDExtensions2 - libchdr\include;libchdr\deps\lzma-24.05\include;zlib;zstd\lib; - - - Windows - true - true - true - MachineX86 - - - - - Level4 - - - MaxSpeed - true - true - Z7_ST;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - false - false - MultiThreaded - true - ProgramDatabase - false - true - AnySuitable - Speed - libchdr\include;libchdr\deps\lzma-24.05\include;zlib;zstd\lib; - - - Windows - true - true - true - - - - - Level4 - - - MaxSpeed - true - true - Z7_ST;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - false - false - MultiThreaded - true - ProgramDatabase - false - true - AnySuitable - Speed - libchdr\include;libchdr\deps\lzma-24.05\include;zlib;zstd\lib; - - - Windows - true - true - true - - - - - - \ No newline at end of file diff --git a/ext/libchdr.vcxproj.filters b/ext/libchdr.vcxproj.filters deleted file mode 100644 index 3efa31b66e..0000000000 --- a/ext/libchdr.vcxproj.filters +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - - - - - - - - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - LZMA - - - - - {ff31581b-3ff9-4e39-bb96-2f662896cf70} - - - \ No newline at end of file diff --git a/ext/libpng17/CMakeLists.txt b/ext/libpng17/CMakeLists.txt deleted file mode 100644 index 6c155a686a..0000000000 --- a/ext/libpng17/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -cmake_minimum_required(VERSION 3.8) -project(libpng17) - -add_library(png17 STATIC - pngconf.h - pngdebug.h - png.c - png.h - pngerror.c - pngget.c - pnginfo.h - pnglibconf.h - pngmem.c - pngpread.c - pngpriv.h - pngread.c - pngrio.c - pngrtran.c - pngrutil.c - pngset.c - pngstruct.h - pngtest.c - pngtrans.c - pngwio.c - pngwrite.c - pngwtran.c - pngwutil.c -) - -# Add arm files for ARM processors -if("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "arm(64)?|aarch64") - set (ARM_FILES arm/arm_init.c - ) - - # Check if it's 32 bit - if("${CMAKE_SIZEOF_VOID_P}" EQUAL 4) - list(APPEND ARM_FILES arm/filter_neon.S) - else() - list(APPEND ARM_FILES arm/filter_neon_intrinsics.c) - endif() - - target_sources(png17 PRIVATE ${ARM_FILES}) -endif() diff --git a/ext/libpng17/arm/arm_init.c b/ext/libpng17/arm/arm_init.c deleted file mode 100644 index 79702c9077..0000000000 --- a/ext/libpng17/arm/arm_init.c +++ /dev/null @@ -1,135 +0,0 @@ - -/* arm_init.c - NEON optimised filter functions - * - * Copyright (c) 2014 Glenn Randers-Pehrson - * Written by Mans Rullgard, 2011. - * Last changed in libpng 1.6.16 [December 22, 2014] - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ -/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are - * called. - */ -#define _POSIX_SOURCE 1 - -#include "../pngpriv.h" -#define PNG_SRC_FILE PNG_SRC_FILE_arm_arm_init - -#ifdef PNG_READ_SUPPORTED - -#if PNG_ARM_NEON_OPT > 0 -#ifdef PNG_ARM_NEON_CHECK_SUPPORTED /* Do run-time checks */ -/* WARNING: it is strongly recommended that you do not build libpng with - * run-time checks for CPU features if at all possible. In the case of the ARM - * NEON instructions there is no processor-specific way of detecting the - * presence of the required support, therefore run-time detection is extremely - * OS specific. - * - * You may set the macro PNG_ARM_NEON_FILE to the file name of file containing - * a fragment of C source code which defines the png_have_neon function. There - * are a number of implementations in contrib/arm-neon, but the only one that - * has partial support is contrib/arm-neon/linux.c - a generic Linux - * implementation which reads /proc/cpufino. - */ -#ifndef PNG_ARM_NEON_FILE -# ifdef __linux__ -# define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c" -# endif -#endif - -#ifdef PNG_ARM_NEON_FILE - -#include /* for sig_atomic_t */ -static int png_have_neon(png_structp png_ptr); -#include PNG_ARM_NEON_FILE - -#else /* PNG_ARM_NEON_FILE */ -# error "PNG_ARM_NEON_FILE undefined: no support for run-time ARM NEON checks" -#endif /* PNG_ARM_NEON_FILE */ -#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ - -#ifndef PNG_ALIGNED_MEMORY_SUPPORTED -# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED" -#endif - -void -png_init_filter_functions_neon(png_structp pp, unsigned int bpp) -{ - /* The switch statement is compiled in for ARM_NEON_API, the call to - * png_have_neon is compiled in for ARM_NEON_CHECK. If both are defined - * the check is only performed if the API has not set the NEON option on - * or off explicitly. In this case the check controls what happens. - * - * If the CHECK is not compiled in and the option is UNSET the behavior prior - * to 1.6.7 was to use the NEON code - this was a bug caused by having the - * wrong order of the 'ON' and 'default' cases. UNSET now defaults to OFF, - * as documented in png.h - */ -#ifdef PNG_ARM_NEON_API_SUPPORTED - switch ((pp->options >> PNG_ARM_NEON) & 3) - { - case PNG_OPTION_UNSET: - /* Allow the run-time check to execute if it has been enabled - - * thus both API and CHECK can be turned on. If it isn't supported - * this case will fall through to the 'default' below, which just - * returns. - */ -#endif /* PNG_ARM_NEON_API_SUPPORTED */ -#ifdef PNG_ARM_NEON_CHECK_SUPPORTED - { - static volatile sig_atomic_t no_neon = -1; /* not checked */ - - if (no_neon < 0) - no_neon = !png_have_neon(pp); - - if (no_neon) - return; - } -#ifdef PNG_ARM_NEON_API_SUPPORTED - break; -#endif -#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ - -#ifdef PNG_ARM_NEON_API_SUPPORTED - default: /* OFF or INVALID */ - return; - - case PNG_OPTION_ON: - /* Option turned on */ - break; - } -#endif - - /* IMPORTANT: any new external functions used here must be declared using - * PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the - * 'prefix' option to configure works: - * - * ./configure --with-libpng-prefix=foobar_ - * - * Verify you have got this right by running the above command, doing a build - * and examining pngprefix.h; it must contain a #define for every external - * function you add. (Notice that this happens automatically for the - * initialization function.) - */ - pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon; - - if (bpp == 3) - { - pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon; - pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon; - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth3_neon; - } - - else if (bpp == 4) - { - pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon; - pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon; - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth4_neon; - } -} -#endif /* PNG_ARM_NEON_OPT > 0 */ -#endif /* READ */ diff --git a/ext/libpng17/arm/filter_neon.S b/ext/libpng17/arm/filter_neon.S deleted file mode 100644 index b7c0a90b43..0000000000 --- a/ext/libpng17/arm/filter_neon.S +++ /dev/null @@ -1,253 +0,0 @@ - -/* filter_neon.S - NEON optimised filter functions - * - * Copyright (c) 2014 Glenn Randers-Pehrson - * Written by Mans Rullgard, 2011. - * Last changed in libpng 1.6.16 [(PENDING RELEASE)] - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* This is required to get the symbol renames, which are #defines, and the - * definitions (or not) of PNG_ARM_NEON_OPT and PNG_ARM_NEON_IMPLEMENTATION. - */ -#define PNG_VERSION_INFO_ONLY -#include "../pngpriv.h" - -#if defined(__linux__) && defined(__ELF__) -.section .note.GNU-stack,"",%progbits /* mark stack as non-executable */ -#endif - -#ifdef PNG_READ_SUPPORTED - -/* Assembler NEON support - only works for 32-bit ARM (i.e. it does not work for - * ARM64). The code in arm/filter_neon_intrinsics.c supports ARM64, however it - * only works if -mfpu=neon is specified on the GCC command line. See pngpriv.h - * for the logic which sets PNG_USE_ARM_NEON_ASM: - */ -#if PNG_ARM_NEON_IMPLEMENTATION == 2 /* hand-coded assembler */ - -#if PNG_ARM_NEON_OPT > 0 - -#ifdef __ELF__ -# define ELF -#else -# define ELF @ -#endif - - .arch armv7-a - .fpu neon - -.macro func name, export=0 - .macro endfunc -ELF .size \name, . - \name - .endfunc - .purgem endfunc - .endm - .text - - /* Explicitly specifying alignment here because some versions of - * GAS don't align code correctly. This is harmless in correctly - * written versions of GAS. - */ - .align 2 - - .if \export - .global \name - .endif -ELF .type \name, STT_FUNC - .func \name -\name: -.endm - -func png_read_filter_row_sub4_neon, export=1 - ldr r3, [r0, #4] @ rowbytes - vmov.i8 d3, #0 -1: - vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] - vadd.u8 d0, d3, d4 - vadd.u8 d1, d0, d5 - vadd.u8 d2, d1, d6 - vadd.u8 d3, d2, d7 - vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! - subs r3, r3, #16 - bgt 1b - - bx lr -endfunc - -func png_read_filter_row_sub3_neon, export=1 - ldr r3, [r0, #4] @ rowbytes - vmov.i8 d3, #0 - mov r0, r1 - mov r2, #3 - mov r12, #12 - vld1.8 {q11}, [r0], r12 -1: - vext.8 d5, d22, d23, #3 - vadd.u8 d0, d3, d22 - vext.8 d6, d22, d23, #6 - vadd.u8 d1, d0, d5 - vext.8 d7, d23, d23, #1 - vld1.8 {q11}, [r0], r12 - vst1.32 {d0[0]}, [r1,:32], r2 - vadd.u8 d2, d1, d6 - vst1.32 {d1[0]}, [r1], r2 - vadd.u8 d3, d2, d7 - vst1.32 {d2[0]}, [r1], r2 - vst1.32 {d3[0]}, [r1], r2 - subs r3, r3, #12 - bgt 1b - - bx lr -endfunc - -func png_read_filter_row_up_neon, export=1 - ldr r3, [r0, #4] @ rowbytes -1: - vld1.8 {q0}, [r1,:128] - vld1.8 {q1}, [r2,:128]! - vadd.u8 q0, q0, q1 - vst1.8 {q0}, [r1,:128]! - subs r3, r3, #16 - bgt 1b - - bx lr -endfunc - -func png_read_filter_row_avg4_neon, export=1 - ldr r12, [r0, #4] @ rowbytes - vmov.i8 d3, #0 -1: - vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] - vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]! - vhadd.u8 d0, d3, d16 - vadd.u8 d0, d0, d4 - vhadd.u8 d1, d0, d17 - vadd.u8 d1, d1, d5 - vhadd.u8 d2, d1, d18 - vadd.u8 d2, d2, d6 - vhadd.u8 d3, d2, d19 - vadd.u8 d3, d3, d7 - vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! - subs r12, r12, #16 - bgt 1b - - bx lr -endfunc - -func png_read_filter_row_avg3_neon, export=1 - push {r4,lr} - ldr r12, [r0, #4] @ rowbytes - vmov.i8 d3, #0 - mov r0, r1 - mov r4, #3 - mov lr, #12 - vld1.8 {q11}, [r0], lr -1: - vld1.8 {q10}, [r2], lr - vext.8 d5, d22, d23, #3 - vhadd.u8 d0, d3, d20 - vext.8 d17, d20, d21, #3 - vadd.u8 d0, d0, d22 - vext.8 d6, d22, d23, #6 - vhadd.u8 d1, d0, d17 - vext.8 d18, d20, d21, #6 - vadd.u8 d1, d1, d5 - vext.8 d7, d23, d23, #1 - vld1.8 {q11}, [r0], lr - vst1.32 {d0[0]}, [r1,:32], r4 - vhadd.u8 d2, d1, d18 - vst1.32 {d1[0]}, [r1], r4 - vext.8 d19, d21, d21, #1 - vadd.u8 d2, d2, d6 - vhadd.u8 d3, d2, d19 - vst1.32 {d2[0]}, [r1], r4 - vadd.u8 d3, d3, d7 - vst1.32 {d3[0]}, [r1], r4 - subs r12, r12, #12 - bgt 1b - - pop {r4,pc} -endfunc - -.macro paeth rx, ra, rb, rc - vaddl.u8 q12, \ra, \rb @ a + b - vaddl.u8 q15, \rc, \rc @ 2*c - vabdl.u8 q13, \rb, \rc @ pa - vabdl.u8 q14, \ra, \rc @ pb - vabd.u16 q15, q12, q15 @ pc - vcle.u16 q12, q13, q14 @ pa <= pb - vcle.u16 q13, q13, q15 @ pa <= pc - vcle.u16 q14, q14, q15 @ pb <= pc - vand q12, q12, q13 @ pa <= pb && pa <= pc - vmovn.u16 d28, q14 - vmovn.u16 \rx, q12 - vbsl d28, \rb, \rc - vbsl \rx, \ra, d28 -.endm - -func png_read_filter_row_paeth4_neon, export=1 - ldr r12, [r0, #4] @ rowbytes - vmov.i8 d3, #0 - vmov.i8 d20, #0 -1: - vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] - vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]! - paeth d0, d3, d16, d20 - vadd.u8 d0, d0, d4 - paeth d1, d0, d17, d16 - vadd.u8 d1, d1, d5 - paeth d2, d1, d18, d17 - vadd.u8 d2, d2, d6 - paeth d3, d2, d19, d18 - vmov d20, d19 - vadd.u8 d3, d3, d7 - vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! - subs r12, r12, #16 - bgt 1b - - bx lr -endfunc - -func png_read_filter_row_paeth3_neon, export=1 - push {r4,lr} - ldr r12, [r0, #4] @ rowbytes - vmov.i8 d3, #0 - vmov.i8 d4, #0 - mov r0, r1 - mov r4, #3 - mov lr, #12 - vld1.8 {q11}, [r0], lr -1: - vld1.8 {q10}, [r2], lr - paeth d0, d3, d20, d4 - vext.8 d5, d22, d23, #3 - vadd.u8 d0, d0, d22 - vext.8 d17, d20, d21, #3 - paeth d1, d0, d17, d20 - vst1.32 {d0[0]}, [r1,:32], r4 - vext.8 d6, d22, d23, #6 - vadd.u8 d1, d1, d5 - vext.8 d18, d20, d21, #6 - paeth d2, d1, d18, d17 - vext.8 d7, d23, d23, #1 - vld1.8 {q11}, [r0], lr - vst1.32 {d1[0]}, [r1], r4 - vadd.u8 d2, d2, d6 - vext.8 d19, d21, d21, #1 - paeth d3, d2, d19, d18 - vst1.32 {d2[0]}, [r1], r4 - vmov d4, d19 - vadd.u8 d3, d3, d7 - vst1.32 {d3[0]}, [r1], r4 - subs r12, r12, #12 - bgt 1b - - pop {r4,pc} -endfunc -#endif /* PNG_ARM_NEON_OPT > 0 */ -#endif /* PNG_ARM_NEON_IMPLEMENTATION == 2 (assembler) */ -#endif /* READ */ diff --git a/ext/libpng17/arm/filter_neon_intrinsics.c b/ext/libpng17/arm/filter_neon_intrinsics.c deleted file mode 100644 index 5d8b5fb083..0000000000 --- a/ext/libpng17/arm/filter_neon_intrinsics.c +++ /dev/null @@ -1,395 +0,0 @@ - -/* filter_neon_intrinsics.c - NEON optimised filter functions - * - * Copyright (c) 2014 Glenn Randers-Pehrson - * Written by James Yu , October 2013. - * Based on filter_neon.S, written by Mans Rullgard, 2011. - * - * Last changed in libpng 1.6.16 [December 22, 2014] - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "../pngpriv.h" -#define PNG_SRC_FILE PNG_SRC_FILE_arm_filter_neon_intrinsics - -#ifdef PNG_READ_SUPPORTED - -/* This code requires -mfpu=neon on the command line: */ -#if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */ - -#if defined(_MSC_VER) && defined(_M_ARM64) -#include -#else -#include -#endif - -/* libpng row pointers are not necessarily aligned to any particular boundary, - * however this code will only work with appropriate alignment. arm/arm_init.c - * checks for this (and will not compile unless it is done). This code uses - * variants of png_aligncast to avoid compiler warnings. - */ -#define png_ptr(type,pointer) png_aligncast(type *,pointer) -#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer) - -/* The following relies on a variable 'temp_pointer' being declared with type - * 'type'. This is written this way just to hide the GCC strict aliasing - * warning; note that the code is safe because there never is an alias between - * the input and output pointers. - */ -#define png_ldr(type,pointer)\ - (temp_pointer = png_ptr(type,pointer), *temp_pointer) - -#if PNG_ARM_NEON_OPT > 0 - -void -png_read_filter_row_up_neon(png_alloc_size_t rowbytes, unsigned int bpp, - png_bytep row, png_const_bytep prev_row, png_const_bytep prev_pixels) -{ - png_bytep rp = row; - png_bytep rp_stop = row + rowbytes; - png_const_bytep pp = prev_row; - - for (; rp < rp_stop; rp += 16, pp += 16) - { - uint8x16_t qrp, qpp; - - qrp = vld1q_u8(rp); - qpp = vld1q_u8(pp); - qrp = vaddq_u8(qrp, qpp); - vst1q_u8(rp, qrp); - } - - PNG_UNUSED(bpp) - PNG_UNUSED(prev_pixels) -} - -void -png_read_filter_row_sub3_neon(png_alloc_size_t rowbytes, unsigned int bpp, png_bytep row, png_const_bytep prev_row, png_const_bytep prev_pixels) -{ - png_bytep rp = row; - png_bytep rp_stop = row + rowbytes; - - uint8x16_t vtmp = vld1q_u8(rp); - uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp); - uint8x8x2_t vrp = *vrpt; - - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - for (; rp < rp_stop;) - { - uint8x8_t vtmp1, vtmp2; - uint32x2_t *temp_pointer; - - vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); - vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); - vtmp2 = vext_u8(vrp.val[0], vrp.val[1], 6); - vdest.val[1] = vadd_u8(vdest.val[0], vtmp1); - - vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); - vdest.val[2] = vadd_u8(vdest.val[1], vtmp2); - vdest.val[3] = vadd_u8(vdest.val[2], vtmp1); - - vtmp = vld1q_u8(rp + 12); - vrpt = png_ptr(uint8x8x2_t, &vtmp); - vrp = *vrpt; - - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); - rp += 3; - } - - PNG_UNUSED(bpp) - PNG_UNUSED(prev_row) - PNG_UNUSED(prev_pixels) -} - -void -png_read_filter_row_sub4_neon(png_alloc_size_t rowbytes, unsigned int bpp, - png_bytep row, png_const_bytep prev_row, png_const_bytep prev_pixels) -{ - png_bytep rp = row; - png_bytep rp_stop = row + rowbytes; - - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - for (; rp < rp_stop; rp += 16) - { - uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp)); - uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp); - uint8x8x4_t vrp = *vrpt; - uint32x2x4_t *temp_pointer; - - vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); - vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]); - vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]); - vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]); - vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0); - } - - PNG_UNUSED(bpp) - PNG_UNUSED(prev_row) - PNG_UNUSED(prev_pixels) -} - -void -png_read_filter_row_avg3_neon(png_alloc_size_t rowbytes, unsigned int bpp, - png_bytep row, png_const_bytep prev_row, png_const_bytep prev_pixels) -{ - png_bytep rp = row; - png_const_bytep pp = prev_row; - png_bytep rp_stop = row + rowbytes; - - uint8x16_t vtmp; - uint8x8x2_t *vrpt; - uint8x8x2_t vrp; - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - vtmp = vld1q_u8(rp); - vrpt = png_ptr(uint8x8x2_t,&vtmp); - vrp = *vrpt; - - for (; rp < rp_stop; pp += 12) - { - uint8x8_t vtmp1, vtmp2, vtmp3; - - uint8x8x2_t *vppt; - uint8x8x2_t vpp; - - uint32x2_t *temp_pointer; - - vtmp = vld1q_u8(pp); - vppt = png_ptr(uint8x8x2_t,&vtmp); - vpp = *vppt; - - vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); - vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]); - vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); - - vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3); - vtmp3 = vext_u8(vrp.val[0], vrp.val[1], 6); - vdest.val[1] = vhadd_u8(vdest.val[0], vtmp2); - vdest.val[1] = vadd_u8(vdest.val[1], vtmp1); - - vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 6); - vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); - - vtmp = vld1q_u8(rp + 12); - vrpt = png_ptr(uint8x8x2_t,&vtmp); - vrp = *vrpt; - - vdest.val[2] = vhadd_u8(vdest.val[1], vtmp2); - vdest.val[2] = vadd_u8(vdest.val[2], vtmp3); - - vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1); - - vdest.val[3] = vhadd_u8(vdest.val[2], vtmp2); - vdest.val[3] = vadd_u8(vdest.val[3], vtmp1); - - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); - rp += 3; - } - - PNG_UNUSED(bpp) - PNG_UNUSED(prev_pixels) -} - -void -png_read_filter_row_avg4_neon(png_alloc_size_t rowbytes, unsigned int bpp, - png_bytep row, png_const_bytep prev_row, png_const_bytep prev_pixels) -{ - png_bytep rp = row; - png_bytep rp_stop = row + rowbytes; - png_const_bytep pp = prev_row; - - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - for (; rp < rp_stop; rp += 16, pp += 16) - { - uint32x2x4_t vtmp; - uint8x8x4_t *vrpt, *vppt; - uint8x8x4_t vrp, vpp; - uint32x2x4_t *temp_pointer; - - vtmp = vld4_u32(png_ptr(uint32_t,rp)); - vrpt = png_ptr(uint8x8x4_t,&vtmp); - vrp = *vrpt; - vtmp = vld4_u32(png_ptrc(uint32_t,pp)); - vppt = png_ptr(uint8x8x4_t,&vtmp); - vpp = *vppt; - - vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]); - vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); - vdest.val[1] = vhadd_u8(vdest.val[0], vpp.val[1]); - vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]); - vdest.val[2] = vhadd_u8(vdest.val[1], vpp.val[2]); - vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]); - vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]); - vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); - - vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0); - } - - PNG_UNUSED(bpp) - PNG_UNUSED(prev_pixels) -} - -static uint8x8_t -paeth(uint8x8_t a, uint8x8_t b, uint8x8_t c) -{ - uint8x8_t d, e; - uint16x8_t p1, pa, pb, pc; - - p1 = vaddl_u8(a, b); /* a + b */ - pc = vaddl_u8(c, c); /* c * 2 */ - pa = vabdl_u8(b, c); /* pa */ - pb = vabdl_u8(a, c); /* pb */ - pc = vabdq_u16(p1, pc); /* pc */ - - p1 = vcleq_u16(pa, pb); /* pa <= pb */ - pa = vcleq_u16(pa, pc); /* pa <= pc */ - pb = vcleq_u16(pb, pc); /* pb <= pc */ - - p1 = vandq_u16(p1, pa); /* pa <= pb && pa <= pc */ - - d = vmovn_u16(pb); - e = vmovn_u16(p1); - - d = vbsl_u8(d, b, c); - e = vbsl_u8(e, a, d); - - return e; -} - -void -png_read_filter_row_paeth3_neon(png_alloc_size_t rowbytes, unsigned int bpp, - png_bytep row, png_const_bytep prev_row, png_const_bytep prev_pixels) -{ - png_bytep rp = row; - png_const_bytep pp = prev_row; - png_bytep rp_stop = row + rowbytes; - - uint8x16_t vtmp; - uint8x8x2_t *vrpt; - uint8x8x2_t vrp; - uint8x8_t vlast = vdup_n_u8(0); - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - vtmp = vld1q_u8(rp); - vrpt = png_ptr(uint8x8x2_t,&vtmp); - vrp = *vrpt; - - for (; rp < rp_stop; pp += 12) - { - uint8x8x2_t *vppt; - uint8x8x2_t vpp; - uint8x8_t vtmp1, vtmp2, vtmp3; - uint32x2_t *temp_pointer; - - vtmp = vld1q_u8(pp); - vppt = png_ptr(uint8x8x2_t,&vtmp); - vpp = *vppt; - - vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast); - vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); - - vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); - vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3); - vdest.val[1] = paeth(vdest.val[0], vtmp2, vpp.val[0]); - vdest.val[1] = vadd_u8(vdest.val[1], vtmp1); - - vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 6); - vtmp3 = vext_u8(vpp.val[0], vpp.val[1], 6); - vdest.val[2] = paeth(vdest.val[1], vtmp3, vtmp2); - vdest.val[2] = vadd_u8(vdest.val[2], vtmp1); - - vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); - vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1); - - vtmp = vld1q_u8(rp + 12); - vrpt = png_ptr(uint8x8x2_t,&vtmp); - vrp = *vrpt; - - vdest.val[3] = paeth(vdest.val[2], vtmp2, vtmp3); - vdest.val[3] = vadd_u8(vdest.val[3], vtmp1); - - vlast = vtmp2; - - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); - rp += 3; - } - - PNG_UNUSED(bpp) - PNG_UNUSED(prev_pixels) -} - -void -png_read_filter_row_paeth4_neon(png_alloc_size_t rowbytes, unsigned int bpp, - png_bytep row, png_const_bytep prev_row, png_const_bytep prev_pixels) -{ - png_bytep rp = row; - png_bytep rp_stop = row + rowbytes; - png_const_bytep pp = prev_row; - - uint8x8_t vlast = vdup_n_u8(0); - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - for (; rp < rp_stop; rp += 16, pp += 16) - { - uint32x2x4_t vtmp; - uint8x8x4_t *vrpt, *vppt; - uint8x8x4_t vrp, vpp; - uint32x2x4_t *temp_pointer; - - vtmp = vld4_u32(png_ptr(uint32_t,rp)); - vrpt = png_ptr(uint8x8x4_t,&vtmp); - vrp = *vrpt; - vtmp = vld4_u32(png_ptrc(uint32_t,pp)); - vppt = png_ptr(uint8x8x4_t,&vtmp); - vpp = *vppt; - - vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast); - vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); - vdest.val[1] = paeth(vdest.val[0], vpp.val[1], vpp.val[0]); - vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]); - vdest.val[2] = paeth(vdest.val[1], vpp.val[2], vpp.val[1]); - vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]); - vdest.val[3] = paeth(vdest.val[2], vpp.val[3], vpp.val[2]); - vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); - - vlast = vpp.val[3]; - - vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0); - } - - PNG_UNUSED(bpp) - PNG_UNUSED(prev_pixels) -} -#endif /* PNG_ARM_NEON_OPT > 0 */ -#endif /* PNG_ARM_NEON_IMPLEMENTATION == 1 (intrinsics) */ -#endif /* READ */ diff --git a/ext/libpng17/arm/neon.h b/ext/libpng17/arm/neon.h deleted file mode 100644 index 0132b945af..0000000000 --- a/ext/libpng17/arm/neon.h +++ /dev/null @@ -1,124 +0,0 @@ -/* Compile time options. - * ===================== - * In a multi-arch build the compiler may compile the code several times for the - * same object module, producing different binaries for different architectures. - * When this happens configure-time setting of the target host options cannot be - * done. An example is iOS vs Android compilation of ARM NEON support. - * - * NOTE: symbol prefixing does not pass $(CFLAGS) to the preprocessor, because - * this is not possible with certain compilers (Oracle SUN OS CC), as a result - * it is necessary to ensure that all extern functions that *might* be used - * regardless of $(CFLAGS) get declared in this file. The test on __ARM_NEON - * below is one example of this behavior because it is controlled by the - * presence or not of -mfpu=neon on the GCC command line, it is possible to do - * this in $(CC), e.g. "CC=gcc -mfpu=neon", but people who build libpng rarely - * do this. - */ -#ifndef PNG_ARM_NEON_OPT - /* ARM NEON optimizations are being controlled by the compiler settings, - * typically the target FPU. If the FPU supports NEON instructions then the - * compiler will define __ARM_NEON and we can rely unconditionally on NEON - * instructions not crashing, otherwise we must disable use of NEON - * instructions. - * - * NOTE: at present these optimizations depend on 'ALIGNED_MEMORY', so they - * can only be turned on automatically if that is supported too. If - * PNG_ARM_NEON_OPT is set in CPPFLAGS (to >0) then arm/arm_init.c will fail - * to compile with an appropriate #error if ALIGNED_MEMORY has been turned - * off. - * - * Note that older versions of GCC defined __ARM_NEON__; this is no longer - * supported. Also 32-bit ARM versions of GCC required the NEON FPU mode to - * be turned on explicitly on the command line. If this is not done (on - * 32-bit ARM) NEON code will not be included. - * - * To disable ARM_NEON optimizations entirely, and skip compiling the - * associated assembler code, pass --enable-arm-neon=no to configure - * or put -DPNG_ARM_NEON_OPT=0 in CPPFLAGS. - */ -# if defined(__ARM_NEON) && defined(PNG_ALIGNED_MEMORY_SUPPORTED) -# define PNG_ARM_NEON_OPT 2 -# else -# define PNG_ARM_NEON_OPT 0 -# endif -#endif - -#if PNG_ARM_NEON_OPT > 0 - /* NEON optimizations are to be at least considered by libpng, so enable the - * callbacks to do this. - */ -# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon - - /* By default the 'intrinsics' code in arm/filter_neon_intrinsics.c is used - * if possible - if __ARM_NEON is set and the compiler version is not known - * to be broken. This is controlled by PNG_ARM_NEON_IMPLEMENTATION which can - * be: - * - * 1 The intrinsics code (the default with __ARM_NEON) - * 2 The hand coded assembler (the default without __ARM_NEON) - * - * It is possible to set PNG_ARM_NEON_IMPLEMENTATION in CPPFLAGS, however - * this is *NOT* supported and may cease to work even after a minor revision - * to libpng. It *is* valid to do this for testing purposes, e.g. speed - * testing or a new compiler, but the results should be communicated to the - * libpng implementation list for incorporation in the next minor release. - */ -# ifndef PNG_ARM_NEON_IMPLEMENTATION -# ifdef __ARM_NEON -# if defined(__clang__) - /* At present it is unknown by the libpng developers which versions - * of clang support the intrinsics, however some or perhaps all - * versions do not work with the assembler so this may be - * irrelevant, so just use the default (do nothing here.) - */ -# elif defined(__GNUC__) - /* GCC 4.5.4 NEON support is known to be broken. 4.6.3 is known to - * work, so if this *is* GCC, or G++, look for a version >4.5 - */ -# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6) -# define PNG_ARM_NEON_IMPLEMENTATION 2 -# endif /* no GNUC support */ -# endif /* __GNUC__ */ -# else /* !defined __ARM_NEON */ - /* The 'intrinsics' code simply won't compile without compiler support - * and that support switches on __ARM_NEON, so use the assembler: - */ -# define PNG_ARM_NEON_IMPLEMENTATION 2 -# endif /* __ARM_NEON */ -# endif /* !defined PNG_ARM_NEON_IMPLEMENTATION */ - -# ifndef PNG_ARM_NEON_IMPLEMENTATION - /* Use the intrinsics code by default. */ -# define PNG_ARM_NEON_IMPLEMENTATION 1 -# endif -#endif /* PNG_ARM_NEON_OPT > 0 */ - -#ifdef PNG_SET_OPTION_SUPPORTED -#ifdef PNG_ARM_NEON_API_SUPPORTED -# define PNG_ARM_NEON 0 /* HARDWARE: ARM Neon SIMD instructions supported */ -#endif -#endif /* SET_OPTION */ - -#if PNG_ARM_NEON_OPT > 0 -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon, - (png_alloc_size_t row_bytes, unsigned int bpp, png_bytep row, - png_const_bytep prev_row, png_const_bytep prev_pixels),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon, - (png_alloc_size_t row_bytes, unsigned int bpp, png_bytep row, - png_const_bytep prev_row, png_const_bytep prev_pixels),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_neon, - (png_alloc_size_t row_bytes, unsigned int bpp, png_bytep row, - png_const_bytep prev_row, png_const_bytep prev_pixels),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_neon, - (png_alloc_size_t row_bytes, unsigned int bpp, png_bytep row, - png_const_bytep prev_row, png_const_bytep prev_pixels),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_neon, - (png_alloc_size_t row_bytes, unsigned int bpp, png_bytep row, - png_const_bytep prev_row, png_const_bytep prev_pixels),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_neon, - (png_alloc_size_t row_bytes, unsigned int bpp, png_bytep row, - png_const_bytep prev_row, png_const_bytep prev_pixels),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon, - (png_alloc_size_t row_bytes, unsigned int bpp, png_bytep row, - png_const_bytep prev_row, png_const_bytep prev_pixels),PNG_EMPTY); -#endif diff --git a/ext/libpng17/png.c b/ext/libpng17/png.c deleted file mode 100644 index edf915a3fc..0000000000 --- a/ext/libpng17/png.c +++ /dev/null @@ -1,3782 +0,0 @@ - -/* png.c - location for general purpose libpng functions - * - * Last changed in libpng 1.7.0 [(PENDING RELEASE)] - * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" -#define PNG_SRC_FILE PNG_SRC_FILE_png - -/* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_7_0beta90 Your_png_h_is_not_version_1_7_0beta90; - -/* Tells libpng that we have already handled the first "num_bytes" bytes - * of the PNG file signature. If the PNG data is embedded into another - * stream we can set num_bytes = 8 so that libpng will not attempt to read - * or write any of the magic bytes before it starts on the IHDR. - */ - -#ifdef PNG_READ_SUPPORTED -void PNGAPI -png_set_sig_bytes(png_structrp png_ptr, int num_bytes) -{ - png_debug(1, "in png_set_sig_bytes"); - - if (png_ptr == NULL) - return; - - if (num_bytes > 8) - png_error(png_ptr, "Too many bytes for PNG signature"); - - png_ptr->sig_bytes = png_check_byte(png_ptr, num_bytes < 0 ? 0 : num_bytes); -} - -/* Checks whether the supplied bytes match the PNG signature. We allow - * checking less than the full 8-byte signature so that those apps that - * already read the first few bytes of a file to determine the file type - * can simply check the remaining bytes for extra assurance. Returns - * an integer less than, equal to, or greater than zero if sig is found, - * respectively, to be less than, to match, or be greater than the correct - * PNG signature (this is the same behavior as strcmp, memcmp, etc). - */ -int PNGAPI -png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check) -{ - png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; - - if (num_to_check > 8) - num_to_check = 8; - - else if (num_to_check < 1) - return (-1); - - if (start > 7) - return (-1); - - if (start + num_to_check > 8) - num_to_check = 8 - start; - - return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check))); -} - -#endif /* READ */ - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -/* Function to allocate memory for zlib */ -PNG_FUNCTION(voidpf /* PRIVATE */, -png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED) -{ - png_alloc_size_t num_bytes = size; - - if (png_ptr == NULL) - return NULL; - - if (items >= (~(png_alloc_size_t)0)/size) - { - png_warning(png_voidcast(png_structrp, png_ptr), - "Potential overflow in png_zalloc()"); - return NULL; - } - - num_bytes *= items; - return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes); -} - -/* Function to free memory for zlib */ -void /* PRIVATE */ -png_zfree(voidpf png_ptr, voidpf ptr) -{ - png_free(png_voidcast(png_const_structrp,png_ptr), ptr); -} - -/* Reset the CRC variable to 32 bits of 1's. Care must be taken - * in case CRC is > 32 bits to leave the top bits 0. - */ -void /* PRIVATE */ -png_reset_crc(png_structrp png_ptr, png_const_bytep chunk_tag) -{ -# ifdef PNG_READ_SUPPORTED - if (png_ptr->read_struct) - { - /* Set png_struct::current_crc appropriately. */ - if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)) - png_ptr->current_crc = png_ptr->ancillary_crc; - - else /* critical */ - png_ptr->current_crc = png_ptr->critical_crc; - } - - else - png_ptr->current_crc = crc_error_quit; /* for write */ - - /* Now do not calculate the CRC if it isn't required: */ - if (png_ptr->current_crc != crc_quiet_use) -# endif /* READ */ - png_ptr->crc = 0xFFFFFFFFU & crc32(0, chunk_tag, 4); -} - -/* Calculate the CRC over a section of data. We can only pass as - * much data to this routine as the largest single buffer size. We - * also check that this data will actually be used before going to the - * trouble of calculating it. - */ -void /* PRIVATE */ -png_calculate_crc(png_structrp png_ptr, png_const_voidp ptr, png_size_t length) -{ - /* 'uLong' is defined in zlib.h as unsigned long; this means that on some - * systems it is a 64 bit value. crc32, however, returns 32 bits so the - * following cast is safe. 'uInt' may be no more than 16 bits, so it is - * necessary to perform a loop here. - */ -# ifdef PNG_READ_SUPPORTED - if (png_ptr->current_crc != crc_quiet_use) -# endif /* READ */ - if (length > 0) - { - uLong crc = png_ptr->crc; /* Should never issue a warning */ - const Bytef* rptr = png_voidcast(const Bytef*,ptr); - - do - { - uInt safe_length; - - /* TODO: this uses ZLIB_IO_MAX which may be #defined to less than the - * maximum of a uInt, is this the best thing to do? - */ - if (length > ZLIB_IO_MAX) - safe_length = ZLIB_IO_MAX; - - else - safe_length = (uInt)/*SAFE*/length; - - crc = crc32(crc, PNGZ_INPUT_CAST(rptr), safe_length); - - /* The following should never issue compiler warnings; if they do the - * target system has characteristics that will probably violate other - * assumptions within the libpng code. - */ - rptr += safe_length; - length -= safe_length; - } - while (length > 0); - - /* And the following is always safe because the crc is only 32 bits. */ - png_ptr->crc = 0xFFFFFFFFU & crc; - } -} - -/* Check a user supplied version number, called from both read and write - * functions that create a png_struct. - */ -static int -png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver) -{ - /* Libpng versions 1.0.0 and later are binary compatible if the version - * string matches through the second '.'; we must recompile any applications - * that use any older library version. - */ - if (user_png_ver != NULL) - { - int library_match = 1; - int i = -1; - unsigned int found_dots = 0; - - do - { - i++; - if (user_png_ver[i] != PNG_LIBPNG_VER_STRING[i]) - library_match = 0; - if (user_png_ver[i] == '.') - found_dots++; - } while (library_match && found_dots < 2 && user_png_ver[i] != 0 && - PNG_LIBPNG_VER_STRING[i] != 0); - - if (library_match) - return 1; /* Library matches ok */ - } - - /* Failure: mismatched library major version number */ -#ifdef PNG_WARNINGS_SUPPORTED - { - size_t pos = 0; - char m[128]; - - pos = png_safecat(m, (sizeof m), pos, - "Application built with libpng-"); - /* This is ok if user_png_ver is NULL, it appends nothing: */ - pos = png_safecat(m, (sizeof m), pos, user_png_ver); - pos = png_safecat(m, (sizeof m), pos, " but running with "); - pos = png_safecat(m, (sizeof m), pos, PNG_LIBPNG_VER_STRING); - PNG_UNUSED(pos) - - png_app_warning(png_ptr, m); - } -#endif - - return 0; /* Failure */ - PNG_UNUSED(png_ptr) /* if no warning */ -} - -/* Generic function to create a png_struct for either read or write - this - * contains the common initialization. - */ -PNG_FUNCTION(png_structp /* PRIVATE */, -png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) -{ - png_struct create_struct; -# ifdef PNG_SETJMP_SUPPORTED - jmp_buf create_jmp_buf; -# endif - - /* This is a compile-type only test to ensure that the build satisifies the - * contraints for the row buffer stack allocations. A 'duplicate case - * statements' style of error means that one of the tests below failed: - */ - switch (0) - { - case 0: - case PNG_ROW_BUFFER_SIZE >= PNG_MIN_ROW_BUFFER_SIZE: /*1*/ - case 2*(PNG_ROW_BUFFER_SIZE <= PNG_MAX_ROW_BUFFER_SIZE): /*2*/ - default: - break; - } - - /* This temporary stack-allocated structure is used to provide a place to - * build enough context to allow the user provided memory allocator (if any) - * to be called. - */ - memset(&create_struct, 0, (sizeof create_struct)); - - /* These limits are only used on read at present, and if READ is not turned - * on neither will USER_LIMITS be. The width/height and chunk malloc limits - * are constants, so if they cannot be set they don't get defined in - * png_struct, the user_chunk_cache limits is a down-counter, when it reaches - * 1 no more chunks will be handled. 0 means unlimited, consequently the - * limit is 1 more than the number of chunks that will be handled. - */ -# ifdef PNG_SET_USER_LIMITS_SUPPORTED - create_struct.user_width_max = PNG_USER_WIDTH_MAX; - create_struct.user_height_max = PNG_USER_HEIGHT_MAX; - create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; -# endif -# ifdef PNG_USER_LIMITS_SUPPORTED - /* Must exist even if the initial value is constant */ - create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; -# endif - - /* The following two API calls simply set fields in png_struct, so it is safe - * to do them now even though error handling is not yet set up. - */ -# ifdef PNG_USER_MEM_SUPPORTED - png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn); -# else - PNG_UNUSED(mem_ptr) - PNG_UNUSED(malloc_fn) - PNG_UNUSED(free_fn) -# endif - - /* (*error_fn) can return control to the caller after the error_ptr is set, - * this will result in a memory leak unless the error_fn does something - * extremely sophisticated. The design lacks merit but is implicit in the - * API. - */ - png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn); - -# ifdef PNG_SETJMP_SUPPORTED - if (!setjmp(create_jmp_buf)) -# endif - { -# ifdef PNG_SETJMP_SUPPORTED - /* Temporarily fake out the longjmp information until we have - * successfully completed this function. This only works if we have - * setjmp() support compiled in, but it is safe - this stuff should - * never happen. - */ - create_struct.jmp_buf_ptr = &create_jmp_buf; - create_struct.jmp_buf_size = 0; /*stack allocation*/ - create_struct.longjmp_fn = longjmp; -# endif - /* Call the general version checker (shared with read and write code): - */ - if (png_user_version_check(&create_struct, user_png_ver) != 0) - { - png_structrp png_ptr = png_voidcast(png_structrp, - png_malloc_warn(&create_struct, (sizeof *png_ptr))); - - if (png_ptr != NULL) - { -# ifdef PNG_SETJMP_SUPPORTED - /* Eliminate the local error handling: */ - create_struct.jmp_buf_ptr = NULL; - create_struct.jmp_buf_size = 0; - create_struct.longjmp_fn = 0; -# endif - - *png_ptr = create_struct; - - /* This is the successful return point */ - return png_ptr; - } - } - } - - /* A longjmp because of a bug in the application storage allocator or a - * simple failure to allocate the png_struct. - */ - return NULL; -} - -/* Allocate the memory for an info_struct for the application. */ -PNG_FUNCTION(png_infop,PNGAPI -png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED) -{ - png_inforp info_ptr; - - png_debug(1, "in png_create_info_struct"); - - if (png_ptr == NULL) - return NULL; - - /* Use the internal API that does not (or at least should not) error out, so - * that this call always returns ok. The application typically sets up the - * error handling *after* creating the info_struct because this is the way it - * has always been done in 'example.c'. - */ - info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr, - (sizeof *info_ptr))); - - if (info_ptr != NULL) - memset(info_ptr, 0, (sizeof *info_ptr)); - - return info_ptr; -} - -/* This function frees the memory associated with a single info struct. - * Normally, one would use either png_destroy_read_struct() or - * png_destroy_write_struct() to free an info struct, but this may be - * useful for some applications. From libpng 1.6.0 this function is also used - * internally to implement the png_info release part of the 'struct' destroy - * APIs. This ensures that all possible approaches free the same data (all of - * it). - */ -void PNGAPI -png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr) -{ - png_inforp info_ptr = NULL; - - png_debug(1, "in png_destroy_info_struct"); - - if (png_ptr == NULL) - return; - - if (info_ptr_ptr != NULL) - info_ptr = *info_ptr_ptr; - - if (info_ptr != NULL) - { - /* Do this first in case of an error below; if the app implements its own - * memory management this can lead to png_free calling png_error, which - * will abort this routine and return control to the app error handler. - * An infinite loop may result if it then tries to free the same info - * ptr. - */ - *info_ptr_ptr = NULL; - - png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); - memset(info_ptr, 0, (sizeof *info_ptr)); - png_free(png_ptr, info_ptr); - } -} - -void PNGAPI -png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask, - int num) -{ - png_debug(1, "in png_free_data"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - -#ifdef PNG_TEXT_SUPPORTED - /* Free text item num or (if num == -1) all text items */ - if (info_ptr->text != 0 && - ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0) - { - if (num != -1) - { - png_free(png_ptr, info_ptr->text[num].key); - info_ptr->text[num].key = NULL; - } - - else - { - int i; - - for (i = 0; i < info_ptr->num_text; i++) - png_free(png_ptr, info_ptr->text[i].key); - - png_free(png_ptr, info_ptr->text); - info_ptr->text = NULL; - info_ptr->num_text = 0; - info_ptr->max_text = 0; - } - } -#endif - -#ifdef PNG_tRNS_SUPPORTED - /* Free any tRNS entry */ - if (((mask & PNG_FREE_TRNS) & info_ptr->free_me) != 0) - { - info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_tRNS); - png_free(png_ptr, info_ptr->trans_alpha); - info_ptr->trans_alpha = NULL; - info_ptr->num_trans = 0; - } -#endif - -#ifdef PNG_sCAL_SUPPORTED - /* Free any sCAL entry */ - if (((mask & PNG_FREE_SCAL) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->scal_s_width); - png_free(png_ptr, info_ptr->scal_s_height); - info_ptr->scal_s_width = NULL; - info_ptr->scal_s_height = NULL; - info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_sCAL); - } -#endif - -#ifdef PNG_pCAL_SUPPORTED - /* Free any pCAL entry */ - if (((mask & PNG_FREE_PCAL) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->pcal_purpose); - png_free(png_ptr, info_ptr->pcal_units); - info_ptr->pcal_purpose = NULL; - info_ptr->pcal_units = NULL; - - if (info_ptr->pcal_params != NULL) - { - int i; - - for (i = 0; i < info_ptr->pcal_nparams; i++) - png_free(png_ptr, info_ptr->pcal_params[i]); - - png_free(png_ptr, info_ptr->pcal_params); - info_ptr->pcal_params = NULL; - } - info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_pCAL); - } -#endif - -#ifdef PNG_iCCP_SUPPORTED - /* Free any profile entry */ - if (((mask & PNG_FREE_ICCP) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->iccp_name); - png_free(png_ptr, info_ptr->iccp_profile); - info_ptr->iccp_name = NULL; - info_ptr->iccp_profile = NULL; - info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_iCCP); - } -#endif - -#ifdef PNG_sPLT_SUPPORTED - /* Free a given sPLT entry, or (if num == -1) all sPLT entries */ - if (info_ptr->splt_palettes != 0 && - ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0) - { - if (num != -1) - { - png_free(png_ptr, info_ptr->splt_palettes[num].name); - png_free(png_ptr, info_ptr->splt_palettes[num].entries); - info_ptr->splt_palettes[num].name = NULL; - info_ptr->splt_palettes[num].entries = NULL; - } - - else - { - int i; - - for (i = 0; i < info_ptr->splt_palettes_num; i++) - { - png_free(png_ptr, info_ptr->splt_palettes[i].name); - png_free(png_ptr, info_ptr->splt_palettes[i].entries); - } - - png_free(png_ptr, info_ptr->splt_palettes); - info_ptr->splt_palettes = NULL; - info_ptr->splt_palettes_num = 0; - info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_sPLT); - } - } -#endif - -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED - if (info_ptr->unknown_chunks != 0 && - ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0) - { - if (num != -1) - { - png_free(png_ptr, info_ptr->unknown_chunks[num].data); - info_ptr->unknown_chunks[num].data = NULL; - } - - else - { - int i; - - for (i = 0; i < info_ptr->unknown_chunks_num; i++) - png_free(png_ptr, info_ptr->unknown_chunks[i].data); - - png_free(png_ptr, info_ptr->unknown_chunks); - info_ptr->unknown_chunks = NULL; - info_ptr->unknown_chunks_num = 0; - } - } -#endif - -#ifdef PNG_hIST_SUPPORTED - /* Free any hIST entry */ - if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->hist); - info_ptr->hist = NULL; - info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_hIST); - } -#endif - - /* Free any PLTE entry that was internally allocated */ - if (((mask & PNG_FREE_PLTE) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->palette); - info_ptr->palette = NULL; - info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_PLTE); - info_ptr->num_palette = 0; - } - -#ifdef PNG_INFO_IMAGE_SUPPORTED - /* Free any image bits attached to the info structure */ - if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0) - { - if (info_ptr->row_pointers != 0) - { - png_uint_32 row; - for (row = 0; row < info_ptr->height; row++) - png_free(png_ptr, info_ptr->row_pointers[row]); - - png_free(png_ptr, info_ptr->row_pointers); - info_ptr->row_pointers = NULL; - } - info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_IDAT); - } -#endif - - if (num != -1) - mask &= PNG_BIC_MASK(PNG_FREE_MUL); - - info_ptr->free_me &= ~mask; -} -#endif /* READ || WRITE */ - -/* This function returns a pointer to the io_ptr associated with the user - * functions. The application should free any memory associated with this - * pointer before png_write_destroy() or png_read_destroy() are called. - */ -png_voidp PNGAPI -png_get_io_ptr(png_const_structrp png_ptr) -{ - if (png_ptr == NULL) - return (NULL); - - return (png_ptr->io_ptr); -} - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -# ifdef PNG_STDIO_SUPPORTED -/* Initialize the default input/output functions for the PNG file. If you - * use your own read or write routines, you can call either png_set_read_fn() - * or png_set_write_fn() instead of png_init_io(). If you have defined - * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a - * function of your own because "FILE *" isn't necessarily available. - */ -void PNGAPI -png_init_io(png_structrp png_ptr, png_FILE_p fp) -{ - png_debug(1, "in png_init_io"); - - if (png_ptr == NULL) - return; - - if (png_ptr->rw_data_fn == NULL) - { -# ifdef PNG_READ_SUPPORTED - if (png_ptr->read_struct) - png_set_read_fn(png_ptr, fp, png_default_read_data); -# ifdef PNG_WRITE_SUPPORTED - else -# endif /* WRITE */ -# endif /* READ */ -# ifdef PNG_WRITE_SUPPORTED - if (!png_ptr->read_struct) -# ifdef PNG_WRITE_FLUSH_SUPPORTED - png_set_write_fn(png_ptr, fp, png_default_write_data, - png_default_flush); -# else - png_set_write_fn(png_ptr, fp, png_default_write_data, NULL); -# endif -# endif /* WRITE */ - } - - else - png_ptr->io_ptr = fp; -} -# endif /* STDIO */ - -# ifdef PNG_TIME_RFC1123_SUPPORTED -/* Convert the supplied time into an RFC 1123 string suitable for use in - * a "Creation Time" or other text-based time string. - */ -int PNGAPI -png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime) -{ - static PNG_CONST char short_months[12][4] = - {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - - if (out == NULL) - return 0; - - if (ptime->year > 9999 /* RFC1123 limitation */ || - ptime->month == 0 || ptime->month > 12 || - ptime->day == 0 || ptime->day > 31 || - ptime->hour > 23 || ptime->minute > 59 || - ptime->second > 60) - return 0; - - { - size_t pos = 0; - char number_buf[5]; /* enough for a four-digit year */ - -# define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string)) -# define APPEND_NUMBER(format, value)\ - APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value))) -# define APPEND(ch) if (pos < 28) out[pos++] = (ch) - - APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day); - APPEND(' '); - APPEND_STRING(short_months[(ptime->month - 1)]); - APPEND(' '); - APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year); - APPEND(' '); - APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour); - APPEND(':'); - APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute); - APPEND(':'); - APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second); - APPEND_STRING(" +0000"); /* This reliably terminates the buffer */ - -# undef APPEND -# undef APPEND_NUMBER -# undef APPEND_STRING - } - - return 1; -} -# endif /* TIME_RFC1123 */ - -#endif /* READ || WRITE */ - -png_const_charp PNGAPI -png_get_copyright(png_const_structrp png_ptr) -{ - PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ -#ifdef PNG_STRING_COPYRIGHT - return PNG_STRING_COPYRIGHT -#else -# ifdef __STDC__ - return PNG_STRING_NEWLINE \ - "libpng version 1.7.0beta90 - August 28, 2017" PNG_STRING_NEWLINE \ - "Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson" \ - PNG_STRING_NEWLINE \ - "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ - "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ - PNG_STRING_NEWLINE; -# else - return "libpng version 1.7.0beta90 - August 28, 2017\ - Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson\ - Copyright (c) 1996-1997 Andreas Dilger\ - Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; -# endif -#endif -} - -/* The following return the library version as a short string in the - * format 1.0.0 through 99.99.99zz. To get the version of *.h files - * used with your application, print out PNG_LIBPNG_VER_STRING, which - * is defined in png.h. - * Note: now there is no difference between png_get_libpng_ver() and - * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard, - * it is guaranteed that png.c uses the correct version of png.h. - */ -png_const_charp PNGAPI -png_get_libpng_ver(png_const_structrp png_ptr) -{ - /* Version of *.c files used when building libpng */ - return png_get_header_ver(png_ptr); -} - -png_const_charp PNGAPI -png_get_header_ver(png_const_structrp png_ptr) -{ - /* Version of *.h files used when building libpng */ - PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ - return PNG_LIBPNG_VER_STRING; -} - -png_const_charp PNGAPI -png_get_header_version(png_const_structrp png_ptr) -{ - /* Returns longer string containing both version and date */ - PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ -#ifdef __STDC__ -# ifndef PNG_READ_SUPPORTED - return PNG_HEADER_VERSION_STRING " (NO READ SUPPORT)" PNG_STRING_NEWLINE; -# else - return PNG_HEADER_VERSION_STRING PNG_STRING_NEWLINE; -# endif -#else - return PNG_HEADER_VERSION_STRING; -#endif -} - -#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED -/* NOTE: this routine is not used internally! */ -/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth - * large of png_color. This lets grayscale images be treated as - * paletted. Most useful for gamma correction and simplification - * of code. This API is not used internally. - */ -void PNGAPI -png_build_grayscale_palette(int bit_depth, png_colorp palette) -{ - int num_palette; - png_byte color_inc; - int i; - png_byte v; - - png_debug(1, "in png_do_build_grayscale_palette"); - - if (palette == NULL) - return; - - switch (bit_depth) - { - case 1: - num_palette = 2; - color_inc = 0xff; - break; - - case 2: - num_palette = 4; - color_inc = 0x55; - break; - - case 4: - num_palette = 16; - color_inc = 0x11; - break; - - case 8: - num_palette = 256; - color_inc = 1; - break; - - default: - num_palette = 0; - color_inc = 0; - break; - } - - for (i = 0, v = 0; i < num_palette; ++i, v = PNG_BYTE(v+color_inc)) - palette[i].red = palette[i].green = palette[i].blue = v; -} -#endif - -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED -int PNGAPI -png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name) -{ - /* Check chunk_name and return "keep" value if it's on the list, else 0 */ - png_const_bytep p, p_end; - - if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0) - return PNG_HANDLE_CHUNK_AS_DEFAULT; - - p_end = png_ptr->chunk_list; - p = p_end + png_ptr->num_chunk_list*5; /* beyond end */ - - /* The code is the fifth byte after each four byte string. Historically this - * code was always searched from the end of the list, this is no longer - * necessary because the 'set' routine handles duplicate entries correcty. - */ - do /* num_chunk_list > 0, so at least one */ - { - p -= 5; - - if (memcmp(chunk_name, p, 4) == 0) - return p[4]; - } - while (p > p_end); - - /* This means that known chunks should be processed and unknown chunks should - * be handled according to the value of png_ptr->unknown_default; this can be - * confusing because, as a result, there are two levels of defaulting for - * unknown chunks. - */ - return PNG_HANDLE_CHUNK_AS_DEFAULT; -} -#endif /* SET_UNKNOWN_CHUNKS */ - -/* This function was added to libpng-1.0.7 */ -png_uint_32 PNGAPI -png_access_version_number(void) -{ - /* Version of *.c files used when building libpng */ - return((png_uint_32)PNG_LIBPNG_VER); -} - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -/* Ensure that png_ptr->zstream.msg holds some appropriate error message string. - * If it doesn't 'ret' is used to set it to something appropriate, even in cases - * like Z_OK or Z_STREAM_END where the error code is apparently a success code. - */ -void /* PRIVATE */ -png_zstream_error(z_stream *zstream, int ret) -{ - /* Translate 'ret' into an appropriate error string, priority is given to the - * one in zstream if set. This always returns a string, even in cases like - * Z_OK or Z_STREAM_END where the error code is a success code. - */ - if (zstream->msg == NULL) switch (ret) - { - default: - case Z_OK: - zstream->msg = PNGZ_MSG_CAST("unexpected zlib return code"); - break; - - case Z_STREAM_END: - /* Normal exit */ - zstream->msg = PNGZ_MSG_CAST("unexpected end of LZ stream"); - break; - - case Z_NEED_DICT: - /* This means the deflate stream did not have a dictionary; this - * indicates a bogus PNG. - */ - zstream->msg = PNGZ_MSG_CAST("missing LZ dictionary"); - break; - - case Z_ERRNO: - /* gz APIs only: should not happen */ - zstream->msg = PNGZ_MSG_CAST("zlib IO error"); - break; - - case Z_STREAM_ERROR: - /* internal libpng error */ - zstream->msg = PNGZ_MSG_CAST("bad parameters to zlib"); - break; - - case Z_DATA_ERROR: - zstream->msg = PNGZ_MSG_CAST("damaged LZ stream"); - break; - - case Z_MEM_ERROR: - zstream->msg = PNGZ_MSG_CAST("insufficient memory"); - break; - - case Z_BUF_ERROR: - /* End of input or output; not a problem if the caller is doing - * incremental read or write. - */ - zstream->msg = PNGZ_MSG_CAST("truncated"); - break; - - case Z_VERSION_ERROR: - zstream->msg = PNGZ_MSG_CAST("unsupported zlib version"); - break; - - case PNG_UNEXPECTED_ZLIB_RETURN: - /* Compile errors here mean that zlib now uses the value co-opted in - * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above - * and change pngpriv.h. Note that this message is "... return", - * whereas the default/Z_OK one is "... return code". - */ - zstream->msg = PNGZ_MSG_CAST("unexpected zlib return"); - break; - } -} - -/* png_convert_size: a PNGAPI but no longer in png.h, so deleted - * at libpng 1.5.5! - */ - -/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */ -#ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */ -static int -png_colorspace_check_gamma(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_fixed_point gAMA, int from) - /* This is called to check a new gamma value against an existing one. The - * routine returns false if the new gamma value should not be written. - * - * 'from' says where the new gamma value comes from: - * - * 0: the new gamma value is the libpng estimate for an ICC profile - * 1: the new gamma value comes from a gAMA chunk - * 2: the new gamma value comes from an sRGB chunk - * - * API CHANGE: libpng 1.7.0: prior to 1.7 the check below used the build-time - * constant PNG_GAMMA_THRESHOLD_FIXED and the results would therefore depend - * on a parameter that was intended for tuning the READ_GAMMA support. In - * 1.7 a fixed value of +/-1% is used instead; this reflects the fact that - * gamma values are rarely quoted to more than 2 decimal digits of precision. - */ -{ - png_fixed_point gtest; - - if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && - (png_muldiv(>est, colorspace->gamma, PNG_FP_1, gAMA) == 0 || - gtest < PNG_FP_1 - 1000 || gtest > PNG_FP_1 + 1000)) - { - /* Either this is an sRGB image, in which case the calculated gamma - * approximation should match, or this is an image with a profile and the - * value libpng calculates for the gamma of the profile does not match the - * value recorded in the file. The former, sRGB, case is an error, the - * latter is just a warning. - */ - if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2) - { - png_chunk_report(png_ptr, "gamma value does not match sRGB", - PNG_CHUNK_ERROR); - /* Do not overwrite an sRGB value */ - return from == 2; - } - - else /* sRGB tag not involved */ - { - png_chunk_report(png_ptr, "gamma value does not match libpng estimate", - PNG_CHUNK_WARNING); - return from == 1; - } - } - - return 1; -} - -void /* PRIVATE */ -png_colorspace_set_gamma(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_fixed_point gAMA) -{ - /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't - * occur. Since the fixed point representation is asymmetrical it is - * possible for 1/gamma to overflow the limit of 21474 and this means the - * gamma value must be at least 5/100000 and hence at most 20000.0. For - * safety the limits here are a little narrower. The values are 0.00016 to - * 6250.0, which are truly ridiculous gamma values (and will produce - * displays that are all black or all white.) - * - * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk - * handling code, which only required the value to be >0. - */ -# if (defined PNG_TRANSFORM_MECH_SUPPORTED) &&\ - (defined PNG_ERROR_TEXT_SUPPORTED) -# define ERRMSG 1 -# else -# define ERRMSG 0 -# endif - -# if ERRMSG - png_const_charp errmsg; -# endif - - if (gAMA < 16 || gAMA > 625000000) - { -# if ERRMSG - errmsg = "gamma value out of range"; -# endif - } - -# ifdef PNG_READ_gAMA_SUPPORTED - /* Allow the application to set the gamma value more than once */ - else if (png_ptr->read_struct && - (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0) - { -# if ERRMSG - errmsg = "duplicate"; -# endif - } -# endif - - /* Do nothing if the colorspace is already invalid */ - else if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) - return; - - else - { - if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA, - 1/*from gAMA*/) != 0) - { - /* Store this gamma value. */ - colorspace->gamma = gAMA; - colorspace->flags |= - (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA); - } - - /* At present if the check_gamma test fails the gamma of the colorspace is - * not updated however the colorspace is not invalidated. This - * corresponds to the case where the existing gamma comes from an sRGB - * chunk or profile. An error message has already been output. - */ - return; - } - - /* Error exit - errmsg has been set. */ -# undef ERRMSG - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR); -} - -void /* PRIVATE */ -png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr) -{ - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) - { - /* Everything is invalid */ - info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB| - PNG_INFO_iCCP); - -# ifdef PNG_COLORSPACE_SUPPORTED - /* Clean up the iCCP profile now if it won't be used. */ - png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/); -# else - PNG_UNUSED(png_ptr) -# endif - } - - else - { -# ifdef PNG_COLORSPACE_SUPPORTED - /* Leave the INFO_iCCP flag set if the pngset.c code has already set - * it; this allows a PNG to contain a profile which matches sRGB and - * yet still have that profile retrievable by the application. - */ - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0) - info_ptr->valid |= PNG_INFO_sRGB; - - else - info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_sRGB); - - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - info_ptr->valid |= PNG_INFO_cHRM; - - else - info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_cHRM); -# endif - - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0) - info_ptr->valid |= PNG_INFO_gAMA; - - else - info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_gAMA); - } -} - -#ifdef PNG_READ_SUPPORTED -void /* PRIVATE */ -png_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr) -{ - if (info_ptr == NULL) /* reduce code size; check here not in the caller */ - return; - - info_ptr->colorspace = png_ptr->colorspace; - png_colorspace_sync_info(png_ptr, info_ptr); -} -#endif -#endif - -#ifdef PNG_COLORSPACE_SUPPORTED -/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */ -static png_fixed_point -png_reciprocal(png_fixed_point a) -{ -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - double r = floor(1E10/a+.5); - - if (r <= 2147483647. && r >= -2147483648.) - return (png_fixed_point)r; -#else - png_fixed_point res; - - if (png_muldiv(&res, PNG_FP_1, PNG_FP_1, a) != 0) - return res; -#endif - - return 0; /* error/overflow */ -} - -/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for - * cHRM, as opposed to using chromaticities. These internal APIs return - * non-zero on a parameter error. The X, Y and Z values are required to be - * positive and less than 1.0. - */ -static int -png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ) -{ - png_int_32 d, dwhite, whiteX, whiteY; - - d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z; - if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d) == 0) - return 1; - if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d) == 0) - return 1; - dwhite = d; - whiteX = XYZ->red_X; - whiteY = XYZ->red_Y; - - d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z; - if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d) == 0) - return 1; - if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d) == 0) - return 1; - dwhite += d; - whiteX += XYZ->green_X; - whiteY += XYZ->green_Y; - - d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z; - if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d) == 0) - return 1; - if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d) == 0) - return 1; - dwhite += d; - whiteX += XYZ->blue_X; - whiteY += XYZ->blue_Y; - - /* The reference white is simply the sum of the end-point (X,Y,Z) vectors, - * thus: - */ - if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0) - return 1; - if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0) - return 1; - - return 0; -} - -static int -png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy) -{ - png_fixed_point red_inverse, green_inverse, blue_scale; - png_fixed_point left, right, denominator; - - /* Check xy and, implicitly, z. Note that wide gamut color spaces typically - * have end points with 0 tristimulus values (these are impossible end - * points, but they are used to cover the possible colors). We check - * xy->whitey against 5, not 0, to avoid a possible integer overflow. - */ - if (xy->redx < 0 || xy->redx > PNG_FP_1) return 1; - if (xy->redy < 0 || xy->redy > PNG_FP_1-xy->redx) return 1; - if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1; - if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1; - if (xy->bluex < 0 || xy->bluex > PNG_FP_1) return 1; - if (xy->bluey < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1; - if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1; - if (xy->whitey < 5 || xy->whitey > PNG_FP_1-xy->whitex) return 1; - - /* The reverse calculation is more difficult because the original tristimulus - * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8 - * derived values were recorded in the cHRM chunk; - * (red,green,blue,white)x(x,y). This loses one degree of freedom and - * therefore an arbitrary ninth value has to be introduced to undo the - * original transformations. - * - * Think of the original end-points as points in (X,Y,Z) space. The - * chromaticity values (c) have the property: - * - * C - * c = --------- - * X + Y + Z - * - * For each c (x,y,z) from the corresponding original C (X,Y,Z). Thus the - * three chromaticity values (x,y,z) for each end-point obey the - * relationship: - * - * x + y + z = 1 - * - * This describes the plane in (X,Y,Z) space that intersects each axis at the - * value 1.0; call this the chromaticity plane. Thus the chromaticity - * calculation has scaled each end-point so that it is on the x+y+z=1 plane - * and chromaticity is the intersection of the vector from the origin to the - * (X,Y,Z) value with the chromaticity plane. - * - * To fully invert the chromaticity calculation we would need the three - * end-point scale factors, (red-scale, green-scale, blue-scale), but these - * were not recorded. Instead we calculated the reference white (X,Y,Z) and - * recorded the chromaticity of this. The reference white (X,Y,Z) would have - * given all three of the scale factors since: - * - * color-C = color-c * color-scale - * white-C = red-C + green-C + blue-C - * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale - * - * But cHRM records only white-x and white-y, so we have lost the white scale - * factor: - * - * white-C = white-c*white-scale - * - * To handle this the inverse transformation makes an arbitrary assumption - * about white-scale: - * - * Assume: white-Y = 1.0 - * Hence: white-scale = 1/white-y - * Or: red-Y + green-Y + blue-Y = 1.0 - * - * Notice the last statement of the assumption gives an equation in three of - * the nine values we want to calculate. 8 more equations come from the - * above routine as summarised at the top above (the chromaticity - * calculation): - * - * Given: color-x = color-X / (color-X + color-Y + color-Z) - * Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0 - * - * This is 9 simultaneous equations in the 9 variables "color-C" and can be - * solved by Cramer's rule. Cramer's rule requires calculating 10 9x9 matrix - * determinants, however this is not as bad as it seems because only 28 of - * the total of 90 terms in the various matrices are non-zero. Nevertheless - * Cramer's rule is notoriously numerically unstable because the determinant - * calculation involves the difference of large, but similar, numbers. It is - * difficult to be sure that the calculation is stable for real world values - * and it is certain that it becomes unstable where the end points are close - * together. - * - * So this code uses the perhaps slightly less optimal but more - * understandable and totally obvious approach of calculating color-scale. - * - * This algorithm depends on the precision in white-scale and that is - * (1/white-y), so we can immediately see that as white-y approaches 0 the - * accuracy inherent in the cHRM chunk drops off substantially. - * - * libpng arithmetic: a simple inversion of the above equations - * ------------------------------------------------------------ - * - * white_scale = 1/white-y - * white-X = white-x * white-scale - * white-Y = 1.0 - * white-Z = (1 - white-x - white-y) * white_scale - * - * white-C = red-C + green-C + blue-C - * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale - * - * This gives us three equations in (red-scale,green-scale,blue-scale) where - * all the coefficients are now known: - * - * red-x*red-scale + green-x*green-scale + blue-x*blue-scale - * = white-x/white-y - * red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1 - * red-z*red-scale + green-z*green-scale + blue-z*blue-scale - * = (1 - white-x - white-y)/white-y - * - * In the last equation color-z is (1 - color-x - color-y) so we can add all - * three equations together to get an alternative third: - * - * red-scale + green-scale + blue-scale = 1/white-y = white-scale - * - * So now we have a Cramer's rule solution where the determinants are just - * 3x3 - far more tractible. Unfortunately 3x3 determinants still involve - * multiplication of three coefficients so we can't guarantee to avoid - * overflow in the libpng fixed point representation. Using Cramer's rule in - * floating point is probably a good choice here, but it's not an option for - * fixed point. Instead proceed to simplify the first two equations by - * eliminating what is likely to be the largest value, blue-scale: - * - * blue-scale = white-scale - red-scale - green-scale - * - * Hence: - * - * (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale = - * (white-x - blue-x)*white-scale - * - * (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale = - * 1 - blue-y*white-scale - * - * And now we can trivially solve for (red-scale,green-scale): - * - * green-scale = - * (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale - * ----------------------------------------------------------- - * green-x - blue-x - * - * red-scale = - * 1 - blue-y*white-scale - (green-y - blue-y) * green-scale - * --------------------------------------------------------- - * red-y - blue-y - * - * Hence: - * - * red-scale = - * ( (green-x - blue-x) * (white-y - blue-y) - - * (green-y - blue-y) * (white-x - blue-x) ) / white-y - * ------------------------------------------------------------------------- - * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) - * - * green-scale = - * ( (red-y - blue-y) * (white-x - blue-x) - - * (red-x - blue-x) * (white-y - blue-y) ) / white-y - * ------------------------------------------------------------------------- - * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) - * - * Accuracy: - * The input values have 5 decimal digits of accuracy. The values are all in - * the range 0 < value < 1, so simple products are in the same range but may - * need up to 10 decimal digits to preserve the original precision and avoid - * underflow. Because we are using a 32-bit signed representation we cannot - * match this; the best is a little over 9 decimal digits, less than 10. - * - * The approach used here is to preserve the maximum precision within the - * signed representation. Because the red-scale calculation above uses the - * difference between two products of values that must be in the range -1..+1 - * it is sufficient to divide the product by 7; ceil(100,000/32767*2). The - * factor is irrelevant in the calculation because it is applied to both - * numerator and denominator. - * - * Note that the values of the differences of the products of the - * chromaticities in the above equations tend to be small, for example for - * the sRGB chromaticities they are: - * - * red numerator: -0.04751 - * green numerator: -0.08788 - * denominator: -0.2241 (without white-y multiplication) - * - * The resultant Y coefficients from the chromaticities of some widely used - * color space definitions are (to 15 decimal places): - * - * sRGB - * 0.212639005871510 0.715168678767756 0.072192315360734 - * Kodak ProPhoto - * 0.288071128229293 0.711843217810102 0.000085653960605 - * Adobe RGB - * 0.297344975250536 0.627363566255466 0.075291458493998 - * Adobe Wide Gamut RGB - * 0.258728243040113 0.724682314948566 0.016589442011321 - */ - /* By the argument, above overflow should be impossible here. The return - * value of 2 indicates an internal error to the caller. - */ - if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7) == 0) - return 2; - if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7) == 0) - return 2; - denominator = left - right; - - /* Now find the red numerator. */ - if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7) == 0) - return 2; - if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7) == 0) - return 2; - - /* Overflow is possible here and it indicates an extreme set of PNG cHRM - * chunk values. This calculation actually returns the reciprocal of the - * scale value because this allows us to delay the multiplication of white-y - * into the denominator, which tends to produce a small number. - */ - if (png_muldiv(&red_inverse, xy->whitey, denominator, left-right) == 0 || - red_inverse <= xy->whitey /* r+g+b scales = white scale */) - return 1; - - /* Similarly for green_inverse: */ - if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7) == 0) - return 2; - if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7) == 0) - return 2; - if (png_muldiv(&green_inverse, xy->whitey, denominator, left-right) == 0 || - green_inverse <= xy->whitey) - return 1; - - /* And the blue scale, the checks above guarantee this can't overflow but it - * can still produce 0 for extreme cHRM values. - */ - blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) - - png_reciprocal(green_inverse); - if (blue_scale <= 0) - return 1; - - - /* And fill in the png_XYZ: */ - if (png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse) == 0) - return 1; - if (png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse) == 0) - return 1; - if (png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1, - red_inverse) == 0) - return 1; - - if (png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse) == 0) - return 1; - if (png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse) == 0) - return 1; - if (png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1, - green_inverse) == 0) - return 1; - - if (png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1) == 0) - return 1; - if (png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1) == 0) - return 1; - if (png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale, - PNG_FP_1) == 0) - return 1; - - return 0; /*success*/ -} - -static int -png_XYZ_normalize(png_XYZ *XYZ) -{ - png_int_32 Y; - - if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 || - XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 || - XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0) - return 1; - - /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1. - * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore - * relying on addition of two positive values producing a negative one is not - * safe. - */ - Y = XYZ->red_Y; - if (0x7fffffff - Y < XYZ->green_X) - return 1; - Y += XYZ->green_Y; - if (0x7fffffff - Y < XYZ->blue_X) - return 1; - Y += XYZ->blue_Y; - - if (Y != PNG_FP_1) - { - if (png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y) == 0) - return 1; - - if (png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y) == 0) - return 1; - - if (png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y) == 0) - return 1; - } - - return 0; -} - -static int -png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta) -{ - /* Allow an error of +/-0.01 (absolute value) on each chromaticity */ - if (PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) || - PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) || - PNG_OUT_OF_RANGE(xy1->redx, xy2->redx, delta) || - PNG_OUT_OF_RANGE(xy1->redy, xy2->redy, delta) || - PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) || - PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) || - PNG_OUT_OF_RANGE(xy1->bluex, xy2->bluex, delta) || - PNG_OUT_OF_RANGE(xy1->bluey, xy2->bluey, delta)) - return 0; - return 1; -} - -/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM - * chunk chromaticities. Earlier checks used to simply look for the overflow - * condition (where the determinant of the matrix to solve for XYZ ends up zero - * because the chromaticity values are not all distinct.) Despite this it is - * theoretically possible to produce chromaticities that are apparently valid - * but that rapidly degrade to invalid, potentially crashing, sets because of - * arithmetic inaccuracies when calculations are performed on them. The new - * check is to round-trip xy -> XYZ -> xy and then check that the result is - * within a small percentage of the original. - */ -static int -png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy) -{ - int result; - png_xy xy_test; - - /* As a side-effect this routine also returns the XYZ endpoints. */ - result = png_XYZ_from_xy(XYZ, xy); - if (result != 0) - return result; - - result = png_xy_from_XYZ(&xy_test, XYZ); - if (result != 0) - return result; - - if (png_colorspace_endpoints_match(xy, &xy_test, - 5/*actually, the math is pretty accurate*/) != 0) - return 0; - - /* Too much slip */ - return 1; -} - -/* This is the check going the other way. The XYZ is modified to normalize it - * (another side-effect) and the xy chromaticities are returned. - */ -static int -png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ) -{ - int result; - png_XYZ XYZtemp; - - result = png_XYZ_normalize(XYZ); - if (result != 0) - return result; - - result = png_xy_from_XYZ(xy, XYZ); - if (result != 0) - return result; - - XYZtemp = *XYZ; - return png_colorspace_check_xy(&XYZtemp, xy); -} - -/* Used to check for an endpoint match against sRGB */ -static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */ -{ - /* color x y */ - /* red */ 64000, 33000, - /* green */ 30000, 60000, - /* blue */ 15000, 6000, - /* white */ 31270, 32900 -}; - -static int -png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr, - png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ, - int preferred) -{ - if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) - return 0; - - /* The consistency check is performed on the chromaticities; this factors out - * variations because of the normalization (or not) of the end point Y - * values. - */ - if (preferred < 2 && - (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - /* The end points must be reasonably close to any we already have. The - * following allows an error of up to +/-.001 - */ - if (png_colorspace_endpoints_match(xy, &colorspace->end_points_xy, - 100) == 0) - { - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_benign_error(png_ptr, "inconsistent chromaticities"); - return 0; /* failed */ - } - - /* Only overwrite with preferred values */ - if (preferred == 0) - return 1; /* ok, but no change */ - } - - colorspace->end_points_xy = *xy; - colorspace->end_points_XYZ = *XYZ; - colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS; - - /* The end points are normally quoted to two decimal digits, so allow +/-0.01 - * on this test. - */ - if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000) != 0) - colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB; - - else - colorspace->flags &= PNG_COLORSPACE_CANCEL( - PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); - - return 2; /* ok and changed */ -} - -int /* PRIVATE */ -png_colorspace_set_chromaticities(png_const_structrp png_ptr, - png_colorspacerp colorspace, const png_xy *xy, int preferred) -{ - /* We must check the end points to ensure they are reasonable - in the past - * color management systems have crashed as a result of getting bogus - * colorant values, while this isn't the fault of libpng it is the - * responsibility of libpng because PNG carries the bomb and libpng is in a - * position to protect against it. - */ - png_XYZ XYZ; - - switch (png_colorspace_check_xy(&XYZ, xy)) - { - case 0: /* success */ - return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ, - preferred); - - case 1: - /* We can't invert the chromaticities so we can't produce value XYZ - * values. Likely as not a color management system will fail too. - */ - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_benign_error(png_ptr, "invalid chromaticities"); - break; - - default: - /* libpng is broken; this should be a warning but if it happens we - * want error reports so for the moment it is an error. - */ - colorspace->flags |= PNG_COLORSPACE_INVALID; - impossible("error checking chromaticities"); - break; - } - - return 0; /* failed */ -} - -int /* PRIVATE */ -png_colorspace_set_endpoints(png_const_structrp png_ptr, - png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred) -{ - png_XYZ XYZ = *XYZ_in; - png_xy xy; - - switch (png_colorspace_check_XYZ(&xy, &XYZ)) - { - case 0: - return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ, - preferred); - - case 1: - /* End points are invalid. */ - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_benign_error(png_ptr, "invalid end points"); - break; - - default: - colorspace->flags |= PNG_COLORSPACE_INVALID; - impossible("error checking chromaticities"); - break; - } - - return 0; /* failed */ -} - -#if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED) -/* Error message generation */ -static char -png_icc_tag_char(png_uint_32 byte) -{ - byte &= 0xff; - if (byte >= 32 && byte <= 126) - return (char)/*SAFE*/byte; - else - return '?'; -} - -static void -png_icc_tag_name(char *name, png_uint_32 tag) -{ - name[0] = '\''; - name[1] = png_icc_tag_char(tag >> 24); - name[2] = png_icc_tag_char(tag >> 16); - name[3] = png_icc_tag_char(tag >> 8); - name[4] = png_icc_tag_char(tag ); - name[5] = '\''; -} - -static int -is_ICC_signature_char(png_alloc_size_t it) -{ - return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) || - (it >= 97 && it <= 122); -} - -static int -is_ICC_signature(png_alloc_size_t it) -{ - return is_ICC_signature_char(it >> 24) /* checks all the top bits */ && - is_ICC_signature_char((it >> 16) & 0xff) && - is_ICC_signature_char((it >> 8) & 0xff) && - is_ICC_signature_char(it & 0xff); -} - -static int -png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_alloc_size_t value, png_const_charp reason) -{ - size_t pos; - char message[196]; /* see below for calculation */ - - if (colorspace != NULL) - colorspace->flags |= PNG_COLORSPACE_INVALID; - - pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */ - pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */ - pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */ - if (is_ICC_signature(value) != 0) - { - /* So 'value' is at most 4 bytes and the following cast is safe */ - png_icc_tag_name(message+pos, (png_uint_32)value); - pos += 6; /* total +8; less than the else clause */ - message[pos++] = ':'; - message[pos++] = ' '; - } -# ifdef PNG_WARNINGS_SUPPORTED - else - { - char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/ - - pos = png_safecat(message, (sizeof message), pos, - png_format_number(number, number+(sizeof number), - PNG_NUMBER_FORMAT_x, value)); - pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/ - } -# endif - /* The 'reason' is an arbitrary message, allow +79 maximum 195 */ - pos = png_safecat(message, (sizeof message), pos, reason); - PNG_UNUSED(pos) - - /* This is recoverable, but make it unconditionally an app_error on write to - * avoid writing invalid ICC profiles into PNG files (i.e., we handle them - * on read, with a warning, but on write unless the app turns off - * application errors the PNG won't be written.) - */ - png_chunk_report(png_ptr, message, - (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR); - - return 0; -} -#endif /* sRGB || iCCP */ - -#ifdef PNG_sRGB_SUPPORTED -int /* PRIVATE */ -png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace, - int intent) -{ - /* sRGB sets known gamma, end points and (from the chunk) intent. */ - /* IMPORTANT: these are not necessarily the values found in an ICC profile - * because ICC profiles store values adapted to a D50 environment; it is - * expected that the ICC profile mediaWhitePointTag will be D50; see the - * checks and code elsewhere to understand this better. - * - * These XYZ values, which are accurate to 5dp, produce rgb to gray - * coefficients of (6968,23435,2366), which are reduced (because they add up - * to 32769 not 32768) to (6968,23434,2366). These are the values that - * libpng has traditionally used (and are the best values given the 15bit - * algorithm used by the rgb to gray code.) - */ - static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */ - { - /* color X Y Z */ - /* red */ 41239, 21264, 1933, - /* green */ 35758, 71517, 11919, - /* blue */ 18048, 7219, 95053 - }; - - /* Do nothing if the colorspace is already invalidated. */ - if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) - return 0; - - /* Check the intent, then check for existing settings. It is valid for the - * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must - * be consistent with the correct values. If, however, this function is - * called below because an iCCP chunk matches sRGB then it is quite - * conceivable that an older app recorded incorrect gAMA and cHRM because of - * an incorrect calculation based on the values in the profile - this does - * *not* invalidate the profile (though it still produces an error, which can - * be ignored.) - */ - if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST) - return png_icc_profile_error(png_ptr, colorspace, "sRGB", - (unsigned)intent, "invalid sRGB rendering intent"); - - if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 && - colorspace->rendering_intent != intent) - return png_icc_profile_error(png_ptr, colorspace, "sRGB", - (unsigned)intent, "inconsistent rendering intents"); - - if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0) - { - png_benign_error(png_ptr, "duplicate sRGB information ignored"); - return 0; - } - - /* If the standard sRGB cHRM chunk does not match the one from the PNG file - * warn but overwrite the value with the correct one. - */ - if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 && - !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy, - 100)) - png_chunk_report(png_ptr, "cHRM chunk does not match sRGB", - PNG_CHUNK_ERROR); - - /* This check is just done for the error reporting - the routine always - * returns true when the 'from' argument corresponds to sRGB (2). - */ - (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE, - 2/*from sRGB*/); - - /* intent: bugs in GCC force 'int' to be used as the parameter type. */ - colorspace->rendering_intent = png_check_u16(png_ptr, intent); - colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT; - - /* endpoints */ - colorspace->end_points_xy = sRGB_xy; - colorspace->end_points_XYZ = sRGB_XYZ; - colorspace->flags |= - (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); - - /* gamma */ - colorspace->gamma = PNG_GAMMA_sRGB_INVERSE; - colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA; - - /* Finally record that we have an sRGB profile */ - colorspace->flags |= - (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB); - - return 1; /* set */ -} -#endif /* sRGB */ - -#ifdef PNG_iCCP_SUPPORTED -/* Encoded value of D50 as an ICC XYZNumber. From the ICC 2010 spec the value - * is XYZ(0.9642,1.0,0.8249), which scales to: - * - * (63189.8112, 65536, 54060.6464) - */ -static const png_byte D50_nCIEXYZ[12] = - { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d }; - -int /* PRIVATE */ -png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length) -{ - if (profile_length < 132) - return png_icc_profile_error(png_ptr, colorspace, name, profile_length, - "too short"); - - if (profile_length & 3) - return png_icc_profile_error(png_ptr, colorspace, name, profile_length, - "invalid length"); - - return 1; -} - -int /* PRIVATE */ -png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length, - png_const_bytep profile/* first 132 bytes only */, int is_color) -{ - png_uint_32 temp; - - /* Length check; this cannot be ignored in this code because profile_length - * is used later to check the tag table, so even if the profile seems over - * long profile_length from the caller must be correct. The caller can fix - * this up on read or write by just passing in the profile header length. - */ - temp = png_get_uint_32(profile); - if (temp != profile_length) - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "length does not match profile"); - - temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */ - if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */ - profile_length < 132+12*temp) /* truncated tag table */ - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "tag count too large"); - - /* The 'intent' must be valid or we can't store it, ICC limits the intent to - * 16 bits. - */ - temp = png_get_uint_32(profile+64); - if (temp >= 0xffff) /* The ICC limit */ - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "invalid rendering intent"); - - /* This is just a warning because the profile may be valid in future - * versions. - */ - if (temp >= PNG_sRGB_INTENT_LAST) - (void)png_icc_profile_error(png_ptr, NULL, name, temp, - "intent outside defined range"); - - /* At this point the tag table can't be checked because it hasn't necessarily - * been loaded; however, various header fields can be checked. These checks - * are for values permitted by the PNG spec in an ICC profile; the PNG spec - * restricts the profiles that can be passed in an iCCP chunk (they must be - * appropriate to processing PNG data!) - */ - - /* Data checks (could be skipped). These checks must be independent of the - * version number; however, the version number doesn't accomodate changes in - * the header fields (just the known tags and the interpretation of the - * data.) - */ - temp = png_get_uint_32(profile+36); /* signature 'ascp' */ - if (temp != 0x61637370) - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "invalid signature"); - - /* Currently the PCS illuminant/adopted white point (the computational - * white point) are required to be D50, - * however the profile contains a record of the illuminant so perhaps ICC - * expects to be able to change this in the future (despite the rationale in - * the introduction for using a fixed PCS adopted white.) Consequently the - * following is just a warning. - */ - if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0) - (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/, - "PCS illuminant is not D50"); - - /* The PNG spec requires this: - * "If the iCCP chunk is present, the image samples conform to the colour - * space represented by the embedded ICC profile as defined by the - * International Color Consortium [ICC]. The colour space of the ICC profile - * shall be an RGB colour space for colour images (PNG colour types 2, 3, and - * 6), or a greyscale colour space for greyscale images (PNG colour types 0 - * and 4)." - * - * This checking code ensures the embedded profile (on either read or write) - * conforms to the specification requirements. Notice that an ICC 'gray' - * color-space profile contains the information to transform the monochrome - * data to XYZ or L*a*b (according to which PCS the profile uses) and this - * should be used in preference to the standard libpng K channel replication - * into R, G and B channels. - * - * Previously it was suggested that an RGB profile on grayscale data could be - * handled. However it it is clear that using an RGB profile in this context - * must be an error - there is no specification of what it means. Thus it is - * almost certainly more correct to ignore the profile. - */ - temp = png_get_uint_32(profile+16); /* data colour space field */ - switch (temp) - { - case 0x52474220: /* 'RGB ' */ - if (!is_color) - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "RGB color space not permitted on grayscale PNG"); - break; - - case 0x47524159: /* 'GRAY' */ - if (is_color) - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "Gray color space not permitted on RGB PNG"); - break; - - default: - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "invalid ICC profile color space"); - } - - /* It is up to the application to check that the profile class matches the - * application requirements; the spec provides no guidance, but it's pretty - * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer - * ('prtr') or 'spac' (for generic color spaces). Issue a warning in these - * cases. Issue an error for device link or abstract profiles - these don't - * contain the records necessary to transform the color-space to anything - * other than the target device (and not even that for an abstract profile). - * Profiles of these classes may not be embedded in images. - */ - temp = png_get_uint_32(profile+12); /* profile/device class */ - switch (temp) - { - case 0x73636E72: /* 'scnr' */ - case 0x6D6E7472: /* 'mntr' */ - case 0x70727472: /* 'prtr' */ - case 0x73706163: /* 'spac' */ - /* All supported */ - break; - - case 0x61627374: /* 'abst' */ - /* May not be embedded in an image */ - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "invalid embedded Abstract ICC profile"); - - case 0x6C696E6B: /* 'link' */ - /* DeviceLink profiles cannot be interpreted in a non-device specific - * fashion, if an app uses the AToB0Tag in the profile the results are - * undefined unless the result is sent to the intended device, - * therefore a DeviceLink profile should not be found embedded in a - * PNG. - */ - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "unexpected DeviceLink ICC profile class"); - - case 0x6E6D636C: /* 'nmcl' */ - /* A NamedColor profile is also device specific, however it doesn't - * contain an AToB0 tag that is open to misinterpretation. Almost - * certainly it will fail the tests below. - */ - (void)png_icc_profile_error(png_ptr, NULL, name, temp, - "unexpected NamedColor ICC profile class"); - break; - - default: - /* To allow for future enhancements to the profile accept unrecognized - * profile classes with a warning, these then hit the test below on the - * tag content to ensure they are backward compatible with one of the - * understood profiles. - */ - (void)png_icc_profile_error(png_ptr, NULL, name, temp, - "unrecognized ICC profile class"); - break; - } - - /* For any profile other than a device link one the PCS must be encoded - * either in XYZ or Lab. - */ - temp = png_get_uint_32(profile+20); - switch (temp) - { - case 0x58595A20: /* 'XYZ ' */ - case 0x4C616220: /* 'Lab ' */ - break; - - default: - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "unexpected ICC PCS encoding"); - } - - return 1; -} - -int /* PRIVATE */ -png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length, - png_const_bytep profile /* header plus whole tag table */) -{ - png_uint_32 tag_count = png_get_uint_32(profile+128); - png_uint_32 itag; - png_const_bytep tag = profile+132; /* The first tag */ - - /* First scan all the tags in the table and add bits to the icc_info value - * (temporarily in 'tags'). - */ - for (itag=0; itag < tag_count; ++itag, tag += 12) - { - png_uint_32 tag_id = png_get_uint_32(tag+0); - png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */ - png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */ - - /* The ICC specification does not exclude zero length tags, therefore the - * start might actually be anywhere if there is no data, but this would be - * a clear abuse of the intent of the standard so the start is checked for - * being in range. All defined tag types have an 8 byte header - a 4 byte - * type signature then 0. - */ - if ((tag_start & 3) != 0) - { - /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is - * only a warning here because libpng does not care about the - * alignment. - */ - (void)png_icc_profile_error(png_ptr, NULL, name, tag_id, - "ICC profile tag start not a multiple of 4"); - } - - /* This is a hard error; potentially it can cause read outside the - * profile. - */ - if (tag_start > profile_length || tag_length > profile_length - tag_start) - return png_icc_profile_error(png_ptr, colorspace, name, tag_id, - "ICC profile tag outside profile"); - } - - return 1; /* success, maybe with warnings */ -} - -#ifdef PNG_sRGB_SUPPORTED -#if PNG_sRGB_PROFILE_CHECKS >= 0 -/* Information about the known ICC sRGB profiles */ -static const struct -{ - png_uint_32 adler, crc, length; - png_uint_32 md5[4]; - png_byte have_md5; - png_byte is_broken; - png_uint_16 intent; - -# define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0) -# define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\ - { adler, crc, length, md5, broke, intent }, - -} png_sRGB_checks[] = -{ - /* This data comes from contrib/tools/checksum-icc run on downloads of - * all four ICC sRGB profiles from www.color.org. - */ - /* adler32, crc32, MD5[4], intent, date, length, file-name */ - PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9, - PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0, - "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc") - - /* ICC sRGB v2 perceptual no black-compensation: */ - PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21, - PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0, - "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc") - - PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae, - PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0, - "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc") - - /* ICC sRGB v4 perceptual */ - PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812, - PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0, - "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc") - - /* The following profiles have no known MD5 checksum. If there is a match - * on the (empty) MD5 the other fields are used to attempt a match and - * a warning is produced. The first two of these profiles have a 'cprt' tag - * which suggests that they were also made by Hewlett Packard. - */ - PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce, - PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0, - "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc") - - /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not - * match the D50 PCS illuminant in the header (it is in fact the D65 values, - * so the white point is recorded as the un-adapted value.) The profiles - * below only differ in one byte - the intent - and are basically the same as - * the previous profile except for the mediaWhitePointTag error and a missing - * chromaticAdaptationTag. - */ - PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552, - PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/, - "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual") - - PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d, - PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/, - "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative") -}; - -static int -png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr, - png_const_bytep profile, uLong adler) -{ - /* The quick check is to verify just the MD5 signature and trust the - * rest of the data. Because the profile has already been verified for - * correctness this is safe. png_colorspace_set_sRGB will check the 'intent' - * field too, so if the profile has been edited with an intent not defined - * by sRGB (but maybe defined by a later ICC specification) the read of - * the profile will fail at that point. - */ - png_uint_32 length = 0; - png_uint_32 intent = 0x10000; /* invalid */ -#if PNG_sRGB_PROFILE_CHECKS > 1 - uLong crc = 0; /* the value for 0 length data */ -#endif - unsigned int i; - -# ifdef PNG_SET_OPTION_SUPPORTED -# ifdef PNG_SKIP_sRGB_CHECK_PROFILE - /* First see if PNG_SKIP_sRGB_CHECK_PROFILE has been set to "on" */ - if (!png_ptr->skip_sRGB_profile_check) -# endif /* SKIP_sRGB_CHECK_PROFILE */ -# endif /* SET_OPTION */ - for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i) - { - if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] && - png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] && - png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] && - png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3]) - { - /* This may be one of the old HP profiles without an MD5, in that - * case we can only use the length and Adler32 (note that these - * are not used by default if there is an MD5!) - */ -# if PNG_sRGB_PROFILE_CHECKS == 0 - if (png_sRGB_checks[i].have_md5 != 0) - return 1+png_sRGB_checks[i].is_broken; -# endif - - /* Profile is unsigned or more checks have been configured in. */ - if (length == 0) - { - length = png_get_uint_32(profile); - intent = png_get_uint_32(profile+64); - } - - /* Length *and* intent must match */ - if (length == png_sRGB_checks[i].length && - intent == (png_uint_32) png_sRGB_checks[i].intent) - { - /* Now calculate the adler32 if not done already. */ - if (adler == 0) - { - adler = adler32(0, NULL, 0); - adler = adler32(adler, profile, length); - } - - if (adler == png_sRGB_checks[i].adler) - { - /* These basic checks suggest that the data has not been - * modified, but if the check level is more than 1 perform - * our own crc32 checksum on the data. - */ -# if PNG_sRGB_PROFILE_CHECKS > 1 - if (crc == 0) - { - crc = crc32(0, NULL, 0); - crc = crc32(crc, profile, length); - } - - /* So this check must pass for the 'return' below to happen. - */ - if (crc == png_sRGB_checks[i].crc) -# endif - { - if (png_sRGB_checks[i].is_broken != 0) - { - /* These profiles are known to have bad data that may cause - * problems if they are used, therefore attempt to - * discourage their use, skip the 'have_md5' warning below, - * which is made irrelevant by this error. - */ - png_chunk_report(png_ptr, "known incorrect sRGB profile", - PNG_CHUNK_ERROR); - } - - /* Warn that this being done; this isn't even an error since - * the profile is perfectly valid, but it would be nice if - * people used the up-to-date ones. - */ - else if (png_sRGB_checks[i].have_md5 == 0) - { - png_chunk_report(png_ptr, - "out-of-date sRGB profile with no signature", - PNG_CHUNK_WARNING); - } - - return 1+png_sRGB_checks[i].is_broken; - } - } - -# if PNG_sRGB_PROFILE_CHECKS > 0 - /* The signature matched, but the profile had been changed in some - * way. This probably indicates a data error or uninformed hacking. - * Fall through to "no match". - */ - png_chunk_report(png_ptr, - "Not recognizing known sRGB profile that has been edited", - PNG_CHUNK_WARNING); - break; -# endif - } - } - } - - return 0; /* no match */ -} - -void /* PRIVATE */ -png_icc_set_sRGB(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_bytep profile, uLong adler) -{ - /* Is this profile one of the known ICC sRGB profiles? If it is, just set - * the sRGB information. - */ - if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0) - (void)png_colorspace_set_sRGB(png_ptr, colorspace, - (int)/*already checked*/png_get_uint_32(profile+64)); -} -#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */ -#endif /* sRGB */ - -int /* PRIVATE */ -png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length, png_const_bytep profile, - int is_color) -{ - if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) - return 0; - - if (png_icc_check_length(png_ptr, colorspace, name, profile_length) != 0 && - png_icc_check_header(png_ptr, colorspace, name, profile_length, profile, - is_color) != 0 && - png_icc_check_tag_table(png_ptr, colorspace, name, profile_length, - profile) != 0) - { -# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0 - /* If no sRGB support, don't try storing sRGB information */ - png_icc_set_sRGB(png_ptr, colorspace, profile, 0); -# endif - return 1; - } - - /* Failure case */ - return 0; -} -#endif /* iCCP */ -#endif /* COLORSPACE */ - -png_alloc_size_t /* PRIVATE */ -png_calc_rowbytes(png_const_structrp png_ptr, unsigned int pixel_depth, - png_uint_32 row_width) -{ - png_alloc_size_t rowbytes = row_width; - - /* Carefully calculate the row buffer size. */ - if (pixel_depth > 8) - { - if ((pixel_depth & 7) != 0) - png_error(png_ptr, "unsupported pixel byte size"); - - pixel_depth >>= 3; /* Now in bytes */ - - if (rowbytes > PNG_SIZE_MAX/pixel_depth) - png_error(png_ptr, "image row exceeds system limits"); - - rowbytes *= pixel_depth; - } - - else /* Less than 1 byte per pixel */ switch (pixel_depth) - { - case 1: rowbytes += 7; rowbytes >>= 3; break; - case 2: rowbytes += 3; rowbytes >>= 2; break; - case 4: rowbytes += 1; rowbytes >>= 1; break; - case 8: break; - default: - png_error(png_ptr, "unsupported pixel bit size"); - } - - return rowbytes; -} - -unsigned int /*PRIVATE*/ -png_max_pixel_block(png_const_structrp png_ptr) -{ - /* Need the *smallest* pixel size that must occur in alignment units. On - * read this is the PNG pixel depth because the read transforms cannot reduce - * the pixel size below the input size or 8-bits, whichever is smaller. - * - * On write the 'pack' transform can pack 8-bit pixels back to a lower bit - * depth, but the lowest bit depth is still given by the PNG pixel size. - */ - const unsigned int pixel_depth = PNG_PIXEL_DEPTH(*png_ptr); - const unsigned int pixel_block = /* count of pixels in a block */ - pixel_depth < 8U ? - PNG_ROW_BUFFER_BYTE_ALIGN * (8U/pixel_depth) : - PNG_ROW_BUFFER_BYTE_ALIGN; /* pixels may be any whole byte size */ - /* The maximum block size in bits is MAX_PIXEL_DEPTH*pixel_block so work out - * the minimum number of pixel blocks that can fit in PNG_ROW_BUFFER_SIZE - * bytes and use this to calculate the maximum number of pixels: - */ - return pixel_block * - ((8U*PNG_ROW_BUFFER_SIZE) / (png_ptr->row_max_pixel_depth*pixel_block)); -} - -void /* PRIVATE */ -png_copy_row(png_const_structrp png_ptr, png_bytep dp, png_const_bytep sp, - png_uint_32 x/*in INPUT*/, png_uint_32 width/*of INPUT*/, - unsigned int pixel_depth, int clear/*clear the final byte*/, int x_in_dest) - /* Copy the row in row_buffer; this is the non-interlaced copy used in both - * the read and write code. 'x_in_dest' specifies whether the 'x' applies to - * the destination (sp->dp[x], x_in_dest tru) or the source (sp[x]->dp, - * x_in_dest false). - */ -{ - png_alloc_size_t cb, offset; - unsigned int remaining; /* remaining bits in a partial byte */ - - /* Copy 'cb' pixels, but take care with the last byte because it may - * be partially written. 'x' must correspond to the start of a byte, check - * that too: - */ - switch (pixel_depth) - { - case 1U: remaining = width & 7U; - debug((x & 7U) == 0U); - cb = width >> 3; - offset = x >> 3; - break; - case 2U: remaining = (width << 1) & 6U; - debug((x & 3U) == 0U); - cb = width >> 2; - offset = x >> 2; - break; - case 4U: remaining = (width << 2) & 4U; - debug((x & 1U) == 0U); - cb = width >> 1; - offset = x >> 1; - break; - case 8U: remaining = 0U; - cb = width; - offset = x; - break; - default: remaining = 0U; - cb = png_calc_rowbytes(png_ptr, pixel_depth, width); - offset = png_calc_rowbytes(png_ptr, pixel_depth, x); - break; - } - - if (x_in_dest) - dp += offset; - - else - sp += offset; - - memcpy(dp, sp, cb); - - if (remaining > 0U) - { - /* 'remaining' is the number of bits still to be copied. Format may be - * little endian; bits to copy in the bottom of 's'. Make 'remaining' - * into a mask of the bits to *preserve* in dp. - */ -# ifdef PNG_TRANSFORM_MECH_SUPPORTED - if ((png_ptr->row_format & PNG_FORMAT_FLAG_SWAPPED) == 0U) - remaining = 0xffU >> remaining; - - else -# endif /* TRANSFORM_MECH */ - remaining = 0xffU << remaining; - - /* remaining is now the bits to *keep* from the destination byte, if - * 'clear' is true the source bytes aren't copied - this is for security - * reasons to avoid copying undefined bits at the end of a row. If - * 'clear' is set the destination bits are not preserved, they are just - * set to 0. - */ - if (clear) - dp[cb] = PNG_BYTE(sp[cb] & ~remaining); - - else - dp[cb] = PNG_BYTE((sp[cb] & ~remaining) | (dp[cb] & remaining)); - } -} - -void /* PRIVATE */ -png_check_IHDR(png_const_structrp png_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_type, int compression_type, - int filter_type) -{ - int error = 0; - - /* Check for width and height valid values */ - if (width == 0) - { - png_warning(png_ptr, "Image width is zero in IHDR"); - error = 1; - } - - if (width > PNG_UINT_31_MAX) - { - png_warning(png_ptr, "Invalid image width in IHDR"); - error = 1; - } - -#ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (width > png_ptr->user_width_max) - { - png_warning(png_ptr, "Image width exceeds user limit in IHDR"); - error = 1; - } -#else - if (width > PNG_USER_WIDTH_MAX) - { - png_warning(png_ptr, "Image width exceeds WIDTH_MAX in IHDR"); - error = 1; - } -#endif - - if (height == 0) - { - png_warning(png_ptr, "Image height is zero in IHDR"); - error = 1; - } - - if (height > PNG_UINT_31_MAX) - { - png_warning(png_ptr, "Invalid image height in IHDR"); - error = 1; - } - -#ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (height > png_ptr->user_height_max) - { - png_warning(png_ptr, "Image height exceeds user limit in IHDR"); - error = 1; - } -#else - if (height > PNG_USER_HEIGHT_MAX) - { - png_warning(png_ptr, "Image height exceeds HEIGHT_MAX in IHDR"); - error = 1; - } -#endif - - /* Check other values */ - if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && - bit_depth != 8 && bit_depth != 16) - { - png_warning(png_ptr, "Invalid bit depth in IHDR"); - error = 1; - } - - if (color_type < 0 || color_type == 1 || - color_type == 5 || color_type > 6) - { - png_warning(png_ptr, "Invalid color type in IHDR"); - error = 1; - } - - if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) || - ((color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_GRAY_ALPHA || - color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8)) - { - png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR"); - error = 1; - } - - if (interlace_type >= PNG_INTERLACE_LAST) - { - png_warning(png_ptr, "Unknown interlace method in IHDR"); - error = 1; - } - - if (compression_type != PNG_COMPRESSION_TYPE_BASE) - { - png_warning(png_ptr, "Unknown compression method in IHDR"); - error = 1; - } - -#ifdef PNG_MNG_FEATURES_SUPPORTED - /* Accept filter_method 64 (intrapixel differencing) only if - * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and - * 2. Libpng did not read a PNG signature (this filter_method is only - * used in PNG datastreams that are embedded in MNG datastreams) and - * 3. The application called png_permit_mng_features with a mask that - * included PNG_FLAG_MNG_FILTER_64 and - * 4. The filter_method is 64 and - * 5. The color_type is RGB or RGBA - */ - if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && - png_ptr->mng_features_permitted != 0) - png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); - - if (filter_type != PNG_FILTER_TYPE_BASE) - { - if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && - (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && - ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && - (color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_RGB_ALPHA))) - { - png_warning(png_ptr, "Invalid filter method in IHDR"); - error = 1; - } - - if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0) - { - png_warning(png_ptr, "Invalid filter method in IHDR"); - error = 1; - } - } - -#else /* !MNG_FEATURES */ - if (filter_type != PNG_FILTER_TYPE_BASE) - { - png_warning(png_ptr, "Unknown filter method in IHDR"); - error = 1; - } -#endif /* !MNG_FEATURES */ - - if (error == 1) - png_error(png_ptr, "Invalid IHDR data"); - - /* Finally, if the IHDR data is correct, check it against the system - * limits (NOTE: this need not be done; the IDAT handling code repeats the - * check in both read and write.) - */ - (void)png_calc_rowbytes(png_ptr, - PNG_COLOR_TYPE_CHANNELS(color_type) * bit_depth, width); -} - -#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) -/* ASCII to fp functions */ -/* Check an ASCII formated floating point value, see the more detailed - * comments in pngpriv.h - */ -/* The following is used internally to preserve the sticky flags */ -#define png_fp_add(state, flags) ((state) |= (flags)) -#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY)) - -int /* PRIVATE */ -png_check_fp_number(png_const_charp string, png_size_t size, int *statep, - png_size_tp whereami) -{ - int state = *statep; - png_size_t i = *whereami; - - while (i < size) - { - int type; - /* First find the type of the next character */ - switch (string[i]) - { - case 43: type = PNG_FP_SAW_SIGN; break; - case 45: type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break; - case 46: type = PNG_FP_SAW_DOT; break; - case 48: type = PNG_FP_SAW_DIGIT; break; - case 49: case 50: case 51: case 52: - case 53: case 54: case 55: case 56: - case 57: type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break; - case 69: - case 101: type = PNG_FP_SAW_E; break; - default: goto PNG_FP_End; - } - - /* Now deal with this type according to the current - * state, the type is arranged to not overlap the - * bits of the PNG_FP_STATE. - */ - switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY)) - { - case PNG_FP_INTEGER + PNG_FP_SAW_SIGN: - if ((state & PNG_FP_SAW_ANY) != 0) - goto PNG_FP_End; /* not a part of the number */ - - png_fp_add(state, type); - break; - - case PNG_FP_INTEGER + PNG_FP_SAW_DOT: - /* Ok as trailer, ok as lead of fraction. */ - if ((state & PNG_FP_SAW_DOT) != 0) /* two dots */ - goto PNG_FP_End; - - else if ((state & PNG_FP_SAW_DIGIT) != 0) /* trailing dot? */ - png_fp_add(state, type); - - else - png_fp_set(state, PNG_FP_FRACTION | type); - - break; - - case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT: - if ((state & PNG_FP_SAW_DOT) != 0) /* delayed fraction */ - png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); - - png_fp_add(state, type | PNG_FP_WAS_VALID); - - break; - - case PNG_FP_INTEGER + PNG_FP_SAW_E: - if ((state & PNG_FP_SAW_DIGIT) == 0) - goto PNG_FP_End; - - png_fp_set(state, PNG_FP_EXPONENT); - - break; - - /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN: - goto PNG_FP_End; ** no sign in fraction */ - - /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT: - goto PNG_FP_End; ** Because SAW_DOT is always set */ - - case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT: - png_fp_add(state, type | PNG_FP_WAS_VALID); - break; - - case PNG_FP_FRACTION + PNG_FP_SAW_E: - /* This is correct because the trailing '.' on an - * integer is handled above - so we can only get here - * with the sequence ".E" (with no preceding digits). - */ - if ((state & PNG_FP_SAW_DIGIT) == 0) - goto PNG_FP_End; - - png_fp_set(state, PNG_FP_EXPONENT); - - break; - - case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN: - if ((state & PNG_FP_SAW_ANY) != 0) - goto PNG_FP_End; /* not a part of the number */ - - png_fp_add(state, PNG_FP_SAW_SIGN); - - break; - - /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT: - goto PNG_FP_End; */ - - case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT: - png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID); - - break; - - /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E: - goto PNG_FP_End; */ - - default: goto PNG_FP_End; /* I.e. break 2 */ - } - - /* The character seems ok, continue. */ - ++i; - } - -PNG_FP_End: - /* Here at the end, update the state and return the correct - * return code. - */ - *statep = state; - *whereami = i; - - return (state & PNG_FP_SAW_DIGIT) != 0; -} - - -/* The same but for a complete string. */ -int -png_check_fp_string(png_const_charp string, png_size_t size) -{ - int state=0; - png_size_t char_index=0; - - if (png_check_fp_number(string, size, &state, &char_index) != 0 && - (char_index == size || string[char_index] == 0)) - return state /* must be non-zero - see above */; - - return 0; /* i.e. fail */ -} -#endif /* pCAL || sCAL */ - -#ifdef PNG_sCAL_SUPPORTED -# ifdef PNG_FLOATING_POINT_SUPPORTED -/* Utility used below - a simple accurate power of ten from an integral - * exponent. - */ -static double -png_pow10(int power) -{ - int recip = 0; - double d = 1; - - /* Handle negative exponent with a reciprocal at the end because - * 10 is exact whereas .1 is inexact in base 2 - */ - if (power < 0) - { - if (power < DBL_MIN_10_EXP) return 0; - recip = 1; power = -power; - } - - if (power > 0) - { - /* Decompose power bitwise. */ - double mult = 10; - do - { - if (power & 1) d *= mult; - mult *= mult; - power >>= 1; - } - while (power > 0); - - if (recip != 0) d = 1/d; - } - /* else power is 0 and d is 1 */ - - return d; -} - -/* Function to format a floating point value in ASCII with a given - * precision. - */ -void /* PRIVATE */ -png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, - double fp, unsigned int precision) -{ - /* We use standard functions from math.h, but not printf because - * that would require stdio. The caller must supply a buffer of - * sufficient size or we will png_error. The tests on size and - * the space in ascii[] consumed are indicated below. - */ - if (precision < 1) - precision = DBL_DIG; - - /* Enforce the limit of the implementation precision too. */ - if (precision > DBL_DIG+1) - precision = DBL_DIG+1; - - /* Basic sanity checks */ - if (size >= precision+5) /* See the requirements below. */ - { - if (fp < 0) - { - fp = -fp; - *ascii++ = 45; /* '-' PLUS 1 TOTAL 1 */ - --size; - } - - if (fp >= DBL_MIN && fp <= DBL_MAX) - { - int exp_b10; /* A base 10 exponent */ - double base; /* 10^exp_b10 */ - - /* First extract a base 10 exponent of the number, - * the calculation below rounds down when converting - * from base 2 to base 10 (multiply by log10(2) - - * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to - * be increased. Note that the arithmetic shift - * performs a floor() unlike C arithmetic - using a - * C multiply would break the following for negative - * exponents. - */ - (void)frexp(fp, &exp_b10); /* exponent to base 2 */ - - exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */ - - /* Avoid underflow here. */ - base = png_pow10(exp_b10); /* May underflow */ - - while (base < DBL_MIN || base < fp) - { - /* And this may overflow. */ - double test = png_pow10(exp_b10+1); - - if (test <= DBL_MAX) - { - ++exp_b10; base = test; - } - - else - break; - } - - /* Normalize fp and correct exp_b10, after this fp is in the - * range [.1,1) and exp_b10 is both the exponent and the digit - * *before* which the decimal point should be inserted - * (starting with 0 for the first digit). Note that this - * works even if 10^exp_b10 is out of range because of the - * test on DBL_MAX above. - */ - fp /= base; - while (fp >= 1) - { - fp /= 10; ++exp_b10; - } - - /* Because of the code above fp may, at this point, be - * less than .1, this is ok because the code below can - * handle the leading zeros this generates, so no attempt - * is made to correct that here. - */ - - { - unsigned int czero, clead, cdigits; - char exponent[10]; - - /* Allow up to two leading zeros - this will not lengthen - * the number compared to using E-n. - */ - if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */ - { - czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */ - exp_b10 = 0; /* Dot added below before first output. */ - } - else - czero = 0; /* No zeros to add */ - - /* Generate the digit list, stripping trailing zeros and - * inserting a '.' before a digit if the exponent is 0. - */ - clead = czero; /* Count of leading zeros */ - cdigits = 0; /* Count of digits in list. */ - - do - { - double d; - - fp *= 10; - /* Use modf here, not floor and subtract, so that - * the separation is done in one step. At the end - * of the loop don't break the number into parts so - * that the final digit is rounded. - */ - if (cdigits+czero+1 < precision+clead) - fp = modf(fp, &d); - - else - { - d = floor(fp + .5); - - if (d > 9) - { - /* Rounding up to 10, handle that here. */ - if (czero > 0) - { - --czero; d = 1; - if (cdigits == 0) --clead; - } - else - { - while (cdigits > 0 && d > 9) - { - int ch = *--ascii; - - if (exp_b10 != (-1)) - ++exp_b10; - - else if (ch == 46) - { - ch = *--ascii; ++size; - /* Advance exp_b10 to '1', so that the - * decimal point happens after the - * previous digit. - */ - exp_b10 = 1; - } - - --cdigits; - d = ch - 47; /* I.e. 1+(ch-48) */ - } - - /* Did we reach the beginning? If so adjust the - * exponent but take into account the leading - * decimal point. - */ - if (d > 9) /* cdigits == 0 */ - { - if (exp_b10 == (-1)) - { - /* Leading decimal point (plus zeros?), if - * we lose the decimal point here it must - * be reentered below. - */ - int ch = *--ascii; - - if (ch == 46) - { - ++size; exp_b10 = 1; - } - - /* Else lost a leading zero, so 'exp_b10' is - * still ok at (-1) - */ - } - else - ++exp_b10; - - /* In all cases we output a '1' */ - d = 1; - } - } - } - fp = 0; /* Guarantees termination below. */ - } - - if (d == 0) - { - ++czero; - if (cdigits == 0) ++clead; - } - else - { - /* Included embedded zeros in the digit count. */ - cdigits += czero - clead; - clead = 0; - - while (czero > 0) - { - /* exp_b10 == (-1) means we just output the decimal - * place - after the DP don't adjust 'exp_b10' any - * more! - */ - if (exp_b10 != (-1)) - { - if (exp_b10 == 0) *ascii++ = 46, --size; - /* PLUS 1: TOTAL 4 */ - --exp_b10; - } - *ascii++ = 48, --czero; - } - - if (exp_b10 != (-1)) - { - if (exp_b10 == 0) - *ascii++ = 46, --size; /* counted above */ - - --exp_b10; - } - *ascii++ = png_check_char(png_ptr, 48 + (int)d), ++cdigits; - } - } - while (cdigits+czero < precision+clead && fp > DBL_MIN); - - /* The total output count (max) is now 4+precision */ - - /* Check for an exponent, if we don't need one we are - * done and just need to terminate the string. At - * this point exp_b10==(-1) is effectively if flag - it got - * to '-1' because of the decrement after outputting - * the decimal point above (the exponent required is - * *not* -1!) - */ - if (exp_b10 >= (-1) && exp_b10 <= 2) - { - /* The following only happens if we didn't output the - * leading zeros above for negative exponent, so this - * doesn't add to the digit requirement. Note that the - * two zeros here can only be output if the two leading - * zeros were *not* output, so this doesn't increase - * the output count. - */ - while (--exp_b10 >= 0) *ascii++ = 48; - - *ascii = 0; - - /* Total buffer requirement (including the '\0') is - * 5+precision - see check at the start. - */ - return; - } - - /* Here if an exponent is required, adjust size for - * the digits we output but did not count. The total - * digit output here so far is at most 1+precision - no - * decimal point and no leading or trailing zeros have - * been output. - */ - size -= cdigits; - - *ascii++ = 69; --size; /* 'E': PLUS 1 TOTAL 2+precision */ - - /* The following use of an unsigned temporary avoids ambiguities in - * the signed arithmetic on exp_b10 and permits GCC at least to do - * better optimization. - */ - { - unsigned int uexp_b10; - - if (exp_b10 < 0) - { - *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */ - uexp_b10 = -exp_b10; - } - - else - uexp_b10 = exp_b10; - - cdigits = 0; - - while (uexp_b10 > 0) - { - exponent[cdigits++] = (char)/*SAFE*/(48 + uexp_b10 % 10); - uexp_b10 /= 10; - } - } - - /* Need another size check here for the exponent digits, so - * this need not be considered above. - */ - if (size > cdigits) - { - while (cdigits > 0) *ascii++ = exponent[--cdigits]; - - *ascii = 0; - - return; - } - } - } - else if (!(fp >= DBL_MIN)) - { - *ascii++ = 48; /* '0' */ - *ascii = 0; - return; - } - else - { - *ascii++ = 105; /* 'i' */ - *ascii++ = 110; /* 'n' */ - *ascii++ = 102; /* 'f' */ - *ascii = 0; - return; - } - } - - /* Here on buffer too small. */ - png_error(png_ptr, "ASCII conversion buffer too small"); -} - -# endif /* FLOATING_POINT */ - -# ifdef PNG_FIXED_POINT_SUPPORTED -/* Function to format a fixed point value in ASCII. - */ -void /* PRIVATE */ -png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii, - png_size_t size, png_fixed_point fp) -{ - /* Require space for 10 decimal digits, a decimal point, a minus sign and a - * trailing \0, 13 characters: - */ - if (size > 12) - { - png_uint_32 num; - - /* Avoid overflow here on the minimum integer. */ - if (fp < 0) - *ascii++ = 45, --size, num = -fp; - else - num = fp; - - if (num <= 0x80000000) /* else overflowed */ - { - unsigned int ndigits = 0, first = 16 /* flag value */; - char digits[10]; - - while (num) - { - /* Split the low digit off num: */ - unsigned int tmp = num/10; - num -= tmp*10; - digits[ndigits++] = png_check_char(png_ptr, 48 + num); - /* Record the first non-zero digit, note that this is a number - * starting at 1, it's not actually the array index. - */ - if (first == 16 && num > 0) - first = ndigits; - num = tmp; - } - - if (ndigits > 0) - { - while (ndigits > 5) *ascii++ = digits[--ndigits]; - /* The remaining digits are fractional digits, ndigits is '5' or - * smaller at this point. It is certainly not zero. Check for a - * non-zero fractional digit: - */ - if (first <= 5) - { - unsigned int i; - *ascii++ = 46; /* decimal point */ - /* ndigits may be <5 for small numbers, output leading zeros - * then ndigits digits to first: - */ - i = 5; - while (ndigits < i) - { - *ascii++ = 48; --i; - } - while (ndigits >= first) *ascii++ = digits[--ndigits]; - /* Don't output the trailing zeros! */ - } - } - else - *ascii++ = 48; - - /* And null terminate the string: */ - *ascii = 0; - return; - } - } - - /* Here on buffer too small. */ - png_error(png_ptr, "ASCII conversion buffer too small"); -} -# endif /* FIXED_POINT */ -#endif /* SCAL */ - -#if !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && (\ - defined(PNG_FLOATING_POINT_SUPPORTED) && \ - (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ - defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ - (defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) &&\ - defined(PNG_sCAL_SUPPORTED))) -png_fixed_point -png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text) -{ - if (fp < 0) - { - if (fp > -21474.836485) - return (png_fixed_point)(100000*fp - .5); - } - - else - { - if (fp < 21474.836475) - return (png_fixed_point)(100000*fp + .5); - } - - /* Overflow */ - png_fixed_error(png_ptr, text); - -# ifndef PNG_ERROR_TEXT_SUPPORTED - PNG_UNUSED(text) -# endif -} -#endif - -#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\ - defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) -/* muldiv functions */ -/* This API takes signed arguments and rounds the result to the nearest - * integer (or, for a fixed point number - the standard argument - to - * the nearest .00001). Overflow and divide by zero are signalled in - * the result, a boolean - true on success, false on overflow. - */ -int -png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, - png_int_32 divisor) -{ - /* Return a * times / divisor, rounded. */ - if (divisor != 0) - { - if (a == 0 || times == 0) - { - *res = 0; - return 1; - } - else - { -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - double r = a; - r *= times; - r /= divisor; - r = floor(r+.5); - - /* A png_fixed_point is a 32-bit integer. */ - if (r <= 2147483647. && r >= -2147483648.) - { - *res = (png_fixed_point)r; - return 1; - } -#else - int negative = 0; - png_uint_32 A, T, D; - png_uint_32 s16, s32, s00; - - if (a < 0) - negative = 1, A = -a; - else - A = a; - - if (times < 0) - negative = !negative, T = -times; - else - T = times; - - if (divisor < 0) - negative = !negative, D = -divisor; - else - D = divisor; - - /* Following can't overflow because the arguments only - * have 31 bits each, however the result may be 32 bits. - */ - s16 = (A >> 16) * (T & 0xffff) + - (A & 0xffff) * (T >> 16); - /* Can't overflow because the a*times bit is only 30 - * bits at most. - */ - s32 = (A >> 16) * (T >> 16) + (s16 >> 16); - s00 = (A & 0xffff) * (T & 0xffff); - - s16 = (s16 & 0xffff) << 16; - s00 += s16; - - if (s00 < s16) - ++s32; /* carry */ - - if (s32 < D) /* else overflow */ - { - /* s32.s00 is now the 64-bit product, do a standard - * division, we know that s32 < D, so the maximum - * required shift is 31. - */ - int bitshift = 32; - png_fixed_point result = 0; /* NOTE: signed */ - - while (--bitshift >= 0) - { - png_uint_32 d32, d00; - - if (bitshift > 0) - d32 = D >> (32-bitshift), d00 = D << bitshift; - - else - d32 = 0, d00 = D; - - if (s32 > d32) - { - if (s00 < d00) --s32; /* carry */ - s32 -= d32, s00 -= d00, result += 1<= d00) - s32 = 0, s00 -= d00, result += 1<= (D >> 1)) - ++result; - - if (negative != 0) - result = -result; - - /* Check for overflow. */ - if ((negative != 0 && result <= 0) || - (negative == 0 && result >= 0)) - { - *res = result; - return 1; - } - } -#endif - } - } - - return 0; -} -#endif /* GAMMA || INCH_CONVERSIONS */ - -/* SOFTWARE SETTING SUPPORT */ -png_int_32 PNGAPI -png_setting(png_structrp png_ptr, png_uint_32 setting, png_uint_32 parameter, - png_int_32 value) -{ - png_int_32 result; - - if (png_ptr != NULL) - { - int handle_error = (setting & PNG_SF_ERROR) != 0U; - - setting &= ~PNG_SF_ERROR; /* because it is handled below. */ - - switch (setting & (PNG_SF_READ|PNG_SF_WRITE)) - { -# ifdef PNG_READ_SUPPORTED - case PNG_SF_READ: - if (png_ptr->read_struct) - result = png_read_setting(png_ptr, setting, parameter, value); - - else - result = PNG_EINVAL; /* read setting on write struct */ - break; -# endif /* READ */ - -# ifdef PNG_WRITE_SUPPORTED - case PNG_SF_WRITE: - if (!png_ptr->read_struct) - result = png_write_setting(png_ptr, setting, parameter, - value); - - else - result = PNG_EINVAL; /* write setting on read struct */ - break; -# endif /* WRITE */ - - default: - /* Handle everything else here. This includes the error of not - * having either read or write set; that error will cause a - * PNG_ENOSYS return code. - */ - switch (setting) - { -# ifdef PNG_SET_OPTION_SUPPORTED - case PNG_SRW_OPTION: - if (parameter >= PNG_OPTION_NEXT) - return PNG_OPTION_INVALID; - - if (parameter == PNG_SKIP_sRGB_CHECK_PROFILE) - { - if (png_ptr->skip_sRGB_profile_check) - { - if (!value) - png_ptr->skip_sRGB_profile_check = 0U; - result = PNG_OPTION_ON; - } - - else - { - if (value) - png_ptr->skip_sRGB_profile_check = 1U; - result = PNG_OPTION_OFF; - } - - break; - } - -# ifdef PNG_READ_SUPPORTED - if (png_ptr->read_struct) - { - result = png_read_setting(png_ptr, setting, - parameter, value); - break; - } -# endif /* READ */ - - /* No write options at present */ - result = PNG_OPTION_UNSET; /* i.e. ignore it */ - break; -# endif /* SET_OPTION */ - - default: - /* Any other option; handle in the appropriate setting: */ -# ifdef PNG_READ_SUPPORTED - if (png_ptr->read_struct) - { - result = png_read_setting(png_ptr, setting, - parameter, value); - break; - } -# endif /* READ */ - -# ifdef PNG_WRITE_SUPPORTED - if (!png_ptr->read_struct) - { - result = png_write_setting(png_ptr, setting, - parameter, value); - break; - } -# endif /* WRITE */ - - NOT_REACHED; - result= PNG_ENOSYS; - break; - } - break; - } /* switch */ - - /* Handle error returns here. - * TODO: this is crude, should use a formatted warning style message and - * output result/setting/parameter/value. - */ - if (handle_error && PNG_FAILED(result)) - png_error(png_ptr, "png_setting"); - } - - else /* png_ptr is NULL */ - result = PNG_EINVAL; - - return result; - PNG_UNUSED(parameter) - PNG_UNUSED(value) -} - -/* sRGB support */ -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -/* sRGB conversion tables; these are machine generated with the code in - * contrib/tools/makesRGB.c. The actual sRGB transfer curve defined in the - * specification (see the article at https://en.wikipedia.org/wiki/SRGB) - * is used, not the gamma=1/2.2 approximation use elsewhere in libpng. - * The sRGB to linear table is exact (to the nearest 16-bit linear fraction). - * The inverse (linear to sRGB) table has accuracies as follows: - * - * For all possible (255*65535+1) input values: - * - * error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact - * - * For the input values corresponding to the 65536 16-bit values: - * - * error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact - * - * In all cases the inexact readings are only off by one. - */ - -#ifdef PNG_SIMPLIFIED_READ_SUPPORTED -/* The convert-to-sRGB table is only currently required for read. */ -const png_uint_16 png_sRGB_table[256] = -{ - 0,20,40,60,80,99,119,139, - 159,179,199,219,241,264,288,313, - 340,367,396,427,458,491,526,562, - 599,637,677,718,761,805,851,898, - 947,997,1048,1101,1156,1212,1270,1330, - 1391,1453,1517,1583,1651,1720,1790,1863, - 1937,2013,2090,2170,2250,2333,2418,2504, - 2592,2681,2773,2866,2961,3058,3157,3258, - 3360,3464,3570,3678,3788,3900,4014,4129, - 4247,4366,4488,4611,4736,4864,4993,5124, - 5257,5392,5530,5669,5810,5953,6099,6246, - 6395,6547,6700,6856,7014,7174,7335,7500, - 7666,7834,8004,8177,8352,8528,8708,8889, - 9072,9258,9445,9635,9828,10022,10219,10417, - 10619,10822,11028,11235,11446,11658,11873,12090, - 12309,12530,12754,12980,13209,13440,13673,13909, - 14146,14387,14629,14874,15122,15371,15623,15878, - 16135,16394,16656,16920,17187,17456,17727,18001, - 18277,18556,18837,19121,19407,19696,19987,20281, - 20577,20876,21177,21481,21787,22096,22407,22721, - 23038,23357,23678,24002,24329,24658,24990,25325, - 25662,26001,26344,26688,27036,27386,27739,28094, - 28452,28813,29176,29542,29911,30282,30656,31033, - 31412,31794,32179,32567,32957,33350,33745,34143, - 34544,34948,35355,35764,36176,36591,37008,37429, - 37852,38278,38706,39138,39572,40009,40449,40891, - 41337,41785,42236,42690,43147,43606,44069,44534, - 45002,45473,45947,46423,46903,47385,47871,48359, - 48850,49344,49841,50341,50844,51349,51858,52369, - 52884,53401,53921,54445,54971,55500,56032,56567, - 57105,57646,58190,58737,59287,59840,60396,60955, - 61517,62082,62650,63221,63795,64372,64952,65535 -}; - -#endif /* SIMPLIFIED_READ */ - -/* The base/delta tables are required for both read and write (but currently - * only the simplified versions.) - */ -const png_uint_16 png_sRGB_base[512] = -{ - 128,1782,3383,4644,5675,6564,7357,8074, - 8732,9346,9921,10463,10977,11466,11935,12384, - 12816,13233,13634,14024,14402,14769,15125,15473, - 15812,16142,16466,16781,17090,17393,17690,17981, - 18266,18546,18822,19093,19359,19621,19879,20133, - 20383,20630,20873,21113,21349,21583,21813,22041, - 22265,22487,22707,22923,23138,23350,23559,23767, - 23972,24175,24376,24575,24772,24967,25160,25352, - 25542,25730,25916,26101,26284,26465,26645,26823, - 27000,27176,27350,27523,27695,27865,28034,28201, - 28368,28533,28697,28860,29021,29182,29341,29500, - 29657,29813,29969,30123,30276,30429,30580,30730, - 30880,31028,31176,31323,31469,31614,31758,31902, - 32045,32186,32327,32468,32607,32746,32884,33021, - 33158,33294,33429,33564,33697,33831,33963,34095, - 34226,34357,34486,34616,34744,34873,35000,35127, - 35253,35379,35504,35629,35753,35876,35999,36122, - 36244,36365,36486,36606,36726,36845,36964,37083, - 37201,37318,37435,37551,37668,37783,37898,38013, - 38127,38241,38354,38467,38580,38692,38803,38915, - 39026,39136,39246,39356,39465,39574,39682,39790, - 39898,40005,40112,40219,40325,40431,40537,40642, - 40747,40851,40955,41059,41163,41266,41369,41471, - 41573,41675,41777,41878,41979,42079,42179,42279, - 42379,42478,42577,42676,42775,42873,42971,43068, - 43165,43262,43359,43456,43552,43648,43743,43839, - 43934,44028,44123,44217,44311,44405,44499,44592, - 44685,44778,44870,44962,45054,45146,45238,45329, - 45420,45511,45601,45692,45782,45872,45961,46051, - 46140,46229,46318,46406,46494,46583,46670,46758, - 46846,46933,47020,47107,47193,47280,47366,47452, - 47538,47623,47709,47794,47879,47964,48048,48133, - 48217,48301,48385,48468,48552,48635,48718,48801, - 48884,48966,49048,49131,49213,49294,49376,49458, - 49539,49620,49701,49782,49862,49943,50023,50103, - 50183,50263,50342,50422,50501,50580,50659,50738, - 50816,50895,50973,51051,51129,51207,51285,51362, - 51439,51517,51594,51671,51747,51824,51900,51977, - 52053,52129,52205,52280,52356,52432,52507,52582, - 52657,52732,52807,52881,52956,53030,53104,53178, - 53252,53326,53400,53473,53546,53620,53693,53766, - 53839,53911,53984,54056,54129,54201,54273,54345, - 54417,54489,54560,54632,54703,54774,54845,54916, - 54987,55058,55129,55199,55269,55340,55410,55480, - 55550,55620,55689,55759,55828,55898,55967,56036, - 56105,56174,56243,56311,56380,56448,56517,56585, - 56653,56721,56789,56857,56924,56992,57059,57127, - 57194,57261,57328,57395,57462,57529,57595,57662, - 57728,57795,57861,57927,57993,58059,58125,58191, - 58256,58322,58387,58453,58518,58583,58648,58713, - 58778,58843,58908,58972,59037,59101,59165,59230, - 59294,59358,59422,59486,59549,59613,59677,59740, - 59804,59867,59930,59993,60056,60119,60182,60245, - 60308,60370,60433,60495,60558,60620,60682,60744, - 60806,60868,60930,60992,61054,61115,61177,61238, - 61300,61361,61422,61483,61544,61605,61666,61727, - 61788,61848,61909,61969,62030,62090,62150,62211, - 62271,62331,62391,62450,62510,62570,62630,62689, - 62749,62808,62867,62927,62986,63045,63104,63163, - 63222,63281,63340,63398,63457,63515,63574,63632, - 63691,63749,63807,63865,63923,63981,64039,64097, - 64155,64212,64270,64328,64385,64443,64500,64557, - 64614,64672,64729,64786,64843,64900,64956,65013, - 65070,65126,65183,65239,65296,65352,65409,65465 -}; - -const png_byte png_sRGB_delta[512] = -{ - 207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54, - 52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36, - 35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28, - 28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24, - 23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21, - 21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19, - 19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17, - 17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16, - 16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15, - 15,15,15,15,14,14,14,14,14,14,14,14,14,14,14,14, - 14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,13, - 13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11, - 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, - 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, - 11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, - 10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 -}; -#endif /* SIMPLIFIED READ/WRITE sRGB support */ - -/* SIMPLIFIED READ/WRITE SUPPORT */ -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -static int -png_image_free_function(png_voidp argument) -{ - png_imagep image = png_voidcast(png_imagep, argument); - png_controlp cp = image->opaque; - png_control c; - - /* Double check that we have a png_ptr - it should be impossible to get here - * without one. - */ - if (cp->png_ptr == NULL) - return 0; - - /* First free any data held in the control structure. */ -# ifdef PNG_STDIO_SUPPORTED - if (cp->owned_file != 0) - { - FILE *fp = png_voidcast(FILE*, png_get_io_ptr(cp->png_ptr)); - cp->owned_file = 0; - - /* Ignore errors here. */ - if (fp != NULL) - { - png_init_io(cp->png_ptr, NULL); - (void)fclose(fp); - } - } -# endif - - /* Copy the control structure so that the original, allocated, version can be - * safely freed. Notice that a png_error here stops the remainder of the - * cleanup, but this is probably fine because that would indicate bad memory - * problems anyway. - */ - c = *cp; - image->opaque = &c; - png_free(c.png_ptr, cp); - - /* Then the structures, calling the correct API. */ - if (c.for_write != 0) - { -# ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED - png_destroy_write_struct(&c.png_ptr, &c.info_ptr); -# else - png_error(c.png_ptr, "simplified write not supported"); -# endif - } - else - { -# ifdef PNG_SIMPLIFIED_READ_SUPPORTED - png_destroy_read_struct(&c.png_ptr, &c.info_ptr, NULL); -# else - png_error(c.png_ptr, "simplified read not supported"); -# endif - } - - /* Success. */ - return 1; -} - -void PNGAPI -png_image_free(png_imagep image) -{ - /* Safely call the real function, but only if doing so is safe at this point - * (if not inside an error handling context). Otherwise assume - * png_safe_execute will call this API after the return. - */ - if (image != NULL && image->opaque != NULL && - image->opaque->error_buf == NULL) - { - /* Ignore errors here: */ - (void)png_safe_execute(image, png_image_free_function, image); - image->opaque = NULL; - } -} - -int /* PRIVATE */ -png_image_error(png_imagep image, png_const_charp error_message) -{ - /* Utility to log an error. */ - png_safecat(image->message, (sizeof image->message), 0, error_message); - image->warning_or_error |= PNG_IMAGE_ERROR; - png_image_free(image); - return 0; -} - -#ifdef PNG_STDIO_SUPPORTED -typedef struct -{ - png_structrp png_ptr; - png_FILE_p fp; -} -png_image_init_io_struct; - -static int -image_init_io(png_voidp display) -{ - png_image_init_io_struct *p = - png_voidcast(png_image_init_io_struct*, display); - - png_init_io(p->png_ptr, p->fp); - return 1; -} - -int /* PRIVATE */ -png_image_init_io(png_imagep image, png_FILE_p fp) -{ - png_image_init_io_struct s; - - s.png_ptr = image->opaque->png_ptr; - s.fp = fp; - - return png_safe_execute(image, image_init_io, &s); -} -#endif /* STDIO */ -#endif /* SIMPLIFIED READ/WRITE */ -#endif /* READ || WRITE */ diff --git a/ext/libpng17/png.h b/ext/libpng17/png.h deleted file mode 100644 index 5a5dd57647..0000000000 --- a/ext/libpng17/png.h +++ /dev/null @@ -1,4252 +0,0 @@ - -/* png.h - header file for PNG reference library - * - * libpng version 1.7.0beta90, August 28, 2017 - * - * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license (See LICENSE, below) - * - * Authors and maintainers: - * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat - * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger - * libpng versions 0.97, January 1998, through 1.7.0beta90, August 28, 2017: - * Glenn Randers-Pehrson. - * See also "Contributing Authors", below. - */ - -/* - * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: - * - * If you modify libpng you may insert additional notices immediately following - * this sentence. - * - * This code is released under the libpng license. - * - * libpng versions 1.0.7, July 1, 2000 through 1.7.0beta90, August 28, 2017 are - * Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are - * derived from libpng-1.0.6, and are distributed according to the same - * disclaimer and license as libpng-1.0.6 with the following individuals - * added to the list of Contributing Authors: - * - * Simon-Pierre Cadieux - * Eric S. Raymond - * Mans Rullgard - * Cosmin Truta - * Gilles Vollant - * James Yu - * - * and with the following additions to the disclaimer: - * - * There is no warranty against interference with your enjoyment of the - * library or against infringement. There is no warranty that our - * efforts or the library will fulfill any of your particular purposes - * or needs. This library is provided with all faults, and the entire - * risk of satisfactory quality, performance, accuracy, and effort is with - * the user. - * - * Some files in the "contrib" directory and some configure-generated - * files that are distributed with libpng have other copyright owners and - * are released under other open source licenses. - * - * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are - * Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from - * libpng-0.96, and are distributed according to the same disclaimer and - * license as libpng-0.96, with the following individuals added to the list - * of Contributing Authors: - * - * Tom Lane - * Glenn Randers-Pehrson - * Willem van Schaik - * - * libpng versions 0.89, June 1996, through 0.96, May 1997, are - * Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, - * and are distributed according to the same disclaimer and license as - * libpng-0.88, with the following individuals added to the list of - * Contributing Authors: - * - * John Bowler - * Kevin Bracey - * Sam Bushell - * Magnus Holmgren - * Greg Roelofs - * Tom Tanner - * - * Some files in the "scripts" directory have other copyright owners - * but are released under this license. - * - * libpng versions 0.5, May 1995, through 0.88, January 1996, are - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * For the purposes of this copyright and license, "Contributing Authors" - * is defined as the following set of individuals: - * - * Andreas Dilger - * Dave Martindale - * Guy Eric Schalnat - * Paul Schmidt - * Tim Wegner - * - * The PNG Reference Library is supplied "AS IS". The Contributing Authors - * and Group 42, Inc. disclaim all warranties, expressed or implied, - * including, without limitation, the warranties of merchantability and of - * fitness for any purpose. The Contributing Authors and Group 42, Inc. - * assume no liability for direct, indirect, incidental, special, exemplary, - * or consequential damages, which may result from the use of the PNG - * Reference Library, even if advised of the possibility of such damage. - * - * Permission is hereby granted to use, copy, modify, and distribute this - * source code, or portions hereof, for any purpose, without fee, subject - * to the following restrictions: - * - * 1. The origin of this source code must not be misrepresented. - * - * 2. Altered versions must be plainly marked as such and must not - * be misrepresented as being the original source. - * - * 3. This Copyright notice may not be removed or altered from any - * source or altered source distribution. - * - * The Contributing Authors and Group 42, Inc. specifically permit, without - * fee, and encourage the use of this source code as a component to - * supporting the PNG file format in commercial products. If you use this - * source code in a product, acknowledgment is not required but would be - * appreciated. - * - * END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE. - * - * TRADEMARK: - * - * The name "libpng" has not been registered by the Copyright owner - * as a trademark in any jurisdiction. However, because libpng has - * been distributed and maintained world-wide, continually since 1995, - * the Copyright owner claims "common-law trademark protection" in any - * jurisdiction where common-law trademark is recognized. - * - * OSI CERTIFICATION: - * - * Libpng is OSI Certified Open Source Software. OSI Certified Open Source is - * a certification mark of the Open Source Initiative. OSI has not addressed - * the additional disclaimers inserted at version 1.0.7. - * - * EXPORT CONTROL: - * - * The Copyright owner believes that the Export Control Classification - * Number (ECCN) for libpng is EAR99, which means not subject to export - * controls or International Traffic in Arms Regulations (ITAR) because - * it is open source, publicly available software, that does not contain - * any encryption software. See the EAR, paragraphs 734.3(b)(3) and - * 734.7(b). - */ - -/* - * A "png_get_copyright" function is available, for convenient use in "about" - * boxes and the like: - * - * printf("%s", png_get_copyright(NULL)); - * - * Also, the PNG logo (in PNG format, of course) is supplied in the - * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). - */ - -/* - * The contributing authors would like to thank all those who helped - * with testing, bug fixes, and patience. This wouldn't have been - * possible without all of you. - * - * Thanks to Frank J. T. Wojcik for helping with the documentation. - */ - -/* Note about libpng version numbers: - * - * Due to various miscommunications, unforeseen code incompatibilities - * and occasional factors outside the authors' control, version numbering - * on the library has not always been consistent and straightforward. - * The following table summarizes matters since version 0.89c, which was - * the first widely used release: - * - * source png.h png.h shared-lib - * version string int version - * ------- ------ ----- ---------- - * 0.89c "1.0 beta 3" 0.89 89 1.0.89 - * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90] - * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95] - * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96] - * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97] - * 0.97c 0.97 97 2.0.97 - * 0.98 0.98 98 2.0.98 - * 0.99 0.99 98 2.0.99 - * 0.99a-m 0.99 99 2.0.99 - * 1.00 1.00 100 2.1.0 [100 should be 10000] - * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000] - * 1.0.1 png.h string is 10001 2.1.0 - * 1.0.1a-e identical to the 10002 from here on, the shared library - * 1.0.2 source version) 10002 is 2.V where V is the source code - * 1.0.2a-b 10003 version, except as noted. - * 1.0.3 10003 - * 1.0.3a-d 10004 - * 1.0.4 10004 - * 1.0.4a-f 10005 - * 1.0.5 (+ 2 patches) 10005 - * 1.0.5a-d 10006 - * 1.0.5e-r 10100 (not source compatible) - * 1.0.5s-v 10006 (not binary compatible) - * 1.0.6 (+ 3 patches) 10006 (still binary incompatible) - * 1.0.6d-f 10007 (still binary incompatible) - * 1.0.6g 10007 - * 1.0.6h 10007 10.6h (testing xy.z so-numbering) - * 1.0.6i 10007 10.6i - * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0) - * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible) - * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible) - * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) - * 1.0.7 1 10007 (still compatible) - * ... - * 1.0.19 10 10019 10.so.0.19[.0] - * ... - * 1.2.56 13 10253 12.so.0.53[.0] - * ... - * 1.5.27 15 10523 15.so.15.23[.0] - * ... - * 1.6.22 16 10622 16.so.16.22[.0] - * ... - * 1.7.0alpha01-10 17 10700 17.so.17.0[.0] - * 1.7.0beta01-84 17 10700 17.so.17.0[.0] - * - * Henceforth the source version will match the shared-library major - * and minor numbers; the shared-library major version number will be - * used for changes in backward compatibility, as it is intended. The - * PNG_LIBPNG_VER macro, which is not used within libpng but is available - * for applications, is an unsigned integer of the form xyyzz corresponding - * to the source version x.y.z (leading zeros in y and z). Beta versions - * were given the previous public release number plus a letter, until - * version 1.0.6j; from then on they were given the upcoming public - * release number plus "betaNN" or "rcNN". - * - * Binary incompatibility exists only when applications make direct access - * to the info_ptr or png_ptr members through png.h, and the compiled - * application is loaded with a different version of the library. - * - * DLLNUM will change each time there are forward or backward changes - * in binary compatibility (e.g., when a new feature is added). - * - * See libpng.txt or libpng.3 for more information. The PNG specification - * is available as a W3C Recommendation and as an ISO Specification, - * - * - * If you just need to read a PNG file and don't want to read the documentation - * skip to the end of this file and read the section entitled 'simplified API'. - */ - -/* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.7.0beta90" -#define PNG_HEADER_VERSION_STRING " libpng version 1.7.0beta90 - August 28, 2017\n" - -#define PNG_LIBPNG_VER_SONUM 17 -#define PNG_LIBPNG_VER_DLLNUM 17 - -/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ -#define PNG_LIBPNG_VER_MAJOR 1 -#define PNG_LIBPNG_VER_MINOR 7 -#define PNG_LIBPNG_VER_RELEASE 0 - -/* This should match the numeric part of the final component of - * PNG_LIBPNG_VER_STRING, omitting any leading zero: - */ - -#define PNG_LIBPNG_VER_BUILD 90 - -/* Release Status */ -#define PNG_LIBPNG_BUILD_ALPHA 1 -#define PNG_LIBPNG_BUILD_BETA 2 -#define PNG_LIBPNG_BUILD_RC 3 -#define PNG_LIBPNG_BUILD_STABLE 4 -#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7 - -/* Release-Specific Flags */ -#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with - PNG_LIBPNG_BUILD_STABLE only */ -#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with - PNG_LIBPNG_BUILD_SPECIAL */ -#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with - PNG_LIBPNG_BUILD_PRIVATE */ - -#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_RC - -/* Careful here. At one time, Guy wanted to use 082, but that would be octal. - * We must not include leading zeros. - * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only - * version 1.0.0 was mis-numbered 100 instead of 10000). From - * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release - */ -#define PNG_LIBPNG_VER 10700 /* 1.7.0 */ - -/* Library configuration: these options cannot be changed after - * the library has been built. - */ -#ifndef PNGLCONF_H -/* If pnglibconf.h is missing, you can - * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h - */ -# include "pnglibconf.h" -#endif - -#ifndef PNG_VERSION_INFO_ONLY -/* Machine specific configuration. */ -# include "pngconf.h" -#endif - -/* - * Added at libpng-1.2.8 - * - * Ref MSDN: Private as priority over Special - * VS_FF_PRIVATEBUILD File *was not* built using standard release - * procedures. If this value is given, the StringFileInfo block must - * contain a PrivateBuild string. - * - * VS_FF_SPECIALBUILD File *was* built by the original company using - * standard release procedures but is a variation of the standard - * file of the same version number. If this value is given, the - * StringFileInfo block must contain a SpecialBuild string. - */ - -#ifdef PNG_USER_PRIVATEBUILD /* From pnglibconf.h */ -# define PNG_LIBPNG_BUILD_TYPE \ - (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE) -#else -# ifdef PNG_LIBPNG_SPECIALBUILD -# define PNG_LIBPNG_BUILD_TYPE \ - (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL) -# else -# define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE) -# endif -#endif - -#ifndef PNG_VERSION_INFO_ONLY - -/* Version information for C files, stored in png.c. This had better match - * the version above. - */ -#define png_libpng_ver png_get_header_ver(NULL) - -/* This file is arranged in several sections: - * - * 1. ISO-PNG constants and definitions; values defined by PNG and not specific - * to the libpng API. - * 2. Any configuration options that can be specified by for the application - * code when it is built. (Build time configuration is in pnglibconf.h) - * 3. Type definitions (base types are defined in pngconf.h), structure - * definitions. - * 4. Exported library functions. - * 5. Simplified API. - * 6. Implementation options - * - * The library source code has additional files (principally pngpriv.h) that - * allow configuration of the library. - */ - -/* Section 1: ISO PNG constants and macros. */ - -/* ISO-PNG defines byte encodings for 16 and 32-bit unsigned values and 32-bit - * signed values. The macros PNG_U16, PNG_U32 and PNG_S32 return values of type - * (png_uint_16), (png_uint_32) and (png_int_32) which are target machine - * specific representations of these values, using the types defined in - * pngconf.h. The macros take two or four byte values in the order in which - * they would occur in a PNG stream. - * - * These macros must return compile time constants if passed constant values - - * machine specific implementations are not permitted. These macros are used by - * default in the API functions/macros png_get_uint_16, png_get_uint_32, - * png_get_uint_31 and png_get_int_32 declared below: these functions or macros - * are the correct places for machine specific implementations (such as hardware - * specific instructions.) - * - * The macros defined here are generic and intended to give maximum flexibility - * in implementation to the compiler; only PNG_S32 contains a sequence point, - * there are no side effects and the expressions used permit the maximum - * parallelization (relevant because the four bytes may be loaded in parallel.) - */ -#define PNG_u2(b1, b2) (((unsigned int)(b1) << 8) + (b2)) - -#define PNG_U16(b1, b2) ((png_uint_16)/*SAFE*/PNG_u2(b1, b2)) -#define PNG_U32(b1, b2, b3, b4)\ - (((png_uint_32)/*SAFE*/PNG_u2(b1, b2) << 16) + PNG_u2(b3, b4)) - -/* ISO-PNG states that signed 32-bit values are stored in two's complement - * format. There is no guarantee that (png_int_32) is exactly 32 bits, so the - * following macro tests for a negative number and generates the machine format - * directly by portable arithmetic operations. The cost is that the argument - * 'b1' is evaluated twice. - * - * NOTE: the 0x7fffffffU BIC is there to ensure that potential overflow in the - * cast does not occur. This fixes the case where 1's complement machines could - * be forced into an overflow by an invalid value in the stream and, therefore, - * potentially raise an arithmetic exception; the invalid value is converted to - * 0 and any resultant problems will be caught later in the libpng checking. - */ -#define PNG_S32(b1, b2, b3, b4) ((b1) & 0x80\ - ? -(png_int_32)(((PNG_U32(b1, b2, b3, b4)^0xffffffffU)+1U)&0x7fffffffU)\ - : (png_int_32)PNG_U32(b1, b2, b3, b4)) - -/* Constants for known chunk types. - * - * MAINTAINERS: If you need to add a chunk, define the name here. - * For historical reasons these constants have the form png_; i.e. - * the prefix is lower case. Please use decimal values as the parameters to - * match the ISO PNG specification and to avoid relying on the C locale - * interpretation of character values. Please keep the list sorted. - * - * Notice that PNG_U32 is used to define a 32-bit value for the 4 byte chunk - * type. In fact the specification does not express chunk types this way, - * however using a 32-bit value means that the chunk type can be read from the - * stream using exactly the same code as used for a 32-bit unsigned value and - * can be examined far more efficiently (using one arithmetic compare). - * - * Prior to 1.5.6 the chunk type constants were expressed as C strings. The - * libpng API still uses strings for 'unknown' chunks and a macro, - * PNG_STRING_FROM_CHUNK, allows a string to be generated if required. Notice - * that for portable code numeric values must still be used; the string "IHDR" - * is not portable and neither is PNG_U32('I', 'H', 'D', 'R'). - * - * In 1.7.0 the definitions were made public in png.h to avoid having to - * duplicate the same definitions in application code. - * - * SOURCE: http://www.libpng.org/pub/png/spec/register/ - * "Register of PNG Public Chunks and Keywords, version 1.4.6" - * "Extensions to the PNG Specification, version 1.4.0" - */ -#define png_IDAT PNG_U32( 73, 68, 65, 84) -#define png_IEND PNG_U32( 73, 69, 78, 68) -#define png_IHDR PNG_U32( 73, 72, 68, 82) -#define png_PLTE PNG_U32( 80, 76, 84, 69) -#define png_bKGD PNG_U32( 98, 75, 71, 68) -#define png_cHRM PNG_U32( 99, 72, 82, 77) -#define png_dSIG PNG_U32(100, 83, 73, 71) /* separate spec */ -#define png_fRAc PNG_U32(102, 82, 65, 99) /* registered, not defined */ -#define png_gAMA PNG_U32(103, 65, 77, 65) -#define png_gIFg PNG_U32(103, 73, 70, 103) -#define png_gIFt PNG_U32(103, 73, 70, 116) /* deprecated */ -#define png_gIFx PNG_U32(103, 73, 70, 120) -#define png_hIST PNG_U32(104, 73, 83, 84) -#define png_iCCP PNG_U32(105, 67, 67, 80) -#define png_iTXt PNG_U32(105, 84, 88, 116) -#define png_oFFs PNG_U32(111, 70, 70, 115) -#define png_pCAL PNG_U32(112, 67, 65, 76) -#define png_pHYs PNG_U32(112, 72, 89, 115) -#define png_sBIT PNG_U32(115, 66, 73, 84) -#define png_sCAL PNG_U32(115, 67, 65, 76) -#define png_sPLT PNG_U32(115, 80, 76, 84) -#define png_sRGB PNG_U32(115, 82, 71, 66) -#define png_sTER PNG_U32(115, 84, 69, 82) -#define png_tEXt PNG_U32(116, 69, 88, 116) -#define png_tIME PNG_U32(116, 73, 77, 69) -#define png_tRNS PNG_U32(116, 82, 78, 83) -#define png_zTXt PNG_U32(122, 84, 88, 116) - -/* The following will work on (signed char*) strings, whereas the PNG_U32 macro - * used directory would fail on top-bit-set values because of the sign - * extension. - */ -#define PNG_CHUNK_FROM_STRING(s)\ - PNG_U32(0xff&(s)[0], 0xff&(s)[1], 0xff&(s)[2], 0xff&(s)[3]) - -/* This uses (char), not (png_byte) to avoid warnings on systems where (char) is - * signed and the argument is a (char[]) This macro will fail miserably on - * systems where (char) is more than 8 bits. - */ -#define PNG_STRING_FROM_CHUNK(s,c)\ - (void)(((char*)(s))[0]=(char)(((c)>>24) & 0xff), \ - ((char*)(s))[1]=(char)(((c)>>16) & 0xff),\ - ((char*)(s))[2]=(char)(((c)>>8) & 0xff), \ - ((char*)(s))[3]=(char)((c & 0xff))) - -/* Do the same but terminate with a null character. */ -#define PNG_CSTRING_FROM_CHUNK(s,c)\ - (void)(PNG_STRING_FROM_CHUNK(s,c), ((char*)(s))[4] = 0) - -/* Test on flag values as defined in the spec (section 5.4): */ -#define PNG_CHUNK_ANCILLARY(c) (1 & ((c) >> 29)) -#define PNG_CHUNK_CRITICAL(c) (!PNG_CHUNK_ANCILLARY(c)) -#define PNG_CHUNK_PRIVATE(c) (1 & ((c) >> 21)) -#define PNG_CHUNK_RESERVED(c) (1 & ((c) >> 13)) -#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >> 5)) - -/* Section 2: run time configuration - * See pnglibconf.h for build time configuration - * - * Run time configuration allows the application to choose between - * implementations of certain arithmetic APIs. The default is set - * at build time and recorded in pnglibconf.h, but it is safe to - * override these (and only these) settings. Note that this won't - * change what the library does, only application code, and the - * settings can (and probably should) be made on a per-file basis - * by setting the #defines before including png.h - * - * Use macros to read integers from PNG data or use the exported - * functions? - * PNG_USE_READ_MACROS: use the macros (see below) Note that - * the macros evaluate their argument multiple times. - * PNG_NO_USE_READ_MACROS: call the relevant library function. - * - * Use the alternative algorithm for compositing alpha samples that - * does not use division? - * PNG_READ_COMPOSITE_NODIV_SUPPORTED: use the 'no division' - * algorithm. - * PNG_NO_READ_COMPOSITE_NODIV: use the 'division' algorithm. - * - * How to handle benign errors if PNG_ALLOW_BENIGN_ERRORS is - * false? - * PNG_ALLOW_BENIGN_ERRORS: map calls to the benign error - * APIs to png_warning. - * Otherwise the calls are mapped to png_error. - */ - -/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Section 3: type definitions, including structures and compile time - * constants. - * See pngconf.h for base types that vary by machine/system - */ - -/* This triggers a compiler error in png.c, if png.c and png.h - * do not agree upon the version number. - */ -typedef char* png_libpng_version_1_7_0beta90; - -/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. - * - * png_struct is the cache of information used while reading or writing a single - * PNG file. One of these is always required, although the simplified API - * (below) hides the creation and destruction of it. - */ -typedef struct png_struct_def png_struct; -typedef const png_struct * png_const_structp; -typedef png_struct * png_structp; -typedef png_struct * * png_structpp; - -/* png_info contains information read from or to be written to a PNG file. One - * or more of these must exist while reading or creating a PNG file. The - * information is not used by libpng during read but is used to control what - * gets written when a PNG file is created. "png_get_" function calls read - * information during read and "png_set_" functions calls write information - * when creating a PNG. - * been moved into a separate header file that is not accessible to - * applications. Read libpng-manual.txt or libpng.3 for more info. - */ -typedef struct png_info_def png_info; -typedef png_info * png_infop; -typedef const png_info * png_const_infop; -typedef png_info * * png_infopp; - -/* Types with names ending 'p' are pointer types. The corresponding types with - * names ending 'rp' are identical pointer types except that the pointer is - * marked 'restrict', which means that it is the only pointer to the object - * passed to the function. Applications should not use the 'restrict' types; - * it is always valid to pass 'p' to a pointer with a function argument of the - * corresponding 'rp' type. Different compilers have different rules with - * regard to type matching in the presence of 'restrict'. For backward - * compatibility libpng callbacks never have 'restrict' in their parameters and, - * consequentially, writing portable application code is extremely difficult if - * an attempt is made to use 'restrict'. - */ -typedef png_struct * PNG_RESTRICT png_structrp; -typedef const png_struct * PNG_RESTRICT png_const_structrp; -typedef png_info * PNG_RESTRICT png_inforp; -typedef const png_info * PNG_RESTRICT png_const_inforp; - -/* Three color definitions. The order of the red, green, and blue, (and the - * exact size) is not important, although the size of the fields need to - * be png_byte or png_uint_16 (as defined below). - */ -typedef struct png_color_struct -{ - png_byte red; - png_byte green; - png_byte blue; -} png_color; -typedef png_color * png_colorp; -typedef const png_color * png_const_colorp; -typedef png_color * * png_colorpp; - -typedef struct png_color_16_struct -{ - png_byte index; /* used for palette files */ - png_uint_16 red; /* for use in red green blue files */ - png_uint_16 green; - png_uint_16 blue; - png_uint_16 gray; /* for use in grayscale files */ -} png_color_16; -typedef png_color_16 * png_color_16p; -typedef const png_color_16 * png_const_color_16p; -typedef png_color_16 * * png_color_16pp; - -typedef struct png_color_8_struct -{ - png_byte red; /* for use in red green blue files */ - png_byte green; - png_byte blue; - png_byte gray; /* for use in grayscale files */ - png_byte alpha; /* for alpha channel files */ -} png_color_8; -typedef png_color_8 * png_color_8p; -typedef const png_color_8 * png_const_color_8p; -typedef png_color_8 * * png_color_8pp; - -/* - * The following two structures are used for the in-core representation - * of sPLT chunks. - */ -typedef struct png_sPLT_entry_struct -{ - png_uint_16 red; - png_uint_16 green; - png_uint_16 blue; - png_uint_16 alpha; - png_uint_16 frequency; -} png_sPLT_entry; -typedef png_sPLT_entry * png_sPLT_entryp; -typedef const png_sPLT_entry * png_const_sPLT_entryp; -typedef png_sPLT_entry * * png_sPLT_entrypp; - -/* When the depth of the sPLT palette is 8 bits, the color and alpha samples - * occupy the LSB of their respective members, and the MSB of each member - * is zero-filled. The frequency member always occupies the full 16 bits. - */ - -typedef struct png_sPLT_struct -{ - png_charp name; /* palette name */ - png_byte depth; /* depth of palette samples */ - png_sPLT_entryp entries; /* palette entries */ - png_int_32 nentries; /* number of palette entries */ -} png_sPLT_t; -typedef png_sPLT_t * png_sPLT_tp; -typedef const png_sPLT_t * png_const_sPLT_tp; -typedef png_sPLT_t * * png_sPLT_tpp; - -#ifdef PNG_TEXT_SUPPORTED -/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file, - * and whether that contents is compressed or not. The "key" field - * points to a regular zero-terminated C string. The "text" fields can be a - * regular C string, an empty string, or a NULL pointer. - * However, the structure returned by png_get_text() will always contain - * the "text" field as a regular zero-terminated C string (possibly - * empty), never a NULL pointer, so it can be safely used in printf() and - * other string-handling functions. Note that the "itxt_length", "lang", and - * "lang_key" members of the structure only exist when the library is built - * with iTXt chunk support. Prior to libpng-1.4.0 the library was built by - * default without iTXt support. Also note that when iTXt *is* supported, - * the "lang" and "lang_key" fields contain NULL pointers when the - * "compression" field contains * PNG_TEXT_COMPRESSION_NONE or - * PNG_TEXT_COMPRESSION_zTXt. Note that the "compression value" is not the - * same as what appears in the PNG tEXt/zTXt/iTXt chunk's "compression flag" - * which is always 0 or 1, or its "compression method" which is always 0. - * - * The location field (added in libpng 1.7.0) records where the text chunk was - * found when png_get_text is used. When png_set_text is used the field in the - * structure passed in is ignored and, instead, the field is set to the current - * write position. - * - * Prior to 1.7.0 the write behavior was the same; the text fields were written - * (once) at the next write_info call, however the read mechanism did not record - * the chunk location so if an info_struct from read was passed to the write - * APIs the text chunks would all be written at the start (before PLTE). - */ -typedef struct png_text_struct -{ - int compression; /* compression value: - -1: tEXt, none - 0: zTXt, deflate - 1: iTXt, none - 2: iTXt, deflate */ - png_byte location; /* 1: PNG_HAVE_IHDR - 2: PNG_HAVE_PLTE - 8: PNG_AFTER_IDAT */ - png_charp key; /* keyword, 1-79 character description of "text" */ - png_charp text; /* comment, may be an empty string (ie "") - or a NULL pointer */ - size_t text_length; /* length of the text string */ - size_t itxt_length; /* length of the itxt string */ - png_charp lang; /* language code, 0-79 characters - or a NULL pointer */ - png_charp lang_key; /* keyword translated UTF-8 string, 0 or more - chars or a NULL pointer */ -} png_text; -typedef png_text * png_textp; -typedef const png_text * png_const_textp; -typedef png_text * * png_textpp; -#endif - -/* Supported compression types for text in PNG files (tEXt, and zTXt). - * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */ -#ifdef PNG_OLD_COMPRESSION_CODES_SUPPORTED - /* These values were used to prevent double write of text chunks in versions - * prior to 1.7.0. They are never set now; if you need them #define the - * _SUPPORTED macro. - */ -#define PNG_TEXT_COMPRESSION_NONE_WR -3 -#define PNG_TEXT_COMPRESSION_zTXt_WR -2 -#endif /* OLD_COMPRESSION_CODES */ -#define PNG_TEXT_COMPRESSION_NONE -1 -#define PNG_TEXT_COMPRESSION_zTXt 0 -#define PNG_ITXT_COMPRESSION_NONE 1 -#define PNG_ITXT_COMPRESSION_zTXt 2 -#define PNG_TEXT_COMPRESSION_LAST 3 /* Not a valid value */ - -/* png_time is a way to hold the time in an machine independent way. - * Two conversions are provided, both from time_t and struct tm. There - * is no portable way to convert to either of these structures, as far - * as I know. If you know of a portable way, send it to me. As a side - * note - PNG has always been Year 2000 compliant! - */ -typedef struct png_time_struct -{ - png_uint_16 year; /* full year, as in, 1995 */ - png_byte month; /* month of year, 1 - 12 */ - png_byte day; /* day of month, 1 - 31 */ - png_byte hour; /* hour of day, 0 - 23 */ - png_byte minute; /* minute of hour, 0 - 59 */ - png_byte second; /* second of minute, 0 - 60 (for leap seconds) */ -} png_time; -typedef png_time * png_timep; -typedef const png_time * png_const_timep; -typedef png_time * * png_timepp; - -#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) ||\ - defined(PNG_USER_CHUNKS_SUPPORTED) -/* png_unknown_chunk is a structure to hold queued chunks for which there is - * no specific support. The idea is that we can use this to queue - * up private chunks for output even though the library doesn't actually - * know about their semantics. - * - * The data in the structure is set by libpng on read and used on write. - */ -typedef struct png_unknown_chunk_t -{ - png_byte *data; /* Data, should not be modified on read! */ - png_uint_32 size; /* Size of data, must not exceed 0x7fffffff. - * API CHANGE 1.7.0: changed from 'size_t' - */ - png_byte name[5]; /* Textual chunk name with '\0' terminator */ - - /* On write 'location' must be set using the flag values listed below. - * Notice that on read it is set by libpng however the values stored have - * more bits set than are listed below. Always treat the value as a - * bitmask. On write set only one bit - setting multiple bits may cause the - * chunk to be written in multiple places. - */ - png_byte location; /* mode of operation at read time */ -} -png_unknown_chunk; - -typedef png_unknown_chunk * png_unknown_chunkp; -typedef const png_unknown_chunk * png_const_unknown_chunkp; -typedef png_unknown_chunk * * png_unknown_chunkpp; -#endif - -/* Flag values for the chunk location byte. */ -#define PNG_HAVE_IHDR 0x01U -#define PNG_HAVE_PLTE 0x02U -#define PNG_AFTER_IDAT 0x08U - -/* Maximum positive integer used in PNG is (2^31)-1 */ -#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL) -#define PNG_UINT_32_MAX ((png_uint_32)(-1)) -#define PNG_SIZE_MAX ((size_t)(-1)) - -/* These are constants for fixed point values encoded in the - * PNG specification manner (x100000) - */ -#define PNG_FP_1 100000 -#define PNG_FP_HALF 50000 -#define PNG_FP_MAX ((png_fixed_point)0x7fffffffL) -#define PNG_FP_MIN (-PNG_FP_MAX) - -/* These describe the color_type field in png_info. */ -/* color type masks */ -#define PNG_COLOR_MASK_PALETTE 1U -#define PNG_COLOR_MASK_COLOR 2U -#define PNG_COLOR_MASK_ALPHA 4U - -/* color types. Note that not all combinations are legal */ -#define PNG_COLOR_TYPE_GRAY 0U -#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE) -#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR) -#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA) -#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA) -/* aliases */ -#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA -#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA - -/* This is for compression type. PNG 1.0-1.2 only define the single type. */ -#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */ -#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE - -/* This is for filter method. PNG 1.0-1.2 only defines a single method. - * - * NOTE: CONFUSING NAME. The specification refers to a 'method', one of the - * defines below, and a 'type', one of the FILTER_VALUE defines. - * Historically libpng uses TYPE for 'method' and VALUE for 'type'. - */ -#define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */ -#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */ -#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE - -/* Filter values defined for method '0' (PNG_FILTER_TYPE_BASE) in the PNG - * specification. - */ -#define PNG_FILTER_VALUE_NONE 0 -#define PNG_FILTER_VALUE_SUB 1 -#define PNG_FILTER_VALUE_UP 2 -#define PNG_FILTER_VALUE_AVG 3 -#define PNG_FILTER_VALUE_PAETH 4 -#define PNG_FILTER_VALUE_LAST 5 /* Not a valid value */ - -/* These are for the interlacing type. These values should NOT be changed. */ -#define PNG_INTERLACE_NONE 0 /* Non-interlaced image */ -#define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */ -#define PNG_INTERLACE_LAST 2 /* Not a valid value */ - -/* These are for the oFFs chunk. These values should NOT be changed. */ -#define PNG_OFFSET_PIXEL 0 /* Offset in pixels */ -#define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */ -#define PNG_OFFSET_LAST 2 /* Not a valid value */ - -/* These are for the pCAL chunk. These values should NOT be changed. */ -#define PNG_EQUATION_LINEAR 0 /* Linear transformation */ -#define PNG_EQUATION_BASE_E 1 /* Exponential base e transform */ -#define PNG_EQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */ -#define PNG_EQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */ -#define PNG_EQUATION_LAST 4 /* Not a valid value */ - -/* These are for the sCAL chunk. These values should NOT be changed. */ -#define PNG_SCALE_UNKNOWN 0 /* unknown unit (image scale) */ -#define PNG_SCALE_METER 1 /* meters per pixel */ -#define PNG_SCALE_RADIAN 2 /* radians per pixel */ -#define PNG_SCALE_LAST 3 /* Not a valid value */ - -/* These are for the pHYs chunk. These values should NOT be changed. */ -#define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */ -#define PNG_RESOLUTION_METER 1 /* pixels/meter */ -#define PNG_RESOLUTION_LAST 2 /* Not a valid value */ - -/* These are for the sRGB chunk. These values should NOT be changed. */ -#define PNG_sRGB_INTENT_PERCEPTUAL 0 -#define PNG_sRGB_INTENT_RELATIVE 1 -#define PNG_sRGB_INTENT_SATURATION 2 -#define PNG_sRGB_INTENT_ABSOLUTE 3 -#define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */ - -/* This is for text chunks */ -#define PNG_KEYWORD_MAX_LENGTH 79 - -/* Maximum number of entries in PLTE/sPLT/tRNS arrays */ -#define PNG_MAX_PALETTE_LENGTH 256 - -/* These determine if an ancillary chunk's data has been successfully read - * from the PNG header, or if the application has filled in the corresponding - * data in the info_struct to be written into the output file. The values - * of the PNG_INFO_ defines should NOT be changed. - */ -#define PNG_INFO_gAMA 0x0001U -#define PNG_INFO_sBIT 0x0002U -#define PNG_INFO_cHRM 0x0004U -#define PNG_INFO_PLTE 0x0008U -#define PNG_INFO_tRNS 0x0010U -#define PNG_INFO_bKGD 0x0020U -#define PNG_INFO_hIST 0x0040U -#define PNG_INFO_pHYs 0x0080U -#define PNG_INFO_oFFs 0x0100U -#define PNG_INFO_tIME 0x0200U -#define PNG_INFO_pCAL 0x0400U -#define PNG_INFO_sRGB 0x0800U /* GR-P, 0.96a */ -#define PNG_INFO_iCCP 0x1000U /* ESR, 1.0.6 */ -#define PNG_INFO_sPLT 0x2000U /* ESR, 1.0.6 */ -#define PNG_INFO_sCAL 0x4000U /* ESR, 1.0.6 */ -#define PNG_INFO_IDAT 0x8000U /* ESR, 1.0.6 */ - -/* This is used for the transformation routines, as some of them - * change these values for the row. It also should enable using - * the routines for other purposes. - */ -typedef struct png_row_info_struct -{ - png_uint_32 width; /* width of row */ - size_t rowbytes; /* number of bytes in row */ - png_byte color_type; /* color type of row */ - png_byte bit_depth; /* bit depth of row */ - png_byte channels; /* number of channels (1, 2, 3, or 4) */ - png_byte pixel_depth; /* bits per pixel (depth * channels) */ -} png_row_info; - -typedef png_row_info * png_row_infop; -typedef png_row_info * * png_row_infopp; - -/* These are the function types for the I/O functions and for the functions - * that allow the user to override the default I/O functions with his or her - * own. The png_error_ptr type should match that of user-supplied warning - * and error functions, while the png_rw_ptr type should match that of the - * user read/write data functions. Note that the 'write' function must not - * modify the buffer it is passed. The 'read' function, on the other hand, is - * expected to return the read data in the buffer. - */ -typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp)); -typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, size_t)); -typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp)); -typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32, - int)); -typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32, - int)); - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop)); -typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop)); - -/* WARNING: the API for this callback is poorly documented and produces - * unexpected results when dealing with interlaced images. For non-interlaced - * images the parameters are straightforward: - * - * next_row: a pointer to the transformed row read from the PNG input - * stream, it has png_get_image_width() pixels. - * row_y: the y ordinate of the image; 0..png_get_image_height()-1 - * pass: 0 - * - * For interlaced images if png_set_interlace_handling has been called (libpng - * does *not* call this itself) the parameters are the same except that the - * pass will be the pass in the range 0..6 (NOTE: one less than the PNG spec) - * and 'next_row' will be NULL if (and only if) the row does not contribute - * to the output in 'blocky' display mode. - * - * pass: 0..6 - * - * If 'next_row' is not NULL it is necessary for the application to combine the - * pixels with the output. This can most easily be done by calling - * png_progressive_combine_row(). Note that the 'next_row' data cannot be - * changed; even though the value is passed to png_progressive_combine_row the - * pointer is not used, it is just a flag , if it is NULL nothing will happen. - * - * If png_set_interlace_handling has not been called the callback only gets - * called for original PNG interlaced row: - * - * row_y: the y ordinate in the pass; 0..PNG_PASS_ROWS()-1 - * - * What is more if PNG_PASS_COLS() is 0 the entire pass will be skipped. The - * row data is not full width and there is no guarantee that the buffer passed - * in 'next_row' is able to accomodate the full width of output pixels, however - * 'next_row' will never be NULL. - * - * Use PNG_ROW_FROM_PASS_ROW(row_y, pass) and PNG_COL_FROM_PASS_COL(col, pass) - * to find the output pixel (x,y) given an interlaced sub-image pixel - * (row_y,col,pass). (See below for these macros.) - * - * Note that in this latter case if you want to do the 'blocky' display update - * method you have to work out all the details yourself with regard to which - * pixels to set for each row and whether to replicate it to the following - * rows of the image. - */ -typedef PNG_CALLBACK(void, *png_progressive_row_ptr, (png_structp, - png_bytep next_row, png_uint_32 row_y, int pass)); -#endif - -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -typedef PNG_CALLBACK(void, *png_user_transform_ptr, (png_structp, png_row_infop, - png_bytep)); -#endif - -#ifdef PNG_USER_CHUNKS_SUPPORTED -typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp, - png_unknown_chunkp)); -#endif -#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED -/* not used anywhere */ -/* typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); */ -#endif - -#ifdef PNG_SETJMP_SUPPORTED -/* This must match the function definition in , and the application - * must include this before png.h to obtain the definition of jmp_buf. The - * function is required to be PNG_NORETURN, but this is not checked. If the - * function does return the application will crash via an abort() or similar - * system level call. - * - * If you get a warning here while building the library you may need to make - * changes to ensure that pnglibconf.h records the calling convention used by - * your compiler. This may be very difficult - try using a different compiler - * to build the library! - */ -PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef); -#endif - -/* Transform masks for the high-level interface */ -#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */ -#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */ -#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */ -#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */ -#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */ -#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */ -#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */ -#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */ -#define PNG_TRANSFORM_BGR 0x0080 /* read and write */ -#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */ -#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */ -#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */ -#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* write only */ -/* Added to libpng-1.2.34 */ -#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER -#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */ -/* Added to libpng-1.4.0 */ -#define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */ -/* Added to libpng-1.5.4 */ -#define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */ -#define PNG_TRANSFORM_SCALE_16 0x8000 /* read only */ - -/* Flags for MNG supported features */ -#define PNG_FLAG_MNG_EMPTY_PLTE 0x01 -#define PNG_FLAG_MNG_FILTER_64 0x04 -#define PNG_ALL_MNG_FEATURES 0x05 - -/* NOTE: prior to 1.5 these functions had no 'API' style declaration, - * this allowed the zlib default functions to be used on Windows - * platforms. In 1.5 the zlib default malloc (which just calls malloc and - * ignores the first argument) should be completely compatible with the - * following. - */ -typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp, - png_alloc_size_t)); -typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp)); - -/* Section 4: exported functions - * Here are the function definitions most commonly used. This is not - * the place to find out how to use libpng. See libpng-manual.txt for the - * full explanation, see example.c for the summary. This just provides - * a simple one line description of the use of each function. - * - * The PNG_EXPORT() and PNG_EXPORTA() macros used below are defined in - * pngconf.h and in the *.dfn files in the scripts directory. - * - * PNG_EXPORT(ordinal, type, name, (args)); - * - * ordinal: ordinal that is used while building - * *.def files. The ordinal value is only - * relevant when preprocessing png.h with - * the *.dfn files for building symbol table - * entries, and are removed by pngconf.h. - * type: return type of the function - * name: function name - * args: function arguments, with types - * - * When we wish to append attributes to a function prototype we use - * the PNG_EXPORTA() macro instead. - * - * PNG_EXPORTA(ordinal, type, name, (args), attributes); - * - * ordinal, type, name, and args: same as in PNG_EXPORT(). - * attributes: function attributes - */ - -/* Returns the version number of the library */ -PNG_EXPORT(1, png_uint_32, png_access_version_number, (void)); - -/* Tell lib we have already handled the first magic bytes. - * Handling more than 8 bytes from the beginning of the file is an error. - */ -PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes)); - -/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a - * PNG file. Returns zero if the supplied bytes match the 8-byte PNG - * signature, and non-zero otherwise. Having num_to_check == 0 or - * start > 7 will always fail (ie return non-zero). - */ -PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, size_t start, - size_t num_to_check)); - -/* Simple signature checking function. This is the same as calling - * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). - */ -#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n)) - -/* Allocate and initialize png_ptr struct for reading, and any other memory. */ -PNG_EXPORTA(4, png_structp, png_create_read_struct, - (png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn), - PNG_ALLOCATED); - -/* Allocate and initialize png_ptr struct for writing, and any other memory */ -PNG_EXPORTA(5, png_structp, png_create_write_struct, - (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, - png_error_ptr warn_fn), - PNG_ALLOCATED); - -/* These APIs control the size of the buffer used for reading IDAT chunks in the - * sequential read code and the size of the IDAT chunks produced when writing. - * They have no effect on the progressive read code. In both read and write - * cases it will be necessary to allocate at least this amount of buffer space. - * The default value is PNG_IDAT_READ_SIZE on read and PNG_ZBUF_SIZE on write. - * - * The valid range is 1..0x7FFFFFFF on write and 1..max(uInt) on read, where - * uInt is the type declared by zlib.h. On write setting the largest value will - * typically cause the PNG image data to be written in one chunk; this gives the - * smallest PNG and has little or no effect on applications that read the PNG. - * - * DEPRECATED: use png_set_IDAT_size on write and png_set_read_buffer_size on - * read. - */ -PNG_EXPORTA(6, png_alloc_size_t, png_get_compression_buffer_size, - (png_const_structrp png_ptr), PNG_DEPRECATED); -PNG_EXPORTA(7, void, png_set_compression_buffer_size, (png_structrp png_ptr, - png_alloc_size_t size), PNG_DEPRECATED); -#define png_set_read_buffer_size(p,size) (png_setting((p),\ - PNG_SR_COMPRESS_buffer_size, (size), 0)) - /* The size of the buffer used while processing compressed data, both single - * chunk data (zTXt, iTXt, iCCP) and IDAT data. With IDAT data in libpng 1.7 - * IDATs are read until the end or until the buffer is full; this means that - * you can optimize the buffer size for the particular memory behavior of - * your system and, possibly, your application. - * - * NOTE: the result (on success) is 0, which is actually an invalid value. - * Retrieving the current value is not possible. - */ - -/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp - * match up. - */ -#ifdef PNG_SETJMP_SUPPORTED -/* This function returns the jmp_buf built in to *png_ptr. It must be - * supplied with an appropriate 'longjmp' function to use on that jmp_buf - * unless the default error function is overridden in which case NULL is - * acceptable. The size of the jmp_buf is checked against the actual size - * allocated by the library - the call will return NULL on a mismatch - * indicating an ABI mismatch. - */ -PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structrp png_ptr, - png_longjmp_ptr longjmp_fn, size_t jmp_buf_size)); -# define png_jmpbuf(png_ptr) \ - (*png_set_longjmp_fn((png_ptr), longjmp, (sizeof (jmp_buf)))) -#else -# define png_jmpbuf(png_ptr) \ - (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP) -#endif -/* This function should be used by libpng applications in place of - * longjmp(png_ptr->jmpbuf, val). If longjmp_fn() has been set, it - * will use it; otherwise it will call PNG_ABORT(). This function was - * added in libpng-1.5.0. - */ -PNG_EXPORTA(9, void, png_longjmp, (png_const_structrp png_ptr, int val), - PNG_NORETURN); - -#ifdef PNG_READ_SUPPORTED -/* Reset the compression stream -- Removed from libpng-1.7.0 */ -PNG_REMOVED(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED) -#endif - -/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ -#ifdef PNG_USER_MEM_SUPPORTED -PNG_EXPORTA(11, png_structp, png_create_read_struct_2, - (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, - png_error_ptr warn_fn, - png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), - PNG_ALLOCATED); -PNG_EXPORTA(12, png_structp, png_create_write_struct_2, - (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, - png_error_ptr warn_fn, - png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), - PNG_ALLOCATED); -#endif - -/* Write the PNG file signature. */ -PNG_EXPORT(13, void, png_write_sig, (png_structrp png_ptr)); - -/* Write a PNG chunk - size, type, (optional) data, CRC. */ -PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, - png_const_bytep chunk_name, png_const_voidp data, size_t length)); - -/* Write the start of a PNG chunk - length and chunk name. */ -PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr, - png_const_bytep chunk_name, png_uint_32 length)); - -/* Write the data of a PNG chunk started with png_write_chunk_start(). */ -PNG_EXPORT(16, void, png_write_chunk_data, (png_structrp png_ptr, - png_const_voidp data, size_t length)); - -/* Finish a chunk started with png_write_chunk_start() (includes CRC). */ -PNG_EXPORT(17, void, png_write_chunk_end, (png_structrp png_ptr)); - -/* Allocate and initialize the info structure */ -PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr), - PNG_ALLOCATED); - -/* Removed from libpng-1.7.0 */ -PNG_REMOVED(19, void, png_info_init_3, (png_infopp info_ptr, - size_t png_info_struct_size), PNG_DEPRECATED) - -/* Writes all the PNG information before the image. */ -PNG_EXPORT(20, void, png_write_info_before_PLTE, - (png_structrp png_ptr, png_const_inforp info_ptr)); -PNG_EXPORT(21, void, png_write_info, - (png_structrp png_ptr, png_const_inforp info_ptr)); - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the information before the actual image data. */ -PNG_EXPORT(22, void, png_read_info, - (png_structrp png_ptr, png_inforp info_ptr)); -#endif - -#ifdef PNG_TIME_RFC1123_SUPPORTED - /* Convert to a US string format: there is no localization support in this - * routine. The original implementation used a 29 character buffer in - * png_struct, this has been removed (in libpng 1.7.0). - */ -PNG_REMOVED(23, png_const_charp, png_convert_to_rfc1123, (png_structrp png_ptr, - png_const_timep ptime),PNG_DEPRECATED) -PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer, (char out[29], - png_const_timep ptime)); -#endif - -#ifdef PNG_CONVERT_tIME_SUPPORTED -/* Convert from a struct tm to png_time */ -PNG_EXPORT(24, PNG_DEPRECATED void, png_convert_from_struct_tm, - (png_timep ptime, const struct tm * ttime)); - -/* Convert from time_t to png_time. Uses gmtime() */ -PNG_EXPORT(25, PNG_DEPRECATED void, png_convert_from_time_t, (png_timep ptime, - time_t ttime)); -#endif /* CONVERT_tIME */ - -#ifdef PNG_READ_EXPAND_SUPPORTED -/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ -PNG_EXPORT(26, void, png_set_expand, (png_structrp png_ptr)); -PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structrp png_ptr)); -PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structrp png_ptr)); -PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structrp png_ptr)); -#endif - -#ifdef PNG_READ_EXPAND_16_SUPPORTED -/* Expand to 16-bit channels, forces conversion of palette to RGB and expansion - * of a tRNS chunk if present. - */ -PNG_EXPORT(221, void, png_set_expand_16, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) -/* Use blue, green, red order for pixels. */ -PNG_EXPORT(30, void, png_set_bgr, (png_structrp png_ptr)); -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -/* Expand the grayscale to 24-bit RGB if necessary. */ -PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structrp png_ptr)); -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -/* Reduce RGB to grayscale. */ -#define PNG_ERROR_ACTION_NO_CHECK 0 -#define PNG_ERROR_ACTION_NONE 1 -#define PNG_ERROR_ACTION_WARN 2 -#define PNG_ERROR_ACTION_ERROR 3 -#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/ - -PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structrp png_ptr, - int error_action, double red, double green)) -PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structrp png_ptr, - int error_action, png_fixed_point red, png_fixed_point green)) - /* Convert RGB pixels to gray (CIE Y) values, the red and green value must be - * less than or equal to 1, if either is negative a set of defaults - * corresponding to the sRGB standard are used. - * - * The error action specifies whether to check for r==g==b in each pixel, if - * it is 0 (PNG_ERROR_ACTION_NO_CHECK; added in libpng 1.7.0) no check will - * be performed, otherwise a check is performed and the result can be - * retrieved using png_get_rgb_to_gray_status (which just returns a - * true if a non-gray pixel was encountered). - * - * Pass PNG_ERROR_ACTION_ERROR if you are confident that the image only - * contains gray pixels (you have already checked); the check is still - * performed but a very optimized code path is used for RGB to gray - * convertion. - * - * If you want to extract a single channel pass PNG_FP_1 for the coefficient - * for that channel and 0 for the rest (0 for both red and green to extract - * blue). - * - * NOTE: the default coefficients used if negative values are passed for red - * or green are based on the cHRM chunk if available, otherwise sRGB. The - * calculation returns the Y (luminance value) corresponding to the white - * point of the PNG. UNLESS THE WHITE POINT IS D50 THIS IS NOT A CIEXYZ Y - * VALUE. It is the luminance of the pixel perceived by a viewer completely - * adapted to the white point of the PNG, this may not be what you want - * because to interpret it you have to also record the white point of the - * PNG. To obtain CIEXYZ Y values read the cHRM chunk XYZ values and - * chromatically adapt them to D50 - */ - -PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structrp - png_ptr)); -#endif - -#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED -PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth, - png_colorp palette)); -#endif - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED -/* How the alpha channel is interpreted - this affects how the color channels - * of a PNG file are returned to the calling application when an alpha channel, - * or a tRNS chunk in a palette file, is present. - * - * This has no effect on the way pixels are written into a PNG output - * datastream. The color samples in a PNG datastream are never premultiplied - * with the alpha samples. - * - * The default is to return data according to the PNG specification: the alpha - * channel is a linear measure of the contribution of the pixel to the - * corresponding composited pixel, and the color channels are unassociated - * (not premultiplied). The gamma encoded color channels must be scaled - * according to the contribution and to do this it is necessary to undo - * the encoding, scale the color values, perform the composition and reencode - * the values. This is the 'PNG' mode. - * - * The alternative is to 'associate' the alpha with the color information by - * storing color channel values that have been scaled by the alpha. - * image. These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes - * (the latter being the two common names for associated alpha color channels). - * - * For the 'OPTIMIZED' mode, a pixel is treated as opaque only if the alpha - * value is equal to the maximum value. - * - * The final choice is to gamma encode the alpha channel as well. This is - * broken because, in practice, no implementation that uses this choice - * correctly undoes the encoding before handling alpha composition. Use this - * choice only if other serious errors in the software or hardware you use - * mandate it; the typical serious error is for dark halos to appear around - * opaque areas of the composited PNG image because of arithmetic overflow. - * - * The API function png_set_alpha_mode specifies which of these choices to use - * with an enumerated 'mode' value and the gamma of the required output: - */ -#define PNG_ALPHA_PNG 0 /* according to the PNG standard */ -#define PNG_ALPHA_STANDARD 1 /* according to Porter/Duff */ -#define PNG_ALPHA_ASSOCIATED 1 /* as above; this is the normal practice */ -#define PNG_ALPHA_PREMULTIPLIED 1 /* as above */ -#define PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */ -#define PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */ - -PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structrp png_ptr, int mode, - double output_gamma)) -PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr, - int mode, png_fixed_point output_gamma)) -#endif - -#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED) -/* The output_gamma value is a screen gamma in libpng terminology: it expresses - * how to decode the output values, not how they are encoded. - */ -#define PNG_DEFAULT_sRGB -1 /* sRGB gamma and color space */ -#define PNG_GAMMA_MAC_18 -2 /* Old Mac '1.8' gamma and color space */ -#define PNG_GAMMA_sRGB 220000 /* Television standards--matches sRGB gamma */ -#define PNG_GAMMA_LINEAR PNG_FP_1 /* Linear */ -#endif - -/* The following are examples of calls to png_set_alpha_mode to achieve the - * required overall gamma correction and, where necessary, alpha - * premultiplication. - * - * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); - * This is the default libpng handling of the alpha channel - it is not - * pre-multiplied into the color components. In addition the call states - * that the output is for a sRGB system and causes all PNG files without gAMA - * chunks to be assumed to be encoded using sRGB. - * - * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); - * In this case the output is assumed to be something like an sRGB conformant - * display preceeded by a power-law lookup table of power 1.45. This is how - * early Mac systems behaved. - * - * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR); - * This is the classic Jim Blinn approach and will work in academic - * environments where everything is done by the book. It has the shortcoming - * of assuming that input PNG data with no gamma information is linear - this - * is unlikely to be correct unless the PNG files where generated locally. - * Most of the time the output precision will be so low as to show - * significant banding in dark areas of the image. - * - * png_set_expand_16(pp); - * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB); - * This is a somewhat more realistic Jim Blinn inspired approach. PNG files - * are assumed to have the sRGB encoding if not marked with a gamma value and - * the output is always 16 bits per component. This permits accurate scaling - * and processing of the data. If you know that your input PNG files were - * generated locally you might need to replace PNG_DEFAULT_sRGB with the - * correct value for your system. - * - * png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB); - * If you just need to composite the PNG image onto an existing background - * and if you control the code that does this you can use the optimization - * setting. In this case you just copy completely opaque pixels to the - * output. For pixels that are not completely transparent (you just skip - * those) you do the composition math using png_composite or png_composite_16 - * below then encode the resultant 8-bit or 16-bit values to match the output - * encoding. - * - * Other cases - * If neither the PNG nor the standard linear encoding work for you because - * of the software or hardware you use then you have a big problem. The PNG - * case will probably result in halos around the image. The linear encoding - * will probably result in a washed out, too bright, image (it's actually too - * contrasty.) Try the ALPHA_OPTIMIZED mode above - this will probably - * substantially reduce the halos. Alternatively try: - * - * png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB); - * This option will also reduce the halos, but there will be slight dark - * halos round the opaque parts of the image where the background is light. - * In the OPTIMIZED mode the halos will be light halos where the background - * is dark. Take your pick - the halos are unavoidable unless you can get - * your hardware/software fixed! (The OPTIMIZED approach is slightly - * faster.) - * - * When the default gamma of PNG files doesn't match the output gamma. - * If you have PNG files with no gamma information png_set_alpha_mode allows - * you to provide a default gamma, but it also sets the ouput gamma to the - * matching value. If you know your PNG files have a gamma that doesn't - * match the output you can take advantage of the fact that - * png_set_alpha_mode always sets the output gamma but only sets the PNG - * default if it is not already set: - * - * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); - * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); - * The first call sets both the default and the output gamma values, the - * second call overrides the output gamma without changing the default. This - * is easier than achieving the same effect with png_set_gamma. You must use - * PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will - * fire if more than one call to png_set_alpha_mode and png_set_background is - * made in the same read operation, however multiple calls with PNG_ALPHA_PNG - * are ignored. - */ - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED -PNG_EXPORT(36, void, png_set_strip_alpha, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) -PNG_EXPORT(37, void, png_set_swap_alpha, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) -PNG_EXPORT(38, void, png_set_invert_alpha, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) -/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */ -PNG_EXPORT(39, void, png_set_filler, (png_structrp png_ptr, png_uint_32 filler, - int flags)); -/* The values of the PNG_FILLER_ defines should NOT be changed */ -# define PNG_FILLER_BEFORE 0 -# define PNG_FILLER_AFTER 1 -/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ -PNG_EXPORT(40, void, png_set_add_alpha, (png_structrp png_ptr, - png_uint_32 filler, int flags)); -#endif /* READ_FILLER || WRITE_FILLER */ - -#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) -/* Swap bytes in 16-bit depth files. */ -PNG_EXPORT(41, void, png_set_swap, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) -/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ -PNG_EXPORT(42, void, png_set_packing, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ - defined(PNG_WRITE_PACKSWAP_SUPPORTED) -/* Swap packing order of pixels in bytes. */ -PNG_EXPORT(43, void, png_set_packswap, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) -/* Converts files to legal bit depths. */ -PNG_EXPORT(44, void, png_set_shift, (png_structrp png_ptr, png_const_color_8p - true_bits)); -#endif - -#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ - defined(PNG_WRITE_INTERLACING_SUPPORTED) -/* Have the code handle the interlacing. Returns the number of passes. - * MUST be called before png_read_update_info or png_start_read_image, - * otherwise it will not have the desired effect. Note that it is still - * necessary to call png_read_row or png_read_rows png_get_image_height - * times for each pass. -*/ -PNG_EXPORT(45, int, png_set_interlace_handling, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) -/* Invert monochrome files */ -PNG_EXPORT(46, void, png_set_invert_mono, (png_structrp png_ptr)); -#endif - -#ifdef PNG_READ_BACKGROUND_SUPPORTED -/* Handle alpha and tRNS by replacing with a background color. Prior to - * libpng-1.5.4 this API must not be called before the PNG file header has been - * read. Doing so will result in unexpected behavior and possible warnings or - * errors if the PNG file contains a bKGD chunk. - */ -PNG_FP_EXPORT(47, void, png_set_background, (png_structrp png_ptr, - png_const_color_16p background_color, int background_gamma_code, - int need_expand, double background_gamma)) -PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structrp png_ptr, - png_const_color_16p background_color, int background_gamma_code, - int need_expand, png_fixed_point background_gamma)) -#endif -#ifdef PNG_READ_BACKGROUND_SUPPORTED -# define PNG_BACKGROUND_GAMMA_UNKNOWN 0 -# define PNG_BACKGROUND_GAMMA_SCREEN 1 -# define PNG_BACKGROUND_GAMMA_FILE 2 -# define PNG_BACKGROUND_GAMMA_UNIQUE 3 -#endif - -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED -/* Scale a 16-bit depth file down to 8-bit, accurately. */ -PNG_EXPORT(229, void, png_set_scale_16, (png_structrp png_ptr)); -#endif - -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED -#define PNG_READ_16_TO_8_SUPPORTED /* Name prior to 1.5.4 */ -/* Strip the second byte of information from a 16-bit depth file. */ -PNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr)); -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED -/* Turn on quantizing, and reduce the palette to the number of colors - * available. - */ -PNG_EXPORT(49, void, png_set_quantize, (png_structrp png_ptr, - png_colorp palette, int num_palette, int maximum_colors, - png_const_uint_16p histogram, int full_quantize)); -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED -/* The threshold on gamma processing is configurable but hard-wired into the - * library. The following is the floating point variant. - */ -#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001) - -/* Handle gamma correction. Screen_gamma=(display_exponent). - * NOTE: this API simply sets the screen and file gamma values. It will - * therefore override the value for gamma in a PNG file if it is called after - * the file header has been read - use with care - call before reading the PNG - * file for best results! - * - * These routines accept the same gamma values as png_set_alpha_mode (described - * above). The PNG_GAMMA_ defines and PNG_DEFAULT_sRGB can be passed to either - * API (floating point or fixed.) Notice, however, that the 'file_gamma' value - * is the inverse of a 'screen gamma' value. - */ -PNG_FP_EXPORT(50, void, png_set_gamma, (png_structrp png_ptr, - double screen_gamma, double override_file_gamma)) -PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structrp png_ptr, - png_fixed_point screen_gamma, png_fixed_point override_file_gamma)) -#endif - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -PNG_REMOVED(51, void, png_set_flush, (png_structrp png_ptr, int nrows), - PNG_EMPTY) -#define png_set_flush(p,v) (png_setting((p), PNG_SW_FLUSH, 0, (v))) - /* Set how many lines between output flushes - 0 for no flushing. The result - * on success is always 0. - */ - -/* Flush the current PNG output buffer */ -PNG_EXPORT(52, void, png_write_flush, (png_structrp png_ptr)); -#endif /* WRITE_FLUSH */ - -/* Optional update palette with requested transformations */ -PNG_EXPORT(53, void, png_start_read_image, (png_structrp png_ptr)); - -/* Optional call to update the users info structure */ -PNG_EXPORT(54, void, png_read_update_info, (png_structrp png_ptr, - png_inforp info_ptr)); - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read one or more rows of image data. */ -PNG_EXPORT(55, void, png_read_rows, (png_structrp png_ptr, png_bytepp row, - png_bytepp display_row, png_uint_32 num_rows)); -#endif - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read a row of data. */ -PNG_EXPORT(56, void, png_read_row, (png_structrp png_ptr, png_bytep row, - png_bytep display_row)); -#endif - -#ifdef PNG_READ_IMAGE_SUPPORTED -/* Read the whole image into memory at once. */ -PNG_EXPORT(57, void, png_read_image, (png_structrp png_ptr, png_bytepp image)); -#endif - -/* Write a row of image data */ -PNG_EXPORT(58, void, png_write_row, (png_structrp png_ptr, - png_const_bytep row)); - -/* Write a few rows of image data: (*row) is not written; however, the type - * is declared as writeable to maintain compatibility with previous versions - * of libpng and to allow the 'display_row' array from read_rows to be passed - * unchanged to write_rows. - */ -PNG_EXPORT(59, void, png_write_rows, (png_structrp png_ptr, png_bytepp row, - png_uint_32 num_rows)); - -/* Write the image data */ -PNG_EXPORT(60, void, png_write_image, (png_structrp png_ptr, png_bytepp image)); - -/* Write the end of the PNG file. */ -PNG_EXPORT(61, void, png_write_end, (png_structrp png_ptr, - png_inforp info_ptr)); - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the end of the PNG file. */ -PNG_EXPORT(62, void, png_read_end, (png_structrp png_ptr, png_inforp info_ptr)); -#endif - -/* Free any memory associated with the png_info_struct */ -PNG_EXPORT(63, void, png_destroy_info_struct, (png_const_structrp png_ptr, - png_infopp info_ptr_ptr)); - -/* Free any memory associated with the png_struct and the png_info_structs */ -PNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr, - png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); - -/* Free any memory associated with the png_struct and the png_info_structs */ -PNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr, - png_infopp info_ptr_ptr)); - -/* Set the libpng method of handling chunk CRC errors on read */ -PNG_REMOVED(66, void, png_set_crc_action, (png_structrp png_ptr, - int crit_action, int ancil_action), PNG_EMPTY) -#define png_set_crc_action(png_ptr, crit, ancil)\ - (png_setting((png_ptr), PNG_SR_CRC_ACTION, (crit), (ancil))) - -/* Values for png_set_crc_action() say how to handle CRC errors in - * ancillary and critical chunks, and whether to use the data contained - * therein. Note that it is impossible to "discard" data in a critical - * chunk. For versions prior to 0.90, the action was always error/quit, - * whereas in version 0.90 and later, the action for CRC errors in ancillary - * chunks is warn/discard. These values should NOT be changed. - * - * value action:critical action:ancillary - */ -#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */ -#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */ -#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */ -#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */ -#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */ -#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */ - -/* Write image filtering and compression options. - * - * These settings just change the very low level encoding of a PNG. The changes - * make no difference to the image or the meta-data stored in the PNG. The API - * used to make these changes can be disabled in a very minimal configuration, - * if it is your compiler will report undefined values when the APIs below are - * used. - * - * Write settings defined here, in order of ease of use: - * - * 1) Write compression settings: whether to optimize the write and the PNG - * that results for read speed, final PNG size, write speed or memory - * usage. - * 2) IDAT size: What size to make the IDAT chunks in the PNG. - * 3) PNG row filters to consider when writing the PNG. - * 4) Very low level control over the deflate compression (useful mainly for - * programs that want to try every option to find which gives the smallest - * PNG.) - */ -#ifdef PNG_WRITE_SUPPORTED -/* (1) Write compression settings: */ -#define png_set_compression(p, v) (png_setting((p), PNG_SW_COMPRESS_png_level,\ - 0, (v))) - /* Control the write compression of all chunks. This affects five basic - * pieces of behavior: - * - * 1) The size of the PNG produced. - * 2) The amount of memory the write code takes to produce the PNG. - * 3) The amount of time the write code takes to produce the PNG. - * 4) The amount of memory required to read the resultant PNG. - * 5) The amount of time required to read the resultant PNG. - * - * There is considerable interdependence between these variables. As a - * result there are a limited number of options: - */ -# define PNG_COMPRESSION_LOW_MEMORY (1) - /* Minimize the memory required both when reading (4) and writing (2) the - * PNG. This results in a significantly larger PNG (which may itself have - * the opposite effect of slowing down either read or write) however the - * memory overhead is reduced and, apart from the extra time to read the - * data, the read time is likely to be reduced too. - * - * Use this when both read and write will happen on a memory starved - * (really, very low memory) system. Note that this sets a high deflate - * compression setting because that does not affect zlib memory usage. - */ -# define PNG_COMPRESSION_HIGH_SPEED (2) - /* Minimize the time to both read (5) and write (3) the PNG. This uses - * slightly more memory on read and potentially significantly more on - * write but is optimized for maximum speed in both cases. - * - * Use this when both read and write need to be fast and PNG size is not - * likely to be an issue. An example would be if you are using PNG to - * pass intermediate data between applications on the same machine. - */ -# define PNG_COMPRESSION_HIGH_READ_SPEED (3) - /* Minimize the time to read (5) the PNG. This also reduces the amount - * of memory on read, however some options which require more memory but - * are likely to decrease PNG size, therefore improve read spead, are - * used. - * - * This is one of the 'normal' options; options that are used when a - * reasonably capable write machine is producing PNG files that will be - * read many times. In this case the option is optimizing for speed on - * read even if it increases the size of the PNG. - */ -# define PNG_COMPRESSION_LOW (4) - /* This switches on options which do affect speed of both compression and - * decompression, but biases the choice towards higher performance in both - * cases. (So it is something of a compromise between all-out speed and - * PNG compression). - * - * This is a good default to use in typical usages where PNG file size is - * less of an issue than the overheads on reading a PNG file. - * - * Use this option when producing PNG files that are not expected to be - * distributed widely or where read speed is more important than size. - * This is also a good default for small images where the slight increase - * in size of the compressed data doesn't change the file size much. - */ -# define PNG_COMPRESSION_MEDIUM (5) - /* This is a compromise which switches on the options found most helpful - * across a wide range of files without switching on the full range of - * options which would decrease file size only a little while taking a lot - * more time. PNG read memory (4) or time (5) is not a factor in the - * choice of options; only write time (3). - * - * This is closest to the default used in prior versions of libpng. There - * seems no logic to using it if the actual requirements are known and, - * even if they aren't, it is probably better to guess 'LOW' or 'HIGH'. - * - * This is the normal libpng default. - */ -# define PNG_COMPRESSION_HIGH (6) - /* This turns on everything which reduces file size on aggregate across a - * large test set of files. It optimizes solely for the size of the - * resultant PNG (1). - * - * This is a good default to use if file size is all important; it was the - * stated original default in the PNG design, but the implementation of - * libpng never used it. - * - * Use this setting in image authoring applications when writing the - * finished image in PNG format. - * - * NOTE: several PNG file size optimizers exist (see the web-site - * libpng.org). libpng does not perform the same functions as these - * optimizers; libpng does not search for the best compression settings. - * For this reason if you really want to minimize the size of the PNG files - * produced use PNG_COMPRESSION_HIGH_SPEED then post-process the result - * with one of the many PNG optimization programs. - */ -# define PNG_COMPRESSION_COMPAT (0) - /* DEPRECATED: this is provided as a setting to aid transition of test - * suites between major library versions (1.5 or 1.6 moving to 1.7). The - * default settings change in 1.7 so, while the PNG files produced do not - * change, their encoding does. Test systems that rely on constant - * encoding can use this to verify that this is all that has changed. - * - * NOTE: the option will be removed at some point. It is difficult to - * maintain and adds to libpng code size. - * - * NOTE: there are other changes in major and minor releases, such as - * better ancillary chunk error handling, that also cause binary changes - * to the PNG files libpng generates. Furthermore versions of libpng - * prior to 1.7 included random data from uninitialized memory in the - * image data under certain circumstances; this meant that earlier - * versions were often not even consistent across two writes of the same - * PNG file! - */ - -/* png_set_compression sets the default for all libpng compression operations. - * While the setting is the same for all chunks it results in different - * compression options for different chunks. The setting can be applied - * separately to each class of chunks as follows: - */ -#define png_set_image_compression(p, v) (png_setting((p),\ - PNG_SW_COMPRESS_png_level, png_IDAT, (v))) - /* Control the compression of the image data (IDAT) chunks. */ - -#define png_set_ICC_profile_compression(p, v) (png_setting((p),\ - PNG_SW_COMPRESS_png_level, png_iCCP, (v))) - /* Control the compression of ICC profiles (iCCP chunks.) */ - -#define png_set_text_compression(p, v) (png_setting((p),\ - PNG_SW_COMPRESS_png_level, png_zTXt, (v))) - /* Control the compression of text (png_zTXt and png_iTXt) chunks. */ - -/* (2) IDAT size: */ -#define png_set_IDAT_size(p, v) (png_setting((p), PNG_SW_IDAT_size, (v), 0)) - /* Set the maximum size of the IDAT chunks libpng writes. Valid values are - * in the range 1U..0x7fffffffU, the default is 'PNG_ZBUF_SIZE' (a - * historically confusing name) and this default *also* controls the size of - * the buffer the read code uses when reading IDAT chunks. - * - * libpng has to buffer the data in the IDAT chunk before it writes any of - * it, therefore this number directly controls that part of the memory - * overhead while writing a PNG. There is a 12 byte per chunk overhead, so - * the number also directly affects the size of the PNG. The number has no - * significant effect (beyond the latter size effect) on the read code. - */ -#endif /* WRITE */ - -/* These functions give the user control over the scan-line filtering in - * libpng and the compression methods used by zlib. These functions are - * mainly useful for testing, as the defaults should work with most users. - * Those users who are tight on memory or want faster performance at the - * expense of compression can modify them. See the compression library - * header file (zlib.h) for an explination of the compression functions. - */ - -#ifdef PNG_WRITE_FILTER_SUPPORTED -/* (3) PNG row filters to consider when writing the PNG. - * - * Control the filtering method(s) used by libpng for the write of subsequent - * rows of the image. The argument is either a single filter value (one of the - * PNG_FILTER_VALUE_ defines above), in which case that filter will be used on - * following rows, or a mask of filter values (logical or of the PNG_FILTER_ - * bit masks that follow PNG_FILTER_VALUE_*). Support for selection of a filter - * from a mask with more than one bit set is dependent on - * PNG_SELECT_FILTER_SUPPORTED, however support is the default configuration of - * libpng. If support is not available the lowest bit set in the mask (the - * lowest numbered filter) is used. - * - * The set of filters may be changed at any time, the new values will affect the - * next row written. - * - * The 'method' must match that passed to png_set_IHDR; it cannot be changed and - * is ignored in 1.7 and later. - * - * If multiple filters are enabled libpng will select one according to the - * following rules: - * - * 1) On the first row of a pass UP is ignored if NONE is set and PAETH is - * ignored if SUB is set; this is because these filter pairs are equivalent - * when there is no previous row. - * - * 2) PNG_SELECT_FILTER_SUPPORTED: - * If the PNG rows are long enough (have enough bytes) libpng will process a - * row at a time; it will buffer the row if necessary. It uses a heuristic - * based on the closeness of the filtered values to 0 to determine which - * filter to use. - * - * 3) !PNG_SELECT_FILTER_SUPPORTED: - * libpng selects the first filter in the list (there is no warning that this - * will happen - check the #defines if you need to know.) - * - * The 'up', 'avg' and 'Paeth' filters require the previous image row to work. - * If it is not available they are removed from the set of filters to try. The - * first time the filter mask includes one of these filters libpng turns on - * saving of the row. The filters do work on the first row of a pass, where - * there is no previous row from the image. The PNG standard defines the - * previous row as consisting of all 0 bytes in this case. That definition - * causes the filters to have the following properties on the first row of a - * pass: - * - * UP: The same as NONE (i.e. no filtering). - * AVG: Uses the arithmetic (not modular arithmetc!) half of the preceding - * pixel as the predictor. This is unique and not typically very - * useful. - * PAETH: The same as SUB. - * - * As a result with all versions of libpng if you want to use any of these - * filters anywhere in the image you need only turn on one of them on the first - * row of the image, or of a pass for interlaced images. For example if you - * want to use 'sub' on the first row simply set 'sub'+'Paeth' in the mask; - * libpng will automatically eliminate the Paeth algorithm from consideration - * because it knows that 'sub' will rank equal or (if the filter byte is taken - * into account) better. - * - * This approach is portable to earlier versions of libpng, however it may be - * difficult to program. 1.7 allows you to directly specify whether or not to - * retain the previous row. This is simpler and allows you to turn off previous - * row retention if you want to. - */ -PNG_REMOVED(67, void, png_set_filter, (png_structrp png_ptr, int method, - int filters), PNG_EMPTY) - -#define png_set_filter(p, m, f) (png_setting((p), PNG_SW_COMPRESS_filters,\ - (m), (f))) - /* 'm' is the method and must be 0 (PNG_FILTER_TYPE_BASE) unless MNG - * processing is supported (very unusual). 'f' is either a single value, - * PNG_FILTER_VALUE_* below, or a combination of one or more PNG_FILTER_MASK - * values. - * - * This sets the filter mask (or value) for the *next* row that is written. - * It may be called at any time but does not have any effect until the next - * row starts to be written. - * - * The return value is the mask that is set (or, with PNG_SF_GET, the - * currently set mask). When PNG_SELECT_FILTER_SUPPORTED is not defined this - * mask will have only one bit. - * - * NOTE: with PNG_SF_GET the result will be PNG_UNSET if png_set_filter has - * not been called before and row writing has not started. - */ - -#define png_set_row_buffers(p, onoff) (png_setting((p),\ - PNG_SW_COMPRESS_row_buffers, (onoff), 0)) - /* If you intend to change the filter list after the first row using the - * previous API call png_set_row_buffers(png_ptr, 1) if you intend to use UP, - * AVG or Paeth filters. - * - * You can turn the buffering on and off dynamically, just as with - * png_set_filter. - * - * The second argument should be 0 (off) or 1 (on). In the future it may be - * used to control the maximum number of rows buffered. - */ -#endif /* WRITE_FILTER */ - -/* The PNG_FILTER_VALUE_ definitions (the filter values from the base PNG spec) - * are valid arguments to png_set_filter() if only a single filter is to be - * used. If multiple filters are to be allowed (the default is to allow any of - * them) then a combination of the following masks must be used and the low - * three bits of the argument to png_set_filter must be 0. - * - * The resultant argument fits in a single byte in either case. - */ -#define PNG_FILTER_MASK(value) (0x08 << (value)) -#define PNG_FILTER_NONE PNG_FILTER_MASK(PNG_FILTER_VALUE_NONE) -#define PNG_FILTER_SUB PNG_FILTER_MASK(PNG_FILTER_VALUE_SUB) -#define PNG_FILTER_UP PNG_FILTER_MASK(PNG_FILTER_VALUE_UP) -#define PNG_FILTER_AVG PNG_FILTER_MASK(PNG_FILTER_VALUE_AVG) -#define PNG_FILTER_PAETH PNG_FILTER_MASK(PNG_FILTER_VALUE_PAETH) - -/* Then three convenience values. PNG_NO_FILTERS is the same as - * PNG_FILTER_VALUE_NONE, but this is harmless because they mean the same thing. - */ -#define PNG_NO_FILTERS 0x00 -#define PNG_FAST_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP) -#define PNG_ALL_FILTERS (PNG_FAST_FILTERS | PNG_FILTER_AVG | PNG_FILTER_PAETH) - -#ifdef PNG_WRITE_SUPPORTED -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */ -PNG_REMOVED(68, void, png_set_filter_heuristics, - (png_structrp png_ptr, int heuristic_method, int num_weights, - png_const_doublep filter_weights, png_const_doublep filter_costs), - PNG_DEPRECATED) -PNG_REMOVED(209, void, png_set_filter_heuristics_fixed, - (png_structrp png_ptr, int heuristic_method, int num_weights, - png_const_fixed_point_p filter_weights, - png_const_fixed_point_p filter_costs), - PNG_DEPRECATED) - /* Neither of these API calls did anything in libpng 1.6, however they were - * not marked PNG_DEPRECATED, so they are converted to no-op function-like - * macros here. (NOTE: the macro arguments are evaluated once each, this - * will probably cause warnings with some compiler options: simply remove the - * function call after ensuring that the arguments had no side effects.) - */ -#define png_set_filter_heuristics(p,m,w,fw,fc) ((void)(p,m,w,fw,fc)) -#define png_set_filter_heuristics_fixed(p,m,w,fw,fc) ((void)(p,m,w,fw,fc)) -#endif /* WRITE_WEIGHTED_FILTER */ - -#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED -PNG_REMOVED(69, void, png_set_compression_level, (png_structrp png_ptr, - int level), PNG_EMPTY) -#define png_set_compression_level(p, v) (png_setting((p),\ - PNG_SW_COMPRESS_zlib_level, png_IDAT, (v))) - -PNG_REMOVED(70, void, png_set_compression_mem_level, (png_structrp png_ptr, - int mem_level), PNG_EMPTY) -#define png_set_compression_mem_level(p, v) (png_setting((p),\ - PNG_SW_COMPRESS_memLevel, png_IDAT, (v))) - -PNG_REMOVED(71, void, png_set_compression_strategy, (png_structrp png_ptr, - int strategy), PNG_EMPTY) -#define png_set_compression_strategy(p, v) (png_setting((p),\ - PNG_SW_COMPRESS_strategy, png_IDAT, (v))) - -PNG_REMOVED(72, void, png_set_compression_window_bits, (png_structrp png_ptr, - int window_bits), PNG_EMPTY) -#define png_set_compression_window_bits(p, v) (png_setting((p),\ - PNG_SW_COMPRESS_windowBits, png_IDAT, (v))) - -PNG_REMOVED(73, void, png_set_compression_method, (png_structrp png_ptr, - int method), PNG_EMPTY) -#define png_set_compression_method(p, v) (png_setting((p),\ - PNG_SW_COMPRESS_method, png_IDAT, (v))) -#endif /* WRITE_CUSTOMIZE_COMPRESSION */ - -#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED -/* Also set zlib parameters for compressing non-IDAT chunks */ -PNG_REMOVED(222, void, png_set_text_compression_level, (png_structrp png_ptr, - int level), PNG_EMPTY) -#define png_set_text_compression_level(p, v) (png_setting((p),\ - PNG_SW_COMPRESS_zlib_level, png_zTXt, (v))) - -PNG_REMOVED(223, void, png_set_text_compression_mem_level, - (png_structrp png_ptr, int mem_level), PNG_EMPTY) -#define png_set_text_compression_mem_level(p, v) (png_setting((p),\ - PNG_SW_COMPRESS_memLevel, png_zTXt, (v))) - -PNG_REMOVED(224, void, png_set_text_compression_strategy, (png_structrp png_ptr, - int strategy), PNG_EMPTY) -#define png_set_text_compression_strategy(p, v) (png_setting((p),\ - PNG_SW_COMPRESS_strategy, png_zTXt, (v))) - -PNG_REMOVED(225, void, png_set_text_compression_window_bits, - (png_structrp png_ptr, int window_bits), PNG_EMPTY) -#define png_set_text_compression_window_bits(p, v) (png_setting((p),\ - PNG_SW_COMPRESS_windowBits, png_zTXt, (v))) - -PNG_REMOVED(226, void, png_set_text_compression_method, (png_structrp png_ptr, - int method), PNG_EMPTY) -#define png_set_text_compression_method(p, v) (png_setting((p),\ - PNG_SW_COMPRESS_method, png_zTXt, (v))) - -/* NOTE: in versions of libpng prior to 1.7 iCCP compression was controlled by - * the text settings, hence the controls were only available if - * PNG_WRITE_CUSTOMIZIZE_ZTXT_COMPRESSION_SUPPORTED. In 1.7 the text settings - * no longer affect iCCP compression, the following macros must be used (if - * necessary): - */ -#define png_set_ICC_profile_compression_level(p, v) (png_setting((p),\ - PNG_SW_COMPRESS_zlib_level, png_iCCP, (v))) -#define png_set_ICC_profile_compression_mem_level(p, v) (png_setting((p),\ - PNG_SW_COMPRESS_memLevel, png_iCCP, (v))) -#define png_set_ICC_profile_compression_strategy(p, v) (png_setting((p),\ - PNG_SW_COMPRESS_strategy, png_iCCP, (v))) -#define png_set_ICC_profile_compression_window_bits(p, v) (png_setting((p),\ - PNG_SW_COMPRESS_windowBits, png_iCCP, (v))) -#define png_set_ICC_profile_compression_method(p, v) (png_setting((p),\ - PNG_SW_COMPRESS_method, png_iCCP, (v))) -#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */ -#endif /* WRITE */ - -/* These next functions are called for input/output, memory, and error - * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, - * and call standard C I/O routines such as fread(), fwrite(), and - * fprintf(). These functions can be made to use other I/O routines - * at run time for those applications that need to handle I/O in a - * different manner by calling png_set_???_fn(). See libpng-manual.txt for - * more information. - */ - -#ifdef PNG_STDIO_SUPPORTED -/* Initialize the input/output for the PNG file to the default functions. */ -PNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, png_FILE_p fp)); -#endif - -/* Replace the (error and abort), and warning functions with user - * supplied functions. If no messages are to be printed you must still - * write and use replacement functions. The replacement error_fn should - * still do a longjmp to the last setjmp location if you are using this - * method of error handling. If error_fn or warning_fn is NULL, the - * default function will be used. - */ - -PNG_EXPORT(75, void, png_set_error_fn, (png_structrp png_ptr, - png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn)); - -/* Return the user pointer associated with the error functions */ -PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structrp png_ptr)); - -/* Replace the default data output functions with a user supplied one(s). - * If buffered output is not used, then output_flush_fn can be set to NULL. - * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time - * output_flush_fn will be ignored (and thus can be NULL). - * It is probably a mistake to use NULL for output_flush_fn if - * write_data_fn is not also NULL unless you have built libpng with - * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's - * default flush function, which uses the standard *FILE structure, will - * be used. - */ -PNG_EXPORT(77, void, png_set_write_fn, (png_structrp png_ptr, png_voidp io_ptr, - png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); - -/* Replace the default data input function with a user supplied one. */ -PNG_EXPORT(78, void, png_set_read_fn, (png_structrp png_ptr, png_voidp io_ptr, - png_rw_ptr read_data_fn)); - -/* Return the user pointer associated with the I/O functions */ -PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_const_structrp png_ptr)); - -PNG_EXPORT(80, void, png_set_read_status_fn, (png_structrp png_ptr, - png_read_status_ptr read_row_fn)); - -PNG_EXPORT(81, void, png_set_write_status_fn, (png_structrp png_ptr, - png_write_status_ptr write_row_fn)); - -#ifdef PNG_USER_MEM_SUPPORTED -/* Replace the default memory allocation functions with user supplied one(s). */ -PNG_EXPORT(82, void, png_set_mem_fn, (png_structrp png_ptr, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn)); -/* Return the user pointer associated with the memory functions */ -PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structrp png_ptr)); -#endif - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED -PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structrp png_ptr, - png_user_transform_ptr read_user_transform_fn)); -#endif - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED -PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structrp png_ptr, - png_user_transform_ptr write_user_transform_fn)); -#endif - -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -PNG_EXPORT(86, void, png_set_user_transform_info, (png_structrp png_ptr, - png_voidp user_transform_ptr, int user_transform_depth, - int user_transform_channels)); -/* Return the user pointer associated with the user transform functions */ -PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr, - (png_const_structrp png_ptr)); -#endif - -#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED -/* Return information about the row currently being processed. Note that these - * APIs do not fail but will return unexpected results if called outside a user - * transform callback. Also note that when transforming an interlaced image the - * row number is the row number within the sub-image of the interlace pass, so - * the value will increase to the height of the sub-image (not the full image) - * then reset to 0 for the next pass. - * - * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to - * find the output pixel (x,y) given an interlaced sub-image pixel - * (row,col,pass). (See below for these macros.) - */ -PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structrp)); -PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp)); -#endif - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED -/* This callback is called only for *unknown* chunks. If - * PNG_HANDLE_AS_UNKNOWN_SUPPORTED is set then it is possible to set known - * chunks to be treated as unknown, however in this case the callback must do - * any processing required by the chunk and this is not possible for any chunk - * that affects the image reading (e.g. PLTE, tRNS). - * - * There is no write support - on write, by default, all the chunks in the - * 'unknown' list are written in the specified position. - * - * The integer return from the callback function is interpreted thus: - * - * negative: An error occurred; png_chunk_error will be called. - * zero: The chunk was not handled, the default unknown handling is used - * (even if this was a chunk that would otherwise be known.) - * NOTE: prior to libpng 1.7 handling values of - * PNG_HANDLE_CHUNK_AS_DEFAULT and PNG_HANDLE_CHUNK_NEVER were - * converted to PNG_HANDLE_CHUNK_IF_SAFE (libpng 1.6.0 warns if this - * happens) so it was not possible to discard unknown chunk data if a - * user callback was installed. - * positive: The chunk was handled, libpng will ignore/discard it. - * - * WARNING: if this callback is set every chunk in the stream is temporarily - * read into a memory buffer. This has potential performance implications, - * particularly for small PNG images with large amounts of ancilliary - * information. - */ -PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structrp png_ptr, - png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); -#endif - -#ifdef PNG_USER_CHUNKS_SUPPORTED -PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structrp png_ptr)); -#endif - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -/* Sets the function callbacks for the push reader, and a pointer to a - * user-defined structure available to the callback functions. - */ -PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structrp png_ptr, - png_voidp progressive_ptr, png_progressive_info_ptr info_fn, - png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn)); - -/* Returns the user pointer associated with the push read functions */ -PNG_EXPORT(91, png_voidp, png_get_progressive_ptr, - (png_const_structrp png_ptr)); - -/* Function to be called when data becomes available */ -PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr, - png_inforp info_ptr, png_bytep buffer, size_t buffer_size)); - -/* A function which may be called *only* within png_process_data to stop the - * processing of any more data. The function returns the number of bytes - * remaining, excluding any that libpng has cached internally. A subsequent - * call to png_process_data must supply these bytes again. If the argument - * 'save' is set to true the routine will first save all the pending data and - * will always return 0. - */ -PNG_EXPORT(219, size_t, png_process_data_pause, (png_structrp, int save)); - -/* A function which may be called *only* outside (after) a call to - * png_process_data. It returns the number of bytes of data to skip in the - * input. Normally it will return 0, but if it returns a non-zero value the - * application must skip than number of bytes of input data and pass the - * following data to the next call to png_process_data. - */ -PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structrp)); - -#ifdef PNG_READ_INTERLACING_SUPPORTED -/* Function that combines rows. 'new_row' is a flag that should come from - * the callback and be non-NULL if anything needs to be done; the library - * stores its own version of the new data internally and ignores the passed - * in value. - */ -PNG_EXPORT(93, void, png_progressive_combine_row, (png_const_structrp png_ptr, - png_bytep old_row, png_const_bytep new_row)); -#endif /* READ_INTERLACING */ -#endif /* PROGRESSIVE_READ */ - -PNG_EXPORTA(94, png_voidp, png_malloc, (png_const_structrp png_ptr, - png_alloc_size_t size), PNG_ALLOCATED); -/* Added at libpng version 1.4.0 */ -PNG_EXPORTA(95, png_voidp, png_calloc, (png_const_structrp png_ptr, - png_alloc_size_t size), PNG_ALLOCATED); - -/* Added at libpng version 1.2.4 */ -PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_const_structrp png_ptr, - png_alloc_size_t size), PNG_ALLOCATED); - -/* Frees a pointer allocated by png_malloc() */ -PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr)); - -/* Free data that was allocated internally */ -PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr, - png_inforp info_ptr, png_uint_32 free_me, int num)); - -/* Reassign responsibility for freeing existing data, whether allocated - * by libpng or by the application; this works on the png_info structure passed - * in, it does not change the state for other png_info structures. - * - * It is unlikely that this function works correctly as of 1.6.0 and using it - * may result either in memory leaks or double free of allocated data. It was - * removed in libpng 1.7.0. - */ -PNG_REMOVED(99, void, png_data_freer, (png_const_structrp png_ptr, - png_inforp info_ptr, int freer, png_uint_32 mask), PNG_DEPRECATED) - -/* Flags for png_free_data */ -#define PNG_FREE_HIST 0x0008U -#define PNG_FREE_ICCP 0x0010U -#define PNG_FREE_SPLT 0x0020U -#define PNG_FREE_ROWS 0x0040U -#define PNG_FREE_PCAL 0x0080U -#define PNG_FREE_SCAL 0x0100U -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -# define PNG_FREE_UNKN 0x0200U -#endif -/* PNG_FREE_LIST 0x0400U removed in 1.6.0 because it is ignored */ -#define PNG_FREE_PLTE 0x1000U -#define PNG_FREE_TRNS 0x2000U -#define PNG_FREE_TEXT 0x4000U -#define PNG_FREE_ALL 0x7fffU -#define PNG_FREE_MUL 0x4220U /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ - -#ifdef PNG_USER_MEM_SUPPORTED - /* These were deprecated in libpng 1.6.0 and have been removed from libpng - * 1.7.0; the functionality should be accessed by calling malloc or free - * directly or, if png_error handling is required, calling png_malloc. - */ -PNG_REMOVED(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr, - png_alloc_size_t size), PNG_ALLOCATED PNG_DEPRECATED) -PNG_REMOVED(101, void, png_free_default, (png_const_structrp png_ptr, - png_voidp ptr), PNG_DEPRECATED) -#endif - -#ifdef PNG_ERROR_TEXT_SUPPORTED -/* Fatal error in PNG image of libpng - can't continue */ -PNG_EXPORTA(102, void, png_error, (png_const_structrp png_ptr, - png_const_charp error_message), PNG_NORETURN); -#else -/* Fatal error in PNG image of libpng - can't continue */ -PNG_EXPORTA(104, void, png_err, (png_const_structrp png_ptr), PNG_NORETURN); -# define png_error(s1,s2) png_err(s1) -#endif - -#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) -/* The same, but the chunk name is prepended to the error string. */ -PNG_EXPORTA(103, void, png_chunk_error, (png_const_structrp png_ptr, - png_const_charp error_message), PNG_NORETURN); -#else -# define png_chunk_error(s1,s2) png_error(s1,s2) -#endif - -#ifdef PNG_WARNINGS_SUPPORTED -/* Non-fatal error in libpng. Can continue, but may have a problem. */ -PNG_EXPORT(105, void, png_warning, (png_const_structrp png_ptr, - png_const_charp warning_message)); - -/* Non-fatal error in libpng, chunk name is prepended to message. */ -PNG_EXPORT(106, void, png_chunk_warning, (png_const_structrp png_ptr, - png_const_charp warning_message)); -#else -# define png_warning(s1,s2) ((void)(s1)) -# define png_chunk_warning(s1,s2) ((void)(s1)) -#endif - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED -/* Benign error in libpng. Can continue, but may have a problem. - * User can choose whether to handle as a fatal error or as a warning. */ -PNG_EXPORT(107, void, png_benign_error, (png_const_structrp png_ptr, - png_const_charp warning_message)); - -#ifdef PNG_READ_SUPPORTED -/* Same, chunk name is prepended to message (only during read) */ -PNG_EXPORT(108, void, png_chunk_benign_error, (png_const_structrp png_ptr, - png_const_charp warning_message)); -#endif - -#define png_set_error_action(png_ptr, what, action)\ - (png_setting((png_ptr), PNG_SRW_ERROR_HANDLING, (what), (action))) - /* Control the handling of 'benign' errors; errors that can be handled in - * some way. The action is one of the following values: - */ -#define PNG_IGNORE 0 /* ignore the error; no warning or error message */ -#define PNG_WARN 1 /* call png_warning with an appropriate error message */ -#define PNG_ERROR 2 /* call png_error with the error message */ - /* 'what' is a list (bit mask) of the errors to set: */ -#define PNG_BENIGN_ERRORS (1U) -#define PNG_APP_WARNINGS (2U) -#define PNG_APP_ERRORS (4U) -#define PNG_IDAT_ERRORS (8U) -#define PNG_SAFE_ERRORS (PNG_BENIGN_ERRORS+PNG_APP_WARNINGS+PNG_APP_ERRORS) -#define PNG_ALL_ERRORS (PNG_SAFE_ERRORS+PNG_IDAT_ERRORS) - -PNG_REMOVED(109, void, png_set_benign_errors, - (png_structrp png_ptr, int allowed), PNG_EMPTY) -#define png_set_benign_errors(png_ptr, allowed) (png_setting((png_ptr),\ - PNG_SRW_ERROR_HANDLING, PNG_SAFE_ERRORS,\ - (allowed) ? PNG_WARN : PNG_ERROR)) - /* Turn all errors that can be handled into warnings, or turn them back into - * errors if 'allowed' is false. - */ - -#else -# ifdef PNG_ALLOW_BENIGN_ERRORS -# define png_benign_error(pp,e) png_warning(pp,e) -# define png_chunk_benign_error(pp,e) png_chunk_warning(pp,e) -# else -# define png_benign_error(pp,e) png_error(pp,e) -# define png_chunk_benign_error(pp,e) png_chunk_error(pp,e) -# endif -#endif - -/* The png_set_ functions are for storing values in the png_info_struct. - * Similarly, the png_get_ calls are used to read values from the - * png_info_struct, either storing the parameters in the passed variables, or - * setting pointers into the png_info_struct where the data is stored. The - * png_get_ functions return a non-zero value if the data was available - * in info_ptr, or return zero and do not change any of the parameters if the - * data was not available. - * - * These functions should be used instead of directly accessing png_info - * to avoid problems with future changes in the size and internal layout of - * png_info_struct. - */ -/* Returns "flag" if chunk data is valid in info_ptr. */ -PNG_EXPORT(110, png_uint_32, png_get_valid, (png_const_structrp png_ptr, - png_const_inforp info_ptr, png_uint_32 flag)); - -/* Returns number of bytes needed to hold a transformed row. */ -PNG_EXPORT(111, png_alloc_size_t, png_get_rowbytes, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -#ifdef PNG_READ_PNG_SUPPORTED -/* Returns row_pointers, which is an array of pointers to scanlines that was - * returned from png_read_png(). - */ -PNG_EXPORT(112, png_bytepp, png_get_rows, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); -#endif - -#ifdef PNG_WRITE_PNG_SUPPORTED -/* Set row_pointers, which is an array of pointers to scanlines for use - * by png_write_png(). - */ -PNG_EXPORT(113, void, png_set_rows, (png_const_structrp png_ptr, - png_inforp info_ptr, png_bytepp row_pointers)); -#endif - -/* Returns number of color channels in image. */ -PNG_EXPORT(114, png_byte, png_get_channels, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -#ifdef PNG_EASY_ACCESS_SUPPORTED -/* Returns image width in pixels. */ -PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image height in pixels. */ -PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image bit_depth. */ -PNG_EXPORT(117, png_byte, png_get_bit_depth, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image color_type. */ -PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image filter_type. */ -PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image interlace_type. */ -PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image compression_type. */ -PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image resolution in pixels per meter, from pHYs chunk data. */ -PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); -PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); -PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); - -/* Returns pixel aspect ratio, computed from pHYs chunk data. */ -PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio, - (png_const_structrp png_ptr, png_const_inforp info_ptr)) -PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr)) - -/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ -PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); -PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); -PNG_EXPORT(128, png_int_32, png_get_x_offset_microns, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); -PNG_EXPORT(129, png_int_32, png_get_y_offset_microns, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); - -#endif /* EASY_ACCESS */ - -#ifdef PNG_READ_SUPPORTED -/* Returns pointer to signature string read from PNG header */ -PNG_EXPORT(130, png_const_bytep, png_get_signature, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); -#endif - -#ifdef PNG_bKGD_SUPPORTED -PNG_EXPORT(131, png_uint_32, png_get_bKGD, (png_const_structrp png_ptr, - png_inforp info_ptr, png_color_16p *background)); -#endif - -#ifdef PNG_bKGD_SUPPORTED -PNG_EXPORT(132, void, png_set_bKGD, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_color_16p background)); -#endif - -#ifdef PNG_cHRM_SUPPORTED -PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structrp png_ptr, - png_const_inforp info_ptr, double *white_x, double *white_y, double *red_x, - double *red_y, double *green_x, double *green_y, double *blue_x, - double *blue_y)) -PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_const_structrp png_ptr, - png_const_inforp info_ptr, double *red_X, double *red_Y, double *red_Z, - double *green_X, double *green_Y, double *green_Z, double *blue_X, - double *blue_Y, double *blue_Z)) -PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *int_white_x, png_fixed_point *int_white_y, - png_fixed_point *int_red_x, png_fixed_point *int_red_y, - png_fixed_point *int_green_x, png_fixed_point *int_green_y, - png_fixed_point *int_blue_x, png_fixed_point *int_blue_y)) -PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *int_red_X, png_fixed_point *int_red_Y, - png_fixed_point *int_red_Z, png_fixed_point *int_green_X, - png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, - png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, - png_fixed_point *int_blue_Z)) -#endif - -#ifdef PNG_cHRM_SUPPORTED -PNG_FP_EXPORT(135, void, png_set_cHRM, (png_const_structrp png_ptr, - png_inforp info_ptr, - double white_x, double white_y, double red_x, double red_y, double green_x, - double green_y, double blue_x, double blue_y)) -PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_const_structrp png_ptr, - png_inforp info_ptr, double red_X, double red_Y, double red_Z, - double green_X, double green_Y, double green_Z, double blue_X, - double blue_Y, double blue_Z)) -PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_const_structrp png_ptr, - png_inforp info_ptr, png_fixed_point int_white_x, - png_fixed_point int_white_y, png_fixed_point int_red_x, - png_fixed_point int_red_y, png_fixed_point int_green_x, - png_fixed_point int_green_y, png_fixed_point int_blue_x, - png_fixed_point int_blue_y)) -PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr, - png_inforp info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y, - png_fixed_point int_red_Z, png_fixed_point int_green_X, - png_fixed_point int_green_Y, png_fixed_point int_green_Z, - png_fixed_point int_blue_X, png_fixed_point int_blue_Y, - png_fixed_point int_blue_Z)) -#endif - -#ifdef PNG_gAMA_SUPPORTED -PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr, - png_const_inforp info_ptr, double *file_gamma)) -PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *int_file_gamma)) -#endif - -#ifdef PNG_gAMA_SUPPORTED -PNG_FP_EXPORT(139, void, png_set_gAMA, (png_const_structrp png_ptr, - png_inforp info_ptr, double file_gamma)) -PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr, - png_inforp info_ptr, png_fixed_point int_file_gamma)) -#endif - -#ifdef PNG_hIST_SUPPORTED -PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr, - png_inforp info_ptr, png_uint_16p *hist)); -#endif - -#ifdef PNG_hIST_SUPPORTED -PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_uint_16p hist)); -#endif - -PNG_EXPORT(143, png_uint_32, png_get_IHDR, (png_const_structrp png_ptr, - png_const_inforp info_ptr, png_uint_32 *width, png_uint_32 *height, - int *bit_depth, int *color_type, int *interlace_method, - int *compression_method, int *filter_method)); - -PNG_EXPORT(144, void, png_set_IHDR, (png_const_structrp png_ptr, - png_inforp info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_method, int compression_method, - int filter_method)); - -#ifdef PNG_oFFs_SUPPORTED -PNG_EXPORT(145, png_uint_32, png_get_oFFs, (png_const_structrp png_ptr, - png_const_inforp info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, - int *unit_type)); -#endif - -#ifdef PNG_oFFs_SUPPORTED -PNG_EXPORT(146, void, png_set_oFFs, (png_const_structrp png_ptr, - png_inforp info_ptr, png_int_32 offset_x, png_int_32 offset_y, - int unit_type)); -#endif - -#ifdef PNG_pCAL_SUPPORTED -PNG_EXPORT(147, png_uint_32, png_get_pCAL, (png_const_structrp png_ptr, - png_inforp info_ptr, png_charp *purpose, png_int_32 *X0, - png_int_32 *X1, int *type, int *nparams, png_charp *units, - png_charpp *params)); -#endif - -#ifdef PNG_pCAL_SUPPORTED -PNG_EXPORT(148, void, png_set_pCAL, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_charp purpose, png_int_32 X0, png_int_32 X1, - int type, int nparams, png_const_charp units, png_charpp params)); -#endif - -#ifdef PNG_pHYs_SUPPORTED -PNG_EXPORT(149, png_uint_32, png_get_pHYs, (png_const_structrp png_ptr, - png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, - int *unit_type)); -#endif - -#ifdef PNG_pHYs_SUPPORTED -PNG_EXPORT(150, void, png_set_pHYs, (png_const_structrp png_ptr, - png_inforp info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type)); -#endif - -PNG_EXPORT(151, png_uint_32, png_get_PLTE, (png_const_structrp png_ptr, - png_inforp info_ptr, png_colorp *palette, int *num_palette)); - -PNG_EXPORT(152, void, png_set_PLTE, (png_structrp png_ptr, - png_inforp info_ptr, png_const_colorp palette, int num_palette)); - -#ifdef PNG_sBIT_SUPPORTED -PNG_EXPORT(153, png_uint_32, png_get_sBIT, (png_const_structrp png_ptr, - png_inforp info_ptr, png_color_8p *sig_bit)); -#endif - -#ifdef PNG_sBIT_SUPPORTED -PNG_EXPORT(154, void, png_set_sBIT, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_color_8p sig_bit)); -#endif - -#ifdef PNG_sRGB_SUPPORTED -PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structrp png_ptr, - png_const_inforp info_ptr, int *file_srgb_intent)); -#endif - -#ifdef PNG_sRGB_SUPPORTED -PNG_EXPORT(156, void, png_set_sRGB, (png_const_structrp png_ptr, - png_inforp info_ptr, int srgb_intent)); -PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_const_structrp png_ptr, - png_inforp info_ptr, int srgb_intent)); -#endif - -#ifdef PNG_iCCP_SUPPORTED -PNG_EXPORT(158, png_uint_32, png_get_iCCP, (png_const_structrp png_ptr, - png_inforp info_ptr, png_charpp name, int *compression_type, - png_bytepp profile, png_uint_32 *proflen)); -#endif - -#ifdef PNG_iCCP_SUPPORTED -PNG_EXPORT(159, void, png_set_iCCP, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_charp name, int compression_type, - png_const_bytep profile, png_uint_32 proflen)); -#endif - -#ifdef PNG_sPLT_SUPPORTED -PNG_EXPORT(160, int, png_get_sPLT, (png_const_structrp png_ptr, - png_inforp info_ptr, png_sPLT_tpp entries)); -#endif - -#ifdef PNG_sPLT_SUPPORTED -PNG_EXPORT(161, void, png_set_sPLT, (png_structrp png_ptr, - png_inforp info_ptr, png_const_sPLT_tp entries, int nentries)); -#endif - -#ifdef PNG_TEXT_SUPPORTED -/* png_get_text also returns the number of text chunks in *num_text */ -PNG_EXPORT(162, int, png_get_text, (png_const_structrp png_ptr, - png_inforp info_ptr, png_textp *text_ptr, int *num_text)); -#endif - -/* Note while png_set_text() will accept a structure whose text, - * language, and translated keywords are NULL pointers, the structure - * returned by png_get_text will always contain regular - * zero-terminated C strings. They might be empty strings but - * they will never be NULL pointers. - */ - -#ifdef PNG_TEXT_SUPPORTED -PNG_EXPORT(163, void, png_set_text, (png_structrp png_ptr, - png_inforp info_ptr, png_const_textp text_ptr, int num_text)); -#endif - -#ifdef PNG_tIME_SUPPORTED -PNG_EXPORT(164, png_uint_32, png_get_tIME, (png_const_structrp png_ptr, - png_inforp info_ptr, png_timep *mod_time)); -#endif - -#ifdef PNG_tIME_SUPPORTED -PNG_EXPORT(165, void, png_set_tIME, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_timep mod_time)); -#endif - -#ifdef PNG_tRNS_SUPPORTED -PNG_EXPORT(166, png_uint_32, png_get_tRNS, (png_const_structrp png_ptr, - png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans, - png_color_16p *trans_color)); -#endif - -#ifdef PNG_tRNS_SUPPORTED -PNG_EXPORT(167, void, png_set_tRNS, (png_structrp png_ptr, - png_inforp info_ptr, png_const_bytep trans_alpha, int num_trans, - png_const_color_16p trans_color)); -#endif - -#ifdef PNG_sCAL_SUPPORTED -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED -/* NOTE: these API are currently implemented using floating point arithmetic, - * consequently they can only be used on systems with floating point support. - * In any case the range of values supported by png_fixed_point is small and it - * is highly recommended that png_get_sCAL_s be used instead. - */ -PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr, - png_const_inforp info_ptr, int *unit, double *width, double *height)) -PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, - png_fixed_point *width, png_fixed_point *height)) -#endif -PNG_EXPORT(169, png_uint_32, png_get_sCAL_s, - (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, - png_charpp swidth, png_charpp sheight)); - -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED -/* This also requires internal floating point arithmetic support - i.e. it - * requires a full math library, not just floating point handling. - */ -PNG_FP_EXPORT(170, void, png_set_sCAL, (png_const_structrp png_ptr, - png_inforp info_ptr, int unit, double width, double height)) -#endif -PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_const_structrp png_ptr, - png_inforp info_ptr, int unit, png_fixed_point width, - png_fixed_point height)) -PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr, - png_inforp info_ptr, int unit, - png_const_charp swidth, png_const_charp sheight)); -#endif /* sCAL */ - -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED -/* Provide the default handling for all unknown chunks or, optionally, for - * specific unknown chunks. - * - * NOTE: prior to 1.6.0 the handling specified for particular chunks on read was - * ignored and the default was used, the per-chunk setting only had an effect on - * write. If you wish to have chunk-specific handling on read in code that must - * work on earlier versions you must use a user chunk callback to implement the - * desired handling (keep or discard.) - * - * NOTE: prior to 1.7.0 when a user callback returned '0', indicating that the - * chunk had not been handled, libpng would preserve it regardless of the - * default or per-chunk settings. For compatibility with earlier versions - * simply return '1' (handled) from the callback to discard the chunk. - * - * The 'keep' parameter is a PNG_HANDLE_CHUNK_ value as listed below. The - * parameter is interpreted as follows: - * - * READ: - * PNG_HANDLE_CHUNK_AS_DEFAULT: - * Known chunks: do normal libpng processing, do not keep the chunk (but - * see the comments below about PNG_HANDLE_AS_UNKNOWN_SUPPORTED) - * Unknown chunks: for a specific chunk use the global default, when used - * as the default discard the chunk data. - * PNG_HANDLE_CHUNK_NEVER: - * Discard the chunk data. - * PNG_HANDLE_CHUNK_IF_SAFE: - * Keep the chunk data if the chunk is not critical else raise a chunk - * error. - * PNG_HANDLE_CHUNK_ALWAYS: - * Keep the chunk data. - * - * If the chunk data is saved it can be retrieved using png_get_unknown_chunks, - * below. Notice that specifying "AS_DEFAULT" as a global default is equivalent - * to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks - * it simply resets the behavior to the libpng default. - * - * The per-chunk handling is always used when there is a png_user_chunk_ptr - * callback and the callback returns 0; the chunk is then always stored *unless* - * it is critical and the per-chunk setting is other than ALWAYS. Notice that - * the global default is *not* used in this case. (In effect the per-chunk - * value is incremented to at least IF_SAFE.) - * - * PNG_HANDLE_AS_UNKNOWN_SUPPORTED: - * If this is *not* set known chunks will always be handled by libpng and - * will never be stored in the unknown chunk list. Known chunks listed to - * png_set_keep_unknown_chunks will have no effect. If it is set then known - * chunks listed with a keep other than AS_DEFAULT will *never* be processed - * by libpng, in addition critical chunks must either be processed by the - * callback or saved. - * - * The IHDR and IEND chunks must not be listed. Because this turns off the - * default handling for chunks that would otherwise be recognized the - * behavior of libpng transformations may well become incorrect! - * - * WRITE: - * When writing chunks the options only apply to the chunks specified by - * png_set_unknown_chunks (below), libpng will *always* write known chunks - * required by png_set_ calls and will always write the core critical chunks - * (as required for PLTE). - * - * Each chunk in the png_set_unknown_chunks list is looked up in the - * png_set_keep_unknown_chunks list to find the keep setting, this is then - * interpreted as follows: - * - * PNG_HANDLE_CHUNK_AS_DEFAULT: - * Write safe-to-copy chunks and write other chunks if the global - * default is set to _ALWAYS, otherwise don't write this chunk. - * PNG_HANDLE_CHUNK_NEVER: - * Do not write the chunk. - * PNG_HANDLE_CHUNK_IF_SAFE: - * Write the chunk if it is safe-to-copy, otherwise do not write it. - * PNG_HANDLE_CHUNK_ALWAYS: - * Write the chunk. - * - * Note that the default behavior is effectively the opposite of the read case - - * in read unknown chunks are not stored by default, in write they are written - * by default. Also the behavior of PNG_HANDLE_CHUNK_IF_SAFE is very different - * - on write the safe-to-copy bit is checked, on read the critical bit is - * checked and on read if the chunk is critical an error will be raised. - * - * num_chunks: - * =========== - * If num_chunks is positive, then the "keep" parameter specifies the manner - * for handling only those chunks appearing in the chunk_list array, - * otherwise the chunk list array is ignored. - * - * If num_chunks is 0 the "keep" parameter specifies the default behavior for - * unknown chunks, as described above. - * - * If num_chunks is negative, then the "keep" parameter specifies the manner - * for handling all unknown chunks plus all chunks recognized by libpng - * except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to - * be processed by libpng. - */ -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr, - int keep, png_const_bytep chunk_list, int num_chunks)); -#endif /* HANDLE_AS_UNKNOWN */ - -/* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned; - * the result is therefore true (non-zero) if special handling is required, - * false for the default handling. - */ -PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr, - png_const_bytep chunk_name)); -#endif /* SET_UNKNOWN_CHUNKS */ - -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -PNG_EXPORT(174, void, png_set_unknown_chunks, (png_structrp png_ptr, - png_inforp info_ptr, png_const_unknown_chunkp unknowns, - int num_unknowns)); - /* NOTE: prior to 1.6.0 this routine set the 'location' field of the added - * unknowns to the location currently stored in the png_struct. This is - * invariably the wrong value on write. To fix this call the following API - * for each chunk in the list with the correct location. If you know your - * code won't be compiled on earlier versions you can rely on - * png_set_unknown_chunks(write-ptr, png_get_unknown_chunks(read-ptr)) doing - * the correct thing. - * - * API CHANGE: in 1.7.0 this API will not work on read unless - * PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED is set; it may be necessary to change - * code to check the latter SUPPORTED flag. png_set_keep_unknown_chunks - * will issue a warning if it is asked to save a chunk and there is no read - * support. - */ - -PNG_EXPORT(175, void, png_set_unknown_chunk_location, - (png_const_structrp png_ptr, png_inforp info_ptr, int chunk, int location)); - -PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structrp png_ptr, - png_inforp info_ptr, png_unknown_chunkpp entries)); -#endif - -/* Png_free_data() will turn off the "valid" flag for anything it frees. - * If you need to turn it off for a chunk that your application has freed, - * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); - */ -PNG_EXPORT(177, void, png_set_invalid, (png_const_structrp png_ptr, - png_inforp info_ptr, int mask)); - -/* The "params" pointer is currently not used and is for future expansion. */ -#ifdef PNG_READ_PNG_SUPPORTED -PNG_EXPORT(178, void, png_read_png, (png_structrp png_ptr, png_inforp info_ptr, - int transforms, png_voidp params)); -#endif -#ifdef PNG_WRITE_PNG_SUPPORTED -PNG_EXPORT(179, void, png_write_png, (png_structrp png_ptr, png_inforp info_ptr, - int transforms, png_voidp params)); -#endif - -PNG_EXPORT(180, png_const_charp, png_get_copyright, - (png_const_structrp png_ptr)); -PNG_EXPORT(181, png_const_charp, png_get_header_ver, - (png_const_structrp png_ptr)); -PNG_EXPORT(182, png_const_charp, png_get_header_version, - (png_const_structrp png_ptr)); -PNG_EXPORT(183, png_const_charp, png_get_libpng_ver, - (png_const_structrp png_ptr)); - -#ifdef PNG_MNG_FEATURES_SUPPORTED -PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structrp png_ptr, - png_uint_32 mng_features_permitted)); -#endif - -/* For use in png_set_keep_unknown, added to version 1.2.6 */ -#define PNG_HANDLE_CHUNK_AS_DEFAULT 0 -#define PNG_HANDLE_CHUNK_NEVER 1 -#define PNG_HANDLE_CHUNK_IF_SAFE 2 -#define PNG_HANDLE_CHUNK_ALWAYS 3 -#define PNG_HANDLE_CHUNK_LAST 4 - -#ifdef PNG_ERROR_NUMBERS_SUPPORTED -/* This was never implemented: */ -PNG_REMOVED(185, void, png_set_strip_error_numbers, (png_structrp png_ptr, - png_uint_32 strip_mode), PNG_EMPTY) -#endif - -/* Added in libpng-1.2.6 */ -#ifdef PNG_SET_USER_LIMITS_SUPPORTED -PNG_EXPORT(186, void, png_set_user_limits, (png_structrp png_ptr, - png_uint_32 user_width_max, png_uint_32 user_height_max)); -PNG_EXPORT(187, png_uint_32, png_get_user_width_max, - (png_const_structrp png_ptr)); -PNG_EXPORT(188, png_uint_32, png_get_user_height_max, - (png_const_structrp png_ptr)); -/* Added in libpng-1.4.0 */ -PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structrp png_ptr, - png_uint_32 user_chunk_cache_max)); -PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max, - (png_const_structrp png_ptr)); -/* Added in libpng-1.4.1 */ -PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structrp png_ptr, - png_alloc_size_t user_chunk_cache_max)); -PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max, - (png_const_structrp png_ptr)); -#endif - -#if defined(PNG_INCH_CONVERSIONS_SUPPORTED) -PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); - -PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); - -PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); - -PNG_FP_EXPORT(196, float, png_get_x_offset_inches, - (png_const_structrp png_ptr, png_const_inforp info_ptr)) -#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ -PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr)) -#endif - -PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structrp png_ptr, - png_const_inforp info_ptr)) -#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ -PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr)) -#endif - -# ifdef PNG_pHYs_SUPPORTED -PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structrp png_ptr, - png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, - int *unit_type)); -# endif /* pHYs */ -#endif /* INCH_CONVERSIONS */ - -/* Added in libpng-1.4.0 */ -#ifdef PNG_IO_STATE_SUPPORTED -PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_const_structrp png_ptr)); - -/* Removed from libpng 1.6; use png_get_io_chunk_type. */ -PNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name, (png_structrp png_ptr), - PNG_DEPRECATED) - -PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type, - (png_const_structrp png_ptr)); - -/* The flags returned by png_get_io_state() are the following: */ -# define PNG_IO_NONE 0x0000U /* no I/O at this moment */ -# define PNG_IO_READING 0x0001U /* currently reading */ -# define PNG_IO_WRITING 0x0002U /* currently writing */ -# define PNG_IO_SIGNATURE 0x0010U /* currently at the file signature */ -# define PNG_IO_CHUNK_HDR 0x0020U /* currently at the chunk header */ -# define PNG_IO_CHUNK_DATA 0x0040U /* currently at the chunk data */ -# define PNG_IO_CHUNK_CRC 0x0080U /* currently at the chunk crc */ -# define PNG_IO_MASK_OP 0x000fU /* current operation: reading/writing */ -# define PNG_IO_MASK_LOC 0x00f0U /* current location: sig/hdr/data/crc */ -#endif /* IO_STATE */ - -/* Interlace support. The following macros are always defined so that if - * libpng interlace handling is turned off the macros may be used to handle - * interlaced images within the application. - */ -#define PNG_INTERLACE_ADAM7_PASSES 7 - -/* Two macros to return the first row and first column of the original, - * full, image which appears in a given pass. 'pass' is in the range 0 - * to 6 and the result is in the range 0 to 7. - */ -#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7) -#define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7) - -/* A macro to return the offset between pixels in the output row for a pair of - * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that - * follows. Note that ROW_OFFSET is the offset from one row to the next whereas - * COL_OFFSET is from one column to the next, within a row. - */ -#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8) -#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1)) - -/* Two macros to help evaluate the number of rows or columns in each - * pass. This is expressed as a shift - effectively 3-log2 of the number or - * rows or columns in each 8x8 tile of the original image. - */ -#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3) -#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3) - -/* Hence two macros to determine the number of rows or columns in a given - * pass of an image given its height or width. In fact these macros may - * return non-zero even though the sub-image is empty, because the other - * dimension may be empty for a small image. - */ -#define PNG_PASS_ROWS(height, pass) (((height)+(((1<>PNG_PASS_ROW_SHIFT(pass)) -#define PNG_PASS_COLS(width, pass) (((width)+(((1<>PNG_PASS_COL_SHIFT(pass)) - -/* For the reader row callbacks (both progressive and sequential) it is - * necessary to find the row in the output image given a row in an interlaced - * image, so two more macros: - */ -#define PNG_ROW_FROM_PASS_ROW(y_in, pass) \ - (((y_in)<>(((7-(off))-(pass))<<2)) & 0xF) | \ - ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0)) - -#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \ - ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1) -#define PNG_COL_IN_INTERLACE_PASS(x, pass) \ - ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1) - -/* Whether the pass is in the image at all, taking into account the full image - * width and height, evaluates 'pass' lots of times, but width and height at - * most once each. - */ -#define PNG_PASS_IN_IMAGE(width, height, pass)\ - ((height) > PNG_PASS_START_ROW(pass) && (width) > PNG_PASS_START_COL(pass)) - -/* A macro to find the last pass (in the range 0 to 6) given an image width and - * height. Then two macros two find whether a given image row or column which - * is present in the pass is the last row or column in the pass. Note that - * these macros return 'true' for earlier rows or columns of the image that are - * *not* in the pass. - */ -#define PNG_LAST_PASS(width, height) ((height) > 1 ? 6 : ((width) > 1 ? 5 : 0)) -#define PNG_LAST_PASS_ROW(y, pass, height)\ - ((y) + PNG_PASS_ROW_OFFSET(pass) >= (height)) -#define PNG_LAST_PASS_COL(x, pass, width)\ - ((x) + PNG_PASS_COL_OFFSET(pass) >= (width)) - -#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED -/* With these routines we avoid an integer divide, which will be slower on - * most machines. However, it does take more operations than the corresponding - * divide method, so it may be slower on a few RISC systems. There are two - * shifts (by 8 or 16 bits) and an addition, versus a single integer divide. - * - * Note that the rounding factors are NOT supposed to be the same! 128 and - * 32768 are correct for the NODIV code; 127 and 32767 are correct for the - * standard method. - * - * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ] - */ - - /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ - -# define png_composite(composite, fg, alpha, bg) \ - { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \ - * (png_uint_16)(alpha) \ - + (png_uint_16)(bg)*(png_uint_16)(255 \ - - (png_uint_16)(alpha)) + 128); \ - (composite) = (png_byte)((temp + (temp >> 8)) >> 8); } - -# define png_composite_16(composite, fg, alpha, bg) \ - { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \ - * (png_uint_32)(alpha) \ - + (png_uint_32)(bg)*(65535 \ - - (png_uint_32)(alpha)) + 32768); \ - (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); } - -#else /* Standard method using integer division */ - -# define png_composite(composite, fg, alpha, bg) \ - (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \ - (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ - 127) / 255) - -# define png_composite_16(composite, fg, alpha, bg) \ - (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \ - (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \ - 32767) / 65535) -#endif /* READ_COMPOSITE_NODIV */ - -#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED -PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf)); -PNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf)); -PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf)); -#endif - -PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_const_structrp png_ptr, - png_const_bytep buf)); -/* No png_get_int_16 -- may be added if there's a real need for it. */ - -/* Place a 32-bit number into a buffer in PNG byte order (big-endian). */ -#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED -PNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i)); - -/* This becomes a macro in 1.7 because the old implementation was wrong; it - * failed to do the cast. ANSI C requires the cast to convert a negative number - * to the 2's complement form, so this just works: - */ -#define png_save_int_32(b, i) png_save_uint_32(b, i); -#endif /* WRITE_INT_FUNCTIONS */ - -/* Apps that used this will use the macro in 1.7. */ -PNG_REMOVED(206, void, png_save_int_32, (png_bytep buf, png_int_32 i), - PNG_DEPRECATED) - -/* Place a 16-bit number into a buffer in PNG byte order. - * The parameter is declared unsigned int, not png_uint_16, - * just to avoid potential problems on pre-ANSI C compilers. - */ -#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED -PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i)); -/* No png_save_int_16 -- may be added if there's a real need for it. */ -#endif - -#ifdef PNG_USE_READ_MACROS -/* Inline macros to do direct reads of bytes from the input buffer. - */ -# define PNG_B(ptr, offset) (((png_const_bytep)(ptr))[offset]) -# define PNG_get_uint_32(buf) \ - PNG_U32(PNG_B(buf,0), PNG_B(buf,1), PNG_B(buf,2), PNG_B(buf,3)) - - /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the - * function) incorrectly returned a value of type png_uint_32. - */ -# define PNG_get_uint_16(buf) PNG_U16(PNG_B(buf,0), PNG_B(buf,1)) - -# define PNG_get_int_32(buf) \ - PNG_S32(PNG_B(buf,0), PNG_B(buf,1), PNG_B(buf,2), PNG_B(buf,3)) - - /* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h, - * but defining a macro name prefixed with PNG_PREFIX. - */ -# ifndef PNG_PREFIX -# define png_get_uint_32(buf) PNG_get_uint_32(buf) -# define png_get_uint_16(buf) PNG_get_uint_16(buf) -# define png_get_int_32(buf) PNG_get_int_32(buf) -# endif -#else -# ifdef PNG_PREFIX - /* No macros; revert to the (redefined) function */ -# define PNG_get_uint_32 (png_get_uint_32) -# define PNG_get_uint_16 (png_get_uint_16) -# define PNG_get_int_32 (png_get_int_32) -# endif -#endif - -#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED -PNG_REMOVED(242, void, png_set_check_for_invalid_index, - (png_structrp png_ptr, int enabled_if_greater_than_0), PNG_EMPTY) -#define png_set_check_for_invalid_index(png_ptr, value)\ - (png_setting((png_ptr), PNG_SRW_CHECK_FOR_INVALID_INDEX, 0, (value))) - /* By default the check is enabled on both read and write when the number of - * entries in the palette is less than the maximum required by the bit depth - * of a palette image. - * - * Passing 1 to 'enabled' turns the check on in all cases. - * Passing -1 turns it off and the PNG may have invalid palette index values. - * Passing 0 restores the default. - * - * On read chunk (benign) error messages are only produced with the default - * setting; it is assumed that when the check is turned on explicitly the - * caller will call png_get_palette_max to check the result. - * - * The png_setting call returns 0. - */ -#endif /* CHECK_FOR_INVALID_INDEX */ -#ifdef PNG_GET_PALETTE_MAX_SUPPORTED -PNG_EXPORT(243, int, png_get_palette_max, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - /* The info_ptr is not used, it may be NULL in 1.7.0 (not in earlier - * versions). If the information is not available because - * png_set_check_for_invalid_index was not used to turn it on -1 is returned. - * Valid results can only be obtained after the complete image has been read, - * though it may be called at any time to get the result so far. - */ -#endif /* GET_PALETTE_MAX */ - -/* Memory format options; these return information about the layout of the - * transformed row using the Simplified API PNG_FORMAT_ values (see below for - * the #defines). - * - * These are only relevant if read or write transforms are supported; these - * may cause the memory format of pixel data to differ from that used in the - * PNG file itself. Nevertheless the APIs are supported regardless of whether - * transforms are applied; use these to consistently and safely determine the - * layout of the image in memory. - * - * Some of the same information can be obtained from png_info, however this - * does not record whether the byte or bit formats have been changed. - */ -PNG_EXPORT(246, unsigned int, png_memory_format, (png_structrp png_ptr)); - /* The in-memory format as a bitmask of PNG_FORMAT_FLAG_ values. All the - * flags listed below are used. If PNG_FORMAT_FLAG_INVALID is set the - * following caveats apply to the interpretation of PNG_FORMAT_FLAG_LINEAR: - * - * The gamma may differ from the sRGB (!LINEAR) or 1.0 (LINEAR). Call - * png_memory_gamma to find the correct value. - * - * The channel depth may differ from 8 (!LINEAR) or 16 (LINEAR). Call - * png_memory_channel_depth to find the correct value. - * - * It is only valid to call these APIS *after* either png_read_update_info - * or png_start_read_image on read or after the first row of an image has - * been written on write. - * - * To find the number of channels in each pixel from the returned value, - * 'fmt' use: - * - * PNG_FORMAT_CHANNELS(fmt) - */ - -PNG_EXPORT(247, unsigned int, png_memory_channel_depth, (png_structrp png_ptr)); - /* The actual depth of each channel in the image, to determine the full pixel - * depth (in bits) use: - * - * png_memory_channel_depth(pp) * PNG_FORMAT_CHANNELS(fmt) - */ - -#ifdef PNG_GAMMA_SUPPORTED -PNG_EXPORT(248, png_fixed_point, png_memory_gamma, (png_structrp png_ptr)); - /* The actual gamma of the image data, scaled by 100,000. This is the - * encoding gamma, e.g. 1/2.2 for sRGB. If the gamma is unknown this will - * return 0. - * - * On write this invariably returns 0; libpng does not change the gamma of - * the data on write. - * - * Note that this is not always the exact inverse of the 'screen gamma' - * passed to png_set_gamma; internal optimizations remove attempts to make - * small changes to the gamma value. This function returns the actual - * output value. - */ -#endif /* GAMMA */ - -/******************************************************************************* - * Section 5: SIMPLIFIED API - ******************************************************************************* - * - * Please read the documentation in libpng-manual.txt (TODO: write said - * documentation) if you don't understand what follows. - * - * The simplified API hides the details of both libpng and the PNG file format - * itself. It allows PNG files to be read into a very limited number of - * in-memory bitmap formats or to be written from the same formats. If these - * formats do not accomodate your needs then you can, and should, use the more - * sophisticated APIs above - these support a wide variety of in-memory formats - * and a wide variety of sophisticated transformations to those formats as well - * as a wide variety of APIs to manipulate ancillary information. - * - * To read a PNG file using the simplified API: - * - * 1) Declare a 'png_image' structure (see below) on the stack and set the - * version field to PNG_IMAGE_VERSION. - * 2) Call the appropriate png_image_begin_read... function. - * 3) Set the png_image 'format' member to the required sample format. - * 4) Allocate a buffer for the image and, if required, the color-map. - * 5) Call png_image_finish_read to read the image and, if required, the - * color-map into your buffers. - * - * There are no restrictions on the format of the PNG input itself; all valid - * color types, bit depths, and interlace methods are acceptable, and the - * input image is transformed as necessary to the requested in-memory format - * during the png_image_finish_read() step. The only caveat is that if you - * request a color-mapped image from a PNG that is full-color or makes - * complex use of an alpha channel the transformation is extremely lossy and the - * result may look terrible. - * - * To write a PNG file using the simplified API: - * - * 1) Declare a 'png_image' structure on the stack and memset() it to all zero. - * 2) Initialize the members of the structure that describe the image, setting - * the 'format' member to the format of the image samples. - * 3) Call the appropriate png_image_write... function with a pointer to the - * image and, if necessary, the color-map to write the PNG data. - * - * png_image is a structure that describes the in-memory format of an image - * when it is being read or defines the in-memory format of an image that you - * need to write: - */ -#define PNG_IMAGE_VERSION 1 - -typedef struct png_control *png_controlp; -typedef struct -{ - png_controlp opaque; /* Initialize to NULL, free with png_image_free */ - png_uint_32 version; /* Set to PNG_IMAGE_VERSION */ - png_uint_32 width; /* Image width in pixels (columns) */ - png_uint_32 height; /* Image height in pixels (rows) */ - png_uint_32 format; /* Image format as defined below */ - png_uint_32 flags; /* A bit mask containing informational flags */ - png_uint_32 colormap_entries; - /* Number of entries in the color-map */ - - /* In the event of an error or warning the following field will be set to a - * non-zero value and the 'message' field will contain a '\0' terminated - * string with the libpng error or warning message. If both warnings and - * an error were encountered, only the error is recorded. If there - * are multiple warnings, only the first one is recorded. - * - * The upper 30 bits of this value are reserved, the low two bits contain - * a value as follows: - */ -# define PNG_IMAGE_WARNING 1 -# define PNG_IMAGE_ERROR 2 - /* - * The result is a two-bit code such that a value more than 1 indicates - * a failure in the API just called: - * - * 0 - no warning or error - * 1 - warning - * 2 - error - * 3 - error preceded by warning - */ -# define PNG_IMAGE_FAILED(png_cntrl) ((((png_cntrl).warning_or_error)&0x03)>1) - - png_uint_32 warning_or_error; - - char message[64]; -} png_image, *png_imagep; - -/* The samples of the image have one to four channels whose components have - * original values in the range 0 to 1.0: - * - * 1: A single gray or luminance channel (G). - * 2: A gray/luminance channel and an alpha channel (GA). - * 3: Three red, green, blue color channels (RGB). - * 4: Three color channels and an alpha channel (RGBA). - * - * The components are encoded in one of two ways: - * - * a) As a small integer, value 0..255, contained in a single byte. For the - * alpha channel the original value is simply value/255. For the color or - * luminance channels the value is encoded according to the sRGB specification - * and matches the 8-bit format expected by typical display devices. - * - * The color/gray channels are not scaled (pre-multiplied) by the alpha - * channel and are suitable for passing to color management software. - * - * b) As a value in the range 0..65535, contained in a 2-byte integer. All - * channels can be converted to the original value by dividing by 65535; all - * channels are linear. Color channels use the RGB encoding (RGB end-points) of - * the sRGB specification. This encoding is identified by the - * PNG_FORMAT_FLAG_LINEAR flag below. - * - * When the simplified API needs to convert between sRGB and linear colorspaces, - * the actual sRGB transfer curve defined in the sRGB specification (see the - * article at https://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 - * approximation used elsewhere in libpng. - * - * When an alpha channel is present it is expected to denote pixel coverage - * of the color or luminance channels and is returned as an associated alpha - * channel: the color/gray channels are scaled (pre-multiplied) by the alpha - * value. - * - * The samples are either contained directly in the image data, between 1 and 8 - * bytes per pixel according to the encoding, or are held in a color-map indexed - * by bytes in the image data. In the case of a color-map the color-map entries - * are individual samples, encoded as above, and the image data has one byte per - * pixel to select the relevant sample from the color-map. - */ - -/* PNG_FORMAT_* - * - * #defines to be used in png_image::format. Each #define identifies a - * particular layout of sample data and, if present, alpha values. There are - * separate defines for each of the two component encodings. - * - * A format is built up using single bit flag values. All combinations are - * valid. Formats can be built up from the flag values or you can use one of - * the predefined values below. When testing formats always use the FORMAT_FLAG - * macros to test for individual features - future versions of the library may - * add new flags. - * - * When reading or writing color-mapped images the format should be set to the - * format of the entries in the color-map then png_image_{read,write}_colormap - * called to read or write the color-map and set the format correctly for the - * image data. Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly! - * - * NOTE: libpng can be built with particular features disabled, if you see - * compiler errors because the definition of one of the following flags has been - * compiled out it is because libpng does not have the required support. It is - * possible, however, for the libpng configuration to enable the format on just - * read or just write; in that case you may see an error at run time. You can - * guard against this by checking for the definition of the appropriate - * "_SUPPORTED" macro, one of: - * - * PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED - */ -#define PNG_FORMAT_FLAG_ALPHA 0x01U /* format with an alpha channel */ -#define PNG_FORMAT_FLAG_COLOR 0x02U /* color format: otherwise grayscale */ -#define PNG_FORMAT_FLAG_LINEAR 0x04U /* 2 byte channels else 1 byte */ -#define PNG_FORMAT_FLAG_COLORMAP 0x08U /* image data is color-mapped */ -#define PNG_FORMAT_FLAG_BGR 0x10U /* BGR colors, else order is RGB */ -#define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */ - /* other bits RESERVED */ - -/* The PNG color type value can be derived from a format which repesents a valid - * PNG format using the following macro. Note that if any of the non-PNG - * format elements are use, such as BGR or AFIRST, the color type value that - * results does represent the number of channels in the format but may not - * represent their order or encoding. - * - * NOTE: the format can encode illegal PNG formats, such as a colormap with - * alpha or without color; these are legal simplified API formats which produce - * data that cannot be represented as PNG regardless of channel order or - * encoding. - * - * The macro below is the bit shift version, a multiplicative version which only - * evaluates 'f' once is: - * - * ((((((((f) * 0x111) & 0x128) * 0x3) & 0x130) * 0x5) >> 6) & 0x7) - */ -#define PNG_COLOR_TYPE_FROM_FORMAT(f)\ - ((((f) & (!((f) & PNG_FORMAT_FLAG_AFILLER))) << 2) |\ - (((f) & PNG_FORMAT_FLAG_COLOR) ) |\ - (((f) & PNG_FORMAT_FLAG_COLORMAP) >> 3)) - -/* The inverse: note that PNG_FORMAT_FLAG_LINEAR is not set by this macro and - * that there is no handling for a 'filler' channel, consequently the macro must - * only be used on genuine PNG color types, not the result of png_get_color_type - * after transforms have been applied to the original PNG data. - */ -#define PNG_FORMAT_FROM_COLOR_TYPE(c)\ - ((((c) & PNG_COLOR_MASK_ALPHA) >> 2) |\ - (((c) & PNG_COLOR_MASK_COLOR) ) |\ - (((c) & PNG_COLOR_MASK_PALETTE) << 3)) - -/* The following flags are not used by the simplified API but may be returned - * by png_memory_format. Presence of any of these flags means that the values - * in the image (in memory) cannot be handled 'normally'. - */ -#define PNG_FORMAT_FLAG_AFILLER 0x40U /* The 'alpha' channel is a filler: - * PNG_FORMAT_FLAG_ALPHA is set however the value in the alpha channel - * is not an alpha value and (therefore) cannot be used for alpha - * computations, it is just a filler value. PNG_COLOR_TYPE_FROM_FORMAT - * will return a color type *without* PNG_COLOR_MASK_ALPHA, however - * PNG_FORMAT_CHANNELS will return the correct number, including the - * filler channel. - */ -#define PNG_FORMAT_FLAG_SWAPPED 0x80U /* bytes or bits swapped: - * When the bit depth is 16 this means that the bytes within the - * components have been swapped, when the bit depth is less than 8 - * it means the pixels within the bytes have been swapped. It should - * not be set for 8-bit compononents (it is meaningless). */ -#define PNG_FORMAT_FLAG_RANGE 0x100U /* component range not 0..bit-depth: - * Low-bit-depth grayscale components have been unpacked into bytes - * without scaling, or RGB[A] pixels have been shifted back to the - * significant-bit range from the sBIT chunk or channels (currently - * alpha or gray) have been inverted. */ -#define PNG_FORMAT_FLAG_INVALID 0x8000U /* Invalid simplified API channel depth: - * For single channel grayscale and palette indexed image data PNG - * supports bit depths of 1, 2 or 4 bits per pixel (and per channel) - * packed into bytes. The simplified API macros will not work with - * these formats (the simplified API always uses 8 or 16-bit channels). - * In the simplified API 'linear' images always have 16-bit channels - * and non-linear images are always sRGB encoded. If the INVALID flag - * is set then this may not be true; it is necessary to check the - * memory format bit-depth and gamma separately. - */ - -/* Commonly used formats have predefined macros. - * - * First the single byte (sRGB) formats: - */ -#define PNG_FORMAT_GRAY 0U -#define PNG_FORMAT_GA PNG_FORMAT_FLAG_ALPHA -#define PNG_FORMAT_AG (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST) -#define PNG_FORMAT_RGB PNG_FORMAT_FLAG_COLOR -#define PNG_FORMAT_BGR (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR) -#define PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA) -#define PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST) -#define PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA) -#define PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST) - -/* Then the linear 2-byte formats. When naming these "Y" is used to - * indicate a luminance (gray) channel. - */ -#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR -#define PNG_FORMAT_LINEAR_Y_ALPHA (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA) -#define PNG_FORMAT_LINEAR_RGB (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR) -#define PNG_FORMAT_LINEAR_RGB_ALPHA \ - (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA) - -/* With color-mapped formats the image data is one byte for each pixel, the byte - * is an index into the color-map which is formatted as above. To obtain a - * color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP - * to one of the above definitions, or you can use one of the definitions below. - */ -#define PNG_FORMAT_RGB_COLORMAP (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_COLORMAP) -#define PNG_FORMAT_BGR_COLORMAP (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_COLORMAP) -#define PNG_FORMAT_RGBA_COLORMAP (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_COLORMAP) -#define PNG_FORMAT_ARGB_COLORMAP (PNG_FORMAT_ARGB|PNG_FORMAT_FLAG_COLORMAP) -#define PNG_FORMAT_BGRA_COLORMAP (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_COLORMAP) -#define PNG_FORMAT_ABGR_COLORMAP (PNG_FORMAT_ABGR|PNG_FORMAT_FLAG_COLORMAP) - -/* PNG_IMAGE macros - * - * These are convenience macros to derive information from a png_image - * structure. The PNG_IMAGE_SAMPLE_ macros return values appropriate to the - * actual image sample values - either the entries in the color-map or the - * pixels in the image. The PNG_IMAGE_PIXEL_ macros return corresponding values - * for the pixels and will always return 1 for color-mapped formats. The - * remaining macros return information about the rows in the image and the - * complete image. - * - * NOTE: All the macros that take a png_image::format parameter are compile time - * constants if the format parameter is, itself, a constant. Therefore these - * macros can be used in array declarations and case labels where required. - * Similarly the macros are also pre-processor constants (sizeof is not used) so - * they can be used in #if tests. - * - * First the information about the samples. - */ -#define PNG_IMAGE_SAMPLE_CHANNELS(fmt)\ - (((fmt)&(PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA))+1) - /* Return the total number of channels in a given format: 1..4 */ - -#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\ - ((((fmt) & PNG_FORMAT_FLAG_LINEAR) >> 2)+1) - /* Return the size in bytes of a single component of a pixel or color-map - * entry (as appropriate) in the image: 1 or 2. - */ - -#define PNG_IMAGE_SAMPLE_SIZE(fmt)\ - (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)) - /* This is the size of the sample data for one sample. If the image is - * color-mapped it is the size of one color-map entry (and image pixels are - * one byte in size), otherwise it is the size of one image pixel. - */ - -#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\ - (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256) - /* The maximum size of the color-map required by the format expressed in a - * count of components. This can be used to compile-time allocate a - * color-map: - * - * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)]; - * - * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)]; - * - * Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the - * information from one of the png_image_begin_read_ APIs and dynamically - * allocate the required memory. - */ - -/* Corresponding information about the pixels */ -#define PNG_IMAGE_PIXEL_(test,fmt)\ - (((fmt)&PNG_FORMAT_FLAG_COLORMAP)?1:test(fmt)) - -#define PNG_IMAGE_PIXEL_CHANNELS(fmt)\ - PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_CHANNELS,fmt) - /* The number of separate channels (components) in a pixel; 1 for a - * color-mapped image. - */ - -#define PNG_FORMAT_CHANNELS(fmt) PNG_IMAGE_PIXEL_CHANNELS(fmt) - /* Synonym for the above for use with the result of png_get_memory_format. - * This exists to avoid confusion with the PNG_IMAGE_ macros which do not - * work on all possible results of png_get_memory_format. - */ - -#define PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\ - PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_COMPONENT_SIZE,fmt) - /* The size, in bytes, of each component in a pixel; 1 for a color-mapped - * image. - */ - -#define PNG_IMAGE_PIXEL_SIZE(fmt) PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_SIZE,fmt) - /* The size, in bytes, of a complete pixel; 1 for a color-mapped image. */ - -/* Information about the whole row, or whole image */ -#define PNG_IMAGE_ROW_STRIDE(image)\ - (PNG_IMAGE_PIXEL_CHANNELS((image).format) * (png_alloc_size_t)(image).width) - /* Return the total number of components in a single row of the image; this - * is the minimum 'row stride', the minimum count of components between each - * row. For a color-mapped image this is the minimum number of bytes in a - * row. - * - * WARNING: libpng 1.7: this macro now returns a png_alloc_size_t, previous - * versions returned a png_uint_32 and could overflow for images that fit in - * memory. This macro can still overflow, but if it does the row will not - * fit in memory. The simplified API functions detect this and refuse to - * handle the image. - */ - -#define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\ - (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride)) - /* Return the size, in bytes, of an image buffer given a png_image and a row - * stride - the number of components to leave space for in each row. - * - * WARNING: This is the total size of the image, for large images it will - * overflow on a 32-bit system. In libpng 1.7 (but not before) it returns a - * png_alloc_size_t which means that the result only overflows for - * ridiculously large PNG files. libpng checks and will refuse to handle - * such data (the PNG is probably invalid.) - * - * Take great care over the type of 'row_stride'; libpng assumes that the - * type is png_alloc_size_t, as returned by PNG_IMAGE_ROW_STRIDE. You can - * use any type you like but libpng only checks for overflow when the type is - * png_alloc_size_t. In particular for png_uint_32 on a 64-bit system you - * must do your own overflow checking. Cast row_stride as (png_alloc_size_t) - * to avoid this (check for overflow before the cast of course!) - */ - -#define PNG_IMAGE_SIZE(image)\ - PNG_IMAGE_BUFFER_SIZE(image, PNG_IMAGE_ROW_STRIDE(image)) - /* Return the size, in bytes, of the image in memory given just a png_image; - * the row stride is the minimum stride required for the image. - */ - -#define PNG_IMAGE_COLORMAP_SIZE(image)\ - (PNG_IMAGE_SAMPLE_SIZE((image).format) * (image).colormap_entries) - /* Return the size, in bytes, of the color-map of this image. If the image - * format is not a color-map format this will return a size sufficient for - * 256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if - * you don't want to allocate a color-map in this case. - */ - -/* PNG_IMAGE_FLAG_* - * - * Flags containing additional information about the image are held in the - * 'flags' field of png_image. - */ -#define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01 - /* This indicates the the RGB values of the in-memory bitmap do not - * correspond to the red, green and blue end-points defined by sRGB. - */ - -#define PNG_IMAGE_FLAG_FAST 0x02 - /* On write emphasise speed over compression; the resultant PNG file will be - * larger but will be produced significantly faster, particular for large - * images. Do not use this option for images which will be distributed, only - * used it when producing intermediate files that will be read back in - * repeatedly. For a typical 24-bit image the option will double the read - * speed at the cost of increasing the image size by 25%, however for many - * more compressible images the PNG file can be 10 times larger with only a - * slight speed gain. - */ - -#define PNG_IMAGE_FLAG_16BIT_sRGB 0x04 - /* On read if the image is a 16-bit per component image and there is no gAMA - * or sRGB chunk assume that the components are sRGB encoded. Notice that - * images output by the simplified API always have gamma information; setting - * this flag only affects the interpretation of 16-bit images from an - * external source. It is recommended that the application expose this flag - * to the user; the user can normally easily recognize the difference between - * linear and sRGB encoding. This flag has no effect on write - the data - * passed to the write APIs must have the correct encoding (as defined - * above.) - * - * If the flag is not set (the default) input 16-bit per component data is - * assumed to be linear. - * - * NOTE: the flag can only be set after the png_image_begin_read_ call, - * because that call initializes the 'flags' field. - */ - -#ifdef PNG_SIMPLIFIED_READ_SUPPORTED -/* READ APIs - * --------- - * - * The png_image passed to the read APIs must have been initialized by setting - * the png_controlp field 'opaque' to NULL (or, safer, memset the whole thing.) - */ -#ifdef PNG_STDIO_SUPPORTED -PNG_EXPORT(234, int, png_image_begin_read_from_file, (png_imagep image, - const char *file_name)); - /* The named file is opened for read and the image header is filled in - * from the PNG header in the file. - */ - -PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image, - FILE* file)); - /* The PNG header is read from the stdio FILE object. */ -#endif /* STDIO */ - -PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image, - png_const_voidp memory, size_t size)); - /* The PNG header is read from the given memory buffer. */ - -PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image, - png_const_colorp background, void *buffer, ptrdiff_t row_stride, - void *colormap)); - /* Finish reading the image into the supplied buffer and clean up the - * png_image structure. - * - * row_stride is the step, in byte or 2-byte units as appropriate, - * between adjacent rows. A positive stride indicates that the top-most row - * is first in the buffer - the normal top-down arrangement. A negative - * stride indicates that the bottom-most row is first in the buffer. - * - * background need only be supplied if an alpha channel must be removed from - * a png_byte format and the removal is to be done by compositing on a solid - * color; otherwise it may be NULL and any composition will be done directly - * onto the buffer. The value is an sRGB color to use for the background, - * for grayscale output the green channel is used. - * - * background must be supplied when an alpha channel must be removed from a - * single byte color-mapped output format, in other words if: - * - * 1) The original format from png_image_begin_read_from_* had - * PNG_FORMAT_FLAG_ALPHA set. - * 2) The format set by the application does not. - * 3) The format set by the application has PNG_FORMAT_FLAG_COLORMAP set and - * PNG_FORMAT_FLAG_LINEAR *not* set. - * - * For linear output removing the alpha channel is always done by compositing - * on black and background is ignored. - * - * colormap must be supplied when PNG_FORMAT_FLAG_COLORMAP is set. It must - * be at least the size (in bytes) returned by PNG_IMAGE_COLORMAP_SIZE. - * image->colormap_entries will be updated to the actual number of entries - * written to the colormap; this may be less than the original value. - */ - -PNG_EXPORT(238, void, png_image_free, (png_imagep image)); - /* Free any data allocated by libpng in image->opaque, setting the pointer to - * NULL. May be called at any time after the structure is initialized. - */ -#endif /* SIMPLIFIED_READ */ - -#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED -/* WRITE APIS - * ---------- - * For write you must initialize a png_image structure to describe the image to - * be written. To do this use memset to set the whole structure to 0 then - * initialize fields describing your image. - * - * version: must be set to PNG_IMAGE_VERSION - * opaque: must be initialized to NULL - * width: image width in pixels - * height: image height in rows - * format: the format of the data (image and color-map) you wish to write - * flags: set to 0 unless one of the defined flags applies; set - * PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images where the RGB - * values do not correspond to the colors in sRGB. - * colormap_entries: set to the number of entries in the color-map (0 to 256) - */ -#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED -PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image, - const char *file, int convert_to_8bit, const void *buffer, - ptrdiff_t row_stride, const void *colormap)); - /* Write the image to the named file. */ - -PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file, - int convert_to_8_bit, const void *buffer, ptrdiff_t row_stride, - const void *colormap)); - /* Write the image to the given (FILE*). */ -#endif /* SIMPLIFIED_WRITE_STDIO */ - -/* With all write APIs if image is in one of the linear formats with 16-bit - * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG - * gamma encoded according to the sRGB specification, otherwise a 16-bit linear - * encoded PNG file is written. - * - * With color-mapped data formats the colormap parameter point to a color-map - * with at least image->colormap_entries encoded in the specified format. If - * the format is linear the written PNG color-map will be converted to sRGB - * regardless of the convert_to_8_bit flag. - * - * With all APIs row_stride is handled as in the read APIs - it is the spacing - * from one row to the next in component sized units (1 or 2 bytes) and if - * negative indicates a bottom-up row layout in the buffer. If row_stride is - * zero, libpng will calculate it for you from the image width and number of - * channels. - * - * Note that the write API does not support interlacing, sub-8-bit pixels or - * most ancillary chunks. If you need to write text chunks (e.g. for copyright - * notices) you need to use one of the other APIs. - */ - -PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory, - png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8_bit, - const void *buffer, ptrdiff_t row_stride, const void *colormap)); - /* Write the image to the given memory buffer. The function both writes the - * whole PNG data stream to *memory and updates *memory_bytes with the count - * of bytes written. - * - * 'memory' may be NULL. In this case *memory_bytes is not read however on - * success the number of bytes which would have been written will still be - * stored in *memory_bytes. On failure *memory_bytes will contain 0. - * - * If 'memory' is not NULL it must point to memory[*memory_bytes] of - * writeable memory. - * - * If the function returns success memory[*memory_bytes] (if 'memory' is not - * NULL) contains the written PNG data. *memory_bytes will always be less - * than or equal to the original value. - * - * If the function returns false and *memory_bytes was not changed an error - * occured during write. If *memory_bytes was changed, or is not 0 if - * 'memory' was NULL, the write would have succeeded but for the memory - * buffer being too small. *memory_bytes contains the required number of - * bytes and will be bigger that the original value. - */ - -#define png_image_write_get_memory_size(image, size, convert_to_8_bit, buffer,\ - row_stride, colormap)\ - png_image_write_to_memory(&(image), 0, &(size), convert_to_8_bit, buffer,\ - row_stride, colormap) - /* Return the amount of memory in 'size' required to compress this image. - * The png_image structure 'image' must be filled in as in the above - * function and must not be changed before the actual write call, the buffer - * and all other parameters must also be identical to that in the final - * write call. The 'size' variable need not be initialized. - * - * NOTE: the macro returns true/false, if false is returned 'size' will be - * set to zero and the write failed and probably will fail if tried again. - */ - -/* You can pre-allocate the buffer by making sure it is of sufficient size - * regardless of the amount of compression achieved. The buffer size will - * always be bigger than the original image and it will never be filled. The - * following macros are provided to assist in allocating the buffer. - */ -#define PNG_IMAGE_DATA_SIZE(image) (PNG_IMAGE_SIZE(image)+(image).height) - /* The number of uncompressed bytes in the PNG byte encoding of the image; - * uncompressing the PNG IDAT data will give this number of bytes. - */ -#ifndef PNG_ZLIB_MAX_SIZE -# define PNG_ZLIB_MAX_SIZE(b) ((b)+(((b)+7U)>>3)+(((b)+63U)>>6)+11U) - /* An upper bound on the number of compressed bytes given 'b' uncompressed - * bytes. This is based on deflateBounds() in zlib; different - * implementations of zlib compression may conceivably produce more data so - * if your zlib implementation is not zlib itself redefine this macro - * appropriately. - */ -#endif - -#define PNG_IMAGE_COMPRESSED_SIZE_MAX(image)\ - PNG_ZLIB_MAX_SIZE((png_alloc_size_t)PNG_IMAGE_DATA_SIZE(image)) - /* An upper bound on the size of the data in the PNG IDAT chunks. */ - -#define PNG_IMAGE_PNG_SIZE_MAX_(image, image_size)\ - ((8U/*sig*/+25U/*IHDR*/+16U/*gAMA*/+44U/*cHRM*/+12U/*IEND*/+\ - (((image).format&PNG_FORMAT_FLAG_COLORMAP)?/*colormap: PLTE, tRNS*/\ - 12U+3U*(image).colormap_entries/*PLTE data*/+\ - (((image).format&PNG_FORMAT_FLAG_ALPHA)?\ - 12U/*tRNS*/+(image).colormap_entries:0U):0U)+\ - 12U)+(12U*((image_size)/PNG_ZBUF_SIZE))/*IDAT*/+(image_size)) - /* A helper for the following macro; if your compiler cannot handle the - * following macro use this one with the result of - * PNG_IMAGE_COMPRESSED_SIZE_MAX(image) as the second argument (most - * compilers should handle this just fine.) - */ - -#define PNG_IMAGE_PNG_SIZE_MAX(image)\ - PNG_IMAGE_PNG_SIZE_MAX_(image, PNG_IMAGE_COMPRESSED_SIZE_MAX(image)) - /* An upper bound on the total length of the PNG data stream for 'image'. - * The result is of type png_alloc_size_t, on 32-bit systems this may - * overflow even though PNG_IMAGE_DATA_SIZE does not overflow; the write will - * run out of buffer space but return a corrected size which should work. - * - * NOTE: while PNG_IMAGE_SIZE cannot overflow for an image in memory this - * macro can because of the extra bytes used in the PNG byte encoding. You - * need to avoid this macro if your image size approaches the limit of your - * system memory; typically the maximum value of size_t. Use the above - * function call instead. - */ -#endif /* SIMPLIFIED_WRITE */ -/******************************************************************************* - * END OF SIMPLIFIED API - ******************************************************************************/ - -/******************************************************************************* - * Section 6: IMPLEMENTATION OPTIONS - ******************************************************************************* - * - * Change of options used during read and/or write. - * - * A number of internal options can (but do not need to be) changed to - * fine tune the implementation. These options control such things as the - * precise settings for compression, the accuracy of arithmetic used internally - * for image processing operations (gamma transformations) and, in some cases, - * the specific implementations (hardware or software optimizations.) - * - * To avoid API proliferation there is a single general API (new in 1.7) to do - * this. When a particular option is not supported by the build in libpng an - * attempt to set it will return a failure code but will be totally ignored - * unless the PNG_SF_ERROR flag is set (see below). - */ -PNG_EXPORT(249, png_int_32, png_setting, (png_structrp png_ptr, - png_uint_32 setting, png_uint_32 parameter, png_int_32 value)); - /* Alter setting 'setting' using the values of 'parameter' and 'value'. The - * result is either one of the following failure codes or a setting/parameter - * specific result code. - * - * The failure codes match the POSIX 1003.1 values (section 2.5, - * error numbers) with a preceding PNG_. (png_uint_32)result gives a number - * in the range 0x80000001U to 0x8000000fU. - */ -# define PNG_EBADF (-0x7fffffff) /* read/write error */ - /* An attempt was made to apply a read setting to a write structure or - * vice versa. - */ -# define PNG_EINVAL (-0x7ffffffe) /* invalid argument */ - /* 'png_ptr' was NULL or 'parameter' or 'value' is invalid for the given - * setting. - */ -# define PNG_EDOM (-0x7ffffffd) /* out of range */ - /* Either 'parameter' or 'value' is out of range for the given setting - * (only returned when paramter or value are used and are numeric; for - * flag values PNG_EINVAL will be returned.) - */ -# define PNG_ENOSYS (-0x7ffffff1) /* unsupported setting/param */ - /* The setting was not recognized; typically this means that libpng was - * built without the appropriate support. - */ -# define PNG_UNSUPPORTED_SETTING PNG_ENOSYS - /* For backware compatibility with earlier libpng versions and - * 'png_set_option' return codes. - */ -# define PNG_UNSET (-0x7ffffff0) /* NOT an erro code: no previous setting */ - /* The setting was not (previously) set. Returned when there is no built - * in default for a setting. Normally this means that the default will - * depend on other settings or the PNG itself. - */ - /* Results larger (more positive) than PNG_ENOSYS are success codes (even if - * negative). The value is interpreted as follows (as defined by the - * setting): - * - * 1) A signed 31-bit number in the range -0x7fffffef to +0x7fffffff - * 2) An unsigned 31 bit number in the range 0U to 0x7fffffffU - * 3) An unsigned 32 bit bit set/flag value in the range 0U to 0xfffffffU - * but excluding values in the range 0x80000000U to 0x80000000FU - * encoded as follows: - * - * if (v <= 0x7fffffffU) - * v - * else if (v > 0x8000000FU) - * -(png_int_32)-v - * - * The result can be converted by to the original (png_uint_32) simply - * by casting it as such. - */ -# define PNG_FAILED(result) ((result) <= PNG_ENOSYS) - /* The setting did not take; this includes both errors making the setting - * (e.g. parameter or value errors) and unsupported settings. Check the - * result code itself for more information. - */ -# define PNG_OK(result) ((result) > PNG_ENOSYS) - /* The setting succeeded; the result is a return code which depends on the - * particular setting. (E.g. it might be a return code or it might be the - * previous value.) - */ - -/* SETTING VALUES (generic) - * - * These are flag values that are added to the setting definitions below to - * simplify processing inside libpng and self-document the setting behavior. - * All these values have the prefix PNG_SF_ - */ -#define PNG_SF_ERROR (0x80000000U) - /* If this is set on the 'setting' argument to png_setting and a failure code - * would otherwise be returned call png_error instead. This is a convenience - * for applications that do not want to check the result code. It is never - * set by default. The error string is cryptic. - */ -#define PNG_SF_GET (0x40000000U) - /* Do not set the setting. With most settings this just allows for the - * presence of support for the setting to be checked at run time; if the - * setting is not support PNG_ENOSYS will be returned. - * - * With some settings checking of the parameter or value may be done, but - * there is no guarantee, so always supply valid parameter and value. - * - * With some settings the current setting is returned. This is typically - * only done when the default setting is configurable and not even always - * then. If the setting does this it will document the behavior. - */ -#define PNG_SF_READ (0x20000000U) - /* The setting may be applied to a read png_struct. If this is not set and - * an attempt is made to apply the setting to a read struct - * PNG_EBADF will be returned. - */ -#define PNG_SF_WRITE (0x10000000U) - /* The setting may be applied to a write png_struct. If this is not set - * and an attempt is made to apply the setting to a write struct - * PNG_EBADF will be returned. - */ - -/*********************************** WRITE ************************************/ -/* WRITE COMPRESSION SUPPORT - * - * These settings are normally accessed using the macros that are defined above; - * the function-like macros replace the API calls present in previous versions - * of libpng. - * - * 'setting' is as follows, 'parameter' is a chunk name; png_IDAT for IDAT - * compression, png_iCCP for iCCP chunk compression png_zTXt for zTZt *and* iTXt - * text chunk compression. Other values must not be used; they will result in - * PNG_ENOSYS at present but may alter compression of new chunks in the future. - * - * The value is the new compression setting. The result is is the old - * compression setting or an error code. Compression settings are documented - * in text above describing the function-like macros. PNG_UNSET is returned - * when the setting was not previously set; in this case the default may vary - * according to the actual data (e.g. length, PNG format). - * - * 0 is valid as a parameter if PNG_SF_GET is set, in that case the current or - * last setting is returned. - */ -#define PNG_SW_COMPRESS_zlib_level (PNG_SF_WRITE + 0U) -#define PNG_SW_COMPRESS_windowBits (PNG_SF_WRITE + 1U) -#define PNG_SW_COMPRESS_memLevel (PNG_SF_WRITE + 2U) -#define PNG_SW_COMPRESS_strategy (PNG_SF_WRITE + 3U) -#define PNG_SW_COMPRESS_png_level (PNG_SF_WRITE + 4U) -#define PNG_SW_COMPRESS_method (PNG_SF_WRITE + 5U) - -/* WRITE IDAT size. - * - * The size of the IDAT chunks that are written (the last may be smaller). - */ -#define PNG_SW_IDAT_size (PNG_SF_WRITE + 6U) - -/* WRITE FILTER CONTROL - * - * These settings are used by png_set_filter and png_set_row_buffers to control - * the filters used during compression. The 'filters' setting has two arguments - * however the first is the filter method (or type) and must be 0 for PNG. - * Standards based on PNG may define additional values, as with other base file - * characteristics such as the compression type, however the result would not be - * a PNG. - */ -#define PNG_SW_COMPRESS_filters (PNG_SF_WRITE + 7U) -#define PNG_SW_COMPRESS_row_buffers (PNG_SF_WRITE + 8U) - -/* WRITE ROW FLUSH CONTROL - * - * This sets the number of rows between flush calls. '0' was used to indicate - * no flushing (before the end). The maximum number of rows in a PNG is - * actually greater than the maximum of a 31-bit integer for interlaced images, - * however this doesn't matter much; the number of rows was always declared as - * 'int', so it is still passed in the 'value' argument. - */ -#define PNG_SW_FLUSH (PNG_SF_WRITE + 9U) - -/*********************************** READ *************************************/ -/* The size of the buffer used while reading IDAT chunks and, potentially, other - * compressed chunks. - */ -#define PNG_SR_COMPRESS_buffer_size (PNG_SF_READ + 1U) - /* Read compressed data buffer size, in 'parameter'. The result is 0. */ - -#define PNG_SR_GAMMA_threshold (PNG_SF_READ + 2U) -#define png_set_gamma_threshold(png_ptr, threshold)\ - (png_setting((png_ptr), PNG_SR_GAMMA_threshold, (threshold), 0)) - /* SETTING: threshold below which gamma correction is not done, the default - * (set when the library is built) is PNG_GAMMA_THRESHOLD_FIXED, the - * 'parameter' is a png_fixed_point number, the difference from PNG_FP_1 - * above which gamma correction will be performed. - * - * The value '153' is sufficient to maintain 1% accuracy in 16-bit linear - * calculations over a 655:1 range; over the maximum range possible with the - * 16-bit linear representation. Reasonable values are: - * - * 0: always do gamma correction, even if the gamma values are - * identical. The only point to this is to avoid a bug in the - * optimized (no gamma correction) code path, or for testing. - * 2: always do gamma correction if there is any significant - * difference. Notice that '1' will result in gamma correction in - * many cases when the screen gamma is the inverse of the encoding - * gamma because of inaccuracies in the representation of gamma. - * 153: do gamma correction if it is needed to maintain the accuracy of - * 16-bit linear calculations at 1% or below. - * 216: maintain 1% accuracy over a 100:1 dynamic range in 16-bit linear - * calculations. This matches the widely accepted numbers for human - * perception of differences within an image, however that doesn't - * mean that such high accuracy is required to avoid artefacts; such - * accuracy (such a low number) is only required if versions of the - * same image with and without gamma correction are to be compared - * visually. - * 5000: this is the default from libpng 1.6 and earlier. Using this - * produces changes in image contrast that are visible when suitable - * images are compared side-by-side however they are not obvious and - * it is inconceivable that a user would notice the change unless - * the user was very familiar with the image and the viewing - * environment. - * - * Values between 216 and 5000 produce varying very small changes in image - * contrast. Values above 10,000 (10%) produce noticeable increase or - * decrease in contrast which will probably change how the image is - * perceived. There is an internal limit on the maximum value which is - * currently 65%; PNG_EDOM will be returned for higher values. - * - * The result is the value that was set. - */ -#if 0 /*NYI*/ -#define PNG_SR_GAMMA_accuracy /*NYI*/ - /* SETTING: controls the accuracy of the gamma calculations when the results - * are cached. The default is PNG_DEFAULT_GAMMA_ACCURACY. The number is 100 - * times the number of bits, 'b', used in the internal tables when the input - * is linear, permitted values are 0..1600 however '0' causes the caching to - * be skipped entirely (so gives maximum accuracy with no caching!) - * - * The accuracy in the linear domain for a value 'a' is: - * - * +/-(.5/2^a) - * - * so for the default-default of 665 this means the accuracy is +/-0.5% and - * this ensures that almost-equal input values do not differ by more than 1% - * in the output, meeting the accepted requirement for human vision. - * - * The default value has no effect on input narrower than 16 bits. For n-bit - * input the total table size is ((n-v)+1)*(2^v), where 'v' is a/gamma and - * 'gamma' is the gamma encoding of the input: - * - * n a gamma 'v' table size - * 8 6.65 .45455 14.6 256 - * 16 6.65 .45455 14.6 65536 - * 16 6.65 1.0 6.65 1280 - * 16 6 1.0 6 704 - * 16 5 1.0 5 384 - */ -#endif /*NYI*/ - -#define PNG_SR_CRC_ACTION (PNG_SF_READ + 4U) - /* 'parameter' is what to do with critical chunks, 'value' is what to do with - * ancillary ones when the CRC does not match on read. 0 is returned. See - * png_set_crc_action for more information. - */ - -/*********************************** OPTIONS **********************************/ -/* png_set_option is implemented via png_setting to provide API compatibility - * with releases prior to 1.7.0 - */ -/* HARDWARE OPTIMIZATIONS - * - * Normally hardware capabilites, such as the Intel SSE instructions, are - * detected at run time, however sometimes it may be impossible to do this in - * user mode, in which case it is necessary to discover the capabilities in an - * OS specific way. Such capabilities are listed here when libpng has support - * for them and must be turned ON by the application if present. Check - * pnglibconf.h for options appropriate to your hardware. - * - * In general 'PNG_EXTENSIONS' controls hardware optimizations; these are not - * supported parts of libpng and, if there are problems with them, bugs should - * be ported to the implementers. Depending on the configuration it may not be - * possible to disable extensions at run time. - */ -#define PNG_SRW_OPTION (PNG_SF_READ+PNG_SF_WRITE + 0U) -#ifdef PNG_SET_OPTION_SUPPORTED -PNG_REMOVED(244, int, png_set_option, (png_structrp png_ptr, int option, - int onoff), PNG_EMPTY) - -#define png_set_option(p, opt, onoff)\ - (png_setting((p), PNG_SRW_OPTION, (opt), (onoff))) - /* Pre 1.7 API; in 1.7 the result values have changed numerically but not by - * name. For backward API compatibility this setting only returns one error - * code, PNG_ENOSYS and that only for option numbers out of range, otherwise - * if the option isn't supported PNG_OPTION_UNSET (PNG_UNSET) is returned. - */ -#endif /* SET_OPTION */ -#define PNG_OPTION_UNSET PNG_UNSET /* Unset - defaults to off */ -#define PNG_OPTION_INVALID PNG_ENOSYS /* Option number out of range */ -#define PNG_OPTION_OFF 0 -#define PNG_OPTION_ON 1 - -/* Specific options: */ -#define PNG_EXTENSIONS 0 /* HARDWARE: switch extensions on or off */ -#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */ -#define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */ -#define PNG_OPTION_NEXT 6 /* Next option - numbers are even */ - -#define PNG_SRW_CHECK_FOR_INVALID_INDEX (PNG_SF_READ+PNG_SF_WRITE + 1U) - /* Turn the palette index check on or off; see - * png_set_check_for_invalid_index above. - */ - -#define PNG_SRW_ERROR_HANDLING (PNG_SF_READ+PNG_SF_WRITE + 2U) - /* Change the action on issues that can be handled. */ - -/******************************************************************************* - * END OF HARDWARE OPTIONS - ******************************************************************************/ - -/* The last ordinal number (this is the *last* one already used; the next - * one to use is one more than this.) Maintainer, remember to add an entry to - * scripts/symbols.def as well. - */ -#ifdef PNG_EXPORT_LAST_ORDINAL - PNG_EXPORT_LAST_ORDINAL(249); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* PNG_VERSION_INFO_ONLY */ -/* Do not put anything past this line */ -#endif /* PNG_H */ diff --git a/ext/libpng17/pngchunk.h b/ext/libpng17/pngchunk.h deleted file mode 100644 index 319eb5ec17..0000000000 --- a/ext/libpng17/pngchunk.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifdef _MSC_VER -#pragma warning (disable:4028) -#endif - -/* pngchunk.h - PNG chunk descriptions - * - * Last changed in libpng 1.7.0 [(PENDING RELEASE)] - * Copyright (c) 2016 Glenn Randers-Pehrson - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * If this list is changed in any way scripts/chunkhash.c must be rebuilt and - * run to regenerate the lookup functions for the tables described from this - * list. - * - * IDAT MUST be first in the list; it must have index '0'. The order of the - * remaining chunks comes from section 5.6 "Chunk ordering" in the ISO spec - * plus the ordering rules in the PNG extensions documnet. - * - * Keep PNG_CHUNK_BEGIN and PNG_CHUNK_END at the beginning and end. - */ -PNG_CHUNK_BEGIN(IDAT, 73, 68, 65, 84, within_IDAT, after_start) -PNG_CHUNK( IHDR, 73, 72, 68, 82, before_start, at_start) -PNG_CHUNK( cHRM, 99, 72, 82, 77, before_PLTE, after_start) -PNG_CHUNK( gAMA, 103, 65, 77, 65, before_PLTE, after_start) -PNG_CHUNK( iCCP, 105, 67, 67, 80, before_PLTE, after_start) -PNG_CHUNK( sBIT, 115, 66, 73, 84, before_PLTE, after_start) -PNG_CHUNK( sRGB, 115, 82, 71, 66, before_PLTE, after_start) -PNG_CHUNK( PLTE, 80, 76, 84, 69, before_PLTE, after_start) -PNG_CHUNK( bKGD, 98, 75, 71, 68, before_IDAT, after_PLTE) -PNG_CHUNK( hIST, 104, 73, 83, 84, before_IDAT, after_PLTE) -PNG_CHUNK( tRNS, 116, 82, 78, 83, before_IDAT, after_PLTE) -PNG_CHUNK( oFFs, 111, 70, 70, 115, before_IDAT, after_start) -PNG_CHUNK( pCAL, 112, 67, 65, 76, before_IDAT, after_start) -PNG_CHUNK( sCAL, 115, 67, 65, 76, before_IDAT, after_start) -PNG_CHUNK( sTER, 115, 84, 69, 82, before_IDAT, after_start) -PNG_CHUNK( pHYs, 112, 72, 89, 115, before_IDAT, after_start) -PNG_CHUNK( sPLT, 115, 80, 76, 84, before_IDAT, after_start) -PNG_CHUNK( tIME, 116, 73, 77, 69, before_end, after_start) -PNG_CHUNK( iTXt, 105, 84, 88, 116, before_end, after_start) -PNG_CHUNK( tEXt, 116, 69, 88, 116, before_end, after_start) -PNG_CHUNK( zTXt, 122, 84, 88, 116, before_end, after_start) -PNG_CHUNK( fRAc, 102, 82, 65, 99, before_end, after_start) -PNG_CHUNK( gIFg, 103, 73, 70, 103, before_end, after_start) -PNG_CHUNK( gIFt, 103, 73, 70, 116, before_end, after_start) -PNG_CHUNK( gIFx, 103, 73, 70, 120, before_end, after_start) -PNG_CHUNK( dSIG, 100, 83, 73, 71, before_end, after_start) -PNG_CHUNK_END( IEND, 73, 69, 78, 68, before_end, after_IDAT) diff --git a/ext/libpng17/pngconf.h b/ext/libpng17/pngconf.h deleted file mode 100644 index 89adb39afb..0000000000 --- a/ext/libpng17/pngconf.h +++ /dev/null @@ -1,632 +0,0 @@ - -/* pngconf.h - machine configurable file for libpng - * - * libpng version 1.7.0beta90, August 28, 2017 - * - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * Any machine specific code is near the front of this file, so if you - * are configuring libpng for a machine, you may want to read the section - * starting here down to where it starts to typedef png_color, png_text, - * and png_info. - */ - -#ifndef PNGCONF_H -#define PNGCONF_H - -#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */ - -/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C - * compiler for correct compilation. The following header files are required by - * the standard. If your compiler doesn't provide these header files, or they - * do not match the standard, you will need to provide/improve them. - */ -#include -#include - -/* Library header files. These header files are all defined by ISOC90; libpng - * expects conformant implementations, however, an ISOC90 conformant system need - * not provide these header files if the functionality cannot be implemented. - * In this case it will be necessary to disable the relevant parts of libpng in - * the build of pnglibconf.h. - * - * Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not - * include this unnecessary header file. - */ - -#ifdef PNG_STDIO_SUPPORTED - /* Required for the definition of FILE: */ -# include -#endif - -#ifdef PNG_SETJMP_SUPPORTED - /* Required for the definition of jmp_buf and the declaration of longjmp: */ -# include -#endif - -#ifdef PNG_CONVERT_tIME_SUPPORTED - /* Required for struct tm: */ -# include -#endif - -#endif /* PNG_BUILDING_SYMBOL_TABLE */ - -/* Prior to 1.6.0 it was possible to turn off 'const' in declarations using - * PNG_NO_CONST; this is no longer supported except for data declarations which - * apparently still cause problems in 2011 on some compilers. - */ -#define PNG_CONST const /* backward compatibility only */ - -/* This controls optimization of the reading of 16 and 32 bit values - * from PNG files. It can be set on a per-app-file basis - it - * just changes whether a macro is used when the function is called. - * The library builder sets the default; if read functions are not - * built into the library the macro implementation is forced on. - */ -#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED -# define PNG_USE_READ_MACROS -#endif -#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS) -# if PNG_DEFAULT_READ_MACROS -# define PNG_USE_READ_MACROS -# endif -#endif - -/* COMPILER SPECIFIC OPTIONS. - * - * These options are provided so that a variety of difficult compilers - * can be used. Some are fixed at build time (e.g. PNG_API_RULE - * below) but still have compiler specific implementations, others - * may be changed on a per-file basis when compiling against libpng. - */ - -/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect - * against legacy (pre ISOC90) compilers that did not understand function - * prototypes. It is not required for modern C compilers. - */ -#ifndef PNGARG -# define PNGARG(arglist) arglist -#endif - -/* Function calling conventions. - * ============================= - * Normally it is not necessary to specify to the compiler how to call - * a function - it just does it - however on x86 systems derived from - * Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems - * and some others) there are multiple ways to call a function and the - * default can be changed on the compiler command line. For this reason - * libpng specifies the calling convention of every exported function and - * every function called via a user supplied function pointer. This is - * done in this file by defining the following macros: - * - * PNGAPI Calling convention for exported functions. - * PNGCBAPI Calling convention for user provided (callback) functions. - * PNGCAPI Calling convention used by the ANSI-C library (required - * for longjmp callbacks and sometimes used internally to - * specify the calling convention for zlib). - * - * These macros should never be overridden. If it is necessary to - * change calling convention in a private build this can be done - * by setting PNG_API_RULE (which defaults to 0) to one of the values - * below to select the correct 'API' variants. - * - * PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout. - * This is correct in every known environment. - * PNG_API_RULE=1 Use the operating system convention for PNGAPI and - * the 'C' calling convention (from PNGCAPI) for - * callbacks (PNGCBAPI). This is no longer required - * in any known environment - if it has to be used - * please post an explanation of the problem to the - * libpng mailing list. - * - * These cases only differ if the operating system does not use the C - * calling convention, at present this just means the above cases - * (x86 DOS/Windows sytems) and, even then, this does not apply to - * Cygwin running on those systems. - * - * Note that the value must be defined in pnglibconf.h so that what - * the application uses to call the library matches the conventions - * set when building the library. - */ - -/* Symbol export - * ============= - * When building a shared library it is almost always necessary to tell - * the compiler which symbols to export. The png.h macro 'PNG_EXPORT' - * is used to mark the symbols. On some systems these symbols can be - * extracted at link time and need no special processing by the compiler, - * on other systems the symbols are flagged by the compiler and just - * the declaration requires a special tag applied (unfortunately) in a - * compiler dependent way. Some systems can do either. - * - * A small number of older systems also require a symbol from a DLL to - * be flagged to the program that calls it. This is a problem because - * we do not know in the header file included by application code that - * the symbol will come from a shared library, as opposed to a statically - * linked one. For this reason the application must tell us by setting - * the magic flag PNG_USE_DLL to turn on the special processing before - * it includes png.h. - * - * Four additional macros are used to make this happen: - * - * PNG_IMPEXP The magic (if any) to cause a symbol to be exported from - * the build or imported if PNG_USE_DLL is set - compiler - * and system specific. - * - * PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to - * 'type', compiler specific. - * - * PNG_DLL_EXPORT Set to the magic to use during a libpng build to - * make a symbol exported from the DLL. Not used in the - * public header files; see pngpriv.h for how it is used - * in the libpng build. - * - * PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come - * from a DLL - used to define PNG_IMPEXP when - * PNG_USE_DLL is set. - */ - -/* System specific discovery. - * ========================== - * This code is used at build time to find PNG_IMPEXP, the API settings - * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL - * import processing is possible. On Windows systems it also sets - * compiler-specific macros to the values required to change the calling - * conventions of the various functions. - */ -#if defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\ - defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) - /* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or - * MinGW on any architecture currently supported by Windows. Also includes - * Watcom builds but these need special treatment because they are not - * compatible with GCC or Visual C because of different calling conventions. - */ -# if PNG_API_RULE == 2 - /* If this line results in an error, either because __watcall is not - * understood or because of a redefine just below you cannot use *this* - * build of the library with the compiler you are using. *This* build was - * build using Watcom and applications must also be built using Watcom! - */ -# define PNGCAPI __watcall -# endif - -# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800)) -# define PNGCAPI __cdecl -# if PNG_API_RULE == 1 - /* If this line results in an error __stdcall is not understood and - * PNG_API_RULE should not have been set to '1'. - */ -# define PNGAPI __stdcall -# endif -# else - /* An older compiler, or one not detected (erroneously) above, - * if necessary override on the command line to get the correct - * variants for the compiler. - */ -# ifndef PNGCAPI -# define PNGCAPI _cdecl -# endif -# if PNG_API_RULE == 1 && !defined(PNGAPI) -# define PNGAPI _stdcall -# endif -# endif /* compiler/api */ - - /* NOTE: PNGCBAPI always defaults to PNGCAPI. */ - -# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD) -# error "PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed" -# endif - -# if (defined(_MSC_VER) && _MSC_VER < 800) ||\ - (defined(__BORLANDC__) && __BORLANDC__ < 0x500) - /* older Borland and MSC - * compilers used '__export' and required this to be after - * the type. - */ -# ifndef PNG_EXPORT_TYPE -# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP -# endif -# define PNG_DLL_EXPORT __export -# else /* newer compiler */ -# define PNG_DLL_EXPORT __declspec(dllexport) -# ifndef PNG_DLL_IMPORT -# define PNG_DLL_IMPORT __declspec(dllimport) -# endif -# endif /* compiler */ - -#else /* !Windows */ -# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) -# define PNGAPI _System -# else /* !Windows/x86 && !OS/2 */ - /* Use the defaults, or define PNG*API on the command line (but - * this will have to be done for every compile!) - */ -# endif /* other system, !OS/2 */ -#endif /* !Windows/x86 */ - -/* Now do all the defaulting . */ -#ifndef PNGCAPI -# define PNGCAPI -#endif -#ifndef PNGCBAPI -# define PNGCBAPI PNGCAPI -#endif -#ifndef PNGAPI -# define PNGAPI PNGCAPI -#endif - -/* PNG_IMPEXP may be set on the compilation system command line or (if not set) - * then in an internal header file when building the library, otherwise (when - * using the library) it is set here. - */ -#ifndef PNG_IMPEXP -# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT) - /* This forces use of a DLL, disallowing static linking */ -# define PNG_IMPEXP PNG_DLL_IMPORT -# endif - -# ifndef PNG_IMPEXP -# define PNG_IMPEXP -# endif -#endif - -/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat - * 'attributes' as a storage class - the attributes go at the start of the - * function definition, and attributes are always appended regardless of the - * compiler. This considerably simplifies these macros but may cause problems - * if any compilers both need function attributes and fail to handle them as - * a storage class (this is unlikely.) - */ -#ifndef PNG_FUNCTION -# define PNG_FUNCTION(type, name, args, attributes) attributes type name args -#endif - -#ifndef PNG_EXPORT_TYPE -# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type -#endif - - /* The ordinal value is only relevant when preprocessing png.h for symbol - * table entries, so we discard it here. See the .dfn files in the - * scripts directory. - */ -#ifndef PNG_EXPORTA - -# define PNG_EXPORTA(ordinal, type, name, args, attributes)\ - PNG_FUNCTION(PNG_EXPORT_TYPE(type),(PNGAPI name),PNGARG(args), \ - extern attributes) -#endif - -/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument, - * so make something non-empty to satisfy the requirement: - */ -#define PNG_EMPTY /*empty list*/ - -#define PNG_EXPORT(ordinal, type, name, args)\ - PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY) - -/* Use PNG_REMOVED to comment out a removed interface. */ -#ifndef PNG_REMOVED -# define PNG_REMOVED(ordinal, type, name, args, attributes) -#endif - -#ifndef PNG_CALLBACK -# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args) -#endif - -/* Support for compiler specific function attributes. These are used - * so that where compiler support is available incorrect use of API - * functions in png.h will generate compiler warnings. - * - * Added at libpng-1.2.41. - */ - -#ifndef PNG_NO_PEDANTIC_WARNINGS -# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED -# define PNG_PEDANTIC_WARNINGS_SUPPORTED -# endif -#endif - -#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED - /* Support for compiler specific function attributes. These are used - * so that where compiler support is available, incorrect use of API - * functions in png.h will generate compiler warnings. Added at libpng - * version 1.2.41. Disabling these removes the warnings but may also produce - * less efficient code. - */ -# if defined(__clang__) && defined(__has_attribute) - /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */ -# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__) -# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) -# endif -# if !defined(PNG_NORETURN) && __has_attribute(__noreturn__) -# define PNG_NORETURN __attribute__((__noreturn__)) -# endif -# if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__) -# define PNG_ALLOCATED __attribute__((__malloc__)) -# endif -# if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__) -# define PNG_DEPRECATED __attribute__((__deprecated__)) -# endif -# if !defined(PNG_PRIVATE) -# ifdef __has_extension -# if __has_extension(attribute_unavailable_with_message) -# define PNG_PRIVATE __attribute__((__unavailable__(\ - "This function is not exported by libpng."))) -# endif -# endif -# endif -# ifndef PNG_RESTRICT -# define PNG_RESTRICT __restrict -# endif - -# elif defined(__GNUC__) -# ifndef PNG_USE_RESULT -# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) -# endif -# ifndef PNG_NORETURN -# define PNG_NORETURN __attribute__((__noreturn__)) -# endif -# if __GNUC__ >= 3 -# ifndef PNG_ALLOCATED -# define PNG_ALLOCATED __attribute__((__malloc__)) -# endif -# ifndef PNG_DEPRECATED -# define PNG_DEPRECATED __attribute__((__deprecated__)) -# endif -# ifndef PNG_PRIVATE -# if 0 /* Doesn't work so we use deprecated instead*/ -# define PNG_PRIVATE \ - __attribute__((warning("This function is not exported by libpng."))) -# else -# define PNG_PRIVATE \ - __attribute__((__deprecated__)) -# endif -# endif -# if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1)) -# ifndef PNG_RESTRICT -# define PNG_RESTRICT __restrict -# endif -# endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */ -# endif /* __GNUC__ >= 3 */ - -# elif defined(_MSC_VER) && (_MSC_VER >= 1300) -# ifndef PNG_USE_RESULT -# define PNG_USE_RESULT /* not supported */ -# endif -# ifndef PNG_NORETURN -# define PNG_NORETURN __declspec(noreturn) -# endif -# ifndef PNG_ALLOCATED -# if (_MSC_VER >= 1400) -# define PNG_ALLOCATED __declspec(restrict) -# endif -# endif -# ifndef PNG_DEPRECATED -# define PNG_DEPRECATED __declspec(deprecated) -# endif -# ifndef PNG_PRIVATE -# define PNG_PRIVATE __declspec(deprecated) -# endif -# ifndef PNG_RESTRICT -# if (_MSC_VER >= 1400) -# define PNG_RESTRICT __restrict -# endif -# endif - -# elif defined(__WATCOMC__) -# ifndef PNG_RESTRICT -# define PNG_RESTRICT __restrict -# endif -# endif -#endif /* PNG_PEDANTIC_WARNINGS */ - -#ifndef PNG_DEPRECATED -# define PNG_DEPRECATED /* Use of this function is deprecated */ -#endif -#ifndef PNG_USE_RESULT -# define PNG_USE_RESULT /* The result of this function must be checked */ -#endif -#ifndef PNG_NORETURN -# define PNG_NORETURN /* This function does not return */ -#endif -#ifndef PNG_ALLOCATED -# define PNG_ALLOCATED /* The result of the function is new memory */ -#endif -#ifndef PNG_PRIVATE -# define PNG_PRIVATE /* This is a private libpng function */ -#endif -#ifndef PNG_RESTRICT -# define PNG_RESTRICT /* The C99 "restrict" feature */ -#endif - -#ifndef PNG_FP_EXPORT /* A floating point API. */ -# ifdef PNG_FLOATING_POINT_SUPPORTED -# define PNG_FP_EXPORT(ordinal, type, name, args)\ - PNG_EXPORT(ordinal, type, name, args); -# else /* No floating point APIs */ -# define PNG_FP_EXPORT(ordinal, type, name, args) -# endif -#endif -#ifndef PNG_FP_EXPORT /* A floating point API. */ -# ifdef PNG_FLOATING_POINT_SUPPORTED -# define PNG_FP_EXPORT(ordinal, type, name, args)\ - PNG_EXPORT(ordinal, type, name, args); -# else /* No floating point APIs */ -# define PNG_FP_EXPORT(ordinal, type, name, args) -# endif -#endif -#ifndef PNG_FIXED_EXPORT /* A fixed point API. */ -# ifdef PNG_FIXED_POINT_SUPPORTED -# define PNG_FIXED_EXPORT(ordinal, type, name, args)\ - PNG_EXPORT(ordinal, type, name, args); -# else /* No fixed point APIs */ -# define PNG_FIXED_EXPORT(ordinal, type, name, args) -# endif -#endif - -#ifndef PNG_BUILDING_SYMBOL_TABLE -/* Some typedefs to get us started. These should be safe on most of the common - * platforms. - * - * png_uint_32 and png_int_32 may, currently, be larger than required to hold a - * 32-bit value however this is not normally advisable. - * - * png_uint_16 and png_int_16 should always be two bytes in size - this is - * verified at library build time. - * - * png_byte must always be one byte in size. - * - * The checks below use constants from limits.h, as defined by the ISOC90 - * standard. - */ -#if CHAR_BIT == 8 && UCHAR_MAX == 255 - typedef unsigned char png_byte; -#else -# error "libpng requires 8 bit bytes" -#endif - -#if INT_MIN == -32768 && INT_MAX == 32767 - typedef int png_int_16; -#elif SHRT_MIN == -32768 && SHRT_MAX == 32767 - typedef short png_int_16; -#else -# error "libpng requires a signed 16 bit type" -#endif - -#if UINT_MAX == 65535 - typedef unsigned int png_uint_16; -#elif USHRT_MAX == 65535 - typedef unsigned short png_uint_16; -#else -# error "libpng requires an unsigned 16 bit type" -#endif - -#if INT_MIN < -2147483646 && INT_MAX > 2147483646 - typedef int png_int_32; -#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646 - typedef long int png_int_32; -#else -# error "libpng requires a signed 32 bit (or more) type" -#endif - -#if UINT_MAX > 4294967294 - typedef unsigned int png_uint_32; -#elif ULONG_MAX > 4294967294 - typedef unsigned long int png_uint_32; -#else -# error "libpng requires an unsigned 32 bit (or more) type" -#endif - -/* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however, - * requires an ISOC90 compiler and relies on consistent behavior of sizeof. - * - * DEPRECATED: don't use these types, instead use size_t and ptrdiff_t. - */ -typedef size_t png_size_t; -typedef ptrdiff_t png_ptrdiff_t; - -/* libpng needs to know the maximum value of 'size_t' and this controls the - * definition of png_alloc_size_t, below. This maximum value of size_t limits - * but does not control the maximum allocations the library makes - there is - * direct application control of this through png_set_user_limits(). - */ -#ifndef PNG_SMALL_SIZE_T - /* Compiler specific tests for systems where size_t is known to be less than - * 32 bits (some of these systems may no longer work because of the lack of - * 'far' support; see above.) - */ -# if (defined(__TURBOC__) && !defined(__FLAT__)) ||\ - (defined(_MSC_VER) && defined(MAXSEG_64K)) -# define PNG_SMALL_SIZE_T -# endif -#endif - -/* png_alloc_size_t is guaranteed to be no smaller than size_t, and no - * smaller than png_uint_32. Casts from size_t or png_uint_32 to - * png_alloc_size_t are not necessary; in fact, it is recommended not to use - * them at all so that the compiler can complain when something turns out to be - * problematic. - * - * Casts in the other direction (from png_alloc_size_t to size_t or - * png_uint_32) should be explicitly applied; however, we do not expect to - * encounter practical situations that require such conversions. - * - * PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than - * 4294967295 - i.e. less than the maximum value of png_uint_32. - */ -#ifdef PNG_SMALL_SIZE_T - typedef png_uint_32 png_alloc_size_t; -#else - typedef size_t png_alloc_size_t; -#endif - -/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler - * implementations of Intel CPU specific support of user-mode segmented address - * spaces, where 16-bit pointers address more than 65536 bytes of memory using - * separate 'segment' registers. The implementation requires two different - * types of pointer (only one of which includes the segment value.) - * - * If required this support is available in version 1.2 of libpng and may be - * available in versions through 1.5, although the correctness of the code has - * not been verified recently. - */ - -/* Typedef for floating-point numbers that are converted to fixed-point with a - * multiple of 100,000, e.g., gamma - */ -typedef png_int_32 png_fixed_point; - -/* Add typedefs for pointers */ -typedef void * png_voidp; -typedef const void * png_const_voidp; -typedef png_byte * png_bytep; -typedef const png_byte * png_const_bytep; -typedef png_uint_32 * png_uint_32p; -typedef const png_uint_32 * png_const_uint_32p; -typedef png_int_32 * png_int_32p; -typedef const png_int_32 * png_const_int_32p; -typedef png_uint_16 * png_uint_16p; -typedef const png_uint_16 * png_const_uint_16p; -typedef png_int_16 * png_int_16p; -typedef const png_int_16 * png_const_int_16p; -typedef char * png_charp; -typedef const char * png_const_charp; -typedef png_fixed_point * png_fixed_point_p; -typedef const png_fixed_point * png_const_fixed_point_p; -typedef size_t * png_size_tp; -typedef const size_t * png_const_size_tp; - -#ifdef PNG_STDIO_SUPPORTED -typedef FILE * png_FILE_p; -#endif - -#ifdef PNG_FLOATING_POINT_SUPPORTED -typedef double * png_doublep; -typedef const double * png_const_doublep; -#endif - -/* Pointers to pointers; i.e. arrays */ -typedef png_byte * * png_bytepp; -typedef png_uint_32 * * png_uint_32pp; -typedef png_int_32 * * png_int_32pp; -typedef png_uint_16 * * png_uint_16pp; -typedef png_int_16 * * png_int_16pp; -typedef const char * * png_const_charpp; -typedef char * * png_charpp; -typedef png_fixed_point * * png_fixed_point_pp; -#ifdef PNG_FLOATING_POINT_SUPPORTED -typedef double * * png_doublepp; -#endif - -/* Pointers to pointers to pointers; i.e., pointer to array */ -typedef char * * * png_charppp; - -#endif /* PNG_BUILDING_SYMBOL_TABLE */ - -#endif /* PNGCONF_H */ diff --git a/ext/libpng17/pngdebug.h b/ext/libpng17/pngdebug.h deleted file mode 100644 index 4bfff4de34..0000000000 --- a/ext/libpng17/pngdebug.h +++ /dev/null @@ -1,150 +0,0 @@ - -/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c - * - * Last changed in libpng 1.6.8 [December 19, 2013] - * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* Define PNG_DEBUG at compile time for debugging information. Higher - * numbers for PNG_DEBUG mean more debugging information. This has - * only been added since version 0.95 so it is not implemented throughout - * libpng yet, but more support will be added as needed. - * - * png_debug[1-2]?(level, message ,arg{0-2}) - * Expands to a statement (either a simple expression or a compound - * do..while(0) statement) that outputs a message with parameter - * substitution if PNG_DEBUG is defined to 2 or more. If PNG_DEBUG - * is undefined, 0 or 1 every png_debug expands to a simple expression - * (actually ((void)0)). - * - * level: level of detail of message, starting at 0. A level 'n' - * message is preceded by 'n' 3-space indentations (not implemented - * on Microsoft compilers unless PNG_DEBUG_FILE is also - * defined, to allow debug DLL compilation with no standard IO). - * message: a printf(3) style text string. A trailing '\n' is added - * to the message. - * arg: 0 to 2 arguments for printf(3) style substitution in message. - */ -#ifndef PNGDEBUG_H -#define PNGDEBUG_H -/* These settings control the formatting of messages in png.c and pngerror.c */ -/* Moved to pngdebug.h at 1.5.0 */ -# ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET -# define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5bU -# endif -# ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET -# define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5dU -# endif -# ifndef PNG_STRING_NEWLINE -# define PNG_STRING_NEWLINE "\n" -# endif - -#ifdef PNG_DEBUG -# if (PNG_DEBUG > 0) -# if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER) -# include -# if (PNG_DEBUG > 1) -# ifndef _DEBUG -# define _DEBUG -# endif -# ifndef png_debug -# define png_debug(l,m) _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE) -# endif -# ifndef png_debug1 -# define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1) -# endif -# ifndef png_debug2 -# define png_debug2(l,m,p1,p2) \ - _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2) -# endif -# endif -# else /* PNG_DEBUG_FILE || !_MSC_VER */ -# ifndef PNG_STDIO_SUPPORTED -# include /* not included yet */ -# endif -# ifndef PNG_DEBUG_FILE -# define PNG_DEBUG_FILE stderr -# endif /* PNG_DEBUG_FILE */ - -# if (PNG_DEBUG > 1) -# ifdef __STDC__ -# ifndef png_debug -# define png_debug(l,m) \ - do { \ - int num_tabs=l; \ - fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \ - (num_tabs==2 ? " " : (num_tabs>2 ? " " : "")))); \ - } while (0) -# endif -# ifndef png_debug1 -# define png_debug1(l,m,p1) \ - do { \ - int num_tabs=l; \ - fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \ - (num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1); \ - } while (0) -# endif -# ifndef png_debug2 -# define png_debug2(l,m,p1,p2) \ - do { \ - int num_tabs=l; \ - fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \ - (num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1,p2);\ - } while (0) -# endif -# else /* __STDC __ */ -# ifndef png_debug -# define png_debug(l,m) \ - do { \ - int num_tabs=l; \ - char format[256]; \ - snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ - m,PNG_STRING_NEWLINE); \ - fprintf(PNG_DEBUG_FILE,format); \ - } while (0) -# endif -# ifndef png_debug1 -# define png_debug1(l,m,p1) \ - do { \ - int num_tabs=l; \ - char format[256]; \ - snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ - m,PNG_STRING_NEWLINE); \ - fprintf(PNG_DEBUG_FILE,format,p1); \ - } while (0) -# endif -# ifndef png_debug2 -# define png_debug2(l,m,p1,p2) \ - do { \ - int num_tabs=l; \ - char format[256]; \ - snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ - m,PNG_STRING_NEWLINE); \ - fprintf(PNG_DEBUG_FILE,format,p1,p2); \ - } while (0) -# endif -# endif /* __STDC __ */ -# endif /* (PNG_DEBUG > 1) */ - -# endif /* _MSC_VER */ -# endif /* (PNG_DEBUG > 0) */ -#endif /* PNG_DEBUG */ -#ifndef png_debug -# define png_debug(l, m) ((void)0) -#endif -#ifndef png_debug1 -# define png_debug1(l, m, p1) ((void)0) -#endif -#ifndef png_debug2 -# define png_debug2(l, m, p1, p2) ((void)0) -#endif -#endif /* PNGDEBUG_H */ diff --git a/ext/libpng17/pngerror.c b/ext/libpng17/pngerror.c deleted file mode 100644 index 0b39ae4f1d..0000000000 --- a/ext/libpng17/pngerror.c +++ /dev/null @@ -1,1123 +0,0 @@ - -/* pngerror.c - stub functions for i/o and memory allocation - * - * Last changed in libpng 1.7.0 [(PENDING RELEASE)] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file provides a location for all error handling. Users who - * need special error handling are expected to write replacement functions - * and use png_set_error_fn() to use those functions. See the instructions - * at each function. - */ - -#include "pngpriv.h" -#define PNG_SRC_FILE PNG_SRC_FILE_pngerror - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - -static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr, - png_const_charp error_message)),PNG_NORETURN); - -#ifdef PNG_WARNINGS_SUPPORTED -static void /* PRIVATE */ -png_default_warning PNGARG((png_const_structrp png_ptr, - png_const_charp warning_message)); -#endif /* WARNINGS */ - -/* This function is called whenever there is a fatal error. This function - * should not be changed. If there is a need to handle errors differently, - * you should supply a replacement error function and use png_set_error_fn() - * to replace the error function at run-time. - */ -#ifdef PNG_ERROR_TEXT_SUPPORTED -PNG_FUNCTION(void,PNGAPI -png_error,(png_const_structrp png_ptr, png_const_charp error_message), - PNG_NORETURN) -{ - if (png_ptr != NULL && png_ptr->error_fn != NULL) - (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), - error_message); - - /* If the custom handler doesn't exist, or if it returns, - use the default handler, which will not return. */ - png_default_error(png_ptr, error_message); -} -#else -PNG_FUNCTION(void,PNGAPI -png_err,(png_const_structrp png_ptr),PNG_NORETURN) -{ - /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed - * erroneously as '\0', instead of the empty string "". This was - * apparently an error, introduced in libpng-1.2.20, and png_default_error - * will crash in this case. - */ - if (png_ptr != NULL && png_ptr->error_fn != NULL) - (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), ""); - - /* If the custom handler doesn't exist, or if it returns, - use the default handler, which will not return. */ - png_default_error(png_ptr, ""); -} -#endif /* ERROR_TEXT */ - -/* Utility to safely appends strings to a buffer. This never errors out so - * error checking is not required in the caller. - */ -size_t -png_safecat(png_charp buffer, size_t bufsize, size_t pos, - png_const_charp string) -{ - if (buffer != NULL && pos < bufsize) - { - if (string != NULL) - while (*string != '\0' && pos < bufsize-1) - buffer[pos++] = *string++; - - buffer[pos] = '\0'; - } - - return pos; -} - -#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED) -/* Utility to dump an unsigned value into a buffer, given a start pointer and - * and end pointer (which should point just *beyond* the end of the buffer!) - * Returns the pointer to the start of the formatted string. - */ -#define PNG_HAVE_FORMAT_NUMBER /* for the code below */ -png_charp -png_format_number(png_const_charp start, png_charp end, int format, - png_alloc_size_t number) -{ - int count = 0; /* number of digits output */ - int mincount = 1; /* minimum number required */ - int output = 0; /* digit output (for the fixed point format) */ - - *--end = '\0'; - - /* This is written so that the loop always runs at least once, even with - * number zero. - */ - while (end > start && (number != 0 || count < mincount)) - { - - static const char digits[] = "0123456789ABCDEF"; - - switch (format) - { - case PNG_NUMBER_FORMAT_fixed: - /* Needs five digits (the fraction) */ - mincount = 5; - if (output != 0 || number % 10 != 0) - { - *--end = digits[number % 10]; - output = 1; - } - number /= 10; - break; - - case PNG_NUMBER_FORMAT_02u: - /* Expects at least 2 digits. */ - mincount = 2; - /* FALL THROUGH */ - - case PNG_NUMBER_FORMAT_u: - *--end = digits[number % 10]; - number /= 10; - break; - - case PNG_NUMBER_FORMAT_02x: - /* This format expects at least two digits */ - mincount = 2; - /* FALL THROUGH */ - - case PNG_NUMBER_FORMAT_x: - *--end = digits[number & 0xf]; - number >>= 4; - break; - - default: /* an error */ - number = 0; - break; - } - - /* Keep track of the number of digits added */ - ++count; - - /* Float a fixed number here: */ - if ((format == PNG_NUMBER_FORMAT_fixed) && (count == 5) && (end > start)) - { - /* End of the fraction, but maybe nothing was output? In that case - * drop the decimal point. If the number is a true zero handle that - * here. - */ - if (output != 0) - *--end = '.'; - else if (number == 0) /* and !output */ - *--end = '0'; - } - } - - return end; -} -#endif - -#ifdef PNG_WARNINGS_SUPPORTED -/* This function is called whenever there is a non-fatal error. This function - * should not be changed. If there is a need to handle warnings differently, - * you should supply a replacement warning function and use - * png_set_error_fn() to replace the warning function at run-time. - */ -void PNGAPI -png_warning(png_const_structrp png_ptr, png_const_charp warning_message) -{ - int offset = 0; - if (png_ptr != NULL && png_ptr->warning_fn != NULL) - (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr), - warning_message + offset); - else - png_default_warning(png_ptr, warning_message + offset); -} - -/* These functions support 'formatted' warning messages with up to - * PNG_WARNING_PARAMETER_COUNT parameters. In the format string the parameter - * is introduced by @, where 'number' starts at 1. This follows the - * standard established by X/Open for internationalizable error messages. - */ -void -png_warning_parameter(png_warning_parameters p, int number, - png_const_charp string) -{ - if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT) - (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string); -} - -void -png_warning_parameter_unsigned(png_warning_parameters p, int number, int format, - png_alloc_size_t value) -{ - char buffer[PNG_NUMBER_BUFFER_SIZE]; - png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value)); -} - -void -png_warning_parameter_signed(png_warning_parameters p, int number, int format, - png_int_32 value) -{ - png_alloc_size_t u; - png_charp str; - char buffer[PNG_NUMBER_BUFFER_SIZE]; - - /* Avoid overflow by doing the negate in a png_alloc_size_t: */ - u = (png_alloc_size_t)value; - if (value < 0) - u = ~u + 1; - - str = PNG_FORMAT_NUMBER(buffer, format, u); - - if (value < 0 && str > buffer) - *--str = '-'; - - png_warning_parameter(p, number, str); -} - -void -png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p, - png_const_charp message) -{ - /* The internal buffer is just 192 bytes - enough for all our messages, - * overflow doesn't happen because this code checks! If someone figures - * out how to send us a message longer than 192 bytes, all that will - * happen is that the message will be truncated appropriately. - */ - size_t i = 0; /* Index in the msg[] buffer: */ - char msg[192]; - - /* Each iteration through the following loop writes at most one character - * to msg[i++] then returns here to validate that there is still space for - * the trailing '\0'. It may (in the case of a parameter) read more than - * one character from message[]; it must check for '\0' and continue to the - * test if it finds the end of string. - */ - while (i<(sizeof msg)-1 && *message != '\0') - { - /* '@' at end of string is now just printed (previously it was skipped); - * it is an error in the calling code to terminate the string with @. - */ - if (p != NULL && *message == '@' && message[1] != '\0') - { - int parameter_char = *++message; /* Consume the '@' */ - static const char valid_parameters[] = "123456789"; - int parameter = 0; - - /* Search for the parameter digit, the index in the string is the - * parameter to use. - */ - while (valid_parameters[parameter] != parameter_char && - valid_parameters[parameter] != '\0') - ++parameter; - - /* If the parameter digit is out of range it will just get printed. */ - if (parameter < PNG_WARNING_PARAMETER_COUNT) - { - /* Append this parameter */ - png_const_charp parm = p[parameter]; - png_const_charp pend = p[parameter] + (sizeof p[parameter]); - - /* No need to copy the trailing '\0' here, but there is no guarantee - * that parm[] has been initialized, so there is no guarantee of a - * trailing '\0': - */ - while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend) - msg[i++] = *parm++; - - /* Consume the parameter digit too: */ - ++message; - continue; - } - - /* else not a parameter and there is a character after the @ sign; just - * copy that. This is known not to be '\0' because of the test above. - */ - } - - /* At this point *message can't be '\0', even in the bad parameter case - * above where there is a lone '@' at the end of the message string. - */ - msg[i++] = *message++; - } - - /* i is always less than (sizeof msg), so: */ - msg[i] = '\0'; - - /* And this is the formatted message. It may be larger than - * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these - * are not (currently) formatted. - */ - png_warning(png_ptr, msg); -} -#endif /* WARNINGS */ - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED -void PNGAPI -png_benign_error(png_const_structrp png_ptr, png_const_charp error_message) -{ - switch (png_ptr->benign_error_action) - { - case PNG_ERROR: - png_chunk_error(png_ptr, error_message); - break; - - case PNG_WARN: - png_chunk_warning(png_ptr, error_message); - break; - - default: /* PNG_IGNORE */ - break; - } - -# ifndef PNG_ERROR_TEXT_SUPPORTED - PNG_UNUSED(error_message) -# endif -} - -static void -app_error(png_const_structrp png_ptr, png_const_charp error_message, - unsigned int error_action) -{ - switch (error_action) - { - case PNG_ERROR: - png_error(png_ptr, error_message); - break; - - case PNG_WARN: - png_warning(png_ptr, error_message); - break; - - default: /* PNG_IGNORE */ - break; - } - -# ifndef PNG_ERROR_TEXT_SUPPORTED - PNG_UNUSED(error_message) -# endif -} - -void /* PRIVATE */ -png_app_warning(png_const_structrp png_ptr, png_const_charp error_message) -{ - app_error(png_ptr, error_message, png_ptr->app_warning_action); -} - -void /* PRIVATE */ -png_app_error(png_const_structrp png_ptr, png_const_charp error_message) -{ - app_error(png_ptr, error_message, png_ptr->app_error_action); -} -#endif /* BENIGN_ERRORS */ - -#define PNG_MAX_ERROR_TEXT 196 /* Currently limited by profile_error in png.c */ -#if defined(PNG_WARNINGS_SUPPORTED) || \ - (defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)) -/* These utilities are used internally to build an error message that relates - * to the current chunk. The chunk name comes from png_ptr->chunk_name unless - * png_ptr->zowner is set in which case that is used in preference. This is - * used to prefix the message. The message is limited in length to 63 bytes. - * The name characters are output as hex digits wrapped in [] if the character - * is invalid. - * - * Using 'zowner' means that IDAT errors at the end of the IDAT stream are still - * reported as from the IDAT chunks. - */ -#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) -static PNG_CONST char png_digit[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F' -}; - -static void /* PRIVATE */ -png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp - error_message) -{ - png_uint_32 chunk_name = png_ptr->zowner; - int iout = 0, ishift = 24; - - if (chunk_name == 0) - chunk_name = png_ptr->chunk_name; - - while (ishift >= 0) - { - int c = (int)(chunk_name >> ishift) & 0xff; - - ishift -= 8; - if (isnonalpha(c) != 0) - { - buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET; - buffer[iout++] = png_digit[(c & 0xf0) >> 4]; - buffer[iout++] = png_digit[c & 0x0f]; - buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET; - } - - else - { - buffer[iout++] = png_check_char(png_ptr, c); - } - } - - if (error_message == NULL) - buffer[iout] = '\0'; - - else - { - int iin = 0; - - buffer[iout++] = ':'; - buffer[iout++] = ' '; - - while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0') - buffer[iout++] = error_message[iin++]; - - /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */ - buffer[iout] = '\0'; - } -} -#endif /* WARNINGS || ERROR_TEXT */ - -#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) -PNG_FUNCTION(void,PNGAPI -png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message), - PNG_NORETURN) -{ - char msg[18+PNG_MAX_ERROR_TEXT]; - if (png_ptr == NULL || png_ptr->chunk_name == 0U) - png_error(png_ptr, error_message); - - else - { - png_format_buffer(png_ptr, msg, error_message); - png_error(png_ptr, msg); - } -} -#endif /* READ && ERROR_TEXT */ - -#ifdef PNG_WARNINGS_SUPPORTED -void PNGAPI -png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message) -{ - char msg[18+PNG_MAX_ERROR_TEXT]; - if (png_ptr == NULL || png_ptr->chunk_name == 0U) - png_warning(png_ptr, warning_message); - - else - { - png_format_buffer(png_ptr, msg, warning_message); - png_warning(png_ptr, msg); - } -} -#endif /* WARNINGS */ - -#ifdef PNG_READ_SUPPORTED -#ifdef PNG_BENIGN_ERRORS_SUPPORTED -void PNGAPI -png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp - error_message) -{ - switch (png_ptr->benign_error_action) - { - case PNG_ERROR: - png_chunk_error(png_ptr, error_message); - break; - - case PNG_WARN: - png_chunk_warning(png_ptr, error_message); - break; - - default: /* PNG_IGNORE */ - break; - } - -# ifndef PNG_ERROR_TEXT_SUPPORTED - PNG_UNUSED(error_message) -# endif -} -#endif /* BENIGN_ERRORS */ -#endif /* READ */ - -void /* PRIVATE */ -(png_chunk_report)(png_const_structrp png_ptr, png_const_charp message, - int error) -{ - /* This is always supported, but for just read or just write it - * unconditionally does the right thing. - */ -# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED) - if (png_ptr->read_struct) -# endif - -# ifdef PNG_READ_SUPPORTED - { - if (error < PNG_CHUNK_ERROR) - png_chunk_warning(png_ptr, message); - - else if (error < PNG_CHUNK_FATAL) - png_chunk_benign_error(png_ptr, message); - - else - png_chunk_error(png_ptr, message); - } -# endif - -# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED) - else if (!png_ptr->read_struct) -# endif - -# ifdef PNG_WRITE_SUPPORTED - { - if (error < PNG_CHUNK_WRITE_ERROR) - png_app_warning(png_ptr, message); - - else if (error < PNG_CHUNK_FATAL) - png_app_error(png_ptr, message); - - else - png_error(png_ptr, message); - } -# endif - -# ifndef PNG_ERROR_TEXT_SUPPORTED - PNG_UNUSED(message) -# endif -} - -#ifdef PNG_ERROR_TEXT_SUPPORTED - -#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ - (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ - defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ - (defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) &&\ - defined(PNG_sCAL_SUPPORTED)) -PNG_FUNCTION(void, -png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN) -{ -# define fixed_message "fixed point overflow in " -# define fixed_message_ln ((sizeof fixed_message)-1) - int iin; - char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT]; - memcpy(msg, fixed_message, fixed_message_ln); - iin = 0; - if (name != NULL) - while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0) - { - msg[fixed_message_ln + iin] = name[iin]; - ++iin; - } - msg[fixed_message_ln + iin] = 0; - png_error(png_ptr, msg); -} -#endif -#endif - -#ifdef PNG_SETJMP_SUPPORTED -/* This API only exists if ANSI-C style error handling is used, - * otherwise it is necessary for png_default_error to be overridden. - */ -jmp_buf* PNGAPI -png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn, - size_t jmp_buf_size) -{ - /* From libpng 1.6.0 the app gets one chance to set a 'jmpbuf_size' value - * and it must not change after that. Libpng doesn't care how big the - * buffer is, just that it doesn't change. - * - * If the buffer size is no *larger* than the size of jmp_buf when libpng is - * compiled a built in jmp_buf is returned; this preserves the pre-1.6.0 - * semantics that this call will not fail. If the size is larger, however, - * the buffer is allocated and this may fail, causing the function to return - * NULL. - */ - if (png_ptr == NULL) - return NULL; - - if (png_ptr->jmp_buf_ptr == NULL) - { - png_ptr->jmp_buf_size = 0; /* not allocated */ - - if (jmp_buf_size <= (sizeof png_ptr->jmp_buf_local)) - png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; - - else - { - png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *, - png_malloc_warn(png_ptr, jmp_buf_size)); - - if (png_ptr->jmp_buf_ptr == NULL) - return NULL; /* new NULL return on OOM */ - - png_ptr->jmp_buf_size = jmp_buf_size; - } - } - - else /* Already allocated: check the size */ - { - size_t size = png_ptr->jmp_buf_size; - - if (size == 0) - { - size = (sizeof png_ptr->jmp_buf_local); - if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local) - { - /* This is an internal error in libpng: somehow we have been left - * with a stack allocated jmp_buf when the application regained - * control. It's always possible to fix this up, but for the moment - * this is an affirm because that makes it easy to detect. - */ - impossible("Libpng jmp_buf still allocated"); - /* png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; */ - } - } - - if (size != jmp_buf_size) - { - png_warning(png_ptr, "Application jmp_buf size changed"); - return NULL; /* caller will probably crash: no choice here */ - } - } - - /* Finally fill in the function, now we have a satisfactory buffer. It is - * valid to change the function on every call. - */ - png_ptr->longjmp_fn = longjmp_fn; - return png_ptr->jmp_buf_ptr; -} - -void /* PRIVATE */ -png_free_jmpbuf(png_structrp png_ptr) -{ - if (png_ptr != NULL) - { - jmp_buf *jb = png_ptr->jmp_buf_ptr; - - /* A size of 0 is used to indicate a local, stack, allocation of the - * pointer; used here and in png.c - */ - if (jb != NULL && png_ptr->jmp_buf_size > 0) - { - - /* This stuff is so that a failure to free the error control structure - * does not leave libpng in a state with no valid error handling: the - * free always succeeds, if there is an error it gets ignored. - */ - if (jb != &png_ptr->jmp_buf_local) - { - /* Make an internal, libpng, jmp_buf to return here */ - jmp_buf free_jmp_buf; - - if (!setjmp(free_jmp_buf)) - { - png_ptr->jmp_buf_ptr = &free_jmp_buf; /* come back here */ - png_ptr->jmp_buf_size = 0; /* stack allocation */ - png_ptr->longjmp_fn = longjmp; - png_free(png_ptr, jb); /* Return to setjmp on error */ - } - } - } - - /* *Always* cancel everything out: */ - png_ptr->jmp_buf_size = 0; - png_ptr->jmp_buf_ptr = NULL; - png_ptr->longjmp_fn = 0; - } -} -#endif - -/* This is the default error handling function. Note that replacements for - * this function MUST NOT RETURN, or the program will likely crash. This - * function is used by default, or if the program supplies NULL for the - * error function pointer in png_set_error_fn(). - */ -static PNG_FUNCTION(void /* PRIVATE */, -png_default_error,(png_const_structrp png_ptr, png_const_charp error_message), - PNG_NORETURN) -{ -#ifdef PNG_CONSOLE_IO_SUPPORTED - { - fprintf(stderr, "libpng error: %s", error_message ? error_message : - "undefined"); - fprintf(stderr, PNG_STRING_NEWLINE); - } -#else - PNG_UNUSED(error_message) /* Make compiler happy */ -#endif - png_longjmp(png_ptr, 1); -} - -PNG_FUNCTION(void,PNGAPI -png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN) -{ -#ifdef PNG_SETJMP_SUPPORTED - if (png_ptr != NULL && png_ptr->longjmp_fn != NULL && - png_ptr->jmp_buf_ptr != NULL) - png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val); -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(val) -#endif - - /* If control reaches this point, png_longjmp() must not return. The only - * choice is to terminate the whole process (or maybe the thread); to do - * this the ANSI-C abort() function is used unless a different method is - * implemented by overriding the default configuration setting for - * PNG_ABORT (see scripts/pnglibconf.dfa). - * - * API change: prior to 1.7.0 PNG_ABORT was invoked as a function type macro - * with no arguments 'PNG_ABORT();', in 1.7.0 this is changed to a simple - * macro that is defined in the configuration. - */ - PNG_ABORT -} - -#ifdef PNG_WARNINGS_SUPPORTED -/* This function is called when there is a warning, but the library thinks - * it can continue anyway. Replacement functions don't have to do anything - * here if you don't want them to. In the default configuration, png_ptr is - * not used, but it is passed in case it may be useful. - */ -static void /* PRIVATE */ -png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message) -{ -#ifdef PNG_CONSOLE_IO_SUPPORTED - { - fprintf(stderr, "libpng warning: %s", warning_message); - fprintf(stderr, PNG_STRING_NEWLINE); - } -#else - PNG_UNUSED(warning_message) /* Make compiler happy */ -#endif - PNG_UNUSED(png_ptr) /* Make compiler happy */ -} -#endif /* WARNINGS */ - -/* This function is called when the application wants to use another method - * of handling errors and warnings. Note that the error function MUST NOT - * return to the calling routine or serious problems will occur. The return - * method used in the default routine calls longjmp(png_ptr->jmp_buf_ptr, 1) - */ -void PNGAPI -png_set_error_fn(png_structrp png_ptr, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warning_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->error_ptr = error_ptr; - png_ptr->error_fn = error_fn; -#ifdef PNG_WARNINGS_SUPPORTED - png_ptr->warning_fn = warning_fn; -#else - PNG_UNUSED(warning_fn) -#endif -} - - -/* This function returns a pointer to the error_ptr associated with the user - * functions. The application should free any memory associated with this - * pointer before png_write_destroy and png_read_destroy are called. - */ -png_voidp PNGAPI -png_get_error_ptr(png_const_structrp png_ptr) -{ - if (png_ptr == NULL) - return NULL; - - return ((png_voidp)png_ptr->error_ptr); -} - - -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) - /* Currently the above both depend on SETJMP_SUPPORTED, however it would be - * possible to implement without setjmp support just so long as there is some - * way to handle the error return here: - */ -PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI -png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message), - PNG_NORETURN) -{ - const png_const_structrp png_ptr = png_nonconst_ptr; - png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); - - /* An error is always logged here, overwriting anything (typically a warning) - * that is already there: - */ - if (image != NULL) - { - png_safecat(image->message, (sizeof image->message), 0, error_message); - image->warning_or_error |= PNG_IMAGE_ERROR; - - /* Retrieve the jmp_buf from within the png_control, making this work for - * C++ compilation too is pretty tricky: C++ wants a pointer to the first - * element of a jmp_buf, but C doesn't tell us the type of that. - */ - if (image->opaque != NULL && image->opaque->error_buf != NULL) - longjmp(png_control_jmp_buf(image->opaque), 1); - - /* Missing longjmp buffer, the following is to help debugging: */ - { - size_t pos = png_safecat(image->message, (sizeof image->message), 0, - "bad longjmp: "); - png_safecat(image->message, (sizeof image->message), pos, - error_message); - } - } - - /* Here on an internal programming error. */ - abort(); -} - -#ifdef PNG_WARNINGS_SUPPORTED -void /* PRIVATE */ PNGCBAPI -png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message) -{ - const png_const_structrp png_ptr = png_nonconst_ptr; - png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); - - /* A warning is only logged if there is no prior warning or error. */ - if (image->warning_or_error == 0) - { - png_safecat(image->message, (sizeof image->message), 0, warning_message); - image->warning_or_error |= PNG_IMAGE_WARNING; - } -} -#endif - -int /* PRIVATE */ -png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg) -{ - volatile png_imagep image = image_in; - volatile int result; - volatile png_voidp saved_error_buf; - jmp_buf safe_jmpbuf; - - /* Safely execute function(arg) with png_error returning to this function. */ - saved_error_buf = image->opaque->error_buf; - result = setjmp(safe_jmpbuf) == 0; - - if (result != 0) - { - - image->opaque->error_buf = safe_jmpbuf; - result = function(arg); - } - - image->opaque->error_buf = saved_error_buf; - - /* And do the cleanup prior to any failure return. */ - if (result == 0) - png_image_free(image); - - return result; -} -#endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */ - -/* Affirms: minimal code in 'STABLE' builds to return control to the - * application via png_error(), more verbose code followed by PNG_ABORT for - * all other builds to ensure that internal errors are detected. - * - * The code always produces a message if it is possible, regardless of the - * setting of PNG_ERROR_TEXT_SUPPORTED, except that in stable builds - * PNG_ERROR_TEXT_SUPPORTED is honored. See pngpriv.h for the calculation of - * the two control macros PNG_RELEASE_BUILD (don't abort; stable build or rc) - * and PNG_AFFIRM_TEXT (output text.) - */ -#if PNG_AFFIRM_TEXT -# ifdef PNG_HAVE_FORMAT_NUMBER -static size_t -png_affirm_number(png_charp buffer, size_t bufsize, size_t pos, - unsigned int number, int format) -{ - char numbuf[PNG_NUMBER_BUFFER_SIZE]; - return png_safecat(buffer, bufsize, pos, - png_format_number(numbuf, numbuf + sizeof numbuf, format, number)); -} -# define affirm_number(a,b,c,d,e) png_affirm_number(a,b,c,d,e) -# else /* !HAVE_FORMAT_NUMBER */ -static size_t -png_affirm_number(png_charp buffer, size_t bufsize, size_t pos, - unsigned int number) -{ - /* binhex it; highly non-portable, assumes the ASCII character set, but - * if warnings are turned off then it is unlikely the text will get read - * anyway. This binhex variant is (48+val), where 'val' is the next 6 - * bits of the number, so it starts as '0' (for 0) and ends at 'I' for - * 63. The number is wrapped in {}, so 0 comes out as '{}' and 9 comes - * out as '{9}' and so on. - */ - char numbuf[32]; - int i = sizeof numbuf; - - numbuf[--i] = 0; - numbuf[--i] = '}'; - - do - { - if (number > 0) - numbuf[--i] = (char)/*SAFE*/((number & 63) + 48), number >>= 6; - else - { - numbuf[--i] = '{'; - break; - } - } - while (i > 0); - - return png_safecat(buffer, bufsize, pos, numbuf+i); -} -# define affirm_number(a,b,c,d,e) png_affirm_number(a,b,c,d) -#endif /* !HAVE_FORMAT_NUMBER */ - -static void -affirm_text(png_charp buffer, size_t bufsize, - param_deb(png_const_charp condition) unsigned int position) -{ - /* Format the 'position' number and output: - * - * " : affirm 'condition' failed\n" - * " libpng version - \n" - * " translated __DATE__ __TIME__" - * - * In the STABLE versions the output is the same for the last two lines - * but the first line becomes: - * - * ": affirm failed" - * - * If there is no number formatting the numbers just get replaced by - * some binhex (see the utility above). - */ - size_t pos = 0; - -# if PNG_RELEASE_BUILD /* no 'condition' parameter: minimal text */ - pos = affirm_number(buffer, bufsize, pos, position, PNG_NUMBER_FORMAT_x); - pos = png_safecat(buffer, bufsize, pos, ": affirm failed"); -# else /* !STABLE */ - /* Break down 'position' into a file name and a line number: */ - { -# define PNG_apply(f) { #f "\0", PNG_SRC_FILE_ ## f }, -# define PNG_end { "", PNG_SRC_FILE_LAST } - static struct { - char filename[28]; /* GCC checks this size */ - unsigned int base; - } fileinfo[] = { PNG_FILES }; -# undef PNG_apply -# undef PNG_end - - unsigned int i; - png_const_charp filename; - - /* Do 'nfiles' this way to avoid problems with g++ where it whines - * about (size_t) being larger than (int), even though this is a - * compile time constant: - */ -# define nfiles ((sizeof fileinfo)/(sizeof (fileinfo[0]))) - for (i=0; i < nfiles && position > fileinfo[i].base; ++i) {} - - if (i == 0 || i > nfiles) - filename = "UNKNOWN"; - else - { - filename = fileinfo[i-1].filename; - position -= fileinfo[i-1].base; - } -# undef nfiles - - pos = png_safecat(buffer, bufsize, pos, filename); - pos = png_safecat(buffer, bufsize, pos, ".c "); - pos = affirm_number(buffer, bufsize, pos, position, - PNG_NUMBER_FORMAT_u); - } - - pos = png_safecat(buffer, bufsize, pos, ": affirm '"); - pos = png_safecat(buffer, bufsize, pos, condition); - pos = png_safecat(buffer, bufsize, pos, "' failed\n"); -# endif /* !STABLE */ - - pos = png_safecat(buffer, bufsize, pos, PNG_HEADER_VERSION_STRING); - pos = png_safecat(buffer, bufsize, pos, - " translated " __DATE__ " " __TIME__); -} - -#define affirm_text(b, c, p)\ - do {\ - (affirm_text)(b, sizeof b, param_deb(c) (p));\ - } while (0) - -#endif /* AFFIRM_TEXT */ - -PNG_FUNCTION(void,png_affirm,(png_const_structrp png_ptr, - param_deb(png_const_charp condition) unsigned int position),PNG_NORETURN) -{ -# if PNG_AFFIRM_TEXT - char buffer[512]; - - affirm_text(buffer, condition, position); -# else /* !AFFIRM_TEXT */ - PNG_UNUSED(position) -# if !PNG_RELEASE_BUILD - PNG_UNUSED(condition) -# endif -# endif /* AFFIRM_TEXT */ - - /* Now in STABLE do a png_error, but in other builds output the message - * (if possible) then abort (PNG_ABORT). - */ -# if PNG_RELEASE_BUILD - png_error(png_ptr, buffer/*macro parameter used only if ERROR_TEXT*/); -# else /* !AFFIRM_ERROR */ - /* Use console IO if possible; this is because there is no guarantee that - * the app 'warning' will output anything. For certain the simplified - * API implementation just copies the message (truncated) to the image - * message buffer, which makes debugging much more difficult. - * - * Note that it is possible that neither WARNINGS nor CONSOLE_IO are - * supported; in that case no text will be output (and PNG_AFFIRM_TEXT - * will be false.) - */ -# ifdef PNG_CONSOLE_IO_SUPPORTED - fprintf(stderr, "%s\n", buffer); - PNG_UNUSED(png_ptr) -# elif defined PNG_WARNINGS_SUPPORTED - if (png_ptr != NULL && png_ptr->warning_fn != NULL) - png_ptr->warning_fn(png_constcast(png_structrp, png_ptr), buffer); - /* else no way to output the text */ -# else - PNG_UNUSED(png_ptr) -# endif - - PNG_ABORT -# endif /* AFFIRM_ERROR */ -} - -#if !PNG_RELEASE_BUILD -void /* PRIVATE */ -png_handled_affirm(png_const_structrp png_ptr, png_const_charp message, - unsigned int position) -{ -# if PNG_RELEASE_BUILD - /* testing in RC: we want to return control to the caller, so do not - * use png_affirm. - */ - char buffer[512]; - - affirm_text(buffer, message, position); - -# ifdef PNG_CONSOLE_IO_SUPPORTED - fprintf(stderr, "%s\n", buffer); -# elif defined PNG_WARNINGS_SUPPORTED - if (png_ptr != NULL && png_ptr->warning_fn != NULL) - png_ptr->warning_fn(png_constcast(png_structrp, png_ptr), buffer); - /* else no way to output the text */ -# else - PNG_UNUSED(png_ptr) -# endif -# else - png_affirm(png_ptr, message, position); -# endif -} -#endif /* !RELEASE_BUILD */ - -#ifdef PNG_RANGE_CHECK_SUPPORTED -/* The character/byte checking APIs. These do their own calls to png_affirm - * because the caller provides the position. - */ -unsigned int /* PRIVATE */ -png_bit_affirm(png_const_structrp png_ptr, unsigned int position, - unsigned int u, unsigned int bits) -{ - /* The following avoids overflow errors even if 'bits' is 16 or 32: */ - if (u <= (1U << bits)-1U) - return u; - - png_affirm(png_ptr, param_deb("(bit field) range") position); -} - -char /* PRIVATE */ -png_char_affirm(png_const_structrp png_ptr, unsigned int position, int c) -{ - if (c >= CHAR_MIN && c <= CHAR_MAX) - return (char)/*SAFE*/c; - - png_affirm(png_ptr, param_deb("(char) range") position); -} - -png_byte /* PRIVATE */ -png_byte_affirm(png_const_structrp png_ptr, unsigned int position, int b) -{ - /* For the type png_byte the limits.h values are ignored and we check - * against the values PNG expects to store in a byte: - */ - if (b >= 0 && b <= 255) - return (png_byte)/*SAFE*/b; - - png_affirm(png_ptr, param_deb("PNG byte range") position); -} - -#if INT_MAX >= 65535 -png_uint_16 /* PRIVATE */ -png_u16_affirm(png_const_structrp png_ptr, unsigned int position, int b) -{ - /* Check against the PNG 16-bit limit, as with png_byte. */ - if (b >= 0 && b <= 65535) - return (png_uint_16)/*SAFE*/b; - - png_affirm(png_ptr, param_deb("PNG 16-bit range") position); -} -#endif /* INT_MAX >= 65535 */ -#endif /* RANGE_CHECK */ -#endif /* READ || WRITE */ diff --git a/ext/libpng17/pngget.c b/ext/libpng17/pngget.c deleted file mode 100644 index 52f6fbf6c7..0000000000 --- a/ext/libpng17/pngget.c +++ /dev/null @@ -1,1206 +0,0 @@ - -/* pngget.c - retrieval of values from info struct - * - * Last changed in libpng 1.7.0 [(PENDING RELEASE)] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - */ - -#include "pngpriv.h" -#define PNG_SRC_FILE PNG_SRC_FILE_pngget - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - -png_uint_32 PNGAPI -png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_uint_32 flag) -{ - if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->valid & flag); - - return(0); -} - -png_alloc_size_t PNGAPI -png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return png_calc_rowbytes(png_ptr, - PNG_FORMAT_CHANNELS(info_ptr->format) * info_ptr->bit_depth, - info_ptr->width); - - return 0; -} - -#ifdef PNG_READ_PNG_SUPPORTED -png_bytepp PNGAPI -png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->row_pointers); - - return(0); -} -#endif - -#ifdef PNG_EASY_ACCESS_SUPPORTED -/* Easy access to info, added in libpng-0.99 */ -png_uint_32 PNGAPI -png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->width; - - return (0); -} - -png_uint_32 PNGAPI -png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->height; - - return (0); -} - -png_byte PNGAPI -png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->bit_depth; - - return (0); -} - -png_byte PNGAPI -png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return png_check_byte(png_ptr, - PNG_COLOR_TYPE_FROM_FORMAT(info_ptr->format)); - - return (0); -} - -png_byte PNGAPI -png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->filter_type; - - return (0); -} - -png_byte PNGAPI -png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->interlace_type; - - return (0); -} - -png_byte PNGAPI -png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->compression_type; - - return (0); -} - -png_uint_32 PNGAPI -png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp - info_ptr) -{ -#ifdef PNG_pHYs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_debug1(1, "in %s retrieval function", - "png_get_x_pixels_per_meter"); - - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) - return (info_ptr->x_pixels_per_unit); - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return (0); -} - -png_uint_32 PNGAPI -png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp - info_ptr) -{ -#ifdef PNG_pHYs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_debug1(1, "in %s retrieval function", - "png_get_y_pixels_per_meter"); - - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) - return (info_ptr->y_pixels_per_unit); - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return (0); -} - -png_uint_32 PNGAPI -png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ -#ifdef PNG_pHYs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter"); - - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER && - info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit) - return (info_ptr->x_pixels_per_unit); - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return (0); -} - -#ifdef PNG_FLOATING_POINT_SUPPORTED -float PNGAPI -png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp - info_ptr) -{ -#ifdef PNG_READ_pHYs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio"); - - if (info_ptr->x_pixels_per_unit != 0) - return ((float)((float)info_ptr->y_pixels_per_unit - /(float)info_ptr->x_pixels_per_unit)); - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return ((float)0.0); -} -#endif - -#ifdef PNG_FIXED_POINT_SUPPORTED -png_fixed_point PNGAPI -png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr, - png_const_inforp info_ptr) -{ -#ifdef PNG_READ_pHYs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0 && - info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 && - info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX && - info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX) - { - png_fixed_point res; - - png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed"); - - /* The following casts work because a PNG 4 byte integer only has a valid - * range of 0..2^31-1; otherwise the cast might overflow. - */ - if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1, - (png_int_32)info_ptr->x_pixels_per_unit) != 0) - return res; - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return 0; -} -#endif - -png_int_32 PNGAPI -png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ -#ifdef PNG_oFFs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns"); - - if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) - return (info_ptr->x_offset); - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return (0); -} - -png_int_32 PNGAPI -png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ -#ifdef PNG_oFFs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns"); - - if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) - return (info_ptr->y_offset); - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return (0); -} - -png_int_32 PNGAPI -png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ -#ifdef PNG_oFFs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels"); - - if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) - return (info_ptr->x_offset); - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return (0); -} - -png_int_32 PNGAPI -png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ -#ifdef PNG_oFFs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels"); - - if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) - return (info_ptr->y_offset); - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return (0); -} - -#ifdef PNG_INCH_CONVERSIONS_SUPPORTED -static png_uint_32 -ppi_from_ppm(png_uint_32 ppm) -{ -#if 0 /*NOT USED*/ - /* The conversion is *(2.54/100), in binary (32 digits): - * .00000110100000001001110101001001 - */ - png_uint_32 t1001, t1101; - ppm >>= 1; /* .1 */ - t1001 = ppm + (ppm >> 3); /* .1001 */ - t1101 = t1001 + (ppm >> 1); /* .1101 */ - ppm >>= 20; /* .000000000000000000001 */ - t1101 += t1101 >> 15; /* .1101000000000001101 */ - t1001 >>= 11; /* .000000000001001 */ - t1001 += t1001 >> 12; /* .000000000001001000000001001 */ - ppm += t1001; /* .000000000001001000001001001 */ - ppm += t1101; /* .110100000001001110101001001 */ - return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */ -#else - /* The argument is a PNG unsigned integer, so it is not permitted - * to be bigger than 2^31. - */ - png_fixed_point result; - if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127, - 5000) != 0) - return result; - - /* Overflow. */ - return 0; -#endif -} - -png_uint_32 PNGAPI -png_get_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr)); -} - -png_uint_32 PNGAPI -png_get_x_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr)); -} - -png_uint_32 PNGAPI -png_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr)); -} - -#ifdef PNG_FIXED_POINT_SUPPORTED -static png_fixed_point -png_fixed_inches_from_microns(png_const_structrp png_ptr, - png_int_32 microns) -{ - /* Convert from metres * 1,000,000 to inches * 100,000, meters to - * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127. - * Notice that this can overflow - a warning is output and 0 is - * returned. - */ - png_fixed_point result; - - if (png_muldiv(&result, microns, 500, 127) != 0) - return result; - - /* TODO: review this, png_error might be better. */ - png_warning(png_ptr, "inch to microns overflow"); - return 0; -# ifndef PNG_WARNINGS_SUPPORTED - PNG_UNUSED(png_ptr) -# endif -} - -png_fixed_point PNGAPI -png_get_x_offset_inches_fixed(png_const_structrp png_ptr, - png_const_inforp info_ptr) -{ - return png_fixed_inches_from_microns(png_ptr, - png_get_x_offset_microns(png_ptr, info_ptr)); -} - -png_fixed_point PNGAPI -png_get_y_offset_inches_fixed(png_const_structrp png_ptr, - png_const_inforp info_ptr) -{ - return png_fixed_inches_from_microns(png_ptr, - png_get_y_offset_microns(png_ptr, info_ptr)); -} -#endif /* FIXED_POINT */ - -#ifdef PNG_FLOATING_POINT_SUPPORTED -float PNGAPI -png_get_x_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - /* To avoid the overflow do the conversion directly in floating - * point. - */ - return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937); -} -#endif - -#ifdef PNG_FLOATING_POINT_SUPPORTED -float PNGAPI -png_get_y_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - /* To avoid the overflow do the conversion directly in floating - * point. - */ - return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937); -} -#endif - -#ifdef PNG_pHYs_SUPPORTED -png_uint_32 PNGAPI -png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) -{ - png_uint_32 retval = 0; - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_debug1(1, "in %s retrieval function", "pHYs"); - - if (res_x != NULL) - { - *res_x = info_ptr->x_pixels_per_unit; - retval |= PNG_INFO_pHYs; - } - - if (res_y != NULL) - { - *res_y = info_ptr->y_pixels_per_unit; - retval |= PNG_INFO_pHYs; - } - - if (unit_type != NULL) - { - *unit_type = (int)info_ptr->phys_unit_type; - retval |= PNG_INFO_pHYs; - - if (*unit_type == 1) - { - if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50); - if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50); - } - } - } - - return (retval); -} -#endif /* pHYs */ -#endif /* INCH_CONVERSIONS */ - -/* png_get_channels really belongs in here, too, but it's been around longer */ - -#endif /* EASY_ACCESS */ - - -png_byte PNGAPI -png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return png_check_byte(png_ptr, PNG_FORMAT_CHANNELS(info_ptr->format)); - - return (0); -} - -#ifdef PNG_READ_SUPPORTED -png_const_bytep PNGAPI -png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->signature); - - return (NULL); -} -#endif - -#ifdef PNG_bKGD_SUPPORTED -png_uint_32 PNGAPI -png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, - png_color_16p *background) -{ - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_bKGD) != 0 && - background != NULL) - { - png_debug1(1, "in %s retrieval function", "bKGD"); - - *background = &(info_ptr->background); - return (PNG_INFO_bKGD); - } - - return (0); -} -#endif - -#ifdef PNG_cHRM_SUPPORTED -/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the - * same time to correct the rgb grayscale coefficient defaults obtained from the - * cHRM chunk in 1.5.4 - */ -# ifdef PNG_FLOATING_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, - double *white_x, double *white_y, double *red_x, double *red_y, - double *green_x, double *green_y, double *blue_x, double *blue_y) -{ - /* Quiet API change: this code used to only return the end points if a cHRM - * chunk was present, but the end points can also come from iCCP or sRGB - * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and - * the png_set_ APIs merely check that set end points are mutually - * consistent. - */ - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - png_debug1(1, "in %s retrieval function", "cHRM"); - - if (white_x != NULL) - *white_x = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.whitex, "cHRM white X"); - if (white_y != NULL) - *white_y = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y"); - if (red_x != NULL) - *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx, - "cHRM red X"); - if (red_y != NULL) - *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy, - "cHRM red Y"); - if (green_x != NULL) - *green_x = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.greenx, "cHRM green X"); - if (green_y != NULL) - *green_y = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y"); - if (blue_x != NULL) - *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex, - "cHRM blue X"); - if (blue_y != NULL) - *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey, - "cHRM blue Y"); - return (PNG_INFO_cHRM); - } - - return (0); -} - -png_uint_32 PNGAPI -png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr, - double *red_X, double *red_Y, double *red_Z, double *green_X, - double *green_Y, double *green_Z, double *blue_X, double *blue_Y, - double *blue_Z) -{ - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)"); - - if (red_X != NULL) - *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X, - "cHRM red X"); - if (red_Y != NULL) - *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y, - "cHRM red Y"); - if (red_Z != NULL) - *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z, - "cHRM red Z"); - if (green_X != NULL) - *green_X = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X"); - if (green_Y != NULL) - *green_Y = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y"); - if (green_Z != NULL) - *green_Z = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z"); - if (blue_X != NULL) - *blue_X = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X"); - if (blue_Y != NULL) - *blue_Y = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y"); - if (blue_Z != NULL) - *blue_Z = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z"); - return (PNG_INFO_cHRM); - } - - return (0); -} -# endif - -# ifdef PNG_FIXED_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *int_red_X, png_fixed_point *int_red_Y, - png_fixed_point *int_red_Z, png_fixed_point *int_green_X, - png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, - png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, - png_fixed_point *int_blue_Z) -{ - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - png_debug1(1, "in %s retrieval function", "cHRM_XYZ"); - - if (int_red_X != NULL) - *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X; - if (int_red_Y != NULL) - *int_red_Y = info_ptr->colorspace.end_points_XYZ.red_Y; - if (int_red_Z != NULL) - *int_red_Z = info_ptr->colorspace.end_points_XYZ.red_Z; - if (int_green_X != NULL) - *int_green_X = info_ptr->colorspace.end_points_XYZ.green_X; - if (int_green_Y != NULL) - *int_green_Y = info_ptr->colorspace.end_points_XYZ.green_Y; - if (int_green_Z != NULL) - *int_green_Z = info_ptr->colorspace.end_points_XYZ.green_Z; - if (int_blue_X != NULL) - *int_blue_X = info_ptr->colorspace.end_points_XYZ.blue_X; - if (int_blue_Y != NULL) - *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y; - if (int_blue_Z != NULL) - *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z; - return (PNG_INFO_cHRM); - } - - return (0); -} - -png_uint_32 PNGAPI -png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x, - png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y, - png_fixed_point *blue_x, png_fixed_point *blue_y) -{ - png_debug1(1, "in %s retrieval function", "cHRM"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - if (white_x != NULL) - *white_x = info_ptr->colorspace.end_points_xy.whitex; - if (white_y != NULL) - *white_y = info_ptr->colorspace.end_points_xy.whitey; - if (red_x != NULL) - *red_x = info_ptr->colorspace.end_points_xy.redx; - if (red_y != NULL) - *red_y = info_ptr->colorspace.end_points_xy.redy; - if (green_x != NULL) - *green_x = info_ptr->colorspace.end_points_xy.greenx; - if (green_y != NULL) - *green_y = info_ptr->colorspace.end_points_xy.greeny; - if (blue_x != NULL) - *blue_x = info_ptr->colorspace.end_points_xy.bluex; - if (blue_y != NULL) - *blue_y = info_ptr->colorspace.end_points_xy.bluey; - return (PNG_INFO_cHRM); - } - - return (0); -} -# endif -#endif - -#ifdef PNG_gAMA_SUPPORTED -# ifdef PNG_FIXED_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *file_gamma) -{ - png_debug1(1, "in %s retrieval function", "gAMA"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && - file_gamma != NULL) - { - *file_gamma = info_ptr->colorspace.gamma; - return (PNG_INFO_gAMA); - } - - return (0); -} -# endif - -# ifdef PNG_FLOATING_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr, - double *file_gamma) -{ - png_debug1(1, "in %s retrieval function", "gAMA(float)"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && - file_gamma != NULL) - { - *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma, - "png_get_gAMA"); - return (PNG_INFO_gAMA); - } - - return (0); -} -# endif -#endif - -#ifdef PNG_sRGB_SUPPORTED -png_uint_32 PNGAPI -png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr, - int *file_srgb_intent) -{ - png_debug1(1, "in %s retrieval function", "sRGB"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sRGB) != 0 && file_srgb_intent != NULL) - { - *file_srgb_intent = info_ptr->colorspace.rendering_intent; - return (PNG_INFO_sRGB); - } - - return (0); -} -#endif - -#ifdef PNG_iCCP_SUPPORTED -png_uint_32 PNGAPI -png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, - png_charpp name, int *compression_type, - png_bytepp profile, png_uint_32 *proflen) -{ - png_debug1(1, "in %s retrieval function", "iCCP"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_iCCP) != 0 && - name != NULL && compression_type != NULL && profile != NULL && - proflen != NULL) - { - *name = info_ptr->iccp_name; - *profile = info_ptr->iccp_profile; - *proflen = png_get_uint_32(info_ptr->iccp_profile); - /* This is somewhat irrelevant since the profile data returned has - * actually been uncompressed. - */ - *compression_type = PNG_COMPRESSION_TYPE_BASE; - return (PNG_INFO_iCCP); - } - - return (0); -} -#endif - -#ifdef PNG_sPLT_SUPPORTED -int PNGAPI -png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr, - png_sPLT_tpp spalettes) -{ - if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL) - { - *spalettes = info_ptr->splt_palettes; - return info_ptr->splt_palettes_num; - } - - return (0); -} -#endif - -#ifdef PNG_hIST_SUPPORTED -png_uint_32 PNGAPI -png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr, - png_uint_16p *hist) -{ - png_debug1(1, "in %s retrieval function", "hIST"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL) - { - *hist = info_ptr->hist; - return (PNG_INFO_hIST); - } - - return (0); -} -#endif - -png_uint_32 PNGAPI -png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_uint_32 *width, png_uint_32 *height, int *bit_depth, - int *color_type, int *interlace_type, int *compression_type, - int *filter_type) -{ - png_debug1(1, "in %s retrieval function", "IHDR"); - - if (png_ptr == NULL || info_ptr == NULL) - return (0); - - if (width != NULL) - *width = info_ptr->width; - - if (height != NULL) - *height = info_ptr->height; - - if (bit_depth != NULL) - *bit_depth = info_ptr->bit_depth; - - if (color_type != NULL) - *color_type = PNG_COLOR_TYPE_FROM_FORMAT(info_ptr->format); - - if (compression_type != NULL) - *compression_type = info_ptr->compression_type; - - if (filter_type != NULL) - *filter_type = info_ptr->filter_type; - - if (interlace_type != NULL) - *interlace_type = info_ptr->interlace_type; - - return 1; -} - -#ifdef PNG_oFFs_SUPPORTED -png_uint_32 PNGAPI -png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type) -{ - png_debug1(1, "in %s retrieval function", "oFFs"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_oFFs) != 0 && - offset_x != NULL && offset_y != NULL && unit_type != NULL) - { - *offset_x = info_ptr->x_offset; - *offset_y = info_ptr->y_offset; - *unit_type = (int)info_ptr->offset_unit_type; - return (PNG_INFO_oFFs); - } - - return (0); -} -#endif - -#ifdef PNG_pCAL_SUPPORTED -png_uint_32 PNGAPI -png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, - png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams, - png_charp *units, png_charpp *params) -{ - png_debug1(1, "in %s retrieval function", "pCAL"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pCAL) != 0 && - purpose != NULL && X0 != NULL && X1 != NULL && type != NULL && - nparams != NULL && units != NULL && params != NULL) - { - *purpose = info_ptr->pcal_purpose; - *X0 = info_ptr->pcal_X0; - *X1 = info_ptr->pcal_X1; - *type = (int)info_ptr->pcal_type; - *nparams = (int)info_ptr->pcal_nparams; - *units = info_ptr->pcal_units; - *params = info_ptr->pcal_params; - return (PNG_INFO_pCAL); - } - - return (0); -} -#endif - -#ifdef PNG_sCAL_SUPPORTED -# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED -# ifdef PNG_FIXED_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, - int *unit, png_fixed_point *width, png_fixed_point *height) -{ - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sCAL) != 0) - { - *unit = info_ptr->scal_unit; - /*TODO: make this work without FP support; the API is currently eliminated - * if neither floating point APIs nor internal floating point arithmetic - * are enabled. - */ - *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width"); - *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height), - "sCAL height"); - return (PNG_INFO_sCAL); - } - - return(0); -} -# endif /* FIXED_POINT */ - -# ifdef PNG_FLOATING_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr, - int *unit, double *width, double *height) -{ - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sCAL) != 0) - { - *unit = info_ptr->scal_unit; - *width = atof(info_ptr->scal_s_width); - *height = atof(info_ptr->scal_s_height); - return (PNG_INFO_sCAL); - } - - return(0); -} -# endif /* FLOATING POINT */ -# endif /* FLOATING_ARITHMETIC */ - -png_uint_32 PNGAPI -png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr, - int *unit, png_charpp width, png_charpp height) -{ - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sCAL) != 0) - { - *unit = info_ptr->scal_unit; - *width = info_ptr->scal_s_width; - *height = info_ptr->scal_s_height; - return (PNG_INFO_sCAL); - } - - return(0); -} -#endif /* sCAL */ - -#ifdef PNG_pHYs_SUPPORTED -png_uint_32 PNGAPI -png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) -{ - png_uint_32 retval = 0; - - png_debug1(1, "in %s retrieval function", "pHYs"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - if (res_x != NULL) - { - *res_x = info_ptr->x_pixels_per_unit; - retval |= PNG_INFO_pHYs; - } - - if (res_y != NULL) - { - *res_y = info_ptr->y_pixels_per_unit; - retval |= PNG_INFO_pHYs; - } - - if (unit_type != NULL) - { - *unit_type = (int)info_ptr->phys_unit_type; - retval |= PNG_INFO_pHYs; - } - } - - return (retval); -} -#endif /* pHYs */ - -png_uint_32 PNGAPI -png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr, - png_colorp *palette, int *num_palette) -{ - png_debug1(1, "in %s retrieval function", "PLTE"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_PLTE) != 0 && palette != NULL) - { - *palette = info_ptr->palette; - *num_palette = info_ptr->num_palette; - png_debug1(3, "num_palette = %d", *num_palette); - return (PNG_INFO_PLTE); - } - - return (0); -} - -#ifdef PNG_sBIT_SUPPORTED -png_uint_32 PNGAPI -png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr, - png_color_8p *sig_bit) -{ - png_debug1(1, "in %s retrieval function", "sBIT"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL) - { - *sig_bit = &(info_ptr->sig_bit); - return (PNG_INFO_sBIT); - } - - return (0); -} -#endif - -#ifdef PNG_TEXT_SUPPORTED -int PNGAPI -png_get_text(png_const_structrp png_ptr, png_inforp info_ptr, - png_textp *text_ptr, int *num_text) -{ - if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0) - { - png_debug1(1, "in 0x%lx retrieval function", - (unsigned long)png_ptr->chunk_name); - - if (text_ptr != NULL) - *text_ptr = info_ptr->text; - - if (num_text != NULL) - *num_text = info_ptr->num_text; - - return info_ptr->num_text; - } - - if (num_text != NULL) - *num_text = 0; - - return(0); -} -#endif - -#ifdef PNG_tIME_SUPPORTED -png_uint_32 PNGAPI -png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr, - png_timep *mod_time) -{ - png_debug1(1, "in %s retrieval function", "tIME"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL) - { - *mod_time = &(info_ptr->mod_time); - return (PNG_INFO_tIME); - } - - return (0); -} -#endif - -#ifdef PNG_tRNS_SUPPORTED -png_uint_32 PNGAPI -png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr, - png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color) -{ - png_uint_32 retval = 0; - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_tRNS) != 0) - { - png_debug1(1, "in %s retrieval function", "tRNS"); - - if ((info_ptr->format & PNG_FORMAT_FLAG_COLORMAP) != 0) - { - if (trans_alpha != NULL) - { - *trans_alpha = info_ptr->trans_alpha; - retval |= PNG_INFO_tRNS; - } - - if (trans_color != NULL) - *trans_color = &(info_ptr->trans_color); - } - - else /* if (info_ptr->format not colormapped */ - { - if (trans_color != NULL) - { - *trans_color = &(info_ptr->trans_color); - retval |= PNG_INFO_tRNS; - } - - if (trans_alpha != NULL) - *trans_alpha = NULL; - } - - if (num_trans != NULL) - { - *num_trans = info_ptr->num_trans; - retval |= PNG_INFO_tRNS; - } - } - - return (retval); -} -#endif - -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -int PNGAPI -png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr, - png_unknown_chunkpp unknowns) -{ - if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL) - { - *unknowns = info_ptr->unknown_chunks; - return info_ptr->unknown_chunks_num; - } - - return 0; -} -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -png_byte PNGAPI -png_get_rgb_to_gray_status(png_const_structrp png_ptr) -{ - if (png_ptr) - return png_ptr->rgb_to_gray_status; - return 0; -} -#endif - -#ifdef PNG_USER_CHUNKS_SUPPORTED -png_voidp PNGAPI -png_get_user_chunk_ptr(png_const_structrp png_ptr) -{ - if (png_ptr) - return png_ptr->user_chunk_ptr; - - return NULL; -} -#endif - -png_alloc_size_t PNGAPI -png_get_compression_buffer_size(png_const_structrp png_ptr) -{ - if (png_ptr == NULL) - return 0; - -# if defined(PNG_SEQUENTIAL_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - return png_ptr->IDAT_size; - -# else - return PNG_IDAT_READ_SIZE; /* progressive reader */ -# endif -} - -#ifdef PNG_SET_USER_LIMITS_SUPPORTED -/* These functions were added to libpng 1.2.6 and were enabled - * by default in libpng-1.4.0 */ -png_uint_32 PNGAPI -png_get_user_width_max (png_const_structrp png_ptr) -{ - return (png_ptr ? png_ptr->user_width_max : 0); -} - -png_uint_32 PNGAPI -png_get_user_height_max (png_const_structrp png_ptr) -{ - return (png_ptr ? png_ptr->user_height_max : 0); -} - -/* This function was added to libpng 1.4.0 */ -png_uint_32 PNGAPI -png_get_chunk_cache_max (png_const_structrp png_ptr) -{ - return (png_ptr ? png_ptr->user_chunk_cache_max : 0); -} - -/* This function was added to libpng 1.4.1 */ -png_alloc_size_t PNGAPI -png_get_chunk_malloc_max (png_const_structrp png_ptr) -{ - return (png_ptr ? png_ptr->user_chunk_malloc_max : 0); -} -#endif /* SET_USER_LIMITS */ - -/* These functions were added to libpng 1.4.0 */ -#ifdef PNG_IO_STATE_SUPPORTED -png_uint_32 PNGAPI -png_get_io_state (png_const_structrp png_ptr) -{ - return png_ptr->io_state; -} - -png_uint_32 PNGAPI -png_get_io_chunk_type (png_const_structrp png_ptr) -{ - return png_ptr->chunk_name; -} -#endif /* IO_STATE */ -#endif /* READ || WRITE */ diff --git a/ext/libpng17/pnginfo.h b/ext/libpng17/pnginfo.h deleted file mode 100644 index a0b5d5c761..0000000000 --- a/ext/libpng17/pnginfo.h +++ /dev/null @@ -1,251 +0,0 @@ - -/* pnginfo.h - header file for PNG reference library - * - * Last changed in libpng 1.6.1 [March 28, 2013] - * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* png_info is a structure that holds the information in a PNG file so - * that the application can find out the characteristics of the image. - * If you are reading the file, this structure will tell you what is - * in the PNG file. If you are writing the file, fill in the information - * you want to put into the PNG file, using png_set_*() functions, then - * call png_write_info(). - * - * The names chosen should be very close to the PNG specification, so - * consult that document for information about the meaning of each field. - * - * With libpng < 0.95, it was only possible to directly set and read the - * the values in the png_info_struct, which meant that the contents and - * order of the values had to remain fixed. With libpng 0.95 and later, - * however, there are now functions that abstract the contents of - * png_info_struct from the application, so this makes it easier to use - * libpng with dynamic libraries, and even makes it possible to use - * libraries that don't have all of the libpng ancillary chunk-handing - * functionality. In libpng-1.5.0 this was moved into a separate private - * file that is not visible to applications. - * - * The following members may have allocated storage attached that should be - * cleaned up before the structure is discarded: palette, trans, text, - * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile, - * splt_palettes, scal_unit, row_pointers, and unknowns. By default, these - * are automatically freed when the info structure is deallocated, if they were - * allocated internally by libpng. This behavior can be changed by means - * of the png_data_freer() function. - * - * More allocation details: all the chunk-reading functions that - * change these members go through the corresponding png_set_* - * functions. A function to clear these members is available: see - * png_free_data(). The png_set_* functions do not depend on being - * able to point info structure members to any of the storage they are - * passed (they make their own copies), EXCEPT that the png_set_text - * functions use the same storage passed to them in the text_ptr or - * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns - * functions do not make their own copies. - */ -#ifndef PNGINFO_H -#define PNGINFO_H - -struct png_info_def -{ - /* The following are necessary for every PNG file */ - png_uint_32 width; /* width of image in pixels (from IHDR) */ - png_uint_32 height; /* height of image in pixels (from IHDR) */ - unsigned int valid; /* valid chunk data (see PNG_INFO_ in png.h) */ - png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */ - unsigned int num_palette:9; /* number of color entries in "palette" (PLTE) */ - unsigned int num_trans:9; /* number of transparent palette color (tRNS) */ - unsigned int bit_depth:6; /* 1, 2, 4, 8, 16 or 32 bits/channel */ - unsigned int format:PNG_RF_BITS; /* row format; see png_struct.h */ - /* The following three should have been named *_method not *_type */ - png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */ - png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */ - png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ - -#ifdef PNG_READ_SUPPORTED - /* This is never set during write */ - png_byte signature[8]; /* magic bytes read by libpng from start of file */ -#endif - - /* The rest of the data is optional. If you are reading, check the - * valid field to see if the information in these are valid. If you - * are writing, set the valid field to those chunks you want written, - * and initialize the appropriate fields below. - */ - -#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) - /* png_colorspace only contains 'flags' if neither GAMMA or COLORSPACE are - * defined. When COLORSPACE is switched on all the colorspace-defining - * chunks should be enabled, when GAMMA is switched on all the gamma-defining - * chunks should be enabled. If this is not done it becomes possible to read - * inconsistent PNG files and assign a probably incorrect interpretation to - * the information. (In other words, by carefully choosing which chunks to - * recognize the system configuration can select an interpretation for PNG - * files containing ambiguous data and this will result in inconsistent - * behavior between different libpng builds!) - */ - png_colorspace colorspace; -#endif - -#ifdef PNG_iCCP_SUPPORTED - /* iCCP chunk data. */ - png_charp iccp_name; /* profile name */ - png_bytep iccp_profile; /* International Color Consortium profile data */ -#endif - -#ifdef PNG_TEXT_SUPPORTED - /* The tEXt, and zTXt chunks contain human-readable textual data in - * uncompressed, compressed, and optionally compressed forms, respectively. - * The data in "text" is an array of pointers to uncompressed, - * null-terminated C strings. Each chunk has a keyword that describes the - * textual data contained in that chunk. Keywords are not required to be - * unique, and the text string may be empty. Any number of text chunks may - * be in an image. - */ - int num_text; /* number of comments read or comments to write */ - int max_text; /* current size of text array */ - png_textp text; /* array of comments read or comments to write */ -#endif /* TEXT */ - -#ifdef PNG_tIME_SUPPORTED - /* The tIME chunk holds the last time the displayed image data was - * modified. See the png_time struct for the contents of this struct. - */ - png_time mod_time; - png_byte time_location; -#endif - -#ifdef PNG_sBIT_SUPPORTED - /* The sBIT chunk specifies the number of significant high-order bits - * in the pixel data. Values are in the range [1, bit_depth], and are - * only specified for the channels in the pixel data. The contents of - * the low-order bits is not specified. Data is valid if - * (valid & PNG_INFO_sBIT) is non-zero. - */ - png_color_8 sig_bit; /* significant bits in color channels */ -#endif - -#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \ -defined(PNG_READ_BACKGROUND_SUPPORTED) - /* The tRNS chunk supplies transparency data for paletted images and - * other image types that don't need a full alpha channel. There are - * "num_trans" transparency values for a paletted image, stored in the - * same order as the palette colors, starting from index 0. Values - * for the data are in the range [0, 255], ranging from fully transparent - * to fully opaque, respectively. For non-paletted images, there is a - * single color specified that should be treated as fully transparent. - * Data is valid if (valid & PNG_INFO_tRNS) is non-zero. - */ - png_bytep trans_alpha; /* alpha values for paletted image */ - png_color_16 trans_color; /* transparent color for non-palette image */ -#endif - -#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - /* The bKGD chunk gives the suggested image background color if the - * display program does not have its own background color and the image - * is needs to composited onto a background before display. The colors - * in "background" are normally in the same color space/depth as the - * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero. - */ - png_color_16 background; -#endif - -#ifdef PNG_oFFs_SUPPORTED - /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards - * and downwards from the top-left corner of the display, page, or other - * application-specific co-ordinate space. See the PNG_OFFSET_ defines - * below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero. - */ - png_int_32 x_offset; /* x offset on page */ - png_int_32 y_offset; /* y offset on page */ - png_byte offset_unit_type; /* offset units type */ -#endif - -#ifdef PNG_pHYs_SUPPORTED - /* The pHYs chunk gives the physical pixel density of the image for - * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_ - * defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero. - */ - png_uint_32 x_pixels_per_unit; /* horizontal pixel density */ - png_uint_32 y_pixels_per_unit; /* vertical pixel density */ - png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */ -#endif - -#ifdef PNG_hIST_SUPPORTED - /* The hIST chunk contains the relative frequency or importance of the - * various palette entries, so that a viewer can intelligently select a - * reduced-color palette, if required. Data is an array of "num_palette" - * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST) - * is non-zero. - */ - png_uint_16p hist; -#endif - -#ifdef PNG_pCAL_SUPPORTED - /* The pCAL chunk describes a transformation between the stored pixel - * values and original physical data values used to create the image. - * The integer range [0, 2^bit_depth - 1] maps to the floating-point - * range given by [pcal_X0, pcal_X1], and are further transformed by a - * (possibly non-linear) transformation function given by "pcal_type" - * and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_ - * defines below, and the PNG-Group's PNG extensions document for a - * complete description of the transformations and how they should be - * implemented, and for a description of the ASCII parameter strings. - * Data values are valid if (valid & PNG_INFO_pCAL) non-zero. - */ - png_charp pcal_purpose; /* pCAL chunk description string */ - png_int_32 pcal_X0; /* minimum value */ - png_int_32 pcal_X1; /* maximum value */ - png_charp pcal_units; /* Latin-1 string giving physical units */ - png_charpp pcal_params; /* ASCII strings containing parameter values */ - png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */ - png_byte pcal_nparams; /* number of parameters given in pcal_params */ -#endif - -/* New members added in libpng-1.0.6 */ - png_uint_32 free_me; /* flags items libpng is responsible for freeing */ - -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED - /* Storage for unknown chunks that the library doesn't recognize. */ - png_unknown_chunkp unknown_chunks; - - /* The type of this field is limited by the type of - * png_struct::user_chunk_cache_max, else overflow can occur. - */ - int unknown_chunks_num; -#endif - -#ifdef PNG_sPLT_SUPPORTED - /* Data on sPLT chunks (there may be more than one). */ - png_sPLT_tp splt_palettes; - int splt_palettes_num; /* Match type returned by png_get API */ -#endif - -#ifdef PNG_sCAL_SUPPORTED - /* The sCAL chunk describes the actual physical dimensions of the - * subject matter of the graphic. The chunk contains a unit specification - * a byte value, and two ASCII strings representing floating-point - * values. The values are width and height corresponsing to one pixel - * in the image. Data values are valid if (valid & PNG_INFO_sCAL) is - * non-zero. - */ - png_byte scal_unit; /* unit of physical scale */ - png_charp scal_s_width; /* string containing height */ - png_charp scal_s_height; /* string containing width */ -#endif - -#ifdef PNG_INFO_IMAGE_SUPPORTED - /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) - non-zero */ - /* Data valid if (valid & PNG_INFO_IDAT) non-zero */ - png_bytepp row_pointers; /* the image bits */ -#endif - -}; -#endif /* PNGINFO_H */ diff --git a/ext/libpng17/pnglibconf.h b/ext/libpng17/pnglibconf.h deleted file mode 100644 index 090f96398c..0000000000 --- a/ext/libpng17/pnglibconf.h +++ /dev/null @@ -1,213 +0,0 @@ -/* libpng 1.7.0beta90 STANDARD API DEFINITION */ - -/* pnglibconf.h - library build configuration */ - -/* libpng version 1.7.0beta90, August 28, 2017 */ - -/* Copyright (c) 1998-2016 Glenn Randers-Pehrson */ - -/* This code is released under the libpng license. */ -/* For conditions of distribution and use, see the disclaimer */ -/* and license in png.h */ - -/* pnglibconf.h */ -/* Machine generated file: DO NOT EDIT */ -/* Derived from: scripts/pnglibconf.dfa */ -#ifndef PNGLCONF_H -#define PNGLCONF_H -/* options */ -#define PNG_16BIT_SUPPORTED -#define PNG_ALIGNED_MEMORY_SUPPORTED -#define PNG_BENIGN_ERRORS_SUPPORTED -#define PNG_BENIGN_READ_ERRORS_SUPPORTED -/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/ -#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED -#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED -#define PNG_COLORSPACE_SUPPORTED -#define PNG_CONSOLE_IO_SUPPORTED -#define PNG_CONVERT_tIME_SUPPORTED -#define PNG_EASY_ACCESS_SUPPORTED -#define PNG_ERROR_TEXT_SUPPORTED -#define PNG_FIXED_POINT_SUPPORTED -#define PNG_FLOATING_ARITHMETIC_SUPPORTED -#define PNG_FLOATING_POINT_SUPPORTED -#define PNG_FORMAT_AFIRST_SUPPORTED -#define PNG_FORMAT_BGR_SUPPORTED -#define PNG_GAMMA_SUPPORTED -#define PNG_GET_PALETTE_MAX_SUPPORTED -#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED -#define PNG_INCH_CONVERSIONS_SUPPORTED -#define PNG_INFO_IMAGE_SUPPORTED -#define PNG_IO_STATE_SUPPORTED -// #define PNG_MNG_FEATURES_SUPPORTED -// #define PNG_MNG_READ_FEATURES_SUPPORTED -// #define PNG_MNG_WRITE_FEATURES_SUPPORTED -#define PNG_PALETTE_MAX_SUPPORTED -#define PNG_PROGRESSIVE_READ_SUPPORTED -#define PNG_READ_16BIT_SUPPORTED -#define PNG_READ_ALPHA_MODE_SUPPORTED -#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED -#define PNG_READ_BACKGROUND_SUPPORTED -#define PNG_READ_BGR_SUPPORTED -#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED -#define PNG_READ_COMPOSITE_NODIV_SUPPORTED -#define PNG_READ_COMPRESSED_TEXT_SUPPORTED -#define PNG_READ_EXPAND_16_SUPPORTED -#define PNG_READ_EXPAND_SUPPORTED -#define PNG_READ_FILLER_SUPPORTED -#define PNG_READ_GAMMA_SUPPORTED -#define PNG_READ_GET_PALETTE_MAX_SUPPORTED -#define PNG_READ_GRAY_TO_RGB_SUPPORTED -#define PNG_READ_IMAGE_SUPPORTED -#define PNG_READ_INTERLACING_SUPPORTED -#define PNG_READ_INT_FUNCTIONS_SUPPORTED -#define PNG_READ_INVERT_ALPHA_SUPPORTED -#define PNG_READ_INVERT_SUPPORTED -#define PNG_READ_OPT_PLTE_SUPPORTED -#define PNG_READ_PACKSWAP_SUPPORTED -#define PNG_READ_PACK_SUPPORTED -#define PNG_READ_PNG_SUPPORTED -#define PNG_READ_QUANTIZE_SUPPORTED -#define PNG_READ_RGB_TO_GRAY_SUPPORTED -#define PNG_READ_SCALE_16_TO_8_SUPPORTED -#define PNG_READ_SHIFT_SUPPORTED -#define PNG_READ_STRIP_16_TO_8_SUPPORTED -#define PNG_READ_STRIP_ALPHA_SUPPORTED -#define PNG_READ_SUPPORTED -#define PNG_READ_SWAP_ALPHA_SUPPORTED -#define PNG_READ_SWAP_SUPPORTED -#define PNG_READ_TEXT_SUPPORTED -#define PNG_READ_TRANSFORMS_SUPPORTED -#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -#define PNG_READ_USER_CHUNKS_SUPPORTED -#define PNG_READ_USER_TRANSFORM_SUPPORTED -#define PNG_READ_bKGD_SUPPORTED -#define PNG_READ_cHRM_SUPPORTED -#define PNG_READ_gAMA_SUPPORTED -#define PNG_READ_hIST_SUPPORTED -#define PNG_READ_iCCP_SUPPORTED -#define PNG_READ_iTXt_SUPPORTED -#define PNG_READ_oFFs_SUPPORTED -#define PNG_READ_pCAL_SUPPORTED -#define PNG_READ_pHYs_SUPPORTED -#define PNG_READ_sBIT_SUPPORTED -#define PNG_READ_sCAL_SUPPORTED -#define PNG_READ_sPLT_SUPPORTED -#define PNG_READ_sRGB_SUPPORTED -#define PNG_READ_tEXt_SUPPORTED -#define PNG_READ_tIME_SUPPORTED -#define PNG_READ_tRNS_SUPPORTED -#define PNG_READ_zTXt_SUPPORTED -#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED -#define PNG_SELECT_FILTER_SUPPORTED -#define PNG_SEQUENTIAL_READ_SUPPORTED -#define PNG_SETJMP_SUPPORTED -#define PNG_SET_OPTION_SUPPORTED -#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED -#define PNG_SET_USER_LIMITS_SUPPORTED -#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED -#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED -#define PNG_SIMPLIFIED_READ_SUPPORTED -#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED -#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED -#define PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED -#define PNG_SIMPLIFIED_WRITE_SUPPORTED -#define PNG_STDIO_SUPPORTED -#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -#define PNG_TEXT_SUPPORTED -#define PNG_TIME_RFC1123_SUPPORTED -#define PNG_TRANSFORM_MECH_SUPPORTED -#define PNG_UNKNOWN_CHUNKS_SUPPORTED -#define PNG_USER_CHUNKS_SUPPORTED -#define PNG_USER_LIMITS_SUPPORTED -#define PNG_USER_MEM_SUPPORTED -#define PNG_USER_TRANSFORM_INFO_SUPPORTED -#define PNG_USER_TRANSFORM_PTR_SUPPORTED -#define PNG_WARNINGS_SUPPORTED -#define PNG_WRITE_16BIT_SUPPORTED -#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED -#define PNG_WRITE_BGR_SUPPORTED -#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED -#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED -#define PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED -#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED -#define PNG_WRITE_FILLER_SUPPORTED -#define PNG_WRITE_FILTER_SUPPORTED -#define PNG_WRITE_FLUSH_SUPPORTED -#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED -#define PNG_WRITE_INTERLACING_SUPPORTED -#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED -#define PNG_WRITE_INVERT_ALPHA_SUPPORTED -#define PNG_WRITE_INVERT_SUPPORTED -#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED -#define PNG_WRITE_PACKSWAP_SUPPORTED -#define PNG_WRITE_PACK_SUPPORTED -#define PNG_WRITE_PNG_SUPPORTED -#define PNG_WRITE_SHIFT_SUPPORTED -#define PNG_WRITE_SUPPORTED -#define PNG_WRITE_SWAP_ALPHA_SUPPORTED -#define PNG_WRITE_SWAP_SUPPORTED -#define PNG_WRITE_TEXT_SUPPORTED -#define PNG_WRITE_TRANSFORMS_SUPPORTED -#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED -#define PNG_WRITE_USER_TRANSFORM_SUPPORTED -#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED -#define PNG_WRITE_bKGD_SUPPORTED -#define PNG_WRITE_cHRM_SUPPORTED -#define PNG_WRITE_gAMA_SUPPORTED -#define PNG_WRITE_hIST_SUPPORTED -#define PNG_WRITE_iCCP_SUPPORTED -#define PNG_WRITE_iTXt_SUPPORTED -#define PNG_WRITE_oFFs_SUPPORTED -#define PNG_WRITE_pCAL_SUPPORTED -#define PNG_WRITE_pHYs_SUPPORTED -#define PNG_WRITE_sBIT_SUPPORTED -#define PNG_WRITE_sCAL_SUPPORTED -#define PNG_WRITE_sPLT_SUPPORTED -#define PNG_WRITE_sRGB_SUPPORTED -#define PNG_WRITE_tEXt_SUPPORTED -#define PNG_WRITE_tIME_SUPPORTED -#define PNG_WRITE_tRNS_SUPPORTED -#define PNG_WRITE_zTXt_SUPPORTED -#define PNG_bKGD_SUPPORTED -#define PNG_cHRM_SUPPORTED -#define PNG_gAMA_SUPPORTED -#define PNG_hIST_SUPPORTED -#define PNG_iCCP_SUPPORTED -#define PNG_iTXt_SUPPORTED -#define PNG_oFFs_SUPPORTED -#define PNG_pCAL_SUPPORTED -#define PNG_pHYs_SUPPORTED -#define PNG_sBIT_SUPPORTED -#define PNG_sCAL_SUPPORTED -#define PNG_sPLT_SUPPORTED -#define PNG_sRGB_SUPPORTED -#define PNG_tEXt_SUPPORTED -#define PNG_tIME_SUPPORTED -#define PNG_tRNS_SUPPORTED -#define PNG_zTXt_SUPPORTED -/* end of options */ -/* settings */ -#define PNG_ABORT { (abort()); } -#define PNG_API_RULE 0 -#define PNG_DEFAULT_COMPRESSION_LEVEL PNG_COMPRESSION_MEDIUM -#define PNG_DEFAULT_GAMMA_ACCURACY 665 -#define PNG_DEFAULT_READ_MACROS 1 -#define PNG_GAMMA_THRESHOLD_FIXED 153 -#define PNG_IDAT_READ_SIZE 4096 -#define PNG_INFLATE_BUF_SIZE 1024 -#define PNG_MAX_GAMMA_8 11 -#define PNG_QUANTIZE_BLUE_BITS 5 -#define PNG_QUANTIZE_GREEN_BITS 5 -#define PNG_QUANTIZE_RED_BITS 5 -#define PNG_USER_CHUNK_CACHE_MAX 1000 -#define PNG_USER_CHUNK_MALLOC_MAX 8000000 -#define PNG_USER_HEIGHT_MAX 1000000 -#define PNG_USER_WIDTH_MAX 1000000 -#define PNG_ZBUF_SIZE 4096 -#define PNG_ZLIB_HEADER -#define PNG_ZLIB_VERNUM 0 -#define PNG_sCAL_PRECISION 5 -#define PNG_sRGB_PROFILE_CHECKS 2 -/* end of settings */ -#endif /* PNGLCONF_H */ diff --git a/ext/libpng17/pngmem.c b/ext/libpng17/pngmem.c deleted file mode 100644 index 0593bb35f2..0000000000 --- a/ext/libpng17/pngmem.c +++ /dev/null @@ -1,269 +0,0 @@ - -/* pngmem.c - stub functions for memory allocation - * - * Last changed in libpng 1.7.0 [(PENDING RELEASE)] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file provides a location for all memory allocation. Users who - * need special memory handling are expected to supply replacement - * functions for png_malloc() and png_free(), and to use - * png_create_read_struct_2() and png_create_write_struct_2() to - * identify the replacement functions. - */ - -#include "pngpriv.h" -#define PNG_SRC_FILE PNG_SRC_FILE_pngmem - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -/* Free a png_struct */ -void /* PRIVATE */ -png_destroy_png_struct(png_structrp png_ptr) -{ - if (png_ptr != NULL) - { - /* png_free might call png_error and may certainly call - * png_get_mem_ptr, so fake a temporary png_struct to support this. - */ - png_struct dummy_struct = *png_ptr; - memset(png_ptr, 0, (sizeof *png_ptr)); - png_free(&dummy_struct, png_ptr); - -# ifdef PNG_SETJMP_SUPPORTED - /* We may have a jmp_buf left to deallocate. */ - png_free_jmpbuf(&dummy_struct); -# endif - } -} - -/* Allocate memory. For reasonable files, size should never exceed - * 64K. However, zlib may allocate more than 64K if you don't tell - * it not to. See zconf.h and png.h for more information. zlib does - * need to allocate exactly 64K, so whatever you call here must - * have the ability to do that. - */ -PNG_FUNCTION(png_voidp,PNGAPI -png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) -{ - png_voidp ret; - - ret = png_malloc(png_ptr, size); - - if (ret != NULL) - memset(ret, 0, size); - - return ret; -} - -/* png_malloc_base, an internal function added at libpng 1.6.0, does the work of - * allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED. - * Checking and error handling must happen outside this routine; it returns NULL - * if the allocation cannot be done (for any reason.) - */ -PNG_FUNCTION(png_voidp /* PRIVATE */, -png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size), - PNG_ALLOCATED) -{ - /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS - * allocators have also been removed in 1.6.0, so any 16-bit system now has - * to implement a user memory handler. This checks to be sure it isn't - * called with big numbers. - */ -#ifndef PNG_USER_MEM_SUPPORTED - PNG_UNUSED(png_ptr) -#endif - - /* Some compilers complain that this is always true. However, it - * can be false when integer overflow happens. - */ -#ifdef PNG_MAX_MALLOC_64K - if (size > 0 && size <= PNG_SIZE_MAX && size <= 65536U) -#else - if (size > 0 && size <= PNG_SIZE_MAX) -#endif - { - png_voidp result; - -#ifdef PNG_USER_MEM_SUPPORTED - if (png_ptr != NULL && png_ptr->malloc_fn != NULL) - result = png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size); - - else -#endif - result = malloc((size_t)size); /* checked for truncation above */ - - return result; - } - - else - return NULL; -} - -#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\ - defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) -/* This is really here only to work round a spurious warning in GCC 4.6 and 4.7 - * that arises because of the checks in png_realloc_array that are repeated in - * png_malloc_array. - */ -static png_voidp -png_malloc_array_checked(png_const_structrp png_ptr, int nelements, - size_t element_size) -{ - png_alloc_size_t req = nelements; /* known to be > 0 */ - - if (req <= PNG_SIZE_MAX/element_size) - return png_malloc_base(png_ptr, req * element_size); - - /* The failure case when the request is too large */ - return NULL; -} - -PNG_FUNCTION(png_voidp /* PRIVATE */, -png_malloc_array,(png_const_structrp png_ptr, int nelements, - size_t element_size),PNG_ALLOCATED) -{ - affirm(nelements > 0 && element_size > 0); - return png_malloc_array_checked(png_ptr, nelements, element_size); -} - -PNG_FUNCTION(png_voidp /* PRIVATE */, -png_realloc_array,(png_structrp png_ptr, png_const_voidp old_array, - int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED) -{ - /* These are internal errors: */ - affirm(add_elements > 0 && element_size > 0 && old_elements >= 0 && - (old_array != NULL || old_elements == 0)); - - /* Check for overflow on the elements count (so the caller does not have to - * check.) - */ - if (add_elements <= INT_MAX - old_elements) - { - png_voidp new_array = png_malloc_array_checked(png_ptr, - old_elements+add_elements, element_size); - - if (new_array != NULL) - { - /* Because png_malloc_array worked the size calculations below cannot - * overflow. - */ - if (old_elements > 0) - memcpy(new_array, old_array, element_size*(unsigned)old_elements); - - memset((char*)new_array + element_size*(unsigned)old_elements, 0, - element_size*(unsigned)add_elements); - - return new_array; - } - } - -#ifdef PNG_READ_SUPPORTED -# ifdef PNG_USER_LIMITS_SUPPORTED - /* The potential overflow case. Set the cache counter so libpng will - * not make any more attempts - */ - png_ptr->user_chunk_cache_max = 2; -# endif -#endif - - return NULL; /* error */ -} -#endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */ - -/* Various functions that have different error handling are derived from this. - * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate - * function png_malloc_default is also provided. - */ -PNG_FUNCTION(png_voidp,PNGAPI -png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) -{ - png_voidp ret; - - if (png_ptr == NULL) - return NULL; - - ret = png_malloc_base(png_ptr, size); - - if (ret == NULL) - png_error(png_ptr, "Out of memory"); - - return ret; -} - -/* This function was added at libpng version 1.2.3. The png_malloc_warn() - * function will issue a png_warning and return NULL instead of issuing a - * png_error, if it fails to allocate the requested memory. - */ -PNG_FUNCTION(png_voidp,PNGAPI -png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size), - PNG_ALLOCATED) -{ - if (png_ptr != NULL) - { - png_voidp ret = png_malloc_base(png_ptr, size); - - if (ret != NULL) - return ret; - - png_warning(png_ptr, "Out of memory"); - } - - return NULL; -} - -/* Free a pointer allocated by png_malloc(). If ptr is NULL, return - * without taking any action. - */ -void PNGAPI -png_free(png_const_structrp png_ptr, png_voidp ptr) -{ - if (png_ptr == NULL || ptr == NULL) - return; - -#ifdef PNG_USER_MEM_SUPPORTED - if (png_ptr->free_fn != NULL) - png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr); - - else - free(ptr); -#else - free(ptr); -#endif /* USER_MEM */ - -} - -#ifdef PNG_USER_MEM_SUPPORTED -/* This function is called when the application wants to use another method - * of allocating and freeing memory. - */ -void PNGAPI -png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr - malloc_fn, png_free_ptr free_fn) -{ - if (png_ptr != NULL) - { - png_ptr->mem_ptr = mem_ptr; - png_ptr->malloc_fn = malloc_fn; - png_ptr->free_fn = free_fn; - } -} - -/* This function returns a pointer to the mem_ptr associated with the user - * functions. The application should free any memory associated with this - * pointer before png_write_destroy and png_read_destroy are called. - */ -png_voidp PNGAPI -png_get_mem_ptr(png_const_structrp png_ptr) -{ - if (png_ptr == NULL) - return NULL; - - return png_ptr->mem_ptr; -} -#endif /* USER_MEM */ -#endif /* READ || WRITE */ diff --git a/ext/libpng17/pngpread.c b/ext/libpng17/pngpread.c deleted file mode 100644 index c7e5425aaf..0000000000 --- a/ext/libpng17/pngpread.c +++ /dev/null @@ -1,866 +0,0 @@ - -/* pngpread.c - read a png file in push mode - * - * Last changed in libpng 1.7.0 [(PENDING RELEASE)] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" -#define PNG_SRC_FILE PNG_SRC_FILE_pngpread - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED - -/* Standard callbacks */ -static void PNGCBAPI -png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) -{ - png_bytep ptr; - - if (png_ptr == NULL) - return; - - ptr = buffer; - debug(length > 0); - - if (length > 0 && png_ptr->save_buffer_size > 0) - { - png_size_t save_size; - - if (length < png_ptr->save_buffer_size) - save_size = length; - - else - save_size = png_ptr->save_buffer_size; - - memcpy(ptr, png_ptr->save_buffer_ptr, save_size); - length -= save_size; - ptr += save_size; - png_ptr->buffer_size -= save_size; - png_ptr->save_buffer_size -= save_size; - png_ptr->save_buffer_ptr += save_size; - } - - if (length > 0 && png_ptr->current_buffer_size > 0) - { - png_size_t save_size; - - if (length < png_ptr->current_buffer_size) - save_size = length; - - else - save_size = png_ptr->current_buffer_size; - - memcpy(ptr, png_ptr->current_buffer_ptr, save_size); - png_ptr->buffer_size -= save_size; - png_ptr->current_buffer_size -= save_size; - png_ptr->current_buffer_ptr += save_size; - } -} - -/* Push model modes: png_chunk_op plus extras */ -typedef enum -{ - /* all the png_chunk_op codes, plus: */ - png_read_signature = 0, /* starting value */ - png_read_chunk_header, - png_read_end_IDAT, - png_read_done, - png_read_chunk, /* Not a state, use these derived from png_chunk_op: */ - png_read_chunk_skip = png_read_chunk+png_chunk_skip, - png_read_chunk_unknown = png_read_chunk+png_chunk_unknown, - png_read_chunk_process_all = png_read_chunk+png_chunk_process_all, - png_read_chunk_process_part = png_read_chunk+png_chunk_process_part -} png_read_mode; - -static void -png_push_save_buffer_partial(png_structrp png_ptr, size_t amount) -{ - /* Copy 'amount' bytes to the end of the save buffer from the current - * buffer. - */ - png_bytep buffer; - size_t save_size = png_ptr->save_buffer_size; - - if (save_size > PNG_SIZE_MAX - amount) - png_error(png_ptr, "save buffer overflow"); - - if (png_ptr->save_buffer_max < save_size + amount) - { - /* Reallocate the save buffer. */ - buffer = png_voidcast(png_bytep, png_malloc(png_ptr, save_size + amount)); - memcpy(buffer, png_ptr->save_buffer_ptr, save_size); - png_free(png_ptr, png_ptr->save_buffer); - png_ptr->save_buffer_ptr = png_ptr->save_buffer = buffer; - } - - else if (png_ptr->save_buffer_max - - (png_ptr->save_buffer_ptr - png_ptr->save_buffer) < save_size + amount) - { - /* Move the existing saved data */ - buffer = png_ptr->save_buffer; - memmove(buffer, png_ptr->save_buffer_ptr, save_size); - png_ptr->save_buffer_ptr = buffer; - } - - else /* Just copy the data */ - buffer = png_ptr->save_buffer_ptr; - - memcpy(buffer+save_size, png_ptr->current_buffer_ptr, amount); - png_ptr->save_buffer_size = save_size + amount; - png_ptr->current_buffer_ptr += amount; - png_ptr->current_buffer_size -= amount; - png_ptr->buffer_size -= amount; -} - -static void -png_push_save_buffer(png_structrp png_ptr) -{ - png_push_save_buffer_partial(png_ptr, png_ptr->current_buffer_size); - /* This terminates the process loop. */ - png_ptr->buffer_size = 0; -} - -#define PNG_PUSH_SAVE_BUFFER_IF_FULL \ -if (png_ptr->chunk_length + 4 > png_ptr->buffer_size) \ - { png_push_save_buffer(png_ptr); return; } -#define PNG_PUSH_SAVE_BUFFER_IF_LT(N) \ -if (png_ptr->buffer_size < N) \ - { png_push_save_buffer(png_ptr); return; } - -png_size_t PNGAPI -png_process_data_pause(png_structrp png_ptr, int save) -{ - if (png_ptr != NULL) - { - /* It's easiest for the caller if we do the save; then the caller doesn't - * have to supply the same data again: - */ - if (save != 0) - png_push_save_buffer(png_ptr); - else - { - /* This includes any pending saved bytes: */ - png_size_t remaining = png_ptr->buffer_size; - png_ptr->buffer_size = 0; /* Terminate the process loop */ - - /* So subtract the saved buffer size, unless all the data - * is actually 'saved', in which case we just return 0 - */ - if (png_ptr->save_buffer_size < remaining) - return remaining - png_ptr->save_buffer_size; - } - } - - return 0; -} - -png_uint_32 PNGAPI -png_process_data_skip(png_structrp png_ptr) -{ - if (png_ptr != NULL && png_ptr->process_mode == png_read_chunk_skip) - { - /* At the end of png_process_data the buffer size must be 0 (see the loop - * above) so we can detect a broken call here: - */ - if (png_ptr->buffer_size != 0) - png_app_error(png_ptr, - "png_process_data_skip called inside png_process_data"); - - /* If is impossible for there to be a saved buffer at this point - - * otherwise we could not be in SKIP mode. This will also happen if - * png_process_skip is called inside png_process_data (but only very - * rarely.) - */ - else if (png_ptr->save_buffer_size != 0) - png_app_error(png_ptr, "png_process_data_skip called with saved data"); - - else - { - /* Skipping png_ptr->chunk_length of data then checking the CRC, after - * that a new chunk header will be read. - */ - png_ptr->process_mode = png_read_chunk_header; - return png_ptr->chunk_length + 4; - } - } - - return 0; -} - -static void -png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer, - png_size_t buffer_length) -{ - png_ptr->current_buffer_size = buffer_length; - png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size; - png_ptr->current_buffer_ptr = buffer; -} - -/* Read any remaining signature bytes from the stream and compare them with - * the correct PNG signature. It is possible that this routine is called - * with bytes already read from the signature, either because they have been - * checked by the calling application, or because of multiple calls to this - * routine. - */ -static void -png_push_read_signature(png_structrp png_ptr, png_inforp info_ptr) -{ - unsigned int num_checked = png_ptr->sig_bytes; - unsigned int num_to_check = 8 - num_checked; - - if (png_ptr->buffer_size < num_to_check) - num_to_check = (int)/*SAFE*/png_ptr->buffer_size; - - png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), - num_to_check); - png_ptr->sig_bytes = png_check_byte(png_ptr, - png_ptr->sig_bytes + num_to_check); - - if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) - { - if (num_checked < 4 && - png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) - png_error(png_ptr, "Not a PNG file"); - - else - png_error(png_ptr, "PNG file corrupted by ASCII conversion"); - } - - else if (png_ptr->sig_bytes >= 8) - png_ptr->process_mode = png_read_chunk_header; -} - -static void -png_push_crc_finish(png_structrp png_ptr) - /* CRC the remainder of the chunk data; png_struct::chunk_length must be the - * amount of data left to read excluding the CRC. - */ -{ - if (png_ptr->chunk_length != 0 && png_ptr->save_buffer_size != 0) - { - png_size_t save_size = png_ptr->save_buffer_size; - png_uint_32 skip_length = png_ptr->chunk_length; - - /* We want the smaller of 'skip_length' and 'save_buffer_size', but - * they are of different types and we don't know which variable has the - * fewest bits. Carefully select the smaller and cast it to the type of - * the larger - this cannot overflow. Do not cast in the following test - * - it will break on either 16 or 64 bit platforms. - */ - if (skip_length < save_size) - save_size = (png_size_t)/*SAFE*/skip_length; - - else - skip_length = (png_uint_32)/*SAFE*/save_size; - - png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); - - png_ptr->chunk_length -= skip_length; - png_ptr->buffer_size -= save_size; - png_ptr->save_buffer_size -= save_size; - png_ptr->save_buffer_ptr += save_size; - } - - if (png_ptr->chunk_length != 0 && png_ptr->current_buffer_size != 0) - { - png_size_t save_size = png_ptr->current_buffer_size; - png_uint_32 skip_length = png_ptr->chunk_length; - - /* We want the smaller of 'skip_length' and 'current_buffer_size', here, - * the same problem exists as above and the same solution. - */ - if (skip_length < save_size) - save_size = (png_size_t)/*SAFE*/skip_length; - - else - skip_length = (png_uint_32)/*SAFE*/save_size; - - png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); - - png_ptr->chunk_length -= skip_length; - png_ptr->buffer_size -= save_size; - png_ptr->current_buffer_size -= save_size; - png_ptr->current_buffer_ptr += save_size; - } - - if (png_ptr->chunk_length == 0) - { - PNG_PUSH_SAVE_BUFFER_IF_LT(4) - png_crc_finish(png_ptr, 0); - png_ptr->process_mode = png_read_chunk_header; - } -} - -static void -png_push_read_unknown(png_structrp png_ptr, png_inforp info_ptr) -{ - /* Handle an unknown chunk. All the data is available but it may not - * all be in the same buffer. png_handle_unknown needs the chunk data in - * just one buffer. - */ - png_bytep buffer; - png_uint_32 chunk_length = png_ptr->chunk_length; - - if (png_ptr->save_buffer_size > 0) - { - png_size_t save_size = png_ptr->save_buffer_size; - - if (save_size < chunk_length) - { - /* Copy the current_buffer_ptr data into the save buffer. */ - png_push_save_buffer_partial(png_ptr, chunk_length - save_size); - save_size = chunk_length; - } - - buffer = png_ptr->save_buffer_ptr; - png_ptr->save_buffer_ptr = buffer+chunk_length; - png_ptr->save_buffer_size = save_size-chunk_length; - png_ptr->buffer_size -= chunk_length; - affirm(png_ptr->buffer_size >= 4); - } - - else - { - affirm(png_ptr->current_buffer_size >= chunk_length+4); - buffer = png_ptr->current_buffer_ptr; - png_ptr->current_buffer_ptr = buffer+chunk_length; - png_ptr->current_buffer_size -= chunk_length; - png_ptr->buffer_size -= chunk_length; - } - - /* Now check the CRC, before attempting the unknown handling. */ - png_calculate_crc(png_ptr, buffer, chunk_length); - png_crc_finish(png_ptr, 0); -# ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - png_handle_unknown(png_ptr, info_ptr, buffer); -# else /* !READ_UNKNOWN_CHUNKS */ - PNG_UNUSED(info_ptr) -# endif /* !READ_UNKNOWN_CHUNKS */ - png_ptr->process_mode = png_read_chunk_header; -} - -static void -png_push_have_row(png_structrp png_ptr, png_bytep row) -{ - if (png_ptr->row_fn != NULL) - { - png_uint_32 row_number = png_ptr->row_number; - png_byte pass = png_ptr->pass; - - if (png_ptr->interlaced) - { - /* If the row de-interlace is not being done by PNG this wacky API - * delivers the row number in the pass to the caller. We know that - * if we get here the row exists, so the number is just one less than - * the height of an interlaced image with just the rows up to this - * one: - */ -# ifdef PNG_READ_INTERLACING_SUPPORTED - if (!png_ptr->do_interlace) -# endif /* READ_INTERLACING */ - { - affirm(PNG_ROW_IN_INTERLACE_PASS(row_number, pass) && row != NULL); - row_number = PNG_PASS_ROWS(row_number+1, pass); - affirm(row_number > 0); - --row_number; - } - } - - (*(png_ptr->row_fn))(png_ptr, row, row_number, pass); - } -} - -static void -png_push_read_sync_zstream(png_structp png_ptr, png_bytep *bufferp, - size_t *buffer_lengthp) - /* Synchronize the png_struct progressive read buffer - * {*bufferp,*buffer_lengthp} with png_struct::zstream.next_in, on the - * assumption that the zstream had previously been set up with *bufferp. - */ -{ - png_bytep original_start = *bufferp; - png_alloc_size_t bytes_consumed = png_ptr->zstream.next_in - original_start; - - affirm(buffer_lengthp != NULL); - - /* Calculate the CRC for the consumed data: */ - png_calculate_crc(png_ptr, original_start, bytes_consumed); - - /* Update the buffer pointers and the various lengths: */ - *bufferp = original_start + bytes_consumed; /* == png_ptr->zstream.next_in */ - - affirm(bytes_consumed <= *buffer_lengthp); - *buffer_lengthp -= (size_t)/*SAFE*/bytes_consumed; - - affirm(bytes_consumed <= png_ptr->chunk_length); - png_ptr->chunk_length -= (png_uint_32)/*SAFE*/bytes_consumed; - - affirm(bytes_consumed <= png_ptr->buffer_size); - png_ptr->buffer_size -= (size_t)/*SAFE*/bytes_consumed; -} - -static void -png_push_read_process_IDAT(png_structp png_ptr, png_bytep *bufferp, - size_t *buffer_lengthp) - /* If the the *buffer_lengthp parameter is NULL there is no more input, - * png_struct::mode & PNG_AFTER_IDAT must be set at this point. - */ -{ - png_alloc_size_t buffer_length; - - if (buffer_lengthp != NULL) - buffer_length = *buffer_lengthp; - - else /* end of IDAT */ - { - /* SECURITY: if this affirm fails the code would go into an infinite loop; - * see the handling of avail_in == 0 in png_inflate_IDAT. - */ - affirm(png_ptr->mode & PNG_AFTER_IDAT); - buffer_length = 0; - } - - /* This routine attempts to process all the data it has been given before - * returning, calling the row callback as required to handle the - * uncompressed results. - * - * If a pause happens during processing (png_ptr->buffer_size is set to 0) - * or the end of the chunk is encountered the routine may return without - * handling all the input data. - */ - if (buffer_length > png_ptr->chunk_length) - { - buffer_length = png_ptr->chunk_length; - - /* This works because the last part of a 'skip' is to read and check the - * CRC, then the process mode is set to png_read_chunk_header. - */ - if (buffer_length == 0) - png_ptr->process_mode = png_read_chunk_skip; - } - - /* It is possble for buffer_length to be zero at this point if the stream - * caontains a zero length IDAT. This is handled below. - */ - png_ptr->zstream.next_in = *bufferp; - - while (buffer_length > 0 || buffer_lengthp == NULL) - { - if (buffer_length >= ZLIB_IO_MAX) - { - png_ptr->zstream.avail_in = ZLIB_IO_MAX; - buffer_length -= ZLIB_IO_MAX; - } - - else - { - png_ptr->zstream.avail_in = (uInt)/*SAFE*/buffer_length; - buffer_length = 0; - } - - /* The last row may already have been processed. - * - * row_number is the *current* row number in the range 0..height-1. It is - * updated only by the call to png_read_process_IDAT that follows the call - * which returns something other than png_row_incomplete. - * - * At the end of the image that call must *NOT* be made; png_process_IDAT - * must not be called after the last row. png_struct::zstream_eod is set - * below to allow this condition to be detected. - * - * Note that png_read_process_IDAT handles errors in the LZ compressed - * data (i.e. the cases where png_struct::zstream_error is set) by filling - * the rows in with 0, which is a safe value, so keep calling it until we - * reach the end of the image. - */ - if (!png_ptr->zstream_eod) - { - png_bytep row_buffer = NULL; - png_row_op row_op = - png_read_process_IDAT(png_ptr, NULL, NULL, 1/*save row*/); - - if (row_op != png_row_incomplete) - { - /* Have a complete row, so check for end-of-image; do this here - * because interlaced images can end on earlier rows or passes but - * we keep calling png_read_process_IDAT until it updates row_number - * to the last row of the actual image: - */ - if (png_ptr->row_number+1 >= png_ptr->height && - (!png_ptr->interlaced || png_ptr->pass == 6)) - png_ptr->zstream_eod = 1; /* end of image */ - } - - switch (row_op) - { - case png_row_incomplete: - /* more IDAT data needed for row */ - debug(png_ptr->zstream.avail_in == 0); - - /* png_inflate_IDAT is supposed to handle this and recognize a - * call with 0 avail_in as end of stream: - */ - affirm(buffer_lengthp != NULL); - continue; - - case png_row_process: - /* If a row was obtained after the end of the IDAT this was done - * by fabricating data, ensure this is reported, else there is a - * security issue; normally libpng does a png_error in this - * case, even if the error is ignored png_struct::zstream_error - * should be set so somehow the error wasn't noticed! - */ - affirm(buffer_lengthp != NULL || png_ptr->zstream_error); - - /* png_struct::transformed_row contains a complete, transformed, - * row; this is processed in both 'sparkle' and 'block' mode. - */ -# ifdef PNG_TRANSFORM_MECH_SUPPORTED - row_buffer = png_ptr->transformed_row; - if (row_buffer == NULL) -# endif /* TRANSFORM_MECH */ - row_buffer = png_ptr->row_buffer; - break; - - case png_row_repeat: - /* row not in this pass, but the existing row in - * png_struct::transformed_row may be used, this is only required - * if the 'block' or 'rectangle' mode of display is done and - * libpng is handling the de-interlace; when the app does it it - * only see the real rows. - */ -# ifdef PNG_READ_INTERLACING_SUPPORTED - if (png_ptr->do_interlace) - { -# ifdef PNG_TRANSFORM_MECH_SUPPORTED - row_buffer = png_ptr->transformed_row; - if (row_buffer == NULL) -# endif /* TRANSFORM_MECH */ - row_buffer = png_ptr->row_buffer; - break; - } -# endif /* READ_INTERLACING */ - continue; - - case png_row_skip: - /* row not in pass and no appropriate data; skip this row, - * nothing more need be done, except the read_row_fn. The use - * of 'NULL' to mean this row doesn't contribute to the output - * is historical and not documented; - */ -# ifdef PNG_READ_INTERLACING_SUPPORTED - if (png_ptr->do_interlace) - break; -# endif /* READ_INTERLACING */ - continue; - - default: - impossible("not reached"); - } - - /* Here if there is a row to process. */ - - /* Now adjust the buffer pointers before calling png_push_have_row - * because the callback might call png_process_data_pause and that - * calls png_push_save_row. (Yes, this is insane; it was forced on - * libpng by writers of an external app that ignored the instructions - * not to fiddle with the insides of png_struct in version 1.4. It - * will probably be fixed here before 1.7.0 is released by removing - * the need for the save buffer entirely.) - */ - if (buffer_lengthp != NULL) - png_push_read_sync_zstream(png_ptr, bufferp, buffer_lengthp); - - /* Process one row: */ - png_push_have_row(png_ptr, row_buffer); - - /* The buffer pointer and size may have changed at this point, - * so everything needs to be reloaded if we can continue reading. - */ - if (buffer_lengthp != NULL) /* not at end of IDATs */ - { - if (png_ptr->chunk_length == 0) - png_ptr->process_mode = png_read_chunk_skip; - - /* If the buffer_size has been set to zero more input is required, - * this may be a 'pause', and if the specific input buffer being - * processed has been exhaused then more input is also required. - * Otherwise we can keep going, however the input buffer may have - * been changed by the app callback, so do a complete reload: - */ - else if (png_ptr->buffer_size > 0 && *buffer_lengthp > 0) - png_push_read_process_IDAT(png_ptr, bufferp, buffer_lengthp); - - return; - } - - /* If we can't continue reading because there is no more IDAT data this - * may still be a pause. - */ - if (png_ptr->buffer_size == 0) - return; - - /* Else continue, with zero data: */ - continue; - } - - affirm(png_ptr->zstream_eod); - - if (png_ptr->zowner == 0 || png_read_finish_IDAT(png_ptr)) - { - /* The zlib stream has ended, there may still be input data in - * png_ptr->zstream.next_in, restore this. - */ - debug(png_ptr->zowner == 0 && png_ptr->zstream_ended); - - if (buffer_lengthp != NULL) - { - png_push_read_sync_zstream(png_ptr, bufferp, buffer_lengthp); - - /* If the chunk_length is greater than 0 then there is extra data, - * report this once. Notice that for IDAT after the end of the - * stream we keep coming to this point and doing the skip. - */ - if (png_ptr->chunk_length > 0) - { - if (!png_ptr->zstream_error) - { - png_chunk_benign_error(png_ptr, - "too much IDAT data (progressive read)"); - png_ptr->zstream_error = 1; - } - } - - /* In any case CRC the chunk, skipping any unneeded data: */ - png_ptr->process_mode = png_read_chunk_skip; - } - return; - } - - /* else more input is required */ - /* NOTE: this test only fires on a small (less than 5 byte) IDAT chunk - * which just contains the LZ EOF and the Adler32 CRC. - */ - affirm(png_ptr->zowner == png_IDAT && !png_ptr->zstream_ended); - } - - /* At this point all the input has been consumed, however the CRC has not - * been done and the three length fields in png_struct, *buffer_lengthp, - * buffer_size and chunk_length, all need updating. - */ - png_push_read_sync_zstream(png_ptr, bufferp, buffer_lengthp); -} - -static void -png_push_read_IDAT(png_structrp png_ptr) -{ - if (png_ptr->save_buffer_size > 0) - { - png_push_read_process_IDAT(png_ptr, &png_ptr->save_buffer_ptr, - &png_ptr->save_buffer_size); - - /* This is a slight optimization; normally when the process mode changes - * there will still be something in the buffer: - */ - if (png_ptr->save_buffer_size > 0) - return; - - /* Check for a change in process mode or an application pause before - * checking the current input buffer. This is only rarely reached. - */ - if (png_ptr->process_mode != png_read_chunk_process_part || - png_ptr->buffer_size == 0) - return; - } - - if (png_ptr->current_buffer_size > 0) - png_push_read_process_IDAT(png_ptr, &png_ptr->current_buffer_ptr, - &png_ptr->current_buffer_size); -} - -static void -png_push_finish_IDAT(png_structrp png_ptr) - /* Called once when the first chunk after IDAT is seen. */ -{ - /* All of the IDAT data has been processed, however the stream may have - * been truncated and the image rows may not all have been processed. - * Clean up here (this doesn't read anything.) - * - * 1.7.0: this attempts some measure of compatibility with the sequential - * API, if the IDAT is truncated and the resultant error reporting doesn't - * abort the read the image is filled in using zeros of pixel data. This - * actually happens inside png_inflate_IDAT (pngrutil.c) when called with - * z_stream::avail_in == 0. - */ - while (png_ptr->zowner == png_IDAT) - { - png_byte b = 0, *pb = &b; - - png_push_read_process_IDAT(png_ptr, &pb, NULL/*end of IDAT*/); - - if (png_ptr->zowner == 0) - break; - - if (png_ptr->buffer_size == 0) /* pause */ - return; - } - - png_ptr->process_mode = png_check_bits(png_ptr, png_ptr->process_mode >> 4, - 4); -} - -static void -png_push_have_info(png_structrp png_ptr, png_inforp info_ptr) -{ - if (png_ptr->info_fn != NULL) - (*(png_ptr->info_fn))(png_ptr, info_ptr); -} - -static void -png_push_have_end(png_structrp png_ptr, png_inforp info_ptr) -{ - if (png_ptr->end_fn != NULL) - (*(png_ptr->end_fn))(png_ptr, info_ptr); -} - -static void -png_push_read_chunk_header(png_structrp png_ptr, png_infop info_ptr) -{ - /* Called to read a new chunk header and work out how to handle the remainder - * of the data. - */ - unsigned int mode; /* mode prior to the header */ - png_byte chunk_header[8]; - - PNG_PUSH_SAVE_BUFFER_IF_LT(8) - png_push_fill_buffer(png_ptr, chunk_header, 8); - png_ptr->chunk_length = png_get_uint_31(png_ptr, chunk_header); - png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_header+4); - png_reset_crc(png_ptr, chunk_header+4); - png_check_chunk_name(png_ptr, png_ptr->chunk_name); - png_check_chunk_length(png_ptr, png_ptr->chunk_length); - mode = png_ptr->mode; - png_ptr->process_mode = png_check_bits(png_ptr, - png_read_chunk+png_find_chunk_op(png_ptr), 4); - - /* Is this the first IDAT chunk? */ - if ((mode ^ png_ptr->mode) & PNG_HAVE_IDAT) - png_push_have_info(png_ptr, info_ptr); - - /* Is it the chunk after the last IDAT chunk? */ - else if (((mode ^ png_ptr->mode) & PNG_AFTER_IDAT) != 0) - png_ptr->process_mode = png_check_bits(png_ptr, - (png_ptr->process_mode << 4) + png_read_end_IDAT, 8); -} - -/* What we do with the incoming data depends on what we were previously - * doing before we ran out of data... - */ -static void -png_process_some_data(png_structrp png_ptr, png_inforp info_ptr) -{ - if (png_ptr == NULL) - return; - - switch (png_ptr->process_mode & 0xf) - { - case png_read_signature: - png_push_read_signature(png_ptr, info_ptr); - return; - - case png_read_chunk_header: - png_push_read_chunk_header(png_ptr, info_ptr); - return; - - case png_read_chunk_skip: - png_push_crc_finish(png_ptr); - return; - - case png_read_chunk_unknown: - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_push_read_unknown(png_ptr, info_ptr); - return; - - case png_read_chunk_process_all: - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_chunk(png_ptr, info_ptr); - - if (png_ptr->mode & PNG_HAVE_IEND) - { - png_ptr->process_mode = png_read_done; - png_push_have_end(png_ptr, info_ptr); - png_ptr->buffer_size = 0; - } - - else - png_ptr->process_mode = png_read_chunk_header; - return; - - case png_read_chunk_process_part: - debug(png_ptr->chunk_name == png_IDAT && - (png_ptr->mode & PNG_HAVE_IDAT) && - !(png_ptr->mode & PNG_AFTER_IDAT)); - - if (png_ptr->zowner == 0 && !png_ptr->zstream_ended) /* first time */ - png_read_start_IDAT(png_ptr); - - png_push_read_IDAT(png_ptr); - return; - - case png_read_end_IDAT: - png_push_finish_IDAT(png_ptr); - return; - - case png_read_done: - png_app_error(png_ptr, "read beyond end of stream"); - png_ptr->buffer_size = 0; - return; - - default: - impossible("invalid process mode"); - } -} - -void PNGAPI -png_process_data(png_structrp png_ptr, png_inforp info_ptr, - png_bytep buffer, png_size_t buffer_size) -{ - if (png_ptr == NULL || info_ptr == NULL) - return; - - png_push_restore_buffer(png_ptr, buffer, buffer_size); - - while (png_ptr->buffer_size) - png_process_some_data(png_ptr, info_ptr); -} - -void PNGAPI -png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr, - png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, - png_progressive_end_ptr end_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->info_fn = info_fn; - png_ptr->row_fn = row_fn; - png_ptr->end_fn = end_fn; - - png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer); -} - -png_voidp PNGAPI -png_get_progressive_ptr(png_const_structrp png_ptr) -{ - if (png_ptr == NULL) - return (NULL); - - return png_ptr->io_ptr; -} -#endif /* PROGRESSIVE_READ */ diff --git a/ext/libpng17/pngpriv.h b/ext/libpng17/pngpriv.h deleted file mode 100644 index 8c5496ec18..0000000000 --- a/ext/libpng17/pngpriv.h +++ /dev/null @@ -1,2270 +0,0 @@ - -/* pngpriv.h - private declarations for use inside libpng - * - * Last changed in libpng 1.7.0 [(PENDING RELEASE)] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* The symbols declared in this file (including the functions declared - * as extern) are PRIVATE. They are not part of the libpng public - * interface, and are not recommended for use by regular applications. - * Some of them may become public in the future; others may stay private, - * change in an incompatible way, or even disappear. - * Although the libpng users are not forbidden to include this header, - * they should be well aware of the issues that may arise from doing so. - */ - -#ifndef PNGPRIV_H -#define PNGPRIV_H - -/* Feature Test Macros. The following are defined here to ensure that correctly - * implemented libraries reveal the APIs libpng needs to build and hide those - * that are not needed and potentially damaging to the compilation. - * - * Feature Test Macros must be defined before any system header is included (see - * POSIX 1003.1 2.8.2 "POSIX Symbols." - * - * These macros only have an effect if the operating system supports either - * POSIX 1003.1 or C99, or both. On other operating systems (particularly - * Windows/Visual Studio) there is no effect; the OS specific tests below are - * still required (as of 2011-05-02.) - */ -#define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */ - -#ifndef PNG_VERSION_INFO_ONLY -/* Keep standard libraries at the top of this file */ - -/* Standard library headers not required by png.h: */ -# include -# include - -/* For headers only required with some build configurations see the lines after - * pnglibconf.h is included! - */ - -#endif /* VERSION_INFO_ONLY */ - -#define PNGLIB_BUILD /*libpng is being built, not used*/ - -/* If HAVE_CONFIG_H is defined during the build then the build system must - * provide an appropriate "config.h" file on the include path. The header file - * must provide definitions as required below (search for "HAVE_CONFIG_H"); - * see configure.ac for more details of the requirements. The macro - * "PNG_NO_CONFIG_H" is provided for maintainers to test for dependencies on - * 'configure'; define this macro to prevent the configure build including the - * configure generated config.h. Libpng is expected to compile without *any* - * special build system support on a reasonably ANSI-C compliant system. - */ -#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H) -# include - - /* Pick up the definition of 'restrict' from config.h if it was read: */ -# define PNG_RESTRICT restrict -#endif - -/* To support symbol prefixing it is necessary to know *before* including png.h - * whether the fixed point (and maybe other) APIs are exported, because if they - * are not internal definitions may be required. This is handled below just - * before png.h is included, but load the configuration now if it is available. - */ -#ifndef PNGLCONF_H -# include "pnglibconf.h" -#endif - -/* Local renames may change non-exported API functions from png.h */ -#if defined(PNG_PREFIX) && !defined(PNGPREFIX_H) -# include "pngprefix.h" -#endif - -#ifdef PNG_USER_CONFIG -# include "pngusr.h" - /* These should have been defined in pngusr.h */ -# ifndef PNG_USER_PRIVATEBUILD -# define PNG_USER_PRIVATEBUILD "Custom libpng build" -# endif -# ifndef PNG_USER_DLLFNAME_POSTFIX -# define PNG_USER_DLLFNAME_POSTFIX "Cb" -# endif -#endif - -#ifndef PNG_VERSION_INFO_ONLY -/* Additional standard libaries required in certain cases, put only standard - * ANSI-C89 headers here. If not available, or non-functional, the problem - * should be fixed by writing a wrapper for the header and the file on your - * include path. - */ -#if defined(PNG_sCAL_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) - /* png.c requires the following ANSI-C constants if the conversion of - * floating point to ASCII is implemented therein: - * - * DBL_MIN_10_EXP Minimum negative integer such that 10^integer is a - * normalized (double) value. - * DBL_DIG Maximum number of decimal digits (can be set to any constant) - * DBL_MIN Smallest normalized fp number (can be set to an arbitrary value) - * DBL_MAX Maximum floating point number (can be set to an arbitrary value) - */ -# include -#endif /* sCAL && FLOATING_POINT */ - -#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) ||\ - defined(PNG_FLOATING_POINT_SUPPORTED) - /* ANSI-C90 math functions are required. Full compliance with the standard - * is probably not a requirement, but the functions must exist and be - * declared in - */ -# include -#endif /* FLOATING_ARITHMETIC || FLOATING_POINT */ - -#endif /* VERSION_INFO_ONLY */ - -/* Is this a build of a DLL where compilation of the object modules requires - * different preprocessor settings to those required for a simple library? If - * so PNG_BUILD_DLL must be set. - * - * If libpng is used inside a DLL but that DLL does not export the libpng APIs - * PNG_BUILD_DLL must not be set. To avoid the code below kicking in build a - * static library of libpng then link the DLL against that. - */ -#ifndef PNG_BUILD_DLL -# ifdef DLL_EXPORT - /* This is set by libtool when files are compiled for a DLL; libtool - * always compiles twice, even on systems where it isn't necessary. Set - * PNG_BUILD_DLL in case it is necessary: - */ -# define PNG_BUILD_DLL -# else -# ifdef _WINDLL - /* This is set by the Microsoft Visual Studio IDE in projects that - * build a DLL. It can't easily be removed from those projects (it - * isn't visible in the Visual Studio UI) so it is a fairly reliable - * indication that PNG_IMPEXP needs to be set to the DLL export - * attributes. - */ -# define PNG_BUILD_DLL -# else -# ifdef __DLL__ - /* This is set by the Borland C system when compiling for a DLL - * (as above.) - */ -# define PNG_BUILD_DLL -# else - /* Add additional compiler cases here. */ -# endif -# endif -# endif -#endif /* Setting PNG_BUILD_DLL if required */ - -/* See pngconf.h for more details: the builder of the library may set this on - * the command line to the right thing for the specific compilation system or it - * may be automagically set above (at present we know of no system where it does - * need to be set on the command line.) - * - * PNG_IMPEXP must be set here when building the library to prevent pngconf.h - * setting it to the "import" setting for a DLL build. - */ -#ifndef PNG_IMPEXP -# ifdef PNG_BUILD_DLL -# define PNG_IMPEXP PNG_DLL_EXPORT -# else - /* Not building a DLL, or the DLL doesn't require specific export - * definitions. - */ -# define PNG_IMPEXP -# endif -#endif - -/* No warnings for private or deprecated functions in the build: */ -#ifndef PNG_DEPRECATED -# define PNG_DEPRECATED -#endif -#ifndef PNG_PRIVATE -# define PNG_PRIVATE -#endif - -/* Symbol preprocessing support. - * - * To enable listing global, but internal, symbols the following macros should - * always be used to declare an extern data or function object in this file. - */ -#ifndef PNG_INTERNAL_DATA -# define PNG_INTERNAL_DATA(type, name, array) extern type name array -#endif - -#ifndef PNG_INTERNAL_FUNCTION -# define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\ - extern PNG_FUNCTION(type, name, args, PNG_EMPTY attributes) -#endif - -#ifndef PNG_INTERNAL_CALLBACK -# define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\ - extern PNG_FUNCTION(type, (PNGCBAPI name), args, PNG_EMPTY attributes) -#endif - -/* If floating or fixed point APIs are disabled they may still be compiled - * internally. To handle this make sure they are declared as the appropriate - * internal extern function (otherwise the symbol prefixing stuff won't work and - * the functions will be used without definitions.) - * - * NOTE: although all the API functions are declared here they are not all - * actually built! Because the declarations are still made it is necessary to - * fake out types that they depend on. - */ -#ifndef PNG_FP_EXPORT -# ifndef PNG_FLOATING_POINT_SUPPORTED -# define PNG_FP_EXPORT(ordinal, type, name, args)\ - PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY); -# ifndef PNG_VERSION_INFO_ONLY - typedef struct png_incomplete png_double; - typedef png_double* png_doublep; - typedef const png_double* png_const_doublep; - typedef png_double** png_doublepp; -# endif -# endif -#endif -#ifndef PNG_FIXED_EXPORT -# ifndef PNG_FIXED_POINT_SUPPORTED -# define PNG_FIXED_EXPORT(ordinal, type, name, args)\ - PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY); -# endif -#endif - -/* Include png.h here to get the version info and other macros, pngstruct.h and - * pnginfo.h are included later under the protection of !PNG_VERSION_INFO_ONLY - */ -#include "png.h" - -/* pngconf.h does not set PNG_DLL_EXPORT unless it is required, so: */ -#ifndef PNG_DLL_EXPORT -# define PNG_DLL_EXPORT -#endif - -/* This is a global switch to set the compilation for an installed system - * (a release build). It can be set for testing debug builds to ensure that - * they will compile when the build type is switched to RC or STABLE, the - * default is just to use PNG_LIBPNG_BUILD_BASE_TYPE. Set this in CPPFLAGS - * with either: - * - * -DPNG_RELEASE_BUILD Turns on the release compile path - * -DPNG_RELEASE_BUILD=0 Turns it off - * or in your pngusr.h with - * #define PNG_RELEASE_BUILD=1 Turns on the release compile path - * #define PNG_RELEASE_BUILD=0 Turns it off - */ -#ifndef PNG_RELEASE_BUILD -# define PNG_RELEASE_BUILD (PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC) -#endif - -/* General purpose macros avoid the need to put #if PNG_RELEASE_BUILD - * macro blocks around function declarations and definitions when the - * parameter number varies. Using these results in slightly cleaner code. - */ -#if PNG_RELEASE_BUILD -# define only_rel(text) text -# define only_deb(text) -# define param_rel(param) param, -# define param_deb(param) -#else -# define only_rel(text) -# define only_deb(text) text -# define param_rel(param) -# define param_deb(param) param, -#endif - -/* The affirm mechanism results in a minimal png_error() in released versions - * ('STABLE' versions) and a more descriptive PNG_ABORT in all other cases, - * when the "condition" is false (zero). If "condition" is true (nonzero), - * then the affirm mechanism does nothing. - * - * The PNG_RELEASE_BUILD macro, defined above, controls the behavior of - * 'affirm': if set to 1 affirm will call png_error (or png_err) rather than - * abort. The png_error text is the minimal (file location) text in this case, - * if it is produced. This flag indicates a STABLE (or RC) build. - * - * The macros rely on the naming convention throughout this code - png_ptr - * exists and is of type png_const_structrp or a compatible type - and the - * presence in each file of a uniquely defined macro PNG_SRC_FILE; a number - * indicating which file this is (this is to save space in released versions). - * - * 'affirm' is intended to look like the ANSI-C macro; note that - * this macro can coexist with the assert macro if is - * included. - * - * PNG_SRC_LINE is the position of the affirm macro. There are currently 15 - * main source files (4 bits) and the biggest (pngrtran.c) has more than 4095 - * lines (12 bits). However, to ensure the number will fit into 16-bits in the - * future and to allow hardware files to use affirm, the encoding is a bit-wise - * encoding based on the current number of lines. - * - * 'debug' is a version of 'affirm' that is completely removed from RELEASE - * builds. This is used when either an unexpected condition is completely - * handled or when it can't be handled even by png_error, for example after a - * memory overwrite. - * - * UNTESTED is used to mark code that has not been tested; it causes an assert - * if the code is executed and (therefore) tested. UNTESTED should not remain - * in release candidate code. - * - * PNG_AFFIRM_TEXT is set to 1 if affirm text should be produced, either - * the minimal text or, if PNG_RELEASE_BUILD is 0, the more verbose text - * including the 'condition' string. This value depends on whether the - * build supports an appropriate way of outputting the message. - * - * Note that PNG_AFFIRM_TEXT is not configurable but is worked out here: this - * is just the affirm code; there's no reason to allow configuration of this - * option. - */ -#if PNG_RELEASE_BUILD ?\ - (defined PNG_ERROR_TEXT_SUPPORTED) :\ - (defined PNG_WARNINGS_SUPPORTED) || (defined PNG_CONSOLE_IO_SUPPORTED) -# define PNG_AFFIRM_TEXT 1 -#else -# define PNG_AFFIRM_TEXT 0 -#endif /* PNG_AFFIRM_TEXT definition */ - -#define PNG_SRC_LINE (PNG_SRC_FILE + __LINE__) - -/* png_affirmpp and png_impossiblepp are macros to make the correct call to the - * png_affirm function; these macros do not assume that the png_structp is - * called png_ptr. - */ -#if PNG_RELEASE_BUILD -# define png_affirmpp(pp, cond)\ - do\ - if (!(cond)) png_affirm(pp, PNG_SRC_LINE);\ - while (0) -# define png_affirmexp(pp, cond)\ - ((cond) ? (void)0 : png_affirm(pp, PNG_SRC_LINE)) -# define png_handled(pp, m) ((void)0) -# define png_impossiblepp(pp, reason) png_affirm(pp, PNG_SRC_LINE) - -# define debug(cond) do {} while (0) -# define debug_handled(cond) do {} while (0) -# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC - /* Make sure there are no 'UNTESTED' macros in released code: */ -// # define UNTESTED libpng untested code -# define UNTESTED -# endif -# define NOT_REACHED do {} while (0) -#else -# define png_affirmpp(pp, cond)\ - do\ - if (!(cond)) png_affirm(pp, #cond, PNG_SRC_LINE);\ - while (0) -# define png_affirmexp(pp, cond)\ - ((cond) ? (void)0 : png_affirm(pp, #cond, PNG_SRC_LINE)) -# define png_handled(pp, m) (png_handled_affirm((pp), (m), PNG_SRC_LINE)) -# define png_impossiblepp(pp, reason) png_affirm(pp, reason, PNG_SRC_LINE) - -# define debug(cond) png_affirmpp(png_ptr, cond) -# define debug_handled(cond)\ - do\ - if (!(cond)) png_handled(png_ptr, #cond);\ - while (0) -# define UNTESTED png_affirm(png_ptr, "untested code", PNG_SRC_LINE); -# define NOT_REACHED png_affirm(png_ptr, "NOT REACHED", PNG_SRC_LINE) -#endif - -#define affirm(cond) png_affirmpp(png_ptr, cond) -#define affirmexp(cond) png_affirmexp(png_ptr, cond) -#define handled(m) png_handled(png_ptr, (m)) -#define impossible(cond) png_impossiblepp(png_ptr, cond) -#define implies(a, b) debug(!(a) || (b)) - -/* The defines for PNG_SRC_FILE: */ -#define PNG_SRC_FILE_(f,lines) PNG_SRC_FILE_ ## f + lines - -#define PNG_SRC_FILE_png 0 -#define PNG_SRC_FILE_pngerror (PNG_SRC_FILE_png +8192) -#define PNG_SRC_FILE_pngget (PNG_SRC_FILE_pngerror +2048) -#define PNG_SRC_FILE_pngmem (PNG_SRC_FILE_pngget +2048) -#define PNG_SRC_FILE_pngpread (PNG_SRC_FILE_pngmem +1024) -#define PNG_SRC_FILE_pngread (PNG_SRC_FILE_pngpread +2048) -#define PNG_SRC_FILE_pngrio (PNG_SRC_FILE_pngread +8192) -#define PNG_SRC_FILE_pngrtran (PNG_SRC_FILE_pngrio +1024) -#define PNG_SRC_FILE_pngrutil (PNG_SRC_FILE_pngrtran +8192) -#define PNG_SRC_FILE_pngset (PNG_SRC_FILE_pngrutil +8192) -#define PNG_SRC_FILE_pngtrans (PNG_SRC_FILE_pngset +2048) -#define PNG_SRC_FILE_pngwio (PNG_SRC_FILE_pngtrans +4096) -#define PNG_SRC_FILE_pngwrite (PNG_SRC_FILE_pngwio +1024) -#define PNG_SRC_FILE_pngwtran (PNG_SRC_FILE_pngwrite +4096) -#define PNG_SRC_FILE_pngwutil (PNG_SRC_FILE_pngwtran +1024) - -#define PNG_SRC_FILE_arm_arm_init (PNG_SRC_FILE_pngwutil +8192) -#define PNG_SRC_FILE_arm_filter_neon_intrinsics\ - (PNG_SRC_FILE_arm_arm_init +1024) - -/* Add new files by changing the following line: */ -#define PNG_SRC_FILE_LAST (PNG_SRC_FILE_arm_filter_neon_intrinsics +1024) - -/* The following #define must list the files in exactly the same order as - * the above. - */ -#define PNG_FILES\ - PNG_apply(png)\ - PNG_apply(pngerror)\ - PNG_apply(pngget)\ - PNG_apply(pngmem)\ - PNG_apply(pngpread)\ - PNG_apply(pngread)\ - PNG_apply(pngrio)\ - PNG_apply(pngrtran)\ - PNG_apply(pngrutil)\ - PNG_apply(pngset)\ - PNG_apply(pngtrans)\ - PNG_apply(pngwio)\ - PNG_apply(pngwrite)\ - PNG_apply(pngwtran)\ - PNG_apply(pngwutil)\ - PNG_apply(arm_arm_init)\ - PNG_apply(arm_filter_neon_intrinsics)\ - PNG_end - -/* SECURITY and SAFETY: - * - * libpng is built with support for internal limits on image dimensions and - * memory usage. These are documented in scripts/pnglibconf.dfa of the - * source and recorded in the machine generated header file pnglibconf.h. - */ - -/* If you are running on a machine where you cannot allocate more - * than 64K of memory at once, uncomment this. While libpng will not - * normally need that much memory in a chunk (unless you load up a very - * large file), zlib needs to know how big of a chunk it can use, and - * libpng thus makes sure to check any memory allocation to verify it - * will fit into memory. - * - * zlib provides 'MAXSEG_64K' which, if defined, indicates the - * same limit and pngconf.h (already included) sets the limit - * if certain operating systems are detected. - */ -#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) -# define PNG_MAX_MALLOC_64K -#endif - -#ifndef PNG_UNUSED -/* Unused formal parameter warnings are silenced using the following macro - * which is expected to have no bad effects on performance (optimizing - * compilers will probably remove it entirely). Note that if you replace - * it with something other than whitespace, you must include the terminating - * semicolon. - */ -# define PNG_UNUSED(param) (void)param; -#endif - -/* This is a convenience for parameters which are not used in release - * builds. - */ -#define PNG_UNUSEDRC(param) only_rel(PNG_UNUSED(param)) - -/* Just a little check that someone hasn't tried to define something - * contradictory. - */ -#if (PNG_ZBUF_SIZE > 32768) && defined(PNG_MAX_MALLOC_64K) -# undef PNG_ZBUF_SIZE -# define PNG_ZBUF_SIZE 32768 -#endif - -/* If warnings or errors are turned off the code is disabled or redirected here. - * From 1.5.4 functions have been added to allow very limited formatting of - * error and warning messages - this code will also be disabled here. - */ -#ifdef PNG_WARNINGS_SUPPORTED -# define PNG_WARNING_PARAMETERS(p) png_warning_parameters p; -#else -# define png_warning_parameter(p,number,string) ((void)0) -# define png_warning_parameter_unsigned(p,number,format,value) ((void)0) -# define png_warning_parameter_signed(p,number,format,value) ((void)0) -# define png_formatted_warning(pp,p,message) ((void)(pp)) -# define PNG_WARNING_PARAMETERS(p) -#endif -#ifndef PNG_ERROR_TEXT_SUPPORTED -# define png_fixed_error(s1,s2) png_err(s1) -#endif - -/* C allows up-casts from (void*) to any pointer and (const void*) to any - * pointer to a const object. C++ regards this as a type error and requires an - * explicit, static, cast and provides the static_cast<> rune to ensure that - * const is not cast away. - */ -#ifdef __cplusplus -# define png_voidcast(type, value) static_cast(value) -# define png_upcast(type, value) static_cast(value) -# define png_constcast(type, value) const_cast(value) -# define png_aligncast(type, value) \ - static_cast(static_cast(value)) -# define png_aligncastconst(type, value) \ - static_cast(static_cast(value)) -#else -# define png_voidcast(type, value) (value) -# define png_upcast(type, value) ((type)(value)) -# define png_constcast(type, value) ((type)(value)) -# define png_aligncast(type, value) ((void*)(value)) -# define png_aligncastconst(type, value) ((const void*)(value)) -#endif /* __cplusplus */ - -/* Some fixed point APIs are still required even if not exported because - * they get used by the corresponding floating point APIs. This magic - * deals with this: - */ -#ifdef PNG_FIXED_POINT_SUPPORTED -# define PNGFAPI PNGAPI -#else -# define PNGFAPI /* PRIVATE */ -#endif - -/* These macros may need to be architecture dependent. */ -#define PNG_ALIGN_NONE 0 /* do not use data alignment */ -#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */ -#ifdef offsetof -# define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */ -#else -# define PNG_ALIGN_OFFSET -1 /* prevent the use of this */ -#endif -#define PNG_ALIGN_SIZE 3 /* use sizeof to determine alignment */ - -#ifndef PNG_ALIGN_TYPE - /* Default to using aligned access optimizations and requiring alignment to a - * multiple of the data type size. Override in a compiler specific fashion - * if necessary by inserting tests here: - */ -# define PNG_ALIGN_TYPE PNG_ALIGN_SIZE -#endif - -#if PNG_ALIGN_TYPE == PNG_ALIGN_SIZE - /* This is used because in some compiler implementations non-aligned - * structure members are supported, so the offsetof approach below fails. - * Set PNG_ALIGN_SIZE=0 for compiler combinations where unaligned access - * is good for performance. Do not do this unless you have tested the result - * and understand it. - */ -# define png_alignof(type) (sizeof (type)) -#else -# if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET -# define png_alignof(type) offsetof(struct{char c; type t;}, t) -# else -# if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS -# define png_alignof(type) (1) -# endif - /* Else leave png_alignof undefined to prevent use thereof */ -# endif -#endif - -/* This implicitly assumes alignment is always to a power of 2. */ -#ifdef png_alignof -# define png_isaligned(ptr, type)\ - ((((const char*)ptr-(const char*)0) & (png_alignof(type)-1)) == 0) -#else -# define png_isaligned(ptr, type) 0 -#endif - -/* Buffer alignment control. These #defines control how the buffers used during - * read are aligned and how big they are. - */ -#ifndef PNG_ROW_BUFFER_ALIGN_TYPE - /* The absolute minimum alignment for a row buffer is that required for - * png_uint_32 direct access. The #define is of a legal C type that can be - * used as the type in the definition of the first member of a C union; give - * a typedef name if in doubt. - */ -# define PNG_ROW_BUFFER_ALIGN_TYPE png_uint_32 -#endif /* !ROW_BUFFER_ALIGN_TYPE */ -#ifndef PNG_ROW_BUFFER_BYTE_ALIGN - /* This is the minimum size in bytes of the buffer used while processing - * parts of row. Except at the end of the row pixels will always be - * processed in blocks such that the block size is a multiple of this number - */ -# define PNG_ROW_BUFFER_BYTE_ALIGN\ - ((unsigned int)/*SAFE*/(sizeof (PNG_ROW_BUFFER_ALIGN_TYPE))) -#endif /* !ROW_BUFFER_BYTE_ALIGN */ -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED -# define PNG_MAX_PIXEL_BYTES 16U /* 4x32-bit channels */ -#else /* !READ_USER_TRANSFORM */ -# define PNG_MAX_PIXEL_BYTES 8U /* 4x16-bit channels */ -#endif /* !READ_USER_TRANSFORM */ -/* PNG_ROW_BUFFER_SIZE is a compile time constant for the size of the row - * buffer. The minimum size of 2048 bytes is intended to allow the buffer to - * hold a complete 256 entry color map of 64-bit (8-byte) pixels. This is a - * requirement at some points of the colormap handling code. - * - * The maximum size is intended to allow (unsigned int) indexing of the buffer, - * it only affects systems with a 16-bit unsigned value where it limits the - * maximum to 4096 bytes. - */ -#define PNG_MIN_ROW_BUFFER_SIZE\ - (PNG_MAX_PIXEL_BYTES * PNG_ROW_BUFFER_BYTE_ALIGN * 8U) -#define PNG_MAX_ROW_BUFFER_SIZE ((UINT_MAX / 16U) + 1U) -#ifndef PNG_ROW_BUFFER_SIZE -# define PNG_ROW_BUFFER_SIZE\ - (PNG_MIN_ROW_BUFFER_SIZE < 2048U ? 2048U : PNG_MIN_ROW_BUFFER_SIZE) -#endif /* ROW_BUFFER_SIZE */ - -/* End of memory model/platform independent support */ -/* End of 1.5.0beta36 move from pngconf.h */ - -/* CONSTANTS and UTILITY MACROS - * These are used internally by libpng and not exposed in the API - */ - -/* Various modes of operation. Note that after an init, mode is set to - * zero automatically when the structure is created. Three of these - * are defined in png.h because they need to be visible to applications - * that call png_set_unknown_chunk(). - */ -/* #define PNG_HAVE_IHDR 0x01 (defined as (int) in png.h) */ -/* #define PNG_HAVE_PLTE 0x02 (defined as (int) in png.h) */ -#define PNG_HAVE_IDAT 0x04U -/* #define PNG_AFTER_IDAT 0x08 (defined as (int) in png.h) */ -#define PNG_HAVE_IEND 0x10U -#define PNG_HAVE_PNG_SIGNATURE 0x20U - -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -/* See below for the definitions of the tables used in these macros */ -#define PNG_sRGB_FROM_LINEAR(pp, linear) png_check_byte(pp,\ - (png_sRGB_base[(linear)>>15] +\ - ((((linear)&0x7fffU)*png_sRGB_delta[(linear)>>15])>>12)) >> 8) - /* Given a value 'linear' in the range 0..255*65535 calculate the 8-bit sRGB - * encoded value with maximum error 0.646365. Note that the input is not a - * 16-bit value; it has been multiplied by 255! */ -#endif /* PNG_SIMPLIFIED_READ/WRITE */ - -/* Added to libpng-1.6.0: scale a 16-bit value in the range 0..65535 to 0..255 - * by dividing by 257 *with rounding*. This macro is exact for the given range. - * See the discourse in pngrtran.c png_do_scale_16_to_8. The values in the - * macro were established by experiment (modifying the added value). The macro - * has a second variant that takes a value already scaled by 255 and divides by - * 65535 - this has a maximum error of .502. Over the range 0..65535*65535 it - * only gives off-by-one errors and only for 0.5% (1 in 200) of the values. - */ -#define PNG_DIV65535(v24) (((v24) + 32895U) >> 16) -#define PNG_DIV257(v16) PNG_DIV65535((png_uint_32)(v16) * 255U) - -/* Added to libpng-1.2.6 JB - * Modified in libpng-1.7.0 to avoid the intermediate calculation overflow - * when: - * - * pixel_bits == 4: any width over 0x3FFFFFFEU overflows - * pixel_bits == 2: any width over 0x7FFFFFFCU overflows - * - * In both these cases any width results in a rowbytes that fits in 32 bits. - * The problem arose in previous versions because the calculation used was - * simply ((width x pixel-bit-depth)+7)/8. At the cost of more calculations - * on pixel_depth this avoids the problem. - */ -#define PNG_SHIFTOF(pixel_bits/*<8*/) \ - ( (pixel_bits) == 1 ? 3 : \ - ( (pixel_bits) == 2 ? 2 : \ - ( (pixel_bits) == 4 ? 1 : \ - 0/*force bytes*/ ) ) ) -#define PNG_ADDOF(pixel_bits/*<8*/) ((1U<= 8 ? \ - ((png_alloc_size_t)(width) * ((pixel_bits) >> 3)) : \ - (((png_alloc_size_t)(width) + PNG_ADDOF(pixel_bits)) >> \ - PNG_SHIFTOF(pixel_bits)) ) - -/* This macros, added in 1.7.0, makes it easy to deduce the number of channels - * and therefore the pixel depth from the color type. The PNG specification - * numbers are used in preference to the png.h constants to make it more clear - * why the macro works. - */ -#define PNG_COLOR_TYPE_CHANNELS(ct)\ - (((ct) & PNG_COLOR_MASK_PALETTE) ?\ - 1U : 1U+((ct) & 2U/*COLOR*/)+(((ct)>>2)&1U/*ALPHA*/)) -#define PNG_CHANNELS(ps) PNG_COLOR_TYPE_CHANNELS((ps).color_type) -#define PNG_PIXEL_DEPTH(ps) (PNG_CHANNELS(ps) * (ps).bit_depth) - -/* PNG_OUT_OF_RANGE returns true if value is outside the range - * ideal-delta..ideal+delta. Each argument is evaluated twice. - * "ideal" and "delta" should be constants, normally simple - * integers, "value" a variable. Added to libpng-1.2.6 JB - */ -#define PNG_OUT_OF_RANGE(value, ideal, delta) \ - ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) ) - -/* Handling of bit-field masks. Because the expression: - * - * bit_field & ~mask - * - * has implementation defined behavior in ANSI C-90 for many (int) values of - * 'mask' and because some of these are defined in png.h and passed in (int) - * parameters use of '~' has been expunged in libpng 1.7 and replaced by this - * macro, which is well defined in ANSI C-90 (there is a similar, 16-bit, - * version in pngstruct.h for the colorspace flags.) - */ -#define PNG_BIC_MASK(flags) (0xFFFFFFFFU - (flags)) - -/* Conversions between fixed and floating point, only defined if - * required (to make sure the code doesn't accidentally use float - * when it is supposedly disabled.) - */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -/* The floating point conversion can't overflow, though it can and - * does lose accuracy relative to the original fixed point value. - * In practice this doesn't matter because png_fixed_point only - * stores numbers with very low precision. The png_ptr and s - * arguments are unused by default but are there in case error - * checking becomes a requirement. - */ -#define png_float(png_ptr, fixed, s) (.00001 * (fixed)) - -/* The fixed point conversion performs range checking and evaluates - * its argument multiple times, so must be used with care. The - * range checking uses the PNG specification values for a signed - * 32 bit fixed point value except that the values are deliberately - * rounded-to-zero to an integral value - 21474 (21474.83 is roughly - * (2^31-1) * 100000). 's' is a string that describes the value being - * converted. - * - * NOTE: this macro will raise a png_error if the range check fails, - * therefore it is normally only appropriate to use this on values - * that come from API calls or other sources where an out of range - * error indicates a programming error, not a data error! - * - * NOTE: by default this is off - the macro is not used - because the - * function call saves a lot of code. - */ -#ifdef PNG_FIXED_POINT_MACRO_SUPPORTED -#define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\ - ((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s),0)) -#endif -/* else the corresponding function is defined below, inside the scope of the - * cplusplus test. - */ -#endif - -/* Gamma values (new at libpng-1.5.4): */ -#define PNG_GAMMA_MAC_OLD 151724 /* Assume '1.8' is really 2.2/1.45! */ -#define PNG_GAMMA_MAC_INVERSE 65909 -#define PNG_GAMMA_sRGB_INVERSE 45455 - -/* Almost everything below is C specific; the #defines above can be used in - * non-C code (so long as it is C-preprocessed) the rest of this stuff cannot. - */ -#ifndef PNG_VERSION_INFO_ONLY - -#include "pngstruct.h" -#include "pnginfo.h" - -/* Validate the include paths - the include path used to generate pnglibconf.h - * must match that used in the build, or we must be using pnglibconf.h.prebuilt: - */ -#if PNG_ZLIB_VERNUM != 0 && PNG_ZLIB_VERNUM != ZLIB_VERNUM -# error ZLIB_VERNUM != PNG_ZLIB_VERNUM \ - "-I (include path) error: see the notes in pngpriv.h" - /* This means that when pnglibconf.h was built the copy of zlib.h that it - * used is not the same as the one being used here. Because the build of - * libpng makes decisions to use inflateInit2 and inflateReset2 based on the - * zlib version number and because this affects handling of certain broken - * PNG files the -I directives must match. - * - * The most likely explanation is that you passed a -I in CFLAGS. This will - * not work; all the preprocessor directories and in particular all the -I - * directives must be in CPPFLAGS. - */ -#endif - -/* This is used for 16 bit gamma tables -- only the top level pointers are - * const; this could be changed: - */ -typedef const png_uint_16p * png_const_uint_16pp; - -/* Added to libpng-1.5.7: sRGB conversion tables */ -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -#ifdef PNG_SIMPLIFIED_READ_SUPPORTED -PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_table, [256]); - /* Convert from an sRGB encoded value 0..255 to a 16-bit linear value, - * 0..65535. This table gives the closest 16-bit answers (no errors). - */ -#endif - -PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_base, [512]); -PNG_INTERNAL_DATA(const png_byte, png_sRGB_delta, [512]); -#endif /* PNG_SIMPLIFIED_READ/WRITE */ - - -/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Internal functions; these are not exported from a DLL however because they - * are used within several of the C source files they have to be C extern. - * - * All of these functions must be declared with PNG_INTERNAL_FUNCTION. - */ -/* Affirm handling */ -PNG_INTERNAL_FUNCTION(void, png_affirm,(png_const_structrp png_ptr, - param_deb(png_const_charp condition) unsigned int position), PNG_NORETURN); - -#if !PNG_RELEASE_BUILD -PNG_INTERNAL_FUNCTION(void, png_handled_affirm,(png_const_structrp png_ptr, - png_const_charp message, unsigned int position), PNG_EMPTY); - /* This is not marked PNG_NORETURN because in PNG_RELEASE_BUILD it will - * disappear and control will pass through it. - */ -#endif /* !RELEASE_BUILD */ - -/* Character/byte range checking. */ -/* GCC complains about assignments of an (int) expression to a (char) even when - * it can readily determine that the value is in range. This makes arithmetic - * on (char) or (png_byte) values tedious. The warning is not issued by - * default, but libpng coding rules require no warnings leading to excessive, - * ridiculous and dangerous expressions of the form: - * - * = (char)(expression & 0xff) - * - * They are dangerous because they hide the warning, which might actually be - * valid, and therefore merely enable introduction of undetected overflows when - * code is modified. - * - * The following macros exist to reliably detect any overflow in non-release - * builds. The theory here is that we really want to know about overflows, not - * merely hide a basically flawed compiler warning by throwing unnecessary casts - * into the code. The warnings disappear in RC builds so that the released - * (STABLE) version just assigns the value (with, possibly, a warning if someone - * turns on the -Wconversion GCC warning.) - * - * Doing it this way ensures that the code meets two very important aims: - * - * 1) Overflows are detected in pre-release tests; previously versions of libpng - * have been released that really did have overflows in the RGB calculations. - * 2) In release builds GCC specific operations, which may reduce the ability - * of other compilers and even GCC to optimize the code, are avoided. - * - * There is one important extra consequence for pre-release code; it is - * performing a lot of checks in pixel arithmetic that the release code won't - * perform. As a consequence a build time option, RANGE_CHECK, is provided - * to allow the checks to be turned off in pre-release when building for - * performance testing. This is a standard "_SUPPORTED" option except that it - * cannot be set in the system configuration (pnglibconf.h, pnglibconf.dfa). - * - * A separate macro PNG_BYTE() is provided to safely convert an unsigned value - * to the PNG byte range 0..255. This handles the fact that, technically, - * an ANSI-C (unsigned char), hence a (png_byte), may be able to store values - * outside this range. Note that if you are building on a system where this is - * true libpng is almost certainly going to produce errors; it has never been - * tested on such a system. For the moment pngconf.h ensures that this will - * not happen. - * - * PNG_UINT_16 does the same thing for a 16-bit value passed in an (int) or - * (png_uint_32) (where checking is not expected.) - */ -#if !PNG_RELEASE_BUILD -# ifndef PNG_NO_RANGE_CHECK /* Turn off even in pre-release */ -# define PNG_RANGE_CHECK_SUPPORTED -# endif -#endif - -#ifdef PNG_RANGE_CHECK_SUPPORTED -PNG_INTERNAL_FUNCTION(unsigned int, png_bit_affirm,(png_const_structrp png_ptr, - unsigned int position, unsigned int u, unsigned int bits), PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(char, png_char_affirm,(png_const_structrp png_ptr, - unsigned int position, int c), PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(png_byte, png_byte_affirm,(png_const_structrp png_ptr, - unsigned int position, int b), PNG_EMPTY); - -#if INT_MAX >= 65535 -PNG_INTERNAL_FUNCTION(png_uint_16, png_u16_affirm,(png_const_structrp png_ptr, - unsigned int position, int u), PNG_EMPTY); -# define png_check_u16(pp, u) (png_u16_affirm((pp), PNG_SRC_LINE, (u))) -#else - /* (int) cannot hold a (png_uint_16) so the above function just won't - * compile correctly, for the moment just do this: - */ -# define png_check_u16(pp, u) (u) -#endif - -# define png_check_bits(pp, u, bits)\ - (((1U<<(bits))-1) & png_bit_affirm((pp), PNG_SRC_LINE, (u), (bits))) -# define png_check_char(pp, c) (png_char_affirm((pp), PNG_SRC_LINE, (c))) -# define png_check_byte(pp, b) (png_byte_affirm((pp), PNG_SRC_LINE, (b))) -# define PNG_BYTE(b) ((png_byte)((b) & 0xFFU)) -# define PNG_UINT_16(u) ((png_uint_16)((u) & 0xFFFFU)) -#elif !(defined PNG_REMOVE_CASTS) /* && !RANGE_CHECK */ -# define png_check_bits(pp, u, bits) (((1U<<(bits))-1U) & (u)) -# define png_check_char(pp, c) ((char)(c)) -# define png_check_byte(pp, b) ((png_byte)(b)) -# define png_check_u16(pp, u) ((png_uint_16)(u)) -# define PNG_BYTE(b) ((png_byte)((b) & 0xFFU)) -# define PNG_UINT_16(u) ((png_uint_16)((u) & 0xFFFFU)) -#else /* !RANGE_CHECK */ - /* This is somewhat trust-me-it-works: if PNG_REMOVE_CASTS is defined then - * the casts, which might otherwise change the values, are completely - * removed. Use this to test your compiler to see if it makes *any* - * difference (code size or speed.) Currently NOT SUPPORTED. - * - * It also makes the PNG_BYTE and PNG_UINT_16 macros do nothing either - * NOTE: this seems safe at present but might lead to unexpected results - * if someone writes code to depend on the truncation. - */ -# define png_check_bits(pp, u, bits) (u) -# define png_check_char(pp, c) (c) -# define png_check_byte(pp, b) (b) -# define png_check_u16(pp, u) (u) -# define PNG_BYTE(b) (b) -# define PNG_UINT_16(u) (u) -#endif /* RANGE_CHECK */ - -/* Safe calculation of a rowbytes value; does a png_error if the system limits - * are exceeded. - */ -PNG_INTERNAL_FUNCTION(png_alloc_size_t,png_calc_rowbytes, - (png_const_structrp png_ptr, unsigned int pixel_depth, - png_uint_32 row_width),PNG_EMPTY); - -/* Common code to calculate the maximum number of pixels to transform or filter - * at one time; controlled by PNG_ROW_BUFFER_SIZE above: - */ -PNG_INTERNAL_FUNCTION(unsigned int,png_max_pixel_block, - (png_const_structrp png_ptr),PNG_EMPTY); - -/* Copy the row in row_buffer; this is the non-interlaced copy used in both the - * read and write code. 'x_in_dest' specifies whether the 'x' applies to - * the destination (sp->dp[x], x_in_dest tru) or the source (sp[x]->dp, - * x_in_dest false). - */ -PNG_INTERNAL_FUNCTION(void, png_copy_row,(png_const_structrp png_ptr, - png_bytep dp, png_const_bytep sp, png_uint_32 x/*in INPUT*/, - png_uint_32 width/*of INPUT*/, unsigned int pixel_depth, - int clear/*clear the final byte*/, int x_in_dest),PNG_EMPTY); - -/* Zlib support */ -#define PNG_UNEXPECTED_ZLIB_RETURN (-7) -PNG_INTERNAL_FUNCTION(void, png_zstream_error,(z_stream *zstream, int ret), - PNG_EMPTY); - /* Used by the zlib handling functions to ensure that z_stream::msg is always - * set before they return. - */ - -#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ - !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \ - (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ - defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ - (defined(PNG_sCAL_SUPPORTED) && \ - defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)) -PNG_INTERNAL_FUNCTION(png_fixed_point,png_fixed,(png_const_structrp png_ptr, - double fp, png_const_charp text),PNG_EMPTY); -#endif - -/* Internal base allocator - no messages, NULL on failure to allocate. This - * does, however, call the application provided allocator and that could call - * png_error (although that would be a bug in the application implementation.) - */ -PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_base,(png_const_structrp png_ptr, - png_alloc_size_t size),PNG_ALLOCATED); - -#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\ - defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) -/* Internal array allocator, outputs no error or warning messages on failure, - * just returns NULL. - */ -PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_array,(png_const_structrp png_ptr, - int nelements, size_t element_size),PNG_ALLOCATED); - -/* The same but an existing array is extended by add_elements. This function - * also memsets the new elements to 0 and copies the old elements. The old - * array is not freed or altered. - */ -PNG_INTERNAL_FUNCTION(png_voidp,png_realloc_array,(png_structrp png_ptr, - png_const_voidp array, int old_elements, int add_elements, - size_t element_size),PNG_ALLOCATED); -#endif /* text, sPLT or unknown chunks */ - -/* Magic to create a struct when there is no struct to call the user supplied - * memory allocators. Because error handling has not been set up the memory - * handlers can't safely call png_error, but this is an obscure and undocumented - * restriction so libpng has to assume that the 'free' handler, at least, might - * call png_error. - */ -PNG_INTERNAL_FUNCTION(png_structp,png_create_png_struct, - (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, - png_error_ptr warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn, - png_free_ptr free_fn),PNG_ALLOCATED); - -/* Free memory from internal libpng struct */ -PNG_INTERNAL_FUNCTION(void,png_destroy_png_struct,(png_structrp png_ptr), - PNG_EMPTY); - -/* Free an allocated jmp_buf (always succeeds) */ -PNG_INTERNAL_FUNCTION(void,png_free_jmpbuf,(png_structrp png_ptr),PNG_EMPTY); - -/* Function to allocate memory for zlib. PNGAPI is disallowed. */ -PNG_INTERNAL_FUNCTION(voidpf,png_zalloc,(voidpf png_ptr, uInt items, uInt size), - PNG_ALLOCATED); - -/* Function to free memory for zlib. PNGAPI is disallowed. */ -PNG_INTERNAL_FUNCTION(void,png_zfree,(voidpf png_ptr, voidpf ptr),PNG_EMPTY); - -/* The next three functions are used by png_init_io to set the default - * implementations for reading or writing to a stdio (png_FILE_p) stream. - * They can't be static because in 1.7 png_init_io needs to reference them. - */ -#ifdef PNG_STDIO_SUPPORTED -# ifdef PNG_READ_SUPPORTED -PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr, - png_bytep data, png_size_t length),PNG_EMPTY); -# endif /* READ */ - -# ifdef PNG_WRITE_SUPPORTED -PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_write_data,(png_structp png_ptr, - png_bytep data, png_size_t length),PNG_EMPTY); - -# ifdef PNG_WRITE_FLUSH_SUPPORTED -PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_flush,(png_structp png_ptr), - PNG_EMPTY); -# endif /* WRITE_FLUSH */ -# endif /* WRITE */ -#endif /* STDIO */ - -/* Reset the CRC variable. The CRC is initialized with the chunk tag (4 bytes). - * NOTE: at present png_struct::chunk_name MUST be set before this as well so - * that png_struct::current_crc is initialized correctly! - */ -PNG_INTERNAL_FUNCTION(void,png_reset_crc,(png_structrp png_ptr, - png_const_bytep chunk_tag), PNG_EMPTY); - -/* Write the "data" buffer to whatever output you are using */ -PNG_INTERNAL_FUNCTION(void,png_write_data,(png_structrp png_ptr, - png_const_voidp data, png_size_t length),PNG_EMPTY); - -/* Read and check the PNG file signature */ -PNG_INTERNAL_FUNCTION(void,png_read_sig,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); - -/* Read data from whatever input you are using into the "data" buffer */ -PNG_INTERNAL_FUNCTION(void,png_read_data,(png_structrp png_ptr, png_voidp data, - png_size_t length),PNG_EMPTY); - -/* Read bytes into buf, and update png_ptr->crc */ -PNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_voidp buf, - png_uint_32 length),PNG_EMPTY); - -/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ -PNG_INTERNAL_FUNCTION(int,png_crc_finish,(png_structrp png_ptr, - png_uint_32 skip),PNG_EMPTY); - -/* Calculate the CRC over a section of data. Note that we are only - * passing a maximum of 64K on systems that have this as a memory limit, - * since this is the maximum buffer size we can specify. - */ -PNG_INTERNAL_FUNCTION(void,png_calculate_crc,(png_structrp png_ptr, - png_const_voidp ptr, png_size_t length),PNG_EMPTY); - -/* Write various chunks */ - -/* Write the IHDR chunk, and update the png_struct with the necessary - * information. - */ -PNG_INTERNAL_FUNCTION(void,png_write_IHDR,(png_structrp png_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, - int compression_method, int filter_method, int interlace_method),PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_write_PLTE,(png_structrp png_ptr, - png_const_colorp palette, unsigned int num_pal),PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_write_IEND,(png_structrp png_ptr),PNG_EMPTY); - -#ifdef PNG_WRITE_gAMA_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_gAMA_fixed,(png_structrp png_ptr, - png_fixed_point file_gamma),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_sBIT_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_sBIT,(png_structrp png_ptr, - png_const_color_8p sbit, int color_type),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_cHRM_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr, - const png_xy *xy), PNG_EMPTY); - /* The xy value must have been previously validated */ -#endif - -#ifdef PNG_WRITE_sRGB_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr, - int intent),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_iCCP_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr, - png_const_charp name, png_const_voidp profile), PNG_EMPTY); - /* The profile must have been previously validated for correctness, the - * length comes from the first four bytes. Only the base, deflate, - * compression is supported. - */ -#endif - -#ifdef PNG_WRITE_sPLT_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_sPLT,(png_structrp png_ptr, - png_const_sPLT_tp palette),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_tRNS_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_tRNS,(png_structrp png_ptr, - png_const_bytep trans, png_const_color_16p values, int number, - int color_type),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_bKGD_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_bKGD,(png_structrp png_ptr, - png_const_color_16p values, int color_type),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_hIST_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_hIST,(png_structrp png_ptr, - png_const_uint_16p hist, int num_hist),PNG_EMPTY); -#endif - -/* Chunks that have keywords */ -#ifdef PNG_WRITE_tEXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr, - png_const_charp key, png_const_charp text, png_size_t text_len),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_zTXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_zTXt,(png_structrp png_ptr, - png_const_charp key, png_const_charp text, int compression),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_iTXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_iTXt,(png_structrp png_ptr, - int compression, png_const_charp key, png_const_charp lang, - png_const_charp lang_key, png_const_charp text),PNG_EMPTY); -#endif - -#ifdef PNG_TEXT_SUPPORTED /* Added at version 1.0.14 and 1.2.4 */ -PNG_INTERNAL_FUNCTION(int,png_set_text_2,(png_structrp png_ptr, - png_inforp info_ptr, png_const_textp text_ptr, int num_text),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_oFFs_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_oFFs,(png_structrp png_ptr, - png_int_32 x_offset, png_int_32 y_offset, int unit_type),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_pCAL_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_pCAL,(png_structrp png_ptr, - png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, - png_const_charp units, png_charpp params),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_pHYs_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_pHYs,(png_structrp png_ptr, - png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, - int unit_type),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_tIME_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_tIME,(png_structrp png_ptr, - png_const_timep mod_time),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_sCAL_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_sCAL_s,(png_structrp png_ptr, - int unit, png_const_charp width, png_const_charp height),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_start_IDAT,(png_structrp png_ptr), - PNG_EMPTY); - /* Do any required initialization before IDAT or row processing starts. */ - -/* Choose the best filter to use and filter the row data then write it out. If - * WRITE_FILTERING is not supported this just writes the data out with a zero - * (NONE) filter byte. - * - * This may be called multiple times per row, but calls must be in 'x' order; - * first a call with x 0 to mark the start of the row and, at the end, one with - * PNG_ROW_END set (this can be done in the same function call if the whole row - * is passed.) The following flags are used internally to control pass - * filtering and deflate: - */ -enum -{ - png_pass_last =0x1U, /* This is the last pass in the image */ - png_pass_last_row =0x2U, /* This is the last row in a pass */ - png_pass_first_row =0x4U, /* This is the first row in a pass */ - png_row_end =0x8U, /* This is the last block in the row */ - png_no_row_info =0x0U /* Placeholder */ - - /* A useful macro; return true if this is the last block of the last row in - * the image. - */ -# define PNG_IDAT_END(f) (((f) & ~png_pass_first_row) == \ - (png_row_end+png_pass_last_row+png_pass_last)) -}; -PNG_INTERNAL_FUNCTION(void,png_write_png_data,(png_structrp png_ptr, - png_bytep prev_pixels, png_const_bytep unfiltered_row, png_uint_32 x, - unsigned int width/*pixels*/, unsigned int row_info_flags), - PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_write_png_rows,(png_structrp png_ptr, - png_const_bytep *rows, png_uint_32 num_rows), PNG_EMPTY); - /* As above but rows[num_rows] of correctly (PNG) formated but unfiltered - * data are passed in. For an interlaced image the rows will be interlaced - * rows and therefore may be narrower than the image width. - * - * This function advances png_structp::pass and png_structp::row_number as - * required. - */ - -/* Release memory used by the deflate mechanism */ -PNG_INTERNAL_FUNCTION(void, png_deflate_destroy, (png_structp png_ptr), - PNG_EMPTY); -#endif /* WRITE */ - -#ifdef PNG_TRANSFORM_MECH_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_transform_free,(png_const_structrp png_ptr, - png_transformp *list),PNG_EMPTY); - /* Free the entire transform list, from the given point on. the argument is - * set to NULL. - */ - -PNG_INTERNAL_FUNCTION(void,png_init_transform_control,( - png_transform_controlp out, png_structp png_ptr),PNG_EMPTY); - /* Initialize a transform control for running the transform list forward (the - * read case, and write initialization, but the write case is called within - * pngtrans.c by the above function.) - */ - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -PNG_INTERNAL_FUNCTION(unsigned int,png_run_this_transform_list_forwards, - (png_transform_controlp tc, png_transformp *start, png_transformp end), - PNG_EMPTY); - /* Used by the transform cache code to run a sub-list, from *start to the - * transform end. - */ -#endif /* READ_TRANSFORMS */ - -#ifdef PNG_READ_SUPPORTED -PNG_INTERNAL_FUNCTION(unsigned int,png_run_transform_list_forwards, - (png_structp png_ptr, png_transform_controlp tc),PNG_EMPTY); - /* Run the transform list in the forwards direction (from PNG format to - * memory format). The transform control must be initialized completely by - * the caller. This function takes account of transforms which delete - * themselves during the run; it must be used. - */ -#endif /* READ */ - -#ifdef PNG_WRITE_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_run_transform_list_backwards, - (png_structp png_ptr, png_transform_controlp tc),PNG_EMPTY); - /* Run the transform list in the backwards direction (from memory format to - * PNG format). The transform control must be initialized completely by - * the caller. This function takes account of transforms which delete - * themselves during the run; it must be used. - */ -#endif /* WRITE */ - -PNG_INTERNAL_FUNCTION(png_transformp,png_add_transform,(png_structrp png_ptr, - size_t size, png_transform_fn fn, unsigned int order),PNG_EMPTY); - /* Add a transform, using the information in 'order' to control the position - * of the transform in the list, returning a pointer to the transform. The - * top 8 bits of 'order' control the position in the list. If a transform - * does not already exist in the list with the given value a new transform - * will be created and 'fn' and 'order' set. If there is a transform with - * that value 'fn' must match and 'order' will be updated by combining the - * new value in with a bitwise or (|). It is up to the function (fn) or the - * caller of png_add_transform to determine whether the combination is valid. - * - * 'size' is used when creating a new transform, it may be larger than - * (sizeof png_transform) if required to accomodate extra data. - * - * Prior to 1.7.0 transforms were executed in an order hard-wired into the - * code that executed the transform functions. This was summarized in the - * read case by the following comment from pngrtran.c - * (png_init_read_transformations), note that this has been marked up to - * indicate which PNG formats the transforms in the list apply to: - * - * *: applies to most formats - * A: only formats with alpha - * L: only low-bit-depth (less than 8 bits per component/pixel) - * H: only high-bit-depth (16-bits per component) - * - > From the code of png_do_read_transformations the order is: - * - * GGRR For example column: . no action - * AGG r acts on read - * BB w acts on write - * A B acts on both read and write - > - > r.r. 1) PNG_EXPAND (including PNG_EXPAND_tRNS) - > .r.r 2) PNG_STRIP_ALPHA (if no compose) - > ..rr 3) PNG_RGB_TO_GRAY - > rr.. 4) PNG_GRAY_TO_RGB iff !PNG_FLAG_BACKGROUND_IS_GRAY - > rrrr 5) PNG_COMPOSE - > rrrr 6) PNG_GAMMA - > .r.r 7) PNG_STRIP_ALPHA (if compose) - > .r.r 8) PNG_ENCODE_ALPHA - > rrrr 9) PNG_SCALE_16_TO_8 - > rrrr 10) PNG_16_TO_8 - > ..rr 11) PNG_QUANTIZE (converts to palette) - > rrrr 12) PNG_EXPAND_16 - > rr.. 13) PNG_GRAY_TO_RGB iff PNG_FLAG_BACKGROUND_IS_GRAY - > BB.. 14) PNG_INVERT_MONO - > .B.B 15) PNG_INVERT_ALPHA - > BBBB 16) PNG_SHIFT - * - * Note that transforms from this point on are used in 1.7.0 on palette - * indices as well; a png_set_pack request (for example) packs the palette - * index values if the output will be palettized and the grayscale values - * if it will not be (if the output is low-bit-grayscale, not palette.) - * - > B... 17) PNG_PACK - > ..BB 18) PNG_BGR - > B... 19) PNG_PACKSWAP - > rwrw 20) PNG_FILLER (includes PNG_ADD_ALPHA) - > .B.B 21) PNG_SWAP_ALPHA - > BBBB 22) PNG_SWAP_BYTES - > BBBB 23) PNG_USER_TRANSFORM [must be last] - * - * Finally, outside the set of transforms prior to 1.7.0, the libpng - * interlace handling required the pixels to be replicated to match the pixel - * spacing in the image row; the first part the pre-1.7.0 interlace support, - * this is still the case when reading, but for writing the interlace is now - * a transform: - * - > BBBB 24) png_do_{read,write}_interlace (interlaced images only). - * - * First transforms are grouped according to basic function using the top 3 - * bits of the order code: - */ -# define PNG_TR_START 0x0000U /* initial ops on the PNG data */ -# define PNG_TR_ARITHMETIC 0x2000U /* arithmetic linear operations */ -# define PNG_TR_CHANNEL 0x4000U /* PNG conformant format changes */ -# define PNG_TR_QUANTIZE 0x6000U /* quantize and following operations */ -# define PNG_TR_ENCODING 0x8000U /* Row encoding transforms */ -# define PNG_TR_INTERLACE 0xA000U /* write interlace transform */ - /* - * In libpng 1.7.0 the check on palette index values is moved to the start - * (of read, end of write, which is where it was before) immediately after - * the MNG filter handling - */ -# define PNG_TR_MNG_INTRAPIXEL (PNG_TR_START + 0x0100U) - /* Perform intra-pixel differencing (write) or un-differencing on read. */ -# define PNG_TR_CHECK_PALETTE (PNG_TR_START + 0x0200U) - /* Done before at the start on read, at the end on write to give a - * consistent postion: - * - * PNG_RWTR_CHECK_PALETTE PI W11: happens in pngwrite.c last - */ -# define PNG_TR_START_CACHE (PNG_TR_START + 0x0300U) - /* Not used on a transform; this is just a marker for the point at which - * palette or low-bit-depth caching can start on read. (The previous - * operations cannot be cached). - */ -# define PNG_TR_INIT_ALPHA (PNG_TR_START + 0x0400U) - /* This just handles alpha/tRNS initialization issues to resolve the - * inter-dependencies with tRNS expansion and background composition; it - * doesn't do anything itself, just sets flags and pushes transforms. - */ - /* - * Prior to 1.7 the arithmetic operations interleaved with the RGB-to-gray - * and alpha strip byte level ops. This was done to reduce the amount of - * data processed, i.e. it was an optimization not a requirement. These - * operations were preceded by the 'expand' operations, which is the - * opposite; it was done to simplify the code and actually slows things down - * in the low bit depth gray case. The full list of operations after expand, - * in the 1.6 order, is: - * - * PNG_TR_STRIP_ALPHA png_do_strip_channel (sometimes) - * PNG_TR_RGB_TO_GRAY png_do_rgb_to_gray - * PNG_TR_GRAY_TO_RGB png_do_gray_to_rgb (sometimes) - * PNG_TR_COMPOSE png_do_compose - * PNG_TR_GAMMA png_do_gamma (if no RGB_TO_GRAY) - * PNG_TR_STRIP_ALPHA png_do_strip_channel (other times) - * PNG_TR_ENCODE_ALPHA png_do_encode_alpha - * - * In 1.7 the operations are moved round somewhat, including moving alpha and - * 16-to-8 bit reduction later. This leaves the following operations: - * - * PNG_TR_RGB_TO_GRAY png_do_rgb_to_gray - * PNG_TR_COMPOSE png_do_compose - * PNG_TR_GAMMA png_do_gamma (if no RGB_TO_GRAY) - * PNG_TR_ENCODE_ALPHA png_do_encode_alpha - * - * Prior to 1.7 some combinations of transforms would do gamma correction - * twice, the actual implementation in 1.7 is to use the following order and - * rely on the cache code to optimize gray 1,2,4,8 and (of course) palette. - */ -# define PNG_TR_COMPOSE (PNG_TR_ARITHMETIC + 0x0100U) - /* Handle background composition. This may need to push a gray-to-rgb - * transform if the background is RGB for gray input. This precedes RGB - * to gray convertion so that it can handle tRNS appropriately when the - * background is in the PNG encoding however, typically, the processing - * happens at PNG_TR_COMPOSE_ALPHA below. - * - * NOTE: this must be the first arithmetic transform because the code in - * png_init_background relies on png_transform_control::gamma being the - * original PNG gamma. - */ -# define PNG_TR_RGB_TO_GRAY (PNG_TR_ARITHMETIC + 0x0200U) /* to gray */ - /* Convert any RGB input (8/16 bit depth, RGB, RGBA) to linear gray - * 16-bit. This happens first because it cannot be cached; the input data - * has 24 or 48 bits of uncorrelated data so the transform has to happen - * pixel-by-pixel. Internally the transform may maintain an 8 or 16-bit - * gamma correction table (to 16-bit linear) to speed things up. - * - * NOTE: this transform must follow PNG_TR_COMPOSE with no intervening - * transforms; see the code in png_init_background (pngrtran.c) which - * relies on this during PNG_TC_INIT_FORMAT. - */ -# define PNG_TR_COMPOSE_ALPHA (PNG_TR_ARITHMETIC + 0x0300U) - /* Compose alpha composition and tRNS handling when the background is a - * screen color. Pushed by PNG_TR_COMPOSE as required. - */ -# define PNG_TR_GAMMA_ENCODE (PNG_TR_ARITHMETIC + 0x1F00U) /* last */ - /* Gamma encode the input. This encodes the gray or RGB channels to the - * required bit depth and either scales the alpha channel or encodes it as - * well, depending on the requested alpha encoding. - */ - /* - * The 'expand' operations come after the arithmetic ones in libpng 1.7, this - * forces the arithmetic stuff to do the expand, but since arithmetic is (in - * 1.7) normally done in 16-bit linear this avoids spurious expands. - */ -# define PNG_TR_EXPAND (PNG_TR_CHANNEL + 0x0100U) - /* Includes: - * - * PNG_TR_EXPAND_PALETTE palette images only, includes tRNS - * PNG_TR_EXPAND_LBP_GRAY grayscale low-bit depth only - * PNG_TR_EXPAND_tRNS non-palette images only - */ -# define PNG_TR_SCALE_16_TO_8 (PNG_TR_CHANNEL + 0x0200U) - /* Comes after the expand and before the chop version; note that it works on - * the pixel values directly, so it is a linear transform on a non-linear - * value. - */ - /* - * To handle transforms that affect the palette entries, not the palette - * indices in the row data, libpng 1.7 reorders some of the post-quantize - * transformations to put all the "PC" transforms ahead of all the "PI" - * transforms. The "PC" transforms that came after png_do_quantize in libpng - * 1.6 cannot be ordered to be before so they are included in the - * PNG_TR_QUANTIZE section. The PI transforms are all in PNG_TR_ENCODING, - * PNG_GRAY_TO_RGB is moved before PNG_TR_QUANTIZE to avoid the unpredictable - * behavior of png_set_quantize that otherwise arises. - * - * The transforms in the PNG_TR_QUANTIZE section are: - * - * PNG_TR_EXPAND_16 !P !W - * PNG_RWTR_INVERT_MONO !P W10: invert the gray channel - * PNG_RWTR_INVERT_ALPHA PC W8: invert the alpha channel - * PNG_RWTR_SHIFT PC W6: read: down, write: scale up - * PNG_RWTR_BGR !P W9 - * PNG_RWTR_FILLER !P W2: add on R, remove on W - * PNG_RWTR_SWAP_ALPHA !P W7 - * PNG_RWTR_SWAP_16 !P W5 - * - * The ones in PNG_TR_ENCODING are: - * - * PNG_RWTR_PACK PI W4: R: unpack bytes, W: pack - * PNG_RWTR_PIXEL_SWAP PI W3: Swap pixels in a byte - * PNG_RWTR_USER PI W1 - */ - -# define PNG_TR_CHANNEL_PREQ (PNG_TR_CHANNEL + 0x1F00U) - /* The channel swap transforms that must happen before PNG_TR_QUANTIZE: - * - * PNG_TR_STRIP_ALPHA - * PNG_TR_CHOP_16_TO_8 - * PNG_TR_GRAY_TO_RGB - */ -# define PNG_TR_CHANNEL_POSTQ (PNG_TR_QUANTIZE + 0x0100U) - /* The post-quantize channel swap transforms: - * - * PNG_TR_EXPAND_16 !P !W - * PNG_RWTR_BGR !P W9 - * PNG_RWTR_FILLER !P W2: (filler) add on R, remove on W - * PNG_RWTR_SWAP_ALPHA !P W7 - * PNG_RWTR_SWAP_16 !P W5 - * - * The 'CHANNEL' operation sets the transform_control channel_add flag for - * use below. - */ -# define PNG_TR_INVERT (PNG_TR_QUANTIZE + 0x0200U) - /* Invert MONO and ALPHA. If the channel_add flag is set in the transform - * control INVERT_ALPHA will not be done; the png_add_alpha/filler APIs - * happened after png_set_invert_alpha in earlier versions so the filler - * value had to include the invert. - * - * PNG_RWTR_INVERT_MONO !P W10: invert the gray channel - * PNG_RWTR_INVERT_ALPHA PC W8: invert the alpha channel - */ -# define PNG_TR_SHIFT (PNG_TR_QUANTIZE + 0x0300U) - /* The channel shift, except that if the channel_add flag has been set the - * alpha channel is not shifted. - * - * PNG_RWTR_SHIFT PC W6: read: down, write: scale up - */ -# define PNG_TR_PACK (PNG_TR_ENCODING + 0x0200U) - /* PNG_RWTR_PACK PI W4: R: unpack bytes, W: pack */ -# define PNG_TR_PIXEL_SWAP (PNG_TR_ENCODING + 0x0300U) - /* PNG_RWTR_PIXEL_SWAP PI W3: Swap pixels in a byte */ -# define PNG_TR_USER (PNG_TR_ENCODING + 0x1F00U) - /* The user transform; must be last before the interlace handling because it - * does unpredictable things to the format. - * - * PNG_RWTR_USER PI W1 - */ - -PNG_INTERNAL_FUNCTION(png_transformp,png_push_transform,(png_structrp png_ptr, - size_t size, png_transform_fn fn, png_transformp *transform, - png_transform_controlp tc),PNG_EMPTY); - /* As png_add_transform except that the new transform is inserted ahead of - * the given transform (*transform). The new transform is returned, but it - * will also invariably be in *transform. If 'tc' is not NULL the transform - * callback will also be called; it needs to be called if this function is - * called while transforms are being run. - * - * 'fn' must not be NULL. - * - * The transform is inserted with the same 'order' as the passed in - * *transform, that transform and following transforms are moved up ('order' - * is incremented) as required to make space. Consequently, unlike with - * png_add_transform, the transform will always be new. To detect loops - * (*transform)->fn must not be the same as the passed in 'fn'. - */ - -PNG_INTERNAL_FUNCTION(png_voidp,png_transform_cast_check, - (png_const_structp png_ptr, unsigned int src_line, png_transformp tr, - size_t size),PNG_EMPTY); - /* Given a pointer to a transform, 'tr' validate that the underlying derived - * class has size 'size' using the tr->size field and return the same - * pointer. If there is a size mismatch the function does an affirm using - * the given line number. - */ -#define png_transform_cast(type, pointer) png_voidcast(type*,\ - png_transform_cast_check(png_ptr, PNG_SRC_LINE, (pointer), sizeof (type))) - /* This takes a pointer to a transform and safely returns a pointer to a - * derived transform class (type); type must not have the pointer. It - * validates the 'size' field. Derived classes start with a png_transform - * as the first member called 'tr'. - */ -#endif /* TRANSFORM_MECH_SUPPORTED */ - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -/* Remove a transform from a list, moving the next transform down into - * *transform. - */ -PNG_INTERNAL_FUNCTION(void,png_remove_transform,(png_const_structp png_ptr, - png_transformp *transform),PNG_EMPTY); - -/* Initializer for read transforms that handles caching, palette update and - * palette expansion. - */ -PNG_INTERNAL_FUNCTION(unsigned int,png_read_init_transform_mech, - (png_structp png_ptr, png_transform_control *tc),PNG_EMPTY); - -/* Optional call to update the users info structure */ -PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -#endif - -/* APIs which do a tranform on both read and write but where the implementation - * is separate for each; the read and write init functions are in pngrtran.c or - * pngwtran.c, the API is in pngtrans.c - */ -#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_init_read_pack,(png_transformp *transform, - png_transform_controlp tc),PNG_EMPTY); -#endif /* READ_PACK || READ_EXPAND */ -#ifdef PNG_WRITE_PACK_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_init_write_pack,(png_transformp *transform, - png_transform_controlp tc),PNG_EMPTY); -#endif /* WRITE_PACK */ - -/* Shared transform functions, defined in pngtran.c */ -#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ - defined(PNG_READ_STRIP_ALPHA_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_do_strip_channel,( - png_transform_controlp row_info, png_bytep row, int at_start),PNG_EMPTY); -#endif /* FILLER */ - -#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_do_invert,(png_transform_controlp row_info, - png_bytep row),PNG_EMPTY); -#endif /* INVERT */ - -#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) ||\ - defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_do_invert_alpha,(png_transform_controlp row_info, - png_bytep row),PNG_EMPTY); -#endif /* INVERT_ALPHA */ - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_add_rgb_to_gray_byte_ops,(png_structrp png_ptr, - png_transform_controlp tc, unsigned int index, unsigned int order), - PNG_EMPTY); - /* This is an init-time utility to add appropriate byte ops to select a given - * channel from R/G/B. - */ -#endif /* READ_RGB_TO_GRAY */ - -#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) &&\ - defined(PNG_READ_BACKGROUND_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_push_gray_to_rgb_byte_ops,(png_transformp *tr, - png_transform_controlp tc), PNG_EMPTY); - /* This is an init-time utility to push appropriate byte ops to expand a - * grayscale PNG data set to RGB. It calls the function callback so 'tc' - * must be non-NULL. - */ -#endif /* GRAY_TO_RGB && READ_BACKGROUND */ - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_add_strip_alpha_byte_ops,(png_structrp png_ptr), - PNG_EMPTY); - /* Called from pngrtran.c to add the relevant byte op. */ -#endif /* READ_STRIP_ALPHA */ - -/* The following decodes the appropriate chunks, and does error correction, - * then calls the appropriate callback for the chunk if it is valid. - */ - -#ifdef PNG_READ_SUPPORTED -PNG_INTERNAL_FUNCTION(png_bytep,png_read_buffer,(png_structrp png_ptr, - png_alloc_size_t new_size, int warn),PNG_EMPTY); - /* Manage the dynamically allocated read buffer */ - -/* Shared READ IDAT handling: */ -PNG_INTERNAL_FUNCTION(void,png_read_start_IDAT,(png_structrp png_ptr), - PNG_EMPTY); - /* Initialize the row buffers, etc. */ - -typedef enum -{ - png_row_incomplete, - /* more IDAT data needed for row */ - png_row_process, - /* png_struct::row_buffer contains a complete row */ - png_row_repeat, - /* row not in this pass, but the existing row may be used */ - png_row_skip - /* row not in pass and no appropriate data; skip this row */ -} png_row_op; -PNG_INTERNAL_FUNCTION(png_row_op,png_read_process_IDAT,(png_structrp png_ptr, - png_bytep transformed_row, png_bytep display_row, int save_row), - PNG_EMPTY); - /* Process a block of IDAT data; the routine returns early if it has - * obtained a row. It is valid to call this routine with no input data; - * it will return png_row_incomplete if it needs input. - * - * transformed_row: The transformed pixels of the input are written here. - * For interlaced images only the pixels in the pass will - * be written, the other pixels will not be touched. - * - * display_row: The transformed pixels but replicated to that the entire - * buffer will have been initialized. For passes after the - * first the pixels written are determined by the 'block' - * algorithm; only those *following* pixels which are - * written by *later* passes are written (with a copy of the - * pixel from the pass.) - * - * save_row: A boolean which indicates that the row (unexpanded) - * should be saved in png_struct::transformed_row. This can - * be used in a later call to png_combine_row. - * - * During reading the row is built up until png_row_process is returned. At - * this point png_struct::row_buffer contains the original PNG row from the - * file and, if save_row was set, png_struct::transformed_row contains the - * row after the selected row transforms have been performed. For interlaced - * images both are the width of the interlace pass. - * - * When png_row_repeat is returned the same is true, except that the buffers - * still contain the contents of the preceding row (the one where this - * funciton returned png_row_pricess). - * - * The row buffers should not be accessed if png_row_skip is returned; this - * row is not modified in the current pass. - */ - -PNG_INTERNAL_FUNCTION(void,png_read_free_row_buffers,(png_structrp png_ptr), - PNG_EMPTY); - /* Free allocated row buffers; done as soon as possible to avoid carrying - * around all the memory for longer than necessary. - */ - -PNG_INTERNAL_FUNCTION(int,png_read_finish_IDAT,(png_structrp png_ptr), - PNG_EMPTY); - /* Complete reading of the IDAT chunks. This returns 0 if more data is to - * be read, 1 if the zlib stream has terminated. Call this routine with - * zstream.avail_in greater than zero unless there is no more input data. - * When zstream_avail_in is 0 on entry and the stream does not terminate - * an "IDAT truncated" error will be output. - * - * ENTRY: png_ptr->zstream.{next,avail}_in points to more IDAT data, if - * available, otherwise avail_in should be 0. - * RET 0: the LZ stream is still active, more IDAT date is required, if - * available, the routine *must* be called again. - * RET 1: the LZ stream has been closed and an error may have been output; - * png_ptr->zstream_error says whether it has. If not and there - * is more IDAT data available the caller should output an - * appropriate (too much IDAT) error message. - */ - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_cache_known_unknown,(png_structrp png_ptr, - png_const_bytep add, int keep),PNG_EMPTY); - /* Update the png_struct::known_unknown bit cache which stores whether each - * known chunk should be treated as unknown. - */ -#endif - -typedef enum -{ - png_chunk_skip = 0, /* Skip this chunk */ - png_chunk_unknown, /* Pass the chunk to png_handle_unknown */ - png_chunk_process_all, /* Process the chunk all at once */ - png_chunk_process_part /* Process the chunk in parts (for IDAT) */ -} png_chunk_op; - -PNG_INTERNAL_FUNCTION(png_chunk_op,png_find_chunk_op,(png_structrp png_ptr), - PNG_EMPTY); - /* Given a chunk in png_struct::{chunk_name,chunk_length} validate the name - * and work out how it should be handled. This function checks the chunk - * location using png_struct::mode and will set the mode appropriately for - * the known critical chunks but otherwise makes no changes to the stream - * read state. - */ - -PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_const_structrp png_ptr, - const png_uint_32 chunk_name),PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_check_chunk_length,(png_const_structrp png_ptr, - const png_uint_32 chunk_length),PNG_EMPTY); - -#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr, - png_inforp info_ptr, png_bytep chunk_data),PNG_EMPTY); - /* Handle an unknown chunk that needs to be processed. It is only valid - * to call this after png_find_chunk_op returns png_chunk_unknown. The - * data argument points to the png_struct::chunk_length bytes of the chunk - * data. - */ -#endif /* READ_UNKNOWN_CHUNKS */ - -PNG_INTERNAL_FUNCTION(void,png_handle_chunk,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); - /* The chunk to handle is in png_struct::chunk_name,chunk_length. - * - * NOTE: at present it is only valid to call this after png_find_chunk_op - * has returned png_chunk_process_all and all the data is available for - * png_handle_chunk (via the libpng read callback.) - */ -#endif /* READ */ - -PNG_INTERNAL_FUNCTION(void,png_init_row_info,(png_structrp png_ptr),PNG_EMPTY); - /* Set the png_struct::row_ members from the PNG file information, running - * transforms if required. - */ - -/* Added at libpng version 1.6.0 */ -#ifdef PNG_GAMMA_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_colorspace_set_gamma,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_fixed_point gAMA), PNG_EMPTY); - /* Set the colorspace gamma with a value provided by the application or by - * the gAMA chunk on read. The value will override anything set by an ICC - * profile. - */ - -PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr, - png_inforp info_ptr), PNG_EMPTY); - /* Synchronize the info 'valid' flags with the colorspace */ - -PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr, - png_inforp info_ptr), PNG_EMPTY); - /* Copy the png_struct colorspace to the info_struct and call the above to - * synchronize the flags. Checks for NULL info_ptr and does nothing. - */ -#endif - -/* Added at libpng version 1.4.0 */ -#ifdef PNG_COLORSPACE_SUPPORTED -/* These internal functions are for maintaining the colorspace structure within - * a png_info or png_struct (or, indeed, both). - */ -PNG_INTERNAL_FUNCTION(int,png_colorspace_set_chromaticities, - (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_xy *xy, - int preferred), PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(int,png_colorspace_set_endpoints, - (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_XYZ *XYZ, - int preferred), PNG_EMPTY); - -#ifdef PNG_sRGB_SUPPORTED -PNG_INTERNAL_FUNCTION(int,png_colorspace_set_sRGB,(png_const_structrp png_ptr, - png_colorspacerp colorspace, int intent), PNG_EMPTY); - /* This does set the colorspace gAMA and cHRM values too, but doesn't set the - * flags to write them, if it returns false there was a problem and an error - * message has already been output (but the colorspace may still need to be - * synced to record the invalid flag). - */ -#endif /* sRGB */ - -#ifdef PNG_iCCP_SUPPORTED -PNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_charp name, - png_uint_32 profile_length, png_const_bytep profile, int is_color), - PNG_EMPTY); - /* The 'name' is used for information only */ - -/* Routines for checking parts of an ICC profile. */ -PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_charp name, - png_uint_32 profile_length), PNG_EMPTY); -PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_charp name, - png_uint_32 profile_length, - png_const_bytep profile /* first 132 bytes only */, int is_color), - PNG_EMPTY); -PNG_INTERNAL_FUNCTION(int,png_icc_check_tag_table,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_charp name, - png_uint_32 profile_length, - png_const_bytep profile /* header plus whole tag table */), PNG_EMPTY); -#ifdef PNG_sRGB_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_icc_set_sRGB,( - png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_bytep profile, uLong adler), PNG_EMPTY); - /* 'adler' is the Adler32 checksum of the uncompressed profile data. It may - * be zero to indicate that it is not available. It is used, if provided, - * as a fast check on the profile when checking to see if it is sRGB. - */ -#endif /* sRGB */ -#endif /* iCCP */ -#endif /* COLORSPACE */ - -/* Added at libpng version 1.4.0 */ -PNG_INTERNAL_FUNCTION(void,png_check_IHDR,(png_const_structrp png_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_type, int compression_type, - int filter_type),PNG_EMPTY); - -#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_fixed_error,(png_const_structrp png_ptr, - png_const_charp name),PNG_NORETURN); -#endif - -/* Puts 'string' into 'buffer' at buffer[pos], taking care never to overwrite - * the end. Always leaves the buffer nul terminated. Never errors out (and - * there is no error code.) - */ -PNG_INTERNAL_FUNCTION(size_t,png_safecat,(png_charp buffer, size_t bufsize, - size_t pos, png_const_charp string),PNG_EMPTY); - -/* Various internal functions to handle formatted warning messages, currently - * only implemented for warnings. - */ -#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED) -/* Utility to dump an unsigned value into a buffer, given a start pointer and - * and end pointer (which should point just *beyond* the end of the buffer!) - * Returns the pointer to the start of the formatted string. This utility only - * does unsigned values. - */ -PNG_INTERNAL_FUNCTION(png_charp,png_format_number,(png_const_charp start, - png_charp end, int format, png_alloc_size_t number),PNG_EMPTY); - -/* Convenience macro that takes an array: */ -#define PNG_FORMAT_NUMBER(buffer,format,number) \ - png_format_number(buffer, buffer + (sizeof buffer), format, number) - -/* Suggested size for a number buffer (enough for 64 bits and a sign!) */ -#define PNG_NUMBER_BUFFER_SIZE 24 - -/* These are the integer formats currently supported, the name is formed from - * the standard printf(3) format string. - */ -#define PNG_NUMBER_FORMAT_u 1 /* chose unsigned API! */ -#define PNG_NUMBER_FORMAT_02u 2 -#define PNG_NUMBER_FORMAT_d 1 /* chose signed API! */ -#define PNG_NUMBER_FORMAT_02d 2 -#define PNG_NUMBER_FORMAT_x 3 -#define PNG_NUMBER_FORMAT_02x 4 -#define PNG_NUMBER_FORMAT_fixed 5 /* choose the signed API */ -#endif - -#ifdef PNG_WARNINGS_SUPPORTED -/* New defines and members adding in libpng-1.5.4 */ -# define PNG_WARNING_PARAMETER_SIZE 32 -# define PNG_WARNING_PARAMETER_COUNT 8 /* Maximum 9; see pngerror.c */ - -/* An l-value of this type has to be passed to the APIs below to cache the - * values of the parameters to a formatted warning message. - */ -typedef char png_warning_parameters[PNG_WARNING_PARAMETER_COUNT][ - PNG_WARNING_PARAMETER_SIZE]; - -PNG_INTERNAL_FUNCTION(void,png_warning_parameter,(png_warning_parameters p, - int number, png_const_charp string),PNG_EMPTY); - /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters, - * including the trailing '\0'. - */ -PNG_INTERNAL_FUNCTION(void,png_warning_parameter_unsigned, - (png_warning_parameters p, int number, int format, png_alloc_size_t value), - PNG_EMPTY); - /* Use png_alloc_size_t because it is an unsigned type as big as any we - * need to output. Use the following for a signed value. - */ -PNG_INTERNAL_FUNCTION(void,png_warning_parameter_signed, - (png_warning_parameters p, int number, int format, png_int_32 value), - PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_formatted_warning,(png_const_structrp png_ptr, - png_warning_parameters p, png_const_charp message),PNG_EMPTY); - /* 'message' follows the X/Open approach of using @1, @2 to insert - * parameters previously supplied using the above functions. Errors in - * specifying the parameters will simply result in garbage substitutions. - */ -#endif - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED -/* Application errors (new in 1.6); use these functions (declared below) for - * errors in the parameters or order of API function calls on read. The - * 'warning' should be used for an error that can be handled completely; the - * 'error' for one which can be handled safely but which may lose application - * information or settings. - * - * By default these both result in a png_error call prior to release, while in a - * released version the 'warning' is just a warning. However if the application - * explicitly disables benign errors (explicitly permitting the code to lose - * information) they both turn into warnings. - * - * If benign errors aren't supported they end up as the corresponding base call - * (png_warning or png_error.) - */ -PNG_INTERNAL_FUNCTION(void,png_app_warning,(png_const_structrp png_ptr, - png_const_charp message),PNG_EMPTY); - /* The application provided invalid parameters to an API function or called - * an API function at the wrong time, libpng can completely recover. - */ - -PNG_INTERNAL_FUNCTION(void,png_app_error,(png_const_structrp png_ptr, - png_const_charp message),PNG_EMPTY); - /* As above but libpng will ignore the call, or attempt some other partial - * recovery from the error. - */ -#else -# define png_app_warning(pp,s) png_warning(pp,s) -# define png_app_error(pp,s) png_error(pp,s) -#endif - -PNG_INTERNAL_FUNCTION(void,png_chunk_report,(png_const_structrp png_ptr, - png_const_charp message, int error),PNG_EMPTY); - /* Report a recoverable issue in chunk data. On read this is used to report - * a problem found while reading a particular chunk and the - * png_chunk_benign_error or png_chunk_warning function is used as - * appropriate. On write this is used to report an error that comes from - * data set via an application call to a png_set_ API and png_app_error or - * png_app_warning is used as appropriate. - * - * With PNG_CHUNK_FATAL an error can be marked as unrecoverable, and the - * function will not return. - * - * The 'error' parameter must have one of the following values: - */ -#define PNG_CHUNK_WARNING 0 /* never an error */ -#define PNG_CHUNK_WRITE_ERROR 1 /* an error only on write */ -#define PNG_CHUNK_ERROR 2 /* always an error */ -#define PNG_CHUNK_FATAL 3 /* an unrecoverable error */ - -#ifndef PNG_ERROR_TEXT_SUPPORTED -# define png_chunk_report(pp,e,v) png_chunk_report(pp,NULL,v) -#endif - -/* ASCII to FP interfaces, currently only implemented if sCAL - * support is required. - */ -#if defined(PNG_sCAL_SUPPORTED) -/* MAX_DIGITS is actually the maximum number of characters in an sCAL - * width or height, derived from the precision (number of significant - * digits - a build time settable option) and assumptions about the - * maximum ridiculous exponent. - */ -#define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/) - -#ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_ascii_from_fp,(png_const_structrp png_ptr, - png_charp ascii, png_size_t size, double fp, unsigned int precision), - PNG_EMPTY); -#endif /* FLOATING_POINT */ - -#ifdef PNG_FIXED_POINT_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr, - png_charp ascii, png_size_t size, png_fixed_point fp),PNG_EMPTY); -#endif /* FIXED_POINT */ -#endif /* sCAL */ - -#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) -/* An internal API to validate the format of a floating point number. - * The result is the index of the next character. If the number is - * not valid it will be the index of a character in the supposed number. - * - * The format of a number is defined in the PNG extensions specification - * and this API is strictly conformant to that spec, not anyone elses! - * - * The format as a regular expression is: - * - * [+-]?[0-9]+.?([Ee][+-]?[0-9]+)? - * - * or: - * - * [+-]?.[0-9]+(.[0-9]+)?([Ee][+-]?[0-9]+)? - * - * The complexity is that either integer or fraction must be present and the - * fraction is permitted to have no digits only if the integer is present. - * - * NOTE: The dangling E problem. - * There is a PNG valid floating point number in the following: - * - * PNG floating point numbers are not greedy. - * - * Working this out requires *TWO* character lookahead (because of the - * sign), the parser does not do this - it will fail at the 'r' - this - * doesn't matter for PNG sCAL chunk values, but it requires more care - * if the value were ever to be embedded in something more complex. Use - * ANSI-C strtod if you need the lookahead. - */ -/* State table for the parser. */ -#define PNG_FP_INTEGER 0 /* before or in integer */ -#define PNG_FP_FRACTION 1 /* before or in fraction */ -#define PNG_FP_EXPONENT 2 /* before or in exponent */ -#define PNG_FP_STATE 3 /* mask for the above */ -#define PNG_FP_SAW_SIGN 4 /* Saw +/- in current state */ -#define PNG_FP_SAW_DIGIT 8 /* Saw a digit in current state */ -#define PNG_FP_SAW_DOT 16 /* Saw a dot in current state */ -#define PNG_FP_SAW_E 32 /* Saw an E (or e) in current state */ -#define PNG_FP_SAW_ANY 60 /* Saw any of the above 4 */ - -/* These three values don't affect the parser. They are set but not used. - */ -#define PNG_FP_WAS_VALID 64 /* Preceding substring is a valid fp number */ -#define PNG_FP_NEGATIVE 128 /* A negative number, including "-0" */ -#define PNG_FP_NONZERO 256 /* A non-zero value */ -#define PNG_FP_STICKY 448 /* The above three flags */ - -/* This is available for the caller to store in 'state' if required. Do not - * call the parser after setting it (the parser sometimes clears it.) - */ -#define PNG_FP_INVALID 512 /* Available for callers as a distinct value */ - -/* Result codes for the parser (boolean - true meants ok, false means - * not ok yet.) - */ -#define PNG_FP_MAYBE 0 /* The number may be valid in the future */ -#define PNG_FP_OK 1 /* The number is valid */ - -/* Tests on the sticky non-zero and negative flags. To pass these checks - * the state must also indicate that the whole number is valid - this is - * achieved by testing PNG_FP_SAW_DIGIT (see the implementation for why this - * is equivalent to PNG_FP_OK above.) - */ -#define PNG_FP_NZ_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NEGATIVE | PNG_FP_NONZERO) - /* NZ_MASK: the string is valid and a non-zero negative value */ -#define PNG_FP_Z_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NONZERO) - /* Z MASK: the string is valid and a non-zero value. */ - /* PNG_FP_SAW_DIGIT: the string is valid. */ -#define PNG_FP_IS_ZERO(state) (((state) & PNG_FP_Z_MASK) == PNG_FP_SAW_DIGIT) -#define PNG_FP_IS_POSITIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_Z_MASK) -#define PNG_FP_IS_NEGATIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_NZ_MASK) - -/* The actual parser. This can be called repeatedly. It updates - * the index into the string and the state variable (which must - * be initialized to 0). It returns a result code, as above. There - * is no point calling the parser any more if it fails to advance to - * the end of the string - it is stuck on an invalid character (or - * terminated by '\0'). - * - * Note that the pointer will consume an E or even an E+ and then leave - * a 'maybe' state even though a preceding integer.fraction is valid. - * The PNG_FP_WAS_VALID flag indicates that a preceding substring was - * a valid number. It's possible to recover from this by calling - * the parser again (from the start, with state 0) but with a string - * that omits the last character (i.e. set the size to the index of - * the problem character.) This has not been tested within libpng. - */ -PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string, - png_size_t size, int *statep, png_size_tp whereami),PNG_EMPTY); - -/* This is the same but it checks a complete string and returns true - * only if it just contains a floating point number. As of 1.5.4 this - * function also returns the state at the end of parsing the number if - * it was valid (otherwise it returns 0.) This can be used for testing - * for negative or zero values using the sticky flag. - */ -PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string, - png_size_t size),PNG_EMPTY); -#endif /* pCAL || sCAL */ - -#if defined(PNG_GAMMA_SUPPORTED) ||\ - defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) -/* Added at libpng version 1.5.0 */ -/* This is a utility to provide a*times/div (rounded) and indicate - * if there is an overflow. The result is a boolean - false (0) - * for overflow, true (1) if no overflow, in which case *res - * holds the result. - */ -PNG_INTERNAL_FUNCTION(int,png_muldiv,(png_fixed_point_p res, png_fixed_point a, - png_int_32 multiplied_by, png_int_32 divided_by),PNG_EMPTY); -#endif /* GAMMA || INCH_CONVERSIONS || READ_pHYs */ - -#ifdef PNG_READ_GAMMA_SUPPORTED -/* Internal fixed point gamma correction. These APIs are called as - * required to convert single values - they don't need to be fast, - * they are not used when processing image pixel values. - */ -PNG_INTERNAL_FUNCTION(unsigned int,png_gamma_nxmbit_correct, - (unsigned int value, png_fixed_point gamma_val, unsigned int n/*input bits*/, - unsigned int m/*output bits */),PNG_EMPTY); - /* In this case the value must have 'n' bits and the output will have 'm' - * bits. - */ - -#if !PNG_RELEASE_BUILD -PNG_INTERNAL_FUNCTION(int,png_gamma_check,(png_const_structrp png_ptr, - png_const_transform_controlp tc),PNG_EMPTY); - /* Debugging only routine to repeat the test used above to determine if the - * gamma was insignificant. - */ -#endif /* !RELEASE_BUILD */ -#endif /* READ_GAMMA */ - -#ifdef PNG_SIMPLIFIED_READ_SUPPORTED -/* Internal check function to saw if the gamma of the PNG data is far enough - * from the given screen gamma to require gamma correction (only needed for a - * bug work-round in the simplified API). - * TODO: it should be possible to remove the bug work-round in 1.7 - */ -PNG_INTERNAL_FUNCTION(int,png_need_gamma_correction,(png_const_structrp png_ptr, - png_fixed_point gamma, int sRGB_output),PNG_EMPTY); -#endif /* SIMPLIFIED_READ */ - -/* This is a utility macro to say whether a gamma value is close enough to sRGB. - * The test is now hardwired: - * - * API CHANGE: prior to 1.7 this would depend on the build-time - * PNG_GAMMA_THRESHOLD_FIXED setting, which would cause inconsistent results - * when the setting was changed. Since this setting can now be changed at - * run-time it seems more sensible to have a single fixed definition of 'sRGB'. - * - * The test is approximately +/- 1%, it allows any decimal value from 0.45 (the - * two digit rounded version of 1/2.2) to just under 0.46). - */ -#define PNG_GAMMA_IS_sRGB(g) ((g) >= 45000 && (g) < 46000) - -/* SIMPLIFIED READ/WRITE SUPPORT */ -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -/* The internal structure that png_image::opaque points to. */ -typedef struct png_control -{ - png_structp png_ptr; - png_infop info_ptr; - png_voidp error_buf; /* Always a jmp_buf at present. */ - - png_const_bytep memory; /* Memory buffer. */ - png_size_t size; /* Size of the memory buffer. */ - - unsigned int for_write :1; /* Otherwise it is a read structure */ - unsigned int owned_file :1; /* We own the file in io_ptr */ -} png_control; - -/* Return the pointer to the jmp_buf from a png_control: necessary because C - * does not reveal the type of the elements of jmp_buf. - */ -#ifdef __cplusplus -# define png_control_jmp_buf(pc) (((jmp_buf*)((pc)->error_buf))[0]) -#else -# define png_control_jmp_buf(pc) ((pc)->error_buf) -#endif - -/* Utility to safely execute a piece of libpng code catching and logging any - * errors that might occur. Returns true on success, false on failure (either - * of the function or as a result of a png_error.) - */ -PNG_INTERNAL_CALLBACK(void,png_safe_error,(png_structp png_ptr, - png_const_charp error_message),PNG_NORETURN); - -#ifdef PNG_WARNINGS_SUPPORTED -PNG_INTERNAL_CALLBACK(void,png_safe_warning,(png_structp png_ptr, - png_const_charp warning_message),PNG_EMPTY); -#else -# define png_safe_warning 0/*dummy argument*/ -#endif - -PNG_INTERNAL_FUNCTION(int,png_safe_execute,(png_imagep image, - int (*function)(png_voidp), png_voidp arg),PNG_EMPTY); - -/* Utility to log an error; this also cleans up the png_image; the function - * always returns 0 (false). - */ -PNG_INTERNAL_FUNCTION(int,png_image_error,(png_imagep image, - png_const_charp error_message),PNG_EMPTY); - -/* Safely initialize a stdio pointer - used by both the read and the write - * code. - */ -#ifdef PNG_STDIO_SUPPORTED -PNG_INTERNAL_FUNCTION(int,png_image_init_io,(png_imagep image, png_FILE_p file), - PNG_EMPTY); -#endif /* STDIO */ - -#ifndef PNG_SIMPLIFIED_READ_SUPPORTED -/* png_image_free is used by the write code but not exported */ -PNG_INTERNAL_FUNCTION(void, png_image_free, (png_imagep image), PNG_EMPTY); -#endif /* !SIMPLIFIED_READ */ - -#endif /* SIMPLIFIED READ/WRITE */ - -#ifdef PNG_READ_SUPPORTED -PNG_INTERNAL_FUNCTION(png_int_32, png_read_setting, (png_structrp png_ptr, - png_uint_32 setting, png_uint_32 parameter, png_int_32 value), PNG_EMPTY); -#endif /* READ */ -#ifdef PNG_WRITE_SUPPORTED -PNG_INTERNAL_FUNCTION(png_int_32, png_write_setting, (png_structrp png_ptr, - png_uint_32 setting, png_uint_32 parameter, png_int_32 value), PNG_EMPTY); - /* Implementations of read and write settings, in pngrutil.c and pngwutil.c - * respectively. - */ -#endif /* WRITE */ - -/* Maintainer: Put new private prototypes here ^ */ - -/* These are initialization functions for hardware specific PNG filter - * optimizations; list these here then select the appropriate one at compile - * time using the macro PNG_FILTER_OPTIMIZATIONS. If the macro is not defined - * the generic code is used. - */ -#ifdef PNG_FILTER_OPTIMIZATIONS -PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structrp png_ptr, - unsigned int bpp), PNG_EMPTY); - /* Just declare the optimization that will be used */ -#else - /* List *all* the possible optimizations here - this branch is required if - * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in - * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing. - */ -PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon, - (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); -#endif - -#include "pngdebug.h" - -/* EXTENSION SPECIFIC FUNCTIONS */ -#include "arm/neon.h" - -#ifdef __cplusplus -} -#endif - -#endif /* PNG_VERSION_INFO_ONLY */ -#endif /* PNGPRIV_H */ diff --git a/ext/libpng17/pngread.c b/ext/libpng17/pngread.c deleted file mode 100644 index 96a5a1b4b4..0000000000 --- a/ext/libpng17/pngread.c +++ /dev/null @@ -1,4185 +0,0 @@ - -/* pngread.c - read a PNG file - * - * Last changed in libpng 1.7.0 [(PENDING RELEASE)] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file contains routines that an application calls directly to - * read a PNG file or stream. - */ - -#include "pngpriv.h" -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) -# include -#endif -#define PNG_SRC_FILE PNG_SRC_FILE_pngread - -#ifdef PNG_READ_SUPPORTED -/* Create a PNG structure for reading, and allocate any memory needed. */ -PNG_FUNCTION(png_structp,PNGAPI -png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) -{ -#ifndef PNG_USER_MEM_SUPPORTED - png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, - error_fn, warn_fn, NULL, NULL, NULL); -#else - return png_create_read_struct_2(user_png_ver, error_ptr, error_fn, - warn_fn, NULL, NULL, NULL); -} - -/* Alternate create PNG structure for reading, and allocate any memory - * needed. - */ -PNG_FUNCTION(png_structp,PNGAPI -png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) -{ - png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, - error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); -#endif /* USER_MEM */ - - if (png_ptr != NULL) - { - png_ptr->read_struct = 1; - png_ptr->critical_crc = crc_error_quit; - png_ptr->ancillary_crc = crc_warn_discard; - -# ifdef PNG_BENIGN_ERRORS_SUPPORTED -# if !PNG_RELEASE_BUILD - /* Always quit on error prior to release */ - png_ptr->benign_error_action = PNG_ERROR; - png_ptr->app_warning_action = PNG_WARN; - png_ptr->app_error_action = PNG_ERROR; -# else /* RELEASE_BUILD */ - /* Allow benign errors on read, subject to app control. */ - png_ptr->benign_error_action = PNG_WARN; -# ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED - png_ptr->app_error_action = PNG_WARN; - png_ptr->app_warning_action = PNG_WARN; -# else /* !BENIGN_READ_ERRORS */ - /* libpng build without benign error support; the application - * author has to be assumed to be correct, so: - */ - png_ptr->app_warning_action = PNG_WARN; - png_ptr->app_error_action = PNG_ERROR; -# endif /* !BENIGN_READ_ERRORS */ -# endif /* RELEASE_BUILD */ - - /* This is always png_error unless explicitly changed: */ - png_ptr->IDAT_error_action = PNG_ERROR; -# endif /* BENIGN_ERRORS */ - -# ifdef PNG_SEQUENTIAL_READ_SUPPORTED - png_ptr->IDAT_size = PNG_IDAT_READ_SIZE; -# endif /* SEQUENTIAL_READ */ - -# ifdef PNG_READ_GAMMA_SUPPORTED - /* Default gamma correction values: */ -# if 0 /*NYI*/ - png_ptr->gamma_accuracy = PNG_DEFAULT_GAMMA_ACCURACY; -# endif /*NYI*/ - png_ptr->gamma_threshold = PNG_GAMMA_THRESHOLD_FIXED; -# endif /* READ_GAMMA */ - } - - return png_ptr; -} - - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the chunk header (length + type name). - * Put the type name into png_ptr->chunk_name, and return the length. - */ -static void -png_read_chunk_header(png_structrp png_ptr) -{ - png_byte buf[8]; - -#ifdef PNG_IO_STATE_SUPPORTED - png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR; -#endif - - /* Read the length and the chunk name. - * This must be performed in a single I/O call. - */ - png_read_data(png_ptr, buf, 8); - - /* Put the chunk name into png_ptr->chunk_name. */ - png_ptr->chunk_length = png_get_uint_31(png_ptr, buf); - png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4); - - png_debug2(0, "Reading %lx chunk, length = %lu", - (unsigned long)png_ptr->chunk_name, - (unsigned long)png_ptr->chunk_length); - - /* Reset the crc and run it over the chunk name. */ - png_reset_crc(png_ptr, buf + 4); - -#ifdef PNG_IO_STATE_SUPPORTED - png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA; -#endif -} - -static void -png_read_sequential_unknown(png_structrp png_ptr, png_inforp info_ptr) -{ -#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - /* Read the data for an unknown chunk. The read buffer is used: */ - png_bytep buffer = png_read_buffer(png_ptr, png_ptr->chunk_length, - PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)); /* error if critical */ - - if (buffer != NULL) - { - if (png_ptr->chunk_length > 0U) - png_crc_read(png_ptr, buffer, png_ptr->chunk_length); - - png_crc_finish(png_ptr, 0); - png_handle_unknown(png_ptr, info_ptr, buffer); - } - - else /* out of memory on an ancillary chunk; skip the chunk */ -#else /* !READ_UNKNOWN_CHUNKS */ - /* or, no support for reading unknown chunks, so just skip it. */ - PNG_UNUSED(info_ptr) -#endif /* !READ_UNKNOWN_CHUNKS */ - png_crc_finish(png_ptr, png_ptr->chunk_length); -} - -/* Read the information before the actual image data. This has been - * changed in v0.90 to allow reading a file that already has the magic - * bytes read from the stream. You can tell libpng how many bytes have - * been read from the beginning of the stream (up to the maximum of 8) - * via png_set_sig_bytes(), and we will only check the remaining bytes - * here. The application can then have access to the signature bytes we - * read if it is determined that this isn't a valid PNG file. - */ -void PNGAPI -png_read_info(png_structrp png_ptr, png_inforp info_ptr) -{ - png_debug(1, "in png_read_info"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - /* Read and check the PNG file signature (this may do nothing if it has - * already been read.) - */ - png_read_sig(png_ptr, info_ptr); - - /* Loop reading chunks until an IDAT is encountered or we reach the end of - * the stream (IEND). - * - * Prior to 1.7.0 this function behaved very weirdly if called after the - * IDATs had been read; it would keep on reading chunks util it found - * another IDAT. This could cause it to read beyond IEND, damaging the - * state in the host stream. This is now caught by the check below. - */ - while ((png_ptr->mode & (PNG_HAVE_IEND|PNG_HAVE_IDAT)) == 0) - { - png_read_chunk_header(png_ptr); - switch (png_find_chunk_op(png_ptr)) - { - default: - impossible("invalid chunk op"); - /* FALL THROUGH */ - case png_chunk_skip: - png_crc_finish(png_ptr, png_ptr->chunk_length); - break; - - case png_chunk_unknown: - png_read_sequential_unknown(png_ptr, info_ptr); - break; - - case png_chunk_process_all: - png_handle_chunk(png_ptr, info_ptr); - break; - - case png_chunk_process_part: - debug(png_ptr->mode & PNG_HAVE_IDAT); - return; - } - } - - /* The loop was ended by IDAT or IEND, but if an IEND was seen the read code - * (png_handle_position in pngrutil.c) should have errored out, therefore: - */ -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - affirm(png_ptr->chunk_name == png_IDAT && ((png_ptr->known_unknown)&1U)); -#else - debug(png_ptr->chunk_name == png_IDAT); - impossible("unknown IDAT"); -#endif - - /* And the code cannot have left it unread; it must have called one of the - * handlers, so we are skipping IDAT. - */ -} - -/* Initialize palette, background, etc, after transformations - * are set, but before any reading takes place. This allows - * the user to obtain a gamma-corrected palette, for example. - * If the user doesn't call this, we will do it ourselves. - */ -void PNGAPI -png_start_read_image(png_structrp png_ptr) -{ - png_debug(1, "in png_start_read_image"); - - if (png_ptr != NULL) - { - if (png_ptr->zowner != png_IDAT) - png_read_start_IDAT(png_ptr); - - /* New in 1.6.0 this avoids the bug of doing the initializations twice, - * it could be a warning but in practice it indicates that the app may - * have made png_get_ calls on png_ptr assuming that it hadn't been - * 'started'. - */ - else - png_app_error(png_ptr, - "png_start_read_image/png_read_update_info: duplicate call"); - } -} - -static void -png_read_IDAT(png_structrp png_ptr) -{ - /* Read more input data, up to png_struct::IDAT_size, stop at the end of the - * IDAT stream. pngset.c checks png_struct::IDAT_size to ensure that it will - * fit in a uInt. - */ - const uInt buffer_size = (uInt)/*SAFE*/png_ptr->IDAT_size; - uInt IDAT_size = 0; - png_bytep buffer = - png_read_buffer(png_ptr, buffer_size, 0/*error*/); - - png_ptr->zstream.next_in = buffer; - - while (png_ptr->chunk_name == png_IDAT && IDAT_size < buffer_size) - { - png_uint_32 l = png_ptr->chunk_length; - - while (l == 0) /* end of this IDAT */ - { - png_crc_finish(png_ptr, 0); - png_read_chunk_header(png_ptr); - - if (png_ptr->chunk_name != png_IDAT) /* end of all IDAT */ - { - png_ptr->mode |= PNG_AFTER_IDAT; - goto done; - } - - l = png_ptr->chunk_length; - } - - /* Read from the IDAT chunk into the buffer, up to png_struct::IDAT_size: - */ - if (l > buffer_size - IDAT_size) /* SAFE: while check */ - l = buffer_size - IDAT_size; - - png_crc_read(png_ptr, buffer+IDAT_size, l); - IDAT_size += (uInt)/*SAFE*/l; - png_ptr->chunk_length -= l; - } -done: - - /* IDAT_size may be zero if the compressed image stream is truncated; - * this is likely given a broken PNG. - */ - png_ptr->zstream.next_in = buffer; - png_ptr->zstream.avail_in = IDAT_size; -} - -void PNGAPI -png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row) - /* It is valid to call this API with both 'row' and 'dsp_row' NULL, all - * the processing gets done. This is only useful for, either, performance - * testing (but it skips png_combine_row) or if there is a user transform - * or user row callback which actually uses the row data. - */ -{ - if (png_ptr == NULL) - return; - - png_debug2(1, "in png_read_row (row %lu, pass %d)", - (unsigned long)png_ptr->row_number, png_ptr->pass); - - /* Check the row number; if png_read_process_IDAT is called too many times - * if issues an affirm, but, while this is appropriate for the progressive - * reader, it is an app error if it happens here. - * - * Note that when the app does the interlace handling the last row will - * typically be before the last row in the image. - */ - if (png_ptr->read_started && - (png_ptr->interlaced == PNG_INTERLACE_NONE ? - png_ptr->row_number == png_ptr->height-1U : ( -# ifdef PNG_READ_INTERLACING_SUPPORTED - png_ptr->do_interlace ? - png_ptr->pass == 6U && png_ptr->row_number == png_ptr->height-1U : -# endif /* READ_INTERLACING */ - png_ptr->pass == PNG_LAST_PASS(png_ptr->width, png_ptr->height) && - PNG_LAST_PASS_ROW(png_ptr->row_number, png_ptr->pass, - png_ptr->height) - ) - )) - { - png_app_error(png_ptr, "Too many calls to png_read_row"); - return; - } - - /* Check this right at the start; functions like png_read_process_IDAT - * regard this condition as an internal error: - */ - if (png_ptr->zowner != png_IDAT) - png_read_start_IDAT(png_ptr); - - /* So reading has started: */ - png_ptr->read_started = 1; - - for (;;) - { - if (png_ptr->zstream.avail_in == 0) - png_read_IDAT(png_ptr); - - /* So... zstream.next_in may still be 0, but this may be enough for the - * next row if zlib is storing enough output state (it only need be enough - * for one byte, because png_read_process_IDAT keeps the next filter byte, - * so on the last row of the image only one byte might be required.) - * - * png_read_process_IDAT handles the case where the input has ended; mode - * has PNG_AFTER_IDAT set, by either doing png_error or using 0 bytes for - * the data (after issuing a warning.) - */ - switch (png_read_process_IDAT(png_ptr, row, dsp_row, 0/*no save*/)) - { - case png_row_incomplete: - /* more IDAT data needed for row */ - debug(png_ptr->zstream.avail_in == 0); - continue; - - case png_row_repeat: - /* row not in this pass, but the existing row in row_buffer or (if - * transforms are happening) png_struct::transformed_row is - * available from a previous row. - */ - /* FALL THROUGH */ - case png_row_skip: - /* row not in pass and no appropriate data; skip this row, nothing - * more need be done, except the read_row_fn and then only if libpng - * is doing the interlace handling (this is the historical - * behavior!) - */ -# ifdef PNG_READ_INTERLACING_SUPPORTED - if (!png_ptr->do_interlace) continue; -# else /* !do_interlace */ - continue; -# endif /* !do_interlace */ - /* FALL THROUGH */ - case png_row_process: - /* png_read_process_IDAT has done everything we need, the only extra - * required is to call the application row callback. - */ - if (png_ptr->read_row_fn != NULL) - png_ptr->read_row_fn(png_ptr, png_ptr->row_number, - png_ptr->pass); - /* And return now because the next row has been processed; so there - * is exactly one read_row_fn callback for each call to - * png_read_process_IDAT. - */ - return; - - default: - impossible("not reached"); - } - } -} - -/* Read one or more rows of image data. If the image is interlaced, - * and png_set_interlace_handling() has been called, the rows need to - * contain the contents of the rows from the previous pass. If the - * image has alpha or transparency, and png_handle_alpha()[*] has been - * called, the rows contents must be initialized to the contents of the - * screen. - * - * "row" holds the actual image, and pixels are placed in it - * as they arrive. If the image is displayed after each pass, it will - * appear to "sparkle" in. "display_row" can be used to display a - * "chunky" progressive image, with finer detail added as it becomes - * available. If you do not want this "chunky" display, you may pass - * NULL for display_row. If you do not want the sparkle display, and - * you have not called png_handle_alpha(), you may pass NULL for rows. - * If you have called png_handle_alpha(), and the image has either an - * alpha channel or a transparency chunk, you must provide a buffer for - * rows. In this case, you do not have to provide a display_row buffer - * also, but you may. If the image is not interlaced, or if you have - * not called png_set_interlace_handling(), the display_row buffer will - * be ignored, so pass NULL to it. - * - * [*] png_handle_alpha() does not exist yet, as of this version of libpng - */ - -void PNGAPI -png_read_rows(png_structrp png_ptr, png_bytepp row, - png_bytepp display_row, png_uint_32 num_rows) -{ - png_uint_32 i; - png_bytepp rp; - png_bytepp dp; - - png_debug(1, "in png_read_rows"); - - if (png_ptr == NULL) - return; - - rp = row; - dp = display_row; - if (rp != NULL && dp != NULL) - for (i = 0; i < num_rows; i++) - { - png_bytep rptr = *rp++; - png_bytep dptr = *dp++; - - png_read_row(png_ptr, rptr, dptr); - } - - else if (rp != NULL) - for (i = 0; i < num_rows; i++) - { - png_bytep rptr = *rp; - png_read_row(png_ptr, rptr, NULL); - rp++; - } - - else if (dp != NULL) - for (i = 0; i < num_rows; i++) - { - png_bytep dptr = *dp; - png_read_row(png_ptr, NULL, dptr); - dp++; - } -} -#endif /* SEQUENTIAL_READ */ - -#ifdef PNG_READ_IMAGE_SUPPORTED -/* Read the entire image. If the image has an alpha channel or a tRNS - * chunk, and you have called png_handle_alpha()[*], you will need to - * initialize the image to the current image that PNG will be overlaying. - * We set the num_rows again here, in case it was incorrectly set in - * png_read_start_IDAT() by a call to png_read_update_info() or - * png_start_read_image() if png_set_interlace_handling() wasn't called - * prior to either of these functions like it should have been. You can - * only call this function once. If you desire to have an image for - * each pass of a interlaced image, use png_read_rows() instead. - * - * [*] png_handle_alpha() does not exist yet, as of this version of libpng - */ -void PNGAPI -png_read_image(png_structrp png_ptr, png_bytepp image) -{ - png_uint_32 image_height; - int pass, j; - - png_debug(1, "in png_read_image"); - - if (png_ptr == NULL) - return; - - if (png_ptr->zowner != png_IDAT) - pass = png_set_interlace_handling(png_ptr); - - else - { - if (png_ptr->interlaced == 0) - pass = 1; - - else - pass = PNG_INTERLACE_ADAM7_PASSES; - } - - for (j = 0, image_height = png_ptr->height; j < pass; ++j) - { - png_bytepp rp = image; - png_uint_32 i; - - for (i = 0; i < image_height; i++) - { - png_read_row(png_ptr, *rp, NULL); - rp++; - } - } -} -#endif /* READ_IMAGE */ - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the end of the PNG file. Will not read past the end of the - * file, will verify the end is accurate, and will read any comments - * or time information at the end of the file, if info is not NULL. - */ -void PNGAPI -png_read_end(png_structrp png_ptr, png_inforp info_ptr) -{ - png_debug(1, "in png_read_end"); - - if (png_ptr == NULL) - return; - - /* When this routine is entered it is possible that an IDAT chunk still - * remains to be read. There are three conditions: - * - * 1) The app decided to handle IDAT as unknown, libpng will have consumed - * the first IDAT in png_read_info, the rest will be consumed as normal - * chunks by calls to png_handle_chunk below. - * - * 2) The app did not start to read an image, so png_read_start_IDAT was - * not called and png_struct::zowner is not png_IDAT. The first IDAT - * must still be skipped then the code below will skip the remainder. - * - * 3) The app did start to read the image. png_struct::zowner is png_IDAT - * and we need to close down the IDAT reading code. There may also be - * pending IDAT chunks, these are passed to png_read_finish_IDAT here so - * that error detection happens. If the app didn't read all the rows - * libpng will issue an 'extra compressed data' error, we could supress - * that by warning that not all the rows have been read and setting - * png_struct::zstream_error if necessary. - */ -# ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - if (!(png_ptr->known_unknown & 1U)) -# endif - { - if (png_ptr->zowner == png_IDAT) - { - /* Normal case: read to the end of the IDAT chunks. In about - * 5/PNG_IDAT_READ_SIZE cases (typically that's 1:820) zlib will have - * returned all the image data but not read up to the end of the - * Adler32 because the end of the stream had not been read. Make sure - * it gets read here: - */ - if (png_ptr->zstream.avail_in == 0) - png_read_IDAT(png_ptr); - - while (!png_read_finish_IDAT(png_ptr)) { - /* This will adjust zstream.next/avail_in appropriately and if - * necessary read the next chunk. After this avail_in may still - * be zero, but if it is then PNG_AFTER_IDAT should be set. - */ - debug(png_ptr->zstream.avail_in == 0); - png_read_IDAT(png_ptr); - debug(png_ptr->zstream.avail_in > 0 || - (png_ptr->mode & PNG_AFTER_IDAT) != 0); - } - - debug(png_ptr->zstream.avail_in == 0 && png_ptr->zowner == 0); - - /* If this is still an IDAT then it hasn't been finished; at least - * the CRC has not been read. If there is data left in it then - * an error may need to be output. Note that the code below handles - * any additional chunks. - */ - if (png_ptr->chunk_name == png_IDAT) - { - if (png_ptr->chunk_length > 0 && !png_ptr->zstream_error) - { - png_chunk_benign_error(png_ptr, "too much IDAT data (read)"); - png_ptr->zstream_error = 1; - } - - png_crc_finish(png_ptr, png_ptr->chunk_length); - png_read_chunk_header(png_ptr); - } - } - - else if (png_ptr->chunk_name == png_IDAT) - { - /* This IDAT has not been processed, the remainder will be finished - * in the loop. This is the case where IDAT is being skipped because - * the rows weren't read, this is OK, but warn anyway. - */ - png_crc_finish(png_ptr, png_ptr->chunk_length); - png_app_warning(png_ptr, "image reading skipped"); - png_ptr->zstream_error = 1; /* Prevent 'too much IDAT' errors */ - png_read_chunk_header(png_ptr); - } - - else /* This might work, if the signature was read, but just in case: */ - png_app_error(png_ptr, "Missing call to png_read_info"); - } - -# ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - else - { - /* IDAT is unknown, the chunk that terminated the loop must be an IDAT - * and it has been processed. Get a new chunk header. - */ - if (png_ptr->chunk_name == png_IDAT) - png_read_chunk_header(png_ptr); - - else - png_app_error(png_ptr, - "Missing call to png_read_info with unknown IDAT"); - } -# endif - - if ((png_ptr->mode & PNG_HAVE_IEND) == 0) for (;;) - { - switch (png_find_chunk_op(png_ptr)) - { - default: - impossible("invalid chunk op"); - /* FALL THROUGH */ - case png_chunk_skip: - png_crc_finish(png_ptr, png_ptr->chunk_length); - break; - - case png_chunk_unknown: - png_read_sequential_unknown(png_ptr, info_ptr); - break; - - case png_chunk_process_all: - png_handle_chunk(png_ptr, info_ptr); - break; - - case png_chunk_process_part: - debug(png_ptr->chunk_name == png_IDAT); - debug(!(png_ptr->mode & PNG_AFTER_IDAT)); - if (png_ptr->chunk_length > 0 && !png_ptr->zstream_error) - { - png_chunk_benign_error(png_ptr, "too many IDAT chunks"); - png_ptr->zstream_error = 1; - } - - /* Skip it: */ - png_crc_finish(png_ptr, png_ptr->chunk_length); - return; - } - - if ((png_ptr->mode & PNG_HAVE_IEND) != 0) - break; - - png_read_chunk_header(png_ptr); - } -} -#endif /* SEQUENTIAL_READ */ - -/* Free all memory used in the read struct */ -static void -png_read_destroy(png_structrp png_ptr) -{ - png_debug(1, "in png_read_destroy"); - - png_read_free_row_buffers(png_ptr); - - png_free(png_ptr, png_ptr->read_buffer); - png_ptr->read_buffer = NULL; - - if (png_ptr->palette != NULL) - { - png_free(png_ptr, png_ptr->palette); - png_ptr->num_palette = 0; - png_ptr->palette = NULL; - } - -#ifdef PNG_READ_tRNS_SUPPORTED - if (png_ptr->trans_alpha != NULL) - { - png_free(png_ptr, png_ptr->trans_alpha); - png_ptr->num_trans = 0; - png_ptr->trans_alpha = NULL; - } -#endif - - if (png_ptr->zstream.state != NULL) - { - int ret = inflateEnd(&png_ptr->zstream); - - if (ret != Z_OK) - { - png_zstream_error(&png_ptr->zstream, ret); - png_warning(png_ptr, png_ptr->zstream.msg); - } - } - -#ifdef PNG_TRANSFORM_MECH_SUPPORTED - png_transform_free(png_ptr, &png_ptr->transform_list); -#endif - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED - png_free(png_ptr, png_ptr->save_buffer); - png_ptr->save_buffer = NULL; -#endif - -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - png_free(png_ptr, png_ptr->chunk_list); - png_ptr->chunk_list = NULL; -#endif - - /* NOTE: the 'setjmp' buffer may still be allocated and the memory and error - * callbacks are still set at this point. They are required to complete the - * destruction of the png_struct itself. - */ -} - -/* Free all memory used by the read */ -void PNGAPI -png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, - png_infopp end_info_ptr_ptr) -{ - png_structrp png_ptr = NULL; - - png_debug(1, "in png_destroy_read_struct"); - - if (png_ptr_ptr != NULL) - png_ptr = *png_ptr_ptr; - - if (png_ptr == NULL) - return; - - /* libpng 1.6.0: use the API to destroy info structs to ensure consistent - * behavior. Prior to 1.6.0 libpng did extra 'info' destruction in this API. - * The extra was, apparently, unnecessary yet this hides memory leak bugs. - */ - png_destroy_info_struct(png_ptr, end_info_ptr_ptr); - png_destroy_info_struct(png_ptr, info_ptr_ptr); - - *png_ptr_ptr = NULL; - png_read_destroy(png_ptr); - png_destroy_png_struct(png_ptr); -} - -void PNGAPI -png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->read_row_fn = read_row_fn; -} - - -#ifdef PNG_READ_PNG_SUPPORTED -#ifdef __GNUC__ -/* This exists solely to work round a warning from GNU C. */ -static int /* PRIVATE */ -png_gt(size_t a, size_t b) -{ - return a > b; -} -#else -# define png_gt(a,b) ((a) > (b)) -#endif - -void PNGAPI -png_read_png(png_structrp png_ptr, png_inforp info_ptr, int transforms, - voidp params) -{ - if (png_ptr == NULL || info_ptr == NULL) - return; - - /* png_read_info() gives us all of the information from the - * PNG file before the first IDAT (image data chunk). - */ - png_read_info(png_ptr, info_ptr); - if (png_gt(info_ptr->height, PNG_SIZE_MAX/(sizeof (png_bytep)))) - png_error(png_ptr, "Image is too high to process with png_read_png()"); - - /* -------------- image transformations start here ------------------- */ - /* libpng 1.6.10: add code to cause a png_app_error if a selected TRANSFORM - * is not implemented. This will only happen in de-configured (non-default) - * libpng builds. The results can be unexpected - png_read_png may return - * short or mal-formed rows because the transform is skipped. - */ - - /* Tell libpng to strip 16-bit/color files down to 8 bits per color. - */ - if ((transforms & PNG_TRANSFORM_SCALE_16) != 0) - /* Added at libpng-1.5.4. "strip_16" produces the same result that it - * did in earlier versions, while "scale_16" is now more accurate. - */ -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - png_set_scale_16(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SCALE_16 not supported"); -#endif - - /* If both SCALE and STRIP are required pngrtran will effectively cancel the - * latter by doing SCALE first. This is ok and allows apps not to check for - * which is supported to get the right answer. - */ - if ((transforms & PNG_TRANSFORM_STRIP_16) != 0) -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - png_set_strip_16(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_16 not supported"); -#endif - - /* Strip alpha bytes from the input data without combining with - * the background (not recommended). - */ - if ((transforms & PNG_TRANSFORM_STRIP_ALPHA) != 0) -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - png_set_strip_alpha(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_ALPHA not supported"); -#endif - - /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single - * byte into separate bytes (useful for paletted and grayscale images). - */ - if ((transforms & PNG_TRANSFORM_PACKING) != 0) -#ifdef PNG_READ_PACK_SUPPORTED - png_set_packing(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported"); -#endif - - /* Change the order of packed pixels to least significant bit first - * (not useful if you are using png_set_packing). - */ - if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0) -#ifdef PNG_READ_PACKSWAP_SUPPORTED - png_set_packswap(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported"); -#endif - - /* Expand paletted colors into true RGB triplets - * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel - * Expand paletted or RGB images with transparency to full alpha - * channels so the data will be available as RGBA quartets. - */ - if ((transforms & PNG_TRANSFORM_EXPAND) != 0) -#ifdef PNG_READ_EXPAND_SUPPORTED - png_set_expand(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND not supported"); -#endif - - /* We don't handle background color, gamma transformation, or quantizing. */ - - /* Invert monochrome files to have 0 as white and 1 as black */ - if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0) -#ifdef PNG_READ_INVERT_SUPPORTED - png_set_invert_mono(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported"); -#endif - - /* If you want to shift the pixel values from the range [0,255] or - * [0,65535] to the original [0,7] or [0,31], or whatever range the - * colors were originally in: - */ - if ((transforms & PNG_TRANSFORM_SHIFT) != 0) -#ifdef PNG_READ_SHIFT_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sBIT) != 0) - png_set_shift(png_ptr, &info_ptr->sig_bit); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported"); -#endif - - /* Flip the RGB pixels to BGR (or RGBA to BGRA) */ - if ((transforms & PNG_TRANSFORM_BGR) != 0) -#ifdef PNG_READ_BGR_SUPPORTED - png_set_bgr(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported"); -#endif - - /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ - if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0) -#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED - png_set_swap_alpha(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported"); -#endif - - /* Swap bytes of 16-bit files to least significant byte first */ - if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0) -#ifdef PNG_READ_SWAP_SUPPORTED - png_set_swap(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported"); -#endif - -/* Added at libpng-1.2.41 */ - /* Invert the alpha channel from opacity to transparency */ - if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0) -#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED - png_set_invert_alpha(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported"); -#endif - -/* Added at libpng-1.2.41 */ - /* Expand grayscale image to RGB */ - if ((transforms & PNG_TRANSFORM_GRAY_TO_RGB) != 0) -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - png_set_gray_to_rgb(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_GRAY_TO_RGB not supported"); -#endif - -/* Added at libpng-1.5.4 */ - if ((transforms & PNG_TRANSFORM_EXPAND_16) != 0) -#ifdef PNG_READ_EXPAND_16_SUPPORTED - png_set_expand_16(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND_16 not supported"); -#endif - - /* We don't handle adding filler bytes */ - - /* We use png_read_image and rely on that for interlace handling, but we also - * call png_read_update_info therefore must turn on interlace handling now: - */ - (void)png_set_interlace_handling(png_ptr); - - /* Optional call to gamma correct and add the background to the palette - * and update info structure. REQUIRED if you are expecting libpng to - * update the palette for you (i.e., you selected such a transform above). - */ - png_read_update_info(png_ptr, info_ptr); - - /* -------------- image transformations end here ------------------- */ - - png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); - if (info_ptr->row_pointers == NULL) - { - png_uint_32 iptr; - png_alloc_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr); - - info_ptr->row_pointers = png_voidcast(png_bytepp, png_malloc(png_ptr, - info_ptr->height * (sizeof (png_bytep)))); - - for (iptr=0; iptrheight; iptr++) - info_ptr->row_pointers[iptr] = NULL; - - info_ptr->free_me |= PNG_FREE_ROWS; - - for (iptr = 0; iptr < info_ptr->height; iptr++) - info_ptr->row_pointers[iptr] = png_voidcast(png_bytep, - png_malloc(png_ptr, rowbytes)); - } - - png_read_image(png_ptr, info_ptr->row_pointers); - info_ptr->valid |= PNG_INFO_IDAT; - - /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ - png_read_end(png_ptr, info_ptr); - - PNG_UNUSED(params) -} -#endif /* READ_PNG */ - -#ifdef PNG_SIMPLIFIED_READ_SUPPORTED -/* SIMPLIFIED READ - * - * This code currently relies on the sequential reader, though it could easily - * be made to work with the progressive one. - */ -/* Arguments to png_image_finish_read: */ - -/* Encoding of PNG data (used by the color-map code) */ -# define P_NOTSET 0 /* File encoding not yet known */ -# define P_sRGB 1 /* 8-bit encoded to sRGB gamma */ -# define P_LINEAR 2 /* 16-bit linear: not encoded, NOT pre-multiplied! */ -# define P_FILE 3 /* 8-bit encoded to file gamma, not sRGB or linear */ -# define P_LINEAR8 4 /* 8-bit linear: only from a file value */ -# define P_FILE8 5 /* 8-bit encoded to file gamma but not significant bits */ - -/* Color-map processing: after libpng has run on the PNG image further - * processing may be needed to convert the data to color-map indices. - */ -#define PNG_CMAP_NONE 0 -#define PNG_CMAP_GA 1 /* Process GA data to a color-map with alpha */ -#define PNG_CMAP_TRANS 2 /* Process GA data to a background index */ -#define PNG_CMAP_RGB 3 /* Process RGB data */ -#define PNG_CMAP_RGB_ALPHA 4 /* Process RGBA data */ - -/* The following document where the background is for each processing case. */ -#define PNG_CMAP_NONE_BACKGROUND 256 -#define PNG_CMAP_GA_BACKGROUND 231 -#define PNG_CMAP_TRANS_BACKGROUND 254 -#define PNG_CMAP_RGB_BACKGROUND 256 -#define PNG_CMAP_RGB_ALPHA_BACKGROUND 216 - -typedef struct -{ - /* Arguments: */ - png_imagep image; - png_voidp buffer; - ptrdiff_t row_stride; - png_voidp colormap; - png_const_colorp background; - /* Local variables: */ - png_voidp local_row; - png_voidp first_row; - ptrdiff_t row_bytes; /* step between rows */ - int file_encoding; /* E_ values above */ - png_fixed_point file_to_sRGB; /* Cached correction factor */ - int colormap_processing; /* PNG_CMAP_ values above */ - png_byte sBIT[4]; /* Significant bits for channels */ -} png_image_read_control; - -/* Do all the *safe* initialization - 'safe' means that png_error won't be - * called, so setting up the jmp_buf is not required. This means that anything - * called from here must *not* call png_malloc - it has to call png_malloc_warn - * instead so that control is returned safely back to this routine. - */ -static int -png_image_read_init(png_imagep image) -{ - if (image->opaque == NULL) - { - png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, image, - png_safe_error, png_safe_warning); - - /* And set the rest of the structure to NULL to ensure that the various - * fields are consistent. - */ - memset(image, 0, (sizeof *image)); - image->version = PNG_IMAGE_VERSION; - - if (png_ptr != NULL) - { - png_infop info_ptr = png_create_info_struct(png_ptr); - - if (info_ptr != NULL) - { - png_controlp control = png_voidcast(png_controlp, - png_malloc_warn(png_ptr, (sizeof *control))); - - if (control != NULL) - { - memset(control, 0, (sizeof *control)); - - control->png_ptr = png_ptr; - control->info_ptr = info_ptr; - control->for_write = 0; - - image->opaque = control; - return 1; - } - - /* Error clean up */ - png_destroy_info_struct(png_ptr, &info_ptr); - } - - png_destroy_read_struct(&png_ptr, NULL, NULL); - } - - return png_image_error(image, "png_image_read: out of memory"); - } - - return png_image_error(image, "png_image_read: opaque pointer not NULL"); -} - -/* Utility to find the base format of a PNG file from a png_struct. */ -static png_uint_32 -png_image_format(png_structrp png_ptr) -{ - png_uint_32 format = 0; - - if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - format |= PNG_FORMAT_FLAG_COLOR; - - if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) - format |= PNG_FORMAT_FLAG_ALPHA; - - /* Use png_ptr here, not info_ptr, because by examination png_handle_tRNS - * sets the png_struct fields; that's all we are interested in here. The - * precise interaction with an app call to png_set_tRNS and PNG file reading - * is unclear. - */ - else if (png_ptr->num_trans > 0) - format |= PNG_FORMAT_FLAG_ALPHA; - - if (png_ptr->bit_depth == 16) - format |= PNG_FORMAT_FLAG_LINEAR; - - if ((png_ptr->color_type & PNG_COLOR_MASK_PALETTE) != 0) - format |= PNG_FORMAT_FLAG_COLORMAP; - - return format; -} - -/* Is the given gamma significantly different from sRGB? - */ -static int -png_gamma_not_sRGB(png_fixed_point g) -{ - /* An uninitialized gamma is assumed to be sRGB for the simplified API. */ - return g != 0 && !PNG_GAMMA_IS_sRGB(g); -} - -/* Do the main body of a 'png_image_begin_read' function; read the PNG file - * header and fill in all the information. This is executed in a safe context, - * unlike the init routine above. - */ -static int -png_image_read_header(png_voidp argument) -{ - png_imagep image = png_voidcast(png_imagep, argument); - png_structrp png_ptr = image->opaque->png_ptr; - png_inforp info_ptr = image->opaque->info_ptr; - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED - png_set_benign_errors(png_ptr, 1/*warn*/); -#endif - png_read_info(png_ptr, info_ptr); - - /* Do this the fast way; just read directly out of png_struct. */ - image->width = png_ptr->width; - image->height = png_ptr->height; - - { - png_uint_32 format = png_image_format(png_ptr); - - image->format = format; - -#ifdef PNG_COLORSPACE_SUPPORTED - /* Does the colorspace match sRGB? If there is no color endpoint - * (colorant) information assume yes, otherwise require the - * 'ENDPOINTS_MATCHP_sRGB' colorspace flag to have been set. If the - * colorspace has been determined to be invalid ignore it. - */ - if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags - & (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB| - PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS)) - image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB; -#endif - } - - /* We need the maximum number of entries regardless of the format the - * application sets here. - */ - { - png_uint_32 cmap_entries; - - switch (png_ptr->color_type) - { - case PNG_COLOR_TYPE_GRAY: - cmap_entries = 1U << png_ptr->bit_depth; - break; - - case PNG_COLOR_TYPE_PALETTE: - cmap_entries = png_ptr->num_palette; - break; - - default: - cmap_entries = 256; - break; - } - - if (cmap_entries > 256) - cmap_entries = 256; - - image->colormap_entries = cmap_entries; - } - - return 1; -} - -static void -png_image_get_sBIT(png_image_read_control *display) - /* Utility to cache the sBIT values. This uses the information from the - * png_struct not png_info because it may be needed after the sBIT - * information in png_info has been invalidated. - */ -{ - if (display->sBIT[0] == 0) - { - const png_const_structrp png_ptr = display->image->opaque->png_ptr; - const unsigned int color_type = png_ptr->color_type; - const png_byte bit_depth = - (color_type & PNG_COLOR_MASK_PALETTE) ? 8U : png_ptr->bit_depth; - - memset(display->sBIT, bit_depth, sizeof display->sBIT); - - if (color_type & PNG_COLOR_MASK_COLOR) - { - if (png_ptr->sig_bit.red > 0 && png_ptr->sig_bit.red < bit_depth) - display->sBIT[0] = png_ptr->sig_bit.red; - if (png_ptr->sig_bit.green > 0 && png_ptr->sig_bit.green < bit_depth) - display->sBIT[1] = png_ptr->sig_bit.green; - if (png_ptr->sig_bit.blue > 0 && png_ptr->sig_bit.blue < bit_depth) - display->sBIT[2] = png_ptr->sig_bit.blue; - } - - else - { - if (png_ptr->sig_bit.gray > 0 && png_ptr->sig_bit.gray < bit_depth) - display->sBIT[2] = display->sBIT[1] = display->sBIT[0] = - png_ptr->sig_bit.gray; - } - - if (color_type & PNG_COLOR_MASK_ALPHA) - { - if (png_ptr->sig_bit.alpha > 0 && png_ptr->sig_bit.alpha < bit_depth) - display->sBIT[3] = png_ptr->sig_bit.alpha; - } - } -} - -#ifdef PNG_STDIO_SUPPORTED -int PNGAPI -png_image_begin_read_from_stdio(png_imagep image, FILE* file) -{ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - if (file != NULL) - { - if (png_image_read_init(image) != 0 && - png_image_init_io(image, file) != 0) - return png_safe_execute(image, png_image_read_header, image); - } - - else - return png_image_error(image, - "png_image_begin_read_from_stdio: invalid argument"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION"); - - return 0; -} - -int PNGAPI -png_image_begin_read_from_file(png_imagep image, const char *file_name) -{ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - if (file_name != NULL) - { - FILE *fp = fopen(file_name, "rb"); - - if (fp != NULL) - { - if (png_image_read_init(image) != 0 && - png_image_init_io(image, fp) != 0) - { - image->opaque->owned_file = 1; - return png_safe_execute(image, png_image_read_header, image); - } - - /* Clean up: just the opened file. */ - (void)fclose(fp); - } - - else - return png_image_error(image, strerror(errno)); - } - - else - return png_image_error(image, - "png_image_begin_read_from_file: invalid argument"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION"); - - return 0; -} -#endif /* STDIO */ - -static void PNGCBAPI -png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need) -{ - if (png_ptr != NULL) - { - png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr); - if (image != NULL) - { - png_controlp cp = image->opaque; - if (cp != NULL) - { - png_const_bytep memory = cp->memory; - png_size_t size = cp->size; - - if (memory != NULL && size >= need) - { - memcpy(out, memory, need); - cp->memory = memory + need; - cp->size = size - need; - return; - } - - png_error(png_ptr, "read beyond end of data"); - } - } - - png_error(png_ptr, "invalid memory read"); - } -} - -static int -image_init_memory_io(png_voidp param) - /* Set the read function and pointer for a memory read, the io pointer is - * just the imagep so it is passed in directly. - */ -{ - png_imagep image = png_voidcast(png_imagep, param); - png_set_read_fn(image->opaque->png_ptr, image, png_image_memory_read); - return 1; -} - -int PNGAPI -png_image_begin_read_from_memory(png_imagep image, png_const_voidp memory, - png_size_t size) -{ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - if (memory != NULL && size > 0) - { - if (png_image_read_init(image) != 0) - { - /* Now set the IO functions to read from the memory buffer and - * store it into io_ptr. Again do this in-place to avoid calling a - * libpng function that requires error handling. - */ - image->opaque->memory = png_voidcast(png_const_bytep, memory); - image->opaque->size = size; - - return png_safe_execute(image, image_init_memory_io, image) && - png_safe_execute(image, png_image_read_header, image); - } - } - - else - return png_image_error(image, - "png_image_begin_read_from_memory: invalid argument"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION"); - - return 0; -} - -/* Utility function to skip chunks that are not used by the simplified image - * read functions and an appropriate macro to call it. - */ -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -static void -png_image_skip_unused_chunks(png_structrp png_ptr) -{ - /* Prepare the reader to ignore all recognized chunks whose data will not - * be used, i.e., all chunks recognized by libpng except for those - * involved in basic image reading: - * - * IHDR, PLTE, IDAT, IEND - * - * Or image data handling: - * - * tRNS, bKGD, gAMA, cHRM, sRGB, [iCCP] and sBIT. - * - * This provides a small performance improvement and eliminates any - * potential vulnerability to security problems in the unused chunks. - * - * At present the iCCP chunk data isn't used, so iCCP chunk can be ignored - * too. This allows the simplified API to be compiled without iCCP support, - * however if the support is there the chunk is still checked to detect - * errors (which are unfortunately quite common.) - */ - { - static PNG_CONST png_byte chunks_to_process[] = { - 98, 75, 71, 68, '\0', /* bKGD */ - 99, 72, 82, 77, '\0', /* cHRM */ - 103, 65, 77, 65, '\0', /* gAMA */ -# ifdef PNG_READ_iCCP_SUPPORTED - 105, 67, 67, 80, '\0', /* iCCP */ -# endif - 115, 66, 73, 84, '\0', /* sBIT */ - 115, 82, 71, 66, '\0', /* sRGB */ - }; - - /* Ignore unknown chunks and all other chunks except for the - * IHDR, PLTE, tRNS, IDAT, and IEND chunks. - */ - png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER, - NULL, -1); - - /* But do not ignore image data handling chunks */ - png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT, - chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5); - } -} - -# define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p) -#else -# define PNG_SKIP_CHUNKS(p) ((void)0) -#endif /* HANDLE_AS_UNKNOWN */ - -/* The following macro gives the exact rounded answer for all values in the - * range 0..255 (it actually divides by 51.2, but the rounding still generates - * the correct numbers 0..5 - */ -#define PNG_DIV51(v8) (((v8) * 5 + 130) >> 8) - -/* Utility functions to make particular color-maps */ -static void -set_file_encoding(png_image_read_control *display) -{ - /* First test for an encoding close to linear: */ - if (png_need_gamma_correction(display->image->opaque->png_ptr, - 0/*PNG gamma*/, 0/*not sRGB*/)) - { - png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma; - - /* Now look for one close to sRGB: */ - if (png_gamma_not_sRGB(g)) - display->file_encoding = P_FILE; - - else - display->file_encoding = P_sRGB; - } - - else - display->file_encoding = P_LINEAR8; -} - -/* For colormap entries we end up doing the gamma correction here and the - * following routines are provided to separate out the code. In all cases the - * input value is in the range 0..255 and is encoded P_FILE with the gamma value - * stored in the png_struct colorspace. - */ -static void -init_correct(png_const_structrp png_ptr, png_fixed_point *correct) -{ - /* Record the convertion necessary to get from the encoding values to - * sRGB. If this overflows just store FP_1. - * - * NOTE: this code used to store, and use, a convertion factor to - * linear then use the sRGB encoding tables to get back to sRGB, but - * this smashes the low values; the ones which fall in the linear part - * of the sRGB transfer function. - * - * The new version of this code assumes an encoding which is neither - * linear nor sRGB is a power law transform of the sRGB curve, not - * linear values. This is somewhat at odds with a precise reading of - * the PNG spec, but given that we are trying to produce sRGB values - * here it is most likely to be correct. - */ - affirm(png_ptr->colorspace.gamma > 0); - - if (!png_muldiv(correct, PNG_GAMMA_sRGB_INVERSE, PNG_FP_1, - png_ptr->colorspace.gamma)) - *correct = PNG_FP_1; -} - -static png_uint_32 -update_for_sBIT(png_uint_32 value, unsigned int significant_bits, - unsigned int bit_depth) - /* Return a bit_depth value adjusted for the number of significant bits in - * the value. - */ -{ - if (significant_bits < bit_depth) - { - value >>= bit_depth - significant_bits; - /* Now scale back to bit_depth, taking care not to overflow when 'value' - * is (1<image->opaque->png_ptr; - - debug(value <= 255U && significant_bits <= 8U && significant_bits > 0U); - - if (display->file_to_sRGB == 0) - init_correct(png_ptr, &display->file_to_sRGB); - - /* Now simply apply this correction factor and scale back to 8 bits. */ - if (display->file_to_sRGB != PNG_FP_1) - value = png_gamma_nxmbit_correct(value >> (8U-significant_bits), - display->file_to_sRGB, significant_bits, 8U); - - else if (significant_bits < 8U) - value = update_for_sBIT(value, significant_bits, 8U); - - return value; -} - -static png_uint_32 -convert_to_linear(png_image_read_control *display, png_uint_32 value, - unsigned int significant_bits) -{ - /* Converts an 8-bit value from P_FILE to 16-bit P_LINEAR */ - png_const_structrp png_ptr = display->image->opaque->png_ptr; - - debug(value <= 255U && significant_bits <= 8U && significant_bits > 0U); - - if (display->file_to_sRGB == 0) - init_correct(png_ptr, &display->file_to_sRGB); - - /* Use this correction to get a 16-bit sRGB value: */ - if (display->file_to_sRGB != PNG_FP_1) - value = png_gamma_nxmbit_correct(value >> (8U-significant_bits), - display->file_to_sRGB, significant_bits, 16U); - - else - { - value *= 257U; - - if (significant_bits < 8U) - value = update_for_sBIT(value, significant_bits, 16U); - } - - /* Now convert this back to linear, using the correct transfer function. */ - if (value <= 2650U /* 65535 * 0.04045 */) - { - /* We want to divide a 12-bit number by 12.92, do this by scaling to 32 - * bits then dividing by 2^24, with rounding: - */ - value = (value * 1298546U + 649273U) >> 24; - } - - else - { - /* Calculate for v in the range 0.04045..1.0 calculate: - * - * ((v + 0.055)/1.055)^2.4 - * - * the gamma correction function needs a 16-bit value: - */ - value *= 62119U; - value += 223904831U+32768U; /* cannot overflow; test with 65535 */ - value = png_gamma_nxmbit_correct(value >> 16, 240000, 16U, 16U); - } - - return value; -} - -static unsigned int -decode_gamma(png_image_read_control *display, png_uint_32 value, - unsigned int significant_bits, int encoding) -{ - int do_sBIT = 0; - - if (encoding == P_FILE) /* double check */ - encoding = display->file_encoding, do_sBIT = 1; - - if (encoding == P_NOTSET) /* must be the file encoding */ - { - set_file_encoding(display); - encoding = display->file_encoding; - } - - switch (encoding) - { - case P_FILE: - /* This is a file value, so the sBIT, if any, needs to be used. */ - value = convert_to_linear(display, value, significant_bits); - break; - - case P_sRGB: - if (do_sBIT) - value = update_for_sBIT(value, significant_bits, 8U); - - value = png_sRGB_table[value]; - break; - - case P_LINEAR: - if (do_sBIT) - value = update_for_sBIT(value, significant_bits, 16U); - break; - - case P_LINEAR8: - value *= 257; - if (do_sBIT) - value = update_for_sBIT(value, significant_bits, 16U); - break; - - default: - png_impossiblepp(display->image->opaque->png_ptr, - "unexpected encoding"); - break; - } - - return value; -} - -static png_uint_32 -png_colormap_compose(png_image_read_control *display, - png_uint_32 foreground, unsigned int foreground_significant_bits, - int foreground_encoding, png_uint_32 alpha, - png_uint_32 background, int encoding) -{ - /* The file value is composed on the background, the background has the given - * encoding and so does the result, the file is encoded with P_FILE and the - * file and alpha are 8-bit values. The (output) encoding will always be - * P_LINEAR or P_sRGB. - */ - png_uint_32 f = decode_gamma(display, foreground, - foreground_significant_bits, foreground_encoding); - png_uint_32 b = decode_gamma(display, background, 0U/*UNUSED*/, encoding); - - /* The alpha is always an 8-bit value (it comes from the palette), the value - * scaled by 255 is what PNG_sRGB_FROM_LINEAR requires. - */ - f = f * alpha + b * (255-alpha); - - if (encoding == P_LINEAR) - { - /* Scale to 65535; divide by 255, approximately (in fact this is extremely - * accurate, it divides by 255.00000005937181414556, with no overflow.) - */ - f *= 257; /* Now scaled by 65535 */ - f += f >> 16; - f = (f+32768) >> 16; - } - - else /* P_sRGB */ - f = PNG_sRGB_FROM_LINEAR(display->image->opaque->png_ptr, f); - - return f; -} - -/* NOTE: P_LINEAR values to this routine must be 16-bit, but P_FILE values must - * be 8-bit. - */ -static void -png_create_colormap_entry(png_image_read_control *display, - png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue, - png_uint_32 alpha, int encoding) -{ - png_imagep image = display->image; -# define png_ptr image->opaque->png_ptr /* for error messages */ - const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ? - P_LINEAR : P_sRGB; - const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 && - (red != green || green != blue); - int use_sBIT = encoding == P_FILE; - - affirm(ip <= 255); - implies(encoding != P_LINEAR, red <= 255U && green <= 255U && blue <= 255U - && display->sBIT[0] <= 8U && display->sBIT[1] <= 8U - && display->sBIT[2] <= 8U && display->sBIT[3] <= 8U); - - /* This is a hack for the grayscale colormap below. */ - if (encoding == P_FILE8) - encoding = P_FILE; - - /* Update the cache with whether the file gamma is significantly different - * from sRGB. - */ - if (encoding == P_FILE) - { - if (display->file_encoding == P_NOTSET) - set_file_encoding(display); - - /* Note that the cached value may be P_FILE too. */ - encoding = display->file_encoding; - if (use_sBIT) - png_image_get_sBIT(display); - } - - if (encoding == P_FILE) - { - if (convert_to_Y != 0 || output_encoding == P_LINEAR) - { - red = convert_to_linear(display, red, - use_sBIT ? display->sBIT[0] : 8U); - green = convert_to_linear(display, green, - use_sBIT ? display->sBIT[1] : 8U); - blue = convert_to_linear(display, blue, - use_sBIT ? display->sBIT[2] : 8U); - alpha *= 257U; - if (use_sBIT) - alpha = update_for_sBIT(alpha, display->sBIT[3], 16U); - - encoding = P_LINEAR; - use_sBIT = 0; - } - - else - { - red = convert_to_sRGB(display, red, - use_sBIT ? display->sBIT[0] : 8U); - green = convert_to_sRGB(display, green, - use_sBIT ? display->sBIT[1] : 8U); - blue = convert_to_sRGB(display, blue, - use_sBIT ? display->sBIT[2] : 8U); - if (use_sBIT) - alpha = update_for_sBIT(alpha, display->sBIT[3], 8U); - encoding = P_sRGB; - use_sBIT = 0; - } - } - - else if (encoding == P_LINEAR8) - { - /* This encoding corresponds to a colormap with linear RGB entries, this - * is not a very sensible encoding but it does happen with the PNGSuite - * test images. - */ - red *= 257; - green *= 257; - blue *= 257; - alpha *= 257; - if (use_sBIT) - { - red = update_for_sBIT(red, display->sBIT[0], 16U); - green = update_for_sBIT(green, display->sBIT[1], 16U); - blue = update_for_sBIT(blue, display->sBIT[2], 16U); - alpha = update_for_sBIT(alpha, display->sBIT[3], 16U); - use_sBIT = 0; - } - encoding = P_LINEAR; - } - - else if (encoding == P_sRGB && - (convert_to_Y != 0 || output_encoding == P_LINEAR)) - { - /* The values are 8-bit sRGB values, but must be converted to 16-bit - * linear. - */ - if (use_sBIT) - { - - red = convert_to_linear(display, red, display->sBIT[0]); - green = convert_to_linear(display, green, display->sBIT[1]); - blue = convert_to_linear(display, blue, display->sBIT[2]); - alpha = update_for_sBIT(alpha * 257U, display->sBIT[3], 16U); - use_sBIT = 0; - } - - else - { - red = png_sRGB_table[red]; - green = png_sRGB_table[green]; - blue = png_sRGB_table[blue]; - alpha *= 257; - } - - encoding = P_LINEAR; - } - - else if (encoding == P_sRGB && use_sBIT) - { - debug(output_encoding == P_sRGB); /* P_LINEAR handled above */ - red = update_for_sBIT(red, display->sBIT[0], 8U); - green = update_for_sBIT(green, display->sBIT[1], 8U); - blue = update_for_sBIT(blue, display->sBIT[2], 8U); - alpha = update_for_sBIT(alpha, display->sBIT[3], 8U); - use_sBIT = 0; - } - - debug(!use_sBIT); /* it should have been handled above */ - - /* This is set if the color isn't gray but the output is. */ - if (encoding == P_LINEAR) - { - if (convert_to_Y != 0) - { - /* NOTE: these values are copied from png_do_rgb_to_gray */ - png_uint_32 y = 6968 * red + 23434 * green + 2366 * blue; - - if (output_encoding == P_LINEAR) - y = (y + 16384) >> 15; - - else - { - /* y is scaled by 32768, we need it scaled by 255: */ - y = (y + 128) >> 8; - y *= 255; - y = PNG_sRGB_FROM_LINEAR(png_ptr, (y + 64) >> 7); - alpha = PNG_DIV257(alpha); - encoding = P_sRGB; - } - - blue = red = green = y; - } - - else if (output_encoding == P_sRGB) - { - red = PNG_sRGB_FROM_LINEAR(png_ptr, red * 255); - green = PNG_sRGB_FROM_LINEAR(png_ptr, green * 255); - blue = PNG_sRGB_FROM_LINEAR(png_ptr, blue * 255); - alpha = PNG_DIV257(alpha); - encoding = P_sRGB; - } - } - - if (encoding != output_encoding) - png_impossiblepp(png_ptr, "bad encoding"); - - /* Store the value. */ - { -# ifdef PNG_FORMAT_AFIRST_SUPPORTED - const int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 && - (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; -# else -# define afirst 0 -# endif -# ifdef PNG_FORMAT_BGR_SUPPORTED - const int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; -# else -# define bgr 0 -# endif - - if (output_encoding == P_LINEAR) - { - png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap); - - entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format); - - /* The linear 16-bit values must be pre-multiplied by the alpha channel - * value, if less than 65535 (this is, effectively, composite on black - * if the alpha channel is removed.) - */ - switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format)) - { - case 4: - entry[afirst ? 0 : 3] = png_check_u16(png_ptr, alpha); - /* FALL THROUGH */ - - case 3: - if (alpha < 65535) - { - if (alpha > 0) - { - blue = (blue * alpha + 32767U)/65535U; - green = (green * alpha + 32767U)/65535U; - red = (red * alpha + 32767U)/65535U; - } - - else - red = green = blue = 0; - } - entry[afirst + (2 ^ bgr)] = png_check_u16(png_ptr, blue); - entry[afirst + 1] = png_check_u16(png_ptr, green); - entry[afirst + bgr] = png_check_u16(png_ptr, red); - break; - - case 2: - entry[1 ^ afirst] = png_check_u16(png_ptr, alpha); - /* FALL THROUGH */ - - case 1: - if (alpha < 65535) - { - if (alpha > 0) - green = (green * alpha + 32767U)/65535U; - - else - green = 0; - } - entry[afirst] = png_check_u16(png_ptr, green); - break; - - default: - break; - } - } - - else /* output encoding is P_sRGB */ - { - png_bytep entry = png_voidcast(png_bytep, display->colormap); - - entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format); - - png_affirmpp(png_ptr, output_encoding == P_sRGB); - - switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format)) - { - case 4: - entry[afirst ? 0 : 3] = png_check_byte(png_ptr, alpha); - - case 3: - entry[afirst + (2 ^ bgr)] = png_check_byte(png_ptr, blue); - entry[afirst + 1] = png_check_byte(png_ptr, green); - entry[afirst + bgr] = png_check_byte(png_ptr, red); - break; - - case 2: - entry[1 ^ afirst] = png_check_byte(png_ptr, alpha); - - case 1: - entry[afirst] = png_check_byte(png_ptr, green); - break; - - default: - break; - } - } - -# ifdef afirst -# undef afirst -# endif -# ifdef bgr -# undef bgr -# endif - } - -# undef png_ptr -} - -static int -make_gray_file_colormap(png_image_read_control *display) -{ - unsigned int i; - - for (i=0; i<256; ++i) - png_create_colormap_entry(display, i, i, i, i, 255, P_FILE8); - - return i; -} - -static int -make_gray_colormap(png_image_read_control *display) -{ - unsigned int i; - - for (i=0; i<256; ++i) - png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB); - - return i; -} -#define PNG_GRAY_COLORMAP_ENTRIES 256 - -static int -make_ga_colormap(png_image_read_control *display) -{ - unsigned int i, a; - - /* Alpha is retained, the output will be a color-map with entries - * selected by six levels of alpha. One transparent entry, 6 gray - * levels for all the intermediate alpha values, leaving 230 entries - * for the opaque grays. The color-map entries are the six values - * [0..5]*51, the GA processing uses PNG_DIV51(value) to find the - * relevant entry. - * - * if (alpha > 229) // opaque - * { - * // The 231 entries are selected to make the math below work: - * base = 0; - * entry = (231 * gray + 128) >> 8; - * } - * else if (alpha < 26) // transparent - * { - * base = 231; - * entry = 0; - * } - * else // partially opaque - * { - * base = 226 + 6 * PNG_DIV51(alpha); - * entry = PNG_DIV51(gray); - * } - */ - i = 0; - while (i < 231) - { - unsigned int gray = (i * 256 + 115) / 231; - png_create_colormap_entry(display, i++, gray, gray, gray, 255, P_sRGB); - } - - /* 255 is used here for the component values for consistency with the code - * that undoes premultiplication in pngwrite.c. - */ - png_create_colormap_entry(display, i++, 255, 255, 255, 0, P_sRGB); - - for (a=1; a<5; ++a) - { - unsigned int g; - - for (g=0; g<6; ++g) - png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51, - P_sRGB); - } - - return i; -} - -#define PNG_GA_COLORMAP_ENTRIES 256 - -static int -make_rgb_colormap(png_image_read_control *display) -{ - unsigned int i, r; - - /* Build a 6x6x6 opaque RGB cube */ - for (i=r=0; r<6; ++r) - { - unsigned int g; - - for (g=0; g<6; ++g) - { - unsigned int b; - - for (b=0; b<6; ++b) - png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255, - P_sRGB); - } - } - - return i; -} - -#define PNG_RGB_COLORMAP_ENTRIES 216 - -/* Return a palette index to the above palette given three 8-bit sRGB values. */ -#define PNG_RGB_INDEX(r,g,b) \ - (png_check_byte(image->opaque->png_ptr,\ - 6 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b))) - -static int -png_image_read_colormap(png_voidp argument) -{ - png_image_read_control *display = - png_voidcast(png_image_read_control*, argument); - const png_imagep image = display->image; - - const png_structrp png_ptr = image->opaque->png_ptr; - const png_uint_32 output_format = image->format; - const int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ? - P_LINEAR : P_sRGB; - - unsigned int cmap_entries; - unsigned int output_processing; /* Output processing option */ - unsigned int data_encoding = P_NOTSET; /* Encoding libpng must produce */ - - /* Background information; the background color and the index of this color - * in the color-map if it exists (else 256). - */ - unsigned int background_index = 256; - png_uint_32 back_r, back_g, back_b; - - /* Flags to accumulate things that need to be done to the input. */ - int expand_tRNS = 0; - - /* Exclude the NYI feature of compositing onto a color-mapped buffer; it is - * very difficult to do, the results look awful, and it is difficult to see - * what possible use it is because the application can't control the - * color-map. - */ - if (((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 || - png_ptr->num_trans > 0) /* alpha in input */ && - ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */) - { - if (output_encoding == P_LINEAR) /* compose on black */ - back_b = back_g = back_r = 0; - - else if (display->background == NULL /* no way to remove it */) - png_error(png_ptr, - "background color must be supplied to remove alpha/transparency"); - - /* Get a copy of the background color (this avoids repeating the checks - * below.) The encoding is 8-bit sRGB or 16-bit linear, depending on the - * output format. - */ - else - { - back_g = display->background->green; - if ((output_format & PNG_FORMAT_FLAG_COLOR) != 0) - { - back_r = display->background->red; - back_b = display->background->blue; - } - else - back_b = back_r = back_g; - } - } - - else if (output_encoding == P_LINEAR) - back_b = back_r = back_g = 65535; - - else - back_b = back_r = back_g = 255; - - /* Default the input file gamma if required - this is necessary because - * libpng assumes that if no gamma information is present the data is in the - * output format, but the simplified API deduces the gamma from the input - * format. - */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0) - { - /* Do this directly, not using the png_colorspace functions, to ensure - * that it happens even if the colorspace is invalid (though probably if - * it is the setting will be ignored) Note that the same thing can be - * achieved at the application interface with png_set_gAMA. - */ - if (png_ptr->bit_depth == 16 && - (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) - png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR; - - else - png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE; - - /* Make sure libpng doesn't ignore the setting: */ - if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) - png_ptr->colorspace.flags = PNG_COLORSPACE_HAVE_GAMMA; - - else - png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; - } - - /* Decide what to do based on the PNG color type of the input data. The - * utility function png_create_colormap_entry deals with most aspects of the - * output transformations; this code works out how to produce bytes of - * color-map entries from the original format. - */ - switch (png_ptr->color_type) - { - case PNG_COLOR_TYPE_GRAY: - if (png_ptr->bit_depth <= 8) - { - /* There at most 256 colors in the output, regardless of - * transparency. - */ - unsigned int step, i, val, trans = 256/*ignore*/, back_alpha = 0; - - cmap_entries = 1U << png_ptr->bit_depth; - if (cmap_entries > image->colormap_entries) - png_error(png_ptr, "gray[8] color-map: too few entries"); - - step = 255 / (cmap_entries - 1); - output_processing = PNG_CMAP_NONE; - - /* If there is a tRNS chunk then this either selects a transparent - * value or, if the output has no alpha, the background color. - */ - if (png_ptr->num_trans > 0) - { - trans = png_ptr->trans_color.gray; - - if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) - back_alpha = output_encoding == P_LINEAR ? 65535 : 255; - } - - /* png_create_colormap_entry just takes an RGBA and writes the - * corresponding color-map entry using the format from 'image', - * including the required conversion to sRGB or linear as - * appropriate. The input values are always either sRGB (if the - * gamma correction flag is 0) or 0..255 scaled file encoded values - * (if the function must gamma correct them). - */ - for (i=val=0; ibit_depth < 8) - png_set_packing(png_ptr); - } - - else /* bit depth is 16 */ - { - /* The 16-bit input values can be converted directly to 8-bit gamma - * encoded values; however, if a tRNS chunk is present 257 color-map - * entries are required. This means that the extra entry requires - * special processing; add an alpha channel, sacrifice gray level - * 254 and convert transparent (alpha==0) entries to that. - * - * Use libpng to chop the data to 8 bits. Convert it to sRGB at the - * same time to minimize quality loss. If a tRNS chunk is present - * this means libpng must handle it too; otherwise it is impossible - * to do the exact match on the 16-bit value. - * - * If the output has no alpha channel *and* the background color is - * gray then it is possible to let libpng handle the substitution by - * ensuring that the corresponding gray level matches the background - * color exactly. - */ - data_encoding = P_sRGB; - - if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "gray[16] color-map: too few entries"); - - cmap_entries = make_gray_colormap(display); - - if (png_ptr->num_trans > 0) - { - unsigned int back_alpha; - - if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) - back_alpha = 0; - - else - { - if (back_r == back_g && back_g == back_b) - { - /* Background is gray; no special processing will be - * required. - */ - png_color_16 c; - png_uint_32 gray = back_g; - - if (output_encoding == P_LINEAR) - { - gray = PNG_sRGB_FROM_LINEAR(png_ptr, gray * 255); - - /* And make sure the corresponding palette entry - * matches. - */ - png_create_colormap_entry(display, gray, back_g, back_g, - back_g, 65535, P_LINEAR); - } - - /* The background passed to libpng, however, must be the - * sRGB value. - */ - c.index = 0; /*unused*/ - c.gray = c.red = c.green = c.blue = - png_check_u16(png_ptr, gray); - - /* NOTE: does this work without expanding tRNS to alpha? - * It should be the color->gray case below apparently - * doesn't. - */ - png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); - - output_processing = PNG_CMAP_NONE; - break; - } - /* Coverity claims that output_encoding cannot be 2 (P_LINEAR) - * here. - */ - affirm(output_encoding != P_LINEAR); - back_alpha = 255U; - } - - /* output_processing means that the libpng-processed row will be - * 8-bit GA and it has to be processing to single byte color-map - * values. Entry 254 is replaced by either a completely - * transparent entry or by the background color at full - * precision (and the background color is not a simple gray - * level in this case.) - */ - expand_tRNS = 1; - output_processing = PNG_CMAP_TRANS; - background_index = 254; - - /* And set (overwrite) color-map entry 254 to the actual - * background color at full precision. - */ -#ifdef __COVERITY__ - /* Coverity says back_r|g|b might be 16-bit values */ - png_affirmpp(png_ptr, back_r < 256 && back_g < 256 && - back_b < 256); -#endif - png_create_colormap_entry(display, 254, back_r, back_g, back_b, - back_alpha, output_encoding); - } - - else - output_processing = PNG_CMAP_NONE; - } - break; - - case PNG_COLOR_TYPE_GRAY_ALPHA: - /* 8-bit or 16-bit PNG with two channels - gray and alpha. A minimum - * of 65536 combinations. If, however, the alpha channel is to be - * removed there are only 256 possibilities if the background is gray. - * (Otherwise there is a subset of the 65536 possibilities defined by - * the triangle between black, white and the background color.) - * - * Reduce 16-bit files to 8-bit and sRGB encode the result. No need to - * worry about tRNS matching - tRNS is ignored if there is an alpha - * channel. - */ - data_encoding = P_sRGB; - - if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "gray+alpha color-map: too few entries"); - - cmap_entries = make_ga_colormap(display); - - background_index = PNG_CMAP_GA_BACKGROUND; - output_processing = PNG_CMAP_GA; - } - - else /* alpha is removed */ - { - /* Alpha must be removed as the PNG data is processed when the - * background is a color because the G and A channels are - * independent and the vector addition (non-parallel vectors) is a - * 2-D problem. - * - * This can be reduced to the same algorithm as above by making a - * colormap containing gray levels (for the opaque grays), a - * background entry (for a transparent pixel) and a set of four six - * level color values, one set for each intermediate alpha value. - * See the comments in make_ga_colormap for how this works in the - * per-pixel processing. - * - * If the background is gray, however, we only need a 256 entry gray - * level color map. It is sufficient to make the entry generated - * for the background color be exactly the color specified. - */ - if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0 || - (back_r == back_g && back_g == back_b)) - { - /* Background is gray; no special processing will be required. */ - png_color_16 c; - png_uint_32 gray = back_g; - - if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "gray-alpha color-map: too few entries"); - - cmap_entries = make_gray_colormap(display); - - if (output_encoding == P_LINEAR) - { - gray = PNG_sRGB_FROM_LINEAR(png_ptr, gray * 255); - - /* And make sure the corresponding palette entry matches. */ - png_create_colormap_entry(display, gray, back_g, back_g, - back_g, 65535, P_LINEAR); - } - - /* The background passed to libpng, however, must be the sRGB - * value. - */ - c.index = 0; /*unused*/ - c.gray = c.red = c.green = c.blue = png_check_u16(png_ptr, gray); - - png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); - - output_processing = PNG_CMAP_NONE; - } - - else - { - png_uint_32 i, a; - - /* This is the same as png_make_ga_colormap, above, except that - * the entries are all opaque. - */ - if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "ga-alpha color-map: too few entries"); - - i = 0; - while (i < 231) - { - png_uint_32 gray = (i * 256 + 115) / 231; - png_create_colormap_entry(display, i++, gray, gray, gray, - 255, P_sRGB); - } - - /* NOTE: this preserves the full precision of the application - * background color. - * - * Coverity claims that output_encoding cannot be 2 (P_LINEAR) - */ - affirm(output_encoding != P_LINEAR); - background_index = i; - png_create_colormap_entry(display, i++, back_r, back_g, back_b, - 255U, output_encoding); - - /* For non-opaque input composite on the sRGB background - this - * requires inverting the encoding for each component. The input - * is still converted to the sRGB encoding because this is a - * reasonable approximate to the logarithmic curve of human - * visual sensitivity, at least over the narrow range which PNG - * represents. Consequently 'G' is always sRGB encoded, while - * 'A' is linear. We need the linear background colors. - */ - if (output_encoding == P_sRGB) /* else already linear */ - { - /* This may produce a value not exactly matching the - * background, but that's ok because these numbers are only - * used when alpha != 0 - */ - back_r = png_sRGB_table[back_r]; - back_g = png_sRGB_table[back_g]; - back_b = png_sRGB_table[back_b]; - } - - for (a=1; a<5; ++a) - { - unsigned int g; - - /* PNG_sRGB_FROM_LINEAR expects a 16-bit linear value scaled - * by an 8-bit alpha value (0..255). - */ - png_uint_32 alpha = 51 * a; - png_uint_32 back_rx = (255-alpha) * back_r; - png_uint_32 back_gx = (255-alpha) * back_g; - png_uint_32 back_bx = (255-alpha) * back_b; - - for (g=0; g<6; ++g) - { - png_uint_32 gray = png_sRGB_table[g*51] * alpha; - - png_create_colormap_entry(display, i++, - PNG_sRGB_FROM_LINEAR(png_ptr, gray + back_rx), - PNG_sRGB_FROM_LINEAR(png_ptr, gray + back_gx), - PNG_sRGB_FROM_LINEAR(png_ptr, gray + back_bx), - 255, P_sRGB); - } - } - - cmap_entries = i; - output_processing = PNG_CMAP_GA; - } - } - break; - - case PNG_COLOR_TYPE_RGB: - case PNG_COLOR_TYPE_RGB_ALPHA: - /* Exclude the case where the output is gray; we can always handle this - * with the cases above. - */ - if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0) - { - /* The color-map will be grayscale, so we may as well convert the - * input RGB values to a simple grayscale and use the grayscale - * code above. - * - * NOTE: calling this apparently damages the recognition of the - * transparent color in background color handling; call - * png_set_tRNS_to_alpha before png_set_background_fixed. - */ - png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1, - -1); - data_encoding = P_sRGB; - - /* The output will now be one or two 8-bit gray or gray+alpha - * channels. The more complex case arises when the input has alpha. - */ - if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - png_ptr->num_trans > 0) && - (output_format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - /* Both input and output have an alpha channel, so no background - * processing is required; just map the GA bytes to the right - * color-map entry. - */ - expand_tRNS = 1; - - if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "rgb[ga] color-map: too few entries"); - - cmap_entries = make_ga_colormap(display); - background_index = PNG_CMAP_GA_BACKGROUND; - output_processing = PNG_CMAP_GA; - } - - else - { - /* Either the input or the output has no alpha channel, so there - * will be no non-opaque pixels in the color-map; it will just be - * grayscale. - */ - if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "rgb[gray] color-map: too few entries"); - - /* Ideally this code would use libpng to do the gamma correction, - * but if an input alpha channel is to be removed we will hit the - * libpng bug in gamma+compose+rgb-to-gray (the double gamma - * correction bug). Fix this by dropping the gamma correction in - * this case and doing it in the palette; this will result in - * duplicate palette entries, but that's better than the - * alternative of double gamma correction. - */ - if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - png_ptr->num_trans > 0) && - png_gamma_not_sRGB(png_ptr->colorspace.gamma) != 0) - { - cmap_entries = make_gray_file_colormap(display); - data_encoding = P_FILE; - } - - else - cmap_entries = make_gray_colormap(display); - - /* But if the input has alpha or transparency it must be removed - */ - if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - png_ptr->num_trans > 0) - { - png_color_16 c; - png_uint_32 gray = back_g; - - /* We need to ensure that the application background exists in - * the colormap and that completely transparent pixels map to - * it. Achieve this simply by ensuring that the entry - * selected for the background really is the background color. - */ - if (data_encoding == P_FILE) /* from the fixup above */ - { - /* The app supplied a gray which is in output_encoding, we - * need to convert it to a value of the input (P_FILE) - * encoding then set this palette entry to the required - * output encoding. - */ - if (output_encoding == P_sRGB) - gray = png_sRGB_table[gray]; /* now P_LINEAR */ - - gray = png_gamma_nxmbit_correct(gray, - png_ptr->colorspace.gamma, 16U, 8U); - - /* And make sure the corresponding palette entry contains - * exactly the required sRGB value. - */ - png_create_colormap_entry(display, gray, back_g, back_g, - back_g, 0/*unused*/, output_encoding); - } - - else if (output_encoding == P_LINEAR) - { - gray = PNG_sRGB_FROM_LINEAR(png_ptr, gray * 255); - - /* And make sure the corresponding palette entry matches. - */ - png_create_colormap_entry(display, gray, back_g, back_g, - back_g, 0/*unused*/, P_LINEAR); - } - - /* The background passed to libpng, however, must be the - * output (normally sRGB) value. - */ - c.index = 0; /*unused*/ - c.gray = c.red = c.green = c.blue = - png_check_u16(png_ptr, gray); - - /* NOTE: the following is apparently a bug in libpng. Without - * it the transparent color recognition in - * png_set_background_fixed seems to go wrong. - */ - expand_tRNS = 1; - png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); - } - - output_processing = PNG_CMAP_NONE; - } - } - - else /* output is color */ - { - /* We could use png_quantize here so long as there is no transparent - * color or alpha; png_quantize ignores alpha. Easier overall just - * to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube. - * Consequently we always want libpng to produce sRGB data. - */ - data_encoding = P_sRGB; - - /* Is there any transparency or alpha? */ - if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - png_ptr->num_trans > 0) - { - /* Is there alpha in the output too? If so all four channels are - * processed into a special RGB cube with alpha support. - */ - if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - png_uint_32 r; - - if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) - png_error(png_ptr, "rgb+alpha color-map: too few entries"); - - cmap_entries = make_rgb_colormap(display); - - /* Add a transparent entry. */ - png_create_colormap_entry(display, cmap_entries, 255, 255, - 255, 0, P_sRGB); - - /* This is stored as the background index for the processing - * algorithm. - */ - background_index = cmap_entries++; - - /* Add 27 r,g,b entries each with alpha 0.5. */ - for (r=0; r<256; r = (r << 1) | 0x7f) - { - png_uint_32 g; - - for (g=0; g<256; g = (g << 1) | 0x7f) - { - png_uint_32 b; - - /* This generates components with the values 0, 127 and - * 255 - */ - for (b=0; b<256; b = (b << 1) | 0x7f) - png_create_colormap_entry(display, cmap_entries++, - r, g, b, 128, P_sRGB); - } - } - - expand_tRNS = 1; - output_processing = PNG_CMAP_RGB_ALPHA; - } - - else - { - /* Alpha/transparency must be removed. The background must - * exist in the color map (achieved by setting adding it after - * the 666 color-map). If the standard processing code will - * pick up this entry automatically that's all that is - * required; libpng can be called to do the background - * processing. - */ - unsigned int sample_size = - PNG_IMAGE_SAMPLE_SIZE(output_format); - png_uint_32 r, g, b; /* sRGB background */ - - if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) - png_error(png_ptr, "rgb-alpha color-map: too few entries"); - - cmap_entries = make_rgb_colormap(display); - - png_create_colormap_entry(display, cmap_entries, back_r, - back_g, back_b, 0/*unused*/, output_encoding); - - if (output_encoding == P_LINEAR) - { - r = PNG_sRGB_FROM_LINEAR(png_ptr, back_r * 255); - g = PNG_sRGB_FROM_LINEAR(png_ptr, back_g * 255); - b = PNG_sRGB_FROM_LINEAR(png_ptr, back_b * 255); - } - - else - { - r = back_r; - g = back_g; - b = back_g; - } - - /* Compare the newly-created color-map entry with the one the - * PNG_CMAP_RGB algorithm will use. If the two entries don't - * match, add the new one and set this as the background - * index. - */ - if (memcmp((png_const_bytep)display->colormap + - sample_size * cmap_entries, - (png_const_bytep)display->colormap + - sample_size * PNG_RGB_INDEX(r,g,b), - sample_size) != 0) - { - /* The background color must be added. */ - background_index = cmap_entries++; - - /* Add 27 r,g,b entries each with created by composing with - * the background at alpha 0.5. - */ - for (r=0; r<256; r = (r << 1) | 0x7f) - { - for (g=0; g<256; g = (g << 1) | 0x7f) - { - /* This generates components with the values 0, 127 - * and 255 - */ - for (b=0; b<256; b = (b << 1) | 0x7f) - png_create_colormap_entry(display, cmap_entries++, - png_colormap_compose(display, r, 8U, P_sRGB, - 128U, back_r, output_encoding), - png_colormap_compose(display, g, 8U, P_sRGB, - 128U, back_g, output_encoding), - png_colormap_compose(display, b, 8U, P_sRGB, - 128U, back_b, output_encoding), - 0/*unused*/, output_encoding); - } - } - - expand_tRNS = 1; - output_processing = PNG_CMAP_RGB_ALPHA; - } - - else /* background color is in the standard color-map */ - { - png_color_16 c; - - c.index = 0; /*unused*/ - c.red = png_check_u16(png_ptr, back_r); - c.gray = c.green = png_check_u16(png_ptr, back_g); - c.blue = png_check_u16(png_ptr, back_b); - - png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); - - output_processing = PNG_CMAP_RGB; - } - } - } - - else /* no alpha or transparency in the input */ - { - /* Alpha in the output is irrelevant, simply map the opaque input - * pixels to the 6x6x6 color-map. - */ - if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "rgb color-map: too few entries"); - - cmap_entries = make_rgb_colormap(display); - output_processing = PNG_CMAP_RGB; - } - } - break; - - case PNG_COLOR_TYPE_PALETTE: - /* It's already got a color-map. It may be necessary to eliminate the - * tRNS entries though. - */ - { - unsigned int num_trans = png_ptr->num_trans; - png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL; - png_const_colorp colormap = png_ptr->palette; - const int do_background = trans != NULL && - (output_format & PNG_FORMAT_FLAG_ALPHA) == 0; - unsigned int i; - - /* Just in case: */ - if (trans == NULL) - num_trans = 0; - - output_processing = PNG_CMAP_NONE; - data_encoding = P_FILE; /* Don't change from color-map indices */ - cmap_entries = png_ptr->num_palette; - if (cmap_entries > 256) - cmap_entries = 256; - - if (cmap_entries > image->colormap_entries) - png_error(png_ptr, "palette color-map: too few entries"); - - for (i=0; i < cmap_entries; ++i) - { - if (do_background != 0 && i < num_trans && trans[i] < 255) - { - if (trans[i] == 0) - png_create_colormap_entry(display, i, back_r, back_g, - back_b, 0, output_encoding); - - else - { - unsigned int alpha; - - /* Must compose the PNG file color in the color-map entry - * on the sRGB color in 'back'. - */ - png_image_get_sBIT(display); - alpha = update_for_sBIT(trans[i], display->sBIT[3], 8U); - - /* Do the sBIT handling here because it only applies to the - * values from the colormap, not the background. Passing - * output_encoding to png_create_colormap_entry prevents - * this being duplicated. - */ - png_create_colormap_entry(display, i, - png_colormap_compose(display, colormap[i].red, - display->sBIT[0], P_FILE, alpha, back_r, - output_encoding), - png_colormap_compose(display, colormap[i].green, - display->sBIT[1], P_FILE, alpha, back_g, - output_encoding), - png_colormap_compose(display, colormap[i].blue, - display->sBIT[2], P_FILE, alpha, back_b, - output_encoding), - output_encoding == P_LINEAR ? - update_for_sBIT(alpha*257U, display->sBIT[3], 16U) : - trans[i], - output_encoding); - } - } - - else - png_create_colormap_entry(display, i, colormap[i].red, - colormap[i].green, colormap[i].blue, - i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/); - } - - /* The PNG data may have indices packed in fewer than 8 bits, it - * must be expanded if so. - */ - if (png_ptr->bit_depth < 8) - png_set_packing(png_ptr); - } - break; - - default: - png_error(png_ptr, "invalid PNG color type"); - /*NOT REACHED*/ - } - - /* Now deal with the output processing */ - if (expand_tRNS != 0 && png_ptr->num_trans > 0 && - (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0) - png_set_tRNS_to_alpha(png_ptr); - - switch (data_encoding) - { - default: - impossible("bad data option"); - break; - - case P_sRGB: - /* Change to 8-bit sRGB */ - png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB); - /* FALL THROUGH */ - - case P_FILE: - if (png_ptr->bit_depth > 8) - png_set_scale_16(png_ptr); - break; - } - - affirm(cmap_entries <= 256 && cmap_entries <= image->colormap_entries); - - image->colormap_entries = cmap_entries; - - /* Double check using the recorded background index */ - switch (output_processing) - { - case PNG_CMAP_NONE: - if (background_index != PNG_CMAP_NONE_BACKGROUND) - goto bad_background; - break; - - case PNG_CMAP_GA: - if (background_index != PNG_CMAP_GA_BACKGROUND) - goto bad_background; - break; - - case PNG_CMAP_TRANS: - if (background_index >= cmap_entries || - background_index != PNG_CMAP_TRANS_BACKGROUND) - goto bad_background; - break; - - case PNG_CMAP_RGB: - if (background_index != PNG_CMAP_RGB_BACKGROUND) - goto bad_background; - break; - - case PNG_CMAP_RGB_ALPHA: - if (background_index != PNG_CMAP_RGB_ALPHA_BACKGROUND) - goto bad_background; - break; - - default: - impossible("bad processing option"); - - bad_background: - impossible("bad background index"); - } - - display->colormap_processing = output_processing; - - return 1/*ok*/; -} - -/* The final part of the color-map read called from png_image_finish_read. */ -static int -png_image_read_and_map(png_voidp argument) -{ - png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); - png_imagep image = display->image; - png_structrp png_ptr = image->opaque->png_ptr; - int passes; - - /* Called when the libpng data must be transformed into the color-mapped - * form. There is a local row buffer in display->local and this routine must - * do the interlace handling. - */ - switch (png_ptr->interlaced) - { - case PNG_INTERLACE_NONE: - passes = 1; - break; - - case PNG_INTERLACE_ADAM7: - passes = PNG_INTERLACE_ADAM7_PASSES; - break; - - default: - png_error(png_ptr, "unknown interlace type"); - } - - { - png_uint_32 height = image->height; - png_uint_32 width = image->width; - int proc = display->colormap_processing; - png_bytep first_row = png_voidcast(png_bytep, display->first_row); - ptrdiff_t step_row = display->row_bytes; - int pass; - - for (pass = 0; pass < passes; ++pass) - { - unsigned int startx, stepx, stepy; - png_uint_32 y; - - if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) - { - /* The row may be empty for a short image: */ - if (PNG_PASS_COLS(width, pass) == 0) - continue; - - startx = PNG_PASS_START_COL(pass); - stepx = PNG_PASS_COL_OFFSET(pass); - y = PNG_PASS_START_ROW(pass); - stepy = PNG_PASS_ROW_OFFSET(pass); - } - - else - { - y = 0; - startx = 0; - stepx = stepy = 1; - } - - for (; ylocal_row); - png_bytep outrow = first_row + y * step_row; - png_const_bytep end_row = outrow + width; - - /* Read read the libpng data into the temporary buffer. */ - png_read_row(png_ptr, inrow, NULL); - - /* Now process the row according to the processing option, note - * that the caller verifies that the format of the libpng output - * data is as required. - */ - outrow += startx; - switch (proc) - { - case PNG_CMAP_GA: - for (; outrow < end_row; outrow += stepx) - { - /* The data is always in the PNG order */ - unsigned int gray = *inrow++; - unsigned int alpha = *inrow++; - unsigned int entry; - - /* NOTE: this code is copied as a comment in - * make_ga_colormap above. Please update the - * comment if you change this code! - */ - if (alpha > 229) /* opaque */ - { - entry = (231 * gray + 128) >> 8; - } - else if (alpha < 26) /* transparent */ - { - entry = 231; - } - else /* partially opaque */ - { - entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray); - } - - *outrow = png_check_byte(png_ptr, entry); - } - break; - - case PNG_CMAP_TRANS: - for (; outrow < end_row; outrow += stepx) - { - png_byte gray = *inrow++; - png_byte alpha = *inrow++; - - if (alpha == 0) - *outrow = PNG_CMAP_TRANS_BACKGROUND; - - else if (gray != PNG_CMAP_TRANS_BACKGROUND) - *outrow = gray; - - else - *outrow = PNG_CMAP_TRANS_BACKGROUND+1; - } - break; - - case PNG_CMAP_RGB: - for (; outrow < end_row; outrow += stepx) - { - *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], inrow[2]); - inrow += 3; - } - break; - - case PNG_CMAP_RGB_ALPHA: - for (; outrow < end_row; outrow += stepx) - { - unsigned int alpha = inrow[3]; - - /* Because the alpha entries only hold alpha==0.5 values - * split the processing at alpha==0.25 (64) and 0.75 - * (196). - */ - - if (alpha >= 196) - *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], - inrow[2]); - - else if (alpha < 64) - *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND; - - else - { - /* Likewise there are three entries for each of r, g - * and b. We could select the entry by popcount on - * the top two bits on those architectures that - * support it, this is what the code below does, - * crudely. - */ - unsigned int back_i = PNG_CMAP_RGB_ALPHA_BACKGROUND+1; - - /* Here are how the values map: - * - * 0x00 .. 0x3f -> 0 - * 0x40 .. 0xbf -> 1 - * 0xc0 .. 0xff -> 2 - * - * So, as above with the explicit alpha checks, the - * breakpoints are at 64 and 196. - */ - if (inrow[0] & 0x80) back_i += 9; /* red */ - if (inrow[0] & 0x40) back_i += 9; - if (inrow[0] & 0x80) back_i += 3; /* green */ - if (inrow[0] & 0x40) back_i += 3; - if (inrow[0] & 0x80) back_i += 1; /* blue */ - if (inrow[0] & 0x40) back_i += 1; - - *outrow = png_check_byte(png_ptr, back_i); - } - - inrow += 4; - } - break; - - default: - break; - } - } - } - } - - return 1; -} - -static int -png_image_read_colormapped(png_voidp argument) -{ - png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); - png_imagep image = display->image; - png_controlp control = image->opaque; - png_structrp png_ptr = control->png_ptr; - png_inforp info_ptr = control->info_ptr; - int color_type, bit_depth; - int passes = 0; /* As a flag */ - - PNG_SKIP_CHUNKS(png_ptr); - - /* Update the 'info' structure and make sure the result is as required; first - * make sure to turn on the interlace handling if it will be required - * (because it can't be turned on *after* the call to png_read_update_info!) - */ - if (display->colormap_processing == PNG_CMAP_NONE) - passes = png_set_interlace_handling(png_ptr); - - png_read_update_info(png_ptr, info_ptr); - - /* Avoid the 'easy access' functions below because this allows them to be - * disabled; there are not useful with the simplified API. - */ - color_type = PNG_COLOR_TYPE_FROM_FORMAT(info_ptr->format); - bit_depth = info_ptr->bit_depth; - - /* The expected output can be deduced from the colormap_processing option. */ - switch (display->colormap_processing) - { - case PNG_CMAP_NONE: - /* Output must be one channel and one byte per pixel, the output - * encoding can be anything. - */ - if ((color_type == PNG_COLOR_TYPE_PALETTE || - color_type == PNG_COLOR_TYPE_GRAY) && bit_depth == 8) - break; - - goto bad_output; - - case PNG_CMAP_TRANS: - case PNG_CMAP_GA: - /* Output must be two channels and the 'G' one must be sRGB, the latter - * can be checked with an exact number because it should have been set - * to this number above! - */ - if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA && bit_depth == 8 && - !png_need_gamma_correction(png_ptr, png_memory_gamma(png_ptr), - 1/*sRGB*/) && - image->colormap_entries == 256) - break; - - goto bad_output; - - case PNG_CMAP_RGB: - /* Output must be 8-bit sRGB encoded RGB */ - if (color_type == PNG_COLOR_TYPE_RGB && bit_depth == 8 && - !png_need_gamma_correction(png_ptr, png_memory_gamma(png_ptr), - 1/*sRGB*/) && - image->colormap_entries == 216) - break; - - goto bad_output; - - case PNG_CMAP_RGB_ALPHA: - /* Output must be 8-bit sRGB encoded RGBA */ - if (color_type == PNG_COLOR_TYPE_RGB_ALPHA && bit_depth == 8 && - !png_need_gamma_correction(png_ptr, png_memory_gamma(png_ptr), - 1/*sRGB*/) && - image->colormap_entries == 244 /* 216 + 1 + 27 */) - break; - - /* goto bad_output; */ - /* FALL THROUGH */ - - default: - bad_output: - impossible("bad color-map processing"); - } - - /* Now read the rows. Do this here if it is possible to read directly into - * the output buffer, otherwise allocate a local row buffer of the maximum - * size libpng requires and call the relevant processing routine safely. - */ - { - png_voidp first_row = display->buffer; - ptrdiff_t row_bytes = display->row_stride; - - /* The following expression is designed to work correctly whether it gives - * a signed or an unsigned result. - */ - if (row_bytes < 0) - { - char *ptr = png_voidcast(char*, first_row); - ptr += (image->height-1) * (-row_bytes); - first_row = png_voidcast(png_voidp, ptr); - } - - display->first_row = first_row; - display->row_bytes = row_bytes; - } - - if (passes == 0) - { - int result; - png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); - - display->local_row = row; - result = png_safe_execute(image, png_image_read_and_map, display); - display->local_row = NULL; - png_free(png_ptr, row); - - return result; - } - - else - { - png_alloc_size_t row_bytes = display->row_bytes; - - while (--passes >= 0) - { - png_uint_32 y = image->height; - png_bytep row = png_voidcast(png_bytep, display->first_row); - - while (y-- > 0) - { - png_read_row(png_ptr, row, NULL); - row += row_bytes; - } - } - - return 1; - } -} - -/* Just the row reading part of png_image_read. */ -static int -png_image_read_composite(png_voidp argument) -{ - png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); - png_imagep image = display->image; - png_structrp png_ptr = image->opaque->png_ptr; - int passes; - - switch (png_ptr->interlaced) - { - case PNG_INTERLACE_NONE: - passes = 1; - break; - - case PNG_INTERLACE_ADAM7: - passes = PNG_INTERLACE_ADAM7_PASSES; - break; - - default: - png_error(png_ptr, "unknown interlace type"); - } - - { - png_uint_32 height = image->height; - png_uint_32 width = image->width; - ptrdiff_t step_row = display->row_bytes; - unsigned int channels = - (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; - int pass; - - for (pass = 0; pass < passes; ++pass) - { - unsigned int startx, stepx, stepy; - png_uint_32 y; - - if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) - { - /* The row may be empty for a short image: */ - if (PNG_PASS_COLS(width, pass) == 0) - continue; - - startx = PNG_PASS_START_COL(pass) * channels; - stepx = PNG_PASS_COL_OFFSET(pass) * channels; - y = PNG_PASS_START_ROW(pass); - stepy = PNG_PASS_ROW_OFFSET(pass); - } - - else - { - y = 0; - startx = 0; - stepx = channels; - stepy = 1; - } - - for (; ylocal_row); - png_bytep outrow; - png_const_bytep end_row; - - /* Read the row, which is packed: */ - png_read_row(png_ptr, inrow, NULL); - - outrow = png_voidcast(png_bytep, display->first_row); - outrow += y * step_row; - end_row = outrow + width * channels; - - /* Now do the composition on each pixel in this row. */ - outrow += startx; - for (; outrow < end_row; outrow += stepx) - { - png_byte alpha = inrow[channels]; - - if (alpha > 0) /* else no change to the output */ - { - unsigned int c; - - for (c=0; cimage; - png_structrp png_ptr = image->opaque->png_ptr; - png_inforp info_ptr = image->opaque->info_ptr; - png_uint_32 height = image->height; - png_uint_32 width = image->width; - int pass, passes; - - /* Double check the convoluted logic below. We expect to get here with - * libpng doing rgb to gray and gamma correction but background processing - * left to the png_image_read_background function. The rows libpng produce - * might be 8 or 16-bit but should always have two channels; gray plus alpha. - */ - affirm(PNG_COLOR_TYPE_FROM_FORMAT(info_ptr->format) == - PNG_COLOR_TYPE_GRAY_ALPHA); - debug(png_get_channels(png_ptr, info_ptr) == 2); - - /* Expect the 8-bit case to always remove the alpha channel */ - if ((image->format & PNG_FORMAT_FLAG_LINEAR) == 0 && - (image->format & PNG_FORMAT_FLAG_ALPHA) != 0) - png_error(png_ptr, "unexpected 8-bit transformation"); - - switch (png_ptr->interlaced) - { - case PNG_INTERLACE_NONE: - passes = 1; - break; - - case PNG_INTERLACE_ADAM7: - passes = PNG_INTERLACE_ADAM7_PASSES; - break; - - default: - png_error(png_ptr, "unknown interlace type"); - } - - /* Use direct access to info_ptr here because otherwise the simplified API - * would require PNG_EASY_ACCESS_SUPPORTED (just for this.) Note this is - * checking the value after libpng expansions, not the original value in the - * PNG. - */ - switch (info_ptr->bit_depth) - { - default: - png_error(png_ptr, "unexpected bit depth"); - break; - - case 8: - /* 8-bit sRGB gray values with an alpha channel; the alpha channel is - * to be removed by composing on a background: either the row if - * display->background is NULL or display->background->green if not. - * Unlike the code above ALPHA_OPTIMIZED has *not* been done. - */ - { - png_bytep first_row = png_voidcast(png_bytep, display->first_row); - ptrdiff_t step_row = display->row_bytes; - - for (pass = 0; pass < passes; ++pass) - { - png_bytep row = png_voidcast(png_bytep, display->first_row); - unsigned int startx, stepx, stepy; - png_uint_32 y; - - if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) - { - /* The row may be empty for a short image: */ - if (PNG_PASS_COLS(width, pass) == 0) - continue; - - startx = PNG_PASS_START_COL(pass); - stepx = PNG_PASS_COL_OFFSET(pass); - y = PNG_PASS_START_ROW(pass); - stepy = PNG_PASS_ROW_OFFSET(pass); - } - - else - { - y = 0; - startx = 0; - stepx = stepy = 1; - } - - if (display->background == NULL) - { - for (; ylocal_row); - png_bytep outrow = first_row + y * step_row; - png_const_bytep end_row = outrow + width; - - /* Read the row, which is packed: */ - png_read_row(png_ptr, inrow, NULL); - - /* Now do the composition on each pixel in this row. */ - outrow += startx; - for (; outrow < end_row; outrow += stepx) - { - png_byte alpha = inrow[1]; - - if (alpha > 0) /* else no change to the output */ - { - png_uint_32 component = inrow[0]; - - if (alpha < 255) /* else just use component */ - { - /* Since PNG_OPTIMIZED_ALPHA was not set it is - * necessary to invert the sRGB transfer - * function and multiply the alpha out. - */ - component = png_sRGB_table[component] * alpha; - component += png_sRGB_table[outrow[0]] * - (255-alpha); - component = - PNG_sRGB_FROM_LINEAR(png_ptr, component); - } - - outrow[0] = png_check_byte(png_ptr, component); - } - - inrow += 2; /* gray and alpha channel */ - } - } - } - - else /* constant background value */ - { - png_byte background8 = display->background->green; - png_uint_16 background = png_sRGB_table[background8]; - - for (; ylocal_row); - png_bytep outrow = first_row + y * step_row; - png_const_bytep end_row = outrow + width; - - /* Read the row, which is packed: */ - png_read_row(png_ptr, inrow, NULL); - - /* Now do the composition on each pixel in this row. */ - outrow += startx; - for (; outrow < end_row; outrow += stepx) - { - png_byte alpha = inrow[1]; - - if (alpha > 0) /* else use background */ - { - png_uint_32 component = inrow[0]; - - if (alpha < 255) /* else just use component */ - { - component = png_sRGB_table[component] * alpha; - component += background * (255-alpha); - component = - PNG_sRGB_FROM_LINEAR(png_ptr, component); - } - - outrow[0] = png_check_byte(png_ptr, component); - } - - else - outrow[0] = background8; - - inrow += 2; /* gray and alpha channel */ - } - - row += display->row_bytes; - } - } - } - } - break; - - case 16: - /* 16-bit linear with pre-multiplied alpha; the pre-multiplication must - * still be done and, maybe, the alpha channel removed. This code also - * handles the alpha-first option. - */ - { - png_uint_16p first_row = png_voidcast(png_uint_16p, - display->first_row); - /* The division by two is safe because the caller passed in a - * stride which was multiplied by 2 (below) to get row_bytes. - */ - ptrdiff_t step_row = display->row_bytes / 2; - int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; - unsigned int outchannels = 1+preserve_alpha; - int swap_alpha = 0; - -#ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED - if (preserve_alpha != 0 && - (image->format & PNG_FORMAT_FLAG_AFIRST) != 0) - swap_alpha = 1; -#endif - - for (pass = 0; pass < passes; ++pass) - { - unsigned int startx, stepx, stepy; - png_uint_32 y; - - /* The 'x' start and step are adjusted to output components here. - */ - if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) - { - /* The row may be empty for a short image: */ - if (PNG_PASS_COLS(width, pass) == 0) - continue; - - startx = PNG_PASS_START_COL(pass) * outchannels; - stepx = PNG_PASS_COL_OFFSET(pass) * outchannels; - y = PNG_PASS_START_ROW(pass); - stepy = PNG_PASS_ROW_OFFSET(pass); - } - - else - { - y = 0; - startx = 0; - stepx = outchannels; - stepy = 1; - } - - for (; ylocal_row), NULL); - inrow = png_voidcast(png_const_uint_16p, display->local_row); - - /* Now do the pre-multiplication on each pixel in this row. - */ - outrow += startx; - for (; outrow < end_row; outrow += stepx) - { - png_uint_32 component = inrow[0]; - png_uint_16 alpha = inrow[1]; - - if (alpha > 0) /* else 0 */ - { - if (alpha < 65535) /* else just use component */ - { - component *= alpha; - component += 32767; - component /= 65535; - } - } - - else - component = 0; - - outrow[swap_alpha] = - png_check_u16(png_ptr, component); - if (preserve_alpha != 0) - outrow[1 ^ swap_alpha] = alpha; - - inrow += 2; /* components and alpha channel */ - } - } - } - } - break; - } - - return 1; -} - -/* The guts of png_image_finish_read as a png_safe_execute callback. */ -static int -png_image_read_direct(png_voidp argument) -{ - png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); - png_imagep image = display->image; - png_structrp png_ptr = image->opaque->png_ptr; - png_inforp info_ptr = image->opaque->info_ptr; - - png_uint_32 format = image->format; - int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0; - int do_local_compose = 0; - int do_local_background = 0; /* to avoid double gamma correction bug */ - int passes = 0; - - /* Add transforms to ensure the correct output format is produced then check - * that the required implementation support is there. Always expand; always - * need 8 bits minimum, no palette and expanded tRNS. - */ - png_set_expand(png_ptr); - - /* Now check the format to see if it was modified. */ - { - png_uint_32 base_format = png_image_format(png_ptr) & - PNG_BIC_MASK(PNG_FORMAT_FLAG_COLORMAP) /* removed by png_set_expand */; - png_uint_32 change = format ^ base_format; - png_fixed_point output_gamma; - int mode; /* alpha mode */ - - /* Do this first so that we have a record if rgb to gray is happening. */ - if ((change & PNG_FORMAT_FLAG_COLOR) != 0) - { - /* gray<->color transformation required. */ - if ((format & PNG_FORMAT_FLAG_COLOR) != 0) - png_set_gray_to_rgb(png_ptr); - - else - { - /* libpng can't do both rgb to gray and - * background/pre-multiplication if there is also significant gamma - * correction, because both operations require linear colors and - * the code only supports one transform doing the gamma correction. - * Handle this by doing the pre-multiplication or background - * operation in this code, if necessary. - * - * TODO: fix this by rewriting pngrtran.c (!) - * - * For the moment (given that fixing this in pngrtran.c is an - * enormous change) 'do_local_background' is used to indicate that - * the problem exists. - */ - if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) - do_local_background = 1/*maybe*/; - - png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, - PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT); - } - - change &= PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR); - } - - /* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise. - */ - { - png_fixed_point input_gamma_default; - - if ((base_format & PNG_FORMAT_FLAG_LINEAR) != 0 && - (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) - input_gamma_default = PNG_GAMMA_LINEAR; - else - input_gamma_default = PNG_DEFAULT_sRGB; - - /* Call png_set_alpha_mode to set the default for the input gamma; the - * output gamma is set by a second call below. - */ - png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, input_gamma_default); - } - - if (linear != 0) - { - /* If there *is* an alpha channel in the input it must be multiplied - * out; use PNG_ALPHA_STANDARD, otherwise just use PNG_ALPHA_PNG. - */ - if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) - mode = PNG_ALPHA_STANDARD; /* associated alpha */ - - else - mode = PNG_ALPHA_PNG; - - output_gamma = PNG_GAMMA_LINEAR; - } - - else - { - mode = PNG_ALPHA_PNG; - output_gamma = PNG_DEFAULT_sRGB; - } - - /* If 'do_local_background' is set check for the presence of gamma - * correction; this is part of the work-round for the libpng bug - * described above. - * - * TODO: fix libpng and remove this. - */ - if (do_local_background != 0) - { - /* This is intended to be a safe check to see if libpng will perform - * gamma work in pngrtran.c; if it will *not* be performed the - * do_local_background flag is cancelled. - */ - if (!png_need_gamma_correction(png_ptr, 0/*PNG gamma*/, - output_gamma != PNG_GAMMA_LINEAR)) - do_local_background = 0; - - else if (mode == PNG_ALPHA_STANDARD) - { - do_local_background = 2/*required*/; - mode = PNG_ALPHA_PNG; /* prevent libpng doing it */ - } - - /* else leave as 1 for the checks below */ - } - - /* If the bit-depth changes then handle that here. */ - if ((change & PNG_FORMAT_FLAG_LINEAR) != 0) - { - if (linear != 0 /*16-bit output*/) - png_set_expand_16(png_ptr); - - else /* 8-bit output */ - png_set_scale_16(png_ptr); - - change &= PNG_BIC_MASK(PNG_FORMAT_FLAG_LINEAR); - } - - /* Now the background/alpha channel changes. */ - if ((change & PNG_FORMAT_FLAG_ALPHA) != 0) - { - /* Removing an alpha channel requires composition for the 8-bit - * formats; for the 16-bit it is already done, above, by the - * pre-multiplication and the channel just needs to be stripped. - */ - if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - /* If RGB->gray is happening the alpha channel must be left and the - * operation completed locally. - * - * TODO: fix libpng and remove this. - */ - if (do_local_background != 0) - do_local_background = 2/*required*/; - - /* 16-bit output: just remove the channel */ - else if (linear != 0) /* compose on black (well, pre-multiply) */ - png_set_strip_alpha(png_ptr); - - /* 8-bit output: do an appropriate compose */ - else if (display->background != NULL) - { - png_color_16 c; - - c.index = 0; /*unused*/ - c.red = display->background->red; - c.green = display->background->green; - c.blue = display->background->blue; - c.gray = display->background->green; - - /* This is always an 8-bit sRGB value, using the 'green' channel - * for gray is much better than calculating the luminance here; - * we can get off-by-one errors in that calculation relative to - * the app expectations and that will show up in transparent - * pixels. - */ - png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); - } - - else /* compose on row: implemented below. */ - { - do_local_compose = 1; - /* This leaves the alpha channel in the output, so it has to be - * removed by the code below. Set the encoding to the 'OPTIMIZE' - * one so the code only has to hack on the pixels that require - * composition. - */ - mode = PNG_ALPHA_OPTIMIZED; - } - } - - else /* output needs an alpha channel */ - { - /* This is tricky because it happens before the swap operation has - * been accomplished; however, the swap does *not* swap the added - * alpha channel (weird API), so it must be added in the correct - * place. - */ - png_uint_32 filler; /* opaque filler */ - int where; - - if (linear != 0) - filler = 65535; - - else - filler = 255; - -#ifdef PNG_FORMAT_AFIRST_SUPPORTED - if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) - { - where = PNG_FILLER_BEFORE; - change &= PNG_BIC_MASK(PNG_FORMAT_FLAG_AFIRST); - } - - else -#endif - where = PNG_FILLER_AFTER; - - png_set_add_alpha(png_ptr, filler, where); - } - - /* This stops the (irrelevant) call to swap_alpha below. */ - change &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA); - } - - /* Now set the alpha mode correctly; this is always done, even if there is - * no alpha channel in either the input or the output because it correctly - * sets the output gamma. - */ - png_set_alpha_mode_fixed(png_ptr, mode, output_gamma); - -# ifdef PNG_FORMAT_BGR_SUPPORTED - if ((change & PNG_FORMAT_FLAG_BGR) != 0) - { - /* Check only the output format; PNG is never BGR; don't do this if - * the output is gray, but fix up the 'format' value in that case. - */ - if ((format & PNG_FORMAT_FLAG_COLOR) != 0) - png_set_bgr(png_ptr); - - else - format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_BGR); - - change &= PNG_BIC_MASK(PNG_FORMAT_FLAG_BGR); - } -# endif - -# ifdef PNG_FORMAT_AFIRST_SUPPORTED - if ((change & PNG_FORMAT_FLAG_AFIRST) != 0) - { - /* Only relevant if there is an alpha channel - it's particularly - * important to handle this correctly because do_local_compose may - * be set above and then libpng will keep the alpha channel for this - * code to remove. - */ - if ((format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - /* Disable this if doing a local background, - * TODO: remove this when local background is no longer required. - */ - if (do_local_background != 2) - png_set_swap_alpha(png_ptr); - } - - else - format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_AFIRST); - - change &= PNG_BIC_MASK(PNG_FORMAT_FLAG_AFIRST); - } -# endif - - /* If the *output* is 16-bit then we need to check for a byte-swap on this - * architecture. - */ - if (linear != 0) - { - PNG_CONST png_uint_16 le = 0x0001; - - if ((*(png_const_bytep) & le) != 0) - png_set_swap(png_ptr); - } - - /* If change is not now 0 some transformation is missing - error out. */ - if (change != 0) - png_error(png_ptr, "png_read_image: unsupported transformation"); - } - - PNG_SKIP_CHUNKS(png_ptr); - - /* Update the 'info' structure and make sure the result is as required; first - * make sure to turn on the interlace handling if it will be required - * (because it can't be turned on *after* the call to png_read_update_info!) - * - * TODO: remove the do_local_background fixup below. - */ - if (do_local_compose == 0 && do_local_background != 2) - passes = png_set_interlace_handling(png_ptr); - - png_read_update_info(png_ptr, info_ptr); - - { - png_uint_32 out_format = png_memory_format(png_ptr); - - /* Swapping is expected for the 16-bit format: */ - out_format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_SWAPPED); - - /* The remaining upper bits should never be set: */ - affirm(!(out_format & ~0x3FU)); - - if ((out_format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - /* do_local_compose removes this channel below. */ - if (do_local_compose != 0 || - /* do_local_background does the same if required. */ - (do_local_background == 2 && - (format & PNG_FORMAT_FLAG_ALPHA) == 0)) - out_format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA); - } - - else - affirm(do_local_compose == 0 /* else alpha channel lost */); - - switch (png_memory_channel_depth(png_ptr)) - { - case 16: affirm((out_format & PNG_FORMAT_FLAG_LINEAR) != 0); break; - case 8: affirm((out_format & PNG_FORMAT_FLAG_LINEAR) == 0); break; - default: impossible("unexpected bit depth"); break; - } - -# ifdef PNG_FORMAT_AFIRST_SUPPORTED - if (do_local_background == 2) - { - /* do_local_background should be handling the swap: */ - affirm(!(out_format & PNG_FORMAT_FLAG_AFIRST)); - - if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) - out_format |= PNG_FORMAT_FLAG_AFIRST; - } -# endif - - /* This is actually an internal error. */ - affirm(out_format == format /* else unimplemented transformations */); - } - - /* Now read the rows. If do_local_compose is set then it is necessary to use - * a local row buffer. The output will be GA, RGBA or BGRA and must be - * converted to G, RGB or BGR as appropriate. The 'local_row' member of the - * display acts as a flag. - */ - { - png_voidp first_row = display->buffer; - ptrdiff_t row_bytes = display->row_stride; - - if (linear != 0) - row_bytes *= 2; - - /* The following expression is designed to work correctly whether it gives - * a signed or an unsigned result. - */ - if (row_bytes < 0) - { - char *ptr = png_voidcast(char*, first_row); - ptr += (image->height-1) * (-row_bytes); - first_row = png_voidcast(png_voidp, ptr); - } - - display->first_row = first_row; - display->row_bytes = row_bytes; - } - - if (do_local_compose != 0) - { - int result; - png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); - - display->local_row = row; - result = png_safe_execute(image, png_image_read_composite, display); - display->local_row = NULL; - png_free(png_ptr, row); - - return result; - } - - else if (do_local_background == 2) - { - int result; - png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); - - display->local_row = row; - result = png_safe_execute(image, png_image_read_background, display); - display->local_row = NULL; - png_free(png_ptr, row); - - return result; - } - - else - { - png_alloc_size_t row_bytes = display->row_bytes; - - while (--passes >= 0) - { - png_uint_32 y = image->height; - png_bytep row = png_voidcast(png_bytep, display->first_row); - - while (y-- > 0) - { - png_read_row(png_ptr, row, NULL); - row += row_bytes; - } - } - - return 1; - } -} - -int PNGAPI -png_image_finish_read(png_imagep image, png_const_colorp background, - void *buffer, ptrdiff_t row_stride, void *colormap) -{ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - /* Check for row_stride overflow. This check is not performed on the - * original PNG format because it may not occur in the output PNG format - * and libpng deals with the issues of reading the original. - */ - const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); - - /* The test is slightly evil: it assumes that a signed pointer difference - * (ptrdiff_t) can hold a maximum value of half, rounded down, of the - * maximum of a (size_t). This is almost certain to be true. - */ - if (image->width <= (PNG_SIZE_MAX >> 1)/channels) /* no overflow */ - { - png_alloc_size_t check; - const png_alloc_size_t png_row_stride = - (png_alloc_size_t)/*SAFE*/image->width * channels; - - if (row_stride == 0) - row_stride = (ptrdiff_t)png_row_stride; - - if (row_stride < 0) - check = -row_stride; - - else - check = row_stride; - - if (image->opaque != NULL && buffer != NULL && check >= png_row_stride) - { - /* Now check for overflow of the image buffer calculation; this - * limits the whole image size to PNG_SIZE_MAX bytes. - * - * The PNG_IMAGE_BUFFER_SIZE macro is: - * - * (PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)*height*(row_stride)) - * - * We have no way of guaranteeing that the application used the - * correct type for 'row_stride' if it used the macro, so this is - * technically not completely safe, but this is the case throughout - * libpng; the app is responsible for making sure the calcualtion of - * buffer sizes does not overflow. - */ - if (image->height <= PNG_SIZE_MAX / - PNG_IMAGE_PIXEL_COMPONENT_SIZE(image->format) / check) - { - if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 || - (image->colormap_entries > 0 && colormap != NULL)) - { - int result; - png_image_read_control display; - - memset(&display, 0, (sizeof display)); - display.image = image; - display.buffer = buffer; - display.row_stride = row_stride; - display.colormap = colormap; - display.background = background; - display.local_row = NULL; - - /* Choose the correct 'end' routine; for the color-map case - * all the setup has already been done. - */ - if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0) - result = - png_safe_execute(image, - png_image_read_colormap, &display) && - png_safe_execute(image, - png_image_read_colormapped, &display); - - else - result = - png_safe_execute(image, - png_image_read_direct, &display); - - png_image_free(image); - return result; - } - - else - return png_image_error(image, - "png_image_finish_read[color-map]: no color-map"); - } - - else - return png_image_error(image, - "png_image_finish_read: image too large"); - } - - else - return png_image_error(image, - "png_image_finish_read: invalid argument"); - } - - else - return png_image_error(image, - "png_image_finish_read: row_stride too large"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_finish_read: damaged PNG_IMAGE_VERSION"); - - return 0; -} - -#endif /* SIMPLIFIED_READ */ -#endif /* READ */ diff --git a/ext/libpng17/pngrio.c b/ext/libpng17/pngrio.c deleted file mode 100644 index b77f827405..0000000000 --- a/ext/libpng17/pngrio.c +++ /dev/null @@ -1,114 +0,0 @@ - -/* pngrio.c - functions for data input - * - * Last changed in libpng 1.7.0 [(PENDING RELEASE)] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file provides a location for all input. Users who need - * special handling are expected to write a function that has the same - * arguments as this and performs a similar function, but that possibly - * has a different input method. Note that you shouldn't change this - * function, but rather write a replacement function and then make - * libpng use it at run time with png_set_read_fn(...). - */ - -#include "pngpriv.h" -#define PNG_SRC_FILE PNG_SRC_FILE_pngrio - -#ifdef PNG_READ_SUPPORTED - -/* Read the data from whatever input you are using. The default routine - * reads from a file pointer. Note that this routine sometimes gets called - * with very small lengths, so you should implement some kind of simple - * buffering if you are using unbuffered reads. This should never be asked - * to read more than 64K on a 16 bit machine. - */ -void /* PRIVATE */ -png_read_data(png_structrp png_ptr, png_voidp data, png_size_t length) -{ - png_debug1(4, "reading %d bytes", (int)length); - - /* This was guaranteed by prior versions of libpng, so app callbacks may - * assume it even though it isn't documented to be the case. - */ - debug(length > 0U); - - if (png_ptr->rw_data_fn != NULL) - png_ptr->rw_data_fn(png_ptr, png_voidcast(png_bytep,data), length); - - else - png_app_error(png_ptr, "No read function"); -} - -#ifdef PNG_STDIO_SUPPORTED -/* This is the function that does the actual reading of data. If you are - * not reading from a standard C stream, you should create a replacement - * read_data function and use it at run time with png_set_read_fn(), rather - * than changing the library. - */ -void PNGCBAPI -png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - png_size_t check; - - if (png_ptr == NULL) - return; - - /* fread() returns 0 on error, so it is OK to store this in a png_size_t - * instead of an int, which is what fread() actually returns. - */ - check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr)); - - if (check != length) - png_error(png_ptr, "Read Error"); -} -#endif /* STDIO */ - -/* This function allows the application to supply a new input function - * for libpng if standard C streams aren't being used. - * - * This function takes as its arguments: - * - * png_ptr - pointer to a png input data structure - * - * io_ptr - pointer to user supplied structure containing info about - * the input functions. May be NULL. - * - * read_data_fn - pointer to a new input function that takes as its - * arguments a pointer to a png_struct, a pointer to - * a location where input data can be stored, and a 32-bit - * unsigned int that is the number of bytes to be read. - * To exit and output any fatal error messages the new write - * function should call png_error(png_ptr, "Error msg"). - * May be NULL, in which case libpng's default function will - * be used. - */ -void PNGAPI -png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr, - png_rw_ptr read_data_fn) -{ - if (png_ptr == NULL) - return; - - if (!png_ptr->read_struct) - { - png_app_error(png_ptr, "cannot set a read function on a write struct"); - return; - } - - if (read_data_fn == NULL) - { - png_app_error(png_ptr, "API change: png_set_read_fn requires a function"); - return; - } - - png_ptr->io_ptr = io_ptr; - png_ptr->rw_data_fn = read_data_fn; -} -#endif /* READ */ diff --git a/ext/libpng17/pngrtran.c b/ext/libpng17/pngrtran.c deleted file mode 100644 index 6a6583eff2..0000000000 --- a/ext/libpng17/pngrtran.c +++ /dev/null @@ -1,6823 +0,0 @@ -#ifdef _MSC_VER -#pragma warning (disable:4146) -#endif - -/* pngrtran.c - transforms the data in a row for PNG readers - * - * Last changed in libpng 1.7.0 [(PENDING RELEASE)] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file contains functions optionally called by an application - * in order to tell libpng how to handle data when reading a PNG. - * Transformations that are used in both reading and writing are - * in pngtrans.c. - */ - -#include "pngpriv.h" -#define PNG_SRC_FILE PNG_SRC_FILE_pngrtran - -#ifdef PNG_READ_QUANTIZE_SUPPORTED -typedef struct -{ - png_transform tr; - png_byte map[256U]; /* Map of palette values */ - png_byte lut[1U << /* LUT for RGB values */ - (PNG_QUANTIZE_RED_BITS+PNG_QUANTIZE_GREEN_BITS+PNG_QUANTIZE_BLUE_BITS)]; -} png_transform_quantize; - -#define PNG_QUANTIZE_MAP 1U /* map is present and not a 1:1 mapping */ -#define PNG_QUANTIZE_LUT 2U /* lut has been built */ - -static void -do_quantize_rgb(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_transform_quantize *tr = png_transform_cast(png_transform_quantize, - *transform); - unsigned int channels = PNG_TC_CHANNELS(*tc); - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - channels/*safety*/; - png_bytep dp = png_voidcast(png_bytep, tc->dp); - - affirm(tc->bit_depth == 8 && (channels == 3 || channels == 4) && - !(tc->format & PNG_FORMAT_FLAG_SWAPPED) && - (tr->tr.args & PNG_QUANTIZE_LUT) != 0); - - tc->sp = dp; - tc->format |= PNG_FORMAT_FLAG_COLORMAP; - - while (sp <= ep) - { - unsigned int r = sp[0]; - unsigned int g = sp[1]; - unsigned int b = sp[2]; - - /* This looks real messy, but the compiler will reduce - * it down to a reasonable formula. For example, with - * 5 bits per color, we get: - * p = (((r >> 3) & 0x1f) << 10) | - * (((g >> 3) & 0x1f) << 5) | - * ((b >> 3) & 0x1f); - */ - *dp++ = tr->lut[(((r >> (8 - PNG_QUANTIZE_RED_BITS)) & - ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << - (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | - (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & - ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << - (PNG_QUANTIZE_BLUE_BITS)) | - ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & - ((1 << PNG_QUANTIZE_BLUE_BITS) - 1))]; - - sp += channels; - } - - affirm(sp == ep+channels); - UNTESTED -# undef png_ptr -} - -static void -do_quantize_pal(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_transform_quantize *tr = png_transform_cast(png_transform_quantize, - *transform); - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - - affirm(tc->bit_depth == 8 && (tc->format & PNG_FORMAT_FLAG_COLORMAP) != 0 && - !(tc->format & PNG_FORMAT_FLAG_SWAPPED) && - (tr->tr.args & PNG_QUANTIZE_MAP) != 0); - - tc->sp = dp; - - while (sp < ep) - *dp++ = tr->map[*sp++]; - - UNTESTED -# undef png_ptr -} - -static void -png_init_quantize(png_transformp *transform, png_transform_controlp tc) -{ - if (tc->bit_depth == 8 && (tc->format & PNG_FORMAT_FLAG_COLOR) != 0) - { - /* Either colormapped input, RGB or RGBA: */ - if (!(tc->format & PNG_FORMAT_FLAG_COLORMAP)) /* RGB, RGBA */ - { - /* This must be a 'palette' lookup */ - if (((*transform)->args & PNG_QUANTIZE_LUT) != 0) - { - /* This changes the format and invalidates pretty much everything in - * the info struct: - */ - tc->format |= PNG_FORMAT_FLAG_COLORMAP; - - if (tc->init == PNG_TC_INIT_FINAL) - { - (*transform)->fn = do_quantize_rgb; - tc->invalid_info |= PNG_INFO_tRNS+PNG_INFO_hIST+PNG_INFO_pCAL+ - PNG_INFO_sBIT+PNG_INFO_bKGD; - tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A = - png_check_byte(tc->png_ptr, tc->bit_depth); - } - - return; - } - } - - else /* colormapped */ - { - /* This must be a 'quantize' lookup */ - if (((*transform)->args & PNG_QUANTIZE_MAP) != 0) - { - /* This doesn't change the format, just the values: */ - if (tc->init == PNG_TC_INIT_FINAL) - { - (*transform)->fn = do_quantize_pal; - tc->invalid_info |= PNG_INFO_sBIT+PNG_INFO_pCAL; - tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A = - png_check_byte(tc->png_ptr, tc->bit_depth); - } - - return; - } - } - } - - /* Else not applicable */ - (*transform)->fn = NULL; -} - -/* Dither file to 8-bit. Supply a palette, the current number - * of elements in the palette, the maximum number of elements - * allowed, and a histogram if possible. If the current number - * of colors is greater then the maximum number, the palette will be - * modified to fit in the maximum number. "full_quantize" indicates - * whether we need a quantizing cube set up for RGB images, or if we - * simply are reducing the number of colors in a paletted image. - */ -typedef struct png_dsort_struct -{ - struct png_dsort_struct * next; - png_byte left; - png_byte right; -} png_dsort; -typedef png_dsort * png_dsortp; -typedef png_dsort * * png_dsortpp; - -static void -init_map(png_bytep map) - /* Initialize a mapping table to be 1:1 */ -{ - png_byte b = 0U; - - do - map[b] = b; - while (b++ != 255U); -} - -/* Save typing and make code easier to understand */ -#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ - abs((int)((c1).green) - (int)((c2).green)) + \ - abs((int)((c1).blue) - (int)((c2).blue))) - -void PNGAPI -png_set_quantize(png_structrp png_ptr, png_colorp palette, - int num_palette, int maximum_colors, png_const_uint_16p histogram, - int full_quantize) -{ - png_debug(1, "in png_set_quantize"); - - if (png_ptr != NULL) - { - png_transform_quantize *tr = png_transform_cast(png_transform_quantize, - png_add_transform(png_ptr, sizeof (png_transform_quantize), - png_init_quantize, PNG_TR_QUANTIZE)); - - /* This is weird (consider what happens to png_set_background on a palette - * image with a tRNS chunk). - */ - if (palette == png_ptr->palette) - png_app_warning(png_ptr, "png_set_quantize: PLTE will be damaged"); - - if (maximum_colors <= 0 || num_palette > 256) - { - /* The spuriously allocated transform will be removed by the init - * code. - */ - png_app_error(png_ptr, "png_set_quantize: invalid color count"); - return; - } - - /* The app passed in a palette with too many colors, it's not clear why - * libpng is providing this functionality, it's nothing to do with PNG and - * can be done by the application without any PNG specific knowledge. - */ - if (num_palette > maximum_colors) - { - int map_changed = 0; - - /* The map table must be preset to do no mapping initially: */ - init_map(tr->map); - - if (histogram != NULL) - { - /* This is easy enough, just throw out the least used colors. - * Perhaps not the best solution, but good enough. - */ - int i; - png_byte quantize_sort[256U]; - - /* Initialize an array to sort colors */ - init_map(quantize_sort); - - /* Find the least used palette entries by starting a - * bubble sort, and running it until we have sorted - * out enough colors. Note that we don't care about - * sorting all the colors, just finding which are - * least used. - */ - for (i = num_palette - 1; i >= maximum_colors; i--) - { - int done; /* To stop early if the list is pre-sorted */ - int j; - - done = 1; - for (j = 0; j < i; j++) - { - if (histogram[quantize_sort[j]] < - histogram[quantize_sort[j+1]]) - { - png_byte t = quantize_sort[j]; - quantize_sort[j] = quantize_sort[j+1]; - quantize_sort[j+1] = t; - done = 0; - } - } - - if (done != 0) - break; - } - - /* Swap the palette around, and set up a table, if necessary */ - if (full_quantize) - { - int j = num_palette; - - /* Put all the useful colors within the max, but don't - * move the others. - * - * NOTE: if the app passes in the result of png_get_PLTE it will - * be overwritten at this point, what is the API? - */ - for (i = 0; i < maximum_colors; i++) - { - if (quantize_sort[i] >= maximum_colors) - { - do - j--; - while (quantize_sort[j] >= maximum_colors); - - /* NOTE: NOT swapped, so the original palette[i] has been - * lost. - */ - palette[i] = palette[j]; - } - } - } - - else /* !full_quantize */ - { - int j = num_palette; - - /* Move all the used colors inside the max limit, and - * develop a translation table. - */ - for (i = 0; i < maximum_colors; i++) - { - /* Only move the colors we need to */ - if (quantize_sort[i] >= maximum_colors) - { - png_color tmp_color; - - do - j--; - while (quantize_sort[j] >= maximum_colors); - - tmp_color = palette[j]; - palette[j] = palette[i]; - palette[i] = tmp_color; - /* Indicate where the color went */ - tr->map[j] = png_check_byte(png_ptr, i); - tr->map[i] = png_check_byte(png_ptr, j); - map_changed = 1; - } - } - - /* Find closest color for those colors we are not using */ - for (i = 0; i < num_palette; i++) - { - if (tr->map[i] >= maximum_colors) - { - int min_d, k, min_k, d_index; - - /* Find the closest color to one we threw out */ - d_index = tr->map[i]; - min_d = PNG_COLOR_DIST(palette[d_index], palette[0]); - for (k = 1, min_k = 0; k < maximum_colors; k++) - { - int d; - - d = PNG_COLOR_DIST(palette[d_index], palette[k]); - - if (d < min_d) - { - min_d = d; - min_k = k; - } - } - - /* Point to closest color */ - tr->map[i] = png_check_byte(png_ptr, min_k); - map_changed = 1; - } - } - } /* !full_quantize */ - } /* have a histogram */ - - else /* no histogram */ - { - /* This is much harder to do simply (and quickly). Perhaps - * we need to go through a median cut routine, but those - * don't always behave themselves with only a few colors - * as input. So we will just find the closest two colors, - * and throw out one of them (chosen somewhat randomly). - * [We don't understand this at all, so if someone wants to - * work on improving it, be our guest - AED, GRP] - */ - int max_d; - int num_new_palette; - png_byte index_to_palette[256U]; - png_byte palette_to_index[256U]; - png_dsortp hash[769]; - - /* Initialize palette index sort arrays */ - init_map(index_to_palette); - init_map(palette_to_index); - memset(hash, 0, sizeof hash); - num_new_palette = num_palette; - - /* Initial wild guess at how far apart the farthest pixel - * pair we will be eliminating will be. Larger - * numbers mean more areas will be allocated, Smaller - * numbers run the risk of not saving enough data, and - * having to do this all over again. - * - * I have not done extensive checking on this number. - */ - max_d = 96; - - while (num_new_palette > maximum_colors) - { - int i; - png_dsortp t = NULL; - - for (i = 0; i < num_new_palette - 1; i++) - { - int j; - - for (j = i + 1; j < num_new_palette; j++) - { - int d = PNG_COLOR_DIST(palette[i], palette[j]); - - if (d <= max_d) - { - - t = png_voidcast(png_dsortp, png_malloc_warn(png_ptr, - sizeof (*t))); - - if (t == NULL) - break; - - t->next = hash[d]; - t->left = png_check_byte(png_ptr, i); - t->right = png_check_byte(png_ptr, j); - hash[d] = t; - } - } - if (t == NULL) - break; - } - - if (t != NULL) for (i = 0; i <= max_d; i++) - { - if (hash[i] != NULL) - { - png_dsortp p; - - for (p = hash[i]; p != NULL; p = p->next) - { - if (index_to_palette[p->left] < num_new_palette && - index_to_palette[p->right] < num_new_palette) - { - int j, next_j; - - if (num_new_palette & 0x01) - { - j = p->left; - next_j = p->right; - } - else - { - j = p->right; - next_j = p->left; - } - - num_new_palette--; - /* NOTE: overwrites palette */ - palette[index_to_palette[j]] = - palette[num_new_palette]; - - if (full_quantize == 0) - { - int k; - - for (k = 0; k < num_palette; k++) - { - if (tr->map[k] == index_to_palette[j]) - { - tr->map[k] = index_to_palette[next_j]; - map_changed = 1; - } - - if (tr->map[k] == num_new_palette) - { - tr->map[k] = index_to_palette[j]; - map_changed = 1; - } - } - } - - index_to_palette[palette_to_index[num_new_palette]] = - index_to_palette[j]; - - palette_to_index[index_to_palette[j]] = - palette_to_index[num_new_palette]; - - index_to_palette[j] = - png_check_byte(png_ptr, num_new_palette); - - palette_to_index[num_new_palette] = - png_check_byte(png_ptr, j); - } - - if (num_new_palette <= maximum_colors) - break; - } - - if (num_new_palette <= maximum_colors) - break; - } - } - - for (i = 0; i < 769; i++) - { - if (hash[i] != NULL) - { - png_dsortp p = hash[i]; - - while (p) - { - t = p->next; - png_free(png_ptr, p); - p = t; - } - - hash[i] = NULL; - } - } - - max_d += 96; - } /* while num_new_colors > maximum_colors */ - } /* no histogram */ - - num_palette = maximum_colors; - - if (map_changed) /* else the map is 1:1 */ - tr->tr.args |= PNG_QUANTIZE_MAP; - } /* num_palette > maximum_colors */ - - /* The palette has been reduced to the requested number of colors if it - * was over maximum colors before. - */ - - /* TODO: what is this? Apparently the png_struct::palette member gets - * updated if it didn't originally have a palette, but the update relies - * on the app not freeing the passed in palette. - */ - if (png_ptr->palette == NULL) - png_ptr->palette = palette; - - png_ptr->num_palette = png_check_bits(png_ptr, num_palette, 9); - - if (full_quantize) - { - int i; - png_byte distance[1U << (PNG_QUANTIZE_RED_BITS+PNG_QUANTIZE_GREEN_BITS+ - PNG_QUANTIZE_BLUE_BITS)]; - - memset(distance, 0xff, sizeof distance); - - for (i = 0; i < num_palette; i++) - { - int ir; - int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS)); - int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS)); - int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS)); - - for (ir = 0; ir < (1< r) ? ir - r : r - ir); - int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS + - PNG_QUANTIZE_GREEN_BITS)); - - for (ig = 0; ig < (1< g) ? ig - g : g - ig); - int dt = dr + dg; - int dm = ((dr > dg) ? dr : dg); - int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS); - - for (ib = 0; ib < (1< b) ? ib - b : b - ib); - int dmax = ((dm > db) ? dm : db); - int d = dmax + dt + db; - - if (d < distance[d_index]) - { - distance[d_index] = png_check_byte(png_ptr, d); - tr->lut[d_index] = png_check_byte(png_ptr, i); - } - } /* for blue */ - } /* for green */ - } /* for red */ - } /* num_palette */ - } /* full_quantize */ - } /* png_ptr != NULL */ -} -#endif /* READ_QUANTIZE */ - -#ifdef PNG_READ_PACK_SUPPORTED -/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, - * without changing the actual values. Thus, if you had a row with - * a bit depth of 1, you would end up with bytes that only contained - * the numbers 0 or 1. If you would rather they contain 0 and 255, use - * png_set_expand_gray_1_2_4_to_8 instead. - */ -static void -png_do_read_unpack(png_transformp *transform, png_transform_controlp tc) -{ - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_const_bytep ep = png_voidcast(png_const_bytep, tc->dp); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - - sp += PNG_TC_ROWBYTES(*tc) - 1; /* Start from end */ - dp += tc->width; /* output bit depth is 8 */ - -# define png_ptr (tc->png_ptr) - png_debug(1, "in png_do_unpack"); - - switch (tc->bit_depth) - { - case 1: - { - /* Because we copy from the last pixel down the shift required - * at the start is 8-pixels_in_last_byte, which is just: - */ - unsigned int shift = 7U & -tc->width; - - while (dp > ep) - { - *--dp = (*sp >> shift) & 1U; - shift = 7U & (shift+1U); - if (shift == 0U) - --sp; - } - - debug(shift == 0U); - break; - } - - case 2: - { - unsigned int shift = 7U & -(tc->width << 1); - - while (dp > ep) - { - *--dp = (*sp >> shift) & 3U; - shift = 7U & (shift+2U); - if (shift == 0U) - --sp; - } - - debug(shift == 0U); - break; - } - - case 4: - { - unsigned int shift = 7U & -(tc->width << 2); - - while (dp > ep) - { - *--dp = (*sp >> shift) & 15U; - shift = 7U & (shift+4U); - if (shift == 0U) - --sp; - } - - debug(shift == 0U); - break; - } - - default: - impossible("bit depth"); - } - - debug(dp == ep && sp == png_upcast(png_const_bytep, tc->sp)-1U); - tc->sp = dp; - - if ((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0U) - { - tc->range++; - tc->format |= PNG_FORMAT_FLAG_RANGE; - } - - tc->bit_depth = 8U; - PNG_UNUSED(transform) -# undef png_ptr -} - -/* Called from the curiously named png_set_packing API in pngtrans.c; the read - * and write code is separated because read 'unpacks' (from PNG format) and - * write 'packs' (to PNG format.) - */ -void /* PRIVATE */ -png_init_read_pack(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr tc->png_ptr - debug(tc->init); - - if (tc->bit_depth < 8) /* else no packing/unpacking */ - { - /* For indexed images the pack operation does not invalidate the range; in - * fact the corresponding shift operation would! - */ - if ((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0U) - { - tc->range++; - tc->format |= PNG_FORMAT_FLAG_RANGE; - } - - tc->bit_depth = 8U; - - if (tc->init == PNG_TC_INIT_FINAL) - (*transform)->fn = png_do_read_unpack/* sic: it unpacks */; - } - - else /* the transform is not applicable */ - (*transform)->fn = NULL; - -# undef png_ptr -} -#endif /* READ_PACK */ - -#if defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) -# ifdef PNG_READ_tRNS_SUPPORTED -static unsigned int -fill_transparent_pixel(png_const_structrp png_ptr, png_byte *trans) - /* Fill a byte array according to the transparent pixel value and return a - * count of the number of bytes. Low bit depth gray values are replicated in - * the first byte. Writes from 1 to 6 bytes. - */ -{ - /* There must be a tRNS chunk and this must not be a palette image: */ - debug(png_ptr->num_trans == 1 && - !(png_ptr->color_type & (PNG_COLOR_MASK_ALPHA+PNG_COLOR_MASK_PALETTE))); - - if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* gray */ - { - unsigned int t = png_ptr->trans_color.gray; - unsigned int depth = png_ptr->bit_depth; - - if (depth < 16U) - { - /* ISO PNG 11.3.2.1 "tRNS Transparency": "If the image bit depth is - * less than 16, the least significant bits are used and the others are - * 0." So mask out the upper bits. - */ - t &= (1U<> 8); - trans[1] = PNG_BYTE(t); - return 2U; - } - - else /* color */ switch (png_ptr->bit_depth) - { - case 8: /* 8-bit RGB */ - trans[0] = PNG_BYTE(png_ptr->trans_color.red); - trans[1] = PNG_BYTE(png_ptr->trans_color.green); - trans[2] = PNG_BYTE(png_ptr->trans_color.blue); - return 3U; - - case 16: /* 16-bit RGB */ - trans[0] = PNG_BYTE(png_ptr->trans_color.red >> 8); - trans[1] = PNG_BYTE(png_ptr->trans_color.red); - trans[2] = PNG_BYTE(png_ptr->trans_color.green >> 8); - trans[3] = PNG_BYTE(png_ptr->trans_color.green); - trans[4] = PNG_BYTE(png_ptr->trans_color.blue >> 8); - trans[5] = PNG_BYTE(png_ptr->trans_color.blue); - return 6U; - - default: - NOT_REACHED; - return 0U; /* safe */ - } -} -# endif /* READ_tRNS */ -#endif /* READ_EXPAND || READ_BACKGROUND */ - -#ifdef PNG_READ_EXPAND_SUPPORTED -/* Flags for png_init_expand */ -#define PNG_EXPAND_PALETTE 1U /* palette images only, includes tRNS */ -#define PNG_EXPAND_LBD_GRAY 2U /* grayscale low-bit depth only */ -#define PNG_EXPAND_tRNS 4U /* non-palette images only */ - -/* This struct is only required for tRNS matching, but it is convenient to - * allocated it anyway even if READ_tRNS is not supported. - */ -typedef struct -{ - png_transform tr; - unsigned int ntrans; /* number of bytes below */ - png_byte transparent_pixel[6]; /* the transparent pixel value */ -} png_expand; - -#ifdef PNG_READ_tRNS_SUPPORTED -/* Look for colors matching the trans_color in png_ptr, low bit depth gray is - * covered below so this only need handle 8 abd 16-bit channels. - */ -static void -png_do_expand_tRNS(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_expand *tr = png_transform_cast(png_expand, *transform); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - const png_const_bytep ep = sp; - const unsigned int spixel_size = PNG_TC_PIXEL_DEPTH(*tc) >> 3; - unsigned int alpha_size; - - /* We expect opaque and transparent pixels to be interleaved but with long - * sequences of each. Because we are adding an alpha channel we must copy - * down. - */ - debug(!(tc->format & PNG_FORMAT_FLAG_ALPHA)); - debug(spixel_size == tr->ntrans); - sp += PNG_TC_ROWBYTES(*tc); - tc->sp = dp; - tc->format |= PNG_FORMAT_FLAG_ALPHA; - tc->invalid_info |= PNG_INFO_tRNS; - tc->transparent_alpha = 1U; - alpha_size = (PNG_TC_PIXEL_DEPTH(*tc)>>3) - spixel_size; - debug(alpha_size == 1 || alpha_size == 2); - dp += PNG_TC_ROWBYTES(*tc); - - do - { - unsigned int i = spixel_size; - png_byte alpha = 0U; - - dp -= alpha_size; - alpha = 0U; - - /* Copy and check one source pixel (backwards, to avoid any - * overwrite): - */ - do if ((*--dp = *--sp) != tr->transparent_pixel[--i]) /* pixel != tRNS */ - alpha = 0xFFU; - while (i != 0U); - - /* i == 0 */ - do - dp[spixel_size + i] = alpha; - while (++i < alpha_size); - } while (sp > ep); - - debug(sp == ep && dp == tc->dp); /* else overwrite */ -# undef png_ptr -} -#endif /* READ_tRNS */ - -/* Expand grayscale images of less than 8-bit depth to 8 bits. - * libpng 1.7.0: this no longer expands everything, it just expands the low bit - * depth gray row. It does *NOT* expand the tRNS into an alpha channel unless - * it is told to do so. - * - * API CHANGE: the function now does what it was always meant to do. - * - * This is like do_unpack except that the packed data is expanded to the full - * 8-bit range; scaled up. This is not a good thing to do on an indexed image; - * the indices will be invalid. - * - * The tRNS handling is included here too; speed is not important because the - * result will always be cached unless the PNG is very small. - */ -static void -png_do_expand_lbd_gray(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_bytep dp = png_voidcast(png_bytep, tc->dp); - const png_const_bytep ep = dp; - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - const unsigned int bit_depth = tc->bit_depth; -# ifdef PNG_READ_sBIT_SUPPORTED - unsigned int insignificant_bits = 0U; -# endif /* READ_sBIT */ -# ifdef PNG_READ_tRNS_SUPPORTED - unsigned int gray = 0xffffU; /* doesn't match anything */ - unsigned int do_alpha = 0U; -# endif /* READ_tRNS */ - - sp += PNG_TC_ROWBYTES(*tc); /* last byte +1 */ - tc->bit_depth = 8U; - tc->invalid_info |= PNG_INFO_tRNS; -# ifdef PNG_READ_sBIT_SUPPORTED - if (bit_depth > 1U /* irrelevant for bit depth 1 */ && - !(tc->invalid_info & PNG_INFO_sBIT) && - tc->sBIT_G > 0U/*SAFETY*/ && tc->sBIT_G < bit_depth) - insignificant_bits = bit_depth - tc->sBIT_G; -# endif /* READ_sBIT */ - -# ifdef PNG_READ_tRNS_SUPPORTED - if (((*transform)->args & PNG_EXPAND_tRNS) != 0) - { - tc->format |= PNG_FORMAT_FLAG_ALPHA; - tc->transparent_alpha = 1U; - gray = png_ptr->trans_color.gray & ((1U << bit_depth)-1U); - do_alpha = 1U; - } - - /* This helps avoid cluttering the code up with #ifdefs: */ -# define check_tRNS if (do_alpha) *--dp = (pixel != gray) * 255U; -# else /* !READ_tRNS */ -# define check_tRNS -# endif /* READ_tRNS */ - - dp += PNG_TC_ROWBYTES(*tc); /* pre-decremented below */ - - switch (bit_depth) - { - case 1: - { - unsigned int shift = 7U & -tc->width; - unsigned int s = *--sp; - - for(;;) - { - if (shift == 8U) s = *--sp, shift = 0; - - { - const unsigned int pixel = (s >> shift) & 1U; - - check_tRNS - *--dp = PNG_BYTE(pixel * 255U); - if (dp <= ep) break; - } - ++shift; - } - - debug(dp == ep && shift == 7U && sp == tc->sp); - break; - } - - case 2: - { - unsigned int shift = 7U & -(tc->width << 1)/*overflow ok*/; - unsigned int s = *--sp; - - for (;;) - { - if (shift == 8U) s = *--sp, shift = 0; - { - const unsigned int pixel = (s >> shift) & 3U; - - check_tRNS - -# ifdef PNG_READ_sBIT_SUPPORTED - /* 'sig_bits' must be 1 or 2 leaving insignificant_bits 0 or - * 1. This may look silly but it allows a compact representation - * of 1 bit gray + 1 bit alpha (transparency): - */ - if (insignificant_bits /* only 1 bit significant */) - *--dp = PNG_BYTE((pixel >> 1) * 255U); - - else -# endif - *--dp = PNG_BYTE(pixel * 85U); - - if (dp <= ep) break; - } - shift += 2U; - } - - debug(dp == ep && shift == 6U && sp == tc->sp); - break; - } - - case 4: - { - unsigned int shift = 7U & -(tc->width << 2)/*overflow ok*/; - unsigned int s = *--sp; -# ifdef PNG_READ_sBIT_SUPPORTED - const unsigned int div = (1U << (4U-insignificant_bits)) - 1U; -# endif - - for (;;) - { - if (shift == 8U) s = *--sp, shift = 0; - { - unsigned int pixel = (s >> shift) & 15U; - - check_tRNS - -# ifdef PNG_READ_sBIT_SUPPORTED - /* insignificant_bits may be 0, 1, 2 or 3, requiring a multiply - * by 17, 255/7, 85 or 255. Since this operation is always - * cached we don't much care about the time to do the divide - * below. - */ - if (insignificant_bits) - pixel = ((pixel>>insignificant_bits) * 255U + (div>>1)) / div; - - else -# endif - pixel *= 17U; - - *--dp = PNG_BYTE(pixel); - if (dp <= ep) break; - } - - shift += 4U; - } - - debug(dp == ep && shift == 4U && sp == tc->sp); - break; - } - - default: - impossible("bit depth"); - } - - tc->sp = ep; - -# undef check_tRNS -# undef png_ptr -} - -static void -png_init_expand(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - /* The possible combinations are: - * - * 1) PALETTE: the 'palette' flag should be set on the transform control and - * all that need be done is cancel this to cause the cache code to do the - * expansion. - * - * 2) LBP_GRAY, LBP_GRAY+tRNS: use png_do_expand_lbd_gray to do the required - * expand. Can be cached. - * - * 3) tRNS: scan the row for the relevant tRNS value. - * - * Note that expanding 8 to 16 bits is a byte op in pngtrans.c (it just - * replicates bytes). - */ - if (tc->palette) - { - debug(tc->caching && !(tc->format & PNG_FORMAT_FLAG_COLORMAP)); - - if (((*transform)->args & PNG_EXPAND_PALETTE) != 0U) - { - tc->palette = 0U; - tc->invalid_info |= PNG_INFO_PLTE + PNG_INFO_tRNS; - tc->cost = PNG_CACHE_COST_LIMIT; /* the cache is required! */ - } - - /* Note that this needs to happen when the row is processed (!tc->init) as - * well. - */ - } - - else if (!(tc->format & PNG_FORMAT_FLAG_COLORMAP)) - { - png_uint_32 args = (*transform)->args & PNG_BIC_MASK(PNG_EXPAND_PALETTE); - unsigned int bit_depth = tc->bit_depth; - - debug(tc->init); - - if (bit_depth >= 8U) - args &= PNG_BIC_MASK(PNG_EXPAND_LBD_GRAY); - -# ifdef PNG_READ_tRNS_SUPPORTED - if (png_ptr->num_trans == 0U || - (tc->format & PNG_FORMAT_FLAG_ALPHA) != 0U || - (tc->invalid_info & PNG_INFO_tRNS) != 0U) -# endif - args &= PNG_BIC_MASK(PNG_EXPAND_tRNS); - - (*transform)->args = args; - - switch (args) - { - case PNG_EXPAND_LBD_GRAY: - tc->bit_depth = 8U; - tc->invalid_info |= PNG_INFO_tRNS; - - if (tc->init == PNG_TC_INIT_FINAL) - (*transform)->fn = png_do_expand_lbd_gray; - break; - -# ifdef PNG_READ_tRNS_SUPPORTED - case PNG_EXPAND_LBD_GRAY + PNG_EXPAND_tRNS: - tc->bit_depth = 8U; - tc->format |= PNG_FORMAT_FLAG_ALPHA; - tc->invalid_info |= PNG_INFO_tRNS; - tc->transparent_alpha = 1U; - - /* In this case tRNS must be left unmodified for the expansion code - * to handle. - */ - if (tc->init == PNG_TC_INIT_FINAL) - (*transform)->fn = png_do_expand_lbd_gray; - break; - - case PNG_EXPAND_tRNS: - if (tc->init == PNG_TC_INIT_FINAL) - { - png_expand *tr = png_transform_cast(png_expand, *transform); - - affirm((tc->bit_depth == 8U || tc->bit_depth == 16U) && - (tc->format & - (PNG_FORMAT_FLAG_COLORMAP|PNG_FORMAT_FLAG_ALPHA)) == 0U); - - tr->ntrans = fill_transparent_pixel(png_ptr, - tr->transparent_pixel); - tr->tr.fn = png_do_expand_tRNS; - } /* TC_INIT_FINAL */ - - tc->format |= PNG_FORMAT_FLAG_ALPHA; - tc->invalid_info |= PNG_INFO_tRNS; - tc->transparent_alpha = 1U; - break; -# endif /* READ_tRNS */ - - default: /* transform not applicable */ - (*transform)->fn = NULL; - break; - } - - implies(tc->init == PNG_TC_INIT_FINAL, - (*transform)->fn != png_init_expand); - } - - else /* not applicable */ - { - debug(tc->init); - (*transform)->fn = NULL; - NOT_REACHED; - } -# undef png_ptr -} - -void PNGAPI -png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr) -{ - if (png_ptr != NULL) - png_add_transform(png_ptr, sizeof (png_expand), png_init_expand, - PNG_TR_EXPAND)->args |= PNG_EXPAND_LBD_GRAY; -} - -/* Expand paletted images to 8-bit RGB or, if there is a tRNS chunk, RGBA. - * Note that this is effectively handled by the read code palette optimizations. - * - * API CHANGE: this used to have the completely unexpected side effect of - * turning on the above two optimizations. - */ -void PNGAPI -png_set_palette_to_rgb(png_structrp png_ptr) -{ - if (png_ptr != NULL) - png_add_transform(png_ptr, sizeof (png_expand), png_init_expand, - PNG_TR_EXPAND)->args |= PNG_EXPAND_PALETTE; -} - -/* Expand paletted images to RGB, expand grayscale images of less than 8-bit - * depth to 8-bit depth, and expand tRNS chunks to alpha channels. I.e. all the - * above. - */ -void PNGAPI -png_set_expand(png_structrp png_ptr) -{ - if (png_ptr != NULL) - { - png_set_palette_to_rgb(png_ptr); - png_set_expand_gray_1_2_4_to_8(png_ptr); - png_set_tRNS_to_alpha(png_ptr); - } -} -#endif /* READ_EXPAND */ - -#if defined(PNG_READ_EXPAND_SUPPORTED) ||\ - defined(PNG_READ_STRIP_ALPHA_SUPPORTED) - -#define PNG_INIT_STRIP_ALPHA 1U -#define PNG_INIT_EXPAND_tRNS 2U -static void -png_init_alpha(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - int required = 0; - -# if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_tRNS_SUPPORTED) - if ((*transform)->args & PNG_INIT_EXPAND_tRNS) - { - /* Prior to 1.7 the alpha channel was stripped after expanding the tRNS - * chunk, so this effectively cancelled out the expand. - */ - if (png_ptr->num_trans > 0 && !tc->palette && - !((*transform)->args & PNG_INIT_STRIP_ALPHA)) - { - debug((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0); - - required = 1; - tc->expand_tRNS = 1U; - - /* This happens as a result of an explicit API call to - * png_set_tRNS_to_alpha, so expand low-bit-depth gray too: - */ - if (tc->init == PNG_TC_INIT_FORMAT) - png_add_transform(png_ptr, sizeof (png_expand), png_init_expand, - PNG_TR_EXPAND)->args |= PNG_EXPAND_tRNS + PNG_EXPAND_LBD_GRAY; - } - - else - (*transform)->args &= PNG_BIC_MASK(PNG_INIT_EXPAND_tRNS); - } -# endif /* READ_EXPAND && READ_tRNS */ - -# ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if ((*transform)->args & PNG_INIT_STRIP_ALPHA) - { - /* When compose is being done tRNS will be expanded regardless of the - * above test. Rather that trying to work out if this will happen the - * code just inserts a strip operation; it will be removed later if it - * is not needed. - */ - required = 1; - tc->strip_alpha = 1U; - - if (tc->init == PNG_TC_INIT_FORMAT) - png_add_strip_alpha_byte_ops(png_ptr); - } -# endif /* READ_STRIP_ALPHA */ - - if (!required) - (*transform)->fn = NULL; -# undef png_ptr -} -#endif /* READ_EXPAND || READ_STRIP_ALPHA */ - -#ifdef PNG_READ_EXPAND_SUPPORTED -/* Expand tRNS chunks to alpha channels. This only expands the tRNS chunk on - * non-palette formats; call png_set_palette_to_rgb to get the corresponding - * effect for a palette. - * - * Note that this will expand low bit depth gray if there is a tRNS chunk, but - * if not nothing will happen. - * - * API CHANGE: this used to do all the expansions, it was rather pointless - * calling it. - */ -void PNGAPI -png_set_tRNS_to_alpha(png_structrp png_ptr) -{ - if (png_ptr != NULL) - png_add_transform(png_ptr, 0/*size*/, png_init_alpha, PNG_TR_INIT_ALPHA)-> - args |= PNG_INIT_EXPAND_tRNS; -} -#endif /* READ_EXPAND */ - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED -void PNGAPI -png_set_strip_alpha(png_structrp png_ptr) -{ - if (png_ptr != NULL) - png_add_transform(png_ptr, 0/*size*/, png_init_alpha, PNG_TR_INIT_ALPHA)-> - args |= PNG_INIT_STRIP_ALPHA; -} -#endif /* READ_STRIP_ALPHA */ - -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED -static void -png_do_chop_16_to_8(png_transformp *transform, png_transform_controlp tc) - /* This is actually a repeat of the byte transform, unnecessary code - * replication. - * - * TODO: remove this - */ -{ -# define png_ptr (tc->png_ptr) - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); /* source */ - png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc); /* end+1 */ - png_bytep dp = png_voidcast(png_bytep, tc->dp); /* destination */ - - debug(tc->bit_depth == 16U); - tc->sp = dp; - tc->bit_depth = 8U; - - while (sp < ep) - *dp++ = *sp, sp += 2; - - debug(sp == ep); -# undef png_ptr - - PNG_UNUSED(transform) -} - -/* A transform containing some useful scaling values... */ -typedef struct -{ - png_transform tr; - png_uint_32 shifts; /* 4 4-bit values preceeded by a shibboleth (1) */ - png_uint_32 channel_scale[4]; -} png_transform_scale_16_to_8; - -/* Scale rows of bit depth 16 down to 8 accurately */ -static void -png_do_scale_16_to_8(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); /* source */ - png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc); /* end+1 */ - png_bytep dp = png_voidcast(png_bytep, tc->dp); /* destination */ - png_transform_scale_16_to_8 *tr = - png_transform_cast(png_transform_scale_16_to_8, *transform); - png_uint_32p scale = 0; - png_uint_32 shift = 1U; /* set the shibboleth at the start */ - - debug(tc->bit_depth == 16U); - tc->sp = dp; - tc->bit_depth = 8U; - - while (sp < ep) - { - /* The input is an array of 16 bit components, these must be scaled to - * 8 bits each taking into account the sBIT setting. The calculation - * requires that the insignificant bits be stripped from the input value - * via a shift then scaled back to 8 bits: - * - * output = ((input >> shift) * scale + round) >> 24 - * - * The shifts are packed into tr->shifts, with the end of the list marked - * by a shibboleth, 1, which is preset above. - */ - png_uint_32 v = png_get_uint_16(sp); - - sp += 2; - - if (shift == 1U) - { - shift = tr->shifts; - scale = tr->channel_scale; - } - - *dp++ = PNG_BYTE(((v >> (shift & 0xFU)) * *scale++ + 0x800000U) >> 24); - shift >>= 4; - } - - affirm(sp == ep); -# undef png_ptr -} - -static int -add_scale(png_transform_scale_16_to_8 *tr, unsigned int sBIT, unsigned int ch) -{ - /* This is the output max (255) scaled by 2^24 divided by the input max' - * (which is variable) and rounded. It gives the exact 8-bit answer for all - * input sBIT depths when used in the calculation: - * - * output = ((input >> shift) * scale + 0x800000U) >> 24 - */ - tr->channel_scale[ch] = (0xFF000000U + ((1U<>1)) / ((1U<shifts |= ((16U-sBIT) & 0xFU) << (4U*ch); - - /* The result says whether there are 8 or fewer significant bits in the - * input value; if so we can just drop the low byte. - */ - return sBIT <= 8U; -} - -static void -png_init_scale_16_to_8(png_transformp *transform, png_transform_controlp tc) -{ - if (tc->bit_depth == 16U) - { -# define png_ptr (tc->png_ptr) - tc->bit_depth = 8U; - /* But this invalidates tRNS (a 16-bit tRNS cannot be updated to match - * 8-bit data correctly). - */ - tc->invalid_info |= PNG_INFO_tRNS+PNG_INFO_hIST+PNG_INFO_pCAL; - /* TODO: These need further processing: PNG_INFO_bKGD */ - - if (tc->init == PNG_TC_INIT_FINAL) - { - png_transform_scale_16_to_8 *tr = - png_transform_cast(png_transform_scale_16_to_8, *transform); - - /* Set the scale factors for each channel (up to 4), the factors are - * made so that: - * - * ((channel >> shift) * factor + 0x800000U) >> 24 - * - * Gives the required 8-bit value. The 'shift' is stored in a single - * png_uint_32 with a shibboleth at the end. - */ - unsigned int channels = 0U; - int chop_ok = 1; - - tr->shifts = 0U; - - /* This adds up to four scale factors, the remainder are left as 0 - * which is safe and leads to obvious errors in the output images in - * the event of an (internal) error. - */ - if (tc->format & PNG_FORMAT_FLAG_COLOR) - chop_ok &= add_scale(tr, tc->sBIT_R, channels++); - - chop_ok &= add_scale(tr, tc->sBIT_G, channels++); - - if (tc->format & PNG_FORMAT_FLAG_COLOR) - chop_ok &= add_scale(tr, tc->sBIT_B, channels++); - - if (tc->format & PNG_FORMAT_FLAG_ALPHA) - chop_ok &= add_scale(tr, tc->sBIT_A, channels++); - - if (chop_ok) - tr->tr.fn = png_do_chop_16_to_8; - - else - { - int handled = 1; - - /* Add the shibboleth at the end */ - tr->shifts |= 1U << (4U*channels); - tr->tr.fn = png_do_scale_16_to_8; - - /* sBIT is a little tricky; it has to be processed in the scaling - * operation. The result will have the same number of bits unless - * there were more than 8 before. The sBIT flags in the transform - * control are left unchanged here because the data is still valid, - * unless all the values end up as 8 in which case there is no - * remaining sBIT info. - * - * Note that fields, such as alpha, which are not set for this row - * format will always have max values, so won't reset 'handled': - */ - if (tc->sBIT_R >= 8U) tc->sBIT_R = 8U; else handled = 0; - if (tc->sBIT_G >= 8U) tc->sBIT_G = 8U; else handled = 0; - if (tc->sBIT_B >= 8U) tc->sBIT_B = 8U; else handled = 0; - if (tc->sBIT_A >= 8U) tc->sBIT_A = 8U; else handled = 0; - - /* If all the sBIT values were >= 8U all the bits are now - * significant: - */ - if (handled) - tc->invalid_info |= PNG_INFO_sBIT; - } - } - -# undef png_ptr - } - - else /* not applicable */ - (*transform)->fn = NULL; -} - -void PNGAPI -png_set_scale_16(png_structrp png_ptr) -{ - if (png_ptr != NULL) - png_add_transform(png_ptr, sizeof (png_transform_scale_16_to_8), - png_init_scale_16_to_8, PNG_TR_SCALE_16_TO_8); -} -#endif /* READ_SCALE_16_TO_8 */ - -#ifdef PNG_READ_GAMMA_SUPPORTED - /* Code that depends on READ_GAMMA support; RGB to gray convertion and - * background composition (including the various alpha-mode handling - * operations which produce pre-multiplied alpha by composing on 0). - */ -/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */ -static png_fixed_point -png_reciprocal(png_fixed_point a) -{ -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - double r = floor(1E10/a+.5); - - if (r <= 2147483647. && r >= -2147483648.) - return (png_fixed_point)r; -#else - png_fixed_point res; - - if (png_muldiv(&res, PNG_FP_1, PNG_FP_1, a) != 0) - return res; -#endif - - return 0; /* error/overflow */ -} - -/* This is the shared test on whether a gamma value is 'significant' - whether - * it is worth doing gamma correction. 'significant_bits' is the number of bits - * in the values to be corrected which are significant. - */ -static int -png_gamma_significant(png_const_structrp png_ptr, png_fixed_point gamma_val, - unsigned int sbits) -{ -#if 0 - /* This seems to be wrong. The issue is that when the app asks for a higher - * bit depth output than the input has significant bits it causes gamma - * correction to be skipped (this was the intent) however there's no - * particular guarantee that the app won't go on to do further gamma - * processing - pngstest does this - and this messes up the results - * completely. - * - * TODO: work out how to optimize this correctly. - */ - /* The following table lists the threshold as a difference from PNG_FP_1 at - * which the gamma correction will make a change to at least an 'sbits' - * value. There is no entry for 1 bit values; gamma correction is never - * significant. - */ - static const png_uint_16 gamma_threshold_by_sbit[15][2] = - { - { 36907, 63092 }, /* 2 bits */ - { 17812, 21518 }, /* 3 bits */ - { 8675, 9496 }, /* 4 bits */ - { 4290, 4484 }, /* 5 bits */ - { 2134, 2181 }, /* 6 bits */ - { 1064, 1075 }, /* 7 bits */ - { 531, 534 }, /* 8 bits */ - { 265, 266 }, /* 9 bits */ - { 132, 132 }, /* 10 bits */ - { 66, 66 }, /* 11 bits */ - { 33, 33 }, /* 12 bits */ - { 16, 16 }, /* 13 bits */ - { 8, 8 }, /* 14 bits */ - { 4, 4 }, /* 15 bits */ - { 2, 2 }, /* 16 bits */ - }; - - /* Handle out of range values in release by doing the gamma correction: */ - debug_handled(sbits > 0U && sbits <= 16U); - if (sbits == 0U || sbits > 16U) - return 1; - - /* 1 bit input or zero gamma, no correction possible/required: */ - if (gamma_val == 0 || sbits < 2U) - return 0; - - if (gamma_val < PNG_FP_1 - gamma_threshold_by_sbit[sbits-2U][0U]) - return gamma_val < PNG_FP_1 - png_ptr->gamma_threshold; - - else if (gamma_val > PNG_FP_1 + gamma_threshold_by_sbit[sbits-2U][1U]) - return gamma_val > PNG_FP_1 + png_ptr->gamma_threshold; -#else /* FIXUP */ - if (gamma_val < PNG_FP_1) - return gamma_val < PNG_FP_1 - png_ptr->gamma_threshold; - - else if (gamma_val > PNG_FP_1) - return gamma_val > PNG_FP_1 + png_ptr->gamma_threshold; - - PNG_UNUSED(sbits) -#endif /* FIXUP */ - - return 0; /* not significant */ -} - -static int -png_gamma_equal(png_const_structrp png_ptr, png_fixed_point g1, - png_fixed_point g2, png_fixed_point *c, unsigned int sbits) - /* Gamma values are equal, or at least one is unknown; c is the correction - * factor from g1 to g2, i.e. g2/g1. - */ -{ - return sbits == 1U || g1 == 0 || g2 == 0 || g1 == g2 || - (png_muldiv(c, g2, PNG_FP_1, g1) && - !png_gamma_significant(png_ptr, *c, sbits)); -} - -#ifdef PNG_SIMPLIFIED_READ_SUPPORTED -int -png_need_gamma_correction(png_const_structrp png_ptr, png_fixed_point gamma, - int sRGB_output) - /* This is a hook for the simplified code; it just decides whether or not the - * given gamma (which defaults to that of the PNG data) is close enough to - * linear or sRGB not to require gamma correction. - */ -{ - if (gamma == 0) - gamma = png_ptr->colorspace.gamma; - - if (gamma != 0 && - (png_ptr->colorspace.flags & - (PNG_COLORSPACE_INVALID|PNG_COLORSPACE_HAVE_GAMMA)) == - PNG_COLORSPACE_HAVE_GAMMA) - { - - if (sRGB_output && !png_muldiv(&gamma, gamma, PNG_GAMMA_sRGB, PNG_FP_1)) - return 0; /* overflow, so no correction */ - - return png_gamma_significant(png_ptr, gamma, (png_ptr->color_type & - PNG_COLOR_MASK_PALETTE) ? 8U : png_ptr->bit_depth); - } - - return 0; /* no info, no correction */ -} -#endif /* SIMPLIFIED_READ */ - -#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED -/* Fixed point gamma. - * - * The code to calculate the tables used below can be found in the shell script - * contrib/tools/intgamma.sh - * - * To calculate gamma this code implements fast log() and exp() calls using only - * fixed point arithmetic. This code has sufficient precision for either 8-bit - * or 16-bit sample values. - * - * The tables used here were calculated using simple 'bc' programs, but C double - * precision floating point arithmetic would work fine. - * - * 8-bit log table - * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to - * 255, so it's the base 2 logarithm of a normalized 8-bit floating point - * mantissa. The numbers are 32-bit fractions. - */ -static const png_uint_32 -png_8bit_l2[128] = -{ - 4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U, - 3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U, - 3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U, - 3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U, - 3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U, - 2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U, - 2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U, - 2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U, - 2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U, - 2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U, - 1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U, - 1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U, - 1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U, - 1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U, - 1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U, - 971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U, - 803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U, - 639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U, - 479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U, - 324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U, - 172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U, - 24347096U, 0U - -#if 0 /* NOT USED */ - /* The following are the values for 16-bit tables - these work fine for the - * 8-bit conversions but produce very slightly larger errors in the 16-bit - * log (about 1.2 as opposed to 0.7 absolute error in the final value). To - * use these all the shifts below must be adjusted appropriately. - */ - 65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054, - 57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803, - 50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068, - 43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782, - 37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887, - 31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339, - 25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098, - 20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132, - 15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415, - 10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523, - 6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495, - 1119, 744, 372 -#endif -}; - -#if 0 /* UNUSED */ -static png_int_32 -png_log8bit(unsigned int x) -{ - png_uint_32 lg2 = 0U; - - /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log, - * because the log is actually negate that means adding 1. The final - * returned value thus has the range 0 (for 255 input) to 7.994 (for 1 - * input), return -1 for the overflow (log 0) case, - so the result is - * always at most 19 bits. - */ - if ((x &= 0xffU) == 0U) /* 0 input, -inf output */ - return -0xfffff; - - if ((x & 0xf0U) == 0U) - lg2 = 4U, x <<= 4; - - if ((x & 0xc0U) == 0U) - lg2 += 2U, x <<= 2; - - if ((x & 0x80U) == 0U) - lg2 += 1U, x <<= 1; - - /* result is at most 19 bits, so this cast is safe: */ - return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128U]+32768U)>>16)); -} -#endif /* UNUSED */ - -/* The above gives exact (to 16 binary places) log2 values for 8-bit images, - * for 16-bit images we use the most significant 8 bits of the 16-bit value to - * get an approximation then multiply the approximation by a correction factor - * determined by the remaining up to 8 bits. This requires an additional step - * in the 16-bit case. - * - * We want log2(value/65535), we have log2(v'/255), where: - * - * value = v' * 256 + v'' - * = v' * f - * - * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128 - * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less - * than 258. The final factor also needs to correct for the fact that our 8-bit - * value is scaled by 255, whereas the 16-bit values must be scaled by 65535. - * - * This gives a final formula using a calculated value 'x' which is value/v' and - * scaling by 65536 to match the above table: - * - * log2(x/257) * 65536 - * - * Since these numbers are so close to '1' we can use simple linear - * interpolation between the two end values 256/257 (result -368.61) and 258/257 - * (result 367.179). The values used below are scaled by a further 64 to give - * 16-bit precision in the interpolation: - * - * Start (256): -23591 - * Zero (257): 0 - * End (258): 23499 - * - * In libpng 1.7.0 this is further generalized to return -log2(value/maxval) for - * any maxval up to 65535. This is done by evaluating -log2(value/65535) first - * then adjusting for the required maxval: - * - * ( value) (value 65535) (value) ( 65535) - * -log2(------) = -log2(----- x ------) = -log2(-----)-log2(------) - * (maxval) (65535 maxval) (65535) (maxval) - * - * The extra argument, 'factor', is (2^(16+12))*log2(65535/maxval) (a positive - * value less than 2^32) and this is *subtracted* from the intermediate - * calculation below. - */ -static png_int_32 -png_log(unsigned int x, png_uint_32 factor) - /* x: a value of up to 16 bits, - * factor: a 4.28 number which is subtracted from the log below - */ -{ - png_uint_32 lg2 = 0U; - - /* As above, but now the input has 16 bits. */ - if ((x &= 0xffffU) == 0U) - return -0xfffff; - - if ((x & 0xff00U) == 0U) - lg2 = 8U, x <<= 8; - - if ((x & 0xf000U) == 0U) - lg2 += 4U, x <<= 4; - - if ((x & 0xc000U) == 0U) - lg2 += 2U, x <<= 2; - - if ((x & 0x8000U) == 0U) - lg2 += 1U, x <<= 1; - - /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional - * value. - */ - lg2 <<= 28; - lg2 += (png_8bit_l2[(x>>8)-128U]+8U) >> 4; - - /* Now we need to interpolate the factor, this requires a division by the top - * 8 bits. Do this with maximum precision. - */ - { - png_uint_32 i = x; - - i = ((i << 16) + (i >> 9)) / (x>> 8); - - /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24, - * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us - * exactly 16 bits to interpolate to get the low bits of the result. - * Round the answer. Note that the end point values are scaled by 64 to - * retain overall precision and that 'lg2' is current scaled by an extra - * 12 bits, so adjust the overall scaling by 6-12. Round at every step. - */ - i -= 1U << 24; - - if (i <= 65536U) /* <= '257' */ - lg2 += ((23591U * (65536U-i)) + (1U << (16+6-12-1))) >> (16+6-12); - - else - lg2 -= ((23499U * (i-65536U)) + (1U << (16+6-12-1))) >> (16+6-12); - } - - if (lg2 >= factor) - return (png_int_32)/*SAFE*/((lg2 - factor + 2048U) >> 12); - - else /* the result will be greater than 1.0, so negative: */ - return -(png_int_32)/*SAFE*/((factor - lg2 + 2048U) >> 12); -} - -#if 0 /* UNUSED */ -static png_int_32 -png_log16bit(unsigned int x) -{ - return png_log(x, 0U); -} -#endif /* UNUSED */ - -/* libpng 1.7.0: generalization of png_log{8,16}bit to accept an n-bit input - * value. We want to maintain 1% accuracy in linear light space. This - * corresponds to, approximately, (1*g)% in a gamma encoded space where the - * gamma encoding is 'g' (in the PNG sense, e.g. 0.45455 for sRGB). Apparently - * this requires unbounded accuracy as the gamma encoding value goes down and - * this is a problem for modern HDR data because it may require a high gamma to - * accurately encode image data over a wide dynamic range; the dynamic range of - * 16-bit linear data is only 655:1 if 1% accuracy is needed! - * - * However 16-bit gamma encoded data is still limited because PNG can only - * express gamma encoding. (A log-to-base-1.01 encoding is unlimited; a 12-bit - * value, with 4094 steps, has a dynamic range of more than 1:10^17, which - * exceeds the human eye's range of 1:10^14.) - * - * Notice that sRGB uses a 1/2.4 encoding and CIELab uses a 1/3 encoding. It is - * obvious that, if we assume a maximum D difference in the luminance of - * adjacent pixel values the dynamic range is given by the lowest pixel value - * which is D or less greater than its predecessor, so: - * - * ( P ) (1) - * (---)^(-) = D - * (P-1) (g) - * - * and the maximum dynamic range that can be achieved using M+1 separate values, - * where M+1 is 2^N-1 for an N bit value, reserving the first value for 0, is: - * - * (M) (1) - * range(R) = (-)^(-) - * (P) (g) - * - * So we can eliminate 'P' from the two equations: - * - * P = (P-1) x (D^g) - * - * D^g - * P = ----- - * D^g-1 - * - * (M x (D^g-1)) (1) - * R = (-----------)^(-) - * ( D^g ) (g) - * - * (M x (D^g-1)) ^ (1/g) - * = --------------------- - * D - * - * Which is a function in two variables (R and g) for a given D (maximum delta - * between two adjacent pixel values) and M (number of pixel values, controlled - * by the channel bit depth). - * - * See contrib/tools/dynamic-range.c for code exploring this function. This - * program will output the optimal gamma for a given number of bits and - * precision. - * - * The range of sensitivity of human vision is roughly as follows (this comes - * from the wikipedia article on scotopic vision): - * - * scotopic: 10^-6 to 10^-3.5 cd/m^2 - * mesopic: 10^-3 to 10^0.5 cd/m^2 - * photopic: 10 to 10^8 cd/m^2 - * - * Giving a total range of about 1:10^14. The maximum precision at which this - * range can be achieved using 16-bit channels is about .15% using a gamma of - * 36, higher ranges are possible using higher gammas but precision is reduced. - * The range with 1% precision and 16-bit channels is 1:10^104, using a gamma of - * 240. - * - * In general the optimal gamma for n-bit channels (where 'n' is at least 7 and - * precision is .01 or less) is: - * - * 2^n * precision - * gamma = --------------- - * 2.736 - * - * Or: (24000 * precision) for 16-bit data. - * - * The net effect is that we can't rely on the encoding gamma being limited to - * values around 1/2.5! - */ -static png_int_32 -png_log_nbit(unsigned int x, unsigned int nbits) -{ - static const png_uint_32 factors[16] = - { - 4294961387U, /* 1 bit */ - 3869501255U, /* 2 bit */ - 3541367788U, /* 3 bit */ - 3246213428U, /* 4 bit */ - 2965079441U, /* 5 bit */ - 2690447525U, /* 6 bit */ - 2418950626U, /* 7 bit */ - 2148993476U, /* 8 bit */ - 1879799410U, /* 9 bit */ - 1610985205U, /* 10 bit */ - 1342360514U, /* 11 bit */ - 1073830475U, /* 12 bit */ - 805347736U, /* 13 bit */ - 536888641U, /* 14 bit */ - 268441365U, /* 15 bit */ - 0U /* 16 bit */ - }; - - return png_log(x, factors[nbits-1]); -} - - -/* The 'exp()' case must invert the above, taking a 20-bit fixed point - * logarithmic value and returning a 16 or 8-bit number as appropriate. In - * each case only the low 16 bits are relevant - the fraction - since the - * integer bits (the top 4) simply determine a shift. - * - * The worst case is the 16-bit distinction between 65535 and 65534. This - * requires perhaps spurious accuracy in the decoding of the logarithm to - * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance - * of needing this accuracy in practice. - * - * To deal with this the following exp() function works out the exponent of the - * frational part of the logarithm by using an accurate 32-bit value from the - * top four fractional bits then multiplying in the remaining bits. - */ -static const png_uint_32 -png_32bit_exp[16] = -{ - /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */ - 4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U, - 3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U, - 2553802834U, 2445529972U, 2341847524U, 2242560872U -}; - -/* Adjustment table; provided to explain the numbers in the code below. */ -#if 0 /* BC CODE */ -for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"} - 11 44937.64284865548751208448 - 10 45180.98734845585101160448 - 9 45303.31936980687359311872 - 8 45364.65110595323018870784 - 7 45395.35850361789624614912 - 6 45410.72259715102037508096 - 5 45418.40724413220722311168 - 4 45422.25021786898173001728 - 3 45424.17186732298419044352 - 2 45425.13273269940811464704 - 1 45425.61317555035558641664 - 0 45425.85339951654943850496 -#endif - -static png_uint_32 -png_exp(png_int_32 x) - /* Utility, the value 'x' must be in the range 0..0x1fffff */ -{ - /* Obtain a 4-bit approximation */ - png_uint_32 e = png_32bit_exp[(x >> 12) & 0xf]; - - /* Incorporate the low 12 bits - these decrease the returned value by - * multiplying by a number less than 1 if the bit is set. The multiplier - * is determined by the above table and the shift. Notice that the values - * converge on 45426 and this is used to allow linear interpolation of the - * low bits. - */ - if (x & 0x800) - e -= (((e >> 16) * 44938U) + 16U) >> 5; - - if (x & 0x400) - e -= (((e >> 16) * 45181U) + 32U) >> 6; - - if (x & 0x200) - e -= (((e >> 16) * 45303U) + 64U) >> 7; - - if (x & 0x100) - e -= (((e >> 16) * 45365U) + 128U) >> 8; - - if (x & 0x080) - e -= (((e >> 16) * 45395U) + 256U) >> 9; - - if (x & 0x040) - e -= (((e >> 16) * 45410U) + 512U) >> 10; - - /* And handle the low 6 bits in a single block. */ - e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9; - - /* Handle the upper bits of x, note that this works for x up to 0x1fffff but - * fails for larger or negative x, where the shift (x >> 16) exceeds 31: - */ - e >>= x >> 16; - return e; -} - -#if 0 /* UNUSED */ -static png_byte -png_exp8bit(png_int_32 lg2) -{ - /* The input is a negative fixed point (16:16) logarithm with a useable range - * of [0.0..8.0). Clamp the value so that the output of png_exp is in the - * range (254.5/255..0.5/255): - */ - if (lg2 <= 185) /* -log2(254.5/255) */ - return 255U; - - else if (lg2 > 589453) /* -log2(0.5/255) */ - return 0U; - - else - { - /* Get a 32-bit value: */ - png_uint_32 x = png_exp(lg2); - - /* Convert the 32-bit value to 0..255 by multiplying by 256-1. Note that - * the second, rounding, step can't overflow because of the first, - * subtraction, step. - */ - x -= x >> 8; - return PNG_BYTE((x + 0x7fffffU) >> 24); - } -} - -static png_uint_16 -png_exp16bit(png_int_32 lg2) -{ - if (lg2 <= 0) /* -log2(65534.5/65535) */ - return 65535U; - - else if (lg2 > 1114110) /* -log2(0.5/65535) */ - return 0U; - - else - { - /* Get a 32-bit value: */ - png_uint_32 x = png_exp(lg2); - - /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */ - x -= x >> 16; - return PNG_UINT_16((x + 32767U) >> 16); - } -} -#endif /* UNUSED */ - -static png_uint_32 -png_exp_nbit(png_int_32 lg2, unsigned int n) -{ - /* These pre-computed limits give the low value of lg2 at and below which - * 2^(-lg2/65536) * (2^n-1) gives (2^n-1) and the high value of lg2 above - * which 2(^-lg2/65536) * (2^n-1) gives 0: - */ - static const png_int_32 limits[16][2] = - { - { 65535, 65535 }, /* bits = 1 */ - { 17238, 169408 }, /* bits = 2 */ - { 7006, 249518 }, /* bits = 3 */ - { 3205, 321577 }, /* bits = 4 */ - { 1537, 390214 }, /* bits = 5 */ - { 753, 457263 }, /* bits = 6 */ - { 372, 523546 }, /* bits = 7 */ - { 185, 589453 }, /* bits = 8 */ - { 92, 655175 }, /* bits = 9 */ - { 46, 720803 }, /* bits = 10 */ - { 23, 786385 }, /* bits = 11 */ - { 11, 851944 }, /* bits = 12 */ - { 5, 917492 }, /* bits = 13 */ - { 2, 983034 }, /* bits = 14 */ - { 1, 1048573 }, /* bits = 15 */ - { 0, 1114110 } /* bits = 16 */ - }; - - /* If 'max' is 2^n-1: */ - if (lg2 <= limits[n-1][0]) /* -log2((max-.5)/max) */ - return (1U << n)-1U; - - else if (lg2 > limits[n-1][1]) /* -log2(.5/max) */ - return 0U; - - else /* 'n' will be at least 2 */ - { - /* Get a 32-bit value: */ - png_uint_32 x = png_exp(lg2); - - /* Convert the 32-bit value to 0..(2^n-1) by multiplying by 2^n-1: */ - x -= x >> n; - return (x + ((1U<<(31U-n))-1U)) >> (32U-n); - } -} -#endif /* !FLOATING_ARITHMETIC */ - -#if 0 /* UNUSED */ -static png_byte -png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val) -{ - if (value == 0U) - return 0U; - - else if (value >= 255U) - return 255U; - - else - { -# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - /* 'value' is unsigned, ANSI-C90 requires the compiler to correctly - * convert this to a floating point value. This includes values that - * would overflow if 'value' were to be converted to 'int'. - * - * Apparently GCC, however, does an intermediate conversion to (int) - * on some (ARM) but not all (x86) platforms, possibly because of - * hardware FP limitations. (E.g. if the hardware conversion always - * assumes the integer register contains a signed value.) This results - * in ANSI-C undefined behavior for large values. - * - * Other implementations on the same machine might actually be ANSI-C90 - * conformant and therefore compile spurious extra code for the large - * values. - * - * We can be reasonably sure that an unsigned to float conversion - * won't be faster than an int to float one. Therefore this code - * assumes responsibility for the undefined behavior, which it knows - * can't happen because of the check above. - * - * Note the argument to this routine is an (unsigned int) because, on - * 16-bit platforms, it is assigned a value which might be out of - * range for an (int); that would result in undefined behavior in the - * caller if the *argument* ('value') were to be declared (int). - */ - double r = 255*pow((int)/*SAFE*/value/255.,gamma_val*.00001); - if (r < .5) - return 0U; - - else if (r >= 254.5) - return 255U; - - r = floor(r+.5); - return (png_byte)/*SAFE*/r; -# else - png_int_32 lg2 = png_log8bit(value); - png_int_32 res; - - /* Overflow in the muldiv means underflow in the calculation, this is - * OK (it happens for ridiculously high gamma). - */ - if (!png_muldiv(&res, gamma_val, lg2, PNG_FP_1)) - return 0U; /* underflow */ - - return png_exp8bit(res); -# endif - } -} -#endif /* UNUSED */ - -/* libpng-1.7.0: this private function converts an n-bit input value to an - * m-bit output value. - */ -unsigned int -png_gamma_nxmbit_correct(unsigned int value, png_fixed_point gamma_val, - unsigned int n/*input bits*/, unsigned int m/*output bits */) -{ - if (value == 0U) - return 0U; - - else - { - unsigned int min = (1U<= min) - return mout; - - else - { -# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - double r = value; - r /= min; - r = floor(mout * pow(r, gamma_val*.00001)+.5); - if (r < 1) - return 0U; - - else if (r >= mout) - return mout; - - return (unsigned int)/*SAFE*/r; -# else - png_int_32 lg2 = png_log_nbit(value, n); - png_int_32 res; - - if (!png_muldiv(&res, gamma_val, lg2, PNG_FP_1)) - return 0U; /* underflow */ - - return png_exp_nbit(res, m); -# endif - } - } -} - -#if 0 /*UNUSED*/ -static unsigned int -png_gamma_sbit_correct(unsigned int value, png_fixed_point gamma_val, - unsigned int n/*input bits*/, unsigned int sbits, - unsigned int m/*output bits */) - /* As above but the number of significant bits in 'n' is passed in. */ -{ - if (sbits < n) - { - value >>= (n-sbits); - n = sbits; - } - - return png_gamma_nxmbit_correct(value, gamma_val, n, m); -} -#endif /*UNUSED*/ - -static int -push_gamma_expand(png_transformp *transform, png_transform_controlp tc, - int need_alpha) - /* Utility to push a transform to expand low-bit-depth gray and, where - * required, tRNS chunks. The caller must return immediately if this - * returns true because the init of the new transform has been run in place - * of the caller's. - */ -{ -# define png_ptr (tc->png_ptr) - unsigned int expand = 0; - - affirm(tc->init == PNG_TC_INIT_FINAL); - - if (tc->bit_depth < 8U) /* low bit gray: expand to 8 bits */ - expand = PNG_EXPAND_LBD_GRAY; - - /* Gamma correction invalidates tRNS, so if it is being expanded and - * alpha is not being stripped expand it now. - */ - if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0 && !tc->palette && - png_ptr->num_trans == 1 && (tc->invalid_info & PNG_INFO_tRNS) == 0) - { - if (need_alpha || (tc->expand_tRNS && !tc->strip_alpha)) - expand |= PNG_EXPAND_tRNS; - - else - tc->invalid_info |= PNG_INFO_tRNS; - } - - if (expand == 0) - return 0; /* nothing needs to be done */ - - { - png_transformp tr = png_push_transform(png_ptr, sizeof (png_expand), - png_init_expand, transform, NULL/*don't run init*/); - - debug(tr == *transform); - tr->args |= expand; - - /* This must be run immediately, because it just got inserted where this - * transform is; this is safe, the caller must return immediately. - */ - png_init_expand(transform, tc); - affirm(tr->fn != NULL); /* because it should need to do something! */ - } - - return 1; -# undef png_ptr -} - -/* Low bit depth gray gamma correction. The 1-bit case is a no-op because 0 and - * 1 always map to 0 and 1. The 2-bit case has the following possiblities: - * - * bits/correction: g0 g1 g2 g3 g4 g5 g6 - * 00 -> 00 00 00 00 00 00 00 - * 01 -> 11 10 10 01 00 00 00 - * 10 -> 11 11 10 10 10 01 00 - * 11 -> 11 11 11 11 11 11 11 - * - * Where the breakpoints are: - * - * g0: correction <= 16595 (1 - log(2.5/3)) - * g1: 16595 < correction <= 44966 (log(2.5/3)/log(2/3)) - * g2: 44966 < correction <= 63092 (1 - log(1.5/3)) - * g3: 63092 < correction <= 163092 (1 - log(.5/3)) - * g4: 163092 < correction <= 170951 (log(1.5/3)/log(2/3)) - * g5: 170951 < correction <= 441902 (log(.5/3)/log(2/3) - * g6 441902 < correction - * - * This can be done by bit-hacking on the byte values (4 pixels), given that - * the correction is fixed (indeed, it can be done on whole 32-bit values!) - * - * g0: B |= B>>1; B &= 0x55U; B |= B<<1; * either bit set - * g1: B ^= B>>1; B &= 0x55U; B += B; * one bit set - * g2: B &= (~B)>>1; B &= 0x55U; B += B; * low bit set, high bit unset - * g3: no-op - * g4: B &= (~B)>>1; B &= 0x55U; B -= B; * low bit set, high bit unset - * g5: B ^= B>>1; B &= 0x55U; B -= B; * one bit set - * g6: B &= B>>1; B &= 0x55U; B |= B<<1; * both bits set - */ -typedef struct -{ - png_transform tr; - png_fixed_point correct; - png_fixed_point to_gamma; - png_uint_32 shifts; /* 1 followed by up to 4 4-bit shifts */ - png_uint_32 channel_scale[4]; /* up to 4 channel scale factors */ - /* These factors are used: - * - * (input >> (shifts & 0xFU) * channel_scale + SCALE_R) >> SCALE_S - * - * Where the rounding value, SCALE_R and the shift SCALE_S are dependent - * on the bit depth: - * - * SCALE_S = 32 - bit_depth range 16..31 - * SCALE_R = 1 << (SCALE_S-1) - */ - unsigned int to_bit_depth; - unsigned int encode_alpha :1; - unsigned int optimize_alpha :1; -} png_transform_gamma; - -static unsigned int -init_gamma_sBIT(png_transform_gamma *tr, png_transform_controlp tc) - /* Returns true if sBIT processing is required, otherwise all relevant sBIT - * values match the from (tc) bit depth. - */ -{ - /* The to_bit_depth and to_gamma fields are already set, but updated values - * are needed for sBIT and the shifts and channel_scale fields must be filled - * in correctly. The do_gamma setting says whether gamma correction will be - * done, but the scale factors are filled in regardless. - * - * The general scaling equation is: - * - * ((in >> shift) * factor + round) >> (32 - to_bit_depth) - * - * 'factor' is then the rounded value of: - * - * out_max - * ------- . (1 << (32-to_bit_depth)) - * in_max - */ -# define png_ptr (tc->png_ptr) - const unsigned int to_bit_depth = tr->to_bit_depth; - const png_uint_32 numerator = ((1U<bit_depth; - - /* The data in the gamma transform is stored in the order of the channels in - * the input row, which is the PNG order. It may be reversed below. - */ - png_uint_32p channel_scale = tr->channel_scale; - png_uint_32 shifts = 0U; - unsigned int count = 0U; - unsigned int need_sBIT = 0U; - - if (tc->format & PNG_FORMAT_FLAG_COLOR) - { - const unsigned int sBIT = tc->sBIT_R; - - if (sBIT < from_bit_depth) - need_sBIT = 1U; - - debug(sBIT > 0U && sBIT <= from_bit_depth); - shifts |= (from_bit_depth - sBIT) << count; - count += 4U; - /* round the scale: */ - *channel_scale++ = (numerator + (1U<<(sBIT-1U))) / ((1U << sBIT)-1U); - } - - { - const unsigned int sBIT = tc->sBIT_G; - - if (sBIT < from_bit_depth) - need_sBIT = 1U; - - debug(sBIT > 0U && sBIT <= from_bit_depth); - shifts |= (from_bit_depth - sBIT) << count; - count += 4U; - *channel_scale++ = (numerator + (1U<<(sBIT-1U))) / ((1U << sBIT)-1U); - } - - if (tc->format & PNG_FORMAT_FLAG_COLOR) - { - const unsigned int sBIT = tc->sBIT_B; - - if (sBIT < from_bit_depth) - need_sBIT = 1U; - - debug(sBIT > 0U && sBIT <= from_bit_depth); - shifts |= (from_bit_depth - sBIT) << count; - count += 4U; - /* round the scale: */ - *channel_scale++ = (numerator + (1U<<(sBIT-1U))) / ((1U << sBIT)-1U); - } - - if (tc->format & PNG_FORMAT_FLAG_ALPHA) - { - const unsigned int sBIT = tc->sBIT_A; - - if (sBIT < from_bit_depth) - need_sBIT = 1U; - - debug(sBIT > 0U && sBIT <= from_bit_depth); - shifts |= (from_bit_depth - sBIT) << count; - count += 4U; - /* round the scale: */ - *channel_scale++ = (numerator + (1U<<(sBIT-1U))) / ((1U << sBIT)-1U); - } - - tr->shifts = shifts | (1U << count); - - return need_sBIT; -# undef png_ptr -} - -static void -reverse_gamma_sBIT(png_transform_gamma *tr) -{ - /* This is called for the 'down' gamma implementations, they read the shifts - * and the channel scales in reverse, so: - */ - png_uint_32 shifts = tr->shifts; - png_uint_32 scales[4U]; - unsigned int count = 0U; - - tr->shifts = 1U; - - while (shifts != 1U) - { - scales[3U-count] = tr->channel_scale[count]; - ++count; - tr->shifts <<= 4; - tr->shifts |= shifts & 0xFU; - shifts >>= 4; - } - - memcpy(tr->channel_scale, scales+(4U-count), count * sizeof (png_uint_32)); -} - -static void -png_do_gamma8_up(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_transform_gamma *tr = - png_transform_cast(png_transform_gamma, *transform); - const png_fixed_point correct = tr->correct; - const unsigned int bit_depth = tr->to_bit_depth; - const png_uint_32 shifts = tr->shifts; - - affirm(tc->bit_depth == 8U); - affirm(tr->shifts != 0U/*uninitialized*/); - debug((shifts & 0x8888U) == 0U); /* all shifts 7 or less */ - debug(!tr->encode_alpha && !tr->optimize_alpha); /* only set for 16 bits */ - - tc->sp = dp; - tc->bit_depth = bit_depth; - tc->gamma = tr->to_gamma; - - /* Handle the <8 bit output case differently because there can be no alpha - * channel. - */ - if (bit_depth < 8U) - { - const unsigned int shift = shifts & 0xFU; - unsigned int bits = 8U; - unsigned int ob = 0U; - - debug((shifts >> 4) == 1U && shift < 8U); - affirm(PNG_TC_CHANNELS(*tc) == 1); - - do - { - const unsigned int inb = png_gamma_nxmbit_correct( - *sp++ >> shift, correct, 8U-shift, bit_depth); - bits -= bit_depth; - ob = ob | (inb << bits); - if (bits == 0U) - bits = 8U, *dp++ = PNG_BYTE(ob), ob = 0U; - } - while (sp < ep); - - if (bits < 8U) - *dp++ = PNG_BYTE(ob); - } - - else /* 8-bit --> 8-bit */ - { - png_uint_32 alpha_scale; - const unsigned int channels = PNG_TC_CHANNELS(*tc); - unsigned int channel, alpha; - - debug(bit_depth == 8U && (shifts >> (4*channels)) == 1U); - - /* The alpha channel is always last, so if present checking against the - * top bits of 'channels' works because of the 1U shibboleth at the end. - */ - if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0) - alpha_scale = alpha = 0U; - - else - { - alpha = shifts >> (4U*(channels-1U)); - alpha_scale = tr->channel_scale[channels-1U]; - } - - channel = 1U; - - do - { - unsigned int inb = *sp++, shift; - - if (channel == 1U) - channel = shifts; - - shift = channel & 0xFU; - inb >>= shift; - - /* The alpha channel is not gamma encoded but it may need some - * appropriate scaling. - */ - if (channel == alpha) - inb = (inb * alpha_scale + 0x800000U) >> 24; - - else - inb = png_gamma_nxmbit_correct(inb, correct, 8U-shift, 8U); - - channel >>= 4; /* for the next channel, or the shibboleth */ - *dp++ = PNG_BYTE(inb); - } - while (sp < ep); - - debug(channel == 1U); - } -# undef png_ptr -} - -static void -png_do_gamma16_up(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 1U/*safety*/; - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_transform_gamma *tr = - png_transform_cast(png_transform_gamma, *transform); - const png_fixed_point correct = tr->correct; - const unsigned int bit_depth = tr->to_bit_depth; - const png_uint_32 shifts = tr->shifts; - - affirm(tc->bit_depth == 16U); - affirm(tr->shifts != 0U/*uninitialized*/); - debug(!tr->optimize_alpha); - - /* This is exactly the same as above but the input has 16 bits per component, - * not 8. - */ - tc->sp = dp; - tc->bit_depth = bit_depth; - tc->gamma = tr->to_gamma; - - /* Handle the <8 bit output case differently, the input cannot be color (at - * present) and, if there is an alpha channel, then it is for the - * low-bit-depth gray input case and we expect the alpha to be transparent. - */ - if (bit_depth < 8U) - { - const unsigned int shift = shifts & 0xFU; - unsigned int bits = 8U; - unsigned int ob = 0U; - - affirm((tc->format & PNG_FORMAT_FLAG_COLOR) == 0U); - - if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0U) - { - debug((shifts >> 4) == 1U && shift < 16U); - debug(!tr->encode_alpha && !tr->optimize_alpha); - - do - { - unsigned int inb = *sp++ << 8; /* high bits first */ - inb = png_gamma_nxmbit_correct( - (inb + *sp++) >> shift, correct, 16U-shift, bit_depth); - - bits -= bit_depth; - ob = ob | (inb << bits); - if (bits == 0U) - bits = 8U, *dp++ = PNG_BYTE(ob), ob = 0U; - } - while (sp < ep); - - UNTESTED - } - - else /* low bit GA intermediate format */ - { - debug((shifts >> 8) == 1U && shift < 16U); - debug(!tr->encode_alpha && !tr->optimize_alpha); - debug(tc->transparent_alpha); - - /* Gray is first then the alpha component, the alpha component is just - * mapped to 0 or 1. - */ - do - { - unsigned int gray = *sp++ << 8; /* high bits first */ - unsigned int alpha; - gray += *sp++; - - alpha = (*sp++ << 8); - alpha += *sp++; - - if (alpha == 0U) - gray = 0U; /* will be replaced later */ - - else - { - gray = png_gamma_nxmbit_correct(gray >> shift, correct, - 16U-shift, bit_depth); - debug(alpha == 65535U); - alpha = (1U << bit_depth)-1U; - } - - bits -= bit_depth; - ob = ob | (gray << bits); - bits -= bit_depth; - ob = ob | (alpha << bits); - - if (bits == 0U) - bits = 8U, *dp++ = PNG_BYTE(ob), ob = 0U; - } - while (sp < ep-2U); - } - - if (bits < 8U) - *dp++ = PNG_BYTE(ob); - - debug(sp == ep+1U); - } - - else - { - png_uint_32 alpha_scale; - const unsigned int channels = PNG_TC_CHANNELS(*tc); - unsigned int channel, alpha; - - debug((bit_depth == 8U || bit_depth == 16U) && - (shifts >> (4*channels)) == 1U); - - /* Note that 'encode_alpha' turns on gamma encoding of the alpha - * channel (and this is a really weird operation!) - */ - if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0 || tr->encode_alpha) - alpha_scale = alpha = 0U; - - else - { - alpha = shifts >> (4U*(channels-1U)); - alpha_scale = tr->channel_scale[channels-1U]; - } - - channel = 1U; - - if (bit_depth == 16U) - { - do - { - unsigned int inb = *sp++ << 8, shift; - inb += *sp++; - - if (channel == 1U) - channel = shifts; - - shift = channel & 0xFU; - inb >>= shift; - - /* The 16-16bit scaling factor equation may be off-by-1 but this - * hardly matters for alpha or for gamma operations. - */ - if (channel == alpha) - inb = (inb * alpha_scale + 0x8000U) >> 16; - - else - inb = png_gamma_nxmbit_correct(inb, correct, 16U-shift, 16U); - - channel >>= 4; /* for the next channel, or the shibboleth */ - *dp++ = PNG_BYTE(inb >> 8); - *dp++ = PNG_BYTE(inb); - } - while (sp < ep); - - debug(channel == 1U && sp == ep+1U); - } - - else /* bit_depth == 8U */ - { - do - { - unsigned int inb = *sp++ << 8, shift; - inb += *sp++; - - if (channel == 1U) - channel = shifts; - - shift = channel & 0xFU; - inb >>= shift; - - if (channel == alpha) - inb = (inb * alpha_scale + 0x800000U) >> 24; - - else - inb = png_gamma_nxmbit_correct(inb, correct, 16U-shift, 8U); - - channel >>= 4; /* for the next channel, or the shibboleth */ - *dp++ = PNG_BYTE(inb); - } - while (sp < ep); - - debug(channel == 1U && sp == ep+1U); - } - } -# undef png_ptr -} - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED -static void -png_do_gamma16_up_optimize(png_transformp *transform, png_transform_controlp tc) - /* As above, but the alpha channel is 'optimized' */ -{ -# define png_ptr (tc->png_ptr) - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_transform_gamma *tr = - png_transform_cast(png_transform_gamma, *transform); - const png_fixed_point correct = tr->correct; - - /* The input always as 16 bits, the output 8 or 16. There is always an alpha - * channel and it is converted to the 'optimized' form, where pixels with - * alpha not 0.0 or 1.0 are left in linear form (not gamma corrected.) Where - * bit depth convertion is required it is from 16-bits to 8-bits and the - * DIV257 macro can be used. - * - * The following affirms and NOT_REACHED cases are consequences of the way - * the background (compose) code works: - */ - affirm(tr->optimize_alpha && !tr->encode_alpha && tc->bit_depth == 16U); - - /* TODO: split this into separate functions */ - switch (tr->to_bit_depth) - { - case 8U: /* 16-bit --> 8-bit */ - tc->sp = dp; - tc->bit_depth = 8U; - tc->gamma = tr->to_gamma; - - switch (PNG_TC_CHANNELS(*tc)) - { - case 2:/* GA */ - debug(tr->shifts == 0x100U); - ep -= 3U; /*SAFETY*/ - - do - { - png_uint_32 alpha = PNG_DIV257((sp[2] << 8) + sp[3]); - - switch (alpha) - { - case 0U: - dp[1] = dp[0] = 0U; - break; - - default: /* optimized case: linear color data */ - dp[0] = png_check_byte(png_ptr, - PNG_DIV257((sp[0] << 8) + sp[1])); - dp[1] = PNG_BYTE(alpha); - break; - - case 255U: /* opaque pixels are encoded */ - dp[0] = PNG_BYTE(png_gamma_nxmbit_correct( - (sp[0] << 8) + sp[1], correct, 16U, 8U)); - dp[1] = 255U; - break; - } - - sp += 4U; - dp += 2U; - } - while (sp < ep); - - debug(sp == ep+3U); - break; - - case 4:/* RGBA */ - debug(tr->shifts == 0x10000U); - ep -= 7U; /*SAFETY*/ - - do - { - png_uint_32 alpha = PNG_DIV257((sp[6] << 8) + sp[7]); - - switch (alpha) - { - case 0U: - memset(dp, 0U, 4U); - break; - - default: /* optimized case: linear color data */ - dp[0] = PNG_BYTE(PNG_DIV257((sp[0] << 8) + sp[1])); - dp[1] = PNG_BYTE(PNG_DIV257((sp[2] << 8) + sp[3])); - dp[2] = PNG_BYTE(PNG_DIV257((sp[4] << 8) + sp[5])); - dp[3] = PNG_BYTE(alpha); - break; - - case 255U: /* opaque pixels are encoded */ - dp[0] = PNG_BYTE(png_gamma_nxmbit_correct( - (sp[0] << 8) + sp[1], correct, 16U, 8U)); - dp[1] = PNG_BYTE(png_gamma_nxmbit_correct( - (sp[2] << 8) + sp[3], correct, 16U, 8U)); - dp[2] = PNG_BYTE(png_gamma_nxmbit_correct( - (sp[4] << 8) + sp[5], correct, 16U, 8U)); - dp[3] = 255U; - break; - } - - sp += 8U; - dp += 4U; - } - while (sp < ep); - - debug(sp == ep+7U); - break; - - default: - NOT_REACHED; - break; - } - break; - - case 16: /* 16-bit to 16-bit */ - tc->sp = dp; - tc->bit_depth = 16U; - tc->gamma = tr->to_gamma; - - switch (PNG_TC_CHANNELS(*tc)) - { - case 2:/* GA */ - debug(tr->shifts == 0x100U); - ep -= 3U; /*SAFETY*/ - - do - { - unsigned int alpha = (sp[2] << 8) + sp[3]; - - switch (alpha) - { - case 0U: - memset(dp, 0U, 4U); - break; - - default: /* optimized case: linear color data */ - if (dp != sp) - { - memcpy(dp, sp, 4U); - UNTESTED - } - break; - - case 65535U: /* opaque pixels are encoded */ - { - unsigned int gray = png_gamma_nxmbit_correct( - (sp[0] << 8) + sp[1], correct, 16U, 16U); - dp[0] = PNG_BYTE(gray >> 8); - dp[1] = PNG_BYTE(gray); - } - dp[3] = dp[2] = 255U; - break; - } - - sp += 4U; - dp += 4U; - } - while (sp < ep); - - debug(sp == ep+3U); - break; - - case 4:/* RGBA */ - debug(tr->shifts == 0x10000U); - ep -= 7U; /*SAFETY*/ - - do - { - unsigned int alpha = (sp[6] << 8) + sp[7]; - - switch (alpha) - { - case 0U: - memset(dp, 0U, 8U); - break; - - default: /* optimized case: linear color data */ - if (dp != sp) - { - memcpy(dp, sp, 8U); - UNTESTED - } - break; - - case 65535U: /* opaque pixels are encoded */ - { - unsigned int c = png_gamma_nxmbit_correct( - (sp[0] << 8) + sp[1], correct, 16U, 16U); - dp[0] = PNG_BYTE(c >> 8); - dp[1] = PNG_BYTE(c); - - c = png_gamma_nxmbit_correct( - (sp[2] << 8) + sp[3], correct, 16U, 16U); - dp[2] = PNG_BYTE(c >> 8); - dp[3] = PNG_BYTE(c); - - c = png_gamma_nxmbit_correct( - (sp[4] << 8) + sp[5], correct, 16U, 16U); - dp[4] = PNG_BYTE(c >> 8); - dp[5] = PNG_BYTE(c); - } - dp[7] = dp[6] = 255U; - break; - } - - sp += 8U; - dp += 8U; - } - while (sp < ep); - - debug(sp == ep+7U); - break; - - default: - NOT_REACHED; - break; - } - break; - - default: - NOT_REACHED; - break; - } -# undef png_ptr -} -#endif /* READ_ALPHA_MODE */ - -static void -png_do_scale16_up(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_transform_gamma *tr = - png_transform_cast(png_transform_gamma, *transform); - const unsigned int bit_depth = tr->to_bit_depth; - - affirm(tc->bit_depth == 16U && bit_depth < 8U); - affirm(tr->shifts != 0U/*uninitialized*/); - - /* This is exactly the same as above but without the gamma correction and - * without the 8-bit target support. The code handles one or two channels, - * but the result is not a PNG format unless the number of channels is just - * 1 (grayscale). - * - * For multi-channel low bit depth the channels are packed into bytes using - * the standard PNG big-endian packing. - */ - affirm((tc->format & PNG_FORMAT_FLAG_COLOR) == 0); - /* The alpha shift is actually ignored; at present we only get here with an - * alpha channel if it is to be removed for transparent alpha processing. - */ - debug(tc->format & PNG_FORMAT_FLAG_ALPHA ? - (tr->shifts >> 8) == 1U : (tr->shifts >> 4) == 1U); - debug(tc->transparent_alpha); - - tc->sp = dp; - /* This is a pure scaling operation so sBIT is not invalidated or altered. */ - tc->bit_depth = bit_depth; - - /* TODO: maybe do this properly and use the alpha shift, but only the top bit - * matters. - */ - { - const unsigned int shift = tr->shifts & 0xFU; - const png_uint_32 factor = tr->channel_scale[0]; - const png_uint_32 round = 1U << (31U-bit_depth); - unsigned int bits = 8U; - unsigned int ob = 0U; - - do - { - png_uint_32 inb = *sp++ << 8; /* high bits first */ - inb += *sp++; - - inb = ((inb >> shift) * factor + round) >> (32U-bit_depth); - bits -= bit_depth; - ob = ob | (inb << bits); - if (bits == 0U) - bits = 8U, *dp++ = PNG_BYTE(ob), ob = 0U; - } - while (sp < ep); - - if (bits < 8U) - *dp++ = PNG_BYTE(ob); - } -# undef png_ptr -} - -static void -png_do_gamma8_down(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_const_bytep ep = dp + 1U/*safety*/; - png_transform_gamma *tr = - png_transform_cast(png_transform_gamma, *transform); - const png_fixed_point correct = tr->correct; - const png_uint_32 shifts = tr->shifts; - - affirm(tc->bit_depth == 8U && tr->to_bit_depth == 16U); - affirm(tr->shifts != 0U/*uninitialized*/); - debug((shifts & 0x8888U) == 0U); /* all shifts 7 or less */ - debug(!tr->encode_alpha && !tr->optimize_alpha); /* only set for 16 bits */ - - sp += PNG_TC_ROWBYTES(*tc); - tc->sp = dp; - tc->bit_depth = tr->to_bit_depth; - tc->gamma = tr->to_gamma; - dp += PNG_TC_ROWBYTES(*tc); - - { - png_uint_32 alpha_scale; - unsigned int channel, alpha; - - debug((shifts >> (4*PNG_TC_CHANNELS(*tc))) == 1U); - - /* We are going down so alpha, if present, is first. Notice that the init - * routine has to reverse both 'shifts' and 'channel_scale' for the _down - * cases. - */ - if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0) - alpha_scale = alpha = 0U; - - else - { - alpha = shifts; - alpha_scale = tr->channel_scale[0U]; - } - - channel = 1U; - - do /* 8-bit --> 16-bit */ - { - unsigned int inb = *--sp, shift; - - if (channel == 1U) - channel = shifts; - - shift = channel & 0xFU; - inb >>= shift; - - if (channel == alpha) /* unencoded alpha, must scale */ - inb = (inb * alpha_scale + 0x8000U) >> 16; - - else - inb = png_gamma_nxmbit_correct(inb, correct, 8U-shift, 16U); - - channel >>= 4; - - *--dp = PNG_BYTE(inb); - *--dp = PNG_BYTE(inb >> 8); - } - while (dp > ep); - - debug(channel == 1U && dp == ep-1U); - } -# undef png_ptr -} - -static void -png_do_expand8_down(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_const_bytep ep = dp + 1U/*safety*/; - png_transform_gamma *tr = - png_transform_cast(png_transform_gamma, *transform); - const png_uint_32 shifts = tr->shifts; - - affirm(tc->bit_depth == 8U && tr->to_bit_depth == 16U); - affirm(tr->shifts != 0U/*uninitialized*/); - - sp += PNG_TC_ROWBYTES(*tc); - tc->sp = dp; - tc->bit_depth = 16U; - dp += PNG_TC_ROWBYTES(*tc); - - { - png_uint_32 channel = 1U; - png_const_uint_32p scale = 0U; - - do /* 8-bit -> 16-bit */ - { - unsigned int inb = *--sp, shift; - - if (channel == 1U) - channel = shifts, scale = tr->channel_scale; - - shift = channel & 0xFU; - channel >>= 4; - inb >>= shift; - inb = (inb * *scale++ + 0x8000U) >> 16; - /* dp starts beyond the end: */ - *--dp = PNG_BYTE(inb); - *--dp = PNG_BYTE(inb >> 8); - } - while (dp > ep); - - debug(channel == 1U && dp == ep-1U); - } -# undef png_ptr -} - -static void -png_do_expand8_down_fast(png_transformp *transform, png_transform_controlp tc) - /* Optimized version of the above for when the sBIT settings are all a full 8 - * bits (the normal case). - */ -{ -# define png_ptr (tc->png_ptr) - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_const_bytep ep = dp + 1U/*safety*/; - png_transform_gamma *tr = - png_transform_cast(png_transform_gamma, *transform); - - affirm(tc->bit_depth == 8U && tr->to_bit_depth == 16U); - affirm(tr->shifts != 0U/*uninitialized*/); - - sp += PNG_TC_ROWBYTES(*tc); - tc->sp = dp; - tc->bit_depth = 16U; - dp += PNG_TC_ROWBYTES(*tc); - - do - dp -= 2, dp[0] = dp[1] = *--sp; - while (dp > ep); - - debug(dp == ep-1U); -# undef png_ptr -} - -static void -png_init_gamma_uncached(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_transform_gamma *tr = - png_transform_cast(png_transform_gamma, *transform); - - debug(tc->init == PNG_TC_INIT_FINAL); - - /* Set this first; the result says if the sBIT data is significant, but it is - * ignored here. - */ - (void)init_gamma_sBIT(tr, tc); - - /* If png_set_alpha_mode is called but no background processing needs to be - * done (because there is no alpha channel or tRNS) we get to here with - * potentially spurious alpha mode flags. - */ - if (!(tc->format & PNG_FORMAT_FLAG_ALPHA)) - tr->encode_alpha = tr->optimize_alpha = 0U; - - /* Use separate functions for the two input depths but not for the five - * possible output depths and four channel counts. - */ - if (tc->bit_depth == 8U) - { - if (tr->to_bit_depth <= 8U) - tr->tr.fn = png_do_gamma8_up; - - else - { - debug(tr->to_bit_depth == 16U); - reverse_gamma_sBIT(tr); - tr->tr.fn = png_do_gamma8_down; - } - } - - else - { - affirm(tc->bit_depth == 16U); -# ifdef PNG_READ_ALPHA_MODE_SUPPORTED - if (!tr->optimize_alpha) - tr->tr.fn = png_do_gamma16_up; - else - tr->tr.fn = png_do_gamma16_up_optimize; -# else /* !READ_ALPHA_MODE */ - tr->tr.fn = png_do_gamma16_up; -# endif /* !READ_ALPHA_MODE */ - } - - /* Since the 'do' routines always perform gamma correction they will always - * expand the significant bits to the full output bit depth. - */ - tc->invalid_info |= PNG_INFO_sBIT; - tc->bit_depth = tr->to_bit_depth; - tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = - png_check_byte(png_ptr, tc->bit_depth); - if (tr->encode_alpha) - tc->sBIT_A = tc->sBIT_G; - tc->gamma = tr->to_gamma; -# undef png_ptr -} - -#ifdef PNG_READ_sBIT_SUPPORTED -static unsigned int -tc_sBIT(png_const_transform_controlp tc) - /* Determine the maximum number of significant bits in the row at this point. - * This uses the png_struct::sig_bit field if it has not been invalidated, - * otherwise it just returns the current bit depth. - */ -{ - const png_structrp png_ptr = tc->png_ptr; - unsigned int bit_depth = tc->bit_depth; - - if ((tc->invalid_info & PNG_INFO_sBIT) == 0U) - { - /* Normally the bit depth will not have been changed from the original PNG - * depth, but it currently is changed by the grayscale expand to 8 bits, - * an operation which doesn't invalidate sBIT. - */ - unsigned int sBIT; - - if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0U) - { - /* Must use the largest of the sBIT depths, except that unset values - * take priority. - */ - sBIT = png_ptr->sig_bit.red && png_ptr->sig_bit.green && - png_ptr->sig_bit.blue; - - if (sBIT != 0U) - { - sBIT = png_ptr->sig_bit.red; - - if (png_ptr->sig_bit.green > sBIT) - sBIT = png_ptr->sig_bit.green; - if (png_ptr->sig_bit.blue > sBIT) - sBIT = png_ptr->sig_bit.blue; - } - } - - else - sBIT = png_ptr->sig_bit.gray; - - if (sBIT > 0U && sBIT < bit_depth) - bit_depth = sBIT; - } - - return bit_depth; -} -#else /* !READ_sBIT */ -# define tc_sBIT(tc) ((tc)->bit_depth) -#endif /* READ_sBIT */ - -static void -png_init_gamma(png_transformp *transform, png_transform_controlp tc) -{ - const png_structrp png_ptr = tc->png_ptr; - png_transform_gamma *tr = - png_transform_cast(png_transform_gamma, *transform); - - if (tc->init == PNG_TC_INIT_FORMAT) - { - /* This should only happen for the final encode gamma transform, which - * never initializes the target bit depth (see png_set_gamma and - * png_set_alpha_mode). The affirm is required here; in we can't continue - * safely if the bit depth has been set somehow. - */ - debug(tr->tr.order == PNG_TR_GAMMA_ENCODE); - affirm(tr->to_gamma > 0 && tr->to_bit_depth == 0U); - - /* At this point the output gamma should not have been set yet: */ - debug(png_ptr->row_gamma == 0); - - /* The following must be true; png_set_gamma and png_set_alpha_mode set - * (or default) the PNG gamma and other routines that insert a gamma - * transform must only do in PNG_TC_INIT_FINAL: - */ - debug(tc->gamma > 0); - - /* At this point the data gamma must be updated so that we get the correct - * png_struct::row_gamma at the end of the init: - */ - tc->gamma = tr->to_gamma; - - /* For safety invalidate the sBIT information too; we don't know yet - * whether a gamma transform will be required but if it is the sBIT - * information becomes invalid. - */ - tc->invalid_info |= PNG_INFO_sBIT; - } - - else /* PNG_TC_INIT_FINAL */ - { - /* It is very bad if we get here when processing a row: */ - affirm(tc->init == PNG_TC_INIT_FINAL && png_ptr->row_bit_depth > 0); - - /* There are three cases: - * - * 1) Gamma correction is required, output bit depth may need to be - * defaulted. - * 2) Gamma correction is not required but a bit depth change is - * necessary. - * 3) Neither is required; the transform can be eliminated. - * - * First default the bit depth if it is not already set. Note that if the - * output is a palette then 'row_bit_depth' refers to the palette size and - * 8U must be used here. tc->palette is irrelevant; it only tells us that - * the data came from a palette. - */ - if (tr->to_bit_depth == 0) - { - if ((png_ptr->row_format & PNG_FORMAT_FLAG_COLORMAP) != 0U) - tr->to_bit_depth = 8U; - - else - tr->to_bit_depth = png_ptr->row_bit_depth; - } - - /* (1); is gamma correction required? If tc->gamma is 0 at this point it - * is not, but then the png_struct::row_gamma should be 0 too. - */ - implies(tc->gamma == 0, png_ptr->row_gamma == 0); - implies(tr->to_gamma == 0, tc->gamma == 0); - - if (!png_gamma_equal(png_ptr, tc->gamma, tr->to_gamma, &tr->correct, - tc_sBIT(tc))) - { - /* First make sure the input doesn't have a tRNS chunk which needs to - * be expanded now; if it does push_gamma_expand will push an - * appropriate transform *before* this one and we need to return - * immediately (the caller will call back to this function). - */ - if (push_gamma_expand(transform, tc, 0/*need alpha*/)) - { - affirm(tc->bit_depth >= 8U && - (tc->invalid_info & PNG_INFO_tRNS) != 0U && - *transform != &tr->tr); - return; - } - - debug(*transform == &tr->tr && tc->bit_depth >= 8U); - - /* The format is now 8 or 16-bit G, GA, RGB or RGBA and gamma - * correction is required. - */ - png_init_gamma_uncached(transform, tc); - /* TODO: implement caching for the !tc->caching cases! */ - return; - } - - /* The cases where the two gamma values are close enough to be considered - * equal. The code lies about the gamma; this prevents apps and the - * simplified API getting into loops or bad conditions because the gamma - * was not set to the expected value. - * - * Note that png_transform_control::gamma is only set here if both the - * input and output gamma values are known, otherwise the transform - * introduces a spurious know gamma value. - */ - if (tr->to_gamma > 0 && tc->gamma > 0) - tc->gamma = tr->to_gamma; - - if (tr->to_bit_depth > tc->bit_depth) - { - /* This is either the to-linear operation, in which case the expected - * bit depth is 16U, or it is the final encode in the case where an - * 'expand' operation was also specified. - * - * We don't care about the PNG_TR_GAMMA_ENCODE case because we know - * that there has to be an expand operation further down the pipeline. - */ - if (tr->tr.order < PNG_TR_GAMMA_ENCODE) - { - affirm(tr->to_bit_depth == 16U); - - if (push_gamma_expand(transform, tc, 0/*need alpha*/)) - { - affirm(tc->bit_depth == 8U && - (tc->invalid_info & PNG_INFO_tRNS) != 0U && - *transform != &tr->tr); - return; - } - - debug(*transform == &tr->tr); - affirm(tc->bit_depth == 8U); /* if 16U we would not be here! */ - - /* not using byte_ops here, but if there is no sBIT required - * (normally the case) the fast code can be used: - */ - if (init_gamma_sBIT(tr, tc)) - tr->tr.fn = png_do_expand8_down; - - else - tr->tr.fn = png_do_expand8_down_fast; - - tc->bit_depth = 16U; - } - - else /* PNG_TR_GAMMA_ENCODE: nothing need be done */ - tr->tr.fn = NULL; - } - - else if (tr->to_bit_depth < tc->bit_depth) - { - /* No gamma correction but bit depth *reduction* is required. Expect - * the 'from' bit depth to always be 16, otherwise this transform - * should not have been pushed. Also expect this to be the gamma - * 'encode' operation at the end of the arithmetic. - */ - affirm(tc->bit_depth == 16U && tr->tr.order == PNG_TR_GAMMA_ENCODE); - - /* If the target bit depth is 8-bit delay the operation and use the - * standard 16-8-bit scale code. For low bit depth do it now. - */ - if (tr->to_bit_depth == 8U) - { - png_set_scale_16(png_ptr); - tr->tr.fn = NULL; - } - - else /* low bit depth */ - { - (void)init_gamma_sBIT(tr, tc); - tr->tr.fn = png_do_scale16_up; - tc->bit_depth = tr->to_bit_depth; - } - } - - else /* gamma !significant and nothing to do */ - tr->tr.fn = NULL; - } -} - -#if !PNG_RELEASE_BUILD -int /* PRIVATE(debug only) */ -png_gamma_check(png_const_structrp png_ptr, png_const_transform_controlp tc) - /* Debugging only routine to repeat the test used above to determine if the - * gamma was insignificant. - * - * NOTE: JB20160723: This may still be incorrect in a complicated transform - * pipeline because it uses 'tc_sBIT' for the end of the pipeline whereas the - * init above happens earlier. I don't think this matters because the test - * is only invoked if the gamma transform is eliminated or if there is a bug - * and in the former case the sBIT values should remain unchanged. - */ -{ - png_fixed_point dummy; - - return png_gamma_equal(png_ptr, png_ptr->row_gamma, tc->gamma, &dummy, - tc_sBIT(tc)); -} -#endif /* !RELEASE_BUILD */ - -static png_fixed_point -translate_gamma_flags(png_const_structrp png_ptr, png_fixed_point gamma, - int is_screen) - /* If 'is_screen' is set this returns the inverse of the supplied value; i.e. - * this routine always returns an encoding value. - */ -{ - /* Check for flag values. The main reason for having the old Mac value as a - * flag is that it is pretty near impossible to work out what the correct - * value is from Apple documentation - a working Mac system is needed to - * discover the value! - */ - switch (gamma) - { - case PNG_DEFAULT_sRGB: - case PNG_GAMMA_sRGB: - case PNG_FP_1/PNG_GAMMA_sRGB: /* stupid case: -100000 */ - gamma = PNG_GAMMA_sRGB_INVERSE; - break; - - case PNG_GAMMA_MAC_18: - case PNG_FP_1/PNG_GAMMA_MAC_18: /* stupid case: -50000 */ - gamma = PNG_GAMMA_MAC_INVERSE; - break; - - default: - if (is_screen) - { - /* Check for a ridiculously low value; this will result in an - * overflow - * in the reciprocal calculation. - */ - if (gamma < 5) - { - png_app_error(png_ptr, "invalid screen gamma (too low)"); - gamma = 0; - } - - else if (gamma != PNG_FP_1) /* optimize linear */ - gamma = png_reciprocal(gamma); - } - - else if (gamma <= 0) - { - png_app_error(png_ptr, "invalid file gamma (too low)"); - gamma = 0; - } - break; - } - - return gamma; -} - -static png_transform_gamma * -add_gamma_transform(png_structrp png_ptr, unsigned int order, - png_fixed_point gamma, unsigned int bit_depth, int force) -{ - /* Add a png_transform_gamma transform at the given position; this is a - * utility which just adds the transform and (unconditionally) overwrites the - * to_gamma field. gamma must be valid. If 'force' is true the gamma value - * in an existing transform will be overwritten, otherwise this is just a - * default value. - */ - png_transform_gamma *tr = png_transform_cast(png_transform_gamma, - png_add_transform(png_ptr, sizeof (png_transform_gamma), png_init_gamma, - order)); - - if (force || tr->to_gamma == 0) - tr->to_gamma = gamma; - - tr->to_bit_depth = bit_depth; - - return tr; -} - -void PNGFAPI -png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma, - png_fixed_point file_gamma) -{ - png_debug(1, "in png_set_gamma_fixed"); - - /* Validate the passed in file gamma value: */ - file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/); - - /* The returned value may be 0, this results in a png_app_error above which - * may be ignored; if that happens simply ignore the setting. - */ - if (file_gamma > 0) - { - /* Set the colorspace gamma value unconditionally - this overrides the - * value in the PNG file if a gAMA chunk was present. png_set_alpha_mode - * provides a different, easier, way to default the file gamma. - */ - png_ptr->colorspace.gamma = file_gamma; - if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) - png_ptr->colorspace.flags = PNG_COLORSPACE_HAVE_GAMMA; - else - png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; - } - - /* Do the same thing with the screen gamma; check it and handle it if valid. - * This adds/sets the encoding of the final gamma transform in the chain. - * png_set_alpha_mode does the same thing. - */ - scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/); - - if (scrn_gamma > 0) - (void)add_gamma_transform(png_ptr, PNG_TR_GAMMA_ENCODE, scrn_gamma, - 0/*bit depth*/, 1/*force to_gamma to scrn_gamma*/); -} - -#ifdef PNG_FLOATING_POINT_SUPPORTED -static png_fixed_point -convert_gamma_value(png_structrp png_ptr, double output_gamma) -{ - /* The following silently ignores cases where fixed point (times 100,000) - * gamma values are passed to the floating point API. This is safe and it - * means the fixed point constants work just fine with the floating point - * API. The alternative would just lead to undetected errors and spurious - * bug reports. Negative values fail inside the _fixed API unless they - * correspond to the flag values. - */ - if (output_gamma < 0 || output_gamma > 128) - output_gamma *= .00001; - - return png_fixed(png_ptr, output_gamma, "gamma value"); -} - -void PNGAPI -png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma) -{ - png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma), - convert_gamma_value(png_ptr, file_gamma)); -} -#endif /* FLOATING_POINT */ -#endif /* READ_GAMMA */ - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -static void -png_do_rtog_48(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - const png_uint_32 r = (*transform)->args >> 16; - const png_uint_32 g = (*transform)->args & 0xFFFFU; - const png_uint_32 b = 65536U - r - g; - - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 6U; - png_bytep dp = png_voidcast(png_bytep, tc->dp); - - debug(tc->bit_depth == 16U && tc->format == PNG_FORMAT_FLAG_COLOR && - (tc->gamma == 0U || !png_gamma_significant(png_ptr, tc->gamma, 16U))); - - tc->sp = dp; - tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR); - - while (sp <= ep) - { - png_uint_32 gray = (((sp[0] << 8) + sp[1]) * r + - ((sp[2] << 8) + sp[3]) * g + - ((sp[4] << 8) + sp[5]) * b + 32767U) >> 16; - - debug(gray < 65536U); - *dp++ = PNG_BYTE(gray >> 8); - *dp++ = PNG_BYTE(gray); - sp += 6U; - } -# undef png_ptr -} - -static void -png_do_rtog_64(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - const png_uint_32 r = (*transform)->args >> 16; - const png_uint_32 g = (*transform)->args & 0xFFFFU; - const png_uint_32 b = 65536U - r - g; - - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 8U; - png_bytep dp = png_voidcast(png_bytep, tc->dp); - - debug(tc->bit_depth == 16U && - tc->format == PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_ALPHA && - (tc->gamma == 0U || !png_gamma_significant(png_ptr, tc->gamma, 16U))); - - tc->sp = dp; - tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR); - - while (sp <= ep) - { - png_uint_32 gray = (((sp[0] << 8) + sp[1]) * r + - ((sp[2] << 8) + sp[3]) * g + - ((sp[4] << 8) + sp[5]) * b + 32767U) >> 16; - - debug(gray < 65536U); - *dp++ = PNG_BYTE(gray >> 8); - *dp++ = PNG_BYTE(gray); - sp += 6U; - *dp++ = *sp++; /* alpha */ - *dp++ = *sp++; - } -# undef png_ptr -} - -static void -png_init_rgb_to_gray_arithmetic(png_transformp *transform, - png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - /* This only gets used in the final init stage: */ - debug(tc->init == PNG_TC_INIT_FINAL && tc->bit_depth == 16U && - (tc->format & PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA)) == - PNG_FORMAT_FLAG_COLOR); - - (*transform)->fn = (tc->format & PNG_FORMAT_FLAG_ALPHA) ? png_do_rtog_64 : - png_do_rtog_48; - - tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR); - tc->invalid_info |= PNG_INFO_sBIT; - tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A = - png_check_byte(png_ptr, tc->bit_depth); -# undef png_ptr -} - -typedef struct -{ - png_transform tr; - png_fixed_point red_coefficient; - png_fixed_point green_coefficient; - unsigned int coefficients_set :1; - unsigned int error_action :2; -} png_transform_rgb_to_gray; - -static void -png_update_rgb_status(png_structrp png_ptr, png_transformp *transform) -{ - png_transform_rgb_to_gray *tr = png_transform_cast(png_transform_rgb_to_gray, - *transform); - - png_ptr->rgb_to_gray_status = 1U; - tr->tr.fn = NULL; /* one warning/error only */ - - switch (tr->error_action) - { - case PNG_ERROR_ACTION_WARN: - png_warning(png_ptr, "RGB to gray found nongray pixel"); - break; - - case PNG_ERROR_ACTION_ERROR: - png_error(png_ptr, "RGB to gray found nongray pixel"); - break; - - default: - break; - } -} - -static void -png_do_rgb_check24(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - /* Sets 'rgb_to_gray' status if a pixel is found where the red green and blue - * channels are not equal. - */ - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 3U; - - debug(tc->bit_depth == 8U && tc->format == PNG_FORMAT_FLAG_COLOR); - - while (sp <= ep) - { - if ((sp[0] ^ sp[1]) | (sp[2] ^ sp[1])) - { - png_update_rgb_status(png_ptr, transform); - break; - } - - sp += 3U; - } -# undef png_ptr -} - -static void -png_do_rgb_check32(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - /* Sets 'rgb_to_gray' status if a pixel is found where the red green and blue - * channels are not equal and alpha is not zero. - */ - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 4U; - - debug(tc->bit_depth == 8U && - tc->format == PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_ALPHA); - - while (sp <= ep) - { - if (((sp[0] ^ sp[1]) | (sp[2] ^ sp[1])) && sp[3] != 0) - { - png_update_rgb_status(png_ptr, transform); - break; - } - - sp += 4U; - } -# undef png_ptr -} - -static void -png_do_rgb_check48(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - /* Sets 'rgb_to_gray' status if a pixel is found where the red green and blue - * channels are not equal. - */ - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 6U; - - debug(tc->bit_depth == 16U && tc->format == PNG_FORMAT_FLAG_COLOR); - - while (sp <= ep) - { - if ((sp[0] ^ sp[2]) | (sp[4] ^ sp[2]) | - (sp[1] ^ sp[3]) | (sp[5] ^ sp[3])) - { - png_update_rgb_status(png_ptr, transform); - break; - } - - sp += 6U; - } -# undef png_ptr -} - -static void -png_do_rgb_check64(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - /* Sets 'rgb_to_gray' status if a pixel is found where the red green and blue - * channels are not equal and alpha is not zero. - */ - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 8U; - - debug(tc->bit_depth == 16U && - tc->format == PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_ALPHA); - - while (sp <= ep) - { - if (((sp[0] ^ sp[2]) | (sp[4] ^ sp[2]) | - (sp[1] ^ sp[3]) | (sp[5] ^ sp[3])) && - (sp[6] | sp[7]) != 0) - { - png_update_rgb_status(png_ptr, transform); - break; - } - - sp += 8U; - } -# undef png_ptr -} - -static void -png_init_rgb_to_gray(png_transformp *transform, png_transform_controlp tc) -{ - png_structrp png_ptr = tc->png_ptr; - - /* Basic checks: if there is no color in the format this transform is not - * applicable. - */ - if ((tc->format & PNG_FORMAT_FLAG_COLOR) != 0) - { - png_transform_rgb_to_gray *tr = png_transform_cast( - png_transform_rgb_to_gray, *transform); - - /* no colormap allowed: */ - affirm(tc->init && !(tc->format & PNG_FORMAT_FLAG_COLORMAP)); - /* no extra flags yet: */ - debug(!(tc->format & - PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_ALPHA))); - /* at present no non-palette caching: */ - implies(tc->caching, tc->palette); - - if (tc->init == PNG_TC_INIT_FORMAT) - { - /* The convertion should just remove the 'COLOR' flag and do nothing - * else, but if a tRNS chunk is present this would invalidate it. - * Handle this by expanding it now. - */ - if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0 && !tc->palette && - png_ptr->num_trans == 1 && !(tc->invalid_info & PNG_INFO_tRNS)) - { - /* Only if expand was requested and not cancelled: */ - if (tc->expand_tRNS && !tc->strip_alpha) - tc->format |= PNG_FORMAT_FLAG_ALPHA; - - tc->invalid_info |= PNG_INFO_tRNS; /* prevent expansion later */ - } - - tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR); - } - - else /* PNG_TC_INIT_FINAL */ - { - unsigned int index; /* channel to select (invalid) */ - png_byte sBIT_color; /* sBIT of that channel if valid */ - png_fixed_point r, g; /* Coefficients in range 0..65536 */ - - /* Push a tRNS transform if required. Because this is a push the - * transform the init needs to be run now. This needs to go in - * before the check on r==g==b because a color key might be used. - */ - if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0 && !tc->palette && - png_ptr->num_trans == 1 && !(tc->invalid_info & PNG_INFO_tRNS)) - { - if (tc->expand_tRNS && !tc->strip_alpha) - { - png_transformp tr_expand = png_push_transform(png_ptr, - sizeof (png_expand), png_init_expand, transform, NULL); - - debug(*transform == tr_expand); - tr_expand->args |= PNG_EXPAND_tRNS; - png_init_expand(transform, tc); - /* Check for the infinite loop possibility: */ - affirm((tc->invalid_info & PNG_INFO_tRNS) != 0); - return; - } - - else - tc->invalid_info |= PNG_INFO_tRNS; - } - - { - png_fixed_point red, green; - - if (tr->coefficients_set) - { - red = tr->red_coefficient; - green = tr->green_coefficient; - } - -# ifdef PNG_COLORSPACE_SUPPORTED - else if ((png_ptr->colorspace.flags & - (PNG_COLORSPACE_HAVE_ENDPOINTS+PNG_COLORSPACE_INVALID)) - == PNG_COLORSPACE_HAVE_ENDPOINTS) - { - red = png_ptr->colorspace.end_points_XYZ.red_Y; - green = png_ptr->colorspace.end_points_XYZ.green_Y; - } -# endif - - else /* no colorspace support, assume sRGB */ - { - /* From IEC 61966-2-1:1999, the reverse transformation from sRGB - * RGB values to XYZ D65 values (not CIEXYZ!). These are not - * exact inverses of the forward transformation; they only have - * four (decimal) digits of precision. - * - * API CHANGE: in 1.7.0 the sRGB values from the official IEC - * specification are used, previously libpng used values from - * Charles Poynton's ColorFAQ of 1998-01-04. The original page - * is gone, however up to date information can be found below: - * - * http://www.poynton.com/ColorFAQ.html - * - * At the time of reading (20150628) this web site quotes the - * same values as below and cites ITU Rec 709 as the source. - */ - red = 21260; - green = 71520; - } - - /* Prior to 1.7 this calculation was done with 15-bit precision, - * this is because the code was written pre-muldiv and tried to - * work round the problems caused by the signs in integer - * calculations. - */ - (void)png_muldiv(&r, red, 65536, PNG_FP_1); - (void)png_muldiv(&g, green, 65536, PNG_FP_1); - } - - /* If the convertion can be deduced to select a single channel do so. - * If the error action is set to error just copy the red channel, if - * the coefficients select just one channel use that. - */ - if (tr->error_action == PNG_ERROR_ACTION_ERROR || r >= 65536) - index = 0U, sBIT_color = tc->sBIT_R; /* select red */ - - else if (g >= 65536) - index = 1U, sBIT_color = tc->sBIT_G; /* select green */ - - else if (r + g == 0) - index = 2U, sBIT_color = tc->sBIT_B; /* select blue */ - - else - index = 3U, sBIT_color = 0U/*UNUSED*/; - - if (index == 3U) - { - /* Arithmetic will have to be done. For this we need linear 16-bit - * data which must then be converted back to the required bit depth, - * png_init_gamma handles this. It may push other expand operations - * (it shouldn't but it can), so give it some space. - * - * The gamma must be restored to the original value, 0U for the bit - * depth means use the output bit depth. - */ - (void)add_gamma_transform(png_ptr, PNG_TR_GAMMA_ENCODE, tc->gamma, - 0U/*bit depth*/, 0/*default*/); - - /* If png_init_gamma is called with tc->gamma 0 it does the right - * thing in PNG_TC_INIT_FINAL; it just does any required bit depth - * adjustment. - */ - (void)add_gamma_transform(png_ptr, tr->tr.order + 0x10U, PNG_FP_1, - 16U, 1/*force: doesn't matter*/); - - { - /* This init routine will update the sBIT information - * appropriately. - */ - png_transformp tr_rtog = png_add_transform(png_ptr, 0/*size*/, - png_init_rgb_to_gray_arithmetic, tr->tr.order + 0x20U); - - /* r and g are known to be in the range 0..65535, so pack them - * into the 'args' argument of a new transform. - */ - tr_rtog->args = (((png_uint_32)r) << 16) + g; - } - } - - else /* index < 3 */ - { - /* TODO: does this need to select the correct sBIT value too? */ - png_add_rgb_to_gray_byte_ops(png_ptr, tc, index, - tr->tr.order + 0x10U); - tc->sBIT_G = sBIT_color; - } - - /* Prior to 1.7 libpng would always check for r!=g!=b. In 1.7 an extra - * error_action setting is added to prevent this overhead. - */ - if (tr->error_action) - tr->tr.fn = tc->bit_depth == 8 ? - ((tc->format & PNG_FORMAT_FLAG_ALPHA) ? - png_do_rgb_check32 : png_do_rgb_check24) : - ((tc->format & PNG_FORMAT_FLAG_ALPHA) ? - png_do_rgb_check64 : png_do_rgb_check48); - - else - tr->tr.fn = NULL; /* PNG_ERROR_ACTION_NO_CHECK */ - } - } - - else /* not color: transform not applicable */ - (*transform)->fn = NULL; -} - -void PNGFAPI -png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, - png_fixed_point red, png_fixed_point green) - /* API CHANGE: in 1.7 calling this on a palette PNG no longer causes the - * palette to be expanded (unless explicitly requested), rather it converts - * the palette to grayscale. - */ -{ - /* The coefficients must be reasonable, the error handling is to warn (pre - * 1.7) or app error (1.7) and drop back to the cHRM definition of Y. The - * drop back is done in the init routine if relevant flag is unset. Passing - * negative values causes this default to be used without a warning. - */ - int pset = 0; - - if (red >= 0 && green >= 0) - { - if (red <= PNG_FP_1 && green <= PNG_FP_1 && red + green <= PNG_FP_1) - pset = 1; - - else /* overflow */ - png_app_error(png_ptr, "rgb_to_gray coefficients too large (ignored)"); - } - - { - png_transform_rgb_to_gray *tr = - png_transform_cast(png_transform_rgb_to_gray, - png_add_transform(png_ptr, sizeof (png_transform_rgb_to_gray), - png_init_rgb_to_gray, PNG_TR_RGB_TO_GRAY)); - - tr->error_action = 0x3U & error_action; - - if (red < 0 || green < 0) /* use cHRM default */ - tr->coefficients_set = 0U; - - else if (pset) /* else bad coefficients which get ignored */ - { - tr->coefficients_set = 1U; - tr->red_coefficient = red; - tr->green_coefficient = green; - } - } -} - -#ifdef PNG_FLOATING_POINT_SUPPORTED -/* Convert a RGB image to a grayscale of the same width. This allows us, - * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. - */ - -void PNGAPI -png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red, - double green) -{ - png_set_rgb_to_gray_fixed(png_ptr, error_action, - png_fixed(png_ptr, red, "rgb to gray red coefficient"), - png_fixed(png_ptr, green, "rgb to gray green coefficient")); -} -#endif /* FLOATING POINT */ -#endif /* RGB_TO_GRAY */ - -#ifdef PNG_READ_BACKGROUND_SUPPORTED -typedef struct -{ - png_transform tr; - struct - { - png_color_16 background; - unsigned int need_expand :1; /* Background matches format of PNG */ - unsigned int rgb_to_gray :1; /* RGB-to-gray transform found */ - unsigned int compose_background :1; /* png_set_background */ - unsigned int associate_alpha :1; - unsigned int encode_alpha :1; - unsigned int optimize_alpha :1; - unsigned int background_is_gray :1; /* Background color is gray */ - unsigned int background_bit_depth :5; /* bit depth, 1..16 */ - unsigned int ntrans :3; /* 1..6 bytes */ - png_byte transparent_pixel[6]; - png_byte background_pixel[6]; - png_fixed_point background_gamma; - } st; /* to allow the whole state to be copied reliably */ -} png_transform_background; - -static void -resolve_background_color(png_transform_background *tr, - png_transform_controlp tc) -{ - png_const_structp png_ptr = tc->png_ptr; - - /* Deduce the bit depth and color information for the background, the - * special case is when need_expand is set and the PNG has palette format, - * then (and only then) the background value is a palette index. - */ - if (tr->st.need_expand && tc->palette) - { - unsigned int i = tr->st.background.index; - png_byte r, g, b; - - if (i >= png_ptr->num_palette) - { - png_app_error(png_ptr, "background index out of range"); - tr->tr.fn = NULL; - return; - } - - tr->st.background_bit_depth = 8U; - r = png_ptr->palette[i].red; - g = png_ptr->palette[i].green; - b = png_ptr->palette[i].blue; - - if (r == g && g == b) - { - tr->st.background_is_gray = 1U; - tr->st.background.gray = g; - UNTESTED - } - - else - { - tr->st.background_is_gray = 0U; - tr->st.background.red = r; - tr->st.background.green = g; - tr->st.background.blue = b; - UNTESTED - } - } - - else /* background is not a palette index */ - { - int use_rgb; - png_uint_16 mask; - - /* First work out the bit depth and whether or not to use the RGB - * fields of the background. - */ - if (tr->st.need_expand) - { - affirm(!(tc->format & PNG_FORMAT_FLAG_COLORMAP)); - tr->st.background_bit_depth = - png_check_bits(png_ptr, png_ptr->bit_depth, 5U); - use_rgb = (png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0; - } - - else /* screen format background */ - { - /* If the final output is in palette format assume the background - * is in a matching format. This covers two cases, an original - * COLORMAP PNG and png_set_quantize. - */ - if ((png_ptr->row_format & PNG_FORMAT_FLAG_COLORMAP) != 0) - tr->st.background_bit_depth = 8U; - - else - tr->st.background_bit_depth = - png_check_bits(png_ptr, png_ptr->row_bit_depth, 5U); - - use_rgb = (png_ptr->row_format & PNG_FORMAT_FLAG_COLOR) != 0; - } - - /* The PNG spec says to use the low bits of the values, so we mask out - * the high bits here (at present no warning is produced if they are - * set.) - */ - mask = png_check_u16(png_ptr, (1U << tr->st.background_bit_depth)-1U); - - if (use_rgb) - { - png_uint_16 r, g, b; - - r = tr->st.background.red & mask; - g = tr->st.background.green & mask; - b = tr->st.background.blue & mask; - - if (r == g && g == b) - { - tr->st.background_is_gray = 1U; - tr->st.background.gray = g; - } - - else - { - tr->st.background_is_gray = 0U; - tr->st.background.red = r; - tr->st.background.green = g; - tr->st.background.blue = b; - } - } - - else /* gray */ - { - tr->st.background_is_gray = 1U; - tr->st.background.gray = tr->st.background.gray & mask; - } - } -} - -static void -gamma_correct_background_component(png_const_structrp png_ptr, png_uint_16p cp, - unsigned int bdc, png_fixed_point correction, unsigned int bdout) - /* Utility function for gamma_correct_background. */ -{ - unsigned int c = *cp; - - /* 0.0 and 1.0 are unchanged (and common): */ - if (c > 0U && c < (1U<png_ptr) - png_fixed_point correction = tc->gamma; - const unsigned int bdback = tr->st.background_bit_depth; - const unsigned int bdrow = tc->bit_depth; - - /* This is harmless if it fails but it will damage the output pixels - they - * won't have the requested color depth accuracy where the background is - * used. - */ - debug(bdback <= bdrow); - debug(tr->st.background_is_gray || (bdrow >= 8U && bdback >= 8U)); - - /* The background is assumed to be full precision; there is no sBIT - * information for it. The convertion converts from the current depth and - * gamma of the background to that in the transform control. It uses the - * full 16-bit precision when considering the gamma values even though this - * is probably spurious. - */ - if (correction != 0 && (tr->st.background_gamma == 0 || - png_gamma_equal(png_ptr, tr->st.background_gamma, correction, - &correction, 16U))) - correction = 0; /* no correction! */ - - if (tr->st.background_is_gray) - gamma_correct_background_component(png_ptr, &tr->st.background.gray, - bdback, correction, bdrow); - - else - { - gamma_correct_background_component(png_ptr, &tr->st.background.red, - bdback, correction, bdrow); - gamma_correct_background_component(png_ptr, &tr->st.background.green, - bdback, correction, bdrow); - gamma_correct_background_component(png_ptr, &tr->st.background.blue, - bdback, correction, bdrow); - } - - /* Regardless of whether there was a correction set the background gamma: */ - tr->st.background_gamma = tc->gamma; - tr->st.background_bit_depth = png_check_bits(png_ptr, bdrow, 5U); -# undef png_ptr -} - -static void -fill_background_pixel(png_transform_background *tr, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - /* Fill in 'background_pixel' if the appropriate sequence of bytes for the - * format given in the transform control. - */ - unsigned int bdtc = tc->bit_depth; - - /* If necessary adjust the background pixel to the current row format (it is - * important to do this as late as possible to avoid spurious - * interconvertions). - */ - gamma_correct_background(tr, tc); - - if (tr->st.background_is_gray) - { - unsigned int g = tr->st.background.gray; - - /* 'g' now has enough bits for the destination, note that in the case of - * low bit depth gray this causes the pixel to be replicated through the - * written byte. Fill all six bytes with the replicated background: - */ - while (bdtc < 8U) - { - g &= (1U << bdtc) - 1U; /* use only the low bits */ - g |= g << bdtc; - bdtc <<= 1; - } - - memset(tr->st.background_pixel, PNG_BYTE(g), 6U); - if (bdtc == 16U) - tr->st.background_pixel[0] = tr->st.background_pixel[2] = - tr->st.background_pixel[4] = PNG_BYTE(g >> 8); - /* Must not include the alpha channel here: */ - tr->st.ntrans = png_check_bits(png_ptr, - ((tc->format & PNG_FORMAT_FLAG_COLOR)+1U) << (bdtc == 16U), 3U); - } - - else - { - unsigned int r = tr->st.background.red; - unsigned int g = tr->st.background.green; - unsigned int b = tr->st.background.blue; - - debug((tc->format & PNG_FORMAT_FLAG_COLOR) != 0); - - switch (bdtc) - { - case 8U: - tr->st.background_pixel[0] = PNG_BYTE(r); - tr->st.background_pixel[1] = PNG_BYTE(g); - tr->st.background_pixel[2] = PNG_BYTE(b); - tr->st.ntrans = 3U; - break; - - case 16U: - tr->st.background_pixel[0] = PNG_BYTE(r>>8); - tr->st.background_pixel[1] = PNG_BYTE(r); - tr->st.background_pixel[2] = PNG_BYTE(g>>8); - tr->st.background_pixel[3] = PNG_BYTE(g); - tr->st.background_pixel[4] = PNG_BYTE(b>>8); - tr->st.background_pixel[5] = PNG_BYTE(b); - tr->st.ntrans = 6U; - break; - - default: - NOT_REACHED; - } - } -# undef png_ptr -} - -/* Look for colors matching the trans_color in png_ptr and replace them. This - * must handle all the non-alpha formats. - */ -static void -png_do_replace_tRNS_multi(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_transform_background *tr = - png_transform_cast(png_transform_background, *transform); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - const unsigned int cbytes = tr->st.ntrans; - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - cbytes/*safety*/; - const int copy = dp != sp; - - /* We expect opaque and transparent pixels to be interleaved but with long - * sequences of each. - */ - debug(!(tc->format & PNG_FORMAT_FLAG_ALPHA) && - PNG_TC_PIXEL_DEPTH(*tc) == cbytes << 3); - tc->invalid_info |= PNG_INFO_tRNS; - tc->sp = dp; - - /* Look for pixels that match the transparent value, copying opaque ones as - * required. - */ - do - { - const png_const_bytep opaque_start = sp; - size_t cb; - - /* Find a transparent pixel, or the end: */ - do - { - if (memcmp(sp, tr->st.transparent_pixel, cbytes) == 0) /*transparent*/ - break; - sp += cbytes; - } - while (sp <= ep); - - cb = sp - opaque_start; - - /* Copy any opaque pixels: */ - if (cb > 0) - { - if (copy) - memcpy(dp, opaque_start, cb); - dp += cb; - } - - /* Set transparent pixels to the background (this has to be done one-by - * one; the case where all the bytes in the background are equal is not - * optimized.) - */ - if (sp <= ep) do - { - memcpy(dp, tr->st.background_pixel, cbytes); - sp += cbytes; - dp += cbytes; - } - while (sp <= ep && memcmp(sp, tr->st.transparent_pixel, cbytes) == 0); - } while (sp <= ep); - - debug(sp == ep+cbytes); -# undef png_ptr -} - -static void -png_do_replace_tRNS_8(png_transformp *transform, png_transform_controlp tc) - /* The single byte version: 8-bit gray */ -{ -# define png_ptr (tc->png_ptr) - png_transform_background *tr = - png_transform_cast(png_transform_background, *transform); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_alloc_size_t row_bytes = tc->width; - const int copy = dp != sp; - const int transparent_pixel = tr->st.transparent_pixel[0]; - const int background_pixel = tr->st.background_pixel[0]; - - /* We expect opaque and transparent pixels to be interleaved but with long - * sequences of each. - */ - debug(!(tc->format & PNG_FORMAT_FLAG_ALPHA) && - PNG_TC_PIXEL_DEPTH(*tc) == 8 && tr->st.ntrans == 1); - tc->invalid_info |= PNG_INFO_tRNS; - tc->sp = dp; - - /* Now search for a byte that matches the transparent pixel. */ - do - { - const png_const_bytep tp = png_voidcast(png_const_bytep, - memchr(sp, transparent_pixel, row_bytes)); - png_alloc_size_t cb; - - if (tp == NULL) /* all remaining pixels are opaque */ - { - if (copy) - memcpy(dp, sp, row_bytes); - return; - } - - cb = tp - sp; - if (cb > 0) /* some opaque pixels found */ - { - if (copy) - memcpy(dp, sp, cb); - sp = tp; - dp += cb; - debug(row_bytes > cb); - row_bytes -= cb; - } - - /* Now count the transparent pixels, this could use strspn but for the - * moment does not. - */ - debug(row_bytes > 0); - ++sp; /* next to check, may be beyond the last */ - while (--row_bytes > 0 && *sp == transparent_pixel) ++sp; - - cb = sp - tp; - memset(dp, background_pixel, cb); - dp += cb; - } while (row_bytes > 0); - UNTESTED -# undef png_ptr -} - -static void -png_do_set_row(png_transformp *transform, png_transform_controlp tc) - /* This is a no-op transform that both invalidates INFO from args and sets - * the entire row to the byte given in the top bits. - */ -{ - png_bytep dp = png_voidcast(png_bytep, tc->dp); - - tc->sp = dp; - memset(dp, (*transform)->args >> 24, PNG_TC_ROWBYTES(*tc)); -} - -static void -png_do_replace_tRNS_lbd(png_transformp *transform, png_transform_controlp tc) -{ - /* This is the 2 or 4 bit depth grayscale case; the 1 bit case is handled by - * the two routines above and the 8-bit and 16-bit cases by the two before - * that. - * - * The transform contains pixel values that have been expanded to one byte, - * the code needs to match the tRNS pixel and substitute the background one - * in each byte. - */ -# define png_ptr (tc->png_ptr) - png_transform_background *tr = - png_transform_cast(png_transform_background, *transform); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc); - const unsigned int copy = sp != dp; - const png_byte transparent_pixel = tr->st.transparent_pixel[0]; - const png_byte background_pixel = tr->st.background_pixel[0]; - - /* We expect opaque and transparent pixels to be interleaved but with long - * sequences of each. - */ - debug(!(tc->format & PNG_FORMAT_FLAG_ALPHA) && - PNG_TC_PIXEL_DEPTH(*tc) < 8 && tr->st.ntrans == 1); - tc->sp = dp; - - /* Now search for a byte that contains the transparent pixel - * - * NOTE: this is the "strlen" algorithm, I first saw a variant implemented in - * Acorn RISC iX (strlen) around 1991, almost certainly derived from a - * suggestion by Alan Mycroft dating from April 27, 1987 (Mycroft was one of - * the authors of the 'Norcroft' compiler used for RISC iX, and well known to - * the RISC iX implementors.) See, e.g.: - * - * http://bits.stephan-brumme.com/null.html. - * - * The exact form used here is the one reported by Brumme; I haven't been - * able to find the original Mycroft posting, it was probably on comp.arch. - * - * The 4-bit and 2-bit versions (probably slower in the 4-bit case than the - * do-it-by-pixel version, but definately faster once 32-bit handling is - * implemented): - * - * 4 bit: (byte - 0x11) & ~byte & 0x88 - * 2 bit: (byte - 0x55) & ~byte & 0xcc - * - * The generalizations to 32 bits (8 and 16 pixels per step) should be - * obvious. - * - * This algorithm reads pixels within a byte beyond the end of the row and, - * potentially, changes the non-existent pixels. This is harmless and not - * a security risk. - */ - if (tc->bit_depth == 4U) - { - /* For the moment the algorithm isn't used; there are only two pixels in - * each byte so it is likely to be quicker to check as below: - */ - do - { - const png_byte b = *sp++; - const unsigned int m = b ^ transparent_pixel; - - if (m == 0U) /* both transparent */ - *dp = background_pixel; - - else if ((m & 0xF0U) == 0U) /* first transparent */ - *dp = PNG_BYTE((background_pixel & 0xF0U) | (b & 0x0FU)); - - else if ((m & 0x0FU) == 0U) /* second transparent */ - *dp = PNG_BYTE((background_pixel & 0x0FU) | (b & 0xF0U)); - - else if (copy) /* neither transparent */ - *dp = b; - - ++dp; - } while (sp < ep); - } - - else - { - affirm(tc->bit_depth == 2U); - - do - { - const png_byte b = *sp++; - const unsigned int m = b ^ transparent_pixel; - - if (m == 0U) /* transparent */ - *dp = background_pixel; - - else if (0xAAU & ((m - 0x55U) & ~m)) - { - /* One or more pixels transparent */ - const unsigned int mask = - (m & 0xC0U ? 0xC0U : 0U) | - (m & 0x30U ? 0x30U : 0U) | - (m & 0x0CU ? 0x0CU : 0U) | - (m & 0x03U ? 0x03U : 0U); - - *dp = PNG_BYTE((b & mask) | (background_pixel & ~mask)); - } - - else if (copy) /* no transparent pixels */ - *dp = b; - - ++dp; - } while (sp < ep); - } - -# undef png_ptr -} - -static void -png_do_background_with_transparent_GA8(png_transformp *transform, - png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_transform_background *tr = - png_transform_cast(png_transform_background, *transform); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 1U/*safety*/; - const png_byte background_pixel = tr->st.background_pixel[0]; - - /* Because this is an alpha format and we are removing the alpha channel we - * can copy up. - */ - debug(tc->bit_depth == 8U && tc->format == PNG_FORMAT_GA && - tr->st.ntrans == 1U); - tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA); - tc->sp = dp; - - /* Look for pixels that have alpha 0; all others should have alpha 1.0, - * however they are simply treated as opaque regardless. - */ - do - { - *dp++ = (sp[1] == 0U) ? background_pixel : sp[0]; - sp += 2U; - } while (sp < ep); - - debug(sp == ep+1U); -# undef png_ptr -} - -static void -png_do_background_with_transparent_GA16(png_transformp *transform, - png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_transform_background *tr = - png_transform_cast(png_transform_background, *transform); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 3U/*safety*/; - - debug(tc->bit_depth == 16U && tc->format == PNG_FORMAT_GA && - tr->st.ntrans == 2U); - tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA); - tc->sp = dp; - - do - { - if (sp[2] == 0U && sp[3] == 0U) /* transparent */ - dp[0] = tr->st.background_pixel[0], dp[1] = tr->st.background_pixel[1]; - - else - dp[0] = sp[0], dp[1] = sp[1]; - - dp += 2U; - sp += 4U; - } while (sp < ep); - - debug(sp == ep+3U); -# undef png_ptr -} - -static void -png_do_background_with_transparent_GAlbd(png_transformp *transform, - png_transform_controlp tc) - /* This is the low-bit-depth gray case, the input is 1, 2 or 4-bit per - * channel gray-alpha. - */ -{ -# define png_ptr (tc->png_ptr) - png_transform_background *tr = - png_transform_cast(png_transform_background, *transform); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc); - const unsigned int bit_depth = tc->bit_depth; - const unsigned int mask = (1U << bit_depth) - 1U; - const unsigned int back = tr->st.background_pixel[0] & mask; - unsigned int opos, ob, inb; - - debug(bit_depth < 8U && tc->format == PNG_FORMAT_GA && tr->st.ntrans == 1U); - tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA); - tc->sp = dp; - - ob = 0U; /* output byte */ - opos = 0U; /* bit index of previous output pixel (counts down) */ - inb = 0U; /* quiet a GCC 4.8.5 warning */ - - for (;;) - { - /* The output is half the size of the input, so we need a new input byte - * for every 4 bits of output: - */ - if (opos == 0U || opos == 4U) - { - if (sp >= ep) - break; - - inb = *sp++; - } - - /* Move to the next *output* pixel, this wraps when bits is 0U: */ - opos = (opos - bit_depth) & 0x7U; - - /* Extract the whole input pixel to the low bits of a temporary: */ - { - unsigned int pixel = inb >> ((opos*2U) & 0x7U); - - /* The alpha channel is second, check for a value of 0: */ - if ((pixel & mask)/* A component*/ == 0U) - pixel = back; - - else - { - debug((pixel & mask) == mask); - pixel = (pixel >> bit_depth) & mask; /* G component */ - } - - ob |= pixel << opos; - } - - if (opos == 0U) - *dp++ = PNG_BYTE(ob), ob = 0U; - } - - if (opos != 0U) - *dp++ = PNG_BYTE(ob); - - debug(sp == ep); -# undef png_ptr -} - -static void -png_do_background_with_transparent_RGBA8(png_transformp *transform, - png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_transform_background *tr = - png_transform_cast(png_transform_background, *transform); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 3U/*safety*/; - - debug(tc->bit_depth == 8U && tc->format == PNG_FORMAT_RGBA && - tr->st.ntrans == 3U); - tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA); - tc->sp = dp; - - do - { - if (sp[3] == 0U) /* transparent */ - memcpy(dp, tr->st.background_pixel, 3U); - - else - memmove(dp, sp, 3U); - - dp += 3U; - sp += 4U; - } while (sp < ep); - - debug(sp == ep+3U); -# undef png_ptr -} - -static void -png_do_background_with_transparent_RGBA16(png_transformp *transform, - png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_transform_background *tr = - png_transform_cast(png_transform_background, *transform); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 7U/*safety*/; - - debug(tc->bit_depth == 16U && tc->format == PNG_FORMAT_RGBA && - tr->st.ntrans == 6U); - tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA); - tc->sp = dp; - - do - { - if (sp[6] == 0U && sp[7] == 0U) /* transparent */ - memcpy(dp, tr->st.background_pixel, 6U); - - else - memmove(dp, sp, 6U); - - dp += 6U; - sp += 8U; - } while (sp < ep); - - debug(sp == ep+7U); -# undef png_ptr -} - -static void -png_init_background_transparent(png_transformp *transform, - png_transform_controlp tc) - /* Select the correct version of the above routines. */ -{ -# define png_ptr (tc->png_ptr) - png_transform_background *tr = - png_transform_cast(png_transform_background, *transform); - - debug(tc->init == PNG_TC_INIT_FINAL /* never called in 'FORMAT' */ && - (tc->format & PNG_FORMAT_FLAG_ALPHA) != 0); - - /* Now we know the format on which processing will happen so it is possible - * to generate the correct fill pixel value to use. - */ - fill_background_pixel(tr, tc); - tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA); - tc->invalid_info |= PNG_INFO_sBIT; - tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A = - png_check_byte(png_ptr, tc->bit_depth); - - if (!(tc->format & PNG_FORMAT_FLAG_COLOR)) - { - if (tc->bit_depth == 8U) - tr->tr.fn = png_do_background_with_transparent_GA8; - - else if (tc->bit_depth == 16U) - tr->tr.fn = png_do_background_with_transparent_GA16; - - else /* low-bit-depth gray with alpha (not a PNG format!) */ - tr->tr.fn = png_do_background_with_transparent_GAlbd; - } - - else /* color */ - { - if (tc->bit_depth == 8U) - tr->tr.fn = png_do_background_with_transparent_RGBA8; - - else - { - debug(tc->bit_depth == 16U); - tr->tr.fn = png_do_background_with_transparent_RGBA16; - } - } -# undef png_ptr -} - -/* The calculated values below have the range 0..65535*65535, the output has the - * range 0..65535, so divide by 65535. Two approaches are given here, one - * modifies the value in place, the other uses a more complex expression. With - * gcc on an AMD64 system the in-place approach is very slightly faster. - * - * The two expressions are slightly different in what they calculate but both - * give the exact answer (verified by exhaustive testing.) - * - * The macro must be given a png_uint_32 variable (lvalue), normally an auto - * variable. - */ -#ifndef PNG_COMPOSE_DIV_65535 -# ifdef PNG_COMPOSE_DIV_EXPRESSION_SUPPORTED -# define PNG_COMPOSE_DIV_65535(v)\ - (v = ((v + (v>>16) + (v>>31) + 32768U) >> 16)) -# else -# define PNG_COMPOSE_DIV_65535(v)\ - (v += v >> 16, v += v >> 31, v += 32768U, v >>= 16) -# endif -#endif - -static void -png_do_background_alpha_GA(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_transform_background *tr = - png_transform_cast(png_transform_background, *transform); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 3U/*safety*/; - const unsigned int background = tr->st.background.gray; - const int copy = (sp != dp); - const int compose = tr->st.compose_background; - - affirm(tc->bit_depth == 16U && tc->format == PNG_FORMAT_GA && - tr->st.background_bit_depth == 16U); - - /* If gamma transforms are eliminated this might fail: */ - debug(tr->st.background_gamma == tc->gamma || - tr->st.background_gamma == 0 || - tc->sBIT_G == 1); - - tc->sp = tc->dp; /* nothing else changes */ - - do - { - const png_uint_32 alpha = (sp[2] << 8) + sp[3]; - - switch (alpha) - { - case 0U: /* transparent */ - memset(dp, 0U, 4U); - break; - - default: - { - png_uint_32 v = ((sp[0] << 8) + sp[1]) * alpha + - background * (65535U - alpha); - - PNG_COMPOSE_DIV_65535(v); - debug(v <= 65535U); - dp[0] = PNG_BYTE(v >> 8); - dp[1] = PNG_BYTE(v); - } - - if (compose) - dp[3] = dp[2] = 0xFFU; /* alpha; set to 1.0 */ - - else if (copy) - { - dp[2] = PNG_BYTE(alpha >> 8); - dp[3] = PNG_BYTE(alpha); - } - break; - - case 65535U: /* opaque */ - if (copy) - memcpy(dp, sp, 4U); - break; - } - - sp += 4U; - dp += 4U; - } - while (sp < ep); - - debug(sp == ep+3U); -# undef png_ptr -} - -static void -png_do_background_alpha_RGBA(png_transformp *transform, - png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_transform_background *tr = - png_transform_cast(png_transform_background, *transform); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 7U/*safety*/; - const unsigned int bred = tr->st.background.red; - const unsigned int bgreen = tr->st.background.green; - const unsigned int bblue = tr->st.background.blue; - const int copy = (sp != dp); - const int compose = tr->st.compose_background; - - affirm(tc->bit_depth == 16U && tc->format == PNG_FORMAT_RGBA && - tr->st.background_bit_depth == 16U); - - debug(tr->st.background_gamma == tc->gamma || - tr->st.background_gamma == 0 || - (tc->sBIT_R == 1 && tc->sBIT_G == 1 && tc->sBIT_B == 1)); - - tc->sp = tc->dp; /* nothing else changes */ - - do - { - const png_uint_32 alpha = (sp[6] << 8) + sp[7]; - - switch (alpha) - { - case 0U: /* transparent */ - memset(dp, 0U, 8U); - break; - - default: - { - const png_uint_32 balpha = (65535U - alpha); - png_uint_32 r = ((sp[0] << 8) + sp[1]) * alpha + bred * balpha; - png_uint_32 g = ((sp[2] << 8) + sp[3]) * alpha + bgreen * balpha; - png_uint_32 b = ((sp[4] << 8) + sp[5]) * alpha + bblue * balpha; - - PNG_COMPOSE_DIV_65535(r); - PNG_COMPOSE_DIV_65535(g); - PNG_COMPOSE_DIV_65535(b); - debug(r <= 65535U && g <= 65535U && b <= 65535U); - dp[0] = PNG_BYTE(r >> 8); - dp[1] = PNG_BYTE(r); - dp[2] = PNG_BYTE(g >> 8); - dp[3] = PNG_BYTE(g); - dp[4] = PNG_BYTE(b >> 8); - dp[5] = PNG_BYTE(b); - } - - if (compose) - dp[7] = dp[6] = 0xFFU; - - else if (copy) - { - dp[6] = PNG_BYTE(alpha >> 8); - dp[7] = PNG_BYTE(alpha); - } - break; - - case 65535U: /* opaque */ - if (copy) - memcpy(dp, sp, 8U); - break; - } - - sp += 8U; - dp += 8U; - } - while (sp < ep); - - debug(sp == ep+7U); -# undef png_ptr -} - -static void -png_init_background_alpha_end(png_transformp *transform, - png_transform_controlp tc) - /* This is just the last part of png_init_background_alpha (below) */ -{ -# define png_ptr (tc->png_ptr) - png_transform_background *tr = - png_transform_cast(png_transform_background, *transform); - - debug(tc->init == PNG_TC_INIT_FINAL); - - /* Repeat the tests at the end of png_init_background_alpha: */ - affirm(tc->bit_depth == 16U && (tc->format & PNG_FORMAT_FLAG_ALPHA) != 0); - debug(tc->gamma == 0 || - !png_gamma_significant(png_ptr, tc->gamma, tc_sBIT(tc))); - - /* tr->st.background_is_gray was filled in by resolve_background_color and - * records if either the background was a gray value or it was a color - * value with all the channels equal. - */ - if (!tr->st.background_is_gray && !(tc->format & PNG_FORMAT_FLAG_COLOR)) - { -# ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - /* Color background with gray data: this happens when there is a - * gray to RGB transform in the pipeline but it hasn't happened - * yet. Unfortunately it has to happen now to be able to do the - * compose against the colored background. - */ - png_push_gray_to_rgb_byte_ops(transform, tc); - affirm((tc->format & PNG_FORMAT_FLAG_COLOR) != 0); - return; -# else /* !GRAY_TO_RGB */ - impossible("gray to RGB"); /* how can this happen? */ -# endif /* !GRAY_TO_RGB */ - } - - /* The transform happens in two parts, a part to do the arithmetic on - * pixels where it is required followed by a part to replace transparent - * pixels. These two parts require different versions of the background - * pixel. Set up the second part first. - * - * This only happens with background composition, otherwise the - * transparent pixels are already 0 and nothing needs to be done. - */ - if (tr->st.compose_background) - { - /* The transparent pixel handling happens *after* the data has been - * re-encoded to the output gamma: - */ - png_transform_background *tr_alpha = - png_transform_cast(png_transform_background, - png_add_transform(png_ptr, sizeof (png_transform_background), - png_init_background_transparent, PNG_TR_GAMMA_ENCODE+0xF0U)); - - /* Copy the current state into the new png_transform_background: */ - tr_alpha->st = tr->st; - tr_alpha->tr.args = tr->tr.args; - } - - /* Now it is possible to overwrite tr->st.background with the linear version. - */ - gamma_correct_background(tr, tc); - - /* sBIT informationmust also be invalidated here, because a gamma - * transform may run before the transparent pixel handling. - */ - tc->invalid_info |= PNG_INFO_sBIT; - tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A = - png_check_byte(png_ptr, tc->bit_depth); - - /* And select an appropriate function; there are only two choices: */ - switch (tc->format) - { - case PNG_FORMAT_GA: - /* If the background format is color this indicates that there is a - * gray to RGB transform missing and we need it to happen before - * this point! - */ - affirm(tr->st.background_is_gray); - tr->tr.fn = png_do_background_alpha_GA; - break; - - case PNG_FORMAT_RGBA: - if (tr->st.background_is_gray) - tr->st.background.blue = tr->st.background.green = - tr->st.background.red = tr->st.background.gray; - tr->tr.fn = png_do_background_alpha_RGBA; - break; - - default: - NOT_REACHED; - } -# undef png_ptr -} - -static void -png_init_background_alpha(png_transformp *transform, png_transform_controlp tc) - /* This is used when alpha composition is required because the alpha channel - * may contain values that are between 0 and 1. Because doing alpha - * composition requires linear arithmetic the data is converted to 16-bit - * linear, however this means that the background pixel gets converted too - * and, for 16-bit output, this tends to smash the value. Consequently the - * algorithm used here is to skip those pixels and use the 'transparent - * alpha' routines to replace them after the gamma correction step. - */ -{ -# define png_ptr (tc->png_ptr) - png_transform_background *tr = - png_transform_cast(png_transform_background, *transform); - - debug(tc->init == PNG_TC_INIT_FINAL); - /* png_init_background ensures this is true: */ - debug((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0); - - /* Always push gamma transforms; don't try to optimize the case when they - * aren't needed because that would be an attempt to duplicate the tests in - * png_init_gamma and it might now work reliably. - * - * Need to push the to-linear transform *before* this transform and add gamma - * correction afterward to get back to the screen format. Do the afterward - * bit first to avoid complexity over *transform: - */ - { - png_transform_gamma *tr_end = add_gamma_transform(png_ptr, - PNG_TR_GAMMA_ENCODE, tc->gamma, 0U/*bit depth*/, 0/*default*/); - - /* Encoding the alpha channel happens in the last step, so this needs to - * be set here. Notice that in C++ terms we are very friendly with - * png_transform_gamma. - */ - tr_end->encode_alpha = tr->st.encode_alpha; - tr_end->optimize_alpha = tr->st.optimize_alpha; - } - - { - /* Now add tr_gamma before this transform, expect it to go in at - * *transform or the whole thing won't work: - */ - png_transform_gamma *tr_gamma = png_transform_cast(png_transform_gamma, - png_push_transform(png_ptr, sizeof (png_transform_gamma), - png_init_gamma, transform, NULL/*don't run init*/)); - - /* This must happen before we run png_gamma_init: */ - tr_gamma->to_gamma = PNG_FP_1; - tr_gamma->to_bit_depth = 16U; - - /* Now run the this transform; it was pushed before this one, so it gets - * to do its init first and this function must return as the caller will - * immediately call here again. - */ - debug(*transform == &tr_gamma->tr); - png_init_gamma(transform, tc); - affirm(tc->bit_depth == 16U && - (tc->format & PNG_FORMAT_FLAG_ALPHA) != 0); - /* This is only a 'debug' because it needs to replicate the test in - * png_init_gamma and that is easy to get wrong (a harmless mistake). - */ - debug(tc->gamma == 0 || - !png_gamma_significant(png_ptr, tc->gamma, tc_sBIT(tc))); - } - - /* A transform was pushed, so this transform init will be run again: */ - tr->tr.fn = png_init_background_alpha_end; -# undef png_ptr -} - -/* Handle alpha and tRNS via a background color */ -static void -png_init_background(png_transformp *transform, png_transform_controlp tc) -{ - /* This init function is called right at the start, this means it can get at - * the tRNS values if appropriate. If not the RGB to gray transform comes - * next followed by PNG_TR_COMPOSE_ALPHA, which actually does the non-tRNS - * work. - */ - png_structp png_ptr = tc->png_ptr; - png_transform_background *tr = - png_transform_cast(png_transform_background, *transform); - - if (tc->init == PNG_TC_INIT_FORMAT) - { - /* Background composition removes the alpha channel, so the other - * operations become irrelevant: - */ - if (tr->st.compose_background) - tr->st.associate_alpha = tr->st.encode_alpha = tr->st.optimize_alpha = - 0U; - - else if (!tr->st.associate_alpha) - { - /* There is nothing to do, delete the whole transform. */ - tr->tr.fn = NULL; - return; - } - - /* Else alpha association ('pre-multiplication') which is achieved by - * composing on a 0 background. The background color will be black (all - * zeros) and the background gamma will be zero. - */ - - /* Because we are in PNG_TC_INIT_FORMAT no other transforms will have been - * inserted between this one and an rgb-to-gray transform, so we can find - * out if rgb-to-gray has been requested: - */ - tr->st.rgb_to_gray = tr->tr.next != NULL && - tr->tr.next->order == PNG_TR_RGB_TO_GRAY; - - if ((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - /* Associated alpha does not strip the alpha channel! */ - if (tr->st.compose_background) - tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA); - } - - else if (!tc->palette && - png_ptr->num_trans == 1 && !(tc->invalid_info & PNG_INFO_tRNS)) - { - /* tRNS will be expanded, or handled */ - tc->invalid_info |= PNG_INFO_tRNS; - if (!tr->st.compose_background) - { - tc->format |= PNG_FORMAT_FLAG_ALPHA; - /* And in this case, only, because we are adding an alpha channel we - * need to have a channel depth of at least 8: - */ - if (tc->bit_depth < 8U) - tc->bit_depth = 8U; - } - } - - else /* no transparent pixels to change */ - tr->tr.fn = NULL; - } - - else /* PNG_TC_INIT_FINAL */ - { - png_fixed_point correction; - - debug(tc->init == PNG_TC_INIT_FINAL && - ((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0 || - (!tc->palette && png_ptr->num_trans == 1 && - !(tc->invalid_info & PNG_INFO_tRNS)))); - - /* The screen gamma is known, so the background gamma can be found, note - * that both the gamma values used below will be 0 if no gamma information - * was in the PNG and no gamma information has been provided by - * png_set_gamma or png_set_alpha_mode. - */ - switch (tr->st.background_gamma) - { - case PNG_BACKGROUND_GAMMA_FILE: - /* png_init_transform_control has already found the file gamma, - * and because this is the first arithmetic transformation - * nothing has changed it. - */ - tr->st.background_gamma = tc->gamma; - break; - - case PNG_BACKGROUND_GAMMA_SCREEN: - tr->st.background_gamma = png_ptr->row_gamma; - break; - - default: - /* already set */ - break; - } - - /* Work out what the background color is, this only depends on 'tc' for - * palette information, so it can be done now before we know the actual - * bit_depth/format that will be required: - */ - resolve_background_color(tr, tc); - - /* Is this format compatible with the current row data? If it is then it - * is possible to avoid the arithmetic if no alpha processing is required. - * This is a useful optimization because PNG files with just transparent - * pixels and no alpha are common. - * - * NOTE: if an RGB-to-gray transform is present this is fine so long as - * the background is gray, otherwise (non-gray background) there is a - * following gray-to-RGB transform and the now gray image must be - * composited on a color background. - */ - if (tr->st.compose_background /* alpha channel stripped */ && - (tr->st.background_is_gray || - ((tc->format & PNG_FORMAT_FLAG_COLOR) != 0 && !tr->st.rgb_to_gray)) - /* color compatible */ && - tc->bit_depth >= tr->st.background_bit_depth - /* bit depth compatible */ && - (tc->transparent_alpha || - (!tc->palette && png_ptr->num_trans == 1 && - !(tc->invalid_info & PNG_INFO_tRNS))) - /* no alpha processing */ && - png_gamma_equal(png_ptr, tc->gamma, png_ptr->row_gamma, &correction, - tc->bit_depth) /* gamma compatible (so no gamma processing) */) - { - /* How the operation gets performed depends on whether the current data - * has an alpha channel or not. - */ - if ((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - affirm(tc->transparent_alpha); - /* This init routine does the sBIT handling: */ - png_init_background_transparent(transform, tc); - } - - else if (!tc->palette && png_ptr->num_trans == 1 && - !(tc->invalid_info & PNG_INFO_tRNS)) - { - /* The background pixel needs to be filled in now; no more init - * routines are called in this case. It is important to delay this - * as late as possible because it needs to know the actual tc format - * that must be used. - */ - fill_background_pixel(tr, tc); - - debug(!(png_ptr->color_type & PNG_COLOR_MASK_PALETTE)); - - /* The pixel depth should not have been changed yet: */ - debug(PNG_PIXEL_DEPTH(*png_ptr) == PNG_TC_PIXEL_DEPTH(*tc)); - - /* The transparent_pixel value needs to be filled in. */ - affirm(tr->st.ntrans == - fill_transparent_pixel(png_ptr, tr->st.transparent_pixel)); - - /* The whole operation is a no-op if the transparent pixel and the - * background pixel match, even in the associated alpha case where - * both will be 0 throughout. - * - * NOTE: for palette images this test happens in the caching - * operation, so the answer is still correct. - * - * NOTE: for low bit depth gray both 'transparent_pixel' and - * 'background_pixel' have been expanded to fill a byte, so this - * works. - */ - if (memcmp(tr->st.transparent_pixel, tr->st.background_pixel, - tr->st.ntrans) == 0) - tr->tr.fn = NULL; - - /* Then the processing function depends on the pixel size: */ - else if (tr->st.ntrans > 1U) - tr->tr.fn = png_do_replace_tRNS_multi; - - else if (tc->bit_depth == 8U) - tr->tr.fn = png_do_replace_tRNS_8; - - else if (tc->bit_depth == 1U) - { - /* This is the silly case: the replacement pixel does not match - * the transparent pixel (handled above) so either all the '0' - * bits are replaced by '1' or all the '1' bits are replaced by - * '0': - */ - png_uint_32 args = tr->st.background_pixel[0]; - - args <<= 24; - args |= PNG_INFO_tRNS | PNG_INFO_sRGB; - tr->tr.args = args; - tr->tr.fn = png_do_set_row; - } - - else - tr->tr.fn = png_do_replace_tRNS_lbd; - - tc->invalid_info |= PNG_INFO_tRNS | PNG_INFO_sBIT; - tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A = - png_check_byte(png_ptr, tc->bit_depth); - } - - else - { - /* Nothing to do; should have been eliminated before! */ - tr->tr.fn = NULL; - NOT_REACHED; - } - } - - else /* alpha, or maybe gamma, processing required */ - { - /* Alpha case, add an appropriate transform; this has to be done - * *after* the RGB-to-gray case so move the transform info there: - */ - png_transform_background *tr_alpha = - png_transform_cast(png_transform_background, - png_add_transform(png_ptr, sizeof (png_transform_background), - png_init_background_alpha, PNG_TR_COMPOSE_ALPHA)); - - /* Copy the current state into the new png_transform_background: */ - tr_alpha->st = tr->st; - tr_alpha->tr.args = tr->tr.args; - - /* The rest of the init occurs later; this transform is no longer - * needed. - */ - tr->tr.fn = NULL; - - /* Ensure that png_init_background_alpha gets an alpha channel, this - * needs to happen here because otherwise intervening transforms can - * invalidate tRNS. - */ - tc->expand_tRNS = 1U; - if (tr->st.compose_background) - tc->strip_alpha = 0U; - - /* And push the expand: */ - (void)push_gamma_expand(transform, tc, 1/*need alpha*/); - - /* Regardless of whether anything got pushed the following should now - * be true: - */ - affirm((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0 && - tc->bit_depth >= 8U); - } - } -} - -void PNGFAPI -png_set_background_fixed(png_structrp png_ptr, - png_const_color_16p background_color, int background_gamma_code, - int need_expand, png_fixed_point background_gamma) -{ - if (png_ptr != NULL) - { - if (background_color != NULL) - { - png_transform_background *tr = - png_transform_cast(png_transform_background, - png_add_transform(png_ptr, sizeof (png_transform_background), - png_init_background, PNG_TR_COMPOSE)); - - /* This silently overwrites the information if png_set_background is - * called more than once. - */ - tr->st.background = *background_color; - tr->st.need_expand = need_expand != 0; - tr->st.compose_background = 1U; /* png_set_background called */ - switch (background_gamma_code) - { - case PNG_BACKGROUND_GAMMA_SCREEN: - case PNG_BACKGROUND_GAMMA_FILE: - tr->st.background_gamma = background_gamma_code; - break; - - case PNG_BACKGROUND_GAMMA_UNIQUE: - if (background_gamma >= 16 && background_gamma <= 625000000) - { - tr->st.background_gamma = background_gamma; - break; - } - - png_app_error(png_ptr, "gamma value out of range"); - /* FALL THROUGH */ - default: - png_app_error(png_ptr, "invalid gamma information"); - tr->st.background_gamma = (need_expand ? - PNG_BACKGROUND_GAMMA_FILE : PNG_BACKGROUND_GAMMA_SCREEN); - break; - } - } - - else - png_app_error(png_ptr, "missing background color"); - } -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_background(png_structrp png_ptr, - png_const_color_16p background_color, int background_gamma_code, - int need_expand, double background_gamma) -{ - png_set_background_fixed(png_ptr, background_color, background_gamma_code, - need_expand, png_fixed(png_ptr, background_gamma, "png_set_background")); -} -# endif /* FLOATING_POINT */ -#endif /* READ_BACKGROUND */ - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED -void PNGFAPI -png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, - png_fixed_point output_gamma) -{ - if (png_ptr != NULL) - { - /* Check the passed in output_gamma value; it must be valid and it must be - * converted to the reciprocal for use below: - */ - output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/); - - if (output_gamma > 0) /* Else an app_error has been signalled. */ - { - /* Only set the colorspace gamma if it has not already been set (this - * has the side effect that the gamma in a second call to - * png_set_alpha_mode will be ignored.) - */ - if ((png_ptr->colorspace.flags & - (PNG_COLORSPACE_INVALID | PNG_COLORSPACE_HAVE_GAMMA)) != - PNG_COLORSPACE_HAVE_GAMMA) - { - /* The default file gamma is the output gamma encoding: */ - png_ptr->colorspace.gamma = output_gamma; - if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) - png_ptr->colorspace.flags = PNG_COLORSPACE_HAVE_GAMMA; - else - png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; - } - - /* Always set the output gamma, note that it may be changed to PNG_FP_1 - * for the associated alpha support. This means that the last call to - * png_set_gamma[_fixed] or png_set_alpha_mode sets the output gamma, - * which is probably what is expected. - */ - { - png_transform_gamma *tr_gamma = add_gamma_transform(png_ptr, - PNG_TR_GAMMA_ENCODE, - mode == PNG_ALPHA_ASSOCIATED ? PNG_FP_1 : output_gamma, 0U, - 1/*force*/); - - /* Get a background transform and set the appropriate fields. - * - * png_set_background removes the alpha channel so it effectively - * disbles png_set_alpha_mode however png_set_alpha_mode is still - * useful to set a default gamma value. - */ - png_transform_background *tr = - png_transform_cast(png_transform_background, - png_add_transform(png_ptr, sizeof (png_transform_background), - png_init_background, PNG_TR_COMPOSE)); - - /* There are really 8 possibilities here, composed of any - * combination of: - * - * premultiply the color channels - * do not encode non-opaque pixels (leave as linear) - * encode the alpha as well as the color channels - * - * The differences disappear if the input/output ('screen') gamma is - * 1.0, because then the encoding is a no-op and there is only the - * choice of premultiplying the color channels or not. - */ - switch (mode) - { - case PNG_ALPHA_PNG: /* default: png standard */ - /* No compose, but it may be set by png_set_background! This - * is the only mode that doesn't interfere with what - * png_set_background does. - */ - tr->st.associate_alpha = 0U; - tr_gamma->encode_alpha = tr->st.encode_alpha = 0U; - tr_gamma->optimize_alpha = tr->st.optimize_alpha = 0U; - break; - - case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */ - tr->st.associate_alpha = 1U; - tr_gamma->encode_alpha = tr->st.encode_alpha = 0U; - tr_gamma->optimize_alpha = tr->st.optimize_alpha = 0U; - break; - - case PNG_ALPHA_OPTIMIZED: - /* associated with opaque pixels having the given gamma and - * non-opaque pixels being linear. - */ - tr->st.associate_alpha = 1U; - tr_gamma->encode_alpha = tr->st.encode_alpha = 0U; - tr_gamma->optimize_alpha = tr->st.optimize_alpha = 1U; - /* output_gamma records the encoding of opaque pixels! */ - break; - - case PNG_ALPHA_BROKEN: - /* associated+non-linear+alpha encoded */ - tr->st.associate_alpha = 1U; - tr_gamma->encode_alpha = tr->st.encode_alpha = 1U; - tr_gamma->optimize_alpha = tr->st.optimize_alpha = 0U; - break; - - default: - png_app_error(png_ptr, "invalid alpha mode"); - /* A return at this point is safe; if a background transform - * was created the init routine will remove it because - * nothing is set. - */ - break; - } /* alpha mode switch */ - } /* add gamma and background transforms */ - } /* valid output gamma */ - } /* png_ptr != NULL */ -} - -#ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma) -{ - png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr, - output_gamma)); -} -#endif /* FLOATING_POINT */ -#endif /* READ_ALPHA_MODE */ - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -typedef struct -{ - png_transform tr; - png_transform_control tc; - union - { - png_uint_32 u32[1]; /* ensure alignment */ - png_uint_16 u16[1]; - png_byte b8[1]; - } cache; -} png_transform_cache; - -#define png_transform_cache_size(size)\ - (offsetof(png_transform_cache, cache)+(size)) -#define png_transform_cache_cast(pointer,size)\ - png_voidcast(png_transform_cache*,\ - png_transform_cast_check(png_ptr, PNG_SRC_LINE, (pointer),\ - png_transform_cache_size(size))) - /* This is like png_transform_cast except that 'size' is the size of the - * cache part in the above structure and the type returned is always - * 'png_transform_cache*'. - */ - -/* Functions to handle the cache operation. These don't do any initialization; - * that happens below when PNG_TC_INIT_FINAL is being run on the whole list. - * These functions are only implemented for read so the transform control - * source and destination are always aligned. - * - * First some utility functions: - */ -static void -png_transform_control_cp(png_transform_controlp tcDest, - png_const_transform_controlp tcSrc) -{ - /* Copy tcSrc over tcDest without overwriting the information specific to the - * row being transformed. - */ - png_structp png_ptr = tcDest->png_ptr; - png_const_voidp sp = tcDest->sp; - png_voidp dp = tcDest->dp; - png_uint_32 width = tcDest->width; - unsigned int init = tcDest->init; - - *tcDest = *tcSrc; - - tcDest->png_ptr = png_ptr; - tcDest->sp = sp; - tcDest->dp = dp; - tcDest->width = width; - tcDest->init = png_check_bits(tcDest->png_ptr, init, 2); -} - -#if !PNG_RELEASE_BUILD -static int -png_transform_control_eq(png_const_transform_controlp tc1, - png_const_transform_controlp tc2) -{ - /* Say if *tc1 == *tc2, ignoring differences in uncopied fields and 'cost': - */ - return -# ifdef PNG_READ_GAMMA_SUPPORTED - tc1->gamma == tc2->gamma && -# endif - tc1->format == tc2->format && - tc1->range == tc2->range && - tc1->bit_depth == tc2->bit_depth && - tc1->caching == tc2->caching && - tc1->palette == tc2->palette; - /* invalid_info, cost, interchannel and channel_add are only set during - * init, so don't do the compare. - */ -} -#endif /* !RELEASE_BUILD */ - -/* Now the routines that actually perform the transform. There are two basic - * cases: - * - * 1) A cached transform that does not change the pixel size and where the pixel - * size 8 bits or less. This can be done by a 256-entry single byte lookup - * table, regardless of the bit depth. Two versions of the code exist, one - * which just transforms the row, the other which transforms and records the - * maximum pixel depth. - * - * 2) A cached transform that increases pixel depth. The destination pixel - * depth will always be a multiple of 8 bits, the source pixel will be less - * than or equal to 8 bits and will be in the PNG native (big endian) layout. - */ -#define png_ptr (tc->png_ptr) /* Used in all functions below */ -/* (1): single-byte cached transforms: */ -static void -do_transform_cache_byte(png_transformp *trIn, png_transform_controlp tc) -{ - png_transform_cache *tr = png_transform_cache_cast(*trIn, 256U); - - /* Copy the bytes through the 256-byte LUT: */ - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_const_bytep ep = dp + PNG_TC_ROWBYTES(*tc); - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - - tc->sp = dp; - - do - *dp++ = tr->cache.b8[*sp++]; - while (dp < ep); - - png_transform_control_cp(tc, &tr->tc); -} - -/* (2) A cached transform that increases pixel depth. - * - * There are six output depth possibilites, all a whole number of bytes: - * - * 1 byte, 8 bits: palette or grayscale - * 2 bytes, 16 bits: 16-bit grayscale or 8-bit gray+alpa - * 3 bytes, 24 bits: 8-bit RGB - * 4 bytes, 32 bits: 16-bit gray+alpha or 8-bit RGBA - * 6 bytes, 48 bits: 16-bit RGB - * 8 bytes, 64 bits: 16-bit RGBA - * - * The input must be 1, 2, 4 or 8-bit gray or palette. The first 1-byte case is - * handled for 8-bit gray/palette above, so there are 22 possibilities. The - * function names below are: - * - * do_transform_cache__ - */ -#define transform_cache_size(ipd,opd) ((((1U << (ipd)) * (opd))+7U) >> 3) -static void -do_transform_cache_(png_transformp *trIn, png_transform_controlp tc, - unsigned int ipd, unsigned int opd) - /* This is the implementation for unknown ipd, opd, below it is called with - * fixed values. The purpose of this is to allow the compiler/system builder - * to decide how to optimize for size vs space vs speed. Note that this - * implementation, while it would work for 8 bit ipd, is not used in that - * case. - */ -{ - png_transform_cache *tr = - png_transform_cache_cast(*trIn, transform_cache_size(ipd, opd)); - - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_const_bytep ep = dp; - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - unsigned int s, shift, mask; - - sp += PNG_TC_ROWBYTES(*tc); /* One byte beyond the end */ - - png_transform_control_cp(tc, &tr->tc); - dp += PNG_TC_ROWBYTES(*tc); - - shift = 7U & -(tc->width * ipd); - /* MSB: shift right required to get last pixel */ - mask = (1U << ipd) - 1U; - /* Mask to extract a single pixel from the low bits of a byte */ - opd >>= 3; - /* Output pixel size in bytes */ - s = *--sp; - /* The first byte; the last byte of the input row */ - - for (;;) - { - png_const_bytep opixel = (((s >> shift) & mask)+1U) * opd + tr->cache.b8; - /* Points to the byte after last byte of the output value */ - unsigned int i; - - for (i=0; isp); - tc->sp = ep; /* start of row, safe even if the above fails */ -} - -#define do_transform_cache(ipd,opd)\ -static void \ -do_transform_cache_##ipd##_##opd(png_transformp *tr, png_transform_controlp tc)\ -{\ - do_transform_cache_(tr, tc, ipd, opd);\ -} - -#define TCLOW(opd)\ -do_transform_cache(1,opd)\ -do_transform_cache(2,opd)\ -do_transform_cache(4,opd) - -TCLOW(8) -TCLOW(16) -TCLOW(24) -TCLOW(32) -TCLOW(48) -TCLOW(64) - -#undef TCLOW -#undef do_transform_cache - -static void -do_transform_cache_8_(png_transformp *trIn, png_transform_controlp tc, - unsigned int opd) - /* This is the 8-bit input implementation. */ -{ - png_transform_cache *tr = - png_transform_cache_cast(*trIn, transform_cache_size(8, opd)); - - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_const_bytep ep = dp; - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - - sp += PNG_TC_ROWBYTES(*tc); /* One byte beyond the end */ - - png_transform_control_cp(tc, &tr->tc); - dp += PNG_TC_ROWBYTES(*tc); - - opd >>= 3; /* Output pixel size in bytes */ - do - { - png_const_bytep opixel = (*--sp + 1U) * opd + tr->cache.b8; - /* Points to the byte after last byte of the output value */ - unsigned int i; - - for (i=0; i ep); - - debug(dp == ep && sp == tc->sp); - tc->sp = ep; /* start of row, safe even if the above fails */ -} - -#define do_transform_cache(opd)\ -static void \ -do_transform_cache_8_##opd(png_transformp *tr, png_transform_controlp tc)\ -{\ - do_transform_cache_8_(tr, tc, opd);\ -} - -/* The 8-bit to 8-bit case uses the byte transform code */ -do_transform_cache(16) -do_transform_cache(24) -do_transform_cache(32) -do_transform_cache(48) -do_transform_cache(64) - -#undef do_transform_cache - -#define do_transform_cache(ipd,opd) do_transform_cache_##ipd##_##opd - -#undef png_ptr - -typedef struct -{ - png_transformp *start; - /* This is a pointer to the pointer to the start of the list being cached, - * i.e. *start is the first transform in the list. - */ - png_transform_control tstart; - /* This is the transform control at the start; i.e. before (*start)->fn is - * called. Note that for palette data it will contain the original - * palette format/bit-depth, not that passed to (*start)->fn which will - * represent the palette. - */ - png_transformp *end; - png_transform_control tend; - /* The same data from the end of the run to be cached, i.e. after the - * function of the transform which *contains* '*end' (end points to - * tr->next). - */ -} png_cache_params, *png_cache_paramsp; - -static void -init_caching(png_structp png_ptr, png_transform_controlp tend) - /* Given an already initialized tend turn on caching if appropriate. */ -{ - /* Handle the colormap case, where a cache is always required: */ - if (tend->format & PNG_FORMAT_FLAG_COLORMAP) - { - /* This turns starts the palette caching with the next transform: */ - tend->palette = tend->caching = 1U; -# ifdef PNG_READ_tRNS_SUPPORTED - tend->transparent_alpha = png_ptr->transparent_palette; -# else /* !READ_tRNS */ - tend->transparent_alpha = 0; - PNG_UNUSED(png_ptr) -# endif /* !READ_tRNS */ - tend->format = PNG_FORMAT_FLAG_COLOR; -# ifdef PNG_READ_tRNS_SUPPORTED - if (png_ptr->num_trans > 0 && !(tend->invalid_info & PNG_INFO_tRNS)) - { - tend->format |= PNG_FORMAT_FLAG_ALPHA; - } -# endif /* READ_tRNS */ - tend->bit_depth = 8U; - } - - else if (PNG_TC_PIXEL_DEPTH(*tend) <= 8) - { - /* Cacheable pixel transforms; the pixel is less than 8 bits in size so - * the cache makes sense. - * - * TODO: check the cost estimate and the image size to avoid expensive - * caches of very small images. - */ - tend->caching = 1U; - } - - /* TODO: handle handle 8-bit GA/RGB/RGBA */ -} - -static void -add_cache_transform(png_structp png_ptr, unsigned int order, - png_transform_fn fn, png_cache_paramsp cp, - png_const_bytep cache, unsigned int size) - /* Add a transform from the input format cp->tstart to the output format - * stored in cp->tend. - */ -{ - affirm(size <= 2048U); /* 256 8-byte pixels at most */ - { - png_transform_cache *tr = png_transform_cache_cast( - png_add_transform(png_ptr, png_transform_cache_size(size), fn, order), - size); - - /* This must have replaced the transform in *cp->start: */ - affirm(&tr->tr == *cp->start); - - /* Fill in the respective members: */ - tr->tc = cp->tend; - memcpy(tr->cache.b8, cache, size); - - /* Skip this transform, because the calling routine has already executed - * the cache (it could be executed again, just to verify that it works; - * cp->tstart should be correct.) - */ - cp->start = &tr->tr.next; - } -} - -static unsigned int -setup_palette_cache(png_structp png_ptr, png_byte cache[8*256]) - /* This returns the number of entries in the cache; the width */ -{ - const unsigned int num_palette = png_ptr->num_palette; -# ifdef PNG_READ_tRNS_SUPPORTED - unsigned int num_trans = png_ptr->num_trans; -# endif /* READ_tRNS */ - const png_colorp palette = png_ptr->palette; - png_bytep p; - unsigned int i; -# ifdef PNG_READ_tRNS_SUPPORTED - const png_bytep trans_alpha = png_ptr->trans_alpha; -# endif /* READ_tRNS */ - - for (i=0, p=cache; i 0) - { - if (i < num_trans) - *p++ = trans_alpha[i]; - - else - *p++ = 0xFFU; - } -# endif /* READ_tRNS */ - } - - return num_palette; -} - -static void -png_remove_PLTE_and_tRNS(png_structrp png_ptr) -{ - if (png_ptr->palette != NULL) - png_free(png_ptr, png_ptr->palette); - - png_ptr->palette = NULL; - png_ptr->num_palette = 0; - -# ifdef PNG_READ_tRNS_SUPPORTED - if (png_ptr->trans_alpha != NULL) - png_free(png_ptr, png_ptr->trans_alpha); - - png_ptr->trans_alpha = NULL; - png_ptr->num_trans = 0; -# endif /* READ_tRNS */ - - png_ptr->palette_updated = 1U; -} - -static void -update_palette(png_structp png_ptr, png_cache_paramsp cp, - unsigned int max_depth) -{ - union - { - png_uint_32 u32[1]; - png_uint_16 u16[1]; /* For alignment */ - png_byte b8[8*256]; /* For 16-bit RGBA intermediate */ - } cache; - - /* The caller only calls this function if the initial transform control had - * the palette flag set, implying that the original 'format' was a COLORMAP - * one. Also this can only happen (at present) when starting the transform - * list, so: - */ - affirm((cp->tstart.format & PNG_FORMAT_FLAG_COLORMAP) != 0); /* required */ - - /* Run the whole of the given list on the palette data. PNG_TC_INIT_FINAL - * has already been run; this is a full run (with init == 0). - */ - { - unsigned int check_depth; - only_deb(png_transform_control orig = cp->tend;) - - cp->tend = cp->tstart; - init_caching(png_ptr, &cp->tend); - /* And set up tend to actually work out the palette: */ - cp->tend.init = 0U; - cp->tend.width = setup_palette_cache(png_ptr, cache.b8); - cp->tend.sp = cache.b8; - cp->tend.dp = cache.b8; - - check_depth = - png_run_this_transform_list_forwards(&cp->tend, cp->start, *cp->end); - - /* If we get here these two things must be true or there are been some - * buggy difference of opinion between the INIT code and the actual run: - */ - affirm(check_depth == max_depth && cp->tend.palette); - - /* This should match the passed in final format obtained before, this - * debug statement detects discrepancies between the init code and the - * run code: - */ - debug(png_transform_control_eq(&cp->tend, &orig)); - - /* Also, expect the palette to still be valid: */ - debug((cp->tend.invalid_info & PNG_INFO_PLTE) == 0); - } - - /* The result must be compatible with a PNG palette with respect to bit - * depth; specifically the expand-16 transform has no effect on palette data. - * - * The colormap setting must not have been re-introduced here either; there - * may be some quantize interactions here, neither can unexpected flags be - * handled; just COLOR and ALPHA. - */ - affirm(cp->tend.bit_depth == 8 && - (cp->tend.format & PNG_FORMAT_FLAG_COLORMAP) == 0); - - /* Remove all the transforms between start(inclusive) and end(exclusive); - * they have been processed. The effect they had on the transform control - * is irrelevant because the caller re-instates the settings from tstart. - */ - { - png_transformp list = *cp->start; /* list to free */ - - *cp->start = *cp->end; /* part of list not to be freed */ - *cp->end = NULL; /* terminate the list to be freed */ - cp->end = cp->start; /* else cp->end points to the end of the list! */ - - png_transform_free(png_ptr, &list); - } - - /* Adjust the PNG palette and, if required, the tRNS entries. Note that - * if the transforms stripped the alpha channel from the palette num_trans - * will get set to 0 here. - * - * This is the point where the gamma gets frozen too. The alternative - * design is to pass palette, tRNS and gamma up the transform chain, but - * that doesn't work because the palette change would, apparently, have to - * be repeated on each row. This seems simpler at the cost of a little - * obscurity; the answer to the question, "Where does the palette get - * updated?", is "Here!" - * - * API CHANGE: (fix): previously the init code would silently overwrite - * the palette information shared with png_info, breaking the API for - * png_read_update_info, which doesn't update the info if it isn't called, - * by changing the palette and maybe tRNS when the first row was read! - * - * NOTE: PNG_FORMAT_FLAG_RANGE is lost at this point, even if the palette - * entries were shifted or inverted. This could be fixed, but it would - * complicate the libpng API to expose the information. - */ - /* Write the transformed palette: */ - { - png_colorp palette = png_voidcast(png_colorp, png_calloc(png_ptr, - sizeof (png_color[PNG_MAX_PALETTE_LENGTH]))); - png_const_bytep p; - const int is_color = (cp->tend.format & PNG_FORMAT_FLAG_COLOR) != 0; - unsigned int i; -# ifdef PNG_READ_tRNS_SUPPORTED - unsigned int num_trans = 0; - const int do_trans = (cp->tend.format & PNG_FORMAT_FLAG_ALPHA) != 0; - png_byte trans_alpha[PNG_MAX_PALETTE_LENGTH]; -# endif /* READ_tRNS */ - - memset(palette, 0xFFU, sizeof (png_color[PNG_MAX_PALETTE_LENGTH])); - png_free(png_ptr, png_ptr->palette); - png_ptr->palette = palette; - - for (i=0, p=cache.b8; itend.width; ++i) - { - if (is_color) - { - palette[i].red = *p++; - palette[i].green = *p++; - palette[i].blue = *p++; - } - - else - palette[i].blue = palette[i].green = palette[i].red = *p++; - -# ifdef PNG_READ_tRNS_SUPPORTED - if (do_trans) - { - png_byte a = *p++; - trans_alpha[i] = a; - - /* Strip opaque entries from the end: */ - if (a < 0xFFU) - num_trans = i+1; - } -# endif /* READ_tRNS */ - } - - png_ptr->num_palette = png_check_bits(png_ptr, cp->tend.width, 9); - -# ifdef PNG_READ_tRNS_SUPPORTED - if (num_trans > 0) - { - png_bytep tRNS = png_voidcast(png_bytep, png_malloc(png_ptr, - PNG_MAX_PALETTE_LENGTH)); - - memset(tRNS, 0xFFU, PNG_MAX_PALETTE_LENGTH); - - if (png_ptr->trans_alpha != NULL) - png_free(png_ptr, png_ptr->trans_alpha); - - png_ptr->trans_alpha = tRNS; - - memcpy(tRNS, trans_alpha, num_trans); - png_ptr->num_trans = png_check_bits(png_ptr, num_trans, 9); - } -# endif /* READ_tRNS */ - } - - /* NOTE: the caller sets cp->start to cp->end and cp->tend to cp->tstart, - * this causes processing to continue with the palette format and the - * first unprocessed transform. The reset of the transform control loses the - * gamma information as well, of course, as any information about the palette - * and tRNS changes (such as the RANGE flags). - * - * The following ensures that png_read_update_info knows to update the - * palette in png_info (which is no longer shared). - */ - png_ptr->palette_updated = 1U; -} - -/* These structure and the save/restore routines that follow it exist to save - * data from a png_transform_control that is specific to the sample encoding of - * the PNG data, rather than the row format itself. - */ -typedef struct -{ -# ifdef PNG_READ_GAMMA_SUPPORTED - png_fixed_point gamma; -# endif - png_byte sBIT_R; - png_byte sBIT_G; - png_byte sBIT_B; - png_byte sBIT_A; /* Signnificant bits in the row channels. */ - unsigned int invalid_info; /* PNG_INFO_* for invalidated chunks */ -} png_tc_channel_data; - -static void -save_cp_channel_data(png_tc_channel_data *save, png_const_transform_controlp tc) -{ -# ifdef PNG_READ_GAMMA_SUPPORTED - save->gamma = tc->gamma; -# endif /* READ_GAMMA */ - - /* The sBIT information and the list of invalidated chunks must also be - * preserved: - */ - save->sBIT_R = tc->sBIT_R; - save->sBIT_G = tc->sBIT_G; - save->sBIT_B = tc->sBIT_B; - save->sBIT_A = tc->sBIT_A; - save->invalid_info = tc->invalid_info; -} - -static void -restore_cp_channel_data(png_transform_controlp tc, - const png_tc_channel_data *save) - /* Reverse the above */ -{ -# ifdef PNG_READ_GAMMA_SUPPORTED - tc->gamma = save->gamma; -# endif /* READ_GAMMA */ - - tc->sBIT_R = save->sBIT_R; - tc->sBIT_G = save->sBIT_G; - tc->sBIT_B = save->sBIT_B; - tc->sBIT_A = save->sBIT_A; - tc->invalid_info = save->invalid_info; -} - -static void -make_cache(png_structp png_ptr, png_cache_paramsp cp, unsigned int max_depth) -{ - /* At present the cache is just a byte lookup table. We need the original - * pixel depth to work out how big the working buffer needs to be. - */ - const unsigned int ipd = PNG_TC_PIXEL_DEPTH(cp->tstart); - const unsigned int opd = PNG_TC_PIXEL_DEPTH(cp->tend); - unsigned int order; /* records position of start transform */ - unsigned int width; /* width of cache in pixels */ - png_tc_channel_data save; /* Record of the final channel info */ - union - { - png_uint_32 u32[1]; - png_uint_16 u16[1]; /* For alignment */ - png_byte b8[8*256]; /* For 16-bit RGBA */ - } cache; - - debug(cp->tend.init == PNG_TC_INIT_FINAL); - affirm(opd <= 64 && max_depth <= 64); /* or the cache is not big enough */ - affirm(ipd == opd || (opd & 0x7U) == 0); - - if ((cp->tstart.format & PNG_FORMAT_FLAG_COLORMAP) != 0) - width = setup_palette_cache(png_ptr, cache.b8); - - else switch (ipd) - { - /* The input to the cache is the full range of possible pixel values: */ - case 1: - /* 2 1-bit pixels, MSB first */ - cache.b8[0] = 0x40U; - width = 2; - break; - - case 2: - /* 4 2-bit pixels, MSB first */ - cache.b8[0] = 0x1BU; - width = 4; - break; - - case 4: - /* 16 4-bit pixels, MSB first */ - cache.b8[0] = 0x01U; - cache.b8[1] = 0x23U; - cache.b8[2] = 0x45U; - cache.b8[3] = 0x67U; - cache.b8[4] = 0x89U; - cache.b8[5] = 0xABU; - cache.b8[6] = 0xCDU; - cache.b8[7] = 0xEFU; - width = 16; - break; - - case 8: - /* 256 8-bit pixels */ - { - unsigned int i; - - for (i=0; i<256; ++i) - cache.b8[i] = PNG_BYTE(i); - } - width = 256; - break; - - default: - impossible("cache input bit depth"); - } - - /* Reset the transform control to run the transforms on this data, but save - * the channel info because the row processing functions do not always - * write it. - */ - save_cp_channel_data(&save, &cp->tend); - cp->tend = cp->tstart; - init_caching(png_ptr, &cp->tend); - /* And set tend to work out the result of transforming each possible pixel - * value: - */ - cp->tend.init = 0U; - cp->tend.width = width; - cp->tend.sp = cache.b8; - cp->tend.dp = cache.b8; - - { - unsigned int check_depth = - png_run_this_transform_list_forwards(&cp->tend, cp->start, *cp->end); - - /* This must not change: */ - affirm(PNG_TC_PIXEL_DEPTH(cp->tend) == opd && check_depth == max_depth); - } - - /* Restore the potentially lost channel data. */ - restore_cp_channel_data(&cp->tend, &save); - - /* This is all the information required to cache the set of transforms - * between 'start' and 'end'. We take the transformed pixels and make a - * cache transform of them. The cache transform skips the work, transforms - * the row, and sets the tranform_control to (a copy of) cp->tend. - * - * Remove all the transforms between start(inclusive) and end(exclusive); - * they have been processed. The effect they had on the transform control - * is irrelevant because the caller re-instates the settings from tstart. - */ - { - png_transformp list = *cp->start; /* list to free */ - - *cp->start = *cp->end; /* part of list not to be freed */ - *cp->end = NULL; /* terminate the list to be freed */ - cp->end = NULL; /* reset below */ - - order = list->order; /* used below when adding the cache transform */ - png_transform_free(png_ptr, &list); - } - - /* Make the required cache, as enumerated above there are 22 possibilities, - * this selects between them, fixes up the cache for the 'byte' cases (where - * multiple pixels can be handled byte-by-byte) and selects the correct - * transform function. - */ - if (ipd == opd) - { - /* We already know that ipd is <= 8 bits, so we can expand this case to - * the byte transform. The complexity is that for ipd < 8 bits we only - * have information for individual pixel values and these may be - * pixel-swapped within the byte. - */ - if (ipd < 8) - { - const int lsb = (cp->tend.format & PNG_FORMAT_FLAG_SWAPPED) != 0; - unsigned int ishift, b; - png_byte bcache[256]; - - switch (ipd) - { - case 1: ishift = 3U; break; - case 2: ishift = 2U; break; - case 4: ishift = 1U; break; - default: impossible("ipd"); - } - - /* Work out the right answer for each byte of pixels: */ - for (b=0U; b<256U; ++b) - { - unsigned int o = 0U; /* output byte */ - unsigned int p = 8U; /* right shift to find input pixel */ - - do - { - unsigned int q = ((1U<> (p-=ipd)); - /* The input pixel. For a palette this value might be outside - * the range of palette indices, in which case simply insert - * '0': - */ - if (q < width) - { - unsigned int r = cache.b8[q >> ishift]; - r >>= ((lsb ? q : ~q) & ((1U<tend); - - affirm(cachebytes <= sizeof cache.b8); - - if (cachebytes < size) - memset(cache.b8+cachebytes, 0, size - cachebytes); - - add_cache_transform(png_ptr, order, fn, cp, cache.b8, size); - } - } - - /* Because a transform was inserted cp->end needs to be set to the new - * pointer to the original end. add_cache_transform sets cp->start to this, - * so: - */ - cp->end = cp->start; - - /* This invalidates the palette if that is what was cached because the - * palette and, if present, tRNS chunk did not get updated above. - */ - if (cp->tstart.palette) - png_remove_PLTE_and_tRNS(png_ptr); -} - -static void restore_cp(png_cache_paramsp cp) -{ - /* A utility to restore cp->tstart by copying it into cp->tend. This is used - * both in the palette case when restoring the transform control for the - * indexed data and in the case where no transforms were cached. It - * preserves the color-channel-specific data from cp->tend because in either - * case it is possible for this data to be modified without preserving any - * transforms, e.g. if only the gamma is changed but no gamma transform is - * retained because the change was not significant. - */ - png_tc_channel_data save; - - save_cp_channel_data(&save, &cp->tend); - cp->tend = cp->tstart; - restore_cp_channel_data(&cp->tend, &save); -} - -static void -handle_cache(png_structp png_ptr, png_cache_paramsp cp, unsigned int max_depth) -{ - /* There is nothing to do if there are no transforms between 'start' and - * 'end': - */ - if (cp->start != cp->end) - { - only_deb(png_transformp tr_check = *cp->end;) - - /* libpng doesn't currently implement any pixel size of more than 64 bits - * so: - */ - affirm(max_depth <= 64); - - if (cp->tend.palette) - { - /* The transforms being cached apply to the palette, the following - * transforms will apply to the original index data and the transformed - * data must be used to update the palette: - */ - if (cp->tend.init == PNG_TC_INIT_FINAL) - update_palette(png_ptr, cp, max_depth); - - cp->start = cp->end; - restore_cp(cp); /* reset to palette data */ - } - - else - { - /* Continue with the transform control in cp.tend; even if there was - * palette data in cp.tstart it has been expanded. - */ - if (cp->tend.init == PNG_TC_INIT_FINAL) - make_cache(png_ptr, cp, max_depth); - - cp->tstart = cp->tend; /* keep current context */ - } - - debug(tr_check == *cp->end); - } - - else /* no transforms cached */ - restore_cp(cp); /* removes any palette caching info */ -} - -#ifdef PNG_READ_tRNS_SUPPORTED -static void -check_tRNS_for_alpha(png_structrp png_ptr) -{ - unsigned int num_trans = png_ptr->num_trans; - - debug(png_ptr->color_type == PNG_COLOR_TYPE_PALETTE); - - while (num_trans > 0) - { - { - const png_byte trans = png_ptr->trans_alpha[--num_trans]; - - if (trans == 0xFFU) - continue; - - if (trans > 0U) - return; /* Palette has at least one entry >0, <0xff */ - } - - /* There is some point to the tRNS chunk; it has a non-opaque entry, this - * code could truncate it but there is no obvious performance advantage to - * doing this. - */ - while (num_trans > 0) - { - const png_byte trans = png_ptr->trans_alpha[--num_trans]; - - if (trans > 0U && trans < 0xFFU) - return; - } - - /* Here if the above did not find an entry >0 && <0xFFU but did find a - * transparent entry (0u). Record this. - */ - png_ptr->transparent_palette = 1U; - return; - } - - /* All entries opaque; remove the tRNS data: */ - // TODO: This optimization doesn't handle adding it back if RGBA is requested. - // See PPSSPP issue #14628. - //png_ptr->num_trans = 0U; -} -#endif /* READ_tRNS */ - -unsigned int /* PRIVATE */ -png_read_init_transform_mech(png_structp png_ptr, png_transform_controlp tc) - /* This is called once for each init stage (PNG_TC_INIT_FORMAT and - * PNG_TC_INIT_FINAL) to run the transform list forwards, returning the - * maximum depth required to process the row. It handles caching of the - * transforms and the processing of the palette for color-mapped PNG data. - */ -{ - png_transformp *list = &png_ptr->transform_list; - unsigned int max_depth, cache_start_depth; - png_cache_params cp; - - /* PNG color-mapped data must be handled here so that the palette is updated - * correctly. png_set_palette_to_rgb causes the palette flag to be removed - * from the transform control but does no other change. png_set_quantize - * causes 8-bit RGB, RGBA or palette data to be converted into palette - * indices, setting the palette flag. - */ -# ifdef PNG_READ_tRNS_SUPPORTED - /* This happens once at the start to find out if the tRNS chunk consisted - * entirely of opaque (255) and/or transparent (0) entries. - */ - if (tc->init == PNG_TC_INIT_FORMAT && - png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - check_tRNS_for_alpha(png_ptr); -# endif /* READ_tRNS */ - cp.end = cp.start = list; - cp.tend = cp.tstart = *tc; - max_depth = cache_start_depth = PNG_TC_PIXEL_DEPTH(cp.tend); - - while (*cp.end != NULL) - { - png_transformp tr = *cp.end; - - /* The user transform cannot be cached. */ - if (tr->order >= PNG_TR_USER) - break; - - /* If caching is not on and this transform is after PNG_TR_START_CACHE - * try to turn it on. - */ - if (tr->order > PNG_TR_START_CACHE && !cp.tend.caching) - { - cp.start = cp.end; - cp.tstart = cp.tend; - init_caching(png_ptr, &cp.tend); - - if (cp.tend.caching) - { - cache_start_depth = max_depth; - max_depth = PNG_TC_PIXEL_DEPTH(cp.tend); - } - } - - /* If the 'palette' flag is set and the next transform has order - * PNG_TR_ENCODING or later cache the results so far and continue with the - * original palette data (cp.tstart). - */ - if (cp.tend.palette && tr->order >= PNG_TR_ENCODING) - { - handle_cache(png_ptr, &cp, max_depth); - - /* The cache handling function must maintain cp.end; */ - affirm(tr == *cp.end); - max_depth = PNG_TC_PIXEL_DEPTH(cp.tend); - if (max_depth < cache_start_depth) - max_depth = cache_start_depth; - } - - /* Now run the transform list entry: */ - if (tr->fn != NULL) - { - tr->fn(cp.end, &cp.tend); - tr = *cp.end; /* in case something was inserted */ - } - - if (tr->fn == NULL) /* delete this transform */ - png_remove_transform(png_ptr, cp.end); - - else - { - /* Handle the initialization of the maximum pixel depth. */ - unsigned int tc_depth = PNG_TC_PIXEL_DEPTH(cp.tend); - - if (tc_depth > max_depth) - max_depth = tc_depth; - - /* Advance to the next transform. */ - cp.end = &tr->next; - } - } - - /* At the end if still caching record the cache information (this is common; - * this is generally the case for an expanded palette.) - */ - if (cp.tend.caching) - { - png_transformp tr = *cp.end; - handle_cache(png_ptr, &cp, max_depth); - affirm(tr == *cp.end); - max_depth = PNG_TC_PIXEL_DEPTH(cp.tend); - if (max_depth < cache_start_depth) - max_depth = cache_start_depth; - } - - /* At the end run the init on the user transform: */ - if (*cp.end != NULL) - { - png_transformp tr = *cp.end; - affirm(tr->order == PNG_TR_USER); - if (tr->fn != NULL) - tr->fn(cp.end, &cp.tend); - /* This cannot insert anything, so: */ - affirm(tr == *cp.end && tr->next == NULL); - - if (tr->fn == NULL) /* delete this transform */ - png_remove_transform(png_ptr, cp.end); - - else - { - unsigned int tc_depth = PNG_TC_PIXEL_DEPTH(cp.tend); - - if (tc_depth > max_depth) - max_depth = tc_depth; - } - } - - /* And write the input transform control: */ - *tc = cp.tend; - - return max_depth; -} - -/* Modify the info structure to reflect the transformations. The - * info should be updated so a PNG file could be written with it, - * assuming the transformations result in valid PNG data. - */ -void /* PRIVATE */ -png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr) -{ - png_debug(1, "in png_read_transform_info"); - - /* WARNING: this is very basic at present. It just updates the format - * information. It should update the palette (and will eventually) as well - * as invalidating chunks that the transforms break. - */ -# ifdef PNG_TRANSFORM_MECH_SUPPORTED - info_ptr->format = png_ptr->row_format; - info_ptr->bit_depth = png_ptr->row_bit_depth; -# ifdef PNG_READ_GAMMA_SUPPORTED - /* If an info struct is used with a different png_ptr in a call to - * png_set_gAMA then the png_struct information won't be updated, this - * doesn't matter on write, but don't zap the value in the info on read - * unless it is known: - * - * TODO: review this whole mess. - */ - if (png_ptr->row_gamma > 0) - info_ptr->colorspace.gamma = png_ptr->row_gamma; -# endif - - /* Invalidate chunks marked as invalid: */ -# ifdef PNG_READ_TRANSFORMS_SUPPORTED - info_ptr->valid &= ~png_ptr->invalid_info; - - /* If the palette or tRNS chunk was changed copy them over to the info - * structure; this may actually re-validate the PLTE or tRNS chunks, - * but only if png_ptr has a new version, otherwise the invalid_info - * settings from above can still invalidate the chunk. - */ - if (png_ptr->palette_updated) - { - if (png_ptr->num_palette > 0) - png_set_PLTE(png_ptr, info_ptr, png_ptr->palette, - png_ptr->num_palette); - - else - { - png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); - info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_PLTE); - } - -# ifdef PNG_READ_tRNS - /* If the output format is not a palette format the tRNS - * information was a single color which is now invalid - * (probably), otherwise the array of tRNS values must be - * updated. - */ - if ((info_ptr->format & PNG_FORMAT_FLAG_COLORMAP) != 0) - { - if (png_ptr->num_trans > 0) - png_set_tRNS(png_ptr, info_ptr, png_ptr->trans_alpha, - png_ptr->num_trans, NULL/*trans color*/); - - else - { - png_free_data(png_ptr, info_ptr, PNG_FREE_tRNS, 0); - info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_tRNS); - } - } - - else - info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_tRNS); -# endif /* READ_tRNS */ - } -# endif /* READ_TRANSFORMS */ -# else /* !TRANSFORM_MECH */ - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -# endif /* !TRANSFORM_MECH */ -} -#endif /* READ_TRANSFORMS */ diff --git a/ext/libpng17/pngrutil.c b/ext/libpng17/pngrutil.c deleted file mode 100644 index 5f94385545..0000000000 --- a/ext/libpng17/pngrutil.c +++ /dev/null @@ -1,4792 +0,0 @@ -#ifdef _MSC_VER -#pragma warning (disable:4018) -#pragma warning (disable:4146) -#endif - -/* pngrutil.c - utilities to read a PNG file - * - * Last changed in libpng 1.7.0 [(PENDING RELEASE)] - * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file contains routines that are only called from within - * libpng itself during the course of reading an image. - */ - -#include "pngpriv.h" -#define PNG_SRC_FILE PNG_SRC_FILE_pngrutil - -#ifdef PNG_READ_SUPPORTED - -#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED) -/* The following is a variation on the above for use with the fixed - * point values used for gAMA and cHRM. Instead of png_error it - * issues a warning and returns (-1) - an invalid value because both - * gAMA and cHRM use *unsigned* integers for fixed point values. - */ -#define PNG_FIXED_ERROR (-1) - -static png_fixed_point /* PRIVATE */ -png_get_fixed_point(png_structrp png_ptr, png_const_bytep buf) -{ - png_uint_32 uval = png_get_uint_32(buf); - - if (uval <= PNG_UINT_31_MAX) - return (png_fixed_point)uval; /* known to be in range */ - - /* The caller can turn off the warning by passing NULL. */ - if (png_ptr != NULL) - png_warning(png_ptr, "PNG fixed point integer out of range"); - - return PNG_FIXED_ERROR; -} -#endif /* READ_gAMA or READ_cHRM */ - -#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED -/* NOTE: the read macros will obscure these definitions, so that if - * PNG_USE_READ_MACROS is set the library will not use them internally, - * but the APIs will still be available externally. - * - * The parentheses around "PNGAPI function_name" in the following three - * functions are necessary because they allow the macros to co-exist with - * these (unused but exported) functions. - */ - -/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ -png_uint_32 (PNGAPI -png_get_uint_32)(png_const_bytep buf) -{ - return PNG_U32(buf[0], buf[1], buf[2], buf[3]); -} - -/* Grab a signed 32-bit integer from a buffer in big-endian format. The - * data is stored in the PNG file in two's complement format and there - * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore - * the following code does a two's complement to native conversion. - */ -png_int_32 (PNGAPI -png_get_int_32)(png_const_bytep buf) -{ - return PNG_S32(buf[0], buf[1], buf[2], buf[3]); -} - -/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ -png_uint_16 (PNGAPI -png_get_uint_16)(png_const_bytep buf) -{ - return PNG_U16(buf[0], buf[1]); -} -#endif /* READ_INT_FUNCTIONS */ - -/* This is an exported function however its error handling is too harsh for most - * internal use. For example if it were used for reading the chunk parameters - * it would error out even on ancillary chunks that can be ignored. - */ -png_uint_32 PNGAPI -png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf) -{ - png_uint_32 uval = png_get_uint_32(buf); - - if (uval > PNG_UINT_31_MAX) - png_error(png_ptr, "PNG unsigned integer out of range"); - - return uval; -} - -/* Read and check the PNG file signature */ -void /* PRIVATE */ -png_read_sig(png_structrp png_ptr, png_inforp info_ptr) -{ - png_size_t num_checked, num_to_check; - - /* Exit if the user application does not expect a signature. */ - if (png_ptr->sig_bytes >= 8) - return; - - num_checked = png_ptr->sig_bytes; - num_to_check = 8 - num_checked; - -#ifdef PNG_IO_STATE_SUPPORTED - png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE; -#endif - - /* The signature must be serialized in a single I/O call. */ - png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check); - png_ptr->sig_bytes = 8; - - if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) - { - if (num_checked < 4 && - png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) - png_error(png_ptr, "Not a PNG file"); - else - png_error(png_ptr, "PNG file corrupted by ASCII conversion"); - } - if (num_checked < 3) - png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; -} - -/* Read data, and (optionally) run it through the CRC. */ -void /* PRIVATE */ -png_crc_read(png_structrp png_ptr, png_voidp buf, png_uint_32 length) -{ - if (png_ptr == NULL) - return; - - png_read_data(png_ptr, buf, length); - png_calculate_crc(png_ptr, buf, length); -} - -/* Optionally skip data and then check the CRC. Depending on whether we are - * reading an ancillary or critical chunk, and how the program has set things - * up, we may calculate the CRC on the data and print a message. Returns true - * if the chunk should be discarded, otherwise false. - */ -int /* PRIVATE */ -png_crc_finish(png_structrp png_ptr, png_uint_32 skip) -{ - /* The size of the local buffer for inflate is a good guess as to a - * reasonable size to use for buffering reads from the application. - */ - while (skip > 0) - { - png_uint_32 len; - png_byte tmpbuf[PNG_INFLATE_BUF_SIZE]; - - len = (sizeof tmpbuf); - if (len > skip) - len = skip; - skip -= len; - - png_crc_read(png_ptr, tmpbuf, len); - } - - /* Compare the CRC stored in the PNG file with that calculated by libpng from - * the data it has read thus far. Do any required error handling. The - * second parameter is to allow a critical chunk (specifically PLTE) to be - * treated as ancillary. - */ - { - png_byte crc_bytes[4]; - -# ifdef PNG_IO_STATE_SUPPORTED - png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC; -# endif - - png_read_data(png_ptr, crc_bytes, 4); - - if (png_ptr->current_crc != crc_quiet_use && - png_get_uint_32(crc_bytes) != png_ptr->crc) - { - if (png_ptr->current_crc == crc_error_quit) - png_chunk_error(png_ptr, "CRC"); - - else - png_chunk_warning(png_ptr, "CRC"); - - /* The only way to discard a chunk at present is to issue a warning. - * TODO: quiet_discard. - */ - return png_ptr->current_crc == crc_warn_discard; - } - } - - return 0; -} - -#if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\ - defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\ - defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\ - defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_SEQUENTIAL_READ_SUPPORTED) -/* Manage the read buffer; this simply reallocates the buffer if it is not small - * enough (or if it is not allocated). The routine returns a pointer to the - * buffer; if an error occurs and 'warn' is set the routine returns NULL, else - * it will call png_error (via png_malloc) on failure. (warn == 2 means - * 'silent'). - */ -png_bytep /* PRIVATE */ -png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn) -{ - png_bytep buffer = png_ptr->read_buffer; - - if (buffer != NULL && new_size > png_ptr->read_buffer_size) - { - png_ptr->read_buffer = NULL; - png_ptr->read_buffer_size = 0; - png_free(png_ptr, buffer); - buffer = NULL; - } - - if (buffer == NULL) - { - buffer = png_voidcast(png_bytep, png_malloc_base(png_ptr, new_size)); - - if (buffer != NULL) - { - png_ptr->read_buffer = buffer; - png_ptr->read_buffer_size = new_size; - } - - else if (warn < 2) /* else silent */ - { - if (warn != 0) - png_chunk_warning(png_ptr, "insufficient memory to read chunk"); - - else - png_chunk_error(png_ptr, "insufficient memory to read chunk"); - } - } - - return buffer; -} -#endif /* READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|SEQUENTIAL_READ */ - -/* png_inflate_claim: claim the zstream for some nefarious purpose that involves - * decompression. Returns Z_OK on success, else a zlib error code. It checks - * the owner but, in final release builds, just issues a warning if some other - * chunk apparently owns the stream. Prior to release it does a png_error. - */ -static int -png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) -{ - if (png_ptr->zowner != 0) - { - char msg[64]; - - PNG_STRING_FROM_CHUNK(msg, png_ptr->zowner); - /* So the message that results is " using zstream"; this is an - * internal error, but is very useful for debugging. i18n requirements - * are minimal. - */ - (void)png_safecat(msg, (sizeof msg), 4, " using zstream"); -#if PNG_RELEASE_BUILD - png_chunk_warning(png_ptr, msg); - png_ptr->zowner = 0; -#else - png_chunk_error(png_ptr, msg); -#endif - } - - /* Implementation note: unlike 'png_deflate_claim' this internal function - * does not take the size of the data as an argument. Some efficiency could - * be gained by using this when it is known *if* the zlib stream itself does - * not record the number; however, this is an illusion: the original writer - * of the PNG may have selected a lower window size, and we really must - * follow that because, for systems with with limited capabilities, we - * would otherwise reject the application's attempts to use a smaller window - * size (zlib doesn't have an interface to say "this or lower"!). - * - * inflateReset2 was added to zlib 1.2.4; before this the window could not be - * reset, therefore it is necessary to always allocate the maximum window - * size with earlier zlibs just in case later compressed chunks need it. - */ - { - int ret; /* zlib return code */ -#if ZLIB_VERNUM >= 0x1240 - int window_bits = 0; - -# if defined(PNG_SET_OPTION_SUPPORTED) && \ - defined(PNG_MAXIMUM_INFLATE_WINDOW) - - if (png_ptr->maximum_inflate_window) - window_bits = 15; - -# endif -#endif /* ZLIB_VERNUM >= 0x1240 */ - - /* Initialize the alloc/free callbacks every time: */ - png_ptr->zstream.zalloc = png_zalloc; - png_ptr->zstream.zfree = png_zfree; - png_ptr->zstream.opaque = png_ptr; - - /* Set this for safety, just in case the previous owner left pointers to - * memory allocations. - */ - png_ptr->zstream.next_in = NULL; - png_ptr->zstream.avail_in = 0; - png_ptr->zstream.next_out = NULL; - png_ptr->zstream.avail_out = 0; - - /* If png_struct::zstream has been used before for decompression it does - * not need to be re-initialized, just reset. - */ - if (png_ptr->zstream.state != NULL) - { -#if ZLIB_VERNUM >= 0x1240 - ret = inflateReset2(&png_ptr->zstream, window_bits); -#else - ret = inflateReset(&png_ptr->zstream); -#endif - } - - else - { -#if ZLIB_VERNUM >= 0x1240 - ret = inflateInit2(&png_ptr->zstream, window_bits); -#else - ret = inflateInit(&png_ptr->zstream); -#endif - } - -#if ZLIB_VERNUM >= 0x1240 - /* Turn off validation of the ADLER32 checksum */ - if (png_ptr->current_crc == crc_quiet_use) - ret = inflateReset2(&png_ptr->zstream, -window_bits); -#endif - - if (ret == Z_OK && png_ptr->zstream.state != NULL) - { - png_ptr->zowner = owner; - png_ptr->zstream_ended = 0; - } - - else - { - png_zstream_error(&png_ptr->zstream, ret); - png_ptr->zstream_ended = 1; - } - - return ret; - } - -# ifdef window_bits -# undef window_bits -# endif -} - -/* This is a wrapper for the zlib deflate call which will handle larger buffer - * sizes than uInt. The input is limited to png_uint_32, because invariably - * the input comes from a chunk which has a 31-bit length, the output can be - * anything that fits in a png_alloc_size_t. - * - * This internal function sets png_struct::zstream_ended when the end of the - * decoded data has been encountered; this includes both a normal end and - * error conditions. - */ -static int -png_zlib_inflate(png_structrp png_ptr, png_uint_32 owner, int finish, - /* INPUT: */ png_const_bytep *next_in_ptr, png_uint_32p avail_in_ptr, - /* OUTPUT: */ png_bytep *next_out_ptr, png_alloc_size_t *avail_out_ptr) -{ - if (png_ptr->zowner == owner) /* Else not claimed */ - { - int ret; - png_alloc_size_t avail_out = *avail_out_ptr; - png_uint_32 avail_in = *avail_in_ptr; - png_bytep output = *next_out_ptr; - png_const_bytep input = *next_in_ptr; - - /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it - * can't even necessarily handle 65536 bytes) because the type uInt is - * "16 bits or more". Consequently it is necessary to chunk the input to - * zlib. This code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the - * maximum value that can be stored in a uInt.) It is possible to set - * ZLIB_IO_MAX to a lower value in pngpriv.h and this may sometimes have - * a performance advantage, because it reduces the amount of data accessed - * at each step and that may give the OS more time to page it in. - */ - png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input); - /* avail_in and avail_out are set below from 'size' */ - png_ptr->zstream.avail_in = 0; - png_ptr->zstream.avail_out = 0; - - /* Read directly into the output if it is available (this is set to - * a local buffer below if output is NULL). - */ - if (output != NULL) - png_ptr->zstream.next_out = output; - - do - { - uInt avail; - Byte local_buffer[PNG_INFLATE_BUF_SIZE]; - - /* zlib INPUT BUFFER */ - /* The setting of 'avail_in' used to be outside the loop; by setting it - * inside it is possible to chunk the input to zlib and simply rely on - * zlib to advance the 'next_in' pointer. This allows arbitrary - * amounts of data to be passed through zlib at the unavoidable cost of - * requiring a window save (memcpy of up to 32768 output bytes) - * every ZLIB_IO_MAX input bytes. - */ - avail_in += png_ptr->zstream.avail_in; /* not consumed last time */ - avail = ZLIB_IO_MAX; - - if (avail_in < avail) - avail = (uInt)avail_in; /* safe: < than ZLIB_IO_MAX */ - - avail_in -= avail; - png_ptr->zstream.avail_in = avail; - - /* zlib OUTPUT BUFFER */ - avail_out += png_ptr->zstream.avail_out; /* not written last time */ - avail = ZLIB_IO_MAX; /* maximum zlib can process */ - - if (output == NULL) - { - /* Reset the output buffer each time round if output is NULL and - * make available the full buffer, up to 'remaining_space' - */ - png_ptr->zstream.next_out = local_buffer; - if ((sizeof local_buffer) < avail) - avail = (sizeof local_buffer); - } - - if (avail_out < avail) - avail = (uInt)avail_out; /* safe: < ZLIB_IO_MAX */ - - png_ptr->zstream.avail_out = avail; - avail_out -= avail; - - /* zlib inflate call */ - /* In fact 'avail_out' may be 0 at this point, that happens at the end - * of the read when the final LZ end code was not passed at the end of - * the previous chunk of input data. Tell zlib if we have reached the - * end of the output buffer. - */ - ret = inflate(&png_ptr->zstream, avail_out > 0 ? Z_NO_FLUSH : - (finish ? Z_FINISH : Z_SYNC_FLUSH)); - } while (ret == Z_OK); - - /* For safety kill the local buffer pointer now */ - if (output == NULL) - png_ptr->zstream.next_out = NULL; - - /* Claw back the 'size' and 'remaining_space' byte counts. */ - avail_in += png_ptr->zstream.avail_in; - avail_out += png_ptr->zstream.avail_out; - - /* Update the input and output sizes; the updated values are the amount - * consumed or written, effectively the inverse of what zlib uses. - */ - *avail_out_ptr = avail_out; - if (output != NULL) - *next_out_ptr = png_ptr->zstream.next_out; - - *avail_in_ptr = avail_in; - *next_in_ptr = png_ptr->zstream.next_in; - - /* Ensure png_ptr->zstream.msg is set, ret can't be Z_OK at this point. - */ - debug(ret != Z_OK); - - if (ret != Z_BUF_ERROR) - png_ptr->zstream_ended = 1; - - png_zstream_error(&png_ptr->zstream, ret); - return ret; - } - - else - { - /* This is a bad internal error. The recovery assigns to the zstream msg - * pointer, which is not owned by the caller, but this is safe; it's only - * used on errors! (The {next,avail}_{in,out} values are not changed.) - */ - png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); - return Z_STREAM_ERROR; - } -} - -#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED -/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to - * allow the caller to do multiple calls if required. If the 'finish' flag is - * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must - * be returned or there has been a problem, otherwise Z_SYNC_FLUSH is used and - * Z_OK or Z_STREAM_END will be returned on success. - * - * The input and output sizes are updated to the actual amounts of data consumed - * or written, not the amount available (as in a z_stream). The data pointers - * are not changed, so the next input is (data+input_size) and the next - * available output is (output+output_size). - */ -static int -png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish, - /* INPUT: */ png_const_bytep input, png_uint_32p input_size_ptr, - /* OUTPUT: */ png_bytep output, png_alloc_size_t *output_size_ptr) -{ - png_uint_32 avail_in = *input_size_ptr; - png_alloc_size_t avail_out = *output_size_ptr; - int ret = png_zlib_inflate(png_ptr, owner, finish, - &input, &avail_in, &output, &avail_out); - - /* And implement the non-zlib semantics (the size values are updated to the - * amounts consumed and written, not the amount remaining.) - */ - *input_size_ptr -= avail_in; - *output_size_ptr -= avail_out; - return ret; -} - -/* Decompress trailing data in a chunk. The assumption is that read_buffer - * points at an allocated area holding the contents of a chunk with a - * trailing compressed part. What we get back is an allocated area - * holding the original prefix part and an uncompressed version of the - * trailing part (the malloc area passed in is freed). - */ -static int -png_decompress_chunk(png_structrp png_ptr, - png_uint_32 chunklength, png_uint_32 prefix_size, - png_alloc_size_t *newlength /* must be initialized to the maximum! */, - int terminate /*add a '\0' to the end of the uncompressed data*/) -{ - /* TODO: implement different limits for different types of chunk. - * - * The caller supplies *newlength set to the maximum length of the - * uncompressed data, but this routine allocates space for the prefix and - * maybe a '\0' terminator too. We have to assume that 'prefix_size' is - * limited only by the maximum chunk size. - */ - png_alloc_size_t limit = PNG_SIZE_MAX; - -#ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_malloc_max > 0 && - png_ptr->user_chunk_malloc_max < limit) - limit = png_ptr->user_chunk_malloc_max; -#elif PNG_USER_CHUNK_MALLOC_MAX > 0 - if (PNG_USER_CHUNK_MALLOC_MAX < limit) - limit = PNG_USER_CHUNK_MALLOC_MAX; -#endif - - if (limit >= prefix_size + (terminate != 0)) - { - int ret; - - limit -= prefix_size + (terminate != 0); - - if (limit < *newlength) - *newlength = limit; - - /* Now try to claim the stream. */ - ret = png_inflate_claim(png_ptr, png_ptr->chunk_name); - - if (ret == Z_OK) - { - png_uint_32 lzsize = chunklength - prefix_size; - - ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, - /* input: */ png_ptr->read_buffer + prefix_size, &lzsize, - /* output: */ NULL, newlength); - - if (ret == Z_STREAM_END) - { - /* Use 'inflateReset' here, not 'inflateReset2' because this - * preserves the previously decided window size (otherwise it would - * be necessary to store the previous window size.) In practice - * this doesn't matter anyway, because png_inflate will call inflate - * with Z_FINISH in almost all cases, so the window will not be - * maintained. - */ - if (inflateReset(&png_ptr->zstream) == Z_OK) - { - /* Because of the limit checks above we know that the new, - * expanded, size will fit in a size_t (let alone an - * png_alloc_size_t). Use png_malloc_base here to avoid an - * extra OOM message. - */ - png_alloc_size_t new_size = *newlength; - png_alloc_size_t buffer_size = prefix_size + new_size + - (terminate != 0); - png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr, - buffer_size)); - - if (text != NULL) - { - ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, - png_ptr->read_buffer + prefix_size, &lzsize, - text + prefix_size, newlength); - - if (ret == Z_STREAM_END) - { - if (new_size == *newlength) - { - if (terminate != 0) - text[prefix_size + *newlength] = 0; - - if (prefix_size > 0) - memcpy(text, png_ptr->read_buffer, prefix_size); - - { - png_bytep old_ptr = png_ptr->read_buffer; - - png_ptr->read_buffer = text; - png_ptr->read_buffer_size = buffer_size; - text = old_ptr; /* freed below */ - } - } - - else - { - /* The size changed on the second read, there can be no - * guarantee that anything is correct at this point. - * The 'msg' pointer has been set to "unexpected end of - * LZ stream", which is fine, but return an error code - * that the caller won't accept. - */ - ret = PNG_UNEXPECTED_ZLIB_RETURN; - } - } - - else if (ret == Z_OK) - ret = PNG_UNEXPECTED_ZLIB_RETURN; /* for safety */ - - /* Free the text pointer (this is the old read_buffer on - * success) - */ - png_free(png_ptr, text); - - /* This really is very benign, but it's still an error because - * the extra space may otherwise be used as a Trojan Horse. - */ - if (ret == Z_STREAM_END && - chunklength - prefix_size != lzsize) - png_chunk_benign_error(png_ptr, "extra compressed data"); - } - - else - { - /* Out of memory allocating the buffer */ - ret = Z_MEM_ERROR; - png_zstream_error(&png_ptr->zstream, Z_MEM_ERROR); - } - } - - else - { - /* inflateReset failed, store the error message */ - png_zstream_error(&png_ptr->zstream, ret); - - if (ret == Z_STREAM_END) - ret = PNG_UNEXPECTED_ZLIB_RETURN; - } - } - - else if (ret == Z_OK) - ret = PNG_UNEXPECTED_ZLIB_RETURN; - - /* Release the claimed stream */ - png_ptr->zowner = 0; - } - - else /* the claim failed */ if (ret == Z_STREAM_END) /* impossible! */ - ret = PNG_UNEXPECTED_ZLIB_RETURN; - - return ret; - } - - else - { - /* Application/configuration limits exceeded */ - png_zstream_error(&png_ptr->zstream, Z_MEM_ERROR); - return Z_MEM_ERROR; - } -} -#endif /* READ_COMPRESSED_TEXT */ - -#ifdef PNG_READ_iCCP_SUPPORTED -/* Perform a partial read and decompress, producing 'avail_out' bytes and - * reading from the current chunk as required. - */ -static int -png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size, - png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size, - int finish) -{ - if (png_ptr->zowner == png_ptr->chunk_name) - { - int ret; - - /* next_in and avail_in must have been initialized by the caller. */ - png_ptr->zstream.next_out = next_out; - png_ptr->zstream.avail_out = 0; /* set in the loop */ - - do - { - if (png_ptr->zstream.avail_in == 0) - { - if (read_size > *chunk_bytes) - read_size = (uInt)*chunk_bytes; - *chunk_bytes -= read_size; - - if (read_size > 0) - png_crc_read(png_ptr, read_buffer, read_size); - - png_ptr->zstream.next_in = read_buffer; - png_ptr->zstream.avail_in = read_size; - } - - if (png_ptr->zstream.avail_out == 0) - { - uInt avail = ZLIB_IO_MAX; - if (avail > *out_size) - avail = (uInt)*out_size; - *out_size -= avail; - - png_ptr->zstream.avail_out = avail; - } - - /* Use Z_SYNC_FLUSH when there is no more chunk data to ensure that all - * the available output is produced; this allows reading of truncated - * streams. - */ - ret = inflate(&png_ptr->zstream, - *chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : - Z_SYNC_FLUSH)); - } - while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0)); - - *out_size += png_ptr->zstream.avail_out; - png_ptr->zstream.avail_out = 0; /* Should not be required, but is safe */ - - /* Ensure the error message pointer is always set: */ - png_zstream_error(&png_ptr->zstream, ret); - return ret; - } - - else - { - png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); - return Z_STREAM_ERROR; - } -} -#endif /* READ_iCCP */ - -/* Chunk handling error handlers and utilities: */ -/* Utility to read the chunk data from the start without processing it; - * a skip function. - */ -static void -png_handle_skip(png_structrp png_ptr) - /* Skip the entire chunk after the name,length header has been read: */ -{ - png_crc_finish(png_ptr, png_ptr->chunk_length); -} - -static void -png_handle_error(png_structrp png_ptr -# ifdef PNG_ERROR_TEXT_SUPPORTED - , png_const_charp error -# else -# define png_handle_error(pp,e) png_handle_error(pp) -# endif - ) - /* Handle an error detected immediately after the chunk header has been - * read; this skips the rest of the chunk data and the CRC then signals - * a *benign* chunk error. - */ -{ - png_handle_skip(png_ptr); - png_chunk_benign_error(png_ptr, error); -} - -#if defined (PNG_READ_gAMA_SUPPORTED) || defined (PNG_READ_sBIT_SUPPORTED) ||\ - defined (PNG_READ_cHRM_SUPPORTED) || defined (PNG_READ_sRGB_SUPPORTED) ||\ - defined (PNG_READ_iCCP_SUPPORTED) || defined (PNG_READ_tRNS_SUPPORTED) ||\ - defined (PNG_READ_bKGD_SUPPORTED) || defined (PNG_READ_hIST_SUPPORTED) ||\ - defined (PNG_READ_pHYs_SUPPORTED) || defined (PNG_READ_oFFs_SUPPORTED) ||\ - defined (PNG_READ_sCAL_SUPPORTED) || defined (PNG_READ_tIME_SUPPORTED) -static void -png_handle_bad_length(png_structrp png_ptr) -{ - png_handle_error(png_ptr, "invalid length"); -} -#endif /* chunks that can generate length errors */ - -/* Read and check the IDHR chunk */ -static void -png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr) -{ - png_byte buf[13]; - png_uint_32 width, height; - png_byte bit_depth, color_type, compression_type, filter_method; - png_byte interlace_type; - - png_debug(1, "in png_handle_IHDR"); - - /* Check the length (this is a chunk error; not benign) */ - if (png_ptr->chunk_length != 13) - png_chunk_error(png_ptr, "invalid length"); - - png_crc_read(png_ptr, buf, 13); - png_crc_finish(png_ptr, 0); - - width = png_get_uint_31(png_ptr, buf); - height = png_get_uint_31(png_ptr, buf + 4); - bit_depth = buf[8]; - color_type = buf[9]; - compression_type = buf[10]; - filter_method = buf[11]; - interlace_type = buf[12]; - - /* Set internal variables */ - png_ptr->width = width; - png_ptr->height = height; - png_ptr->bit_depth = bit_depth; - png_ptr->interlaced = interlace_type; - png_ptr->color_type = color_type; - png_ptr->filter_method = filter_method; - - png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, - color_type, interlace_type, compression_type, filter_method); -} - -/* Read and check the palette */ -static void -png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr) -{ - png_color palette[PNG_MAX_PALETTE_LENGTH]; - png_uint_32 length = png_ptr->chunk_length; - png_uint_32 max_palette_length, num, i; - - png_debug(1, "in png_handle_PLTE"); - - if (info_ptr == NULL) - return; - - if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) - { - png_handle_error(png_ptr, "ignored in grayscale PNG"); - return; - } - -#ifndef PNG_READ_OPT_PLTE_SUPPORTED - if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) - { - /* Skip the whole chunk: */ - png_handle_skip(png_ptr); - return; - } -#endif - - if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) - { - png_crc_finish(png_ptr, length); - png_chunk_report(png_ptr, "invalid length", - ((png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) ? PNG_CHUNK_ERROR : - PNG_CHUNK_FATAL)); - return; - } - - /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */ - num = length / 3U; - - /* If the palette has 256 or fewer entries but is too large for the bit - * depth, we don't issue an error, to preserve the behavior of previous - * libpng versions. We silently truncate the unused extra palette entries - * here. - */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - max_palette_length = (1U << png_ptr->bit_depth); - else - max_palette_length = PNG_MAX_PALETTE_LENGTH; - - if (num > max_palette_length) - num = max_palette_length; - - for (i = 0; i < num; ++i) - { - png_byte buf[3]; - - png_crc_read(png_ptr, buf, 3); - palette[i].red = buf[0]; - palette[i].green = buf[1]; - palette[i].blue = buf[2]; - } - - png_crc_finish(png_ptr, length - num * 3U); - png_set_PLTE(png_ptr, info_ptr, palette, num); - - /* Ok, make our own copy since the set succeeded: */ - debug(png_ptr->palette == NULL); /* should only get set once */ - png_ptr->palette = png_voidcast(png_colorp, png_malloc(png_ptr, - sizeof (png_color[PNG_MAX_PALETTE_LENGTH]))); - /* This works because we know png_set_PLTE also expands the palette to the - * full size: - */ - memcpy(png_ptr->palette, info_ptr->palette, - sizeof (png_color[PNG_MAX_PALETTE_LENGTH])); - png_ptr->num_palette = info_ptr->num_palette; - - /* The three chunks, bKGD, hIST and tRNS *must* appear after PLTE and before - * IDAT. Prior to 1.6.0 this was not checked; instead the code merely - * checked the apparent validity of a tRNS chunk inserted before PLTE on a - * palette PNG. 1.6.0 attempts to rigorously follow the standard and - * therefore does a benign error if the erroneous condition is detected *and* - * cancels the tRNS if the benign error returns. The alternative is to - * amend the standard since it would be rather hypocritical of the standards - * maintainers to ignore it. - */ -#ifdef PNG_READ_tRNS_SUPPORTED - if (png_ptr->num_trans > 0 || - (info_ptr->valid & PNG_INFO_tRNS) != 0) - { - /* Cancel this because otherwise it would be used if the transforms - * require it. Don't cancel the 'valid' flag because this would prevent - * detection of duplicate chunks. - */ - png_ptr->num_trans = 0; - info_ptr->num_trans = 0; - - png_chunk_benign_error(png_ptr, "tRNS must be after"); - } -#endif /* READ_tRNS */ - -#ifdef PNG_READ_hIST_SUPPORTED - if ((info_ptr->valid & PNG_INFO_hIST) != 0) - png_chunk_benign_error(png_ptr, "hIST must be after"); -#endif /* READ_hIST */ - -#ifdef PNG_READ_bKGD_SUPPORTED - if ((info_ptr->valid & PNG_INFO_bKGD) != 0) - png_chunk_benign_error(png_ptr, "bKGD must be after"); -#endif /* READ_bKGD */ -} - -static void -png_handle_IEND(png_structrp png_ptr, png_inforp info_ptr) -{ - png_debug(1, "in png_handle_IEND"); - - png_crc_finish(png_ptr, png_ptr->chunk_length); - - /* Treat this as benign and terminate the PNG anyway: */ - if (png_ptr->chunk_length != 0) - png_chunk_benign_error(png_ptr, "invalid length"); - - PNG_UNUSED(info_ptr) -} - -#ifdef PNG_READ_gAMA_SUPPORTED -static void -png_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr) -{ - png_fixed_point igamma; - png_byte buf[4]; - - png_debug(1, "in png_handle_gAMA"); - - if (png_ptr->chunk_length != 4) - { - png_handle_bad_length(png_ptr); - return; - } - - png_crc_read(png_ptr, buf, 4); - - if (png_crc_finish(png_ptr, 0)) - return; - - igamma = png_get_fixed_point(NULL, buf); - - png_colorspace_set_gamma(png_ptr, &png_ptr->colorspace, igamma); - png_colorspace_sync(png_ptr, info_ptr); -} -#else -# define png_handle_gAMA NULL -#endif /* READ_gAMA */ - -#ifdef PNG_READ_sBIT_SUPPORTED -static void -png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr) -{ - unsigned int truelen, i; - png_byte sample_depth; - png_byte buf[4]; - - png_debug(1, "in png_handle_sBIT"); - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) - { - png_handle_error(png_ptr, "duplicate"); - return; - } - - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - truelen = 3; - sample_depth = 8; - } - - else - { - truelen = PNG_CHANNELS(*png_ptr); - sample_depth = png_ptr->bit_depth; - affirm(truelen <= 4); - } - - if (png_ptr->chunk_length != truelen) - { - png_handle_bad_length(png_ptr); - return; - } - - buf[0] = buf[1] = buf[2] = buf[3] = sample_depth; - png_crc_read(png_ptr, buf, truelen); - - if (png_crc_finish(png_ptr, 0)) - return; - - for (i=0; i sample_depth) - { - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) - { - png_ptr->sig_bit.red = buf[0]; - png_ptr->sig_bit.green = buf[1]; - png_ptr->sig_bit.blue = buf[2]; - png_ptr->sig_bit.alpha = buf[3]; - } - - else - { - png_ptr->sig_bit.gray = buf[0]; - png_ptr->sig_bit.red = buf[0]; - png_ptr->sig_bit.green = buf[0]; - png_ptr->sig_bit.blue = buf[0]; - png_ptr->sig_bit.alpha = buf[1]; - } - - png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); -} -#else -# define png_handle_sBIT NULL -#endif /* READ_sBIT */ - -#ifdef PNG_READ_cHRM_SUPPORTED -static void -png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr) -{ - png_byte buf[32]; - png_xy xy; - - png_debug(1, "in png_handle_cHRM"); - - if (png_ptr->chunk_length != 32) - { - png_handle_bad_length(png_ptr); - return; - } - - png_crc_read(png_ptr, buf, 32); - - if (png_crc_finish(png_ptr, 0)) - return; - - xy.whitex = png_get_fixed_point(NULL, buf); - xy.whitey = png_get_fixed_point(NULL, buf + 4); - xy.redx = png_get_fixed_point(NULL, buf + 8); - xy.redy = png_get_fixed_point(NULL, buf + 12); - xy.greenx = png_get_fixed_point(NULL, buf + 16); - xy.greeny = png_get_fixed_point(NULL, buf + 20); - xy.bluex = png_get_fixed_point(NULL, buf + 24); - xy.bluey = png_get_fixed_point(NULL, buf + 28); - - if (xy.whitex == PNG_FIXED_ERROR || - xy.whitey == PNG_FIXED_ERROR || - xy.redx == PNG_FIXED_ERROR || - xy.redy == PNG_FIXED_ERROR || - xy.greenx == PNG_FIXED_ERROR || - xy.greeny == PNG_FIXED_ERROR || - xy.bluex == PNG_FIXED_ERROR || - xy.bluey == PNG_FIXED_ERROR) - { - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - /* If a colorspace error has already been output skip this chunk */ - if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) - return; - - if (png_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) - { - png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; - png_colorspace_sync(png_ptr, info_ptr); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; - (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy, - 1/*prefer cHRM values*/); - png_colorspace_sync(png_ptr, info_ptr); -} -#else -# define png_handle_cHRM NULL -#endif /* READ_cHRM */ - -#ifdef PNG_READ_sRGB_SUPPORTED -static void -png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr) -{ - png_byte intent; - - png_debug(1, "in png_handle_sRGB"); - - if (png_ptr->chunk_length != 1) - { - png_handle_bad_length(png_ptr); - return; - } - - png_crc_read(png_ptr, &intent, 1); - - if (png_crc_finish(png_ptr, 0)) - return; - - /* If a colorspace error has already been output skip this chunk */ - if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) - return; - - /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect - * this. - */ - if (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) - { - png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; - png_colorspace_sync(png_ptr, info_ptr); - png_chunk_benign_error(png_ptr, "too many profiles"); - return; - } - - (void)png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent); - png_colorspace_sync(png_ptr, info_ptr); -} -#else -# define png_handle_sRGB NULL -#endif /* READ_sRGB */ - -#ifdef PNG_READ_iCCP_SUPPORTED -static void -png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr) -/* Note: this does not properly handle profiles that are > 64K under DOS */ -{ - png_const_charp errmsg = NULL; /* error message output, or no error */ - png_uint_32 length = png_ptr->chunk_length; - int finished = 0; /* crc checked */ - - png_debug(1, "in png_handle_iCCP"); - - /* Consistent with all the above colorspace handling an obviously *invalid* - * chunk is just ignored, so does not invalidate the color space. An - * alternative is to set the 'invalid' flags at the start of this routine - * and only clear them in they were not set before and all the tests pass. - * The minimum 'deflate' stream is assumed to be just the 2 byte header and - * 4 byte checksum. The keyword must be at least one character and there is - * a terminator (0) byte and the compression method. - */ - if (length < 9) - { - png_handle_bad_length(png_ptr); - return; - } - - /* If a colorspace error has already been output skip this chunk */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) - { - png_crc_finish(png_ptr, length); - return; - } - - /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect - * this. - */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) == 0) - { - uInt read_length, keyword_length; - char keyword[81]; - - /* Find the keyword; the keyword plus separator and compression method - * bytes can be at most 81 characters long. - */ - read_length = 81; /* maximum */ - if (read_length > length) - read_length = (uInt)/*SAFE*/length; - - png_crc_read(png_ptr, (png_bytep)keyword, read_length); - length -= read_length; - - keyword_length = 0; - while (keyword_length < 80 && keyword_length < read_length && - keyword[keyword_length] != 0) - ++keyword_length; - - /* TODO: make the keyword checking common */ - if (keyword_length >= 1 && keyword_length <= 79) - { - /* We only understand '0' compression - deflate - so if we get a - * different value we can't safely decode the chunk. - */ - if (keyword_length+1 < read_length && - keyword[keyword_length+1] == PNG_COMPRESSION_TYPE_BASE) - { - read_length -= keyword_length+2; - - if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK) - { - Byte profile_header[132]; - Byte local_buffer[PNG_INFLATE_BUF_SIZE]; - png_alloc_size_t size = (sizeof profile_header); - - png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2); - png_ptr->zstream.avail_in = read_length; - (void)png_inflate_read(png_ptr, local_buffer, - (sizeof local_buffer), &length, profile_header, &size, - 0/*finish: don't, because the output is too small*/); - - if (size == 0) - { - /* We have the ICC profile header; do the basic header checks. - */ - const png_uint_32 profile_length = - png_get_uint_32(profile_header); - - if (png_icc_check_length(png_ptr, &png_ptr->colorspace, - keyword, profile_length)) - { - /* The length is apparently ok, so we can check the 132 - * byte header. - */ - if (png_icc_check_header(png_ptr, &png_ptr->colorspace, - keyword, profile_length, profile_header, - (png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)) - { - /* Now read the tag table; a variable size buffer is - * needed at this point, allocate one for the whole - * profile. The header check has already validated - * that none of these stuff will overflow. - */ - const png_uint_32 tag_count = png_get_uint_32( - profile_header+128); - png_bytep profile = png_read_buffer(png_ptr, - profile_length, 2/*silent*/); - - if (profile != NULL) - { - memcpy(profile, profile_header, - (sizeof profile_header)); - - size = 12 * tag_count; - - (void)png_inflate_read(png_ptr, local_buffer, - (sizeof local_buffer), &length, - profile + (sizeof profile_header), &size, 0); - - /* Still expect a buffer error because we expect - * there to be some tag data! - */ - if (size == 0) - { - if (png_icc_check_tag_table(png_ptr, - &png_ptr->colorspace, keyword, profile_length, - profile)) - { - /* The profile has been validated for basic - * security issues, so read the whole thing in. - */ - size = profile_length - (sizeof profile_header) - - 12 * tag_count; - - (void)png_inflate_read(png_ptr, local_buffer, - (sizeof local_buffer), &length, - profile + (sizeof profile_header) + - 12 * tag_count, &size, 1/*finish*/); - - if (length > 0 -# ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED - && png_ptr->benign_error_action == - PNG_ERROR -# endif /* BENIGN_READ_ERRORS */ - ) - errmsg = "extra compressed data"; - - /* But otherwise allow extra data: */ - else if (size == 0) - { - if (length > 0) - { - /* This can be handled completely, so - * keep going. - */ - png_chunk_warning(png_ptr, - "extra compressed data"); - } - - png_crc_finish(png_ptr, length); - finished = 1; - -# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0 - /* Check for a match against sRGB */ - png_icc_set_sRGB(png_ptr, - &png_ptr->colorspace, profile, - png_ptr->zstream.adler); -# endif - - /* Steal the profile for info_ptr. */ - if (info_ptr != NULL) - { - png_free_data(png_ptr, info_ptr, - PNG_FREE_ICCP, 0); - - info_ptr->iccp_name = png_voidcast(char*, - png_malloc_base(png_ptr, - keyword_length+1)); - if (info_ptr->iccp_name != NULL) - { - memcpy(info_ptr->iccp_name, keyword, - keyword_length+1); - info_ptr->iccp_profile = profile; - png_ptr->read_buffer = NULL; /*steal*/ - info_ptr->free_me |= PNG_FREE_ICCP; - info_ptr->valid |= PNG_INFO_iCCP; - } - - else - { - png_ptr->colorspace.flags |= - PNG_COLORSPACE_INVALID; - errmsg = "out of memory"; - } - } - - /* else the profile remains in the read - * buffer which gets reused for subsequent - * chunks. - */ - - if (info_ptr != NULL) - png_colorspace_sync(png_ptr, info_ptr); - - if (errmsg == NULL) - { - png_ptr->zowner = 0; - return; - } - } - - else if (size > 0) - errmsg = "truncated"; - } - - /* else png_icc_check_tag_table output an error */ - } - - else /* profile truncated */ - errmsg = png_ptr->zstream.msg; - } - - else - errmsg = "out of memory"; - } - - /* else png_icc_check_header output an error */ - } - - /* else png_icc_check_length output an error */ - } - - else /* profile truncated */ - errmsg = png_ptr->zstream.msg; - - /* Release the stream */ - png_ptr->zowner = 0; - } - - else /* png_inflate_claim failed */ - errmsg = png_ptr->zstream.msg; - } - - else - errmsg = "bad compression method"; /* or missing */ - } - - else - errmsg = "bad keyword"; - } - - else - errmsg = "too many profiles"; - - /* Failure: the reason is in 'errmsg' */ - if (finished == 0) - png_crc_finish(png_ptr, length); - - png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; - png_colorspace_sync(png_ptr, info_ptr); - if (errmsg != NULL) /* else already output */ - png_chunk_benign_error(png_ptr, errmsg); -} -#else -# define png_handle_iCCP NULL -#endif /* READ_iCCP */ - -#ifdef PNG_READ_sPLT_SUPPORTED -static void -png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr) -/* Note: this does not properly handle chunks that are > 64K under DOS */ -{ - png_uint_32 length = png_ptr->chunk_length; - png_bytep entry_start, buffer; - png_sPLT_t new_palette; - png_sPLT_entryp pp; - png_uint_32 data_length; - int entry_size, i; - png_uint_32 skip = 0; - png_uint_32 dl; - png_size_t max_dl; - - png_debug(1, "in png_handle_sPLT"); - -#ifdef PNG_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - return; - } - - if (--png_ptr->user_chunk_cache_max == 1) - { - /* Warn the first time */ - png_chunk_benign_error(png_ptr, "no space in chunk cache"); - png_crc_finish(png_ptr, length); - return; - } - } -#endif /* USER_LIMITS */ - - buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); - if (buffer == NULL) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - - /* WARNING: this may break if size_t is less than 32 bits; it is assumed - * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a - * potential breakage point if the types in pngconf.h aren't exactly right. - */ - png_crc_read(png_ptr, buffer, length); - - if (png_crc_finish(png_ptr, skip)) - return; - - buffer[length] = 0; - - for (entry_start = buffer; *entry_start; entry_start++) - /* Empty loop to find end of name */ ; - - ++entry_start; - - /* A sample depth should follow the separator, and we should be on it */ - if (length < 2U || entry_start > buffer + (length - 2U)) - { - png_chunk_benign_error(png_ptr, "malformed"); - return; - } - - new_palette.depth = *entry_start++; - entry_size = (new_palette.depth == 8 ? 6 : 10); - /* This must fit in a png_uint_32 because it is derived from the original - * chunk data length. - */ - data_length = length - (png_uint_32)(entry_start - buffer); - - /* Integrity-check the data length */ - if (data_length % entry_size) - { - png_chunk_benign_error(png_ptr, "invalid length"); - return; - } - - dl = (png_int_32)(data_length / entry_size); - max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry)); - - if (dl > max_dl) - { - png_chunk_benign_error(png_ptr, "exceeds system limits"); - return; - } - - new_palette.nentries = (png_int_32)(data_length / entry_size); - - new_palette.entries = png_voidcast(png_sPLT_entryp, png_malloc_base( - png_ptr, new_palette.nentries * (sizeof (png_sPLT_entry)))); - - if (new_palette.entries == NULL) - { - png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - - for (i = 0; i < new_palette.nentries; i++) - { - pp = new_palette.entries + i; - - if (new_palette.depth == 8) - { - pp->red = *entry_start++; - pp->green = *entry_start++; - pp->blue = *entry_start++; - pp->alpha = *entry_start++; - } - - else - { - pp->red = png_get_uint_16(entry_start); entry_start += 2; - pp->green = png_get_uint_16(entry_start); entry_start += 2; - pp->blue = png_get_uint_16(entry_start); entry_start += 2; - pp->alpha = png_get_uint_16(entry_start); entry_start += 2; - } - - pp->frequency = png_get_uint_16(entry_start); entry_start += 2; - } - - /* Discard all chunk data except the name and stash that */ - new_palette.name = (png_charp)buffer; - - png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); - - png_free(png_ptr, new_palette.entries); -} -#else -# define png_handle_sPLT NULL -#endif /* READ_sPLT */ - -#ifdef PNG_READ_tRNS_SUPPORTED -static void -png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr) -{ - png_uint_32 num_trans; - png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; - - png_debug(1, "in png_handle_tRNS"); - - png_ptr->num_trans = 0U; /* safety */ - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) - { - /* libpng 1.7.0: this used to be a benign error, but it doesn't look very - * benign because it has security implications; libpng ignores the second - * tRNS, so if you can find something that ignores the first instead you - * can choose which image the user sees depending on the PNG decoder. - */ - png_crc_finish(png_ptr, png_ptr->chunk_length); - png_chunk_error(png_ptr, "duplicate"); - return; - } - - if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) - { - png_byte buf[2]; - - if (png_ptr->chunk_length != 2) - { - png_handle_bad_length(png_ptr); - return; - } - - png_crc_read(png_ptr, buf, 2); - num_trans = 1U; - png_ptr->trans_color.gray = png_get_uint_16(buf); - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) - { - png_byte buf[6]; - - if (png_ptr->chunk_length != 6) - { - png_handle_bad_length(png_ptr); - return; - } - - png_crc_read(png_ptr, buf, 6); - num_trans = 1U; - png_ptr->trans_color.red = png_get_uint_16(buf); - png_ptr->trans_color.green = png_get_uint_16(buf + 2); - png_ptr->trans_color.blue = png_get_uint_16(buf + 4); - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - /* png_find_chunk_op checks this: */ - debug(png_ptr->mode & PNG_HAVE_PLTE); - - num_trans = png_ptr->chunk_length; - - if (num_trans > png_ptr->num_palette || num_trans == 0) - { - png_handle_bad_length(png_ptr); - return; - } - - png_crc_read(png_ptr, readbuf, num_trans); - } - - else - { - png_handle_error(png_ptr, "invalid"); - return; - } - - if (png_crc_finish(png_ptr, 0)) - return; - - /* Set it into the info_struct: */ - png_set_tRNS(png_ptr, info_ptr, readbuf, num_trans, &png_ptr->trans_color); - - /* Now make a copy of the buffer if one is required (palette images). */ - debug(png_ptr->trans_alpha == NULL); - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - png_ptr->trans_alpha = png_voidcast(png_bytep, - png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH)); - memset(png_ptr->trans_alpha, 0xFFU, PNG_MAX_PALETTE_LENGTH); - memcpy(png_ptr->trans_alpha, info_ptr->trans_alpha, num_trans); - } - - png_ptr->num_trans = png_check_bits(png_ptr, num_trans, 9); -} -#else -# define png_handle_tRNS NULL -#endif /* READ_tRNS */ - -#ifdef PNG_READ_bKGD_SUPPORTED -static void -png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr) -{ - unsigned int truelen; - png_byte buf[6]; - png_color_16 background; - - png_debug(1, "in png_handle_bKGD"); - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) - { - png_handle_error(png_ptr, "duplicate"); - return; - } - - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - truelen = 1; - - else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) - truelen = 6; - - else - truelen = 2; - - if (png_ptr->chunk_length != truelen) - { - png_handle_bad_length(png_ptr); - return; - } - - png_crc_read(png_ptr, buf, truelen); - - if (png_crc_finish(png_ptr, 0)) - return; - - /* We convert the index value into RGB components so that we can allow - * arbitrary RGB values for background when we have transparency, and - * so it is easy to determine the RGB values of the background color - * from the info_ptr struct. - */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - background.index = buf[0]; - - if (info_ptr && info_ptr->num_palette) - { - if (buf[0] >= info_ptr->num_palette) - { - png_chunk_benign_error(png_ptr, "invalid index"); - return; - } - - background.red = png_check_u16(png_ptr, png_ptr->palette[buf[0]].red); - background.green = - png_check_u16(png_ptr, png_ptr->palette[buf[0]].green); - background.blue = - png_check_u16(png_ptr, png_ptr->palette[buf[0]].blue); - } - - else - background.red = background.green = background.blue = 0; - - background.gray = 0; - } - - else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */ - { - background.index = 0; - background.red = - background.green = - background.blue = - background.gray = png_get_uint_16(buf); - } - - else - { - background.index = 0; - background.red = png_get_uint_16(buf); - background.green = png_get_uint_16(buf + 2); - background.blue = png_get_uint_16(buf + 4); - background.gray = 0; - } - - png_set_bKGD(png_ptr, info_ptr, &background); -} -#else -# define png_handle_bKGD NULL -#endif /* READ_bKGD */ - -#ifdef PNG_READ_hIST_SUPPORTED -static void -png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr) -{ - unsigned int num, i; - png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; - - png_debug(1, "in png_handle_hIST"); - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) - { - png_handle_error(png_ptr, "duplicate"); - return; - } - - num = png_ptr->chunk_length / 2; - - if (num != png_ptr->num_palette || 2*num != png_ptr->chunk_length) - { - png_handle_bad_length(png_ptr); - return; - } - - for (i = 0; i < num; i++) - { - png_byte buf[2]; - - png_crc_read(png_ptr, buf, 2); - readbuf[i] = png_get_uint_16(buf); - } - - if (png_crc_finish(png_ptr, 0)) - return; - - png_set_hIST(png_ptr, info_ptr, readbuf); -} -#else -# define png_handle_hIST NULL -#endif /* READ_hIST */ - -#ifdef PNG_READ_pHYs_SUPPORTED -static void -png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr) -{ - png_byte buf[9]; - png_uint_32 res_x, res_y; - int unit_type; - - png_debug(1, "in png_handle_pHYs"); - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) - { - png_handle_error(png_ptr, "duplicate"); - return; - } - - if (png_ptr->chunk_length != 9) - { - png_handle_bad_length(png_ptr); - return; - } - - png_crc_read(png_ptr, buf, 9); - - if (png_crc_finish(png_ptr, 0)) - return; - - res_x = png_get_uint_32(buf); - res_y = png_get_uint_32(buf + 4); - unit_type = buf[8]; - png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); -} -#else -# define png_handle_pHYs NULL -#endif /* READ_pHYs */ - -#ifdef PNG_READ_oFFs_SUPPORTED /* EXTENSION, before IDAT, no duplicates */ -static void -png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr) -{ - png_byte buf[9]; - png_int_32 offset_x, offset_y; - int unit_type; - - png_debug(1, "in png_handle_oFFs"); - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) - { - png_handle_error(png_ptr, "duplicate"); - return; - } - - if (png_ptr->chunk_length != 9) - { - png_handle_bad_length(png_ptr); - return; - } - - png_crc_read(png_ptr, buf, 9); - - if (png_crc_finish(png_ptr, 0)) - return; - - offset_x = png_get_int_32(buf); - offset_y = png_get_int_32(buf + 4); - unit_type = buf[8]; - png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); -} -#else -# define png_handle_oFFs NULL -#endif /* READ_oFFs */ - -#ifdef PNG_READ_pCAL_SUPPORTED /* EXTENSION: before IDAT, no duplicates */ -static void -png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr) -{ - png_int_32 X0, X1; - png_byte type, nparams; - png_bytep buffer, buf, units, endptr; - png_charpp params; - int i; - - png_debug(1, "in png_handle_pCAL"); - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)) - { - png_handle_error(png_ptr, "duplicate"); - return; - } - - png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)", - png_ptr->chunk_length + 1); - - buffer = png_read_buffer(png_ptr, png_ptr->chunk_length+1, 2/*silent*/); - - if (buffer == NULL) - { - png_handle_error(png_ptr, "out of memory"); - return; - } - - png_crc_read(png_ptr, buffer, png_ptr->chunk_length); - - if (png_crc_finish(png_ptr, 0)) - return; - - buffer[png_ptr->chunk_length] = 0; /* Null terminate the last string */ - - png_debug(3, "Finding end of pCAL purpose string"); - for (buf = buffer; *buf; buf++) - /* Empty loop */ ; - - endptr = buffer + png_ptr->chunk_length; - - /* We need to have at least 12 bytes after the purpose string - * in order to get the parameter information. - */ - if (endptr - buf <= 12) - { - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_debug(3, "Reading pCAL X0, X1, type, nparams, and units"); - X0 = png_get_int_32((png_bytep)buf+1); - X1 = png_get_int_32((png_bytep)buf+5); - type = buf[9]; - nparams = buf[10]; - units = buf + 11; - - png_debug(3, "Checking pCAL equation type and number of parameters"); - /* Check that we have the right number of parameters for known - * equation types. - */ - if ((type == PNG_EQUATION_LINEAR && nparams != 2) || - (type == PNG_EQUATION_BASE_E && nparams != 3) || - (type == PNG_EQUATION_ARBITRARY && nparams != 3) || - (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) - { - png_chunk_benign_error(png_ptr, "invalid parameter count"); - return; - } - - else if (type >= PNG_EQUATION_LAST) - { - png_chunk_benign_error(png_ptr, "unrecognized equation type"); - return; - } - - for (buf = units; *buf; buf++) - /* Empty loop to move past the units string. */ ; - - png_debug(3, "Allocating pCAL parameters array"); - - params = png_voidcast(png_charpp, png_malloc_base(png_ptr, - nparams * (sizeof (png_charp)))); - - if (params == NULL) - { - png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - - /* Get pointers to the start of each parameter string. */ - for (i = 0; i < nparams; i++) - { - buf++; /* Skip the null string terminator from previous parameter. */ - - png_debug1(3, "Reading pCAL parameter %d", i); - - for (params[i] = (png_charp)buf; buf <= endptr && *buf != 0; buf++) - /* Empty loop to move past each parameter string */ ; - - /* Make sure we haven't run out of data yet */ - if (buf > endptr) - { - png_free(png_ptr, params); - png_chunk_benign_error(png_ptr, "invalid data"); - return; - } - } - - png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams, - (png_charp)units, params); - - png_free(png_ptr, params); -} -#else -# define png_handle_pCAL NULL -#endif /* READ_pCAL */ - -#ifdef PNG_READ_sCAL_SUPPORTED -/* Read the sCAL chunk */ -static void -png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr) -{ - png_uint_32 length = png_ptr->chunk_length; - png_bytep buffer; - png_size_t i; - int state; - - png_debug(1, "in png_handle_sCAL"); - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) - { - png_handle_error(png_ptr, "duplicate"); - return; - } - - /* Need unit type, width, \0, height: minimum 4 bytes */ - if (length < 4) - { - png_handle_bad_length(png_ptr); - return; - } - - png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", - length + 1); - - buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); - - if (buffer == NULL) - { - png_handle_error(png_ptr, "out of memory"); - return; - } - - png_crc_read(png_ptr, buffer, length); - buffer[length] = 0; /* Null terminate the last string */ - - if (png_crc_finish(png_ptr, 0)) - return; - - /* Validate the unit. */ - if (buffer[0] != 1 && buffer[0] != 2) - { - png_chunk_benign_error(png_ptr, "invalid unit"); - return; - } - - /* Validate the ASCII numbers, need two ASCII numbers separated by - * a '\0' and they need to fit exactly in the chunk data. - */ - i = 1; - state = 0; - - if (!png_check_fp_number((png_const_charp)buffer, length, &state, &i) || - i >= length || buffer[i++] != 0) - png_chunk_benign_error(png_ptr, "bad width format"); - - else if (!PNG_FP_IS_POSITIVE(state)) - png_chunk_benign_error(png_ptr, "non-positive width"); - - else - { - png_size_t heighti = i; - - state = 0; - if (!png_check_fp_number((png_const_charp)buffer, length, &state, &i) || - i != length) - png_chunk_benign_error(png_ptr, "bad height format"); - - else if (!PNG_FP_IS_POSITIVE(state)) - png_chunk_benign_error(png_ptr, "non-positive height"); - - else - /* This is the (only) success case. */ - png_set_sCAL_s(png_ptr, info_ptr, buffer[0], - (png_charp)buffer+1, (png_charp)buffer+heighti); - } -} -#else -# define png_handle_sCAL NULL -#endif /* READ_sCAL */ - -#ifdef PNG_READ_tIME_SUPPORTED -static void -png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr) -{ - png_byte buf[7]; - png_time mod_time; - - png_debug(1, "in png_handle_tIME"); - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) - { - png_handle_error(png_ptr, "duplicate"); - return; - } - - if (png_ptr->chunk_length != 7) - { - png_handle_bad_length(png_ptr); - return; - } - - png_crc_read(png_ptr, buf, 7); - - if (png_crc_finish(png_ptr, 0)) - return; - - mod_time.second = buf[6]; - mod_time.minute = buf[5]; - mod_time.hour = buf[4]; - mod_time.day = buf[3]; - mod_time.month = buf[2]; - mod_time.year = png_get_uint_16(buf); - - png_set_tIME(png_ptr, info_ptr, &mod_time); -} -#else -# define png_handle_tIME NULL -#endif /* READ_tIME */ - -#ifdef PNG_READ_tEXt_SUPPORTED -static void -png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr) -{ - png_uint_32 length = png_ptr->chunk_length; - png_text text_info; - png_bytep buffer; - png_charp key; - png_charp text; - png_uint_32 skip = 0; - - png_debug(1, "in png_handle_tEXt"); - -#ifdef PNG_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - return; - } - - if (--png_ptr->user_chunk_cache_max == 1) - { - png_handle_error(png_ptr, "no space in chunk cache"); - return; - } - } -#endif /* USER_LIMITS */ - - buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); - - if (buffer == NULL) - { - png_handle_error(png_ptr, "out of memory"); - return; - } - - png_crc_read(png_ptr, buffer, length); - - if (png_crc_finish(png_ptr, skip)) - return; - - key = (png_charp)buffer; - key[length] = 0; - - for (text = key; *text; text++) - /* Empty loop to find end of key */ ; - - if (text != key + length) - text++; - - text_info.compression = PNG_TEXT_COMPRESSION_NONE; - text_info.key = key; - text_info.lang = NULL; - text_info.lang_key = NULL; - text_info.itxt_length = 0; - text_info.text = text; - text_info.text_length = strlen(text); - - if (png_set_text_2(png_ptr, info_ptr, &text_info, 1)) - png_warning(png_ptr, "Insufficient memory to process text chunk"); -} -#else -# define png_handle_tEXt NULL -#endif /* READ_tEXt */ - -#ifdef PNG_READ_zTXt_SUPPORTED -static void -png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr) -{ - png_uint_32 length = png_ptr->chunk_length; - png_const_charp errmsg = NULL; - png_bytep buffer; - png_uint_32 keyword_length; - - png_debug(1, "in png_handle_zTXt"); - -#ifdef PNG_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - return; - } - - if (--png_ptr->user_chunk_cache_max == 1) - { - png_handle_error(png_ptr, "no space in chunk cache"); - return; - } - } -#endif /* USER_LIMITS */ - - /* Note, "length" is sufficient here; we won't be adding - * a null terminator later. - */ - buffer = png_read_buffer(png_ptr, length, 2/*silent*/); - - if (buffer == NULL) - { - png_handle_error(png_ptr, "out of memory"); - return; - } - - png_crc_read(png_ptr, buffer, length); - - if (png_crc_finish(png_ptr, 0)) - return; - - /* TODO: also check that the keyword contents match the spec! */ - for (keyword_length = 0; - keyword_length < length && buffer[keyword_length] != 0; - ++keyword_length) - /* Empty loop to find end of name */ ; - - if (keyword_length > 79 || keyword_length < 1) - errmsg = "bad keyword"; - - /* zTXt must have some LZ data after the keyword, although it may expand to - * zero bytes; we need a '\0' at the end of the keyword, the compression type - * then the LZ data: - */ - else if (keyword_length + 3 > length) - errmsg = "truncated"; - - else if (buffer[keyword_length+1] != PNG_COMPRESSION_TYPE_BASE) - errmsg = "unknown compression type"; - - else - { - png_alloc_size_t uncompressed_length = PNG_SIZE_MAX; - - /* TODO: at present png_decompress_chunk imposes a single application - * level memory limit, this should be split to different values for iCCP - * and text chunks. - */ - if (png_decompress_chunk(png_ptr, length, keyword_length+2, - &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) - { - png_text text; - - /* It worked; png_ptr->read_buffer now looks like a tEXt chunk except - * for the extra compression type byte and the fact that it isn't - * necessarily '\0' terminated. - */ - buffer = png_ptr->read_buffer; - buffer[uncompressed_length+(keyword_length+2)] = 0; - - text.compression = PNG_TEXT_COMPRESSION_zTXt; - text.key = (png_charp)buffer; - text.text = (png_charp)(buffer + keyword_length+2); - text.text_length = uncompressed_length; - text.itxt_length = 0; - text.lang = NULL; - text.lang_key = NULL; - - if (png_set_text_2(png_ptr, info_ptr, &text, 1)) - errmsg = "insufficient memory"; - } - - else - errmsg = png_ptr->zstream.msg; - } - - if (errmsg != NULL) - png_chunk_benign_error(png_ptr, errmsg); -} -#else -# define png_handle_zTXt NULL -#endif /* READ_zTXt */ - -#ifdef PNG_READ_iTXt_SUPPORTED -static void -png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr) -{ - png_uint_32 length = png_ptr->chunk_length; - png_const_charp errmsg = NULL; - png_bytep buffer; - png_uint_32 prefix_length; - - png_debug(1, "in png_handle_iTXt"); - -#ifdef PNG_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - return; - } - - if (--png_ptr->user_chunk_cache_max == 1) - { - png_handle_error(png_ptr, "no space in chunk cache"); - return; - } - } -#endif /* USER_LIMITS */ - - buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); - - if (buffer == NULL) - { - png_handle_error(png_ptr, "out of memory"); - return; - } - - png_crc_read(png_ptr, buffer, length); - - if (png_crc_finish(png_ptr, 0)) - return; - - /* First the keyword. */ - for (prefix_length=0; - prefix_length < length && buffer[prefix_length] != 0; - ++prefix_length) - /* Empty loop */ ; - - /* Perform a basic check on the keyword length here. */ - if (prefix_length > 79 || prefix_length < 1) - errmsg = "bad keyword"; - - /* Expect keyword, compression flag, compression type, language, translated - * keyword (both may be empty but are 0 terminated) then the text, which may - * be empty. - */ - else if (prefix_length + 5 > length) - errmsg = "truncated"; - - else if (buffer[prefix_length+1] == 0 || - (buffer[prefix_length+1] == 1 && - buffer[prefix_length+2] == PNG_COMPRESSION_TYPE_BASE)) - { - int compressed = buffer[prefix_length+1] != 0; - png_uint_32 language_offset, translated_keyword_offset; - png_alloc_size_t uncompressed_length = 0; - - /* Now the language tag */ - prefix_length += 3; - language_offset = prefix_length; - - for (; prefix_length < length && buffer[prefix_length] != 0; - ++prefix_length) - /* Empty loop */ ; - - /* WARNING: the length may be invalid here, this is checked below. */ - translated_keyword_offset = ++prefix_length; - - for (; prefix_length < length && buffer[prefix_length] != 0; - ++prefix_length) - /* Empty loop */ ; - - /* prefix_length should now be at the trailing '\0' of the translated - * keyword, but it may already be over the end. None of this arithmetic - * can overflow because chunks are at most 2^31 bytes long, but on 16-bit - * systems the available allocation may overflow. - */ - ++prefix_length; - - if (!compressed && prefix_length <= length) - uncompressed_length = length - prefix_length; - - else if (compressed && prefix_length < length) - { - uncompressed_length = PNG_SIZE_MAX; - - /* TODO: at present png_decompress_chunk imposes a single application - * level memory limit, this should be split to different values for - * iCCP and text chunks. - */ - if (png_decompress_chunk(png_ptr, length, prefix_length, - &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) - buffer = png_ptr->read_buffer; - - else - errmsg = png_ptr->zstream.msg; - } - - else - errmsg = "truncated"; - - if (errmsg == NULL) - { - png_text text; - - buffer[uncompressed_length+prefix_length] = 0; - - if (compressed == 0) - text.compression = PNG_ITXT_COMPRESSION_NONE; - - else - text.compression = PNG_ITXT_COMPRESSION_zTXt; - - text.key = (png_charp)buffer; - text.lang = (png_charp)buffer + language_offset; - text.lang_key = (png_charp)buffer + translated_keyword_offset; - text.text = (png_charp)buffer + prefix_length; - text.text_length = 0; - text.itxt_length = uncompressed_length; - - if (png_set_text_2(png_ptr, info_ptr, &text, 1)) - errmsg = "insufficient memory"; - } - } - - else - errmsg = "bad compression info"; - - if (errmsg != NULL) - png_chunk_benign_error(png_ptr, errmsg); -} -#else -# define png_handle_iTXt NULL -#endif /* READ_iTXt */ - -/* UNSUPPORTED CHUNKS */ -#define png_handle_sTER NULL -#define png_handle_fRAc NULL -#define png_handle_gIFg NULL -#define png_handle_gIFt NULL -#define png_handle_gIFx NULL -#define png_handle_dSIG NULL - -/* IDAT has special treatment below */ -#define png_handle_IDAT NULL - -/****************************************************************************** - * UNKNOWN HANDLING LOGIC - * - * There are three ways an unknown chunk may arise: - * - * 1) Chunks not in the spec. - * 2) Chunks in the spec where libpng support doesn't exist or has been compiled - * out. These are recognized, for a very small performance benefit at the - * cost of maintaining a png_known_chunks entry for each one. - * 3) Chunks supported by libpng which have been marked as 'unknown' by the - * application. - * - * Prior to 1.7.0 all three cases are handled the same way, in 1.7.0 some - * attempt is made to optimize (2) and (3) by storing flags in - * png_struct::known_unknown for chunks in the spec which have been marked for - * unknown handling. - * - * There are three things libpng can do with an unknown chunk, in order of - * preference: - * - * 1) If PNG_READ_USER_CHUNKS_SUPPORTED call an application supplied callback - * with all the chunk data. If this doesn't handle the chunk in prior - * versions of libpng the chunk would be stored if safe otherwise skipped. - * In 1.7.0 the specified chunk unknown handling is used. - * 2) If PNG_SAVE_UNKNOWN_CHUNKS_SUPPOPRTED the chunk may be saved in the - * info_struct (if there is one.) - * 3) The chunk can be skipped. - * - * In effect libpng tries each option in turn. (2) looks at any per-chunk - * unknown handling then, if one wasn't specified, the overall default. - * - * IHDR and IEND cannot be treated as unknown. PLTE and IDAT can. Prior to - * 1.7.0 they couldn't be skipped without a png_error. 1.7.0 adds an extension - * which allows any critical chunk to be skipped so long as IDAT is skipped; the - * logic for failing on critical chunks only applies if the image data is being - * processed. - * - * The default behavior is (3); unknown chunks are simply skipped. 1.7.0 uses - * this to optimize the read code when possible. - * - * In the read code PNG_READ_UNKNOWN_CHUNKS_SUPPORTED is set only if either (1) - * or (2) or both are supported. - * - *****************************************************************************/ -#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED -static int -png_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name) -{ - png_byte chunk_string[5]; - - PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name); - return png_handle_as_unknown(png_ptr, chunk_string); -} -#endif /* SAVE_UNKNOWN_CHUNKS */ - -#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -/* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */ -static void -png_make_unknown_chunk(png_structrp png_ptr, png_unknown_chunkp chunk, - png_bytep data) -{ - chunk->data = data; - chunk->size = png_ptr->chunk_length; - PNG_CSTRING_FROM_CHUNK(chunk->name, png_ptr->chunk_name); - /* 'mode' is a flag array, only three of the bottom four bits are public: */ - chunk->location = - png_ptr->mode & (PNG_HAVE_IHDR+PNG_HAVE_PLTE+PNG_AFTER_IDAT); -} - -/* Handle an unknown, or known but disabled, chunk */ -void /* PRIVATE */ -png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, - png_bytep chunk_data) -{ - png_debug(1, "in png_handle_unknown"); - - /* NOTE: this code is based on the code in libpng-1.4.12 except for fixing - * the bug which meant that setting a non-default behavior for a specific - * chunk would be ignored (the default was always used unless a user - * callback was installed). - * - * 'keep' is the value from the png_chunk_unknown_handling, the setting for - * this specific chunk_name, if PNG_HANDLE_AS_UNKNOWN_SUPPORTED, if not it - * will always be PNG_HANDLE_CHUNK_AS_DEFAULT and it needs to be set here. - * This is just an optimization to avoid multiple calls to the lookup - * function. - * - * One of the following methods will read the chunk or skip it (at least one - * of these is always defined because this is the only way to switch on - * PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) - */ -# ifdef PNG_READ_USER_CHUNKS_SUPPORTED - /* The user callback takes precedence over the chunk handling option: */ - if (png_ptr->read_user_chunk_fn != NULL) - { - png_unknown_chunk unknown_chunk; - int ret; - - /* Callback to user unknown chunk handler */ - png_make_unknown_chunk(png_ptr, &unknown_chunk, chunk_data); - ret = png_ptr->read_user_chunk_fn(png_ptr, &unknown_chunk); - - /* ret is: - * negative: An error occurred; png_chunk_error will be called. - * zero: The chunk was not handled, the chunk will be discarded - * unless png_set_keep_unknown_chunks has been used to set - * a 'keep' behavior for this particular chunk, in which - * case that will be used. A critical chunk will cause an - * error at this point unless it is to be saved. - * positive: The chunk was handled, libpng will ignore/discard it. - */ - if (ret > 0) - return; - - else if (ret < 0) - png_chunk_error(png_ptr, "application error"); - - /* Else: use the default handling. */ - } -# endif /* READ_USER_CHUNKS */ - -# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED - { - int keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name); - - /* keep is currently just the per-chunk setting, if there was no - * setting change it to the global default now (note that this may - * still be AS_DEFAULT) then obtain the cache of the chunk if required, - * if not simply skip the chunk. - */ - if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT) - keep = png_ptr->unknown_default; - - if (keep == PNG_HANDLE_CHUNK_ALWAYS || - (keep == PNG_HANDLE_CHUNK_IF_SAFE && - PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) -# ifdef PNG_USER_LIMITS_SUPPORTED - switch (png_ptr->user_chunk_cache_max) - { - case 2: - png_ptr->user_chunk_cache_max = 1; - png_chunk_benign_error(png_ptr, "no space in chunk cache"); - /* FALL THROUGH */ - case 1: - /* NOTE: prior to 1.6.0 this case resulted in an unknown - * critical chunk being skipped, now there will be a hard - * error below. - */ - break; - - default: /* not at limit */ - --(png_ptr->user_chunk_cache_max); - /* FALL THROUGH */ - case 0: /* no limit */ -# endif /* USER_LIMITS */ - /* Here when the limit isn't reached or when limits are - * compiled out; store the chunk. - */ - { - png_unknown_chunk unknown_chunk; - - png_make_unknown_chunk(png_ptr, &unknown_chunk, - chunk_data); - png_set_unknown_chunks(png_ptr, info_ptr, &unknown_chunk, - 1); - return; - } -# ifdef PNG_USER_LIMITS_SUPPORTED - } -# endif /* USER_LIMITS */ - } -# else /* !SAVE_UNKNOWN_CHUNKS */ - PNG_UNUSED(info_ptr) -# endif /* !SAVE_UNKNOWN_CHUNKS */ - - /* This is the 'skip' case, where the read callback (if any) returned 0 and - * the save code did not save the chunk. - */ - if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) - png_chunk_error(png_ptr, "unhandled critical chunk"); -} -#endif /* READ_UNKNOWN_CHUNKS */ - -/* This function is called to verify that a chunk name is valid. - * This function can't have the "critical chunk check" incorporated - * into it, since in the future we will need to be able to call user - * functions to handle unknown critical chunks after we check that - * the chunk name itself is valid. - */ - -/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is: - * - * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) - */ - -void /* PRIVATE */ -png_check_chunk_name(png_const_structrp png_ptr, const png_uint_32 chunk_name) -{ - int i; - png_uint_32 cn=chunk_name; - - png_debug(1, "in png_check_chunk_name"); - - for (i=1; i<=4; ++i) - { - int c = cn & 0xff; - - if (c < 65 || c > 122 || (c > 90 && c < 97)) - png_chunk_error(png_ptr, "invalid chunk type"); - - cn >>= 8; - } -} -void /* PRIVATE */ -png_check_chunk_length(png_const_structrp png_ptr, const png_uint_32 length) -{ - png_alloc_size_t limit = PNG_UINT_31_MAX; - -# ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_malloc_max > 0 && - png_ptr->user_chunk_malloc_max < limit) - limit = png_ptr->user_chunk_malloc_max; -# elif PNG_USER_CHUNK_MALLOC_MAX > 0 - if (PNG_USER_CHUNK_MALLOC_MAX < limit) - limit = PNG_USER_CHUNK_MALLOC_MAX; -# endif - if (png_ptr->chunk_name == png_IDAT) - { - /* color_type 0 x 2 3 4 x 6 */ - int channels[]={1,0,3,1,2,0,4}; - png_alloc_size_t idat_limit = PNG_UINT_31_MAX; - size_t row_factor = - (png_ptr->width * channels[png_ptr->color_type] * - (png_ptr->bit_depth > 8? 2: 1) - + 1 + (png_ptr->interlaced? 6: 0)); - if (png_ptr->height > PNG_UINT_32_MAX/row_factor) - idat_limit=PNG_UINT_31_MAX; - else - idat_limit = png_ptr->height * row_factor; - row_factor = row_factor > 32566? 32566 : row_factor; - idat_limit += 6 + 5*(idat_limit/row_factor+1); /* zlib+deflate overhead */ - idat_limit=idat_limit < PNG_UINT_31_MAX? idat_limit : PNG_UINT_31_MAX; - limit = limit < idat_limit? idat_limit : limit; - } - - if (length > limit) - { - png_debug2(0," length = %lu, limit = %lu", - (unsigned long)length,(unsigned long)limit); - png_chunk_error(png_ptr, "chunk data is too large"); - } -} - -/* This is the known chunk table; it contains an entry for each supported - * chunk. - */ -static const struct -{ - void (*handle)(png_structrp png_ptr, png_infop info_ptr); - png_uint_32 name; - unsigned int before :5; - unsigned int after :5; -} -png_known_chunks[] = -/* To make the code easier to write the following defines are used, note that - * before_end should never trip - it would indicate that libpng attempted to - * read beyond the IEND chunk. - * - * 'within_IDAT' is used for IDAT chunks; PNG_AFTER_IDAT must not be set, but - * PNG_HAVE_IDAT may be set. - */ -#define before_end PNG_HAVE_IEND /* Should be impossible */ -#define within_IDAT (before_end+PNG_AFTER_IDAT) -#define before_IDAT (within_IDAT+PNG_HAVE_IDAT) -#define before_PLTE (before_IDAT+PNG_HAVE_PLTE) -#define before_start (before_PLTE+PNG_HAVE_IHDR) -#define at_start 0 -#define after_start PNG_HAVE_IHDR -#define after_PLTE (after_start+PNG_HAVE_PLTE) /* NOTE: PLTE optional */ -#define after_IDAT (after_PLTE+PNG_AFTER_IDAT) /* NOTE: PLTE optional */ - -/* See pngchunk.h for how this works: */ -#define PNG_CHUNK_END(n, c1, c2, c3, c4, before, after)\ - { png_handle_ ## n, png_ ##n, before, after } -#define PNG_CHUNK(n, c1, c2, c3, c4, before, after)\ - PNG_CHUNK_END(n, c1, c2, c3, c4, before, after), -#define PNG_CHUNK_BEGIN(n, c1, c2, c3, c4, before, after)\ - PNG_CHUNK_END(n, c1, c2, c3, c4, before, after), -{ -# include "pngchunk.h" -}; -#undef PNG_CHUNK_START -#undef PNG_CHUNK -#undef PNG_CHUNK_END - -#define C_KNOWN ((sizeof png_known_chunks)/(sizeof png_known_chunks[0])) - -/* See: scripts/chunkhash.c for code to generate this. This reads the same - * description file (pngchunk.h) as is included above. Whenever - * that file is changed chunkhash needs to be re-run to generate the lines - * following this comment. - * - * PNG_CHUNK_HASH modifes its argument and returns an index. png_chunk_index is - * a function which does the same thing without modifying the value of the - * argument. Both macro and function always return a valid index; to detect - * known chunks it is necessary to check png_known_chunks[index].name against - * the hashed name. - */ -static const png_byte png_chunk_lut[64] = -{ - 10, 20, 7, 3, 0, 23, 8, 0, 0, 11, 24, 0, 0, 0, 0, 4, - 12, 0, 0, 0, 13, 0, 0, 0, 25, 0, 0, 0, 2, 0, 0, 0, - 0, 6, 17, 0, 15, 0, 5, 19, 26, 0, 0, 0, 18, 0, 0, 9, - 1, 0, 21, 0, 22, 14, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0 -}; - -#define PNG_CHUNK_HASH(n)\ - png_chunk_lut[0x3f & (((n += n >> 2),n += n >> 8),n += n >> 16)] - -static png_byte -png_chunk_index(png_uint_32 name) -{ - name += name >> 2; - name += name >> 8; - name += name >> 16; - return png_chunk_lut[name & 0x3f]; -} - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -/* Mark a known chunk to be handled as unknown. */ -void /*PRIVATE*/ -png_cache_known_unknown(png_structrp png_ptr, png_const_bytep add, int keep) - /* Update the png_struct::known_unknown bit cache which stores whether each - * known chunk should be treated as unknown. - * - * This cache exists to avoid doing the search loop on every chunk while - * handling chunks. This code is only ever used if unknown handling is - * invoked, and the loop is isolated code; the function is called from - * add_one_chunk in pngset.c once for each unknown and while this is - * happening no other code is being run in this thread. - */ -{ - /* The cache only stores whether or not to handle the chunk; specifically - * whether or not keep is 0. - */ - png_uint_32 name = PNG_CHUNK_FROM_STRING(add); - - debug(PNG_HANDLE_CHUNK_AS_DEFAULT == 0 && C_KNOWN <= 32); - - /* But do not treat IHDR or IEND as unknown. This is historical; it - * always was this way, it's not clear if PLTE can always safely be - * treated as unknown, but it is allowed. - */ - if (name != png_IHDR && name != png_IEND) - { - png_byte i = png_chunk_index(name); - - if (png_known_chunks[i].name == name) - { - { - if (keep != PNG_HANDLE_CHUNK_AS_DEFAULT) - { - png_ptr->known_unknown |= 1U << i; - -# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED - if (keep == PNG_HANDLE_CHUNK_ALWAYS || - (keep == PNG_HANDLE_CHUNK_IF_SAFE && - PNG_CHUNK_ANCILLARY(name))) - png_ptr->save_unknown |= 1U << i; - - else /* PNG_HANDLE_CHUNK_NEVER || !SAFE */ - png_ptr->save_unknown &= ~(1U << i); -# endif /* SAVE_UNKNOWN_CHUNKS */ - } - - else - png_ptr->known_unknown &= ~(1U << i); - } - } - - /* else this is not a known chunk */ - } - - else /* 1.7.0: inform the app writer; */ - png_app_warning(png_ptr, "IHDR, IEND cannot be treated as unknown"); - -} -#endif /* HANDLE_AS_UNKNOWN */ - -/* Handle chunk position requirements in a consistent way. The chunk must - * come after 'after' and before 'before', either of which may be 0. If it - * does the function returns true, if it does not an appropriate chunk error - * is issued; benign for non-critical chunks, fatal for critical ones. - */ -static int -png_handle_position(png_const_structrp png_ptr, unsigned int chunk) -{ - unsigned int before = png_known_chunks[chunk].before; - unsigned int after = png_known_chunks[chunk].after; - -# ifdef PNG_ERROR_TEXT_SUPPORTED - png_const_charp error = NULL; -# endif /* ERROR_TEXT */ - - /* PLTE is optional with all color types except PALETTE, so for the other - * color types clear it from the 'after' bits. - * - * TODO: find some better way of recognizing the case where there is a PLTE - * and it follows after_PLTE chunks (see the complex stuff in handle_PLTE.) - */ - if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) - after &= PNG_BIC_MASK(PNG_HAVE_PLTE); - - if ((png_ptr->mode & before) == 0 && - (png_ptr->mode & after) == after) - return 1; - - /* The error case; do before first (it is normally more important) */ -# ifdef PNG_ERROR_TEXT_SUPPORTED - switch (before & -before) /* Lowest set bit */ - { - case 0: - /* Check 'after'; only one bit set. */ - switch (after) - { - case PNG_HAVE_IHDR: - error = "missing IHDR"; - break; - - case PNG_HAVE_PLTE: - error = "must occur after PLTE"; - break; - - case PNG_AFTER_IDAT: - error = "must come after IDAT"; - break; - - default: - impossible("invalid 'after' position"); - } - break; - - case PNG_HAVE_IHDR: - error = "must occur first"; - break; - - case PNG_HAVE_PLTE: - error = "must come before PLTE"; - break; - - case PNG_HAVE_IDAT: - error = "must come before IDAT"; - break; - - default: - impossible("invalid 'before' position"); - } -# endif /* ERROR_TEXT */ - - png_chunk_report(png_ptr, error, PNG_CHUNK_CRITICAL(png_ptr->chunk_name) ? - PNG_CHUNK_FATAL : PNG_CHUNK_ERROR); - return 0; -} - -/* This is the shared chunk handling function, used for both the sequential and - * progressive reader. - */ -png_chunk_op /* PRIVATE */ -png_find_chunk_op(png_structrp png_ptr) -{ - /* Given a chunk in png_struct::{chunk_name,chunk_length} validate the name - * and work out how it should be handled. This function checks the chunk - * location using png_struct::mode and will set the PNG_AFTER_IDAT bit if - * appropriate but otherwise makes no changes to the stream read state. - * - * png_chunk_skip Skip this chunk - * png_chunk_unknown This is an unknown chunk which can't be skipped; - * the unknown handler must be called with all the - * chunk data. - * png_chunk_process_all The caller must call png_chunk_handle to handle - * the chunk, when this call is made all the chunk - * data must be available to the handler. - * png_chunk_process_part The handler expects data in png_struct::zstream. - * {next,avail}_in and does not require all of the - * data at once (as png_read_process_IDAT). - */ - png_uint_32 chunk_name = png_ptr->chunk_name; - unsigned int mode = png_ptr->mode; - unsigned int index; - - /* This function should never be called if IEND has been set: - */ - debug((mode & PNG_HAVE_IEND) == 0); - - /* IDAT logic: we are only *after* IDAT when we start reading the first - * following (non-IDAT) chunk, this may already have been set in the IDAT - * handling code, but if IDAT is handled as unknown this doesn't happen. - */ - if (chunk_name != png_IDAT && (mode & PNG_HAVE_IDAT) != 0) - mode = png_ptr->mode |= PNG_AFTER_IDAT; - - index = png_chunk_index(chunk_name); - - if (png_known_chunks[index].name == chunk_name) - { - /* Known chunks have a position requirement; check it, badly positioned - * chunks that do not error out in png_handle_position are simply skipped. - * - * API CHANGE: libpng 1.7.0: prior versions of libpng did not check - * ordering requirements for known chunks where the support for reading - * them had been configured out of libpng. This seems dangerous; the - * user chunk callback could still see them and crash as a result. - */ - if (!png_handle_position(png_ptr, index)) - return png_chunk_skip; - - /* Do the mode update. - * - * API CHANGE 1.7.0: the 'HAVE' flags are now consistently set *before* - * the chunk is handled. Previously only IDAT was handled this way. This - * can only affect an app that was previously handling PLTE itself in a - * callback, however this seems to be impossible. - */ - switch (chunk_name) - { - case png_IHDR: png_ptr->mode |= PNG_HAVE_IHDR; break; - case png_PLTE: png_ptr->mode |= PNG_HAVE_PLTE; break; - case png_IDAT: png_ptr->mode |= PNG_HAVE_IDAT; break; - case png_IEND: png_ptr->mode |= PNG_HAVE_IEND; break; - default: break; - } - -# ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - /* A known chunk may still be treated as unknown. Check for that. */ - if (!((png_ptr->known_unknown >> index) & 1U)) -# endif /* HANDLE_AS_UNKNOWN */ - { - /* This is a known chunk that is not being treated as unknown. If - * it is IDAT then partial processing is done, otherwise (at present) - * the whole thing is processed in one shot - * - * TODO: this is a feature of the legacy use of the sequential read - * code in the handlers, fix this. - */ - if (chunk_name == png_IDAT) - return png_chunk_process_part; - - /* Check for a known chunk where support has been compiled out of - * libpng. We know it cannot be a critical chunk; support for those - * cannot be removed. - */ - if (png_known_chunks[index].handle != NULL) - return png_chunk_process_all; - -# ifdef PNG_READ_USER_CHUNKS_SUPPORTED - if (png_ptr->read_user_chunk_fn != NULL) - return png_chunk_unknown; -# endif /* READ_USER_CHUNKS */ - -# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED - /* There is no per-chunk special handling set for this chunk - * (because of the test on known_unknown above) so only the - * default unknown handling behavior matters. We skip the chunk - * if the behavior is 'NEVER' or 'DEFAULT'. This is irrelevant - * if SAVE_UNKNOWN_CHUNKS is not supported. - */ - if (png_ptr->unknown_default > PNG_HANDLE_CHUNK_NEVER) - return png_chunk_unknown; -# endif /* SAVE_UNKNOWN_CHUNKS */ - - return png_chunk_skip; - } - -# ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - else - { - /* Else this is a known chunk that is being treated as unknown. If - * there is a user callback the whole shebang is required: - */ -# ifdef PNG_READ_USER_CHUNKS_SUPPORTED - if (png_ptr->read_user_chunk_fn != NULL) - return png_chunk_unknown; -# endif /* READ_USER_CHUNKS */ - - /* No user callback, there is a possibility that we can skip this - * chunk: - */ -# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED - if ((png_ptr->save_unknown >> index) & 1U) - return png_chunk_unknown; -# endif /* SAVE_UNKNOWN_CHUNKS */ - - /* If this is a critical chunk and IDAT is not being skipped then - * this is an error. The only possibility here is PLTE on an - * image which is palette mapped. If the app ignores this error - * then there will be a more definate one in png_handle_unknown. - */ - if (chunk_name == png_PLTE && - png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - png_app_error(png_ptr, "skipping PLTE on palette image"); - - return png_chunk_skip; - } -# endif /* HANDLE_AS_UNKNOWN */ - } - - else /* unknown chunk */ - { - /* The code above implicitly validates the chunk name, however if a chunk - * name/type is not recognized it is necessary to validate it to ensure - * that the PNG stream isn't hopelessly damaged: - */ - png_check_chunk_name(png_ptr, chunk_name); - -# ifdef PNG_READ_USER_CHUNKS_SUPPORTED - if (png_ptr->read_user_chunk_fn != NULL) - return png_chunk_unknown; -# endif /* READ_USER_CHUNKS */ - -# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED - /* There may be per-chunk handling, otherwise the default is used, this - * is the one place where the list needs to be searched: - */ - { - int keep = png_chunk_unknown_handling(png_ptr, chunk_name); - - if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT) - keep = png_ptr->unknown_default; - - if (keep == PNG_HANDLE_CHUNK_ALWAYS || - (keep == PNG_HANDLE_CHUNK_IF_SAFE && - PNG_CHUNK_ANCILLARY(chunk_name))) - return png_chunk_unknown; - } -# endif /* SAVE_UNKNOWN_CHUNKS */ - - /* The chunk will be skipped so it must not be a critical chunk, unless - * IDATs are being skipped too. - */ - if (PNG_CHUNK_CRITICAL(chunk_name) -# ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - && !png_IDATs_skipped(png_ptr) -# endif /* HANDLE_AS_UNKNOWN */ - ) - png_chunk_error(png_ptr, "unhandled critical chunk"); - - return png_chunk_skip; - } -} - -void /* PRIVATE */ -png_handle_chunk(png_structrp png_ptr, png_inforp info_ptr) - /* The chunk to handle is in png_struct::chunk_name,chunk_length. - * - * NOTE: at present it is only valid to call this after png_find_chunk_op - * has returned png_chunk_process_all and all the data is available for - * png_handle_chunk (via the libpng read callback.) - */ -{ - png_uint_32 chunk_name = png_ptr->chunk_name; - unsigned int index = png_chunk_index(chunk_name); - - /* So this must be true: */ - affirm(png_known_chunks[index].name == chunk_name && - png_known_chunks[index].handle != NULL); - - png_known_chunks[index].handle(png_ptr, info_ptr); -} - -static void -copy_row(png_const_structrp png_ptr, png_bytep dp, png_const_bytep sp, - png_uint_32 x/*in INPUT*/, png_uint_32 width/*of INPUT*/, int clear) - /* Copy the row in row_buffer; this is the 'simple' case of combine_row - * where no adjustment to the pixel spacing is required. - */ -{ - png_copy_row(png_ptr, dp, sp, x, width, -# ifdef PNG_TRANSFORM_MECH_SUPPORTED - png_ptr->row_bit_depth * PNG_FORMAT_CHANNELS(png_ptr->row_format), -# else - PNG_PIXEL_DEPTH(*png_ptr), -# endif - clear/*clear partial byte at end of row*/, 1/*sp -> dp[x]*/); -} - -#ifdef PNG_READ_INTERLACING_SUPPORTED -static void -combine_row(png_const_structrp png_ptr, png_bytep dp, png_const_bytep sp, - png_uint_32 x/*in INPUT*/, png_uint_32 width/*of INPUT*/, int display) - /* 1.7.0: API CHANGE: prior to 1.7.0 read de-interlace was done in two steps, - * the first would expand a narrow pass by replicating pixels according to - * the inter-pixel spacing of the pixels from the pass in the image. It did - * not take account of any offset from the start of the image row of the - * first pixel. The second step happened in png_combine_row where the result - * was merged into the output rows. - * - * In 1.7.0 this is no longer done. Instead all the work happens here. This - * is only an API change for the progressive reader if the app didn't call - * png_combine_row, but rather expected an expanded row. It's not obvious - * why any user of the progressive reader would want this, particularly given - * the weird non-offseting of the start in the original - * 'png_do_read_interlace'; the behavior was completely undocumented. - * - * In 1.7.0 combine_row does all the work. It expects a raw uncompressed, - * de-filtered, transformed row and it either copies it if: - * - * 1) It is not interlaced. - * 2) libpng isn't handling the de-interlace. - * 3) This is pass 7 (i.e. '6' using the libpng 0-based numbering). - * - * The input data comes from png_struct and sp: - * - * sp[width(pixels)]; the row data from input[x(pixels)...] - * png_struct::pass; the pass - * png_struct::row_number; the row number in the *image* - * png_struct::row_bit_depth, - * png_struct::row_format; the pixel format, if TRANSFORM_MECH, else: - * png_struct::bit_depth, - * png_struct::color_type; the pixel format otherwise - * - * The destination pointer (but not size) and how to handle intermediate - * passes are arguments to the API. The destination is the pointer to the - * entire row buffer, not just the part from output[x] on. 'display' is - * interpreted as: - * - * 0: only overwrite destination pixels that will correspond to the source - * pixel in the final image. 'sparkle' mode. - * 1: overwrite the corresponding destination pixel and all following - * pixels (horizontally and, eventually, vertically) that will come - * from *later* passes. 'block' mode. - */ -{ - const unsigned int pass = png_ptr->pass; - - png_debug(1, "in png_combine_row"); - - /* Factor out the copy case first, the 'display' argument is irrelevant in - * these cases: - */ - if (!png_ptr->do_interlace || png_ptr->pass == 6) - { - copy_row(png_ptr, dp, sp, x, width, 0/*do not clear*/); - return; - } - - else /* not a simple copy */ - { - const unsigned int pixel_depth = -# ifdef PNG_TRANSFORM_MECH_SUPPORTED - png_ptr->row_bit_depth * PNG_IMAGE_PIXEL_CHANNELS(png_ptr->row_format); -# else - PNG_PIXEL_DEPTH(*png_ptr); -# endif - png_uint_32 row_width = png_ptr->width; /* output width */ - /* The first source pixel is written to PNG_COL_FROM_PASS of the - * destination: - */ - png_uint_32 dx = PNG_COL_FROM_PASS_COL(x, pass); - /* The corresponding offset within the 8x8 block: */ - const unsigned int dstart = dx & 0x7U; - /* Find the first pixel written in any 8x8 block IN THIS PASS: */ - const unsigned int pass_start = PNG_PASS_START_COL(pass); - /* Subsequent pixels are written PNG_PASS_COL_OFFSET further on: */ - const unsigned int doffset = PNG_PASS_COL_OFFSET(pass); - /* In 'block' mode when PNG_PASS_START_COL(pass) is 0 (PNG passes 1,3,5,7) - * the same pixel is replicated doffset times, when PNG_PASS_START_COL is - * non-zero (PNG passes 2,4,6) it is replicated PNG_PASS_START_COL times. - * For 'sparkle' mode only one copy of the pixel is written: - */ - unsigned int drep = display ? (pass_start ? pass_start : doffset) : 1; - - /* Standard check for byte alignment */ - debug(((x * pixel_depth/*OVERFLOW OK*/) & 0x7U) == 0U); - - /* The caller should have excluded the narrow cases: */ - affirm(row_width > dx); - row_width -= dx; - /* Advance dp to the start of the 8x8 block containing the first pixel to - * write, adjust dx to be an offset within the block: - */ - dp += png_calc_rowbytes(png_ptr, pixel_depth, dx & ~0x7U); - dx &= 0x7U; - - /* So each source pixel sp[i] is written to: - * - * dp[dstart + i*doffset]..dp[dstart + i*doffset + (drep-1)] - * - * Until we get to row_width. This is easy for pixels that are 8 or more - * bits deep; whole bytes are read and written, slightly more difficult - * when pixel_depth * drep is at least 8 bits, because then dstart * - * pixel_depth will always be a whole byte and most complex when source - * and destination require sub-byte addressing. - * - * Cherry pick the easy cases: - */ - if (pixel_depth > 8U) - { - /* Convert to bytes: */ - const unsigned int pixel_bytes = pixel_depth >> 3; - - dp += dstart * pixel_bytes; - - for (;;) - { - unsigned int c; - - if (drep > row_width) - drep = row_width; - - for (c=0U; c= row_width) - break; - - row_width -= doffset; - dp += (doffset-drep) * pixel_bytes; - sp += pixel_bytes; - } - } - - else if (pixel_depth == 8U) - { - /* Optimize the common 1-byte per pixel case (typical case for palette - * mapped images): - */ - dp += dstart; - - for (;;) - { - if (drep > row_width) - drep = row_width; - - memset(dp, *sp++, drep); - - if (doffset >= row_width) - break; - - row_width -= doffset; - dp += doffset; - } - } - - else /* pixel_depth < 8 */ - { - /* Pixels are 1, 2 or 4 bits in size. */ - unsigned int spixel = *sp++; - unsigned int dbrep = pixel_depth * drep; - unsigned int spos = 0U; -# ifdef PNG_READ_PACKSWAP_SUPPORTED - const int lsb = - (png_ptr->row_format & PNG_FORMAT_FLAG_SWAPPED) != 0; -# endif /* READ_PACKSWAP */ - - if (dbrep >= 8U) - { - /* brep must be greater than 1, the destination does not require - * sub-byte addressing except, maybe, at the end. - * - * db is the count of bytes required to replicate the source pixel - * drep times. - */ - debug((dbrep & 7U) == 0U); - dbrep >>= 3; - debug((dstart * pixel_depth & 7U) == 0U); - dp += (dstart * pixel_depth) >> 3; - - for (;;) - { - /* Fill a byte with copies of the next pixel: */ - unsigned int spixel_rep = spixel; - -# ifdef PNG_READ_PACKSWAP_SUPPORTED - if (lsb) - spixel_rep >>= spos; - else -# endif /* READ_PACKSWAP */ - spixel_rep >>= (8U-pixel_depth)-spos; - - switch (pixel_depth) - { - case 1U: spixel_rep &= 1U; spixel_rep |= spixel_rep << 1; - /*FALL THROUGH*/ - case 2U: spixel_rep &= 3U; spixel_rep |= spixel_rep << 2; - /*FALL THROUGH*/ - case 4U: spixel_rep &= 15U; spixel_rep |= spixel_rep << 4; - /*FALL THROUGH*/ - default: break; - } - - /* This may leave some pixels unwritten when there is a partial - * byte write required at the end: - */ - if (drep > row_width) - drep = row_width, dbrep = (pixel_depth * drep) >> 3; - - memset(dp, spixel_rep, dbrep); - - if (doffset >= row_width) - { - /* End condition; were all 'drep' pixels written at the end? - */ - drep = (pixel_depth * drep - (dbrep << 3)); - - if (drep) - { - unsigned int mask; - - debug(drep < 8U); - dp += dbrep; - - /* Set 'mask' to have 0's where *dp must be overwritten - * with spixel_rep: - */ -# ifdef PNG_READ_PACKSWAP_SUPPORTED - if (lsb) - mask = 0xff << drep; - else -# endif /* READ_PACKSWAP */ - mask = 0xff >> drep; - - *dp = PNG_BYTE((*dp & mask) | (spixel_rep & ~mask)); - } - - break; - } - - row_width -= doffset; - dp += (doffset * pixel_depth) >> 3; - spos += pixel_depth; - if (spos == 8U) - spixel = *sp++, spos = 0U; - } /* for (;;) */ - } /* pixel_depth * drep >= 8 */ - - else /* pixel_depth * drep < 8 */ - { - /* brep may be 1, pixel_depth may be 1, 2 or 4, dbrep is the number - * of bits to set. - */ - unsigned int bstart = dstart * pixel_depth; /* in bits */ - unsigned int dpixel; - - dp += bstart >> 3; - bstart &= 7U; - dpixel = *dp; - - /* dpixel: current *dp, being modified - * bstart: bit offset within dpixel - * drep: pixel size to write (used as a check against row_width) - * doffset: pixel step to next written destination - * - * spixel: current *sp, being read, and: - * spixel_rep: current pixel, replicated to fill a byte - * spos: bit offset within spixel - * - * Set dbrep to a mask for the bits to set: - */ - dbrep = (1U<>= spos; - else -# endif /* READ_PACKSWAP */ - spixel_rep >>= (8U-pixel_depth)-spos; - - switch (pixel_depth) - { - case 1U: spixel_rep &= 1U; spixel_rep |= spixel_rep << 1; - /*FALL THROUGH*/ - case 2U: spixel_rep &= 3U; spixel_rep |= spixel_rep << 2; - /*FALL THROUGH*/ - case 4U: spixel_rep &= 15U; spixel_rep |= spixel_rep << 4; - /*FALL THROUGH*/ - default: break; - } - - /* This may leave some pixels unwritten when there is a partial - * byte write required at the end: - */ - if (drep > row_width) - drep = row_width, dbrep = (1U<<(pixel_depth*drep))-1U; - - { - unsigned int mask; - - /* Mask dbrep bits at bstart: */ -# ifdef PNG_READ_PACKSWAP_SUPPORTED - if (lsb) - mask = bstart; - else -# endif /* READ_PACKSWAP */ - mask = (8U-pixel_depth)-bstart; - mask = dbrep << mask; - - dpixel &= ~mask; - dpixel |= spixel_rep & mask; - } - - if (doffset >= row_width) - { - *dp = PNG_BYTE(dpixel); - break; - } - - row_width -= doffset; - bstart += doffset * pixel_depth; - - if (bstart >= 8U) - { - *dp = PNG_BYTE(dpixel); - dp += bstart >> 3; - bstart &= 7U; - dpixel = *dp; - } - - spos += pixel_depth; - if (spos == 8U) - spixel = *sp++, spos = 0U; - } /* for (;;) */ - } /* pixel_depth * drep < 8 */ - } /* pixel_depth < 8 */ - } /* not a simple copy */ -} - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -void PNGAPI -png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row, - png_const_bytep new_row) -{ - /* new_row is a flag here - if it is NULL then the app callback was called - * from an empty row (see the calls to png_struct::row_fn above), otherwise - * it must be png_struct::transformed_row - */ - if (png_ptr != NULL && new_row != NULL) - { - if (new_row != png_ptr->row_buffer -# ifdef PNG_TRANSFORM_MECH_SUPPORTED - && new_row != png_ptr->transformed_row -# endif /* TRANSFORM_MECH */ - ) - png_app_error(png_ptr, "invalid call to png_progressive_combine_row"); - else - { - png_uint_32 width = png_ptr->width; - - if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) - { - const unsigned int pass = png_ptr->pass; - width = PNG_PASS_COLS(width, pass); - } - - combine_row(png_ptr, old_row, new_row, 0U, width, 1/*blocky display*/); - } - } -} -#endif /* PROGRESSIVE_READ */ -#else /* !READ_INTERLACING */ - /* No read deinterlace support, so 'combine' always reduces to 'copy', there - * is no 'display' argument: - */ -# define combine_row(pp, dp, sp, x, w, display)\ - copy_row(pp, dp, sp, x, w, 0/*!clear*/) -#endif /* !READ_INTERLACING */ - -static void -png_read_filter_row_sub(png_alloc_size_t row_bytes, unsigned int bpp, - png_bytep row, png_const_bytep prev_row, png_const_bytep prev_pixels) -{ - while (row_bytes >= bpp) - { - unsigned int i; - - for (i=0; i 0) - { - *row = PNG_BYTE(*row + *prev_row); - ++row; - ++prev_row; - --row_bytes; - } - - PNG_UNUSED(bpp) - PNG_UNUSED(prev_pixels) -} - -static void -png_read_filter_row_avg(png_alloc_size_t row_bytes, unsigned int bpp, - png_bytep row, png_const_bytep prev_row, png_const_bytep prev_pixels) -{ - while (row_bytes >= bpp) - { - unsigned int i; - - for (i=0; iread_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub; - pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up; - pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg; - if (bpp == 1) - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth_1byte_pixel; - else - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth_multibyte_pixel; - -#ifdef PNG_FILTER_OPTIMIZATIONS - /* To use this define PNG_FILTER_OPTIMIZATIONS as the name of a function to - * call to install hardware optimizations for the above functions; simply - * replace whatever elements of the pp->read_filter[] array with a hardware - * specific (or, for that matter, generic) optimization. - * - * To see an example of this examine what configure.ac does when - * --enable-arm-neon is specified on the command line. - */ - PNG_FILTER_OPTIMIZATIONS(pp, bpp); -#endif -} - -/* This is an IDAT specific wrapper for png_zlib_inflate; the input is already - * in png_ptr->zstream.{next,avail}_in however the output uses the full - * capabilities of png_zlib_inflate, returning a byte count of bytes read. - * This is just a convenience for IDAT processing. - * - * NOTE: this function works just fine after the zstream has ended, it just - * fills the buffer with zeros (outputing an error message once.) - */ -static png_alloc_size_t -png_inflate_IDAT(png_structrp png_ptr, int finish, - /* OUTPUT: */ png_bytep output, png_alloc_size_t output_size) -{ - /* Expect Z_OK if !finsh and Z_STREAM_END if finish; if Z_STREAM_END is - * delivered when finish is not set the IDAT stream is truncated, if Z_OK is - * delivered when finish is set this is harmless and indicates that the - * stream end code has not been read. - * - * finish should be set as follows: - * - * 0: not reading the last row, stream not expected to end - * 1: reading the last row, stream expected to end - * 2: looking for stream end after the last row has been read, expect no - * more output and stream end. - */ - png_alloc_size_t original_size = output_size; - int ret = Z_STREAM_END; /* In case it ended ok before. */ - - if (!png_ptr->zstream_ended) - { - png_const_bytep next_in = png_ptr->zstream.next_in; - png_uint_32 avail_in = png_ptr->zstream.avail_in; - - ret = png_zlib_inflate(png_ptr, png_IDAT, finish, - &next_in, &avail_in, &output, &output_size/*remaining*/); - - debug(next_in == png_ptr->zstream.next_in); - debug(avail_in == png_ptr->zstream.avail_in); - debug(output == png_ptr->zstream.next_out); - /* But zstream.avail_out may be truncated to uInt */ - - switch (ret) - { - case Z_STREAM_END: - /* The caller must set finish on the last row of the image (not - * the last row of the pass!) - */ - debug(png_ptr->zstream_ended); - - if (!finish) /* early end */ - break; - - if (output_size > 0) /* incomplete read */ - { - if (finish == 2) /* looking for end; it has been found */ - return original_size - output_size; - - /* else those bytes are really needed: */ - break; - } - - /* else: FALL THROUGH: success */ - - case Z_BUF_ERROR: - /* this is the success case: output or input is empty: */ - original_size -= output_size; /* bytes written */ - - if (output_size > 0) - { - /* Some output still needed; if the next chunk is known - * to not be an IDAT then this is the truncation case. - */ - affirm(avail_in == 0); - - if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) - { - /* Zlib doesn't know we are out of data, so this must be - * done here: - */ - png_ptr->zstream_ended = 1; - break; - } - } - - return original_size; /* bytes written */ - - default: - /* error */ - break; - } - - /* The 'ended' flag should always be set if we get here, the success - * cases where the LZ stream hasn't reached an end or an error leave - * the function at the return above. - */ - debug(png_ptr->zstream_ended); - } - - /* This is the error return case; there was missing data, or an error. - * Either continue with a warning (once; hence the zstream_error flag) - * or png_error. - */ - if (!png_ptr->zstream_error) /* first time */ - { -#ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED - switch (png_ptr->IDAT_error_action) - { - case PNG_ERROR: - if(!strncmp(png_ptr->zstream.msg,"incorrect data check",20)) - { - if (png_ptr->current_crc != crc_quiet_use) - png_chunk_warning(png_ptr, "ADLER32 checksum mismatch"); - } - - else - { - png_chunk_error(png_ptr, png_ptr->zstream.msg); - } - break; - - case PNG_WARN: - png_chunk_warning(png_ptr, png_ptr->zstream.msg); - break; - - default: /* ignore */ - /* Keep going */ - break; - } -#else - { - if(!strncmp(png_ptr->zstream.msg,"incorrect data check",20)) - png_chunk_warning(png_ptr, "ADLER32 checksum mismatch"); - else - png_chunk_error(png_ptr, png_ptr->zstream.msg); - } -#endif /* !BENIGN_ERRORS */ - - /* And prevent the report about too many IDATs on streams with internal - * LZ errors: - */ - png_ptr->zstream_error = 1; - } - - /* This is the error recovery case; fill the buffer with zeros. This is - * safe because it makes the filter byte 'NONE' and the row fairly innocent. - */ - memset(output, 0, output_size); - return original_size; -} - -/* SHARED IDAT HANDLING. - * - * This is the 1.7+ common read code; shared by both the progressive and - * sequential readers. - */ -/* Initialize the row buffers, etc. */ -void /* PRIVATE */ -png_read_start_IDAT(png_structrp png_ptr) -{ -# ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - /* This won't work at all if the app turned on unknown handling for IDAT - * chunks; the first IDAT has already been consumed! - */ - if (png_ptr->known_unknown & 1U) - png_error(png_ptr, "Attempt to read image with unknown IDAT"); -# endif /* HANDLE_AS_UNKNOWN */ - - /* This is a missing read of the header information; we still haven't - * countered the first IDAT chunk. This can only happen in the sequential - * reader if the app didn't call png_read_info. - */ - if (png_ptr->chunk_name != png_IDAT) - png_error(png_ptr, "Missing call to png_read_info"); - - /* Two things need to happen: first work out the effect of any - * transformations (if supported) on the row size, second, allocate - * row_buffer and claim the zstream. - */ - png_init_row_info(png_ptr); - - /* Now allocate the row buffer and, if that succeeds, claim the zstream. - */ - png_ptr->row_buffer = png_voidcast(png_bytep, png_malloc(png_ptr, - png_calc_rowbytes(png_ptr, PNG_PIXEL_DEPTH(*png_ptr), png_ptr->width))); - - if (png_inflate_claim(png_ptr, png_IDAT) != Z_OK) - png_error(png_ptr, png_ptr->zstream.msg); -} - -/* The process function gets called when there is some IDAT data to process - * and it just does the right thing with it. The zstream must have been claimed - * (owner png_IDAT) and the input data is in zstream.{next,avail}_in. The - * output next_{in,out} must not be changed by the caller; it is used - * internally. - * - * Result codes are as follows: - * - * png_row_incomplete: Insufficient IDAT data (from zstream) was present to - * process the next row. zstream.avail_in will be 0. - * png_row_process: A new row is available in the input buffer, it should be - * handled before the next call (if any) to this function. - * png_row_repeat: For interlaced images (only) this row is not in the pass, - * however the existing buffer may be displayed in lieu; if doing the - * 'blocky' (not 'sparkle') display the row should be displayed, - * otherwise treat as: - * png_row_skip: For interlaced images (only) the interlace pass has no data - * appropriate to this row, it should be skipped. - * - * In both of the two cases zstream.avail_in may be non-0, indicating that some - * IDAT data at zstream.next_in remains to be consumed. This data must be - * preserved and preset at the next call to the function. - * - * The function may also call png_error if an unrecoverable error occurs. - * - * The caller passes in a callback function and parameter to be called when row - * data is available. The callback is called repeatedly for each row to handle - * all the transformed row data. - */ -png_row_op /*PRIVATE*/ -png_read_process_IDAT(png_structrp png_ptr, png_bytep transformed_row, - png_bytep display_row, int save_row) -{ - /* Common sub-expressions. These are all constant across the whole PNG, but - * are recalculated here each time because this is fast and it only happens - * once per row + once per block of input data. - */ - const unsigned int max_pixels = png_max_pixel_block(png_ptr); - const unsigned int pixel_depth = png_ptr->row_input_pixel_depth; - /* The number of input bytes read each time (cannot overflow because it is - * limited by PNG_ROW_BUFFER_SIZE): - */ - const unsigned int input_byte_count = (max_pixels * pixel_depth) / 8U; - const unsigned int bpp = (pixel_depth+0x7U)>>3; - const png_uint_32 width = png_ptr->width; - const unsigned int interlaced = png_ptr->interlaced != PNG_INTERLACE_NONE; - - png_uint_32 row_number = png_ptr->row_number; - unsigned int pass = png_ptr->pass; - enum anonymous { - start_of_row = 0U, /* at the start of the row; read a filter byte */ - need_row_bytes = 2U, /* reading the row */ - processing_row = 3U /* control returned to caller to process the row */ - } state = png_upcast(enum anonymous, png_ptr->row_state); - - /* The caller is responsible for calling png_read_start_IDAT: */ - affirm(png_ptr->zowner == png_IDAT); - - /* Basic sanity checks: */ - affirm(pixel_depth > 0U && pixel_depth <= 64U && - input_byte_count <= PNG_ROW_BUFFER_SIZE && - pixel_depth <= 8U*PNG_MAX_PIXEL_BYTES); - - for (;;) switch (state) - { - png_alloc_size_t row_bytes_processed; - png_alloc_size_t bytes_read; /* bytes in pixel_buffer */ - png_uint_32 pass_width; - png_byte row_filter; - union - { - PNG_ROW_BUFFER_ALIGN_TYPE force_buffer_alignment; - png_byte buffer[16U]; - } previous_pixels; - union - { - PNG_ROW_BUFFER_ALIGN_TYPE force_buffer_alignment; - png_byte buffer[PNG_ROW_BUFFER_SIZE]; - } pixel_buffer; - - case need_row_bytes: - /* The above variables need to be restored: */ - row_bytes_processed = png_ptr->row_bytes_read; - bytes_read = row_bytes_processed % input_byte_count; - row_bytes_processed -= bytes_read; - - pass_width = width; - if (interlaced) - pass_width = PNG_PASS_COLS(pass_width, pass); - - memcpy(pixel_buffer.buffer, png_ptr->scratch, bytes_read); - memcpy(previous_pixels.buffer, png_ptr->scratch+bytes_read, 2*bpp); - row_filter = png_ptr->scratch[bytes_read+2*bpp]; - - goto pixel_loop; - - case processing_row: - /* When there was a previous row (not at the start of the image) the - * row number needs to be updated and, possibly, the pass number. - */ - if (++row_number == png_ptr->height) - { - affirm(interlaced && pass < 6); /* else too many calls */ - - /* Start a new pass: there never is a pending filter byte so it - * is always necessary to read the filter byte of the next row. - */ - png_ptr->pass = ++pass & 0x7; - row_number = 0U; - } /* end of pass */ - - png_ptr->row_number = row_number; - - /* This is a new row, but it may not be in the pass data so it - * may be possible to simply return control to the caller to - * skip it or use the previous row as appropriate. - */ - if (interlaced) - { - debug(pass <= 6); - - /* This macro cannot overflow because the PNG width (and height) - * have already been checked to ensure that they are less than - * 2^31 (i.e. they are 31-bit values, not 32-bit values.) - */ - pass_width = PNG_PASS_COLS(width, pass); - - /* On average most rows are skipped, so do this first: */ - if (pass_width == 0 || - !PNG_ROW_IN_INTERLACE_PASS(row_number, pass)) - { - /* Using the PNG specification numbering (pass+1), passes 1, - * 2, 4, 6 contribute to all the rows in 'block' interlaced - * filling mode. Pass 3 contributes to four rows (5,6,7,8), - * pass 5 to two rows (3,4 then 7,8) and pass 7 only to one - * (the one on which it is processed). have_row must be set - * appropriately; it is set when a row is processed (end of - * this function) and remains set while the 'block' mode of - * interlace handling should reuse the previous row for this - * row. - * - * Each pass row can be used in a fixed number of rows, shown - * in 'rows' below, the '*' indicates that the row is actually - * in the pass, the '^' that the previous '*' row is used in - * block display update and the '@' that the pass doesn't - * contribte at all to that row in block display mode: - * - * PASS: 0 1 2 3 4 5 6 - * rows: 8 8 4 4 2 2 1 - * 0: * * @ * @ * @ - * 1: ^ ^ @ ^ @ ^ * - * 2: ^ ^ @ ^ * * @ - * 3: ^ ^ @ ^ ^ ^ * - * 4: ^ ^ * * @ * @ - * 5: ^ ^ ^ ^ @ ^ * - * 6: ^ ^ ^ ^ * * @ - * 7: ^ ^ ^ ^ ^ ^ * - * - * The '@' signs are the interesting thing, since we know that - * this row isn't present in the pass data. Rewriting the - * above table with '1' for '@', little endian (i.e. row 0 at - * the LSB end): - * - * row: 76543210 - * Pass 0: 00000000 0x00 [bit 3, 0x8 of row unset (always)] - * Pass 1: 00000000 0x00 - * Pass 2: 00001111 0x0F [bit 2, 0x4 of row unset] - * Pass 3: 00000000 0x00 - * Pass 4: 00110011 0x33 [bit 1, 0x2 of row unset] - * Pass 5: 00000000 0x00 - * Pass 6: 01010101 0x55 [bit 0, 0x1 of row unset] - * - * PNG_PASS_BLOCK_SKIP(pass, row) can be written two ways; - * - * As a shift and a mask: - * (0x55330F00 >> ((pass >> 1) + (row & 7))) & ~pass & 1 - * - * And, somewhat simpler, as a bit check on the low bits of - * row: - * - * ~((row) >> (3-(pass >> 1))) & ~pass & 1 - */ -# define PNG_PASS_BLOCK_SKIP(pass, row)\ - (~((row) >> (3U-((pass) >> 1))) & ~(pass) & 0x1U) - - /* Hence: */ - debug(png_ptr->row_state == processing_row); - return pass_width == 0 || PNG_PASS_BLOCK_SKIP(pass, - row_number) ? png_row_skip : png_row_repeat; - } /* skipped row */ - - /* processed; fall through to start_of_row */ - } /* interlaced */ - - /* FALL THROUGH */ - case start_of_row: - { - /* Read the filter byte for the next row, previous_pixels is just - * used as a temporary buffer; it is reset below. - */ - png_alloc_size_t cb = png_inflate_IDAT(png_ptr, 0/*finish*/, - previous_pixels.buffer, 1U); - - /* This can be temporary; it verifies the invariants on how - * png_inflate_IDAT updates the {next,avail}_out fields: - */ -#ifndef __COVERITY__ /* Suppress bogus Coverity complaint */ - debug(png_ptr->zstream.avail_out == 1-cb && - png_ptr->zstream.next_out == cb + previous_pixels.buffer); -#endif - - /* next_out points to previous_pixels, for security do this: */ - png_ptr->zstream.next_out = NULL; - png_ptr->zstream.avail_out = 0U; - - /* One byte, so we either got it or have to get more input data: */ - if (cb != 1U) - { - affirm(cb == 0U && png_ptr->zstream.avail_in == 0U); - png_ptr->row_state = start_of_row; - return png_row_incomplete; - } - } - - /* Check the filter byte. */ - row_filter = previous_pixels.buffer[0]; - if (row_filter >= PNG_FILTER_VALUE_LAST) - png_chunk_error(png_ptr, "invalid PNG filter"); - - /* These are needed for the filter check below: */ - pass_width = width; - if (interlaced) - pass_width = PNG_PASS_COLS(pass_width, pass); - - /* The filter is followed by the row data, but first check the - * filter byte; the spec requires that we invent an empty row - * if the first row of a pass requires it. - * - * Note that row_number is the image row. - */ - if (row_number == PNG_PASS_START_ROW(pass)) switch (row_filter) - { - case PNG_FILTER_VALUE_UP: - /* x-0 == x, so do this optimization: */ - row_filter = PNG_FILTER_VALUE_NONE; - break; - - case PNG_FILTER_VALUE_PAETH: - /* The Paeth predictor is always the preceding (leftwards) - * value, so this is the same as sub: - */ - row_filter = PNG_FILTER_VALUE_SUB; - break; - - case PNG_FILTER_VALUE_AVG: - /* It would be possible to 'invent' a new filter that did - * AVG using only the previous byte; it's 'SUB' of half the - * preceding value, but this seems pointless. Zero out the - * row buffer to make AVG work. - */ - memset(png_ptr->row_buffer, 0U, - PNG_ROWBYTES(pixel_depth, pass_width)); - break; - - default: - break; - } /* switch row_filter */ - - /* Always zero the 'previous pixel' out at the start of a row; this - * allows the filter code to ignore the row start. - */ - memset(previous_pixels.buffer, 0U, sizeof previous_pixels.buffer); - - row_bytes_processed = 0U; - bytes_read = 0U; - - pixel_loop: - /* At this point the following must be set correctly: - * - * row_bytes_processed: bytes processed so far - * pass_width: width of a row in this pass in pixels - * pixel_depth: depth in bits of a pixel - * bytes_read: count of filtered bytes in pixel_buffer - * row_filter: filter byte for this row - * previous_pixels[0]: pixel 'a' for the filter - * previous_pixels[1]: pixel 'c' for the filter - * pixel_buffer[]: bytes_read filtered bytes - * - * The code in the loop decompresses PNG_ROW_BUFFER_SIZE filterd pixels - * from the input, unfilters and transforms them, then saves them to - * png_struct::row_buffer[row_bytes_processed...]. - */ - { /* pixel loop */ - const png_alloc_size_t row_bytes = - PNG_ROWBYTES(pixel_depth, pass_width); - png_bytep row_buffer = png_ptr->row_buffer + row_bytes_processed; - unsigned int pixels; - png_uint_32 x; - - /* Sanity check for potential buffer overwrite: */ - affirm(row_bytes > row_bytes_processed); - - /* Work out the current pixel index of the pixel at the start of the - * row buffer: - */ - switch (pixel_depth) - { - case 1U: x = (png_uint_32)/*SAFE*/(row_bytes_processed << 3); - break; - case 2U: x = (png_uint_32)/*SAFE*/(row_bytes_processed << 2); - break; - case 4U: x = (png_uint_32)/*SAFE*/(row_bytes_processed << 1); - break; - case 8U: x = (png_uint_32)/*SAFE*/row_bytes_processed; - break; - default: x = (png_uint_32)/*SAFE*/(row_bytes_processed / bpp); - debug(row_bytes_processed % bpp == 0U); - break; - } - - for (pixels = max_pixels; x < pass_width; x += pixels) - { - if (pixels > pass_width - x) - pixels = (unsigned int)/*SAFE*/(pass_width - x); - - /* At the end of the image pass Z_FINISH to zlib to optimize the - * final read (very slightly, is this worth doing?) To do this - * work out if we are at the end. - */ - { - const png_uint_32 height = png_ptr->height; - - /* last_pass_row indicates that this is the last row in this - * pass (the test is optimized for the non-interlaced case): - */ - const int last_pass_row = row_number+1 >= height || - (interlaced && PNG_LAST_PASS_ROW(row_number,pass,height)); - - /* Set 'finish' if this is the last row in the last pass of - * the image: - */ - const int finish = last_pass_row && (!interlaced || - pass >= PNG_LAST_PASS(width, height)); - - const png_alloc_size_t bytes_to_read = - PNG_ROWBYTES(pixel_depth, pixels); - - png_alloc_size_t cb; - - affirm(bytes_to_read > bytes_read); - cb = png_inflate_IDAT(png_ptr, finish, - pixel_buffer.buffer + bytes_read, - bytes_to_read - bytes_read); - bytes_read += cb; - - if (bytes_read < bytes_to_read) - { - /* Fewer bytes were read than needed: we need to stash all - * the information required at pixel_loop in png_struct so - * that the need_row_bytes case can restore it when more - * input is available. - */ - debug(png_ptr->zstream.avail_in == 0U); - png_ptr->zstream.next_out = NULL; - png_ptr->zstream.avail_out = 0U; - - png_ptr->row_bytes_read = row_bytes_processed + bytes_read; - memcpy(png_ptr->scratch, pixel_buffer.buffer, bytes_read); - memcpy(png_ptr->scratch+bytes_read, previous_pixels.buffer, - 2*bpp); - png_ptr->scratch[bytes_read+2*bpp] = row_filter; - png_ptr->row_state = need_row_bytes; - return png_row_incomplete; - } - - debug(bytes_read == bytes_to_read); - } /* fill pixel_buffer */ - - /* The buffer is full or the row is complete but the calculation - * was done using the pixel count, so double check against the - * byte count here: - */ - implies(bytes_read != input_byte_count, - bytes_read == row_bytes - row_bytes_processed); - - /* At this point all the required information to process the next - * block of pixels in the row has been read from the input stream - * and the original, filtered, row data is held in pixel_buffer. - * - * Because the buffer will be transformed after the unfilter - * operation we require whole pixels: - */ - debug(bytes_read >= bpp && bytes_read % bpp == 0); - - if (row_filter > PNG_FILTER_VALUE_NONE) - { - /* This is checked in the read code above: */ - debug(row_filter < PNG_FILTER_VALUE_LAST); - - /* Lazy init of the read functions, which allows hand crafted - * optimizations for 'bpp' (which does not change.) - */ - if (png_ptr->read_filter[0] == NULL) - png_init_filter_functions(png_ptr, bpp); - - /* Pixels 'a' then 'c' are in previous_pixels, pixel 'b' is in - * row_buffer and pixel 'x' (filtered) is in pixel_buffer. - */ - png_ptr->read_filter[row_filter-1](bytes_read, bpp, - pixel_buffer.buffer, row_buffer, previous_pixels.buffer); - } /* do the filter */ - - /* Now pixel_buffer.buffer contains the *un*filtered bytes of the - * current row and row_buffer needs updating with these. First - * preserve pixels 'a' and 'c' for the next time round the loop - * (if necessary). - */ - if (bytes_read < row_bytes - row_bytes_processed) - { - debug(bytes_read == input_byte_count); - memcpy(previous_pixels.buffer/* pixel 'a' */, - pixel_buffer.buffer + bytes_read - bpp, bpp); - memcpy(previous_pixels.buffer+bpp/* pixel 'c' */, - row_buffer + bytes_read - bpp, bpp); - } - - /* Now overwrite the previous row pixels in row_buffer with the - * current row pixels: - */ - memcpy(row_buffer, pixel_buffer.buffer, bytes_read); - row_buffer += bytes_read; - row_bytes_processed += bytes_read; - bytes_read = 0U; /* for next buffer */ - - /* Any transforms can now be performed along with any output - * handling (copy or interlace handling). - */ -# ifdef PNG_TRANSFORM_MECH_SUPPORTED - if (png_ptr->transform_list != NULL) - { - unsigned int max_depth; - png_transform_control tc; - - png_init_transform_control(&tc, png_ptr); - - tc.width = pixels; - tc.sp = tc.dp = pixel_buffer.buffer; - - /* Run the list. It is ok if it doesn't end up doing - * anything; this can happen with a lazy init. - * - * NOTE: if the only thing in the list is a palette check - * function it can remove itself at this point. - */ - max_depth = png_run_transform_list_forwards(png_ptr, &tc); - - /* This is too late, a stack overwrite has already - * happened, but it may still prevent exploits: - */ - affirm(max_depth <= png_ptr->row_max_pixel_depth); - - /* It is very important that the transform produces the - * same pixel format as the TC_INIT steps: - */ - affirm(png_ptr->row_format == tc.format && - png_ptr->row_range == tc.range && - png_ptr->row_bit_depth == tc.bit_depth); -# ifdef PNG_READ_GAMMA_SUPPORTED - /* This checks the output gamma taking into account the - * fact that small gamma changes are eliminated. - */ - debug(png_ptr->row_gamma == tc.gamma || - png_gamma_check(png_ptr, &tc)); -# endif /* READ_GAMMA */ - - /* If the caller needs the row saved (for the progressive - * read API) or if this PNG is interlaced and this row may - * be required in a subsequent pass (any pass before the - * last one) then it is stored in - * png_struct::transformed_row, and that may need to be - * allocated here. - */ -# if defined(PNG_PROGRESSIVE_READ_SUPPORTED) ||\ - defined(PNG_READ_INTERLACING_SUPPORTED) - if (png_ptr->transform_list != NULL && - (save_row -# ifdef PNG_READ_INTERLACING_SUPPORTED - || (png_ptr->do_interlace && pass < 6U) -# endif /* READ_INTERLACING */ - )) - { - if (png_ptr->transformed_row == NULL) - png_ptr->transformed_row = png_voidcast(png_bytep, - png_malloc(png_ptr, png_calc_rowbytes(png_ptr, - png_ptr->row_bit_depth * - PNG_FORMAT_CHANNELS(png_ptr->row_format), - save_row ? width : (width+1U)>>1))); - - copy_row(png_ptr, png_ptr->transformed_row, - pixel_buffer.buffer, x, pixels, 1/*clear*/); - } -# endif /* PROGRESSIVE_READ || READ_INTERLACING */ - } /* transform_list != NULL */ -# endif /* TRANSFORM_MECH */ - - /* There are now 'pixels' possibly transformed pixels starting at - * row pixel x, where 'x' is an index in the interlaced row if - * interlacing is happening. Handle this row. - */ - if (transformed_row != NULL) - combine_row(png_ptr, transformed_row, pixel_buffer.buffer, - x, pixels, 0/*!display*/); - - if (display_row != NULL) - combine_row(png_ptr, display_row, pixel_buffer.buffer, x, - pixels, 1/*display*/); - } /* for x < pass_width */ - } /* pixel loop */ - - png_ptr->row_state = processing_row; - return png_row_process; - - default: - impossible("bad row state"); - } /* forever switch */ - - PNG_UNUSED(save_row) /* May not be used above */ -} - -void /* PRIVATE */ -png_read_free_row_buffers(png_structrp png_ptr) -{ - /* The transformed row only gets saved if needed: */ -# if (defined(PNG_PROGRESSIVE_READ_SUPPORTED) ||\ - defined(PNG_READ_INTERLACING_SUPPORTED)) &&\ - defined(PNG_TRANSFORM_MECH_SUPPORTED) - if (png_ptr->transformed_row != NULL) - { - png_free(png_ptr, png_ptr->transformed_row); - png_ptr->transformed_row = NULL; - } -# endif /* PROGRESSIVE_READ || READ_INTERLACING */ - - if (png_ptr->row_buffer != NULL) - { - png_free(png_ptr, png_ptr->row_buffer); - png_ptr->row_buffer = NULL; - } -} - -/* Complete reading of the IDAT chunks. This returns 0 if more data is to - * be read, 1 if the zlib stream has terminated. Call this routine with - * zstream.avail_in greater than zero unless there is no more input data. - * When zstream_avail_in is 0 on entry and the stream does not terminate - * an "IDAT truncated" error will be output. - */ -int /* PRIVATE */ -png_read_finish_IDAT(png_structrp png_ptr) -{ - enum - { - no_error = 0, - LZ_too_long, - IDAT_too_long, - IDAT_truncated - } error = no_error; - - /* Release the rowd buffers first; they can use considerable amounts of - * memory. - */ - png_read_free_row_buffers(png_ptr); - - affirm(png_ptr->zowner == png_IDAT); /* else this should not be called */ - - /* We don't need any more data and the stream should have ended, however the - * LZ end code may actually not have been processed. In this case we must - * read it otherwise stray unread IDAT data or, more likely, an IDAT chunk - * may still remain to be consumed. - */ - if (!png_ptr->zstream_ended) - { - int end_of_IDAT = png_ptr->zstream.avail_in == 0; - png_byte b[1]; - png_alloc_size_t cb = png_inflate_IDAT(png_ptr, 2/*finish*/, b, 1); - - debug(png_ptr->zstream.avail_out == 1-cb && - png_ptr->zstream.next_out == cb + b); - - /* As above, for safety do this: */ - png_ptr->zstream.next_out = NULL; - png_ptr->zstream.avail_out = 0; - - /* No data is expected, either compressed or in the IDAT: */ - if (cb != 0) - error = LZ_too_long; - - else if (png_ptr->zstream.avail_in == 0 /* && cb == 0 */) - { - /* This is the normal case but there may still be some waiting codes - * (including the adler32 that follow the LZ77 end code; so we can - * have at least 5 bytes after the end of the row data before the - * end of the stream. - */ - if (!png_ptr->zstream_ended) - { - if (!end_of_IDAT) - return 0; /* keep reading, no detectable error yet */ - - error = IDAT_truncated; - } - - /* Else there may still be an error; too much IDAT, but we can't - * tell. - */ - } - } - - /* If there is still pending zstream input then there was too much IDAT - * data: - */ - if (!error && png_ptr->zstream.avail_in > 0) - error = IDAT_too_long; - - /* Either this is the success case or an error has been detected and - * warned about. - */ - { - int ret = inflateEnd(&png_ptr->zstream); - - /* In fact we expect this to always succeed, so it is a good idea to - * catch it in pre-release builds: - */ - debug_handled(ret == Z_OK); - - if (ret != Z_OK) - { - /* This is just a warning; it's safe, and the zstream_error flag is - * not set. - */ - png_zstream_error(&png_ptr->zstream, ret); - png_chunk_warning(png_ptr, png_ptr->zstream.msg); - } - } - - /* Output an error message if required: */ - if (error && !png_ptr->zstream_error) - { - switch (error) - { - case LZ_too_long: - png_benign_error(png_ptr, "compressed data too long"); - break; - - case IDAT_too_long: - png_benign_error(png_ptr, "uncompressed data too long"); - break; - - case IDAT_truncated: - png_benign_error(png_ptr, "data truncated"); - break; - - default: - case no_error: /* Satisfy the compiler */ - break; - } - - png_ptr->zstream_error = 1; - } - - /* WARNING: leave {next,avail}_in set here, the progressive reader uses these - * to complete the PNG chunk CRC calculation. - */ - png_ptr->zstream_ended = 1; - png_ptr->zowner = 0; - - return 1; /* end of stream */ -} - -/* Optional call to update the users info_ptr structure, can be used from both - * the progressive and sequential reader, but the app must call it. - */ -void PNGAPI -png_read_update_info(png_structrp png_ptr, png_inforp info_ptr) -{ - png_debug(1, "in png_read_update_info"); - - if (png_ptr != NULL) - { - if (png_ptr->zowner != png_IDAT) - { - png_read_start_IDAT(png_ptr); - -# ifdef PNG_READ_TRANSFORMS_SUPPORTED - png_read_transform_info(png_ptr, info_ptr); -# else - PNG_UNUSED(info_ptr) -# endif - } - - /* New in 1.6.0 this avoids the bug of doing the initializations twice */ - else - png_app_error(png_ptr, - "png_read_update_info/png_start_read_image: duplicate call"); - } -} - -png_int_32 /* PRIVATE */ -png_read_setting(png_structrp png_ptr, png_uint_32 setting, - png_uint_32 parameter, png_int_32 value) -{ - /* Caller checks the arguments for basic validity */ - int only_get = (setting & PNG_SF_GET) != 0U; - - if (only_get) /* spurious: in case it isn't used */ - setting &= ~PNG_SF_GET; - - switch (setting) - { -# ifdef PNG_SEQUENTIAL_READ_SUPPORTED - case PNG_SR_COMPRESS_buffer_size: - if (parameter > 0 && parameter <= ZLIB_IO_MAX) - { - png_ptr->IDAT_size = parameter; - return 0; /* Cannot return a 32-bit value */ - } - - else - return PNG_EINVAL; -# endif /* SEQUENTIAL_READ */ - -# ifdef PNG_READ_GAMMA_SUPPORTED - case PNG_SR_GAMMA_threshold: - if (parameter <= 0xFFFF) - { - if (!only_get) - png_ptr->gamma_threshold = PNG_UINT_16(parameter); - - return (png_int_32)/*SAFE*/parameter; - } - - return PNG_EDOM; - -#if 0 /*NYI*/ - case PNG_SR_GAMMA_accuracy: - if (parameter <= 1600) - { - if (!only_get) - png_ptr->gamma_accuracy = parameter; - - return (png_int_32)/*SAFE*/parameter; - } - - return PNG_EDOM; -#endif /*NYI*/ -# endif /* READ_GAMMA */ - - case PNG_SR_CRC_ACTION: - /* Tell libpng how we react to CRC errors in critical chunks */ - switch (parameter) - { - case PNG_CRC_NO_CHANGE: /* Leave setting as is */ - break; - - case PNG_CRC_WARN_USE: /* Warn/use data */ - png_ptr->critical_crc = crc_warn_use; - break; - - case PNG_CRC_QUIET_USE: /* Quiet/use data */ - png_ptr->critical_crc = crc_quiet_use; - break; - - default: - case PNG_CRC_WARN_DISCARD: /* Not valid for critical data */ - return PNG_EINVAL; - - case PNG_CRC_ERROR_QUIT: /* Error/quit */ - case PNG_CRC_DEFAULT: - png_ptr->critical_crc = crc_error_quit; - break; - } - - /* Tell libpng how we react to CRC errors in ancillary chunks */ - switch (value) - { - case PNG_CRC_NO_CHANGE: /* Leave setting as is */ - break; - - case PNG_CRC_WARN_USE: /* Warn/use data */ - png_ptr->ancillary_crc = crc_warn_use; - break; - - case PNG_CRC_QUIET_USE: /* Quiet/use data */ - png_ptr->ancillary_crc = crc_quiet_use; - break; - - case PNG_CRC_ERROR_QUIT: /* Error/quit */ - png_ptr->ancillary_crc = crc_error_quit; - break; - - case PNG_CRC_WARN_DISCARD: /* Warn/discard data */ - case PNG_CRC_DEFAULT: - png_ptr->ancillary_crc = crc_warn_discard; - break; - - default: - return PNG_EINVAL; - } - - return 0; /* success */ - -# ifdef PNG_SET_OPTION_SUPPORTED - case PNG_SRW_OPTION: - switch (parameter) - { - case PNG_MAXIMUM_INFLATE_WINDOW: - if (png_ptr->maximum_inflate_window) - { - if (!value && !only_get) - png_ptr->maximum_inflate_window = 0U; - return PNG_OPTION_ON; - } - - else - { - if (value && !only_get) - png_ptr->maximum_inflate_window = 1U; - return PNG_OPTION_OFF; - } - - default: - return PNG_OPTION_UNSET; - } -# endif /* SET_OPTION */ - -# ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED - case PNG_SRW_CHECK_FOR_INVALID_INDEX: - /* The 'enabled' value is a FORTRAN style three-state: */ - if (value > 0) - png_ptr->palette_index_check = PNG_PALETTE_CHECK_ON; - - else if (value < 0) - png_ptr->palette_index_check = PNG_PALETTE_CHECK_OFF; - - else - png_ptr->palette_index_check = PNG_PALETTE_CHECK_DEFAULT; - - return 0; -# endif /* READ_CHECK_FOR_INVALID_INDEX */ - -# ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED - case PNG_SRW_ERROR_HANDLING: - /* The parameter is a bit mask of what to set, the value is what to - * set it to. - */ - if (value >= PNG_IGNORE && value <= PNG_ERROR && - parameter <= PNG_ALL_ERRORS) - { - if ((parameter & PNG_BENIGN_ERRORS) != 0U) - png_ptr->benign_error_action = value & 0x3U; - - if ((parameter & PNG_APP_WARNINGS) != 0U) - png_ptr->app_warning_action = value & 0x3U; - - if ((parameter & PNG_APP_ERRORS) != 0U) - png_ptr->app_error_action = value & 0x3U; - - if ((parameter & PNG_IDAT_ERRORS) != 0U) - png_ptr->IDAT_error_action = value & 0x3U; - - return 0; - } - - return PNG_EINVAL; -# endif /* BENIGN_READ_ERRORS */ - - default: - return PNG_ENOSYS; /* not supported (whatever it is) */ - } -} -#endif /* READ */ diff --git a/ext/libpng17/pngset.c b/ext/libpng17/pngset.c deleted file mode 100644 index abd13c377c..0000000000 --- a/ext/libpng17/pngset.c +++ /dev/null @@ -1,1674 +0,0 @@ - -/* pngset.c - storage of image information into info struct - * - * Last changed in libpng 1.7.0 [(PENDING RELEASE)] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * The functions here are used during reads to store data from the file - * into the info struct, and during writes to store application data - * into the info struct for writing into the file. This abstracts the - * info struct and allows us to change the structure in the future. - */ - -#include "pngpriv.h" -#define PNG_SRC_FILE PNG_SRC_FILE_pngset - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - -#ifdef PNG_bKGD_SUPPORTED -void PNGAPI -png_set_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_color_16p background) -{ - png_debug1(1, "in %s storage function", "bKGD"); - - if (png_ptr == NULL || info_ptr == NULL || background == NULL) - return; - - info_ptr->background = *background; - info_ptr->valid |= PNG_INFO_bKGD; -} -#endif - -#ifdef PNG_cHRM_SUPPORTED -void PNGFAPI -png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr, - png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, - png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, - png_fixed_point blue_x, png_fixed_point blue_y) -{ - png_xy xy; - - png_debug1(1, "in %s storage function", "cHRM fixed"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - xy.redx = red_x; - xy.redy = red_y; - xy.greenx = green_x; - xy.greeny = green_y; - xy.bluex = blue_x; - xy.bluey = blue_y; - xy.whitex = white_x; - xy.whitey = white_y; - - if (png_colorspace_set_chromaticities(png_ptr, &info_ptr->colorspace, &xy, - 2/* override with app values*/) != 0) - info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; - - png_colorspace_sync_info(png_ptr, info_ptr); -} - -void PNGFAPI -png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr, - png_fixed_point int_red_X, png_fixed_point int_red_Y, - png_fixed_point int_red_Z, png_fixed_point int_green_X, - png_fixed_point int_green_Y, png_fixed_point int_green_Z, - png_fixed_point int_blue_X, png_fixed_point int_blue_Y, - png_fixed_point int_blue_Z) -{ - png_XYZ XYZ; - - png_debug1(1, "in %s storage function", "cHRM XYZ fixed"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - XYZ.red_X = int_red_X; - XYZ.red_Y = int_red_Y; - XYZ.red_Z = int_red_Z; - XYZ.green_X = int_green_X; - XYZ.green_Y = int_green_Y; - XYZ.green_Z = int_green_Z; - XYZ.blue_X = int_blue_X; - XYZ.blue_Y = int_blue_Y; - XYZ.blue_Z = int_blue_Z; - - if (png_colorspace_set_endpoints(png_ptr, &info_ptr->colorspace, - &XYZ, 2) != 0) - info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; - - png_colorspace_sync_info(png_ptr, info_ptr); -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, - double white_x, double white_y, double red_x, double red_y, - double green_x, double green_y, double blue_x, double blue_y) -{ - png_set_cHRM_fixed(png_ptr, info_ptr, - png_fixed(png_ptr, white_x, "cHRM White X"), - png_fixed(png_ptr, white_y, "cHRM White Y"), - png_fixed(png_ptr, red_x, "cHRM Red X"), - png_fixed(png_ptr, red_y, "cHRM Red Y"), - png_fixed(png_ptr, green_x, "cHRM Green X"), - png_fixed(png_ptr, green_y, "cHRM Green Y"), - png_fixed(png_ptr, blue_x, "cHRM Blue X"), - png_fixed(png_ptr, blue_y, "cHRM Blue Y")); -} - -void PNGAPI -png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X, - double red_Y, double red_Z, double green_X, double green_Y, double green_Z, - double blue_X, double blue_Y, double blue_Z) -{ - png_set_cHRM_XYZ_fixed(png_ptr, info_ptr, - png_fixed(png_ptr, red_X, "cHRM Red X"), - png_fixed(png_ptr, red_Y, "cHRM Red Y"), - png_fixed(png_ptr, red_Z, "cHRM Red Z"), - png_fixed(png_ptr, green_X, "cHRM Green X"), - png_fixed(png_ptr, green_Y, "cHRM Green Y"), - png_fixed(png_ptr, green_Z, "cHRM Green Z"), - png_fixed(png_ptr, blue_X, "cHRM Blue X"), - png_fixed(png_ptr, blue_Y, "cHRM Blue Y"), - png_fixed(png_ptr, blue_Z, "cHRM Blue Z")); -} -# endif /* FLOATING_POINT */ - -#endif /* cHRM */ - -#ifdef PNG_gAMA_SUPPORTED -void PNGFAPI -png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr, - png_fixed_point file_gamma) -{ - png_debug1(1, "in %s storage function", "gAMA"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma); - png_colorspace_sync_info(png_ptr, info_ptr); -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_gAMA(png_const_structrp png_ptr, png_inforp info_ptr, double file_gamma) -{ - png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma, - "png_set_gAMA")); -} -# endif -#endif - -#ifdef PNG_hIST_SUPPORTED -void PNGAPI -png_set_hIST(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_uint_16p hist) -{ - png_debug1(1, "in %s storage function", "hIST"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (info_ptr->num_palette == 0 || info_ptr->num_palette - > PNG_MAX_PALETTE_LENGTH) - { - png_warning(png_ptr, - "Invalid palette size, hIST allocation skipped"); - - return; - } - - png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0); - - /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in - * version 1.2.1 - */ - info_ptr->hist = png_voidcast(png_uint_16p, png_malloc_warn(png_ptr, - PNG_MAX_PALETTE_LENGTH * (sizeof (png_uint_16)))); - - if (info_ptr->hist == NULL) - { - png_warning(png_ptr, "Insufficient memory for hIST chunk data"); - - return; - } - - info_ptr->free_me |= PNG_FREE_HIST; - - { - unsigned int i; - - for (i = 0; i < info_ptr->num_palette; i++) - info_ptr->hist[i] = hist[i]; - } - - info_ptr->valid |= PNG_INFO_hIST; -} -#endif - -void PNGAPI -png_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_type, int compression_type, - int filter_type) -{ - png_debug1(1, "in %s storage function", "IHDR"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - info_ptr->width = width; - info_ptr->height = height; - info_ptr->bit_depth = png_check_bits(png_ptr, bit_depth, 6); - info_ptr->format = png_check_bits(png_ptr, - PNG_FORMAT_FROM_COLOR_TYPE(color_type), PNG_RF_BITS); - info_ptr->compression_type = png_check_byte(png_ptr, compression_type); - info_ptr->filter_type = png_check_byte(png_ptr, filter_type); - info_ptr->interlace_type = png_check_byte(png_ptr, interlace_type); - - png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height, - info_ptr->bit_depth, color_type, info_ptr->interlace_type, - info_ptr->compression_type, info_ptr->filter_type); -} - -#ifdef PNG_oFFs_SUPPORTED -void PNGAPI -png_set_oFFs(png_const_structrp png_ptr, png_inforp info_ptr, - png_int_32 offset_x, png_int_32 offset_y, int unit_type) -{ - png_debug1(1, "in %s storage function", "oFFs"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - info_ptr->x_offset = offset_x; - info_ptr->y_offset = offset_y; - info_ptr->offset_unit_type = png_check_byte(png_ptr, unit_type); - info_ptr->valid |= PNG_INFO_oFFs; -} -#endif - -#ifdef PNG_pCAL_SUPPORTED -void PNGAPI -png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, - int nparams, png_const_charp units, png_charpp params) -{ - png_size_t length; - int i; - - png_debug1(1, "in %s storage function", "pCAL"); - - if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL - || (nparams > 0 && params == NULL)) - return; - - length = strlen(purpose) + 1; - png_debug1(3, "allocating purpose for info (%lu bytes)", - (unsigned long)length); - - /* TODO: validate format of calibration name and unit name */ - - /* Check that the type matches the specification. */ - if (type < 0 || type > 3) - png_error(png_ptr, "Invalid pCAL equation type"); - - if (nparams < 0 || nparams > 255) - png_error(png_ptr, "Invalid pCAL parameter count"); - - /* Validate params[nparams] */ - for (i=0; ipcal_purpose = png_voidcast(png_charp, - png_malloc_warn(png_ptr, length)); - - if (info_ptr->pcal_purpose == NULL) - { - png_warning(png_ptr, "Insufficient memory for pCAL purpose"); - - return; - } - - memcpy(info_ptr->pcal_purpose, purpose, length); - - png_debug(3, "storing X0, X1, type, and nparams in info"); - info_ptr->pcal_X0 = X0; - info_ptr->pcal_X1 = X1; - info_ptr->pcal_type = png_check_byte(png_ptr, type); - info_ptr->pcal_nparams = png_check_byte(png_ptr, nparams); - - length = strlen(units) + 1; - png_debug1(3, "allocating units for info (%lu bytes)", - (unsigned long)length); - - info_ptr->pcal_units = png_voidcast(png_charp, - png_malloc_warn(png_ptr, length)); - - if (info_ptr->pcal_units == NULL) - { - png_warning(png_ptr, "Insufficient memory for pCAL units"); - - return; - } - - memcpy(info_ptr->pcal_units, units, length); - - info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, - (png_size_t)((nparams + 1) * (sizeof (png_charp))))); - - if (info_ptr->pcal_params == NULL) - { - png_warning(png_ptr, "Insufficient memory for pCAL params"); - - return; - } - - memset(info_ptr->pcal_params, 0, (nparams + 1) * (sizeof (png_charp))); - - for (i = 0; i < nparams; i++) - { - length = strlen(params[i]) + 1; - png_debug2(3, "allocating parameter %d for info (%lu bytes)", i, - (unsigned long)length); - - info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length); - - if (info_ptr->pcal_params[i] == NULL) - { - png_warning(png_ptr, "Insufficient memory for pCAL parameter"); - - return; - } - - memcpy(info_ptr->pcal_params[i], params[i], length); - } - - info_ptr->valid |= PNG_INFO_pCAL; - info_ptr->free_me |= PNG_FREE_PCAL; -} -#endif - -#ifdef PNG_sCAL_SUPPORTED -void PNGAPI -png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr, - int unit, png_const_charp swidth, png_const_charp sheight) -{ - png_size_t lengthw = 0, lengthh = 0; - - png_debug1(1, "in %s storage function", "sCAL"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - /* Double check the unit (should never get here with an invalid - * unit unless this is an API call.) - */ - if (unit != 1 && unit != 2) - png_error(png_ptr, "Invalid sCAL unit"); - - if (swidth == NULL || (lengthw = strlen(swidth)) == 0 || - swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw)) - png_error(png_ptr, "Invalid sCAL width"); - - if (sheight == NULL || (lengthh = strlen(sheight)) == 0 || - sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh)) - png_error(png_ptr, "Invalid sCAL height"); - - info_ptr->scal_unit = png_check_byte(png_ptr, unit); - - ++lengthw; - - png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw); - - info_ptr->scal_s_width = png_voidcast(png_charp, - png_malloc_warn(png_ptr, lengthw)); - - if (info_ptr->scal_s_width == NULL) - { - png_warning(png_ptr, "Memory allocation failed while processing sCAL"); - - return; - } - - memcpy(info_ptr->scal_s_width, swidth, lengthw); - - ++lengthh; - - png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh); - - info_ptr->scal_s_height = png_voidcast(png_charp, - png_malloc_warn(png_ptr, lengthh)); - - if (info_ptr->scal_s_height == NULL) - { - png_free (png_ptr, info_ptr->scal_s_width); - info_ptr->scal_s_width = NULL; - - png_warning(png_ptr, "Memory allocation failed while processing sCAL"); - - return; - } - - memcpy(info_ptr->scal_s_height, sheight, lengthh); - - info_ptr->valid |= PNG_INFO_sCAL; - info_ptr->free_me |= PNG_FREE_SCAL; -} - -# if defined(PNG_FLOATING_POINT_SUPPORTED) &&\ - defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) -void PNGAPI -png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit, - double width, double height) -{ - png_debug1(1, "in %s storage function", "sCAL"); - - /* Check the arguments. */ - if (width <= 0) - png_warning(png_ptr, "Invalid sCAL width ignored"); - - else if (height <= 0) - png_warning(png_ptr, "Invalid sCAL height ignored"); - - else - { - /* Convert 'width' and 'height' to ASCII. */ - char swidth[PNG_sCAL_MAX_DIGITS+1]; - char sheight[PNG_sCAL_MAX_DIGITS+1]; - - png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width, - PNG_sCAL_PRECISION); - png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height, - PNG_sCAL_PRECISION); - - png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); - } -} -# endif - -# ifdef PNG_FIXED_POINT_SUPPORTED -void PNGAPI -png_set_sCAL_fixed(png_const_structrp png_ptr, png_inforp info_ptr, int unit, - png_fixed_point width, png_fixed_point height) -{ - png_debug1(1, "in %s storage function", "sCAL"); - - /* Check the arguments. */ - if (width <= 0) - png_warning(png_ptr, "Invalid sCAL width ignored"); - - else if (height <= 0) - png_warning(png_ptr, "Invalid sCAL height ignored"); - - else - { - /* Convert 'width' and 'height' to ASCII. */ - char swidth[PNG_sCAL_MAX_DIGITS+1]; - char sheight[PNG_sCAL_MAX_DIGITS+1]; - - png_ascii_from_fixed(png_ptr, swidth, (sizeof swidth), width); - png_ascii_from_fixed(png_ptr, sheight, (sizeof sheight), height); - - png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); - } -} -# endif -#endif - -#ifdef PNG_pHYs_SUPPORTED -void PNGAPI -png_set_pHYs(png_const_structrp png_ptr, png_inforp info_ptr, - png_uint_32 res_x, png_uint_32 res_y, int unit_type) -{ - png_debug1(1, "in %s storage function", "pHYs"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - info_ptr->x_pixels_per_unit = res_x; - info_ptr->y_pixels_per_unit = res_y; - info_ptr->phys_unit_type = png_check_byte(png_ptr, unit_type); - info_ptr->valid |= PNG_INFO_pHYs; -} -#endif - -void PNGAPI -png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr, - png_const_colorp palette, int num_palette) -{ - - png_uint_32 max_palette_length; - - png_debug1(1, "in %s storage function", "PLTE"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - max_palette_length = (info_ptr->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ? - (1 << info_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH; - - if (num_palette < 0 || num_palette > (int) max_palette_length) - { - if ((info_ptr->format & PNG_FORMAT_FLAG_COLORMAP) != 0) - png_chunk_error(png_ptr, "Invalid palette length"); - - else - { - png_chunk_report(png_ptr, "Invalid palette length", PNG_CHUNK_ERROR); - return; - } - } - -#ifdef PNG_MNG_FEATURES_SUPPORTED - if ((num_palette > 0 && palette == NULL) || (num_palette == 0 && - (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0)) - png_error(png_ptr, "Invalid palette"); -#else - if ((num_palette > 0 && palette == NULL) || num_palette == 0) - png_error(png_ptr, "Invalid palette"); -#endif /* MNG_FEATURES */ - - png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); - - /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead - * of num_palette entries, in case of an invalid PNG file or incorrect - * call to png_set_PLTE() with too-large sample values. - */ - info_ptr->palette = png_voidcast(png_colorp, png_malloc(png_ptr, - PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)))); - - if (num_palette > 0) - memcpy(info_ptr->palette, palette, num_palette * (sizeof (png_color))); - - /* Set the remainder of the palette entries to something recognizable; the - * code used to leave them set to 0, which made seeing palette index errors - * difficult. - */ - if (num_palette < PNG_MAX_PALETTE_LENGTH) - { - int i; - png_color c; - - memset(&c, 0x42, sizeof c); /* fill in any padding */ - c.red = 0xbe; - c.green = 0xad; - c.blue = 0xed; /* Visible in memory as 'beaded' */ - - for (i=num_palette; ipalette[i] = c; - } - - info_ptr->num_palette = png_check_bits(png_ptr, num_palette, 9); - info_ptr->free_me |= PNG_FREE_PLTE; - info_ptr->valid |= PNG_INFO_PLTE; -} - -#ifdef PNG_sBIT_SUPPORTED -void PNGAPI -png_set_sBIT(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_color_8p sig_bit) -{ - png_debug1(1, "in %s storage function", "sBIT"); - - if (png_ptr == NULL || info_ptr == NULL || sig_bit == NULL) - return; - - info_ptr->sig_bit = *sig_bit; - info_ptr->valid |= PNG_INFO_sBIT; -} -#endif - -#ifdef PNG_sRGB_SUPPORTED -void PNGAPI -png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent) -{ - png_debug1(1, "in %s storage function", "sRGB"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - (void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent); - png_colorspace_sync_info(png_ptr, info_ptr); -} - -void PNGAPI -png_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, - int srgb_intent) -{ - png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, - srgb_intent) != 0) - { - /* This causes the gAMA and cHRM to be written too */ - info_ptr->colorspace.flags |= - PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM; - } - - png_colorspace_sync_info(png_ptr, info_ptr); -} -#endif /* sRGB */ - - -#ifdef PNG_iCCP_SUPPORTED -void PNGAPI -png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_charp name, int compression_type, - png_const_bytep profile, png_uint_32 proflen) -{ - png_charp new_iccp_name; - png_bytep new_iccp_profile; - png_size_t length; - - png_debug1(1, "in %s storage function", "iCCP"); - - if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) - return; - - if (compression_type != PNG_COMPRESSION_TYPE_BASE) - png_app_error(png_ptr, "Invalid iCCP compression method"); - - /* Set the colorspace first because this validates the profile; do not - * override previously set app cHRM or gAMA here (because likely as not the - * application knows better than libpng what the correct values are.) Pass - * the info_ptr color_type field to png_colorspace_set_ICC because in the - * write case it has not yet been stored in png_ptr. - */ - { - int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name, - proflen, profile, (info_ptr->format & PNG_FORMAT_FLAG_COLOR) != 0); - - png_colorspace_sync_info(png_ptr, info_ptr); - - /* Don't do any of the copying if the profile was bad, or inconsistent. */ - if (result == 0) - return; - - /* But do write the gAMA and cHRM chunks from the profile. */ - info_ptr->colorspace.flags |= - PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM; - } - - length = strlen(name)+1; - new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length)); - - if (new_iccp_name == NULL) - { - png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk"); - - return; - } - - memcpy(new_iccp_name, name, length); - new_iccp_profile = png_voidcast(png_bytep, - png_malloc_warn(png_ptr, proflen)); - - if (new_iccp_profile == NULL) - { - png_free(png_ptr, new_iccp_name); - png_benign_error(png_ptr, - "Insufficient memory to process iCCP profile"); - - return; - } - - memcpy(new_iccp_profile, profile, proflen); - - png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0); - - info_ptr->iccp_name = new_iccp_name; - info_ptr->iccp_profile = new_iccp_profile; - info_ptr->free_me |= PNG_FREE_ICCP; - info_ptr->valid |= PNG_INFO_iCCP; -} -#endif - -#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_tIME_SUPPORTED) -static png_byte -get_location(png_const_structrp png_ptr) - /* Return the correct location flag for a chunk. For a png_set_ - * called during read this is the current read location, for a - * png_set_ called during write it is the following write location - * (because the chunks at the current location have already been written.) - * For a png_set_ called before read starts (none of the 'position' - * mode bits are set) the position is set to the start (PNG_HAVE_IHDR). For - * a png_set_chunk> called before write starts PNG_HAVE_PLTE|PNG_AFTER_IDAT - * are set because we don't know whether this is the main png_info or the one - * for use after the IDAT from png_write_end. - * - * The latter behavior gives compatibility with the old behavior of - * png_set_text; it only wrote text chunks after the PLTE or IDAT and it just - * wrote them once. - */ -{ - if ((png_ptr->mode & PNG_AFTER_IDAT) != 0U) - return PNG_AFTER_IDAT; - - else if ((png_ptr->mode & PNG_HAVE_PLTE) != 0U) - { - /* In a write operation PNG_HAVE_PLTE is set when the chunks before the - * IDAT are written (in png_write_info), so the location needs to be after - * IDAT. In a read the chunk was read after the PLTE but before the IDAT. - */ - if (png_ptr->read_struct) - return PNG_HAVE_PLTE; - - else /* write struct */ - return PNG_AFTER_IDAT; - } - - else if ((png_ptr->mode & PNG_HAVE_IHDR) != 0U) - { - /* For read this means the chunk is between the IHDR and any PLTE; there - * may be none but then there is no order to preserve. - * - * For write png_write_IHDR has been called and that means that the info - * before PLTE has been written, so the chunk goes after. - */ - if (png_ptr->read_struct) - return PNG_HAVE_IHDR; - - else /* write struct */ - return PNG_HAVE_PLTE; - } - - else if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0U) - { - /* This should not happen on read, on write it means that the app has - * started writing so assume the text is meant to go before PLTE. - */ - return PNG_HAVE_IHDR; - } - - /* Either a png_set_ from the application during read before reading - * starts (so mode is 0) or the same for write. - */ - else - { - if (png_ptr->read_struct) - return PNG_HAVE_IHDR; - - else - return PNG_HAVE_PLTE|PNG_AFTER_IDAT; - } -} -#endif /* TEXT || tIME */ - -#ifdef PNG_TEXT_SUPPORTED -void PNGAPI -png_set_text(png_structrp png_ptr, png_inforp info_ptr, - png_const_textp text_ptr, int num_text) -{ - int ret; - ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); - - if (ret != 0) - png_error(png_ptr, "Insufficient memory to store text"); -} - -int /* PRIVATE */ -png_set_text_2(png_structrp png_ptr, png_inforp info_ptr, - png_const_textp text_ptr, int num_text) -{ - int i; - - png_debug1(1, "in %lx storage function", png_ptr == NULL ? 0xabadca11 : - (unsigned long)png_ptr->chunk_name); - - if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL) - return(0); - - /* Make sure we have enough space in the "text" array in info_struct - * to hold all of the incoming text_ptr objects. This compare can't overflow - * because max_text >= num_text (anyway, subtract of two positive integers - * can't overflow in any case.) - */ - if (num_text > info_ptr->max_text - info_ptr->num_text) - { - int old_num_text = info_ptr->num_text; - int max_text; - png_textp new_text = NULL; - - /* The code below goes horribly wrong if old_num_text ever ends up - * negative, so: - */ - affirm(old_num_text >= 0); - - /* Calculate an appropriate max_text, checking for overflow. */ - max_text = old_num_text; - if (num_text <= INT_MAX - max_text) - { - max_text += num_text; - - /* Round up to a multiple of 8 */ - if (max_text < INT_MAX-8) - max_text = (max_text + 8) & ~0x7; - - else - max_text = INT_MAX; - - /* Now allocate a new array and copy the old members in; this does all - * the overflow checks. - */ - new_text = png_voidcast(png_textp,png_realloc_array(png_ptr, - info_ptr->text, old_num_text, max_text-old_num_text, - sizeof *new_text)); - } - - if (new_text == NULL) - { - png_chunk_report(png_ptr, "too many text chunks", - PNG_CHUNK_WRITE_ERROR); - - return 1; - } - - png_free(png_ptr, info_ptr->text); - - info_ptr->text = new_text; - info_ptr->free_me |= PNG_FREE_TEXT; - info_ptr->max_text = max_text; - /* num_text is adjusted below as the entries are copied in */ - - png_debug1(3, "allocated %d entries for info_ptr->text", max_text); - } - - for (i = 0; i < num_text; i++) - { - size_t text_length, key_len; - size_t lang_len, lang_key_len; - png_textp textp = &(info_ptr->text[info_ptr->num_text]); - - if (text_ptr[i].key == NULL) - continue; - - if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE || - text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST) - { - png_chunk_report(png_ptr, "text compression mode is out of range", - PNG_CHUNK_WRITE_ERROR); - continue; - } - - key_len = strlen(text_ptr[i].key); - - if (text_ptr[i].compression <= 0) - { - lang_len = 0; - lang_key_len = 0; - } - - else -# ifdef PNG_iTXt_SUPPORTED - { - /* Set iTXt data */ - - if (text_ptr[i].lang != NULL) - lang_len = strlen(text_ptr[i].lang); - - else - lang_len = 0; - - if (text_ptr[i].lang_key != NULL) - lang_key_len = strlen(text_ptr[i].lang_key); - - else - lang_key_len = 0; - } -# else /* iTXt */ - { - png_chunk_report(png_ptr, "iTXt chunk not supported", - PNG_CHUNK_WRITE_ERROR); - continue; - } -# endif - - /* Record the location for posterity. On the read side this just says - * where the chunk was (approximately). On the write side it says how far - * through the write process libpng was before this API was called. - */ - textp->location = get_location(png_ptr); - - if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0') - { - text_length = 0; -# ifdef PNG_iTXt_SUPPORTED - if (text_ptr[i].compression > 0) - textp->compression = PNG_ITXT_COMPRESSION_NONE; - - else -# endif - textp->compression = PNG_TEXT_COMPRESSION_NONE; - } - - else - { - text_length = strlen(text_ptr[i].text); - textp->compression = text_ptr[i].compression; - } - - textp->key = png_voidcast(png_charp,png_malloc_base(png_ptr, - key_len + text_length + lang_len + lang_key_len + 4)); - - if (textp->key == NULL) - { - png_chunk_report(png_ptr, "text chunk: out of memory", - PNG_CHUNK_WRITE_ERROR); - - return 1; - } - - png_debug2(2, "Allocated %lu bytes at %p in png_set_text", - (unsigned long)(png_uint_32) - (key_len + lang_len + lang_key_len + text_length + 4), - textp->key); - - memcpy(textp->key, text_ptr[i].key, key_len); - *(textp->key + key_len) = '\0'; - - if (text_ptr[i].compression > 0) - { - textp->lang = textp->key + key_len + 1; - memcpy(textp->lang, text_ptr[i].lang, lang_len); - *(textp->lang + lang_len) = '\0'; - textp->lang_key = textp->lang + lang_len + 1; - memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); - *(textp->lang_key + lang_key_len) = '\0'; - textp->text = textp->lang_key + lang_key_len + 1; - } - - else - { - textp->lang=NULL; - textp->lang_key=NULL; - textp->text = textp->key + key_len + 1; - } - - if (text_length != 0) - memcpy(textp->text, text_ptr[i].text, text_length); - - *(textp->text + text_length) = '\0'; - -# ifdef PNG_iTXt_SUPPORTED - if (textp->compression > 0) - { - textp->text_length = 0; - textp->itxt_length = text_length; - } - - else -# endif - { - textp->text_length = text_length; - textp->itxt_length = 0; - } - - info_ptr->num_text++; - png_debug1(3, "transferred text chunk %d", info_ptr->num_text); - } - - return(0); -} -#endif - -#ifdef PNG_tIME_SUPPORTED -void PNGAPI -png_set_tIME(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_timep mod_time) -{ - png_debug1(1, "in %s storage function", "tIME"); - - if (png_ptr == NULL || info_ptr == NULL || mod_time == NULL) - return; - - /* It is valid to do set the tIME chunk after the IDAT has been written, but - * not if one has already been written. This was ignored before - the - * previous time was used - this is a bad thing. - */ - if ((info_ptr->valid & PNG_INFO_tIME) != 0 /* Changing a time chunk */ && - (png_ptr->mode & PNG_HAVE_IHDR) != 0 /* after writing started */) - { - /* So it can be *set* but it can't be *changed* after the info before PLTE - * has been written. (Note that putting tIME into an unknown chunk - * currently gets round this; to be fixed.) - */ - png_app_error(png_ptr, "cannot change tIME after writing starts"); - return; - } - - if (mod_time->month == 0 || mod_time->month > 12 || - mod_time->day == 0 || mod_time->day > 31 || - mod_time->hour > 23 || mod_time->minute > 59 || - mod_time->second > 60) - { - png_app_error(png_ptr, "Ignoring invalid time value"); - return; - } - - info_ptr->mod_time = *mod_time; - info_ptr->time_location = get_location(png_ptr); - info_ptr->valid |= PNG_INFO_tIME; -} -#endif /* tIME */ - -#ifdef PNG_tRNS_SUPPORTED -void PNGAPI -png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr, - png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color) -{ - png_debug1(1, "in %s storage function", "tRNS"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if ((info_ptr->format & PNG_FORMAT_FLAG_ALPHA) != 0) - png_chunk_report(png_ptr, - "png_set_tRNS: invalid on PNG with alpha channel", PNG_CHUNK_ERROR); - - else if ((info_ptr->format & PNG_FORMAT_FLAG_COLORMAP) != 0) - { - int max_num; - - /* Free the old data; num_trans 0 can be used to kill the tRNS */ - png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); - - /* Do this just in case the old data was not owned by libpng: */ - info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_tRNS); - info_ptr->trans_alpha = NULL; - info_ptr->num_trans = 0; - - /* Expect png_set_PLTE to happen before png_set_tRNS, so num_palette will - * be set, but this is not a requirement of the API. - */ - if (info_ptr->num_palette) - max_num = info_ptr->num_palette; - - else - max_num = 1 << info_ptr->bit_depth; - - if (num_trans > max_num) - { - png_chunk_report(png_ptr, "png_set_tRNS: num_trans too large", - PNG_CHUNK_ERROR); - /* If control returns simply limit it; the behavior prior to 1.7 was to - * issue a warning and skip the palette in png_write_tRNS. - */ - num_trans = max_num; - } - - /* But only attempt a malloc if there is something to do; so the app can - * set a tRNS array then later delete it. - */ - if (num_trans > 0 && trans_alpha != NULL) - { - /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1, - * this avoids issues where a palette image contains out of range - * indices. - */ - info_ptr->trans_alpha = png_voidcast(png_bytep, png_malloc(png_ptr, - PNG_MAX_PALETTE_LENGTH)); - info_ptr->free_me |= PNG_FREE_TRNS; - - memcpy(info_ptr->trans_alpha, trans_alpha, - (unsigned)/*SAFE*/num_trans); - info_ptr->valid |= PNG_INFO_tRNS; - info_ptr->num_trans = png_check_bits(png_ptr, num_trans, 9); - } - } - - else /* not a PALETTE image */ - { - /* Invalidate any prior transparent color and set num_trans. It is not - * used internally in this case but png_get_tRNS still returns it. - */ - info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_tRNS); - info_ptr->num_trans = 0; /* for png_get_tRNS */ - - if (trans_color != NULL && info_ptr->bit_depth < 16) - { - unsigned int sample_max = (1U << info_ptr->bit_depth) - 1U; - - if (!(info_ptr->format & PNG_FORMAT_FLAG_COLOR) ? - trans_color->gray <= sample_max : - trans_color->red <= sample_max && - trans_color->green <= sample_max && - trans_color->blue <= sample_max) - { - info_ptr->trans_color = *trans_color; - info_ptr->valid |= PNG_INFO_tRNS; - info_ptr->num_trans = 1; /* for png_get_tRNS */ - } - - else - png_chunk_report(png_ptr, - "tRNS chunk has out-of-range samples for bit_depth", - PNG_CHUNK_ERROR); - } - } -} -#endif - -#ifdef PNG_sPLT_SUPPORTED -void PNGAPI -png_set_sPLT(png_structrp png_ptr, - png_inforp info_ptr, png_const_sPLT_tp entries, int nentries) -/* - * entries - array of png_sPLT_t structures - * to be added to the list of palettes - * in the info structure. - * - * nentries - number of palette structures to be - * added. - */ -{ - png_sPLT_tp np; - - if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL) - return; - - /* Use the internal realloc function, which checks for all the possible - * overflows. Notice that the parameters are (int) and (size_t) - */ - np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr, - info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries, - sizeof *np)); - - if (np == NULL) - { - /* Out of memory or too many chunks */ - png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR); - - return; - } - - png_free(png_ptr, info_ptr->splt_palettes); - info_ptr->splt_palettes = np; - info_ptr->free_me |= PNG_FREE_SPLT; - - np += info_ptr->splt_palettes_num; - - do - { - png_size_t length; - - /* Skip invalid input entries */ - if (entries->name == NULL || entries->entries == NULL) - { - /* png_handle_sPLT doesn't do this, so this is an app error */ - png_app_error(png_ptr, "png_set_sPLT: invalid sPLT"); - /* Just skip the invalid entry */ - continue; - } - - np->depth = entries->depth; - - /* In the event of out-of-memory just return - there's no point keeping - * on trying to add sPLT chunks. - */ - length = strlen(entries->name) + 1; - np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length)); - - if (np->name == NULL) - break; - - memcpy(np->name, entries->name, length); - - /* IMPORTANT: we have memory now that won't get freed if something else - * goes wrong; this code must free it. png_malloc_array produces no - * warnings; use a png_chunk_report (below) if there is an error. - */ - np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr, - entries->nentries, sizeof (png_sPLT_entry))); - - if (np->entries == NULL) - { - png_free(png_ptr, np->name); - np->name = NULL; - break; - } - - np->nentries = entries->nentries; - /* This multiply can't overflow because png_malloc_array has already - * checked it when doing the allocation. - */ - memcpy(np->entries, entries->entries, - entries->nentries * sizeof (png_sPLT_entry)); - - /* Note that 'continue' skips the advance of the out pointer and out - * count, so an invalid entry is not added. - */ - info_ptr->valid |= PNG_INFO_sPLT; - ++(info_ptr->splt_palettes_num); - ++np; - ++entries; - } - while (--nentries); - - if (nentries > 0) - png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR); -} -#endif /* sPLT */ - -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -static png_byte -check_location(png_const_structrp png_ptr, int location) -{ - location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT); - - /* New in 1.6.0; copy the location and check it. This is an API - * change; previously the app had to use the - * png_set_unknown_chunk_location API below for each chunk. - */ - if (location == 0 && !png_ptr->read_struct) - { - /* Write struct, so unknown chunks come from the app */ - png_app_warning(png_ptr, - "png_set_unknown_chunks now expects a valid location"); - /* Use the old behavior */ - location = png_check_byte(png_ptr, png_ptr->mode & - (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)); - } - - /* This need not be an internal error - if the app calls - * png_set_unknown_chunks on a read pointer it must get the location right. - */ - if (location == 0) - png_error(png_ptr, "invalid location in png_set_unknown_chunks"); - - /* Now reduce the location to the top-most set bit by removing each least - * significant bit in turn. - */ - while (location != (location & -location)) - location &= ~(location & -location); - - /* The cast is safe because 'location' is a bit mask and only the low four - * bits are significant. - */ - return png_check_byte(png_ptr, location); -} - -void PNGAPI -png_set_unknown_chunks(png_structrp png_ptr, - png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) -{ - png_unknown_chunkp np; - - if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 || - unknowns == NULL) - return; - - /* Check for the failure cases where support has been disabled at compile - * time. This code is hardly ever compiled - it's here because - * STORE_UNKNOWN_CHUNKS is set by both read and write code (compiling in this - * code) but may be meaningless if the read or write handling of unknown - * chunks is not compiled in. - */ -# ifndef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - if (png_ptr->read_struct) - { - png_app_error(png_ptr, "no unknown chunk support on read"); - - return; - } -# endif -# ifndef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - if (!png_ptr->read_struct) - { - png_app_error(png_ptr, "no unknown chunk support on write"); - - return; - } -# endif - - /* Prior to 1.6.0 this code used png_malloc_warn; however, this meant that - * unknown critical chunks could be lost with just a warning resulting in - * undefined behavior. Now png_chunk_report is used to provide behavior - * appropriate to read or write. - */ - np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr, - info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns, - sizeof *np)); - - if (np == NULL) - { - png_chunk_report(png_ptr, "too many unknown chunks", PNG_CHUNK_ERROR); - return; - } - - png_free(png_ptr, info_ptr->unknown_chunks); - info_ptr->unknown_chunks = np; /* safe because it is initialized */ - info_ptr->free_me |= PNG_FREE_UNKN; - - np += info_ptr->unknown_chunks_num; - - /* Increment unknown_chunks_num each time round the loop to protect the - * just-allocated chunk data. - */ - for (; num_unknowns > 0; --num_unknowns, ++unknowns) - { - memcpy(np->name, unknowns->name, (sizeof np->name)); - np->name[(sizeof np->name)-1] = '\0'; - np->location = check_location(png_ptr, unknowns->location); - - if (unknowns->size == 0) - { - np->data = NULL; - np->size = 0; - } - - else - { - np->data = png_voidcast(png_bytep, - png_malloc_base(png_ptr, unknowns->size)); - - if (np->data == NULL) - { - png_chunk_report(png_ptr, "unknown chunk: out of memory", - PNG_CHUNK_ERROR); - /* But just skip storing the unknown chunk */ - continue; - } - - memcpy(np->data, unknowns->data, unknowns->size); - np->size = unknowns->size; - } - - /* These increments are skipped on out-of-memory for the data - the - * unknown chunk entry gets overwritten if the png_chunk_report returns. - * This is correct in the read case (the chunk is just dropped.) - */ - ++np; - ++(info_ptr->unknown_chunks_num); - } -} - -void PNGAPI -png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr, - int chunk, int location) -{ - /* This API is pretty pointless in 1.6.0 because the location can be set - * before the call to png_set_unknown_chunks. - */ - if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && - chunk < info_ptr->unknown_chunks_num) - { - if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0) - { - png_app_error(png_ptr, "invalid unknown chunk location"); - /* Fake out the pre 1.6.0 behavior: */ - if ((location & PNG_HAVE_IDAT) != 0) /* undocumented! */ - location = PNG_AFTER_IDAT; - - else - location = PNG_HAVE_IHDR; /* also undocumented */ - } - - info_ptr->unknown_chunks[chunk].location = - check_location(png_ptr, location); - } - - /* TODO: make this an error in 1.8 (or maybe it will become one in 1.7!) */ - else if (png_ptr != NULL) - png_app_warning(png_ptr, "unknown chunk index out of range"); -} -#endif /* STORE_UNKNOWN_CHUNKS */ - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -static unsigned int -add_one_chunk(png_structrp png_ptr, png_bytep list, unsigned int count, - png_const_bytep add, int keep) -{ - unsigned int i; - - /* Utility function: update the 'keep' state of a chunk if it is already in - * the list, otherwise add it to the list. - */ - for (i=0; i= PNG_HANDLE_CHUNK_LAST) - { - png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep"); - return; - } - -# ifndef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED - /* This is only a warning; if the application handles the chunk with a - * read callback it may work fine. - */ - if (png_ptr->read_struct && keep >= PNG_HANDLE_CHUNK_IF_SAFE) - png_app_warning(png_ptr, - "png_set_keep_unknown_chunks: unsupported keep"); -# endif - - if (num_chunks_in <= 0) - { - png_ptr->unknown_default = (unsigned)keep & 0x3; - - /* '0' means just set the flags, so stop here */ - if (num_chunks_in == 0) - return; - } - - if (num_chunks_in < 0) - { - /* Ignore all unknown chunks and all chunks recognized by - * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND - */ - static PNG_CONST png_byte chunks_to_ignore[] = { - 98, 75, 71, 68, '\0', /* bKGD */ - 99, 72, 82, 77, '\0', /* cHRM */ - 103, 65, 77, 65, '\0', /* gAMA */ - 104, 73, 83, 84, '\0', /* hIST */ - 105, 67, 67, 80, '\0', /* iCCP */ - 105, 84, 88, 116, '\0', /* iTXt */ - 111, 70, 70, 115, '\0', /* oFFs */ - 112, 67, 65, 76, '\0', /* pCAL */ - 112, 72, 89, 115, '\0', /* pHYs */ - 115, 66, 73, 84, '\0', /* sBIT */ - 115, 67, 65, 76, '\0', /* sCAL */ - 115, 80, 76, 84, '\0', /* sPLT */ - 115, 84, 69, 82, '\0', /* sTER */ - 115, 82, 71, 66, '\0', /* sRGB */ - 116, 69, 88, 116, '\0', /* tEXt */ - 116, 73, 77, 69, '\0', /* tIME */ - 122, 84, 88, 116, '\0' /* zTXt */ - }; - - chunk_list = chunks_to_ignore; - num_chunks = (unsigned int)/*SAFE*/(sizeof chunks_to_ignore)/5U; - } - - else /* num_chunks_in > 0 */ - { - if (chunk_list == NULL) - { - /* Prior to 1.6.0 this was silently ignored, now it is an app_error - * which can be switched off. - */ - png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list"); - return; - } - - num_chunks = num_chunks_in; - } - - old_num_chunks = png_ptr->num_chunk_list; - if (png_ptr->chunk_list == NULL) - old_num_chunks = 0; - - /* Since num_chunks is always restricted to UINT_MAX/5 this can't overflow. - */ - if (num_chunks + old_num_chunks > UINT_MAX/5) - { - png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks"); - return; - } - - /* If these chunks are being reset to the default then no more memory is - * required because add_one_chunk above doesn't extend the list if the 'keep' - * parameter is the default. - */ - if (keep != 0) - { - new_list = png_voidcast(png_bytep, png_malloc(png_ptr, - 5 * (num_chunks + old_num_chunks))); - - if (old_num_chunks > 0) - memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks); - } - - else if (old_num_chunks > 0) - new_list = png_ptr->chunk_list; - - else - new_list = NULL; - - /* Add the new chunks together with each one's handling code. If the chunk - * already exists the code is updated, otherwise the chunk is added to the - * end. (In libpng 1.6.0 order no longer matters because this code enforces - * the earlier convention that the last setting is the one that is used.) - */ - if (new_list != NULL) - { - png_const_bytep inlist; - png_bytep outlist; - unsigned int i; - - for (i=0; ichunk_list != new_list) - png_free(png_ptr, new_list); - - new_list = NULL; - } - } - - else - num_chunks = 0; - - png_ptr->num_chunk_list = num_chunks; - - if (png_ptr->chunk_list != new_list) - { - if (png_ptr->chunk_list != NULL) - png_free(png_ptr, png_ptr->chunk_list); - - png_ptr->chunk_list = new_list; - } -} -#endif - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED -void PNGAPI -png_set_read_user_chunk_fn(png_structrp png_ptr, png_voidp user_chunk_ptr, - png_user_chunk_ptr read_user_chunk_fn) -{ - png_debug(1, "in png_set_read_user_chunk_fn"); - - if (png_ptr == NULL) - return; - - png_ptr->read_user_chunk_fn = read_user_chunk_fn; - png_ptr->user_chunk_ptr = user_chunk_ptr; -} -#endif - -#ifdef PNG_WRITE_PNG_SUPPORTED -void PNGAPI -png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr, - png_bytepp row_pointers) -{ - png_debug1(1, "in %s storage function", "rows"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (info_ptr->row_pointers != NULL && - (info_ptr->row_pointers != row_pointers)) - png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); - - info_ptr->row_pointers = row_pointers; - - if (row_pointers != NULL) - info_ptr->valid |= PNG_INFO_IDAT; -} -#endif - -void PNGAPI -png_set_compression_buffer_size(png_structrp png_ptr, png_alloc_size_t size) -{ - if (png_ptr == NULL) - return; - - if (size == 0 || - size > (png_ptr->read_struct ? ZLIB_IO_MAX : PNG_UINT_31_MAX)) - png_error(png_ptr, "invalid compression buffer size"); - -# if (defined PNG_SEQUENTIAL_READ_SUPPORTED) || defined PNG_WRITE_SUPPORTED - png_ptr->IDAT_size = (png_uint_32)/*SAFE*/size; -# endif /* SEQUENTIAL_READ || WRITE */ -} - -void PNGAPI -png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask) -{ - if (png_ptr != NULL && info_ptr != NULL) - info_ptr->valid &= PNG_BIC_MASK(mask); -} - - -#ifdef PNG_SET_USER_LIMITS_SUPPORTED -/* This function was added to libpng 1.2.6 */ -void PNGAPI -png_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max, - png_uint_32 user_height_max) -{ - /* Images with dimensions larger than these limits will be - * rejected by png_set_IHDR(). To accept any PNG datastream - * regardless of dimensions, set both limits to 0x7fffffffL. - */ - if (png_ptr == NULL) - return; - - png_ptr->user_width_max = user_width_max; - png_ptr->user_height_max = user_height_max; -} - -/* This function was added to libpng 1.4.0 */ -void PNGAPI -png_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max) -{ - if (png_ptr != NULL) - png_ptr->user_chunk_cache_max = user_chunk_cache_max; -} - -/* This function was added to libpng 1.4.1 */ -void PNGAPI -png_set_chunk_malloc_max (png_structrp png_ptr, - png_alloc_size_t user_chunk_malloc_max) -{ - if (png_ptr != NULL) - png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; -} -#endif /* ?SET_USER_LIMITS */ -#endif /* READ || WRITE */ diff --git a/ext/libpng17/pngstruct.h b/ext/libpng17/pngstruct.h deleted file mode 100644 index c6ca8475e0..0000000000 --- a/ext/libpng17/pngstruct.h +++ /dev/null @@ -1,777 +0,0 @@ - -/* pngstruct.h - header file for PNG reference library - * - * Last changed in libpng 1.7.0 [(PENDING RELEASE)] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* The structure that holds the information to read and write PNG files. - * The only people who need to care about what is inside of this are the - * people who will be modifying the library for their own special needs. - * It should NOT be accessed directly by an application. - */ - -#ifndef PNGSTRUCT_H -#define PNGSTRUCT_H -/* zlib.h defines the structure z_stream, an instance of which is included - * in this structure and is required for decompressing the LZ compressed - * data in PNG files. - */ -#ifndef ZLIB_CONST - /* We must ensure that zlib uses 'const' in declarations. */ -# define ZLIB_CONST -#endif /* !ZLIB_CONST */ - -#include PNG_ZLIB_HEADER - -#ifdef const - /* zlib.h sometimes #defines const to nothing, undo this. */ -# undef const -#endif /* const */ - -/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility - * with older builds. - */ -#if ZLIB_VERNUM < 0x1260 -# define PNGZ_MSG_CAST(s) png_constcast(char*,s) -# define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b) -#else /* ZLIB_VERNUM >= 0x1260 */ -# define PNGZ_MSG_CAST(s) (s) -# define PNGZ_INPUT_CAST(b) (b) -#endif /* ZLIB_VERNUM >= 0x1260 */ - -/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib - * can handle at once. This type need be no larger than 16 bits (so maximum of - * 65535), this define allows us to discover how big it is, but limited by the - * maximum for size_t. The value can be overridden in a library build (pngusr.h, - * or set it in CPPFLAGS) and it works to set it to a considerably lower value - * (e.g. 255 works). A lower value may help memory usage (slightly) and may - * even improve performance on some systems (and degrade it on others.) - */ -#ifndef ZLIB_IO_MAX -# ifdef __COVERITY__ -# define ZLIB_IO_MAX ((uInt)255U) /* else COVERITY whines */ -# else /* !COVERITY */ -# define ZLIB_IO_MAX ((uInt)-1) -# endif /* !COVERITY */ -#endif /* !ZLIB_IO_MAX */ - -#ifdef PNG_WRITE_SUPPORTED -/* The write compression control (allocated on demand). - * TODO: use this for the read state too. - */ -typedef struct png_zlib_state *png_zlib_statep; -#endif /* WRITE */ - -/* Colorspace support; structures used in png_struct, png_info and in internal - * functions to hold and communicate information about the color space. - * - * PNG_COLORSPACE_SUPPORTED is only required if the application will perform - * colorspace corrections, otherwise all the colorspace information can be - * skipped and the size of libpng can be reduced (significantly) by compiling - * out the colorspace support. - */ -#ifdef PNG_COLORSPACE_SUPPORTED -/* The chromaticities of the red, green and blue colorants and the chromaticity - * of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)). - */ -typedef struct png_xy -{ - png_fixed_point redx, redy; - png_fixed_point greenx, greeny; - png_fixed_point bluex, bluey; - png_fixed_point whitex, whitey; -} png_xy; - -/* The same data as above but encoded as CIE XYZ values. When this data comes - * from chromaticities the sum of the Y values is assumed to be 1.0 - */ -typedef struct png_XYZ -{ - png_fixed_point red_X, red_Y, red_Z; - png_fixed_point green_X, green_Y, green_Z; - png_fixed_point blue_X, blue_Y, blue_Z; -} png_XYZ; -#endif /* COLORSPACE */ - -#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) -/* A colorspace is all the above plus, potentially, profile information; - * however at present libpng does not use the profile internally so it is only - * stored in the png_info struct (if iCCP is supported.) The rendering intent - * is retained here and is checked. - * - * The file gamma encoding information is also stored here and gamma correction - * is done by libpng, whereas color correction must currently be done by the - * application. - */ -typedef struct png_colorspace -{ -#ifdef PNG_GAMMA_SUPPORTED - png_fixed_point gamma; /* File gamma */ -#endif /* GAMMA */ - -#ifdef PNG_COLORSPACE_SUPPORTED - png_xy end_points_xy; /* End points as chromaticities */ - png_XYZ end_points_XYZ; /* End points as CIE XYZ colorant values */ - png_uint_16 rendering_intent; /* Rendering intent of a profile */ -#endif /* COLORSPACE */ - - /* Flags are always defined to simplify the code. */ - png_uint_16 flags; /* As defined below */ -} png_colorspace, * PNG_RESTRICT png_colorspacerp; - -typedef const png_colorspace * PNG_RESTRICT png_const_colorspacerp; - -/* General flags for the 'flags' field */ -#define PNG_COLORSPACE_HAVE_GAMMA 0x0001U -#define PNG_COLORSPACE_HAVE_ENDPOINTS 0x0002U -#define PNG_COLORSPACE_HAVE_INTENT 0x0004U -#define PNG_COLORSPACE_FROM_gAMA 0x0008U -#define PNG_COLORSPACE_FROM_cHRM 0x0010U -#define PNG_COLORSPACE_FROM_sRGB 0x0020U -#define PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB 0x0040U -#define PNG_COLORSPACE_MATCHES_sRGB 0x0080U /* exact match on profile */ -#define PNG_COLORSPACE_RGB_TO_GRAY_SET 0x0100U /* user specified coeffs */ -#define PNG_COLORSPACE_INVALID 0x8000U -#define PNG_COLORSPACE_CANCEL(flags) (0xffffU - (flags)) -#endif /* COLORSPACE || GAMMA */ - -#ifdef PNG_TRANSFORM_MECH_SUPPORTED -/***************************** READ and WRITE TRANSFORMS *********************** - * These structures are used in pngrtran.c, pngwtran.c and pngtrans.c to hold - * information about transforms in progress. This mechanism was introduced in - * libpng 1.7.0 to ensure reliable transform code and to fix multiple bugs in - * the pre-1.7 transform handling. - * - * Prior to 1.7.0 the internal transform routines took a png_row_infop, like the - * user transform function, but without the png_ptr because it was never used. - * In 1.7.0 a separate internal structure is used in place of this to allow both - * future development to change the structure. - * - * The values in this structure will normally be changed by transformation - * implementations. - ***************************** READ and WRITE TRANSFORMS **********************/ -typedef struct -{ - png_structp png_ptr; /* png_struct for error handling and some - * transform parameters. May be aliased. - */ - png_const_voidp sp; /* Source; the input row. */ - png_voidp dp; /* Output buffer for the transformed row, - * this may be the same as sp. - */ - /* If the row is changed the tranform routine must write the result to - * dp[] and set sp to dp, otherwise it must not write to dp and must leave - * sp unchanged. dp[] and sp[] are both 'malloc' aligned; i.e. they have - * the system alignment, so the data can be read as any valid ANSI-C - * type. - */ - png_uint_32 width; /* width of row */ -# ifdef PNG_READ_GAMMA_SUPPORTED - png_fixed_point gamma; /* Current gamma of the row data */ - /* When a row is being transformed this contains the current gamma of the - * data if known. During initialization the value is used to accumulate - * information for png_struct::row_gamma in the first step, - * PNG_TC_INIT_FORMAT, then used to insert the correct gamma transforms - * during PNG_TC_INIT_FINAL. The field is only used on read; write - * transforms do not modify the gamma of the data. - */ -# endif /* READ_GAMMA */ - unsigned int format; /* As pngstruct::row_format below */ - unsigned int range; /* Count of range transforms */ -# define PNG_TC_CHANNELS(tc) PNG_FORMAT_CHANNELS((tc).format) - unsigned int bit_depth; /* bit depth of row */ - png_byte sBIT_R; - png_byte sBIT_G; - png_byte sBIT_B; - png_byte sBIT_A; /* Signnificant bits in the row channels. */ - /* The above four values are initially set to the number of bits significant - * in the input PNG data, R/G/B are set to the same (gray) value for - * grayscale input. All values are set to the bit depth if there is no sBIT - * chunk, if there is no alpha channel sBIT_A is set to the bit depth. - * - * When any potentially spurious bits have been cleared PNG_INFO_sBIT will be - * set in invalid_info. From this point on the above values record the - * approximate number of bits of accuracy in the channels and the lower bits - * should be preserved; they potentially contain useful information. - */ -# define PNG_TC_PIXEL_DEPTH(tc) (PNG_TC_CHANNELS(tc) * (tc).bit_depth) -# define PNG_TC_ROWBYTES(tc) PNG_ROWBYTES(PNG_TC_PIXEL_DEPTH(tc), (tc).width) - unsigned int invalid_info; /* PNG_INFO_* for invalidated chunks */ - unsigned int cost; /* Cache cost */ -# define PNG_CACHE_COST_LIMIT 0x100U - /* This is a runtime structure, so size doesn't matter much, and it helps - * code reliability to use real member names here. Feel free to experiment - * with integer values rather than bitfields. - */ - unsigned int init :2; /* 0 for processing, non zero for init: */ -# define PNG_TC_INIT_FORMAT 0x01U /* Initialization step 1: just set 'format', - * 'bit_depth' and 'gamma' to the output - * values iff the transform corresponds to - * a user requested change to those values. - */ -# define PNG_TC_INIT_FINAL 0x03U /* Initialization step 2; set the 'format' - * 'bit_depth' and 'gamma' to the values the - * transform will actually produce (which - * need not be the same as the above). - */ - /* During initialization 'init' must be set and sp and dp may be NULL. If - * neither flag is set sp and dp must be non-NULL. - * - * When the transform runs it must update 'format', 'bit_depth' and 'gamma' - * to the values previously reported during PNG_TC_INIT_FINAL; not doing so - * may result in an affirm from a later transform. - */ - unsigned int caching :1; /* The color values are being used to - * generate a cache of the transforms. - */ - unsigned int palette :1; /* The values come from a PNG palette and - * the palette will not be expanded. The - * CACHE flag must be set too. A - * transform which causes the palette to - * be expanded must clear this flag. - */ -#if 0 /* NYI */ - unsigned int interchannel:1; /* Set by a transform that combines two or - * more channels together; for example - * alpha composition or RGB to gray. - */ -#endif /* NYI */ - unsigned int channel_add :1; /* A channel (alpha/filler) was added */ - unsigned int strip_alpha :1; /* Set if the alpha channel will be - * stripped on read, this also prevents - * the tRNS chunk being expanded. Only - * some transforms check this, depending - * on the handling order and checks in - * pre-1.7 versions. - */ - unsigned int expand_tRNS :1; /* Set if the tRNS chunk should be - * expanded (ignored if read_strip_alpha - * is set). If this is *not* set - * transforms which do not use alpha/tRNS - * but would invalidate it (such as - * simple gamma correction) will simply - * mark the tRNS info as invalid. - */ - unsigned int transparent_alpha :1; /* Indicates that the alpha channel - * consists entirely of opaque (1.0 alpha) - * or completely transparent (0.0 alpha) - * pixels. Set when tRNS is expanded to - * alpha. - */ - unsigned int optimized_alpha :1; /* Meaningful only when bit_depth is - * 16 and gamma is 1 or unknown (0). - * Indicates that pixels which are opaque - * (alpha 1.0) have not been expanded to - * 16-bit linear; instead these pixels - * are encoded in the final format in - * png_struct::row_bit_depth and - * png_struct::row_gamma. This will - * invariably match the file format. - */ -} png_transform_control, *png_transform_controlp; - -typedef const png_transform_control *png_const_transform_controlp; -typedef const png_row_info *png_const_row_infop; - -typedef struct png_transform *png_transformp; /* Forward declaration */ -typedef void (*png_transform_free_fn)(/* Function to free a transform */ - png_const_structrp png_ptr, - png_transformp transform); /* pointer to this transform */ - /* This function need not exist in a transform, it must free all the data - * allocated within the transform but not the transform itself. It is called - * from png_transform_free. - */ -typedef void (*png_transform_fn)(/* Function to implement a transform */ - png_transformp *transform, /* pointer to this transform */ - png_transform_controlp control); /* row information */ - /* The transform function has two modes of operation: - * - * 1) Initialization. The list of transforms is processed from the start to - * the end and each function is called with one of hte PNG_TC_INIT_ flags - * set in control->flags, control->dp and control->sp may be NULL. - * - * For read the control structure contains the input row format and bit - * depth, the transform function changes this to represent what the - * transform will produce when it runs. - * - * For write the control structure contains the *required* output format - * and bit depth. The transform function changes this to the values that - * it needs to produce the required values. - * - * In both cases the transform function may update the 'fn' function to a - * new function to perform the desired transform; this allows considerable - * optimization on multi-row images. - * - * In both cases the caller considers the pixel bit depth changes and - * records the maximum required so that it can allocate a suitably sized - * buffer. - * - * 2) Execution. - * - * In the read case the transforms are processed in the stored order and - * must transform the row data appropriately *and* update the bit depth - * and format as before. - * - * In the write case the transforms are called in the reverse order and - * the input bit depth and format should match the required values. - * - * It is valid during initialization for the transform function to push - * another transform into the list in either the read or the write case if - * the transform cannot handle (read) or produce (write) the required format. * The transform pushes another transform into the list ahead of itself (at - * *transform) and runs that initialization; when control is returned to the - * caller the caller will re-run the transform initialization. - * - * It is also valid (during initialization) to push new transforms onto the - * list, just so long as the order of the transform is greater than the - * current transform (so that the caller will still call the new transform - * initialization.) - * - * In the write case the user transform callback might still end up producing - * an unexpected format, but at present this is unavoidable; the libpng API - * is extremely inconsistent in how a user transform reports the changes it - * made. - * - * TODO: fix this, probably with an API change in 1.7.0 - */ -typedef struct png_transform /* Linked list of transform functions */ -{ - png_transformp next; /* Next transform in the list */ - png_transform_fn fn; /* Function to implement the transform */ - png_transform_free_fn free; /* Free allocated data, normally NULL */ - unsigned int order; /* Order of the transform in the list. */ - unsigned int size; /* Size of this structure (max 65535) */ - png_uint_32 args; /* Optional transform arguments. */ -} png_transform; -#endif /* TRANSFORM_MECH */ - -/* Action to take on CRC errors (four values) */ -typedef enum -{ - crc_error_quit = PNG_CRC_ERROR_QUIT-1, - crc_warn_discard = PNG_CRC_WARN_DISCARD-1, - crc_warn_use = PNG_CRC_WARN_USE-1, - crc_quiet_use = PNG_CRC_QUIET_USE-1 -} png_crc_action; - -struct png_struct_def -{ - /* Rearranged in libpng 1.7 to attempt to lessen padding; in general - * (char), (short), (int) and pointer types are kept separate; however - * associated members under the control of the same #define are still - * together. - */ -#ifdef PNG_SETJMP_SUPPORTED - /* jmp_buf can have very high alignment requirements on some systems, so put - * it first (the other setjmp members are later as they are infrequently - * accessed.) - */ - jmp_buf jmp_buf_local; -#endif /* SETJMP */ - - /* Next the frequently accessed fields. Many processors perform arithmetic - * in the address pipeline, but frequently the amount of addition or - * subtraction is limited. By putting these fields at the head of png_struct - * the hope is that such processors will generate code that is both smaller - * and faster. - */ -#ifdef PNG_READ_SUPPORTED - png_colorp palette; /* palette from the input file */ -#endif /* READ */ -#ifdef PNG_READ_tRNS_SUPPORTED - png_bytep trans_alpha; /* alpha values for paletted files */ -#endif /* READ_tRNS */ - - png_uint_32 width; /* width of image in pixels */ - png_uint_32 height; /* height of image in pixels */ - png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */ -#ifdef PNG_READ_SUPPORTED - png_uint_32 chunk_length; /* Length (possibly remaining) in said chunk. */ -#endif /* READ */ - png_uint_32 crc; /* current chunk CRC value */ - - unsigned int mode :6; /* where we are in the PNG file */ - unsigned int read_struct :1; /* this is a read (not write) struct */ - unsigned int num_palette :9; /* number of color entries in palette */ -#ifdef PNG_READ_tRNS_SUPPORTED - unsigned int num_trans :9; /* number of transparency values */ - unsigned int transparent_palette :1; /* if they are all 0 or 255 */ -#endif /* READ_tRNS */ -#ifdef PNG_PALETTE_MAX_SUPPORTED - unsigned int palette_index_max :8; /* maximum palette index in IDAT */ - unsigned int palette_index_check :2; /* one of the following: */ -# define PNG_PALETTE_CHECK_DEFAULT 0U -# define PNG_PALETTE_CHECK_OFF 1U -# define PNG_PALETTE_CHECK_ON 2U - unsigned int palette_index_have_max :1; /* max is being set */ - unsigned int palette_index_check_issued :1; /* error message output */ -#endif /* PALETTE_MAX */ -#ifdef PNG_READ_tRNS_SUPPORTED - png_color_16 trans_color; /* transparent color for non-paletted files */ -#endif /* READ_tRNS */ -#ifdef PNG_READ_sBIT_SUPPORTED - png_color_8 sig_bit; /* significant bits in each channel */ -#endif /* READ_sBIT */ - - /* Single byte values, typically used either to save space or to hold 1-byte - * values from the PNG chunk specifications. - */ - png_byte filter_method; /* file filter type (only non-0 with MNG) */ - png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ - png_byte color_type; /* color type of file */ - png_byte bit_depth; /* bit depth of file */ - png_byte sig_bytes; /* magic bytes read/written at start of file */ - -#ifdef PNG_READ_SUPPORTED -#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) - /* The png_struct colorspace structure is only required on read - on write it - * is in (just) the info_struct. - */ - png_colorspace colorspace; -#endif /* COLORSPACE || GAMMA */ -#endif /* READ */ - - /* Transform handling */ -#ifdef PNG_TRANSFORM_MECH_SUPPORTED - png_transformp transform_list; /* List of transformation to perform. */ -#endif /* TRANSFORM_MECH */ - - /* ROW BUFFERS and CONTROL - * - * Members used for image row compression (write) or decompression (read). - * filter byte (which is in next_filter.) All fields are only used during - * IDAT processing and start of 0. - */ -#ifdef PNG_READ_SUPPORTED - png_bytep row_buffer; /* primary row buffer */ -#if (defined(PNG_PROGRESSIVE_READ_SUPPORTED) ||\ - defined(PNG_READ_INTERLACING_SUPPORTED)) &&\ - defined(PNG_TRANSFORM_MECH_SUPPORTED) - png_bytep transformed_row; /* pointer to the transformed row, if - * required. May point to row_buffer. - */ -#endif /* (PROGRESSIVE_READ || READ_INTERLACING) && TRANSFORM_MECH */ - - png_alloc_size_t row_bytes_read; /* Total read in row */ -#endif /* READ */ - - png_uint_32 row_number; /* current row in pass */ -#ifdef PNG_READ_SUPPORTED -#ifdef PNG_READ_GAMMA_SUPPORTED - png_fixed_point row_gamma; /* Gamma of final output */ -#if 0 /* NYI */ - unsigned int gamma_accuracy; - /* LINEAR gamma cache table size (in bits) times 100; for non-linear - * tables the value used is gamma_accuracy/gamma where 'gamma' is the - * encoding value of the data (typically less than 1). - * - * default: PNG_DEFAULT_GAMMA_ACCURACY (665) - */ -#endif /* NYI */ - png_uint_16 gamma_threshold; - /* Gamma threshold value as a fixed-point value in the range 0..1; the - * threshold at or below which gamma correction is skipped. '0' forces - * gamma correction even when there is none because the input and output - * gammas are equal. - * - * default: PNG_GAMMA_THRESHOLD_FIXED (153) - */ -#endif /* READ_GAMMA */ -#ifdef PNG_READ_TRANSFORMS_SUPPORTED - unsigned int invalid_info; /* PNG_INFO_* for invalidated chunks */ - unsigned int palette_updated:1; /* png_struct::palette changed */ -#endif /* READ_TRANSFORMS */ -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED - unsigned int read_started :1; /* at least one call to png_read_row */ -#endif /* SEQUENTIAL_READ */ - /* The next field is just used by the read IDAT process functions to store - * the state of IDAT processing; they should not be altered or used by other - * functions. - */ - unsigned int row_state :2; /* state of row parsing (internal) */ -#endif /* READ */ - -#if defined (PNG_READ_INTERLACING_SUPPORTED) ||\ - defined (PNG_WRITE_INTERLACING_SUPPORTED) - unsigned int do_interlace :1; /* libpng handles the interlace */ -# endif /* R/W INTERLACING */ - - unsigned int pass :3; /* current (interlace) pass (0 - 6) */ - - /* The following fields are set by png_row_init to the pixel depths of the - * pixels at various states. If transforms are not supported they will - * always be the same value: - * - * READ WRITE - * input: PNG From application - * output: To application PNG - * max: Largest in transform - */ - unsigned int row_input_pixel_depth :8; - unsigned int row_output_pixel_depth :8; - unsigned int row_max_pixel_depth :8; - -# define PNG_RF_BITS 9 /* Number of bits required for the row format (below) */ -#ifdef PNG_TRANSFORM_MECH_SUPPORTED - /* The following fields describe the format of the user row; the output on - * read or the input on write, and give the maximum pixel depth, which - * controls the row buffer allocation size (row_allocated_bytes) above. - */ - unsigned int row_range :3; /* range error count */ - unsigned int row_bit_depth :6; /* bits per channel (up to 32) */ - unsigned int row_format:PNG_RF_BITS;/* format of output(R)/input(W) row: */ - /* PNG_FORMAT_FLAG_ALPHA 0x01U format with an alpha channel - * PNG_FORMAT_FLAG_COLOR 0x02U color format: otherwise grayscale - * PNG_FORMAT_FLAG_LINEAR 0x04U NOT used (informational) - * PNG_FORMAT_FLAG_COLORMAP 0x08U image data is color-mapped - * PNG_FORMAT_FLAG_BGR 0x10U BGR colors, else order is RGB - * PNG_FORMAT_FLAG_AFIRST 0x20U alpha channel comes first * - * PNG_FORAMT_FLAG_AFILLER 0x40U The 'alpha' channel is a filler: - * PNG_FORMAT_FLAG_ALPHA is set however the value in the alpha channel - * is not an alpha value and (therefore) cannot be used for alpha - * computations, it is just a filler value. PNG_COLOR_TYPE_FROM_FORMAT - * will return a color type *without* PNG_COLOR_MASK_ALPHA, however - * PNG_FORMAT_CHANNELS will return the correct number, including the - * filler channel. - * PNG_FORMAT_FLAG_SWAPPED 0x80U bytes or bits swapped: - * When the bit depth is 16 this means that the bytes within the - * components have been swapped, when the bit depth is less than 8 - * it means the pixels within the bytes have been swapped. It should - * not be set for 8-bit compononents (it is meaningless). - * PNG_FORMAT_FLAG_RANGE 0x100U component range not 0..bit-depth: - * Low-bit-depth grayscale components have been unpacked into bytes - * without scaling, or RGB[A] pixels have been shifted back to the - * significant-bit range from the sBIT chunk or channels (currently - * alpha or gray) have been inverted. - * PNG_FORMAT_FLAG_INVALID NOT STORED HERE - */ -#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED - unsigned int info_format:PNG_RF_BITS; - /* This field is used to validate the png_info used to write the - * IHDR. This is a new check in 1.7.0; previously it was possible to pass - * a png_info from a png_read with the read tranform information in the - * format having manually removed the required transforms from the rows - * passed to png_write_row. - */ -#endif /* WRITE_TRANSFORMS */ -#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED - unsigned int write_invert_alpha :1; - /* This indicates the png_set_invert_alpha was called, it is used by the - * write code to implement the transform without needing to run the whole - * transform mechanism on the PNG palette data. - */ -#endif /* WRITE_INVERT_ALPHA */ -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - unsigned int rgb_to_gray_status :1; - /* If set an RGB pixel was encountered by the RGB to gray transform - * wherein !(r==g==b). - */ -#endif /* RGB_TO_GRAY */ -#endif /* TRANSFORM_MECH */ - -#ifdef PNG_READ_SUPPORTED - /* These, and IDAT_size below, control how much input and output (at most) is - * available to zlib during read decompression. - */ - png_alloc_size_t read_buffer_size; /* current size of the buffer */ -#endif /* READ */ - -#if defined(PNG_SEQUENTIAL_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - png_uint_32 IDAT_size; /* limit on IDAT read and write IDAT size */ -#endif /* SEQUENTIAL_READ || WRITE */ - - /* ERROR HANDLING */ -#ifdef PNG_SETJMP_SUPPORTED - jmp_buf *jmp_buf_ptr; /* passed to longjmp_fn */ - png_longjmp_ptr longjmp_fn; /* setjmp non-local goto function. */ - size_t jmp_buf_size; /* size of *jmp_buf_ptr, if allocated */ -#endif /* SETJMP */ - - /* Error/warning callbacks */ - png_error_ptr error_fn; /* print an error message and abort */ -#ifdef PNG_WARNINGS_SUPPORTED - png_error_ptr warning_fn; /* print a warning and continue */ -#endif /* WARNINGS */ - png_voidp error_ptr; /* user supplied data for the above */ - - /* MEMORY ALLOCATION */ -#ifdef PNG_USER_MEM_SUPPORTED - png_malloc_ptr malloc_fn; /* allocate memory */ - png_free_ptr free_fn; /* free memory */ - png_voidp mem_ptr; /* user supplied data for the above */ -#endif /* USER_MEM */ - - /* IO and BASIC READ/WRITE SUPPORT */ - png_voidp io_ptr; /* user supplied data for IO callbacks */ - png_rw_ptr rw_data_fn; /* read/write some bytes (must succeed) */ - -#ifdef PNG_READ_SUPPORTED - png_read_status_ptr read_row_fn; /* called after each row is decoded */ - png_bytep read_buffer; /* buffer for reading chunk data */ - - /* During read the following array is set up to point to the appropriate - * un-filter function, this allows per-image and per-processor optimization. - */ - void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_alloc_size_t row_bytes, - unsigned int bpp, png_bytep row, png_const_bytep prev_row, - png_const_bytep prev_pixels); -#endif /* READ */ - -#ifdef PNG_WRITE_SUPPORTED - png_write_status_ptr write_row_fn; /* called after each row is encoded */ - -#ifdef PNG_WRITE_FLUSH_SUPPORTED - png_flush_ptr output_flush_fn; /* Function for flushing output */ -#endif /* WRITE_FLUSH */ -#endif /* WRITE */ - -#ifdef PNG_SET_USER_LIMITS_SUPPORTED - png_uint_32 user_width_max; /* Maximum width on read */ - png_uint_32 user_height_max; /* Maximum height on read */ - /* Total memory that a single zTXt, sPLT, iTXt, iCCP, or unknown chunk - * can occupy when decompressed. 0 means unlimited. This field is a counter - * - it is decremented as memory is allocated. - */ - png_alloc_size_t user_chunk_malloc_max; -#endif /* SET_USER_LIMITS */ -#ifdef PNG_USER_LIMITS_SUPPORTED - /* limit on total *number* of sPLT, text and unknown chunks that can be - * stored. 0 means unlimited. This field is a counter - it is decremented - * as chunks are encountered. - */ - png_uint_32 user_chunk_cache_max; -#endif /* USER_LIMITS */ - - /* The progressive reader gets passed data and calls application handling - * functions when appropriate. - */ -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED - png_progressive_info_ptr info_fn; /* called after header data fully read */ - png_progressive_row_ptr row_fn; /* called after a row is decoded */ - png_progressive_end_ptr end_fn; /* called after image is complete */ - - /* Progressive read control data */ - png_bytep save_buffer_ptr; /* current location in save_buffer */ - png_bytep save_buffer; /* buffer for previously read data */ - png_bytep current_buffer_ptr; /* current location in current_buffer */ - - size_t save_buffer_size; /* amount of data now in save_buffer */ - size_t save_buffer_max; /* total size of save_buffer */ - size_t current_buffer_size; /* amount of data now in current_buffer */ - size_t buffer_size; /* total amount of available input data */ - - unsigned int process_mode :8; - /* This is one or two four bit codes describing the current state of the - * 'push' reader. Normally the low four bits are a state code, however in - * some cases this may be pushed to the top four bits and replaced by a - * different temporary state code. The value is, in effect, a two entry - * stack. - */ -#endif /* PROGRESSIVE_READ */ - -#ifdef PNG_IO_STATE_SUPPORTED - png_uint_32 io_state; /* tells the app read/write progress */ -#endif /* IO_STATE */ - - /* UNKNOWN CHUNK HANDLING */ - /* TODO: this is excessively complicated, there are multiple ways of doing - * the same thing. It should be cleaned up, possibly by finding out which - * APIs applications really use. - */ -#ifdef PNG_USER_CHUNKS_SUPPORTED - /* General purpose pointer for all user/unknown chunk handling; points to - * application supplied data for use in the read_user_chunk_fn callback - * (currently there is no write side support - the write side must use the - * set_unknown_chunks interface.) - */ - png_voidp user_chunk_ptr; -#endif /* USER_CHUNKS */ - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - /* This is called back from the unknown chunk handling */ - png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ -#endif /* READ_USER_CHUNKS */ - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - png_uint_32 known_unknown; /* Bit mask of known chunks to be treated as - * unknown in the read code. - */ -#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED - png_uint_32 save_unknown; /* Whether to save or skip these chunks: - * 'save' is 'known & save', 'skip' is - * 'known & ~save'. - */ -# define png_IDATs_skipped(pp) (((pp)->known_unknown & ~(pp)->save_unknown)&1U) -#else /* !SAVE_UNKNOWN_CHUNKS */ -# define png_IDATs_skipped(pp) ((pp)->known_unknown & 1U) -#endif /* !SAVE_UNKNOWN_CHUNKS */ -#endif /* HANDLE_AS_UNKNOWN */ - -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - png_bytep chunk_list; /* List of png_byte[5]; the textual chunk name - * followed by a PNG_HANDLE_* byte */ - unsigned int unknown_default :2; /* As PNG_HANDLE_* */ - unsigned int num_chunk_list; /* Number of entries in the list */ -#endif /* SET_UNKNOWN_CHUNKS */ - - /* COMPRESSION AND DECOMPRESSION SUPPORT. - * - * zlib expects a 'zstream' as the fundamental control structure, it allows - * all the parameters to be passed as one pointer. - */ - png_uint_32 zowner; /* ID (chunk type) of zlib owner, 0 if none */ -# ifdef PNG_WRITE_SUPPORTED - png_zlib_statep zlib_state; /* State of zlib compression */ -# endif /* WRITE */ -# ifdef PNG_READ_SUPPORTED - z_stream zstream; /* decompression structure */ - unsigned int zstream_ended:1; /* no more zlib output available [read] */ - unsigned int zstream_error:1; /* zlib error message has been output [read] */ -# endif /* READ */ -# ifdef PNG_PROGRESSIVE_READ_SUPPORTED - unsigned int zstream_eod :1; /* all the required uncompressed data has been - * received; set by the zstream using code for - * its own purposes. [progressive read] */ -# endif /* PROGRESSIVE_READ */ -# ifdef PNG_BENIGN_ERRORS_SUPPORTED - unsigned int benign_error_action :2; - unsigned int app_warning_action :2; - unsigned int app_error_action :2; -# ifdef PNG_READ_SUPPORTED - unsigned int IDAT_error_action :2; -# endif /* READ */ -# endif /* BENIGN_ERRORS */ -# ifdef PNG_READ_SUPPORTED - /* CRC checking actions, one for critical chunks, one for ancillary - * chunks. - */ - unsigned int critical_crc :2; - unsigned int ancillary_crc :2; - unsigned int current_crc :2; /* Cache of one or other of the above */ -# endif -# ifdef PNG_SET_OPTION_SUPPORTED -# ifdef PNG_READ_SUPPORTED - unsigned int maximum_inflate_window :1U; -# endif /* READ */ - unsigned int skip_sRGB_profile_check :1U; -# endif /* SET_OPTION */ - - /* MNG SUPPORT */ -#ifdef PNG_MNG_FEATURES_SUPPORTED - unsigned int mng_features_permitted :3; -#endif /* MNG_FEATURES */ - - /* SCRATCH buffers, used when control returns to the application or a read - * loop. - */ -# ifdef PNG_READ_SUPPORTED - png_byte scratch[PNG_ROW_BUFFER_SIZE+16U]; -# endif /* READ */ -}; -#endif /* PNGSTRUCT_H */ diff --git a/ext/libpng17/pngtest.c b/ext/libpng17/pngtest.c deleted file mode 100644 index d872d803e7..0000000000 --- a/ext/libpng17/pngtest.c +++ /dev/null @@ -1,2086 +0,0 @@ - -/* pngtest.c - a simple test program to test libpng - * - * Last changed in libpng 1.6.26 [(PENDING RELEASE)] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This program reads in a PNG image, writes it out again, and then - * compares the two files. If the files are identical, this shows that - * the basic chunk handling, filtering, and (de)compression code is working - * properly. It does not currently test all of the transforms, although - * it probably should. - * - * The program will report "FAIL" in certain legitimate cases: - * 1) when the compression level or filter selection method is changed. - * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192. - * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks - * exist in the input file. - * 4) others not listed here... - * In these cases, it is best to check with another tool such as "pngcheck" - * to see what the differences between the two files are. - * - * If a filename is given on the command-line, then this file is used - * for the input, rather than the default "pngtest.png". This allows - * testing a wide variety of files easily. You can also test a number - * of files at once by typing "pngtest -m file1.png file2.png ..." - */ - -#define _POSIX_SOURCE 1 - -#include -#include -#include - -/* Defined so I can write to a file on gui/windowing platforms */ -/* #define STDERR stderr */ -#define STDERR stdout /* For DOS */ - -#include "png.h" - -/* Known chunks that exist in pngtest.png must be supported or pngtest will fail - * simply as a result of re-ordering them. This may be fixed in 1.7 - * - * pngtest allocates a single row buffer for each row and overwrites it, - * therefore if the write side doesn't support the writing of interlaced images - * nothing can be done for an interlaced image (and the code below will fail - * horribly trying to write extra data after writing garbage). - */ -#if defined PNG_READ_SUPPORTED && /* else nothing can be done */\ - defined PNG_READ_bKGD_SUPPORTED &&\ - defined PNG_READ_cHRM_SUPPORTED &&\ - defined PNG_READ_gAMA_SUPPORTED &&\ - defined PNG_READ_oFFs_SUPPORTED &&\ - defined PNG_READ_pCAL_SUPPORTED &&\ - defined PNG_READ_pHYs_SUPPORTED &&\ - defined PNG_READ_sBIT_SUPPORTED &&\ - defined PNG_READ_sCAL_SUPPORTED &&\ - defined PNG_READ_sRGB_SUPPORTED &&\ - defined PNG_READ_sPLT_SUPPORTED &&\ - defined PNG_READ_tEXt_SUPPORTED &&\ - defined PNG_READ_tIME_SUPPORTED &&\ - defined PNG_READ_zTXt_SUPPORTED &&\ - (defined PNG_WRITE_INTERLACING_SUPPORTED || PNG_LIBPNG_VER >= 10700) - -#ifdef PNG_ZLIB_HEADER -# include PNG_ZLIB_HEADER /* defined by pnglibconf.h from 1.7 */ -#else -# include "zlib.h" -#endif - -/* Copied from pngpriv.h but only used in error messages below. */ -#ifndef PNG_ZBUF_SIZE -# define PNG_ZBUF_SIZE 8192 -#endif -#define FCLOSE(file) fclose(file) - -#ifndef PNG_STDIO_SUPPORTED -typedef FILE * png_FILE_p; -#endif - -/* Makes pngtest verbose so we can find problems. */ -#ifndef PNG_DEBUG -# define PNG_DEBUG 0 -#endif - -#if PNG_DEBUG > 1 -# define pngtest_debug(m) ((void)fprintf(stderr, m "\n")) -# define pngtest_debug1(m,p1) ((void)fprintf(stderr, m "\n", p1)) -# define pngtest_debug2(m,p1,p2) ((void)fprintf(stderr, m "\n", p1, p2)) -#else -# define pngtest_debug(m) ((void)0) -# define pngtest_debug1(m,p1) ((void)0) -# define pngtest_debug2(m,p1,p2) ((void)0) -#endif - -#if !PNG_DEBUG -# define SINGLE_ROWBUF_ALLOC /* Makes buffer overruns easier to nail */ -#endif - -#ifndef PNG_UNUSED -# define PNG_UNUSED(param) (void)param; -#endif - -/* Turn on CPU timing -#define PNGTEST_TIMING -*/ - -#ifndef PNG_FLOATING_POINT_SUPPORTED -#undef PNGTEST_TIMING -#endif - -#ifdef PNGTEST_TIMING -static float t_start, t_stop, t_decode, t_encode, t_misc; -#include -#endif - -#ifdef PNG_TIME_RFC1123_SUPPORTED -#define PNG_tIME_STRING_LENGTH 29 -static int tIME_chunk_present = 0; -static char tIME_string[PNG_tIME_STRING_LENGTH] = "tIME chunk is not present"; - -#if PNG_LIBPNG_VER < 10619 -#define png_convert_to_rfc1123_buffer(ts, t) tIME_to_str(read_ptr, ts, t) - -static int -tIME_to_str(png_structp png_ptr, png_charp ts, png_const_timep t) -{ - png_const_charp str = png_convert_to_rfc1123(png_ptr, t); - - if (str == NULL) - return 0; - - strcpy(ts, str); - return 1; -} -#endif /* older libpng */ -#endif - -static int verbose = 0; -static int strict = 0; -static int relaxed = 0; -static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */ -static int error_count = 0; /* count calls to png_error */ -static int warning_count = 0; /* count calls to png_warning */ - -/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ -#ifndef png_jmpbuf -# define png_jmpbuf(png_ptr) png_ptr->jmpbuf -#endif - -/* Defines for unknown chunk handling if required. */ -#ifndef PNG_HANDLE_CHUNK_ALWAYS -# define PNG_HANDLE_CHUNK_ALWAYS 3 -#endif -#ifndef PNG_HANDLE_CHUNK_IF_SAFE -# define PNG_HANDLE_CHUNK_IF_SAFE 2 -#endif - -/* Utility to save typing/errors, the argument must be a name */ -#define MEMZERO(var) ((void)memset(&var, 0, sizeof var)) - -/* Example of using row callbacks to make a simple progress meter */ -static int status_pass = 1; -static int status_dots_requested = 0; -static int status_dots = 1; - -static void PNGCBAPI -read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) -{ - if (png_ptr == NULL || row_number > PNG_UINT_31_MAX) - return; - - if (status_pass != pass) - { - fprintf(stdout, "\n Pass %d: ", pass); - status_pass = pass; - status_dots = 31; - } - - status_dots--; - - if (status_dots == 0) - { - fprintf(stdout, "\n "); - status_dots=30; - } - - fprintf(stdout, "r"); -} - -#ifdef PNG_WRITE_SUPPORTED -static void PNGCBAPI -write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) -{ - if (png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7) - return; - - fprintf(stdout, "w"); -} -#endif - - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED -/* Example of using a user transform callback (doesn't do anything at present). - */ -static void PNGCBAPI -read_user_callback(png_structp png_ptr, png_row_infop row_info, png_bytep data) -{ - PNG_UNUSED(png_ptr) - PNG_UNUSED(row_info) - PNG_UNUSED(data) -} -#endif - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED -/* Example of using user transform callback (we don't transform anything, - * but merely count the zero samples) - */ - -static png_uint_32 zero_samples; - -static void PNGCBAPI -count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data) -{ - png_bytep dp = data; - if (png_ptr == NULL) - return; - - /* Contents of row_info: - * png_uint_32 width width of row - * png_uint_32 rowbytes number of bytes in row - * png_byte color_type color type of pixels - * png_byte bit_depth bit depth of samples - * png_byte channels number of channels (1-4) - * png_byte pixel_depth bits per pixel (depth*channels) - */ - - /* Counts the number of zero samples (or zero pixels if color_type is 3 */ - - if (row_info->color_type == 0 || row_info->color_type == 3) - { - int pos = 0; - png_uint_32 n, nstop; - - for (n = 0, nstop=row_info->width; nbit_depth == 1) - { - if (((*dp << pos++ ) & 0x80) == 0) - zero_samples++; - - if (pos == 8) - { - pos = 0; - dp++; - } - } - - if (row_info->bit_depth == 2) - { - if (((*dp << (pos+=2)) & 0xc0) == 0) - zero_samples++; - - if (pos == 8) - { - pos = 0; - dp++; - } - } - - if (row_info->bit_depth == 4) - { - if (((*dp << (pos+=4)) & 0xf0) == 0) - zero_samples++; - - if (pos == 8) - { - pos = 0; - dp++; - } - } - - if (row_info->bit_depth == 8) - if (*dp++ == 0) - zero_samples++; - - if (row_info->bit_depth == 16) - { - if ((*dp | *(dp+1)) == 0) - zero_samples++; - dp+=2; - } - } - } - else /* Other color types */ - { - png_uint_32 n, nstop; - int channel; - int color_channels = row_info->channels; - if (row_info->color_type > 3) - color_channels--; - - for (n = 0, nstop=row_info->width; nbit_depth == 8) - if (*dp++ == 0) - zero_samples++; - - if (row_info->bit_depth == 16) - { - if ((*dp | *(dp+1)) == 0) - zero_samples++; - - dp+=2; - } - } - if (row_info->color_type > 3) - { - dp++; - if (row_info->bit_depth == 16) - dp++; - } - } - } -} -#endif /* WRITE_USER_TRANSFORM */ - -#ifndef PNG_STDIO_SUPPORTED -/* START of code to validate stdio-free compilation */ -/* These copies of the default read/write functions come from pngrio.c and - * pngwio.c. They allow "don't include stdio" testing of the library. - * This is the function that does the actual reading of data. If you are - * not reading from a standard C stream, you should create a replacement - * read_data function and use it at run time with png_set_read_fn(), rather - * than changing the library. - */ - -#ifdef PNG_IO_STATE_SUPPORTED -void -pngtest_check_io_state(png_structp png_ptr, png_size_t data_length, - png_uint_32 io_op); -void -pngtest_check_io_state(png_structp png_ptr, png_size_t data_length, - png_uint_32 io_op) -{ - png_uint_32 io_state = png_get_io_state(png_ptr); - int err = 0; - - /* Check if the current operation (reading / writing) is as expected. */ - if ((io_state & PNG_IO_MASK_OP) != io_op) - png_error(png_ptr, "Incorrect operation in I/O state"); - - /* Check if the buffer size specific to the current location - * (file signature / header / data / crc) is as expected. - */ - switch (io_state & PNG_IO_MASK_LOC) - { - case PNG_IO_SIGNATURE: - if (data_length > 8) - err = 1; - break; - case PNG_IO_CHUNK_HDR: - if (data_length != 8) - err = 1; - break; - case PNG_IO_CHUNK_DATA: - break; /* no restrictions here */ - case PNG_IO_CHUNK_CRC: - if (data_length != 4) - err = 1; - break; - default: - err = 1; /* uninitialized */ - } - if (err != 0) - png_error(png_ptr, "Bad I/O state or buffer size"); -} -#endif - -static void PNGCBAPI -pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - png_size_t check = 0; - png_voidp io_ptr; - - /* fread() returns 0 on error, so it is OK to store this in a png_size_t - * instead of an int, which is what fread() actually returns. - */ - io_ptr = png_get_io_ptr(png_ptr); - if (io_ptr != NULL) - { - check = fread(data, 1, length, (png_FILE_p)io_ptr); - } - - if (check != length) - { - png_error(png_ptr, "Read Error"); - } - -#ifdef PNG_IO_STATE_SUPPORTED - pngtest_check_io_state(png_ptr, length, PNG_IO_READING); -#endif -} - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -static void PNGCBAPI -pngtest_flush(png_structp png_ptr) -{ - /* Do nothing; fflush() is said to be just a waste of energy. */ - PNG_UNUSED(png_ptr) /* Stifle compiler warning */ -} -#endif - -/* This is the function that does the actual writing of data. If you are - * not writing to a standard C stream, you should create a replacement - * write_data function and use it at run time with png_set_write_fn(), rather - * than changing the library. - */ -static void PNGCBAPI -pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - png_size_t check; - - check = fwrite(data, 1, length, (png_FILE_p)png_get_io_ptr(png_ptr)); - - if (check != length) - { - png_error(png_ptr, "Write Error"); - } - -#ifdef PNG_IO_STATE_SUPPORTED - pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING); -#endif -} -#endif /* !STDIO */ - -/* This function is called when there is a warning, but the library thinks - * it can continue anyway. Replacement functions don't have to do anything - * here if you don't want to. In the default configuration, png_ptr is - * not used, but it is passed in case it may be useful. - */ -typedef struct -{ - PNG_CONST char *file_name; -} pngtest_error_parameters; - -static void PNGCBAPI -pngtest_warning(png_structp png_ptr, png_const_charp message) -{ - PNG_CONST char *name = "UNKNOWN (ERROR!)"; - pngtest_error_parameters *test = - (pngtest_error_parameters*)png_get_error_ptr(png_ptr); - - ++warning_count; - - if (test != NULL && test->file_name != NULL) - name = test->file_name; - - fprintf(STDERR, "%s: libpng warning: %s\n", name, message); -} - -/* This is the default error handling function. Note that replacements for - * this function MUST NOT RETURN, or the program will likely crash. This - * function is used by default, or if the program supplies NULL for the - * error function pointer in png_set_error_fn(). - */ -static void PNGCBAPI -pngtest_error(png_structp png_ptr, png_const_charp message) -{ - ++error_count; - - pngtest_warning(png_ptr, message); - /* We can return because png_error calls the default handler, which is - * actually OK in this case. - */ -} - -/* END of code to validate stdio-free compilation */ - -/* START of code to validate memory allocation and deallocation */ -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - -/* Allocate memory. For reasonable files, size should never exceed - * 64K. However, zlib may allocate more than 64K if you don't tell - * it not to. See zconf.h and png.h for more information. zlib does - * need to allocate exactly 64K, so whatever you call here must - * have the ability to do that. - * - * This piece of code can be compiled to validate max 64K allocations - * by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. - */ -typedef struct memory_information -{ - png_alloc_size_t size; - png_voidp pointer; - struct memory_information *next; -} memory_information; -typedef memory_information *memory_infop; - -static memory_infop pinformation = NULL; -static int current_allocation = 0; -static int maximum_allocation = 0; -static int total_allocation = 0; -static int num_allocations = 0; - -png_voidp PNGCBAPI png_debug_malloc PNGARG((png_structp png_ptr, - png_alloc_size_t size)); -void PNGCBAPI png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr)); - -png_voidp -PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size) -{ - - /* png_malloc has already tested for NULL; png_create_struct calls - * png_debug_malloc directly, with png_ptr == NULL which is OK - */ - - if (size == 0) - return (NULL); - - /* This calls the library allocator twice, once to get the requested - buffer and once to get a new free list entry. */ - { - /* Disable malloc_fn and free_fn */ - memory_infop pinfo; - png_set_mem_fn(png_ptr, NULL, NULL, NULL); - pinfo = (memory_infop)png_malloc(png_ptr, - (sizeof *pinfo)); - pinfo->size = size; - current_allocation += size; - total_allocation += size; - num_allocations ++; - - if (current_allocation > maximum_allocation) - maximum_allocation = current_allocation; - - pinfo->pointer = png_malloc(png_ptr, size); - /* Restore malloc_fn and free_fn */ - - png_set_mem_fn(png_ptr, - NULL, png_debug_malloc, png_debug_free); - - if (size != 0 && pinfo->pointer == NULL) - { - current_allocation -= size; - total_allocation -= size; - png_error(png_ptr, - "out of memory in pngtest->png_debug_malloc"); - } - - pinfo->next = pinformation; - pinformation = pinfo; - /* Make sure the caller isn't assuming zeroed memory. */ - memset(pinfo->pointer, 0xdd, pinfo->size); - - if (verbose != 0) - printf("png_malloc %lu bytes at %p\n", (unsigned long)size, - pinfo->pointer); - - return (png_voidp)(pinfo->pointer); - } -} - -/* Free a pointer. It is removed from the list at the same time. */ -void PNGCBAPI -png_debug_free(png_structp png_ptr, png_voidp ptr) -{ - if (png_ptr == NULL) - fprintf(STDERR, "NULL pointer to png_debug_free.\n"); - - if (ptr == 0) - { -#if 0 /* This happens all the time. */ - fprintf(STDERR, "WARNING: freeing NULL pointer\n"); -#endif - return; - } - - /* Unlink the element from the list. */ - if (pinformation != NULL) - { - memory_infop *ppinfo = &pinformation; - - for (;;) - { - memory_infop pinfo = *ppinfo; - - if (pinfo->pointer == ptr) - { - *ppinfo = pinfo->next; - current_allocation -= pinfo->size; - if (current_allocation < 0) - fprintf(STDERR, "Duplicate free of memory\n"); - /* We must free the list element too, but first kill - the memory that is to be freed. */ - memset(ptr, 0x55, pinfo->size); - free(pinfo); - pinfo = NULL; - break; - } - - if (pinfo->next == NULL) - { - fprintf(STDERR, "Pointer %p not found\n", ptr); - break; - } - - ppinfo = &pinfo->next; - } - } - - /* Finally free the data. */ - if (verbose != 0) - printf("Freeing %p\n", ptr); - - if (ptr != NULL) - free(ptr); - ptr = NULL; -} -#endif /* USER_MEM && DEBUG */ -/* END of code to test memory allocation/deallocation */ - - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED -/* Demonstration of user chunk support of the sTER and vpAg chunks */ - -/* (sTER is a public chunk not yet known by libpng. vpAg is a private -chunk used in ImageMagick to store "virtual page" size). */ - -static struct user_chunk_data -{ - png_const_infop info_ptr; - png_uint_32 vpAg_width, vpAg_height; - png_byte vpAg_units; - png_byte sTER_mode; - int location[2]; -} -user_chunk_data; - -/* Used for location and order; zero means nothing. */ -#define have_sTER 0x01 -#define have_vpAg 0x02 -#define before_PLTE 0x10 -#define before_IDAT 0x20 -#define after_IDAT 0x40 - -static void -init_callback_info(png_const_infop info_ptr) -{ - MEMZERO(user_chunk_data); - user_chunk_data.info_ptr = info_ptr; -} - -static int -set_location(png_structp png_ptr, struct user_chunk_data *data, int what) -{ - int location; - - if ((data->location[0] & what) != 0 || (data->location[1] & what) != 0) - return 0; /* already have one of these */ - - /* Find where we are (the code below zeroes info_ptr to indicate that the - * chunks before the first IDAT have been read.) - */ - if (data->info_ptr == NULL) /* after IDAT */ - location = what | after_IDAT; - - else if (png_get_valid(png_ptr, data->info_ptr, PNG_INFO_PLTE) != 0) - location = what | before_IDAT; - - else - location = what | before_PLTE; - - if (data->location[0] == 0) - data->location[0] = location; - - else - data->location[1] = location; - - return 1; /* handled */ -} - -static int PNGCBAPI -read_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk) -{ - struct user_chunk_data *my_user_chunk_data = - (struct user_chunk_data*)png_get_user_chunk_ptr(png_ptr); - - if (my_user_chunk_data == NULL) - png_error(png_ptr, "lost user chunk pointer"); - - /* Return one of the following: - * return (-n); chunk had an error - * return (0); did not recognize - * return (n); success - * - * The unknown chunk structure contains the chunk data: - * png_byte name[5]; - * png_byte *data; - * png_size_t size; - * - * Note that libpng has already taken care of the CRC handling. - */ - - if (chunk->name[0] == 115 && chunk->name[1] == 84 && /* s T */ - chunk->name[2] == 69 && chunk->name[3] == 82) /* E R */ - { - /* Found sTER chunk */ - if (chunk->size != 1) - return (-1); /* Error return */ - - if (chunk->data[0] != 0 && chunk->data[0] != 1) - return (-1); /* Invalid mode */ - - if (set_location(png_ptr, my_user_chunk_data, have_sTER) != 0) - { - my_user_chunk_data->sTER_mode=chunk->data[0]; - return (1); - } - - else - return (0); /* duplicate sTER - give it to libpng */ - } - - if (chunk->name[0] != 118 || chunk->name[1] != 112 || /* v p */ - chunk->name[2] != 65 || chunk->name[3] != 103) /* A g */ - return (0); /* Did not recognize */ - - /* Found ImageMagick vpAg chunk */ - - if (chunk->size != 9) - return (-1); /* Error return */ - - if (set_location(png_ptr, my_user_chunk_data, have_vpAg) == 0) - return (0); /* duplicate vpAg */ - - my_user_chunk_data->vpAg_width = png_get_uint_31(png_ptr, chunk->data); - my_user_chunk_data->vpAg_height = png_get_uint_31(png_ptr, chunk->data + 4); - my_user_chunk_data->vpAg_units = chunk->data[8]; - - return (1); -} - -#ifdef PNG_WRITE_SUPPORTED -static void -write_sTER_chunk(png_structp write_ptr) -{ - png_byte sTER[5] = {115, 84, 69, 82, '\0'}; - - if (verbose != 0) - fprintf(STDERR, "\n stereo mode = %d\n", user_chunk_data.sTER_mode); - - png_write_chunk(write_ptr, sTER, &user_chunk_data.sTER_mode, 1); -} - -static void -write_vpAg_chunk(png_structp write_ptr) -{ - png_byte vpAg[5] = {118, 112, 65, 103, '\0'}; - - png_byte vpag_chunk_data[9]; - - if (verbose != 0) - fprintf(STDERR, " vpAg = %lu x %lu, units = %d\n", - (unsigned long)user_chunk_data.vpAg_width, - (unsigned long)user_chunk_data.vpAg_height, - user_chunk_data.vpAg_units); - - png_save_uint_32(vpag_chunk_data, user_chunk_data.vpAg_width); - png_save_uint_32(vpag_chunk_data + 4, user_chunk_data.vpAg_height); - vpag_chunk_data[8] = user_chunk_data.vpAg_units; - png_write_chunk(write_ptr, vpAg, vpag_chunk_data, 9); -} - -static void -write_chunks(png_structp write_ptr, int location) -{ - int i; - - /* Notice that this preserves the original chunk order, however chunks - * intercepted by the callback will be written *after* chunks passed to - * libpng. This will actually reverse a pair of sTER chunks or a pair of - * vpAg chunks, resulting in an error later. This is not worth worrying - * about - the chunks should not be duplicated! - */ - for (i=0; i<2; ++i) - { - if (user_chunk_data.location[i] == (location | have_sTER)) - write_sTER_chunk(write_ptr); - - else if (user_chunk_data.location[i] == (location | have_vpAg)) - write_vpAg_chunk(write_ptr); - } -} -#endif /* WRITE */ -#else /* !READ_USER_CHUNKS */ -# define write_chunks(pp,loc) ((void)0) -#endif -/* END of code to demonstrate user chunk support */ - -/* START of code to check that libpng has the required text support; this only - * checks for the write support because if read support is missing the chunk - * will simply not be reported back to pngtest. - */ -#ifdef PNG_TEXT_SUPPORTED -static void -pngtest_check_text_support(png_structp png_ptr, png_textp text_ptr, - int num_text) -{ - while (num_text > 0) - { - switch (text_ptr[--num_text].compression) - { - case PNG_TEXT_COMPRESSION_NONE: - break; - - case PNG_TEXT_COMPRESSION_zTXt: -# ifndef PNG_WRITE_zTXt_SUPPORTED - ++unsupported_chunks; - /* In libpng 1.7 this now does an app-error, so stop it: */ - text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE; -# endif - break; - - case PNG_ITXT_COMPRESSION_NONE: - case PNG_ITXT_COMPRESSION_zTXt: -# ifndef PNG_WRITE_iTXt_SUPPORTED - ++unsupported_chunks; - text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE; -# endif - break; - - default: - /* This is an error */ - png_error(png_ptr, "invalid text chunk compression field"); - break; - } - } -} -#endif -/* END of code to check that libpng has the required text support */ - -/* Test one file */ -static int -test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) -{ - static png_FILE_p fpin; - static png_FILE_p fpout; /* "static" prevents setjmp corruption */ - pngtest_error_parameters error_parameters; - png_structp read_ptr; - png_infop read_info_ptr, end_info_ptr; -#ifdef PNG_WRITE_SUPPORTED - png_structp write_ptr; - png_infop write_info_ptr; - png_infop write_end_info_ptr; -#ifdef PNG_WRITE_FILTER_SUPPORTED - int interlace_preserved = 1; -#endif /* WRITE_FILTER */ -#else /* !WRITE */ - png_structp write_ptr = NULL; - png_infop write_info_ptr = NULL; - png_infop write_end_info_ptr = NULL; -#endif /* !WRITE */ - png_bytep row_buf; - png_uint_32 y; - png_uint_32 width, height; - volatile int num_passes; - int pass; - int bit_depth, color_type; - - row_buf = NULL; - error_parameters.file_name = inname; - - if ((fpin = fopen(inname, "rb")) == NULL) - { - fprintf(STDERR, "Could not find input file %s\n", inname); - return (1); - } - - if ((fpout = fopen(outname, "wb")) == NULL) - { - fprintf(STDERR, "Could not open output file %s\n", outname); - FCLOSE(fpin); - return (1); - } - - pngtest_debug("Allocating read and write structures"); -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - read_ptr = - png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL, - NULL, NULL, NULL, png_debug_malloc, png_debug_free); -#else - read_ptr = - png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); -#endif - png_set_error_fn(read_ptr, &error_parameters, pngtest_error, - pngtest_warning); - -#ifdef PNG_WRITE_SUPPORTED -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - write_ptr = - png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL, - NULL, NULL, NULL, png_debug_malloc, png_debug_free); -#else - write_ptr = - png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); -#endif - png_set_error_fn(write_ptr, &error_parameters, pngtest_error, - pngtest_warning); -#endif - pngtest_debug("Allocating read_info, write_info and end_info structures"); - read_info_ptr = png_create_info_struct(read_ptr); - end_info_ptr = png_create_info_struct(read_ptr); -#ifdef PNG_WRITE_SUPPORTED - write_info_ptr = png_create_info_struct(write_ptr); - write_end_info_ptr = png_create_info_struct(write_ptr); -#endif - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - init_callback_info(read_info_ptr); - png_set_read_user_chunk_fn(read_ptr, &user_chunk_data, - read_user_chunk_callback); -#endif - -#ifdef PNG_SETJMP_SUPPORTED - pngtest_debug("Setting jmpbuf for read struct"); - if (setjmp(png_jmpbuf(read_ptr))) - { - fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname); - png_free(read_ptr, row_buf); - row_buf = NULL; - png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); -#ifdef PNG_WRITE_SUPPORTED - png_destroy_info_struct(write_ptr, &write_end_info_ptr); - png_destroy_write_struct(&write_ptr, &write_info_ptr); -#endif - FCLOSE(fpin); - FCLOSE(fpout); - return (1); - } - -#ifdef PNG_WRITE_SUPPORTED - pngtest_debug("Setting jmpbuf for write struct"); - - if (setjmp(png_jmpbuf(write_ptr))) - { - fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname); - png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); - png_destroy_info_struct(write_ptr, &write_end_info_ptr); -#ifdef PNG_WRITE_SUPPORTED - png_destroy_write_struct(&write_ptr, &write_info_ptr); -#endif - FCLOSE(fpin); - FCLOSE(fpout); - return (1); - } -#endif -#endif - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED - if (strict != 0) - { - /* Treat png_benign_error() as errors on read */ - png_set_benign_errors(read_ptr, 0); - -# ifdef PNG_WRITE_SUPPORTED - /* Treat them as errors on write */ - png_set_benign_errors(write_ptr, 0); -# endif - - /* if strict is not set, then app warnings and errors are treated as - * warnings in release builds, but not in unstable builds; this can be - * changed with '--relaxed'. - */ - } - - else if (relaxed != 0) - { - /* Allow application (pngtest) errors and warnings to pass */ - png_set_benign_errors(read_ptr, 1); - - /* Turn off CRC and ADLER32 checking while reading */ - png_set_crc_action(read_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); - -# ifdef PNG_WRITE_SUPPORTED - png_set_benign_errors(write_ptr, 1); -# endif - - } -#endif /* BENIGN_ERRORS */ - - pngtest_debug("Initializing input and output streams"); -#ifdef PNG_STDIO_SUPPORTED - png_init_io(read_ptr, fpin); -# ifdef PNG_WRITE_SUPPORTED - png_init_io(write_ptr, fpout); -# endif -#else - png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data); -# ifdef PNG_WRITE_SUPPORTED - png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data, -# ifdef PNG_WRITE_FLUSH_SUPPORTED - pngtest_flush); -# else - NULL); -# endif -# endif -#endif - - if (status_dots_requested == 1) - { -#ifdef PNG_WRITE_SUPPORTED - png_set_write_status_fn(write_ptr, write_row_callback); -#endif - png_set_read_status_fn(read_ptr, read_row_callback); - } - - else - { -#ifdef PNG_WRITE_SUPPORTED - png_set_write_status_fn(write_ptr, NULL); -#endif - png_set_read_status_fn(read_ptr, NULL); - } - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - png_set_read_user_transform_fn(read_ptr, read_user_callback); -#endif -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - zero_samples = 0; - png_set_write_user_transform_fn(write_ptr, count_zero_samples); -#endif - -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - /* Preserve all the unknown chunks, if possible. If this is disabled then, - * even if the png_{get,set}_unknown_chunks stuff is enabled, we can't use - * libpng to *save* the unknown chunks on read (because we can't switch the - * save option on!) - * - * Notice that if SET_UNKNOWN_CHUNKS is *not* supported read will discard all - * unknown chunks and write will write them all. - */ -#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED - png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS, - NULL, 0); -#endif -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS, - NULL, 0); -#endif -#endif - - pngtest_debug("Reading info struct"); - png_read_info(read_ptr, read_info_ptr); - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - /* This is a bit of a hack; there is no obvious way in the callback function - * to determine that the chunks before the first IDAT have been read, so - * remove the info_ptr (which is only used to determine position relative to - * PLTE) here to indicate that we are after the IDAT. - */ - user_chunk_data.info_ptr = NULL; -#endif - - pngtest_debug("Transferring info struct"); - { - int interlace_type, compression_type, filter_type; - - if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth, - &color_type, &interlace_type, &compression_type, &filter_type) != 0) - { - png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth, - color_type, interlace_type, compression_type, filter_type); - /* num_passes may not be available below if interlace support is not - * provided by libpng for both read and write. - */ - switch (interlace_type) - { - case PNG_INTERLACE_NONE: - num_passes = 1; - break; - - case PNG_INTERLACE_ADAM7: - num_passes = 7; - break; - - default: - png_error(read_ptr, "invalid interlace type"); - /*NOT REACHED*/ - } - } - - else - png_error(read_ptr, "png_get_IHDR failed"); - } -#ifdef PNG_FIXED_POINT_SUPPORTED -#ifdef PNG_cHRM_SUPPORTED - { - png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x, - blue_y; - - if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, - &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) - { - png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x, - red_y, green_x, green_y, blue_x, blue_y); - } - } -#endif -#ifdef PNG_gAMA_SUPPORTED - { - png_fixed_point gamma; - - if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma) != 0) - png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma); - } -#endif -#else /* Use floating point versions */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -#ifdef PNG_cHRM_SUPPORTED - { - double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, - blue_y; - - if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x, - &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) - { - png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x, - red_y, green_x, green_y, blue_x, blue_y); - } - } -#endif -#ifdef PNG_gAMA_SUPPORTED - { - double gamma; - - if (png_get_gAMA(read_ptr, read_info_ptr, &gamma) != 0) - png_set_gAMA(write_ptr, write_info_ptr, gamma); - } -#endif -#endif /* Floating point */ -#endif /* Fixed point */ -#ifdef PNG_iCCP_SUPPORTED - { - png_charp name; - png_bytep profile; - png_uint_32 proflen; - int compression_type; - - if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type, - &profile, &proflen) != 0) - { - png_set_iCCP(write_ptr, write_info_ptr, name, compression_type, - profile, proflen); - } - } -#endif -#ifdef PNG_sRGB_SUPPORTED - { - int intent; - - if (png_get_sRGB(read_ptr, read_info_ptr, &intent) != 0) - png_set_sRGB(write_ptr, write_info_ptr, intent); - } -#endif - { - png_colorp palette; - int num_palette; - - if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette) != 0) - png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette); - } -#ifdef PNG_bKGD_SUPPORTED - { - png_color_16p background; - - if (png_get_bKGD(read_ptr, read_info_ptr, &background) != 0) - { - png_set_bKGD(write_ptr, write_info_ptr, background); - } - } -#endif -#ifdef PNG_hIST_SUPPORTED - { - png_uint_16p hist; - - if (png_get_hIST(read_ptr, read_info_ptr, &hist) != 0) - png_set_hIST(write_ptr, write_info_ptr, hist); - } -#endif -#ifdef PNG_oFFs_SUPPORTED - { - png_int_32 offset_x, offset_y; - int unit_type; - - if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y, - &unit_type) != 0) - { - png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type); - } - } -#endif -#ifdef PNG_pCAL_SUPPORTED - { - png_charp purpose, units; - png_charpp params; - png_int_32 X0, X1; - int type, nparams; - - if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type, - &nparams, &units, ¶ms) != 0) - { - png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type, - nparams, units, params); - } - } -#endif -#ifdef PNG_pHYs_SUPPORTED - { - png_uint_32 res_x, res_y; - int unit_type; - - if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, - &unit_type) != 0) - png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type); - } -#endif -#ifdef PNG_sBIT_SUPPORTED - { - png_color_8p sig_bit; - - if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit) != 0) - png_set_sBIT(write_ptr, write_info_ptr, sig_bit); - } -#endif -#ifdef PNG_sCAL_SUPPORTED -#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ - defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) - { - int unit; - double scal_width, scal_height; - - if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width, - &scal_height) != 0) - { - png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height); - } - } -#else -#ifdef PNG_FIXED_POINT_SUPPORTED - { - int unit; - png_charp scal_width, scal_height; - - if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width, - &scal_height) != 0) - { - png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, - scal_height); - } - } -#endif -#endif -#endif - -#ifdef PNG_sPLT_SUPPORTED - { - png_sPLT_tp entries; - - int num_entries = (int) png_get_sPLT(read_ptr, read_info_ptr, &entries); - if (num_entries) - { - png_set_sPLT(write_ptr, write_info_ptr, entries, num_entries); - } - } -#endif - -#ifdef PNG_TEXT_SUPPORTED - { - png_textp text_ptr; - int num_text; - - if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0) - { - pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text); - - pngtest_check_text_support(read_ptr, text_ptr, num_text); - - if (verbose != 0) - { - int i; - - printf("\n"); - for (i=0; igray > sample_max) || - (color_type == PNG_COLOR_TYPE_RGB && - ((int)trans_color->red > sample_max || - (int)trans_color->green > sample_max || - (int)trans_color->blue > sample_max)))) - png_set_tRNS(write_ptr, write_info_ptr, trans_alpha, num_trans, - trans_color); - } - } -#endif -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - { - png_unknown_chunkp unknowns; - int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr, - &unknowns); - - if (num_unknowns != 0) - { - png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns, - num_unknowns); -#if PNG_LIBPNG_VER < 10600 - /* Copy the locations from the read_info_ptr. The automatically - * generated locations in write_end_info_ptr are wrong prior to 1.6.0 - * because they are reset from the write pointer (removed in 1.6.0). - */ - { - int i; - for (i = 0; i < num_unknowns; i++) - png_set_unknown_chunk_location(write_ptr, write_info_ptr, i, - unknowns[i].location); - } -#endif - } - } -#endif - -#ifdef PNG_WRITE_SUPPORTED - pngtest_debug("Writing info struct"); - - /* Write the info in two steps so that if we write the 'unknown' chunks here - * they go to the correct place. - */ - png_write_info_before_PLTE(write_ptr, write_info_ptr); - - write_chunks(write_ptr, before_PLTE); /* before PLTE */ - - png_write_info(write_ptr, write_info_ptr); - - write_chunks(write_ptr, before_IDAT); /* after PLTE */ - -#ifdef PNG_COMPRESSION_COMPAT - /* Test the 'compatibility' setting here, if it is available. */ - png_set_compression(write_ptr, PNG_COMPRESSION_COMPAT); -#endif -#endif - -#ifdef SINGLE_ROWBUF_ALLOC - pngtest_debug("Allocating row buffer..."); - row_buf = (png_bytep)png_malloc(read_ptr, - png_get_rowbytes(read_ptr, read_info_ptr)); - - pngtest_debug1("\t0x%08lx", (unsigned long)row_buf); -#endif /* SINGLE_ROWBUF_ALLOC */ - pngtest_debug("Writing row data"); - -#if defined(PNG_READ_INTERLACING_SUPPORTED) &&\ - defined(PNG_WRITE_INTERLACING_SUPPORTED) - /* Both must be defined for libpng to be able to handle the interlace, - * otherwise it gets handled below by simply reading and writing the passes - * directly. - */ - if (png_set_interlace_handling(read_ptr) != num_passes) - png_error(write_ptr, - "png_set_interlace_handling(read): wrong pass count "); - if (png_set_interlace_handling(write_ptr) != num_passes) - png_error(write_ptr, - "png_set_interlace_handling(write): wrong pass count "); -#else /* png_set_interlace_handling not called on either read or write */ -# define calc_pass_height -#endif /* not using libpng interlace handling */ - -#ifdef PNGTEST_TIMING - t_stop = (float)clock(); - t_misc += (t_stop - t_start); - t_start = t_stop; -#endif - for (pass = 0; pass < num_passes; pass++) - { -# ifdef calc_pass_height - png_uint_32 pass_height; - - if (num_passes == 7) /* interlaced */ - { - if (PNG_PASS_COLS(width, pass) > 0) - pass_height = PNG_PASS_ROWS(height, pass); - - else - pass_height = 0; - } - - else /* not interlaced */ - pass_height = height; -# else -# define pass_height height -# endif - - pngtest_debug1("Writing row data for pass %d", pass); - for (y = 0; y < pass_height; y++) - { -#ifndef SINGLE_ROWBUF_ALLOC - pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y); - - row_buf = (png_bytep)png_malloc(read_ptr, - png_get_rowbytes(read_ptr, read_info_ptr)); - - pngtest_debug2("\t0x%08lx (%lu bytes)", (unsigned long)row_buf, - (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr)); - -#endif /* !SINGLE_ROWBUF_ALLOC */ - png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1); - -#ifdef PNG_WRITE_SUPPORTED -#ifdef PNGTEST_TIMING - t_stop = (float)clock(); - t_decode += (t_stop - t_start); - t_start = t_stop; -#endif - png_write_rows(write_ptr, (png_bytepp)&row_buf, 1); -#ifdef PNGTEST_TIMING - t_stop = (float)clock(); - t_encode += (t_stop - t_start); - t_start = t_stop; -#endif -#endif /* WRITE */ - -#ifndef SINGLE_ROWBUF_ALLOC - pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y); - png_free(read_ptr, row_buf); - row_buf = NULL; -#endif /* !SINGLE_ROWBUF_ALLOC */ - } - } - -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -# ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1); -# endif -# ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1); -# endif -#endif - - pngtest_debug("Reading and writing end_info data"); - - png_read_end(read_ptr, end_info_ptr); -#ifdef PNG_TEXT_SUPPORTED - { - png_textp text_ptr; - int num_text; - - if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0) - { - pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text); - - pngtest_check_text_support(read_ptr, text_ptr, num_text); - - if (verbose != 0) - { - int i; - - printf("\n"); - for (i=0; i 0) - { - /* We don't really expect to get here because of the setjmp handling - * above, but this is safe. - */ - fprintf(STDERR, "\n %s: %d libpng errors found (%d warnings)", - inname, error_count, warning_count); - - if (strict != 0) - return (1); - } - -# ifdef PNG_WRITE_SUPPORTED - /* If there is no write support nothing was written! */ - else if (unsupported_chunks > 0) - { - fprintf(STDERR, "\n %s: unsupported chunks (%d)%s", - inname, unsupported_chunks, strict ? ": IGNORED --strict!" : ""); - } -# endif - - else if (warning_count > 0) - { - fprintf(STDERR, "\n %s: %d libpng warnings found", - inname, warning_count); - - if (strict != 0) - return (1); - } - - pngtest_debug("Opening files for comparison"); - if ((fpin = fopen(inname, "rb")) == NULL) - { - fprintf(STDERR, "Could not find file %s\n", inname); - return (1); - } - - if ((fpout = fopen(outname, "rb")) == NULL) - { - fprintf(STDERR, "Could not find file %s\n", outname); - FCLOSE(fpin); - return (1); - } - -#if defined (PNG_WRITE_SUPPORTED) /* else nothing was written */ &&\ - defined (PNG_WRITE_FILTER_SUPPORTED) - if (interlace_preserved != 0) /* else the files will be changed */ - { - for (;;) - { - static int wrote_question = 0; - png_size_t num_in, num_out; - char inbuf[256], outbuf[256]; - - num_in = fread(inbuf, 1, sizeof inbuf, fpin); - num_out = fread(outbuf, 1, sizeof outbuf, fpout); - - if (num_in != num_out) - { - fprintf(STDERR, "\nFiles %s and %s are of a different size\n", - inname, outname); - - if (wrote_question == 0 && unsupported_chunks == 0) - { - fprintf(STDERR, - " Was %s written with the same maximum IDAT" - " chunk size (%d bytes),", - inname, PNG_ZBUF_SIZE); - fprintf(STDERR, - "\n filtering heuristic (libpng default), compression"); - fprintf(STDERR, - " level (zlib default),\n and zlib version (%s)?\n\n", - ZLIB_VERSION); - wrote_question = 1; - } - - FCLOSE(fpin); - FCLOSE(fpout); - - if (strict != 0 && unsupported_chunks == 0) - return (1); - - else - return (0); - } - - if (num_in == 0) - break; - - if (memcmp(inbuf, outbuf, num_in)) - { - fprintf(STDERR, "\nFiles %s and %s are different\n", inname, - outname); - - if (wrote_question == 0 && unsupported_chunks == 0) - { - fprintf(STDERR, - " Was %s written with the same maximum" - " IDAT chunk size (%d bytes),", - inname, PNG_ZBUF_SIZE); - fprintf(STDERR, - "\n filtering heuristic (libpng default), compression"); - fprintf(STDERR, - " level (zlib default),\n and zlib version (%s)?\n\n", - ZLIB_VERSION); - wrote_question = 1; - } - - FCLOSE(fpin); - FCLOSE(fpout); - - /* NOTE: the unsupported_chunks escape is permitted here because - * unsupported text chunk compression will result in the compression - * mode being changed (to NONE) yet, in the test case, the result - * can be exactly the same size! - */ - if (strict != 0 && unsupported_chunks == 0) - return (1); - - else - return (0); - } - } - } -#endif /* WRITE && WRITE_FILTER */ - - FCLOSE(fpin); - FCLOSE(fpout); - - return (0); -} - -/* Input and output filenames */ -#ifdef RISCOS -static PNG_CONST char *inname = "pngtest/png"; -static PNG_CONST char *outname = "pngout/png"; -#else -static PNG_CONST char *inname = "pngtest.png"; -static PNG_CONST char *outname = "pngout.png"; -#endif - -int -main(int argc, char *argv[]) -{ - int multiple = 0; - int ierror = 0; - - png_structp dummy_ptr; - - fprintf(STDERR, "\n Testing libpng version %s\n", PNG_LIBPNG_VER_STRING); - fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION); - fprintf(STDERR, "%s", png_get_copyright(NULL)); - /* Show the version of libpng used in building the library */ - fprintf(STDERR, " library (%lu):%s", - (unsigned long)png_access_version_number(), - png_get_header_version(NULL)); - - /* Show the version of libpng used in building the application */ - fprintf(STDERR, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER, - PNG_HEADER_VERSION_STRING); - - /* Do some consistency checking on the memory allocation settings, I'm - * not sure this matters, but it is nice to know, the first of these - * tests should be impossible because of the way the macros are set - * in pngconf.h - */ -#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) - fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n"); -#endif - /* I think the following can happen. */ -#if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K) - fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n"); -#endif - - if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING)) - { - fprintf(STDERR, - "Warning: versions are different between png.h and png.c\n"); - fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING); - fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver); - ++ierror; - } - - if (argc > 1) - { - if (strcmp(argv[1], "-m") == 0) - { - multiple = 1; - status_dots_requested = 0; - } - - else if (strcmp(argv[1], "-mv") == 0 || - strcmp(argv[1], "-vm") == 0 ) - { - multiple = 1; - verbose = 1; - status_dots_requested = 1; - } - - else if (strcmp(argv[1], "-v") == 0) - { - verbose = 1; - status_dots_requested = 1; - inname = argv[2]; - } - - else if (strcmp(argv[1], "--strict") == 0) - { - status_dots_requested = 0; - verbose = 1; - inname = argv[2]; - strict++; - relaxed = 0; - } - - else if (strcmp(argv[1], "--relaxed") == 0) - { - status_dots_requested = 0; - verbose = 1; - inname = argv[2]; - strict = 0; - relaxed++; - } - - else - { - inname = argv[1]; - status_dots_requested = 0; - } - } - - if (multiple == 0 && argc == 3 + verbose) - outname = argv[2 + verbose]; - - if ((multiple == 0 && argc > 3 + verbose) || - (multiple != 0 && argc < 2)) - { - fprintf(STDERR, - "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n", - argv[0], argv[0]); - fprintf(STDERR, - " reads/writes one PNG file (without -m) or multiple files (-m)\n"); - fprintf(STDERR, - " with -m %s is used as a temporary file\n", outname); - exit(1); - } - - if (multiple != 0) - { - int i; -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - int allocation_now = current_allocation; -#endif - for (i=2; i 0 - fprintf(STDERR, "\n"); -#endif - kerror = test_one_file(argv[i], outname); - if (kerror == 0) - { -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - fprintf(STDERR, "\n PASS (%lu zero samples)\n", - (unsigned long)zero_samples); -#else - fprintf(STDERR, " PASS\n"); -#endif -#ifdef PNG_TIME_RFC1123_SUPPORTED - if (tIME_chunk_present != 0) - fprintf(STDERR, " tIME = %s\n", tIME_string); - - tIME_chunk_present = 0; -#endif /* TIME_RFC1123 */ - } - - else - { - fprintf(STDERR, " FAIL\n"); - ierror += kerror; - } -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - if (allocation_now != current_allocation) - fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n", - current_allocation - allocation_now); - - if (current_allocation != 0) - { - memory_infop pinfo = pinformation; - - fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n", - current_allocation); - - while (pinfo != NULL) - { - fprintf(STDERR, " %lu bytes at %p\n", - (unsigned long)pinfo->size, - pinfo->pointer); - pinfo = pinfo->next; - } - } -#endif - } -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - fprintf(STDERR, " Current memory allocation: %10d bytes\n", - current_allocation); - fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", - maximum_allocation); - fprintf(STDERR, " Total memory allocation: %10d bytes\n", - total_allocation); - fprintf(STDERR, " Number of allocations: %10d\n", - num_allocations); -#endif - } - - else - { - int i; - for (i = 0; i<3; ++i) - { - int kerror; -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - int allocation_now = current_allocation; -#endif - if (i == 1) - status_dots_requested = 1; - - else if (verbose == 0) - status_dots_requested = 0; - - if (i == 0 || verbose == 1 || ierror != 0) - { - fprintf(STDERR, "\n Testing %s:", inname); -#if PNG_DEBUG > 0 - fprintf(STDERR, "\n"); -#endif - } - - kerror = test_one_file(inname, outname); - - if (kerror == 0) - { - if (verbose == 1 || i == 2) - { -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - fprintf(STDERR, "\n PASS (%lu zero samples)\n", - (unsigned long)zero_samples); -#else - fprintf(STDERR, " PASS\n"); -#endif -#ifdef PNG_TIME_RFC1123_SUPPORTED - if (tIME_chunk_present != 0) - fprintf(STDERR, " tIME = %s\n", tIME_string); -#endif /* TIME_RFC1123 */ - } - } - - else - { - if (verbose == 0 && i != 2) - { - fprintf(STDERR, "\n Testing %s:", inname); -#if PNG_DEBUG > 0 - fprintf(STDERR, "\n"); -#endif - } - - fprintf(STDERR, " FAIL\n"); - ierror += kerror; - } -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - if (allocation_now != current_allocation) - fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n", - current_allocation - allocation_now); - - if (current_allocation != 0) - { - memory_infop pinfo = pinformation; - - fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n", - current_allocation); - - while (pinfo != NULL) - { - fprintf(STDERR, " %lu bytes at %p\n", - (unsigned long)pinfo->size, pinfo->pointer); - pinfo = pinfo->next; - } - } -#endif - } -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - fprintf(STDERR, " Current memory allocation: %10d bytes\n", - current_allocation); - fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", - maximum_allocation); - fprintf(STDERR, " Total memory allocation: %10d bytes\n", - total_allocation); - fprintf(STDERR, " Number of allocations: %10d\n", - num_allocations); -#endif - } - -#ifdef PNGTEST_TIMING - t_stop = (float)clock(); - t_misc += (t_stop - t_start); - t_start = t_stop; - fprintf(STDERR, " CPU time used = %.3f seconds", - (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC); - fprintf(STDERR, " (decoding %.3f,\n", - t_decode/(float)CLOCKS_PER_SEC); - fprintf(STDERR, " encoding %.3f ,", - t_encode/(float)CLOCKS_PER_SEC); - fprintf(STDERR, " other %.3f seconds)\n\n", - t_misc/(float)CLOCKS_PER_SEC); -#endif - - if (ierror == 0) - fprintf(STDERR, " libpng passes test\n"); - - else - fprintf(STDERR, " libpng FAILS test\n"); - - dummy_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - fprintf(STDERR, " Default limits:\n"); - fprintf(STDERR, " width_max = %lu\n", - (unsigned long) png_get_user_width_max(dummy_ptr)); - fprintf(STDERR, " height_max = %lu\n", - (unsigned long) png_get_user_height_max(dummy_ptr)); - if (png_get_chunk_cache_max(dummy_ptr) == 0) - fprintf(STDERR, " cache_max = unlimited\n"); - else - fprintf(STDERR, " cache_max = %lu\n", - (unsigned long) png_get_chunk_cache_max(dummy_ptr)); - if (png_get_chunk_malloc_max(dummy_ptr) == 0) - fprintf(STDERR, " malloc_max = unlimited\n"); - else - fprintf(STDERR, " malloc_max = %lu\n", - (unsigned long) png_get_chunk_malloc_max(dummy_ptr)); - png_destroy_read_struct(&dummy_ptr, NULL, NULL); - - return (int)(ierror != 0); -} -#else -int -main(void) -{ - fprintf(STDERR, - " test ignored because libpng was not built with read support\n"); - /* And skip this test */ - return PNG_LIBPNG_VER < 10600 ? 0 : 77; -} -#endif - -/* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_7_0beta90 Your_png_h_is_not_version_1_7_0beta90; diff --git a/ext/libpng17/pngtrans.c b/ext/libpng17/pngtrans.c deleted file mode 100644 index 3b62749832..0000000000 --- a/ext/libpng17/pngtrans.c +++ /dev/null @@ -1,3760 +0,0 @@ - -/* pngtrans.c - transforms the data in a row (used by both readers and writers) - * - * Last changed in libpng 1.7.0 [(PENDING RELEASE)] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ -#include "pngpriv.h" -#define PNG_SRC_FILE PNG_SRC_FILE_pngtrans - -#ifdef _XOPEN_SOURCE -# include -#endif /* for swab */ - -/* Memory format enquiries */ -#ifdef PNG_GAMMA_SUPPORTED -static png_fixed_point -memory_gamma(png_const_structrp png_ptr) -{ -# ifdef PNG_READ_GAMMA_SUPPORTED -# ifdef PNG_TRANSFORM_MECH_SUPPORTED - if (png_ptr->read_struct) - return png_ptr->row_gamma; -# endif /* TRANSFORM_MECH */ -# endif /* READ_GAMMA */ - - /* Else either no READ_GAMMA support or this is a write struct; in both - * cases there are no gamma transforms. In the write case the set of the - * gamma in the info may not have been copied to the png_struct. - */ -# if defined(PNG_GAMMA_SUPPORTED) && defined(PNG_READ_SUPPORTED) - if ((png_ptr->colorspace.flags & - (PNG_COLORSPACE_INVALID|PNG_COLORSPACE_HAVE_GAMMA)) == - PNG_COLORSPACE_HAVE_GAMMA) - return png_ptr->colorspace.gamma; -# else /* !(GAMMA && READ) */ - PNG_UNUSED(png_ptr) -# endif /* !(GAMMA && READ) */ - - /* '0' means the value is not know: */ - return 0; -} -#endif /* GAMMA */ - -unsigned int PNGAPI -png_memory_format(png_structrp png_ptr) -{ - /* The in-memory format as a bitmask of PNG_FORMAT_FLAG_ values. All the - * flags listed below are used. If PNG_FORMAT_FLAG_INVALID is set the - * following caveats apply to the interpretation of PNG_FORMAT_FLAG_LINEAR: - * - * The gamma may differ from the sRGB (!LINEAR) or 1.0 (LINEAR). Call - * png_memory_gamma to find the correct value. - * - * The channel depth may differ from 8 (!LINEAR) or 16 (LINEAR). Call - * png_memory_channel_depth to find the correct value. - * - * It is only valid to call these APIS *after* either png_read_update_info - * or png_start_read_image on read or after the first row of an image has - * been written on write. - */ - if (png_ptr != NULL) - { -# ifdef PNG_TRANSFORM_MECH_SUPPORTED - unsigned int format = png_ptr->row_format; -# else /* !TRANSFORM_MECH */ - unsigned int format = PNG_FORMAT_FROM_COLOR_TYPE(png_ptr->color_type); -# endif /* !TRANSFORM_MECH */ - - if (png_ptr->read_struct) /* else no way to find the gamma! */ - { -# ifdef PNG_GAMMA_SUPPORTED -# ifdef PNG_TRANSFORM_MECH_SUPPORTED - unsigned int bit_depth = png_ptr->row_bit_depth; -# else /* !TRANSFORM_MECH */ - unsigned int bit_depth = png_ptr->bit_depth; -# endif /* !TRANSFORM_MECH */ - - /* Now work out whether this is a valid simplified API format. */ - switch (bit_depth) - { - case 8U: - { - png_fixed_point gamma = memory_gamma(png_ptr); - - if (!PNG_GAMMA_IS_sRGB(gamma)) - format |= PNG_FORMAT_FLAG_INVALID; - } - break; - - case 16: - if (memory_gamma(png_ptr) == PNG_GAMMA_LINEAR) - { - static const union - { - png_uint_16 u16; - png_byte u8[2]; - } sex = { 1U }; - - format |= PNG_FORMAT_FLAG_LINEAR; - - /* But the memory layout of the 16-bit quantities must also - * match; we need swapped data on LSB platforms. - */ - if (sex.u8[0] == ((format & PNG_FORMAT_FLAG_SWAPPED) != 0)) - break; /* ok */ - } - - /* FALL THROUGH*/ - default: /* bit depth not supported for simplified API */ - format |= PNG_FORMAT_FLAG_INVALID; - break; - } -# else /* !GAMMA */ - /* We have no way of knowing if the gamma value matches that - * expected by the simplified API so mark the format as invalid: - */ - format |= PNG_FORMAT_FLAG_INVALID; -# endif - } /* read_struct */ - - return format; - } - - return 0; -} - -unsigned int PNGAPI png_memory_channel_depth(png_structrp png_ptr) -{ - /* The actual depth of each channel in the image. */ - if (png_ptr != NULL) - { -# ifdef PNG_TRANSFORM_MECH_SUPPORTED - return png_ptr->row_bit_depth; -# else - return png_ptr->bit_depth; -# endif - } - - return 0; -} - -#ifdef PNG_GAMMA_SUPPORTED -png_fixed_point PNGAPI -png_memory_gamma(png_structrp png_ptr) -{ - /* The actual gamma of the image data, scaled by 100,000. This is the - * encoding gamma, e.g. 1/2.2 for sRGB. If the gamma is unknown this will - * return 0. - * - * On write this invariably returns 0; libpng does not change the gamma of - * the data on write. - * - * Note that this is not always the exact inverse of the 'screen gamma' - * passed to png_set_gamma; internal optimizations remove attempts to make - * small changes to the gamma value. This function returns the actual - * output value. - */ - return (png_ptr != NULL) ? memory_gamma(png_ptr) : 0; -} -#endif /* GAMMA */ - -/* These are general purpose APIs that deal with the row buffer format in both - * the read and write case. The png_struct::row_* members describe the - * in-memory format of the image data based on the transformations requested by - * the application. - */ -#ifdef PNG_TRANSFORM_MECH_SUPPORTED -png_voidp /* PRIVATE */ -png_transform_cast_check(png_const_structp png_ptr, unsigned int src_line, - png_transformp tr, size_t size) -{ - /* Given a pointer to a transform, 'tr' validate that the underlying derived - * class has size 'size' using the tr->size field and return the same - * pointer. If there is a size mismatch the function does an affirm using - * the given line number. - */ - if (tr->size != size) - png_affirm(png_ptr, param_deb("transform upcast") src_line); - - return tr; -} - -void /* PRIAVE */ -png_transform_free(png_const_structrp png_ptr, png_transformp *list) -{ - if (*list != NULL) - { - png_transform_free(png_ptr, &(*list)-> next); - if ((*list)->free != NULL) - (*list)->free(png_ptr, *list); - png_free(png_ptr, *list); - *list = NULL; - } -} - -/* Utility to initialize a png_transform_control for read or write. */ -void /* PRIVATE */ -png_init_transform_control(png_transform_controlp tc, png_structp png_ptr) -{ - png_byte bd; /* bit depth of the row */ - png_byte cd; /* bit depth of color information */ - - memset(tc, 0, sizeof *tc); - tc->png_ptr = png_ptr; /* ALIAS */ - tc->sp = tc->dp = NULL; - tc->width = 0; - -# ifdef PNG_READ_GAMMA_SUPPORTED - /* The file gamma is set by png_set_gamma, as well as being read from the - * input PNG gAMA chunk, if present, we don't have a png_info so can't get - * the set_gAMA value but this doesn't matter because on read the gamma - * value is in png_struct::colorspace and on write it isn't used. - */ - if ((png_ptr->colorspace.flags & - (PNG_COLORSPACE_INVALID|PNG_COLORSPACE_HAVE_GAMMA)) == - PNG_COLORSPACE_HAVE_GAMMA) - { - tc->gamma = png_ptr->colorspace.gamma; - debug(tc->gamma > 0); - } - - else - { - /* There is no input gamma, so there should be no overall gamma - * correction going on. This test works because the various things - * that set an output gamma also default the input gamma. - */ - debug(png_ptr->row_gamma == 0); - } -# endif - - /* Validate bit depth and color type here */ - cd = bd = png_ptr->bit_depth; - - switch (png_ptr->color_type) - { - case PNG_COLOR_TYPE_GRAY: - affirm(bd == 1U || bd == 2U || bd == 4U || bd == 8U || bd == 16U); - tc->format = 0U; - break; - - case PNG_COLOR_TYPE_PALETTE: - affirm(bd == 1U || bd == 2U || bd == 4U || bd == 8U); - tc->format = PNG_FORMAT_FLAG_COLORMAP | PNG_FORMAT_FLAG_COLOR; - cd = 8U; - break; - - case PNG_COLOR_TYPE_GRAY_ALPHA: - affirm(bd == 8U || bd == 16U); - tc->format = PNG_FORMAT_FLAG_ALPHA; - break; - - case PNG_COLOR_TYPE_RGB: - affirm(bd == 8U || bd == 16U); - tc->format = PNG_FORMAT_FLAG_COLOR; - break; - - case PNG_COLOR_TYPE_RGB_ALPHA: - affirm(bd == 8U || bd == 16U); - tc->format = PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_ALPHA; - break; - - default: - impossible("PNG color type"); - } - - tc->bit_depth = bd; - tc->range = 0; - - /* Preset the sBIT data to full precision/handled. */ - tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A = cd; -# ifdef PNG_READ_sBIT_SUPPORTED - { - int handled = 1; - - if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - png_byte c = png_ptr->sig_bit.red; - if (c > 0 && c < cd) - { - tc->sBIT_R = c; - handled = 0; - } - - c = png_ptr->sig_bit.green; - if (c > 0 && c < cd) - { - tc->sBIT_G = c; - handled = 0; - } - - c = png_ptr->sig_bit.blue; - if (c > 0 && c < cd) - { - tc->sBIT_B = c; - handled = 0; - } - } - - else /* grayscale */ - { - png_byte c = png_ptr->sig_bit.gray; - if (c > 0 && c < cd) - { - tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = c; - handled = 0; - } - } - - /* The palette-mapped format doesn't store alpha information, an - * omission in the spec that is difficult to fix. Notice that - * 'handled' is not cleared below, this is because the alpha channel is - * always linear, so the sBIT_A value can always be treated as a - * precision value. - */ - if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) - { - png_byte c = png_ptr->sig_bit.alpha; - if (c > 0 && c < cd) - tc->sBIT_A = c; - } - - /* If 'handled' did not get cleared there is no sBIT information. */ - if (handled) - tc->invalid_info = PNG_INFO_sBIT; - } -# else /* !READ_sBIT */ - /* No sBIT information */ - tc->invalid_info = PNG_INFO_sBIT; -# endif /* !READ_sBIT */ -} - -png_transformp /*PRIVATE*/ -png_add_transform(png_structrp png_ptr, size_t size, png_transform_fn fn, - unsigned int order) -{ - /* Add a transform. This is a minimal implementation; the order is just - * controlled by 'order', the result is a point to the new transform, or - * to an existing one if one was already in the list. - */ - png_transformp *p = &png_ptr->transform_list; - - while (*p != NULL && (*p)->order < order) - p = &(*p)->next; - - if (size == 0) - size = sizeof (png_transform); - - else - affirm(size >= sizeof (png_transform)); - - if (*p == NULL || (*p)->order > order) - { - png_transformp t; - - t = png_voidcast(png_transformp, png_malloc(png_ptr, size)); - memset(t, 0, size); /* zeros out the extra data too */ - /* *p comes after the new entry, t: */ - t->next = *p; - t->fn = fn; - t->free = NULL; - t->order = order; - t->size = 0xFFFFU & size; - *p = t; - return t; - } - - else /* (*p)->order matches order, return *p */ - { - affirm((*p)->fn == fn && (*p)->order == order && (*p)->size == size); - return *p; - } -} - -png_transformp /* PRIVATE */ -png_push_transform(png_structrp png_ptr, size_t size, png_transform_fn fn, - png_transformp *transform, png_transform_controlp tc) -{ - png_transformp tr = *transform; - unsigned int order = tr->order; - - /* Basic loop detection: */ - affirm(fn != NULL && tr->fn != fn); - - /* Move the following transforms up: */ - { - unsigned int old_order = order; - - do - { - tr->order = ++old_order; - tr = tr->next; - } - while (tr != NULL && tr->order == old_order); - - affirm(tr == NULL || tr->order > old_order); - } - - *transform = png_add_transform(png_ptr, size, fn, order); - - if (tc != NULL) - fn(transform, tc); - - return *transform; -} - -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -static png_transformp -png_find_transform(png_const_structrp png_ptr, unsigned int order) - /* Find a transform with the given order, or return NULL. Currently only - * used here. - */ -{ - png_transformp p = png_ptr->transform_list; - - for (;;) - { - if (p == NULL || p->order > order) - return NULL; - - if (p->order == order) - return p; - - p = p->next; - } -} -#endif /* USER_TRANSFORM_PTR */ - -static void -remove_transform(png_const_structp png_ptr, png_transformp *transform) - /* Remove a transform on a running list */ -{ - png_transformp tp = *transform; - png_transformp next = tp->next; - - *transform = next; - tp->next = NULL; - png_transform_free(png_ptr, &tp); -} - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -void /* PRIVATE */ -png_remove_transform(png_const_structp png_ptr, png_transformp *transform) -{ - remove_transform(png_ptr, transform); -} -#endif /* READ_TRANSFORMS */ - -static unsigned int -run_transform_list_forwards(png_transform_controlp tc, png_transformp *start, - png_transformp end/*NULL for whole list*/) - /* Called from the init code and below, the caller must initialize 'tc' */ -{ - png_const_structp png_ptr = tc->png_ptr; - unsigned int max_depth = PNG_TC_PIXEL_DEPTH(*tc); - - /* Caller guarantees that *start is non-NULL */ - debug(*start != NULL); - - do - { - if ((*start)->fn != NULL) - (*start)->fn(start, tc); - - if ((*start)->fn == NULL) /* delete this transform */ - remove_transform(png_ptr, start); - - else - { - /* Handle the initialization of the maximum pixel depth. */ - unsigned int tc_depth = PNG_TC_PIXEL_DEPTH(*tc); - - if (tc_depth > max_depth) - max_depth = tc_depth; - - /* Advance to the next transform. */ - start = &(*start)->next; - } - } - while (*start != NULL && *start != end); - - /* This only goes wrong if 'end' was non-NULL and not in the list: */ - debug(*start == end); - - return max_depth; -} - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -unsigned int /* PRIVATE */ -png_run_this_transform_list_forwards(png_transform_controlp tc, - png_transformp *start, png_transformp end) -{ - return run_transform_list_forwards(tc, start, end); -} -#endif /* READ_TRANSFORMS */ - -#ifdef PNG_READ_SUPPORTED -unsigned int /* PRIVATE */ -png_run_transform_list_forwards(png_structp png_ptr, png_transform_controlp tc) -{ - if (png_ptr->transform_list != NULL) - return run_transform_list_forwards(tc, &png_ptr->transform_list, NULL); - - else - return PNG_PIXEL_DEPTH(*png_ptr); -} -#endif /* READ */ - -#ifdef PNG_WRITE_SUPPORTED /* only used from pngwrite.c */ -static unsigned int -run_transform_list_backwards(png_transform_controlp tc, png_transformp *list) -{ - png_const_structp png_ptr = tc->png_ptr; - unsigned int max_depth = 0; - - if ((*list)->next != NULL) - max_depth = run_transform_list_backwards(tc, &(*list)->next); - - /* Note that the above might change (*list)->next, but it can't change - * *list itself. - */ - if ((*list)->fn != NULL) - (*list)->fn(list, tc); - - /* If that set 'fn' to NULL this transform must be removed; this is how - * (*list)->next gets changed in our caller: - */ - if ((*list)->fn == NULL) - remove_transform(png_ptr, list); - - else - { - unsigned int depth = PNG_TC_PIXEL_DEPTH(*tc); - - if (depth > max_depth) - max_depth = depth; - } - - return max_depth; -} - -void /* PRIVATE */ -png_run_transform_list_backwards(png_structp png_ptr, png_transform_controlp tc) -{ - if (png_ptr->transform_list != NULL) - { - /* This doesn't take account of the base PNG depth, but that shouldn't - * matter, it's just a check: - */ - unsigned int max_depth = - run_transform_list_backwards(tc, &png_ptr->transform_list); - - /* Better late than never (if this fires a memory overwrite has happened): - */ - affirm(max_depth <= png_ptr->row_max_pixel_depth); - } -} -#endif /* WRITE */ - -static unsigned int -init_transform_mech(png_structrp png_ptr, png_transform_control *tc, int start) - /* Called each time to run the transform list once during initialization. */ -{ - png_init_transform_control(tc, png_ptr); - tc->init = start ? PNG_TC_INIT_FORMAT : PNG_TC_INIT_FINAL; -# ifdef PNG_READ_TRANSFORMS_SUPPORTED - if (png_ptr->read_struct) - return png_read_init_transform_mech(png_ptr, tc); - else -# endif - return run_transform_list_forwards(tc, &png_ptr->transform_list, NULL); -} -#endif /* TRANSFORM_MECH */ - -#ifdef PNG_PALETTE_MAX_SUPPORTED -static int -set_palette_max(png_structrp png_ptr, png_transformp tr, unsigned int max, - unsigned int format_max) - /* Called whenever a new maximum pixel value is found */ -{ - /* One of these must be true: */ -# ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED - if (max >= (tr->args & 0x1FFU) && !png_ptr->palette_index_check_issued) - { - /* In 1.7 only issue the error/warning by default; the 'check' API is - * used to enable/disable the check. Assume that if the app enabled it - * then the app will be checking the result with get_palette_max in - * read. In write an error results unless the check is disabled. - */ - if (png_ptr->palette_index_check == PNG_PALETTE_CHECK_DEFAULT -# ifdef PNG_WRITE_SUPPORTED - || (!png_ptr->read_struct && - png_ptr->palette_index_check != PNG_PALETTE_CHECK_OFF) -# endif /* WRITE */ - ) - { -# ifdef PNG_READ_SUPPORTED -# ifdef PNG_WRITE_SUPPORTED - if (png_ptr->read_struct) -# endif /* WRITE */ - png_chunk_benign_error(png_ptr, "palette index too large"); -# ifdef PNG_WRITE_SUPPORTED - else -# endif -# endif /* READ */ -# ifdef PNG_WRITE_SUPPORTED - png_error(png_ptr, "palette index too large"); -# endif /* WRITE */ - } - - png_ptr->palette_index_check_issued = 1; - } -# endif /* CHECK_FOR_INVALID_INDEX */ -# ifdef PNG_GET_PALETTE_MAX_SUPPORTED - png_ptr->palette_index_max = png_check_byte(png_ptr, max); -# endif - - if (max == format_max) - { - tr->fn = NULL; /* no point continuing once the max has been seen */ - return 1; /* stop */ - } - - return 0; /* keep going */ -} - -static void -palette_max_1bpp(png_transformp *tr, png_transform_controlp tc) -{ - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_uint_32 width = tc->width; - - while (width >= 8) - { - if (*sp++) break; - width -= 8; - } - - if (width < 8) - { - if (width == 0 || - (*sp & (((1U<png_ptr, *tr, 1U, 1U); -} - -static void -palette_max_2bpp(png_transformp *tr, png_transform_controlp tc) -{ - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_uint_32 width = tc->width; - const png_uint_32 args = (*tr)->args; - unsigned int max = args >> 24; /* saved maximum */ - - while (width > 0) - { - png_uint_32 input = 0U, test; - unsigned int new_max; - - /* This just skips 0 bytes: */ - while (width > 0) - { - unsigned int next = *sp++; - - /* There may be partial pixels at the end, just remove the absent - * pixels with a right shift: - */ - if (width >= 4) - width -= 4; - else - next >>= (4U-width) * 2U, width = 0; - - if (next) - { - input = (input << 8) | next; - if ((input & 0xFF000000U) != 0) - break; - } - } - - test = input & 0xAAAAAAAAU; - - if (test != 0) - { - if ((input & (test >> 1)) != 0) - new_max = 3U; /* both bits set in at least one pixel */ - - else if (max < 2U) - new_max = 2U; - - else - continue; /* no change to max */ - } - - else /* test is 0 */ if (input != 0 && max == 0) - new_max = 1U; - - else /* input is 0, or max is at least 1 */ - continue; - - /* new_max is greater than max: */ - if (set_palette_max(tc->png_ptr, *tr, new_max, 3U)) - return; - - /* Record new_max: */ - max = new_max; - } - - /* End of input, check the next line. */ - (*tr)->args = (max << 24) + (args & 0xFFFFFFU); -} - -static void -palette_max_4bpp(png_transformp *tr, png_transform_controlp tc) -{ - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_uint_32 width = tc->width; - const png_uint_32 args = (*tr)->args; - unsigned int max = args >> 24; /* saved maximum */ - - while (width > 0) - { - unsigned int input = *sp++; - - if (width >= 2) - width -= 2; - else - input >>= 1, width = 0; - - if ((input & 0xFU) > max) - max = input & 0xFU; - - if (((input >> 4) & 0xFU) > max) - max = (input >> 4) & 0xFU; - } - - if (max > (args >> 24)) - { - if (set_palette_max(tc->png_ptr, *tr, max, 15U)) - return; - - (*tr)->args = (max << 24) + (args & 0xFFFFFFU); - } -} - -static void -palette_max_8bpp(png_transformp *tr, png_transform_controlp tc) -{ - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_uint_32 width = tc->width; - const png_uint_32 args = (*tr)->args; - unsigned int max = args >> 24; /* saved maximum */ - - while (width > 0) - { - unsigned int input = *sp++; - - if (input > max) - max = input; - - --width; - } - - if (max > (args >> 24)) - { - if (set_palette_max(tc->png_ptr, *tr, max, 255U)) - return; - - (*tr)->args = (max << 24) + (args & 0xFFFFFFU); - } -} - -static void -palette_max_init(png_transformp *tr, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - affirm((tc->format & PNG_FORMAT_FLAG_COLORMAP) != 0); - debug(tc->init); - - if (tc->init == PNG_TC_INIT_FINAL) - { - /* Record the palette depth to check here along with the running total - * in the top 8 bits (initially 0, which is always valid). - */ - (*tr)->args = png_ptr->num_palette; - - switch (tc->bit_depth) - { - case 1: (*tr)->fn = palette_max_1bpp; break; - case 2: (*tr)->fn = palette_max_2bpp; break; - case 4: (*tr)->fn = palette_max_4bpp; break; - case 8: (*tr)->fn = palette_max_8bpp; break; - default:impossible("palette bit depth"); - } - - png_ptr->palette_index_have_max = 1U; - } -# undef png_ptr -} -#endif /* PALETTE_MAX */ - -#ifdef PNG_GET_PALETTE_MAX_SUPPORTED -int PNGAPI -png_get_palette_max(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && png_ptr->palette_index_have_max) - return png_ptr->palette_index_max; - - /* This indicates to the caller that the information is not available: */ - return -1; - PNG_UNUSED(info_ptr) -} -#endif /* GET_PALETTE_MAX */ - -void /* PRIVATE */ -png_init_row_info(png_structrp png_ptr) -{ - /* PNG pixels never exceed 64 bits in depth: */ - const png_byte png_depth = - png_check_bits(png_ptr, PNG_PIXEL_DEPTH(*png_ptr), 7U); - -# ifdef PNG_TRANSFORM_MECH_SUPPORTED - /* The palette index check stuff is *on* automatically. To handle this - * add it here, if it is supported. - */ -# ifdef PNG_PALETTE_MAX_SUPPORTED - /* The logic here is a little complex because of the plethora of - * #defines controlling this stuff. - */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE/* fast escape */ && ( -# if defined (PNG_READ_GET_PALETTE_MAX_SUPPORTED) ||\ - defined (PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) - (png_ptr->read_struct -# ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED - && (png_ptr->palette_index_check == PNG_PALETTE_CHECK_ON || - (png_ptr->palette_index_check == PNG_PALETTE_CHECK_DEFAULT - && png_ptr->num_palette < (1U << png_ptr->bit_depth))) -# endif /* READ_CHECK_FOR_INVALID_INDEX */ - ) -# else /* no READ support */ - 0 -# endif /* READ checks */ - || -# if defined (PNG_WRITE_GET_PALETTE_MAX_SUPPORTED) ||\ - defined (PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) - (!png_ptr->read_struct -# ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED - && (png_ptr->palette_index_check == PNG_PALETTE_CHECK_ON || - (png_ptr->palette_index_check == PNG_PALETTE_CHECK_DEFAULT - && png_ptr->num_palette < (1U << png_ptr->bit_depth))) -# endif /* WRITE_CHECK_FOR_INVALID_INDEX */ - ) -# else /* no WRITE support */ - 0 -# endif /* WRITE checks */ - )) - png_add_transform(png_ptr, 0/*size*/, palette_max_init, - PNG_TR_CHECK_PALETTE); -# endif - - /* Application transforms may change the format of the data or, when - * producing interlaced images, the number of pixels in a line. This code - * determines the maximum pixel depth required and allows transformations - * a chance to initialize themselves. - */ - if (png_ptr->transform_list != NULL) - { - png_transform_control tc; - - (void)init_transform_mech(png_ptr, &tc, 1/*start*/); - - png_ptr->row_format = png_check_bits(png_ptr, tc.format, PNG_RF_BITS); - affirm(tc.bit_depth <= 32); - png_ptr->row_bit_depth = png_check_bits(png_ptr, tc.bit_depth, 6); - png_ptr->row_range = png_check_bits(png_ptr, tc.range, 3); -# ifdef PNG_READ_GAMMA_SUPPORTED - png_ptr->row_gamma = tc.gamma; -# endif /* READ_GAMMA */ - - /* The above may have cancelled all the transforms in the list. */ - if (png_ptr->transform_list != NULL) - { - /* Run the transform list again, also forward, and accumulate the - * maximum pixel depth. At this point the transforms can swap - * out their initialization code. - */ - unsigned int max_depth = - init_transform_mech(png_ptr, &tc, 0/*final*/); - - /* init_transform_mech is expected to take the input depth into - * account: - */ - debug(max_depth >= png_depth); - if (max_depth < png_depth) - max_depth = png_depth; - affirm(max_depth <= (png_ptr->read_struct ? 128U : 64U)); - -# ifdef PNG_READ_TRANSFORMS_SUPPORTED - /* Set this now because it only gets resolved finally at this - * point. - */ - png_ptr->invalid_info = tc.invalid_info; -# endif /* READ_TRANSFORMS */ - - /* And check the transform fields: */ - affirm(png_ptr->row_format == tc.format && - png_ptr->row_range == tc.range && - png_ptr->row_bit_depth == tc.bit_depth); -# ifdef PNG_READ_GAMMA_SUPPORTED - affirm(png_ptr->row_gamma == tc.gamma); -# endif /* READ_GAMMA */ - - png_ptr->row_max_pixel_depth = - png_check_bits(png_ptr, max_depth, 8U); - - /* On 'read' input_depth is the PNG pixel depth and output_depth is - * the depth of the pixels passed to the application, but on 'write' - * the transform list is reversed so output_depth is the PNG depth - * and input_depth the application depth. - */ - { - const png_byte app_depth = - png_check_bits(png_ptr, PNG_TC_PIXEL_DEPTH(tc), 8U); - - affirm(app_depth <= max_depth); - - if (png_ptr->read_struct) - { - png_ptr->row_input_pixel_depth = png_depth; - png_ptr->row_output_pixel_depth = app_depth; - } - - else - { - png_ptr->row_input_pixel_depth = app_depth; - png_ptr->row_output_pixel_depth = png_depth; - } - - return; /* to skip the default settings below */ - } - } - } - - else /* png_ptr->transform_list == NULL */ - { - png_ptr->row_format = png_check_bits(png_ptr, - PNG_FORMAT_FROM_COLOR_TYPE(png_ptr->color_type), PNG_RF_BITS); - png_ptr->row_bit_depth = png_check_bits(png_ptr, png_ptr->bit_depth, - 6); - png_ptr->row_range = 0; -# ifdef PNG_READ_GAMMA_SUPPORTED - if ((png_ptr->colorspace.flags & - (PNG_COLORSPACE_INVALID|PNG_COLORSPACE_HAVE_GAMMA)) == - PNG_COLORSPACE_HAVE_GAMMA) - png_ptr->row_gamma = png_ptr->colorspace.gamma; -# endif /* READ_GAMMA */ -# ifdef PNG_READ_TRANSFORMS_SUPPORTED - png_ptr->invalid_info = 0U; -# endif /* READ_TRANSFORMS */ - } -# endif /* TRANSFORM_MECH */ - - /* We get here if there are no transforms therefore no change to the pixel - * bit depths. - */ - png_ptr->row_output_pixel_depth = png_ptr->row_max_pixel_depth = - png_ptr->row_input_pixel_depth = png_depth; -} - -#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ - defined(PNG_WRITE_INTERLACING_SUPPORTED) -int PNGAPI -png_set_interlace_handling(png_structrp png_ptr) -{ - png_debug(1, "in png_set_interlace handling"); - - if (png_ptr != 0) - { - if (png_ptr->read_struct) - { -# ifdef PNG_READ_INTERLACING_SUPPORTED - if (png_ptr->interlaced) - { - png_ptr->do_interlace = 1; - return PNG_INTERLACE_ADAM7_PASSES; - } - - return 1; -# else /* !READ_INTERLACING */ - png_app_error(png_ptr, "no de-interlace support"); - /* return 0 below */ -# endif /* !READ_INTERLACING */ - } - - else /* write */ - { -# ifdef PNG_WRITE_INTERLACING_SUPPORTED - if (png_ptr->interlaced) - { - png_ptr->do_interlace = 1; - return PNG_INTERLACE_ADAM7_PASSES; - } - - return 1; -# else /* !WRITE_INTERLACING */ - png_app_error(png_ptr, "no interlace support"); - /* return 0 below */ -# endif /* !WRITE_INTERLACING */ - } - } - - /* API CHANGE: 1.7.0: returns 0 if called with a NULL png_ptr */ - return 0; -} -#endif /* READ_INTERLACING || WRITE_INTERLACING */ - -#ifdef PNG_MNG_READ_FEATURES_SUPPORTED -/* Undoes intrapixel differencing, this is called immediately after the PNG - * filter has been undone. - */ -static void -png_do_read_intrapixel_RGB8(png_transformp *tr, png_transform_controlp tc) -{ - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_uint_32 width = tc->width; - - tc->sp = dp; - - /* TAKE CARE: dp and sp may be the same, in which case the assignments to *dp - * are overwriting sp[] - */ - do - { - *dp++ = PNG_BYTE(sp[0] + sp[1]); /* red+green */ - *dp++ = *++sp; /* green */ - *dp++ = PNG_BYTE(sp[0] + sp[1]); /* green+blue */ - sp += 2; - } - while (--width > 0); - -# define png_ptr (tc->png_ptr) - UNTESTED -# undef png_ptr - PNG_UNUSED(tr) -} - -static void -png_do_read_intrapixel_RGBA8(png_transformp *tr, png_transform_controlp tc) -{ - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_uint_32 width = tc->width; - - tc->sp = dp; - - do - { - *dp++ = PNG_BYTE(sp[0] + sp[1]); /* red+green */ - *dp++ = *++sp; /* green */ - *dp++ = PNG_BYTE(sp[0] + sp[1]); /* green+blue */ - sp += 2; - *dp++ = *sp++; /* alpha */ - } - while (--width > 0); - -# define png_ptr (tc->png_ptr) - UNTESTED -# undef png_ptr - PNG_UNUSED(tr) -} - -static void -png_do_read_intrapixel_RGB16(png_transformp *tr, png_transform_controlp tc) -{ - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_uint_32 width = tc->width; - - tc->sp = dp; - - /* The input consists of 16-bit values and, by examination of the code - * (please, someone, check; I didn't read the spec) the differencing is done - * against the 16-bit green value. - */ - do - { - unsigned int red = png_get_uint_16(sp + 0); - unsigned int green = png_get_uint_16(sp + 2); - unsigned int blue = png_get_uint_16(sp + 4); - sp += 6; - - red += green; - blue += green; - - *dp++ = PNG_BYTE(red >> 8); - *dp++ = PNG_BYTE(red); - *dp++ = PNG_BYTE(green >> 8); - *dp++ = PNG_BYTE(green); - *dp++ = PNG_BYTE(blue >> 8); - *dp++ = PNG_BYTE(blue); - } - while (--width > 0); - -# define png_ptr (tc->png_ptr) - UNTESTED -# undef png_ptr - PNG_UNUSED(tr) -} - -static void -png_do_read_intrapixel_RGBA16(png_transformp *tr, png_transform_controlp tc) -{ - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_uint_32 width = tc->width; - - tc->sp = dp; - - /* As above but copy the alpha over too. */ - do - { - unsigned int red = png_get_uint_16(sp + 0); - unsigned int green = png_get_uint_16(sp + 2); - unsigned int blue = png_get_uint_16(sp + 4); - sp += 6; - - red += green; - blue += green; - - *dp++ = PNG_BYTE(red >> 8); - *dp++ = PNG_BYTE(red); - *dp++ = PNG_BYTE(green >> 8); - *dp++ = PNG_BYTE(green); - *dp++ = PNG_BYTE(blue >> 8); - *dp++ = PNG_BYTE(blue); - *dp++ = *sp++; - *dp++ = *sp++; /* alpha */ - } - while (--width > 0); - -# define png_ptr (tc->png_ptr) - UNTESTED -# undef png_ptr - PNG_UNUSED(tr) -} - -static void -png_init_read_intrapixel(png_transformp *tr, png_transform_controlp tc) -{ - /* Double check the permitted MNG features in case the app turned the feature - * on then off again. Also make sure the color type is acceptable; it must - * be RGB or RGBA. - */ - png_const_structp png_ptr = tc->png_ptr; - - if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && - (png_ptr->filter_method == PNG_INTRAPIXEL_DIFFERENCING) && - (tc->format & (PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_COLORMAP)) == - PNG_FORMAT_FLAG_COLOR) - { - if (tc->init == PNG_TC_INIT_FINAL) switch (PNG_TC_PIXEL_DEPTH(*tc)) - { - case 24: (*tr)->fn = png_do_read_intrapixel_RGB8; break; - case 32: (*tr)->fn = png_do_read_intrapixel_RGBA8; break; - case 48: (*tr)->fn = png_do_read_intrapixel_RGB16; break; - case 64: (*tr)->fn = png_do_read_intrapixel_RGBA16; break; - default: impossible("bit depth"); - } - } - - else - (*tr)->fn = NULL; -} -#endif /* MNG_READ_FEATURES_SUPPORTED */ - -#ifdef PNG_MNG_WRITE_FEATURES_SUPPORTED -/* This is just the forward direction of the above: - * - * red := red - green - * blue:= blue- green - * - * Alpha is not changed. - */ -static void -png_do_write_intrapixel_RGB8(png_transformp *tr, png_transform_controlp tc) -{ - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_uint_32 width = tc->width; - - tc->sp = dp; - - /* TAKE CARE: dp and sp may be the same, in which case the assignments to *dp - * are overwriting sp[] - */ - do - { - *dp++ = PNG_BYTE(sp[0] - sp[1]); /* red-green */ - *dp++ = *++sp; /* green */ - *dp++ = PNG_BYTE(sp[0] - sp[1]); /* green-blue */ - sp += 2; - } - while (--width > 0); - -# define png_ptr (tc->png_ptr) - UNTESTED -# undef png_ptr - PNG_UNUSED(tr) -} - -static void -png_do_write_intrapixel_RGBA8(png_transformp *tr, png_transform_controlp tc) -{ - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_uint_32 width = tc->width; - - tc->sp = dp; - - do - { - *dp++ = PNG_BYTE(sp[0] - sp[1]); /* red-green */ - *dp++ = *++sp; /* green */ - *dp++ = PNG_BYTE(sp[0] - sp[1]); /* green-blue */ - sp += 2; - *dp++ = *sp++; /* alpha */ - } - while (--width > 0); - -# define png_ptr (tc->png_ptr) - UNTESTED -# undef png_ptr - PNG_UNUSED(tr) -} - -static void -png_do_write_intrapixel_RGB16(png_transformp *tr, png_transform_controlp tc) -{ - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_uint_32 width = tc->width; - - tc->sp = dp; - - do - { - unsigned int red = png_get_uint_16(sp + 0); - unsigned int green = png_get_uint_16(sp + 2); - unsigned int blue = png_get_uint_16(sp + 4); - sp += 6; - - red -= green; - blue -= green; - - *dp++ = PNG_BYTE(red >> 8); - *dp++ = PNG_BYTE(red); - *dp++ = PNG_BYTE(green >> 8); - *dp++ = PNG_BYTE(green); - *dp++ = PNG_BYTE(blue >> 8); - *dp++ = PNG_BYTE(blue); - } - while (--width > 0); - -# define png_ptr (tc->png_ptr) - UNTESTED -# undef png_ptr - PNG_UNUSED(tr) -} - -static void -png_do_write_intrapixel_RGBA16(png_transformp *tr, png_transform_controlp tc) -{ - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_uint_32 width = tc->width; - - tc->sp = dp; - - /* As above but copy the alpha over too. */ - do - { - unsigned int red = png_get_uint_16(sp + 0); - unsigned int green = png_get_uint_16(sp + 2); - unsigned int blue = png_get_uint_16(sp + 4); - sp += 6; - - red -= green; - blue -= green; - - *dp++ = PNG_BYTE(red >> 8); - *dp++ = PNG_BYTE(red); - *dp++ = PNG_BYTE(green >> 8); - *dp++ = PNG_BYTE(green); - *dp++ = PNG_BYTE(blue >> 8); - *dp++ = PNG_BYTE(blue); - *dp++ = *sp++; - *dp++ = *sp++; /* alpha */ - } - while (--width > 0); - -# define png_ptr (tc->png_ptr) - UNTESTED -# undef png_ptr - PNG_UNUSED(tr) -} - -static void -png_init_write_intrapixel(png_transformp *tr, png_transform_controlp tc) -{ - /* Write filter_method 64 (intrapixel differencing) only if: - * - * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED, and; - * 2. Libpng did not write a PNG signature (this filter_method is only - * used in PNG datastreams that are embedded in MNG datastreams), - * and; - * 3. The application called png_permit_mng_features with a mask that - * included PNG_FLAG_MNG_FILTER_64, and; - * 4. The filter_method is 64, and; - * 5. The color_type is RGB or RGBA - */ - png_const_structp png_ptr = tc->png_ptr; - - if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && - (png_ptr->filter_method == PNG_INTRAPIXEL_DIFFERENCING) && - (tc->format & (PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_COLORMAP)) == - PNG_FORMAT_FLAG_COLOR) - { - if (tc->init == PNG_TC_INIT_FINAL) switch (PNG_TC_PIXEL_DEPTH(*tc)) - { - case 24: (*tr)->fn = png_do_write_intrapixel_RGB8; break; - case 32: (*tr)->fn = png_do_write_intrapixel_RGBA8; break; - case 48: (*tr)->fn = png_do_write_intrapixel_RGB16; break; - case 64: (*tr)->fn = png_do_write_intrapixel_RGBA16; break; - default: impossible("bit depth"); - } - } - - else - (*tr)->fn = NULL; -} -#endif /* MNG_WRITE_FEATURES */ - -#ifdef PNG_MNG_FEATURES_SUPPORTED -png_uint_32 PNGAPI -png_permit_mng_features(png_structrp png_ptr, png_uint_32 mng_features) -{ - if (png_ptr != NULL) - { -# ifdef PNG_MNG_READ_FEATURES_SUPPORTED - if ((mng_features & PNG_FLAG_MNG_FILTER_64) != 0) - png_add_transform(png_ptr, 0/*size*/, png_init_read_intrapixel, - PNG_TR_MNG_INTRAPIXEL); -# else /* !MNG_READ_FEATURES */ - if (png_ptr->read_struct) - { - png_app_error(png_ptr, "MNG not supported on read"); - return; - } -# endif /* !MNG_READ_FEATURES */ - -# ifdef PNG_MNG_WRITE_FEATURES_SUPPORTED - if ((mng_features & PNG_FLAG_MNG_FILTER_64) != 0) - png_add_transform(png_ptr, 0/*size*/, png_init_write_intrapixel, - PNG_TR_MNG_INTRAPIXEL); -# else /* !MNG_WRITE_FEATURES */ - if (!png_ptr->read_struct) - { - png_app_error(png_ptr, "MNG not supported on write"); - return; - } -# endif /* !MNG_WRITE_FEATURES */ - - return png_ptr->mng_features_permitted = - mng_features & PNG_ALL_MNG_FEATURES; - } - - return 0; -} -#endif /* MNG_FEATURES */ - -#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) ||\ - defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) ||\ - defined(PNG_READ_SWAP_ALPHA_SUPPORTED) ||\ - defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) ||\ - defined(PNG_READ_FILLER_SUPPORTED) ||\ - defined(PNG_WRITE_FILLER_SUPPORTED) ||\ - defined(PNG_READ_STRIP_ALPHA_SUPPORTED) ||\ - defined(PNG_READ_STRIP_16_TO_8_SUPPORTED) ||\ - defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) ||\ - defined(PNG_READ_EXPAND_16_SUPPORTED) ||\ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) -/* This is a generic transform which manipulates the bytes in an input row. The - * manipulations supported are: - * - * Channel addition (alpha or filler) - * Channel removal (alpha or filler) - * Channel swaps - RGB to BGR, alpha/filler from last to first and vice versa - * - * The output is described in blocks of output pixel size 4-bit codes encoded - * as follows: - * - * 0 Advance the source pointer by the source pixel size, start the - * code list again. This code doesn't actually exist; it is simply - * the result of emptying the code list. - * 1..3 An error (ignored; treated like 0) - * 4..7 Put filler[code-4] into the output - * 8..15 Put source byte[code-8] in the output - * - * The codes are held in a png_uint_32 parameter. transform->args is used by - * the init routine to work out the required codes. The format change is a mask - * which is XORed with the tc format. Note that the init routine works out - * whether to work from the beginning or end of the row and the codes are always - * stored LSB first in the order needed. - */ -typedef struct -{ - png_transform tr; - png_uint_32 codes; /* As above */ - unsigned int format; /* format after transform */ - unsigned int bit_depth; /* bit depth after transform */ - png_byte filler[4]; /* Filler or alpha bytes, LSB first (see below) */ -} png_transform_byte_op; - -static void -png_do_byte_ops_up(png_transformp *transform, png_transform_controlp tc) - /* Row width is unchanged or decreasing */ -{ -# define png_ptr (tc->png_ptr) - png_transform_byte_op *tr = - png_transform_cast(png_transform_byte_op, *transform); - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - const unsigned int sp_advance = PNG_TC_PIXEL_DEPTH(*tc) >> 3; - const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - - debug(tc->bit_depth == 8 || tc->bit_depth == 16); - debug((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0); - - tc->sp = tc->dp; - tc->format = tr->format; - tc->bit_depth = tr->bit_depth; - - /* 'output' is a 32-byte buffer that is used to delay writes for 16 bytes, - * avoiding overwrite when source and destination buffers are the same. - * 'hwm' is either 32 or 16, initially '32', when the byte counter 'i' - * reaches 'hwm' the last-but-one 16 bytes are written; the bytes - * [hwm..hwm+15] modulo 32. hwm is then swapped to hwm+16 mod 32 and i - * continues to advance. i is always below hwm. - * - * At the end the whole remaining buffer from hwm to i is written. - */ - { - const png_uint_32 codes = tr->codes; - png_uint_32 code = codes; - unsigned int i, hwm; /* buffer index and high-water-mark */ - png_byte output[32]; - - hwm = 32; - - for (i=0;;) - { - unsigned int next_code = code & 0xf; - - if (next_code >= 8) - output[i++] = sp[next_code-8]; - - else if (next_code >= 4) - output[i++] = tr->filler[next_code - 4]; - - else /* end code */ - { - sp += sp_advance; - - if (sp >= ep) - break; /* i may be == hwm at this point. */ - - code = codes; - continue; /* no ouput produced, skip the check */ - } - - code >>= 4; /* find the next code */ - - if (i == hwm) - { - hwm &= 0x10U; /* 0 or 16 */ - memcpy(dp, output + hwm, 16); - dp += 16; - i = hwm; /* reset i if hwm was 32 */ - /* hwm is only ever 16 or 32: */ - hwm += 16; - } - } - - /* Write from hwm to (i-1), the delay means there is always something to - * write. - */ - hwm &= 0x10U; - if (hwm == 16) - { - debug(i <= 16); - memcpy(dp, output + hwm, 16); - dp += 16; - } - - if (i > 0) - memcpy(dp, output, i); - -# ifndef PNG_RELEASE_BUILD - dp += i; - /* The macro expansion exceeded the limit on ANSI strings, so split it: - */ - dp -= PNG_TC_ROWBYTES(*tc); - debug(dp == tc->dp); -# endif - } - - debug(sp == ep); -# undef png_ptr -} - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -static void -png_do_byte_ops_down(png_transformp *transform, png_transform_controlp tc) - /* Row width is increasing */ -{ -# define png_ptr (tc->png_ptr) - png_transform_byte_op *tr = - png_transform_cast(png_transform_byte_op, *transform); - const png_const_bytep ep = png_voidcast(png_const_bytep, tc->sp); - const unsigned int sp_advance = PNG_TC_PIXEL_DEPTH(*tc) >> 3; - png_const_bytep sp = ep + PNG_TC_ROWBYTES(*tc); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_alloc_size_t dest_rowbytes; - - debug(tc->bit_depth == 8U || tc->bit_depth == 16U); - debug((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0U); - - tc->sp = tc->dp; - tc->format = tr->format; - tc->bit_depth = tr->bit_depth; - dest_rowbytes = PNG_TC_ROWBYTES(*tc); - dp += dest_rowbytes; - - /* In this case the 32-byte buffer is written downwards with a writes delayed - * by 16 bytes as before. 'hwm' is lower than i; 0 or 16. - */ - { - const png_uint_32 codes = tr->codes; - png_uint_32 code = codes; - unsigned int size, hwm, i; - png_byte output[32] = { 0 }; - - /* This catches an empty codes array, which would cause all the input to - * be skipped and, potentially, a garbage output[] to be written (once) to - * *dp. - */ - affirm((codes & 0xFU) >= 4U); - - /* Align the writes to a 16-byte multiple from the start of the - * destination buffer: - */ - size = dest_rowbytes & 0xFU; - if (size == 0U) size = 16U; - i = size+16U; - sp -= sp_advance; /* Move 1 pixel back */ - hwm = 0U; - - for (;;) - { - unsigned int next_code = code & 0xFU; - - if (next_code >= 8U) - output[--i] = sp[next_code-8U]; - - else if (next_code >= 4U) - output[--i] = tr->filler[next_code - 4U]; - - else /* end code */ - { - sp -= sp_advance; - - if (sp < ep) - break; - - code = codes; - continue; /* no ouput produced, skip the check */ - } - - code >>= 4; /* find the next code */ - - if (i == hwm) - { - /* A partial copy comes at the beginning to align the copies to a - * 16-byte boundary. The bytes to be written are the bytes - * i+16..(hwm-1) except that the partial buffer may reduce this. - */ - dp -= size; - hwm ^= 0x10U; /* == i+16 mod 32 */ - memcpy(dp, output + hwm, size); - size = 16U; - if (i == 0U) i = 32U; - } - } - - /* The loop above only exits with an exit code, so 'i' has been checked - * against 'hwm' before and, because of the alignment, i will always be - * either 16 or 32: - */ - debug((i == 16U || i == 32U) & (((i & 0x10U)^0x10U) == hwm)); - debug(sp+sp_advance == ep); - - /* At the end the bytes i..(hwm-1) need to be written, with the proviso - * that 'size' will be less than 16 for short rows. If 'size' is still a - * short value then the range to be written is output[i..16+(size-1)], - * otherwise (size == 16) either this is the first write and a full 32 - * bytes will be written (hwm == 0, i == 32) or 16 bytes need to be - * written. - */ - if (size < 16U) - { - debug(i == 16U); - dp -= size; - memcpy(dp, output + i, size); - } - - else /* size == 16 */ - { - debug(size == 16U); - - /* Write i..(hwm-1); 16 or 32 bytes, however if 32 bytes are written - * they are contiguous and i==0. - * - * hwm is 0 or 16, i is 16 or 32, swap 0 and 32: - */ - if (hwm == 0U) hwm = 32U; - if (i == 32U) i = 0U; - affirm(i < hwm); - debug(hwm == i+16U || (i == 0U && hwm == 32U)); - - hwm -= i; - dp -= hwm; - memcpy(dp, output+i, hwm); - } - } - - debug(dp == png_upcast(png_bytep, tc->dp)); - -# undef png_ptr -} -#endif /* READ_TRANSFORMS */ - -/* 16 bit byte swapping */ -static void -png_do_bswap(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_transform_byte_op *tr = - png_transform_cast(png_transform_byte_op, *transform); - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - const png_alloc_size_t rowbytes = PNG_TC_ROWBYTES(*tc); - - tc->format = tr->format; - tc->bit_depth = tr->bit_depth; - tc->sp = dp; - -# ifdef _XOPEN_SOURCE - /* byte swapping often has incredibly fast implementations because of the - * importance in handling ethernet traffic. X/Open defines swab() for - * this purpose and it is widely supported and normally incredibly fast: - */ - debug((rowbytes & 1) == 0); - swab(sp, dp, rowbytes); -# else /* !_XOPEN_SOURCE */ - { - const png_const_bytep ep = sp + rowbytes - 1; - - while (sp < ep) - { - png_byte b0 = *sp++; - *dp++ = *sp++; - *dp++ = b0; - } - - debug(sp == ep+1); /* even number of bytes */ - } -# endif - - PNG_UNUSED(transform) -# undef png_ptr -} - -/* The following flags, store in tr->args, are set by the relevant PNGAPI - * png_set calls then resolved below. - */ -#define PNG_BO_STRIP_ALPHA 0x0001U /* Remove an alpha channel (read only) */ -#define PNG_BO_CHOP_16_TO_8 0x0002U /* Chop 16-bit to 8-bit channels */ -#define PNG_BO_GRAY_TO_RGB 0x0004U /* G <-> RGB; replicate channels */ -/* QUANTIZE happens here */ -#define PNG_BO_EXPAND_16 0x0008U /* Expand 8-bit channels to 16-bit */ -#define PNG_BO_BGR 0x0010U /* RGB <-> BGR */ -#define PNG_BO_FILLER 0x0020U /* Add a filler/alpha */ -#define PNG_BO_SWAP_ALPHA 0x0040U /* xA <-> Ax; alpha swap */ -#define PNG_BO_SWAP_16 0x0080U /* 16-bit channel byte swapping */ - -/* The following are additional flags to qualify the transforms: */ -#define PNG_BO_FILLER_ALPHA 0x4000U /* The filler is an alpha value */ -#define PNG_BO_FILLER_FIRST 0x8000U /* The filler comes first */ - -static void -png_init_byte_ops(png_transformp *transform, png_transform_controlp tc) -{ - /* In the absence of png_set_quantize none of the above operations apply to a - * palette row except indirectly; they may apply if the palette was expanded, - * but this happens earlier in the pipeline. - * - * In the presence of png_set_quantize the rules are considerably more - * complex. In libpng 1.6.0 the following operations occur before - * png_do_quantize: - * - * PNG_BO_GRAY_TO_RGB (png_do_gray_to_rgb, but only sometimes) - * PNG_BO_STRIP_ALPHA (png_do_strip_channel; removes alpha) - * encode_alpha - * scale_16_to_8 - * PNG_BO_CHOP_16_TO_8 (png_do_chop) - * - * The following occur afterward: - * - * PNG_BO_EXPAND_16 (png_do_expand_16) - * PNG_BO_GRAY_TO_RGB (png_do_gray_to_rgb, normally) - * PNG_BO_BGR (png_do_bgr) - * PNG_BO_FILLER (png_do_read_filler) - * PNG_BO_SWAP_ALPHA (png_do_read_swap_alpha) - * PNG_BO_SWAP_16 (png_do_swap; 16-bit byte swap) - * - * The gray to RGB operation needs to occur early for GA or gray+tRNS images - * where the pixels are being composed on a non-gray value. For the moment - * we assume that if this is necessary the following 'init' code will see RGB - * at this point. - * - * The quantize operation operates only if: - * - * 1) tc->bit_depth is 8 - * 2) The color type exactly matches that required by the parameters to - * png_set_quantize; it can be RGB, RGBA or palette, but - * png_set_quantize (not the init routine) determines this. - * - * To avoid needing to know this here the two stage initialization is used - * with two transforms, one pre-quantization the other post. In the first - * stage the correct row format and depth is set up. In the second stage the - * pre-quantization transform looks for a post-quantization transform - * immediately following and, if it exists, transfers its flags to that. - */ - png_structp png_ptr = tc->png_ptr; - png_transform_byte_op *tr = - png_transform_cast(png_transform_byte_op, *transform); - png_uint_32 args = tr->tr.args; - const unsigned int png_format = tc->format; - unsigned int format = png_format; /* memory format */ - const unsigned int png_bit_depth = tc->bit_depth; - unsigned int bit_depth = png_bit_depth; /* memory bit depth */ - - debug(tc->init); - - /* Channel swaps do not occur on COLORMAP format data at present because the - * COLORMAP is limited to 1 byte per pixel (so there is nothing to - * manipulate). Likewise for low bit depth gray, however the code below may - * widen 8-bit gray to RGB. - */ - if ((png_format & PNG_FORMAT_FLAG_COLORMAP) != 0U || png_bit_depth < 8U) - { - tr->tr.fn = NULL; - return; - } - - /* This will normally happen in TC_INIT_FORMAT, but if there is a - * png_do_quantize operation which doesn't apply (this is unlikely) it will - * happen in TC_INIT_FINAL. - */ - if (tr->tr.next != NULL && tr->tr.next->order == PNG_TR_CHANNEL_POSTQ) - { - debug(tr->tr.order == PNG_TR_CHANNEL_PREQ); - - /* So we can merge this transform into the next one, note that because the - * PNG_BO_FILLER operation is POSTQ we don't need to copy anything other - * than the flags. - */ - debug((args & tr->tr.next->args) == 0U); - tr->tr.next->args |= args; - tr->tr.fn = NULL; - return; - } - - /* Else compact the flags for this transform - this is done in both - * TC_INIT_FORMAT and TC_INIT_FINAL because it is safer that way; the copy - * above shouldn't actually affect the results but might result in TO8 and - * TO16 cancelling each other because they are in separate transforms before - * the merge above. - * - * QUIET API CHANGE: - * For compatiblity with earlier versions of libpng these tests need to - * occur in the same order as the earlier transforms; 'TO8' combined with - * 'TO16' did actually do something to 16-bit data, however now it just - * preserves the original bit depth. - */ - if ((args & PNG_BO_STRIP_ALPHA) != 0U) - { - if ((format & PNG_FORMAT_FLAG_ALPHA) != 0U) - format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA); - - else - args &= PNG_BIC_MASK(PNG_BO_STRIP_ALPHA); - } - - if ((args & PNG_BO_CHOP_16_TO_8) != 0U) - { - /* This is the quiet API CHANGE; in fact it isn't necessary, but it - * seems likely that requesting both operations is a mistake: - */ - if ((args & PNG_BO_EXPAND_16) != 0U) - args &= PNG_BIC_MASK(PNG_BO_CHOP_16_TO_8|PNG_BO_EXPAND_16); - - else if (bit_depth == 16U) - { - bit_depth = 8U; - - /* This also makes the tRNS chunk unusable: */ - tc->invalid_info |= PNG_INFO_tRNS+PNG_INFO_hIST+PNG_INFO_pCAL; - /* These need further processing: PNG_INFO_sBIT, PNG_INFO_bKGD */ - } - - else - args &= PNG_BIC_MASK(PNG_BO_CHOP_16_TO_8); - } - - /* QUANTIZE happens here */ - - if ((args & PNG_BO_EXPAND_16) != 0U) - { - /* This only does the 8 to 16-bit part of the expansion by multiply by - * 65535/255 (257) using byte replication. The cases of low bit depth - * gray being expanded to 16-bit have to be handled separately. - */ - if (bit_depth == 8U) - bit_depth = 16U; - - else - args &= PNG_BIC_MASK(PNG_BO_EXPAND_16); - } - - if ((args & PNG_BO_GRAY_TO_RGB) != 0U) - { - if ((format & PNG_FORMAT_FLAG_COLOR) == 0U) - format |= PNG_FORMAT_FLAG_COLOR; - - else - args &= PNG_BIC_MASK(PNG_BO_GRAY_TO_RGB); - } - - if ((args & PNG_BO_BGR) != 0U) - { - /* This does not happen on colormaps: */ - if ((format & PNG_FORMAT_FLAG_COLOR) != 0U && !tc->palette) - format |= PNG_FORMAT_FLAG_BGR; - - else - args &= PNG_BIC_MASK(PNG_BO_BGR); - } - - if ((args & PNG_BO_FILLER) != 0U) - { - if ((format & PNG_FORMAT_FLAG_ALPHA) == 0U) - { - format |= PNG_FORMAT_FLAG_ALPHA; - tc->channel_add = 1U; - /* And SWAP_ALPHA did not occur, because prior to 1.7.0 the filler op - * did not set ALPHA in the color type, so use SWAP_ALPHA to handle the - * before/after filler location. - * - * NOTE: this occurs twice, once in TC_START and once in TC_FINAL, but - * that is ok, the operations are idempotent. - * - * For colormaps (tc->palette set) the filler will just end up setting - * all the tRNS entries and PNG_BO_SWAP_ALPHA will be cancelled below. - */ - if ((args & PNG_BO_FILLER_FIRST) != 0U) - args |= PNG_BO_SWAP_ALPHA; - - else - args &= PNG_BIC_MASK(PNG_BO_SWAP_ALPHA); - - if (!(args & PNG_BO_FILLER_ALPHA)) /* filler is not alpha */ - format |= PNG_FORMAT_FLAG_AFILLER; - } - - else - args &= PNG_BIC_MASK(PNG_BO_FILLER); - } - - if ((args & PNG_BO_SWAP_ALPHA) != 0U) - { - /* This does not happen on color maps: */ - if ((format & PNG_FORMAT_FLAG_ALPHA) != 0U && !tc->palette) - format |= PNG_FORMAT_FLAG_AFIRST; - - else - args &= PNG_BIC_MASK(PNG_BO_SWAP_ALPHA); - } - - if ((args & PNG_BO_SWAP_16) != 0U) - { - if (bit_depth == 16U) - format |= PNG_FORMAT_FLAG_SWAPPED; - - else - args &= PNG_BIC_MASK(PNG_BO_SWAP_16); - } - - if (args != 0U) - { - /* At the end (TC_INIT_FINAL) work out the mapping array using the codes - * defined above and store the format and bit depth changes (as changes, - * so they will work either forward or backward). The filler array must - * be set up by the png_set API. - */ - if (tc->init == PNG_TC_INIT_FINAL) - { - const unsigned int png_pixel_size = PNG_TC_PIXEL_DEPTH(*tc) >> 3; - - tc->format = format; - tc->bit_depth = bit_depth; - - { - const unsigned int memory_pixel_size = PNG_TC_PIXEL_DEPTH(*tc) >> 3; - unsigned int code_size, src_size; - int go_down; - png_byte codes[8]; - - /* The codes array maps the PNG format into the memory format - * assuming the mapping works upwards in the address space. - * Initially ignore the bit depth and just work on the first four - * bytes. - */ - codes[0] = 8U; - codes[1] = 9U; - codes[2] = 10U; - codes[3] = 11U; - codes[7] = codes[6] = codes[5] = codes[4] = 0U/*error*/; - - /* PNG_BO_STRIP_ALPHA: handled by memory_pixel_size */ - /* PNG_BO_CHOP_16_TO_8: handled below */ - /* PNG_BO_EXPAND_16: handled below */ - - if ((args & PNG_BO_GRAY_TO_RGB) != 0U) - { - codes[3] = 9U; /* alpha, if present */ - codes[2] = codes[1] = 8U; - -# ifdef PNG_READ_tRNS_SUPPORTED - /* Gray to RGB, so copy the tRNS G value into r,g,b: */ - if (png_ptr->num_trans == 1U) - png_ptr->trans_color.blue = - png_ptr->trans_color.green = - png_ptr->trans_color.red = - png_ptr->trans_color.gray; -# endif /* READ_tRNS */ - } - - /* 'BGR' and gray-to-RGB are mutually exclusive; with gray-to-RGB - * codes[0] == codes[2] == 8 - */ - else if ((args & PNG_BO_BGR) != 0U) - { - codes[0] = 10U; - codes[2] = 8U; - } - - if ((args & PNG_BO_FILLER) != 0U) - { - /* The filler alway goes after; for a 'before' filler the code - * above turns on SWAP_ALPHA too. The gray-to-RGB transform has - * happened already, so the location of the filler channel is - * given by 'format': - */ - if ((format & PNG_FORMAT_FLAG_COLOR) != 0U) - codes[3] = 4U; /* low byte of filler */ - - else - codes[1] = 4U; - } - - if ((args & PNG_BO_SWAP_ALPHA) != 0U) - { - if ((format & PNG_FORMAT_FLAG_COLOR) != 0U) - { - /* BGR may have swapped the early codes. gray-to-RGB may have - * set them all to '8': - */ - png_byte acode = codes[3]; - codes[3] = codes[2]; - codes[2] = codes[1]; - codes[1] = codes[0]; - codes[0] = acode; - } - - else /* GA format */ - codes[0] = codes[1], codes[1] = 8U; - } - - /* PNG_BO_SWAP_16: 16-bit only, handled below */ - - /* Now the 16-bit dependent stuff. */ - if ((args & PNG_BO_CHOP_16_TO_8) != 0U) - { - /* 16-bit input, 8-bit output, happens before FILLER so the - * filler must be an 8-bit value. Apart from a filler code (4 in - * this case) the code must be adjusted from byte 'x' to byte - * '2x' to select the MSB of each 16-bit channel. - * - * We must use PNG_FORMAT_CHANNELS here because the memory pixel - * size might (in the future) include a TO16 operation. - */ - unsigned int i = PNG_FORMAT_CHANNELS(format); - - while (i > 0U) - { - unsigned int code = codes[--i]; - - if (code > 8U) /* 8, 4 need not change */ - codes[i] = PNG_BYTE(8U+2U*(code-8U)); - } - } - - if ((args & PNG_BO_EXPAND_16) != 0U) - { - /* Don't expect this with CHOP, but it will work, setting the low - * 8-bits of each 16-bit value to the high bits. - */ - unsigned int i = PNG_FORMAT_CHANNELS(format); - - while (i > 0U) - { - png_byte code = codes[--i]; - - /* BSWAP is after FILLER, however the data passed in is a - * machine native png_uint_16. We don't know until this init - * routine whether the data is an 8 or 16-bit value because we - * don't know the full set of transforms the app will apply - * when the png_set_filler API is called. - * - * This means that the data in tr->filler[] needs to have the - * low bits in a known place, so the code here puts the low 8 - * bits in filler[0], code 4. Hence the following: - */ - if (code == 4U) - codes[2U*i/*MSB*/] = 5U, codes[2U*i+1U/*LSB*/] = 4U; - - else - codes[2U*i] = codes[2U*i+1U] = code; - } - -# ifdef PNG_READ_tRNS_SUPPORTED - /* We're just duplicating bytes, so the tRNS chunk can be - * maintained if present. If the tRNS is for a colormap this - * produces garbage in trans_color, but it isn't used. - */ - if (png_ptr->num_trans == 1U) - { -# define TO16(x) x = PNG_UINT_16((x & 0xFFU) * 0x101U) - TO16(png_ptr->trans_color.gray); - TO16(png_ptr->trans_color.red); - TO16(png_ptr->trans_color.green); - TO16(png_ptr->trans_color.blue); -# undef TO16 - } -# endif /* READ_tRNS */ - } - - else if (bit_depth == 16U) - { - /* 16-bit input and output. */ - unsigned int i = PNG_FORMAT_CHANNELS(format); - - while (i > 0U) - { - unsigned int code = codes[--i]; - - if (code == 4U) /* as above */ - codes[2U*i/*MSB*/] = 5U, codes[2U*i+1U/*LSB*/] = 4U; - - else - { - codes[2U*i] = PNG_BYTE(8U+2U*(code-8U)); - codes[2U*i+1U] = PNG_BYTE(8U+2U*(code-8U)+1U); - } - } - } - - if ((args & PNG_BO_SWAP_16) != 0U) - { - /* bswap the memory bytes. */ - unsigned int i; - png_byte bswap_codes[sizeof codes]; - - debug((memory_pixel_size & 1U) == 0U); - - for (i=0U; iread_struct) - { - /* There are no write transforms that add data to the PNG - * file; the 'filler' transform removes a channel, but that is - * the limit of the changes. - */ - unsigned int i = 0U; - png_byte write_codes[8U]; - - memset(write_codes, 0, sizeof write_codes); - - while (i= 8U) /* 8+index of PNG byte */ - write_codes[code-8U] = PNG_BYTE(8U+i); - /* else this is a filler byte to be removed */ - else - debug(code == 4U || code == 5U); - - ++i; - } - - code_size = png_pixel_size; - src_size = memory_pixel_size; - tr->format = png_format; - tr->bit_depth = png_bit_depth; - - /* The PNG size should always be <= to the memory size, the - * source pointer will be the memory, the destination the PNG - * format, so it should always be possible to do the upwards - * copy. - */ - go_down = png_pixel_size > memory_pixel_size; - affirm(!go_down); - memcpy(codes, write_codes, sizeof codes); - } - - else -# endif /* WRITE_TRANSFORMS */ - { - code_size = memory_pixel_size; - src_size = png_pixel_size; - tr->format = format; - tr->bit_depth = bit_depth; - go_down = png_pixel_size < memory_pixel_size; - } - - /* Record this for debugging: */ - tr->tr.args = args; - - /* For the same-pixel-size case check for a bswap; this is available - * in heavily optimized forms and is a common operation (50% of the - * time) with 16-bit PNG data, particularly given the handling in - * the simplified API. - */ - if (!go_down) - { - if (memory_pixel_size == png_pixel_size) - { - int the_same = 1; - int swapped = (memory_pixel_size & 1) == 0; /* even count */ - unsigned int i; - - for (i=0U; itr.fn = png_do_bswap; - return; - } - - else if (the_same) - impossible("not reached"); - } - - tr->tr.fn = png_do_byte_ops_up; - - /* Construct the code, forwards: */ - { - unsigned int i = code_size; - png_uint_32 code = 0U; - - while (i > 0U) - { - unsigned int next = codes[--i]; - - code <<= 4U; - - if ((next >= 8U && next < 8U+src_size) || - next == 4U || next == 5U) - code += next; - - else - impossible("invalid code (up)"); - } - - tr->codes = code; - } - } - - else /* go_down */ -# ifdef PNG_READ_TRANSFORMS_SUPPORTED - { - tr->tr.fn = png_do_byte_ops_down; - - /* Construct the code, backwards: */ - { - unsigned int i = 0U; - png_uint_32 code = 0U; - - while (i < code_size) - { - unsigned int next = codes[i++]; - - code <<= 4; - - if ((next >= 8U && next < 8U+src_size) || - next == 4U || next == 5U) - code += next; - - else - impossible("invalid code (down)"); - } - - tr->codes = code; - } - } -# else /* !READ_TRANSFORMS */ - impossible("not reached"); /* because of the affirm above */ -# endif /* !READ_TRANSFORMS */ - } - } - - else /* TC_INIT_FORMAT: just store modified 'args' */ - { - tc->format = format; - tc->bit_depth = bit_depth; - tr->tr.args = args; - } - } - - else /* the transform is not applicable */ - tr->tr.fn = NULL; -} -#endif /* SWAP poo */ - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -static void -png_init_rgb_to_gray_byte_ops(png_transformp *transform, - png_transform_controlp tc) -{ - /* This just delay initializes the function; all the transform initialization - * has been done below. - */ - (*transform)->fn = png_do_byte_ops_up; - - /* If this happens on a row do the transform immediately: */ - if (!tc->init) - png_do_byte_ops_up(transform, tc); - - else - { - /* This doing the init - update the row information here */ -# define png_ptr (tc->png_ptr) - png_transform_byte_op *tr = - png_transform_cast(png_transform_byte_op, *transform); - - debug(tc->bit_depth == 8U || tc->bit_depth == 16U); - debug((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0U && - (tc->format & PNG_FORMAT_FLAG_COLOR) != 0U); - - tc->format = tr->format; - tc->bit_depth = tr->bit_depth; -# undef png_ptr - } -} - -void /* PRIVATE */ -png_add_rgb_to_gray_byte_ops(png_structrp png_ptr, png_transform_controlp tc, - unsigned int index, unsigned int order) - /* Add a byte_ops transform to convert RGB or RGBA data to 'gray' by - * selecting just the given change [index] The transform added is added at - * 'order'. - */ -{ - png_transform_byte_op *tr = png_transform_cast(png_transform_byte_op, - png_add_transform(png_ptr, sizeof (png_transform_byte_op), - png_init_rgb_to_gray_byte_ops, order)); - - affirm((tc->format & (PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_COLORMAP)) == - PNG_FORMAT_FLAG_COLOR && - index <= 2 && tc->init == PNG_TC_INIT_FINAL); - - tr->format = tc->format & PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR); - tr->bit_depth = tc->bit_depth; - - /* For 1 byte channel [index] plus, maybe, alpha: */ - if (tc->bit_depth == 8) - tr->codes = 8U + index + - ((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0 ? (8U+3U) << 4 : 0U); - - else - { - affirm(tc->bit_depth == 16); - - /* As above, but two bytes; [2*index] and [2*index+1] */ - index *= 2U; - tr->codes = (8U + index) + ((9U + index) << 4) + - ((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0 ? - ((8U+6U) + ((9U+6U) << 4)) << 8 : 0U); - } -} -#endif /* READ_RGB_TO_GRAY */ - -#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) &&\ - defined(PNG_READ_BACKGROUND_SUPPORTED) -void /* PRIVATE */ -png_push_gray_to_rgb_byte_ops(png_transformp *transform, - png_transform_controlp tc) - /* This is an init-time utility to add appropriate byte ops to expand a - * grayscale PNG data set to RGB. - */ -{ -# define png_ptr (tc->png_ptr) - png_transformp tr = png_push_transform(png_ptr, - sizeof (png_transform_byte_op), png_init_byte_ops, transform, NULL); - - tr->args = PNG_BO_GRAY_TO_RGB; - debug(tr == *transform); - png_init_byte_ops(transform, tc); -# undef png_ptr -} -#endif /* GRAY_TO_RGB && READ_BACKGROUND */ - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED -void /* PRIVATE */ -png_add_strip_alpha_byte_ops(png_structrp png_ptr) -{ - png_add_transform(png_ptr, sizeof (png_transform_byte_op), png_init_byte_ops, - PNG_TR_CHANNEL_PREQ)->args |= PNG_BO_STRIP_ALPHA; -} -#endif /* READ_STRIP_ALPHA */ - -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED -/* Chop 16-bit depth files to 8-bit depth */ -void PNGAPI -png_set_strip_16(png_structrp png_ptr) -{ - if (png_ptr != NULL) - png_add_transform(png_ptr, sizeof (png_transform_byte_op), - png_init_byte_ops, PNG_TR_CHANNEL_PREQ)->args |= - PNG_BO_CHOP_16_TO_8; -} -#endif /* READ_STRIP_16_TO_8 */ - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -void PNGAPI -png_set_gray_to_rgb(png_structrp png_ptr) -{ - if (png_ptr != NULL) - { - png_set_expand_gray_1_2_4_to_8(png_ptr); - png_add_transform(png_ptr, sizeof (png_transform_byte_op), - png_init_byte_ops, PNG_TR_CHANNEL_PREQ)->args |= - PNG_BO_GRAY_TO_RGB; - } -} -#endif /* READ_GRAY_TO_RGB */ - -/* QUANTIZE */ - -#ifdef PNG_READ_EXPAND_16_SUPPORTED -/* Expand to 16-bit channels. PNG_BO_EXPAND_16 also expands the tRNS chunk if - * it is present, but it requires low bit depth grayscale expanded first. This - * must also force palette to RGB. - */ -void PNGAPI -png_set_expand_16(png_structrp png_ptr) -{ - if (png_ptr != NULL) - { - png_set_expand_gray_1_2_4_to_8(png_ptr); - png_set_palette_to_rgb(png_ptr); - png_add_transform(png_ptr, sizeof (png_transform_byte_op), - png_init_byte_ops, PNG_TR_CHANNEL_POSTQ)->args |= - PNG_BO_EXPAND_16; - } -} -#endif /* READ_EXPAND_16 */ - -#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) -void PNGAPI -png_set_bgr(png_structrp png_ptr) -{ - if (png_ptr != NULL) - { -# ifndef PNG_READ_BGR_SUPPORTED - if (png_ptr->read_struct) - { - png_app_error(png_ptr, "png_set_bgr not supported on read"); - return; - } -# endif -# ifndef PNG_WRITE_BGR_SUPPORTED - if (!png_ptr->read_struct) - { - png_app_error(png_ptr, "png_set_bgr not supported on write"); - return; - } -# endif - - png_add_transform(png_ptr, sizeof (png_transform_byte_op), - png_init_byte_ops, PNG_TR_CHANNEL_POSTQ)->args |= - PNG_BO_BGR; - } -} -#endif /* BGR */ - -#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) -/* This includes png_set_filler and png_set_add_alpha. The only difference - * between the two is that the latter resulted in PNG_COLOR_MASK_ALPHA being - * added to the info_ptr color type, if png_read_update_info was called whereas - * the former did not. - * - * Regardless of whether the added channel resulted in the change to the - * png_info color type, the SWAP_ALPHA transform was not performed, even though - * it apparently occured after the add, because PNG_COLOR_MASK_ALPHA was never - * set in the 1.6 'row_info'. - * - * Consequently 'SWAP_ALPHA' and 'FILLER' were independent; one or the other - * would occur depending on the color type (not the number of channels) prior to - * the two transforms. - * - * Prior to 1.7.0 the app could obtain information about the memory format by - * calling png_read_update_info followed by png_get_color_type and - * png_get_channels. The first would return PNG_COLOR_TYPE..._ALPHA if - * png_set_add_alpha was performed and the base type if png_set_filler was - * performed, however in both cases png_get_channels would return the extra - * channel; 2 or 4. - * - * The app could also insert a user transform callback and view the color type - * in the old "row_info" structure, however this resulted in an inconsistent - * color type because png_set_alpha did not add COLOR_MASK_ALPHA to the color - * type. - * - * Hence API CHANGE: 1.7.0, row transform callbacks now see the same color type - * as reported by png_get_color_type after png_read_update_info. - */ -/* Add a filler byte on read, or remove a filler or alpha byte on write. - * The filler type has changed in v0.95 to allow future 2-byte fillers - * for 48-bit input data, as well as to avoid problems with some compilers - * that don't like bytes as parameters. - */ -static void -set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc, int alpha) -{ - if (png_ptr != NULL) - { - if (filler_loc != PNG_FILLER_BEFORE && filler_loc != PNG_FILLER_AFTER) - { - png_app_error(png_ptr, "png_set_filler: invalid filler location"); - return; - } - -# ifndef PNG_READ_SWAP_SUPPORTED - if (png_ptr->read_struct) - { - png_app_error(png_ptr, "png_set_filler not supported on read"); - return; - } -# endif -# ifndef PNG_WRITE_SWAP_SUPPORTED - if (!png_ptr->read_struct) - { - png_app_error(png_ptr, "png_set_filler not supported on write"); - return; - } -# endif - - { - png_transform_byte_op *tr = - png_transform_cast(png_transform_byte_op, - png_add_transform(png_ptr, sizeof (png_transform_byte_op), - png_init_byte_ops, PNG_TR_CHANNEL_POSTQ)); - png_uint_32 args = PNG_BO_FILLER; - - if (filler_loc == PNG_FILLER_BEFORE) - args |= PNG_BO_FILLER_FIRST; - - if (alpha) - args |= PNG_BO_FILLER_ALPHA; - - tr->tr.args |= args; - - /* The filler must be stored LSByte first: */ - tr->filler[0] = PNG_BYTE(filler >> 0); - tr->filler[1] = PNG_BYTE(filler >> 8); - tr->filler[2] = PNG_BYTE(filler >> 16); - tr->filler[3] = PNG_BYTE(filler >> 24); - } - } -} - -void PNGAPI -png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc) -{ - set_filler(png_ptr, filler, filler_loc, 0/*!alpha*/); -} - -/* Added to libpng-1.2.7 */ -void PNGAPI -png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc) -{ - set_filler(png_ptr, filler, filler_loc, 1/*alpha*/); -} -#endif /* FILLER */ - -#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) -void PNGAPI -png_set_swap_alpha(png_structrp png_ptr) -{ - if (png_ptr != NULL) - { -# ifndef PNG_READ_SWAP_SUPPORTED - if (png_ptr->read_struct) - { - png_app_error(png_ptr, "png_set_swap_alpha not supported on read"); - return; - } -# endif -# ifndef PNG_WRITE_SWAP_SUPPORTED - if (!png_ptr->read_struct) - { - png_app_error(png_ptr, "png_set_swap_alpha not supported on write"); - return; - } -# endif - - png_add_transform(png_ptr, sizeof (png_transform_byte_op), - png_init_byte_ops, PNG_TR_CHANNEL_POSTQ)->args |= - PNG_BO_SWAP_ALPHA; - } -} -#endif /* SWAP_ALPHA */ - -#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) -void PNGAPI -png_set_swap(png_structrp png_ptr) -{ - if (png_ptr != NULL) - { -# ifndef PNG_READ_SWAP_SUPPORTED - if (png_ptr->read_struct) - { - png_app_error(png_ptr, "png_set_swap not supported on read"); - return; - } -# endif -# ifndef PNG_WRITE_SWAP_SUPPORTED - if (!png_ptr->read_struct) - { - png_app_error(png_ptr, "png_set_swap not supported on write"); - return; - } -# endif - - png_add_transform(png_ptr, sizeof (png_transform_byte_op), - png_init_byte_ops, PNG_TR_CHANNEL_POSTQ)->args |= - PNG_BO_SWAP_16; - } -} -#endif /* SWAP */ - -#if defined(PNG_READ_PACKSWAP_SUPPORTED) ||\ - defined(PNG_WRITE_PACKSWAP_SUPPORTED) ||\ - defined(PNG_READ_INVERT_ALPHA_SUPPORTED) ||\ - defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) ||\ - defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) -static png_alloc_size_t -row_align(png_transform_controlp tc) - /* Utiltity to align the source row (sp) in a transform control; it does this - * by simply copying it to dp if it is not already aligned. As a convenience - * the utility returns the number of bytes in the row. - */ -{ - png_const_structp png_ptr = tc->png_ptr; - png_const_voidp sp = tc->sp; - png_voidp dp = tc->dp; - png_alloc_size_t rowbytes = PNG_TC_ROWBYTES(*tc); - - /* For alignment; if png_alignof is not supported by the compiler this will - * always do an initial memcpy if the source and destination are not the - * same. We can only get here for write; the read case always uses locally - * allocated buffers, only write reads from the application data directly. - */ -# ifdef png_alignof - debug(png_isaligned(dp, png_uint_32)); -# endif - if (sp != dp && !png_ptr->read_struct && !png_isaligned(sp, png_uint_32)) - { - UNTESTED - memcpy(dp, sp, rowbytes); - tc->sp = dp; - } - - return rowbytes; -} -#endif /* Stuff that needs row_align */ - -#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) ||\ - defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) ||\ - defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) -/* Bit-ops; invert bytes. This works for mono inverts too because even the low - * bit depths can be handled as bytes (since there can be no intervening - * channels). - */ -#define PNG_B_INVERT_MONO 1U -#define PNG_B_INVERT_RGB 2U /* not set, used below */ -#define PNG_B_INVERT_ALPHA 4U - -typedef struct -{ - png_transform tr; - unsigned int step0; /* initial advance on sp and dp */ - unsigned int step; /* advance after start */ - png_uint_32 mask; /* XOR mask */ -} png_transform_bit_op; - -static void -png_do_invert_all(png_transformp *transform, png_transform_controlp tc) -{ - const png_const_structp png_ptr = tc->png_ptr; - /* Invert the whole row, quickly */ - const png_const_voidp dp_end = png_upcast(png_bytep, tc->dp) + row_align(tc); - png_uint_32p dp = png_voidcast(png_uint_32p, tc->dp); - png_const_uint_32p sp = png_voidcast(png_const_uint_32p, tc->sp); - - tc->sp = dp; - - if (png_ptr->read_struct) - { - tc->format |= PNG_FORMAT_FLAG_RANGE; - tc->range++; - } - - else if (--(tc->range) == 0) - tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_RANGE); - - while (png_upcast(void*,dp) < dp_end) - *dp++ = ~*sp++; - - PNG_UNUSED(transform) -} - -static void -png_do_invert_channel(png_transformp *transform, png_transform_controlp tc) -{ - const png_const_structp png_ptr = tc->png_ptr; - /* Invert just one channel in the row. */ - const png_transform_bit_op * const tr = - png_transform_cast(png_transform_bit_op, *transform); - const png_uint_32 mask = tr->mask; - const unsigned int step = tr->step; - const unsigned int step0 = tr->step0; - const png_const_voidp dp_end = png_upcast(png_bytep, tc->dp) + row_align(tc); - png_uint_32p dp = png_voidcast(png_uint_32p, tc->dp); - png_const_uint_32p sp = png_voidcast(png_const_uint_32p, tc->sp); - - tc->sp = dp; - - if (png_ptr->read_struct) - { - tc->format |= PNG_FORMAT_FLAG_RANGE; - tc->range++; - } - - else if (--(tc->range) == 0) - tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_RANGE); - - if (sp == dp || step == 1) - { - sp += step0; - dp += step0; - - while (png_upcast(void*,dp) < dp_end) - *dp = *sp ^ mask, dp += step, sp += step; - } - - else /* step == 2, copy required */ - { - if (step0) /* must be 1 */ - *dp++ = *sp++; - - while (png_upcast(void*,dp) < dp_end) - { - *dp++ = *sp++ ^ mask; - if (!(png_upcast(void*,dp) < dp_end)) - break; - *dp++ = *sp++; - } - } - - PNG_UNUSED(transform) -} - -static void -png_init_invert(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_transform_bit_op *tr = - png_transform_cast(png_transform_bit_op, *transform); - png_uint_32 invert = tr->tr.args; - png_uint_32 present; /* channels present */ - - if ((tc->format & PNG_FORMAT_FLAG_COLORMAP) != 0) - present = 0; - - else /* not color mapped */ - { - if ((tc->format & PNG_FORMAT_FLAG_COLOR) != 0) - present = PNG_B_INVERT_RGB; - else - present = PNG_B_INVERT_MONO; - - if ((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0) - present |= PNG_B_INVERT_ALPHA; - } - - /* Cannot invert things that aren't there: */ - invert &= present; - - /* If nothing can be inverted is present the transform is not applicable: */ - if (invert == 0) - (*transform)->fn = NULL; - - else - { - tc->format |= PNG_FORMAT_FLAG_RANGE; - tc->range++; - - if (tc->init == PNG_TC_INIT_FINAL) - { - /* If everything that is present is to be inverted just invert the - * whole row: - */ - if (invert == present) - (*transform)->fn = png_do_invert_all; - - else - { - /* One thing is to be inverted, G or A: */ - unsigned int channels = PNG_TC_CHANNELS(*tc); - unsigned int channel = - (tc->format & PNG_FORMAT_FLAG_AFIRST) != 0 ? 0 : channels-1; - - affirm(channels == 2 || channels == 4); - - if (invert != PNG_B_INVERT_ALPHA) - { - debug(invert == PNG_B_INVERT_MONO && channels == 2 && - present == PNG_B_INVERT_MONO+PNG_B_INVERT_ALPHA); - channel = (channels-1) - channel; - } - - affirm(tc->bit_depth == 8 || tc->bit_depth == 16); - - /* So channels[channel] is to be inverted, make a mask: */ - { - union - { - png_byte bytes[8]; - png_uint_32 words[2]; - } masks; - - memset(&masks, 0, sizeof masks); - - if (tc->bit_depth == 8) - { - /* channels is 2 or 4, channel < 4. */ - masks.bytes[channel+channels] = masks.bytes[channel] = 0xff; - tr->step = 1; - tr->mask = masks.words[0]; - tr->step0 = 0; - } - - else /* tc->bit_depth == 16 */ - { - channel <<= 1; /* in bytes */ - masks.bytes[channel+1] = masks.bytes[channel] = 0xff; - - if (channels == 2) - { - tr->step = 1; - tr->mask = masks.words[0]; - tr->step0 = 0; - } - - else /* channels == 4 */ - { - tr->step = 2; - - if (masks.words[0] == 0) - { - tr->mask = masks.words[1]; - tr->step0 = 1; - } - - else - { - tr->mask = masks.words[0]; - tr->step0 = 0; - } - } - } - } - - (*transform)->fn = png_do_invert_channel; - } - } - } -# undef png_ptr -} - -#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) ||\ - defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) -void PNGAPI -png_set_invert_alpha(png_structrp png_ptr) -{ - if (png_ptr != NULL) - { - png_add_transform(png_ptr, sizeof (png_transform_bit_op), - png_init_invert, PNG_TR_INVERT)->args |= PNG_B_INVERT_ALPHA; -# ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED - /* This is necessary to avoid palette processing on write; the only - * transform that applies to colormapped images is the tRNS chunk - * invert. - */ - png_ptr->write_invert_alpha = 1U; -# endif - } -} -#endif /* INVERT_ALPHA */ - -#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) -void PNGAPI -png_set_invert_mono(png_structrp png_ptr) -{ - if (png_ptr != NULL) - png_add_transform(png_ptr, sizeof (png_transform_bit_op), - png_init_invert, PNG_TR_INVERT)->args |= PNG_B_INVERT_MONO; -} -#endif /* INVERT */ -#endif /* INVERT_ALPHA || INVERT */ - -/* - * WARNING - * WARNING - * WARNING - * WARNING - * WARNING The transforms below are temporary; they can and will be - * WARNING heavily optimized before release. - * WARNING - * WARNING - * WARNING - */ -#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) -typedef struct -{ - png_transform tr; - png_color_8 true_bits; -} png_transform_shift; - -/* Shift pixel values to take advantage of whole range. Pass the - * true number of bits in bit_depth. The row should be packed - * according to tc->bit_depth. Thus, if you had a row of - * bit depth 4, but the pixels only had values from 0 to 7, you - * would pass 3 as bit_depth, and this routine would translate the - * data to 0 to 15. - * - * NOTE: this is horrible complexity for no value. Once people suggested they - * were selling 16-bit displays with 5:6:5 bits spread R:G:B but so far as I - * could determine these displays produced intermediate grey (uncolored) colors, - * which is impossible with a true 5:6:5, so most likely 5:6:5 was marketing. - */ -static unsigned int -set_shifts(unsigned int format, unsigned int bit_depth, - png_const_color_8p true_bits, int *shift_start, int *shift_dec) -{ - unsigned int channels = 0; - - if ((format & (PNG_FORMAT_FLAG_ALPHA+PNG_FORMAT_FLAG_AFIRST)) == - (PNG_FORMAT_FLAG_ALPHA+PNG_FORMAT_FLAG_AFIRST)) - ++channels; /* filled in below */ - - if ((format & PNG_FORMAT_FLAG_COLOR) != 0) - { - unsigned int offset = /* 0 or 2 as appropriate for red */ - ((format & PNG_FORMAT_FLAG_BGR) != 0) << 1; - - shift_start[channels+offset] = bit_depth - true_bits->red; - if (shift_dec != NULL) shift_dec[channels+offset] = true_bits->red; - - shift_start[channels+1] = bit_depth - true_bits->green; - if (shift_dec != NULL) shift_dec[channels+1] = true_bits->green; - - offset ^= 2; /* for blue */ - shift_start[channels+offset] = bit_depth - true_bits->blue; - if (shift_dec != NULL) shift_dec[channels+offset] = true_bits->blue; - - channels += 3; - } - - else /* no color: gray */ - { - shift_start[channels] = bit_depth - true_bits->gray; - if (shift_dec != NULL) shift_dec[channels] = true_bits->gray; - ++channels; - } - - if ((format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - const unsigned int offset = - (format & PNG_FORMAT_FLAG_AFIRST) != 0 ? 0 : channels++; - - shift_start[offset] = bit_depth - true_bits->alpha; - if (shift_dec != NULL) shift_dec[offset] = true_bits->alpha; - } - - return channels; -} - -#ifdef PNG_WRITE_SHIFT_SUPPORTED -static void -png_do_shift(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_transform_shift *tr = - png_transform_cast(png_transform_shift, *transform); - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_const_bytep dp_end = dp + PNG_TC_ROWBYTES(*tc); - - png_debug(1, "in png_do_shift"); - - if (--(tc->range) == 0) - tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_RANGE); - - tc->sp = dp; - - { - int shift_start[4], shift_dec[4]; - unsigned int channels = set_shifts(tc->format, tc->bit_depth, - &tr->true_bits, shift_start, shift_dec); - - debug(PNG_TC_CHANNELS(*tc) == channels); - - /* With low res depths, could only be grayscale, so one channel */ - if (tc->bit_depth < 8) - { - unsigned int mask; - - UNTESTED - affirm(channels == 1); - /* This doesn't matter but we expect to run before packswap: */ - debug(!(tc->format & PNG_FORMAT_FLAG_SWAPPED)); - - if (tr->true_bits.gray == 1 && tc->bit_depth == 2) - mask = 0x55; - - else if (tc->bit_depth == 4 && tr->true_bits.gray == 3) - mask = 0x11; - - else - mask = 0xff; - - while (dp < dp_end) - { - int j; - unsigned int v, out; - - v = *sp++; - out = 0; - - for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) - { - if (j > 0) - out |= v << j; - - else - out |= (v >> (-j)) & mask; - } - - *dp++ = png_check_byte(png_ptr, out); - } - } - - else if (tc->bit_depth == 8) - { - unsigned int c = 0; - - UNTESTED - while (dp < dp_end) - { - - int j; - unsigned int v, out; - - v = *sp++; - out = 0; - - for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) - { - if (j > 0) - out |= v << j; - - else - out |= v >> (-j); - } - - *dp++ = png_check_byte(png_ptr, out); - if (++c == channels) c = 0; - } - } - - else /* tc->bit_depth == 16 */ - { - unsigned int c = 0, s0, s1; - - UNTESTED - if ((tc->format & PNG_FORMAT_FLAG_SWAPPED) != 0) - s0 = 0, s1 = 8; /* LSB */ - - else - s0 = 8, s1 = 0; /* MSB */ - - while (dp < dp_end) - { - int j; - unsigned int value, v; - - v = *sp++ << s0; - v += *sp++ << s1; - value = 0; - - for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) - { - if (j > 0) - value |= v << j; - - else - value |= v >> (-j); - } - - *dp++ = PNG_BYTE(value >> s0); - *dp++ = PNG_BYTE(value >> s1); - } - } - } -# undef png_ptr -} -#endif /* WRITE_SHIFT */ - -#ifdef PNG_READ_SHIFT_SUPPORTED -/* Reverse the effects of png_do_shift. This routine merely shifts the - * pixels back to their significant bits values. Thus, if you have - * a row of bit depth 8, but only 5 are significant, this will shift - * the values back to 0 through 31. - */ -static void -png_do_unshift(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_transform_shift *tr = - png_transform_cast(png_transform_shift, *transform); - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_bytep dp = png_voidcast(png_bytep, tc->dp); - png_const_bytep dp_end = dp + PNG_TC_ROWBYTES(*tc); - - png_debug(1, "in png_do_unshift"); - - tc->range++; - tc->format |= PNG_FORMAT_FLAG_RANGE; - - { - int shift[4]; - unsigned int channels = set_shifts(tc->format, tc->bit_depth, - &tr->true_bits, shift, NULL); - - debug(PNG_TC_CHANNELS(*tc) == channels); - - { - unsigned int c, have_shift; - - for (c = have_shift = 0; c < channels; ++c) - { - /* A shift of more than the bit depth is an error condition but it - * gets ignored here. - */ - if (shift[c] <= 0 || (unsigned)/*SAFE*/shift[c] >= tc->bit_depth) - shift[c] = 0; - - else - have_shift = 1; - } - - if (have_shift == 0) - return; - } - - /* The code below will copy sp to dp, so: */ - tc->sp = dp; - - switch (tc->bit_depth) - { - default: - /* Must be 1bpp gray: should not be here! */ - impossible("unshift bit depth"); - /* NOTREACHED */ - break; - - case 2: - /* Must be 2bpp gray */ - debug(channels == 1 && shift[0] == 1); - debug(!(tc->format & PNG_FORMAT_FLAG_SWAPPED)); - - while (dp < dp_end) - *dp++ = (*sp++ >> 1) & 0x55; - break; - - case 4: - /* Must be 4bpp gray */ - debug(channels == 1); - debug(!(tc->format & PNG_FORMAT_FLAG_SWAPPED)); - { - unsigned int gray_shift = shift[0]; - unsigned int mask = 0xf >> gray_shift; /* <= 4 bits */ - - mask |= mask << 4; /* <= 8 bits */ - - while (dp < dp_end) - *dp++ = (png_byte)/*SAFE*/((*sp++ >> gray_shift) & mask); - } - break; - - case 8: - /* Single byte components, G, GA, RGB, RGBA */ - { - unsigned int channel = 0; - - while (dp < dp_end) - { - *dp++ = (png_byte)/*SAFE*/(*sp++ >> shift[channel]); - if (++channel >= channels) - channel = 0; - } - } - break; - - case 16: - /* Double byte components, G, GA, RGB, RGBA */ - { - unsigned int channel = 0; - unsigned int s0, s1; - - if ((tc->format & PNG_FORMAT_FLAG_SWAPPED) != 0) - s0 = 0, s1 = 8; /* LSB */ - - else - s0 = 8, s1 = 0; /* MSB */ - - while (dp < dp_end) - { - unsigned int value = *sp++ << s0; - - value += *sp++ << s1; /* <= 16 bits */ - - value >>= shift[channel]; - if (++channel >= channels) channel = 0; - *dp++ = PNG_BYTE(value >> s0); - *dp++ = PNG_BYTE(value >> s1); - } - } - break; - } - } - -# undef png_ptr -} -#endif /* READ_SHIFT */ - -static void -init_shift(png_transformp *transform, png_transform_controlp tc) -{ - png_const_structp png_ptr = tc->png_ptr; - - /* These shifts apply to the component value, not the pixel index, so skip - * palette data. In addition there is no *write* shift for palette entries; - * only a read one, so skip the write/palette case too. - */ - if ((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0 && - (png_ptr->read_struct || !tc->palette)) - { - /* The only change to the format is to mark the data as having a non-PNG - * range. - */ - tc->range++; - tc->format |= PNG_FORMAT_FLAG_RANGE; - - if (tc->init == PNG_TC_INIT_FINAL) - { -# ifdef PNG_READ_SHIFT_SUPPORTED - if (png_ptr->read_struct) - { - (*transform)->fn = png_do_unshift; - return; - } -# endif -# ifdef PNG_WRITE_SHIFT_SUPPORTED - if (png_ptr->read_struct) - { - (*transform)->fn = png_do_shift; - return; - } -# endif - } - } - - else /* transform not applicable */ - (*transform)->fn = NULL; -} - -void PNGAPI -png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits) -{ - if (png_ptr != NULL && true_bits != NULL) - { -# ifndef PNG_READ_SHIFT_SUPPORTED - if (png_ptr->read_struct) - { - png_app_error(png_ptr, "png_set_shift not supported on read"); - return; - } -# endif -# ifndef PNG_WRITE_SHIFT_SUPPORTED - if (!png_ptr->read_struct) - { - png_app_error(png_ptr, "png_set_shift not supported on write"); - return; - } -# endif - - { - png_transform_shift *trs = png_transform_cast(png_transform_shift, - png_add_transform(png_ptr, sizeof (png_transform_shift), - init_shift, PNG_TR_SHIFT)); - trs->true_bits = *true_bits; - } - } -} -#endif /* SHIFT */ - -#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) -/* Turn on pixel packing */ -void PNGAPI -png_set_packing(png_structrp png_ptr) -{ - /* The transforms aren't symmetric, so even though there is one API there are - * two internal init functions, one for read, the other write: - */ - if (png_ptr != NULL) - { - if (png_ptr->read_struct) - { -# ifdef PNG_READ_PACK_SUPPORTED - png_add_transform(png_ptr, 0/*size*/, png_init_read_pack, - PNG_TR_PACK); -# else - png_app_error(png_ptr, "png_set_packing not supported on read"); -# endif - } - - else - { -# ifdef PNG_WRITE_PACK_SUPPORTED - png_add_transform(png_ptr, 0/*size*/, png_init_write_pack, - PNG_TR_PACK); -# else - png_app_error(png_ptr, "png_set_packing not supported on write"); -# endif - } - } -} -#endif /* PACK */ - -#if defined(PNG_READ_PACKSWAP_SUPPORTED) ||\ - defined(PNG_WRITE_PACKSWAP_SUPPORTED) -/* Turn on pixel-swapping within a byte, this is symmetric - doing the swap - * twice produces the original value, so only one implementation is required for - * either read or write. - * - * Used to be refered to as "packswap", but pixel-swap seems more - * self-documenting. - */ -static void -png_do_swap_1bit(png_transformp *transform, png_transform_controlp tc) -{ - png_alloc_size_t rowbytes = row_align(tc); /* may change tc->sp */ - png_const_uint_32p sp = png_voidcast(png_const_uint_32p, tc->sp); - png_uint_32p dp = png_voidcast(png_uint_32p, tc->dp); - - tc->sp = dp; - tc->format ^= PNG_FORMAT_FLAG_SWAPPED; - - for (;;) - { - png_uint_32 s = *sp++; - s = ((s >> 1) & 0x55555555) | ((s & 0x55555555) << 1); - s = ((s >> 2) & 0x33333333) | ((s & 0x33333333) << 2); - s = ((s >> 4) & 0x0f0f0f0f) | ((s & 0x0f0f0f0f) << 4); - *dp++ = s; - if (rowbytes <= 4) break; - rowbytes -= 4; - } - - PNG_UNUSED(transform) -} - -static void -png_do_swap_2bit(png_transformp *transform, png_transform_controlp tc) -{ - png_alloc_size_t rowbytes = row_align(tc); /* may change tc->sp */ - png_const_uint_32p sp = png_voidcast(png_const_uint_32p, tc->sp); - png_uint_32p dp = png_voidcast(png_uint_32p, tc->dp); - - tc->sp = dp; - tc->format ^= PNG_FORMAT_FLAG_SWAPPED; - - for (;;) - { - png_uint_32 s = *sp++; - s = ((s >> 2) & 0x33333333) | ((s & 0x33333333) << 2); - s = ((s >> 4) & 0x0f0f0f0f) | ((s & 0x0f0f0f0f) << 4); - *dp++ = s; - if (rowbytes <= 4) break; - rowbytes -= 4; - } - - PNG_UNUSED(transform) -} - -static void -png_do_swap_4bit(png_transformp *transform, png_transform_controlp tc) -{ - png_alloc_size_t rowbytes = row_align(tc); /* may change tc->sp */ - png_const_uint_32p sp = png_voidcast(png_const_uint_32p, tc->sp); - png_uint_32p dp = png_voidcast(png_uint_32p, tc->dp); - - tc->sp = dp; - tc->format ^= PNG_FORMAT_FLAG_SWAPPED; - - for (;;) - { - png_uint_32 s = *sp++; - s = ((s >> 4) & 0x0f0f0f0f) | ((s & 0x0f0f0f0f) << 4); - *dp++ = s; - if (rowbytes <= 4) break; - rowbytes -= 4; - } - - PNG_UNUSED(transform) -} - -static void -init_packswap(png_transformp *transform, png_transform_controlp tc) -{ - png_transform_fn fn; - -# define png_ptr tc->png_ptr - debug(tc->init); -# undef png_ptr - - switch (tc->bit_depth) - { - case 1: fn = png_do_swap_1bit; break; - case 2: fn = png_do_swap_2bit; break; - case 4: fn = png_do_swap_4bit; break; - - default: /* transform not applicable */ - (*transform)->fn = NULL; - return; - } - - tc->format ^= PNG_FORMAT_FLAG_SWAPPED; - if (tc->init == PNG_TC_INIT_FINAL) - (*transform)->fn = fn; -} - -void PNGAPI -png_set_packswap(png_structrp png_ptr) -{ - if (png_ptr != NULL) - { -# ifndef PNG_READ_PACKSWAP_SUPPORTED - if (png_ptr->read_struct) - { - png_app_error(png_ptr, "png_set_packswap not supported on read"); - return; - } -# endif -# ifndef PNG_WRITE_PACKSWAP_SUPPORTED - if (!png_ptr->read_struct) - { - png_app_error(png_ptr, "png_set_packswap not supported on write"); - return; - } -# endif - - png_add_transform(png_ptr, 0/*size*/, init_packswap, PNG_TR_PIXEL_SWAP); - } -} -#endif /* PACKSWAP */ - -/* User transform handling */ -#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED -png_uint_32 PNGAPI -png_get_current_row_number(png_const_structrp png_ptr) -{ - /* See the comments in png.h - this is the sub-image row when reading an - * interlaced image. - */ - if (png_ptr != NULL) - { - /* In the read case png_struct::row_number is the row in the final image, - * not the pass, this will return the previous row number if the row isn't - * in the pass: - */ - if (png_ptr->read_struct) - return PNG_PASS_ROWS(png_ptr->row_number+1, png_ptr->pass)-1U; - - else - return png_ptr->row_number; - } - - return PNG_UINT_32_MAX; /* help the app not to fail silently */ -} - -png_byte PNGAPI -png_get_current_pass_number(png_const_structrp png_ptr) -{ - if (png_ptr != NULL) - return png_ptr->pass; - return 8; /* invalid */ -} -#endif /* USER_TRANSFORM_INFO */ - -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) ||\ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) -typedef struct -{ - png_transform tr; - png_user_transform_ptr user_fn; -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED - png_voidp user_ptr; -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - unsigned int user_depth; - unsigned int user_channels; -#endif -#endif -} png_user_transform, *png_user_transformp; - -typedef const png_user_transform *png_const_user_transformp; - -static png_user_transformp -get_user_transform(png_structrp png_ptr) -{ - /* Note that in an added transform the whole transform is memset to 0, so we - * don't need to initialize anything. - */ - return png_transform_cast(png_user_transform, png_add_transform(png_ptr, - sizeof (png_user_transform), NULL/*function*/, PNG_TR_USER)); -} -#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */ - -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -png_voidp PNGAPI -png_get_user_transform_ptr(png_const_structrp png_ptr) -{ - if (png_ptr != NULL) - { - png_transformp tr = png_find_transform(png_ptr, PNG_TR_USER); - - if (tr != NULL) - { - png_user_transformp tru = png_transform_cast(png_user_transform, tr); - return tru->user_ptr; - } - } - - return NULL; -} -#endif /* USER_TRANSFORM_PTR */ - -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -void PNGAPI -png_set_user_transform_info(png_structrp png_ptr, png_voidp ptr, int depth, - int channels) -{ - if (png_ptr != NULL) - { - /* NOTE: this function only sets the user transform pointer on write, i.e. - * the depth and channels arguments are ignored. - */ - png_user_transformp tr = get_user_transform(png_ptr); - - tr->user_ptr = ptr; - -# ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - if (png_ptr->read_struct) - { - if (png_ptr->row_bit_depth == 0) - { - if (depth > 0 && depth <= 32 && channels > 0 && channels <= 4 && - (-depth & depth) == depth /* power of 2 */) - { - tr->user_depth = png_check_bits(png_ptr, depth, 6); - tr->user_channels = png_check_bits(png_ptr, channels, 3); - } - - else - png_app_error(png_ptr, "unsupported bit-depth or channels"); - } - else - png_app_error(png_ptr, - "cannot change user info after image start"); - } -# else /* !READ_USER_TRANSFORM */ - PNG_UNUSED(depth) - PNG_UNUSED(channels) -# endif /* !READ_USER_TRANSFORM */ - } -} -#endif /* USER_TRANSFORM_PTR */ - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED -static void -png_do_read_user_transform(png_transformp *trIn, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - png_user_transformp tr = png_transform_cast(png_user_transform, *trIn); - - if (!tc->init && tr->user_fn != NULL) - { - png_row_info row_info; - - row_info.width = tc->width; - row_info.rowbytes = PNG_TC_ROWBYTES(*tc); - row_info.color_type = png_check_byte(png_ptr, - PNG_COLOR_TYPE_FROM_FORMAT(tc->format)); - row_info.bit_depth = png_check_byte(png_ptr, tc->bit_depth); - row_info.channels = png_check_byte(png_ptr, - PNG_FORMAT_CHANNELS(tc->format)); - row_info.bit_depth = png_check_byte(png_ptr, - PNG_TC_PIXEL_DEPTH(*tc)); - - /* TODO: fix this API, but for the moment we have to copy the row data to - * the working buffer. This is an unnecessary perf overhead when a user - * transform is used to read information without a transform or when it is - * used on write. - */ - if (tc->sp != tc->dp) - { - memcpy(tc->dp, tc->sp, PNG_TC_ROWBYTES(*tc)); - tc->sp = tc->dp; - } - - tr->user_fn(png_ptr, &row_info, png_voidcast(png_bytep, tc->dp)); - } - -# ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED - if (tr->user_depth > 0) - { - /* The read transform can modify the bit depth and number of - * channels; the interface doesn't permit anything else to be - * changed. If the information isn't set the user callback has to - * produce pixels with the correct pixel depth (otherwise the - * de-interlace won't work) but there really is no other constraint. - */ - tc->bit_depth = tr->user_depth; - - /* The API is very restricted in functionality; the user_channels - * can be changed, but the color_type can't, so the format is simply - * fixed up to match the channels. - */ - if (tr->user_channels != PNG_FORMAT_CHANNELS(tc->format)) - switch (tr->user_channels) - { - case 1: - tc->format &= - PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_ALPHA); - break; - - case 2: /* has to be GA */ - tc->format &= - PNG_BIC_MASK(PNG_FORMAT_FLAG_COLORMAP+PNG_FORMAT_FLAG_COLOR); - tc->format |= PNG_FORMAT_FLAG_ALPHA; - break; - - case 3: /* has to be RGB */ - tc->format &= - PNG_BIC_MASK(PNG_FORMAT_FLAG_COLORMAP|PNG_FORMAT_FLAG_ALPHA); - tc->format |= PNG_FORMAT_FLAG_COLOR; - break; - - case 4: /* has to be RGBA */ - tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_COLORMAP); - tc->format |= (PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_ALPHA); - break; - - default: /* checked before */ - impossible("user channels"); - } - - debug(PNG_FORMAT_CHANNELS(tc->format) == tr->user_channels); - } -# endif /* USER_TRANSFORM_PTR */ -# undef png_ptr -} - -void PNGAPI -png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr - read_user_transform_fn) -{ - /* There is no 'init' function, just the callback above to handle the - * transform. - */ - if (png_ptr != NULL) - { - if (png_ptr->read_struct) - { - png_user_transformp tr = get_user_transform(png_ptr); - - tr->user_fn = read_user_transform_fn; - tr->tr.fn = png_do_read_user_transform; - } - - else - png_app_error(png_ptr, "cannot set a read transform on write"); - } -} -#endif /* READ_USER_TRANSFORM */ - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED -static void -png_do_write_user_transform(png_transformp *trIn, png_transform_controlp tc) -{ -# define png_ptr (tc->png_ptr) - /* The write side is pretty simple; call the call-back, it will make the row - * data right. - * - * BUG: we need to copy the input row (it would be a non-quiet API change - * otherwise) and we don't know how big it is because the information passed - * to png_set_user_transform_info never was used on write, but that's fine - * because the write code never did get this right, so presumably all the - * apps have worked round it... - */ - if (!tc->init) - { - png_user_transformp tr = png_transform_cast(png_user_transform, *trIn); - png_row_info row_info; - - if (tc->sp != tc->dp) /* no interlace */ - { - memcpy(tc->dp, tc->sp, PNG_TC_ROWBYTES(*tc)); - tc->sp = tc->dp; - } - - row_info.width = tc->width; - row_info.rowbytes = PNG_TC_ROWBYTES(*tc); - row_info.color_type = png_check_byte(png_ptr, - PNG_COLOR_TYPE_FROM_FORMAT(tc->format)); - row_info.bit_depth = png_check_byte(png_ptr, tc->bit_depth); - row_info.channels = png_check_byte(png_ptr, - PNG_FORMAT_CHANNELS(tc->format)); - row_info.bit_depth = png_check_byte(png_ptr, - PNG_TC_PIXEL_DEPTH(*tc)); - - /* The user function promises to give us this format: */ - tr->user_fn(png_ptr, &row_info, png_voidcast(png_bytep, tc->dp)); - } -# undef png_ptr -} - -void PNGAPI -png_set_write_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr - write_user_transform_fn) -{ - - if (png_ptr != NULL) - { - if (!png_ptr->read_struct) - { - png_user_transformp tr = get_user_transform(png_ptr); - - tr->user_fn = write_user_transform_fn; - tr->tr.fn = png_do_write_user_transform; - } - - else - png_app_error(png_ptr, "cannot set a write transform on read"); - } -} -#endif /* WRITE_USER_TRANSFORM */ diff --git a/ext/libpng17/pngwio.c b/ext/libpng17/pngwio.c deleted file mode 100644 index 430cb29e56..0000000000 --- a/ext/libpng17/pngwio.c +++ /dev/null @@ -1,146 +0,0 @@ - -/* pngwio.c - functions for data output - * - * Last changed in libpng 1.7.0 [(PENDING RELEASE)] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file provides a location for all output. Users who need - * special handling are expected to write functions that have the same - * arguments as these and perform similar functions, but that possibly - * use different output methods. Note that you shouldn't change these - * functions, but rather write replacement functions and then change - * them at run time with png_set_write_fn(...). - */ - -#include "pngpriv.h" -#define PNG_SRC_FILE PNG_SRC_FILE_pngwio - -#ifdef PNG_WRITE_SUPPORTED - -/* Write the data to whatever output you are using. The default routine - * writes to a file pointer. Note that this routine sometimes gets called - * with very small lengths, so you should implement some kind of simple - * buffering if you are using unbuffered writes. This should never be asked - * to write more than 64K on a 16 bit machine. - */ - -void /* PRIVATE */ -png_write_data(png_structrp png_ptr, png_const_voidp data, png_size_t length) -{ - /* This was guaranteed by prior versions of libpng, so app callbacks may - * assume it even though it isn't documented to be the case. - */ - debug(length > 0U); - - /* NOTE: write_data_fn must not change the buffer! - * This cast is required because of the API; changing the type of the - * callback would require every app to change the callback and that change - * would have to be conditional on the libpng version. - */ - if (png_ptr->rw_data_fn != NULL ) - png_ptr->rw_data_fn(png_ptr, - png_constcast(png_bytep,png_voidcast(png_const_bytep,data)), length); - - else - png_app_error(png_ptr, "No write function"); -} - -#ifdef PNG_STDIO_SUPPORTED -/* This is the function that does the actual writing of data. If you are - * not writing to a standard C stream, you should create a replacement - * write_data function and use it at run time with png_set_write_fn(), rather - * than changing the library. - */ -void PNGCBAPI -png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - png_size_t check; - - if (png_ptr == NULL) - return; - - check = fwrite(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr)); - - if (check != length) - png_error(png_ptr, "Write Error"); -} -#endif - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -# ifdef PNG_STDIO_SUPPORTED -void PNGCBAPI -png_default_flush(png_structp png_ptr) -{ - if (png_ptr == NULL) - return; - - fflush(png_voidcast(png_FILE_p, (png_ptr->io_ptr))); -} -# endif -#endif - -/* This function allows the application to supply new output functions for - * libpng if standard C streams aren't being used. - * - * This function takes as its arguments: - * png_ptr - pointer to a png output data structure - * io_ptr - pointer to user supplied structure containing info about - * the output functions. May be NULL. - * write_data_fn - pointer to a new output function that takes as its - * arguments a pointer to a png_struct, a pointer to - * data to be written, and a 32-bit unsigned int that is - * the number of bytes to be written. The new write - * function should call png_error(png_ptr, "Error msg") - * to exit and output any fatal error messages. May be - * NULL, in which case libpng's default function will - * be used. - * flush_data_fn - pointer to a new flush function that takes as its - * arguments a pointer to a png_struct. After a call to - * the flush function, there should be no data in any buffers - * or pending transmission. If the output method doesn't do - * any buffering of output, a function prototype must still be - * supplied although it doesn't have to do anything. If - * PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile - * time, output_flush_fn will be ignored, although it must be - * supplied for compatibility. May be NULL, in which case - * libpng's default function will be used, if - * PNG_WRITE_FLUSH_SUPPORTED is defined. This is not - * a good idea if io_ptr does not point to a standard - * *FILE structure. - */ -void PNGAPI -png_set_write_fn(png_structrp png_ptr, png_voidp io_ptr, - png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn) -{ - if (png_ptr == NULL) - return; - - if (png_ptr->read_struct) - { - png_app_error(png_ptr, "cannot set a write function on a read struct"); - return; - } - - if (write_data_fn == NULL) - { - png_app_error(png_ptr, - "API change: png_set_write_fn requires a function"); - return; - } - - png_ptr->io_ptr = io_ptr; - png_ptr->rw_data_fn = write_data_fn; -# ifdef PNG_WRITE_FLUSH_SUPPORTED - if (output_flush_fn != NULL) - png_ptr->output_flush_fn = output_flush_fn; -# else - PNG_UNUSED(output_flush_fn) -# endif /* WRITE_FLUSH */ -} -#endif /* WRITE */ diff --git a/ext/libpng17/pngwrite.c b/ext/libpng17/pngwrite.c deleted file mode 100644 index 77d1de69c0..0000000000 --- a/ext/libpng17/pngwrite.c +++ /dev/null @@ -1,2193 +0,0 @@ - -/* pngwrite.c - general routines to write a PNG file - * - * Last changed in libpng 1.7.0 [(PENDING RELEASE)] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" -#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED -# include -#endif /* SIMPLIFIED_WRITE_STDIO */ - -#define PNG_SRC_FILE PNG_SRC_FILE_pngwrite - -#ifdef PNG_WRITE_SUPPORTED - -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED -/* Write out all the unknown chunks for the current given location */ -static void -write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr, - unsigned int where) -{ - if (info_ptr->unknown_chunks_num != 0) - { - png_const_unknown_chunkp up; - - png_debug(5, "writing extra chunks"); - - for (up = info_ptr->unknown_chunks; - up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; - ++up) - if ((up->location & where) != 0) - { - /* If per-chunk unknown chunk handling is enabled use it, otherwise - * just write the chunks the application has set. - */ -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - int keep = png_handle_as_unknown(png_ptr, up->name); - - /* NOTE: this code is radically different from the read side in the - * matter of handling an ancillary unknown chunk. In the read side - * the default behavior is to discard it, in the code below the default - * behavior is to write it. Critical chunks are, however, only - * written if explicitly listed or if the default is set to write all - * unknown chunks. - * - * The default handling is also slightly weird - it is not possible to - * stop the writing of all unsafe-to-copy chunks! - * - * TODO: REVIEW: this would seem to be a bug. - */ - if (keep != PNG_HANDLE_CHUNK_NEVER && - ((up->name[3] & 0x20) /* safe-to-copy overrides everything */ || - keep == PNG_HANDLE_CHUNK_ALWAYS || - (keep == PNG_HANDLE_CHUNK_AS_DEFAULT && - png_ptr->unknown_default == PNG_HANDLE_CHUNK_ALWAYS))) -#endif - png_write_chunk(png_ptr, up->name, up->data, up->size); - } - } -} -#endif /* WRITE_UNKNOWN_CHUNKS */ - -#ifdef PNG_WRITE_TEXT_SUPPORTED -static void -png_write_text(png_structrp png_ptr, png_const_inforp info_ptr, png_byte where) - /* Text chunk helper */ -{ - int i; - - /* Check to see if we need to write text chunks */ - for (i = 0; i < info_ptr->num_text; i++) - { - png_debug2(2, "Writing text chunk %d, type %d", i, - info_ptr->text[i].compression); - - /* Text chunks are written at info_ptr->text[i].location, skip the chunk - * if we are not writing at that location: - */ - if ((info_ptr->text[i].location & where) == 0U) - continue; - - switch (info_ptr->text[i].compression) - { - case PNG_ITXT_COMPRESSION_NONE: - case PNG_ITXT_COMPRESSION_zTXt: -# ifdef PNG_WRITE_iTXt_SUPPORTED - /* Write international chunk */ - png_write_iTXt(png_ptr, info_ptr->text[i].compression, - info_ptr->text[i].key, info_ptr->text[i].lang, - info_ptr->text[i].lang_key, info_ptr->text[i].text); -# else /* !WRITE_iTXT */ - png_app_error(png_ptr, "Unable to write international text"); -# endif /* !WRITE_iTXT */ - break; - - case PNG_TEXT_COMPRESSION_zTXt: -# ifdef PNG_WRITE_zTXt_SUPPORTED - /* Write compressed chunk */ - png_write_zTXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, info_ptr->text[i].compression); -# else /* !WRITE_zTXT */ - png_app_error(png_ptr, "Unable to write compressed text"); -# endif /* !WRITE_zTXT */ - break; - - case PNG_TEXT_COMPRESSION_NONE: -# ifdef PNG_WRITE_tEXt_SUPPORTED - /* Write uncompressed chunk */ - png_write_tEXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, 0); -# else /* !WRITE_tEXt */ - /* Can't get here TODO: why not? */ - png_app_error(png_ptr, "Unable to write uncompressed text"); -# endif /* !WRITE_tEXt */ - break; - - default: - /* This is an internal error because the libpng checking should - * never manage to set any 'compression' except the above values. - */ - impossible("invalid text compression"); - } - - /* The chunk was written, record where. This allows the location to have - * multiple bits set; the first successful write freezes the location. - */ - info_ptr->text[i].location = where; - } -} -#endif /* WRITE_TEXT */ - -/* Writes all the PNG information. This is the suggested way to use the - * library. If you have a new chunk to add, make a function to write it, - * and put it in the correct location here. If you want the chunk written - * after the image data, put it in png_write_end(). I strongly encourage - * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing - * the chunk, as that will keep the code from breaking if you want to just - * write a plain PNG file. If you have long comments, I suggest writing - * them in png_write_end(), and compressing them. - */ -void PNGAPI -png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr) -{ - png_debug(1, "in png_write_info_before_PLTE"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - { - int color_type = PNG_COLOR_TYPE_FROM_FORMAT(info_ptr->format); - - /* Write PNG signature; doesn't set PNG_HAVE_PNG_SIGNATURE if it has - * already been written (or rather, if at least 3 bytes have already been - * written; undocumented wackiness, it means the 'PNG' at the start can be - * replace by, e.g. "FOO" or "BAR" or "MNG"). - */ - png_write_sig(png_ptr); - -# ifdef PNG_MNG_FEATURES_SUPPORTED - if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && - png_ptr->mng_features_permitted != 0) - { - png_app_error(png_ptr, - "MNG features are not allowed in a PNG datastream"); - /* Recovery: disable MNG features: */ - png_ptr->mng_features_permitted = 0; - } -# endif /* MNG_FEATURES */ - - /* Write IHDR information. */ - png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height, - info_ptr->bit_depth, color_type, info_ptr->compression_type, - info_ptr->filter_type, info_ptr->interlace_type); - -# ifdef PNG_WRITE_TRANSFORMS_SUPPORTED - /* This are used for checking later on: */ - png_ptr->info_format = info_ptr->format; -# endif /* WRITE_TRANSFORMS */ - - /* This sets the flag that prevents re-entry to the 'before PLTE' case: */ - affirm((png_ptr->mode & PNG_HAVE_IHDR) != 0); - - /* The rest of these check to see if the valid field has the appropriate - * flag set, and if it does, writes the chunk. - * - * 1.6.0: COLORSPACE support controls the writing of these chunks too, and - * the chunks will be written if the WRITE routine is there and - * information is available in the COLORSPACE. (See - * png_colorspace_sync_info in png.c for where the valid flags get set.) - * - * Under certain circumstances the colorspace can be invalidated without - * syncing the info_struct 'valid' flags; this happens if libpng detects - * an error and calls png_error while the color space is being set, yet - * the application continues writing the PNG. So check the 'invalid' - * flag here too. - */ -# ifdef PNG_WRITE_tIME_SUPPORTED - if ((info_ptr->valid & PNG_INFO_tIME) != 0 && - (info_ptr->time_location & PNG_HAVE_IHDR) != 0) - png_write_tIME(png_ptr, &(info_ptr->mod_time)); -# endif /* WRITE_tIME */ - -# ifdef PNG_WRITE_gAMA_SUPPORTED /* enables GAMMA */ - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_gAMA) != 0 && - (info_ptr->valid & PNG_INFO_gAMA) != 0) - { - /* This is the inverse of the test in png.c: */ - affirm(info_ptr->colorspace.gamma >= 16 && - info_ptr->colorspace.gamma <= 625000000); - png_write_gAMA_fixed(png_ptr, info_ptr->colorspace.gamma); - } -# endif /* WRITE_gAMA */ - - /* Write only one of sRGB or an ICC profile. If a profile was supplied - * and it matches one of the known sRGB ones issue a warning. - */ -# ifdef PNG_WRITE_iCCP_SUPPORTED /* enables COLORSPACE, GAMMA */ - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->valid & PNG_INFO_iCCP) != 0) - { -# ifdef PNG_WRITE_sRGB_SUPPORTED - /* The app must have supplied an sRGB iCCP profile (and one that - * is recognized and therefore known to be correct) so we write - * that profile, even though it increases the size of the PNG - * significantly. A warning is reasonable: - */ - if ((info_ptr->valid & PNG_INFO_sRGB) != 0) - png_app_warning(png_ptr, - "profile matches sRGB but writing iCCP instead"); -# endif /* WRITE_sRGB */ - - png_write_iCCP(png_ptr, info_ptr->iccp_name, - info_ptr->iccp_profile); - } -# ifdef PNG_WRITE_sRGB_SUPPORTED - else /* iCCP not written */ -# endif /* WRITE_sRGB */ -# endif /* WRITE_iCCP */ - -# ifdef PNG_WRITE_sRGB_SUPPORTED /* enables COLORSPACE, GAMMA */ - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->valid & PNG_INFO_sRGB) != 0) - png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent); -# endif /* WRITE_sRGB */ - -# ifdef PNG_WRITE_sBIT_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sBIT) != 0) - png_write_sBIT(png_ptr, &(info_ptr->sig_bit), color_type); -# endif /* WRITE_sBIT */ - -# ifdef PNG_WRITE_cHRM_SUPPORTED /* enables COLORSPACE */ - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0 && - (info_ptr->valid & PNG_INFO_cHRM) != 0) - png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy); -# endif /* WRITE_cHRM */ - -# ifdef PNG_WRITE_TEXT_SUPPORTED - if (info_ptr->num_text > 0) - png_write_text(png_ptr, info_ptr, PNG_HAVE_IHDR); -# endif /* WRITE_TEXT */ - -# ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - /* The third arugment must encode only one bit, otherwise chunks will - * be written twice because the test in write_unknown_chunks is - * 'location & where'. - */ - write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR); -# endif - } - - else /* 1.7.0: flag multiple calls; previously ignored */ - png_app_error(png_ptr, - "png_write_info_before_PLTE called more than once"); -} - -void PNGAPI -png_write_info(png_structrp png_ptr, png_const_inforp info_ptr) -{ - png_debug(1, "in png_write_info"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if ((png_ptr->mode & (PNG_HAVE_PLTE+PNG_HAVE_IDAT)) != 0) - { - png_app_error(png_ptr, "late call to png_write_info"); - return; - } - - /* The app may do this for us, and in 1.7.0 multiple calls are flagged as an - * application error, so this code must check: - */ - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_write_info_before_PLTE(png_ptr, info_ptr); - - if ((info_ptr->valid & PNG_INFO_PLTE) != 0) - png_write_PLTE(png_ptr, info_ptr->palette, info_ptr->num_palette); - - /* Validate the consistency of the PNG being produced; a palette must have - * been written if a palette mapped PNG is to be valid: - */ - if ((png_ptr->mode & PNG_HAVE_PLTE) == 0 && - png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - png_error(png_ptr, "Valid palette required for paletted images"); - - /* But always set the mode flag because without this we don't know when to - * write the post-palette text or unknown chunks. - */ - png_ptr->mode |= PNG_HAVE_PLTE; - -# ifdef PNG_WRITE_tRNS_SUPPORTED - if ((info_ptr->valid & PNG_INFO_tRNS) !=0) - { - png_write_tRNS(png_ptr, info_ptr->trans_alpha, - &(info_ptr->trans_color), info_ptr->num_trans, - PNG_COLOR_TYPE_FROM_FORMAT(info_ptr->format)); - } -# endif /* WRITE_tRNS */ - -# ifdef PNG_WRITE_bKGD_SUPPORTED - if ((info_ptr->valid & PNG_INFO_bKGD) != 0) - png_write_bKGD(png_ptr, &(info_ptr->background), - PNG_COLOR_TYPE_FROM_FORMAT(info_ptr->format)); -# endif /* WRITE_bKGD */ - -# ifdef PNG_WRITE_hIST_SUPPORTED - if ((info_ptr->valid & PNG_INFO_hIST) != 0) - png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); -# endif /* WRITE_hIST */ - -# ifdef PNG_WRITE_oFFs_SUPPORTED - if ((info_ptr->valid & PNG_INFO_oFFs) != 0) - png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset, - info_ptr->offset_unit_type); -# endif /* WRITE_oFFs */ - -# ifdef PNG_WRITE_pCAL_SUPPORTED - if ((info_ptr->valid & PNG_INFO_pCAL) != 0) - png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0, - info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, - info_ptr->pcal_units, info_ptr->pcal_params); -# endif /* WRITE_pCAL */ - -# ifdef PNG_WRITE_sCAL_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sCAL) != 0) - png_write_sCAL_s(png_ptr, info_ptr->scal_unit, info_ptr->scal_s_width, - info_ptr->scal_s_height); -# endif /* WRITE_sCAL */ - -# ifdef PNG_WRITE_pHYs_SUPPORTED - if ((info_ptr->valid & PNG_INFO_pHYs) != 0) - png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit, - info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type); -# endif /* WRITE_pHYs */ - -# ifdef PNG_WRITE_tIME_SUPPORTED - if ((info_ptr->valid & PNG_INFO_tIME) != 0 && - (info_ptr->time_location & PNG_HAVE_PLTE) != 0) - png_write_tIME(png_ptr, &(info_ptr->mod_time)); -# endif /* WRITE_tIME */ - -# ifdef PNG_WRITE_sPLT_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sPLT) != 0) - { - int i; - - for (i = 0; i < info_ptr->splt_palettes_num; i++) - png_write_sPLT(png_ptr, info_ptr->splt_palettes + i); - } -# endif /* WRITE_sPLT */ - -# ifdef PNG_WRITE_TEXT_SUPPORTED - if (info_ptr->num_text > 0) - png_write_text(png_ptr, info_ptr, PNG_HAVE_PLTE); -# endif /* WRITE_TEXT */ - -# ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_PLTE); -# endif /* WRITE_UNKNOWN_CHUNKS */ -} - -/* Writes the end of the PNG file. If you don't want to write comments or - * time information, you can pass NULL for info. If you already wrote these - * in png_write_info(), do not write them again here. If you have long - * comments, I suggest writing them here, and compressing them. - */ -void PNGAPI -png_write_end(png_structrp png_ptr, png_inforp info_ptr) -{ - png_debug(1, "in png_write_end"); - - if (png_ptr == NULL) - return; - - if ((png_ptr->mode & - (PNG_HAVE_IHDR+PNG_HAVE_IDAT+PNG_AFTER_IDAT+PNG_HAVE_IEND)) != - (PNG_HAVE_IHDR+PNG_HAVE_IDAT+PNG_AFTER_IDAT)) - { - /* Out of place png_write_end: */ - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_error(png_ptr, "Missing call to png_write_info"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 && png_ptr->zowner == 0) - { - /* TODO: write unknown IDAT here, for the moment allow the app to write - * IDAT then call write_end: - */ - png_app_error(png_ptr, "No IDATs written into file"); - png_ptr->mode |= PNG_HAVE_IDAT+PNG_AFTER_IDAT; - } - - else if ((png_ptr->mode & PNG_AFTER_IDAT) == 0) - { - affirm(png_ptr->zowner == png_IDAT); - png_error(png_ptr, "incomplete PNG image"); /* unrecoverable */ - } - - else if ((png_ptr->mode & PNG_HAVE_IEND) != 0) - { - png_app_error(png_ptr, "multiple calls to png_write_end"); - return; - } - - else - impossible("not reached"); - } - - /* And double check that the image rows were all written; this is actually - * a harmless error on an interlaced image because the image rows with - * data were all passed in or the above check would not work. - * - * Don't do this if the IDAT came from unknowns (TBD) or the app, above. - * - * The check depends on the precise logic in png_write_row. - */ - else if (png_ptr->pass != 7U) - png_app_error(png_ptr, "png_write_row not called to last row"); - - else - debug(png_ptr->row_number == 0U); - - /* See if user wants us to write information chunks */ - if (info_ptr != NULL) - { -# ifdef PNG_WRITE_tIME_SUPPORTED - /* Check to see if user has supplied a time chunk */ - if ((info_ptr->valid & PNG_INFO_tIME) != 0 && - (info_ptr->time_location & PNG_AFTER_IDAT) != 0) - png_write_tIME(png_ptr, &(info_ptr->mod_time)); -# endif - -# ifdef PNG_WRITE_TEXT_SUPPORTED - if (info_ptr->num_text > 0) - png_write_text(png_ptr, info_ptr, PNG_AFTER_IDAT); -# endif /* WRITE_TEXT */ - -# ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT); -# endif - } - - /* Write end of PNG file */ - png_write_IEND(png_ptr); - - /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03, - * and restored again in libpng-1.2.30, may cause some applications that - * do not set png_ptr->output_flush_fn to crash. If your application - * experiences a problem, please try building libpng with - * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to - * png-mng-implement at lists.sf.net . - */ -# ifdef PNG_WRITE_FLUSH_SUPPORTED -# ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED - if (png_ptr->output_flush_fn != NULL) - png_ptr->output_flush_fn(png_ptr); -# endif -# endif -} - -#ifdef PNG_CONVERT_tIME_SUPPORTED -void PNGAPI -png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm * ttime) -{ - png_debug(1, "in png_convert_from_struct_tm"); - - ptime->year = png_check_u16(0/*TODO: fixme*/, 1900 + ttime->tm_year); - ptime->month = png_check_byte(0/*TODO: fixme*/, ttime->tm_mon + 1); - ptime->day = png_check_byte(0/*TODO: fixme*/, ttime->tm_mday); - ptime->hour = png_check_byte(0/*TODO: fixme*/, ttime->tm_hour); - ptime->minute = png_check_byte(0/*TODO: fixme*/, ttime->tm_min); - ptime->second = png_check_byte(0/*TODO: fixme*/, ttime->tm_sec); -} - -void PNGAPI -png_convert_from_time_t(png_timep ptime, time_t ttime) -{ - struct tm *tbuf; - - png_debug(1, "in png_convert_from_time_t"); - - tbuf = gmtime(&ttime); - png_convert_from_struct_tm(ptime, tbuf); -} -#endif - -/* Initialize png_ptr structure, and allocate any memory needed */ -PNG_FUNCTION(png_structp,PNGAPI -png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) -{ -#ifndef PNG_USER_MEM_SUPPORTED - png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr, - error_fn, warn_fn, NULL, NULL, NULL); -#else - return png_create_write_struct_2(user_png_ver, error_ptr, error_fn, - warn_fn, NULL, NULL, NULL); -} - -/* Alternate initialize png_ptr structure, and allocate any memory needed */ -PNG_FUNCTION(png_structp,PNGAPI -png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) -{ - png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr, - error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); -#endif /* USER_MEM */ - - if (png_ptr != NULL) - { -# ifdef PNG_BENIGN_ERRORS_SUPPORTED -# if !PNG_RELEASE_BUILD - /* Always quit on error prior to release */ - png_ptr->benign_error_action = PNG_ERROR; - png_ptr->app_warning_action = PNG_WARN; - png_ptr->app_error_action = PNG_ERROR; -# else /* RELEASE_BUILD */ - /* Allow benign errors on write, subject to app control. */ -# ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED - png_ptr->benign_error_action = PNG_WARN; - png_ptr->app_error_action = PNG_WARN; - png_ptr->app_warning_action = PNG_WARN; -# else /* !BENIGN_WRITE_ERRORS */ - /* libpng build without benign error support; the application - * author has to be assumed to be correct, so: - */ - png_ptr->benign_error_action = PNG_ERROR; - png_ptr->app_warning_action = PNG_WARN; - png_ptr->app_error_action = PNG_ERROR; -# endif /* !BENIGN_WRITE_ERRORS */ -# endif /* RELEASE_BUILD */ -# endif /* BENIGN_ERRORS */ - } - - return png_ptr; -} - - -#if defined(PNG_WRITE_INTERLACING_SUPPORTED) ||\ - defined(PNG_WRITE_TRANSFORMS_SUPPORTED) -static void -write_row_buffered(png_structrp png_ptr, - png_const_bytep row, unsigned int row_info_flags, - void (*copy_fn)(png_const_structrp png_ptr, png_bytep row_buffer, - png_const_bytep row, png_uint_32 x, unsigned int count, unsigned int p), - unsigned int copy_parameter) -{ - unsigned int max_pixels = png_max_pixel_block(png_ptr); - const unsigned int pass = png_ptr->pass; - const png_uint_32 width = png_ptr->interlaced == PNG_INTERLACE_NONE ? - png_ptr->width : PNG_PASS_COLS(png_ptr->width, pass); - png_uint_32 x; - png_byte prev_pixels[4*2*2]; /* 2 pixels up to 4 2-byte channels each */ - - memset(prev_pixels, 0U, sizeof prev_pixels); - - for (x = 0U; x < width; x += max_pixels) - { - union - { - PNG_ROW_BUFFER_ALIGN_TYPE force_buffer_alignment; - png_byte buffer[PNG_ROW_BUFFER_SIZE]; - } pixel_buffer; - - if (max_pixels > width - x) - max_pixels = (unsigned int)/*SAFE*/(width - x); - - debug((row_info_flags & png_row_end) == 0U); /* must be set here at end */ - if (x + max_pixels >= width) - row_info_flags |= png_row_end; - - /* Copy a block of input pixels into the buffer, effecting the interlace - * on the way if required. The argument is the number of pixels in the - * buffer, not the number handled from the input which will be larger in - * the interlaced case. - */ - copy_fn(png_ptr, pixel_buffer.buffer, row, x, max_pixels, copy_parameter); - - /* Now pixel_buffer[0..max_pixels-1] contains max_pixels pixels which may - * need to be transformed (the interlace has already been handled). - */ -# ifdef PNG_WRITE_TRANSFORMS_SUPPORTED - if (png_ptr->transform_list != NULL) - { - png_transform_control tc; - - /* The initial values are the memory format; this was worked out in - * png_init_row_info below. - */ - memset(&tc, 0, sizeof tc); - tc.png_ptr = png_ptr; - tc.sp = tc.dp = pixel_buffer.buffer; - - tc.width = max_pixels; /* width of block that we have */ - tc.format = png_ptr->row_format; - tc.range = png_ptr->row_range; - tc.bit_depth = png_ptr->row_bit_depth; - /* tc.init == 0 */ - /* tc.caching: not used */ - /* tc.palette: not used */ - debug(PNG_TC_PIXEL_DEPTH(tc) == png_ptr->row_input_pixel_depth); - - /* Run the list. */ - png_run_transform_list_backwards(png_ptr, &tc); - - /* Make sure the format that resulted is compatible with PNG: */ - affirm((tc.format & PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA + - PNG_FORMAT_FLAG_COLOR + PNG_FORMAT_FLAG_LINEAR + - PNG_FORMAT_FLAG_COLORMAP)) == 0); - - /* Now we must have the PNG format from the IHDR: */ - affirm(png_ptr->bit_depth == tc.bit_depth && - png_ptr->color_type == PNG_COLOR_TYPE_FROM_FORMAT(tc.format)); - } -# endif /* WRITE_TRANSFORMS */ - - /* Call png_write_png_data to write this block of data, the test on - * maxpixels says if this is the final block in the row. - */ - png_write_png_data(png_ptr, prev_pixels, pixel_buffer.buffer, x, - max_pixels, row_info_flags); - } -} -#endif /* WRITE { INTERLACING || TRANSFORMS } */ - -#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED -static void -copy_row(png_const_structrp png_ptr, png_bytep row_buffer, - png_const_bytep row, png_uint_32 x, unsigned int count, - unsigned int pixel_depth) -{ - /* Copy row[x..x+count] pixels to row_buffer. */ - png_copy_row(png_ptr, row_buffer, row, x, count, pixel_depth, 1/*clear*/, - 0/* x_in_dest; row[x]->row_buffer */); -} -#endif /* WRITE_TRANSFORMS */ - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED -static void -interlace_row_lbd(png_const_structrp png_ptr, png_bytep dp, png_const_bytep sp, - png_uint_32 x, unsigned int count, const unsigned int B) -{ - /* Pick out the correct pixels for the interlace pass. The basic idea here - * is to go through the row with a source pointer and a destination pointer - * (sp and dp), and copy the correct pixels for the pass. As the row gets - * compacted, sp will always be >= dp, so we should never overwrite anything. - * See the default: case for the easiest code to understand. - */ - const unsigned int pass = png_ptr->pass; - png_uint_32 i = PNG_COL_FROM_PASS_COL(x, pass); - const unsigned int inc = PNG_PASS_COL_OFFSET(pass); - - /* For pixels less than one byte wide the correct pixels have to be - * extracted from the input bytes. Because we are reading data in - * the application memory format we cannot rely on the PNG big - * endian order. Notice that this was apparently broken before - * 1.7.0. - * - * In libpng 1.7.0 libpng uses a classic bit-pump to optimize the - * extraction. In all passes before the last (6/7) no two pixels - * are adjacent in the input, so we are always extracting 1 bit. - * At present the code uses an 8-bit buffer to avoid coding for - * different byte sexes, but this could easily be changed. - * - * 'i' is the bit-index of bit in the input (sp[]), so, - * considering the 1-bit per pixel case, sp[i>>3] is the byte - * and the bit is bit (i&7) (0 lowest) on swapped (little endian) - * data or 7-(i&7) on PNG default (big-endian) data. - * - * Define these macros, where: - * - * B: the log2 bit depth (0, 1, 2 for 1bpp, 2bpp or 4bpp) of - * the data; this should be a constant. - * sp: the source pointer (sp) (a png_const_bytep) - * i: the pixel index in the input (png_uint_32) - * j: the bit index in the output (unsigned int) - * - * Unlike 'i', 'j' is interpreted directly; for LSB bytes it counts - * up, for MSB it counts down. - * - * NOTE: this could all be expanded to eliminate the code below by - * the time honoured copy'n'paste into three separate functions. This - * might be worth doing in the future. - */ -# define PIXEL_MASK ((1U << (1<>(3-(B))]) /* byte to use */ -# define SP_OFFSET_LSB ((BIT_MASK & i) << (B)) -# define SP_OFFSET_MSB ((BIT_MASK & ~i) << (B)) -# define SP_PIXEL(sex) ((SP_BYTE >> SP_OFFSET_ ## sex) & PIXEL_MASK) - { - unsigned int j; - unsigned int d; - - /* The data is always in the PNG, big-endian, format: */ - for (j = 8U, d = 0U; count > 0U; --count, i += inc) - { /* big-endian */ - j -= 1U<pass; - const unsigned int inc = PNG_PASS_COL_OFFSET(pass); - - /* Loop through the input copying each pixel to the correct place - * in the output. Note that the loop may be executed 0 times if - * this is called on a narrow image that does not contain this - * pass. - */ - for (sp += PNG_COL_FROM_PASS_COL(x, pass) * cbytes; count > 0; - --count, sp += inc * cbytes, dp += cbytes) - memcpy(dp, sp, cbytes); -} -#endif /* WRITE_INTERLACING */ - -#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED -static void -write_row_core(png_structrp png_ptr, png_const_bytep row, - unsigned int row_info_flags) -{ -# ifdef PNG_WRITE_TRANSFORMS_SUPPORTED - if (png_ptr->transform_list != NULL) - write_row_buffered(png_ptr, row, row_info_flags, - copy_row, png_ptr->row_input_pixel_depth); - - else -# endif /* WRITE_TRANSFORMS */ - - /* If control reaches this point the intermediate buffer is not required and - * the input data can be used unmodified. - */ - png_write_png_rows(png_ptr, &row, 1U); - PNG_UNUSED(row_info_flags) -} - -/* Write a single non-interlaced row. */ -static void -write_row_non_interlaced(png_structrp png_ptr, png_const_bytep row) -{ - const png_uint_32 row_number = png_ptr->row_number+1U; - /* There is only one pass, so this is the last pass: */ - const unsigned int row_info_flags = - (row_number == 1U ? png_pass_first_row : 0) | - (row_number >= png_ptr->height ? png_pass_last_row : 0) | - png_pass_last; - - debug(png_ptr->interlaced == PNG_INTERLACE_NONE); - - write_row_core(png_ptr, row, row_info_flags); -} - -/* Write a single interlaced row. */ -static void -write_row_interlaced(png_structrp png_ptr, png_const_bytep row) -{ - const png_uint_32 row_number = png_ptr->row_number+1U; - const png_uint_32 height = png_ptr->height; - const unsigned int pass = png_ptr->pass; - const unsigned int row_info_flags = - (row_number == 1U ? png_pass_first_row : 0) | - (row_number == PNG_PASS_ROWS(height, pass) ? png_pass_last_row : 0) | - (pass == PNG_LAST_PASS(png_ptr->width, height) ? png_pass_last : 0); - -# ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* Check that libpng is not doing the interlace: */ - debug(png_ptr->interlaced != PNG_INTERLACE_NONE && - !png_ptr->do_interlace); -# endif /* WRITE_INTERLACING */ - - write_row_core(png_ptr, row, row_info_flags); -} -#endif /* WRITE_TRANSFORMS */ - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED -/* Interlace a row then write it out. */ -static void -interlace_row(png_structrp png_ptr, png_const_bytep row) -{ - /* The row may not exist in the image (for this pass). */ - const png_uint_32 row_number = png_ptr->row_number; /* in image */ - const unsigned int pass = png_ptr->pass; - - if (png_ptr->width > PNG_PASS_START_COL(pass) && - PNG_ROW_IN_INTERLACE_PASS(row_number, pass)) - { - const unsigned int row_info_flags = - (row_number == PNG_PASS_START_ROW(pass) ? png_pass_first_row : 0) | - (PNG_LAST_PASS_ROW(row_number, pass, png_ptr->height) ? - png_pass_last_row : 0) | - (pass == PNG_LAST_PASS(png_ptr->width, png_ptr->height) ? - png_pass_last : 0); - - if (pass < 6) - { - /* Libpng is doing the interlacing and pixels need to be selected - * from the input row for this pass. - */ - /* row interlacing uses either the log bit depth for low bit - * depth input or the byte count for 8bpp or bigger pixels. - */ - const unsigned int input_depth = png_ptr->row_input_pixel_depth; - unsigned int B = 0; /* log2(input_depth) */ - - switch (input_depth) - { - case 4U: /* B will be 2 */ - ++B; - /*FALL THROUGH*/ - case 2U: /* B will be 1 */ - ++B; - /*FALL THROUGH*/ - case 1U: /* B will be 0 */ - write_row_buffered(png_ptr, row, row_info_flags, - interlace_row_lbd, B); - break; - - default: /* Parameter is the pixel size in bytes */ - write_row_buffered(png_ptr, row, row_info_flags, - interlace_row_byte, input_depth >> 3); - break; - } - } /* pass < 6 */ - - else /* pass 6: no interlacing required */ - write_row_core(png_ptr, row, row_info_flags); - } - - else - { - /* This code must advance row_number/pass itself; the row has been - * skipped. - */ - if (row_number+1U < png_ptr->height) - png_ptr->row_number = row_number+1U; - - else - { - png_ptr->row_number = 0U; - png_ptr->pass = 0x7U & (pass+1U); - } - } -} -#endif /* WRITE_INTERLACING */ - -/* Bottleneck API to actually write a number of rows, only exists because the - * rows parameter to png_write_rows is wrong. - */ -static void -png_write_rows_internal(png_structrp png_ptr, png_const_bytep *rows, - png_uint_32 num_rows) -{ - if (png_ptr != NULL && num_rows > 0U && rows != NULL) - { - /* Unlike the read code initialization happens automatically: */ - if (png_ptr->row_number == 0U && png_ptr->pass == 0U) - { - png_init_row_info(png_ptr); - -# ifdef PNG_WRITE_TRANSFORMS_SUPPORTED - /* If the app takes a png_info from a read operation and if the app has - * performed transforms on the data the png_info can contain IHDR - * information that cannot be represented in PNG. The code that writes - * the IHDR takes the color type from the png_info::format. The app - * adds transforms, before or after writing the IHDR, then the IHDR - * color_type stored in png_struct::color_type is used in - * png_init_row_info above to work out the actual row format. - * - * Prior to 1.7.0 this was not verified (there was no easy way to do - * so). Now we can check it here, however this is an: - * - * API CHANGE: in 1.7.0 an error may be flagged against bogus - * info_struct formats even though the app had removed them itself. - * It's just a warning at present. - * - * The test is that either the row_format produced by the write - * transforms exactly matches that in the original info_struct::format - * or that the info_struct::format was a simple mapping of the - * color_type that ended up in the IHDR: - */ - if (png_ptr->row_format != png_ptr->info_format && - PNG_FORMAT_FROM_COLOR_TYPE(png_ptr->color_type) != - png_ptr->info_format) - png_app_warning(png_ptr, "info_struct format does not match IHDR"); -# endif /* WRITE_TRANSFORMS */ - - /* Perform initialization required before IDATs are written. */ - png_write_start_IDAT(png_ptr); - } - - else if (png_ptr->pass >= 7U) /* too many calls; write already ended */ - { - debug(png_ptr->row_number == 0U); - png_app_error(png_ptr, "Too many calls to png_write_row"); - return; - } - - /* The remainder of these tests detect internal errors in libpng */ - else if (png_ptr->interlaced == PNG_INTERLACE_NONE) - affirm(png_ptr->row_number < png_ptr->height && png_ptr->pass == 0U); - -# ifdef PNG_WRITE_INTERLACING_SUPPORTED - else if (png_ptr->do_interlace) - affirm(png_ptr->row_number < png_ptr->height); -# endif /* WRITE_INTERLACING */ - - else /* app does interlace */ - affirm( - PNG_PASS_IN_IMAGE(png_ptr->width, png_ptr->height, png_ptr->pass) && - png_ptr->row_number < PNG_PASS_ROWS(png_ptr->height, png_ptr->pass) - ); - - /* First handle rows that require buffering because of the need to - * interlace them or the need to perform write transforms. - */ -# ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* libpng is doing the interlacing, but this only makes a difference to - * the first six passes (numbered, in libpng, 0..5); the seventh pass - * (numbered 6 by libpng) consists of complete image rows. - */ - if (png_ptr->do_interlace) while (num_rows > 0U && png_ptr->pass < 6) - interlace_row(png_ptr, *rows++), --num_rows; -# endif /* WRITE_INTERLACING */ - -# ifdef PNG_WRITE_TRANSFORMS_SUPPORTED - /* Transforms required however the row interlacing has already been - * handled and we have a complete (PNG) row. - */ - if (png_ptr->transform_list != NULL) - { - if (png_ptr->interlaced == PNG_INTERLACE_NONE) - while (num_rows > 0U) - write_row_non_interlaced(png_ptr, *rows++), --num_rows; - -# ifdef PNG_WRITE_INTERLACING_SUPPORTED - else if (png_ptr->do_interlace) - while (num_rows > 0U) - interlace_row(png_ptr, *rows++), --num_rows; -# endif /* WRITE_INTERLACING */ - - else /* app does the interlacing */ - while (num_rows > 0U) - write_row_interlaced(png_ptr, *rows++), --num_rows; - } -# endif /* WRITE_TRANSFORMS */ - - /* Finally handle any remaining rows that require no (libpng) interlace - * and no transforms. - */ - if (num_rows > 0U) - png_write_png_rows(png_ptr, rows, num_rows); - - /* Repeat the checks above, but allow for end-of-image. */ - if (png_ptr->pass < 7U) - { - if (png_ptr->interlaced == PNG_INTERLACE_NONE) - affirm(png_ptr->row_number < png_ptr->height && - png_ptr->pass == 0U); - -# ifdef PNG_WRITE_INTERLACING_SUPPORTED - else if (png_ptr->do_interlace) - affirm(png_ptr->row_number < png_ptr->height); -# endif /* WRITE_INTERLACING */ - - else /* app does interlace */ - affirm(PNG_PASS_IN_IMAGE(png_ptr->width, png_ptr->height, - png_ptr->pass) && - png_ptr->row_number < - PNG_PASS_ROWS(png_ptr->height, png_ptr->pass)); - } - } /* png_ptr, rows, num_rows all valid */ - - else if (png_ptr != NULL) - png_app_warning(png_ptr, "Missing rows to row write API"); -} - -/* ROW WRITE APIs */ -/* Called by user to write a single row of image data */ -void PNGAPI -png_write_row(png_structrp png_ptr, png_const_bytep row) -{ - png_debug(1, "in png_write_row"); - png_write_rows_internal(png_ptr, &row, 1U); -} - -/* Write a few rows of image data. If the image is interlaced, - * either you will have to write the 7 sub images, or, if you - * have called png_set_interlace_handling(), you will have to - * "write" the image seven times. - */ -void PNGAPI -png_write_rows(png_structrp png_ptr, png_bytepp rows, png_uint_32 num_rows) -{ - png_debug(1, "in png_write_rows"); - - if (png_ptr != NULL) - png_write_rows_internal(png_ptr, png_constcast(png_const_bytep*,rows), - num_rows); -} - -/* Write the image. You only need to call this function once, even - * if you are writing an interlaced image. - */ -void PNGAPI -png_write_image(png_structrp png_ptr, png_bytepp image) -{ - png_debug(1, "in png_write_image"); - - if (png_ptr != NULL) - { - int num_pass = 1; - - /* The image is always an non-interlaced image. To write it as interlaced - * interlace handling must be present: - */ - if (png_ptr->interlaced) - { -# ifdef PNG_WRITE_INTERLACING_SUPPORTED - num_pass = png_set_interlace_handling(png_ptr); -# else /* !WRITE_INTERLACING */ - /* There is no recovery because the IHDR has already been written. - */ - png_error(png_ptr, "No interlace support"); -# endif /* !WRITE_INTERLACING */ - } - - /* And write the whole thing, 7 times if interlacing it: */ - for (; num_pass > 0; --num_pass) - png_write_rows(png_ptr, image, png_ptr->height); - } -} - -/* Free any memory used in png_ptr struct without freeing the struct itself. */ -static void -png_write_destroy(png_structrp png_ptr) -{ - png_debug(1, "in png_write_destroy"); - - png_deflate_destroy(png_ptr); - -#ifdef PNG_TRANSFORM_MECH_SUPPORTED - png_transform_free(png_ptr, &png_ptr->transform_list); -#endif - -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - png_free(png_ptr, png_ptr->chunk_list); - png_ptr->chunk_list = NULL; -#endif - - /* The error handling and memory handling information is left intact at this - * point: the jmp_buf may still have to be freed. See png_destroy_png_struct - * for how this happens. - */ -} - -/* Free all memory used by the write. - * In libpng 1.6.0 this API changed quietly to no longer accept a NULL value for - * *png_ptr_ptr. Prior to 1.6.0 it would accept such a value and it would free - * the passed in info_structs but it would quietly fail to free any of the data - * inside them. In 1.6.0 it quietly does nothing (it has to be quiet because it - * has no png_ptr.) - */ -void PNGAPI -png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) -{ - png_debug(1, "in png_destroy_write_struct"); - - if (png_ptr_ptr != NULL) - { - png_structrp png_ptr = *png_ptr_ptr; - - if (png_ptr != NULL) /* added in libpng 1.6.0 */ - { - png_destroy_info_struct(png_ptr, info_ptr_ptr); - - *png_ptr_ptr = NULL; - png_write_destroy(png_ptr); - png_destroy_png_struct(png_ptr); - } - } -} - -void PNGAPI -png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->write_row_fn = write_row_fn; -} - -#ifdef PNG_WRITE_PNG_SUPPORTED -void PNGAPI -png_write_png(png_structrp png_ptr, png_inforp info_ptr, - int transforms, voidp params) -{ - if (png_ptr == NULL || info_ptr == NULL) - return; - - if ((info_ptr->valid & PNG_INFO_IDAT) == 0) - { - png_app_error(png_ptr, "no rows for png_write_image to write"); - return; - } - - /* Write the file header information. */ - png_write_info(png_ptr, info_ptr); - - /* ------ these transformations don't touch the info structure ------- */ - - /* Invert monochrome pixels */ - if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0) -#ifdef PNG_WRITE_INVERT_SUPPORTED - png_set_invert_mono(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported"); -#endif - - /* Shift the pixels up to a legal bit depth and fill in - * as appropriate to correctly scale the image. - */ - if ((transforms & PNG_TRANSFORM_SHIFT) != 0) -#ifdef PNG_WRITE_SHIFT_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sBIT) != 0) - png_set_shift(png_ptr, &info_ptr->sig_bit); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported"); -#endif - - /* Pack pixels into bytes */ - if ((transforms & PNG_TRANSFORM_PACKING) != 0) -#ifdef PNG_WRITE_PACK_SUPPORTED - png_set_packing(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported"); -#endif - - /* Swap location of alpha bytes from ARGB to RGBA */ - if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0) -#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED - png_set_swap_alpha(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported"); -#endif - - /* Remove a filler (X) from XRGB/RGBX/AG/GA into to convert it into - * RGB, note that the code expects the input color type to be G or RGB; no - * alpha channel. - */ - if ((transforms & (PNG_TRANSFORM_STRIP_FILLER_AFTER| - PNG_TRANSFORM_STRIP_FILLER_BEFORE)) != 0) - { -#ifdef PNG_WRITE_FILLER_SUPPORTED - if ((transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) != 0) - { - if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0) - png_app_error(png_ptr, - "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported"); - - /* Continue if ignored - this is the pre-1.6.10 behavior */ - png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); - } - - else if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0) - png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_FILLER not supported"); -#endif - } - - /* Flip BGR pixels to RGB */ - if ((transforms & PNG_TRANSFORM_BGR) != 0) -#ifdef PNG_WRITE_BGR_SUPPORTED - png_set_bgr(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported"); -#endif - - /* Swap bytes of 16-bit files to most significant byte first */ - if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0) -#ifdef PNG_WRITE_SWAP_SUPPORTED - png_set_swap(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported"); -#endif - - /* Swap bits of 1, 2, 4 bit packed pixel formats */ - if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0) -#ifdef PNG_WRITE_PACKSWAP_SUPPORTED - png_set_packswap(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported"); -#endif - - /* Invert the alpha channel from opacity to transparency */ - if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0) -#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED - png_set_invert_alpha(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported"); -#endif - - /* ----------------------- end of transformations ------------------- */ - - /* Write the bits */ - png_write_image(png_ptr, info_ptr->row_pointers); - - /* It is REQUIRED to call this to finish writing the rest of the file */ - png_write_end(png_ptr, info_ptr); - - PNG_UNUSED(params) -} -#endif /* WRITE_PNG */ - - -#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED -/* Initialize the write structure - general purpose utility. */ -static int -png_image_write_init(png_imagep image) -{ - png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image, - png_safe_error, png_safe_warning); - - if (png_ptr != NULL) - { - png_infop info_ptr = png_create_info_struct(png_ptr); - - if (info_ptr != NULL) - { - png_controlp control = png_voidcast(png_controlp, - png_malloc_warn(png_ptr, (sizeof *control))); - - if (control != NULL) - { - memset(control, 0, (sizeof *control)); - - control->png_ptr = png_ptr; - control->info_ptr = info_ptr; - control->for_write = 1; - - image->opaque = control; - return 1; - } - - /* Error clean up */ - png_destroy_info_struct(png_ptr, &info_ptr); - } - - png_destroy_write_struct(&png_ptr, NULL); - } - - return png_image_error(image, "png_image_write_: out of memory"); -} - -/* Arguments to png_image_write_main: */ -typedef struct -{ - /* Arguments: */ - png_imagep image; - png_const_voidp buffer; - ptrdiff_t row_stride; - png_const_voidp colormap; - int convert_to_8bit; - /* Local variables: */ - png_const_voidp first_row; - ptrdiff_t row_bytes; - png_voidp local_row; - /* Byte count for memory writing */ - png_bytep memory; - png_alloc_size_t memory_bytes; /* not used for STDIO */ - png_alloc_size_t output_bytes; /* running total */ -} png_image_write_control; - -/* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to - * do any necessary byte swapping. The component order is defined by the - * png_image format value. - */ -static int -png_write_image_16bit(png_voidp argument) -{ - png_image_write_control *display = png_voidcast(png_image_write_control*, - argument); - png_imagep image = display->image; - png_structrp png_ptr = image->opaque->png_ptr; - - png_const_uint_16p input_row = png_voidcast(png_const_uint_16p, - display->first_row); - png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row); - png_uint_16p row_end; - const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; - int aindex = 0; - png_uint_32 y = image->height; - - if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) - { -# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED - if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0) - { - aindex = -1; - ++input_row; /* To point to the first component */ - ++output_row; - } - - else -# endif - aindex = channels; - } - - else - png_error(png_ptr, "png_write_image: internal call error"); - - /* Work out the output row end and count over this, note that the increment - * above to 'row' means that row_end can actually be beyond the end of the - * row; this is correct. - */ - row_end = output_row + image->width * (channels+1); - - while (y-- > 0) - { - png_const_uint_16p in_ptr = input_row; - png_uint_16p out_ptr = output_row; - - while (out_ptr < row_end) - { - const png_uint_16 alpha = in_ptr[aindex]; - png_uint_32 reciprocal = 0; - int c; - - out_ptr[aindex] = alpha; - - /* Calculate a reciprocal. The correct calculation is simply - * component/alpha*65535 << 15. (I.e. 15 bits of precision); this - * allows correct rounding by adding .5 before the shift. 'reciprocal' - * is only initialized when required. - */ - if (alpha > 0 && alpha < 65535) - reciprocal = ((0xffff<<15)+(alpha>>1))/alpha; - - c = channels; - do /* always at least one channel */ - { - png_uint_16 component = *in_ptr++; - - /* The following gives 65535 for an alpha of 0, which is fine, - * otherwise if 0/0 is represented as some other value there is more - * likely to be a discontinuity which will probably damage - * compression when moving from a fully transparent area to a - * nearly transparent one. (The assumption here is that opaque - * areas tend not to be 0 intensity.) - */ - if (component >= alpha) - component = 65535; - - /* component 0 && alpha < 65535) - { - png_uint_32 calc = component * reciprocal; - calc += 16384; /* round to nearest */ - component = png_check_u16(png_ptr, calc >> 15); - } - - *out_ptr++ = component; - } - while (--c > 0); - - /* Skip to next component (skip the intervening alpha channel) */ - ++in_ptr; - ++out_ptr; - } - - png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row)); - input_row += display->row_bytes/(sizeof (png_uint_16)); - } - - return 1; -} - -/* Given 16-bit input (1 to 4 channels) write 8-bit output. If an alpha channel - * is present it must be removed from the components, the components are then - * written in sRGB encoding. No components are added or removed. - * - * Calculate an alpha reciprocal to reverse pre-multiplication. As above the - * calculation can be done to 15 bits of accuracy; however, the output needs to - * be scaled in the range 0..255*65535, so include that scaling here. - */ -#define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha) - -static png_byte -png_unpremultiply(png_const_structrp png_ptr, png_uint_32 component, - png_uint_32 alpha, png_uint_32 reciprocal/*from the above macro*/) -{ - /* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0 - * is represented as some other value there is more likely to be a - * discontinuity which will probably damage compression when moving from a - * fully transparent area to a nearly transparent one. (The assumption here - * is that opaque areas tend not to be 0 intensity.) - * - * There is a rounding problem here; if alpha is less than 128 it will end up - * as 0 when scaled to 8 bits. To avoid introducing spurious colors into the - * output change for this too. - */ - if (component >= alpha || alpha < 128) - return 255; - - /* component 0) - { - /* The test is that alpha/257 (rounded) is less than 255, the first value - * that becomes 255 is 65407. - * NOTE: this must agree with the PNG_DIV257 macro (which must, therefore, - * be exact!) [Could also test reciprocal != 0] - */ - if (alpha < 65407) - { - component *= reciprocal; - component += 64; /* round to nearest */ - component >>= 7; - } - - else - component *= 255; - - /* Convert the component to sRGB. */ - return PNG_sRGB_FROM_LINEAR(png_ptr, component); - } - - else - return 0; - - PNG_UNUSEDRC(png_ptr) -} - -static int -png_write_image_8bit(png_voidp argument) -{ - png_image_write_control *display = png_voidcast(png_image_write_control*, - argument); - png_imagep image = display->image; - png_structrp png_ptr = image->opaque->png_ptr; - - png_const_uint_16p input_row = png_voidcast(png_const_uint_16p, - display->first_row); - png_bytep output_row = png_voidcast(png_bytep, display->local_row); - png_uint_32 y = image->height; - const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; - - if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - png_bytep row_end; - int aindex; - -# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED - if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0) - { - aindex = -1; - ++input_row; /* To point to the first component */ - ++output_row; - } - - else -# endif - aindex = channels; - - /* Use row_end in place of a loop counter: */ - row_end = output_row + image->width * (channels+1); - - while (y-- > 0) - { - png_const_uint_16p in_ptr = input_row; - png_bytep out_ptr = output_row; - - while (out_ptr < row_end) - { - png_uint_16 alpha = in_ptr[aindex]; - png_byte alphabyte = png_check_byte(png_ptr, PNG_DIV257(alpha)); - png_uint_32 reciprocal = 0; - int c; - - /* Scale and write the alpha channel. */ - out_ptr[aindex] = alphabyte; - - if (alphabyte > 0 && alphabyte < 255) - reciprocal = UNP_RECIPROCAL(alpha); - - c = channels; - do /* always at least one channel */ - *out_ptr++ = png_unpremultiply(png_ptr, *in_ptr++, alpha, - reciprocal); - while (--c > 0); - - /* Skip to next component (skip the intervening alpha channel) */ - ++in_ptr; - ++out_ptr; - } /* while out_ptr < row_end */ - - png_write_row(png_ptr, png_voidcast(png_const_bytep, - display->local_row)); - input_row += display->row_bytes/(sizeof (png_uint_16)); - } /* while y */ - } - - else - { - /* No alpha channel, so the row_end really is the end of the row and it - * is sufficient to loop over the components one by one. - */ - png_bytep row_end = output_row + image->width * channels; - - while (y-- > 0) - { - png_const_uint_16p in_ptr = input_row; - png_bytep out_ptr = output_row; - - while (out_ptr < row_end) - { - png_uint_32 component = *in_ptr++; - - component *= 255; - *out_ptr++ = PNG_sRGB_FROM_LINEAR(png_ptr, component); - } - - png_write_row(png_ptr, output_row); - input_row += display->row_bytes/(sizeof (png_uint_16)); - } - } - - return 1; -} - -static void -png_image_set_PLTE(png_image_write_control *display) -{ - const png_imagep image = display->image; - const void *cmap = display->colormap; - const int entries = image->colormap_entries > 256 ? 256 : - (int)image->colormap_entries; - - /* NOTE: the caller must check for cmap != NULL and entries != 0 */ - const png_uint_32 format = image->format; - const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format); - -# if defined(PNG_FORMAT_BGR_SUPPORTED) &&\ - defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED) - const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 && - (format & PNG_FORMAT_FLAG_ALPHA) != 0; -# else -# define afirst 0 -# endif - -# ifdef PNG_FORMAT_BGR_SUPPORTED - const int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; -# else -# define bgr 0 -# endif - - int i, num_trans; - png_color palette[256]; - png_byte tRNS[256]; - - memset(tRNS, 255, (sizeof tRNS)); - memset(palette, 0, (sizeof palette)); - - for (i=num_trans=0; i= 3) /* RGB */ - { - palette[i].blue = PNG_sRGB_FROM_LINEAR( - display->image->opaque->png_ptr, 255 * entry[(2 ^ bgr)]); - palette[i].green = PNG_sRGB_FROM_LINEAR( - display->image->opaque->png_ptr, 255 * entry[1]); - palette[i].red = PNG_sRGB_FROM_LINEAR( - display->image->opaque->png_ptr, 255 * entry[bgr]); - } - - else /* Gray */ - palette[i].blue = palette[i].red = palette[i].green = - PNG_sRGB_FROM_LINEAR(display->image->opaque->png_ptr, - 255 * *entry); - } - - else /* alpha */ - { - png_uint_16 alpha = entry[afirst ? 0 : channels-1]; - png_byte alphabyte = png_check_byte( - display->image->opaque->png_ptr, PNG_DIV257(alpha)); - png_uint_32 reciprocal = 0; - - /* Calculate a reciprocal, as in the png_write_image_8bit code above - * this is designed to produce a value scaled to 255*65535 when - * divided by 128 (i.e. asr 7). - */ - if (alphabyte > 0 && alphabyte < 255) - reciprocal = (((0xffff*0xff)<<7)+(alpha>>1))/alpha; - - tRNS[i] = alphabyte; - if (alphabyte < 255) - num_trans = i+1; - - if (channels >= 3) /* RGB */ - { - palette[i].blue = png_unpremultiply( - display->image->opaque->png_ptr, entry[afirst + (2 ^ bgr)], - alpha, reciprocal); - palette[i].green = png_unpremultiply( - display->image->opaque->png_ptr, entry[afirst + 1], alpha, - reciprocal); - palette[i].red = png_unpremultiply( - display->image->opaque->png_ptr, entry[afirst + bgr], alpha, - reciprocal); - } - - else /* gray */ - palette[i].blue = palette[i].red = palette[i].green = - png_unpremultiply(display->image->opaque->png_ptr, - entry[afirst], alpha, reciprocal); - } - } - - else /* Color-map has sRGB values */ - { - png_const_bytep entry = png_voidcast(png_const_bytep, cmap); - - entry += i * channels; - - switch (channels) - { - case 4: - tRNS[i] = entry[afirst ? 0 : 3]; - if (tRNS[i] < 255) - num_trans = i+1; - /* FALL THROUGH */ - case 3: - palette[i].blue = entry[afirst + (2 ^ bgr)]; - palette[i].green = entry[afirst + 1]; - palette[i].red = entry[afirst + bgr]; - break; - - case 2: - tRNS[i] = entry[1 ^ afirst]; - if (tRNS[i] < 255) - num_trans = i+1; - /* FALL THROUGH */ - case 1: - palette[i].blue = palette[i].red = palette[i].green = - entry[afirst]; - break; - - default: - break; - } - } - } - -# ifdef afirst -# undef afirst -# endif -# ifdef bgr -# undef bgr -# endif - - png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette, - entries); - - if (num_trans > 0) - png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS, - num_trans, NULL); - - image->colormap_entries = entries; -} - -static int -png_image_write_main(png_voidp argument) -{ - png_image_write_control *display = png_voidcast(png_image_write_control*, - argument); - png_imagep image = display->image; - png_structrp png_ptr = image->opaque->png_ptr; - png_inforp info_ptr = image->opaque->info_ptr; - png_uint_32 format = image->format; - - /* The following four ints are actually booleans */ - int colormap = (format & PNG_FORMAT_FLAG_COLORMAP); - int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */ - int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA); - int write_16bit = linear && !colormap && (display->convert_to_8bit == 0); - -# ifdef PNG_BENIGN_ERRORS_SUPPORTED - /* Make sure we error out on any bad situation */ - png_set_benign_errors(png_ptr, 0/*error*/); -# endif - - /* Default the 'row_stride' parameter if required, also check the row stride - * and total image size to ensure that they are within the system limits. - */ - { - const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); - - /* The test is slightly evil: it assumes that a signed pointer difference - * (ptrdiff_t) can hold a maximum value of half, rounded down, of the - * maximum of a (size_t). This is almost certain to be true. - */ - if (image->width <= (PNG_SIZE_MAX >> 1)/channels) /* no overflow */ - { - png_alloc_size_t check; - const png_alloc_size_t png_row_stride = - (png_alloc_size_t)/*SAFE*/image->width * channels; - - if (display->row_stride == 0) - display->row_stride = (ptrdiff_t)png_row_stride; - - if (display->row_stride < 0) - check = -display->row_stride; - - else - check = display->row_stride; - - if (check >= png_row_stride) - { - /* Now check for overflow of the image buffer calculation; check for - * (size_t) overflow here. This detects issues with the - * PNG_IMAGE_BUFFER_SIZE macro. - */ - if (image->height > PNG_SIZE_MAX/png_row_stride) - png_error(image->opaque->png_ptr, "memory image too large"); - } - - else - png_error(image->opaque->png_ptr, "supplied row stride too small"); - } - - else - png_error(image->opaque->png_ptr, "image row stride too large"); - } - - /* Set the required transforms then write the rows in the correct order. */ - if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0) - { - if (display->colormap != NULL && image->colormap_entries > 0) - { - png_uint_32 entries = image->colormap_entries; - - png_set_IHDR(png_ptr, info_ptr, image->width, image->height, - entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)), - PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - - png_image_set_PLTE(display); - } - - else - png_error(image->opaque->png_ptr, - "no color-map for color-mapped image"); - } - - else - png_set_IHDR(png_ptr, info_ptr, image->width, image->height, - write_16bit ? 16 : 8, - ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) + - ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0), - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - - /* Counter-intuitively the data transformations must be called *after* - * png_write_info, not before as in the read code, but the 'set' functions - * must still be called before. Just set the color space information, never - * write an interlaced image. - */ - - if (write_16bit != 0) - { - /* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */ - png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_LINEAR); - - if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0) - png_set_cHRM_fixed(png_ptr, info_ptr, - /* color x y */ - /* white */ 31270, 32900, - /* red */ 64000, 33000, - /* green */ 30000, 60000, - /* blue */ 15000, 6000 - ); - } - - else if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0) - png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL); - - /* Else writing an 8-bit file and the *colors* aren't sRGB, but the 8-bit - * space must still be gamma encoded. - */ - else - png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE); - - /* Write the file header. */ - png_write_info(png_ptr, info_ptr); - - /* Now set up the data transformations (*after* the header is written), - * remove the handled transformations from the 'format' flags for checking. - * - * First check for a little endian system if writing 16 bit files. - */ - if (write_16bit != 0) - { - PNG_CONST png_uint_16 le = 0x0001; - - if ((*(png_const_bytep) & le) != 0) - png_set_swap(png_ptr); - } - -# ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED - if ((format & PNG_FORMAT_FLAG_BGR) != 0) - { - if (colormap == 0 && (format & PNG_FORMAT_FLAG_COLOR) != 0) - png_set_bgr(png_ptr); - format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_BGR); - } -# endif - -# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED - if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) - { - if (colormap == 0 && (format & PNG_FORMAT_FLAG_ALPHA) != 0) - png_set_swap_alpha(png_ptr); - format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_AFIRST); - } -# endif - - /* If there are 16 or fewer color-map entries we wrote a lower bit depth - * above, but the application data is still byte packed. - */ - if (colormap != 0 && image->colormap_entries <= 16) - png_set_packing(png_ptr); - - /* That should have handled all (both) the transforms. */ - if ((format & PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR | - PNG_FORMAT_FLAG_ALPHA | PNG_FORMAT_FLAG_COLORMAP)) != 0) - png_error(png_ptr, "png_write_image: unsupported transformation"); - - { - png_const_bytep row = png_voidcast(png_const_bytep, display->buffer); - ptrdiff_t row_bytes = display->row_stride; - - if (linear != 0) - row_bytes *= (sizeof (png_uint_16)); - - if (row_bytes < 0) - row += (image->height-1) * (-row_bytes); - - display->first_row = row; - display->row_bytes = row_bytes; - } - - /* Select the right compression mode based on the presence or absence of the - * 'fast' flag. This will use whatever options are available in the libpng - * build. It is always supported. - */ - png_set_compression(png_ptr, (image->flags & PNG_IMAGE_FLAG_FAST) != 0 ? - PNG_COMPRESSION_HIGH_SPEED : PNG_COMPRESSION_HIGH); - - /* Check for the cases that currently require a pre-transform on the row - * before it is written. This only applies when the input is 16-bit and - * either there is an alpha channel or it is converted to 8-bit. - */ - if ((linear != 0 && alpha != 0 ) || - (colormap == 0 && display->convert_to_8bit != 0)) - { - png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr, - png_get_rowbytes(png_ptr, info_ptr))); - int result; - - display->local_row = row; - if (write_16bit != 0) - result = png_safe_execute(image, png_write_image_16bit, display); - else - result = png_safe_execute(image, png_write_image_8bit, display); - display->local_row = NULL; - - png_free(png_ptr, row); - - /* Skip the 'write_end' on error: */ - if (result == 0) - return 0; - } - - /* Otherwise this is the case where the input is in a format currently - * supported by the rest of the libpng write code; call it directly. - */ - else - { - png_const_bytep row = png_voidcast(png_const_bytep, display->first_row); - ptrdiff_t row_bytes = display->row_bytes; - png_uint_32 y = image->height; - - while (y-- > 0) - { - png_write_row(png_ptr, row); - row += row_bytes; - } - } - - png_write_end(png_ptr, info_ptr); - return 1; -} - - -static void (PNGCBAPI -image_memory_write)(png_structp png_ptr, png_bytep/*const*/ data, - png_size_t size) -{ - png_image_write_control *display = png_voidcast(png_image_write_control*, - png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/); - const png_alloc_size_t ob = display->output_bytes; - - /* Check for overflow; this should never happen: */ - if (size <= ((png_alloc_size_t)-1) - ob) - { - /* I don't think libpng ever does this, but just in case: */ - if (size > 0) - { - if (display->memory_bytes >= ob+size) /* writing */ - memcpy(display->memory+ob, data, size); - - /* Always update the size: */ - display->output_bytes = ob+size; - } - } - - else - png_error(png_ptr, "png_image_write_to_memory: PNG too big"); -} - -static void (PNGCBAPI -image_memory_flush)(png_structp png_ptr) -{ - PNG_UNUSED(png_ptr) -} - -static int -png_image_write_memory(png_voidp argument) -{ - png_image_write_control *display = png_voidcast(png_image_write_control*, - argument); - - /* The rest of the memory-specific init and write_main in an error protected - * environment. This case needs to use callbacks for the write operations - * since libpng has no built in support for writing to memory. - */ - png_set_write_fn(display->image->opaque->png_ptr, display/*io_ptr*/, - image_memory_write, image_memory_flush); - - return png_image_write_main(display); -} - -int PNGAPI -png_image_write_to_memory(png_imagep image, void *memory, - png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8bit, - const void *buffer, ptrdiff_t row_stride, const void *colormap) -{ - /* Write the image to the given buffer, or count the bytes if it is NULL */ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - if (memory_bytes != NULL && buffer != NULL) - { - /* This is to give the caller an easier error detection in the NULL - * case and guard against uninitialized variable problems: - */ - if (memory == NULL) - *memory_bytes = 0; - - if (png_image_write_init(image) != 0) - { - png_image_write_control display; - int result; - - memset(&display, 0, (sizeof display)); - display.image = image; - display.buffer = buffer; - display.row_stride = row_stride; - display.colormap = colormap; - display.convert_to_8bit = convert_to_8bit; - display.memory = png_voidcast(png_bytep, memory); - display.memory_bytes = *memory_bytes; - display.output_bytes = 0; - - result = png_safe_execute(image, png_image_write_memory, &display); - png_image_free(image); - - /* write_memory returns true even if we ran out of buffer. */ - if (result) - { - /* On out-of-buffer this function returns '0' but still updates - * memory_bytes: - */ - if (memory != NULL && display.output_bytes > *memory_bytes) - result = 0; - - *memory_bytes = display.output_bytes; - } - - return result; - } - - else - return 0; - } - - else - return png_image_error(image, - "png_image_write_to_memory: invalid argument"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_write_to_memory: incorrect PNG_IMAGE_VERSION"); - - else - return 0; -} - -#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED -int PNGAPI -png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit, - const void *buffer, ptrdiff_t row_stride, const void *colormap) -{ - /* Write the image to the given (FILE*). */ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - if (file != NULL && buffer != NULL) - { - if (png_image_write_init(image) != 0 && - png_image_init_io(image, file) != 0) - { - png_image_write_control display; - int result; - - memset(&display, 0, (sizeof display)); - display.image = image; - display.buffer = buffer; - display.row_stride = row_stride; - display.colormap = colormap; - display.convert_to_8bit = convert_to_8bit; - - result = png_safe_execute(image, png_image_write_main, &display); - png_image_free(image); - return result; - } - - else - return 0; - } - - else - return png_image_error(image, - "png_image_write_to_stdio: invalid argument"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION"); - - else - return 0; -} - -int PNGAPI -png_image_write_to_file(png_imagep image, const char *file_name, - int convert_to_8bit, const void *buffer, ptrdiff_t row_stride, - const void *colormap) -{ - /* Write the image to the named file. */ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - if (file_name != NULL && buffer != NULL) - { - FILE *fp = fopen(file_name, "wb"); - - if (fp != NULL) - { - if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer, - row_stride, colormap) != 0) - { - int error; /* from fflush/fclose */ - - /* Make sure the file is flushed correctly. */ - if (fflush(fp) == 0 && ferror(fp) == 0) - { - if (fclose(fp) == 0) - return 1; - - error = errno; /* from fclose */ - } - - else - { - error = errno; /* from fflush or ferror */ - (void)fclose(fp); - } - - (void)remove(file_name); - /* The image has already been cleaned up; this is just used to - * set the error (because the original write succeeded). - */ - return png_image_error(image, strerror(error)); - } - - else - { - /* Clean up: just the opened file. */ - (void)fclose(fp); - (void)remove(file_name); - return 0; - } - } - - else - return png_image_error(image, strerror(errno)); - } - - else - return png_image_error(image, - "png_image_write_to_file: invalid argument"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_write_to_file: incorrect PNG_IMAGE_VERSION"); - - else - return 0; -} -#endif /* SIMPLIFIED_WRITE_STDIO */ -#endif /* SIMPLIFIED_WRITE */ -#endif /* WRITE */ diff --git a/ext/libpng17/pngwtran.c b/ext/libpng17/pngwtran.c deleted file mode 100644 index 3aaf2205e0..0000000000 --- a/ext/libpng17/pngwtran.c +++ /dev/null @@ -1,148 +0,0 @@ - -/* pngwtran.c - transforms the data in a row for PNG writers - * - * Last changed in libpng 1.7.0 [(PENDING RELEASE)] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" -#define PNG_SRC_FILE PNG_SRC_FILE_pngwtran - -#ifdef PNG_WRITE_PACK_SUPPORTED -/* Pack pixels into bytes. */ -static void -png_do_write_pack(png_transformp *transform, png_transform_controlp tc) -{ - png_alloc_size_t rowbytes = PNG_TC_ROWBYTES(*tc); - png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); - png_const_bytep ep = png_upcast(png_const_bytep, tc->sp) + rowbytes; - png_bytep dp = png_voidcast(png_bytep, tc->dp); - - png_debug(1, "in png_do_pack"); - -# define png_ptr tc->png_ptr - - switch ((*transform)->args) - { - case 1: - { - unsigned int mask = 0x80, v = 0; - - while (sp < ep) - { - if (*sp++ != 0) - v |= mask; - - mask >>= 1; - - if (mask == 0) - { - mask = 0x80; - *dp++ = PNG_BYTE(v); - v = 0; - } - } - - if (mask != 0x80) - *dp++ = PNG_BYTE(v); - break; - } - - case 2: - { - unsigned int shift = 8, v = 0; - - while (sp < ep) - { - shift -= 2; - v |= (*sp++ & 0x3) << shift; - - if (shift == 0) - { - shift = 8; - *dp++ = PNG_BYTE(v); - v = 0; - } - } - - if (shift != 8) - *dp++ = PNG_BYTE(v); - break; - } - - case 4: - { - unsigned int shift = 8, v = 0; - - while (sp < ep) - { - shift -= 4; - v |= ((*sp++ & 0xf) << shift); - - if (shift == 0) - { - shift = 8; - *dp++ = PNG_BYTE(v); - v = 0; - } - } - - if (shift != 8) - *dp++ = PNG_BYTE(v); - break; - } - - default: - impossible("bit depth"); - } - - if ((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0 && - --(tc->range) == 0) - tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_RANGE); - - tc->bit_depth = (*transform)->args; - tc->sp = tc->dp; -# undef png_ptr -} - -void /* PRIVATE */ -png_init_write_pack(png_transformp *transform, png_transform_controlp tc) -{ -# define png_ptr tc->png_ptr - debug(tc->init); -# undef png_ptr - - /* The init routine is called *forward* so the transform control we get has - * the required bit depth and the transform routine will increase it to 8 - * bits per channel. The code doesn't really care how many channels there - * are, but the only way to get a channel depth of less than 8 is to have - * just one channel. - */ - if (tc->bit_depth < 8) /* else no packing/unpacking */ - { - if (tc->init == PNG_TC_INIT_FINAL) - { - (*transform)->fn = png_do_write_pack; - /* Record this for the backwards run: */ - (*transform)->args = tc->bit_depth & 0xf; - } - - if ((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0) - { - tc->range++; - tc->format |= PNG_FORMAT_FLAG_RANGE; /* forwards: backwards cancels */ - } - - tc->bit_depth = 8; - } - - else /* the transform is not applicable */ - (*transform)->fn = NULL; -} -#endif /* WRITE_PACK */ diff --git a/ext/libpng17/pngwutil.c b/ext/libpng17/pngwutil.c deleted file mode 100644 index 19052bfbaa..0000000000 --- a/ext/libpng17/pngwutil.c +++ /dev/null @@ -1,5054 +0,0 @@ -#ifdef _MSC_VER -#pragma warning (disable:4018) -#pragma warning (disable:4028) -#pragma warning (disable:4146) -#pragma warning (disable:4334) -#endif - -/* pngwutil.c - utilities to write a PNG file - * - * Last changed in libpng 1.7.0 [(PENDING RELEASE)] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" -#define PNG_SRC_FILE PNG_SRC_FILE_pngwutil - -#ifdef PNG_WRITE_SUPPORTED - -#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED -/* Place a 32-bit number into a buffer in PNG byte order. We work - * with unsigned numbers for convenience, although one supported - * ancillary chunk uses signed (two's complement) numbers. - */ -void PNGAPI -png_save_uint_32(png_bytep buf, png_uint_32 i) -{ - buf[0] = PNG_BYTE(i >> 24); - buf[1] = PNG_BYTE(i >> 16); - buf[2] = PNG_BYTE(i >> 8); - buf[3] = PNG_BYTE(i); -} - -/* Place a 16-bit number into a buffer in PNG byte order. - * The parameter is declared unsigned int, not png_uint_16, - * just to avoid potential problems on pre-ANSI C compilers. - */ -void PNGAPI -png_save_uint_16(png_bytep buf, unsigned int i) -{ - buf[0] = PNG_BYTE(i >> 8); - buf[1] = PNG_BYTE(i); -} -#endif /* WRITE_INT_FUNCTIONS */ - -/* Simple function to write the signature. If we have already written - * the magic bytes of the signature, or more likely, the PNG stream is - * being embedded into another stream and doesn't need its own signature, - * we should call png_set_sig_bytes() to tell libpng how many of the - * bytes have already been written. - */ -void PNGAPI -png_write_sig(png_structrp png_ptr) -{ - png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; - -#ifdef PNG_IO_STATE_SUPPORTED - /* Inform the I/O callback that the signature is being written */ - png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE; -#endif - - /* Write the rest of the 8 byte signature */ - png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], - (png_size_t)(8 - png_ptr->sig_bytes)); - - if (png_ptr->sig_bytes < 3) - png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; -} - -/* Write the start of a PNG chunk. The type is the chunk type. - * The total_length is the sum of the lengths of all the data you will be - * passing in png_write_chunk_data(). - */ -static void -png_write_chunk_header(png_structrp png_ptr, png_uint_32 chunk_name, - png_uint_32 length) -{ - png_byte buf[8]; - -#if defined(PNG_DEBUG) && (PNG_DEBUG > 0) - PNG_CSTRING_FROM_CHUNK(buf, chunk_name); - png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length); -#endif - - if (png_ptr == NULL) - return; - -#ifdef PNG_IO_STATE_SUPPORTED - /* Inform the I/O callback that the chunk header is being written. - * PNG_IO_CHUNK_HDR requires a single I/O call. - */ - png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR; -#endif - - /* Write the length and the chunk name */ - png_save_uint_32(buf, length); - png_save_uint_32(buf + 4, chunk_name); - png_write_data(png_ptr, buf, 8); - - /* Put the chunk name into png_ptr->chunk_name */ - png_ptr->chunk_name = chunk_name; - - /* Reset the crc and run it over the chunk name */ - png_reset_crc(png_ptr, buf+4); - -#ifdef PNG_IO_STATE_SUPPORTED - /* Inform the I/O callback that chunk data will (possibly) be written. - * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls. - */ - png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA; -#endif -} - -void PNGAPI -png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string, - png_uint_32 length) -{ - png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length); -} - -/* Write the data of a PNG chunk started with png_write_chunk_header(). - * Note that multiple calls to this function are allowed, and that the - * sum of the lengths from these calls *must* add up to the total_length - * given to png_write_chunk_header(). - */ -void PNGAPI -png_write_chunk_data(png_structrp png_ptr, png_const_voidp data, - png_size_t length) -{ - /* Write the data, and run the CRC over it */ - if (png_ptr == NULL) - return; - - if (data != NULL && length > 0) - { - png_write_data(png_ptr, data, length); - - /* Update the CRC after writing the data, - * in case the user I/O routine alters it. - */ - png_calculate_crc(png_ptr, data, length); - } -} - -/* Finish a chunk started with png_write_chunk_header(). */ -void PNGAPI -png_write_chunk_end(png_structrp png_ptr) -{ - png_byte buf[4]; - - if (png_ptr == NULL) return; - -#ifdef PNG_IO_STATE_SUPPORTED - /* Inform the I/O callback that the chunk CRC is being written. - * PNG_IO_CHUNK_CRC requires a single I/O function call. - */ - png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC; -#endif - - /* Write the crc in a single operation */ - png_save_uint_32(buf, png_ptr->crc); - - png_write_data(png_ptr, buf, (png_size_t)4); -} - -/* Write a PNG chunk all at once. The type is an array of ASCII characters - * representing the chunk name. The array must be at least 4 bytes in - * length, and does not need to be null terminated. To be safe, pass the - * pre-defined chunk names here, and if you need a new one, define it - * where the others are defined. The length is the length of the data. - * All the data must be present. If that is not possible, use the - * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() - * functions instead. - */ -static void -png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name, - png_const_voidp data, png_size_t length) -{ - if (png_ptr == NULL) - return; - - /* On 64 bit architectures 'length' may not fit in a png_uint_32. */ - if (length > PNG_UINT_31_MAX) - png_error(png_ptr, "length exceeds PNG maximum"); - - png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)/*SAFE*/length); - png_write_chunk_data(png_ptr, data, length); - png_write_chunk_end(png_ptr); -} - -/* This is the API that calls the internal function above. */ -void PNGAPI -png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string, - png_const_voidp data, png_size_t length) -{ - png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data, - length); -} - -static png_alloc_size_t -png_write_row_buffer_size(png_const_structrp png_ptr) - /* Returns the width of the widest pass in the first row of an interlaced - * image. Passes in the first row are: 0.5.3.5.1.5.3.5, so the widest row is - * normally the one from pass 5. The only exception is if the image is only - * one pixel wide, so: - */ -#define PNG_FIRST_ROW_MAX_WIDTH(w) (w > 1U ? PNG_PASS_COLS(w, 5U) : 1U) - - /* For interlaced images the count of pixels is rounded up to a the number of - * pixels in the first pass (numbered 0). This ensures that passes before - * the last can be packed in the buffer without overflow. - */ -{ - png_alloc_size_t w; - - /* If the image is interlaced adjust 'w' for the interlacing: */ - if (png_ptr->interlaced != PNG_INTERLACE_NONE) - { - /* Take advantage of the fact that 1-row interlaced PNGs require half the - * normal row width: - */ - if (png_ptr->height == 1U) /* no pass 6 */ - w = PNG_FIRST_ROW_MAX_WIDTH(png_ptr->width); - - /* Otherwise round up to a multiple of 8. This may waste a few (less - * than 8) bytes for PNGs with a height less than 57 but this hardly - * matters. - */ - else - w = (png_ptr->width + 7U) & ~7U; - } - - else - w = png_ptr->width; - - /* The rounding above may leave 'w' exactly 2^31 */ - debug(w <= 0x80000000U); - - switch (png_ptr->row_output_pixel_depth) - { - /* This would happen if the function is called before png_write_IHDR. */ - default: NOT_REACHED; return 0; - - case 1: w = (w+7) >> 3; break; - case 2: w = (w+3) >> 2; break; - case 4: w = (w+1) >> 1; break; - case 8: break; - case 16: w <<= 1; break; /* overflow: w is set to 0, which is OK */ - - /* For the remaining cases the answer is w*bytes; where bytes is 3,4,6 - * or 8. This may overflow 32 bits. There is no way to compute the - * result on an arbitrary platform, so test the maximum of a (size_t) - * against w for each possible byte depth: - */ -# define CASE(b)\ - case b*8:\ - if (w <= (PNG_SIZE_MAX/b)/*compile-time constant*/)\ - return w * b;\ - return 0; - - CASE(3) - CASE(4) - CASE(6) - CASE(8) - -# undef CASE - } - - /* This is the low bit depth case. The following can never be false on - * systems with a 32-bit or greater size_t: - */ - if (w <= PNG_SIZE_MAX) - return w; - - return 0U; -} - -/* Release memory used by the deflate mechanism */ -static void -png_deflateEnd(png_const_structrp png_ptr, z_stream *zs, int check) -{ - if (zs->state != NULL) - { - int ret = deflateEnd(zs); - - /* Z_DATA_ERROR means there was pending output. */ - if ((ret != Z_OK && (check || ret != Z_DATA_ERROR)) || zs->state != NULL) - { - png_zstream_error(zs, ret); - - if (check) - png_error(png_ptr, zs->msg); - - else - png_warning(png_ptr, zs->msg); - - zs->state = NULL; - } - } -} - -/* compression_buffer (new in 1.6.0) is just a linked list of temporary buffers. * From 1.6.0 it is retained in png_struct so that it will be correctly freed in - * the event of a write error (previous implementations just leaked memory.) - * - * From 1.7.0 the size is fixed to the same as the (uncompressed) row buffer - * size. This avoids allocating a large chunk of memory when compressing small - * images. This type is also opaque outside this file. - */ -typedef struct png_compression_buffer -{ - struct png_compression_buffer *next; - png_byte output[PNG_ROW_BUFFER_SIZE]; -} png_compression_buffer, *png_compression_bufferp; - -/* png_compression_buffer methods */ -/* Deleting a compression buffer deletes the whole list: */ -static void -png_free_compression_buffer(png_const_structrp png_ptr, - png_compression_bufferp *listp) -{ - png_compression_bufferp list = *listp; - - if (list != NULL) - { - *listp = NULL; - - do - { - png_compression_bufferp next = list->next; - - png_free(png_ptr, list); - list = next; - } - while (list != NULL); - } -} - -/* Return the next compression buffer in the list, allocating it if necessary. - * The caller must update 'end' if required; this just moves down the list. - */ -static png_compression_bufferp -png_get_compression_buffer(png_const_structrp png_ptr, - png_compression_bufferp *end) -{ - png_compression_bufferp next = *end; - - if (next == NULL) - { - next = png_voidcast(png_compression_bufferp, png_malloc_base(png_ptr, - sizeof *next)); - - /* Check for OOM: this is a recoverable error for non-critical chunks, let - * the caller decide what to do rather than issuing a png_error here. - */ - if (next != NULL) - { - next->next = NULL; /* initialize the buffer */ - *end = next; - } - } - - return next; /* may still be NULL on OOM */ -} - -/* This structure is used to hold all the data for zlib compression of a single - * stream of data. It may be re-used, it stores the compressed data internally - * and can handle arbitrary input and output. - * - * 'list' is the output data contained in compression buffers, 'end' points to - * list at the start and is advanced down the compression buffer list (extending - * it as required) as the data is written. If 'end' points into a compression - * buffer (does not point to 'list') that is the buffer in use in - * z_stream::{next,avail}_out. - * - * Compression may be performed in multiple steps, '*end' always points to the - * compression buffer *after* the one that is in use, so 'end' is pointing - * *into* the one in use. - * - * end(on entry) .... end ....... end(on exit) - * | | | - * | | | - * V +----V-----+ +-----V----+ +----------+ - * list ---> | next --+--> | next --+--> | next | - * | output[] | | output[] | | output[] | - * +----------+ +----------+ +----------+ - * [in use] [unused] - * - * These invariants should always hold: - * - * 1) If zs.state is NULL decompression is not in progress, list may be non-NULL - * but end could be anything; - * - * 2) Otherwise if zs.next_out is NULL list will be NULL and end will point at - * list, len, overflow and start will be 0; - * - * 3) Otherwise list is non-NULL and end points at the 'next' element of an - * in-use compression buffer. zs.next_out points into the 'output' element - * of the same buffer. {overflow, len} is the amount of compressed data, len - * being the low 31 bits, overflow being the higher bits. start is used for - * writing and is the index of the first byte in list->output to write, - * {overflow, len} does not include start. - */ -typedef struct -{ - z_stream zs; /* zlib compression data */ - png_compression_bufferp list; /* Head of the buffer list */ - png_compression_bufferp *end; /* Pointer to last 'next' pointer */ - png_uint_32 len; /* Bottom 31 bits of data length */ - unsigned int overflow; /* Top bits of data length */ - unsigned int start; /* Start of data in first block */ -} png_zlib_compress, *png_zlib_compressp; - -/* png_zlib_compress methods */ -/* Initialize the compress structure. The z_stream itself is not initialized, - * however the the 'user' fields are set, including {next,avail}_{in,out}. The - * initialization does not change 'list', however it does set 'end' to point to - * it, effectively truncating the list. - */ -static void -png_zlib_compress_init(png_structrp png_ptr, png_zlib_compressp pz) -{ - /* png_zlib_compress z_stream: */ - pz->zs.zalloc = png_zalloc; - pz->zs.zfree = png_zfree; - /* NOTE: this does not destroy 'restrict' because in all the functions herein - * *png_ptr is only ever accessed via *either* pz->zs.opaque *or* a passed in - * png_ptr. - */ - pz->zs.opaque = png_ptr; - - pz->zs.next_in = NULL; - pz->zs.avail_in = 0U; - pz->zs.total_in = 0U; - - pz->zs.next_out = NULL; - pz->zs.avail_out = 0U; - pz->zs.total_out = 0U; - - pz->zs.msg = PNGZ_MSG_CAST("zlib success"); /* safety */ - - /* pz->list preserved */ - pz->end = &pz->list; - pz->len = 0U; - pz->overflow = 0U; - pz->start = 0U; -} - -/* Return the png_ptr: this is defined here for all the remaining - * png_zlib_compress methods because they are only ever called with zs - * initialized. - */ -#define png_ptr png_voidcast(png_const_structrp, pz->zs.opaque) - -#if PNG_RELEASE_BUILD -# define png_zlib_compress_validate(pz, in_use) ((void)0) -#else /* !RELEASE_BUILD */ -static void -png_zlib_compress_validate(png_zlib_compressp pz, int in_use) -{ - const uInt o_size = sizeof pz->list->output; - - affirm(pz->end != NULL && (in_use || (pz->zs.next_in == NULL && - pz->zs.avail_in == 0U && *pz->end == NULL))); - - if (pz->overflow == 0U && pz->len == 0U && pz->start == 0U) /* empty */ - { - affirm((pz->end == &pz->list && pz->zs.next_out == NULL - && pz->zs.avail_out == 0U) || - (pz->list != NULL && pz->end == &pz->list->next && - pz->zs.next_out == pz->list->output && - pz->zs.avail_out == o_size)); - } - - else /* not empty */ - { - png_compression_bufferp *ep = &pz->list, list; - png_uint_32 o, l; - - affirm(*ep != NULL && pz->zs.next_out != NULL); - - /* Check the list length: */ - o = pz->overflow; - l = pz->len; - affirm((l & 0x80000000U) == 0U && (o & 0x80000000U) == 0U); - - do - { - list = *ep; - l -= o_size; - if (l & 0x80000000U) --o, l &= 0x7FFFFFFFU; - ep = &list->next; - } - while (ep != pz->end); - - l += pz->start; - l += pz->zs.avail_out; - if (l & 0x80000000U) ++o, l &= 0x7FFFFFFFU; - - affirm(o == 0U && l == 0U && pz->zs.next_out >= list->output && - pz->zs.next_out + pz->zs.avail_out == list->output + o_size); - } -} -#endif /* !RELEASE_BUILD */ - -/* Destroy one zlib compress structure. */ -static void -png_zlib_compress_destroy(png_zlib_compressp pz, int check) -{ - /* If the 'opaque' pointer is NULL this png_zlib_compress was never - * initialized, so do nothing. - */ - if (png_ptr != NULL) - { - if (pz->zs.state != NULL) - { - if (check) - png_zlib_compress_validate(pz, 0/*in_use*/); - - png_deflateEnd(png_ptr, &pz->zs, check); - } - - pz->end = &pz->list; /* safety */ - png_free_compression_buffer(png_ptr, &pz->list); - } -} - -/* Ensure that space is available for output, returns the amount of space - * available, 0 on OOM. This updates pz->zs.avail_out (etc) as required. - */ -static uInt -png_zlib_compress_avail_out(png_zlib_compressp pz) -{ - uInt avail_out = pz->zs.avail_out; - - png_zlib_compress_validate(pz, 1/*in_use*/); - - if (avail_out == 0U) - { - png_compression_bufferp next; - - affirm(pz->end == &pz->list || (pz->end != NULL && pz->list != NULL)); - next = png_get_compression_buffer(png_ptr, pz->end); - - if (next != NULL) - { - pz->zs.next_out = next->output; - pz->zs.avail_out = avail_out = sizeof next->output; - pz->end = &next->next; - } - - /* else return 0: OOM */ - } - - else - affirm(pz->end != NULL && pz->list != NULL); - - return avail_out; -} - -/* Compress the given data given an initialized png_zlib_compress structure. - * This may be called multiple times, interleaved with writes as required. - * - * The input data is passed in in pz->zs.next_in, however the length of the data - * is in 'input_len' (to avoid the zlib uInt limit) and pz->zs.avail_in is - * overwritten (and left at 0). - * - * The output information is used and the amount of compressed data is added on - * to pz->{overflow,len}. - * - * If 'limit' is a limit on the amount of data to add to the output (not the - * total amount). The function will retun Z_BUF_ERROR if the limit is reached - * and the function will never produce more (additional) compressed data than - * the limit. - * - * All of zstream::next_in[input] is consumed if a success code is returned - * (Z_OK or Z_STREAM_END if flush is Z_FINISH), otherwise next_in may be used to - * determine how much was compressed. - * - * pz->overflow is not checked for overflow, so if 'limit' is not set overflow - * is possible. The caller must guard against this when supplying a limit of 0. - */ -static int -png_compress( - png_zlib_compressp pz, - png_alloc_size_t input_len, /* Length of data to be compressed */ - png_uint_32 limit, /* Limit on amount of compressed data made */ - int flush) /* Flush parameter at end of input */ -{ - const int unlimited = (limit == 0U); - - /* Sanity checking: */ - affirm(pz->zs.state != NULL && - (pz->zs.next_out == NULL - ? pz->end == &pz->list && pz->len == 0U && pz->overflow == 0U - : pz->list != NULL && pz->end != NULL)); - implies(pz->zs.next_out == NULL, pz->zs.avail_out == 0); - - for (;;) - { - uInt extra; - - /* OUTPUT: make sure some space is available: */ - if (png_zlib_compress_avail_out(pz) == 0U) - return Z_MEM_ERROR; - - /* INPUT: limit the deflate call input to ZLIB_IO_MAX: */ - /* Adjust the input counters: */ - { - uInt avail_in = ZLIB_IO_MAX; - - if (avail_in > input_len) - avail_in = (uInt)/*SAFE*/input_len; - - input_len -= avail_in; - pz->zs.avail_in = avail_in; - } - - if (!unlimited && pz->zs.avail_out > limit) - { - extra = (uInt)/*SAFE*/(pz->zs.avail_out - limit); /* unused bytes */ - pz->zs.avail_out = (uInt)/*SAFE*/limit; - limit = 0U; - } - - else - { - extra = 0U; - limit -= pz->zs.avail_out; /* limit >= 0U */ - } - - pz->len += pz->zs.avail_out; /* maximum that can be produced */ - - /* Compress the data */ - { - int ret = deflate(&pz->zs, input_len > 0U ? Z_NO_FLUSH : flush); - - /* Claw back input data that was not consumed (because avail_in is - * reset above every time round the loop) and correct the output - * length. - */ - input_len += pz->zs.avail_in; - pz->zs.avail_in = 0; /* safety */ - pz->len -= pz->zs.avail_out; - - if (pz->len & 0x80000000U) - ++pz->overflow, pz->len &= 0x7FFFFFFFU; - - limit += pz->zs.avail_out; - pz->zs.avail_out += extra; - - /* Check the error code: */ - switch (ret) - { - case Z_OK: - if (pz->zs.avail_out > extra) - { - /* zlib had output space, so all the input should have been - * consumed: - */ - affirm(input_len == 0U /* else unexpected stop */ && - flush != Z_FINISH/* ret != Z_STREAM_END */); - return Z_OK; - } - - else - { - /* zlib ran out of output space, produce some more. If the - * limit is 0 at this point, however, no more space is - * available. - */ - if (unlimited || limit > 0U) - break; /* Allocate more output */ - - /* No more output space available, but the input may have all - * been consumed. - */ - if (input_len == 0U && flush != Z_FINISH) - return Z_OK; - - /* Input all consumed, but insufficient space to flush the - * output; this is the Z_BUF_ERROR case. - */ - return Z_BUF_ERROR; - } - - case Z_STREAM_END: - affirm(input_len == 0U && flush == Z_FINISH); - return Z_STREAM_END; - - case Z_BUF_ERROR: - /* This means that we are flushing all the output; expect - * avail_out and input_len to be 0. - * - * NOTE: if png_compress is called with input_len 0 and flush set - * to Z_NO_FLUSH this affirm will fire because zlib will have no - * work to do. - */ - affirm(input_len == 0U && pz->zs.avail_out == extra); - /* Allocate another buffer */ - break; - - default: - /* An error */ - return ret; - } - } - } -} - -#undef png_ptr /* remove definition using a png_zlib_compressp */ - -/* All the compression state is held here, it is allocated when required. This - * ensures that the read code doesn't carry the overhead of the much less - * frequently used write stuff. - * - * TODO: make png_create_write_struct allocate this stuff after the main - * png_struct. - */ -struct filter_selector; /* Used only for filter selection */ - -typedef struct png_zlib_state -{ - png_zlib_compress s; /* Primary compression state */ - png_compression_bufferp stash; /* Unused compression buffers */ - -# define ps_png_ptr(ps) png_upcast(png_const_structrp, (ps)->s.zs.opaque) - /* A png_ptr, used below in functions that only have a png_zlib_state. - * NOTE: the png_zlib_compress must have been initialized! - */ - - png_uint_32 zlib_max_pixels; - /* Maximum number of pixels that zlib can handle at once; the lesser of - * the PNG maximum and the maximum that will fit in (uInt)-1 bytes. This - * number of pixels may not be byte aligned. - */ - png_uint_32 zlib_max_aligned_pixels; - /* The maximum number of pixels that zlib can handle while maintaining a - * buffer byte alignment of PNG_ROW_BUFFER_BYTE_ALIGN; <= the previous - * value. - */ - - png_alloc_size_t write_row_size; - /* Size of the PNG row (without the filter byte) in bytes or 0 if it is - * too large to be cached. - */ - -# ifdef PNG_WRITE_FILTER_SUPPORTED - /* During write libpng needs the previous row when writing a new row with - * up, avg or paeth and one or more image rows when performing filter - * selection. So if performing filter selection typically two or more - * rows are required while if no filter selection is to be done only the - * previous row pointer is required. - */ - png_bytep previous_write_row; /* Last row written, if any */ -# ifdef PNG_SELECT_FILTER_SUPPORTED - png_bytep current_write_row; /* Row being written */ - struct filter_selector *selector; /* Data for filter selection */ - png_uint_32 filter_select_window; - /* The number of bytes of uncompressed PNG data which are assumed to - * be relevant when doing filter selection. Limited to 8453377 - * (about 2^23); the maximum number of bytes that can be encoded in - * the largest deflate window. - */ -# define PNG_FILTER_SELECT_WINDOW_MAX 8453377U - png_byte filter_select_threshold; - /* If the number of distinct codes seen in the PNG data are below - * this threshold the PNG data will not be filtered (if the 'none' - * filter is allowed). If this is still true and a particular - * filter does not add new codes that filter will be used. - */ - png_byte filter_select_threshold2; - /* If the number of distinct codes that result by using a particular - * filter is below this second threshold that filter will be used. - * (When multiple filters pass this criterion the lowest numbered - * one producing the lowest number of new codes will be - * chosen.) - */ -# endif /* SELECT_FILTER */ - - unsigned int row_buffer_max_pixels; - /* The maximum number of pixels that can fit in PNG_ROW_BUFFER_SIZE - * bytes; not necessary a whole number of bytes. - */ - unsigned int row_buffer_max_aligned_pixels; - /* The maximum number of pixels that can fit in PNG_ROW_BUFFER_SIZE - * bytes while maintaining PNG_ROW_BUFFER_BYTE_ALIGN alignment. - */ - - unsigned int filter_mask :8; /* mask of filters to consider on NEXT row */ -# define PREVIOUS_ROW_FILTERS\ - (PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH) - unsigned int filters :8; /* Filters for current row */ - unsigned int save_row :2; /* As below: */ -# define SAVE_ROW_UNSET 0U -# define SAVE_ROW_OFF 1U /* Previous-row filters will be ignored */ -# define SAVE_ROW_DEFAULT 2U /* Default to save rows set by libpng */ -# define SAVE_ROW_ON 3U /* Force rows to be saved */ -# define SAVE_ROW(ps) ((ps)->save_row >= SAVE_ROW_DEFAULT) -# endif /* WRITE_FILTER */ - - /* Compression settings: see below for how these are encoded. */ - png_uint_32 pz_IDAT; /* Settings for the image */ - png_uint_32 pz_iCCP; /* Settings for iCCP chunks */ - png_uint_32 pz_text; /* Settings for text chunks */ - png_uint_32 pz_current; /* Last set settings */ - -# ifdef PNG_WRITE_FLUSH_SUPPORTED - png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */ - png_uint_32 flush_rows; /* number of rows written since last flush */ -# endif /* WRITE_FLUSH */ -} png_zlib_state; - -/* Create the zlib state: */ -static void -png_create_zlib_state(png_structrp png_ptr) -{ - png_zlib_statep ps = png_voidcast(png_zlib_state*, - png_malloc(png_ptr, sizeof *ps)); - - /* Clear to NULL/0: */ - memset(ps, 0, sizeof *ps); - - debug(png_ptr->zlib_state == NULL); - png_ptr->zlib_state = ps; - png_zlib_compress_init(png_ptr, &ps->s); - -# ifdef PNG_WRITE_FILTER_SUPPORTED - ps->previous_write_row = NULL; -# ifdef PNG_SELECT_FILTER_SUPPORTED - ps->current_write_row = NULL; - ps->selector = NULL; -# endif /* SELECT_FILTER */ -# endif /* WRITE_FILTER */ -# ifdef PNG_WRITE_FLUSH_SUPPORTED - /* Set this to prevent flushing by making it larger than the number - * of rows in the largest interlaced PNG; PNG_UINT_31_MAX times - * (1/8+1/8+1/8+1/4+1/4+1/2+1/2); 1.875, or 15/8 - */ - ps->flush_dist = 0xEFFFFFFFU; -# endif /* WRITE_FLUSH */ -} - -static void -png_zlib_state_set_buffer_limits(png_const_structrp png_ptr, png_zlib_statep ps) - /* Delayed initialization of the zlib state maxima; this is not done above in - * case the zlib_state is created before the IHDR has been written, which - * would lead to the various png_struct fields used below being - * uninitialized. - */ -{ - /* Initialization of the buffer size constants. */ - const unsigned int bpp = PNG_PIXEL_DEPTH(*png_ptr); - const unsigned int byte_pp = bpp >> 3; /* May be 0 */ - const unsigned int pixel_block = - /* Number of pixels required to maintain PNG_ROW_BUFFER_BYTE_ALIGN - * alignment. For multi-byte pixels use the first set bit to determine - * if the pixels have a greater alignment already. - */ - bpp < 8U ? - PNG_ROW_BUFFER_BYTE_ALIGN * (8U/bpp) : - PNG_ROW_BUFFER_BYTE_ALIGN <= (byte_pp & -byte_pp) ? - 1U : - PNG_ROW_BUFFER_BYTE_ALIGN / (byte_pp & -byte_pp); - - /* pixel_block must always be a power of two: */ - debug(bpp > 0 && pixel_block > 0 && - (pixel_block & -pixel_block) == pixel_block && - ((8U*PNG_ROW_BUFFER_BYTE_ALIGN-1U) & (pixel_block*bpp)) == 0U); - - /* Zlib maxima */ - { - png_uint_32 max = (uInt)-1; /* max bytes */ - - if (bpp <= 8U) - { - /* Maximum number of bytes PNG can generate in the lower bit depth - * cases: - */ - png_uint_32 png_max = - (0x7FFFFFFF + PNG_ADDOF(bpp)) >> PNG_SHIFTOF(bpp); - - if (png_max < max) - max = 0x7FFFFFFF; - } - - else /* bpp > 8U */ - { - max /= byte_pp; - if (max > 0x7FFFFFFF) - max = 0x7FFFFFFF; - } - - /* So this is the maximum number of pixels regardless of alignment: */ - ps->zlib_max_pixels = max; - - /* For byte alignment the value has to be a multiple of pixel_block and - * that is a power of 2, so: - */ - ps->zlib_max_aligned_pixels = max & ~(pixel_block-1U); - } - -# ifdef PNG_WRITE_FILTER_SUPPORTED - /* PNG_ROW_BUFFER maxima; this is easier because PNG_ROW_BUFFER_SIZE is - * limited so that the number of bits fits in any ANSI-C (unsigned int). - */ - { - const unsigned int max = (8U * PNG_ROW_BUFFER_SIZE) / bpp; - - ps->row_buffer_max_pixels = max; - ps->row_buffer_max_aligned_pixels = max & ~(pixel_block-1U); - } -# endif /* WRITE_FILTER */ - - /* NOTE: this will be 0 for very long rows on 32-bit or less systems */ - ps->write_row_size = png_write_row_buffer_size(png_ptr); -} - -static png_zlib_statep -get_zlib_state(png_structrp png_ptr) -{ - if (png_ptr->zlib_state == NULL) - png_create_zlib_state(png_ptr); - - return png_ptr->zlib_state; -} - -/* Internal API to clean up all the deflate related stuff, including the buffer - * lists. - */ -static void /* PRIVATE */ -png_deflate_release(png_structrp png_ptr, png_zlib_statep ps, int check) -{ -# ifdef PNG_WRITE_FILTER_SUPPORTED - /* Free any mode-specific data that is owned here: */ - if (ps->previous_write_row != NULL) - { - png_bytep p = ps->previous_write_row; - ps->previous_write_row = NULL; - png_free(png_ptr, p); - } - -# ifdef PNG_SELECT_FILTER_SUPPORTED - if (ps->current_write_row != NULL) - { - png_bytep p = ps->current_write_row; - ps->current_write_row = NULL; - png_free(png_ptr, p); - } - - if (ps->selector != NULL) - { - struct filter_selector *s = ps->selector; - ps->selector = NULL; - png_free(png_ptr, s); - } -# endif /* SELECT_FILTER */ -# endif /* WRITE_FILTER */ - - /* The main z_stream opaque pointer needs to remain set to png_ptr; it is - * only set once. - */ - png_zlib_compress_destroy(&ps->s, check); - png_free_compression_buffer(png_ptr, &ps->stash); -} - -void /* PRIVATE */ -png_deflate_destroy(png_structrp png_ptr) -{ - png_zlib_statep ps = png_ptr->zlib_state; - - if (ps != NULL) - { - png_deflate_release(png_ptr, ps, 0/*check*/); - png_ptr->zlib_state = NULL; - png_free(png_ptr, ps); - } -} - -/* Compression settings. - * - * These are stored packed into a png_uint_32 to make comparison with the - * current setting quick. The packing method uses four bits for each setting - * and reserves '0' for unset. - * - * ps__base: The lowest valid value (encoded as 1). - * ps__max: The highest valid value. - * ps__pos: The position in the range 0..3 (shift of 0..12). - * - * The low 16 bits are the zlib compression parameters: - */ -#define pz_level_base (-1) -#define pz_level_max 9 -#define pz_level_pos 0 -#define pz_windowBits_base 8 -#define pz_windowBits_max 15 -#define pz_windowBits_pos 1 -#define pz_memLevel_base 1 -#define pz_memLevel_max 9 -#define pz_memLevel_pos 2 -#define pz_strategy_base 0 -#define pz_strategy_max 4 -#define pz_strategy_pos 3 -#define pz_zlib_bits 0xFFFFU -/* Anything below this is not used directly by zlib: */ -#define pz_png_level_base 0 -#define pz_png_level_max 6 -#define pz_png_level_pos 4 - -#define pz_offset(name) (pz_ ## name ## _base - 1) - /* setting_value == pz_offset(setting)+encoded_value */ -#define pz_min(name) pz_ ## name ## _base -#define pz_max(name) pz_ ## name ## _max -#define pz_shift(name) (4 * pz_ ## name ## _pos) - -#define pz_bits(name,x) ((int)(((x)>>pz_shift(name))&0xF)) - /* the encoded value, or 0 if unset */ - -/* Enquiries: */ -#define pz_isset(name,x) (pz_bits(name,x) != 0) -#define pz_value(name,x) (pz_bits(name,x)+pz_offset(name)) - -/* Assignments: */ -#define pz_clear(name,x) ((x)&~((png_uint_32)0xFU<pz_ ## type) -#define pz_get(ps, type, name, def)\ - (pz_isset(name, pz_var(ps, type)) ? pz_value(name, pz_var(ps, type)) : (def)) -/* pz_assign checks for out-of-range values and clears the setting if these are - * given. No warning or error is generated. - */ -#define pz_assign(ps, type, name, value)\ - (pz_var(ps, type) = pz_clear(name, pz_var(ps, type)) |\ - ((value) >= pz_min(name) && (value) <= pz_max(name) ?\ - pz_encode(name, value) : 0)) - -static png_int_32 -pz_compression_setting(png_structrp png_ptr, png_uint_32 owner, - int min, int max, int shift, png_int_32 value, int only_get, int unset) - /* This is a support function for png_write_setting below. */ -{ - png_zlib_statep ps; - png_uint_32p psettings; - - /* The value is only required for a 'set', eliminate out-of-range values - * first: - */ - if (!only_get && (value < min || value > max)) - return PNG_EDOM; - - /* If setting a value make sure the state exists: */ - if (!only_get) - ps = get_zlib_state(png_ptr); - - else if (owner != 0U) /* ps may be NULL */ - ps = png_ptr->zlib_state; - - else /* get and owner is 0U */ - return 0; /* supported */ - - psettings = NULL; - switch (owner) - { - png_int_32 res; - - case png_IDAT: - if (ps != NULL) psettings = &ps->pz_IDAT; - break; - - case png_iCCP: - if (ps != NULL) psettings = &ps->pz_iCCP; - break; - - case 0U: - /* All the settings. At this point the 'get' case has returned 0 - * above, the value has been checked and the paramter is 0, therefore - * valid. Each of the following calls should succeed and it would be - * reasonable to eliminate the PNG_FAILED tests in a world where - * software engineers never made mistakes. - */ - res = pz_compression_setting(png_ptr, png_IDAT, min, max, shift, - value, 0/*set*/, 1/*iff unset*/); - - if (PNG_FAILED(res)) - return res; - - res = pz_compression_setting(png_ptr, png_iCCP, min, max, shift, - value, 0/*set*/, 1/*iff unset*/); - - if (PNG_FAILED(res)) - return res; - - /* The text settings are changed regardless of the customize support - * because if WRITE_CUSTOMIZE_ZTXT_COMPRESSION is not supported the old - * behavior was to use the WRITE_CUSTOMIZE_COMPRESSION setting. - * - * However, when we get png_zTXt directly (from png_write_setting) and - * the support is not compiled in return PNG_ENOSYS. - */ - unset = 1; /* i.e. only if not already set */ - -# ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED - case png_zTXt: - case png_iTXt: -# endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */ - if (ps != NULL) psettings = &ps->pz_text; - break; - - default: - /* Return PNG_ENOSYS, not PNG_EINVAL, to support future addition of new - * compressed chunks and the fact that zTXt and iTXt customization can - * be disabled. - */ - return PNG_ENOSYS; - } - - if (psettings == NULL) - return PNG_UNSET; /* valid setting that is not set */ - - { - png_uint_32 settings = *psettings; - png_uint_32 mask = 0xFU << shift; - - /* Do not set it if 'only_get' was passed in or if 'unset' is true and the - * setting is not currently set: - */ - if (!only_get && ((settings & mask) == 0U || !unset)) - *psettings = (settings & ~mask) + - ((png_uint_32)/*SAFE*/(value-min+1) << shift); - - settings &= mask; - - if (settings == 0U) - return PNG_UNSET; - - else - return (int)/*SAFE*/((settings >> shift)-1U) + min; - } -} - -#define compression_setting(pp, owner, setting, value, get)\ - pz_compression_setting(pp, owner, pz_min(setting), pz_max(setting),\ - pz_shift(setting), value, get, 0/*always*/) - -/* There is (as of zlib 1.2.8) a bug in the implementation of compression with a - * window size of 256 which zlib works round by resetting windowBits from 8 to 9 - * whenever deflateInit2 is called with that value. Fix this up here. - */ -static void -fix_cinfo(png_zlib_statep ps, png_bytep data, png_alloc_size_t data_size) -{ - /* Do this if the CINFO field is '1', meaning windowBits of 9. The first - * byte of the stream is the CMF value, CINFO is in the upper four bits. - * - * If zlib didn't futz with the value then it should match the value in - * pz_current; check this is debug. (See below for why this works in the - * pz_default_settings call.) - */ -# define png_ptr png_voidcast(png_const_structrp, ps->s.zs.opaque) - if (data[0] == 0x18U && - pz_get(ps, current, windowBits, 0) == 8 /* i.e. it was requested */) - { - /* Double check this here; the fixup only works if the data was 256 bytes - * or shorter *or* the window is never used. For safety repeat the checks - * done in pz_default_settings; technically we should be able to just skip - * this test. - * - * TODO: set a 'fixup' flag in zlib_state to make this quicker? - */ - if (data_size <= 256U || - pz_get(ps, current, strategy, Z_RLE) == Z_HUFFMAN_ONLY || - pz_get(ps, current, level, 1) == Z_NO_COMPRESSION) - { - unsigned int d1; - - data[0] = 0x08U; - /* The header checksum must be fixed too. The FCHECK (low 5 bits) make - * CMF.FLG a multiple of 31: - */ - d1 = data[1] & 0xE0U; /* top three bits */ - d1 += 31U - (0x0800U + d1) % 31U; - data[1] = PNG_BYTE(d1); - } - - else /* pz_default_settings is expected to guarantee the above */ - NOT_REACHED; - } - - else if (data_size > 0U) - { - /* Prior to 1.7.0 libpng would shrink the windowBits even if the - * application requested a particular value, so: - */ - unsigned int z_cinfo = data[0] >> 4; - unsigned int half_z_window_size = 1U << (z_cinfo + 7); - - if (data_size <= half_z_window_size && z_cinfo > 0) - { - unsigned int tmp; - - do - { - half_z_window_size >>= 1; - --z_cinfo; - } - while (z_cinfo > 0 && data_size <= half_z_window_size); - - data[0] = PNG_BYTE((z_cinfo << 4) + 0x8U); - tmp = data[1] & 0xE0U; /* top three bits */ - tmp += 31U - ((data[0] << 8) + tmp) % 31U; - data[1] = PNG_BYTE(tmp); - } - } - - else - NOT_REACHED; /* invalid data size (0) */ -# undef png_ptr -} - -static png_uint_32 -pz_default_settings(png_uint_32 settings, const png_uint_32 owner, - const png_alloc_size_t data_size, const unsigned int filters/*for IDAT*/) -{ - int png_level, strategy, zlib_level, windowBits; - - /* The png 'level' parameter controls the defaults below. It uses the same - * numbering scheme as the Zlib compression level except that -1 invokes the - * set of options and, in some cases, libpng behavior of libpng 1.6 and - * earlier. - * - * In the comments below reference is made to the differences beteen the - * legacy compression sizes from libpng 1.6 and earlier and the result of - * using the various options. These are quoted as an overall size change in - * the compression of 147323 PNG test files. The set of test files is - * slightly restricted because pre-1.7 versions of png_read_png leave random - * bits into the final byte of a row which ends with a partial byte. This - * affects the compression unpredictably so such files were omitted from the - * measurements. - */ - if (!pz_isset(png_level, settings)) - { - png_level = PNG_DEFAULT_COMPRESSION_LEVEL; - settings |= pz_encode(png_level, png_level); - } - - else - png_level = pz_value(png_level, settings); - - /* First default the strategy. At lower data sizes other strategies do as - * well as the zlib default compression strategy but they never seem to - * improve on it with the 1.7 filtering. - */ - if (!pz_isset(strategy, settings)) - { - switch (png_level) - { - case PNG_COMPRESSION_COMPAT: /* Legacy setting */ - /* The pre-1.7 code used Z_FILTERED normally but uses - * Z_DEFAULT_STRATEGY for palette or low-bit-depth images. - * - * In fact Z_DEFAULT_STRATEGY works best for filtered images as - * well, however the change in results is small: - * - * Z_DEFAULT_STRATEGY: -0.1% - * Z_FILTERED: +0.1% - * - * NOTE: this happened even if WRITE_FILTER was *not* supported. - */ - if (owner != png_IDAT || filters == PNG_FILTER_NONE) - strategy = Z_DEFAULT_STRATEGY; - - else - strategy = Z_FILTERED; - break; - - case PNG_COMPRESSION_HIGH_SPEED: - /* RLE is as fast as HUFFMAN_ONLY and can reduce size a lot in a few - * cases. - */ - strategy = Z_RLE; - break; - - default: /* For GCC */ - case PNG_COMPRESSION_LOW: - case PNG_COMPRESSION_MEDIUM: - /* Z_FILTERED is almost as good as the default and can be - * significantly faster. It biases the algorithm towards smaller - * byte values. - * - * Using Z_DEFAULT_STRATEGY here, rather than Z_FILTERED, benefits - * smaller 8 and 16-bit gray and larger 8 and 16-bit RGB images, - * however the overall gain is only 0.1% because it is offset by - * losses in larger 8-bit gray and alpha images. It is extremely - * difficult to deduce a pattern other than biases in the test set - * of images. - * - * Looking at the pattern of behavior with the 1.6 filter selection - * algorithm (none of palette or low-bit-depth, else all) produces - * results as follows: - */ - if (owner == png_IDAT) - { - if (filters == PNG_FILTER_NONE) - strategy = Z_DEFAULT_STRATEGY; - - else - strategy = Z_FILTERED; - } - - else if (owner == png_iCCP) - strategy = Z_DEFAULT_STRATEGY; - - /* TODO: investigate this, the observed behavior is suspicious: */ - else /* text chunk */ - strategy = Z_FILTERED; /* Always better for some reason */ - break; - - case PNG_COMPRESSION_LOW_MEMORY: - /* Reduce memory at all costs, speed doesn't matter. */ - case PNG_COMPRESSION_HIGH_READ_SPEED: - case PNG_COMPRESSION_HIGH: - if (owner == png_IDAT || owner == png_iCCP) - strategy = Z_DEFAULT_STRATEGY; - - else - strategy = Z_FILTERED; - break; - } - - settings |= pz_encode(strategy, strategy); - } - - else - strategy = pz_value(strategy, settings); - - /* Next the zlib level; this just defaults to the png level, except that for - * Huffman or RLE encoding the level setting for Zlib doesn't matter. - */ - if (!pz_isset(level, settings)) - { - switch (strategy) - { - case Z_HUFFMAN_ONLY: - case Z_RLE: - /* The 'level' doesn't make any significant difference to the - * compression with these strategies; in a test set of about 3GByte - * of PNG files the total compressed size changed under 20 bytes - * with libpng 1.6! - */ - zlib_level = 1; - break; - - default: /* Z_FIXED, Z_FILTERED, Z_DEFAULT_STRATEGY */ - /* Everything that uses the window seems to show rapidly diminishing - * returns above level 6 (at least with libpng 1.6). - * Z_DEFAULT_COMPRESSION is, in fact, level 6 so Mark seems to - * concur. With libpng 1.6 the following results were obtained - * using the full test set of files (including those with a partial - * byte at the end of the row) and just varying the zlib level: - * - * LEVEL SIZE(bytes) CHANGE TIME(s) CHANGE METRIC - * 9 2550246600 -1.19% 1972 +227% -77% - * 8 2556675866 -0.94% 1215 +101% -59% - * 7 2572685552 -0.32% 679 +12% -15% - * 6 2581196708 0% 604 0% 0% - * 5 2602831249 +0.84% 414 -30% +87% - * 4 2625206800 +1.71% 358 -40% +153% - * 3 2674752349 +3.62% 298 -50% +303% - * 2 2716261483 +5.23% 262 -56% +537% - * 1 2749875805 +6.53% 251 -57% +662% - * 0 7174488347 202 -66% - * - * The CHANGE columns express the change in compressed size - * (positive is an increase; a decrease in compression) and time - * (positive is an increase; an increase in time) relative to level - * 6. The METRIC column is a measure of the compression-per-second - * relative to level 6; positive is an increase in - * compression-per-second. - * - * The metric is derived by assuming the difference in time between - * level 0 (which does no compression) and the level being - * considered is spent doing the compression. (Reasonable, since - * only the level changed). Just the inverse of the product of the - * size and the time difference is a measure of compression per - * second. It can be seen that time dominates the metric; - * compression only varies slightly (under 8%) across the level - * range. - */ - switch (png_level) - { - case PNG_COMPRESSION_COMPAT: - zlib_level = Z_DEFAULT_COMPRESSION; /* NOTE: -1 */ - break; - - case PNG_COMPRESSION_HIGH_SPEED: - zlib_level = 1; - break; - - default: /* For GCC */ - case PNG_COMPRESSION_LOW: - zlib_level = 3; - break; - - case PNG_COMPRESSION_MEDIUM: - zlib_level = 6; /* Old default! */ - break; - - case PNG_COMPRESSION_LOW_MEMORY: - case PNG_COMPRESSION_HIGH_READ_SPEED: - case PNG_COMPRESSION_HIGH: - zlib_level = 9; - break; - } - break; - } - - settings |= pz_encode(level, zlib_level); - } - - else - zlib_level = pz_value(level, settings); - - /* Now default windowBits. This is probably the most important of the - * settings because it is pretty much the only one that affects decode - * performance. The smaller the better: - */ - if (!pz_isset(windowBits, settings)) - { - if (png_level == PNG_COMPRESSION_COMPAT/* Legacy */) - { - /* This is the libpng16 calculation (it is wrong; a misunderstanding of - * what zlib actually requires!) - * - * Using the code below with the legacy choice of Z_FILTERED or - * Z_DEFAULT_STRATEGY increases the size of the test files by only - * 0.04%, however the settings below considerably reduce the windowBits - * used potentially benefitting read code a lot. - * - * NOTE: the algorithm below was determined by experiment and - * observation with the same set of test files; there is some - * considerable possibility that a different set might show different - * results. Obtaining large, representative, test sets is both a - * considerable amount of work and very error prone. [JB 20160518] - */ - windowBits = 15; - - if (data_size <= 16384U) - { - unsigned int half_window_size = 1U << (windowBits-1); - - while (data_size + 262U <= half_window_size) - { - half_window_size >>= 1; - --windowBits; - } - } - } - - /* The window size affects the memory used on both read and write but also - * the time on write (but not normally read). Handle the low memory - * requirement first: - */ - else if (zlib_level == Z_NO_COMPRESSION || - png_level == PNG_COMPRESSION_LOW_MEMORY) - windowBits = 8; - - /* If the strategy has been set to something that doesn't benefit from - * higher windowBits values take advantage of this. Note that pz_value - * returns an invalid value if pz_isset is false. - * - * The only png_level that affects this decision is HIGH_SPEED, because - * a smaller windowBits should speed up the search, however the code above - * chose zlib_level based on this so ignore that consideration and just - * use zlib_level below. - */ - else switch (strategy) - { - png_alloc_size_t test_size; - - case Z_HUFFMAN_ONLY: - /* Use the minimum; the window doesn't get used */ - windowBits = 8; - break; - - case Z_RLE: - /* The longest length code is 258 bytes, the shortest string that - * can achieve this is 259 bytes long; 259 copies of the same byte - * which can be encoded as a code for the byte value then a string - * of length 258 starting at the first byte. So if the data is - * longer than 256 bytes use '9' for the windowBits, otherwise use - * 8: - */ - if (data_size <= 256U) - windowBits = 8; - - else - windowBits = 9; - break; - - /* By experiment using about 150,000 files the optimal windowBits - * value across a range of files is somewhat less than implied by - * the data size and depends on the zlib level and the strategy - * used, the following values were determined by experiment using - * those files: - */ - case Z_FILTERED: - /* The Z_FILTERED case changes suddenly at (zlib) level 4 to - * benefit from looking at all the data: - */ - if (zlib_level < 4 && zlib_level != Z_DEFAULT_COMPRESSION/*-1: 6*/) - test_size = data_size / 8U; - - else - test_size = data_size; - - goto check_test_size; - - case Z_FIXED: - /* With the fixed Huffman tables better compression only ever comes - * from looking for matches, so, logically: - */ - test_size = data_size; - goto check_test_size; - - default: - /* The default algorithm always does better with a window smaller - * than all the data and shows jumps at level 4 and level 8. The - * net effect with the test set of images is a very minor overall - * improvement compared to the pre-1.7 calculation (data size + - * 262). The benefit is less than 0.01%, however smaller window - * sizes reduce the memory zlib has to allocate in the decoder. - */ - switch (zlib_level) - { - case 1: case 2: case 3: - test_size = data_size / 8U; - break; - - default: /* -1(Z_DEFAULT_COMPRESSION) == 6, 4..7 */ - /* This includes, implicitly, ZLIB_NO_COMPRESSION, but that - * was eliminated in the 'if' above. - */ - test_size = data_size / 4U; - break; - - case 8: case 9: - test_size = data_size / 3U; - break; - } - - goto check_test_size; - - check_test_size: - /* Find the smallest window that covers 'test_size' bytes, subject - * to the constraint that if the actual data size is more than 256 - * bytes the minimum windowBits that can be supported is 9: - */ - if (data_size <= 256U) - windowBits = 8; - - else - windowBits = 9; - - while (windowBits < 15 && (1U << windowBits) < test_size) - ++windowBits; - - break; - } - - settings |= pz_encode(windowBits, windowBits); - } - - else - windowBits = pz_value(windowBits, settings); - - /* zlib has a problem with 256 byte windows; 512 is used instead. - * We can't work round this if the data size is more than 256 bytes and - * the strategy actually uses the window (everything except huffman-only) - * so fix the problem here. - */ - if (windowBits == 8 && data_size > 256U && strategy != Z_HUFFMAN_ONLY && - zlib_level != Z_NO_COMPRESSION) - settings = pz_change(windowBits, settings, 9); - - /* For memLevel this just increases the memory used but can help with the - * Huffman code generation even to level 9 (the maximum), so just set the - * max. This affects memory used, not (apparently) compression speed so - * the only relevant png_level is LOW_MEMORY. - * - * The legacy setting is '8'; this is the level that Zlib defaults to because - * 16-bit iAPX86 systems could not handle '9'. Because MAX_MEM_LEVEL is used - * below this does not matter; zconf.h selects 8 or 9 as appropriate. - * - * In fact using '9' with the legacy settings increases the size of the test - * set minutely; +0.007%. This is hardly significant; 0.007% of the test - * images equals 10 images. (Nevertheless it is interesting, just as the - * observation that decreasing windowBits can result in smaller compressed - * sizes is interesting.) - */ - if (!pz_isset(memLevel, settings)) - { - int memLevel; - - switch (png_level) - { - case PNG_COMPRESSION_COMPAT: - memLevel = 8; - break; - - case PNG_COMPRESSION_LOW_MEMORY: - memLevel = 1; - break; - - default: - memLevel = MAX_MEM_LEVEL/*from zconf.h*/; - break; - } - - settings |= pz_encode(memLevel, memLevel); - } - - return settings; -} - -/* This is used below to find the size of an image to pass to png_deflate_claim. - * It returns 0 for images whose size would overflow a 32-bit integer or have - * rows which cannot be allocated. - */ -static png_alloc_size_t -png_image_size(png_const_structrp png_ptr) -{ - /* The size returned here is limited to PNG_SIZE_MAX, if the size would - * exceed that (or is close to exceeding that) 0 is returned. See below for - * a variant that limits the size of 0xFFFFFFFFU. - */ - const png_alloc_size_t rowbytes = png_ptr->zlib_state->write_row_size; - - /* NON-INTERLACED: (1+rowbytes) * h - * INTERLACED: Each pixel is transmitted exactly once, so the size is - * (rowbytes * h) + the count of filter bytes. Each complete - * block of 8 image rows generates at most 15 output rows - * (less for narrow images), so the filter byte count is - * at most (15*h/8)+14. Because the original rows are split - * extra byte passing may be introduced. Account for this by - * allowing an extra 1 byte per output row; that's two bytes - * including the filer byte. - * - * So: - * NON-INTERLACED: (rowbytes * h) + h - * INTERLACED: < (rowbytes * h) + 2*(15 * h/8) + 2*15 - * - * Hence: - */ - if (rowbytes != 0) - { - const png_uint_32 h = png_ptr->height; - - if (png_ptr->interlaced == PNG_INTERLACE_NONE) - { - const png_alloc_size_t limit = PNG_SIZE_MAX / h; - - /* On 16-bit systems the above might be 0, so: */ - if (rowbytes width; - - /* Interlacing makes the image larger because of the replication of - * both the filter byte and the padding to a byte boundary. - */ - png_alloc_size_t cb_base; - int pass; - - for (cb_base=0, pass=0; pass 0) - { - const png_uint_32 pass_h = PNG_PASS_ROWS(h, pass); - - if (pass_h > 0) - { - /* This is the number of bytes available for each row of this - * pass: - */ - const png_alloc_size_t limit = (PNG_SIZE_MAX - cb_base)/pass_h; - /* This cannot overflow because if it did rowbytes would - * have been 0 above. - */ - const png_alloc_size_t pass_bytes = - PNG_ROWBYTES(png_ptr->row_output_pixel_depth, pass_w); - - if (pass_bytes zowner == 0); - - { - int ret; /* zlib return code */ - unsigned int filters = 0U; - png_uint_32 settings; - - switch (owner) - { - case png_IDAT: - debug(data_size == 0U); - data_size = png_image_size(png_ptr); - - if (data_size == 0U) - data_size = PNG_SIZE_MAX; - - settings = ps->pz_IDAT; -# ifdef PNG_WRITE_FILTER_SUPPORTED - filters = ps->filter_mask; - debug(filters != 0U); -# else /* !WRITE_FILTER */ - filters = PNG_FILTER_NONE; -# endif /* !WRITE_FILTER */ - break; - - case png_iCCP: - settings = ps->pz_iCCP; - break; - - default: /* text chunk */ - settings = ps->pz_text; - break; - } - - settings = pz_default_settings(settings, owner, data_size, filters); - - /* Check against the previous initialized values, if any. The relevant - * settings are in the low 16 bits. - */ - if (ps->s.zs.state != NULL && - ((settings ^ ps->pz_current) & pz_zlib_bits) != 0U) - png_deflateEnd(png_ptr, &ps->s.zs, 0/*check*/); - - /* For safety clear out the input and output pointers (currently zlib - * doesn't use them on Init, but it might in the future). - */ - ps->s.zs.next_in = NULL; - ps->s.zs.avail_in = 0; - ps->s.zs.next_out = NULL; - ps->s.zs.avail_out = 0; - - /* The length fields must be cleared too and the lists reset: */ - ps->s.overflow = ps->s.len = ps->s.start = 0U; - - if (ps->s.list != NULL) /* error in prior chunk writing */ - { - debug(ps->stash == NULL); - ps->stash = ps->s.list; - ps->s.list = NULL; - } - - ps->s.end = &ps->s.list; - - /* Now initialize if required, setting the new parameters, otherwise just - * do a simple reset to the previous parameters. - */ - if (ps->s.zs.state != NULL) - ret = deflateReset(&ps->s.zs); - - else - ret = deflateInit2(&ps->s.zs, pz_value(level, settings), Z_DEFLATED, - pz_value(windowBits, settings), pz_value(memLevel, settings), - pz_value(strategy, settings)); - - ps->pz_current = settings; - - /* The return code is from either deflateReset or deflateInit2; they have - * pretty much the same set of error codes. - */ - if (ret == Z_OK && ps->s.zs.state != NULL) - png_ptr->zowner = owner; - - else - { - png_zstream_error(&ps->s.zs, ret); - png_error(png_ptr, ps->s.zs.msg); - } - } - - return ps; -} - -#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED /* includes iCCP */ -/* Compress the block of data at the end of a chunk. This claims and releases - * png_struct::z_stream. It returns the amount of data in the chunk list or - * zero on error (a zlib stream always contains some bytes!) - * - * prefix_len is the amount of (uncompressed) data before the start of the - * compressed data. The routine will return 0 if the total of the compressed - * data and the prefix exceeds PNG_UINT_MAX_31. - * - * NOTE: this function may not return; it only returns 0 if - * png_chunk_report(PNG_CHUNK_WRITE_ERROR) returns (not the default). - */ -static int /* success */ -png_compress_chunk_data(png_structrp png_ptr, png_uint_32 chunk_name, - png_uint_32 prefix_len, png_const_voidp input, png_alloc_size_t input_len) -{ - /* To find the length of the output it is necessary to first compress the - * input. The result is buffered rather than using the two-pass algorithm - * that is used on the inflate side; deflate is assumed to be slower and a - * PNG writer is assumed to have more memory available than a PNG reader. - * - * IMPLEMENTATION NOTE: the zlib API deflateBound() can be used to find an - * upper limit on the output size, but it is always bigger than the input - * size so it is likely to be more efficient to use this linked-list - * approach. - */ - png_zlib_statep ps = png_deflate_claim(png_ptr, chunk_name, input_len); - - affirm(ps != NULL); - - /* The data compression function always returns so that we can clean up. */ - ps->s.zs.next_in = PNGZ_INPUT_CAST(png_voidcast(const Bytef*, input)); - - /* Use the stash, if available: */ - debug(ps->s.list == NULL); - ps->s.list = ps->stash; - ps->stash = NULL; - - { - int ret = png_compress(&ps->s, input_len, PNG_UINT_31_MAX-prefix_len, - Z_FINISH); - - ps->s.zs.next_out = NULL; /* safety */ - ps->s.zs.avail_out = 0; - ps->s.zs.next_in = NULL; - ps->s.zs.avail_in = 0; - png_ptr->zowner = 0; /* release png_ptr::zstream */ - - /* Since Z_FINISH was passed as the flush parameter any result other than - * Z_STREAM_END is an error. In any case in the event of an error free - * the whole compression state; the only expected error is Z_MEM_ERROR. - */ - if (ret != Z_STREAM_END) - { - png_zlib_compress_destroy(&ps->s, 0/*check*/); - - /* This is not very likely given the PNG_UINT_31_MAX limit above, but - * if code is added to limit the size of the chunks produced it can - * start to happen. - */ - if (ret == Z_BUF_ERROR) - ps->s.zs.msg = PNGZ_MSG_CAST("compressed chunk too long"); - - else - png_zstream_error(&ps->s.zs, ret); - - png_chunk_report(png_ptr, ps->s.zs.msg, PNG_CHUNK_WRITE_ERROR); - return 0; - } - } - - /* png_compress is meant to guarantee this on a successful return: */ - affirm(ps->s.overflow == 0U && ps->s.len <= PNG_UINT_31_MAX - prefix_len); - - /* Correct the zlib CINFO field: */ - if (ps->s.len >= 2U) - fix_cinfo(ps, ps->s.list->output, input_len); - - return 1; -} - -/* Return the length of the compressed data; this is effectively a debug - * function to catch inconsistencies caused by internal errors. It will - * disappear in a release build. - */ -#if PNG_RELEASE_BUILD -# define png_length_compressed_chunk_data(pp, p) ((pp)->zlib_state->s.len) -#else /* !RELEASE_BUILD */ -static png_uint_32 -png_length_compressed_chunk_data(png_structrp png_ptr, png_uint_32 p) -{ - png_zlib_statep ps = png_ptr->zlib_state; - - debug(ps != NULL && ps->s.overflow == 0U && ps->s.len <= PNG_UINT_31_MAX-p); - return ps->s.len; -} -#endif /* !RELEASE_BUILD */ - -/* Write all the data produced by the above function; the caller must write the - * prefix and chunk header. - */ -static void -png_write_compressed_chunk_data(png_structrp png_ptr) -{ - png_zlib_statep ps = png_ptr->zlib_state; - png_compression_bufferp next; - png_uint_32 output_len; - - affirm(ps != NULL && ps->s.overflow == 0U); - next = ps->s.list; - - for (output_len = ps->s.len; output_len > 0U; next = next->next) - { - png_uint_32 size = PNG_ROW_BUFFER_SIZE; - - /* If this affirm fails there is a bug in the calculation of - * output_length above, or in the buffer_limit code in png_compress. - */ - affirm(next != NULL && output_len > 0U); - - if (size > output_len) - size = output_len; - - png_write_chunk_data(png_ptr, next->output, size); - - output_len -= size; - } - - /* Release the list back to the stash. */ - debug(ps->stash == NULL); - ps->stash = ps->s.list; - ps->s.list = NULL; - ps->s.end = &ps->s.list; -} -#endif /* WRITE_COMPRESSED_TEXT */ - -#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ - defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) -/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, - * and if invalid, correct the keyword rather than discarding the entire - * chunk. The PNG 1.0 specification requires keywords 1-79 characters in - * length, forbids leading or trailing whitespace, multiple internal spaces, - * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. - * - * The 'new_key' buffer must be at least 80 characters in size (for the keyword - * plus a trailing '\0'). If this routine returns 0 then there was no keyword, - * or a valid one could not be generated, and the caller must CHUNK_WRITE_ERROR. - */ -static unsigned int -png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key) -{ - png_const_charp orig_key = key; - unsigned int key_len = 0; - int bad_character = 0; - int space = 1; - - png_debug(1, "in png_check_keyword"); - - if (key == NULL) - { - *new_key = 0; - return 0; - } - - while (*key && key_len < 79) - { - png_byte ch = (png_byte)(0xff & *key++); - - if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/)) - *new_key++ = ch, ++key_len, space = 0; - - else if (space == 0) - { - /* A space or an invalid character when one wasn't seen immediately - * before; output just a space. - */ - *new_key++ = 32, ++key_len, space = 1; - - /* If the character was not a space then it is invalid. */ - if (ch != 32) - bad_character = ch; - } - - else if (bad_character == 0) - bad_character = ch; /* just skip it, record the first error */ - } - - if (key_len > 0 && space != 0) /* trailing space */ - { - --key_len, --new_key; - if (bad_character == 0) - bad_character = 32; - } - - /* Terminate the keyword */ - *new_key = 0; - - if (key_len == 0) - return 0; - -#ifdef PNG_WARNINGS_SUPPORTED - /* Try to only output one warning per keyword: */ - if (*key != 0) /* keyword too long */ - png_app_warning(png_ptr, "keyword truncated"); - - else if (bad_character != 0) - { - PNG_WARNING_PARAMETERS(p) - - png_warning_parameter(p, 1, orig_key); - png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character); - - png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'"); - } -#endif /* WARNINGS */ - - return key_len; -} -#endif /* WRITE_TEXT || WRITE_pCAL || WRITE_iCCP || WRITE_sPLT */ - -/* Write the IHDR chunk, and update the png_struct with the necessary - * information. Note that the rest of this code depends upon this - * information being correct. - */ -void /* PRIVATE */ -png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height, - int bit_depth, int color_type, int compression_type, int filter_method, - int interlace_type) -{ - png_byte buf[13]; /* Buffer to store the IHDR info */ - - png_debug(1, "in png_write_IHDR"); - - /* Check that we have valid input data from the application info */ - switch (color_type) - { - case PNG_COLOR_TYPE_GRAY: - switch (bit_depth) - { - case 1: - case 2: - case 4: - case 8: -#ifdef PNG_WRITE_16BIT_SUPPORTED - case 16: -#endif - break; - - default: - png_error(png_ptr, "Invalid bit depth for grayscale image"); - } - break; - - case PNG_COLOR_TYPE_RGB: -#ifdef PNG_WRITE_16BIT_SUPPORTED - if (bit_depth != 8 && bit_depth != 16) -#else - if (bit_depth != 8) -#endif - png_error(png_ptr, "Invalid bit depth for RGB image"); - - break; - - case PNG_COLOR_TYPE_PALETTE: - switch (bit_depth) - { - case 1: - case 2: - case 4: - case 8: - break; - - default: - png_error(png_ptr, "Invalid bit depth for paletted image"); - } - break; - - case PNG_COLOR_TYPE_GRAY_ALPHA: - if (bit_depth != 8 && bit_depth != 16) - png_error(png_ptr, "Invalid bit depth for grayscale+alpha image"); - - break; - - case PNG_COLOR_TYPE_RGB_ALPHA: -#ifdef PNG_WRITE_16BIT_SUPPORTED - if (bit_depth != 8 && bit_depth != 16) -#else - if (bit_depth != 8) -#endif - png_error(png_ptr, "Invalid bit depth for RGBA image"); - - break; - - default: - png_error(png_ptr, "Invalid image color type specified"); - } - - if (compression_type != PNG_COMPRESSION_TYPE_BASE) - { - png_app_error(png_ptr, "Invalid compression type specified"); - compression_type = PNG_COMPRESSION_TYPE_BASE; - } - - /* Write filter_method 64 (intrapixel differencing) only if - * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and - * 2. Libpng did not write a PNG signature (this filter_method is only - * used in PNG datastreams that are embedded in MNG datastreams) and - * 3. The application called png_permit_mng_features with a mask that - * included PNG_FLAG_MNG_FILTER_64 and - * 4. The filter_method is 64 and - * 5. The color_type is RGB or RGBA - */ - if ( -# ifdef PNG_MNG_FEATURES_SUPPORTED - !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && - ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && - (color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_RGB_ALPHA) && - (filter_method == PNG_INTRAPIXEL_DIFFERENCING)) && -# endif /* MNG_FEATURES */ - filter_method != PNG_FILTER_TYPE_BASE) - { - png_app_error(png_ptr, "Invalid filter type specified"); - filter_method = PNG_FILTER_TYPE_BASE; - } - - if (interlace_type != PNG_INTERLACE_NONE && - interlace_type != PNG_INTERLACE_ADAM7) - { - png_app_error(png_ptr, "Invalid interlace type specified"); - interlace_type = PNG_INTERLACE_ADAM7; - } - - /* Save the relevant information */ - png_ptr->bit_depth = png_check_byte(png_ptr, bit_depth); - png_ptr->color_type = png_check_byte(png_ptr, color_type); - png_ptr->interlaced = png_check_byte(png_ptr, interlace_type); - png_ptr->filter_method = png_check_byte(png_ptr, filter_method); - png_ptr->width = width; - png_ptr->height = height; - - /* Pack the header information into the buffer */ - png_save_uint_32(buf, width); - png_save_uint_32(buf + 4, height); - buf[8] = png_check_byte(png_ptr, bit_depth); - buf[9] = png_check_byte(png_ptr, color_type); - buf[10] = png_check_byte(png_ptr, compression_type); - buf[11] = png_check_byte(png_ptr, filter_method); - buf[12] = png_check_byte(png_ptr, interlace_type); - - /* Write the chunk */ - png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); - png_ptr->mode |= PNG_HAVE_IHDR; -} - -/* Write the palette. We are careful not to trust png_color to be in the - * correct order for PNG, so people can redefine it to any convenient - * structure. - */ -void /* PRIVATE */ -png_write_PLTE(png_structrp png_ptr, png_const_colorp palette, - unsigned int num_pal) -{ - png_uint_32 max_palette_length, i; - png_const_colorp pal_ptr; - png_byte buf[3]; - - png_debug(1, "in png_write_PLTE"); - - max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? - (1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH; - - if (( -# ifdef PNG_MNG_FEATURES_SUPPORTED - (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 && -# endif /* MNG_FEATURES */ - num_pal == 0) || num_pal > max_palette_length) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - png_error(png_ptr, "Invalid number of colors in palette"); - } - - else - { - png_warning(png_ptr, "Invalid number of colors in palette"); - return; - } - } - - if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) - { - png_warning(png_ptr, - "Ignoring request to write a PLTE chunk in grayscale PNG"); - - return; - } - - png_ptr->num_palette = png_check_bits(png_ptr, num_pal, 9); - png_debug1(3, "num_palette = %d", png_ptr->num_palette); - - png_write_chunk_header(png_ptr, png_PLTE, num_pal * 3U); - - for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) - { - buf[0] = pal_ptr->red; - buf[1] = pal_ptr->green; - buf[2] = pal_ptr->blue; - png_write_chunk_data(png_ptr, buf, 3U); - } - - png_write_chunk_end(png_ptr); - png_ptr->mode |= PNG_HAVE_PLTE; -} - -/* Write an IEND chunk */ -void /* PRIVATE */ -png_write_IEND(png_structrp png_ptr) -{ - png_debug(1, "in png_write_IEND"); - - png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); - png_ptr->mode |= PNG_HAVE_IEND; -} - -#if defined(PNG_WRITE_gAMA_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED) -static int -png_save_int_31(png_structrp png_ptr, png_bytep buf, png_int_32 i) - /* Save a signed value as a PNG unsigned value; the argument is required to - * be in the range 0..0x7FFFFFFFU. If not a *warning* is produced and false - * is returned. Because this is only called from png_write_cHRM_fixed and - * png_write_gAMA_fixed below this is safe (we don't need either chunk, - * particularly if the value is bogus.) - * - * The warning is png_app_error; it may return if the app tells it to but the - * app can have it error out. JB 20150821: I believe the checking in png.c - * actually makes this error impossible, but this is safe. - */ -{ -#ifndef __COVERITY__ - if (i >= 0 && i <= 0x7FFFFFFF) -#else - /* Supress bogus Coverity complaint */ - if (i >= 0) -#endif - { - png_save_uint_32(buf, (png_uint_32)/*SAFE*/i); - return 1; - } - - else - { - png_chunk_report(png_ptr, "negative value in cHRM or gAMA", - PNG_CHUNK_WRITE_ERROR); - return 0; - } -} -#endif /* WRITE_gAMA || WRITE_cHRM */ - -#ifdef PNG_WRITE_gAMA_SUPPORTED -/* Write a gAMA chunk */ -void /* PRIVATE */ -png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma) -{ - png_byte buf[4]; - - png_debug(1, "in png_write_gAMA"); - - /* file_gamma is saved in 1/100,000ths */ - if (png_save_int_31(png_ptr, buf, file_gamma)) - png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); -} -#endif - -#ifdef PNG_WRITE_sRGB_SUPPORTED -/* Write a sRGB chunk */ -void /* PRIVATE */ -png_write_sRGB(png_structrp png_ptr, int srgb_intent) -{ - png_byte buf[1]; - - png_debug(1, "in png_write_sRGB"); - - if (srgb_intent >= PNG_sRGB_INTENT_LAST) - png_chunk_report(png_ptr, "Invalid sRGB rendering intent specified", - PNG_CHUNK_WRITE_ERROR); - - buf[0] = png_check_byte(png_ptr, srgb_intent); - png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); -} -#endif - -#ifdef PNG_WRITE_iCCP_SUPPORTED -/* Write an iCCP chunk */ -void /* PRIVATE */ -png_write_iCCP(png_structrp png_ptr, png_const_charp name, - png_const_voidp profile) -{ - png_uint_32 name_len; - png_uint_32 profile_len; - png_byte new_name[81]; /* 1 byte for the compression byte */ - - png_debug(1, "in png_write_iCCP"); - - affirm(profile != NULL); - - profile_len = png_get_uint_32(profile); - name_len = png_check_keyword(png_ptr, name, new_name); - - if (name_len == 0) - { - png_chunk_report(png_ptr, "iCCP: invalid keyword", PNG_CHUNK_WRITE_ERROR); - return; - } - - ++name_len; /* trailing '\0' */ - new_name[name_len++] = PNG_COMPRESSION_TYPE_BASE; - - if (png_compress_chunk_data(png_ptr, png_iCCP, name_len, profile, - profile_len)) - { - png_write_chunk_header(png_ptr, png_iCCP, - name_len+png_length_compressed_chunk_data(png_ptr, name_len)); - png_write_chunk_data(png_ptr, new_name, name_len); - png_write_compressed_chunk_data(png_ptr); - png_write_chunk_end(png_ptr); - } -} -#endif - -#ifdef PNG_WRITE_sPLT_SUPPORTED -/* Write a sPLT chunk */ -void /* PRIVATE */ -png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette) -{ - png_uint_32 name_len; - png_byte new_name[80]; - png_byte entrybuf[10]; - png_size_t entry_size = (spalette->depth == 8 ? 6 : 10); - png_size_t palette_size = entry_size * spalette->nentries; - png_sPLT_entryp ep; - - png_debug(1, "in png_write_sPLT"); - - name_len = png_check_keyword(png_ptr, spalette->name, new_name); - - if (name_len == 0) - png_error(png_ptr, "sPLT: invalid keyword"); - - /* Make sure we include the NULL after the name */ - png_write_chunk_header(png_ptr, png_sPLT, - (png_uint_32)(name_len + 2 + palette_size)); - - png_write_chunk_data(png_ptr, new_name, name_len + 1); - - png_write_chunk_data(png_ptr, &spalette->depth, 1); - - /* Loop through each palette entry, writing appropriately */ - for (ep = spalette->entries; epentries + spalette->nentries; ep++) - { - if (spalette->depth == 8) - { - entrybuf[0] = png_check_byte(png_ptr, ep->red); - entrybuf[1] = png_check_byte(png_ptr, ep->green); - entrybuf[2] = png_check_byte(png_ptr, ep->blue); - entrybuf[3] = png_check_byte(png_ptr, ep->alpha); - png_save_uint_16(entrybuf + 4, ep->frequency); - } - - else - { - png_save_uint_16(entrybuf + 0, ep->red); - png_save_uint_16(entrybuf + 2, ep->green); - png_save_uint_16(entrybuf + 4, ep->blue); - png_save_uint_16(entrybuf + 6, ep->alpha); - png_save_uint_16(entrybuf + 8, ep->frequency); - } - - png_write_chunk_data(png_ptr, entrybuf, entry_size); - } - - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_sBIT_SUPPORTED -/* Write the sBIT chunk */ -void /* PRIVATE */ -png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type) -{ - png_byte buf[4]; - png_size_t size; - - png_debug(1, "in png_write_sBIT"); - - /* Make sure we don't depend upon the order of PNG_COLOR_8 */ - if ((color_type & PNG_COLOR_MASK_COLOR) != 0) - { - unsigned int maxbits; - - maxbits = color_type==PNG_COLOR_TYPE_PALETTE ? 8 : png_ptr->bit_depth; - - if (sbit->red == 0 || sbit->red > maxbits || - sbit->green == 0 || sbit->green > maxbits || - sbit->blue == 0 || sbit->blue > maxbits) - { - png_app_error(png_ptr, "Invalid sBIT depth specified"); - return; - } - - buf[0] = sbit->red; - buf[1] = sbit->green; - buf[2] = sbit->blue; - size = 3; - } - - else - { - if (sbit->gray == 0 || sbit->gray > png_ptr->bit_depth) - { - png_app_error(png_ptr, "Invalid sBIT depth specified"); - return; - } - - buf[0] = sbit->gray; - size = 1; - } - - if ((color_type & PNG_COLOR_MASK_ALPHA) != 0) - { - if (sbit->alpha == 0 || sbit->alpha > png_ptr->bit_depth) - { - png_app_error(png_ptr, "Invalid sBIT depth specified"); - return; - } - - buf[size++] = sbit->alpha; - } - - png_write_complete_chunk(png_ptr, png_sBIT, buf, size); -} -#endif - -#ifdef PNG_WRITE_cHRM_SUPPORTED -/* Write the cHRM chunk */ -void /* PRIVATE */ -png_write_cHRM_fixed(png_structrp png_ptr, const png_xy *xy) -{ - png_byte buf[32]; - - png_debug(1, "in png_write_cHRM"); - - /* Each value is saved in 1/100,000ths */ - if (png_save_int_31(png_ptr, buf, xy->whitex) && - png_save_int_31(png_ptr, buf + 4, xy->whitey) && - png_save_int_31(png_ptr, buf + 8, xy->redx) && - png_save_int_31(png_ptr, buf + 12, xy->redy) && - png_save_int_31(png_ptr, buf + 16, xy->greenx) && - png_save_int_31(png_ptr, buf + 20, xy->greeny) && - png_save_int_31(png_ptr, buf + 24, xy->bluex) && - png_save_int_31(png_ptr, buf + 28, xy->bluey)) - png_write_complete_chunk(png_ptr, png_cHRM, buf, 32); -} -#endif - -#ifdef PNG_WRITE_tRNS_SUPPORTED -/* Write the tRNS chunk */ -void /* PRIVATE */ -png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha, - png_const_color_16p tran, int num_trans, int color_type) -{ - png_byte buf[6]; - - png_debug(1, "in png_write_tRNS"); - - if (color_type == PNG_COLOR_TYPE_PALETTE) - { - affirm(num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH); - { -# ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED - union - { - png_uint_32 u32[1]; - png_byte b8[PNG_MAX_PALETTE_LENGTH]; - } inverted_alpha; - - /* Invert the alpha channel (in tRNS) if required */ - if (png_ptr->write_invert_alpha) - { - int i; - - memcpy(inverted_alpha.b8, trans_alpha, num_trans); - - for (i=0; 4*igray < (1 << png_ptr->bit_depth)); - png_save_uint_16(buf, tran->gray); - png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2); - } - - else if (color_type == PNG_COLOR_TYPE_RGB) - { - /* Three 16 bit values */ - png_save_uint_16(buf, tran->red); - png_save_uint_16(buf + 2, tran->green); - png_save_uint_16(buf + 4, tran->blue); - affirm(png_ptr->bit_depth == 8 || (buf[0] | buf[2] | buf[4]) == 0); - png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); - } - - else /* Already checked in png_set_tRNS */ - impossible("invalid tRNS"); -} -#endif - -#ifdef PNG_WRITE_bKGD_SUPPORTED -/* Write the background chunk */ -void /* PRIVATE */ -png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type) -{ - png_byte buf[6]; - - png_debug(1, "in png_write_bKGD"); - - if (color_type == PNG_COLOR_TYPE_PALETTE) - { - if ( -# ifdef PNG_MNG_FEATURES_SUPPORTED - (png_ptr->num_palette != 0 || - (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0) && -# endif /* MNG_FEATURES */ - back->index >= png_ptr->num_palette) - { - png_app_error(png_ptr, "Invalid background palette index"); - return; - } - - buf[0] = back->index; - png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1); - } - - else if ((color_type & PNG_COLOR_MASK_COLOR) != 0) - { - png_save_uint_16(buf, back->red); - png_save_uint_16(buf + 2, back->green); - png_save_uint_16(buf + 4, back->blue); -#ifdef PNG_WRITE_16BIT_SUPPORTED - if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0) -#else - if ((buf[0] | buf[2] | buf[4]) != 0) -#endif - { - png_app_error(png_ptr, - "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8"); - - return; - } - - png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6); - } - - else - { - if (back->gray >= (1 << png_ptr->bit_depth)) - { - png_app_error(png_ptr, - "Ignoring attempt to write bKGD chunk out-of-range for bit_depth"); - - return; - } - - png_save_uint_16(buf, back->gray); - png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); - } -} -#endif - -#ifdef PNG_WRITE_hIST_SUPPORTED -/* Write the histogram */ -void /* PRIVATE */ -png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist) -{ - int i; - png_byte buf[3]; - - png_debug(1, "in png_write_hIST"); - - if (num_hist > (int)png_ptr->num_palette) - { - png_debug2(3, "num_hist = %d, num_palette = %d", num_hist, - png_ptr->num_palette); - - png_warning(png_ptr, "Invalid number of histogram entries specified"); - return; - } - - png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); - - for (i = 0; i < num_hist; i++) - { - png_save_uint_16(buf, hist[i]); - png_write_chunk_data(png_ptr, buf, (png_size_t)2); - } - - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_tEXt_SUPPORTED -/* Write a tEXt chunk */ -void /* PRIVATE */ -png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, - png_size_t text_len) -{ - unsigned int key_len; - png_byte new_key[80]; - - png_debug(1, "in png_write_tEXt"); - - key_len = png_check_keyword(png_ptr, key, new_key); - - if (key_len == 0) - { - png_chunk_report(png_ptr, "tEXt: invalid keyword", PNG_CHUNK_WRITE_ERROR); - return; - } - - if (text == NULL || *text == '\0') - text_len = 0; - - else - text_len = strlen(text); - - if (text_len > PNG_UINT_31_MAX - (key_len+1)) - { - png_chunk_report(png_ptr, "tEXt: text too long", PNG_CHUNK_WRITE_ERROR); - return; - } - - /* Make sure we include the 0 after the key */ - png_write_chunk_header(png_ptr, png_tEXt, - (png_uint_32)/*checked above*/(key_len + text_len + 1)); - /* - * We leave it to the application to meet PNG-1.0 requirements on the - * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of - * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. - * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. - */ - png_write_chunk_data(png_ptr, new_key, key_len + 1); - - if (text_len != 0) - png_write_chunk_data(png_ptr, (png_const_bytep)text, text_len); - - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_zTXt_SUPPORTED -/* Write a compressed text chunk */ -void /* PRIVATE */ -png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, - int compression) -{ - unsigned int key_len; - png_byte new_key[81]; - - png_debug(1, "in png_write_zTXt"); - - if (compression != PNG_TEXT_COMPRESSION_zTXt) - png_app_warning(png_ptr, "zTXt: invalid compression type ignored"); - - key_len = png_check_keyword(png_ptr, key, new_key); - - if (key_len == 0) - { - png_chunk_report(png_ptr, "zTXt: invalid keyword", PNG_CHUNK_WRITE_ERROR); - return; - } - - /* Add the compression method and 1 for the keyword separator. */ - ++key_len; - new_key[key_len++] = PNG_COMPRESSION_TYPE_BASE; - - if (png_compress_chunk_data(png_ptr, png_zTXt, key_len, text, strlen(text))) - { - png_write_chunk_header(png_ptr, png_zTXt, - key_len+png_length_compressed_chunk_data(png_ptr, key_len)); - png_write_chunk_data(png_ptr, new_key, key_len); - png_write_compressed_chunk_data(png_ptr); - png_write_chunk_end(png_ptr); - } - - /* else chunk report already issued and ignored */ -} -#endif - -#ifdef PNG_WRITE_iTXt_SUPPORTED -/* Write an iTXt chunk */ -void /* PRIVATE */ -png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key, - png_const_charp lang, png_const_charp lang_key, png_const_charp text) -{ - png_uint_32 key_len, prefix_len, data_len; - png_size_t lang_len, lang_key_len, text_len; - png_byte new_key[82]; /* 80 bytes for the key, 2 byte compression info */ - - png_debug(1, "in png_write_iTXt"); - - key_len = png_check_keyword(png_ptr, key, new_key); - - if (key_len == 0) - { - png_chunk_report(png_ptr, "iTXt: invalid keyword", PNG_CHUNK_WRITE_ERROR); - return; - } - - debug(new_key[key_len] == 0); - ++key_len; /* terminating 0 added by png_check_keyword */ - - /* Set the compression flag */ - switch (compression) - { - case PNG_ITXT_COMPRESSION_NONE: - case PNG_TEXT_COMPRESSION_NONE: - compression = new_key[key_len++] = 0; /* no compression */ - break; - - case PNG_TEXT_COMPRESSION_zTXt: - case PNG_ITXT_COMPRESSION_zTXt: - compression = new_key[key_len++] = 1; /* compressed */ - break; - - default: - png_chunk_report(png_ptr, "iTXt: invalid compression", - PNG_CHUNK_WRITE_ERROR); - return; - } - - new_key[key_len++] = PNG_COMPRESSION_TYPE_BASE; - - /* We leave it to the application to meet PNG-1.0 requirements on the - * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of - * any non-Latin-1 characters except for NEWLINE (yes, this is really weird - * in an 'international' text string. ISO PNG, however, specifies that the - * text is UTF-8 and this *IS NOT YET CHECKED*, so invalid sequences may be - * present. - * - * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. - * - * TODO: validate the language tag correctly (see the spec.) - */ - if (lang == NULL) lang = ""; /* empty language is valid */ - lang_len = strlen(lang)+1U; - if (lang_key == NULL) lang_key = ""; /* may be empty */ - lang_key_len = strlen(lang_key)+1U; - if (text == NULL) text = ""; /* may be empty */ - - if (lang_len > PNG_UINT_31_MAX-key_len || - lang_key_len > PNG_UINT_31_MAX-key_len-lang_len) - { - png_chunk_report(png_ptr, "iTXt: prefix too long", PNG_CHUNK_WRITE_ERROR); - return; - } - - prefix_len = (png_uint_32)/*SAFE*/(key_len+lang_len+lang_key_len); - text_len = strlen(text); /* no trailing '\0' */ - - if (compression != 0) - { - if (png_compress_chunk_data(png_ptr, png_iTXt, prefix_len, text, - text_len)) - data_len = png_length_compressed_chunk_data(png_ptr, prefix_len); - - else - return; /* chunk report already issued and ignored */ - } - - else - { - if (text_len > PNG_UINT_31_MAX-prefix_len) - { - png_chunk_report(png_ptr, "iTXt: text too long", - PNG_CHUNK_WRITE_ERROR); - return; - } - - data_len = (png_uint_32)/*SAFE*/text_len; - } - - png_write_chunk_header(png_ptr, png_iTXt, prefix_len+data_len); - png_write_chunk_data(png_ptr, new_key, key_len); - png_write_chunk_data(png_ptr, lang, lang_len); - png_write_chunk_data(png_ptr, lang_key, lang_key_len); - - if (compression != 0) - png_write_compressed_chunk_data(png_ptr); - - else - png_write_chunk_data(png_ptr, text, data_len); - - png_write_chunk_end(png_ptr); -} -#endif /* WRITE_iTXt */ - -#if defined(PNG_WRITE_oFFs_SUPPORTED) ||\ - defined(PNG_WRITE_pCAL_SUPPORTED) -/* PNG signed integers are saved in 32-bit 2's complement format. ANSI C-90 - * defines a cast of a signed integer to an unsigned integer either to preserve - * the value, if it is positive, or to calculate: - * - * (UNSIGNED_MAX+1) + integer - * - * Where UNSIGNED_MAX is the appropriate maximum unsigned value, so when the - * negative integral value is added the result will be an unsigned value - * correspnding to the 2's complement representation. - */ -static int -save_int_32(png_structrp png_ptr, png_bytep buf, png_int_32 j) -{ - png_uint_32 i = 0xFFFFFFFFU & (png_uint_32)/*SAFE & CORRECT*/j; - - if (i != 0x80000000U/*value not permitted*/) - { - png_save_uint_32(buf, i); - return 1; - } - - else - { - png_chunk_report(png_ptr, "invalid value in oFFS or pCAL", - PNG_CHUNK_WRITE_ERROR); - return 0; - } -} -#endif /* WRITE_oFFs || WRITE_pCAL */ - -#ifdef PNG_WRITE_oFFs_SUPPORTED -/* Write the oFFs chunk */ -void /* PRIVATE */ -png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset, - int unit_type) -{ - png_byte buf[9]; - - png_debug(1, "in png_write_oFFs"); - - if (unit_type >= PNG_OFFSET_LAST) - png_warning(png_ptr, "Unrecognized unit type for oFFs chunk"); - - if (save_int_32(png_ptr, buf, x_offset) && - save_int_32(png_ptr, buf + 4, y_offset)) - { - /* unit type is 0 or 1, this has been checked already so the following - * is safe: - */ - buf[8] = unit_type != 0; - png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); - } -} -#endif /* WRITE_oFFs */ - -#ifdef PNG_WRITE_pCAL_SUPPORTED -/* Write the pCAL chunk (described in the PNG extensions document) */ -void /* PRIVATE */ -png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0, - png_int_32 X1, int type, int nparams, png_const_charp units, - png_charpp params) -{ - png_uint_32 purpose_len; - size_t units_len; - png_byte buf[10]; - png_byte new_purpose[80]; - - png_debug1(1, "in png_write_pCAL (%d parameters)", nparams); - - if (type >= PNG_EQUATION_LAST) - png_error(png_ptr, "Unrecognized equation type for pCAL chunk"); - - purpose_len = png_check_keyword(png_ptr, purpose, new_purpose); - - if (purpose_len == 0) - png_error(png_ptr, "pCAL: invalid keyword"); - - ++purpose_len; /* terminator */ - - png_debug1(3, "pCAL purpose length = %d", (int)purpose_len); - units_len = strlen(units) + (nparams == 0 ? 0 : 1); - png_debug1(3, "pCAL units length = %d", (int)units_len); - - if (save_int_32(png_ptr, buf, X0) && - save_int_32(png_ptr, buf + 4, X1)) - { - png_size_tp params_len = png_voidcast(png_size_tp, - png_malloc(png_ptr, nparams * sizeof (png_size_t))); - int i; - size_t total_len = purpose_len + units_len + 10; - - /* Find the length of each parameter, making sure we don't count the - * null terminator for the last parameter. - */ - for (i = 0; i < nparams; i++) - { - params_len[i] = strlen(params[i]) + (i == nparams - 1 ? 0 : 1); - png_debug2(3, "pCAL parameter %d length = %lu", i, - (unsigned long)params_len[i]); - total_len += params_len[i]; - } - - png_debug1(3, "pCAL total length = %d", (int)total_len); - png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len); - png_write_chunk_data(png_ptr, new_purpose, purpose_len); - buf[8] = png_check_byte(png_ptr, type); - buf[9] = png_check_byte(png_ptr, nparams); - png_write_chunk_data(png_ptr, buf, (png_size_t)10); - png_write_chunk_data(png_ptr, (png_const_bytep)units, - (png_size_t)units_len); - - for (i = 0; i < nparams; i++) - png_write_chunk_data(png_ptr, (png_const_bytep)params[i], - params_len[i]); - - png_free(png_ptr, params_len); - png_write_chunk_end(png_ptr); - } -} -#endif /* WRITE_pCAL */ - -#ifdef PNG_WRITE_sCAL_SUPPORTED -/* Write the sCAL chunk */ -void /* PRIVATE */ -png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width, - png_const_charp height) -{ - png_byte buf[64]; - png_size_t wlen, hlen, total_len; - - png_debug(1, "in png_write_sCAL_s"); - - wlen = strlen(width); - hlen = strlen(height); - total_len = wlen + hlen + 2; - - if (total_len > 64) - { - png_warning(png_ptr, "Can't write sCAL (buffer too small)"); - return; - } - - buf[0] = png_check_byte(png_ptr, unit); - memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */ - memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */ - - png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); - png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len); -} -#endif - -#ifdef PNG_WRITE_pHYs_SUPPORTED -/* Write the pHYs chunk */ -void /* PRIVATE */ -png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit, - png_uint_32 y_pixels_per_unit, - int unit_type) -{ - png_byte buf[9]; - - png_debug(1, "in png_write_pHYs"); - - if (unit_type >= PNG_RESOLUTION_LAST) - png_warning(png_ptr, "Unrecognized unit type for pHYs chunk"); - - png_save_uint_32(buf, x_pixels_per_unit); - png_save_uint_32(buf + 4, y_pixels_per_unit); - buf[8] = png_check_byte(png_ptr, unit_type); - - png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); -} -#endif - -#ifdef PNG_WRITE_tIME_SUPPORTED -/* Write the tIME chunk. Use either png_convert_from_struct_tm() - * or png_convert_from_time_t(), or fill in the structure yourself. - */ -void /* PRIVATE */ -png_write_tIME(png_structrp png_ptr, png_const_timep mod_time) -{ - png_byte buf[7]; - - png_debug(1, "in png_write_tIME"); - - if (mod_time->month > 12 || mod_time->month < 1 || - mod_time->day > 31 || mod_time->day < 1 || - mod_time->hour > 23 || mod_time->second > 60) - { - png_warning(png_ptr, "Invalid time specified for tIME chunk"); - return; - } - - png_save_uint_16(buf, mod_time->year); - buf[2] = mod_time->month; - buf[3] = mod_time->day; - buf[4] = mod_time->hour; - buf[5] = mod_time->minute; - buf[6] = mod_time->second; - - png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7); -} -#endif - -static void -png_end_IDAT(png_structrp png_ptr) -{ - png_zlib_statep ps = png_ptr->zlib_state; - - png_ptr->zowner = 0U; /* release the stream */ - - if (ps != NULL) - png_deflate_release(png_ptr, ps, 1/*check*/); -} - -static void -png_write_IDAT(png_structrp png_ptr, int flush) -{ - png_zlib_statep ps = png_ptr->zlib_state; - png_uint_32 IDAT_size; - - /* Check for a correctly initialized list, the requirement that the end - * pointer is NULL means that the end of the list can be easily detected. - */ - affirm(ps != NULL && ps->s.end != NULL && *ps->s.end == NULL); - png_zlib_compress_validate(&png_ptr->zlib_state->s, 0/*in_use*/); - - IDAT_size = png_ptr->IDAT_size; - if (IDAT_size == 0U) - { - switch (pz_get(ps, IDAT, png_level, PNG_DEFAULT_COMPRESSION_LEVEL)) - { - case PNG_COMPRESSION_COMPAT: /* Legacy */ - IDAT_size = 8192U; - break; - - case PNG_COMPRESSION_LOW_MEMORY: - case PNG_COMPRESSION_HIGH_SPEED: - case PNG_COMPRESSION_LOW: - /* png_compress uses PNG_ROW_BUFFER_SIZE buffers for the compressed - * data. Optimize to allocate only one of these: - */ - IDAT_size = PNG_ROW_BUFFER_SIZE; - break; - - default: - case PNG_COMPRESSION_MEDIUM: - IDAT_size = PNG_ZBUF_SIZE; - break; - - case PNG_COMPRESSION_HIGH_READ_SPEED: - /* Assume the reader reads partial IDAT chunks (pretty much a - * requirement given that some PNG encoders produce just one IDAT) - */ - case PNG_COMPRESSION_HIGH: - /* This doesn't control the amount of memory allocated unless the - * PNG IDAT data really is this big. - * - * TODO: review handling out-of-memory from png_compress() by - * flushing an IDAT. - */ - IDAT_size = PNG_UINT_31_MAX; - break; - } - } - - /* Write IDAT chunks while either 'flush' is true or there are at - * least png_ptr->IDAT_size bytes available to be written. - */ - for (;;) - { - png_uint_32 len = IDAT_size; - - if (ps->s.overflow == 0U) - { - png_uint_32 avail = ps->s.len; - - if (avail < len) - { - /* When end_of_image is true everything gets written, otherwise - * there must be at least IDAT_size bytes available. - */ - if (!flush) - return; - - if (avail == 0U) - break; - - len = avail; - } - } - - png_write_chunk_header(png_ptr, png_IDAT, len); - - /* Write bytes from the buffer list, adjusting {overflow,len} as they are - * written. - */ - do - { - png_compression_bufferp next = ps->s.list; - unsigned int avail = sizeof next->output; - unsigned int start = ps->s.start; - unsigned int written; - - affirm(next != NULL); - - if (next->next == NULL) /* end of list */ - { - /* The z_stream should always be pointing into this output buffer, - * the buffer may not be full: - */ - debug(ps->s.zs.next_out + ps->s.zs.avail_out == - next->output + sizeof next->output); - avail -= ps->s.zs.avail_out; - } - - else /* not end of list */ - debug((ps->s.zs.next_out < next->output || - ps->s.zs.next_out > next->output + sizeof next->output) && - (ps->s.overflow > 0 || - ps->s.start + ps->s.len >= sizeof next->output)); - - /* First, if this is the very first IDAT (PNG_HAVE_IDAT not set) - * fix the Zlib CINFO field if required: - */ - if ((png_ptr->mode & PNG_HAVE_IDAT) == 0U && - avail >= start+2U /* enough for the zlib header */) - { - debug(start == 0U); - fix_cinfo(ps, next->output+start, png_image_size(png_ptr)); - } - - else /* always expect to see at least 2 bytes: */ - debug((png_ptr->mode & PNG_HAVE_IDAT) != 0U); - - /* Set this now to prevent the above happening again second time round - * the loop: - */ - png_ptr->mode |= PNG_HAVE_IDAT; - - if (avail <= start+len) - { - /* Write all of this buffer: */ - affirm(avail > start); /* else overflow on the subtract */ - written = avail-start; - png_write_chunk_data(png_ptr, next->output+start, written); - - /* At the end there are no buffers in the list but the z_stream - * still points into the old (just released) buffer. This can - * happen when the old buffer is not full if the compressed bytes - * exactly match the IDAT length; it should always happen when - * end_of_image is set. - */ - ps->s.list = next->next; - - if (next->next == NULL) - { - debug(avail == start+len); - ps->s.end = &ps->s.list; - ps->s.zs.next_out = NULL; - ps->s.zs.avail_out = 0U; - } - - next->next = ps->stash; - ps->stash = next; - ps->s.start = 0U; - } - - else /* write only part of this buffer */ - { - written = len; - png_write_chunk_data(png_ptr, next->output+start, written); - ps->s.start = (unsigned int)/*SAFE*/(start + written); - } - - /* 'written' bytes were written: */ - len -= written; - - if (written <= ps->s.len) - ps->s.len -= written; - - else - { - affirm(ps->s.overflow > 0U); - --ps->s.overflow; - ps->s.len += 0x80000000U - written; - UNTESTED - } - } - while (len > 0U); - - png_write_chunk_end(png_ptr); - } - - /* avail == 0 && flush */ - png_end_IDAT(png_ptr); - png_ptr->mode |= PNG_AFTER_IDAT; -} - -/* This is is a convenience wrapper to handle IDAT compression; it takes a - * pointer to the input data and places no limit on the size of the output but - * is otherwise the same as png_compress(). It also handles the use of the - * stash (only used for IDAT compression.) - */ -static int -png_compress_IDAT_data(png_structrp png_ptr, png_zlib_statep ps, - png_zlib_compressp pz, png_const_voidp input, uInt input_len, int flush) -{ - /* Delay initialize the z_stream. */ - if (png_ptr->zowner != png_IDAT) - png_deflate_claim(png_ptr, png_IDAT, 0U); - - affirm(png_ptr->zowner == png_IDAT && pz->end != NULL && *pz->end == NULL); - - /* z_stream::{next,avail}_out are set by png_compress to point into the - * buffer list. next_in must be set here, avail_in comes from the input_len - * parameter: - */ - pz->zs.next_in = PNGZ_INPUT_CAST(png_voidcast(const Bytef*, input)); - *pz->end = ps->stash; /* May be NULL */ - ps->stash = NULL; - - /* zlib buffers the output, the maximum amount of compressed data that can be - * produced here is governed by the amount of buffering. - */ - { - int ret = png_compress(pz, input_len, 0U/*unlimited*/, flush); - - affirm(pz->end != NULL && ps->stash == NULL); - ps->stash = *pz->end; /* May be NULL */ - *pz->end = NULL; - - /* Z_FINISH should give Z_STREAM_END, everything else should give Z_OK, in - * either case all the input should have been consumed: - */ - implies(ret == Z_OK || ret == Z_FINISH, pz->zs.avail_in == 0U && - (ret == Z_STREAM_END) == (flush == Z_FINISH)); - pz->zs.next_in = NULL; - pz->zs.avail_in = 0U; /* safety */ - png_zlib_compress_validate(pz, 0/*in_use*/); - - return ret; - } -} - -/* Compress some image data using the main png_zlib_compress. Write the result - * out if there is sufficient data. - */ -static void -png_compress_IDAT(png_structrp png_ptr, png_const_voidp input, uInt input_len, - int flush) -{ - png_zlib_statep ps = png_ptr->zlib_state; - int ret = png_compress_IDAT_data(png_ptr, ps, &ps->s, input, input_len, - flush); - - /* Check the return code. */ - if (ret == Z_OK || ret == Z_STREAM_END) - png_write_IDAT(png_ptr, flush == Z_FINISH); - - else /* ret != Z_OK && ret != Z_STREAM_END */ - { - /* This is an error condition. It is fatal. */ - png_end_IDAT(png_ptr); - png_zstream_error(&ps->s.zs, ret); - png_error(png_ptr, ps->s.zs.msg); - } -} - -/* This is called at the end of every row to handle the required callbacks and - * advance png_struct::row_number and png_struct::pass. - */ -static void -png_write_end_row(png_structrp png_ptr, int flush) -{ - png_uint_32 row_number = png_ptr->row_number; - unsigned int pass = png_ptr->pass; - - debug(pass < 7U); - implies(flush == Z_FINISH, png_ptr->zowner == 0U); - - /* API NOTE: the write callback is made before any changes to the row number - * or pass however, in 1.7.0, the zlib stream can be closed before the - * callback is made (this is new). The application flush function happens - * afterward as was the case before. In 1.7.0 this is solely determined by - * the order of the code that follows. - */ - if (png_ptr->write_row_fn != NULL) - png_ptr->write_row_fn(png_ptr, row_number, pass); - -# ifdef PNG_WRITE_FLUSH_SUPPORTED - if (flush == Z_SYNC_FLUSH) - { - if (png_ptr->output_flush_fn != NULL) - png_ptr->output_flush_fn(png_ptr); - png_ptr->zlib_state->flush_rows = 0U; - } -# else /* !WRITE_FLUSH */ - PNG_UNUSED(flush) -# endif /* !WRITE_FLUSH */ - - /* Finally advance to the next row/pass: */ - if (png_ptr->interlaced == PNG_INTERLACE_NONE) - { - debug(row_number < png_ptr->height); - - if (++row_number == png_ptr->height) /* last row */ - { - row_number = 0U; - debug(flush == Z_FINISH); - png_ptr->pass = 7U; - } - } - -# ifdef PNG_WRITE_INTERLACING_SUPPORTED - else /* interlaced */ if (png_ptr->do_interlace) - { - /* This gets called only for rows that are processed; i.e. rows that - * are in the pass of a pass which is itself in the output. - */ - debug(row_number < png_ptr->height && - PNG_PASS_IN_IMAGE(png_ptr->width, png_ptr->height, pass) && - pass <= PNG_LAST_PASS(png_ptr->width, png_ptr->height) && - PNG_ROW_IN_INTERLACE_PASS(row_number, pass)); - - /* NOTE: the last row of the original image may not be in the pass, in - * this case the code which skipped the row must do the increment - * below! See 'interlace_row' in pngwrite.c and the code in - * png_write_png_rows below. - * - * In that case an earlier row will be the last one in the pass (if the - * pass is in the output), check this here: - */ - implies(pass == PNG_LAST_PASS(png_ptr->width, png_ptr->height) && - PNG_LAST_PASS_ROW(row_number, pass, png_ptr->height), - flush == Z_FINISH); - - if (++row_number == png_ptr->height) /* last row */ - { - row_number = 0U; - png_ptr->pass = 0x7U & ++pass; - } - } -# endif /* WRITE_INTERLACING */ - - else /* application does interlace */ - { - implies(png_ptr->height == 1U, pass != 6U); - debug(PNG_PASS_IN_IMAGE(png_ptr->width, png_ptr->height, pass) && - row_number < PNG_PASS_ROWS(png_ptr->height, pass)); - - if (++row_number == PNG_PASS_ROWS(png_ptr->height, pass)) - { - /* last row in this pass, next one may be empty. */ - row_number = 0U; - - do - ++pass; - while (pass < 7U && - !PNG_PASS_IN_IMAGE(png_ptr->width, png_ptr->height, pass)); - - implies(png_ptr->height == 1U, pass != 6U); - implies(pass == 7U, flush == Z_FINISH); - png_ptr->pass = 0x7U & pass; - } - } - - png_ptr->row_number = row_number; -} - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -/* Flush the current output buffers now */ -void PNGAPI -png_write_flush(png_structrp png_ptr) -{ - png_debug(1, "in png_write_flush"); - - /* Force a flush at the end of the current row by setting 'flush_rows' to the - * maximum: - */ - if (png_ptr != NULL && png_ptr->zlib_state != NULL) - png_ptr->zlib_state->flush_rows = 0xEFFFFFFF; -} - -/* Return the correct flush to use */ -static int -row_flush(png_zlib_statep ps, unsigned int row_info_flags) -{ - if (PNG_IDAT_END(row_info_flags)) - return Z_FINISH; - - else if ((row_info_flags & png_row_end) != 0 && - ++ps->flush_rows >= ps->flush_dist) - return Z_SYNC_FLUSH; - - else - return Z_NO_FLUSH; -} -#else /* !WRITE_FLUSH */ -# define row_flush(ps, ri) (PNG_IDAT_END(ri) ? Z_FINISH : Z_NO_FLUSH) -#endif /* !WRITE_FLUSH */ - -static void -write_filtered_row(png_structrp png_ptr, png_const_voidp filtered_row, - unsigned int row_bytes, unsigned int filter /*if at start of row*/, - int flush) -{ - /* This handles writing a row that has been filtered, or did not need to be - * filtered. If the data row has a partial pixel it must have been handled - * correctly in the caller; filters generate a full 8 bits even if the pixel - * only has one significant bit! - */ - debug(row_bytes > 0); - affirm(row_bytes <= ZLIB_IO_MAX); /* I.e. it fits in a uInt */ - - if (filter < PNG_FILTER_VALUE_LAST) /* start of row */ - { - png_byte buffer[1]; - - buffer[0] = PNG_BYTE(filter); - png_compress_IDAT(png_ptr, buffer, 1U/*len*/, Z_NO_FLUSH); - } - - png_compress_IDAT(png_ptr, filtered_row, row_bytes, flush); -} - -static void -write_unfiltered_rowbits(png_structrp png_ptr, png_const_bytep filtered_row, - unsigned int row_bits, png_byte filter /*if at start of row*/, - int flush) -{ - /* Same as above, but it correctly clears the unused bits in a partial - * byte. - */ - const png_uint_32 row_bytes = row_bits >> 3; - - debug(filter == PNG_FILTER_VALUE_NONE || filter == PNG_FILTER_VALUE_LAST); - - if (row_bytes > 0U) - { - row_bits -= row_bytes << 3; - write_filtered_row(png_ptr, filtered_row, row_bytes, filter, - row_bits == 0U ? flush : Z_NO_FLUSH); - filter = PNG_FILTER_VALUE_LAST; /* written */ - } - - /* Handle a partial byte. */ - if (row_bits > 0U) - { - png_byte buffer[1]; - - buffer[0] = PNG_BYTE(filtered_row[row_bytes] & ~(0xFFU >> row_bits)); - write_filtered_row(png_ptr, buffer, 1U, filter, flush); - } -} - -#ifdef PNG_WRITE_FILTER_SUPPORTED -static void -filter_block_singlebyte(unsigned int row_bytes, png_bytep sub_row, - png_bytep up_row, png_bytep avg_row, png_bytep paeth_row, - png_const_bytep row, png_const_bytep prev_row, png_bytep prev_pixels) -{ - /* Calculate rows for all four filters where the input has one byte per pixel - * (more accurately per filter-unit). - */ - png_byte a = prev_pixels[0]; - png_byte c = prev_pixels[1]; - - while (row_bytes-- > 0U) - { - const png_byte x = *row++; - const png_byte b = prev_row == NULL ? 0U : *prev_row++; - - /* Calculate each filtered byte in turn: */ - if (sub_row != NULL) *sub_row++ = 0xFFU & (x - a); - if (up_row != NULL) *up_row++ = 0xFFU & (x - b); - if (avg_row != NULL) *avg_row++ = 0xFFU & (x - (a+b)/2U); - - /* Paeth is a little more difficult: */ - if (paeth_row != NULL) - { - int pa = b-c; /* a+b-c - a */ - int pb = a-c; /* a+b-c - b */ - int pc = pa+pb; /* a+b-c - c = b-c + a-c */ - png_byte p = a; - - pa = abs(pa); - pb = abs(pb); - if (pa > pb) pa = pb, p = b; - if (pa > abs(pc)) p = c; - - *paeth_row++ = 0xFFU & (x - p); - } - - /* And set a and c for the next pixel: */ - a = x; - c = b; - } - - /* Store a and c for the next block: */ - prev_pixels[0] = a; - prev_pixels[1] = c; -} - -static void -filter_block_multibyte(unsigned int row_bytes, - const unsigned int bpp, png_bytep sub_row, png_bytep up_row, - png_bytep avg_row, png_bytep paeth_row, png_const_bytep row, - png_const_bytep prev_row, png_bytep prev_pixels) -{ - /* Calculate rows for all four filters, the input is a block of bytes such - * that row_bytes is a multiple of bpp. bpp can be 2, 3, 4, 6 or 8. - * prev_pixels will be updated to the last pixels processed. - */ - while (row_bytes >= bpp) - { - unsigned int i; - - for (i=0; i pb) pa = pb, p = b; - if (pa > abs(pc)) p = c; - - *paeth_row++ = 0xFFU & (x - p); - } - } - - row_bytes -= i; - } -} - -static void -filter_block(png_const_bytep prev_row, png_bytep prev_pixels, - png_const_bytep unfiltered_row, unsigned int row_bits, - const unsigned int bpp, png_bytep sub_row, png_bytep up_row, - png_bytep avg_row, png_bytep paeth_row) -{ - const unsigned int row_bytes = row_bits >> 3; /* complete bytes */ - - if (bpp <= 8U) - { - /* There may be a partial byte at the end. */ - if (row_bytes > 0) - filter_block_singlebyte(row_bytes, sub_row, up_row, avg_row, paeth_row, - unfiltered_row, prev_row, prev_pixels); - - /* The partial byte must be handled correctly here; both the previous row - * value and the current value need to have non-present bits cleared. - */ - if ((row_bits & 7U) != 0) - { - const png_byte mask = PNG_BYTE(~(0xFFU >> (row_bits & 7U))); - png_byte buffer[2]; - - buffer[0] = unfiltered_row[row_bytes] & mask; - - if (prev_row != NULL) - buffer[1U] = prev_row[row_bytes] & mask; - - else - buffer[1U] = 0U; - - filter_block_singlebyte(1U, - sub_row == NULL ? NULL : sub_row+row_bytes, - up_row == NULL ? NULL : up_row+row_bytes, - avg_row == NULL ? NULL : avg_row+row_bytes, - paeth_row == NULL ? NULL : paeth_row+row_bytes, - buffer, buffer+1U, prev_pixels); - } - } - - else - filter_block_multibyte(row_bytes, bpp >> 3, - sub_row, up_row, avg_row, paeth_row, - unfiltered_row, prev_row, prev_pixels); -} - -static void -filter_row(png_structrp png_ptr, png_const_bytep prev_row, - png_bytep prev_pixels, png_const_bytep unfiltered_row, - unsigned int row_bits, unsigned int bpp, unsigned int filter, - int start_of_row, int flush) -{ - /* filters_to_try identifies a single filter and it is not PNG_FILTER_NONE. - */ - png_byte filtered_row[PNG_ROW_BUFFER_SIZE]; - - affirm((row_bits+7U) >> 3 <= PNG_ROW_BUFFER_SIZE && - filter >= PNG_FILTER_VALUE_SUB && filter <= PNG_FILTER_VALUE_PAETH); - debug((row_bits % bpp) == 0U); - - filter_block(prev_row, prev_pixels, unfiltered_row, row_bits, bpp, - filter == PNG_FILTER_VALUE_SUB ? filtered_row : NULL, - filter == PNG_FILTER_VALUE_UP ? filtered_row : NULL, - filter == PNG_FILTER_VALUE_AVG ? filtered_row : NULL, - filter == PNG_FILTER_VALUE_PAETH ? filtered_row : NULL); - - write_filtered_row(png_ptr, filtered_row, (row_bits+7U)>>3, - start_of_row ? filter : PNG_FILTER_VALUE_LAST, flush); -} - -/* Allow the application to select one or more row filters to use. */ -static png_int_32 -set_filter(png_zlib_statep ps, unsigned int filtersIn) -{ - /* Notice that PNG_NO_FILTERS is 0 and passes this test; this is OK because - * filters then gets set to PNG_FILTER_NONE, as is required. - * - * The argument to this routine is actually an (int), but conversion to - * (unsigned int) is safe because it leaves the top bits set which results in - * PNG_EDOM below. - */ - if (filtersIn < PNG_FILTER_NONE) - filtersIn = PNG_FILTER_MASK(filtersIn); - - /* PNG_ALL_FILTERS is a constant, unfortunately it is nominally signed, for - * historical reasons, hence the PNG_BIC_MASK here. - */ - if ((filtersIn & PNG_BIC_MASK(PNG_ALL_FILTERS)) == 0U) - { -# ifndef PNG_SELECT_FILTER_SUPPORTED - filtersIn &= -filtersIn; /* Use lowest set bit */ -# endif /* !SELECT_FILTER */ - - return ps->filter_mask = filtersIn & PNG_ALL_FILTERS; - } - - else /* Out-of-range filtersIn: */ - return PNG_EDOM; -} -#endif /* WRITE_FILTER */ - -#ifdef PNG_WRITE_FILTER_SUPPORTED -void /* PRIVATE */ -png_write_start_IDAT(png_structrp png_ptr) -{ - png_zlib_statep ps = get_zlib_state(png_ptr); - - /* Set up the IDAT compression state. Expect the state to have been released - * by the previous owner, but it doesn't much matter if there was an error. - * Note that the stream is not claimed yet. - */ - debug(png_ptr->zowner == 0U); - - /* This sets the buffer limits and write_row_size, which is used below. */ - png_zlib_state_set_buffer_limits(png_ptr, ps); - - if (ps->filter_mask == 0) - { -# ifdef PNG_SELECT_FILTER_SUPPORTED - /* Now default the filter mask if it hasn't been set already: */ - int png_level = - pz_get(ps, IDAT, png_level, PNG_DEFAULT_COMPRESSION_LEVEL); - - /* If the bit depth is less than 8, so pixels are not byte aligned, PNG - * filtering hardly ever helps because there is no correlation between - * the bytes on which the filter works and the actual pixel values. - * Note that GIF is a whole lot better at this because it uses LZW to - * compress a bit-stream, not a byte stream as in the deflate - * implementation of LZ77. - * - * If the row size is less than 256 bytes filter selection algorithms - * are flakey because the restricted range of codes in each row can - * lead to poor selection of filters, particularly if the bytes in the - * image are themselves limited. (This happens when a low bit-depth - * image is encoded with 8-bit channels.) - * - * By experiment with the test set of images the breakpoint between - * not filtering and filtering based on which gives best compression by - * row size is as follows: - * - * NONE FAST ALL - * PAL <=anything [even 8-bit palette images larger if filtered] - * G<8 <=anything [low bit depth gray images] - * G8 <=16 [+~1%] >16 - * G16 <=128 [+~1%] >128 - * GA8 <=64 [+~1%] >64 - * GA16 <=anything [always better without filtering!] - * RGB8 <=32 [+0-2%(1)] >32 - * RGB16 <=1024 [+~1%] >1024 - * RGBA8 <=64 [+~~1%] >64 - * RGBA16 <=128 {+~0.5%] >128 - * - * (1) The largest 24-bit RGB image (RGB8) faired better, by 1.3%, - * with 'fast' filters. This is assumed to be random. - * - * Aggregated across all color types and bit depths the breakpoint for - * filtering is >16 bytes, but the size increase only exceeds 0.5% for - * images with rows between 64 and 128 bytes, hence the choices below. - * - * Across all the test images that change (not including selecting just - * the 'fast' filters by default) does not change the compressed size - * significantly (+0.06% across the whole test set), however it does - * substantially increase the number of images without filtering. - * - * Using just none and sub filters results in overall compressed sizes - * somewhere around the geometric mean of no filtering and 'fast'. - * - * The image size also plays a part. Filtering is not an advantage for - * images of size <= 512 bytes. This is also reflected below. - * - * NOTE: the libpng 1.6 (and earlier) algorithm seems to work - * because it biases the byte codes in the output towards 0 and 255. - * Zlib doesn't care what the codes are, but Huffman encoding always - * benefits from a biased distribution and the filters themselves were - * designed to produce values in this range. - * - * In a raw comparison with the legacy code selection of specific sets - * of filters always increased the compressed size of the test set, as - * follows: - * - * PNG_ALL_FILTERS: +0.26% - * PNG_FAST_FILTERS: +1.9% - * NONE+SUB: +5.8% - * PNG_NO_FILTERS: +14% - * - * This mainly proves that a static selection of filters (without - * considering the PNG format) is always worse than the legacy - * algorithm below. - * - * NOTE: ps->filter_mask must be set to a mask value, not a simple - * PNG_FILTER_VALUE_ number. - */ - if (ps->write_row_size == 0U /* row cannot be buffered */) - ps->filter_mask = PNG_FILTER_NONE; - - else if (png_level == PNG_COMPRESSION_COMPAT/* Legacy */) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE || - png_ptr->bit_depth < 8U) - ps->filter_mask = PNG_FILTER_NONE; - - else - ps->filter_mask = PNG_ALL_FILTERS; - } - - /* NOTE: overall with the following size tests (row and image size) the - * test set of images end up 0.06% larger, however some color types are - * smaller and some larger; the differences are minute. If the test is - * <=128 (which means <=129 bytes per row with the filter byte) the - * resultant inclusion of 32x32 RGBA images results in significantly - * increased compressed size. - * - * The test on png_level captures the following settings: - * - * PNG_COMPRESSION_LOW_MEMORY - * PNG_COMPRESSION_HIGH_SPEED - * PNG_COMPRESSION_HIGH_READ_SPEED - * - * NOTE: this relies on the exact values in png.h! - */ - else if (png_level <= PNG_COMPRESSION_HIGH_READ_SPEED - || png_ptr->color_type == PNG_COLOR_TYPE_PALETTE - || png_ptr->bit_depth < 8U - || ps->write_row_size/*does not include filter*/ < 128U - || png_image_size(png_ptr) <= 512U) - ps->filter_mask = PNG_FILTER_NONE; - - /* ELSE: there are at least 128 bytes in every row and the pixels - * are multiples of a byte. - */ - else switch (png_level) - { - default: /* For GCC */ - case PNG_COMPRESSION_LOW: - ps->filter_mask = PNG_FILTER_NONE+PNG_FILTER_SUB; - break; - - case PNG_COMPRESSION_MEDIUM: - ps->filter_mask = PNG_FAST_FILTERS; - break; - - case PNG_COMPRESSION_HIGH: - ps->filter_mask = PNG_ALL_FILTERS; - break; - } -# else /* !SELECT_FILTER */ - ps->filter_mask = PNG_FILTER_NONE; -# endif /* !SELECT_FILTER */ - } -} - -static png_byte -png_write_start_row(png_zlib_statep ps, int start_of_pass, int no_previous_row) - /* Called at the start of a row to set up anything required for filter - * handling in the row. Sets png_zlib_state::filters to a single filter. - */ -{ - unsigned int mask = ps->filter_mask; - - /* If we see a previous-row filter in mask and png_zlib_state::save_row is - * still unset set it. This means that the first time a previous-row filter - * is seen row-saving gets turned on. - */ - if (ps->save_row == SAVE_ROW_UNSET && (mask & PREVIOUS_ROW_FILTERS) != 0U) - ps->save_row = SAVE_ROW_DEFAULT; - - if ((no_previous_row /* row not stored */ && !start_of_pass) || - ps->save_row == SAVE_ROW_OFF /* disabled by app */ || - ps->write_row_size == 0U /* row too large to buffer */) - mask &= PNG_BIC_MASK(PREVIOUS_ROW_FILTERS); - - /* On the first row of a pass Paeth is equivalent to sub and up is equivalent - * to none, so try to simplify the mask in in this case. - */ - else if (start_of_pass) { -# define MATCH(flags) ((mask & (flags)) == (flags)) - if (MATCH(PNG_FILTER_NONE|PNG_FILTER_UP)) - mask &= PNG_BIC_MASK(PNG_FILTER_UP); - - if (MATCH(PNG_FILTER_SUB|PNG_FILTER_PAETH)) - mask &= PNG_BIC_MASK(PNG_FILTER_PAETH); -# undef MATCH - } - -# ifdef PNG_SELECT_FILTER_SUPPORTED - if ((mask & (mask-1U)) == 0U /* single bit set */ || - ps->write_row_size == 0U /* row cannot be buffered */) -# endif /* SELECT_FILTER */ - /* Convert the lowest set bit into the corresponding value. If no bits - * are set select NONE. After this switch statement the value of - * ps->filters is guaranteed to just be a single filter. - */ - switch (mask & -mask) - { - default: mask = PNG_FILTER_VALUE_NONE; break; - case PNG_FILTER_SUB: mask = PNG_FILTER_VALUE_SUB; break; - case PNG_FILTER_UP: mask = PNG_FILTER_VALUE_UP; break; - case PNG_FILTER_AVG: mask = PNG_FILTER_VALUE_AVG; break; - case PNG_FILTER_PAETH: mask = PNG_FILTER_VALUE_PAETH; break; - } - - return ps->filters = PNG_BYTE(mask); -} - -static png_bytep -allocate_row(png_structrp png_ptr, png_const_bytep data, png_alloc_size_t size) - /* Utility to allocate and save some row bytes. If the result is NULL the - * allocation failed and the png_zlib_struct will have been updated to - * prevent further allocation attempts. - */ -{ - const png_zlib_statep ps = png_ptr->zlib_state; - png_bytep buffer; - - debug(ps->write_row_size > 0U); - - /* OOM is handled silently, as is the case where the row is too large to - * buffer. - */ - buffer = png_voidcast(png_bytep, - png_malloc_base(png_ptr, ps->write_row_size)); - - /* Setting write_row_size to 0 switches on the code for handling a row that - * is too large to buffer. This will kick in next time round, i.e. on the - * next row. - */ - if (buffer == NULL) - ps->write_row_size = 0U; - - else - memcpy(buffer, data, size); - - return buffer; -} -#endif /* WRITE_FILTER */ - -#ifdef PNG_SELECT_FILTER_SUPPORTED -/* Bit set operations. Not in ANSI C-90 but commonly available in highly - * optimized versions, hence the ifndef. These operations just work on bitsets - * of size 256. The second argument (the code index) may be evaluated multiple - * times. - */ -#ifndef PNG_CODE_SET /* Can be set in pngpriv.h */ -typedef png_uint_32 png_codeset[8]; -# define PNG_CODE_MASK(i) (((png_uint_32)1U) << ((i) & 0x1FU)) -# define PNG_CODE_IS_SET(c,i) (((c)[(i) >> 5] & PNG_CODE_MASK(i))) -# define PNG_CODE_SET(c,i) (((c)[(i) >> 5] |= PNG_CODE_MASK(i))) -# define PNG_CODE_CLEAR(c,i) (((c)[(i) >> 5] &= ~PNG_CODE_MASK(i))) -#endif /* !PNG_CODE_SET */ - -typedef struct filter_selector -{ - /* Persistent filter selection information (stored across row boundaries). - * A code is not considered if it last occured more than 'window' bytes ago. - * The deflate algorithm means that 'window' cannot exceed 8453377, however - * practical versions may be far less. When 'distance' reaches 'window' any - * code where: - * - * distance - code_distance[code] > window - * - * at the end of a row 'code' is removed from codeset. Otherwise - * (rearranging the above): - * - * distance - window <= code_distance[code] - * - * and so the distances of the still active codes can be reduced: - * - * code_distance[code] -= distance-window - * distance = window - * - * This prevents any wrap of 'distance' on a row which is shorter than - * 2^32-window. - * - * However when then row is 2^32-window or more bytes long (the row can be up - * to just under 2^34 bytes long) this algorithm doesn't work; 'distance' - * will overflow in the middle of the row and all codes are relevant. This - * is handled below simply by reseting the set of present codes at the start - * of the row and ignoring the overflow. - */ - unsigned int code_count; /* Number of distinct codes seen */ - int png_level; /* Cached compression level */ - png_uint_32 filter_select_max_width; - /* The maximum number of pixels which can be fitted in the window without - * filling the entire window (i.e. the maximum number that can be fitted - * in (window-1) bytes). - */ - png_uint_32 sum_bias[PNG_FILTER_VALUE_LAST]; - /* For each filter a measure of its cost in the filter sum calculation. - * This allows filter selection based on the sum-of-absolute-dfferences - * method to be biased to favour particular filters. There was no such - * bias before 1.7 and the filter byte was ignored. - */ - png_uint_32 distance; /* Distance from beginning */ - png_codeset codeset; /* Set of seen codes */ - png_uint_32 code_distance[256]; /* Distance at last occurence */ -} filter_selector; - -static const filter_selector * -png_start_filter_select(png_zlib_statep ps, unsigned int bpp) -{ -# define png_ptr ps_png_ptr(ps) - filter_selector *fs = ps->selector; - - if (fs == NULL) - { - fs = png_voidcast(filter_selector*, png_malloc_base(png_ptr, sizeof *fs)); - - if (fs != NULL) - { - png_uint_32 window = ps->filter_select_window; - fs->png_level = pz_get(ps, IDAT, png_level, - PNG_DEFAULT_COMPRESSION_LEVEL); - - /* Delay initialize this here: */ - if (window < 3U || window > PNG_FILTER_SELECT_WINDOW_MAX) - ps->filter_select_window = window = PNG_FILTER_SELECT_WINDOW_MAX; - - fs->code_count = 0; - - switch (fs->png_level) - { - default: - /* TODO: investigate other settings */ - { - unsigned int f; - - for (f=0; fsum_bias[f] = f; - } - ps->filter_select_threshold = 64U; /* 6bit RGB */ - ps->filter_select_threshold2 = 50U; /* TODO: experiment! */ - break; - - case PNG_COMPRESSION_COMPAT: /* Legacy */ - memset(fs->sum_bias, 0U, sizeof fs->sum_bias); - ps->filter_select_threshold = 1U; /* disabled */ - ps->filter_select_threshold2 = 1U; - break; - } - - /* This is the maximum row width, in pixels, of a row which fits and - * leaves 1 byte free in the window. For any bigger row filter - * selection ignores the previous rows. - */ - fs->filter_select_max_width = ((window-2U/*filter+last byte*/)*8U)/bpp; - fs->distance = 0U; - memset(fs->codeset, 0U, sizeof fs->codeset); - /* fs->code_distance is left uninitialized because fs->codeset says - * whether or not each entry has been initialized. - */ - ps->selector = fs; - } - - else - ps->write_row_size = 0U; /* OOM */ - } -# undef png_ptr - - return fs; -} - -typedef struct -{ - /* Per-filter data. This remains separate from the above until the filter - * selection has been made. It reflects the above however the codeset only - * records codes present in this row. - * - * The 'sum' fields are the sum of the absolute deviation of each code from - * 0, the algorithm from 1.6 and earlier. In other words: - * - * if (code >= 128) - * sum += code; - * else - * sum += 256-code; - */ - unsigned int code_count; /* Number of distinct codes seen in row */ - unsigned int new_code_count; /* Number of new codes seen in row */ - png_uint_32 sum_low; /* Low 31 bits of code sum */ - png_uint_32 sum_high; /* High 32 bits of code sum */ - png_codeset codeset; /* Set of codes seen in this row */ - png_uint_32 code_distance[256]; /* Distance at last occurence in this row */ -} filter_data; - -static void -filter_data_init(filter_data *fd, png_uint_32 distance, unsigned int filter, - unsigned int code_is_set, png_uint_32 bias) -{ - fd->code_count = 1U; - fd->new_code_count = !code_is_set; - fd->sum_low = bias; - fd->sum_high = 0U; - memset(&fd->codeset, 0U, sizeof fd->codeset); - PNG_CODE_SET(fd->codeset, filter); - fd->code_distance[filter] = distance; -} - -static void -add_code(const filter_selector *fs, filter_data *fd, png_uint_32 distance, - unsigned int code) -{ - if (!PNG_CODE_IS_SET(fd->codeset, code)) - { - PNG_CODE_SET(fd->codeset, code); - ++(fd->code_count); - fd->code_distance[code] = distance; - if (!PNG_CODE_IS_SET(fs->codeset, code)) - ++(fd->new_code_count); - } - - { - png_uint_32 low = fd->sum_low; - - if (code <= 128U) - low += code; - - else - low += 256U-code; - - /* Handle overflow into the top bit: */ - if (low & 0x80000000U) - fd->sum_low = low & 0x7FFFFFFFU, ++fd->sum_high; - - else - fd->sum_low = low; - } -} - -static png_byte -filter_data_select(png_zlib_statep ps, filter_data fd[PNG_FILTER_VALUE_LAST], - unsigned int filter, png_uint_32 distance, png_uint_32 w) -{ -# define png_ptr ps_png_ptr(ps) - /* Choose how to do this depending on the row and window size. */ - filter_selector *fs = ps->selector; - png_uint_32 window = ps->filter_select_window; - - affirm(fs != NULL); - - /* Check the width against the maximum number of pixels that can fit in a - * window without filling it: - */ - if (w > fs->filter_select_max_width) - { - /* The cache is not used */ - fs->distance = 0U; /* for next row */ - fs->code_count = 0U; - memset(fs->codeset, 0U, sizeof fs->codeset); - } - - else - { - /* Merge the two code sets, discounting codes that last occurred before - * the start of the window. - */ - png_uint_32 adjust, code_count; - unsigned int code; - - /* filter_selector::distance is the distance of the first byte in the row - * (the filter byte), but 'distance' can wrap on long rows. The above - * test is meant to exclude the wrap case by excluding any case where the - * row has as many bytes as the window, so: - */ - affirm(distance > fs->distance && distance - fs->distance < window); - - /* Set 'adjust' to the current distance of the start of the window. I.e: - * - * +---------------+--------+ - * | before window | window | future data - * +---------------+--------+ - * A A - * | | - * adjust + + distance - * - * If the window isn't full yet 'adjust' will be zero, otherwise all the - * distances will be reduced by 'adjust' so that the first byte of the - * window has distance 0. - */ - if (distance > window) - adjust = distance-window; - - else - adjust = 0; - - - /* This may be decreased below if some old codes only occured before the - * start of the window. - */ - code_count = fs->code_count + fd->new_code_count; - - for (code=0U; code<256U; ++code) - { - if (PNG_CODE_IS_SET(fd[filter].codeset, code)) - { - PNG_CODE_SET(fs->codeset, code); - debug(fd[filter].code_distance[code] >= adjust); - fs->code_distance[code] = fd[filter].code_distance[code] - adjust; - } - - else if (PNG_CODE_IS_SET(fs->codeset, code) && adjust > 0) - { - /* The code did not occur in this row, the old distance may now be - * outside the window (because adjust is non-zero). - */ - const png_uint_32 d = fs->code_distance[code]; - - if (d >= adjust) - fs->code_distance[code] = d-adjust; - - else - PNG_CODE_CLEAR(fs->codeset, code), --code_count; - } - } - - fs->code_count = code_count; - fs->distance = distance - adjust; /* I.e. either distance or window! */ - } - - return ps->filters = PNG_BYTE(filter); -# undef png_ptr -} - -static png_byte -select_filter(png_zlib_statep ps, png_const_bytep row, - png_const_bytep prev, unsigned int bpp, png_uint_32 width, int start_of_pass) - /* Select a filter from the list provided by png_write_start_row. */ -{ - png_byte filters = png_write_start_row(ps, start_of_pass, prev == NULL); - -# define png_ptr ps_png_ptr(ps) - if (filters >= PNG_FILTER_NONE) /* multiple filters to test */ - { - const png_uint_32 max_pixels = ps->row_buffer_max_pixels; - const png_uint_32 block_pixels = ps->row_buffer_max_aligned_pixels; - const filter_selector *fs = ps->selector; - png_uint_32 pixels_to_go = width; - png_uint_32 distance; - unsigned int bits_at_end = 0U; - png_byte prev_pixels[4*2*2]; /* 2 pixels up to 4x2-bytes each */ - filter_data fd[PNG_FILTER_VALUE_LAST]; - - debug((filters & (filters-1)) != 0U); /* Expect more than one bit! */ - - if (fs == NULL) - { - /* Delay initialize with a quiet OOM handler */ - fs = png_start_filter_select(ps, bpp); - if (fs == NULL) - { - ps->filters = PNG_FILTER_VALUE_NONE; - return PNG_FILTER_VALUE_NONE; - } - } - - /* If PNG_FILTER_NONE is in the list check it first. */ - if (filters & PNG_FILTER_NONE) - { - png_const_bytep rp = row; - png_uint_32 w = width; - - distance = fs->distance; - filter_data_init(fd+PNG_FILTER_VALUE_NONE, distance++, - PNG_FILTER_VALUE_NONE, - PNG_CODE_IS_SET(fs->codeset, PNG_FILTER_VALUE_NONE), - fs->sum_bias[PNG_FILTER_VALUE_NONE]); - - if (bpp >= 8) /* complete bytes */ - { - const unsigned int bytes = bpp/8U; - - while (w > 0) - { - unsigned int b; - for (b=0; b= ppb) - { - add_code(fs, fd+PNG_FILTER_VALUE_NONE, distance++, *rp++); - w -= ppb; - } - - if (w > 0) /* partial byte at end */ - add_code(fs, fd+PNG_FILTER_VALUE_NONE, distance++, - *rp & (0xFFU >> (w*bpp) /* zero unused bits */)); - } - - /* For PNG data with a small number of codes it is worth skipping the - * filtering because it almost always increases the code count - * significantly. This is controlled by - * png_zlib_state::filter_select_threshold and causes an early return - * here. - */ - if (fd[PNG_FILTER_VALUE_NONE].new_code_count + - fs->code_count < ps->filter_select_threshold) - return filter_data_select(ps, fd, PNG_FILTER_VALUE_NONE, distance, - width); - } /* PNG_FILTER_NONE */ - - memset(prev_pixels, 0U, sizeof prev_pixels); - distance = fs->distance; - - { - unsigned int i; - - for (i=PNG_FILTER_VALUE_NONE+1U; icodeset, i), fs->sum_bias[i]); - } - - ++distance; - - while (pixels_to_go || bits_at_end) - { - unsigned int bits, i; - union - { - PNG_ROW_BUFFER_ALIGN_TYPE force_buffer_alignment; - png_byte row[4][PNG_ROW_BUFFER_SIZE]; - } filtered; - union - { - PNG_ROW_BUFFER_ALIGN_TYPE force_buffer_alignment; - png_byte byte; - } last; - - if (pixels_to_go) - { - if (pixels_to_go > max_pixels) - { - /* Maintain alignment by consuming on block_pixels at once */ - bits = block_pixels * bpp; - pixels_to_go -= block_pixels; /* May be 0 */ - } - - else - { - bits = pixels_to_go * bpp; - bits_at_end = bits & 0x7U; - bits -= bits_at_end; - pixels_to_go = 0U; /* +bits_at_end */ - } - } - - else /* incomplete byte at the end of the pixel */ - { - /* Make sure the unused bits are cleared (to zero, although this is - * an arbitrary choice): - */ - last.byte = PNG_BYTE(*row & ~(0xFFU >> bits_at_end)); - row = &last.byte; - bits = bits_at_end; - bits_at_end = 0U; - } - - filter_block(prev, prev_pixels, row, bits, bpp, - filtered.row[0/*sub*/], filtered.row[1/*up*/], - filtered.row[2/*avg*/], filtered.row[3/*Paeth*/]); - - /* A block of (bits+7)/8 bytes is now available to process. */ - for (i=0; 8U*i < bits; ++i, ++distance) - { - unsigned int f; - - for (f=PNG_FILTER_VALUE_NONE+1U; f> 3; - - row += bits >> 3; - } - - /* Now look at the candidate filters, including 'none' and select the - * best. We know that 'none' increases the code count beyond the - * threshold, so if the old code count is below the threshold and there is - * a filter which does not increase the code count select it; doing so - * should do no harm to the overall compression. - */ - if (fs->code_count < ps->filter_select_threshold) - { - unsigned int f, min_new_count = 257U, min_f = PNG_FILTER_VALUE_NONE; - - for (f=PNG_FILTER_VALUE_NONE+1U; fcode_count + min_new_count < ps->filter_select_threshold2) - return filter_data_select(ps, fd, min_f, distance, width); - } - - /* Now fall back to the libpng 1.6 and earlier algorithm. This favours - * the filter which produces least deviation in the codes from 0. When - * this works it does so by reducing the distribution of code values. The - * filters implicitly encode the difference between a predictor based on - * adjacent values, the assumption is that this will result in values - * close to 0. - */ - { - png_uint_32 high = -1; - png_uint_32 low = -1; - unsigned int min_f = 0 /*unset, but safe*/; - unsigned int f; - - for (f=PNG_FILTER_VALUE_NONE; ffilters = filters; -# undef png_ptr -} -#else /* !SELECT_FILTER */ - /* Filter selection not being done, just call png_write_start_row: */ -# define select_filter(ps, rp, pp, bpp, width, start_of_pass)\ - png_write_start_row((ps), (start_of_pass), (pp) == NULL) -#endif /* !SELECT_FILTER */ - -/* This is the common function to write multiple rows of PNG data. The data is - * in the relevant PNG format but has had no filtering done. - */ -void /* PRIVATE */ -png_write_png_rows(png_structrp png_ptr, png_const_bytep *rows, - png_uint_32 num_rows) -{ - const png_zlib_statep ps = png_ptr->zlib_state; - const unsigned int bpp = png_ptr->row_output_pixel_depth; -# ifdef PNG_WRITE_FILTER_SUPPORTED - png_const_bytep previous_row = ps->previous_write_row; -# else /* !WRITE_FILTER */ - /* These are constant in the no-filer case: */ - const png_byte filter = PNG_FILTER_VALUE_NONE; - const png_uint_32 max_pixels = ps->zlib_max_pixels; - const png_uint_32 block_pixels = ps->zlib_max_aligned_pixels; -# endif /* !WRITE_FILTER */ - /* Write the given rows handling the png_compress_IDAT argument limitations - * (uInt) and any valid row width. - */ - png_uint_32 last_row_in_pass = 0U; /* Actual last, not last+1! */ - png_uint_32 pixels_in_pass = 0U; - unsigned int first_row_in_pass = 0U; /* For do_interlace */ - unsigned int pixels_at_end = 0U; /* for a partial byte at the end */ - unsigned int base_info_flags = png_row_end; - int pass = -1; /* Invalid: force calculation first time round */ - - debug(png_ptr->row_output_pixel_depth == PNG_PIXEL_DEPTH(*png_ptr)); - - while (num_rows-- > 0U) - { - if (png_ptr->pass != pass) - { - /* Recalcuate the row bytes and partial bits */ - pass = png_ptr->pass; - pixels_in_pass = png_ptr->width; - - if (png_ptr->interlaced == PNG_INTERLACE_NONE) - { - debug(pass == 0); - last_row_in_pass = png_ptr->height - 1U; - base_info_flags |= png_pass_last; /* there is only one */ - } - - else - { - const png_uint_32 height = png_ptr->height; - - last_row_in_pass = PNG_PASS_ROWS(height, pass); - debug(pass >= 0 && pass < 7); - -# ifdef PNG_WRITE_INTERLACING_SUPPORTED - if (png_ptr->do_interlace) - { - /* libpng is doing the interlace handling, the row number is - * actually the row in the image. - * - * This overflows when the PNG height is such that the are no - * rows in this pass. This does not matter; because there are - * no rows the value doesn't get used. - */ - last_row_in_pass = - PNG_ROW_FROM_PASS_ROW(last_row_in_pass-1U, pass); - first_row_in_pass = PNG_PASS_START_ROW(pass); - } - - else /* Application handles the interlace */ -# endif /* WRITE_INTERLACING */ - { - /* The row does exist, so this works without checking the column - * count. - */ - debug(last_row_in_pass > 0U); - last_row_in_pass -= 1U; - } - - if (pass == PNG_LAST_PASS(pixels_in_pass/*PNG width*/, height)) - base_info_flags |= png_pass_last; - - /* Finally, adjust pixels_in_pass for the interlacing (skip the - * final pass; it is full width). - */ - if (pass < 6) - pixels_in_pass = PNG_PASS_COLS(pixels_in_pass, pass); - } - - /* Mask out the bits in a partial byte. */ - pixels_at_end = pixels_in_pass & PNG_ADDOF(bpp); - -# ifdef PNG_WRITE_FILTER_SUPPORTED - /* Reset the previous_row pointer correctly; NULL at the start of - * the pass. If row_number is not 0 then a previous write_rows was - * interrupted in mid-pass and any required buffer should be in - * previous_write_row (set in the initializer). - */ - if (png_ptr->row_number == first_row_in_pass) - previous_row = NULL; -# endif /* WRITE_FILTER */ - } - -# ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* When libpng is handling the interlace we see rows that must be - * skipped. - */ - if (!png_ptr->do_interlace || - PNG_ROW_IN_INTERLACE_PASS(png_ptr->row_number, pass)) -# endif /* WRITE_INTERLACING */ - { - const unsigned int row_info_flags = base_info_flags | - (png_ptr->row_number == - first_row_in_pass ? png_pass_first_row : 0) | - (png_ptr->row_number == last_row_in_pass ? png_pass_last_row : 0); - const int flush = row_flush(ps, row_info_flags); - png_const_bytep row = *rows; - png_uint_32 pixels_to_go = pixels_in_pass; -# ifdef PNG_WRITE_FILTER_SUPPORTED - /* The filter can change each time round. Call png_write_start_row - * to resolve any changes. Note that when this function is used to - * do filter selection from png_write_png_data on the first row - * png_write_start_row will get called twice. - */ - const png_byte filter = select_filter(ps, row, previous_row, bpp, - pixels_in_pass, png_ptr->row_number == first_row_in_pass); - const png_uint_32 max_pixels = filter == PNG_FILTER_VALUE_NONE ? - ps->zlib_max_pixels : ps->row_buffer_max_pixels; - const png_uint_32 block_pixels = filter == PNG_FILTER_VALUE_NONE ? - ps->zlib_max_aligned_pixels : ps->row_buffer_max_aligned_pixels; - - /* The row handling uses png_compress_IDAT directly if there is no - * filter to be applied, otherwise it uses filter_row. - */ - if (filter != PNG_FILTER_VALUE_NONE) - { - int start_of_row = 1; - png_byte prev_pixels[4*2*2]; /* 2 pixels up to 4x2-bytes each */ - - memset(prev_pixels, 0U, sizeof prev_pixels); - - while (pixels_to_go > max_pixels) - { - /* Write a block at once to maintain alignment */ - filter_row(png_ptr, previous_row, prev_pixels, row, - bpp * block_pixels, bpp, filter, start_of_row, - Z_NO_FLUSH); - - if (previous_row != NULL) - previous_row += (block_pixels * bpp) >> 3; - - row += (block_pixels * bpp) >> 3; - pixels_to_go -= block_pixels; - start_of_row = 0; - } - - /* The filter code handles the partial byte at the end correctly, - * so this is all that is required: - */ - if (pixels_to_go > 0) - filter_row(png_ptr, previous_row, prev_pixels, row, - bpp * pixels_to_go, bpp, filter, start_of_row, flush); - } - - else -# endif /* WRITE_FILTER */ - - { - /* The no-filter case. */ - const uInt block_bytes = (uInt)/*SAFE*/( - bpp <= 8U ? - block_pixels >> PNG_SHIFTOF(bpp) : - block_pixels * (bpp >> 3)); - - /* png_write_start_IDAT guarantees this, but double check for - * overflow above in debug: - */ - debug((block_bytes & (PNG_ROW_BUFFER_BYTE_ALIGN-1U)) == 0U); - - /* The filter has to be written here: */ - png_compress_IDAT(png_ptr, &filter, 1U/*len*/, Z_NO_FLUSH); - - /* Process blocks of pixels up to the limit. */ - while (pixels_to_go > max_pixels) - { - png_compress_IDAT(png_ptr, row, block_bytes, Z_NO_FLUSH); - row += block_bytes; - pixels_to_go -= block_pixels; - } - - /* Now compress the remainder; pixels_to_go <= max_pixels so it will - * fit in a uInt. - */ - { - const png_uint_32 remainder = - bpp <= 8U - ? (pixels_to_go-pixels_at_end) >> PNG_SHIFTOF(bpp) - : (pixels_to_go-pixels_at_end) * (bpp >> 3); - - if (remainder > 0U) - png_compress_IDAT(png_ptr, row, remainder, - pixels_at_end > 0U ? Z_NO_FLUSH : flush); - - else - debug(pixels_at_end > 0U); - - if (pixels_at_end > 0U) - { - /* There is a final partial byte. This is PNG format so the - * left-most bits are the most significant. - */ - const png_byte last = PNG_BYTE(row[remainder] & - ~(0xFFU >> (pixels_at_end * bpp))); - - png_compress_IDAT(png_ptr, &last, 1U, flush); - } - } - } - - png_write_end_row(png_ptr, flush); - -# ifdef PNG_WRITE_FILTER_SUPPORTED - previous_row = *rows; -# endif /* WRITE_FILTER */ -# undef HANDLE - } /* row in pass */ - -# ifdef PNG_WRITE_INTERLACING_SUPPORTED - else /* row not in pass; just skip it */ - { - if (++png_ptr->row_number >= png_ptr->height) - { - debug(png_ptr->row_number == png_ptr->height); - - png_ptr->row_number = 0U; - png_ptr->pass = 0x7U & (pass+1U); - } - } -# endif /* WRITE_INTERLACING */ - - ++rows; - } /* while num_rows */ - -# ifdef PNG_WRITE_FILTER_SUPPORTED - /* previous_row must be copied back unless we don't need it because the - * next row is the first one in the pass (this relies on png_write_end_row - * setting row_number to 0 at the end!) - */ - if (png_ptr->row_number != 0U && previous_row != NULL && SAVE_ROW(ps) && - ps->previous_write_row != previous_row/*all rows skipped*/) - { -# ifdef PNG_SELECT_FILTER_SUPPORTED - /* We might be able to avoid any copy. */ - if (ps->current_write_row == previous_row) - { - png_bytep old = ps->previous_write_row; - ps->previous_write_row = ps->current_write_row; - ps->current_write_row = old; /* may be NULL */ - } - - else -# endif /* SELECT_FILTER */ - - if (ps->previous_write_row != NULL) - memcpy(ps->previous_write_row, previous_row, - png_calc_rowbytes(png_ptr, bpp, pixels_in_pass)); - - else - ps->previous_write_row = allocate_row(png_ptr, previous_row, - png_calc_rowbytes(png_ptr, bpp, pixels_in_pass)); - } -# endif /* WRITE_FILTER */ -} - -#ifdef PNG_WRITE_FILTER_SUPPORTED -/* This filters the row, chooses which filter to use, if it has not already - * been specified by the application, and then writes the row out with the - * chosen filter. - */ -static void -write_png_data(png_structrp png_ptr, png_const_bytep prev_row, - png_bytep prev_pixels, png_const_bytep unfiltered_row, png_uint_32 x, - unsigned int row_bits, unsigned int row_info_flags) - /* This filters the row appropriately and returns an updated prev_row - * (updated for 'x'). - */ -{ - const png_zlib_statep ps = png_ptr->zlib_state; - const unsigned int bpp = png_ptr->row_output_pixel_depth; - const int flush = row_flush(ps, row_info_flags); - const png_byte filter = ps->filters; /* just one */ - - /* These invariants are expected from the caller: */ - affirm(row_bits <= 8U*PNG_ROW_BUFFER_SIZE); - debug(filter < PNG_FILTER_VALUE_LAST/*sic: last+1*/); - - /* Now choose the correct filter implementation according to the number of - * filters in the filters_to_try list. The prev_row parameter is made - * NULL on the first row because it is uninitialized at that point. - */ - if (filter == PNG_FILTER_VALUE_NONE) - write_unfiltered_rowbits(png_ptr, unfiltered_row, row_bits, - x == 0 ? PNG_FILTER_VALUE_NONE : PNG_FILTER_VALUE_LAST, flush); - - else - filter_row(png_ptr, - (row_info_flags & png_pass_first_row) ? NULL : prev_row, - prev_pixels, unfiltered_row, row_bits, bpp, filter, x == 0, flush); - - /* Handle end of row: */ - if ((row_info_flags & png_row_end) != 0) - png_write_end_row(png_ptr, flush); -} - -void /* PRIVATE */ -png_write_png_data(png_structrp png_ptr, png_bytep prev_pixels, - png_const_bytep unfiltered_row, png_uint_32 x, - unsigned int width/*pixels*/, unsigned int row_info_flags) -{ - const png_zlib_statep ps = png_ptr->zlib_state; - - affirm(ps != NULL); - - { - const unsigned int bpp = png_ptr->row_output_pixel_depth; - const unsigned int row_bits = width * bpp; - png_bytep prev_row = ps->previous_write_row; - - debug(bpp <= 64U && width <= 65535U && - width < 65535U/bpp); /* Expensive: only matters on 16-bit */ - - /* This is called once before starting a new row here, but below it is - * only called once between starting a new list of rows. - */ - if (x == 0) - png_write_start_row(ps, (row_info_flags & png_pass_first_row) != 0, - prev_row == NULL); - - /* If filter selection is required the filter will have at least one mask - * bit set. - */ -# ifdef PNG_SELECT_FILTER_SUPPORTED - if (ps->filters >= PNG_FILTER_NONE/*lowest mask bit*/) - { - /* If the entire row is passed in the input process it via - * immediately, otherwise the row must be buffered for later - * analysis. - */ - png_const_bytep row; - - if (x > 0 || (row_info_flags & png_row_end) == 0) - { - /* The row must be saved for later. */ - png_bytep buffer = ps->current_write_row; - - /* png_write_start row should always check this: */ - debug(ps->write_row_size > 0U); - - if (buffer != NULL) - memcpy(buffer + png_calc_rowbytes(png_ptr, bpp, x), - unfiltered_row, (row_bits + 7U) >> 3); - - - else if (x == 0U) - ps->current_write_row = buffer = allocate_row(png_ptr, - unfiltered_row, (row_bits + 7U) >> 3); - - row = buffer; - } - - else - row = unfiltered_row; - - if (row != NULL) /* else out of memory */ - { - /* At row end, process the save buffer. */ - if ((row_info_flags & png_row_end) != 0) - png_write_png_rows(png_ptr, &row, 1U); - - /* Early return to skip the single-filter code */ - return; - } - - /* Caching the row failed, so process the row using the lowest set - * filter. The allocation error should only ever happen at the - * start of the row. If this goes wrong the output will have been - * damaged. - */ - affirm(x == 0U); - } -# endif /* SELECT_FILTER */ - - /* prev_row is either NULL or the position in the previous row buffer */ - if (prev_row != NULL && x > 0) - prev_row += png_calc_rowbytes(png_ptr, bpp, x); - - /* This is the single filter case (no selection): */ - write_png_data(png_ptr, prev_row, prev_pixels, unfiltered_row, x, - row_bits, row_info_flags); - - /* Copy the current row into the previous row buffer, if available, unless - * this is the last row in the pass, when there is no point. Note that - * write_previous_row may have garbage in a partial byte at the end as a - * result of this memcpy. - */ - if (!(row_info_flags & png_pass_last_row) && SAVE_ROW(ps)) { - if (prev_row != NULL) - memcpy(prev_row, unfiltered_row, (row_bits + 7U) >> 3); - - /* NOTE: if the application sets png_zlib_state::save_row in a callback - * it isn't possible to do the save until the next row. allocate_row - * handles OOM silently by turning off the save. - */ - else if (x == 0) /* can allocate the save buffer */ - ps->previous_write_row = - allocate_row(png_ptr, unfiltered_row, (row_bits + 7U) >> 3); - } - } -} -#else /* !WRITE_FILTER */ -void /* PRIVATE */ -png_write_start_IDAT(png_structrp png_ptr) -{ - png_zlib_statep ps = get_zlib_state(png_ptr); - - /* Set up the IDAT compression state. Expect the state to have been released - * by the previous owner, but it doesn't much matter if there was an error. - * Note that the stream is not claimed yet. - */ - debug(png_ptr->zowner == 0U); - - /* This sets the buffer limits and write_row_size, which is used below. */ - png_zlib_state_set_buffer_limits(png_ptr, ps); -} - -void /* PRIVATE */ -png_write_png_data(png_structrp png_ptr, png_bytep prev_pixels, - png_const_bytep unfiltered_row, png_uint_32 x, - unsigned int width/*pixels*/, unsigned int row_info_flags) -{ - const unsigned int bpp = png_ptr->row_output_pixel_depth; - int flush; - png_uint_32 row_bits; - - row_bits = width; - row_bits *= bpp; - /* These invariants are expected from the caller: */ - affirm(width < 65536U && bpp <= 64U && width < 65536U/bpp && - row_bits <= 8U*PNG_ROW_BUFFER_SIZE); - - affirm(png_ptr->zlib_state != NULL); - flush = row_flush(png_ptr->zlib_state, row_info_flags); - - write_unfiltered_rowbits(png_ptr, unfiltered_row, row_bits, - x == 0 ? PNG_FILTER_VALUE_NONE : PNG_FILTER_VALUE_LAST, flush); - - PNG_UNUSED(prev_pixels) - - /* Handle end of row: */ - if ((row_info_flags & png_row_end) != 0) - png_write_end_row(png_ptr, flush); -} -#endif /* !WRITE_FILTER */ - -png_int_32 /* PRIVATE */ -png_write_setting(png_structrp png_ptr, png_uint_32 setting, - png_uint_32 parameter, png_int_32 value) -{ - /* Caller checks the arguments for basic validity */ - int only_get = (setting & PNG_SF_GET) != 0U; - - setting &= ~PNG_SF_GET; - - switch (setting) - { - /* Settings in png_struct: */ - case PNG_SW_IDAT_size: - if (parameter > 0 && parameter <= PNG_UINT_31_MAX) - { - if (!only_get) - png_ptr->IDAT_size = parameter; - - return 0; /* set ok */ - } - - else - return PNG_EINVAL; - - /* Settings in zlib_state: */ - case PNG_SW_COMPRESS_png_level: - return compression_setting(png_ptr, parameter, png_level, value, - only_get); - -# ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED - case PNG_SW_COMPRESS_zlib_level: - return compression_setting(png_ptr, parameter, level, value, - only_get); - - case PNG_SW_COMPRESS_windowBits: - return compression_setting(png_ptr, parameter, windowBits, value, - only_get); - - case PNG_SW_COMPRESS_memLevel: - return compression_setting(png_ptr, parameter, memLevel, value, - only_get); - - case PNG_SW_COMPRESS_strategy: - return compression_setting(png_ptr, parameter, strategy, value, - only_get); - - case PNG_SW_COMPRESS_method: - if (value != 8) /* Only supported method */ - return PNG_EINVAL; - return 8; /* old method */ -# endif /* WRITE_CUSTOMIZE_COMPRESSION */ - -# ifdef PNG_WRITE_FILTER_SUPPORTED - case PNG_SW_COMPRESS_filters: - /* The method must match that in the IHDR: */ - if (parameter == png_ptr->filter_method) - { - if (!only_get) - return set_filter(get_zlib_state(png_ptr), value); - - else if (png_ptr->zlib_state != NULL && - png_ptr->zlib_state->filter_mask != 0U/*unset*/) - return png_ptr->zlib_state->filter_mask; - - else - return PNG_UNSET; - } - - else /* Invalid filter method */ - return PNG_EINVAL; - - case PNG_SW_COMPRESS_row_buffers: - /* New in 1.7.0: direct control of the buffering. */ - switch (parameter) - { - case 0: - if (!only_get) - get_zlib_state(png_ptr)->save_row = SAVE_ROW_OFF; - return 0; - - case 1: - if (!only_get) - get_zlib_state(png_ptr)->save_row = SAVE_ROW_ON; - return 1; - - default: - return PNG_ENOSYS; /* no support for bigger values */ - } -# endif /* WRITE_FILTER */ - -# ifdef PNG_WRITE_FLUSH_SUPPORTED - case PNG_SW_FLUSH: - /* Set the automatic flush interval or 0 to turn flushing off */ - if (!only_get) - get_zlib_state(png_ptr)->flush_dist = - value <= 0 ? 0xEFFFFFFFU : (png_uint_32)/*SAFE*/value; - - return 0; -# endif /* WRITE_FLUSH */ - -# ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED - case PNG_SRW_CHECK_FOR_INVALID_INDEX: - /* The 'enabled' value is a FORTRAN style three-state: */ - if (value > 0) - png_ptr->palette_index_check = PNG_PALETTE_CHECK_ON; - - else if (value < 0) - png_ptr->palette_index_check = PNG_PALETTE_CHECK_OFF; - - else - png_ptr->palette_index_check = PNG_PALETTE_CHECK_DEFAULT; - - return 0; -# endif /* WRITE_CHECK_FOR_INVALID_INDEX */ - -# ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED - case PNG_SRW_ERROR_HANDLING: - /* The parameter is a bit mask of what to set, the value is what to - * set it to. PNG_IDAT_ERRORS is ignored on write. - */ - if (value >= PNG_IGNORE && value <= PNG_ERROR && - parameter <= PNG_ALL_ERRORS) - { - if ((parameter & PNG_BENIGN_ERRORS) != 0U) - png_ptr->benign_error_action = value & 0x3U; - - if ((parameter & PNG_APP_WARNINGS) != 0U) - png_ptr->app_warning_action = value & 0x3U; - - if ((parameter & PNG_APP_ERRORS) != 0U) - png_ptr->app_error_action = value & 0x3U; - - return 0; - } - - return PNG_EINVAL; -# endif /* BENIGN_WRITE_ERRORS */ - - default: - return PNG_ENOSYS; /* not supported (whatever it is) */ - } -} -#endif /* WRITE */ diff --git a/ext/libzip/Android.mk b/ext/libzip/Android.mk deleted file mode 100644 index 544765db10..0000000000 --- a/ext/libzip/Android.mk +++ /dev/null @@ -1,136 +0,0 @@ -# Copyright (C) 2009 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE := libzip -LOCAL_SRC_FILES :=\ - zip_add.c \ - zip_add_dir.c \ - zip_add_entry.c \ - zip_algorithm_deflate.c \ - zip_buffer.c \ - zip_close.c \ - zip_delete.c \ - zip_dir_add.c \ - zip_dirent.c \ - zip_discard.c \ - zip_entry.c \ - zip_error.c \ - zip_error_clear.c \ - zip_error_get.c \ - zip_error_get_sys_type.c \ - zip_error_strerror.c \ - zip_error_to_str.c \ - zip_extra_field.c \ - zip_extra_field_api.c \ - zip_fclose.c \ - zip_fdopen.c \ - zip_file_add.c \ - zip_file_error_clear.c \ - zip_file_error_get.c \ - zip_file_get_comment.c \ - zip_file_get_external_attributes.c \ - zip_file_get_offset.c \ - zip_file_rename.c \ - zip_file_replace.c \ - zip_file_set_comment.c \ - zip_file_set_encryption.c \ - zip_file_set_external_attributes.c \ - zip_file_set_mtime.c \ - zip_file_strerror.c \ - zip_fopen.c \ - zip_fopen_encrypted.c \ - zip_fopen_index.c \ - zip_fopen_index_encrypted.c \ - zip_fread.c \ - zip_fseek.c \ - zip_ftell.c \ - zip_get_archive_comment.c \ - zip_get_archive_flag.c \ - zip_get_encryption_implementation.c \ - zip_get_file_comment.c \ - zip_get_name.c \ - zip_get_num_entries.c \ - zip_get_num_files.c \ - zip_hash.c \ - zip_io_util.c \ - zip_libzip_version.c \ - zip_memdup.c \ - zip_name_locate.c \ - zip_new.c \ - zip_open.c \ - zip_pkware.c \ - zip_progress.c \ - zip_rename.c \ - zip_replace.c \ - zip_set_archive_comment.c \ - zip_set_archive_flag.c \ - zip_set_default_password.c \ - zip_set_file_comment.c \ - zip_set_file_compression.c \ - zip_set_name.c \ - zip_source_accept_empty.c \ - zip_source_begin_write.c \ - zip_source_begin_write_cloning.c \ - zip_source_buffer.c \ - zip_source_call.c \ - zip_source_close.c \ - zip_source_commit_write.c \ - zip_source_compress.c \ - zip_source_crc.c \ - zip_source_error.c \ - zip_source_file_common.c \ - zip_source_file_stdio.c \ - zip_source_free.c \ - zip_source_function.c \ - zip_source_get_file_attributes.c \ - zip_source_is_deleted.c \ - zip_source_layered.c \ - zip_source_open.c \ - zip_source_pkware_decode.c \ - zip_source_pkware_encode.c \ - zip_source_read.c \ - zip_source_remove.c \ - zip_source_rollback_write.c \ - zip_source_seek.c \ - zip_source_seek_write.c \ - zip_source_stat.c \ - zip_source_supports.c \ - zip_source_tell.c \ - zip_source_tell_write.c \ - zip_source_window.c \ - zip_source_write.c \ - zip_source_zip.c \ - zip_source_zip_new.c \ - zip_stat.c \ - zip_stat_index.c \ - zip_stat_init.c \ - zip_strerror.c \ - zip_string.c \ - zip_unchange.c \ - zip_unchange_all.c \ - zip_unchange_archive.c \ - zip_unchange_data.c \ - zip_utf-8.c \ - zip_err_str.c \ - zip_mkstempm.c \ - zip_source_file_stdio_named.c \ - zip_random_unix.c - -LOCAL_CFLAGS := -O2 - -include $(BUILD_STATIC_LIBRARY) diff --git a/ext/libzip/CMakeLists.txt b/ext/libzip/CMakeLists.txt deleted file mode 100644 index 975ae4d7a5..0000000000 --- a/ext/libzip/CMakeLists.txt +++ /dev/null @@ -1,135 +0,0 @@ -set(SRCS - zip_add.c - zip_add_dir.c - zip_add_entry.c - zip_algorithm_deflate.c - zip_buffer.c - zip_close.c - zip_delete.c - zip_dir_add.c - zip_dirent.c - zip_discard.c - zip_entry.c - zip_error.c - zip_error_clear.c - zip_error_get.c - zip_error_get_sys_type.c - zip_error_strerror.c - zip_error_to_str.c - zip_extra_field.c - zip_extra_field_api.c - zip_fclose.c - zip_fdopen.c - zip_file_add.c - zip_file_error_clear.c - zip_file_error_get.c - zip_file_get_comment.c - zip_file_get_external_attributes.c - zip_file_get_offset.c - zip_file_rename.c - zip_file_replace.c - zip_file_set_comment.c - zip_file_set_encryption.c - zip_file_set_external_attributes.c - zip_file_set_mtime.c - zip_file_strerror.c - zip_fopen.c - zip_fopen_encrypted.c - zip_fopen_index.c - zip_fopen_index_encrypted.c - zip_fread.c - zip_fseek.c - zip_ftell.c - zip_get_archive_comment.c - zip_get_archive_flag.c - zip_get_encryption_implementation.c - zip_get_file_comment.c - zip_get_name.c - zip_get_num_entries.c - zip_get_num_files.c - zip_hash.c - zip_io_util.c - zip_libzip_version.c - zip_memdup.c - zip_name_locate.c - zip_new.c - zip_open.c - zip_pkware.c - zip_progress.c - zip_rename.c - zip_replace.c - zip_set_archive_comment.c - zip_set_archive_flag.c - zip_set_default_password.c - zip_set_file_comment.c - zip_set_file_compression.c - zip_set_name.c - zip_source_accept_empty.c - zip_source_begin_write.c - zip_source_begin_write_cloning.c - zip_source_buffer.c - zip_source_call.c - zip_source_close.c - zip_source_commit_write.c - zip_source_compress.c - zip_source_crc.c - zip_source_error.c - zip_source_file_common.c - zip_source_file_stdio.c - zip_source_free.c - zip_source_function.c - zip_source_get_file_attributes.c - zip_source_is_deleted.c - zip_source_layered.c - zip_source_open.c - zip_source_pkware_decode.c - zip_source_pkware_encode.c - zip_source_read.c - zip_source_remove.c - zip_source_rollback_write.c - zip_source_seek.c - zip_source_seek_write.c - zip_source_stat.c - zip_source_supports.c - zip_source_tell.c - zip_source_tell_write.c - zip_source_window.c - zip_source_write.c - zip_source_zip.c - zip_source_zip_new.c - zip_stat.c - zip_stat_index.c - zip_stat_init.c - zip_strerror.c - zip_string.c - zip_unchange.c - zip_unchange_all.c - zip_unchange_archive.c - zip_unchange_data.c - zip_utf-8.c - zip_err_str.c) - -if(WIN32) - set(SRCS ${SRCS} - zip_source_file_win32.c - zip_source_file_win32_named.c - zip_source_file_win32_utf16.c - zip_source_file_win32_utf8.c) - if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore) - set(SRCS ${SRCS} zip_random_uwp.c) - else() - set(SRCS ${SRCS} zip_source_file_win32_ansi.c zip_random_win32.c) - endif() -else() - set(SRCS ${SRCS} - zip_mkstempm.c - zip_source_file_stdio_named.c - zip_random_unix.c) -endif() - -add_library(zip STATIC ${SRCS}) - -if(UNIX) - add_definitions(-fPIC) -endif(UNIX) - diff --git a/ext/libzip/compat.h b/ext/libzip/compat.h deleted file mode 100644 index a5cf728040..0000000000 --- a/ext/libzip/compat.h +++ /dev/null @@ -1,194 +0,0 @@ -#ifndef _HAD_LIBZIP_COMPAT_H -#define _HAD_LIBZIP_COMPAT_H - -/* - compat.h -- compatibility defines. - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "zipconf.h" - -#include "config.h" - -/* to have *_MAX definitions for all types when compiling with g++ */ -#define __STDC_LIMIT_MACROS - -#ifdef _WIN32 -#ifndef ZIP_EXTERN -#ifndef ZIP_STATIC -#define ZIP_EXTERN __declspec(dllexport) -#endif -#endif -/* for dup(), close(), etc. */ -#include -#endif - -#ifdef HAVE_STDBOOL_H -#include -#else -typedef char bool; -#define true 1 -#define false 0 -#endif - -#include - -/* at least MinGW does not provide EOPNOTSUPP, see - * http://sourceforge.net/p/mingw/bugs/263/ - */ -#ifndef EOPNOTSUPP -#define EOPNOTSUPP EINVAL -#endif - -/* at least MinGW does not provide EOVERFLOW, see - * http://sourceforge.net/p/mingw/bugs/242/ - */ -#ifndef EOVERFLOW -#define EOVERFLOW EFBIG -#endif - -/* not supported on at least Windows */ -#ifndef O_CLOEXEC -#define O_CLOEXEC 0 -#endif - -#ifdef _WIN32 -#if defined(HAVE__CLOSE) -#define close _close -#endif -#if defined(HAVE__DUP) -#define dup _dup -#endif -/* crashes reported when using fdopen instead of _fdopen on Windows/Visual Studio 10/Win64 */ -#if defined(HAVE__FDOPEN) -#define fdopen _fdopen -#endif -#if !defined(HAVE_FILENO) && defined(HAVE__FILENO) -#define fileno _fileno -#endif -#if defined(HAVE__SNPRINTF) -#define snprintf _snprintf -#endif -#if defined(HAVE__STRDUP) -#if !defined(HAVE_STRDUP) || defined(_WIN32) -#undef strdup -#define strdup _strdup -#endif -#endif -#if !defined(HAVE__SETMODE) && defined(HAVE_SETMODE) -#define _setmode setmode -#endif -#if !defined(HAVE_STRTOLL) && defined(HAVE__STRTOI64) -#define strtoll _strtoi64 -#endif -#if !defined(HAVE_STRTOULL) && defined(HAVE__STRTOUI64) -#define strtoull _strtoui64 -#endif -#if defined(HAVE__UNLINK) -#define unlink _unlink -#endif -#endif - -#ifndef HAVE_FSEEKO -#define fseeko(s, o, w) (fseek((s), (long int)(o), (w))) -#endif - -#ifndef HAVE_FTELLO -#define ftello(s) ((long)ftell((s))) -#endif - -#if !defined(HAVE_STRCASECMP) -#if defined(HAVE__STRICMP) -#define strcasecmp _stricmp -#elif defined(HAVE_STRICMP) -#define strcasecmp stricmp -#endif -#endif - -#if SIZEOF_OFF_T == 8 -#define ZIP_OFF_MAX ZIP_INT64_MAX -#define ZIP_OFF_MIN ZIP_INT64_MIN -#elif SIZEOF_OFF_T == 4 -#define ZIP_OFF_MAX ZIP_INT32_MAX -#define ZIP_OFF_MIN ZIP_INT32_MIN -#elif SIZEOF_OFF_T == 2 -#define ZIP_OFF_MAX ZIP_INT16_MAX -#define ZIP_OFF_MIN ZIP_INT16_MIN -#else -#error unsupported size of off_t -#endif - -#if defined(HAVE_FTELLO) && defined(HAVE_FSEEKO) -#define ZIP_FSEEK_MAX ZIP_OFF_MAX -#define ZIP_FSEEK_MIN ZIP_OFF_MIN -#else -#include -#define ZIP_FSEEK_MAX LONG_MAX -#define ZIP_FSEEK_MIN LONG_MIN -#endif - -#ifndef SIZE_MAX -#if SIZEOF_SIZE_T == 8 -#define SIZE_MAX ZIP_INT64_MAX -#elif SIZEOF_SIZE_T == 4 -#define SIZE_MAX ZIP_INT32_MAX -#elif SIZEOF_SIZE_T == 2 -#define SIZE_MAX ZIP_INT16_MAX -#else -#error unsupported size of size_t -#endif -#endif - -#ifndef PRId64 -#ifdef _MSC_VER -#define PRId64 "I64d" -#else -#define PRId64 "lld" -#endif -#endif - -#ifndef PRIu64 -#ifdef _MSC_VER -#define PRIu64 "I64u" -#else -#define PRIu64 "llu" -#endif -#endif - -#ifndef S_ISDIR -#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR) -#endif - -#ifndef S_ISREG -#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG) -#endif - -#endif /* compat.h */ diff --git a/ext/libzip/config.h b/ext/libzip/config.h deleted file mode 100644 index da80b22115..0000000000 --- a/ext/libzip/config.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef HAD_CONFIG_H -#define HAD_CONFIG_H -#ifndef _HAD_ZIPCONF_H -#include "zipconf.h" -#endif - -#if defined(WINAPI_FAMILY) && defined(WINAPI_FAMILY_PARTITION) -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP -#define MS_UWP -#define _WIN32_WINNT 0x0602 -#endif -#endif - -/* BEGIN DEFINES */ -#ifdef _WIN32 -#define HAVE__CLOSE -#define HAVE__DUP -#define HAVE__FDOPEN -#define HAVE__FILENO -#define HAVE__SETMODE -#define HAVE__STRDUP -#define HAVE__STRICMP -#define HAVE__STRTOI64 -#define HAVE__STRTOUI64 -#define HAVE__UMASK -#define HAVE__UNLINK -#endif -#ifndef MS_UWP -#define HAVE_FILENO -#define HAVE_GETPROGNAME -#endif -#ifndef _WIN32 -#define HAVE_FSEEKO -#define HAVE_FTELLO -#define HAVE_LOCALTIME_R -#define HAVE_MKSTEMP 1 -#endif -#ifdef __MINGW32__ -#define HAVE_FSEEKO -#define HAVE_FTELLO -#endif -#define HAVE_SNPRINTF -#define HAVE_STDBOOL_H 1 -#define HAVE_STRDUP -#if !defined(__MINGW32__) && defined(_WIN32) -#define HAVE_STRICMP -#else -#define HAVE_STRCASECMP -#endif -#ifndef _WIN32 -#define HAVE_STRINGS_H 1 -#define HAVE_UNISTD_H -#endif -#if defined(_M_X64) || defined(__amd64__) || defined(__x86_64__) || defined(__aarch64__) || defined(_M_ARM64) || defined(__mips64__) -#define SIZEOF_OFF_T 8 -#define SIZEOF_SIZE_T 8 -#else -#define SIZEOF_OFF_T 4 -#define SIZEOF_SIZE_T 4 -#endif -/* END DEFINES */ -#define PACKAGE "libzip" -#define VERSION "1.7.3" - -#endif /* HAD_CONFIG_H */ diff --git a/ext/libzip/libzip.la b/ext/libzip/libzip.la deleted file mode 100644 index 49b0cd7779..0000000000 --- a/ext/libzip/libzip.la +++ /dev/null @@ -1,41 +0,0 @@ -# libzip.la - a libtool library file -# Generated by ltmain.sh (GNU libtool) 2.2.6b -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='libzip.so.1' - -# Names of this library. -library_names='libzip.so.1.0.0 libzip.so.1 libzip.so' - -# The name of the static archive. -old_library='libzip.a' - -# Linker flags that can not go in dependency_libs. -inherited_linker_flags='' - -# Libraries that this one depends upon. -dependency_libs=' -lz' - -# Names of additional weak libraries provided by this library -weak_library_names='' - -# Version information for libzip. -current=1 -age=0 -revision=0 - -# Is this an already installed library? -installed=no - -# Should we warn about portability when linking against -modules? -shouldnotlink=no - -# Files to dlopen/dlpreopen -dlopen='' -dlpreopen='' - -# Directory that this library needs to be installed in: -libdir='/usr/local/lib' diff --git a/ext/libzip/zip.h b/ext/libzip/zip.h deleted file mode 100644 index eda150aea0..0000000000 --- a/ext/libzip/zip.h +++ /dev/null @@ -1,479 +0,0 @@ -#ifndef _HAD_ZIP_H -#define _HAD_ZIP_H - -/* - zip.h -- exported declarations. - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* fix autoindent */ -#endif -#endif - -#include "zipconf.h" - -#ifndef ZIP_EXTERN -#ifndef ZIP_STATIC -#ifdef _WIN32 -#define ZIP_EXTERN __declspec(dllimport) -#elif defined(__GNUC__) && __GNUC__ >= 4 -#define ZIP_EXTERN __attribute__((visibility("default"))) -#else -#define ZIP_EXTERN -#endif -#else -#define ZIP_EXTERN -#endif -#endif - -#include -#include -#include - -/* flags for zip_open */ - -#define ZIP_CREATE 1 -#define ZIP_EXCL 2 -#define ZIP_CHECKCONS 4 -#define ZIP_TRUNCATE 8 -#define ZIP_RDONLY 16 - - -/* flags for zip_name_locate, zip_fopen, zip_stat, ... */ - -#define ZIP_FL_NOCASE 1u /* ignore case on name lookup */ -#define ZIP_FL_NODIR 2u /* ignore directory component */ -#define ZIP_FL_COMPRESSED 4u /* read compressed data */ -#define ZIP_FL_UNCHANGED 8u /* use original data, ignoring changes */ -#define ZIP_FL_RECOMPRESS 16u /* force recompression of data */ -#define ZIP_FL_ENCRYPTED 32u /* read encrypted data (implies ZIP_FL_COMPRESSED) */ -#define ZIP_FL_ENC_GUESS 0u /* guess string encoding (is default) */ -#define ZIP_FL_ENC_RAW 64u /* get unmodified string */ -#define ZIP_FL_ENC_STRICT 128u /* follow specification strictly */ -#define ZIP_FL_LOCAL 256u /* in local header */ -#define ZIP_FL_CENTRAL 512u /* in central directory */ -/* 1024u reserved for internal use */ -#define ZIP_FL_ENC_UTF_8 2048u /* string is UTF-8 encoded */ -#define ZIP_FL_ENC_CP437 4096u /* string is CP437 encoded */ -#define ZIP_FL_OVERWRITE 8192u /* zip_file_add: if file with name exists, overwrite (replace) it */ - -/* archive global flags flags */ - -#define ZIP_AFL_RDONLY 2u /* read only -- cannot be cleared */ - - -/* create a new extra field */ - -#define ZIP_EXTRA_FIELD_ALL ZIP_UINT16_MAX -#define ZIP_EXTRA_FIELD_NEW ZIP_UINT16_MAX - - -/* libzip error codes */ - -#define ZIP_ER_OK 0 /* N No error */ -#define ZIP_ER_MULTIDISK 1 /* N Multi-disk zip archives not supported */ -#define ZIP_ER_RENAME 2 /* S Renaming temporary file failed */ -#define ZIP_ER_CLOSE 3 /* S Closing zip archive failed */ -#define ZIP_ER_SEEK 4 /* S Seek error */ -#define ZIP_ER_READ 5 /* S Read error */ -#define ZIP_ER_WRITE 6 /* S Write error */ -#define ZIP_ER_CRC 7 /* N CRC error */ -#define ZIP_ER_ZIPCLOSED 8 /* N Containing zip archive was closed */ -#define ZIP_ER_NOENT 9 /* N No such file */ -#define ZIP_ER_EXISTS 10 /* N File already exists */ -#define ZIP_ER_OPEN 11 /* S Can't open file */ -#define ZIP_ER_TMPOPEN 12 /* S Failure to create temporary file */ -#define ZIP_ER_ZLIB 13 /* Z Zlib error */ -#define ZIP_ER_MEMORY 14 /* N Malloc failure */ -#define ZIP_ER_CHANGED 15 /* N Entry has been changed */ -#define ZIP_ER_COMPNOTSUPP 16 /* N Compression method not supported */ -#define ZIP_ER_EOF 17 /* N Premature end of file */ -#define ZIP_ER_INVAL 18 /* N Invalid argument */ -#define ZIP_ER_NOZIP 19 /* N Not a zip archive */ -#define ZIP_ER_INTERNAL 20 /* N Internal error */ -#define ZIP_ER_INCONS 21 /* N Zip archive inconsistent */ -#define ZIP_ER_REMOVE 22 /* S Can't remove file */ -#define ZIP_ER_DELETED 23 /* N Entry has been deleted */ -#define ZIP_ER_ENCRNOTSUPP 24 /* N Encryption method not supported */ -#define ZIP_ER_RDONLY 25 /* N Read-only archive */ -#define ZIP_ER_NOPASSWD 26 /* N No password provided */ -#define ZIP_ER_WRONGPASSWD 27 /* N Wrong password provided */ -#define ZIP_ER_OPNOTSUPP 28 /* N Operation not supported */ -#define ZIP_ER_INUSE 29 /* N Resource still in use */ -#define ZIP_ER_TELL 30 /* S Tell error */ -#define ZIP_ER_COMPRESSED_DATA 31 /* N Compressed data invalid */ -#define ZIP_ER_CANCELLED 32 /* N Operation cancelled */ - -/* type of system error value */ - -#define ZIP_ET_NONE 0 /* sys_err unused */ -#define ZIP_ET_SYS 1 /* sys_err is errno */ -#define ZIP_ET_ZLIB 2 /* sys_err is zlib error code */ - -/* compression methods */ - -#define ZIP_CM_DEFAULT -1 /* better of deflate or store */ -#define ZIP_CM_STORE 0 /* stored (uncompressed) */ -#define ZIP_CM_SHRINK 1 /* shrunk */ -#define ZIP_CM_REDUCE_1 2 /* reduced with factor 1 */ -#define ZIP_CM_REDUCE_2 3 /* reduced with factor 2 */ -#define ZIP_CM_REDUCE_3 4 /* reduced with factor 3 */ -#define ZIP_CM_REDUCE_4 5 /* reduced with factor 4 */ -#define ZIP_CM_IMPLODE 6 /* imploded */ -/* 7 - Reserved for Tokenizing compression algorithm */ -#define ZIP_CM_DEFLATE 8 /* deflated */ -#define ZIP_CM_DEFLATE64 9 /* deflate64 */ -#define ZIP_CM_PKWARE_IMPLODE 10 /* PKWARE imploding */ -/* 11 - Reserved by PKWARE */ -#define ZIP_CM_BZIP2 12 /* compressed using BZIP2 algorithm */ -/* 13 - Reserved by PKWARE */ -#define ZIP_CM_LZMA 14 /* LZMA (EFS) */ -/* 15-17 - Reserved by PKWARE */ -#define ZIP_CM_TERSE 18 /* compressed using IBM TERSE (new) */ -#define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */ -#define ZIP_CM_LZMA2 33 -#define ZIP_CM_XZ 95 /* XZ compressed data */ -#define ZIP_CM_JPEG 96 /* Compressed Jpeg data */ -#define ZIP_CM_WAVPACK 97 /* WavPack compressed data */ -#define ZIP_CM_PPMD 98 /* PPMd version I, Rev 1 */ - -/* encryption methods */ - -#define ZIP_EM_NONE 0 /* not encrypted */ -#define ZIP_EM_TRAD_PKWARE 1 /* traditional PKWARE encryption */ -#if 0 /* Strong Encryption Header not parsed yet */ -#define ZIP_EM_DES 0x6601 /* strong encryption: DES */ -#define ZIP_EM_RC2_OLD 0x6602 /* strong encryption: RC2, version < 5.2 */ -#define ZIP_EM_3DES_168 0x6603 -#define ZIP_EM_3DES_112 0x6609 -#define ZIP_EM_PKZIP_AES_128 0x660e -#define ZIP_EM_PKZIP_AES_192 0x660f -#define ZIP_EM_PKZIP_AES_256 0x6610 -#define ZIP_EM_RC2 0x6702 /* strong encryption: RC2, version >= 5.2 */ -#define ZIP_EM_RC4 0x6801 -#endif -#define ZIP_EM_AES_128 0x0101 /* Winzip AES encryption */ -#define ZIP_EM_AES_192 0x0102 -#define ZIP_EM_AES_256 0x0103 -#define ZIP_EM_UNKNOWN 0xffff /* unknown algorithm */ - -#define ZIP_OPSYS_DOS 0x00u -#define ZIP_OPSYS_AMIGA 0x01u -#define ZIP_OPSYS_OPENVMS 0x02u -#define ZIP_OPSYS_UNIX 0x03u -#define ZIP_OPSYS_VM_CMS 0x04u -#define ZIP_OPSYS_ATARI_ST 0x05u -#define ZIP_OPSYS_OS_2 0x06u -#define ZIP_OPSYS_MACINTOSH 0x07u -#define ZIP_OPSYS_Z_SYSTEM 0x08u -#define ZIP_OPSYS_CPM 0x09u -#define ZIP_OPSYS_WINDOWS_NTFS 0x0au -#define ZIP_OPSYS_MVS 0x0bu -#define ZIP_OPSYS_VSE 0x0cu -#define ZIP_OPSYS_ACORN_RISC 0x0du -#define ZIP_OPSYS_VFAT 0x0eu -#define ZIP_OPSYS_ALTERNATE_MVS 0x0fu -#define ZIP_OPSYS_BEOS 0x10u -#define ZIP_OPSYS_TANDEM 0x11u -#define ZIP_OPSYS_OS_400 0x12u -#define ZIP_OPSYS_OS_X 0x13u - -#define ZIP_OPSYS_DEFAULT ZIP_OPSYS_UNIX - - -enum zip_source_cmd { - ZIP_SOURCE_OPEN, /* prepare for reading */ - ZIP_SOURCE_READ, /* read data */ - ZIP_SOURCE_CLOSE, /* reading is done */ - ZIP_SOURCE_STAT, /* get meta information */ - ZIP_SOURCE_ERROR, /* get error information */ - ZIP_SOURCE_FREE, /* cleanup and free resources */ - ZIP_SOURCE_SEEK, /* set position for reading */ - ZIP_SOURCE_TELL, /* get read position */ - ZIP_SOURCE_BEGIN_WRITE, /* prepare for writing */ - ZIP_SOURCE_COMMIT_WRITE, /* writing is done */ - ZIP_SOURCE_ROLLBACK_WRITE, /* discard written changes */ - ZIP_SOURCE_WRITE, /* write data */ - ZIP_SOURCE_SEEK_WRITE, /* set position for writing */ - ZIP_SOURCE_TELL_WRITE, /* get write position */ - ZIP_SOURCE_SUPPORTS, /* check whether source supports command */ - ZIP_SOURCE_REMOVE, /* remove file */ - ZIP_SOURCE_RESERVED_1, /* previously used internally */ - ZIP_SOURCE_BEGIN_WRITE_CLONING, /* like ZIP_SOURCE_BEGIN_WRITE, but keep part of original file */ - ZIP_SOURCE_ACCEPT_EMPTY, /* whether empty files are valid archives */ - ZIP_SOURCE_GET_FILE_ATTRIBUTES /* get additional file attributes */ -}; -typedef enum zip_source_cmd zip_source_cmd_t; - -#define ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd) (((zip_int64_t)1) << (cmd)) - -/* clang-format off */ - -#define ZIP_SOURCE_SUPPORTS_READABLE (ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_OPEN) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_READ) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_CLOSE) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_STAT) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ERROR) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_FREE)) - -#define ZIP_SOURCE_SUPPORTS_SEEKABLE (ZIP_SOURCE_SUPPORTS_READABLE \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SUPPORTS)) - -#define ZIP_SOURCE_SUPPORTS_WRITABLE (ZIP_SOURCE_SUPPORTS_SEEKABLE \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_COMMIT_WRITE) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ROLLBACK_WRITE) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_WRITE) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK_WRITE) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL_WRITE) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_REMOVE)) - -/* clang-format on */ - -/* for use by sources */ -struct zip_source_args_seek { - zip_int64_t offset; - int whence; -}; - -typedef struct zip_source_args_seek zip_source_args_seek_t; -#define ZIP_SOURCE_GET_ARGS(type, data, len, error) ((len) < sizeof(type) ? zip_error_set((error), ZIP_ER_INVAL, 0), (type *)NULL : (type *)(data)) - - -/* error information */ -/* use zip_error_*() to access */ -struct zip_error { - int zip_err; /* libzip error code (ZIP_ER_*) */ - int sys_err; /* copy of errno (E*) or zlib error code */ - char *_Nullable str; /* string representation or NULL */ -}; - -#define ZIP_STAT_NAME 0x0001u -#define ZIP_STAT_INDEX 0x0002u -#define ZIP_STAT_SIZE 0x0004u -#define ZIP_STAT_COMP_SIZE 0x0008u -#define ZIP_STAT_MTIME 0x0010u -#define ZIP_STAT_CRC 0x0020u -#define ZIP_STAT_COMP_METHOD 0x0040u -#define ZIP_STAT_ENCRYPTION_METHOD 0x0080u -#define ZIP_STAT_FLAGS 0x0100u - -struct zip_stat { - zip_uint64_t valid; /* which fields have valid values */ - const char *_Nullable name; /* name of the file */ - zip_uint64_t index; /* index within archive */ - zip_uint64_t size; /* size of file (uncompressed) */ - zip_uint64_t comp_size; /* size of file (compressed) */ - time_t mtime; /* modification time */ - zip_uint32_t crc; /* crc of file data */ - zip_uint16_t comp_method; /* compression method used */ - zip_uint16_t encryption_method; /* encryption method used */ - zip_uint32_t flags; /* reserved for future use */ -}; - -struct zip_buffer_fragment { - zip_uint8_t *_Nonnull data; - zip_uint64_t length; -}; - -struct zip_file_attributes { - zip_uint64_t valid; /* which fields have valid values */ - zip_uint8_t version; /* version of this struct, currently 1 */ - zip_uint8_t host_system; /* host system on which file was created */ - zip_uint8_t ascii; /* flag whether file is ASCII text */ - zip_uint8_t version_needed; /* minimum version needed to extract file */ - zip_uint32_t external_file_attributes; /* external file attributes (host-system specific) */ - zip_uint16_t general_purpose_bit_flags; /* general purpose big flags, only some bits are honored */ - zip_uint16_t general_purpose_bit_mask; /* which bits in general_purpose_bit_flags are valid */ -}; - -#define ZIP_FILE_ATTRIBUTES_HOST_SYSTEM 0x0001u -#define ZIP_FILE_ATTRIBUTES_ASCII 0x0002u -#define ZIP_FILE_ATTRIBUTES_VERSION_NEEDED 0x0004u -#define ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES 0x0008u -#define ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS 0x0010u - -struct zip; -struct zip_file; -struct zip_source; - -typedef struct zip zip_t; -typedef struct zip_error zip_error_t; -typedef struct zip_file zip_file_t; -typedef struct zip_file_attributes zip_file_attributes_t; -typedef struct zip_source zip_source_t; -typedef struct zip_stat zip_stat_t; -typedef struct zip_buffer_fragment zip_buffer_fragment_t; - -typedef zip_uint32_t zip_flags_t; - -typedef zip_int64_t (*zip_source_callback)(void *_Nullable, void *_Nullable, zip_uint64_t, zip_source_cmd_t); -typedef void (*zip_progress_callback)(zip_t *_Nonnull, double, void *_Nullable); -typedef int (*zip_cancel_callback)(zip_t *_Nonnull, void *_Nullable); - -#ifndef ZIP_DISABLE_DEPRECATED -typedef void (*zip_progress_callback_t)(double); -ZIP_EXTERN void zip_register_progress_callback(zip_t *_Nonnull, zip_progress_callback_t _Nullable); /* use zip_register_progress_callback_with_state */ - -ZIP_EXTERN zip_int64_t zip_add(zip_t *_Nonnull, const char *_Nonnull, zip_source_t *_Nonnull); /* use zip_file_add */ -ZIP_EXTERN zip_int64_t zip_add_dir(zip_t *_Nonnull, const char *_Nonnull); /* use zip_dir_add */ -ZIP_EXTERN const char *_Nullable zip_get_file_comment(zip_t *_Nonnull, zip_uint64_t, int *_Nullable, int); /* use zip_file_get_comment */ -ZIP_EXTERN int zip_get_num_files(zip_t *_Nonnull); /* use zip_get_num_entries instead */ -ZIP_EXTERN int zip_rename(zip_t *_Nonnull, zip_uint64_t, const char *_Nonnull); /* use zip_file_rename */ -ZIP_EXTERN int zip_replace(zip_t *_Nonnull, zip_uint64_t, zip_source_t *_Nonnull); /* use zip_file_replace */ -ZIP_EXTERN int zip_set_file_comment(zip_t *_Nonnull, zip_uint64_t, const char *_Nullable, int); /* use zip_file_set_comment */ -ZIP_EXTERN int zip_error_get_sys_type(int); /* use zip_error_system_type */ -ZIP_EXTERN void zip_error_get(zip_t *_Nonnull, int *_Nullable, int *_Nullable); /* use zip_get_error, zip_error_code_zip / zip_error_code_system */ -ZIP_EXTERN int zip_error_to_str(char *_Nonnull, zip_uint64_t, int, int); /* use zip_error_init_with_code / zip_error_strerror */ -ZIP_EXTERN void zip_file_error_get(zip_file_t *_Nonnull, int *_Nullable, int *_Nullable); /* use zip_file_get_error, zip_error_code_zip / zip_error_code_system */ -#endif - -ZIP_EXTERN int zip_close(zip_t *_Nonnull); -ZIP_EXTERN int zip_delete(zip_t *_Nonnull, zip_uint64_t); -ZIP_EXTERN zip_int64_t zip_dir_add(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t); -ZIP_EXTERN void zip_discard(zip_t *_Nonnull); - -ZIP_EXTERN zip_error_t *_Nonnull zip_get_error(zip_t *_Nonnull); -ZIP_EXTERN void zip_error_clear(zip_t *_Nonnull); -ZIP_EXTERN int zip_error_code_zip(const zip_error_t *_Nonnull); -ZIP_EXTERN int zip_error_code_system(const zip_error_t *_Nonnull); -ZIP_EXTERN void zip_error_fini(zip_error_t *_Nonnull); -ZIP_EXTERN void zip_error_init(zip_error_t *_Nonnull); -ZIP_EXTERN void zip_error_init_with_code(zip_error_t *_Nonnull, int); -ZIP_EXTERN void zip_error_set(zip_error_t *_Nullable, int, int); -ZIP_EXTERN const char *_Nonnull zip_error_strerror(zip_error_t *_Nonnull); -ZIP_EXTERN int zip_error_system_type(const zip_error_t *_Nonnull); -ZIP_EXTERN zip_int64_t zip_error_to_data(const zip_error_t *_Nonnull, void *_Nonnull, zip_uint64_t); - -ZIP_EXTERN int zip_fclose(zip_file_t *_Nonnull); -ZIP_EXTERN zip_t *_Nullable zip_fdopen(int, int, int *_Nullable); -ZIP_EXTERN zip_int64_t zip_file_add(zip_t *_Nonnull, const char *_Nonnull, zip_source_t *_Nonnull, zip_flags_t); -ZIP_EXTERN void zip_file_attributes_init(zip_file_attributes_t *_Nonnull); -ZIP_EXTERN void zip_file_error_clear(zip_file_t *_Nonnull); -ZIP_EXTERN int zip_file_extra_field_delete(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_flags_t); -ZIP_EXTERN int zip_file_extra_field_delete_by_id(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t); -ZIP_EXTERN int zip_file_extra_field_set(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, const zip_uint8_t *_Nullable, zip_uint16_t, zip_flags_t); -ZIP_EXTERN zip_int16_t zip_file_extra_fields_count(zip_t *_Nonnull, zip_uint64_t, zip_flags_t); -ZIP_EXTERN zip_int16_t zip_file_extra_fields_count_by_id(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_flags_t); -ZIP_EXTERN const zip_uint8_t *_Nullable zip_file_extra_field_get(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t *_Nullable, zip_uint16_t *_Nullable, zip_flags_t); -ZIP_EXTERN const zip_uint8_t *_Nullable zip_file_extra_field_get_by_id(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_uint16_t *_Nullable, zip_flags_t); -ZIP_EXTERN const char *_Nullable zip_file_get_comment(zip_t *_Nonnull, zip_uint64_t, zip_uint32_t *_Nullable, zip_flags_t); -ZIP_EXTERN zip_error_t *_Nonnull zip_file_get_error(zip_file_t *_Nonnull); -ZIP_EXTERN int zip_file_get_external_attributes(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint8_t *_Nullable, zip_uint32_t *_Nullable); -ZIP_EXTERN int zip_file_rename(zip_t *_Nonnull, zip_uint64_t, const char *_Nonnull, zip_flags_t); -ZIP_EXTERN int zip_file_replace(zip_t *_Nonnull, zip_uint64_t, zip_source_t *_Nonnull, zip_flags_t); -ZIP_EXTERN int zip_file_set_comment(zip_t *_Nonnull, zip_uint64_t, const char *_Nullable, zip_uint16_t, zip_flags_t); -ZIP_EXTERN int zip_file_set_dostime(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t); -ZIP_EXTERN int zip_file_set_encryption(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, const char *_Nullable); -ZIP_EXTERN int zip_file_set_external_attributes(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint8_t, zip_uint32_t); -ZIP_EXTERN int zip_file_set_mtime(zip_t *_Nonnull, zip_uint64_t, time_t, zip_flags_t); -ZIP_EXTERN const char *_Nonnull zip_file_strerror(zip_file_t *_Nonnull); -ZIP_EXTERN zip_file_t *_Nullable zip_fopen(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t); -ZIP_EXTERN zip_file_t *_Nullable zip_fopen_encrypted(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t, const char *_Nullable); -ZIP_EXTERN zip_file_t *_Nullable zip_fopen_index(zip_t *_Nonnull, zip_uint64_t, zip_flags_t); -ZIP_EXTERN zip_file_t *_Nullable zip_fopen_index_encrypted(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, const char *_Nullable); -ZIP_EXTERN zip_int64_t zip_fread(zip_file_t *_Nonnull, void *_Nonnull, zip_uint64_t); -ZIP_EXTERN zip_int8_t zip_fseek(zip_file_t *_Nonnull, zip_int64_t, int); -ZIP_EXTERN zip_int64_t zip_ftell(zip_file_t *_Nonnull); -ZIP_EXTERN const char *_Nullable zip_get_archive_comment(zip_t *_Nonnull, int *_Nullable, zip_flags_t); -ZIP_EXTERN int zip_get_archive_flag(zip_t *_Nonnull, zip_flags_t, zip_flags_t); -ZIP_EXTERN const char *_Nullable zip_get_name(zip_t *_Nonnull, zip_uint64_t, zip_flags_t); -ZIP_EXTERN zip_int64_t zip_get_num_entries(zip_t *_Nonnull, zip_flags_t); -ZIP_EXTERN const char *_Nonnull zip_libzip_version(void); -ZIP_EXTERN zip_int64_t zip_name_locate(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t); -ZIP_EXTERN zip_t *_Nullable zip_open(const char *_Nonnull, int, int *_Nullable); -ZIP_EXTERN zip_t *_Nullable zip_open_from_source(zip_source_t *_Nonnull, int, zip_error_t *_Nullable); -ZIP_EXTERN int zip_register_progress_callback_with_state(zip_t *_Nonnull, double, zip_progress_callback _Nullable, void (*_Nullable)(void *_Nullable), void *_Nullable); -ZIP_EXTERN int zip_register_cancel_callback_with_state(zip_t *_Nonnull, zip_cancel_callback _Nullable, void (*_Nullable)(void *_Nullable), void *_Nullable); -ZIP_EXTERN int zip_set_archive_comment(zip_t *_Nonnull, const char *_Nullable, zip_uint16_t); -ZIP_EXTERN int zip_set_archive_flag(zip_t *_Nonnull, zip_flags_t, int); -ZIP_EXTERN int zip_set_default_password(zip_t *_Nonnull, const char *_Nullable); -ZIP_EXTERN int zip_set_file_compression(zip_t *_Nonnull, zip_uint64_t, zip_int32_t, zip_uint32_t); -ZIP_EXTERN int zip_source_begin_write(zip_source_t *_Nonnull); -ZIP_EXTERN int zip_source_begin_write_cloning(zip_source_t *_Nonnull, zip_uint64_t); -ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer(zip_t *_Nonnull, const void *_Nullable, zip_uint64_t, int); -ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer_create(const void *_Nullable, zip_uint64_t, int, zip_error_t *_Nullable); -ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer_fragment(zip_t *_Nonnull, const zip_buffer_fragment_t *_Nonnull, zip_uint64_t, int); -ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer_fragment_create(const zip_buffer_fragment_t *_Nullable, zip_uint64_t, int, zip_error_t *_Nullable); -ZIP_EXTERN int zip_source_close(zip_source_t *_Nonnull); -ZIP_EXTERN int zip_source_commit_write(zip_source_t *_Nonnull); -ZIP_EXTERN zip_error_t *_Nonnull zip_source_error(zip_source_t *_Nonnull); -ZIP_EXTERN zip_source_t *_Nullable zip_source_file(zip_t *_Nonnull, const char *_Nonnull, zip_uint64_t, zip_int64_t); -ZIP_EXTERN zip_source_t *_Nullable zip_source_file_create(const char *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable); -ZIP_EXTERN zip_source_t *_Nullable zip_source_filep(zip_t *_Nonnull, FILE *_Nonnull, zip_uint64_t, zip_int64_t); -ZIP_EXTERN zip_source_t *_Nullable zip_source_filep_create(FILE *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable); -ZIP_EXTERN void zip_source_free(zip_source_t *_Nullable); -ZIP_EXTERN zip_source_t *_Nullable zip_source_function(zip_t *_Nonnull, zip_source_callback _Nonnull, void *_Nullable); -ZIP_EXTERN zip_source_t *_Nullable zip_source_function_create(zip_source_callback _Nonnull, void *_Nullable, zip_error_t *_Nullable); -ZIP_EXTERN int zip_source_get_file_attributes(zip_source_t *_Nonnull, zip_file_attributes_t *_Nonnull); -ZIP_EXTERN int zip_source_is_deleted(zip_source_t *_Nonnull); -ZIP_EXTERN void zip_source_keep(zip_source_t *_Nonnull); -ZIP_EXTERN zip_int64_t zip_source_make_command_bitmap(zip_source_cmd_t, ...); -ZIP_EXTERN int zip_source_open(zip_source_t *_Nonnull); -ZIP_EXTERN zip_int64_t zip_source_read(zip_source_t *_Nonnull, void *_Nonnull, zip_uint64_t); -ZIP_EXTERN void zip_source_rollback_write(zip_source_t *_Nonnull); -ZIP_EXTERN int zip_source_seek(zip_source_t *_Nonnull, zip_int64_t, int); -ZIP_EXTERN zip_int64_t zip_source_seek_compute_offset(zip_uint64_t, zip_uint64_t, void *_Nonnull, zip_uint64_t, zip_error_t *_Nullable); -ZIP_EXTERN int zip_source_seek_write(zip_source_t *_Nonnull, zip_int64_t, int); -ZIP_EXTERN int zip_source_stat(zip_source_t *_Nonnull, zip_stat_t *_Nonnull); -ZIP_EXTERN zip_int64_t zip_source_tell(zip_source_t *_Nonnull); -ZIP_EXTERN zip_int64_t zip_source_tell_write(zip_source_t *_Nonnull); -#ifdef _WIN32 -ZIP_EXTERN zip_source_t *zip_source_win32a(zip_t *, const char *, zip_uint64_t, zip_int64_t); -ZIP_EXTERN zip_source_t *zip_source_win32a_create(const char *, zip_uint64_t, zip_int64_t, zip_error_t *); -ZIP_EXTERN zip_source_t *zip_source_win32handle(zip_t *, void *, zip_uint64_t, zip_int64_t); -ZIP_EXTERN zip_source_t *zip_source_win32handle_create(void *, zip_uint64_t, zip_int64_t, zip_error_t *); -ZIP_EXTERN zip_source_t *zip_source_win32w(zip_t *, const wchar_t *, zip_uint64_t, zip_int64_t); -ZIP_EXTERN zip_source_t *zip_source_win32w_create(const wchar_t *, zip_uint64_t, zip_int64_t, zip_error_t *); -#endif -ZIP_EXTERN zip_int64_t zip_source_write(zip_source_t *_Nonnull, const void *_Nullable, zip_uint64_t); -ZIP_EXTERN zip_source_t *_Nullable zip_source_zip(zip_t *_Nonnull, zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t); -ZIP_EXTERN int zip_stat(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t, zip_stat_t *_Nonnull); -ZIP_EXTERN int zip_stat_index(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_stat_t *_Nonnull); -ZIP_EXTERN void zip_stat_init(zip_stat_t *_Nonnull); -ZIP_EXTERN const char *_Nonnull zip_strerror(zip_t *_Nonnull); -ZIP_EXTERN int zip_unchange(zip_t *_Nonnull, zip_uint64_t); -ZIP_EXTERN int zip_unchange_all(zip_t *_Nonnull); -ZIP_EXTERN int zip_unchange_archive(zip_t *_Nonnull); -ZIP_EXTERN int zip_compression_method_supported(zip_int32_t method, int compress); -ZIP_EXTERN int zip_encryption_method_supported(zip_uint16_t method, int encode); - -#ifdef __cplusplus -} -#endif - -#endif /* _HAD_ZIP_H */ diff --git a/ext/libzip/zip_add.c b/ext/libzip/zip_add.c deleted file mode 100644 index 1954235708..0000000000 --- a/ext/libzip/zip_add.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - zip_add.c -- add file via callback function - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#define _ZIP_COMPILING_DEPRECATED -#include "zipint.h" - - -/* - NOTE: Return type is signed so we can return -1 on error. - The index can not be larger than ZIP_INT64_MAX since the size - of the central directory cannot be larger than - ZIP_UINT64_MAX, and each entry is larger than 2 bytes. -*/ - -ZIP_EXTERN zip_int64_t -zip_add(zip_t *za, const char *name, zip_source_t *source) { - return zip_file_add(za, name, source, 0); -} diff --git a/ext/libzip/zip_add_dir.c b/ext/libzip/zip_add_dir.c deleted file mode 100644 index 88fcf53a43..0000000000 --- a/ext/libzip/zip_add_dir.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - zip_add_dir.c -- add directory - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#define _ZIP_COMPILING_DEPRECATED -#include "zipint.h" - - -/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */ - -ZIP_EXTERN zip_int64_t -zip_add_dir(zip_t *za, const char *name) { - return zip_dir_add(za, name, 0); -} diff --git a/ext/libzip/zip_add_entry.c b/ext/libzip/zip_add_entry.c deleted file mode 100644 index f52e0b5ca2..0000000000 --- a/ext/libzip/zip_add_entry.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - zip_add_entry.c -- create and init struct zip_entry - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include - -#include "zipint.h" - - -/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */ - -zip_int64_t -_zip_add_entry(zip_t *za) { - zip_uint64_t idx; - - if (za->nentry + 1 >= za->nentry_alloc) { - zip_entry_t *rentries; - zip_uint64_t nalloc = za->nentry_alloc; - zip_uint64_t additional_entries = 2 * nalloc; - zip_uint64_t realloc_size; - - if (additional_entries < 16) { - additional_entries = 16; - } - else if (additional_entries > 1024) { - additional_entries = 1024; - } - /* neither + nor * overflows can happen: nentry_alloc * sizeof(struct zip_entry) < UINT64_MAX */ - nalloc += additional_entries; - realloc_size = sizeof(struct zip_entry) * (size_t)nalloc; - - if (sizeof(struct zip_entry) * (size_t)za->nentry_alloc > realloc_size) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - rentries = (zip_entry_t *)realloc(za->entry, sizeof(struct zip_entry) * (size_t)nalloc); - if (!rentries) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - za->entry = rentries; - za->nentry_alloc = nalloc; - } - - idx = za->nentry++; - - _zip_entry_init(za->entry + idx); - - return (zip_int64_t)idx; -} diff --git a/ext/libzip/zip_algorithm_deflate.c b/ext/libzip/zip_algorithm_deflate.c deleted file mode 100644 index d28a1ac50a..0000000000 --- a/ext/libzip/zip_algorithm_deflate.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - zip_algorithm_deflate.c -- deflate (de)compression routines - Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "zipint.h" - -#include -#include -#include - -struct ctx { - zip_error_t *error; - bool compress; - int compression_flags; - bool end_of_input; - z_stream zstr; -}; - - -static void * -allocate(bool compress, int compression_flags, zip_error_t *error) { - struct ctx *ctx; - - if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) { - zip_error_set(error, ZIP_ET_SYS, errno); - return NULL; - } - - ctx->error = error; - ctx->compress = compress; - ctx->compression_flags = compression_flags; - if (ctx->compression_flags < 1 || ctx->compression_flags > 9) { - ctx->compression_flags = Z_BEST_COMPRESSION; - } - ctx->end_of_input = false; - - ctx->zstr.zalloc = Z_NULL; - ctx->zstr.zfree = Z_NULL; - ctx->zstr.opaque = NULL; - - return ctx; -} - - -static void * -compress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) { - return allocate(true, compression_flags, error); -} - - -static void * -decompress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) { - return allocate(false, compression_flags, error); -} - - -static void -deallocate(void *ud) { - struct ctx *ctx = (struct ctx *)ud; - - free(ctx); -} - - -static zip_uint16_t -general_purpose_bit_flags(void *ud) { - struct ctx *ctx = (struct ctx *)ud; - - if (!ctx->compress) { - return 0; - } - - if (ctx->compression_flags < 3) { - return 2 << 1; - } - else if (ctx->compression_flags > 7) { - return 1 << 1; - } - return 0; -} - - -static bool -start(void *ud) { - struct ctx *ctx = (struct ctx *)ud; - int ret; - - ctx->zstr.avail_in = 0; - ctx->zstr.next_in = NULL; - ctx->zstr.avail_out = 0; - ctx->zstr.next_out = NULL; - - if (ctx->compress) { - /* negative value to tell zlib not to write a header */ - ret = deflateInit2(&ctx->zstr, ctx->compression_flags, Z_DEFLATED, -MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); - } - else { - ret = inflateInit2(&ctx->zstr, -MAX_WBITS); - } - - if (ret != Z_OK) { - zip_error_set(ctx->error, ZIP_ER_ZLIB, ret); - return false; - } - - - return true; -} - - -static bool -end(void *ud) { - struct ctx *ctx = (struct ctx *)ud; - int err; - - if (ctx->compress) { - err = deflateEnd(&ctx->zstr); - } - else { - err = inflateEnd(&ctx->zstr); - } - - if (err != Z_OK) { - zip_error_set(ctx->error, ZIP_ER_ZLIB, err); - return false; - } - - return true; -} - - -static bool -input(void *ud, zip_uint8_t *data, zip_uint64_t length) { - struct ctx *ctx = (struct ctx *)ud; - - if (length > UINT_MAX || ctx->zstr.avail_in > 0) { - zip_error_set(ctx->error, ZIP_ER_INVAL, 0); - return false; - } - - ctx->zstr.avail_in = (uInt)length; - ctx->zstr.next_in = (Bytef *)data; - - return true; -} - - -static void -end_of_input(void *ud) { - struct ctx *ctx = (struct ctx *)ud; - - ctx->end_of_input = true; -} - - -static zip_compression_status_t -process(void *ud, zip_uint8_t *data, zip_uint64_t *length) { - struct ctx *ctx = (struct ctx *)ud; - - int ret; - - ctx->zstr.avail_out = (uInt)ZIP_MIN(UINT_MAX, *length); - ctx->zstr.next_out = (Bytef *)data; - - if (ctx->compress) { - ret = deflate(&ctx->zstr, ctx->end_of_input ? Z_FINISH : 0); - } - else { - ret = inflate(&ctx->zstr, Z_SYNC_FLUSH); - } - - *length = *length - ctx->zstr.avail_out; - - switch (ret) { - case Z_OK: - return ZIP_COMPRESSION_OK; - - case Z_STREAM_END: - return ZIP_COMPRESSION_END; - - case Z_BUF_ERROR: - if (ctx->zstr.avail_in == 0) { - return ZIP_COMPRESSION_NEED_DATA; - } - - /* fallthrough */ - - default: - zip_error_set(ctx->error, ZIP_ER_ZLIB, ret); - return ZIP_COMPRESSION_ERROR; - } -} - -/* clang-format off */ - -zip_compression_algorithm_t zip_algorithm_deflate_compress = { - compress_allocate, - deallocate, - general_purpose_bit_flags, - 20, - start, - end, - input, - end_of_input, - process -}; - - -zip_compression_algorithm_t zip_algorithm_deflate_decompress = { - decompress_allocate, - deallocate, - general_purpose_bit_flags, - 20, - start, - end, - input, - end_of_input, - process -}; - -/* clang-format on */ diff --git a/ext/libzip/zip_buffer.c b/ext/libzip/zip_buffer.c deleted file mode 100644 index 8c24b27e0d..0000000000 --- a/ext/libzip/zip_buffer.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - zip_buffer.c -- bounds checked access to memory buffer - Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include "zipint.h" - -zip_uint8_t * -_zip_buffer_data(zip_buffer_t *buffer) { - return buffer->data; -} - - -void -_zip_buffer_free(zip_buffer_t *buffer) { - if (buffer == NULL) { - return; - } - - if (buffer->free_data) { - free(buffer->data); - } - - free(buffer); -} - - -bool -_zip_buffer_eof(zip_buffer_t *buffer) { - return buffer->ok && buffer->offset == buffer->size; -} - - -zip_uint8_t * -_zip_buffer_get(zip_buffer_t *buffer, zip_uint64_t length) { - zip_uint8_t *data; - - data = _zip_buffer_peek(buffer, length); - - if (data != NULL) { - buffer->offset += length; - } - - return data; -} - - -zip_uint16_t -_zip_buffer_get_16(zip_buffer_t *buffer) { - zip_uint8_t *data = _zip_buffer_get(buffer, 2); - - if (data == NULL) { - return 0; - } - - return (zip_uint16_t)(data[0] + (data[1] << 8)); -} - - -zip_uint32_t -_zip_buffer_get_32(zip_buffer_t *buffer) { - zip_uint8_t *data = _zip_buffer_get(buffer, 4); - - if (data == NULL) { - return 0; - } - - return ((((((zip_uint32_t)data[3] << 8) + data[2]) << 8) + data[1]) << 8) + data[0]; -} - - -zip_uint64_t -_zip_buffer_get_64(zip_buffer_t *buffer) { - zip_uint8_t *data = _zip_buffer_get(buffer, 8); - - if (data == NULL) { - return 0; - } - - return ((zip_uint64_t)data[7] << 56) + ((zip_uint64_t)data[6] << 48) + ((zip_uint64_t)data[5] << 40) + ((zip_uint64_t)data[4] << 32) + ((zip_uint64_t)data[3] << 24) + ((zip_uint64_t)data[2] << 16) + ((zip_uint64_t)data[1] << 8) + (zip_uint64_t)data[0]; -} - - -zip_uint8_t -_zip_buffer_get_8(zip_buffer_t *buffer) { - zip_uint8_t *data = _zip_buffer_get(buffer, 1); - - if (data == NULL) { - return 0; - } - - return data[0]; -} - - -zip_uint64_t -_zip_buffer_left(zip_buffer_t *buffer) { - return buffer->ok ? buffer->size - buffer->offset : 0; -} - - -zip_uint64_t -_zip_buffer_read(zip_buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length) { - if (_zip_buffer_left(buffer) < length) { - length = _zip_buffer_left(buffer); - } - - memcpy(data, _zip_buffer_get(buffer, length), length); - - return length; -} - - -zip_buffer_t * -_zip_buffer_new(zip_uint8_t *data, zip_uint64_t size) { - bool free_data = (data == NULL); - zip_buffer_t *buffer; - - if (data == NULL) { - if ((data = (zip_uint8_t *)malloc(size)) == NULL) { - return NULL; - } - } - - if ((buffer = (zip_buffer_t *)malloc(sizeof(*buffer))) == NULL) { - if (free_data) { - free(data); - } - return NULL; - } - - buffer->ok = true; - buffer->data = data; - buffer->size = size; - buffer->offset = 0; - buffer->free_data = free_data; - - return buffer; -} - - -zip_buffer_t * -_zip_buffer_new_from_source(zip_source_t *src, zip_uint64_t size, zip_uint8_t *buf, zip_error_t *error) { - zip_buffer_t *buffer; - - if ((buffer = _zip_buffer_new(buf, size)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; - } - - if (_zip_read(src, buffer->data, size, error) < 0) { - _zip_buffer_free(buffer); - return NULL; - } - - return buffer; -} - - -zip_uint64_t -_zip_buffer_offset(zip_buffer_t *buffer) { - return buffer->ok ? buffer->offset : 0; -} - - -bool -_zip_buffer_ok(zip_buffer_t *buffer) { - return buffer->ok; -} - - -zip_uint8_t * -_zip_buffer_peek(zip_buffer_t *buffer, zip_uint64_t length) { - zip_uint8_t *data; - - if (!buffer->ok || buffer->offset + length < length || buffer->offset + length > buffer->size) { - buffer->ok = false; - return NULL; - } - - data = buffer->data + buffer->offset; - return data; -} - -int -_zip_buffer_put(zip_buffer_t *buffer, const void *src, size_t length) { - zip_uint8_t *dst = _zip_buffer_get(buffer, length); - - if (dst == NULL) { - return -1; - } - - memcpy(dst, src, length); - return 0; -} - - -int -_zip_buffer_put_16(zip_buffer_t *buffer, zip_uint16_t i) { - zip_uint8_t *data = _zip_buffer_get(buffer, 2); - - if (data == NULL) { - return -1; - } - - data[0] = (zip_uint8_t)(i & 0xff); - data[1] = (zip_uint8_t)((i >> 8) & 0xff); - - return 0; -} - - -int -_zip_buffer_put_32(zip_buffer_t *buffer, zip_uint32_t i) { - zip_uint8_t *data = _zip_buffer_get(buffer, 4); - - if (data == NULL) { - return -1; - } - - data[0] = (zip_uint8_t)(i & 0xff); - data[1] = (zip_uint8_t)((i >> 8) & 0xff); - data[2] = (zip_uint8_t)((i >> 16) & 0xff); - data[3] = (zip_uint8_t)((i >> 24) & 0xff); - - return 0; -} - - -int -_zip_buffer_put_64(zip_buffer_t *buffer, zip_uint64_t i) { - zip_uint8_t *data = _zip_buffer_get(buffer, 8); - - if (data == NULL) { - return -1; - } - - data[0] = (zip_uint8_t)(i & 0xff); - data[1] = (zip_uint8_t)((i >> 8) & 0xff); - data[2] = (zip_uint8_t)((i >> 16) & 0xff); - data[3] = (zip_uint8_t)((i >> 24) & 0xff); - data[4] = (zip_uint8_t)((i >> 32) & 0xff); - data[5] = (zip_uint8_t)((i >> 40) & 0xff); - data[6] = (zip_uint8_t)((i >> 48) & 0xff); - data[7] = (zip_uint8_t)((i >> 56) & 0xff); - - return 0; -} - - -int -_zip_buffer_put_8(zip_buffer_t *buffer, zip_uint8_t i) { - zip_uint8_t *data = _zip_buffer_get(buffer, 1); - - if (data == NULL) { - return -1; - } - - data[0] = i; - - return 0; -} - - -int -_zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset) { - if (offset > buffer->size) { - buffer->ok = false; - return -1; - } - - buffer->ok = true; - buffer->offset = offset; - - return 0; -} - - -int -_zip_buffer_skip(zip_buffer_t *buffer, zip_uint64_t length) { - zip_uint64_t offset = buffer->offset + length; - - if (offset < buffer->offset) { - buffer->ok = false; - return -1; - } - return _zip_buffer_set_offset(buffer, offset); -} - -zip_uint64_t -_zip_buffer_size(zip_buffer_t *buffer) { - return buffer->size; -} diff --git a/ext/libzip/zip_close.c b/ext/libzip/zip_close.c deleted file mode 100644 index 816fcefa3b..0000000000 --- a/ext/libzip/zip_close.c +++ /dev/null @@ -1,703 +0,0 @@ -/* - zip_close.c -- close zip archive and update changes - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - -#include -#include -#ifdef _WIN32 -#include -#include -#endif - - -static int add_data(zip_t *, zip_source_t *, zip_dirent_t *, zip_uint32_t); -static int copy_data(zip_t *, zip_uint64_t); -static int copy_source(zip_t *, zip_source_t *, zip_int64_t); -static int write_cdir(zip_t *, const zip_filelist_t *, zip_uint64_t); -static int write_data_descriptor(zip_t *za, const zip_dirent_t *dirent, int is_zip64); - -ZIP_EXTERN int -zip_close(zip_t *za) { - zip_uint64_t i, j, survivors, unchanged_offset; - zip_int64_t off; - int error; - zip_filelist_t *filelist; - int changed; - - if (za == NULL) - return -1; - - changed = _zip_changed(za, &survivors); - - /* don't create zip files with no entries */ - if (survivors == 0) { - if ((za->open_flags & ZIP_TRUNCATE) || changed) { - if (zip_source_remove(za->src) < 0) { - if (!((zip_error_code_zip(zip_source_error(za->src)) == ZIP_ER_REMOVE) && (zip_error_code_system(zip_source_error(za->src)) == ENOENT))) { - _zip_error_set_from_source(&za->error, za->src); - return -1; - } - } - } - zip_discard(za); - return 0; - } - - if (!changed) { - zip_discard(za); - return 0; - } - - if (survivors > za->nentry) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - return -1; - } - - if ((filelist = (zip_filelist_t *)malloc(sizeof(filelist[0]) * (size_t)survivors)) == NULL) - return -1; - - unchanged_offset = ZIP_UINT64_MAX; - /* create list of files with index into original archive */ - for (i = j = 0; i < za->nentry; i++) { - if (za->entry[i].orig != NULL && ZIP_ENTRY_HAS_CHANGES(&za->entry[i])) { - unchanged_offset = ZIP_MIN(unchanged_offset, za->entry[i].orig->offset); - } - if (za->entry[i].deleted) { - continue; - } - - if (j >= survivors) { - free(filelist); - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - return -1; - } - - filelist[j].idx = i; - j++; - } - if (j < survivors) { - free(filelist); - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - return -1; - } - - if ((zip_source_supports(za->src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING)) == 0) { - unchanged_offset = 0; - } - else { - if (unchanged_offset == ZIP_UINT64_MAX) { - /* we're keeping all file data, find the end of the last one */ - zip_uint64_t last_index = ZIP_UINT64_MAX; - unchanged_offset = 0; - - for (i = 0; i < za->nentry; i++) { - if (za->entry[i].orig != NULL) { - if (za->entry[i].orig->offset >= unchanged_offset) { - unchanged_offset = za->entry[i].orig->offset; - last_index = i; - } - } - } - if (last_index != ZIP_UINT64_MAX) { - if ((unchanged_offset = _zip_file_get_end(za, last_index, &za->error)) == 0) { - free(filelist); - return -1; - } - } - } - if (unchanged_offset > 0) { - if (zip_source_begin_write_cloning(za->src, unchanged_offset) < 0) { - /* cloning not supported, need to copy everything */ - unchanged_offset = 0; - } - } - } - if (unchanged_offset == 0) { - if (zip_source_begin_write(za->src) < 0) { - _zip_error_set_from_source(&za->error, za->src); - free(filelist); - return -1; - } - } - - if (_zip_progress_start(za->progress) != 0) { - zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); - zip_source_rollback_write(za->src); - free(filelist); - return -1; - } - error = 0; - for (j = 0; j < survivors; j++) { - int new_data; - zip_entry_t *entry; - zip_dirent_t *de; - - if (_zip_progress_subrange(za->progress, (double)j / (double)survivors, (double)(j + 1) / (double)survivors) != 0) { - zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); - error = 1; - break; - } - - i = filelist[j].idx; - entry = za->entry + i; - - if (entry->orig != NULL && entry->orig->offset < unchanged_offset) { - /* already implicitly copied by cloning */ - continue; - } - - new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_ENCRYPTION_METHOD)); - - /* create new local directory entry */ - if (entry->changes == NULL) { - if ((entry->changes = _zip_dirent_clone(entry->orig)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - error = 1; - break; - } - } - de = entry->changes; - - if (_zip_read_local_ef(za, i) < 0) { - error = 1; - break; - } - - if ((off = zip_source_tell_write(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); - error = 1; - break; - } - de->offset = (zip_uint64_t)off; - - if (new_data) { - zip_source_t *zs; - - zs = NULL; - if (!ZIP_ENTRY_DATA_CHANGED(entry)) { - if ((zs = _zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, 0, NULL)) == NULL) { - error = 1; - break; - } - } - - /* add_data writes dirent */ - if (add_data(za, zs ? zs : entry->source, de, entry->changes ? entry->changes->changed : 0) < 0) { - error = 1; - if (zs) - zip_source_free(zs); - break; - } - if (zs) - zip_source_free(zs); - } - else { - zip_uint64_t offset; - - if (de->encryption_method != ZIP_EM_TRAD_PKWARE) { - /* when copying data, all sizes are known -> no data descriptor needed */ - /* except for PKWare encryption, where removing the data descriptor breaks password validation */ - de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR; - } - if (_zip_dirent_write(za, de, ZIP_FL_LOCAL) < 0) { - error = 1; - break; - } - if ((offset = _zip_file_get_offset(za, i, &za->error)) == 0) { - error = 1; - break; - } - if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) { - _zip_error_set_from_source(&za->error, za->src); - error = 1; - break; - } - if (copy_data(za, de->comp_size) < 0) { - error = 1; - break; - } - - if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) { - if (write_data_descriptor(za, de, _zip_dirent_needs_zip64(de, 0)) < 0) { - error = 1; - break; - } - } - } - } - - if (!error) { - if (write_cdir(za, filelist, survivors) < 0) - error = 1; - } - - free(filelist); - - if (!error) { - if (zip_source_commit_write(za->src) != 0) { - _zip_error_set_from_source(&za->error, za->src); - error = 1; - } - _zip_progress_end(za->progress); - } - - if (error) { - zip_source_rollback_write(za->src); - return -1; - } - - zip_discard(za); - - return 0; -} - - -static int -add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { - zip_int64_t offstart, offdata, offend, data_length; - zip_stat_t st; - zip_file_attributes_t attributes; - zip_source_t *src_final, *src_tmp; - int ret; - int is_zip64; - zip_flags_t flags; - bool needs_recompress, needs_decompress, needs_crc, needs_compress, needs_reencrypt, needs_decrypt, needs_encrypt; - - if (zip_source_stat(src, &st) < 0) { - _zip_error_set_from_source(&za->error, src); - return -1; - } - - if ((st.valid & ZIP_STAT_COMP_METHOD) == 0) { - st.valid |= ZIP_STAT_COMP_METHOD; - st.comp_method = ZIP_CM_STORE; - } - - if (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != ZIP_CM_STORE) - de->comp_method = st.comp_method; - else if (de->comp_method == ZIP_CM_STORE && (st.valid & ZIP_STAT_SIZE)) { - st.valid |= ZIP_STAT_COMP_SIZE; - st.comp_size = st.size; - } - else { - /* we'll recompress */ - st.valid &= ~ZIP_STAT_COMP_SIZE; - } - - if ((st.valid & ZIP_STAT_ENCRYPTION_METHOD) == 0) { - st.valid |= ZIP_STAT_ENCRYPTION_METHOD; - st.encryption_method = ZIP_EM_NONE; - } - - flags = ZIP_EF_LOCAL; - - if ((st.valid & ZIP_STAT_SIZE) == 0) { - flags |= ZIP_FL_FORCE_ZIP64; - data_length = -1; - } - else { - de->uncomp_size = st.size; - /* this is technically incorrect (copy_source counts compressed data), but it's the best we have */ - data_length = (zip_int64_t)st.size; - - if ((st.valid & ZIP_STAT_COMP_SIZE) == 0) { - zip_uint64_t max_size; - - switch (ZIP_CM_ACTUAL(de->comp_method)) { - case ZIP_CM_BZIP2: - /* computed by looking at increase of 10 random files of size 1MB when - * compressed with bzip2, rounded up: 1.006 */ - max_size = 4269351188u; - break; - - case ZIP_CM_DEFLATE: - /* max deflate size increase: size + ceil(size/16k)*5+6 */ - max_size = 4293656963u; - break; - - case ZIP_CM_STORE: - max_size = 0xffffffffu; - break; - - default: - max_size = 0; - } - - if (st.size > max_size) { - flags |= ZIP_FL_FORCE_ZIP64; - } - } - else - de->comp_size = st.comp_size; - } - - if ((offstart = zip_source_tell_write(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); - return -1; - } - - /* as long as we don't support non-seekable output, clear data descriptor bit */ - de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR; - if ((is_zip64 = _zip_dirent_write(za, de, flags)) < 0) { - return -1; - } - - needs_recompress = st.comp_method != ZIP_CM_ACTUAL(de->comp_method); - needs_decompress = needs_recompress && (st.comp_method != ZIP_CM_STORE); - needs_crc = (st.comp_method == ZIP_CM_STORE) || needs_decompress; - needs_compress = needs_recompress && (de->comp_method != ZIP_CM_STORE); - - needs_reencrypt = needs_recompress || (de->changed & ZIP_DIRENT_PASSWORD) || (de->encryption_method != st.encryption_method); - needs_decrypt = needs_reencrypt && (st.encryption_method != ZIP_EM_NONE); - needs_encrypt = needs_reencrypt && (de->encryption_method != ZIP_EM_NONE); - - src_final = src; - zip_source_keep(src_final); - - if (needs_decrypt) { - zip_encryption_implementation impl; - - if ((impl = _zip_get_encryption_implementation(st.encryption_method, ZIP_CODEC_DECODE)) == NULL) { - zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); - zip_source_free(src_final); - return -1; - } - if ((src_tmp = impl(za, src_final, st.encryption_method, ZIP_CODEC_DECODE, za->default_password)) == NULL) { - /* error set by impl */ - zip_source_free(src_final); - return -1; - } - - zip_source_free(src_final); - src_final = src_tmp; - } - - if (needs_decompress) { - if ((src_tmp = zip_source_decompress(za, src_final, st.comp_method)) == NULL) { - zip_source_free(src_final); - return -1; - } - - zip_source_free(src_final); - src_final = src_tmp; - } - - if (needs_crc) { - if ((src_tmp = zip_source_crc(za, src_final, 0)) == NULL) { - zip_source_free(src_final); - return -1; - } - - zip_source_free(src_final); - src_final = src_tmp; - } - - if (needs_compress) { - if ((src_tmp = zip_source_compress(za, src_final, de->comp_method, de->compression_level)) == NULL) { - zip_source_free(src_final); - return -1; - } - - zip_source_free(src_final); - src_final = src_tmp; - } - - - if (needs_encrypt) { - zip_encryption_implementation impl; - const char *password = NULL; - - if (de->password) { - password = de->password; - } - else if (za->default_password) { - password = za->default_password; - } - - if ((impl = _zip_get_encryption_implementation(de->encryption_method, ZIP_CODEC_ENCODE)) == NULL) { - zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); - zip_source_free(src_final); - return -1; - } - if ((src_tmp = impl(za, src_final, de->encryption_method, ZIP_CODEC_ENCODE, password)) == NULL) { - /* error set by impl */ - zip_source_free(src_final); - return -1; - } - if (de->encryption_method == ZIP_EM_TRAD_PKWARE) { - de->bitflags |= ZIP_GPBF_DATA_DESCRIPTOR; - } - - zip_source_free(src_final); - src_final = src_tmp; - } - - - if ((offdata = zip_source_tell_write(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); - return -1; - } - - ret = copy_source(za, src_final, data_length); - - if (zip_source_stat(src_final, &st) < 0) { - _zip_error_set_from_source(&za->error, src_final); - ret = -1; - } - - if (zip_source_get_file_attributes(src_final, &attributes) != 0) { - _zip_error_set_from_source(&za->error, src_final); - ret = -1; - } - - zip_source_free(src_final); - - if (ret < 0) { - return -1; - } - - if ((offend = zip_source_tell_write(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); - return -1; - } - - if (zip_source_seek_write(za->src, offstart, SEEK_SET) < 0) { - _zip_error_set_from_source(&za->error, za->src); - return -1; - } - - if ((st.valid & (ZIP_STAT_COMP_METHOD | ZIP_STAT_CRC | ZIP_STAT_SIZE)) != (ZIP_STAT_COMP_METHOD | ZIP_STAT_CRC | ZIP_STAT_SIZE)) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - return -1; - } - - if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) { - if (st.valid & ZIP_STAT_MTIME) - de->last_mod = st.mtime; - else - time(&de->last_mod); - } - de->comp_method = st.comp_method; - de->crc = st.crc; - de->uncomp_size = st.size; - de->comp_size = (zip_uint64_t)(offend - offdata); - _zip_dirent_apply_attributes(de, &attributes, (flags & ZIP_FL_FORCE_ZIP64) != 0, changed); - - if ((ret = _zip_dirent_write(za, de, flags)) < 0) - return -1; - - if (is_zip64 != ret) { - /* Zip64 mismatch between preliminary file header written before data and final file header written afterwards */ - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - return -1; - } - - if (zip_source_seek_write(za->src, offend, SEEK_SET) < 0) { - _zip_error_set_from_source(&za->error, za->src); - return -1; - } - - if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) { - if (write_data_descriptor(za, de, is_zip64) < 0) { - return -1; - } - } - - return 0; -} - - -static int -copy_data(zip_t *za, zip_uint64_t len) { - DEFINE_BYTE_ARRAY(buf, BUFSIZE); - size_t n; - double total = (double)len; - - if (!byte_array_init(buf, BUFSIZE)) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - - while (len > 0) { - n = len > BUFSIZE ? BUFSIZE : len; - if (_zip_read(za->src, buf, n, &za->error) < 0) { - byte_array_fini(buf); - return -1; - } - - if (_zip_write(za, buf, n) < 0) { - byte_array_fini(buf); - return -1; - } - - len -= n; - - if (_zip_progress_update(za->progress, (total - (double)len) / total) != 0) { - zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); - return -1; - } - } - - byte_array_fini(buf); - return 0; -} - - -static int -copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) { - DEFINE_BYTE_ARRAY(buf, BUFSIZE); - zip_int64_t n, current; - int ret; - - if (zip_source_open(src) < 0) { - _zip_error_set_from_source(&za->error, src); - return -1; - } - - if (!byte_array_init(buf, BUFSIZE)) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - - ret = 0; - current = 0; - while ((n = zip_source_read(src, buf, BUFSIZE)) > 0) { - if (_zip_write(za, buf, (zip_uint64_t)n) < 0) { - ret = -1; - break; - } - if (n == BUFSIZE && za->progress && data_length > 0) { - current += n; - if (_zip_progress_update(za->progress, (double)current / (double)data_length) != 0) { - zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); - ret = -1; - break; - } - } - } - - if (n < 0) { - _zip_error_set_from_source(&za->error, src); - ret = -1; - } - - byte_array_fini(buf); - - zip_source_close(src); - - return ret; -} - -static int -write_cdir(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors) { - zip_int64_t cd_start, end, size; - - if ((cd_start = zip_source_tell_write(za->src)) < 0) { - return -1; - } - - if ((size = _zip_cdir_write(za, filelist, survivors)) < 0) { - return -1; - } - - if ((end = zip_source_tell_write(za->src)) < 0) { - return -1; - } - - return 0; -} - - -int -_zip_changed(const zip_t *za, zip_uint64_t *survivorsp) { - int changed; - zip_uint64_t i, survivors; - - changed = 0; - survivors = 0; - - if (za->comment_changed || za->ch_flags != za->flags) { - changed = 1; - } - - for (i = 0; i < za->nentry; i++) { - if (ZIP_ENTRY_HAS_CHANGES(&za->entry[i])) { - changed = 1; - } - if (!za->entry[i].deleted) { - survivors++; - } - } - - if (survivorsp) { - *survivorsp = survivors; - } - - return changed; -} - -static int -write_data_descriptor(zip_t *za, const zip_dirent_t *de, int is_zip64) { - zip_buffer_t *buffer = _zip_buffer_new(NULL, MAX_DATA_DESCRIPTOR_LENGTH); - int ret = 0; - - if (buffer == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - - _zip_buffer_put(buffer, DATADES_MAGIC, 4); - _zip_buffer_put_32(buffer, de->crc); - if (is_zip64) { - _zip_buffer_put_64(buffer, de->comp_size); - _zip_buffer_put_64(buffer, de->uncomp_size); - } - else { - _zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size); - _zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size); - } - - if (!_zip_buffer_ok(buffer)) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - ret = -1; - } - else { - ret = _zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer)); - } - - _zip_buffer_free(buffer); - - return ret; -} diff --git a/ext/libzip/zip_delete.c b/ext/libzip/zip_delete.c deleted file mode 100644 index 97701a01d6..0000000000 --- a/ext/libzip/zip_delete.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - zip_delete.c -- delete file from zip archive - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN int -zip_delete(zip_t *za, zip_uint64_t idx) { - const char *name; - - if (idx >= za->nentry) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (ZIP_IS_RDONLY(za)) { - zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - if ((name = _zip_get_name(za, idx, 0, &za->error)) == NULL) { - return -1; - } - - if (!_zip_hash_delete(za->names, (const zip_uint8_t *)name, &za->error)) { - return -1; - } - - /* allow duplicate file names, because the file will - * be removed directly afterwards */ - if (_zip_unchange(za, idx, 1) != 0) - return -1; - - za->entry[idx].deleted = 1; - - return 0; -} diff --git a/ext/libzip/zip_dir_add.c b/ext/libzip/zip_dir_add.c deleted file mode 100644 index c40b1cb9af..0000000000 --- a/ext/libzip/zip_dir_add.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - zip_dir_add.c -- add directory - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include -#include - -#include "zipint.h" - - -/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */ - -ZIP_EXTERN zip_int64_t -zip_dir_add(zip_t *za, const char *name, zip_flags_t flags) { - size_t len; - zip_int64_t idx; - char *s; - zip_source_t *source; - - if (ZIP_IS_RDONLY(za)) { - zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - if (name == NULL) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - s = NULL; - len = strlen(name); - - if (name[len - 1] != '/') { - if ((s = (char *)malloc(len + 2)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - strcpy(s, name); - s[len] = '/'; - s[len + 1] = '\0'; - } - - if ((source = zip_source_buffer(za, NULL, 0, 0)) == NULL) { - free(s); - return -1; - } - - idx = _zip_file_replace(za, ZIP_UINT64_MAX, s ? s : name, source, flags); - - free(s); - - if (idx < 0) - zip_source_free(source); - else { - if (zip_file_set_external_attributes(za, (zip_uint64_t)idx, 0, ZIP_OPSYS_DEFAULT, ZIP_EXT_ATTRIB_DEFAULT_DIR) < 0) { - zip_delete(za, (zip_uint64_t)idx); - return -1; - } - } - - return idx; -} diff --git a/ext/libzip/zip_dirent.c b/ext/libzip/zip_dirent.c deleted file mode 100644 index 1691071fed..0000000000 --- a/ext/libzip/zip_dirent.c +++ /dev/null @@ -1,1163 +0,0 @@ -/* - zip_dirent.c -- read directory entry (local or central), clean dirent - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include -#include -#include -#include -#include - -#include "zipint.h" - -static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str); -static zip_extra_field_t *_zip_ef_utf8(zip_uint16_t, zip_string_t *, zip_error_t *); -static bool _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error); - - -void -_zip_cdir_free(zip_cdir_t *cd) { - zip_uint64_t i; - - if (!cd) - return; - - for (i = 0; i < cd->nentry; i++) - _zip_entry_finalize(cd->entry + i); - free(cd->entry); - _zip_string_free(cd->comment); - free(cd); -} - - -zip_cdir_t * -_zip_cdir_new(zip_uint64_t nentry, zip_error_t *error) { - zip_cdir_t *cd; - - if ((cd = (zip_cdir_t *)malloc(sizeof(*cd))) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; - } - - cd->entry = NULL; - cd->nentry = cd->nentry_alloc = 0; - cd->size = cd->offset = 0; - cd->comment = NULL; - cd->is_zip64 = false; - - if (!_zip_cdir_grow(cd, nentry, error)) { - _zip_cdir_free(cd); - return NULL; - } - - return cd; -} - - -bool -_zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *error) { - zip_uint64_t i, new_alloc; - zip_entry_t *new_entry; - - if (additional_entries == 0) { - return true; - } - - new_alloc = cd->nentry_alloc + additional_entries; - - if (new_alloc < additional_entries || new_alloc > SIZE_MAX / sizeof(*(cd->entry))) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return false; - } - - if ((new_entry = (zip_entry_t *)realloc(cd->entry, sizeof(*(cd->entry)) * (size_t)new_alloc)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return false; - } - - cd->entry = new_entry; - - for (i = cd->nentry; i < new_alloc; i++) { - _zip_entry_init(cd->entry + i); - } - - cd->nentry = cd->nentry_alloc = new_alloc; - - return true; -} - - -zip_int64_t -_zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors) { - zip_uint64_t offset, size; - zip_string_t *comment; - zip_uint8_t buf[EOCDLEN + EOCD64LEN + EOCD64LOCLEN]; - zip_buffer_t *buffer; - zip_int64_t off; - zip_uint64_t i; - bool is_zip64; - int ret; - - if ((off = zip_source_tell_write(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); - return -1; - } - offset = (zip_uint64_t)off; - - is_zip64 = false; - - for (i = 0; i < survivors; i++) { - zip_entry_t *entry = za->entry + filelist[i].idx; - - if ((ret = _zip_dirent_write(za, entry->changes ? entry->changes : entry->orig, ZIP_FL_CENTRAL)) < 0) - return -1; - if (ret) - is_zip64 = true; - } - - if ((off = zip_source_tell_write(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); - return -1; - } - size = (zip_uint64_t)off - offset; - - if (offset > ZIP_UINT32_MAX || survivors > ZIP_UINT16_MAX) - is_zip64 = true; - - - if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - - if (is_zip64) { - _zip_buffer_put(buffer, EOCD64_MAGIC, 4); - _zip_buffer_put_64(buffer, EOCD64LEN - 12); - _zip_buffer_put_16(buffer, 45); - _zip_buffer_put_16(buffer, 45); - _zip_buffer_put_32(buffer, 0); - _zip_buffer_put_32(buffer, 0); - _zip_buffer_put_64(buffer, survivors); - _zip_buffer_put_64(buffer, survivors); - _zip_buffer_put_64(buffer, size); - _zip_buffer_put_64(buffer, offset); - _zip_buffer_put(buffer, EOCD64LOC_MAGIC, 4); - _zip_buffer_put_32(buffer, 0); - _zip_buffer_put_64(buffer, offset + size); - _zip_buffer_put_32(buffer, 1); - } - - _zip_buffer_put(buffer, EOCD_MAGIC, 4); - _zip_buffer_put_32(buffer, 0); - _zip_buffer_put_16(buffer, (zip_uint16_t)(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors)); - _zip_buffer_put_16(buffer, (zip_uint16_t)(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors)); - _zip_buffer_put_32(buffer, size >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)size); - _zip_buffer_put_32(buffer, offset >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)offset); - - comment = za->comment_changed ? za->comment_changes : za->comment_orig; - - _zip_buffer_put_16(buffer, (zip_uint16_t)(comment ? comment->length : 0)); - - if (!_zip_buffer_ok(buffer)) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - _zip_buffer_free(buffer); - return -1; - } - - if (_zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer)) < 0) { - _zip_buffer_free(buffer); - return -1; - } - - _zip_buffer_free(buffer); - - if (comment) { - if (_zip_write(za, comment->raw, comment->length) < 0) { - return -1; - } - } - - return (zip_int64_t)size; -} - - -zip_dirent_t * -_zip_dirent_clone(const zip_dirent_t *sde) { - zip_dirent_t *tde; - - if ((tde = (zip_dirent_t *)malloc(sizeof(*tde))) == NULL) - return NULL; - - if (sde) - memcpy(tde, sde, sizeof(*sde)); - else - _zip_dirent_init(tde); - - tde->changed = 0; - tde->cloned = 1; - - return tde; -} - - -void -_zip_dirent_finalize(zip_dirent_t *zde) { - if (!zde->cloned || zde->changed & ZIP_DIRENT_FILENAME) { - _zip_string_free(zde->filename); - zde->filename = NULL; - } - if (!zde->cloned || zde->changed & ZIP_DIRENT_EXTRA_FIELD) { - _zip_ef_free(zde->extra_fields); - zde->extra_fields = NULL; - } - if (!zde->cloned || zde->changed & ZIP_DIRENT_COMMENT) { - _zip_string_free(zde->comment); - zde->comment = NULL; - } - if (!zde->cloned || zde->changed & ZIP_DIRENT_PASSWORD) { - if (zde->password) { - _zip_crypto_clear(zde->password, strlen(zde->password)); - } - free(zde->password); - zde->password = NULL; - } -} - - -void -_zip_dirent_free(zip_dirent_t *zde) { - if (zde == NULL) - return; - - _zip_dirent_finalize(zde); - free(zde); -} - - -void -_zip_dirent_init(zip_dirent_t *de) { - de->changed = 0; - de->local_extra_fields_read = 0; - de->cloned = 0; - - de->crc_valid = true; - de->version_madeby = 63 | (ZIP_OPSYS_DEFAULT << 8); - de->version_needed = 10; /* 1.0 */ - de->bitflags = 0; - de->comp_method = ZIP_CM_DEFAULT; - de->last_mod = 0; - de->crc = 0; - de->comp_size = 0; - de->uncomp_size = 0; - de->filename = NULL; - de->extra_fields = NULL; - de->comment = NULL; - de->disk_number = 0; - de->int_attrib = 0; - de->ext_attrib = ZIP_EXT_ATTRIB_DEFAULT; - de->offset = 0; - de->compression_level = 0; - de->encryption_method = ZIP_EM_NONE; - de->password = NULL; -} - - -bool -_zip_dirent_needs_zip64(const zip_dirent_t *de, zip_flags_t flags) { - if (de->uncomp_size >= ZIP_UINT32_MAX || de->comp_size >= ZIP_UINT32_MAX || ((flags & ZIP_FL_CENTRAL) && de->offset >= ZIP_UINT32_MAX)) - return true; - - return false; -} - - -zip_dirent_t * -_zip_dirent_new(void) { - zip_dirent_t *de; - - if ((de = (zip_dirent_t *)malloc(sizeof(*de))) == NULL) - return NULL; - - _zip_dirent_init(de); - return de; -} - - -/* _zip_dirent_read(zde, fp, bufp, left, localp, error): - Fills the zip directory entry zde. - - If buffer is non-NULL, data is taken from there; otherwise data is read from fp as needed. - - If local is true, it reads a local header instead of a central directory entry. - - Returns size of dirent read if successful. On error, error is filled in and -1 is returned. -*/ - -zip_int64_t -_zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_error_t *error) { - zip_uint8_t buf[CDENTRYSIZE]; - zip_uint16_t dostime, dosdate; - zip_uint32_t size, variable_size; - zip_uint16_t filename_len, comment_len, ef_len; - - bool from_buffer = (buffer != NULL); - - size = local ? LENTRYSIZE : CDENTRYSIZE; - - if (buffer) { - if (_zip_buffer_left(buffer) < size) { - zip_error_set(error, ZIP_ER_NOZIP, 0); - return -1; - } - } - else { - if ((buffer = _zip_buffer_new_from_source(src, size, buf, error)) == NULL) { - return -1; - } - } - - if (memcmp(_zip_buffer_get(buffer, 4), (local ? LOCAL_MAGIC : CENTRAL_MAGIC), 4) != 0) { - zip_error_set(error, ZIP_ER_NOZIP, 0); - if (!from_buffer) { - _zip_buffer_free(buffer); - } - return -1; - } - - /* convert buffercontents to zip_dirent */ - - _zip_dirent_init(zde); - if (!local) - zde->version_madeby = _zip_buffer_get_16(buffer); - else - zde->version_madeby = 0; - zde->version_needed = _zip_buffer_get_16(buffer); - zde->bitflags = _zip_buffer_get_16(buffer); - zde->comp_method = _zip_buffer_get_16(buffer); - - /* convert to time_t */ - dostime = _zip_buffer_get_16(buffer); - dosdate = _zip_buffer_get_16(buffer); - zde->last_mod = _zip_d2u_time(dostime, dosdate); - - zde->crc = _zip_buffer_get_32(buffer); - zde->comp_size = _zip_buffer_get_32(buffer); - zde->uncomp_size = _zip_buffer_get_32(buffer); - - filename_len = _zip_buffer_get_16(buffer); - ef_len = _zip_buffer_get_16(buffer); - - if (local) { - comment_len = 0; - zde->disk_number = 0; - zde->int_attrib = 0; - zde->ext_attrib = 0; - zde->offset = 0; - } - else { - comment_len = _zip_buffer_get_16(buffer); - zde->disk_number = _zip_buffer_get_16(buffer); - zde->int_attrib = _zip_buffer_get_16(buffer); - zde->ext_attrib = _zip_buffer_get_32(buffer); - zde->offset = _zip_buffer_get_32(buffer); - } - - if (!_zip_buffer_ok(buffer)) { - zip_error_set(error, ZIP_ER_INTERNAL, 0); - if (!from_buffer) { - _zip_buffer_free(buffer); - } - return -1; - } - - if (zde->bitflags & ZIP_GPBF_ENCRYPTED) { - if (zde->bitflags & ZIP_GPBF_STRONG_ENCRYPTION) { - /* TODO */ - zde->encryption_method = ZIP_EM_UNKNOWN; - } - else { - zde->encryption_method = ZIP_EM_TRAD_PKWARE; - } - } - else { - zde->encryption_method = ZIP_EM_NONE; - } - - zde->filename = NULL; - zde->extra_fields = NULL; - zde->comment = NULL; - - variable_size = (zip_uint32_t)filename_len + (zip_uint32_t)ef_len + (zip_uint32_t)comment_len; - - if (from_buffer) { - if (_zip_buffer_left(buffer) < variable_size) { - zip_error_set(error, ZIP_ER_INCONS, 0); - return -1; - } - } - else { - _zip_buffer_free(buffer); - - if ((buffer = _zip_buffer_new_from_source(src, variable_size, NULL, error)) == NULL) { - return -1; - } - } - - if (filename_len) { - zde->filename = _zip_read_string(buffer, src, filename_len, 1, error); - if (!zde->filename) { - if (zip_error_code_zip(error) == ZIP_ER_EOF) { - zip_error_set(error, ZIP_ER_INCONS, 0); - } - if (!from_buffer) { - _zip_buffer_free(buffer); - } - return -1; - } - - if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) { - if (_zip_guess_encoding(zde->filename, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) { - zip_error_set(error, ZIP_ER_INCONS, 0); - if (!from_buffer) { - _zip_buffer_free(buffer); - } - return -1; - } - } - } - - if (ef_len) { - zip_uint8_t *ef = _zip_read_data(buffer, src, ef_len, 0, error); - - if (ef == NULL) { - if (!from_buffer) { - _zip_buffer_free(buffer); - } - return -1; - } - if (!_zip_ef_parse(ef, ef_len, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, &zde->extra_fields, error)) { - free(ef); - if (!from_buffer) { - _zip_buffer_free(buffer); - } - return -1; - } - free(ef); - if (local) - zde->local_extra_fields_read = 1; - } - - if (comment_len) { - zde->comment = _zip_read_string(buffer, src, comment_len, 0, error); - if (!zde->comment) { - if (!from_buffer) { - _zip_buffer_free(buffer); - } - return -1; - } - if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) { - if (_zip_guess_encoding(zde->comment, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) { - zip_error_set(error, ZIP_ER_INCONS, 0); - if (!from_buffer) { - _zip_buffer_free(buffer); - } - return -1; - } - } - } - - zde->filename = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_NAME, zde->filename); - zde->comment = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_COMMENT, zde->comment); - - /* Zip64 */ - - if (zde->uncomp_size == ZIP_UINT32_MAX || zde->comp_size == ZIP_UINT32_MAX || zde->offset == ZIP_UINT32_MAX) { - zip_uint16_t got_len; - zip_buffer_t *ef_buffer; - const zip_uint8_t *ef = _zip_ef_get_by_id(zde->extra_fields, &got_len, ZIP_EF_ZIP64, 0, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, error); - /* TODO: if got_len == 0 && !ZIP64_EOCD: no error, 0xffffffff is valid value */ - if (ef == NULL) { - if (!from_buffer) { - _zip_buffer_free(buffer); - } - return -1; - } - - if ((ef_buffer = _zip_buffer_new((zip_uint8_t *)ef, got_len)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - if (!from_buffer) { - _zip_buffer_free(buffer); - } - return -1; - } - - if (zde->uncomp_size == ZIP_UINT32_MAX) { - zde->uncomp_size = _zip_buffer_get_64(ef_buffer); - } - else if (local) { - /* From appnote.txt: This entry in the Local header MUST - include BOTH original and compressed file size fields. */ - (void)_zip_buffer_skip(ef_buffer, 8); /* error is caught by _zip_buffer_eof() call */ - } - if (zde->comp_size == ZIP_UINT32_MAX) { - zde->comp_size = _zip_buffer_get_64(ef_buffer); - } - if (!local) { - if (zde->offset == ZIP_UINT32_MAX) { - zde->offset = _zip_buffer_get_64(ef_buffer); - } - if (zde->disk_number == ZIP_UINT16_MAX) { - zde->disk_number = _zip_buffer_get_32(ef_buffer); - } - } - - if (!_zip_buffer_eof(ef_buffer)) { - /* accept additional fields if values match */ - bool ok = true; - switch (got_len) { - case 28: - _zip_buffer_set_offset(ef_buffer, 24); - if (zde->disk_number != _zip_buffer_get_32(ef_buffer)) { - ok = false; - } - /* fallthrough */ - case 24: - _zip_buffer_set_offset(ef_buffer, 0); - if ((zde->uncomp_size != _zip_buffer_get_64(ef_buffer)) || (zde->comp_size != _zip_buffer_get_64(ef_buffer)) || (zde->offset != _zip_buffer_get_64(ef_buffer))) { - ok = false; - } - break; - - default: - ok = false; - } - if (!ok) { - zip_error_set(error, ZIP_ER_INCONS, 0); - _zip_buffer_free(ef_buffer); - if (!from_buffer) { - _zip_buffer_free(buffer); - } - return -1; - } - } - _zip_buffer_free(ef_buffer); - } - - if (!_zip_buffer_ok(buffer)) { - zip_error_set(error, ZIP_ER_INTERNAL, 0); - if (!from_buffer) { - _zip_buffer_free(buffer); - } - return -1; - } - if (!from_buffer) { - _zip_buffer_free(buffer); - } - - /* zip_source_seek / zip_source_tell don't support values > ZIP_INT64_MAX */ - if (zde->offset > ZIP_INT64_MAX) { - zip_error_set(error, ZIP_ER_SEEK, EFBIG); - return -1; - } - - if (!_zip_dirent_process_winzip_aes(zde, error)) { - return -1; - } - - zde->extra_fields = _zip_ef_remove_internal(zde->extra_fields); - - return (zip_int64_t)size + (zip_int64_t)variable_size; -} - - -static zip_string_t * -_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str) { - zip_uint16_t ef_len; - zip_uint32_t ef_crc; - zip_buffer_t *buffer; - - const zip_uint8_t *ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, id, 0, ZIP_EF_BOTH, NULL); - - if (ef == NULL || ef_len < 5 || ef[0] != 1) { - return str; - } - - if ((buffer = _zip_buffer_new((zip_uint8_t *)ef, ef_len)) == NULL) { - return str; - } - - _zip_buffer_get_8(buffer); - ef_crc = _zip_buffer_get_32(buffer); - - if (_zip_string_crc32(str) == ef_crc) { - zip_uint16_t len = (zip_uint16_t)_zip_buffer_left(buffer); - zip_string_t *ef_str = _zip_string_new(_zip_buffer_get(buffer, len), len, ZIP_FL_ENC_UTF_8, NULL); - - if (ef_str != NULL) { - _zip_string_free(str); - str = ef_str; - } - } - - _zip_buffer_free(buffer); - - return str; -} - - -static bool -_zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error) { - zip_uint16_t ef_len; - zip_buffer_t *buffer; - const zip_uint8_t *ef; - bool crc_valid; - zip_uint16_t enc_method; - - - if (de->comp_method != ZIP_CM_WINZIP_AES) { - return true; - } - - ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, ZIP_EF_WINZIP_AES, 0, ZIP_EF_BOTH, NULL); - - if (ef == NULL || ef_len < 7) { - zip_error_set(error, ZIP_ER_INCONS, 0); - return false; - } - - if ((buffer = _zip_buffer_new((zip_uint8_t *)ef, ef_len)) == NULL) { - zip_error_set(error, ZIP_ER_INTERNAL, 0); - return false; - } - - /* version */ - - crc_valid = true; - switch (_zip_buffer_get_16(buffer)) { - case 1: - break; - - case 2: - if (de->uncomp_size < 20 /* TODO: constant */) { - crc_valid = false; - } - break; - - default: - zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0); - _zip_buffer_free(buffer); - return false; - } - - /* vendor */ - if (memcmp(_zip_buffer_get(buffer, 2), "AE", 2) != 0) { - zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0); - _zip_buffer_free(buffer); - return false; - } - - /* mode */ - switch (_zip_buffer_get_8(buffer)) { - case 1: - enc_method = ZIP_EM_AES_128; - break; - case 2: - enc_method = ZIP_EM_AES_192; - break; - case 3: - enc_method = ZIP_EM_AES_256; - break; - default: - zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0); - _zip_buffer_free(buffer); - return false; - } - - if (ef_len != 7) { - zip_error_set(error, ZIP_ER_INCONS, 0); - _zip_buffer_free(buffer); - return false; - } - - de->crc_valid = crc_valid; - de->encryption_method = enc_method; - de->comp_method = _zip_buffer_get_16(buffer); - - _zip_buffer_free(buffer); - return true; -} - - -zip_int32_t -_zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error) { - zip_int32_t size; - bool local = (flags & ZIP_EF_LOCAL) != 0; - int i; - zip_uint8_t b[6]; - zip_buffer_t *buffer; - - size = local ? LENTRYSIZE : CDENTRYSIZE; - - if (zip_source_seek(src, local ? 26 : 28, SEEK_CUR) < 0) { - _zip_error_set_from_source(error, src); - return -1; - } - - if ((buffer = _zip_buffer_new_from_source(src, local ? 4 : 6, b, error)) == NULL) { - return -1; - } - - for (i = 0; i < (local ? 2 : 3); i++) { - size += _zip_buffer_get_16(buffer); - } - - if (!_zip_buffer_eof(buffer)) { - zip_error_set(error, ZIP_ER_INTERNAL, 0); - _zip_buffer_free(buffer); - return -1; - } - - _zip_buffer_free(buffer); - return size; -} - - -/* _zip_dirent_write - Writes zip directory entry. - - If flags & ZIP_EF_LOCAL, it writes a local header instead of a central - directory entry. If flags & ZIP_EF_FORCE_ZIP64, a ZIP64 extra field is written, even if not needed. - - Returns 0 if successful, 1 if successful and wrote ZIP64 extra field. On error, error is filled in and -1 is - returned. -*/ - -int -_zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) { - zip_uint16_t dostime, dosdate; - zip_encoding_type_t com_enc, name_enc; - zip_extra_field_t *ef; - zip_extra_field_t *ef64; - zip_uint32_t ef_total_size; - bool is_zip64; - bool is_really_zip64; - bool is_winzip_aes; - zip_uint8_t buf[CDENTRYSIZE]; - zip_buffer_t *buffer; - - ef = NULL; - - name_enc = _zip_guess_encoding(de->filename, ZIP_ENCODING_UNKNOWN); - com_enc = _zip_guess_encoding(de->comment, ZIP_ENCODING_UNKNOWN); - - if ((name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_ASCII) || (name_enc == ZIP_ENCODING_ASCII && com_enc == ZIP_ENCODING_UTF8_KNOWN) || (name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_UTF8_KNOWN)) - de->bitflags |= ZIP_GPBF_ENCODING_UTF_8; - else { - de->bitflags &= (zip_uint16_t)~ZIP_GPBF_ENCODING_UTF_8; - if (name_enc == ZIP_ENCODING_UTF8_KNOWN) { - ef = _zip_ef_utf8(ZIP_EF_UTF_8_NAME, de->filename, &za->error); - if (ef == NULL) - return -1; - } - if ((flags & ZIP_FL_LOCAL) == 0 && com_enc == ZIP_ENCODING_UTF8_KNOWN) { - zip_extra_field_t *ef2 = _zip_ef_utf8(ZIP_EF_UTF_8_COMMENT, de->comment, &za->error); - if (ef2 == NULL) { - _zip_ef_free(ef); - return -1; - } - ef2->next = ef; - ef = ef2; - } - } - - if (de->encryption_method == ZIP_EM_NONE) { - de->bitflags &= (zip_uint16_t)~ZIP_GPBF_ENCRYPTED; - } - else { - de->bitflags |= (zip_uint16_t)ZIP_GPBF_ENCRYPTED; - } - - is_really_zip64 = _zip_dirent_needs_zip64(de, flags); - is_zip64 = (flags & (ZIP_FL_LOCAL | ZIP_FL_FORCE_ZIP64)) == (ZIP_FL_LOCAL | ZIP_FL_FORCE_ZIP64) || is_really_zip64; - is_winzip_aes = de->encryption_method == ZIP_EM_AES_128 || de->encryption_method == ZIP_EM_AES_192 || de->encryption_method == ZIP_EM_AES_256; - - if (is_zip64) { - zip_uint8_t ef_zip64[EFZIP64SIZE]; - zip_buffer_t *ef_buffer = _zip_buffer_new(ef_zip64, sizeof(ef_zip64)); - if (ef_buffer == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - _zip_ef_free(ef); - return -1; - } - - if (flags & ZIP_FL_LOCAL) { - if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX) { - _zip_buffer_put_64(ef_buffer, de->uncomp_size); - _zip_buffer_put_64(ef_buffer, de->comp_size); - } - } - else { - if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX || de->offset > ZIP_UINT32_MAX) { - if (de->uncomp_size >= ZIP_UINT32_MAX) { - _zip_buffer_put_64(ef_buffer, de->uncomp_size); - } - if (de->comp_size >= ZIP_UINT32_MAX) { - _zip_buffer_put_64(ef_buffer, de->comp_size); - } - if (de->offset >= ZIP_UINT32_MAX) { - _zip_buffer_put_64(ef_buffer, de->offset); - } - } - } - - if (!_zip_buffer_ok(ef_buffer)) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - _zip_buffer_free(ef_buffer); - _zip_ef_free(ef); - return -1; - } - - ef64 = _zip_ef_new(ZIP_EF_ZIP64, (zip_uint16_t)(_zip_buffer_offset(ef_buffer)), ef_zip64, ZIP_EF_BOTH); - _zip_buffer_free(ef_buffer); - ef64->next = ef; - ef = ef64; - } - - if (is_winzip_aes) { - zip_uint8_t data[EF_WINZIP_AES_SIZE]; - zip_buffer_t *ef_buffer = _zip_buffer_new(data, sizeof(data)); - zip_extra_field_t *ef_winzip; - - if (ef_buffer == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - _zip_ef_free(ef); - return -1; - } - - _zip_buffer_put_16(ef_buffer, 2); - _zip_buffer_put(ef_buffer, "AE", 2); - _zip_buffer_put_8(ef_buffer, (zip_uint8_t)(de->encryption_method & 0xff)); - _zip_buffer_put_16(ef_buffer, (zip_uint16_t)de->comp_method); - - if (!_zip_buffer_ok(ef_buffer)) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - _zip_buffer_free(ef_buffer); - _zip_ef_free(ef); - return -1; - } - - ef_winzip = _zip_ef_new(ZIP_EF_WINZIP_AES, EF_WINZIP_AES_SIZE, data, ZIP_EF_BOTH); - _zip_buffer_free(ef_buffer); - ef_winzip->next = ef; - ef = ef_winzip; - } - - if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - _zip_ef_free(ef); - return -1; - } - - _zip_buffer_put(buffer, (flags & ZIP_FL_LOCAL) ? LOCAL_MAGIC : CENTRAL_MAGIC, 4); - - if ((flags & ZIP_FL_LOCAL) == 0) { - _zip_buffer_put_16(buffer, de->version_madeby); - } - _zip_buffer_put_16(buffer, ZIP_MAX(is_really_zip64 ? 45 : 0, de->version_needed)); - _zip_buffer_put_16(buffer, de->bitflags); - if (is_winzip_aes) { - _zip_buffer_put_16(buffer, ZIP_CM_WINZIP_AES); - } - else { - _zip_buffer_put_16(buffer, (zip_uint16_t)de->comp_method); - } - - _zip_u2d_time(de->last_mod, &dostime, &dosdate); - _zip_buffer_put_16(buffer, dostime); - _zip_buffer_put_16(buffer, dosdate); - - if (is_winzip_aes && de->uncomp_size < 20) { - _zip_buffer_put_32(buffer, 0); - } - else { - _zip_buffer_put_32(buffer, de->crc); - } - - if (((flags & ZIP_FL_LOCAL) == ZIP_FL_LOCAL) && ((de->comp_size >= ZIP_UINT32_MAX) || (de->uncomp_size >= ZIP_UINT32_MAX))) { - /* In local headers, if a ZIP64 EF is written, it MUST contain - * both compressed and uncompressed sizes (even if one of the - * two is smaller than 0xFFFFFFFF); on the other hand, those - * may only appear when the corresponding standard entry is - * 0xFFFFFFFF. (appnote.txt 4.5.3) */ - _zip_buffer_put_32(buffer, ZIP_UINT32_MAX); - _zip_buffer_put_32(buffer, ZIP_UINT32_MAX); - } - else { - if (de->comp_size < ZIP_UINT32_MAX) { - _zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size); - } - else { - _zip_buffer_put_32(buffer, ZIP_UINT32_MAX); - } - if (de->uncomp_size < ZIP_UINT32_MAX) { - _zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size); - } - else { - _zip_buffer_put_32(buffer, ZIP_UINT32_MAX); - } - } - - _zip_buffer_put_16(buffer, _zip_string_length(de->filename)); - /* TODO: check for overflow */ - ef_total_size = (zip_uint32_t)_zip_ef_size(de->extra_fields, flags) + (zip_uint32_t)_zip_ef_size(ef, ZIP_EF_BOTH); - _zip_buffer_put_16(buffer, (zip_uint16_t)ef_total_size); - - if ((flags & ZIP_FL_LOCAL) == 0) { - _zip_buffer_put_16(buffer, _zip_string_length(de->comment)); - _zip_buffer_put_16(buffer, (zip_uint16_t)de->disk_number); - _zip_buffer_put_16(buffer, de->int_attrib); - _zip_buffer_put_32(buffer, de->ext_attrib); - if (de->offset < ZIP_UINT32_MAX) - _zip_buffer_put_32(buffer, (zip_uint32_t)de->offset); - else - _zip_buffer_put_32(buffer, ZIP_UINT32_MAX); - } - - if (!_zip_buffer_ok(buffer)) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - _zip_buffer_free(buffer); - _zip_ef_free(ef); - return -1; - } - - if (_zip_write(za, buf, _zip_buffer_offset(buffer)) < 0) { - _zip_buffer_free(buffer); - _zip_ef_free(ef); - return -1; - } - - _zip_buffer_free(buffer); - - if (de->filename) { - if (_zip_string_write(za, de->filename) < 0) { - _zip_ef_free(ef); - return -1; - } - } - - if (ef) { - if (_zip_ef_write(za, ef, ZIP_EF_BOTH) < 0) { - _zip_ef_free(ef); - return -1; - } - } - _zip_ef_free(ef); - if (de->extra_fields) { - if (_zip_ef_write(za, de->extra_fields, flags) < 0) { - return -1; - } - } - - if ((flags & ZIP_FL_LOCAL) == 0) { - if (de->comment) { - if (_zip_string_write(za, de->comment) < 0) { - return -1; - } - } - } - - - return is_zip64; -} - - -time_t -_zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate) { - struct tm tm; - - memset(&tm, 0, sizeof(tm)); - - /* let mktime decide if DST is in effect */ - tm.tm_isdst = -1; - - tm.tm_year = ((ddate >> 9) & 127) + 1980 - 1900; - tm.tm_mon = ((ddate >> 5) & 15) - 1; - tm.tm_mday = ddate & 31; - - tm.tm_hour = (dtime >> 11) & 31; - tm.tm_min = (dtime >> 5) & 63; - tm.tm_sec = (dtime << 1) & 62; - - return mktime(&tm); -} - - -static zip_extra_field_t * -_zip_ef_utf8(zip_uint16_t id, zip_string_t *str, zip_error_t *error) { - const zip_uint8_t *raw; - zip_uint32_t len; - zip_buffer_t *buffer; - zip_extra_field_t *ef; - - if ((raw = _zip_string_get(str, &len, ZIP_FL_ENC_RAW, NULL)) == NULL) { - /* error already set */ - return NULL; - } - - if (len + 5 > ZIP_UINT16_MAX) { - zip_error_set(error, ZIP_ER_INVAL, 0); /* TODO: better error code? */ - return NULL; - } - - if ((buffer = _zip_buffer_new(NULL, len + 5)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; - } - - _zip_buffer_put_8(buffer, 1); - _zip_buffer_put_32(buffer, _zip_string_crc32(str)); - _zip_buffer_put(buffer, raw, len); - - if (!_zip_buffer_ok(buffer)) { - zip_error_set(error, ZIP_ER_INTERNAL, 0); - _zip_buffer_free(buffer); - return NULL; - } - - ef = _zip_ef_new(id, (zip_uint16_t)(_zip_buffer_offset(buffer)), _zip_buffer_data(buffer), ZIP_EF_BOTH); - _zip_buffer_free(buffer); - - return ef; -} - - -zip_dirent_t * -_zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error) { - if (error == NULL) - error = &za->error; - - if (idx >= za->nentry) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - if ((flags & ZIP_FL_UNCHANGED) || za->entry[idx].changes == NULL) { - if (za->entry[idx].orig == NULL) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - if (za->entry[idx].deleted && (flags & ZIP_FL_UNCHANGED) == 0) { - zip_error_set(error, ZIP_ER_DELETED, 0); - return NULL; - } - return za->entry[idx].orig; - } - else - return za->entry[idx].changes; -} - - -void -_zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) { - struct tm *tpm; - -#ifdef HAVE_LOCALTIME_R - struct tm tm; - tpm = localtime_r(&intime, &tm); -#else - tpm = localtime(&intime); -#endif - if (tpm == NULL) { - /* if localtime() fails, return an arbitrary date (1980-01-01 00:00:00) */ - *ddate = (1 << 5) + 1; - *dtime = 0; - return; - } - if (tpm->tm_year < 80) { - tpm->tm_year = 80; - } - - *ddate = (zip_uint16_t)(((tpm->tm_year + 1900 - 1980) << 9) + ((tpm->tm_mon + 1) << 5) + tpm->tm_mday); - *dtime = (zip_uint16_t)(((tpm->tm_hour) << 11) + ((tpm->tm_min) << 5) + ((tpm->tm_sec) >> 1)); - - return; -} - - -void -_zip_dirent_apply_attributes(zip_dirent_t *de, zip_file_attributes_t *attributes, bool force_zip64, zip_uint32_t changed) { - zip_uint16_t length; - - if (attributes->valid & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS) { - zip_uint16_t mask = attributes->general_purpose_bit_mask & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK; - de->bitflags = (de->bitflags & ~mask) | (attributes->general_purpose_bit_flags & mask); - } - if (attributes->valid & ZIP_FILE_ATTRIBUTES_ASCII) { - de->int_attrib = (de->int_attrib & ~0x1) | (attributes->ascii ? 1 : 0); - } - /* manually set attributes are preferred over attributes provided by source */ - if ((changed & ZIP_DIRENT_ATTRIBUTES) == 0 && (attributes->valid & ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES)) { - de->ext_attrib = attributes->external_file_attributes; - } - - if (de->comp_method == ZIP_CM_LZMA) { - de->version_needed = 63; - } - else if (de->encryption_method == ZIP_EM_AES_128 || de->encryption_method == ZIP_EM_AES_192 || de->encryption_method == ZIP_EM_AES_256) { - de->version_needed = 51; - } - else if (de->comp_method == ZIP_CM_BZIP2) { - de->version_needed = 46; - } - else if (force_zip64 || _zip_dirent_needs_zip64(de, 0)) { - de->version_needed = 45; - } - else if (de->comp_method == ZIP_CM_DEFLATE || de->encryption_method == ZIP_EM_TRAD_PKWARE) { - de->version_needed = 20; - } - else if ((length = _zip_string_length(de->filename)) > 0 && de->filename->raw[length - 1] == '/') { - de->version_needed = 20; - } - else { - de->version_needed = 10; - } - - if (attributes->valid & ZIP_FILE_ATTRIBUTES_VERSION_NEEDED) { - de->version_needed = ZIP_MAX(de->version_needed, attributes->version_needed); - } - - de->version_madeby = 63 | (de->version_madeby & 0xff00); - if ((changed & ZIP_DIRENT_ATTRIBUTES) == 0 && (attributes->valid & ZIP_FILE_ATTRIBUTES_HOST_SYSTEM)) { - de->version_madeby = (de->version_madeby & 0xff) | (zip_uint16_t)(attributes->host_system << 8); - } -} diff --git a/ext/libzip/zip_discard.c b/ext/libzip/zip_discard.c deleted file mode 100644 index 12f0636724..0000000000 --- a/ext/libzip/zip_discard.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - zip_discard.c -- discard and free struct zip - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include - -#include "zipint.h" - - -/* zip_discard: - frees the space allocated to a zipfile struct, and closes the - corresponding file. */ - -void -zip_discard(zip_t *za) { - zip_uint64_t i; - - if (za == NULL) - return; - - if (za->src) { - zip_source_close(za->src); - zip_source_free(za->src); - } - - free(za->default_password); - _zip_string_free(za->comment_orig); - _zip_string_free(za->comment_changes); - - _zip_hash_free(za->names); - - if (za->entry) { - for (i = 0; i < za->nentry; i++) - _zip_entry_finalize(za->entry + i); - free(za->entry); - } - - for (i = 0; i < za->nopen_source; i++) { - _zip_source_invalidate(za->open_source[i]); - } - free(za->open_source); - - _zip_progress_free(za->progress); - - zip_error_fini(&za->error); - - free(za); - - return; -} diff --git a/ext/libzip/zip_entry.c b/ext/libzip/zip_entry.c deleted file mode 100644 index 52ecaef916..0000000000 --- a/ext/libzip/zip_entry.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - zip_entry.c -- struct zip_entry helper functions - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - -void -_zip_entry_finalize(zip_entry_t *e) { - _zip_unchange_data(e); - _zip_dirent_free(e->orig); - _zip_dirent_free(e->changes); -} - - -void -_zip_entry_init(zip_entry_t *e) { - e->orig = NULL; - e->changes = NULL; - e->source = NULL; - e->deleted = 0; -} diff --git a/ext/libzip/zip_err_str.c b/ext/libzip/zip_err_str.c deleted file mode 100644 index c46258b4ac..0000000000 --- a/ext/libzip/zip_err_str.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - This file was generated automatically by CMake - from zip.h; make changes there. -*/ - -#include "zipint.h" - -const char * const _zip_err_str[] = { - "No error", - "Multi-disk zip archives not supported", - "Renaming temporary file failed", - "Closing zip archive failed", - "Seek error", - "Read error", - "Write error", - "CRC error", - "Containing zip archive was closed", - "No such file", - "File already exists", - "Can't open file", - "Failure to create temporary file", - "Zlib error", - "Malloc failure", - "Entry has been changed", - "Compression method not supported", - "Premature end of file", - "Invalid argument", - "Not a zip archive", - "Internal error", - "Zip archive inconsistent", - "Can't remove file", - "Entry has been deleted", - "Encryption method not supported", - "Read-only archive", - "No password provided", - "Wrong password provided", - "Operation not supported", - "Resource still in use", - "Tell error", - "Compressed data invalid", - "Operation cancelled", -}; - -const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]); - -#define N ZIP_ET_NONE -#define S ZIP_ET_SYS -#define Z ZIP_ET_ZLIB - -const int _zip_err_type[] = { - N, - N, - S, - S, - S, - S, - S, - N, - N, - N, - N, - S, - S, - Z, - N, - N, - N, - N, - N, - N, - N, - N, - S, - N, - N, - N, - N, - N, - N, - N, - S, - N, - N, -}; diff --git a/ext/libzip/zip_error.c b/ext/libzip/zip_error.c deleted file mode 100644 index a0f74f022d..0000000000 --- a/ext/libzip/zip_error.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - zip_error.c -- zip_error_t helper functions - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include - -#include "zipint.h" - - -ZIP_EXTERN int -zip_error_code_system(const zip_error_t *error) { - return error->sys_err; -} - - -ZIP_EXTERN int -zip_error_code_zip(const zip_error_t *error) { - return error->zip_err; -} - - -ZIP_EXTERN void -zip_error_fini(zip_error_t *err) { - free(err->str); - err->str = NULL; -} - - -ZIP_EXTERN void -zip_error_init(zip_error_t *err) { - err->zip_err = ZIP_ER_OK; - err->sys_err = 0; - err->str = NULL; -} - -ZIP_EXTERN void -zip_error_init_with_code(zip_error_t *error, int ze) { - zip_error_init(error); - error->zip_err = ze; - switch (zip_error_system_type(error)) { - case ZIP_ET_SYS: - error->sys_err = errno; - break; - - default: - error->sys_err = 0; - break; - } -} - - -ZIP_EXTERN int -zip_error_system_type(const zip_error_t *error) { - if (error->zip_err < 0 || error->zip_err >= _zip_nerr_str) - return ZIP_ET_NONE; - - return _zip_err_type[error->zip_err]; -} - - -void -_zip_error_clear(zip_error_t *err) { - if (err == NULL) - return; - - err->zip_err = ZIP_ER_OK; - err->sys_err = 0; -} - - -void -_zip_error_copy(zip_error_t *dst, const zip_error_t *src) { - if (dst == NULL) { - return; - } - - dst->zip_err = src->zip_err; - dst->sys_err = src->sys_err; -} - - -void -_zip_error_get(const zip_error_t *err, int *zep, int *sep) { - if (zep) - *zep = err->zip_err; - if (sep) { - if (zip_error_system_type(err) != ZIP_ET_NONE) - *sep = err->sys_err; - else - *sep = 0; - } -} - - -void -zip_error_set(zip_error_t *err, int ze, int se) { - if (err) { - err->zip_err = ze; - err->sys_err = se; - } -} - - -void -_zip_error_set_from_source(zip_error_t *err, zip_source_t *src) { - _zip_error_copy(err, zip_source_error(src)); -} - - -zip_int64_t -zip_error_to_data(const zip_error_t *error, void *data, zip_uint64_t length) { - int *e = (int *)data; - - if (length < sizeof(int) * 2) { - return -1; - } - - e[0] = zip_error_code_zip(error); - e[1] = zip_error_code_system(error); - return sizeof(int) * 2; -} diff --git a/ext/libzip/zip_error_clear.c b/ext/libzip/zip_error_clear.c deleted file mode 100644 index eec1568ff2..0000000000 --- a/ext/libzip/zip_error_clear.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - zip_error_clear.c -- clear zip error - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN void -zip_error_clear(zip_t *za) { - if (za == NULL) - return; - - _zip_error_clear(&za->error); -} diff --git a/ext/libzip/zip_error_get.c b/ext/libzip/zip_error_get.c deleted file mode 100644 index 9588b4c4a5..0000000000 --- a/ext/libzip/zip_error_get.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - zip_error_get.c -- get zip error - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#define _ZIP_COMPILING_DEPRECATED -#include "zipint.h" - - -ZIP_EXTERN void -zip_error_get(zip_t *za, int *zep, int *sep) { - _zip_error_get(&za->error, zep, sep); -} - - -ZIP_EXTERN zip_error_t * -zip_get_error(zip_t *za) { - return &za->error; -} - - -ZIP_EXTERN zip_error_t * -zip_file_get_error(zip_file_t *f) { - return &f->error; -} diff --git a/ext/libzip/zip_error_get_sys_type.c b/ext/libzip/zip_error_get_sys_type.c deleted file mode 100644 index 3dfe5c26d4..0000000000 --- a/ext/libzip/zip_error_get_sys_type.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - zip_error_get_sys_type.c -- return type of system error code - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#define _ZIP_COMPILING_DEPRECATED -#include "zipint.h" - - -ZIP_EXTERN int -zip_error_get_sys_type(int ze) { - if (ze < 0 || ze >= _zip_nerr_str) - return 0; - - return _zip_err_type[ze]; -} diff --git a/ext/libzip/zip_error_strerror.c b/ext/libzip/zip_error_strerror.c deleted file mode 100644 index 93b24eab17..0000000000 --- a/ext/libzip/zip_error_strerror.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - zip_error_sterror.c -- get string representation of struct zip_error - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include -#include -#include -#include - -#include "zipint.h" - - -ZIP_EXTERN const char * -zip_error_strerror(zip_error_t *err) { - const char *zs, *ss; - char buf[128], *s; - - zip_error_fini(err); - - if (err->zip_err < 0 || err->zip_err >= _zip_nerr_str) { - sprintf(buf, "Unknown error %d", err->zip_err); - zs = NULL; - ss = buf; - } - else { - zs = _zip_err_str[err->zip_err]; - - switch (_zip_err_type[err->zip_err]) { - case ZIP_ET_SYS: - ss = strerror(err->sys_err); - break; - - case ZIP_ET_ZLIB: - ss = zError(err->sys_err); - break; - - default: - ss = NULL; - } - } - - if (ss == NULL) - return zs; - else { - if ((s = (char *)malloc(strlen(ss) + (zs ? strlen(zs) + 2 : 0) + 1)) == NULL) - return _zip_err_str[ZIP_ER_MEMORY]; - - sprintf(s, "%s%s%s", (zs ? zs : ""), (zs ? ": " : ""), ss); - err->str = s; - - return s; - } -} diff --git a/ext/libzip/zip_error_to_str.c b/ext/libzip/zip_error_to_str.c deleted file mode 100644 index 34a3331fb8..0000000000 --- a/ext/libzip/zip_error_to_str.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - zip_error_to_str.c -- get string representation of zip error code - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include -#include -#include - -#define _ZIP_COMPILING_DEPRECATED -#include "zipint.h" - - -ZIP_EXTERN int -zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se) { - const char *zs, *ss; - - if (ze < 0 || ze >= _zip_nerr_str) - return snprintf(buf, len, "Unknown error %d", ze); - - zs = _zip_err_str[ze]; - - switch (_zip_err_type[ze]) { - case ZIP_ET_SYS: - ss = strerror(se); - break; - - case ZIP_ET_ZLIB: - ss = zError(se); - break; - - default: - ss = NULL; - } - - return snprintf(buf, len, "%s%s%s", zs, (ss ? ": " : ""), (ss ? ss : "")); -} diff --git a/ext/libzip/zip_extra_field.c b/ext/libzip/zip_extra_field.c deleted file mode 100644 index 7114a2510f..0000000000 --- a/ext/libzip/zip_extra_field.c +++ /dev/null @@ -1,426 +0,0 @@ -/* - zip_extra_field.c -- manipulate extra fields - Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include - -#include "zipint.h" - - -zip_extra_field_t * -_zip_ef_clone(const zip_extra_field_t *ef, zip_error_t *error) { - zip_extra_field_t *head, *prev, *def; - - head = prev = NULL; - - while (ef) { - if ((def = _zip_ef_new(ef->id, ef->size, ef->data, ef->flags)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - _zip_ef_free(head); - return NULL; - } - - if (head == NULL) - head = def; - if (prev) - prev->next = def; - prev = def; - - ef = ef->next; - } - - return head; -} - - -zip_extra_field_t * -_zip_ef_delete_by_id(zip_extra_field_t *ef, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags) { - zip_extra_field_t *head, *prev; - int i; - - i = 0; - head = ef; - prev = NULL; - for (; ef; ef = (prev ? prev->next : head)) { - if ((ef->flags & flags & ZIP_EF_BOTH) && ((ef->id == id) || (id == ZIP_EXTRA_FIELD_ALL))) { - if (id_idx == ZIP_EXTRA_FIELD_ALL || i == id_idx) { - ef->flags &= ~(flags & ZIP_EF_BOTH); - if ((ef->flags & ZIP_EF_BOTH) == 0) { - if (prev) - prev->next = ef->next; - else - head = ef->next; - ef->next = NULL; - _zip_ef_free(ef); - - if (id_idx == ZIP_EXTRA_FIELD_ALL) - continue; - } - } - - i++; - if (i > id_idx) - break; - } - prev = ef; - } - - return head; -} - - -void -_zip_ef_free(zip_extra_field_t *ef) { - zip_extra_field_t *ef2; - - while (ef) { - ef2 = ef->next; - free(ef->data); - free(ef); - ef = ef2; - } -} - - -const zip_uint8_t * -_zip_ef_get_by_id(const zip_extra_field_t *ef, zip_uint16_t *lenp, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags, zip_error_t *error) { - static const zip_uint8_t empty[1] = {'\0'}; - - int i; - - i = 0; - for (; ef; ef = ef->next) { - if (ef->id == id && (ef->flags & flags & ZIP_EF_BOTH)) { - if (i < id_idx) { - i++; - continue; - } - - if (lenp) - *lenp = ef->size; - if (ef->size > 0) - return ef->data; - else - return empty; - } - } - - zip_error_set(error, ZIP_ER_NOENT, 0); - return NULL; -} - - -zip_extra_field_t * -_zip_ef_merge(zip_extra_field_t *to, zip_extra_field_t *from) { - zip_extra_field_t *ef2, *tt, *tail; - int duplicate; - - if (to == NULL) - return from; - - for (tail = to; tail->next; tail = tail->next) - ; - - for (; from; from = ef2) { - ef2 = from->next; - - duplicate = 0; - for (tt = to; tt; tt = tt->next) { - if (tt->id == from->id && tt->size == from->size && (tt->size == 0 || memcmp(tt->data, from->data, tt->size) == 0)) { - tt->flags |= (from->flags & ZIP_EF_BOTH); - duplicate = 1; - break; - } - } - - from->next = NULL; - if (duplicate) - _zip_ef_free(from); - else - tail = tail->next = from; - } - - return to; -} - - -zip_extra_field_t * -_zip_ef_new(zip_uint16_t id, zip_uint16_t size, const zip_uint8_t *data, zip_flags_t flags) { - zip_extra_field_t *ef; - - if ((ef = (zip_extra_field_t *)malloc(sizeof(*ef))) == NULL) - return NULL; - - ef->next = NULL; - ef->flags = flags; - ef->id = id; - ef->size = size; - if (size > 0) { - if ((ef->data = (zip_uint8_t *)_zip_memdup(data, size, NULL)) == NULL) { - free(ef); - return NULL; - } - } - else - ef->data = NULL; - - return ef; -} - - -bool -_zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, zip_extra_field_t **ef_head_p, zip_error_t *error) { - zip_buffer_t *buffer; - zip_extra_field_t *ef, *ef2, *ef_head; - - if ((buffer = _zip_buffer_new((zip_uint8_t *)data, len)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return false; - } - - ef_head = ef = NULL; - - while (_zip_buffer_ok(buffer) && _zip_buffer_left(buffer) >= 4) { - zip_uint16_t fid, flen; - zip_uint8_t *ef_data; - - fid = _zip_buffer_get_16(buffer); - flen = _zip_buffer_get_16(buffer); - ef_data = _zip_buffer_get(buffer, flen); - - if (ef_data == NULL) { - zip_error_set(error, ZIP_ER_INCONS, 0); - _zip_buffer_free(buffer); - _zip_ef_free(ef_head); - return false; - } - - if ((ef2 = _zip_ef_new(fid, flen, ef_data, flags)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - _zip_buffer_free(buffer); - _zip_ef_free(ef_head); - return false; - } - - if (ef_head) { - ef->next = ef2; - ef = ef2; - } - else - ef_head = ef = ef2; - } - - if (!_zip_buffer_eof(buffer)) { - /* Android APK files align stored file data with padding in extra fields; ignore. */ - /* see https://android.googlesource.com/platform/build/+/master/tools/zipalign/ZipAlign.cpp */ - size_t glen = _zip_buffer_left(buffer); - zip_uint8_t *garbage; - garbage = _zip_buffer_get(buffer, glen); - if (glen >= 4 || garbage == NULL || memcmp(garbage, "\0\0\0", glen) != 0) { - zip_error_set(error, ZIP_ER_INCONS, 0); - _zip_buffer_free(buffer); - _zip_ef_free(ef_head); - return false; - } - } - - _zip_buffer_free(buffer); - - if (ef_head_p) { - *ef_head_p = ef_head; - } - else { - _zip_ef_free(ef_head); - } - - return true; -} - - -zip_extra_field_t * -_zip_ef_remove_internal(zip_extra_field_t *ef) { - zip_extra_field_t *ef_head; - zip_extra_field_t *prev, *next; - - ef_head = ef; - prev = NULL; - - while (ef) { - if (ZIP_EF_IS_INTERNAL(ef->id)) { - next = ef->next; - if (ef_head == ef) - ef_head = next; - ef->next = NULL; - _zip_ef_free(ef); - if (prev) - prev->next = next; - ef = next; - } - else { - prev = ef; - ef = ef->next; - } - } - - return ef_head; -} - - -zip_uint16_t -_zip_ef_size(const zip_extra_field_t *ef, zip_flags_t flags) { - zip_uint16_t size; - - size = 0; - for (; ef; ef = ef->next) { - if (ef->flags & flags & ZIP_EF_BOTH) - size = (zip_uint16_t)(size + 4 + ef->size); - } - - return size; -} - - -int -_zip_ef_write(zip_t *za, const zip_extra_field_t *ef, zip_flags_t flags) { - zip_uint8_t b[4]; - zip_buffer_t *buffer = _zip_buffer_new(b, sizeof(b)); - - if (buffer == NULL) { - return -1; - } - - for (; ef; ef = ef->next) { - if (ef->flags & flags & ZIP_EF_BOTH) { - _zip_buffer_set_offset(buffer, 0); - _zip_buffer_put_16(buffer, ef->id); - _zip_buffer_put_16(buffer, ef->size); - if (!_zip_buffer_ok(buffer)) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - _zip_buffer_free(buffer); - return -1; - } - if (_zip_write(za, b, 4) < 0) { - _zip_buffer_free(buffer); - return -1; - } - if (ef->size > 0) { - if (_zip_write(za, ef->data, ef->size) < 0) { - _zip_buffer_free(buffer); - return -1; - } - } - } - } - - _zip_buffer_free(buffer); - return 0; -} - - -int -_zip_read_local_ef(zip_t *za, zip_uint64_t idx) { - zip_entry_t *e; - unsigned char b[4]; - zip_buffer_t *buffer; - zip_uint16_t fname_len, ef_len; - - if (idx >= za->nentry) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - e = za->entry + idx; - - if (e->orig == NULL || e->orig->local_extra_fields_read) - return 0; - - if (e->orig->offset + 26 > ZIP_INT64_MAX) { - zip_error_set(&za->error, ZIP_ER_SEEK, EFBIG); - return -1; - } - - if (zip_source_seek(za->src, (zip_int64_t)(e->orig->offset + 26), SEEK_SET) < 0) { - _zip_error_set_from_source(&za->error, za->src); - return -1; - } - - if ((buffer = _zip_buffer_new_from_source(za->src, sizeof(b), b, &za->error)) == NULL) { - return -1; - } - - fname_len = _zip_buffer_get_16(buffer); - ef_len = _zip_buffer_get_16(buffer); - - if (!_zip_buffer_eof(buffer)) { - _zip_buffer_free(buffer); - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - return -1; - } - - _zip_buffer_free(buffer); - - if (ef_len > 0) { - zip_extra_field_t *ef; - zip_uint8_t *ef_raw; - - if (zip_source_seek(za->src, fname_len, SEEK_CUR) < 0) { - zip_error_set(&za->error, ZIP_ER_SEEK, errno); - return -1; - } - - ef_raw = _zip_read_data(NULL, za->src, ef_len, 0, &za->error); - - if (ef_raw == NULL) - return -1; - - if (!_zip_ef_parse(ef_raw, ef_len, ZIP_EF_LOCAL, &ef, &za->error)) { - free(ef_raw); - return -1; - } - free(ef_raw); - - if (ef) { - ef = _zip_ef_remove_internal(ef); - e->orig->extra_fields = _zip_ef_merge(e->orig->extra_fields, ef); - } - } - - e->orig->local_extra_fields_read = 1; - - if (e->changes && e->changes->local_extra_fields_read == 0) { - e->changes->extra_fields = e->orig->extra_fields; - e->changes->local_extra_fields_read = 1; - } - - return 0; -} diff --git a/ext/libzip/zip_extra_field_api.c b/ext/libzip/zip_extra_field_api.c deleted file mode 100644 index 605f95d0f1..0000000000 --- a/ext/libzip/zip_extra_field_api.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - zip_extra_field_api.c -- public extra fields API functions - Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN int -zip_file_extra_field_delete(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_flags_t flags) { - zip_dirent_t *de; - - if ((flags & ZIP_EF_BOTH) == 0) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (((flags & ZIP_EF_BOTH) == ZIP_EF_BOTH) && (ef_idx != ZIP_EXTRA_FIELD_ALL)) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (_zip_get_dirent(za, idx, 0, NULL) == NULL) - return -1; - - if (ZIP_IS_RDONLY(za)) { - zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - if (_zip_file_extra_field_prepare_for_change(za, idx) < 0) - return -1; - - de = za->entry[idx].changes; - - de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ZIP_EXTRA_FIELD_ALL, ef_idx, flags); - return 0; -} - - -ZIP_EXTERN int -zip_file_extra_field_delete_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_flags_t flags) { - zip_dirent_t *de; - - if ((flags & ZIP_EF_BOTH) == 0) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (((flags & ZIP_EF_BOTH) == ZIP_EF_BOTH) && (ef_idx != ZIP_EXTRA_FIELD_ALL)) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (_zip_get_dirent(za, idx, 0, NULL) == NULL) - return -1; - - if (ZIP_IS_RDONLY(za)) { - zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - if (_zip_file_extra_field_prepare_for_change(za, idx) < 0) - return -1; - - de = za->entry[idx].changes; - - de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ef_id, ef_idx, flags); - return 0; -} - - -ZIP_EXTERN const zip_uint8_t * -zip_file_extra_field_get(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_uint16_t *idp, zip_uint16_t *lenp, zip_flags_t flags) { - static const zip_uint8_t empty[1] = {'\0'}; - - zip_dirent_t *de; - zip_extra_field_t *ef; - int i; - - if ((flags & ZIP_EF_BOTH) == 0) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } - - if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL) - return NULL; - - if (flags & ZIP_FL_LOCAL) - if (_zip_read_local_ef(za, idx) < 0) - return NULL; - - i = 0; - for (ef = de->extra_fields; ef; ef = ef->next) { - if (ef->flags & flags & ZIP_EF_BOTH) { - if (i < ef_idx) { - i++; - continue; - } - - if (idp) - *idp = ef->id; - if (lenp) - *lenp = ef->size; - if (ef->size > 0) - return ef->data; - else - return empty; - } - } - - zip_error_set(&za->error, ZIP_ER_NOENT, 0); - return NULL; -} - - -ZIP_EXTERN const zip_uint8_t * -zip_file_extra_field_get_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_uint16_t *lenp, zip_flags_t flags) { - zip_dirent_t *de; - - if ((flags & ZIP_EF_BOTH) == 0) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } - - if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL) - return NULL; - - if (flags & ZIP_FL_LOCAL) - if (_zip_read_local_ef(za, idx) < 0) - return NULL; - - return _zip_ef_get_by_id(de->extra_fields, lenp, ef_id, ef_idx, flags, &za->error); -} - - -ZIP_EXTERN zip_int16_t -zip_file_extra_fields_count(zip_t *za, zip_uint64_t idx, zip_flags_t flags) { - zip_dirent_t *de; - zip_extra_field_t *ef; - zip_uint16_t n; - - if ((flags & ZIP_EF_BOTH) == 0) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL) - return -1; - - if (flags & ZIP_FL_LOCAL) - if (_zip_read_local_ef(za, idx) < 0) - return -1; - - n = 0; - for (ef = de->extra_fields; ef; ef = ef->next) - if (ef->flags & flags & ZIP_EF_BOTH) - n++; - - return (zip_int16_t)n; -} - - -ZIP_EXTERN zip_int16_t -zip_file_extra_fields_count_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_flags_t flags) { - zip_dirent_t *de; - zip_extra_field_t *ef; - zip_uint16_t n; - - if ((flags & ZIP_EF_BOTH) == 0) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL) - return -1; - - if (flags & ZIP_FL_LOCAL) - if (_zip_read_local_ef(za, idx) < 0) - return -1; - - n = 0; - for (ef = de->extra_fields; ef; ef = ef->next) - if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH)) - n++; - - return (zip_int16_t)n; -} - - -ZIP_EXTERN int -zip_file_extra_field_set(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags) { - zip_dirent_t *de; - zip_uint16_t ls, cs; - zip_extra_field_t *ef, *ef_prev, *ef_new; - int i, found, new_len; - - if ((flags & ZIP_EF_BOTH) == 0) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (_zip_get_dirent(za, idx, 0, NULL) == NULL) - return -1; - - if (ZIP_IS_RDONLY(za)) { - zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - if (ZIP_EF_IS_INTERNAL(ef_id)) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (_zip_file_extra_field_prepare_for_change(za, idx) < 0) - return -1; - - de = za->entry[idx].changes; - - ef = de->extra_fields; - ef_prev = NULL; - i = 0; - found = 0; - - for (; ef; ef = ef->next) { - if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH)) { - if (i == ef_idx) { - found = 1; - break; - } - i++; - } - ef_prev = ef; - } - - if (i < ef_idx && ef_idx != ZIP_EXTRA_FIELD_NEW) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (flags & ZIP_EF_LOCAL) - ls = _zip_ef_size(de->extra_fields, ZIP_EF_LOCAL); - else - ls = 0; - if (flags & ZIP_EF_CENTRAL) - cs = _zip_ef_size(de->extra_fields, ZIP_EF_CENTRAL); - else - cs = 0; - - new_len = ls > cs ? ls : cs; - if (found) - new_len -= ef->size + 4; - new_len += len + 4; - - if (new_len > ZIP_UINT16_MAX) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if ((ef_new = _zip_ef_new(ef_id, len, data, flags)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - - if (found) { - if ((ef->flags & ZIP_EF_BOTH) == (flags & ZIP_EF_BOTH)) { - ef_new->next = ef->next; - ef->next = NULL; - _zip_ef_free(ef); - if (ef_prev) - ef_prev->next = ef_new; - else - de->extra_fields = ef_new; - } - else { - ef->flags &= ~(flags & ZIP_EF_BOTH); - ef_new->next = ef->next; - ef->next = ef_new; - } - } - else if (ef_prev) { - ef_new->next = ef_prev->next; - ef_prev->next = ef_new; - } - else - de->extra_fields = ef_new; - - return 0; -} - - -int -_zip_file_extra_field_prepare_for_change(zip_t *za, zip_uint64_t idx) { - zip_entry_t *e; - - if (idx >= za->nentry) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - e = za->entry + idx; - - if (e->changes && (e->changes->changed & ZIP_DIRENT_EXTRA_FIELD)) - return 0; - - if (e->orig) { - if (_zip_read_local_ef(za, idx) < 0) - return -1; - } - - if (e->changes == NULL) { - if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - } - - if (e->orig && e->orig->extra_fields) { - if ((e->changes->extra_fields = _zip_ef_clone(e->orig->extra_fields, &za->error)) == NULL) - return -1; - } - e->changes->changed |= ZIP_DIRENT_EXTRA_FIELD; - - return 0; -} diff --git a/ext/libzip/zip_fclose.c b/ext/libzip/zip_fclose.c deleted file mode 100644 index 6eb9dc910e..0000000000 --- a/ext/libzip/zip_fclose.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - zip_fclose.c -- close file in zip archive - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include - -#include "zipint.h" - - -ZIP_EXTERN int -zip_fclose(zip_file_t *zf) { - int ret; - - if (zf->src) - zip_source_free(zf->src); - - ret = 0; - if (zf->error.zip_err) - ret = zf->error.zip_err; - - zip_error_fini(&zf->error); - free(zf); - return ret; -} diff --git a/ext/libzip/zip_fdopen.c b/ext/libzip/zip_fdopen.c deleted file mode 100644 index 5a732cd41a..0000000000 --- a/ext/libzip/zip_fdopen.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - zip_fdopen.c -- open read-only archive from file descriptor - Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" -#ifdef HAVE_UNISTD_H -#include -#endif - - -ZIP_EXTERN zip_t * -zip_fdopen(int fd_orig, int _flags, int *zep) { - int fd; - FILE *fp; - zip_t *za; - zip_source_t *src; - struct zip_error error; - - if (_flags < 0 || (_flags & ~(ZIP_CHECKCONS | ZIP_RDONLY))) { - _zip_set_open_error(zep, NULL, ZIP_ER_INVAL); - return NULL; - } - - /* We dup() here to avoid messing with the passed in fd. - We could not restore it to the original state in case of error. */ - - if ((fd = dup(fd_orig)) < 0) { - _zip_set_open_error(zep, NULL, ZIP_ER_OPEN); - return NULL; - } - - if ((fp = fdopen(fd, "rb")) == NULL) { - close(fd); - _zip_set_open_error(zep, NULL, ZIP_ER_OPEN); - return NULL; - } - - zip_error_init(&error); - if ((src = zip_source_filep_create(fp, 0, -1, &error)) == NULL) { - fclose(fp); - _zip_set_open_error(zep, &error, 0); - zip_error_fini(&error); - return NULL; - } - - if ((za = zip_open_from_source(src, _flags, &error)) == NULL) { - zip_source_free(src); - _zip_set_open_error(zep, &error, 0); - zip_error_fini(&error); - return NULL; - } - - zip_error_fini(&error); - close(fd_orig); - return za; -} diff --git a/ext/libzip/zip_file_add.c b/ext/libzip/zip_file_add.c deleted file mode 100644 index c019d8dd7d..0000000000 --- a/ext/libzip/zip_file_add.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - zip_file_add.c -- add file via callback function - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - -/* - NOTE: Return type is signed so we can return -1 on error. - The index can not be larger than ZIP_INT64_MAX since the size - of the central directory cannot be larger than - ZIP_UINT64_MAX, and each entry is larger than 2 bytes. -*/ - -ZIP_EXTERN zip_int64_t -zip_file_add(zip_t *za, const char *name, zip_source_t *source, zip_flags_t flags) { - if (name == NULL || source == NULL) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - return _zip_file_replace(za, ZIP_UINT64_MAX, name, source, flags); -} diff --git a/ext/libzip/zip_file_error_clear.c b/ext/libzip/zip_file_error_clear.c deleted file mode 100644 index 47e5da63ab..0000000000 --- a/ext/libzip/zip_file_error_clear.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - zip_file_error_clear.c -- clear zip file error - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN void -zip_file_error_clear(zip_file_t *zf) { - if (zf == NULL) - return; - - _zip_error_clear(&zf->error); -} diff --git a/ext/libzip/zip_file_error_get.c b/ext/libzip/zip_file_error_get.c deleted file mode 100644 index 1ed68df195..0000000000 --- a/ext/libzip/zip_file_error_get.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - zip_file_error_get.c -- get zip file error - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#define _ZIP_COMPILING_DEPRECATED -#include "zipint.h" - - -ZIP_EXTERN void -zip_file_error_get(zip_file_t *zf, int *zep, int *sep) { - _zip_error_get(&zf->error, zep, sep); -} diff --git a/ext/libzip/zip_file_get_comment.c b/ext/libzip/zip_file_get_comment.c deleted file mode 100644 index 8f68141aea..0000000000 --- a/ext/libzip/zip_file_get_comment.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - zip_file_get_comment.c -- get file comment - Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - -/* lenp is 32 bit because converted comment can be longer than ZIP_UINT16_MAX */ - -ZIP_EXTERN const char * -zip_file_get_comment(zip_t *za, zip_uint64_t idx, zip_uint32_t *lenp, zip_flags_t flags) { - zip_dirent_t *de; - zip_uint32_t len; - const zip_uint8_t *str; - - if ((de = _zip_get_dirent(za, idx, flags, NULL)) == NULL) - return NULL; - - if ((str = _zip_string_get(de->comment, &len, flags, &za->error)) == NULL) - return NULL; - - if (lenp) - *lenp = len; - - return (const char *)str; -} diff --git a/ext/libzip/zip_file_get_external_attributes.c b/ext/libzip/zip_file_get_external_attributes.c deleted file mode 100644 index ebc20580cb..0000000000 --- a/ext/libzip/zip_file_get_external_attributes.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - zip_file_get_external_attributes.c -- get opsys/external attributes - Copyright (C) 2013-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "zipint.h" - -int -zip_file_get_external_attributes(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_uint8_t *opsys, zip_uint32_t *attributes) { - zip_dirent_t *de; - - if ((de = _zip_get_dirent(za, idx, flags, NULL)) == NULL) - return -1; - - if (opsys) - *opsys = (zip_uint8_t)((de->version_madeby >> 8) & 0xff); - - if (attributes) - *attributes = de->ext_attrib; - - return 0; -} diff --git a/ext/libzip/zip_file_get_offset.c b/ext/libzip/zip_file_get_offset.c deleted file mode 100644 index 2cf4480db7..0000000000 --- a/ext/libzip/zip_file_get_offset.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - zip_file_get_offset.c -- get offset of file data in archive. - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include -#include - -#include "zipint.h" - - -/* _zip_file_get_offset(za, ze): - Returns the offset of the file data for entry ze. - - On error, fills in za->error and returns 0. -*/ - -zip_uint64_t -_zip_file_get_offset(const zip_t *za, zip_uint64_t idx, zip_error_t *error) { - zip_uint64_t offset; - zip_int32_t size; - - if (za->entry[idx].orig == NULL) { - zip_error_set(error, ZIP_ER_INTERNAL, 0); - return 0; - } - - offset = za->entry[idx].orig->offset; - - if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) { - _zip_error_set_from_source(error, za->src); - return 0; - } - - /* TODO: cache? */ - if ((size = _zip_dirent_size(za->src, ZIP_EF_LOCAL, error)) < 0) - return 0; - - if (offset + (zip_uint32_t)size > ZIP_INT64_MAX) { - zip_error_set(error, ZIP_ER_SEEK, EFBIG); - return 0; - } - - return offset + (zip_uint32_t)size; -} - -zip_uint64_t -_zip_file_get_end(const zip_t *za, zip_uint64_t index, zip_error_t *error) { - zip_uint64_t offset; - zip_dirent_t *entry; - - if ((offset = _zip_file_get_offset(za, index, error)) == 0) { - return 0; - } - - entry = za->entry[index].orig; - - if (offset + entry->comp_size < offset || offset + entry->comp_size > ZIP_INT64_MAX) { - zip_error_set(error, ZIP_ER_SEEK, EFBIG); - return 0; - } - offset += entry->comp_size; - - if (entry->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) { - zip_uint8_t buf[4]; - if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) { - _zip_error_set_from_source(error, za->src); - return 0; - } - if (zip_source_read(za->src, buf, 4) != 4) { - _zip_error_set_from_source(error, za->src); - return 0; - } - if (memcmp(buf, DATADES_MAGIC, 4) == 0) { - offset += 4; - } - offset += 12; - if (_zip_dirent_needs_zip64(entry, 0)) { - offset += 8; - } - if (offset > ZIP_INT64_MAX) { - zip_error_set(error, ZIP_ER_SEEK, EFBIG); - return 0; - } - } - - return offset; -} diff --git a/ext/libzip/zip_file_rename.c b/ext/libzip/zip_file_rename.c deleted file mode 100644 index 7ca428c499..0000000000 --- a/ext/libzip/zip_file_rename.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - zip_file_rename.c -- rename file in zip archive - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include - -#include "zipint.h" - - -ZIP_EXTERN int -zip_file_rename(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags) { - const char *old_name; - int old_is_dir, new_is_dir; - - if (idx >= za->nentry || (name != NULL && strlen(name) > ZIP_UINT16_MAX)) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (ZIP_IS_RDONLY(za)) { - zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - if ((old_name = zip_get_name(za, idx, 0)) == NULL) - return -1; - - new_is_dir = (name != NULL && name[strlen(name) - 1] == '/'); - old_is_dir = (old_name[strlen(old_name) - 1] == '/'); - - if (new_is_dir != old_is_dir) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - return _zip_set_name(za, idx, name, flags); -} diff --git a/ext/libzip/zip_file_replace.c b/ext/libzip/zip_file_replace.c deleted file mode 100644 index 87401f4a46..0000000000 --- a/ext/libzip/zip_file_replace.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - zip_file_replace.c -- replace file via callback function - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN int -zip_file_replace(zip_t *za, zip_uint64_t idx, zip_source_t *source, zip_flags_t flags) { - if (idx >= za->nentry || source == NULL) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (_zip_file_replace(za, idx, NULL, source, flags) == -1) - return -1; - - return 0; -} - - -/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */ - -zip_int64_t -_zip_file_replace(zip_t *za, zip_uint64_t idx, const char *name, zip_source_t *source, zip_flags_t flags) { - zip_uint64_t za_nentry_prev; - - if (ZIP_IS_RDONLY(za)) { - zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - za_nentry_prev = za->nentry; - if (idx == ZIP_UINT64_MAX) { - zip_int64_t i = -1; - - if (flags & ZIP_FL_OVERWRITE) - i = _zip_name_locate(za, name, flags, NULL); - - if (i == -1) { - /* create and use new entry, used by zip_add */ - if ((i = _zip_add_entry(za)) < 0) - return -1; - } - idx = (zip_uint64_t)i; - } - - if (name && _zip_set_name(za, idx, name, flags) != 0) { - if (za->nentry != za_nentry_prev) { - _zip_entry_finalize(za->entry + idx); - za->nentry = za_nentry_prev; - } - return -1; - } - - /* does not change any name related data, so we can do it here; - * needed for a double add of the same file name */ - _zip_unchange_data(za->entry + idx); - - if (za->entry[idx].orig != NULL && (za->entry[idx].changes == NULL || (za->entry[idx].changes->changed & ZIP_DIRENT_COMP_METHOD) == 0)) { - if (za->entry[idx].changes == NULL) { - if ((za->entry[idx].changes = _zip_dirent_clone(za->entry[idx].orig)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - } - - za->entry[idx].changes->comp_method = ZIP_CM_REPLACED_DEFAULT; - za->entry[idx].changes->changed |= ZIP_DIRENT_COMP_METHOD; - } - - za->entry[idx].source = source; - - return (zip_int64_t)idx; -} diff --git a/ext/libzip/zip_file_set_comment.c b/ext/libzip/zip_file_set_comment.c deleted file mode 100644 index c309db8b1e..0000000000 --- a/ext/libzip/zip_file_set_comment.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - zip_file_set_comment.c -- set comment for file in archive - Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include - -#include "zipint.h" - - -ZIP_EXTERN int -zip_file_set_comment(zip_t *za, zip_uint64_t idx, const char *comment, zip_uint16_t len, zip_flags_t flags) { - zip_entry_t *e; - zip_string_t *cstr; - int changed; - - if (_zip_get_dirent(za, idx, 0, NULL) == NULL) - return -1; - - if (ZIP_IS_RDONLY(za)) { - zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - if (len > 0 && comment == NULL) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (len > 0) { - if ((cstr = _zip_string_new((const zip_uint8_t *)comment, len, flags, &za->error)) == NULL) - return -1; - if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(cstr, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED) - cstr->encoding = ZIP_ENCODING_UTF8_KNOWN; - } - else - cstr = NULL; - - e = za->entry + idx; - - if (e->changes) { - _zip_string_free(e->changes->comment); - e->changes->comment = NULL; - e->changes->changed &= ~ZIP_DIRENT_COMMENT; - } - - if (e->orig && e->orig->comment) - changed = !_zip_string_equal(e->orig->comment, cstr); - else - changed = (cstr != NULL); - - if (changed) { - if (e->changes == NULL) { - if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - _zip_string_free(cstr); - return -1; - } - } - e->changes->comment = cstr; - e->changes->changed |= ZIP_DIRENT_COMMENT; - } - else { - _zip_string_free(cstr); - if (e->changes && e->changes->changed == 0) { - _zip_dirent_free(e->changes); - e->changes = NULL; - } - } - - return 0; -} diff --git a/ext/libzip/zip_file_set_encryption.c b/ext/libzip/zip_file_set_encryption.c deleted file mode 100644 index a66a1b5472..0000000000 --- a/ext/libzip/zip_file_set_encryption.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - zip_file_set_encryption.c -- set encryption for file in archive - Copyright (C) 2016-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - -#include -#include - -ZIP_EXTERN int -zip_file_set_encryption(zip_t *za, zip_uint64_t idx, zip_uint16_t method, const char *password) { - zip_entry_t *e; - zip_uint16_t old_method; - - if (idx >= za->nentry) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (ZIP_IS_RDONLY(za)) { - zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - if (method != ZIP_EM_NONE && _zip_get_encryption_implementation(method, ZIP_CODEC_ENCODE) == NULL) { - zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); - return -1; - } - - e = za->entry + idx; - - old_method = (e->orig == NULL ? ZIP_EM_NONE : e->orig->encryption_method); - - if (method == old_method && password == NULL) { - if (e->changes) { - if (e->changes->changed & ZIP_DIRENT_PASSWORD) { - _zip_crypto_clear(e->changes->password, strlen(e->changes->password)); - free(e->changes->password); - e->changes->password = (e->orig == NULL ? NULL : e->orig->password); - } - e->changes->changed &= ~(ZIP_DIRENT_ENCRYPTION_METHOD | ZIP_DIRENT_PASSWORD); - if (e->changes->changed == 0) { - _zip_dirent_free(e->changes); - e->changes = NULL; - } - } - } - else { - char *our_password = NULL; - - if (password) { - if ((our_password = strdup(password)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - } - - if (e->changes == NULL) { - if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) { - if (our_password) { - _zip_crypto_clear(our_password, strlen(our_password)); - } - free(our_password); - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - } - - e->changes->encryption_method = method; - e->changes->changed |= ZIP_DIRENT_ENCRYPTION_METHOD; - if (password) { - e->changes->password = our_password; - e->changes->changed |= ZIP_DIRENT_PASSWORD; - } - else { - if (e->changes->changed & ZIP_DIRENT_PASSWORD) { - _zip_crypto_clear(e->changes->password, strlen(e->changes->password)); - free(e->changes->password); - e->changes->password = e->orig ? e->orig->password : NULL; - e->changes->changed &= ~ZIP_DIRENT_PASSWORD; - } - } - } - - return 0; -} diff --git a/ext/libzip/zip_file_set_external_attributes.c b/ext/libzip/zip_file_set_external_attributes.c deleted file mode 100644 index bb2ea61466..0000000000 --- a/ext/libzip/zip_file_set_external_attributes.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - zip_file_set_external_attributes.c -- set external attributes for entry - Copyright (C) 2013-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "zipint.h" - -ZIP_EXTERN int -zip_file_set_external_attributes(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_uint8_t opsys, zip_uint32_t attributes) { - zip_entry_t *e; - int changed; - zip_uint8_t unchanged_opsys; - zip_uint32_t unchanged_attributes; - - if (_zip_get_dirent(za, idx, 0, NULL) == NULL) - return -1; - - if (ZIP_IS_RDONLY(za)) { - zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - e = za->entry + idx; - - unchanged_opsys = (e->orig ? (zip_uint8_t)(e->orig->version_madeby >> 8) : (zip_uint8_t)ZIP_OPSYS_DEFAULT); - unchanged_attributes = e->orig ? e->orig->ext_attrib : ZIP_EXT_ATTRIB_DEFAULT; - - changed = (opsys != unchanged_opsys || attributes != unchanged_attributes); - - if (changed) { - if (e->changes == NULL) { - if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - } - e->changes->version_madeby = (zip_uint16_t)((opsys << 8) | (e->changes->version_madeby & 0xff)); - e->changes->ext_attrib = attributes; - e->changes->changed |= ZIP_DIRENT_ATTRIBUTES; - } - else if (e->changes) { - e->changes->changed &= ~ZIP_DIRENT_ATTRIBUTES; - if (e->changes->changed == 0) { - _zip_dirent_free(e->changes); - e->changes = NULL; - } - else { - e->changes->version_madeby = (zip_uint16_t)((unchanged_opsys << 8) | (e->changes->version_madeby & 0xff)); - e->changes->ext_attrib = unchanged_attributes; - } - } - - return 0; -} diff --git a/ext/libzip/zip_file_set_mtime.c b/ext/libzip/zip_file_set_mtime.c deleted file mode 100644 index 838548ef92..0000000000 --- a/ext/libzip/zip_file_set_mtime.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - zip_file_set_mtime.c -- set modification time of entry. - Copyright (C) 2014-2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "zipint.h" - -ZIP_EXTERN int -zip_file_set_dostime(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16_t ddate, zip_flags_t flags) { - time_t mtime; - mtime = _zip_d2u_time(dtime, ddate); - return zip_file_set_mtime(za, idx, mtime, flags); -} - -ZIP_EXTERN int -zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags) { - zip_entry_t *e; - - if (_zip_get_dirent(za, idx, 0, NULL) == NULL) - return -1; - - if (ZIP_IS_RDONLY(za)) { - zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - e = za->entry + idx; - - if (e->changes == NULL) { - if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - } - - e->changes->last_mod = mtime; - e->changes->changed |= ZIP_DIRENT_LAST_MOD; - - return 0; -} diff --git a/ext/libzip/zip_file_strerror.c b/ext/libzip/zip_file_strerror.c deleted file mode 100644 index 1fa7fffd63..0000000000 --- a/ext/libzip/zip_file_strerror.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - zip_file_sterror.c -- get string representation of zip file error - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN const char * -zip_file_strerror(zip_file_t *zf) { - return zip_error_strerror(&zf->error); -} diff --git a/ext/libzip/zip_fopen.c b/ext/libzip/zip_fopen.c deleted file mode 100644 index 4f1a051dbd..0000000000 --- a/ext/libzip/zip_fopen.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - zip_fopen.c -- open file in zip archive for reading - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN zip_file_t * -zip_fopen(zip_t *za, const char *fname, zip_flags_t flags) { - zip_int64_t idx; - - if ((idx = zip_name_locate(za, fname, flags)) < 0) - return NULL; - - return zip_fopen_index_encrypted(za, (zip_uint64_t)idx, flags, za->default_password); -} diff --git a/ext/libzip/zip_fopen_encrypted.c b/ext/libzip/zip_fopen_encrypted.c deleted file mode 100644 index 9e9b13e53e..0000000000 --- a/ext/libzip/zip_fopen_encrypted.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - zip_fopen_encrypted.c -- open file for reading with password - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN zip_file_t * -zip_fopen_encrypted(zip_t *za, const char *fname, zip_flags_t flags, const char *password) { - zip_int64_t idx; - - if ((idx = zip_name_locate(za, fname, flags)) < 0) - return NULL; - - return zip_fopen_index_encrypted(za, (zip_uint64_t)idx, flags, password); -} diff --git a/ext/libzip/zip_fopen_index.c b/ext/libzip/zip_fopen_index.c deleted file mode 100644 index e5205b73ef..0000000000 --- a/ext/libzip/zip_fopen_index.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - zip_fopen_index.c -- open file in zip archive for reading by index - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN zip_file_t * -zip_fopen_index(zip_t *za, zip_uint64_t index, zip_flags_t flags) { - return zip_fopen_index_encrypted(za, index, flags, za->default_password); -} diff --git a/ext/libzip/zip_fopen_index_encrypted.c b/ext/libzip/zip_fopen_index_encrypted.c deleted file mode 100644 index 6712c32a9f..0000000000 --- a/ext/libzip/zip_fopen_index_encrypted.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - zip_fopen_index_encrypted.c -- open file for reading by index w/ password - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include -#include - -#include "zipint.h" - -static zip_file_t *_zip_file_new(zip_t *za); - - -ZIP_EXTERN zip_file_t * -zip_fopen_index_encrypted(zip_t *za, zip_uint64_t index, zip_flags_t flags, const char *password) { - zip_file_t *zf; - zip_source_t *src; - - if ((src = _zip_source_zip_new(za, za, index, flags, 0, 0, password)) == NULL) - return NULL; - - if (zip_source_open(src) < 0) { - _zip_error_set_from_source(&za->error, src); - zip_source_free(src); - return NULL; - } - - if ((zf = _zip_file_new(za)) == NULL) { - zip_source_free(src); - return NULL; - } - - zf->src = src; - - return zf; -} - - -static zip_file_t * -_zip_file_new(zip_t *za) { - zip_file_t *zf; - - if ((zf = (zip_file_t *)malloc(sizeof(struct zip_file))) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return NULL; - } - - zf->za = za; - zip_error_init(&zf->error); - zf->eof = 0; - zf->src = NULL; - - return zf; -} diff --git a/ext/libzip/zip_fread.c b/ext/libzip/zip_fread.c deleted file mode 100644 index 646d712408..0000000000 --- a/ext/libzip/zip_fread.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - zip_fread.c -- read from file - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN zip_int64_t -zip_fread(zip_file_t *zf, void *outbuf, zip_uint64_t toread) { - zip_int64_t n; - - if (!zf) - return -1; - - if (zf->error.zip_err != 0) - return -1; - - if (toread > ZIP_INT64_MAX) { - zip_error_set(&zf->error, ZIP_ER_INVAL, 0); - return -1; - } - - if ((zf->eof) || (toread == 0)) - return 0; - - if ((n = zip_source_read(zf->src, outbuf, toread)) < 0) { - _zip_error_set_from_source(&zf->error, zf->src); - return -1; - } - - return n; -} diff --git a/ext/libzip/zip_fseek.c b/ext/libzip/zip_fseek.c deleted file mode 100644 index dc6d9787ef..0000000000 --- a/ext/libzip/zip_fseek.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - zip_fseek.c -- seek in file - Copyright (C) 2016-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - -ZIP_EXTERN zip_int8_t -zip_fseek(zip_file_t *zf, zip_int64_t offset, int whence) { - if (!zf) - return -1; - - if (zf->error.zip_err != 0) - return -1; - - if (zip_source_seek(zf->src, offset, whence) < 0) { - _zip_error_set_from_source(&zf->error, zf->src); - return -1; - } - - return 0; -} diff --git a/ext/libzip/zip_ftell.c b/ext/libzip/zip_ftell.c deleted file mode 100644 index 944db7b978..0000000000 --- a/ext/libzip/zip_ftell.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - zip_ftell.c -- tell position in file - Copyright (C) 2016-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - -ZIP_EXTERN zip_int64_t -zip_ftell(zip_file_t *zf) { - zip_int64_t res; - - if (!zf) - return -1; - - if (zf->error.zip_err != 0) - return -1; - - res = zip_source_tell(zf->src); - if (res < 0) { - _zip_error_set_from_source(&zf->error, zf->src); - return -1; - } - - return res; -} diff --git a/ext/libzip/zip_get_archive_comment.c b/ext/libzip/zip_get_archive_comment.c deleted file mode 100644 index 953c6f42db..0000000000 --- a/ext/libzip/zip_get_archive_comment.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - zip_get_archive_comment.c -- get archive comment - Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include - -#include "zipint.h" - - -ZIP_EXTERN const char * -zip_get_archive_comment(zip_t *za, int *lenp, zip_flags_t flags) { - zip_string_t *comment; - zip_uint32_t len; - const zip_uint8_t *str; - - if ((flags & ZIP_FL_UNCHANGED) || (za->comment_changes == NULL)) - comment = za->comment_orig; - else - comment = za->comment_changes; - - if ((str = _zip_string_get(comment, &len, flags, &za->error)) == NULL) - return NULL; - - if (lenp) - *lenp = (int)len; - - return (const char *)str; -} diff --git a/ext/libzip/zip_get_archive_flag.c b/ext/libzip/zip_get_archive_flag.c deleted file mode 100644 index fa4dd502b2..0000000000 --- a/ext/libzip/zip_get_archive_flag.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - zip_get_archive_flag.c -- get archive global flag - Copyright (C) 2008-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN int -zip_get_archive_flag(zip_t *za, zip_flags_t flag, zip_flags_t flags) { - unsigned int fl; - - fl = (flags & ZIP_FL_UNCHANGED) ? za->flags : za->ch_flags; - - return (fl & flag) ? 1 : 0; -} diff --git a/ext/libzip/zip_get_encryption_implementation.c b/ext/libzip/zip_get_encryption_implementation.c deleted file mode 100644 index 3909e6f6b4..0000000000 --- a/ext/libzip/zip_get_encryption_implementation.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - zip_get_encryption_implementation.c -- get encryption implementation - Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -zip_encryption_implementation -_zip_get_encryption_implementation(zip_uint16_t em, int operation) { - switch (em) { - case ZIP_EM_TRAD_PKWARE: - return operation == ZIP_CODEC_DECODE ? zip_source_pkware_decode : zip_source_pkware_encode; - -#if defined(HAVE_CRYPTO) - case ZIP_EM_AES_128: - case ZIP_EM_AES_192: - case ZIP_EM_AES_256: - return operation == ZIP_CODEC_DECODE ? zip_source_winzip_aes_decode : zip_source_winzip_aes_encode; -#endif - - default: - return NULL; - } -} - -ZIP_EXTERN int -zip_encryption_method_supported(zip_uint16_t method, int encode) { - if (method == ZIP_EM_NONE) { - return 1; - } - return _zip_get_encryption_implementation(method, encode ? ZIP_CODEC_ENCODE : ZIP_CODEC_DECODE) != NULL; -} diff --git a/ext/libzip/zip_get_file_comment.c b/ext/libzip/zip_get_file_comment.c deleted file mode 100644 index f80068612c..0000000000 --- a/ext/libzip/zip_get_file_comment.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - zip_get_file_comment.c -- get file comment - Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#define _ZIP_COMPILING_DEPRECATED -#include "zipint.h" - - -ZIP_EXTERN const char * -zip_get_file_comment(zip_t *za, zip_uint64_t idx, int *lenp, int flags) { - zip_uint32_t len; - const char *s; - - if ((s = zip_file_get_comment(za, idx, &len, (zip_flags_t)flags)) != NULL) { - if (lenp) - *lenp = (int)len; - } - - return s; -} diff --git a/ext/libzip/zip_get_name.c b/ext/libzip/zip_get_name.c deleted file mode 100644 index 4344209303..0000000000 --- a/ext/libzip/zip_get_name.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - zip_get_name.c -- get filename for a file in zip file - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include - -#include "zipint.h" - - -ZIP_EXTERN const char * -zip_get_name(zip_t *za, zip_uint64_t idx, zip_flags_t flags) { - return _zip_get_name(za, idx, flags, &za->error); -} - - -const char * -_zip_get_name(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error) { - zip_dirent_t *de; - const zip_uint8_t *str; - - if ((de = _zip_get_dirent(za, idx, flags, error)) == NULL) - return NULL; - - if ((str = _zip_string_get(de->filename, NULL, flags, error)) == NULL) - return NULL; - - return (const char *)str; -} diff --git a/ext/libzip/zip_get_num_entries.c b/ext/libzip/zip_get_num_entries.c deleted file mode 100644 index 410d26e117..0000000000 --- a/ext/libzip/zip_get_num_entries.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - zip_get_num_entries.c -- get number of entries in archive - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN zip_int64_t -zip_get_num_entries(zip_t *za, zip_flags_t flags) { - zip_uint64_t n; - - if (za == NULL) - return -1; - - if (flags & ZIP_FL_UNCHANGED) { - n = za->nentry; - while (n > 0 && za->entry[n - 1].orig == NULL) - --n; - return (zip_int64_t)n; - } - return (zip_int64_t)za->nentry; -} diff --git a/ext/libzip/zip_get_num_files.c b/ext/libzip/zip_get_num_files.c deleted file mode 100644 index 4895eaabe4..0000000000 --- a/ext/libzip/zip_get_num_files.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - zip_get_num_files.c -- get number of files in archive - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#define _ZIP_COMPILING_DEPRECATED -#include "zipint.h" -#include - - -ZIP_EXTERN int -zip_get_num_files(zip_t *za) { - if (za == NULL) - return -1; - - if (za->nentry > INT_MAX) { - zip_error_set(&za->error, ZIP_ER_OPNOTSUPP, 0); - return -1; - } - - return (int)za->nentry; -} diff --git a/ext/libzip/zip_hash.c b/ext/libzip/zip_hash.c deleted file mode 100644 index 3206dbf749..0000000000 --- a/ext/libzip/zip_hash.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - zip_hash.c -- hash table string -> uint64 - Copyright (C) 2015-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "zipint.h" -#include -#include - -/* parameter for the string hash function */ -#define HASH_MULTIPLIER 33 -#define HASH_START 5381 - -/* hash table's fill ratio is kept between these by doubling/halfing its size as necessary */ -#define HASH_MAX_FILL .75 -#define HASH_MIN_FILL .01 - -/* but hash table size is kept between these */ -#define HASH_MIN_SIZE 256 -#define HASH_MAX_SIZE 0x80000000ul - -struct zip_hash_entry { - const zip_uint8_t *name; - zip_int64_t orig_index; - zip_int64_t current_index; - struct zip_hash_entry *next; - zip_uint32_t hash_value; -}; -typedef struct zip_hash_entry zip_hash_entry_t; - -struct zip_hash { - zip_uint32_t table_size; - zip_uint64_t nentries; - zip_hash_entry_t **table; -}; - - -/* free list of entries */ -static void -free_list(zip_hash_entry_t *entry) { - while (entry != NULL) { - zip_hash_entry_t *next = entry->next; - free(entry); - entry = next; - } -} - - -/* compute hash of string, full 32 bit value */ -static zip_uint32_t -hash_string(const zip_uint8_t *name) { - zip_uint64_t value = HASH_START; - - if (name == NULL) { - return 0; - } - - while (*name != 0) { - value = (zip_uint64_t)(((value * HASH_MULTIPLIER) + (zip_uint8_t)*name) % 0x100000000ul); - name++; - } - - return (zip_uint32_t)value; -} - - -/* resize hash table; new_size must be a power of 2, can be larger or smaller than current size */ -static bool -hash_resize(zip_hash_t *hash, zip_uint32_t new_size, zip_error_t *error) { - zip_hash_entry_t **new_table; - - if (new_size == hash->table_size) { - return true; - } - - if ((new_table = (zip_hash_entry_t **)calloc(new_size, sizeof(zip_hash_entry_t *))) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return false; - } - - if (hash->nentries > 0) { - zip_uint32_t i; - - for (i = 0; i < hash->table_size; i++) { - zip_hash_entry_t *entry = hash->table[i]; - while (entry) { - zip_hash_entry_t *next = entry->next; - - zip_uint32_t new_index = entry->hash_value % new_size; - - entry->next = new_table[new_index]; - new_table[new_index] = entry; - - entry = next; - } - } - } - - free(hash->table); - hash->table = new_table; - hash->table_size = new_size; - - return true; -} - - -static zip_uint32_t -size_for_capacity(zip_uint64_t capacity) { - double needed_size = capacity / HASH_MAX_FILL; - zip_uint32_t v; - - if (needed_size > ZIP_UINT32_MAX) { - v = ZIP_UINT32_MAX; - } - else { - v = (zip_uint32_t)needed_size; - } - - if (v > HASH_MAX_SIZE) { - return HASH_MAX_SIZE; - } - - /* From Bit Twiddling Hacks by Sean Eron Anderson - (http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2). */ - - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v++; - - return v; -} - - -zip_hash_t * -_zip_hash_new(zip_error_t *error) { - zip_hash_t *hash; - - if ((hash = (zip_hash_t *)malloc(sizeof(zip_hash_t))) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; - } - - hash->table_size = 0; - hash->nentries = 0; - hash->table = NULL; - - return hash; -} - - -void -_zip_hash_free(zip_hash_t *hash) { - zip_uint32_t i; - - if (hash == NULL) { - return; - } - - if (hash->table != NULL) { - for (i = 0; i < hash->table_size; i++) { - if (hash->table[i] != NULL) { - free_list(hash->table[i]); - } - } - free(hash->table); - } - free(hash); -} - - -/* insert into hash, return error on existence or memory issues */ -bool -_zip_hash_add(zip_hash_t *hash, const zip_uint8_t *name, zip_uint64_t index, zip_flags_t flags, zip_error_t *error) { - zip_uint32_t hash_value, table_index; - zip_hash_entry_t *entry; - - if (hash == NULL || name == NULL || index > ZIP_INT64_MAX) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return false; - } - - if (hash->table_size == 0) { - if (!hash_resize(hash, HASH_MIN_SIZE, error)) { - return false; - } - } - - hash_value = hash_string(name); - table_index = hash_value % hash->table_size; - - for (entry = hash->table[table_index]; entry != NULL; entry = entry->next) { - if (entry->hash_value == hash_value && strcmp((const char *)name, (const char *)entry->name) == 0) { - if (((flags & ZIP_FL_UNCHANGED) && entry->orig_index != -1) || entry->current_index != -1) { - zip_error_set(error, ZIP_ER_EXISTS, 0); - return false; - } - else { - break; - } - } - } - - if (entry == NULL) { - if ((entry = (zip_hash_entry_t *)malloc(sizeof(zip_hash_entry_t))) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return false; - } - entry->name = name; - entry->next = hash->table[table_index]; - hash->table[table_index] = entry; - entry->hash_value = hash_value; - entry->orig_index = -1; - hash->nentries++; - if (hash->nentries > hash->table_size * HASH_MAX_FILL && hash->table_size < HASH_MAX_SIZE) { - if (!hash_resize(hash, hash->table_size * 2, error)) { - return false; - } - } - } - - if (flags & ZIP_FL_UNCHANGED) { - entry->orig_index = (zip_int64_t)index; - } - entry->current_index = (zip_int64_t)index; - - return true; -} - - -/* remove entry from hash, error if not found */ -bool -_zip_hash_delete(zip_hash_t *hash, const zip_uint8_t *name, zip_error_t *error) { - zip_uint32_t hash_value, index; - zip_hash_entry_t *entry, *previous; - - if (hash == NULL || name == NULL) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return false; - } - - if (hash->nentries > 0) { - hash_value = hash_string(name); - index = hash_value % hash->table_size; - previous = NULL; - entry = hash->table[index]; - while (entry) { - if (entry->hash_value == hash_value && strcmp((const char *)name, (const char *)entry->name) == 0) { - if (entry->orig_index == -1) { - if (previous) { - previous->next = entry->next; - } - else { - hash->table[index] = entry->next; - } - free(entry); - hash->nentries--; - if (hash->nentries < hash->table_size * HASH_MIN_FILL && hash->table_size > HASH_MIN_SIZE) { - if (!hash_resize(hash, hash->table_size / 2, error)) { - return false; - } - } - } - else { - entry->current_index = -1; - } - return true; - } - previous = entry; - entry = entry->next; - } - } - - zip_error_set(error, ZIP_ER_NOENT, 0); - return false; -} - - -/* find value for entry in hash, -1 if not found */ -zip_int64_t -_zip_hash_lookup(zip_hash_t *hash, const zip_uint8_t *name, zip_flags_t flags, zip_error_t *error) { - zip_uint32_t hash_value, index; - zip_hash_entry_t *entry; - - if (hash == NULL || name == NULL) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return -1; - } - - if (hash->nentries > 0) { - hash_value = hash_string(name); - index = hash_value % hash->table_size; - for (entry = hash->table[index]; entry != NULL; entry = entry->next) { - if (strcmp((const char *)name, (const char *)entry->name) == 0) { - if (flags & ZIP_FL_UNCHANGED) { - if (entry->orig_index != -1) { - return entry->orig_index; - } - } - else { - if (entry->current_index != -1) { - return entry->current_index; - } - } - break; - } - } - } - - zip_error_set(error, ZIP_ER_NOENT, 0); - return -1; -} - - -bool -_zip_hash_reserve_capacity(zip_hash_t *hash, zip_uint64_t capacity, zip_error_t *error) { - zip_uint32_t new_size; - - if (capacity == 0) { - return true; - } - - new_size = size_for_capacity(capacity); - - if (new_size <= hash->table_size) { - return true; - } - - if (!hash_resize(hash, new_size, error)) { - return false; - } - - return true; -} - - -bool -_zip_hash_revert(zip_hash_t *hash, zip_error_t *error) { - zip_uint32_t i; - zip_hash_entry_t *entry, *previous; - - for (i = 0; i < hash->table_size; i++) { - previous = NULL; - entry = hash->table[i]; - while (entry) { - if (entry->orig_index == -1) { - zip_hash_entry_t *p; - if (previous) { - previous->next = entry->next; - } - else { - hash->table[i] = entry->next; - } - p = entry; - entry = entry->next; - /* previous does not change */ - free(p); - hash->nentries--; - } - else { - entry->current_index = entry->orig_index; - previous = entry; - entry = entry->next; - } - } - } - - if (hash->nentries < hash->table_size * HASH_MIN_FILL && hash->table_size > HASH_MIN_SIZE) { - zip_uint32_t new_size = hash->table_size / 2; - while (hash->nentries < new_size * HASH_MIN_FILL && new_size > HASH_MIN_SIZE) { - new_size /= 2; - } - if (!hash_resize(hash, new_size, error)) { - return false; - } - } - - return true; -} diff --git a/ext/libzip/zip_io_util.c b/ext/libzip/zip_io_util.c deleted file mode 100644 index dd07cbb9aa..0000000000 --- a/ext/libzip/zip_io_util.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - zip_io_util.c -- I/O helper functions - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include "zipint.h" - -int -_zip_read(zip_source_t *src, zip_uint8_t *b, zip_uint64_t length, zip_error_t *error) { - zip_int64_t n; - - if (length > ZIP_INT64_MAX) { - zip_error_set(error, ZIP_ER_INTERNAL, 0); - return -1; - } - - if ((n = zip_source_read(src, b, length)) < 0) { - _zip_error_set_from_source(error, src); - return -1; - } - - if (n < (zip_int64_t)length) { - zip_error_set(error, ZIP_ER_EOF, 0); - return -1; - } - - return 0; -} - - -zip_uint8_t * -_zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp, zip_error_t *error) { - zip_uint8_t *r; - - if (length == 0 && !nulp) { - return NULL; - } - - r = (zip_uint8_t *)malloc(length + (nulp ? 1 : 0)); - if (!r) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; - } - - if (buffer) { - zip_uint8_t *data = _zip_buffer_get(buffer, length); - - if (data == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - free(r); - return NULL; - } - memcpy(r, data, length); - } - else { - if (_zip_read(src, r, length, error) < 0) { - free(r); - return NULL; - } - } - - if (nulp) { - zip_uint8_t *o; - /* replace any in-string NUL characters with spaces */ - r[length] = 0; - for (o = r; o < r + length; o++) - if (*o == '\0') - *o = ' '; - } - - return r; -} - - -zip_string_t * -_zip_read_string(zip_buffer_t *buffer, zip_source_t *src, zip_uint16_t len, bool nulp, zip_error_t *error) { - zip_uint8_t *raw; - zip_string_t *s; - - if ((raw = _zip_read_data(buffer, src, len, nulp, error)) == NULL) - return NULL; - - s = _zip_string_new(raw, len, ZIP_FL_ENC_GUESS, error); - free(raw); - return s; -} - - -int -_zip_write(zip_t *za, const void *data, zip_uint64_t length) { - zip_int64_t n; - - if ((n = zip_source_write(za->src, data, length)) < 0) { - _zip_error_set_from_source(&za->error, za->src); - return -1; - } - if ((zip_uint64_t)n != length) { - zip_error_set(&za->error, ZIP_ER_WRITE, EINTR); - return -1; - } - - return 0; -} diff --git a/ext/libzip/zip_libzip_version.c b/ext/libzip/zip_libzip_version.c deleted file mode 100644 index fadbc69bcc..0000000000 --- a/ext/libzip/zip_libzip_version.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - zip_libzip_version.c -- return run-time version of library - Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN const char * -zip_libzip_version(void) { - return LIBZIP_VERSION; -} diff --git a/ext/libzip/zip_memdup.c b/ext/libzip/zip_memdup.c deleted file mode 100644 index 05fcb7b77e..0000000000 --- a/ext/libzip/zip_memdup.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - zip_memdup.c -- internal zip function, "strdup" with len - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include - -#include "zipint.h" - - -void * -_zip_memdup(const void *mem, size_t len, zip_error_t *error) { - void *ret; - - if (len == 0) - return NULL; - - ret = malloc(len); - if (!ret) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; - } - - memcpy(ret, mem, len); - - return ret; -} diff --git a/ext/libzip/zip_mkstempm.c b/ext/libzip/zip_mkstempm.c deleted file mode 100644 index c1afade331..0000000000 --- a/ext/libzip/zip_mkstempm.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - zip_mkstempm.c -- mkstemp replacement that accepts a mode argument - Copyright (C) 2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include -#include -#include - -#include "zipint.h" - -/* - * create temporary file with same permissions as previous one; - * or default permissions if there is no previous file - */ -int -_zip_mkstempm(char *path, int mode) { - int fd; - char *start, *end, *xs; - - int xcnt = 0; - - end = path + strlen(path); - start = end - 1; - while (start >= path && *start == 'X') { - xcnt++; - start--; - } - - if (xcnt == 0) { - errno = EINVAL; - return -1; - } - - start++; - - for (;;) { - zip_uint32_t value = zip_random_uint32(); - - xs = start; - - while (xs < end) { - char digit = value % 36; - if (digit < 10) { - *(xs++) = digit + '0'; - } - else { - *(xs++) = digit - 10 + 'a'; - } - value /= 36; - } - - if ((fd = open(path, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC, mode == -1 ? 0666 : (mode_t)mode)) >= 0) { - if (mode != -1) { - /* open() honors umask(), which we don't want in this case */ - (void)chmod(path, (mode_t)mode); - } - return fd; - } - if (errno != EEXIST) { - return -1; - } - } -} diff --git a/ext/libzip/zip_name_locate.c b/ext/libzip/zip_name_locate.c deleted file mode 100644 index f7318ecede..0000000000 --- a/ext/libzip/zip_name_locate.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - zip_name_locate.c -- get index by name - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include -#ifdef HAVE_STRINGS_H -#include -#endif - -#include "zipint.h" - - -ZIP_EXTERN zip_int64_t -zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags) { - return _zip_name_locate(za, fname, flags, &za->error); -} - - -zip_int64_t -_zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags, zip_error_t *error) { - int (*cmp)(const char *, const char *); - const char *fn, *p; - zip_uint64_t i; - - if (za == NULL) - return -1; - - if (fname == NULL) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return -1; - } - - if (flags & (ZIP_FL_NOCASE | ZIP_FL_NODIR | ZIP_FL_ENC_CP437)) { - /* can't use hash table */ - cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp; - - for (i = 0; i < za->nentry; i++) { - fn = _zip_get_name(za, i, flags, error); - - /* newly added (partially filled) entry or error */ - if (fn == NULL) - continue; - - if (flags & ZIP_FL_NODIR) { - p = strrchr(fn, '/'); - if (p) - fn = p + 1; - } - - if (cmp(fname, fn) == 0) { - _zip_error_clear(error); - return (zip_int64_t)i; - } - } - - zip_error_set(error, ZIP_ER_NOENT, 0); - return -1; - } - else { - return _zip_hash_lookup(za->names, (const zip_uint8_t *)fname, flags, error); - } -} diff --git a/ext/libzip/zip_new.c b/ext/libzip/zip_new.c deleted file mode 100644 index 4f58ecc7ee..0000000000 --- a/ext/libzip/zip_new.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - zip_new.c -- create and init struct zip - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include - -#include "zipint.h" - - -/* _zip_new: - creates a new zipfile struct, and sets the contents to zero; returns - the new struct. */ - -zip_t * -_zip_new(zip_error_t *error) { - zip_t *za; - - za = (zip_t *)malloc(sizeof(struct zip)); - if (!za) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; - } - - if ((za->names = _zip_hash_new(error)) == NULL) { - free(za); - return NULL; - } - - za->src = NULL; - za->open_flags = 0; - zip_error_init(&za->error); - za->flags = za->ch_flags = 0; - za->default_password = NULL; - za->comment_orig = za->comment_changes = NULL; - za->comment_changed = 0; - za->nentry = za->nentry_alloc = 0; - za->entry = NULL; - za->nopen_source = za->nopen_source_alloc = 0; - za->open_source = NULL; - za->progress = NULL; - - return za; -} diff --git a/ext/libzip/zip_open.c b/ext/libzip/zip_open.c deleted file mode 100644 index 019cd987b8..0000000000 --- a/ext/libzip/zip_open.c +++ /dev/null @@ -1,849 +0,0 @@ -/* - zip_open.c -- open zip archive by name - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include -#include -#include - -#include "zipint.h" - -typedef enum { EXISTS_ERROR = -1, EXISTS_NOT = 0, EXISTS_OK } exists_t; -static zip_t *_zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error); -static zip_int64_t _zip_checkcons(zip_t *za, zip_cdir_t *cdir, zip_error_t *error); -static zip_cdir_t *_zip_find_central_dir(zip_t *za, zip_uint64_t len); -static exists_t _zip_file_exists(zip_source_t *src, zip_error_t *error); -static int _zip_headercomp(const zip_dirent_t *, const zip_dirent_t *); -static unsigned char *_zip_memmem(const unsigned char *, size_t, const unsigned char *, size_t); -static zip_cdir_t *_zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error); -static zip_cdir_t *_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error); -static zip_cdir_t *_zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error); - - -ZIP_EXTERN zip_t * -zip_open(const char *fn, int _flags, int *zep) { - zip_t *za; - zip_source_t *src; - struct zip_error error; - - zip_error_init(&error); - if ((src = zip_source_file_create(fn, 0, -1, &error)) == NULL) { - _zip_set_open_error(zep, &error, 0); - zip_error_fini(&error); - return NULL; - } - - if ((za = zip_open_from_source(src, _flags, &error)) == NULL) { - zip_source_free(src); - _zip_set_open_error(zep, &error, 0); - zip_error_fini(&error); - return NULL; - } - - zip_error_fini(&error); - return za; -} - - -ZIP_EXTERN zip_t * -zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error) { - static zip_int64_t needed_support_read = -1; - static zip_int64_t needed_support_write = -1; - - unsigned int flags; - zip_int64_t supported; - exists_t exists; - - if (_flags < 0 || src == NULL) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - flags = (unsigned int)_flags; - - supported = zip_source_supports(src); - if (needed_support_read == -1) { - needed_support_read = zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_STAT, -1); - needed_support_write = zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, -1); - } - if ((supported & needed_support_read) != needed_support_read) { - zip_error_set(error, ZIP_ER_OPNOTSUPP, 0); - return NULL; - } - if ((supported & needed_support_write) != needed_support_write) { - flags |= ZIP_RDONLY; - } - - if ((flags & (ZIP_RDONLY | ZIP_TRUNCATE)) == (ZIP_RDONLY | ZIP_TRUNCATE)) { - zip_error_set(error, ZIP_ER_RDONLY, 0); - return NULL; - } - - exists = _zip_file_exists(src, error); - switch (exists) { - case EXISTS_ERROR: - return NULL; - - case EXISTS_NOT: - if ((flags & ZIP_CREATE) == 0) { - zip_error_set(error, ZIP_ER_NOENT, 0); - return NULL; - } - return _zip_allocate_new(src, flags, error); - - default: { - zip_t *za; - if (flags & ZIP_EXCL) { - zip_error_set(error, ZIP_ER_EXISTS, 0); - return NULL; - } - if (zip_source_open(src) < 0) { - _zip_error_set_from_source(error, src); - return NULL; - } - - if (flags & ZIP_TRUNCATE) { - za = _zip_allocate_new(src, flags, error); - } - else { - /* ZIP_CREATE gets ignored if file exists and not ZIP_EXCL, just like open() */ - za = _zip_open(src, flags, error); - } - - if (za == NULL) { - zip_source_close(src); - return NULL; - } - return za; - } - } -} - - -zip_t * -_zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) { - zip_t *za; - zip_cdir_t *cdir; - struct zip_stat st; - zip_uint64_t len, idx; - - zip_stat_init(&st); - if (zip_source_stat(src, &st) < 0) { - _zip_error_set_from_source(error, src); - return NULL; - } - if ((st.valid & ZIP_STAT_SIZE) == 0) { - zip_error_set(error, ZIP_ER_SEEK, EOPNOTSUPP); - return NULL; - } - len = st.size; - - - if ((za = _zip_allocate_new(src, flags, error)) == NULL) { - return NULL; - } - - /* treat empty files as empty archives */ - if (len == 0 && zip_source_accept_empty(src)) { - return za; - } - - if ((cdir = _zip_find_central_dir(za, len)) == NULL) { - _zip_error_copy(error, &za->error); - /* keep src so discard does not get rid of it */ - zip_source_keep(src); - zip_discard(za); - return NULL; - } - - za->entry = cdir->entry; - za->nentry = cdir->nentry; - za->nentry_alloc = cdir->nentry_alloc; - za->comment_orig = cdir->comment; - - free(cdir); - - _zip_hash_reserve_capacity(za->names, za->nentry, &za->error); - - for (idx = 0; idx < za->nentry; idx++) { - const zip_uint8_t *name = _zip_string_get(za->entry[idx].orig->filename, NULL, 0, error); - if (name == NULL) { - /* keep src so discard does not get rid of it */ - zip_source_keep(src); - zip_discard(za); - return NULL; - } - - if (_zip_hash_add(za->names, name, idx, ZIP_FL_UNCHANGED, &za->error) == false) { - if (za->error.zip_err != ZIP_ER_EXISTS || (flags & ZIP_CHECKCONS)) { - _zip_error_copy(error, &za->error); - /* keep src so discard does not get rid of it */ - zip_source_keep(src); - zip_discard(za); - return NULL; - } - } - } - - za->ch_flags = za->flags; - - return za; -} - - -void -_zip_set_open_error(int *zep, const zip_error_t *err, int ze) { - if (err) { - ze = zip_error_code_zip(err); - if (zip_error_system_type(err) == ZIP_ET_SYS) { - errno = zip_error_code_system(err); - } - } - - if (zep) - *zep = ze; -} - - -/* _zip_readcdir: - tries to find a valid end-of-central-directory at the beginning of - buf, and then the corresponding central directory entries. - Returns a struct zip_cdir which contains the central directory - entries, or NULL if unsuccessful. */ - -static zip_cdir_t * -_zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error) { - zip_cdir_t *cd; - zip_uint16_t comment_len; - zip_uint64_t i, left; - zip_uint64_t eocd_offset = _zip_buffer_offset(buffer); - zip_buffer_t *cd_buffer; - - if (_zip_buffer_left(buffer) < EOCDLEN) { - /* not enough bytes left for comment */ - zip_error_set(error, ZIP_ER_NOZIP, 0); - return NULL; - } - - /* check for end-of-central-dir magic */ - if (memcmp(_zip_buffer_get(buffer, 4), EOCD_MAGIC, 4) != 0) { - zip_error_set(error, ZIP_ER_NOZIP, 0); - return NULL; - } - - if (eocd_offset >= EOCD64LOCLEN && memcmp(_zip_buffer_data(buffer) + eocd_offset - EOCD64LOCLEN, EOCD64LOC_MAGIC, 4) == 0) { - _zip_buffer_set_offset(buffer, eocd_offset - EOCD64LOCLEN); - cd = _zip_read_eocd64(za->src, buffer, buf_offset, za->flags, error); - } - else { - _zip_buffer_set_offset(buffer, eocd_offset); - cd = _zip_read_eocd(buffer, buf_offset, za->flags, error); - } - - if (cd == NULL) - return NULL; - - _zip_buffer_set_offset(buffer, eocd_offset + 20); - comment_len = _zip_buffer_get_16(buffer); - - if (cd->offset + cd->size > buf_offset + eocd_offset) { - /* cdir spans past EOCD record */ - zip_error_set(error, ZIP_ER_INCONS, 0); - _zip_cdir_free(cd); - return NULL; - } - - if (comment_len || (za->open_flags & ZIP_CHECKCONS)) { - zip_uint64_t tail_len; - - _zip_buffer_set_offset(buffer, eocd_offset + EOCDLEN); - tail_len = _zip_buffer_left(buffer); - - if (tail_len < comment_len || ((za->open_flags & ZIP_CHECKCONS) && tail_len != comment_len)) { - zip_error_set(error, ZIP_ER_INCONS, 0); - _zip_cdir_free(cd); - return NULL; - } - - if (comment_len) { - if ((cd->comment = _zip_string_new(_zip_buffer_get(buffer, comment_len), comment_len, ZIP_FL_ENC_GUESS, error)) == NULL) { - _zip_cdir_free(cd); - return NULL; - } - } - } - - if (cd->offset >= buf_offset) { - zip_uint8_t *data; - /* if buffer already read in, use it */ - _zip_buffer_set_offset(buffer, cd->offset - buf_offset); - - if ((data = _zip_buffer_get(buffer, cd->size)) == NULL) { - zip_error_set(error, ZIP_ER_INCONS, 0); - _zip_cdir_free(cd); - return NULL; - } - if ((cd_buffer = _zip_buffer_new(data, cd->size)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - _zip_cdir_free(cd); - return NULL; - } - } - else { - cd_buffer = NULL; - - if (zip_source_seek(za->src, (zip_int64_t)cd->offset, SEEK_SET) < 0) { - _zip_error_set_from_source(error, za->src); - _zip_cdir_free(cd); - return NULL; - } - - /* possible consistency check: cd->offset = len-(cd->size+cd->comment_len+EOCDLEN) ? */ - if (zip_source_tell(za->src) != (zip_int64_t)cd->offset) { - zip_error_set(error, ZIP_ER_NOZIP, 0); - _zip_cdir_free(cd); - return NULL; - } - } - - left = (zip_uint64_t)cd->size; - i = 0; - while (left > 0) { - bool grown = false; - zip_int64_t entry_size; - - if (i == cd->nentry) { - /* InfoZIP has a hack to avoid using Zip64: it stores nentries % 0x10000 */ - /* This hack isn't applicable if we're using Zip64, or if there is no central directory entry following. */ - - if (cd->is_zip64 || left < CDENTRYSIZE) { - break; - } - - if (!_zip_cdir_grow(cd, 0x10000, error)) { - _zip_cdir_free(cd); - _zip_buffer_free(cd_buffer); - return NULL; - } - grown = true; - } - - if ((cd->entry[i].orig = _zip_dirent_new()) == NULL || (entry_size = _zip_dirent_read(cd->entry[i].orig, za->src, cd_buffer, false, error)) < 0) { - if (grown && zip_error_code_zip(error) == ZIP_ER_NOZIP) { - zip_error_set(error, ZIP_ER_INCONS, 0); - } - _zip_cdir_free(cd); - _zip_buffer_free(cd_buffer); - return NULL; - } - i++; - left -= (zip_uint64_t)entry_size; - } - - if (i != cd->nentry || left > 0) { - zip_error_set(error, ZIP_ER_INCONS, 0); - _zip_buffer_free(cd_buffer); - _zip_cdir_free(cd); - return NULL; - } - - if (za->open_flags & ZIP_CHECKCONS) { - bool ok; - - if (cd_buffer) { - ok = _zip_buffer_eof(cd_buffer); - } - else { - zip_int64_t offset = zip_source_tell(za->src); - - if (offset < 0) { - _zip_error_set_from_source(error, za->src); - _zip_cdir_free(cd); - return NULL; - } - ok = ((zip_uint64_t)offset == cd->offset + cd->size); - } - - if (!ok) { - zip_error_set(error, ZIP_ER_INCONS, 0); - _zip_buffer_free(cd_buffer); - _zip_cdir_free(cd); - return NULL; - } - } - - _zip_buffer_free(cd_buffer); - return cd; -} - - -/* _zip_checkcons: - Checks the consistency of the central directory by comparing central - directory entries with local headers and checking for plausible - file and header offsets. Returns -1 if not plausible, else the - difference between the lowest and the highest fileposition reached */ - -static zip_int64_t -_zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) { - zip_uint64_t i; - zip_uint64_t min, max, j; - struct zip_dirent temp; - - _zip_dirent_init(&temp); - if (cd->nentry) { - max = cd->entry[0].orig->offset; - min = cd->entry[0].orig->offset; - } - else - min = max = 0; - - for (i = 0; i < cd->nentry; i++) { - if (cd->entry[i].orig->offset < min) - min = cd->entry[i].orig->offset; - if (min > (zip_uint64_t)cd->offset) { - zip_error_set(error, ZIP_ER_NOZIP, 0); - return -1; - } - - j = cd->entry[i].orig->offset + cd->entry[i].orig->comp_size + _zip_string_length(cd->entry[i].orig->filename) + LENTRYSIZE; - if (j > max) - max = j; - if (max > (zip_uint64_t)cd->offset) { - zip_error_set(error, ZIP_ER_NOZIP, 0); - return -1; - } - - if (zip_source_seek(za->src, (zip_int64_t)cd->entry[i].orig->offset, SEEK_SET) < 0) { - _zip_error_set_from_source(error, za->src); - return -1; - } - - if (_zip_dirent_read(&temp, za->src, NULL, true, error) == -1) { - _zip_dirent_finalize(&temp); - return -1; - } - - if (_zip_headercomp(cd->entry[i].orig, &temp) != 0) { - zip_error_set(error, ZIP_ER_INCONS, 0); - _zip_dirent_finalize(&temp); - return -1; - } - - cd->entry[i].orig->extra_fields = _zip_ef_merge(cd->entry[i].orig->extra_fields, temp.extra_fields); - cd->entry[i].orig->local_extra_fields_read = 1; - temp.extra_fields = NULL; - - _zip_dirent_finalize(&temp); - } - - return (max - min) < ZIP_INT64_MAX ? (zip_int64_t)(max - min) : ZIP_INT64_MAX; -} - - -/* _zip_headercomp: - compares a central directory entry and a local file header - Return 0 if they are consistent, -1 if not. */ - -static int -_zip_headercomp(const zip_dirent_t *central, const zip_dirent_t *local) { - if ((central->version_needed < local->version_needed) -#if 0 - /* some zip-files have different values in local - and global headers for the bitflags */ - || (central->bitflags != local->bitflags) -#endif - || (central->comp_method != local->comp_method) || (central->last_mod != local->last_mod) || !_zip_string_equal(central->filename, local->filename)) - return -1; - - if ((central->crc != local->crc) || (central->comp_size != local->comp_size) || (central->uncomp_size != local->uncomp_size)) { - /* InfoZip stores valid values in local header even when data descriptor is used. - This is in violation of the appnote. */ - if (((local->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 || local->crc != 0 || local->comp_size != 0 || local->uncomp_size != 0)) - return -1; - } - - return 0; -} - - -static zip_t * -_zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error) { - zip_t *za; - - if ((za = _zip_new(error)) == NULL) { - return NULL; - } - - za->src = src; - za->open_flags = flags; - if (flags & ZIP_RDONLY) { - za->flags |= ZIP_AFL_RDONLY; - za->ch_flags |= ZIP_AFL_RDONLY; - } - return za; -} - - -/* - * tests for file existence - */ -static exists_t -_zip_file_exists(zip_source_t *src, zip_error_t *error) { - struct zip_stat st; - - zip_stat_init(&st); - if (zip_source_stat(src, &st) != 0) { - zip_error_t *src_error = zip_source_error(src); - if (zip_error_code_zip(src_error) == ZIP_ER_READ && zip_error_code_system(src_error) == ENOENT) { - return EXISTS_NOT; - } - _zip_error_copy(error, src_error); - return EXISTS_ERROR; - } - - return EXISTS_OK; -} - - -static zip_cdir_t * -_zip_find_central_dir(zip_t *za, zip_uint64_t len) { - zip_cdir_t *cdir, *cdirnew; - zip_uint8_t *match; - zip_int64_t buf_offset; - zip_uint64_t buflen; - zip_int64_t a; - zip_int64_t best; - zip_error_t error; - zip_buffer_t *buffer; - - if (len < EOCDLEN) { - zip_error_set(&za->error, ZIP_ER_NOZIP, 0); - return NULL; - } - - buflen = (len < CDBUFSIZE ? len : CDBUFSIZE); - if (zip_source_seek(za->src, -(zip_int64_t)buflen, SEEK_END) < 0) { - zip_error_t *src_error = zip_source_error(za->src); - if (zip_error_code_zip(src_error) != ZIP_ER_SEEK || zip_error_code_system(src_error) != EFBIG) { - /* seek before start of file on my machine */ - _zip_error_copy(&za->error, src_error); - return NULL; - } - } - if ((buf_offset = zip_source_tell(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); - return NULL; - } - - if ((buffer = _zip_buffer_new_from_source(za->src, buflen, NULL, &za->error)) == NULL) { - return NULL; - } - - best = -1; - cdir = NULL; - if (buflen >= CDBUFSIZE) { - /* EOCD64 locator is before EOCD, so leave place for it */ - _zip_buffer_set_offset(buffer, EOCD64LOCLEN); - } - zip_error_set(&error, ZIP_ER_NOZIP, 0); - - match = _zip_buffer_get(buffer, 0); - while ((match = _zip_memmem(match, _zip_buffer_left(buffer) - (EOCDLEN - 4), (const unsigned char *)EOCD_MAGIC, 4)) != NULL) { - _zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer))); - if ((cdirnew = _zip_read_cdir(za, buffer, (zip_uint64_t)buf_offset, &error)) != NULL) { - if (cdir) { - if (best <= 0) { - best = _zip_checkcons(za, cdir, &error); - } - - a = _zip_checkcons(za, cdirnew, &error); - if (best < a) { - _zip_cdir_free(cdir); - cdir = cdirnew; - best = a; - } - else { - _zip_cdir_free(cdirnew); - } - } - else { - cdir = cdirnew; - if (za->open_flags & ZIP_CHECKCONS) - best = _zip_checkcons(za, cdir, &error); - else { - best = 0; - } - } - cdirnew = NULL; - } - - match++; - _zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer))); - } - - _zip_buffer_free(buffer); - - if (best < 0) { - _zip_error_copy(&za->error, &error); - _zip_cdir_free(cdir); - return NULL; - } - - return cdir; -} - - -static unsigned char * -_zip_memmem(const unsigned char *big, size_t biglen, const unsigned char *little, size_t littlelen) { - const unsigned char *p; - - if ((biglen < littlelen) || (littlelen == 0)) - return NULL; - p = big - 1; - while ((p = (const unsigned char *)memchr(p + 1, little[0], (size_t)(big - (p + 1)) + (size_t)(biglen - littlelen) + 1)) != NULL) { - if (memcmp(p + 1, little + 1, littlelen - 1) == 0) - return (unsigned char *)p; - } - - return NULL; -} - - -static zip_cdir_t * -_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error) { - zip_cdir_t *cd; - zip_uint64_t i, nentry, size, offset, eocd_offset; - - if (_zip_buffer_left(buffer) < EOCDLEN) { - zip_error_set(error, ZIP_ER_INCONS, 0); - return NULL; - } - - eocd_offset = _zip_buffer_offset(buffer); - - _zip_buffer_get(buffer, 4); /* magic already verified */ - - if (_zip_buffer_get_32(buffer) != 0) { - zip_error_set(error, ZIP_ER_MULTIDISK, 0); - return NULL; - } - - /* number of cdir-entries on this disk */ - i = _zip_buffer_get_16(buffer); - /* number of cdir-entries */ - nentry = _zip_buffer_get_16(buffer); - - if (nentry != i) { - zip_error_set(error, ZIP_ER_NOZIP, 0); - return NULL; - } - - size = _zip_buffer_get_32(buffer); - offset = _zip_buffer_get_32(buffer); - - if (offset + size < offset) { - zip_error_set(error, ZIP_ER_SEEK, EFBIG); - return NULL; - } - - if (offset + size > buf_offset + eocd_offset) { - /* cdir spans past EOCD record */ - zip_error_set(error, ZIP_ER_INCONS, 0); - return NULL; - } - - if ((flags & ZIP_CHECKCONS) && offset + size != buf_offset + eocd_offset) { - zip_error_set(error, ZIP_ER_INCONS, 0); - return NULL; - } - - if ((cd = _zip_cdir_new(nentry, error)) == NULL) - return NULL; - - cd->is_zip64 = false; - cd->size = size; - cd->offset = offset; - - return cd; -} - - -static zip_cdir_t * -_zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error) { - zip_cdir_t *cd; - zip_uint64_t offset; - zip_uint8_t eocd[EOCD64LEN]; - zip_uint64_t eocd_offset; - zip_uint64_t size, nentry, i, eocdloc_offset; - bool free_buffer; - zip_uint32_t num_disks, num_disks64, eocd_disk, eocd_disk64; - - eocdloc_offset = _zip_buffer_offset(buffer); - - _zip_buffer_get(buffer, 4); /* magic already verified */ - - num_disks = _zip_buffer_get_16(buffer); - eocd_disk = _zip_buffer_get_16(buffer); - eocd_offset = _zip_buffer_get_64(buffer); - - /* valid seek value for start of EOCD */ - if (eocd_offset > ZIP_INT64_MAX) { - zip_error_set(error, ZIP_ER_SEEK, EFBIG); - return NULL; - } - - /* does EOCD fit before EOCD locator? */ - if (eocd_offset + EOCD64LEN > eocdloc_offset + buf_offset) { - zip_error_set(error, ZIP_ER_INCONS, 0); - return NULL; - } - - /* make sure current position of buffer is beginning of EOCD */ - if (eocd_offset >= buf_offset && eocd_offset + EOCD64LEN <= buf_offset + _zip_buffer_size(buffer)) { - _zip_buffer_set_offset(buffer, eocd_offset - buf_offset); - free_buffer = false; - } - else { - if (zip_source_seek(src, (zip_int64_t)eocd_offset, SEEK_SET) < 0) { - _zip_error_set_from_source(error, src); - return NULL; - } - if ((buffer = _zip_buffer_new_from_source(src, EOCD64LEN, eocd, error)) == NULL) { - return NULL; - } - free_buffer = true; - } - - if (memcmp(_zip_buffer_get(buffer, 4), EOCD64_MAGIC, 4) != 0) { - zip_error_set(error, ZIP_ER_INCONS, 0); - if (free_buffer) { - _zip_buffer_free(buffer); - } - return NULL; - } - - /* size of EOCD */ - size = _zip_buffer_get_64(buffer); - - /* is there a hole between EOCD and EOCD locator, or do they overlap? */ - if ((flags & ZIP_CHECKCONS) && size + eocd_offset + 12 != buf_offset + eocdloc_offset) { - zip_error_set(error, ZIP_ER_INCONS, 0); - if (free_buffer) { - _zip_buffer_free(buffer); - } - return NULL; - } - - _zip_buffer_get(buffer, 4); /* skip version made by/needed */ - - num_disks64 = _zip_buffer_get_32(buffer); - eocd_disk64 = _zip_buffer_get_32(buffer); - - /* if eocd values are 0xffff, we have to use eocd64 values. - otherwise, if the values are not the same, it's inconsistent; - in any case, if the value is not 0, we don't support it */ - if (num_disks == 0xffff) { - num_disks = num_disks64; - } - if (eocd_disk == 0xffff) { - eocd_disk = eocd_disk64; - } - if ((flags & ZIP_CHECKCONS) && (eocd_disk != eocd_disk64 || num_disks != num_disks64)) { - zip_error_set(error, ZIP_ER_INCONS, 0); - if (free_buffer) { - _zip_buffer_free(buffer); - } - return NULL; - } - if (num_disks != 0 || eocd_disk != 0) { - zip_error_set(error, ZIP_ER_MULTIDISK, 0); - if (free_buffer) { - _zip_buffer_free(buffer); - } - return NULL; - } - - nentry = _zip_buffer_get_64(buffer); - i = _zip_buffer_get_64(buffer); - - if (nentry != i) { - zip_error_set(error, ZIP_ER_MULTIDISK, 0); - if (free_buffer) { - _zip_buffer_free(buffer); - } - return NULL; - } - - size = _zip_buffer_get_64(buffer); - offset = _zip_buffer_get_64(buffer); - - /* did we read past the end of the buffer? */ - if (!_zip_buffer_ok(buffer)) { - zip_error_set(error, ZIP_ER_INTERNAL, 0); - if (free_buffer) { - _zip_buffer_free(buffer); - } - return NULL; - } - - if (free_buffer) { - _zip_buffer_free(buffer); - } - - if (offset > ZIP_INT64_MAX || offset + size < offset) { - zip_error_set(error, ZIP_ER_SEEK, EFBIG); - return NULL; - } - if (offset + size > buf_offset + eocd_offset) { - /* cdir spans past EOCD record */ - zip_error_set(error, ZIP_ER_INCONS, 0); - return NULL; - } - if ((flags & ZIP_CHECKCONS) && offset + size != buf_offset + eocd_offset) { - zip_error_set(error, ZIP_ER_INCONS, 0); - return NULL; - } - - if (nentry > size / CDENTRYSIZE) { - zip_error_set(error, ZIP_ER_INCONS, 0); - return NULL; - } - - if ((cd = _zip_cdir_new(nentry, error)) == NULL) - return NULL; - - cd->is_zip64 = true; - cd->size = size; - cd->offset = offset; - - return cd; -} diff --git a/ext/libzip/zip_pkware.c b/ext/libzip/zip_pkware.c deleted file mode 100644 index eb12b1e948..0000000000 --- a/ext/libzip/zip_pkware.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - zip_pkware.c -- Traditional PKWARE de/encryption backend routines - Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include -#include - -#include "zipint.h" - -#define PKWARE_KEY0 305419896 -#define PKWARE_KEY1 591751049 -#define PKWARE_KEY2 878082192 - - -static void -update_keys(zip_pkware_keys_t *keys, zip_uint8_t b) { - keys->key[0] = (zip_uint32_t)crc32(keys->key[0] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL; - keys->key[1] = (keys->key[1] + (keys->key[0] & 0xff)) * 134775813 + 1; - b = (zip_uint8_t)(keys->key[1] >> 24); - keys->key[2] = (zip_uint32_t)crc32(keys->key[2] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL; -} - - -static zip_uint8_t -crypt_byte(zip_pkware_keys_t *keys) { - zip_uint16_t tmp; - tmp = (zip_uint16_t)(keys->key[2] | 2); - tmp = (zip_uint16_t)(((zip_uint32_t)tmp * (tmp ^ 1)) >> 8); - return (zip_uint8_t)tmp; -} - - -void -_zip_pkware_keys_reset(zip_pkware_keys_t *keys) { - keys->key[0] = PKWARE_KEY0; - keys->key[1] = PKWARE_KEY1; - keys->key[2] = PKWARE_KEY2; -} - - -void -_zip_pkware_encrypt(zip_pkware_keys_t *keys, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len) { - zip_uint64_t i; - zip_uint8_t b; - zip_uint8_t tmp; - - for (i = 0; i < len; i++) { - b = in[i]; - - if (out != NULL) { - tmp = crypt_byte(keys); - update_keys(keys, b); - b ^= tmp; - out[i] = b; - } - else { - /* during initialization, we're only interested in key updates */ - update_keys(keys, b); - } - } -} - - -void -_zip_pkware_decrypt(zip_pkware_keys_t *keys, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len) { - zip_uint64_t i; - zip_uint8_t b; - zip_uint8_t tmp; - - for (i = 0; i < len; i++) { - b = in[i]; - - /* during initialization, we're only interested in key updates */ - if (out != NULL) { - tmp = crypt_byte(keys); - b ^= tmp; - out[i] = b; - } - - update_keys(keys, b); - } -} diff --git a/ext/libzip/zip_progress.c b/ext/libzip/zip_progress.c deleted file mode 100644 index ddb47c70a5..0000000000 --- a/ext/libzip/zip_progress.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - zip_progress.c -- progress reporting - Copyright (C) 2017-2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#include - - -#define _ZIP_COMPILING_DEPRECATED -#include "zipint.h" - -struct zip_progress { - zip_t *za; - - zip_progress_callback callback_progress; - void (*ud_progress_free)(void *); - void *ud_progress; - - zip_cancel_callback callback_cancel; - void (*ud_cancel_free)(void *); - void *ud_cancel; - - double precision; - - /* state */ - double last_update; /* last value callback function was called with */ - - double start; /* start of sub-progress section */ - double end; /* end of sub-progress section */ -}; - -static void _zip_progress_free_cancel_callback(zip_progress_t *progress); -static void _zip_progress_free_progress_callback(zip_progress_t *progress); -static zip_progress_t *_zip_progress_new(zip_t *za); -static void _zip_progress_set_cancel_callback(zip_progress_t *progress, zip_cancel_callback callback, void (*ud_free)(void *), void *ud); -static void _zip_progress_set_progress_callback(zip_progress_t *progress, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud); - -void -_zip_progress_end(zip_progress_t *progress) { - _zip_progress_update(progress, 1.0); -} - - -void -_zip_progress_free(zip_progress_t *progress) { - if (progress == NULL) { - return; - } - - _zip_progress_free_progress_callback(progress); - _zip_progress_free_cancel_callback(progress); - - free(progress); -} - - -static zip_progress_t * -_zip_progress_new(zip_t *za) { - zip_progress_t *progress = (zip_progress_t *)malloc(sizeof(*progress)); - - if (progress == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return NULL; - } - - progress->za = za; - - progress->callback_progress = NULL; - progress->ud_progress_free = NULL; - progress->ud_progress = NULL; - progress->precision = 0.0; - - progress->callback_cancel = NULL; - progress->ud_cancel_free = NULL; - progress->ud_cancel = NULL; - - return progress; -} - -static void -_zip_progress_free_progress_callback(zip_progress_t *progress) { - if (progress->ud_progress_free) { - progress->ud_progress_free(progress->ud_progress); - } - - progress->callback_progress = NULL; - progress->ud_progress = NULL; - progress->ud_progress_free = NULL; -} - -static void -_zip_progress_free_cancel_callback(zip_progress_t *progress) { - if (progress->ud_cancel_free) { - progress->ud_cancel_free(progress->ud_cancel); - } - - progress->callback_cancel = NULL; - progress->ud_cancel = NULL; - progress->ud_cancel_free = NULL; -} - -static void -_zip_progress_set_progress_callback(zip_progress_t *progress, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud) { - _zip_progress_free_progress_callback(progress); - - progress->callback_progress = callback; - progress->ud_progress_free = ud_free; - progress->ud_progress = ud; - progress->precision = precision; -} - -void -_zip_progress_set_cancel_callback(zip_progress_t *progress, zip_cancel_callback callback, void (*ud_free)(void *), void *ud) { - _zip_progress_free_cancel_callback(progress); - - progress->callback_cancel = callback; - progress->ud_cancel_free = ud_free; - progress->ud_cancel = ud; -} - -int -_zip_progress_start(zip_progress_t *progress) { - if (progress == NULL) { - return 0; - } - - if (progress->callback_progress != NULL) { - progress->last_update = 0.0; - progress->callback_progress(progress->za, 0.0, progress->ud_progress); - } - - if (progress->callback_cancel != NULL) { - if (progress->callback_cancel(progress->za, progress->ud_cancel)) { - return -1; - } - } - - return 0; -} - - -int -_zip_progress_subrange(zip_progress_t *progress, double start, double end) { - if (progress == NULL) { - return 0; - } - - progress->start = start; - progress->end = end; - - return _zip_progress_update(progress, 0.0); -} - -int -_zip_progress_update(zip_progress_t *progress, double sub_current) { - double current; - - if (progress == NULL) { - return 0; - } - - if (progress->callback_progress != NULL) { - current = ZIP_MIN(ZIP_MAX(sub_current, 0.0), 1.0) * (progress->end - progress->start) + progress->start; - - if (current - progress->last_update > progress->precision) { - progress->callback_progress(progress->za, current, progress->ud_progress); - progress->last_update = current; - } - } - - if (progress->callback_cancel != NULL) { - if (progress->callback_cancel(progress->za, progress->ud_cancel)) { - return -1; - } - } - - return 0; -} - - -ZIP_EXTERN int -zip_register_progress_callback_with_state(zip_t *za, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud) { - if (callback != NULL) { - if (za->progress == NULL) { - if ((za->progress = _zip_progress_new(za)) == NULL) { - return -1; - } - } - - _zip_progress_set_progress_callback(za->progress, precision, callback, ud_free, ud); - } - else { - if (za->progress != NULL) { - if (za->progress->callback_cancel == NULL) { - _zip_progress_free(za->progress); - za->progress = NULL; - } - else { - _zip_progress_free_progress_callback(za->progress); - } - } - } - - return 0; -} - - -ZIP_EXTERN int -zip_register_cancel_callback_with_state(zip_t *za, zip_cancel_callback callback, void (*ud_free)(void *), void *ud) { - if (callback != NULL) { - if (za->progress == NULL) { - if ((za->progress = _zip_progress_new(za)) == NULL) { - return -1; - } - } - - _zip_progress_set_cancel_callback(za->progress, callback, ud_free, ud); - } - else { - if (za->progress != NULL) { - if (za->progress->callback_progress == NULL) { - _zip_progress_free(za->progress); - za->progress = NULL; - } - else { - _zip_progress_free_cancel_callback(za->progress); - } - } - } - - return 0; -} - - -struct legacy_ud { - zip_progress_callback_t callback; -}; - - -static void -_zip_legacy_progress_callback(zip_t *za, double progress, void *vud) { - struct legacy_ud *ud = (struct legacy_ud *)vud; - - ud->callback(progress); -} - -ZIP_EXTERN void -zip_register_progress_callback(zip_t *za, zip_progress_callback_t progress_callback) { - struct legacy_ud *ud; - - if (progress_callback == NULL) { - zip_register_progress_callback_with_state(za, 0, NULL, NULL, NULL); - } - - if ((ud = (struct legacy_ud *)malloc(sizeof(*ud))) == NULL) { - return; - } - - ud->callback = progress_callback; - - if (zip_register_progress_callback_with_state(za, 0.001, _zip_legacy_progress_callback, free, ud) < 0) { - free(ud); - } -} diff --git a/ext/libzip/zip_random_unix.c b/ext/libzip/zip_random_unix.c deleted file mode 100644 index 1d0c9674a7..0000000000 --- a/ext/libzip/zip_random_unix.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - zip_random_unix.c -- fill the user's buffer with random stuff (Unix version) - Copyright (C) 2016-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "zipint.h" - -#ifdef HAVE_CRYPTO -#include "zip_crypto.h" -#endif - -#ifdef HAVE_ARC4RANDOM - -#include - -#ifndef HAVE_SECURE_RANDOM -ZIP_EXTERN bool -zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) { - arc4random_buf(buffer, length); - return true; -} -#endif - -#ifndef HAVE_RANDOM_UINT32 -zip_uint32_t -zip_random_uint32(void) { - return arc4random(); -} -#endif - -#else /* HAVE_ARC4RANDOM */ - -#ifndef HAVE_SECURE_RANDOM -#include -#include - -ZIP_EXTERN bool -zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) { - int fd; - - if ((fd = open("/dev/urandom", O_RDONLY)) < 0) { - return false; - } - - if (read(fd, buffer, length) != length) { - close(fd); - return false; - } - - close(fd); - return true; -} -#endif - -#ifndef HAVE_RANDOM_UINT32 -#include - -zip_uint32_t -zip_random_uint32(void) { - static bool seeded = false; - - zip_uint32_t value; - - if (zip_secure_random((zip_uint8_t *)&value, sizeof(value))) { - return value; - } - - if (!seeded) { - srandom((unsigned int)time(NULL)); - } - - return (zip_uint32_t)random(); -} -#endif - -#endif /* HAVE_ARC4RANDOM */ diff --git a/ext/libzip/zip_random_uwp.c b/ext/libzip/zip_random_uwp.c deleted file mode 100644 index 70c998cfa4..0000000000 --- a/ext/libzip/zip_random_uwp.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - zip_random_uwp.c -- fill the user's buffer with random stuff (UWP version) - Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "zipint.h" - -#ifdef HAVE_CRYPTO -#include "zip_crypto.h" -#endif - -#ifndef HAVE_SECURE_RANDOM - -#include -#include -#include - -ZIP_EXTERN bool -zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) { - BCRYPT_ALG_HANDLE hAlg = NULL; - NTSTATUS hr = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); - if (hr != STATUS_SUCCESS || hAlg == NULL) { - return false; - } - hr = BCryptGenRandom(&hAlg, buffer, length, 0); - BCryptCloseAlgorithmProvider(&hAlg, 0); - if (hr != STATUS_SUCCESS) { - return false; - } - return true; -} - -#endif - -#ifndef HAVE_RANDOM_UINT32 -#include - -zip_uint32_t -zip_random_uint32(void) { - static bool seeded = false; - - zip_uint32_t value; - - if (zip_secure_random((zip_uint8_t *)&value, sizeof(value))) { - return value; - } - - if (!seeded) { - srand((unsigned int)time(NULL)); - } - - return (zip_uint32_t)rand(); -} -#endif diff --git a/ext/libzip/zip_random_win32.c b/ext/libzip/zip_random_win32.c deleted file mode 100644 index 19d488eced..0000000000 --- a/ext/libzip/zip_random_win32.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - zip_random_win32.c -- fill the user's buffer with random stuff (Windows version) - Copyright (C) 2016-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "zipint.h" - -#ifdef HAVE_CRYPTO -#include "zip_crypto.h" -#endif - -#include - -#ifndef HAVE_SECURE_RANDOM - -#include - -ZIP_EXTERN bool -zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) { - HCRYPTPROV hprov; - if (!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { - return false; - } - if (!CryptGenRandom(hprov, length, buffer)) { - return false; - } - if (!CryptReleaseContext(hprov, 0)) { - return false; - } - return true; -} -#endif - -#ifndef HAVE_RANDOM_UINT32 -#include - -zip_uint32_t -zip_random_uint32(void) { - static bool seeded = false; - - zip_uint32_t value; - - if (zip_secure_random((zip_uint8_t *)&value, sizeof(value))) { - return value; - } - - if (!seeded) { - srand((unsigned int)time(NULL)); - } - - return (zip_uint32_t)rand(); -} -#endif diff --git a/ext/libzip/zip_rename.c b/ext/libzip/zip_rename.c deleted file mode 100644 index 75b456de56..0000000000 --- a/ext/libzip/zip_rename.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - zip_rename.c -- rename file in zip archive - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#define _ZIP_COMPILING_DEPRECATED -#include "zipint.h" - - -ZIP_EXTERN int -zip_rename(zip_t *za, zip_uint64_t idx, const char *name) { - return zip_file_rename(za, idx, name, 0); -} diff --git a/ext/libzip/zip_replace.c b/ext/libzip/zip_replace.c deleted file mode 100644 index 30a2eb1d63..0000000000 --- a/ext/libzip/zip_replace.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - zip_replace.c -- replace file via callback function - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#define _ZIP_COMPILING_DEPRECATED -#include "zipint.h" - - -ZIP_EXTERN int -zip_replace(zip_t *za, zip_uint64_t idx, zip_source_t *source) { - return zip_file_replace(za, idx, source, 0); -} diff --git a/ext/libzip/zip_set_archive_comment.c b/ext/libzip/zip_set_archive_comment.c deleted file mode 100644 index 3f050b3eaa..0000000000 --- a/ext/libzip/zip_set_archive_comment.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - zip_set_archive_comment.c -- set archive comment - Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include - -#include "zipint.h" - - -ZIP_EXTERN int -zip_set_archive_comment(zip_t *za, const char *comment, zip_uint16_t len) { - zip_string_t *cstr; - - if (ZIP_IS_RDONLY(za)) { - zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - if (len > 0 && comment == NULL) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (len > 0) { - if ((cstr = _zip_string_new((const zip_uint8_t *)comment, len, ZIP_FL_ENC_GUESS, &za->error)) == NULL) - return -1; - - if (_zip_guess_encoding(cstr, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_CP437) { - _zip_string_free(cstr); - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - } - else - cstr = NULL; - - _zip_string_free(za->comment_changes); - za->comment_changes = NULL; - - if (((za->comment_orig && _zip_string_equal(za->comment_orig, cstr)) || (za->comment_orig == NULL && cstr == NULL))) { - _zip_string_free(cstr); - za->comment_changed = 0; - } - else { - za->comment_changes = cstr; - za->comment_changed = 1; - } - - return 0; -} diff --git a/ext/libzip/zip_set_archive_flag.c b/ext/libzip/zip_set_archive_flag.c deleted file mode 100644 index e0d550212f..0000000000 --- a/ext/libzip/zip_set_archive_flag.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - zip_get_archive_flag.c -- set archive global flag - Copyright (C) 2008-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN int -zip_set_archive_flag(zip_t *za, zip_flags_t flag, int value) { - unsigned int new_flags; - - if (value) - new_flags = za->ch_flags | flag; - else - new_flags = za->ch_flags & ~flag; - - if (new_flags == za->ch_flags) - return 0; - - if (ZIP_IS_RDONLY(za)) { - zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - if ((flag & ZIP_AFL_RDONLY) && value && (za->ch_flags & ZIP_AFL_RDONLY) == 0) { - if (_zip_changed(za, NULL)) { - zip_error_set(&za->error, ZIP_ER_CHANGED, 0); - return -1; - } - } - - za->ch_flags = new_flags; - - return 0; -} diff --git a/ext/libzip/zip_set_default_password.c b/ext/libzip/zip_set_default_password.c deleted file mode 100644 index 41c7c51969..0000000000 --- a/ext/libzip/zip_set_default_password.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - zip_set_default_password.c -- set default password for decryption - Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include -#include - -#include "zipint.h" - - -ZIP_EXTERN int -zip_set_default_password(zip_t *za, const char *passwd) { - if (za == NULL) - return -1; - - free(za->default_password); - - if (passwd) { - if ((za->default_password = strdup(passwd)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - } - else - za->default_password = NULL; - - return 0; -} diff --git a/ext/libzip/zip_set_file_comment.c b/ext/libzip/zip_set_file_comment.c deleted file mode 100644 index 4277893f23..0000000000 --- a/ext/libzip/zip_set_file_comment.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - zip_set_file_comment.c -- set comment for file in archive - Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#define _ZIP_COMPILING_DEPRECATED -#include "zipint.h" - - -ZIP_EXTERN int -zip_set_file_comment(zip_t *za, zip_uint64_t idx, const char *comment, int len) { - if (len < 0 || len > ZIP_UINT16_MAX) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - return zip_file_set_comment(za, idx, comment, (zip_uint16_t)len, 0); -} diff --git a/ext/libzip/zip_set_file_compression.c b/ext/libzip/zip_set_file_compression.c deleted file mode 100644 index 927fbb7682..0000000000 --- a/ext/libzip/zip_set_file_compression.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - zip_set_file_compression.c -- set compression for file in archive - Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN int -zip_set_file_compression(zip_t *za, zip_uint64_t idx, zip_int32_t method, zip_uint32_t flags) { - zip_entry_t *e; - zip_int32_t old_method; - - if (idx >= za->nentry || flags > 9) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (ZIP_IS_RDONLY(za)) { - zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - if (!zip_compression_method_supported(method, true)) { - zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); - return -1; - } - - e = za->entry + idx; - - old_method = (e->orig == NULL ? ZIP_CM_DEFAULT : e->orig->comp_method); - - /* TODO: do we want to recompress if level is set? Only if it's - * different than what bit flags tell us, but those are not - * defined for all compression methods, or not directly mappable - * to levels */ - - if (method == old_method) { - if (e->changes) { - e->changes->changed &= ~ZIP_DIRENT_COMP_METHOD; - e->changes->compression_level = 0; - if (e->changes->changed == 0) { - _zip_dirent_free(e->changes); - e->changes = NULL; - } - } - } - else { - if (e->changes == NULL) { - if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - } - - e->changes->comp_method = method; - e->changes->compression_level = (zip_uint16_t)flags; - e->changes->changed |= ZIP_DIRENT_COMP_METHOD; - } - - return 0; -} diff --git a/ext/libzip/zip_set_name.c b/ext/libzip/zip_set_name.c deleted file mode 100644 index 43c772e48a..0000000000 --- a/ext/libzip/zip_set_name.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - zip_set_name.c -- rename helper function - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include -#include - -#include "zipint.h" - - -int -_zip_set_name(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags) { - zip_entry_t *e; - zip_string_t *str; - bool same_as_orig; - zip_int64_t i; - const zip_uint8_t *old_name, *new_name; - zip_string_t *old_str; - - if (idx >= za->nentry) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (ZIP_IS_RDONLY(za)) { - zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - if (name && name[0] != '\0') { - /* TODO: check for string too long */ - if ((str = _zip_string_new((const zip_uint8_t *)name, (zip_uint16_t)strlen(name), flags, &za->error)) == NULL) - return -1; - if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(str, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED) - str->encoding = ZIP_ENCODING_UTF8_KNOWN; - } - else - str = NULL; - - /* TODO: encoding flags needed for CP437? */ - if ((i = _zip_name_locate(za, name, 0, NULL)) >= 0 && (zip_uint64_t)i != idx) { - _zip_string_free(str); - zip_error_set(&za->error, ZIP_ER_EXISTS, 0); - return -1; - } - - /* no effective name change */ - if (i >= 0 && (zip_uint64_t)i == idx) { - _zip_string_free(str); - return 0; - } - - e = za->entry + idx; - - if (e->orig) - same_as_orig = _zip_string_equal(e->orig->filename, str); - else - same_as_orig = false; - - if (!same_as_orig && e->changes == NULL) { - if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - _zip_string_free(str); - return -1; - } - } - - if ((new_name = _zip_string_get(same_as_orig ? e->orig->filename : str, NULL, 0, &za->error)) == NULL) { - _zip_string_free(str); - return -1; - } - - if (e->changes) { - old_str = e->changes->filename; - } - else if (e->orig) { - old_str = e->orig->filename; - } - else { - old_str = NULL; - } - - if (old_str) { - if ((old_name = _zip_string_get(old_str, NULL, 0, &za->error)) == NULL) { - _zip_string_free(str); - return -1; - } - } - else { - old_name = NULL; - } - - if (_zip_hash_add(za->names, new_name, idx, 0, &za->error) == false) { - _zip_string_free(str); - return -1; - } - if (old_name) { - _zip_hash_delete(za->names, old_name, NULL); - } - - if (same_as_orig) { - if (e->changes) { - if (e->changes->changed & ZIP_DIRENT_FILENAME) { - _zip_string_free(e->changes->filename); - e->changes->changed &= ~ZIP_DIRENT_FILENAME; - if (e->changes->changed == 0) { - _zip_dirent_free(e->changes); - e->changes = NULL; - } - else { - /* TODO: what if not cloned? can that happen? */ - e->changes->filename = e->orig->filename; - } - } - } - _zip_string_free(str); - } - else { - if (e->changes->changed & ZIP_DIRENT_FILENAME) { - _zip_string_free(e->changes->filename); - } - e->changes->changed |= ZIP_DIRENT_FILENAME; - e->changes->filename = str; - } - - return 0; -} diff --git a/ext/libzip/zip_source_accept_empty.c b/ext/libzip/zip_source_accept_empty.c deleted file mode 100644 index e6d515168c..0000000000 --- a/ext/libzip/zip_source_accept_empty.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - zip_source_accept_empty.c -- if empty source is a valid archive - Copyright (C) 2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -bool -zip_source_accept_empty(zip_source_t *src) { - int ret; - - if ((zip_source_supports(src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ACCEPT_EMPTY)) == 0) { - if (ZIP_SOURCE_IS_LAYERED(src)) { - return zip_source_accept_empty(src->src); - } - return true; - } - - ret = (int)_zip_source_call(src, NULL, 0, ZIP_SOURCE_ACCEPT_EMPTY); - - return ret != 0; -} diff --git a/ext/libzip/zip_source_begin_write.c b/ext/libzip/zip_source_begin_write.c deleted file mode 100644 index 432c2c15a8..0000000000 --- a/ext/libzip/zip_source_begin_write.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - zip_source_begin_write.c -- start a new file for writing - Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN int -zip_source_begin_write(zip_source_t *src) { - if (ZIP_SOURCE_IS_OPEN_WRITING(src)) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_BEGIN_WRITE) < 0) { - return -1; - } - - src->write_state = ZIP_SOURCE_WRITE_OPEN; - - return 0; -} diff --git a/ext/libzip/zip_source_begin_write_cloning.c b/ext/libzip/zip_source_begin_write_cloning.c deleted file mode 100644 index 41b4c73c3d..0000000000 --- a/ext/libzip/zip_source_begin_write_cloning.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - zip_source_begin_write_cloning.c -- clone part of file for writing - Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN int -zip_source_begin_write_cloning(zip_source_t *src, zip_uint64_t offset) { - if (ZIP_SOURCE_IS_OPEN_WRITING(src)) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (_zip_source_call(src, NULL, offset, ZIP_SOURCE_BEGIN_WRITE_CLONING) < 0) { - return -1; - } - - src->write_state = ZIP_SOURCE_WRITE_OPEN; - - return 0; -} diff --git a/ext/libzip/zip_source_buffer.c b/ext/libzip/zip_source_buffer.c deleted file mode 100644 index 519d2c30da..0000000000 --- a/ext/libzip/zip_source_buffer.c +++ /dev/null @@ -1,620 +0,0 @@ -/* - zip_source_buffer.c -- create zip data source from buffer - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include - -#include "zipint.h" - -#ifndef WRITE_FRAGMENT_SIZE -#define WRITE_FRAGMENT_SIZE (64 * 1024) -#endif - -struct buffer { - zip_buffer_fragment_t *fragments; /* fragments */ - zip_uint64_t *fragment_offsets; /* offset of each fragment from start of buffer, nfragments+1 entries */ - zip_uint64_t nfragments; /* number of allocated fragments */ - zip_uint64_t fragments_capacity; /* size of fragments (number of pointers) */ - - zip_uint64_t first_owned_fragment; /* first fragment to free data from */ - - zip_uint64_t shared_fragments; /* number of shared fragments */ - struct buffer *shared_buffer; /* buffer fragments are shared with */ - zip_uint64_t size; /* size of buffer */ - - zip_uint64_t offset; /* current offset in buffer */ - zip_uint64_t current_fragment; /* fragment current offset is in */ -}; - -typedef struct buffer buffer_t; - -struct read_data { - zip_error_t error; - time_t mtime; - zip_file_attributes_t attributes; - buffer_t *in; - buffer_t *out; -}; - -#define buffer_capacity(buffer) ((buffer)->fragment_offsets[(buffer)->nfragments]) -#define buffer_size(buffer) ((buffer)->size) - -static buffer_t *buffer_clone(buffer_t *buffer, zip_uint64_t length, zip_error_t *error); -static zip_uint64_t buffer_find_fragment(const buffer_t *buffer, zip_uint64_t offset); -static void buffer_free(buffer_t *buffer); -static bool buffer_grow_fragments(buffer_t *buffer, zip_uint64_t capacity, zip_error_t *error); -static buffer_t *buffer_new(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int free_data, zip_error_t *error); -static zip_int64_t buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length); -static int buffer_seek(buffer_t *buffer, void *data, zip_uint64_t len, zip_error_t *error); -static zip_int64_t buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip_error_t *); - -static zip_int64_t read_data(void *, void *, zip_uint64_t, zip_source_cmd_t); - -zip_source_t *zip_source_buffer_with_attributes_create(const void *data, zip_uint64_t len, int freep, zip_file_attributes_t *attributes, zip_error_t *error); -zip_source_t *zip_source_buffer_fragment_with_attributes_create(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int freep, zip_file_attributes_t *attributes, zip_error_t *error); - - -ZIP_EXTERN zip_source_t * -zip_source_buffer(zip_t *za, const void *data, zip_uint64_t len, int freep) { - if (za == NULL) - return NULL; - - return zip_source_buffer_with_attributes_create(data, len, freep, NULL, &za->error); -} - - -ZIP_EXTERN zip_source_t * -zip_source_buffer_create(const void *data, zip_uint64_t len, int freep, zip_error_t *error) { - return zip_source_buffer_with_attributes_create(data, len, freep, NULL, error); -} - - -zip_source_t * -zip_source_buffer_with_attributes_create(const void *data, zip_uint64_t len, int freep, zip_file_attributes_t *attributes, zip_error_t *error) { - zip_buffer_fragment_t fragment; - - if (data == NULL) { - if (len > 0) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - return zip_source_buffer_fragment_with_attributes_create(NULL, 0, freep, attributes, error); - } - - fragment.data = (zip_uint8_t *)data; - fragment.length = len; - - return zip_source_buffer_fragment_with_attributes_create(&fragment, 1, freep, attributes, error); -} - - -ZIP_EXTERN zip_source_t * -zip_source_buffer_fragment(zip_t *za, const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int freep) { - if (za == NULL) { - return NULL; - } - - return zip_source_buffer_fragment_with_attributes_create(fragments, nfragments, freep, NULL, &za->error); -} - - -ZIP_EXTERN zip_source_t * -zip_source_buffer_fragment_create(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int freep, zip_error_t *error) { - return zip_source_buffer_fragment_with_attributes_create(fragments, nfragments, freep, NULL, error); -} - -zip_source_t * -zip_source_buffer_fragment_with_attributes_create(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int freep, zip_file_attributes_t *attributes, zip_error_t *error) { - struct read_data *ctx; - zip_source_t *zs; - buffer_t *buffer; - - if (fragments == NULL && nfragments > 0) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - if ((buffer = buffer_new(fragments, nfragments, freep, error)) == NULL) { - return NULL; - } - - if ((ctx = (struct read_data *)malloc(sizeof(*ctx))) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - buffer_free(buffer); - return NULL; - } - - ctx->in = buffer; - ctx->out = NULL; - ctx->mtime = time(NULL); - if (attributes) { - memcpy(&ctx->attributes, attributes, sizeof(ctx->attributes)); - } - else { - zip_file_attributes_init(&ctx->attributes); - } - zip_error_init(&ctx->error); - - if ((zs = zip_source_function_create(read_data, ctx, error)) == NULL) { - buffer_free(ctx->in); - free(ctx); - return NULL; - } - - return zs; -} - - -zip_source_t * -zip_source_buffer_with_attributes(zip_t *za, const void *data, zip_uint64_t len, int freep, zip_file_attributes_t *attributes) { - return zip_source_buffer_with_attributes_create(data, len, freep, attributes, &za->error); -} - -static zip_int64_t -read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { - struct read_data *ctx = (struct read_data *)state; - - switch (cmd) { - case ZIP_SOURCE_BEGIN_WRITE: - if ((ctx->out = buffer_new(NULL, 0, 0, &ctx->error)) == NULL) { - return -1; - } - ctx->out->offset = 0; - ctx->out->current_fragment = 0; - return 0; - - case ZIP_SOURCE_BEGIN_WRITE_CLONING: - if ((ctx->out = buffer_clone(ctx->in, len, &ctx->error)) == NULL) { - return -1; - } - ctx->out->offset = len; - ctx->out->current_fragment = ctx->out->nfragments; - return 0; - - case ZIP_SOURCE_CLOSE: - return 0; - - case ZIP_SOURCE_COMMIT_WRITE: - buffer_free(ctx->in); - ctx->in = ctx->out; - ctx->out = NULL; - return 0; - - case ZIP_SOURCE_ERROR: - return zip_error_to_data(&ctx->error, data, len); - - case ZIP_SOURCE_FREE: - buffer_free(ctx->in); - buffer_free(ctx->out); - free(ctx); - return 0; - - case ZIP_SOURCE_GET_FILE_ATTRIBUTES: { - if (len < sizeof(ctx->attributes)) { - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } - - memcpy(data, &ctx->attributes, sizeof(ctx->attributes)); - - return sizeof(ctx->attributes); - } - - case ZIP_SOURCE_OPEN: - ctx->in->offset = 0; - ctx->in->current_fragment = 0; - return 0; - - case ZIP_SOURCE_READ: - if (len > ZIP_INT64_MAX) { - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } - return buffer_read(ctx->in, data, len); - - case ZIP_SOURCE_REMOVE: { - buffer_t *empty = buffer_new(NULL, 0, 0, &ctx->error); - if (empty == NULL) { - return -1; - } - - buffer_free(ctx->in); - ctx->in = empty; - return 0; - } - - case ZIP_SOURCE_ROLLBACK_WRITE: - buffer_free(ctx->out); - ctx->out = NULL; - return 0; - - case ZIP_SOURCE_SEEK: - return buffer_seek(ctx->in, data, len, &ctx->error); - - case ZIP_SOURCE_SEEK_WRITE: - return buffer_seek(ctx->out, data, len, &ctx->error); - - case ZIP_SOURCE_STAT: { - zip_stat_t *st; - - if (len < sizeof(*st)) { - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } - - st = (zip_stat_t *)data; - - zip_stat_init(st); - st->mtime = ctx->mtime; - st->size = ctx->in->size; - st->comp_size = st->size; - st->comp_method = ZIP_CM_STORE; - st->encryption_method = ZIP_EM_NONE; - st->valid = ZIP_STAT_MTIME | ZIP_STAT_SIZE | ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD | ZIP_STAT_ENCRYPTION_METHOD; - - return sizeof(*st); - } - - case ZIP_SOURCE_SUPPORTS: - return zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_BEGIN_WRITE_CLONING, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_WRITE, -1); - - case ZIP_SOURCE_TELL: - if (ctx->in->offset > ZIP_INT64_MAX) { - zip_error_set(&ctx->error, ZIP_ER_TELL, EOVERFLOW); - return -1; - } - return (zip_int64_t)ctx->in->offset; - - - case ZIP_SOURCE_TELL_WRITE: - if (ctx->out->offset > ZIP_INT64_MAX) { - zip_error_set(&ctx->error, ZIP_ER_TELL, EOVERFLOW); - return -1; - } - return (zip_int64_t)ctx->out->offset; - - case ZIP_SOURCE_WRITE: - if (len > ZIP_INT64_MAX) { - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } - return buffer_write(ctx->out, data, len, &ctx->error); - - default: - zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); - return -1; - } -} - - -static buffer_t * -buffer_clone(buffer_t *buffer, zip_uint64_t offset, zip_error_t *error) { - zip_uint64_t fragment, fragment_offset, waste; - buffer_t *clone; - - if (offset == 0) { - return buffer_new(NULL, 0, 1, error); - } - - if (offset > buffer->size) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - if (buffer->shared_buffer != NULL) { - zip_error_set(error, ZIP_ER_INUSE, 0); - return NULL; - } - - fragment = buffer_find_fragment(buffer, offset); - fragment_offset = offset - buffer->fragment_offsets[fragment]; - - if (fragment_offset == 0) { - fragment--; - fragment_offset = buffer->fragments[fragment].length; - } - - waste = buffer->fragments[fragment].length - fragment_offset; - if (waste > offset) { - zip_error_set(error, ZIP_ER_OPNOTSUPP, 0); - return NULL; - } - - if ((clone = buffer_new(buffer->fragments, fragment + 1, 0, error)) == NULL) { - return NULL; - } - -#ifndef __clang_analyzer__ - /* clone->fragments can't be null, since it was created with at least one fragment */ - clone->fragments[clone->nfragments - 1].length = fragment_offset; -#endif - clone->fragment_offsets[clone->nfragments] = offset; - clone->size = offset; - - clone->first_owned_fragment = ZIP_MIN(buffer->first_owned_fragment, clone->nfragments - 1); - - buffer->shared_buffer = clone; - clone->shared_buffer = buffer; - buffer->shared_fragments = clone->nfragments; - clone->shared_fragments = fragment + 1; - - return clone; -} - - -static zip_uint64_t -buffer_find_fragment(const buffer_t *buffer, zip_uint64_t offset) { - zip_uint64_t low, high, mid; - - low = 0; - high = buffer->nfragments - 1; - - while (low < high) { - mid = (high - low) / 2 + low; - if (buffer->fragment_offsets[mid] > offset) { - high = mid - 1; - } - else if (mid == buffer->nfragments || buffer->fragment_offsets[mid + 1] > offset) { - return mid; - } - else { - low = mid + 1; - } - } - - return low; -} - - -static void -buffer_free(buffer_t *buffer) { - zip_uint64_t i; - - if (buffer == NULL) { - return; - } - - if (buffer->shared_buffer != NULL) { - buffer->shared_buffer->shared_buffer = NULL; - buffer->shared_buffer->shared_fragments = 0; - - buffer->first_owned_fragment = ZIP_MAX(buffer->first_owned_fragment, buffer->shared_fragments); - } - - for (i = buffer->first_owned_fragment; i < buffer->nfragments; i++) { - free(buffer->fragments[i].data); - } - free(buffer->fragments); - free(buffer->fragment_offsets); - free(buffer); -} - - -static bool -buffer_grow_fragments(buffer_t *buffer, zip_uint64_t capacity, zip_error_t *error) { - zip_buffer_fragment_t *fragments; - zip_uint64_t *offsets; - - if (capacity < buffer->fragments_capacity) { - return true; - } - - if ((fragments = realloc(buffer->fragments, sizeof(buffer->fragments[0]) * capacity)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return false; - } - buffer->fragments = fragments; - if ((offsets = realloc(buffer->fragment_offsets, sizeof(buffer->fragment_offsets[0]) * (capacity + 1))) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return false; - } - buffer->fragment_offsets = offsets; - buffer->fragments_capacity = capacity; - - return true; -} - - -static buffer_t * -buffer_new(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int free_data, zip_error_t *error) { - buffer_t *buffer; - - if ((buffer = malloc(sizeof(*buffer))) == NULL) { - return NULL; - } - - buffer->offset = 0; - buffer->first_owned_fragment = 0; - buffer->size = 0; - buffer->fragments = NULL; - buffer->fragment_offsets = NULL; - buffer->nfragments = 0; - buffer->fragments_capacity = 0; - buffer->shared_buffer = NULL; - buffer->shared_fragments = 0; - - if (nfragments == 0) { - if ((buffer->fragment_offsets = malloc(sizeof(buffer->fragment_offsets[0]))) == NULL) { - free(buffer); - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; - } - buffer->fragment_offsets[0] = 0; - } - else { - zip_uint64_t i, j, offset; - - if (!buffer_grow_fragments(buffer, nfragments, NULL)) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - buffer_free(buffer); - return NULL; - } - - offset = 0; - for (i = 0, j = 0; i < nfragments; i++) { - if (fragments[i].length == 0) { - continue; - } - if (fragments[i].data == NULL) { - zip_error_set(error, ZIP_ER_INVAL, 0); - buffer_free(buffer); - return NULL; - } - buffer->fragments[j].data = fragments[i].data; - buffer->fragments[j].length = fragments[i].length; - buffer->fragment_offsets[i] = offset; - offset += fragments[i].length; - j++; - } - buffer->nfragments = j; - buffer->first_owned_fragment = free_data ? 0 : buffer->nfragments; - buffer->fragment_offsets[buffer->nfragments] = offset; - buffer->size = offset; - } - - return buffer; -} - -static zip_int64_t -buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length) { - zip_uint64_t n, i, fragment_offset; - - length = ZIP_MIN(length, buffer->size - buffer->offset); - - if (length == 0) { - return 0; - } - if (length > ZIP_INT64_MAX) { - return -1; - } - - i = buffer->current_fragment; - fragment_offset = buffer->offset - buffer->fragment_offsets[i]; - n = 0; - while (n < length) { - zip_uint64_t left = ZIP_MIN(length - n, buffer->fragments[i].length - fragment_offset); - - memcpy(data + n, buffer->fragments[i].data + fragment_offset, left); - - if (left == buffer->fragments[i].length - fragment_offset) { - i++; - } - n += left; - fragment_offset = 0; - } - - buffer->offset += n; - buffer->current_fragment = i; - return (zip_int64_t)n; -} - - -static int -buffer_seek(buffer_t *buffer, void *data, zip_uint64_t len, zip_error_t *error) { - zip_int64_t new_offset = zip_source_seek_compute_offset(buffer->offset, buffer->size, data, len, error); - - if (new_offset < 0) { - return -1; - } - - buffer->offset = (zip_uint64_t)new_offset; - buffer->current_fragment = buffer_find_fragment(buffer, buffer->offset); - return 0; -} - - -static zip_int64_t -buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip_error_t *error) { - zip_uint64_t n, i, fragment_offset, capacity; - - if (buffer->offset + length + WRITE_FRAGMENT_SIZE - 1 < length) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return -1; - } - - /* grow buffer if needed */ - capacity = buffer_capacity(buffer); - if (buffer->offset + length > capacity) { - zip_uint64_t needed_fragments = buffer->nfragments + (length - (capacity - buffer->offset) + WRITE_FRAGMENT_SIZE - 1) / WRITE_FRAGMENT_SIZE; - - if (needed_fragments > buffer->fragments_capacity) { - zip_uint64_t new_capacity = buffer->fragments_capacity; - - if (new_capacity == 0) { - new_capacity = 16; - } - while (new_capacity < needed_fragments) { - new_capacity *= 2; - } - - if (!buffer_grow_fragments(buffer, new_capacity, error)) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return -1; - } - } - - while (buffer->nfragments < needed_fragments) { - if ((buffer->fragments[buffer->nfragments].data = malloc(WRITE_FRAGMENT_SIZE)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return -1; - } - buffer->fragments[buffer->nfragments].length = WRITE_FRAGMENT_SIZE; - buffer->nfragments++; - capacity += WRITE_FRAGMENT_SIZE; - buffer->fragment_offsets[buffer->nfragments] = capacity; - } - } - - i = buffer->current_fragment; - fragment_offset = buffer->offset - buffer->fragment_offsets[i]; - n = 0; - while (n < length) { - zip_uint64_t left = ZIP_MIN(length - n, buffer->fragments[i].length - fragment_offset); - - memcpy(buffer->fragments[i].data + fragment_offset, data + n, left); - - if (left == buffer->fragments[i].length - fragment_offset) { - i++; - } - n += left; - fragment_offset = 0; - } - - buffer->offset += n; - buffer->current_fragment = i; - if (buffer->offset > buffer->size) { - buffer->size = buffer->offset; - } - - return (zip_int64_t)n; -} diff --git a/ext/libzip/zip_source_call.c b/ext/libzip/zip_source_call.c deleted file mode 100644 index e7c295444d..0000000000 --- a/ext/libzip/zip_source_call.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - zip_source_call.c -- invoke callback command on zip_source - Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#include "zipint.h" - - -zip_int64_t -_zip_source_call(zip_source_t *src, void *data, zip_uint64_t length, zip_source_cmd_t command) { - zip_int64_t ret; - - if ((src->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(command)) == 0) { - zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0); - return -1; - } - - if (src->src == NULL) { - ret = src->cb.f(src->ud, data, length, command); - } - else { - ret = src->cb.l(src->src, src->ud, data, length, command); - } - - if (ret < 0) { - if (command != ZIP_SOURCE_ERROR && command != ZIP_SOURCE_SUPPORTS) { - int e[2]; - - if (_zip_source_call(src, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) { - zip_error_set(&src->error, ZIP_ER_INTERNAL, 0); - } - else { - zip_error_set(&src->error, e[0], e[1]); - } - } - } - - return ret; -} diff --git a/ext/libzip/zip_source_close.c b/ext/libzip/zip_source_close.c deleted file mode 100644 index ab7898ce73..0000000000 --- a/ext/libzip/zip_source_close.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - zip_source_close.c -- close zip_source (stop reading) - Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -int -zip_source_close(zip_source_t *src) { - if (!ZIP_SOURCE_IS_OPEN_READING(src)) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; - } - - src->open_count--; - if (src->open_count == 0) { - _zip_source_call(src, NULL, 0, ZIP_SOURCE_CLOSE); - - if (ZIP_SOURCE_IS_LAYERED(src)) { - if (zip_source_close(src->src) < 0) { - zip_error_set(&src->error, ZIP_ER_INTERNAL, 0); - } - } - } - - return 0; -} diff --git a/ext/libzip/zip_source_commit_write.c b/ext/libzip/zip_source_commit_write.c deleted file mode 100644 index d1254bf1f8..0000000000 --- a/ext/libzip/zip_source_commit_write.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - zip_source_commit_write.c -- commit changes to file - Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN int -zip_source_commit_write(zip_source_t *src) { - if (!ZIP_SOURCE_IS_OPEN_WRITING(src)) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (src->open_count > 1) { - zip_error_set(&src->error, ZIP_ER_INUSE, 0); - return -1; - } - else if (ZIP_SOURCE_IS_OPEN_READING(src)) { - if (zip_source_close(src) < 0) { - return -1; - } - } - - if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_COMMIT_WRITE) < 0) { - src->write_state = ZIP_SOURCE_WRITE_FAILED; - return -1; - } - - src->write_state = ZIP_SOURCE_WRITE_CLOSED; - - return 0; -} diff --git a/ext/libzip/zip_source_compress.c b/ext/libzip/zip_source_compress.c deleted file mode 100644 index e49929f563..0000000000 --- a/ext/libzip/zip_source_compress.c +++ /dev/null @@ -1,389 +0,0 @@ -/* - zip_source_compress.c -- (de)compression routines - Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include - -#include "zipint.h" - -struct context { - zip_error_t error; - - bool end_of_input; - bool end_of_stream; - bool can_store; - bool is_stored; /* only valid if end_of_stream is true */ - bool compress; - zip_int32_t method; - - zip_uint64_t size; - zip_int64_t first_read; - zip_uint8_t buffer[BUFSIZE]; - - zip_compression_algorithm_t *algorithm; - void *ud; -}; - - -struct implementation { - zip_uint16_t method; - zip_compression_algorithm_t *compress; - zip_compression_algorithm_t *decompress; -}; - -static struct implementation implementations[] = { - {ZIP_CM_DEFLATE, &zip_algorithm_deflate_compress, &zip_algorithm_deflate_decompress}, -#if defined(HAVE_LIBBZ2) - {ZIP_CM_BZIP2, &zip_algorithm_bzip2_compress, &zip_algorithm_bzip2_decompress}, -#endif -#if defined(HAVE_LIBLZMA) - /* Disabled - because 7z isn't able to unpack ZIP+LZMA ZIP+LZMA2 - archives made this way - and vice versa. - - {ZIP_CM_LZMA, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress}, - {ZIP_CM_LZMA2, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress}, - */ - {ZIP_CM_XZ, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress}, -#endif - -}; - -static size_t implementations_size = sizeof(implementations) / sizeof(implementations[0]); - -static zip_source_t *compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool compress, int compression_flags); -static zip_int64_t compress_callback(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t); -static void context_free(struct context *ctx); -static struct context *context_new(zip_int32_t method, bool compress, int compression_flags, zip_compression_algorithm_t *algorithm); -static zip_int64_t compress_read(zip_source_t *, struct context *, void *, zip_uint64_t); - -static zip_compression_algorithm_t * -get_algorithm(zip_int32_t method, bool compress) { - size_t i; - zip_uint16_t real_method = ZIP_CM_ACTUAL(method); - - for (i = 0; i < implementations_size; i++) { - if (implementations[i].method == real_method) { - if (compress) { - return implementations[i].compress; - } - else { - return implementations[i].decompress; - } - } - } - - return NULL; -} - -ZIP_EXTERN int -zip_compression_method_supported(zip_int32_t method, int compress) { - if (method == ZIP_CM_STORE) { - return 1; - } - return get_algorithm(method, compress) != NULL; -} - -zip_source_t * -zip_source_compress(zip_t *za, zip_source_t *src, zip_int32_t method, int compression_flags) { - return compression_source_new(za, src, method, true, compression_flags); -} - -zip_source_t * -zip_source_decompress(zip_t *za, zip_source_t *src, zip_int32_t method) { - return compression_source_new(za, src, method, false, 0); -} - - -static zip_source_t * -compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool compress, int compression_flags) { - struct context *ctx; - zip_source_t *s2; - zip_compression_algorithm_t *algorithm = NULL; - - if (src == NULL) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } - - if ((algorithm = get_algorithm(method, compress)) == NULL) { - zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); - return NULL; - } - - if ((ctx = context_new(method, compress, compression_flags, algorithm)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return NULL; - } - - if ((s2 = zip_source_layered(za, src, compress_callback, ctx)) == NULL) { - context_free(ctx); - return NULL; - } - - return s2; -} - - -static struct context * -context_new(zip_int32_t method, bool compress, int compression_flags, zip_compression_algorithm_t *algorithm) { - struct context *ctx; - - if ((ctx = (struct context *)malloc(sizeof(*ctx))) == NULL) { - return NULL; - } - zip_error_init(&ctx->error); - ctx->can_store = compress ? ZIP_CM_IS_DEFAULT(method) : false; - ctx->algorithm = algorithm; - ctx->method = method; - ctx->compress = compress; - ctx->end_of_input = false; - ctx->end_of_stream = false; - ctx->is_stored = false; - - if ((ctx->ud = ctx->algorithm->allocate(ZIP_CM_ACTUAL(method), compression_flags, &ctx->error)) == NULL) { - zip_error_fini(&ctx->error); - free(ctx); - return NULL; - } - - return ctx; -} - - -static void -context_free(struct context *ctx) { - if (ctx == NULL) { - return; - } - - ctx->algorithm->deallocate(ctx->ud); - zip_error_fini(&ctx->error); - - free(ctx); -} - - -static zip_int64_t -compress_read(zip_source_t *src, struct context *ctx, void *data, zip_uint64_t len) { - zip_compression_status_t ret; - bool end; - zip_int64_t n; - zip_uint64_t out_offset; - zip_uint64_t out_len; - - if (zip_error_code_zip(&ctx->error) != ZIP_ER_OK) { - return -1; - } - - if (len == 0 || ctx->end_of_stream) { - return 0; - } - - out_offset = 0; - - end = false; - while (!end && out_offset < len) { - out_len = len - out_offset; - ret = ctx->algorithm->process(ctx->ud, (zip_uint8_t *)data + out_offset, &out_len); - - if (ret != ZIP_COMPRESSION_ERROR) { - out_offset += out_len; - } - - switch (ret) { - case ZIP_COMPRESSION_END: - ctx->end_of_stream = true; - - if (!ctx->end_of_input) { - /* TODO: garbage after stream, or compression ended before all data read */ - } - - if (ctx->first_read < 0) { - /* we got end of processed stream before reading any input data */ - zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0); - end = true; - break; - } - if (ctx->can_store && (zip_uint64_t)ctx->first_read <= out_offset) { - ctx->is_stored = true; - ctx->size = (zip_uint64_t)ctx->first_read; - memcpy(data, ctx->buffer, ctx->size); - return (zip_int64_t)ctx->size; - } - end = true; - break; - - case ZIP_COMPRESSION_OK: - break; - - case ZIP_COMPRESSION_NEED_DATA: - if (ctx->end_of_input) { - /* TODO: error: stream not ended, but no more input */ - end = true; - break; - } - - if ((n = zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) { - _zip_error_set_from_source(&ctx->error, src); - end = true; - break; - } - else if (n == 0) { - ctx->end_of_input = true; - ctx->algorithm->end_of_input(ctx->ud); - if (ctx->first_read < 0) { - ctx->first_read = 0; - } - } - else { - if (ctx->first_read >= 0) { - /* we overwrote a previously filled ctx->buffer */ - ctx->can_store = false; - } - else { - ctx->first_read = n; - } - - ctx->algorithm->input(ctx->ud, ctx->buffer, (zip_uint64_t)n); - } - break; - - case ZIP_COMPRESSION_ERROR: - /* error set by algorithm */ - if (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) { - zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0); - } - end = true; - break; - } - } - - if (out_offset > 0) { - ctx->can_store = false; - ctx->size += out_offset; - return (zip_int64_t)out_offset; - } - - return (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) ? 0 : -1; -} - - -static zip_int64_t -compress_callback(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { - struct context *ctx; - - ctx = (struct context *)ud; - - switch (cmd) { - case ZIP_SOURCE_OPEN: - ctx->size = 0; - ctx->end_of_input = false; - ctx->end_of_stream = false; - ctx->is_stored = false; - ctx->first_read = -1; - - if (!ctx->algorithm->start(ctx->ud)) { - return -1; - } - - return 0; - - case ZIP_SOURCE_READ: - return compress_read(src, ctx, data, len); - - case ZIP_SOURCE_CLOSE: - if (!ctx->algorithm->end(ctx->ud)) { - return -1; - } - return 0; - - case ZIP_SOURCE_STAT: { - zip_stat_t *st; - - st = (zip_stat_t *)data; - - if (ctx->compress) { - if (ctx->end_of_stream) { - st->comp_method = ctx->is_stored ? ZIP_CM_STORE : ZIP_CM_ACTUAL(ctx->method); - st->comp_size = ctx->size; - st->valid |= ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD; - } - else { - st->valid &= ~(ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD); - } - } - else { - st->comp_method = ZIP_CM_STORE; - st->valid |= ZIP_STAT_COMP_METHOD; - if (ctx->end_of_stream) { - st->size = ctx->size; - st->valid |= ZIP_STAT_SIZE; - } - else { - st->valid &= ~ZIP_STAT_SIZE; - } - } - } - return 0; - - case ZIP_SOURCE_ERROR: - return zip_error_to_data(&ctx->error, data, len); - - case ZIP_SOURCE_FREE: - context_free(ctx); - return 0; - - case ZIP_SOURCE_GET_FILE_ATTRIBUTES: { - zip_file_attributes_t *attributes = (zip_file_attributes_t *)data; - - if (len < sizeof(*attributes)) { - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } - - attributes->valid |= ZIP_FILE_ATTRIBUTES_VERSION_NEEDED | ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS; - attributes->version_needed = ctx->algorithm->version_needed; - attributes->general_purpose_bit_mask = ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK; - attributes->general_purpose_bit_flags = (ctx->is_stored ? 0 : ctx->algorithm->general_purpose_bit_flags(ctx->ud)); - - return sizeof(*attributes); - } - - case ZIP_SOURCE_SUPPORTS: - return ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1); - - default: - zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0); - return -1; - } -} diff --git a/ext/libzip/zip_source_crc.c b/ext/libzip/zip_source_crc.c deleted file mode 100644 index 4f3f223f3a..0000000000 --- a/ext/libzip/zip_source_crc.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - zip_source_crc.c -- pass-through source that calculates CRC32 and size - Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include -#include -#include - -#include "zipint.h" - -struct crc_context { - int validate; /* whether to check CRC on EOF and return error on mismatch */ - int crc_complete; /* whether CRC was computed for complete file */ - zip_error_t error; - zip_uint64_t size; - zip_uint64_t position; /* current reading position */ - zip_uint64_t crc_position; /* how far we've computed the CRC */ - zip_uint32_t crc; -}; - -static zip_int64_t crc_read(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t); - - -zip_source_t * -zip_source_crc(zip_t *za, zip_source_t *src, int validate) { - struct crc_context *ctx; - - if (src == NULL) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } - - if ((ctx = (struct crc_context *)malloc(sizeof(*ctx))) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return NULL; - } - - zip_error_init(&ctx->error); - ctx->validate = validate; - ctx->crc_complete = 0; - ctx->crc_position = 0; - ctx->crc = (zip_uint32_t)crc32(0, NULL, 0); - ctx->size = 0; - - return zip_source_layered(za, src, crc_read, ctx); -} - - -static zip_int64_t -crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { - struct crc_context *ctx; - zip_int64_t n; - - ctx = (struct crc_context *)_ctx; - - switch (cmd) { - case ZIP_SOURCE_OPEN: - ctx->position = 0; - return 0; - - case ZIP_SOURCE_READ: - if ((n = zip_source_read(src, data, len)) < 0) { - _zip_error_set_from_source(&ctx->error, src); - return -1; - } - - if (n == 0) { - if (ctx->crc_position == ctx->position) { - ctx->crc_complete = 1; - ctx->size = ctx->position; - - if (ctx->validate) { - struct zip_stat st; - - if (zip_source_stat(src, &st) < 0) { - _zip_error_set_from_source(&ctx->error, src); - return -1; - } - - if ((st.valid & ZIP_STAT_CRC) && st.crc != ctx->crc) { - zip_error_set(&ctx->error, ZIP_ER_CRC, 0); - return -1; - } - if ((st.valid & ZIP_STAT_SIZE) && st.size != ctx->size) { - zip_error_set(&ctx->error, ZIP_ER_INCONS, 0); - return -1; - } - } - } - } - else if (!ctx->crc_complete && ctx->position <= ctx->crc_position) { - zip_uint64_t i, nn; - - for (i = ctx->crc_position - ctx->position; i < (zip_uint64_t)n; i += nn) { - nn = ZIP_MIN(UINT_MAX, (zip_uint64_t)n - i); - - ctx->crc = (zip_uint32_t)crc32(ctx->crc, (const Bytef *)data + i, (uInt)nn); - ctx->crc_position += nn; - } - } - ctx->position += (zip_uint64_t)n; - return n; - - case ZIP_SOURCE_CLOSE: - return 0; - - case ZIP_SOURCE_STAT: { - zip_stat_t *st; - - st = (zip_stat_t *)data; - - if (ctx->crc_complete) { - /* TODO: Set comp_size, comp_method, encryption_method? - After all, this only works for uncompressed data. */ - st->size = ctx->size; - st->crc = ctx->crc; - st->comp_size = ctx->size; - st->comp_method = ZIP_CM_STORE; - st->encryption_method = ZIP_EM_NONE; - st->valid |= ZIP_STAT_SIZE | ZIP_STAT_CRC | ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD | ZIP_STAT_ENCRYPTION_METHOD; - } - return 0; - } - - case ZIP_SOURCE_ERROR: - return zip_error_to_data(&ctx->error, data, len); - - case ZIP_SOURCE_FREE: - free(ctx); - return 0; - - case ZIP_SOURCE_SUPPORTS: { - zip_int64_t mask = zip_source_supports(src); - - if (mask < 0) { - _zip_error_set_from_source(&ctx->error, src); - return -1; - } - - return mask & ~zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1); - } - - case ZIP_SOURCE_SEEK: { - zip_int64_t new_position; - zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error); - - if (args == NULL) { - return -1; - } - if (zip_source_seek(src, args->offset, args->whence) < 0 || (new_position = zip_source_tell(src)) < 0) { - _zip_error_set_from_source(&ctx->error, src); - return -1; - } - - ctx->position = (zip_uint64_t)new_position; - - return 0; - } - - case ZIP_SOURCE_TELL: - return (zip_int64_t)ctx->position; - - default: - zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); - return -1; - } -} diff --git a/ext/libzip/zip_source_error.c b/ext/libzip/zip_source_error.c deleted file mode 100644 index 2257f71559..0000000000 --- a/ext/libzip/zip_source_error.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - zip_source_error.c -- get last error from zip_source - Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -zip_error_t * -zip_source_error(zip_source_t *src) { - return &src->error; -} - -bool -_zip_source_had_error(zip_source_t *src) { - return zip_source_error(src)->zip_err != ZIP_ER_OK; -} diff --git a/ext/libzip/zip_source_file.h b/ext/libzip/zip_source_file.h deleted file mode 100644 index 43a464533c..0000000000 --- a/ext/libzip/zip_source_file.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - zip_source_file.h -- header for common file operations - Copyright (C) 2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -struct zip_source_file_stat { - zip_uint64_t size; /* must be valid for regular files */ - time_t mtime; /* must always be valid, is initialized to current time */ - bool exists; /* must always be vaild */ - bool regular_file; /* must always be valid */ -}; - -typedef struct zip_source_file_context zip_source_file_context_t; -typedef struct zip_source_file_operations zip_source_file_operations_t; -typedef struct zip_source_file_stat zip_source_file_stat_t; - -struct zip_source_file_context { - zip_error_t error; /* last error information */ - zip_int64_t supports; - - /* reading */ - char *fname; /* name of file to read from */ - void *f; /* file to read from */ - zip_stat_t st; /* stat information passed in */ - zip_file_attributes_t attributes; /* additional file attributes */ - zip_error_t stat_error; /* error returned for stat */ - zip_uint64_t start; /* start offset of data to read */ - zip_uint64_t len; /* length of the file, 0 for up to EOF */ - zip_uint64_t offset; /* current offset relative to start (0 is beginning of part we read) */ - - /* writing */ - char *tmpname; - void *fout; - - zip_source_file_operations_t *ops; - void *ops_userdata; -}; - - -/* The following methods must be implemented to support each feature: - - close, read, seek, and stat must always be implemented. - - To support specifying the file by name, open, and strdup must be implemented. - - For write support, the file must be specified by name and close, commit_write, create_temp_output, remove, rollback_write, and tell must be implemented. - - create_temp_output_cloning is always optional. */ - -struct zip_source_file_operations { - void (*close)(zip_source_file_context_t *ctx); - zip_int64_t (*commit_write)(zip_source_file_context_t *ctx); - zip_int64_t (*create_temp_output)(zip_source_file_context_t *ctx); - zip_int64_t (*create_temp_output_cloning)(zip_source_file_context_t *ctx, zip_uint64_t len); - bool (*open)(zip_source_file_context_t *ctx); - zip_int64_t (*read)(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len); - zip_int64_t (*remove)(zip_source_file_context_t *ctx); - void (*rollback_write)(zip_source_file_context_t *ctx); - bool (*seek)(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence); - bool (*stat)(zip_source_file_context_t *ctx, zip_source_file_stat_t *st); - char *(*string_duplicate)(zip_source_file_context_t *ctx, const char *); - zip_int64_t (*tell)(zip_source_file_context_t *ctx, void *f); - zip_int64_t (*write)(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len); -}; - -zip_source_t *zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_source_file_operations_t *ops, void *ops_userdata, zip_error_t *error); diff --git a/ext/libzip/zip_source_file_common.c b/ext/libzip/zip_source_file_common.c deleted file mode 100644 index 74e21009bd..0000000000 --- a/ext/libzip/zip_source_file_common.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - zip_source_file_common.c -- create data source from file - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include -#include - -#include "zipint.h" - -#include "zip_source_file.h" - -static zip_int64_t read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd); - -static void -zip_source_file_stat_init(zip_source_file_stat_t *st) { - st->size = 0; - st->mtime = time(NULL); - st->exists = false; - st->regular_file = false; -} - -zip_source_t * -zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_source_file_operations_t *ops, void *ops_userdata, zip_error_t *error) { - zip_source_file_context_t *ctx; - zip_source_t *zs; - zip_source_file_stat_t sb; - - if (ops == NULL) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - if (ops->close == NULL || ops->read == NULL || ops->seek == NULL || ops->stat == NULL) { - zip_error_set(error, ZIP_ER_INTERNAL, 0); - return NULL; - } - - if (ops->write != NULL && (ops->commit_write == NULL || ops->create_temp_output == NULL || ops->remove == NULL || ops->rollback_write == NULL || ops->tell == NULL)) { - zip_error_set(error, ZIP_ER_INTERNAL, 0); - return NULL; - } - - if (fname != NULL) { - if (ops->open == NULL || ops->string_duplicate == NULL) { - zip_error_set(error, ZIP_ER_INTERNAL, 0); - return NULL; - } - } - else if (file == NULL) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - if (len < 0) { - len = 0; - } - - if (start > ZIP_INT64_MAX || start + (zip_uint64_t)len < start) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - if ((ctx = (zip_source_file_context_t *)malloc(sizeof(zip_source_file_context_t))) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; - } - - ctx->ops = ops; - ctx->ops_userdata = ops_userdata; - ctx->fname = NULL; - if (fname) { - if ((ctx->fname = ops->string_duplicate(ctx, fname)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - free(ctx); - return NULL; - } - } - ctx->f = file; - ctx->start = start; - ctx->len = (zip_uint64_t)len; - if (st) { - memcpy(&ctx->st, st, sizeof(ctx->st)); - ctx->st.name = NULL; - ctx->st.valid &= ~ZIP_STAT_NAME; - } - else { - zip_stat_init(&ctx->st); - } - - if (ctx->len > 0) { - ctx->st.size = ctx->len; - ctx->st.valid |= ZIP_STAT_SIZE; - } - - zip_error_init(&ctx->stat_error); - - ctx->tmpname = NULL; - ctx->fout = NULL; - - zip_error_init(&ctx->error); - zip_file_attributes_init(&ctx->attributes); - - ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1); - - zip_source_file_stat_init(&sb); - if (!ops->stat(ctx, &sb)) { - _zip_error_copy(error, &ctx->error); - free(ctx->fname); - free(ctx); - return NULL; - } - - if (!sb.exists) { - if (ctx->fname && ctx->start == 0 && ctx->len == 0 && ops->write != NULL) { - ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE; - /* zip_open_from_source checks for this to detect non-existing files */ - zip_error_set(&ctx->stat_error, ZIP_ER_READ, ENOENT); - } - else { - zip_error_set(&ctx->stat_error, ZIP_ER_READ, ENOENT); - free(ctx->fname); - free(ctx); - return NULL; - } - } - else { - if ((ctx->st.valid & ZIP_STAT_MTIME) == 0) { - ctx->st.mtime = sb.mtime; - ctx->st.valid |= ZIP_STAT_MTIME; - } - if (sb.regular_file) { - ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE; - - if (ctx->start + ctx->len > sb.size) { - zip_error_set(error, ZIP_ER_INVAL, 0); - free(ctx->fname); - free(ctx); - return NULL; - } - - if (ctx->len == 0) { - ctx->len = sb.size - ctx->start; - ctx->st.size = ctx->len; - ctx->st.valid |= ZIP_STAT_SIZE; - - /* when using a partial file, don't allow writing */ - if (ctx->fname && start == 0 && ops->write != NULL) { - ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE; - } - } - } - - ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_GET_FILE_ATTRIBUTES); - } - - ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ACCEPT_EMPTY); - if (ops->create_temp_output_cloning != NULL) { - if (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE)) { - ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING); - } - } - - if ((zs = zip_source_function_create(read_file, ctx, error)) == NULL) { - free(ctx->fname); - free(ctx); - return NULL; - } - - return zs; -} - - -static zip_int64_t -read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { - zip_source_file_context_t *ctx; - char *buf; - - ctx = (zip_source_file_context_t *)state; - buf = (char *)data; - - switch (cmd) { - case ZIP_SOURCE_ACCEPT_EMPTY: - return 0; - - case ZIP_SOURCE_BEGIN_WRITE: - /* write support should not be set if fname is NULL */ - if (ctx->fname == NULL) { - zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0); - return -1; - } - return ctx->ops->create_temp_output(ctx); - - case ZIP_SOURCE_BEGIN_WRITE_CLONING: - /* write support should not be set if fname is NULL */ - if (ctx->fname == NULL) { - zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0); - return -1; - } - return ctx->ops->create_temp_output_cloning(ctx, len); - - case ZIP_SOURCE_CLOSE: - if (ctx->fname) { - ctx->ops->close(ctx); - ctx->f = NULL; - } - return 0; - - case ZIP_SOURCE_COMMIT_WRITE: { - zip_int64_t ret = ctx->ops->commit_write(ctx); - ctx->fout = NULL; - if (ret == 0) { - free(ctx->tmpname); - ctx->tmpname = NULL; - } - return ret; - } - - case ZIP_SOURCE_ERROR: - return zip_error_to_data(&ctx->error, data, len); - - case ZIP_SOURCE_FREE: - free(ctx->fname); - free(ctx->tmpname); - if (ctx->f) { - ctx->ops->close(ctx); - } - free(ctx); - return 0; - - case ZIP_SOURCE_GET_FILE_ATTRIBUTES: - if (len < sizeof(ctx->attributes)) { - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } - memcpy(data, &ctx->attributes, sizeof(ctx->attributes)); - return sizeof(ctx->attributes); - - case ZIP_SOURCE_OPEN: - if (ctx->fname) { - if (ctx->ops->open(ctx) == false) { - return -1; - } - } - - if (ctx->start > 0) { // TODO: rewind on re-open - if (ctx->ops->seek(ctx, ctx->f, (zip_int64_t)ctx->start, SEEK_SET) == false) { - /* TODO: skip by reading */ - return -1; - } - } - ctx->offset = 0; - return 0; - - case ZIP_SOURCE_READ: { - zip_int64_t i; - zip_uint64_t n; - - if (ctx->len > 0) { - n = ZIP_MIN(ctx->len - ctx->offset, len); - } - else { - n = len; - } - - if ((i = ctx->ops->read(ctx, buf, n)) < 0) { - zip_error_set(&ctx->error, ZIP_ER_READ, errno); - return -1; - } - ctx->offset += (zip_uint64_t)i; - - return i; - } - - case ZIP_SOURCE_REMOVE: - return ctx->ops->remove(ctx); - - case ZIP_SOURCE_ROLLBACK_WRITE: - ctx->ops->rollback_write(ctx); - ctx->fout = NULL; - free(ctx->tmpname); - ctx->tmpname = NULL; - return 0; - - case ZIP_SOURCE_SEEK: { - zip_int64_t new_offset = zip_source_seek_compute_offset(ctx->offset, ctx->len, data, len, &ctx->error); - - if (new_offset < 0) { - return -1; - } - - /* The actual offset inside the file must be representable as zip_int64_t. */ - if (new_offset > ZIP_INT64_MAX - (zip_int64_t)ctx->start) { - zip_error_set(&ctx->error, ZIP_ER_SEEK, EOVERFLOW); - return -1; - } - - ctx->offset = (zip_uint64_t)new_offset; - - if (ctx->ops->seek(ctx, ctx->f, (zip_int64_t)(ctx->offset + ctx->start), SEEK_SET) == false) { - return -1; - } - return 0; - } - - case ZIP_SOURCE_SEEK_WRITE: { - zip_source_args_seek_t *args; - - args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error); - if (args == NULL) { - return -1; - } - - if (ctx->ops->seek(ctx, ctx->fout, args->offset, args->whence) == false) { - return -1; - } - return 0; - } - - case ZIP_SOURCE_STAT: { - if (len < sizeof(ctx->st)) - return -1; - - if (zip_error_code_zip(&ctx->stat_error) != 0) { - zip_error_set(&ctx->error, zip_error_code_zip(&ctx->stat_error), zip_error_code_system(&ctx->stat_error)); - return -1; - } - - memcpy(data, &ctx->st, sizeof(ctx->st)); - return sizeof(ctx->st); - } - - case ZIP_SOURCE_SUPPORTS: - return ctx->supports; - - case ZIP_SOURCE_TELL: - return (zip_int64_t)ctx->offset; - - case ZIP_SOURCE_TELL_WRITE: - return ctx->ops->tell(ctx, ctx->fout); - - case ZIP_SOURCE_WRITE: - return ctx->ops->write(ctx, data, len); - - default: - zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); - return -1; - } -} diff --git a/ext/libzip/zip_source_file_stdio.c b/ext/libzip/zip_source_file_stdio.c deleted file mode 100644 index 4a22f78cb4..0000000000 --- a/ext/libzip/zip_source_file_stdio.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - zip_source_file_stdio.c -- read-only stdio file source implementation - Copyright (C) 2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "zipint.h" - -#include "zip_source_file.h" -#include "zip_source_file_stdio.h" - -#include -#include -#include -#include - -#ifdef _WIN32 -#ifndef S_IWUSR -#define S_IWUSR _S_IWRITE -#endif -#endif - -/* clang-format off */ -static zip_source_file_operations_t ops_stdio_read = { - _zip_stdio_op_close, - NULL, - NULL, - NULL, - NULL, - _zip_stdio_op_read, - NULL, - NULL, - _zip_stdio_op_seek, - _zip_stdio_op_stat, - NULL, - _zip_stdio_op_tell, - NULL -}; -/* clang-format on */ - - -ZIP_EXTERN zip_source_t * -zip_source_filep(zip_t *za, FILE *file, zip_uint64_t start, zip_int64_t len) { - if (za == NULL) { - return NULL; - } - - return zip_source_filep_create(file, start, len, &za->error); -} - - -ZIP_EXTERN zip_source_t * -zip_source_filep_create(FILE *file, zip_uint64_t start, zip_int64_t length, zip_error_t *error) { - if (file == NULL || length < -1) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - return zip_source_file_common_new(NULL, file, start, length, NULL, &ops_stdio_read, NULL, error); -} - - -void -_zip_stdio_op_close(zip_source_file_context_t *ctx) { - fclose((FILE *)ctx->f); -} - - -zip_int64_t -_zip_stdio_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len) { - size_t i; - if (len > SIZE_MAX) { - len = SIZE_MAX; - } - - if ((i = fread(buf, 1, (size_t)len, ctx->f)) == 0) { - if (ferror((FILE *)ctx->f)) { - zip_error_set(&ctx->error, ZIP_ER_READ, errno); - return -1; - } - } - - return (zip_int64_t)i; -} - - -bool -_zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence) { -#if ZIP_FSEEK_MAX > ZIP_INT64_MAX - if (offset > ZIP_FSEEK_MAX || offset < ZIP_FSEEK_MIN) { - zip_error_set(&ctx->error, ZIP_ER_SEEK, EOVERFLOW); - return false; - } -#endif - - if (fseeko((FILE *)f, (off_t)offset, whence) < 0) { - zip_error_set(&ctx->error, ZIP_ER_SEEK, errno); - return false; - } - return true; -} - - -bool -_zip_stdio_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) { - struct stat sb; - - int ret; - - if (ctx->fname) { - ret = stat(ctx->fname, &sb); - } - else { - ret = fstat(fileno((FILE *)ctx->f), &sb); - } - - if (ret < 0) { - if (errno == ENOENT) { - st->exists = false; - return true; - } - zip_error_set(&ctx->error, ZIP_ER_READ, errno); - return false; - } - - st->size = (zip_uint64_t)sb.st_size; - st->mtime = sb.st_mtime; - - st->regular_file = S_ISREG(sb.st_mode); - st->exists = true; - - /* We're using UNIX file API, even on Windows; thus, we supply external file attributes with Unix values. */ - /* TODO: This could be improved on Windows by providing Windows-specific file attributes */ - ctx->attributes.valid = ZIP_FILE_ATTRIBUTES_HOST_SYSTEM | ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES; - ctx->attributes.host_system = ZIP_OPSYS_UNIX; - ctx->attributes.external_file_attributes = (((zip_uint32_t)sb.st_mode) << 16) | ((sb.st_mode & S_IWUSR) ? 0 : 1); - - return true; -} - - -zip_int64_t -_zip_stdio_op_tell(zip_source_file_context_t *ctx, void *f) { - off_t offset = ftello((FILE *)f); - - if (offset < 0) { - zip_error_set(&ctx->error, ZIP_ER_SEEK, errno); - } - - return offset; -} - - -/* - * fopen replacement that sets the close-on-exec flag - * some implementations support an fopen 'e' flag for that, - * but e.g. macOS doesn't. - */ -FILE * -_zip_fopen_close_on_exec(const char *name, bool writeable) { - int fd; - int flags; - FILE *fp; - - flags = O_CLOEXEC; - if (writeable) { - flags |= O_RDWR; - } - else { - flags |= O_RDONLY; - } - - /* mode argument needed on Windows */ - if ((fd = open(name, flags, 0666)) < 0) { - return NULL; - } - if ((fp = fdopen(fd, writeable ? "r+b" : "rb")) == NULL) { - return NULL; - } - return fp; -} diff --git a/ext/libzip/zip_source_file_stdio.h b/ext/libzip/zip_source_file_stdio.h deleted file mode 100644 index 1bf698ce28..0000000000 --- a/ext/libzip/zip_source_file_stdio.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _HAD_ZIP_SOURCE_FILE_STDIO_H -#define _HAD_ZIP_SOURCE_FILE_STDIO_H - -/* - zip_source_file_stdio.h -- common header for stdio file implementation - Copyright (C) 2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include - -void _zip_stdio_op_close(zip_source_file_context_t *ctx); -zip_int64_t _zip_stdio_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len); -bool _zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence); -bool _zip_stdio_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st); -zip_int64_t _zip_stdio_op_tell(zip_source_file_context_t *ctx, void *f); - -FILE *_zip_fopen_close_on_exec(const char *name, bool writeable); - -#endif /* _HAD_ZIP_SOURCE_FILE_STDIO_H */ diff --git a/ext/libzip/zip_source_file_stdio_named.c b/ext/libzip/zip_source_file_stdio_named.c deleted file mode 100644 index dae8177c49..0000000000 --- a/ext/libzip/zip_source_file_stdio_named.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - zip_source_file_stdio_named.c -- source for stdio file opened by name - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "zipint.h" - -#include "zip_source_file.h" -#include "zip_source_file_stdio.h" - -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_CLONEFILE -#include -#include -#define CAN_CLONE -#endif -#ifdef HAVE_FICLONERANGE -#include -#include -#define CAN_CLONE -#endif - -static zip_int64_t _zip_stdio_op_commit_write(zip_source_file_context_t *ctx); -static zip_int64_t _zip_stdio_op_create_temp_output(zip_source_file_context_t *ctx); -#ifdef CAN_CLONE -static zip_int64_t _zip_stdio_op_create_temp_output_cloning(zip_source_file_context_t *ctx, zip_uint64_t offset); -#endif -static bool _zip_stdio_op_open(zip_source_file_context_t *ctx); -static zip_int64_t _zip_stdio_op_remove(zip_source_file_context_t *ctx); -static void _zip_stdio_op_rollback_write(zip_source_file_context_t *ctx); -static char *_zip_stdio_op_strdup(zip_source_file_context_t *ctx, const char *string); -static zip_int64_t _zip_stdio_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len); - -/* clang-format off */ -static zip_source_file_operations_t ops_stdio_named = { - _zip_stdio_op_close, - _zip_stdio_op_commit_write, - _zip_stdio_op_create_temp_output, -#ifdef CAN_CLONE - _zip_stdio_op_create_temp_output_cloning, -#else - NULL, -#endif - _zip_stdio_op_open, - _zip_stdio_op_read, - _zip_stdio_op_remove, - _zip_stdio_op_rollback_write, - _zip_stdio_op_seek, - _zip_stdio_op_stat, - _zip_stdio_op_strdup, - _zip_stdio_op_tell, - _zip_stdio_op_write -}; -/* clang-format on */ - -ZIP_EXTERN zip_source_t * -zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len) { - if (za == NULL) - return NULL; - - return zip_source_file_create(fname, start, len, &za->error); -} - - -ZIP_EXTERN zip_source_t * -zip_source_file_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) { - if (fname == NULL || length < -1) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - return zip_source_file_common_new(fname, NULL, start, length, NULL, &ops_stdio_named, NULL, error); -} - - -static zip_int64_t -_zip_stdio_op_commit_write(zip_source_file_context_t *ctx) { - if (fclose(ctx->fout) < 0) { - zip_error_set(&ctx->error, ZIP_ER_WRITE, errno); - return -1; - } - if (rename(ctx->tmpname, ctx->fname) < 0) { - zip_error_set(&ctx->error, ZIP_ER_RENAME, errno); - return -1; - } - - return 0; -} - - -static zip_int64_t -_zip_stdio_op_create_temp_output(zip_source_file_context_t *ctx) { - char *temp; - int tfd; - int mode; - FILE *tfp; - struct stat st; - - if ((temp = (char *)malloc(strlen(ctx->fname) + 8)) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); - return -1; - } - - if (stat(ctx->fname, &st) == 0) { - mode = st.st_mode; - } - else { - mode = -1; - } - - sprintf(temp, "%s.XXXXXX", ctx->fname); - - if ((tfd = _zip_mkstempm(temp, mode)) == -1) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - free(temp); - return -1; - } - - if ((tfp = fdopen(tfd, "r+b")) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - close(tfd); - (void)remove(temp); - free(temp); - return -1; - } - - ctx->fout = tfp; - ctx->tmpname = temp; - - return 0; -} - -#ifdef CAN_CLONE -static zip_int64_t -_zip_stdio_op_create_temp_output_cloning(zip_source_file_context_t *ctx, zip_uint64_t offset) { - char *temp; - FILE *tfp; - - if (offset > ZIP_OFF_MAX) { - zip_error_set(&ctx->error, ZIP_ER_SEEK, E2BIG); - return -1; - } - - if ((temp = (char *)malloc(strlen(ctx->fname) + 8)) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); - return -1; - } - sprintf(temp, "%s.XXXXXX", ctx->fname); - -#ifdef HAVE_CLONEFILE -#ifndef __clang_analyzer__ - /* we can't use mkstemp, since clonefile insists on creating the file */ - if (mktemp(temp) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - free(temp); - return -1; - } -#endif - - if (clonefile(ctx->fname, temp, 0) < 0) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - free(temp); - return -1; - } - if ((tfp = _zip_fopen_close_on_exec(temp, true)) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - (void)remove(temp); - free(temp); - return -1; - } -#else - { - int fd; - struct file_clone_range range; - struct stat st; - - if (fstat(fileno(ctx->f), &st) < 0) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - free(temp); - return -1; - } - - if ((fd = mkstemp(temp)) < 0) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - free(temp); - return -1; - } - - range.src_fd = fileno(ctx->f); - range.src_offset = 0; - range.src_length = ((offset + st.st_blksize - 1) / st.st_blksize) * st.st_blksize; - if (range.src_length > st.st_size) { - range.src_length = 0; - } - range.dest_offset = 0; - if (ioctl(fd, FICLONERANGE, &range) < 0) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - (void)close(fd); - (void)remove(temp); - free(temp); - return -1; - } - - if ((tfp = fdopen(fd, "r+b")) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - (void)close(fd); - (void)remove(temp); - free(temp); - return -1; - } - } -#endif - - if (ftruncate(fileno(tfp), (off_t)offset) < 0) { - (void)fclose(tfp); - (void)remove(temp); - free(temp); - return -1; - } - if (fseeko(tfp, (off_t)offset, SEEK_SET) < 0) { - (void)fclose(tfp); - (void)remove(temp); - free(temp); - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - } - - ctx->fout = tfp; - ctx->tmpname = temp; - - return 0; -} -#endif - -static bool -_zip_stdio_op_open(zip_source_file_context_t *ctx) { - if ((ctx->f = _zip_fopen_close_on_exec(ctx->fname, false)) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_OPEN, errno); - return false; - } - return true; -} - - -static zip_int64_t -_zip_stdio_op_remove(zip_source_file_context_t *ctx) { - if (remove(ctx->fname) < 0) { - zip_error_set(&ctx->error, ZIP_ER_REMOVE, errno); - return -1; - } - return 0; -} - - -static void -_zip_stdio_op_rollback_write(zip_source_file_context_t *ctx) { - if (ctx->fout) { - fclose(ctx->fout); - } - (void)remove(ctx->tmpname); -} - -static char * -_zip_stdio_op_strdup(zip_source_file_context_t *ctx, const char *string) { - return strdup(string); -} - - -static zip_int64_t -_zip_stdio_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len) { - size_t ret; - - clearerr((FILE *)ctx->fout); - ret = fwrite(data, 1, len, (FILE *)ctx->fout); - if (ret != len || ferror((FILE *)ctx->fout)) { - zip_error_set(&ctx->error, ZIP_ER_WRITE, errno); - return -1; - } - - return (zip_int64_t)ret; -} diff --git a/ext/libzip/zip_source_file_win32.c b/ext/libzip/zip_source_file_win32.c deleted file mode 100644 index 2fe838f1fe..0000000000 --- a/ext/libzip/zip_source_file_win32.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - zip_source_file_win32.c -- read-only Windows file source implementation - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "zip_source_file_win32.h" - -static bool _zip_win32_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st); - -static bool _zip_stat_win32(zip_source_file_context_t *ctx, zip_source_file_stat_t *st, HANDLE h); - -static zip_source_file_operations_t ops_win32_read = { - _zip_win32_op_close, - NULL, - NULL, - NULL, - NULL, - _zip_win32_op_read, - NULL, - NULL, - _zip_win32_op_seek, - _zip_win32_op_stat, - NULL, - _zip_win32_op_tell, - NULL -}; - - -ZIP_EXTERN zip_source_t * -zip_source_win32handle(zip_t *za, HANDLE h, zip_uint64_t start, zip_int64_t len) { - if (za == NULL) { - return NULL; - } - - return zip_source_win32handle_create(h, start, len, &za->error); -} - - -ZIP_EXTERN zip_source_t * -zip_source_win32handle_create(HANDLE h, zip_uint64_t start, zip_int64_t length, zip_error_t *error) { - if (h == INVALID_HANDLE_VALUE || length < -1) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - return zip_source_file_common_new(NULL, h, start, length, NULL, &ops_win32_read, NULL, error); -} - - -void -_zip_win32_op_close(zip_source_file_context_t *ctx) { - CloseHandle((HANDLE)ctx->f); -} - - -zip_int64_t -_zip_win32_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len) { - DWORD i; - - /* TODO: cap len to "DWORD_MAX" */ - if (!ReadFile((HANDLE)ctx->f, buf, (DWORD)len, &i, NULL)) { - zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - - return (zip_int64_t)i; -} - - -bool -_zip_win32_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence) { - LARGE_INTEGER li; - DWORD method; - - switch (whence) { - case SEEK_SET: - method = FILE_BEGIN; - break; - case SEEK_END: - method = FILE_END; - break; - case SEEK_CUR: - method = FILE_CURRENT; - break; - default: - zip_error_set(&ctx->error, ZIP_ER_SEEK, EINVAL); - return -1; - } - - li.QuadPart = (LONGLONG)offset; - if (!SetFilePointerEx((HANDLE)f, li, NULL, method)) { - zip_error_set(&ctx->error, ZIP_ER_SEEK, _zip_win32_error_to_errno(GetLastError())); - return false; - } - - return true; -} - - -static bool -_zip_win32_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) { - return _zip_stat_win32(ctx, st, (HANDLE)ctx->f); -} - - -zip_int64_t -_zip_win32_op_tell(zip_source_file_context_t *ctx, void *f) { - LARGE_INTEGER zero; - LARGE_INTEGER new_offset; - - zero.QuadPart = 0; - if (!SetFilePointerEx((HANDLE)f, zero, &new_offset, FILE_CURRENT)) { - zip_error_set(&ctx->error, ZIP_ER_SEEK, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - - return (zip_int64_t)new_offset.QuadPart; -} - - -int -_zip_win32_error_to_errno(DWORD win32err) { - /* Note: This list isn't exhaustive, but should cover common cases. */ - switch (win32err) { - case ERROR_INVALID_PARAMETER: - return EINVAL; - case ERROR_FILE_NOT_FOUND: - return ENOENT; - case ERROR_INVALID_HANDLE: - return EBADF; - case ERROR_ACCESS_DENIED: - return EACCES; - case ERROR_FILE_EXISTS: - return EEXIST; - case ERROR_TOO_MANY_OPEN_FILES: - return EMFILE; - case ERROR_DISK_FULL: - return ENOSPC; - default: - return 10000 + win32err; - } -} - - -static bool -_zip_stat_win32(zip_source_file_context_t *ctx, zip_source_file_stat_t *st, HANDLE h) { - FILETIME mtimeft; - time_t mtime; - LARGE_INTEGER size; - - if (!GetFileTime(h, NULL, NULL, &mtimeft)) { - zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError())); - return false; - } - if (_zip_filetime_to_time_t(mtimeft, &mtime) < 0) { - zip_error_set(&ctx->error, ZIP_ER_READ, ERANGE); - return false; - } - - st->exists = true; - st->mtime = mtime; - - if (GetFileType(h) == FILE_TYPE_DISK) { - st->regular_file = 1; - - if (!GetFileSizeEx(h, &size)) { - zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError())); - return false; - } - - st->size = (zip_uint64_t)size.QuadPart; - } - - /* TODO: fill in ctx->attributes */ - - return true; -} - - -bool -_zip_filetime_to_time_t(FILETIME ft, time_t *t) { - /* - Inspired by http://stackoverflow.com/questions/6161776/convert-windows-filetime-to-second-in-unix-linux - */ - const zip_int64_t WINDOWS_TICK = 10000000LL; - const zip_int64_t SEC_TO_UNIX_EPOCH = 11644473600LL; - ULARGE_INTEGER li; - zip_int64_t secs; - time_t temp; - - li.LowPart = ft.dwLowDateTime; - li.HighPart = ft.dwHighDateTime; - secs = (li.QuadPart / WINDOWS_TICK - SEC_TO_UNIX_EPOCH); - - temp = (time_t)secs; - if (secs != (zip_int64_t)temp) { - return false; - } - - *t = temp; - return true; -} diff --git a/ext/libzip/zip_source_file_win32.h b/ext/libzip/zip_source_file_win32.h deleted file mode 100644 index 7da2379691..0000000000 --- a/ext/libzip/zip_source_file_win32.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef _HAD_ZIP_SOURCE_FILE_WIN32_H -#define _HAD_ZIP_SOURCE_FILE_WIN32_H - -/* - zip_source_file_win32.h -- common header for Windows file implementation - Copyright (C) 2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* 0x0501 => Windows XP; needs to be at least this value because of GetFileSizeEx */ -#if !defined(MS_UWP) && !defined(_WIN32_WINNT) -#define _WIN32_WINNT 0x0501 -#endif - -#include - -#include - -#include "zipint.h" - -#include "zip_source_file.h" - -/* The A/W entry points are stored behind const void * name types and need - * an explicit cast; GCC 14 rejects the implicit conversion. */ -typedef HANDLE (__stdcall *zip_win32_create_file_t)(const void *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file); -typedef BOOL (__stdcall *zip_win32_delete_file_t)(const void *name); -typedef DWORD (__stdcall *zip_win32_get_file_attributes_t)(const void *name); -typedef BOOL (__stdcall *zip_win32_get_file_attributes_ex_t)(const void *name, GET_FILEEX_INFO_LEVELS info_level, void *information); -typedef BOOL (__stdcall *zip_win32_move_file_t)(const void *from, const void *to, DWORD flags); -typedef BOOL (__stdcall *zip_win32_set_file_attributes_t)(const void *name, DWORD attributes); - -struct zip_win32_file_operations { - char *(*allocate_tempname)(const char *name, size_t extra_chars, size_t *lengthp); - zip_win32_create_file_t create_file; - zip_win32_delete_file_t delete_file; - zip_win32_get_file_attributes_t get_file_attributes; - zip_win32_get_file_attributes_ex_t get_file_attributes_ex; - void (*make_tempname)(char *buf, size_t len, const char *name, zip_uint32_t i); - zip_win32_move_file_t move_file; - zip_win32_set_file_attributes_t set_file_attributes; - char *(*string_duplicate)(const char *string); -}; - -typedef struct zip_win32_file_operations zip_win32_file_operations_t; - -extern zip_source_file_operations_t _zip_source_file_win32_named_ops; - -void _zip_win32_op_close(zip_source_file_context_t *ctx); -zip_int64_t _zip_win32_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len); -bool _zip_win32_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence); -zip_int64_t _zip_win32_op_tell(zip_source_file_context_t *ctx, void *f); - -bool _zip_filetime_to_time_t(FILETIME ft, time_t *t); -int _zip_win32_error_to_errno(DWORD win32err); - -#endif /* _HAD_ZIP_SOURCE_FILE_WIN32_H */ diff --git a/ext/libzip/zip_source_file_win32_ansi.c b/ext/libzip/zip_source_file_win32_ansi.c deleted file mode 100644 index 5c226d312d..0000000000 --- a/ext/libzip/zip_source_file_win32_ansi.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - zip_source_file_win32_ansi.c -- source for Windows file opened by ANSI name - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "zip_source_file_win32.h" - -static char *ansi_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp); -static void ansi_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i); - -zip_win32_file_operations_t ops_ansi = { - ansi_allocate_tempname, - (zip_win32_create_file_t)CreateFileA, - (zip_win32_delete_file_t)DeleteFileA, - (zip_win32_get_file_attributes_t)GetFileAttributesA, - (zip_win32_get_file_attributes_ex_t)GetFileAttributesExA, - ansi_make_tempname, - (zip_win32_move_file_t)MoveFileExA, - (zip_win32_set_file_attributes_t)SetFileAttributesA, - strdup -}; - -ZIP_EXTERN zip_source_t * -zip_source_win32a(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len) { - if (za == NULL) - return NULL; - - return zip_source_win32a_create(fname, start, len, &za->error); -} - - -ZIP_EXTERN zip_source_t * -zip_source_win32a_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) { - if (fname == NULL || length < -1) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - return zip_source_file_common_new(fname, NULL, start, length, NULL, &_zip_source_file_win32_named_ops, &ops_ansi, error); -} - - -static char * -ansi_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp) { - *lengthp = strlen(name) + extra_chars; - return (char *)malloc(*lengthp); -} - - -static void -ansi_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i) { - snprintf(buf, len, "%s.%08x", name, i); -} diff --git a/ext/libzip/zip_source_file_win32_named.c b/ext/libzip/zip_source_file_win32_named.c deleted file mode 100644 index 9591b26c0a..0000000000 --- a/ext/libzip/zip_source_file_win32_named.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - zip_source_file_win32_named.c -- source for Windows file opened by name - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "zip_source_file_win32.h" - -static zip_int64_t _zip_win32_named_op_commit_write(zip_source_file_context_t *ctx); -static zip_int64_t _zip_win32_named_op_create_temp_output(zip_source_file_context_t *ctx); -static bool _zip_win32_named_op_open(zip_source_file_context_t *ctx); -static zip_int64_t _zip_win32_named_op_remove(zip_source_file_context_t *ctx); -static void _zip_win32_named_op_rollback_write(zip_source_file_context_t *ctx); -static bool _zip_win32_named_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st); -static char *_zip_win32_named_op_string_duplicate(zip_source_file_context_t *ctx, const char *string); -static zip_int64_t _zip_win32_named_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len); - -static HANDLE win32_named_open(zip_source_file_context_t *ctx, const char *name, bool temporary, PSECURITY_ATTRIBUTES security_attributes); - -/* clang-format off */ -zip_source_file_operations_t _zip_source_file_win32_named_ops = { - _zip_win32_op_close, - _zip_win32_named_op_commit_write, - _zip_win32_named_op_create_temp_output, - NULL, - _zip_win32_named_op_open, - _zip_win32_op_read, - _zip_win32_named_op_remove, - _zip_win32_named_op_rollback_write, - _zip_win32_op_seek, - _zip_win32_named_op_stat, - _zip_win32_named_op_string_duplicate, - _zip_win32_op_tell, - _zip_win32_named_op_write -}; -/* clang-format on */ - -static zip_int64_t -_zip_win32_named_op_commit_write(zip_source_file_context_t *ctx) { - zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata; - - if (!CloseHandle((HANDLE)ctx->fout)) { - zip_error_set(&ctx->error, ZIP_ER_WRITE, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - - DWORD attributes = file_ops->get_file_attributes(ctx->tmpname); - if (attributes == INVALID_FILE_ATTRIBUTES) { - zip_error_set(&ctx->error, ZIP_ER_RENAME, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - - if (attributes & FILE_ATTRIBUTE_TEMPORARY) { - if (!file_ops->set_file_attributes(ctx->tmpname, attributes & ~FILE_ATTRIBUTE_TEMPORARY)) { - zip_error_set(&ctx->error, ZIP_ER_RENAME, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - } - - if (!file_ops->move_file(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING)) { - zip_error_set(&ctx->error, ZIP_ER_RENAME, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - - return 0; -} - -static zip_int64_t -_zip_win32_named_op_create_temp_output(zip_source_file_context_t *ctx) { - zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata; - - zip_uint32_t value, i; - HANDLE th = INVALID_HANDLE_VALUE; - void *temp = NULL; - PSECURITY_DESCRIPTOR psd = NULL; - PSECURITY_ATTRIBUTES psa = NULL; - SECURITY_ATTRIBUTES sa; - SECURITY_INFORMATION si; - DWORD success; - PACL dacl = NULL; - char *tempname = NULL; - size_t tempname_size = 0; - - if ((HANDLE)ctx->f != INVALID_HANDLE_VALUE && GetFileType((HANDLE)ctx->f) == FILE_TYPE_DISK) { - si = DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION; - success = GetSecurityInfo((HANDLE)ctx->f, SE_FILE_OBJECT, si, NULL, NULL, &dacl, NULL, &psd); - if (success == ERROR_SUCCESS) { - sa.nLength = sizeof(SECURITY_ATTRIBUTES); - sa.bInheritHandle = FALSE; - sa.lpSecurityDescriptor = psd; - psa = &sa; - } - } - - #ifndef MS_UWP - value = GetTickCount(); -#else - value = (zip_uint32_t)(GetTickCount64() & 0xffffffff); -#endif - - if ((tempname = file_ops->allocate_tempname(ctx->fname, 10, &tempname_size)) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); - return -1; - } - - for (i = 0; i < 1024 && th == INVALID_HANDLE_VALUE; i++) { - file_ops->make_tempname(tempname, tempname_size, ctx->fname, value + i); - - th = win32_named_open(ctx, tempname, true, psa); - if (th == INVALID_HANDLE_VALUE && GetLastError() != ERROR_FILE_EXISTS) - break; - } - - if (th == INVALID_HANDLE_VALUE) { - free(tempname); - LocalFree(psd); - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - - LocalFree(psd); - ctx->fout = th; - ctx->tmpname = tempname; - - return 0; -} - - -static bool -_zip_win32_named_op_open(zip_source_file_context_t *ctx) { - HANDLE h = win32_named_open(ctx, ctx->fname, false, NULL); - - if (h == INVALID_HANDLE_VALUE) { - return false; - } - - ctx->f = h; - return true; -} - - -static zip_int64_t -_zip_win32_named_op_remove(zip_source_file_context_t *ctx) { - zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata; - - if (!file_ops->delete_file(ctx->fname)) { - zip_error_set(&ctx->error, ZIP_ER_REMOVE, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - - return 0; -} - - -static void -_zip_win32_named_op_rollback_write(zip_source_file_context_t *ctx) { - zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata; - - if (ctx->fout) { - CloseHandle((HANDLE)ctx->fout); - } - file_ops->delete_file(ctx->tmpname); -} - - -static bool -_zip_win32_named_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) { - zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata; - - WIN32_FILE_ATTRIBUTE_DATA file_attributes; - - if (!file_ops->get_file_attributes_ex(ctx->fname, GetFileExInfoStandard, &file_attributes)) { - DWORD error = GetLastError(); - if (error == ERROR_FILE_NOT_FOUND) { - st->exists = false; - return true; - } - zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(error)); - return false; - } - - st->exists = true; - st->regular_file = true; /* TODO: Is this always right? How to determine without a HANDLE? */ - if (!_zip_filetime_to_time_t(file_attributes.ftLastWriteTime, &st->mtime)) { - zip_error_set(&ctx->error, ZIP_ER_READ, ERANGE); - return false; - } - st->size = ((zip_uint64_t)file_attributes.nFileSizeHigh << 32) | file_attributes.nFileSizeLow; - - /* TODO: fill in ctx->attributes */ - - return true; -} - - -static char * -_zip_win32_named_op_string_duplicate(zip_source_file_context_t *ctx, const char *string) { - zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata; - - return file_ops->string_duplicate(string); -} - - -static zip_int64_t -_zip_win32_named_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len) { - DWORD ret; - if (!WriteFile((HANDLE)ctx->fout, data, (DWORD)len, &ret, NULL) || ret != len) { - zip_error_set(&ctx->error, ZIP_ER_WRITE, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - - return (zip_int64_t)ret; -} - - -static HANDLE -win32_named_open(zip_source_file_context_t *ctx, const char *name, bool temporary, PSECURITY_ATTRIBUTES security_attributes) { - zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata; - - DWORD access = GENERIC_READ; - DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE; - DWORD creation_disposition = OPEN_EXISTING; - DWORD file_attributes = FILE_ATTRIBUTE_NORMAL; - - if (temporary) { - access = GENERIC_READ | GENERIC_WRITE; - share_mode = FILE_SHARE_READ; - creation_disposition = CREATE_NEW; - file_attributes = FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY; - } - - HANDLE h = file_ops->create_file(name, access, share_mode, security_attributes, creation_disposition, file_attributes, NULL); - - if (h == INVALID_HANDLE_VALUE) { - zip_error_set(&ctx->error, ZIP_ER_OPEN, _zip_win32_error_to_errno(GetLastError())); - } - - return h; -} diff --git a/ext/libzip/zip_source_file_win32_utf16.c b/ext/libzip/zip_source_file_win32_utf16.c deleted file mode 100644 index 3c8daa08ba..0000000000 --- a/ext/libzip/zip_source_file_win32_utf16.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - zip_source_file_win32_utf16.c -- source for Windows file opened by UTF-16 name - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#ifdef MS_UWP -#include -#endif - -#include "zip_source_file_win32.h" - -static char *utf16_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp); -static HANDLE __stdcall utf16_create_file(const char *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file); -static void utf16_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i); -static char *utf16_strdup(const char *string); - -#ifdef MS_UWP -static BOOL __stdcall GetFileAttr(const void* name, GET_FILEEX_INFO_LEVELS info_level, void* lpFileInformation) { - BOOL state = GetFileAttributesExFromAppW(name, info_level, lpFileInformation); - return state; -} - -static BOOL __stdcall DelFile(const void* name) { - BOOL state = DeleteFileFromAppW(name); - return state; -} - -zip_win32_file_operations_t ops_utf16 = { - utf16_allocate_tempname, - (zip_win32_create_file_t)utf16_create_file, - DelFile, - (zip_win32_get_file_attributes_t)GetFileAttributesW, - GetFileAttr, - utf16_make_tempname, - (zip_win32_move_file_t)MoveFileExW, - (zip_win32_set_file_attributes_t)SetFileAttributesW, - utf16_strdup -}; -#else -zip_win32_file_operations_t ops_utf16 = { - utf16_allocate_tempname, - (zip_win32_create_file_t)utf16_create_file, - (zip_win32_delete_file_t)DeleteFileW, - (zip_win32_get_file_attributes_t)GetFileAttributesW, - (zip_win32_get_file_attributes_ex_t)GetFileAttributesExW, - utf16_make_tempname, - (zip_win32_move_file_t)MoveFileExW, - (zip_win32_set_file_attributes_t)SetFileAttributesW, - utf16_strdup -}; -#endif - -ZIP_EXTERN zip_source_t * -zip_source_win32w(zip_t *za, const wchar_t *fname, zip_uint64_t start, zip_int64_t len) { - if (za == NULL) - return NULL; - - return zip_source_win32w_create(fname, start, len, &za->error); -} - - -ZIP_EXTERN zip_source_t * -zip_source_win32w_create(const wchar_t *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) { - if (fname == NULL || length < -1) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - - return zip_source_file_common_new((const char *)fname, NULL, start, length, NULL, &_zip_source_file_win32_named_ops, &ops_utf16, error); -} - - -static char * -utf16_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp) { - *lengthp = wcslen((const wchar_t *)name) + extra_chars; - return (char *)malloc(*lengthp * sizeof(wchar_t)); -} - - -static HANDLE __stdcall -utf16_create_file(const char *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file) { -#ifdef MS_UWP -#if 0 - CREATEFILE2_EXTENDED_PARAMETERS extParams = {0}; - extParams.dwFileAttributes = file_attributes; - extParams.dwFileFlags = FILE_FLAG_RANDOM_ACCESS; - extParams.dwSecurityQosFlags = SECURITY_ANONYMOUS; - extParams.dwSize = sizeof(extParams); - extParams.hTemplateFile = template_file; - extParams.lpSecurityAttributes = security_attributes; - - return CreateFile2((const wchar_t *)name, access, share_mode, creation_disposition, &extParams); -#else - return CreateFile2FromAppW((const wchar_t *)name, access, share_mode, creation_disposition, NULL); -#endif -#else - return CreateFileW((const wchar_t *)name, access, share_mode, security_attributes, creation_disposition, file_attributes, template_file); -#endif -} - - -static void -utf16_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i) { - _snwprintf((wchar_t *)buf, len, L"%s.%08x", (const wchar_t *)name, i); -} - - -static char * -utf16_strdup(const char *string) { - return (char *)_wcsdup((const wchar_t *)string); -} diff --git a/ext/libzip/zip_source_file_win32_utf8.c b/ext/libzip/zip_source_file_win32_utf8.c deleted file mode 100644 index 4955eede2d..0000000000 --- a/ext/libzip/zip_source_file_win32_utf8.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - zip_source_file_win32_ansi.c -- source for Windows file opened by UTF-8 name - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include "zip_source_file_win32.h" - -ZIP_EXTERN zip_source_t * -zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len) { - if (za == NULL) { - return NULL; - } - - return zip_source_file_create(fname, start, len, &za->error); -} - - -ZIP_EXTERN zip_source_t * -zip_source_file_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) { - int size; - wchar_t *wfname; - zip_source_t *source; - - if (fname == NULL || length < -1) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - /* Convert fname from UTF-8 to Windows-friendly UTF-16. */ - size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, fname, -1, NULL, 0); - if (size == 0) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - if ((wfname = (wchar_t *)malloc(sizeof(wchar_t) * size)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; - } - MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, fname, -1, wfname, size); - - source = zip_source_win32w_create(wfname, start, length, error); - - free(wfname); - return source; -} diff --git a/ext/libzip/zip_source_free.c b/ext/libzip/zip_source_free.c deleted file mode 100644 index 2f10ef8f1b..0000000000 --- a/ext/libzip/zip_source_free.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - zip_source_free.c -- free zip data source - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include - -#include "zipint.h" - - -ZIP_EXTERN void -zip_source_free(zip_source_t *src) { - if (src == NULL) - return; - - if (src->refcount > 0) { - src->refcount--; - } - if (src->refcount > 0) { - return; - } - - if (ZIP_SOURCE_IS_OPEN_READING(src)) { - src->open_count = 1; /* force close */ - zip_source_close(src); - } - if (ZIP_SOURCE_IS_OPEN_WRITING(src)) { - zip_source_rollback_write(src); - } - - if (src->source_archive && !src->source_closed) { - _zip_deregister_source(src->source_archive, src); - } - - (void)_zip_source_call(src, NULL, 0, ZIP_SOURCE_FREE); - - if (src->src) { - zip_source_free(src->src); - } - - free(src); -} diff --git a/ext/libzip/zip_source_function.c b/ext/libzip/zip_source_function.c deleted file mode 100644 index d5c1b5b01f..0000000000 --- a/ext/libzip/zip_source_function.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - zip_source_function.c -- create zip data source from callback function - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include - -#include "zipint.h" - - -ZIP_EXTERN zip_source_t * -zip_source_function(zip_t *za, zip_source_callback zcb, void *ud) { - if (za == NULL) { - return NULL; - } - - return zip_source_function_create(zcb, ud, &za->error); -} - - -ZIP_EXTERN zip_source_t * -zip_source_function_create(zip_source_callback zcb, void *ud, zip_error_t *error) { - zip_source_t *zs; - - if ((zs = _zip_source_new(error)) == NULL) - return NULL; - - zs->cb.f = zcb; - zs->ud = ud; - - zs->supports = zcb(ud, NULL, 0, ZIP_SOURCE_SUPPORTS); - if (zs->supports < 0) { - zs->supports = ZIP_SOURCE_SUPPORTS_READABLE; - } - - return zs; -} - - -ZIP_EXTERN void -zip_source_keep(zip_source_t *src) { - src->refcount++; -} - - -zip_source_t * -_zip_source_new(zip_error_t *error) { - zip_source_t *src; - - if ((src = (zip_source_t *)malloc(sizeof(*src))) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; - } - - src->src = NULL; - src->cb.f = NULL; - src->ud = NULL; - src->open_count = 0; - src->write_state = ZIP_SOURCE_WRITE_CLOSED; - src->source_closed = false; - src->source_archive = NULL; - src->refcount = 1; - zip_error_init(&src->error); - src->eof = false; - src->had_read_error = false; - - return src; -} diff --git a/ext/libzip/zip_source_get_file_attributes.c b/ext/libzip/zip_source_get_file_attributes.c deleted file mode 100644 index acbede1de6..0000000000 --- a/ext/libzip/zip_source_get_file_attributes.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - zip_source_get_file_attributes.c -- get attributes for file from source - Copyright (C) 2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "zipint.h" - -ZIP_EXTERN void -zip_file_attributes_init(zip_file_attributes_t *attributes) { - attributes->valid = 0; - attributes->version = 1; -} - -int -zip_source_get_file_attributes(zip_source_t *src, zip_file_attributes_t *attributes) { - if (src->source_closed) { - return -1; - } - if (attributes == NULL) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; - } - - zip_file_attributes_init(attributes); - - if (src->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_GET_FILE_ATTRIBUTES)) { - if (_zip_source_call(src, attributes, sizeof(*attributes), ZIP_SOURCE_GET_FILE_ATTRIBUTES) < 0) { - return -1; - } - } - - if (ZIP_SOURCE_IS_LAYERED(src)) { - zip_file_attributes_t lower_attributes; - - if (zip_source_get_file_attributes(src->src, &lower_attributes) < 0) { - _zip_error_set_from_source(&src->error, src->src); - return -1; - } - - if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_HOST_SYSTEM) && (attributes->valid & ZIP_FILE_ATTRIBUTES_HOST_SYSTEM) == 0) { - attributes->host_system = lower_attributes.host_system; - attributes->valid |= ZIP_FILE_ATTRIBUTES_HOST_SYSTEM; - } - if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_ASCII) && (attributes->valid & ZIP_FILE_ATTRIBUTES_ASCII) == 0) { - attributes->ascii = lower_attributes.ascii; - attributes->valid |= ZIP_FILE_ATTRIBUTES_ASCII; - } - if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_VERSION_NEEDED)) { - if (attributes->valid & ZIP_FILE_ATTRIBUTES_VERSION_NEEDED) { - attributes->version_needed = ZIP_MAX(lower_attributes.version_needed, attributes->version_needed); - } - else { - attributes->version_needed = lower_attributes.version_needed; - attributes->valid |= ZIP_FILE_ATTRIBUTES_VERSION_NEEDED; - } - } - if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES) && (attributes->valid & ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES) == 0) { - attributes->external_file_attributes = lower_attributes.external_file_attributes; - attributes->valid |= ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES; - } - if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS)) { - if (attributes->valid & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS) { - attributes->general_purpose_bit_flags &= ~lower_attributes.general_purpose_bit_mask; - attributes->general_purpose_bit_flags |= lower_attributes.general_purpose_bit_flags & lower_attributes.general_purpose_bit_mask; - attributes->general_purpose_bit_mask |= lower_attributes.general_purpose_bit_mask; - } - else { - attributes->valid |= ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS; - attributes->general_purpose_bit_flags = lower_attributes.general_purpose_bit_flags; - attributes->general_purpose_bit_mask = lower_attributes.general_purpose_bit_mask; - } - } - } - - return 0; -} diff --git a/ext/libzip/zip_source_is_deleted.c b/ext/libzip/zip_source_is_deleted.c deleted file mode 100644 index edd10ca221..0000000000 --- a/ext/libzip/zip_source_is_deleted.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - zip_source_is_deleted.c -- was archive was removed? - Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN int -zip_source_is_deleted(zip_source_t *src) { - return src->write_state == ZIP_SOURCE_WRITE_REMOVED; -} diff --git a/ext/libzip/zip_source_layered.c b/ext/libzip/zip_source_layered.c deleted file mode 100644 index d02bc8529d..0000000000 --- a/ext/libzip/zip_source_layered.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - zip_source_layered.c -- create layered source - Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include - -#include "zipint.h" - - -zip_source_t * -zip_source_layered(zip_t *za, zip_source_t *src, zip_source_layered_callback cb, void *ud) { - if (za == NULL) - return NULL; - - return zip_source_layered_create(src, cb, ud, &za->error); -} - - -zip_source_t * -zip_source_layered_create(zip_source_t *src, zip_source_layered_callback cb, void *ud, zip_error_t *error) { - zip_source_t *zs; - - if ((zs = _zip_source_new(error)) == NULL) - return NULL; - - zip_source_keep(src); - zs->src = src; - zs->cb.l = cb; - zs->ud = ud; - - zs->supports = cb(src, ud, NULL, 0, ZIP_SOURCE_SUPPORTS); - if (zs->supports < 0) { - zs->supports = ZIP_SOURCE_SUPPORTS_READABLE; - } - - return zs; -} diff --git a/ext/libzip/zip_source_open.c b/ext/libzip/zip_source_open.c deleted file mode 100644 index 414c677a17..0000000000 --- a/ext/libzip/zip_source_open.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - zip_source_open.c -- open zip_source (prepare for reading) - Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - -ZIP_EXTERN int -zip_source_open(zip_source_t *src) { - if (src->source_closed) { - return -1; - } - if (src->write_state == ZIP_SOURCE_WRITE_REMOVED) { - zip_error_set(&src->error, ZIP_ER_DELETED, 0); - return -1; - } - - if (ZIP_SOURCE_IS_OPEN_READING(src)) { - if ((zip_source_supports(src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK)) == 0) { - zip_error_set(&src->error, ZIP_ER_INUSE, 0); - return -1; - } - } - else { - if (ZIP_SOURCE_IS_LAYERED(src)) { - if (zip_source_open(src->src) < 0) { - _zip_error_set_from_source(&src->error, src->src); - return -1; - } - } - - if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_OPEN) < 0) { - if (ZIP_SOURCE_IS_LAYERED(src)) { - zip_source_close(src->src); - } - return -1; - } - } - - src->eof = false; - src->had_read_error = false; - _zip_error_clear(&src->error); - src->open_count++; - - return 0; -} diff --git a/ext/libzip/zip_source_pkware_decode.c b/ext/libzip/zip_source_pkware_decode.c deleted file mode 100644 index d5489a500f..0000000000 --- a/ext/libzip/zip_source_pkware_decode.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - zip_source_pkware_decode.c -- Traditional PKWARE decryption routines - Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include -#include - -#include "zipint.h" - -struct trad_pkware { - char *password; - zip_pkware_keys_t keys; - zip_error_t error; -}; - - -static int decrypt_header(zip_source_t *, struct trad_pkware *); -static zip_int64_t pkware_decrypt(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t); -static struct trad_pkware *trad_pkware_new(const char *password, zip_error_t *error); -static void trad_pkware_free(struct trad_pkware *); - - -zip_source_t * -zip_source_pkware_decode(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, const char *password) { - struct trad_pkware *ctx; - zip_source_t *s2; - - if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } - if (flags & ZIP_CODEC_ENCODE) { - zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); - return NULL; - } - - if ((ctx = trad_pkware_new(password, &za->error)) == NULL) { - return NULL; - } - - if ((s2 = zip_source_layered(za, src, pkware_decrypt, ctx)) == NULL) { - trad_pkware_free(ctx); - return NULL; - } - - return s2; -} - - -static int -decrypt_header(zip_source_t *src, struct trad_pkware *ctx) { - zip_uint8_t header[ZIP_CRYPTO_PKWARE_HEADERLEN]; - struct zip_stat st; - zip_int64_t n; - - if ((n = zip_source_read(src, header, ZIP_CRYPTO_PKWARE_HEADERLEN)) < 0) { - _zip_error_set_from_source(&ctx->error, src); - return -1; - } - - if (n != ZIP_CRYPTO_PKWARE_HEADERLEN) { - zip_error_set(&ctx->error, ZIP_ER_EOF, 0); - return -1; - } - - _zip_pkware_decrypt(&ctx->keys, header, header, ZIP_CRYPTO_PKWARE_HEADERLEN); - - if (zip_source_stat(src, &st)) { - /* stat failed, skip password validation */ - return 0; - } - - /* password verification - two ways: - * mtime - InfoZIP way, to avoid computing complete CRC before encrypting data - * CRC - old PKWare way - */ - - bool ok = false; - - if (st.valid & ZIP_STAT_MTIME) { - unsigned short dostime, dosdate; - _zip_u2d_time(st.mtime, &dostime, &dosdate); - if (header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] == dostime >> 8) { - ok = true; - } - } - - if (st.valid & ZIP_STAT_CRC) { - if (header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] == st.crc >> 24) { - ok = true; - } - } - - if (!ok && ((st.valid & (ZIP_STAT_MTIME | ZIP_STAT_CRC)) != 0)) { - zip_error_set(&ctx->error, ZIP_ER_WRONGPASSWD, 0); - return -1; - } - - return 0; -} - - -static zip_int64_t -pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { - struct trad_pkware *ctx; - zip_int64_t n; - - ctx = (struct trad_pkware *)ud; - - switch (cmd) { - case ZIP_SOURCE_OPEN: - _zip_pkware_keys_reset(&ctx->keys); - _zip_pkware_decrypt(&ctx->keys, NULL, (const zip_uint8_t *)ctx->password, strlen(ctx->password)); - if (decrypt_header(src, ctx) < 0) { - return -1; - } - return 0; - - case ZIP_SOURCE_READ: - if ((n = zip_source_read(src, data, len)) < 0) { - _zip_error_set_from_source(&ctx->error, src); - return -1; - } - - _zip_pkware_decrypt(&ctx->keys, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n); - return n; - - case ZIP_SOURCE_CLOSE: - return 0; - - case ZIP_SOURCE_STAT: { - zip_stat_t *st; - - st = (zip_stat_t *)data; - - st->encryption_method = ZIP_EM_NONE; - st->valid |= ZIP_STAT_ENCRYPTION_METHOD; - if (st->valid & ZIP_STAT_COMP_SIZE) { - st->comp_size -= ZIP_CRYPTO_PKWARE_HEADERLEN; - } - - return 0; - } - - case ZIP_SOURCE_SUPPORTS: - return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, -1); - - case ZIP_SOURCE_ERROR: - return zip_error_to_data(&ctx->error, data, len); - - case ZIP_SOURCE_FREE: - trad_pkware_free(ctx); - return 0; - - default: - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } -} - - -static struct trad_pkware * -trad_pkware_new(const char *password, zip_error_t *error) { - struct trad_pkware *ctx; - - if ((ctx = (struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; - } - - if ((ctx->password = strdup(password)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - free(ctx); - return NULL; - } - - zip_error_init(&ctx->error); - - return ctx; -} - - -static void -trad_pkware_free(struct trad_pkware *ctx) { - if (ctx == NULL) { - return; - } - - free(ctx->password); - free(ctx); -} diff --git a/ext/libzip/zip_source_pkware_encode.c b/ext/libzip/zip_source_pkware_encode.c deleted file mode 100644 index 1e8f42c39b..0000000000 --- a/ext/libzip/zip_source_pkware_encode.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - zip_source_pkware_encode.c -- Traditional PKWARE encryption routines - Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include -#include - -#include "zipint.h" - -struct trad_pkware { - char *password; - zip_pkware_keys_t keys; - zip_buffer_t *buffer; - bool eof; - zip_error_t error; -}; - - -static int encrypt_header(zip_source_t *, struct trad_pkware *); -static zip_int64_t pkware_encrypt(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t); -static void trad_pkware_free(struct trad_pkware *); -static struct trad_pkware *trad_pkware_new(const char *password, zip_error_t *error); - - -zip_source_t * -zip_source_pkware_encode(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, const char *password) { - struct trad_pkware *ctx; - zip_source_t *s2; - - if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } - if (!(flags & ZIP_CODEC_ENCODE)) { - zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); - return NULL; - } - - if ((ctx = trad_pkware_new(password, &za->error)) == NULL) { - return NULL; - } - - if ((s2 = zip_source_layered(za, src, pkware_encrypt, ctx)) == NULL) { - trad_pkware_free(ctx); - return NULL; - } - - return s2; -} - - -static int -encrypt_header(zip_source_t *src, struct trad_pkware *ctx) { - struct zip_stat st; - unsigned short dostime, dosdate; - zip_uint8_t *header; - - if (zip_source_stat(src, &st) != 0) { - _zip_error_set_from_source(&ctx->error, src); - return -1; - } - - _zip_u2d_time(st.mtime, &dostime, &dosdate); - - if ((ctx->buffer = _zip_buffer_new(NULL, ZIP_CRYPTO_PKWARE_HEADERLEN)) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); - return -1; - } - - header = _zip_buffer_data(ctx->buffer); - - /* generate header from random bytes and mtime - see appnote.iz, XIII. Decryption, Step 2, last paragraph */ - if (!zip_secure_random(header, ZIP_CRYPTO_PKWARE_HEADERLEN - 1)) { - zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0); - _zip_buffer_free(ctx->buffer); - ctx->buffer = NULL; - return -1; - } - header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] = (zip_uint8_t)((dostime >> 8) & 0xff); - - _zip_pkware_encrypt(&ctx->keys, header, header, ZIP_CRYPTO_PKWARE_HEADERLEN); - - return 0; -} - - -static zip_int64_t -pkware_encrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t length, zip_source_cmd_t cmd) { - struct trad_pkware *ctx; - zip_int64_t n; - zip_uint64_t buffer_n; - - ctx = (struct trad_pkware *)ud; - - switch (cmd) { - case ZIP_SOURCE_OPEN: - ctx->eof = false; - - /* initialize keys */ - _zip_pkware_keys_reset(&ctx->keys); - _zip_pkware_encrypt(&ctx->keys, NULL, (const zip_uint8_t *)ctx->password, strlen(ctx->password)); - - if (encrypt_header(src, ctx) < 0) { - return -1; - } - return 0; - - case ZIP_SOURCE_READ: - buffer_n = 0; - - if (ctx->buffer) { - /* write header values to data */ - buffer_n = _zip_buffer_read(ctx->buffer, data, length); - data = (zip_uint8_t *)data + buffer_n; - length -= buffer_n; - - if (_zip_buffer_eof(ctx->buffer)) { - _zip_buffer_free(ctx->buffer); - ctx->buffer = NULL; - } - } - - if (ctx->eof) { - return (zip_int64_t)buffer_n; - } - - if ((n = zip_source_read(src, data, length)) < 0) { - _zip_error_set_from_source(&ctx->error, src); - return -1; - } - - _zip_pkware_encrypt(&ctx->keys, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n); - - if ((zip_uint64_t)n < length) { - ctx->eof = true; - } - - return (zip_int64_t)buffer_n + n; - - case ZIP_SOURCE_CLOSE: - _zip_buffer_free(ctx->buffer); - ctx->buffer = NULL; - return 0; - - case ZIP_SOURCE_STAT: { - zip_stat_t *st; - - st = (zip_stat_t *)data; - st->encryption_method = ZIP_EM_TRAD_PKWARE; - st->valid |= ZIP_STAT_ENCRYPTION_METHOD; - if (st->valid & ZIP_STAT_COMP_SIZE) { - st->comp_size += ZIP_CRYPTO_PKWARE_HEADERLEN; - } - - return 0; - } - - case ZIP_SOURCE_GET_FILE_ATTRIBUTES: { - zip_file_attributes_t *attributes = (zip_file_attributes_t *)data; - if (length < sizeof(*attributes)) { - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } - attributes->valid |= ZIP_FILE_ATTRIBUTES_VERSION_NEEDED; - attributes->version_needed = 20; - - return 0; - } - - case ZIP_SOURCE_SUPPORTS: - return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1); - - case ZIP_SOURCE_ERROR: - return zip_error_to_data(&ctx->error, data, length); - - case ZIP_SOURCE_FREE: - trad_pkware_free(ctx); - return 0; - - default: - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } -} - - -static struct trad_pkware * -trad_pkware_new(const char *password, zip_error_t *error) { - struct trad_pkware *ctx; - - if ((ctx = (struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; - } - - if ((ctx->password = strdup(password)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - free(ctx); - return NULL; - } - ctx->buffer = NULL; - zip_error_init(&ctx->error); - - return ctx; -} - - -static void -trad_pkware_free(struct trad_pkware *ctx) { - if (ctx == NULL) { - return; - } - - free(ctx->password); - _zip_buffer_free(ctx->buffer); - zip_error_fini(&ctx->error); - free(ctx); -} diff --git a/ext/libzip/zip_source_read.c b/ext/libzip/zip_source_read.c deleted file mode 100644 index 33088cb117..0000000000 --- a/ext/libzip/zip_source_read.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - zip_source_read.c -- read data from zip_source - Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -zip_int64_t -zip_source_read(zip_source_t *src, void *data, zip_uint64_t len) { - zip_uint64_t bytes_read; - zip_int64_t n; - - if (src->source_closed) { - return -1; - } - if (!ZIP_SOURCE_IS_OPEN_READING(src) || len > ZIP_INT64_MAX || (len > 0 && data == NULL)) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (src->had_read_error) { - return -1; - } - - if (_zip_source_eof(src)) { - return 0; - } - - if (len == 0) { - return 0; - } - - bytes_read = 0; - while (bytes_read < len) { - if ((n = _zip_source_call(src, (zip_uint8_t *)data + bytes_read, len - bytes_read, ZIP_SOURCE_READ)) < 0) { - src->had_read_error = true; - if (bytes_read == 0) { - return -1; - } - else { - return (zip_int64_t)bytes_read; - } - } - - if (n == 0) { - src->eof = 1; - break; - } - - bytes_read += (zip_uint64_t)n; - } - - return (zip_int64_t)bytes_read; -} - - -bool -_zip_source_eof(zip_source_t *src) { - return src->eof; -} diff --git a/ext/libzip/zip_source_remove.c b/ext/libzip/zip_source_remove.c deleted file mode 100644 index 14eddb8f58..0000000000 --- a/ext/libzip/zip_source_remove.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - zip_source_remove.c -- remove empty archive - Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#include "zipint.h" - - -int -zip_source_remove(zip_source_t *src) { - if (src->write_state == ZIP_SOURCE_WRITE_REMOVED) { - return 0; - } - - if (ZIP_SOURCE_IS_OPEN_READING(src)) { - if (zip_source_close(src) < 0) { - return -1; - } - } - if (src->write_state != ZIP_SOURCE_WRITE_CLOSED) { - zip_source_rollback_write(src); - } - - if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_REMOVE) < 0) { - return -1; - } - - src->write_state = ZIP_SOURCE_WRITE_REMOVED; - - return 0; -} diff --git a/ext/libzip/zip_source_rollback_write.c b/ext/libzip/zip_source_rollback_write.c deleted file mode 100644 index e8259bff2c..0000000000 --- a/ext/libzip/zip_source_rollback_write.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - zip_source_rollback_write.c -- discard changes - Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN void -zip_source_rollback_write(zip_source_t *src) { - if (src->write_state != ZIP_SOURCE_WRITE_OPEN && src->write_state != ZIP_SOURCE_WRITE_FAILED) { - return; - } - - _zip_source_call(src, NULL, 0, ZIP_SOURCE_ROLLBACK_WRITE); - src->write_state = ZIP_SOURCE_WRITE_CLOSED; -} diff --git a/ext/libzip/zip_source_seek.c b/ext/libzip/zip_source_seek.c deleted file mode 100644 index 163daf1b66..0000000000 --- a/ext/libzip/zip_source_seek.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - zip_source_seek.c -- seek to offset - Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN int -zip_source_seek(zip_source_t *src, zip_int64_t offset, int whence) { - zip_source_args_seek_t args; - - if (src->source_closed) { - return -1; - } - if (!ZIP_SOURCE_IS_OPEN_READING(src) || (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END)) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; - } - - args.offset = offset; - args.whence = whence; - - if (_zip_source_call(src, &args, sizeof(args), ZIP_SOURCE_SEEK) < 0) { - return -1; - } - - src->eof = 0; - return 0; -} - - -zip_int64_t -zip_source_seek_compute_offset(zip_uint64_t offset, zip_uint64_t length, void *data, zip_uint64_t data_length, zip_error_t *error) { - zip_int64_t new_offset; - zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, data_length, error); - - if (args == NULL) { - return -1; - } - - switch (args->whence) { - case SEEK_CUR: - new_offset = (zip_int64_t)offset + args->offset; - break; - - case SEEK_END: - new_offset = (zip_int64_t)length + args->offset; - break; - - case SEEK_SET: - new_offset = args->offset; - break; - - default: - zip_error_set(error, ZIP_ER_INVAL, 0); - return -1; - } - - if (new_offset < 0 || (zip_uint64_t)new_offset > length) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return -1; - } - - return new_offset; -} diff --git a/ext/libzip/zip_source_seek_write.c b/ext/libzip/zip_source_seek_write.c deleted file mode 100644 index 6b0aa78e53..0000000000 --- a/ext/libzip/zip_source_seek_write.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - zip_source_seek_write.c -- seek to offset for writing - Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN int -zip_source_seek_write(zip_source_t *src, zip_int64_t offset, int whence) { - zip_source_args_seek_t args; - - if (!ZIP_SOURCE_IS_OPEN_WRITING(src) || (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END)) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; - } - - args.offset = offset; - args.whence = whence; - - return (_zip_source_call(src, &args, sizeof(args), ZIP_SOURCE_SEEK_WRITE) < 0 ? -1 : 0); -} diff --git a/ext/libzip/zip_source_stat.c b/ext/libzip/zip_source_stat.c deleted file mode 100644 index 3421d2cbd5..0000000000 --- a/ext/libzip/zip_source_stat.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - zip_source_stat.c -- get meta information from zip_source - Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN int -zip_source_stat(zip_source_t *src, zip_stat_t *st) { - if (src->source_closed) { - return -1; - } - if (st == NULL) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; - } - - zip_stat_init(st); - - if (ZIP_SOURCE_IS_LAYERED(src)) { - if (zip_source_stat(src->src, st) < 0) { - _zip_error_set_from_source(&src->error, src->src); - return -1; - } - } - - if (_zip_source_call(src, st, sizeof(*st), ZIP_SOURCE_STAT) < 0) { - return -1; - } - - return 0; -} diff --git a/ext/libzip/zip_source_supports.c b/ext/libzip/zip_source_supports.c deleted file mode 100644 index 8471559821..0000000000 --- a/ext/libzip/zip_source_supports.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - zip_source_supports.c -- check for supported functions - Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include - -#include "zipint.h" - - -zip_int64_t -zip_source_supports(zip_source_t *src) { - return src->supports; -} - - -ZIP_EXTERN zip_int64_t -zip_source_make_command_bitmap(zip_source_cmd_t cmd0, ...) { - zip_int64_t bitmap; - va_list ap; - - bitmap = ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd0); - - - va_start(ap, cmd0); - for (;;) { - int cmd = va_arg(ap, int); - if (cmd < 0) { - break; - } - bitmap |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd); - } - va_end(ap); - - return bitmap; -} diff --git a/ext/libzip/zip_source_tell.c b/ext/libzip/zip_source_tell.c deleted file mode 100644 index 772e2524a8..0000000000 --- a/ext/libzip/zip_source_tell.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - zip_source_tell.c -- report current offset - Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN zip_int64_t -zip_source_tell(zip_source_t *src) { - if (src->source_closed) { - return -1; - } - if (!ZIP_SOURCE_IS_OPEN_READING(src)) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; - } - - return _zip_source_call(src, NULL, 0, ZIP_SOURCE_TELL); -} diff --git a/ext/libzip/zip_source_tell_write.c b/ext/libzip/zip_source_tell_write.c deleted file mode 100644 index 96ad7e2673..0000000000 --- a/ext/libzip/zip_source_tell_write.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - zip_source_tell_write.c -- report current offset for writing - Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN zip_int64_t -zip_source_tell_write(zip_source_t *src) { - if (!ZIP_SOURCE_IS_OPEN_WRITING(src)) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; - } - - return _zip_source_call(src, NULL, 0, ZIP_SOURCE_TELL_WRITE); -} diff --git a/ext/libzip/zip_source_window.c b/ext/libzip/zip_source_window.c deleted file mode 100644 index d996015da4..0000000000 --- a/ext/libzip/zip_source_window.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - zip_source_window.c -- return part of lower source - Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include -#include - -#include "zipint.h" - -struct window { - zip_uint64_t start; /* where in file we start reading */ - zip_uint64_t end; /* where in file we stop reading */ - - /* if not NULL, read file data for this file */ - zip_t *source_archive; - zip_uint64_t source_index; - - zip_uint64_t offset; /* offset in src for next read */ - - zip_stat_t stat; - zip_file_attributes_t attributes; - zip_error_t error; - zip_int64_t supports; - bool needs_seek; -}; - -static zip_int64_t window_read(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t); - - -zip_source_t * -zip_source_window(zip_t *za, zip_source_t *src, zip_uint64_t start, zip_uint64_t len) { - return _zip_source_window_new(src, start, len, NULL, 0, NULL, 0, &za->error); -} - - -zip_source_t * -_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t length, zip_stat_t *st, zip_file_attributes_t *attributes, zip_t *source_archive, zip_uint64_t source_index, zip_error_t *error) { - struct window *ctx; - - if (src == NULL || start + length < start || (source_archive == NULL && source_index != 0)) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - if ((ctx = (struct window *)malloc(sizeof(*ctx))) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; - } - - ctx->start = start; - ctx->end = start + length; - zip_stat_init(&ctx->stat); - if (attributes != NULL) { - memcpy(&ctx->attributes, attributes, sizeof(ctx->attributes)); - } - else { - zip_file_attributes_init(&ctx->attributes); - } - ctx->source_archive = source_archive; - ctx->source_index = source_index; - zip_error_init(&ctx->error); - ctx->supports = (zip_source_supports(src) & ZIP_SOURCE_SUPPORTS_SEEKABLE) | (zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1)); - ctx->needs_seek = (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK)) ? true : false; - - if (st) { - if (_zip_stat_merge(&ctx->stat, st, error) < 0) { - free(ctx); - return NULL; - } - } - - return zip_source_layered_create(src, window_read, ctx, error); -} - - -int -_zip_source_set_source_archive(zip_source_t *src, zip_t *za) { - src->source_archive = za; - return _zip_register_source(za, src); -} - - -/* called by zip_discard to avoid operating on file from closed archive */ -void -_zip_source_invalidate(zip_source_t *src) { - src->source_closed = 1; - - if (zip_error_code_zip(&src->error) == ZIP_ER_OK) { - zip_error_set(&src->error, ZIP_ER_ZIPCLOSED, 0); - } -} - - -static zip_int64_t -window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { - struct window *ctx; - zip_int64_t ret; - zip_uint64_t n, i; - - ctx = (struct window *)_ctx; - - switch (cmd) { - case ZIP_SOURCE_CLOSE: - return 0; - - case ZIP_SOURCE_ERROR: - return zip_error_to_data(&ctx->error, data, len); - - case ZIP_SOURCE_FREE: - free(ctx); - return 0; - - case ZIP_SOURCE_OPEN: - if (ctx->source_archive) { - zip_uint64_t offset; - - if ((offset = _zip_file_get_offset(ctx->source_archive, ctx->source_index, &ctx->error)) == 0) { - return -1; - } - if (ctx->end + offset < ctx->end) { - /* zip archive data claims end of data past zip64 limits */ - zip_error_set(&ctx->error, ZIP_ER_INCONS, 0); - return -1; - } - ctx->start += offset; - ctx->end += offset; - ctx->source_archive = NULL; - } - - if (!ctx->needs_seek) { - DEFINE_BYTE_ARRAY(b, BUFSIZE); - - if (!byte_array_init(b, BUFSIZE)) { - zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); - return -1; - } - - for (n = 0; n < ctx->start; n += (zip_uint64_t)ret) { - i = (ctx->start - n > BUFSIZE ? BUFSIZE : ctx->start - n); - if ((ret = zip_source_read(src, b, i)) < 0) { - _zip_error_set_from_source(&ctx->error, src); - byte_array_fini(b); - return -1; - } - if (ret == 0) { - zip_error_set(&ctx->error, ZIP_ER_EOF, 0); - byte_array_fini(b); - return -1; - } - } - - byte_array_fini(b); - } - - ctx->offset = ctx->start; - return 0; - - case ZIP_SOURCE_READ: - if (len > ctx->end - ctx->offset) - len = ctx->end - ctx->offset; - - if (len == 0) - return 0; - - if (ctx->needs_seek) { - if (zip_source_seek(src, (zip_int64_t)ctx->offset, SEEK_SET) < 0) { - _zip_error_set_from_source(&ctx->error, src); - return -1; - } - } - - if ((ret = zip_source_read(src, data, len)) < 0) { - zip_error_set(&ctx->error, ZIP_ER_EOF, 0); - return -1; - } - - ctx->offset += (zip_uint64_t)ret; - - if (ret == 0) { - if (ctx->offset < ctx->end) { - zip_error_set(&ctx->error, ZIP_ER_EOF, 0); - return -1; - } - } - return ret; - - case ZIP_SOURCE_SEEK: { - zip_int64_t new_offset = zip_source_seek_compute_offset(ctx->offset - ctx->start, ctx->end - ctx->start, data, len, &ctx->error); - - if (new_offset < 0) { - return -1; - } - - ctx->offset = (zip_uint64_t)new_offset + ctx->start; - return 0; - } - - case ZIP_SOURCE_STAT: { - zip_stat_t *st; - - st = (zip_stat_t *)data; - - if (_zip_stat_merge(st, &ctx->stat, &ctx->error) < 0) { - return -1; - } - return 0; - } - - case ZIP_SOURCE_GET_FILE_ATTRIBUTES: - if (len < sizeof(ctx->attributes)) { - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } - - memcpy(data, &ctx->attributes, sizeof(ctx->attributes)); - return sizeof(ctx->attributes); - - case ZIP_SOURCE_SUPPORTS: - return ctx->supports; - - case ZIP_SOURCE_TELL: - return (zip_int64_t)(ctx->offset - ctx->start); - - default: - zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); - return -1; - } -} - - -void -_zip_deregister_source(zip_t *za, zip_source_t *src) { - unsigned int i; - - for (i = 0; i < za->nopen_source; i++) { - if (za->open_source[i] == src) { - za->open_source[i] = za->open_source[za->nopen_source - 1]; - za->nopen_source--; - break; - } - } -} - - -int -_zip_register_source(zip_t *za, zip_source_t *src) { - zip_source_t **open_source; - - if (za->nopen_source + 1 >= za->nopen_source_alloc) { - unsigned int n; - n = za->nopen_source_alloc + 10; - open_source = (zip_source_t **)realloc(za->open_source, n * sizeof(zip_source_t *)); - if (open_source == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - za->nopen_source_alloc = n; - za->open_source = open_source; - } - - za->open_source[za->nopen_source++] = src; - - return 0; -} diff --git a/ext/libzip/zip_source_write.c b/ext/libzip/zip_source_write.c deleted file mode 100644 index 73fc3a318e..0000000000 --- a/ext/libzip/zip_source_write.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - zip_source_write.c -- start a new file for writing - Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN zip_int64_t -zip_source_write(zip_source_t *src, const void *data, zip_uint64_t length) { - if (!ZIP_SOURCE_IS_OPEN_WRITING(src) || length > ZIP_INT64_MAX) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; - } - - return _zip_source_call(src, (void *)data, length, ZIP_SOURCE_WRITE); -} diff --git a/ext/libzip/zip_source_zip.c b/ext/libzip/zip_source_zip.c deleted file mode 100644 index 8a7feaa489..0000000000 --- a/ext/libzip/zip_source_zip.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - zip_source_zip.c -- create data source from zip file - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include - -#include "zipint.h" - - -ZIP_EXTERN zip_source_t * -zip_source_zip(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t flags, zip_uint64_t start, zip_int64_t len) { - if (len < -1) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } - - if (len == -1) - len = 0; - - if (start == 0 && len == 0) - flags |= ZIP_FL_COMPRESSED; - else - flags &= ~ZIP_FL_COMPRESSED; - - return _zip_source_zip_new(za, srcza, srcidx, flags, start, (zip_uint64_t)len, NULL); -} diff --git a/ext/libzip/zip_source_zip_new.c b/ext/libzip/zip_source_zip_new.c deleted file mode 100644 index 6d547f0eb8..0000000000 --- a/ext/libzip/zip_source_zip_new.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - zip_source_zip_new.c -- prepare data structures for zip_fopen/zip_source_zip - Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include - -#include "zipint.h" - -static void _zip_file_attributes_from_dirent(zip_file_attributes_t *attributes, zip_dirent_t *de); - -zip_source_t * -_zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t flags, zip_uint64_t start, zip_uint64_t len, const char *password) { - zip_source_t *src, *s2; - zip_stat_t st; - zip_file_attributes_t attributes; - zip_dirent_t *de; - bool partial_data, needs_crc, needs_decrypt, needs_decompress; - - if (za == NULL) { - return NULL; - } - - if (srcza == NULL || srcidx >= srcza->nentry) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } - - if ((flags & ZIP_FL_UNCHANGED) == 0 && (ZIP_ENTRY_DATA_CHANGED(srcza->entry + srcidx) || srcza->entry[srcidx].deleted)) { - zip_error_set(&za->error, ZIP_ER_CHANGED, 0); - return NULL; - } - - if (zip_stat_index(srcza, srcidx, flags | ZIP_FL_UNCHANGED, &st) < 0) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - return NULL; - } - - if (flags & ZIP_FL_ENCRYPTED) { - flags |= ZIP_FL_COMPRESSED; - } - - if ((start > 0 || len > 0) && (flags & ZIP_FL_COMPRESSED)) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } - - /* overflow or past end of file */ - if ((start > 0 || len > 0) && (start + len < start || start + len > st.size)) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } - - if (len == 0) { - len = st.size - start; - } - - partial_data = len < st.size; - needs_decrypt = ((flags & ZIP_FL_ENCRYPTED) == 0) && (st.encryption_method != ZIP_EM_NONE); - needs_decompress = ((flags & ZIP_FL_COMPRESSED) == 0) && (st.comp_method != ZIP_CM_STORE); - /* when reading the whole file, check for CRC errors */ - needs_crc = ((flags & ZIP_FL_COMPRESSED) == 0 || st.comp_method == ZIP_CM_STORE) && !partial_data; - - if (needs_decrypt) { - if (password == NULL) { - password = za->default_password; - } - if (password == NULL) { - zip_error_set(&za->error, ZIP_ER_NOPASSWD, 0); - return NULL; - } - } - - if ((de = _zip_get_dirent(srcza, srcidx, flags, &za->error)) == NULL) { - return NULL; - } - _zip_file_attributes_from_dirent(&attributes, de); - - if (st.comp_size == 0) { - return zip_source_buffer_with_attributes(za, NULL, 0, 0, &attributes); - } - - if (partial_data && !needs_decrypt && !needs_decompress) { - struct zip_stat st2; - - st2.size = len; - st2.comp_size = len; - st2.comp_method = ZIP_CM_STORE; - st2.mtime = st.mtime; - st2.valid = ZIP_STAT_SIZE | ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD | ZIP_STAT_MTIME; - - if ((src = _zip_source_window_new(srcza->src, start, len, &st2, &attributes, srcza, srcidx, &za->error)) == NULL) { - return NULL; - } - } - else { - if ((src = _zip_source_window_new(srcza->src, 0, st.comp_size, &st, &attributes, srcza, srcidx, &za->error)) == NULL) { - return NULL; - } - } - - if (_zip_source_set_source_archive(src, srcza) < 0) { - zip_source_free(src); - return NULL; - } - - /* creating a layered source calls zip_keep() on the lower layer, so we free it */ - - if (needs_decrypt) { - zip_encryption_implementation enc_impl; - - if ((enc_impl = _zip_get_encryption_implementation(st.encryption_method, ZIP_CODEC_DECODE)) == NULL) { - zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); - return NULL; - } - - s2 = enc_impl(za, src, st.encryption_method, 0, password); - zip_source_free(src); - if (s2 == NULL) { - return NULL; - } - src = s2; - } - if (needs_decompress) { - s2 = zip_source_decompress(za, src, st.comp_method); - zip_source_free(src); - if (s2 == NULL) { - return NULL; - } - src = s2; - } - if (needs_crc) { - s2 = zip_source_crc(za, src, 1); - zip_source_free(src); - if (s2 == NULL) { - return NULL; - } - src = s2; - } - - if (partial_data && (needs_decrypt || needs_decompress)) { - s2 = zip_source_window(za, src, start, len); - zip_source_free(src); - if (s2 == NULL) { - return NULL; - } - src = s2; - } - - return src; -} - -static void -_zip_file_attributes_from_dirent(zip_file_attributes_t *attributes, zip_dirent_t *de) { - zip_file_attributes_init(attributes); - attributes->valid = ZIP_FILE_ATTRIBUTES_ASCII | ZIP_FILE_ATTRIBUTES_HOST_SYSTEM | ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES | ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS; - attributes->ascii = de->int_attrib & 1; - attributes->host_system = de->version_madeby >> 8; - attributes->external_file_attributes = de->ext_attrib; - attributes->general_purpose_bit_flags = de->bitflags; - attributes->general_purpose_bit_mask = ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK; -} diff --git a/ext/libzip/zip_stat.c b/ext/libzip/zip_stat.c deleted file mode 100644 index 341c6f7701..0000000000 --- a/ext/libzip/zip_stat.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - zip_stat.c -- get information about file by name - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN int -zip_stat(zip_t *za, const char *fname, zip_flags_t flags, zip_stat_t *st) { - zip_int64_t idx; - - if ((idx = zip_name_locate(za, fname, flags)) < 0) - return -1; - - return zip_stat_index(za, (zip_uint64_t)idx, flags, st); -} diff --git a/ext/libzip/zip_stat_index.c b/ext/libzip/zip_stat_index.c deleted file mode 100644 index 7799325712..0000000000 --- a/ext/libzip/zip_stat_index.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - zip_stat_index.c -- get information about file by index - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN int -zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st) { - const char *name; - zip_dirent_t *de; - - if ((de = _zip_get_dirent(za, index, flags, NULL)) == NULL) - return -1; - - if ((name = zip_get_name(za, index, flags)) == NULL) - return -1; - - - if ((flags & ZIP_FL_UNCHANGED) == 0 && ZIP_ENTRY_DATA_CHANGED(za->entry + index)) { - zip_entry_t *entry = za->entry + index; - - if (zip_source_stat(entry->source, st) < 0) { - zip_error_set(&za->error, ZIP_ER_CHANGED, 0); - return -1; - } - - if (entry->changes->changed & ZIP_DIRENT_LAST_MOD) { - st->mtime = de->last_mod; - st->valid |= ZIP_STAT_MTIME; - } - } - else { - zip_stat_init(st); - - st->crc = de->crc; - st->size = de->uncomp_size; - st->mtime = de->last_mod; - st->comp_size = de->comp_size; - st->comp_method = (zip_uint16_t)de->comp_method; - st->encryption_method = de->encryption_method; - st->valid = (de->crc_valid ? ZIP_STAT_CRC : 0) | ZIP_STAT_SIZE | ZIP_STAT_MTIME | ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD | ZIP_STAT_ENCRYPTION_METHOD; - } - - st->index = index; - st->name = name; - st->valid |= ZIP_STAT_INDEX | ZIP_STAT_NAME; - - return 0; -} diff --git a/ext/libzip/zip_stat_init.c b/ext/libzip/zip_stat_init.c deleted file mode 100644 index 6d0903d6c0..0000000000 --- a/ext/libzip/zip_stat_init.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - zip_stat_init.c -- initialize struct zip_stat. - Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include - -#include "zipint.h" - - -ZIP_EXTERN void -zip_stat_init(zip_stat_t *st) { - st->valid = 0; - st->name = NULL; - st->index = ZIP_UINT64_MAX; - st->crc = 0; - st->mtime = (time_t)-1; - st->size = 0; - st->comp_size = 0; - st->comp_method = ZIP_CM_STORE; - st->encryption_method = ZIP_EM_NONE; -} - - -int -_zip_stat_merge(zip_stat_t *dst, const zip_stat_t *src, zip_error_t *error) { - /* name is not merged, since zip_stat_t doesn't own it, and src may not be valid as long as dst */ - if (src->valid & ZIP_STAT_INDEX) { - dst->index = src->index; - } - if (src->valid & ZIP_STAT_SIZE) { - dst->size = src->size; - } - if (src->valid & ZIP_STAT_COMP_SIZE) { - dst->comp_size = src->comp_size; - } - if (src->valid & ZIP_STAT_MTIME) { - dst->mtime = src->mtime; - } - if (src->valid & ZIP_STAT_CRC) { - dst->crc = src->crc; - } - if (src->valid & ZIP_STAT_COMP_METHOD) { - dst->comp_method = src->comp_method; - } - if (src->valid & ZIP_STAT_ENCRYPTION_METHOD) { - dst->encryption_method = src->encryption_method; - } - if (src->valid & ZIP_STAT_FLAGS) { - dst->flags = src->flags; - } - dst->valid |= src->valid; - - return 0; -} diff --git a/ext/libzip/zip_strerror.c b/ext/libzip/zip_strerror.c deleted file mode 100644 index 906c7f7602..0000000000 --- a/ext/libzip/zip_strerror.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - zip_sterror.c -- get string representation of zip error - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN const char * -zip_strerror(zip_t *za) { - return zip_error_strerror(&za->error); -} diff --git a/ext/libzip/zip_string.c b/ext/libzip/zip_string.c deleted file mode 100644 index 122721d84b..0000000000 --- a/ext/libzip/zip_string.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - zip_string.c -- string handling (with encoding) - Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include -#include -#include - -#include "zipint.h" - -zip_uint32_t -_zip_string_crc32(const zip_string_t *s) { - zip_uint32_t crc; - - crc = (zip_uint32_t)crc32(0L, Z_NULL, 0); - - if (s != NULL) - crc = (zip_uint32_t)crc32(crc, s->raw, s->length); - - return crc; -} - - -int -_zip_string_equal(const zip_string_t *a, const zip_string_t *b) { - if (a == NULL || b == NULL) - return a == b; - - if (a->length != b->length) - return 0; - - /* TODO: encoding */ - - return (memcmp(a->raw, b->raw, a->length) == 0); -} - - -void -_zip_string_free(zip_string_t *s) { - if (s == NULL) - return; - - free(s->raw); - free(s->converted); - free(s); -} - - -const zip_uint8_t * -_zip_string_get(zip_string_t *string, zip_uint32_t *lenp, zip_flags_t flags, zip_error_t *error) { - static const zip_uint8_t empty[1] = ""; - - if (string == NULL) { - if (lenp) - *lenp = 0; - return empty; - } - - if ((flags & ZIP_FL_ENC_RAW) == 0) { - /* start guessing */ - if (string->encoding == ZIP_ENCODING_UNKNOWN) - _zip_guess_encoding(string, ZIP_ENCODING_UNKNOWN); - - if (((flags & ZIP_FL_ENC_STRICT) && string->encoding != ZIP_ENCODING_ASCII && string->encoding != ZIP_ENCODING_UTF8_KNOWN) || (string->encoding == ZIP_ENCODING_CP437)) { - if (string->converted == NULL) { - if ((string->converted = _zip_cp437_to_utf8(string->raw, string->length, &string->converted_length, error)) == NULL) - return NULL; - } - if (lenp) - *lenp = string->converted_length; - return string->converted; - } - } - - if (lenp) - *lenp = string->length; - return string->raw; -} - - -zip_uint16_t -_zip_string_length(const zip_string_t *s) { - if (s == NULL) - return 0; - - return s->length; -} - - -zip_string_t * -_zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags, zip_error_t *error) { - zip_string_t *s; - zip_encoding_type_t expected_encoding; - - if (length == 0) - return NULL; - - switch (flags & ZIP_FL_ENCODING_ALL) { - case ZIP_FL_ENC_GUESS: - expected_encoding = ZIP_ENCODING_UNKNOWN; - break; - case ZIP_FL_ENC_UTF_8: - expected_encoding = ZIP_ENCODING_UTF8_KNOWN; - break; - case ZIP_FL_ENC_CP437: - expected_encoding = ZIP_ENCODING_CP437; - break; - default: - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - if ((s = (zip_string_t *)malloc(sizeof(*s))) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; - } - - if ((s->raw = (zip_uint8_t *)malloc((size_t)length + 1)) == NULL) { - free(s); - return NULL; - } - - memcpy(s->raw, raw, length); - s->raw[length] = '\0'; - s->length = length; - s->encoding = ZIP_ENCODING_UNKNOWN; - s->converted = NULL; - s->converted_length = 0; - - if (expected_encoding != ZIP_ENCODING_UNKNOWN) { - if (_zip_guess_encoding(s, expected_encoding) == ZIP_ENCODING_ERROR) { - _zip_string_free(s); - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - } - - return s; -} - - -int -_zip_string_write(zip_t *za, const zip_string_t *s) { - if (s == NULL) - return 0; - - return _zip_write(za, s->raw, s->length); -} diff --git a/ext/libzip/zip_unchange.c b/ext/libzip/zip_unchange.c deleted file mode 100644 index 1a78e2c354..0000000000 --- a/ext/libzip/zip_unchange.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - zip_unchange.c -- undo changes to file in zip archive - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include - -#include "zipint.h" - - -ZIP_EXTERN int -zip_unchange(zip_t *za, zip_uint64_t idx) { - return _zip_unchange(za, idx, 0); -} - - -int -_zip_unchange(zip_t *za, zip_uint64_t idx, int allow_duplicates) { - zip_int64_t i; - const char *orig_name, *changed_name; - - if (idx >= za->nentry) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (!allow_duplicates && za->entry[idx].changes && (za->entry[idx].changes->changed & ZIP_DIRENT_FILENAME)) { - if (za->entry[idx].orig != NULL) { - if ((orig_name = _zip_get_name(za, idx, ZIP_FL_UNCHANGED, &za->error)) == NULL) { - return -1; - } - - i = _zip_name_locate(za, orig_name, 0, NULL); - if (i >= 0 && (zip_uint64_t)i != idx) { - zip_error_set(&za->error, ZIP_ER_EXISTS, 0); - return -1; - } - } - else { - orig_name = NULL; - } - - if ((changed_name = _zip_get_name(za, idx, 0, &za->error)) == NULL) { - return -1; - } - - if (orig_name) { - if (_zip_hash_add(za->names, (const zip_uint8_t *)orig_name, idx, 0, &za->error) == false) { - return -1; - } - } - if (_zip_hash_delete(za->names, (const zip_uint8_t *)changed_name, &za->error) == false) { - _zip_hash_delete(za->names, (const zip_uint8_t *)orig_name, NULL); - return -1; - } - } - - _zip_dirent_free(za->entry[idx].changes); - za->entry[idx].changes = NULL; - - _zip_unchange_data(za->entry + idx); - - return 0; -} diff --git a/ext/libzip/zip_unchange_all.c b/ext/libzip/zip_unchange_all.c deleted file mode 100644 index 2ae742f87f..0000000000 --- a/ext/libzip/zip_unchange_all.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - zip_unchange.c -- undo changes to all files in zip archive - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - - -ZIP_EXTERN int -zip_unchange_all(zip_t *za) { - int ret; - zip_uint64_t i; - - if (!_zip_hash_revert(za->names, &za->error)) { - return -1; - } - - ret = 0; - for (i = 0; i < za->nentry; i++) - ret |= _zip_unchange(za, i, 1); - - ret |= zip_unchange_archive(za); - - return ret; -} diff --git a/ext/libzip/zip_unchange_archive.c b/ext/libzip/zip_unchange_archive.c deleted file mode 100644 index bd223ef57d..0000000000 --- a/ext/libzip/zip_unchange_archive.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - zip_unchange_archive.c -- undo global changes to ZIP archive - Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include - -#include "zipint.h" - - -ZIP_EXTERN int -zip_unchange_archive(zip_t *za) { - if (za->comment_changed) { - _zip_string_free(za->comment_changes); - za->comment_changes = NULL; - za->comment_changed = 0; - } - - za->ch_flags = za->flags; - - return 0; -} diff --git a/ext/libzip/zip_unchange_data.c b/ext/libzip/zip_unchange_data.c deleted file mode 100644 index 74a429c91f..0000000000 --- a/ext/libzip/zip_unchange_data.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - zip_unchange_data.c -- undo helper function - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - -void -_zip_unchange_data(zip_entry_t *ze) { - if (ze->source) { - zip_source_free(ze->source); - ze->source = NULL; - } - - if (ze->changes != NULL && (ze->changes->changed & ZIP_DIRENT_COMP_METHOD) && ze->changes->comp_method == ZIP_CM_REPLACED_DEFAULT) { - ze->changes->changed &= ~ZIP_DIRENT_COMP_METHOD; - if (ze->changes->changed == 0) { - _zip_dirent_free(ze->changes); - ze->changes = NULL; - } - } - - ze->deleted = 0; -} diff --git a/ext/libzip/zip_utf-8.c b/ext/libzip/zip_utf-8.c deleted file mode 100644 index 099db9bf26..0000000000 --- a/ext/libzip/zip_utf-8.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - zip_utf-8.c -- UTF-8 support functions for libzip - Copyright (C) 2011-2019 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "zipint.h" - -#include - - -static const zip_uint16_t _cp437_to_unicode[256] = { - /* 0x00 - 0x0F */ - 0x0000, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, 0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C, - - /* 0x10 - 0x1F */ - 0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8, 0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC, - - /* 0x20 - 0x2F */ - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, - - /* 0x30 - 0x3F */ - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, - - /* 0x40 - 0x4F */ - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, - - /* 0x50 - 0x5F */ - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, - - /* 0x60 - 0x6F */ - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, - - /* 0x70 - 0x7F */ - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x2302, - - /* 0x80 - 0x8F */ - 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, - - /* 0x90 - 0x9F */ - 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, - - /* 0xA0 - 0xAF */ - 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, - - /* 0xB0 - 0xBF */ - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, - - /* 0xC0 - 0xCF */ - 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, - - /* 0xD0 - 0xDF */ - 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, - - /* 0xE0 - 0xEF */ - 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, - - /* 0xF0 - 0xFF */ - 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0}; - -#define UTF_8_LEN_2_MASK 0xe0 -#define UTF_8_LEN_2_MATCH 0xc0 -#define UTF_8_LEN_3_MASK 0xf0 -#define UTF_8_LEN_3_MATCH 0xe0 -#define UTF_8_LEN_4_MASK 0xf8 -#define UTF_8_LEN_4_MATCH 0xf0 -#define UTF_8_CONTINUE_MASK 0xc0 -#define UTF_8_CONTINUE_MATCH 0x80 - - -zip_encoding_type_t -_zip_guess_encoding(zip_string_t *str, zip_encoding_type_t expected_encoding) { - zip_encoding_type_t enc; - const zip_uint8_t *name; - zip_uint32_t i, j, ulen; - - if (str == NULL) - return ZIP_ENCODING_ASCII; - - name = str->raw; - - if (str->encoding != ZIP_ENCODING_UNKNOWN) - enc = str->encoding; - else { - enc = ZIP_ENCODING_ASCII; - for (i = 0; i < str->length; i++) { - if ((name[i] > 31 && name[i] < 128) || name[i] == '\r' || name[i] == '\n' || name[i] == '\t') - continue; - - enc = ZIP_ENCODING_UTF8_GUESSED; - if ((name[i] & UTF_8_LEN_2_MASK) == UTF_8_LEN_2_MATCH) - ulen = 1; - else if ((name[i] & UTF_8_LEN_3_MASK) == UTF_8_LEN_3_MATCH) - ulen = 2; - else if ((name[i] & UTF_8_LEN_4_MASK) == UTF_8_LEN_4_MATCH) - ulen = 3; - else { - enc = ZIP_ENCODING_CP437; - break; - } - - if (i + ulen >= str->length) { - enc = ZIP_ENCODING_CP437; - break; - } - - for (j = 1; j <= ulen; j++) { - if ((name[i + j] & UTF_8_CONTINUE_MASK) != UTF_8_CONTINUE_MATCH) { - enc = ZIP_ENCODING_CP437; - goto done; - } - } - i += ulen; - } - } - -done: - str->encoding = enc; - - if (expected_encoding != ZIP_ENCODING_UNKNOWN) { - if (expected_encoding == ZIP_ENCODING_UTF8_KNOWN && enc == ZIP_ENCODING_UTF8_GUESSED) - str->encoding = enc = ZIP_ENCODING_UTF8_KNOWN; - - if (expected_encoding != enc && enc != ZIP_ENCODING_ASCII) - return ZIP_ENCODING_ERROR; - } - - return enc; -} - - -static zip_uint32_t -_zip_unicode_to_utf8_len(zip_uint32_t codepoint) { - if (codepoint < 0x0080) - return 1; - if (codepoint < 0x0800) - return 2; - if (codepoint < 0x10000) - return 3; - return 4; -} - - -static zip_uint32_t -_zip_unicode_to_utf8(zip_uint32_t codepoint, zip_uint8_t *buf) { - if (codepoint < 0x0080) { - buf[0] = codepoint & 0xff; - return 1; - } - if (codepoint < 0x0800) { - buf[0] = (zip_uint8_t)(UTF_8_LEN_2_MATCH | ((codepoint >> 6) & 0x1f)); - buf[1] = (zip_uint8_t)(UTF_8_CONTINUE_MATCH | (codepoint & 0x3f)); - return 2; - } - if (codepoint < 0x10000) { - buf[0] = (zip_uint8_t)(UTF_8_LEN_3_MATCH | ((codepoint >> 12) & 0x0f)); - buf[1] = (zip_uint8_t)(UTF_8_CONTINUE_MATCH | ((codepoint >> 6) & 0x3f)); - buf[2] = (zip_uint8_t)(UTF_8_CONTINUE_MATCH | (codepoint & 0x3f)); - return 3; - } - buf[0] = (zip_uint8_t)(UTF_8_LEN_4_MATCH | ((codepoint >> 18) & 0x07)); - buf[1] = (zip_uint8_t)(UTF_8_CONTINUE_MATCH | ((codepoint >> 12) & 0x3f)); - buf[2] = (zip_uint8_t)(UTF_8_CONTINUE_MATCH | ((codepoint >> 6) & 0x3f)); - buf[3] = (zip_uint8_t)(UTF_8_CONTINUE_MATCH | (codepoint & 0x3f)); - return 4; -} - - -zip_uint8_t * -_zip_cp437_to_utf8(const zip_uint8_t *const _cp437buf, zip_uint32_t len, zip_uint32_t *utf8_lenp, zip_error_t *error) { - zip_uint8_t *cp437buf = (zip_uint8_t *)_cp437buf; - zip_uint8_t *utf8buf; - zip_uint32_t buflen, i, offset; - - if (len == 0) { - if (utf8_lenp) - *utf8_lenp = 0; - return NULL; - } - - buflen = 1; - for (i = 0; i < len; i++) - buflen += _zip_unicode_to_utf8_len(_cp437_to_unicode[cp437buf[i]]); - - if ((utf8buf = (zip_uint8_t *)malloc(buflen)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; - } - - offset = 0; - for (i = 0; i < len; i++) - offset += _zip_unicode_to_utf8(_cp437_to_unicode[cp437buf[i]], utf8buf + offset); - - utf8buf[buflen - 1] = 0; - if (utf8_lenp) - *utf8_lenp = buflen - 1; - return utf8buf; -} diff --git a/ext/libzip/zipconf.h b/ext/libzip/zipconf.h deleted file mode 100644 index e07637e06f..0000000000 --- a/ext/libzip/zipconf.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef _HAD_ZIPCONF_H -#define _HAD_ZIPCONF_H - -/* - zipconf.h -- platform specific include file - - This file was generated automatically by CMake - based on ../cmake-zipconf.h.in. - */ - -#define LIBZIP_VERSION "1.7.3" -#define LIBZIP_VERSION_MAJOR 1 -#define LIBZIP_VERSION_MINOR 7 -#define LIBZIP_VERSION_MICRO 3 - -#define ZIP_STATIC - -#define _Nullable -#define _Nonnull - -#include - -typedef int8_t zip_int8_t; -typedef uint8_t zip_uint8_t; -typedef int16_t zip_int16_t; -typedef uint16_t zip_uint16_t; -typedef int32_t zip_int32_t; -typedef uint32_t zip_uint32_t; -typedef int64_t zip_int64_t; -typedef uint64_t zip_uint64_t; - -#define ZIP_INT8_MIN (-ZIP_INT8_MAX-1) -#define ZIP_INT8_MAX 0x7f -#define ZIP_UINT8_MAX 0xff - -#define ZIP_INT16_MIN (-ZIP_INT16_MAX-1) -#define ZIP_INT16_MAX 0x7fff -#define ZIP_UINT16_MAX 0xffff - -#define ZIP_INT32_MIN (-ZIP_INT32_MAX-1L) -#define ZIP_INT32_MAX 0x7fffffffL -#define ZIP_UINT32_MAX 0xffffffffLU - -#define ZIP_INT64_MIN (-ZIP_INT64_MAX-1LL) -#define ZIP_INT64_MAX 0x7fffffffffffffffLL -#define ZIP_UINT64_MAX 0xffffffffffffffffULL - -#endif /* zipconf.h */ diff --git a/ext/libzip/zipint.h b/ext/libzip/zipint.h deleted file mode 100644 index 99c1806133..0000000000 --- a/ext/libzip/zipint.h +++ /dev/null @@ -1,601 +0,0 @@ -#ifndef _HAD_ZIPINT_H -#define _HAD_ZIPINT_H - -/* - zipint.h -- internal declarations. - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "config.h" -#include "compat.h" - -#ifdef ZIP_ALLOCATE_BUFFER -#include -#endif - -#ifndef _ZIP_COMPILING_DEPRECATED -#define ZIP_DISABLE_DEPRECATED -#endif - -#include "zip.h" - -#define CENTRAL_MAGIC "PK\1\2" -#define LOCAL_MAGIC "PK\3\4" -#define EOCD_MAGIC "PK\5\6" -#define DATADES_MAGIC "PK\7\10" -#define EOCD64LOC_MAGIC "PK\6\7" -#define EOCD64_MAGIC "PK\6\6" -#define CDENTRYSIZE 46u -#define LENTRYSIZE 30 -#define MAXCOMLEN 65536 -#define MAXEXTLEN 65536 -#define EOCDLEN 22 -#define EOCD64LOCLEN 20 -#define EOCD64LEN 56 -#define CDBUFSIZE (MAXCOMLEN + EOCDLEN + EOCD64LOCLEN) -#define BUFSIZE 8192 -#define EFZIP64SIZE 28 -#define EF_WINZIP_AES_SIZE 7 -#define MAX_DATA_DESCRIPTOR_LENGTH 24 - -#define ZIP_CRYPTO_PKWARE_HEADERLEN 12 - -#define ZIP_CM_REPLACED_DEFAULT (-2) -#define ZIP_CM_WINZIP_AES 99 /* Winzip AES encrypted */ - -#define WINZIP_AES_PASSWORD_VERIFY_LENGTH 2 -#define WINZIP_AES_MAX_HEADER_LENGTH (16 + WINZIP_AES_PASSWORD_VERIFY_LENGTH) -#define AES_BLOCK_SIZE 16 -#define HMAC_LENGTH 10 -#define SHA1_LENGTH 20 -#define SALT_LENGTH(method) ((method) == ZIP_EM_AES_128 ? 8 : ((method) == ZIP_EM_AES_192 ? 12 : 16)) - -#define ZIP_CM_IS_DEFAULT(x) ((x) == ZIP_CM_DEFAULT || (x) == ZIP_CM_REPLACED_DEFAULT) -#define ZIP_CM_ACTUAL(x) ((zip_uint16_t)(ZIP_CM_IS_DEFAULT(x) ? ZIP_CM_DEFLATE : (x))) - -#define ZIP_EF_UTF_8_COMMENT 0x6375 -#define ZIP_EF_UTF_8_NAME 0x7075 -#define ZIP_EF_WINZIP_AES 0x9901 -#define ZIP_EF_ZIP64 0x0001 - -#define ZIP_EF_IS_INTERNAL(id) ((id) == ZIP_EF_UTF_8_COMMENT || (id) == ZIP_EF_UTF_8_NAME || (id) == ZIP_EF_WINZIP_AES || (id) == ZIP_EF_ZIP64) - -/* according to unzip-6.0's zipinfo.c, this corresponds to a regular file with rw permissions for everyone */ -#define ZIP_EXT_ATTRIB_DEFAULT (0100666u << 16) -/* according to unzip-6.0's zipinfo.c, this corresponds to a directory with rwx permissions for everyone */ -#define ZIP_EXT_ATTRIB_DEFAULT_DIR (0040777u << 16) - -#define ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK 0x0836 - -#define ZIP_MAX(a, b) ((a) > (b) ? (a) : (b)) -#define ZIP_MIN(a, b) ((a) < (b) ? (a) : (b)) - -/* This section contains API that won't materialize like this. It's - placed in the internal section, pending cleanup. */ - -/* flags for compression and encryption sources */ - -#define ZIP_CODEC_DECODE 0 /* decompress/decrypt (encode flag not set) */ -#define ZIP_CODEC_ENCODE 1 /* compress/encrypt */ - -typedef zip_source_t *(*zip_encryption_implementation)(zip_t *, zip_source_t *, zip_uint16_t, int, const char *); - -zip_encryption_implementation _zip_get_encryption_implementation(zip_uint16_t method, int operation); - -/* clang-format off */ -enum zip_compression_status { - ZIP_COMPRESSION_OK, - ZIP_COMPRESSION_END, - ZIP_COMPRESSION_ERROR, - ZIP_COMPRESSION_NEED_DATA -}; -/* clang-format on */ -typedef enum zip_compression_status zip_compression_status_t; - -struct zip_compression_algorithm { - /* called once to create new context */ - void *(*allocate)(zip_uint16_t method, int compression_flags, zip_error_t *error); - /* called once to free context */ - void (*deallocate)(void *ctx); - - /* get compression specific general purpose bitflags */ - zip_uint16_t (*general_purpose_bit_flags)(void *ctx); - /* minimum version needed when using this algorithm */ - zip_uint8_t version_needed; - - /* start processing */ - bool (*start)(void *ctx); - /* stop processing */ - bool (*end)(void *ctx); - - /* provide new input data, remains valid until next call to input or end */ - bool (*input)(void *ctx, zip_uint8_t *data, zip_uint64_t length); - - /* all input data has been provided */ - void (*end_of_input)(void *ctx); - - /* process input data, writing to data, which has room for length bytes, update length to number of bytes written */ - zip_compression_status_t (*process)(void *ctx, zip_uint8_t *data, zip_uint64_t *length); -}; -typedef struct zip_compression_algorithm zip_compression_algorithm_t; - -extern zip_compression_algorithm_t zip_algorithm_bzip2_compress; -extern zip_compression_algorithm_t zip_algorithm_bzip2_decompress; -extern zip_compression_algorithm_t zip_algorithm_deflate_compress; -extern zip_compression_algorithm_t zip_algorithm_deflate_decompress; -extern zip_compression_algorithm_t zip_algorithm_xz_compress; -extern zip_compression_algorithm_t zip_algorithm_xz_decompress; - - -/* This API is not final yet, but we need it internally, so it's private for now. */ - -const zip_uint8_t *zip_get_extra_field_by_id(zip_t *, int, int, zip_uint16_t, int, zip_uint16_t *); - -/* This section contains API that is of limited use until support for - user-supplied compression/encryption implementation is finished. - Thus we will keep it private for now. */ - -typedef zip_int64_t (*zip_source_layered_callback)(zip_source_t *, void *, void *, zip_uint64_t, enum zip_source_cmd); -zip_source_t *zip_source_compress(zip_t *za, zip_source_t *src, zip_int32_t cm, int compression_flags); -zip_source_t *zip_source_crc(zip_t *, zip_source_t *, int); -zip_source_t *zip_source_decompress(zip_t *za, zip_source_t *src, zip_int32_t cm); -zip_source_t *zip_source_layered(zip_t *, zip_source_t *, zip_source_layered_callback, void *); -zip_source_t *zip_source_layered_create(zip_source_t *src, zip_source_layered_callback cb, void *ud, zip_error_t *error); -zip_source_t *zip_source_pkware_decode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *); -zip_source_t *zip_source_pkware_encode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *); -int zip_source_remove(zip_source_t *); -zip_int64_t zip_source_supports(zip_source_t *src); -zip_source_t *zip_source_window(zip_t *, zip_source_t *, zip_uint64_t, zip_uint64_t); -zip_source_t *zip_source_winzip_aes_decode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *); -zip_source_t *zip_source_winzip_aes_encode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *); -zip_source_t *zip_source_buffer_with_attributes(zip_t *za, const void *data, zip_uint64_t len, int freep, zip_file_attributes_t *attributes); - -/* error source for layered sources */ - -enum zip_les { ZIP_LES_NONE, ZIP_LES_UPPER, ZIP_LES_LOWER, ZIP_LES_INVAL }; - -/* directory entry: general purpose bit flags */ - -#define ZIP_GPBF_ENCRYPTED 0x0001u /* is encrypted */ -#define ZIP_GPBF_DATA_DESCRIPTOR 0x0008u /* crc/size after file data */ -#define ZIP_GPBF_STRONG_ENCRYPTION 0x0040u /* uses strong encryption */ -#define ZIP_GPBF_ENCODING_UTF_8 0x0800u /* file name encoding is UTF-8 */ - - -/* extra fields */ -#define ZIP_EF_LOCAL ZIP_FL_LOCAL /* include in local header */ -#define ZIP_EF_CENTRAL ZIP_FL_CENTRAL /* include in central directory */ -#define ZIP_EF_BOTH (ZIP_EF_LOCAL | ZIP_EF_CENTRAL) /* include in both */ - -#define ZIP_FL_FORCE_ZIP64 1024 /* force zip64 extra field (_zip_dirent_write) */ - -#define ZIP_FL_ENCODING_ALL (ZIP_FL_ENC_GUESS | ZIP_FL_ENC_CP437 | ZIP_FL_ENC_UTF_8) - - -/* encoding type */ -enum zip_encoding_type { - ZIP_ENCODING_UNKNOWN, /* not yet analyzed */ - ZIP_ENCODING_ASCII, /* plain ASCII */ - ZIP_ENCODING_UTF8_KNOWN, /* is UTF-8 */ - ZIP_ENCODING_UTF8_GUESSED, /* possibly UTF-8 */ - ZIP_ENCODING_CP437, /* Code Page 437 */ - ZIP_ENCODING_ERROR /* should be UTF-8 but isn't */ -}; - -typedef enum zip_encoding_type zip_encoding_type_t; - -struct zip_hash; -struct zip_progress; - -typedef struct zip_cdir zip_cdir_t; -typedef struct zip_dirent zip_dirent_t; -typedef struct zip_entry zip_entry_t; -typedef struct zip_extra_field zip_extra_field_t; -typedef struct zip_string zip_string_t; -typedef struct zip_buffer zip_buffer_t; -typedef struct zip_hash zip_hash_t; -typedef struct zip_progress zip_progress_t; - -/* zip archive, part of API */ - -struct zip { - zip_source_t *src; /* data source for archive */ - unsigned int open_flags; /* flags passed to zip_open */ - zip_error_t error; /* error information */ - - unsigned int flags; /* archive global flags */ - unsigned int ch_flags; /* changed archive global flags */ - - char *default_password; /* password used when no other supplied */ - - zip_string_t *comment_orig; /* archive comment */ - zip_string_t *comment_changes; /* changed archive comment */ - bool comment_changed; /* whether archive comment was changed */ - - zip_uint64_t nentry; /* number of entries */ - zip_uint64_t nentry_alloc; /* number of entries allocated */ - zip_entry_t *entry; /* entries */ - - unsigned int nopen_source; /* number of open sources using archive */ - unsigned int nopen_source_alloc; /* number of sources allocated */ - zip_source_t **open_source; /* open sources using archive */ - - zip_hash_t *names; /* hash table for name lookup */ - - zip_progress_t *progress; /* progress callback for zip_close() */ -}; - -/* file in zip archive, part of API */ - -struct zip_file { - zip_t *za; /* zip archive containing this file */ - zip_error_t error; /* error information */ - bool eof; - zip_source_t *src; /* data source */ -}; - -/* zip archive directory entry (central or local) */ - -#define ZIP_DIRENT_COMP_METHOD 0x0001u -#define ZIP_DIRENT_FILENAME 0x0002u -#define ZIP_DIRENT_COMMENT 0x0004u -#define ZIP_DIRENT_EXTRA_FIELD 0x0008u -#define ZIP_DIRENT_ATTRIBUTES 0x0010u -#define ZIP_DIRENT_LAST_MOD 0x0020u -#define ZIP_DIRENT_ENCRYPTION_METHOD 0x0040u -#define ZIP_DIRENT_PASSWORD 0x0080u -#define ZIP_DIRENT_ALL ZIP_UINT32_MAX - -struct zip_dirent { - zip_uint32_t changed; - bool local_extra_fields_read; /* whether we already read in local header extra fields */ - bool cloned; /* whether this instance is cloned, and thus shares non-changed strings */ - - bool crc_valid; /* if CRC is valid (sometimes not for encrypted archives) */ - - zip_uint16_t version_madeby; /* (c) version of creator */ - zip_uint16_t version_needed; /* (cl) version needed to extract */ - zip_uint16_t bitflags; /* (cl) general purpose bit flag */ - zip_int32_t comp_method; /* (cl) compression method used (uint16 and ZIP_CM_DEFAULT (-1)) */ - time_t last_mod; /* (cl) time of last modification */ - zip_uint32_t crc; /* (cl) CRC-32 of uncompressed data */ - zip_uint64_t comp_size; /* (cl) size of compressed data */ - zip_uint64_t uncomp_size; /* (cl) size of uncompressed data */ - zip_string_t *filename; /* (cl) file name (NUL-terminated) */ - zip_extra_field_t *extra_fields; /* (cl) extra fields, parsed */ - zip_string_t *comment; /* (c) file comment */ - zip_uint32_t disk_number; /* (c) disk number start */ - zip_uint16_t int_attrib; /* (c) internal file attributes */ - zip_uint32_t ext_attrib; /* (c) external file attributes */ - zip_uint64_t offset; /* (c) offset of local header */ - - zip_uint16_t compression_level; /* level of compression to use (never valid in orig) */ - zip_uint16_t encryption_method; /* encryption method, computed from other fields */ - char *password; /* file specific encryption password */ -}; - -/* zip archive central directory */ - -struct zip_cdir { - zip_entry_t *entry; /* directory entries */ - zip_uint64_t nentry; /* number of entries */ - zip_uint64_t nentry_alloc; /* number of entries allocated */ - - zip_uint64_t size; /* size of central directory */ - zip_uint64_t offset; /* offset of central directory in file */ - zip_string_t *comment; /* zip archive comment */ - bool is_zip64; /* central directory in zip64 format */ -}; - -struct zip_extra_field { - zip_extra_field_t *next; - zip_flags_t flags; /* in local/central header */ - zip_uint16_t id; /* header id */ - zip_uint16_t size; /* data size */ - zip_uint8_t *data; -}; - -enum zip_source_write_state { - ZIP_SOURCE_WRITE_CLOSED, /* write is not in progress */ - ZIP_SOURCE_WRITE_OPEN, /* write is in progress */ - ZIP_SOURCE_WRITE_FAILED, /* commit failed, only rollback allowed */ - ZIP_SOURCE_WRITE_REMOVED /* file was removed */ -}; -typedef enum zip_source_write_state zip_source_write_state_t; - -struct zip_source { - zip_source_t *src; - union { - zip_source_callback f; - zip_source_layered_callback l; - } cb; - void *ud; - zip_error_t error; - zip_int64_t supports; /* supported commands */ - unsigned int open_count; /* number of times source was opened (directly or as lower layer) */ - zip_source_write_state_t write_state; /* whether source is open for writing */ - bool source_closed; /* set if source archive is closed */ - zip_t *source_archive; /* zip archive we're reading from, NULL if not from archive */ - unsigned int refcount; - bool eof; /* EOF reached */ - bool had_read_error; /* a previous ZIP_SOURCE_READ reported an error */ -}; - -#define ZIP_SOURCE_IS_OPEN_READING(src) ((src)->open_count > 0) -#define ZIP_SOURCE_IS_OPEN_WRITING(src) ((src)->write_state == ZIP_SOURCE_WRITE_OPEN) -#define ZIP_SOURCE_IS_LAYERED(src) ((src)->src != NULL) - -/* entry in zip archive directory */ - -struct zip_entry { - zip_dirent_t *orig; - zip_dirent_t *changes; - zip_source_t *source; - bool deleted; -}; - - -/* file or archive comment, or filename */ - -struct zip_string { - zip_uint8_t *raw; /* raw string */ - zip_uint16_t length; /* length of raw string */ - enum zip_encoding_type encoding; /* autorecognized encoding */ - zip_uint8_t *converted; /* autoconverted string */ - zip_uint32_t converted_length; /* length of converted */ -}; - - -/* byte array */ - -/* For performance, we usually keep 8k byte arrays on the stack. - However, there are (embedded) systems with a stack size of 12k; - for those, use malloc()/free() */ - -#ifdef ZIP_ALLOCATE_BUFFER -#define DEFINE_BYTE_ARRAY(buf, size) zip_uint8_t *buf -#define byte_array_init(buf, size) (((buf) = (zip_uint8_t *)malloc(size)) != NULL) -#define byte_array_fini(buf) (free(buf)) -#else -#define DEFINE_BYTE_ARRAY(buf, size) zip_uint8_t buf[size] -#define byte_array_init(buf, size) (1) -#define byte_array_fini(buf) ((void)0) -#endif - - -/* bounds checked access to memory buffer */ - -struct zip_buffer { - bool ok; - bool free_data; - - zip_uint8_t *data; - zip_uint64_t size; - zip_uint64_t offset; -}; - -/* which files to write in which order */ - -struct zip_filelist { - zip_uint64_t idx; - /* TODO const char *name; */ -}; - -typedef struct zip_filelist zip_filelist_t; - -struct _zip_winzip_aes; -typedef struct _zip_winzip_aes zip_winzip_aes_t; - -struct _zip_pkware_keys { - zip_uint32_t key[3]; -}; -typedef struct _zip_pkware_keys zip_pkware_keys_t; - -extern const char *const _zip_err_str[]; -extern const int _zip_nerr_str; -extern const int _zip_err_type[]; - -#define ZIP_MAX(a, b) ((a) > (b) ? (a) : (b)) -#define ZIP_MIN(a, b) ((a) < (b) ? (a) : (b)) - -#define ZIP_ENTRY_CHANGED(e, f) ((e)->changes && ((e)->changes->changed & (f))) -#define ZIP_ENTRY_DATA_CHANGED(x) ((x)->source != NULL) -#define ZIP_ENTRY_HAS_CHANGES(e) (ZIP_ENTRY_DATA_CHANGED(e) || (e)->deleted || ZIP_ENTRY_CHANGED((e), ZIP_DIRENT_ALL)) - -#define ZIP_IS_RDONLY(za) ((za)->ch_flags & ZIP_AFL_RDONLY) - - -#ifdef HAVE_EXPLICIT_MEMSET -#define _zip_crypto_clear(b, l) explicit_memset((b), 0, (l)) -#else -#ifdef HAVE_EXPLICIT_BZERO -#define _zip_crypto_clear(b, l) explicit_bzero((b), (l)) -#else -#include -#define _zip_crypto_clear(b, l) memset((b), 0, (l)) -#endif -#endif - - -zip_int64_t _zip_add_entry(zip_t *); - -zip_uint8_t *_zip_buffer_data(zip_buffer_t *buffer); -bool _zip_buffer_eof(zip_buffer_t *buffer); -void _zip_buffer_free(zip_buffer_t *buffer); -zip_uint8_t *_zip_buffer_get(zip_buffer_t *buffer, zip_uint64_t length); -zip_uint16_t _zip_buffer_get_16(zip_buffer_t *buffer); -zip_uint32_t _zip_buffer_get_32(zip_buffer_t *buffer); -zip_uint64_t _zip_buffer_get_64(zip_buffer_t *buffer); -zip_uint8_t _zip_buffer_get_8(zip_buffer_t *buffer); -zip_uint64_t _zip_buffer_left(zip_buffer_t *buffer); -zip_buffer_t *_zip_buffer_new(zip_uint8_t *data, zip_uint64_t size); -zip_buffer_t *_zip_buffer_new_from_source(zip_source_t *src, zip_uint64_t size, zip_uint8_t *buf, zip_error_t *error); -zip_uint64_t _zip_buffer_offset(zip_buffer_t *buffer); -bool _zip_buffer_ok(zip_buffer_t *buffer); -zip_uint8_t *_zip_buffer_peek(zip_buffer_t *buffer, zip_uint64_t length); -int _zip_buffer_put(zip_buffer_t *buffer, const void *src, size_t length); -int _zip_buffer_put_16(zip_buffer_t *buffer, zip_uint16_t i); -int _zip_buffer_put_32(zip_buffer_t *buffer, zip_uint32_t i); -int _zip_buffer_put_64(zip_buffer_t *buffer, zip_uint64_t i); -int _zip_buffer_put_8(zip_buffer_t *buffer, zip_uint8_t i); -zip_uint64_t _zip_buffer_read(zip_buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length); -int _zip_buffer_skip(zip_buffer_t *buffer, zip_uint64_t length); -int _zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset); -zip_uint64_t _zip_buffer_size(zip_buffer_t *buffer); - -void _zip_cdir_free(zip_cdir_t *); -bool _zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *error); -zip_cdir_t *_zip_cdir_new(zip_uint64_t, zip_error_t *); -zip_int64_t _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors); -time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t); -void _zip_deregister_source(zip_t *za, zip_source_t *src); - -void _zip_dirent_apply_attributes(zip_dirent_t *, zip_file_attributes_t *, bool, zip_uint32_t); -zip_dirent_t *_zip_dirent_clone(const zip_dirent_t *); -void _zip_dirent_free(zip_dirent_t *); -void _zip_dirent_finalize(zip_dirent_t *); -void _zip_dirent_init(zip_dirent_t *); -bool _zip_dirent_needs_zip64(const zip_dirent_t *, zip_flags_t); -zip_dirent_t *_zip_dirent_new(void); -zip_int64_t _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_error_t *error); -void _zip_dirent_set_version_needed(zip_dirent_t *de, bool force_zip64); -zip_int32_t _zip_dirent_size(zip_source_t *src, zip_uint16_t, zip_error_t *); -int _zip_dirent_write(zip_t *za, zip_dirent_t *dirent, zip_flags_t flags); - -zip_extra_field_t *_zip_ef_clone(const zip_extra_field_t *, zip_error_t *); -zip_extra_field_t *_zip_ef_delete_by_id(zip_extra_field_t *, zip_uint16_t, zip_uint16_t, zip_flags_t); -void _zip_ef_free(zip_extra_field_t *); -const zip_uint8_t *_zip_ef_get_by_id(const zip_extra_field_t *, zip_uint16_t *, zip_uint16_t, zip_uint16_t, zip_flags_t, zip_error_t *); -zip_extra_field_t *_zip_ef_merge(zip_extra_field_t *, zip_extra_field_t *); -zip_extra_field_t *_zip_ef_new(zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_flags_t); -bool _zip_ef_parse(const zip_uint8_t *, zip_uint16_t, zip_flags_t, zip_extra_field_t **, zip_error_t *); -zip_extra_field_t *_zip_ef_remove_internal(zip_extra_field_t *); -zip_uint16_t _zip_ef_size(const zip_extra_field_t *, zip_flags_t); -int _zip_ef_write(zip_t *za, const zip_extra_field_t *ef, zip_flags_t flags); - -void _zip_entry_finalize(zip_entry_t *); -void _zip_entry_init(zip_entry_t *); - -void _zip_error_clear(zip_error_t *); -void _zip_error_get(const zip_error_t *, int *, int *); - -void _zip_error_copy(zip_error_t *dst, const zip_error_t *src); -void _zip_error_set_from_source(zip_error_t *, zip_source_t *); - -const zip_uint8_t *_zip_extract_extra_field_by_id(zip_error_t *, zip_uint16_t, int, const zip_uint8_t *, zip_uint16_t, zip_uint16_t *); - -int _zip_file_extra_field_prepare_for_change(zip_t *, zip_uint64_t); -int _zip_file_fillbuf(void *, size_t, zip_file_t *); -zip_uint64_t _zip_file_get_end(const zip_t *za, zip_uint64_t index, zip_error_t *error); -zip_uint64_t _zip_file_get_offset(const zip_t *, zip_uint64_t, zip_error_t *); - -zip_dirent_t *_zip_get_dirent(zip_t *, zip_uint64_t, zip_flags_t, zip_error_t *); - -enum zip_encoding_type _zip_guess_encoding(zip_string_t *, enum zip_encoding_type); -zip_uint8_t *_zip_cp437_to_utf8(const zip_uint8_t *const, zip_uint32_t, zip_uint32_t *, zip_error_t *); - -bool _zip_hash_add(zip_hash_t *hash, const zip_uint8_t *name, zip_uint64_t index, zip_flags_t flags, zip_error_t *error); -bool _zip_hash_delete(zip_hash_t *hash, const zip_uint8_t *key, zip_error_t *error); -void _zip_hash_free(zip_hash_t *hash); -zip_int64_t _zip_hash_lookup(zip_hash_t *hash, const zip_uint8_t *name, zip_flags_t flags, zip_error_t *error); -zip_hash_t *_zip_hash_new(zip_error_t *error); -bool _zip_hash_reserve_capacity(zip_hash_t *hash, zip_uint64_t capacity, zip_error_t *error); -bool _zip_hash_revert(zip_hash_t *hash, zip_error_t *error); - -int _zip_mkstempm(char *path, int mode); - -zip_t *_zip_open(zip_source_t *, unsigned int, zip_error_t *); - -void _zip_progress_end(zip_progress_t *progress); -void _zip_progress_free(zip_progress_t *progress); -int _zip_progress_start(zip_progress_t *progress); -int _zip_progress_subrange(zip_progress_t *progress, double start, double end); -int _zip_progress_update(zip_progress_t *progress, double value); - -/* this symbol is extern so it can be overridden for regression testing */ -ZIP_EXTERN bool zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length); -zip_uint32_t zip_random_uint32(void); - -int _zip_read(zip_source_t *src, zip_uint8_t *data, zip_uint64_t length, zip_error_t *error); -int _zip_read_at_offset(zip_source_t *src, zip_uint64_t offset, unsigned char *b, size_t length, zip_error_t *error); -zip_uint8_t *_zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp, zip_error_t *error); -int _zip_read_local_ef(zip_t *, zip_uint64_t); -zip_string_t *_zip_read_string(zip_buffer_t *buffer, zip_source_t *src, zip_uint16_t length, bool nulp, zip_error_t *error); -int _zip_register_source(zip_t *za, zip_source_t *src); - -void _zip_set_open_error(int *zep, const zip_error_t *err, int ze); - -bool zip_source_accept_empty(zip_source_t *src); -zip_int64_t _zip_source_call(zip_source_t *src, void *data, zip_uint64_t length, zip_source_cmd_t command); -bool _zip_source_eof(zip_source_t *); -zip_source_t *_zip_source_file_or_p(const char *, FILE *, zip_uint64_t, zip_int64_t, const zip_stat_t *, zip_error_t *error); -bool _zip_source_had_error(zip_source_t *); -void _zip_source_invalidate(zip_source_t *src); -zip_source_t *_zip_source_new(zip_error_t *error); -int _zip_source_set_source_archive(zip_source_t *, zip_t *); -zip_source_t *_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t length, zip_stat_t *st, zip_file_attributes_t *attributes, zip_t *source_archive, zip_uint64_t source_index, zip_error_t *error); -zip_source_t *_zip_source_zip_new(zip_t *, zip_t *, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_uint64_t, const char *); - -int _zip_stat_merge(zip_stat_t *dst, const zip_stat_t *src, zip_error_t *error); -int _zip_string_equal(const zip_string_t *, const zip_string_t *); -void _zip_string_free(zip_string_t *); -zip_uint32_t _zip_string_crc32(const zip_string_t *); -const zip_uint8_t *_zip_string_get(zip_string_t *, zip_uint32_t *, zip_flags_t, zip_error_t *); -zip_uint16_t _zip_string_length(const zip_string_t *); -zip_string_t *_zip_string_new(const zip_uint8_t *, zip_uint16_t, zip_flags_t, zip_error_t *); -int _zip_string_write(zip_t *za, const zip_string_t *string); -bool _zip_winzip_aes_decrypt(zip_winzip_aes_t *ctx, zip_uint8_t *data, zip_uint64_t length); -bool _zip_winzip_aes_encrypt(zip_winzip_aes_t *ctx, zip_uint8_t *data, zip_uint64_t length); -bool _zip_winzip_aes_finish(zip_winzip_aes_t *ctx, zip_uint8_t *hmac); -void _zip_winzip_aes_free(zip_winzip_aes_t *ctx); -zip_winzip_aes_t *_zip_winzip_aes_new(const zip_uint8_t *password, zip_uint64_t password_length, const zip_uint8_t *salt, zip_uint16_t key_size, zip_uint8_t *password_verify, zip_error_t *error); - -void _zip_pkware_encrypt(zip_pkware_keys_t *keys, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len); -void _zip_pkware_decrypt(zip_pkware_keys_t *keys, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len); -zip_pkware_keys_t *_zip_pkware_keys_new(zip_error_t *error); -void _zip_pkware_keys_free(zip_pkware_keys_t *keys); -void _zip_pkware_keys_reset(zip_pkware_keys_t *keys); - -int _zip_changed(const zip_t *, zip_uint64_t *); -const char *_zip_get_name(zip_t *, zip_uint64_t, zip_flags_t, zip_error_t *); -int _zip_local_header_read(zip_t *, int); -void *_zip_memdup(const void *, size_t, zip_error_t *); -zip_int64_t _zip_name_locate(zip_t *, const char *, zip_flags_t, zip_error_t *); -zip_t *_zip_new(zip_error_t *); - -zip_int64_t _zip_file_replace(zip_t *, zip_uint64_t, const char *, zip_source_t *, zip_flags_t); -int _zip_set_name(zip_t *, zip_uint64_t, const char *, zip_flags_t); -void _zip_u2d_time(time_t, zip_uint16_t *, zip_uint16_t *); -int _zip_unchange(zip_t *, zip_uint64_t, int); -void _zip_unchange_data(zip_entry_t *); -int _zip_write(zip_t *za, const void *data, zip_uint64_t length); - -#endif /* zipint.h */ diff --git a/ext/libzstd.vcxproj b/ext/libzstd.vcxproj deleted file mode 100644 index a437886731..0000000000 --- a/ext/libzstd.vcxproj +++ /dev/null @@ -1,341 +0,0 @@ - - - - - Debug - ARM64 - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850} - Win32Proj - libzstd - libzstd_static - Unicode - StaticLibrary - $(SolutionDir)..\ext\zstd\bin\$(Platform)_$(Configuration)\ - $(SolutionDir)..\ext\zstd\bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ - 10.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - $(DefaultPlatformToolset) - - - true - $(DefaultPlatformToolset) - - - true - $(DefaultPlatformToolset) - - - false - true - $(DefaultPlatformToolset) - - - false - true - $(DefaultPlatformToolset) - - - false - true - $(DefaultPlatformToolset) - - - - - - - - - - - - - - - - - - - true - $(IncludePath);$(SolutionDir)..\ext\zstd\lib;$(SolutionDir)..\ext\zstd\programs\legacy;$(SolutionDir)..\ext\zstd\lib\legacy;$(SolutionDir)..\ext\zstd\lib\common;$(SolutionDir)..\ext\zstd\lib\dictBuilder;$(UniversalCRT_IncludePath); - false - - - true - $(IncludePath);$(SolutionDir)..\ext\zstd\lib;$(SolutionDir)..\ext\zstd\programs\legacy;$(SolutionDir)..\ext\zstd\lib\legacy;$(SolutionDir)..\ext\zstd\lib\common;$(SolutionDir)..\ext\zstd\lib\dictBuilder;$(UniversalCRT_IncludePath); - false - - - false - $(IncludePath);$(SolutionDir)..\ext\zstd\lib;$(SolutionDir)..\ext\zstd\programs\legacy;$(SolutionDir)..\ext\zstd\lib\legacy;$(SolutionDir)..\ext\zstd\lib\common;$(SolutionDir)..\ext\zstd\lib\dictBuilder;$(UniversalCRT_IncludePath); - false - - - false - $(IncludePath);$(SolutionDir)..\ext\zstd\lib;$(SolutionDir)..\ext\zstd\programs\legacy;$(SolutionDir)..\ext\zstd\lib\legacy;$(SolutionDir)..\ext\zstd\lib\common;$(SolutionDir)..\ext\zstd\lib\dictBuilder;$(UniversalCRT_IncludePath); - false - - - - $(OutDir)$(TargetName).pdb - - - - - - - Level4 - ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - true - ProgramDatabase - false - - - Windows - true - MachineX86 - - - - - - - Level4 - ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug - true - ProgramDatabase - false - - - Windows - true - - - - - - - Level4 - ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug - true - ProgramDatabase - false - - - Windows - true - - - - - Level4 - - - MaxSpeed - true - true - ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - false - MultiThreaded - true - ProgramDatabase - AnySuitable - Speed - true - false - StreamingSIMDExtensions2 - - - Windows - true - true - true - MachineX86 - - - - - Level4 - - - MaxSpeed - true - true - ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - false - false - MultiThreaded - true - ProgramDatabase - false - true - AnySuitable - Speed - - - Windows - true - true - true - - - - - Level4 - - - MaxSpeed - true - true - ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - false - false - MultiThreaded - true - ProgramDatabase - false - true - AnySuitable - Speed - - - Windows - true - true - true - - - - - - \ No newline at end of file diff --git a/ext/zlib/CMakeLists.txt b/ext/zlib/CMakeLists.txt deleted file mode 100644 index 15ceebe787..0000000000 --- a/ext/zlib/CMakeLists.txt +++ /dev/null @@ -1,218 +0,0 @@ -cmake_minimum_required(VERSION 2.4.4...3.15.0) -set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) - -project(zlib C) - -set(VERSION "1.3.1") - -option(ZLIB_BUILD_EXAMPLES "Enable Zlib Examples" ON) - -set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables") -set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries") -set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers") -set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages") -set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files") - -include(CheckTypeSize) -include(CheckFunctionExists) -include(CheckIncludeFile) -include(CheckCSourceCompiles) -enable_testing() - -check_include_file(sys/types.h HAVE_SYS_TYPES_H) -check_include_file(stdint.h HAVE_STDINT_H) -check_include_file(stddef.h HAVE_STDDEF_H) - -# -# Check to see if we have large file support -# -set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1) -# We add these other definitions here because CheckTypeSize.cmake -# in CMake 2.4.x does not automatically do so and we want -# compatibility with CMake 2.4.x. -if(HAVE_SYS_TYPES_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H) -endif() -if(HAVE_STDINT_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H) -endif() -if(HAVE_STDDEF_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H) -endif() -check_type_size(off64_t OFF64_T) -if(HAVE_OFF64_T) - add_definitions(-D_LARGEFILE64_SOURCE=1) -endif() -set(CMAKE_REQUIRED_DEFINITIONS) # clear variable - -# -# Check for fseeko -# -check_function_exists(fseeko HAVE_FSEEKO) -if(NOT HAVE_FSEEKO) - add_definitions(-DNO_FSEEKO) -endif() - -# -# Check for unistd.h -# -check_include_file(unistd.h Z_HAVE_UNISTD_H) - -if(MSVC) - set(CMAKE_DEBUG_POSTFIX "d") - add_definitions(-D_CRT_SECURE_NO_DEPRECATE) - add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -endif() - -if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) - # If we're doing an out of source build and the user has a zconf.h - # in their source tree... - if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h) - message(STATUS "Renaming") - message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h") - message(STATUS "to 'zconf.h.included' because this file is included with zlib") - message(STATUS "but CMake generates it automatically in the build directory.") - file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included) - endif() -endif() - -set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc) -configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein - ${ZLIB_PC} @ONLY) -configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein - ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY) -include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}) - - -#============================================================================ -# zlib -#============================================================================ - -set(ZLIB_PUBLIC_HDRS - ${CMAKE_CURRENT_BINARY_DIR}/zconf.h - zlib.h -) -set(ZLIB_PRIVATE_HDRS - crc32.h - deflate.h - gzguts.h - inffast.h - inffixed.h - inflate.h - inftrees.h - trees.h - zutil.h -) -set(ZLIB_SRCS - adler32.c - compress.c - crc32.c - deflate.c - gzclose.c - gzlib.c - gzread.c - gzwrite.c - inflate.c - infback.c - inftrees.c - inffast.c - trees.c - uncompr.c - zutil.c -) - -if(NOT MINGW) - set(ZLIB_DLL_SRCS - win32/zlib1.rc # If present will override custom build rule below. - ) -endif() - -# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION -file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents) -string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*" - "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents}) - -if(MINGW) - # This gets us DLL resource information when compiling on MinGW. - if(NOT CMAKE_RC_COMPILER) - set(CMAKE_RC_COMPILER windres.exe) - endif() - - add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj - COMMAND ${CMAKE_RC_COMPILER} - -D GCC_WINDRES - -I ${CMAKE_CURRENT_SOURCE_DIR} - -I ${CMAKE_CURRENT_BINARY_DIR} - -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj - -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc) - set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj) -endif(MINGW) - -add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) -target_include_directories(zlib PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) -add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) -target_include_directories(zlibstatic PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) -set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL) -set_target_properties(zlib PROPERTIES SOVERSION 1) - -if(NOT CYGWIN) - # This property causes shared libraries on Linux to have the full version - # encoded into their final filename. We disable this on Cygwin because - # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll - # seems to be the default. - # - # This has no effect with MSVC, on that platform the version info for - # the DLL comes from the resource file win32/zlib1.rc - set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION}) -endif() - -if(UNIX) - # On unix-like platforms the library is almost always called libz - set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z) - if(NOT APPLE AND NOT(CMAKE_SYSTEM_NAME STREQUAL AIX)) - set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"") - endif() -elseif(BUILD_SHARED_LIBS AND WIN32) - # Creates zlib1.dll when building shared library version - set_target_properties(zlib PROPERTIES SUFFIX "1.dll") -endif() - -if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL ) - install(TARGETS zlib zlibstatic - RUNTIME DESTINATION "${INSTALL_BIN_DIR}" - ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" - LIBRARY DESTINATION "${INSTALL_LIB_DIR}" ) -endif() -if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL ) - install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION "${INSTALL_INC_DIR}") -endif() -if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) - install(FILES zlib.3 DESTINATION "${INSTALL_MAN_DIR}/man3") -endif() -if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) - install(FILES ${ZLIB_PC} DESTINATION "${INSTALL_PKGCONFIG_DIR}") -endif() - -#============================================================================ -# Example binaries -#============================================================================ -if(ZLIB_BUILD_EXAMPLES) - add_executable(example test/example.c) - target_link_libraries(example zlib) - add_test(example example) - - add_executable(minigzip test/minigzip.c) - target_link_libraries(minigzip zlib) - - if(HAVE_OFF64_T) - add_executable(example64 test/example.c) - target_link_libraries(example64 zlib) - set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") - add_test(example64 example64) - - add_executable(minigzip64 test/minigzip.c) - target_link_libraries(minigzip64 zlib) - set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") - endif() -endif() diff --git a/ext/zlib/LICENSE b/ext/zlib/LICENSE deleted file mode 100644 index ab8ee6f714..0000000000 --- a/ext/zlib/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright notice: - - (C) 1995-2022 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu diff --git a/ext/zlib/README b/ext/zlib/README deleted file mode 100644 index c5f917540b..0000000000 --- a/ext/zlib/README +++ /dev/null @@ -1,117 +0,0 @@ -ZLIB DATA COMPRESSION LIBRARY - -zlib 1.3.1 is a general purpose data compression library. All the code is -thread safe. The data format used by the zlib library is described by RFCs -(Request for Comments) 1950 to 1952 in the files -http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and -rfc1952 (gzip format). - -All functions of the compression library are documented in the file zlib.h -(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example -of the library is given in the file test/example.c which also tests that -the library is working correctly. Another example is given in the file -test/minigzip.c. The compression library itself is composed of all source -files in the root directory. - -To compile all files and run the test program, follow the instructions given at -the top of Makefile.in. In short "./configure; make test", and if that goes -well, "make install" should work for most flavors of Unix. For Windows, use -one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use -make_vms.com. - -Questions about zlib should be sent to , or to Gilles Vollant - for the Windows DLL version. The zlib home page is -http://zlib.net/ . Before reporting a problem, please check this site to -verify that you have the latest version of zlib; otherwise get the latest -version and check whether the problem still exists or not. - -PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. - -Mark Nelson wrote an article about zlib for the Jan. 1997 -issue of Dr. Dobb's Journal; a copy of the article is available at -https://marknelson.us/posts/1997/01/01/zlib-engine.html . - -The changes made in version 1.3.1 are documented in the file ChangeLog. - -Unsupported third party contributions are provided in directory contrib/ . - -zlib is available in Java using the java.util.zip package. Follow the API -Documentation link at: https://docs.oracle.com/search/?q=java.util.zip . - -A Perl interface to zlib and bzip2 written by Paul Marquess -can be found at https://github.com/pmqs/IO-Compress . - -A Python interface to zlib written by A.M. Kuchling is -available in Python 1.5 and later versions, see -http://docs.python.org/library/zlib.html . - -zlib is built into tcl: http://wiki.tcl.tk/4610 . - -An experimental package to read and write files in .zip format, written on top -of zlib by Gilles Vollant , is available in the -contrib/minizip directory of zlib. - - -Notes for some targets: - -- For Windows DLL versions, please see win32/DLL_FAQ.txt - -- For 64-bit Irix, deflate.c must be compiled without any optimization. With - -O, one libpng test fails. The test works in 32 bit mode (with the -n32 - compiler flag). The compiler bug has been reported to SGI. - -- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works - when compiled with cc. - -- On Digital Unix 4.0D (formerly OSF/1) on AlphaServer, the cc option -std1 is - necessary to get gzprintf working correctly. This is done by configure. - -- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with - other compilers. Use "make test" to check your compiler. - -- gzdopen is not supported on RISCOS or BEOS. - -- For PalmOs, see http://palmzlib.sourceforge.net/ - - -Acknowledgments: - - The deflate format used by zlib was defined by Phil Katz. The deflate and - zlib specifications were written by L. Peter Deutsch. Thanks to all the - people who reported problems and suggested various improvements in zlib; they - are too numerous to cite here. - -Copyright notice: - - (C) 1995-2024 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - -If you use the zlib library in a product, we would appreciate *not* receiving -lengthy legal documents to sign. The sources are provided for free but without -warranty of any kind. The library has been entirely written by Jean-loup -Gailly and Mark Adler; it does not include third-party code. We make all -contributions to and distributions of this project solely in our personal -capacity, and are not conveying any rights to any intellectual property of -any third parties. - -If you redistribute modified sources, we would appreciate that you include in -the file ChangeLog history information documenting your changes. Please read -the FAQ for more information on the distribution of modified source versions. diff --git a/ext/zlib/adler32.c b/ext/zlib/adler32.c deleted file mode 100644 index 04b81d29ba..0000000000 --- a/ext/zlib/adler32.c +++ /dev/null @@ -1,164 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2011, 2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -#define BASE 65521U /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* use NO_DIVIDE if your processor does not do division in hardware -- - try it both ways to see which is faster */ -#ifdef NO_DIVIDE -/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 - (thank you to John Reiser for pointing this out) */ -# define CHOP(a) \ - do { \ - unsigned long tmp = a >> 16; \ - a &= 0xffffUL; \ - a += (tmp << 4) - tmp; \ - } while (0) -# define MOD28(a) \ - do { \ - CHOP(a); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD(a) \ - do { \ - CHOP(a); \ - MOD28(a); \ - } while (0) -# define MOD63(a) \ - do { /* this assumes a is not negative */ \ - z_off64_t tmp = a >> 32; \ - a &= 0xffffffffL; \ - a += (tmp << 8) - (tmp << 5) + tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD28(a) a %= BASE -# define MOD63(a) a %= BASE -#endif - -/* ========================================================================= */ -uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) { - unsigned long sum2; - unsigned n; - - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; - - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } - - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; - - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD28(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } - - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; - n = NMAX / 16; /* NMAX is divisible by 16 */ - do { - DO16(buf); /* 16 sums unrolled */ - buf += 16; - } while (--n); - MOD(adler); - MOD(sum2); - } - - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } - - /* return recombined sums */ - return adler | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) { - return adler32_z(adler, buf, len); -} - -/* ========================================================================= */ -local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2) { - unsigned long sum1; - unsigned long sum2; - unsigned rem; - - /* for negative len, return invalid adler32 as a clue for debugging */ - if (len2 < 0) - return 0xffffffffUL; - - /* the derivation of this formula is left as an exercise for the reader */ - MOD63(len2); /* assumes len2 >= 0 */ - rem = (unsigned)len2; - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 >= BASE) sum1 -= BASE; - if (sum1 >= BASE) sum1 -= BASE; - if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); - if (sum2 >= BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) { - return adler32_combine_(adler1, adler2, len2); -} - -uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2) { - return adler32_combine_(adler1, adler2, len2); -} diff --git a/ext/zlib/compress.c b/ext/zlib/compress.c deleted file mode 100644 index f43bacf7ab..0000000000 --- a/ext/zlib/compress.c +++ /dev/null @@ -1,75 +0,0 @@ -/* compress.c -- compress a memory buffer - * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least 0.1% larger than sourceLen plus - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ -int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong sourceLen, int level) { - z_stream stream; - int err; - const uInt max = (uInt)-1; - uLong left; - - left = *destLen; - *destLen = 0; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit(&stream, level); - if (err != Z_OK) return err; - - stream.next_out = dest; - stream.avail_out = 0; - stream.next_in = (z_const Bytef *)source; - stream.avail_in = 0; - - do { - if (stream.avail_out == 0) { - stream.avail_out = left > (uLong)max ? max : (uInt)left; - left -= stream.avail_out; - } - if (stream.avail_in == 0) { - stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; - sourceLen -= stream.avail_in; - } - err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); - } while (err == Z_OK); - - *destLen = stream.total_out; - deflateEnd(&stream); - return err == Z_STREAM_END ? Z_OK : err; -} - -/* =========================================================================== - */ -int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong sourceLen) { - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); -} - -/* =========================================================================== - If the default memLevel or windowBits for deflateInit() is changed, then - this function needs to be updated. - */ -uLong ZEXPORT compressBound(uLong sourceLen) { - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13; -} diff --git a/ext/zlib/crc32.c b/ext/zlib/crc32.c deleted file mode 100644 index 6c38f5c04c..0000000000 --- a/ext/zlib/crc32.c +++ /dev/null @@ -1,1049 +0,0 @@ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2022 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - * This interleaved implementation of a CRC makes use of pipelined multiple - * arithmetic-logic units, commonly found in modern CPU cores. It is due to - * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution. - */ - -/* @(#) $Id$ */ - -/* - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore - protection on the static variables used to control the first-use generation - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should - first call get_crc_table() to initialize the tables before allowing more than - one thread to use crc32(). - - MAKECRCH can be #defined to write out crc32.h. A main() routine is also - produced, so that this one source file can be compiled to an executable. - */ - -#ifdef MAKECRCH -# include -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ -#endif /* MAKECRCH */ - -#include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */ - - /* - A CRC of a message is computed on N braids of words in the message, where - each word consists of W bytes (4 or 8). If N is 3, for example, then three - running sparse CRCs are calculated respectively on each braid, at these - indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ... - This is done starting at a word boundary, and continues until as many blocks - of N * W bytes as are available have been processed. The results are combined - into a single CRC at the end. For this code, N must be in the range 1..6 and - W must be 4 or 8. The upper limit on N can be increased if desired by adding - more #if blocks, extending the patterns apparent in the code. In addition, - crc32.h would need to be regenerated, if the maximum N value is increased. - - N and W are chosen empirically by benchmarking the execution time on a given - processor. The choices for N and W below were based on testing on Intel Kaby - Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64 - Octeon II processors. The Intel, AMD, and ARM processors were all fastest - with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4. - They were all tested with either gcc or clang, all using the -O3 optimization - level. Your mileage may vary. - */ - -/* Define N */ -#ifdef Z_TESTN -# define N Z_TESTN -#else -# define N 5 -#endif -#if N < 1 || N > 6 -# error N must be in 1..6 -#endif - -/* - z_crc_t must be at least 32 bits. z_word_t must be at least as long as - z_crc_t. It is assumed here that z_word_t is either 32 bits or 64 bits, and - that bytes are eight bits. - */ - -/* - Define W and the associated z_word_t type. If W is not defined, then a - braided calculation is not used, and the associated tables and code are not - compiled. - */ -#ifdef Z_TESTW -# if Z_TESTW-1 != -1 -# define W Z_TESTW -# endif -#else -# ifdef MAKECRCH -# define W 8 /* required for MAKECRCH */ -# else -# if defined(__x86_64__) || defined(__aarch64__) -# define W 8 -# else -# define W 4 -# endif -# endif -#endif -#ifdef W -# if W == 8 && defined(Z_U8) - typedef Z_U8 z_word_t; -# elif defined(Z_U4) -# undef W -# define W 4 - typedef Z_U4 z_word_t; -# else -# undef W -# endif -#endif - -/* If available, use the ARM processor CRC32 instruction. */ -#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8 -# define ARMCRC32 -#endif - -#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE)) -/* - Swap the bytes in a z_word_t to convert between little and big endian. Any - self-respecting compiler will optimize this to a single machine byte-swap - instruction, if one is available. This assumes that word_t is either 32 bits - or 64 bits. - */ -local z_word_t byte_swap(z_word_t word) { -# if W == 8 - return - (word & 0xff00000000000000) >> 56 | - (word & 0xff000000000000) >> 40 | - (word & 0xff0000000000) >> 24 | - (word & 0xff00000000) >> 8 | - (word & 0xff000000) << 8 | - (word & 0xff0000) << 24 | - (word & 0xff00) << 40 | - (word & 0xff) << 56; -# else /* W == 4 */ - return - (word & 0xff000000) >> 24 | - (word & 0xff0000) >> 8 | - (word & 0xff00) << 8 | - (word & 0xff) << 24; -# endif -} -#endif - -#ifdef DYNAMIC_CRC_TABLE -/* ========================================================================= - * Table of powers of x for combining CRC-32s, filled in by make_crc_table() - * below. - */ - local z_crc_t FAR x2n_table[32]; -#else -/* ========================================================================= - * Tables for byte-wise and braided CRC-32 calculations, and a table of powers - * of x for combining CRC-32s, all made by make_crc_table(). - */ -# include "crc32.h" -#endif - -/* CRC polynomial. */ -#define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */ - -/* - Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, - reflected. For speed, this requires that a not be zero. - */ -local z_crc_t multmodp(z_crc_t a, z_crc_t b) { - z_crc_t m, p; - - m = (z_crc_t)1 << 31; - p = 0; - for (;;) { - if (a & m) { - p ^= b; - if ((a & (m - 1)) == 0) - break; - } - m >>= 1; - b = b & 1 ? (b >> 1) ^ POLY : b >> 1; - } - return p; -} - -/* - Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been - initialized. - */ -local z_crc_t x2nmodp(z_off64_t n, unsigned k) { - z_crc_t p; - - p = (z_crc_t)1 << 31; /* x^0 == 1 */ - while (n) { - if (n & 1) - p = multmodp(x2n_table[k & 31], p); - n >>= 1; - k++; - } - return p; -} - -#ifdef DYNAMIC_CRC_TABLE -/* ========================================================================= - * Build the tables for byte-wise and braided CRC-32 calculations, and a table - * of powers of x for combining CRC-32s. - */ -local z_crc_t FAR crc_table[256]; -#ifdef W - local z_word_t FAR crc_big_table[256]; - local z_crc_t FAR crc_braid_table[W][256]; - local z_word_t FAR crc_braid_big_table[W][256]; - local void braid(z_crc_t [][256], z_word_t [][256], int, int); -#endif -#ifdef MAKECRCH - local void write_table(FILE *, const z_crc_t FAR *, int); - local void write_table32hi(FILE *, const z_word_t FAR *, int); - local void write_table64(FILE *, const z_word_t FAR *, int); -#endif /* MAKECRCH */ - -/* - Define a once() function depending on the availability of atomics. If this is - compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in - multiple threads, and if atomics are not available, then get_crc_table() must - be called to initialize the tables and must return before any threads are - allowed to compute or combine CRCs. - */ - -/* Definition of once functionality. */ -typedef struct once_s once_t; - -/* Check for the availability of atomics. */ -#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ - !defined(__STDC_NO_ATOMICS__) - -#include - -/* Structure for once(), which must be initialized with ONCE_INIT. */ -struct once_s { - atomic_flag begun; - atomic_int done; -}; -#define ONCE_INIT {ATOMIC_FLAG_INIT, 0} - -/* - Run the provided init() function exactly once, even if multiple threads - invoke once() at the same time. The state must be a once_t initialized with - ONCE_INIT. - */ -local void once(once_t *state, void (*init)(void)) { - if (!atomic_load(&state->done)) { - if (atomic_flag_test_and_set(&state->begun)) - while (!atomic_load(&state->done)) - ; - else { - init(); - atomic_store(&state->done, 1); - } - } -} - -#else /* no atomics */ - -/* Structure for once(), which must be initialized with ONCE_INIT. */ -struct once_s { - volatile int begun; - volatile int done; -}; -#define ONCE_INIT {0, 0} - -/* Test and set. Alas, not atomic, but tries to minimize the period of - vulnerability. */ -local int test_and_set(int volatile *flag) { - int was; - - was = *flag; - *flag = 1; - return was; -} - -/* Run the provided init() function once. This is not thread-safe. */ -local void once(once_t *state, void (*init)(void)) { - if (!state->done) { - if (test_and_set(&state->begun)) - while (!state->done) - ; - else { - init(); - state->done = 1; - } - } -} - -#endif - -/* State for once(). */ -local once_t made = ONCE_INIT; - -/* - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x - (which is shifting right by one and adding x^32 mod p if the bit shifted out - is a one). We start with the highest power (least significant bit) of q and - repeat for all eight bits of q. - - The table is simply the CRC of all possible eight bit values. This is all the - information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. - */ - -local void make_crc_table(void) { - unsigned i, j, n; - z_crc_t p; - - /* initialize the CRC of bytes tables */ - for (i = 0; i < 256; i++) { - p = i; - for (j = 0; j < 8; j++) - p = p & 1 ? (p >> 1) ^ POLY : p >> 1; - crc_table[i] = p; -#ifdef W - crc_big_table[i] = byte_swap(p); -#endif - } - - /* initialize the x^2^n mod p(x) table */ - p = (z_crc_t)1 << 30; /* x^1 */ - x2n_table[0] = p; - for (n = 1; n < 32; n++) - x2n_table[n] = p = multmodp(p, p); - -#ifdef W - /* initialize the braiding tables -- needs x2n_table[] */ - braid(crc_braid_table, crc_braid_big_table, N, W); -#endif - -#ifdef MAKECRCH - { - /* - The crc32.h header file contains tables for both 32-bit and 64-bit - z_word_t's, and so requires a 64-bit type be available. In that case, - z_word_t must be defined to be 64-bits. This code then also generates - and writes out the tables for the case that z_word_t is 32 bits. - */ -#if !defined(W) || W != 8 -# error Need a 64-bit integer type in order to generate crc32.h. -#endif - FILE *out; - int k, n; - z_crc_t ltl[8][256]; - z_word_t big[8][256]; - - out = fopen("crc32.h", "w"); - if (out == NULL) return; - - /* write out little-endian CRC table to crc32.h */ - fprintf(out, - "/* crc32.h -- tables for rapid CRC calculation\n" - " * Generated automatically by crc32.c\n */\n" - "\n" - "local const z_crc_t FAR crc_table[] = {\n" - " "); - write_table(out, crc_table, 256); - fprintf(out, - "};\n"); - - /* write out big-endian CRC table for 64-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#ifdef W\n" - "\n" - "#if W == 8\n" - "\n" - "local const z_word_t FAR crc_big_table[] = {\n" - " "); - write_table64(out, crc_big_table, 256); - fprintf(out, - "};\n"); - - /* write out big-endian CRC table for 32-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#else /* W == 4 */\n" - "\n" - "local const z_word_t FAR crc_big_table[] = {\n" - " "); - write_table32hi(out, crc_big_table, 256); - fprintf(out, - "};\n" - "\n" - "#endif\n"); - - /* write out braid tables for each value of N */ - for (n = 1; n <= 6; n++) { - fprintf(out, - "\n" - "#if N == %d\n", n); - - /* compute braid tables for this N and 64-bit word_t */ - braid(ltl, big, n, 8); - - /* write out braid tables for 64-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#if W == 8\n" - "\n" - "local const z_crc_t FAR crc_braid_table[][256] = {\n"); - for (k = 0; k < 8; k++) { - fprintf(out, " {"); - write_table(out, ltl[k], 256); - fprintf(out, "}%s", k < 7 ? ",\n" : ""); - } - fprintf(out, - "};\n" - "\n" - "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); - for (k = 0; k < 8; k++) { - fprintf(out, " {"); - write_table64(out, big[k], 256); - fprintf(out, "}%s", k < 7 ? ",\n" : ""); - } - fprintf(out, - "};\n"); - - /* compute braid tables for this N and 32-bit word_t */ - braid(ltl, big, n, 4); - - /* write out braid tables for 32-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#else /* W == 4 */\n" - "\n" - "local const z_crc_t FAR crc_braid_table[][256] = {\n"); - for (k = 0; k < 4; k++) { - fprintf(out, " {"); - write_table(out, ltl[k], 256); - fprintf(out, "}%s", k < 3 ? ",\n" : ""); - } - fprintf(out, - "};\n" - "\n" - "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); - for (k = 0; k < 4; k++) { - fprintf(out, " {"); - write_table32hi(out, big[k], 256); - fprintf(out, "}%s", k < 3 ? ",\n" : ""); - } - fprintf(out, - "};\n" - "\n" - "#endif\n" - "\n" - "#endif\n"); - } - fprintf(out, - "\n" - "#endif\n"); - - /* write out zeros operator table to crc32.h */ - fprintf(out, - "\n" - "local const z_crc_t FAR x2n_table[] = {\n" - " "); - write_table(out, x2n_table, 32); - fprintf(out, - "};\n"); - fclose(out); - } -#endif /* MAKECRCH */ -} - -#ifdef MAKECRCH - -/* - Write the 32-bit values in table[0..k-1] to out, five per line in - hexadecimal separated by commas. - */ -local void write_table(FILE *out, const z_crc_t FAR *table, int k) { - int n; - - for (n = 0; n < k; n++) - fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", - (unsigned long)(table[n]), - n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); -} - -/* - Write the high 32-bits of each value in table[0..k-1] to out, five per line - in hexadecimal separated by commas. - */ -local void write_table32hi(FILE *out, const z_word_t FAR *table, int k) { - int n; - - for (n = 0; n < k; n++) - fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", - (unsigned long)(table[n] >> 32), - n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); -} - -/* - Write the 64-bit values in table[0..k-1] to out, three per line in - hexadecimal separated by commas. This assumes that if there is a 64-bit - type, then there is also a long long integer type, and it is at least 64 - bits. If not, then the type cast and format string can be adjusted - accordingly. - */ -local void write_table64(FILE *out, const z_word_t FAR *table, int k) { - int n; - - for (n = 0; n < k; n++) - fprintf(out, "%s0x%016llx%s", n == 0 || n % 3 ? "" : " ", - (unsigned long long)(table[n]), - n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", ")); -} - -/* Actually do the deed. */ -int main(void) { - make_crc_table(); - return 0; -} - -#endif /* MAKECRCH */ - -#ifdef W -/* - Generate the little and big-endian braid tables for the given n and z_word_t - size w. Each array must have room for w blocks of 256 elements. - */ -local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) { - int k; - z_crc_t i, p, q; - for (k = 0; k < w; k++) { - p = x2nmodp((n * w + 3 - k) << 3, 0); - ltl[k][0] = 0; - big[w - 1 - k][0] = 0; - for (i = 1; i < 256; i++) { - ltl[k][i] = q = multmodp(i << 24, p); - big[w - 1 - k][i] = byte_swap(q); - } - } -} -#endif - -#endif /* DYNAMIC_CRC_TABLE */ - -/* ========================================================================= - * This function can be used by asm versions of crc32(), and to force the - * generation of the CRC tables in a threaded application. - */ -const z_crc_t FAR * ZEXPORT get_crc_table(void) { -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - return (const z_crc_t FAR *)crc_table; -} - -/* ========================================================================= - * Use ARM machine instructions if available. This will compute the CRC about - * ten times faster than the braided calculation. This code does not check for - * the presence of the CRC instruction at run time. __ARM_FEATURE_CRC32 will - * only be defined if the compilation specifies an ARM processor architecture - * that has the instructions. For example, compiling with -march=armv8.1-a or - * -march=armv8-a+crc, or -march=native if the compile machine has the crc32 - * instructions. - */ -#ifdef ARMCRC32 - -/* - Constants empirically determined to maximize speed. These values are from - measurements on a Cortex-A57. Your mileage may vary. - */ -#define Z_BATCH 3990 /* number of words in a batch */ -#define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */ -#define Z_BATCH_MIN 800 /* fewest words in a final batch */ - -unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, - z_size_t len) { - z_crc_t val; - z_word_t crc1, crc2; - const z_word_t *word; - z_word_t val0, val1, val2; - z_size_t last, last2, i; - z_size_t num; - - /* Return initial CRC, if requested. */ - if (buf == Z_NULL) return 0; - -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - - /* Pre-condition the CRC */ - crc = (~crc) & 0xffffffff; - - /* Compute the CRC up to a word boundary. */ - while (len && ((z_size_t)buf & 7) != 0) { - len--; - val = *buf++; - __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); - } - - /* Prepare to compute the CRC on full 64-bit words word[0..num-1]. */ - word = (z_word_t const *)buf; - num = len >> 3; - len &= 7; - - /* Do three interleaved CRCs to realize the throughput of one crc32x - instruction per cycle. Each CRC is calculated on Z_BATCH words. The - three CRCs are combined into a single CRC after each set of batches. */ - while (num >= 3 * Z_BATCH) { - crc1 = 0; - crc2 = 0; - for (i = 0; i < Z_BATCH; i++) { - val0 = word[i]; - val1 = word[i + Z_BATCH]; - val2 = word[i + 2 * Z_BATCH]; - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); - } - word += 3 * Z_BATCH; - num -= 3 * Z_BATCH; - crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc1; - crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc2; - } - - /* Do one last smaller batch with the remaining words, if there are enough - to pay for the combination of CRCs. */ - last = num / 3; - if (last >= Z_BATCH_MIN) { - last2 = last << 1; - crc1 = 0; - crc2 = 0; - for (i = 0; i < last; i++) { - val0 = word[i]; - val1 = word[i + last]; - val2 = word[i + last2]; - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); - } - word += 3 * last; - num -= 3 * last; - val = x2nmodp(last, 6); - crc = multmodp(val, crc) ^ crc1; - crc = multmodp(val, crc) ^ crc2; - } - - /* Compute the CRC on any remaining words. */ - for (i = 0; i < num; i++) { - val0 = word[i]; - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); - } - word += num; - - /* Complete the CRC on any remaining bytes. */ - buf = (const unsigned char FAR *)word; - while (len) { - len--; - val = *buf++; - __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); - } - - /* Return the CRC, post-conditioned. */ - return crc ^ 0xffffffff; -} - -#else - -#ifdef W - -/* - Return the CRC of the W bytes in the word_t data, taking the - least-significant byte of the word as the first byte of data, without any pre - or post conditioning. This is used to combine the CRCs of each braid. - */ -local z_crc_t crc_word(z_word_t data) { - int k; - for (k = 0; k < W; k++) - data = (data >> 8) ^ crc_table[data & 0xff]; - return (z_crc_t)data; -} - -local z_word_t crc_word_big(z_word_t data) { - int k; - for (k = 0; k < W; k++) - data = (data << 8) ^ - crc_big_table[(data >> ((W - 1) << 3)) & 0xff]; - return data; -} - -#endif - -/* ========================================================================= */ -unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, - z_size_t len) { - /* Return initial CRC, if requested. */ - if (buf == Z_NULL) return 0; - -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - - /* Pre-condition the CRC */ - crc = (~crc) & 0xffffffff; - -#ifdef W - - /* If provided enough bytes, do a braided CRC calculation. */ - if (len >= N * W + W - 1) { - z_size_t blks; - z_word_t const *words; - unsigned endian; - int k; - - /* Compute the CRC up to a z_word_t boundary. */ - while (len && ((z_size_t)buf & (W - 1)) != 0) { - len--; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - } - - /* Compute the CRC on as many N z_word_t blocks as are available. */ - blks = len / (N * W); - len -= blks * N * W; - words = (z_word_t const *)buf; - - /* Do endian check at execution time instead of compile time, since ARM - processors can change the endianness at execution time. If the - compiler knows what the endianness will be, it can optimize out the - check and the unused branch. */ - endian = 1; - if (*(unsigned char *)&endian) { - /* Little endian. */ - - z_crc_t crc0; - z_word_t word0; -#if N > 1 - z_crc_t crc1; - z_word_t word1; -#if N > 2 - z_crc_t crc2; - z_word_t word2; -#if N > 3 - z_crc_t crc3; - z_word_t word3; -#if N > 4 - z_crc_t crc4; - z_word_t word4; -#if N > 5 - z_crc_t crc5; - z_word_t word5; -#endif -#endif -#endif -#endif -#endif - - /* Initialize the CRC for each braid. */ - crc0 = crc; -#if N > 1 - crc1 = 0; -#if N > 2 - crc2 = 0; -#if N > 3 - crc3 = 0; -#if N > 4 - crc4 = 0; -#if N > 5 - crc5 = 0; -#endif -#endif -#endif -#endif -#endif - - /* - Process the first blks-1 blocks, computing the CRCs on each braid - independently. - */ - while (--blks) { - /* Load the word for each braid into registers. */ - word0 = crc0 ^ words[0]; -#if N > 1 - word1 = crc1 ^ words[1]; -#if N > 2 - word2 = crc2 ^ words[2]; -#if N > 3 - word3 = crc3 ^ words[3]; -#if N > 4 - word4 = crc4 ^ words[4]; -#if N > 5 - word5 = crc5 ^ words[5]; -#endif -#endif -#endif -#endif -#endif - words += N; - - /* Compute and update the CRC for each word. The loop should - get unrolled. */ - crc0 = crc_braid_table[0][word0 & 0xff]; -#if N > 1 - crc1 = crc_braid_table[0][word1 & 0xff]; -#if N > 2 - crc2 = crc_braid_table[0][word2 & 0xff]; -#if N > 3 - crc3 = crc_braid_table[0][word3 & 0xff]; -#if N > 4 - crc4 = crc_braid_table[0][word4 & 0xff]; -#if N > 5 - crc5 = crc_braid_table[0][word5 & 0xff]; -#endif -#endif -#endif -#endif -#endif - for (k = 1; k < W; k++) { - crc0 ^= crc_braid_table[k][(word0 >> (k << 3)) & 0xff]; -#if N > 1 - crc1 ^= crc_braid_table[k][(word1 >> (k << 3)) & 0xff]; -#if N > 2 - crc2 ^= crc_braid_table[k][(word2 >> (k << 3)) & 0xff]; -#if N > 3 - crc3 ^= crc_braid_table[k][(word3 >> (k << 3)) & 0xff]; -#if N > 4 - crc4 ^= crc_braid_table[k][(word4 >> (k << 3)) & 0xff]; -#if N > 5 - crc5 ^= crc_braid_table[k][(word5 >> (k << 3)) & 0xff]; -#endif -#endif -#endif -#endif -#endif - } - } - - /* - Process the last block, combining the CRCs of the N braids at the - same time. - */ - crc = crc_word(crc0 ^ words[0]); -#if N > 1 - crc = crc_word(crc1 ^ words[1] ^ crc); -#if N > 2 - crc = crc_word(crc2 ^ words[2] ^ crc); -#if N > 3 - crc = crc_word(crc3 ^ words[3] ^ crc); -#if N > 4 - crc = crc_word(crc4 ^ words[4] ^ crc); -#if N > 5 - crc = crc_word(crc5 ^ words[5] ^ crc); -#endif -#endif -#endif -#endif -#endif - words += N; - } - else { - /* Big endian. */ - - z_word_t crc0, word0, comb; -#if N > 1 - z_word_t crc1, word1; -#if N > 2 - z_word_t crc2, word2; -#if N > 3 - z_word_t crc3, word3; -#if N > 4 - z_word_t crc4, word4; -#if N > 5 - z_word_t crc5, word5; -#endif -#endif -#endif -#endif -#endif - - /* Initialize the CRC for each braid. */ - crc0 = byte_swap(crc); -#if N > 1 - crc1 = 0; -#if N > 2 - crc2 = 0; -#if N > 3 - crc3 = 0; -#if N > 4 - crc4 = 0; -#if N > 5 - crc5 = 0; -#endif -#endif -#endif -#endif -#endif - - /* - Process the first blks-1 blocks, computing the CRCs on each braid - independently. - */ - while (--blks) { - /* Load the word for each braid into registers. */ - word0 = crc0 ^ words[0]; -#if N > 1 - word1 = crc1 ^ words[1]; -#if N > 2 - word2 = crc2 ^ words[2]; -#if N > 3 - word3 = crc3 ^ words[3]; -#if N > 4 - word4 = crc4 ^ words[4]; -#if N > 5 - word5 = crc5 ^ words[5]; -#endif -#endif -#endif -#endif -#endif - words += N; - - /* Compute and update the CRC for each word. The loop should - get unrolled. */ - crc0 = crc_braid_big_table[0][word0 & 0xff]; -#if N > 1 - crc1 = crc_braid_big_table[0][word1 & 0xff]; -#if N > 2 - crc2 = crc_braid_big_table[0][word2 & 0xff]; -#if N > 3 - crc3 = crc_braid_big_table[0][word3 & 0xff]; -#if N > 4 - crc4 = crc_braid_big_table[0][word4 & 0xff]; -#if N > 5 - crc5 = crc_braid_big_table[0][word5 & 0xff]; -#endif -#endif -#endif -#endif -#endif - for (k = 1; k < W; k++) { - crc0 ^= crc_braid_big_table[k][(word0 >> (k << 3)) & 0xff]; -#if N > 1 - crc1 ^= crc_braid_big_table[k][(word1 >> (k << 3)) & 0xff]; -#if N > 2 - crc2 ^= crc_braid_big_table[k][(word2 >> (k << 3)) & 0xff]; -#if N > 3 - crc3 ^= crc_braid_big_table[k][(word3 >> (k << 3)) & 0xff]; -#if N > 4 - crc4 ^= crc_braid_big_table[k][(word4 >> (k << 3)) & 0xff]; -#if N > 5 - crc5 ^= crc_braid_big_table[k][(word5 >> (k << 3)) & 0xff]; -#endif -#endif -#endif -#endif -#endif - } - } - - /* - Process the last block, combining the CRCs of the N braids at the - same time. - */ - comb = crc_word_big(crc0 ^ words[0]); -#if N > 1 - comb = crc_word_big(crc1 ^ words[1] ^ comb); -#if N > 2 - comb = crc_word_big(crc2 ^ words[2] ^ comb); -#if N > 3 - comb = crc_word_big(crc3 ^ words[3] ^ comb); -#if N > 4 - comb = crc_word_big(crc4 ^ words[4] ^ comb); -#if N > 5 - comb = crc_word_big(crc5 ^ words[5] ^ comb); -#endif -#endif -#endif -#endif -#endif - words += N; - crc = byte_swap(comb); - } - - /* - Update the pointer to the remaining bytes to process. - */ - buf = (unsigned char const *)words; - } - -#endif /* W */ - - /* Complete the computation of the CRC on any remaining bytes. */ - while (len >= 8) { - len -= 8; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - } - while (len) { - len--; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - } - - /* Return the CRC, post-conditioned. */ - return crc ^ 0xffffffff; -} - -#endif - -/* ========================================================================= */ -unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, - uInt len) { - return crc32_z(crc, buf, len); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) { -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) { - return crc32_combine64(crc1, crc2, (z_off64_t)len2); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) { -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - return x2nmodp(len2, 3); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine_gen(z_off_t len2) { - return crc32_combine_gen64((z_off64_t)len2); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) { - return multmodp(op, crc1) ^ (crc2 & 0xffffffff); -} diff --git a/ext/zlib/crc32.h b/ext/zlib/crc32.h deleted file mode 100644 index 137df68d61..0000000000 --- a/ext/zlib/crc32.h +++ /dev/null @@ -1,9446 +0,0 @@ -/* crc32.h -- tables for rapid CRC calculation - * Generated automatically by crc32.c - */ - -local const z_crc_t FAR crc_table[] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d}; - -#ifdef W - -#if W == 8 - -local const z_word_t FAR crc_big_table[] = { - 0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, - 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, - 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, - 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, - 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, - 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, - 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, - 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, - 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, - 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, - 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, - 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, - 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, - 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, - 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, - 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, - 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, - 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, - 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, - 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, - 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, - 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, - 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, - 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, - 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, - 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, - 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, - 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, - 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, - 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, - 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, - 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, - 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, - 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, - 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, - 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, - 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, - 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, - 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, - 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, - 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, - 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, - 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, - 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, - 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, - 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, - 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, - 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, - 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, - 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, - 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, - 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, - 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, - 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, - 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, - 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, - 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, - 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, - 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, - 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, - 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, - 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, - 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, - 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, - 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, - 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, - 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, - 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, - 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, - 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, - 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, - 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, - 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, - 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, - 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, - 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, - 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, - 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, - 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, - 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, - 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, - 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, - 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, - 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, - 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, - 0x8def022d00000000}; - -#else /* W == 4 */ - -local const z_word_t FAR crc_big_table[] = { - 0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, - 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, - 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, - 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, - 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, - 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, - 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, - 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, - 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, - 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, - 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, - 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, - 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, - 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, - 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, - 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, - 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, - 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, - 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, - 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, - 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, - 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, - 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, - 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, - 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, - 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, - 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, - 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, - 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, - 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, - 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, - 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, - 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, - 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, - 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, - 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, - 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, - 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, - 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, - 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, - 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, - 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, - 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, - 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, - 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, - 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, - 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, - 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, - 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, - 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, - 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, - 0x8def022d}; - -#endif - -#if N == 1 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, - 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, - 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, - 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, - 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, - 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, - 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, - 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, - 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, - 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, - 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, - 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, - 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, - 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, - 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, - 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, - 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, - 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, - 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, - 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, - 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, - 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, - 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, - 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, - 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, - 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, - 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, - 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, - 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, - 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, - 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, - 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, - 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, - 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, - 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, - 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, - 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, - 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, - 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, - 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, - 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, - 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, - 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, - 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, - 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, - 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, - 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, - 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, - 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, - 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, - 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, - 0x264b06e6}, - {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, - 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, - 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, - 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, - 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, - 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, - 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, - 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, - 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, - 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, - 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, - 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, - 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, - 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, - 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, - 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, - 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, - 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, - 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, - 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, - 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, - 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, - 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, - 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, - 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, - 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, - 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, - 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, - 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, - 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, - 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, - 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, - 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, - 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, - 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, - 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, - 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, - 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, - 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, - 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, - 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, - 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, - 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, - 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, - 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, - 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, - 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, - 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, - 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, - 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, - 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, - 0x92364a30}, - {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, - 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, - 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, - 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, - 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, - 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, - 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, - 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, - 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, - 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, - 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, - 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, - 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, - 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, - 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, - 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, - 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, - 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, - 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, - 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, - 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, - 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, - 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, - 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, - 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, - 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, - 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, - 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, - 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, - 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, - 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, - 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, - 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, - 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, - 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, - 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, - 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, - 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, - 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, - 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, - 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, - 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, - 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, - 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, - 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, - 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, - 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, - 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, - 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, - 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, - 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, - 0xe4c4abcc}, - {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, - 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, - 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, - 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, - 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, - 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, - 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, - 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, - 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, - 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, - 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, - 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, - 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, - 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, - 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, - 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, - 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, - 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, - 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, - 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, - 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, - 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, - 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, - 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, - 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, - 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, - 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, - 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, - 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, - 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, - 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, - 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, - 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, - 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, - 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, - 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, - 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, - 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, - 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, - 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, - 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, - 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, - 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, - 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, - 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, - 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, - 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, - 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, - 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, - 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, - 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, - 0xca64c78c}, - {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, - 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, - 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, - 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, - 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, - 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, - 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, - 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, - 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, - 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, - 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, - 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, - 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, - 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, - 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, - 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, - 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, - 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, - 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, - 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, - 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, - 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, - 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, - 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, - 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, - 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, - 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, - 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, - 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, - 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, - 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, - 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, - 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, - 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, - 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, - 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, - 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, - 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, - 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, - 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, - 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, - 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, - 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, - 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, - 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, - 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, - 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, - 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, - 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, - 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, - 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, - 0xde0506f1}, - {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, - 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, - 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, - 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, - 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, - 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, - 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, - 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, - 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, - 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, - 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, - 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, - 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, - 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, - 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, - 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, - 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, - 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, - 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, - 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, - 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, - 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, - 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, - 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, - 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, - 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, - 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, - 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, - 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, - 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, - 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, - 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, - 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, - 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, - 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, - 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, - 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, - 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, - 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, - 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, - 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, - 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, - 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, - 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, - 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, - 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, - 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, - 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, - 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, - 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, - 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, - 0xbe9834ed}, - {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, - 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, - 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, - 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, - 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, - 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, - 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, - 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, - 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, - 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, - 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, - 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, - 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, - 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, - 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, - 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, - 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, - 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, - 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, - 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, - 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, - 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, - 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, - 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, - 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, - 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, - 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, - 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, - 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, - 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, - 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, - 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, - 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, - 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, - 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, - 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, - 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, - 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, - 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, - 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, - 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, - 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, - 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, - 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, - 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, - 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, - 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, - 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, - 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, - 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, - 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, - 0x9324fd72}, - {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, - 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, - 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, - 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, - 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, - 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, - 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, - 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, - 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, - 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, - 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, - 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, - 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, - 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, - 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, - 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, - 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, - 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, - 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, - 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, - 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, - 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, - 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, - 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, - 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, - 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, - 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, - 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, - 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, - 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, - 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, - 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, - 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, - 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, - 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, - 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, - 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, - 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, - 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, - 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, - 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, - 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, - 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, - 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, - 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, - 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, - 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, - 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, - 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, - 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, - 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, - 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, - 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, - 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, - 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, - 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, - 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, - 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, - 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, - 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, - 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, - 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, - 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, - 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, - 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, - 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, - 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, - 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, - 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, - 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, - 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, - 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, - 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, - 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, - 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, - 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, - 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, - 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, - 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, - 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, - 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, - 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, - 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, - 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, - 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, - 0x8def022d00000000}, - {0x0000000000000000, 0x41311b1900000000, 0x8262363200000000, - 0xc3532d2b00000000, 0x04c56c6400000000, 0x45f4777d00000000, - 0x86a75a5600000000, 0xc796414f00000000, 0x088ad9c800000000, - 0x49bbc2d100000000, 0x8ae8effa00000000, 0xcbd9f4e300000000, - 0x0c4fb5ac00000000, 0x4d7eaeb500000000, 0x8e2d839e00000000, - 0xcf1c988700000000, 0x5112c24a00000000, 0x1023d95300000000, - 0xd370f47800000000, 0x9241ef6100000000, 0x55d7ae2e00000000, - 0x14e6b53700000000, 0xd7b5981c00000000, 0x9684830500000000, - 0x59981b8200000000, 0x18a9009b00000000, 0xdbfa2db000000000, - 0x9acb36a900000000, 0x5d5d77e600000000, 0x1c6c6cff00000000, - 0xdf3f41d400000000, 0x9e0e5acd00000000, 0xa224849500000000, - 0xe3159f8c00000000, 0x2046b2a700000000, 0x6177a9be00000000, - 0xa6e1e8f100000000, 0xe7d0f3e800000000, 0x2483dec300000000, - 0x65b2c5da00000000, 0xaaae5d5d00000000, 0xeb9f464400000000, - 0x28cc6b6f00000000, 0x69fd707600000000, 0xae6b313900000000, - 0xef5a2a2000000000, 0x2c09070b00000000, 0x6d381c1200000000, - 0xf33646df00000000, 0xb2075dc600000000, 0x715470ed00000000, - 0x30656bf400000000, 0xf7f32abb00000000, 0xb6c231a200000000, - 0x75911c8900000000, 0x34a0079000000000, 0xfbbc9f1700000000, - 0xba8d840e00000000, 0x79dea92500000000, 0x38efb23c00000000, - 0xff79f37300000000, 0xbe48e86a00000000, 0x7d1bc54100000000, - 0x3c2ade5800000000, 0x054f79f000000000, 0x447e62e900000000, - 0x872d4fc200000000, 0xc61c54db00000000, 0x018a159400000000, - 0x40bb0e8d00000000, 0x83e823a600000000, 0xc2d938bf00000000, - 0x0dc5a03800000000, 0x4cf4bb2100000000, 0x8fa7960a00000000, - 0xce968d1300000000, 0x0900cc5c00000000, 0x4831d74500000000, - 0x8b62fa6e00000000, 0xca53e17700000000, 0x545dbbba00000000, - 0x156ca0a300000000, 0xd63f8d8800000000, 0x970e969100000000, - 0x5098d7de00000000, 0x11a9ccc700000000, 0xd2fae1ec00000000, - 0x93cbfaf500000000, 0x5cd7627200000000, 0x1de6796b00000000, - 0xdeb5544000000000, 0x9f844f5900000000, 0x58120e1600000000, - 0x1923150f00000000, 0xda70382400000000, 0x9b41233d00000000, - 0xa76bfd6500000000, 0xe65ae67c00000000, 0x2509cb5700000000, - 0x6438d04e00000000, 0xa3ae910100000000, 0xe29f8a1800000000, - 0x21cca73300000000, 0x60fdbc2a00000000, 0xafe124ad00000000, - 0xeed03fb400000000, 0x2d83129f00000000, 0x6cb2098600000000, - 0xab2448c900000000, 0xea1553d000000000, 0x29467efb00000000, - 0x687765e200000000, 0xf6793f2f00000000, 0xb748243600000000, - 0x741b091d00000000, 0x352a120400000000, 0xf2bc534b00000000, - 0xb38d485200000000, 0x70de657900000000, 0x31ef7e6000000000, - 0xfef3e6e700000000, 0xbfc2fdfe00000000, 0x7c91d0d500000000, - 0x3da0cbcc00000000, 0xfa368a8300000000, 0xbb07919a00000000, - 0x7854bcb100000000, 0x3965a7a800000000, 0x4b98833b00000000, - 0x0aa9982200000000, 0xc9fab50900000000, 0x88cbae1000000000, - 0x4f5def5f00000000, 0x0e6cf44600000000, 0xcd3fd96d00000000, - 0x8c0ec27400000000, 0x43125af300000000, 0x022341ea00000000, - 0xc1706cc100000000, 0x804177d800000000, 0x47d7369700000000, - 0x06e62d8e00000000, 0xc5b500a500000000, 0x84841bbc00000000, - 0x1a8a417100000000, 0x5bbb5a6800000000, 0x98e8774300000000, - 0xd9d96c5a00000000, 0x1e4f2d1500000000, 0x5f7e360c00000000, - 0x9c2d1b2700000000, 0xdd1c003e00000000, 0x120098b900000000, - 0x533183a000000000, 0x9062ae8b00000000, 0xd153b59200000000, - 0x16c5f4dd00000000, 0x57f4efc400000000, 0x94a7c2ef00000000, - 0xd596d9f600000000, 0xe9bc07ae00000000, 0xa88d1cb700000000, - 0x6bde319c00000000, 0x2aef2a8500000000, 0xed796bca00000000, - 0xac4870d300000000, 0x6f1b5df800000000, 0x2e2a46e100000000, - 0xe136de6600000000, 0xa007c57f00000000, 0x6354e85400000000, - 0x2265f34d00000000, 0xe5f3b20200000000, 0xa4c2a91b00000000, - 0x6791843000000000, 0x26a09f2900000000, 0xb8aec5e400000000, - 0xf99fdefd00000000, 0x3accf3d600000000, 0x7bfde8cf00000000, - 0xbc6ba98000000000, 0xfd5ab29900000000, 0x3e099fb200000000, - 0x7f3884ab00000000, 0xb0241c2c00000000, 0xf115073500000000, - 0x32462a1e00000000, 0x7377310700000000, 0xb4e1704800000000, - 0xf5d06b5100000000, 0x3683467a00000000, 0x77b25d6300000000, - 0x4ed7facb00000000, 0x0fe6e1d200000000, 0xccb5ccf900000000, - 0x8d84d7e000000000, 0x4a1296af00000000, 0x0b238db600000000, - 0xc870a09d00000000, 0x8941bb8400000000, 0x465d230300000000, - 0x076c381a00000000, 0xc43f153100000000, 0x850e0e2800000000, - 0x42984f6700000000, 0x03a9547e00000000, 0xc0fa795500000000, - 0x81cb624c00000000, 0x1fc5388100000000, 0x5ef4239800000000, - 0x9da70eb300000000, 0xdc9615aa00000000, 0x1b0054e500000000, - 0x5a314ffc00000000, 0x996262d700000000, 0xd85379ce00000000, - 0x174fe14900000000, 0x567efa5000000000, 0x952dd77b00000000, - 0xd41ccc6200000000, 0x138a8d2d00000000, 0x52bb963400000000, - 0x91e8bb1f00000000, 0xd0d9a00600000000, 0xecf37e5e00000000, - 0xadc2654700000000, 0x6e91486c00000000, 0x2fa0537500000000, - 0xe836123a00000000, 0xa907092300000000, 0x6a54240800000000, - 0x2b653f1100000000, 0xe479a79600000000, 0xa548bc8f00000000, - 0x661b91a400000000, 0x272a8abd00000000, 0xe0bccbf200000000, - 0xa18dd0eb00000000, 0x62defdc000000000, 0x23efe6d900000000, - 0xbde1bc1400000000, 0xfcd0a70d00000000, 0x3f838a2600000000, - 0x7eb2913f00000000, 0xb924d07000000000, 0xf815cb6900000000, - 0x3b46e64200000000, 0x7a77fd5b00000000, 0xb56b65dc00000000, - 0xf45a7ec500000000, 0x370953ee00000000, 0x763848f700000000, - 0xb1ae09b800000000, 0xf09f12a100000000, 0x33cc3f8a00000000, - 0x72fd249300000000}, - {0x0000000000000000, 0x376ac20100000000, 0x6ed4840300000000, - 0x59be460200000000, 0xdca8090700000000, 0xebc2cb0600000000, - 0xb27c8d0400000000, 0x85164f0500000000, 0xb851130e00000000, - 0x8f3bd10f00000000, 0xd685970d00000000, 0xe1ef550c00000000, - 0x64f91a0900000000, 0x5393d80800000000, 0x0a2d9e0a00000000, - 0x3d475c0b00000000, 0x70a3261c00000000, 0x47c9e41d00000000, - 0x1e77a21f00000000, 0x291d601e00000000, 0xac0b2f1b00000000, - 0x9b61ed1a00000000, 0xc2dfab1800000000, 0xf5b5691900000000, - 0xc8f2351200000000, 0xff98f71300000000, 0xa626b11100000000, - 0x914c731000000000, 0x145a3c1500000000, 0x2330fe1400000000, - 0x7a8eb81600000000, 0x4de47a1700000000, 0xe0464d3800000000, - 0xd72c8f3900000000, 0x8e92c93b00000000, 0xb9f80b3a00000000, - 0x3cee443f00000000, 0x0b84863e00000000, 0x523ac03c00000000, - 0x6550023d00000000, 0x58175e3600000000, 0x6f7d9c3700000000, - 0x36c3da3500000000, 0x01a9183400000000, 0x84bf573100000000, - 0xb3d5953000000000, 0xea6bd33200000000, 0xdd01113300000000, - 0x90e56b2400000000, 0xa78fa92500000000, 0xfe31ef2700000000, - 0xc95b2d2600000000, 0x4c4d622300000000, 0x7b27a02200000000, - 0x2299e62000000000, 0x15f3242100000000, 0x28b4782a00000000, - 0x1fdeba2b00000000, 0x4660fc2900000000, 0x710a3e2800000000, - 0xf41c712d00000000, 0xc376b32c00000000, 0x9ac8f52e00000000, - 0xada2372f00000000, 0xc08d9a7000000000, 0xf7e7587100000000, - 0xae591e7300000000, 0x9933dc7200000000, 0x1c25937700000000, - 0x2b4f517600000000, 0x72f1177400000000, 0x459bd57500000000, - 0x78dc897e00000000, 0x4fb64b7f00000000, 0x16080d7d00000000, - 0x2162cf7c00000000, 0xa474807900000000, 0x931e427800000000, - 0xcaa0047a00000000, 0xfdcac67b00000000, 0xb02ebc6c00000000, - 0x87447e6d00000000, 0xdefa386f00000000, 0xe990fa6e00000000, - 0x6c86b56b00000000, 0x5bec776a00000000, 0x0252316800000000, - 0x3538f36900000000, 0x087faf6200000000, 0x3f156d6300000000, - 0x66ab2b6100000000, 0x51c1e96000000000, 0xd4d7a66500000000, - 0xe3bd646400000000, 0xba03226600000000, 0x8d69e06700000000, - 0x20cbd74800000000, 0x17a1154900000000, 0x4e1f534b00000000, - 0x7975914a00000000, 0xfc63de4f00000000, 0xcb091c4e00000000, - 0x92b75a4c00000000, 0xa5dd984d00000000, 0x989ac44600000000, - 0xaff0064700000000, 0xf64e404500000000, 0xc124824400000000, - 0x4432cd4100000000, 0x73580f4000000000, 0x2ae6494200000000, - 0x1d8c8b4300000000, 0x5068f15400000000, 0x6702335500000000, - 0x3ebc755700000000, 0x09d6b75600000000, 0x8cc0f85300000000, - 0xbbaa3a5200000000, 0xe2147c5000000000, 0xd57ebe5100000000, - 0xe839e25a00000000, 0xdf53205b00000000, 0x86ed665900000000, - 0xb187a45800000000, 0x3491eb5d00000000, 0x03fb295c00000000, - 0x5a456f5e00000000, 0x6d2fad5f00000000, 0x801b35e100000000, - 0xb771f7e000000000, 0xeecfb1e200000000, 0xd9a573e300000000, - 0x5cb33ce600000000, 0x6bd9fee700000000, 0x3267b8e500000000, - 0x050d7ae400000000, 0x384a26ef00000000, 0x0f20e4ee00000000, - 0x569ea2ec00000000, 0x61f460ed00000000, 0xe4e22fe800000000, - 0xd388ede900000000, 0x8a36abeb00000000, 0xbd5c69ea00000000, - 0xf0b813fd00000000, 0xc7d2d1fc00000000, 0x9e6c97fe00000000, - 0xa90655ff00000000, 0x2c101afa00000000, 0x1b7ad8fb00000000, - 0x42c49ef900000000, 0x75ae5cf800000000, 0x48e900f300000000, - 0x7f83c2f200000000, 0x263d84f000000000, 0x115746f100000000, - 0x944109f400000000, 0xa32bcbf500000000, 0xfa958df700000000, - 0xcdff4ff600000000, 0x605d78d900000000, 0x5737bad800000000, - 0x0e89fcda00000000, 0x39e33edb00000000, 0xbcf571de00000000, - 0x8b9fb3df00000000, 0xd221f5dd00000000, 0xe54b37dc00000000, - 0xd80c6bd700000000, 0xef66a9d600000000, 0xb6d8efd400000000, - 0x81b22dd500000000, 0x04a462d000000000, 0x33cea0d100000000, - 0x6a70e6d300000000, 0x5d1a24d200000000, 0x10fe5ec500000000, - 0x27949cc400000000, 0x7e2adac600000000, 0x494018c700000000, - 0xcc5657c200000000, 0xfb3c95c300000000, 0xa282d3c100000000, - 0x95e811c000000000, 0xa8af4dcb00000000, 0x9fc58fca00000000, - 0xc67bc9c800000000, 0xf1110bc900000000, 0x740744cc00000000, - 0x436d86cd00000000, 0x1ad3c0cf00000000, 0x2db902ce00000000, - 0x4096af9100000000, 0x77fc6d9000000000, 0x2e422b9200000000, - 0x1928e99300000000, 0x9c3ea69600000000, 0xab54649700000000, - 0xf2ea229500000000, 0xc580e09400000000, 0xf8c7bc9f00000000, - 0xcfad7e9e00000000, 0x9613389c00000000, 0xa179fa9d00000000, - 0x246fb59800000000, 0x1305779900000000, 0x4abb319b00000000, - 0x7dd1f39a00000000, 0x3035898d00000000, 0x075f4b8c00000000, - 0x5ee10d8e00000000, 0x698bcf8f00000000, 0xec9d808a00000000, - 0xdbf7428b00000000, 0x8249048900000000, 0xb523c68800000000, - 0x88649a8300000000, 0xbf0e588200000000, 0xe6b01e8000000000, - 0xd1dadc8100000000, 0x54cc938400000000, 0x63a6518500000000, - 0x3a18178700000000, 0x0d72d58600000000, 0xa0d0e2a900000000, - 0x97ba20a800000000, 0xce0466aa00000000, 0xf96ea4ab00000000, - 0x7c78ebae00000000, 0x4b1229af00000000, 0x12ac6fad00000000, - 0x25c6adac00000000, 0x1881f1a700000000, 0x2feb33a600000000, - 0x765575a400000000, 0x413fb7a500000000, 0xc429f8a000000000, - 0xf3433aa100000000, 0xaafd7ca300000000, 0x9d97bea200000000, - 0xd073c4b500000000, 0xe71906b400000000, 0xbea740b600000000, - 0x89cd82b700000000, 0x0cdbcdb200000000, 0x3bb10fb300000000, - 0x620f49b100000000, 0x55658bb000000000, 0x6822d7bb00000000, - 0x5f4815ba00000000, 0x06f653b800000000, 0x319c91b900000000, - 0xb48adebc00000000, 0x83e01cbd00000000, 0xda5e5abf00000000, - 0xed3498be00000000}, - {0x0000000000000000, 0x6567bcb800000000, 0x8bc809aa00000000, - 0xeeafb51200000000, 0x5797628f00000000, 0x32f0de3700000000, - 0xdc5f6b2500000000, 0xb938d79d00000000, 0xef28b4c500000000, - 0x8a4f087d00000000, 0x64e0bd6f00000000, 0x018701d700000000, - 0xb8bfd64a00000000, 0xddd86af200000000, 0x3377dfe000000000, - 0x5610635800000000, 0x9f57195000000000, 0xfa30a5e800000000, - 0x149f10fa00000000, 0x71f8ac4200000000, 0xc8c07bdf00000000, - 0xada7c76700000000, 0x4308727500000000, 0x266fcecd00000000, - 0x707fad9500000000, 0x1518112d00000000, 0xfbb7a43f00000000, - 0x9ed0188700000000, 0x27e8cf1a00000000, 0x428f73a200000000, - 0xac20c6b000000000, 0xc9477a0800000000, 0x3eaf32a000000000, - 0x5bc88e1800000000, 0xb5673b0a00000000, 0xd00087b200000000, - 0x6938502f00000000, 0x0c5fec9700000000, 0xe2f0598500000000, - 0x8797e53d00000000, 0xd187866500000000, 0xb4e03add00000000, - 0x5a4f8fcf00000000, 0x3f28337700000000, 0x8610e4ea00000000, - 0xe377585200000000, 0x0dd8ed4000000000, 0x68bf51f800000000, - 0xa1f82bf000000000, 0xc49f974800000000, 0x2a30225a00000000, - 0x4f579ee200000000, 0xf66f497f00000000, 0x9308f5c700000000, - 0x7da740d500000000, 0x18c0fc6d00000000, 0x4ed09f3500000000, - 0x2bb7238d00000000, 0xc518969f00000000, 0xa07f2a2700000000, - 0x1947fdba00000000, 0x7c20410200000000, 0x928ff41000000000, - 0xf7e848a800000000, 0x3d58149b00000000, 0x583fa82300000000, - 0xb6901d3100000000, 0xd3f7a18900000000, 0x6acf761400000000, - 0x0fa8caac00000000, 0xe1077fbe00000000, 0x8460c30600000000, - 0xd270a05e00000000, 0xb7171ce600000000, 0x59b8a9f400000000, - 0x3cdf154c00000000, 0x85e7c2d100000000, 0xe0807e6900000000, - 0x0e2fcb7b00000000, 0x6b4877c300000000, 0xa20f0dcb00000000, - 0xc768b17300000000, 0x29c7046100000000, 0x4ca0b8d900000000, - 0xf5986f4400000000, 0x90ffd3fc00000000, 0x7e5066ee00000000, - 0x1b37da5600000000, 0x4d27b90e00000000, 0x284005b600000000, - 0xc6efb0a400000000, 0xa3880c1c00000000, 0x1ab0db8100000000, - 0x7fd7673900000000, 0x9178d22b00000000, 0xf41f6e9300000000, - 0x03f7263b00000000, 0x66909a8300000000, 0x883f2f9100000000, - 0xed58932900000000, 0x546044b400000000, 0x3107f80c00000000, - 0xdfa84d1e00000000, 0xbacff1a600000000, 0xecdf92fe00000000, - 0x89b82e4600000000, 0x67179b5400000000, 0x027027ec00000000, - 0xbb48f07100000000, 0xde2f4cc900000000, 0x3080f9db00000000, - 0x55e7456300000000, 0x9ca03f6b00000000, 0xf9c783d300000000, - 0x176836c100000000, 0x720f8a7900000000, 0xcb375de400000000, - 0xae50e15c00000000, 0x40ff544e00000000, 0x2598e8f600000000, - 0x73888bae00000000, 0x16ef371600000000, 0xf840820400000000, - 0x9d273ebc00000000, 0x241fe92100000000, 0x4178559900000000, - 0xafd7e08b00000000, 0xcab05c3300000000, 0x3bb659ed00000000, - 0x5ed1e55500000000, 0xb07e504700000000, 0xd519ecff00000000, - 0x6c213b6200000000, 0x094687da00000000, 0xe7e932c800000000, - 0x828e8e7000000000, 0xd49eed2800000000, 0xb1f9519000000000, - 0x5f56e48200000000, 0x3a31583a00000000, 0x83098fa700000000, - 0xe66e331f00000000, 0x08c1860d00000000, 0x6da63ab500000000, - 0xa4e140bd00000000, 0xc186fc0500000000, 0x2f29491700000000, - 0x4a4ef5af00000000, 0xf376223200000000, 0x96119e8a00000000, - 0x78be2b9800000000, 0x1dd9972000000000, 0x4bc9f47800000000, - 0x2eae48c000000000, 0xc001fdd200000000, 0xa566416a00000000, - 0x1c5e96f700000000, 0x79392a4f00000000, 0x97969f5d00000000, - 0xf2f123e500000000, 0x05196b4d00000000, 0x607ed7f500000000, - 0x8ed162e700000000, 0xebb6de5f00000000, 0x528e09c200000000, - 0x37e9b57a00000000, 0xd946006800000000, 0xbc21bcd000000000, - 0xea31df8800000000, 0x8f56633000000000, 0x61f9d62200000000, - 0x049e6a9a00000000, 0xbda6bd0700000000, 0xd8c101bf00000000, - 0x366eb4ad00000000, 0x5309081500000000, 0x9a4e721d00000000, - 0xff29cea500000000, 0x11867bb700000000, 0x74e1c70f00000000, - 0xcdd9109200000000, 0xa8beac2a00000000, 0x4611193800000000, - 0x2376a58000000000, 0x7566c6d800000000, 0x10017a6000000000, - 0xfeaecf7200000000, 0x9bc973ca00000000, 0x22f1a45700000000, - 0x479618ef00000000, 0xa939adfd00000000, 0xcc5e114500000000, - 0x06ee4d7600000000, 0x6389f1ce00000000, 0x8d2644dc00000000, - 0xe841f86400000000, 0x51792ff900000000, 0x341e934100000000, - 0xdab1265300000000, 0xbfd69aeb00000000, 0xe9c6f9b300000000, - 0x8ca1450b00000000, 0x620ef01900000000, 0x07694ca100000000, - 0xbe519b3c00000000, 0xdb36278400000000, 0x3599929600000000, - 0x50fe2e2e00000000, 0x99b9542600000000, 0xfcdee89e00000000, - 0x12715d8c00000000, 0x7716e13400000000, 0xce2e36a900000000, - 0xab498a1100000000, 0x45e63f0300000000, 0x208183bb00000000, - 0x7691e0e300000000, 0x13f65c5b00000000, 0xfd59e94900000000, - 0x983e55f100000000, 0x2106826c00000000, 0x44613ed400000000, - 0xaace8bc600000000, 0xcfa9377e00000000, 0x38417fd600000000, - 0x5d26c36e00000000, 0xb389767c00000000, 0xd6eecac400000000, - 0x6fd61d5900000000, 0x0ab1a1e100000000, 0xe41e14f300000000, - 0x8179a84b00000000, 0xd769cb1300000000, 0xb20e77ab00000000, - 0x5ca1c2b900000000, 0x39c67e0100000000, 0x80fea99c00000000, - 0xe599152400000000, 0x0b36a03600000000, 0x6e511c8e00000000, - 0xa716668600000000, 0xc271da3e00000000, 0x2cde6f2c00000000, - 0x49b9d39400000000, 0xf081040900000000, 0x95e6b8b100000000, - 0x7b490da300000000, 0x1e2eb11b00000000, 0x483ed24300000000, - 0x2d596efb00000000, 0xc3f6dbe900000000, 0xa691675100000000, - 0x1fa9b0cc00000000, 0x7ace0c7400000000, 0x9461b96600000000, - 0xf10605de00000000}, - {0x0000000000000000, 0xb029603d00000000, 0x6053c07a00000000, - 0xd07aa04700000000, 0xc0a680f500000000, 0x708fe0c800000000, - 0xa0f5408f00000000, 0x10dc20b200000000, 0xc14b703000000000, - 0x7162100d00000000, 0xa118b04a00000000, 0x1131d07700000000, - 0x01edf0c500000000, 0xb1c490f800000000, 0x61be30bf00000000, - 0xd197508200000000, 0x8297e06000000000, 0x32be805d00000000, - 0xe2c4201a00000000, 0x52ed402700000000, 0x4231609500000000, - 0xf21800a800000000, 0x2262a0ef00000000, 0x924bc0d200000000, - 0x43dc905000000000, 0xf3f5f06d00000000, 0x238f502a00000000, - 0x93a6301700000000, 0x837a10a500000000, 0x3353709800000000, - 0xe329d0df00000000, 0x5300b0e200000000, 0x042fc1c100000000, - 0xb406a1fc00000000, 0x647c01bb00000000, 0xd455618600000000, - 0xc489413400000000, 0x74a0210900000000, 0xa4da814e00000000, - 0x14f3e17300000000, 0xc564b1f100000000, 0x754dd1cc00000000, - 0xa537718b00000000, 0x151e11b600000000, 0x05c2310400000000, - 0xb5eb513900000000, 0x6591f17e00000000, 0xd5b8914300000000, - 0x86b821a100000000, 0x3691419c00000000, 0xe6ebe1db00000000, - 0x56c281e600000000, 0x461ea15400000000, 0xf637c16900000000, - 0x264d612e00000000, 0x9664011300000000, 0x47f3519100000000, - 0xf7da31ac00000000, 0x27a091eb00000000, 0x9789f1d600000000, - 0x8755d16400000000, 0x377cb15900000000, 0xe706111e00000000, - 0x572f712300000000, 0x4958f35800000000, 0xf971936500000000, - 0x290b332200000000, 0x9922531f00000000, 0x89fe73ad00000000, - 0x39d7139000000000, 0xe9adb3d700000000, 0x5984d3ea00000000, - 0x8813836800000000, 0x383ae35500000000, 0xe840431200000000, - 0x5869232f00000000, 0x48b5039d00000000, 0xf89c63a000000000, - 0x28e6c3e700000000, 0x98cfa3da00000000, 0xcbcf133800000000, - 0x7be6730500000000, 0xab9cd34200000000, 0x1bb5b37f00000000, - 0x0b6993cd00000000, 0xbb40f3f000000000, 0x6b3a53b700000000, - 0xdb13338a00000000, 0x0a84630800000000, 0xbaad033500000000, - 0x6ad7a37200000000, 0xdafec34f00000000, 0xca22e3fd00000000, - 0x7a0b83c000000000, 0xaa71238700000000, 0x1a5843ba00000000, - 0x4d77329900000000, 0xfd5e52a400000000, 0x2d24f2e300000000, - 0x9d0d92de00000000, 0x8dd1b26c00000000, 0x3df8d25100000000, - 0xed82721600000000, 0x5dab122b00000000, 0x8c3c42a900000000, - 0x3c15229400000000, 0xec6f82d300000000, 0x5c46e2ee00000000, - 0x4c9ac25c00000000, 0xfcb3a26100000000, 0x2cc9022600000000, - 0x9ce0621b00000000, 0xcfe0d2f900000000, 0x7fc9b2c400000000, - 0xafb3128300000000, 0x1f9a72be00000000, 0x0f46520c00000000, - 0xbf6f323100000000, 0x6f15927600000000, 0xdf3cf24b00000000, - 0x0eaba2c900000000, 0xbe82c2f400000000, 0x6ef862b300000000, - 0xded1028e00000000, 0xce0d223c00000000, 0x7e24420100000000, - 0xae5ee24600000000, 0x1e77827b00000000, 0x92b0e6b100000000, - 0x2299868c00000000, 0xf2e326cb00000000, 0x42ca46f600000000, - 0x5216664400000000, 0xe23f067900000000, 0x3245a63e00000000, - 0x826cc60300000000, 0x53fb968100000000, 0xe3d2f6bc00000000, - 0x33a856fb00000000, 0x838136c600000000, 0x935d167400000000, - 0x2374764900000000, 0xf30ed60e00000000, 0x4327b63300000000, - 0x102706d100000000, 0xa00e66ec00000000, 0x7074c6ab00000000, - 0xc05da69600000000, 0xd081862400000000, 0x60a8e61900000000, - 0xb0d2465e00000000, 0x00fb266300000000, 0xd16c76e100000000, - 0x614516dc00000000, 0xb13fb69b00000000, 0x0116d6a600000000, - 0x11caf61400000000, 0xa1e3962900000000, 0x7199366e00000000, - 0xc1b0565300000000, 0x969f277000000000, 0x26b6474d00000000, - 0xf6cce70a00000000, 0x46e5873700000000, 0x5639a78500000000, - 0xe610c7b800000000, 0x366a67ff00000000, 0x864307c200000000, - 0x57d4574000000000, 0xe7fd377d00000000, 0x3787973a00000000, - 0x87aef70700000000, 0x9772d7b500000000, 0x275bb78800000000, - 0xf72117cf00000000, 0x470877f200000000, 0x1408c71000000000, - 0xa421a72d00000000, 0x745b076a00000000, 0xc472675700000000, - 0xd4ae47e500000000, 0x648727d800000000, 0xb4fd879f00000000, - 0x04d4e7a200000000, 0xd543b72000000000, 0x656ad71d00000000, - 0xb510775a00000000, 0x0539176700000000, 0x15e537d500000000, - 0xa5cc57e800000000, 0x75b6f7af00000000, 0xc59f979200000000, - 0xdbe815e900000000, 0x6bc175d400000000, 0xbbbbd59300000000, - 0x0b92b5ae00000000, 0x1b4e951c00000000, 0xab67f52100000000, - 0x7b1d556600000000, 0xcb34355b00000000, 0x1aa365d900000000, - 0xaa8a05e400000000, 0x7af0a5a300000000, 0xcad9c59e00000000, - 0xda05e52c00000000, 0x6a2c851100000000, 0xba56255600000000, - 0x0a7f456b00000000, 0x597ff58900000000, 0xe95695b400000000, - 0x392c35f300000000, 0x890555ce00000000, 0x99d9757c00000000, - 0x29f0154100000000, 0xf98ab50600000000, 0x49a3d53b00000000, - 0x983485b900000000, 0x281de58400000000, 0xf86745c300000000, - 0x484e25fe00000000, 0x5892054c00000000, 0xe8bb657100000000, - 0x38c1c53600000000, 0x88e8a50b00000000, 0xdfc7d42800000000, - 0x6feeb41500000000, 0xbf94145200000000, 0x0fbd746f00000000, - 0x1f6154dd00000000, 0xaf4834e000000000, 0x7f3294a700000000, - 0xcf1bf49a00000000, 0x1e8ca41800000000, 0xaea5c42500000000, - 0x7edf646200000000, 0xcef6045f00000000, 0xde2a24ed00000000, - 0x6e0344d000000000, 0xbe79e49700000000, 0x0e5084aa00000000, - 0x5d50344800000000, 0xed79547500000000, 0x3d03f43200000000, - 0x8d2a940f00000000, 0x9df6b4bd00000000, 0x2ddfd48000000000, - 0xfda574c700000000, 0x4d8c14fa00000000, 0x9c1b447800000000, - 0x2c32244500000000, 0xfc48840200000000, 0x4c61e43f00000000, - 0x5cbdc48d00000000, 0xec94a4b000000000, 0x3cee04f700000000, - 0x8cc764ca00000000}, - {0x0000000000000000, 0xa5d35ccb00000000, 0x0ba1c84d00000000, - 0xae72948600000000, 0x1642919b00000000, 0xb391cd5000000000, - 0x1de359d600000000, 0xb830051d00000000, 0x6d8253ec00000000, - 0xc8510f2700000000, 0x66239ba100000000, 0xc3f0c76a00000000, - 0x7bc0c27700000000, 0xde139ebc00000000, 0x70610a3a00000000, - 0xd5b256f100000000, 0x9b02d60300000000, 0x3ed18ac800000000, - 0x90a31e4e00000000, 0x3570428500000000, 0x8d40479800000000, - 0x28931b5300000000, 0x86e18fd500000000, 0x2332d31e00000000, - 0xf68085ef00000000, 0x5353d92400000000, 0xfd214da200000000, - 0x58f2116900000000, 0xe0c2147400000000, 0x451148bf00000000, - 0xeb63dc3900000000, 0x4eb080f200000000, 0x3605ac0700000000, - 0x93d6f0cc00000000, 0x3da4644a00000000, 0x9877388100000000, - 0x20473d9c00000000, 0x8594615700000000, 0x2be6f5d100000000, - 0x8e35a91a00000000, 0x5b87ffeb00000000, 0xfe54a32000000000, - 0x502637a600000000, 0xf5f56b6d00000000, 0x4dc56e7000000000, - 0xe81632bb00000000, 0x4664a63d00000000, 0xe3b7faf600000000, - 0xad077a0400000000, 0x08d426cf00000000, 0xa6a6b24900000000, - 0x0375ee8200000000, 0xbb45eb9f00000000, 0x1e96b75400000000, - 0xb0e423d200000000, 0x15377f1900000000, 0xc08529e800000000, - 0x6556752300000000, 0xcb24e1a500000000, 0x6ef7bd6e00000000, - 0xd6c7b87300000000, 0x7314e4b800000000, 0xdd66703e00000000, - 0x78b52cf500000000, 0x6c0a580f00000000, 0xc9d904c400000000, - 0x67ab904200000000, 0xc278cc8900000000, 0x7a48c99400000000, - 0xdf9b955f00000000, 0x71e901d900000000, 0xd43a5d1200000000, - 0x01880be300000000, 0xa45b572800000000, 0x0a29c3ae00000000, - 0xaffa9f6500000000, 0x17ca9a7800000000, 0xb219c6b300000000, - 0x1c6b523500000000, 0xb9b80efe00000000, 0xf7088e0c00000000, - 0x52dbd2c700000000, 0xfca9464100000000, 0x597a1a8a00000000, - 0xe14a1f9700000000, 0x4499435c00000000, 0xeaebd7da00000000, - 0x4f388b1100000000, 0x9a8adde000000000, 0x3f59812b00000000, - 0x912b15ad00000000, 0x34f8496600000000, 0x8cc84c7b00000000, - 0x291b10b000000000, 0x8769843600000000, 0x22bad8fd00000000, - 0x5a0ff40800000000, 0xffdca8c300000000, 0x51ae3c4500000000, - 0xf47d608e00000000, 0x4c4d659300000000, 0xe99e395800000000, - 0x47ecadde00000000, 0xe23ff11500000000, 0x378da7e400000000, - 0x925efb2f00000000, 0x3c2c6fa900000000, 0x99ff336200000000, - 0x21cf367f00000000, 0x841c6ab400000000, 0x2a6efe3200000000, - 0x8fbda2f900000000, 0xc10d220b00000000, 0x64de7ec000000000, - 0xcaacea4600000000, 0x6f7fb68d00000000, 0xd74fb39000000000, - 0x729cef5b00000000, 0xdcee7bdd00000000, 0x793d271600000000, - 0xac8f71e700000000, 0x095c2d2c00000000, 0xa72eb9aa00000000, - 0x02fde56100000000, 0xbacde07c00000000, 0x1f1ebcb700000000, - 0xb16c283100000000, 0x14bf74fa00000000, 0xd814b01e00000000, - 0x7dc7ecd500000000, 0xd3b5785300000000, 0x7666249800000000, - 0xce56218500000000, 0x6b857d4e00000000, 0xc5f7e9c800000000, - 0x6024b50300000000, 0xb596e3f200000000, 0x1045bf3900000000, - 0xbe372bbf00000000, 0x1be4777400000000, 0xa3d4726900000000, - 0x06072ea200000000, 0xa875ba2400000000, 0x0da6e6ef00000000, - 0x4316661d00000000, 0xe6c53ad600000000, 0x48b7ae5000000000, - 0xed64f29b00000000, 0x5554f78600000000, 0xf087ab4d00000000, - 0x5ef53fcb00000000, 0xfb26630000000000, 0x2e9435f100000000, - 0x8b47693a00000000, 0x2535fdbc00000000, 0x80e6a17700000000, - 0x38d6a46a00000000, 0x9d05f8a100000000, 0x33776c2700000000, - 0x96a430ec00000000, 0xee111c1900000000, 0x4bc240d200000000, - 0xe5b0d45400000000, 0x4063889f00000000, 0xf8538d8200000000, - 0x5d80d14900000000, 0xf3f245cf00000000, 0x5621190400000000, - 0x83934ff500000000, 0x2640133e00000000, 0x883287b800000000, - 0x2de1db7300000000, 0x95d1de6e00000000, 0x300282a500000000, - 0x9e70162300000000, 0x3ba34ae800000000, 0x7513ca1a00000000, - 0xd0c096d100000000, 0x7eb2025700000000, 0xdb615e9c00000000, - 0x63515b8100000000, 0xc682074a00000000, 0x68f093cc00000000, - 0xcd23cf0700000000, 0x189199f600000000, 0xbd42c53d00000000, - 0x133051bb00000000, 0xb6e30d7000000000, 0x0ed3086d00000000, - 0xab0054a600000000, 0x0572c02000000000, 0xa0a19ceb00000000, - 0xb41ee81100000000, 0x11cdb4da00000000, 0xbfbf205c00000000, - 0x1a6c7c9700000000, 0xa25c798a00000000, 0x078f254100000000, - 0xa9fdb1c700000000, 0x0c2eed0c00000000, 0xd99cbbfd00000000, - 0x7c4fe73600000000, 0xd23d73b000000000, 0x77ee2f7b00000000, - 0xcfde2a6600000000, 0x6a0d76ad00000000, 0xc47fe22b00000000, - 0x61acbee000000000, 0x2f1c3e1200000000, 0x8acf62d900000000, - 0x24bdf65f00000000, 0x816eaa9400000000, 0x395eaf8900000000, - 0x9c8df34200000000, 0x32ff67c400000000, 0x972c3b0f00000000, - 0x429e6dfe00000000, 0xe74d313500000000, 0x493fa5b300000000, - 0xececf97800000000, 0x54dcfc6500000000, 0xf10fa0ae00000000, - 0x5f7d342800000000, 0xfaae68e300000000, 0x821b441600000000, - 0x27c818dd00000000, 0x89ba8c5b00000000, 0x2c69d09000000000, - 0x9459d58d00000000, 0x318a894600000000, 0x9ff81dc000000000, - 0x3a2b410b00000000, 0xef9917fa00000000, 0x4a4a4b3100000000, - 0xe438dfb700000000, 0x41eb837c00000000, 0xf9db866100000000, - 0x5c08daaa00000000, 0xf27a4e2c00000000, 0x57a912e700000000, - 0x1919921500000000, 0xbccacede00000000, 0x12b85a5800000000, - 0xb76b069300000000, 0x0f5b038e00000000, 0xaa885f4500000000, - 0x04facbc300000000, 0xa129970800000000, 0x749bc1f900000000, - 0xd1489d3200000000, 0x7f3a09b400000000, 0xdae9557f00000000, - 0x62d9506200000000, 0xc70a0ca900000000, 0x6978982f00000000, - 0xccabc4e400000000}, - {0x0000000000000000, 0xb40b77a600000000, 0x29119f9700000000, - 0x9d1ae83100000000, 0x13244ff400000000, 0xa72f385200000000, - 0x3a35d06300000000, 0x8e3ea7c500000000, 0x674eef3300000000, - 0xd345989500000000, 0x4e5f70a400000000, 0xfa54070200000000, - 0x746aa0c700000000, 0xc061d76100000000, 0x5d7b3f5000000000, - 0xe97048f600000000, 0xce9cde6700000000, 0x7a97a9c100000000, - 0xe78d41f000000000, 0x5386365600000000, 0xddb8919300000000, - 0x69b3e63500000000, 0xf4a90e0400000000, 0x40a279a200000000, - 0xa9d2315400000000, 0x1dd946f200000000, 0x80c3aec300000000, - 0x34c8d96500000000, 0xbaf67ea000000000, 0x0efd090600000000, - 0x93e7e13700000000, 0x27ec969100000000, 0x9c39bdcf00000000, - 0x2832ca6900000000, 0xb528225800000000, 0x012355fe00000000, - 0x8f1df23b00000000, 0x3b16859d00000000, 0xa60c6dac00000000, - 0x12071a0a00000000, 0xfb7752fc00000000, 0x4f7c255a00000000, - 0xd266cd6b00000000, 0x666dbacd00000000, 0xe8531d0800000000, - 0x5c586aae00000000, 0xc142829f00000000, 0x7549f53900000000, - 0x52a563a800000000, 0xe6ae140e00000000, 0x7bb4fc3f00000000, - 0xcfbf8b9900000000, 0x41812c5c00000000, 0xf58a5bfa00000000, - 0x6890b3cb00000000, 0xdc9bc46d00000000, 0x35eb8c9b00000000, - 0x81e0fb3d00000000, 0x1cfa130c00000000, 0xa8f164aa00000000, - 0x26cfc36f00000000, 0x92c4b4c900000000, 0x0fde5cf800000000, - 0xbbd52b5e00000000, 0x79750b4400000000, 0xcd7e7ce200000000, - 0x506494d300000000, 0xe46fe37500000000, 0x6a5144b000000000, - 0xde5a331600000000, 0x4340db2700000000, 0xf74bac8100000000, - 0x1e3be47700000000, 0xaa3093d100000000, 0x372a7be000000000, - 0x83210c4600000000, 0x0d1fab8300000000, 0xb914dc2500000000, - 0x240e341400000000, 0x900543b200000000, 0xb7e9d52300000000, - 0x03e2a28500000000, 0x9ef84ab400000000, 0x2af33d1200000000, - 0xa4cd9ad700000000, 0x10c6ed7100000000, 0x8ddc054000000000, - 0x39d772e600000000, 0xd0a73a1000000000, 0x64ac4db600000000, - 0xf9b6a58700000000, 0x4dbdd22100000000, 0xc38375e400000000, - 0x7788024200000000, 0xea92ea7300000000, 0x5e999dd500000000, - 0xe54cb68b00000000, 0x5147c12d00000000, 0xcc5d291c00000000, - 0x78565eba00000000, 0xf668f97f00000000, 0x42638ed900000000, - 0xdf7966e800000000, 0x6b72114e00000000, 0x820259b800000000, - 0x36092e1e00000000, 0xab13c62f00000000, 0x1f18b18900000000, - 0x9126164c00000000, 0x252d61ea00000000, 0xb83789db00000000, - 0x0c3cfe7d00000000, 0x2bd068ec00000000, 0x9fdb1f4a00000000, - 0x02c1f77b00000000, 0xb6ca80dd00000000, 0x38f4271800000000, - 0x8cff50be00000000, 0x11e5b88f00000000, 0xa5eecf2900000000, - 0x4c9e87df00000000, 0xf895f07900000000, 0x658f184800000000, - 0xd1846fee00000000, 0x5fbac82b00000000, 0xebb1bf8d00000000, - 0x76ab57bc00000000, 0xc2a0201a00000000, 0xf2ea168800000000, - 0x46e1612e00000000, 0xdbfb891f00000000, 0x6ff0feb900000000, - 0xe1ce597c00000000, 0x55c52eda00000000, 0xc8dfc6eb00000000, - 0x7cd4b14d00000000, 0x95a4f9bb00000000, 0x21af8e1d00000000, - 0xbcb5662c00000000, 0x08be118a00000000, 0x8680b64f00000000, - 0x328bc1e900000000, 0xaf9129d800000000, 0x1b9a5e7e00000000, - 0x3c76c8ef00000000, 0x887dbf4900000000, 0x1567577800000000, - 0xa16c20de00000000, 0x2f52871b00000000, 0x9b59f0bd00000000, - 0x0643188c00000000, 0xb2486f2a00000000, 0x5b3827dc00000000, - 0xef33507a00000000, 0x7229b84b00000000, 0xc622cfed00000000, - 0x481c682800000000, 0xfc171f8e00000000, 0x610df7bf00000000, - 0xd506801900000000, 0x6ed3ab4700000000, 0xdad8dce100000000, - 0x47c234d000000000, 0xf3c9437600000000, 0x7df7e4b300000000, - 0xc9fc931500000000, 0x54e67b2400000000, 0xe0ed0c8200000000, - 0x099d447400000000, 0xbd9633d200000000, 0x208cdbe300000000, - 0x9487ac4500000000, 0x1ab90b8000000000, 0xaeb27c2600000000, - 0x33a8941700000000, 0x87a3e3b100000000, 0xa04f752000000000, - 0x1444028600000000, 0x895eeab700000000, 0x3d559d1100000000, - 0xb36b3ad400000000, 0x07604d7200000000, 0x9a7aa54300000000, - 0x2e71d2e500000000, 0xc7019a1300000000, 0x730aedb500000000, - 0xee10058400000000, 0x5a1b722200000000, 0xd425d5e700000000, - 0x602ea24100000000, 0xfd344a7000000000, 0x493f3dd600000000, - 0x8b9f1dcc00000000, 0x3f946a6a00000000, 0xa28e825b00000000, - 0x1685f5fd00000000, 0x98bb523800000000, 0x2cb0259e00000000, - 0xb1aacdaf00000000, 0x05a1ba0900000000, 0xecd1f2ff00000000, - 0x58da855900000000, 0xc5c06d6800000000, 0x71cb1ace00000000, - 0xfff5bd0b00000000, 0x4bfecaad00000000, 0xd6e4229c00000000, - 0x62ef553a00000000, 0x4503c3ab00000000, 0xf108b40d00000000, - 0x6c125c3c00000000, 0xd8192b9a00000000, 0x56278c5f00000000, - 0xe22cfbf900000000, 0x7f3613c800000000, 0xcb3d646e00000000, - 0x224d2c9800000000, 0x96465b3e00000000, 0x0b5cb30f00000000, - 0xbf57c4a900000000, 0x3169636c00000000, 0x856214ca00000000, - 0x1878fcfb00000000, 0xac738b5d00000000, 0x17a6a00300000000, - 0xa3add7a500000000, 0x3eb73f9400000000, 0x8abc483200000000, - 0x0482eff700000000, 0xb089985100000000, 0x2d93706000000000, - 0x999807c600000000, 0x70e84f3000000000, 0xc4e3389600000000, - 0x59f9d0a700000000, 0xedf2a70100000000, 0x63cc00c400000000, - 0xd7c7776200000000, 0x4add9f5300000000, 0xfed6e8f500000000, - 0xd93a7e6400000000, 0x6d3109c200000000, 0xf02be1f300000000, - 0x4420965500000000, 0xca1e319000000000, 0x7e15463600000000, - 0xe30fae0700000000, 0x5704d9a100000000, 0xbe74915700000000, - 0x0a7fe6f100000000, 0x97650ec000000000, 0x236e796600000000, - 0xad50dea300000000, 0x195ba90500000000, 0x8441413400000000, - 0x304a369200000000}, - {0x0000000000000000, 0x9e00aacc00000000, 0x7d07254200000000, - 0xe3078f8e00000000, 0xfa0e4a8400000000, 0x640ee04800000000, - 0x87096fc600000000, 0x1909c50a00000000, 0xb51be5d300000000, - 0x2b1b4f1f00000000, 0xc81cc09100000000, 0x561c6a5d00000000, - 0x4f15af5700000000, 0xd115059b00000000, 0x32128a1500000000, - 0xac1220d900000000, 0x2b31bb7c00000000, 0xb53111b000000000, - 0x56369e3e00000000, 0xc83634f200000000, 0xd13ff1f800000000, - 0x4f3f5b3400000000, 0xac38d4ba00000000, 0x32387e7600000000, - 0x9e2a5eaf00000000, 0x002af46300000000, 0xe32d7bed00000000, - 0x7d2dd12100000000, 0x6424142b00000000, 0xfa24bee700000000, - 0x1923316900000000, 0x87239ba500000000, 0x566276f900000000, - 0xc862dc3500000000, 0x2b6553bb00000000, 0xb565f97700000000, - 0xac6c3c7d00000000, 0x326c96b100000000, 0xd16b193f00000000, - 0x4f6bb3f300000000, 0xe379932a00000000, 0x7d7939e600000000, - 0x9e7eb66800000000, 0x007e1ca400000000, 0x1977d9ae00000000, - 0x8777736200000000, 0x6470fcec00000000, 0xfa70562000000000, - 0x7d53cd8500000000, 0xe353674900000000, 0x0054e8c700000000, - 0x9e54420b00000000, 0x875d870100000000, 0x195d2dcd00000000, - 0xfa5aa24300000000, 0x645a088f00000000, 0xc848285600000000, - 0x5648829a00000000, 0xb54f0d1400000000, 0x2b4fa7d800000000, - 0x324662d200000000, 0xac46c81e00000000, 0x4f41479000000000, - 0xd141ed5c00000000, 0xedc29d2900000000, 0x73c237e500000000, - 0x90c5b86b00000000, 0x0ec512a700000000, 0x17ccd7ad00000000, - 0x89cc7d6100000000, 0x6acbf2ef00000000, 0xf4cb582300000000, - 0x58d978fa00000000, 0xc6d9d23600000000, 0x25de5db800000000, - 0xbbdef77400000000, 0xa2d7327e00000000, 0x3cd798b200000000, - 0xdfd0173c00000000, 0x41d0bdf000000000, 0xc6f3265500000000, - 0x58f38c9900000000, 0xbbf4031700000000, 0x25f4a9db00000000, - 0x3cfd6cd100000000, 0xa2fdc61d00000000, 0x41fa499300000000, - 0xdffae35f00000000, 0x73e8c38600000000, 0xede8694a00000000, - 0x0eefe6c400000000, 0x90ef4c0800000000, 0x89e6890200000000, - 0x17e623ce00000000, 0xf4e1ac4000000000, 0x6ae1068c00000000, - 0xbba0ebd000000000, 0x25a0411c00000000, 0xc6a7ce9200000000, - 0x58a7645e00000000, 0x41aea15400000000, 0xdfae0b9800000000, - 0x3ca9841600000000, 0xa2a92eda00000000, 0x0ebb0e0300000000, - 0x90bba4cf00000000, 0x73bc2b4100000000, 0xedbc818d00000000, - 0xf4b5448700000000, 0x6ab5ee4b00000000, 0x89b261c500000000, - 0x17b2cb0900000000, 0x909150ac00000000, 0x0e91fa6000000000, - 0xed9675ee00000000, 0x7396df2200000000, 0x6a9f1a2800000000, - 0xf49fb0e400000000, 0x17983f6a00000000, 0x899895a600000000, - 0x258ab57f00000000, 0xbb8a1fb300000000, 0x588d903d00000000, - 0xc68d3af100000000, 0xdf84fffb00000000, 0x4184553700000000, - 0xa283dab900000000, 0x3c83707500000000, 0xda853b5300000000, - 0x4485919f00000000, 0xa7821e1100000000, 0x3982b4dd00000000, - 0x208b71d700000000, 0xbe8bdb1b00000000, 0x5d8c549500000000, - 0xc38cfe5900000000, 0x6f9ede8000000000, 0xf19e744c00000000, - 0x1299fbc200000000, 0x8c99510e00000000, 0x9590940400000000, - 0x0b903ec800000000, 0xe897b14600000000, 0x76971b8a00000000, - 0xf1b4802f00000000, 0x6fb42ae300000000, 0x8cb3a56d00000000, - 0x12b30fa100000000, 0x0bbacaab00000000, 0x95ba606700000000, - 0x76bdefe900000000, 0xe8bd452500000000, 0x44af65fc00000000, - 0xdaafcf3000000000, 0x39a840be00000000, 0xa7a8ea7200000000, - 0xbea12f7800000000, 0x20a185b400000000, 0xc3a60a3a00000000, - 0x5da6a0f600000000, 0x8ce74daa00000000, 0x12e7e76600000000, - 0xf1e068e800000000, 0x6fe0c22400000000, 0x76e9072e00000000, - 0xe8e9ade200000000, 0x0bee226c00000000, 0x95ee88a000000000, - 0x39fca87900000000, 0xa7fc02b500000000, 0x44fb8d3b00000000, - 0xdafb27f700000000, 0xc3f2e2fd00000000, 0x5df2483100000000, - 0xbef5c7bf00000000, 0x20f56d7300000000, 0xa7d6f6d600000000, - 0x39d65c1a00000000, 0xdad1d39400000000, 0x44d1795800000000, - 0x5dd8bc5200000000, 0xc3d8169e00000000, 0x20df991000000000, - 0xbedf33dc00000000, 0x12cd130500000000, 0x8ccdb9c900000000, - 0x6fca364700000000, 0xf1ca9c8b00000000, 0xe8c3598100000000, - 0x76c3f34d00000000, 0x95c47cc300000000, 0x0bc4d60f00000000, - 0x3747a67a00000000, 0xa9470cb600000000, 0x4a40833800000000, - 0xd44029f400000000, 0xcd49ecfe00000000, 0x5349463200000000, - 0xb04ec9bc00000000, 0x2e4e637000000000, 0x825c43a900000000, - 0x1c5ce96500000000, 0xff5b66eb00000000, 0x615bcc2700000000, - 0x7852092d00000000, 0xe652a3e100000000, 0x05552c6f00000000, - 0x9b5586a300000000, 0x1c761d0600000000, 0x8276b7ca00000000, - 0x6171384400000000, 0xff71928800000000, 0xe678578200000000, - 0x7878fd4e00000000, 0x9b7f72c000000000, 0x057fd80c00000000, - 0xa96df8d500000000, 0x376d521900000000, 0xd46add9700000000, - 0x4a6a775b00000000, 0x5363b25100000000, 0xcd63189d00000000, - 0x2e64971300000000, 0xb0643ddf00000000, 0x6125d08300000000, - 0xff257a4f00000000, 0x1c22f5c100000000, 0x82225f0d00000000, - 0x9b2b9a0700000000, 0x052b30cb00000000, 0xe62cbf4500000000, - 0x782c158900000000, 0xd43e355000000000, 0x4a3e9f9c00000000, - 0xa939101200000000, 0x3739bade00000000, 0x2e307fd400000000, - 0xb030d51800000000, 0x53375a9600000000, 0xcd37f05a00000000, - 0x4a146bff00000000, 0xd414c13300000000, 0x37134ebd00000000, - 0xa913e47100000000, 0xb01a217b00000000, 0x2e1a8bb700000000, - 0xcd1d043900000000, 0x531daef500000000, 0xff0f8e2c00000000, - 0x610f24e000000000, 0x8208ab6e00000000, 0x1c0801a200000000, - 0x0501c4a800000000, 0x9b016e6400000000, 0x7806e1ea00000000, - 0xe6064b2600000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, - 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, - 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, - 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, - 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, - 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, - 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, - 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, - 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, - 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, - 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, - 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, - 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, - 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, - 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, - 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, - 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, - 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, - 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, - 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, - 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, - 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, - 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, - 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, - 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, - 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, - 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, - 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, - 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, - 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, - 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, - 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, - 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, - 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, - 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, - 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, - 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, - 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, - 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, - 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, - 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, - 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, - 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, - 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, - 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, - 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, - 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, - 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, - 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, - 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, - 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, - 0xde0506f1}, - {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, - 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, - 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, - 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, - 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, - 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, - 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, - 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, - 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, - 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, - 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, - 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, - 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, - 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, - 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, - 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, - 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, - 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, - 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, - 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, - 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, - 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, - 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, - 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, - 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, - 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, - 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, - 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, - 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, - 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, - 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, - 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, - 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, - 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, - 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, - 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, - 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, - 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, - 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, - 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, - 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, - 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, - 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, - 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, - 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, - 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, - 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, - 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, - 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, - 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, - 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, - 0xbe9834ed}, - {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, - 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, - 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, - 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, - 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, - 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, - 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, - 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, - 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, - 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, - 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, - 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, - 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, - 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, - 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, - 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, - 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, - 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, - 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, - 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, - 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, - 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, - 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, - 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, - 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, - 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, - 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, - 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, - 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, - 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, - 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, - 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, - 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, - 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, - 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, - 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, - 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, - 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, - 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, - 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, - 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, - 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, - 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, - 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, - 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, - 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, - 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, - 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, - 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, - 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, - 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, - 0x9324fd72}, - {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, - 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, - 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, - 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, - 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, - 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, - 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, - 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, - 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, - 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, - 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, - 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, - 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, - 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, - 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, - 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, - 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, - 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, - 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, - 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, - 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, - 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, - 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, - 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, - 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, - 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, - 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, - 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, - 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, - 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, - 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, - 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, - 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, - 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, - 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, - 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, - 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, - 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, - 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, - 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, - 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, - 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, - 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, - 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, - 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, - 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, - 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, - 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, - 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, - 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, - 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, - 0x8def022d}, - {0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, 0x04c56c64, - 0x45f4777d, 0x86a75a56, 0xc796414f, 0x088ad9c8, 0x49bbc2d1, - 0x8ae8effa, 0xcbd9f4e3, 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e, - 0xcf1c9887, 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61, - 0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, 0x59981b82, - 0x18a9009b, 0xdbfa2db0, 0x9acb36a9, 0x5d5d77e6, 0x1c6c6cff, - 0xdf3f41d4, 0x9e0e5acd, 0xa2248495, 0xe3159f8c, 0x2046b2a7, - 0x6177a9be, 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da, - 0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, 0xae6b3139, - 0xef5a2a20, 0x2c09070b, 0x6d381c12, 0xf33646df, 0xb2075dc6, - 0x715470ed, 0x30656bf4, 0xf7f32abb, 0xb6c231a2, 0x75911c89, - 0x34a00790, 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c, - 0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, 0x054f79f0, - 0x447e62e9, 0x872d4fc2, 0xc61c54db, 0x018a1594, 0x40bb0e8d, - 0x83e823a6, 0xc2d938bf, 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a, - 0xce968d13, 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177, - 0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, 0x5098d7de, - 0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, 0x5cd76272, 0x1de6796b, - 0xdeb55440, 0x9f844f59, 0x58120e16, 0x1923150f, 0xda703824, - 0x9b41233d, 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e, - 0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, 0xafe124ad, - 0xeed03fb4, 0x2d83129f, 0x6cb20986, 0xab2448c9, 0xea1553d0, - 0x29467efb, 0x687765e2, 0xf6793f2f, 0xb7482436, 0x741b091d, - 0x352a1204, 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60, - 0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, 0xfa368a83, - 0xbb07919a, 0x7854bcb1, 0x3965a7a8, 0x4b98833b, 0x0aa99822, - 0xc9fab509, 0x88cbae10, 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d, - 0x8c0ec274, 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8, - 0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, 0x1a8a4171, - 0x5bbb5a68, 0x98e87743, 0xd9d96c5a, 0x1e4f2d15, 0x5f7e360c, - 0x9c2d1b27, 0xdd1c003e, 0x120098b9, 0x533183a0, 0x9062ae8b, - 0xd153b592, 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6, - 0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, 0xed796bca, - 0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, 0xe136de66, 0xa007c57f, - 0x6354e854, 0x2265f34d, 0xe5f3b202, 0xa4c2a91b, 0x67918430, - 0x26a09f29, 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf, - 0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, 0xb0241c2c, - 0xf1150735, 0x32462a1e, 0x73773107, 0xb4e17048, 0xf5d06b51, - 0x3683467a, 0x77b25d63, 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9, - 0x8d84d7e0, 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84, - 0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, 0x42984f67, - 0x03a9547e, 0xc0fa7955, 0x81cb624c, 0x1fc53881, 0x5ef42398, - 0x9da70eb3, 0xdc9615aa, 0x1b0054e5, 0x5a314ffc, 0x996262d7, - 0xd85379ce, 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62, - 0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, 0xecf37e5e, - 0xadc26547, 0x6e91486c, 0x2fa05375, 0xe836123a, 0xa9070923, - 0x6a542408, 0x2b653f11, 0xe479a796, 0xa548bc8f, 0x661b91a4, - 0x272a8abd, 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9, - 0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, 0xb924d070, - 0xf815cb69, 0x3b46e642, 0x7a77fd5b, 0xb56b65dc, 0xf45a7ec5, - 0x370953ee, 0x763848f7, 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a, - 0x72fd2493}, - {0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, 0xdca80907, - 0xebc2cb06, 0xb27c8d04, 0x85164f05, 0xb851130e, 0x8f3bd10f, - 0xd685970d, 0xe1ef550c, 0x64f91a09, 0x5393d808, 0x0a2d9e0a, - 0x3d475c0b, 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e, - 0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, 0xc8f23512, - 0xff98f713, 0xa626b111, 0x914c7310, 0x145a3c15, 0x2330fe14, - 0x7a8eb816, 0x4de47a17, 0xe0464d38, 0xd72c8f39, 0x8e92c93b, - 0xb9f80b3a, 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d, - 0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, 0x84bf5731, - 0xb3d59530, 0xea6bd332, 0xdd011133, 0x90e56b24, 0xa78fa925, - 0xfe31ef27, 0xc95b2d26, 0x4c4d6223, 0x7b27a022, 0x2299e620, - 0x15f32421, 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28, - 0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, 0xc08d9a70, - 0xf7e75871, 0xae591e73, 0x9933dc72, 0x1c259377, 0x2b4f5176, - 0x72f11774, 0x459bd575, 0x78dc897e, 0x4fb64b7f, 0x16080d7d, - 0x2162cf7c, 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b, - 0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, 0x6c86b56b, - 0x5bec776a, 0x02523168, 0x3538f369, 0x087faf62, 0x3f156d63, - 0x66ab2b61, 0x51c1e960, 0xd4d7a665, 0xe3bd6464, 0xba032266, - 0x8d69e067, 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a, - 0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, 0x989ac446, - 0xaff00647, 0xf64e4045, 0xc1248244, 0x4432cd41, 0x73580f40, - 0x2ae64942, 0x1d8c8b43, 0x5068f154, 0x67023355, 0x3ebc7557, - 0x09d6b756, 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51, - 0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, 0x3491eb5d, - 0x03fb295c, 0x5a456f5e, 0x6d2fad5f, 0x801b35e1, 0xb771f7e0, - 0xeecfb1e2, 0xd9a573e3, 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5, - 0x050d7ae4, 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed, - 0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, 0xf0b813fd, - 0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, 0x2c101afa, 0x1b7ad8fb, - 0x42c49ef9, 0x75ae5cf8, 0x48e900f3, 0x7f83c2f2, 0x263d84f0, - 0x115746f1, 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6, - 0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, 0xbcf571de, - 0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, 0xd80c6bd7, 0xef66a9d6, - 0xb6d8efd4, 0x81b22dd5, 0x04a462d0, 0x33cea0d1, 0x6a70e6d3, - 0x5d1a24d2, 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7, - 0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, 0xa8af4dcb, - 0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, 0x740744cc, 0x436d86cd, - 0x1ad3c0cf, 0x2db902ce, 0x4096af91, 0x77fc6d90, 0x2e422b92, - 0x1928e993, 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094, - 0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, 0x246fb598, - 0x13057799, 0x4abb319b, 0x7dd1f39a, 0x3035898d, 0x075f4b8c, - 0x5ee10d8e, 0x698bcf8f, 0xec9d808a, 0xdbf7428b, 0x82490489, - 0xb523c688, 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81, - 0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, 0xa0d0e2a9, - 0x97ba20a8, 0xce0466aa, 0xf96ea4ab, 0x7c78ebae, 0x4b1229af, - 0x12ac6fad, 0x25c6adac, 0x1881f1a7, 0x2feb33a6, 0x765575a4, - 0x413fb7a5, 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2, - 0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, 0x0cdbcdb2, - 0x3bb10fb3, 0x620f49b1, 0x55658bb0, 0x6822d7bb, 0x5f4815ba, - 0x06f653b8, 0x319c91b9, 0xb48adebc, 0x83e01cbd, 0xda5e5abf, - 0xed3498be}, - {0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, 0x5797628f, - 0x32f0de37, 0xdc5f6b25, 0xb938d79d, 0xef28b4c5, 0x8a4f087d, - 0x64e0bd6f, 0x018701d7, 0xb8bfd64a, 0xddd86af2, 0x3377dfe0, - 0x56106358, 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42, - 0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, 0x707fad95, - 0x1518112d, 0xfbb7a43f, 0x9ed01887, 0x27e8cf1a, 0x428f73a2, - 0xac20c6b0, 0xc9477a08, 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a, - 0xd00087b2, 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d, - 0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, 0x8610e4ea, - 0xe3775852, 0x0dd8ed40, 0x68bf51f8, 0xa1f82bf0, 0xc49f9748, - 0x2a30225a, 0x4f579ee2, 0xf66f497f, 0x9308f5c7, 0x7da740d5, - 0x18c0fc6d, 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27, - 0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, 0x3d58149b, - 0x583fa823, 0xb6901d31, 0xd3f7a189, 0x6acf7614, 0x0fa8caac, - 0xe1077fbe, 0x8460c306, 0xd270a05e, 0xb7171ce6, 0x59b8a9f4, - 0x3cdf154c, 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3, - 0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, 0xf5986f44, - 0x90ffd3fc, 0x7e5066ee, 0x1b37da56, 0x4d27b90e, 0x284005b6, - 0xc6efb0a4, 0xa3880c1c, 0x1ab0db81, 0x7fd76739, 0x9178d22b, - 0xf41f6e93, 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329, - 0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, 0xecdf92fe, - 0x89b82e46, 0x67179b54, 0x027027ec, 0xbb48f071, 0xde2f4cc9, - 0x3080f9db, 0x55e74563, 0x9ca03f6b, 0xf9c783d3, 0x176836c1, - 0x720f8a79, 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6, - 0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, 0x241fe921, - 0x41785599, 0xafd7e08b, 0xcab05c33, 0x3bb659ed, 0x5ed1e555, - 0xb07e5047, 0xd519ecff, 0x6c213b62, 0x094687da, 0xe7e932c8, - 0x828e8e70, 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a, - 0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, 0xa4e140bd, - 0xc186fc05, 0x2f294917, 0x4a4ef5af, 0xf3762232, 0x96119e8a, - 0x78be2b98, 0x1dd99720, 0x4bc9f478, 0x2eae48c0, 0xc001fdd2, - 0xa566416a, 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5, - 0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, 0x528e09c2, - 0x37e9b57a, 0xd9460068, 0xbc21bcd0, 0xea31df88, 0x8f566330, - 0x61f9d622, 0x049e6a9a, 0xbda6bd07, 0xd8c101bf, 0x366eb4ad, - 0x53090815, 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f, - 0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, 0x7566c6d8, - 0x10017a60, 0xfeaecf72, 0x9bc973ca, 0x22f1a457, 0x479618ef, - 0xa939adfd, 0xcc5e1145, 0x06ee4d76, 0x6389f1ce, 0x8d2644dc, - 0xe841f864, 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb, - 0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, 0xbe519b3c, - 0xdb362784, 0x35999296, 0x50fe2e2e, 0x99b95426, 0xfcdee89e, - 0x12715d8c, 0x7716e134, 0xce2e36a9, 0xab498a11, 0x45e63f03, - 0x208183bb, 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1, - 0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, 0x38417fd6, - 0x5d26c36e, 0xb389767c, 0xd6eecac4, 0x6fd61d59, 0x0ab1a1e1, - 0xe41e14f3, 0x8179a84b, 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9, - 0x39c67e01, 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e, - 0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, 0xf0810409, - 0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, 0x483ed243, 0x2d596efb, - 0xc3f6dbe9, 0xa6916751, 0x1fa9b0cc, 0x7ace0c74, 0x9461b966, - 0xf10605de}}; - -#endif - -#endif - -#if N == 2 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, - 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, - 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, - 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, - 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, - 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, - 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, - 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, - 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, - 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, - 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, - 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, - 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, - 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, - 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, - 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, - 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, - 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, - 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, - 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, - 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, - 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, - 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, - 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, - 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, - 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, - 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, - 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, - 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, - 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, - 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, - 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, - 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, - 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, - 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, - 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, - 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, - 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, - 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, - 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, - 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, - 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, - 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, - 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, - 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, - 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, - 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, - 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, - 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, - 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, - 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, - 0x0d7139d7}, - {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, - 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, - 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, - 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, - 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, - 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, - 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, - 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, - 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, - 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, - 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, - 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, - 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, - 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, - 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, - 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, - 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, - 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, - 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, - 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, - 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, - 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, - 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, - 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, - 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, - 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, - 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, - 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, - 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, - 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, - 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, - 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, - 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, - 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, - 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, - 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, - 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, - 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, - 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, - 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, - 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, - 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, - 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, - 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, - 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, - 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, - 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, - 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, - 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, - 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, - 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, - 0x1c53e98a}, - {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, - 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, - 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, - 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, - 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, - 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, - 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, - 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, - 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, - 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, - 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, - 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, - 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, - 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, - 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, - 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, - 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, - 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, - 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, - 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, - 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, - 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, - 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, - 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, - 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, - 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, - 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, - 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, - 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, - 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, - 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, - 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, - 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, - 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, - 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, - 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, - 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, - 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, - 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, - 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, - 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, - 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, - 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, - 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, - 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, - 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, - 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, - 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, - 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, - 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, - 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, - 0x3f88e851}, - {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, - 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, - 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, - 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, - 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, - 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, - 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, - 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, - 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, - 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, - 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, - 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, - 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, - 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, - 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, - 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, - 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, - 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, - 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, - 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, - 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, - 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, - 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, - 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, - 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, - 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, - 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, - 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, - 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, - 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, - 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, - 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, - 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, - 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, - 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, - 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, - 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, - 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, - 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, - 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, - 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, - 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, - 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, - 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, - 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, - 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, - 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, - 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, - 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, - 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, - 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, - 0x3dee8ca6}, - {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, - 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, - 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, - 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, - 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, - 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, - 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, - 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, - 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, - 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, - 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, - 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, - 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, - 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, - 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, - 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, - 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, - 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, - 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, - 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, - 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, - 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, - 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, - 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, - 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, - 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, - 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, - 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, - 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, - 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, - 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, - 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, - 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, - 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, - 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, - 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, - 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, - 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, - 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, - 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, - 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, - 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, - 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, - 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, - 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, - 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, - 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, - 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, - 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, - 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, - 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, - 0x36197165}, - {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, - 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, - 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, - 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, - 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, - 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, - 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, - 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, - 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, - 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, - 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, - 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, - 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, - 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, - 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, - 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, - 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, - 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, - 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, - 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, - 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, - 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, - 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, - 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, - 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, - 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, - 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, - 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, - 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, - 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, - 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, - 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, - 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, - 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, - 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, - 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, - 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, - 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, - 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, - 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, - 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, - 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, - 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, - 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, - 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, - 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, - 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, - 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, - 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, - 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, - 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, - 0x1a3b93aa}, - {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, - 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, - 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, - 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, - 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, - 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, - 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, - 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, - 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, - 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, - 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, - 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, - 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, - 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, - 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, - 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, - 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, - 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, - 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, - 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, - 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, - 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, - 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, - 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, - 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, - 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, - 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, - 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, - 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, - 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, - 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, - 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, - 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, - 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, - 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, - 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, - 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, - 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, - 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, - 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, - 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, - 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, - 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, - 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, - 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, - 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, - 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, - 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, - 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, - 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, - 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, - 0xe147d714}, - {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, - 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, - 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, - 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, - 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, - 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, - 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, - 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, - 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, - 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, - 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, - 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, - 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, - 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, - 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, - 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, - 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, - 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, - 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, - 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, - 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, - 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, - 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, - 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, - 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, - 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, - 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, - 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, - 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, - 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, - 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, - 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, - 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, - 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, - 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, - 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, - 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, - 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, - 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, - 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, - 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, - 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, - 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, - 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, - 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, - 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, - 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, - 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, - 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, - 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, - 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, - 0x494f0c4b}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x43147b1700000000, 0x8628f62e00000000, - 0xc53c8d3900000000, 0x0c51ec5d00000000, 0x4f45974a00000000, - 0x8a791a7300000000, 0xc96d616400000000, 0x18a2d8bb00000000, - 0x5bb6a3ac00000000, 0x9e8a2e9500000000, 0xdd9e558200000000, - 0x14f334e600000000, 0x57e74ff100000000, 0x92dbc2c800000000, - 0xd1cfb9df00000000, 0x7142c0ac00000000, 0x3256bbbb00000000, - 0xf76a368200000000, 0xb47e4d9500000000, 0x7d132cf100000000, - 0x3e0757e600000000, 0xfb3bdadf00000000, 0xb82fa1c800000000, - 0x69e0181700000000, 0x2af4630000000000, 0xefc8ee3900000000, - 0xacdc952e00000000, 0x65b1f44a00000000, 0x26a58f5d00000000, - 0xe399026400000000, 0xa08d797300000000, 0xa382f18200000000, - 0xe0968a9500000000, 0x25aa07ac00000000, 0x66be7cbb00000000, - 0xafd31ddf00000000, 0xecc766c800000000, 0x29fbebf100000000, - 0x6aef90e600000000, 0xbb20293900000000, 0xf834522e00000000, - 0x3d08df1700000000, 0x7e1ca40000000000, 0xb771c56400000000, - 0xf465be7300000000, 0x3159334a00000000, 0x724d485d00000000, - 0xd2c0312e00000000, 0x91d44a3900000000, 0x54e8c70000000000, - 0x17fcbc1700000000, 0xde91dd7300000000, 0x9d85a66400000000, - 0x58b92b5d00000000, 0x1bad504a00000000, 0xca62e99500000000, - 0x8976928200000000, 0x4c4a1fbb00000000, 0x0f5e64ac00000000, - 0xc63305c800000000, 0x85277edf00000000, 0x401bf3e600000000, - 0x030f88f100000000, 0x070392de00000000, 0x4417e9c900000000, - 0x812b64f000000000, 0xc23f1fe700000000, 0x0b527e8300000000, - 0x4846059400000000, 0x8d7a88ad00000000, 0xce6ef3ba00000000, - 0x1fa14a6500000000, 0x5cb5317200000000, 0x9989bc4b00000000, - 0xda9dc75c00000000, 0x13f0a63800000000, 0x50e4dd2f00000000, - 0x95d8501600000000, 0xd6cc2b0100000000, 0x7641527200000000, - 0x3555296500000000, 0xf069a45c00000000, 0xb37ddf4b00000000, - 0x7a10be2f00000000, 0x3904c53800000000, 0xfc38480100000000, - 0xbf2c331600000000, 0x6ee38ac900000000, 0x2df7f1de00000000, - 0xe8cb7ce700000000, 0xabdf07f000000000, 0x62b2669400000000, - 0x21a61d8300000000, 0xe49a90ba00000000, 0xa78eebad00000000, - 0xa481635c00000000, 0xe795184b00000000, 0x22a9957200000000, - 0x61bdee6500000000, 0xa8d08f0100000000, 0xebc4f41600000000, - 0x2ef8792f00000000, 0x6dec023800000000, 0xbc23bbe700000000, - 0xff37c0f000000000, 0x3a0b4dc900000000, 0x791f36de00000000, - 0xb07257ba00000000, 0xf3662cad00000000, 0x365aa19400000000, - 0x754eda8300000000, 0xd5c3a3f000000000, 0x96d7d8e700000000, - 0x53eb55de00000000, 0x10ff2ec900000000, 0xd9924fad00000000, - 0x9a8634ba00000000, 0x5fbab98300000000, 0x1caec29400000000, - 0xcd617b4b00000000, 0x8e75005c00000000, 0x4b498d6500000000, - 0x085df67200000000, 0xc130971600000000, 0x8224ec0100000000, - 0x4718613800000000, 0x040c1a2f00000000, 0x4f00556600000000, - 0x0c142e7100000000, 0xc928a34800000000, 0x8a3cd85f00000000, - 0x4351b93b00000000, 0x0045c22c00000000, 0xc5794f1500000000, - 0x866d340200000000, 0x57a28ddd00000000, 0x14b6f6ca00000000, - 0xd18a7bf300000000, 0x929e00e400000000, 0x5bf3618000000000, - 0x18e71a9700000000, 0xdddb97ae00000000, 0x9ecfecb900000000, - 0x3e4295ca00000000, 0x7d56eedd00000000, 0xb86a63e400000000, - 0xfb7e18f300000000, 0x3213799700000000, 0x7107028000000000, - 0xb43b8fb900000000, 0xf72ff4ae00000000, 0x26e04d7100000000, - 0x65f4366600000000, 0xa0c8bb5f00000000, 0xe3dcc04800000000, - 0x2ab1a12c00000000, 0x69a5da3b00000000, 0xac99570200000000, - 0xef8d2c1500000000, 0xec82a4e400000000, 0xaf96dff300000000, - 0x6aaa52ca00000000, 0x29be29dd00000000, 0xe0d348b900000000, - 0xa3c733ae00000000, 0x66fbbe9700000000, 0x25efc58000000000, - 0xf4207c5f00000000, 0xb734074800000000, 0x72088a7100000000, - 0x311cf16600000000, 0xf871900200000000, 0xbb65eb1500000000, - 0x7e59662c00000000, 0x3d4d1d3b00000000, 0x9dc0644800000000, - 0xded41f5f00000000, 0x1be8926600000000, 0x58fce97100000000, - 0x9191881500000000, 0xd285f30200000000, 0x17b97e3b00000000, - 0x54ad052c00000000, 0x8562bcf300000000, 0xc676c7e400000000, - 0x034a4add00000000, 0x405e31ca00000000, 0x893350ae00000000, - 0xca272bb900000000, 0x0f1ba68000000000, 0x4c0fdd9700000000, - 0x4803c7b800000000, 0x0b17bcaf00000000, 0xce2b319600000000, - 0x8d3f4a8100000000, 0x44522be500000000, 0x074650f200000000, - 0xc27addcb00000000, 0x816ea6dc00000000, 0x50a11f0300000000, - 0x13b5641400000000, 0xd689e92d00000000, 0x959d923a00000000, - 0x5cf0f35e00000000, 0x1fe4884900000000, 0xdad8057000000000, - 0x99cc7e6700000000, 0x3941071400000000, 0x7a557c0300000000, - 0xbf69f13a00000000, 0xfc7d8a2d00000000, 0x3510eb4900000000, - 0x7604905e00000000, 0xb3381d6700000000, 0xf02c667000000000, - 0x21e3dfaf00000000, 0x62f7a4b800000000, 0xa7cb298100000000, - 0xe4df529600000000, 0x2db233f200000000, 0x6ea648e500000000, - 0xab9ac5dc00000000, 0xe88ebecb00000000, 0xeb81363a00000000, - 0xa8954d2d00000000, 0x6da9c01400000000, 0x2ebdbb0300000000, - 0xe7d0da6700000000, 0xa4c4a17000000000, 0x61f82c4900000000, - 0x22ec575e00000000, 0xf323ee8100000000, 0xb037959600000000, - 0x750b18af00000000, 0x361f63b800000000, 0xff7202dc00000000, - 0xbc6679cb00000000, 0x795af4f200000000, 0x3a4e8fe500000000, - 0x9ac3f69600000000, 0xd9d78d8100000000, 0x1ceb00b800000000, - 0x5fff7baf00000000, 0x96921acb00000000, 0xd58661dc00000000, - 0x10baece500000000, 0x53ae97f200000000, 0x82612e2d00000000, - 0xc175553a00000000, 0x0449d80300000000, 0x475da31400000000, - 0x8e30c27000000000, 0xcd24b96700000000, 0x0818345e00000000, - 0x4b0c4f4900000000}, - {0x0000000000000000, 0x3e6bc2ef00000000, 0x3dd0f50400000000, - 0x03bb37eb00000000, 0x7aa0eb0900000000, 0x44cb29e600000000, - 0x47701e0d00000000, 0x791bdce200000000, 0xf440d71300000000, - 0xca2b15fc00000000, 0xc990221700000000, 0xf7fbe0f800000000, - 0x8ee03c1a00000000, 0xb08bfef500000000, 0xb330c91e00000000, - 0x8d5b0bf100000000, 0xe881ae2700000000, 0xd6ea6cc800000000, - 0xd5515b2300000000, 0xeb3a99cc00000000, 0x9221452e00000000, - 0xac4a87c100000000, 0xaff1b02a00000000, 0x919a72c500000000, - 0x1cc1793400000000, 0x22aabbdb00000000, 0x21118c3000000000, - 0x1f7a4edf00000000, 0x6661923d00000000, 0x580a50d200000000, - 0x5bb1673900000000, 0x65daa5d600000000, 0xd0035d4f00000000, - 0xee689fa000000000, 0xedd3a84b00000000, 0xd3b86aa400000000, - 0xaaa3b64600000000, 0x94c874a900000000, 0x9773434200000000, - 0xa91881ad00000000, 0x24438a5c00000000, 0x1a2848b300000000, - 0x19937f5800000000, 0x27f8bdb700000000, 0x5ee3615500000000, - 0x6088a3ba00000000, 0x6333945100000000, 0x5d5856be00000000, - 0x3882f36800000000, 0x06e9318700000000, 0x0552066c00000000, - 0x3b39c48300000000, 0x4222186100000000, 0x7c49da8e00000000, - 0x7ff2ed6500000000, 0x41992f8a00000000, 0xccc2247b00000000, - 0xf2a9e69400000000, 0xf112d17f00000000, 0xcf79139000000000, - 0xb662cf7200000000, 0x88090d9d00000000, 0x8bb23a7600000000, - 0xb5d9f89900000000, 0xa007ba9e00000000, 0x9e6c787100000000, - 0x9dd74f9a00000000, 0xa3bc8d7500000000, 0xdaa7519700000000, - 0xe4cc937800000000, 0xe777a49300000000, 0xd91c667c00000000, - 0x54476d8d00000000, 0x6a2caf6200000000, 0x6997988900000000, - 0x57fc5a6600000000, 0x2ee7868400000000, 0x108c446b00000000, - 0x1337738000000000, 0x2d5cb16f00000000, 0x488614b900000000, - 0x76edd65600000000, 0x7556e1bd00000000, 0x4b3d235200000000, - 0x3226ffb000000000, 0x0c4d3d5f00000000, 0x0ff60ab400000000, - 0x319dc85b00000000, 0xbcc6c3aa00000000, 0x82ad014500000000, - 0x811636ae00000000, 0xbf7df44100000000, 0xc66628a300000000, - 0xf80dea4c00000000, 0xfbb6dda700000000, 0xc5dd1f4800000000, - 0x7004e7d100000000, 0x4e6f253e00000000, 0x4dd412d500000000, - 0x73bfd03a00000000, 0x0aa40cd800000000, 0x34cfce3700000000, - 0x3774f9dc00000000, 0x091f3b3300000000, 0x844430c200000000, - 0xba2ff22d00000000, 0xb994c5c600000000, 0x87ff072900000000, - 0xfee4dbcb00000000, 0xc08f192400000000, 0xc3342ecf00000000, - 0xfd5fec2000000000, 0x988549f600000000, 0xa6ee8b1900000000, - 0xa555bcf200000000, 0x9b3e7e1d00000000, 0xe225a2ff00000000, - 0xdc4e601000000000, 0xdff557fb00000000, 0xe19e951400000000, - 0x6cc59ee500000000, 0x52ae5c0a00000000, 0x51156be100000000, - 0x6f7ea90e00000000, 0x166575ec00000000, 0x280eb70300000000, - 0x2bb580e800000000, 0x15de420700000000, 0x010905e600000000, - 0x3f62c70900000000, 0x3cd9f0e200000000, 0x02b2320d00000000, - 0x7ba9eeef00000000, 0x45c22c0000000000, 0x46791beb00000000, - 0x7812d90400000000, 0xf549d2f500000000, 0xcb22101a00000000, - 0xc89927f100000000, 0xf6f2e51e00000000, 0x8fe939fc00000000, - 0xb182fb1300000000, 0xb239ccf800000000, 0x8c520e1700000000, - 0xe988abc100000000, 0xd7e3692e00000000, 0xd4585ec500000000, - 0xea339c2a00000000, 0x932840c800000000, 0xad43822700000000, - 0xaef8b5cc00000000, 0x9093772300000000, 0x1dc87cd200000000, - 0x23a3be3d00000000, 0x201889d600000000, 0x1e734b3900000000, - 0x676897db00000000, 0x5903553400000000, 0x5ab862df00000000, - 0x64d3a03000000000, 0xd10a58a900000000, 0xef619a4600000000, - 0xecdaadad00000000, 0xd2b16f4200000000, 0xabaab3a000000000, - 0x95c1714f00000000, 0x967a46a400000000, 0xa811844b00000000, - 0x254a8fba00000000, 0x1b214d5500000000, 0x189a7abe00000000, - 0x26f1b85100000000, 0x5fea64b300000000, 0x6181a65c00000000, - 0x623a91b700000000, 0x5c51535800000000, 0x398bf68e00000000, - 0x07e0346100000000, 0x045b038a00000000, 0x3a30c16500000000, - 0x432b1d8700000000, 0x7d40df6800000000, 0x7efbe88300000000, - 0x40902a6c00000000, 0xcdcb219d00000000, 0xf3a0e37200000000, - 0xf01bd49900000000, 0xce70167600000000, 0xb76bca9400000000, - 0x8900087b00000000, 0x8abb3f9000000000, 0xb4d0fd7f00000000, - 0xa10ebf7800000000, 0x9f657d9700000000, 0x9cde4a7c00000000, - 0xa2b5889300000000, 0xdbae547100000000, 0xe5c5969e00000000, - 0xe67ea17500000000, 0xd815639a00000000, 0x554e686b00000000, - 0x6b25aa8400000000, 0x689e9d6f00000000, 0x56f55f8000000000, - 0x2fee836200000000, 0x1185418d00000000, 0x123e766600000000, - 0x2c55b48900000000, 0x498f115f00000000, 0x77e4d3b000000000, - 0x745fe45b00000000, 0x4a3426b400000000, 0x332ffa5600000000, - 0x0d4438b900000000, 0x0eff0f5200000000, 0x3094cdbd00000000, - 0xbdcfc64c00000000, 0x83a404a300000000, 0x801f334800000000, - 0xbe74f1a700000000, 0xc76f2d4500000000, 0xf904efaa00000000, - 0xfabfd84100000000, 0xc4d41aae00000000, 0x710de23700000000, - 0x4f6620d800000000, 0x4cdd173300000000, 0x72b6d5dc00000000, - 0x0bad093e00000000, 0x35c6cbd100000000, 0x367dfc3a00000000, - 0x08163ed500000000, 0x854d352400000000, 0xbb26f7cb00000000, - 0xb89dc02000000000, 0x86f602cf00000000, 0xffedde2d00000000, - 0xc1861cc200000000, 0xc23d2b2900000000, 0xfc56e9c600000000, - 0x998c4c1000000000, 0xa7e78eff00000000, 0xa45cb91400000000, - 0x9a377bfb00000000, 0xe32ca71900000000, 0xdd4765f600000000, - 0xdefc521d00000000, 0xe09790f200000000, 0x6dcc9b0300000000, - 0x53a759ec00000000, 0x501c6e0700000000, 0x6e77ace800000000, - 0x176c700a00000000, 0x2907b2e500000000, 0x2abc850e00000000, - 0x14d747e100000000}, - {0x0000000000000000, 0xc0df8ec100000000, 0xc1b96c5800000000, - 0x0166e29900000000, 0x8273d9b000000000, 0x42ac577100000000, - 0x43cab5e800000000, 0x83153b2900000000, 0x45e1c3ba00000000, - 0x853e4d7b00000000, 0x8458afe200000000, 0x4487212300000000, - 0xc7921a0a00000000, 0x074d94cb00000000, 0x062b765200000000, - 0xc6f4f89300000000, 0xcbc4f6ae00000000, 0x0b1b786f00000000, - 0x0a7d9af600000000, 0xcaa2143700000000, 0x49b72f1e00000000, - 0x8968a1df00000000, 0x880e434600000000, 0x48d1cd8700000000, - 0x8e25351400000000, 0x4efabbd500000000, 0x4f9c594c00000000, - 0x8f43d78d00000000, 0x0c56eca400000000, 0xcc89626500000000, - 0xcdef80fc00000000, 0x0d300e3d00000000, 0xd78f9c8600000000, - 0x1750124700000000, 0x1636f0de00000000, 0xd6e97e1f00000000, - 0x55fc453600000000, 0x9523cbf700000000, 0x9445296e00000000, - 0x549aa7af00000000, 0x926e5f3c00000000, 0x52b1d1fd00000000, - 0x53d7336400000000, 0x9308bda500000000, 0x101d868c00000000, - 0xd0c2084d00000000, 0xd1a4ead400000000, 0x117b641500000000, - 0x1c4b6a2800000000, 0xdc94e4e900000000, 0xddf2067000000000, - 0x1d2d88b100000000, 0x9e38b39800000000, 0x5ee73d5900000000, - 0x5f81dfc000000000, 0x9f5e510100000000, 0x59aaa99200000000, - 0x9975275300000000, 0x9813c5ca00000000, 0x58cc4b0b00000000, - 0xdbd9702200000000, 0x1b06fee300000000, 0x1a601c7a00000000, - 0xdabf92bb00000000, 0xef1948d600000000, 0x2fc6c61700000000, - 0x2ea0248e00000000, 0xee7faa4f00000000, 0x6d6a916600000000, - 0xadb51fa700000000, 0xacd3fd3e00000000, 0x6c0c73ff00000000, - 0xaaf88b6c00000000, 0x6a2705ad00000000, 0x6b41e73400000000, - 0xab9e69f500000000, 0x288b52dc00000000, 0xe854dc1d00000000, - 0xe9323e8400000000, 0x29edb04500000000, 0x24ddbe7800000000, - 0xe40230b900000000, 0xe564d22000000000, 0x25bb5ce100000000, - 0xa6ae67c800000000, 0x6671e90900000000, 0x67170b9000000000, - 0xa7c8855100000000, 0x613c7dc200000000, 0xa1e3f30300000000, - 0xa085119a00000000, 0x605a9f5b00000000, 0xe34fa47200000000, - 0x23902ab300000000, 0x22f6c82a00000000, 0xe22946eb00000000, - 0x3896d45000000000, 0xf8495a9100000000, 0xf92fb80800000000, - 0x39f036c900000000, 0xbae50de000000000, 0x7a3a832100000000, - 0x7b5c61b800000000, 0xbb83ef7900000000, 0x7d7717ea00000000, - 0xbda8992b00000000, 0xbcce7bb200000000, 0x7c11f57300000000, - 0xff04ce5a00000000, 0x3fdb409b00000000, 0x3ebda20200000000, - 0xfe622cc300000000, 0xf35222fe00000000, 0x338dac3f00000000, - 0x32eb4ea600000000, 0xf234c06700000000, 0x7121fb4e00000000, - 0xb1fe758f00000000, 0xb098971600000000, 0x704719d700000000, - 0xb6b3e14400000000, 0x766c6f8500000000, 0x770a8d1c00000000, - 0xb7d503dd00000000, 0x34c038f400000000, 0xf41fb63500000000, - 0xf57954ac00000000, 0x35a6da6d00000000, 0x9f35e17700000000, - 0x5fea6fb600000000, 0x5e8c8d2f00000000, 0x9e5303ee00000000, - 0x1d4638c700000000, 0xdd99b60600000000, 0xdcff549f00000000, - 0x1c20da5e00000000, 0xdad422cd00000000, 0x1a0bac0c00000000, - 0x1b6d4e9500000000, 0xdbb2c05400000000, 0x58a7fb7d00000000, - 0x987875bc00000000, 0x991e972500000000, 0x59c119e400000000, - 0x54f117d900000000, 0x942e991800000000, 0x95487b8100000000, - 0x5597f54000000000, 0xd682ce6900000000, 0x165d40a800000000, - 0x173ba23100000000, 0xd7e42cf000000000, 0x1110d46300000000, - 0xd1cf5aa200000000, 0xd0a9b83b00000000, 0x107636fa00000000, - 0x93630dd300000000, 0x53bc831200000000, 0x52da618b00000000, - 0x9205ef4a00000000, 0x48ba7df100000000, 0x8865f33000000000, - 0x890311a900000000, 0x49dc9f6800000000, 0xcac9a44100000000, - 0x0a162a8000000000, 0x0b70c81900000000, 0xcbaf46d800000000, - 0x0d5bbe4b00000000, 0xcd84308a00000000, 0xcce2d21300000000, - 0x0c3d5cd200000000, 0x8f2867fb00000000, 0x4ff7e93a00000000, - 0x4e910ba300000000, 0x8e4e856200000000, 0x837e8b5f00000000, - 0x43a1059e00000000, 0x42c7e70700000000, 0x821869c600000000, - 0x010d52ef00000000, 0xc1d2dc2e00000000, 0xc0b43eb700000000, - 0x006bb07600000000, 0xc69f48e500000000, 0x0640c62400000000, - 0x072624bd00000000, 0xc7f9aa7c00000000, 0x44ec915500000000, - 0x84331f9400000000, 0x8555fd0d00000000, 0x458a73cc00000000, - 0x702ca9a100000000, 0xb0f3276000000000, 0xb195c5f900000000, - 0x714a4b3800000000, 0xf25f701100000000, 0x3280fed000000000, - 0x33e61c4900000000, 0xf339928800000000, 0x35cd6a1b00000000, - 0xf512e4da00000000, 0xf474064300000000, 0x34ab888200000000, - 0xb7beb3ab00000000, 0x77613d6a00000000, 0x7607dff300000000, - 0xb6d8513200000000, 0xbbe85f0f00000000, 0x7b37d1ce00000000, - 0x7a51335700000000, 0xba8ebd9600000000, 0x399b86bf00000000, - 0xf944087e00000000, 0xf822eae700000000, 0x38fd642600000000, - 0xfe099cb500000000, 0x3ed6127400000000, 0x3fb0f0ed00000000, - 0xff6f7e2c00000000, 0x7c7a450500000000, 0xbca5cbc400000000, - 0xbdc3295d00000000, 0x7d1ca79c00000000, 0xa7a3352700000000, - 0x677cbbe600000000, 0x661a597f00000000, 0xa6c5d7be00000000, - 0x25d0ec9700000000, 0xe50f625600000000, 0xe46980cf00000000, - 0x24b60e0e00000000, 0xe242f69d00000000, 0x229d785c00000000, - 0x23fb9ac500000000, 0xe324140400000000, 0x60312f2d00000000, - 0xa0eea1ec00000000, 0xa188437500000000, 0x6157cdb400000000, - 0x6c67c38900000000, 0xacb84d4800000000, 0xaddeafd100000000, - 0x6d01211000000000, 0xee141a3900000000, 0x2ecb94f800000000, - 0x2fad766100000000, 0xef72f8a000000000, 0x2986003300000000, - 0xe9598ef200000000, 0xe83f6c6b00000000, 0x28e0e2aa00000000, - 0xabf5d98300000000, 0x6b2a574200000000, 0x6a4cb5db00000000, - 0xaa933b1a00000000}, - {0x0000000000000000, 0x6f4ca59b00000000, 0x9f9e3bec00000000, - 0xf0d29e7700000000, 0x7f3b060300000000, 0x1077a39800000000, - 0xe0a53def00000000, 0x8fe9987400000000, 0xfe760c0600000000, - 0x913aa99d00000000, 0x61e837ea00000000, 0x0ea4927100000000, - 0x814d0a0500000000, 0xee01af9e00000000, 0x1ed331e900000000, - 0x719f947200000000, 0xfced180c00000000, 0x93a1bd9700000000, - 0x637323e000000000, 0x0c3f867b00000000, 0x83d61e0f00000000, - 0xec9abb9400000000, 0x1c4825e300000000, 0x7304807800000000, - 0x029b140a00000000, 0x6dd7b19100000000, 0x9d052fe600000000, - 0xf2498a7d00000000, 0x7da0120900000000, 0x12ecb79200000000, - 0xe23e29e500000000, 0x8d728c7e00000000, 0xf8db311800000000, - 0x9797948300000000, 0x67450af400000000, 0x0809af6f00000000, - 0x87e0371b00000000, 0xe8ac928000000000, 0x187e0cf700000000, - 0x7732a96c00000000, 0x06ad3d1e00000000, 0x69e1988500000000, - 0x993306f200000000, 0xf67fa36900000000, 0x79963b1d00000000, - 0x16da9e8600000000, 0xe60800f100000000, 0x8944a56a00000000, - 0x0436291400000000, 0x6b7a8c8f00000000, 0x9ba812f800000000, - 0xf4e4b76300000000, 0x7b0d2f1700000000, 0x14418a8c00000000, - 0xe49314fb00000000, 0x8bdfb16000000000, 0xfa40251200000000, - 0x950c808900000000, 0x65de1efe00000000, 0x0a92bb6500000000, - 0x857b231100000000, 0xea37868a00000000, 0x1ae518fd00000000, - 0x75a9bd6600000000, 0xf0b7633000000000, 0x9ffbc6ab00000000, - 0x6f2958dc00000000, 0x0065fd4700000000, 0x8f8c653300000000, - 0xe0c0c0a800000000, 0x10125edf00000000, 0x7f5efb4400000000, - 0x0ec16f3600000000, 0x618dcaad00000000, 0x915f54da00000000, - 0xfe13f14100000000, 0x71fa693500000000, 0x1eb6ccae00000000, - 0xee6452d900000000, 0x8128f74200000000, 0x0c5a7b3c00000000, - 0x6316dea700000000, 0x93c440d000000000, 0xfc88e54b00000000, - 0x73617d3f00000000, 0x1c2dd8a400000000, 0xecff46d300000000, - 0x83b3e34800000000, 0xf22c773a00000000, 0x9d60d2a100000000, - 0x6db24cd600000000, 0x02fee94d00000000, 0x8d17713900000000, - 0xe25bd4a200000000, 0x12894ad500000000, 0x7dc5ef4e00000000, - 0x086c522800000000, 0x6720f7b300000000, 0x97f269c400000000, - 0xf8becc5f00000000, 0x7757542b00000000, 0x181bf1b000000000, - 0xe8c96fc700000000, 0x8785ca5c00000000, 0xf61a5e2e00000000, - 0x9956fbb500000000, 0x698465c200000000, 0x06c8c05900000000, - 0x8921582d00000000, 0xe66dfdb600000000, 0x16bf63c100000000, - 0x79f3c65a00000000, 0xf4814a2400000000, 0x9bcdefbf00000000, - 0x6b1f71c800000000, 0x0453d45300000000, 0x8bba4c2700000000, - 0xe4f6e9bc00000000, 0x142477cb00000000, 0x7b68d25000000000, - 0x0af7462200000000, 0x65bbe3b900000000, 0x95697dce00000000, - 0xfa25d85500000000, 0x75cc402100000000, 0x1a80e5ba00000000, - 0xea527bcd00000000, 0x851ede5600000000, 0xe06fc76000000000, - 0x8f2362fb00000000, 0x7ff1fc8c00000000, 0x10bd591700000000, - 0x9f54c16300000000, 0xf01864f800000000, 0x00cafa8f00000000, - 0x6f865f1400000000, 0x1e19cb6600000000, 0x71556efd00000000, - 0x8187f08a00000000, 0xeecb551100000000, 0x6122cd6500000000, - 0x0e6e68fe00000000, 0xfebcf68900000000, 0x91f0531200000000, - 0x1c82df6c00000000, 0x73ce7af700000000, 0x831ce48000000000, - 0xec50411b00000000, 0x63b9d96f00000000, 0x0cf57cf400000000, - 0xfc27e28300000000, 0x936b471800000000, 0xe2f4d36a00000000, - 0x8db876f100000000, 0x7d6ae88600000000, 0x12264d1d00000000, - 0x9dcfd56900000000, 0xf28370f200000000, 0x0251ee8500000000, - 0x6d1d4b1e00000000, 0x18b4f67800000000, 0x77f853e300000000, - 0x872acd9400000000, 0xe866680f00000000, 0x678ff07b00000000, - 0x08c355e000000000, 0xf811cb9700000000, 0x975d6e0c00000000, - 0xe6c2fa7e00000000, 0x898e5fe500000000, 0x795cc19200000000, - 0x1610640900000000, 0x99f9fc7d00000000, 0xf6b559e600000000, - 0x0667c79100000000, 0x692b620a00000000, 0xe459ee7400000000, - 0x8b154bef00000000, 0x7bc7d59800000000, 0x148b700300000000, - 0x9b62e87700000000, 0xf42e4dec00000000, 0x04fcd39b00000000, - 0x6bb0760000000000, 0x1a2fe27200000000, 0x756347e900000000, - 0x85b1d99e00000000, 0xeafd7c0500000000, 0x6514e47100000000, - 0x0a5841ea00000000, 0xfa8adf9d00000000, 0x95c67a0600000000, - 0x10d8a45000000000, 0x7f9401cb00000000, 0x8f469fbc00000000, - 0xe00a3a2700000000, 0x6fe3a25300000000, 0x00af07c800000000, - 0xf07d99bf00000000, 0x9f313c2400000000, 0xeeaea85600000000, - 0x81e20dcd00000000, 0x713093ba00000000, 0x1e7c362100000000, - 0x9195ae5500000000, 0xfed90bce00000000, 0x0e0b95b900000000, - 0x6147302200000000, 0xec35bc5c00000000, 0x837919c700000000, - 0x73ab87b000000000, 0x1ce7222b00000000, 0x930eba5f00000000, - 0xfc421fc400000000, 0x0c9081b300000000, 0x63dc242800000000, - 0x1243b05a00000000, 0x7d0f15c100000000, 0x8ddd8bb600000000, - 0xe2912e2d00000000, 0x6d78b65900000000, 0x023413c200000000, - 0xf2e68db500000000, 0x9daa282e00000000, 0xe803954800000000, - 0x874f30d300000000, 0x779daea400000000, 0x18d10b3f00000000, - 0x9738934b00000000, 0xf87436d000000000, 0x08a6a8a700000000, - 0x67ea0d3c00000000, 0x1675994e00000000, 0x79393cd500000000, - 0x89eba2a200000000, 0xe6a7073900000000, 0x694e9f4d00000000, - 0x06023ad600000000, 0xf6d0a4a100000000, 0x999c013a00000000, - 0x14ee8d4400000000, 0x7ba228df00000000, 0x8b70b6a800000000, - 0xe43c133300000000, 0x6bd58b4700000000, 0x04992edc00000000, - 0xf44bb0ab00000000, 0x9b07153000000000, 0xea98814200000000, - 0x85d424d900000000, 0x7506baae00000000, 0x1a4a1f3500000000, - 0x95a3874100000000, 0xfaef22da00000000, 0x0a3dbcad00000000, - 0x6571193600000000}, - {0x0000000000000000, 0x85d996dd00000000, 0x4bb55c6000000000, - 0xce6ccabd00000000, 0x966ab9c000000000, 0x13b32f1d00000000, - 0xdddfe5a000000000, 0x5806737d00000000, 0x6dd3035a00000000, - 0xe80a958700000000, 0x26665f3a00000000, 0xa3bfc9e700000000, - 0xfbb9ba9a00000000, 0x7e602c4700000000, 0xb00ce6fa00000000, - 0x35d5702700000000, 0xdaa607b400000000, 0x5f7f916900000000, - 0x91135bd400000000, 0x14cacd0900000000, 0x4cccbe7400000000, - 0xc91528a900000000, 0x0779e21400000000, 0x82a074c900000000, - 0xb77504ee00000000, 0x32ac923300000000, 0xfcc0588e00000000, - 0x7919ce5300000000, 0x211fbd2e00000000, 0xa4c62bf300000000, - 0x6aaae14e00000000, 0xef73779300000000, 0xf54b7eb300000000, - 0x7092e86e00000000, 0xbefe22d300000000, 0x3b27b40e00000000, - 0x6321c77300000000, 0xe6f851ae00000000, 0x28949b1300000000, - 0xad4d0dce00000000, 0x98987de900000000, 0x1d41eb3400000000, - 0xd32d218900000000, 0x56f4b75400000000, 0x0ef2c42900000000, - 0x8b2b52f400000000, 0x4547984900000000, 0xc09e0e9400000000, - 0x2fed790700000000, 0xaa34efda00000000, 0x6458256700000000, - 0xe181b3ba00000000, 0xb987c0c700000000, 0x3c5e561a00000000, - 0xf2329ca700000000, 0x77eb0a7a00000000, 0x423e7a5d00000000, - 0xc7e7ec8000000000, 0x098b263d00000000, 0x8c52b0e000000000, - 0xd454c39d00000000, 0x518d554000000000, 0x9fe19ffd00000000, - 0x1a38092000000000, 0xab918dbd00000000, 0x2e481b6000000000, - 0xe024d1dd00000000, 0x65fd470000000000, 0x3dfb347d00000000, - 0xb822a2a000000000, 0x764e681d00000000, 0xf397fec000000000, - 0xc6428ee700000000, 0x439b183a00000000, 0x8df7d28700000000, - 0x082e445a00000000, 0x5028372700000000, 0xd5f1a1fa00000000, - 0x1b9d6b4700000000, 0x9e44fd9a00000000, 0x71378a0900000000, - 0xf4ee1cd400000000, 0x3a82d66900000000, 0xbf5b40b400000000, - 0xe75d33c900000000, 0x6284a51400000000, 0xace86fa900000000, - 0x2931f97400000000, 0x1ce4895300000000, 0x993d1f8e00000000, - 0x5751d53300000000, 0xd28843ee00000000, 0x8a8e309300000000, - 0x0f57a64e00000000, 0xc13b6cf300000000, 0x44e2fa2e00000000, - 0x5edaf30e00000000, 0xdb0365d300000000, 0x156faf6e00000000, - 0x90b639b300000000, 0xc8b04ace00000000, 0x4d69dc1300000000, - 0x830516ae00000000, 0x06dc807300000000, 0x3309f05400000000, - 0xb6d0668900000000, 0x78bcac3400000000, 0xfd653ae900000000, - 0xa563499400000000, 0x20badf4900000000, 0xeed615f400000000, - 0x6b0f832900000000, 0x847cf4ba00000000, 0x01a5626700000000, - 0xcfc9a8da00000000, 0x4a103e0700000000, 0x12164d7a00000000, - 0x97cfdba700000000, 0x59a3111a00000000, 0xdc7a87c700000000, - 0xe9aff7e000000000, 0x6c76613d00000000, 0xa21aab8000000000, - 0x27c33d5d00000000, 0x7fc54e2000000000, 0xfa1cd8fd00000000, - 0x3470124000000000, 0xb1a9849d00000000, 0x17256aa000000000, - 0x92fcfc7d00000000, 0x5c9036c000000000, 0xd949a01d00000000, - 0x814fd36000000000, 0x049645bd00000000, 0xcafa8f0000000000, - 0x4f2319dd00000000, 0x7af669fa00000000, 0xff2fff2700000000, - 0x3143359a00000000, 0xb49aa34700000000, 0xec9cd03a00000000, - 0x694546e700000000, 0xa7298c5a00000000, 0x22f01a8700000000, - 0xcd836d1400000000, 0x485afbc900000000, 0x8636317400000000, - 0x03efa7a900000000, 0x5be9d4d400000000, 0xde30420900000000, - 0x105c88b400000000, 0x95851e6900000000, 0xa0506e4e00000000, - 0x2589f89300000000, 0xebe5322e00000000, 0x6e3ca4f300000000, - 0x363ad78e00000000, 0xb3e3415300000000, 0x7d8f8bee00000000, - 0xf8561d3300000000, 0xe26e141300000000, 0x67b782ce00000000, - 0xa9db487300000000, 0x2c02deae00000000, 0x7404add300000000, - 0xf1dd3b0e00000000, 0x3fb1f1b300000000, 0xba68676e00000000, - 0x8fbd174900000000, 0x0a64819400000000, 0xc4084b2900000000, - 0x41d1ddf400000000, 0x19d7ae8900000000, 0x9c0e385400000000, - 0x5262f2e900000000, 0xd7bb643400000000, 0x38c813a700000000, - 0xbd11857a00000000, 0x737d4fc700000000, 0xf6a4d91a00000000, - 0xaea2aa6700000000, 0x2b7b3cba00000000, 0xe517f60700000000, - 0x60ce60da00000000, 0x551b10fd00000000, 0xd0c2862000000000, - 0x1eae4c9d00000000, 0x9b77da4000000000, 0xc371a93d00000000, - 0x46a83fe000000000, 0x88c4f55d00000000, 0x0d1d638000000000, - 0xbcb4e71d00000000, 0x396d71c000000000, 0xf701bb7d00000000, - 0x72d82da000000000, 0x2ade5edd00000000, 0xaf07c80000000000, - 0x616b02bd00000000, 0xe4b2946000000000, 0xd167e44700000000, - 0x54be729a00000000, 0x9ad2b82700000000, 0x1f0b2efa00000000, - 0x470d5d8700000000, 0xc2d4cb5a00000000, 0x0cb801e700000000, - 0x8961973a00000000, 0x6612e0a900000000, 0xe3cb767400000000, - 0x2da7bcc900000000, 0xa87e2a1400000000, 0xf078596900000000, - 0x75a1cfb400000000, 0xbbcd050900000000, 0x3e1493d400000000, - 0x0bc1e3f300000000, 0x8e18752e00000000, 0x4074bf9300000000, - 0xc5ad294e00000000, 0x9dab5a3300000000, 0x1872ccee00000000, - 0xd61e065300000000, 0x53c7908e00000000, 0x49ff99ae00000000, - 0xcc260f7300000000, 0x024ac5ce00000000, 0x8793531300000000, - 0xdf95206e00000000, 0x5a4cb6b300000000, 0x94207c0e00000000, - 0x11f9ead300000000, 0x242c9af400000000, 0xa1f50c2900000000, - 0x6f99c69400000000, 0xea40504900000000, 0xb246233400000000, - 0x379fb5e900000000, 0xf9f37f5400000000, 0x7c2ae98900000000, - 0x93599e1a00000000, 0x168008c700000000, 0xd8ecc27a00000000, - 0x5d3554a700000000, 0x053327da00000000, 0x80eab10700000000, - 0x4e867bba00000000, 0xcb5fed6700000000, 0xfe8a9d4000000000, - 0x7b530b9d00000000, 0xb53fc12000000000, 0x30e657fd00000000, - 0x68e0248000000000, 0xed39b25d00000000, 0x235578e000000000, - 0xa68cee3d00000000}, - {0x0000000000000000, 0x76e10f9d00000000, 0xadc46ee100000000, - 0xdb25617c00000000, 0x1b8fac1900000000, 0x6d6ea38400000000, - 0xb64bc2f800000000, 0xc0aacd6500000000, 0x361e593300000000, - 0x40ff56ae00000000, 0x9bda37d200000000, 0xed3b384f00000000, - 0x2d91f52a00000000, 0x5b70fab700000000, 0x80559bcb00000000, - 0xf6b4945600000000, 0x6c3cb26600000000, 0x1addbdfb00000000, - 0xc1f8dc8700000000, 0xb719d31a00000000, 0x77b31e7f00000000, - 0x015211e200000000, 0xda77709e00000000, 0xac967f0300000000, - 0x5a22eb5500000000, 0x2cc3e4c800000000, 0xf7e685b400000000, - 0x81078a2900000000, 0x41ad474c00000000, 0x374c48d100000000, - 0xec6929ad00000000, 0x9a88263000000000, 0xd87864cd00000000, - 0xae996b5000000000, 0x75bc0a2c00000000, 0x035d05b100000000, - 0xc3f7c8d400000000, 0xb516c74900000000, 0x6e33a63500000000, - 0x18d2a9a800000000, 0xee663dfe00000000, 0x9887326300000000, - 0x43a2531f00000000, 0x35435c8200000000, 0xf5e991e700000000, - 0x83089e7a00000000, 0x582dff0600000000, 0x2eccf09b00000000, - 0xb444d6ab00000000, 0xc2a5d93600000000, 0x1980b84a00000000, - 0x6f61b7d700000000, 0xafcb7ab200000000, 0xd92a752f00000000, - 0x020f145300000000, 0x74ee1bce00000000, 0x825a8f9800000000, - 0xf4bb800500000000, 0x2f9ee17900000000, 0x597feee400000000, - 0x99d5238100000000, 0xef342c1c00000000, 0x34114d6000000000, - 0x42f042fd00000000, 0xf1f7b94100000000, 0x8716b6dc00000000, - 0x5c33d7a000000000, 0x2ad2d83d00000000, 0xea78155800000000, - 0x9c991ac500000000, 0x47bc7bb900000000, 0x315d742400000000, - 0xc7e9e07200000000, 0xb108efef00000000, 0x6a2d8e9300000000, - 0x1ccc810e00000000, 0xdc664c6b00000000, 0xaa8743f600000000, - 0x71a2228a00000000, 0x07432d1700000000, 0x9dcb0b2700000000, - 0xeb2a04ba00000000, 0x300f65c600000000, 0x46ee6a5b00000000, - 0x8644a73e00000000, 0xf0a5a8a300000000, 0x2b80c9df00000000, - 0x5d61c64200000000, 0xabd5521400000000, 0xdd345d8900000000, - 0x06113cf500000000, 0x70f0336800000000, 0xb05afe0d00000000, - 0xc6bbf19000000000, 0x1d9e90ec00000000, 0x6b7f9f7100000000, - 0x298fdd8c00000000, 0x5f6ed21100000000, 0x844bb36d00000000, - 0xf2aabcf000000000, 0x3200719500000000, 0x44e17e0800000000, - 0x9fc41f7400000000, 0xe92510e900000000, 0x1f9184bf00000000, - 0x69708b2200000000, 0xb255ea5e00000000, 0xc4b4e5c300000000, - 0x041e28a600000000, 0x72ff273b00000000, 0xa9da464700000000, - 0xdf3b49da00000000, 0x45b36fea00000000, 0x3352607700000000, - 0xe877010b00000000, 0x9e960e9600000000, 0x5e3cc3f300000000, - 0x28ddcc6e00000000, 0xf3f8ad1200000000, 0x8519a28f00000000, - 0x73ad36d900000000, 0x054c394400000000, 0xde69583800000000, - 0xa88857a500000000, 0x68229ac000000000, 0x1ec3955d00000000, - 0xc5e6f42100000000, 0xb307fbbc00000000, 0xe2ef738300000000, - 0x940e7c1e00000000, 0x4f2b1d6200000000, 0x39ca12ff00000000, - 0xf960df9a00000000, 0x8f81d00700000000, 0x54a4b17b00000000, - 0x2245bee600000000, 0xd4f12ab000000000, 0xa210252d00000000, - 0x7935445100000000, 0x0fd44bcc00000000, 0xcf7e86a900000000, - 0xb99f893400000000, 0x62bae84800000000, 0x145be7d500000000, - 0x8ed3c1e500000000, 0xf832ce7800000000, 0x2317af0400000000, - 0x55f6a09900000000, 0x955c6dfc00000000, 0xe3bd626100000000, - 0x3898031d00000000, 0x4e790c8000000000, 0xb8cd98d600000000, - 0xce2c974b00000000, 0x1509f63700000000, 0x63e8f9aa00000000, - 0xa34234cf00000000, 0xd5a33b5200000000, 0x0e865a2e00000000, - 0x786755b300000000, 0x3a97174e00000000, 0x4c7618d300000000, - 0x975379af00000000, 0xe1b2763200000000, 0x2118bb5700000000, - 0x57f9b4ca00000000, 0x8cdcd5b600000000, 0xfa3dda2b00000000, - 0x0c894e7d00000000, 0x7a6841e000000000, 0xa14d209c00000000, - 0xd7ac2f0100000000, 0x1706e26400000000, 0x61e7edf900000000, - 0xbac28c8500000000, 0xcc23831800000000, 0x56aba52800000000, - 0x204aaab500000000, 0xfb6fcbc900000000, 0x8d8ec45400000000, - 0x4d24093100000000, 0x3bc506ac00000000, 0xe0e067d000000000, - 0x9601684d00000000, 0x60b5fc1b00000000, 0x1654f38600000000, - 0xcd7192fa00000000, 0xbb909d6700000000, 0x7b3a500200000000, - 0x0ddb5f9f00000000, 0xd6fe3ee300000000, 0xa01f317e00000000, - 0x1318cac200000000, 0x65f9c55f00000000, 0xbedca42300000000, - 0xc83dabbe00000000, 0x089766db00000000, 0x7e76694600000000, - 0xa553083a00000000, 0xd3b207a700000000, 0x250693f100000000, - 0x53e79c6c00000000, 0x88c2fd1000000000, 0xfe23f28d00000000, - 0x3e893fe800000000, 0x4868307500000000, 0x934d510900000000, - 0xe5ac5e9400000000, 0x7f2478a400000000, 0x09c5773900000000, - 0xd2e0164500000000, 0xa40119d800000000, 0x64abd4bd00000000, - 0x124adb2000000000, 0xc96fba5c00000000, 0xbf8eb5c100000000, - 0x493a219700000000, 0x3fdb2e0a00000000, 0xe4fe4f7600000000, - 0x921f40eb00000000, 0x52b58d8e00000000, 0x2454821300000000, - 0xff71e36f00000000, 0x8990ecf200000000, 0xcb60ae0f00000000, - 0xbd81a19200000000, 0x66a4c0ee00000000, 0x1045cf7300000000, - 0xd0ef021600000000, 0xa60e0d8b00000000, 0x7d2b6cf700000000, - 0x0bca636a00000000, 0xfd7ef73c00000000, 0x8b9ff8a100000000, - 0x50ba99dd00000000, 0x265b964000000000, 0xe6f15b2500000000, - 0x901054b800000000, 0x4b3535c400000000, 0x3dd43a5900000000, - 0xa75c1c6900000000, 0xd1bd13f400000000, 0x0a98728800000000, - 0x7c797d1500000000, 0xbcd3b07000000000, 0xca32bfed00000000, - 0x1117de9100000000, 0x67f6d10c00000000, 0x9142455a00000000, - 0xe7a34ac700000000, 0x3c862bbb00000000, 0x4a67242600000000, - 0x8acde94300000000, 0xfc2ce6de00000000, 0x270987a200000000, - 0x51e8883f00000000}, - {0x0000000000000000, 0xe8dbfbb900000000, 0x91b186a800000000, - 0x796a7d1100000000, 0x63657c8a00000000, 0x8bbe873300000000, - 0xf2d4fa2200000000, 0x1a0f019b00000000, 0x87cc89cf00000000, - 0x6f17727600000000, 0x167d0f6700000000, 0xfea6f4de00000000, - 0xe4a9f54500000000, 0x0c720efc00000000, 0x751873ed00000000, - 0x9dc3885400000000, 0x4f9f624400000000, 0xa74499fd00000000, - 0xde2ee4ec00000000, 0x36f51f5500000000, 0x2cfa1ece00000000, - 0xc421e57700000000, 0xbd4b986600000000, 0x559063df00000000, - 0xc853eb8b00000000, 0x2088103200000000, 0x59e26d2300000000, - 0xb139969a00000000, 0xab36970100000000, 0x43ed6cb800000000, - 0x3a8711a900000000, 0xd25cea1000000000, 0x9e3ec58800000000, - 0x76e53e3100000000, 0x0f8f432000000000, 0xe754b89900000000, - 0xfd5bb90200000000, 0x158042bb00000000, 0x6cea3faa00000000, - 0x8431c41300000000, 0x19f24c4700000000, 0xf129b7fe00000000, - 0x8843caef00000000, 0x6098315600000000, 0x7a9730cd00000000, - 0x924ccb7400000000, 0xeb26b66500000000, 0x03fd4ddc00000000, - 0xd1a1a7cc00000000, 0x397a5c7500000000, 0x4010216400000000, - 0xa8cbdadd00000000, 0xb2c4db4600000000, 0x5a1f20ff00000000, - 0x23755dee00000000, 0xcbaea65700000000, 0x566d2e0300000000, - 0xbeb6d5ba00000000, 0xc7dca8ab00000000, 0x2f07531200000000, - 0x3508528900000000, 0xddd3a93000000000, 0xa4b9d42100000000, - 0x4c622f9800000000, 0x7d7bfbca00000000, 0x95a0007300000000, - 0xecca7d6200000000, 0x041186db00000000, 0x1e1e874000000000, - 0xf6c57cf900000000, 0x8faf01e800000000, 0x6774fa5100000000, - 0xfab7720500000000, 0x126c89bc00000000, 0x6b06f4ad00000000, - 0x83dd0f1400000000, 0x99d20e8f00000000, 0x7109f53600000000, - 0x0863882700000000, 0xe0b8739e00000000, 0x32e4998e00000000, - 0xda3f623700000000, 0xa3551f2600000000, 0x4b8ee49f00000000, - 0x5181e50400000000, 0xb95a1ebd00000000, 0xc03063ac00000000, - 0x28eb981500000000, 0xb528104100000000, 0x5df3ebf800000000, - 0x249996e900000000, 0xcc426d5000000000, 0xd64d6ccb00000000, - 0x3e96977200000000, 0x47fcea6300000000, 0xaf2711da00000000, - 0xe3453e4200000000, 0x0b9ec5fb00000000, 0x72f4b8ea00000000, - 0x9a2f435300000000, 0x802042c800000000, 0x68fbb97100000000, - 0x1191c46000000000, 0xf94a3fd900000000, 0x6489b78d00000000, - 0x8c524c3400000000, 0xf538312500000000, 0x1de3ca9c00000000, - 0x07eccb0700000000, 0xef3730be00000000, 0x965d4daf00000000, - 0x7e86b61600000000, 0xacda5c0600000000, 0x4401a7bf00000000, - 0x3d6bdaae00000000, 0xd5b0211700000000, 0xcfbf208c00000000, - 0x2764db3500000000, 0x5e0ea62400000000, 0xb6d55d9d00000000, - 0x2b16d5c900000000, 0xc3cd2e7000000000, 0xbaa7536100000000, - 0x527ca8d800000000, 0x4873a94300000000, 0xa0a852fa00000000, - 0xd9c22feb00000000, 0x3119d45200000000, 0xbbf0874e00000000, - 0x532b7cf700000000, 0x2a4101e600000000, 0xc29afa5f00000000, - 0xd895fbc400000000, 0x304e007d00000000, 0x49247d6c00000000, - 0xa1ff86d500000000, 0x3c3c0e8100000000, 0xd4e7f53800000000, - 0xad8d882900000000, 0x4556739000000000, 0x5f59720b00000000, - 0xb78289b200000000, 0xcee8f4a300000000, 0x26330f1a00000000, - 0xf46fe50a00000000, 0x1cb41eb300000000, 0x65de63a200000000, - 0x8d05981b00000000, 0x970a998000000000, 0x7fd1623900000000, - 0x06bb1f2800000000, 0xee60e49100000000, 0x73a36cc500000000, - 0x9b78977c00000000, 0xe212ea6d00000000, 0x0ac911d400000000, - 0x10c6104f00000000, 0xf81debf600000000, 0x817796e700000000, - 0x69ac6d5e00000000, 0x25ce42c600000000, 0xcd15b97f00000000, - 0xb47fc46e00000000, 0x5ca43fd700000000, 0x46ab3e4c00000000, - 0xae70c5f500000000, 0xd71ab8e400000000, 0x3fc1435d00000000, - 0xa202cb0900000000, 0x4ad930b000000000, 0x33b34da100000000, - 0xdb68b61800000000, 0xc167b78300000000, 0x29bc4c3a00000000, - 0x50d6312b00000000, 0xb80dca9200000000, 0x6a51208200000000, - 0x828adb3b00000000, 0xfbe0a62a00000000, 0x133b5d9300000000, - 0x09345c0800000000, 0xe1efa7b100000000, 0x9885daa000000000, - 0x705e211900000000, 0xed9da94d00000000, 0x054652f400000000, - 0x7c2c2fe500000000, 0x94f7d45c00000000, 0x8ef8d5c700000000, - 0x66232e7e00000000, 0x1f49536f00000000, 0xf792a8d600000000, - 0xc68b7c8400000000, 0x2e50873d00000000, 0x573afa2c00000000, - 0xbfe1019500000000, 0xa5ee000e00000000, 0x4d35fbb700000000, - 0x345f86a600000000, 0xdc847d1f00000000, 0x4147f54b00000000, - 0xa99c0ef200000000, 0xd0f673e300000000, 0x382d885a00000000, - 0x222289c100000000, 0xcaf9727800000000, 0xb3930f6900000000, - 0x5b48f4d000000000, 0x89141ec000000000, 0x61cfe57900000000, - 0x18a5986800000000, 0xf07e63d100000000, 0xea71624a00000000, - 0x02aa99f300000000, 0x7bc0e4e200000000, 0x931b1f5b00000000, - 0x0ed8970f00000000, 0xe6036cb600000000, 0x9f6911a700000000, - 0x77b2ea1e00000000, 0x6dbdeb8500000000, 0x8566103c00000000, - 0xfc0c6d2d00000000, 0x14d7969400000000, 0x58b5b90c00000000, - 0xb06e42b500000000, 0xc9043fa400000000, 0x21dfc41d00000000, - 0x3bd0c58600000000, 0xd30b3e3f00000000, 0xaa61432e00000000, - 0x42bab89700000000, 0xdf7930c300000000, 0x37a2cb7a00000000, - 0x4ec8b66b00000000, 0xa6134dd200000000, 0xbc1c4c4900000000, - 0x54c7b7f000000000, 0x2dadcae100000000, 0xc576315800000000, - 0x172adb4800000000, 0xfff120f100000000, 0x869b5de000000000, - 0x6e40a65900000000, 0x744fa7c200000000, 0x9c945c7b00000000, - 0xe5fe216a00000000, 0x0d25dad300000000, 0x90e6528700000000, - 0x783da93e00000000, 0x0157d42f00000000, 0xe98c2f9600000000, - 0xf3832e0d00000000, 0x1b58d5b400000000, 0x6232a8a500000000, - 0x8ae9531c00000000}, - {0x0000000000000000, 0x919168ae00000000, 0x6325a08700000000, - 0xf2b4c82900000000, 0x874c31d400000000, 0x16dd597a00000000, - 0xe469915300000000, 0x75f8f9fd00000000, 0x4f9f137300000000, - 0xde0e7bdd00000000, 0x2cbab3f400000000, 0xbd2bdb5a00000000, - 0xc8d322a700000000, 0x59424a0900000000, 0xabf6822000000000, - 0x3a67ea8e00000000, 0x9e3e27e600000000, 0x0faf4f4800000000, - 0xfd1b876100000000, 0x6c8aefcf00000000, 0x1972163200000000, - 0x88e37e9c00000000, 0x7a57b6b500000000, 0xebc6de1b00000000, - 0xd1a1349500000000, 0x40305c3b00000000, 0xb284941200000000, - 0x2315fcbc00000000, 0x56ed054100000000, 0xc77c6def00000000, - 0x35c8a5c600000000, 0xa459cd6800000000, 0x7d7b3f1700000000, - 0xecea57b900000000, 0x1e5e9f9000000000, 0x8fcff73e00000000, - 0xfa370ec300000000, 0x6ba6666d00000000, 0x9912ae4400000000, - 0x0883c6ea00000000, 0x32e42c6400000000, 0xa37544ca00000000, - 0x51c18ce300000000, 0xc050e44d00000000, 0xb5a81db000000000, - 0x2439751e00000000, 0xd68dbd3700000000, 0x471cd59900000000, - 0xe34518f100000000, 0x72d4705f00000000, 0x8060b87600000000, - 0x11f1d0d800000000, 0x6409292500000000, 0xf598418b00000000, - 0x072c89a200000000, 0x96bde10c00000000, 0xacda0b8200000000, - 0x3d4b632c00000000, 0xcfffab0500000000, 0x5e6ec3ab00000000, - 0x2b963a5600000000, 0xba0752f800000000, 0x48b39ad100000000, - 0xd922f27f00000000, 0xfaf67e2e00000000, 0x6b67168000000000, - 0x99d3dea900000000, 0x0842b60700000000, 0x7dba4ffa00000000, - 0xec2b275400000000, 0x1e9fef7d00000000, 0x8f0e87d300000000, - 0xb5696d5d00000000, 0x24f805f300000000, 0xd64ccdda00000000, - 0x47dda57400000000, 0x32255c8900000000, 0xa3b4342700000000, - 0x5100fc0e00000000, 0xc09194a000000000, 0x64c859c800000000, - 0xf559316600000000, 0x07edf94f00000000, 0x967c91e100000000, - 0xe384681c00000000, 0x721500b200000000, 0x80a1c89b00000000, - 0x1130a03500000000, 0x2b574abb00000000, 0xbac6221500000000, - 0x4872ea3c00000000, 0xd9e3829200000000, 0xac1b7b6f00000000, - 0x3d8a13c100000000, 0xcf3edbe800000000, 0x5eafb34600000000, - 0x878d413900000000, 0x161c299700000000, 0xe4a8e1be00000000, - 0x7539891000000000, 0x00c170ed00000000, 0x9150184300000000, - 0x63e4d06a00000000, 0xf275b8c400000000, 0xc812524a00000000, - 0x59833ae400000000, 0xab37f2cd00000000, 0x3aa69a6300000000, - 0x4f5e639e00000000, 0xdecf0b3000000000, 0x2c7bc31900000000, - 0xbdeaabb700000000, 0x19b366df00000000, 0x88220e7100000000, - 0x7a96c65800000000, 0xeb07aef600000000, 0x9eff570b00000000, - 0x0f6e3fa500000000, 0xfddaf78c00000000, 0x6c4b9f2200000000, - 0x562c75ac00000000, 0xc7bd1d0200000000, 0x3509d52b00000000, - 0xa498bd8500000000, 0xd160447800000000, 0x40f12cd600000000, - 0xb245e4ff00000000, 0x23d48c5100000000, 0xf4edfd5c00000000, - 0x657c95f200000000, 0x97c85ddb00000000, 0x0659357500000000, - 0x73a1cc8800000000, 0xe230a42600000000, 0x10846c0f00000000, - 0x811504a100000000, 0xbb72ee2f00000000, 0x2ae3868100000000, - 0xd8574ea800000000, 0x49c6260600000000, 0x3c3edffb00000000, - 0xadafb75500000000, 0x5f1b7f7c00000000, 0xce8a17d200000000, - 0x6ad3daba00000000, 0xfb42b21400000000, 0x09f67a3d00000000, - 0x9867129300000000, 0xed9feb6e00000000, 0x7c0e83c000000000, - 0x8eba4be900000000, 0x1f2b234700000000, 0x254cc9c900000000, - 0xb4dda16700000000, 0x4669694e00000000, 0xd7f801e000000000, - 0xa200f81d00000000, 0x339190b300000000, 0xc125589a00000000, - 0x50b4303400000000, 0x8996c24b00000000, 0x1807aae500000000, - 0xeab362cc00000000, 0x7b220a6200000000, 0x0edaf39f00000000, - 0x9f4b9b3100000000, 0x6dff531800000000, 0xfc6e3bb600000000, - 0xc609d13800000000, 0x5798b99600000000, 0xa52c71bf00000000, - 0x34bd191100000000, 0x4145e0ec00000000, 0xd0d4884200000000, - 0x2260406b00000000, 0xb3f128c500000000, 0x17a8e5ad00000000, - 0x86398d0300000000, 0x748d452a00000000, 0xe51c2d8400000000, - 0x90e4d47900000000, 0x0175bcd700000000, 0xf3c174fe00000000, - 0x62501c5000000000, 0x5837f6de00000000, 0xc9a69e7000000000, - 0x3b12565900000000, 0xaa833ef700000000, 0xdf7bc70a00000000, - 0x4eeaafa400000000, 0xbc5e678d00000000, 0x2dcf0f2300000000, - 0x0e1b837200000000, 0x9f8aebdc00000000, 0x6d3e23f500000000, - 0xfcaf4b5b00000000, 0x8957b2a600000000, 0x18c6da0800000000, - 0xea72122100000000, 0x7be37a8f00000000, 0x4184900100000000, - 0xd015f8af00000000, 0x22a1308600000000, 0xb330582800000000, - 0xc6c8a1d500000000, 0x5759c97b00000000, 0xa5ed015200000000, - 0x347c69fc00000000, 0x9025a49400000000, 0x01b4cc3a00000000, - 0xf300041300000000, 0x62916cbd00000000, 0x1769954000000000, - 0x86f8fdee00000000, 0x744c35c700000000, 0xe5dd5d6900000000, - 0xdfbab7e700000000, 0x4e2bdf4900000000, 0xbc9f176000000000, - 0x2d0e7fce00000000, 0x58f6863300000000, 0xc967ee9d00000000, - 0x3bd326b400000000, 0xaa424e1a00000000, 0x7360bc6500000000, - 0xe2f1d4cb00000000, 0x10451ce200000000, 0x81d4744c00000000, - 0xf42c8db100000000, 0x65bde51f00000000, 0x97092d3600000000, - 0x0698459800000000, 0x3cffaf1600000000, 0xad6ec7b800000000, - 0x5fda0f9100000000, 0xce4b673f00000000, 0xbbb39ec200000000, - 0x2a22f66c00000000, 0xd8963e4500000000, 0x490756eb00000000, - 0xed5e9b8300000000, 0x7ccff32d00000000, 0x8e7b3b0400000000, - 0x1fea53aa00000000, 0x6a12aa5700000000, 0xfb83c2f900000000, - 0x09370ad000000000, 0x98a6627e00000000, 0xa2c188f000000000, - 0x3350e05e00000000, 0xc1e4287700000000, 0x507540d900000000, - 0x258db92400000000, 0xb41cd18a00000000, 0x46a819a300000000, - 0xd739710d00000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, - 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, - 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, - 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, - 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, - 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, - 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, - 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, - 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, - 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, - 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, - 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, - 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, - 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, - 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, - 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, - 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, - 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, - 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, - 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, - 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, - 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, - 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, - 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, - 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, - 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, - 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, - 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, - 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, - 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, - 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, - 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, - 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, - 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, - 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, - 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, - 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, - 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, - 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, - 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, - 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, - 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, - 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, - 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, - 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, - 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, - 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, - 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, - 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, - 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, - 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, - 0x264b06e6}, - {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, - 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, - 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, - 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, - 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, - 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, - 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, - 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, - 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, - 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, - 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, - 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, - 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, - 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, - 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, - 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, - 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, - 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, - 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, - 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, - 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, - 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, - 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, - 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, - 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, - 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, - 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, - 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, - 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, - 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, - 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, - 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, - 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, - 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, - 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, - 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, - 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, - 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, - 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, - 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, - 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, - 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, - 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, - 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, - 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, - 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, - 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, - 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, - 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, - 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, - 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, - 0x92364a30}, - {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, - 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, - 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, - 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, - 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, - 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, - 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, - 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, - 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, - 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, - 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, - 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, - 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, - 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, - 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, - 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, - 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, - 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, - 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, - 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, - 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, - 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, - 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, - 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, - 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, - 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, - 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, - 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, - 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, - 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, - 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, - 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, - 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, - 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, - 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, - 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, - 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, - 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, - 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, - 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, - 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, - 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, - 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, - 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, - 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, - 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, - 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, - 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, - 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, - 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, - 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, - 0xe4c4abcc}, - {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, - 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, - 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, - 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, - 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, - 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, - 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, - 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, - 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, - 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, - 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, - 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, - 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, - 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, - 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, - 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, - 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, - 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, - 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, - 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, - 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, - 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, - 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, - 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, - 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, - 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, - 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, - 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, - 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, - 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, - 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, - 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, - 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, - 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, - 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, - 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, - 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, - 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, - 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, - 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, - 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, - 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, - 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, - 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, - 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, - 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, - 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, - 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, - 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, - 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, - 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, - 0xca64c78c}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0xb029603d, 0x6053c07a, 0xd07aa047, 0xc0a680f5, - 0x708fe0c8, 0xa0f5408f, 0x10dc20b2, 0xc14b7030, 0x7162100d, - 0xa118b04a, 0x1131d077, 0x01edf0c5, 0xb1c490f8, 0x61be30bf, - 0xd1975082, 0x8297e060, 0x32be805d, 0xe2c4201a, 0x52ed4027, - 0x42316095, 0xf21800a8, 0x2262a0ef, 0x924bc0d2, 0x43dc9050, - 0xf3f5f06d, 0x238f502a, 0x93a63017, 0x837a10a5, 0x33537098, - 0xe329d0df, 0x5300b0e2, 0x042fc1c1, 0xb406a1fc, 0x647c01bb, - 0xd4556186, 0xc4894134, 0x74a02109, 0xa4da814e, 0x14f3e173, - 0xc564b1f1, 0x754dd1cc, 0xa537718b, 0x151e11b6, 0x05c23104, - 0xb5eb5139, 0x6591f17e, 0xd5b89143, 0x86b821a1, 0x3691419c, - 0xe6ebe1db, 0x56c281e6, 0x461ea154, 0xf637c169, 0x264d612e, - 0x96640113, 0x47f35191, 0xf7da31ac, 0x27a091eb, 0x9789f1d6, - 0x8755d164, 0x377cb159, 0xe706111e, 0x572f7123, 0x4958f358, - 0xf9719365, 0x290b3322, 0x9922531f, 0x89fe73ad, 0x39d71390, - 0xe9adb3d7, 0x5984d3ea, 0x88138368, 0x383ae355, 0xe8404312, - 0x5869232f, 0x48b5039d, 0xf89c63a0, 0x28e6c3e7, 0x98cfa3da, - 0xcbcf1338, 0x7be67305, 0xab9cd342, 0x1bb5b37f, 0x0b6993cd, - 0xbb40f3f0, 0x6b3a53b7, 0xdb13338a, 0x0a846308, 0xbaad0335, - 0x6ad7a372, 0xdafec34f, 0xca22e3fd, 0x7a0b83c0, 0xaa712387, - 0x1a5843ba, 0x4d773299, 0xfd5e52a4, 0x2d24f2e3, 0x9d0d92de, - 0x8dd1b26c, 0x3df8d251, 0xed827216, 0x5dab122b, 0x8c3c42a9, - 0x3c152294, 0xec6f82d3, 0x5c46e2ee, 0x4c9ac25c, 0xfcb3a261, - 0x2cc90226, 0x9ce0621b, 0xcfe0d2f9, 0x7fc9b2c4, 0xafb31283, - 0x1f9a72be, 0x0f46520c, 0xbf6f3231, 0x6f159276, 0xdf3cf24b, - 0x0eaba2c9, 0xbe82c2f4, 0x6ef862b3, 0xded1028e, 0xce0d223c, - 0x7e244201, 0xae5ee246, 0x1e77827b, 0x92b0e6b1, 0x2299868c, - 0xf2e326cb, 0x42ca46f6, 0x52166644, 0xe23f0679, 0x3245a63e, - 0x826cc603, 0x53fb9681, 0xe3d2f6bc, 0x33a856fb, 0x838136c6, - 0x935d1674, 0x23747649, 0xf30ed60e, 0x4327b633, 0x102706d1, - 0xa00e66ec, 0x7074c6ab, 0xc05da696, 0xd0818624, 0x60a8e619, - 0xb0d2465e, 0x00fb2663, 0xd16c76e1, 0x614516dc, 0xb13fb69b, - 0x0116d6a6, 0x11caf614, 0xa1e39629, 0x7199366e, 0xc1b05653, - 0x969f2770, 0x26b6474d, 0xf6cce70a, 0x46e58737, 0x5639a785, - 0xe610c7b8, 0x366a67ff, 0x864307c2, 0x57d45740, 0xe7fd377d, - 0x3787973a, 0x87aef707, 0x9772d7b5, 0x275bb788, 0xf72117cf, - 0x470877f2, 0x1408c710, 0xa421a72d, 0x745b076a, 0xc4726757, - 0xd4ae47e5, 0x648727d8, 0xb4fd879f, 0x04d4e7a2, 0xd543b720, - 0x656ad71d, 0xb510775a, 0x05391767, 0x15e537d5, 0xa5cc57e8, - 0x75b6f7af, 0xc59f9792, 0xdbe815e9, 0x6bc175d4, 0xbbbbd593, - 0x0b92b5ae, 0x1b4e951c, 0xab67f521, 0x7b1d5566, 0xcb34355b, - 0x1aa365d9, 0xaa8a05e4, 0x7af0a5a3, 0xcad9c59e, 0xda05e52c, - 0x6a2c8511, 0xba562556, 0x0a7f456b, 0x597ff589, 0xe95695b4, - 0x392c35f3, 0x890555ce, 0x99d9757c, 0x29f01541, 0xf98ab506, - 0x49a3d53b, 0x983485b9, 0x281de584, 0xf86745c3, 0x484e25fe, - 0x5892054c, 0xe8bb6571, 0x38c1c536, 0x88e8a50b, 0xdfc7d428, - 0x6feeb415, 0xbf941452, 0x0fbd746f, 0x1f6154dd, 0xaf4834e0, - 0x7f3294a7, 0xcf1bf49a, 0x1e8ca418, 0xaea5c425, 0x7edf6462, - 0xcef6045f, 0xde2a24ed, 0x6e0344d0, 0xbe79e497, 0x0e5084aa, - 0x5d503448, 0xed795475, 0x3d03f432, 0x8d2a940f, 0x9df6b4bd, - 0x2ddfd480, 0xfda574c7, 0x4d8c14fa, 0x9c1b4478, 0x2c322445, - 0xfc488402, 0x4c61e43f, 0x5cbdc48d, 0xec94a4b0, 0x3cee04f7, - 0x8cc764ca}, - {0x00000000, 0xa5d35ccb, 0x0ba1c84d, 0xae729486, 0x1642919b, - 0xb391cd50, 0x1de359d6, 0xb830051d, 0x6d8253ec, 0xc8510f27, - 0x66239ba1, 0xc3f0c76a, 0x7bc0c277, 0xde139ebc, 0x70610a3a, - 0xd5b256f1, 0x9b02d603, 0x3ed18ac8, 0x90a31e4e, 0x35704285, - 0x8d404798, 0x28931b53, 0x86e18fd5, 0x2332d31e, 0xf68085ef, - 0x5353d924, 0xfd214da2, 0x58f21169, 0xe0c21474, 0x451148bf, - 0xeb63dc39, 0x4eb080f2, 0x3605ac07, 0x93d6f0cc, 0x3da4644a, - 0x98773881, 0x20473d9c, 0x85946157, 0x2be6f5d1, 0x8e35a91a, - 0x5b87ffeb, 0xfe54a320, 0x502637a6, 0xf5f56b6d, 0x4dc56e70, - 0xe81632bb, 0x4664a63d, 0xe3b7faf6, 0xad077a04, 0x08d426cf, - 0xa6a6b249, 0x0375ee82, 0xbb45eb9f, 0x1e96b754, 0xb0e423d2, - 0x15377f19, 0xc08529e8, 0x65567523, 0xcb24e1a5, 0x6ef7bd6e, - 0xd6c7b873, 0x7314e4b8, 0xdd66703e, 0x78b52cf5, 0x6c0a580f, - 0xc9d904c4, 0x67ab9042, 0xc278cc89, 0x7a48c994, 0xdf9b955f, - 0x71e901d9, 0xd43a5d12, 0x01880be3, 0xa45b5728, 0x0a29c3ae, - 0xaffa9f65, 0x17ca9a78, 0xb219c6b3, 0x1c6b5235, 0xb9b80efe, - 0xf7088e0c, 0x52dbd2c7, 0xfca94641, 0x597a1a8a, 0xe14a1f97, - 0x4499435c, 0xeaebd7da, 0x4f388b11, 0x9a8adde0, 0x3f59812b, - 0x912b15ad, 0x34f84966, 0x8cc84c7b, 0x291b10b0, 0x87698436, - 0x22bad8fd, 0x5a0ff408, 0xffdca8c3, 0x51ae3c45, 0xf47d608e, - 0x4c4d6593, 0xe99e3958, 0x47ecadde, 0xe23ff115, 0x378da7e4, - 0x925efb2f, 0x3c2c6fa9, 0x99ff3362, 0x21cf367f, 0x841c6ab4, - 0x2a6efe32, 0x8fbda2f9, 0xc10d220b, 0x64de7ec0, 0xcaacea46, - 0x6f7fb68d, 0xd74fb390, 0x729cef5b, 0xdcee7bdd, 0x793d2716, - 0xac8f71e7, 0x095c2d2c, 0xa72eb9aa, 0x02fde561, 0xbacde07c, - 0x1f1ebcb7, 0xb16c2831, 0x14bf74fa, 0xd814b01e, 0x7dc7ecd5, - 0xd3b57853, 0x76662498, 0xce562185, 0x6b857d4e, 0xc5f7e9c8, - 0x6024b503, 0xb596e3f2, 0x1045bf39, 0xbe372bbf, 0x1be47774, - 0xa3d47269, 0x06072ea2, 0xa875ba24, 0x0da6e6ef, 0x4316661d, - 0xe6c53ad6, 0x48b7ae50, 0xed64f29b, 0x5554f786, 0xf087ab4d, - 0x5ef53fcb, 0xfb266300, 0x2e9435f1, 0x8b47693a, 0x2535fdbc, - 0x80e6a177, 0x38d6a46a, 0x9d05f8a1, 0x33776c27, 0x96a430ec, - 0xee111c19, 0x4bc240d2, 0xe5b0d454, 0x4063889f, 0xf8538d82, - 0x5d80d149, 0xf3f245cf, 0x56211904, 0x83934ff5, 0x2640133e, - 0x883287b8, 0x2de1db73, 0x95d1de6e, 0x300282a5, 0x9e701623, - 0x3ba34ae8, 0x7513ca1a, 0xd0c096d1, 0x7eb20257, 0xdb615e9c, - 0x63515b81, 0xc682074a, 0x68f093cc, 0xcd23cf07, 0x189199f6, - 0xbd42c53d, 0x133051bb, 0xb6e30d70, 0x0ed3086d, 0xab0054a6, - 0x0572c020, 0xa0a19ceb, 0xb41ee811, 0x11cdb4da, 0xbfbf205c, - 0x1a6c7c97, 0xa25c798a, 0x078f2541, 0xa9fdb1c7, 0x0c2eed0c, - 0xd99cbbfd, 0x7c4fe736, 0xd23d73b0, 0x77ee2f7b, 0xcfde2a66, - 0x6a0d76ad, 0xc47fe22b, 0x61acbee0, 0x2f1c3e12, 0x8acf62d9, - 0x24bdf65f, 0x816eaa94, 0x395eaf89, 0x9c8df342, 0x32ff67c4, - 0x972c3b0f, 0x429e6dfe, 0xe74d3135, 0x493fa5b3, 0xececf978, - 0x54dcfc65, 0xf10fa0ae, 0x5f7d3428, 0xfaae68e3, 0x821b4416, - 0x27c818dd, 0x89ba8c5b, 0x2c69d090, 0x9459d58d, 0x318a8946, - 0x9ff81dc0, 0x3a2b410b, 0xef9917fa, 0x4a4a4b31, 0xe438dfb7, - 0x41eb837c, 0xf9db8661, 0x5c08daaa, 0xf27a4e2c, 0x57a912e7, - 0x19199215, 0xbccacede, 0x12b85a58, 0xb76b0693, 0x0f5b038e, - 0xaa885f45, 0x04facbc3, 0xa1299708, 0x749bc1f9, 0xd1489d32, - 0x7f3a09b4, 0xdae9557f, 0x62d95062, 0xc70a0ca9, 0x6978982f, - 0xccabc4e4}, - {0x00000000, 0xb40b77a6, 0x29119f97, 0x9d1ae831, 0x13244ff4, - 0xa72f3852, 0x3a35d063, 0x8e3ea7c5, 0x674eef33, 0xd3459895, - 0x4e5f70a4, 0xfa540702, 0x746aa0c7, 0xc061d761, 0x5d7b3f50, - 0xe97048f6, 0xce9cde67, 0x7a97a9c1, 0xe78d41f0, 0x53863656, - 0xddb89193, 0x69b3e635, 0xf4a90e04, 0x40a279a2, 0xa9d23154, - 0x1dd946f2, 0x80c3aec3, 0x34c8d965, 0xbaf67ea0, 0x0efd0906, - 0x93e7e137, 0x27ec9691, 0x9c39bdcf, 0x2832ca69, 0xb5282258, - 0x012355fe, 0x8f1df23b, 0x3b16859d, 0xa60c6dac, 0x12071a0a, - 0xfb7752fc, 0x4f7c255a, 0xd266cd6b, 0x666dbacd, 0xe8531d08, - 0x5c586aae, 0xc142829f, 0x7549f539, 0x52a563a8, 0xe6ae140e, - 0x7bb4fc3f, 0xcfbf8b99, 0x41812c5c, 0xf58a5bfa, 0x6890b3cb, - 0xdc9bc46d, 0x35eb8c9b, 0x81e0fb3d, 0x1cfa130c, 0xa8f164aa, - 0x26cfc36f, 0x92c4b4c9, 0x0fde5cf8, 0xbbd52b5e, 0x79750b44, - 0xcd7e7ce2, 0x506494d3, 0xe46fe375, 0x6a5144b0, 0xde5a3316, - 0x4340db27, 0xf74bac81, 0x1e3be477, 0xaa3093d1, 0x372a7be0, - 0x83210c46, 0x0d1fab83, 0xb914dc25, 0x240e3414, 0x900543b2, - 0xb7e9d523, 0x03e2a285, 0x9ef84ab4, 0x2af33d12, 0xa4cd9ad7, - 0x10c6ed71, 0x8ddc0540, 0x39d772e6, 0xd0a73a10, 0x64ac4db6, - 0xf9b6a587, 0x4dbdd221, 0xc38375e4, 0x77880242, 0xea92ea73, - 0x5e999dd5, 0xe54cb68b, 0x5147c12d, 0xcc5d291c, 0x78565eba, - 0xf668f97f, 0x42638ed9, 0xdf7966e8, 0x6b72114e, 0x820259b8, - 0x36092e1e, 0xab13c62f, 0x1f18b189, 0x9126164c, 0x252d61ea, - 0xb83789db, 0x0c3cfe7d, 0x2bd068ec, 0x9fdb1f4a, 0x02c1f77b, - 0xb6ca80dd, 0x38f42718, 0x8cff50be, 0x11e5b88f, 0xa5eecf29, - 0x4c9e87df, 0xf895f079, 0x658f1848, 0xd1846fee, 0x5fbac82b, - 0xebb1bf8d, 0x76ab57bc, 0xc2a0201a, 0xf2ea1688, 0x46e1612e, - 0xdbfb891f, 0x6ff0feb9, 0xe1ce597c, 0x55c52eda, 0xc8dfc6eb, - 0x7cd4b14d, 0x95a4f9bb, 0x21af8e1d, 0xbcb5662c, 0x08be118a, - 0x8680b64f, 0x328bc1e9, 0xaf9129d8, 0x1b9a5e7e, 0x3c76c8ef, - 0x887dbf49, 0x15675778, 0xa16c20de, 0x2f52871b, 0x9b59f0bd, - 0x0643188c, 0xb2486f2a, 0x5b3827dc, 0xef33507a, 0x7229b84b, - 0xc622cfed, 0x481c6828, 0xfc171f8e, 0x610df7bf, 0xd5068019, - 0x6ed3ab47, 0xdad8dce1, 0x47c234d0, 0xf3c94376, 0x7df7e4b3, - 0xc9fc9315, 0x54e67b24, 0xe0ed0c82, 0x099d4474, 0xbd9633d2, - 0x208cdbe3, 0x9487ac45, 0x1ab90b80, 0xaeb27c26, 0x33a89417, - 0x87a3e3b1, 0xa04f7520, 0x14440286, 0x895eeab7, 0x3d559d11, - 0xb36b3ad4, 0x07604d72, 0x9a7aa543, 0x2e71d2e5, 0xc7019a13, - 0x730aedb5, 0xee100584, 0x5a1b7222, 0xd425d5e7, 0x602ea241, - 0xfd344a70, 0x493f3dd6, 0x8b9f1dcc, 0x3f946a6a, 0xa28e825b, - 0x1685f5fd, 0x98bb5238, 0x2cb0259e, 0xb1aacdaf, 0x05a1ba09, - 0xecd1f2ff, 0x58da8559, 0xc5c06d68, 0x71cb1ace, 0xfff5bd0b, - 0x4bfecaad, 0xd6e4229c, 0x62ef553a, 0x4503c3ab, 0xf108b40d, - 0x6c125c3c, 0xd8192b9a, 0x56278c5f, 0xe22cfbf9, 0x7f3613c8, - 0xcb3d646e, 0x224d2c98, 0x96465b3e, 0x0b5cb30f, 0xbf57c4a9, - 0x3169636c, 0x856214ca, 0x1878fcfb, 0xac738b5d, 0x17a6a003, - 0xa3add7a5, 0x3eb73f94, 0x8abc4832, 0x0482eff7, 0xb0899851, - 0x2d937060, 0x999807c6, 0x70e84f30, 0xc4e33896, 0x59f9d0a7, - 0xedf2a701, 0x63cc00c4, 0xd7c77762, 0x4add9f53, 0xfed6e8f5, - 0xd93a7e64, 0x6d3109c2, 0xf02be1f3, 0x44209655, 0xca1e3190, - 0x7e154636, 0xe30fae07, 0x5704d9a1, 0xbe749157, 0x0a7fe6f1, - 0x97650ec0, 0x236e7966, 0xad50dea3, 0x195ba905, 0x84414134, - 0x304a3692}, - {0x00000000, 0x9e00aacc, 0x7d072542, 0xe3078f8e, 0xfa0e4a84, - 0x640ee048, 0x87096fc6, 0x1909c50a, 0xb51be5d3, 0x2b1b4f1f, - 0xc81cc091, 0x561c6a5d, 0x4f15af57, 0xd115059b, 0x32128a15, - 0xac1220d9, 0x2b31bb7c, 0xb53111b0, 0x56369e3e, 0xc83634f2, - 0xd13ff1f8, 0x4f3f5b34, 0xac38d4ba, 0x32387e76, 0x9e2a5eaf, - 0x002af463, 0xe32d7bed, 0x7d2dd121, 0x6424142b, 0xfa24bee7, - 0x19233169, 0x87239ba5, 0x566276f9, 0xc862dc35, 0x2b6553bb, - 0xb565f977, 0xac6c3c7d, 0x326c96b1, 0xd16b193f, 0x4f6bb3f3, - 0xe379932a, 0x7d7939e6, 0x9e7eb668, 0x007e1ca4, 0x1977d9ae, - 0x87777362, 0x6470fcec, 0xfa705620, 0x7d53cd85, 0xe3536749, - 0x0054e8c7, 0x9e54420b, 0x875d8701, 0x195d2dcd, 0xfa5aa243, - 0x645a088f, 0xc8482856, 0x5648829a, 0xb54f0d14, 0x2b4fa7d8, - 0x324662d2, 0xac46c81e, 0x4f414790, 0xd141ed5c, 0xedc29d29, - 0x73c237e5, 0x90c5b86b, 0x0ec512a7, 0x17ccd7ad, 0x89cc7d61, - 0x6acbf2ef, 0xf4cb5823, 0x58d978fa, 0xc6d9d236, 0x25de5db8, - 0xbbdef774, 0xa2d7327e, 0x3cd798b2, 0xdfd0173c, 0x41d0bdf0, - 0xc6f32655, 0x58f38c99, 0xbbf40317, 0x25f4a9db, 0x3cfd6cd1, - 0xa2fdc61d, 0x41fa4993, 0xdffae35f, 0x73e8c386, 0xede8694a, - 0x0eefe6c4, 0x90ef4c08, 0x89e68902, 0x17e623ce, 0xf4e1ac40, - 0x6ae1068c, 0xbba0ebd0, 0x25a0411c, 0xc6a7ce92, 0x58a7645e, - 0x41aea154, 0xdfae0b98, 0x3ca98416, 0xa2a92eda, 0x0ebb0e03, - 0x90bba4cf, 0x73bc2b41, 0xedbc818d, 0xf4b54487, 0x6ab5ee4b, - 0x89b261c5, 0x17b2cb09, 0x909150ac, 0x0e91fa60, 0xed9675ee, - 0x7396df22, 0x6a9f1a28, 0xf49fb0e4, 0x17983f6a, 0x899895a6, - 0x258ab57f, 0xbb8a1fb3, 0x588d903d, 0xc68d3af1, 0xdf84fffb, - 0x41845537, 0xa283dab9, 0x3c837075, 0xda853b53, 0x4485919f, - 0xa7821e11, 0x3982b4dd, 0x208b71d7, 0xbe8bdb1b, 0x5d8c5495, - 0xc38cfe59, 0x6f9ede80, 0xf19e744c, 0x1299fbc2, 0x8c99510e, - 0x95909404, 0x0b903ec8, 0xe897b146, 0x76971b8a, 0xf1b4802f, - 0x6fb42ae3, 0x8cb3a56d, 0x12b30fa1, 0x0bbacaab, 0x95ba6067, - 0x76bdefe9, 0xe8bd4525, 0x44af65fc, 0xdaafcf30, 0x39a840be, - 0xa7a8ea72, 0xbea12f78, 0x20a185b4, 0xc3a60a3a, 0x5da6a0f6, - 0x8ce74daa, 0x12e7e766, 0xf1e068e8, 0x6fe0c224, 0x76e9072e, - 0xe8e9ade2, 0x0bee226c, 0x95ee88a0, 0x39fca879, 0xa7fc02b5, - 0x44fb8d3b, 0xdafb27f7, 0xc3f2e2fd, 0x5df24831, 0xbef5c7bf, - 0x20f56d73, 0xa7d6f6d6, 0x39d65c1a, 0xdad1d394, 0x44d17958, - 0x5dd8bc52, 0xc3d8169e, 0x20df9910, 0xbedf33dc, 0x12cd1305, - 0x8ccdb9c9, 0x6fca3647, 0xf1ca9c8b, 0xe8c35981, 0x76c3f34d, - 0x95c47cc3, 0x0bc4d60f, 0x3747a67a, 0xa9470cb6, 0x4a408338, - 0xd44029f4, 0xcd49ecfe, 0x53494632, 0xb04ec9bc, 0x2e4e6370, - 0x825c43a9, 0x1c5ce965, 0xff5b66eb, 0x615bcc27, 0x7852092d, - 0xe652a3e1, 0x05552c6f, 0x9b5586a3, 0x1c761d06, 0x8276b7ca, - 0x61713844, 0xff719288, 0xe6785782, 0x7878fd4e, 0x9b7f72c0, - 0x057fd80c, 0xa96df8d5, 0x376d5219, 0xd46add97, 0x4a6a775b, - 0x5363b251, 0xcd63189d, 0x2e649713, 0xb0643ddf, 0x6125d083, - 0xff257a4f, 0x1c22f5c1, 0x82225f0d, 0x9b2b9a07, 0x052b30cb, - 0xe62cbf45, 0x782c1589, 0xd43e3550, 0x4a3e9f9c, 0xa9391012, - 0x3739bade, 0x2e307fd4, 0xb030d518, 0x53375a96, 0xcd37f05a, - 0x4a146bff, 0xd414c133, 0x37134ebd, 0xa913e471, 0xb01a217b, - 0x2e1a8bb7, 0xcd1d0439, 0x531daef5, 0xff0f8e2c, 0x610f24e0, - 0x8208ab6e, 0x1c0801a2, 0x0501c4a8, 0x9b016e64, 0x7806e1ea, - 0xe6064b26}}; - -#endif - -#endif - -#if N == 3 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, - 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, - 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, - 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, - 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, - 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, - 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, - 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, - 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, - 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, - 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, - 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, - 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, - 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, - 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, - 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, - 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, - 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, - 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, - 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, - 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, - 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, - 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, - 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, - 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, - 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, - 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, - 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, - 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, - 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, - 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, - 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, - 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, - 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, - 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, - 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, - 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, - 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, - 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, - 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, - 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, - 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, - 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, - 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, - 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, - 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, - 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, - 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, - 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, - 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, - 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, - 0x09cd8551}, - {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, - 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, - 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, - 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, - 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, - 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, - 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, - 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, - 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, - 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, - 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, - 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, - 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, - 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, - 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, - 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, - 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, - 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, - 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, - 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, - 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, - 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, - 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, - 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, - 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, - 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, - 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, - 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, - 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, - 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, - 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, - 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, - 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, - 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, - 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, - 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, - 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, - 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, - 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, - 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, - 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, - 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, - 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, - 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, - 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, - 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, - 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, - 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, - 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, - 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, - 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, - 0x7bc97a0c}, - {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, - 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, - 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, - 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, - 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, - 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, - 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, - 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, - 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, - 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, - 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, - 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, - 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, - 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, - 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, - 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, - 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, - 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, - 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, - 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, - 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, - 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, - 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, - 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, - 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, - 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, - 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, - 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, - 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, - 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, - 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, - 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, - 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, - 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, - 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, - 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, - 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, - 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, - 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, - 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, - 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, - 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, - 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, - 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, - 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, - 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, - 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, - 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, - 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, - 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, - 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, - 0x7851a2ca}, - {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, - 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, - 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, - 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, - 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, - 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, - 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, - 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, - 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, - 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, - 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, - 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, - 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, - 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, - 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, - 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, - 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, - 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, - 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, - 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, - 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, - 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, - 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, - 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, - 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, - 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, - 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, - 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, - 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, - 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, - 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, - 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, - 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, - 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, - 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, - 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, - 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, - 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, - 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, - 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, - 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, - 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, - 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, - 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, - 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, - 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, - 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, - 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, - 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, - 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, - 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, - 0x566b6848}, - {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, - 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, - 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, - 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, - 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, - 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, - 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, - 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, - 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, - 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, - 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, - 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, - 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, - 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, - 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, - 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, - 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, - 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, - 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, - 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, - 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, - 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, - 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, - 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, - 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, - 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, - 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, - 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, - 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, - 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, - 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, - 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, - 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, - 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, - 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, - 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, - 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, - 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, - 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, - 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, - 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, - 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, - 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, - 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, - 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, - 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, - 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, - 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, - 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, - 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, - 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, - 0xd8ac6b35}, - {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, - 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, - 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, - 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, - 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, - 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, - 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, - 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, - 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, - 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, - 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, - 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, - 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, - 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, - 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, - 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, - 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, - 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, - 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, - 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, - 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, - 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, - 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, - 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, - 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, - 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, - 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, - 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, - 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, - 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, - 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, - 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, - 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, - 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, - 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, - 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, - 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, - 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, - 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, - 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, - 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, - 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, - 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, - 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, - 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, - 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, - 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, - 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, - 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, - 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, - 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, - 0xa140efa8}, - {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, - 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, - 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, - 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, - 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, - 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, - 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, - 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, - 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, - 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, - 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, - 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, - 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, - 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, - 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, - 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, - 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, - 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, - 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, - 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, - 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, - 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, - 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, - 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, - 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, - 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, - 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, - 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, - 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, - 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, - 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, - 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, - 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, - 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, - 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, - 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, - 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, - 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, - 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, - 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, - 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, - 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, - 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, - 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, - 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, - 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, - 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, - 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, - 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, - 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, - 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, - 0x917cd6a1}, - {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, - 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, - 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, - 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, - 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, - 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, - 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, - 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, - 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, - 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, - 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, - 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, - 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, - 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, - 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, - 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, - 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, - 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, - 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, - 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, - 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, - 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, - 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, - 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, - 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, - 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, - 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, - 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, - 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, - 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, - 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, - 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, - 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, - 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, - 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, - 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, - 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, - 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, - 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, - 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, - 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, - 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, - 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, - 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, - 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, - 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, - 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, - 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, - 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, - 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, - 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, - 0x18ba364e}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x43cba68700000000, 0xc7903cd400000000, - 0x845b9a5300000000, 0xcf27087300000000, 0x8cecaef400000000, - 0x08b734a700000000, 0x4b7c922000000000, 0x9e4f10e600000000, - 0xdd84b66100000000, 0x59df2c3200000000, 0x1a148ab500000000, - 0x5168189500000000, 0x12a3be1200000000, 0x96f8244100000000, - 0xd53382c600000000, 0x7d99511700000000, 0x3e52f79000000000, - 0xba096dc300000000, 0xf9c2cb4400000000, 0xb2be596400000000, - 0xf175ffe300000000, 0x752e65b000000000, 0x36e5c33700000000, - 0xe3d641f100000000, 0xa01de77600000000, 0x24467d2500000000, - 0x678ddba200000000, 0x2cf1498200000000, 0x6f3aef0500000000, - 0xeb61755600000000, 0xa8aad3d100000000, 0xfa32a32e00000000, - 0xb9f905a900000000, 0x3da29ffa00000000, 0x7e69397d00000000, - 0x3515ab5d00000000, 0x76de0dda00000000, 0xf285978900000000, - 0xb14e310e00000000, 0x647db3c800000000, 0x27b6154f00000000, - 0xa3ed8f1c00000000, 0xe026299b00000000, 0xab5abbbb00000000, - 0xe8911d3c00000000, 0x6cca876f00000000, 0x2f0121e800000000, - 0x87abf23900000000, 0xc46054be00000000, 0x403bceed00000000, - 0x03f0686a00000000, 0x488cfa4a00000000, 0x0b475ccd00000000, - 0x8f1cc69e00000000, 0xccd7601900000000, 0x19e4e2df00000000, - 0x5a2f445800000000, 0xde74de0b00000000, 0x9dbf788c00000000, - 0xd6c3eaac00000000, 0x95084c2b00000000, 0x1153d67800000000, - 0x529870ff00000000, 0xf465465d00000000, 0xb7aee0da00000000, - 0x33f57a8900000000, 0x703edc0e00000000, 0x3b424e2e00000000, - 0x7889e8a900000000, 0xfcd272fa00000000, 0xbf19d47d00000000, - 0x6a2a56bb00000000, 0x29e1f03c00000000, 0xadba6a6f00000000, - 0xee71cce800000000, 0xa50d5ec800000000, 0xe6c6f84f00000000, - 0x629d621c00000000, 0x2156c49b00000000, 0x89fc174a00000000, - 0xca37b1cd00000000, 0x4e6c2b9e00000000, 0x0da78d1900000000, - 0x46db1f3900000000, 0x0510b9be00000000, 0x814b23ed00000000, - 0xc280856a00000000, 0x17b307ac00000000, 0x5478a12b00000000, - 0xd0233b7800000000, 0x93e89dff00000000, 0xd8940fdf00000000, - 0x9b5fa95800000000, 0x1f04330b00000000, 0x5ccf958c00000000, - 0x0e57e57300000000, 0x4d9c43f400000000, 0xc9c7d9a700000000, - 0x8a0c7f2000000000, 0xc170ed0000000000, 0x82bb4b8700000000, - 0x06e0d1d400000000, 0x452b775300000000, 0x9018f59500000000, - 0xd3d3531200000000, 0x5788c94100000000, 0x14436fc600000000, - 0x5f3ffde600000000, 0x1cf45b6100000000, 0x98afc13200000000, - 0xdb6467b500000000, 0x73ceb46400000000, 0x300512e300000000, - 0xb45e88b000000000, 0xf7952e3700000000, 0xbce9bc1700000000, - 0xff221a9000000000, 0x7b7980c300000000, 0x38b2264400000000, - 0xed81a48200000000, 0xae4a020500000000, 0x2a11985600000000, - 0x69da3ed100000000, 0x22a6acf100000000, 0x616d0a7600000000, - 0xe536902500000000, 0xa6fd36a200000000, 0xe8cb8cba00000000, - 0xab002a3d00000000, 0x2f5bb06e00000000, 0x6c9016e900000000, - 0x27ec84c900000000, 0x6427224e00000000, 0xe07cb81d00000000, - 0xa3b71e9a00000000, 0x76849c5c00000000, 0x354f3adb00000000, - 0xb114a08800000000, 0xf2df060f00000000, 0xb9a3942f00000000, - 0xfa6832a800000000, 0x7e33a8fb00000000, 0x3df80e7c00000000, - 0x9552ddad00000000, 0xd6997b2a00000000, 0x52c2e17900000000, - 0x110947fe00000000, 0x5a75d5de00000000, 0x19be735900000000, - 0x9de5e90a00000000, 0xde2e4f8d00000000, 0x0b1dcd4b00000000, - 0x48d66bcc00000000, 0xcc8df19f00000000, 0x8f46571800000000, - 0xc43ac53800000000, 0x87f163bf00000000, 0x03aaf9ec00000000, - 0x40615f6b00000000, 0x12f92f9400000000, 0x5132891300000000, - 0xd569134000000000, 0x96a2b5c700000000, 0xddde27e700000000, - 0x9e15816000000000, 0x1a4e1b3300000000, 0x5985bdb400000000, - 0x8cb63f7200000000, 0xcf7d99f500000000, 0x4b2603a600000000, - 0x08eda52100000000, 0x4391370100000000, 0x005a918600000000, - 0x84010bd500000000, 0xc7caad5200000000, 0x6f607e8300000000, - 0x2cabd80400000000, 0xa8f0425700000000, 0xeb3be4d000000000, - 0xa04776f000000000, 0xe38cd07700000000, 0x67d74a2400000000, - 0x241ceca300000000, 0xf12f6e6500000000, 0xb2e4c8e200000000, - 0x36bf52b100000000, 0x7574f43600000000, 0x3e08661600000000, - 0x7dc3c09100000000, 0xf9985ac200000000, 0xba53fc4500000000, - 0x1caecae700000000, 0x5f656c6000000000, 0xdb3ef63300000000, - 0x98f550b400000000, 0xd389c29400000000, 0x9042641300000000, - 0x1419fe4000000000, 0x57d258c700000000, 0x82e1da0100000000, - 0xc12a7c8600000000, 0x4571e6d500000000, 0x06ba405200000000, - 0x4dc6d27200000000, 0x0e0d74f500000000, 0x8a56eea600000000, - 0xc99d482100000000, 0x61379bf000000000, 0x22fc3d7700000000, - 0xa6a7a72400000000, 0xe56c01a300000000, 0xae10938300000000, - 0xeddb350400000000, 0x6980af5700000000, 0x2a4b09d000000000, - 0xff788b1600000000, 0xbcb32d9100000000, 0x38e8b7c200000000, - 0x7b23114500000000, 0x305f836500000000, 0x739425e200000000, - 0xf7cfbfb100000000, 0xb404193600000000, 0xe69c69c900000000, - 0xa557cf4e00000000, 0x210c551d00000000, 0x62c7f39a00000000, - 0x29bb61ba00000000, 0x6a70c73d00000000, 0xee2b5d6e00000000, - 0xade0fbe900000000, 0x78d3792f00000000, 0x3b18dfa800000000, - 0xbf4345fb00000000, 0xfc88e37c00000000, 0xb7f4715c00000000, - 0xf43fd7db00000000, 0x70644d8800000000, 0x33afeb0f00000000, - 0x9b0538de00000000, 0xd8ce9e5900000000, 0x5c95040a00000000, - 0x1f5ea28d00000000, 0x542230ad00000000, 0x17e9962a00000000, - 0x93b20c7900000000, 0xd079aafe00000000, 0x054a283800000000, - 0x46818ebf00000000, 0xc2da14ec00000000, 0x8111b26b00000000, - 0xca6d204b00000000, 0x89a686cc00000000, 0x0dfd1c9f00000000, - 0x4e36ba1800000000}, - {0x0000000000000000, 0xe1b652ef00000000, 0x836bd40500000000, - 0x62dd86ea00000000, 0x06d7a80b00000000, 0xe761fae400000000, - 0x85bc7c0e00000000, 0x640a2ee100000000, 0x0cae511700000000, - 0xed1803f800000000, 0x8fc5851200000000, 0x6e73d7fd00000000, - 0x0a79f91c00000000, 0xebcfabf300000000, 0x89122d1900000000, - 0x68a47ff600000000, 0x185ca32e00000000, 0xf9eaf1c100000000, - 0x9b37772b00000000, 0x7a8125c400000000, 0x1e8b0b2500000000, - 0xff3d59ca00000000, 0x9de0df2000000000, 0x7c568dcf00000000, - 0x14f2f23900000000, 0xf544a0d600000000, 0x9799263c00000000, - 0x762f74d300000000, 0x12255a3200000000, 0xf39308dd00000000, - 0x914e8e3700000000, 0x70f8dcd800000000, 0x30b8465d00000000, - 0xd10e14b200000000, 0xb3d3925800000000, 0x5265c0b700000000, - 0x366fee5600000000, 0xd7d9bcb900000000, 0xb5043a5300000000, - 0x54b268bc00000000, 0x3c16174a00000000, 0xdda045a500000000, - 0xbf7dc34f00000000, 0x5ecb91a000000000, 0x3ac1bf4100000000, - 0xdb77edae00000000, 0xb9aa6b4400000000, 0x581c39ab00000000, - 0x28e4e57300000000, 0xc952b79c00000000, 0xab8f317600000000, - 0x4a39639900000000, 0x2e334d7800000000, 0xcf851f9700000000, - 0xad58997d00000000, 0x4ceecb9200000000, 0x244ab46400000000, - 0xc5fce68b00000000, 0xa721606100000000, 0x4697328e00000000, - 0x229d1c6f00000000, 0xc32b4e8000000000, 0xa1f6c86a00000000, - 0x40409a8500000000, 0x60708dba00000000, 0x81c6df5500000000, - 0xe31b59bf00000000, 0x02ad0b5000000000, 0x66a725b100000000, - 0x8711775e00000000, 0xe5ccf1b400000000, 0x047aa35b00000000, - 0x6cdedcad00000000, 0x8d688e4200000000, 0xefb508a800000000, - 0x0e035a4700000000, 0x6a0974a600000000, 0x8bbf264900000000, - 0xe962a0a300000000, 0x08d4f24c00000000, 0x782c2e9400000000, - 0x999a7c7b00000000, 0xfb47fa9100000000, 0x1af1a87e00000000, - 0x7efb869f00000000, 0x9f4dd47000000000, 0xfd90529a00000000, - 0x1c26007500000000, 0x74827f8300000000, 0x95342d6c00000000, - 0xf7e9ab8600000000, 0x165ff96900000000, 0x7255d78800000000, - 0x93e3856700000000, 0xf13e038d00000000, 0x1088516200000000, - 0x50c8cbe700000000, 0xb17e990800000000, 0xd3a31fe200000000, - 0x32154d0d00000000, 0x561f63ec00000000, 0xb7a9310300000000, - 0xd574b7e900000000, 0x34c2e50600000000, 0x5c669af000000000, - 0xbdd0c81f00000000, 0xdf0d4ef500000000, 0x3ebb1c1a00000000, - 0x5ab132fb00000000, 0xbb07601400000000, 0xd9dae6fe00000000, - 0x386cb41100000000, 0x489468c900000000, 0xa9223a2600000000, - 0xcbffbccc00000000, 0x2a49ee2300000000, 0x4e43c0c200000000, - 0xaff5922d00000000, 0xcd2814c700000000, 0x2c9e462800000000, - 0x443a39de00000000, 0xa58c6b3100000000, 0xc751eddb00000000, - 0x26e7bf3400000000, 0x42ed91d500000000, 0xa35bc33a00000000, - 0xc18645d000000000, 0x2030173f00000000, 0x81e66bae00000000, - 0x6050394100000000, 0x028dbfab00000000, 0xe33bed4400000000, - 0x8731c3a500000000, 0x6687914a00000000, 0x045a17a000000000, - 0xe5ec454f00000000, 0x8d483ab900000000, 0x6cfe685600000000, - 0x0e23eebc00000000, 0xef95bc5300000000, 0x8b9f92b200000000, - 0x6a29c05d00000000, 0x08f446b700000000, 0xe942145800000000, - 0x99bac88000000000, 0x780c9a6f00000000, 0x1ad11c8500000000, - 0xfb674e6a00000000, 0x9f6d608b00000000, 0x7edb326400000000, - 0x1c06b48e00000000, 0xfdb0e66100000000, 0x9514999700000000, - 0x74a2cb7800000000, 0x167f4d9200000000, 0xf7c91f7d00000000, - 0x93c3319c00000000, 0x7275637300000000, 0x10a8e59900000000, - 0xf11eb77600000000, 0xb15e2df300000000, 0x50e87f1c00000000, - 0x3235f9f600000000, 0xd383ab1900000000, 0xb78985f800000000, - 0x563fd71700000000, 0x34e251fd00000000, 0xd554031200000000, - 0xbdf07ce400000000, 0x5c462e0b00000000, 0x3e9ba8e100000000, - 0xdf2dfa0e00000000, 0xbb27d4ef00000000, 0x5a91860000000000, - 0x384c00ea00000000, 0xd9fa520500000000, 0xa9028edd00000000, - 0x48b4dc3200000000, 0x2a695ad800000000, 0xcbdf083700000000, - 0xafd526d600000000, 0x4e63743900000000, 0x2cbef2d300000000, - 0xcd08a03c00000000, 0xa5acdfca00000000, 0x441a8d2500000000, - 0x26c70bcf00000000, 0xc771592000000000, 0xa37b77c100000000, - 0x42cd252e00000000, 0x2010a3c400000000, 0xc1a6f12b00000000, - 0xe196e61400000000, 0x0020b4fb00000000, 0x62fd321100000000, - 0x834b60fe00000000, 0xe7414e1f00000000, 0x06f71cf000000000, - 0x642a9a1a00000000, 0x859cc8f500000000, 0xed38b70300000000, - 0x0c8ee5ec00000000, 0x6e53630600000000, 0x8fe531e900000000, - 0xebef1f0800000000, 0x0a594de700000000, 0x6884cb0d00000000, - 0x893299e200000000, 0xf9ca453a00000000, 0x187c17d500000000, - 0x7aa1913f00000000, 0x9b17c3d000000000, 0xff1ded3100000000, - 0x1eabbfde00000000, 0x7c76393400000000, 0x9dc06bdb00000000, - 0xf564142d00000000, 0x14d246c200000000, 0x760fc02800000000, - 0x97b992c700000000, 0xf3b3bc2600000000, 0x1205eec900000000, - 0x70d8682300000000, 0x916e3acc00000000, 0xd12ea04900000000, - 0x3098f2a600000000, 0x5245744c00000000, 0xb3f326a300000000, - 0xd7f9084200000000, 0x364f5aad00000000, 0x5492dc4700000000, - 0xb5248ea800000000, 0xdd80f15e00000000, 0x3c36a3b100000000, - 0x5eeb255b00000000, 0xbf5d77b400000000, 0xdb57595500000000, - 0x3ae10bba00000000, 0x583c8d5000000000, 0xb98adfbf00000000, - 0xc972036700000000, 0x28c4518800000000, 0x4a19d76200000000, - 0xabaf858d00000000, 0xcfa5ab6c00000000, 0x2e13f98300000000, - 0x4cce7f6900000000, 0xad782d8600000000, 0xc5dc527000000000, - 0x246a009f00000000, 0x46b7867500000000, 0xa701d49a00000000, - 0xc30bfa7b00000000, 0x22bda89400000000, 0x40602e7e00000000, - 0xa1d67c9100000000}, - {0x0000000000000000, 0x5880e2d700000000, 0xf106b47400000000, - 0xa98656a300000000, 0xe20d68e900000000, 0xba8d8a3e00000000, - 0x130bdc9d00000000, 0x4b8b3e4a00000000, 0x851da10900000000, - 0xdd9d43de00000000, 0x741b157d00000000, 0x2c9bf7aa00000000, - 0x6710c9e000000000, 0x3f902b3700000000, 0x96167d9400000000, - 0xce969f4300000000, 0x0a3b421300000000, 0x52bba0c400000000, - 0xfb3df66700000000, 0xa3bd14b000000000, 0xe8362afa00000000, - 0xb0b6c82d00000000, 0x19309e8e00000000, 0x41b07c5900000000, - 0x8f26e31a00000000, 0xd7a601cd00000000, 0x7e20576e00000000, - 0x26a0b5b900000000, 0x6d2b8bf300000000, 0x35ab692400000000, - 0x9c2d3f8700000000, 0xc4addd5000000000, 0x1476842600000000, - 0x4cf666f100000000, 0xe570305200000000, 0xbdf0d28500000000, - 0xf67beccf00000000, 0xaefb0e1800000000, 0x077d58bb00000000, - 0x5ffdba6c00000000, 0x916b252f00000000, 0xc9ebc7f800000000, - 0x606d915b00000000, 0x38ed738c00000000, 0x73664dc600000000, - 0x2be6af1100000000, 0x8260f9b200000000, 0xdae01b6500000000, - 0x1e4dc63500000000, 0x46cd24e200000000, 0xef4b724100000000, - 0xb7cb909600000000, 0xfc40aedc00000000, 0xa4c04c0b00000000, - 0x0d461aa800000000, 0x55c6f87f00000000, 0x9b50673c00000000, - 0xc3d085eb00000000, 0x6a56d34800000000, 0x32d6319f00000000, - 0x795d0fd500000000, 0x21dded0200000000, 0x885bbba100000000, - 0xd0db597600000000, 0x28ec084d00000000, 0x706cea9a00000000, - 0xd9eabc3900000000, 0x816a5eee00000000, 0xcae160a400000000, - 0x9261827300000000, 0x3be7d4d000000000, 0x6367360700000000, - 0xadf1a94400000000, 0xf5714b9300000000, 0x5cf71d3000000000, - 0x0477ffe700000000, 0x4ffcc1ad00000000, 0x177c237a00000000, - 0xbefa75d900000000, 0xe67a970e00000000, 0x22d74a5e00000000, - 0x7a57a88900000000, 0xd3d1fe2a00000000, 0x8b511cfd00000000, - 0xc0da22b700000000, 0x985ac06000000000, 0x31dc96c300000000, - 0x695c741400000000, 0xa7caeb5700000000, 0xff4a098000000000, - 0x56cc5f2300000000, 0x0e4cbdf400000000, 0x45c783be00000000, - 0x1d47616900000000, 0xb4c137ca00000000, 0xec41d51d00000000, - 0x3c9a8c6b00000000, 0x641a6ebc00000000, 0xcd9c381f00000000, - 0x951cdac800000000, 0xde97e48200000000, 0x8617065500000000, - 0x2f9150f600000000, 0x7711b22100000000, 0xb9872d6200000000, - 0xe107cfb500000000, 0x4881991600000000, 0x10017bc100000000, - 0x5b8a458b00000000, 0x030aa75c00000000, 0xaa8cf1ff00000000, - 0xf20c132800000000, 0x36a1ce7800000000, 0x6e212caf00000000, - 0xc7a77a0c00000000, 0x9f2798db00000000, 0xd4aca69100000000, - 0x8c2c444600000000, 0x25aa12e500000000, 0x7d2af03200000000, - 0xb3bc6f7100000000, 0xeb3c8da600000000, 0x42badb0500000000, - 0x1a3a39d200000000, 0x51b1079800000000, 0x0931e54f00000000, - 0xa0b7b3ec00000000, 0xf837513b00000000, 0x50d8119a00000000, - 0x0858f34d00000000, 0xa1dea5ee00000000, 0xf95e473900000000, - 0xb2d5797300000000, 0xea559ba400000000, 0x43d3cd0700000000, - 0x1b532fd000000000, 0xd5c5b09300000000, 0x8d45524400000000, - 0x24c304e700000000, 0x7c43e63000000000, 0x37c8d87a00000000, - 0x6f483aad00000000, 0xc6ce6c0e00000000, 0x9e4e8ed900000000, - 0x5ae3538900000000, 0x0263b15e00000000, 0xabe5e7fd00000000, - 0xf365052a00000000, 0xb8ee3b6000000000, 0xe06ed9b700000000, - 0x49e88f1400000000, 0x11686dc300000000, 0xdffef28000000000, - 0x877e105700000000, 0x2ef846f400000000, 0x7678a42300000000, - 0x3df39a6900000000, 0x657378be00000000, 0xccf52e1d00000000, - 0x9475ccca00000000, 0x44ae95bc00000000, 0x1c2e776b00000000, - 0xb5a821c800000000, 0xed28c31f00000000, 0xa6a3fd5500000000, - 0xfe231f8200000000, 0x57a5492100000000, 0x0f25abf600000000, - 0xc1b334b500000000, 0x9933d66200000000, 0x30b580c100000000, - 0x6835621600000000, 0x23be5c5c00000000, 0x7b3ebe8b00000000, - 0xd2b8e82800000000, 0x8a380aff00000000, 0x4e95d7af00000000, - 0x1615357800000000, 0xbf9363db00000000, 0xe713810c00000000, - 0xac98bf4600000000, 0xf4185d9100000000, 0x5d9e0b3200000000, - 0x051ee9e500000000, 0xcb8876a600000000, 0x9308947100000000, - 0x3a8ec2d200000000, 0x620e200500000000, 0x29851e4f00000000, - 0x7105fc9800000000, 0xd883aa3b00000000, 0x800348ec00000000, - 0x783419d700000000, 0x20b4fb0000000000, 0x8932ada300000000, - 0xd1b24f7400000000, 0x9a39713e00000000, 0xc2b993e900000000, - 0x6b3fc54a00000000, 0x33bf279d00000000, 0xfd29b8de00000000, - 0xa5a95a0900000000, 0x0c2f0caa00000000, 0x54afee7d00000000, - 0x1f24d03700000000, 0x47a432e000000000, 0xee22644300000000, - 0xb6a2869400000000, 0x720f5bc400000000, 0x2a8fb91300000000, - 0x8309efb000000000, 0xdb890d6700000000, 0x9002332d00000000, - 0xc882d1fa00000000, 0x6104875900000000, 0x3984658e00000000, - 0xf712facd00000000, 0xaf92181a00000000, 0x06144eb900000000, - 0x5e94ac6e00000000, 0x151f922400000000, 0x4d9f70f300000000, - 0xe419265000000000, 0xbc99c48700000000, 0x6c429df100000000, - 0x34c27f2600000000, 0x9d44298500000000, 0xc5c4cb5200000000, - 0x8e4ff51800000000, 0xd6cf17cf00000000, 0x7f49416c00000000, - 0x27c9a3bb00000000, 0xe95f3cf800000000, 0xb1dfde2f00000000, - 0x1859888c00000000, 0x40d96a5b00000000, 0x0b52541100000000, - 0x53d2b6c600000000, 0xfa54e06500000000, 0xa2d402b200000000, - 0x6679dfe200000000, 0x3ef93d3500000000, 0x977f6b9600000000, - 0xcfff894100000000, 0x8474b70b00000000, 0xdcf455dc00000000, - 0x7572037f00000000, 0x2df2e1a800000000, 0xe3647eeb00000000, - 0xbbe49c3c00000000, 0x1262ca9f00000000, 0x4ae2284800000000, - 0x0169160200000000, 0x59e9f4d500000000, 0xf06fa27600000000, - 0xa8ef40a100000000}, - {0x0000000000000000, 0x463b676500000000, 0x8c76ceca00000000, - 0xca4da9af00000000, 0x59ebed4e00000000, 0x1fd08a2b00000000, - 0xd59d238400000000, 0x93a644e100000000, 0xb2d6db9d00000000, - 0xf4edbcf800000000, 0x3ea0155700000000, 0x789b723200000000, - 0xeb3d36d300000000, 0xad0651b600000000, 0x674bf81900000000, - 0x21709f7c00000000, 0x25abc6e000000000, 0x6390a18500000000, - 0xa9dd082a00000000, 0xefe66f4f00000000, 0x7c402bae00000000, - 0x3a7b4ccb00000000, 0xf036e56400000000, 0xb60d820100000000, - 0x977d1d7d00000000, 0xd1467a1800000000, 0x1b0bd3b700000000, - 0x5d30b4d200000000, 0xce96f03300000000, 0x88ad975600000000, - 0x42e03ef900000000, 0x04db599c00000000, 0x0b50fc1a00000000, - 0x4d6b9b7f00000000, 0x872632d000000000, 0xc11d55b500000000, - 0x52bb115400000000, 0x1480763100000000, 0xdecddf9e00000000, - 0x98f6b8fb00000000, 0xb986278700000000, 0xffbd40e200000000, - 0x35f0e94d00000000, 0x73cb8e2800000000, 0xe06dcac900000000, - 0xa656adac00000000, 0x6c1b040300000000, 0x2a20636600000000, - 0x2efb3afa00000000, 0x68c05d9f00000000, 0xa28df43000000000, - 0xe4b6935500000000, 0x7710d7b400000000, 0x312bb0d100000000, - 0xfb66197e00000000, 0xbd5d7e1b00000000, 0x9c2de16700000000, - 0xda16860200000000, 0x105b2fad00000000, 0x566048c800000000, - 0xc5c60c2900000000, 0x83fd6b4c00000000, 0x49b0c2e300000000, - 0x0f8ba58600000000, 0x16a0f83500000000, 0x509b9f5000000000, - 0x9ad636ff00000000, 0xdced519a00000000, 0x4f4b157b00000000, - 0x0970721e00000000, 0xc33ddbb100000000, 0x8506bcd400000000, - 0xa47623a800000000, 0xe24d44cd00000000, 0x2800ed6200000000, - 0x6e3b8a0700000000, 0xfd9dcee600000000, 0xbba6a98300000000, - 0x71eb002c00000000, 0x37d0674900000000, 0x330b3ed500000000, - 0x753059b000000000, 0xbf7df01f00000000, 0xf946977a00000000, - 0x6ae0d39b00000000, 0x2cdbb4fe00000000, 0xe6961d5100000000, - 0xa0ad7a3400000000, 0x81dde54800000000, 0xc7e6822d00000000, - 0x0dab2b8200000000, 0x4b904ce700000000, 0xd836080600000000, - 0x9e0d6f6300000000, 0x5440c6cc00000000, 0x127ba1a900000000, - 0x1df0042f00000000, 0x5bcb634a00000000, 0x9186cae500000000, - 0xd7bdad8000000000, 0x441be96100000000, 0x02208e0400000000, - 0xc86d27ab00000000, 0x8e5640ce00000000, 0xaf26dfb200000000, - 0xe91db8d700000000, 0x2350117800000000, 0x656b761d00000000, - 0xf6cd32fc00000000, 0xb0f6559900000000, 0x7abbfc3600000000, - 0x3c809b5300000000, 0x385bc2cf00000000, 0x7e60a5aa00000000, - 0xb42d0c0500000000, 0xf2166b6000000000, 0x61b02f8100000000, - 0x278b48e400000000, 0xedc6e14b00000000, 0xabfd862e00000000, - 0x8a8d195200000000, 0xccb67e3700000000, 0x06fbd79800000000, - 0x40c0b0fd00000000, 0xd366f41c00000000, 0x955d937900000000, - 0x5f103ad600000000, 0x192b5db300000000, 0x2c40f16b00000000, - 0x6a7b960e00000000, 0xa0363fa100000000, 0xe60d58c400000000, - 0x75ab1c2500000000, 0x33907b4000000000, 0xf9ddd2ef00000000, - 0xbfe6b58a00000000, 0x9e962af600000000, 0xd8ad4d9300000000, - 0x12e0e43c00000000, 0x54db835900000000, 0xc77dc7b800000000, - 0x8146a0dd00000000, 0x4b0b097200000000, 0x0d306e1700000000, - 0x09eb378b00000000, 0x4fd050ee00000000, 0x859df94100000000, - 0xc3a69e2400000000, 0x5000dac500000000, 0x163bbda000000000, - 0xdc76140f00000000, 0x9a4d736a00000000, 0xbb3dec1600000000, - 0xfd068b7300000000, 0x374b22dc00000000, 0x717045b900000000, - 0xe2d6015800000000, 0xa4ed663d00000000, 0x6ea0cf9200000000, - 0x289ba8f700000000, 0x27100d7100000000, 0x612b6a1400000000, - 0xab66c3bb00000000, 0xed5da4de00000000, 0x7efbe03f00000000, - 0x38c0875a00000000, 0xf28d2ef500000000, 0xb4b6499000000000, - 0x95c6d6ec00000000, 0xd3fdb18900000000, 0x19b0182600000000, - 0x5f8b7f4300000000, 0xcc2d3ba200000000, 0x8a165cc700000000, - 0x405bf56800000000, 0x0660920d00000000, 0x02bbcb9100000000, - 0x4480acf400000000, 0x8ecd055b00000000, 0xc8f6623e00000000, - 0x5b5026df00000000, 0x1d6b41ba00000000, 0xd726e81500000000, - 0x911d8f7000000000, 0xb06d100c00000000, 0xf656776900000000, - 0x3c1bdec600000000, 0x7a20b9a300000000, 0xe986fd4200000000, - 0xafbd9a2700000000, 0x65f0338800000000, 0x23cb54ed00000000, - 0x3ae0095e00000000, 0x7cdb6e3b00000000, 0xb696c79400000000, - 0xf0ada0f100000000, 0x630be41000000000, 0x2530837500000000, - 0xef7d2ada00000000, 0xa9464dbf00000000, 0x8836d2c300000000, - 0xce0db5a600000000, 0x04401c0900000000, 0x427b7b6c00000000, - 0xd1dd3f8d00000000, 0x97e658e800000000, 0x5dabf14700000000, - 0x1b90962200000000, 0x1f4bcfbe00000000, 0x5970a8db00000000, - 0x933d017400000000, 0xd506661100000000, 0x46a022f000000000, - 0x009b459500000000, 0xcad6ec3a00000000, 0x8ced8b5f00000000, - 0xad9d142300000000, 0xeba6734600000000, 0x21ebdae900000000, - 0x67d0bd8c00000000, 0xf476f96d00000000, 0xb24d9e0800000000, - 0x780037a700000000, 0x3e3b50c200000000, 0x31b0f54400000000, - 0x778b922100000000, 0xbdc63b8e00000000, 0xfbfd5ceb00000000, - 0x685b180a00000000, 0x2e607f6f00000000, 0xe42dd6c000000000, - 0xa216b1a500000000, 0x83662ed900000000, 0xc55d49bc00000000, - 0x0f10e01300000000, 0x492b877600000000, 0xda8dc39700000000, - 0x9cb6a4f200000000, 0x56fb0d5d00000000, 0x10c06a3800000000, - 0x141b33a400000000, 0x522054c100000000, 0x986dfd6e00000000, - 0xde569a0b00000000, 0x4df0deea00000000, 0x0bcbb98f00000000, - 0xc186102000000000, 0x87bd774500000000, 0xa6cde83900000000, - 0xe0f68f5c00000000, 0x2abb26f300000000, 0x6c80419600000000, - 0xff26057700000000, 0xb91d621200000000, 0x7350cbbd00000000, - 0x356bacd800000000}, - {0x0000000000000000, 0x9e83da9f00000000, 0x7d01c4e400000000, - 0xe3821e7b00000000, 0xbb04f91200000000, 0x2587238d00000000, - 0xc6053df600000000, 0x5886e76900000000, 0x7609f22500000000, - 0xe88a28ba00000000, 0x0b0836c100000000, 0x958bec5e00000000, - 0xcd0d0b3700000000, 0x538ed1a800000000, 0xb00ccfd300000000, - 0x2e8f154c00000000, 0xec12e44b00000000, 0x72913ed400000000, - 0x911320af00000000, 0x0f90fa3000000000, 0x57161d5900000000, - 0xc995c7c600000000, 0x2a17d9bd00000000, 0xb494032200000000, - 0x9a1b166e00000000, 0x0498ccf100000000, 0xe71ad28a00000000, - 0x7999081500000000, 0x211fef7c00000000, 0xbf9c35e300000000, - 0x5c1e2b9800000000, 0xc29df10700000000, 0xd825c89700000000, - 0x46a6120800000000, 0xa5240c7300000000, 0x3ba7d6ec00000000, - 0x6321318500000000, 0xfda2eb1a00000000, 0x1e20f56100000000, - 0x80a32ffe00000000, 0xae2c3ab200000000, 0x30afe02d00000000, - 0xd32dfe5600000000, 0x4dae24c900000000, 0x1528c3a000000000, - 0x8bab193f00000000, 0x6829074400000000, 0xf6aadddb00000000, - 0x34372cdc00000000, 0xaab4f64300000000, 0x4936e83800000000, - 0xd7b532a700000000, 0x8f33d5ce00000000, 0x11b00f5100000000, - 0xf232112a00000000, 0x6cb1cbb500000000, 0x423edef900000000, - 0xdcbd046600000000, 0x3f3f1a1d00000000, 0xa1bcc08200000000, - 0xf93a27eb00000000, 0x67b9fd7400000000, 0x843be30f00000000, - 0x1ab8399000000000, 0xf14de1f400000000, 0x6fce3b6b00000000, - 0x8c4c251000000000, 0x12cfff8f00000000, 0x4a4918e600000000, - 0xd4cac27900000000, 0x3748dc0200000000, 0xa9cb069d00000000, - 0x874413d100000000, 0x19c7c94e00000000, 0xfa45d73500000000, - 0x64c60daa00000000, 0x3c40eac300000000, 0xa2c3305c00000000, - 0x41412e2700000000, 0xdfc2f4b800000000, 0x1d5f05bf00000000, - 0x83dcdf2000000000, 0x605ec15b00000000, 0xfedd1bc400000000, - 0xa65bfcad00000000, 0x38d8263200000000, 0xdb5a384900000000, - 0x45d9e2d600000000, 0x6b56f79a00000000, 0xf5d52d0500000000, - 0x1657337e00000000, 0x88d4e9e100000000, 0xd0520e8800000000, - 0x4ed1d41700000000, 0xad53ca6c00000000, 0x33d010f300000000, - 0x2968296300000000, 0xb7ebf3fc00000000, 0x5469ed8700000000, - 0xcaea371800000000, 0x926cd07100000000, 0x0cef0aee00000000, - 0xef6d149500000000, 0x71eece0a00000000, 0x5f61db4600000000, - 0xc1e201d900000000, 0x22601fa200000000, 0xbce3c53d00000000, - 0xe465225400000000, 0x7ae6f8cb00000000, 0x9964e6b000000000, - 0x07e73c2f00000000, 0xc57acd2800000000, 0x5bf917b700000000, - 0xb87b09cc00000000, 0x26f8d35300000000, 0x7e7e343a00000000, - 0xe0fdeea500000000, 0x037ff0de00000000, 0x9dfc2a4100000000, - 0xb3733f0d00000000, 0x2df0e59200000000, 0xce72fbe900000000, - 0x50f1217600000000, 0x0877c61f00000000, 0x96f41c8000000000, - 0x757602fb00000000, 0xebf5d86400000000, 0xa39db33200000000, - 0x3d1e69ad00000000, 0xde9c77d600000000, 0x401fad4900000000, - 0x18994a2000000000, 0x861a90bf00000000, 0x65988ec400000000, - 0xfb1b545b00000000, 0xd594411700000000, 0x4b179b8800000000, - 0xa89585f300000000, 0x36165f6c00000000, 0x6e90b80500000000, - 0xf013629a00000000, 0x13917ce100000000, 0x8d12a67e00000000, - 0x4f8f577900000000, 0xd10c8de600000000, 0x328e939d00000000, - 0xac0d490200000000, 0xf48bae6b00000000, 0x6a0874f400000000, - 0x898a6a8f00000000, 0x1709b01000000000, 0x3986a55c00000000, - 0xa7057fc300000000, 0x448761b800000000, 0xda04bb2700000000, - 0x82825c4e00000000, 0x1c0186d100000000, 0xff8398aa00000000, - 0x6100423500000000, 0x7bb87ba500000000, 0xe53ba13a00000000, - 0x06b9bf4100000000, 0x983a65de00000000, 0xc0bc82b700000000, - 0x5e3f582800000000, 0xbdbd465300000000, 0x233e9ccc00000000, - 0x0db1898000000000, 0x9332531f00000000, 0x70b04d6400000000, - 0xee3397fb00000000, 0xb6b5709200000000, 0x2836aa0d00000000, - 0xcbb4b47600000000, 0x55376ee900000000, 0x97aa9fee00000000, - 0x0929457100000000, 0xeaab5b0a00000000, 0x7428819500000000, - 0x2cae66fc00000000, 0xb22dbc6300000000, 0x51afa21800000000, - 0xcf2c788700000000, 0xe1a36dcb00000000, 0x7f20b75400000000, - 0x9ca2a92f00000000, 0x022173b000000000, 0x5aa794d900000000, - 0xc4244e4600000000, 0x27a6503d00000000, 0xb9258aa200000000, - 0x52d052c600000000, 0xcc53885900000000, 0x2fd1962200000000, - 0xb1524cbd00000000, 0xe9d4abd400000000, 0x7757714b00000000, - 0x94d56f3000000000, 0x0a56b5af00000000, 0x24d9a0e300000000, - 0xba5a7a7c00000000, 0x59d8640700000000, 0xc75bbe9800000000, - 0x9fdd59f100000000, 0x015e836e00000000, 0xe2dc9d1500000000, - 0x7c5f478a00000000, 0xbec2b68d00000000, 0x20416c1200000000, - 0xc3c3726900000000, 0x5d40a8f600000000, 0x05c64f9f00000000, - 0x9b45950000000000, 0x78c78b7b00000000, 0xe64451e400000000, - 0xc8cb44a800000000, 0x56489e3700000000, 0xb5ca804c00000000, - 0x2b495ad300000000, 0x73cfbdba00000000, 0xed4c672500000000, - 0x0ece795e00000000, 0x904da3c100000000, 0x8af59a5100000000, - 0x147640ce00000000, 0xf7f45eb500000000, 0x6977842a00000000, - 0x31f1634300000000, 0xaf72b9dc00000000, 0x4cf0a7a700000000, - 0xd2737d3800000000, 0xfcfc687400000000, 0x627fb2eb00000000, - 0x81fdac9000000000, 0x1f7e760f00000000, 0x47f8916600000000, - 0xd97b4bf900000000, 0x3af9558200000000, 0xa47a8f1d00000000, - 0x66e77e1a00000000, 0xf864a48500000000, 0x1be6bafe00000000, - 0x8565606100000000, 0xdde3870800000000, 0x43605d9700000000, - 0xa0e243ec00000000, 0x3e61997300000000, 0x10ee8c3f00000000, - 0x8e6d56a000000000, 0x6def48db00000000, 0xf36c924400000000, - 0xabea752d00000000, 0x3569afb200000000, 0xd6ebb1c900000000, - 0x48686b5600000000}, - {0x0000000000000000, 0xc064281700000000, 0x80c9502e00000000, - 0x40ad783900000000, 0x0093a15c00000000, 0xc0f7894b00000000, - 0x805af17200000000, 0x403ed96500000000, 0x002643b900000000, - 0xc0426bae00000000, 0x80ef139700000000, 0x408b3b8000000000, - 0x00b5e2e500000000, 0xc0d1caf200000000, 0x807cb2cb00000000, - 0x40189adc00000000, 0x414af7a900000000, 0x812edfbe00000000, - 0xc183a78700000000, 0x01e78f9000000000, 0x41d956f500000000, - 0x81bd7ee200000000, 0xc11006db00000000, 0x01742ecc00000000, - 0x416cb41000000000, 0x81089c0700000000, 0xc1a5e43e00000000, - 0x01c1cc2900000000, 0x41ff154c00000000, 0x819b3d5b00000000, - 0xc136456200000000, 0x01526d7500000000, 0xc3929f8800000000, - 0x03f6b79f00000000, 0x435bcfa600000000, 0x833fe7b100000000, - 0xc3013ed400000000, 0x036516c300000000, 0x43c86efa00000000, - 0x83ac46ed00000000, 0xc3b4dc3100000000, 0x03d0f42600000000, - 0x437d8c1f00000000, 0x8319a40800000000, 0xc3277d6d00000000, - 0x0343557a00000000, 0x43ee2d4300000000, 0x838a055400000000, - 0x82d8682100000000, 0x42bc403600000000, 0x0211380f00000000, - 0xc275101800000000, 0x824bc97d00000000, 0x422fe16a00000000, - 0x0282995300000000, 0xc2e6b14400000000, 0x82fe2b9800000000, - 0x429a038f00000000, 0x02377bb600000000, 0xc25353a100000000, - 0x826d8ac400000000, 0x4209a2d300000000, 0x02a4daea00000000, - 0xc2c0f2fd00000000, 0xc7234eca00000000, 0x074766dd00000000, - 0x47ea1ee400000000, 0x878e36f300000000, 0xc7b0ef9600000000, - 0x07d4c78100000000, 0x4779bfb800000000, 0x871d97af00000000, - 0xc7050d7300000000, 0x0761256400000000, 0x47cc5d5d00000000, - 0x87a8754a00000000, 0xc796ac2f00000000, 0x07f2843800000000, - 0x475ffc0100000000, 0x873bd41600000000, 0x8669b96300000000, - 0x460d917400000000, 0x06a0e94d00000000, 0xc6c4c15a00000000, - 0x86fa183f00000000, 0x469e302800000000, 0x0633481100000000, - 0xc657600600000000, 0x864ffada00000000, 0x462bd2cd00000000, - 0x0686aaf400000000, 0xc6e282e300000000, 0x86dc5b8600000000, - 0x46b8739100000000, 0x06150ba800000000, 0xc67123bf00000000, - 0x04b1d14200000000, 0xc4d5f95500000000, 0x8478816c00000000, - 0x441ca97b00000000, 0x0422701e00000000, 0xc446580900000000, - 0x84eb203000000000, 0x448f082700000000, 0x049792fb00000000, - 0xc4f3baec00000000, 0x845ec2d500000000, 0x443aeac200000000, - 0x040433a700000000, 0xc4601bb000000000, 0x84cd638900000000, - 0x44a94b9e00000000, 0x45fb26eb00000000, 0x859f0efc00000000, - 0xc53276c500000000, 0x05565ed200000000, 0x456887b700000000, - 0x850cafa000000000, 0xc5a1d79900000000, 0x05c5ff8e00000000, - 0x45dd655200000000, 0x85b94d4500000000, 0xc514357c00000000, - 0x05701d6b00000000, 0x454ec40e00000000, 0x852aec1900000000, - 0xc587942000000000, 0x05e3bc3700000000, 0xcf41ed4f00000000, - 0x0f25c55800000000, 0x4f88bd6100000000, 0x8fec957600000000, - 0xcfd24c1300000000, 0x0fb6640400000000, 0x4f1b1c3d00000000, - 0x8f7f342a00000000, 0xcf67aef600000000, 0x0f0386e100000000, - 0x4faefed800000000, 0x8fcad6cf00000000, 0xcff40faa00000000, - 0x0f9027bd00000000, 0x4f3d5f8400000000, 0x8f59779300000000, - 0x8e0b1ae600000000, 0x4e6f32f100000000, 0x0ec24ac800000000, - 0xcea662df00000000, 0x8e98bbba00000000, 0x4efc93ad00000000, - 0x0e51eb9400000000, 0xce35c38300000000, 0x8e2d595f00000000, - 0x4e49714800000000, 0x0ee4097100000000, 0xce80216600000000, - 0x8ebef80300000000, 0x4edad01400000000, 0x0e77a82d00000000, - 0xce13803a00000000, 0x0cd372c700000000, 0xccb75ad000000000, - 0x8c1a22e900000000, 0x4c7e0afe00000000, 0x0c40d39b00000000, - 0xcc24fb8c00000000, 0x8c8983b500000000, 0x4cedaba200000000, - 0x0cf5317e00000000, 0xcc91196900000000, 0x8c3c615000000000, - 0x4c58494700000000, 0x0c66902200000000, 0xcc02b83500000000, - 0x8cafc00c00000000, 0x4ccbe81b00000000, 0x4d99856e00000000, - 0x8dfdad7900000000, 0xcd50d54000000000, 0x0d34fd5700000000, - 0x4d0a243200000000, 0x8d6e0c2500000000, 0xcdc3741c00000000, - 0x0da75c0b00000000, 0x4dbfc6d700000000, 0x8ddbeec000000000, - 0xcd7696f900000000, 0x0d12beee00000000, 0x4d2c678b00000000, - 0x8d484f9c00000000, 0xcde537a500000000, 0x0d811fb200000000, - 0x0862a38500000000, 0xc8068b9200000000, 0x88abf3ab00000000, - 0x48cfdbbc00000000, 0x08f102d900000000, 0xc8952ace00000000, - 0x883852f700000000, 0x485c7ae000000000, 0x0844e03c00000000, - 0xc820c82b00000000, 0x888db01200000000, 0x48e9980500000000, - 0x08d7416000000000, 0xc8b3697700000000, 0x881e114e00000000, - 0x487a395900000000, 0x4928542c00000000, 0x894c7c3b00000000, - 0xc9e1040200000000, 0x09852c1500000000, 0x49bbf57000000000, - 0x89dfdd6700000000, 0xc972a55e00000000, 0x09168d4900000000, - 0x490e179500000000, 0x896a3f8200000000, 0xc9c747bb00000000, - 0x09a36fac00000000, 0x499db6c900000000, 0x89f99ede00000000, - 0xc954e6e700000000, 0x0930cef000000000, 0xcbf03c0d00000000, - 0x0b94141a00000000, 0x4b396c2300000000, 0x8b5d443400000000, - 0xcb639d5100000000, 0x0b07b54600000000, 0x4baacd7f00000000, - 0x8bcee56800000000, 0xcbd67fb400000000, 0x0bb257a300000000, - 0x4b1f2f9a00000000, 0x8b7b078d00000000, 0xcb45dee800000000, - 0x0b21f6ff00000000, 0x4b8c8ec600000000, 0x8be8a6d100000000, - 0x8abacba400000000, 0x4adee3b300000000, 0x0a739b8a00000000, - 0xca17b39d00000000, 0x8a296af800000000, 0x4a4d42ef00000000, - 0x0ae03ad600000000, 0xca8412c100000000, 0x8a9c881d00000000, - 0x4af8a00a00000000, 0x0a55d83300000000, 0xca31f02400000000, - 0x8a0f294100000000, 0x4a6b015600000000, 0x0ac6796f00000000, - 0xcaa2517800000000}, - {0x0000000000000000, 0xd4ea739b00000000, 0xe9d396ed00000000, - 0x3d39e57600000000, 0x93a15c0000000000, 0x474b2f9b00000000, - 0x7a72caed00000000, 0xae98b97600000000, 0x2643b90000000000, - 0xf2a9ca9b00000000, 0xcf902fed00000000, 0x1b7a5c7600000000, - 0xb5e2e50000000000, 0x6108969b00000000, 0x5c3173ed00000000, - 0x88db007600000000, 0x4c86720100000000, 0x986c019a00000000, - 0xa555e4ec00000000, 0x71bf977700000000, 0xdf272e0100000000, - 0x0bcd5d9a00000000, 0x36f4b8ec00000000, 0xe21ecb7700000000, - 0x6ac5cb0100000000, 0xbe2fb89a00000000, 0x83165dec00000000, - 0x57fc2e7700000000, 0xf964970100000000, 0x2d8ee49a00000000, - 0x10b701ec00000000, 0xc45d727700000000, 0x980ce50200000000, - 0x4ce6969900000000, 0x71df73ef00000000, 0xa535007400000000, - 0x0badb90200000000, 0xdf47ca9900000000, 0xe27e2fef00000000, - 0x36945c7400000000, 0xbe4f5c0200000000, 0x6aa52f9900000000, - 0x579ccaef00000000, 0x8376b97400000000, 0x2dee000200000000, - 0xf904739900000000, 0xc43d96ef00000000, 0x10d7e57400000000, - 0xd48a970300000000, 0x0060e49800000000, 0x3d5901ee00000000, - 0xe9b3727500000000, 0x472bcb0300000000, 0x93c1b89800000000, - 0xaef85dee00000000, 0x7a122e7500000000, 0xf2c92e0300000000, - 0x26235d9800000000, 0x1b1ab8ee00000000, 0xcff0cb7500000000, - 0x6168720300000000, 0xb582019800000000, 0x88bbe4ee00000000, - 0x5c51977500000000, 0x3019ca0500000000, 0xe4f3b99e00000000, - 0xd9ca5ce800000000, 0x0d202f7300000000, 0xa3b8960500000000, - 0x7752e59e00000000, 0x4a6b00e800000000, 0x9e81737300000000, - 0x165a730500000000, 0xc2b0009e00000000, 0xff89e5e800000000, - 0x2b63967300000000, 0x85fb2f0500000000, 0x51115c9e00000000, - 0x6c28b9e800000000, 0xb8c2ca7300000000, 0x7c9fb80400000000, - 0xa875cb9f00000000, 0x954c2ee900000000, 0x41a65d7200000000, - 0xef3ee40400000000, 0x3bd4979f00000000, 0x06ed72e900000000, - 0xd207017200000000, 0x5adc010400000000, 0x8e36729f00000000, - 0xb30f97e900000000, 0x67e5e47200000000, 0xc97d5d0400000000, - 0x1d972e9f00000000, 0x20aecbe900000000, 0xf444b87200000000, - 0xa8152f0700000000, 0x7cff5c9c00000000, 0x41c6b9ea00000000, - 0x952cca7100000000, 0x3bb4730700000000, 0xef5e009c00000000, - 0xd267e5ea00000000, 0x068d967100000000, 0x8e56960700000000, - 0x5abce59c00000000, 0x678500ea00000000, 0xb36f737100000000, - 0x1df7ca0700000000, 0xc91db99c00000000, 0xf4245cea00000000, - 0x20ce2f7100000000, 0xe4935d0600000000, 0x30792e9d00000000, - 0x0d40cbeb00000000, 0xd9aab87000000000, 0x7732010600000000, - 0xa3d8729d00000000, 0x9ee197eb00000000, 0x4a0be47000000000, - 0xc2d0e40600000000, 0x163a979d00000000, 0x2b0372eb00000000, - 0xffe9017000000000, 0x5171b80600000000, 0x859bcb9d00000000, - 0xb8a22eeb00000000, 0x6c485d7000000000, 0x6032940b00000000, - 0xb4d8e79000000000, 0x89e102e600000000, 0x5d0b717d00000000, - 0xf393c80b00000000, 0x2779bb9000000000, 0x1a405ee600000000, - 0xceaa2d7d00000000, 0x46712d0b00000000, 0x929b5e9000000000, - 0xafa2bbe600000000, 0x7b48c87d00000000, 0xd5d0710b00000000, - 0x013a029000000000, 0x3c03e7e600000000, 0xe8e9947d00000000, - 0x2cb4e60a00000000, 0xf85e959100000000, 0xc56770e700000000, - 0x118d037c00000000, 0xbf15ba0a00000000, 0x6bffc99100000000, - 0x56c62ce700000000, 0x822c5f7c00000000, 0x0af75f0a00000000, - 0xde1d2c9100000000, 0xe324c9e700000000, 0x37ceba7c00000000, - 0x9956030a00000000, 0x4dbc709100000000, 0x708595e700000000, - 0xa46fe67c00000000, 0xf83e710900000000, 0x2cd4029200000000, - 0x11ede7e400000000, 0xc507947f00000000, 0x6b9f2d0900000000, - 0xbf755e9200000000, 0x824cbbe400000000, 0x56a6c87f00000000, - 0xde7dc80900000000, 0x0a97bb9200000000, 0x37ae5ee400000000, - 0xe3442d7f00000000, 0x4ddc940900000000, 0x9936e79200000000, - 0xa40f02e400000000, 0x70e5717f00000000, 0xb4b8030800000000, - 0x6052709300000000, 0x5d6b95e500000000, 0x8981e67e00000000, - 0x27195f0800000000, 0xf3f32c9300000000, 0xcecac9e500000000, - 0x1a20ba7e00000000, 0x92fbba0800000000, 0x4611c99300000000, - 0x7b282ce500000000, 0xafc25f7e00000000, 0x015ae60800000000, - 0xd5b0959300000000, 0xe88970e500000000, 0x3c63037e00000000, - 0x502b5e0e00000000, 0x84c12d9500000000, 0xb9f8c8e300000000, - 0x6d12bb7800000000, 0xc38a020e00000000, 0x1760719500000000, - 0x2a5994e300000000, 0xfeb3e77800000000, 0x7668e70e00000000, - 0xa282949500000000, 0x9fbb71e300000000, 0x4b51027800000000, - 0xe5c9bb0e00000000, 0x3123c89500000000, 0x0c1a2de300000000, - 0xd8f05e7800000000, 0x1cad2c0f00000000, 0xc8475f9400000000, - 0xf57ebae200000000, 0x2194c97900000000, 0x8f0c700f00000000, - 0x5be6039400000000, 0x66dfe6e200000000, 0xb235957900000000, - 0x3aee950f00000000, 0xee04e69400000000, 0xd33d03e200000000, - 0x07d7707900000000, 0xa94fc90f00000000, 0x7da5ba9400000000, - 0x409c5fe200000000, 0x94762c7900000000, 0xc827bb0c00000000, - 0x1ccdc89700000000, 0x21f42de100000000, 0xf51e5e7a00000000, - 0x5b86e70c00000000, 0x8f6c949700000000, 0xb25571e100000000, - 0x66bf027a00000000, 0xee64020c00000000, 0x3a8e719700000000, - 0x07b794e100000000, 0xd35de77a00000000, 0x7dc55e0c00000000, - 0xa92f2d9700000000, 0x9416c8e100000000, 0x40fcbb7a00000000, - 0x84a1c90d00000000, 0x504bba9600000000, 0x6d725fe000000000, - 0xb9982c7b00000000, 0x1700950d00000000, 0xc3eae69600000000, - 0xfed303e000000000, 0x2a39707b00000000, 0xa2e2700d00000000, - 0x7608039600000000, 0x4b31e6e000000000, 0x9fdb957b00000000, - 0x31432c0d00000000, 0xe5a95f9600000000, 0xd890bae000000000, - 0x0c7ac97b00000000}, - {0x0000000000000000, 0x2765258100000000, 0x0fcc3bd900000000, - 0x28a91e5800000000, 0x5f9e066900000000, 0x78fb23e800000000, - 0x50523db000000000, 0x7737183100000000, 0xbe3c0dd200000000, - 0x9959285300000000, 0xb1f0360b00000000, 0x9695138a00000000, - 0xe1a20bbb00000000, 0xc6c72e3a00000000, 0xee6e306200000000, - 0xc90b15e300000000, 0x3d7f6b7f00000000, 0x1a1a4efe00000000, - 0x32b350a600000000, 0x15d6752700000000, 0x62e16d1600000000, - 0x4584489700000000, 0x6d2d56cf00000000, 0x4a48734e00000000, - 0x834366ad00000000, 0xa426432c00000000, 0x8c8f5d7400000000, - 0xabea78f500000000, 0xdcdd60c400000000, 0xfbb8454500000000, - 0xd3115b1d00000000, 0xf4747e9c00000000, 0x7afed6fe00000000, - 0x5d9bf37f00000000, 0x7532ed2700000000, 0x5257c8a600000000, - 0x2560d09700000000, 0x0205f51600000000, 0x2aaceb4e00000000, - 0x0dc9cecf00000000, 0xc4c2db2c00000000, 0xe3a7fead00000000, - 0xcb0ee0f500000000, 0xec6bc57400000000, 0x9b5cdd4500000000, - 0xbc39f8c400000000, 0x9490e69c00000000, 0xb3f5c31d00000000, - 0x4781bd8100000000, 0x60e4980000000000, 0x484d865800000000, - 0x6f28a3d900000000, 0x181fbbe800000000, 0x3f7a9e6900000000, - 0x17d3803100000000, 0x30b6a5b000000000, 0xf9bdb05300000000, - 0xded895d200000000, 0xf6718b8a00000000, 0xd114ae0b00000000, - 0xa623b63a00000000, 0x814693bb00000000, 0xa9ef8de300000000, - 0x8e8aa86200000000, 0xb5fadc2600000000, 0x929ff9a700000000, - 0xba36e7ff00000000, 0x9d53c27e00000000, 0xea64da4f00000000, - 0xcd01ffce00000000, 0xe5a8e19600000000, 0xc2cdc41700000000, - 0x0bc6d1f400000000, 0x2ca3f47500000000, 0x040aea2d00000000, - 0x236fcfac00000000, 0x5458d79d00000000, 0x733df21c00000000, - 0x5b94ec4400000000, 0x7cf1c9c500000000, 0x8885b75900000000, - 0xafe092d800000000, 0x87498c8000000000, 0xa02ca90100000000, - 0xd71bb13000000000, 0xf07e94b100000000, 0xd8d78ae900000000, - 0xffb2af6800000000, 0x36b9ba8b00000000, 0x11dc9f0a00000000, - 0x3975815200000000, 0x1e10a4d300000000, 0x6927bce200000000, - 0x4e42996300000000, 0x66eb873b00000000, 0x418ea2ba00000000, - 0xcf040ad800000000, 0xe8612f5900000000, 0xc0c8310100000000, - 0xe7ad148000000000, 0x909a0cb100000000, 0xb7ff293000000000, - 0x9f56376800000000, 0xb83312e900000000, 0x7138070a00000000, - 0x565d228b00000000, 0x7ef43cd300000000, 0x5991195200000000, - 0x2ea6016300000000, 0x09c324e200000000, 0x216a3aba00000000, - 0x060f1f3b00000000, 0xf27b61a700000000, 0xd51e442600000000, - 0xfdb75a7e00000000, 0xdad27fff00000000, 0xade567ce00000000, - 0x8a80424f00000000, 0xa2295c1700000000, 0x854c799600000000, - 0x4c476c7500000000, 0x6b2249f400000000, 0x438b57ac00000000, - 0x64ee722d00000000, 0x13d96a1c00000000, 0x34bc4f9d00000000, - 0x1c1551c500000000, 0x3b70744400000000, 0x6af5b94d00000000, - 0x4d909ccc00000000, 0x6539829400000000, 0x425ca71500000000, - 0x356bbf2400000000, 0x120e9aa500000000, 0x3aa784fd00000000, - 0x1dc2a17c00000000, 0xd4c9b49f00000000, 0xf3ac911e00000000, - 0xdb058f4600000000, 0xfc60aac700000000, 0x8b57b2f600000000, - 0xac32977700000000, 0x849b892f00000000, 0xa3feacae00000000, - 0x578ad23200000000, 0x70eff7b300000000, 0x5846e9eb00000000, - 0x7f23cc6a00000000, 0x0814d45b00000000, 0x2f71f1da00000000, - 0x07d8ef8200000000, 0x20bdca0300000000, 0xe9b6dfe000000000, - 0xced3fa6100000000, 0xe67ae43900000000, 0xc11fc1b800000000, - 0xb628d98900000000, 0x914dfc0800000000, 0xb9e4e25000000000, - 0x9e81c7d100000000, 0x100b6fb300000000, 0x376e4a3200000000, - 0x1fc7546a00000000, 0x38a271eb00000000, 0x4f9569da00000000, - 0x68f04c5b00000000, 0x4059520300000000, 0x673c778200000000, - 0xae37626100000000, 0x895247e000000000, 0xa1fb59b800000000, - 0x869e7c3900000000, 0xf1a9640800000000, 0xd6cc418900000000, - 0xfe655fd100000000, 0xd9007a5000000000, 0x2d7404cc00000000, - 0x0a11214d00000000, 0x22b83f1500000000, 0x05dd1a9400000000, - 0x72ea02a500000000, 0x558f272400000000, 0x7d26397c00000000, - 0x5a431cfd00000000, 0x9348091e00000000, 0xb42d2c9f00000000, - 0x9c8432c700000000, 0xbbe1174600000000, 0xccd60f7700000000, - 0xebb32af600000000, 0xc31a34ae00000000, 0xe47f112f00000000, - 0xdf0f656b00000000, 0xf86a40ea00000000, 0xd0c35eb200000000, - 0xf7a67b3300000000, 0x8091630200000000, 0xa7f4468300000000, - 0x8f5d58db00000000, 0xa8387d5a00000000, 0x613368b900000000, - 0x46564d3800000000, 0x6eff536000000000, 0x499a76e100000000, - 0x3ead6ed000000000, 0x19c84b5100000000, 0x3161550900000000, - 0x1604708800000000, 0xe2700e1400000000, 0xc5152b9500000000, - 0xedbc35cd00000000, 0xcad9104c00000000, 0xbdee087d00000000, - 0x9a8b2dfc00000000, 0xb22233a400000000, 0x9547162500000000, - 0x5c4c03c600000000, 0x7b29264700000000, 0x5380381f00000000, - 0x74e51d9e00000000, 0x03d205af00000000, 0x24b7202e00000000, - 0x0c1e3e7600000000, 0x2b7b1bf700000000, 0xa5f1b39500000000, - 0x8294961400000000, 0xaa3d884c00000000, 0x8d58adcd00000000, - 0xfa6fb5fc00000000, 0xdd0a907d00000000, 0xf5a38e2500000000, - 0xd2c6aba400000000, 0x1bcdbe4700000000, 0x3ca89bc600000000, - 0x1401859e00000000, 0x3364a01f00000000, 0x4453b82e00000000, - 0x63369daf00000000, 0x4b9f83f700000000, 0x6cfaa67600000000, - 0x988ed8ea00000000, 0xbfebfd6b00000000, 0x9742e33300000000, - 0xb027c6b200000000, 0xc710de8300000000, 0xe075fb0200000000, - 0xc8dce55a00000000, 0xefb9c0db00000000, 0x26b2d53800000000, - 0x01d7f0b900000000, 0x297eeee100000000, 0x0e1bcb6000000000, - 0x792cd35100000000, 0x5e49f6d000000000, 0x76e0e88800000000, - 0x5185cd0900000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, - 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, - 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, - 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, - 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, - 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, - 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, - 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, - 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, - 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, - 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, - 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, - 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, - 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, - 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, - 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, - 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, - 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, - 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, - 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, - 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, - 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, - 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, - 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, - 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, - 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, - 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, - 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, - 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, - 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, - 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, - 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, - 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, - 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, - 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, - 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, - 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, - 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, - 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, - 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, - 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, - 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, - 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, - 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, - 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, - 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, - 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, - 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, - 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, - 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, - 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, - 0x36197165}, - {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, - 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, - 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, - 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, - 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, - 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, - 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, - 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, - 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, - 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, - 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, - 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, - 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, - 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, - 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, - 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, - 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, - 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, - 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, - 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, - 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, - 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, - 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, - 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, - 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, - 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, - 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, - 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, - 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, - 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, - 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, - 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, - 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, - 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, - 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, - 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, - 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, - 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, - 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, - 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, - 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, - 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, - 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, - 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, - 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, - 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, - 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, - 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, - 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, - 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, - 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, - 0x1a3b93aa}, - {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, - 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, - 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, - 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, - 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, - 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, - 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, - 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, - 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, - 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, - 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, - 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, - 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, - 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, - 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, - 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, - 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, - 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, - 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, - 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, - 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, - 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, - 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, - 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, - 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, - 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, - 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, - 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, - 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, - 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, - 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, - 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, - 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, - 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, - 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, - 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, - 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, - 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, - 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, - 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, - 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, - 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, - 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, - 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, - 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, - 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, - 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, - 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, - 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, - 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, - 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, - 0xe147d714}, - {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, - 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, - 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, - 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, - 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, - 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, - 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, - 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, - 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, - 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, - 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, - 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, - 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, - 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, - 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, - 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, - 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, - 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, - 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, - 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, - 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, - 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, - 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, - 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, - 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, - 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, - 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, - 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, - 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, - 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, - 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, - 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, - 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, - 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, - 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, - 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, - 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, - 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, - 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, - 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, - 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, - 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, - 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, - 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, - 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, - 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, - 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, - 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, - 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, - 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, - 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, - 0x494f0c4b}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x43147b17, 0x8628f62e, 0xc53c8d39, 0x0c51ec5d, - 0x4f45974a, 0x8a791a73, 0xc96d6164, 0x18a2d8bb, 0x5bb6a3ac, - 0x9e8a2e95, 0xdd9e5582, 0x14f334e6, 0x57e74ff1, 0x92dbc2c8, - 0xd1cfb9df, 0x7142c0ac, 0x3256bbbb, 0xf76a3682, 0xb47e4d95, - 0x7d132cf1, 0x3e0757e6, 0xfb3bdadf, 0xb82fa1c8, 0x69e01817, - 0x2af46300, 0xefc8ee39, 0xacdc952e, 0x65b1f44a, 0x26a58f5d, - 0xe3990264, 0xa08d7973, 0xa382f182, 0xe0968a95, 0x25aa07ac, - 0x66be7cbb, 0xafd31ddf, 0xecc766c8, 0x29fbebf1, 0x6aef90e6, - 0xbb202939, 0xf834522e, 0x3d08df17, 0x7e1ca400, 0xb771c564, - 0xf465be73, 0x3159334a, 0x724d485d, 0xd2c0312e, 0x91d44a39, - 0x54e8c700, 0x17fcbc17, 0xde91dd73, 0x9d85a664, 0x58b92b5d, - 0x1bad504a, 0xca62e995, 0x89769282, 0x4c4a1fbb, 0x0f5e64ac, - 0xc63305c8, 0x85277edf, 0x401bf3e6, 0x030f88f1, 0x070392de, - 0x4417e9c9, 0x812b64f0, 0xc23f1fe7, 0x0b527e83, 0x48460594, - 0x8d7a88ad, 0xce6ef3ba, 0x1fa14a65, 0x5cb53172, 0x9989bc4b, - 0xda9dc75c, 0x13f0a638, 0x50e4dd2f, 0x95d85016, 0xd6cc2b01, - 0x76415272, 0x35552965, 0xf069a45c, 0xb37ddf4b, 0x7a10be2f, - 0x3904c538, 0xfc384801, 0xbf2c3316, 0x6ee38ac9, 0x2df7f1de, - 0xe8cb7ce7, 0xabdf07f0, 0x62b26694, 0x21a61d83, 0xe49a90ba, - 0xa78eebad, 0xa481635c, 0xe795184b, 0x22a99572, 0x61bdee65, - 0xa8d08f01, 0xebc4f416, 0x2ef8792f, 0x6dec0238, 0xbc23bbe7, - 0xff37c0f0, 0x3a0b4dc9, 0x791f36de, 0xb07257ba, 0xf3662cad, - 0x365aa194, 0x754eda83, 0xd5c3a3f0, 0x96d7d8e7, 0x53eb55de, - 0x10ff2ec9, 0xd9924fad, 0x9a8634ba, 0x5fbab983, 0x1caec294, - 0xcd617b4b, 0x8e75005c, 0x4b498d65, 0x085df672, 0xc1309716, - 0x8224ec01, 0x47186138, 0x040c1a2f, 0x4f005566, 0x0c142e71, - 0xc928a348, 0x8a3cd85f, 0x4351b93b, 0x0045c22c, 0xc5794f15, - 0x866d3402, 0x57a28ddd, 0x14b6f6ca, 0xd18a7bf3, 0x929e00e4, - 0x5bf36180, 0x18e71a97, 0xdddb97ae, 0x9ecfecb9, 0x3e4295ca, - 0x7d56eedd, 0xb86a63e4, 0xfb7e18f3, 0x32137997, 0x71070280, - 0xb43b8fb9, 0xf72ff4ae, 0x26e04d71, 0x65f43666, 0xa0c8bb5f, - 0xe3dcc048, 0x2ab1a12c, 0x69a5da3b, 0xac995702, 0xef8d2c15, - 0xec82a4e4, 0xaf96dff3, 0x6aaa52ca, 0x29be29dd, 0xe0d348b9, - 0xa3c733ae, 0x66fbbe97, 0x25efc580, 0xf4207c5f, 0xb7340748, - 0x72088a71, 0x311cf166, 0xf8719002, 0xbb65eb15, 0x7e59662c, - 0x3d4d1d3b, 0x9dc06448, 0xded41f5f, 0x1be89266, 0x58fce971, - 0x91918815, 0xd285f302, 0x17b97e3b, 0x54ad052c, 0x8562bcf3, - 0xc676c7e4, 0x034a4add, 0x405e31ca, 0x893350ae, 0xca272bb9, - 0x0f1ba680, 0x4c0fdd97, 0x4803c7b8, 0x0b17bcaf, 0xce2b3196, - 0x8d3f4a81, 0x44522be5, 0x074650f2, 0xc27addcb, 0x816ea6dc, - 0x50a11f03, 0x13b56414, 0xd689e92d, 0x959d923a, 0x5cf0f35e, - 0x1fe48849, 0xdad80570, 0x99cc7e67, 0x39410714, 0x7a557c03, - 0xbf69f13a, 0xfc7d8a2d, 0x3510eb49, 0x7604905e, 0xb3381d67, - 0xf02c6670, 0x21e3dfaf, 0x62f7a4b8, 0xa7cb2981, 0xe4df5296, - 0x2db233f2, 0x6ea648e5, 0xab9ac5dc, 0xe88ebecb, 0xeb81363a, - 0xa8954d2d, 0x6da9c014, 0x2ebdbb03, 0xe7d0da67, 0xa4c4a170, - 0x61f82c49, 0x22ec575e, 0xf323ee81, 0xb0379596, 0x750b18af, - 0x361f63b8, 0xff7202dc, 0xbc6679cb, 0x795af4f2, 0x3a4e8fe5, - 0x9ac3f696, 0xd9d78d81, 0x1ceb00b8, 0x5fff7baf, 0x96921acb, - 0xd58661dc, 0x10baece5, 0x53ae97f2, 0x82612e2d, 0xc175553a, - 0x0449d803, 0x475da314, 0x8e30c270, 0xcd24b967, 0x0818345e, - 0x4b0c4f49}, - {0x00000000, 0x3e6bc2ef, 0x3dd0f504, 0x03bb37eb, 0x7aa0eb09, - 0x44cb29e6, 0x47701e0d, 0x791bdce2, 0xf440d713, 0xca2b15fc, - 0xc9902217, 0xf7fbe0f8, 0x8ee03c1a, 0xb08bfef5, 0xb330c91e, - 0x8d5b0bf1, 0xe881ae27, 0xd6ea6cc8, 0xd5515b23, 0xeb3a99cc, - 0x9221452e, 0xac4a87c1, 0xaff1b02a, 0x919a72c5, 0x1cc17934, - 0x22aabbdb, 0x21118c30, 0x1f7a4edf, 0x6661923d, 0x580a50d2, - 0x5bb16739, 0x65daa5d6, 0xd0035d4f, 0xee689fa0, 0xedd3a84b, - 0xd3b86aa4, 0xaaa3b646, 0x94c874a9, 0x97734342, 0xa91881ad, - 0x24438a5c, 0x1a2848b3, 0x19937f58, 0x27f8bdb7, 0x5ee36155, - 0x6088a3ba, 0x63339451, 0x5d5856be, 0x3882f368, 0x06e93187, - 0x0552066c, 0x3b39c483, 0x42221861, 0x7c49da8e, 0x7ff2ed65, - 0x41992f8a, 0xccc2247b, 0xf2a9e694, 0xf112d17f, 0xcf791390, - 0xb662cf72, 0x88090d9d, 0x8bb23a76, 0xb5d9f899, 0xa007ba9e, - 0x9e6c7871, 0x9dd74f9a, 0xa3bc8d75, 0xdaa75197, 0xe4cc9378, - 0xe777a493, 0xd91c667c, 0x54476d8d, 0x6a2caf62, 0x69979889, - 0x57fc5a66, 0x2ee78684, 0x108c446b, 0x13377380, 0x2d5cb16f, - 0x488614b9, 0x76edd656, 0x7556e1bd, 0x4b3d2352, 0x3226ffb0, - 0x0c4d3d5f, 0x0ff60ab4, 0x319dc85b, 0xbcc6c3aa, 0x82ad0145, - 0x811636ae, 0xbf7df441, 0xc66628a3, 0xf80dea4c, 0xfbb6dda7, - 0xc5dd1f48, 0x7004e7d1, 0x4e6f253e, 0x4dd412d5, 0x73bfd03a, - 0x0aa40cd8, 0x34cfce37, 0x3774f9dc, 0x091f3b33, 0x844430c2, - 0xba2ff22d, 0xb994c5c6, 0x87ff0729, 0xfee4dbcb, 0xc08f1924, - 0xc3342ecf, 0xfd5fec20, 0x988549f6, 0xa6ee8b19, 0xa555bcf2, - 0x9b3e7e1d, 0xe225a2ff, 0xdc4e6010, 0xdff557fb, 0xe19e9514, - 0x6cc59ee5, 0x52ae5c0a, 0x51156be1, 0x6f7ea90e, 0x166575ec, - 0x280eb703, 0x2bb580e8, 0x15de4207, 0x010905e6, 0x3f62c709, - 0x3cd9f0e2, 0x02b2320d, 0x7ba9eeef, 0x45c22c00, 0x46791beb, - 0x7812d904, 0xf549d2f5, 0xcb22101a, 0xc89927f1, 0xf6f2e51e, - 0x8fe939fc, 0xb182fb13, 0xb239ccf8, 0x8c520e17, 0xe988abc1, - 0xd7e3692e, 0xd4585ec5, 0xea339c2a, 0x932840c8, 0xad438227, - 0xaef8b5cc, 0x90937723, 0x1dc87cd2, 0x23a3be3d, 0x201889d6, - 0x1e734b39, 0x676897db, 0x59035534, 0x5ab862df, 0x64d3a030, - 0xd10a58a9, 0xef619a46, 0xecdaadad, 0xd2b16f42, 0xabaab3a0, - 0x95c1714f, 0x967a46a4, 0xa811844b, 0x254a8fba, 0x1b214d55, - 0x189a7abe, 0x26f1b851, 0x5fea64b3, 0x6181a65c, 0x623a91b7, - 0x5c515358, 0x398bf68e, 0x07e03461, 0x045b038a, 0x3a30c165, - 0x432b1d87, 0x7d40df68, 0x7efbe883, 0x40902a6c, 0xcdcb219d, - 0xf3a0e372, 0xf01bd499, 0xce701676, 0xb76bca94, 0x8900087b, - 0x8abb3f90, 0xb4d0fd7f, 0xa10ebf78, 0x9f657d97, 0x9cde4a7c, - 0xa2b58893, 0xdbae5471, 0xe5c5969e, 0xe67ea175, 0xd815639a, - 0x554e686b, 0x6b25aa84, 0x689e9d6f, 0x56f55f80, 0x2fee8362, - 0x1185418d, 0x123e7666, 0x2c55b489, 0x498f115f, 0x77e4d3b0, - 0x745fe45b, 0x4a3426b4, 0x332ffa56, 0x0d4438b9, 0x0eff0f52, - 0x3094cdbd, 0xbdcfc64c, 0x83a404a3, 0x801f3348, 0xbe74f1a7, - 0xc76f2d45, 0xf904efaa, 0xfabfd841, 0xc4d41aae, 0x710de237, - 0x4f6620d8, 0x4cdd1733, 0x72b6d5dc, 0x0bad093e, 0x35c6cbd1, - 0x367dfc3a, 0x08163ed5, 0x854d3524, 0xbb26f7cb, 0xb89dc020, - 0x86f602cf, 0xffedde2d, 0xc1861cc2, 0xc23d2b29, 0xfc56e9c6, - 0x998c4c10, 0xa7e78eff, 0xa45cb914, 0x9a377bfb, 0xe32ca719, - 0xdd4765f6, 0xdefc521d, 0xe09790f2, 0x6dcc9b03, 0x53a759ec, - 0x501c6e07, 0x6e77ace8, 0x176c700a, 0x2907b2e5, 0x2abc850e, - 0x14d747e1}, - {0x00000000, 0xc0df8ec1, 0xc1b96c58, 0x0166e299, 0x8273d9b0, - 0x42ac5771, 0x43cab5e8, 0x83153b29, 0x45e1c3ba, 0x853e4d7b, - 0x8458afe2, 0x44872123, 0xc7921a0a, 0x074d94cb, 0x062b7652, - 0xc6f4f893, 0xcbc4f6ae, 0x0b1b786f, 0x0a7d9af6, 0xcaa21437, - 0x49b72f1e, 0x8968a1df, 0x880e4346, 0x48d1cd87, 0x8e253514, - 0x4efabbd5, 0x4f9c594c, 0x8f43d78d, 0x0c56eca4, 0xcc896265, - 0xcdef80fc, 0x0d300e3d, 0xd78f9c86, 0x17501247, 0x1636f0de, - 0xd6e97e1f, 0x55fc4536, 0x9523cbf7, 0x9445296e, 0x549aa7af, - 0x926e5f3c, 0x52b1d1fd, 0x53d73364, 0x9308bda5, 0x101d868c, - 0xd0c2084d, 0xd1a4ead4, 0x117b6415, 0x1c4b6a28, 0xdc94e4e9, - 0xddf20670, 0x1d2d88b1, 0x9e38b398, 0x5ee73d59, 0x5f81dfc0, - 0x9f5e5101, 0x59aaa992, 0x99752753, 0x9813c5ca, 0x58cc4b0b, - 0xdbd97022, 0x1b06fee3, 0x1a601c7a, 0xdabf92bb, 0xef1948d6, - 0x2fc6c617, 0x2ea0248e, 0xee7faa4f, 0x6d6a9166, 0xadb51fa7, - 0xacd3fd3e, 0x6c0c73ff, 0xaaf88b6c, 0x6a2705ad, 0x6b41e734, - 0xab9e69f5, 0x288b52dc, 0xe854dc1d, 0xe9323e84, 0x29edb045, - 0x24ddbe78, 0xe40230b9, 0xe564d220, 0x25bb5ce1, 0xa6ae67c8, - 0x6671e909, 0x67170b90, 0xa7c88551, 0x613c7dc2, 0xa1e3f303, - 0xa085119a, 0x605a9f5b, 0xe34fa472, 0x23902ab3, 0x22f6c82a, - 0xe22946eb, 0x3896d450, 0xf8495a91, 0xf92fb808, 0x39f036c9, - 0xbae50de0, 0x7a3a8321, 0x7b5c61b8, 0xbb83ef79, 0x7d7717ea, - 0xbda8992b, 0xbcce7bb2, 0x7c11f573, 0xff04ce5a, 0x3fdb409b, - 0x3ebda202, 0xfe622cc3, 0xf35222fe, 0x338dac3f, 0x32eb4ea6, - 0xf234c067, 0x7121fb4e, 0xb1fe758f, 0xb0989716, 0x704719d7, - 0xb6b3e144, 0x766c6f85, 0x770a8d1c, 0xb7d503dd, 0x34c038f4, - 0xf41fb635, 0xf57954ac, 0x35a6da6d, 0x9f35e177, 0x5fea6fb6, - 0x5e8c8d2f, 0x9e5303ee, 0x1d4638c7, 0xdd99b606, 0xdcff549f, - 0x1c20da5e, 0xdad422cd, 0x1a0bac0c, 0x1b6d4e95, 0xdbb2c054, - 0x58a7fb7d, 0x987875bc, 0x991e9725, 0x59c119e4, 0x54f117d9, - 0x942e9918, 0x95487b81, 0x5597f540, 0xd682ce69, 0x165d40a8, - 0x173ba231, 0xd7e42cf0, 0x1110d463, 0xd1cf5aa2, 0xd0a9b83b, - 0x107636fa, 0x93630dd3, 0x53bc8312, 0x52da618b, 0x9205ef4a, - 0x48ba7df1, 0x8865f330, 0x890311a9, 0x49dc9f68, 0xcac9a441, - 0x0a162a80, 0x0b70c819, 0xcbaf46d8, 0x0d5bbe4b, 0xcd84308a, - 0xcce2d213, 0x0c3d5cd2, 0x8f2867fb, 0x4ff7e93a, 0x4e910ba3, - 0x8e4e8562, 0x837e8b5f, 0x43a1059e, 0x42c7e707, 0x821869c6, - 0x010d52ef, 0xc1d2dc2e, 0xc0b43eb7, 0x006bb076, 0xc69f48e5, - 0x0640c624, 0x072624bd, 0xc7f9aa7c, 0x44ec9155, 0x84331f94, - 0x8555fd0d, 0x458a73cc, 0x702ca9a1, 0xb0f32760, 0xb195c5f9, - 0x714a4b38, 0xf25f7011, 0x3280fed0, 0x33e61c49, 0xf3399288, - 0x35cd6a1b, 0xf512e4da, 0xf4740643, 0x34ab8882, 0xb7beb3ab, - 0x77613d6a, 0x7607dff3, 0xb6d85132, 0xbbe85f0f, 0x7b37d1ce, - 0x7a513357, 0xba8ebd96, 0x399b86bf, 0xf944087e, 0xf822eae7, - 0x38fd6426, 0xfe099cb5, 0x3ed61274, 0x3fb0f0ed, 0xff6f7e2c, - 0x7c7a4505, 0xbca5cbc4, 0xbdc3295d, 0x7d1ca79c, 0xa7a33527, - 0x677cbbe6, 0x661a597f, 0xa6c5d7be, 0x25d0ec97, 0xe50f6256, - 0xe46980cf, 0x24b60e0e, 0xe242f69d, 0x229d785c, 0x23fb9ac5, - 0xe3241404, 0x60312f2d, 0xa0eea1ec, 0xa1884375, 0x6157cdb4, - 0x6c67c389, 0xacb84d48, 0xaddeafd1, 0x6d012110, 0xee141a39, - 0x2ecb94f8, 0x2fad7661, 0xef72f8a0, 0x29860033, 0xe9598ef2, - 0xe83f6c6b, 0x28e0e2aa, 0xabf5d983, 0x6b2a5742, 0x6a4cb5db, - 0xaa933b1a}, - {0x00000000, 0x6f4ca59b, 0x9f9e3bec, 0xf0d29e77, 0x7f3b0603, - 0x1077a398, 0xe0a53def, 0x8fe99874, 0xfe760c06, 0x913aa99d, - 0x61e837ea, 0x0ea49271, 0x814d0a05, 0xee01af9e, 0x1ed331e9, - 0x719f9472, 0xfced180c, 0x93a1bd97, 0x637323e0, 0x0c3f867b, - 0x83d61e0f, 0xec9abb94, 0x1c4825e3, 0x73048078, 0x029b140a, - 0x6dd7b191, 0x9d052fe6, 0xf2498a7d, 0x7da01209, 0x12ecb792, - 0xe23e29e5, 0x8d728c7e, 0xf8db3118, 0x97979483, 0x67450af4, - 0x0809af6f, 0x87e0371b, 0xe8ac9280, 0x187e0cf7, 0x7732a96c, - 0x06ad3d1e, 0x69e19885, 0x993306f2, 0xf67fa369, 0x79963b1d, - 0x16da9e86, 0xe60800f1, 0x8944a56a, 0x04362914, 0x6b7a8c8f, - 0x9ba812f8, 0xf4e4b763, 0x7b0d2f17, 0x14418a8c, 0xe49314fb, - 0x8bdfb160, 0xfa402512, 0x950c8089, 0x65de1efe, 0x0a92bb65, - 0x857b2311, 0xea37868a, 0x1ae518fd, 0x75a9bd66, 0xf0b76330, - 0x9ffbc6ab, 0x6f2958dc, 0x0065fd47, 0x8f8c6533, 0xe0c0c0a8, - 0x10125edf, 0x7f5efb44, 0x0ec16f36, 0x618dcaad, 0x915f54da, - 0xfe13f141, 0x71fa6935, 0x1eb6ccae, 0xee6452d9, 0x8128f742, - 0x0c5a7b3c, 0x6316dea7, 0x93c440d0, 0xfc88e54b, 0x73617d3f, - 0x1c2dd8a4, 0xecff46d3, 0x83b3e348, 0xf22c773a, 0x9d60d2a1, - 0x6db24cd6, 0x02fee94d, 0x8d177139, 0xe25bd4a2, 0x12894ad5, - 0x7dc5ef4e, 0x086c5228, 0x6720f7b3, 0x97f269c4, 0xf8becc5f, - 0x7757542b, 0x181bf1b0, 0xe8c96fc7, 0x8785ca5c, 0xf61a5e2e, - 0x9956fbb5, 0x698465c2, 0x06c8c059, 0x8921582d, 0xe66dfdb6, - 0x16bf63c1, 0x79f3c65a, 0xf4814a24, 0x9bcdefbf, 0x6b1f71c8, - 0x0453d453, 0x8bba4c27, 0xe4f6e9bc, 0x142477cb, 0x7b68d250, - 0x0af74622, 0x65bbe3b9, 0x95697dce, 0xfa25d855, 0x75cc4021, - 0x1a80e5ba, 0xea527bcd, 0x851ede56, 0xe06fc760, 0x8f2362fb, - 0x7ff1fc8c, 0x10bd5917, 0x9f54c163, 0xf01864f8, 0x00cafa8f, - 0x6f865f14, 0x1e19cb66, 0x71556efd, 0x8187f08a, 0xeecb5511, - 0x6122cd65, 0x0e6e68fe, 0xfebcf689, 0x91f05312, 0x1c82df6c, - 0x73ce7af7, 0x831ce480, 0xec50411b, 0x63b9d96f, 0x0cf57cf4, - 0xfc27e283, 0x936b4718, 0xe2f4d36a, 0x8db876f1, 0x7d6ae886, - 0x12264d1d, 0x9dcfd569, 0xf28370f2, 0x0251ee85, 0x6d1d4b1e, - 0x18b4f678, 0x77f853e3, 0x872acd94, 0xe866680f, 0x678ff07b, - 0x08c355e0, 0xf811cb97, 0x975d6e0c, 0xe6c2fa7e, 0x898e5fe5, - 0x795cc192, 0x16106409, 0x99f9fc7d, 0xf6b559e6, 0x0667c791, - 0x692b620a, 0xe459ee74, 0x8b154bef, 0x7bc7d598, 0x148b7003, - 0x9b62e877, 0xf42e4dec, 0x04fcd39b, 0x6bb07600, 0x1a2fe272, - 0x756347e9, 0x85b1d99e, 0xeafd7c05, 0x6514e471, 0x0a5841ea, - 0xfa8adf9d, 0x95c67a06, 0x10d8a450, 0x7f9401cb, 0x8f469fbc, - 0xe00a3a27, 0x6fe3a253, 0x00af07c8, 0xf07d99bf, 0x9f313c24, - 0xeeaea856, 0x81e20dcd, 0x713093ba, 0x1e7c3621, 0x9195ae55, - 0xfed90bce, 0x0e0b95b9, 0x61473022, 0xec35bc5c, 0x837919c7, - 0x73ab87b0, 0x1ce7222b, 0x930eba5f, 0xfc421fc4, 0x0c9081b3, - 0x63dc2428, 0x1243b05a, 0x7d0f15c1, 0x8ddd8bb6, 0xe2912e2d, - 0x6d78b659, 0x023413c2, 0xf2e68db5, 0x9daa282e, 0xe8039548, - 0x874f30d3, 0x779daea4, 0x18d10b3f, 0x9738934b, 0xf87436d0, - 0x08a6a8a7, 0x67ea0d3c, 0x1675994e, 0x79393cd5, 0x89eba2a2, - 0xe6a70739, 0x694e9f4d, 0x06023ad6, 0xf6d0a4a1, 0x999c013a, - 0x14ee8d44, 0x7ba228df, 0x8b70b6a8, 0xe43c1333, 0x6bd58b47, - 0x04992edc, 0xf44bb0ab, 0x9b071530, 0xea988142, 0x85d424d9, - 0x7506baae, 0x1a4a1f35, 0x95a38741, 0xfaef22da, 0x0a3dbcad, - 0x65711936}}; - -#endif - -#endif - -#if N == 4 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xf1da05aa, 0x38c50d15, 0xc91f08bf, 0x718a1a2a, - 0x80501f80, 0x494f173f, 0xb8951295, 0xe3143454, 0x12ce31fe, - 0xdbd13941, 0x2a0b3ceb, 0x929e2e7e, 0x63442bd4, 0xaa5b236b, - 0x5b8126c1, 0x1d596ee9, 0xec836b43, 0x259c63fc, 0xd4466656, - 0x6cd374c3, 0x9d097169, 0x541679d6, 0xa5cc7c7c, 0xfe4d5abd, - 0x0f975f17, 0xc68857a8, 0x37525202, 0x8fc74097, 0x7e1d453d, - 0xb7024d82, 0x46d84828, 0x3ab2ddd2, 0xcb68d878, 0x0277d0c7, - 0xf3add56d, 0x4b38c7f8, 0xbae2c252, 0x73fdcaed, 0x8227cf47, - 0xd9a6e986, 0x287cec2c, 0xe163e493, 0x10b9e139, 0xa82cf3ac, - 0x59f6f606, 0x90e9feb9, 0x6133fb13, 0x27ebb33b, 0xd631b691, - 0x1f2ebe2e, 0xeef4bb84, 0x5661a911, 0xa7bbacbb, 0x6ea4a404, - 0x9f7ea1ae, 0xc4ff876f, 0x352582c5, 0xfc3a8a7a, 0x0de08fd0, - 0xb5759d45, 0x44af98ef, 0x8db09050, 0x7c6a95fa, 0x7565bba4, - 0x84bfbe0e, 0x4da0b6b1, 0xbc7ab31b, 0x04efa18e, 0xf535a424, - 0x3c2aac9b, 0xcdf0a931, 0x96718ff0, 0x67ab8a5a, 0xaeb482e5, - 0x5f6e874f, 0xe7fb95da, 0x16219070, 0xdf3e98cf, 0x2ee49d65, - 0x683cd54d, 0x99e6d0e7, 0x50f9d858, 0xa123ddf2, 0x19b6cf67, - 0xe86ccacd, 0x2173c272, 0xd0a9c7d8, 0x8b28e119, 0x7af2e4b3, - 0xb3edec0c, 0x4237e9a6, 0xfaa2fb33, 0x0b78fe99, 0xc267f626, - 0x33bdf38c, 0x4fd76676, 0xbe0d63dc, 0x77126b63, 0x86c86ec9, - 0x3e5d7c5c, 0xcf8779f6, 0x06987149, 0xf74274e3, 0xacc35222, - 0x5d195788, 0x94065f37, 0x65dc5a9d, 0xdd494808, 0x2c934da2, - 0xe58c451d, 0x145640b7, 0x528e089f, 0xa3540d35, 0x6a4b058a, - 0x9b910020, 0x230412b5, 0xd2de171f, 0x1bc11fa0, 0xea1b1a0a, - 0xb19a3ccb, 0x40403961, 0x895f31de, 0x78853474, 0xc01026e1, - 0x31ca234b, 0xf8d52bf4, 0x090f2e5e, 0xeacb7748, 0x1b1172e2, - 0xd20e7a5d, 0x23d47ff7, 0x9b416d62, 0x6a9b68c8, 0xa3846077, - 0x525e65dd, 0x09df431c, 0xf80546b6, 0x311a4e09, 0xc0c04ba3, - 0x78555936, 0x898f5c9c, 0x40905423, 0xb14a5189, 0xf79219a1, - 0x06481c0b, 0xcf5714b4, 0x3e8d111e, 0x8618038b, 0x77c20621, - 0xbedd0e9e, 0x4f070b34, 0x14862df5, 0xe55c285f, 0x2c4320e0, - 0xdd99254a, 0x650c37df, 0x94d63275, 0x5dc93aca, 0xac133f60, - 0xd079aa9a, 0x21a3af30, 0xe8bca78f, 0x1966a225, 0xa1f3b0b0, - 0x5029b51a, 0x9936bda5, 0x68ecb80f, 0x336d9ece, 0xc2b79b64, - 0x0ba893db, 0xfa729671, 0x42e784e4, 0xb33d814e, 0x7a2289f1, - 0x8bf88c5b, 0xcd20c473, 0x3cfac1d9, 0xf5e5c966, 0x043fcccc, - 0xbcaade59, 0x4d70dbf3, 0x846fd34c, 0x75b5d6e6, 0x2e34f027, - 0xdfeef58d, 0x16f1fd32, 0xe72bf898, 0x5fbeea0d, 0xae64efa7, - 0x677be718, 0x96a1e2b2, 0x9faeccec, 0x6e74c946, 0xa76bc1f9, - 0x56b1c453, 0xee24d6c6, 0x1ffed36c, 0xd6e1dbd3, 0x273bde79, - 0x7cbaf8b8, 0x8d60fd12, 0x447ff5ad, 0xb5a5f007, 0x0d30e292, - 0xfceae738, 0x35f5ef87, 0xc42fea2d, 0x82f7a205, 0x732da7af, - 0xba32af10, 0x4be8aaba, 0xf37db82f, 0x02a7bd85, 0xcbb8b53a, - 0x3a62b090, 0x61e39651, 0x903993fb, 0x59269b44, 0xa8fc9eee, - 0x10698c7b, 0xe1b389d1, 0x28ac816e, 0xd97684c4, 0xa51c113e, - 0x54c61494, 0x9dd91c2b, 0x6c031981, 0xd4960b14, 0x254c0ebe, - 0xec530601, 0x1d8903ab, 0x4608256a, 0xb7d220c0, 0x7ecd287f, - 0x8f172dd5, 0x37823f40, 0xc6583aea, 0x0f473255, 0xfe9d37ff, - 0xb8457fd7, 0x499f7a7d, 0x808072c2, 0x715a7768, 0xc9cf65fd, - 0x38156057, 0xf10a68e8, 0x00d06d42, 0x5b514b83, 0xaa8b4e29, - 0x63944696, 0x924e433c, 0x2adb51a9, 0xdb015403, 0x121e5cbc, - 0xe3c45916}, - {0x00000000, 0x0ee7e8d1, 0x1dcfd1a2, 0x13283973, 0x3b9fa344, - 0x35784b95, 0x265072e6, 0x28b79a37, 0x773f4688, 0x79d8ae59, - 0x6af0972a, 0x64177ffb, 0x4ca0e5cc, 0x42470d1d, 0x516f346e, - 0x5f88dcbf, 0xee7e8d10, 0xe09965c1, 0xf3b15cb2, 0xfd56b463, - 0xd5e12e54, 0xdb06c685, 0xc82efff6, 0xc6c91727, 0x9941cb98, - 0x97a62349, 0x848e1a3a, 0x8a69f2eb, 0xa2de68dc, 0xac39800d, - 0xbf11b97e, 0xb1f651af, 0x078c1c61, 0x096bf4b0, 0x1a43cdc3, - 0x14a42512, 0x3c13bf25, 0x32f457f4, 0x21dc6e87, 0x2f3b8656, - 0x70b35ae9, 0x7e54b238, 0x6d7c8b4b, 0x639b639a, 0x4b2cf9ad, - 0x45cb117c, 0x56e3280f, 0x5804c0de, 0xe9f29171, 0xe71579a0, - 0xf43d40d3, 0xfadaa802, 0xd26d3235, 0xdc8adae4, 0xcfa2e397, - 0xc1450b46, 0x9ecdd7f9, 0x902a3f28, 0x8302065b, 0x8de5ee8a, - 0xa55274bd, 0xabb59c6c, 0xb89da51f, 0xb67a4dce, 0x0f1838c2, - 0x01ffd013, 0x12d7e960, 0x1c3001b1, 0x34879b86, 0x3a607357, - 0x29484a24, 0x27afa2f5, 0x78277e4a, 0x76c0969b, 0x65e8afe8, - 0x6b0f4739, 0x43b8dd0e, 0x4d5f35df, 0x5e770cac, 0x5090e47d, - 0xe166b5d2, 0xef815d03, 0xfca96470, 0xf24e8ca1, 0xdaf91696, - 0xd41efe47, 0xc736c734, 0xc9d12fe5, 0x9659f35a, 0x98be1b8b, - 0x8b9622f8, 0x8571ca29, 0xadc6501e, 0xa321b8cf, 0xb00981bc, - 0xbeee696d, 0x089424a3, 0x0673cc72, 0x155bf501, 0x1bbc1dd0, - 0x330b87e7, 0x3dec6f36, 0x2ec45645, 0x2023be94, 0x7fab622b, - 0x714c8afa, 0x6264b389, 0x6c835b58, 0x4434c16f, 0x4ad329be, - 0x59fb10cd, 0x571cf81c, 0xe6eaa9b3, 0xe80d4162, 0xfb257811, - 0xf5c290c0, 0xdd750af7, 0xd392e226, 0xc0badb55, 0xce5d3384, - 0x91d5ef3b, 0x9f3207ea, 0x8c1a3e99, 0x82fdd648, 0xaa4a4c7f, - 0xa4ada4ae, 0xb7859ddd, 0xb962750c, 0x1e307184, 0x10d79955, - 0x03ffa026, 0x0d1848f7, 0x25afd2c0, 0x2b483a11, 0x38600362, - 0x3687ebb3, 0x690f370c, 0x67e8dfdd, 0x74c0e6ae, 0x7a270e7f, - 0x52909448, 0x5c777c99, 0x4f5f45ea, 0x41b8ad3b, 0xf04efc94, - 0xfea91445, 0xed812d36, 0xe366c5e7, 0xcbd15fd0, 0xc536b701, - 0xd61e8e72, 0xd8f966a3, 0x8771ba1c, 0x899652cd, 0x9abe6bbe, - 0x9459836f, 0xbcee1958, 0xb209f189, 0xa121c8fa, 0xafc6202b, - 0x19bc6de5, 0x175b8534, 0x0473bc47, 0x0a945496, 0x2223cea1, - 0x2cc42670, 0x3fec1f03, 0x310bf7d2, 0x6e832b6d, 0x6064c3bc, - 0x734cfacf, 0x7dab121e, 0x551c8829, 0x5bfb60f8, 0x48d3598b, - 0x4634b15a, 0xf7c2e0f5, 0xf9250824, 0xea0d3157, 0xe4ead986, - 0xcc5d43b1, 0xc2baab60, 0xd1929213, 0xdf757ac2, 0x80fda67d, - 0x8e1a4eac, 0x9d3277df, 0x93d59f0e, 0xbb620539, 0xb585ede8, - 0xa6add49b, 0xa84a3c4a, 0x11284946, 0x1fcfa197, 0x0ce798e4, - 0x02007035, 0x2ab7ea02, 0x245002d3, 0x37783ba0, 0x399fd371, - 0x66170fce, 0x68f0e71f, 0x7bd8de6c, 0x753f36bd, 0x5d88ac8a, - 0x536f445b, 0x40477d28, 0x4ea095f9, 0xff56c456, 0xf1b12c87, - 0xe29915f4, 0xec7efd25, 0xc4c96712, 0xca2e8fc3, 0xd906b6b0, - 0xd7e15e61, 0x886982de, 0x868e6a0f, 0x95a6537c, 0x9b41bbad, - 0xb3f6219a, 0xbd11c94b, 0xae39f038, 0xa0de18e9, 0x16a45527, - 0x1843bdf6, 0x0b6b8485, 0x058c6c54, 0x2d3bf663, 0x23dc1eb2, - 0x30f427c1, 0x3e13cf10, 0x619b13af, 0x6f7cfb7e, 0x7c54c20d, - 0x72b32adc, 0x5a04b0eb, 0x54e3583a, 0x47cb6149, 0x492c8998, - 0xf8dad837, 0xf63d30e6, 0xe5150995, 0xebf2e144, 0xc3457b73, - 0xcda293a2, 0xde8aaad1, 0xd06d4200, 0x8fe59ebf, 0x8102766e, - 0x922a4f1d, 0x9ccda7cc, 0xb47a3dfb, 0xba9dd52a, 0xa9b5ec59, - 0xa7520488}, - {0x00000000, 0x3c60e308, 0x78c1c610, 0x44a12518, 0xf1838c20, - 0xcde36f28, 0x89424a30, 0xb522a938, 0x38761e01, 0x0416fd09, - 0x40b7d811, 0x7cd73b19, 0xc9f59221, 0xf5957129, 0xb1345431, - 0x8d54b739, 0x70ec3c02, 0x4c8cdf0a, 0x082dfa12, 0x344d191a, - 0x816fb022, 0xbd0f532a, 0xf9ae7632, 0xc5ce953a, 0x489a2203, - 0x74fac10b, 0x305be413, 0x0c3b071b, 0xb919ae23, 0x85794d2b, - 0xc1d86833, 0xfdb88b3b, 0xe1d87804, 0xddb89b0c, 0x9919be14, - 0xa5795d1c, 0x105bf424, 0x2c3b172c, 0x689a3234, 0x54fad13c, - 0xd9ae6605, 0xe5ce850d, 0xa16fa015, 0x9d0f431d, 0x282dea25, - 0x144d092d, 0x50ec2c35, 0x6c8ccf3d, 0x91344406, 0xad54a70e, - 0xe9f58216, 0xd595611e, 0x60b7c826, 0x5cd72b2e, 0x18760e36, - 0x2416ed3e, 0xa9425a07, 0x9522b90f, 0xd1839c17, 0xede37f1f, - 0x58c1d627, 0x64a1352f, 0x20001037, 0x1c60f33f, 0x18c1f649, - 0x24a11541, 0x60003059, 0x5c60d351, 0xe9427a69, 0xd5229961, - 0x9183bc79, 0xade35f71, 0x20b7e848, 0x1cd70b40, 0x58762e58, - 0x6416cd50, 0xd1346468, 0xed548760, 0xa9f5a278, 0x95954170, - 0x682dca4b, 0x544d2943, 0x10ec0c5b, 0x2c8cef53, 0x99ae466b, - 0xa5cea563, 0xe16f807b, 0xdd0f6373, 0x505bd44a, 0x6c3b3742, - 0x289a125a, 0x14faf152, 0xa1d8586a, 0x9db8bb62, 0xd9199e7a, - 0xe5797d72, 0xf9198e4d, 0xc5796d45, 0x81d8485d, 0xbdb8ab55, - 0x089a026d, 0x34fae165, 0x705bc47d, 0x4c3b2775, 0xc16f904c, - 0xfd0f7344, 0xb9ae565c, 0x85ceb554, 0x30ec1c6c, 0x0c8cff64, - 0x482dda7c, 0x744d3974, 0x89f5b24f, 0xb5955147, 0xf134745f, - 0xcd549757, 0x78763e6f, 0x4416dd67, 0x00b7f87f, 0x3cd71b77, - 0xb183ac4e, 0x8de34f46, 0xc9426a5e, 0xf5228956, 0x4000206e, - 0x7c60c366, 0x38c1e67e, 0x04a10576, 0x3183ec92, 0x0de30f9a, - 0x49422a82, 0x7522c98a, 0xc00060b2, 0xfc6083ba, 0xb8c1a6a2, - 0x84a145aa, 0x09f5f293, 0x3595119b, 0x71343483, 0x4d54d78b, - 0xf8767eb3, 0xc4169dbb, 0x80b7b8a3, 0xbcd75bab, 0x416fd090, - 0x7d0f3398, 0x39ae1680, 0x05cef588, 0xb0ec5cb0, 0x8c8cbfb8, - 0xc82d9aa0, 0xf44d79a8, 0x7919ce91, 0x45792d99, 0x01d80881, - 0x3db8eb89, 0x889a42b1, 0xb4faa1b9, 0xf05b84a1, 0xcc3b67a9, - 0xd05b9496, 0xec3b779e, 0xa89a5286, 0x94fab18e, 0x21d818b6, - 0x1db8fbbe, 0x5919dea6, 0x65793dae, 0xe82d8a97, 0xd44d699f, - 0x90ec4c87, 0xac8caf8f, 0x19ae06b7, 0x25cee5bf, 0x616fc0a7, - 0x5d0f23af, 0xa0b7a894, 0x9cd74b9c, 0xd8766e84, 0xe4168d8c, - 0x513424b4, 0x6d54c7bc, 0x29f5e2a4, 0x159501ac, 0x98c1b695, - 0xa4a1559d, 0xe0007085, 0xdc60938d, 0x69423ab5, 0x5522d9bd, - 0x1183fca5, 0x2de31fad, 0x29421adb, 0x1522f9d3, 0x5183dccb, - 0x6de33fc3, 0xd8c196fb, 0xe4a175f3, 0xa00050eb, 0x9c60b3e3, - 0x113404da, 0x2d54e7d2, 0x69f5c2ca, 0x559521c2, 0xe0b788fa, - 0xdcd76bf2, 0x98764eea, 0xa416ade2, 0x59ae26d9, 0x65cec5d1, - 0x216fe0c9, 0x1d0f03c1, 0xa82daaf9, 0x944d49f1, 0xd0ec6ce9, - 0xec8c8fe1, 0x61d838d8, 0x5db8dbd0, 0x1919fec8, 0x25791dc0, - 0x905bb4f8, 0xac3b57f0, 0xe89a72e8, 0xd4fa91e0, 0xc89a62df, - 0xf4fa81d7, 0xb05ba4cf, 0x8c3b47c7, 0x3919eeff, 0x05790df7, - 0x41d828ef, 0x7db8cbe7, 0xf0ec7cde, 0xcc8c9fd6, 0x882dbace, - 0xb44d59c6, 0x016ff0fe, 0x3d0f13f6, 0x79ae36ee, 0x45ced5e6, - 0xb8765edd, 0x8416bdd5, 0xc0b798cd, 0xfcd77bc5, 0x49f5d2fd, - 0x759531f5, 0x313414ed, 0x0d54f7e5, 0x800040dc, 0xbc60a3d4, - 0xf8c186cc, 0xc4a165c4, 0x7183ccfc, 0x4de32ff4, 0x09420aec, - 0x3522e9e4}, - {0x00000000, 0x6307d924, 0xc60fb248, 0xa5086b6c, 0x576e62d1, - 0x3469bbf5, 0x9161d099, 0xf26609bd, 0xaedcc5a2, 0xcddb1c86, - 0x68d377ea, 0x0bd4aece, 0xf9b2a773, 0x9ab57e57, 0x3fbd153b, - 0x5cbacc1f, 0x86c88d05, 0xe5cf5421, 0x40c73f4d, 0x23c0e669, - 0xd1a6efd4, 0xb2a136f0, 0x17a95d9c, 0x74ae84b8, 0x281448a7, - 0x4b139183, 0xee1bfaef, 0x8d1c23cb, 0x7f7a2a76, 0x1c7df352, - 0xb975983e, 0xda72411a, 0xd6e01c4b, 0xb5e7c56f, 0x10efae03, - 0x73e87727, 0x818e7e9a, 0xe289a7be, 0x4781ccd2, 0x248615f6, - 0x783cd9e9, 0x1b3b00cd, 0xbe336ba1, 0xdd34b285, 0x2f52bb38, - 0x4c55621c, 0xe95d0970, 0x8a5ad054, 0x5028914e, 0x332f486a, - 0x96272306, 0xf520fa22, 0x0746f39f, 0x64412abb, 0xc14941d7, - 0xa24e98f3, 0xfef454ec, 0x9df38dc8, 0x38fbe6a4, 0x5bfc3f80, - 0xa99a363d, 0xca9def19, 0x6f958475, 0x0c925d51, 0x76b13ed7, - 0x15b6e7f3, 0xb0be8c9f, 0xd3b955bb, 0x21df5c06, 0x42d88522, - 0xe7d0ee4e, 0x84d7376a, 0xd86dfb75, 0xbb6a2251, 0x1e62493d, - 0x7d659019, 0x8f0399a4, 0xec044080, 0x490c2bec, 0x2a0bf2c8, - 0xf079b3d2, 0x937e6af6, 0x3676019a, 0x5571d8be, 0xa717d103, - 0xc4100827, 0x6118634b, 0x021fba6f, 0x5ea57670, 0x3da2af54, - 0x98aac438, 0xfbad1d1c, 0x09cb14a1, 0x6acccd85, 0xcfc4a6e9, - 0xacc37fcd, 0xa051229c, 0xc356fbb8, 0x665e90d4, 0x055949f0, - 0xf73f404d, 0x94389969, 0x3130f205, 0x52372b21, 0x0e8de73e, - 0x6d8a3e1a, 0xc8825576, 0xab858c52, 0x59e385ef, 0x3ae45ccb, - 0x9fec37a7, 0xfcebee83, 0x2699af99, 0x459e76bd, 0xe0961dd1, - 0x8391c4f5, 0x71f7cd48, 0x12f0146c, 0xb7f87f00, 0xd4ffa624, - 0x88456a3b, 0xeb42b31f, 0x4e4ad873, 0x2d4d0157, 0xdf2b08ea, - 0xbc2cd1ce, 0x1924baa2, 0x7a236386, 0xed627dae, 0x8e65a48a, - 0x2b6dcfe6, 0x486a16c2, 0xba0c1f7f, 0xd90bc65b, 0x7c03ad37, - 0x1f047413, 0x43beb80c, 0x20b96128, 0x85b10a44, 0xe6b6d360, - 0x14d0dadd, 0x77d703f9, 0xd2df6895, 0xb1d8b1b1, 0x6baaf0ab, - 0x08ad298f, 0xada542e3, 0xcea29bc7, 0x3cc4927a, 0x5fc34b5e, - 0xfacb2032, 0x99ccf916, 0xc5763509, 0xa671ec2d, 0x03798741, - 0x607e5e65, 0x921857d8, 0xf11f8efc, 0x5417e590, 0x37103cb4, - 0x3b8261e5, 0x5885b8c1, 0xfd8dd3ad, 0x9e8a0a89, 0x6cec0334, - 0x0febda10, 0xaae3b17c, 0xc9e46858, 0x955ea447, 0xf6597d63, - 0x5351160f, 0x3056cf2b, 0xc230c696, 0xa1371fb2, 0x043f74de, - 0x6738adfa, 0xbd4aece0, 0xde4d35c4, 0x7b455ea8, 0x1842878c, - 0xea248e31, 0x89235715, 0x2c2b3c79, 0x4f2ce55d, 0x13962942, - 0x7091f066, 0xd5999b0a, 0xb69e422e, 0x44f84b93, 0x27ff92b7, - 0x82f7f9db, 0xe1f020ff, 0x9bd34379, 0xf8d49a5d, 0x5ddcf131, - 0x3edb2815, 0xccbd21a8, 0xafbaf88c, 0x0ab293e0, 0x69b54ac4, - 0x350f86db, 0x56085fff, 0xf3003493, 0x9007edb7, 0x6261e40a, - 0x01663d2e, 0xa46e5642, 0xc7698f66, 0x1d1bce7c, 0x7e1c1758, - 0xdb147c34, 0xb813a510, 0x4a75acad, 0x29727589, 0x8c7a1ee5, - 0xef7dc7c1, 0xb3c70bde, 0xd0c0d2fa, 0x75c8b996, 0x16cf60b2, - 0xe4a9690f, 0x87aeb02b, 0x22a6db47, 0x41a10263, 0x4d335f32, - 0x2e348616, 0x8b3ced7a, 0xe83b345e, 0x1a5d3de3, 0x795ae4c7, - 0xdc528fab, 0xbf55568f, 0xe3ef9a90, 0x80e843b4, 0x25e028d8, - 0x46e7f1fc, 0xb481f841, 0xd7862165, 0x728e4a09, 0x1189932d, - 0xcbfbd237, 0xa8fc0b13, 0x0df4607f, 0x6ef3b95b, 0x9c95b0e6, - 0xff9269c2, 0x5a9a02ae, 0x399ddb8a, 0x65271795, 0x0620ceb1, - 0xa328a5dd, 0xc02f7cf9, 0x32497544, 0x514eac60, 0xf446c70c, - 0x97411e28}, - {0x00000000, 0x01b5fd1d, 0x036bfa3a, 0x02de0727, 0x06d7f474, - 0x07620969, 0x05bc0e4e, 0x0409f353, 0x0dafe8e8, 0x0c1a15f5, - 0x0ec412d2, 0x0f71efcf, 0x0b781c9c, 0x0acde181, 0x0813e6a6, - 0x09a61bbb, 0x1b5fd1d0, 0x1aea2ccd, 0x18342bea, 0x1981d6f7, - 0x1d8825a4, 0x1c3dd8b9, 0x1ee3df9e, 0x1f562283, 0x16f03938, - 0x1745c425, 0x159bc302, 0x142e3e1f, 0x1027cd4c, 0x11923051, - 0x134c3776, 0x12f9ca6b, 0x36bfa3a0, 0x370a5ebd, 0x35d4599a, - 0x3461a487, 0x306857d4, 0x31ddaac9, 0x3303adee, 0x32b650f3, - 0x3b104b48, 0x3aa5b655, 0x387bb172, 0x39ce4c6f, 0x3dc7bf3c, - 0x3c724221, 0x3eac4506, 0x3f19b81b, 0x2de07270, 0x2c558f6d, - 0x2e8b884a, 0x2f3e7557, 0x2b378604, 0x2a827b19, 0x285c7c3e, - 0x29e98123, 0x204f9a98, 0x21fa6785, 0x232460a2, 0x22919dbf, - 0x26986eec, 0x272d93f1, 0x25f394d6, 0x244669cb, 0x6d7f4740, - 0x6ccaba5d, 0x6e14bd7a, 0x6fa14067, 0x6ba8b334, 0x6a1d4e29, - 0x68c3490e, 0x6976b413, 0x60d0afa8, 0x616552b5, 0x63bb5592, - 0x620ea88f, 0x66075bdc, 0x67b2a6c1, 0x656ca1e6, 0x64d95cfb, - 0x76209690, 0x77956b8d, 0x754b6caa, 0x74fe91b7, 0x70f762e4, - 0x71429ff9, 0x739c98de, 0x722965c3, 0x7b8f7e78, 0x7a3a8365, - 0x78e48442, 0x7951795f, 0x7d588a0c, 0x7ced7711, 0x7e337036, - 0x7f868d2b, 0x5bc0e4e0, 0x5a7519fd, 0x58ab1eda, 0x591ee3c7, - 0x5d171094, 0x5ca2ed89, 0x5e7ceaae, 0x5fc917b3, 0x566f0c08, - 0x57daf115, 0x5504f632, 0x54b10b2f, 0x50b8f87c, 0x510d0561, - 0x53d30246, 0x5266ff5b, 0x409f3530, 0x412ac82d, 0x43f4cf0a, - 0x42413217, 0x4648c144, 0x47fd3c59, 0x45233b7e, 0x4496c663, - 0x4d30ddd8, 0x4c8520c5, 0x4e5b27e2, 0x4feedaff, 0x4be729ac, - 0x4a52d4b1, 0x488cd396, 0x49392e8b, 0xdafe8e80, 0xdb4b739d, - 0xd99574ba, 0xd82089a7, 0xdc297af4, 0xdd9c87e9, 0xdf4280ce, - 0xdef77dd3, 0xd7516668, 0xd6e49b75, 0xd43a9c52, 0xd58f614f, - 0xd186921c, 0xd0336f01, 0xd2ed6826, 0xd358953b, 0xc1a15f50, - 0xc014a24d, 0xc2caa56a, 0xc37f5877, 0xc776ab24, 0xc6c35639, - 0xc41d511e, 0xc5a8ac03, 0xcc0eb7b8, 0xcdbb4aa5, 0xcf654d82, - 0xced0b09f, 0xcad943cc, 0xcb6cbed1, 0xc9b2b9f6, 0xc80744eb, - 0xec412d20, 0xedf4d03d, 0xef2ad71a, 0xee9f2a07, 0xea96d954, - 0xeb232449, 0xe9fd236e, 0xe848de73, 0xe1eec5c8, 0xe05b38d5, - 0xe2853ff2, 0xe330c2ef, 0xe73931bc, 0xe68ccca1, 0xe452cb86, - 0xe5e7369b, 0xf71efcf0, 0xf6ab01ed, 0xf47506ca, 0xf5c0fbd7, - 0xf1c90884, 0xf07cf599, 0xf2a2f2be, 0xf3170fa3, 0xfab11418, - 0xfb04e905, 0xf9daee22, 0xf86f133f, 0xfc66e06c, 0xfdd31d71, - 0xff0d1a56, 0xfeb8e74b, 0xb781c9c0, 0xb63434dd, 0xb4ea33fa, - 0xb55fcee7, 0xb1563db4, 0xb0e3c0a9, 0xb23dc78e, 0xb3883a93, - 0xba2e2128, 0xbb9bdc35, 0xb945db12, 0xb8f0260f, 0xbcf9d55c, - 0xbd4c2841, 0xbf922f66, 0xbe27d27b, 0xacde1810, 0xad6be50d, - 0xafb5e22a, 0xae001f37, 0xaa09ec64, 0xabbc1179, 0xa962165e, - 0xa8d7eb43, 0xa171f0f8, 0xa0c40de5, 0xa21a0ac2, 0xa3aff7df, - 0xa7a6048c, 0xa613f991, 0xa4cdfeb6, 0xa57803ab, 0x813e6a60, - 0x808b977d, 0x8255905a, 0x83e06d47, 0x87e99e14, 0x865c6309, - 0x8482642e, 0x85379933, 0x8c918288, 0x8d247f95, 0x8ffa78b2, - 0x8e4f85af, 0x8a4676fc, 0x8bf38be1, 0x892d8cc6, 0x889871db, - 0x9a61bbb0, 0x9bd446ad, 0x990a418a, 0x98bfbc97, 0x9cb64fc4, - 0x9d03b2d9, 0x9fddb5fe, 0x9e6848e3, 0x97ce5358, 0x967bae45, - 0x94a5a962, 0x9510547f, 0x9119a72c, 0x90ac5a31, 0x92725d16, - 0x93c7a00b}, - {0x00000000, 0x6e8c1b41, 0xdd183682, 0xb3942dc3, 0x61416b45, - 0x0fcd7004, 0xbc595dc7, 0xd2d54686, 0xc282d68a, 0xac0ecdcb, - 0x1f9ae008, 0x7116fb49, 0xa3c3bdcf, 0xcd4fa68e, 0x7edb8b4d, - 0x1057900c, 0x5e74ab55, 0x30f8b014, 0x836c9dd7, 0xede08696, - 0x3f35c010, 0x51b9db51, 0xe22df692, 0x8ca1edd3, 0x9cf67ddf, - 0xf27a669e, 0x41ee4b5d, 0x2f62501c, 0xfdb7169a, 0x933b0ddb, - 0x20af2018, 0x4e233b59, 0xbce956aa, 0xd2654deb, 0x61f16028, - 0x0f7d7b69, 0xdda83def, 0xb32426ae, 0x00b00b6d, 0x6e3c102c, - 0x7e6b8020, 0x10e79b61, 0xa373b6a2, 0xcdffade3, 0x1f2aeb65, - 0x71a6f024, 0xc232dde7, 0xacbec6a6, 0xe29dfdff, 0x8c11e6be, - 0x3f85cb7d, 0x5109d03c, 0x83dc96ba, 0xed508dfb, 0x5ec4a038, - 0x3048bb79, 0x201f2b75, 0x4e933034, 0xfd071df7, 0x938b06b6, - 0x415e4030, 0x2fd25b71, 0x9c4676b2, 0xf2ca6df3, 0xa2a3ab15, - 0xcc2fb054, 0x7fbb9d97, 0x113786d6, 0xc3e2c050, 0xad6edb11, - 0x1efaf6d2, 0x7076ed93, 0x60217d9f, 0x0ead66de, 0xbd394b1d, - 0xd3b5505c, 0x016016da, 0x6fec0d9b, 0xdc782058, 0xb2f43b19, - 0xfcd70040, 0x925b1b01, 0x21cf36c2, 0x4f432d83, 0x9d966b05, - 0xf31a7044, 0x408e5d87, 0x2e0246c6, 0x3e55d6ca, 0x50d9cd8b, - 0xe34de048, 0x8dc1fb09, 0x5f14bd8f, 0x3198a6ce, 0x820c8b0d, - 0xec80904c, 0x1e4afdbf, 0x70c6e6fe, 0xc352cb3d, 0xadded07c, - 0x7f0b96fa, 0x11878dbb, 0xa213a078, 0xcc9fbb39, 0xdcc82b35, - 0xb2443074, 0x01d01db7, 0x6f5c06f6, 0xbd894070, 0xd3055b31, - 0x609176f2, 0x0e1d6db3, 0x403e56ea, 0x2eb24dab, 0x9d266068, - 0xf3aa7b29, 0x217f3daf, 0x4ff326ee, 0xfc670b2d, 0x92eb106c, - 0x82bc8060, 0xec309b21, 0x5fa4b6e2, 0x3128ada3, 0xe3fdeb25, - 0x8d71f064, 0x3ee5dda7, 0x5069c6e6, 0x9e36506b, 0xf0ba4b2a, - 0x432e66e9, 0x2da27da8, 0xff773b2e, 0x91fb206f, 0x226f0dac, - 0x4ce316ed, 0x5cb486e1, 0x32389da0, 0x81acb063, 0xef20ab22, - 0x3df5eda4, 0x5379f6e5, 0xe0eddb26, 0x8e61c067, 0xc042fb3e, - 0xaecee07f, 0x1d5acdbc, 0x73d6d6fd, 0xa103907b, 0xcf8f8b3a, - 0x7c1ba6f9, 0x1297bdb8, 0x02c02db4, 0x6c4c36f5, 0xdfd81b36, - 0xb1540077, 0x638146f1, 0x0d0d5db0, 0xbe997073, 0xd0156b32, - 0x22df06c1, 0x4c531d80, 0xffc73043, 0x914b2b02, 0x439e6d84, - 0x2d1276c5, 0x9e865b06, 0xf00a4047, 0xe05dd04b, 0x8ed1cb0a, - 0x3d45e6c9, 0x53c9fd88, 0x811cbb0e, 0xef90a04f, 0x5c048d8c, - 0x328896cd, 0x7cabad94, 0x1227b6d5, 0xa1b39b16, 0xcf3f8057, - 0x1deac6d1, 0x7366dd90, 0xc0f2f053, 0xae7eeb12, 0xbe297b1e, - 0xd0a5605f, 0x63314d9c, 0x0dbd56dd, 0xdf68105b, 0xb1e40b1a, - 0x027026d9, 0x6cfc3d98, 0x3c95fb7e, 0x5219e03f, 0xe18dcdfc, - 0x8f01d6bd, 0x5dd4903b, 0x33588b7a, 0x80cca6b9, 0xee40bdf8, - 0xfe172df4, 0x909b36b5, 0x230f1b76, 0x4d830037, 0x9f5646b1, - 0xf1da5df0, 0x424e7033, 0x2cc26b72, 0x62e1502b, 0x0c6d4b6a, - 0xbff966a9, 0xd1757de8, 0x03a03b6e, 0x6d2c202f, 0xdeb80dec, - 0xb03416ad, 0xa06386a1, 0xceef9de0, 0x7d7bb023, 0x13f7ab62, - 0xc122ede4, 0xafaef6a5, 0x1c3adb66, 0x72b6c027, 0x807cadd4, - 0xeef0b695, 0x5d649b56, 0x33e88017, 0xe13dc691, 0x8fb1ddd0, - 0x3c25f013, 0x52a9eb52, 0x42fe7b5e, 0x2c72601f, 0x9fe64ddc, - 0xf16a569d, 0x23bf101b, 0x4d330b5a, 0xfea72699, 0x902b3dd8, - 0xde080681, 0xb0841dc0, 0x03103003, 0x6d9c2b42, 0xbf496dc4, - 0xd1c57685, 0x62515b46, 0x0cdd4007, 0x1c8ad00b, 0x7206cb4a, - 0xc192e689, 0xaf1efdc8, 0x7dcbbb4e, 0x1347a00f, 0xa0d38dcc, - 0xce5f968d}, - {0x00000000, 0xe71da697, 0x154a4b6f, 0xf257edf8, 0x2a9496de, - 0xcd893049, 0x3fdeddb1, 0xd8c37b26, 0x55292dbc, 0xb2348b2b, - 0x406366d3, 0xa77ec044, 0x7fbdbb62, 0x98a01df5, 0x6af7f00d, - 0x8dea569a, 0xaa525b78, 0x4d4ffdef, 0xbf181017, 0x5805b680, - 0x80c6cda6, 0x67db6b31, 0x958c86c9, 0x7291205e, 0xff7b76c4, - 0x1866d053, 0xea313dab, 0x0d2c9b3c, 0xd5efe01a, 0x32f2468d, - 0xc0a5ab75, 0x27b80de2, 0x8fd5b0b1, 0x68c81626, 0x9a9ffbde, - 0x7d825d49, 0xa541266f, 0x425c80f8, 0xb00b6d00, 0x5716cb97, - 0xdafc9d0d, 0x3de13b9a, 0xcfb6d662, 0x28ab70f5, 0xf0680bd3, - 0x1775ad44, 0xe52240bc, 0x023fe62b, 0x2587ebc9, 0xc29a4d5e, - 0x30cda0a6, 0xd7d00631, 0x0f137d17, 0xe80edb80, 0x1a593678, - 0xfd4490ef, 0x70aec675, 0x97b360e2, 0x65e48d1a, 0x82f92b8d, - 0x5a3a50ab, 0xbd27f63c, 0x4f701bc4, 0xa86dbd53, 0xc4da6723, - 0x23c7c1b4, 0xd1902c4c, 0x368d8adb, 0xee4ef1fd, 0x0953576a, - 0xfb04ba92, 0x1c191c05, 0x91f34a9f, 0x76eeec08, 0x84b901f0, - 0x63a4a767, 0xbb67dc41, 0x5c7a7ad6, 0xae2d972e, 0x493031b9, - 0x6e883c5b, 0x89959acc, 0x7bc27734, 0x9cdfd1a3, 0x441caa85, - 0xa3010c12, 0x5156e1ea, 0xb64b477d, 0x3ba111e7, 0xdcbcb770, - 0x2eeb5a88, 0xc9f6fc1f, 0x11358739, 0xf62821ae, 0x047fcc56, - 0xe3626ac1, 0x4b0fd792, 0xac127105, 0x5e459cfd, 0xb9583a6a, - 0x619b414c, 0x8686e7db, 0x74d10a23, 0x93ccacb4, 0x1e26fa2e, - 0xf93b5cb9, 0x0b6cb141, 0xec7117d6, 0x34b26cf0, 0xd3afca67, - 0x21f8279f, 0xc6e58108, 0xe15d8cea, 0x06402a7d, 0xf417c785, - 0x130a6112, 0xcbc91a34, 0x2cd4bca3, 0xde83515b, 0x399ef7cc, - 0xb474a156, 0x536907c1, 0xa13eea39, 0x46234cae, 0x9ee03788, - 0x79fd911f, 0x8baa7ce7, 0x6cb7da70, 0x52c5c807, 0xb5d86e90, - 0x478f8368, 0xa09225ff, 0x78515ed9, 0x9f4cf84e, 0x6d1b15b6, - 0x8a06b321, 0x07ece5bb, 0xe0f1432c, 0x12a6aed4, 0xf5bb0843, - 0x2d787365, 0xca65d5f2, 0x3832380a, 0xdf2f9e9d, 0xf897937f, - 0x1f8a35e8, 0xedddd810, 0x0ac07e87, 0xd20305a1, 0x351ea336, - 0xc7494ece, 0x2054e859, 0xadbebec3, 0x4aa31854, 0xb8f4f5ac, - 0x5fe9533b, 0x872a281d, 0x60378e8a, 0x92606372, 0x757dc5e5, - 0xdd1078b6, 0x3a0dde21, 0xc85a33d9, 0x2f47954e, 0xf784ee68, - 0x109948ff, 0xe2cea507, 0x05d30390, 0x8839550a, 0x6f24f39d, - 0x9d731e65, 0x7a6eb8f2, 0xa2adc3d4, 0x45b06543, 0xb7e788bb, - 0x50fa2e2c, 0x774223ce, 0x905f8559, 0x620868a1, 0x8515ce36, - 0x5dd6b510, 0xbacb1387, 0x489cfe7f, 0xaf8158e8, 0x226b0e72, - 0xc576a8e5, 0x3721451d, 0xd03ce38a, 0x08ff98ac, 0xefe23e3b, - 0x1db5d3c3, 0xfaa87554, 0x961faf24, 0x710209b3, 0x8355e44b, - 0x644842dc, 0xbc8b39fa, 0x5b969f6d, 0xa9c17295, 0x4edcd402, - 0xc3368298, 0x242b240f, 0xd67cc9f7, 0x31616f60, 0xe9a21446, - 0x0ebfb2d1, 0xfce85f29, 0x1bf5f9be, 0x3c4df45c, 0xdb5052cb, - 0x2907bf33, 0xce1a19a4, 0x16d96282, 0xf1c4c415, 0x039329ed, - 0xe48e8f7a, 0x6964d9e0, 0x8e797f77, 0x7c2e928f, 0x9b333418, - 0x43f04f3e, 0xa4ede9a9, 0x56ba0451, 0xb1a7a2c6, 0x19ca1f95, - 0xfed7b902, 0x0c8054fa, 0xeb9df26d, 0x335e894b, 0xd4432fdc, - 0x2614c224, 0xc10964b3, 0x4ce33229, 0xabfe94be, 0x59a97946, - 0xbeb4dfd1, 0x6677a4f7, 0x816a0260, 0x733def98, 0x9420490f, - 0xb39844ed, 0x5485e27a, 0xa6d20f82, 0x41cfa915, 0x990cd233, - 0x7e1174a4, 0x8c46995c, 0x6b5b3fcb, 0xe6b16951, 0x01accfc6, - 0xf3fb223e, 0x14e684a9, 0xcc25ff8f, 0x2b385918, 0xd96fb4e0, - 0x3e721277}, - {0x00000000, 0xa58b900e, 0x9066265d, 0x35edb653, 0xfbbd4afb, - 0x5e36daf5, 0x6bdb6ca6, 0xce50fca8, 0x2c0b93b7, 0x898003b9, - 0xbc6db5ea, 0x19e625e4, 0xd7b6d94c, 0x723d4942, 0x47d0ff11, - 0xe25b6f1f, 0x5817276e, 0xfd9cb760, 0xc8710133, 0x6dfa913d, - 0xa3aa6d95, 0x0621fd9b, 0x33cc4bc8, 0x9647dbc6, 0x741cb4d9, - 0xd19724d7, 0xe47a9284, 0x41f1028a, 0x8fa1fe22, 0x2a2a6e2c, - 0x1fc7d87f, 0xba4c4871, 0xb02e4edc, 0x15a5ded2, 0x20486881, - 0x85c3f88f, 0x4b930427, 0xee189429, 0xdbf5227a, 0x7e7eb274, - 0x9c25dd6b, 0x39ae4d65, 0x0c43fb36, 0xa9c86b38, 0x67989790, - 0xc213079e, 0xf7feb1cd, 0x527521c3, 0xe83969b2, 0x4db2f9bc, - 0x785f4fef, 0xddd4dfe1, 0x13842349, 0xb60fb347, 0x83e20514, - 0x2669951a, 0xc432fa05, 0x61b96a0b, 0x5454dc58, 0xf1df4c56, - 0x3f8fb0fe, 0x9a0420f0, 0xafe996a3, 0x0a6206ad, 0xbb2d9bf9, - 0x1ea60bf7, 0x2b4bbda4, 0x8ec02daa, 0x4090d102, 0xe51b410c, - 0xd0f6f75f, 0x757d6751, 0x9726084e, 0x32ad9840, 0x07402e13, - 0xa2cbbe1d, 0x6c9b42b5, 0xc910d2bb, 0xfcfd64e8, 0x5976f4e6, - 0xe33abc97, 0x46b12c99, 0x735c9aca, 0xd6d70ac4, 0x1887f66c, - 0xbd0c6662, 0x88e1d031, 0x2d6a403f, 0xcf312f20, 0x6ababf2e, - 0x5f57097d, 0xfadc9973, 0x348c65db, 0x9107f5d5, 0xa4ea4386, - 0x0161d388, 0x0b03d525, 0xae88452b, 0x9b65f378, 0x3eee6376, - 0xf0be9fde, 0x55350fd0, 0x60d8b983, 0xc553298d, 0x27084692, - 0x8283d69c, 0xb76e60cf, 0x12e5f0c1, 0xdcb50c69, 0x793e9c67, - 0x4cd32a34, 0xe958ba3a, 0x5314f24b, 0xf69f6245, 0xc372d416, - 0x66f94418, 0xa8a9b8b0, 0x0d2228be, 0x38cf9eed, 0x9d440ee3, - 0x7f1f61fc, 0xda94f1f2, 0xef7947a1, 0x4af2d7af, 0x84a22b07, - 0x2129bb09, 0x14c40d5a, 0xb14f9d54, 0xad2a31b3, 0x08a1a1bd, - 0x3d4c17ee, 0x98c787e0, 0x56977b48, 0xf31ceb46, 0xc6f15d15, - 0x637acd1b, 0x8121a204, 0x24aa320a, 0x11478459, 0xb4cc1457, - 0x7a9ce8ff, 0xdf1778f1, 0xeafacea2, 0x4f715eac, 0xf53d16dd, - 0x50b686d3, 0x655b3080, 0xc0d0a08e, 0x0e805c26, 0xab0bcc28, - 0x9ee67a7b, 0x3b6dea75, 0xd936856a, 0x7cbd1564, 0x4950a337, - 0xecdb3339, 0x228bcf91, 0x87005f9f, 0xb2ede9cc, 0x176679c2, - 0x1d047f6f, 0xb88fef61, 0x8d625932, 0x28e9c93c, 0xe6b93594, - 0x4332a59a, 0x76df13c9, 0xd35483c7, 0x310fecd8, 0x94847cd6, - 0xa169ca85, 0x04e25a8b, 0xcab2a623, 0x6f39362d, 0x5ad4807e, - 0xff5f1070, 0x45135801, 0xe098c80f, 0xd5757e5c, 0x70feee52, - 0xbeae12fa, 0x1b2582f4, 0x2ec834a7, 0x8b43a4a9, 0x6918cbb6, - 0xcc935bb8, 0xf97eedeb, 0x5cf57de5, 0x92a5814d, 0x372e1143, - 0x02c3a710, 0xa748371e, 0x1607aa4a, 0xb38c3a44, 0x86618c17, - 0x23ea1c19, 0xedbae0b1, 0x483170bf, 0x7ddcc6ec, 0xd85756e2, - 0x3a0c39fd, 0x9f87a9f3, 0xaa6a1fa0, 0x0fe18fae, 0xc1b17306, - 0x643ae308, 0x51d7555b, 0xf45cc555, 0x4e108d24, 0xeb9b1d2a, - 0xde76ab79, 0x7bfd3b77, 0xb5adc7df, 0x102657d1, 0x25cbe182, - 0x8040718c, 0x621b1e93, 0xc7908e9d, 0xf27d38ce, 0x57f6a8c0, - 0x99a65468, 0x3c2dc466, 0x09c07235, 0xac4be23b, 0xa629e496, - 0x03a27498, 0x364fc2cb, 0x93c452c5, 0x5d94ae6d, 0xf81f3e63, - 0xcdf28830, 0x6879183e, 0x8a227721, 0x2fa9e72f, 0x1a44517c, - 0xbfcfc172, 0x719f3dda, 0xd414add4, 0xe1f91b87, 0x44728b89, - 0xfe3ec3f8, 0x5bb553f6, 0x6e58e5a5, 0xcbd375ab, 0x05838903, - 0xa008190d, 0x95e5af5e, 0x306e3f50, 0xd235504f, 0x77bec041, - 0x42537612, 0xe7d8e61c, 0x29881ab4, 0x8c038aba, 0xb9ee3ce9, - 0x1c65ace7}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x0e908ba500000000, 0x5d26669000000000, - 0x53b6ed3500000000, 0xfb4abdfb00000000, 0xf5da365e00000000, - 0xa66cdb6b00000000, 0xa8fc50ce00000000, 0xb7930b2c00000000, - 0xb903808900000000, 0xeab56dbc00000000, 0xe425e61900000000, - 0x4cd9b6d700000000, 0x42493d7200000000, 0x11ffd04700000000, - 0x1f6f5be200000000, 0x6e27175800000000, 0x60b79cfd00000000, - 0x330171c800000000, 0x3d91fa6d00000000, 0x956daaa300000000, - 0x9bfd210600000000, 0xc84bcc3300000000, 0xc6db479600000000, - 0xd9b41c7400000000, 0xd72497d100000000, 0x84927ae400000000, - 0x8a02f14100000000, 0x22fea18f00000000, 0x2c6e2a2a00000000, - 0x7fd8c71f00000000, 0x71484cba00000000, 0xdc4e2eb000000000, - 0xd2dea51500000000, 0x8168482000000000, 0x8ff8c38500000000, - 0x2704934b00000000, 0x299418ee00000000, 0x7a22f5db00000000, - 0x74b27e7e00000000, 0x6bdd259c00000000, 0x654dae3900000000, - 0x36fb430c00000000, 0x386bc8a900000000, 0x9097986700000000, - 0x9e0713c200000000, 0xcdb1fef700000000, 0xc321755200000000, - 0xb26939e800000000, 0xbcf9b24d00000000, 0xef4f5f7800000000, - 0xe1dfd4dd00000000, 0x4923841300000000, 0x47b30fb600000000, - 0x1405e28300000000, 0x1a95692600000000, 0x05fa32c400000000, - 0x0b6ab96100000000, 0x58dc545400000000, 0x564cdff100000000, - 0xfeb08f3f00000000, 0xf020049a00000000, 0xa396e9af00000000, - 0xad06620a00000000, 0xf99b2dbb00000000, 0xf70ba61e00000000, - 0xa4bd4b2b00000000, 0xaa2dc08e00000000, 0x02d1904000000000, - 0x0c411be500000000, 0x5ff7f6d000000000, 0x51677d7500000000, - 0x4e08269700000000, 0x4098ad3200000000, 0x132e400700000000, - 0x1dbecba200000000, 0xb5429b6c00000000, 0xbbd210c900000000, - 0xe864fdfc00000000, 0xe6f4765900000000, 0x97bc3ae300000000, - 0x992cb14600000000, 0xca9a5c7300000000, 0xc40ad7d600000000, - 0x6cf6871800000000, 0x62660cbd00000000, 0x31d0e18800000000, - 0x3f406a2d00000000, 0x202f31cf00000000, 0x2ebfba6a00000000, - 0x7d09575f00000000, 0x7399dcfa00000000, 0xdb658c3400000000, - 0xd5f5079100000000, 0x8643eaa400000000, 0x88d3610100000000, - 0x25d5030b00000000, 0x2b4588ae00000000, 0x78f3659b00000000, - 0x7663ee3e00000000, 0xde9fbef000000000, 0xd00f355500000000, - 0x83b9d86000000000, 0x8d2953c500000000, 0x9246082700000000, - 0x9cd6838200000000, 0xcf606eb700000000, 0xc1f0e51200000000, - 0x690cb5dc00000000, 0x679c3e7900000000, 0x342ad34c00000000, - 0x3aba58e900000000, 0x4bf2145300000000, 0x45629ff600000000, - 0x16d472c300000000, 0x1844f96600000000, 0xb0b8a9a800000000, - 0xbe28220d00000000, 0xed9ecf3800000000, 0xe30e449d00000000, - 0xfc611f7f00000000, 0xf2f194da00000000, 0xa14779ef00000000, - 0xafd7f24a00000000, 0x072ba28400000000, 0x09bb292100000000, - 0x5a0dc41400000000, 0x549d4fb100000000, 0xb3312aad00000000, - 0xbda1a10800000000, 0xee174c3d00000000, 0xe087c79800000000, - 0x487b975600000000, 0x46eb1cf300000000, 0x155df1c600000000, - 0x1bcd7a6300000000, 0x04a2218100000000, 0x0a32aa2400000000, - 0x5984471100000000, 0x5714ccb400000000, 0xffe89c7a00000000, - 0xf17817df00000000, 0xa2cefaea00000000, 0xac5e714f00000000, - 0xdd163df500000000, 0xd386b65000000000, 0x80305b6500000000, - 0x8ea0d0c000000000, 0x265c800e00000000, 0x28cc0bab00000000, - 0x7b7ae69e00000000, 0x75ea6d3b00000000, 0x6a8536d900000000, - 0x6415bd7c00000000, 0x37a3504900000000, 0x3933dbec00000000, - 0x91cf8b2200000000, 0x9f5f008700000000, 0xcce9edb200000000, - 0xc279661700000000, 0x6f7f041d00000000, 0x61ef8fb800000000, - 0x3259628d00000000, 0x3cc9e92800000000, 0x9435b9e600000000, - 0x9aa5324300000000, 0xc913df7600000000, 0xc78354d300000000, - 0xd8ec0f3100000000, 0xd67c849400000000, 0x85ca69a100000000, - 0x8b5ae20400000000, 0x23a6b2ca00000000, 0x2d36396f00000000, - 0x7e80d45a00000000, 0x70105fff00000000, 0x0158134500000000, - 0x0fc898e000000000, 0x5c7e75d500000000, 0x52eefe7000000000, - 0xfa12aebe00000000, 0xf482251b00000000, 0xa734c82e00000000, - 0xa9a4438b00000000, 0xb6cb186900000000, 0xb85b93cc00000000, - 0xebed7ef900000000, 0xe57df55c00000000, 0x4d81a59200000000, - 0x43112e3700000000, 0x10a7c30200000000, 0x1e3748a700000000, - 0x4aaa071600000000, 0x443a8cb300000000, 0x178c618600000000, - 0x191cea2300000000, 0xb1e0baed00000000, 0xbf70314800000000, - 0xecc6dc7d00000000, 0xe25657d800000000, 0xfd390c3a00000000, - 0xf3a9879f00000000, 0xa01f6aaa00000000, 0xae8fe10f00000000, - 0x0673b1c100000000, 0x08e33a6400000000, 0x5b55d75100000000, - 0x55c55cf400000000, 0x248d104e00000000, 0x2a1d9beb00000000, - 0x79ab76de00000000, 0x773bfd7b00000000, 0xdfc7adb500000000, - 0xd157261000000000, 0x82e1cb2500000000, 0x8c71408000000000, - 0x931e1b6200000000, 0x9d8e90c700000000, 0xce387df200000000, - 0xc0a8f65700000000, 0x6854a69900000000, 0x66c42d3c00000000, - 0x3572c00900000000, 0x3be24bac00000000, 0x96e429a600000000, - 0x9874a20300000000, 0xcbc24f3600000000, 0xc552c49300000000, - 0x6dae945d00000000, 0x633e1ff800000000, 0x3088f2cd00000000, - 0x3e18796800000000, 0x2177228a00000000, 0x2fe7a92f00000000, - 0x7c51441a00000000, 0x72c1cfbf00000000, 0xda3d9f7100000000, - 0xd4ad14d400000000, 0x871bf9e100000000, 0x898b724400000000, - 0xf8c33efe00000000, 0xf653b55b00000000, 0xa5e5586e00000000, - 0xab75d3cb00000000, 0x0389830500000000, 0x0d1908a000000000, - 0x5eafe59500000000, 0x503f6e3000000000, 0x4f5035d200000000, - 0x41c0be7700000000, 0x1276534200000000, 0x1ce6d8e700000000, - 0xb41a882900000000, 0xba8a038c00000000, 0xe93ceeb900000000, - 0xe7ac651c00000000}, - {0x0000000000000000, 0x97a61de700000000, 0x6f4b4a1500000000, - 0xf8ed57f200000000, 0xde96942a00000000, 0x493089cd00000000, - 0xb1ddde3f00000000, 0x267bc3d800000000, 0xbc2d295500000000, - 0x2b8b34b200000000, 0xd366634000000000, 0x44c07ea700000000, - 0x62bbbd7f00000000, 0xf51da09800000000, 0x0df0f76a00000000, - 0x9a56ea8d00000000, 0x785b52aa00000000, 0xeffd4f4d00000000, - 0x171018bf00000000, 0x80b6055800000000, 0xa6cdc68000000000, - 0x316bdb6700000000, 0xc9868c9500000000, 0x5e20917200000000, - 0xc4767bff00000000, 0x53d0661800000000, 0xab3d31ea00000000, - 0x3c9b2c0d00000000, 0x1ae0efd500000000, 0x8d46f23200000000, - 0x75aba5c000000000, 0xe20db82700000000, 0xb1b0d58f00000000, - 0x2616c86800000000, 0xdefb9f9a00000000, 0x495d827d00000000, - 0x6f2641a500000000, 0xf8805c4200000000, 0x006d0bb000000000, - 0x97cb165700000000, 0x0d9dfcda00000000, 0x9a3be13d00000000, - 0x62d6b6cf00000000, 0xf570ab2800000000, 0xd30b68f000000000, - 0x44ad751700000000, 0xbc4022e500000000, 0x2be63f0200000000, - 0xc9eb872500000000, 0x5e4d9ac200000000, 0xa6a0cd3000000000, - 0x3106d0d700000000, 0x177d130f00000000, 0x80db0ee800000000, - 0x7836591a00000000, 0xef9044fd00000000, 0x75c6ae7000000000, - 0xe260b39700000000, 0x1a8de46500000000, 0x8d2bf98200000000, - 0xab503a5a00000000, 0x3cf627bd00000000, 0xc41b704f00000000, - 0x53bd6da800000000, 0x2367dac400000000, 0xb4c1c72300000000, - 0x4c2c90d100000000, 0xdb8a8d3600000000, 0xfdf14eee00000000, - 0x6a57530900000000, 0x92ba04fb00000000, 0x051c191c00000000, - 0x9f4af39100000000, 0x08ecee7600000000, 0xf001b98400000000, - 0x67a7a46300000000, 0x41dc67bb00000000, 0xd67a7a5c00000000, - 0x2e972dae00000000, 0xb931304900000000, 0x5b3c886e00000000, - 0xcc9a958900000000, 0x3477c27b00000000, 0xa3d1df9c00000000, - 0x85aa1c4400000000, 0x120c01a300000000, 0xeae1565100000000, - 0x7d474bb600000000, 0xe711a13b00000000, 0x70b7bcdc00000000, - 0x885aeb2e00000000, 0x1ffcf6c900000000, 0x3987351100000000, - 0xae2128f600000000, 0x56cc7f0400000000, 0xc16a62e300000000, - 0x92d70f4b00000000, 0x057112ac00000000, 0xfd9c455e00000000, - 0x6a3a58b900000000, 0x4c419b6100000000, 0xdbe7868600000000, - 0x230ad17400000000, 0xb4accc9300000000, 0x2efa261e00000000, - 0xb95c3bf900000000, 0x41b16c0b00000000, 0xd61771ec00000000, - 0xf06cb23400000000, 0x67caafd300000000, 0x9f27f82100000000, - 0x0881e5c600000000, 0xea8c5de100000000, 0x7d2a400600000000, - 0x85c717f400000000, 0x12610a1300000000, 0x341ac9cb00000000, - 0xa3bcd42c00000000, 0x5b5183de00000000, 0xccf79e3900000000, - 0x56a174b400000000, 0xc107695300000000, 0x39ea3ea100000000, - 0xae4c234600000000, 0x8837e09e00000000, 0x1f91fd7900000000, - 0xe77caa8b00000000, 0x70dab76c00000000, 0x07c8c55200000000, - 0x906ed8b500000000, 0x68838f4700000000, 0xff2592a000000000, - 0xd95e517800000000, 0x4ef84c9f00000000, 0xb6151b6d00000000, - 0x21b3068a00000000, 0xbbe5ec0700000000, 0x2c43f1e000000000, - 0xd4aea61200000000, 0x4308bbf500000000, 0x6573782d00000000, - 0xf2d565ca00000000, 0x0a38323800000000, 0x9d9e2fdf00000000, - 0x7f9397f800000000, 0xe8358a1f00000000, 0x10d8dded00000000, - 0x877ec00a00000000, 0xa10503d200000000, 0x36a31e3500000000, - 0xce4e49c700000000, 0x59e8542000000000, 0xc3bebead00000000, - 0x5418a34a00000000, 0xacf5f4b800000000, 0x3b53e95f00000000, - 0x1d282a8700000000, 0x8a8e376000000000, 0x7263609200000000, - 0xe5c57d7500000000, 0xb67810dd00000000, 0x21de0d3a00000000, - 0xd9335ac800000000, 0x4e95472f00000000, 0x68ee84f700000000, - 0xff48991000000000, 0x07a5cee200000000, 0x9003d30500000000, - 0x0a55398800000000, 0x9df3246f00000000, 0x651e739d00000000, - 0xf2b86e7a00000000, 0xd4c3ada200000000, 0x4365b04500000000, - 0xbb88e7b700000000, 0x2c2efa5000000000, 0xce23427700000000, - 0x59855f9000000000, 0xa168086200000000, 0x36ce158500000000, - 0x10b5d65d00000000, 0x8713cbba00000000, 0x7ffe9c4800000000, - 0xe85881af00000000, 0x720e6b2200000000, 0xe5a876c500000000, - 0x1d45213700000000, 0x8ae33cd000000000, 0xac98ff0800000000, - 0x3b3ee2ef00000000, 0xc3d3b51d00000000, 0x5475a8fa00000000, - 0x24af1f9600000000, 0xb309027100000000, 0x4be4558300000000, - 0xdc42486400000000, 0xfa398bbc00000000, 0x6d9f965b00000000, - 0x9572c1a900000000, 0x02d4dc4e00000000, 0x988236c300000000, - 0x0f242b2400000000, 0xf7c97cd600000000, 0x606f613100000000, - 0x4614a2e900000000, 0xd1b2bf0e00000000, 0x295fe8fc00000000, - 0xbef9f51b00000000, 0x5cf44d3c00000000, 0xcb5250db00000000, - 0x33bf072900000000, 0xa4191ace00000000, 0x8262d91600000000, - 0x15c4c4f100000000, 0xed29930300000000, 0x7a8f8ee400000000, - 0xe0d9646900000000, 0x777f798e00000000, 0x8f922e7c00000000, - 0x1834339b00000000, 0x3e4ff04300000000, 0xa9e9eda400000000, - 0x5104ba5600000000, 0xc6a2a7b100000000, 0x951fca1900000000, - 0x02b9d7fe00000000, 0xfa54800c00000000, 0x6df29deb00000000, - 0x4b895e3300000000, 0xdc2f43d400000000, 0x24c2142600000000, - 0xb36409c100000000, 0x2932e34c00000000, 0xbe94feab00000000, - 0x4679a95900000000, 0xd1dfb4be00000000, 0xf7a4776600000000, - 0x60026a8100000000, 0x98ef3d7300000000, 0x0f49209400000000, - 0xed4498b300000000, 0x7ae2855400000000, 0x820fd2a600000000, - 0x15a9cf4100000000, 0x33d20c9900000000, 0xa474117e00000000, - 0x5c99468c00000000, 0xcb3f5b6b00000000, 0x5169b1e600000000, - 0xc6cfac0100000000, 0x3e22fbf300000000, 0xa984e61400000000, - 0x8fff25cc00000000, 0x1859382b00000000, 0xe0b46fd900000000, - 0x7712723e00000000}, - {0x0000000000000000, 0x411b8c6e00000000, 0x823618dd00000000, - 0xc32d94b300000000, 0x456b416100000000, 0x0470cd0f00000000, - 0xc75d59bc00000000, 0x8646d5d200000000, 0x8ad682c200000000, - 0xcbcd0eac00000000, 0x08e09a1f00000000, 0x49fb167100000000, - 0xcfbdc3a300000000, 0x8ea64fcd00000000, 0x4d8bdb7e00000000, - 0x0c90571000000000, 0x55ab745e00000000, 0x14b0f83000000000, - 0xd79d6c8300000000, 0x9686e0ed00000000, 0x10c0353f00000000, - 0x51dbb95100000000, 0x92f62de200000000, 0xd3eda18c00000000, - 0xdf7df69c00000000, 0x9e667af200000000, 0x5d4bee4100000000, - 0x1c50622f00000000, 0x9a16b7fd00000000, 0xdb0d3b9300000000, - 0x1820af2000000000, 0x593b234e00000000, 0xaa56e9bc00000000, - 0xeb4d65d200000000, 0x2860f16100000000, 0x697b7d0f00000000, - 0xef3da8dd00000000, 0xae2624b300000000, 0x6d0bb00000000000, - 0x2c103c6e00000000, 0x20806b7e00000000, 0x619be71000000000, - 0xa2b673a300000000, 0xe3adffcd00000000, 0x65eb2a1f00000000, - 0x24f0a67100000000, 0xe7dd32c200000000, 0xa6c6beac00000000, - 0xfffd9de200000000, 0xbee6118c00000000, 0x7dcb853f00000000, - 0x3cd0095100000000, 0xba96dc8300000000, 0xfb8d50ed00000000, - 0x38a0c45e00000000, 0x79bb483000000000, 0x752b1f2000000000, - 0x3430934e00000000, 0xf71d07fd00000000, 0xb6068b9300000000, - 0x30405e4100000000, 0x715bd22f00000000, 0xb276469c00000000, - 0xf36dcaf200000000, 0x15aba3a200000000, 0x54b02fcc00000000, - 0x979dbb7f00000000, 0xd686371100000000, 0x50c0e2c300000000, - 0x11db6ead00000000, 0xd2f6fa1e00000000, 0x93ed767000000000, - 0x9f7d216000000000, 0xde66ad0e00000000, 0x1d4b39bd00000000, - 0x5c50b5d300000000, 0xda16600100000000, 0x9b0dec6f00000000, - 0x582078dc00000000, 0x193bf4b200000000, 0x4000d7fc00000000, - 0x011b5b9200000000, 0xc236cf2100000000, 0x832d434f00000000, - 0x056b969d00000000, 0x44701af300000000, 0x875d8e4000000000, - 0xc646022e00000000, 0xcad6553e00000000, 0x8bcdd95000000000, - 0x48e04de300000000, 0x09fbc18d00000000, 0x8fbd145f00000000, - 0xcea6983100000000, 0x0d8b0c8200000000, 0x4c9080ec00000000, - 0xbffd4a1e00000000, 0xfee6c67000000000, 0x3dcb52c300000000, - 0x7cd0dead00000000, 0xfa960b7f00000000, 0xbb8d871100000000, - 0x78a013a200000000, 0x39bb9fcc00000000, 0x352bc8dc00000000, - 0x743044b200000000, 0xb71dd00100000000, 0xf6065c6f00000000, - 0x704089bd00000000, 0x315b05d300000000, 0xf276916000000000, - 0xb36d1d0e00000000, 0xea563e4000000000, 0xab4db22e00000000, - 0x6860269d00000000, 0x297baaf300000000, 0xaf3d7f2100000000, - 0xee26f34f00000000, 0x2d0b67fc00000000, 0x6c10eb9200000000, - 0x6080bc8200000000, 0x219b30ec00000000, 0xe2b6a45f00000000, - 0xa3ad283100000000, 0x25ebfde300000000, 0x64f0718d00000000, - 0xa7dde53e00000000, 0xe6c6695000000000, 0x6b50369e00000000, - 0x2a4bbaf000000000, 0xe9662e4300000000, 0xa87da22d00000000, - 0x2e3b77ff00000000, 0x6f20fb9100000000, 0xac0d6f2200000000, - 0xed16e34c00000000, 0xe186b45c00000000, 0xa09d383200000000, - 0x63b0ac8100000000, 0x22ab20ef00000000, 0xa4edf53d00000000, - 0xe5f6795300000000, 0x26dbede000000000, 0x67c0618e00000000, - 0x3efb42c000000000, 0x7fe0ceae00000000, 0xbccd5a1d00000000, - 0xfdd6d67300000000, 0x7b9003a100000000, 0x3a8b8fcf00000000, - 0xf9a61b7c00000000, 0xb8bd971200000000, 0xb42dc00200000000, - 0xf5364c6c00000000, 0x361bd8df00000000, 0x770054b100000000, - 0xf146816300000000, 0xb05d0d0d00000000, 0x737099be00000000, - 0x326b15d000000000, 0xc106df2200000000, 0x801d534c00000000, - 0x4330c7ff00000000, 0x022b4b9100000000, 0x846d9e4300000000, - 0xc576122d00000000, 0x065b869e00000000, 0x47400af000000000, - 0x4bd05de000000000, 0x0acbd18e00000000, 0xc9e6453d00000000, - 0x88fdc95300000000, 0x0ebb1c8100000000, 0x4fa090ef00000000, - 0x8c8d045c00000000, 0xcd96883200000000, 0x94adab7c00000000, - 0xd5b6271200000000, 0x169bb3a100000000, 0x57803fcf00000000, - 0xd1c6ea1d00000000, 0x90dd667300000000, 0x53f0f2c000000000, - 0x12eb7eae00000000, 0x1e7b29be00000000, 0x5f60a5d000000000, - 0x9c4d316300000000, 0xdd56bd0d00000000, 0x5b1068df00000000, - 0x1a0be4b100000000, 0xd926700200000000, 0x983dfc6c00000000, - 0x7efb953c00000000, 0x3fe0195200000000, 0xfccd8de100000000, - 0xbdd6018f00000000, 0x3b90d45d00000000, 0x7a8b583300000000, - 0xb9a6cc8000000000, 0xf8bd40ee00000000, 0xf42d17fe00000000, - 0xb5369b9000000000, 0x761b0f2300000000, 0x3700834d00000000, - 0xb146569f00000000, 0xf05ddaf100000000, 0x33704e4200000000, - 0x726bc22c00000000, 0x2b50e16200000000, 0x6a4b6d0c00000000, - 0xa966f9bf00000000, 0xe87d75d100000000, 0x6e3ba00300000000, - 0x2f202c6d00000000, 0xec0db8de00000000, 0xad1634b000000000, - 0xa18663a000000000, 0xe09defce00000000, 0x23b07b7d00000000, - 0x62abf71300000000, 0xe4ed22c100000000, 0xa5f6aeaf00000000, - 0x66db3a1c00000000, 0x27c0b67200000000, 0xd4ad7c8000000000, - 0x95b6f0ee00000000, 0x569b645d00000000, 0x1780e83300000000, - 0x91c63de100000000, 0xd0ddb18f00000000, 0x13f0253c00000000, - 0x52eba95200000000, 0x5e7bfe4200000000, 0x1f60722c00000000, - 0xdc4de69f00000000, 0x9d566af100000000, 0x1b10bf2300000000, - 0x5a0b334d00000000, 0x9926a7fe00000000, 0xd83d2b9000000000, - 0x810608de00000000, 0xc01d84b000000000, 0x0330100300000000, - 0x422b9c6d00000000, 0xc46d49bf00000000, 0x8576c5d100000000, - 0x465b516200000000, 0x0740dd0c00000000, 0x0bd08a1c00000000, - 0x4acb067200000000, 0x89e692c100000000, 0xc8fd1eaf00000000, - 0x4ebbcb7d00000000, 0x0fa0471300000000, 0xcc8dd3a000000000, - 0x8d965fce00000000}, - {0x0000000000000000, 0x1dfdb50100000000, 0x3afa6b0300000000, - 0x2707de0200000000, 0x74f4d70600000000, 0x6909620700000000, - 0x4e0ebc0500000000, 0x53f3090400000000, 0xe8e8af0d00000000, - 0xf5151a0c00000000, 0xd212c40e00000000, 0xcfef710f00000000, - 0x9c1c780b00000000, 0x81e1cd0a00000000, 0xa6e6130800000000, - 0xbb1ba60900000000, 0xd0d15f1b00000000, 0xcd2cea1a00000000, - 0xea2b341800000000, 0xf7d6811900000000, 0xa425881d00000000, - 0xb9d83d1c00000000, 0x9edfe31e00000000, 0x8322561f00000000, - 0x3839f01600000000, 0x25c4451700000000, 0x02c39b1500000000, - 0x1f3e2e1400000000, 0x4ccd271000000000, 0x5130921100000000, - 0x76374c1300000000, 0x6bcaf91200000000, 0xa0a3bf3600000000, - 0xbd5e0a3700000000, 0x9a59d43500000000, 0x87a4613400000000, - 0xd457683000000000, 0xc9aadd3100000000, 0xeead033300000000, - 0xf350b63200000000, 0x484b103b00000000, 0x55b6a53a00000000, - 0x72b17b3800000000, 0x6f4cce3900000000, 0x3cbfc73d00000000, - 0x2142723c00000000, 0x0645ac3e00000000, 0x1bb8193f00000000, - 0x7072e02d00000000, 0x6d8f552c00000000, 0x4a888b2e00000000, - 0x57753e2f00000000, 0x0486372b00000000, 0x197b822a00000000, - 0x3e7c5c2800000000, 0x2381e92900000000, 0x989a4f2000000000, - 0x8567fa2100000000, 0xa260242300000000, 0xbf9d912200000000, - 0xec6e982600000000, 0xf1932d2700000000, 0xd694f32500000000, - 0xcb69462400000000, 0x40477f6d00000000, 0x5dbaca6c00000000, - 0x7abd146e00000000, 0x6740a16f00000000, 0x34b3a86b00000000, - 0x294e1d6a00000000, 0x0e49c36800000000, 0x13b4766900000000, - 0xa8afd06000000000, 0xb552656100000000, 0x9255bb6300000000, - 0x8fa80e6200000000, 0xdc5b076600000000, 0xc1a6b26700000000, - 0xe6a16c6500000000, 0xfb5cd96400000000, 0x9096207600000000, - 0x8d6b957700000000, 0xaa6c4b7500000000, 0xb791fe7400000000, - 0xe462f77000000000, 0xf99f427100000000, 0xde989c7300000000, - 0xc365297200000000, 0x787e8f7b00000000, 0x65833a7a00000000, - 0x4284e47800000000, 0x5f79517900000000, 0x0c8a587d00000000, - 0x1177ed7c00000000, 0x3670337e00000000, 0x2b8d867f00000000, - 0xe0e4c05b00000000, 0xfd19755a00000000, 0xda1eab5800000000, - 0xc7e31e5900000000, 0x9410175d00000000, 0x89eda25c00000000, - 0xaeea7c5e00000000, 0xb317c95f00000000, 0x080c6f5600000000, - 0x15f1da5700000000, 0x32f6045500000000, 0x2f0bb15400000000, - 0x7cf8b85000000000, 0x61050d5100000000, 0x4602d35300000000, - 0x5bff665200000000, 0x30359f4000000000, 0x2dc82a4100000000, - 0x0acff44300000000, 0x1732414200000000, 0x44c1484600000000, - 0x593cfd4700000000, 0x7e3b234500000000, 0x63c6964400000000, - 0xd8dd304d00000000, 0xc520854c00000000, 0xe2275b4e00000000, - 0xffdaee4f00000000, 0xac29e74b00000000, 0xb1d4524a00000000, - 0x96d38c4800000000, 0x8b2e394900000000, 0x808efeda00000000, - 0x9d734bdb00000000, 0xba7495d900000000, 0xa78920d800000000, - 0xf47a29dc00000000, 0xe9879cdd00000000, 0xce8042df00000000, - 0xd37df7de00000000, 0x686651d700000000, 0x759be4d600000000, - 0x529c3ad400000000, 0x4f618fd500000000, 0x1c9286d100000000, - 0x016f33d000000000, 0x2668edd200000000, 0x3b9558d300000000, - 0x505fa1c100000000, 0x4da214c000000000, 0x6aa5cac200000000, - 0x77587fc300000000, 0x24ab76c700000000, 0x3956c3c600000000, - 0x1e511dc400000000, 0x03aca8c500000000, 0xb8b70ecc00000000, - 0xa54abbcd00000000, 0x824d65cf00000000, 0x9fb0d0ce00000000, - 0xcc43d9ca00000000, 0xd1be6ccb00000000, 0xf6b9b2c900000000, - 0xeb4407c800000000, 0x202d41ec00000000, 0x3dd0f4ed00000000, - 0x1ad72aef00000000, 0x072a9fee00000000, 0x54d996ea00000000, - 0x492423eb00000000, 0x6e23fde900000000, 0x73de48e800000000, - 0xc8c5eee100000000, 0xd5385be000000000, 0xf23f85e200000000, - 0xefc230e300000000, 0xbc3139e700000000, 0xa1cc8ce600000000, - 0x86cb52e400000000, 0x9b36e7e500000000, 0xf0fc1ef700000000, - 0xed01abf600000000, 0xca0675f400000000, 0xd7fbc0f500000000, - 0x8408c9f100000000, 0x99f57cf000000000, 0xbef2a2f200000000, - 0xa30f17f300000000, 0x1814b1fa00000000, 0x05e904fb00000000, - 0x22eedaf900000000, 0x3f136ff800000000, 0x6ce066fc00000000, - 0x711dd3fd00000000, 0x561a0dff00000000, 0x4be7b8fe00000000, - 0xc0c981b700000000, 0xdd3434b600000000, 0xfa33eab400000000, - 0xe7ce5fb500000000, 0xb43d56b100000000, 0xa9c0e3b000000000, - 0x8ec73db200000000, 0x933a88b300000000, 0x28212eba00000000, - 0x35dc9bbb00000000, 0x12db45b900000000, 0x0f26f0b800000000, - 0x5cd5f9bc00000000, 0x41284cbd00000000, 0x662f92bf00000000, - 0x7bd227be00000000, 0x1018deac00000000, 0x0de56bad00000000, - 0x2ae2b5af00000000, 0x371f00ae00000000, 0x64ec09aa00000000, - 0x7911bcab00000000, 0x5e1662a900000000, 0x43ebd7a800000000, - 0xf8f071a100000000, 0xe50dc4a000000000, 0xc20a1aa200000000, - 0xdff7afa300000000, 0x8c04a6a700000000, 0x91f913a600000000, - 0xb6fecda400000000, 0xab0378a500000000, 0x606a3e8100000000, - 0x7d978b8000000000, 0x5a90558200000000, 0x476de08300000000, - 0x149ee98700000000, 0x09635c8600000000, 0x2e64828400000000, - 0x3399378500000000, 0x8882918c00000000, 0x957f248d00000000, - 0xb278fa8f00000000, 0xaf854f8e00000000, 0xfc76468a00000000, - 0xe18bf38b00000000, 0xc68c2d8900000000, 0xdb71988800000000, - 0xb0bb619a00000000, 0xad46d49b00000000, 0x8a410a9900000000, - 0x97bcbf9800000000, 0xc44fb69c00000000, 0xd9b2039d00000000, - 0xfeb5dd9f00000000, 0xe348689e00000000, 0x5853ce9700000000, - 0x45ae7b9600000000, 0x62a9a59400000000, 0x7f54109500000000, - 0x2ca7199100000000, 0x315aac9000000000, 0x165d729200000000, - 0x0ba0c79300000000}, - {0x0000000000000000, 0x24d9076300000000, 0x48b20fc600000000, - 0x6c6b08a500000000, 0xd1626e5700000000, 0xf5bb693400000000, - 0x99d0619100000000, 0xbd0966f200000000, 0xa2c5dcae00000000, - 0x861cdbcd00000000, 0xea77d36800000000, 0xceaed40b00000000, - 0x73a7b2f900000000, 0x577eb59a00000000, 0x3b15bd3f00000000, - 0x1fccba5c00000000, 0x058dc88600000000, 0x2154cfe500000000, - 0x4d3fc74000000000, 0x69e6c02300000000, 0xd4efa6d100000000, - 0xf036a1b200000000, 0x9c5da91700000000, 0xb884ae7400000000, - 0xa748142800000000, 0x8391134b00000000, 0xeffa1bee00000000, - 0xcb231c8d00000000, 0x762a7a7f00000000, 0x52f37d1c00000000, - 0x3e9875b900000000, 0x1a4172da00000000, 0x4b1ce0d600000000, - 0x6fc5e7b500000000, 0x03aeef1000000000, 0x2777e87300000000, - 0x9a7e8e8100000000, 0xbea789e200000000, 0xd2cc814700000000, - 0xf615862400000000, 0xe9d93c7800000000, 0xcd003b1b00000000, - 0xa16b33be00000000, 0x85b234dd00000000, 0x38bb522f00000000, - 0x1c62554c00000000, 0x70095de900000000, 0x54d05a8a00000000, - 0x4e91285000000000, 0x6a482f3300000000, 0x0623279600000000, - 0x22fa20f500000000, 0x9ff3460700000000, 0xbb2a416400000000, - 0xd74149c100000000, 0xf3984ea200000000, 0xec54f4fe00000000, - 0xc88df39d00000000, 0xa4e6fb3800000000, 0x803ffc5b00000000, - 0x3d369aa900000000, 0x19ef9dca00000000, 0x7584956f00000000, - 0x515d920c00000000, 0xd73eb17600000000, 0xf3e7b61500000000, - 0x9f8cbeb000000000, 0xbb55b9d300000000, 0x065cdf2100000000, - 0x2285d84200000000, 0x4eeed0e700000000, 0x6a37d78400000000, - 0x75fb6dd800000000, 0x51226abb00000000, 0x3d49621e00000000, - 0x1990657d00000000, 0xa499038f00000000, 0x804004ec00000000, - 0xec2b0c4900000000, 0xc8f20b2a00000000, 0xd2b379f000000000, - 0xf66a7e9300000000, 0x9a01763600000000, 0xbed8715500000000, - 0x03d117a700000000, 0x270810c400000000, 0x4b63186100000000, - 0x6fba1f0200000000, 0x7076a55e00000000, 0x54afa23d00000000, - 0x38c4aa9800000000, 0x1c1dadfb00000000, 0xa114cb0900000000, - 0x85cdcc6a00000000, 0xe9a6c4cf00000000, 0xcd7fc3ac00000000, - 0x9c2251a000000000, 0xb8fb56c300000000, 0xd4905e6600000000, - 0xf049590500000000, 0x4d403ff700000000, 0x6999389400000000, - 0x05f2303100000000, 0x212b375200000000, 0x3ee78d0e00000000, - 0x1a3e8a6d00000000, 0x765582c800000000, 0x528c85ab00000000, - 0xef85e35900000000, 0xcb5ce43a00000000, 0xa737ec9f00000000, - 0x83eeebfc00000000, 0x99af992600000000, 0xbd769e4500000000, - 0xd11d96e000000000, 0xf5c4918300000000, 0x48cdf77100000000, - 0x6c14f01200000000, 0x007ff8b700000000, 0x24a6ffd400000000, - 0x3b6a458800000000, 0x1fb342eb00000000, 0x73d84a4e00000000, - 0x57014d2d00000000, 0xea082bdf00000000, 0xced12cbc00000000, - 0xa2ba241900000000, 0x8663237a00000000, 0xae7d62ed00000000, - 0x8aa4658e00000000, 0xe6cf6d2b00000000, 0xc2166a4800000000, - 0x7f1f0cba00000000, 0x5bc60bd900000000, 0x37ad037c00000000, - 0x1374041f00000000, 0x0cb8be4300000000, 0x2861b92000000000, - 0x440ab18500000000, 0x60d3b6e600000000, 0xdddad01400000000, - 0xf903d77700000000, 0x9568dfd200000000, 0xb1b1d8b100000000, - 0xabf0aa6b00000000, 0x8f29ad0800000000, 0xe342a5ad00000000, - 0xc79ba2ce00000000, 0x7a92c43c00000000, 0x5e4bc35f00000000, - 0x3220cbfa00000000, 0x16f9cc9900000000, 0x093576c500000000, - 0x2dec71a600000000, 0x4187790300000000, 0x655e7e6000000000, - 0xd857189200000000, 0xfc8e1ff100000000, 0x90e5175400000000, - 0xb43c103700000000, 0xe561823b00000000, 0xc1b8855800000000, - 0xadd38dfd00000000, 0x890a8a9e00000000, 0x3403ec6c00000000, - 0x10daeb0f00000000, 0x7cb1e3aa00000000, 0x5868e4c900000000, - 0x47a45e9500000000, 0x637d59f600000000, 0x0f16515300000000, - 0x2bcf563000000000, 0x96c630c200000000, 0xb21f37a100000000, - 0xde743f0400000000, 0xfaad386700000000, 0xe0ec4abd00000000, - 0xc4354dde00000000, 0xa85e457b00000000, 0x8c87421800000000, - 0x318e24ea00000000, 0x1557238900000000, 0x793c2b2c00000000, - 0x5de52c4f00000000, 0x4229961300000000, 0x66f0917000000000, - 0x0a9b99d500000000, 0x2e429eb600000000, 0x934bf84400000000, - 0xb792ff2700000000, 0xdbf9f78200000000, 0xff20f0e100000000, - 0x7943d39b00000000, 0x5d9ad4f800000000, 0x31f1dc5d00000000, - 0x1528db3e00000000, 0xa821bdcc00000000, 0x8cf8baaf00000000, - 0xe093b20a00000000, 0xc44ab56900000000, 0xdb860f3500000000, - 0xff5f085600000000, 0x933400f300000000, 0xb7ed079000000000, - 0x0ae4616200000000, 0x2e3d660100000000, 0x42566ea400000000, - 0x668f69c700000000, 0x7cce1b1d00000000, 0x58171c7e00000000, - 0x347c14db00000000, 0x10a513b800000000, 0xadac754a00000000, - 0x8975722900000000, 0xe51e7a8c00000000, 0xc1c77def00000000, - 0xde0bc7b300000000, 0xfad2c0d000000000, 0x96b9c87500000000, - 0xb260cf1600000000, 0x0f69a9e400000000, 0x2bb0ae8700000000, - 0x47dba62200000000, 0x6302a14100000000, 0x325f334d00000000, - 0x1686342e00000000, 0x7aed3c8b00000000, 0x5e343be800000000, - 0xe33d5d1a00000000, 0xc7e45a7900000000, 0xab8f52dc00000000, - 0x8f5655bf00000000, 0x909aefe300000000, 0xb443e88000000000, - 0xd828e02500000000, 0xfcf1e74600000000, 0x41f881b400000000, - 0x652186d700000000, 0x094a8e7200000000, 0x2d93891100000000, - 0x37d2fbcb00000000, 0x130bfca800000000, 0x7f60f40d00000000, - 0x5bb9f36e00000000, 0xe6b0959c00000000, 0xc26992ff00000000, - 0xae029a5a00000000, 0x8adb9d3900000000, 0x9517276500000000, - 0xb1ce200600000000, 0xdda528a300000000, 0xf97c2fc000000000, - 0x4475493200000000, 0x60ac4e5100000000, 0x0cc746f400000000, - 0x281e419700000000}, - {0x0000000000000000, 0x08e3603c00000000, 0x10c6c17800000000, - 0x1825a14400000000, 0x208c83f100000000, 0x286fe3cd00000000, - 0x304a428900000000, 0x38a922b500000000, 0x011e763800000000, - 0x09fd160400000000, 0x11d8b74000000000, 0x193bd77c00000000, - 0x2192f5c900000000, 0x297195f500000000, 0x315434b100000000, - 0x39b7548d00000000, 0x023cec7000000000, 0x0adf8c4c00000000, - 0x12fa2d0800000000, 0x1a194d3400000000, 0x22b06f8100000000, - 0x2a530fbd00000000, 0x3276aef900000000, 0x3a95cec500000000, - 0x03229a4800000000, 0x0bc1fa7400000000, 0x13e45b3000000000, - 0x1b073b0c00000000, 0x23ae19b900000000, 0x2b4d798500000000, - 0x3368d8c100000000, 0x3b8bb8fd00000000, 0x0478d8e100000000, - 0x0c9bb8dd00000000, 0x14be199900000000, 0x1c5d79a500000000, - 0x24f45b1000000000, 0x2c173b2c00000000, 0x34329a6800000000, - 0x3cd1fa5400000000, 0x0566aed900000000, 0x0d85cee500000000, - 0x15a06fa100000000, 0x1d430f9d00000000, 0x25ea2d2800000000, - 0x2d094d1400000000, 0x352cec5000000000, 0x3dcf8c6c00000000, - 0x0644349100000000, 0x0ea754ad00000000, 0x1682f5e900000000, - 0x1e6195d500000000, 0x26c8b76000000000, 0x2e2bd75c00000000, - 0x360e761800000000, 0x3eed162400000000, 0x075a42a900000000, - 0x0fb9229500000000, 0x179c83d100000000, 0x1f7fe3ed00000000, - 0x27d6c15800000000, 0x2f35a16400000000, 0x3710002000000000, - 0x3ff3601c00000000, 0x49f6c11800000000, 0x4115a12400000000, - 0x5930006000000000, 0x51d3605c00000000, 0x697a42e900000000, - 0x619922d500000000, 0x79bc839100000000, 0x715fe3ad00000000, - 0x48e8b72000000000, 0x400bd71c00000000, 0x582e765800000000, - 0x50cd166400000000, 0x686434d100000000, 0x608754ed00000000, - 0x78a2f5a900000000, 0x7041959500000000, 0x4bca2d6800000000, - 0x43294d5400000000, 0x5b0cec1000000000, 0x53ef8c2c00000000, - 0x6b46ae9900000000, 0x63a5cea500000000, 0x7b806fe100000000, - 0x73630fdd00000000, 0x4ad45b5000000000, 0x42373b6c00000000, - 0x5a129a2800000000, 0x52f1fa1400000000, 0x6a58d8a100000000, - 0x62bbb89d00000000, 0x7a9e19d900000000, 0x727d79e500000000, - 0x4d8e19f900000000, 0x456d79c500000000, 0x5d48d88100000000, - 0x55abb8bd00000000, 0x6d029a0800000000, 0x65e1fa3400000000, - 0x7dc45b7000000000, 0x75273b4c00000000, 0x4c906fc100000000, - 0x44730ffd00000000, 0x5c56aeb900000000, 0x54b5ce8500000000, - 0x6c1cec3000000000, 0x64ff8c0c00000000, 0x7cda2d4800000000, - 0x74394d7400000000, 0x4fb2f58900000000, 0x475195b500000000, - 0x5f7434f100000000, 0x579754cd00000000, 0x6f3e767800000000, - 0x67dd164400000000, 0x7ff8b70000000000, 0x771bd73c00000000, - 0x4eac83b100000000, 0x464fe38d00000000, 0x5e6a42c900000000, - 0x568922f500000000, 0x6e20004000000000, 0x66c3607c00000000, - 0x7ee6c13800000000, 0x7605a10400000000, 0x92ec833100000000, - 0x9a0fe30d00000000, 0x822a424900000000, 0x8ac9227500000000, - 0xb26000c000000000, 0xba8360fc00000000, 0xa2a6c1b800000000, - 0xaa45a18400000000, 0x93f2f50900000000, 0x9b11953500000000, - 0x8334347100000000, 0x8bd7544d00000000, 0xb37e76f800000000, - 0xbb9d16c400000000, 0xa3b8b78000000000, 0xab5bd7bc00000000, - 0x90d06f4100000000, 0x98330f7d00000000, 0x8016ae3900000000, - 0x88f5ce0500000000, 0xb05cecb000000000, 0xb8bf8c8c00000000, - 0xa09a2dc800000000, 0xa8794df400000000, 0x91ce197900000000, - 0x992d794500000000, 0x8108d80100000000, 0x89ebb83d00000000, - 0xb1429a8800000000, 0xb9a1fab400000000, 0xa1845bf000000000, - 0xa9673bcc00000000, 0x96945bd000000000, 0x9e773bec00000000, - 0x86529aa800000000, 0x8eb1fa9400000000, 0xb618d82100000000, - 0xbefbb81d00000000, 0xa6de195900000000, 0xae3d796500000000, - 0x978a2de800000000, 0x9f694dd400000000, 0x874cec9000000000, - 0x8faf8cac00000000, 0xb706ae1900000000, 0xbfe5ce2500000000, - 0xa7c06f6100000000, 0xaf230f5d00000000, 0x94a8b7a000000000, - 0x9c4bd79c00000000, 0x846e76d800000000, 0x8c8d16e400000000, - 0xb424345100000000, 0xbcc7546d00000000, 0xa4e2f52900000000, - 0xac01951500000000, 0x95b6c19800000000, 0x9d55a1a400000000, - 0x857000e000000000, 0x8d9360dc00000000, 0xb53a426900000000, - 0xbdd9225500000000, 0xa5fc831100000000, 0xad1fe32d00000000, - 0xdb1a422900000000, 0xd3f9221500000000, 0xcbdc835100000000, - 0xc33fe36d00000000, 0xfb96c1d800000000, 0xf375a1e400000000, - 0xeb5000a000000000, 0xe3b3609c00000000, 0xda04341100000000, - 0xd2e7542d00000000, 0xcac2f56900000000, 0xc221955500000000, - 0xfa88b7e000000000, 0xf26bd7dc00000000, 0xea4e769800000000, - 0xe2ad16a400000000, 0xd926ae5900000000, 0xd1c5ce6500000000, - 0xc9e06f2100000000, 0xc1030f1d00000000, 0xf9aa2da800000000, - 0xf1494d9400000000, 0xe96cecd000000000, 0xe18f8cec00000000, - 0xd838d86100000000, 0xd0dbb85d00000000, 0xc8fe191900000000, - 0xc01d792500000000, 0xf8b45b9000000000, 0xf0573bac00000000, - 0xe8729ae800000000, 0xe091fad400000000, 0xdf629ac800000000, - 0xd781faf400000000, 0xcfa45bb000000000, 0xc7473b8c00000000, - 0xffee193900000000, 0xf70d790500000000, 0xef28d84100000000, - 0xe7cbb87d00000000, 0xde7cecf000000000, 0xd69f8ccc00000000, - 0xceba2d8800000000, 0xc6594db400000000, 0xfef06f0100000000, - 0xf6130f3d00000000, 0xee36ae7900000000, 0xe6d5ce4500000000, - 0xdd5e76b800000000, 0xd5bd168400000000, 0xcd98b7c000000000, - 0xc57bd7fc00000000, 0xfdd2f54900000000, 0xf531957500000000, - 0xed14343100000000, 0xe5f7540d00000000, 0xdc40008000000000, - 0xd4a360bc00000000, 0xcc86c1f800000000, 0xc465a1c400000000, - 0xfccc837100000000, 0xf42fe34d00000000, 0xec0a420900000000, - 0xe4e9223500000000}, - {0x0000000000000000, 0xd1e8e70e00000000, 0xa2d1cf1d00000000, - 0x7339281300000000, 0x44a39f3b00000000, 0x954b783500000000, - 0xe672502600000000, 0x379ab72800000000, 0x88463f7700000000, - 0x59aed87900000000, 0x2a97f06a00000000, 0xfb7f176400000000, - 0xcce5a04c00000000, 0x1d0d474200000000, 0x6e346f5100000000, - 0xbfdc885f00000000, 0x108d7eee00000000, 0xc16599e000000000, - 0xb25cb1f300000000, 0x63b456fd00000000, 0x542ee1d500000000, - 0x85c606db00000000, 0xf6ff2ec800000000, 0x2717c9c600000000, - 0x98cb419900000000, 0x4923a69700000000, 0x3a1a8e8400000000, - 0xebf2698a00000000, 0xdc68dea200000000, 0x0d8039ac00000000, - 0x7eb911bf00000000, 0xaf51f6b100000000, 0x611c8c0700000000, - 0xb0f46b0900000000, 0xc3cd431a00000000, 0x1225a41400000000, - 0x25bf133c00000000, 0xf457f43200000000, 0x876edc2100000000, - 0x56863b2f00000000, 0xe95ab37000000000, 0x38b2547e00000000, - 0x4b8b7c6d00000000, 0x9a639b6300000000, 0xadf92c4b00000000, - 0x7c11cb4500000000, 0x0f28e35600000000, 0xdec0045800000000, - 0x7191f2e900000000, 0xa07915e700000000, 0xd3403df400000000, - 0x02a8dafa00000000, 0x35326dd200000000, 0xe4da8adc00000000, - 0x97e3a2cf00000000, 0x460b45c100000000, 0xf9d7cd9e00000000, - 0x283f2a9000000000, 0x5b06028300000000, 0x8aeee58d00000000, - 0xbd7452a500000000, 0x6c9cb5ab00000000, 0x1fa59db800000000, - 0xce4d7ab600000000, 0xc238180f00000000, 0x13d0ff0100000000, - 0x60e9d71200000000, 0xb101301c00000000, 0x869b873400000000, - 0x5773603a00000000, 0x244a482900000000, 0xf5a2af2700000000, - 0x4a7e277800000000, 0x9b96c07600000000, 0xe8afe86500000000, - 0x39470f6b00000000, 0x0eddb84300000000, 0xdf355f4d00000000, - 0xac0c775e00000000, 0x7de4905000000000, 0xd2b566e100000000, - 0x035d81ef00000000, 0x7064a9fc00000000, 0xa18c4ef200000000, - 0x9616f9da00000000, 0x47fe1ed400000000, 0x34c736c700000000, - 0xe52fd1c900000000, 0x5af3599600000000, 0x8b1bbe9800000000, - 0xf822968b00000000, 0x29ca718500000000, 0x1e50c6ad00000000, - 0xcfb821a300000000, 0xbc8109b000000000, 0x6d69eebe00000000, - 0xa324940800000000, 0x72cc730600000000, 0x01f55b1500000000, - 0xd01dbc1b00000000, 0xe7870b3300000000, 0x366fec3d00000000, - 0x4556c42e00000000, 0x94be232000000000, 0x2b62ab7f00000000, - 0xfa8a4c7100000000, 0x89b3646200000000, 0x585b836c00000000, - 0x6fc1344400000000, 0xbe29d34a00000000, 0xcd10fb5900000000, - 0x1cf81c5700000000, 0xb3a9eae600000000, 0x62410de800000000, - 0x117825fb00000000, 0xc090c2f500000000, 0xf70a75dd00000000, - 0x26e292d300000000, 0x55dbbac000000000, 0x84335dce00000000, - 0x3befd59100000000, 0xea07329f00000000, 0x993e1a8c00000000, - 0x48d6fd8200000000, 0x7f4c4aaa00000000, 0xaea4ada400000000, - 0xdd9d85b700000000, 0x0c7562b900000000, 0x8471301e00000000, - 0x5599d71000000000, 0x26a0ff0300000000, 0xf748180d00000000, - 0xc0d2af2500000000, 0x113a482b00000000, 0x6203603800000000, - 0xb3eb873600000000, 0x0c370f6900000000, 0xdddfe86700000000, - 0xaee6c07400000000, 0x7f0e277a00000000, 0x4894905200000000, - 0x997c775c00000000, 0xea455f4f00000000, 0x3badb84100000000, - 0x94fc4ef000000000, 0x4514a9fe00000000, 0x362d81ed00000000, - 0xe7c566e300000000, 0xd05fd1cb00000000, 0x01b736c500000000, - 0x728e1ed600000000, 0xa366f9d800000000, 0x1cba718700000000, - 0xcd52968900000000, 0xbe6bbe9a00000000, 0x6f83599400000000, - 0x5819eebc00000000, 0x89f109b200000000, 0xfac821a100000000, - 0x2b20c6af00000000, 0xe56dbc1900000000, 0x34855b1700000000, - 0x47bc730400000000, 0x9654940a00000000, 0xa1ce232200000000, - 0x7026c42c00000000, 0x031fec3f00000000, 0xd2f70b3100000000, - 0x6d2b836e00000000, 0xbcc3646000000000, 0xcffa4c7300000000, - 0x1e12ab7d00000000, 0x29881c5500000000, 0xf860fb5b00000000, - 0x8b59d34800000000, 0x5ab1344600000000, 0xf5e0c2f700000000, - 0x240825f900000000, 0x57310dea00000000, 0x86d9eae400000000, - 0xb1435dcc00000000, 0x60abbac200000000, 0x139292d100000000, - 0xc27a75df00000000, 0x7da6fd8000000000, 0xac4e1a8e00000000, - 0xdf77329d00000000, 0x0e9fd59300000000, 0x390562bb00000000, - 0xe8ed85b500000000, 0x9bd4ada600000000, 0x4a3c4aa800000000, - 0x4649281100000000, 0x97a1cf1f00000000, 0xe498e70c00000000, - 0x3570000200000000, 0x02eab72a00000000, 0xd302502400000000, - 0xa03b783700000000, 0x71d39f3900000000, 0xce0f176600000000, - 0x1fe7f06800000000, 0x6cded87b00000000, 0xbd363f7500000000, - 0x8aac885d00000000, 0x5b446f5300000000, 0x287d474000000000, - 0xf995a04e00000000, 0x56c456ff00000000, 0x872cb1f100000000, - 0xf41599e200000000, 0x25fd7eec00000000, 0x1267c9c400000000, - 0xc38f2eca00000000, 0xb0b606d900000000, 0x615ee1d700000000, - 0xde82698800000000, 0x0f6a8e8600000000, 0x7c53a69500000000, - 0xadbb419b00000000, 0x9a21f6b300000000, 0x4bc911bd00000000, - 0x38f039ae00000000, 0xe918dea000000000, 0x2755a41600000000, - 0xf6bd431800000000, 0x85846b0b00000000, 0x546c8c0500000000, - 0x63f63b2d00000000, 0xb21edc2300000000, 0xc127f43000000000, - 0x10cf133e00000000, 0xaf139b6100000000, 0x7efb7c6f00000000, - 0x0dc2547c00000000, 0xdc2ab37200000000, 0xebb0045a00000000, - 0x3a58e35400000000, 0x4961cb4700000000, 0x98892c4900000000, - 0x37d8daf800000000, 0xe6303df600000000, 0x950915e500000000, - 0x44e1f2eb00000000, 0x737b45c300000000, 0xa293a2cd00000000, - 0xd1aa8ade00000000, 0x00426dd000000000, 0xbf9ee58f00000000, - 0x6e76028100000000, 0x1d4f2a9200000000, 0xcca7cd9c00000000, - 0xfb3d7ab400000000, 0x2ad59dba00000000, 0x59ecb5a900000000, - 0x880452a700000000}, - {0x0000000000000000, 0xaa05daf100000000, 0x150dc53800000000, - 0xbf081fc900000000, 0x2a1a8a7100000000, 0x801f508000000000, - 0x3f174f4900000000, 0x951295b800000000, 0x543414e300000000, - 0xfe31ce1200000000, 0x4139d1db00000000, 0xeb3c0b2a00000000, - 0x7e2e9e9200000000, 0xd42b446300000000, 0x6b235baa00000000, - 0xc126815b00000000, 0xe96e591d00000000, 0x436b83ec00000000, - 0xfc639c2500000000, 0x566646d400000000, 0xc374d36c00000000, - 0x6971099d00000000, 0xd679165400000000, 0x7c7ccca500000000, - 0xbd5a4dfe00000000, 0x175f970f00000000, 0xa85788c600000000, - 0x0252523700000000, 0x9740c78f00000000, 0x3d451d7e00000000, - 0x824d02b700000000, 0x2848d84600000000, 0xd2ddb23a00000000, - 0x78d868cb00000000, 0xc7d0770200000000, 0x6dd5adf300000000, - 0xf8c7384b00000000, 0x52c2e2ba00000000, 0xedcafd7300000000, - 0x47cf278200000000, 0x86e9a6d900000000, 0x2cec7c2800000000, - 0x93e463e100000000, 0x39e1b91000000000, 0xacf32ca800000000, - 0x06f6f65900000000, 0xb9fee99000000000, 0x13fb336100000000, - 0x3bb3eb2700000000, 0x91b631d600000000, 0x2ebe2e1f00000000, - 0x84bbf4ee00000000, 0x11a9615600000000, 0xbbacbba700000000, - 0x04a4a46e00000000, 0xaea17e9f00000000, 0x6f87ffc400000000, - 0xc582253500000000, 0x7a8a3afc00000000, 0xd08fe00d00000000, - 0x459d75b500000000, 0xef98af4400000000, 0x5090b08d00000000, - 0xfa956a7c00000000, 0xa4bb657500000000, 0x0ebebf8400000000, - 0xb1b6a04d00000000, 0x1bb37abc00000000, 0x8ea1ef0400000000, - 0x24a435f500000000, 0x9bac2a3c00000000, 0x31a9f0cd00000000, - 0xf08f719600000000, 0x5a8aab6700000000, 0xe582b4ae00000000, - 0x4f876e5f00000000, 0xda95fbe700000000, 0x7090211600000000, - 0xcf983edf00000000, 0x659de42e00000000, 0x4dd53c6800000000, - 0xe7d0e69900000000, 0x58d8f95000000000, 0xf2dd23a100000000, - 0x67cfb61900000000, 0xcdca6ce800000000, 0x72c2732100000000, - 0xd8c7a9d000000000, 0x19e1288b00000000, 0xb3e4f27a00000000, - 0x0cecedb300000000, 0xa6e9374200000000, 0x33fba2fa00000000, - 0x99fe780b00000000, 0x26f667c200000000, 0x8cf3bd3300000000, - 0x7666d74f00000000, 0xdc630dbe00000000, 0x636b127700000000, - 0xc96ec88600000000, 0x5c7c5d3e00000000, 0xf67987cf00000000, - 0x4971980600000000, 0xe37442f700000000, 0x2252c3ac00000000, - 0x8857195d00000000, 0x375f069400000000, 0x9d5adc6500000000, - 0x084849dd00000000, 0xa24d932c00000000, 0x1d458ce500000000, - 0xb740561400000000, 0x9f088e5200000000, 0x350d54a300000000, - 0x8a054b6a00000000, 0x2000919b00000000, 0xb512042300000000, - 0x1f17ded200000000, 0xa01fc11b00000000, 0x0a1a1bea00000000, - 0xcb3c9ab100000000, 0x6139404000000000, 0xde315f8900000000, - 0x7434857800000000, 0xe12610c000000000, 0x4b23ca3100000000, - 0xf42bd5f800000000, 0x5e2e0f0900000000, 0x4877cbea00000000, - 0xe272111b00000000, 0x5d7a0ed200000000, 0xf77fd42300000000, - 0x626d419b00000000, 0xc8689b6a00000000, 0x776084a300000000, - 0xdd655e5200000000, 0x1c43df0900000000, 0xb64605f800000000, - 0x094e1a3100000000, 0xa34bc0c000000000, 0x3659557800000000, - 0x9c5c8f8900000000, 0x2354904000000000, 0x89514ab100000000, - 0xa11992f700000000, 0x0b1c480600000000, 0xb41457cf00000000, - 0x1e118d3e00000000, 0x8b03188600000000, 0x2106c27700000000, - 0x9e0eddbe00000000, 0x340b074f00000000, 0xf52d861400000000, - 0x5f285ce500000000, 0xe020432c00000000, 0x4a2599dd00000000, - 0xdf370c6500000000, 0x7532d69400000000, 0xca3ac95d00000000, - 0x603f13ac00000000, 0x9aaa79d000000000, 0x30afa32100000000, - 0x8fa7bce800000000, 0x25a2661900000000, 0xb0b0f3a100000000, - 0x1ab5295000000000, 0xa5bd369900000000, 0x0fb8ec6800000000, - 0xce9e6d3300000000, 0x649bb7c200000000, 0xdb93a80b00000000, - 0x719672fa00000000, 0xe484e74200000000, 0x4e813db300000000, - 0xf189227a00000000, 0x5b8cf88b00000000, 0x73c420cd00000000, - 0xd9c1fa3c00000000, 0x66c9e5f500000000, 0xcccc3f0400000000, - 0x59deaabc00000000, 0xf3db704d00000000, 0x4cd36f8400000000, - 0xe6d6b57500000000, 0x27f0342e00000000, 0x8df5eedf00000000, - 0x32fdf11600000000, 0x98f82be700000000, 0x0deabe5f00000000, - 0xa7ef64ae00000000, 0x18e77b6700000000, 0xb2e2a19600000000, - 0xecccae9f00000000, 0x46c9746e00000000, 0xf9c16ba700000000, - 0x53c4b15600000000, 0xc6d624ee00000000, 0x6cd3fe1f00000000, - 0xd3dbe1d600000000, 0x79de3b2700000000, 0xb8f8ba7c00000000, - 0x12fd608d00000000, 0xadf57f4400000000, 0x07f0a5b500000000, - 0x92e2300d00000000, 0x38e7eafc00000000, 0x87eff53500000000, - 0x2dea2fc400000000, 0x05a2f78200000000, 0xafa72d7300000000, - 0x10af32ba00000000, 0xbaaae84b00000000, 0x2fb87df300000000, - 0x85bda70200000000, 0x3ab5b8cb00000000, 0x90b0623a00000000, - 0x5196e36100000000, 0xfb93399000000000, 0x449b265900000000, - 0xee9efca800000000, 0x7b8c691000000000, 0xd189b3e100000000, - 0x6e81ac2800000000, 0xc48476d900000000, 0x3e111ca500000000, - 0x9414c65400000000, 0x2b1cd99d00000000, 0x8119036c00000000, - 0x140b96d400000000, 0xbe0e4c2500000000, 0x010653ec00000000, - 0xab03891d00000000, 0x6a25084600000000, 0xc020d2b700000000, - 0x7f28cd7e00000000, 0xd52d178f00000000, 0x403f823700000000, - 0xea3a58c600000000, 0x5532470f00000000, 0xff379dfe00000000, - 0xd77f45b800000000, 0x7d7a9f4900000000, 0xc272808000000000, - 0x68775a7100000000, 0xfd65cfc900000000, 0x5760153800000000, - 0xe8680af100000000, 0x426dd00000000000, 0x834b515b00000000, - 0x294e8baa00000000, 0x9646946300000000, 0x3c434e9200000000, - 0xa951db2a00000000, 0x035401db00000000, 0xbc5c1e1200000000, - 0x1659c4e300000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, - 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, - 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, - 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, - 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, - 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, - 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, - 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, - 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, - 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, - 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, - 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, - 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, - 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, - 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, - 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, - 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, - 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, - 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, - 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, - 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, - 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, - 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, - 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, - 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, - 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, - 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, - 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, - 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, - 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, - 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, - 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, - 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, - 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, - 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, - 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, - 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, - 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, - 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, - 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, - 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, - 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, - 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, - 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, - 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, - 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, - 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, - 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, - 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, - 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, - 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, - 0x0d7139d7}, - {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, - 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, - 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, - 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, - 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, - 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, - 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, - 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, - 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, - 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, - 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, - 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, - 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, - 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, - 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, - 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, - 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, - 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, - 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, - 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, - 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, - 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, - 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, - 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, - 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, - 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, - 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, - 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, - 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, - 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, - 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, - 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, - 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, - 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, - 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, - 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, - 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, - 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, - 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, - 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, - 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, - 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, - 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, - 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, - 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, - 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, - 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, - 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, - 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, - 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, - 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, - 0x1c53e98a}, - {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, - 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, - 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, - 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, - 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, - 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, - 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, - 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, - 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, - 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, - 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, - 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, - 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, - 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, - 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, - 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, - 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, - 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, - 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, - 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, - 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, - 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, - 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, - 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, - 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, - 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, - 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, - 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, - 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, - 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, - 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, - 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, - 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, - 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, - 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, - 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, - 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, - 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, - 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, - 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, - 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, - 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, - 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, - 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, - 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, - 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, - 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, - 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, - 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, - 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, - 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, - 0x3f88e851}, - {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, - 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, - 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, - 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, - 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, - 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, - 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, - 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, - 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, - 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, - 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, - 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, - 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, - 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, - 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, - 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, - 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, - 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, - 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, - 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, - 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, - 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, - 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, - 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, - 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, - 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, - 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, - 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, - 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, - 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, - 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, - 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, - 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, - 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, - 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, - 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, - 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, - 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, - 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, - 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, - 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, - 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, - 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, - 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, - 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, - 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, - 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, - 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, - 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, - 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, - 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, - 0x3dee8ca6}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x85d996dd, 0x4bb55c60, 0xce6ccabd, 0x966ab9c0, - 0x13b32f1d, 0xdddfe5a0, 0x5806737d, 0x6dd3035a, 0xe80a9587, - 0x26665f3a, 0xa3bfc9e7, 0xfbb9ba9a, 0x7e602c47, 0xb00ce6fa, - 0x35d57027, 0xdaa607b4, 0x5f7f9169, 0x91135bd4, 0x14cacd09, - 0x4cccbe74, 0xc91528a9, 0x0779e214, 0x82a074c9, 0xb77504ee, - 0x32ac9233, 0xfcc0588e, 0x7919ce53, 0x211fbd2e, 0xa4c62bf3, - 0x6aaae14e, 0xef737793, 0xf54b7eb3, 0x7092e86e, 0xbefe22d3, - 0x3b27b40e, 0x6321c773, 0xe6f851ae, 0x28949b13, 0xad4d0dce, - 0x98987de9, 0x1d41eb34, 0xd32d2189, 0x56f4b754, 0x0ef2c429, - 0x8b2b52f4, 0x45479849, 0xc09e0e94, 0x2fed7907, 0xaa34efda, - 0x64582567, 0xe181b3ba, 0xb987c0c7, 0x3c5e561a, 0xf2329ca7, - 0x77eb0a7a, 0x423e7a5d, 0xc7e7ec80, 0x098b263d, 0x8c52b0e0, - 0xd454c39d, 0x518d5540, 0x9fe19ffd, 0x1a380920, 0xab918dbd, - 0x2e481b60, 0xe024d1dd, 0x65fd4700, 0x3dfb347d, 0xb822a2a0, - 0x764e681d, 0xf397fec0, 0xc6428ee7, 0x439b183a, 0x8df7d287, - 0x082e445a, 0x50283727, 0xd5f1a1fa, 0x1b9d6b47, 0x9e44fd9a, - 0x71378a09, 0xf4ee1cd4, 0x3a82d669, 0xbf5b40b4, 0xe75d33c9, - 0x6284a514, 0xace86fa9, 0x2931f974, 0x1ce48953, 0x993d1f8e, - 0x5751d533, 0xd28843ee, 0x8a8e3093, 0x0f57a64e, 0xc13b6cf3, - 0x44e2fa2e, 0x5edaf30e, 0xdb0365d3, 0x156faf6e, 0x90b639b3, - 0xc8b04ace, 0x4d69dc13, 0x830516ae, 0x06dc8073, 0x3309f054, - 0xb6d06689, 0x78bcac34, 0xfd653ae9, 0xa5634994, 0x20badf49, - 0xeed615f4, 0x6b0f8329, 0x847cf4ba, 0x01a56267, 0xcfc9a8da, - 0x4a103e07, 0x12164d7a, 0x97cfdba7, 0x59a3111a, 0xdc7a87c7, - 0xe9aff7e0, 0x6c76613d, 0xa21aab80, 0x27c33d5d, 0x7fc54e20, - 0xfa1cd8fd, 0x34701240, 0xb1a9849d, 0x17256aa0, 0x92fcfc7d, - 0x5c9036c0, 0xd949a01d, 0x814fd360, 0x049645bd, 0xcafa8f00, - 0x4f2319dd, 0x7af669fa, 0xff2fff27, 0x3143359a, 0xb49aa347, - 0xec9cd03a, 0x694546e7, 0xa7298c5a, 0x22f01a87, 0xcd836d14, - 0x485afbc9, 0x86363174, 0x03efa7a9, 0x5be9d4d4, 0xde304209, - 0x105c88b4, 0x95851e69, 0xa0506e4e, 0x2589f893, 0xebe5322e, - 0x6e3ca4f3, 0x363ad78e, 0xb3e34153, 0x7d8f8bee, 0xf8561d33, - 0xe26e1413, 0x67b782ce, 0xa9db4873, 0x2c02deae, 0x7404add3, - 0xf1dd3b0e, 0x3fb1f1b3, 0xba68676e, 0x8fbd1749, 0x0a648194, - 0xc4084b29, 0x41d1ddf4, 0x19d7ae89, 0x9c0e3854, 0x5262f2e9, - 0xd7bb6434, 0x38c813a7, 0xbd11857a, 0x737d4fc7, 0xf6a4d91a, - 0xaea2aa67, 0x2b7b3cba, 0xe517f607, 0x60ce60da, 0x551b10fd, - 0xd0c28620, 0x1eae4c9d, 0x9b77da40, 0xc371a93d, 0x46a83fe0, - 0x88c4f55d, 0x0d1d6380, 0xbcb4e71d, 0x396d71c0, 0xf701bb7d, - 0x72d82da0, 0x2ade5edd, 0xaf07c800, 0x616b02bd, 0xe4b29460, - 0xd167e447, 0x54be729a, 0x9ad2b827, 0x1f0b2efa, 0x470d5d87, - 0xc2d4cb5a, 0x0cb801e7, 0x8961973a, 0x6612e0a9, 0xe3cb7674, - 0x2da7bcc9, 0xa87e2a14, 0xf0785969, 0x75a1cfb4, 0xbbcd0509, - 0x3e1493d4, 0x0bc1e3f3, 0x8e18752e, 0x4074bf93, 0xc5ad294e, - 0x9dab5a33, 0x1872ccee, 0xd61e0653, 0x53c7908e, 0x49ff99ae, - 0xcc260f73, 0x024ac5ce, 0x87935313, 0xdf95206e, 0x5a4cb6b3, - 0x94207c0e, 0x11f9ead3, 0x242c9af4, 0xa1f50c29, 0x6f99c694, - 0xea405049, 0xb2462334, 0x379fb5e9, 0xf9f37f54, 0x7c2ae989, - 0x93599e1a, 0x168008c7, 0xd8ecc27a, 0x5d3554a7, 0x053327da, - 0x80eab107, 0x4e867bba, 0xcb5fed67, 0xfe8a9d40, 0x7b530b9d, - 0xb53fc120, 0x30e657fd, 0x68e02480, 0xed39b25d, 0x235578e0, - 0xa68cee3d}, - {0x00000000, 0x76e10f9d, 0xadc46ee1, 0xdb25617c, 0x1b8fac19, - 0x6d6ea384, 0xb64bc2f8, 0xc0aacd65, 0x361e5933, 0x40ff56ae, - 0x9bda37d2, 0xed3b384f, 0x2d91f52a, 0x5b70fab7, 0x80559bcb, - 0xf6b49456, 0x6c3cb266, 0x1addbdfb, 0xc1f8dc87, 0xb719d31a, - 0x77b31e7f, 0x015211e2, 0xda77709e, 0xac967f03, 0x5a22eb55, - 0x2cc3e4c8, 0xf7e685b4, 0x81078a29, 0x41ad474c, 0x374c48d1, - 0xec6929ad, 0x9a882630, 0xd87864cd, 0xae996b50, 0x75bc0a2c, - 0x035d05b1, 0xc3f7c8d4, 0xb516c749, 0x6e33a635, 0x18d2a9a8, - 0xee663dfe, 0x98873263, 0x43a2531f, 0x35435c82, 0xf5e991e7, - 0x83089e7a, 0x582dff06, 0x2eccf09b, 0xb444d6ab, 0xc2a5d936, - 0x1980b84a, 0x6f61b7d7, 0xafcb7ab2, 0xd92a752f, 0x020f1453, - 0x74ee1bce, 0x825a8f98, 0xf4bb8005, 0x2f9ee179, 0x597feee4, - 0x99d52381, 0xef342c1c, 0x34114d60, 0x42f042fd, 0xf1f7b941, - 0x8716b6dc, 0x5c33d7a0, 0x2ad2d83d, 0xea781558, 0x9c991ac5, - 0x47bc7bb9, 0x315d7424, 0xc7e9e072, 0xb108efef, 0x6a2d8e93, - 0x1ccc810e, 0xdc664c6b, 0xaa8743f6, 0x71a2228a, 0x07432d17, - 0x9dcb0b27, 0xeb2a04ba, 0x300f65c6, 0x46ee6a5b, 0x8644a73e, - 0xf0a5a8a3, 0x2b80c9df, 0x5d61c642, 0xabd55214, 0xdd345d89, - 0x06113cf5, 0x70f03368, 0xb05afe0d, 0xc6bbf190, 0x1d9e90ec, - 0x6b7f9f71, 0x298fdd8c, 0x5f6ed211, 0x844bb36d, 0xf2aabcf0, - 0x32007195, 0x44e17e08, 0x9fc41f74, 0xe92510e9, 0x1f9184bf, - 0x69708b22, 0xb255ea5e, 0xc4b4e5c3, 0x041e28a6, 0x72ff273b, - 0xa9da4647, 0xdf3b49da, 0x45b36fea, 0x33526077, 0xe877010b, - 0x9e960e96, 0x5e3cc3f3, 0x28ddcc6e, 0xf3f8ad12, 0x8519a28f, - 0x73ad36d9, 0x054c3944, 0xde695838, 0xa88857a5, 0x68229ac0, - 0x1ec3955d, 0xc5e6f421, 0xb307fbbc, 0xe2ef7383, 0x940e7c1e, - 0x4f2b1d62, 0x39ca12ff, 0xf960df9a, 0x8f81d007, 0x54a4b17b, - 0x2245bee6, 0xd4f12ab0, 0xa210252d, 0x79354451, 0x0fd44bcc, - 0xcf7e86a9, 0xb99f8934, 0x62bae848, 0x145be7d5, 0x8ed3c1e5, - 0xf832ce78, 0x2317af04, 0x55f6a099, 0x955c6dfc, 0xe3bd6261, - 0x3898031d, 0x4e790c80, 0xb8cd98d6, 0xce2c974b, 0x1509f637, - 0x63e8f9aa, 0xa34234cf, 0xd5a33b52, 0x0e865a2e, 0x786755b3, - 0x3a97174e, 0x4c7618d3, 0x975379af, 0xe1b27632, 0x2118bb57, - 0x57f9b4ca, 0x8cdcd5b6, 0xfa3dda2b, 0x0c894e7d, 0x7a6841e0, - 0xa14d209c, 0xd7ac2f01, 0x1706e264, 0x61e7edf9, 0xbac28c85, - 0xcc238318, 0x56aba528, 0x204aaab5, 0xfb6fcbc9, 0x8d8ec454, - 0x4d240931, 0x3bc506ac, 0xe0e067d0, 0x9601684d, 0x60b5fc1b, - 0x1654f386, 0xcd7192fa, 0xbb909d67, 0x7b3a5002, 0x0ddb5f9f, - 0xd6fe3ee3, 0xa01f317e, 0x1318cac2, 0x65f9c55f, 0xbedca423, - 0xc83dabbe, 0x089766db, 0x7e766946, 0xa553083a, 0xd3b207a7, - 0x250693f1, 0x53e79c6c, 0x88c2fd10, 0xfe23f28d, 0x3e893fe8, - 0x48683075, 0x934d5109, 0xe5ac5e94, 0x7f2478a4, 0x09c57739, - 0xd2e01645, 0xa40119d8, 0x64abd4bd, 0x124adb20, 0xc96fba5c, - 0xbf8eb5c1, 0x493a2197, 0x3fdb2e0a, 0xe4fe4f76, 0x921f40eb, - 0x52b58d8e, 0x24548213, 0xff71e36f, 0x8990ecf2, 0xcb60ae0f, - 0xbd81a192, 0x66a4c0ee, 0x1045cf73, 0xd0ef0216, 0xa60e0d8b, - 0x7d2b6cf7, 0x0bca636a, 0xfd7ef73c, 0x8b9ff8a1, 0x50ba99dd, - 0x265b9640, 0xe6f15b25, 0x901054b8, 0x4b3535c4, 0x3dd43a59, - 0xa75c1c69, 0xd1bd13f4, 0x0a987288, 0x7c797d15, 0xbcd3b070, - 0xca32bfed, 0x1117de91, 0x67f6d10c, 0x9142455a, 0xe7a34ac7, - 0x3c862bbb, 0x4a672426, 0x8acde943, 0xfc2ce6de, 0x270987a2, - 0x51e8883f}, - {0x00000000, 0xe8dbfbb9, 0x91b186a8, 0x796a7d11, 0x63657c8a, - 0x8bbe8733, 0xf2d4fa22, 0x1a0f019b, 0x87cc89cf, 0x6f177276, - 0x167d0f67, 0xfea6f4de, 0xe4a9f545, 0x0c720efc, 0x751873ed, - 0x9dc38854, 0x4f9f6244, 0xa74499fd, 0xde2ee4ec, 0x36f51f55, - 0x2cfa1ece, 0xc421e577, 0xbd4b9866, 0x559063df, 0xc853eb8b, - 0x20881032, 0x59e26d23, 0xb139969a, 0xab369701, 0x43ed6cb8, - 0x3a8711a9, 0xd25cea10, 0x9e3ec588, 0x76e53e31, 0x0f8f4320, - 0xe754b899, 0xfd5bb902, 0x158042bb, 0x6cea3faa, 0x8431c413, - 0x19f24c47, 0xf129b7fe, 0x8843caef, 0x60983156, 0x7a9730cd, - 0x924ccb74, 0xeb26b665, 0x03fd4ddc, 0xd1a1a7cc, 0x397a5c75, - 0x40102164, 0xa8cbdadd, 0xb2c4db46, 0x5a1f20ff, 0x23755dee, - 0xcbaea657, 0x566d2e03, 0xbeb6d5ba, 0xc7dca8ab, 0x2f075312, - 0x35085289, 0xddd3a930, 0xa4b9d421, 0x4c622f98, 0x7d7bfbca, - 0x95a00073, 0xecca7d62, 0x041186db, 0x1e1e8740, 0xf6c57cf9, - 0x8faf01e8, 0x6774fa51, 0xfab77205, 0x126c89bc, 0x6b06f4ad, - 0x83dd0f14, 0x99d20e8f, 0x7109f536, 0x08638827, 0xe0b8739e, - 0x32e4998e, 0xda3f6237, 0xa3551f26, 0x4b8ee49f, 0x5181e504, - 0xb95a1ebd, 0xc03063ac, 0x28eb9815, 0xb5281041, 0x5df3ebf8, - 0x249996e9, 0xcc426d50, 0xd64d6ccb, 0x3e969772, 0x47fcea63, - 0xaf2711da, 0xe3453e42, 0x0b9ec5fb, 0x72f4b8ea, 0x9a2f4353, - 0x802042c8, 0x68fbb971, 0x1191c460, 0xf94a3fd9, 0x6489b78d, - 0x8c524c34, 0xf5383125, 0x1de3ca9c, 0x07eccb07, 0xef3730be, - 0x965d4daf, 0x7e86b616, 0xacda5c06, 0x4401a7bf, 0x3d6bdaae, - 0xd5b02117, 0xcfbf208c, 0x2764db35, 0x5e0ea624, 0xb6d55d9d, - 0x2b16d5c9, 0xc3cd2e70, 0xbaa75361, 0x527ca8d8, 0x4873a943, - 0xa0a852fa, 0xd9c22feb, 0x3119d452, 0xbbf0874e, 0x532b7cf7, - 0x2a4101e6, 0xc29afa5f, 0xd895fbc4, 0x304e007d, 0x49247d6c, - 0xa1ff86d5, 0x3c3c0e81, 0xd4e7f538, 0xad8d8829, 0x45567390, - 0x5f59720b, 0xb78289b2, 0xcee8f4a3, 0x26330f1a, 0xf46fe50a, - 0x1cb41eb3, 0x65de63a2, 0x8d05981b, 0x970a9980, 0x7fd16239, - 0x06bb1f28, 0xee60e491, 0x73a36cc5, 0x9b78977c, 0xe212ea6d, - 0x0ac911d4, 0x10c6104f, 0xf81debf6, 0x817796e7, 0x69ac6d5e, - 0x25ce42c6, 0xcd15b97f, 0xb47fc46e, 0x5ca43fd7, 0x46ab3e4c, - 0xae70c5f5, 0xd71ab8e4, 0x3fc1435d, 0xa202cb09, 0x4ad930b0, - 0x33b34da1, 0xdb68b618, 0xc167b783, 0x29bc4c3a, 0x50d6312b, - 0xb80dca92, 0x6a512082, 0x828adb3b, 0xfbe0a62a, 0x133b5d93, - 0x09345c08, 0xe1efa7b1, 0x9885daa0, 0x705e2119, 0xed9da94d, - 0x054652f4, 0x7c2c2fe5, 0x94f7d45c, 0x8ef8d5c7, 0x66232e7e, - 0x1f49536f, 0xf792a8d6, 0xc68b7c84, 0x2e50873d, 0x573afa2c, - 0xbfe10195, 0xa5ee000e, 0x4d35fbb7, 0x345f86a6, 0xdc847d1f, - 0x4147f54b, 0xa99c0ef2, 0xd0f673e3, 0x382d885a, 0x222289c1, - 0xcaf97278, 0xb3930f69, 0x5b48f4d0, 0x89141ec0, 0x61cfe579, - 0x18a59868, 0xf07e63d1, 0xea71624a, 0x02aa99f3, 0x7bc0e4e2, - 0x931b1f5b, 0x0ed8970f, 0xe6036cb6, 0x9f6911a7, 0x77b2ea1e, - 0x6dbdeb85, 0x8566103c, 0xfc0c6d2d, 0x14d79694, 0x58b5b90c, - 0xb06e42b5, 0xc9043fa4, 0x21dfc41d, 0x3bd0c586, 0xd30b3e3f, - 0xaa61432e, 0x42bab897, 0xdf7930c3, 0x37a2cb7a, 0x4ec8b66b, - 0xa6134dd2, 0xbc1c4c49, 0x54c7b7f0, 0x2dadcae1, 0xc5763158, - 0x172adb48, 0xfff120f1, 0x869b5de0, 0x6e40a659, 0x744fa7c2, - 0x9c945c7b, 0xe5fe216a, 0x0d25dad3, 0x90e65287, 0x783da93e, - 0x0157d42f, 0xe98c2f96, 0xf3832e0d, 0x1b58d5b4, 0x6232a8a5, - 0x8ae9531c}, - {0x00000000, 0x919168ae, 0x6325a087, 0xf2b4c829, 0x874c31d4, - 0x16dd597a, 0xe4699153, 0x75f8f9fd, 0x4f9f1373, 0xde0e7bdd, - 0x2cbab3f4, 0xbd2bdb5a, 0xc8d322a7, 0x59424a09, 0xabf68220, - 0x3a67ea8e, 0x9e3e27e6, 0x0faf4f48, 0xfd1b8761, 0x6c8aefcf, - 0x19721632, 0x88e37e9c, 0x7a57b6b5, 0xebc6de1b, 0xd1a13495, - 0x40305c3b, 0xb2849412, 0x2315fcbc, 0x56ed0541, 0xc77c6def, - 0x35c8a5c6, 0xa459cd68, 0x7d7b3f17, 0xecea57b9, 0x1e5e9f90, - 0x8fcff73e, 0xfa370ec3, 0x6ba6666d, 0x9912ae44, 0x0883c6ea, - 0x32e42c64, 0xa37544ca, 0x51c18ce3, 0xc050e44d, 0xb5a81db0, - 0x2439751e, 0xd68dbd37, 0x471cd599, 0xe34518f1, 0x72d4705f, - 0x8060b876, 0x11f1d0d8, 0x64092925, 0xf598418b, 0x072c89a2, - 0x96bde10c, 0xacda0b82, 0x3d4b632c, 0xcfffab05, 0x5e6ec3ab, - 0x2b963a56, 0xba0752f8, 0x48b39ad1, 0xd922f27f, 0xfaf67e2e, - 0x6b671680, 0x99d3dea9, 0x0842b607, 0x7dba4ffa, 0xec2b2754, - 0x1e9fef7d, 0x8f0e87d3, 0xb5696d5d, 0x24f805f3, 0xd64ccdda, - 0x47dda574, 0x32255c89, 0xa3b43427, 0x5100fc0e, 0xc09194a0, - 0x64c859c8, 0xf5593166, 0x07edf94f, 0x967c91e1, 0xe384681c, - 0x721500b2, 0x80a1c89b, 0x1130a035, 0x2b574abb, 0xbac62215, - 0x4872ea3c, 0xd9e38292, 0xac1b7b6f, 0x3d8a13c1, 0xcf3edbe8, - 0x5eafb346, 0x878d4139, 0x161c2997, 0xe4a8e1be, 0x75398910, - 0x00c170ed, 0x91501843, 0x63e4d06a, 0xf275b8c4, 0xc812524a, - 0x59833ae4, 0xab37f2cd, 0x3aa69a63, 0x4f5e639e, 0xdecf0b30, - 0x2c7bc319, 0xbdeaabb7, 0x19b366df, 0x88220e71, 0x7a96c658, - 0xeb07aef6, 0x9eff570b, 0x0f6e3fa5, 0xfddaf78c, 0x6c4b9f22, - 0x562c75ac, 0xc7bd1d02, 0x3509d52b, 0xa498bd85, 0xd1604478, - 0x40f12cd6, 0xb245e4ff, 0x23d48c51, 0xf4edfd5c, 0x657c95f2, - 0x97c85ddb, 0x06593575, 0x73a1cc88, 0xe230a426, 0x10846c0f, - 0x811504a1, 0xbb72ee2f, 0x2ae38681, 0xd8574ea8, 0x49c62606, - 0x3c3edffb, 0xadafb755, 0x5f1b7f7c, 0xce8a17d2, 0x6ad3daba, - 0xfb42b214, 0x09f67a3d, 0x98671293, 0xed9feb6e, 0x7c0e83c0, - 0x8eba4be9, 0x1f2b2347, 0x254cc9c9, 0xb4dda167, 0x4669694e, - 0xd7f801e0, 0xa200f81d, 0x339190b3, 0xc125589a, 0x50b43034, - 0x8996c24b, 0x1807aae5, 0xeab362cc, 0x7b220a62, 0x0edaf39f, - 0x9f4b9b31, 0x6dff5318, 0xfc6e3bb6, 0xc609d138, 0x5798b996, - 0xa52c71bf, 0x34bd1911, 0x4145e0ec, 0xd0d48842, 0x2260406b, - 0xb3f128c5, 0x17a8e5ad, 0x86398d03, 0x748d452a, 0xe51c2d84, - 0x90e4d479, 0x0175bcd7, 0xf3c174fe, 0x62501c50, 0x5837f6de, - 0xc9a69e70, 0x3b125659, 0xaa833ef7, 0xdf7bc70a, 0x4eeaafa4, - 0xbc5e678d, 0x2dcf0f23, 0x0e1b8372, 0x9f8aebdc, 0x6d3e23f5, - 0xfcaf4b5b, 0x8957b2a6, 0x18c6da08, 0xea721221, 0x7be37a8f, - 0x41849001, 0xd015f8af, 0x22a13086, 0xb3305828, 0xc6c8a1d5, - 0x5759c97b, 0xa5ed0152, 0x347c69fc, 0x9025a494, 0x01b4cc3a, - 0xf3000413, 0x62916cbd, 0x17699540, 0x86f8fdee, 0x744c35c7, - 0xe5dd5d69, 0xdfbab7e7, 0x4e2bdf49, 0xbc9f1760, 0x2d0e7fce, - 0x58f68633, 0xc967ee9d, 0x3bd326b4, 0xaa424e1a, 0x7360bc65, - 0xe2f1d4cb, 0x10451ce2, 0x81d4744c, 0xf42c8db1, 0x65bde51f, - 0x97092d36, 0x06984598, 0x3cffaf16, 0xad6ec7b8, 0x5fda0f91, - 0xce4b673f, 0xbbb39ec2, 0x2a22f66c, 0xd8963e45, 0x490756eb, - 0xed5e9b83, 0x7ccff32d, 0x8e7b3b04, 0x1fea53aa, 0x6a12aa57, - 0xfb83c2f9, 0x09370ad0, 0x98a6627e, 0xa2c188f0, 0x3350e05e, - 0xc1e42877, 0x507540d9, 0x258db924, 0xb41cd18a, 0x46a819a3, - 0xd739710d}}; - -#endif - -#endif - -#if N == 5 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xaf449247, 0x85f822cf, 0x2abcb088, 0xd08143df, - 0x7fc5d198, 0x55796110, 0xfa3df357, 0x7a7381ff, 0xd53713b8, - 0xff8ba330, 0x50cf3177, 0xaaf2c220, 0x05b65067, 0x2f0ae0ef, - 0x804e72a8, 0xf4e703fe, 0x5ba391b9, 0x711f2131, 0xde5bb376, - 0x24664021, 0x8b22d266, 0xa19e62ee, 0x0edaf0a9, 0x8e948201, - 0x21d01046, 0x0b6ca0ce, 0xa4283289, 0x5e15c1de, 0xf1515399, - 0xdbede311, 0x74a97156, 0x32bf01bd, 0x9dfb93fa, 0xb7472372, - 0x1803b135, 0xe23e4262, 0x4d7ad025, 0x67c660ad, 0xc882f2ea, - 0x48cc8042, 0xe7881205, 0xcd34a28d, 0x627030ca, 0x984dc39d, - 0x370951da, 0x1db5e152, 0xb2f17315, 0xc6580243, 0x691c9004, - 0x43a0208c, 0xece4b2cb, 0x16d9419c, 0xb99dd3db, 0x93216353, - 0x3c65f114, 0xbc2b83bc, 0x136f11fb, 0x39d3a173, 0x96973334, - 0x6caac063, 0xc3ee5224, 0xe952e2ac, 0x461670eb, 0x657e037a, - 0xca3a913d, 0xe08621b5, 0x4fc2b3f2, 0xb5ff40a5, 0x1abbd2e2, - 0x3007626a, 0x9f43f02d, 0x1f0d8285, 0xb04910c2, 0x9af5a04a, - 0x35b1320d, 0xcf8cc15a, 0x60c8531d, 0x4a74e395, 0xe53071d2, - 0x91990084, 0x3edd92c3, 0x1461224b, 0xbb25b00c, 0x4118435b, - 0xee5cd11c, 0xc4e06194, 0x6ba4f3d3, 0xebea817b, 0x44ae133c, - 0x6e12a3b4, 0xc15631f3, 0x3b6bc2a4, 0x942f50e3, 0xbe93e06b, - 0x11d7722c, 0x57c102c7, 0xf8859080, 0xd2392008, 0x7d7db24f, - 0x87404118, 0x2804d35f, 0x02b863d7, 0xadfcf190, 0x2db28338, - 0x82f6117f, 0xa84aa1f7, 0x070e33b0, 0xfd33c0e7, 0x527752a0, - 0x78cbe228, 0xd78f706f, 0xa3260139, 0x0c62937e, 0x26de23f6, - 0x899ab1b1, 0x73a742e6, 0xdce3d0a1, 0xf65f6029, 0x591bf26e, - 0xd95580c6, 0x76111281, 0x5cada209, 0xf3e9304e, 0x09d4c319, - 0xa690515e, 0x8c2ce1d6, 0x23687391, 0xcafc06f4, 0x65b894b3, - 0x4f04243b, 0xe040b67c, 0x1a7d452b, 0xb539d76c, 0x9f8567e4, - 0x30c1f5a3, 0xb08f870b, 0x1fcb154c, 0x3577a5c4, 0x9a333783, - 0x600ec4d4, 0xcf4a5693, 0xe5f6e61b, 0x4ab2745c, 0x3e1b050a, - 0x915f974d, 0xbbe327c5, 0x14a7b582, 0xee9a46d5, 0x41ded492, - 0x6b62641a, 0xc426f65d, 0x446884f5, 0xeb2c16b2, 0xc190a63a, - 0x6ed4347d, 0x94e9c72a, 0x3bad556d, 0x1111e5e5, 0xbe5577a2, - 0xf8430749, 0x5707950e, 0x7dbb2586, 0xd2ffb7c1, 0x28c24496, - 0x8786d6d1, 0xad3a6659, 0x027ef41e, 0x823086b6, 0x2d7414f1, - 0x07c8a479, 0xa88c363e, 0x52b1c569, 0xfdf5572e, 0xd749e7a6, - 0x780d75e1, 0x0ca404b7, 0xa3e096f0, 0x895c2678, 0x2618b43f, - 0xdc254768, 0x7361d52f, 0x59dd65a7, 0xf699f7e0, 0x76d78548, - 0xd993170f, 0xf32fa787, 0x5c6b35c0, 0xa656c697, 0x091254d0, - 0x23aee458, 0x8cea761f, 0xaf82058e, 0x00c697c9, 0x2a7a2741, - 0x853eb506, 0x7f034651, 0xd047d416, 0xfafb649e, 0x55bff6d9, - 0xd5f18471, 0x7ab51636, 0x5009a6be, 0xff4d34f9, 0x0570c7ae, - 0xaa3455e9, 0x8088e561, 0x2fcc7726, 0x5b650670, 0xf4219437, - 0xde9d24bf, 0x71d9b6f8, 0x8be445af, 0x24a0d7e8, 0x0e1c6760, - 0xa158f527, 0x2116878f, 0x8e5215c8, 0xa4eea540, 0x0baa3707, - 0xf197c450, 0x5ed35617, 0x746fe69f, 0xdb2b74d8, 0x9d3d0433, - 0x32799674, 0x18c526fc, 0xb781b4bb, 0x4dbc47ec, 0xe2f8d5ab, - 0xc8446523, 0x6700f764, 0xe74e85cc, 0x480a178b, 0x62b6a703, - 0xcdf23544, 0x37cfc613, 0x988b5454, 0xb237e4dc, 0x1d73769b, - 0x69da07cd, 0xc69e958a, 0xec222502, 0x4366b745, 0xb95b4412, - 0x161fd655, 0x3ca366dd, 0x93e7f49a, 0x13a98632, 0xbced1475, - 0x9651a4fd, 0x391536ba, 0xc328c5ed, 0x6c6c57aa, 0x46d0e722, - 0xe9947565}, - {0x00000000, 0x4e890ba9, 0x9d121752, 0xd39b1cfb, 0xe15528e5, - 0xafdc234c, 0x7c473fb7, 0x32ce341e, 0x19db578b, 0x57525c22, - 0x84c940d9, 0xca404b70, 0xf88e7f6e, 0xb60774c7, 0x659c683c, - 0x2b156395, 0x33b6af16, 0x7d3fa4bf, 0xaea4b844, 0xe02db3ed, - 0xd2e387f3, 0x9c6a8c5a, 0x4ff190a1, 0x01789b08, 0x2a6df89d, - 0x64e4f334, 0xb77fefcf, 0xf9f6e466, 0xcb38d078, 0x85b1dbd1, - 0x562ac72a, 0x18a3cc83, 0x676d5e2c, 0x29e45585, 0xfa7f497e, - 0xb4f642d7, 0x863876c9, 0xc8b17d60, 0x1b2a619b, 0x55a36a32, - 0x7eb609a7, 0x303f020e, 0xe3a41ef5, 0xad2d155c, 0x9fe32142, - 0xd16a2aeb, 0x02f13610, 0x4c783db9, 0x54dbf13a, 0x1a52fa93, - 0xc9c9e668, 0x8740edc1, 0xb58ed9df, 0xfb07d276, 0x289cce8d, - 0x6615c524, 0x4d00a6b1, 0x0389ad18, 0xd012b1e3, 0x9e9bba4a, - 0xac558e54, 0xe2dc85fd, 0x31479906, 0x7fce92af, 0xcedabc58, - 0x8053b7f1, 0x53c8ab0a, 0x1d41a0a3, 0x2f8f94bd, 0x61069f14, - 0xb29d83ef, 0xfc148846, 0xd701ebd3, 0x9988e07a, 0x4a13fc81, - 0x049af728, 0x3654c336, 0x78ddc89f, 0xab46d464, 0xe5cfdfcd, - 0xfd6c134e, 0xb3e518e7, 0x607e041c, 0x2ef70fb5, 0x1c393bab, - 0x52b03002, 0x812b2cf9, 0xcfa22750, 0xe4b744c5, 0xaa3e4f6c, - 0x79a55397, 0x372c583e, 0x05e26c20, 0x4b6b6789, 0x98f07b72, - 0xd67970db, 0xa9b7e274, 0xe73ee9dd, 0x34a5f526, 0x7a2cfe8f, - 0x48e2ca91, 0x066bc138, 0xd5f0ddc3, 0x9b79d66a, 0xb06cb5ff, - 0xfee5be56, 0x2d7ea2ad, 0x63f7a904, 0x51399d1a, 0x1fb096b3, - 0xcc2b8a48, 0x82a281e1, 0x9a014d62, 0xd48846cb, 0x07135a30, - 0x499a5199, 0x7b546587, 0x35dd6e2e, 0xe64672d5, 0xa8cf797c, - 0x83da1ae9, 0xcd531140, 0x1ec80dbb, 0x50410612, 0x628f320c, - 0x2c0639a5, 0xff9d255e, 0xb1142ef7, 0x46c47ef1, 0x084d7558, - 0xdbd669a3, 0x955f620a, 0xa7915614, 0xe9185dbd, 0x3a834146, - 0x740a4aef, 0x5f1f297a, 0x119622d3, 0xc20d3e28, 0x8c843581, - 0xbe4a019f, 0xf0c30a36, 0x235816cd, 0x6dd11d64, 0x7572d1e7, - 0x3bfbda4e, 0xe860c6b5, 0xa6e9cd1c, 0x9427f902, 0xdaaef2ab, - 0x0935ee50, 0x47bce5f9, 0x6ca9866c, 0x22208dc5, 0xf1bb913e, - 0xbf329a97, 0x8dfcae89, 0xc375a520, 0x10eeb9db, 0x5e67b272, - 0x21a920dd, 0x6f202b74, 0xbcbb378f, 0xf2323c26, 0xc0fc0838, - 0x8e750391, 0x5dee1f6a, 0x136714c3, 0x38727756, 0x76fb7cff, - 0xa5606004, 0xebe96bad, 0xd9275fb3, 0x97ae541a, 0x443548e1, - 0x0abc4348, 0x121f8fcb, 0x5c968462, 0x8f0d9899, 0xc1849330, - 0xf34aa72e, 0xbdc3ac87, 0x6e58b07c, 0x20d1bbd5, 0x0bc4d840, - 0x454dd3e9, 0x96d6cf12, 0xd85fc4bb, 0xea91f0a5, 0xa418fb0c, - 0x7783e7f7, 0x390aec5e, 0x881ec2a9, 0xc697c900, 0x150cd5fb, - 0x5b85de52, 0x694bea4c, 0x27c2e1e5, 0xf459fd1e, 0xbad0f6b7, - 0x91c59522, 0xdf4c9e8b, 0x0cd78270, 0x425e89d9, 0x7090bdc7, - 0x3e19b66e, 0xed82aa95, 0xa30ba13c, 0xbba86dbf, 0xf5216616, - 0x26ba7aed, 0x68337144, 0x5afd455a, 0x14744ef3, 0xc7ef5208, - 0x896659a1, 0xa2733a34, 0xecfa319d, 0x3f612d66, 0x71e826cf, - 0x432612d1, 0x0daf1978, 0xde340583, 0x90bd0e2a, 0xef739c85, - 0xa1fa972c, 0x72618bd7, 0x3ce8807e, 0x0e26b460, 0x40afbfc9, - 0x9334a332, 0xddbda89b, 0xf6a8cb0e, 0xb821c0a7, 0x6bbadc5c, - 0x2533d7f5, 0x17fde3eb, 0x5974e842, 0x8aeff4b9, 0xc466ff10, - 0xdcc53393, 0x924c383a, 0x41d724c1, 0x0f5e2f68, 0x3d901b76, - 0x731910df, 0xa0820c24, 0xee0b078d, 0xc51e6418, 0x8b976fb1, - 0x580c734a, 0x168578e3, 0x244b4cfd, 0x6ac24754, 0xb9595baf, - 0xf7d05006}, - {0x00000000, 0x8d88fde2, 0xc060fd85, 0x4de80067, 0x5bb0fd4b, - 0xd63800a9, 0x9bd000ce, 0x1658fd2c, 0xb761fa96, 0x3ae90774, - 0x77010713, 0xfa89faf1, 0xecd107dd, 0x6159fa3f, 0x2cb1fa58, - 0xa13907ba, 0xb5b2f36d, 0x383a0e8f, 0x75d20ee8, 0xf85af30a, - 0xee020e26, 0x638af3c4, 0x2e62f3a3, 0xa3ea0e41, 0x02d309fb, - 0x8f5bf419, 0xc2b3f47e, 0x4f3b099c, 0x5963f4b0, 0xd4eb0952, - 0x99030935, 0x148bf4d7, 0xb014e09b, 0x3d9c1d79, 0x70741d1e, - 0xfdfce0fc, 0xeba41dd0, 0x662ce032, 0x2bc4e055, 0xa64c1db7, - 0x07751a0d, 0x8afde7ef, 0xc715e788, 0x4a9d1a6a, 0x5cc5e746, - 0xd14d1aa4, 0x9ca51ac3, 0x112de721, 0x05a613f6, 0x882eee14, - 0xc5c6ee73, 0x484e1391, 0x5e16eebd, 0xd39e135f, 0x9e761338, - 0x13feeeda, 0xb2c7e960, 0x3f4f1482, 0x72a714e5, 0xff2fe907, - 0xe977142b, 0x64ffe9c9, 0x2917e9ae, 0xa49f144c, 0xbb58c777, - 0x36d03a95, 0x7b383af2, 0xf6b0c710, 0xe0e83a3c, 0x6d60c7de, - 0x2088c7b9, 0xad003a5b, 0x0c393de1, 0x81b1c003, 0xcc59c064, - 0x41d13d86, 0x5789c0aa, 0xda013d48, 0x97e93d2f, 0x1a61c0cd, - 0x0eea341a, 0x8362c9f8, 0xce8ac99f, 0x4302347d, 0x555ac951, - 0xd8d234b3, 0x953a34d4, 0x18b2c936, 0xb98bce8c, 0x3403336e, - 0x79eb3309, 0xf463ceeb, 0xe23b33c7, 0x6fb3ce25, 0x225bce42, - 0xafd333a0, 0x0b4c27ec, 0x86c4da0e, 0xcb2cda69, 0x46a4278b, - 0x50fcdaa7, 0xdd742745, 0x909c2722, 0x1d14dac0, 0xbc2ddd7a, - 0x31a52098, 0x7c4d20ff, 0xf1c5dd1d, 0xe79d2031, 0x6a15ddd3, - 0x27fdddb4, 0xaa752056, 0xbefed481, 0x33762963, 0x7e9e2904, - 0xf316d4e6, 0xe54e29ca, 0x68c6d428, 0x252ed44f, 0xa8a629ad, - 0x099f2e17, 0x8417d3f5, 0xc9ffd392, 0x44772e70, 0x522fd35c, - 0xdfa72ebe, 0x924f2ed9, 0x1fc7d33b, 0xadc088af, 0x2048754d, - 0x6da0752a, 0xe02888c8, 0xf67075e4, 0x7bf88806, 0x36108861, - 0xbb987583, 0x1aa17239, 0x97298fdb, 0xdac18fbc, 0x5749725e, - 0x41118f72, 0xcc997290, 0x817172f7, 0x0cf98f15, 0x18727bc2, - 0x95fa8620, 0xd8128647, 0x559a7ba5, 0x43c28689, 0xce4a7b6b, - 0x83a27b0c, 0x0e2a86ee, 0xaf138154, 0x229b7cb6, 0x6f737cd1, - 0xe2fb8133, 0xf4a37c1f, 0x792b81fd, 0x34c3819a, 0xb94b7c78, - 0x1dd46834, 0x905c95d6, 0xddb495b1, 0x503c6853, 0x4664957f, - 0xcbec689d, 0x860468fa, 0x0b8c9518, 0xaab592a2, 0x273d6f40, - 0x6ad56f27, 0xe75d92c5, 0xf1056fe9, 0x7c8d920b, 0x3165926c, - 0xbced6f8e, 0xa8669b59, 0x25ee66bb, 0x680666dc, 0xe58e9b3e, - 0xf3d66612, 0x7e5e9bf0, 0x33b69b97, 0xbe3e6675, 0x1f0761cf, - 0x928f9c2d, 0xdf679c4a, 0x52ef61a8, 0x44b79c84, 0xc93f6166, - 0x84d76101, 0x095f9ce3, 0x16984fd8, 0x9b10b23a, 0xd6f8b25d, - 0x5b704fbf, 0x4d28b293, 0xc0a04f71, 0x8d484f16, 0x00c0b2f4, - 0xa1f9b54e, 0x2c7148ac, 0x619948cb, 0xec11b529, 0xfa494805, - 0x77c1b5e7, 0x3a29b580, 0xb7a14862, 0xa32abcb5, 0x2ea24157, - 0x634a4130, 0xeec2bcd2, 0xf89a41fe, 0x7512bc1c, 0x38fabc7b, - 0xb5724199, 0x144b4623, 0x99c3bbc1, 0xd42bbba6, 0x59a34644, - 0x4ffbbb68, 0xc273468a, 0x8f9b46ed, 0x0213bb0f, 0xa68caf43, - 0x2b0452a1, 0x66ec52c6, 0xeb64af24, 0xfd3c5208, 0x70b4afea, - 0x3d5caf8d, 0xb0d4526f, 0x11ed55d5, 0x9c65a837, 0xd18da850, - 0x5c0555b2, 0x4a5da89e, 0xc7d5557c, 0x8a3d551b, 0x07b5a8f9, - 0x133e5c2e, 0x9eb6a1cc, 0xd35ea1ab, 0x5ed65c49, 0x488ea165, - 0xc5065c87, 0x88ee5ce0, 0x0566a102, 0xa45fa6b8, 0x29d75b5a, - 0x643f5b3d, 0xe9b7a6df, 0xffef5bf3, 0x7267a611, 0x3f8fa676, - 0xb2075b94}, - {0x00000000, 0x80f0171f, 0xda91287f, 0x5a613f60, 0x6e5356bf, - 0xeea341a0, 0xb4c27ec0, 0x343269df, 0xdca6ad7e, 0x5c56ba61, - 0x06378501, 0x86c7921e, 0xb2f5fbc1, 0x3205ecde, 0x6864d3be, - 0xe894c4a1, 0x623c5cbd, 0xe2cc4ba2, 0xb8ad74c2, 0x385d63dd, - 0x0c6f0a02, 0x8c9f1d1d, 0xd6fe227d, 0x560e3562, 0xbe9af1c3, - 0x3e6ae6dc, 0x640bd9bc, 0xe4fbcea3, 0xd0c9a77c, 0x5039b063, - 0x0a588f03, 0x8aa8981c, 0xc478b97a, 0x4488ae65, 0x1ee99105, - 0x9e19861a, 0xaa2befc5, 0x2adbf8da, 0x70bac7ba, 0xf04ad0a5, - 0x18de1404, 0x982e031b, 0xc24f3c7b, 0x42bf2b64, 0x768d42bb, - 0xf67d55a4, 0xac1c6ac4, 0x2cec7ddb, 0xa644e5c7, 0x26b4f2d8, - 0x7cd5cdb8, 0xfc25daa7, 0xc817b378, 0x48e7a467, 0x12869b07, - 0x92768c18, 0x7ae248b9, 0xfa125fa6, 0xa07360c6, 0x208377d9, - 0x14b11e06, 0x94410919, 0xce203679, 0x4ed02166, 0x538074b5, - 0xd37063aa, 0x89115cca, 0x09e14bd5, 0x3dd3220a, 0xbd233515, - 0xe7420a75, 0x67b21d6a, 0x8f26d9cb, 0x0fd6ced4, 0x55b7f1b4, - 0xd547e6ab, 0xe1758f74, 0x6185986b, 0x3be4a70b, 0xbb14b014, - 0x31bc2808, 0xb14c3f17, 0xeb2d0077, 0x6bdd1768, 0x5fef7eb7, - 0xdf1f69a8, 0x857e56c8, 0x058e41d7, 0xed1a8576, 0x6dea9269, - 0x378bad09, 0xb77bba16, 0x8349d3c9, 0x03b9c4d6, 0x59d8fbb6, - 0xd928eca9, 0x97f8cdcf, 0x1708dad0, 0x4d69e5b0, 0xcd99f2af, - 0xf9ab9b70, 0x795b8c6f, 0x233ab30f, 0xa3caa410, 0x4b5e60b1, - 0xcbae77ae, 0x91cf48ce, 0x113f5fd1, 0x250d360e, 0xa5fd2111, - 0xff9c1e71, 0x7f6c096e, 0xf5c49172, 0x7534866d, 0x2f55b90d, - 0xafa5ae12, 0x9b97c7cd, 0x1b67d0d2, 0x4106efb2, 0xc1f6f8ad, - 0x29623c0c, 0xa9922b13, 0xf3f31473, 0x7303036c, 0x47316ab3, - 0xc7c17dac, 0x9da042cc, 0x1d5055d3, 0xa700e96a, 0x27f0fe75, - 0x7d91c115, 0xfd61d60a, 0xc953bfd5, 0x49a3a8ca, 0x13c297aa, - 0x933280b5, 0x7ba64414, 0xfb56530b, 0xa1376c6b, 0x21c77b74, - 0x15f512ab, 0x950505b4, 0xcf643ad4, 0x4f942dcb, 0xc53cb5d7, - 0x45cca2c8, 0x1fad9da8, 0x9f5d8ab7, 0xab6fe368, 0x2b9ff477, - 0x71fecb17, 0xf10edc08, 0x199a18a9, 0x996a0fb6, 0xc30b30d6, - 0x43fb27c9, 0x77c94e16, 0xf7395909, 0xad586669, 0x2da87176, - 0x63785010, 0xe388470f, 0xb9e9786f, 0x39196f70, 0x0d2b06af, - 0x8ddb11b0, 0xd7ba2ed0, 0x574a39cf, 0xbfdefd6e, 0x3f2eea71, - 0x654fd511, 0xe5bfc20e, 0xd18dabd1, 0x517dbcce, 0x0b1c83ae, - 0x8bec94b1, 0x01440cad, 0x81b41bb2, 0xdbd524d2, 0x5b2533cd, - 0x6f175a12, 0xefe74d0d, 0xb586726d, 0x35766572, 0xdde2a1d3, - 0x5d12b6cc, 0x077389ac, 0x87839eb3, 0xb3b1f76c, 0x3341e073, - 0x6920df13, 0xe9d0c80c, 0xf4809ddf, 0x74708ac0, 0x2e11b5a0, - 0xaee1a2bf, 0x9ad3cb60, 0x1a23dc7f, 0x4042e31f, 0xc0b2f400, - 0x282630a1, 0xa8d627be, 0xf2b718de, 0x72470fc1, 0x4675661e, - 0xc6857101, 0x9ce44e61, 0x1c14597e, 0x96bcc162, 0x164cd67d, - 0x4c2de91d, 0xccddfe02, 0xf8ef97dd, 0x781f80c2, 0x227ebfa2, - 0xa28ea8bd, 0x4a1a6c1c, 0xcaea7b03, 0x908b4463, 0x107b537c, - 0x24493aa3, 0xa4b92dbc, 0xfed812dc, 0x7e2805c3, 0x30f824a5, - 0xb00833ba, 0xea690cda, 0x6a991bc5, 0x5eab721a, 0xde5b6505, - 0x843a5a65, 0x04ca4d7a, 0xec5e89db, 0x6cae9ec4, 0x36cfa1a4, - 0xb63fb6bb, 0x820ddf64, 0x02fdc87b, 0x589cf71b, 0xd86ce004, - 0x52c47818, 0xd2346f07, 0x88555067, 0x08a54778, 0x3c972ea7, - 0xbc6739b8, 0xe60606d8, 0x66f611c7, 0x8e62d566, 0x0e92c279, - 0x54f3fd19, 0xd403ea06, 0xe03183d9, 0x60c194c6, 0x3aa0aba6, - 0xba50bcb9}, - {0x00000000, 0x9570d495, 0xf190af6b, 0x64e07bfe, 0x38505897, - 0xad208c02, 0xc9c0f7fc, 0x5cb02369, 0x70a0b12e, 0xe5d065bb, - 0x81301e45, 0x1440cad0, 0x48f0e9b9, 0xdd803d2c, 0xb96046d2, - 0x2c109247, 0xe141625c, 0x7431b6c9, 0x10d1cd37, 0x85a119a2, - 0xd9113acb, 0x4c61ee5e, 0x288195a0, 0xbdf14135, 0x91e1d372, - 0x049107e7, 0x60717c19, 0xf501a88c, 0xa9b18be5, 0x3cc15f70, - 0x5821248e, 0xcd51f01b, 0x19f3c2f9, 0x8c83166c, 0xe8636d92, - 0x7d13b907, 0x21a39a6e, 0xb4d34efb, 0xd0333505, 0x4543e190, - 0x695373d7, 0xfc23a742, 0x98c3dcbc, 0x0db30829, 0x51032b40, - 0xc473ffd5, 0xa093842b, 0x35e350be, 0xf8b2a0a5, 0x6dc27430, - 0x09220fce, 0x9c52db5b, 0xc0e2f832, 0x55922ca7, 0x31725759, - 0xa40283cc, 0x8812118b, 0x1d62c51e, 0x7982bee0, 0xecf26a75, - 0xb042491c, 0x25329d89, 0x41d2e677, 0xd4a232e2, 0x33e785f2, - 0xa6975167, 0xc2772a99, 0x5707fe0c, 0x0bb7dd65, 0x9ec709f0, - 0xfa27720e, 0x6f57a69b, 0x434734dc, 0xd637e049, 0xb2d79bb7, - 0x27a74f22, 0x7b176c4b, 0xee67b8de, 0x8a87c320, 0x1ff717b5, - 0xd2a6e7ae, 0x47d6333b, 0x233648c5, 0xb6469c50, 0xeaf6bf39, - 0x7f866bac, 0x1b661052, 0x8e16c4c7, 0xa2065680, 0x37768215, - 0x5396f9eb, 0xc6e62d7e, 0x9a560e17, 0x0f26da82, 0x6bc6a17c, - 0xfeb675e9, 0x2a14470b, 0xbf64939e, 0xdb84e860, 0x4ef43cf5, - 0x12441f9c, 0x8734cb09, 0xe3d4b0f7, 0x76a46462, 0x5ab4f625, - 0xcfc422b0, 0xab24594e, 0x3e548ddb, 0x62e4aeb2, 0xf7947a27, - 0x937401d9, 0x0604d54c, 0xcb552557, 0x5e25f1c2, 0x3ac58a3c, - 0xafb55ea9, 0xf3057dc0, 0x6675a955, 0x0295d2ab, 0x97e5063e, - 0xbbf59479, 0x2e8540ec, 0x4a653b12, 0xdf15ef87, 0x83a5ccee, - 0x16d5187b, 0x72356385, 0xe745b710, 0x67cf0be4, 0xf2bfdf71, - 0x965fa48f, 0x032f701a, 0x5f9f5373, 0xcaef87e6, 0xae0ffc18, - 0x3b7f288d, 0x176fbaca, 0x821f6e5f, 0xe6ff15a1, 0x738fc134, - 0x2f3fe25d, 0xba4f36c8, 0xdeaf4d36, 0x4bdf99a3, 0x868e69b8, - 0x13febd2d, 0x771ec6d3, 0xe26e1246, 0xbede312f, 0x2baee5ba, - 0x4f4e9e44, 0xda3e4ad1, 0xf62ed896, 0x635e0c03, 0x07be77fd, - 0x92cea368, 0xce7e8001, 0x5b0e5494, 0x3fee2f6a, 0xaa9efbff, - 0x7e3cc91d, 0xeb4c1d88, 0x8fac6676, 0x1adcb2e3, 0x466c918a, - 0xd31c451f, 0xb7fc3ee1, 0x228cea74, 0x0e9c7833, 0x9becaca6, - 0xff0cd758, 0x6a7c03cd, 0x36cc20a4, 0xa3bcf431, 0xc75c8fcf, - 0x522c5b5a, 0x9f7dab41, 0x0a0d7fd4, 0x6eed042a, 0xfb9dd0bf, - 0xa72df3d6, 0x325d2743, 0x56bd5cbd, 0xc3cd8828, 0xefdd1a6f, - 0x7aadcefa, 0x1e4db504, 0x8b3d6191, 0xd78d42f8, 0x42fd966d, - 0x261ded93, 0xb36d3906, 0x54288e16, 0xc1585a83, 0xa5b8217d, - 0x30c8f5e8, 0x6c78d681, 0xf9080214, 0x9de879ea, 0x0898ad7f, - 0x24883f38, 0xb1f8ebad, 0xd5189053, 0x406844c6, 0x1cd867af, - 0x89a8b33a, 0xed48c8c4, 0x78381c51, 0xb569ec4a, 0x201938df, - 0x44f94321, 0xd18997b4, 0x8d39b4dd, 0x18496048, 0x7ca91bb6, - 0xe9d9cf23, 0xc5c95d64, 0x50b989f1, 0x3459f20f, 0xa129269a, - 0xfd9905f3, 0x68e9d166, 0x0c09aa98, 0x99797e0d, 0x4ddb4cef, - 0xd8ab987a, 0xbc4be384, 0x293b3711, 0x758b1478, 0xe0fbc0ed, - 0x841bbb13, 0x116b6f86, 0x3d7bfdc1, 0xa80b2954, 0xcceb52aa, - 0x599b863f, 0x052ba556, 0x905b71c3, 0xf4bb0a3d, 0x61cbdea8, - 0xac9a2eb3, 0x39eafa26, 0x5d0a81d8, 0xc87a554d, 0x94ca7624, - 0x01baa2b1, 0x655ad94f, 0xf02a0dda, 0xdc3a9f9d, 0x494a4b08, - 0x2daa30f6, 0xb8dae463, 0xe46ac70a, 0x711a139f, 0x15fa6861, - 0x808abcf4}, - {0x00000000, 0xcf9e17c8, 0x444d29d1, 0x8bd33e19, 0x889a53a2, - 0x4704446a, 0xccd77a73, 0x03496dbb, 0xca45a105, 0x05dbb6cd, - 0x8e0888d4, 0x41969f1c, 0x42dff2a7, 0x8d41e56f, 0x0692db76, - 0xc90cccbe, 0x4ffa444b, 0x80645383, 0x0bb76d9a, 0xc4297a52, - 0xc76017e9, 0x08fe0021, 0x832d3e38, 0x4cb329f0, 0x85bfe54e, - 0x4a21f286, 0xc1f2cc9f, 0x0e6cdb57, 0x0d25b6ec, 0xc2bba124, - 0x49689f3d, 0x86f688f5, 0x9ff48896, 0x506a9f5e, 0xdbb9a147, - 0x1427b68f, 0x176edb34, 0xd8f0ccfc, 0x5323f2e5, 0x9cbde52d, - 0x55b12993, 0x9a2f3e5b, 0x11fc0042, 0xde62178a, 0xdd2b7a31, - 0x12b56df9, 0x996653e0, 0x56f84428, 0xd00eccdd, 0x1f90db15, - 0x9443e50c, 0x5bddf2c4, 0x58949f7f, 0x970a88b7, 0x1cd9b6ae, - 0xd347a166, 0x1a4b6dd8, 0xd5d57a10, 0x5e064409, 0x919853c1, - 0x92d13e7a, 0x5d4f29b2, 0xd69c17ab, 0x19020063, 0xe498176d, - 0x2b0600a5, 0xa0d53ebc, 0x6f4b2974, 0x6c0244cf, 0xa39c5307, - 0x284f6d1e, 0xe7d17ad6, 0x2eddb668, 0xe143a1a0, 0x6a909fb9, - 0xa50e8871, 0xa647e5ca, 0x69d9f202, 0xe20acc1b, 0x2d94dbd3, - 0xab625326, 0x64fc44ee, 0xef2f7af7, 0x20b16d3f, 0x23f80084, - 0xec66174c, 0x67b52955, 0xa82b3e9d, 0x6127f223, 0xaeb9e5eb, - 0x256adbf2, 0xeaf4cc3a, 0xe9bda181, 0x2623b649, 0xadf08850, - 0x626e9f98, 0x7b6c9ffb, 0xb4f28833, 0x3f21b62a, 0xf0bfa1e2, - 0xf3f6cc59, 0x3c68db91, 0xb7bbe588, 0x7825f240, 0xb1293efe, - 0x7eb72936, 0xf564172f, 0x3afa00e7, 0x39b36d5c, 0xf62d7a94, - 0x7dfe448d, 0xb2605345, 0x3496dbb0, 0xfb08cc78, 0x70dbf261, - 0xbf45e5a9, 0xbc0c8812, 0x73929fda, 0xf841a1c3, 0x37dfb60b, - 0xfed37ab5, 0x314d6d7d, 0xba9e5364, 0x750044ac, 0x76492917, - 0xb9d73edf, 0x320400c6, 0xfd9a170e, 0x1241289b, 0xdddf3f53, - 0x560c014a, 0x99921682, 0x9adb7b39, 0x55456cf1, 0xde9652e8, - 0x11084520, 0xd804899e, 0x179a9e56, 0x9c49a04f, 0x53d7b787, - 0x509eda3c, 0x9f00cdf4, 0x14d3f3ed, 0xdb4de425, 0x5dbb6cd0, - 0x92257b18, 0x19f64501, 0xd66852c9, 0xd5213f72, 0x1abf28ba, - 0x916c16a3, 0x5ef2016b, 0x97fecdd5, 0x5860da1d, 0xd3b3e404, - 0x1c2df3cc, 0x1f649e77, 0xd0fa89bf, 0x5b29b7a6, 0x94b7a06e, - 0x8db5a00d, 0x422bb7c5, 0xc9f889dc, 0x06669e14, 0x052ff3af, - 0xcab1e467, 0x4162da7e, 0x8efccdb6, 0x47f00108, 0x886e16c0, - 0x03bd28d9, 0xcc233f11, 0xcf6a52aa, 0x00f44562, 0x8b277b7b, - 0x44b96cb3, 0xc24fe446, 0x0dd1f38e, 0x8602cd97, 0x499cda5f, - 0x4ad5b7e4, 0x854ba02c, 0x0e989e35, 0xc10689fd, 0x080a4543, - 0xc794528b, 0x4c476c92, 0x83d97b5a, 0x809016e1, 0x4f0e0129, - 0xc4dd3f30, 0x0b4328f8, 0xf6d93ff6, 0x3947283e, 0xb2941627, - 0x7d0a01ef, 0x7e436c54, 0xb1dd7b9c, 0x3a0e4585, 0xf590524d, - 0x3c9c9ef3, 0xf302893b, 0x78d1b722, 0xb74fa0ea, 0xb406cd51, - 0x7b98da99, 0xf04be480, 0x3fd5f348, 0xb9237bbd, 0x76bd6c75, - 0xfd6e526c, 0x32f045a4, 0x31b9281f, 0xfe273fd7, 0x75f401ce, - 0xba6a1606, 0x7366dab8, 0xbcf8cd70, 0x372bf369, 0xf8b5e4a1, - 0xfbfc891a, 0x34629ed2, 0xbfb1a0cb, 0x702fb703, 0x692db760, - 0xa6b3a0a8, 0x2d609eb1, 0xe2fe8979, 0xe1b7e4c2, 0x2e29f30a, - 0xa5facd13, 0x6a64dadb, 0xa3681665, 0x6cf601ad, 0xe7253fb4, - 0x28bb287c, 0x2bf245c7, 0xe46c520f, 0x6fbf6c16, 0xa0217bde, - 0x26d7f32b, 0xe949e4e3, 0x629adafa, 0xad04cd32, 0xae4da089, - 0x61d3b741, 0xea008958, 0x259e9e90, 0xec92522e, 0x230c45e6, - 0xa8df7bff, 0x67416c37, 0x6408018c, 0xab961644, 0x2045285d, - 0xefdb3f95}, - {0x00000000, 0x24825136, 0x4904a26c, 0x6d86f35a, 0x920944d8, - 0xb68b15ee, 0xdb0de6b4, 0xff8fb782, 0xff638ff1, 0xdbe1dec7, - 0xb6672d9d, 0x92e57cab, 0x6d6acb29, 0x49e89a1f, 0x246e6945, - 0x00ec3873, 0x25b619a3, 0x01344895, 0x6cb2bbcf, 0x4830eaf9, - 0xb7bf5d7b, 0x933d0c4d, 0xfebbff17, 0xda39ae21, 0xdad59652, - 0xfe57c764, 0x93d1343e, 0xb7536508, 0x48dcd28a, 0x6c5e83bc, - 0x01d870e6, 0x255a21d0, 0x4b6c3346, 0x6fee6270, 0x0268912a, - 0x26eac01c, 0xd965779e, 0xfde726a8, 0x9061d5f2, 0xb4e384c4, - 0xb40fbcb7, 0x908ded81, 0xfd0b1edb, 0xd9894fed, 0x2606f86f, - 0x0284a959, 0x6f025a03, 0x4b800b35, 0x6eda2ae5, 0x4a587bd3, - 0x27de8889, 0x035cd9bf, 0xfcd36e3d, 0xd8513f0b, 0xb5d7cc51, - 0x91559d67, 0x91b9a514, 0xb53bf422, 0xd8bd0778, 0xfc3f564e, - 0x03b0e1cc, 0x2732b0fa, 0x4ab443a0, 0x6e361296, 0x96d8668c, - 0xb25a37ba, 0xdfdcc4e0, 0xfb5e95d6, 0x04d12254, 0x20537362, - 0x4dd58038, 0x6957d10e, 0x69bbe97d, 0x4d39b84b, 0x20bf4b11, - 0x043d1a27, 0xfbb2ada5, 0xdf30fc93, 0xb2b60fc9, 0x96345eff, - 0xb36e7f2f, 0x97ec2e19, 0xfa6add43, 0xdee88c75, 0x21673bf7, - 0x05e56ac1, 0x6863999b, 0x4ce1c8ad, 0x4c0df0de, 0x688fa1e8, - 0x050952b2, 0x218b0384, 0xde04b406, 0xfa86e530, 0x9700166a, - 0xb382475c, 0xddb455ca, 0xf93604fc, 0x94b0f7a6, 0xb032a690, - 0x4fbd1112, 0x6b3f4024, 0x06b9b37e, 0x223be248, 0x22d7da3b, - 0x06558b0d, 0x6bd37857, 0x4f512961, 0xb0de9ee3, 0x945ccfd5, - 0xf9da3c8f, 0xdd586db9, 0xf8024c69, 0xdc801d5f, 0xb106ee05, - 0x9584bf33, 0x6a0b08b1, 0x4e895987, 0x230faadd, 0x078dfbeb, - 0x0761c398, 0x23e392ae, 0x4e6561f4, 0x6ae730c2, 0x95688740, - 0xb1ead676, 0xdc6c252c, 0xf8ee741a, 0xf6c1cb59, 0xd2439a6f, - 0xbfc56935, 0x9b473803, 0x64c88f81, 0x404adeb7, 0x2dcc2ded, - 0x094e7cdb, 0x09a244a8, 0x2d20159e, 0x40a6e6c4, 0x6424b7f2, - 0x9bab0070, 0xbf295146, 0xd2afa21c, 0xf62df32a, 0xd377d2fa, - 0xf7f583cc, 0x9a737096, 0xbef121a0, 0x417e9622, 0x65fcc714, - 0x087a344e, 0x2cf86578, 0x2c145d0b, 0x08960c3d, 0x6510ff67, - 0x4192ae51, 0xbe1d19d3, 0x9a9f48e5, 0xf719bbbf, 0xd39bea89, - 0xbdadf81f, 0x992fa929, 0xf4a95a73, 0xd02b0b45, 0x2fa4bcc7, - 0x0b26edf1, 0x66a01eab, 0x42224f9d, 0x42ce77ee, 0x664c26d8, - 0x0bcad582, 0x2f4884b4, 0xd0c73336, 0xf4456200, 0x99c3915a, - 0xbd41c06c, 0x981be1bc, 0xbc99b08a, 0xd11f43d0, 0xf59d12e6, - 0x0a12a564, 0x2e90f452, 0x43160708, 0x6794563e, 0x67786e4d, - 0x43fa3f7b, 0x2e7ccc21, 0x0afe9d17, 0xf5712a95, 0xd1f37ba3, - 0xbc7588f9, 0x98f7d9cf, 0x6019add5, 0x449bfce3, 0x291d0fb9, - 0x0d9f5e8f, 0xf210e90d, 0xd692b83b, 0xbb144b61, 0x9f961a57, - 0x9f7a2224, 0xbbf87312, 0xd67e8048, 0xf2fcd17e, 0x0d7366fc, - 0x29f137ca, 0x4477c490, 0x60f595a6, 0x45afb476, 0x612de540, - 0x0cab161a, 0x2829472c, 0xd7a6f0ae, 0xf324a198, 0x9ea252c2, - 0xba2003f4, 0xbacc3b87, 0x9e4e6ab1, 0xf3c899eb, 0xd74ac8dd, - 0x28c57f5f, 0x0c472e69, 0x61c1dd33, 0x45438c05, 0x2b759e93, - 0x0ff7cfa5, 0x62713cff, 0x46f36dc9, 0xb97cda4b, 0x9dfe8b7d, - 0xf0787827, 0xd4fa2911, 0xd4161162, 0xf0944054, 0x9d12b30e, - 0xb990e238, 0x461f55ba, 0x629d048c, 0x0f1bf7d6, 0x2b99a6e0, - 0x0ec38730, 0x2a41d606, 0x47c7255c, 0x6345746a, 0x9ccac3e8, - 0xb84892de, 0xd5ce6184, 0xf14c30b2, 0xf1a008c1, 0xd52259f7, - 0xb8a4aaad, 0x9c26fb9b, 0x63a94c19, 0x472b1d2f, 0x2aadee75, - 0x0e2fbf43}, - {0x00000000, 0x36f290f3, 0x6de521e6, 0x5b17b115, 0xdbca43cc, - 0xed38d33f, 0xb62f622a, 0x80ddf2d9, 0x6ce581d9, 0x5a17112a, - 0x0100a03f, 0x37f230cc, 0xb72fc215, 0x81dd52e6, 0xdacae3f3, - 0xec387300, 0xd9cb03b2, 0xef399341, 0xb42e2254, 0x82dcb2a7, - 0x0201407e, 0x34f3d08d, 0x6fe46198, 0x5916f16b, 0xb52e826b, - 0x83dc1298, 0xd8cba38d, 0xee39337e, 0x6ee4c1a7, 0x58165154, - 0x0301e041, 0x35f370b2, 0x68e70125, 0x5e1591d6, 0x050220c3, - 0x33f0b030, 0xb32d42e9, 0x85dfd21a, 0xdec8630f, 0xe83af3fc, - 0x040280fc, 0x32f0100f, 0x69e7a11a, 0x5f1531e9, 0xdfc8c330, - 0xe93a53c3, 0xb22de2d6, 0x84df7225, 0xb12c0297, 0x87de9264, - 0xdcc92371, 0xea3bb382, 0x6ae6415b, 0x5c14d1a8, 0x070360bd, - 0x31f1f04e, 0xddc9834e, 0xeb3b13bd, 0xb02ca2a8, 0x86de325b, - 0x0603c082, 0x30f15071, 0x6be6e164, 0x5d147197, 0xd1ce024a, - 0xe73c92b9, 0xbc2b23ac, 0x8ad9b35f, 0x0a044186, 0x3cf6d175, - 0x67e16060, 0x5113f093, 0xbd2b8393, 0x8bd91360, 0xd0cea275, - 0xe63c3286, 0x66e1c05f, 0x501350ac, 0x0b04e1b9, 0x3df6714a, - 0x080501f8, 0x3ef7910b, 0x65e0201e, 0x5312b0ed, 0xd3cf4234, - 0xe53dd2c7, 0xbe2a63d2, 0x88d8f321, 0x64e08021, 0x521210d2, - 0x0905a1c7, 0x3ff73134, 0xbf2ac3ed, 0x89d8531e, 0xd2cfe20b, - 0xe43d72f8, 0xb929036f, 0x8fdb939c, 0xd4cc2289, 0xe23eb27a, - 0x62e340a3, 0x5411d050, 0x0f066145, 0x39f4f1b6, 0xd5cc82b6, - 0xe33e1245, 0xb829a350, 0x8edb33a3, 0x0e06c17a, 0x38f45189, - 0x63e3e09c, 0x5511706f, 0x60e200dd, 0x5610902e, 0x0d07213b, - 0x3bf5b1c8, 0xbb284311, 0x8ddad3e2, 0xd6cd62f7, 0xe03ff204, - 0x0c078104, 0x3af511f7, 0x61e2a0e2, 0x57103011, 0xd7cdc2c8, - 0xe13f523b, 0xba28e32e, 0x8cda73dd, 0x78ed02d5, 0x4e1f9226, - 0x15082333, 0x23fab3c0, 0xa3274119, 0x95d5d1ea, 0xcec260ff, - 0xf830f00c, 0x1408830c, 0x22fa13ff, 0x79eda2ea, 0x4f1f3219, - 0xcfc2c0c0, 0xf9305033, 0xa227e126, 0x94d571d5, 0xa1260167, - 0x97d49194, 0xccc32081, 0xfa31b072, 0x7aec42ab, 0x4c1ed258, - 0x1709634d, 0x21fbf3be, 0xcdc380be, 0xfb31104d, 0xa026a158, - 0x96d431ab, 0x1609c372, 0x20fb5381, 0x7bece294, 0x4d1e7267, - 0x100a03f0, 0x26f89303, 0x7def2216, 0x4b1db2e5, 0xcbc0403c, - 0xfd32d0cf, 0xa62561da, 0x90d7f129, 0x7cef8229, 0x4a1d12da, - 0x110aa3cf, 0x27f8333c, 0xa725c1e5, 0x91d75116, 0xcac0e003, - 0xfc3270f0, 0xc9c10042, 0xff3390b1, 0xa42421a4, 0x92d6b157, - 0x120b438e, 0x24f9d37d, 0x7fee6268, 0x491cf29b, 0xa524819b, - 0x93d61168, 0xc8c1a07d, 0xfe33308e, 0x7eeec257, 0x481c52a4, - 0x130be3b1, 0x25f97342, 0xa923009f, 0x9fd1906c, 0xc4c62179, - 0xf234b18a, 0x72e94353, 0x441bd3a0, 0x1f0c62b5, 0x29fef246, - 0xc5c68146, 0xf33411b5, 0xa823a0a0, 0x9ed13053, 0x1e0cc28a, - 0x28fe5279, 0x73e9e36c, 0x451b739f, 0x70e8032d, 0x461a93de, - 0x1d0d22cb, 0x2bffb238, 0xab2240e1, 0x9dd0d012, 0xc6c76107, - 0xf035f1f4, 0x1c0d82f4, 0x2aff1207, 0x71e8a312, 0x471a33e1, - 0xc7c7c138, 0xf13551cb, 0xaa22e0de, 0x9cd0702d, 0xc1c401ba, - 0xf7369149, 0xac21205c, 0x9ad3b0af, 0x1a0e4276, 0x2cfcd285, - 0x77eb6390, 0x4119f363, 0xad218063, 0x9bd31090, 0xc0c4a185, - 0xf6363176, 0x76ebc3af, 0x4019535c, 0x1b0ee249, 0x2dfc72ba, - 0x180f0208, 0x2efd92fb, 0x75ea23ee, 0x4318b31d, 0xc3c541c4, - 0xf537d137, 0xae206022, 0x98d2f0d1, 0x74ea83d1, 0x42181322, - 0x190fa237, 0x2ffd32c4, 0xaf20c01d, 0x99d250ee, 0xc2c5e1fb, - 0xf4377108}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0xf390f23600000000, 0xe621e56d00000000, - 0x15b1175b00000000, 0xcc43cadb00000000, 0x3fd338ed00000000, - 0x2a622fb600000000, 0xd9f2dd8000000000, 0xd981e56c00000000, - 0x2a11175a00000000, 0x3fa0000100000000, 0xcc30f23700000000, - 0x15c22fb700000000, 0xe652dd8100000000, 0xf3e3cada00000000, - 0x007338ec00000000, 0xb203cbd900000000, 0x419339ef00000000, - 0x54222eb400000000, 0xa7b2dc8200000000, 0x7e40010200000000, - 0x8dd0f33400000000, 0x9861e46f00000000, 0x6bf1165900000000, - 0x6b822eb500000000, 0x9812dc8300000000, 0x8da3cbd800000000, - 0x7e3339ee00000000, 0xa7c1e46e00000000, 0x5451165800000000, - 0x41e0010300000000, 0xb270f33500000000, 0x2501e76800000000, - 0xd691155e00000000, 0xc320020500000000, 0x30b0f03300000000, - 0xe9422db300000000, 0x1ad2df8500000000, 0x0f63c8de00000000, - 0xfcf33ae800000000, 0xfc80020400000000, 0x0f10f03200000000, - 0x1aa1e76900000000, 0xe931155f00000000, 0x30c3c8df00000000, - 0xc3533ae900000000, 0xd6e22db200000000, 0x2572df8400000000, - 0x97022cb100000000, 0x6492de8700000000, 0x7123c9dc00000000, - 0x82b33bea00000000, 0x5b41e66a00000000, 0xa8d1145c00000000, - 0xbd60030700000000, 0x4ef0f13100000000, 0x4e83c9dd00000000, - 0xbd133beb00000000, 0xa8a22cb000000000, 0x5b32de8600000000, - 0x82c0030600000000, 0x7150f13000000000, 0x64e1e66b00000000, - 0x9771145d00000000, 0x4a02ced100000000, 0xb9923ce700000000, - 0xac232bbc00000000, 0x5fb3d98a00000000, 0x8641040a00000000, - 0x75d1f63c00000000, 0x6060e16700000000, 0x93f0135100000000, - 0x93832bbd00000000, 0x6013d98b00000000, 0x75a2ced000000000, - 0x86323ce600000000, 0x5fc0e16600000000, 0xac50135000000000, - 0xb9e1040b00000000, 0x4a71f63d00000000, 0xf801050800000000, - 0x0b91f73e00000000, 0x1e20e06500000000, 0xedb0125300000000, - 0x3442cfd300000000, 0xc7d23de500000000, 0xd2632abe00000000, - 0x21f3d88800000000, 0x2180e06400000000, 0xd210125200000000, - 0xc7a1050900000000, 0x3431f73f00000000, 0xedc32abf00000000, - 0x1e53d88900000000, 0x0be2cfd200000000, 0xf8723de400000000, - 0x6f0329b900000000, 0x9c93db8f00000000, 0x8922ccd400000000, - 0x7ab23ee200000000, 0xa340e36200000000, 0x50d0115400000000, - 0x4561060f00000000, 0xb6f1f43900000000, 0xb682ccd500000000, - 0x45123ee300000000, 0x50a329b800000000, 0xa333db8e00000000, - 0x7ac1060e00000000, 0x8951f43800000000, 0x9ce0e36300000000, - 0x6f70115500000000, 0xdd00e26000000000, 0x2e90105600000000, - 0x3b21070d00000000, 0xc8b1f53b00000000, 0x114328bb00000000, - 0xe2d3da8d00000000, 0xf762cdd600000000, 0x04f23fe000000000, - 0x0481070c00000000, 0xf711f53a00000000, 0xe2a0e26100000000, - 0x1130105700000000, 0xc8c2cdd700000000, 0x3b523fe100000000, - 0x2ee328ba00000000, 0xdd73da8c00000000, 0xd502ed7800000000, - 0x26921f4e00000000, 0x3323081500000000, 0xc0b3fa2300000000, - 0x194127a300000000, 0xead1d59500000000, 0xff60c2ce00000000, - 0x0cf030f800000000, 0x0c83081400000000, 0xff13fa2200000000, - 0xeaa2ed7900000000, 0x19321f4f00000000, 0xc0c0c2cf00000000, - 0x335030f900000000, 0x26e127a200000000, 0xd571d59400000000, - 0x670126a100000000, 0x9491d49700000000, 0x8120c3cc00000000, - 0x72b031fa00000000, 0xab42ec7a00000000, 0x58d21e4c00000000, - 0x4d63091700000000, 0xbef3fb2100000000, 0xbe80c3cd00000000, - 0x4d1031fb00000000, 0x58a126a000000000, 0xab31d49600000000, - 0x72c3091600000000, 0x8153fb2000000000, 0x94e2ec7b00000000, - 0x67721e4d00000000, 0xf0030a1000000000, 0x0393f82600000000, - 0x1622ef7d00000000, 0xe5b21d4b00000000, 0x3c40c0cb00000000, - 0xcfd032fd00000000, 0xda6125a600000000, 0x29f1d79000000000, - 0x2982ef7c00000000, 0xda121d4a00000000, 0xcfa30a1100000000, - 0x3c33f82700000000, 0xe5c125a700000000, 0x1651d79100000000, - 0x03e0c0ca00000000, 0xf07032fc00000000, 0x4200c1c900000000, - 0xb19033ff00000000, 0xa42124a400000000, 0x57b1d69200000000, - 0x8e430b1200000000, 0x7dd3f92400000000, 0x6862ee7f00000000, - 0x9bf21c4900000000, 0x9b8124a500000000, 0x6811d69300000000, - 0x7da0c1c800000000, 0x8e3033fe00000000, 0x57c2ee7e00000000, - 0xa4521c4800000000, 0xb1e30b1300000000, 0x4273f92500000000, - 0x9f0023a900000000, 0x6c90d19f00000000, 0x7921c6c400000000, - 0x8ab134f200000000, 0x5343e97200000000, 0xa0d31b4400000000, - 0xb5620c1f00000000, 0x46f2fe2900000000, 0x4681c6c500000000, - 0xb51134f300000000, 0xa0a023a800000000, 0x5330d19e00000000, - 0x8ac20c1e00000000, 0x7952fe2800000000, 0x6ce3e97300000000, - 0x9f731b4500000000, 0x2d03e87000000000, 0xde931a4600000000, - 0xcb220d1d00000000, 0x38b2ff2b00000000, 0xe14022ab00000000, - 0x12d0d09d00000000, 0x0761c7c600000000, 0xf4f135f000000000, - 0xf4820d1c00000000, 0x0712ff2a00000000, 0x12a3e87100000000, - 0xe1331a4700000000, 0x38c1c7c700000000, 0xcb5135f100000000, - 0xdee022aa00000000, 0x2d70d09c00000000, 0xba01c4c100000000, - 0x499136f700000000, 0x5c2021ac00000000, 0xafb0d39a00000000, - 0x76420e1a00000000, 0x85d2fc2c00000000, 0x9063eb7700000000, - 0x63f3194100000000, 0x638021ad00000000, 0x9010d39b00000000, - 0x85a1c4c000000000, 0x763136f600000000, 0xafc3eb7600000000, - 0x5c53194000000000, 0x49e20e1b00000000, 0xba72fc2d00000000, - 0x08020f1800000000, 0xfb92fd2e00000000, 0xee23ea7500000000, - 0x1db3184300000000, 0xc441c5c300000000, 0x37d137f500000000, - 0x226020ae00000000, 0xd1f0d29800000000, 0xd183ea7400000000, - 0x2213184200000000, 0x37a20f1900000000, 0xc432fd2f00000000, - 0x1dc020af00000000, 0xee50d29900000000, 0xfbe1c5c200000000, - 0x087137f400000000}, - {0x0000000000000000, 0x3651822400000000, 0x6ca2044900000000, - 0x5af3866d00000000, 0xd844099200000000, 0xee158bb600000000, - 0xb4e60ddb00000000, 0x82b78fff00000000, 0xf18f63ff00000000, - 0xc7dee1db00000000, 0x9d2d67b600000000, 0xab7ce59200000000, - 0x29cb6a6d00000000, 0x1f9ae84900000000, 0x45696e2400000000, - 0x7338ec0000000000, 0xa319b62500000000, 0x9548340100000000, - 0xcfbbb26c00000000, 0xf9ea304800000000, 0x7b5dbfb700000000, - 0x4d0c3d9300000000, 0x17ffbbfe00000000, 0x21ae39da00000000, - 0x5296d5da00000000, 0x64c757fe00000000, 0x3e34d19300000000, - 0x086553b700000000, 0x8ad2dc4800000000, 0xbc835e6c00000000, - 0xe670d80100000000, 0xd0215a2500000000, 0x46336c4b00000000, - 0x7062ee6f00000000, 0x2a91680200000000, 0x1cc0ea2600000000, - 0x9e7765d900000000, 0xa826e7fd00000000, 0xf2d5619000000000, - 0xc484e3b400000000, 0xb7bc0fb400000000, 0x81ed8d9000000000, - 0xdb1e0bfd00000000, 0xed4f89d900000000, 0x6ff8062600000000, - 0x59a9840200000000, 0x035a026f00000000, 0x350b804b00000000, - 0xe52ada6e00000000, 0xd37b584a00000000, 0x8988de2700000000, - 0xbfd95c0300000000, 0x3d6ed3fc00000000, 0x0b3f51d800000000, - 0x51ccd7b500000000, 0x679d559100000000, 0x14a5b99100000000, - 0x22f43bb500000000, 0x7807bdd800000000, 0x4e563ffc00000000, - 0xcce1b00300000000, 0xfab0322700000000, 0xa043b44a00000000, - 0x9612366e00000000, 0x8c66d89600000000, 0xba375ab200000000, - 0xe0c4dcdf00000000, 0xd6955efb00000000, 0x5422d10400000000, - 0x6273532000000000, 0x3880d54d00000000, 0x0ed1576900000000, - 0x7de9bb6900000000, 0x4bb8394d00000000, 0x114bbf2000000000, - 0x271a3d0400000000, 0xa5adb2fb00000000, 0x93fc30df00000000, - 0xc90fb6b200000000, 0xff5e349600000000, 0x2f7f6eb300000000, - 0x192eec9700000000, 0x43dd6afa00000000, 0x758ce8de00000000, - 0xf73b672100000000, 0xc16ae50500000000, 0x9b99636800000000, - 0xadc8e14c00000000, 0xdef00d4c00000000, 0xe8a18f6800000000, - 0xb252090500000000, 0x84038b2100000000, 0x06b404de00000000, - 0x30e586fa00000000, 0x6a16009700000000, 0x5c4782b300000000, - 0xca55b4dd00000000, 0xfc0436f900000000, 0xa6f7b09400000000, - 0x90a632b000000000, 0x1211bd4f00000000, 0x24403f6b00000000, - 0x7eb3b90600000000, 0x48e23b2200000000, 0x3bdad72200000000, - 0x0d8b550600000000, 0x5778d36b00000000, 0x6129514f00000000, - 0xe39edeb000000000, 0xd5cf5c9400000000, 0x8f3cdaf900000000, - 0xb96d58dd00000000, 0x694c02f800000000, 0x5f1d80dc00000000, - 0x05ee06b100000000, 0x33bf849500000000, 0xb1080b6a00000000, - 0x8759894e00000000, 0xddaa0f2300000000, 0xebfb8d0700000000, - 0x98c3610700000000, 0xae92e32300000000, 0xf461654e00000000, - 0xc230e76a00000000, 0x4087689500000000, 0x76d6eab100000000, - 0x2c256cdc00000000, 0x1a74eef800000000, 0x59cbc1f600000000, - 0x6f9a43d200000000, 0x3569c5bf00000000, 0x0338479b00000000, - 0x818fc86400000000, 0xb7de4a4000000000, 0xed2dcc2d00000000, - 0xdb7c4e0900000000, 0xa844a20900000000, 0x9e15202d00000000, - 0xc4e6a64000000000, 0xf2b7246400000000, 0x7000ab9b00000000, - 0x465129bf00000000, 0x1ca2afd200000000, 0x2af32df600000000, - 0xfad277d300000000, 0xcc83f5f700000000, 0x9670739a00000000, - 0xa021f1be00000000, 0x22967e4100000000, 0x14c7fc6500000000, - 0x4e347a0800000000, 0x7865f82c00000000, 0x0b5d142c00000000, - 0x3d0c960800000000, 0x67ff106500000000, 0x51ae924100000000, - 0xd3191dbe00000000, 0xe5489f9a00000000, 0xbfbb19f700000000, - 0x89ea9bd300000000, 0x1ff8adbd00000000, 0x29a92f9900000000, - 0x735aa9f400000000, 0x450b2bd000000000, 0xc7bca42f00000000, - 0xf1ed260b00000000, 0xab1ea06600000000, 0x9d4f224200000000, - 0xee77ce4200000000, 0xd8264c6600000000, 0x82d5ca0b00000000, - 0xb484482f00000000, 0x3633c7d000000000, 0x006245f400000000, - 0x5a91c39900000000, 0x6cc041bd00000000, 0xbce11b9800000000, - 0x8ab099bc00000000, 0xd0431fd100000000, 0xe6129df500000000, - 0x64a5120a00000000, 0x52f4902e00000000, 0x0807164300000000, - 0x3e56946700000000, 0x4d6e786700000000, 0x7b3ffa4300000000, - 0x21cc7c2e00000000, 0x179dfe0a00000000, 0x952a71f500000000, - 0xa37bf3d100000000, 0xf98875bc00000000, 0xcfd9f79800000000, - 0xd5ad196000000000, 0xe3fc9b4400000000, 0xb90f1d2900000000, - 0x8f5e9f0d00000000, 0x0de910f200000000, 0x3bb892d600000000, - 0x614b14bb00000000, 0x571a969f00000000, 0x24227a9f00000000, - 0x1273f8bb00000000, 0x48807ed600000000, 0x7ed1fcf200000000, - 0xfc66730d00000000, 0xca37f12900000000, 0x90c4774400000000, - 0xa695f56000000000, 0x76b4af4500000000, 0x40e52d6100000000, - 0x1a16ab0c00000000, 0x2c47292800000000, 0xaef0a6d700000000, - 0x98a124f300000000, 0xc252a29e00000000, 0xf40320ba00000000, - 0x873bccba00000000, 0xb16a4e9e00000000, 0xeb99c8f300000000, - 0xddc84ad700000000, 0x5f7fc52800000000, 0x692e470c00000000, - 0x33ddc16100000000, 0x058c434500000000, 0x939e752b00000000, - 0xa5cff70f00000000, 0xff3c716200000000, 0xc96df34600000000, - 0x4bda7cb900000000, 0x7d8bfe9d00000000, 0x277878f000000000, - 0x1129fad400000000, 0x621116d400000000, 0x544094f000000000, - 0x0eb3129d00000000, 0x38e290b900000000, 0xba551f4600000000, - 0x8c049d6200000000, 0xd6f71b0f00000000, 0xe0a6992b00000000, - 0x3087c30e00000000, 0x06d6412a00000000, 0x5c25c74700000000, - 0x6a74456300000000, 0xe8c3ca9c00000000, 0xde9248b800000000, - 0x8461ced500000000, 0xb2304cf100000000, 0xc108a0f100000000, - 0xf75922d500000000, 0xadaaa4b800000000, 0x9bfb269c00000000, - 0x194ca96300000000, 0x2f1d2b4700000000, 0x75eead2a00000000, - 0x43bf2f0e00000000}, - {0x0000000000000000, 0xc8179ecf00000000, 0xd1294d4400000000, - 0x193ed38b00000000, 0xa2539a8800000000, 0x6a44044700000000, - 0x737ad7cc00000000, 0xbb6d490300000000, 0x05a145ca00000000, - 0xcdb6db0500000000, 0xd488088e00000000, 0x1c9f964100000000, - 0xa7f2df4200000000, 0x6fe5418d00000000, 0x76db920600000000, - 0xbecc0cc900000000, 0x4b44fa4f00000000, 0x8353648000000000, - 0x9a6db70b00000000, 0x527a29c400000000, 0xe91760c700000000, - 0x2100fe0800000000, 0x383e2d8300000000, 0xf029b34c00000000, - 0x4ee5bf8500000000, 0x86f2214a00000000, 0x9fccf2c100000000, - 0x57db6c0e00000000, 0xecb6250d00000000, 0x24a1bbc200000000, - 0x3d9f684900000000, 0xf588f68600000000, 0x9688f49f00000000, - 0x5e9f6a5000000000, 0x47a1b9db00000000, 0x8fb6271400000000, - 0x34db6e1700000000, 0xfcccf0d800000000, 0xe5f2235300000000, - 0x2de5bd9c00000000, 0x9329b15500000000, 0x5b3e2f9a00000000, - 0x4200fc1100000000, 0x8a1762de00000000, 0x317a2bdd00000000, - 0xf96db51200000000, 0xe053669900000000, 0x2844f85600000000, - 0xddcc0ed000000000, 0x15db901f00000000, 0x0ce5439400000000, - 0xc4f2dd5b00000000, 0x7f9f945800000000, 0xb7880a9700000000, - 0xaeb6d91c00000000, 0x66a147d300000000, 0xd86d4b1a00000000, - 0x107ad5d500000000, 0x0944065e00000000, 0xc153989100000000, - 0x7a3ed19200000000, 0xb2294f5d00000000, 0xab179cd600000000, - 0x6300021900000000, 0x6d1798e400000000, 0xa500062b00000000, - 0xbc3ed5a000000000, 0x74294b6f00000000, 0xcf44026c00000000, - 0x07539ca300000000, 0x1e6d4f2800000000, 0xd67ad1e700000000, - 0x68b6dd2e00000000, 0xa0a143e100000000, 0xb99f906a00000000, - 0x71880ea500000000, 0xcae547a600000000, 0x02f2d96900000000, - 0x1bcc0ae200000000, 0xd3db942d00000000, 0x265362ab00000000, - 0xee44fc6400000000, 0xf77a2fef00000000, 0x3f6db12000000000, - 0x8400f82300000000, 0x4c1766ec00000000, 0x5529b56700000000, - 0x9d3e2ba800000000, 0x23f2276100000000, 0xebe5b9ae00000000, - 0xf2db6a2500000000, 0x3accf4ea00000000, 0x81a1bde900000000, - 0x49b6232600000000, 0x5088f0ad00000000, 0x989f6e6200000000, - 0xfb9f6c7b00000000, 0x3388f2b400000000, 0x2ab6213f00000000, - 0xe2a1bff000000000, 0x59ccf6f300000000, 0x91db683c00000000, - 0x88e5bbb700000000, 0x40f2257800000000, 0xfe3e29b100000000, - 0x3629b77e00000000, 0x2f1764f500000000, 0xe700fa3a00000000, - 0x5c6db33900000000, 0x947a2df600000000, 0x8d44fe7d00000000, - 0x455360b200000000, 0xb0db963400000000, 0x78cc08fb00000000, - 0x61f2db7000000000, 0xa9e545bf00000000, 0x12880cbc00000000, - 0xda9f927300000000, 0xc3a141f800000000, 0x0bb6df3700000000, - 0xb57ad3fe00000000, 0x7d6d4d3100000000, 0x64539eba00000000, - 0xac44007500000000, 0x1729497600000000, 0xdf3ed7b900000000, - 0xc600043200000000, 0x0e179afd00000000, 0x9b28411200000000, - 0x533fdfdd00000000, 0x4a010c5600000000, 0x8216929900000000, - 0x397bdb9a00000000, 0xf16c455500000000, 0xe85296de00000000, - 0x2045081100000000, 0x9e8904d800000000, 0x569e9a1700000000, - 0x4fa0499c00000000, 0x87b7d75300000000, 0x3cda9e5000000000, - 0xf4cd009f00000000, 0xedf3d31400000000, 0x25e44ddb00000000, - 0xd06cbb5d00000000, 0x187b259200000000, 0x0145f61900000000, - 0xc95268d600000000, 0x723f21d500000000, 0xba28bf1a00000000, - 0xa3166c9100000000, 0x6b01f25e00000000, 0xd5cdfe9700000000, - 0x1dda605800000000, 0x04e4b3d300000000, 0xccf32d1c00000000, - 0x779e641f00000000, 0xbf89fad000000000, 0xa6b7295b00000000, - 0x6ea0b79400000000, 0x0da0b58d00000000, 0xc5b72b4200000000, - 0xdc89f8c900000000, 0x149e660600000000, 0xaff32f0500000000, - 0x67e4b1ca00000000, 0x7eda624100000000, 0xb6cdfc8e00000000, - 0x0801f04700000000, 0xc0166e8800000000, 0xd928bd0300000000, - 0x113f23cc00000000, 0xaa526acf00000000, 0x6245f40000000000, - 0x7b7b278b00000000, 0xb36cb94400000000, 0x46e44fc200000000, - 0x8ef3d10d00000000, 0x97cd028600000000, 0x5fda9c4900000000, - 0xe4b7d54a00000000, 0x2ca04b8500000000, 0x359e980e00000000, - 0xfd8906c100000000, 0x43450a0800000000, 0x8b5294c700000000, - 0x926c474c00000000, 0x5a7bd98300000000, 0xe116908000000000, - 0x29010e4f00000000, 0x303fddc400000000, 0xf828430b00000000, - 0xf63fd9f600000000, 0x3e28473900000000, 0x271694b200000000, - 0xef010a7d00000000, 0x546c437e00000000, 0x9c7bddb100000000, - 0x85450e3a00000000, 0x4d5290f500000000, 0xf39e9c3c00000000, - 0x3b8902f300000000, 0x22b7d17800000000, 0xeaa04fb700000000, - 0x51cd06b400000000, 0x99da987b00000000, 0x80e44bf000000000, - 0x48f3d53f00000000, 0xbd7b23b900000000, 0x756cbd7600000000, - 0x6c526efd00000000, 0xa445f03200000000, 0x1f28b93100000000, - 0xd73f27fe00000000, 0xce01f47500000000, 0x06166aba00000000, - 0xb8da667300000000, 0x70cdf8bc00000000, 0x69f32b3700000000, - 0xa1e4b5f800000000, 0x1a89fcfb00000000, 0xd29e623400000000, - 0xcba0b1bf00000000, 0x03b72f7000000000, 0x60b72d6900000000, - 0xa8a0b3a600000000, 0xb19e602d00000000, 0x7989fee200000000, - 0xc2e4b7e100000000, 0x0af3292e00000000, 0x13cdfaa500000000, - 0xdbda646a00000000, 0x651668a300000000, 0xad01f66c00000000, - 0xb43f25e700000000, 0x7c28bb2800000000, 0xc745f22b00000000, - 0x0f526ce400000000, 0x166cbf6f00000000, 0xde7b21a000000000, - 0x2bf3d72600000000, 0xe3e449e900000000, 0xfada9a6200000000, - 0x32cd04ad00000000, 0x89a04dae00000000, 0x41b7d36100000000, - 0x588900ea00000000, 0x909e9e2500000000, 0x2e5292ec00000000, - 0xe6450c2300000000, 0xff7bdfa800000000, 0x376c416700000000, - 0x8c01086400000000, 0x441696ab00000000, 0x5d28452000000000, - 0x953fdbef00000000}, - {0x0000000000000000, 0x95d4709500000000, 0x6baf90f100000000, - 0xfe7be06400000000, 0x9758503800000000, 0x028c20ad00000000, - 0xfcf7c0c900000000, 0x6923b05c00000000, 0x2eb1a07000000000, - 0xbb65d0e500000000, 0x451e308100000000, 0xd0ca401400000000, - 0xb9e9f04800000000, 0x2c3d80dd00000000, 0xd24660b900000000, - 0x4792102c00000000, 0x5c6241e100000000, 0xc9b6317400000000, - 0x37cdd11000000000, 0xa219a18500000000, 0xcb3a11d900000000, - 0x5eee614c00000000, 0xa095812800000000, 0x3541f1bd00000000, - 0x72d3e19100000000, 0xe707910400000000, 0x197c716000000000, - 0x8ca801f500000000, 0xe58bb1a900000000, 0x705fc13c00000000, - 0x8e24215800000000, 0x1bf051cd00000000, 0xf9c2f31900000000, - 0x6c16838c00000000, 0x926d63e800000000, 0x07b9137d00000000, - 0x6e9aa32100000000, 0xfb4ed3b400000000, 0x053533d000000000, - 0x90e1434500000000, 0xd773536900000000, 0x42a723fc00000000, - 0xbcdcc39800000000, 0x2908b30d00000000, 0x402b035100000000, - 0xd5ff73c400000000, 0x2b8493a000000000, 0xbe50e33500000000, - 0xa5a0b2f800000000, 0x3074c26d00000000, 0xce0f220900000000, - 0x5bdb529c00000000, 0x32f8e2c000000000, 0xa72c925500000000, - 0x5957723100000000, 0xcc8302a400000000, 0x8b11128800000000, - 0x1ec5621d00000000, 0xe0be827900000000, 0x756af2ec00000000, - 0x1c4942b000000000, 0x899d322500000000, 0x77e6d24100000000, - 0xe232a2d400000000, 0xf285e73300000000, 0x675197a600000000, - 0x992a77c200000000, 0x0cfe075700000000, 0x65ddb70b00000000, - 0xf009c79e00000000, 0x0e7227fa00000000, 0x9ba6576f00000000, - 0xdc34474300000000, 0x49e037d600000000, 0xb79bd7b200000000, - 0x224fa72700000000, 0x4b6c177b00000000, 0xdeb867ee00000000, - 0x20c3878a00000000, 0xb517f71f00000000, 0xaee7a6d200000000, - 0x3b33d64700000000, 0xc548362300000000, 0x509c46b600000000, - 0x39bff6ea00000000, 0xac6b867f00000000, 0x5210661b00000000, - 0xc7c4168e00000000, 0x805606a200000000, 0x1582763700000000, - 0xebf9965300000000, 0x7e2de6c600000000, 0x170e569a00000000, - 0x82da260f00000000, 0x7ca1c66b00000000, 0xe975b6fe00000000, - 0x0b47142a00000000, 0x9e9364bf00000000, 0x60e884db00000000, - 0xf53cf44e00000000, 0x9c1f441200000000, 0x09cb348700000000, - 0xf7b0d4e300000000, 0x6264a47600000000, 0x25f6b45a00000000, - 0xb022c4cf00000000, 0x4e5924ab00000000, 0xdb8d543e00000000, - 0xb2aee46200000000, 0x277a94f700000000, 0xd901749300000000, - 0x4cd5040600000000, 0x572555cb00000000, 0xc2f1255e00000000, - 0x3c8ac53a00000000, 0xa95eb5af00000000, 0xc07d05f300000000, - 0x55a9756600000000, 0xabd2950200000000, 0x3e06e59700000000, - 0x7994f5bb00000000, 0xec40852e00000000, 0x123b654a00000000, - 0x87ef15df00000000, 0xeecca58300000000, 0x7b18d51600000000, - 0x8563357200000000, 0x10b745e700000000, 0xe40bcf6700000000, - 0x71dfbff200000000, 0x8fa45f9600000000, 0x1a702f0300000000, - 0x73539f5f00000000, 0xe687efca00000000, 0x18fc0fae00000000, - 0x8d287f3b00000000, 0xcaba6f1700000000, 0x5f6e1f8200000000, - 0xa115ffe600000000, 0x34c18f7300000000, 0x5de23f2f00000000, - 0xc8364fba00000000, 0x364dafde00000000, 0xa399df4b00000000, - 0xb8698e8600000000, 0x2dbdfe1300000000, 0xd3c61e7700000000, - 0x46126ee200000000, 0x2f31debe00000000, 0xbae5ae2b00000000, - 0x449e4e4f00000000, 0xd14a3eda00000000, 0x96d82ef600000000, - 0x030c5e6300000000, 0xfd77be0700000000, 0x68a3ce9200000000, - 0x01807ece00000000, 0x94540e5b00000000, 0x6a2fee3f00000000, - 0xfffb9eaa00000000, 0x1dc93c7e00000000, 0x881d4ceb00000000, - 0x7666ac8f00000000, 0xe3b2dc1a00000000, 0x8a916c4600000000, - 0x1f451cd300000000, 0xe13efcb700000000, 0x74ea8c2200000000, - 0x33789c0e00000000, 0xa6acec9b00000000, 0x58d70cff00000000, - 0xcd037c6a00000000, 0xa420cc3600000000, 0x31f4bca300000000, - 0xcf8f5cc700000000, 0x5a5b2c5200000000, 0x41ab7d9f00000000, - 0xd47f0d0a00000000, 0x2a04ed6e00000000, 0xbfd09dfb00000000, - 0xd6f32da700000000, 0x43275d3200000000, 0xbd5cbd5600000000, - 0x2888cdc300000000, 0x6f1addef00000000, 0xfacead7a00000000, - 0x04b54d1e00000000, 0x91613d8b00000000, 0xf8428dd700000000, - 0x6d96fd4200000000, 0x93ed1d2600000000, 0x06396db300000000, - 0x168e285400000000, 0x835a58c100000000, 0x7d21b8a500000000, - 0xe8f5c83000000000, 0x81d6786c00000000, 0x140208f900000000, - 0xea79e89d00000000, 0x7fad980800000000, 0x383f882400000000, - 0xadebf8b100000000, 0x539018d500000000, 0xc644684000000000, - 0xaf67d81c00000000, 0x3ab3a88900000000, 0xc4c848ed00000000, - 0x511c387800000000, 0x4aec69b500000000, 0xdf38192000000000, - 0x2143f94400000000, 0xb49789d100000000, 0xddb4398d00000000, - 0x4860491800000000, 0xb61ba97c00000000, 0x23cfd9e900000000, - 0x645dc9c500000000, 0xf189b95000000000, 0x0ff2593400000000, - 0x9a2629a100000000, 0xf30599fd00000000, 0x66d1e96800000000, - 0x98aa090c00000000, 0x0d7e799900000000, 0xef4cdb4d00000000, - 0x7a98abd800000000, 0x84e34bbc00000000, 0x11373b2900000000, - 0x78148b7500000000, 0xedc0fbe000000000, 0x13bb1b8400000000, - 0x866f6b1100000000, 0xc1fd7b3d00000000, 0x54290ba800000000, - 0xaa52ebcc00000000, 0x3f869b5900000000, 0x56a52b0500000000, - 0xc3715b9000000000, 0x3d0abbf400000000, 0xa8decb6100000000, - 0xb32e9aac00000000, 0x26faea3900000000, 0xd8810a5d00000000, - 0x4d557ac800000000, 0x2476ca9400000000, 0xb1a2ba0100000000, - 0x4fd95a6500000000, 0xda0d2af000000000, 0x9d9f3adc00000000, - 0x084b4a4900000000, 0xf630aa2d00000000, 0x63e4dab800000000, - 0x0ac76ae400000000, 0x9f131a7100000000, 0x6168fa1500000000, - 0xf4bc8a8000000000}, - {0x0000000000000000, 0x1f17f08000000000, 0x7f2891da00000000, - 0x603f615a00000000, 0xbf56536e00000000, 0xa041a3ee00000000, - 0xc07ec2b400000000, 0xdf69323400000000, 0x7eada6dc00000000, - 0x61ba565c00000000, 0x0185370600000000, 0x1e92c78600000000, - 0xc1fbf5b200000000, 0xdeec053200000000, 0xbed3646800000000, - 0xa1c494e800000000, 0xbd5c3c6200000000, 0xa24bcce200000000, - 0xc274adb800000000, 0xdd635d3800000000, 0x020a6f0c00000000, - 0x1d1d9f8c00000000, 0x7d22fed600000000, 0x62350e5600000000, - 0xc3f19abe00000000, 0xdce66a3e00000000, 0xbcd90b6400000000, - 0xa3cefbe400000000, 0x7ca7c9d000000000, 0x63b0395000000000, - 0x038f580a00000000, 0x1c98a88a00000000, 0x7ab978c400000000, - 0x65ae884400000000, 0x0591e91e00000000, 0x1a86199e00000000, - 0xc5ef2baa00000000, 0xdaf8db2a00000000, 0xbac7ba7000000000, - 0xa5d04af000000000, 0x0414de1800000000, 0x1b032e9800000000, - 0x7b3c4fc200000000, 0x642bbf4200000000, 0xbb428d7600000000, - 0xa4557df600000000, 0xc46a1cac00000000, 0xdb7dec2c00000000, - 0xc7e544a600000000, 0xd8f2b42600000000, 0xb8cdd57c00000000, - 0xa7da25fc00000000, 0x78b317c800000000, 0x67a4e74800000000, - 0x079b861200000000, 0x188c769200000000, 0xb948e27a00000000, - 0xa65f12fa00000000, 0xc66073a000000000, 0xd977832000000000, - 0x061eb11400000000, 0x1909419400000000, 0x793620ce00000000, - 0x6621d04e00000000, 0xb574805300000000, 0xaa6370d300000000, - 0xca5c118900000000, 0xd54be10900000000, 0x0a22d33d00000000, - 0x153523bd00000000, 0x750a42e700000000, 0x6a1db26700000000, - 0xcbd9268f00000000, 0xd4ced60f00000000, 0xb4f1b75500000000, - 0xabe647d500000000, 0x748f75e100000000, 0x6b98856100000000, - 0x0ba7e43b00000000, 0x14b014bb00000000, 0x0828bc3100000000, - 0x173f4cb100000000, 0x77002deb00000000, 0x6817dd6b00000000, - 0xb77eef5f00000000, 0xa8691fdf00000000, 0xc8567e8500000000, - 0xd7418e0500000000, 0x76851aed00000000, 0x6992ea6d00000000, - 0x09ad8b3700000000, 0x16ba7bb700000000, 0xc9d3498300000000, - 0xd6c4b90300000000, 0xb6fbd85900000000, 0xa9ec28d900000000, - 0xcfcdf89700000000, 0xd0da081700000000, 0xb0e5694d00000000, - 0xaff299cd00000000, 0x709babf900000000, 0x6f8c5b7900000000, - 0x0fb33a2300000000, 0x10a4caa300000000, 0xb1605e4b00000000, - 0xae77aecb00000000, 0xce48cf9100000000, 0xd15f3f1100000000, - 0x0e360d2500000000, 0x1121fda500000000, 0x711e9cff00000000, - 0x6e096c7f00000000, 0x7291c4f500000000, 0x6d86347500000000, - 0x0db9552f00000000, 0x12aea5af00000000, 0xcdc7979b00000000, - 0xd2d0671b00000000, 0xb2ef064100000000, 0xadf8f6c100000000, - 0x0c3c622900000000, 0x132b92a900000000, 0x7314f3f300000000, - 0x6c03037300000000, 0xb36a314700000000, 0xac7dc1c700000000, - 0xcc42a09d00000000, 0xd355501d00000000, 0x6ae900a700000000, - 0x75fef02700000000, 0x15c1917d00000000, 0x0ad661fd00000000, - 0xd5bf53c900000000, 0xcaa8a34900000000, 0xaa97c21300000000, - 0xb580329300000000, 0x1444a67b00000000, 0x0b5356fb00000000, - 0x6b6c37a100000000, 0x747bc72100000000, 0xab12f51500000000, - 0xb405059500000000, 0xd43a64cf00000000, 0xcb2d944f00000000, - 0xd7b53cc500000000, 0xc8a2cc4500000000, 0xa89dad1f00000000, - 0xb78a5d9f00000000, 0x68e36fab00000000, 0x77f49f2b00000000, - 0x17cbfe7100000000, 0x08dc0ef100000000, 0xa9189a1900000000, - 0xb60f6a9900000000, 0xd6300bc300000000, 0xc927fb4300000000, - 0x164ec97700000000, 0x095939f700000000, 0x696658ad00000000, - 0x7671a82d00000000, 0x1050786300000000, 0x0f4788e300000000, - 0x6f78e9b900000000, 0x706f193900000000, 0xaf062b0d00000000, - 0xb011db8d00000000, 0xd02ebad700000000, 0xcf394a5700000000, - 0x6efddebf00000000, 0x71ea2e3f00000000, 0x11d54f6500000000, - 0x0ec2bfe500000000, 0xd1ab8dd100000000, 0xcebc7d5100000000, - 0xae831c0b00000000, 0xb194ec8b00000000, 0xad0c440100000000, - 0xb21bb48100000000, 0xd224d5db00000000, 0xcd33255b00000000, - 0x125a176f00000000, 0x0d4de7ef00000000, 0x6d7286b500000000, - 0x7265763500000000, 0xd3a1e2dd00000000, 0xccb6125d00000000, - 0xac89730700000000, 0xb39e838700000000, 0x6cf7b1b300000000, - 0x73e0413300000000, 0x13df206900000000, 0x0cc8d0e900000000, - 0xdf9d80f400000000, 0xc08a707400000000, 0xa0b5112e00000000, - 0xbfa2e1ae00000000, 0x60cbd39a00000000, 0x7fdc231a00000000, - 0x1fe3424000000000, 0x00f4b2c000000000, 0xa130262800000000, - 0xbe27d6a800000000, 0xde18b7f200000000, 0xc10f477200000000, - 0x1e66754600000000, 0x017185c600000000, 0x614ee49c00000000, - 0x7e59141c00000000, 0x62c1bc9600000000, 0x7dd64c1600000000, - 0x1de92d4c00000000, 0x02feddcc00000000, 0xdd97eff800000000, - 0xc2801f7800000000, 0xa2bf7e2200000000, 0xbda88ea200000000, - 0x1c6c1a4a00000000, 0x037beaca00000000, 0x63448b9000000000, - 0x7c537b1000000000, 0xa33a492400000000, 0xbc2db9a400000000, - 0xdc12d8fe00000000, 0xc305287e00000000, 0xa524f83000000000, - 0xba3308b000000000, 0xda0c69ea00000000, 0xc51b996a00000000, - 0x1a72ab5e00000000, 0x05655bde00000000, 0x655a3a8400000000, - 0x7a4dca0400000000, 0xdb895eec00000000, 0xc49eae6c00000000, - 0xa4a1cf3600000000, 0xbbb63fb600000000, 0x64df0d8200000000, - 0x7bc8fd0200000000, 0x1bf79c5800000000, 0x04e06cd800000000, - 0x1878c45200000000, 0x076f34d200000000, 0x6750558800000000, - 0x7847a50800000000, 0xa72e973c00000000, 0xb83967bc00000000, - 0xd80606e600000000, 0xc711f66600000000, 0x66d5628e00000000, - 0x79c2920e00000000, 0x19fdf35400000000, 0x06ea03d400000000, - 0xd98331e000000000, 0xc694c16000000000, 0xa6aba03a00000000, - 0xb9bc50ba00000000}, - {0x0000000000000000, 0xe2fd888d00000000, 0x85fd60c000000000, - 0x6700e84d00000000, 0x4bfdb05b00000000, 0xa90038d600000000, - 0xce00d09b00000000, 0x2cfd581600000000, 0x96fa61b700000000, - 0x7407e93a00000000, 0x1307017700000000, 0xf1fa89fa00000000, - 0xdd07d1ec00000000, 0x3ffa596100000000, 0x58fab12c00000000, - 0xba0739a100000000, 0x6df3b2b500000000, 0x8f0e3a3800000000, - 0xe80ed27500000000, 0x0af35af800000000, 0x260e02ee00000000, - 0xc4f38a6300000000, 0xa3f3622e00000000, 0x410eeaa300000000, - 0xfb09d30200000000, 0x19f45b8f00000000, 0x7ef4b3c200000000, - 0x9c093b4f00000000, 0xb0f4635900000000, 0x5209ebd400000000, - 0x3509039900000000, 0xd7f48b1400000000, 0x9be014b000000000, - 0x791d9c3d00000000, 0x1e1d747000000000, 0xfce0fcfd00000000, - 0xd01da4eb00000000, 0x32e02c6600000000, 0x55e0c42b00000000, - 0xb71d4ca600000000, 0x0d1a750700000000, 0xefe7fd8a00000000, - 0x88e715c700000000, 0x6a1a9d4a00000000, 0x46e7c55c00000000, - 0xa41a4dd100000000, 0xc31aa59c00000000, 0x21e72d1100000000, - 0xf613a60500000000, 0x14ee2e8800000000, 0x73eec6c500000000, - 0x91134e4800000000, 0xbdee165e00000000, 0x5f139ed300000000, - 0x3813769e00000000, 0xdaeefe1300000000, 0x60e9c7b200000000, - 0x82144f3f00000000, 0xe514a77200000000, 0x07e92fff00000000, - 0x2b1477e900000000, 0xc9e9ff6400000000, 0xaee9172900000000, - 0x4c149fa400000000, 0x77c758bb00000000, 0x953ad03600000000, - 0xf23a387b00000000, 0x10c7b0f600000000, 0x3c3ae8e000000000, - 0xdec7606d00000000, 0xb9c7882000000000, 0x5b3a00ad00000000, - 0xe13d390c00000000, 0x03c0b18100000000, 0x64c059cc00000000, - 0x863dd14100000000, 0xaac0895700000000, 0x483d01da00000000, - 0x2f3de99700000000, 0xcdc0611a00000000, 0x1a34ea0e00000000, - 0xf8c9628300000000, 0x9fc98ace00000000, 0x7d34024300000000, - 0x51c95a5500000000, 0xb334d2d800000000, 0xd4343a9500000000, - 0x36c9b21800000000, 0x8cce8bb900000000, 0x6e33033400000000, - 0x0933eb7900000000, 0xebce63f400000000, 0xc7333be200000000, - 0x25ceb36f00000000, 0x42ce5b2200000000, 0xa033d3af00000000, - 0xec274c0b00000000, 0x0edac48600000000, 0x69da2ccb00000000, - 0x8b27a44600000000, 0xa7dafc5000000000, 0x452774dd00000000, - 0x22279c9000000000, 0xc0da141d00000000, 0x7add2dbc00000000, - 0x9820a53100000000, 0xff204d7c00000000, 0x1dddc5f100000000, - 0x31209de700000000, 0xd3dd156a00000000, 0xb4ddfd2700000000, - 0x562075aa00000000, 0x81d4febe00000000, 0x6329763300000000, - 0x04299e7e00000000, 0xe6d416f300000000, 0xca294ee500000000, - 0x28d4c66800000000, 0x4fd42e2500000000, 0xad29a6a800000000, - 0x172e9f0900000000, 0xf5d3178400000000, 0x92d3ffc900000000, - 0x702e774400000000, 0x5cd32f5200000000, 0xbe2ea7df00000000, - 0xd92e4f9200000000, 0x3bd3c71f00000000, 0xaf88c0ad00000000, - 0x4d75482000000000, 0x2a75a06d00000000, 0xc88828e000000000, - 0xe47570f600000000, 0x0688f87b00000000, 0x6188103600000000, - 0x837598bb00000000, 0x3972a11a00000000, 0xdb8f299700000000, - 0xbc8fc1da00000000, 0x5e72495700000000, 0x728f114100000000, - 0x907299cc00000000, 0xf772718100000000, 0x158ff90c00000000, - 0xc27b721800000000, 0x2086fa9500000000, 0x478612d800000000, - 0xa57b9a5500000000, 0x8986c24300000000, 0x6b7b4ace00000000, - 0x0c7ba28300000000, 0xee862a0e00000000, 0x548113af00000000, - 0xb67c9b2200000000, 0xd17c736f00000000, 0x3381fbe200000000, - 0x1f7ca3f400000000, 0xfd812b7900000000, 0x9a81c33400000000, - 0x787c4bb900000000, 0x3468d41d00000000, 0xd6955c9000000000, - 0xb195b4dd00000000, 0x53683c5000000000, 0x7f95644600000000, - 0x9d68eccb00000000, 0xfa68048600000000, 0x18958c0b00000000, - 0xa292b5aa00000000, 0x406f3d2700000000, 0x276fd56a00000000, - 0xc5925de700000000, 0xe96f05f100000000, 0x0b928d7c00000000, - 0x6c92653100000000, 0x8e6fedbc00000000, 0x599b66a800000000, - 0xbb66ee2500000000, 0xdc66066800000000, 0x3e9b8ee500000000, - 0x1266d6f300000000, 0xf09b5e7e00000000, 0x979bb63300000000, - 0x75663ebe00000000, 0xcf61071f00000000, 0x2d9c8f9200000000, - 0x4a9c67df00000000, 0xa861ef5200000000, 0x849cb74400000000, - 0x66613fc900000000, 0x0161d78400000000, 0xe39c5f0900000000, - 0xd84f981600000000, 0x3ab2109b00000000, 0x5db2f8d600000000, - 0xbf4f705b00000000, 0x93b2284d00000000, 0x714fa0c000000000, - 0x164f488d00000000, 0xf4b2c00000000000, 0x4eb5f9a100000000, - 0xac48712c00000000, 0xcb48996100000000, 0x29b511ec00000000, - 0x054849fa00000000, 0xe7b5c17700000000, 0x80b5293a00000000, - 0x6248a1b700000000, 0xb5bc2aa300000000, 0x5741a22e00000000, - 0x30414a6300000000, 0xd2bcc2ee00000000, 0xfe419af800000000, - 0x1cbc127500000000, 0x7bbcfa3800000000, 0x994172b500000000, - 0x23464b1400000000, 0xc1bbc39900000000, 0xa6bb2bd400000000, - 0x4446a35900000000, 0x68bbfb4f00000000, 0x8a4673c200000000, - 0xed469b8f00000000, 0x0fbb130200000000, 0x43af8ca600000000, - 0xa152042b00000000, 0xc652ec6600000000, 0x24af64eb00000000, - 0x08523cfd00000000, 0xeaafb47000000000, 0x8daf5c3d00000000, - 0x6f52d4b000000000, 0xd555ed1100000000, 0x37a8659c00000000, - 0x50a88dd100000000, 0xb255055c00000000, 0x9ea85d4a00000000, - 0x7c55d5c700000000, 0x1b553d8a00000000, 0xf9a8b50700000000, - 0x2e5c3e1300000000, 0xcca1b69e00000000, 0xaba15ed300000000, - 0x495cd65e00000000, 0x65a18e4800000000, 0x875c06c500000000, - 0xe05cee8800000000, 0x02a1660500000000, 0xb8a65fa400000000, - 0x5a5bd72900000000, 0x3d5b3f6400000000, 0xdfa6b7e900000000, - 0xf35befff00000000, 0x11a6677200000000, 0x76a68f3f00000000, - 0x945b07b200000000}, - {0x0000000000000000, 0xa90b894e00000000, 0x5217129d00000000, - 0xfb1c9bd300000000, 0xe52855e100000000, 0x4c23dcaf00000000, - 0xb73f477c00000000, 0x1e34ce3200000000, 0x8b57db1900000000, - 0x225c525700000000, 0xd940c98400000000, 0x704b40ca00000000, - 0x6e7f8ef800000000, 0xc77407b600000000, 0x3c689c6500000000, - 0x9563152b00000000, 0x16afb63300000000, 0xbfa43f7d00000000, - 0x44b8a4ae00000000, 0xedb32de000000000, 0xf387e3d200000000, - 0x5a8c6a9c00000000, 0xa190f14f00000000, 0x089b780100000000, - 0x9df86d2a00000000, 0x34f3e46400000000, 0xcfef7fb700000000, - 0x66e4f6f900000000, 0x78d038cb00000000, 0xd1dbb18500000000, - 0x2ac72a5600000000, 0x83cca31800000000, 0x2c5e6d6700000000, - 0x8555e42900000000, 0x7e497ffa00000000, 0xd742f6b400000000, - 0xc976388600000000, 0x607db1c800000000, 0x9b612a1b00000000, - 0x326aa35500000000, 0xa709b67e00000000, 0x0e023f3000000000, - 0xf51ea4e300000000, 0x5c152dad00000000, 0x4221e39f00000000, - 0xeb2a6ad100000000, 0x1036f10200000000, 0xb93d784c00000000, - 0x3af1db5400000000, 0x93fa521a00000000, 0x68e6c9c900000000, - 0xc1ed408700000000, 0xdfd98eb500000000, 0x76d207fb00000000, - 0x8dce9c2800000000, 0x24c5156600000000, 0xb1a6004d00000000, - 0x18ad890300000000, 0xe3b112d000000000, 0x4aba9b9e00000000, - 0x548e55ac00000000, 0xfd85dce200000000, 0x0699473100000000, - 0xaf92ce7f00000000, 0x58bcdace00000000, 0xf1b7538000000000, - 0x0aabc85300000000, 0xa3a0411d00000000, 0xbd948f2f00000000, - 0x149f066100000000, 0xef839db200000000, 0x468814fc00000000, - 0xd3eb01d700000000, 0x7ae0889900000000, 0x81fc134a00000000, - 0x28f79a0400000000, 0x36c3543600000000, 0x9fc8dd7800000000, - 0x64d446ab00000000, 0xcddfcfe500000000, 0x4e136cfd00000000, - 0xe718e5b300000000, 0x1c047e6000000000, 0xb50ff72e00000000, - 0xab3b391c00000000, 0x0230b05200000000, 0xf92c2b8100000000, - 0x5027a2cf00000000, 0xc544b7e400000000, 0x6c4f3eaa00000000, - 0x9753a57900000000, 0x3e582c3700000000, 0x206ce20500000000, - 0x89676b4b00000000, 0x727bf09800000000, 0xdb7079d600000000, - 0x74e2b7a900000000, 0xdde93ee700000000, 0x26f5a53400000000, - 0x8ffe2c7a00000000, 0x91cae24800000000, 0x38c16b0600000000, - 0xc3ddf0d500000000, 0x6ad6799b00000000, 0xffb56cb000000000, - 0x56bee5fe00000000, 0xada27e2d00000000, 0x04a9f76300000000, - 0x1a9d395100000000, 0xb396b01f00000000, 0x488a2bcc00000000, - 0xe181a28200000000, 0x624d019a00000000, 0xcb4688d400000000, - 0x305a130700000000, 0x99519a4900000000, 0x8765547b00000000, - 0x2e6edd3500000000, 0xd57246e600000000, 0x7c79cfa800000000, - 0xe91ada8300000000, 0x401153cd00000000, 0xbb0dc81e00000000, - 0x1206415000000000, 0x0c328f6200000000, 0xa539062c00000000, - 0x5e259dff00000000, 0xf72e14b100000000, 0xf17ec44600000000, - 0x58754d0800000000, 0xa369d6db00000000, 0x0a625f9500000000, - 0x145691a700000000, 0xbd5d18e900000000, 0x4641833a00000000, - 0xef4a0a7400000000, 0x7a291f5f00000000, 0xd322961100000000, - 0x283e0dc200000000, 0x8135848c00000000, 0x9f014abe00000000, - 0x360ac3f000000000, 0xcd16582300000000, 0x641dd16d00000000, - 0xe7d1727500000000, 0x4edafb3b00000000, 0xb5c660e800000000, - 0x1ccde9a600000000, 0x02f9279400000000, 0xabf2aeda00000000, - 0x50ee350900000000, 0xf9e5bc4700000000, 0x6c86a96c00000000, - 0xc58d202200000000, 0x3e91bbf100000000, 0x979a32bf00000000, - 0x89aefc8d00000000, 0x20a575c300000000, 0xdbb9ee1000000000, - 0x72b2675e00000000, 0xdd20a92100000000, 0x742b206f00000000, - 0x8f37bbbc00000000, 0x263c32f200000000, 0x3808fcc000000000, - 0x9103758e00000000, 0x6a1fee5d00000000, 0xc314671300000000, - 0x5677723800000000, 0xff7cfb7600000000, 0x046060a500000000, - 0xad6be9eb00000000, 0xb35f27d900000000, 0x1a54ae9700000000, - 0xe148354400000000, 0x4843bc0a00000000, 0xcb8f1f1200000000, - 0x6284965c00000000, 0x99980d8f00000000, 0x309384c100000000, - 0x2ea74af300000000, 0x87acc3bd00000000, 0x7cb0586e00000000, - 0xd5bbd12000000000, 0x40d8c40b00000000, 0xe9d34d4500000000, - 0x12cfd69600000000, 0xbbc45fd800000000, 0xa5f091ea00000000, - 0x0cfb18a400000000, 0xf7e7837700000000, 0x5eec0a3900000000, - 0xa9c21e8800000000, 0x00c997c600000000, 0xfbd50c1500000000, - 0x52de855b00000000, 0x4cea4b6900000000, 0xe5e1c22700000000, - 0x1efd59f400000000, 0xb7f6d0ba00000000, 0x2295c59100000000, - 0x8b9e4cdf00000000, 0x7082d70c00000000, 0xd9895e4200000000, - 0xc7bd907000000000, 0x6eb6193e00000000, 0x95aa82ed00000000, - 0x3ca10ba300000000, 0xbf6da8bb00000000, 0x166621f500000000, - 0xed7aba2600000000, 0x4471336800000000, 0x5a45fd5a00000000, - 0xf34e741400000000, 0x0852efc700000000, 0xa159668900000000, - 0x343a73a200000000, 0x9d31faec00000000, 0x662d613f00000000, - 0xcf26e87100000000, 0xd112264300000000, 0x7819af0d00000000, - 0x830534de00000000, 0x2a0ebd9000000000, 0x859c73ef00000000, - 0x2c97faa100000000, 0xd78b617200000000, 0x7e80e83c00000000, - 0x60b4260e00000000, 0xc9bfaf4000000000, 0x32a3349300000000, - 0x9ba8bddd00000000, 0x0ecba8f600000000, 0xa7c021b800000000, - 0x5cdcba6b00000000, 0xf5d7332500000000, 0xebe3fd1700000000, - 0x42e8745900000000, 0xb9f4ef8a00000000, 0x10ff66c400000000, - 0x9333c5dc00000000, 0x3a384c9200000000, 0xc124d74100000000, - 0x682f5e0f00000000, 0x761b903d00000000, 0xdf10197300000000, - 0x240c82a000000000, 0x8d070bee00000000, 0x18641ec500000000, - 0xb16f978b00000000, 0x4a730c5800000000, 0xe378851600000000, - 0xfd4c4b2400000000, 0x5447c26a00000000, 0xaf5b59b900000000, - 0x0650d0f700000000}, - {0x0000000000000000, 0x479244af00000000, 0xcf22f88500000000, - 0x88b0bc2a00000000, 0xdf4381d000000000, 0x98d1c57f00000000, - 0x1061795500000000, 0x57f33dfa00000000, 0xff81737a00000000, - 0xb81337d500000000, 0x30a38bff00000000, 0x7731cf5000000000, - 0x20c2f2aa00000000, 0x6750b60500000000, 0xefe00a2f00000000, - 0xa8724e8000000000, 0xfe03e7f400000000, 0xb991a35b00000000, - 0x31211f7100000000, 0x76b35bde00000000, 0x2140662400000000, - 0x66d2228b00000000, 0xee629ea100000000, 0xa9f0da0e00000000, - 0x0182948e00000000, 0x4610d02100000000, 0xcea06c0b00000000, - 0x893228a400000000, 0xdec1155e00000000, 0x995351f100000000, - 0x11e3eddb00000000, 0x5671a97400000000, 0xbd01bf3200000000, - 0xfa93fb9d00000000, 0x722347b700000000, 0x35b1031800000000, - 0x62423ee200000000, 0x25d07a4d00000000, 0xad60c66700000000, - 0xeaf282c800000000, 0x4280cc4800000000, 0x051288e700000000, - 0x8da234cd00000000, 0xca30706200000000, 0x9dc34d9800000000, - 0xda51093700000000, 0x52e1b51d00000000, 0x1573f1b200000000, - 0x430258c600000000, 0x04901c6900000000, 0x8c20a04300000000, - 0xcbb2e4ec00000000, 0x9c41d91600000000, 0xdbd39db900000000, - 0x5363219300000000, 0x14f1653c00000000, 0xbc832bbc00000000, - 0xfb116f1300000000, 0x73a1d33900000000, 0x3433979600000000, - 0x63c0aa6c00000000, 0x2452eec300000000, 0xace252e900000000, - 0xeb70164600000000, 0x7a037e6500000000, 0x3d913aca00000000, - 0xb52186e000000000, 0xf2b3c24f00000000, 0xa540ffb500000000, - 0xe2d2bb1a00000000, 0x6a62073000000000, 0x2df0439f00000000, - 0x85820d1f00000000, 0xc21049b000000000, 0x4aa0f59a00000000, - 0x0d32b13500000000, 0x5ac18ccf00000000, 0x1d53c86000000000, - 0x95e3744a00000000, 0xd27130e500000000, 0x8400999100000000, - 0xc392dd3e00000000, 0x4b22611400000000, 0x0cb025bb00000000, - 0x5b43184100000000, 0x1cd15cee00000000, 0x9461e0c400000000, - 0xd3f3a46b00000000, 0x7b81eaeb00000000, 0x3c13ae4400000000, - 0xb4a3126e00000000, 0xf33156c100000000, 0xa4c26b3b00000000, - 0xe3502f9400000000, 0x6be093be00000000, 0x2c72d71100000000, - 0xc702c15700000000, 0x809085f800000000, 0x082039d200000000, - 0x4fb27d7d00000000, 0x1841408700000000, 0x5fd3042800000000, - 0xd763b80200000000, 0x90f1fcad00000000, 0x3883b22d00000000, - 0x7f11f68200000000, 0xf7a14aa800000000, 0xb0330e0700000000, - 0xe7c033fd00000000, 0xa052775200000000, 0x28e2cb7800000000, - 0x6f708fd700000000, 0x390126a300000000, 0x7e93620c00000000, - 0xf623de2600000000, 0xb1b19a8900000000, 0xe642a77300000000, - 0xa1d0e3dc00000000, 0x29605ff600000000, 0x6ef21b5900000000, - 0xc68055d900000000, 0x8112117600000000, 0x09a2ad5c00000000, - 0x4e30e9f300000000, 0x19c3d40900000000, 0x5e5190a600000000, - 0xd6e12c8c00000000, 0x9173682300000000, 0xf406fcca00000000, - 0xb394b86500000000, 0x3b24044f00000000, 0x7cb640e000000000, - 0x2b457d1a00000000, 0x6cd739b500000000, 0xe467859f00000000, - 0xa3f5c13000000000, 0x0b878fb000000000, 0x4c15cb1f00000000, - 0xc4a5773500000000, 0x8337339a00000000, 0xd4c40e6000000000, - 0x93564acf00000000, 0x1be6f6e500000000, 0x5c74b24a00000000, - 0x0a051b3e00000000, 0x4d975f9100000000, 0xc527e3bb00000000, - 0x82b5a71400000000, 0xd5469aee00000000, 0x92d4de4100000000, - 0x1a64626b00000000, 0x5df626c400000000, 0xf584684400000000, - 0xb2162ceb00000000, 0x3aa690c100000000, 0x7d34d46e00000000, - 0x2ac7e99400000000, 0x6d55ad3b00000000, 0xe5e5111100000000, - 0xa27755be00000000, 0x490743f800000000, 0x0e95075700000000, - 0x8625bb7d00000000, 0xc1b7ffd200000000, 0x9644c22800000000, - 0xd1d6868700000000, 0x59663aad00000000, 0x1ef47e0200000000, - 0xb686308200000000, 0xf114742d00000000, 0x79a4c80700000000, - 0x3e368ca800000000, 0x69c5b15200000000, 0x2e57f5fd00000000, - 0xa6e749d700000000, 0xe1750d7800000000, 0xb704a40c00000000, - 0xf096e0a300000000, 0x78265c8900000000, 0x3fb4182600000000, - 0x684725dc00000000, 0x2fd5617300000000, 0xa765dd5900000000, - 0xe0f799f600000000, 0x4885d77600000000, 0x0f1793d900000000, - 0x87a72ff300000000, 0xc0356b5c00000000, 0x97c656a600000000, - 0xd054120900000000, 0x58e4ae2300000000, 0x1f76ea8c00000000, - 0x8e0582af00000000, 0xc997c60000000000, 0x41277a2a00000000, - 0x06b53e8500000000, 0x5146037f00000000, 0x16d447d000000000, - 0x9e64fbfa00000000, 0xd9f6bf5500000000, 0x7184f1d500000000, - 0x3616b57a00000000, 0xbea6095000000000, 0xf9344dff00000000, - 0xaec7700500000000, 0xe95534aa00000000, 0x61e5888000000000, - 0x2677cc2f00000000, 0x7006655b00000000, 0x379421f400000000, - 0xbf249dde00000000, 0xf8b6d97100000000, 0xaf45e48b00000000, - 0xe8d7a02400000000, 0x60671c0e00000000, 0x27f558a100000000, - 0x8f87162100000000, 0xc815528e00000000, 0x40a5eea400000000, - 0x0737aa0b00000000, 0x50c497f100000000, 0x1756d35e00000000, - 0x9fe66f7400000000, 0xd8742bdb00000000, 0x33043d9d00000000, - 0x7496793200000000, 0xfc26c51800000000, 0xbbb481b700000000, - 0xec47bc4d00000000, 0xabd5f8e200000000, 0x236544c800000000, - 0x64f7006700000000, 0xcc854ee700000000, 0x8b170a4800000000, - 0x03a7b66200000000, 0x4435f2cd00000000, 0x13c6cf3700000000, - 0x54548b9800000000, 0xdce437b200000000, 0x9b76731d00000000, - 0xcd07da6900000000, 0x8a959ec600000000, 0x022522ec00000000, - 0x45b7664300000000, 0x12445bb900000000, 0x55d61f1600000000, - 0xdd66a33c00000000, 0x9af4e79300000000, 0x3286a91300000000, - 0x7514edbc00000000, 0xfda4519600000000, 0xba36153900000000, - 0xedc528c300000000, 0xaa576c6c00000000, 0x22e7d04600000000, - 0x657594e900000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, - 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, - 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, - 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, - 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, - 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, - 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, - 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, - 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, - 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, - 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, - 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, - 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, - 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, - 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, - 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, - 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, - 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, - 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, - 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, - 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, - 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, - 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, - 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, - 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, - 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, - 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, - 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, - 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, - 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, - 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, - 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, - 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, - 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, - 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, - 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, - 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, - 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, - 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, - 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, - 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, - 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, - 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, - 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, - 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, - 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, - 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, - 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, - 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, - 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, - 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, - 0xd8ac6b35}, - {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, - 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, - 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, - 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, - 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, - 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, - 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, - 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, - 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, - 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, - 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, - 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, - 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, - 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, - 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, - 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, - 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, - 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, - 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, - 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, - 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, - 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, - 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, - 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, - 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, - 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, - 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, - 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, - 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, - 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, - 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, - 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, - 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, - 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, - 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, - 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, - 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, - 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, - 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, - 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, - 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, - 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, - 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, - 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, - 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, - 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, - 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, - 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, - 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, - 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, - 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, - 0xa140efa8}, - {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, - 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, - 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, - 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, - 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, - 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, - 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, - 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, - 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, - 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, - 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, - 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, - 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, - 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, - 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, - 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, - 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, - 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, - 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, - 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, - 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, - 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, - 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, - 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, - 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, - 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, - 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, - 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, - 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, - 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, - 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, - 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, - 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, - 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, - 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, - 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, - 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, - 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, - 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, - 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, - 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, - 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, - 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, - 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, - 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, - 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, - 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, - 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, - 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, - 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, - 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, - 0x917cd6a1}, - {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, - 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, - 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, - 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, - 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, - 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, - 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, - 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, - 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, - 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, - 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, - 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, - 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, - 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, - 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, - 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, - 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, - 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, - 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, - 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, - 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, - 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, - 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, - 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, - 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, - 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, - 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, - 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, - 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, - 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, - 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, - 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, - 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, - 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, - 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, - 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, - 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, - 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, - 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, - 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, - 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, - 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, - 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, - 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, - 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, - 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, - 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, - 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, - 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, - 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, - 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, - 0x18ba364e}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x43cba687, 0xc7903cd4, 0x845b9a53, 0xcf270873, - 0x8cecaef4, 0x08b734a7, 0x4b7c9220, 0x9e4f10e6, 0xdd84b661, - 0x59df2c32, 0x1a148ab5, 0x51681895, 0x12a3be12, 0x96f82441, - 0xd53382c6, 0x7d995117, 0x3e52f790, 0xba096dc3, 0xf9c2cb44, - 0xb2be5964, 0xf175ffe3, 0x752e65b0, 0x36e5c337, 0xe3d641f1, - 0xa01de776, 0x24467d25, 0x678ddba2, 0x2cf14982, 0x6f3aef05, - 0xeb617556, 0xa8aad3d1, 0xfa32a32e, 0xb9f905a9, 0x3da29ffa, - 0x7e69397d, 0x3515ab5d, 0x76de0dda, 0xf2859789, 0xb14e310e, - 0x647db3c8, 0x27b6154f, 0xa3ed8f1c, 0xe026299b, 0xab5abbbb, - 0xe8911d3c, 0x6cca876f, 0x2f0121e8, 0x87abf239, 0xc46054be, - 0x403bceed, 0x03f0686a, 0x488cfa4a, 0x0b475ccd, 0x8f1cc69e, - 0xccd76019, 0x19e4e2df, 0x5a2f4458, 0xde74de0b, 0x9dbf788c, - 0xd6c3eaac, 0x95084c2b, 0x1153d678, 0x529870ff, 0xf465465d, - 0xb7aee0da, 0x33f57a89, 0x703edc0e, 0x3b424e2e, 0x7889e8a9, - 0xfcd272fa, 0xbf19d47d, 0x6a2a56bb, 0x29e1f03c, 0xadba6a6f, - 0xee71cce8, 0xa50d5ec8, 0xe6c6f84f, 0x629d621c, 0x2156c49b, - 0x89fc174a, 0xca37b1cd, 0x4e6c2b9e, 0x0da78d19, 0x46db1f39, - 0x0510b9be, 0x814b23ed, 0xc280856a, 0x17b307ac, 0x5478a12b, - 0xd0233b78, 0x93e89dff, 0xd8940fdf, 0x9b5fa958, 0x1f04330b, - 0x5ccf958c, 0x0e57e573, 0x4d9c43f4, 0xc9c7d9a7, 0x8a0c7f20, - 0xc170ed00, 0x82bb4b87, 0x06e0d1d4, 0x452b7753, 0x9018f595, - 0xd3d35312, 0x5788c941, 0x14436fc6, 0x5f3ffde6, 0x1cf45b61, - 0x98afc132, 0xdb6467b5, 0x73ceb464, 0x300512e3, 0xb45e88b0, - 0xf7952e37, 0xbce9bc17, 0xff221a90, 0x7b7980c3, 0x38b22644, - 0xed81a482, 0xae4a0205, 0x2a119856, 0x69da3ed1, 0x22a6acf1, - 0x616d0a76, 0xe5369025, 0xa6fd36a2, 0xe8cb8cba, 0xab002a3d, - 0x2f5bb06e, 0x6c9016e9, 0x27ec84c9, 0x6427224e, 0xe07cb81d, - 0xa3b71e9a, 0x76849c5c, 0x354f3adb, 0xb114a088, 0xf2df060f, - 0xb9a3942f, 0xfa6832a8, 0x7e33a8fb, 0x3df80e7c, 0x9552ddad, - 0xd6997b2a, 0x52c2e179, 0x110947fe, 0x5a75d5de, 0x19be7359, - 0x9de5e90a, 0xde2e4f8d, 0x0b1dcd4b, 0x48d66bcc, 0xcc8df19f, - 0x8f465718, 0xc43ac538, 0x87f163bf, 0x03aaf9ec, 0x40615f6b, - 0x12f92f94, 0x51328913, 0xd5691340, 0x96a2b5c7, 0xddde27e7, - 0x9e158160, 0x1a4e1b33, 0x5985bdb4, 0x8cb63f72, 0xcf7d99f5, - 0x4b2603a6, 0x08eda521, 0x43913701, 0x005a9186, 0x84010bd5, - 0xc7caad52, 0x6f607e83, 0x2cabd804, 0xa8f04257, 0xeb3be4d0, - 0xa04776f0, 0xe38cd077, 0x67d74a24, 0x241ceca3, 0xf12f6e65, - 0xb2e4c8e2, 0x36bf52b1, 0x7574f436, 0x3e086616, 0x7dc3c091, - 0xf9985ac2, 0xba53fc45, 0x1caecae7, 0x5f656c60, 0xdb3ef633, - 0x98f550b4, 0xd389c294, 0x90426413, 0x1419fe40, 0x57d258c7, - 0x82e1da01, 0xc12a7c86, 0x4571e6d5, 0x06ba4052, 0x4dc6d272, - 0x0e0d74f5, 0x8a56eea6, 0xc99d4821, 0x61379bf0, 0x22fc3d77, - 0xa6a7a724, 0xe56c01a3, 0xae109383, 0xeddb3504, 0x6980af57, - 0x2a4b09d0, 0xff788b16, 0xbcb32d91, 0x38e8b7c2, 0x7b231145, - 0x305f8365, 0x739425e2, 0xf7cfbfb1, 0xb4041936, 0xe69c69c9, - 0xa557cf4e, 0x210c551d, 0x62c7f39a, 0x29bb61ba, 0x6a70c73d, - 0xee2b5d6e, 0xade0fbe9, 0x78d3792f, 0x3b18dfa8, 0xbf4345fb, - 0xfc88e37c, 0xb7f4715c, 0xf43fd7db, 0x70644d88, 0x33afeb0f, - 0x9b0538de, 0xd8ce9e59, 0x5c95040a, 0x1f5ea28d, 0x542230ad, - 0x17e9962a, 0x93b20c79, 0xd079aafe, 0x054a2838, 0x46818ebf, - 0xc2da14ec, 0x8111b26b, 0xca6d204b, 0x89a686cc, 0x0dfd1c9f, - 0x4e36ba18}, - {0x00000000, 0xe1b652ef, 0x836bd405, 0x62dd86ea, 0x06d7a80b, - 0xe761fae4, 0x85bc7c0e, 0x640a2ee1, 0x0cae5117, 0xed1803f8, - 0x8fc58512, 0x6e73d7fd, 0x0a79f91c, 0xebcfabf3, 0x89122d19, - 0x68a47ff6, 0x185ca32e, 0xf9eaf1c1, 0x9b37772b, 0x7a8125c4, - 0x1e8b0b25, 0xff3d59ca, 0x9de0df20, 0x7c568dcf, 0x14f2f239, - 0xf544a0d6, 0x9799263c, 0x762f74d3, 0x12255a32, 0xf39308dd, - 0x914e8e37, 0x70f8dcd8, 0x30b8465d, 0xd10e14b2, 0xb3d39258, - 0x5265c0b7, 0x366fee56, 0xd7d9bcb9, 0xb5043a53, 0x54b268bc, - 0x3c16174a, 0xdda045a5, 0xbf7dc34f, 0x5ecb91a0, 0x3ac1bf41, - 0xdb77edae, 0xb9aa6b44, 0x581c39ab, 0x28e4e573, 0xc952b79c, - 0xab8f3176, 0x4a396399, 0x2e334d78, 0xcf851f97, 0xad58997d, - 0x4ceecb92, 0x244ab464, 0xc5fce68b, 0xa7216061, 0x4697328e, - 0x229d1c6f, 0xc32b4e80, 0xa1f6c86a, 0x40409a85, 0x60708dba, - 0x81c6df55, 0xe31b59bf, 0x02ad0b50, 0x66a725b1, 0x8711775e, - 0xe5ccf1b4, 0x047aa35b, 0x6cdedcad, 0x8d688e42, 0xefb508a8, - 0x0e035a47, 0x6a0974a6, 0x8bbf2649, 0xe962a0a3, 0x08d4f24c, - 0x782c2e94, 0x999a7c7b, 0xfb47fa91, 0x1af1a87e, 0x7efb869f, - 0x9f4dd470, 0xfd90529a, 0x1c260075, 0x74827f83, 0x95342d6c, - 0xf7e9ab86, 0x165ff969, 0x7255d788, 0x93e38567, 0xf13e038d, - 0x10885162, 0x50c8cbe7, 0xb17e9908, 0xd3a31fe2, 0x32154d0d, - 0x561f63ec, 0xb7a93103, 0xd574b7e9, 0x34c2e506, 0x5c669af0, - 0xbdd0c81f, 0xdf0d4ef5, 0x3ebb1c1a, 0x5ab132fb, 0xbb076014, - 0xd9dae6fe, 0x386cb411, 0x489468c9, 0xa9223a26, 0xcbffbccc, - 0x2a49ee23, 0x4e43c0c2, 0xaff5922d, 0xcd2814c7, 0x2c9e4628, - 0x443a39de, 0xa58c6b31, 0xc751eddb, 0x26e7bf34, 0x42ed91d5, - 0xa35bc33a, 0xc18645d0, 0x2030173f, 0x81e66bae, 0x60503941, - 0x028dbfab, 0xe33bed44, 0x8731c3a5, 0x6687914a, 0x045a17a0, - 0xe5ec454f, 0x8d483ab9, 0x6cfe6856, 0x0e23eebc, 0xef95bc53, - 0x8b9f92b2, 0x6a29c05d, 0x08f446b7, 0xe9421458, 0x99bac880, - 0x780c9a6f, 0x1ad11c85, 0xfb674e6a, 0x9f6d608b, 0x7edb3264, - 0x1c06b48e, 0xfdb0e661, 0x95149997, 0x74a2cb78, 0x167f4d92, - 0xf7c91f7d, 0x93c3319c, 0x72756373, 0x10a8e599, 0xf11eb776, - 0xb15e2df3, 0x50e87f1c, 0x3235f9f6, 0xd383ab19, 0xb78985f8, - 0x563fd717, 0x34e251fd, 0xd5540312, 0xbdf07ce4, 0x5c462e0b, - 0x3e9ba8e1, 0xdf2dfa0e, 0xbb27d4ef, 0x5a918600, 0x384c00ea, - 0xd9fa5205, 0xa9028edd, 0x48b4dc32, 0x2a695ad8, 0xcbdf0837, - 0xafd526d6, 0x4e637439, 0x2cbef2d3, 0xcd08a03c, 0xa5acdfca, - 0x441a8d25, 0x26c70bcf, 0xc7715920, 0xa37b77c1, 0x42cd252e, - 0x2010a3c4, 0xc1a6f12b, 0xe196e614, 0x0020b4fb, 0x62fd3211, - 0x834b60fe, 0xe7414e1f, 0x06f71cf0, 0x642a9a1a, 0x859cc8f5, - 0xed38b703, 0x0c8ee5ec, 0x6e536306, 0x8fe531e9, 0xebef1f08, - 0x0a594de7, 0x6884cb0d, 0x893299e2, 0xf9ca453a, 0x187c17d5, - 0x7aa1913f, 0x9b17c3d0, 0xff1ded31, 0x1eabbfde, 0x7c763934, - 0x9dc06bdb, 0xf564142d, 0x14d246c2, 0x760fc028, 0x97b992c7, - 0xf3b3bc26, 0x1205eec9, 0x70d86823, 0x916e3acc, 0xd12ea049, - 0x3098f2a6, 0x5245744c, 0xb3f326a3, 0xd7f90842, 0x364f5aad, - 0x5492dc47, 0xb5248ea8, 0xdd80f15e, 0x3c36a3b1, 0x5eeb255b, - 0xbf5d77b4, 0xdb575955, 0x3ae10bba, 0x583c8d50, 0xb98adfbf, - 0xc9720367, 0x28c45188, 0x4a19d762, 0xabaf858d, 0xcfa5ab6c, - 0x2e13f983, 0x4cce7f69, 0xad782d86, 0xc5dc5270, 0x246a009f, - 0x46b78675, 0xa701d49a, 0xc30bfa7b, 0x22bda894, 0x40602e7e, - 0xa1d67c91}, - {0x00000000, 0x5880e2d7, 0xf106b474, 0xa98656a3, 0xe20d68e9, - 0xba8d8a3e, 0x130bdc9d, 0x4b8b3e4a, 0x851da109, 0xdd9d43de, - 0x741b157d, 0x2c9bf7aa, 0x6710c9e0, 0x3f902b37, 0x96167d94, - 0xce969f43, 0x0a3b4213, 0x52bba0c4, 0xfb3df667, 0xa3bd14b0, - 0xe8362afa, 0xb0b6c82d, 0x19309e8e, 0x41b07c59, 0x8f26e31a, - 0xd7a601cd, 0x7e20576e, 0x26a0b5b9, 0x6d2b8bf3, 0x35ab6924, - 0x9c2d3f87, 0xc4addd50, 0x14768426, 0x4cf666f1, 0xe5703052, - 0xbdf0d285, 0xf67beccf, 0xaefb0e18, 0x077d58bb, 0x5ffdba6c, - 0x916b252f, 0xc9ebc7f8, 0x606d915b, 0x38ed738c, 0x73664dc6, - 0x2be6af11, 0x8260f9b2, 0xdae01b65, 0x1e4dc635, 0x46cd24e2, - 0xef4b7241, 0xb7cb9096, 0xfc40aedc, 0xa4c04c0b, 0x0d461aa8, - 0x55c6f87f, 0x9b50673c, 0xc3d085eb, 0x6a56d348, 0x32d6319f, - 0x795d0fd5, 0x21dded02, 0x885bbba1, 0xd0db5976, 0x28ec084d, - 0x706cea9a, 0xd9eabc39, 0x816a5eee, 0xcae160a4, 0x92618273, - 0x3be7d4d0, 0x63673607, 0xadf1a944, 0xf5714b93, 0x5cf71d30, - 0x0477ffe7, 0x4ffcc1ad, 0x177c237a, 0xbefa75d9, 0xe67a970e, - 0x22d74a5e, 0x7a57a889, 0xd3d1fe2a, 0x8b511cfd, 0xc0da22b7, - 0x985ac060, 0x31dc96c3, 0x695c7414, 0xa7caeb57, 0xff4a0980, - 0x56cc5f23, 0x0e4cbdf4, 0x45c783be, 0x1d476169, 0xb4c137ca, - 0xec41d51d, 0x3c9a8c6b, 0x641a6ebc, 0xcd9c381f, 0x951cdac8, - 0xde97e482, 0x86170655, 0x2f9150f6, 0x7711b221, 0xb9872d62, - 0xe107cfb5, 0x48819916, 0x10017bc1, 0x5b8a458b, 0x030aa75c, - 0xaa8cf1ff, 0xf20c1328, 0x36a1ce78, 0x6e212caf, 0xc7a77a0c, - 0x9f2798db, 0xd4aca691, 0x8c2c4446, 0x25aa12e5, 0x7d2af032, - 0xb3bc6f71, 0xeb3c8da6, 0x42badb05, 0x1a3a39d2, 0x51b10798, - 0x0931e54f, 0xa0b7b3ec, 0xf837513b, 0x50d8119a, 0x0858f34d, - 0xa1dea5ee, 0xf95e4739, 0xb2d57973, 0xea559ba4, 0x43d3cd07, - 0x1b532fd0, 0xd5c5b093, 0x8d455244, 0x24c304e7, 0x7c43e630, - 0x37c8d87a, 0x6f483aad, 0xc6ce6c0e, 0x9e4e8ed9, 0x5ae35389, - 0x0263b15e, 0xabe5e7fd, 0xf365052a, 0xb8ee3b60, 0xe06ed9b7, - 0x49e88f14, 0x11686dc3, 0xdffef280, 0x877e1057, 0x2ef846f4, - 0x7678a423, 0x3df39a69, 0x657378be, 0xccf52e1d, 0x9475ccca, - 0x44ae95bc, 0x1c2e776b, 0xb5a821c8, 0xed28c31f, 0xa6a3fd55, - 0xfe231f82, 0x57a54921, 0x0f25abf6, 0xc1b334b5, 0x9933d662, - 0x30b580c1, 0x68356216, 0x23be5c5c, 0x7b3ebe8b, 0xd2b8e828, - 0x8a380aff, 0x4e95d7af, 0x16153578, 0xbf9363db, 0xe713810c, - 0xac98bf46, 0xf4185d91, 0x5d9e0b32, 0x051ee9e5, 0xcb8876a6, - 0x93089471, 0x3a8ec2d2, 0x620e2005, 0x29851e4f, 0x7105fc98, - 0xd883aa3b, 0x800348ec, 0x783419d7, 0x20b4fb00, 0x8932ada3, - 0xd1b24f74, 0x9a39713e, 0xc2b993e9, 0x6b3fc54a, 0x33bf279d, - 0xfd29b8de, 0xa5a95a09, 0x0c2f0caa, 0x54afee7d, 0x1f24d037, - 0x47a432e0, 0xee226443, 0xb6a28694, 0x720f5bc4, 0x2a8fb913, - 0x8309efb0, 0xdb890d67, 0x9002332d, 0xc882d1fa, 0x61048759, - 0x3984658e, 0xf712facd, 0xaf92181a, 0x06144eb9, 0x5e94ac6e, - 0x151f9224, 0x4d9f70f3, 0xe4192650, 0xbc99c487, 0x6c429df1, - 0x34c27f26, 0x9d442985, 0xc5c4cb52, 0x8e4ff518, 0xd6cf17cf, - 0x7f49416c, 0x27c9a3bb, 0xe95f3cf8, 0xb1dfde2f, 0x1859888c, - 0x40d96a5b, 0x0b525411, 0x53d2b6c6, 0xfa54e065, 0xa2d402b2, - 0x6679dfe2, 0x3ef93d35, 0x977f6b96, 0xcfff8941, 0x8474b70b, - 0xdcf455dc, 0x7572037f, 0x2df2e1a8, 0xe3647eeb, 0xbbe49c3c, - 0x1262ca9f, 0x4ae22848, 0x01691602, 0x59e9f4d5, 0xf06fa276, - 0xa8ef40a1}, - {0x00000000, 0x463b6765, 0x8c76ceca, 0xca4da9af, 0x59ebed4e, - 0x1fd08a2b, 0xd59d2384, 0x93a644e1, 0xb2d6db9d, 0xf4edbcf8, - 0x3ea01557, 0x789b7232, 0xeb3d36d3, 0xad0651b6, 0x674bf819, - 0x21709f7c, 0x25abc6e0, 0x6390a185, 0xa9dd082a, 0xefe66f4f, - 0x7c402bae, 0x3a7b4ccb, 0xf036e564, 0xb60d8201, 0x977d1d7d, - 0xd1467a18, 0x1b0bd3b7, 0x5d30b4d2, 0xce96f033, 0x88ad9756, - 0x42e03ef9, 0x04db599c, 0x0b50fc1a, 0x4d6b9b7f, 0x872632d0, - 0xc11d55b5, 0x52bb1154, 0x14807631, 0xdecddf9e, 0x98f6b8fb, - 0xb9862787, 0xffbd40e2, 0x35f0e94d, 0x73cb8e28, 0xe06dcac9, - 0xa656adac, 0x6c1b0403, 0x2a206366, 0x2efb3afa, 0x68c05d9f, - 0xa28df430, 0xe4b69355, 0x7710d7b4, 0x312bb0d1, 0xfb66197e, - 0xbd5d7e1b, 0x9c2de167, 0xda168602, 0x105b2fad, 0x566048c8, - 0xc5c60c29, 0x83fd6b4c, 0x49b0c2e3, 0x0f8ba586, 0x16a0f835, - 0x509b9f50, 0x9ad636ff, 0xdced519a, 0x4f4b157b, 0x0970721e, - 0xc33ddbb1, 0x8506bcd4, 0xa47623a8, 0xe24d44cd, 0x2800ed62, - 0x6e3b8a07, 0xfd9dcee6, 0xbba6a983, 0x71eb002c, 0x37d06749, - 0x330b3ed5, 0x753059b0, 0xbf7df01f, 0xf946977a, 0x6ae0d39b, - 0x2cdbb4fe, 0xe6961d51, 0xa0ad7a34, 0x81dde548, 0xc7e6822d, - 0x0dab2b82, 0x4b904ce7, 0xd8360806, 0x9e0d6f63, 0x5440c6cc, - 0x127ba1a9, 0x1df0042f, 0x5bcb634a, 0x9186cae5, 0xd7bdad80, - 0x441be961, 0x02208e04, 0xc86d27ab, 0x8e5640ce, 0xaf26dfb2, - 0xe91db8d7, 0x23501178, 0x656b761d, 0xf6cd32fc, 0xb0f65599, - 0x7abbfc36, 0x3c809b53, 0x385bc2cf, 0x7e60a5aa, 0xb42d0c05, - 0xf2166b60, 0x61b02f81, 0x278b48e4, 0xedc6e14b, 0xabfd862e, - 0x8a8d1952, 0xccb67e37, 0x06fbd798, 0x40c0b0fd, 0xd366f41c, - 0x955d9379, 0x5f103ad6, 0x192b5db3, 0x2c40f16b, 0x6a7b960e, - 0xa0363fa1, 0xe60d58c4, 0x75ab1c25, 0x33907b40, 0xf9ddd2ef, - 0xbfe6b58a, 0x9e962af6, 0xd8ad4d93, 0x12e0e43c, 0x54db8359, - 0xc77dc7b8, 0x8146a0dd, 0x4b0b0972, 0x0d306e17, 0x09eb378b, - 0x4fd050ee, 0x859df941, 0xc3a69e24, 0x5000dac5, 0x163bbda0, - 0xdc76140f, 0x9a4d736a, 0xbb3dec16, 0xfd068b73, 0x374b22dc, - 0x717045b9, 0xe2d60158, 0xa4ed663d, 0x6ea0cf92, 0x289ba8f7, - 0x27100d71, 0x612b6a14, 0xab66c3bb, 0xed5da4de, 0x7efbe03f, - 0x38c0875a, 0xf28d2ef5, 0xb4b64990, 0x95c6d6ec, 0xd3fdb189, - 0x19b01826, 0x5f8b7f43, 0xcc2d3ba2, 0x8a165cc7, 0x405bf568, - 0x0660920d, 0x02bbcb91, 0x4480acf4, 0x8ecd055b, 0xc8f6623e, - 0x5b5026df, 0x1d6b41ba, 0xd726e815, 0x911d8f70, 0xb06d100c, - 0xf6567769, 0x3c1bdec6, 0x7a20b9a3, 0xe986fd42, 0xafbd9a27, - 0x65f03388, 0x23cb54ed, 0x3ae0095e, 0x7cdb6e3b, 0xb696c794, - 0xf0ada0f1, 0x630be410, 0x25308375, 0xef7d2ada, 0xa9464dbf, - 0x8836d2c3, 0xce0db5a6, 0x04401c09, 0x427b7b6c, 0xd1dd3f8d, - 0x97e658e8, 0x5dabf147, 0x1b909622, 0x1f4bcfbe, 0x5970a8db, - 0x933d0174, 0xd5066611, 0x46a022f0, 0x009b4595, 0xcad6ec3a, - 0x8ced8b5f, 0xad9d1423, 0xeba67346, 0x21ebdae9, 0x67d0bd8c, - 0xf476f96d, 0xb24d9e08, 0x780037a7, 0x3e3b50c2, 0x31b0f544, - 0x778b9221, 0xbdc63b8e, 0xfbfd5ceb, 0x685b180a, 0x2e607f6f, - 0xe42dd6c0, 0xa216b1a5, 0x83662ed9, 0xc55d49bc, 0x0f10e013, - 0x492b8776, 0xda8dc397, 0x9cb6a4f2, 0x56fb0d5d, 0x10c06a38, - 0x141b33a4, 0x522054c1, 0x986dfd6e, 0xde569a0b, 0x4df0deea, - 0x0bcbb98f, 0xc1861020, 0x87bd7745, 0xa6cde839, 0xe0f68f5c, - 0x2abb26f3, 0x6c804196, 0xff260577, 0xb91d6212, 0x7350cbbd, - 0x356bacd8}}; - -#endif - -#endif - -#if N == 6 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x3db1ecdc, 0x7b63d9b8, 0x46d23564, 0xf6c7b370, - 0xcb765fac, 0x8da46ac8, 0xb0158614, 0x36fe60a1, 0x0b4f8c7d, - 0x4d9db919, 0x702c55c5, 0xc039d3d1, 0xfd883f0d, 0xbb5a0a69, - 0x86ebe6b5, 0x6dfcc142, 0x504d2d9e, 0x169f18fa, 0x2b2ef426, - 0x9b3b7232, 0xa68a9eee, 0xe058ab8a, 0xdde94756, 0x5b02a1e3, - 0x66b34d3f, 0x2061785b, 0x1dd09487, 0xadc51293, 0x9074fe4f, - 0xd6a6cb2b, 0xeb1727f7, 0xdbf98284, 0xe6486e58, 0xa09a5b3c, - 0x9d2bb7e0, 0x2d3e31f4, 0x108fdd28, 0x565de84c, 0x6bec0490, - 0xed07e225, 0xd0b60ef9, 0x96643b9d, 0xabd5d741, 0x1bc05155, - 0x2671bd89, 0x60a388ed, 0x5d126431, 0xb60543c6, 0x8bb4af1a, - 0xcd669a7e, 0xf0d776a2, 0x40c2f0b6, 0x7d731c6a, 0x3ba1290e, - 0x0610c5d2, 0x80fb2367, 0xbd4acfbb, 0xfb98fadf, 0xc6291603, - 0x763c9017, 0x4b8d7ccb, 0x0d5f49af, 0x30eea573, 0x6c820349, - 0x5133ef95, 0x17e1daf1, 0x2a50362d, 0x9a45b039, 0xa7f45ce5, - 0xe1266981, 0xdc97855d, 0x5a7c63e8, 0x67cd8f34, 0x211fba50, - 0x1cae568c, 0xacbbd098, 0x910a3c44, 0xd7d80920, 0xea69e5fc, - 0x017ec20b, 0x3ccf2ed7, 0x7a1d1bb3, 0x47acf76f, 0xf7b9717b, - 0xca089da7, 0x8cdaa8c3, 0xb16b441f, 0x3780a2aa, 0x0a314e76, - 0x4ce37b12, 0x715297ce, 0xc14711da, 0xfcf6fd06, 0xba24c862, - 0x879524be, 0xb77b81cd, 0x8aca6d11, 0xcc185875, 0xf1a9b4a9, - 0x41bc32bd, 0x7c0dde61, 0x3adfeb05, 0x076e07d9, 0x8185e16c, - 0xbc340db0, 0xfae638d4, 0xc757d408, 0x7742521c, 0x4af3bec0, - 0x0c218ba4, 0x31906778, 0xda87408f, 0xe736ac53, 0xa1e49937, - 0x9c5575eb, 0x2c40f3ff, 0x11f11f23, 0x57232a47, 0x6a92c69b, - 0xec79202e, 0xd1c8ccf2, 0x971af996, 0xaaab154a, 0x1abe935e, - 0x270f7f82, 0x61dd4ae6, 0x5c6ca63a, 0xd9040692, 0xe4b5ea4e, - 0xa267df2a, 0x9fd633f6, 0x2fc3b5e2, 0x1272593e, 0x54a06c5a, - 0x69118086, 0xeffa6633, 0xd24b8aef, 0x9499bf8b, 0xa9285357, - 0x193dd543, 0x248c399f, 0x625e0cfb, 0x5fefe027, 0xb4f8c7d0, - 0x89492b0c, 0xcf9b1e68, 0xf22af2b4, 0x423f74a0, 0x7f8e987c, - 0x395cad18, 0x04ed41c4, 0x8206a771, 0xbfb74bad, 0xf9657ec9, - 0xc4d49215, 0x74c11401, 0x4970f8dd, 0x0fa2cdb9, 0x32132165, - 0x02fd8416, 0x3f4c68ca, 0x799e5dae, 0x442fb172, 0xf43a3766, - 0xc98bdbba, 0x8f59eede, 0xb2e80202, 0x3403e4b7, 0x09b2086b, - 0x4f603d0f, 0x72d1d1d3, 0xc2c457c7, 0xff75bb1b, 0xb9a78e7f, - 0x841662a3, 0x6f014554, 0x52b0a988, 0x14629cec, 0x29d37030, - 0x99c6f624, 0xa4771af8, 0xe2a52f9c, 0xdf14c340, 0x59ff25f5, - 0x644ec929, 0x229cfc4d, 0x1f2d1091, 0xaf389685, 0x92897a59, - 0xd45b4f3d, 0xe9eaa3e1, 0xb58605db, 0x8837e907, 0xcee5dc63, - 0xf35430bf, 0x4341b6ab, 0x7ef05a77, 0x38226f13, 0x059383cf, - 0x8378657a, 0xbec989a6, 0xf81bbcc2, 0xc5aa501e, 0x75bfd60a, - 0x480e3ad6, 0x0edc0fb2, 0x336de36e, 0xd87ac499, 0xe5cb2845, - 0xa3191d21, 0x9ea8f1fd, 0x2ebd77e9, 0x130c9b35, 0x55deae51, - 0x686f428d, 0xee84a438, 0xd33548e4, 0x95e77d80, 0xa856915c, - 0x18431748, 0x25f2fb94, 0x6320cef0, 0x5e91222c, 0x6e7f875f, - 0x53ce6b83, 0x151c5ee7, 0x28adb23b, 0x98b8342f, 0xa509d8f3, - 0xe3dbed97, 0xde6a014b, 0x5881e7fe, 0x65300b22, 0x23e23e46, - 0x1e53d29a, 0xae46548e, 0x93f7b852, 0xd5258d36, 0xe89461ea, - 0x0383461d, 0x3e32aac1, 0x78e09fa5, 0x45517379, 0xf544f56d, - 0xc8f519b1, 0x8e272cd5, 0xb396c009, 0x357d26bc, 0x08ccca60, - 0x4e1eff04, 0x73af13d8, 0xc3ba95cc, 0xfe0b7910, 0xb8d94c74, - 0x8568a0a8}, - {0x00000000, 0x69790b65, 0xd2f216ca, 0xbb8b1daf, 0x7e952bd5, - 0x17ec20b0, 0xac673d1f, 0xc51e367a, 0xfd2a57aa, 0x94535ccf, - 0x2fd84160, 0x46a14a05, 0x83bf7c7f, 0xeac6771a, 0x514d6ab5, - 0x383461d0, 0x2125a915, 0x485ca270, 0xf3d7bfdf, 0x9aaeb4ba, - 0x5fb082c0, 0x36c989a5, 0x8d42940a, 0xe43b9f6f, 0xdc0ffebf, - 0xb576f5da, 0x0efde875, 0x6784e310, 0xa29ad56a, 0xcbe3de0f, - 0x7068c3a0, 0x1911c8c5, 0x424b522a, 0x2b32594f, 0x90b944e0, - 0xf9c04f85, 0x3cde79ff, 0x55a7729a, 0xee2c6f35, 0x87556450, - 0xbf610580, 0xd6180ee5, 0x6d93134a, 0x04ea182f, 0xc1f42e55, - 0xa88d2530, 0x1306389f, 0x7a7f33fa, 0x636efb3f, 0x0a17f05a, - 0xb19cedf5, 0xd8e5e690, 0x1dfbd0ea, 0x7482db8f, 0xcf09c620, - 0xa670cd45, 0x9e44ac95, 0xf73da7f0, 0x4cb6ba5f, 0x25cfb13a, - 0xe0d18740, 0x89a88c25, 0x3223918a, 0x5b5a9aef, 0x8496a454, - 0xedefaf31, 0x5664b29e, 0x3f1db9fb, 0xfa038f81, 0x937a84e4, - 0x28f1994b, 0x4188922e, 0x79bcf3fe, 0x10c5f89b, 0xab4ee534, - 0xc237ee51, 0x0729d82b, 0x6e50d34e, 0xd5dbcee1, 0xbca2c584, - 0xa5b30d41, 0xccca0624, 0x77411b8b, 0x1e3810ee, 0xdb262694, - 0xb25f2df1, 0x09d4305e, 0x60ad3b3b, 0x58995aeb, 0x31e0518e, - 0x8a6b4c21, 0xe3124744, 0x260c713e, 0x4f757a5b, 0xf4fe67f4, - 0x9d876c91, 0xc6ddf67e, 0xafa4fd1b, 0x142fe0b4, 0x7d56ebd1, - 0xb848ddab, 0xd131d6ce, 0x6abacb61, 0x03c3c004, 0x3bf7a1d4, - 0x528eaab1, 0xe905b71e, 0x807cbc7b, 0x45628a01, 0x2c1b8164, - 0x97909ccb, 0xfee997ae, 0xe7f85f6b, 0x8e81540e, 0x350a49a1, - 0x5c7342c4, 0x996d74be, 0xf0147fdb, 0x4b9f6274, 0x22e66911, - 0x1ad208c1, 0x73ab03a4, 0xc8201e0b, 0xa159156e, 0x64472314, - 0x0d3e2871, 0xb6b535de, 0xdfcc3ebb, 0xd25c4ee9, 0xbb25458c, - 0x00ae5823, 0x69d75346, 0xacc9653c, 0xc5b06e59, 0x7e3b73f6, - 0x17427893, 0x2f761943, 0x460f1226, 0xfd840f89, 0x94fd04ec, - 0x51e33296, 0x389a39f3, 0x8311245c, 0xea682f39, 0xf379e7fc, - 0x9a00ec99, 0x218bf136, 0x48f2fa53, 0x8deccc29, 0xe495c74c, - 0x5f1edae3, 0x3667d186, 0x0e53b056, 0x672abb33, 0xdca1a69c, - 0xb5d8adf9, 0x70c69b83, 0x19bf90e6, 0xa2348d49, 0xcb4d862c, - 0x90171cc3, 0xf96e17a6, 0x42e50a09, 0x2b9c016c, 0xee823716, - 0x87fb3c73, 0x3c7021dc, 0x55092ab9, 0x6d3d4b69, 0x0444400c, - 0xbfcf5da3, 0xd6b656c6, 0x13a860bc, 0x7ad16bd9, 0xc15a7676, - 0xa8237d13, 0xb132b5d6, 0xd84bbeb3, 0x63c0a31c, 0x0ab9a879, - 0xcfa79e03, 0xa6de9566, 0x1d5588c9, 0x742c83ac, 0x4c18e27c, - 0x2561e919, 0x9eeaf4b6, 0xf793ffd3, 0x328dc9a9, 0x5bf4c2cc, - 0xe07fdf63, 0x8906d406, 0x56caeabd, 0x3fb3e1d8, 0x8438fc77, - 0xed41f712, 0x285fc168, 0x4126ca0d, 0xfaadd7a2, 0x93d4dcc7, - 0xabe0bd17, 0xc299b672, 0x7912abdd, 0x106ba0b8, 0xd57596c2, - 0xbc0c9da7, 0x07878008, 0x6efe8b6d, 0x77ef43a8, 0x1e9648cd, - 0xa51d5562, 0xcc645e07, 0x097a687d, 0x60036318, 0xdb887eb7, - 0xb2f175d2, 0x8ac51402, 0xe3bc1f67, 0x583702c8, 0x314e09ad, - 0xf4503fd7, 0x9d2934b2, 0x26a2291d, 0x4fdb2278, 0x1481b897, - 0x7df8b3f2, 0xc673ae5d, 0xaf0aa538, 0x6a149342, 0x036d9827, - 0xb8e68588, 0xd19f8eed, 0xe9abef3d, 0x80d2e458, 0x3b59f9f7, - 0x5220f292, 0x973ec4e8, 0xfe47cf8d, 0x45ccd222, 0x2cb5d947, - 0x35a41182, 0x5cdd1ae7, 0xe7560748, 0x8e2f0c2d, 0x4b313a57, - 0x22483132, 0x99c32c9d, 0xf0ba27f8, 0xc88e4628, 0xa1f74d4d, - 0x1a7c50e2, 0x73055b87, 0xb61b6dfd, 0xdf626698, 0x64e97b37, - 0x0d907052}, - {0x00000000, 0x7fc99b93, 0xff933726, 0x805aacb5, 0x2457680d, - 0x5b9ef39e, 0xdbc45f2b, 0xa40dc4b8, 0x48aed01a, 0x37674b89, - 0xb73de73c, 0xc8f47caf, 0x6cf9b817, 0x13302384, 0x936a8f31, - 0xeca314a2, 0x915da034, 0xee943ba7, 0x6ece9712, 0x11070c81, - 0xb50ac839, 0xcac353aa, 0x4a99ff1f, 0x3550648c, 0xd9f3702e, - 0xa63aebbd, 0x26604708, 0x59a9dc9b, 0xfda41823, 0x826d83b0, - 0x02372f05, 0x7dfeb496, 0xf9ca4629, 0x8603ddba, 0x0659710f, - 0x7990ea9c, 0xdd9d2e24, 0xa254b5b7, 0x220e1902, 0x5dc78291, - 0xb1649633, 0xcead0da0, 0x4ef7a115, 0x313e3a86, 0x9533fe3e, - 0xeafa65ad, 0x6aa0c918, 0x1569528b, 0x6897e61d, 0x175e7d8e, - 0x9704d13b, 0xe8cd4aa8, 0x4cc08e10, 0x33091583, 0xb353b936, - 0xcc9a22a5, 0x20393607, 0x5ff0ad94, 0xdfaa0121, 0xa0639ab2, - 0x046e5e0a, 0x7ba7c599, 0xfbfd692c, 0x8434f2bf, 0x28e58a13, - 0x572c1180, 0xd776bd35, 0xa8bf26a6, 0x0cb2e21e, 0x737b798d, - 0xf321d538, 0x8ce84eab, 0x604b5a09, 0x1f82c19a, 0x9fd86d2f, - 0xe011f6bc, 0x441c3204, 0x3bd5a997, 0xbb8f0522, 0xc4469eb1, - 0xb9b82a27, 0xc671b1b4, 0x462b1d01, 0x39e28692, 0x9def422a, - 0xe226d9b9, 0x627c750c, 0x1db5ee9f, 0xf116fa3d, 0x8edf61ae, - 0x0e85cd1b, 0x714c5688, 0xd5419230, 0xaa8809a3, 0x2ad2a516, - 0x551b3e85, 0xd12fcc3a, 0xaee657a9, 0x2ebcfb1c, 0x5175608f, - 0xf578a437, 0x8ab13fa4, 0x0aeb9311, 0x75220882, 0x99811c20, - 0xe64887b3, 0x66122b06, 0x19dbb095, 0xbdd6742d, 0xc21fefbe, - 0x4245430b, 0x3d8cd898, 0x40726c0e, 0x3fbbf79d, 0xbfe15b28, - 0xc028c0bb, 0x64250403, 0x1bec9f90, 0x9bb63325, 0xe47fa8b6, - 0x08dcbc14, 0x77152787, 0xf74f8b32, 0x888610a1, 0x2c8bd419, - 0x53424f8a, 0xd318e33f, 0xacd178ac, 0x51cb1426, 0x2e028fb5, - 0xae582300, 0xd191b893, 0x759c7c2b, 0x0a55e7b8, 0x8a0f4b0d, - 0xf5c6d09e, 0x1965c43c, 0x66ac5faf, 0xe6f6f31a, 0x993f6889, - 0x3d32ac31, 0x42fb37a2, 0xc2a19b17, 0xbd680084, 0xc096b412, - 0xbf5f2f81, 0x3f058334, 0x40cc18a7, 0xe4c1dc1f, 0x9b08478c, - 0x1b52eb39, 0x649b70aa, 0x88386408, 0xf7f1ff9b, 0x77ab532e, - 0x0862c8bd, 0xac6f0c05, 0xd3a69796, 0x53fc3b23, 0x2c35a0b0, - 0xa801520f, 0xd7c8c99c, 0x57926529, 0x285bfeba, 0x8c563a02, - 0xf39fa191, 0x73c50d24, 0x0c0c96b7, 0xe0af8215, 0x9f661986, - 0x1f3cb533, 0x60f52ea0, 0xc4f8ea18, 0xbb31718b, 0x3b6bdd3e, - 0x44a246ad, 0x395cf23b, 0x469569a8, 0xc6cfc51d, 0xb9065e8e, - 0x1d0b9a36, 0x62c201a5, 0xe298ad10, 0x9d513683, 0x71f22221, - 0x0e3bb9b2, 0x8e611507, 0xf1a88e94, 0x55a54a2c, 0x2a6cd1bf, - 0xaa367d0a, 0xd5ffe699, 0x792e9e35, 0x06e705a6, 0x86bda913, - 0xf9743280, 0x5d79f638, 0x22b06dab, 0xa2eac11e, 0xdd235a8d, - 0x31804e2f, 0x4e49d5bc, 0xce137909, 0xb1dae29a, 0x15d72622, - 0x6a1ebdb1, 0xea441104, 0x958d8a97, 0xe8733e01, 0x97baa592, - 0x17e00927, 0x682992b4, 0xcc24560c, 0xb3edcd9f, 0x33b7612a, - 0x4c7efab9, 0xa0ddee1b, 0xdf147588, 0x5f4ed93d, 0x208742ae, - 0x848a8616, 0xfb431d85, 0x7b19b130, 0x04d02aa3, 0x80e4d81c, - 0xff2d438f, 0x7f77ef3a, 0x00be74a9, 0xa4b3b011, 0xdb7a2b82, - 0x5b208737, 0x24e91ca4, 0xc84a0806, 0xb7839395, 0x37d93f20, - 0x4810a4b3, 0xec1d600b, 0x93d4fb98, 0x138e572d, 0x6c47ccbe, - 0x11b97828, 0x6e70e3bb, 0xee2a4f0e, 0x91e3d49d, 0x35ee1025, - 0x4a278bb6, 0xca7d2703, 0xb5b4bc90, 0x5917a832, 0x26de33a1, - 0xa6849f14, 0xd94d0487, 0x7d40c03f, 0x02895bac, 0x82d3f719, - 0xfd1a6c8a}, - {0x00000000, 0xa396284c, 0x9c5d56d9, 0x3fcb7e95, 0xe3cbabf3, - 0x405d83bf, 0x7f96fd2a, 0xdc00d566, 0x1ce651a7, 0xbf7079eb, - 0x80bb077e, 0x232d2f32, 0xff2dfa54, 0x5cbbd218, 0x6370ac8d, - 0xc0e684c1, 0x39cca34e, 0x9a5a8b02, 0xa591f597, 0x0607dddb, - 0xda0708bd, 0x799120f1, 0x465a5e64, 0xe5cc7628, 0x252af2e9, - 0x86bcdaa5, 0xb977a430, 0x1ae18c7c, 0xc6e1591a, 0x65777156, - 0x5abc0fc3, 0xf92a278f, 0x7399469c, 0xd00f6ed0, 0xefc41045, - 0x4c523809, 0x9052ed6f, 0x33c4c523, 0x0c0fbbb6, 0xaf9993fa, - 0x6f7f173b, 0xcce93f77, 0xf32241e2, 0x50b469ae, 0x8cb4bcc8, - 0x2f229484, 0x10e9ea11, 0xb37fc25d, 0x4a55e5d2, 0xe9c3cd9e, - 0xd608b30b, 0x759e9b47, 0xa99e4e21, 0x0a08666d, 0x35c318f8, - 0x965530b4, 0x56b3b475, 0xf5259c39, 0xcaeee2ac, 0x6978cae0, - 0xb5781f86, 0x16ee37ca, 0x2925495f, 0x8ab36113, 0xe7328d38, - 0x44a4a574, 0x7b6fdbe1, 0xd8f9f3ad, 0x04f926cb, 0xa76f0e87, - 0x98a47012, 0x3b32585e, 0xfbd4dc9f, 0x5842f4d3, 0x67898a46, - 0xc41fa20a, 0x181f776c, 0xbb895f20, 0x844221b5, 0x27d409f9, - 0xdefe2e76, 0x7d68063a, 0x42a378af, 0xe13550e3, 0x3d358585, - 0x9ea3adc9, 0xa168d35c, 0x02fefb10, 0xc2187fd1, 0x618e579d, - 0x5e452908, 0xfdd30144, 0x21d3d422, 0x8245fc6e, 0xbd8e82fb, - 0x1e18aab7, 0x94abcba4, 0x373de3e8, 0x08f69d7d, 0xab60b531, - 0x77606057, 0xd4f6481b, 0xeb3d368e, 0x48ab1ec2, 0x884d9a03, - 0x2bdbb24f, 0x1410ccda, 0xb786e496, 0x6b8631f0, 0xc81019bc, - 0xf7db6729, 0x544d4f65, 0xad6768ea, 0x0ef140a6, 0x313a3e33, - 0x92ac167f, 0x4eacc319, 0xed3aeb55, 0xd2f195c0, 0x7167bd8c, - 0xb181394d, 0x12171101, 0x2ddc6f94, 0x8e4a47d8, 0x524a92be, - 0xf1dcbaf2, 0xce17c467, 0x6d81ec2b, 0x15141c31, 0xb682347d, - 0x89494ae8, 0x2adf62a4, 0xf6dfb7c2, 0x55499f8e, 0x6a82e11b, - 0xc914c957, 0x09f24d96, 0xaa6465da, 0x95af1b4f, 0x36393303, - 0xea39e665, 0x49afce29, 0x7664b0bc, 0xd5f298f0, 0x2cd8bf7f, - 0x8f4e9733, 0xb085e9a6, 0x1313c1ea, 0xcf13148c, 0x6c853cc0, - 0x534e4255, 0xf0d86a19, 0x303eeed8, 0x93a8c694, 0xac63b801, - 0x0ff5904d, 0xd3f5452b, 0x70636d67, 0x4fa813f2, 0xec3e3bbe, - 0x668d5aad, 0xc51b72e1, 0xfad00c74, 0x59462438, 0x8546f15e, - 0x26d0d912, 0x191ba787, 0xba8d8fcb, 0x7a6b0b0a, 0xd9fd2346, - 0xe6365dd3, 0x45a0759f, 0x99a0a0f9, 0x3a3688b5, 0x05fdf620, - 0xa66bde6c, 0x5f41f9e3, 0xfcd7d1af, 0xc31caf3a, 0x608a8776, - 0xbc8a5210, 0x1f1c7a5c, 0x20d704c9, 0x83412c85, 0x43a7a844, - 0xe0318008, 0xdffafe9d, 0x7c6cd6d1, 0xa06c03b7, 0x03fa2bfb, - 0x3c31556e, 0x9fa77d22, 0xf2269109, 0x51b0b945, 0x6e7bc7d0, - 0xcdedef9c, 0x11ed3afa, 0xb27b12b6, 0x8db06c23, 0x2e26446f, - 0xeec0c0ae, 0x4d56e8e2, 0x729d9677, 0xd10bbe3b, 0x0d0b6b5d, - 0xae9d4311, 0x91563d84, 0x32c015c8, 0xcbea3247, 0x687c1a0b, - 0x57b7649e, 0xf4214cd2, 0x282199b4, 0x8bb7b1f8, 0xb47ccf6d, - 0x17eae721, 0xd70c63e0, 0x749a4bac, 0x4b513539, 0xe8c71d75, - 0x34c7c813, 0x9751e05f, 0xa89a9eca, 0x0b0cb686, 0x81bfd795, - 0x2229ffd9, 0x1de2814c, 0xbe74a900, 0x62747c66, 0xc1e2542a, - 0xfe292abf, 0x5dbf02f3, 0x9d598632, 0x3ecfae7e, 0x0104d0eb, - 0xa292f8a7, 0x7e922dc1, 0xdd04058d, 0xe2cf7b18, 0x41595354, - 0xb87374db, 0x1be55c97, 0x242e2202, 0x87b80a4e, 0x5bb8df28, - 0xf82ef764, 0xc7e589f1, 0x6473a1bd, 0xa495257c, 0x07030d30, - 0x38c873a5, 0x9b5e5be9, 0x475e8e8f, 0xe4c8a6c3, 0xdb03d856, - 0x7895f01a}, - {0x00000000, 0x2a283862, 0x545070c4, 0x7e7848a6, 0xa8a0e188, - 0x8288d9ea, 0xfcf0914c, 0xd6d8a92e, 0x8a30c551, 0xa018fd33, - 0xde60b595, 0xf4488df7, 0x229024d9, 0x08b81cbb, 0x76c0541d, - 0x5ce86c7f, 0xcf108ce3, 0xe538b481, 0x9b40fc27, 0xb168c445, - 0x67b06d6b, 0x4d985509, 0x33e01daf, 0x19c825cd, 0x452049b2, - 0x6f0871d0, 0x11703976, 0x3b580114, 0xed80a83a, 0xc7a89058, - 0xb9d0d8fe, 0x93f8e09c, 0x45501f87, 0x6f7827e5, 0x11006f43, - 0x3b285721, 0xedf0fe0f, 0xc7d8c66d, 0xb9a08ecb, 0x9388b6a9, - 0xcf60dad6, 0xe548e2b4, 0x9b30aa12, 0xb1189270, 0x67c03b5e, - 0x4de8033c, 0x33904b9a, 0x19b873f8, 0x8a409364, 0xa068ab06, - 0xde10e3a0, 0xf438dbc2, 0x22e072ec, 0x08c84a8e, 0x76b00228, - 0x5c983a4a, 0x00705635, 0x2a586e57, 0x542026f1, 0x7e081e93, - 0xa8d0b7bd, 0x82f88fdf, 0xfc80c779, 0xd6a8ff1b, 0x8aa03f0e, - 0xa088076c, 0xdef04fca, 0xf4d877a8, 0x2200de86, 0x0828e6e4, - 0x7650ae42, 0x5c789620, 0x0090fa5f, 0x2ab8c23d, 0x54c08a9b, - 0x7ee8b2f9, 0xa8301bd7, 0x821823b5, 0xfc606b13, 0xd6485371, - 0x45b0b3ed, 0x6f988b8f, 0x11e0c329, 0x3bc8fb4b, 0xed105265, - 0xc7386a07, 0xb94022a1, 0x93681ac3, 0xcf8076bc, 0xe5a84ede, - 0x9bd00678, 0xb1f83e1a, 0x67209734, 0x4d08af56, 0x3370e7f0, - 0x1958df92, 0xcff02089, 0xe5d818eb, 0x9ba0504d, 0xb188682f, - 0x6750c101, 0x4d78f963, 0x3300b1c5, 0x192889a7, 0x45c0e5d8, - 0x6fe8ddba, 0x1190951c, 0x3bb8ad7e, 0xed600450, 0xc7483c32, - 0xb9307494, 0x93184cf6, 0x00e0ac6a, 0x2ac89408, 0x54b0dcae, - 0x7e98e4cc, 0xa8404de2, 0x82687580, 0xfc103d26, 0xd6380544, - 0x8ad0693b, 0xa0f85159, 0xde8019ff, 0xf4a8219d, 0x227088b3, - 0x0858b0d1, 0x7620f877, 0x5c08c015, 0xce31785d, 0xe419403f, - 0x9a610899, 0xb04930fb, 0x669199d5, 0x4cb9a1b7, 0x32c1e911, - 0x18e9d173, 0x4401bd0c, 0x6e29856e, 0x1051cdc8, 0x3a79f5aa, - 0xeca15c84, 0xc68964e6, 0xb8f12c40, 0x92d91422, 0x0121f4be, - 0x2b09ccdc, 0x5571847a, 0x7f59bc18, 0xa9811536, 0x83a92d54, - 0xfdd165f2, 0xd7f95d90, 0x8b1131ef, 0xa139098d, 0xdf41412b, - 0xf5697949, 0x23b1d067, 0x0999e805, 0x77e1a0a3, 0x5dc998c1, - 0x8b6167da, 0xa1495fb8, 0xdf31171e, 0xf5192f7c, 0x23c18652, - 0x09e9be30, 0x7791f696, 0x5db9cef4, 0x0151a28b, 0x2b799ae9, - 0x5501d24f, 0x7f29ea2d, 0xa9f14303, 0x83d97b61, 0xfda133c7, - 0xd7890ba5, 0x4471eb39, 0x6e59d35b, 0x10219bfd, 0x3a09a39f, - 0xecd10ab1, 0xc6f932d3, 0xb8817a75, 0x92a94217, 0xce412e68, - 0xe469160a, 0x9a115eac, 0xb03966ce, 0x66e1cfe0, 0x4cc9f782, - 0x32b1bf24, 0x18998746, 0x44914753, 0x6eb97f31, 0x10c13797, - 0x3ae90ff5, 0xec31a6db, 0xc6199eb9, 0xb861d61f, 0x9249ee7d, - 0xcea18202, 0xe489ba60, 0x9af1f2c6, 0xb0d9caa4, 0x6601638a, - 0x4c295be8, 0x3251134e, 0x18792b2c, 0x8b81cbb0, 0xa1a9f3d2, - 0xdfd1bb74, 0xf5f98316, 0x23212a38, 0x0909125a, 0x77715afc, - 0x5d59629e, 0x01b10ee1, 0x2b993683, 0x55e17e25, 0x7fc94647, - 0xa911ef69, 0x8339d70b, 0xfd419fad, 0xd769a7cf, 0x01c158d4, - 0x2be960b6, 0x55912810, 0x7fb91072, 0xa961b95c, 0x8349813e, - 0xfd31c998, 0xd719f1fa, 0x8bf19d85, 0xa1d9a5e7, 0xdfa1ed41, - 0xf589d523, 0x23517c0d, 0x0979446f, 0x77010cc9, 0x5d2934ab, - 0xced1d437, 0xe4f9ec55, 0x9a81a4f3, 0xb0a99c91, 0x667135bf, - 0x4c590ddd, 0x3221457b, 0x18097d19, 0x44e11166, 0x6ec92904, - 0x10b161a2, 0x3a9959c0, 0xec41f0ee, 0xc669c88c, 0xb811802a, - 0x9239b848}, - {0x00000000, 0x4713f6fb, 0x8e27edf6, 0xc9341b0d, 0xc73eddad, - 0x802d2b56, 0x4919305b, 0x0e0ac6a0, 0x550cbd1b, 0x121f4be0, - 0xdb2b50ed, 0x9c38a616, 0x923260b6, 0xd521964d, 0x1c158d40, - 0x5b067bbb, 0xaa197a36, 0xed0a8ccd, 0x243e97c0, 0x632d613b, - 0x6d27a79b, 0x2a345160, 0xe3004a6d, 0xa413bc96, 0xff15c72d, - 0xb80631d6, 0x71322adb, 0x3621dc20, 0x382b1a80, 0x7f38ec7b, - 0xb60cf776, 0xf11f018d, 0x8f43f22d, 0xc85004d6, 0x01641fdb, - 0x4677e920, 0x487d2f80, 0x0f6ed97b, 0xc65ac276, 0x8149348d, - 0xda4f4f36, 0x9d5cb9cd, 0x5468a2c0, 0x137b543b, 0x1d71929b, - 0x5a626460, 0x93567f6d, 0xd4458996, 0x255a881b, 0x62497ee0, - 0xab7d65ed, 0xec6e9316, 0xe26455b6, 0xa577a34d, 0x6c43b840, - 0x2b504ebb, 0x70563500, 0x3745c3fb, 0xfe71d8f6, 0xb9622e0d, - 0xb768e8ad, 0xf07b1e56, 0x394f055b, 0x7e5cf3a0, 0xc5f6e21b, - 0x82e514e0, 0x4bd10fed, 0x0cc2f916, 0x02c83fb6, 0x45dbc94d, - 0x8cefd240, 0xcbfc24bb, 0x90fa5f00, 0xd7e9a9fb, 0x1eddb2f6, - 0x59ce440d, 0x57c482ad, 0x10d77456, 0xd9e36f5b, 0x9ef099a0, - 0x6fef982d, 0x28fc6ed6, 0xe1c875db, 0xa6db8320, 0xa8d14580, - 0xefc2b37b, 0x26f6a876, 0x61e55e8d, 0x3ae32536, 0x7df0d3cd, - 0xb4c4c8c0, 0xf3d73e3b, 0xfdddf89b, 0xbace0e60, 0x73fa156d, - 0x34e9e396, 0x4ab51036, 0x0da6e6cd, 0xc492fdc0, 0x83810b3b, - 0x8d8bcd9b, 0xca983b60, 0x03ac206d, 0x44bfd696, 0x1fb9ad2d, - 0x58aa5bd6, 0x919e40db, 0xd68db620, 0xd8877080, 0x9f94867b, - 0x56a09d76, 0x11b36b8d, 0xe0ac6a00, 0xa7bf9cfb, 0x6e8b87f6, - 0x2998710d, 0x2792b7ad, 0x60814156, 0xa9b55a5b, 0xeea6aca0, - 0xb5a0d71b, 0xf2b321e0, 0x3b873aed, 0x7c94cc16, 0x729e0ab6, - 0x358dfc4d, 0xfcb9e740, 0xbbaa11bb, 0x509cc277, 0x178f348c, - 0xdebb2f81, 0x99a8d97a, 0x97a21fda, 0xd0b1e921, 0x1985f22c, - 0x5e9604d7, 0x05907f6c, 0x42838997, 0x8bb7929a, 0xcca46461, - 0xc2aea2c1, 0x85bd543a, 0x4c894f37, 0x0b9ab9cc, 0xfa85b841, - 0xbd964eba, 0x74a255b7, 0x33b1a34c, 0x3dbb65ec, 0x7aa89317, - 0xb39c881a, 0xf48f7ee1, 0xaf89055a, 0xe89af3a1, 0x21aee8ac, - 0x66bd1e57, 0x68b7d8f7, 0x2fa42e0c, 0xe6903501, 0xa183c3fa, - 0xdfdf305a, 0x98ccc6a1, 0x51f8ddac, 0x16eb2b57, 0x18e1edf7, - 0x5ff21b0c, 0x96c60001, 0xd1d5f6fa, 0x8ad38d41, 0xcdc07bba, - 0x04f460b7, 0x43e7964c, 0x4ded50ec, 0x0afea617, 0xc3cabd1a, - 0x84d94be1, 0x75c64a6c, 0x32d5bc97, 0xfbe1a79a, 0xbcf25161, - 0xb2f897c1, 0xf5eb613a, 0x3cdf7a37, 0x7bcc8ccc, 0x20caf777, - 0x67d9018c, 0xaeed1a81, 0xe9feec7a, 0xe7f42ada, 0xa0e7dc21, - 0x69d3c72c, 0x2ec031d7, 0x956a206c, 0xd279d697, 0x1b4dcd9a, - 0x5c5e3b61, 0x5254fdc1, 0x15470b3a, 0xdc731037, 0x9b60e6cc, - 0xc0669d77, 0x87756b8c, 0x4e417081, 0x0952867a, 0x075840da, - 0x404bb621, 0x897fad2c, 0xce6c5bd7, 0x3f735a5a, 0x7860aca1, - 0xb154b7ac, 0xf6474157, 0xf84d87f7, 0xbf5e710c, 0x766a6a01, - 0x31799cfa, 0x6a7fe741, 0x2d6c11ba, 0xe4580ab7, 0xa34bfc4c, - 0xad413aec, 0xea52cc17, 0x2366d71a, 0x647521e1, 0x1a29d241, - 0x5d3a24ba, 0x940e3fb7, 0xd31dc94c, 0xdd170fec, 0x9a04f917, - 0x5330e21a, 0x142314e1, 0x4f256f5a, 0x083699a1, 0xc10282ac, - 0x86117457, 0x881bb2f7, 0xcf08440c, 0x063c5f01, 0x412fa9fa, - 0xb030a877, 0xf7235e8c, 0x3e174581, 0x7904b37a, 0x770e75da, - 0x301d8321, 0xf929982c, 0xbe3a6ed7, 0xe53c156c, 0xa22fe397, - 0x6b1bf89a, 0x2c080e61, 0x2202c8c1, 0x65113e3a, 0xac252537, - 0xeb36d3cc}, - {0x00000000, 0xa13984ee, 0x99020f9d, 0x383b8b73, 0xe975197b, - 0x484c9d95, 0x707716e6, 0xd14e9208, 0x099b34b7, 0xa8a2b059, - 0x90993b2a, 0x31a0bfc4, 0xe0ee2dcc, 0x41d7a922, 0x79ec2251, - 0xd8d5a6bf, 0x1336696e, 0xb20fed80, 0x8a3466f3, 0x2b0de21d, - 0xfa437015, 0x5b7af4fb, 0x63417f88, 0xc278fb66, 0x1aad5dd9, - 0xbb94d937, 0x83af5244, 0x2296d6aa, 0xf3d844a2, 0x52e1c04c, - 0x6ada4b3f, 0xcbe3cfd1, 0x266cd2dc, 0x87555632, 0xbf6edd41, - 0x1e5759af, 0xcf19cba7, 0x6e204f49, 0x561bc43a, 0xf72240d4, - 0x2ff7e66b, 0x8ece6285, 0xb6f5e9f6, 0x17cc6d18, 0xc682ff10, - 0x67bb7bfe, 0x5f80f08d, 0xfeb97463, 0x355abbb2, 0x94633f5c, - 0xac58b42f, 0x0d6130c1, 0xdc2fa2c9, 0x7d162627, 0x452dad54, - 0xe41429ba, 0x3cc18f05, 0x9df80beb, 0xa5c38098, 0x04fa0476, - 0xd5b4967e, 0x748d1290, 0x4cb699e3, 0xed8f1d0d, 0x4cd9a5b8, - 0xede02156, 0xd5dbaa25, 0x74e22ecb, 0xa5acbcc3, 0x0495382d, - 0x3caeb35e, 0x9d9737b0, 0x4542910f, 0xe47b15e1, 0xdc409e92, - 0x7d791a7c, 0xac378874, 0x0d0e0c9a, 0x353587e9, 0x940c0307, - 0x5fefccd6, 0xfed64838, 0xc6edc34b, 0x67d447a5, 0xb69ad5ad, - 0x17a35143, 0x2f98da30, 0x8ea15ede, 0x5674f861, 0xf74d7c8f, - 0xcf76f7fc, 0x6e4f7312, 0xbf01e11a, 0x1e3865f4, 0x2603ee87, - 0x873a6a69, 0x6ab57764, 0xcb8cf38a, 0xf3b778f9, 0x528efc17, - 0x83c06e1f, 0x22f9eaf1, 0x1ac26182, 0xbbfbe56c, 0x632e43d3, - 0xc217c73d, 0xfa2c4c4e, 0x5b15c8a0, 0x8a5b5aa8, 0x2b62de46, - 0x13595535, 0xb260d1db, 0x79831e0a, 0xd8ba9ae4, 0xe0811197, - 0x41b89579, 0x90f60771, 0x31cf839f, 0x09f408ec, 0xa8cd8c02, - 0x70182abd, 0xd121ae53, 0xe91a2520, 0x4823a1ce, 0x996d33c6, - 0x3854b728, 0x006f3c5b, 0xa156b8b5, 0x99b34b70, 0x388acf9e, - 0x00b144ed, 0xa188c003, 0x70c6520b, 0xd1ffd6e5, 0xe9c45d96, - 0x48fdd978, 0x90287fc7, 0x3111fb29, 0x092a705a, 0xa813f4b4, - 0x795d66bc, 0xd864e252, 0xe05f6921, 0x4166edcf, 0x8a85221e, - 0x2bbca6f0, 0x13872d83, 0xb2bea96d, 0x63f03b65, 0xc2c9bf8b, - 0xfaf234f8, 0x5bcbb016, 0x831e16a9, 0x22279247, 0x1a1c1934, - 0xbb259dda, 0x6a6b0fd2, 0xcb528b3c, 0xf369004f, 0x525084a1, - 0xbfdf99ac, 0x1ee61d42, 0x26dd9631, 0x87e412df, 0x56aa80d7, - 0xf7930439, 0xcfa88f4a, 0x6e910ba4, 0xb644ad1b, 0x177d29f5, - 0x2f46a286, 0x8e7f2668, 0x5f31b460, 0xfe08308e, 0xc633bbfd, - 0x670a3f13, 0xace9f0c2, 0x0dd0742c, 0x35ebff5f, 0x94d27bb1, - 0x459ce9b9, 0xe4a56d57, 0xdc9ee624, 0x7da762ca, 0xa572c475, - 0x044b409b, 0x3c70cbe8, 0x9d494f06, 0x4c07dd0e, 0xed3e59e0, - 0xd505d293, 0x743c567d, 0xd56aeec8, 0x74536a26, 0x4c68e155, - 0xed5165bb, 0x3c1ff7b3, 0x9d26735d, 0xa51df82e, 0x04247cc0, - 0xdcf1da7f, 0x7dc85e91, 0x45f3d5e2, 0xe4ca510c, 0x3584c304, - 0x94bd47ea, 0xac86cc99, 0x0dbf4877, 0xc65c87a6, 0x67650348, - 0x5f5e883b, 0xfe670cd5, 0x2f299edd, 0x8e101a33, 0xb62b9140, - 0x171215ae, 0xcfc7b311, 0x6efe37ff, 0x56c5bc8c, 0xf7fc3862, - 0x26b2aa6a, 0x878b2e84, 0xbfb0a5f7, 0x1e892119, 0xf3063c14, - 0x523fb8fa, 0x6a043389, 0xcb3db767, 0x1a73256f, 0xbb4aa181, - 0x83712af2, 0x2248ae1c, 0xfa9d08a3, 0x5ba48c4d, 0x639f073e, - 0xc2a683d0, 0x13e811d8, 0xb2d19536, 0x8aea1e45, 0x2bd39aab, - 0xe030557a, 0x4109d194, 0x79325ae7, 0xd80bde09, 0x09454c01, - 0xa87cc8ef, 0x9047439c, 0x317ec772, 0xe9ab61cd, 0x4892e523, - 0x70a96e50, 0xd190eabe, 0x00de78b6, 0xa1e7fc58, 0x99dc772b, - 0x38e5f3c5}, - {0x00000000, 0xe81790a1, 0x0b5e2703, 0xe349b7a2, 0x16bc4e06, - 0xfeabdea7, 0x1de26905, 0xf5f5f9a4, 0x2d789c0c, 0xc56f0cad, - 0x2626bb0f, 0xce312bae, 0x3bc4d20a, 0xd3d342ab, 0x309af509, - 0xd88d65a8, 0x5af13818, 0xb2e6a8b9, 0x51af1f1b, 0xb9b88fba, - 0x4c4d761e, 0xa45ae6bf, 0x4713511d, 0xaf04c1bc, 0x7789a414, - 0x9f9e34b5, 0x7cd78317, 0x94c013b6, 0x6135ea12, 0x89227ab3, - 0x6a6bcd11, 0x827c5db0, 0xb5e27030, 0x5df5e091, 0xbebc5733, - 0x56abc792, 0xa35e3e36, 0x4b49ae97, 0xa8001935, 0x40178994, - 0x989aec3c, 0x708d7c9d, 0x93c4cb3f, 0x7bd35b9e, 0x8e26a23a, - 0x6631329b, 0x85788539, 0x6d6f1598, 0xef134828, 0x0704d889, - 0xe44d6f2b, 0x0c5aff8a, 0xf9af062e, 0x11b8968f, 0xf2f1212d, - 0x1ae6b18c, 0xc26bd424, 0x2a7c4485, 0xc935f327, 0x21226386, - 0xd4d79a22, 0x3cc00a83, 0xdf89bd21, 0x379e2d80, 0xb0b5e621, - 0x58a27680, 0xbbebc122, 0x53fc5183, 0xa609a827, 0x4e1e3886, - 0xad578f24, 0x45401f85, 0x9dcd7a2d, 0x75daea8c, 0x96935d2e, - 0x7e84cd8f, 0x8b71342b, 0x6366a48a, 0x802f1328, 0x68388389, - 0xea44de39, 0x02534e98, 0xe11af93a, 0x090d699b, 0xfcf8903f, - 0x14ef009e, 0xf7a6b73c, 0x1fb1279d, 0xc73c4235, 0x2f2bd294, - 0xcc626536, 0x2475f597, 0xd1800c33, 0x39979c92, 0xdade2b30, - 0x32c9bb91, 0x05579611, 0xed4006b0, 0x0e09b112, 0xe61e21b3, - 0x13ebd817, 0xfbfc48b6, 0x18b5ff14, 0xf0a26fb5, 0x282f0a1d, - 0xc0389abc, 0x23712d1e, 0xcb66bdbf, 0x3e93441b, 0xd684d4ba, - 0x35cd6318, 0xdddaf3b9, 0x5fa6ae09, 0xb7b13ea8, 0x54f8890a, - 0xbcef19ab, 0x491ae00f, 0xa10d70ae, 0x4244c70c, 0xaa5357ad, - 0x72de3205, 0x9ac9a2a4, 0x79801506, 0x919785a7, 0x64627c03, - 0x8c75eca2, 0x6f3c5b00, 0x872bcba1, 0xba1aca03, 0x520d5aa2, - 0xb144ed00, 0x59537da1, 0xaca68405, 0x44b114a4, 0xa7f8a306, - 0x4fef33a7, 0x9762560f, 0x7f75c6ae, 0x9c3c710c, 0x742be1ad, - 0x81de1809, 0x69c988a8, 0x8a803f0a, 0x6297afab, 0xe0ebf21b, - 0x08fc62ba, 0xebb5d518, 0x03a245b9, 0xf657bc1d, 0x1e402cbc, - 0xfd099b1e, 0x151e0bbf, 0xcd936e17, 0x2584feb6, 0xc6cd4914, - 0x2edad9b5, 0xdb2f2011, 0x3338b0b0, 0xd0710712, 0x386697b3, - 0x0ff8ba33, 0xe7ef2a92, 0x04a69d30, 0xecb10d91, 0x1944f435, - 0xf1536494, 0x121ad336, 0xfa0d4397, 0x2280263f, 0xca97b69e, - 0x29de013c, 0xc1c9919d, 0x343c6839, 0xdc2bf898, 0x3f624f3a, - 0xd775df9b, 0x5509822b, 0xbd1e128a, 0x5e57a528, 0xb6403589, - 0x43b5cc2d, 0xaba25c8c, 0x48ebeb2e, 0xa0fc7b8f, 0x78711e27, - 0x90668e86, 0x732f3924, 0x9b38a985, 0x6ecd5021, 0x86dac080, - 0x65937722, 0x8d84e783, 0x0aaf2c22, 0xe2b8bc83, 0x01f10b21, - 0xe9e69b80, 0x1c136224, 0xf404f285, 0x174d4527, 0xff5ad586, - 0x27d7b02e, 0xcfc0208f, 0x2c89972d, 0xc49e078c, 0x316bfe28, - 0xd97c6e89, 0x3a35d92b, 0xd222498a, 0x505e143a, 0xb849849b, - 0x5b003339, 0xb317a398, 0x46e25a3c, 0xaef5ca9d, 0x4dbc7d3f, - 0xa5abed9e, 0x7d268836, 0x95311897, 0x7678af35, 0x9e6f3f94, - 0x6b9ac630, 0x838d5691, 0x60c4e133, 0x88d37192, 0xbf4d5c12, - 0x575accb3, 0xb4137b11, 0x5c04ebb0, 0xa9f11214, 0x41e682b5, - 0xa2af3517, 0x4ab8a5b6, 0x9235c01e, 0x7a2250bf, 0x996be71d, - 0x717c77bc, 0x84898e18, 0x6c9e1eb9, 0x8fd7a91b, 0x67c039ba, - 0xe5bc640a, 0x0dabf4ab, 0xeee24309, 0x06f5d3a8, 0xf3002a0c, - 0x1b17baad, 0xf85e0d0f, 0x10499dae, 0xc8c4f806, 0x20d368a7, - 0xc39adf05, 0x2b8d4fa4, 0xde78b600, 0x366f26a1, 0xd5269103, - 0x3d3101a2}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0xa19017e800000000, 0x03275e0b00000000, - 0xa2b749e300000000, 0x064ebc1600000000, 0xa7deabfe00000000, - 0x0569e21d00000000, 0xa4f9f5f500000000, 0x0c9c782d00000000, - 0xad0c6fc500000000, 0x0fbb262600000000, 0xae2b31ce00000000, - 0x0ad2c43b00000000, 0xab42d3d300000000, 0x09f59a3000000000, - 0xa8658dd800000000, 0x1838f15a00000000, 0xb9a8e6b200000000, - 0x1b1faf5100000000, 0xba8fb8b900000000, 0x1e764d4c00000000, - 0xbfe65aa400000000, 0x1d51134700000000, 0xbcc104af00000000, - 0x14a4897700000000, 0xb5349e9f00000000, 0x1783d77c00000000, - 0xb613c09400000000, 0x12ea356100000000, 0xb37a228900000000, - 0x11cd6b6a00000000, 0xb05d7c8200000000, 0x3070e2b500000000, - 0x91e0f55d00000000, 0x3357bcbe00000000, 0x92c7ab5600000000, - 0x363e5ea300000000, 0x97ae494b00000000, 0x351900a800000000, - 0x9489174000000000, 0x3cec9a9800000000, 0x9d7c8d7000000000, - 0x3fcbc49300000000, 0x9e5bd37b00000000, 0x3aa2268e00000000, - 0x9b32316600000000, 0x3985788500000000, 0x98156f6d00000000, - 0x284813ef00000000, 0x89d8040700000000, 0x2b6f4de400000000, - 0x8aff5a0c00000000, 0x2e06aff900000000, 0x8f96b81100000000, - 0x2d21f1f200000000, 0x8cb1e61a00000000, 0x24d46bc200000000, - 0x85447c2a00000000, 0x27f335c900000000, 0x8663222100000000, - 0x229ad7d400000000, 0x830ac03c00000000, 0x21bd89df00000000, - 0x802d9e3700000000, 0x21e6b5b000000000, 0x8076a25800000000, - 0x22c1ebbb00000000, 0x8351fc5300000000, 0x27a809a600000000, - 0x86381e4e00000000, 0x248f57ad00000000, 0x851f404500000000, - 0x2d7acd9d00000000, 0x8ceada7500000000, 0x2e5d939600000000, - 0x8fcd847e00000000, 0x2b34718b00000000, 0x8aa4666300000000, - 0x28132f8000000000, 0x8983386800000000, 0x39de44ea00000000, - 0x984e530200000000, 0x3af91ae100000000, 0x9b690d0900000000, - 0x3f90f8fc00000000, 0x9e00ef1400000000, 0x3cb7a6f700000000, - 0x9d27b11f00000000, 0x35423cc700000000, 0x94d22b2f00000000, - 0x366562cc00000000, 0x97f5752400000000, 0x330c80d100000000, - 0x929c973900000000, 0x302bdeda00000000, 0x91bbc93200000000, - 0x1196570500000000, 0xb00640ed00000000, 0x12b1090e00000000, - 0xb3211ee600000000, 0x17d8eb1300000000, 0xb648fcfb00000000, - 0x14ffb51800000000, 0xb56fa2f000000000, 0x1d0a2f2800000000, - 0xbc9a38c000000000, 0x1e2d712300000000, 0xbfbd66cb00000000, - 0x1b44933e00000000, 0xbad484d600000000, 0x1863cd3500000000, - 0xb9f3dadd00000000, 0x09aea65f00000000, 0xa83eb1b700000000, - 0x0a89f85400000000, 0xab19efbc00000000, 0x0fe01a4900000000, - 0xae700da100000000, 0x0cc7444200000000, 0xad5753aa00000000, - 0x0532de7200000000, 0xa4a2c99a00000000, 0x0615807900000000, - 0xa785979100000000, 0x037c626400000000, 0xa2ec758c00000000, - 0x005b3c6f00000000, 0xa1cb2b8700000000, 0x03ca1aba00000000, - 0xa25a0d5200000000, 0x00ed44b100000000, 0xa17d535900000000, - 0x0584a6ac00000000, 0xa414b14400000000, 0x06a3f8a700000000, - 0xa733ef4f00000000, 0x0f56629700000000, 0xaec6757f00000000, - 0x0c713c9c00000000, 0xade12b7400000000, 0x0918de8100000000, - 0xa888c96900000000, 0x0a3f808a00000000, 0xabaf976200000000, - 0x1bf2ebe000000000, 0xba62fc0800000000, 0x18d5b5eb00000000, - 0xb945a20300000000, 0x1dbc57f600000000, 0xbc2c401e00000000, - 0x1e9b09fd00000000, 0xbf0b1e1500000000, 0x176e93cd00000000, - 0xb6fe842500000000, 0x1449cdc600000000, 0xb5d9da2e00000000, - 0x11202fdb00000000, 0xb0b0383300000000, 0x120771d000000000, - 0xb397663800000000, 0x33baf80f00000000, 0x922aefe700000000, - 0x309da60400000000, 0x910db1ec00000000, 0x35f4441900000000, - 0x946453f100000000, 0x36d31a1200000000, 0x97430dfa00000000, - 0x3f26802200000000, 0x9eb697ca00000000, 0x3c01de2900000000, - 0x9d91c9c100000000, 0x39683c3400000000, 0x98f82bdc00000000, - 0x3a4f623f00000000, 0x9bdf75d700000000, 0x2b82095500000000, - 0x8a121ebd00000000, 0x28a5575e00000000, 0x893540b600000000, - 0x2dccb54300000000, 0x8c5ca2ab00000000, 0x2eebeb4800000000, - 0x8f7bfca000000000, 0x271e717800000000, 0x868e669000000000, - 0x24392f7300000000, 0x85a9389b00000000, 0x2150cd6e00000000, - 0x80c0da8600000000, 0x2277936500000000, 0x83e7848d00000000, - 0x222caf0a00000000, 0x83bcb8e200000000, 0x210bf10100000000, - 0x809be6e900000000, 0x2462131c00000000, 0x85f204f400000000, - 0x27454d1700000000, 0x86d55aff00000000, 0x2eb0d72700000000, - 0x8f20c0cf00000000, 0x2d97892c00000000, 0x8c079ec400000000, - 0x28fe6b3100000000, 0x896e7cd900000000, 0x2bd9353a00000000, - 0x8a4922d200000000, 0x3a145e5000000000, 0x9b8449b800000000, - 0x3933005b00000000, 0x98a317b300000000, 0x3c5ae24600000000, - 0x9dcaf5ae00000000, 0x3f7dbc4d00000000, 0x9eedaba500000000, - 0x3688267d00000000, 0x9718319500000000, 0x35af787600000000, - 0x943f6f9e00000000, 0x30c69a6b00000000, 0x91568d8300000000, - 0x33e1c46000000000, 0x9271d38800000000, 0x125c4dbf00000000, - 0xb3cc5a5700000000, 0x117b13b400000000, 0xb0eb045c00000000, - 0x1412f1a900000000, 0xb582e64100000000, 0x1735afa200000000, - 0xb6a5b84a00000000, 0x1ec0359200000000, 0xbf50227a00000000, - 0x1de76b9900000000, 0xbc777c7100000000, 0x188e898400000000, - 0xb91e9e6c00000000, 0x1ba9d78f00000000, 0xba39c06700000000, - 0x0a64bce500000000, 0xabf4ab0d00000000, 0x0943e2ee00000000, - 0xa8d3f50600000000, 0x0c2a00f300000000, 0xadba171b00000000, - 0x0f0d5ef800000000, 0xae9d491000000000, 0x06f8c4c800000000, - 0xa768d32000000000, 0x05df9ac300000000, 0xa44f8d2b00000000, - 0x00b678de00000000, 0xa1266f3600000000, 0x039126d500000000, - 0xa201313d00000000}, - {0x0000000000000000, 0xee8439a100000000, 0x9d0f029900000000, - 0x738b3b3800000000, 0x7b1975e900000000, 0x959d4c4800000000, - 0xe616777000000000, 0x08924ed100000000, 0xb7349b0900000000, - 0x59b0a2a800000000, 0x2a3b999000000000, 0xc4bfa03100000000, - 0xcc2deee000000000, 0x22a9d74100000000, 0x5122ec7900000000, - 0xbfa6d5d800000000, 0x6e69361300000000, 0x80ed0fb200000000, - 0xf366348a00000000, 0x1de20d2b00000000, 0x157043fa00000000, - 0xfbf47a5b00000000, 0x887f416300000000, 0x66fb78c200000000, - 0xd95dad1a00000000, 0x37d994bb00000000, 0x4452af8300000000, - 0xaad6962200000000, 0xa244d8f300000000, 0x4cc0e15200000000, - 0x3f4bda6a00000000, 0xd1cfe3cb00000000, 0xdcd26c2600000000, - 0x3256558700000000, 0x41dd6ebf00000000, 0xaf59571e00000000, - 0xa7cb19cf00000000, 0x494f206e00000000, 0x3ac41b5600000000, - 0xd44022f700000000, 0x6be6f72f00000000, 0x8562ce8e00000000, - 0xf6e9f5b600000000, 0x186dcc1700000000, 0x10ff82c600000000, - 0xfe7bbb6700000000, 0x8df0805f00000000, 0x6374b9fe00000000, - 0xb2bb5a3500000000, 0x5c3f639400000000, 0x2fb458ac00000000, - 0xc130610d00000000, 0xc9a22fdc00000000, 0x2726167d00000000, - 0x54ad2d4500000000, 0xba2914e400000000, 0x058fc13c00000000, - 0xeb0bf89d00000000, 0x9880c3a500000000, 0x7604fa0400000000, - 0x7e96b4d500000000, 0x90128d7400000000, 0xe399b64c00000000, - 0x0d1d8fed00000000, 0xb8a5d94c00000000, 0x5621e0ed00000000, - 0x25aadbd500000000, 0xcb2ee27400000000, 0xc3bcaca500000000, - 0x2d38950400000000, 0x5eb3ae3c00000000, 0xb037979d00000000, - 0x0f91424500000000, 0xe1157be400000000, 0x929e40dc00000000, - 0x7c1a797d00000000, 0x748837ac00000000, 0x9a0c0e0d00000000, - 0xe987353500000000, 0x07030c9400000000, 0xd6ccef5f00000000, - 0x3848d6fe00000000, 0x4bc3edc600000000, 0xa547d46700000000, - 0xadd59ab600000000, 0x4351a31700000000, 0x30da982f00000000, - 0xde5ea18e00000000, 0x61f8745600000000, 0x8f7c4df700000000, - 0xfcf776cf00000000, 0x12734f6e00000000, 0x1ae101bf00000000, - 0xf465381e00000000, 0x87ee032600000000, 0x696a3a8700000000, - 0x6477b56a00000000, 0x8af38ccb00000000, 0xf978b7f300000000, - 0x17fc8e5200000000, 0x1f6ec08300000000, 0xf1eaf92200000000, - 0x8261c21a00000000, 0x6ce5fbbb00000000, 0xd3432e6300000000, - 0x3dc717c200000000, 0x4e4c2cfa00000000, 0xa0c8155b00000000, - 0xa85a5b8a00000000, 0x46de622b00000000, 0x3555591300000000, - 0xdbd160b200000000, 0x0a1e837900000000, 0xe49abad800000000, - 0x971181e000000000, 0x7995b84100000000, 0x7107f69000000000, - 0x9f83cf3100000000, 0xec08f40900000000, 0x028ccda800000000, - 0xbd2a187000000000, 0x53ae21d100000000, 0x20251ae900000000, - 0xcea1234800000000, 0xc6336d9900000000, 0x28b7543800000000, - 0x5b3c6f0000000000, 0xb5b856a100000000, 0x704bb39900000000, - 0x9ecf8a3800000000, 0xed44b10000000000, 0x03c088a100000000, - 0x0b52c67000000000, 0xe5d6ffd100000000, 0x965dc4e900000000, - 0x78d9fd4800000000, 0xc77f289000000000, 0x29fb113100000000, - 0x5a702a0900000000, 0xb4f413a800000000, 0xbc665d7900000000, - 0x52e264d800000000, 0x21695fe000000000, 0xcfed664100000000, - 0x1e22858a00000000, 0xf0a6bc2b00000000, 0x832d871300000000, - 0x6da9beb200000000, 0x653bf06300000000, 0x8bbfc9c200000000, - 0xf834f2fa00000000, 0x16b0cb5b00000000, 0xa9161e8300000000, - 0x4792272200000000, 0x34191c1a00000000, 0xda9d25bb00000000, - 0xd20f6b6a00000000, 0x3c8b52cb00000000, 0x4f0069f300000000, - 0xa184505200000000, 0xac99dfbf00000000, 0x421de61e00000000, - 0x3196dd2600000000, 0xdf12e48700000000, 0xd780aa5600000000, - 0x390493f700000000, 0x4a8fa8cf00000000, 0xa40b916e00000000, - 0x1bad44b600000000, 0xf5297d1700000000, 0x86a2462f00000000, - 0x68267f8e00000000, 0x60b4315f00000000, 0x8e3008fe00000000, - 0xfdbb33c600000000, 0x133f0a6700000000, 0xc2f0e9ac00000000, - 0x2c74d00d00000000, 0x5fffeb3500000000, 0xb17bd29400000000, - 0xb9e99c4500000000, 0x576da5e400000000, 0x24e69edc00000000, - 0xca62a77d00000000, 0x75c472a500000000, 0x9b404b0400000000, - 0xe8cb703c00000000, 0x064f499d00000000, 0x0edd074c00000000, - 0xe0593eed00000000, 0x93d205d500000000, 0x7d563c7400000000, - 0xc8ee6ad500000000, 0x266a537400000000, 0x55e1684c00000000, - 0xbb6551ed00000000, 0xb3f71f3c00000000, 0x5d73269d00000000, - 0x2ef81da500000000, 0xc07c240400000000, 0x7fdaf1dc00000000, - 0x915ec87d00000000, 0xe2d5f34500000000, 0x0c51cae400000000, - 0x04c3843500000000, 0xea47bd9400000000, 0x99cc86ac00000000, - 0x7748bf0d00000000, 0xa6875cc600000000, 0x4803656700000000, - 0x3b885e5f00000000, 0xd50c67fe00000000, 0xdd9e292f00000000, - 0x331a108e00000000, 0x40912bb600000000, 0xae15121700000000, - 0x11b3c7cf00000000, 0xff37fe6e00000000, 0x8cbcc55600000000, - 0x6238fcf700000000, 0x6aaab22600000000, 0x842e8b8700000000, - 0xf7a5b0bf00000000, 0x1921891e00000000, 0x143c06f300000000, - 0xfab83f5200000000, 0x8933046a00000000, 0x67b73dcb00000000, - 0x6f25731a00000000, 0x81a14abb00000000, 0xf22a718300000000, - 0x1cae482200000000, 0xa3089dfa00000000, 0x4d8ca45b00000000, - 0x3e079f6300000000, 0xd083a6c200000000, 0xd811e81300000000, - 0x3695d1b200000000, 0x451eea8a00000000, 0xab9ad32b00000000, - 0x7a5530e000000000, 0x94d1094100000000, 0xe75a327900000000, - 0x09de0bd800000000, 0x014c450900000000, 0xefc87ca800000000, - 0x9c43479000000000, 0x72c77e3100000000, 0xcd61abe900000000, - 0x23e5924800000000, 0x506ea97000000000, 0xbeea90d100000000, - 0xb678de0000000000, 0x58fce7a100000000, 0x2b77dc9900000000, - 0xc5f3e53800000000}, - {0x0000000000000000, 0xfbf6134700000000, 0xf6ed278e00000000, - 0x0d1b34c900000000, 0xaddd3ec700000000, 0x562b2d8000000000, - 0x5b30194900000000, 0xa0c60a0e00000000, 0x1bbd0c5500000000, - 0xe04b1f1200000000, 0xed502bdb00000000, 0x16a6389c00000000, - 0xb660329200000000, 0x4d9621d500000000, 0x408d151c00000000, - 0xbb7b065b00000000, 0x367a19aa00000000, 0xcd8c0aed00000000, - 0xc0973e2400000000, 0x3b612d6300000000, 0x9ba7276d00000000, - 0x6051342a00000000, 0x6d4a00e300000000, 0x96bc13a400000000, - 0x2dc715ff00000000, 0xd63106b800000000, 0xdb2a327100000000, - 0x20dc213600000000, 0x801a2b3800000000, 0x7bec387f00000000, - 0x76f70cb600000000, 0x8d011ff100000000, 0x2df2438f00000000, - 0xd60450c800000000, 0xdb1f640100000000, 0x20e9774600000000, - 0x802f7d4800000000, 0x7bd96e0f00000000, 0x76c25ac600000000, - 0x8d34498100000000, 0x364f4fda00000000, 0xcdb95c9d00000000, - 0xc0a2685400000000, 0x3b547b1300000000, 0x9b92711d00000000, - 0x6064625a00000000, 0x6d7f569300000000, 0x968945d400000000, - 0x1b885a2500000000, 0xe07e496200000000, 0xed657dab00000000, - 0x16936eec00000000, 0xb65564e200000000, 0x4da377a500000000, - 0x40b8436c00000000, 0xbb4e502b00000000, 0x0035567000000000, - 0xfbc3453700000000, 0xf6d871fe00000000, 0x0d2e62b900000000, - 0xade868b700000000, 0x561e7bf000000000, 0x5b054f3900000000, - 0xa0f35c7e00000000, 0x1be2f6c500000000, 0xe014e58200000000, - 0xed0fd14b00000000, 0x16f9c20c00000000, 0xb63fc80200000000, - 0x4dc9db4500000000, 0x40d2ef8c00000000, 0xbb24fccb00000000, - 0x005ffa9000000000, 0xfba9e9d700000000, 0xf6b2dd1e00000000, - 0x0d44ce5900000000, 0xad82c45700000000, 0x5674d71000000000, - 0x5b6fe3d900000000, 0xa099f09e00000000, 0x2d98ef6f00000000, - 0xd66efc2800000000, 0xdb75c8e100000000, 0x2083dba600000000, - 0x8045d1a800000000, 0x7bb3c2ef00000000, 0x76a8f62600000000, - 0x8d5ee56100000000, 0x3625e33a00000000, 0xcdd3f07d00000000, - 0xc0c8c4b400000000, 0x3b3ed7f300000000, 0x9bf8ddfd00000000, - 0x600eceba00000000, 0x6d15fa7300000000, 0x96e3e93400000000, - 0x3610b54a00000000, 0xcde6a60d00000000, 0xc0fd92c400000000, - 0x3b0b818300000000, 0x9bcd8b8d00000000, 0x603b98ca00000000, - 0x6d20ac0300000000, 0x96d6bf4400000000, 0x2dadb91f00000000, - 0xd65baa5800000000, 0xdb409e9100000000, 0x20b68dd600000000, - 0x807087d800000000, 0x7b86949f00000000, 0x769da05600000000, - 0x8d6bb31100000000, 0x006aace000000000, 0xfb9cbfa700000000, - 0xf6878b6e00000000, 0x0d71982900000000, 0xadb7922700000000, - 0x5641816000000000, 0x5b5ab5a900000000, 0xa0aca6ee00000000, - 0x1bd7a0b500000000, 0xe021b3f200000000, 0xed3a873b00000000, - 0x16cc947c00000000, 0xb60a9e7200000000, 0x4dfc8d3500000000, - 0x40e7b9fc00000000, 0xbb11aabb00000000, 0x77c29c5000000000, - 0x8c348f1700000000, 0x812fbbde00000000, 0x7ad9a89900000000, - 0xda1fa29700000000, 0x21e9b1d000000000, 0x2cf2851900000000, - 0xd704965e00000000, 0x6c7f900500000000, 0x9789834200000000, - 0x9a92b78b00000000, 0x6164a4cc00000000, 0xc1a2aec200000000, - 0x3a54bd8500000000, 0x374f894c00000000, 0xccb99a0b00000000, - 0x41b885fa00000000, 0xba4e96bd00000000, 0xb755a27400000000, - 0x4ca3b13300000000, 0xec65bb3d00000000, 0x1793a87a00000000, - 0x1a889cb300000000, 0xe17e8ff400000000, 0x5a0589af00000000, - 0xa1f39ae800000000, 0xace8ae2100000000, 0x571ebd6600000000, - 0xf7d8b76800000000, 0x0c2ea42f00000000, 0x013590e600000000, - 0xfac383a100000000, 0x5a30dfdf00000000, 0xa1c6cc9800000000, - 0xacddf85100000000, 0x572beb1600000000, 0xf7ede11800000000, - 0x0c1bf25f00000000, 0x0100c69600000000, 0xfaf6d5d100000000, - 0x418dd38a00000000, 0xba7bc0cd00000000, 0xb760f40400000000, - 0x4c96e74300000000, 0xec50ed4d00000000, 0x17a6fe0a00000000, - 0x1abdcac300000000, 0xe14bd98400000000, 0x6c4ac67500000000, - 0x97bcd53200000000, 0x9aa7e1fb00000000, 0x6151f2bc00000000, - 0xc197f8b200000000, 0x3a61ebf500000000, 0x377adf3c00000000, - 0xcc8ccc7b00000000, 0x77f7ca2000000000, 0x8c01d96700000000, - 0x811aedae00000000, 0x7aecfee900000000, 0xda2af4e700000000, - 0x21dce7a000000000, 0x2cc7d36900000000, 0xd731c02e00000000, - 0x6c206a9500000000, 0x97d679d200000000, 0x9acd4d1b00000000, - 0x613b5e5c00000000, 0xc1fd545200000000, 0x3a0b471500000000, - 0x371073dc00000000, 0xcce6609b00000000, 0x779d66c000000000, - 0x8c6b758700000000, 0x8170414e00000000, 0x7a86520900000000, - 0xda40580700000000, 0x21b64b4000000000, 0x2cad7f8900000000, - 0xd75b6cce00000000, 0x5a5a733f00000000, 0xa1ac607800000000, - 0xacb754b100000000, 0x574147f600000000, 0xf7874df800000000, - 0x0c715ebf00000000, 0x016a6a7600000000, 0xfa9c793100000000, - 0x41e77f6a00000000, 0xba116c2d00000000, 0xb70a58e400000000, - 0x4cfc4ba300000000, 0xec3a41ad00000000, 0x17cc52ea00000000, - 0x1ad7662300000000, 0xe121756400000000, 0x41d2291a00000000, - 0xba243a5d00000000, 0xb73f0e9400000000, 0x4cc91dd300000000, - 0xec0f17dd00000000, 0x17f9049a00000000, 0x1ae2305300000000, - 0xe114231400000000, 0x5a6f254f00000000, 0xa199360800000000, - 0xac8202c100000000, 0x5774118600000000, 0xf7b21b8800000000, - 0x0c4408cf00000000, 0x015f3c0600000000, 0xfaa92f4100000000, - 0x77a830b000000000, 0x8c5e23f700000000, 0x8145173e00000000, - 0x7ab3047900000000, 0xda750e7700000000, 0x21831d3000000000, - 0x2c9829f900000000, 0xd76e3abe00000000, 0x6c153ce500000000, - 0x97e32fa200000000, 0x9af81b6b00000000, 0x610e082c00000000, - 0xc1c8022200000000, 0x3a3e116500000000, 0x372525ac00000000, - 0xccd336eb00000000}, - {0x0000000000000000, 0x6238282a00000000, 0xc470505400000000, - 0xa648787e00000000, 0x88e1a0a800000000, 0xead9888200000000, - 0x4c91f0fc00000000, 0x2ea9d8d600000000, 0x51c5308a00000000, - 0x33fd18a000000000, 0x95b560de00000000, 0xf78d48f400000000, - 0xd924902200000000, 0xbb1cb80800000000, 0x1d54c07600000000, - 0x7f6ce85c00000000, 0xe38c10cf00000000, 0x81b438e500000000, - 0x27fc409b00000000, 0x45c468b100000000, 0x6b6db06700000000, - 0x0955984d00000000, 0xaf1de03300000000, 0xcd25c81900000000, - 0xb249204500000000, 0xd071086f00000000, 0x7639701100000000, - 0x1401583b00000000, 0x3aa880ed00000000, 0x5890a8c700000000, - 0xfed8d0b900000000, 0x9ce0f89300000000, 0x871f504500000000, - 0xe527786f00000000, 0x436f001100000000, 0x2157283b00000000, - 0x0ffef0ed00000000, 0x6dc6d8c700000000, 0xcb8ea0b900000000, - 0xa9b6889300000000, 0xd6da60cf00000000, 0xb4e248e500000000, - 0x12aa309b00000000, 0x709218b100000000, 0x5e3bc06700000000, - 0x3c03e84d00000000, 0x9a4b903300000000, 0xf873b81900000000, - 0x6493408a00000000, 0x06ab68a000000000, 0xa0e310de00000000, - 0xc2db38f400000000, 0xec72e02200000000, 0x8e4ac80800000000, - 0x2802b07600000000, 0x4a3a985c00000000, 0x3556700000000000, - 0x576e582a00000000, 0xf126205400000000, 0x931e087e00000000, - 0xbdb7d0a800000000, 0xdf8ff88200000000, 0x79c780fc00000000, - 0x1bffa8d600000000, 0x0e3fa08a00000000, 0x6c0788a000000000, - 0xca4ff0de00000000, 0xa877d8f400000000, 0x86de002200000000, - 0xe4e6280800000000, 0x42ae507600000000, 0x2096785c00000000, - 0x5ffa900000000000, 0x3dc2b82a00000000, 0x9b8ac05400000000, - 0xf9b2e87e00000000, 0xd71b30a800000000, 0xb523188200000000, - 0x136b60fc00000000, 0x715348d600000000, 0xedb3b04500000000, - 0x8f8b986f00000000, 0x29c3e01100000000, 0x4bfbc83b00000000, - 0x655210ed00000000, 0x076a38c700000000, 0xa12240b900000000, - 0xc31a689300000000, 0xbc7680cf00000000, 0xde4ea8e500000000, - 0x7806d09b00000000, 0x1a3ef8b100000000, 0x3497206700000000, - 0x56af084d00000000, 0xf0e7703300000000, 0x92df581900000000, - 0x8920f0cf00000000, 0xeb18d8e500000000, 0x4d50a09b00000000, - 0x2f6888b100000000, 0x01c1506700000000, 0x63f9784d00000000, - 0xc5b1003300000000, 0xa789281900000000, 0xd8e5c04500000000, - 0xbadde86f00000000, 0x1c95901100000000, 0x7eadb83b00000000, - 0x500460ed00000000, 0x323c48c700000000, 0x947430b900000000, - 0xf64c189300000000, 0x6aace00000000000, 0x0894c82a00000000, - 0xaedcb05400000000, 0xcce4987e00000000, 0xe24d40a800000000, - 0x8075688200000000, 0x263d10fc00000000, 0x440538d600000000, - 0x3b69d08a00000000, 0x5951f8a000000000, 0xff1980de00000000, - 0x9d21a8f400000000, 0xb388702200000000, 0xd1b0580800000000, - 0x77f8207600000000, 0x15c0085c00000000, 0x5d7831ce00000000, - 0x3f4019e400000000, 0x9908619a00000000, 0xfb3049b000000000, - 0xd599916600000000, 0xb7a1b94c00000000, 0x11e9c13200000000, - 0x73d1e91800000000, 0x0cbd014400000000, 0x6e85296e00000000, - 0xc8cd511000000000, 0xaaf5793a00000000, 0x845ca1ec00000000, - 0xe66489c600000000, 0x402cf1b800000000, 0x2214d99200000000, - 0xbef4210100000000, 0xdccc092b00000000, 0x7a84715500000000, - 0x18bc597f00000000, 0x361581a900000000, 0x542da98300000000, - 0xf265d1fd00000000, 0x905df9d700000000, 0xef31118b00000000, - 0x8d0939a100000000, 0x2b4141df00000000, 0x497969f500000000, - 0x67d0b12300000000, 0x05e8990900000000, 0xa3a0e17700000000, - 0xc198c95d00000000, 0xda67618b00000000, 0xb85f49a100000000, - 0x1e1731df00000000, 0x7c2f19f500000000, 0x5286c12300000000, - 0x30bee90900000000, 0x96f6917700000000, 0xf4ceb95d00000000, - 0x8ba2510100000000, 0xe99a792b00000000, 0x4fd2015500000000, - 0x2dea297f00000000, 0x0343f1a900000000, 0x617bd98300000000, - 0xc733a1fd00000000, 0xa50b89d700000000, 0x39eb714400000000, - 0x5bd3596e00000000, 0xfd9b211000000000, 0x9fa3093a00000000, - 0xb10ad1ec00000000, 0xd332f9c600000000, 0x757a81b800000000, - 0x1742a99200000000, 0x682e41ce00000000, 0x0a1669e400000000, - 0xac5e119a00000000, 0xce6639b000000000, 0xe0cfe16600000000, - 0x82f7c94c00000000, 0x24bfb13200000000, 0x4687991800000000, - 0x5347914400000000, 0x317fb96e00000000, 0x9737c11000000000, - 0xf50fe93a00000000, 0xdba631ec00000000, 0xb99e19c600000000, - 0x1fd661b800000000, 0x7dee499200000000, 0x0282a1ce00000000, - 0x60ba89e400000000, 0xc6f2f19a00000000, 0xa4cad9b000000000, - 0x8a63016600000000, 0xe85b294c00000000, 0x4e13513200000000, - 0x2c2b791800000000, 0xb0cb818b00000000, 0xd2f3a9a100000000, - 0x74bbd1df00000000, 0x1683f9f500000000, 0x382a212300000000, - 0x5a12090900000000, 0xfc5a717700000000, 0x9e62595d00000000, - 0xe10eb10100000000, 0x8336992b00000000, 0x257ee15500000000, - 0x4746c97f00000000, 0x69ef11a900000000, 0x0bd7398300000000, - 0xad9f41fd00000000, 0xcfa769d700000000, 0xd458c10100000000, - 0xb660e92b00000000, 0x1028915500000000, 0x7210b97f00000000, - 0x5cb961a900000000, 0x3e81498300000000, 0x98c931fd00000000, - 0xfaf119d700000000, 0x859df18b00000000, 0xe7a5d9a100000000, - 0x41eda1df00000000, 0x23d589f500000000, 0x0d7c512300000000, - 0x6f44790900000000, 0xc90c017700000000, 0xab34295d00000000, - 0x37d4d1ce00000000, 0x55ecf9e400000000, 0xf3a4819a00000000, - 0x919ca9b000000000, 0xbf35716600000000, 0xdd0d594c00000000, - 0x7b45213200000000, 0x197d091800000000, 0x6611e14400000000, - 0x0429c96e00000000, 0xa261b11000000000, 0xc059993a00000000, - 0xeef041ec00000000, 0x8cc869c600000000, 0x2a8011b800000000, - 0x48b8399200000000}, - {0x0000000000000000, 0x4c2896a300000000, 0xd9565d9c00000000, - 0x957ecb3f00000000, 0xf3abcbe300000000, 0xbf835d4000000000, - 0x2afd967f00000000, 0x66d500dc00000000, 0xa751e61c00000000, - 0xeb7970bf00000000, 0x7e07bb8000000000, 0x322f2d2300000000, - 0x54fa2dff00000000, 0x18d2bb5c00000000, 0x8dac706300000000, - 0xc184e6c000000000, 0x4ea3cc3900000000, 0x028b5a9a00000000, - 0x97f591a500000000, 0xdbdd070600000000, 0xbd0807da00000000, - 0xf120917900000000, 0x645e5a4600000000, 0x2876cce500000000, - 0xe9f22a2500000000, 0xa5dabc8600000000, 0x30a477b900000000, - 0x7c8ce11a00000000, 0x1a59e1c600000000, 0x5671776500000000, - 0xc30fbc5a00000000, 0x8f272af900000000, 0x9c46997300000000, - 0xd06e0fd000000000, 0x4510c4ef00000000, 0x0938524c00000000, - 0x6fed529000000000, 0x23c5c43300000000, 0xb6bb0f0c00000000, - 0xfa9399af00000000, 0x3b177f6f00000000, 0x773fe9cc00000000, - 0xe24122f300000000, 0xae69b45000000000, 0xc8bcb48c00000000, - 0x8494222f00000000, 0x11eae91000000000, 0x5dc27fb300000000, - 0xd2e5554a00000000, 0x9ecdc3e900000000, 0x0bb308d600000000, - 0x479b9e7500000000, 0x214e9ea900000000, 0x6d66080a00000000, - 0xf818c33500000000, 0xb430559600000000, 0x75b4b35600000000, - 0x399c25f500000000, 0xace2eeca00000000, 0xe0ca786900000000, - 0x861f78b500000000, 0xca37ee1600000000, 0x5f49252900000000, - 0x1361b38a00000000, 0x388d32e700000000, 0x74a5a44400000000, - 0xe1db6f7b00000000, 0xadf3f9d800000000, 0xcb26f90400000000, - 0x870e6fa700000000, 0x1270a49800000000, 0x5e58323b00000000, - 0x9fdcd4fb00000000, 0xd3f4425800000000, 0x468a896700000000, - 0x0aa21fc400000000, 0x6c771f1800000000, 0x205f89bb00000000, - 0xb521428400000000, 0xf909d42700000000, 0x762efede00000000, - 0x3a06687d00000000, 0xaf78a34200000000, 0xe35035e100000000, - 0x8585353d00000000, 0xc9ada39e00000000, 0x5cd368a100000000, - 0x10fbfe0200000000, 0xd17f18c200000000, 0x9d578e6100000000, - 0x0829455e00000000, 0x4401d3fd00000000, 0x22d4d32100000000, - 0x6efc458200000000, 0xfb828ebd00000000, 0xb7aa181e00000000, - 0xa4cbab9400000000, 0xe8e33d3700000000, 0x7d9df60800000000, - 0x31b560ab00000000, 0x5760607700000000, 0x1b48f6d400000000, - 0x8e363deb00000000, 0xc21eab4800000000, 0x039a4d8800000000, - 0x4fb2db2b00000000, 0xdacc101400000000, 0x96e486b700000000, - 0xf031866b00000000, 0xbc1910c800000000, 0x2967dbf700000000, - 0x654f4d5400000000, 0xea6867ad00000000, 0xa640f10e00000000, - 0x333e3a3100000000, 0x7f16ac9200000000, 0x19c3ac4e00000000, - 0x55eb3aed00000000, 0xc095f1d200000000, 0x8cbd677100000000, - 0x4d3981b100000000, 0x0111171200000000, 0x946fdc2d00000000, - 0xd8474a8e00000000, 0xbe924a5200000000, 0xf2badcf100000000, - 0x67c417ce00000000, 0x2bec816d00000000, 0x311c141500000000, - 0x7d3482b600000000, 0xe84a498900000000, 0xa462df2a00000000, - 0xc2b7dff600000000, 0x8e9f495500000000, 0x1be1826a00000000, - 0x57c914c900000000, 0x964df20900000000, 0xda6564aa00000000, - 0x4f1baf9500000000, 0x0333393600000000, 0x65e639ea00000000, - 0x29ceaf4900000000, 0xbcb0647600000000, 0xf098f2d500000000, - 0x7fbfd82c00000000, 0x33974e8f00000000, 0xa6e985b000000000, - 0xeac1131300000000, 0x8c1413cf00000000, 0xc03c856c00000000, - 0x55424e5300000000, 0x196ad8f000000000, 0xd8ee3e3000000000, - 0x94c6a89300000000, 0x01b863ac00000000, 0x4d90f50f00000000, - 0x2b45f5d300000000, 0x676d637000000000, 0xf213a84f00000000, - 0xbe3b3eec00000000, 0xad5a8d6600000000, 0xe1721bc500000000, - 0x740cd0fa00000000, 0x3824465900000000, 0x5ef1468500000000, - 0x12d9d02600000000, 0x87a71b1900000000, 0xcb8f8dba00000000, - 0x0a0b6b7a00000000, 0x4623fdd900000000, 0xd35d36e600000000, - 0x9f75a04500000000, 0xf9a0a09900000000, 0xb588363a00000000, - 0x20f6fd0500000000, 0x6cde6ba600000000, 0xe3f9415f00000000, - 0xafd1d7fc00000000, 0x3aaf1cc300000000, 0x76878a6000000000, - 0x10528abc00000000, 0x5c7a1c1f00000000, 0xc904d72000000000, - 0x852c418300000000, 0x44a8a74300000000, 0x088031e000000000, - 0x9dfefadf00000000, 0xd1d66c7c00000000, 0xb7036ca000000000, - 0xfb2bfa0300000000, 0x6e55313c00000000, 0x227da79f00000000, - 0x099126f200000000, 0x45b9b05100000000, 0xd0c77b6e00000000, - 0x9cefedcd00000000, 0xfa3aed1100000000, 0xb6127bb200000000, - 0x236cb08d00000000, 0x6f44262e00000000, 0xaec0c0ee00000000, - 0xe2e8564d00000000, 0x77969d7200000000, 0x3bbe0bd100000000, - 0x5d6b0b0d00000000, 0x11439dae00000000, 0x843d569100000000, - 0xc815c03200000000, 0x4732eacb00000000, 0x0b1a7c6800000000, - 0x9e64b75700000000, 0xd24c21f400000000, 0xb499212800000000, - 0xf8b1b78b00000000, 0x6dcf7cb400000000, 0x21e7ea1700000000, - 0xe0630cd700000000, 0xac4b9a7400000000, 0x3935514b00000000, - 0x751dc7e800000000, 0x13c8c73400000000, 0x5fe0519700000000, - 0xca9e9aa800000000, 0x86b60c0b00000000, 0x95d7bf8100000000, - 0xd9ff292200000000, 0x4c81e21d00000000, 0x00a974be00000000, - 0x667c746200000000, 0x2a54e2c100000000, 0xbf2a29fe00000000, - 0xf302bf5d00000000, 0x3286599d00000000, 0x7eaecf3e00000000, - 0xebd0040100000000, 0xa7f892a200000000, 0xc12d927e00000000, - 0x8d0504dd00000000, 0x187bcfe200000000, 0x5453594100000000, - 0xdb7473b800000000, 0x975ce51b00000000, 0x02222e2400000000, - 0x4e0ab88700000000, 0x28dfb85b00000000, 0x64f72ef800000000, - 0xf189e5c700000000, 0xbda1736400000000, 0x7c2595a400000000, - 0x300d030700000000, 0xa573c83800000000, 0xe95b5e9b00000000, - 0x8f8e5e4700000000, 0xc3a6c8e400000000, 0x56d803db00000000, - 0x1af0957800000000}, - {0x0000000000000000, 0x939bc97f00000000, 0x263793ff00000000, - 0xb5ac5a8000000000, 0x0d68572400000000, 0x9ef39e5b00000000, - 0x2b5fc4db00000000, 0xb8c40da400000000, 0x1ad0ae4800000000, - 0x894b673700000000, 0x3ce73db700000000, 0xaf7cf4c800000000, - 0x17b8f96c00000000, 0x8423301300000000, 0x318f6a9300000000, - 0xa214a3ec00000000, 0x34a05d9100000000, 0xa73b94ee00000000, - 0x1297ce6e00000000, 0x810c071100000000, 0x39c80ab500000000, - 0xaa53c3ca00000000, 0x1fff994a00000000, 0x8c64503500000000, - 0x2e70f3d900000000, 0xbdeb3aa600000000, 0x0847602600000000, - 0x9bdca95900000000, 0x2318a4fd00000000, 0xb0836d8200000000, - 0x052f370200000000, 0x96b4fe7d00000000, 0x2946caf900000000, - 0xbadd038600000000, 0x0f71590600000000, 0x9cea907900000000, - 0x242e9ddd00000000, 0xb7b554a200000000, 0x02190e2200000000, - 0x9182c75d00000000, 0x339664b100000000, 0xa00dadce00000000, - 0x15a1f74e00000000, 0x863a3e3100000000, 0x3efe339500000000, - 0xad65faea00000000, 0x18c9a06a00000000, 0x8b52691500000000, - 0x1de6976800000000, 0x8e7d5e1700000000, 0x3bd1049700000000, - 0xa84acde800000000, 0x108ec04c00000000, 0x8315093300000000, - 0x36b953b300000000, 0xa5229acc00000000, 0x0736392000000000, - 0x94adf05f00000000, 0x2101aadf00000000, 0xb29a63a000000000, - 0x0a5e6e0400000000, 0x99c5a77b00000000, 0x2c69fdfb00000000, - 0xbff2348400000000, 0x138ae52800000000, 0x80112c5700000000, - 0x35bd76d700000000, 0xa626bfa800000000, 0x1ee2b20c00000000, - 0x8d797b7300000000, 0x38d521f300000000, 0xab4ee88c00000000, - 0x095a4b6000000000, 0x9ac1821f00000000, 0x2f6dd89f00000000, - 0xbcf611e000000000, 0x04321c4400000000, 0x97a9d53b00000000, - 0x22058fbb00000000, 0xb19e46c400000000, 0x272ab8b900000000, - 0xb4b171c600000000, 0x011d2b4600000000, 0x9286e23900000000, - 0x2a42ef9d00000000, 0xb9d926e200000000, 0x0c757c6200000000, - 0x9feeb51d00000000, 0x3dfa16f100000000, 0xae61df8e00000000, - 0x1bcd850e00000000, 0x88564c7100000000, 0x309241d500000000, - 0xa30988aa00000000, 0x16a5d22a00000000, 0x853e1b5500000000, - 0x3acc2fd100000000, 0xa957e6ae00000000, 0x1cfbbc2e00000000, - 0x8f60755100000000, 0x37a478f500000000, 0xa43fb18a00000000, - 0x1193eb0a00000000, 0x8208227500000000, 0x201c819900000000, - 0xb38748e600000000, 0x062b126600000000, 0x95b0db1900000000, - 0x2d74d6bd00000000, 0xbeef1fc200000000, 0x0b43454200000000, - 0x98d88c3d00000000, 0x0e6c724000000000, 0x9df7bb3f00000000, - 0x285be1bf00000000, 0xbbc028c000000000, 0x0304256400000000, - 0x909fec1b00000000, 0x2533b69b00000000, 0xb6a87fe400000000, - 0x14bcdc0800000000, 0x8727157700000000, 0x328b4ff700000000, - 0xa110868800000000, 0x19d48b2c00000000, 0x8a4f425300000000, - 0x3fe318d300000000, 0xac78d1ac00000000, 0x2614cb5100000000, - 0xb58f022e00000000, 0x002358ae00000000, 0x93b891d100000000, - 0x2b7c9c7500000000, 0xb8e7550a00000000, 0x0d4b0f8a00000000, - 0x9ed0c6f500000000, 0x3cc4651900000000, 0xaf5fac6600000000, - 0x1af3f6e600000000, 0x89683f9900000000, 0x31ac323d00000000, - 0xa237fb4200000000, 0x179ba1c200000000, 0x840068bd00000000, - 0x12b496c000000000, 0x812f5fbf00000000, 0x3483053f00000000, - 0xa718cc4000000000, 0x1fdcc1e400000000, 0x8c47089b00000000, - 0x39eb521b00000000, 0xaa709b6400000000, 0x0864388800000000, - 0x9bfff1f700000000, 0x2e53ab7700000000, 0xbdc8620800000000, - 0x050c6fac00000000, 0x9697a6d300000000, 0x233bfc5300000000, - 0xb0a0352c00000000, 0x0f5201a800000000, 0x9cc9c8d700000000, - 0x2965925700000000, 0xbafe5b2800000000, 0x023a568c00000000, - 0x91a19ff300000000, 0x240dc57300000000, 0xb7960c0c00000000, - 0x1582afe000000000, 0x8619669f00000000, 0x33b53c1f00000000, - 0xa02ef56000000000, 0x18eaf8c400000000, 0x8b7131bb00000000, - 0x3edd6b3b00000000, 0xad46a24400000000, 0x3bf25c3900000000, - 0xa869954600000000, 0x1dc5cfc600000000, 0x8e5e06b900000000, - 0x369a0b1d00000000, 0xa501c26200000000, 0x10ad98e200000000, - 0x8336519d00000000, 0x2122f27100000000, 0xb2b93b0e00000000, - 0x0715618e00000000, 0x948ea8f100000000, 0x2c4aa55500000000, - 0xbfd16c2a00000000, 0x0a7d36aa00000000, 0x99e6ffd500000000, - 0x359e2e7900000000, 0xa605e70600000000, 0x13a9bd8600000000, - 0x803274f900000000, 0x38f6795d00000000, 0xab6db02200000000, - 0x1ec1eaa200000000, 0x8d5a23dd00000000, 0x2f4e803100000000, - 0xbcd5494e00000000, 0x097913ce00000000, 0x9ae2dab100000000, - 0x2226d71500000000, 0xb1bd1e6a00000000, 0x041144ea00000000, - 0x978a8d9500000000, 0x013e73e800000000, 0x92a5ba9700000000, - 0x2709e01700000000, 0xb492296800000000, 0x0c5624cc00000000, - 0x9fcdedb300000000, 0x2a61b73300000000, 0xb9fa7e4c00000000, - 0x1beedda000000000, 0x887514df00000000, 0x3dd94e5f00000000, - 0xae42872000000000, 0x16868a8400000000, 0x851d43fb00000000, - 0x30b1197b00000000, 0xa32ad00400000000, 0x1cd8e48000000000, - 0x8f432dff00000000, 0x3aef777f00000000, 0xa974be0000000000, - 0x11b0b3a400000000, 0x822b7adb00000000, 0x3787205b00000000, - 0xa41ce92400000000, 0x06084ac800000000, 0x959383b700000000, - 0x203fd93700000000, 0xb3a4104800000000, 0x0b601dec00000000, - 0x98fbd49300000000, 0x2d578e1300000000, 0xbecc476c00000000, - 0x2878b91100000000, 0xbbe3706e00000000, 0x0e4f2aee00000000, - 0x9dd4e39100000000, 0x2510ee3500000000, 0xb68b274a00000000, - 0x03277dca00000000, 0x90bcb4b500000000, 0x32a8175900000000, - 0xa133de2600000000, 0x149f84a600000000, 0x87044dd900000000, - 0x3fc0407d00000000, 0xac5b890200000000, 0x19f7d38200000000, - 0x8a6c1afd00000000}, - {0x0000000000000000, 0x650b796900000000, 0xca16f2d200000000, - 0xaf1d8bbb00000000, 0xd52b957e00000000, 0xb020ec1700000000, - 0x1f3d67ac00000000, 0x7a361ec500000000, 0xaa572afd00000000, - 0xcf5c539400000000, 0x6041d82f00000000, 0x054aa14600000000, - 0x7f7cbf8300000000, 0x1a77c6ea00000000, 0xb56a4d5100000000, - 0xd061343800000000, 0x15a9252100000000, 0x70a25c4800000000, - 0xdfbfd7f300000000, 0xbab4ae9a00000000, 0xc082b05f00000000, - 0xa589c93600000000, 0x0a94428d00000000, 0x6f9f3be400000000, - 0xbffe0fdc00000000, 0xdaf576b500000000, 0x75e8fd0e00000000, - 0x10e3846700000000, 0x6ad59aa200000000, 0x0fdee3cb00000000, - 0xa0c3687000000000, 0xc5c8111900000000, 0x2a524b4200000000, - 0x4f59322b00000000, 0xe044b99000000000, 0x854fc0f900000000, - 0xff79de3c00000000, 0x9a72a75500000000, 0x356f2cee00000000, - 0x5064558700000000, 0x800561bf00000000, 0xe50e18d600000000, - 0x4a13936d00000000, 0x2f18ea0400000000, 0x552ef4c100000000, - 0x30258da800000000, 0x9f38061300000000, 0xfa337f7a00000000, - 0x3ffb6e6300000000, 0x5af0170a00000000, 0xf5ed9cb100000000, - 0x90e6e5d800000000, 0xead0fb1d00000000, 0x8fdb827400000000, - 0x20c609cf00000000, 0x45cd70a600000000, 0x95ac449e00000000, - 0xf0a73df700000000, 0x5fbab64c00000000, 0x3ab1cf2500000000, - 0x4087d1e000000000, 0x258ca88900000000, 0x8a91233200000000, - 0xef9a5a5b00000000, 0x54a4968400000000, 0x31afefed00000000, - 0x9eb2645600000000, 0xfbb91d3f00000000, 0x818f03fa00000000, - 0xe4847a9300000000, 0x4b99f12800000000, 0x2e92884100000000, - 0xfef3bc7900000000, 0x9bf8c51000000000, 0x34e54eab00000000, - 0x51ee37c200000000, 0x2bd8290700000000, 0x4ed3506e00000000, - 0xe1cedbd500000000, 0x84c5a2bc00000000, 0x410db3a500000000, - 0x2406cacc00000000, 0x8b1b417700000000, 0xee10381e00000000, - 0x942626db00000000, 0xf12d5fb200000000, 0x5e30d40900000000, - 0x3b3bad6000000000, 0xeb5a995800000000, 0x8e51e03100000000, - 0x214c6b8a00000000, 0x444712e300000000, 0x3e710c2600000000, - 0x5b7a754f00000000, 0xf467fef400000000, 0x916c879d00000000, - 0x7ef6ddc600000000, 0x1bfda4af00000000, 0xb4e02f1400000000, - 0xd1eb567d00000000, 0xabdd48b800000000, 0xced631d100000000, - 0x61cbba6a00000000, 0x04c0c30300000000, 0xd4a1f73b00000000, - 0xb1aa8e5200000000, 0x1eb705e900000000, 0x7bbc7c8000000000, - 0x018a624500000000, 0x64811b2c00000000, 0xcb9c909700000000, - 0xae97e9fe00000000, 0x6b5ff8e700000000, 0x0e54818e00000000, - 0xa1490a3500000000, 0xc442735c00000000, 0xbe746d9900000000, - 0xdb7f14f000000000, 0x74629f4b00000000, 0x1169e62200000000, - 0xc108d21a00000000, 0xa403ab7300000000, 0x0b1e20c800000000, - 0x6e1559a100000000, 0x1423476400000000, 0x71283e0d00000000, - 0xde35b5b600000000, 0xbb3eccdf00000000, 0xe94e5cd200000000, - 0x8c4525bb00000000, 0x2358ae0000000000, 0x4653d76900000000, - 0x3c65c9ac00000000, 0x596eb0c500000000, 0xf6733b7e00000000, - 0x9378421700000000, 0x4319762f00000000, 0x26120f4600000000, - 0x890f84fd00000000, 0xec04fd9400000000, 0x9632e35100000000, - 0xf3399a3800000000, 0x5c24118300000000, 0x392f68ea00000000, - 0xfce779f300000000, 0x99ec009a00000000, 0x36f18b2100000000, - 0x53faf24800000000, 0x29ccec8d00000000, 0x4cc795e400000000, - 0xe3da1e5f00000000, 0x86d1673600000000, 0x56b0530e00000000, - 0x33bb2a6700000000, 0x9ca6a1dc00000000, 0xf9add8b500000000, - 0x839bc67000000000, 0xe690bf1900000000, 0x498d34a200000000, - 0x2c864dcb00000000, 0xc31c179000000000, 0xa6176ef900000000, - 0x090ae54200000000, 0x6c019c2b00000000, 0x163782ee00000000, - 0x733cfb8700000000, 0xdc21703c00000000, 0xb92a095500000000, - 0x694b3d6d00000000, 0x0c40440400000000, 0xa35dcfbf00000000, - 0xc656b6d600000000, 0xbc60a81300000000, 0xd96bd17a00000000, - 0x76765ac100000000, 0x137d23a800000000, 0xd6b532b100000000, - 0xb3be4bd800000000, 0x1ca3c06300000000, 0x79a8b90a00000000, - 0x039ea7cf00000000, 0x6695dea600000000, 0xc988551d00000000, - 0xac832c7400000000, 0x7ce2184c00000000, 0x19e9612500000000, - 0xb6f4ea9e00000000, 0xd3ff93f700000000, 0xa9c98d3200000000, - 0xccc2f45b00000000, 0x63df7fe000000000, 0x06d4068900000000, - 0xbdeaca5600000000, 0xd8e1b33f00000000, 0x77fc388400000000, - 0x12f741ed00000000, 0x68c15f2800000000, 0x0dca264100000000, - 0xa2d7adfa00000000, 0xc7dcd49300000000, 0x17bde0ab00000000, - 0x72b699c200000000, 0xddab127900000000, 0xb8a06b1000000000, - 0xc29675d500000000, 0xa79d0cbc00000000, 0x0880870700000000, - 0x6d8bfe6e00000000, 0xa843ef7700000000, 0xcd48961e00000000, - 0x62551da500000000, 0x075e64cc00000000, 0x7d687a0900000000, - 0x1863036000000000, 0xb77e88db00000000, 0xd275f1b200000000, - 0x0214c58a00000000, 0x671fbce300000000, 0xc802375800000000, - 0xad094e3100000000, 0xd73f50f400000000, 0xb234299d00000000, - 0x1d29a22600000000, 0x7822db4f00000000, 0x97b8811400000000, - 0xf2b3f87d00000000, 0x5dae73c600000000, 0x38a50aaf00000000, - 0x4293146a00000000, 0x27986d0300000000, 0x8885e6b800000000, - 0xed8e9fd100000000, 0x3defabe900000000, 0x58e4d28000000000, - 0xf7f9593b00000000, 0x92f2205200000000, 0xe8c43e9700000000, - 0x8dcf47fe00000000, 0x22d2cc4500000000, 0x47d9b52c00000000, - 0x8211a43500000000, 0xe71add5c00000000, 0x480756e700000000, - 0x2d0c2f8e00000000, 0x573a314b00000000, 0x3231482200000000, - 0x9d2cc39900000000, 0xf827baf000000000, 0x28468ec800000000, - 0x4d4df7a100000000, 0xe2507c1a00000000, 0x875b057300000000, - 0xfd6d1bb600000000, 0x986662df00000000, 0x377be96400000000, - 0x5270900d00000000}, - {0x0000000000000000, 0xdcecb13d00000000, 0xb8d9637b00000000, - 0x6435d24600000000, 0x70b3c7f600000000, 0xac5f76cb00000000, - 0xc86aa48d00000000, 0x148615b000000000, 0xa160fe3600000000, - 0x7d8c4f0b00000000, 0x19b99d4d00000000, 0xc5552c7000000000, - 0xd1d339c000000000, 0x0d3f88fd00000000, 0x690a5abb00000000, - 0xb5e6eb8600000000, 0x42c1fc6d00000000, 0x9e2d4d5000000000, - 0xfa189f1600000000, 0x26f42e2b00000000, 0x32723b9b00000000, - 0xee9e8aa600000000, 0x8aab58e000000000, 0x5647e9dd00000000, - 0xe3a1025b00000000, 0x3f4db36600000000, 0x5b78612000000000, - 0x8794d01d00000000, 0x9312c5ad00000000, 0x4ffe749000000000, - 0x2bcba6d600000000, 0xf72717eb00000000, 0x8482f9db00000000, - 0x586e48e600000000, 0x3c5b9aa000000000, 0xe0b72b9d00000000, - 0xf4313e2d00000000, 0x28dd8f1000000000, 0x4ce85d5600000000, - 0x9004ec6b00000000, 0x25e207ed00000000, 0xf90eb6d000000000, - 0x9d3b649600000000, 0x41d7d5ab00000000, 0x5551c01b00000000, - 0x89bd712600000000, 0xed88a36000000000, 0x3164125d00000000, - 0xc64305b600000000, 0x1aafb48b00000000, 0x7e9a66cd00000000, - 0xa276d7f000000000, 0xb6f0c24000000000, 0x6a1c737d00000000, - 0x0e29a13b00000000, 0xd2c5100600000000, 0x6723fb8000000000, - 0xbbcf4abd00000000, 0xdffa98fb00000000, 0x031629c600000000, - 0x17903c7600000000, 0xcb7c8d4b00000000, 0xaf495f0d00000000, - 0x73a5ee3000000000, 0x4903826c00000000, 0x95ef335100000000, - 0xf1dae11700000000, 0x2d36502a00000000, 0x39b0459a00000000, - 0xe55cf4a700000000, 0x816926e100000000, 0x5d8597dc00000000, - 0xe8637c5a00000000, 0x348fcd6700000000, 0x50ba1f2100000000, - 0x8c56ae1c00000000, 0x98d0bbac00000000, 0x443c0a9100000000, - 0x2009d8d700000000, 0xfce569ea00000000, 0x0bc27e0100000000, - 0xd72ecf3c00000000, 0xb31b1d7a00000000, 0x6ff7ac4700000000, - 0x7b71b9f700000000, 0xa79d08ca00000000, 0xc3a8da8c00000000, - 0x1f446bb100000000, 0xaaa2803700000000, 0x764e310a00000000, - 0x127be34c00000000, 0xce97527100000000, 0xda1147c100000000, - 0x06fdf6fc00000000, 0x62c824ba00000000, 0xbe24958700000000, - 0xcd817bb700000000, 0x116dca8a00000000, 0x755818cc00000000, - 0xa9b4a9f100000000, 0xbd32bc4100000000, 0x61de0d7c00000000, - 0x05ebdf3a00000000, 0xd9076e0700000000, 0x6ce1858100000000, - 0xb00d34bc00000000, 0xd438e6fa00000000, 0x08d457c700000000, - 0x1c52427700000000, 0xc0bef34a00000000, 0xa48b210c00000000, - 0x7867903100000000, 0x8f4087da00000000, 0x53ac36e700000000, - 0x3799e4a100000000, 0xeb75559c00000000, 0xfff3402c00000000, - 0x231ff11100000000, 0x472a235700000000, 0x9bc6926a00000000, - 0x2e2079ec00000000, 0xf2ccc8d100000000, 0x96f91a9700000000, - 0x4a15abaa00000000, 0x5e93be1a00000000, 0x827f0f2700000000, - 0xe64add6100000000, 0x3aa66c5c00000000, 0x920604d900000000, - 0x4eeab5e400000000, 0x2adf67a200000000, 0xf633d69f00000000, - 0xe2b5c32f00000000, 0x3e59721200000000, 0x5a6ca05400000000, - 0x8680116900000000, 0x3366faef00000000, 0xef8a4bd200000000, - 0x8bbf999400000000, 0x575328a900000000, 0x43d53d1900000000, - 0x9f398c2400000000, 0xfb0c5e6200000000, 0x27e0ef5f00000000, - 0xd0c7f8b400000000, 0x0c2b498900000000, 0x681e9bcf00000000, - 0xb4f22af200000000, 0xa0743f4200000000, 0x7c988e7f00000000, - 0x18ad5c3900000000, 0xc441ed0400000000, 0x71a7068200000000, - 0xad4bb7bf00000000, 0xc97e65f900000000, 0x1592d4c400000000, - 0x0114c17400000000, 0xddf8704900000000, 0xb9cda20f00000000, - 0x6521133200000000, 0x1684fd0200000000, 0xca684c3f00000000, - 0xae5d9e7900000000, 0x72b12f4400000000, 0x66373af400000000, - 0xbadb8bc900000000, 0xdeee598f00000000, 0x0202e8b200000000, - 0xb7e4033400000000, 0x6b08b20900000000, 0x0f3d604f00000000, - 0xd3d1d17200000000, 0xc757c4c200000000, 0x1bbb75ff00000000, - 0x7f8ea7b900000000, 0xa362168400000000, 0x5445016f00000000, - 0x88a9b05200000000, 0xec9c621400000000, 0x3070d32900000000, - 0x24f6c69900000000, 0xf81a77a400000000, 0x9c2fa5e200000000, - 0x40c314df00000000, 0xf525ff5900000000, 0x29c94e6400000000, - 0x4dfc9c2200000000, 0x91102d1f00000000, 0x859638af00000000, - 0x597a899200000000, 0x3d4f5bd400000000, 0xe1a3eae900000000, - 0xdb0586b500000000, 0x07e9378800000000, 0x63dce5ce00000000, - 0xbf3054f300000000, 0xabb6414300000000, 0x775af07e00000000, - 0x136f223800000000, 0xcf83930500000000, 0x7a65788300000000, - 0xa689c9be00000000, 0xc2bc1bf800000000, 0x1e50aac500000000, - 0x0ad6bf7500000000, 0xd63a0e4800000000, 0xb20fdc0e00000000, - 0x6ee36d3300000000, 0x99c47ad800000000, 0x4528cbe500000000, - 0x211d19a300000000, 0xfdf1a89e00000000, 0xe977bd2e00000000, - 0x359b0c1300000000, 0x51aede5500000000, 0x8d426f6800000000, - 0x38a484ee00000000, 0xe44835d300000000, 0x807de79500000000, - 0x5c9156a800000000, 0x4817431800000000, 0x94fbf22500000000, - 0xf0ce206300000000, 0x2c22915e00000000, 0x5f877f6e00000000, - 0x836bce5300000000, 0xe75e1c1500000000, 0x3bb2ad2800000000, - 0x2f34b89800000000, 0xf3d809a500000000, 0x97eddbe300000000, - 0x4b016ade00000000, 0xfee7815800000000, 0x220b306500000000, - 0x463ee22300000000, 0x9ad2531e00000000, 0x8e5446ae00000000, - 0x52b8f79300000000, 0x368d25d500000000, 0xea6194e800000000, - 0x1d46830300000000, 0xc1aa323e00000000, 0xa59fe07800000000, - 0x7973514500000000, 0x6df544f500000000, 0xb119f5c800000000, - 0xd52c278e00000000, 0x09c096b300000000, 0xbc267d3500000000, - 0x60cacc0800000000, 0x04ff1e4e00000000, 0xd813af7300000000, - 0xcc95bac300000000, 0x10790bfe00000000, 0x744cd9b800000000, - 0xa8a0688500000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, - 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, - 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, - 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, - 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, - 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, - 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, - 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, - 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, - 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, - 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, - 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, - 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, - 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, - 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, - 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, - 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, - 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, - 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, - 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, - 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, - 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, - 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, - 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, - 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, - 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, - 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, - 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, - 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, - 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, - 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, - 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, - 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, - 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, - 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, - 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, - 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, - 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, - 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, - 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, - 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, - 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, - 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, - 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, - 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, - 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, - 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, - 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, - 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, - 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, - 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, - 0x09cd8551}, - {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, - 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, - 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, - 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, - 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, - 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, - 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, - 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, - 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, - 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, - 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, - 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, - 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, - 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, - 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, - 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, - 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, - 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, - 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, - 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, - 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, - 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, - 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, - 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, - 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, - 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, - 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, - 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, - 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, - 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, - 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, - 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, - 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, - 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, - 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, - 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, - 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, - 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, - 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, - 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, - 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, - 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, - 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, - 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, - 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, - 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, - 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, - 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, - 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, - 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, - 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, - 0x7bc97a0c}, - {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, - 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, - 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, - 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, - 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, - 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, - 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, - 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, - 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, - 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, - 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, - 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, - 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, - 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, - 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, - 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, - 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, - 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, - 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, - 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, - 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, - 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, - 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, - 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, - 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, - 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, - 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, - 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, - 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, - 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, - 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, - 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, - 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, - 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, - 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, - 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, - 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, - 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, - 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, - 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, - 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, - 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, - 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, - 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, - 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, - 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, - 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, - 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, - 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, - 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, - 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, - 0x7851a2ca}, - {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, - 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, - 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, - 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, - 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, - 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, - 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, - 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, - 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, - 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, - 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, - 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, - 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, - 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, - 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, - 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, - 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, - 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, - 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, - 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, - 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, - 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, - 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, - 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, - 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, - 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, - 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, - 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, - 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, - 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, - 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, - 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, - 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, - 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, - 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, - 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, - 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, - 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, - 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, - 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, - 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, - 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, - 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, - 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, - 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, - 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, - 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, - 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, - 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, - 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, - 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, - 0x566b6848}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x9e83da9f, 0x7d01c4e4, 0xe3821e7b, 0xbb04f912, - 0x2587238d, 0xc6053df6, 0x5886e769, 0x7609f225, 0xe88a28ba, - 0x0b0836c1, 0x958bec5e, 0xcd0d0b37, 0x538ed1a8, 0xb00ccfd3, - 0x2e8f154c, 0xec12e44b, 0x72913ed4, 0x911320af, 0x0f90fa30, - 0x57161d59, 0xc995c7c6, 0x2a17d9bd, 0xb4940322, 0x9a1b166e, - 0x0498ccf1, 0xe71ad28a, 0x79990815, 0x211fef7c, 0xbf9c35e3, - 0x5c1e2b98, 0xc29df107, 0xd825c897, 0x46a61208, 0xa5240c73, - 0x3ba7d6ec, 0x63213185, 0xfda2eb1a, 0x1e20f561, 0x80a32ffe, - 0xae2c3ab2, 0x30afe02d, 0xd32dfe56, 0x4dae24c9, 0x1528c3a0, - 0x8bab193f, 0x68290744, 0xf6aadddb, 0x34372cdc, 0xaab4f643, - 0x4936e838, 0xd7b532a7, 0x8f33d5ce, 0x11b00f51, 0xf232112a, - 0x6cb1cbb5, 0x423edef9, 0xdcbd0466, 0x3f3f1a1d, 0xa1bcc082, - 0xf93a27eb, 0x67b9fd74, 0x843be30f, 0x1ab83990, 0xf14de1f4, - 0x6fce3b6b, 0x8c4c2510, 0x12cfff8f, 0x4a4918e6, 0xd4cac279, - 0x3748dc02, 0xa9cb069d, 0x874413d1, 0x19c7c94e, 0xfa45d735, - 0x64c60daa, 0x3c40eac3, 0xa2c3305c, 0x41412e27, 0xdfc2f4b8, - 0x1d5f05bf, 0x83dcdf20, 0x605ec15b, 0xfedd1bc4, 0xa65bfcad, - 0x38d82632, 0xdb5a3849, 0x45d9e2d6, 0x6b56f79a, 0xf5d52d05, - 0x1657337e, 0x88d4e9e1, 0xd0520e88, 0x4ed1d417, 0xad53ca6c, - 0x33d010f3, 0x29682963, 0xb7ebf3fc, 0x5469ed87, 0xcaea3718, - 0x926cd071, 0x0cef0aee, 0xef6d1495, 0x71eece0a, 0x5f61db46, - 0xc1e201d9, 0x22601fa2, 0xbce3c53d, 0xe4652254, 0x7ae6f8cb, - 0x9964e6b0, 0x07e73c2f, 0xc57acd28, 0x5bf917b7, 0xb87b09cc, - 0x26f8d353, 0x7e7e343a, 0xe0fdeea5, 0x037ff0de, 0x9dfc2a41, - 0xb3733f0d, 0x2df0e592, 0xce72fbe9, 0x50f12176, 0x0877c61f, - 0x96f41c80, 0x757602fb, 0xebf5d864, 0xa39db332, 0x3d1e69ad, - 0xde9c77d6, 0x401fad49, 0x18994a20, 0x861a90bf, 0x65988ec4, - 0xfb1b545b, 0xd5944117, 0x4b179b88, 0xa89585f3, 0x36165f6c, - 0x6e90b805, 0xf013629a, 0x13917ce1, 0x8d12a67e, 0x4f8f5779, - 0xd10c8de6, 0x328e939d, 0xac0d4902, 0xf48bae6b, 0x6a0874f4, - 0x898a6a8f, 0x1709b010, 0x3986a55c, 0xa7057fc3, 0x448761b8, - 0xda04bb27, 0x82825c4e, 0x1c0186d1, 0xff8398aa, 0x61004235, - 0x7bb87ba5, 0xe53ba13a, 0x06b9bf41, 0x983a65de, 0xc0bc82b7, - 0x5e3f5828, 0xbdbd4653, 0x233e9ccc, 0x0db18980, 0x9332531f, - 0x70b04d64, 0xee3397fb, 0xb6b57092, 0x2836aa0d, 0xcbb4b476, - 0x55376ee9, 0x97aa9fee, 0x09294571, 0xeaab5b0a, 0x74288195, - 0x2cae66fc, 0xb22dbc63, 0x51afa218, 0xcf2c7887, 0xe1a36dcb, - 0x7f20b754, 0x9ca2a92f, 0x022173b0, 0x5aa794d9, 0xc4244e46, - 0x27a6503d, 0xb9258aa2, 0x52d052c6, 0xcc538859, 0x2fd19622, - 0xb1524cbd, 0xe9d4abd4, 0x7757714b, 0x94d56f30, 0x0a56b5af, - 0x24d9a0e3, 0xba5a7a7c, 0x59d86407, 0xc75bbe98, 0x9fdd59f1, - 0x015e836e, 0xe2dc9d15, 0x7c5f478a, 0xbec2b68d, 0x20416c12, - 0xc3c37269, 0x5d40a8f6, 0x05c64f9f, 0x9b459500, 0x78c78b7b, - 0xe64451e4, 0xc8cb44a8, 0x56489e37, 0xb5ca804c, 0x2b495ad3, - 0x73cfbdba, 0xed4c6725, 0x0ece795e, 0x904da3c1, 0x8af59a51, - 0x147640ce, 0xf7f45eb5, 0x6977842a, 0x31f16343, 0xaf72b9dc, - 0x4cf0a7a7, 0xd2737d38, 0xfcfc6874, 0x627fb2eb, 0x81fdac90, - 0x1f7e760f, 0x47f89166, 0xd97b4bf9, 0x3af95582, 0xa47a8f1d, - 0x66e77e1a, 0xf864a485, 0x1be6bafe, 0x85656061, 0xdde38708, - 0x43605d97, 0xa0e243ec, 0x3e619973, 0x10ee8c3f, 0x8e6d56a0, - 0x6def48db, 0xf36c9244, 0xabea752d, 0x3569afb2, 0xd6ebb1c9, - 0x48686b56}, - {0x00000000, 0xc0642817, 0x80c9502e, 0x40ad7839, 0x0093a15c, - 0xc0f7894b, 0x805af172, 0x403ed965, 0x002643b9, 0xc0426bae, - 0x80ef1397, 0x408b3b80, 0x00b5e2e5, 0xc0d1caf2, 0x807cb2cb, - 0x40189adc, 0x414af7a9, 0x812edfbe, 0xc183a787, 0x01e78f90, - 0x41d956f5, 0x81bd7ee2, 0xc11006db, 0x01742ecc, 0x416cb410, - 0x81089c07, 0xc1a5e43e, 0x01c1cc29, 0x41ff154c, 0x819b3d5b, - 0xc1364562, 0x01526d75, 0xc3929f88, 0x03f6b79f, 0x435bcfa6, - 0x833fe7b1, 0xc3013ed4, 0x036516c3, 0x43c86efa, 0x83ac46ed, - 0xc3b4dc31, 0x03d0f426, 0x437d8c1f, 0x8319a408, 0xc3277d6d, - 0x0343557a, 0x43ee2d43, 0x838a0554, 0x82d86821, 0x42bc4036, - 0x0211380f, 0xc2751018, 0x824bc97d, 0x422fe16a, 0x02829953, - 0xc2e6b144, 0x82fe2b98, 0x429a038f, 0x02377bb6, 0xc25353a1, - 0x826d8ac4, 0x4209a2d3, 0x02a4daea, 0xc2c0f2fd, 0xc7234eca, - 0x074766dd, 0x47ea1ee4, 0x878e36f3, 0xc7b0ef96, 0x07d4c781, - 0x4779bfb8, 0x871d97af, 0xc7050d73, 0x07612564, 0x47cc5d5d, - 0x87a8754a, 0xc796ac2f, 0x07f28438, 0x475ffc01, 0x873bd416, - 0x8669b963, 0x460d9174, 0x06a0e94d, 0xc6c4c15a, 0x86fa183f, - 0x469e3028, 0x06334811, 0xc6576006, 0x864ffada, 0x462bd2cd, - 0x0686aaf4, 0xc6e282e3, 0x86dc5b86, 0x46b87391, 0x06150ba8, - 0xc67123bf, 0x04b1d142, 0xc4d5f955, 0x8478816c, 0x441ca97b, - 0x0422701e, 0xc4465809, 0x84eb2030, 0x448f0827, 0x049792fb, - 0xc4f3baec, 0x845ec2d5, 0x443aeac2, 0x040433a7, 0xc4601bb0, - 0x84cd6389, 0x44a94b9e, 0x45fb26eb, 0x859f0efc, 0xc53276c5, - 0x05565ed2, 0x456887b7, 0x850cafa0, 0xc5a1d799, 0x05c5ff8e, - 0x45dd6552, 0x85b94d45, 0xc514357c, 0x05701d6b, 0x454ec40e, - 0x852aec19, 0xc5879420, 0x05e3bc37, 0xcf41ed4f, 0x0f25c558, - 0x4f88bd61, 0x8fec9576, 0xcfd24c13, 0x0fb66404, 0x4f1b1c3d, - 0x8f7f342a, 0xcf67aef6, 0x0f0386e1, 0x4faefed8, 0x8fcad6cf, - 0xcff40faa, 0x0f9027bd, 0x4f3d5f84, 0x8f597793, 0x8e0b1ae6, - 0x4e6f32f1, 0x0ec24ac8, 0xcea662df, 0x8e98bbba, 0x4efc93ad, - 0x0e51eb94, 0xce35c383, 0x8e2d595f, 0x4e497148, 0x0ee40971, - 0xce802166, 0x8ebef803, 0x4edad014, 0x0e77a82d, 0xce13803a, - 0x0cd372c7, 0xccb75ad0, 0x8c1a22e9, 0x4c7e0afe, 0x0c40d39b, - 0xcc24fb8c, 0x8c8983b5, 0x4cedaba2, 0x0cf5317e, 0xcc911969, - 0x8c3c6150, 0x4c584947, 0x0c669022, 0xcc02b835, 0x8cafc00c, - 0x4ccbe81b, 0x4d99856e, 0x8dfdad79, 0xcd50d540, 0x0d34fd57, - 0x4d0a2432, 0x8d6e0c25, 0xcdc3741c, 0x0da75c0b, 0x4dbfc6d7, - 0x8ddbeec0, 0xcd7696f9, 0x0d12beee, 0x4d2c678b, 0x8d484f9c, - 0xcde537a5, 0x0d811fb2, 0x0862a385, 0xc8068b92, 0x88abf3ab, - 0x48cfdbbc, 0x08f102d9, 0xc8952ace, 0x883852f7, 0x485c7ae0, - 0x0844e03c, 0xc820c82b, 0x888db012, 0x48e99805, 0x08d74160, - 0xc8b36977, 0x881e114e, 0x487a3959, 0x4928542c, 0x894c7c3b, - 0xc9e10402, 0x09852c15, 0x49bbf570, 0x89dfdd67, 0xc972a55e, - 0x09168d49, 0x490e1795, 0x896a3f82, 0xc9c747bb, 0x09a36fac, - 0x499db6c9, 0x89f99ede, 0xc954e6e7, 0x0930cef0, 0xcbf03c0d, - 0x0b94141a, 0x4b396c23, 0x8b5d4434, 0xcb639d51, 0x0b07b546, - 0x4baacd7f, 0x8bcee568, 0xcbd67fb4, 0x0bb257a3, 0x4b1f2f9a, - 0x8b7b078d, 0xcb45dee8, 0x0b21f6ff, 0x4b8c8ec6, 0x8be8a6d1, - 0x8abacba4, 0x4adee3b3, 0x0a739b8a, 0xca17b39d, 0x8a296af8, - 0x4a4d42ef, 0x0ae03ad6, 0xca8412c1, 0x8a9c881d, 0x4af8a00a, - 0x0a55d833, 0xca31f024, 0x8a0f2941, 0x4a6b0156, 0x0ac6796f, - 0xcaa25178}, - {0x00000000, 0xd4ea739b, 0xe9d396ed, 0x3d39e576, 0x93a15c00, - 0x474b2f9b, 0x7a72caed, 0xae98b976, 0x2643b900, 0xf2a9ca9b, - 0xcf902fed, 0x1b7a5c76, 0xb5e2e500, 0x6108969b, 0x5c3173ed, - 0x88db0076, 0x4c867201, 0x986c019a, 0xa555e4ec, 0x71bf9777, - 0xdf272e01, 0x0bcd5d9a, 0x36f4b8ec, 0xe21ecb77, 0x6ac5cb01, - 0xbe2fb89a, 0x83165dec, 0x57fc2e77, 0xf9649701, 0x2d8ee49a, - 0x10b701ec, 0xc45d7277, 0x980ce502, 0x4ce69699, 0x71df73ef, - 0xa5350074, 0x0badb902, 0xdf47ca99, 0xe27e2fef, 0x36945c74, - 0xbe4f5c02, 0x6aa52f99, 0x579ccaef, 0x8376b974, 0x2dee0002, - 0xf9047399, 0xc43d96ef, 0x10d7e574, 0xd48a9703, 0x0060e498, - 0x3d5901ee, 0xe9b37275, 0x472bcb03, 0x93c1b898, 0xaef85dee, - 0x7a122e75, 0xf2c92e03, 0x26235d98, 0x1b1ab8ee, 0xcff0cb75, - 0x61687203, 0xb5820198, 0x88bbe4ee, 0x5c519775, 0x3019ca05, - 0xe4f3b99e, 0xd9ca5ce8, 0x0d202f73, 0xa3b89605, 0x7752e59e, - 0x4a6b00e8, 0x9e817373, 0x165a7305, 0xc2b0009e, 0xff89e5e8, - 0x2b639673, 0x85fb2f05, 0x51115c9e, 0x6c28b9e8, 0xb8c2ca73, - 0x7c9fb804, 0xa875cb9f, 0x954c2ee9, 0x41a65d72, 0xef3ee404, - 0x3bd4979f, 0x06ed72e9, 0xd2070172, 0x5adc0104, 0x8e36729f, - 0xb30f97e9, 0x67e5e472, 0xc97d5d04, 0x1d972e9f, 0x20aecbe9, - 0xf444b872, 0xa8152f07, 0x7cff5c9c, 0x41c6b9ea, 0x952cca71, - 0x3bb47307, 0xef5e009c, 0xd267e5ea, 0x068d9671, 0x8e569607, - 0x5abce59c, 0x678500ea, 0xb36f7371, 0x1df7ca07, 0xc91db99c, - 0xf4245cea, 0x20ce2f71, 0xe4935d06, 0x30792e9d, 0x0d40cbeb, - 0xd9aab870, 0x77320106, 0xa3d8729d, 0x9ee197eb, 0x4a0be470, - 0xc2d0e406, 0x163a979d, 0x2b0372eb, 0xffe90170, 0x5171b806, - 0x859bcb9d, 0xb8a22eeb, 0x6c485d70, 0x6032940b, 0xb4d8e790, - 0x89e102e6, 0x5d0b717d, 0xf393c80b, 0x2779bb90, 0x1a405ee6, - 0xceaa2d7d, 0x46712d0b, 0x929b5e90, 0xafa2bbe6, 0x7b48c87d, - 0xd5d0710b, 0x013a0290, 0x3c03e7e6, 0xe8e9947d, 0x2cb4e60a, - 0xf85e9591, 0xc56770e7, 0x118d037c, 0xbf15ba0a, 0x6bffc991, - 0x56c62ce7, 0x822c5f7c, 0x0af75f0a, 0xde1d2c91, 0xe324c9e7, - 0x37ceba7c, 0x9956030a, 0x4dbc7091, 0x708595e7, 0xa46fe67c, - 0xf83e7109, 0x2cd40292, 0x11ede7e4, 0xc507947f, 0x6b9f2d09, - 0xbf755e92, 0x824cbbe4, 0x56a6c87f, 0xde7dc809, 0x0a97bb92, - 0x37ae5ee4, 0xe3442d7f, 0x4ddc9409, 0x9936e792, 0xa40f02e4, - 0x70e5717f, 0xb4b80308, 0x60527093, 0x5d6b95e5, 0x8981e67e, - 0x27195f08, 0xf3f32c93, 0xcecac9e5, 0x1a20ba7e, 0x92fbba08, - 0x4611c993, 0x7b282ce5, 0xafc25f7e, 0x015ae608, 0xd5b09593, - 0xe88970e5, 0x3c63037e, 0x502b5e0e, 0x84c12d95, 0xb9f8c8e3, - 0x6d12bb78, 0xc38a020e, 0x17607195, 0x2a5994e3, 0xfeb3e778, - 0x7668e70e, 0xa2829495, 0x9fbb71e3, 0x4b510278, 0xe5c9bb0e, - 0x3123c895, 0x0c1a2de3, 0xd8f05e78, 0x1cad2c0f, 0xc8475f94, - 0xf57ebae2, 0x2194c979, 0x8f0c700f, 0x5be60394, 0x66dfe6e2, - 0xb2359579, 0x3aee950f, 0xee04e694, 0xd33d03e2, 0x07d77079, - 0xa94fc90f, 0x7da5ba94, 0x409c5fe2, 0x94762c79, 0xc827bb0c, - 0x1ccdc897, 0x21f42de1, 0xf51e5e7a, 0x5b86e70c, 0x8f6c9497, - 0xb25571e1, 0x66bf027a, 0xee64020c, 0x3a8e7197, 0x07b794e1, - 0xd35de77a, 0x7dc55e0c, 0xa92f2d97, 0x9416c8e1, 0x40fcbb7a, - 0x84a1c90d, 0x504bba96, 0x6d725fe0, 0xb9982c7b, 0x1700950d, - 0xc3eae696, 0xfed303e0, 0x2a39707b, 0xa2e2700d, 0x76080396, - 0x4b31e6e0, 0x9fdb957b, 0x31432c0d, 0xe5a95f96, 0xd890bae0, - 0x0c7ac97b}, - {0x00000000, 0x27652581, 0x0fcc3bd9, 0x28a91e58, 0x5f9e0669, - 0x78fb23e8, 0x50523db0, 0x77371831, 0xbe3c0dd2, 0x99592853, - 0xb1f0360b, 0x9695138a, 0xe1a20bbb, 0xc6c72e3a, 0xee6e3062, - 0xc90b15e3, 0x3d7f6b7f, 0x1a1a4efe, 0x32b350a6, 0x15d67527, - 0x62e16d16, 0x45844897, 0x6d2d56cf, 0x4a48734e, 0x834366ad, - 0xa426432c, 0x8c8f5d74, 0xabea78f5, 0xdcdd60c4, 0xfbb84545, - 0xd3115b1d, 0xf4747e9c, 0x7afed6fe, 0x5d9bf37f, 0x7532ed27, - 0x5257c8a6, 0x2560d097, 0x0205f516, 0x2aaceb4e, 0x0dc9cecf, - 0xc4c2db2c, 0xe3a7fead, 0xcb0ee0f5, 0xec6bc574, 0x9b5cdd45, - 0xbc39f8c4, 0x9490e69c, 0xb3f5c31d, 0x4781bd81, 0x60e49800, - 0x484d8658, 0x6f28a3d9, 0x181fbbe8, 0x3f7a9e69, 0x17d38031, - 0x30b6a5b0, 0xf9bdb053, 0xded895d2, 0xf6718b8a, 0xd114ae0b, - 0xa623b63a, 0x814693bb, 0xa9ef8de3, 0x8e8aa862, 0xb5fadc26, - 0x929ff9a7, 0xba36e7ff, 0x9d53c27e, 0xea64da4f, 0xcd01ffce, - 0xe5a8e196, 0xc2cdc417, 0x0bc6d1f4, 0x2ca3f475, 0x040aea2d, - 0x236fcfac, 0x5458d79d, 0x733df21c, 0x5b94ec44, 0x7cf1c9c5, - 0x8885b759, 0xafe092d8, 0x87498c80, 0xa02ca901, 0xd71bb130, - 0xf07e94b1, 0xd8d78ae9, 0xffb2af68, 0x36b9ba8b, 0x11dc9f0a, - 0x39758152, 0x1e10a4d3, 0x6927bce2, 0x4e429963, 0x66eb873b, - 0x418ea2ba, 0xcf040ad8, 0xe8612f59, 0xc0c83101, 0xe7ad1480, - 0x909a0cb1, 0xb7ff2930, 0x9f563768, 0xb83312e9, 0x7138070a, - 0x565d228b, 0x7ef43cd3, 0x59911952, 0x2ea60163, 0x09c324e2, - 0x216a3aba, 0x060f1f3b, 0xf27b61a7, 0xd51e4426, 0xfdb75a7e, - 0xdad27fff, 0xade567ce, 0x8a80424f, 0xa2295c17, 0x854c7996, - 0x4c476c75, 0x6b2249f4, 0x438b57ac, 0x64ee722d, 0x13d96a1c, - 0x34bc4f9d, 0x1c1551c5, 0x3b707444, 0x6af5b94d, 0x4d909ccc, - 0x65398294, 0x425ca715, 0x356bbf24, 0x120e9aa5, 0x3aa784fd, - 0x1dc2a17c, 0xd4c9b49f, 0xf3ac911e, 0xdb058f46, 0xfc60aac7, - 0x8b57b2f6, 0xac329777, 0x849b892f, 0xa3feacae, 0x578ad232, - 0x70eff7b3, 0x5846e9eb, 0x7f23cc6a, 0x0814d45b, 0x2f71f1da, - 0x07d8ef82, 0x20bdca03, 0xe9b6dfe0, 0xced3fa61, 0xe67ae439, - 0xc11fc1b8, 0xb628d989, 0x914dfc08, 0xb9e4e250, 0x9e81c7d1, - 0x100b6fb3, 0x376e4a32, 0x1fc7546a, 0x38a271eb, 0x4f9569da, - 0x68f04c5b, 0x40595203, 0x673c7782, 0xae376261, 0x895247e0, - 0xa1fb59b8, 0x869e7c39, 0xf1a96408, 0xd6cc4189, 0xfe655fd1, - 0xd9007a50, 0x2d7404cc, 0x0a11214d, 0x22b83f15, 0x05dd1a94, - 0x72ea02a5, 0x558f2724, 0x7d26397c, 0x5a431cfd, 0x9348091e, - 0xb42d2c9f, 0x9c8432c7, 0xbbe11746, 0xccd60f77, 0xebb32af6, - 0xc31a34ae, 0xe47f112f, 0xdf0f656b, 0xf86a40ea, 0xd0c35eb2, - 0xf7a67b33, 0x80916302, 0xa7f44683, 0x8f5d58db, 0xa8387d5a, - 0x613368b9, 0x46564d38, 0x6eff5360, 0x499a76e1, 0x3ead6ed0, - 0x19c84b51, 0x31615509, 0x16047088, 0xe2700e14, 0xc5152b95, - 0xedbc35cd, 0xcad9104c, 0xbdee087d, 0x9a8b2dfc, 0xb22233a4, - 0x95471625, 0x5c4c03c6, 0x7b292647, 0x5380381f, 0x74e51d9e, - 0x03d205af, 0x24b7202e, 0x0c1e3e76, 0x2b7b1bf7, 0xa5f1b395, - 0x82949614, 0xaa3d884c, 0x8d58adcd, 0xfa6fb5fc, 0xdd0a907d, - 0xf5a38e25, 0xd2c6aba4, 0x1bcdbe47, 0x3ca89bc6, 0x1401859e, - 0x3364a01f, 0x4453b82e, 0x63369daf, 0x4b9f83f7, 0x6cfaa676, - 0x988ed8ea, 0xbfebfd6b, 0x9742e333, 0xb027c6b2, 0xc710de83, - 0xe075fb02, 0xc8dce55a, 0xefb9c0db, 0x26b2d538, 0x01d7f0b9, - 0x297eeee1, 0x0e1bcb60, 0x792cd351, 0x5e49f6d0, 0x76e0e888, - 0x5185cd09}}; - -#endif - -#endif - -#endif - -local const z_crc_t FAR x2n_table[] = { - 0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000, - 0xedb88320, 0xb1e6b092, 0xa06a2517, 0xed627dae, 0x88d14467, - 0xd7bbfe6a, 0xec447f11, 0x8e7ea170, 0x6427800e, 0x4d47bae0, - 0x09fe548f, 0x83852d0f, 0x30362f1a, 0x7b5a9cc3, 0x31fec169, - 0x9fec022a, 0x6c8dedc4, 0x15d6874d, 0x5fde7a4e, 0xbad90e37, - 0x2e4e5eef, 0x4eaba214, 0xa8a472c0, 0x429a969e, 0x148d302a, - 0xc40ba6d0, 0xc4e22c3c}; diff --git a/ext/zlib/deflate.c b/ext/zlib/deflate.c deleted file mode 100644 index 012ea8148e..0000000000 --- a/ext/zlib/deflate.c +++ /dev/null @@ -1,2139 +0,0 @@ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://tools.ietf.org/html/rfc1951 - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* @(#) $Id$ */ - -#include "deflate.h" - -const char deflate_copyright[] = - " deflate 1.3.1 Copyright 1995-2024 Jean-loup Gailly and Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func)(deflate_state *s, int flush); -/* Compression function. Returns the block state after the call. */ - -local block_state deflate_stored(deflate_state *s, int flush); -local block_state deflate_fast(deflate_state *s, int flush); -#ifndef FASTEST -local block_state deflate_slow(deflate_state *s, int flush); -#endif -local block_state deflate_rle(deflate_state *s, int flush); -local block_state deflate_huff(deflate_state *s, int flush); - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -#ifdef FASTEST -local const config configuration_table[2] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ -#else -local const config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ -#endif - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ -#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to UPDATE_HASH are made with consecutive input - * characters, so that a running hash key can be computed from the previous - * key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h) << s->hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * If this file is compiled with -DFASTEST, the compression level is forced - * to 1, and no hash chains are maintained. - * IN assertion: all calls to INSERT_STRING are made with consecutive input - * characters and the first MIN_MATCH bytes of str are valid (except for - * the last MIN_MATCH-1 bytes of the input file). - */ -#ifdef FASTEST -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#else -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#endif - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - do { \ - s->head[s->hash_size - 1] = NIL; \ - zmemzero((Bytef *)s->head, \ - (unsigned)(s->hash_size - 1)*sizeof(*s->head)); \ - } while (0) - -/* =========================================================================== - * Slide the hash table when sliding the window down (could be avoided with 32 - * bit values at the expense of memory usage). We slide even when level == 0 to - * keep the hash table consistent if we switch back to level > 0 later. - */ -#if defined(__has_feature) -# if __has_feature(memory_sanitizer) - __attribute__((no_sanitize("memory"))) -# endif -#endif -local void slide_hash(deflate_state *s) { - unsigned n, m; - Posf *p; - uInt wsize = s->w_size; - - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m - wsize : NIL); - } while (--n); - n = wsize; -#ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m - wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local unsigned read_buf(z_streamp strm, Bytef *buf, unsigned size) { - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - zmemcpy(buf, strm->next_in, len); - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, buf, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, buf, len); - } -#endif - strm->next_in += len; - strm->total_in += len; - - return len; -} - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(deflate_state *s) { - unsigned n; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize + MAX_DIST(s)) { - - zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - if (s->insert > s->strstart) - s->insert = s->strstart; - slide_hash(s); - more += wsize; - } - if (s->strm->avail_in == 0) break; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead + s->insert >= MIN_MATCH) { - uInt str = s->strstart - s->insert; - s->ins_h = s->window[str]; - UPDATE_HASH(s, s->ins_h, s->window[str + 1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - while (s->insert) { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - s->insert--; - if (s->lookahead + s->insert < MIN_MATCH) - break; - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - if (s->high_water < s->window_size) { - ulg curr = s->strstart + (ulg)(s->lookahead); - ulg init; - - if (s->high_water < curr) { - /* Previous high water mark below current data -- zero WIN_INIT - * bytes or up to end of window, whichever is less. - */ - init = s->window_size - curr; - if (init > WIN_INIT) - init = WIN_INIT; - zmemzero(s->window + curr, (unsigned)init); - s->high_water = curr + init; - } - else if (s->high_water < (ulg)curr + WIN_INIT) { - /* High water mark at or above current data, but below current data - * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - * to end of window, whichever is less. - */ - init = (ulg)curr + WIN_INIT - s->high_water; - if (init > s->window_size - s->high_water) - init = s->window_size - s->high_water; - zmemzero(s->window + s->high_water, (unsigned)init); - s->high_water += init; - } - } - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "not enough room for search"); -} - -/* ========================================================================= */ -int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version, - int stream_size) { - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, - int windowBits, int memLevel, int strategy, - const char *version, int stream_size) { - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - if (windowBits < -15) - return Z_STREAM_ERROR; - windowBits = -windowBits; - } -#ifdef GZIP - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } -#endif - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - s->status = INIT_STATE; /* to pass state test in deflateReset() */ - - s->wrap = wrap; - s->gzhead = Z_NULL; - s->w_bits = (uInt)windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = (uInt)memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits + MIN_MATCH-1) / MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->high_water = 0; /* nothing written to s->window yet */ - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - /* We overlay pending_buf and sym_buf. This works since the average size - * for length/distance pairs over any compressed block is assured to be 31 - * bits or less. - * - * Analysis: The longest fixed codes are a length code of 8 bits plus 5 - * extra bits, for lengths 131 to 257. The longest fixed distance codes are - * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest - * possible fixed-codes length/distance pair is then 31 bits total. - * - * sym_buf starts one-fourth of the way into pending_buf. So there are - * three bytes in sym_buf for every four bytes in pending_buf. Each symbol - * in sym_buf is three bytes -- two for the distance and one for the - * literal/length. As each symbol is consumed, the pointer to the next - * sym_buf value to read moves forward three bytes. From that symbol, up to - * 31 bits are written to pending_buf. The closest the written pending_buf - * bits gets to the next sym_buf symbol to read is just before the last - * code is written. At that time, 31*(n - 2) bits have been written, just - * after 24*(n - 2) bits have been consumed from sym_buf. sym_buf starts at - * 8*n bits into pending_buf. (Note that the symbol buffer fills when n - 1 - * symbols are written.) The closest the writing gets to what is unread is - * then n + 14 bits. Here n is lit_bufsize, which is 16384 by default, and - * can range from 128 to 32768. - * - * Therefore, at a minimum, there are 142 bits of space between what is - * written and what is read in the overlain buffers, so the symbols cannot - * be overwritten by the compressed data. That space is actually 139 bits, - * due to the three-bit fixed-code block header. - * - * That covers the case where either Z_FIXED is specified, forcing fixed - * codes, or when the use of fixed codes is chosen, because that choice - * results in a smaller compressed block than dynamic codes. That latter - * condition then assures that the above analysis also covers all dynamic - * blocks. A dynamic-code block will only be chosen to be emitted if it has - * fewer bits than a fixed-code block would for the same set of symbols. - * Therefore its average symbol length is assured to be less than 31. So - * the compressed data for a dynamic block also cannot overwrite the - * symbols from which it is being constructed. - */ - - s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, LIT_BUFS); - s->pending_buf_size = (ulg)s->lit_bufsize * 4; - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } -#ifdef LIT_MEM - s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1)); - s->l_buf = s->pending_buf + (s->lit_bufsize << 2); - s->sym_end = s->lit_bufsize - 1; -#else - s->sym_buf = s->pending_buf + s->lit_bufsize; - s->sym_end = (s->lit_bufsize - 1) * 3; -#endif - /* We avoid equality with lit_bufsize*3 because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= - * Check for a valid deflate stream state. Return 0 if ok, 1 if not. - */ -local int deflateStateCheck(z_streamp strm) { - deflate_state *s; - if (strm == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) - return 1; - s = strm->state; - if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE && -#ifdef GZIP - s->status != GZIP_STATE && -#endif - s->status != EXTRA_STATE && - s->status != NAME_STATE && - s->status != COMMENT_STATE && - s->status != HCRC_STATE && - s->status != BUSY_STATE && - s->status != FINISH_STATE)) - return 1; - return 0; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetDictionary(z_streamp strm, const Bytef *dictionary, - uInt dictLength) { - deflate_state *s; - uInt str, n; - int wrap; - unsigned avail; - z_const unsigned char *next; - - if (deflateStateCheck(strm) || dictionary == Z_NULL) - return Z_STREAM_ERROR; - s = strm->state; - wrap = s->wrap; - if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) - return Z_STREAM_ERROR; - - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap == 1) - strm->adler = adler32(strm->adler, dictionary, dictLength); - s->wrap = 0; /* avoid computing Adler-32 in read_buf */ - - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s->w_size) { - if (wrap == 0) { /* already empty otherwise */ - CLEAR_HASH(s); - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - dictionary += dictLength - s->w_size; /* use the tail */ - dictLength = s->w_size; - } - - /* insert dictionary into window and hash */ - avail = strm->avail_in; - next = strm->next_in; - strm->avail_in = dictLength; - strm->next_in = (z_const Bytef *)dictionary; - fill_window(s); - while (s->lookahead >= MIN_MATCH) { - str = s->strstart; - n = s->lookahead - (MIN_MATCH-1); - do { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - } while (--n); - s->strstart = str; - s->lookahead = MIN_MATCH-1; - fill_window(s); - } - s->strstart += s->lookahead; - s->block_start = (long)s->strstart; - s->insert = s->lookahead; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - strm->next_in = next; - strm->avail_in = avail; - s->wrap = wrap; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateGetDictionary(z_streamp strm, Bytef *dictionary, - uInt *dictLength) { - deflate_state *s; - uInt len; - - if (deflateStateCheck(strm)) - return Z_STREAM_ERROR; - s = strm->state; - len = s->strstart + s->lookahead; - if (len > s->w_size) - len = s->w_size; - if (dictionary != Z_NULL && len) - zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len); - if (dictLength != Z_NULL) - *dictLength = len; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateResetKeep(z_streamp strm) { - deflate_state *s; - - if (deflateStateCheck(strm)) { - return Z_STREAM_ERROR; - } - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = -#ifdef GZIP - s->wrap == 2 ? GZIP_STATE : -#endif - INIT_STATE; - strm->adler = -#ifdef GZIP - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : -#endif - adler32(0L, Z_NULL, 0); - s->last_flush = -2; - - _tr_init(s); - - return Z_OK; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init(deflate_state *s) { - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->insert = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -} - -/* ========================================================================= */ -int ZEXPORT deflateReset(z_streamp strm) { - int ret; - - ret = deflateResetKeep(strm); - if (ret == Z_OK) - lm_init(strm->state); - return ret; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetHeader(z_streamp strm, gz_headerp head) { - if (deflateStateCheck(strm) || strm->state->wrap != 2) - return Z_STREAM_ERROR; - strm->state->gzhead = head; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) { - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - if (pending != Z_NULL) - *pending = strm->state->pending; - if (bits != Z_NULL) - *bits = strm->state->bi_valid; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { - deflate_state *s; - int put; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; -#ifdef LIT_MEM - if (bits < 0 || bits > 16 || - (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3)) - return Z_BUF_ERROR; -#else - if (bits < 0 || bits > 16 || - s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) - return Z_BUF_ERROR; -#endif - do { - put = Buf_size - s->bi_valid; - if (put > bits) - put = bits; - s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); - s->bi_valid += put; - _tr_flush_bits(s); - value >>= put; - bits -= put; - } while (bits); - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateParams(z_streamp strm, int level, int strategy) { - deflate_state *s; - compress_func func; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if ((strategy != s->strategy || func != configuration_table[level].func) && - s->last_flush != -2) { - /* Flush the last buffer: */ - int err = deflate(strm, Z_BLOCK); - if (err == Z_STREAM_ERROR) - return err; - if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead) - return Z_BUF_ERROR; - } - if (s->level != level) { - if (s->level == 0 && s->matches != 0) { - if (s->matches == 1) - slide_hash(s); - else - CLEAR_HASH(s); - s->matches = 0; - } - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy, - int nice_length, int max_chain) { - deflate_state *s; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - s->good_match = (uInt)good_length; - s->max_lazy_match = (uInt)max_lazy; - s->nice_match = nice_length; - s->max_chain_length = (uInt)max_chain; - return Z_OK; -} - -/* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns a - * close to exact, as well as small, upper bound on the compressed size. This - * is an expansion of ~0.03%, plus a small constant. - * - * For any setting other than those defaults for windowBits and memLevel, one - * of two worst case bounds is returned. This is at most an expansion of ~4% or - * ~13%, plus a small constant. - * - * Both the 0.03% and 4% derive from the overhead of stored blocks. The first - * one is for stored blocks of 16383 bytes (memLevel == 8), whereas the second - * is for stored blocks of 127 bytes (the worst case memLevel == 1). The - * expansion results from five bytes of header for each stored block. - * - * The larger expansion of 13% results from a window size less than or equal to - * the symbols buffer size (windowBits <= memLevel + 7). In that case some of - * the data being compressed may have slid out of the sliding window, impeding - * a stored block from being emitted. Then the only choice is a fixed or - * dynamic block, where a fixed block limits the maximum expansion to 9 bits - * per 8-bit byte, plus 10 bits for every block. The smallest block size for - * which this can occur is 255 (memLevel == 2). - * - * Shifts are used to approximate divisions, for speed. - */ -uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { - deflate_state *s; - uLong fixedlen, storelen, wraplen; - - /* upper bound for fixed blocks with 9-bit literals and length 255 - (memLevel == 2, which is the lowest that may not use stored blocks) -- - ~13% overhead plus a small constant */ - fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) + - (sourceLen >> 9) + 4; - - /* upper bound for stored blocks with length 127 (memLevel == 1) -- - ~4% overhead plus a small constant */ - storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + - (sourceLen >> 11) + 7; - - /* if can't get parameters, return larger bound plus a zlib wrapper */ - if (deflateStateCheck(strm)) - return (fixedlen > storelen ? fixedlen : storelen) + 6; - - /* compute wrapper length */ - s = strm->state; - switch (s->wrap) { - case 0: /* raw deflate */ - wraplen = 0; - break; - case 1: /* zlib wrapper */ - wraplen = 6 + (s->strstart ? 4 : 0); - break; -#ifdef GZIP - case 2: /* gzip wrapper */ - wraplen = 18; - if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ - Bytef *str; - if (s->gzhead->extra != Z_NULL) - wraplen += 2 + s->gzhead->extra_len; - str = s->gzhead->name; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - str = s->gzhead->comment; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - if (s->gzhead->hcrc) - wraplen += 2; - } - break; -#endif - default: /* for compiler happiness */ - wraplen = 6; - } - - /* if not default parameters, return one of the conservative bounds */ - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) + - wraplen; - - /* default settings: return tight bound for that case -- ~0.03% overhead - plus a small constant */ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13 - 6 + wraplen; -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB(deflate_state *s, uInt b) { - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output, except for - * some deflate_stored() output, goes through this function so some - * applications may wish to modify it to avoid allocating a large - * strm->next_out buffer and copying into it. (See also read_buf()). - */ -local void flush_pending(z_streamp strm) { - unsigned len; - deflate_state *s = strm->state; - - _tr_flush_bits(s); - len = s->pending; - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - zmemcpy(strm->next_out, s->pending_out, len); - strm->next_out += len; - s->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - s->pending -= len; - if (s->pending == 0) { - s->pending_out = s->pending_buf; - } -} - -/* =========================================================================== - * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. - */ -#define HCRC_UPDATE(beg) \ - do { \ - if (s->gzhead->hcrc && s->pending > (beg)) \ - strm->adler = crc32(strm->adler, s->pending_buf + (beg), \ - s->pending - (beg)); \ - } while (0) - -/* ========================================================================= */ -int ZEXPORT deflate(z_streamp strm, int flush) { - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; - - if (strm->next_out == Z_NULL || - (strm->avail_in != 0 && strm->next_in == Z_NULL) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - old_flush = s->last_flush; - s->last_flush = flush; - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Write the header */ - if (s->status == INIT_STATE && s->wrap == 0) - s->status = BUSY_STATE; - if (s->status == INIT_STATE) { - /* zlib header */ - uInt header = (Z_DEFLATED + ((s->w_bits - 8) << 4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } -#ifdef GZIP - if (s->status == GZIP_STATE) { - /* gzip header */ - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == Z_NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } - else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != Z_NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex; - while (s->pending + left > s->pending_buf_size) { - uInt copy = s->pending_buf_size - s->pending; - zmemcpy(s->pending_buf + s->pending, - s->gzhead->extra + s->gzindex, copy); - s->pending = s->pending_buf_size; - HCRC_UPDATE(beg); - s->gzindex += copy; - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - left -= copy; - } - zmemcpy(s->pending_buf + s->pending, - s->gzhead->extra + s->gzindex, left); - s->pending += left; - HCRC_UPDATE(beg); - s->gzindex = 0; - } - s->status = NAME_STATE; - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - int val; - do { - if (s->pending == s->pending_buf_size) { - HCRC_UPDATE(beg); - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - HCRC_UPDATE(beg); - s->gzindex = 0; - } - s->status = COMMENT_STATE; - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - int val; - do { - if (s->pending == s->pending_buf_size) { - HCRC_UPDATE(beg); - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - HCRC_UPDATE(beg); - } - s->status = HCRC_STATE; - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) { - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - } - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } -#endif - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = s->level == 0 ? deflate_stored(s, flush) : - s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - s->strategy == Z_RLE ? deflate_rle(s, flush) : - (*(configuration_table[s->level].func))(s, flush); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - if (s->lookahead == 0) { - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - - if (flush != Z_FINISH) return Z_OK; - if (s->wrap <= 0) return Z_STREAM_END; - - /* Write the trailer */ -#ifdef GZIP - if (s->wrap == 2) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); - put_byte(s, (Byte)(strm->total_in & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); - } - else -#endif - { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int ZEXPORT deflateEnd(z_streamp strm) { - int status; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - - status = strm->state->status; - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); - - ZFREE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - * To simplify the source, this is not supported for 16-bit MSDOS (which - * doesn't have enough memory anyway to duplicate compression states). - */ -int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { -#ifdef MAXSEG_64K - (void)dest; - (void)source; - return Z_STREAM_ERROR; -#else - deflate_state *ds; - deflate_state *ss; - - - if (deflateStateCheck(source) || dest == Z_NULL) { - return Z_STREAM_ERROR; - } - - ss = source->state; - - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS); - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* following zmemcpy do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, ds->lit_bufsize * LIT_BUFS); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); -#ifdef LIT_MEM - ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1)); - ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2); -#else - ds->sym_buf = ds->pending_buf + ds->lit_bufsize; -#endif - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -#endif /* MAXSEG_64K */ -} - -#ifndef FASTEST -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -local uInt longest_match(deflate_state *s, IPos cur_match) { - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = (int)s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan + best_len - 1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len - 1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead; - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match + best_len - 1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart + 3, + 5, up to strstart + 257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart + 257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan += 2) == *(ushf*)(match += 2) && - *(ushf*)(scan += 2) == *(ushf*)(match += 2) && - *(ushf*)(scan += 2) == *(ushf*)(match += 2) && - *(ushf*)(scan += 2) == *(ushf*)(match += 2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window + strstart + 257 */ - Assert(scan <= s->window + (unsigned)(s->window_size - 1), - "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend - scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len - 1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len - 1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart + 258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window + (unsigned)(s->window_size - 1), - "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan + best_len - 1); -#else - scan_end1 = scan[best_len - 1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return (uInt)best_len; - return s->lookahead; -} - -#else /* FASTEST */ - -/* --------------------------------------------------------------------------- - * Optimized version for FASTEST only - */ -local uInt longest_match(deflate_state *s, IPos cur_match) { - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "need lookahead"); - - Assert(cur_match < s->strstart, "no future"); - - match = s->window + cur_match; - - /* Return failure if the match length is less than 2: - */ - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; - - /* The check at best_len - 1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match += 2; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart + 258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - - if (len < MIN_MATCH) return MIN_MATCH - 1; - - s->match_start = cur_match; - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; -} - -#endif /* FASTEST */ - -#ifdef ZLIB_DEBUG - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(deflate_state *s, IPos start, IPos match, int length) { - /* check that the match is indeed a match */ - Bytef *back = s->window + (int)match, *here = s->window + start; - IPos len = length; - if (match == (IPos)-1) { - /* match starts one byte before the current window -- just compare the - subsequent length-1 bytes */ - back++; - here++; - len--; - } - if (zmemcmp(back, here, len) != EQUAL) { - fprintf(stderr, " start %u, match %d, length %d\n", - start, (int)match, length); - do { - fprintf(stderr, "(%02x %02x)", *back++, *here++); - } while (--len != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start - match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif /* ZLIB_DEBUG */ - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, last) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (last)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, last) { \ - FLUSH_BLOCK_ONLY(s, last); \ - if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ -} - -/* Maximum stored block length in deflate format (not including header). */ -#define MAX_STORED 65535 - -/* Minimum of a and b. */ -#define MIN(a, b) ((a) > (b) ? (b) : (a)) - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * - * In case deflateParams() is used to later switch to a non-zero compression - * level, s->matches (otherwise unused when storing) keeps track of the number - * of hash table slides to perform. If s->matches is 1, then one hash table - * slide will be done when switching. If s->matches is 2, the maximum value - * allowed here, then the hash table will be cleared, since two or more slides - * is the same as a clear. - * - * deflate_stored() is written to minimize the number of times an input byte is - * copied. It is most efficient with large input and output buffers, which - * maximizes the opportunities to have a single copy from next_in to next_out. - */ -local block_state deflate_stored(deflate_state *s, int flush) { - /* Smallest worthy block size when not flushing or finishing. By default - * this is 32K. This can be as small as 507 bytes for memLevel == 1. For - * large input and output buffers, the stored block size will be larger. - */ - unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); - - /* Copy as many min_block or larger stored blocks directly to next_out as - * possible. If flushing, copy the remaining available input to next_out as - * stored blocks, if there is enough space. - */ - unsigned len, left, have, last = 0; - unsigned used = s->strm->avail_in; - do { - /* Set len to the maximum size block that we can copy directly with the - * available input data and output space. Set left to how much of that - * would be copied from what's left in the window. - */ - len = MAX_STORED; /* maximum deflate stored block length */ - have = (s->bi_valid + 42) >> 3; /* number of header bytes */ - if (s->strm->avail_out < have) /* need room for header */ - break; - /* maximum stored block length that will fit in avail_out: */ - have = s->strm->avail_out - have; - left = s->strstart - s->block_start; /* bytes left in window */ - if (len > (ulg)left + s->strm->avail_in) - len = left + s->strm->avail_in; /* limit len to the input */ - if (len > have) - len = have; /* limit len to the output */ - - /* If the stored block would be less than min_block in length, or if - * unable to copy all of the available input when flushing, then try - * copying to the window and the pending buffer instead. Also don't - * write an empty block when flushing -- deflate() does that. - */ - if (len < min_block && ((len == 0 && flush != Z_FINISH) || - flush == Z_NO_FLUSH || - len != left + s->strm->avail_in)) - break; - - /* Make a dummy stored block in pending to get the header bytes, - * including any pending bits. This also updates the debugging counts. - */ - last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; - _tr_stored_block(s, (char *)0, 0L, last); - - /* Replace the lengths in the dummy stored block with len. */ - s->pending_buf[s->pending - 4] = len; - s->pending_buf[s->pending - 3] = len >> 8; - s->pending_buf[s->pending - 2] = ~len; - s->pending_buf[s->pending - 1] = ~len >> 8; - - /* Write the stored block header bytes. */ - flush_pending(s->strm); - -#ifdef ZLIB_DEBUG - /* Update debugging counts for the data about to be copied. */ - s->compressed_len += len << 3; - s->bits_sent += len << 3; -#endif - - /* Copy uncompressed bytes from the window to next_out. */ - if (left) { - if (left > len) - left = len; - zmemcpy(s->strm->next_out, s->window + s->block_start, left); - s->strm->next_out += left; - s->strm->avail_out -= left; - s->strm->total_out += left; - s->block_start += left; - len -= left; - } - - /* Copy uncompressed bytes directly from next_in to next_out, updating - * the check value. - */ - if (len) { - read_buf(s->strm, s->strm->next_out, len); - s->strm->next_out += len; - s->strm->avail_out -= len; - s->strm->total_out += len; - } - } while (last == 0); - - /* Update the sliding window with the last s->w_size bytes of the copied - * data, or append all of the copied data to the existing window if less - * than s->w_size bytes were copied. Also update the number of bytes to - * insert in the hash tables, in the event that deflateParams() switches to - * a non-zero compression level. - */ - used -= s->strm->avail_in; /* number of input bytes directly copied */ - if (used) { - /* If any input was used, then no unused input remains in the window, - * therefore s->block_start == s->strstart. - */ - if (used >= s->w_size) { /* supplant the previous history */ - s->matches = 2; /* clear hash */ - zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); - s->strstart = s->w_size; - s->insert = s->strstart; - } - else { - if (s->window_size - s->strstart <= used) { - /* Slide the window down. */ - s->strstart -= s->w_size; - zmemcpy(s->window, s->window + s->w_size, s->strstart); - if (s->matches < 2) - s->matches++; /* add a pending slide_hash() */ - if (s->insert > s->strstart) - s->insert = s->strstart; - } - zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); - s->strstart += used; - s->insert += MIN(used, s->w_size - s->insert); - } - s->block_start = s->strstart; - } - if (s->high_water < s->strstart) - s->high_water = s->strstart; - - /* If the last block was written to next_out, then done. */ - if (last) - return finish_done; - - /* If flushing and all input has been consumed, then done. */ - if (flush != Z_NO_FLUSH && flush != Z_FINISH && - s->strm->avail_in == 0 && (long)s->strstart == s->block_start) - return block_done; - - /* Fill the window with any remaining input. */ - have = s->window_size - s->strstart; - if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { - /* Slide the window down. */ - s->block_start -= s->w_size; - s->strstart -= s->w_size; - zmemcpy(s->window, s->window + s->w_size, s->strstart); - if (s->matches < 2) - s->matches++; /* add a pending slide_hash() */ - have += s->w_size; /* more space now */ - if (s->insert > s->strstart) - s->insert = s->strstart; - } - if (have > s->strm->avail_in) - have = s->strm->avail_in; - if (have) { - read_buf(s->strm, s->window + s->strstart, have); - s->strstart += have; - s->insert += MIN(have, s->w_size - s->insert); - } - if (s->high_water < s->strstart) - s->high_water = s->strstart; - - /* There was not enough avail_out to write a complete worthy or flushed - * stored block to next_out. Write a stored block to pending instead, if we - * have enough input for a worthy block, or if flushing and there is enough - * room for the remaining input as a stored block in the pending buffer. - */ - have = (s->bi_valid + 42) >> 3; /* number of header bytes */ - /* maximum stored block length that will fit in pending: */ - have = MIN(s->pending_buf_size - have, MAX_STORED); - min_block = MIN(have, s->w_size); - left = s->strstart - s->block_start; - if (left >= min_block || - ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && - s->strm->avail_in == 0 && left <= have)) { - len = MIN(left, have); - last = flush == Z_FINISH && s->strm->avail_in == 0 && - len == left ? 1 : 0; - _tr_stored_block(s, (charf *)s->window + s->block_start, len, last); - s->block_start += len; - flush_pending(s->strm); - } - - /* We've done all we can with the available input and output. */ - return last ? finish_started : need_more; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(deflate_state *s, int flush) { - IPos hash_head; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart + 2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - _tr_tally_dist(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ -#ifndef FASTEST - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else -#endif - { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart + 1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit(s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; -} - -#ifndef FASTEST -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(deflate_state *s, int flush) { - IPos hash_head; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart + 2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED -#if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR) -#endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart - 1, s->prev_match, s->prev_length); - - _tr_tally_dist(s, s->strstart - 1 - s->prev_match, - s->prev_length - MIN_MATCH, bflush); - - /* Insert in hash table all strings up to the end of the match. - * strstart - 1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length - 1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart - 1])); - _tr_tally_lit(s, s->window[s->strstart - 1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart - 1])); - _tr_tally_lit(s, s->window[s->strstart - 1], bflush); - s->match_available = 0; - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; -} -#endif /* FASTEST */ - -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -local block_state deflate_rle(deflate_state *s, int flush) { - int bflush; /* set if current block must be flushed */ - uInt prev; /* byte at distance one to match */ - Bytef *scan, *strend; /* scan goes up to strend for length of run */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest run, plus one for the unrolled loop. - */ - if (s->lookahead <= MAX_MATCH) { - fill_window(s); - if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s->match_length = 0; - if (s->lookahead >= MIN_MATCH && s->strstart > 0) { - scan = s->window + s->strstart - 1; - prev = *scan; - if (prev == *++scan && prev == *++scan && prev == *++scan) { - strend = s->window + s->strstart + MAX_MATCH; - do { - } while (prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - scan < strend); - s->match_length = MAX_MATCH - (uInt)(strend - scan); - if (s->match_length > s->lookahead) - s->match_length = s->lookahead; - } - Assert(scan <= s->window + (uInt)(s->window_size - 1), - "wild scan"); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, s->match_length); - - _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - s->strstart += s->match_length; - s->match_length = 0; - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit(s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; -} - -/* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ -local block_state deflate_huff(deflate_state *s, int flush) { - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s->lookahead == 0) { - fill_window(s); - if (s->lookahead == 0) { - if (flush == Z_NO_FLUSH) - return need_more; - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s->match_length = 0; - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit(s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; -} diff --git a/ext/zlib/deflate.h b/ext/zlib/deflate.h deleted file mode 100644 index 300c6ada62..0000000000 --- a/ext/zlib/deflate.h +++ /dev/null @@ -1,377 +0,0 @@ -/* deflate.h -- internal compression state - * Copyright (C) 1995-2024 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef DEFLATE_H -#define DEFLATE_H - -#include "zutil.h" - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer creation by deflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip encoding - should be left enabled. */ -#ifndef NO_GZIP -# define GZIP -#endif - -/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at - the cost of a larger memory footprint */ -/* #define LIT_MEM */ - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define Buf_size 16 -/* size of bit buffer in bi_buf */ - -#define INIT_STATE 42 /* zlib header -> BUSY_STATE */ -#ifdef GZIP -# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ -#endif -#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ -#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ -#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ -#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ -#define BUSY_STATE 113 /* deflate -> FINISH_STATE */ -#define FINISH_STATE 666 /* stream complete */ -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - const static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct internal_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - ulg pending; /* nb of bytes in the pending buffer */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - gz_headerp gzhead; /* gzip header information to write */ - ulg gzindex; /* where in extra, name, or comment */ - Byte method; /* can only be DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to suppress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - -#ifdef LIT_MEM -# define LIT_BUFS 5 - ushf *d_buf; /* buffer for distances */ - uchf *l_buf; /* buffer for literals/lengths */ -#else -# define LIT_BUFS 4 - uchf *sym_buf; /* buffer for distances and literals/lengths */ -#endif - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt sym_next; /* running index in symbol buffer */ - uInt sym_end; /* symbol table full when sym_next reaches this */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - uInt matches; /* number of string matches in current block */ - uInt insert; /* bytes at end of window left to insert */ - -#ifdef ZLIB_DEBUG - ulg compressed_len; /* total bit length of compressed file mod 2^32 */ - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - ulg high_water; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - -#define WIN_INIT MAX_MATCH -/* Number of bytes after end of data in window to initialize in order to avoid - memory checker errors from longest match routines */ - - /* in trees.c */ -void ZLIB_INTERNAL _tr_init(deflate_state *s); -int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc); -void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, - ulg stored_len, int last); -void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s); -void ZLIB_INTERNAL _tr_align(deflate_state *s); -void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, - ulg stored_len, int last); - -#define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. _dist_code[256] and _dist_code[257] are never - * used. - */ - -#ifndef ZLIB_DEBUG -/* Inline versions of _tr_tally for speed: */ - -#if defined(GEN_TREES_H) || !defined(STDC) - extern uch ZLIB_INTERNAL _length_code[]; - extern uch ZLIB_INTERNAL _dist_code[]; -#else - extern const uch ZLIB_INTERNAL _length_code[]; - extern const uch ZLIB_INTERNAL _dist_code[]; -#endif - -#ifdef LIT_MEM -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->d_buf[s->sym_next] = 0; \ - s->l_buf[s->sym_next++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->sym_next == s->sym_end); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (uch)(length); \ - ush dist = (ush)(distance); \ - s->d_buf[s->sym_next] = dist; \ - s->l_buf[s->sym_next++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->sym_next == s->sym_end); \ - } -#else -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->sym_buf[s->sym_next++] = 0; \ - s->sym_buf[s->sym_next++] = 0; \ - s->sym_buf[s->sym_next++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->sym_next == s->sym_end); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (uch)(length); \ - ush dist = (ush)(distance); \ - s->sym_buf[s->sym_next++] = (uch)dist; \ - s->sym_buf[s->sym_next++] = (uch)(dist >> 8); \ - s->sym_buf[s->sym_next++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->sym_next == s->sym_end); \ - } -#endif -#else -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -# define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) -#endif - -#endif /* DEFLATE_H */ diff --git a/ext/zlib/gzclose.c b/ext/zlib/gzclose.c deleted file mode 100644 index 48d6a86f04..0000000000 --- a/ext/zlib/gzclose.c +++ /dev/null @@ -1,23 +0,0 @@ -/* gzclose.c -- zlib gzclose() function - * Copyright (C) 2004, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* gzclose() is in a separate file so that it is linked in only if it is used. - That way the other gzclose functions can be used instead to avoid linking in - unneeded compression or decompression routines. */ -int ZEXPORT gzclose(gzFile file) { -#ifndef NO_GZCOMPRESS - gz_statep state; - - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); -#else - return gzclose_r(file); -#endif -} diff --git a/ext/zlib/gzguts.h b/ext/zlib/gzguts.h deleted file mode 100644 index 22bb1ce2ec..0000000000 --- a/ext/zlib/gzguts.h +++ /dev/null @@ -1,216 +0,0 @@ -/* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004-2024 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#ifdef _LARGEFILE64_SOURCE -# ifndef _LARGEFILE_SOURCE -# define _LARGEFILE_SOURCE 1 -# endif -# undef _FILE_OFFSET_BITS -# undef _TIME_BITS -#endif - -#ifdef HAVE_HIDDEN -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include -#include "zlib.h" -#ifdef STDC -# include -# include -# include -#endif - -#ifndef _POSIX_SOURCE -# define _POSIX_SOURCE -#endif -#include - -#ifdef _WIN32 -# include -#else -# include -#endif - -#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) -# include -#endif - -#if defined(_WIN32) -# define WIDECHAR -#endif - -#ifdef WINAPI_FAMILY -# define open _open -# define read _read -# define write _write -# define close _close -#endif - -#ifdef NO_DEFLATE /* for compatibility with old definition */ -# define NO_GZCOMPRESS -#endif - -#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#if defined(__CYGWIN__) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#ifndef HAVE_VSNPRINTF -# ifdef MSDOS -/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), - but for now we just assume it doesn't. */ -# define NO_vsnprintf -# endif -# ifdef __TURBOC__ -# define NO_vsnprintf -# endif -# ifdef WIN32 -/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ -# if !defined(vsnprintf) && !defined(NO_vsnprintf) -# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) -# define vsnprintf _vsnprintf -# endif -# endif -# endif -# ifdef __SASC -# define NO_vsnprintf -# endif -# ifdef VMS -# define NO_vsnprintf -# endif -# ifdef __OS400__ -# define NO_vsnprintf -# endif -# ifdef __MVS__ -# define NO_vsnprintf -# endif -#endif - -/* unlike snprintf (which is required in C99), _snprintf does not guarantee - null termination of the result -- however this is only used in gzlib.c where - the result is assured to fit in the space provided */ -#if defined(_MSC_VER) && _MSC_VER < 1900 -# define snprintf _snprintf -#endif - -#ifndef local -# define local static -#endif -/* since "static" is used to mean two completely different things in C, we - define "local" for the non-static meaning of "static", for readability - (compile with -Dlocal if your debugger can't find static symbols) */ - -/* gz* functions always use library allocation functions */ -#ifndef STDC - extern voidp malloc(uInt size); - extern void free(voidpf ptr); -#endif - -/* get errno and strerror definition */ -#if defined UNDER_CE -# include -# define zstrerror() gz_strwinerror((DWORD)GetLastError()) -#else -# ifndef NO_STRERROR -# include -# define zstrerror() strerror(errno) -# else -# define zstrerror() "stdio error (consult errno)" -# endif -#endif - -/* provide prototypes for these when building zlib without LFS */ -#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 - ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); - ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); - ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); - ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); -#endif - -/* default memLevel */ -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif - -/* default i/o buffer size -- double this for output when reading (this and - twice this must be able to fit in an unsigned type) */ -#define GZBUFSIZE 8192 - -/* gzip modes, also provide a little integrity check on the passed structure */ -#define GZ_NONE 0 -#define GZ_READ 7247 -#define GZ_WRITE 31153 -#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ - -/* values for gz_state how */ -#define LOOK 0 /* look for a gzip header */ -#define COPY 1 /* copy input directly */ -#define GZIP 2 /* decompress a gzip stream */ - -/* internal gzip file state data structure */ -typedef struct { - /* exposed contents for gzgetc() macro */ - struct gzFile_s x; /* "x" for exposed */ - /* x.have: number of bytes available at x.next */ - /* x.next: next output data to deliver or write */ - /* x.pos: current position in uncompressed data */ - /* used for both reading and writing */ - int mode; /* see gzip modes above */ - int fd; /* file descriptor */ - char *path; /* path or fd for error messages */ - unsigned size; /* buffer size, zero if not allocated yet */ - unsigned want; /* requested buffer size, default is GZBUFSIZE */ - unsigned char *in; /* input buffer (double-sized when writing) */ - unsigned char *out; /* output buffer (double-sized when reading) */ - int direct; /* 0 if processing gzip, 1 if transparent */ - /* just for reading */ - int how; /* 0: get header, 1: copy, 2: decompress */ - z_off64_t start; /* where the gzip data started, for rewinding */ - int eof; /* true if end of input file reached */ - int past; /* true if read requested past end */ - /* just for writing */ - int level; /* compression level */ - int strategy; /* compression strategy */ - int reset; /* true if a reset is pending after a Z_FINISH */ - /* seek request */ - z_off64_t skip; /* amount to skip (already rewound if backwards) */ - int seek; /* true if seek request pending */ - /* error information */ - int err; /* error code */ - char *msg; /* error message */ - /* zlib inflate or deflate stream */ - z_stream strm; /* stream structure in-place (not a pointer) */ -} gz_state; -typedef gz_state FAR *gz_statep; - -/* shared functions */ -void ZLIB_INTERNAL gz_error(gz_statep, int, const char *); -#if defined UNDER_CE -char ZLIB_INTERNAL *gz_strwinerror(DWORD error); -#endif - -/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t - value -- needed when comparing unsigned to z_off64_t, which is signed - (possible z_off64_t types off_t, off64_t, and long are all signed) */ -unsigned ZLIB_INTERNAL gz_intmax(void); -#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) diff --git a/ext/zlib/gzlib.c b/ext/zlib/gzlib.c deleted file mode 100644 index 983153cc8e..0000000000 --- a/ext/zlib/gzlib.c +++ /dev/null @@ -1,582 +0,0 @@ -/* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004-2024 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -#if defined(_WIN32) && !defined(__BORLANDC__) -# define LSEEK _lseeki64 -#else -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 -# define LSEEK lseek64 -#else -# define LSEEK lseek -#endif -#endif - -#if defined UNDER_CE - -/* Map the Windows error number in ERROR to a locale-dependent error message - string and return a pointer to it. Typically, the values for ERROR come - from GetLastError. - - The string pointed to shall not be modified by the application, but may be - overwritten by a subsequent call to gz_strwinerror - - The gz_strwinerror function does not change the current setting of - GetLastError. */ -char ZLIB_INTERNAL *gz_strwinerror(DWORD error) { - static char buf[1024]; - - wchar_t *msgbuf; - DWORD lasterr = GetLastError(); - DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_ALLOCATE_BUFFER, - NULL, - error, - 0, /* Default language */ - (LPVOID)&msgbuf, - 0, - NULL); - if (chars != 0) { - /* If there is an \r\n appended, zap it. */ - if (chars >= 2 - && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { - chars -= 2; - msgbuf[chars] = 0; - } - - if (chars > sizeof (buf) - 1) { - chars = sizeof (buf) - 1; - msgbuf[chars] = 0; - } - - wcstombs(buf, msgbuf, chars + 1); - LocalFree(msgbuf); - } - else { - sprintf(buf, "unknown win32 error (%ld)", error); - } - - SetLastError(lasterr); - return buf; -} - -#endif /* UNDER_CE */ - -/* Reset gzip file state */ -local void gz_reset(gz_statep state) { - state->x.have = 0; /* no output data available */ - if (state->mode == GZ_READ) { /* for reading ... */ - state->eof = 0; /* not at end of file */ - state->past = 0; /* have not read past end yet */ - state->how = LOOK; /* look for gzip header */ - } - else /* for writing ... */ - state->reset = 0; /* no deflateReset pending */ - state->seek = 0; /* no seek request pending */ - gz_error(state, Z_OK, NULL); /* clear error */ - state->x.pos = 0; /* no uncompressed data yet */ - state->strm.avail_in = 0; /* no input data yet */ -} - -/* Open a gzip file either by name or file descriptor. */ -local gzFile gz_open(const void *path, int fd, const char *mode) { - gz_statep state; - z_size_t len; - int oflag; -#ifdef O_CLOEXEC - int cloexec = 0; -#endif -#ifdef O_EXCL - int exclusive = 0; -#endif - - /* check input */ - if (path == NULL) - return NULL; - - /* allocate gzFile structure to return */ - state = (gz_statep)malloc(sizeof(gz_state)); - if (state == NULL) - return NULL; - state->size = 0; /* no buffers allocated yet */ - state->want = GZBUFSIZE; /* requested buffer size */ - state->msg = NULL; /* no error message yet */ - - /* interpret mode */ - state->mode = GZ_NONE; - state->level = Z_DEFAULT_COMPRESSION; - state->strategy = Z_DEFAULT_STRATEGY; - state->direct = 0; - while (*mode) { - if (*mode >= '0' && *mode <= '9') - state->level = *mode - '0'; - else - switch (*mode) { - case 'r': - state->mode = GZ_READ; - break; -#ifndef NO_GZCOMPRESS - case 'w': - state->mode = GZ_WRITE; - break; - case 'a': - state->mode = GZ_APPEND; - break; -#endif - case '+': /* can't read and write at the same time */ - free(state); - return NULL; - case 'b': /* ignore -- will request binary anyway */ - break; -#ifdef O_CLOEXEC - case 'e': - cloexec = 1; - break; -#endif -#ifdef O_EXCL - case 'x': - exclusive = 1; - break; -#endif - case 'f': - state->strategy = Z_FILTERED; - break; - case 'h': - state->strategy = Z_HUFFMAN_ONLY; - break; - case 'R': - state->strategy = Z_RLE; - break; - case 'F': - state->strategy = Z_FIXED; - break; - case 'T': - state->direct = 1; - break; - default: /* could consider as an error, but just ignore */ - ; - } - mode++; - } - - /* must provide an "r", "w", or "a" */ - if (state->mode == GZ_NONE) { - free(state); - return NULL; - } - - /* can't force transparent read */ - if (state->mode == GZ_READ) { - if (state->direct) { - free(state); - return NULL; - } - state->direct = 1; /* for empty file */ - } - - /* save the path name for error messages */ -#ifdef WIDECHAR - if (fd == -2) { - len = wcstombs(NULL, path, 0); - if (len == (z_size_t)-1) - len = 0; - } - else -#endif - len = strlen((const char *)path); - state->path = (char *)malloc(len + 1); - if (state->path == NULL) { - free(state); - return NULL; - } -#ifdef WIDECHAR - if (fd == -2) - if (len) - wcstombs(state->path, path, len + 1); - else - *(state->path) = 0; - else -#endif -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - (void)snprintf(state->path, len + 1, "%s", (const char *)path); -#else - strcpy(state->path, path); -#endif - - /* compute the flags for open() */ - oflag = -#ifdef O_LARGEFILE - O_LARGEFILE | -#endif -#ifdef O_BINARY - O_BINARY | -#endif -#ifdef O_CLOEXEC - (cloexec ? O_CLOEXEC : 0) | -#endif - (state->mode == GZ_READ ? - O_RDONLY : - (O_WRONLY | O_CREAT | -#ifdef O_EXCL - (exclusive ? O_EXCL : 0) | -#endif - (state->mode == GZ_WRITE ? - O_TRUNC : - O_APPEND))); - - /* open the file with the appropriate flags (or just use fd) */ - state->fd = fd > -1 ? fd : ( -#ifdef WIDECHAR - fd == -2 ? _wopen(path, oflag, 0666) : -#endif - open((const char *)path, oflag, 0666)); - if (state->fd == -1) { - free(state->path); - free(state); - return NULL; - } - if (state->mode == GZ_APPEND) { - LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */ - state->mode = GZ_WRITE; /* simplify later checks */ - } - - /* save the current position for rewinding (only if reading) */ - if (state->mode == GZ_READ) { - state->start = LSEEK(state->fd, 0, SEEK_CUR); - if (state->start == -1) state->start = 0; - } - - /* initialize stream */ - gz_reset(state); - - /* return stream */ - return (gzFile)state; -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzopen(const char *path, const char *mode) { - return gz_open(path, -1, mode); -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzopen64(const char *path, const char *mode) { - return gz_open(path, -1, mode); -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzdopen(int fd, const char *mode) { - char *path; /* identifier for error messages */ - gzFile gz; - - if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) - return NULL; -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - (void)snprintf(path, 7 + 3 * sizeof(int), "", fd); -#else - sprintf(path, "", fd); /* for debugging */ -#endif - gz = gz_open(path, fd, mode); - free(path); - return gz; -} - -/* -- see zlib.h -- */ -#ifdef WIDECHAR -gzFile ZEXPORT gzopen_w(const wchar_t *path, const char *mode) { - return gz_open(path, -2, mode); -} -#endif - -/* -- see zlib.h -- */ -int ZEXPORT gzbuffer(gzFile file, unsigned size) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* make sure we haven't already allocated memory */ - if (state->size != 0) - return -1; - - /* check and set requested size */ - if ((size << 1) < size) - return -1; /* need to be able to double it */ - if (size < 8) - size = 8; /* needed to behave well with flushing */ - state->want = size; - return 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzrewind(gzFile file) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* back up and start over */ - if (LSEEK(state->fd, state->start, SEEK_SET) == -1) - return -1; - gz_reset(state); - return 0; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) { - unsigned n; - z_off64_t ret; - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* check that there's no error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - - /* can only seek from start or relative to current position */ - if (whence != SEEK_SET && whence != SEEK_CUR) - return -1; - - /* normalize offset to a SEEK_CUR specification */ - if (whence == SEEK_SET) - offset -= state->x.pos; - else if (state->seek) - offset += state->skip; - state->seek = 0; - - /* if within raw area while reading, just go there */ - if (state->mode == GZ_READ && state->how == COPY && - state->x.pos + offset >= 0) { - ret = LSEEK(state->fd, offset - (z_off64_t)state->x.have, SEEK_CUR); - if (ret == -1) - return -1; - state->x.have = 0; - state->eof = 0; - state->past = 0; - state->seek = 0; - gz_error(state, Z_OK, NULL); - state->strm.avail_in = 0; - state->x.pos += offset; - return state->x.pos; - } - - /* calculate skip amount, rewinding if needed for back seek when reading */ - if (offset < 0) { - if (state->mode != GZ_READ) /* writing -- can't go backwards */ - return -1; - offset += state->x.pos; - if (offset < 0) /* before start of file! */ - return -1; - if (gzrewind(file) == -1) /* rewind, then skip to offset */ - return -1; - } - - /* if reading, skip what's in output buffer (one less gzgetc() check) */ - if (state->mode == GZ_READ) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? - (unsigned)offset : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - offset -= n; - } - - /* request skip (if not zero) */ - if (offset) { - state->seek = 1; - state->skip = offset; - } - return state->x.pos + offset; -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence) { - z_off64_t ret; - - ret = gzseek64(file, (z_off64_t)offset, whence); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gztell64(gzFile file) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* return position */ - return state->x.pos + (state->seek ? state->skip : 0); -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gztell(gzFile file) { - z_off64_t ret; - - ret = gztell64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gzoffset64(gzFile file) { - z_off64_t offset; - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* compute and return effective offset in file */ - offset = LSEEK(state->fd, 0, SEEK_CUR); - if (offset == -1) - return -1; - if (state->mode == GZ_READ) /* reading */ - offset -= state->strm.avail_in; /* don't count buffered input */ - return offset; -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gzoffset(gzFile file) { - z_off64_t ret; - - ret = gzoffset64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzeof(gzFile file) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return 0; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return 0; - - /* return end-of-file state */ - return state->mode == GZ_READ ? state->past : 0; -} - -/* -- see zlib.h -- */ -const char * ZEXPORT gzerror(gzFile file, int *errnum) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return NULL; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return NULL; - - /* return error information */ - if (errnum != NULL) - *errnum = state->err; - return state->err == Z_MEM_ERROR ? "out of memory" : - (state->msg == NULL ? "" : state->msg); -} - -/* -- see zlib.h -- */ -void ZEXPORT gzclearerr(gzFile file) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return; - - /* clear error and end-of-file */ - if (state->mode == GZ_READ) { - state->eof = 0; - state->past = 0; - } - gz_error(state, Z_OK, NULL); -} - -/* Create an error message in allocated memory and set state->err and - state->msg accordingly. Free any previous error message already there. Do - not try to free or allocate space if the error is Z_MEM_ERROR (out of - memory). Simply save the error message as a static string. If there is an - allocation failure constructing the error message, then convert the error to - out of memory. */ -void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) { - /* free previously allocated message and clear */ - if (state->msg != NULL) { - if (state->err != Z_MEM_ERROR) - free(state->msg); - state->msg = NULL; - } - - /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ - if (err != Z_OK && err != Z_BUF_ERROR) - state->x.have = 0; - - /* set error code, and if no message, then done */ - state->err = err; - if (msg == NULL) - return; - - /* for an out of memory error, return literal string when requested */ - if (err == Z_MEM_ERROR) - return; - - /* construct error message with path */ - if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == - NULL) { - state->err = Z_MEM_ERROR; - return; - } -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, - "%s%s%s", state->path, ": ", msg); -#else - strcpy(state->msg, state->path); - strcat(state->msg, ": "); - strcat(state->msg, msg); -#endif -} - -/* portably return maximum value for an int (when limits.h presumed not - available) -- we need to do this to cover cases where 2's complement not - used, since C standard permits 1's complement and sign-bit representations, - otherwise we could just use ((unsigned)-1) >> 1 */ -unsigned ZLIB_INTERNAL gz_intmax(void) { -#ifdef INT_MAX - return INT_MAX; -#else - unsigned p = 1, q; - do { - q = p; - p <<= 1; - p++; - } while (p > q); - return q >> 1; -#endif -} diff --git a/ext/zlib/gzread.c b/ext/zlib/gzread.c deleted file mode 100644 index 4168cbc887..0000000000 --- a/ext/zlib/gzread.c +++ /dev/null @@ -1,602 +0,0 @@ -/* gzread.c -- zlib functions for reading gzip files - * Copyright (C) 2004-2017 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from - state->fd, and update state->eof, state->err, and state->msg as appropriate. - This function needs to loop on read(), since read() is not guaranteed to - read the number of bytes requested, depending on the type of descriptor. */ -local int gz_load(gz_statep state, unsigned char *buf, unsigned len, - unsigned *have) { - int ret; - unsigned get, max = ((unsigned)-1 >> 2) + 1; - - *have = 0; - do { - get = len - *have; - if (get > max) - get = max; - ret = read(state->fd, buf + *have, get); - if (ret <= 0) - break; - *have += (unsigned)ret; - } while (*have < len); - if (ret < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - if (ret == 0) - state->eof = 1; - return 0; -} - -/* Load up input buffer and set eof flag if last data loaded -- return -1 on - error, 0 otherwise. Note that the eof flag is set when the end of the input - file is reached, even though there may be unused data in the buffer. Once - that data has been used, no more attempts will be made to read the file. - If strm->avail_in != 0, then the current data is moved to the beginning of - the input buffer, and then the remainder of the buffer is loaded with the - available data from the input file. */ -local int gz_avail(gz_statep state) { - unsigned got; - z_streamp strm = &(state->strm); - - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - if (state->eof == 0) { - if (strm->avail_in) { /* copy what's there to the start */ - unsigned char *p = state->in; - unsigned const char *q = strm->next_in; - unsigned n = strm->avail_in; - do { - *p++ = *q++; - } while (--n); - } - if (gz_load(state, state->in + strm->avail_in, - state->size - strm->avail_in, &got) == -1) - return -1; - strm->avail_in += got; - strm->next_in = state->in; - } - return 0; -} - -/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. - If this is the first time in, allocate required memory. state->how will be - left unchanged if there is no more input data available, will be set to COPY - if there is no gzip header and direct copying will be performed, or it will - be set to GZIP for decompression. If direct copying, then leftover input - data from the input buffer will be copied to the output buffer. In that - case, all further file reads will be directly to either the output buffer or - a user buffer. If decompressing, the inflate state will be initialized. - gz_look() will return 0 on success or -1 on failure. */ -local int gz_look(gz_statep state) { - z_streamp strm = &(state->strm); - - /* allocate read buffers and inflate memory */ - if (state->size == 0) { - /* allocate buffers */ - state->in = (unsigned char *)malloc(state->want); - state->out = (unsigned char *)malloc(state->want << 1); - if (state->in == NULL || state->out == NULL) { - free(state->out); - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - state->size = state->want; - - /* allocate inflate memory */ - state->strm.zalloc = Z_NULL; - state->strm.zfree = Z_NULL; - state->strm.opaque = Z_NULL; - state->strm.avail_in = 0; - state->strm.next_in = Z_NULL; - if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ - free(state->out); - free(state->in); - state->size = 0; - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - } - - /* get at least the magic bytes in the input buffer */ - if (strm->avail_in < 2) { - if (gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) - return 0; - } - - /* look for gzip magic bytes -- if there, do gzip decoding (note: there is - a logical dilemma here when considering the case of a partially written - gzip file, to wit, if a single 31 byte is written, then we cannot tell - whether this is a single-byte file, or just a partially written gzip - file -- for here we assume that if a gzip file is being written, then - the header will be written in a single operation, so that reading a - single byte is sufficient indication that it is not a gzip file) */ - if (strm->avail_in > 1 && - strm->next_in[0] == 31 && strm->next_in[1] == 139) { - inflateReset(strm); - state->how = GZIP; - state->direct = 0; - return 0; - } - - /* no gzip header -- if we were decoding gzip before, then this is trailing - garbage. Ignore the trailing garbage and finish. */ - if (state->direct == 0) { - strm->avail_in = 0; - state->eof = 1; - state->x.have = 0; - return 0; - } - - /* doing raw i/o, copy any leftover input to output -- this assumes that - the output buffer is larger than the input buffer, which also assures - space for gzungetc() */ - state->x.next = state->out; - memcpy(state->x.next, strm->next_in, strm->avail_in); - state->x.have = strm->avail_in; - strm->avail_in = 0; - state->how = COPY; - state->direct = 1; - return 0; -} - -/* Decompress from input to the provided next_out and avail_out in the state. - On return, state->x.have and state->x.next point to the just decompressed - data. If the gzip stream completes, state->how is reset to LOOK to look for - the next gzip stream or raw data, once state->x.have is depleted. Returns 0 - on success, -1 on failure. */ -local int gz_decomp(gz_statep state) { - int ret = Z_OK; - unsigned had; - z_streamp strm = &(state->strm); - - /* fill output buffer up to end of deflate stream */ - had = strm->avail_out; - do { - /* get more input for inflate() */ - if (strm->avail_in == 0 && gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) { - gz_error(state, Z_BUF_ERROR, "unexpected end of file"); - break; - } - - /* decompress and handle errors */ - ret = inflate(strm, Z_NO_FLUSH); - if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { - gz_error(state, Z_STREAM_ERROR, - "internal error: inflate stream corrupt"); - return -1; - } - if (ret == Z_MEM_ERROR) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ - gz_error(state, Z_DATA_ERROR, - strm->msg == NULL ? "compressed data error" : strm->msg); - return -1; - } - } while (strm->avail_out && ret != Z_STREAM_END); - - /* update available output */ - state->x.have = had - strm->avail_out; - state->x.next = strm->next_out - state->x.have; - - /* if the gzip stream completed successfully, look for another */ - if (ret == Z_STREAM_END) - state->how = LOOK; - - /* good decompression */ - return 0; -} - -/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. - Data is either copied from the input file or decompressed from the input - file depending on state->how. If state->how is LOOK, then a gzip header is - looked for to determine whether to copy or decompress. Returns -1 on error, - otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the - end of the input file has been reached and all data has been processed. */ -local int gz_fetch(gz_statep state) { - z_streamp strm = &(state->strm); - - do { - switch(state->how) { - case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ - if (gz_look(state) == -1) - return -1; - if (state->how == LOOK) - return 0; - break; - case COPY: /* -> COPY */ - if (gz_load(state, state->out, state->size << 1, &(state->x.have)) - == -1) - return -1; - state->x.next = state->out; - return 0; - case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ - strm->avail_out = state->size << 1; - strm->next_out = state->out; - if (gz_decomp(state) == -1) - return -1; - } - } while (state->x.have == 0 && (!state->eof || strm->avail_in)); - return 0; -} - -/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ -local int gz_skip(gz_statep state, z_off64_t len) { - unsigned n; - - /* skip over len bytes or reach end-of-file, whichever comes first */ - while (len) - /* skip over whatever is in output buffer */ - if (state->x.have) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? - (unsigned)len : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - len -= n; - } - - /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) - break; - - /* need more data to skip -- load up output buffer */ - else { - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) - return -1; - } - return 0; -} - -/* Read len bytes into buf from file, or less than len up to the end of the - input. Return the number of bytes read. If zero is returned, either the - end of file was reached, or there was an error. state->err must be - consulted in that case to determine which. */ -local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) { - z_size_t got; - unsigned n; - - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return 0; - } - - /* get len bytes to buf, or less than len if at the end */ - got = 0; - do { - /* set n to the maximum amount of len that fits in an unsigned int */ - n = (unsigned)-1; - if (n > len) - n = (unsigned)len; - - /* first just try copying data from the output buffer */ - if (state->x.have) { - if (state->x.have < n) - n = state->x.have; - memcpy(buf, state->x.next, n); - state->x.next += n; - state->x.have -= n; - } - - /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) { - state->past = 1; /* tried to read past end */ - break; - } - - /* need output data -- for small len or new stream load up our output - buffer */ - else if (state->how == LOOK || n < (state->size << 1)) { - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) - return 0; - continue; /* no progress yet -- go back to copy above */ - /* the copy above assures that we will leave with space in the - output buffer, allowing at least one gzungetc() to succeed */ - } - - /* large len -- read directly into user buffer */ - else if (state->how == COPY) { /* read directly */ - if (gz_load(state, (unsigned char *)buf, n, &n) == -1) - return 0; - } - - /* large len -- decompress directly into user buffer */ - else { /* state->how == GZIP */ - state->strm.avail_out = n; - state->strm.next_out = (unsigned char *)buf; - if (gz_decomp(state) == -1) - return 0; - n = state->x.have; - state->x.have = 0; - } - - /* update progress */ - len -= n; - buf = (char *)buf + n; - got += n; - state->x.pos += n; - } while (len); - - /* return number of bytes read into user buffer */ - return got; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids a flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_STREAM_ERROR, "request does not fit in an int"); - return -1; - } - - /* read len or fewer bytes to buf */ - len = (unsigned)gz_read(state, buf, len); - - /* check for an error */ - if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - - /* return the number of bytes read (this is assured to fit in an int) */ - return (int)len; -} - -/* -- see zlib.h -- */ -z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file) { - z_size_t len; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return 0; - - /* compute bytes to read -- error on overflow */ - len = nitems * size; - if (size && len / size != nitems) { - gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); - return 0; - } - - /* read len or fewer bytes to buf, return the number of full items read */ - return len ? gz_read(state, buf, len) / size : 0; -} - -/* -- see zlib.h -- */ -#ifdef Z_PREFIX_SET -# undef z_gzgetc -#else -# undef gzgetc -#endif -int ZEXPORT gzgetc(gzFile file) { - unsigned char buf[1]; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* try output buffer (no need to check for skip request) */ - if (state->x.have) { - state->x.have--; - state->x.pos++; - return *(state->x.next)++; - } - - /* nothing there -- try gz_read() */ - return gz_read(state, buf, 1) < 1 ? -1 : buf[0]; -} - -int ZEXPORT gzgetc_(gzFile file) { - return gzgetc(file); -} - -/* -- see zlib.h -- */ -int ZEXPORT gzungetc(int c, gzFile file) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* in case this was just opened, set up the input buffer */ - if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) - (void)gz_look(state); - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return -1; - } - - /* can't push EOF */ - if (c < 0) - return -1; - - /* if output buffer empty, put byte at end (allows more pushing) */ - if (state->x.have == 0) { - state->x.have = 1; - state->x.next = state->out + (state->size << 1) - 1; - state->x.next[0] = (unsigned char)c; - state->x.pos--; - state->past = 0; - return c; - } - - /* if no room, give up (must have already done a gzungetc()) */ - if (state->x.have == (state->size << 1)) { - gz_error(state, Z_DATA_ERROR, "out of room to push characters"); - return -1; - } - - /* slide output data if needed and insert byte before existing data */ - if (state->x.next == state->out) { - unsigned char *src = state->out + state->x.have; - unsigned char *dest = state->out + (state->size << 1); - while (src > state->out) - *--dest = *--src; - state->x.next = dest; - } - state->x.have++; - state->x.next--; - state->x.next[0] = (unsigned char)c; - state->x.pos--; - state->past = 0; - return c; -} - -/* -- see zlib.h -- */ -char * ZEXPORT gzgets(gzFile file, char *buf, int len) { - unsigned left, n; - char *str; - unsigned char *eol; - gz_statep state; - - /* check parameters and get internal structure */ - if (file == NULL || buf == NULL || len < 1) - return NULL; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return NULL; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return NULL; - } - - /* copy output bytes up to new line or len - 1, whichever comes first -- - append a terminating zero to the string (we don't check for a zero in - the contents, let the user worry about that) */ - str = buf; - left = (unsigned)len - 1; - if (left) do { - /* assure that something is in the output buffer */ - if (state->x.have == 0 && gz_fetch(state) == -1) - return NULL; /* error */ - if (state->x.have == 0) { /* end of file */ - state->past = 1; /* read past end */ - break; /* return what we have */ - } - - /* look for end-of-line in current output buffer */ - n = state->x.have > left ? left : state->x.have; - eol = (unsigned char *)memchr(state->x.next, '\n', n); - if (eol != NULL) - n = (unsigned)(eol - state->x.next) + 1; - - /* copy through end-of-line, or remainder if not found */ - memcpy(buf, state->x.next, n); - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - left -= n; - buf += n; - } while (left && eol == NULL); - - /* return terminated string, or if nothing, end of file */ - if (buf == str) - return NULL; - buf[0] = 0; - return str; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzdirect(gzFile file) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* if the state is not known, but we can find out, then do so (this is - mainly for right after a gzopen() or gzdopen()) */ - if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) - (void)gz_look(state); - - /* return 1 if transparent, 0 if processing a gzip stream */ - return state->direct; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzclose_r(gzFile file) { - int ret, err; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're reading */ - if (state->mode != GZ_READ) - return Z_STREAM_ERROR; - - /* free memory and close file */ - if (state->size) { - inflateEnd(&(state->strm)); - free(state->out); - free(state->in); - } - err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; - gz_error(state, Z_OK, NULL); - free(state->path); - ret = close(state->fd); - free(state); - return ret ? Z_ERRNO : err; -} diff --git a/ext/zlib/gzwrite.c b/ext/zlib/gzwrite.c deleted file mode 100644 index 435b4621b5..0000000000 --- a/ext/zlib/gzwrite.c +++ /dev/null @@ -1,631 +0,0 @@ -/* gzwrite.c -- zlib functions for writing gzip files - * Copyright (C) 2004-2019 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* Initialize state for writing a gzip file. Mark initialization by setting - state->size to non-zero. Return -1 on a memory allocation failure, or 0 on - success. */ -local int gz_init(gz_statep state) { - int ret; - z_streamp strm = &(state->strm); - - /* allocate input buffer (double size for gzprintf) */ - state->in = (unsigned char *)malloc(state->want << 1); - if (state->in == NULL) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - - /* only need output buffer and deflate state if compressing */ - if (!state->direct) { - /* allocate output buffer */ - state->out = (unsigned char *)malloc(state->want); - if (state->out == NULL) { - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - - /* allocate deflate memory, set up for gzip compression */ - strm->zalloc = Z_NULL; - strm->zfree = Z_NULL; - strm->opaque = Z_NULL; - ret = deflateInit2(strm, state->level, Z_DEFLATED, - MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); - if (ret != Z_OK) { - free(state->out); - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - strm->next_in = NULL; - } - - /* mark state as initialized */ - state->size = state->want; - - /* initialize write buffer if compressing */ - if (!state->direct) { - strm->avail_out = state->size; - strm->next_out = state->out; - state->x.next = strm->next_out; - } - return 0; -} - -/* Compress whatever is at avail_in and next_in and write to the output file. - Return -1 if there is an error writing to the output file or if gz_init() - fails to allocate memory, otherwise 0. flush is assumed to be a valid - deflate() flush value. If flush is Z_FINISH, then the deflate() state is - reset to start a new gzip stream. If gz->direct is true, then simply write - to the output file without compressing, and ignore flush. */ -local int gz_comp(gz_statep state, int flush) { - int ret, writ; - unsigned have, put, max = ((unsigned)-1 >> 2) + 1; - z_streamp strm = &(state->strm); - - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return -1; - - /* write directly if requested */ - if (state->direct) { - while (strm->avail_in) { - put = strm->avail_in > max ? max : strm->avail_in; - writ = write(state->fd, strm->next_in, put); - if (writ < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - strm->avail_in -= (unsigned)writ; - strm->next_in += writ; - } - return 0; - } - - /* check for a pending reset */ - if (state->reset) { - /* don't start a new gzip member unless there is data to write */ - if (strm->avail_in == 0) - return 0; - deflateReset(strm); - state->reset = 0; - } - - /* run deflate() on provided input until it produces no more output */ - ret = Z_OK; - do { - /* write out current buffer contents if full, or if flushing, but if - doing Z_FINISH then don't write until we get to Z_STREAM_END */ - if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && - (flush != Z_FINISH || ret == Z_STREAM_END))) { - while (strm->next_out > state->x.next) { - put = strm->next_out - state->x.next > (int)max ? max : - (unsigned)(strm->next_out - state->x.next); - writ = write(state->fd, state->x.next, put); - if (writ < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - state->x.next += writ; - } - if (strm->avail_out == 0) { - strm->avail_out = state->size; - strm->next_out = state->out; - state->x.next = state->out; - } - } - - /* compress */ - have = strm->avail_out; - ret = deflate(strm, flush); - if (ret == Z_STREAM_ERROR) { - gz_error(state, Z_STREAM_ERROR, - "internal error: deflate stream corrupt"); - return -1; - } - have -= strm->avail_out; - } while (have); - - /* if that completed a deflate stream, allow another to start */ - if (flush == Z_FINISH) - state->reset = 1; - - /* all done, no errors */ - return 0; -} - -/* Compress len zeros to output. Return -1 on a write error or memory - allocation failure by gz_comp(), or 0 on success. */ -local int gz_zero(gz_statep state, z_off64_t len) { - int first; - unsigned n; - z_streamp strm = &(state->strm); - - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return -1; - - /* compress len zeros (len guaranteed > 0) */ - first = 1; - while (len) { - n = GT_OFF(state->size) || (z_off64_t)state->size > len ? - (unsigned)len : state->size; - if (first) { - memset(state->in, 0, n); - first = 0; - } - strm->avail_in = n; - strm->next_in = state->in; - state->x.pos += n; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return -1; - len -= n; - } - return 0; -} - -/* Write len bytes from buf to file. Return the number of bytes written. If - the returned value is less than len, then there was an error. */ -local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) { - z_size_t put = len; - - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; - - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return 0; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } - - /* for small len, copy to input buffer, otherwise compress directly */ - if (len < state->size) { - /* copy to input buffer, compress when full */ - do { - unsigned have, copy; - - if (state->strm.avail_in == 0) - state->strm.next_in = state->in; - have = (unsigned)((state->strm.next_in + state->strm.avail_in) - - state->in); - copy = state->size - have; - if (copy > len) - copy = (unsigned)len; - memcpy(state->in + have, buf, copy); - state->strm.avail_in += copy; - state->x.pos += copy; - buf = (const char *)buf + copy; - len -= copy; - if (len && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - } while (len); - } - else { - /* consume whatever's left in the input buffer */ - if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - - /* directly compress user buffer to file */ - state->strm.next_in = (z_const Bytef *)buf; - do { - unsigned n = (unsigned)-1; - if (n > len) - n = (unsigned)len; - state->strm.avail_in = n; - state->x.pos += n; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - len -= n; - } while (len); - } - - /* input was all buffered or compressed */ - return put; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids a flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); - return 0; - } - - /* write len bytes from buf (the return value will fit in an int) */ - return (int)gz_write(state, buf, len); -} - -/* -- see zlib.h -- */ -z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems, - gzFile file) { - z_size_t len; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* compute bytes to read -- error on overflow */ - len = nitems * size; - if (size && len / size != nitems) { - gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); - return 0; - } - - /* write len bytes to buf, return the number of full items written */ - return len ? gz_write(state, buf, len) / size : 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzputc(gzFile file, int c) { - unsigned have; - unsigned char buf[1]; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return -1; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } - - /* try writing to input buffer for speed (state->size == 0 if buffer not - initialized) */ - if (state->size) { - if (strm->avail_in == 0) - strm->next_in = state->in; - have = (unsigned)((strm->next_in + strm->avail_in) - state->in); - if (have < state->size) { - state->in[have] = (unsigned char)c; - strm->avail_in++; - state->x.pos++; - return c & 0xff; - } - } - - /* no room in buffer or not initialized, use gz_write() */ - buf[0] = (unsigned char)c; - if (gz_write(state, buf, 1) != 1) - return -1; - return c & 0xff; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzputs(gzFile file, const char *s) { - z_size_t len, put; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return -1; - - /* write string */ - len = strlen(s); - if ((int)len < 0 || (unsigned)len != len) { - gz_error(state, Z_STREAM_ERROR, "string length does not fit in int"); - return -1; - } - put = gz_write(state, s, len); - return put < len ? -1 : (int)len; -} - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -#include - -/* -- see zlib.h -- */ -int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { - int len; - unsigned left; - char *next; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return state->err; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->err; - } - - /* do the printf() into the input buffer, put length in len -- the input - buffer is double-sized just for this function, so there is guaranteed to - be state->size bytes available after the current contents */ - if (strm->avail_in == 0) - strm->next_in = state->in; - next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); - next[state->size - 1] = 0; -#ifdef NO_vsnprintf -# ifdef HAS_vsprintf_void - (void)vsprintf(next, format, va); - for (len = 0; len < state->size; len++) - if (next[len] == 0) break; -# else - len = vsprintf(next, format, va); -# endif -#else -# ifdef HAS_vsnprintf_void - (void)vsnprintf(next, state->size, format, va); - len = strlen(next); -# else - len = vsnprintf(next, state->size, format, va); -# endif -#endif - - /* check that printf() results fit in buffer */ - if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) - return 0; - - /* update buffer and position, compress first half if past that */ - strm->avail_in += (unsigned)len; - state->x.pos += len; - if (strm->avail_in >= state->size) { - left = strm->avail_in - state->size; - strm->avail_in = state->size; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return state->err; - memmove(state->in, state->in + state->size, left); - strm->next_in = state->in; - strm->avail_in = left; - } - return len; -} - -int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) { - va_list va; - int ret; - - va_start(va, format); - ret = gzvprintf(file, format, va); - va_end(va); - return ret; -} - -#else /* !STDC && !Z_HAVE_STDARG_H */ - -/* -- see zlib.h -- */ -int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3, - int a4, int a5, int a6, int a7, int a8, int a9, int a10, - int a11, int a12, int a13, int a14, int a15, int a16, - int a17, int a18, int a19, int a20) { - unsigned len, left; - char *next; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that can really pass pointer in ints */ - if (sizeof(int) != sizeof(void *)) - return Z_STREAM_ERROR; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return state->error; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->error; - } - - /* do the printf() into the input buffer, put length in len -- the input - buffer is double-sized just for this function, so there is guaranteed to - be state->size bytes available after the current contents */ - if (strm->avail_in == 0) - strm->next_in = state->in; - next = (char *)(strm->next_in + strm->avail_in); - next[state->size - 1] = 0; -#ifdef NO_snprintf -# ifdef HAS_sprintf_void - sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, - a13, a14, a15, a16, a17, a18, a19, a20); - for (len = 0; len < size; len++) - if (next[len] == 0) - break; -# else - len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, - a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#else -# ifdef HAS_snprintf_void - snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, - a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - len = strlen(next); -# else - len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#endif - - /* check that printf() results fit in buffer */ - if (len == 0 || len >= state->size || next[state->size - 1] != 0) - return 0; - - /* update buffer and position, compress first half if past that */ - strm->avail_in += len; - state->x.pos += len; - if (strm->avail_in >= state->size) { - left = strm->avail_in - state->size; - strm->avail_in = state->size; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return state->err; - memmove(state->in, state->in + state->size, left); - strm->next_in = state->in; - strm->avail_in = left; - } - return (int)len; -} - -#endif - -/* -- see zlib.h -- */ -int ZEXPORT gzflush(gzFile file, int flush) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* check flush parameter */ - if (flush < 0 || flush > Z_FINISH) - return Z_STREAM_ERROR; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->err; - } - - /* compress remaining data with requested flush */ - (void)gz_comp(state, flush); - return state->err; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzsetparams(gzFile file, int level, int strategy) { - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct) - return Z_STREAM_ERROR; - - /* if no change is requested, then do nothing */ - if (level == state->level && strategy == state->strategy) - return Z_OK; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->err; - } - - /* change compression parameters for subsequent input */ - if (state->size) { - /* flush previous input with previous parameters before changing */ - if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1) - return state->err; - deflateParams(strm, level, strategy); - } - state->level = level; - state->strategy = strategy; - return Z_OK; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzclose_w(gzFile file) { - int ret = Z_OK; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're writing */ - if (state->mode != GZ_WRITE) - return Z_STREAM_ERROR; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - ret = state->err; - } - - /* flush, free memory, and close file */ - if (gz_comp(state, Z_FINISH) == -1) - ret = state->err; - if (state->size) { - if (!state->direct) { - (void)deflateEnd(&(state->strm)); - free(state->out); - } - free(state->in); - } - gz_error(state, Z_OK, NULL); - free(state->path); - if (close(state->fd) == -1) - ret = Z_ERRNO; - free(state); - return ret; -} diff --git a/ext/zlib/infback.c b/ext/zlib/infback.c deleted file mode 100644 index e7b25b307a..0000000000 --- a/ext/zlib/infback.c +++ /dev/null @@ -1,628 +0,0 @@ -/* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2022 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - This code is largely copied from inflate.c. Normally either infback.o or - inflate.o would be linked into an application--not both. The interface - with inffast.c is retained so that optimized assembler-coded versions of - inflate_fast() can be used with either inflate.c or infback.c. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -/* - strm provides memory allocation functions in zalloc and zfree, or - Z_NULL to use the library memory allocation functions. - - windowBits is in the range 8..15, and window is a user-supplied - window and output buffer that is 2**windowBits bytes. - */ -int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, - unsigned char FAR *window, const char *version, - int stream_size) { - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL || window == Z_NULL || - windowBits < 8 || windowBits > 15) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *)ZALLOC(strm, 1, - sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->dmax = 32768U; - state->wbits = (uInt)windowBits; - state->wsize = 1U << windowBits; - state->window = window; - state->wnext = 0; - state->whave = 0; - state->sane = 1; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(struct inflate_state FAR *state) { -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -/* Macros for inflateBack(): */ - -/* Load returned state from inflate_fast() */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Set state from registers for inflate_fast() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Assure that some input is available. If input is requested, but denied, - then return a Z_BUF_ERROR from inflateBack(). */ -#define PULL() \ - do { \ - if (have == 0) { \ - have = in(in_desc, &next); \ - if (have == 0) { \ - next = Z_NULL; \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflateBack() - with an error if there is no input available. */ -#define PULLBYTE() \ - do { \ - PULL(); \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflateBack() with - an error. */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Assure that some output space is available, by writing out the window - if it's full. If the write fails, return from inflateBack() with a - Z_BUF_ERROR. */ -#define ROOM() \ - do { \ - if (left == 0) { \ - put = state->window; \ - left = state->wsize; \ - state->whave = left; \ - if (out(out_desc, put, left)) { \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* - strm provides the memory allocation functions and window buffer on input, - and provides information on the unused input on return. For Z_DATA_ERROR - returns, strm will also provide an error message. - - in() and out() are the call-back input and output functions. When - inflateBack() needs more input, it calls in(). When inflateBack() has - filled the window with output, or when it completes with data in the - window, it calls out() to write out the data. The application must not - change the provided input until in() is called again or inflateBack() - returns. The application must not change the window/output buffer until - inflateBack() returns. - - in() and out() are called with a descriptor parameter provided in the - inflateBack() call. This parameter can be a structure that provides the - information required to do the read or write, as well as accumulated - information on the input and output such as totals and check values. - - in() should return zero on failure. out() should return non-zero on - failure. If either in() or out() fails, than inflateBack() returns a - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it - was in() or out() that caused in the error. Otherwise, inflateBack() - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format - error, or Z_MEM_ERROR if it could not allocate memory for the state. - inflateBack() can also return Z_STREAM_ERROR if the input parameters - are not correct, i.e. strm is Z_NULL or the state was not initialized. - */ -int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc) { - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - /* Check that the strm exists and that the state was initialized */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* Reset the state */ - strm->msg = Z_NULL; - state->mode = TYPE; - state->last = 0; - state->whave = 0; - next = strm->next_in; - have = next != Z_NULL ? strm->avail_in : 0; - hold = 0; - bits = 0; - put = state->window; - left = state->wsize; - - /* Inflate until end of block marked as last */ - for (;;) - switch (state->mode) { - case TYPE: - /* determine and dispatch block type */ - if (state->last) { - BYTEBITS(); - state->mode = DONE; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - - case STORED: - /* get and verify stored block length */ - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - - /* copy stored block from input to output */ - while (state->length != 0) { - copy = state->length; - PULL(); - ROOM(); - if (copy > have) copy = have; - if (copy > left) copy = left; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - - case TABLE: - /* get dynamic table entries descriptor */ - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - - /* get code length code lengths (not a typo) */ - state->have = 0; - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - - /* get length and distance code code lengths */ - state->have = 0; - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = (unsigned)(state->lens[state->have - 1]); - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - /* fallthrough */ - - case LEN: - /* use inflate_fast() if we have enough input and output */ - if (have >= 6 && left >= 258) { - RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; - inflate_fast(strm, state->wsize); - LOAD(); - break; - } - - /* get a literal, length, or end-of-block code */ - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - state->length = (unsigned)here.val; - - /* process literal */ - if (here.op == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - ROOM(); - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - } - - /* process end of block */ - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - - /* invalid code */ - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - - /* length code -- get extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - - /* get distance code */ - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - - /* get distance extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->wsize - (state->whave < state->wsize ? - left : 0)) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - - /* copy match from window to output */ - do { - ROOM(); - copy = state->wsize - state->offset; - if (copy < left) { - from = put + copy; - copy = left - copy; - } - else { - from = put - state->offset; - copy = left; - } - if (copy > state->length) copy = state->length; - state->length -= copy; - left -= copy; - do { - *put++ = *from++; - } while (--copy); - } while (state->length != 0); - break; - - case DONE: - /* inflate stream terminated properly */ - ret = Z_STREAM_END; - goto inf_leave; - - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - - default: - /* can't happen, but makes compilers happy */ - ret = Z_STREAM_ERROR; - goto inf_leave; - } - - /* Write leftover output and return unused input */ - inf_leave: - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left) && - ret == Z_STREAM_END) - ret = Z_BUF_ERROR; - } - strm->next_in = next; - strm->avail_in = have; - return ret; -} - -int ZEXPORT inflateBackEnd(z_streamp strm) { - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} diff --git a/ext/zlib/inffast.c b/ext/zlib/inffast.c deleted file mode 100644 index 9354676e78..0000000000 --- a/ext/zlib/inffast.c +++ /dev/null @@ -1,320 +0,0 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2017 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef ASMINF -# pragma message("Assembler code may have bugs -- use at your own risk") -#else - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) { - struct inflate_state FAR *state; - z_const unsigned char FAR *in; /* local strm->next_in */ - z_const unsigned char FAR *last; /* have enough input while in < last */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ -#ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ -#endif - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code const *here; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in; - last = in + (strm->avail_in - 5); - out = strm->next_out; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); -#ifdef INFLATE_STRICT - dmax = state->dmax; -#endif - wsize = state->wsize; - whave = state->whave; - wnext = state->wnext; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - here = lcode + (hold & lmask); - dolen: - op = (unsigned)(here->bits); - hold >>= op; - bits -= op; - op = (unsigned)(here->op); - if (op == 0) { /* literal */ - Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here->val)); - *out++ = (unsigned char)(here->val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(here->val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - here = dcode + (hold & dmask); - dodist: - op = (unsigned)(here->bits); - hold >>= op; - bits -= op; - op = (unsigned)(here->op); - if (op & 16) { /* distance base */ - dist = (unsigned)(here->val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); -#ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state->sane) { - strm->msg = - (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - if (len <= op - whave) { - do { - *out++ = 0; - } while (--len); - continue; - } - len -= op - whave; - do { - *out++ = 0; - } while (--op > whave); - if (op == 0) { - from = out - dist; - do { - *out++ = *from++; - } while (--len); - continue; - } -#endif - } - from = window; - if (wnext == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = window; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; - len -= 3; - } - if (len) { - *out++ = *from++; - if (len > 1) - *out++ = *from++; - } - } - else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; - len -= 3; - } while (len > 2); - if (len) { - *out++ = *from++; - if (len > 1) - *out++ = *from++; - } - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ - here = dcode + here->val + (hold & ((1U << op) - 1)); - goto dodist; - } - else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } - else if ((op & 64) == 0) { /* 2nd level length code */ - here = lcode + here->val + (hold & ((1U << op) - 1)); - goto dolen; - } - else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in; - strm->next_out = out; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and wnext == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ - -#endif /* !ASMINF */ diff --git a/ext/zlib/inffast.h b/ext/zlib/inffast.h deleted file mode 100644 index 49c6d156c5..0000000000 --- a/ext/zlib/inffast.h +++ /dev/null @@ -1,11 +0,0 @@ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start); diff --git a/ext/zlib/inffixed.h b/ext/zlib/inffixed.h deleted file mode 100644 index d628327769..0000000000 --- a/ext/zlib/inffixed.h +++ /dev/null @@ -1,94 +0,0 @@ - /* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - - /* WARNING: this file should *not* be used by applications. - It is part of the implementation of this library and is - subject to change. Applications should only use zlib.h. - */ - - static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} - }; - - static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} - }; diff --git a/ext/zlib/inflate.c b/ext/zlib/inflate.c deleted file mode 100644 index 94ecff015a..0000000000 --- a/ext/zlib/inflate.c +++ /dev/null @@ -1,1526 +0,0 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2022 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common wnext == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - -local int inflateStateCheck(z_streamp strm) { - struct inflate_state FAR *state; - if (strm == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) - return 1; - state = (struct inflate_state FAR *)strm->state; - if (state == Z_NULL || state->strm != strm || - state->mode < HEAD || state->mode > SYNC) - return 1; - return 0; -} - -int ZEXPORT inflateResetKeep(z_streamp strm) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - if (state->wrap) /* to support ill-conceived Java test suite */ - strm->adler = state->wrap & 1; - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->flags = -1; - state->dmax = 32768U; - state->head = Z_NULL; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - state->sane = 1; - state->back = -1; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflateReset(z_streamp strm) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->wsize = 0; - state->whave = 0; - state->wnext = 0; - return inflateResetKeep(strm); -} - -int ZEXPORT inflateReset2(z_streamp strm, int windowBits) { - int wrap; - struct inflate_state FAR *state; - - /* get the state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - if (windowBits < -15) - return Z_STREAM_ERROR; - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 5; -#ifdef GUNZIP - if (windowBits < 48) - windowBits &= 15; -#endif - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) - return Z_STREAM_ERROR; - if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { - ZFREE(strm, state->window); - state->window = Z_NULL; - } - - /* update state and reset the rest of it */ - state->wrap = wrap; - state->wbits = (unsigned)windowBits; - return inflateReset(strm); -} - -int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, - const char *version, int stream_size) { - int ret; - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->strm = strm; - state->window = Z_NULL; - state->mode = HEAD; /* to pass state test in inflateReset2() */ - ret = inflateReset2(strm, windowBits); - if (ret != Z_OK) { - ZFREE(strm, state); - strm->state = Z_NULL; - } - return ret; -} - -int ZEXPORT inflateInit_(z_streamp strm, const char *version, - int stream_size) { - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - if (bits == 0) - return Z_OK; - state = (struct inflate_state FAR *)strm->state; - if (bits < 0) { - state->hold = 0; - state->bits = 0; - return Z_OK; - } - if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += (unsigned)value << state->bits; - state->bits += (uInt)bits; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(struct inflate_state FAR *state) { -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed(void) -{ - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, - state.lencode[low].bits, state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) { - struct inflate_state FAR *state; - unsigned dist; - - state = (struct inflate_state FAR *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->wnext = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state->wsize) { - zmemcpy(state->window, end - state->wsize, state->wsize); - state->wnext = 0; - state->whave = state->wsize; - } - else { - dist = state->wsize - state->wnext; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, end - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, end - copy, copy); - state->wnext = copy; - state->whave = state->wsize; - } - else { - state->wnext += dist; - if (state->wnext == state->wsize) state->wnext = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE_CHECK(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE_CHECK(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate(z_streamp strm, int flush) { - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (inflateStateCheck(strm) || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - if (state->wbits == 0) - state->wbits = 15; - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (state->wbits == 0) - state->wbits = len; - if (len > 15 || len > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - state->flags = 0; /* indicate zlib header */ - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - /* fallthrough */ - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - /* fallthrough */ - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - /* fallthrough */ - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->head != Z_NULL) - state->head->extra_len = (unsigned)hold; - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - } - else if (state->head != Z_NULL) - state->head->extra = Z_NULL; - state->mode = EXTRA; - /* fallthrough */ - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL && - (len = state->head->extra_len - state->length) < - state->head->extra_max) { - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->length = 0; - state->mode = NAME; - /* fallthrough */ - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->name != Z_NULL && - state->length < state->head->name_max) - state->head->name[state->length++] = (Bytef)len; - } while (len && copy < have); - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->name = Z_NULL; - state->length = 0; - state->mode = COMMENT; - /* fallthrough */ - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->comment != Z_NULL && - state->length < state->head->comm_max) - state->head->comment[state->length++] = (Bytef)len; - } while (len && copy < have); - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->comment = Z_NULL; - state->mode = HCRC; - /* fallthrough */ - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if ((state->wrap & 4) && hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = ZSWAP32(hold); - INITBITS(); - state->mode = DICT; - /* fallthrough */ - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - /* fallthrough */ - case TYPE: - if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; - /* fallthrough */ - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN_; /* decode codes */ - if (flush == Z_TREES) { - DROPBITS(2); - goto inf_leave; - } - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY_; - if (flush == Z_TREES) goto inf_leave; - /* fallthrough */ - case COPY_: - state->mode = COPY; - /* fallthrough */ - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - /* fallthrough */ - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (const code FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - /* fallthrough */ - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (const code FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (const code FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN_; - if (flush == Z_TREES) goto inf_leave; - /* fallthrough */ - case LEN_: - state->mode = LEN; - /* fallthrough */ - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - if (state->mode == TYPE) - state->back = -1; - break; - } - state->back = 0; - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - state->length = (unsigned)here.val; - if ((int)(here.op) == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - state->mode = LIT; - break; - } - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->back = -1; - state->mode = TYPE; - break; - } - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(here.op) & 15; - state->mode = LENEXT; - /* fallthrough */ - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->was = state->length; - state->mode = DIST; - /* fallthrough */ - case DIST: - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - state->extra = (unsigned)(here.op) & 15; - state->mode = DISTEXT; - /* fallthrough */ - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } -#ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - /* fallthrough */ - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->whave) { - if (state->sane) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - Trace((stderr, "inflate.c too far\n")); - copy -= state->whave; - if (copy > state->length) copy = state->length; - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = 0; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; -#endif - } - if (copy > state->wnext) { - copy -= state->wnext; - from = state->window + (state->wsize - copy); - } - else - from = state->window + (state->wnext - copy); - if (copy > state->length) copy = state->length; - } - else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if ((state->wrap & 4) && out) - strm->adler = state->check = - UPDATE_CHECK(state->check, put - out, out); - out = left; - if ((state->wrap & 4) && ( -#ifdef GUNZIP - state->flags ? hold : -#endif - ZSWAP32(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - /* fallthrough */ - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - /* fallthrough */ - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - /* fallthrough */ - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - inf_leave: - RESTORE(); - if (state->wsize || (out != strm->avail_out && state->mode < BAD && - (state->mode < CHECK || flush != Z_FINISH))) - if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if ((state->wrap & 4) && out) - strm->adler = state->check = - UPDATE_CHECK(state->check, strm->next_out - out, out); - strm->data_type = (int)state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0) + - (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd(z_streamp strm) { - struct inflate_state FAR *state; - if (inflateStateCheck(strm)) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary, - uInt *dictLength) { - struct inflate_state FAR *state; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* copy dictionary */ - if (state->whave && dictionary != Z_NULL) { - zmemcpy(dictionary, state->window + state->wnext, - state->whave - state->wnext); - zmemcpy(dictionary + state->whave - state->wnext, - state->window, state->wnext); - } - if (dictLength != Z_NULL) - *dictLength = state->whave; - return Z_OK; -} - -int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary, - uInt dictLength) { - struct inflate_state FAR *state; - unsigned long dictid; - int ret; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; - - /* check for correct dictionary identifier */ - if (state->mode == DICT) { - dictid = adler32(0L, Z_NULL, 0); - dictid = adler32(dictid, dictionary, dictLength); - if (dictid != state->check) - return Z_DATA_ERROR; - } - - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - ret = updatewindow(strm, dictionary + dictLength, dictLength); - if (ret) { - state->mode = MEM; - return Z_MEM_ERROR; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) { - struct inflate_state FAR *state; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; - - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf, - unsigned len) { - unsigned got; - unsigned next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync(z_streamp strm) { - unsigned len; /* number of bytes to look at or looked at */ - int flags; /* temporary to save header status */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; - - /* check parameters */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold >>= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - if (state->flags == -1) - state->wrap = 0; /* if no header yet, treat as raw */ - else - state->wrap &= ~4; /* no point in computing a check value now */ - flags = state->flags; - in = strm->total_in; out = strm->total_out; - inflateReset(strm); - strm->total_in = in; strm->total_out = out; - state->flags = flags; - state->mode = TYPE; - return Z_OK; -} - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint(z_streamp strm) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - unsigned wsize; - - /* check input */ - if (inflateStateCheck(source) || dest == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; - - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); - copy->strm = dest; - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - zmemcpy(window, state->window, wsize); - } - copy->window = window; - dest->state = (struct internal_state FAR *)copy; - return Z_OK; -} - -int ZEXPORT inflateUndermine(z_streamp strm, int subvert) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - state->sane = !subvert; - return Z_OK; -#else - (void)subvert; - state->sane = 1; - return Z_DATA_ERROR; -#endif -} - -int ZEXPORT inflateValidate(z_streamp strm, int check) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (check && state->wrap) - state->wrap |= 4; - else - state->wrap &= ~4; - return Z_OK; -} - -long ZEXPORT inflateMark(z_streamp strm) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) - return -(1L << 16); - state = (struct inflate_state FAR *)strm->state; - return (long)(((unsigned long)((long)state->back)) << 16) + - (state->mode == COPY ? state->length : - (state->mode == MATCH ? state->was - state->length : 0)); -} - -unsigned long ZEXPORT inflateCodesUsed(z_streamp strm) { - struct inflate_state FAR *state; - if (inflateStateCheck(strm)) return (unsigned long)-1; - state = (struct inflate_state FAR *)strm->state; - return (unsigned long)(state->next - state->codes); -} diff --git a/ext/zlib/inflate.h b/ext/zlib/inflate.h deleted file mode 100644 index f127b6b1fa..0000000000 --- a/ext/zlib/inflate.h +++ /dev/null @@ -1,126 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2019 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD = 16180, /* i: waiting for magic header */ - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY_, /* i/o: same as COPY below, but only first time in */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN_, /* i: same as LEN below, but only first time in */ - LEN, /* i: waiting for length/lit/eob code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ - LENGTH, /* i: waiting for 32-bit length (gzip) */ - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to BAD or MEM on error -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) or (raw) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> - HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - (raw) -> TYPEDO - Read deflate blocks: - TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK - STORED -> COPY_ -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN_ - LEN_ -> LEN - Read deflate codes in fixed or dynamic block: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* State maintained between inflate() calls -- approximately 7K bytes, not - including the allocated sliding window, which is up to 32K bytes. */ -struct inflate_state { - z_streamp strm; /* pointer back to this zlib stream */ - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip, - bit 2 true to validate check value */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags, 0 if zlib, or - -1 if raw or no header yet */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ - int sane; /* if false, allow invalid distance too far */ - int back; /* bits back of last unprocessed length/lit */ - unsigned was; /* initial length of match */ -}; diff --git a/ext/zlib/inftrees.c b/ext/zlib/inftrees.c deleted file mode 100644 index 98cfe16445..0000000000 --- a/ext/zlib/inftrees.c +++ /dev/null @@ -1,299 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2024 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" - -#define MAXBITS 15 - -const char inflate_copyright[] = - " inflate 1.3.1 Copyright 1995-2024 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work) { - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code here; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - unsigned match; /* use base and extra for symbol >= match */ - unsigned short count[MAXBITS+1]; /* number of codes of each length */ - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 77}; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0}; - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)1; - here.val = (unsigned short)0; - *(*table)++ = here; /* make a table to force an error */ - *(*table)++ = here; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - match = 20; - break; - case LENS: - base = lbase; - extra = lext; - match = 257; - break; - default: /* DISTS */ - base = dbase; - extra = dext; - match = 0; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here.bits = (unsigned char)(len - drop); - if (work[sym] + 1U < match) { - here.op = (unsigned char)0; - here.val = work[sym]; - } - else if (work[sym] >= match) { - here.op = (unsigned char)(extra[work[sym] - match]); - here.val = base[work[sym] - match]; - } - else { - here.op = (unsigned char)(32 + 64); /* end of block */ - here.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = here; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff != 0) { - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)(len - drop); - here.val = (unsigned short)0; - next[huff] = here; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} diff --git a/ext/zlib/inftrees.h b/ext/zlib/inftrees.h deleted file mode 100644 index 396f74b5da..0000000000 --- a/ext/zlib/inftrees.h +++ /dev/null @@ -1,62 +0,0 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of the dynamic table. The maximum number of code structures is - 1444, which is the sum of 852 for literal/length codes and 592 for distance - codes. These values were found by exhaustive searches using the program - examples/enough.c found in the zlib distribution. The arguments to that - program are the number of symbols, the initial root table size, and the - maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns 852, and "enough 30 6 15" for distance codes returns 592. The - initial root table size (9 or 6) is found in the fifth argument of the - inflate_table() calls in inflate.c and infback.c. If the root table size is - changed, then these maximum sizes would be need to be recalculated and - updated. */ -#define ENOUGH_LENS 852 -#define ENOUGH_DISTS 592 -#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) - -/* Type of code to build for inflate_table() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work); diff --git a/ext/zlib/trees.c b/ext/zlib/trees.c deleted file mode 100644 index 6a523ef34e..0000000000 --- a/ext/zlib/trees.c +++ /dev/null @@ -1,1117 +0,0 @@ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2024 Jean-loup Gailly - * detect_data_type() function provided freely by Cosmin Truta, 2006 - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* @(#) $Id$ */ - -/* #define GEN_TREES_H */ - -#include "deflate.h" - -#ifdef ZLIB_DEBUG -# include -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local const uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) || !defined(STDC) -/* non ANSI compilers may not accept trees.h */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ - -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -#ifdef NO_INIT_GLOBAL_POINTERS -# define TCONST -#else -# define TCONST const -#endif - -local TCONST static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local TCONST static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local TCONST static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(unsigned code, int len) { - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(deflate_state *s) { - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(deflate_state *s) { - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef ZLIB_DEBUG - s->bits_sent = (s->bits_sent + 7) & ~7; -#endif -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes(ct_data *tree, int max_code, ushf *bl_count) { - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - unsigned code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - code = (code + bl_count[bits - 1]) << 1; - next_code[bits] = (ush)code; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, - "inconsistent bit counts"); - Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); - - for (n = 0; n <= max_code; n++) { - int len = tree[n].Len; - if (len == 0) continue; - /* Now reverse the bits */ - tree[n].Code = (ush)bi_reverse(next_code[len]++, len); - - Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", - n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); - } -} - -#ifdef GEN_TREES_H -local void gen_trees_header(void); -#endif - -#ifndef ZLIB_DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* !ZLIB_DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef ZLIB_DEBUG -local void send_bits(deflate_state *s, int value, int length) { - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16 - bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (ush)value << s->bi_valid; - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= (ush)value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !ZLIB_DEBUG */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = (int)value;\ - s->bi_buf |= (ush)val << s->bi_valid;\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (ush)(value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* ZLIB_DEBUG */ - - -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init(void) { -#if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ -#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; -#endif - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1 << extra_lbits[code]); n++) { - _length_code[length++] = (uch)code; - } - } - Assert (length == 256, "tr_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - _length_code[length - 1] = (uch)code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1 << extra_dbits[code]); n++) { - _dist_code[dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256 + dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -} - -/* =========================================================================== - * Generate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef ZLIB_DEBUG -# include -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width) - 1 ? ",\n" : ", ")) - -void gen_trees_header(void) { - FILE *header = fopen("trees.h", "w"); - int i; - - Assert (header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, - "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES-1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(deflate_state *s) { - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->sym_next = s->matches = 0; -} - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void ZLIB_INTERNAL _tr_init(deflate_state *s) { - tr_static_init(); - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef ZLIB_DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(deflate_state *s, ct_data *tree, int k) { - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j + 1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(deflate_state *s, tree_desc *desc) { - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max + 1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n - base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (unsigned)(bits + xbits); - if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits); - } - if (overflow == 0) return; - - Tracev((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length - 1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits + 1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if ((unsigned) tree[m].Len != (unsigned) bits) { - Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -#ifdef DUMP_BL_TREE -# include -#endif - -/* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ -local void build_tree(deflate_state *s, tree_desc *desc) { - ct_data *tree = desc->dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n + 1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2 + 1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree(deflate_state *s, ct_data *tree, int max_code) { - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code + 1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n + 1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree(deflate_state *s, ct_data *tree, int max_code) { - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code + 1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n + 1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count - 3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count - 3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count - 11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(deflate_state *s) { - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except the - * lengths of the bit lengths codes and the 5 + 5 + 4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*((ulg)max_blindex + 1) + 5 + 5 + 4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(deflate_state *s, int lcodes, int dcodes, - int blcodes) { - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes - 1, 5); - send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, - ulg stored_len, int last) { - send_bits(s, (STORED_BLOCK<<1) + last, 3); /* send block type */ - bi_windup(s); /* align on byte boundary */ - put_short(s, (ush)stored_len); - put_short(s, (ush)~stored_len); - if (stored_len) - zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); - s->pending += stored_len; -#ifdef ZLIB_DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; - s->bits_sent += 2*16; - s->bits_sent += stored_len << 3; -#endif -} - -/* =========================================================================== - * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) - */ -void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s) { - bi_flush(s); -} - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - */ -void ZLIB_INTERNAL _tr_align(deflate_state *s) { - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef ZLIB_DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -#endif - bi_flush(s); -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(deflate_state *s, const ct_data *ltree, - const ct_data *dtree) { - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned sx = 0; /* running index in symbol buffers */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->sym_next != 0) do { -#ifdef LIT_MEM - dist = s->d_buf[sx]; - lc = s->l_buf[sx++]; -#else - dist = s->sym_buf[sx++] & 0xff; - dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; - lc = s->sym_buf[sx++]; -#endif - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code + LITERALS + 1, ltree); /* send length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= (unsigned)base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check for no overlay of pending_buf on needed symbols */ -#ifdef LIT_MEM - Assert(s->pending < 2 * (s->lit_bufsize + sx), "pendingBuf overflow"); -#else - Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); -#endif - - } while (sx < s->sym_next); - - send_code(s, END_BLOCK, ltree); -} - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "block list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local int detect_data_type(deflate_state *s) { - /* block_mask is the bit mask of block-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - unsigned long block_mask = 0xf3ffc07fUL; - int n; - - /* Check for non-textual ("block-listed") bytes. */ - for (n = 0; n <= 31; n++, block_mask >>= 1) - if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0)) - return Z_BINARY; - - /* Check for textual ("allow-listed") bytes. */ - if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 - || s->dyn_ltree[13].Freq != 0) - return Z_TEXT; - for (n = 32; n < LITERALS; n++) - if (s->dyn_ltree[n].Freq != 0) - return Z_TEXT; - - /* There are no "block-listed" or "allow-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and write out the encoded block. - */ -void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, - ulg stored_len, int last) { - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is binary or text */ - if (s->strm->data_type == Z_UNKNOWN) - s->strm->data_type = detect_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len + 3 + 7) >> 3; - static_lenb = (s->static_len + 3 + 7) >> 3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->sym_next / 3)); - -#ifndef FORCE_STATIC - if (static_lenb <= opt_lenb || s->strategy == Z_FIXED) -#endif - opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len + 4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, last); - - } else if (static_lenb == opt_lenb) { - send_bits(s, (STATIC_TREES<<1) + last, 3); - compress_block(s, (const ct_data *)static_ltree, - (const ct_data *)static_dtree); -#ifdef ZLIB_DEBUG - s->compressed_len += 3 + s->static_len; -#endif - } else { - send_bits(s, (DYN_TREES<<1) + last, 3); - send_all_trees(s, s->l_desc.max_code + 1, s->d_desc.max_code + 1, - max_blindex + 1); - compress_block(s, (const ct_data *)s->dyn_ltree, - (const ct_data *)s->dyn_dtree); -#ifdef ZLIB_DEBUG - s->compressed_len += 3 + s->opt_len; -#endif - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (last) { - bi_windup(s); -#ifdef ZLIB_DEBUG - s->compressed_len += 7; /* align on byte boundary */ -#endif - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len >> 3, - s->compressed_len - 7*last)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) { -#ifdef LIT_MEM - s->d_buf[s->sym_next] = (ush)dist; - s->l_buf[s->sym_next++] = (uch)lc; -#else - s->sym_buf[s->sym_next++] = (uch)dist; - s->sym_buf[s->sym_next++] = (uch)(dist >> 8); - s->sym_buf[s->sym_next++] = (uch)lc; -#endif - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[_length_code[lc] + LITERALS + 1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - return (s->sym_next == s->sym_end); -} diff --git a/ext/zlib/trees.h b/ext/zlib/trees.h deleted file mode 100644 index d35639d82a..0000000000 --- a/ext/zlib/trees.h +++ /dev/null @@ -1,128 +0,0 @@ -/* header created automatically with -DGEN_TREES_H */ - -local const ct_data static_ltree[L_CODES+2] = { -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} -}; - -local const ct_data static_dtree[D_CODES] = { -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} -}; - -const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; - -const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; - -local const int base_length[LENGTH_CODES] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -64, 80, 96, 112, 128, 160, 192, 224, 0 -}; - -local const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; - diff --git a/ext/zlib/uncompr.c b/ext/zlib/uncompr.c deleted file mode 100644 index 5e256663b4..0000000000 --- a/ext/zlib/uncompr.c +++ /dev/null @@ -1,85 +0,0 @@ -/* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Decompresses the source buffer into the destination buffer. *sourceLen is - the byte length of the source buffer. Upon entry, *destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, - *destLen is the size of the decompressed data and *sourceLen is the number - of source bytes consumed. Upon return, source + *sourceLen points to the - first unused input byte. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, or - Z_DATA_ERROR if the input data was corrupted, including if the input data is - an incomplete zlib stream. -*/ -int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong *sourceLen) { - z_stream stream; - int err; - const uInt max = (uInt)-1; - uLong len, left; - Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ - - len = *sourceLen; - if (*destLen) { - left = *destLen; - *destLen = 0; - } - else { - left = 1; - dest = buf; - } - - stream.next_in = (z_const Bytef *)source; - stream.avail_in = 0; - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = inflateInit(&stream); - if (err != Z_OK) return err; - - stream.next_out = dest; - stream.avail_out = 0; - - do { - if (stream.avail_out == 0) { - stream.avail_out = left > (uLong)max ? max : (uInt)left; - left -= stream.avail_out; - } - if (stream.avail_in == 0) { - stream.avail_in = len > (uLong)max ? max : (uInt)len; - len -= stream.avail_in; - } - err = inflate(&stream, Z_NO_FLUSH); - } while (err == Z_OK); - - *sourceLen -= len + stream.avail_in; - if (dest != buf) - *destLen = stream.total_out; - else if (stream.total_out && err == Z_BUF_ERROR) - left = 1; - - inflateEnd(&stream); - return err == Z_STREAM_END ? Z_OK : - err == Z_NEED_DICT ? Z_DATA_ERROR : - err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : - err; -} - -int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong sourceLen) { - return uncompress2(dest, destLen, source, &sourceLen); -} diff --git a/ext/zlib/zconf.h b/ext/zlib/zconf.h deleted file mode 100644 index 62adc8d843..0000000000 --- a/ext/zlib/zconf.h +++ /dev/null @@ -1,543 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - * Even better than compiling with -DZ_PREFIX would be to use configure to set - * this permanently in zconf.h using "./configure --zprefix". - */ -#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ -# define Z_PREFIX_SET - -/* all linked symbols and init macros */ -# define _dist_code z__dist_code -# define _length_code z__length_code -# define _tr_align z__tr_align -# define _tr_flush_bits z__tr_flush_bits -# define _tr_flush_block z__tr_flush_block -# define _tr_init z__tr_init -# define _tr_stored_block z__tr_stored_block -# define _tr_tally z__tr_tally -# define adler32 z_adler32 -# define adler32_combine z_adler32_combine -# define adler32_combine64 z_adler32_combine64 -# define adler32_z z_adler32_z -# ifndef Z_SOLO -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# endif -# define crc32 z_crc32 -# define crc32_combine z_crc32_combine -# define crc32_combine64 z_crc32_combine64 -# define crc32_combine_gen z_crc32_combine_gen -# define crc32_combine_gen64 z_crc32_combine_gen64 -# define crc32_combine_op z_crc32_combine_op -# define crc32_z z_crc32_z -# define deflate z_deflate -# define deflateBound z_deflateBound -# define deflateCopy z_deflateCopy -# define deflateEnd z_deflateEnd -# define deflateGetDictionary z_deflateGetDictionary -# define deflateInit z_deflateInit -# define deflateInit2 z_deflateInit2 -# define deflateInit2_ z_deflateInit2_ -# define deflateInit_ z_deflateInit_ -# define deflateParams z_deflateParams -# define deflatePending z_deflatePending -# define deflatePrime z_deflatePrime -# define deflateReset z_deflateReset -# define deflateResetKeep z_deflateResetKeep -# define deflateSetDictionary z_deflateSetDictionary -# define deflateSetHeader z_deflateSetHeader -# define deflateTune z_deflateTune -# define deflate_copyright z_deflate_copyright -# define get_crc_table z_get_crc_table -# ifndef Z_SOLO -# define gz_error z_gz_error -# define gz_intmax z_gz_intmax -# define gz_strwinerror z_gz_strwinerror -# define gzbuffer z_gzbuffer -# define gzclearerr z_gzclearerr -# define gzclose z_gzclose -# define gzclose_r z_gzclose_r -# define gzclose_w z_gzclose_w -# define gzdirect z_gzdirect -# define gzdopen z_gzdopen -# define gzeof z_gzeof -# define gzerror z_gzerror -# define gzflush z_gzflush -# define gzfread z_gzfread -# define gzfwrite z_gzfwrite -# define gzgetc z_gzgetc -# define gzgetc_ z_gzgetc_ -# define gzgets z_gzgets -# define gzoffset z_gzoffset -# define gzoffset64 z_gzoffset64 -# define gzopen z_gzopen -# define gzopen64 z_gzopen64 -# ifdef _WIN32 -# define gzopen_w z_gzopen_w -# endif -# define gzprintf z_gzprintf -# define gzputc z_gzputc -# define gzputs z_gzputs -# define gzread z_gzread -# define gzrewind z_gzrewind -# define gzseek z_gzseek -# define gzseek64 z_gzseek64 -# define gzsetparams z_gzsetparams -# define gztell z_gztell -# define gztell64 z_gztell64 -# define gzungetc z_gzungetc -# define gzvprintf z_gzvprintf -# define gzwrite z_gzwrite -# endif -# define inflate z_inflate -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define inflateBackInit z_inflateBackInit -# define inflateBackInit_ z_inflateBackInit_ -# define inflateCodesUsed z_inflateCodesUsed -# define inflateCopy z_inflateCopy -# define inflateEnd z_inflateEnd -# define inflateGetDictionary z_inflateGetDictionary -# define inflateGetHeader z_inflateGetHeader -# define inflateInit z_inflateInit -# define inflateInit2 z_inflateInit2 -# define inflateInit2_ z_inflateInit2_ -# define inflateInit_ z_inflateInit_ -# define inflateMark z_inflateMark -# define inflatePrime z_inflatePrime -# define inflateReset z_inflateReset -# define inflateReset2 z_inflateReset2 -# define inflateResetKeep z_inflateResetKeep -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateUndermine z_inflateUndermine -# define inflateValidate z_inflateValidate -# define inflate_copyright z_inflate_copyright -# define inflate_fast z_inflate_fast -# define inflate_table z_inflate_table -# ifndef Z_SOLO -# define uncompress z_uncompress -# define uncompress2 z_uncompress2 -# endif -# define zError z_zError -# ifndef Z_SOLO -# define zcalloc z_zcalloc -# define zcfree z_zcfree -# endif -# define zlibCompileFlags z_zlibCompileFlags -# define zlibVersion z_zlibVersion - -/* all zlib typedefs in zlib.h and zconf.h */ -# define Byte z_Byte -# define Bytef z_Bytef -# define alloc_func z_alloc_func -# define charf z_charf -# define free_func z_free_func -# ifndef Z_SOLO -# define gzFile z_gzFile -# endif -# define gz_header z_gz_header -# define gz_headerp z_gz_headerp -# define in_func z_in_func -# define intf z_intf -# define out_func z_out_func -# define uInt z_uInt -# define uIntf z_uIntf -# define uLong z_uLong -# define uLongf z_uLongf -# define voidp z_voidp -# define voidpc z_voidpc -# define voidpf z_voidpf - -/* all zlib structs in zlib.h and zconf.h */ -# define gz_header_s z_gz_header_s -# define internal_state z_internal_state - -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -#if defined(ZLIB_CONST) && !defined(z_const) -# define z_const const -#else -# define z_const -#endif - -#ifdef Z_SOLO -# ifdef _WIN64 - typedef unsigned long long z_size_t; -# else - typedef unsigned long z_size_t; -# endif -#else -# define z_longlong long long -# if defined(NO_SIZE_T) - typedef unsigned NO_SIZE_T z_size_t; -# elif defined(STDC) -# include - typedef size_t z_size_t; -# else - typedef unsigned long z_size_t; -# endif -# undef z_longlong -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus about 7 kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) -# include -# if (UINT_MAX == 0xffffffffUL) -# define Z_U4 unsigned -# elif (ULONG_MAX == 0xffffffffUL) -# define Z_U4 unsigned long -# elif (USHRT_MAX == 0xffffffffUL) -# define Z_U4 unsigned short -# endif -#endif - -#ifdef Z_U4 - typedef Z_U4 z_crc_t; -#else - typedef unsigned long z_crc_t; -#endif - -#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_UNISTD_H -#endif - -#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_STDARG_H -#endif - -#ifdef STDC -# ifndef Z_SOLO -# include /* for off_t */ -# endif -#endif - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -# include /* for va_list */ -# endif -#endif - -#ifdef _WIN32 -# ifndef Z_SOLO -# include /* for wchar_t */ -# endif -#endif - -/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and - * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even - * though the former does not conform to the LFS document), but considering - * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as - * equivalently requesting no 64-bit operations - */ -#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE -#endif - -#ifndef Z_HAVE_UNISTD_H -# ifdef __WATCOMC__ -# define Z_HAVE_UNISTD_H -# endif -#endif -#ifndef Z_HAVE_UNISTD_H -# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32) -# define Z_HAVE_UNISTD_H -# endif -#endif -#ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) -# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ -# ifdef VMS -# include /* for off_t */ -# endif -# ifndef z_off_t -# define z_off_t off_t -# endif -# endif -#endif - -#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 -# define Z_LFS64 -#endif - -#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) -# define Z_LARGE64 -#endif - -#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) -# define Z_WANT64 -#endif - -#if !defined(SEEK_SET) && !defined(Z_SOLO) -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#ifndef z_off_t -# define z_off_t long -#endif - -#if !defined(_WIN32) && defined(Z_LARGE64) -# define z_off64_t off64_t -#else -# if defined(_WIN32) && !defined(__GNUC__) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) - #pragma map(deflateInit_,"DEIN") - #pragma map(deflateInit2_,"DEIN2") - #pragma map(deflateEnd,"DEEND") - #pragma map(deflateBound,"DEBND") - #pragma map(inflateInit_,"ININ") - #pragma map(inflateInit2_,"ININ2") - #pragma map(inflateEnd,"INEND") - #pragma map(inflateSync,"INSY") - #pragma map(inflateSetDictionary,"INSEDI") - #pragma map(compressBound,"CMBND") - #pragma map(inflate_table,"INTABL") - #pragma map(inflate_fast,"INFA") - #pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/ext/zlib/zlib.h b/ext/zlib/zlib.h deleted file mode 100644 index 8d4b932eaf..0000000000 --- a/ext/zlib/zlib.h +++ /dev/null @@ -1,1938 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.3.1, January 22nd, 2024 - - Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 - (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.3.1" -#define ZLIB_VERNUM 0x1310 -#define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 3 -#define ZLIB_VER_REVISION 1 -#define ZLIB_VER_SUBREVISION 0 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed data. - This version of the library supports only one compression method (deflation) - but other algorithms will be added later and will have the same stream - interface. - - Compression can be done in a single step if the buffers are large enough, - or can be done by repeated calls of the compression function. In the latter - case, the application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip and raw deflate streams in - memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never crash - even in the case of corrupted input. -*/ - -typedef voidpf (*alloc_func)(voidpf opaque, uInt items, uInt size); -typedef void (*free_func)(voidpf opaque, voidpf address); - -struct internal_state; - -typedef struct z_stream_s { - z_const Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total number of input bytes read so far */ - - Bytef *next_out; /* next output byte will go here */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total number of bytes output so far */ - - z_const char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text - for deflate, or the decoding state for inflate */ - uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has dropped - to zero. It must update next_out and avail_out when avail_out has dropped - to zero. The application must initialize zalloc, zfree and opaque before - calling the init function. All other fields are set by the compression - library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. In that case, zlib is thread-safe. When zalloc and zfree are - Z_NULL on entry to the initialization function, they are set to internal - routines that use the standard library functions malloc() and free(). - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this if - the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers - returned by zalloc for objects of exactly 65536 bytes *must* have their - offset normalized to zero. The default allocation function provided by this - library ensures this (see zutil.c). To reduce memory requirements and avoid - any allocation of 64K objects, at the expense of compression ratio, compile - the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or progress - reports. After compression, total_in holds the total size of the - uncompressed data and may be saved for use by the decompressor (particularly - if the decompressor wants to decompress everything in a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -#define Z_TREES 6 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field for deflate() */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion(void); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is not - compatible with the zlib.h header file used by the application. This check - is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit(z_streamp strm, int level); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. total_in, total_out, adler, and msg are initialized. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at all - (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION - requests a default compromise between speed and compression (currently - equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if level is not a valid compression level, or - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). msg is set to null - if there is no error message. deflateInit does not perform any compression: - this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate(z_streamp strm, int flush); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Generate more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary. Some output may be provided even if - flush is zero. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating avail_in or avail_out accordingly; avail_out should - never be zero before the call. The application can consume the compressed - output when it wants, for example when the output buffer is full (avail_out - == 0), or after each call of deflate(). If deflate returns Z_OK and with - zero avail_out, it must be called again after making room in the output - buffer because there might be more output pending. See deflatePending(), - which can be used if desired to determine whether or not there is more output - in that case. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumulate before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In - particular avail_in is zero after the call if enough output space has been - provided before the call.) Flushing may degrade compression for some - compression algorithms and so it should be used only when necessary. This - completes the current deflate block and follows it with an empty stored block - that is three bits plus filler bits to the next byte, followed by four bytes - (00 00 ff ff). - - If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the - output buffer, but the output is not aligned to a byte boundary. All of the - input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. - This completes the current deflate block and follows it with an empty fixed - codes block that is 10 bits long. This assures that enough bytes are output - in order for the decompressor to finish the block before the empty fixed - codes block. - - If flush is set to Z_BLOCK, a deflate block is completed and emitted, as - for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to - seven bits of the current block are held to be written as the next byte after - the next deflate block is completed. In this case, the decompressor may not - be provided enough bits at this point in order to complete decompression of - the data provided so far to the compressor. It may need to wait for the next - block to be emitted. This is for advanced applications that need to control - the emission of deflate blocks. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six when the flush marker begins, in order to avoid - repeated flush markers upon calling deflate() again when avail_out == 0. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there was - enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this - function must be called again with Z_FINISH and more output space (updated - avail_out) but no more input data, until it returns with Z_STREAM_END or an - error. After deflate has returned Z_STREAM_END, the only possible operations - on the stream are deflateReset or deflateEnd. - - Z_FINISH can be used in the first deflate call after deflateInit if all the - compression is to be done in a single step. In order to complete in one - call, avail_out must be at least the value returned by deflateBound (see - below). Then deflate is guaranteed to return Z_STREAM_END. If not enough - output space is provided, deflate will not return Z_STREAM_END, and it must - be called again as described above. - - deflate() sets strm->adler to the Adler-32 checksum of all input read - so far (that is, total_in bytes). If a gzip stream is being generated, then - strm->adler will be the CRC-32 checksum of the input read so far. (See - deflateInit2 below.) - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is - considered binary. This field is only for information purposes and does not - affect the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was Z_NULL or the state was inadvertently written over - by the application), or Z_BUF_ERROR if no progress is possible (for example - avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and - deflate() can be called again with more input and more output space to - continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd(z_streamp strm); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, msg - may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit(z_streamp strm); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. In the current version of inflate, the provided input is not - read or consumed. The allocation of a sliding window will be deferred to - the first call of inflate (if the decompression does not complete on the - first call). If zalloc and zfree are set to Z_NULL, inflateInit updates - them to use default allocation functions. total_in, total_out, adler, and - msg are initialized. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit does not perform any decompression. - Actual decompression will be done by inflate(). So next_in, and avail_in, - next_out, and avail_out are unused and unchanged. The current - implementation of inflateInit() does not process any header information -- - that is deferred until inflate() is called. -*/ - - -ZEXTERN int ZEXPORT inflate(z_streamp strm, int flush); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), then next_in and avail_in are updated - accordingly, and processing will resume at this point for the next call of - inflate(). - - - Generate more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there is - no more input data or no more space in the output buffer (see below about - the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating the next_* and avail_* values accordingly. If the - caller of inflate() does not provide both available input and available - output space, it is possible that there will be no progress made. The - application can consume the uncompressed output when it wants, for example - when the output buffer is full (avail_out == 0), or after each call of - inflate(). If inflate returns Z_OK and with zero avail_out, it must be - called again after making room in the output buffer because there might be - more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, - Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() - stop if and when it gets to the next deflate block boundary. When decoding - the zlib or gzip format, this will cause inflate() to return immediately - after the header and before the first block. When doing a raw inflate, - inflate() will go ahead and process the first block, and will return when it - gets to the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - To assist in this, on return inflate() always sets strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 if - inflate() is currently decoding the last block in the deflate stream, plus - 128 if inflate() returned immediately after decoding an end-of-block code or - decoding the complete header up to just before the first byte of the deflate - stream. The end-of-block will not be indicated until all of the uncompressed - data from that block has been written to strm->next_out. The number of - unused bits may in general be greater than seven, except when bit 7 of - data_type is set, in which case the number of unused bits will be less than - eight. data_type is set as noted here every time inflate() returns for all - flush options, and so can be used to determine the amount of currently - consumed input in bits. - - The Z_TREES option behaves as Z_BLOCK does, but it also returns when the - end of each deflate block header is reached, before any actual data in that - block is decoded. This allows the caller to determine the length of the - deflate block header for later use in random access within a deflate block. - 256 is added to the value of strm->data_type when inflate() returns - immediately after reaching the end of the deflate block header. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step (a - single call of inflate), the parameter flush should be set to Z_FINISH. In - this case all pending input is processed and all pending output is flushed; - avail_out must be large enough to hold all of the uncompressed data for the - operation to complete. (The size of the uncompressed data may have been - saved by the compressor for this purpose.) The use of Z_FINISH is not - required to perform an inflation in one step. However it may be used to - inform inflate that a faster approach can be used for the single inflate() - call. Z_FINISH also informs inflate to not maintain a sliding window if the - stream completes, which reduces inflate's memory footprint. If the stream - does not complete, either because not all of the stream is provided or not - enough output space is provided, then a sliding window will be allocated and - inflate() can be called again to continue the operation as if Z_NO_FLUSH had - been used. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the effects of the flush parameter in this implementation are - on the return value of inflate() as noted below, when inflate() returns early - when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of - memory for a sliding window when Z_FINISH is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the Adler-32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the Adler-32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed Adler-32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() can decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically, if requested when - initializing with inflateInit2(). Any information contained in the gzip - header is not retained unless inflateGetHeader() is used. When processing - gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output - produced so far. The CRC-32 is checked against the gzip trailer, as is the - uncompressed length, modulo 2^32. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value, in which case strm->msg points to a string with a more specific - error), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL, or the state was inadvertently written over - by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR - if no progress was possible or if there was not enough room in the output - buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may - then call inflateSync() to look for a good compression block if a partial - recovery of the data is to be attempted. -*/ - - -ZEXTERN int ZEXPORT inflateEnd(z_streamp strm); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state - was inconsistent. -*/ - - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2(z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy); - - This is another version of deflateInit with more compression options. The - fields zalloc, zfree and opaque must be initialized before by the caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - For the current implementation of deflate(), a windowBits value of 8 (a - window size of 256 bytes) is not supported. As a result, a request for 8 - will result in 9 (a 512-byte window). In that case, providing 8 to - inflateInit2() will result in an error when the zlib header with 9 is - checked against the initialization of inflate(). The remedy is to not use 8 - with deflateInit2() with this initialization, or at least in that case use 9 - with inflateInit2(). - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute a check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), no - header crc, and the operating system will be set to the appropriate value, - if the operating system was determined at compile time. If a gzip stream is - being written, strm->adler is a CRC-32 instead of an Adler-32. - - For raw deflate or gzip encoding, a request for a 256-byte window is - rejected as invalid, since only the zlib header provides a means of - transmitting the window size to the decompressor. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but is - slow and reduces compression ratio; memLevel=9 uses maximum memory for - optimal speed. The default value is 8. See zconf.h for total memory usage - as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as - fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The - strategy parameter only affects the compression ratio but not the - correctness of the compressed output even if it is not set appropriately. - Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler - decoder for special applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid - method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is - incompatible with the version assumed by the caller (ZLIB_VERSION). msg is - set to null if there is no error message. deflateInit2 does not perform any - compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary(z_streamp strm, - const Bytef *dictionary, - uInt dictLength); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. When using the zlib format, this - function must be called immediately after deflateInit, deflateInit2 or - deflateReset, and before any call of deflate. When doing raw deflate, this - function must be called either before any call of deflate, or immediately - after the completion of a deflate block, i.e. after all input has been - consumed and all output has been delivered when using any of the flush - options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The - compressor and decompressor must use exactly the same dictionary (see - inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size - provided in deflateInit or deflateInit2. Thus the strings most likely to be - useful should be put at the end of the dictionary, not at the front. In - addition, the current implementation of deflate will use at most the window - size minus 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the Adler-32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The Adler-32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - Adler-32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if not at a block boundary for raw deflate). deflateSetDictionary does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateGetDictionary(z_streamp strm, - Bytef *dictionary, - uInt *dictLength); -/* - Returns the sliding dictionary being maintained by deflate. dictLength is - set to the number of bytes in the dictionary, and that many bytes are copied - to dictionary. dictionary must have enough space, where 32768 bytes is - always enough. If deflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similarly, if dictLength is Z_NULL, then it is not set. - - deflateGetDictionary() may return a length less than the window size, even - when more than the window size in input has been provided. It may return up - to 258 bytes less in that case, due to how zlib's implementation of deflate - manages the sliding window and lookahead for matches, where matches can be - up to 258 bytes long. If the application needs the last window-size bytes of - input, then that would need to be saved by the application outside of zlib. - - deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateCopy(z_streamp dest, - z_streamp source); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and can - consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset(z_streamp strm); -/* - This function is equivalent to deflateEnd followed by deflateInit, but - does not free and reallocate the internal compression state. The stream - will leave the compression level and any other attributes that may have been - set unchanged. total_in, total_out, adler, and msg are initialized. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams(z_streamp strm, - int level, - int strategy); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2(). This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different strategy. - If the compression approach (which is a function of the level) or the - strategy is changed, and if there have been any deflate() calls since the - state was initialized or reset, then the input available so far is - compressed with the old level and strategy using deflate(strm, Z_BLOCK). - There are three approaches for the compression levels 0, 1..3, and 4..9 - respectively. The new level and strategy will take effect at the next call - of deflate(). - - If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does - not have enough output space to complete, then the parameter change will not - take effect. In this case, deflateParams() can be called again with the - same parameters and more output space to try again. - - In order to assure a change in the parameters on the first try, the - deflate stream should be flushed using deflate() with Z_BLOCK or other flush - request until strm.avail_out is not zero, before calling deflateParams(). - Then no more input data should be provided before the deflateParams() call. - If this is done, the old level and strategy will be applied to the data - compressed before deflateParams(), and the new level and strategy will be - applied to the data compressed after deflateParams(). - - deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream - state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if - there was not enough output space to complete the compression of the - available input data before a change in the strategy or approach. Note that - in the case of a Z_BUF_ERROR, the parameters are not changed. A return - value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be - retried with more output space. -*/ - -ZEXTERN int ZEXPORT deflateTune(z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm, - uLong sourceLen); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() or - deflateInit2(), and after deflateSetHeader(), if used. This would be used - to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). If that first deflate() call is provided the - sourceLen input bytes, an output buffer allocated to the size returned by - deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed - to return Z_STREAM_END. Note that it is possible for the compressed size to - be larger than the value returned by deflateBound() if flush options other - than Z_FINISH or Z_NO_FLUSH are used. -*/ - -ZEXTERN int ZEXPORT deflatePending(z_streamp strm, - unsigned *pending, - int *bits); -/* - deflatePending() returns the number of bytes and bits of output that have - been generated, but not yet provided in the available output. The bytes not - provided would be due to the available output space having being consumed. - The number of bits of output not provided are between 0 and 7, where they - await more bits to join them in order to fill out a full byte. If pending - or bits are Z_NULL, then those values are not set. - - deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. - */ - -ZEXTERN int ZEXPORT deflatePrime(z_streamp strm, - int bits, - int value); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the bits - leftover from a previous deflate stream when appending to it. As such, this - function can only be used for raw deflate, and must be used before the first - deflate() call after a deflateInit2() or deflateReset(). bits must be less - than or equal to 16, and that many of the least significant bits of value - will be inserted in the output. - - deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough - room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader(z_streamp strm, - gz_headerp head); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to the current operating system, with no - extra, name, or comment fields. The gzip header is returned to the default - state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2(z_streamp strm, - int windowBits); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be zero to request that inflate use the window size in - the zlib header of the compressed stream. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an Adler-32 or a CRC-32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a - CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see - below), inflate() will *not* automatically decode concatenated gzip members. - inflate() will return Z_STREAM_END at the end of the gzip member. The state - would need to be reset to continue decoding a subsequent gzip member. This - *must* be done if there is more data after a gzip member, in order for the - decompression to be compliant with the gzip standard (RFC 1952). - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit2 does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit2() does not process any header information -- that is - deferred until inflate() is called. -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary(z_streamp strm, - const Bytef *dictionary, - uInt dictLength); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the Adler-32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called at any - time to set the dictionary. If the provided dictionary is smaller than the - window and there is already data in the window, then the provided dictionary - will amend what's there. The application must insure that the dictionary - that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect Adler-32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateGetDictionary(z_streamp strm, - Bytef *dictionary, - uInt *dictLength); -/* - Returns the sliding dictionary being maintained by inflate. dictLength is - set to the number of bytes in the dictionary, and that many bytes are copied - to dictionary. dictionary must have enough space, where 32768 bytes is - always enough. If inflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similarly, if dictLength is Z_NULL, then it is not set. - - inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateSync(z_streamp strm); -/* - Skips invalid compressed data until a possible full flush point (see above - for the description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync searches for a 00 00 FF FF pattern in the compressed data. - All full flush points have this pattern, but not all occurrences of this - pattern are full flush points. - - inflateSync returns Z_OK if a possible full flush point has been found, - Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point - has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current value of total_in - which indicates where valid compressed data was found. In the error case, - the application may repeatedly call inflateSync, providing more input each - time, until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy(z_streamp dest, - z_streamp source); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset(z_streamp strm); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate the internal decompression state. The - stream will keep attributes that may have been set by inflateInit2. - total_in, total_out, adler, and msg are initialized. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT inflateReset2(z_streamp strm, - int windowBits); -/* - This function is the same as inflateReset, but it also permits changing - the wrap and window size requests. The windowBits parameter is interpreted - the same as it is for inflateInit2. If the window size is changed, then the - memory allocated for the window is freed, and the window will be reallocated - by inflate() if needed. - - inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL), or if - the windowBits parameter is invalid. -*/ - -ZEXTERN int ZEXPORT inflatePrime(z_streamp strm, - int bits, - int value); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - If bits is negative, then the input stream bit buffer is emptied. Then - inflatePrime() can be called again to put bits in the buffer. This is used - to clear out bits leftover after feeding inflate a block description prior - to feeding inflate codes. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN long ZEXPORT inflateMark(z_streamp strm); -/* - This function returns two values, one in the lower 16 bits of the return - value, and the other in the remaining upper bits, obtained by shifting the - return value down 16 bits. If the upper value is -1 and the lower value is - zero, then inflate() is currently decoding information outside of a block. - If the upper value is -1 and the lower value is non-zero, then inflate is in - the middle of a stored block, with the lower value equaling the number of - bytes from the input remaining to copy. If the upper value is not -1, then - it is the number of bits back from the current bit position in the input of - the code (literal or length/distance pair) currently being processed. In - that case the lower value is the number of bytes already emitted for that - code. - - A code is being processed if inflate is waiting for more input to complete - decoding of the code, or if it has completed decoding but is waiting for - more output space to write the literal or match data. - - inflateMark() is used to mark locations in the input data for random - access, which may be at bit positions, and to note those cases where the - output of a code may span boundaries of random access blocks. The current - location in the input stream can be determined from avail_in and data_type - as noted in the description for the Z_BLOCK flush parameter for inflate. - - inflateMark returns the value noted above, or -65536 if the provided - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader(z_streamp strm, - gz_headerp head); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be - used to force inflate() to return immediately after header processing is - complete and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When any - of extra, name, or comment are not Z_NULL and the respective field is not - present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit(z_streamp strm, int windowBits, - unsigned char FAR *window); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the parameters are invalid, Z_MEM_ERROR if the internal state could not be - allocated, or Z_VERSION_ERROR if the version of the library does not match - the version of the header file. -*/ - -typedef unsigned (*in_func)(void FAR *, - z_const unsigned char FAR * FAR *); -typedef int (*out_func)(void FAR *, unsigned char FAR *, unsigned); - -ZEXTERN int ZEXPORT inflateBack(z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is potentially more efficient than - inflate() for file i/o applications, in that it avoids copying between the - output and the sliding window by simply making the window itself the output - buffer. inflate() can be faster on modern CPUs when used with large - buffers. inflateBack() trusts the application to not change the output - buffer passed by the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free the - allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects only - the raw deflate stream to decompress. This is different from the default - behavior of inflate(), which expects a zlib header and trailer around the - deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero -- buf is ignored in that - case -- and inflateBack() will return a buffer error. inflateBack() will - call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. - out() should return zero on success, or non-zero on failure. If out() - returns non-zero, inflateBack() will return with an error. Neither in() nor - out() are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format error - in the deflate stream (in which case strm->msg is set to indicate the nature - of the error), or Z_STREAM_ERROR if the stream was not properly initialized. - In the case of Z_BUF_ERROR, an input or output error can be distinguished - using strm->next_in which will be Z_NULL only if in() returned an error. If - strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning - non-zero. (in() will always be called before out(), so strm->next_in is - assured to be defined if out() returns non-zero.) Note that inflateBack() - cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd(z_streamp strm); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags(void); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: ZLIB_DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - -#ifndef Z_SOLO - - /* utility functions */ - -/* - The following utility functions are implemented on top of the basic - stream-oriented functions. To simplify the interface, some default options - are assumed (compression level and memory usage, standard memory allocation - functions). The source code of these utility functions can be modified if - you need special options. -*/ - -ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed data. compress() is equivalent to compress2() with a level - parameter of Z_DEFAULT_COMPRESSION. - - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed data. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound(uLong sourceLen); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before a - compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, destLen - is the actual size of the uncompressed data. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In - the case where there is not enough room, uncompress() will fill the output - buffer with the uncompressed data up to that point. -*/ - -ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, - const Bytef *source, uLong *sourceLen); -/* - Same as uncompress, except that sourceLen is a pointer, where the - length of the source is *sourceLen. On return, *sourceLen is the number of - source bytes consumed. -*/ - - /* gzip file access functions */ - -/* - This library supports reading and writing files in gzip (.gz) format with - an interface similar to that of stdio, using the functions that start with - "gz". The gzip format is different from the zlib format. gzip is a gzip - wrapper, documented in RFC 1952, wrapped around a deflate stream. -*/ - -typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ - -/* -ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode); - - Open the gzip (.gz) file at path for reading and decompressing, or - compressing and writing. The mode parameter is as in fopen ("rb" or "wb") - but can also include a compression level ("wb9") or a strategy: 'f' for - filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", - 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression - as in "wb9F". (See the description of deflateInit2 for more information - about the strategy parameter.) 'T' will request transparent writing or - appending with no compression and not using the gzip format. - - "a" can be used instead of "w" to request that the gzip stream that will - be written be appended to the file. "+" will result in an error, since - reading and writing to the same gzip file is not supported. The addition of - "x" when writing will create the file exclusively, which fails if the file - already exists. On systems that support it, the addition of "e" when - reading or writing will set the flag to close the file on an execve() call. - - These functions, as well as gzip, will read and decode a sequence of gzip - streams in a file. The append function of gzopen() can be used to create - such a file. (Also see gzflush() for another way to do this.) When - appending, gzopen does not test whether the file begins with a gzip stream, - nor does it look for the end of the gzip streams to begin appending. gzopen - will simply append a gzip stream to the existing file. - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. When - reading, this will be detected automatically by looking for the magic two- - byte gzip header. - - gzopen returns NULL if the file could not be opened, if there was - insufficient memory to allocate the gzFile state, or if an invalid mode was - specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). - errno can be checked to determine if the reason gzopen failed was that the - file could not be opened. -*/ - -ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode); -/* - Associate a gzFile with the file descriptor fd. File descriptors are - obtained from calls like open, dup, creat, pipe or fileno (if the file has - been previously opened with fopen). The mode parameter is as in gzopen. - - The next call of gzclose on the returned gzFile will also close the file - descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor - fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, - mode);. The duplicated descriptor should be saved to avoid a leak, since - gzdopen does not close fd if it fails. If you are using fileno() to get the - file descriptor from a FILE *, then you will have to use dup() to avoid - double-close()ing the file descriptor. Both gzclose() and fclose() will - close the associated file descriptor, so they need to have different file - descriptors. - - gzdopen returns NULL if there was insufficient memory to allocate the - gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not - provided, or '+' was provided), or if fd is -1. The file descriptor is not - used until the next gz* read, write, seek, or close operation, so gzdopen - will not detect if fd is invalid (unless fd is -1). -*/ - -ZEXTERN int ZEXPORT gzbuffer(gzFile file, unsigned size); -/* - Set the internal buffer size used by this library's functions for file to - size. The default buffer size is 8192 bytes. This function must be called - after gzopen() or gzdopen(), and before any other calls that read or write - the file. The buffer memory allocation is always deferred to the first read - or write. Three times that size in buffer space is allocated. A larger - buffer size of, for example, 64K or 128K bytes will noticeably increase the - speed of decompression (reading). - - The new buffer size also affects the maximum length for gzprintf(). - - gzbuffer() returns 0 on success, or -1 on failure, such as being called - too late. -*/ - -ZEXTERN int ZEXPORT gzsetparams(gzFile file, int level, int strategy); -/* - Dynamically update the compression level and strategy for file. See the - description of deflateInit2 for the meaning of these parameters. Previously - provided data is flushed before applying the parameter changes. - - gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not - opened for writing, Z_ERRNO if there is an error writing the flushed data, - or Z_MEM_ERROR if there is a memory allocation error. -*/ - -ZEXTERN int ZEXPORT gzread(gzFile file, voidp buf, unsigned len); -/* - Read and decompress up to len uncompressed bytes from file into buf. If - the input file is not in gzip format, gzread copies the given number of - bytes into the buffer directly from the file. - - After reaching the end of a gzip stream in the input, gzread will continue - to read, looking for another gzip stream. Any number of gzip streams may be - concatenated in the input file, and will all be decompressed by gzread(). - If something other than a gzip stream is encountered after a gzip stream, - that remaining trailing garbage is ignored (and no error is returned). - - gzread can be used to read a gzip file that is being concurrently written. - Upon reaching the end of the input, gzread will return with the available - data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then - gzclearerr can be used to clear the end of file indicator in order to permit - gzread to be tried again. Z_OK indicates that a gzip stream was completed - on the last gzread. Z_BUF_ERROR indicates that the input file ended in the - middle of a gzip stream. Note that gzread does not return -1 in the event - of an incomplete gzip stream. This error is deferred until gzclose(), which - will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip - stream. Alternatively, gzerror can be used before gzclose to detect this - case. - - gzread returns the number of uncompressed bytes actually read, less than - len for end of file, or -1 for error. If len is too large to fit in an int, - then nothing is read, -1 is returned, and the error state is set to - Z_STREAM_ERROR. -*/ - -ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, - gzFile file); -/* - Read and decompress up to nitems items of size size from file into buf, - otherwise operating as gzread() does. This duplicates the interface of - stdio's fread(), with size_t request and return types. If the library - defines size_t, then z_size_t is identical to size_t. If not, then z_size_t - is an unsigned integer type that can contain a pointer. - - gzfread() returns the number of full items read of size size, or zero if - the end of the file was reached and a full item could not be read, or if - there was an error. gzerror() must be consulted if zero is returned in - order to determine if there was an error. If the multiplication of size and - nitems overflows, i.e. the product does not fit in a z_size_t, then nothing - is read, zero is returned, and the error state is set to Z_STREAM_ERROR. - - In the event that the end of file is reached and only a partial item is - available at the end, i.e. the remaining uncompressed data length is not a - multiple of size, then the final partial item is nevertheless read into buf - and the end-of-file flag is set. The length of the partial item read is not - provided, but could be inferred from the result of gztell(). This behavior - is the same as the behavior of fread() implementations in common libraries, - but it prevents the direct use of gzfread() to read a concurrently written - file, resetting and retrying on end-of-file, when size is not 1. -*/ - -ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len); -/* - Compress and write the len uncompressed bytes at buf to file. gzwrite - returns the number of uncompressed bytes written or 0 in case of error. -*/ - -ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, - z_size_t nitems, gzFile file); -/* - Compress and write nitems items of size size from buf to file, duplicating - the interface of stdio's fwrite(), with size_t request and return types. If - the library defines size_t, then z_size_t is identical to size_t. If not, - then z_size_t is an unsigned integer type that can contain a pointer. - - gzfwrite() returns the number of full items written of size size, or zero - if there was an error. If the multiplication of size and nitems overflows, - i.e. the product does not fit in a z_size_t, then nothing is written, zero - is returned, and the error state is set to Z_STREAM_ERROR. -*/ - -ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...); -/* - Convert, format, compress, and write the arguments (...) to file under - control of the string format, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or a negative zlib error code in case - of error. The number of uncompressed bytes written is limited to 8191, or - one less than the buffer size given to gzbuffer(). The caller should assure - that this limit is not exceeded. If it is exceeded, then gzprintf() will - return an error (0) with nothing written. In this case, there may also be a - buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf(), - because the secure snprintf() or vsnprintf() functions were not available. - This can be determined using zlibCompileFlags(). -*/ - -ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s); -/* - Compress and write the given null-terminated string s to file, excluding - the terminating null character. - - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len); -/* - Read and decompress bytes from file into buf, until len-1 characters are - read, or until a newline character is read and transferred to buf, or an - end-of-file condition is encountered. If any characters are read or if len - is one, the string is terminated with a null character. If no characters - are read due to an end-of-file or len is less than one, then the buffer is - left untouched. - - gzgets returns buf which is a null-terminated string, or it returns NULL - for end-of-file or in case of error. If there was an error, the contents at - buf are indeterminate. -*/ - -ZEXTERN int ZEXPORT gzputc(gzFile file, int c); -/* - Compress and write c, converted to an unsigned char, into file. gzputc - returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc(gzFile file); -/* - Read and decompress one byte from file. gzgetc returns this byte or -1 - in case of end of file or error. This is implemented as a macro for speed. - As such, it does not do all of the checking the other functions do. I.e. - it does not check to see if file is NULL, nor whether the structure file - points to has been clobbered or not. -*/ - -ZEXTERN int ZEXPORT gzungetc(int c, gzFile file); -/* - Push c back onto the stream for file to be read as the first character on - the next read. At least one character of push-back is always allowed. - gzungetc() returns the character pushed, or -1 on failure. gzungetc() will - fail if c is -1, and may fail if a character has been pushed but not read - yet. If gzungetc is used immediately after gzopen or gzdopen, at least the - output buffer size of pushed characters is allowed. (See gzbuffer above.) - The pushed character will be discarded if the stream is repositioned with - gzseek() or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush(gzFile file, int flush); -/* - Flush all pending output to file. The parameter flush is as in the - deflate() function. The return value is the zlib error number (see function - gzerror below). gzflush is only permitted when writing. - - If the flush parameter is Z_FINISH, the remaining data is written and the - gzip stream is completed in the output. If gzwrite() is called again, a new - gzip stream will be started in the output. gzread() is able to read such - concatenated gzip streams. - - gzflush should be called only when strictly necessary because it will - degrade compression if called too often. -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzseek(gzFile file, - z_off_t offset, int whence); - - Set the starting position to offset relative to whence for the next gzread - or gzwrite on file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind(gzFile file); -/* - Rewind file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET). -*/ - -/* -ZEXTERN z_off_t ZEXPORT gztell(gzFile file); - - Return the starting position for the next gzread or gzwrite on file. - This position represents a number of bytes in the uncompressed data stream, - and is zero when starting, even if appending or reading a gzip stream from - the middle of a file using gzdopen(). - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzoffset(gzFile file); - - Return the current compressed (actual) read or write offset of file. This - offset includes the count of bytes that precede the gzip stream, for example - when appending or when using gzdopen() for reading. When reading, the - offset does not include as yet unused buffered input. This information can - be used for a progress indicator. On error, gzoffset() returns -1. -*/ - -ZEXTERN int ZEXPORT gzeof(gzFile file); -/* - Return true (1) if the end-of-file indicator for file has been set while - reading, false (0) otherwise. Note that the end-of-file indicator is set - only if the read tried to go past the end of the input, but came up short. - Therefore, just like feof(), gzeof() may return false even if there is no - more data to read, in the event that the last read request was for the exact - number of bytes remaining in the input file. This will happen if the input - file size is an exact multiple of the buffer size. - - If gzeof() returns true, then the read functions will return no more data, - unless the end-of-file indicator is reset by gzclearerr() and the input file - has grown since the previous end of file was detected. -*/ - -ZEXTERN int ZEXPORT gzdirect(gzFile file); -/* - Return true (1) if file is being copied directly while reading, or false - (0) if file is a gzip stream being decompressed. - - If the input file is empty, gzdirect() will return true, since the input - does not contain a gzip stream. - - If gzdirect() is used immediately after gzopen() or gzdopen() it will - cause buffers to be allocated to allow reading the file to determine if it - is a gzip file. Therefore if gzbuffer() is used, it should be called before - gzdirect(). - - When writing, gzdirect() returns true (1) if transparent writing was - requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: - gzdirect() is not needed when writing. Transparent writing must be - explicitly requested, so the application already knows the answer. When - linking statically, using gzdirect() will include all of the zlib code for - gzip file reading and decompression, which may not be desired.) -*/ - -ZEXTERN int ZEXPORT gzclose(gzFile file); -/* - Flush all pending output for file, if necessary, close file and - deallocate the (de)compression state. Note that once file is closed, you - cannot call gzerror with file, since its structures have been deallocated. - gzclose must not be called more than once on the same file, just as free - must not be called more than once on the same allocation. - - gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a - file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the - last read ended in the middle of a gzip stream, or Z_OK on success. -*/ - -ZEXTERN int ZEXPORT gzclose_r(gzFile file); -ZEXTERN int ZEXPORT gzclose_w(gzFile file); -/* - Same as gzclose(), but gzclose_r() is only for use when reading, and - gzclose_w() is only for use when writing or appending. The advantage to - using these instead of gzclose() is that they avoid linking in zlib - compression or decompression code that is not used when only reading or only - writing respectively. If gzclose() is used, then both compression and - decompression code will be included the application when linking to a static - zlib library. -*/ - -ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum); -/* - Return the error message for the last error which occurred on file. - errnum is set to zlib error number. If an error occurred in the file system - and not in the compression library, errnum is set to Z_ERRNO and the - application may consult errno to get the exact error code. - - The application must not modify the returned string. Future calls to - this function may invalidate the previously returned string. If file is - closed, then the string previously returned by gzerror will no longer be - available. - - gzerror() should be used to distinguish errors from end-of-file for those - functions above that do not distinguish those cases in their return values. -*/ - -ZEXTERN void ZEXPORT gzclearerr(gzFile file); -/* - Clear the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - -#endif /* !Z_SOLO */ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the compression - library. -*/ - -ZEXTERN uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. An Adler-32 value is in the range of a 32-bit - unsigned integer. If buf is Z_NULL, this function returns the required - initial value for the checksum. - - An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed - much faster. - - Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -ZEXTERN uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, - z_size_t len); -/* - Same as adler32(), but with a size_t length. -*/ - -/* -ZEXTERN uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, - z_off_t len2); - - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note - that the z_off_t type (like off_t) is a signed integer. If len2 is - negative, the result has no meaning or utility. -*/ - -ZEXTERN uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. - If buf is Z_NULL, this function returns the required initial value for the - crc. Pre- and post-conditioning (one's complement) is performed within this - function so it shouldn't be done by the application. - - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -ZEXTERN uLong ZEXPORT crc32_z(uLong crc, const Bytef *buf, - z_size_t len); -/* - Same as crc32(), but with a size_t length. -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2); - - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. len2 must be non-negative. -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); - - Return the operator corresponding to length len2, to be used with - crc32_combine_op(). len2 must be non-negative. -*/ - -ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); -/* - Give the same result as crc32_combine(), using op in place of len2. op is - is generated from len2 by crc32_combine_gen(). This will be faster than - crc32_combine() if the generated op is used more than once. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_(z_streamp strm, int level, - const char *version, int stream_size); -ZEXTERN int ZEXPORT inflateInit_(z_streamp strm, - const char *version, int stream_size); -ZEXTERN int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size); -ZEXTERN int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, - const char *version, int stream_size); -ZEXTERN int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size); -#ifdef Z_PREFIX_SET -# define z_deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -# define z_inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) -#else -# define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -# define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -# define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -# define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) -#endif - -#ifndef Z_SOLO - -/* gzgetc() macro and its supporting function and exposed data structure. Note - * that the real internal state is much larger than the exposed structure. - * This abbreviated structure exposes just enough for the gzgetc() macro. The - * user should not mess with these exposed elements, since their names or - * behavior could change in the future, perhaps even capriciously. They can - * only be used by the gzgetc() macro. You have been warned. - */ -struct gzFile_s { - unsigned have; - unsigned char *next; - z_off64_t pos; -}; -ZEXTERN int ZEXPORT gzgetc_(gzFile file); /* backward compatibility */ -#ifdef Z_PREFIX_SET -# undef z_gzgetc -# define z_gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) -#else -# define gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) -#endif - -/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or - * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if - * both are true, the application gets the *64 functions, and the regular - * functions are changed to 64 bits) -- in case these are set on systems - * without large file support, _LFS64_LARGEFILE must also be true - */ -#ifdef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); - ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); - ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); - ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); - ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t); - ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t); - ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t); -#endif - -#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) -# ifdef Z_PREFIX_SET -# define z_gzopen z_gzopen64 -# define z_gzseek z_gzseek64 -# define z_gztell z_gztell64 -# define z_gzoffset z_gzoffset64 -# define z_adler32_combine z_adler32_combine64 -# define z_crc32_combine z_crc32_combine64 -# define z_crc32_combine_gen z_crc32_combine_gen64 -# else -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# define crc32_combine_gen crc32_combine_gen64 -# endif -# ifndef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); - ZEXTERN z_off_t ZEXPORT gzseek64(gzFile, z_off_t, int); - ZEXTERN z_off_t ZEXPORT gztell64(gzFile); - ZEXTERN z_off_t ZEXPORT gzoffset64(gzFile); - ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); -# endif -#else - ZEXTERN gzFile ZEXPORT gzopen(const char *, const char *); - ZEXTERN z_off_t ZEXPORT gzseek(gzFile, z_off_t, int); - ZEXTERN z_off_t ZEXPORT gztell(gzFile); - ZEXTERN z_off_t ZEXPORT gzoffset(gzFile); - ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); -#endif - -#else /* Z_SOLO */ - - ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); - -#endif /* !Z_SOLO */ - -/* undocumented functions */ -ZEXTERN const char * ZEXPORT zError(int); -ZEXTERN int ZEXPORT inflateSyncPoint(z_streamp); -ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table(void); -ZEXTERN int ZEXPORT inflateUndermine(z_streamp, int); -ZEXTERN int ZEXPORT inflateValidate(z_streamp, int); -ZEXTERN unsigned long ZEXPORT inflateCodesUsed(z_streamp); -ZEXTERN int ZEXPORT inflateResetKeep(z_streamp); -ZEXTERN int ZEXPORT deflateResetKeep(z_streamp); -#if defined(_WIN32) && !defined(Z_SOLO) -ZEXTERN gzFile ZEXPORT gzopen_w(const wchar_t *path, - const char *mode); -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -ZEXTERN int ZEXPORTVA gzvprintf(gzFile file, - const char *format, - va_list va); -# endif -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/ext/zlib/zlib.vcxproj b/ext/zlib/zlib.vcxproj deleted file mode 100644 index dbd8459891..0000000000 --- a/ext/zlib/zlib.vcxproj +++ /dev/null @@ -1,281 +0,0 @@ - - - - - Debug - ARM64 - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {F761046E-6C38-4428-A5F1-38391A37BB34} - Win32Proj - zlib - 10.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - StaticLibrary - true - Unicode - $(DefaultPlatformToolset) - - - StaticLibrary - true - Unicode - $(DefaultPlatformToolset) - - - StaticLibrary - true - Unicode - $(DefaultPlatformToolset) - true - - - StaticLibrary - false - false - Unicode - $(DefaultPlatformToolset) - - - StaticLibrary - false - Unicode - $(DefaultPlatformToolset) - - - StaticLibrary - false - Unicode - $(DefaultPlatformToolset) - true - - - - - - - $(SolutionDir)$(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - - - - - - Level3 - _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - StreamingSIMDExtensions2 - Precise - Default - true - false - MultiThreadedDebug - ../../Common/DbgNew.h - ProgramDatabase - - - Windows - true - - - - - - - Level3 - _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - false - NotSet - Precise - Default - true - false - MultiThreadedDebug - ../../Common/DbgNew.h - ProgramDatabase - - - Windows - true - - - - - - - Level3 - _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - false - NotSet - Precise - Default - true - false - MultiThreadedDebug - ../../Common/DbgNew.h - ProgramDatabase - - - Windows - true - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - StreamingSIMDExtensions2 - false - Precise - Speed - AnySuitable - true - MultiThreaded - ProgramDatabase - - - Windows - true - true - true - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - false - AnySuitable - Speed - false - NotSet - Precise - true - MultiThreaded - ProgramDatabase - true - - - Windows - true - true - true - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - false - AnySuitable - Speed - false - NotSet - Precise - true - MultiThreaded - ProgramDatabase - true - - - Windows - true - true - true - - - - - - \ No newline at end of file diff --git a/ext/zlib/zlib.vcxproj.filters b/ext/zlib/zlib.vcxproj.filters deleted file mode 100644 index 54f2aba917..0000000000 --- a/ext/zlib/zlib.vcxproj.filters +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ext/zlib/zutil.c b/ext/zlib/zutil.c deleted file mode 100644 index b1c5d2d3c6..0000000000 --- a/ext/zlib/zutil.c +++ /dev/null @@ -1,299 +0,0 @@ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2017 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" -#ifndef Z_SOLO -# include "gzguts.h" -#endif - -z_const char * const z_errmsg[10] = { - (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ - (z_const char *)"stream end", /* Z_STREAM_END 1 */ - (z_const char *)"", /* Z_OK 0 */ - (z_const char *)"file error", /* Z_ERRNO (-1) */ - (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ - (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ - (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ - (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ - (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ - (z_const char *)"" -}; - - -const char * ZEXPORT zlibVersion(void) { - return ZLIB_VERSION; -} - -uLong ZEXPORT zlibCompileFlags(void) { - uLong flags; - - flags = 0; - switch ((int)(sizeof(uInt))) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch ((int)(sizeof(uLong))) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch ((int)(sizeof(voidpf))) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch ((int)(sizeof(z_off_t))) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } -#ifdef ZLIB_DEBUG - flags += 1 << 8; -#endif - /* -#if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; -#endif - */ -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1L << 16; -#endif -#ifdef NO_GZIP - flags += 1L << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; -#endif -#ifdef FASTEST - flags += 1L << 21; -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifdef NO_vsnprintf - flags += 1L << 25; -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif -#else - flags += 1L << 24; -# ifdef NO_snprintf - flags += 1L << 25; -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif -#endif - return flags; -} - -#ifdef ZLIB_DEBUG -#include -# ifndef verbose -# define verbose 0 -# endif -int ZLIB_INTERNAL z_verbose = verbose; - -void ZLIB_INTERNAL z_error(char *m) { - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char * ZEXPORT zError(int err) { - return ERR_MSG(err); -} - -#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800 - /* The older Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. - */ - int errno = 0; -#endif - -#ifndef HAVE_MEMCPY - -void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len) { - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) { - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; -} - -void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) { - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - -#ifndef Z_SOLO - -#ifdef SYS16BIT - -#ifdef __TURBOC__ -/* Turbo C in 16-bit mode */ - -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { - voidpf buf; - ulg bsize = (ulg)items*size; - - (void)opaque; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { - int n; - - (void)opaque; - - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - Assert(0, "zcfree: ptr not found"); -} - -#endif /* __TURBOC__ */ - - -#ifdef M_I86 -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) { - (void)opaque; - return _halloc((long)items, size); -} - -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { - (void)opaque; - _hfree(ptr); -} - -#endif /* M_I86 */ - -#endif /* SYS16BIT */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp malloc(uInt size); -extern voidp calloc(uInt items, uInt size); -extern void free(voidpf ptr); -#endif - -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { - (void)opaque; - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); -} - -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { - (void)opaque; - free(ptr); -} - -#endif /* MY_ZCALLOC */ - -#endif /* !Z_SOLO */ diff --git a/ext/zlib/zutil.h b/ext/zlib/zutil.h deleted file mode 100644 index 48dd7febae..0000000000 --- a/ext/zlib/zutil.h +++ /dev/null @@ -1,254 +0,0 @@ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef ZUTIL_H -#define ZUTIL_H - -#ifdef HAVE_HIDDEN -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include "zlib.h" - -#if defined(STDC) && !defined(Z_SOLO) -# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) -# include -# endif -# include -# include -#endif - -#ifndef local -# define local static -#endif -/* since "static" is used to mean two completely different things in C, we - define "local" for the non-static meaning of "static", for readability - (compile with -Dlocal if your debugger can't find static symbols) */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -#if !defined(Z_U8) && !defined(Z_SOLO) && defined(STDC) -# include -# if (ULONG_MAX == 0xffffffffffffffff) -# define Z_U8 unsigned long -# elif (ULLONG_MAX == 0xffffffffffffffff) -# define Z_U8 unsigned long long -# elif (UINT_MAX == 0xffffffffffffffff) -# define Z_U8 unsigned -# endif -#endif - -extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - -#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) -# define OS_CODE 0x00 -# ifndef Z_SOLO -# if defined(__TURBOC__) || defined(__BORLANDC__) -# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) - /* Allow compilation with ANSI keywords only enabled */ - void _Cdecl farfree( void *block ); - void *_Cdecl farmalloc( unsigned long nbytes ); -# else -# include -# endif -# else /* MSC or DJGPP */ -# include -# endif -# endif -#endif - -#ifdef AMIGA -# define OS_CODE 1 -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 2 -# define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#ifdef __370__ -# if __TARGET_LIB__ < 0x20000000 -# define OS_CODE 4 -# elif __TARGET_LIB__ < 0x40000000 -# define OS_CODE 11 -# else -# define OS_CODE 8 -# endif -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 5 -#endif - -#ifdef OS2 -# define OS_CODE 6 -# if defined(M_I86) && !defined(Z_SOLO) -# include -# endif -#endif - -#if defined(MACOS) -# define OS_CODE 7 -#endif - -#ifdef __acorn -# define OS_CODE 13 -#endif - -#if defined(WIN32) && !defined(__CYGWIN__) -# define OS_CODE 10 -#endif - -#ifdef _BEOS_ -# define OS_CODE 16 -#endif - -#ifdef __TOS_OS400__ -# define OS_CODE 18 -#endif - -#ifdef __APPLE__ -# define OS_CODE 19 -#endif - -#if defined(__BORLANDC__) && !defined(MSDOS) - #pragma warn -8004 - #pragma warn -8008 - #pragma warn -8066 -#endif - -/* provide prototypes for these when building zlib without LFS */ -#if !defined(_WIN32) && \ - (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) - ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); -#endif - - /* common defaults */ - -#ifndef OS_CODE -# define OS_CODE 3 /* assume Unix */ -#endif - -#ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -#if defined(pyr) || defined(Z_SOLO) -# define NO_MEMCPY -#endif -#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) - /* Use our own functions for small and medium model with MSC <= 5.0. - * You may have to use the same strategy for Borland C (untested). - * The __SC__ check is for Symantec. - */ -# define NO_MEMCPY -#endif -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) -# endif -#else - void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len); - int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len); - void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len); -#endif - -/* Diagnostic functions */ -#ifdef ZLIB_DEBUG -# include - extern int ZLIB_INTERNAL z_verbose; - extern void ZLIB_INTERNAL z_error(char *m); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) {if (z_verbose>=0) fprintf x ;} -# define Tracev(x) {if (z_verbose>0) fprintf x ;} -# define Tracevv(x) {if (z_verbose>1) fprintf x ;} -# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} -# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - -#ifndef Z_SOLO - voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, - unsigned size); - void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr); -#endif - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -/* Reverse the bytes in a 32-bit value */ -#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) - -#endif /* ZUTIL_H */ diff --git a/ext/zstd b/ext/zstd deleted file mode 160000 index f8745da6ff..0000000000 --- a/ext/zstd +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f8745da6ff1ad1e7bab384bd1f9d742439278e99 diff --git a/ext/zstd-build/CMakeLists.txt b/ext/zstd-build/CMakeLists.txt deleted file mode 100644 index 1f65a3f070..0000000000 --- a/ext/zstd-build/CMakeLists.txt +++ /dev/null @@ -1,51 +0,0 @@ -cmake_minimum_required (VERSION 3.10.0) -project (libzstd_static) - -set(SRC_DIR ../zstd/lib) - -set(ALL_SOURCE_FILES - ${SRC_DIR}/common/debug.c - ${SRC_DIR}/common/entropy_common.c - ${SRC_DIR}/common/error_private.c - ${SRC_DIR}/common/fse_decompress.c - ${SRC_DIR}/common/pool.c - ${SRC_DIR}/common/threading.c - ${SRC_DIR}/common/xxhash.c - ${SRC_DIR}/common/zstd_common.c - ${SRC_DIR}/compress/fse_compress.c - ${SRC_DIR}/compress/hist.c - ${SRC_DIR}/compress/huf_compress.c - ${SRC_DIR}/compress/zstd_compress.c - ${SRC_DIR}/compress/zstd_compress_literals.c - ${SRC_DIR}/compress/zstd_compress_sequences.c - ${SRC_DIR}/compress/zstd_compress_superblock.c - ${SRC_DIR}/compress/zstd_double_fast.c - ${SRC_DIR}/compress/zstd_fast.c - ${SRC_DIR}/compress/zstd_lazy.c - ${SRC_DIR}/compress/zstd_ldm.c - ${SRC_DIR}/compress/zstd_opt.c - ${SRC_DIR}/compress/zstd_preSplit.c - ${SRC_DIR}/compress/zstdmt_compress.c - ${SRC_DIR}/decompress/huf_decompress.c - ${SRC_DIR}/decompress/zstd_ddict.c - ${SRC_DIR}/decompress/zstd_decompress.c - ${SRC_DIR}/decompress/zstd_decompress_block.c - ${SRC_DIR}/dictBuilder/cover.c - ${SRC_DIR}/dictBuilder/divsufsort.c - ${SRC_DIR}/dictBuilder/fastcover.c - ${SRC_DIR}/dictBuilder/zdict.c -) - -if (MSVC) - add_compile_options(-DZSTD_DISABLE_ASM) -else () - if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|AMD64.*|x86_64.*|X86_64.*") - set(ALL_SOURCE_FILES ${ALL_SOURCE_FILES} ${SRC_DIR}/decompress/huf_decompress_amd64.S) - else() - add_compile_options(-DZSTD_DISABLE_ASM) - endif() -endif () - -add_library(libzstd_static STATIC ${ALL_SOURCE_FILES}) - -target_include_directories(libzstd_static PUBLIC ../zstd/lib) diff --git a/headless/Compare.cpp b/headless/Compare.cpp index 16e7897dad..a897f32333 100644 --- a/headless/Compare.cpp +++ b/headless/Compare.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include "headless/Compare.h" @@ -503,22 +502,9 @@ bool ScreenshotComparer::SaveVisualComparisonPNG(const Path &resultFilename) { } } - FILE *fp = File::OpenCFile(resultFilename, "wb"); - if (!fp) - return false; - - png_image png; - memset(&png, 0, sizeof(png)); - png.version = PNG_IMAGE_VERSION; - png.format = PNG_FORMAT_BGRA; - png.width = w_ * 2; - png.height = h_ * 2; - - bool success = png_image_write_to_stdio(&png, fp, 0, comparison.get(), w_ * 2 * 4, nullptr) != 0; - fclose(fp); - png_image_free(&png); - - return success && png.warning_or_error < 2; + std::vector png; + return pngEncode(&png, comparison.get(), w_ * 2, h_ * 2, PNGFormat::BGRA8888) && + File::WriteDataToFile(false, png.data(), png.size(), resultFilename); } int ChannelDifference(u8 actual, u8 reference) { diff --git a/libretro/CMakeLists.txt b/libretro/CMakeLists.txt index d5015eddeb..e1e43fbf9c 100644 --- a/libretro/CMakeLists.txt +++ b/libretro/CMakeLists.txt @@ -12,27 +12,6 @@ if(WIN32) LibretroD3D11Context.cpp) endif() -set(LIBRETRO_SRCS ${LIBRETRO_SRCS} - libretro-common/compat/compat_posix_string.c - libretro-common/compat/fopen_utf8.c - libretro-common/compat/compat_strl.c - libretro-common/encodings/encoding_utf.c - libretro-common/file/file_path.c - libretro-common/file/file_path_io.c - libretro-common/streams/file_stream.c - libretro-common/streams/file_stream_transforms.c - libretro-common/string/rstrtod.c - libretro-common/time/rtime.c - libretro-common/vfs/vfs_implementation.c - libretro-common/features/features_cpu.c - libretro-common/queues/retro_spsc.c - libretro-common/queues/retro_waitable_spsc.c - libretro-common/rthreads/retro_asym_eventcount.c - libretro-common/rthreads/retro_eventcount.c - libretro-common/rthreads/retro_procbarrier.c - libretro-common/rthreads/rthreads.c - libretro-common/rthreads/tpool.c) - include_directories(libretro) add_library(ppsspp_libretro SHARED ${LIBRETRO_SRCS}) @@ -41,7 +20,6 @@ set_target_properties(ppsspp_libretro PROPERTIES PREFIX "") if(ANDROID) set_target_properties(ppsspp_libretro PROPERTIES SUFFIX "_android.so") endif() -target_include_directories(ppsspp_libretro PRIVATE libretro-common/include) if(NOT MSVC) if (APPLE OR IOS) diff --git a/libretro/Makefile b/libretro/Makefile index 6a49c64936..1f8e2fc523 100644 --- a/libretro/Makefile +++ b/libretro/Makefile @@ -557,13 +557,27 @@ else $(LD) $(LINKOUT)$@ $(OBJECTS) $(LDFLAGS) $(GL_LIB) endif +# Host-side image and codec checks (test/run.sh). They link the core's own objects, +# so they build with the same flags; minixmlvalid.o is a program of its own. +comma := , +TEST_OBJECTS = $(filter-out %/minixmlvalid.o,$(OBJECTS)) +TEST_LDFLAGS = $(filter-out -shared -Wl$(comma)--version-script=link.T,$(LDFLAGS)) + +test/%: test/%.o $(TEST_OBJECTS) + $(LD) $(LINKOUT)$@ $< $(TEST_OBJECTS) $(TEST_LDFLAGS) $(GL_LIB) + +test/lrtest: test/lrtest.c + $(CC) -O2 -I$(LIBRETROCOMMONDIR)/include -o $@ $< -ldl + +test-tools: $(TARGET) test/codectest test/blocktest test/lrtest + clean: - rm -f $(filter-out $(CORE_DIR)/ext/zstd/lib/decompress/huf_decompress_amd64.S,$(OBJECTS)) $(TARGET) + rm -f $(OBJECTS) $(TARGET) test/*.o test/codectest test/blocktest test/lrtest ifeq ($(FFMPEG_MINGW), 1) rm -rf $(FFMPEG_MINGW_DIR) endif -.PHONY: clean +.PHONY: clean test-tools print-%: @echo '$*=$($*)' diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 230182ac9e..54d93493f9 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -1,5 +1,3 @@ -HAVE_LIBRETRO_VFS ?= 1 - FFMPEGDIR = $(CORE_DIR)/ffmpeg LIBRETRODIR = $(CORE_DIR)/libretro COREDIR = $(CORE_DIR)/Core @@ -8,7 +6,6 @@ GPUCOMMONDIR = $(CORE_DIR)/GPU/Common GPUDIR = $(CORE_DIR)/GPU EXTDIR = $(CORE_DIR)/ext NATIVEDIR = $(EXTDIR)/native -ZSTDDIR = $(EXTDIR)/zstd/lib LIBRETROCOMMONDIR = $(LIBRETRODIR)/libretro-common SOURCES_CXX := @@ -25,9 +22,7 @@ INCFLAGS += \ -I$(EXTDIR)/glslang \ -I$(EXTDIR)/glslang-build \ -I$(EXTDIR)/native \ - -I$(EXTDIR)/zlib \ -I$(EXTDIR)/cpu_features/include \ - -I$(ZSTDDIR) \ -I$(EXTDIR)/snappy \ -I$(FFMPEGDIR) \ $(FFMPEGINCFLAGS) \ @@ -35,142 +30,13 @@ INCFLAGS += \ -I$(EXTDIR)/armips \ -I$(EXTDIR)/armips/ext/filesystem/include \ -I$(EXTDIR)/armips/ext/tinyformat \ - -I$(EXTDIR)/zstd/lib \ -I$(EXTDIR) \ -I$(NATIVEDIR) \ - -I$(EXTDIR)/libpng17 \ -I$(EXTDIR)/libkirk \ -I$(EXTDIR)/xbrz \ -I$(EXTDIR)/xxhash \ -I$(EXTDIR)/glew -INCFLAGS += -I$(EXTDIR)/libzip -SOURCES_C += \ - $(EXTDIR)/libzip/zip_add.c \ - $(EXTDIR)/libzip/zip_add_dir.c \ - $(EXTDIR)/libzip/zip_add_entry.c \ - $(EXTDIR)/libzip/zip_algorithm_deflate.c \ - $(EXTDIR)/libzip/zip_buffer.c \ - $(EXTDIR)/libzip/zip_close.c \ - $(EXTDIR)/libzip/zip_delete.c \ - $(EXTDIR)/libzip/zip_dir_add.c \ - $(EXTDIR)/libzip/zip_dirent.c \ - $(EXTDIR)/libzip/zip_discard.c \ - $(EXTDIR)/libzip/zip_entry.c \ - $(EXTDIR)/libzip/zip_error.c \ - $(EXTDIR)/libzip/zip_error_clear.c \ - $(EXTDIR)/libzip/zip_error_get.c \ - $(EXTDIR)/libzip/zip_error_get_sys_type.c \ - $(EXTDIR)/libzip/zip_error_strerror.c \ - $(EXTDIR)/libzip/zip_error_to_str.c \ - $(EXTDIR)/libzip/zip_extra_field.c \ - $(EXTDIR)/libzip/zip_extra_field_api.c \ - $(EXTDIR)/libzip/zip_fclose.c \ - $(EXTDIR)/libzip/zip_fdopen.c \ - $(EXTDIR)/libzip/zip_file_add.c \ - $(EXTDIR)/libzip/zip_file_error_clear.c \ - $(EXTDIR)/libzip/zip_file_error_get.c \ - $(EXTDIR)/libzip/zip_file_get_comment.c \ - $(EXTDIR)/libzip/zip_file_get_external_attributes.c \ - $(EXTDIR)/libzip/zip_file_get_offset.c \ - $(EXTDIR)/libzip/zip_file_rename.c \ - $(EXTDIR)/libzip/zip_file_replace.c \ - $(EXTDIR)/libzip/zip_file_set_comment.c \ - $(EXTDIR)/libzip/zip_file_set_encryption.c \ - $(EXTDIR)/libzip/zip_file_set_external_attributes.c \ - $(EXTDIR)/libzip/zip_file_set_mtime.c \ - $(EXTDIR)/libzip/zip_file_strerror.c \ - $(EXTDIR)/libzip/zip_fopen.c \ - $(EXTDIR)/libzip/zip_fopen_encrypted.c \ - $(EXTDIR)/libzip/zip_fopen_index.c \ - $(EXTDIR)/libzip/zip_fopen_index_encrypted.c \ - $(EXTDIR)/libzip/zip_fread.c \ - $(EXTDIR)/libzip/zip_fseek.c \ - $(EXTDIR)/libzip/zip_ftell.c \ - $(EXTDIR)/libzip/zip_get_archive_comment.c \ - $(EXTDIR)/libzip/zip_get_archive_flag.c \ - $(EXTDIR)/libzip/zip_get_encryption_implementation.c \ - $(EXTDIR)/libzip/zip_get_file_comment.c \ - $(EXTDIR)/libzip/zip_get_name.c \ - $(EXTDIR)/libzip/zip_get_num_entries.c \ - $(EXTDIR)/libzip/zip_get_num_files.c \ - $(EXTDIR)/libzip/zip_hash.c \ - $(EXTDIR)/libzip/zip_io_util.c \ - $(EXTDIR)/libzip/zip_libzip_version.c \ - $(EXTDIR)/libzip/zip_memdup.c \ - $(EXTDIR)/libzip/zip_name_locate.c \ - $(EXTDIR)/libzip/zip_new.c \ - $(EXTDIR)/libzip/zip_open.c \ - $(EXTDIR)/libzip/zip_pkware.c \ - $(EXTDIR)/libzip/zip_progress.c \ - $(EXTDIR)/libzip/zip_rename.c \ - $(EXTDIR)/libzip/zip_replace.c \ - $(EXTDIR)/libzip/zip_set_archive_comment.c \ - $(EXTDIR)/libzip/zip_set_archive_flag.c \ - $(EXTDIR)/libzip/zip_set_default_password.c \ - $(EXTDIR)/libzip/zip_set_file_comment.c \ - $(EXTDIR)/libzip/zip_set_file_compression.c \ - $(EXTDIR)/libzip/zip_set_name.c \ - $(EXTDIR)/libzip/zip_source_accept_empty.c \ - $(EXTDIR)/libzip/zip_source_begin_write.c \ - $(EXTDIR)/libzip/zip_source_begin_write_cloning.c \ - $(EXTDIR)/libzip/zip_source_buffer.c \ - $(EXTDIR)/libzip/zip_source_call.c \ - $(EXTDIR)/libzip/zip_source_close.c \ - $(EXTDIR)/libzip/zip_source_commit_write.c \ - $(EXTDIR)/libzip/zip_source_compress.c \ - $(EXTDIR)/libzip/zip_source_crc.c \ - $(EXTDIR)/libzip/zip_source_error.c \ - $(EXTDIR)/libzip/zip_source_file_common.c \ - $(EXTDIR)/libzip/zip_source_file_stdio.c \ - $(EXTDIR)/libzip/zip_source_free.c \ - $(EXTDIR)/libzip/zip_source_function.c \ - $(EXTDIR)/libzip/zip_source_get_file_attributes.c \ - $(EXTDIR)/libzip/zip_source_is_deleted.c \ - $(EXTDIR)/libzip/zip_source_layered.c \ - $(EXTDIR)/libzip/zip_source_open.c \ - $(EXTDIR)/libzip/zip_source_pkware_decode.c \ - $(EXTDIR)/libzip/zip_source_pkware_encode.c \ - $(EXTDIR)/libzip/zip_source_read.c \ - $(EXTDIR)/libzip/zip_source_remove.c \ - $(EXTDIR)/libzip/zip_source_rollback_write.c \ - $(EXTDIR)/libzip/zip_source_seek.c \ - $(EXTDIR)/libzip/zip_source_seek_write.c \ - $(EXTDIR)/libzip/zip_source_stat.c \ - $(EXTDIR)/libzip/zip_source_supports.c \ - $(EXTDIR)/libzip/zip_source_tell.c \ - $(EXTDIR)/libzip/zip_source_tell_write.c \ - $(EXTDIR)/libzip/zip_source_window.c \ - $(EXTDIR)/libzip/zip_source_write.c \ - $(EXTDIR)/libzip/zip_source_zip.c \ - $(EXTDIR)/libzip/zip_source_zip_new.c \ - $(EXTDIR)/libzip/zip_stat.c \ - $(EXTDIR)/libzip/zip_stat_index.c \ - $(EXTDIR)/libzip/zip_stat_init.c \ - $(EXTDIR)/libzip/zip_strerror.c \ - $(EXTDIR)/libzip/zip_string.c \ - $(EXTDIR)/libzip/zip_unchange.c \ - $(EXTDIR)/libzip/zip_unchange_all.c \ - $(EXTDIR)/libzip/zip_unchange_archive.c \ - $(EXTDIR)/libzip/zip_unchange_data.c \ - $(EXTDIR)/libzip/zip_utf-8.c \ - $(EXTDIR)/libzip/zip_err_str.c - -ifeq ($(PLATFORM_EXT), win32) - SOURCES_C += \ - $(EXTDIR)/libzip/zip_source_file_win32.c \ - $(EXTDIR)/libzip/zip_source_file_win32_named.c \ - $(EXTDIR)/libzip/zip_source_file_win32_utf16.c \ - $(EXTDIR)/libzip/zip_source_file_win32_utf8.c \ - $(EXTDIR)/libzip/zip_source_file_win32_ansi.c \ - $(EXTDIR)/libzip/zip_random_win32.c -else - SOURCES_C += \ - $(EXTDIR)/libzip/zip_mkstempm.c \ - $(EXTDIR)/libzip/zip_source_file_stdio_named.c \ - $(EXTDIR)/libzip/zip_random_unix.c -endif - SOURCES_C += $(LIBRETRODIR)/ext/glew/glew.c SOURCES_C += \ @@ -181,22 +47,6 @@ SOURCES_C += \ $(EXTDIR)/libkirk/ec.c \ $(EXTDIR)/libkirk/kirk_engine.c -SOURCES_C += \ - $(EXTDIR)/libpng17/png.c \ - $(EXTDIR)/libpng17/pngerror.c \ - $(EXTDIR)/libpng17/pngget.c \ - $(EXTDIR)/libpng17/pngmem.c \ - $(EXTDIR)/libpng17/pngread.c \ - $(EXTDIR)/libpng17/pngrio.c \ - $(EXTDIR)/libpng17/pngrtran.c \ - $(EXTDIR)/libpng17/pngrutil.c \ - $(EXTDIR)/libpng17/pngset.c \ - $(EXTDIR)/libpng17/pngtrans.c \ - $(EXTDIR)/libpng17/pngwio.c \ - $(EXTDIR)/libpng17/pngwrite.c \ - $(EXTDIR)/libpng17/pngwtran.c \ - $(EXTDIR)/libpng17/pngwutil.c - INCFLAGS += -I$(EXTDIR)/lua SOURCES_C += \ @@ -266,31 +116,6 @@ SOURCES_C += \ COREFLAGS += -DSTACK_LINE_READER_BUFFER_SIZE=1024 COREFLAGS += -DHTTPS_NOT_AVAILABLE -COREFLAGS += -DZ7_ST -INCFLAGS += -I$(EXTDIR)/libchdr/deps/lzma-24.05/include - -SOURCES_C += \ - $(EXTDIR)/libchdr/deps/lzma-24.05/src/Alloc.c \ - $(EXTDIR)/libchdr/deps/lzma-24.05/src/Bra.c \ - $(EXTDIR)/libchdr/deps/lzma-24.05/src/Bra86.c \ - $(EXTDIR)/libchdr/deps/lzma-24.05/src/BraIA64.c \ - $(EXTDIR)/libchdr/deps/lzma-24.05/src/CpuArch.c \ - $(EXTDIR)/libchdr/deps/lzma-24.05/src/Delta.c \ - $(EXTDIR)/libchdr/deps/lzma-24.05/src/LzFind.c \ - $(EXTDIR)/libchdr/deps/lzma-24.05/src/LzmaDec.c \ - $(EXTDIR)/libchdr/deps/lzma-24.05/src/LzmaEnc.c \ - $(EXTDIR)/libchdr/deps/lzma-24.05/src/Lzma86Dec.c \ - $(EXTDIR)/libchdr/deps/lzma-24.05/src/Sort.c - -INCFLAGS += -I$(EXTDIR)/libchdr/include - -SOURCES_C += \ - $(EXTDIR)/libchdr/src/libchdr_bitstream.c \ - $(EXTDIR)/libchdr/src/libchdr_cdrom.c \ - $(EXTDIR)/libchdr/src/libchdr_chd.c \ - $(EXTDIR)/libchdr/src/libchdr_flac.c \ - $(EXTDIR)/libchdr/src/libchdr_huffman.c - INCFLAGS += -I$(EXTDIR)/at3_standalone SOURCES_CXX += \ @@ -931,12 +756,6 @@ ifeq ($(WITH_DYNAREC),1) $(COREDIR)/MIPS/ARM/ArmRegCacheFPU.cpp \ $(EXTDIR)/disarm.cpp \ $(GPUCOMMONDIR)/VertexDecoderArm.cpp - - ifeq ($(HAVE_NEON),1) - SOURCES_C += $(EXTDIR)/libpng17/arm/arm_init.c \ - $(EXTDIR)/libpng17/arm/filter_neon_intrinsics.c - ASMFILES += $(EXTDIR)/libpng17/arm/filter_neon.S - endif else ifeq ($(TARGET_ARCH),arm64) DYNAFLAGS += -D_ARCH_64 SOURCES_CXX += $(COMMONDIR)/Arm64Emitter.cpp \ @@ -1068,64 +887,6 @@ SOURCES_CXX += \ $(LIBRETRODIR)/LibretroGLContext.cpp \ $(LIBRETRODIR)/LibretroGLCoreContext.cpp -SOURCES_C += $(ZSTDDIR)/common/debug.c \ - $(ZSTDDIR)/common/entropy_common.c \ - $(ZSTDDIR)/common/error_private.c \ - $(ZSTDDIR)/common/fse_decompress.c \ - $(ZSTDDIR)/common/pool.c \ - $(ZSTDDIR)/common/threading.c \ - $(ZSTDDIR)/common/xxhash.c \ - $(ZSTDDIR)/common/zstd_common.c \ - $(ZSTDDIR)/compress/fse_compress.c \ - $(ZSTDDIR)/compress/hist.c \ - $(ZSTDDIR)/compress/huf_compress.c \ - $(ZSTDDIR)/compress/zstd_compress.c \ - $(ZSTDDIR)/compress/zstd_compress_literals.c \ - $(ZSTDDIR)/compress/zstd_compress_sequences.c \ - $(ZSTDDIR)/compress/zstd_compress_superblock.c \ - $(ZSTDDIR)/compress/zstd_double_fast.c \ - $(ZSTDDIR)/compress/zstd_fast.c \ - $(ZSTDDIR)/compress/zstd_lazy.c \ - $(ZSTDDIR)/compress/zstd_ldm.c \ - $(ZSTDDIR)/compress/zstd_opt.c \ - $(ZSTDDIR)/compress/zstd_preSplit.c \ - $(ZSTDDIR)/compress/zstdmt_compress.c \ - $(ZSTDDIR)/decompress/huf_decompress.c \ - $(ZSTDDIR)/decompress/zstd_ddict.c \ - $(ZSTDDIR)/decompress/zstd_decompress.c \ - $(ZSTDDIR)/decompress/zstd_decompress_block.c \ - $(ZSTDDIR)/dictBuilder/cover.c \ - $(ZSTDDIR)/dictBuilder/divsufsort.c \ - $(ZSTDDIR)/dictBuilder/fastcover.c \ - $(ZSTDDIR)/dictBuilder/zdict.c - -# zstd enables its x86-64 asm for any GNU C compiler, MinGW included; only -# MSVC builds it without. -ifeq (,$(findstring msvc,$(platform))) -ifeq ($(TARGET_ARCH),x86_64) -SOURCES_C += $(ZSTDDIR)/decompress/huf_decompress_amd64.S -endif -endif - -ifneq ($(STATIC_LINKING), 1) -SOURCES_C += \ - $(EXTDIR)/zlib/adler32.c \ - $(EXTDIR)/zlib/compress.c \ - $(EXTDIR)/zlib/crc32.c \ - $(EXTDIR)/zlib/deflate.c \ - $(EXTDIR)/zlib/gzclose.c \ - $(EXTDIR)/zlib/gzlib.c \ - $(EXTDIR)/zlib/gzread.c \ - $(EXTDIR)/zlib/gzwrite.c \ - $(EXTDIR)/zlib/inffast.c \ - $(EXTDIR)/zlib/inflate.c \ - $(EXTDIR)/zlib/inftrees.c \ - $(EXTDIR)/zlib/trees.c \ - $(EXTDIR)/zlib/uncompr.c \ - $(EXTDIR)/zlib/zutil.c -endif - -ifeq ($(HAVE_LIBRETRO_VFS), 1) COREFLAGS += -DHAVE_LIBRETRO_VFS SOURCES_C += $(LIBRETROCOMMONDIR)/compat/compat_posix_string.c \ $(LIBRETROCOMMONDIR)/compat/fopen_utf8.c \ @@ -1138,7 +899,24 @@ SOURCES_C += $(LIBRETROCOMMONDIR)/compat/compat_posix_string.c \ $(LIBRETROCOMMONDIR)/string/rstrtod.c \ $(LIBRETROCOMMONDIR)/time/rtime.c \ $(LIBRETROCOMMONDIR)/vfs/vfs_implementation.c -endif + +# Codecs: zlib-format deflate, zstd, CHD, zip and PNG. +COREFLAGS += -DHAVE_RZSTD -DHAVE_RFLAC -DHAVE_RCHD_DEFLATE -DHAVE_RCHD_LZMA -DHAVE_RCHD_FLAC -DHAVE_RCHD_ZSTD +SOURCES_C += $(LIBRETROCOMMONDIR)/encodings/encoding_crc32.c \ + $(LIBRETROCOMMONDIR)/encodings/encoding_deflate.c \ + $(LIBRETROCOMMONDIR)/encodings/encoding_huffman.c \ + $(LIBRETROCOMMONDIR)/encodings/encoding_rzstd.c \ + $(LIBRETROCOMMONDIR)/formats/7z/r7z_lzma.c \ + $(LIBRETROCOMMONDIR)/formats/chd/rchd.c \ + $(LIBRETROCOMMONDIR)/formats/flac/rflac.c \ + $(LIBRETROCOMMONDIR)/formats/png/rpng.c \ + $(LIBRETROCOMMONDIR)/formats/png/rpng_encode.c \ + $(LIBRETROCOMMONDIR)/formats/zip/rzip_archive.c \ + $(LIBRETROCOMMONDIR)/streams/interface_stream.c \ + $(LIBRETROCOMMONDIR)/streams/memory_stream.c \ + $(LIBRETROCOMMONDIR)/streams/trans_stream.c \ + $(LIBRETROCOMMONDIR)/streams/trans_stream_deflate.c \ + $(LIBRETROCOMMONDIR)/streams/trans_stream_pipe.c SOURCES_C += $(LIBRETROCOMMONDIR)/features/features_cpu.c \ $(LIBRETROCOMMONDIR)/queues/retro_spsc.c \ diff --git a/libretro/test/.gitignore b/libretro/test/.gitignore new file mode 100644 index 0000000000..c625c8676e --- /dev/null +++ b/libretro/test/.gitignore @@ -0,0 +1,4 @@ +codectest +blocktest +lrtest +*.o diff --git a/libretro/test/blocktest.cpp b/libretro/test/blocktest.cpp new file mode 100644 index 0000000000..6f6235926b --- /dev/null +++ b/libretro/test/blocktest.cpp @@ -0,0 +1,68 @@ +// Reads an image (ISO, CSO, CHD, or an ISO inside a zip) through the loader chain +// and block devices, and compares every block with the plain ISO. +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Common/File/Path.h" +#include "Core/Loaders.h" +#include "Core/FileSystems/BlockDevices.h" + +static std::vector ReadAll(const char *path) { + std::ifstream f(path, std::ios::binary); + return std::vector((std::istreambuf_iterator(f)), std::istreambuf_iterator()); +} + +int main(int argc, char **argv) { + if (argc < 3) { printf("usage: blocktest ref.iso image\n"); return 2; } + std::vector ref = ReadAll(argv[1]); + const u32 refBlocks = (u32)(ref.size() / 2048); + std::string err; + IdentifiedFileType type; + FileLoader *loader = ResolveFileLoaderTarget(ConstructFileLoader(Path(argv[2])), &type, &err); + std::unique_ptr loaderOwner(loader); + if (!loader || !loader->Exists()) { printf("FAIL open %s: %s\n", argv[2], err.c_str()); return 1; } + std::unique_ptr dev(ConstructBlockDevice(loader, &err)); + if (!dev) { printf("FAIL device %s: %s\n", argv[2], err.c_str()); return 1; } + if (dev->GetNumBlocks() != refBlocks) { printf("FAIL blocks %u vs %u\n", dev->GetNumBlocks(), refBlocks); return 1; } + std::vector buf(2048 * 64); + int bad = 0; + // Sequential, mixed run lengths. + std::mt19937 rng(42); + for (u32 b = 0; b < refBlocks;) { + int n = 1 + rng() % 40; + if (b + n > refBlocks) n = refBlocks - b; + if (!dev->ReadBlocks(b, n, buf.data()) || memcmp(buf.data(), &ref[(size_t)b * 2048], (size_t)n * 2048) != 0) { + if (bad++ < 5) printf("mismatch seq at %u (+%d)\n", b, n); + } + b += n; + } + // Random single and multi-block reads. + for (int i = 0; i < 4000; i++) { + u32 b = rng() % refBlocks; + int n = (i & 1) ? 1 : 1 + rng() % 64; + if (b + n > refBlocks) n = refBlocks - b; + bool ok = n == 1 ? dev->ReadBlock(b, buf.data()) : dev->ReadBlocks(b, n, buf.data()); + if (!ok || memcmp(buf.data(), &ref[(size_t)b * 2048], (size_t)n * 2048) != 0) { + if (bad++ < 10) printf("mismatch rnd at %u (+%d)\n", b, n); + } + } + // Byte ranges at any alignment, as file reads ask for them. + std::vector bytes(300000); + for (int i = 0; i < 2000; i++) { + const u64 total = (u64)refBlocks * 2048; + u64 off = ((u64)rng() << 16 ^ rng()) % total; + size_t len = (i % 3 == 0) ? rng() % 64 : rng() % bytes.size(); + if (off + len > total) len = (size_t)(total - off); + if (!dev->ReadBytes(off, len, bytes.data()) || memcmp(bytes.data(), &ref[off], len) != 0) { + if (bad++ < 15) printf("mismatch bytes at %llu (+%zu)\n", (unsigned long long)off, len); + } + } + printf("%s %s: %u blocks, %d bad\n", bad ? "FAIL" : "PASS", argv[2], refBlocks, bad); + return bad ? 1 : 0; +} diff --git a/libretro/test/codectest.cpp b/libretro/test/codectest.cpp new file mode 100644 index 0000000000..d65ddb059b --- /dev/null +++ b/libretro/test/codectest.cpp @@ -0,0 +1,139 @@ +// Checks the deflate, zstd, PNG and zip code against vectors made by make_vectors.py. +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "Common/Data/Encoding/Compression.h" +#include "Common/Data/Format/PNGLoad.h" +#include "Common/File/VFS/ZipFileReader.h" + +static std::string Read(const std::string &p) { + std::ifstream f(p, std::ios::binary); + return std::string((std::istreambuf_iterator(f)), std::istreambuf_iterator()); +} +static int fails = 0; +#define CHECK(c, ...) do { if (!(c)) { fails++; printf("FAIL: " __VA_ARGS__); printf("\n"); } } while (0) + +int main(int argc, char **argv) { + std::string dir = argv[1]; + const char *names[] = { "text", "rand", "zero", "small", "empty" }; + for (const char *n : names) { + std::string raw = Read(dir + "/in/" + n + ".raw"); + struct { const char *ext; int wb; } fmts[] = { { "deflate", -15 }, { "zlib", 15 }, { "gz", 31 }, { "zlib", 47 }, { "gz", 47 } }; + for (auto &f : fmts) { + std::string c = Read(dir + "/in/" + n + "." + f.ext); + std::vector out(raw.size() + 16); + size_t used = 0; + int64_t got = InflateBuffer(f.wb, (const uint8_t *)c.data(), c.size(), out.data(), out.size(), &used); + CHECK(got == (int64_t)raw.size() && !memcmp(out.data(), raw.data(), raw.size()), "inflate %s.%s wb=%d got=%lld", n, f.ext, f.wb, (long long)got); + CHECK(used == c.size(), "inflate %s.%s consumed %zu of %zu", n, f.ext, used, c.size()); + if (!raw.empty()) { + // One byte short must fail, not truncate. + int64_t shortGot = InflateBuffer(f.wb, (const uint8_t *)c.data(), c.size(), out.data(), raw.size() - 1); + CHECK(shortGot < 0, "inflate %s.%s short output accepted", n, f.ext); + int64_t trunc = InflateBuffer(f.wb, (const uint8_t *)c.data(), c.size() / 2, out.data(), out.size()); + CHECK(trunc < 0, "inflate %s.%s truncated input accepted", n, f.ext); + } + } + std::string s; + CHECK(decompress_string(Read(dir + "/in/" + n + ".zlib"), &s) && s == raw, "decompress_string zlib %s", n); + if (!raw.empty()) { + CHECK(decompress_string(Read(dir + "/in/" + n + ".gz"), &s) && s == raw, "decompress_string gz %s", n); + std::string z, back; + CHECK(compress_string(raw, &z, 9) && decompress_string(z, &back) && back == raw, "zlib roundtrip %s", n); + CHECK(compress_string(raw, &z, 6, 31) && decompress_string(z, &back) && back == raw, "gzip roundtrip %s", n); + std::ofstream(dir + "/out_" + n + ".gz", std::ios::binary) << z; + } + unsigned adler = 0, crc = 0; + sscanf(Read(dir + "/in/" + n + ".adler").c_str(), "%x", &adler); + sscanf(Read(dir + "/in/" + n + ".crc").c_str(), "%x", &crc); + CHECK(Adler32(1, (const uint8_t *)raw.data(), raw.size()) == adler, "adler32 %s", n); + CHECK(encoding_crc32(0, (const uint8_t *)raw.data(), raw.size()) == crc, "crc32 %s", n); + for (int lvl : { 1, 3, 9, 19 }) { + std::string c = Read(dir + "/in/" + n + ".l" + std::to_string(lvl) + ".zst"); + std::vector out(raw.size() + 1); + size_t wrote = 0; + int r = rzstd_decode(out.data(), out.size(), (const uint8_t *)c.data(), c.size(), &wrote); + CHECK(r == RZSTD_PROCESS_END && wrote == raw.size() && !memcmp(out.data(), raw.data(), raw.size()), "rzstd decode %s l%d", n, lvl); + } + { + std::vector enc(rzstd_compress_bound(raw.size())); + size_t encLen = 0; + int r = rzstd_encode(enc.data(), enc.size(), (const uint8_t *)raw.data(), raw.size(), 3, &encLen); + CHECK(r == RZSTD_PROCESS_END, "rzstd encode %s", n); + std::ofstream(dir + "/out_" + n + ".zst", std::ios::binary).write((const char *)enc.data(), encLen); + std::vector back(raw.size() + 1); + size_t wrote = 0; + r = rzstd_decode(back.data(), back.size(), enc.data(), encLen, &wrote); + CHECK(r == RZSTD_PROCESS_END && wrote == raw.size() && !memcmp(back.data(), raw.data(), raw.size()), "rzstd roundtrip %s", n); + } + } + const char *pngs[] = { "rgba", "rgb", "gray", "graya", "pal", "paltrns", "solid", "gray16" }; + for (const char *n : pngs) { + std::string p = Read(dir + "/png/" + n + ".png"); + std::string want = Read(dir + "/png/" + n + ".png.rgba"); + int w = 0, h = 0; + unsigned char *img = nullptr; + int ok = pngLoadPtr((const unsigned char *)p.data(), p.size(), &w, &h, &img); + CHECK(ok == 1 && (size_t)w * h * 4 == want.size() && !memcmp(img, want.data(), want.size()), "png decode %s (%d %dx%d)", n, ok, w, h); + if (ok == 1) { + std::vector enc; + CHECK(pngEncode(&enc, img, w, h), "png encode %s", n); + int w2 = 0, h2 = 0; + unsigned char *img2 = nullptr; + CHECK(pngLoadPtr(enc.data(), enc.size(), &w2, &h2, &img2) == 1 && w2 == w && h2 == h && !memcmp(img, img2, (size_t)w * h * 4), "png roundtrip %s", n); + std::ofstream(dir + "/out_" + n + ".png", std::ios::binary).write((const char *)enc.data(), enc.size()); + free(img2); + // Too large for the caller's limits is refused. + CHECK(pngLoadPtr((const unsigned char *)p.data(), p.size(), &w2, &h2, &img2, w - 1, h) == 0, "png limit %s", n); + } + free(img); + // Truncated file fails cleanly. + CHECK(pngLoadPtr((const unsigned char *)p.data(), p.size() / 2, &w, &h, &img) == 0, "png truncated %s", n); + } + { + ZipFileReader *z = ZipFileReader::Create(Path(dir + "/vfs.zip"), "", true); + CHECK(z != nullptr, "zip open"); + if (z) { + size_t sz = 0; + uint8_t *d = z->ReadFile("dir/sub/deflated.txt", &sz); + std::string text = Read(dir + "/in/text.raw"); + CHECK(d && sz == text.size() && !memcmp(d, text.data(), sz), "zip deflated read"); + delete[] d; + d = z->ReadFile("DIR/stored.BIN", &sz); + std::string rnd = Read(dir + "/in/rand.raw").substr(0, 5000); + CHECK(d && sz == 5000 && !memcmp(d, rnd.data(), sz), "zip stored nocase read"); + delete[] d; + std::vector list; + CHECK(z->GetFileListing("dir", &list, nullptr) && list.size() == 2, "zip listing %zu", list.size()); + File::FileInfo info; + CHECK(z->GetFileInfo("textures.ini", &info) && info.size == 9, "zip info"); + CHECK(!z->GetFileInfo("missing", &info), "zip missing"); + VFSFileReference *ref = z->GetFile("dir/sub/deflated.txt"); + CHECK(ref, "zip ref"); + if (ref) { + size_t size = 0; + VFSOpenFile *of = z->OpenFileForRead(ref, &size); + std::string part(1000, 0), rest(size, 0); + CHECK(z->Read(of, &part[0], 1000) == 1000 && part == text.substr(0, 1000), "zip partial read"); + CHECK(z->Read(of, &rest[0], size) == size - 1000 && rest.substr(0, size - 1000) == text.substr(1000), "zip rest read"); + z->Rewind(of); + CHECK(z->Read(of, &rest[0], size) == size && rest == text, "zip rewind read"); + z->CloseFile(of); + of = z->OpenFileForRead(ref, &size); + CHECK(z->Read(of, &rest[0], size) == size && rest == text, "zip whole read"); + z->CloseFile(of); + z->ReleaseFile(ref); + } + delete z; + } + } + printf("%s (%d failures)\n", fails ? "FAIL" : "PASS", fails); + return fails ? 1 : 0; +} diff --git a/libretro/test/lrtest.c b/libretro/test/lrtest.c new file mode 100644 index 0000000000..d9cedb7d39 --- /dev/null +++ b/libretro/test/lrtest.c @@ -0,0 +1,282 @@ +/* Headless libretro frontend for running pspautotests against the core. + * Prints the emulated program's stdout/stderr lines, then a summary with + * frame/audio counts and FNV-1a digests of the video and audio output. */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include "libretro.h" + +static bool shutdown_requested; +static bool exit_seen; +static unsigned pixel_format = RETRO_PIXEL_FORMAT_0RGB1555; +static uint64_t video_digest = 1469598103934665603ULL; +static uint64_t audio_digest = 1469598103934665603ULL; +static unsigned long frames_video, frames_dupe; +static unsigned long audio_frames; +static const char *system_dir; +static const char *save_dir; +static FILE *log_out; +static bool verbose; + +static void fnv(uint64_t *h, const void *data, size_t len) +{ + const unsigned char *p = (const unsigned char *)data; + size_t i; + for (i = 0; i < len; i++) + { + *h ^= p[i]; + *h *= 1099511628211ULL; + } +} + +static void core_log(enum retro_log_level level, const char *fmt, ...) +{ + char buf[4096]; + va_list ap; + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + if (strstr(buf, "sceKernelExitGame")) + exit_seen = true; + /* The emulated program's output is logged as "stdout: ..." / "stderr: ...". */ + { + const char *p = strstr(buf, "stdout: "); + if (!p) + p = strstr(buf, "stderr: "); + if (p) + fputs(p, stdout); + } + if (log_out) + fputs(buf, log_out); + if (verbose) + fputs(buf, stderr); + (void)level; +} + +static const char *option_value(const char *key) +{ + /* LRTEST_OPT="key=value;key=value" */ + static char storage[64][256]; + static int used; + const char *env = getenv("LRTEST_OPT"); + size_t klen = strlen(key); + while (env && *env) + { + const char *end = strchr(env, ';'); + size_t len = end ? (size_t)(end - env) : strlen(env); + if (len > klen && !strncmp(env, key, klen) && env[klen] == '=') + { + char *dst = storage[used++ & 63]; + size_t vlen = len - klen - 1; + if (vlen > 255) + vlen = 255; + memcpy(dst, env + klen + 1, vlen); + dst[vlen] = '\0'; + return dst; + } + env = end ? end + 1 : NULL; + } + return NULL; +} + +static bool environ_cb(unsigned cmd, void *data) +{ + switch (cmd) + { + case RETRO_ENVIRONMENT_GET_LOG_INTERFACE: + ((struct retro_log_callback *)data)->log = core_log; + return true; + case RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY: + *(const char **)data = system_dir; + return true; + case RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY: + *(const char **)data = save_dir; + return true; + case RETRO_ENVIRONMENT_SET_PIXEL_FORMAT: + pixel_format = *(const enum retro_pixel_format *)data; + return true; + case RETRO_ENVIRONMENT_GET_VARIABLE: + { + struct retro_variable *var = (struct retro_variable *)data; + var->value = option_value(var->key); + return var->value != NULL; + } + case RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE: + *(bool *)data = false; + return true; + case RETRO_ENVIRONMENT_SHUTDOWN: + shutdown_requested = true; + return true; + case RETRO_ENVIRONMENT_GET_INPUT_BITMASKS: + return true; + case RETRO_ENVIRONMENT_SET_GEOMETRY: + case RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO: + case RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS: + case RETRO_ENVIRONMENT_SET_CONTROLLER_INFO: + case RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME: + return true; + case RETRO_ENVIRONMENT_SET_HW_RENDER: + case RETRO_ENVIRONMENT_GET_PREFERRED_HW_RENDER: + /* Software rendering only. */ + return false; + default: + return false; + } +} + +static void video_cb(const void *data, unsigned width, unsigned height, size_t pitch) +{ + unsigned y; + unsigned bpp = pixel_format == RETRO_PIXEL_FORMAT_XRGB8888 ? 4 : 2; + if (!data) + { + frames_dupe++; + return; + } + frames_video++; + for (y = 0; y < height; y++) + fnv(&video_digest, (const char *)data + y * pitch, (size_t)width * bpp); +} + +static size_t audio_batch_cb(const int16_t *data, size_t frames) +{ + fnv(&audio_digest, data, frames * 4); + audio_frames += frames; + return frames; +} + +static void audio_cb(int16_t l, int16_t r) +{ + int16_t s[2]; + s[0] = l; + s[1] = r; + audio_batch_cb(s, 1); +} + +static void input_poll_cb(void) { } +static int16_t input_state_cb(unsigned port, unsigned device, unsigned index, unsigned id) { return 0; } + +#define SYM(name) do { *(void **)&p_##name = dlsym(h, #name); if (!p_##name) { fprintf(stderr, "missing %s\n", #name); return 2; } } while (0) + +int main(int argc, char **argv) +{ + void (*p_retro_init)(void); + void (*p_retro_deinit)(void); + void (*p_retro_set_environment)(retro_environment_t); + void (*p_retro_set_video_refresh)(retro_video_refresh_t); + void (*p_retro_set_audio_sample)(retro_audio_sample_t); + void (*p_retro_set_audio_sample_batch)(retro_audio_sample_batch_t); + void (*p_retro_set_input_poll)(retro_input_poll_t); + void (*p_retro_set_input_state)(retro_input_state_t); + bool (*p_retro_load_game)(const struct retro_game_info *); + void (*p_retro_unload_game)(void); + void (*p_retro_run)(void); + size_t (*p_retro_serialize_size)(void); + bool (*p_retro_serialize)(void *, size_t); + bool (*p_retro_unserialize)(const void *, size_t); + void (*p_retro_reset)(void); + struct retro_game_info info; + void *h; + int max_frames, i; + int state_every = 0; + int reset_at = -1; + int frames_after_exit = 5; + int ran = 0; + int boot_polls = 0; + bool booted = false; + + if (argc < 4) + { + fprintf(stderr, "usage: %s core.so content max_frames [state_every] [reset_at]\n", argv[0]); + return 2; + } + max_frames = atoi(argv[3]); + if (argc > 4) + state_every = atoi(argv[4]); + if (argc > 5) + reset_at = atoi(argv[5]); + system_dir = getenv("LRTEST_SYSTEM") ? getenv("LRTEST_SYSTEM") : "/tmp"; + save_dir = getenv("LRTEST_SAVE") ? getenv("LRTEST_SAVE") : "/tmp"; + verbose = getenv("LRTEST_VERBOSE") != NULL; + if (getenv("LRTEST_LOG")) + log_out = fopen(getenv("LRTEST_LOG"), "w"); + + h = dlopen(argv[1], RTLD_NOW | RTLD_LOCAL); + if (!h) + { + fprintf(stderr, "dlopen: %s\n", dlerror()); + return 2; + } + SYM(retro_init); SYM(retro_deinit); SYM(retro_set_environment); + SYM(retro_set_video_refresh); SYM(retro_set_audio_sample); + SYM(retro_set_audio_sample_batch); SYM(retro_set_input_poll); + SYM(retro_set_input_state); SYM(retro_load_game); SYM(retro_unload_game); + SYM(retro_run); SYM(retro_serialize_size); SYM(retro_serialize); + SYM(retro_unserialize); SYM(retro_reset); + + p_retro_set_environment(environ_cb); + p_retro_set_video_refresh(video_cb); + p_retro_set_audio_sample(audio_cb); + p_retro_set_audio_sample_batch(audio_batch_cb); + p_retro_set_input_poll(input_poll_cb); + p_retro_set_input_state(input_state_cb); + p_retro_init(); + + memset(&info, 0, sizeof(info)); + info.path = argv[2]; + if (!p_retro_load_game(&info)) + { + fprintf(stderr, "retro_load_game failed\n"); + p_retro_deinit(); + return 3; + } + + for (i = 0; i < max_frames && !shutdown_requested; i++) + { + unsigned long before = frames_video + audio_frames; + p_retro_run(); + /* While booting, retro_run returns straight away with a dupe frame. + * Those don't count; give up after 60 s of them. */ + if (frames_video + audio_frames == before && !booted) + { + if (++boot_polls > 60000) + { + fprintf(stderr, "boot timeout\n"); + break; + } + usleep(1000); + i--; + continue; + } + booted = true; + ran++; + if (exit_seen && --frames_after_exit <= 0) + break; + if (state_every > 0 && i > 0 && i % state_every == 0) + { + size_t size = p_retro_serialize_size(); + void *buf = malloc(size); + if (buf && p_retro_serialize(buf, size)) + p_retro_unserialize(buf, size); + free(buf); + } + if (i == reset_at) + p_retro_reset(); + } + + p_retro_unload_game(); + p_retro_deinit(); + printf("@@ frames=%d video=%lu dupe=%lu audio_frames=%lu video_digest=%016llx audio_digest=%016llx exit=%d\n", + ran, frames_video, frames_dupe, audio_frames, + (unsigned long long)video_digest, (unsigned long long)audio_digest, exit_seen ? 1 : 0); + if (log_out) + fclose(log_out); + dlclose(h); + return 0; +} diff --git a/libretro/test/make_vectors.py b/libretro/test/make_vectors.py new file mode 100755 index 0000000000..6a6399e434 --- /dev/null +++ b/libretro/test/make_vectors.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python3 +# Test data for codectest and blocktest: python3 make_vectors.py outdir eboot.prx +# Needs Pillow, zstandard, genisoimage, chdman and zip. +import gzip, os, random, struct, subprocess, sys, zipfile, zlib +import zstandard +from PIL import Image + +out, prx = sys.argv[1], sys.argv[2] +os.makedirs(out, exist_ok=True) +rnd = random.Random(7) + +# Raw blobs in every zlib-family wrapper and several zstd levels. +os.makedirs(os.path.join(out, 'in'), exist_ok=True) +blobs = { + 'text': b''.join(rnd.choice([b'psp ', b'umd ', b'sector ', b'\n', b'zlib ']) for _ in range(200000)), + 'rand': rnd.randbytes(300000), + 'zero': bytes(1 << 20), + 'small': b'hello', + 'empty': b'', +} +for k, v in blobs.items(): + base = os.path.join(out, 'in', k) + open(base + '.raw', 'wb').write(v) + c = zlib.compressobj(9, zlib.DEFLATED, -15) + open(base + '.deflate', 'wb').write(c.compress(v) + c.flush()) + open(base + '.zlib', 'wb').write(zlib.compress(v, 6)) + open(base + '.gz', 'wb').write(gzip.compress(v, 9)) + for lvl in (1, 3, 9, 19): + cctx = zstandard.ZstdCompressor(level=lvl, write_checksum=True, write_content_size=True) + open(base + '.l%d.zst' % lvl, 'wb').write(cctx.compress(v)) + open(base + '.adler', 'w').write('%08x' % zlib.adler32(v)) + open(base + '.crc', 'w').write('%08x' % zlib.crc32(v)) + +# PNGs in each colour type, with the RGBA they should decode to. +pngdir = os.path.join(out, 'png') +os.makedirs(pngdir, exist_ok=True) +img = Image.new('RGBA', (61, 47)) +img.putdata([((x * 4) & 255, (y * 5) & 255, (x * y) & 255, (x + y * 3) & 255) for y in range(47) for x in range(61)]) +img.save(os.path.join(pngdir, 'rgba.png')) +img.convert('RGB').save(os.path.join(pngdir, 'rgb.png')) +img.convert('L').save(os.path.join(pngdir, 'gray.png')) +img.convert('LA').save(os.path.join(pngdir, 'graya.png')) +img.convert('P', palette=Image.ADAPTIVE).save(os.path.join(pngdir, 'pal.png')) +img.convert('P', palette=Image.ADAPTIVE).save(os.path.join(pngdir, 'paltrns.png'), transparency=0) +Image.new('RGB', (300, 200), (10, 200, 30)).save(os.path.join(pngdir, 'solid.png'), optimize=True) +for n in os.listdir(pngdir): + if n.endswith('.png'): + open(os.path.join(pngdir, n + '.rgba'), 'wb').write(Image.open(os.path.join(pngdir, n)).convert('RGBA').tobytes()) +# 16 bits per sample decodes to the high byte. +g16 = [(i * 97) % 65536 for i in range(40 * 30)] +Image.frombytes('I;16', (40, 30), struct.pack('<%dH' % len(g16), *g16)).save(os.path.join(pngdir, 'gray16.png')) +open(os.path.join(pngdir, 'gray16.png.rgba'), 'wb').write(b''.join(bytes((v >> 8, v >> 8, v >> 8, 255)) for v in g16)) + +# A zip for the VFS reader: directories, stored and deflated members. +with zipfile.ZipFile(os.path.join(out, 'vfs.zip'), 'w') as z: + z.writestr('textures.ini', b'[hashes]\n') + z.writestr('dir/', b'') + z.writestr(zipfile.ZipInfo('dir/Stored.bin'), blobs['rand'][:5000], compress_type=zipfile.ZIP_STORED) + z.writestr('dir/sub/deflated.txt', blobs['text'], compress_type=zipfile.ZIP_DEFLATED) + z.writestr('empty.txt', b'') + +# A bootable disc image, and the same image as CSO, CHD and inside zips. +root = os.path.join(out, 'isoroot') +os.makedirs(os.path.join(root, 'PSP_GAME', 'SYSDIR'), exist_ok=True) +os.makedirs(os.path.join(root, 'DATA'), exist_ok=True) +open(os.path.join(root, 'PSP_GAME', 'SYSDIR', 'EBOOT.BIN'), 'wb').write(open(prx, 'rb').read()) + +def sfo(entries): + keys = b''; data = b''; idx = b'' + for k, v in entries: + if isinstance(v, int): + raw = struct.pack('= block: + index.append((pos + len(body)) | 0x80000000); body += chunk + else: + index.append(pos + len(body)); body += comp + index.append(pos + len(body)) + with open(dst, 'wb') as f: + f.write(hdr); f.write(struct.pack('<%dI' % len(index), *index)); f.write(body) + +cso(iso, os.path.join(out, 'test.cso'), 2048) +cso(iso, os.path.join(out, 'test16k.cso'), 16384) +for name, extra in [('test.chd', []), ('test_zstd.chd', ['-c', 'zstd']), ('test_zlib.chd', ['-c', 'zlib']), + ('test_lzma.chd', ['-c', 'lzma']), ('test_huff.chd', ['-c', 'huff']), + ('test_big.chd', ['-hs', '65536', '-c', 'zstd,lzma'])]: + subprocess.check_call(['chdman', 'createdvd', '-f', '-i', iso, '-o', os.path.join(out, name)] + extra, + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) +for name, level in [('stored.zip', '-0'), ('deflated.zip', '-9')]: + path = os.path.join(out, name) + if os.path.exists(path): + os.remove(path) + subprocess.check_call(['zip', '-q', level, '-j', path, iso]) diff --git a/libretro/test/run.sh b/libretro/test/run.sh new file mode 100755 index 0000000000..8a60e76b46 --- /dev/null +++ b/libretro/test/run.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Image, codec and boot checks for the core. Run from the repo root after +# "make -C libretro test-tools". Needs what make_vectors.py needs. +set -e +here=$(cd "$(dirname "$0")" && pwd) +root=$(cd "$here/../.." && pwd) +data=${1:-$(mktemp -d)} +python3 "$here/make_vectors.py" "$data" "$root/pspautotests/tests/cpu/cpu_alu/cpu_alu.prx" + +"$here/codectest" "$data" +for img in test.iso test.cso test16k.cso test.chd test_zstd.chd test_zlib.chd test_lzma.chd test_huff.chd test_big.chd stored.zip deflated.zip; do + "$here/blocktest" "$data/test.iso" "$data/$img" +done + +# Every container boots to the same exit, frames and output as the ISO. +sys=$(mktemp -d) +mkdir -p "$sys/PPSSPP" +cp -r "$root/assets/." "$sys/PPSSPP/" +ref= +for img in test.iso test.cso test.chd test_zstd.chd stored.zip deflated.zip; do + save=$(mktemp -d) + line=$(LRTEST_SYSTEM=$sys LRTEST_SAVE=$save "$here/lrtest" "$root/libretro/ppsspp_libretro.so" "$data/$img" 600 | grep '^@@' | sed -E 's/ dupe=[0-9]+//') + rm -rf "$save" + echo "$img $line" + case "$line" in *exit=1*) ;; *) echo "FAIL: $img did not run to its exit"; exit 1;; esac + [ -z "$ref" ] && ref=$line + [ "$line" = "$ref" ] || { echo "FAIL: $img differs from test.iso"; exit 1; } +done +echo "All image and codec checks passed." diff --git a/unittest/TestZipSlip.cpp b/unittest/TestZipSlip.cpp index 40a6da70d8..599a1b7104 100644 --- a/unittest/TestZipSlip.cpp +++ b/unittest/TestZipSlip.cpp @@ -1,7 +1,11 @@ -#include "ext/libzip/zip.h" +#include +#include + +#include #include "Common/File/FileUtil.h" #include "Common/File/Path.h" +#include "Common/File/VFS/ZipFileReader.h" #include "Core/Loaders.h" #include "Core/Util/GameManager.h" #include "Core/Util/PathUtil.h" @@ -23,23 +27,28 @@ static bool TestHasParentDirComponent() { return true; } -// Creates a zip archive at the given path with one entry of the given name. +// Creates a zip archive at the given path with one stored entry of the given name. +static void Put16(std::string &s, uint32_t v) { s += (char)(v & 0xFF); s += (char)((v >> 8) & 0xFF); } +static void Put32(std::string &s, uint32_t v) { Put16(s, v & 0xFFFF); Put16(s, v >> 16); } + static bool CreateZipWithEntry(const Path &zipPath, const std::string &entryName, const std::string &contents) { - int errorp = 0; - zip_t *z = zip_open(zipPath.c_str(), ZIP_CREATE | ZIP_TRUNCATE, &errorp); - if (!z) - return false; - zip_source_t *source = zip_source_buffer(z, contents.data(), contents.size(), 0); - if (!source) { - zip_close(z); - return false; - } - if (zip_file_add(z, entryName.c_str(), source, ZIP_FL_ENC_UTF_8) < 0) { - zip_source_free(source); - zip_close(z); - return false; - } - return zip_close(z) == 0; + const uint32_t crc = encoding_crc32(0, (const uint8_t *)contents.data(), contents.size()); + std::string zip; + Put32(zip, 0x04034b50); Put16(zip, 20); Put16(zip, 0); Put16(zip, 0); Put16(zip, 0); Put16(zip, 0); + Put32(zip, crc); Put32(zip, (uint32_t)contents.size()); Put32(zip, (uint32_t)contents.size()); + Put16(zip, (uint32_t)entryName.size()); Put16(zip, 0); + zip += entryName; + zip += contents; + const uint32_t cdOffset = (uint32_t)zip.size(); + Put32(zip, 0x02014b50); Put16(zip, 20); Put16(zip, 20); Put16(zip, 0); Put16(zip, 0); Put16(zip, 0); Put16(zip, 0); + Put32(zip, crc); Put32(zip, (uint32_t)contents.size()); Put32(zip, (uint32_t)contents.size()); + Put16(zip, (uint32_t)entryName.size()); Put16(zip, 0); Put16(zip, 0); Put16(zip, 0); Put16(zip, 0); + Put32(zip, 0); Put32(zip, 0); + zip += entryName; + const uint32_t cdSize = (uint32_t)zip.size() - cdOffset; + Put32(zip, 0x06054b50); Put16(zip, 0); Put16(zip, 0); Put16(zip, 1); Put16(zip, 1); + Put32(zip, cdSize); Put32(zip, cdOffset); Put16(zip, 0); + return File::WriteDataToFile(false, zip.data(), zip.size(), zipPath); } // Crafts a zip with a parent-directory entry and verifies ExtractZipContents @@ -55,9 +64,8 @@ static bool TestZipSlipExtraction() { Path zipPath = tempRoot / "bad.zip"; EXPECT_TRUE(CreateZipWithEntry(zipPath, "../evil.txt", "should not escape")); - int errorp = 0; - zip_t *z = zip_open(zipPath.c_str(), 0, &errorp); - EXPECT_TRUE(z != nullptr); + ZipContainer z(zipPath); + EXPECT_TRUE((bool)z); ZipFileInfo info; info.numFiles = 1; @@ -66,7 +74,7 @@ static bool TestZipSlipExtraction() { GameManager manager; EXPECT_TRUE(manager.ExtractZipContents(z, destDir, info, true)); - zip_close(z); + z.close(); // The malicious file must not have been written outside destDir. // A naive "dest / ../evil.txt" would land here.