mirror of
https://github.com/opencv/opencv.git
synced 2026-11-10 18:49:00 -06:00
Compare commits
365 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2853bdce0d | ||
|
|
a0fbf9c283 | ||
|
|
55ff746075 | ||
|
|
4bea6a5f0e | ||
|
|
b41241fa41 | ||
|
|
db0380a7a0 | ||
|
|
54142329e9 | ||
|
|
9231ce54bf | ||
|
|
b0af5ebf70 | ||
|
|
e7d32cb9db | ||
|
|
0cbde9ceeb | ||
|
|
173a1cf711 | ||
|
|
ccf4ca3243 | ||
|
|
9d4808bef8 | ||
|
|
103f61f252 | ||
|
|
6fa237896a | ||
|
|
5f20f48a5b | ||
|
|
131f1745a9 | ||
|
|
a1f93dd19c | ||
|
|
e4b73b28e2 | ||
|
|
6d381e029f | ||
|
|
199fd78571 | ||
|
|
6f461fc85a | ||
|
|
d195a5ad7e | ||
|
|
af3b2f2b80 | ||
|
|
187e2e9694 | ||
|
|
c7c32d37eb | ||
|
|
5584875dba | ||
|
|
c55f0e9418 | ||
|
|
099dde0419 | ||
|
|
981ff0ff05 | ||
|
|
57a97025ef | ||
|
|
50cfa93293 | ||
|
|
77d9a8e69c | ||
|
|
f2efb42906 | ||
|
|
58e52e9d3c | ||
|
|
fa3037533e | ||
|
|
d9b582d464 | ||
|
|
91ca181f19 | ||
|
|
1a97289f43 | ||
|
|
9171eaf2fa | ||
|
|
7dc486f74c | ||
|
|
de47a33bb4 | ||
|
|
32f9288034 | ||
|
|
4187e46d27 | ||
|
|
b070b228e4 | ||
|
|
b423992c26 | ||
|
|
6cee324515 | ||
|
|
4ffd42f66a | ||
|
|
4a30faa06f | ||
|
|
7f0113b6af | ||
|
|
a8f184e130 | ||
|
|
d8dd0f2683 | ||
|
|
e147e535bd | ||
|
|
2814f93395 | ||
|
|
0eb3ae9586 | ||
|
|
2bbc5b12bb | ||
|
|
8d0d7b3b81 | ||
|
|
1b09dd45c9 | ||
|
|
bc14301ac1 | ||
|
|
b9a980c380 | ||
|
|
ffbf6e6bcc | ||
|
|
0a5c96c832 | ||
|
|
2004a8568c | ||
|
|
1e71c2b43a | ||
|
|
69c37f364d | ||
|
|
df42eeef2b | ||
|
|
2cf429b882 | ||
|
|
038cd01c03 | ||
|
|
b1ed6b7184 | ||
|
|
c85f560671 | ||
|
|
f2be0a0a28 | ||
|
|
43a4c20ef8 | ||
|
|
b29dda362e | ||
|
|
ee817043f0 | ||
|
|
0bddb3d4c8 | ||
|
|
310a55eeac | ||
|
|
f093da6500 | ||
|
|
6fcd0b1f9b | ||
|
|
7e5ae00163 | ||
|
|
de80ecc474 | ||
|
|
1936dc5de8 | ||
|
|
2d79dcf58e | ||
|
|
538e7bf2c1 | ||
|
|
9b6287ec50 | ||
|
|
607d01b1dd | ||
|
|
fc8bc13f24 | ||
|
|
5a9f1eb452 | ||
|
|
b15ede0f00 | ||
|
|
b3a6211a9b | ||
|
|
7294629fd6 | ||
|
|
9b71353da8 | ||
|
|
a07749e9ad | ||
|
|
386e05a00c | ||
|
|
18d8191f3f | ||
|
|
9d80321677 | ||
|
|
cf475c2e2e | ||
|
|
871ef3e60f | ||
|
|
6d4d3fd865 | ||
|
|
473255ebf9 | ||
|
|
0332904392 | ||
|
|
7dc5622cc0 | ||
|
|
1b351a67db | ||
|
|
d539219101 | ||
|
|
7d7dc94af8 | ||
|
|
cb607b5c68 | ||
|
|
05f9331d8e | ||
|
|
7d8b32aa9c | ||
|
|
585417393a | ||
|
|
669668f306 | ||
|
|
d7dcb0f011 | ||
|
|
ba94197bc8 | ||
|
|
d4524cfa8b | ||
|
|
9005fe35f0 | ||
|
|
bc3d837580 | ||
|
|
b050d58cd1 | ||
|
|
1f2e793345 | ||
|
|
1c02d71be1 | ||
|
|
ec42ced52f | ||
|
|
3e5416cbd6 | ||
|
|
16dc45aa1f | ||
|
|
9f0f40ccdd | ||
|
|
d49f559d9a | ||
|
|
802cf95aa3 | ||
|
|
6603df780b | ||
|
|
67ede46c65 | ||
|
|
07e29c2ac4 | ||
|
|
b512c2bd6e | ||
|
|
e2f1bf29b0 | ||
|
|
5a30c27c98 | ||
|
|
53ebe537da | ||
|
|
7ee43da56d | ||
|
|
62587ae997 | ||
|
|
fca4226f5a | ||
|
|
237b3c2eac | ||
|
|
ec92ed9323 | ||
|
|
310bf2c0a4 | ||
|
|
3679a26580 | ||
|
|
e1d721d906 | ||
|
|
d21a05f1af | ||
|
|
62cd3d63c5 | ||
|
|
2c9dce6164 | ||
|
|
30f5aac0bd | ||
|
|
d3427276fb | ||
|
|
8dcbf62ef3 | ||
|
|
d79e074422 | ||
|
|
f70a7d035c | ||
|
|
d13ae27a93 | ||
|
|
9a78d45a2f | ||
|
|
a61df2c9ae | ||
|
|
744002fcb9 | ||
|
|
bed6800f05 | ||
|
|
f46dd2af02 | ||
|
|
c7b9dc388c | ||
|
|
527a6b2284 | ||
|
|
a91ff70ceb | ||
|
|
62751db0d7 | ||
|
|
73a4f63134 | ||
|
|
d5c6e8be7b | ||
|
|
a023b0d69c | ||
|
|
0781253073 | ||
|
|
018bc3ebdf | ||
|
|
35bb03a9fc | ||
|
|
9e15eac47f | ||
|
|
b6a8780959 | ||
|
|
ffaa389415 | ||
|
|
cf66d2c6ad | ||
|
|
7434859646 | ||
|
|
186f31f09e | ||
|
|
46b9862506 | ||
|
|
a31b3d5e85 | ||
|
|
71c17ec0cd | ||
|
|
61453b77fa | ||
|
|
db189ed863 | ||
|
|
5c061f003b | ||
|
|
62f14c08d1 | ||
|
|
b24763ffa9 | ||
|
|
96ec0c97df | ||
|
|
da8527c189 | ||
|
|
cd3aa54bc7 | ||
|
|
329e9c279c | ||
|
|
87eff0a6d2 | ||
|
|
225283da63 | ||
|
|
c1ca7c2e56 | ||
|
|
f41f25bb37 | ||
|
|
ec8d2e3810 | ||
|
|
4ecb9762d1 | ||
|
|
b808ef6615 | ||
|
|
32080eb949 | ||
|
|
5d174966e2 | ||
|
|
600bcf4b21 | ||
|
|
0aa49a8ef5 | ||
|
|
de42350f04 | ||
|
|
1c312e0820 | ||
|
|
bb9e3eff13 | ||
|
|
ed65b9186e | ||
|
|
2d781f51e1 | ||
|
|
42076ef3b7 | ||
|
|
370b619e55 | ||
|
|
7c3880d0de | ||
|
|
0c6b4a9b6d | ||
|
|
7f48fe9b49 | ||
|
|
415ba6a444 | ||
|
|
0b475cd66f | ||
|
|
2d350df3c3 | ||
|
|
a15bcc7ea8 | ||
|
|
e39c9a2411 | ||
|
|
5b526645b6 | ||
|
|
1209808c70 | ||
|
|
7b0ce2b50b | ||
|
|
e7652038ee | ||
|
|
bf4a8248c9 | ||
|
|
184fb3f51c | ||
|
|
2ce3cbc260 | ||
|
|
8602d9d964 | ||
|
|
c3565d2759 | ||
|
|
6da81770bb | ||
|
|
a9dea1e4a4 | ||
|
|
1f21c5d7a3 | ||
|
|
879577b2dd | ||
|
|
6e4c669be8 | ||
|
|
1e82d103e5 | ||
|
|
b6d7927e13 | ||
|
|
fbc9bf4ba0 | ||
|
|
2ea6598f64 | ||
|
|
88f2f459db | ||
|
|
3e990c4ec2 | ||
|
|
755546643a | ||
|
|
13c571a801 | ||
|
|
8714d8afec | ||
|
|
37df748155 | ||
|
|
6dc8e40903 | ||
|
|
7699b4c796 | ||
|
|
b0cfda3187 | ||
|
|
524fbae162 | ||
|
|
8f592d81e8 | ||
|
|
e4c14c5c4f | ||
|
|
357fd2e58d | ||
|
|
8b006606b5 | ||
|
|
400ded6619 | ||
|
|
69f42526bb | ||
|
|
44e7b4eb11 | ||
|
|
b2efa6f860 | ||
|
|
2cfad59a38 | ||
|
|
9a17c30493 | ||
|
|
d223a5ba93 | ||
|
|
80bdbd7a99 | ||
|
|
218573c340 | ||
|
|
908c30ceb6 | ||
|
|
c469c6ed2b | ||
|
|
c6a9061207 | ||
|
|
97360301eb | ||
|
|
dd4b7fc8d7 | ||
|
|
f63983d8e8 | ||
|
|
1a0e2d459d | ||
|
|
fa705c6668 | ||
|
|
039e02ed9c | ||
|
|
ea08a50e9b | ||
|
|
c4359763ab | ||
|
|
a163c5a7eb | ||
|
|
1c59b23c9f | ||
|
|
690f3d25c2 | ||
|
|
cc293eaff6 | ||
|
|
3621c83f2f | ||
|
|
eca8ab3038 | ||
|
|
c3e1b10d3d | ||
|
|
3dceb69212 | ||
|
|
f5cce0bdc4 | ||
|
|
2eebb803cb | ||
|
|
77ac6ec9d5 | ||
|
|
466dff53c2 | ||
|
|
0a17023d1e | ||
|
|
726a0959df | ||
|
|
9cb2f5e191 | ||
|
|
681d3ecd2b | ||
|
|
52aa8c2961 | ||
|
|
fece2acfba | ||
|
|
28026fe2cf | ||
|
|
c6e84d494c | ||
|
|
bfa07fc52a | ||
|
|
4afa329a78 | ||
|
|
e24dc1ff4c | ||
|
|
3043094d71 | ||
|
|
7075c595ae | ||
|
|
21d60a9afe | ||
|
|
f347805418 | ||
|
|
5fe174365d | ||
|
|
c0166c617d | ||
|
|
83ed22ca28 | ||
|
|
700cd32ffd | ||
|
|
49c8d21f16 | ||
|
|
bbab7da39f | ||
|
|
dea9ce421d | ||
|
|
d53047927b | ||
|
|
9b1aa94e69 | ||
|
|
119dd753e9 | ||
|
|
2459ac65fe | ||
|
|
77dfa297d0 | ||
|
|
59a0461d50 | ||
|
|
49ca26154e | ||
|
|
3ea443b670 | ||
|
|
a21f7a1d1b | ||
|
|
ff6112c09e | ||
|
|
f625c00f5a | ||
|
|
64a04b540a | ||
|
|
5940b25d34 | ||
|
|
4bee6895eb | ||
|
|
5a5ac33c87 | ||
|
|
154dac563f | ||
|
|
6e82dddfb5 | ||
|
|
de15c6af68 | ||
|
|
caaabca123 | ||
|
|
6ad702680e | ||
|
|
92d1ebe1a0 | ||
|
|
4edef8f4bf | ||
|
|
e35ad60e4e | ||
|
|
f42fa7b214 | ||
|
|
2fb7adbd53 | ||
|
|
2b6c3df954 | ||
|
|
a906dfbed2 | ||
|
|
b7860407f0 | ||
|
|
dee2bb288b | ||
|
|
096759c0b0 | ||
|
|
73c9537f3b | ||
|
|
70fc346580 | ||
|
|
664f59e750 | ||
|
|
19ef7e6e16 | ||
|
|
c8446af29a | ||
|
|
0e09f1a238 | ||
|
|
ba53d1d6b7 | ||
|
|
1f36f15a49 | ||
|
|
df9da57e4f | ||
|
|
2b6ea5f344 | ||
|
|
1bf1e70c0f | ||
|
|
ee3b0d5bd0 | ||
|
|
898f1e9691 | ||
|
|
ed1a25df19 | ||
|
|
fe5ab36245 | ||
|
|
a859f3feff | ||
|
|
6f402272e7 | ||
|
|
5ab3e2e580 | ||
|
|
0654a42e19 | ||
|
|
f7dd7df170 | ||
|
|
c6b17073e9 | ||
|
|
7aa163b83f | ||
|
|
c47541acbd | ||
|
|
b5fe8dfef3 | ||
|
|
2665cec7f2 | ||
|
|
4d1e206f5e | ||
|
|
2e778c52c1 | ||
|
|
6b640b424c | ||
|
|
06574736b3 | ||
|
|
4fe51e51e0 | ||
|
|
335abd236f | ||
|
|
46d1b6c99d | ||
|
|
e6b1ef272e | ||
|
|
1bea199e00 | ||
|
|
42cd88d737 | ||
|
|
4c3895e96c | ||
|
|
2c14cc1897 | ||
|
|
13fb140932 | ||
|
|
9d66a589b4 | ||
|
|
d87e0e6117 | ||
|
|
7962c00701 | ||
|
|
8963a3868e |
4
.github/workflows/PR-4.x.yaml
vendored
4
.github/workflows/PR-4.x.yaml
vendored
@@ -58,4 +58,6 @@ jobs:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-docs.yaml@main
|
||||
|
||||
Linux-RISC-V-Clang:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-RISCV.yaml@main
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-RISCV.yaml@main
|
||||
with:
|
||||
workflow_branch: main
|
||||
|
||||
12
3rdparty/ffmpeg/ffmpeg.cmake
vendored
12
3rdparty/ffmpeg/ffmpeg.cmake
vendored
@@ -1,9 +1,9 @@
|
||||
# Binaries branch name: ffmpeg/4.x_20251226
|
||||
# Binaries were created for OpenCV: cff7581175d2abfc6aef2e4f04f482e258b5c864
|
||||
ocv_update(FFMPEG_BINARIES_COMMIT "d82ad9a54a7b42a1648a9cae8fed5c2f20ea396c")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN32 "47730de2286110b0d1250ff9cf50ce56")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN64 "3248b4663ffef770cdb54ec8b9d16a28")
|
||||
ocv_update(FFMPEG_FILE_HASH_CMAKE "8862c87496e2e8c375965e1277dee1c7")
|
||||
# Binaries branch name: ffmpeg/4.x_20260715
|
||||
# Binaries were created for OpenCV: 6b640b424c516d27217700392a7ed6a362e040a5
|
||||
ocv_update(FFMPEG_BINARIES_COMMIT "bd9418020a5c342be979c56d6e6434261959d3af")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN32 "31968b434799d3dd56969b15aac3efa8")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN64 "84757ed0f16ddedce99227529d3165e9")
|
||||
ocv_update(FFMPEG_FILE_HASH_CMAKE "e09efc33312d1173be8a9446f3b088fe")
|
||||
|
||||
function(download_win_ffmpeg script_var)
|
||||
set(${script_var} "" PARENT_SCOPE)
|
||||
|
||||
10
3rdparty/ippicv/ippicv.cmake
vendored
10
3rdparty/ippicv/ippicv.cmake
vendored
@@ -2,7 +2,7 @@ function(download_ippicv root_var)
|
||||
set(${root_var} "" PARENT_SCOPE)
|
||||
|
||||
# Commit SHA in the opencv_3rdparty repo
|
||||
set(IPPICV_COMMIT "406d398c436d0465c8e53dd432d9ecd9301d5f4a")
|
||||
set(IPPICV_COMMIT "4fe81acdb1688d5f2a3fa6f34b1c28793e706f0b")
|
||||
# Define actual ICV versions
|
||||
if(APPLE)
|
||||
set(IPPICV_COMMIT "0cc4aa06bf2bef4b05d237c69a5a96b9cd0cb85a")
|
||||
@@ -14,8 +14,8 @@ function(download_ippicv root_var)
|
||||
set(OPENCV_ICV_PLATFORM "linux")
|
||||
set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_lnx")
|
||||
if(X86_64)
|
||||
set(OPENCV_ICV_NAME "ippicv_2026.0.0_lnx_intel64_20260327_general.tgz")
|
||||
set(OPENCV_ICV_HASH "9a3ee0c5c3c02102faa422d60bfd1f4a")
|
||||
set(OPENCV_ICV_NAME "ippicv_2026.1.0_lnx_intel64_20260922_general.tgz")
|
||||
set(OPENCV_ICV_HASH "78f38db04a4d8f08f7d715a5c976347b")
|
||||
else()
|
||||
if(ANDROID)
|
||||
set(IPPICV_COMMIT "c7c6d527dde5fee7cb914ee9e4e20f7436aab3a1")
|
||||
@@ -31,8 +31,8 @@ function(download_ippicv root_var)
|
||||
set(OPENCV_ICV_PLATFORM "windows")
|
||||
set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_win")
|
||||
if(X86_64)
|
||||
set(OPENCV_ICV_NAME "ippicv_2026.0.0_win_intel64_20260327_general.zip")
|
||||
set(OPENCV_ICV_HASH "73bc67cd5e4c8da706fa88fe84630231")
|
||||
set(OPENCV_ICV_NAME "ippicv_2026.1.0_win_intel64_20260922_general.zip")
|
||||
set(OPENCV_ICV_HASH "d24183f73b413c5b4e2d2b371affc82a")
|
||||
else()
|
||||
set(IPPICV_COMMIT "7f55c0c26be418d494615afca15218566775c725")
|
||||
set(OPENCV_ICV_NAME "ippicv_2021.12.0_win_ia32_20240425_general.zip")
|
||||
|
||||
21
3rdparty/libtiff/CMakeLists.txt
vendored
21
3rdparty/libtiff/CMakeLists.txt
vendored
@@ -297,6 +297,16 @@ if(JPEG_SUPPORT AND old-jpeg)
|
||||
set(OJPEG_SUPPORT TRUE)
|
||||
endif()
|
||||
|
||||
# WEBP
|
||||
set(WEBP_SUPPORT FALSE)
|
||||
if(HAVE_WEBP)
|
||||
set(WEBP_SUPPORT TRUE)
|
||||
if(TARGET ${WEBP_LIBRARY} AND DEFINED ${WEBP_LIBRARY}_BINARY_DIR)
|
||||
include_directories("${${WEBP_LIBRARY}_BINARY_DIR}")
|
||||
endif()
|
||||
include_directories(${WEBP_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
# OpenCV: turned off
|
||||
set(JBIG_SUPPORT 0)
|
||||
set(LZMA_SUPPORT 0) # OpenCV: turned off
|
||||
@@ -329,6 +339,9 @@ endif()
|
||||
if(JPEG12_INCLUDE_DIR)
|
||||
list(APPEND TIFF_INCLUDES ${JPEG12_INCLUDE_DIR})
|
||||
endif()
|
||||
if(WEBP_INCLUDE_DIR)
|
||||
list(APPEND TIFF_INCLUDES ${WEBP_INCLUDE_DIR})
|
||||
endif()
|
||||
if(JBIG_INCLUDE_DIR)
|
||||
list(APPEND TIFF_INCLUDES ${JBIG_INCLUDE_DIR})
|
||||
endif()
|
||||
@@ -347,6 +360,9 @@ endif()
|
||||
if(JPEG_LIBRARIES)
|
||||
list(APPEND TIFF_LIBRARY_DEPS ${JPEG_LIBRARIES})
|
||||
endif()
|
||||
if(WEBP_LIBRARIES)
|
||||
list(APPEND TIFF_LIBRARY_DEPS ${WEBP_LIBRARIES})
|
||||
endif()
|
||||
if(JPEG12_LIBRARIES)
|
||||
list(APPEND TIFF_LIBRARY_DEPS ${JPEG12_LIBRARIES})
|
||||
endif()
|
||||
@@ -359,7 +375,7 @@ endif()
|
||||
|
||||
set(LIBTIFF_MAJOR_VERSION "4")
|
||||
set(LIBTIFF_MINOR_VERSION "7")
|
||||
set(LIBTIFF_MICRO_VERSION "1")
|
||||
set(LIBTIFF_MICRO_VERSION "2")
|
||||
set(LIBTIFF_VERSION "${LIBTIFF_MAJOR_VERSION}.${LIBTIFF_MINOR_VERSION}.${LIBTIFF_MICRO_VERSION}")
|
||||
file(READ "RELEASE-DATE" LIBTIFF_RELEASE_DATE content)
|
||||
|
||||
@@ -462,6 +478,9 @@ ocv_warnings_disable(CMAKE_C_FLAGS /wd4267 /wd4244 /wd4018 /wd4311 /wd4312)
|
||||
|
||||
add_library(${TIFF_LIBRARY} STATIC ${OPENCV_3RDPARTY_EXCLUDE_FROM_ALL} ${lib_srcs})
|
||||
target_link_libraries(${TIFF_LIBRARY} ${ZLIB_LIBRARIES})
|
||||
if(HAVE_WEBP)
|
||||
target_link_libraries(${TIFF_LIBRARY} ${WEBP_LIBRARY})
|
||||
endif()
|
||||
|
||||
set_target_properties(${TIFF_LIBRARY}
|
||||
PROPERTIES
|
||||
|
||||
2336
3rdparty/libtiff/ChangeLog
vendored
2336
3rdparty/libtiff/ChangeLog
vendored
File diff suppressed because it is too large
Load Diff
2
3rdparty/libtiff/RELEASE-DATE
vendored
2
3rdparty/libtiff/RELEASE-DATE
vendored
@@ -1 +1 @@
|
||||
20250911
|
||||
20260627
|
||||
|
||||
127
3rdparty/libtiff/tif_aux.c
vendored
127
3rdparty/libtiff/tif_aux.c
vendored
@@ -56,6 +56,21 @@ uint64_t _TIFFMultiply64(TIFF *tif, uint64_t first, uint64_t second,
|
||||
return first * second;
|
||||
}
|
||||
|
||||
uint64_t _TIFFAdd64(TIFF *tif, uint64_t first, uint64_t second,
|
||||
const char *where)
|
||||
{
|
||||
if (first > UINT64_MAX - second)
|
||||
{
|
||||
if (tif != NULL && where != NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, where, "Integer overflow in %s", where);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return first + second;
|
||||
}
|
||||
|
||||
tmsize_t _TIFFMultiplySSize(TIFF *tif, tmsize_t first, tmsize_t second,
|
||||
const char *where)
|
||||
{
|
||||
@@ -81,6 +96,30 @@ tmsize_t _TIFFMultiplySSize(TIFF *tif, tmsize_t first, tmsize_t second,
|
||||
return first * second;
|
||||
}
|
||||
|
||||
tmsize_t _TIFFAddSSize(TIFF *tif, tmsize_t first, tmsize_t second,
|
||||
const char *where)
|
||||
{
|
||||
if (first < 0 || second < 0)
|
||||
{
|
||||
if (tif != NULL && where != NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, where,
|
||||
"Invalid argument to _TIFFAddSSize() in %s", where);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (first > TIFF_TMSIZE_T_MAX - second)
|
||||
{
|
||||
if (tif != NULL && where != NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, where, "Integer overflow in %s", where);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return first + second;
|
||||
}
|
||||
|
||||
tmsize_t _TIFFCastUInt64ToSSize(TIFF *tif, uint64_t val, const char *module)
|
||||
{
|
||||
if (val > (uint64_t)TIFF_TMSIZE_T_MAX)
|
||||
@@ -94,6 +133,55 @@ tmsize_t _TIFFCastUInt64ToSSize(TIFF *tif, uint64_t val, const char *module)
|
||||
return (tmsize_t)val;
|
||||
}
|
||||
|
||||
uint32_t _TIFFCastUInt64ToUInt32(TIFF *tif, uint64_t val, const char *module)
|
||||
{
|
||||
if (val > UINT32_MAX)
|
||||
{
|
||||
if (tif != NULL && module != NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Integer overflow");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return (uint32_t)val;
|
||||
}
|
||||
|
||||
tmsize_t _TIFFComputeRowOffset(TIFF *tif, tmsize_t rowstride, uint32_t row,
|
||||
const char *where)
|
||||
{
|
||||
if (row == 0)
|
||||
return 0;
|
||||
return _TIFFMultiplySSize(tif, rowstride, (tmsize_t)row, where);
|
||||
}
|
||||
|
||||
uint64_t _TIFFComputeBitOffset(TIFF *tif, uint32_t col, uint16_t spp,
|
||||
uint16_t bps, const char *where)
|
||||
{
|
||||
uint64_t samples = _TIFFMultiply64(tif, col, spp, where);
|
||||
if (samples == 0 && col != 0)
|
||||
return 0;
|
||||
return _TIFFMultiply64(tif, samples, bps, where);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 0 on overflow or invalid zero-sized row inputs. Callers that
|
||||
* intentionally allow empty rows should not use this helper directly.
|
||||
*/
|
||||
uint64_t _TIFFComputeRowSize64(TIFF *tif, uint32_t width, uint16_t spp,
|
||||
uint16_t bps, const char *where)
|
||||
{
|
||||
uint64_t samples = _TIFFMultiply64(tif, width, spp, where);
|
||||
uint64_t bits;
|
||||
if (samples == 0)
|
||||
return 0;
|
||||
|
||||
bits = _TIFFMultiply64(tif, samples, bps, where);
|
||||
if (bits == 0)
|
||||
return 0;
|
||||
|
||||
return TIFFhowmany8_64(bits);
|
||||
}
|
||||
|
||||
void *_TIFFCheckRealloc(TIFF *tif, void *buffer, tmsize_t nmemb,
|
||||
tmsize_t elem_size, const char *what)
|
||||
{
|
||||
@@ -137,8 +225,8 @@ static int TIFFDefaultTransferFunction(TIFF *tif, TIFFDirectory *td)
|
||||
if (td->td_bitspersample > 24)
|
||||
return 0;
|
||||
|
||||
n = ((tmsize_t)1) << td->td_bitspersample;
|
||||
nbytes = n * sizeof(uint16_t);
|
||||
n = (tmsize_t)(1ULL << td->td_bitspersample);
|
||||
nbytes = (tmsize_t)((uint64_t)n * sizeof(uint16_t));
|
||||
tf[0] = (uint16_t *)_TIFFmallocExt(tif, nbytes);
|
||||
if (tf[0] == NULL)
|
||||
return 0;
|
||||
@@ -186,10 +274,10 @@ static int TIFFDefaultRefBlackWhite(TIFF *tif, TIFFDirectory *td)
|
||||
* YCbCr (Class Y) images must have the ReferenceBlackWhite
|
||||
* tag set. Fix the broken images, which lacks that tag.
|
||||
*/
|
||||
td->td_refblackwhite[0] = 0.0F;
|
||||
td->td_refblackwhite[0] = 0.0f;
|
||||
td->td_refblackwhite[1] = td->td_refblackwhite[3] =
|
||||
td->td_refblackwhite[5] = 255.0F;
|
||||
td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0F;
|
||||
td->td_refblackwhite[5] = 255.0f;
|
||||
td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -199,8 +287,11 @@ static int TIFFDefaultRefBlackWhite(TIFF *tif, TIFFDirectory *td)
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
td->td_refblackwhite[2 * i + 0] = 0;
|
||||
td->td_refblackwhite[2 * i + 1] =
|
||||
(float)((1L << td->td_bitspersample) - 1L);
|
||||
if (td->td_bitspersample < 64)
|
||||
td->td_refblackwhite[2 * i + 1] =
|
||||
(float)((1ULL << td->td_bitspersample) - 1ULL);
|
||||
else
|
||||
td->td_refblackwhite[2 * i + 1] = (float)UINT64_MAX;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@@ -258,8 +349,8 @@ int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap)
|
||||
* 65535 even if td_bitspersamle is > 16 */
|
||||
if (td->td_bitspersample <= 16)
|
||||
{
|
||||
maxsamplevalue = (1 << td->td_bitspersample) -
|
||||
1; /* 2**(BitsPerSample) - 1 */
|
||||
maxsamplevalue = (uint16_t)((1U << td->td_bitspersample) -
|
||||
1); /* 2**(BitsPerSample) - 1 */
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -295,7 +386,11 @@ int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap)
|
||||
}
|
||||
case TIFFTAG_DOTRANGE:
|
||||
*va_arg(ap, uint16_t *) = 0;
|
||||
*va_arg(ap, uint16_t *) = (1 << td->td_bitspersample) - 1;
|
||||
if (td->td_bitspersample <= 16)
|
||||
*va_arg(ap, uint16_t *) =
|
||||
(uint16_t)((1U << td->td_bitspersample) - 1);
|
||||
else
|
||||
*va_arg(ap, uint16_t *) = 65535;
|
||||
return (1);
|
||||
case TIFFTAG_INKSET:
|
||||
*va_arg(ap, uint16_t *) = INKSET_CMYK;
|
||||
@@ -309,14 +404,14 @@ int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap)
|
||||
return (1);
|
||||
case TIFFTAG_MATTEING:
|
||||
*va_arg(ap, uint16_t *) =
|
||||
(td->td_extrasamples == 1 &&
|
||||
(td->td_extrasamples == 1 && td->td_sampleinfo &&
|
||||
td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
|
||||
return (1);
|
||||
case TIFFTAG_TILEDEPTH:
|
||||
*va_arg(ap, uint32_t *) = td->td_tiledepth;
|
||||
return (1);
|
||||
case TIFFTAG_DATATYPE:
|
||||
*va_arg(ap, uint16_t *) = td->td_sampleformat - 1;
|
||||
*va_arg(ap, uint16_t *) = (uint16_t)(td->td_sampleformat - 1);
|
||||
return (1);
|
||||
case TIFFTAG_SAMPLEFORMAT:
|
||||
*va_arg(ap, uint16_t *) = td->td_sampleformat;
|
||||
@@ -369,6 +464,8 @@ int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap)
|
||||
return (0);
|
||||
*va_arg(ap, const float **) = td->td_refblackwhite;
|
||||
return (1);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -390,9 +487,9 @@ int TIFFGetFieldDefaulted(TIFF *tif, uint32_t tag, ...)
|
||||
|
||||
float _TIFFClampDoubleToFloat(double val)
|
||||
{
|
||||
if (val > FLT_MAX)
|
||||
if (val > (double)FLT_MAX)
|
||||
return FLT_MAX;
|
||||
if (val < -FLT_MAX)
|
||||
if (val < -(double)FLT_MAX)
|
||||
return -FLT_MAX;
|
||||
return (float)val;
|
||||
}
|
||||
@@ -401,7 +498,7 @@ uint32_t _TIFFClampDoubleToUInt32(double val)
|
||||
{
|
||||
if (val < 0)
|
||||
return 0;
|
||||
if (val > 0xFFFFFFFFU || val != val)
|
||||
if (val > 0xFFFFFFFFU || isnan(val))
|
||||
return 0xFFFFFFFFU;
|
||||
return (uint32_t)val;
|
||||
}
|
||||
|
||||
6
3rdparty/libtiff/tif_close.c
vendored
6
3rdparty/libtiff/tif_close.c
vendored
@@ -88,7 +88,7 @@ void TIFFCleanup(TIFF *tif)
|
||||
*/
|
||||
TIFFFieldIsAnonymous(fld))
|
||||
{
|
||||
_TIFFfreeExt(tif, fld->field_name);
|
||||
_TIFFfreeExt(tif, (void *)fld->field_name);
|
||||
_TIFFfreeExt(tif, fld);
|
||||
}
|
||||
}
|
||||
@@ -121,7 +121,7 @@ void TIFFCleanup(TIFF *tif)
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* _TIFFCleanupIFDOffsetAndNumberMaps() */
|
||||
/* _TIFFCleanupIFDOffsetAndNumberMaps() */
|
||||
/************************************************************************/
|
||||
|
||||
void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif)
|
||||
@@ -139,7 +139,7 @@ void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif)
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* TIFFClose() */
|
||||
/* TIFFClose() */
|
||||
/************************************************************************/
|
||||
|
||||
/**
|
||||
|
||||
81
3rdparty/libtiff/tif_color.c
vendored
81
3rdparty/libtiff/tif_color.c
vendored
@@ -55,34 +55,34 @@ void TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, int32_t b,
|
||||
void TIFFCIELab16ToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a,
|
||||
int32_t b, float *X, float *Y, float *Z)
|
||||
{
|
||||
float L = (float)l * 100.0F / 65535.0F;
|
||||
float L = (float)l * 100.0f / 65535.0f;
|
||||
float cby, tmp;
|
||||
|
||||
if (L < 8.856F)
|
||||
if (L < 8.856f)
|
||||
{
|
||||
*Y = (L * cielab->Y0) / 903.292F;
|
||||
cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F;
|
||||
*Y = (L * cielab->Y0) / 903.292f;
|
||||
cby = 7.787f * (*Y / cielab->Y0) + 16.0f / 116.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
cby = (L + 16.0F) / 116.0F;
|
||||
cby = (L + 16.0f) / 116.0f;
|
||||
*Y = cielab->Y0 * cby * cby * cby;
|
||||
}
|
||||
|
||||
tmp = (float)a / 256.0F / 500.0F + cby;
|
||||
if (tmp < 0.2069F)
|
||||
*X = cielab->X0 * (tmp - 0.13793F) / 7.787F;
|
||||
tmp = (float)a / 256.0f / 500.0f + cby;
|
||||
if (tmp < 0.2069f)
|
||||
*X = cielab->X0 * (tmp - 0.13793f) / 7.787f;
|
||||
else
|
||||
*X = cielab->X0 * tmp * tmp * tmp;
|
||||
|
||||
tmp = cby - (float)b / 256.0F / 200.0F;
|
||||
if (tmp < 0.2069F)
|
||||
*Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F;
|
||||
tmp = cby - (float)b / 256.0f / 200.0f;
|
||||
if (tmp < 0.2069f)
|
||||
*Z = cielab->Z0 * (tmp - 0.13793f) / 7.787f;
|
||||
else
|
||||
*Z = cielab->Z0 * tmp * tmp * tmp;
|
||||
}
|
||||
|
||||
#define RINT(R) ((uint32_t)((R) > 0 ? ((R) + 0.5) : ((R)-0.5)))
|
||||
#define RINT(R) ((uint32_t)((R) > 0 ? ((R) + 0.5f) : ((R) - 0.5f)))
|
||||
/*
|
||||
* Convert color value from the XYZ space to RGB.
|
||||
*/
|
||||
@@ -143,32 +143,32 @@ int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display,
|
||||
_TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay));
|
||||
|
||||
/* Red */
|
||||
dfGamma = 1.0 / cielab->display.d_gammaR;
|
||||
dfGamma = 1.0 / (double)cielab->display.d_gammaR;
|
||||
cielab->rstep =
|
||||
(cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
|
||||
(cielab->display.d_YCR - cielab->display.d_Y0R) / (float)cielab->range;
|
||||
for (i = 0; i <= (size_t)cielab->range; i++)
|
||||
{
|
||||
cielab->Yr2r[i] = cielab->display.d_Vrwr *
|
||||
cielab->Yr2r[i] = (float)cielab->display.d_Vrwr *
|
||||
((float)pow((double)i / cielab->range, dfGamma));
|
||||
}
|
||||
|
||||
/* Green */
|
||||
dfGamma = 1.0 / cielab->display.d_gammaG;
|
||||
dfGamma = 1.0 / (double)cielab->display.d_gammaG;
|
||||
cielab->gstep =
|
||||
(cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
|
||||
(cielab->display.d_YCR - cielab->display.d_Y0R) / (float)cielab->range;
|
||||
for (i = 0; i <= (size_t)cielab->range; i++)
|
||||
{
|
||||
cielab->Yg2g[i] = cielab->display.d_Vrwg *
|
||||
cielab->Yg2g[i] = (float)cielab->display.d_Vrwg *
|
||||
((float)pow((double)i / cielab->range, dfGamma));
|
||||
}
|
||||
|
||||
/* Blue */
|
||||
dfGamma = 1.0 / cielab->display.d_gammaB;
|
||||
dfGamma = 1.0 / (double)cielab->display.d_gammaB;
|
||||
cielab->bstep =
|
||||
(cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
|
||||
(cielab->display.d_YCR - cielab->display.d_Y0R) / (float)cielab->range;
|
||||
for (i = 0; i <= (size_t)cielab->range; i++)
|
||||
{
|
||||
cielab->Yb2b[i] = cielab->display.d_Vrwb *
|
||||
cielab->Yb2b[i] = (float)cielab->display.d_Vrwb *
|
||||
((float)pow((double)i / cielab->range, dfGamma));
|
||||
}
|
||||
|
||||
@@ -186,11 +186,11 @@ int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display,
|
||||
* see below for more information on how it works.
|
||||
*/
|
||||
#define SHIFT 16
|
||||
#define FIX(x) ((int32_t)((x) * (1L << SHIFT) + 0.5))
|
||||
#define FIX(x) ((int32_t)((double)(x) * (1L << SHIFT) + 0.5))
|
||||
#define ONE_HALF ((int32_t)(1 << (SHIFT - 1)))
|
||||
#define Code2V(c, RB, RW, CR) \
|
||||
((((c) - (int32_t)(RB)) * (float)(CR)) / \
|
||||
(float)(((RW) - (RB) != 0) ? ((RW) - (RB)) : 1))
|
||||
(((float)((c) - (int32_t)(RB)) * (float)(CR)) / \
|
||||
((!TIFF_FLOAT_EQ((RW), (RB))) ? ((RW) - (RB)) : 1.0f))
|
||||
/* !((f)>=(min)) written that way to deal with NaN */
|
||||
#define CLAMP(f, min, max) \
|
||||
((!((f) >= (min))) ? (min) : (f) > (max) ? (max) : (f))
|
||||
@@ -207,12 +207,12 @@ void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32_t Y, int32_t Cb, int32_t Cr,
|
||||
Cr = CLAMP(Cr, 0, 255);
|
||||
|
||||
i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr];
|
||||
*r = CLAMP(i, 0, 255);
|
||||
*r = (uint32_t)CLAMP(i, 0, 255);
|
||||
i = ycbcr->Y_tab[Y] +
|
||||
(int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT);
|
||||
*g = CLAMP(i, 0, 255);
|
||||
((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT);
|
||||
*g = (uint32_t)CLAMP(i, 0, 255);
|
||||
i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb];
|
||||
*b = CLAMP(i, 0, 255);
|
||||
*b = (uint32_t)CLAMP(i, 0, 255);
|
||||
}
|
||||
|
||||
/* Clamp function for sanitization purposes. Normally clamping should not */
|
||||
@@ -258,8 +258,7 @@ int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite)
|
||||
#define LumaBlue luma[2]
|
||||
|
||||
clamptab =
|
||||
(TIFFRGBValue *)((uint8_t *)ycbcr +
|
||||
TIFFroundup_32(sizeof(TIFFYCbCrToRGB), sizeof(long)));
|
||||
(uint8_t *)ycbcr + TIFFroundup_32(sizeof(TIFFYCbCrToRGB), sizeof(long));
|
||||
_TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */
|
||||
ycbcr->clamptab = (clamptab += 256);
|
||||
for (i = 0; i < 256; i++)
|
||||
@@ -273,13 +272,13 @@ int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite)
|
||||
|
||||
{
|
||||
float f1 = 2 - 2 * LumaRed;
|
||||
int32_t D1 = FIX(CLAMP(f1, 0.0F, 2.0F));
|
||||
int32_t D1 = FIX(CLAMP(f1, 0.0f, 2.0f));
|
||||
float f2 = LumaRed * f1 / LumaGreen;
|
||||
int32_t D2 = -FIX(CLAMP(f2, 0.0F, 2.0F));
|
||||
int32_t D2 = -FIX(CLAMP(f2, 0.0f, 2.0f));
|
||||
float f3 = 2 - 2 * LumaBlue;
|
||||
int32_t D3 = FIX(CLAMP(f3, 0.0F, 2.0F));
|
||||
int32_t D3 = FIX(CLAMP(f3, 0.0f, 2.0f));
|
||||
float f4 = LumaBlue * f3 / LumaGreen;
|
||||
int32_t D4 = -FIX(CLAMP(f4, 0.0F, 2.0F));
|
||||
int32_t D4 = -FIX(CLAMP(f4, 0.0f, 2.0f));
|
||||
int x;
|
||||
|
||||
#undef LumaBlue
|
||||
@@ -295,12 +294,12 @@ int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite)
|
||||
*/
|
||||
for (i = 0, x = -128; i < 256; i++, x++)
|
||||
{
|
||||
int32_t Cr = (int32_t)CLAMPw(Code2V(x, refBlackWhite[4] - 128.0F,
|
||||
refBlackWhite[5] - 128.0F, 127),
|
||||
-128.0F * 32, 128.0F * 32);
|
||||
int32_t Cb = (int32_t)CLAMPw(Code2V(x, refBlackWhite[2] - 128.0F,
|
||||
refBlackWhite[3] - 128.0F, 127),
|
||||
-128.0F * 32, 128.0F * 32);
|
||||
int32_t Cr = (int32_t)CLAMPw(Code2V(x, refBlackWhite[4] - 128.0f,
|
||||
refBlackWhite[5] - 128.0f, 127),
|
||||
-128.0f * 32, 128.0f * 32);
|
||||
int32_t Cb = (int32_t)CLAMPw(Code2V(x, refBlackWhite[2] - 128.0f,
|
||||
refBlackWhite[3] - 128.0f, 127),
|
||||
-128.0f * 32, 128.0f * 32);
|
||||
|
||||
ycbcr->Cr_r_tab[i] = (int32_t)((D1 * Cr + ONE_HALF) >> SHIFT);
|
||||
ycbcr->Cb_b_tab[i] = (int32_t)((D3 * Cb + ONE_HALF) >> SHIFT);
|
||||
@@ -308,7 +307,7 @@ int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite)
|
||||
ycbcr->Cb_g_tab[i] = D4 * Cb + ONE_HALF;
|
||||
ycbcr->Y_tab[i] = (int32_t)CLAMPw(
|
||||
Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255),
|
||||
-128.0F * 32, 128.0F * 32);
|
||||
-128.0f * 32, 128.0f * 32);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
48
3rdparty/libtiff/tif_compress.c
vendored
48
3rdparty/libtiff/tif_compress.c
vendored
@@ -139,6 +139,18 @@ static int _TIFFtrue(TIFF *tif)
|
||||
}
|
||||
static void _TIFFvoid(TIFF *tif) { (void)tif; }
|
||||
|
||||
static uint64_t _TIFFDefaultGetMaxCompressionRatio(TIFF *tif)
|
||||
{
|
||||
(void)tif;
|
||||
return 0; /* unknown */
|
||||
}
|
||||
|
||||
static uint64_t _TIFFGetMaxCompressionRatioOne(TIFF *tif)
|
||||
{
|
||||
(void)tif;
|
||||
return 1; /* no compression */
|
||||
}
|
||||
|
||||
void _TIFFSetDefaultCompressionState(TIFF *tif)
|
||||
{
|
||||
tif->tif_fixuptags = _TIFFNoFixupTags;
|
||||
@@ -160,6 +172,7 @@ void _TIFFSetDefaultCompressionState(TIFF *tif)
|
||||
tif->tif_cleanup = _TIFFvoid;
|
||||
tif->tif_defstripsize = _TIFFDefaultStripSize;
|
||||
tif->tif_deftilesize = _TIFFDefaultTileSize;
|
||||
tif->tif_getmaxcompressionratio = _TIFFDefaultGetMaxCompressionRatio;
|
||||
tif->tif_flags &= ~(TIFF_NOBITREV | TIFF_NOREADRAW);
|
||||
}
|
||||
|
||||
@@ -168,6 +181,8 @@ int TIFFSetCompressionScheme(TIFF *tif, int scheme)
|
||||
const TIFFCodec *c = TIFFFindCODEC((uint16_t)scheme);
|
||||
|
||||
_TIFFSetDefaultCompressionState(tif);
|
||||
if (scheme == COMPRESSION_NONE)
|
||||
tif->tif_getmaxcompressionratio = _TIFFGetMaxCompressionRatioOne;
|
||||
/*
|
||||
* Don't treat an unknown compression scheme as an error.
|
||||
* This permits applications to open files with data that
|
||||
@@ -177,6 +192,13 @@ int TIFFSetCompressionScheme(TIFF *tif, int scheme)
|
||||
return (c ? (*c->init)(tif, scheme) : 1);
|
||||
}
|
||||
|
||||
uint64_t TIFFGetMaxCompressionRatio(TIFF *tif)
|
||||
{
|
||||
if (tif->tif_getmaxcompressionratio)
|
||||
return tif->tif_getmaxcompressionratio(tif);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Other compression schemes may be registered. Registered
|
||||
* schemes can also override the builtin versions provided
|
||||
@@ -200,7 +222,7 @@ const TIFFCodec *TIFFFindCODEC(uint16_t scheme)
|
||||
for (c = _TIFFBuiltinCODECS; c->name; c++)
|
||||
if (c->scheme == scheme)
|
||||
return (c);
|
||||
return ((const TIFFCodec *)0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TIFFCodec *TIFFRegisterCODEC(uint16_t scheme, const char *name,
|
||||
@@ -212,9 +234,11 @@ TIFFCodec *TIFFRegisterCODEC(uint16_t scheme, const char *name,
|
||||
|
||||
if (cd != NULL)
|
||||
{
|
||||
char *codec_name;
|
||||
cd->info = (TIFFCodec *)((uint8_t *)cd + sizeof(codec_t));
|
||||
cd->info->name = (char *)((uint8_t *)cd->info + sizeof(TIFFCodec));
|
||||
strcpy(cd->info->name, name);
|
||||
codec_name = (char *)((uint8_t *)cd->info + sizeof(TIFFCodec));
|
||||
strcpy(codec_name, name);
|
||||
cd->info->name = codec_name;
|
||||
cd->info->scheme = scheme;
|
||||
cd->info->init = init;
|
||||
cd->next = registeredCODECS;
|
||||
@@ -247,7 +271,7 @@ void TIFFUnRegisterCODEC(TIFFCodec *c)
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* TIFFGetConfisuredCODECs() */
|
||||
/* TIFFGetConfiguredCODECs() */
|
||||
/************************************************************************/
|
||||
|
||||
/**
|
||||
@@ -258,7 +282,7 @@ void TIFFUnRegisterCODEC(TIFFCodec *c)
|
||||
* or NULL if function failed.
|
||||
*/
|
||||
|
||||
TIFFCodec *TIFFGetConfiguredCODECs()
|
||||
TIFFCodec *TIFFGetConfiguredCODECs(void)
|
||||
{
|
||||
int i = 1;
|
||||
codec_t *cd;
|
||||
@@ -268,8 +292,8 @@ TIFFCodec *TIFFGetConfiguredCODECs()
|
||||
|
||||
for (cd = registeredCODECS; cd; cd = cd->next)
|
||||
{
|
||||
new_codecs =
|
||||
(TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec));
|
||||
new_codecs = (TIFFCodec *)_TIFFreallocExt(
|
||||
NULL, codecs, (tmsize_t)((size_t)i * sizeof(TIFFCodec)));
|
||||
if (!new_codecs)
|
||||
{
|
||||
_TIFFfreeExt(NULL, codecs);
|
||||
@@ -283,21 +307,21 @@ TIFFCodec *TIFFGetConfiguredCODECs()
|
||||
{
|
||||
if (TIFFIsCODECConfigured(c->scheme))
|
||||
{
|
||||
new_codecs = (TIFFCodec *)_TIFFreallocExt(NULL, codecs,
|
||||
i * sizeof(TIFFCodec));
|
||||
new_codecs = (TIFFCodec *)_TIFFreallocExt(
|
||||
NULL, codecs, (tmsize_t)((size_t)i * sizeof(TIFFCodec)));
|
||||
if (!new_codecs)
|
||||
{
|
||||
_TIFFfreeExt(NULL, codecs);
|
||||
return NULL;
|
||||
}
|
||||
codecs = new_codecs;
|
||||
_TIFFmemcpy(codecs + i - 1, (const void *)c, sizeof(TIFFCodec));
|
||||
_TIFFmemcpy(codecs + i - 1, c, sizeof(TIFFCodec));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
new_codecs =
|
||||
(TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec));
|
||||
new_codecs = (TIFFCodec *)_TIFFreallocExt(
|
||||
NULL, codecs, (tmsize_t)((size_t)i * sizeof(TIFFCodec)));
|
||||
if (!new_codecs)
|
||||
{
|
||||
_TIFFfreeExt(NULL, codecs);
|
||||
|
||||
145
3rdparty/libtiff/tif_dir.c
vendored
145
3rdparty/libtiff/tif_dir.c
vendored
@@ -31,6 +31,7 @@
|
||||
#include "tiffiop.h"
|
||||
#include <float.h> /*--: for Rational2Double */
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
/*
|
||||
* These are used in the backwards compatibility code...
|
||||
@@ -50,7 +51,8 @@ static void setByteArray(TIFF *tif, void **vpp, const void *vp, size_t nmemb,
|
||||
}
|
||||
if (vp)
|
||||
{
|
||||
tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL);
|
||||
tmsize_t bytes = _TIFFMultiplySSize(NULL, (tmsize_t)nmemb,
|
||||
(tmsize_t)elem_size, NULL);
|
||||
if (bytes)
|
||||
*vpp = (void *)_TIFFmallocExt(tif, bytes);
|
||||
if (*vpp)
|
||||
@@ -121,7 +123,8 @@ static void setDoubleArrayOneValue(TIFF *tif, double **vpp, double value,
|
||||
{
|
||||
if (*vpp)
|
||||
_TIFFfreeExt(tif, *vpp);
|
||||
*vpp = _TIFFmallocExt(tif, nmemb * sizeof(double));
|
||||
*vpp = (double *)_TIFFmallocExt(tif,
|
||||
(tmsize_t)nmemb * (tmsize_t)sizeof(double));
|
||||
if (*vpp)
|
||||
{
|
||||
while (nmemb--)
|
||||
@@ -294,7 +297,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
/*
|
||||
* Setup new compression routine state.
|
||||
*/
|
||||
if ((status = TIFFSetCompressionScheme(tif, v)) != 0)
|
||||
if ((status = TIFFSetCompressionScheme(tif, (int)v)) != 0)
|
||||
td->td_compression = (uint16_t)v;
|
||||
else
|
||||
status = 0;
|
||||
@@ -402,13 +405,13 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
break;
|
||||
case TIFFTAG_XRESOLUTION:
|
||||
dblval = va_arg(ap, double);
|
||||
if (dblval != dblval || dblval < 0)
|
||||
if (isnan(dblval) || dblval < 0)
|
||||
goto badvaluedouble;
|
||||
td->td_xresolution = _TIFFClampDoubleToFloat(dblval);
|
||||
break;
|
||||
case TIFFTAG_YRESOLUTION:
|
||||
dblval = va_arg(ap, double);
|
||||
if (dblval != dblval || dblval < 0)
|
||||
if (isnan(dblval) || dblval < 0)
|
||||
goto badvaluedouble;
|
||||
td->td_yresolution = _TIFFClampDoubleToFloat(dblval);
|
||||
break;
|
||||
@@ -439,7 +442,12 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
td->td_halftonehints[1] = (uint16_t)va_arg(ap, uint16_vap);
|
||||
break;
|
||||
case TIFFTAG_COLORMAP:
|
||||
v32 = (uint32_t)(1L << td->td_bitspersample);
|
||||
if (td->td_bitspersample >= 32)
|
||||
{
|
||||
v = td->td_bitspersample;
|
||||
goto badvalue;
|
||||
}
|
||||
v32 = 1U << td->td_bitspersample;
|
||||
_TIFFsetShortArrayExt(tif, &td->td_colormap[0],
|
||||
va_arg(ap, uint16_t *), v32);
|
||||
_TIFFsetShortArrayExt(tif, &td->td_colormap[1],
|
||||
@@ -557,11 +565,17 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
case TIFFTAG_TRANSFERFUNCTION:
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t count;
|
||||
if (td->td_bitspersample >= 32)
|
||||
{
|
||||
v = td->td_bitspersample;
|
||||
goto badvalue;
|
||||
}
|
||||
count = 1U << td->td_bitspersample;
|
||||
v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
|
||||
for (i = 0; i < v; i++)
|
||||
_TIFFsetShortArrayExt(tif, &td->td_transferfunction[i],
|
||||
va_arg(ap, uint16_t *),
|
||||
1U << td->td_bitspersample);
|
||||
va_arg(ap, uint16_t *), count);
|
||||
break;
|
||||
}
|
||||
case TIFFTAG_REFERENCEBLACKWHITE:
|
||||
@@ -579,7 +593,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
if (ninksinstring > 0)
|
||||
{
|
||||
_TIFFsetNString(tif, &td->td_inknames, s, v);
|
||||
td->td_inknameslen = v;
|
||||
td->td_inknameslen = (int)v;
|
||||
/* Set NumberOfInks to the value ninksinstring */
|
||||
if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
|
||||
{
|
||||
@@ -725,7 +739,8 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
|
||||
new_customValues = (TIFFTagValue *)_TIFFreallocExt(
|
||||
tif, td->td_customValues,
|
||||
sizeof(TIFFTagValue) * (td->td_customValueCount + 1));
|
||||
(tmsize_t)(sizeof(TIFFTagValue) *
|
||||
(size_t)(td->td_customValueCount + 1)));
|
||||
if (!new_customValues)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
@@ -754,7 +769,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
if (tv_size == 0)
|
||||
{
|
||||
status = 0;
|
||||
TIFFErrorExtR(tif, module, "%s: Bad field type %d for \"%s\"",
|
||||
TIFFErrorExtR(tif, module, "%s: Bad field type %u for \"%s\"",
|
||||
tif->tif_name, fip->field_type, fip->field_name);
|
||||
goto end;
|
||||
}
|
||||
@@ -784,7 +799,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
}
|
||||
ma = (uint32_t)len;
|
||||
}
|
||||
tv->count = ma;
|
||||
tv->count = (int)ma;
|
||||
setByteArray(tif, &tv->value, mb, ma, 1);
|
||||
}
|
||||
else
|
||||
@@ -792,9 +807,9 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
if (fip->field_passcount)
|
||||
{
|
||||
if (fip->field_writecount == TIFF_VARIABLE2)
|
||||
tv->count = (uint32_t)va_arg(ap, uint32_t);
|
||||
tv->count = (int)va_arg(ap, uint32_t);
|
||||
else
|
||||
tv->count = (int)va_arg(ap, int);
|
||||
tv->count = va_arg(ap, int);
|
||||
}
|
||||
else if (fip->field_writecount == TIFF_VARIABLE ||
|
||||
fip->field_writecount == TIFF_VARIABLE2)
|
||||
@@ -808,7 +823,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
{
|
||||
TIFFWarningExtR(tif, module,
|
||||
"%s: Null count for \"%s\" (type "
|
||||
"%d, writecount %d, passcount %d)",
|
||||
"%u, writecount %d, passcount %d)",
|
||||
tif->tif_name, fip->field_name,
|
||||
fip->field_type, fip->field_writecount,
|
||||
fip->field_passcount);
|
||||
@@ -845,11 +860,12 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
* 4 or 8 according to fip->set_get_field_type! */
|
||||
_TIFFmemcpy(tv->value, va_arg(ap, void *),
|
||||
tv->count * tv_size);
|
||||
/* Test here for too big values for LONG8, SLONG8 in
|
||||
/* Test here for too big values for LONG8, IFD8, SLONG8 in
|
||||
* ClassicTIFF and delete custom field from custom list */
|
||||
if (!(tif->tif_flags & TIFF_BIGTIFF))
|
||||
{
|
||||
if (tv->info->field_type == TIFF_LONG8)
|
||||
if (tv->info->field_type == TIFF_LONG8 ||
|
||||
tv->info->field_type == TIFF_IFD8)
|
||||
{
|
||||
uint64_t *pui64 = (uint64_t *)tv->value;
|
||||
for (int i = 0; i < tv->count; i++)
|
||||
@@ -858,12 +874,15 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
tif, module,
|
||||
"%s: Bad LONG8 value %" PRIu64
|
||||
"%s: Bad %s value %" PRIu64
|
||||
" at %d. array position for \"%s\" tag "
|
||||
"%d in ClassicTIFF. Tag won't be "
|
||||
"%u in ClassicTIFF. Tag won't be "
|
||||
"written to file",
|
||||
tif->tif_name, pui64[i], i,
|
||||
fip->field_name, tag);
|
||||
tif->tif_name,
|
||||
(tv->info->field_type == TIFF_LONG8
|
||||
? "LONG8"
|
||||
: "IFD8"),
|
||||
pui64[i], i, fip->field_name, tag);
|
||||
goto badvalueifd8long8;
|
||||
}
|
||||
}
|
||||
@@ -880,7 +899,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
tif, module,
|
||||
"%s: Bad SLONG8 value %" PRIi64
|
||||
" at %d. array position for \"%s\" tag "
|
||||
"%d in ClassicTIFF. Tag won't be "
|
||||
"%u in ClassicTIFF. Tag won't be "
|
||||
"written to file",
|
||||
tif->tif_name, pi64[i], i,
|
||||
fip->field_name, tag);
|
||||
@@ -948,7 +967,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
TIFFErrorExtR(
|
||||
tif, module,
|
||||
"%s: Bad LONG8 or IFD8 value %" PRIu64
|
||||
" for \"%s\" tag %d in ClassicTIFF. Tag "
|
||||
" for \"%s\" tag %u in ClassicTIFF. Tag "
|
||||
"won't be written to file",
|
||||
tif->tif_name, v2, fip->field_name, tag);
|
||||
goto badvalueifd8long8;
|
||||
@@ -967,7 +986,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
TIFFErrorExtR(
|
||||
tif, module,
|
||||
"%s: Bad SLONG8 value %" PRIi64
|
||||
" for \"%s\" tag %d in ClassicTIFF. Tag "
|
||||
" for \"%s\" tag %u in ClassicTIFF. Tag "
|
||||
"won't be written to file",
|
||||
tif->tif_name, v2, fip->field_name, tag);
|
||||
goto badvalueifd8long8;
|
||||
@@ -1018,6 +1037,8 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
_TIFFmemcpy(val, &v2, tv_size);
|
||||
}
|
||||
break;
|
||||
case TIFF_NOTYPE:
|
||||
case TIFF_ASCII:
|
||||
default:
|
||||
_TIFFmemset(val, 0, tv_size);
|
||||
status = 0;
|
||||
@@ -1345,7 +1366,7 @@ static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
break;
|
||||
case TIFFTAG_MATTEING:
|
||||
*va_arg(ap, uint16_t *) =
|
||||
(td->td_extrasamples == 1 &&
|
||||
(td->td_extrasamples == 1 && td->td_sampleinfo &&
|
||||
td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
|
||||
break;
|
||||
case TIFFTAG_EXTRASAMPLES:
|
||||
@@ -1376,6 +1397,8 @@ static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
case SAMPLEFORMAT_VOID:
|
||||
*va_arg(ap, uint16_t *) = DATATYPE_VOID;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TIFFTAG_SAMPLEFORMAT:
|
||||
@@ -1562,6 +1585,8 @@ static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
*va_arg(ap, double *) = *(double *)val;
|
||||
ret_val = 1;
|
||||
break;
|
||||
case TIFF_NOTYPE:
|
||||
case TIFF_ASCII:
|
||||
default:
|
||||
ret_val = 0;
|
||||
break;
|
||||
@@ -1613,6 +1638,21 @@ int TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset tif->tif_dir structure to zero and
|
||||
* initialize some IFD strile counter and index parameters.
|
||||
*/
|
||||
void _TIFFResetTifDirAndInitStrileCounters(TIFFDirectory *td)
|
||||
{
|
||||
_TIFFmemset(td, 0, sizeof(*td));
|
||||
td->td_curstrip = NOSTRIP; /* invalid strip = NOSTRIP */
|
||||
td->td_row = (uint32_t)-1; /* read/write pre-increment */
|
||||
td->td_col = (uint32_t)-1; /* read/write pre-increment */
|
||||
td->td_scanlinesize = 0; /* initialize to zero */
|
||||
td->td_curtile = NOTILE; /* invalid tile = NOTILE */
|
||||
td->td_tilesize = (tmsize_t)-1; /* invalidate tilezize */
|
||||
}
|
||||
|
||||
/*
|
||||
* Release storage associated with a directory.
|
||||
*/
|
||||
@@ -1664,6 +1704,7 @@ void TIFFFreeDirectory(TIFF *tif)
|
||||
tif->tif_dir.td_dirdatasize_Noffsets = 0;
|
||||
}
|
||||
tif->tif_dir.td_iswrittentofile = FALSE;
|
||||
/* Note: tif->tif_dir structure is set to zero in TIFFDefaultDirectory() */
|
||||
}
|
||||
#undef CleanupField
|
||||
|
||||
@@ -1694,10 +1735,7 @@ int TIFFCreateDirectory(TIFF *tif)
|
||||
tif->tif_diroff = 0;
|
||||
tif->tif_nextdiroff = 0;
|
||||
tif->tif_curoff = 0;
|
||||
tif->tif_row = (uint32_t)-1;
|
||||
tif->tif_curstrip = (uint32_t)-1;
|
||||
tif->tif_dir.td_iswrittentofile = FALSE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1717,15 +1755,12 @@ int TIFFCreateCustomDirectory(TIFF *tif, const TIFFFieldArray *infoarray)
|
||||
tif->tif_diroff = 0;
|
||||
tif->tif_nextdiroff = 0;
|
||||
tif->tif_curoff = 0;
|
||||
tif->tif_row = (uint32_t)-1;
|
||||
tif->tif_curstrip = (uint32_t)-1;
|
||||
/* invalidate directory index */
|
||||
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
/* invalidate IFD loop lists */
|
||||
_TIFFCleanupIFDOffsetAndNumberMaps(tif);
|
||||
/* To be able to return from SubIFD or custom-IFD to main-IFD */
|
||||
tif->tif_setdirectory_force_absolute = TRUE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1751,13 +1786,14 @@ int TIFFCreateGPSDirectory(TIFF *tif)
|
||||
*/
|
||||
int TIFFDefaultDirectory(TIFF *tif)
|
||||
{
|
||||
register TIFFDirectory *td = &tif->tif_dir;
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
const TIFFFieldArray *tiffFieldArray;
|
||||
|
||||
tiffFieldArray = _TIFFGetFields();
|
||||
_TIFFSetupFields(tif, tiffFieldArray);
|
||||
|
||||
_TIFFmemset(td, 0, sizeof(*td));
|
||||
/* Reset tif->tif_dir structure to zero and
|
||||
* initialize some IFD strile counter and index parameters. */
|
||||
_TIFFResetTifDirAndInitStrileCounters(td);
|
||||
td->td_fillorder = FILLORDER_MSB2LSB;
|
||||
td->td_bitspersample = 1;
|
||||
td->td_threshholding = THRESHHOLD_BILEVEL;
|
||||
@@ -1860,10 +1896,8 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
|
||||
tmsize_t poffa, poffb, poffc, poffd;
|
||||
uint16_t dircount;
|
||||
uint32_t nextdir32;
|
||||
poffa = (tmsize_t)poff;
|
||||
poffb = poffa + sizeof(uint16_t);
|
||||
if (((uint64_t)poffa != poff) || (poffb < poffa) ||
|
||||
(poffb < (tmsize_t)sizeof(uint16_t)) || (poffb > tif->tif_size))
|
||||
if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint16_t) ||
|
||||
poff > (uint64_t)tif->tif_size - sizeof(uint16_t))
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"%s:%d: %s: Error fetching directory count",
|
||||
@@ -1871,13 +1905,20 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
|
||||
*nextdiroff = 0;
|
||||
return (0);
|
||||
}
|
||||
poffa = (tmsize_t)poff;
|
||||
poffb = poffa + (tmsize_t)sizeof(uint16_t);
|
||||
_TIFFmemcpy(&dircount, tif->tif_base + poffa, sizeof(uint16_t));
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabShort(&dircount);
|
||||
if (poffb >
|
||||
TIFF_TMSIZE_T_MAX - dircount * 12 - (tmsize_t)sizeof(uint32_t))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error fetching directory link");
|
||||
return (0);
|
||||
}
|
||||
poffc = poffb + dircount * 12;
|
||||
poffd = poffc + sizeof(uint32_t);
|
||||
if ((poffc < poffb) || (poffc < dircount * 12) || (poffd < poffc) ||
|
||||
(poffd < (tmsize_t)sizeof(uint32_t)) || (poffd > tif->tif_size))
|
||||
poffd = poffc + (tmsize_t)sizeof(uint32_t);
|
||||
if (poffd > tif->tif_size)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error fetching directory link");
|
||||
return (0);
|
||||
@@ -1893,7 +1934,6 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
|
||||
{
|
||||
tmsize_t poffa, poffb, poffc, poffd;
|
||||
uint64_t dircount64;
|
||||
uint16_t dircount16;
|
||||
if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint64_t))
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
@@ -1902,7 +1942,7 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
|
||||
return (0);
|
||||
}
|
||||
poffa = (tmsize_t)poff;
|
||||
poffb = poffa + sizeof(uint64_t);
|
||||
poffb = poffa + (tmsize_t)sizeof(uint64_t);
|
||||
if (poffb > tif->tif_size)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
@@ -1919,15 +1959,14 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
|
||||
"Sanity check on directory count failed");
|
||||
return (0);
|
||||
}
|
||||
dircount16 = (uint16_t)dircount64;
|
||||
if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount16 * 20) -
|
||||
if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount64 * 20) -
|
||||
(tmsize_t)sizeof(uint64_t))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error fetching directory link");
|
||||
return (0);
|
||||
}
|
||||
poffc = poffb + dircount16 * 20;
|
||||
poffd = poffc + sizeof(uint64_t);
|
||||
poffc = poffb + (tmsize_t)(dircount64 * 20);
|
||||
poffd = poffc + (tmsize_t)sizeof(uint64_t);
|
||||
if (poffd > tif->tif_size)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error fetching directory link");
|
||||
@@ -1957,9 +1996,9 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabShort(&dircount);
|
||||
if (off != NULL)
|
||||
*off = TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
|
||||
*off = TIFFSeekFile(tif, dircount * 12U, SEEK_CUR);
|
||||
else
|
||||
(void)TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
|
||||
(void)TIFFSeekFile(tif, dircount * 12U, SEEK_CUR);
|
||||
if (!ReadOK(tif, &nextdir32, sizeof(uint32_t)))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
|
||||
@@ -1973,7 +2012,6 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
|
||||
else
|
||||
{
|
||||
uint64_t dircount64;
|
||||
uint16_t dircount16;
|
||||
if (!SeekOK(tif, *nextdiroff) ||
|
||||
!ReadOK(tif, &dircount64, sizeof(uint64_t)))
|
||||
{
|
||||
@@ -1991,11 +2029,10 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
|
||||
__FILE__, __LINE__, tif->tif_name);
|
||||
return (0);
|
||||
}
|
||||
dircount16 = (uint16_t)dircount64;
|
||||
if (off != NULL)
|
||||
*off = TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
|
||||
*off = TIFFSeekFile(tif, dircount64 * 20, SEEK_CUR);
|
||||
else
|
||||
(void)TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
|
||||
(void)TIFFSeekFile(tif, dircount64 * 20, SEEK_CUR);
|
||||
if (!ReadOK(tif, nextdiroff, sizeof(uint64_t)))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
|
||||
@@ -2354,8 +2391,6 @@ int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn)
|
||||
tif->tif_nextdiroff = 0; /* next write must be at end */
|
||||
tif->tif_lastdiroff = 0; /* will be updated on next link */
|
||||
tif->tif_curoff = 0;
|
||||
tif->tif_row = (uint32_t)-1;
|
||||
tif->tif_curstrip = (uint32_t)-1;
|
||||
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
if (tif->tif_curdircount > 0)
|
||||
tif->tif_curdircount--;
|
||||
|
||||
16
3rdparty/libtiff/tif_dir.h
vendored
16
3rdparty/libtiff/tif_dir.h
vendored
@@ -104,6 +104,16 @@ typedef struct
|
||||
uint16_t td_halftonehints[2];
|
||||
uint16_t td_extrasamples;
|
||||
uint16_t *td_sampleinfo;
|
||||
/* strip support */
|
||||
uint32_t td_row; /* current scanline */
|
||||
uint32_t td_curstrip; /* current strip for read/write */
|
||||
tmsize_t td_scanlinesize; /* # of bytes in a scanline */
|
||||
#define NOSTRIP ((uint32_t)(-1)) /* undefined state */
|
||||
/* tiling support */
|
||||
uint32_t td_col; /* current column (offset by row too) */
|
||||
uint32_t td_curtile; /* current tile for read/write */
|
||||
tmsize_t td_tilesize; /* # of bytes in a tile */
|
||||
#define NOTILE ((uint32_t)(-1)) /* undefined state */
|
||||
/* even though the name is misleading, td_stripsperimage is the number
|
||||
* of striles (=strips or tiles) per plane, and td_nstrips the total
|
||||
* number of striles */
|
||||
@@ -164,6 +174,8 @@ typedef struct
|
||||
entries. */
|
||||
} TIFFDirectory;
|
||||
|
||||
extern void _TIFFResetTifDirAndInitStrileCounters(TIFFDirectory *td);
|
||||
|
||||
/*
|
||||
* Field flags used to indicate fields that have been set in a directory, and
|
||||
* to reference fields when manipulating a directory.
|
||||
@@ -231,7 +243,7 @@ typedef struct
|
||||
|
||||
#define FIELD_LAST (32 * FIELDSET_ITEMS - 1)
|
||||
|
||||
#define BITn(n) (((uint32_t)1L) << ((n)&0x1f))
|
||||
#define BITn(n) (1U << ((n) & 0x1f))
|
||||
#define BITFIELDn(tif, n) ((tif)->tif_dir.td_fieldsset[(n) / 32])
|
||||
#define TIFFFieldSet(tif, field) (BITFIELDn(tif, field) & BITn(field))
|
||||
#define TIFFSetFieldBit(tif, field) (BITFIELDn(tif, field) |= BITn(field))
|
||||
@@ -340,7 +352,7 @@ extern "C"
|
||||
unsigned short field_bit; /* bit in fieldsset bit vector */
|
||||
unsigned char field_oktochange; /* if true, can change while writing */
|
||||
unsigned char field_passcount; /* if true, pass dir count on set */
|
||||
char *field_name; /* ASCII name */
|
||||
const char *field_name; /* ASCII name */
|
||||
TIFFFieldArray *field_subfields; /* if field points to child ifds, child
|
||||
ifd field definition array */
|
||||
};
|
||||
|
||||
154
3rdparty/libtiff/tif_dirinfo.c
vendored
154
3rdparty/libtiff/tif_dirinfo.c
vendored
@@ -40,17 +40,47 @@
|
||||
* values accordingly.
|
||||
*/
|
||||
|
||||
/* const object should be initialized */
|
||||
#ifdef _MSC_VER
|
||||
/* Forward declarations - definition follows after field arrays.
|
||||
* Note: In C, we can forward declare static const objects and define them
|
||||
* later. In C++, we need extern for the declaration, then define without
|
||||
* extern. Since these are only used within this file via pointers, we use a
|
||||
* workaround that works in both C and C++: declare as extern here, define as
|
||||
* static later, but actually we need a different approach for C++
|
||||
* compatibility.
|
||||
*
|
||||
* For C/C++ compatibility, we define a simple struct that holds the pointer
|
||||
* and initialize it after the arrays are defined.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
/* C++ doesn't allow forward declaration of const objects, so we use extern */
|
||||
extern const TIFFFieldArray tiffFieldArray;
|
||||
extern const TIFFFieldArray exifFieldArray;
|
||||
extern const TIFFFieldArray gpsFieldArray;
|
||||
#else
|
||||
/* C allows forward declaration of const objects, but C++ doesn't.
|
||||
* We disable the C++-compat warning for this section since these circular
|
||||
* dependencies are unavoidable with static initialization. */
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wc++-compat"
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wc++-compat"
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4132)
|
||||
#endif
|
||||
static const TIFFFieldArray tiffFieldArray;
|
||||
static const TIFFFieldArray exifFieldArray;
|
||||
static const TIFFFieldArray gpsFieldArray;
|
||||
#ifdef _MSC_VER
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
#endif
|
||||
/*--: Rational2Double: --
|
||||
* The Rational2Double upgraded libtiff functionality allows the definition and
|
||||
* achievement of true double-precision accuracy for TIFF tags of RATIONAL type
|
||||
@@ -152,9 +182,9 @@ static const TIFFField tiffFields[] = {
|
||||
/*--: EXIFIFD and GPSIFD specified as TIFF_LONG by Aware-Systems and not TIFF_IFD8 as in original LibTiff. However, for IFD-like tags,
|
||||
* libtiff uses the data type TIFF_IFD8 in tiffFields[]-tag definition combined with a special handling procedure in order to write either
|
||||
* a 32-bit value and the TIFF_IFD type-id into ClassicTIFF files or a 64-bit value and the TIFF_IFD8 type-id into BigTIFF files. */
|
||||
{TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, FIELD_CUSTOM, 1, 0, "EXIFIFDOffset", (TIFFFieldArray *)&exifFieldArray},
|
||||
{TIFFTAG_EXIFIFD, 1, 1, TIFF_LONG8, 0, TIFF_SETGET_UINT64, FIELD_CUSTOM, 1, 0, "EXIFIFDOffset", (TIFFFieldArray *)&exifFieldArray},
|
||||
{TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "ICC Profile", NULL},
|
||||
{TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, FIELD_CUSTOM, 1, 0, "GPSIFDOffset", (TIFFFieldArray *)&gpsFieldArray},
|
||||
{TIFFTAG_GPSIFD, 1, 1, TIFF_LONG8, 0, TIFF_SETGET_UINT64, FIELD_CUSTOM, 1, 0, "GPSIFDOffset", (TIFFFieldArray *)&gpsFieldArray},
|
||||
{TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvParams", NULL},
|
||||
{TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxSubAddress", NULL},
|
||||
{TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL},
|
||||
@@ -479,12 +509,36 @@ static const TIFFField gpsFields[] = {
|
||||
{GPSTAG_GPSHPOSITIONINGERROR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, FIELD_CUSTOM, 1, 0, "HorizontalPositioningError", NULL}};
|
||||
/* clang-format on */ /* was off for better readability of tag comments */
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* In C++, the forward declaration used extern, so definitions must not be
|
||||
* static */
|
||||
const TIFFFieldArray tiffFieldArray = {
|
||||
tfiatImage, 0, TIFFArrayCount(tiffFields), (TIFFField *)tiffFields};
|
||||
const TIFFFieldArray exifFieldArray = {tfiatExif, 0, TIFFArrayCount(exifFields),
|
||||
(TIFFField *)exifFields};
|
||||
const TIFFFieldArray gpsFieldArray = {tfiatGps, 0, TIFFArrayCount(gpsFields),
|
||||
(TIFFField *)gpsFields};
|
||||
#else
|
||||
/* Suppress C++-compat warning for the definitions as well */
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wc++-compat"
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wc++-compat"
|
||||
#endif
|
||||
static const TIFFFieldArray tiffFieldArray = {
|
||||
tfiatImage, 0, TIFFArrayCount(tiffFields), (TIFFField *)tiffFields};
|
||||
static const TIFFFieldArray exifFieldArray = {
|
||||
tfiatExif, 0, TIFFArrayCount(exifFields), (TIFFField *)exifFields};
|
||||
static const TIFFFieldArray gpsFieldArray = {
|
||||
tfiatGps, 0, TIFFArrayCount(gpsFields), (TIFFField *)gpsFields};
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We have our own local lfind() equivalent to avoid subtle differences
|
||||
@@ -523,7 +577,7 @@ void _TIFFSetupFields(TIFF *tif, const TIFFFieldArray *fieldarray)
|
||||
{
|
||||
if (fld->field_bit == FIELD_CUSTOM && TIFFFieldIsAnonymous(fld))
|
||||
{
|
||||
_TIFFfreeExt(tif, fld->field_name);
|
||||
_TIFFfreeExt(tif, (void *)fld->field_name);
|
||||
/* caution: tif_fields[i] must not be the beginning of a
|
||||
* fields-array. Otherwise the following tags are also freed
|
||||
* with the first free().
|
||||
@@ -579,22 +633,26 @@ int _TIFFMergeFields(TIFF *tif, const TIFFField info[], uint32_t n)
|
||||
|
||||
tif->tif_foundfield = NULL;
|
||||
|
||||
TIFFField **tif_newfields = NULL;
|
||||
|
||||
if (tif->tif_fields && tif->tif_nfields > 0)
|
||||
{
|
||||
tif->tif_fields = (TIFFField **)_TIFFCheckRealloc(
|
||||
tif, tif->tif_fields, (tif->tif_nfields + n), sizeof(TIFFField *),
|
||||
reason);
|
||||
tif_newfields = (TIFFField **)_TIFFCheckRealloc(
|
||||
tif, tif->tif_fields, (tmsize_t)tif->tif_nfields + n,
|
||||
(tmsize_t)sizeof(TIFFField *), reason);
|
||||
}
|
||||
else
|
||||
{
|
||||
tif->tif_fields =
|
||||
tif_newfields =
|
||||
(TIFFField **)_TIFFCheckMalloc(tif, n, sizeof(TIFFField *), reason);
|
||||
}
|
||||
if (!tif->tif_fields)
|
||||
if (!tif_newfields)
|
||||
{
|
||||
tif->tif_nfields = 0;
|
||||
TIFFErrorExtR(tif, module, "Failed to allocate fields array");
|
||||
return 0;
|
||||
}
|
||||
tif->tif_fields = tif_newfields;
|
||||
|
||||
/* tp = tif->tif_fields + tif->tif_nfields; */
|
||||
for (i = 0; i < n; i++)
|
||||
@@ -612,7 +670,7 @@ int _TIFFMergeFields(TIFF *tif, const TIFFField info[], uint32_t n)
|
||||
/* Sort the field info by tag number */
|
||||
qsort(tif->tif_fields, tif->tif_nfields, sizeof(TIFFField *), tagCompare);
|
||||
|
||||
return n;
|
||||
return (int)n;
|
||||
}
|
||||
|
||||
void _TIFFPrintFieldInfo(TIFF *tif, FILE *fd)
|
||||
@@ -623,7 +681,7 @@ void _TIFFPrintFieldInfo(TIFF *tif, FILE *fd)
|
||||
for (i = 0; i < tif->tif_nfields; i++)
|
||||
{
|
||||
const TIFFField *fip = tif->tif_fields[i];
|
||||
fprintf(fd, "field[%2d] %5lu, %2d, %2d, %d, %2d, %5s, %5s, %s\n",
|
||||
fprintf(fd, "field[%2d] %5lu, %2d, %2d, %u, %2d, %5s, %5s, %s\n",
|
||||
(int)i, (unsigned long)fip->field_tag, fip->field_readcount,
|
||||
fip->field_writecount, fip->field_type, fip->field_bit,
|
||||
fip->field_oktochange ? "TRUE" : "FALSE",
|
||||
@@ -787,6 +845,34 @@ int TIFFFieldSetGetCountSize(const TIFFField *fip)
|
||||
case TIFF_SETGET_C32_DOUBLE:
|
||||
case TIFF_SETGET_C32_IFD8:
|
||||
return 4;
|
||||
case TIFF_SETGET_UNDEFINED:
|
||||
case TIFF_SETGET_ASCII:
|
||||
case TIFF_SETGET_UINT8:
|
||||
case TIFF_SETGET_SINT8:
|
||||
case TIFF_SETGET_UINT16:
|
||||
case TIFF_SETGET_SINT16:
|
||||
case TIFF_SETGET_UINT32:
|
||||
case TIFF_SETGET_SINT32:
|
||||
case TIFF_SETGET_UINT64:
|
||||
case TIFF_SETGET_SINT64:
|
||||
case TIFF_SETGET_FLOAT:
|
||||
case TIFF_SETGET_DOUBLE:
|
||||
case TIFF_SETGET_IFD8:
|
||||
case TIFF_SETGET_INT:
|
||||
case TIFF_SETGET_UINT16_PAIR:
|
||||
case TIFF_SETGET_C0_ASCII:
|
||||
case TIFF_SETGET_C0_UINT8:
|
||||
case TIFF_SETGET_C0_SINT8:
|
||||
case TIFF_SETGET_C0_UINT16:
|
||||
case TIFF_SETGET_C0_SINT16:
|
||||
case TIFF_SETGET_C0_UINT32:
|
||||
case TIFF_SETGET_C0_SINT32:
|
||||
case TIFF_SETGET_C0_UINT64:
|
||||
case TIFF_SETGET_C0_SINT64:
|
||||
case TIFF_SETGET_C0_FLOAT:
|
||||
case TIFF_SETGET_C0_DOUBLE:
|
||||
case TIFF_SETGET_C0_IFD8:
|
||||
case TIFF_SETGET_OTHER:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -794,7 +880,8 @@ int TIFFFieldSetGetCountSize(const TIFFField *fip)
|
||||
|
||||
const TIFFField *TIFFFindField(TIFF *tif, uint32_t tag, TIFFDataType dt)
|
||||
{
|
||||
TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, NULL, NULL};
|
||||
TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, TIFF_SETGET_UNDEFINED,
|
||||
0, 0, 0, NULL, NULL};
|
||||
TIFFField *pkey = &key;
|
||||
const TIFFField **ret;
|
||||
if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag &&
|
||||
@@ -818,7 +905,8 @@ const TIFFField *TIFFFindField(TIFF *tif, uint32_t tag, TIFFDataType dt)
|
||||
static const TIFFField *_TIFFFindFieldByName(TIFF *tif, const char *field_name,
|
||||
TIFFDataType dt)
|
||||
{
|
||||
TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, NULL, NULL};
|
||||
TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, TIFF_SETGET_UNDEFINED,
|
||||
0, 0, 0, NULL, NULL};
|
||||
TIFFField *pkey = &key;
|
||||
const TIFFField **ret;
|
||||
if (tif->tif_foundfield &&
|
||||
@@ -876,7 +964,10 @@ int TIFFFieldReadCount(const TIFFField *fip) { return fip->field_readcount; }
|
||||
|
||||
int TIFFFieldWriteCount(const TIFFField *fip) { return fip->field_writecount; }
|
||||
|
||||
int TIFFFieldIsAnonymous(const TIFFField *fip) { return fip->field_anonymous; }
|
||||
int TIFFFieldIsAnonymous(const TIFFField *fip)
|
||||
{
|
||||
return (int)fip->field_anonymous;
|
||||
}
|
||||
|
||||
const TIFFField *_TIFFFindOrRegisterField(TIFF *tif, uint32_t tag,
|
||||
TIFFDataType dt)
|
||||
@@ -954,6 +1045,7 @@ TIFFField *_TIFFCreateAnonField(TIFF *tif, uint32_t tag,
|
||||
case TIFF_SLONG8:
|
||||
fld->set_get_field_type = TIFF_SETGET_C32_SINT64;
|
||||
break;
|
||||
case TIFF_NOTYPE:
|
||||
default:
|
||||
fld->set_get_field_type = TIFF_SETGET_UNDEFINED;
|
||||
break;
|
||||
@@ -961,8 +1053,8 @@ TIFFField *_TIFFCreateAnonField(TIFF *tif, uint32_t tag,
|
||||
fld->field_bit = FIELD_CUSTOM;
|
||||
fld->field_oktochange = TRUE;
|
||||
fld->field_passcount = TRUE;
|
||||
fld->field_name = (char *)_TIFFmallocExt(tif, 32);
|
||||
if (fld->field_name == NULL)
|
||||
char *field_name_buf = (char *)_TIFFmallocExt(tif, 32);
|
||||
if (field_name_buf == NULL)
|
||||
{
|
||||
_TIFFfreeExt(tif, fld);
|
||||
return NULL;
|
||||
@@ -975,7 +1067,8 @@ TIFFField *_TIFFCreateAnonField(TIFF *tif, uint32_t tag,
|
||||
* Update:
|
||||
* This special sign is replaced by fld->field_anonymous flag.
|
||||
*/
|
||||
(void)snprintf(fld->field_name, 32, "Tag %d", (int)tag);
|
||||
(void)snprintf(field_name_buf, 32, "Tag %d", (int)tag);
|
||||
fld->field_name = field_name_buf;
|
||||
|
||||
return fld;
|
||||
}
|
||||
@@ -1025,6 +1118,7 @@ static TIFFSetGetFieldType _TIFFSetGetType(TIFFDataType type, short count,
|
||||
return TIFF_SETGET_UINT64;
|
||||
case TIFF_SLONG8:
|
||||
return TIFF_SETGET_SINT64;
|
||||
case TIFF_NOTYPE:
|
||||
default:
|
||||
return TIFF_SETGET_UNDEFINED;
|
||||
}
|
||||
@@ -1062,6 +1156,7 @@ static TIFFSetGetFieldType _TIFFSetGetType(TIFFDataType type, short count,
|
||||
return TIFF_SETGET_C0_UINT64;
|
||||
case TIFF_SLONG8:
|
||||
return TIFF_SETGET_C0_SINT64;
|
||||
case TIFF_NOTYPE:
|
||||
default:
|
||||
return TIFF_SETGET_UNDEFINED;
|
||||
}
|
||||
@@ -1099,6 +1194,7 @@ static TIFFSetGetFieldType _TIFFSetGetType(TIFFDataType type, short count,
|
||||
return TIFF_SETGET_C16_UINT64;
|
||||
case TIFF_SLONG8:
|
||||
return TIFF_SETGET_C16_SINT64;
|
||||
case TIFF_NOTYPE:
|
||||
default:
|
||||
return TIFF_SETGET_UNDEFINED;
|
||||
}
|
||||
@@ -1136,6 +1232,7 @@ static TIFFSetGetFieldType _TIFFSetGetType(TIFFDataType type, short count,
|
||||
return TIFF_SETGET_C32_UINT64;
|
||||
case TIFF_SLONG8:
|
||||
return TIFF_SETGET_C32_SINT64;
|
||||
case TIFF_NOTYPE:
|
||||
default:
|
||||
return TIFF_SETGET_UNDEFINED;
|
||||
}
|
||||
@@ -1152,22 +1249,25 @@ int TIFFMergeFieldInfo(TIFF *tif, const TIFFFieldInfo info[], uint32_t n)
|
||||
size_t nfields;
|
||||
uint32_t i;
|
||||
|
||||
TIFFFieldArray *tif_newfieldscompat = NULL;
|
||||
|
||||
if (tif->tif_nfieldscompat > 0)
|
||||
{
|
||||
tif->tif_fieldscompat = (TIFFFieldArray *)_TIFFCheckRealloc(
|
||||
tif, tif->tif_fieldscompat, tif->tif_nfieldscompat + 1,
|
||||
sizeof(TIFFFieldArray), reason);
|
||||
tif_newfieldscompat = (TIFFFieldArray *)_TIFFCheckRealloc(
|
||||
tif, tif->tif_fieldscompat, (tmsize_t)tif->tif_nfieldscompat + 1,
|
||||
(tmsize_t)sizeof(TIFFFieldArray), reason);
|
||||
}
|
||||
else
|
||||
{
|
||||
tif->tif_fieldscompat = (TIFFFieldArray *)_TIFFCheckMalloc(
|
||||
tif_newfieldscompat = (TIFFFieldArray *)_TIFFCheckMalloc(
|
||||
tif, 1, sizeof(TIFFFieldArray), reason);
|
||||
}
|
||||
if (!tif->tif_fieldscompat)
|
||||
if (!tif_newfieldscompat)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Failed to allocate fields array");
|
||||
return -1;
|
||||
}
|
||||
tif->tif_fieldscompat = tif_newfieldscompat;
|
||||
nfields = tif->tif_nfieldscompat++;
|
||||
|
||||
tif->tif_fieldscompat[nfields].type = tfiatOther;
|
||||
@@ -1309,6 +1409,8 @@ int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag)
|
||||
case TIFFTAG_JPEGPROC:
|
||||
case TIFFTAG_JPEGRESTARTINTERVAL:
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case COMPRESSION_CCITTRLE:
|
||||
@@ -1329,6 +1431,8 @@ int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag)
|
||||
if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4)
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case COMPRESSION_JBIG:
|
||||
@@ -1359,6 +1463,8 @@ int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag)
|
||||
if (tag == TIFFTAG_LERC_PARAMETERS)
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
323
3rdparty/libtiff/tif_dirread.c
vendored
323
3rdparty/libtiff/tif_dirread.c
vendored
@@ -597,7 +597,7 @@ TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value)
|
||||
err = TIFFReadDirEntryCheckRangeSshortShort(m);
|
||||
if (err != TIFFReadDirEntryErrOk)
|
||||
return (err);
|
||||
*value = (uint16_t)m;
|
||||
*value = (int16_t)m;
|
||||
return (TIFFReadDirEntryErrOk);
|
||||
}
|
||||
case TIFF_SSHORT:
|
||||
@@ -695,6 +695,7 @@ TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value)
|
||||
return (TIFFReadDirEntryErrOk);
|
||||
}
|
||||
case TIFF_LONG:
|
||||
case TIFF_IFD:
|
||||
TIFFReadDirEntryCheckedLong(tif, direntry, value);
|
||||
return (TIFFReadDirEntryErrOk);
|
||||
case TIFF_SLONG:
|
||||
@@ -708,6 +709,7 @@ TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value)
|
||||
return (TIFFReadDirEntryErrOk);
|
||||
}
|
||||
case TIFF_LONG8:
|
||||
case TIFF_IFD8:
|
||||
{
|
||||
uint64_t m;
|
||||
err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
|
||||
@@ -857,6 +859,7 @@ TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value)
|
||||
return (TIFFReadDirEntryErrOk);
|
||||
}
|
||||
case TIFF_LONG:
|
||||
case TIFF_IFD:
|
||||
{
|
||||
uint32_t m;
|
||||
TIFFReadDirEntryCheckedLong(tif, direntry, &m);
|
||||
@@ -874,6 +877,7 @@ TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value)
|
||||
return (TIFFReadDirEntryErrOk);
|
||||
}
|
||||
case TIFF_LONG8:
|
||||
case TIFF_IFD8:
|
||||
err = TIFFReadDirEntryCheckedLong8(tif, direntry, value);
|
||||
return (err);
|
||||
case TIFF_SLONG8:
|
||||
@@ -1058,7 +1062,7 @@ TIFFReadDirEntryFloat(TIFF *tif, TIFFDirEntry *direntry, float *value)
|
||||
err = TIFFReadDirEntryCheckedDouble(tif, direntry, &m);
|
||||
if (err != TIFFReadDirEntryErrOk)
|
||||
return (err);
|
||||
if ((m > FLT_MAX) || (m < -FLT_MAX))
|
||||
if ((m > (double)FLT_MAX) || (m < -(double)FLT_MAX))
|
||||
return (TIFFReadDirEntryErrRange);
|
||||
*value = (float)m;
|
||||
return (TIFFReadDirEntryErrOk);
|
||||
@@ -1237,6 +1241,8 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc(TIFF *tif,
|
||||
*pdest = new_dest;
|
||||
|
||||
bytes_read = TIFFReadFile(tif, (char *)*pdest + already_read, to_read);
|
||||
if (bytes_read < 0)
|
||||
return TIFFReadDirEntryErrIo;
|
||||
already_read += bytes_read;
|
||||
if (bytes_read != to_read)
|
||||
{
|
||||
@@ -1260,7 +1266,7 @@ TIFFReadDirEntryArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
|
||||
void *data;
|
||||
uint64_t target_count64;
|
||||
int original_datasize_clamped;
|
||||
typesize = TIFFDataWidth(direntry->tdir_type);
|
||||
typesize = TIFFDataWidth((TIFFDataType)direntry->tdir_type);
|
||||
|
||||
target_count64 =
|
||||
(direntry->tdir_count > maxcount) ? maxcount : direntry->tdir_count;
|
||||
@@ -1284,13 +1290,13 @@ TIFFReadDirEntryArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
|
||||
* in either the current data type or the dest data type. This also
|
||||
* avoids problems with overflow of tmsize_t on 32bit systems.
|
||||
*/
|
||||
if ((uint64_t)(MAX_SIZE_TAG_DATA / typesize) < target_count64)
|
||||
if ((uint64_t)(MAX_SIZE_TAG_DATA / (unsigned int)typesize) < target_count64)
|
||||
return (TIFFReadDirEntryErrSizesan);
|
||||
if ((uint64_t)(MAX_SIZE_TAG_DATA / desttypesize) < target_count64)
|
||||
return (TIFFReadDirEntryErrSizesan);
|
||||
|
||||
*count = (uint32_t)target_count64;
|
||||
datasize = (*count) * typesize;
|
||||
datasize = (uint32_t)(*count) * (unsigned int)typesize;
|
||||
assert((tmsize_t)datasize > 0);
|
||||
|
||||
if (datasize > 100 * 1024 * 1024)
|
||||
@@ -1440,6 +1446,8 @@ TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value)
|
||||
*value = (uint8_t *)origdata;
|
||||
return (TIFFReadDirEntryErrOk);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
data = (uint8_t *)_TIFFmallocExt(tif, count);
|
||||
if (data == 0)
|
||||
@@ -1557,6 +1565,8 @@ TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value)
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_TIFFfreeExt(tif, origdata);
|
||||
if (err != TIFFReadDirEntryErrOk)
|
||||
@@ -1620,6 +1630,8 @@ TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value)
|
||||
case TIFF_SBYTE:
|
||||
*value = (int8_t *)origdata;
|
||||
return (TIFFReadDirEntryErrOk);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
data = (int8_t *)_TIFFmallocExt(tif, count);
|
||||
if (data == 0)
|
||||
@@ -1737,6 +1749,8 @@ TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value)
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_TIFFfreeExt(tif, origdata);
|
||||
if (err != TIFFReadDirEntryErrOk)
|
||||
@@ -1802,6 +1816,8 @@ TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value)
|
||||
*value = (uint16_t *)origdata;
|
||||
return (TIFFReadDirEntryErrOk);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
data = (uint16_t *)_TIFFmallocExt(tif, count * 2);
|
||||
if (data == 0)
|
||||
@@ -1910,6 +1926,8 @@ TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value)
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_TIFFfreeExt(tif, origdata);
|
||||
if (err != TIFFReadDirEntryErrOk)
|
||||
@@ -1975,6 +1993,8 @@ TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value)
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabArrayOfShort((uint16_t *)(*value), count);
|
||||
return (TIFFReadDirEntryErrOk);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
data = (int16_t *)_TIFFmallocExt(tif, count * 2);
|
||||
if (data == 0)
|
||||
@@ -2078,6 +2098,8 @@ TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value)
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_TIFFfreeExt(tif, origdata);
|
||||
if (err != TIFFReadDirEntryErrOk)
|
||||
@@ -2106,6 +2128,8 @@ TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value)
|
||||
case TIFF_SLONG:
|
||||
case TIFF_LONG8:
|
||||
case TIFF_SLONG8:
|
||||
case TIFF_IFD:
|
||||
case TIFF_IFD8:
|
||||
break;
|
||||
default:
|
||||
return (TIFFReadDirEntryErrType);
|
||||
@@ -2119,6 +2143,7 @@ TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value)
|
||||
switch (direntry->tdir_type)
|
||||
{
|
||||
case TIFF_LONG:
|
||||
case TIFF_IFD:
|
||||
*value = (uint32_t *)origdata;
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabArrayOfLong(*value, count);
|
||||
@@ -2143,6 +2168,8 @@ TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value)
|
||||
*value = (uint32_t *)origdata;
|
||||
return (TIFFReadDirEntryErrOk);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
data = (uint32_t *)_TIFFmallocExt(tif, count * 4);
|
||||
if (data == 0)
|
||||
@@ -2213,6 +2240,7 @@ TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value)
|
||||
}
|
||||
break;
|
||||
case TIFF_LONG8:
|
||||
case TIFF_IFD8:
|
||||
{
|
||||
uint64_t *ma;
|
||||
uint32_t *mb;
|
||||
@@ -2248,6 +2276,8 @@ TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value)
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_TIFFfreeExt(tif, origdata);
|
||||
if (err != TIFFReadDirEntryErrOk)
|
||||
@@ -2313,6 +2343,8 @@ TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value)
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabArrayOfLong((uint32_t *)(*value), count);
|
||||
return (TIFFReadDirEntryErrOk);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
data = (int32_t *)_TIFFmallocExt(tif, count * 4);
|
||||
if (data == 0)
|
||||
@@ -2410,6 +2442,8 @@ TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value)
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_TIFFfreeExt(tif, origdata);
|
||||
if (err != TIFFReadDirEntryErrOk)
|
||||
@@ -2439,6 +2473,8 @@ TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
|
||||
case TIFF_SLONG:
|
||||
case TIFF_LONG8:
|
||||
case TIFF_SLONG8:
|
||||
case TIFF_IFD:
|
||||
case TIFF_IFD8:
|
||||
break;
|
||||
default:
|
||||
return (TIFFReadDirEntryErrType);
|
||||
@@ -2453,6 +2489,7 @@ TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
|
||||
switch (direntry->tdir_type)
|
||||
{
|
||||
case TIFF_LONG8:
|
||||
case TIFF_IFD8:
|
||||
*value = (uint64_t *)origdata;
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabArrayOfLong8(*value, count);
|
||||
@@ -2477,6 +2514,8 @@ TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
|
||||
*value = (uint64_t *)origdata;
|
||||
return (TIFFReadDirEntryErrOk);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
data = (uint64_t *)_TIFFmallocExt(tif, count * 8);
|
||||
if (data == 0)
|
||||
@@ -2547,6 +2586,7 @@ TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
|
||||
}
|
||||
break;
|
||||
case TIFF_LONG:
|
||||
case TIFF_IFD:
|
||||
{
|
||||
uint32_t *ma;
|
||||
uint64_t *mb;
|
||||
@@ -2579,6 +2619,8 @@ TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_TIFFfreeExt(tif, origdata);
|
||||
if (err != TIFFReadDirEntryErrOk)
|
||||
@@ -2651,6 +2693,8 @@ TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value)
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabArrayOfLong8((uint64_t *)(*value), count);
|
||||
return (TIFFReadDirEntryErrOk);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
data = (int64_t *)_TIFFmallocExt(tif, count * 8);
|
||||
if (data == 0)
|
||||
@@ -2742,6 +2786,8 @@ TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value)
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_TIFFfreeExt(tif, origdata);
|
||||
*value = data;
|
||||
@@ -2787,8 +2833,11 @@ TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value)
|
||||
TIFFCvtIEEEFloatToNative(tif, count, (float *)origdata);
|
||||
*value = (float *)origdata;
|
||||
return (TIFFReadDirEntryErrOk);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
data = (float *)_TIFFmallocExt(tif, count * sizeof(float));
|
||||
data =
|
||||
(float *)_TIFFmallocExt(tif, (tmsize_t)((size_t)count * sizeof(float)));
|
||||
if (data == 0)
|
||||
{
|
||||
_TIFFfreeExt(tif, origdata);
|
||||
@@ -2970,14 +3019,16 @@ TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value)
|
||||
for (n = 0; n < count; n++)
|
||||
{
|
||||
double val = *ma++;
|
||||
if (val > FLT_MAX)
|
||||
val = FLT_MAX;
|
||||
else if (val < -FLT_MAX)
|
||||
val = -FLT_MAX;
|
||||
if (val > (double)FLT_MAX)
|
||||
val = (double)FLT_MAX;
|
||||
else if (val < -(double)FLT_MAX)
|
||||
val = -(double)FLT_MAX;
|
||||
*mb++ = (float)val;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_TIFFfreeExt(tif, origdata);
|
||||
*value = data;
|
||||
@@ -3023,8 +3074,11 @@ TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value)
|
||||
TIFFCvtIEEEDoubleToNative(tif, count, (double *)origdata);
|
||||
*value = (double *)origdata;
|
||||
return (TIFFReadDirEntryErrOk);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
data = (double *)_TIFFmallocExt(tif, count * sizeof(double));
|
||||
data = (double *)_TIFFmallocExt(tif,
|
||||
(tmsize_t)((size_t)count * sizeof(double)));
|
||||
if (data == 0)
|
||||
{
|
||||
_TIFFfreeExt(tif, origdata);
|
||||
@@ -3207,6 +3261,8 @@ TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value)
|
||||
*mb++ = (double)(*ma++);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_TIFFfreeExt(tif, origdata);
|
||||
*value = data;
|
||||
@@ -3244,6 +3300,8 @@ TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value)
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabArrayOfLong8(*value, count);
|
||||
return (TIFFReadDirEntryErrOk);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
data = (uint64_t *)_TIFFmallocExt(tif, count * 8);
|
||||
if (data == 0)
|
||||
@@ -3269,6 +3327,8 @@ TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value)
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_TIFFfreeExt(tif, origdata);
|
||||
*value = data;
|
||||
@@ -3283,13 +3343,42 @@ TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry,
|
||||
uint16_t *m;
|
||||
uint16_t *na;
|
||||
uint16_t nb;
|
||||
if (direntry->tdir_count < (uint64_t)tif->tif_dir.td_samplesperpixel)
|
||||
return (TIFFReadDirEntryErrCount);
|
||||
if (direntry->tdir_count != (uint64_t)tif->tif_dir.td_samplesperpixel)
|
||||
{
|
||||
const TIFFField *fip = TIFFFieldWithTag(tif, direntry->tdir_tag);
|
||||
if (direntry->tdir_count == 0)
|
||||
{
|
||||
return TIFFReadDirEntryErrCount;
|
||||
}
|
||||
else if (direntry->tdir_count <
|
||||
(uint64_t)tif->tif_dir.td_samplesperpixel)
|
||||
{
|
||||
TIFFWarningExtR(
|
||||
tif, "TIFFReadDirEntryPersampleShort",
|
||||
"Tag %s entry count is %" PRIu64
|
||||
" , whereas it should be SamplesPerPixel=%d. Assuming that "
|
||||
"missing entries are all at the value of the first one",
|
||||
fip ? fip->field_name : "unknown tagname", direntry->tdir_count,
|
||||
tif->tif_dir.td_samplesperpixel);
|
||||
}
|
||||
else
|
||||
{
|
||||
TIFFWarningExtR(tif, "TIFFReadDirEntryPersampleShort",
|
||||
"Tag %s entry count is %" PRIu64
|
||||
" , whereas it should be SamplesPerPixel=%d. "
|
||||
"Ignoring extra entries",
|
||||
fip ? fip->field_name : "unknown tagname",
|
||||
direntry->tdir_count,
|
||||
tif->tif_dir.td_samplesperpixel);
|
||||
}
|
||||
}
|
||||
err = TIFFReadDirEntryShortArray(tif, direntry, &m);
|
||||
if (err != TIFFReadDirEntryErrOk || m == NULL)
|
||||
return (err);
|
||||
na = m;
|
||||
nb = tif->tif_dir.td_samplesperpixel;
|
||||
if (direntry->tdir_count < nb)
|
||||
nb = (uint16_t)direntry->tdir_count;
|
||||
*value = *na++;
|
||||
nb--;
|
||||
while (nb > 0)
|
||||
@@ -3908,7 +3997,7 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset,
|
||||
{
|
||||
return TIFFReadDirEntryErrIo;
|
||||
}
|
||||
mb = ma + size;
|
||||
mb = (uint64_t)ma + (uint64_t)size;
|
||||
if (mb > (uint64_t)tif->tif_size)
|
||||
return (TIFFReadDirEntryErrIo);
|
||||
_TIFFmemcpy(dest, tif->tif_base + ma, size);
|
||||
@@ -3955,6 +4044,7 @@ static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err,
|
||||
TIFFErrorExtR(tif, module, "Out of memory reading of \"%s\"",
|
||||
tagname);
|
||||
break;
|
||||
case TIFFReadDirEntryErrOk:
|
||||
default:
|
||||
assert(0); /* we should never get here */
|
||||
break;
|
||||
@@ -4001,6 +4091,7 @@ static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err,
|
||||
"Out of memory reading of \"%s\"; tag ignored",
|
||||
tagname);
|
||||
break;
|
||||
case TIFFReadDirEntryErrOk:
|
||||
default:
|
||||
assert(0); /* we should never get here */
|
||||
break;
|
||||
@@ -4086,7 +4177,8 @@ static int ByteCountLooksBad(TIFF *tif)
|
||||
*/
|
||||
static bool EvaluateIFDdatasizeReading(TIFF *tif, TIFFDirEntry *dp)
|
||||
{
|
||||
const uint64_t data_width = TIFFDataWidth(dp->tdir_type);
|
||||
const uint64_t data_width =
|
||||
(uint64_t)TIFFDataWidth((TIFFDataType)dp->tdir_type);
|
||||
if (data_width != 0 && dp->tdir_count > UINT64_MAX / data_width)
|
||||
{
|
||||
TIFFErrorExtR(tif, "EvaluateIFDdatasizeReading",
|
||||
@@ -4173,9 +4265,9 @@ static void CalcFinalIFDdatasizeReading(TIFF *tif, uint16_t dircount)
|
||||
/* Get offset of end of IFD entry space. */
|
||||
uint64_t IFDendoffset;
|
||||
if (!(tif->tif_flags & TIFF_BIGTIFF))
|
||||
IFDendoffset = tif->tif_diroff + 2 + dircount * 12 + 4;
|
||||
IFDendoffset = tif->tif_diroff + 2 + (uint64_t)dircount * 12 + 4;
|
||||
else
|
||||
IFDendoffset = tif->tif_diroff + 8 + dircount * 20 + 8;
|
||||
IFDendoffset = tif->tif_diroff + 8 + (uint64_t)dircount * 20 + 8;
|
||||
|
||||
/* Check which offsets are right behind IFD entries. However, LibTIFF
|
||||
* increments the writing address for every external data to an even offset.
|
||||
@@ -4224,9 +4316,9 @@ static void CalcFinalIFDdatasizeReading(TIFF *tif, uint16_t dircount)
|
||||
|
||||
/* Finally, add the size of the IFD tag entries themselves. */
|
||||
if (!(tif->tif_flags & TIFF_BIGTIFF))
|
||||
tif->tif_dir.td_dirdatasize_read = 2 + dircount * 12 + 4 + size;
|
||||
tif->tif_dir.td_dirdatasize_read = 2U + dircount * 12U + 4U + size;
|
||||
else
|
||||
tif->tif_dir.td_dirdatasize_read = 8 + dircount * 20 + 8 + size;
|
||||
tif->tif_dir.td_dirdatasize_read = 8U + dircount * 20U + 8U + size;
|
||||
} /*-- CalcFinalIFDdatasizeReading() --*/
|
||||
|
||||
/*
|
||||
@@ -4298,7 +4390,8 @@ int TIFFReadDirectory(TIFF *tif)
|
||||
{
|
||||
TIFFDirEntry *na;
|
||||
uint16_t nb;
|
||||
for (na = ma + 1, nb = mb + 1; nb < dircount; na++, nb++)
|
||||
for (na = ma + 1, nb = (uint16_t)(mb + 1); nb < dircount;
|
||||
na++, nb++)
|
||||
{
|
||||
if (ma->tdir_tag == na->tdir_tag)
|
||||
{
|
||||
@@ -4312,7 +4405,15 @@ int TIFFReadDirectory(TIFF *tif)
|
||||
tif->tif_flags &= ~TIFF_BUF4WRITE; /* reset before new dir */
|
||||
tif->tif_flags &= ~TIFF_CHOPPEDUPARRAYS;
|
||||
|
||||
/* free any old stuff and reinit */
|
||||
/* When changing directory, in deferred strile loading mode, we must also
|
||||
* unset the TIFF_LAZYSTRILELOAD_DONE bit if it was initially set,
|
||||
* to make sure the strile offset/bytecount are read again (when they fit
|
||||
* in the tag data area).
|
||||
*/
|
||||
tif->tif_flags &= ~TIFF_LAZYSTRILELOAD_DONE;
|
||||
|
||||
/* Free any old stuff and reinit i/o and other parameters within
|
||||
* TIFFDefaultDirectory() since we are starting on a new directory. */
|
||||
TIFFFreeDirectory(tif);
|
||||
TIFFDefaultDirectory(tif);
|
||||
|
||||
@@ -4325,7 +4426,8 @@ int TIFFReadDirectory(TIFF *tif)
|
||||
* checking. Note: Counter are reset within TIFFFreeDirectory(). */
|
||||
tif->tif_dir.td_dirdatasize_offsets =
|
||||
(TIFFEntryOffsetAndLength *)_TIFFmallocExt(
|
||||
tif, dircount * sizeof(TIFFEntryOffsetAndLength));
|
||||
tif,
|
||||
(tmsize_t)((size_t)dircount * sizeof(TIFFEntryOffsetAndLength)));
|
||||
if (tif->tif_dir.td_dirdatasize_offsets == NULL)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
@@ -4788,8 +4890,8 @@ int TIFFReadDirectory(TIFF *tif)
|
||||
(void)TIFFFetchNormalTag(tif, dp, TRUE);
|
||||
break;
|
||||
} /* -- switch (dp->tdir_tag) -- */
|
||||
} /* -- if (!dp->tdir_ignore) */
|
||||
} /* -- for-loop -- */
|
||||
} /* -- if (!dp->tdir_ignore) */
|
||||
} /* -- for-loop -- */
|
||||
|
||||
/* Evaluate final IFD data size. */
|
||||
CalcFinalIFDdatasizeReading(tif, dircount);
|
||||
@@ -5098,7 +5200,7 @@ int TIFFReadDirectory(TIFF *tif)
|
||||
tif->tif_dir.td_maxsamplevalue = 0xFFFF;
|
||||
else
|
||||
tif->tif_dir.td_maxsamplevalue =
|
||||
(uint16_t)((1L << tif->tif_dir.td_bitspersample) - 1);
|
||||
(uint16_t)((1 << tif->tif_dir.td_bitspersample) - 1);
|
||||
}
|
||||
|
||||
#ifdef STRIPBYTECOUNTSORTED_UNUSED
|
||||
@@ -5164,16 +5266,10 @@ int TIFFReadDirectory(TIFF *tif)
|
||||
tif->tif_flags &= ~TIFF_DIRTYSTRIP;
|
||||
|
||||
/*
|
||||
* Reinitialize i/o since we are starting on a new directory.
|
||||
* Reinitialize some further i/o since we are starting on a new directory.
|
||||
*/
|
||||
tif->tif_row = (uint32_t)-1;
|
||||
tif->tif_curstrip = (uint32_t)-1;
|
||||
tif->tif_col = (uint32_t)-1;
|
||||
tif->tif_curtile = (uint32_t)-1;
|
||||
tif->tif_tilesize = (tmsize_t)-1;
|
||||
|
||||
tif->tif_scanlinesize = TIFFScanlineSize(tif);
|
||||
if (!tif->tif_scanlinesize)
|
||||
tif->tif_dir.td_scanlinesize = TIFFScanlineSize(tif);
|
||||
if (!tif->tif_dir.td_scanlinesize)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Cannot handle zero scanline size");
|
||||
return (0);
|
||||
@@ -5181,8 +5277,8 @@ int TIFFReadDirectory(TIFF *tif)
|
||||
|
||||
if (isTiled(tif))
|
||||
{
|
||||
tif->tif_tilesize = TIFFTileSize(tif);
|
||||
if (!tif->tif_tilesize)
|
||||
tif->tif_dir.td_tilesize = TIFFTileSize(tif);
|
||||
if (!tif->tif_dir.td_tilesize)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Cannot handle zero tile size");
|
||||
return (0);
|
||||
@@ -5220,7 +5316,7 @@ static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir,
|
||||
"ascending order");
|
||||
break;
|
||||
}
|
||||
m = o->tdir_tag + 1;
|
||||
m = o->tdir_tag + 1U;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5268,7 +5364,7 @@ static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid,
|
||||
break;
|
||||
mb--;
|
||||
}
|
||||
*fii = mb;
|
||||
*fii = (uint32_t)mb;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5308,7 +5404,8 @@ int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff,
|
||||
{
|
||||
TIFFDirEntry *na;
|
||||
uint16_t nb;
|
||||
for (na = ma + 1, nb = mb + 1; nb < dircount; na++, nb++)
|
||||
for (na = ma + 1, nb = (uint16_t)(mb + 1); nb < dircount;
|
||||
na++, nb++)
|
||||
{
|
||||
if (ma->tdir_tag == na->tdir_tag)
|
||||
{
|
||||
@@ -5333,7 +5430,8 @@ int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff,
|
||||
* checking. Note: Counter are reset within TIFFFreeDirectory(). */
|
||||
tif->tif_dir.td_dirdatasize_offsets =
|
||||
(TIFFEntryOffsetAndLength *)_TIFFmallocExt(
|
||||
tif, dircount * sizeof(TIFFEntryOffsetAndLength));
|
||||
tif,
|
||||
(tmsize_t)((size_t)dircount * sizeof(TIFFEntryOffsetAndLength)));
|
||||
if (tif->tif_dir.td_dirdatasize_offsets == NULL)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
@@ -5515,15 +5613,17 @@ static int EstimateStripByteCounts(TIFF *tif, TIFFDirEntry *dir,
|
||||
uint64_t space;
|
||||
uint16_t n;
|
||||
if (!(tif->tif_flags & TIFF_BIGTIFF))
|
||||
space = sizeof(TIFFHeaderClassic) + 2 + dircount * 12 + 4;
|
||||
space = sizeof(TIFFHeaderClassic) + 2 +
|
||||
(unsigned long)dircount * 12 + 4;
|
||||
else
|
||||
space = sizeof(TIFFHeaderBig) + 8 + dircount * 20 + 8;
|
||||
space =
|
||||
sizeof(TIFFHeaderBig) + 8 + (unsigned long)dircount * 20 + 8;
|
||||
/* calculate amount of space used by indirect values */
|
||||
for (dp = dir, n = dircount; n > 0; n--, dp++)
|
||||
{
|
||||
uint32_t typewidth;
|
||||
uint64_t datasize;
|
||||
typewidth = TIFFDataWidth((TIFFDataType)dp->tdir_type);
|
||||
typewidth = (uint32_t)TIFFDataWidth((TIFFDataType)dp->tdir_type);
|
||||
if (typewidth == 0)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
@@ -5786,7 +5886,7 @@ int _TIFFCheckDirNumberAndOffset(TIFF *tif, tdir_t dirn, uint64_t diroff)
|
||||
{
|
||||
TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
|
||||
"Cannot handle more than %u TIFF directories",
|
||||
TIFF_MAX_DIR_COUNT);
|
||||
(unsigned)TIFF_MAX_DIR_COUNT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6048,7 +6148,7 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
|
||||
"to read TIFF directory");
|
||||
if (origdir == NULL)
|
||||
return 0;
|
||||
if (!ReadOK(tif, origdir, (tmsize_t)(dircount16 * dirsize)))
|
||||
if (!ReadOK(tif, origdir, (tmsize_t)dircount16 * dirsize))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "%.100s: Can not read TIFF directory",
|
||||
tif->tif_name);
|
||||
@@ -6101,9 +6201,9 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
|
||||
*/
|
||||
if (!(tif->tif_flags & TIFF_BIGTIFF))
|
||||
{
|
||||
m = off + sizeof(uint16_t);
|
||||
if ((m < off) || (m < (tmsize_t)sizeof(uint16_t)) ||
|
||||
(m > tif->tif_size))
|
||||
m = (tmsize_t)((uint64_t)off + sizeof(uint16_t));
|
||||
if ((m < off) || ((uint64_t)m < sizeof(uint16_t)) ||
|
||||
((uint64_t)m > (uint64_t)tif->tif_size))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Can not read TIFF directory count");
|
||||
return 0;
|
||||
@@ -6112,7 +6212,7 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
|
||||
{
|
||||
_TIFFmemcpy(&dircount16, tif->tif_base + off, sizeof(uint16_t));
|
||||
}
|
||||
off += sizeof(uint16_t);
|
||||
off = (tmsize_t)((uint64_t)off + sizeof(uint16_t));
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabShort(&dircount16);
|
||||
if (dircount16 > 4096)
|
||||
@@ -6127,9 +6227,9 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
|
||||
else
|
||||
{
|
||||
uint64_t dircount64;
|
||||
m = off + sizeof(uint64_t);
|
||||
if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) ||
|
||||
(m > tif->tif_size))
|
||||
m = (tmsize_t)((uint64_t)off + sizeof(uint64_t));
|
||||
if ((m < off) || ((uint64_t)m < sizeof(uint64_t)) ||
|
||||
((uint64_t)m > (uint64_t)tif->tif_size))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Can not read TIFF directory count");
|
||||
return 0;
|
||||
@@ -6138,7 +6238,7 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
|
||||
{
|
||||
_TIFFmemcpy(&dircount64, tif->tif_base + off, sizeof(uint64_t));
|
||||
}
|
||||
off += sizeof(uint64_t);
|
||||
off = (tmsize_t)((uint64_t)off + sizeof(uint64_t));
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabLong8(&dircount64);
|
||||
if (dircount64 > 4096)
|
||||
@@ -6177,7 +6277,7 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
|
||||
if (origdir == NULL)
|
||||
return 0;
|
||||
m = off + dircount16 * dirsize;
|
||||
if ((m < off) || (m < (tmsize_t)(dircount16 * dirsize)) ||
|
||||
if ((m < off) || (m < (tmsize_t)dircount16 * (tmsize_t)dirsize) ||
|
||||
(m > tif->tif_size))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Can not read TIFF directory");
|
||||
@@ -6186,7 +6286,8 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
|
||||
}
|
||||
else
|
||||
{
|
||||
_TIFFmemcpy(origdir, tif->tif_base + off, dircount16 * dirsize);
|
||||
_TIFFmemcpy(origdir, tif->tif_base + off,
|
||||
(tmsize_t)dircount16 * dirsize);
|
||||
}
|
||||
if (nextdiroff)
|
||||
{
|
||||
@@ -6194,9 +6295,9 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
|
||||
if (!(tif->tif_flags & TIFF_BIGTIFF))
|
||||
{
|
||||
uint32_t nextdiroff32;
|
||||
m = off + sizeof(uint32_t);
|
||||
if ((m < off) || (m < (tmsize_t)sizeof(uint32_t)) ||
|
||||
(m > tif->tif_size))
|
||||
m = (tmsize_t)((uint64_t)off + sizeof(uint32_t));
|
||||
if ((m < off) || ((uint64_t)m < sizeof(uint32_t)) ||
|
||||
((uint64_t)m > (uint64_t)tif->tif_size))
|
||||
nextdiroff32 = 0;
|
||||
else
|
||||
_TIFFmemcpy(&nextdiroff32, tif->tif_base + off,
|
||||
@@ -6207,9 +6308,9 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
|
||||
}
|
||||
else
|
||||
{
|
||||
m = off + sizeof(uint64_t);
|
||||
if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) ||
|
||||
(m > tif->tif_size))
|
||||
m = (tmsize_t)((uint64_t)off + sizeof(uint64_t));
|
||||
if ((m < off) || ((uint64_t)m < sizeof(uint64_t)) ||
|
||||
((uint64_t)m > (uint64_t)tif->tif_size))
|
||||
*nextdiroff = 0;
|
||||
else
|
||||
_TIFFmemcpy(nextdiroff, tif->tif_base + off,
|
||||
@@ -6355,8 +6456,8 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover)
|
||||
/* TIFFReadDirEntryArrayWithLimit() ensures this can't be
|
||||
* larger than MAX_SIZE_TAG_DATA */
|
||||
assert((uint32_t)dp->tdir_count + 1 == dp->tdir_count + 1);
|
||||
uint8_t *o =
|
||||
_TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1);
|
||||
uint8_t *o = (uint8_t *)_TIFFmallocExt(
|
||||
tif, (uint32_t)dp->tdir_count + 1);
|
||||
if (o == NULL)
|
||||
{
|
||||
if (data != NULL)
|
||||
@@ -6498,7 +6599,7 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover)
|
||||
{
|
||||
if (!EvaluateIFDdatasizeReading(tif, dp))
|
||||
return 0;
|
||||
if (!TIFFSetField(tif, dp->tdir_tag, data))
|
||||
if (!TIFFSetField(tif, dp->tdir_tag, (double)data))
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
@@ -6910,6 +7011,41 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TIFF_SETGET_C0_IFD8:
|
||||
{
|
||||
uint64_t *data;
|
||||
assert(fip->field_readcount >= 1);
|
||||
assert(fip->field_passcount == 0);
|
||||
if (dp->tdir_count != (uint64_t)fip->field_readcount)
|
||||
{
|
||||
TIFFWarningExtR(tif, module,
|
||||
"incorrect count for field \"%s\", expected "
|
||||
"%d, got %" PRIu64,
|
||||
fip->field_name, (int)fip->field_readcount,
|
||||
dp->tdir_count);
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = TIFFReadDirEntryIfd8Array(tif, dp, &data);
|
||||
if (err == TIFFReadDirEntryErrOk)
|
||||
{
|
||||
if (!EvaluateIFDdatasizeReading(tif, dp))
|
||||
{
|
||||
if (data != 0)
|
||||
_TIFFfreeExt(tif, data);
|
||||
return 0;
|
||||
}
|
||||
int m;
|
||||
m = TIFFSetField(tif, dp->tdir_tag, data);
|
||||
if (data != 0)
|
||||
_TIFFfreeExt(tif, data);
|
||||
if (!m)
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TIFF_SETGET_C16_ASCII:
|
||||
{
|
||||
uint8_t *data;
|
||||
@@ -6938,8 +7074,8 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover)
|
||||
"byte. Forcing it to be null",
|
||||
fip->field_name);
|
||||
/* Enlarge buffer and add terminating null. */
|
||||
uint8_t *o =
|
||||
_TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1);
|
||||
uint8_t *o = (uint8_t *)_TIFFmallocExt(
|
||||
tif, (uint32_t)dp->tdir_count + 1);
|
||||
if (o == NULL)
|
||||
{
|
||||
if (data != NULL)
|
||||
@@ -7309,8 +7445,8 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover)
|
||||
"in null byte. Forcing it to be null",
|
||||
fip->field_name);
|
||||
/* Enlarge buffer and add terminating null. */
|
||||
uint8_t *o =
|
||||
_TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1);
|
||||
uint8_t *o = (uint8_t *)_TIFFmallocExt(
|
||||
tif, (uint32_t)dp->tdir_count + 1);
|
||||
if (o == NULL)
|
||||
{
|
||||
if (data != NULL)
|
||||
@@ -7624,6 +7760,11 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TIFF_SETGET_INT:
|
||||
case TIFF_SETGET_C0_ASCII:
|
||||
case TIFF_SETGET_OTHER:
|
||||
assert(0); /* these should not arrive here */
|
||||
break;
|
||||
default:
|
||||
assert(0); /* we should never get here */
|
||||
break;
|
||||
@@ -7700,9 +7841,10 @@ static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips,
|
||||
}
|
||||
if (dir->tdir_count)
|
||||
_TIFFmemcpy(resizeddata, data,
|
||||
(uint32_t)dir->tdir_count * sizeof(uint64_t));
|
||||
(tmsize_t)((size_t)dir->tdir_count * sizeof(uint64_t)));
|
||||
_TIFFmemset(resizeddata + (uint32_t)dir->tdir_count, 0,
|
||||
(nstrips - (uint32_t)dir->tdir_count) * sizeof(uint64_t));
|
||||
(tmsize_t)((size_t)(nstrips - (uint32_t)dir->tdir_count) *
|
||||
sizeof(uint64_t)));
|
||||
_TIFFfreeExt(tif, data);
|
||||
data = resizeddata;
|
||||
}
|
||||
@@ -7866,7 +8008,7 @@ static void allocChoppedUpStripArrays(TIFF *tif, uint32_t nstrips,
|
||||
*/
|
||||
static void ChopUpSingleUncompressedStrip(TIFF *tif)
|
||||
{
|
||||
register TIFFDirectory *td = &tif->tif_dir;
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
uint64_t bytecount;
|
||||
uint64_t offset;
|
||||
uint32_t rowblock;
|
||||
@@ -7881,7 +8023,7 @@ static void ChopUpSingleUncompressedStrip(TIFF *tif)
|
||||
/* later ( StripOffsets and StripByteCounts improperly filled) . */
|
||||
if (bytecount == 0 && tif->tif_mode != O_RDONLY)
|
||||
return;
|
||||
offset = TIFFGetStrileByteCount(tif, 0);
|
||||
offset = TIFFGetStrileOffset(tif, 0);
|
||||
assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
|
||||
if ((td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif)))
|
||||
rowblock = td->td_ycbcrsubsampling[1];
|
||||
@@ -8032,7 +8174,7 @@ static void TryChopUpUncompressedBigTiff(TIFF *tif)
|
||||
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
|
||||
static uint64_t _TIFFUnsanitizedAddUInt64AndInt(uint64_t a, int b)
|
||||
{
|
||||
return a + b;
|
||||
return a + (uint64_t)b;
|
||||
}
|
||||
|
||||
/* Read the value of [Strip|Tile]Offset or [Strip|Tile]ByteCount around
|
||||
@@ -8111,7 +8253,7 @@ static int _TIFFPartialReadStripArray(TIFF *tif, TIFFDirEntry *dirent,
|
||||
panVals[strile] = 0;
|
||||
return 0;
|
||||
}
|
||||
nOffset = nBaseOffset + sizeofval * strile;
|
||||
nOffset = nBaseOffset + (uint64_t)sizeofval * (uint64_t)strile;
|
||||
nOffsetStartPage = (nOffset / IO_CACHE_PAGE_SIZE) * IO_CACHE_PAGE_SIZE;
|
||||
nOffsetEndPage = nOffsetStartPage + IO_CACHE_PAGE_SIZE;
|
||||
|
||||
@@ -8119,7 +8261,7 @@ static int _TIFFPartialReadStripArray(TIFF *tif, TIFFDirEntry *dirent,
|
||||
nOffsetEndPage += IO_CACHE_PAGE_SIZE;
|
||||
#undef IO_CACHE_PAGE_SIZE
|
||||
|
||||
nLastStripOffset = nBaseOffset + arraySize * sizeofval;
|
||||
nLastStripOffset = nBaseOffset + (uint64_t)arraySize * sizeofval;
|
||||
if (nLastStripOffset < nOffsetEndPage)
|
||||
nOffsetEndPage = nLastStripOffset;
|
||||
if (nOffsetStartPage >= nOffsetEndPage)
|
||||
@@ -8254,9 +8396,9 @@ static int _TIFFFetchStrileValue(TIFF *tif, uint32_t strile,
|
||||
}
|
||||
#endif
|
||||
offsetArray = (uint64_t *)(_TIFFreallocExt(tif, td->td_stripoffset_p,
|
||||
nArraySize));
|
||||
(tmsize_t)nArraySize));
|
||||
bytecountArray = (uint64_t *)(_TIFFreallocExt(
|
||||
tif, td->td_stripbytecount_p, nArraySize));
|
||||
tif, td->td_stripbytecount_p, (tmsize_t)nArraySize));
|
||||
if (offsetArray)
|
||||
td->td_stripoffset_p = offsetArray;
|
||||
if (bytecountArray)
|
||||
@@ -8290,7 +8432,7 @@ static int _TIFFFetchStrileValue(TIFF *tif, uint32_t strile,
|
||||
|
||||
if (~((*parray)[strile]) == 0)
|
||||
{
|
||||
if (!_TIFFPartialReadStripArray(tif, dirent, strile, *parray))
|
||||
if (!_TIFFPartialReadStripArray(tif, dirent, (int)strile, *parray))
|
||||
{
|
||||
(*parray)[strile] = 0;
|
||||
return 0;
|
||||
@@ -8308,10 +8450,26 @@ static uint64_t _TIFFGetStrileOffsetOrByteCountValue(TIFF *tif, uint32_t strile,
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
if (pbErr)
|
||||
*pbErr = 0;
|
||||
|
||||
/* Avoid the "dirent->tdir_count <= 4" code path for one of
|
||||
* StripOffsets/StripByteCounts, and the other code path for the other one,
|
||||
* which will lead to inconsistencies and potential out-of-bounds reads.
|
||||
*/
|
||||
if ((td->td_stripoffset_entry.tdir_count <= 4) !=
|
||||
(td->td_stripbytecount_entry.tdir_count <= 4))
|
||||
{
|
||||
TIFFErrorExtR(tif, "_TIFFGetStrileOffsetOrByteCountValue",
|
||||
"Inconsistent directory count between StripOffsets and "
|
||||
"StripByteCounts");
|
||||
if (pbErr)
|
||||
*pbErr = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((tif->tif_flags & TIFF_DEFERSTRILELOAD) &&
|
||||
!(tif->tif_flags & TIFF_CHOPPEDUPARRAYS))
|
||||
{
|
||||
if (!(tif->tif_flags & TIFF_LAZYSTRILELOAD) ||
|
||||
if (!(tif->tif_flags & TIFF_LAZYSTRILELOAD_ASKED) ||
|
||||
/* If the values may fit in the toff_long/toff_long8 member */
|
||||
/* then use _TIFFFillStriles to simplify _TIFFFetchStrileValue */
|
||||
dirent->tdir_count <= 4)
|
||||
@@ -8382,7 +8540,7 @@ int _TIFFFillStriles(TIFF *tif) { return _TIFFFillStrilesInternal(tif, 1); }
|
||||
|
||||
static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount)
|
||||
{
|
||||
register TIFFDirectory *td = &tif->tif_dir;
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
int return_value = 1;
|
||||
|
||||
/* Do not do anything if TIFF_DEFERSTRILELOAD is not set */
|
||||
@@ -8390,7 +8548,8 @@ static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount)
|
||||
(tif->tif_flags & TIFF_CHOPPEDUPARRAYS) != 0)
|
||||
return 1;
|
||||
|
||||
if (tif->tif_flags & TIFF_LAZYSTRILELOAD)
|
||||
if ((tif->tif_flags & TIFF_LAZYSTRILELOAD_ASKED) &&
|
||||
!(tif->tif_flags & TIFF_LAZYSTRILELOAD_DONE))
|
||||
{
|
||||
/* In case of lazy loading, reload completely the arrays */
|
||||
_TIFFfreeExt(tif, td->td_stripoffset_p);
|
||||
@@ -8398,7 +8557,7 @@ static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount)
|
||||
td->td_stripoffset_p = NULL;
|
||||
td->td_stripbytecount_p = NULL;
|
||||
td->td_stripoffsetbyteallocsize = 0;
|
||||
tif->tif_flags &= ~TIFF_LAZYSTRILELOAD;
|
||||
tif->tif_flags |= TIFF_LAZYSTRILELOAD_DONE;
|
||||
}
|
||||
|
||||
/* If stripoffset array is already loaded, exit with success */
|
||||
|
||||
364
3rdparty/libtiff/tif_dirwrite.c
vendored
364
3rdparty/libtiff/tif_dirwrite.c
vendored
@@ -365,7 +365,7 @@ static int TIFFRewriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
}
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabShort(&dircount);
|
||||
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
|
||||
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12U, SEEK_SET);
|
||||
if (!ReadOK(tif, &nextnextdir, 4))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error fetching directory link");
|
||||
@@ -377,7 +377,7 @@ static int TIFFRewriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
{
|
||||
uint32_t m;
|
||||
m = 0;
|
||||
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12,
|
||||
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12U,
|
||||
SEEK_SET);
|
||||
if (!WriteOK(tif, &m, 4))
|
||||
{
|
||||
@@ -417,7 +417,6 @@ static int TIFFRewriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
while (1)
|
||||
{
|
||||
uint64_t dircount64;
|
||||
uint16_t dircount;
|
||||
uint64_t nextnextdir;
|
||||
|
||||
if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8))
|
||||
@@ -435,8 +434,8 @@ static int TIFFRewriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
"corrupt TIFF");
|
||||
return (0);
|
||||
}
|
||||
dircount = (uint16_t)dircount64;
|
||||
(void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
|
||||
(void)TIFFSeekFile(tif, nextdir + 8 + dircount64 * 20,
|
||||
SEEK_SET);
|
||||
if (!ReadOK(tif, &nextnextdir, 8))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error fetching directory link");
|
||||
@@ -448,7 +447,7 @@ static int TIFFRewriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
{
|
||||
uint64_t m;
|
||||
m = 0;
|
||||
(void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20,
|
||||
(void)TIFFSeekFile(tif, nextdir + 8 + dircount64 * 20,
|
||||
SEEK_SET);
|
||||
if (!WriteOK(tif, &m, 8))
|
||||
{
|
||||
@@ -592,24 +591,24 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
}
|
||||
if (TIFFFieldSet(tif, FIELD_RESOLUTION))
|
||||
{
|
||||
if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
|
||||
TIFFTAG_XRESOLUTION,
|
||||
tif->tif_dir.td_xresolution))
|
||||
if (!TIFFWriteDirectoryTagRational(
|
||||
tif, &ndir, dir, TIFFTAG_XRESOLUTION,
|
||||
(double)tif->tif_dir.td_xresolution))
|
||||
goto bad;
|
||||
if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
|
||||
TIFFTAG_YRESOLUTION,
|
||||
tif->tif_dir.td_yresolution))
|
||||
if (!TIFFWriteDirectoryTagRational(
|
||||
tif, &ndir, dir, TIFFTAG_YRESOLUTION,
|
||||
(double)tif->tif_dir.td_yresolution))
|
||||
goto bad;
|
||||
}
|
||||
if (TIFFFieldSet(tif, FIELD_POSITION))
|
||||
{
|
||||
if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
|
||||
TIFFTAG_XPOSITION,
|
||||
tif->tif_dir.td_xposition))
|
||||
if (!TIFFWriteDirectoryTagRational(
|
||||
tif, &ndir, dir, TIFFTAG_XPOSITION,
|
||||
(double)tif->tif_dir.td_xposition))
|
||||
goto bad;
|
||||
if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
|
||||
TIFFTAG_YPOSITION,
|
||||
tif->tif_dir.td_yposition))
|
||||
if (!TIFFWriteDirectoryTagRational(
|
||||
tif, &ndir, dir, TIFFTAG_YPOSITION,
|
||||
(double)tif->tif_dir.td_yposition))
|
||||
goto bad;
|
||||
}
|
||||
if (TIFFFieldSet(tif, FIELD_SUBFILETYPE))
|
||||
@@ -712,6 +711,14 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
}
|
||||
if (TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS))
|
||||
{
|
||||
/* Check td_stripbytecount_p for NULL pointer (bug#749) */
|
||||
if (tif->tif_dir.td_stripbytecount_p == NULL)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
tif, module,
|
||||
"StripByteCount array is not set, pointer is NULL");
|
||||
goto bad;
|
||||
}
|
||||
if (!isTiled(tif))
|
||||
{
|
||||
if (!TIFFWriteDirectoryTagLongLong8Array(
|
||||
@@ -731,6 +738,14 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
}
|
||||
if (TIFFFieldSet(tif, FIELD_STRIPOFFSETS))
|
||||
{
|
||||
/* Check td_stripoffset_p for NULL pointer (bug#749) */
|
||||
if (tif->tif_dir.td_stripoffset_p == NULL)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
tif, module,
|
||||
"StripByteOffset array is not set, pointer is NULL");
|
||||
goto bad;
|
||||
}
|
||||
if (!isTiled(tif))
|
||||
{
|
||||
/* td_stripoffset_p might be NULL in an odd OJPEG case. See
|
||||
@@ -851,7 +866,8 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
{
|
||||
if (!TIFFWriteDirectoryTagAscii(
|
||||
tif, &ndir, dir, TIFFTAG_INKNAMES,
|
||||
tif->tif_dir.td_inknameslen, tif->tif_dir.td_inknames))
|
||||
(uint32_t)tif->tif_dir.td_inknameslen,
|
||||
tif->tif_dir.td_inknames))
|
||||
goto bad;
|
||||
}
|
||||
if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
|
||||
@@ -932,10 +948,58 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
TIFFGetField(tif, o->field_tag, &pa, &pb);
|
||||
if (!TIFFWriteDirectoryTagUndefinedArray(
|
||||
tif, &ndir, dir, (uint16_t)o->field_tag,
|
||||
pa, pb))
|
||||
pa, (uint8_t *)pb))
|
||||
goto bad;
|
||||
}
|
||||
break;
|
||||
case TIFF_SETGET_UNDEFINED:
|
||||
case TIFF_SETGET_SINT8:
|
||||
case TIFF_SETGET_SINT16:
|
||||
case TIFF_SETGET_SINT32:
|
||||
case TIFF_SETGET_UINT64:
|
||||
case TIFF_SETGET_SINT64:
|
||||
case TIFF_SETGET_FLOAT:
|
||||
case TIFF_SETGET_DOUBLE:
|
||||
case TIFF_SETGET_IFD8:
|
||||
case TIFF_SETGET_INT:
|
||||
case TIFF_SETGET_UINT16_PAIR:
|
||||
case TIFF_SETGET_C0_ASCII:
|
||||
case TIFF_SETGET_C0_UINT8:
|
||||
case TIFF_SETGET_C0_SINT8:
|
||||
case TIFF_SETGET_C0_UINT16:
|
||||
case TIFF_SETGET_C0_SINT16:
|
||||
case TIFF_SETGET_C0_UINT32:
|
||||
case TIFF_SETGET_C0_SINT32:
|
||||
case TIFF_SETGET_C0_UINT64:
|
||||
case TIFF_SETGET_C0_SINT64:
|
||||
case TIFF_SETGET_C0_FLOAT:
|
||||
case TIFF_SETGET_C0_DOUBLE:
|
||||
case TIFF_SETGET_C0_IFD8:
|
||||
case TIFF_SETGET_C16_ASCII:
|
||||
case TIFF_SETGET_C16_UINT8:
|
||||
case TIFF_SETGET_C16_SINT8:
|
||||
case TIFF_SETGET_C16_UINT16:
|
||||
case TIFF_SETGET_C16_SINT16:
|
||||
case TIFF_SETGET_C16_UINT32:
|
||||
case TIFF_SETGET_C16_SINT32:
|
||||
case TIFF_SETGET_C16_UINT64:
|
||||
case TIFF_SETGET_C16_SINT64:
|
||||
case TIFF_SETGET_C16_FLOAT:
|
||||
case TIFF_SETGET_C16_DOUBLE:
|
||||
case TIFF_SETGET_C16_IFD8:
|
||||
case TIFF_SETGET_C32_ASCII:
|
||||
case TIFF_SETGET_C32_SINT8:
|
||||
case TIFF_SETGET_C32_UINT16:
|
||||
case TIFF_SETGET_C32_SINT16:
|
||||
case TIFF_SETGET_C32_UINT32:
|
||||
case TIFF_SETGET_C32_SINT32:
|
||||
case TIFF_SETGET_C32_UINT64:
|
||||
case TIFF_SETGET_C32_SINT64:
|
||||
case TIFF_SETGET_C32_FLOAT:
|
||||
case TIFF_SETGET_C32_DOUBLE:
|
||||
case TIFF_SETGET_C32_IFD8:
|
||||
case TIFF_SETGET_UINT8:
|
||||
case TIFF_SETGET_OTHER:
|
||||
default:
|
||||
TIFFErrorExtR(
|
||||
tif, module,
|
||||
@@ -954,67 +1018,67 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
{
|
||||
uint16_t tag =
|
||||
(uint16_t)tif->tif_dir.td_customValues[m].info->field_tag;
|
||||
uint32_t count = tif->tif_dir.td_customValues[m].count;
|
||||
uint32_t count = (uint32_t)tif->tif_dir.td_customValues[m].count;
|
||||
switch (tif->tif_dir.td_customValues[m].info->field_type)
|
||||
{
|
||||
case TIFF_ASCII:
|
||||
if (!TIFFWriteDirectoryTagAscii(
|
||||
tif, &ndir, dir, tag, count,
|
||||
tif->tif_dir.td_customValues[m].value))
|
||||
(char *)tif->tif_dir.td_customValues[m].value))
|
||||
goto bad;
|
||||
break;
|
||||
case TIFF_UNDEFINED:
|
||||
if (!TIFFWriteDirectoryTagUndefinedArray(
|
||||
tif, &ndir, dir, tag, count,
|
||||
tif->tif_dir.td_customValues[m].value))
|
||||
(uint8_t *)tif->tif_dir.td_customValues[m].value))
|
||||
goto bad;
|
||||
break;
|
||||
case TIFF_BYTE:
|
||||
if (!TIFFWriteDirectoryTagByteArray(
|
||||
tif, &ndir, dir, tag, count,
|
||||
tif->tif_dir.td_customValues[m].value))
|
||||
(uint8_t *)tif->tif_dir.td_customValues[m].value))
|
||||
goto bad;
|
||||
break;
|
||||
case TIFF_SBYTE:
|
||||
if (!TIFFWriteDirectoryTagSbyteArray(
|
||||
tif, &ndir, dir, tag, count,
|
||||
tif->tif_dir.td_customValues[m].value))
|
||||
(int8_t *)tif->tif_dir.td_customValues[m].value))
|
||||
goto bad;
|
||||
break;
|
||||
case TIFF_SHORT:
|
||||
if (!TIFFWriteDirectoryTagShortArray(
|
||||
tif, &ndir, dir, tag, count,
|
||||
tif->tif_dir.td_customValues[m].value))
|
||||
(uint16_t *)tif->tif_dir.td_customValues[m].value))
|
||||
goto bad;
|
||||
break;
|
||||
case TIFF_SSHORT:
|
||||
if (!TIFFWriteDirectoryTagSshortArray(
|
||||
tif, &ndir, dir, tag, count,
|
||||
tif->tif_dir.td_customValues[m].value))
|
||||
(int16_t *)tif->tif_dir.td_customValues[m].value))
|
||||
goto bad;
|
||||
break;
|
||||
case TIFF_LONG:
|
||||
if (!TIFFWriteDirectoryTagLongArray(
|
||||
tif, &ndir, dir, tag, count,
|
||||
tif->tif_dir.td_customValues[m].value))
|
||||
(uint32_t *)tif->tif_dir.td_customValues[m].value))
|
||||
goto bad;
|
||||
break;
|
||||
case TIFF_SLONG:
|
||||
if (!TIFFWriteDirectoryTagSlongArray(
|
||||
tif, &ndir, dir, tag, count,
|
||||
tif->tif_dir.td_customValues[m].value))
|
||||
(int32_t *)tif->tif_dir.td_customValues[m].value))
|
||||
goto bad;
|
||||
break;
|
||||
case TIFF_LONG8:
|
||||
if (!TIFFWriteDirectoryTagLong8Array(
|
||||
tif, &ndir, dir, tag, count,
|
||||
tif->tif_dir.td_customValues[m].value))
|
||||
(uint64_t *)tif->tif_dir.td_customValues[m].value))
|
||||
goto bad;
|
||||
break;
|
||||
case TIFF_SLONG8:
|
||||
if (!TIFFWriteDirectoryTagSlong8Array(
|
||||
tif, &ndir, dir, tag, count,
|
||||
tif->tif_dir.td_customValues[m].value))
|
||||
(int64_t *)tif->tif_dir.td_customValues[m].value))
|
||||
goto bad;
|
||||
break;
|
||||
case TIFF_RATIONAL:
|
||||
@@ -1029,7 +1093,8 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
{
|
||||
if (!TIFFWriteDirectoryTagRationalDoubleArray(
|
||||
tif, &ndir, dir, tag, count,
|
||||
tif->tif_dir.td_customValues[m].value))
|
||||
(double *)tif->tif_dir.td_customValues[m]
|
||||
.value))
|
||||
goto bad;
|
||||
}
|
||||
else
|
||||
@@ -1037,7 +1102,7 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
/*-- default should be tv_size == 4 */
|
||||
if (!TIFFWriteDirectoryTagRationalArray(
|
||||
tif, &ndir, dir, tag, count,
|
||||
tif->tif_dir.td_customValues[m].value))
|
||||
(float *)tif->tif_dir.td_customValues[m].value))
|
||||
goto bad;
|
||||
/*-- ToDo: After Testing, this should be removed and
|
||||
* tv_size==4 should be set as default. */
|
||||
@@ -1064,7 +1129,8 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
{
|
||||
if (!TIFFWriteDirectoryTagSrationalDoubleArray(
|
||||
tif, &ndir, dir, tag, count,
|
||||
tif->tif_dir.td_customValues[m].value))
|
||||
(double *)tif->tif_dir.td_customValues[m]
|
||||
.value))
|
||||
goto bad;
|
||||
}
|
||||
else
|
||||
@@ -1072,7 +1138,7 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
/*-- default should be tv_size == 4 */
|
||||
if (!TIFFWriteDirectoryTagSrationalArray(
|
||||
tif, &ndir, dir, tag, count,
|
||||
tif->tif_dir.td_customValues[m].value))
|
||||
(float *)tif->tif_dir.td_customValues[m].value))
|
||||
goto bad;
|
||||
/*-- ToDo: After Testing, this should be removed and
|
||||
* tv_size==4 should be set as default. */
|
||||
@@ -1090,27 +1156,28 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
case TIFF_FLOAT:
|
||||
if (!TIFFWriteDirectoryTagFloatArray(
|
||||
tif, &ndir, dir, tag, count,
|
||||
tif->tif_dir.td_customValues[m].value))
|
||||
(float *)tif->tif_dir.td_customValues[m].value))
|
||||
goto bad;
|
||||
break;
|
||||
case TIFF_DOUBLE:
|
||||
if (!TIFFWriteDirectoryTagDoubleArray(
|
||||
tif, &ndir, dir, tag, count,
|
||||
tif->tif_dir.td_customValues[m].value))
|
||||
(double *)tif->tif_dir.td_customValues[m].value))
|
||||
goto bad;
|
||||
break;
|
||||
case TIFF_IFD:
|
||||
if (!TIFFWriteDirectoryTagIfdArray(
|
||||
tif, &ndir, dir, tag, count,
|
||||
tif->tif_dir.td_customValues[m].value))
|
||||
(uint32_t *)tif->tif_dir.td_customValues[m].value))
|
||||
goto bad;
|
||||
break;
|
||||
case TIFF_IFD8:
|
||||
if (!TIFFWriteDirectoryTagIfdIfd8Array(
|
||||
tif, &ndir, dir, tag, count,
|
||||
tif->tif_dir.td_customValues[m].value))
|
||||
(uint64_t *)tif->tif_dir.td_customValues[m].value))
|
||||
goto bad;
|
||||
break;
|
||||
case TIFF_NOTYPE:
|
||||
default:
|
||||
assert(0); /* we should never get here */
|
||||
break;
|
||||
@@ -1128,7 +1195,8 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
tif->tif_dir.td_dirdatasize_write += 8 + ndir * 20 + 8;
|
||||
|
||||
/* Setup a new directory within first pass. */
|
||||
dir = _TIFFmallocExt(tif, ndir * sizeof(TIFFDirEntry));
|
||||
dir = (TIFFDirEntry *)_TIFFmallocExt(
|
||||
tif, (tmsize_t)((size_t)ndir * sizeof(TIFFDirEntry)));
|
||||
if (dir == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -1238,7 +1306,7 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
uint8_t *n;
|
||||
uint32_t nTmp;
|
||||
TIFFDirEntry *o;
|
||||
n = dirmem;
|
||||
n = (uint8_t *)dirmem;
|
||||
*(uint16_t *)n = (uint16_t)ndir;
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabShort((uint16_t *)n);
|
||||
@@ -1274,7 +1342,7 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
|
||||
{
|
||||
uint8_t *n;
|
||||
TIFFDirEntry *o;
|
||||
n = dirmem;
|
||||
n = (uint8_t *)dirmem;
|
||||
*(uint64_t *)n = ndir;
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabLong8((uint64_t *)n);
|
||||
@@ -1405,7 +1473,7 @@ static int8_t TIFFClampDoubleToInt8(double val)
|
||||
{
|
||||
if (val > 127)
|
||||
return 127;
|
||||
if (val < -128 || val != val)
|
||||
if (val < -128 || isnan(val))
|
||||
return -128;
|
||||
return (int8_t)val;
|
||||
}
|
||||
@@ -1414,7 +1482,7 @@ static int16_t TIFFClampDoubleToInt16(double val)
|
||||
{
|
||||
if (val > 32767)
|
||||
return 32767;
|
||||
if (val < -32768 || val != val)
|
||||
if (val < -32768 || isnan(val))
|
||||
return -32768;
|
||||
return (int16_t)val;
|
||||
}
|
||||
@@ -1423,7 +1491,7 @@ static int32_t TIFFClampDoubleToInt32(double val)
|
||||
{
|
||||
if (val > 0x7FFFFFFF)
|
||||
return 0x7FFFFFFF;
|
||||
if (val < -0x7FFFFFFF - 1 || val != val)
|
||||
if (val < -0x7FFFFFFF - 1 || isnan(val))
|
||||
return -0x7FFFFFFF - 1;
|
||||
return (int32_t)val;
|
||||
}
|
||||
@@ -1432,7 +1500,7 @@ static uint8_t TIFFClampDoubleToUInt8(double val)
|
||||
{
|
||||
if (val < 0)
|
||||
return 0;
|
||||
if (val > 255 || val != val)
|
||||
if (val > 255 || isnan(val))
|
||||
return 255;
|
||||
return (uint8_t)val;
|
||||
}
|
||||
@@ -1441,7 +1509,7 @@ static uint16_t TIFFClampDoubleToUInt16(double val)
|
||||
{
|
||||
if (val < 0)
|
||||
return 0;
|
||||
if (val > 65535 || val != val)
|
||||
if (val > 65535 || isnan(val))
|
||||
return 65535;
|
||||
return (uint16_t)val;
|
||||
}
|
||||
@@ -1450,7 +1518,7 @@ static uint32_t TIFFClampDoubleToUInt32(double val)
|
||||
{
|
||||
if (val < 0)
|
||||
return 0;
|
||||
if (val > 0xFFFFFFFFU || val != val)
|
||||
if (val > 0xFFFFFFFFU || isnan(val))
|
||||
return 0xFFFFFFFFU;
|
||||
return (uint32_t)val;
|
||||
}
|
||||
@@ -1464,7 +1532,7 @@ static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir,
|
||||
void *conv;
|
||||
uint32_t i;
|
||||
int ok;
|
||||
conv = _TIFFmallocExt(tif, count * sizeof(double));
|
||||
conv = _TIFFmallocExt(tif, (tmsize_t)((size_t)count * sizeof(double)));
|
||||
if (conv == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -1603,7 +1671,9 @@ static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir,
|
||||
return (TIFFWriteDirectoryTagCheckedShortArray(
|
||||
tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, NULL));
|
||||
}
|
||||
m = _TIFFmallocExt(tif, tif->tif_dir.td_samplesperpixel * sizeof(uint16_t));
|
||||
m = (uint16_t *)_TIFFmallocExt(
|
||||
tif,
|
||||
(tmsize_t)((size_t)tif->tif_dir.td_samplesperpixel * sizeof(uint16_t)));
|
||||
if (m == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -1664,14 +1734,6 @@ static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir,
|
||||
uint32_t *q;
|
||||
int o;
|
||||
|
||||
/* is this just a counting pass? */
|
||||
if (dir == NULL)
|
||||
{
|
||||
/* only evaluate IFD data size and inc. ndir */
|
||||
return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
|
||||
count, value));
|
||||
}
|
||||
|
||||
/* We always write Long8 for BigTIFF, no checking needed. */
|
||||
if (tif->tif_flags & TIFF_BIGTIFF)
|
||||
return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
|
||||
@@ -1681,7 +1743,8 @@ static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir,
|
||||
** For classic tiff we want to verify everything is in range for long
|
||||
** and convert to long format.
|
||||
*/
|
||||
p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
|
||||
p = (uint32_t *)_TIFFmallocExt(
|
||||
tif, (tmsize_t)((size_t)count * sizeof(uint32_t)));
|
||||
if (p == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -1725,13 +1788,6 @@ static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir,
|
||||
int32_t *q;
|
||||
int o;
|
||||
|
||||
/* is this just a counting pass? */
|
||||
if (dir == NULL)
|
||||
{
|
||||
/* only evaluate IFD data size and inc. ndir */
|
||||
return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag,
|
||||
count, value));
|
||||
}
|
||||
/* We always write SLong8 for BigTIFF, no checking needed. */
|
||||
if (tif->tif_flags & TIFF_BIGTIFF)
|
||||
return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag,
|
||||
@@ -1741,7 +1797,8 @@ static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir,
|
||||
** For classic tiff we want to verify everything is in range for signed-long
|
||||
** and convert to signed-long format.
|
||||
*/
|
||||
p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
|
||||
p = (int32_t *)_TIFFmallocExt(tif,
|
||||
(tmsize_t)((size_t)count * sizeof(uint32_t)));
|
||||
if (p == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -1960,7 +2017,8 @@ static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir,
|
||||
** and convert to long format.
|
||||
*/
|
||||
|
||||
uint32_t *p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
|
||||
uint32_t *p = (uint32_t *)_TIFFmallocExt(
|
||||
tif, (tmsize_t)((size_t)count * sizeof(uint32_t)));
|
||||
uint32_t *q;
|
||||
uint64_t *ma;
|
||||
uint32_t mb;
|
||||
@@ -1990,7 +2048,8 @@ static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir,
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t *p = _TIFFmallocExt(tif, count * sizeof(uint16_t));
|
||||
uint16_t *p = (uint16_t *)_TIFFmallocExt(
|
||||
tif, (tmsize_t)((size_t)count * sizeof(uint16_t)));
|
||||
uint16_t *q;
|
||||
uint64_t *ma;
|
||||
uint32_t mb;
|
||||
@@ -2050,7 +2109,8 @@ static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir,
|
||||
** and convert to long format.
|
||||
*/
|
||||
|
||||
p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
|
||||
p = (uint32_t *)_TIFFmallocExt(
|
||||
tif, (tmsize_t)((size_t)count * sizeof(uint32_t)));
|
||||
if (p == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -2101,26 +2161,45 @@ static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir,
|
||||
{
|
||||
static const char module[] = "TIFFWriteDirectoryTagColormap";
|
||||
uint32_t m;
|
||||
uint32_t count;
|
||||
uint64_t count64;
|
||||
tmsize_t total_values;
|
||||
tmsize_t plane_bytes;
|
||||
uint16_t *n;
|
||||
int o;
|
||||
m = (1 << tif->tif_dir.td_bitspersample);
|
||||
if (tif->tif_dir.td_bitspersample >= 32)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "BitsPerSample too large for Colormap");
|
||||
return (0);
|
||||
}
|
||||
m = 1U << tif->tif_dir.td_bitspersample;
|
||||
count64 = _TIFFMultiply64(tif, 3U, m, module);
|
||||
if (count64 == 0)
|
||||
return (0);
|
||||
count = _TIFFCastUInt64ToUInt32(tif, count64, module);
|
||||
total_values = _TIFFCastUInt64ToSSize(tif, count64, module);
|
||||
plane_bytes = _TIFFCastUInt64ToSSize(
|
||||
tif, _TIFFMultiply64(tif, m, sizeof(uint16_t), module), module);
|
||||
if (count == 0 || total_values == 0 || plane_bytes == 0)
|
||||
return (0);
|
||||
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
|
||||
{
|
||||
EvaluateIFDdatasizeWrite(tif, 3 * m, sizeof(uint16_t), ndir);
|
||||
EvaluateIFDdatasizeWrite(tif, count, sizeof(uint16_t), ndir);
|
||||
return 1;
|
||||
}
|
||||
|
||||
n = _TIFFmallocExt(tif, 3 * m * sizeof(uint16_t));
|
||||
n = (uint16_t *)_TIFFCheckMalloc(tif, total_values, sizeof(uint16_t),
|
||||
module);
|
||||
if (n == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
return (0);
|
||||
}
|
||||
_TIFFmemcpy(&n[0], tif->tif_dir.td_colormap[0], m * sizeof(uint16_t));
|
||||
_TIFFmemcpy(&n[m], tif->tif_dir.td_colormap[1], m * sizeof(uint16_t));
|
||||
_TIFFmemcpy(&n[2 * m], tif->tif_dir.td_colormap[2], m * sizeof(uint16_t));
|
||||
_TIFFmemcpy(&n[0], tif->tif_dir.td_colormap[0], plane_bytes);
|
||||
_TIFFmemcpy(&n[m], tif->tif_dir.td_colormap[1], plane_bytes);
|
||||
_TIFFmemcpy(&n[2 * m], tif->tif_dir.td_colormap[2], plane_bytes);
|
||||
o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, TIFFTAG_COLORMAP,
|
||||
3 * m, n);
|
||||
count, n);
|
||||
_TIFFfreeExt(tif, n);
|
||||
return (o);
|
||||
}
|
||||
@@ -2130,13 +2209,27 @@ static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir,
|
||||
{
|
||||
static const char module[] = "TIFFWriteDirectoryTagTransferfunction";
|
||||
uint32_t m;
|
||||
uint32_t count;
|
||||
uint64_t count64;
|
||||
tmsize_t total_values;
|
||||
tmsize_t plane_bytes;
|
||||
uint16_t n;
|
||||
uint16_t *o;
|
||||
int p;
|
||||
/* TIFFTAG_TRANSFERFUNCTION expects (1 or 3) pointer to arrays with
|
||||
* (1 << BitsPerSample) * uint16_t values.
|
||||
* 2**BitsPerSample uint16_t values.
|
||||
*/
|
||||
m = (1 << tif->tif_dir.td_bitspersample);
|
||||
if (tif->tif_dir.td_bitspersample >= 32)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"BitsPerSample too large for TransferFunction");
|
||||
return (0);
|
||||
}
|
||||
m = 1U << tif->tif_dir.td_bitspersample;
|
||||
plane_bytes = _TIFFCastUInt64ToSSize(
|
||||
tif, _TIFFMultiply64(tif, m, sizeof(uint16_t), module), module);
|
||||
if (plane_bytes == 0)
|
||||
return (0);
|
||||
/* clang-format off */
|
||||
n = (tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples) > 1 ? 3 : 1;
|
||||
/* clang-format on */
|
||||
@@ -2161,35 +2254,39 @@ static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir,
|
||||
if (n == 3)
|
||||
{
|
||||
if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],
|
||||
tif->tif_dir.td_transferfunction[2],
|
||||
m * sizeof(uint16_t)) &&
|
||||
tif->tif_dir.td_transferfunction[2], plane_bytes) &&
|
||||
!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],
|
||||
tif->tif_dir.td_transferfunction[1],
|
||||
m * sizeof(uint16_t)))
|
||||
tif->tif_dir.td_transferfunction[1], plane_bytes))
|
||||
n = 1;
|
||||
}
|
||||
count64 = _TIFFMultiply64(tif, n, m, module);
|
||||
if (count64 == 0)
|
||||
return (0);
|
||||
count = _TIFFCastUInt64ToUInt32(tif, count64, module);
|
||||
total_values = _TIFFCastUInt64ToSSize(tif, count64, module);
|
||||
if (count == 0 || total_values == 0)
|
||||
return (0);
|
||||
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
|
||||
{
|
||||
EvaluateIFDdatasizeWrite(tif, n * m, 2, ndir);
|
||||
EvaluateIFDdatasizeWrite(tif, count, 2, ndir);
|
||||
return 1;
|
||||
}
|
||||
|
||||
o = _TIFFmallocExt(tif, n * m * sizeof(uint16_t));
|
||||
o = (uint16_t *)_TIFFCheckMalloc(tif, total_values, sizeof(uint16_t),
|
||||
module);
|
||||
if (o == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
return (0);
|
||||
}
|
||||
_TIFFmemcpy(&o[0], tif->tif_dir.td_transferfunction[0],
|
||||
m * sizeof(uint16_t));
|
||||
_TIFFmemcpy(&o[0], tif->tif_dir.td_transferfunction[0], plane_bytes);
|
||||
if (n > 1)
|
||||
_TIFFmemcpy(&o[m], tif->tif_dir.td_transferfunction[1],
|
||||
m * sizeof(uint16_t));
|
||||
_TIFFmemcpy(&o[m], tif->tif_dir.td_transferfunction[1], plane_bytes);
|
||||
if (n > 2)
|
||||
_TIFFmemcpy(&o[2 * m], tif->tif_dir.td_transferfunction[2],
|
||||
m * sizeof(uint16_t));
|
||||
plane_bytes);
|
||||
p = TIFFWriteDirectoryTagCheckedShortArray(
|
||||
tif, ndir, dir, TIFFTAG_TRANSFERFUNCTION, n * m, o);
|
||||
tif, ndir, dir, TIFFTAG_TRANSFERFUNCTION, count, o);
|
||||
_TIFFfreeExt(tif, o);
|
||||
return (p);
|
||||
}
|
||||
@@ -2209,7 +2306,9 @@ static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir,
|
||||
uint64_t *pa;
|
||||
uint32_t *pb;
|
||||
uint16_t p;
|
||||
o = _TIFFmallocExt(tif, tif->tif_dir.td_nsubifd * sizeof(uint32_t));
|
||||
o = (uint32_t *)_TIFFmallocExt(
|
||||
tif,
|
||||
(tmsize_t)((size_t)tif->tif_dir.td_nsubifd * sizeof(uint32_t)));
|
||||
if (o == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -2494,7 +2593,7 @@ static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir,
|
||||
TIFFErrorExtR(tif, module, "Negative value is illegal");
|
||||
return 0;
|
||||
}
|
||||
else if (value != value)
|
||||
else if (isnan(value))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Not-a-number value is illegal");
|
||||
return 0;
|
||||
@@ -2537,7 +2636,8 @@ static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir,
|
||||
EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(uint32_t), ndir);
|
||||
return 1;
|
||||
}
|
||||
m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t));
|
||||
m = (uint32_t *)_TIFFCheckMalloc(tif, count, 2 * sizeof(uint32_t),
|
||||
"for rational array");
|
||||
if (m == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -2545,7 +2645,7 @@ static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir,
|
||||
}
|
||||
for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
|
||||
{
|
||||
DoubleToRational(*na, &nb[0], &nb[1]);
|
||||
DoubleToRational((double)*na, &nb[0], &nb[1]);
|
||||
}
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabArrayOfLong(m, count * 2);
|
||||
@@ -2573,7 +2673,8 @@ static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir,
|
||||
EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(int32_t), ndir);
|
||||
return 1;
|
||||
}
|
||||
m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t));
|
||||
m = (int32_t *)_TIFFCheckMalloc(tif, count, 2 * sizeof(int32_t),
|
||||
"for srational array");
|
||||
if (m == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -2581,7 +2682,7 @@ static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir,
|
||||
}
|
||||
for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
|
||||
{
|
||||
DoubleToSrational(*na, &nb[0], &nb[1]);
|
||||
DoubleToSrational((double)*na, &nb[0], &nb[1]);
|
||||
}
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabArrayOfLong((uint32_t *)m, count * 2);
|
||||
@@ -2610,7 +2711,8 @@ TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir,
|
||||
EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(uint32_t), ndir);
|
||||
return 1;
|
||||
}
|
||||
m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t));
|
||||
m = (uint32_t *)_TIFFCheckMalloc(tif, count, 2 * sizeof(uint32_t),
|
||||
"for rational double array");
|
||||
if (m == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -2618,7 +2720,7 @@ TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir,
|
||||
}
|
||||
for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
|
||||
{
|
||||
DoubleToRational(*na, &nb[0], &nb[1]);
|
||||
DoubleToRational((double)*na, &nb[0], &nb[1]);
|
||||
}
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabArrayOfLong(m, count * 2);
|
||||
@@ -2645,7 +2747,8 @@ static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
|
||||
EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(int32_t), ndir);
|
||||
return 1;
|
||||
}
|
||||
m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t));
|
||||
m = (int32_t *)_TIFFCheckMalloc(tif, count, 2 * sizeof(int32_t),
|
||||
"for srational double array");
|
||||
if (m == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -2653,7 +2756,7 @@ static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
|
||||
}
|
||||
for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
|
||||
{
|
||||
DoubleToSrational(*na, &nb[0], &nb[1]);
|
||||
DoubleToSrational((double)*na, &nb[0], &nb[1]);
|
||||
}
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabArrayOfLong((uint32_t *)m, count * 2);
|
||||
@@ -2744,7 +2847,8 @@ static void ToRationalEuclideanGCD(double value, int blnUseSignedRange,
|
||||
*the double-value of it reaches an integer number without fractional part.
|
||||
*/
|
||||
bigDenom = 1;
|
||||
while ((value != floor(value)) && (value < fMax) && (bigDenom < nMax))
|
||||
while ((!TIFF_DOUBLE_EQ(value, floor(value))) && (value < fMax) &&
|
||||
(bigDenom < nMax))
|
||||
{
|
||||
bigDenom <<= 1;
|
||||
value *= 2;
|
||||
@@ -2836,7 +2940,7 @@ static void DoubleToRational(double value, uint32_t *num, uint32_t *denom)
|
||||
return;
|
||||
}
|
||||
/*-- Check for easy integer numbers -- */
|
||||
if (value == (uint32_t)(value))
|
||||
if (TIFF_DOUBLE_EQ(value, (double)(uint32_t)value))
|
||||
{
|
||||
*num = (uint32_t)value;
|
||||
*denom = 1;
|
||||
@@ -2911,7 +3015,7 @@ static void DoubleToSrational(double value, int32_t *num, int32_t *denom)
|
||||
return;
|
||||
}
|
||||
/*-- Check for easy numbers -- */
|
||||
if (value == (int32_t)(value))
|
||||
if (TIFF_DOUBLE_EQ(value, (double)(int32_t)value))
|
||||
{
|
||||
*num = (int32_t)(neg * value);
|
||||
*denom = 1;
|
||||
@@ -3231,6 +3335,14 @@ static int TIFFLinkDirectory(TIFF *tif)
|
||||
uint16_t dircount;
|
||||
uint32_t nextnextdir;
|
||||
|
||||
/* Update IDF loop list and check for IFD loop.
|
||||
* ndir is IFD ID plus one. */
|
||||
if (!_TIFFCheckDirNumberAndOffset(tif, ndir - 1, nextdir))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error IFD loop detected");
|
||||
return 0; /* bad offset (IFD looping or more than
|
||||
TIFF_MAX_DIR_COUNT IFDs) */
|
||||
}
|
||||
if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error fetching directory count");
|
||||
@@ -3238,7 +3350,7 @@ static int TIFFLinkDirectory(TIFF *tif)
|
||||
}
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabShort(&dircount);
|
||||
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
|
||||
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12U, SEEK_SET);
|
||||
if (!ReadOK(tif, &nextnextdir, 4))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error fetching directory link");
|
||||
@@ -3248,7 +3360,7 @@ static int TIFFLinkDirectory(TIFF *tif)
|
||||
TIFFSwabLong(&nextnextdir);
|
||||
if (nextnextdir == 0)
|
||||
{
|
||||
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
|
||||
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12U, SEEK_SET);
|
||||
if (!WriteOK(tif, &m, 4))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error writing directory link");
|
||||
@@ -3306,9 +3418,15 @@ static int TIFFLinkDirectory(TIFF *tif)
|
||||
while (1)
|
||||
{
|
||||
uint64_t dircount64;
|
||||
uint16_t dircount;
|
||||
uint64_t nextnextdir;
|
||||
|
||||
/* Update IDF loop list and check for IFD loop. */
|
||||
if (!_TIFFCheckDirNumberAndOffset(tif, ndir - 1, nextdir))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error IFD loop detected");
|
||||
return 0; /* bad offset (IFD looping or more than
|
||||
TIFF_MAX_DIR_COUNT IFDs) */
|
||||
}
|
||||
if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error fetching directory count");
|
||||
@@ -3323,8 +3441,7 @@ static int TIFFLinkDirectory(TIFF *tif)
|
||||
"likely corrupt TIFF");
|
||||
return (0);
|
||||
}
|
||||
dircount = (uint16_t)dircount64;
|
||||
(void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
|
||||
(void)TIFFSeekFile(tif, nextdir + 8 + dircount64 * 20, SEEK_SET);
|
||||
if (!ReadOK(tif, &nextnextdir, 8))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error fetching directory link");
|
||||
@@ -3334,7 +3451,8 @@ static int TIFFLinkDirectory(TIFF *tif)
|
||||
TIFFSwabLong8(&nextnextdir);
|
||||
if (nextnextdir == 0)
|
||||
{
|
||||
(void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
|
||||
(void)TIFFSeekFile(tif, nextdir + 8 + dircount64 * 20,
|
||||
SEEK_SET);
|
||||
if (!WriteOK(tif, &m, 8))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error writing directory link");
|
||||
@@ -3475,7 +3593,7 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
|
||||
if (entry_tag == tag)
|
||||
break;
|
||||
|
||||
read_offset += dirsize;
|
||||
read_offset += (uint64_t)dirsize;
|
||||
}
|
||||
|
||||
if (entry_tag != tag)
|
||||
@@ -3584,13 +3702,13 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
|
||||
if (in_datatype == TIFF_LONG8 &&
|
||||
(entry_type == TIFF_SHORT || entry_type == TIFF_LONG ||
|
||||
entry_type == TIFF_LONG8))
|
||||
datatype = entry_type;
|
||||
datatype = (TIFFDataType)entry_type;
|
||||
else if (in_datatype == TIFF_SLONG8 &&
|
||||
(entry_type == TIFF_SLONG || entry_type == TIFF_SLONG8))
|
||||
datatype = entry_type;
|
||||
datatype = (TIFFDataType)entry_type;
|
||||
else if (in_datatype == TIFF_IFD8 &&
|
||||
(entry_type == TIFF_IFD || entry_type == TIFF_IFD8))
|
||||
datatype = entry_type;
|
||||
datatype = (TIFFDataType)entry_type;
|
||||
else
|
||||
datatype = in_datatype;
|
||||
}
|
||||
@@ -3605,7 +3723,8 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
|
||||
return 0;
|
||||
|
||||
if (datatype == in_datatype)
|
||||
memcpy(buf_to_write, data, count * TIFFDataWidth(datatype));
|
||||
memcpy(buf_to_write, data,
|
||||
(size_t)count * (size_t)TIFFDataWidth(datatype));
|
||||
else if (datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8)
|
||||
{
|
||||
tmsize_t i;
|
||||
@@ -3698,8 +3817,8 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
|
||||
tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
|
||||
tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0)
|
||||
{
|
||||
tif->tif_dir.td_stripoffset_entry.tdir_type = datatype;
|
||||
tif->tif_dir.td_stripoffset_entry.tdir_count = count;
|
||||
tif->tif_dir.td_stripoffset_entry.tdir_type = (uint16_t)datatype;
|
||||
tif->tif_dir.td_stripoffset_entry.tdir_count = (uint64_t)count;
|
||||
}
|
||||
else if ((tag == TIFFTAG_TILEBYTECOUNTS ||
|
||||
tag == TIFFTAG_STRIPBYTECOUNTS) &&
|
||||
@@ -3707,8 +3826,8 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
|
||||
tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
|
||||
tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0)
|
||||
{
|
||||
tif->tif_dir.td_stripbytecount_entry.tdir_type = datatype;
|
||||
tif->tif_dir.td_stripbytecount_entry.tdir_count = count;
|
||||
tif->tif_dir.td_stripbytecount_entry.tdir_type = (uint16_t)datatype;
|
||||
tif->tif_dir.td_stripbytecount_entry.tdir_count = (uint64_t)count;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@@ -3756,13 +3875,14 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
|
||||
if (count * TIFFDataWidth(datatype) == 4)
|
||||
{
|
||||
uint32_t value;
|
||||
memcpy(&value, buf_to_write, count * TIFFDataWidth(datatype));
|
||||
memcpy(&value, buf_to_write,
|
||||
(size_t)count * (size_t)TIFFDataWidth(datatype));
|
||||
entry_offset = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&entry_offset, buf_to_write,
|
||||
count * TIFFDataWidth(datatype));
|
||||
(size_t)count * (size_t)TIFFDataWidth(datatype));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3772,7 +3892,7 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Adjust the directory entry. */
|
||||
/* -------------------------------------------------------------------- */
|
||||
entry_type = datatype;
|
||||
entry_type = (uint16_t)datatype;
|
||||
entry_count = (uint64_t)count;
|
||||
memcpy(direntry_raw + 2, &entry_type, sizeof(uint16_t));
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
|
||||
21
3rdparty/libtiff/tif_dumpmode.c
vendored
21
3rdparty/libtiff/tif_dumpmode.c
vendored
@@ -80,7 +80,7 @@ static int DumpModeDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
"Not enough data for scanline %" PRIu32
|
||||
", expected a request for at most %" TIFF_SSIZE_FORMAT
|
||||
" bytes, got a request for %" TIFF_SSIZE_FORMAT " bytes",
|
||||
tif->tif_row, tif->tif_rawcc, cc);
|
||||
tif->tif_dir.td_row, tif->tif_rawcc, cc);
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
@@ -99,8 +99,23 @@ static int DumpModeDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
*/
|
||||
static int DumpModeSeek(TIFF *tif, uint32_t nrows)
|
||||
{
|
||||
tif->tif_rawcp += nrows * tif->tif_scanlinesize;
|
||||
tif->tif_rawcc -= nrows * tif->tif_scanlinesize;
|
||||
tmsize_t seek_size;
|
||||
if (nrows > 0 &&
|
||||
tif->tif_dir.td_scanlinesize > (tmsize_t)(TIFF_TMSIZE_T_MAX / nrows))
|
||||
{
|
||||
TIFFErrorExtR(tif, "DumpModeSeek",
|
||||
"Integer overflow computing seek size");
|
||||
return (0);
|
||||
}
|
||||
seek_size = (tmsize_t)nrows * tif->tif_dir.td_scanlinesize;
|
||||
if (seek_size > tif->tif_rawcc)
|
||||
{
|
||||
TIFFErrorExtR(tif, "DumpModeSeek",
|
||||
"Seek beyond end of raw data buffer");
|
||||
return (0);
|
||||
}
|
||||
tif->tif_rawcp += seek_size;
|
||||
tif->tif_rawcc -= seek_size;
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
253
3rdparty/libtiff/tif_fax3.c
vendored
253
3rdparty/libtiff/tif_fax3.c
vendored
@@ -123,7 +123,7 @@ typedef struct
|
||||
static const char module[] = mod; \
|
||||
Fax3CodecState *sp = DecoderState(tif); \
|
||||
int a0; /* reference element */ \
|
||||
int lastx = sp->b.rowpixels; /* last element in row */ \
|
||||
int lastx = (int)sp->b.rowpixels; /* last element in row */ \
|
||||
uint32_t BitAcc; /* bit accumulator */ \
|
||||
int BitsAvail; /* # valid bits in BitAcc */ \
|
||||
int RunLength; /* length of current run */ \
|
||||
@@ -209,61 +209,68 @@ static int Fax3PreDecode(TIFF *tif, uint16_t s)
|
||||
static void Fax3Unexpected(const char *module, TIFF *tif, uint32_t line,
|
||||
uint32_t a0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Bad code word at line %" PRIu32 " of %s %" PRIu32
|
||||
" (x %" PRIu32 ")",
|
||||
line, isTiled(tif) ? "tile" : "strip",
|
||||
(isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0);
|
||||
TIFFErrorExtR(
|
||||
tif, module,
|
||||
"Bad code word at line %" PRIu32 " of %s %" PRIu32 " (x %" PRIu32 ")",
|
||||
line, isTiled(tif) ? "tile" : "strip",
|
||||
(isTiled(tif) ? tif->tif_dir.td_curtile : tif->tif_dir.td_curstrip),
|
||||
a0);
|
||||
}
|
||||
#define unexpected(table, a0) \
|
||||
do \
|
||||
{ \
|
||||
Fax3Unexpected(module, tif, sp->line, a0); \
|
||||
Fax3Unexpected(module, tif, (uint32_t)sp->line, (uint32_t)(a0)); \
|
||||
++sp->unexpectedReachedCount; \
|
||||
} while (0)
|
||||
|
||||
static void Fax3Extension(const char *module, TIFF *tif, uint32_t line,
|
||||
uint32_t a0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Uncompressed data (not supported) at line %" PRIu32
|
||||
" of %s %" PRIu32 " (x %" PRIu32 ")",
|
||||
line, isTiled(tif) ? "tile" : "strip",
|
||||
(isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0);
|
||||
TIFFErrorExtR(
|
||||
tif, module,
|
||||
"Uncompressed data (not supported) at line %" PRIu32 " of %s %" PRIu32
|
||||
" (x %" PRIu32 ")",
|
||||
line, isTiled(tif) ? "tile" : "strip",
|
||||
(isTiled(tif) ? tif->tif_dir.td_curtile : tif->tif_dir.td_curstrip),
|
||||
a0);
|
||||
}
|
||||
#define extension(a0) Fax3Extension(module, tif, sp->line, a0)
|
||||
#define extension(a0) \
|
||||
Fax3Extension(module, tif, (uint32_t)sp->line, (uint32_t)(a0))
|
||||
|
||||
static void Fax3BadLength(const char *module, TIFF *tif, uint32_t line,
|
||||
uint32_t a0, uint32_t lastx)
|
||||
{
|
||||
TIFFWarningExtR(tif, module,
|
||||
"%s at line %" PRIu32 " of %s %" PRIu32 " (got %" PRIu32
|
||||
", expected %" PRIu32 ")",
|
||||
a0 < lastx ? "Premature EOL" : "Line length mismatch", line,
|
||||
isTiled(tif) ? "tile" : "strip",
|
||||
(isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0,
|
||||
lastx);
|
||||
TIFFWarningExtR(
|
||||
tif, module,
|
||||
"%s at line %" PRIu32 " of %s %" PRIu32 " (got %" PRIu32
|
||||
", expected %" PRIu32 ")",
|
||||
a0 < lastx ? "Premature EOL" : "Line length mismatch", line,
|
||||
isTiled(tif) ? "tile" : "strip",
|
||||
(isTiled(tif) ? tif->tif_dir.td_curtile : tif->tif_dir.td_curstrip), a0,
|
||||
lastx);
|
||||
}
|
||||
#define badlength(a0, lastx) \
|
||||
do \
|
||||
{ \
|
||||
Fax3BadLength(module, tif, sp->line, a0, lastx); \
|
||||
Fax3BadLength(module, tif, (uint32_t)sp->line, (uint32_t)(a0), \
|
||||
(uint32_t)(lastx)); \
|
||||
++sp->eolReachedCount; \
|
||||
} while (0)
|
||||
|
||||
static void Fax3PrematureEOF(const char *module, TIFF *tif, uint32_t line,
|
||||
uint32_t a0)
|
||||
{
|
||||
TIFFWarningExtR(tif, module,
|
||||
"Premature EOF at line %" PRIu32 " of %s %" PRIu32
|
||||
" (x %" PRIu32 ")",
|
||||
line, isTiled(tif) ? "tile" : "strip",
|
||||
(isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0);
|
||||
TIFFWarningExtR(
|
||||
tif, module,
|
||||
"Premature EOF at line %" PRIu32 " of %s %" PRIu32 " (x %" PRIu32 ")",
|
||||
line, isTiled(tif) ? "tile" : "strip",
|
||||
(isTiled(tif) ? tif->tif_dir.td_curtile : tif->tif_dir.td_curstrip),
|
||||
a0);
|
||||
}
|
||||
#define prematureEOF(a0) \
|
||||
do \
|
||||
{ \
|
||||
Fax3PrematureEOF(module, tif, sp->line, a0); \
|
||||
Fax3PrematureEOF(module, tif, (uint32_t)sp->line, (uint32_t)(a0)); \
|
||||
++sp->eofReachedCount; \
|
||||
} while (0)
|
||||
|
||||
@@ -275,16 +282,15 @@ static void Fax3TryG3WithoutEOL(const char *module, TIFF *tif, uint32_t line,
|
||||
"Try to decode (read) fax Group 3 data without EOL at line %" PRIu32
|
||||
" of %s %" PRIu32 " (x %" PRIu32 "). Please check result",
|
||||
line, isTiled(tif) ? "tile" : "strip",
|
||||
(isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0);
|
||||
(isTiled(tif) ? tif->tif_dir.td_curtile : tif->tif_dir.td_curstrip),
|
||||
a0);
|
||||
}
|
||||
#define tryG3WithoutEOL(a0) \
|
||||
do \
|
||||
{ \
|
||||
Fax3TryG3WithoutEOL(module, tif, sp->line, a0); \
|
||||
Fax3TryG3WithoutEOL(module, tif, (uint32_t)sp->line, (uint32_t)(a0)); \
|
||||
} while (0)
|
||||
|
||||
#define Nop
|
||||
|
||||
static int CheckReachedCounters(TIFF *tif, const char *module,
|
||||
Fax3CodecState *sp)
|
||||
{
|
||||
@@ -344,12 +350,12 @@ RETRY_WITHOUT_EOL_1D:
|
||||
pa = thisrun;
|
||||
#ifdef FAX3_DEBUG
|
||||
printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail);
|
||||
printf("-------------------- %" PRIu32 "\n", tif->tif_row);
|
||||
printf("-------------------- %" PRIu32 "\n", tif->tif_dir.td_row);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
SYNC_EOL(EOF1D, RETRY_WITHOUT_EOL_1D);
|
||||
EXPAND1D(EOF1Da);
|
||||
(*sp->fill)(buf, thisrun, pa, lastx);
|
||||
(*sp->fill)(buf, thisrun, pa, (uint32_t)lastx);
|
||||
buf += sp->b.rowbytes;
|
||||
occ -= sp->b.rowbytes;
|
||||
sp->line++;
|
||||
@@ -357,7 +363,7 @@ RETRY_WITHOUT_EOL_1D:
|
||||
EOF1D: /* premature EOF */
|
||||
CLEANUP_RUNS();
|
||||
EOF1Da: /* premature EOF */
|
||||
(*sp->fill)(buf, thisrun, pa, lastx);
|
||||
(*sp->fill)(buf, thisrun, pa, (uint32_t)lastx);
|
||||
UNCACHE_STATE(tif, sp);
|
||||
return (-1);
|
||||
}
|
||||
@@ -404,16 +410,16 @@ RETRY_WITHOUT_EOL_2D:
|
||||
ClrBits(1);
|
||||
#ifdef FAX3_DEBUG
|
||||
printf(" %s\n-------------------- %" PRIu32 "\n", is1D ? "1D" : "2D",
|
||||
tif->tif_row);
|
||||
tif->tif_dir.td_row);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
pb = sp->refruns;
|
||||
b1 = *pb++;
|
||||
b1 = (int)*pb++;
|
||||
if (is1D)
|
||||
EXPAND1D(EOF2Da);
|
||||
else
|
||||
EXPAND2D(EOF2Da);
|
||||
(*sp->fill)(buf, thisrun, pa, lastx);
|
||||
(*sp->fill)(buf, thisrun, pa, (uint32_t)lastx);
|
||||
if (pa < thisrun + sp->nruns)
|
||||
{
|
||||
SETVALUE(0); /* imaginary change for reference */
|
||||
@@ -426,7 +432,7 @@ RETRY_WITHOUT_EOL_2D:
|
||||
EOF2D: /* premature EOF */
|
||||
CLEANUP_RUNS();
|
||||
EOF2Da: /* premature EOF */
|
||||
(*sp->fill)(buf, thisrun, pa, lastx);
|
||||
(*sp->fill)(buf, thisrun, pa, (uint32_t)lastx);
|
||||
UNCACHE_STATE(tif, sp);
|
||||
return (-1);
|
||||
}
|
||||
@@ -479,12 +485,12 @@ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun,
|
||||
{
|
||||
if (bx)
|
||||
{ /* align to byte boundary */
|
||||
*cp++ &= 0xff << (8 - bx);
|
||||
*cp++ &= (unsigned char)(0xff << (8 - bx));
|
||||
run -= 8 - bx;
|
||||
}
|
||||
if ((n = run >> 3) != 0)
|
||||
if ((n = (int32_t)(run >> 3)) != 0)
|
||||
{ /* multiple bytes to fill */
|
||||
if ((n / sizeof(int64_t)) > 1)
|
||||
if (((size_t)n / sizeof(int64_t)) > 1)
|
||||
{
|
||||
/*
|
||||
* Align to int64_tword boundary and fill.
|
||||
@@ -492,8 +498,8 @@ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun,
|
||||
for (; n && !isAligned(cp, int64_t); n--)
|
||||
*cp++ = 0x00;
|
||||
lp = (int64_t *)cp;
|
||||
nw = (int32_t)(n / sizeof(int64_t));
|
||||
n -= nw * sizeof(int64_t);
|
||||
nw = (int32_t)((size_t)n / sizeof(int64_t));
|
||||
n -= (int32_t)((size_t)nw * sizeof(int64_t));
|
||||
do
|
||||
{
|
||||
*lp++ = 0L;
|
||||
@@ -504,10 +510,10 @@ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun,
|
||||
run &= 7;
|
||||
}
|
||||
if (run)
|
||||
cp[0] &= 0xff >> run;
|
||||
cp[0] &= (unsigned char)(0xff >> run);
|
||||
}
|
||||
else
|
||||
cp[0] &= ~(_fillmasks[run] >> bx);
|
||||
cp[0] &= (unsigned char)~(_fillmasks[run] >> bx);
|
||||
x += runs[0];
|
||||
}
|
||||
run = runs[1];
|
||||
@@ -521,12 +527,12 @@ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun,
|
||||
{
|
||||
if (bx)
|
||||
{ /* align to byte boundary */
|
||||
*cp++ |= 0xff >> bx;
|
||||
*cp++ |= (unsigned char)(0xff >> bx);
|
||||
run -= 8 - bx;
|
||||
}
|
||||
if ((n = run >> 3) != 0)
|
||||
if ((n = (int32_t)(run >> 3)) != 0)
|
||||
{ /* multiple bytes to fill */
|
||||
if ((n / sizeof(int64_t)) > 1)
|
||||
if (((size_t)n / sizeof(int64_t)) > 1)
|
||||
{
|
||||
/*
|
||||
* Align to int64_t boundary and fill.
|
||||
@@ -534,8 +540,8 @@ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun,
|
||||
for (; n && !isAligned(cp, int64_t); n--)
|
||||
*cp++ = 0xff;
|
||||
lp = (int64_t *)cp;
|
||||
nw = (int32_t)(n / sizeof(int64_t));
|
||||
n -= nw * sizeof(int64_t);
|
||||
nw = (int32_t)((size_t)n / sizeof(int64_t));
|
||||
n -= (int32_t)((size_t)nw * sizeof(int64_t));
|
||||
do
|
||||
{
|
||||
*lp++ = -1L;
|
||||
@@ -550,7 +556,7 @@ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun,
|
||||
cp[0] = (unsigned char)((cp[0] | (0xff00 >> run)) & 0xff);
|
||||
}
|
||||
else
|
||||
cp[0] |= _fillmasks[run] >> bx;
|
||||
cp[0] |= (unsigned char)(_fillmasks[run] >> bx);
|
||||
x += runs[1];
|
||||
}
|
||||
}
|
||||
@@ -726,12 +732,13 @@ static const int _msbmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f,
|
||||
{ \
|
||||
while (length > bit) \
|
||||
{ \
|
||||
data |= bits >> (length - bit); \
|
||||
data |= (int)((unsigned int)bits >> (length - bit)); \
|
||||
length -= bit; \
|
||||
_FlushBits(tif); \
|
||||
} \
|
||||
assert(length < 9); \
|
||||
data |= (bits & _msbmask[length]) << (bit - length); \
|
||||
data |= (int)(((unsigned int)bits & (unsigned int)_msbmask[length]) \
|
||||
<< (unsigned int)(bit - length)); \
|
||||
bit -= length; \
|
||||
if (bit == 0) \
|
||||
_FlushBits(tif); \
|
||||
@@ -745,13 +752,13 @@ static const int _msbmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f,
|
||||
static int Fax3PutBits(TIFF *tif, unsigned int bits, unsigned int length)
|
||||
{
|
||||
Fax3CodecState *sp = EncoderState(tif);
|
||||
unsigned int bit = sp->bit;
|
||||
int data = sp->data;
|
||||
unsigned int bit = (unsigned int)sp->bit;
|
||||
int data = (int)sp->data;
|
||||
|
||||
_PutBits(tif, bits, length);
|
||||
|
||||
sp->data = data;
|
||||
sp->bit = bit;
|
||||
sp->data = (uint32_t)data;
|
||||
sp->bit = (int)bit;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -782,8 +789,8 @@ static int Fax3PutBits(TIFF *tif, unsigned int bits, unsigned int length)
|
||||
static int putspan(TIFF *tif, int32_t span, const tableentry *tab)
|
||||
{
|
||||
Fax3CodecState *sp = EncoderState(tif);
|
||||
unsigned int bit = sp->bit;
|
||||
int data = sp->data;
|
||||
unsigned int bit = (unsigned int)sp->bit;
|
||||
int data = (int)sp->data;
|
||||
unsigned int code, length;
|
||||
|
||||
while (span >= 2624)
|
||||
@@ -816,8 +823,8 @@ static int putspan(TIFF *tif, int32_t span, const tableentry *tab)
|
||||
#endif
|
||||
_PutBits(tif, code, length);
|
||||
|
||||
sp->data = data;
|
||||
sp->bit = bit;
|
||||
sp->data = (uint32_t)data;
|
||||
sp->bit = (int)bit;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -831,8 +838,8 @@ static int putspan(TIFF *tif, int32_t span, const tableentry *tab)
|
||||
static int Fax3PutEOL(TIFF *tif)
|
||||
{
|
||||
Fax3CodecState *sp = EncoderState(tif);
|
||||
unsigned int bit = sp->bit;
|
||||
int data = sp->data;
|
||||
unsigned int bit = (unsigned int)sp->bit;
|
||||
int data = (int)sp->data;
|
||||
unsigned int code, length, tparm;
|
||||
|
||||
if (sp->b.groupoptions & GROUP3OPT_FILLBITS)
|
||||
@@ -849,7 +856,7 @@ static int Fax3PutEOL(TIFF *tif)
|
||||
align = sp->bit + (8 - align);
|
||||
else
|
||||
align = sp->bit - align;
|
||||
tparm = align;
|
||||
tparm = (unsigned int)align;
|
||||
_PutBits(tif, 0, tparm);
|
||||
}
|
||||
}
|
||||
@@ -862,8 +869,8 @@ static int Fax3PutEOL(TIFF *tif)
|
||||
}
|
||||
_PutBits(tif, code, length);
|
||||
|
||||
sp->data = data;
|
||||
sp->bit = bit;
|
||||
sp->data = (uint32_t)data;
|
||||
sp->bit = (int)bit;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -991,10 +998,10 @@ static inline int32_t find0span(unsigned char *bp, int32_t bs, int32_t be)
|
||||
bp++;
|
||||
}
|
||||
lp = (int64_t *)bp;
|
||||
while ((bits >= (int32_t)(8 * sizeof(int64_t))) && (0 == *lp))
|
||||
while ((bits >= (int32_t)(size_t)(8 * sizeof(int64_t))) && (0 == *lp))
|
||||
{
|
||||
span += 8 * sizeof(int64_t);
|
||||
bits -= 8 * sizeof(int64_t);
|
||||
span += (int32_t)(size_t)(8 * sizeof(int64_t));
|
||||
bits -= (int32_t)(size_t)(8 * sizeof(int64_t));
|
||||
lp++;
|
||||
}
|
||||
bp = (unsigned char *)lp;
|
||||
@@ -1059,11 +1066,11 @@ static inline int32_t find1span(unsigned char *bp, int32_t bs, int32_t be)
|
||||
bp++;
|
||||
}
|
||||
lp = (int64_t *)bp;
|
||||
while ((bits >= (int32_t)(8 * sizeof(int64_t))) &&
|
||||
while ((bits >= (int32_t)(size_t)(8 * sizeof(int64_t))) &&
|
||||
(~((uint64_t)0) == (uint64_t)*lp))
|
||||
{
|
||||
span += 8 * sizeof(int64_t);
|
||||
bits -= 8 * sizeof(int64_t);
|
||||
span += (int32_t)(size_t)(8 * sizeof(int64_t));
|
||||
bits -= (int32_t)(size_t)(8 * sizeof(int64_t));
|
||||
lp++;
|
||||
}
|
||||
bp = (unsigned char *)lp;
|
||||
@@ -1118,16 +1125,16 @@ static int Fax3Encode1DRow(TIFF *tif, unsigned char *bp, uint32_t bits)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
span = find0span(bp, bs, bits); /* white span */
|
||||
span = find0span(bp, (int32_t)bs, (int32_t)bits); /* white span */
|
||||
if (!putspan(tif, span, TIFFFaxWhiteCodes))
|
||||
return 0;
|
||||
bs += span;
|
||||
bs += (uint32_t)span;
|
||||
if (bs >= bits)
|
||||
break;
|
||||
span = find1span(bp, bs, bits); /* black span */
|
||||
span = find1span(bp, (int32_t)bs, (int32_t)bits); /* black span */
|
||||
if (!putspan(tif, span, TIFFFaxBlackCodes))
|
||||
return 0;
|
||||
bs += span;
|
||||
bs += (uint32_t)span;
|
||||
if (bs >= bits)
|
||||
break;
|
||||
}
|
||||
@@ -1161,15 +1168,20 @@ static const tableentry vcodes[7] = {
|
||||
static int Fax3Encode2DRow(TIFF *tif, unsigned char *bp, unsigned char *rp,
|
||||
uint32_t bits)
|
||||
{
|
||||
#define PIXEL(buf, ix) ((((buf)[(ix) >> 3]) >> (7 - ((ix)&7))) & 1)
|
||||
#define PIXEL(buf, ix) ((((buf)[(ix) >> 3]) >> (7 - ((ix) & 7))) & 1)
|
||||
uint32_t a0 = 0;
|
||||
uint32_t a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, bits, 0));
|
||||
uint32_t b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, bits, 0));
|
||||
uint32_t a1 = (PIXEL(bp, 0) != 0
|
||||
? 0
|
||||
: (uint32_t)finddiff(bp, (int32_t)0, (int32_t)bits, 0));
|
||||
uint32_t b1 = (PIXEL(rp, 0) != 0
|
||||
? 0
|
||||
: (uint32_t)finddiff(rp, (int32_t)0, (int32_t)bits, 0));
|
||||
uint32_t a2, b2;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
b2 = finddiff2(rp, b1, bits, PIXEL(rp, b1));
|
||||
b2 = (uint32_t)finddiff2(rp, (int32_t)b1, (int32_t)bits,
|
||||
(int32_t)PIXEL(rp, b1));
|
||||
if (b2 >= a1)
|
||||
{
|
||||
/* Naive computation triggers
|
||||
@@ -1182,21 +1194,22 @@ static int Fax3Encode2DRow(TIFF *tif, unsigned char *bp, unsigned char *rp,
|
||||
: 0x7FFFFFFF;
|
||||
if (!(-3 <= d && d <= 3))
|
||||
{ /* horizontal mode */
|
||||
a2 = finddiff2(bp, a1, bits, PIXEL(bp, a1));
|
||||
a2 = (uint32_t)finddiff2(bp, (int32_t)a1, (int32_t)bits,
|
||||
(int32_t)PIXEL(bp, a1));
|
||||
if (!putcode(tif, &horizcode))
|
||||
return 0;
|
||||
if (a0 + a1 == 0 || PIXEL(bp, a0) == 0)
|
||||
{
|
||||
if (!putspan(tif, a1 - a0, TIFFFaxWhiteCodes))
|
||||
if (!putspan(tif, (int32_t)(a1 - a0), TIFFFaxWhiteCodes))
|
||||
return 0;
|
||||
if (!putspan(tif, a2 - a1, TIFFFaxBlackCodes))
|
||||
if (!putspan(tif, (int32_t)(a2 - a1), TIFFFaxBlackCodes))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!putspan(tif, a1 - a0, TIFFFaxBlackCodes))
|
||||
if (!putspan(tif, (int32_t)(a1 - a0), TIFFFaxBlackCodes))
|
||||
return 0;
|
||||
if (!putspan(tif, a2 - a1, TIFFFaxWhiteCodes))
|
||||
if (!putspan(tif, (int32_t)(a2 - a1), TIFFFaxWhiteCodes))
|
||||
return 0;
|
||||
}
|
||||
a0 = a2;
|
||||
@@ -1216,9 +1229,12 @@ static int Fax3Encode2DRow(TIFF *tif, unsigned char *bp, unsigned char *rp,
|
||||
}
|
||||
if (a0 >= bits)
|
||||
break;
|
||||
a1 = finddiff(bp, a0, bits, PIXEL(bp, a0));
|
||||
b1 = finddiff(rp, a0, bits, !PIXEL(bp, a0));
|
||||
b1 = finddiff(rp, b1, bits, PIXEL(bp, a0));
|
||||
a1 = (uint32_t)finddiff(bp, (int32_t)a0, (int32_t)bits,
|
||||
(int32_t)PIXEL(bp, a0));
|
||||
b1 = (uint32_t)finddiff(rp, (int32_t)a0, (int32_t)bits,
|
||||
(int32_t)!PIXEL(bp, a0));
|
||||
b1 = (uint32_t)finddiff(rp, (int32_t)b1, (int32_t)bits,
|
||||
(int32_t)PIXEL(bp, a0));
|
||||
}
|
||||
return (1);
|
||||
#undef PIXEL
|
||||
@@ -1487,6 +1503,8 @@ static void Fax3PrintDir(TIFF *tif, FILE *fd, long flags)
|
||||
case CLEANFAXDATA_UNCLEAN:
|
||||
fprintf(fd, " uncorrected errors");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
fprintf(fd, " (%" PRIu16 " = 0x%" PRIx16 ")\n", sp->cleanfaxdata,
|
||||
sp->cleanfaxdata);
|
||||
@@ -1500,6 +1518,22 @@ static void Fax3PrintDir(TIFF *tif, FILE *fd, long flags)
|
||||
(*sp->printdir)(tif, fd, flags);
|
||||
}
|
||||
|
||||
static uint64_t Fax3GetMaxCompressionRatio(TIFF *tif)
|
||||
{
|
||||
(void)tif;
|
||||
|
||||
/* See README_for_libtiff_developpers.md for raw data used to estimate
|
||||
* the maximum compression rate. */
|
||||
|
||||
/* 1024x1024: 36 */
|
||||
/* 4096x4096: 100 */
|
||||
/* 16383x16383: 163 */
|
||||
/* 65536x65536: 200 */
|
||||
/* 200000x200000: 208 */
|
||||
|
||||
return 250;
|
||||
}
|
||||
|
||||
static int InitCCITTFax3(TIFF *tif)
|
||||
{
|
||||
static const char module[] = "InitCCITTFax3";
|
||||
@@ -1564,6 +1598,7 @@ static int InitCCITTFax3(TIFF *tif)
|
||||
tif->tif_encodetile = Fax3Encode;
|
||||
tif->tif_close = Fax3Close;
|
||||
tif->tif_cleanup = Fax3Cleanup;
|
||||
tif->tif_getmaxcompressionratio = Fax3GetMaxCompressionRatio;
|
||||
|
||||
return (1);
|
||||
}
|
||||
@@ -1626,10 +1661,10 @@ static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
||||
RunLength = 0;
|
||||
pa = thisrun = sp->curruns;
|
||||
pb = sp->refruns;
|
||||
b1 = *pb++;
|
||||
b1 = (int)*pb++;
|
||||
#ifdef FAX3_DEBUG
|
||||
printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail);
|
||||
printf("-------------------- %d\n", tif->tif_row);
|
||||
printf("-------------------- %d\n", tif->tif_dir.td_row);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
EXPAND2D(EOFG4);
|
||||
@@ -1643,7 +1678,7 @@ static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
||||
occ, lastx);
|
||||
return -1;
|
||||
}
|
||||
(*sp->fill)(buf, thisrun, pa, lastx);
|
||||
(*sp->fill)(buf, thisrun, pa, (uint32_t)lastx);
|
||||
SETVALUE(0); /* imaginary change for reference */
|
||||
SWAP(uint32_t *, sp->curruns, sp->refruns);
|
||||
buf += sp->b.rowbytes;
|
||||
@@ -1666,7 +1701,7 @@ static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
||||
occ, lastx);
|
||||
return -1;
|
||||
}
|
||||
(*sp->fill)(buf, thisrun, pa, lastx);
|
||||
(*sp->fill)(buf, thisrun, pa, (uint32_t)lastx);
|
||||
UNCACHE_STATE(tif, sp);
|
||||
return (sp->line != start
|
||||
? 1
|
||||
@@ -1713,6 +1748,16 @@ static int Fax4PostEncode(TIFF *tif)
|
||||
return (1);
|
||||
}
|
||||
|
||||
static uint64_t Fax4GetMaxCompressionRatio(TIFF *tif)
|
||||
{
|
||||
/* FAX4 can compress up to almost one byte per line, so the compression
|
||||
* ratio can be up to the tile/strip width.
|
||||
* See README_for_libtiff_developpers.md for raw data
|
||||
*/
|
||||
return isTiled(tif) ? tif->tif_dir.td_tilewidth
|
||||
: tif->tif_dir.td_imagewidth;
|
||||
}
|
||||
|
||||
int TIFFInitCCITTFax4(TIFF *tif, int scheme)
|
||||
{
|
||||
(void)scheme;
|
||||
@@ -1735,6 +1780,7 @@ int TIFFInitCCITTFax4(TIFF *tif, int scheme)
|
||||
tif->tif_encodestrip = Fax4Encode;
|
||||
tif->tif_encodetile = Fax4Encode;
|
||||
tif->tif_postencode = Fax4PostEncode;
|
||||
tif->tif_getmaxcompressionratio = Fax4GetMaxCompressionRatio;
|
||||
/*
|
||||
* Suppress RTC at the end of each strip.
|
||||
*/
|
||||
@@ -1773,11 +1819,11 @@ static int Fax3DecodeRLE(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
||||
pa = thisrun;
|
||||
#ifdef FAX3_DEBUG
|
||||
printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail);
|
||||
printf("-------------------- %" PRIu32 "\n", tif->tif_row);
|
||||
printf("-------------------- %" PRIu32 "\n", tif->tif_dir.td_row);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
EXPAND1D(EOFRLE);
|
||||
(*sp->fill)(buf, thisrun, pa, lastx);
|
||||
(*sp->fill)(buf, thisrun, pa, (uint32_t)lastx);
|
||||
/*
|
||||
* Cleanup at the end of the row.
|
||||
*/
|
||||
@@ -1798,7 +1844,7 @@ static int Fax3DecodeRLE(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
||||
sp->line++;
|
||||
continue;
|
||||
EOFRLE: /* premature EOF */
|
||||
(*sp->fill)(buf, thisrun, pa, lastx);
|
||||
(*sp->fill)(buf, thisrun, pa, (uint32_t)lastx);
|
||||
UNCACHE_STATE(tif, sp);
|
||||
return (-1);
|
||||
}
|
||||
@@ -1806,6 +1852,21 @@ static int Fax3DecodeRLE(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
||||
return (1);
|
||||
}
|
||||
|
||||
static uint64_t Fax3RLEGetMaxCompressionRatio(TIFF *tif)
|
||||
{
|
||||
(void)tif;
|
||||
/* See README_for_libtiff_developpers.md for raw data used to estimate
|
||||
* the maximum compression rate. */
|
||||
|
||||
/* 1024x1024: 43 */
|
||||
/* 4096x4096: 128 */
|
||||
/* 16383x16383: 171 */
|
||||
/* 65536x65536: 205 */
|
||||
/* 200000x200000: 211 */
|
||||
|
||||
return 250;
|
||||
}
|
||||
|
||||
int TIFFInitCCITTRLE(TIFF *tif, int scheme)
|
||||
{
|
||||
(void)scheme;
|
||||
@@ -1814,6 +1875,7 @@ int TIFFInitCCITTRLE(TIFF *tif, int scheme)
|
||||
tif->tif_decoderow = Fax3DecodeRLE;
|
||||
tif->tif_decodestrip = Fax3DecodeRLE;
|
||||
tif->tif_decodetile = Fax3DecodeRLE;
|
||||
tif->tif_getmaxcompressionratio = Fax3RLEGetMaxCompressionRatio;
|
||||
/*
|
||||
* Suppress RTC+EOLs when encoding and byte-align data.
|
||||
*/
|
||||
@@ -1832,6 +1894,7 @@ int TIFFInitCCITTRLEW(TIFF *tif, int scheme)
|
||||
tif->tif_decoderow = Fax3DecodeRLE;
|
||||
tif->tif_decodestrip = Fax3DecodeRLE;
|
||||
tif->tif_decodetile = Fax3DecodeRLE;
|
||||
tif->tif_getmaxcompressionratio = Fax3RLEGetMaxCompressionRatio;
|
||||
/*
|
||||
* Suppress RTC+EOLs when encoding and word-align data.
|
||||
*/
|
||||
|
||||
138
3rdparty/libtiff/tif_fax3.h
vendored
138
3rdparty/libtiff/tif_fax3.h
vendored
@@ -267,14 +267,14 @@ static const char *StateNames[] = {
|
||||
{ \
|
||||
if (pa >= thisrun + sp->nruns) \
|
||||
{ \
|
||||
TIFFErrorExtR(tif, module, "Buffer overflow at line %u of %s %u", \
|
||||
TIFFErrorExtR(tif, module, "Buffer overflow at line %d of %s %u", \
|
||||
sp->line, isTiled(tif) ? "tile" : "strip", \
|
||||
isTiled(tif) ? tif->tif_curtile \
|
||||
: tif->tif_curstrip); \
|
||||
isTiled(tif) ? tif->tif_dir.td_curtile \
|
||||
: tif->tif_dir.td_curstrip); \
|
||||
return (-1); \
|
||||
} \
|
||||
*pa++ = RunLength + (x); \
|
||||
a0 += (x); \
|
||||
*pa++ = (uint32_t)((uint32_t)RunLength + (uint32_t)(x)); \
|
||||
a0 += (int)(uint32_t)(x); \
|
||||
RunLength = 0; \
|
||||
} while (0)
|
||||
#endif
|
||||
@@ -334,20 +334,20 @@ static const char *StateNames[] = {
|
||||
{ \
|
||||
if (RunLength) \
|
||||
SETVALUE(0); \
|
||||
if (a0 != lastx) \
|
||||
if (a0 != (int)lastx) \
|
||||
{ \
|
||||
badlength(a0, lastx); \
|
||||
while (a0 > lastx && pa > thisrun) \
|
||||
a0 -= *--pa; \
|
||||
if (a0 < lastx) \
|
||||
while (a0 > (int)lastx && pa > thisrun) \
|
||||
a0 -= (int)*--pa; \
|
||||
if (a0 < (int)lastx) \
|
||||
{ \
|
||||
if (a0 < 0) \
|
||||
a0 = 0; \
|
||||
if ((pa - thisrun) & 1) \
|
||||
SETVALUE(0); \
|
||||
SETVALUE(lastx - a0); \
|
||||
SETVALUE((uint32_t)((int)lastx - a0)); \
|
||||
} \
|
||||
else if (a0 > lastx) \
|
||||
else if (a0 > (int)lastx) \
|
||||
{ \
|
||||
SETVALUE(lastx); \
|
||||
SETVALUE(0); \
|
||||
@@ -385,8 +385,9 @@ static const char *StateNames[] = {
|
||||
goto doneWhite1d; \
|
||||
case S_MakeUpW: \
|
||||
case S_MakeUp: \
|
||||
a0 += TabEnt->Param; \
|
||||
RunLength += TabEnt->Param; \
|
||||
a0 = (int)((uint32_t)a0 + TabEnt->Param); \
|
||||
RunLength = \
|
||||
(int)((uint32_t)RunLength + TabEnt->Param); \
|
||||
break; \
|
||||
default: \
|
||||
unexpected("WhiteTable", a0); \
|
||||
@@ -394,7 +395,7 @@ static const char *StateNames[] = {
|
||||
} \
|
||||
} \
|
||||
doneWhite1d: \
|
||||
if (a0 >= lastx) \
|
||||
if (a0 >= (int)lastx) \
|
||||
goto done1d; \
|
||||
for (;;) \
|
||||
{ \
|
||||
@@ -409,8 +410,8 @@ static const char *StateNames[] = {
|
||||
goto doneBlack1d; \
|
||||
case S_MakeUpB: \
|
||||
case S_MakeUp: \
|
||||
a0 += TabEnt->Param; \
|
||||
RunLength += TabEnt->Param; \
|
||||
a0 += (int)TabEnt->Param; \
|
||||
RunLength += (int)TabEnt->Param; \
|
||||
break; \
|
||||
default: \
|
||||
unexpected("BlackTable", a0); \
|
||||
@@ -418,7 +419,7 @@ static const char *StateNames[] = {
|
||||
} \
|
||||
} \
|
||||
doneBlack1d: \
|
||||
if (a0 >= lastx) \
|
||||
if (a0 >= (int)lastx) \
|
||||
goto done1d; \
|
||||
if (*(pa - 1) == 0 && *(pa - 2) == 0) \
|
||||
pa -= 2; \
|
||||
@@ -439,17 +440,18 @@ static const char *StateNames[] = {
|
||||
do \
|
||||
{ \
|
||||
if (pa != thisrun) \
|
||||
while (b1 <= a0 && b1 < lastx) \
|
||||
while (b1 <= a0 && b1 < (int)lastx) \
|
||||
{ \
|
||||
if (pb + 1 >= sp->refruns + sp->nruns) \
|
||||
{ \
|
||||
TIFFErrorExtR( \
|
||||
tif, module, "Buffer overflow at line %u of %s %u", \
|
||||
sp->line, isTiled(tif) ? "tile" : "strip", \
|
||||
isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
|
||||
TIFFErrorExtR(tif, module, \
|
||||
"Buffer overflow at line %d of %s %u", \
|
||||
sp->line, isTiled(tif) ? "tile" : "strip", \
|
||||
isTiled(tif) ? tif->tif_dir.td_curtile \
|
||||
: tif->tif_dir.td_curstrip); \
|
||||
return (-1); \
|
||||
} \
|
||||
b1 += pb[0] + pb[1]; \
|
||||
b1 += (int)(pb[0] + pb[1]); \
|
||||
pb += 2; \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -460,14 +462,15 @@ static const char *StateNames[] = {
|
||||
#define EXPAND2D(eoflab) \
|
||||
do \
|
||||
{ \
|
||||
while (a0 < lastx) \
|
||||
while (a0 < (int)lastx) \
|
||||
{ \
|
||||
if (pa >= thisrun + sp->nruns) \
|
||||
{ \
|
||||
TIFFErrorExtR( \
|
||||
tif, module, "Buffer overflow at line %u of %s %u", \
|
||||
sp->line, isTiled(tif) ? "tile" : "strip", \
|
||||
isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
|
||||
TIFFErrorExtR(tif, module, \
|
||||
"Buffer overflow at line %d of %s %u", sp->line, \
|
||||
isTiled(tif) ? "tile" : "strip", \
|
||||
isTiled(tif) ? tif->tif_dir.td_curtile \
|
||||
: tif->tif_dir.td_curstrip); \
|
||||
return (-1); \
|
||||
} \
|
||||
LOOKUP8(7, TIFFFaxMainTable, eof2d); \
|
||||
@@ -477,18 +480,19 @@ static const char *StateNames[] = {
|
||||
CHECK_b1; \
|
||||
if (pb + 1 >= sp->refruns + sp->nruns) \
|
||||
{ \
|
||||
TIFFErrorExtR(tif, module, \
|
||||
"Buffer overflow at line %u of %s %u", \
|
||||
sp->line, \
|
||||
isTiled(tif) ? "tile" : "strip", \
|
||||
isTiled(tif) ? tif->tif_curtile \
|
||||
: tif->tif_curstrip); \
|
||||
TIFFErrorExtR( \
|
||||
tif, module, \
|
||||
"Buffer overflow at line %d of %s %u", sp->line, \
|
||||
isTiled(tif) ? "tile" : "strip", \
|
||||
isTiled(tif) ? tif->tif_dir.td_curtile \
|
||||
: tif->tif_dir.td_curstrip); \
|
||||
return (-1); \
|
||||
} \
|
||||
b1 += *pb++; \
|
||||
RunLength += b1 - a0; \
|
||||
b1 = b1 + (int)*pb++; \
|
||||
RunLength = \
|
||||
(int)((uint32_t)RunLength + (uint32_t)(b1 - a0)); \
|
||||
a0 = b1; \
|
||||
b1 += *pb++; \
|
||||
b1 = b1 + (int)*pb++; \
|
||||
break; \
|
||||
case S_Horiz: \
|
||||
if ((pa - thisrun) & 1) \
|
||||
@@ -503,8 +507,9 @@ static const char *StateNames[] = {
|
||||
goto doneWhite2da; \
|
||||
case S_MakeUpB: \
|
||||
case S_MakeUp: \
|
||||
a0 += TabEnt->Param; \
|
||||
RunLength += TabEnt->Param; \
|
||||
a0 = (int)((uint32_t)a0 + TabEnt->Param); \
|
||||
RunLength = (int)((uint32_t)RunLength + \
|
||||
TabEnt->Param); \
|
||||
break; \
|
||||
default: \
|
||||
goto badBlack2d; \
|
||||
@@ -521,8 +526,9 @@ static const char *StateNames[] = {
|
||||
goto doneBlack2da; \
|
||||
case S_MakeUpW: \
|
||||
case S_MakeUp: \
|
||||
a0 += TabEnt->Param; \
|
||||
RunLength += TabEnt->Param; \
|
||||
a0 = (int)((uint32_t)a0 + TabEnt->Param); \
|
||||
RunLength = (int)((uint32_t)RunLength + \
|
||||
TabEnt->Param); \
|
||||
break; \
|
||||
default: \
|
||||
goto badWhite2d; \
|
||||
@@ -542,8 +548,9 @@ static const char *StateNames[] = {
|
||||
goto doneWhite2db; \
|
||||
case S_MakeUpW: \
|
||||
case S_MakeUp: \
|
||||
a0 += TabEnt->Param; \
|
||||
RunLength += TabEnt->Param; \
|
||||
a0 = (int)((uint32_t)a0 + TabEnt->Param); \
|
||||
RunLength = (int)((uint32_t)RunLength + \
|
||||
TabEnt->Param); \
|
||||
break; \
|
||||
default: \
|
||||
goto badWhite2d; \
|
||||
@@ -560,8 +567,9 @@ static const char *StateNames[] = {
|
||||
goto doneBlack2db; \
|
||||
case S_MakeUpB: \
|
||||
case S_MakeUp: \
|
||||
a0 += TabEnt->Param; \
|
||||
RunLength += TabEnt->Param; \
|
||||
a0 = (int)((uint32_t)a0 + TabEnt->Param); \
|
||||
RunLength = (int)((uint32_t)RunLength + \
|
||||
TabEnt->Param); \
|
||||
break; \
|
||||
default: \
|
||||
goto badBlack2d; \
|
||||
@@ -576,47 +584,47 @@ static const char *StateNames[] = {
|
||||
SETVALUE(b1 - a0); \
|
||||
if (pb >= sp->refruns + sp->nruns) \
|
||||
{ \
|
||||
TIFFErrorExtR(tif, module, \
|
||||
"Buffer overflow at line %u of %s %u", \
|
||||
sp->line, \
|
||||
isTiled(tif) ? "tile" : "strip", \
|
||||
isTiled(tif) ? tif->tif_curtile \
|
||||
: tif->tif_curstrip); \
|
||||
TIFFErrorExtR( \
|
||||
tif, module, \
|
||||
"Buffer overflow at line %d of %s %u", sp->line, \
|
||||
isTiled(tif) ? "tile" : "strip", \
|
||||
isTiled(tif) ? tif->tif_dir.td_curtile \
|
||||
: tif->tif_dir.td_curstrip); \
|
||||
return (-1); \
|
||||
} \
|
||||
b1 += *pb++; \
|
||||
b1 = b1 + (int)*pb++; \
|
||||
break; \
|
||||
case S_VR: \
|
||||
CHECK_b1; \
|
||||
SETVALUE(b1 - a0 + TabEnt->Param); \
|
||||
SETVALUE((int)((uint32_t)(b1 - a0) + TabEnt->Param)); \
|
||||
if (pb >= sp->refruns + sp->nruns) \
|
||||
{ \
|
||||
TIFFErrorExtR(tif, module, \
|
||||
"Buffer overflow at line %u of %s %u", \
|
||||
sp->line, \
|
||||
isTiled(tif) ? "tile" : "strip", \
|
||||
isTiled(tif) ? tif->tif_curtile \
|
||||
: tif->tif_curstrip); \
|
||||
TIFFErrorExtR( \
|
||||
tif, module, \
|
||||
"Buffer overflow at line %d of %s %u", sp->line, \
|
||||
isTiled(tif) ? "tile" : "strip", \
|
||||
isTiled(tif) ? tif->tif_dir.td_curtile \
|
||||
: tif->tif_dir.td_curstrip); \
|
||||
return (-1); \
|
||||
} \
|
||||
b1 += *pb++; \
|
||||
b1 = b1 + (int)*pb++; \
|
||||
break; \
|
||||
case S_VL: \
|
||||
CHECK_b1; \
|
||||
if (b1 < (int)(a0 + TabEnt->Param)) \
|
||||
if (b1 < (int)((uint32_t)a0 + TabEnt->Param)) \
|
||||
{ \
|
||||
unexpected("VL", a0); \
|
||||
goto eol2d; \
|
||||
} \
|
||||
SETVALUE(b1 - a0 - TabEnt->Param); \
|
||||
b1 -= *--pb; \
|
||||
SETVALUE((int)((uint32_t)(b1 - a0) - TabEnt->Param)); \
|
||||
b1 = b1 - (int)*--pb; \
|
||||
break; \
|
||||
case S_Ext: \
|
||||
*pa++ = lastx - a0; \
|
||||
*pa++ = (uint32_t)((int)lastx - a0); \
|
||||
extension(a0); \
|
||||
goto eol2d; \
|
||||
case S_EOL: \
|
||||
*pa++ = lastx - a0; \
|
||||
*pa++ = (uint32_t)((int)lastx - a0); \
|
||||
NeedBits8(4, eof2d); \
|
||||
if (GetBits(4)) \
|
||||
unexpected("EOL", a0); \
|
||||
|
||||
432
3rdparty/libtiff/tif_getimage.c
vendored
432
3rdparty/libtiff/tif_getimage.c
vendored
File diff suppressed because it is too large
Load Diff
43
3rdparty/libtiff/tif_hash_set.c
vendored
43
3rdparty/libtiff/tif_hash_set.c
vendored
@@ -76,7 +76,7 @@ static const int anPrimes[] = {
|
||||
100663319, 201326611, 402653189, 805306457, 1610612741};
|
||||
|
||||
/************************************************************************/
|
||||
/* TIFFHashSetHashPointer() */
|
||||
/* TIFFHashSetHashPointer() */
|
||||
/************************************************************************/
|
||||
|
||||
/**
|
||||
@@ -93,7 +93,7 @@ static unsigned long TIFFHashSetHashPointer(const void *elt)
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* TIFFHashSetEqualPointer() */
|
||||
/* TIFFHashSetEqualPointer() */
|
||||
/************************************************************************/
|
||||
|
||||
/**
|
||||
@@ -111,7 +111,7 @@ static bool TIFFHashSetEqualPointer(const void *elt1, const void *elt2)
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* TIFFHashSetNew() */
|
||||
/* TIFFHashSetNew() */
|
||||
/************************************************************************/
|
||||
|
||||
/**
|
||||
@@ -164,7 +164,7 @@ TIFFHashSet *TIFFHashSetNew(TIFFHashSetHashFunc fnHashFunc,
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* TIFFHashSetSize() */
|
||||
/* TIFFHashSetSize() */
|
||||
/************************************************************************/
|
||||
|
||||
/**
|
||||
@@ -184,7 +184,7 @@ int TIFFHashSetSize(const TIFFHashSet *set)
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* TIFFHashSetGetNewListElt() */
|
||||
/* TIFFHashSetGetNewListElt() */
|
||||
/************************************************************************/
|
||||
|
||||
static TIFFList *TIFFHashSetGetNewListElt(TIFFHashSet *set)
|
||||
@@ -202,7 +202,7 @@ static TIFFList *TIFFHashSetGetNewListElt(TIFFHashSet *set)
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* TIFFHashSetReturnListElt() */
|
||||
/* TIFFHashSetReturnListElt() */
|
||||
/************************************************************************/
|
||||
|
||||
static void TIFFHashSetReturnListElt(TIFFHashSet *set, TIFFList *psList)
|
||||
@@ -220,7 +220,7 @@ static void TIFFHashSetReturnListElt(TIFFHashSet *set, TIFFList *psList)
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* TIFFHashSetClearInternal() */
|
||||
/* TIFFHashSetClearInternal() */
|
||||
/************************************************************************/
|
||||
|
||||
static void TIFFHashSetClearInternal(TIFFHashSet *set, bool bFinalize)
|
||||
@@ -246,7 +246,7 @@ static void TIFFHashSetClearInternal(TIFFHashSet *set, bool bFinalize)
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* TIFFListDestroy() */
|
||||
/* TIFFListDestroy() */
|
||||
/************************************************************************/
|
||||
|
||||
/**
|
||||
@@ -270,7 +270,7 @@ static void TIFFListDestroy(TIFFList *psList)
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* TIFFHashSetDestroy() */
|
||||
/* TIFFHashSetDestroy() */
|
||||
/************************************************************************/
|
||||
|
||||
/**
|
||||
@@ -295,7 +295,7 @@ void TIFFHashSetDestroy(TIFFHashSet *set)
|
||||
|
||||
#ifdef notused
|
||||
/************************************************************************/
|
||||
/* TIFFHashSetClear() */
|
||||
/* TIFFHashSetClear() */
|
||||
/************************************************************************/
|
||||
|
||||
/**
|
||||
@@ -319,7 +319,7 @@ void TIFFHashSetClear(TIFFHashSet *set)
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* TIFFHashSetForeach() */
|
||||
/* TIFFHashSetForeach() */
|
||||
/************************************************************************/
|
||||
|
||||
/**
|
||||
@@ -360,14 +360,14 @@ void TIFFHashSetForeach(TIFFHashSet *set, TIFFHashSetIterEltFunc fnIterFunc,
|
||||
#endif
|
||||
|
||||
/************************************************************************/
|
||||
/* TIFFHashSetRehash() */
|
||||
/* TIFFHashSetRehash() */
|
||||
/************************************************************************/
|
||||
|
||||
static bool TIFFHashSetRehash(TIFFHashSet *set)
|
||||
{
|
||||
int nNewAllocatedSize = anPrimes[set->nIndiceAllocatedSize];
|
||||
TIFFList **newTabList =
|
||||
(TIFFList **)(calloc(nNewAllocatedSize, sizeof(TIFFList *)));
|
||||
(TIFFList **)(calloc((size_t)nNewAllocatedSize, sizeof(TIFFList *)));
|
||||
if (newTabList == NULL)
|
||||
return false;
|
||||
#ifdef HASH_DEBUG
|
||||
@@ -384,7 +384,7 @@ static bool TIFFHashSetRehash(TIFFHashSet *set)
|
||||
while (cur)
|
||||
{
|
||||
const unsigned long nNewHashVal =
|
||||
set->fnHashFunc(cur->pData) % nNewAllocatedSize;
|
||||
set->fnHashFunc(cur->pData) % (unsigned long)nNewAllocatedSize;
|
||||
#ifdef HASH_DEBUG
|
||||
if (newTabList[nNewHashVal])
|
||||
set->nCollisions++;
|
||||
@@ -403,12 +403,13 @@ static bool TIFFHashSetRehash(TIFFHashSet *set)
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* TIFFHashSetFindPtr() */
|
||||
/* TIFFHashSetFindPtr() */
|
||||
/************************************************************************/
|
||||
|
||||
static void **TIFFHashSetFindPtr(TIFFHashSet *set, const void *elt)
|
||||
{
|
||||
const unsigned long nHashVal = set->fnHashFunc(elt) % set->nAllocatedSize;
|
||||
const unsigned long nHashVal =
|
||||
set->fnHashFunc(elt) % (unsigned long)set->nAllocatedSize;
|
||||
TIFFList *cur = set->tabList[nHashVal];
|
||||
while (cur)
|
||||
{
|
||||
@@ -464,7 +465,8 @@ bool TIFFHashSetInsert(TIFFHashSet *set, void *elt)
|
||||
}
|
||||
}
|
||||
|
||||
const unsigned long nHashVal = set->fnHashFunc(elt) % set->nAllocatedSize;
|
||||
const unsigned long nHashVal =
|
||||
set->fnHashFunc(elt) % (unsigned long)set->nAllocatedSize;
|
||||
#ifdef HASH_DEBUG
|
||||
if (set->tabList[nHashVal])
|
||||
set->nCollisions++;
|
||||
@@ -486,7 +488,7 @@ bool TIFFHashSetInsert(TIFFHashSet *set, void *elt)
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* TIFFHashSetLookup() */
|
||||
/* TIFFHashSetLookup() */
|
||||
/************************************************************************/
|
||||
|
||||
/**
|
||||
@@ -532,7 +534,8 @@ static bool TIFFHashSetRemoveInternal(TIFFHashSet *set, const void *elt,
|
||||
}
|
||||
}
|
||||
|
||||
int nHashVal = (int)(set->fnHashFunc(elt) % set->nAllocatedSize);
|
||||
int nHashVal =
|
||||
(int)(set->fnHashFunc(elt) % (unsigned long)set->nAllocatedSize);
|
||||
TIFFList *cur = set->tabList[nHashVal];
|
||||
TIFFList *prev = NULL;
|
||||
while (cur)
|
||||
@@ -581,7 +584,7 @@ bool TIFFHashSetRemove(TIFFHashSet *set, const void *elt)
|
||||
|
||||
#ifdef notused
|
||||
/************************************************************************/
|
||||
/* TIFFHashSetRemoveDeferRehash() */
|
||||
/* TIFFHashSetRemoveDeferRehash() */
|
||||
/************************************************************************/
|
||||
|
||||
/**
|
||||
|
||||
11
3rdparty/libtiff/tif_jbig.c
vendored
11
3rdparty/libtiff/tif_jbig.c
vendored
@@ -33,7 +33,14 @@
|
||||
#include "tiffiop.h"
|
||||
|
||||
#ifdef JBIG_SUPPORT
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#include "jbig.h"
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
static int JBIGSetupDecode(TIFF *tif)
|
||||
{
|
||||
@@ -100,7 +107,7 @@ static int JBIGDecode(TIFF *tif, uint8_t *buffer, tmsize_t size, uint16_t s)
|
||||
decodedSize = jbg_dec_getsize(&decoder);
|
||||
if ((tmsize_t)decodedSize < size)
|
||||
{
|
||||
memset(buffer + decodedSize, 0, (size_t)(size - decodedSize));
|
||||
memset(buffer + decodedSize, 0, (size_t)(size - (tmsize_t)decodedSize));
|
||||
TIFFWarningExtR(tif, "JBIG",
|
||||
"Only decoded %lu bytes, whereas %" TIFF_SSIZE_FORMAT
|
||||
" requested",
|
||||
@@ -116,7 +123,7 @@ static int JBIGDecode(TIFF *tif, uint8_t *buffer, tmsize_t size, uint16_t s)
|
||||
return 0;
|
||||
}
|
||||
pImage = jbg_dec_getimage(&decoder, 0);
|
||||
_TIFFmemcpy(buffer, pImage, decodedSize);
|
||||
_TIFFmemcpy(buffer, pImage, (tmsize_t)decodedSize);
|
||||
jbg_dec_free(&decoder);
|
||||
|
||||
tif->tif_rawcp += tif->tif_rawcc;
|
||||
|
||||
392
3rdparty/libtiff/tif_jpeg.c
vendored
392
3rdparty/libtiff/tif_jpeg.c
vendored
@@ -22,9 +22,6 @@
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define VC_EXTRALEAN
|
||||
|
||||
#include "tiffiop.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -146,20 +143,9 @@ int TIFFJPEGIsFullStripRequired_12(TIFF *tif);
|
||||
#define LONGJMP(jbuf, code) longjmp(jbuf, code)
|
||||
#define JMP_BUF jmp_buf
|
||||
|
||||
#ifndef TIFF_jpeg_destination_mgr_defined
|
||||
#define TIFF_jpeg_destination_mgr_defined
|
||||
typedef struct jpeg_destination_mgr jpeg_destination_mgr;
|
||||
#endif
|
||||
|
||||
#ifndef TIFF_jpeg_source_mgr_defined
|
||||
#define TIFF_jpeg_source_mgr_defined
|
||||
typedef struct jpeg_source_mgr jpeg_source_mgr;
|
||||
#endif
|
||||
|
||||
#ifndef TIFF_jpeg_error_mgr_defined
|
||||
#define TIFF_jpeg_error_mgr_defined
|
||||
typedef struct jpeg_error_mgr jpeg_error_mgr;
|
||||
#endif
|
||||
typedef struct jpeg_destination_mgr tiff_jpeg_destination_mgr;
|
||||
typedef struct jpeg_source_mgr tiff_jpeg_source_mgr;
|
||||
typedef struct jpeg_error_mgr tiff_jpeg_error_mgr;
|
||||
|
||||
/*
|
||||
* State block for each open TIFF file using
|
||||
@@ -174,6 +160,10 @@ typedef struct jpeg_error_mgr jpeg_error_mgr;
|
||||
* so we can safely cast JPEGState* -> jpeg_xxx_struct*
|
||||
* and vice versa!
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4324) /* structure padding due to alignment */
|
||||
#endif
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
@@ -184,22 +174,24 @@ typedef struct
|
||||
} cinfo; /* NB: must be first */
|
||||
int cinfo_initialized;
|
||||
|
||||
jpeg_error_mgr err; /* libjpeg error manager */
|
||||
JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */
|
||||
tiff_jpeg_error_mgr err; /* libjpeg error manager */
|
||||
JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */
|
||||
|
||||
struct jpeg_progress_mgr progress;
|
||||
/*
|
||||
* The following two members could be a union, but
|
||||
* they're small enough that it's not worth the effort.
|
||||
*/
|
||||
jpeg_destination_mgr dest; /* data dest for compression */
|
||||
jpeg_source_mgr src; /* data source for decompression */
|
||||
/* private state */
|
||||
TIFF *tif; /* back link needed by some code */
|
||||
uint16_t photometric; /* copy of PhotometricInterpretation */
|
||||
uint16_t h_sampling; /* luminance sampling factors */
|
||||
tiff_jpeg_destination_mgr dest; /* data dest for compression */
|
||||
tiff_jpeg_source_mgr src; /* data source for decompression */
|
||||
/* private state */
|
||||
TIFF *tif; /* back link needed by some code */
|
||||
uint16_t photometric; /* copy of PhotometricInterpretation */
|
||||
uint16_t h_sampling; /* luminance sampling factors */
|
||||
uint16_t v_sampling;
|
||||
tmsize_t bytesperline; /* decompressed bytes per scanline */
|
||||
uint32_t strile_width;
|
||||
uint32_t strile_height;
|
||||
/* pointers to intermediate buffers when processing downsampled data */
|
||||
TIFF_JSAMPARRAY ds_buffer[MAX_COMPONENTS];
|
||||
int scancount; /* number of "scanlines" accumulated */
|
||||
@@ -209,6 +201,9 @@ typedef struct
|
||||
|
||||
int encode_raw_error;
|
||||
} JPEGState;
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#define JState(tif) ((JPEGState *)(tif)->tif_data)
|
||||
|
||||
@@ -559,7 +554,7 @@ static boolean tables_empty_output_buffer(j_compress_ptr cinfo)
|
||||
/* the entire buffer has been filled; enlarge it by 1000 bytes */
|
||||
newbuf =
|
||||
_TIFFreallocExt(sp->tif, (void *)sp->otherSettings.jpegtables,
|
||||
(tmsize_t)(sp->otherSettings.jpegtables_length + 1000));
|
||||
(tmsize_t)sp->otherSettings.jpegtables_length + 1000);
|
||||
if (newbuf == NULL)
|
||||
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100);
|
||||
sp->dest.next_output_byte =
|
||||
@@ -912,7 +907,7 @@ JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData *data)
|
||||
return (0);
|
||||
if (n < 2)
|
||||
return (0);
|
||||
n -= 2;
|
||||
n = (uint16_t)(n - 2);
|
||||
if (n > 0)
|
||||
JPEGFixupTagsSubsamplingSkip(data, n);
|
||||
}
|
||||
@@ -1016,7 +1011,7 @@ JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData *data,
|
||||
assert(m < 0x80000000UL);
|
||||
if (TIFFReadFile(data->tif, data->buffer, (tmsize_t)m) != (tmsize_t)m)
|
||||
return (0);
|
||||
data->buffercurrentbyte = data->buffer;
|
||||
data->buffercurrentbyte = (uint8_t *)data->buffer;
|
||||
data->bufferbytesleft = m;
|
||||
data->fileoffset += m;
|
||||
data->filebytesleft -= m;
|
||||
@@ -1037,7 +1032,7 @@ JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData *data,
|
||||
return (0);
|
||||
if (!JPEGFixupTagsSubsamplingReadByte(data, &mb))
|
||||
return (0);
|
||||
*result = (ma << 8) | mb;
|
||||
*result = (uint16_t)((ma << 8) | mb);
|
||||
return (1);
|
||||
}
|
||||
|
||||
@@ -1159,6 +1154,47 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int JPEGComputeStrileWidthHeightBytesPerLine(TIFF *tif, uint16_t s)
|
||||
{
|
||||
JPEGState *sp = JState(tif);
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
|
||||
/*
|
||||
* Check image parameters and set decompression parameters.
|
||||
*/
|
||||
if (isTiled(tif))
|
||||
{
|
||||
sp->strile_width = td->td_tilewidth;
|
||||
sp->strile_height = td->td_tilelength;
|
||||
sp->bytesperline = TIFFTileRowSize(tif);
|
||||
}
|
||||
else
|
||||
{
|
||||
sp->strile_width = td->td_imagewidth;
|
||||
sp->strile_height = td->td_imagelength - tif->tif_dir.td_row;
|
||||
if (sp->strile_height > td->td_rowsperstrip)
|
||||
sp->strile_height = td->td_rowsperstrip;
|
||||
sp->bytesperline = TIFFScanlineSize(tif);
|
||||
}
|
||||
if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0)
|
||||
{
|
||||
/*
|
||||
* For PC 2, scale down the expected strip/tile size
|
||||
* to match a downsampled component
|
||||
*/
|
||||
if (sp->h_sampling == 0 || sp->v_sampling == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, "JPEGComputeStrileWidthHeightBytesPerLine",
|
||||
"JPEG horizontal or vertical sampling is zero");
|
||||
return (0);
|
||||
}
|
||||
sp->strile_width = TIFFhowmany_32(sp->strile_width, sp->h_sampling);
|
||||
sp->strile_height = TIFFhowmany_32(sp->strile_height, sp->v_sampling);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up for decoding a strip or tile.
|
||||
*/
|
||||
@@ -1167,7 +1203,6 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif)
|
||||
JPEGState *sp = JState(tif);
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
static const char module[] = "JPEGPreDecode";
|
||||
uint32_t segment_width, segment_height;
|
||||
int downsampled_output;
|
||||
int ci;
|
||||
|
||||
@@ -1193,52 +1228,24 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif)
|
||||
return (0);
|
||||
|
||||
tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte;
|
||||
tif->tif_rawcc = sp->src.bytes_in_buffer;
|
||||
tif->tif_rawcc = (tmsize_t)sp->src.bytes_in_buffer;
|
||||
|
||||
/*
|
||||
* Check image parameters and set decompression parameters.
|
||||
*/
|
||||
if (isTiled(tif))
|
||||
{
|
||||
segment_width = td->td_tilewidth;
|
||||
segment_height = td->td_tilelength;
|
||||
sp->bytesperline = TIFFTileRowSize(tif);
|
||||
}
|
||||
else
|
||||
{
|
||||
segment_width = td->td_imagewidth;
|
||||
segment_height = td->td_imagelength - tif->tif_row;
|
||||
if (segment_height > td->td_rowsperstrip)
|
||||
segment_height = td->td_rowsperstrip;
|
||||
sp->bytesperline = TIFFScanlineSize(tif);
|
||||
}
|
||||
if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0)
|
||||
{
|
||||
/*
|
||||
* For PC 2, scale down the expected strip/tile size
|
||||
* to match a downsampled component
|
||||
*/
|
||||
if (sp->h_sampling == 0 || sp->v_sampling == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"JPEG horizontal or vertical sampling is zero");
|
||||
return (0);
|
||||
}
|
||||
segment_width = TIFFhowmany_32(segment_width, sp->h_sampling);
|
||||
segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
|
||||
}
|
||||
if (sp->cinfo.d.image_width < segment_width ||
|
||||
sp->cinfo.d.image_height < segment_height)
|
||||
if (!JPEGComputeStrileWidthHeightBytesPerLine(tif, s))
|
||||
return 0;
|
||||
|
||||
if (sp->cinfo.d.image_width < sp->strile_width ||
|
||||
sp->cinfo.d.image_height < sp->strile_height)
|
||||
{
|
||||
TIFFWarningExtR(tif, module,
|
||||
"Improper JPEG strip/tile size, "
|
||||
"expected %" PRIu32 "x%" PRIu32 ", got %ux%u",
|
||||
segment_width, segment_height, sp->cinfo.d.image_width,
|
||||
sp->cinfo.d.image_height);
|
||||
sp->strile_width, sp->strile_height,
|
||||
sp->cinfo.d.image_width, sp->cinfo.d.image_height);
|
||||
}
|
||||
if (sp->cinfo.d.image_width == segment_width &&
|
||||
sp->cinfo.d.image_height > segment_height &&
|
||||
tif->tif_row + segment_height == td->td_imagelength && !isTiled(tif))
|
||||
if (sp->cinfo.d.image_width == sp->strile_width &&
|
||||
sp->cinfo.d.image_height > sp->strile_height &&
|
||||
tif->tif_dir.td_row + sp->strile_height == td->td_imagelength &&
|
||||
!isTiled(tif))
|
||||
{
|
||||
/* Some files have a last strip, that should be truncated, */
|
||||
/* but their JPEG codestream has still the maximum strip */
|
||||
@@ -1247,11 +1254,11 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif)
|
||||
TIFFWarningExtR(tif, module,
|
||||
"JPEG strip size exceeds expected dimensions,"
|
||||
" expected %" PRIu32 "x%" PRIu32 ", got %ux%u",
|
||||
segment_width, segment_height, sp->cinfo.d.image_width,
|
||||
sp->cinfo.d.image_height);
|
||||
sp->strile_width, sp->strile_height,
|
||||
sp->cinfo.d.image_width, sp->cinfo.d.image_height);
|
||||
}
|
||||
else if (sp->cinfo.d.image_width > segment_width ||
|
||||
sp->cinfo.d.image_height > segment_height)
|
||||
else if (sp->cinfo.d.image_width > sp->strile_width ||
|
||||
sp->cinfo.d.image_height > sp->strile_height)
|
||||
{
|
||||
/*
|
||||
* This case could be dangerous, if the strip or tile size has
|
||||
@@ -1262,8 +1269,8 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif)
|
||||
TIFFErrorExtR(tif, module,
|
||||
"JPEG strip/tile size exceeds expected dimensions,"
|
||||
" expected %" PRIu32 "x%" PRIu32 ", got %ux%u",
|
||||
segment_width, segment_height, sp->cinfo.d.image_width,
|
||||
sp->cinfo.d.image_height);
|
||||
sp->strile_width, sp->strile_height,
|
||||
sp->cinfo.d.image_width, sp->cinfo.d.image_height);
|
||||
return (0);
|
||||
}
|
||||
if (sp->cinfo.d.num_components !=
|
||||
@@ -1282,7 +1289,8 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif)
|
||||
sp->cinfo.d.data_precision = td->td_bitspersample;
|
||||
sp->cinfo.d.bits_in_jsample = td->td_bitspersample;
|
||||
#else
|
||||
if (sp->cinfo.d.data_precision != td->td_bitspersample)
|
||||
if (td->td_bitspersample != BITS_IN_JSAMPLE ||
|
||||
sp->cinfo.d.data_precision != td->td_bitspersample)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Improper JPEG data precision");
|
||||
return (0);
|
||||
@@ -1319,11 +1327,12 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif)
|
||||
if (compptr->h_samp_factor > 0 && compptr->v_samp_factor > 0)
|
||||
{
|
||||
nRequiredMemory +=
|
||||
(toff_t)(((compptr->width_in_blocks +
|
||||
compptr->h_samp_factor - 1) /
|
||||
compptr->h_samp_factor)) *
|
||||
((compptr->height_in_blocks + compptr->v_samp_factor - 1) /
|
||||
compptr->v_samp_factor) *
|
||||
(toff_t)((JDIMENSION)(((int)compptr->width_in_blocks +
|
||||
compptr->h_samp_factor - 1) /
|
||||
compptr->h_samp_factor)) *
|
||||
(JDIMENSION)(((int)compptr->height_in_blocks +
|
||||
compptr->v_samp_factor - 1) /
|
||||
compptr->v_samp_factor) *
|
||||
sizeof(JBLOCK);
|
||||
}
|
||||
}
|
||||
@@ -1439,7 +1448,7 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif)
|
||||
* Decode a chunk of pixels.
|
||||
* "Standard" case: returned data is not downsampled.
|
||||
*/
|
||||
#if !JPEG_LIB_MK1_OR_12BIT
|
||||
#if !defined(JPEG_LIB_MK1_OR_12BIT)
|
||||
static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
{
|
||||
JPEGState *sp = JState(tif);
|
||||
@@ -1464,7 +1473,18 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
TIFFWarningExtR(tif, tif->tif_name, "fractional scanline not read");
|
||||
|
||||
if (nrows > (tmsize_t)sp->cinfo.d.image_height)
|
||||
{
|
||||
/* Initialize the output buffer if the JPEG image is smaller than the
|
||||
* strile height. */
|
||||
memset(buf, 0, (size_t)cc);
|
||||
nrows = sp->cinfo.d.image_height;
|
||||
}
|
||||
else if (sp->strile_width > sp->cinfo.d.image_width)
|
||||
{
|
||||
/* Initialize the output buffer if the JPEG image is smaller than the
|
||||
* strile width. */
|
||||
memset(buf, 0, (size_t)cc);
|
||||
}
|
||||
|
||||
/* data is expected to be read in multiples of a scanline */
|
||||
if (nrows)
|
||||
@@ -1483,7 +1503,7 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
return (0);
|
||||
}
|
||||
|
||||
++tif->tif_row;
|
||||
++tif->tif_dir.td_row;
|
||||
buf += sp->bytesperline;
|
||||
cc -= sp->bytesperline;
|
||||
} while (--nrows > 0);
|
||||
@@ -1491,15 +1511,15 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
|
||||
/* Update information on consumed data */
|
||||
tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte;
|
||||
tif->tif_rawcc = sp->src.bytes_in_buffer;
|
||||
tif->tif_rawcc = (tmsize_t)sp->src.bytes_in_buffer;
|
||||
|
||||
/* Close down the decompressor if we've finished the strip or tile. */
|
||||
return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height ||
|
||||
TIFFjpeg_finish_decompress(sp);
|
||||
}
|
||||
#endif /* !JPEG_LIB_MK1_OR_12BIT */
|
||||
#endif /* !defined(JPEG_LIB_MK1_OR_12BIT) */
|
||||
|
||||
#if JPEG_LIB_MK1_OR_12BIT
|
||||
#if defined(JPEG_LIB_MK1_OR_12BIT)
|
||||
/*ARGSUSED*/ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc,
|
||||
uint16_t s)
|
||||
{
|
||||
@@ -1525,7 +1545,18 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
TIFFWarningExtR(tif, tif->tif_name, "fractional scanline not read");
|
||||
|
||||
if (nrows > (tmsize_t)sp->cinfo.d.image_height)
|
||||
{
|
||||
/* Initialize the output buffer if the JPEG image is smaller than the
|
||||
* strile height. */
|
||||
memset(buf, 0, (size_t)cc);
|
||||
nrows = sp->cinfo.d.image_height;
|
||||
}
|
||||
else if (sp->strile_width > sp->cinfo.d.image_width)
|
||||
{
|
||||
/* Initialize the output buffer if the JPEG image is smaller than the
|
||||
* strile width. */
|
||||
memset(buf, 0, (size_t)cc);
|
||||
}
|
||||
|
||||
/* data is expected to be read in multiples of a scanline */
|
||||
if (nrows)
|
||||
@@ -1539,8 +1570,9 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
if (sp->cinfo.d.data_precision == 12)
|
||||
{
|
||||
line_work_buf = (TIFF_JSAMPROW)_TIFFmallocExt(
|
||||
tif, sizeof(short) * sp->cinfo.d.output_width *
|
||||
sp->cinfo.d.num_components);
|
||||
tif, (tmsize_t)((size_t)sizeof(short) *
|
||||
(size_t)sp->cinfo.d.output_width *
|
||||
(size_t)sp->cinfo.d.num_components));
|
||||
}
|
||||
|
||||
do
|
||||
@@ -1556,14 +1588,16 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1)
|
||||
{
|
||||
memset(buf, 0, (size_t)cc);
|
||||
_TIFFfreeExt(tif, line_work_buf);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (sp->cinfo.d.data_precision == 12)
|
||||
{
|
||||
int value_pairs = (sp->cinfo.d.output_width *
|
||||
sp->cinfo.d.num_components) /
|
||||
2;
|
||||
int value_pairs =
|
||||
(int)((JDIMENSION)sp->cinfo.d.output_width *
|
||||
(JDIMENSION)sp->cinfo.d.num_components) /
|
||||
2;
|
||||
int iPair;
|
||||
|
||||
for (iPair = 0; iPair < value_pairs; iPair++)
|
||||
@@ -1582,18 +1616,19 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
else if (sp->cinfo.d.data_precision == 8)
|
||||
{
|
||||
int value_count =
|
||||
(sp->cinfo.d.output_width * sp->cinfo.d.num_components);
|
||||
(int)((JDIMENSION)sp->cinfo.d.output_width *
|
||||
(JDIMENSION)sp->cinfo.d.num_components);
|
||||
int iValue;
|
||||
|
||||
for (iValue = 0; iValue < value_count; iValue++)
|
||||
{
|
||||
((unsigned char *)buf)[iValue] =
|
||||
line_work_buf[iValue] & 0xff;
|
||||
(unsigned char)(line_work_buf[iValue] & 0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++tif->tif_row;
|
||||
++tif->tif_dir.td_row;
|
||||
buf += sp->bytesperline;
|
||||
cc -= sp->bytesperline;
|
||||
} while (--nrows > 0);
|
||||
@@ -1604,13 +1639,13 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
|
||||
/* Update information on consumed data */
|
||||
tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte;
|
||||
tif->tif_rawcc = sp->src.bytes_in_buffer;
|
||||
tif->tif_rawcc = (tmsize_t)sp->src.bytes_in_buffer;
|
||||
|
||||
/* Close down the decompressor if we've finished the strip or tile. */
|
||||
return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height ||
|
||||
TIFFjpeg_finish_decompress(sp);
|
||||
}
|
||||
#endif /* JPEG_LIB_MK1_OR_12BIT */
|
||||
#endif /* defined(JPEG_LIB_MK1_OR_12BIT) */
|
||||
|
||||
/*ARGSUSED*/ static int DecodeRowError(TIFF *tif, uint8_t *buf, tmsize_t cc,
|
||||
uint16_t s)
|
||||
@@ -1644,8 +1679,16 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
/* For last strip, limit number of rows to its truncated height */
|
||||
/* even if the codestream height is larger (which is not compliant, */
|
||||
/* but that we tolerate) */
|
||||
if ((uint32_t)nrows > td->td_imagelength - tif->tif_row && !isTiled(tif))
|
||||
nrows = td->td_imagelength - tif->tif_row;
|
||||
if ((uint32_t)nrows > td->td_imagelength - tif->tif_dir.td_row &&
|
||||
!isTiled(tif))
|
||||
nrows = td->td_imagelength - tif->tif_dir.td_row;
|
||||
|
||||
/* The downsampled-data decode loop below only writes up to the JPEG
|
||||
* codestream dimensions (and, due to the clump stride, may not cover the
|
||||
* full caller buffer even for compliant files). Zero the whole buffer so
|
||||
* no uninitialised heap is ever returned, mirroring the guard JPEGDecode
|
||||
* received in 65759931ab6e (#826). */
|
||||
memset(buf, 0, (size_t)cc);
|
||||
|
||||
#if defined(JPEG_LIB_MK1_OR_12BIT)
|
||||
unsigned short *tmpbuf = NULL;
|
||||
@@ -1660,9 +1703,10 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
int samples_per_clump = sp->samplesperclump;
|
||||
|
||||
#if defined(JPEG_LIB_MK1_OR_12BIT)
|
||||
tmpbuf = _TIFFmallocExt(tif, sizeof(unsigned short) *
|
||||
sp->cinfo.d.output_width *
|
||||
sp->cinfo.d.num_components);
|
||||
tmpbuf = (unsigned short *)_TIFFmallocExt(
|
||||
tif, (tmsize_t)((size_t)sizeof(unsigned short) *
|
||||
(size_t)sp->cinfo.d.output_width *
|
||||
(size_t)sp->cinfo.d.num_components));
|
||||
if (tmpbuf == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, "JPEGDecodeRaw", "Out of memory");
|
||||
@@ -1755,18 +1799,20 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
if (sp->cinfo.d.data_precision == 8)
|
||||
{
|
||||
int i = 0;
|
||||
int len =
|
||||
sp->cinfo.d.output_width * sp->cinfo.d.num_components;
|
||||
int len = (int)((JDIMENSION)sp->cinfo.d.output_width *
|
||||
(JDIMENSION)sp->cinfo.d.num_components);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
((unsigned char *)buf)[i] = tmpbuf[i] & 0xff;
|
||||
((unsigned char *)buf)[i] =
|
||||
(unsigned char)(tmpbuf[i] & 0xff);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* 12-bit */
|
||||
int value_pairs = (sp->cinfo.d.output_width *
|
||||
sp->cinfo.d.num_components) /
|
||||
2;
|
||||
int value_pairs =
|
||||
(int)((JDIMENSION)sp->cinfo.d.output_width *
|
||||
(JDIMENSION)sp->cinfo.d.num_components) /
|
||||
2;
|
||||
int iPair;
|
||||
for (iPair = 0; iPair < value_pairs; iPair++)
|
||||
{
|
||||
@@ -1785,7 +1831,7 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
#endif
|
||||
|
||||
sp->scancount++;
|
||||
tif->tif_row += sp->v_sampling;
|
||||
tif->tif_dir.td_row += sp->v_sampling;
|
||||
|
||||
buf += sp->bytesperline;
|
||||
cc -= sp->bytesperline;
|
||||
@@ -2024,9 +2070,9 @@ static int JPEGSetupEncode(TIFF *tif)
|
||||
if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE, &ref))
|
||||
{
|
||||
float refbw[6];
|
||||
long top = 1L << td->td_bitspersample;
|
||||
uint32_t top = 1U << td->td_bitspersample;
|
||||
refbw[0] = 0;
|
||||
refbw[1] = (float)(top - 1L);
|
||||
refbw[1] = (float)(top - 1);
|
||||
refbw[2] = (float)(top >> 1);
|
||||
refbw[3] = refbw[1];
|
||||
refbw[4] = refbw[2];
|
||||
@@ -2074,30 +2120,30 @@ static int JPEGSetupEncode(TIFF *tif)
|
||||
#endif
|
||||
if (isTiled(tif))
|
||||
{
|
||||
if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0)
|
||||
if ((td->td_tilelength % ((uint32_t)sp->v_sampling * DCTSIZE)) != 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"JPEG tile height must be multiple of %" PRIu32,
|
||||
(uint32_t)(sp->v_sampling * DCTSIZE));
|
||||
(uint32_t)sp->v_sampling * DCTSIZE);
|
||||
return (0);
|
||||
}
|
||||
if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0)
|
||||
if ((td->td_tilewidth % ((uint32_t)sp->h_sampling * DCTSIZE)) != 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"JPEG tile width must be multiple of %" PRIu32,
|
||||
(uint32_t)(sp->h_sampling * DCTSIZE));
|
||||
(uint32_t)sp->h_sampling * DCTSIZE);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (td->td_rowsperstrip < td->td_imagelength &&
|
||||
(td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0)
|
||||
(td->td_rowsperstrip % ((uint32_t)sp->v_sampling * DCTSIZE)) != 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"RowsPerStrip must be multiple of %" PRIu32
|
||||
" for JPEG",
|
||||
(uint32_t)(sp->v_sampling * DCTSIZE));
|
||||
(uint32_t)sp->v_sampling * DCTSIZE);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
@@ -2153,7 +2199,6 @@ static int JPEGPreEncode(TIFF *tif, uint16_t s)
|
||||
JPEGState *sp = JState(tif);
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
static const char module[] = "JPEGPreEncode";
|
||||
uint32_t segment_width, segment_height;
|
||||
int downsampled_input;
|
||||
|
||||
assert(sp != NULL);
|
||||
@@ -2164,47 +2209,20 @@ static int JPEGPreEncode(TIFF *tif, uint16_t s)
|
||||
}
|
||||
|
||||
assert(!sp->cinfo.comm.is_decompressor);
|
||||
/*
|
||||
* Set encoding parameters for this strip/tile.
|
||||
*/
|
||||
if (isTiled(tif))
|
||||
{
|
||||
segment_width = td->td_tilewidth;
|
||||
segment_height = td->td_tilelength;
|
||||
sp->bytesperline = TIFFTileRowSize(tif);
|
||||
}
|
||||
else
|
||||
{
|
||||
segment_width = td->td_imagewidth;
|
||||
segment_height = td->td_imagelength - tif->tif_row;
|
||||
if (segment_height > td->td_rowsperstrip)
|
||||
segment_height = td->td_rowsperstrip;
|
||||
sp->bytesperline = TIFFScanlineSize(tif);
|
||||
}
|
||||
if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0)
|
||||
{
|
||||
/* for PC 2, scale down the strip/tile size
|
||||
* to match a downsampled component
|
||||
*/
|
||||
if (sp->h_sampling == 0 || sp->v_sampling == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"JPEG horizontal or vertical sampling is zero");
|
||||
return (0);
|
||||
}
|
||||
segment_width = TIFFhowmany_32(segment_width, sp->h_sampling);
|
||||
segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
|
||||
}
|
||||
if (segment_width > (uint32_t)JPEG_MAX_DIMENSION ||
|
||||
segment_height > (uint32_t)JPEG_MAX_DIMENSION)
|
||||
|
||||
if (!JPEGComputeStrileWidthHeightBytesPerLine(tif, s))
|
||||
return 0;
|
||||
|
||||
if (sp->strile_width > (uint32_t)JPEG_MAX_DIMENSION ||
|
||||
sp->strile_height > (uint32_t)JPEG_MAX_DIMENSION)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Strip/tile too large for JPEG. Maximum dimension is %d",
|
||||
(int)JPEG_MAX_DIMENSION);
|
||||
return (0);
|
||||
}
|
||||
sp->cinfo.c.image_width = segment_width;
|
||||
sp->cinfo.c.image_height = segment_height;
|
||||
sp->cinfo.c.image_width = sp->strile_width;
|
||||
sp->cinfo.c.image_height = sp->strile_height;
|
||||
downsampled_input = FALSE;
|
||||
if (td->td_planarconfig == PLANARCONFIG_CONTIG)
|
||||
{
|
||||
@@ -2276,7 +2294,13 @@ static int JPEGPreEncode(TIFF *tif, uint16_t s)
|
||||
/* an existing file */
|
||||
suppress_huff_table(sp, 0);
|
||||
suppress_huff_table(sp, 1);
|
||||
sp->cinfo.c.optimize_coding = FALSE;
|
||||
|
||||
/* We want to keep optimize_coding = TRUE for 12-bit JPEG */
|
||||
/* See lengthy explanation at
|
||||
* https://gitlab.com/libtiff/libtiff/-/work_items/773#note_3009836854
|
||||
*/
|
||||
if (sp->cinfo.c.data_precision == 8)
|
||||
sp->cinfo.c.optimize_coding = FALSE;
|
||||
}
|
||||
else
|
||||
sp->cinfo.c.optimize_coding = TRUE;
|
||||
@@ -2332,13 +2356,15 @@ static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
TIFFWarningExtR(tif, tif->tif_name, "fractional scanline discarded");
|
||||
|
||||
/* The last strip will be limited to image size */
|
||||
if (!isTiled(tif) && tif->tif_row + nrows > tif->tif_dir.td_imagelength)
|
||||
nrows = tif->tif_dir.td_imagelength - tif->tif_row;
|
||||
if (!isTiled(tif) &&
|
||||
tif->tif_dir.td_row + nrows > tif->tif_dir.td_imagelength)
|
||||
nrows = tif->tif_dir.td_imagelength - tif->tif_dir.td_row;
|
||||
|
||||
if (sp->cinfo.c.data_precision == 12)
|
||||
{
|
||||
line16_count = (int)((sp->bytesperline * 2) / 3);
|
||||
line16 = (short *)_TIFFmallocExt(tif, sizeof(short) * line16_count);
|
||||
line16 = (short *)_TIFFmallocExt(
|
||||
tif, (tmsize_t)(sizeof(short) * (size_t)line16_count));
|
||||
if (!line16)
|
||||
{
|
||||
TIFFErrorExtR(tif, "JPEGEncode", "Failed to allocate memory");
|
||||
@@ -2363,8 +2389,10 @@ static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
unsigned char *in_ptr = ((unsigned char *)buf) + iPair * 3;
|
||||
TIFF_JSAMPLE *out_ptr = (TIFF_JSAMPLE *)(line16 + iPair * 2);
|
||||
|
||||
out_ptr[0] = (in_ptr[0] << 4) | ((in_ptr[1] & 0xf0) >> 4);
|
||||
out_ptr[1] = ((in_ptr[1] & 0x0f) << 8) | in_ptr[2];
|
||||
out_ptr[0] = (TIFF_JSAMPLE)((in_ptr[0] << 4) |
|
||||
((in_ptr[1] & 0xf0) >> 4));
|
||||
out_ptr[1] =
|
||||
(TIFF_JSAMPLE)(((in_ptr[1] & 0x0f) << 8) | in_ptr[2]);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2374,7 +2402,7 @@ static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1)
|
||||
return (0);
|
||||
if (nrows > 0)
|
||||
tif->tif_row++;
|
||||
tif->tif_dir.td_row++;
|
||||
buf += sp->bytesperline;
|
||||
}
|
||||
|
||||
@@ -2443,8 +2471,9 @@ static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
{
|
||||
int hsamp = compptr->h_samp_factor;
|
||||
int vsamp = compptr->v_samp_factor;
|
||||
int padding = (int)(compptr->width_in_blocks * DCTSIZE -
|
||||
clumps_per_line * hsamp);
|
||||
int padding =
|
||||
(int)(compptr->width_in_blocks * DCTSIZE -
|
||||
(JDIMENSION)clumps_per_line * (JDIMENSION)hsamp);
|
||||
for (ypos = 0; ypos < vsamp; ypos++)
|
||||
{
|
||||
inptr = ((TIFF_JSAMPLE *)buf) + clumpoffset;
|
||||
@@ -2488,7 +2517,7 @@ static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
}
|
||||
sp->scancount = 0;
|
||||
}
|
||||
tif->tif_row += sp->v_sampling;
|
||||
tif->tif_dir.td_row += sp->v_sampling;
|
||||
buf += bytesperclumpline;
|
||||
nrows -= sp->v_sampling;
|
||||
}
|
||||
@@ -2582,10 +2611,11 @@ static void JPEGResetUpsampled(TIFF *tif)
|
||||
* Must recalculate cached tile size in case sampling state changed.
|
||||
* Should we really be doing this now if image size isn't set?
|
||||
*/
|
||||
if (tif->tif_tilesize > 0)
|
||||
tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);
|
||||
if (tif->tif_scanlinesize > 0)
|
||||
tif->tif_scanlinesize = TIFFScanlineSize(tif);
|
||||
if (tif->tif_dir.td_tilesize > 0)
|
||||
tif->tif_dir.td_tilesize =
|
||||
isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);
|
||||
if (tif->tif_dir.td_scanlinesize > 0)
|
||||
tif->tif_dir.td_scanlinesize = TIFFScanlineSize(tif);
|
||||
}
|
||||
|
||||
static int JPEGVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
@@ -2793,6 +2823,33 @@ static int JPEGInitializeLibJPEG(TIFF *tif, int decompress)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint64_t JPEGGetMaxCompressionRatio(TIFF *tif)
|
||||
{
|
||||
/* See README_for_libtiff_developpers.md for raw data used to estimate
|
||||
* the maximum compression rate. */
|
||||
|
||||
const JPEGState *sp = JState(tif);
|
||||
if ((tif->tif_dir.td_photometric == PHOTOMETRIC_YCBCR) &&
|
||||
(tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) &&
|
||||
(tif->tif_dir.td_samplesperpixel == 3))
|
||||
{
|
||||
if (sp->h_sampling == 2 && sp->v_sampling == 2)
|
||||
{
|
||||
if (tif->tif_dir.td_bitspersample == 12)
|
||||
return 768;
|
||||
else
|
||||
return 512;
|
||||
}
|
||||
|
||||
return 0; /* unknown */
|
||||
}
|
||||
|
||||
if (tif->tif_dir.td_bitspersample == 12)
|
||||
return 384;
|
||||
else
|
||||
return 256;
|
||||
}
|
||||
|
||||
/* Common to tif_jpeg.c and tif_jpeg_12.c */
|
||||
static void TIFFInitJPEGCommon(TIFF *tif)
|
||||
{
|
||||
@@ -2829,6 +2886,7 @@ static void TIFFInitJPEGCommon(TIFF *tif)
|
||||
tif->tif_encoderow = JPEGEncode;
|
||||
tif->tif_encodestrip = JPEGEncode;
|
||||
tif->tif_encodetile = JPEGEncode;
|
||||
tif->tif_getmaxcompressionratio = JPEGGetMaxCompressionRatio;
|
||||
tif->tif_cleanup = JPEGCleanup;
|
||||
|
||||
tif->tif_defstripsize = JPEGDefaultStripSize;
|
||||
|
||||
148
3rdparty/libtiff/tif_lerc.c
vendored
148
3rdparty/libtiff/tif_lerc.c
vendored
@@ -33,6 +33,7 @@
|
||||
|
||||
#include "Lerc_c_api.h"
|
||||
#include "zlib.h"
|
||||
#include <math.h>
|
||||
#ifdef ZSTD_SUPPORT
|
||||
#include "zstd.h"
|
||||
#endif
|
||||
@@ -188,7 +189,7 @@ static int SetupBuffers(TIFF *tif, LERCState *sp, const char *module)
|
||||
else
|
||||
{
|
||||
sp->segment_width = td->td_imagewidth;
|
||||
sp->segment_height = td->td_imagelength - tif->tif_row;
|
||||
sp->segment_height = td->td_imagelength - tif->tif_dir.td_row;
|
||||
if (sp->segment_height > td->td_rowsperstrip)
|
||||
sp->segment_height = td->td_rowsperstrip;
|
||||
}
|
||||
@@ -242,7 +243,7 @@ static int SetupBuffers(TIFF *tif, LERCState *sp, const char *module)
|
||||
}
|
||||
|
||||
if ((td->td_planarconfig == PLANARCONFIG_CONTIG &&
|
||||
td->td_extrasamples > 0 &&
|
||||
td->td_extrasamples > 0 && td->td_sampleinfo &&
|
||||
td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
|
||||
GetLercDataType(tif) == 1) ||
|
||||
(td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
|
||||
@@ -343,7 +344,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
||||
if (res != LIBDEFLATE_SUCCESS)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Decoding error at scanline %lu",
|
||||
(unsigned long)tif->tif_row);
|
||||
(unsigned long)tif->tif_dir.td_row);
|
||||
return 0;
|
||||
}
|
||||
assert(lerc_data_sizet == (unsigned int)lerc_data_sizet);
|
||||
@@ -387,7 +388,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
||||
size_t zstd_ret;
|
||||
|
||||
zstd_ret = ZSTD_decompress(sp->compressed_buffer, sp->compressed_size,
|
||||
tif->tif_rawcp, tif->tif_rawcc);
|
||||
tif->tif_rawcp, (size_t)tif->tif_rawcc);
|
||||
if (ZSTD_isError(zstd_ret))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Error in ZSTD_decompress(): %s",
|
||||
@@ -420,6 +421,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
||||
/* LERC info has dim == samplesperpixel - 1, then there is a LERC */
|
||||
/* mask. */
|
||||
if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 &&
|
||||
td->td_sampleinfo &&
|
||||
td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
|
||||
GetLercDataType(tif) == 1 &&
|
||||
infoArray[2] == td->td_samplesperpixel - 1U)
|
||||
@@ -432,7 +434,8 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
||||
use_mask = 1;
|
||||
}
|
||||
|
||||
ndims = td->td_planarconfig == PLANARCONFIG_CONTIG ? nomask_bands : 1;
|
||||
ndims =
|
||||
(int)(td->td_planarconfig == PLANARCONFIG_CONTIG ? nomask_bands : 1);
|
||||
|
||||
/* Info returned in infoArray is { version, dataType, nDim/nDepth, nCols,
|
||||
nRows, nBands, nValidPixels, blobSize,
|
||||
@@ -440,12 +443,12 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
||||
if (infoArray[0] != (unsigned)sp->lerc_version)
|
||||
{
|
||||
TIFFWarningExtR(tif, module,
|
||||
"Unexpected version number: %d. Expected: %d",
|
||||
"Unexpected version number: %u. Expected: %d",
|
||||
infoArray[0], sp->lerc_version);
|
||||
}
|
||||
if (infoArray[1] != (unsigned)lerc_data_type)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Unexpected dataType: %d. Expected: %d",
|
||||
TIFFErrorExtR(tif, module, "Unexpected dataType: %u. Expected: %d",
|
||||
infoArray[1], lerc_data_type);
|
||||
return 0;
|
||||
}
|
||||
@@ -458,7 +461,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
if (nFoundDims != 1 && nFoundDims != (unsigned)ndims)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Unexpected nDim: %d. Expected: 1 or %d",
|
||||
TIFFErrorExtR(tif, module, "Unexpected nDim: %u. Expected: 1 or %d",
|
||||
nFoundDims, ndims);
|
||||
return 0;
|
||||
}
|
||||
@@ -467,20 +470,20 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
||||
#endif
|
||||
if (nFoundDims != (unsigned)ndims)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Unexpected nDim: %d. Expected: %d",
|
||||
TIFFErrorExtR(tif, module, "Unexpected nDim: %u. Expected: %d",
|
||||
nFoundDims, ndims);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (infoArray[3] != sp->segment_width)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Unexpected nCols: %d. Expected: %du",
|
||||
TIFFErrorExtR(tif, module, "Unexpected nCols: %u. Expected: %u",
|
||||
infoArray[3], sp->segment_width);
|
||||
return 0;
|
||||
}
|
||||
if (infoArray[4] != sp->segment_height)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Unexpected nRows: %d. Expected: %u",
|
||||
TIFFErrorExtR(tif, module, "Unexpected nRows: %u. Expected: %u",
|
||||
infoArray[4], sp->segment_height);
|
||||
return 0;
|
||||
}
|
||||
@@ -504,28 +507,28 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
||||
#endif
|
||||
if (nFoundBands != td->td_samplesperpixel)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Unexpected nBands: %d. Expected: %d",
|
||||
TIFFErrorExtR(tif, module, "Unexpected nBands: %u. Expected: %d",
|
||||
nFoundBands, td->td_samplesperpixel);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (nFoundBands != 1)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Unexpected nBands: %d. Expected: %d",
|
||||
TIFFErrorExtR(tif, module, "Unexpected nBands: %u. Expected: %d",
|
||||
nFoundBands, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (infoArray[7] != lerc_data_size)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Unexpected blobSize: %d. Expected: %u",
|
||||
TIFFErrorExtR(tif, module, "Unexpected blobSize: %u. Expected: %u",
|
||||
infoArray[7], lerc_data_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nRequestedMasks = use_mask ? 1 : 0;
|
||||
#if LERC_AT_LEAST_VERSION(3, 0, 0)
|
||||
const int nFoundMasks = infoArray[8];
|
||||
const int nFoundMasks = (int)infoArray[8];
|
||||
if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
|
||||
td->td_planarconfig == PLANARCONFIG_CONTIG &&
|
||||
td->td_samplesperpixel > 1 && nFoundDims == 1)
|
||||
@@ -576,21 +579,22 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
||||
sp->uncompressed_buffer_multiband_alloc = num_bytes_needed;
|
||||
}
|
||||
lerc_ret = lerc_decode(lerc_data, lerc_data_size, nRequestedMasks,
|
||||
sp->mask_buffer, nFoundDims, sp->segment_width,
|
||||
sp->segment_height, nFoundBands, lerc_data_type,
|
||||
sp->mask_buffer, (int)nFoundDims,
|
||||
(int)sp->segment_width, (int)sp->segment_height,
|
||||
(int)nFoundBands, (unsigned int)lerc_data_type,
|
||||
sp->uncompressed_buffer_multiband);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
lerc_ret =
|
||||
lerc_decode(lerc_data, lerc_data_size,
|
||||
lerc_ret = lerc_decode(
|
||||
lerc_data, lerc_data_size,
|
||||
#if LERC_AT_LEAST_VERSION(3, 0, 0)
|
||||
nRequestedMasks,
|
||||
nRequestedMasks,
|
||||
#endif
|
||||
use_mask ? sp->mask_buffer : NULL, nFoundDims,
|
||||
sp->segment_width, sp->segment_height, nFoundBands,
|
||||
lerc_data_type, sp->uncompressed_buffer);
|
||||
use_mask ? sp->mask_buffer : NULL, (int)nFoundDims,
|
||||
(int)sp->segment_width, (int)sp->segment_height, (int)nFoundBands,
|
||||
(unsigned int)lerc_data_type, sp->uncompressed_buffer);
|
||||
}
|
||||
if (lerc_ret != 0)
|
||||
{
|
||||
@@ -601,17 +605,17 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
||||
/* Interleave alpha mask with other samples. */
|
||||
if (use_mask && GetLercDataType(tif) == 1)
|
||||
{
|
||||
unsigned src_stride =
|
||||
(td->td_samplesperpixel - 1) * (td->td_bitspersample / 8);
|
||||
unsigned src_stride = (unsigned int)((td->td_samplesperpixel - 1) *
|
||||
(td->td_bitspersample / 8));
|
||||
unsigned dst_stride =
|
||||
td->td_samplesperpixel * (td->td_bitspersample / 8);
|
||||
(unsigned int)(td->td_samplesperpixel * (td->td_bitspersample / 8));
|
||||
unsigned i = sp->segment_width * sp->segment_height;
|
||||
/* Operate from end to begin to be able to move in place */
|
||||
while (i > 0 && i > nomask_bands)
|
||||
{
|
||||
i--;
|
||||
sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel -
|
||||
1] = 255 * sp->mask_buffer[i];
|
||||
1] = (uint8_t)(255 * sp->mask_buffer[i]);
|
||||
memcpy(sp->uncompressed_buffer + i * dst_stride,
|
||||
sp->uncompressed_buffer + i * src_stride, src_stride);
|
||||
}
|
||||
@@ -620,7 +624,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
i--;
|
||||
sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel -
|
||||
1] = 255 * sp->mask_buffer[i];
|
||||
1] = (uint8_t)(255 * sp->mask_buffer[i]);
|
||||
memmove(sp->uncompressed_buffer + i * dst_stride,
|
||||
sp->uncompressed_buffer + i * src_stride, src_stride);
|
||||
}
|
||||
@@ -649,7 +653,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
||||
}
|
||||
else
|
||||
{
|
||||
const double nan_float64 = nan_float32;
|
||||
const double nan_float64 = (double)nan_float32;
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
if (sp->mask_buffer[i] == 0)
|
||||
@@ -677,7 +681,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
||||
}
|
||||
else
|
||||
{
|
||||
const double nan_float64 = nan_float32;
|
||||
const double nan_float64 = (double)nan_float32;
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
for (int j = 0; j < td->td_samplesperpixel; j++)
|
||||
@@ -704,30 +708,32 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
|
||||
{
|
||||
for (int j = 0; j < td->td_samplesperpixel; j++)
|
||||
{
|
||||
if (sp->mask_buffer[i + j * nb_pixels] == 0)
|
||||
if (sp->mask_buffer[i + (unsigned int)j * nb_pixels] ==
|
||||
0)
|
||||
((float *)sp->uncompressed_buffer)[k] = nan_float32;
|
||||
else
|
||||
((float *)sp->uncompressed_buffer)[k] =
|
||||
((float *)sp->uncompressed_buffer_multiband)
|
||||
[i + j * nb_pixels];
|
||||
[i + (unsigned int)j * nb_pixels];
|
||||
++k;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const double nan_float64 = nan_float32;
|
||||
const double nan_float64 = (double)nan_float32;
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
for (int j = 0; j < td->td_samplesperpixel; j++)
|
||||
{
|
||||
if (sp->mask_buffer[i + j * nb_pixels] == 0)
|
||||
if (sp->mask_buffer[i + (unsigned int)j * nb_pixels] ==
|
||||
0)
|
||||
((double *)sp->uncompressed_buffer)[k] =
|
||||
nan_float64;
|
||||
else
|
||||
((double *)sp->uncompressed_buffer)[k] =
|
||||
((double *)sp->uncompressed_buffer_multiband)
|
||||
[i + j * nb_pixels];
|
||||
[i + (unsigned int)j * nb_pixels];
|
||||
++k;
|
||||
}
|
||||
}
|
||||
@@ -766,8 +772,8 @@ static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(op, sp->uncompressed_buffer + sp->uncompressed_offset, occ);
|
||||
sp->uncompressed_offset += (unsigned)occ;
|
||||
memcpy(op, sp->uncompressed_buffer + sp->uncompressed_offset, (size_t)occ);
|
||||
sp->uncompressed_offset += (unsigned int)occ;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -832,8 +838,8 @@ static int LERCEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(sp->uncompressed_buffer + sp->uncompressed_offset, bp, cc);
|
||||
sp->uncompressed_offset += (unsigned)cc;
|
||||
memcpy(sp->uncompressed_buffer + sp->uncompressed_offset, bp, (size_t)cc);
|
||||
sp->uncompressed_offset += (unsigned int)cc;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -863,13 +869,15 @@ static int LERCPostEncode(TIFF *tif)
|
||||
/* Extract alpha mask (if containing only 0 and 255 values, */
|
||||
/* and compact array of regular bands */
|
||||
if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 &&
|
||||
td->td_sampleinfo &&
|
||||
td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
|
||||
GetLercDataType(tif) == 1)
|
||||
{
|
||||
const unsigned dst_stride =
|
||||
(td->td_samplesperpixel - 1) * (td->td_bitspersample / 8);
|
||||
(unsigned int)((td->td_samplesperpixel - 1) *
|
||||
(td->td_bitspersample / 8));
|
||||
const unsigned src_stride =
|
||||
td->td_samplesperpixel * (td->td_bitspersample / 8);
|
||||
(unsigned int)(td->td_samplesperpixel * (td->td_bitspersample / 8));
|
||||
unsigned i = 0;
|
||||
|
||||
use_mask = 1;
|
||||
@@ -923,7 +931,7 @@ static int LERCPostEncode(TIFF *tif)
|
||||
{
|
||||
const float val = ((float *)sp->uncompressed_buffer)[k];
|
||||
++k;
|
||||
if (val != val)
|
||||
if (isnan(val))
|
||||
{
|
||||
++count_nan;
|
||||
}
|
||||
@@ -944,7 +952,7 @@ static int LERCPostEncode(TIFF *tif)
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
const float val = ((float *)sp->uncompressed_buffer)[i];
|
||||
if (val != val)
|
||||
if (isnan(val))
|
||||
{
|
||||
use_mask = 1;
|
||||
break;
|
||||
@@ -965,7 +973,7 @@ static int LERCPostEncode(TIFF *tif)
|
||||
const double val =
|
||||
((double *)sp->uncompressed_buffer)[k];
|
||||
++k;
|
||||
if (val != val)
|
||||
if (isnan(val))
|
||||
{
|
||||
++count_nan;
|
||||
}
|
||||
@@ -986,7 +994,7 @@ static int LERCPostEncode(TIFF *tif)
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
const double val = ((double *)sp->uncompressed_buffer)[i];
|
||||
if (val != val)
|
||||
if (isnan(val))
|
||||
{
|
||||
use_mask = 1;
|
||||
break;
|
||||
@@ -1025,10 +1033,10 @@ static int LERCPostEncode(TIFF *tif)
|
||||
const float val =
|
||||
((float *)sp->uncompressed_buffer)[k];
|
||||
((float *)sp->uncompressed_buffer_multiband)
|
||||
[i + j * nb_pixels] = val;
|
||||
[i + (unsigned int)j * nb_pixels] = val;
|
||||
++k;
|
||||
sp->mask_buffer[i + j * nb_pixels] =
|
||||
(val == val) ? 255 : 0;
|
||||
sp->mask_buffer[i + (unsigned int)j * nb_pixels] =
|
||||
!isnan(val) ? 255 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1041,10 +1049,10 @@ static int LERCPostEncode(TIFF *tif)
|
||||
const double val =
|
||||
((double *)sp->uncompressed_buffer)[k];
|
||||
((double *)sp->uncompressed_buffer_multiband)
|
||||
[i + j * nb_pixels] = val;
|
||||
[i + (unsigned int)j * nb_pixels] = val;
|
||||
++k;
|
||||
sp->mask_buffer[i + j * nb_pixels] =
|
||||
(val == val) ? 255 : 0;
|
||||
sp->mask_buffer[i + (unsigned int)j * nb_pixels] =
|
||||
!isnan(val) ? 255 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1064,7 +1072,7 @@ static int LERCPostEncode(TIFF *tif)
|
||||
{
|
||||
const float val =
|
||||
((float *)sp->uncompressed_buffer)[i * dst_nbands];
|
||||
sp->mask_buffer[i] = (val == val) ? 255 : 0;
|
||||
sp->mask_buffer[i] = !isnan(val) ? 255 : 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1073,7 +1081,7 @@ static int LERCPostEncode(TIFF *tif)
|
||||
{
|
||||
const double val =
|
||||
((double *)sp->uncompressed_buffer)[i * dst_nbands];
|
||||
sp->mask_buffer[i] = (val == val) ? 255 : 0;
|
||||
sp->mask_buffer[i] = !isnan(val) ? 255 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1084,7 +1092,7 @@ static int LERCPostEncode(TIFF *tif)
|
||||
for (i = 0; i < nb_pixels; i++)
|
||||
{
|
||||
const float val = ((float *)sp->uncompressed_buffer)[i];
|
||||
sp->mask_buffer[i] = (val == val) ? 255 : 0;
|
||||
sp->mask_buffer[i] = !isnan(val) ? 255 : 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1093,7 +1101,7 @@ static int LERCPostEncode(TIFF *tif)
|
||||
{
|
||||
const double val =
|
||||
((double *)sp->uncompressed_buffer)[i];
|
||||
sp->mask_buffer[i] = (val == val) ? 255 : 0;
|
||||
sp->mask_buffer[i] = !isnan(val) ? 255 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1104,7 +1112,8 @@ static int LERCPostEncode(TIFF *tif)
|
||||
#if LERC_AT_LEAST_VERSION(3, 0, 0)
|
||||
if (mask_count > 1)
|
||||
{
|
||||
estimated_compressed_size += nb_pixels * mask_count / 8;
|
||||
estimated_compressed_size +=
|
||||
(unsigned int)(nb_pixels * (unsigned int)mask_count / 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1125,8 +1134,9 @@ static int LERCPostEncode(TIFF *tif)
|
||||
{
|
||||
lerc_ret = lerc_encodeForVersion(
|
||||
sp->uncompressed_buffer_multiband, sp->lerc_version,
|
||||
GetLercDataType(tif), 1, sp->segment_width, sp->segment_height,
|
||||
dst_nbands, dst_nbands, sp->mask_buffer, sp->maxzerror,
|
||||
(unsigned int)GetLercDataType(tif), 1, (int)sp->segment_width,
|
||||
(int)sp->segment_height, (int)dst_nbands, (int)dst_nbands,
|
||||
sp->mask_buffer, sp->maxzerror,
|
||||
(unsigned char *)sp->compressed_buffer, sp->compressed_size,
|
||||
&numBytesWritten);
|
||||
}
|
||||
@@ -1134,9 +1144,10 @@ static int LERCPostEncode(TIFF *tif)
|
||||
#endif
|
||||
{
|
||||
lerc_ret = lerc_encodeForVersion(
|
||||
sp->uncompressed_buffer, sp->lerc_version, GetLercDataType(tif),
|
||||
td->td_planarconfig == PLANARCONFIG_CONTIG ? dst_nbands : 1,
|
||||
sp->segment_width, sp->segment_height, 1,
|
||||
sp->uncompressed_buffer, sp->lerc_version,
|
||||
(unsigned int)GetLercDataType(tif),
|
||||
(int)(td->td_planarconfig == PLANARCONFIG_CONTIG ? dst_nbands : 1),
|
||||
(int)sp->segment_width, (int)sp->segment_height, 1,
|
||||
#if LERC_AT_LEAST_VERSION(3, 0, 0)
|
||||
use_mask ? 1 : 0,
|
||||
#endif
|
||||
@@ -1179,14 +1190,14 @@ static int LERCPostEncode(TIFF *tif)
|
||||
return 0;
|
||||
}
|
||||
|
||||
tif->tif_rawcc = libdeflate_zlib_compress(
|
||||
tif->tif_rawcc = (tmsize_t)libdeflate_zlib_compress(
|
||||
sp->libdeflate_enc, sp->compressed_buffer, numBytesWritten,
|
||||
sp->uncompressed_buffer, sp->uncompressed_alloc);
|
||||
|
||||
if (tif->tif_rawcc == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Encoder error at scanline %lu",
|
||||
(unsigned long)tif->tif_row);
|
||||
(unsigned long)tif->tif_dir.td_row);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
@@ -1252,7 +1263,7 @@ static int LERCPostEncode(TIFF *tif)
|
||||
int ret;
|
||||
uint8_t *tif_rawdata_backup = tif->tif_rawdata;
|
||||
tif->tif_rawdata = sp->uncompressed_buffer;
|
||||
tif->tif_rawcc = zstd_ret;
|
||||
tif->tif_rawcc = (tmsize_t)zstd_ret;
|
||||
ret = TIFFFlushData1(tif);
|
||||
tif->tif_rawdata = tif_rawdata_backup;
|
||||
if (!ret)
|
||||
@@ -1350,7 +1361,7 @@ static int LERCVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
{
|
||||
case TIFFTAG_LERC_PARAMETERS:
|
||||
{
|
||||
uint32_t count = va_arg(ap, int);
|
||||
uint32_t count = (uint32_t)va_arg(ap, int);
|
||||
int *params = va_arg(ap, int *);
|
||||
if (count < 2)
|
||||
{
|
||||
@@ -1529,6 +1540,13 @@ int TIFFInitLERC(TIFF *tif, int scheme)
|
||||
#endif
|
||||
tif->tif_cleanup = LERCCleanup;
|
||||
|
||||
/* LERC compression ratio can grow to several millions */
|
||||
/* eg. 5703725 for Lerc deflate on 16383x16383 array */
|
||||
/* or 3829644 for regular Lerc */
|
||||
/* See README_for_libtiff_developpers.md for raw data used to estimate
|
||||
* the maximum compression rate. */
|
||||
/* so we don't define tif->tif_getmaxcompressionratio */
|
||||
|
||||
/* Default values for codec-specific fields */
|
||||
TIFFSetField(tif, TIFFTAG_LERC_VERSION, LERC_VERSION_2_4);
|
||||
TIFFSetField(tif, TIFFTAG_LERC_ADD_COMPRESSION, LERC_ADD_COMPRESSION_NONE);
|
||||
|
||||
165
3rdparty/libtiff/tif_luv.c
vendored
165
3rdparty/libtiff/tif_luv.c
vendored
@@ -212,7 +212,7 @@ static int LogL16Decode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
}
|
||||
tp = (int16_t *)sp->tbuf;
|
||||
}
|
||||
_TIFFmemset((void *)tp, 0, npixels * sizeof(tp[0]));
|
||||
_TIFFmemset((void *)tp, 0, (tmsize_t)((size_t)npixels * sizeof(tp[0])));
|
||||
|
||||
bp = (unsigned char *)tif->tif_rawcp;
|
||||
cc = tif->tif_rawcc;
|
||||
@@ -235,7 +235,7 @@ static int LogL16Decode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
{ /* non-run */
|
||||
rc = *bp++; /* nul is noop */
|
||||
while (--cc && rc-- && i < npixels)
|
||||
tp[i++] |= (int16_t)*bp++ << shft;
|
||||
tp[i++] |= (int16_t)(*bp++ << shft);
|
||||
}
|
||||
}
|
||||
if (i != npixels)
|
||||
@@ -243,7 +243,7 @@ static int LogL16Decode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Not enough data at row %" PRIu32
|
||||
" (short %" TIFF_SSIZE_FORMAT " pixels)",
|
||||
tif->tif_row, npixels - i);
|
||||
tif->tif_dir.td_row, npixels - i);
|
||||
tif->tif_rawcp = (uint8_t *)bp;
|
||||
tif->tif_rawcc = cc;
|
||||
return (0);
|
||||
@@ -290,7 +290,7 @@ static int LogLuvDecode24(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
cc = tif->tif_rawcc;
|
||||
for (i = 0; i < npixels && cc >= 3; i++)
|
||||
{
|
||||
tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2];
|
||||
tp[i] = (uint32_t)bp[0] << 16 | (uint32_t)bp[1] << 8 | bp[2];
|
||||
bp += 3;
|
||||
cc -= 3;
|
||||
}
|
||||
@@ -301,7 +301,7 @@ static int LogLuvDecode24(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Not enough data at row %" PRIu32
|
||||
" (short %" TIFF_SSIZE_FORMAT " pixels)",
|
||||
tif->tif_row, npixels - i);
|
||||
tif->tif_dir.td_row, npixels - i);
|
||||
return (0);
|
||||
}
|
||||
(*sp->tfunc)(sp, op, npixels);
|
||||
@@ -342,7 +342,7 @@ static int LogLuvDecode32(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
}
|
||||
tp = (uint32_t *)sp->tbuf;
|
||||
}
|
||||
_TIFFmemset((void *)tp, 0, npixels * sizeof(tp[0]));
|
||||
_TIFFmemset((void *)tp, 0, (tmsize_t)((size_t)npixels * sizeof(tp[0])));
|
||||
|
||||
bp = (unsigned char *)tif->tif_rawcp;
|
||||
cc = tif->tif_rawcc;
|
||||
@@ -373,7 +373,7 @@ static int LogLuvDecode32(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Not enough data at row %" PRIu32
|
||||
" (short %" TIFF_SSIZE_FORMAT " pixels)",
|
||||
tif->tif_row, npixels - i);
|
||||
tif->tif_dir.td_row, npixels - i);
|
||||
tif->tif_rawcp = (uint8_t *)bp;
|
||||
tif->tif_rawcc = cc;
|
||||
return (0);
|
||||
@@ -767,25 +767,21 @@ static int LogLuvEncodeTile(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
#undef log2 /* Conflict with C'99 function */
|
||||
#define log2(x) ((1. / M_LN2) * log(x))
|
||||
#undef exp2 /* Conflict with C'99 function */
|
||||
#define exp2(x) exp(M_LN2 *(x))
|
||||
|
||||
#define TIFF_RAND_MAX 32767
|
||||
|
||||
// From POSIX.1-2001 as an example of an implementation of rand()
|
||||
static uint32_t _TIFFRand()
|
||||
static uint32_t _TIFFRand(void)
|
||||
{
|
||||
static uint32_t nCounter = 0;
|
||||
if (!nCounter)
|
||||
nCounter = (uint32_t)(time(NULL) & UINT32_MAX);
|
||||
++nCounter;
|
||||
uint32_t nCounterLocal =
|
||||
(uint32_t)(((uint64_t)(nCounter)*1103515245U + 12345U) & UINT32_MAX);
|
||||
(uint32_t)(((uint64_t)(nCounter) * 1103515245U + 12345U) & UINT32_MAX);
|
||||
nCounter = nCounterLocal;
|
||||
return (nCounterLocal / 65536U) % (TIFF_RAND_MAX + 1);
|
||||
};
|
||||
}
|
||||
|
||||
static int tiff_itrunc(double x, int m)
|
||||
{
|
||||
@@ -797,8 +793,7 @@ static int tiff_itrunc(double x, int m)
|
||||
#if !LOGLUV_PUBLIC
|
||||
static
|
||||
#endif
|
||||
double
|
||||
LogL16toY(int p16) /* compute luminance from 16-bit LogL */
|
||||
double LogL16toY(int p16) /* compute luminance from 16-bit LogL */
|
||||
{
|
||||
int Le = p16 & 0x7fff;
|
||||
double Y;
|
||||
@@ -812,8 +807,7 @@ static
|
||||
#if !LOGLUV_PUBLIC
|
||||
static
|
||||
#endif
|
||||
int
|
||||
LogL16fromY(double Y, int em) /* get 16-bit LogL from Y */
|
||||
int LogL16fromY(double Y, int em) /* get 16-bit LogL from Y */
|
||||
{
|
||||
if (Y >= 1.8371976e19)
|
||||
return (0x7fff);
|
||||
@@ -855,20 +849,22 @@ static void L16fromY(LogLuvState *sp, uint8_t *op, tmsize_t n)
|
||||
float *yp = (float *)op;
|
||||
|
||||
while (n-- > 0)
|
||||
*l16++ = (int16_t)(LogL16fromY(*yp++, sp->encode_meth));
|
||||
*l16++ = (int16_t)(LogL16fromY((double)*yp++, sp->encode_meth));
|
||||
}
|
||||
|
||||
#if !LOGLUV_PUBLIC
|
||||
static
|
||||
#endif
|
||||
void
|
||||
XYZtoRGB24(float *xyz, uint8_t *rgb)
|
||||
void XYZtoRGB24(float *xyz, uint8_t *rgb)
|
||||
{
|
||||
double r, g, b;
|
||||
/* assume CCIR-709 primaries */
|
||||
r = 2.690 * xyz[0] + -1.276 * xyz[1] + -0.414 * xyz[2];
|
||||
g = -1.022 * xyz[0] + 1.978 * xyz[1] + 0.044 * xyz[2];
|
||||
b = 0.061 * xyz[0] + -0.224 * xyz[1] + 1.163 * xyz[2];
|
||||
r = 2.690 * (double)xyz[0] + -1.276 * (double)xyz[1] +
|
||||
-0.414 * (double)xyz[2];
|
||||
g = -1.022 * (double)xyz[0] + 1.978 * (double)xyz[1] +
|
||||
0.044 * (double)xyz[2];
|
||||
b = 0.061 * (double)xyz[0] + -0.224 * (double)xyz[1] +
|
||||
1.163 * (double)xyz[2];
|
||||
/* assume 2.0 gamma for speed */
|
||||
/* could use integer sqrt approx., but this is probably faster */
|
||||
rgb[0] = (uint8_t)((r <= 0.) ? 0 : (r >= 1.) ? 255 : (int)(256. * sqrt(r)));
|
||||
@@ -879,8 +875,7 @@ static
|
||||
#if !LOGLUV_PUBLIC
|
||||
static
|
||||
#endif
|
||||
double
|
||||
LogL10toY(int p10) /* compute luminance from 10-bit LogL */
|
||||
double LogL10toY(int p10) /* compute luminance from 10-bit LogL */
|
||||
{
|
||||
if (p10 == 0)
|
||||
return (0.);
|
||||
@@ -890,8 +885,7 @@ static
|
||||
#if !LOGLUV_PUBLIC
|
||||
static
|
||||
#endif
|
||||
int
|
||||
LogL10fromY(double Y, int em) /* get 10-bit LogL from Y */
|
||||
int LogL10fromY(double Y, int em) /* get 10-bit LogL from Y */
|
||||
{
|
||||
if (Y >= 15.742)
|
||||
return (0x3ff);
|
||||
@@ -903,13 +897,14 @@ static
|
||||
|
||||
#define NANGLES 100
|
||||
#define uv2ang(u, v) \
|
||||
((NANGLES * .499999999 / M_PI) * atan2((v)-V_NEU, (u)-U_NEU) + .5 * NANGLES)
|
||||
((NANGLES * .499999999 / M_PI) * atan2((v) - V_NEU, (u) - U_NEU) + \
|
||||
.5 * NANGLES)
|
||||
|
||||
static int oog_encode(double u, double v) /* encode out-of-gamut chroma */
|
||||
{
|
||||
static int oog_table[NANGLES];
|
||||
static int initialized = 0;
|
||||
register int i;
|
||||
int i;
|
||||
|
||||
if (!initialized)
|
||||
{ /* set up perimeter table */
|
||||
@@ -919,13 +914,14 @@ static int oog_encode(double u, double v) /* encode out-of-gamut chroma */
|
||||
eps[i] = 2.;
|
||||
for (vi = UV_NVS; vi--;)
|
||||
{
|
||||
va = UV_VSTART + (vi + .5) * UV_SQSIZ;
|
||||
va = (double)UV_VSTART + ((double)vi + .5) * (double)UV_SQSIZ;
|
||||
ustep = uv_row[vi].nus - 1;
|
||||
if (vi == UV_NVS - 1 || vi == 0 || ustep <= 0)
|
||||
ustep = 1;
|
||||
for (ui = uv_row[vi].nus - 1; ui >= 0; ui -= ustep)
|
||||
{
|
||||
ua = uv_row[vi].ustart + (ui + .5) * UV_SQSIZ;
|
||||
ua = (double)uv_row[vi].ustart +
|
||||
((double)ui + .5) * (double)UV_SQSIZ;
|
||||
ang = uv2ang(ua, va);
|
||||
i = (int)ang;
|
||||
epsa = fabs(ang - (i + .5));
|
||||
@@ -963,27 +959,28 @@ static int oog_encode(double u, double v) /* encode out-of-gamut chroma */
|
||||
#if !LOGLUV_PUBLIC
|
||||
static
|
||||
#endif
|
||||
int
|
||||
uv_encode(double u, double v, int em) /* encode (u',v') coordinates */
|
||||
int uv_encode(double u, double v, int em) /* encode (u',v') coordinates */
|
||||
{
|
||||
unsigned int vi;
|
||||
int ui;
|
||||
|
||||
/* check for NaN */
|
||||
if (u != u || v != v)
|
||||
if (isnan(u) || isnan(v))
|
||||
{
|
||||
u = U_NEU;
|
||||
v = V_NEU;
|
||||
}
|
||||
|
||||
if (v < UV_VSTART)
|
||||
if ((double)v < (double)UV_VSTART)
|
||||
return oog_encode(u, v);
|
||||
vi = tiff_itrunc((v - UV_VSTART) * (1. / UV_SQSIZ), em);
|
||||
vi = (unsigned int)tiff_itrunc(
|
||||
((double)v - (double)UV_VSTART) * (1. / (double)UV_SQSIZ), em);
|
||||
if (vi >= UV_NVS)
|
||||
return oog_encode(u, v);
|
||||
if (u < uv_row[vi].ustart)
|
||||
if ((double)u < (double)uv_row[vi].ustart)
|
||||
return oog_encode(u, v);
|
||||
ui = tiff_itrunc((u - uv_row[vi].ustart) * (1. / UV_SQSIZ), em);
|
||||
ui = tiff_itrunc(
|
||||
((double)u - (double)uv_row[vi].ustart) * (1. / (double)UV_SQSIZ), em);
|
||||
if (ui >= uv_row[vi].nus)
|
||||
return oog_encode(u, v);
|
||||
|
||||
@@ -993,8 +990,7 @@ static
|
||||
#if !LOGLUV_PUBLIC
|
||||
static
|
||||
#endif
|
||||
int
|
||||
uv_decode(double *up, double *vp, int c) /* decode (u',v') index */
|
||||
int uv_decode(double *up, double *vp, int c) /* decode (u',v') index */
|
||||
{
|
||||
unsigned int upper, lower;
|
||||
int ui;
|
||||
@@ -1020,16 +1016,15 @@ static
|
||||
}
|
||||
vi = lower;
|
||||
ui = c - uv_row[vi].ncum;
|
||||
*up = uv_row[vi].ustart + (ui + .5) * UV_SQSIZ;
|
||||
*vp = UV_VSTART + (vi + .5) * UV_SQSIZ;
|
||||
*up = (double)uv_row[vi].ustart + ((double)ui + .5) * (double)UV_SQSIZ;
|
||||
*vp = (double)UV_VSTART + ((double)vi + .5) * (double)UV_SQSIZ;
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if !LOGLUV_PUBLIC
|
||||
static
|
||||
#endif
|
||||
void
|
||||
LogLuv24toXYZ(uint32_t p, float *XYZ)
|
||||
void LogLuv24toXYZ(uint32_t p, float *XYZ)
|
||||
{
|
||||
int Ce;
|
||||
double L, u, v, s, x, y;
|
||||
@@ -1059,15 +1054,14 @@ static
|
||||
#if !LOGLUV_PUBLIC
|
||||
static
|
||||
#endif
|
||||
uint32_t
|
||||
LogLuv24fromXYZ(float *XYZ, int em)
|
||||
uint32_t LogLuv24fromXYZ(float *XYZ, int em)
|
||||
{
|
||||
int Le, Ce;
|
||||
double u, v, s;
|
||||
/* encode luminance */
|
||||
Le = LogL10fromY(XYZ[1], em);
|
||||
Le = LogL10fromY((double)XYZ[1], em);
|
||||
/* encode color */
|
||||
s = XYZ[0] + 15. * XYZ[1] + 3. * XYZ[2];
|
||||
s = (double)XYZ[0] + 15. * (double)XYZ[1] + 3. * (double)XYZ[2];
|
||||
if (!Le || s <= 0.)
|
||||
{
|
||||
u = U_NEU;
|
||||
@@ -1075,14 +1069,14 @@ static
|
||||
}
|
||||
else
|
||||
{
|
||||
u = 4. * XYZ[0] / s;
|
||||
v = 9. * XYZ[1] / s;
|
||||
u = 4. * (double)XYZ[0] / s;
|
||||
v = 9. * (double)XYZ[1] / s;
|
||||
}
|
||||
Ce = uv_encode(u, v, em);
|
||||
if (Ce < 0) /* never happens */
|
||||
Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER);
|
||||
/* combine encodings */
|
||||
return (Le << 14 | Ce);
|
||||
return (uint32_t)Le << 14 | (uint32_t)Ce;
|
||||
}
|
||||
|
||||
static void Luv24toXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n)
|
||||
@@ -1113,8 +1107,8 @@ static void Luv24toLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n)
|
||||
u = U_NEU;
|
||||
v = V_NEU;
|
||||
}
|
||||
*luv3++ = (int16_t)(u * (1L << 15));
|
||||
*luv3++ = (int16_t)(v * (1L << 15));
|
||||
*luv3++ = (int16_t)(u * (1 << 15));
|
||||
*luv3++ = (int16_t)(v * (1 << 15));
|
||||
luv++;
|
||||
}
|
||||
}
|
||||
@@ -1168,7 +1162,7 @@ static void Luv24fromLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n)
|
||||
sp->encode_meth);
|
||||
if (Ce < 0) /* never happens */
|
||||
Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER);
|
||||
*luv++ = (uint32_t)Le << 14 | Ce;
|
||||
*luv++ = (uint32_t)Le << 14 | (uint32_t)Ce;
|
||||
luv3 += 3;
|
||||
}
|
||||
}
|
||||
@@ -1176,8 +1170,7 @@ static void Luv24fromLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n)
|
||||
#if !LOGLUV_PUBLIC
|
||||
static
|
||||
#endif
|
||||
void
|
||||
LogLuv32toXYZ(uint32_t p, float *XYZ)
|
||||
void LogLuv32toXYZ(uint32_t p, float *XYZ)
|
||||
{
|
||||
double L, u, v, s, x, y;
|
||||
/* decode luminance */
|
||||
@@ -1202,15 +1195,14 @@ static
|
||||
#if !LOGLUV_PUBLIC
|
||||
static
|
||||
#endif
|
||||
uint32_t
|
||||
LogLuv32fromXYZ(float *XYZ, int em)
|
||||
uint32_t LogLuv32fromXYZ(float *XYZ, int em)
|
||||
{
|
||||
unsigned int Le, ue, ve;
|
||||
double u, v, s;
|
||||
/* encode luminance */
|
||||
Le = (unsigned int)LogL16fromY(XYZ[1], em);
|
||||
Le = (unsigned int)LogL16fromY((double)XYZ[1], em);
|
||||
/* encode color */
|
||||
s = XYZ[0] + 15. * XYZ[1] + 3. * XYZ[2];
|
||||
s = (double)XYZ[0] + 15. * (double)XYZ[1] + 3. * (double)XYZ[2];
|
||||
if (!Le || s <= 0.)
|
||||
{
|
||||
u = U_NEU;
|
||||
@@ -1218,19 +1210,19 @@ static
|
||||
}
|
||||
else
|
||||
{
|
||||
u = 4. * XYZ[0] / s;
|
||||
v = 9. * XYZ[1] / s;
|
||||
u = 4. * (double)XYZ[0] / s;
|
||||
v = 9. * (double)XYZ[1] / s;
|
||||
}
|
||||
if (u <= 0.)
|
||||
ue = 0;
|
||||
else
|
||||
ue = tiff_itrunc(UVSCALE * u, em);
|
||||
ue = (unsigned int)tiff_itrunc(UVSCALE * u, em);
|
||||
if (ue > 255)
|
||||
ue = 255;
|
||||
if (v <= 0.)
|
||||
ve = 0;
|
||||
else
|
||||
ve = tiff_itrunc(UVSCALE * v, em);
|
||||
ve = (unsigned int)tiff_itrunc(UVSCALE * v, em);
|
||||
if (ve > 255)
|
||||
ve = 255;
|
||||
/* combine encodings */
|
||||
@@ -1261,8 +1253,8 @@ static void Luv32toLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n)
|
||||
*luv3++ = (int16_t)(*luv >> 16);
|
||||
u = 1. / UVSCALE * ((*luv >> 8 & 0xff) + .5);
|
||||
v = 1. / UVSCALE * ((*luv & 0xff) + .5);
|
||||
*luv3++ = (int16_t)(u * (1L << 15));
|
||||
*luv3++ = (int16_t)(v * (1L << 15));
|
||||
*luv3++ = (int16_t)(u * (1 << 15));
|
||||
*luv3++ = (int16_t)(v * (1 << 15));
|
||||
luv++;
|
||||
}
|
||||
}
|
||||
@@ -1303,22 +1295,24 @@ static void Luv32fromLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n)
|
||||
{
|
||||
while (n-- > 0)
|
||||
{
|
||||
*luv++ = (uint32_t)luv3[0] << 16 |
|
||||
(luv3[1] * (uint32_t)(UVSCALE + .5) >> 7 & 0xff00) |
|
||||
(luv3[2] * (uint32_t)(UVSCALE + .5) >> 15 & 0xff);
|
||||
*luv++ =
|
||||
(uint32_t)luv3[0] << 16 |
|
||||
((uint32_t)luv3[1] * (uint32_t)(UVSCALE + .5) >> 7 & 0xff00) |
|
||||
((uint32_t)luv3[2] * (uint32_t)(UVSCALE + .5) >> 15 & 0xff);
|
||||
luv3 += 3;
|
||||
}
|
||||
return;
|
||||
}
|
||||
while (n-- > 0)
|
||||
{
|
||||
*luv++ =
|
||||
(uint32_t)luv3[0] << 16 |
|
||||
(tiff_itrunc(luv3[1] * (UVSCALE / (1 << 15)), sp->encode_meth)
|
||||
<< 8 &
|
||||
0xff00) |
|
||||
(tiff_itrunc(luv3[2] * (UVSCALE / (1 << 15)), sp->encode_meth) &
|
||||
0xff);
|
||||
*luv++ = (uint32_t)luv3[0] << 16 |
|
||||
((uint32_t)tiff_itrunc(luv3[1] * (UVSCALE / (1 << 15)),
|
||||
sp->encode_meth)
|
||||
<< 8 &
|
||||
0xff00) |
|
||||
((uint32_t)tiff_itrunc(luv3[2] * (UVSCALE / (1 << 15)),
|
||||
sp->encode_meth) &
|
||||
0xff);
|
||||
luv3 += 3;
|
||||
}
|
||||
}
|
||||
@@ -1345,6 +1339,8 @@ static int LogL16GuessDataFmt(TIFFDirectory *td)
|
||||
case PACK(1, 8, SAMPLEFORMAT_VOID):
|
||||
case PACK(1, 8, SAMPLEFORMAT_UINT):
|
||||
return (SGILOGDATAFMT_8BIT);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#undef PACK
|
||||
return (SGILOGDATAFMT_UNKNOWN);
|
||||
@@ -1399,7 +1395,7 @@ static int LogL16InitState(TIFF *tif)
|
||||
sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength);
|
||||
if (multiply_ms(sp->tbuflen, sizeof(int16_t)) == 0 ||
|
||||
(sp->tbuf = (uint8_t *)_TIFFmallocExt(
|
||||
tif, sp->tbuflen * sizeof(int16_t))) == NULL)
|
||||
tif, (tmsize_t)((size_t)sp->tbuflen * sizeof(int16_t)))) == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "No space for SGILog translation buffer");
|
||||
return (0);
|
||||
@@ -1506,7 +1502,7 @@ static int LogLuvInitState(TIFF *tif)
|
||||
sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength);
|
||||
if (multiply_ms(sp->tbuflen, sizeof(uint32_t)) == 0 ||
|
||||
(sp->tbuf = (uint8_t *)_TIFFmallocExt(
|
||||
tif, sp->tbuflen * sizeof(uint32_t))) == NULL)
|
||||
tif, (tmsize_t)((size_t)sp->tbuflen * sizeof(uint32_t)))) == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "No space for SGILog translation buffer");
|
||||
return (0);
|
||||
@@ -1546,6 +1542,8 @@ static int LogLuvSetupDecode(TIFF *tif)
|
||||
case SGILOGDATAFMT_8BIT:
|
||||
sp->tfunc = Luv24toRGB;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1562,6 +1560,8 @@ static int LogLuvSetupDecode(TIFF *tif)
|
||||
case SGILOGDATAFMT_8BIT:
|
||||
sp->tfunc = Luv32toRGB;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (1);
|
||||
@@ -1577,6 +1577,8 @@ static int LogLuvSetupDecode(TIFF *tif)
|
||||
case SGILOGDATAFMT_8BIT:
|
||||
sp->tfunc = L16toGry;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (1);
|
||||
default:
|
||||
@@ -1755,8 +1757,9 @@ static int LogLuvVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
/*
|
||||
* Must recalculate sizes should bits/sample change.
|
||||
*/
|
||||
tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)-1;
|
||||
tif->tif_scanlinesize = TIFFScanlineSize(tif);
|
||||
tif->tif_dir.td_tilesize =
|
||||
isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)-1;
|
||||
tif->tif_dir.td_scanlinesize = TIFFScanlineSize(tif);
|
||||
return (1);
|
||||
case TIFFTAG_SGILOGENCODE:
|
||||
sp->encode_meth = (int)va_arg(ap, int);
|
||||
|
||||
65
3rdparty/libtiff/tif_lzma.c
vendored
65
3rdparty/libtiff/tif_lzma.c
vendored
@@ -95,6 +95,17 @@ static const char *LZMAStrerror(lzma_ret ret)
|
||||
return "no progress is possible (stream is truncated or corrupt)";
|
||||
case LZMA_PROG_ERROR:
|
||||
return "programming error";
|
||||
#if LZMA_VERSION >= 50040000 /* 5.4.0 */
|
||||
case LZMA_SEEK_NEEDED:
|
||||
case LZMA_RET_INTERNAL1:
|
||||
case LZMA_RET_INTERNAL2:
|
||||
case LZMA_RET_INTERNAL3:
|
||||
case LZMA_RET_INTERNAL4:
|
||||
case LZMA_RET_INTERNAL5:
|
||||
case LZMA_RET_INTERNAL6:
|
||||
case LZMA_RET_INTERNAL7:
|
||||
case LZMA_RET_INTERNAL8:
|
||||
#endif
|
||||
default:
|
||||
return "unidentified liblzma error";
|
||||
}
|
||||
@@ -179,7 +190,7 @@ static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
TIFFErrorExtR(tif, module,
|
||||
"LZMADecode: Scanline %" PRIu32 " cannot be read due to "
|
||||
"previous error",
|
||||
tif->tif_row);
|
||||
tif->tif_dir.td_row);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -231,7 +242,7 @@ static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Decoding error at scanline %" PRIu32 ", %s",
|
||||
tif->tif_row, LZMAStrerror(ret));
|
||||
tif->tif_dir.td_row, LZMAStrerror(ret));
|
||||
break;
|
||||
}
|
||||
} while (sp->stream.avail_out > 0);
|
||||
@@ -242,12 +253,12 @@ static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Not enough data at scanline %" PRIu32
|
||||
" (short %" TIFF_SIZE_FORMAT " bytes)",
|
||||
tif->tif_row, sp->stream.avail_out);
|
||||
tif->tif_dir.td_row, sp->stream.avail_out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tif->tif_rawcp = (uint8_t *)sp->stream.next_in; /* cast away const */
|
||||
tif->tif_rawcc = sp->stream.avail_in;
|
||||
tif->tif_rawcc = (tmsize_t)sp->stream.avail_in;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -326,7 +337,7 @@ static int LZMAEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Encoding error at scanline %" PRIu32 ", %s",
|
||||
tif->tif_row, LZMAStrerror(ret));
|
||||
tif->tif_dir.td_row, LZMAStrerror(ret));
|
||||
return 0;
|
||||
}
|
||||
if (sp->stream.avail_out == 0)
|
||||
@@ -365,7 +376,7 @@ static int LZMAPostEncode(TIFF *tif)
|
||||
if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
|
||||
{
|
||||
tif->tif_rawcc =
|
||||
tif->tif_rawdatasize - sp->stream.avail_out;
|
||||
tif->tif_rawdatasize - (tmsize_t)sp->stream.avail_out;
|
||||
if (!TIFFFlushData1(tif))
|
||||
return 0;
|
||||
sp->stream.next_out = tif->tif_rawdata;
|
||||
@@ -376,6 +387,27 @@ static int LZMAPostEncode(TIFF *tif)
|
||||
ZIPPreEncode */
|
||||
}
|
||||
break;
|
||||
case LZMA_NO_CHECK:
|
||||
case LZMA_UNSUPPORTED_CHECK:
|
||||
case LZMA_GET_CHECK:
|
||||
case LZMA_MEM_ERROR:
|
||||
case LZMA_MEMLIMIT_ERROR:
|
||||
case LZMA_FORMAT_ERROR:
|
||||
case LZMA_OPTIONS_ERROR:
|
||||
case LZMA_DATA_ERROR:
|
||||
case LZMA_BUF_ERROR:
|
||||
case LZMA_PROG_ERROR:
|
||||
#if LZMA_VERSION >= 50040000 /* 5.4.0 */
|
||||
case LZMA_SEEK_NEEDED:
|
||||
case LZMA_RET_INTERNAL1:
|
||||
case LZMA_RET_INTERNAL2:
|
||||
case LZMA_RET_INTERNAL3:
|
||||
case LZMA_RET_INTERNAL4:
|
||||
case LZMA_RET_INTERNAL5:
|
||||
case LZMA_RET_INTERNAL6:
|
||||
case LZMA_RET_INTERNAL7:
|
||||
case LZMA_RET_INTERNAL8:
|
||||
#endif
|
||||
default:
|
||||
TIFFErrorExtR(tif, module, "Liblzma error: %s",
|
||||
LZMAStrerror(ret));
|
||||
@@ -416,7 +448,7 @@ static int LZMAVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
{
|
||||
case TIFFTAG_LZMAPRESET:
|
||||
sp->preset = (int)va_arg(ap, int);
|
||||
lzma_lzma_preset(&sp->opt_lzma, sp->preset);
|
||||
lzma_lzma_preset(&sp->opt_lzma, (uint32_t)sp->preset);
|
||||
if (sp->state & LSTATE_INIT_ENCODE)
|
||||
{
|
||||
lzma_ret ret =
|
||||
@@ -454,6 +486,21 @@ static const TIFFField lzmaFields[] = {
|
||||
FALSE, "LZMA2 Compression Preset", NULL},
|
||||
};
|
||||
|
||||
static uint64_t LZMAGetMaxCompressionRatio(TIFF *tif)
|
||||
{
|
||||
(void)tif;
|
||||
|
||||
/* See README_for_libtiff_developpers.md for raw data used to estimate
|
||||
* the maximum compression rate. */
|
||||
|
||||
/* 1024x1024: 3800 */
|
||||
/* 4096x4096: 6534 */
|
||||
/* 16383x16383: 6846 */
|
||||
/* 65536x65536: 6874 */
|
||||
|
||||
return 7000;
|
||||
}
|
||||
|
||||
int TIFFInitLZMA(TIFF *tif, int scheme)
|
||||
{
|
||||
static const char module[] = "TIFFInitLZMA";
|
||||
@@ -506,7 +553,7 @@ int TIFFInitLZMA(TIFF *tif, int scheme)
|
||||
sp->filters[0].id = LZMA_FILTER_DELTA;
|
||||
sp->filters[0].options = &sp->opt_delta;
|
||||
|
||||
lzma_lzma_preset(&sp->opt_lzma, sp->preset);
|
||||
lzma_lzma_preset(&sp->opt_lzma, (uint32_t)sp->preset);
|
||||
sp->filters[1].id = LZMA_FILTER_LZMA2;
|
||||
sp->filters[1].options = &sp->opt_lzma;
|
||||
|
||||
@@ -529,6 +576,8 @@ int TIFFInitLZMA(TIFF *tif, int scheme)
|
||||
tif->tif_encodestrip = LZMAEncode;
|
||||
tif->tif_encodetile = LZMAEncode;
|
||||
tif->tif_cleanup = LZMACleanup;
|
||||
tif->tif_getmaxcompressionratio = LZMAGetMaxCompressionRatio;
|
||||
|
||||
/*
|
||||
* Setup predictor setup.
|
||||
*/
|
||||
|
||||
82
3rdparty/libtiff/tif_lzw.c
vendored
82
3rdparty/libtiff/tif_lzw.c
vendored
@@ -60,7 +60,7 @@ typedef size_t WordType;
|
||||
*/
|
||||
#define LZW_COMPAT /* include backwards compatibility code */
|
||||
|
||||
#define MAXCODE(n) ((1L << (n)) - 1)
|
||||
#define MAXCODE(n) ((1 << (n)) - 1)
|
||||
/*
|
||||
* The TIFF spec specifies that encoded bit
|
||||
* strings range from 9 to 12 bits.
|
||||
@@ -72,7 +72,7 @@ typedef size_t WordType;
|
||||
#define CODE_EOI 257 /* end-of-information code */
|
||||
#define CODE_FIRST 258 /* first free code entry */
|
||||
#define CODE_MAX MAXCODE(BITS_MAX)
|
||||
#define HSIZE 9001L /* 91% occupancy */
|
||||
#define HSIZE 9001 /* 91% occupancy */
|
||||
#define HSHIFT (13 - 8)
|
||||
#ifdef LZW_COMPAT
|
||||
/* NB: +1024 is for compatibility with old files */
|
||||
@@ -325,7 +325,7 @@ static int LZWPreDecode(TIFF *tif, uint16_t s)
|
||||
*/
|
||||
|
||||
/* Get the next 32 or 64-bit from the input data */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#if WORDS_BIGENDIAN
|
||||
#define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata))
|
||||
#elif SIZEOF_WORDTYPE == 8
|
||||
#if defined(_M_X64)
|
||||
@@ -372,7 +372,7 @@ static int LZWPreDecode(TIFF *tif, uint16_t s)
|
||||
nextbits += 8 * SIZEOF_WORDTYPE; \
|
||||
dec_bitsleft -= 8 * SIZEOF_WORDTYPE; \
|
||||
code = (WordType)((codetmp | (nextdata >> nextbits)) & \
|
||||
nbitsmask); \
|
||||
(WordType)nbitsmask); \
|
||||
break; \
|
||||
} \
|
||||
else \
|
||||
@@ -396,7 +396,7 @@ static int LZWPreDecode(TIFF *tif, uint16_t s)
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
code = (WordType)((nextdata >> nextbits) & nbitsmask); \
|
||||
code = (WordType)((nextdata >> nextbits) & (WordType)nbitsmask); \
|
||||
} while (0)
|
||||
|
||||
static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
|
||||
@@ -420,7 +420,7 @@ static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
|
||||
TIFFErrorExtR(tif, module,
|
||||
"LZWDecode: Scanline %" PRIu32 " cannot be read due to "
|
||||
"previous error",
|
||||
tif->tif_row);
|
||||
tif->tif_dir.td_row);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -472,7 +472,8 @@ static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
|
||||
}
|
||||
|
||||
bp = (uint8_t *)tif->tif_rawcp;
|
||||
sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3);
|
||||
sp->dec_bitsleft +=
|
||||
(((uint64_t)tif->tif_rawcc - (uint64_t)sp->old_tif_rawcc) << 3);
|
||||
uint64_t dec_bitsleft = sp->dec_bitsleft;
|
||||
nbits = sp->lzw_nbits;
|
||||
nextdata = sp->lzw_nextdata;
|
||||
@@ -493,7 +494,7 @@ begin:
|
||||
{
|
||||
WordType code;
|
||||
GetNextCodeLZW();
|
||||
codep = dec_codetab + code;
|
||||
codep = dec_codetab + (unsigned long)code;
|
||||
if (code >= CODE_FIRST)
|
||||
goto code_above_or_equal_to_258;
|
||||
if (code < 256)
|
||||
@@ -508,7 +509,7 @@ code_below_256:
|
||||
goto error_code;
|
||||
free_entp->next = oldcodep;
|
||||
free_entp->firstchar = oldcodep->firstchar;
|
||||
free_entp->length = oldcodep->length + 1;
|
||||
free_entp->length = (uint16_t)(oldcodep->length + 1);
|
||||
free_entp->value = (uint8_t)code;
|
||||
free_entp->repeated =
|
||||
(bool)(oldcodep->repeated & (oldcodep->value == code));
|
||||
@@ -556,7 +557,7 @@ code_above_or_equal_to_258:
|
||||
free_entp->next = oldcodep;
|
||||
|
||||
free_entp->firstchar = oldcodep->firstchar;
|
||||
free_entp->length = oldcodep->length + 1;
|
||||
free_entp->length = (uint16_t)(oldcodep->length + 1);
|
||||
if (++free_entp > maxcodep)
|
||||
{
|
||||
if (++nbits > BITS_MAX) /* should not happen for a conformant encoder */
|
||||
@@ -673,7 +674,7 @@ code_clear:
|
||||
free_entp = dec_codetab + CODE_FIRST;
|
||||
nbits = BITS_MIN;
|
||||
nbitsmask = MAXCODE(BITS_MIN);
|
||||
maxcodep = dec_codetab + nbitsmask - 1;
|
||||
maxcodep = dec_codetab + (unsigned long)nbitsmask - 1;
|
||||
do
|
||||
{
|
||||
GetNextCodeLZW();
|
||||
@@ -736,7 +737,7 @@ after_loop:
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Not enough data at scanline %" PRIu32 " (short %" PRIu64
|
||||
" bytes)",
|
||||
tif->tif_row, (uint64_t)occ);
|
||||
tif->tif_dir.td_row, (uint64_t)occ);
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
@@ -746,7 +747,7 @@ no_eoi:
|
||||
sp->read_error = 1;
|
||||
TIFFErrorExtR(tif, module,
|
||||
"LZWDecode: Strip %" PRIu32 " not terminated with EOI code",
|
||||
tif->tif_curstrip);
|
||||
tif->tif_dir.td_curstrip);
|
||||
return 0;
|
||||
error_code:
|
||||
memset(op, 0, (size_t)occ);
|
||||
@@ -768,13 +769,13 @@ error_code:
|
||||
TIFFWarningExtR(_tif, module, \
|
||||
"LZWDecode: Strip %" PRIu32 \
|
||||
" not terminated with EOI code", \
|
||||
_tif->tif_curstrip); \
|
||||
_tif->tif_dir.td_curstrip); \
|
||||
_code = CODE_EOI; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_get(_sp, _bp, _code); \
|
||||
dec_bitsleft -= nbits; \
|
||||
dec_bitsleft -= (uint64_t)nbits; \
|
||||
} \
|
||||
}
|
||||
|
||||
@@ -790,7 +791,7 @@ error_code:
|
||||
nextdata |= (unsigned long)*(bp)++ << nextbits; \
|
||||
nextbits += 8; \
|
||||
} \
|
||||
code = (hcode_t)(nextdata & nbitsmask); \
|
||||
code = (hcode_t)(nextdata & (unsigned long)nbitsmask); \
|
||||
nextdata >>= nbits; \
|
||||
nextbits -= nbits; \
|
||||
}
|
||||
@@ -858,7 +859,8 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
|
||||
|
||||
bp = (uint8_t *)tif->tif_rawcp;
|
||||
|
||||
sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3);
|
||||
sp->dec_bitsleft +=
|
||||
(((uint64_t)tif->tif_rawcc - (uint64_t)sp->old_tif_rawcc) << 3);
|
||||
uint64_t dec_bitsleft = sp->dec_bitsleft;
|
||||
|
||||
nbits = sp->lzw_nbits;
|
||||
@@ -893,7 +895,7 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
|
||||
TIFFErrorExtR(
|
||||
tif, tif->tif_name,
|
||||
"LZWDecode: Corrupted LZW table at scanline %" PRIu32,
|
||||
tif->tif_row);
|
||||
tif->tif_dir.td_row);
|
||||
return (0);
|
||||
}
|
||||
*op++ = (uint8_t)code;
|
||||
@@ -911,7 +913,7 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Corrupted LZW table at scanline %" PRIu32,
|
||||
tif->tif_row);
|
||||
tif->tif_dir.td_row);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -921,11 +923,11 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Corrupted LZW table at scanline %" PRIu32,
|
||||
tif->tif_row);
|
||||
tif->tif_dir.td_row);
|
||||
return (0);
|
||||
}
|
||||
free_entp->firstchar = free_entp->next->firstchar;
|
||||
free_entp->length = free_entp->next->length + 1;
|
||||
free_entp->length = (uint16_t)(free_entp->next->length + 1);
|
||||
free_entp->value =
|
||||
(codep < free_entp) ? codep->firstchar : free_entp->firstchar;
|
||||
if (++free_entp > maxcodep)
|
||||
@@ -948,7 +950,7 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
|
||||
tif, module,
|
||||
"Wrong length of decoded "
|
||||
"string: data probably corrupted at scanline %" PRIu32,
|
||||
tif->tif_row);
|
||||
tif->tif_dir.td_row);
|
||||
return (0);
|
||||
}
|
||||
if (codep->length > occ)
|
||||
@@ -1010,7 +1012,7 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Not enough data at scanline %" PRIu32 " (short %" PRIu64
|
||||
" bytes)",
|
||||
tif->tif_row, (uint64_t)occ);
|
||||
tif->tif_dir.td_row, (uint64_t)occ);
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
@@ -1116,10 +1118,10 @@ static int LZWPreEncode(TIFF *tif, uint16_t s)
|
||||
*/
|
||||
static int LZWEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
{
|
||||
register LZWCodecState *sp = LZWEncoderState(tif);
|
||||
register long fcode;
|
||||
register hash_t *hp;
|
||||
register int h, c;
|
||||
LZWCodecState *sp = LZWEncoderState(tif);
|
||||
long fcode;
|
||||
hash_t *hp;
|
||||
int h, c;
|
||||
hcode_t ent;
|
||||
long disp;
|
||||
tmsize_t incount, outcount, checkpoint;
|
||||
@@ -1196,7 +1198,7 @@ static int LZWEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
* Avoid pointer arithmetic because of
|
||||
* wraparound problems with segments.
|
||||
*/
|
||||
if ((h -= disp) < 0)
|
||||
if ((h -= (int)disp) < 0)
|
||||
h += HSIZE;
|
||||
hp = &sp->enc_hashtab[h];
|
||||
if (hp->hash == fcode)
|
||||
@@ -1301,7 +1303,7 @@ static int LZWEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
*/
|
||||
static int LZWPostEncode(TIFF *tif)
|
||||
{
|
||||
register LZWCodecState *sp = LZWEncoderState(tif);
|
||||
LZWCodecState *sp = LZWEncoderState(tif);
|
||||
uint8_t *op = tif->tif_rawcp;
|
||||
long nextbits = sp->lzw_nextbits;
|
||||
WordType nextdata = sp->lzw_nextdata;
|
||||
@@ -1319,7 +1321,7 @@ static int LZWPostEncode(TIFF *tif)
|
||||
{
|
||||
int free_ent = sp->lzw_free_ent;
|
||||
|
||||
PutNextCode(op, sp->enc_oldcode);
|
||||
PutNextCode(op, (WordType)sp->enc_oldcode);
|
||||
sp->enc_oldcode = (hcode_t)-1;
|
||||
free_ent++;
|
||||
|
||||
@@ -1357,8 +1359,8 @@ static int LZWPostEncode(TIFF *tif)
|
||||
*/
|
||||
static void cl_hash(LZWCodecState *sp)
|
||||
{
|
||||
register hash_t *hp = &sp->enc_hashtab[HSIZE - 1];
|
||||
register long i = HSIZE - 8;
|
||||
hash_t *hp = &sp->enc_hashtab[HSIZE - 1];
|
||||
long i = HSIZE - 8;
|
||||
|
||||
do
|
||||
{
|
||||
@@ -1397,6 +1399,21 @@ static void LZWCleanup(TIFF *tif)
|
||||
_TIFFSetDefaultCompressionState(tif);
|
||||
}
|
||||
|
||||
static uint64_t LZWGetMaxCompressionRatio(TIFF *tif)
|
||||
{
|
||||
(void)tif;
|
||||
|
||||
/* See README_for_libtiff_developpers.md for raw data used to estimate
|
||||
* the maximum compression rate. */
|
||||
|
||||
/* 1024x1024: 562 */
|
||||
/* 4096x4096: 1243 */
|
||||
/* 16383x16383: 1353 */
|
||||
/* 65536x65536: 1362 */
|
||||
|
||||
return 1400;
|
||||
}
|
||||
|
||||
int TIFFInitLZW(TIFF *tif, int scheme)
|
||||
{
|
||||
static const char module[] = "TIFFInitLZW";
|
||||
@@ -1430,6 +1447,7 @@ int TIFFInitLZW(TIFF *tif, int scheme)
|
||||
tif->tif_encodestrip = LZWEncode;
|
||||
tif->tif_encodetile = LZWEncode;
|
||||
#endif
|
||||
tif->tif_getmaxcompressionratio = LZWGetMaxCompressionRatio;
|
||||
tif->tif_cleanup = LZWCleanup;
|
||||
/*
|
||||
* Setup predictor setup.
|
||||
|
||||
15
3rdparty/libtiff/tif_next.c
vendored
15
3rdparty/libtiff/tif_next.c
vendored
@@ -38,21 +38,22 @@
|
||||
op[0] = (unsigned char)((v) << 6); \
|
||||
break; \
|
||||
case 1: \
|
||||
op[0] |= (v) << 4; \
|
||||
op[0] |= (unsigned char)((v) << 4); \
|
||||
break; \
|
||||
case 2: \
|
||||
op[0] |= (v) << 2; \
|
||||
op[0] |= (unsigned char)((v) << 2); \
|
||||
break; \
|
||||
case 3: \
|
||||
*op++ |= (v); \
|
||||
*op++ |= (unsigned char)(v); \
|
||||
op_offset++; \
|
||||
break; \
|
||||
default: \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define LITERALROW 0x00
|
||||
#define LITERALSPAN 0x40
|
||||
#define WHITE ((1 << 2) - 1)
|
||||
|
||||
static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
||||
{
|
||||
@@ -73,7 +74,7 @@ static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
||||
|
||||
bp = (unsigned char *)tif->tif_rawcp;
|
||||
cc = tif->tif_rawcc;
|
||||
scanline = tif->tif_scanlinesize;
|
||||
scanline = tif->tif_dir.td_scanlinesize;
|
||||
if (occ % scanline)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
|
||||
@@ -146,7 +147,7 @@ static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Invalid data for scanline %" PRIu32,
|
||||
tif->tif_row);
|
||||
tif->tif_dir.td_row);
|
||||
return (0);
|
||||
}
|
||||
if (cc == 0)
|
||||
@@ -163,7 +164,7 @@ static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
||||
return (1);
|
||||
bad:
|
||||
TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32,
|
||||
tif->tif_row);
|
||||
tif->tif_dir.td_row);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
302
3rdparty/libtiff/tif_ojpeg.c
vendored
302
3rdparty/libtiff/tif_ojpeg.c
vendored
@@ -122,9 +122,6 @@
|
||||
restarting of LibJpeg decoding session.
|
||||
*/
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define VC_EXTRALEAN
|
||||
|
||||
#include "tiffiop.h"
|
||||
#ifdef OJPEG_SUPPORT
|
||||
|
||||
@@ -209,18 +206,12 @@ static const TIFFField ojpegFields[] = {
|
||||
#include "jerror.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
#ifndef TIFF_jpeg_source_mgr_defined
|
||||
#define TIFF_jpeg_source_mgr_defined
|
||||
typedef struct jpeg_source_mgr jpeg_source_mgr;
|
||||
#endif
|
||||
typedef struct jpeg_source_mgr tiff_ojpeg_source_mgr;
|
||||
|
||||
#ifndef TIFF_jpeg_error_mgr_defined
|
||||
#define TIFF_jpeg_error_mgr_defined
|
||||
typedef struct jpeg_error_mgr jpeg_error_mgr;
|
||||
#endif
|
||||
typedef struct jpeg_error_mgr tiff_ojpeg_error_mgr;
|
||||
|
||||
typedef struct jpeg_common_struct jpeg_common_struct;
|
||||
typedef struct jpeg_decompress_struct jpeg_decompress_struct;
|
||||
typedef struct jpeg_common_struct tiff_ojpeg_common_struct;
|
||||
typedef struct jpeg_decompress_struct tiff_ojpeg_decompress_struct;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -316,9 +307,9 @@ typedef struct
|
||||
uint32_t write_curstrile;
|
||||
uint8_t libjpeg_session_active;
|
||||
uint8_t libjpeg_jpeg_query_style;
|
||||
jpeg_error_mgr libjpeg_jpeg_error_mgr;
|
||||
jpeg_decompress_struct libjpeg_jpeg_decompress_struct;
|
||||
jpeg_source_mgr libjpeg_jpeg_source_mgr;
|
||||
tiff_ojpeg_error_mgr libjpeg_jpeg_error_mgr;
|
||||
tiff_ojpeg_decompress_struct libjpeg_jpeg_decompress_struct;
|
||||
tiff_ojpeg_source_mgr libjpeg_jpeg_source_mgr;
|
||||
uint8_t subsampling_convert_log;
|
||||
uint32_t subsampling_convert_ylinelen;
|
||||
uint32_t subsampling_convert_ylines;
|
||||
@@ -413,46 +404,51 @@ static void OJPEGWriteStreamEoi(TIFF *tif, void **mem, uint32_t *len);
|
||||
|
||||
#ifdef LIBJPEG_ENCAP_EXTERNAL
|
||||
extern int jpeg_create_decompress_encap(OJPEGState *sp,
|
||||
jpeg_decompress_struct *cinfo);
|
||||
extern int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo,
|
||||
tiff_ojpeg_decompress_struct *cinfo);
|
||||
extern int jpeg_read_header_encap(OJPEGState *sp,
|
||||
tiff_ojpeg_decompress_struct *cinfo,
|
||||
uint8_t require_image);
|
||||
extern int jpeg_start_decompress_encap(OJPEGState *sp,
|
||||
jpeg_decompress_struct *cinfo);
|
||||
tiff_ojpeg_decompress_struct *cinfo);
|
||||
extern int jpeg_read_scanlines_encap(OJPEGState *sp,
|
||||
jpeg_decompress_struct *cinfo,
|
||||
tiff_ojpeg_decompress_struct *cinfo,
|
||||
void *scanlines, uint32_t max_lines);
|
||||
extern int jpeg_read_raw_data_encap(OJPEGState *sp,
|
||||
jpeg_decompress_struct *cinfo, void *data,
|
||||
uint32_t max_lines);
|
||||
tiff_ojpeg_decompress_struct *cinfo,
|
||||
void *data, uint32_t max_lines);
|
||||
extern void jpeg_encap_unwind(TIFF *tif);
|
||||
#else
|
||||
static int jpeg_create_decompress_encap(OJPEGState *sp,
|
||||
jpeg_decompress_struct *j);
|
||||
static int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo,
|
||||
tiff_ojpeg_decompress_struct *j);
|
||||
static int jpeg_read_header_encap(OJPEGState *sp,
|
||||
tiff_ojpeg_decompress_struct *cinfo,
|
||||
uint8_t require_image);
|
||||
static int jpeg_start_decompress_encap(OJPEGState *sp,
|
||||
jpeg_decompress_struct *cinfo);
|
||||
tiff_ojpeg_decompress_struct *cinfo);
|
||||
static int jpeg_read_scanlines_encap(OJPEGState *sp,
|
||||
jpeg_decompress_struct *cinfo,
|
||||
tiff_ojpeg_decompress_struct *cinfo,
|
||||
void *scanlines, uint32_t max_lines);
|
||||
static int jpeg_read_raw_data_encap(OJPEGState *sp,
|
||||
jpeg_decompress_struct *cinfo, void *data,
|
||||
uint32_t max_lines);
|
||||
tiff_ojpeg_decompress_struct *cinfo,
|
||||
void *data, uint32_t max_lines);
|
||||
static void jpeg_encap_unwind(TIFF *tif);
|
||||
#endif
|
||||
|
||||
static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct *cinfo);
|
||||
static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct *cinfo);
|
||||
static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct *cinfo);
|
||||
static boolean
|
||||
OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct *cinfo);
|
||||
static void
|
||||
OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct *cinfo,
|
||||
OJPEGLibjpegJpegErrorMgrOutputMessage(tiff_ojpeg_common_struct *cinfo);
|
||||
static void OJPEGLibjpegJpegErrorMgrErrorExit(tiff_ojpeg_common_struct *cinfo);
|
||||
static void
|
||||
OJPEGLibjpegJpegSourceMgrInitSource(tiff_ojpeg_decompress_struct *cinfo);
|
||||
static boolean
|
||||
OJPEGLibjpegJpegSourceMgrFillInputBuffer(tiff_ojpeg_decompress_struct *cinfo);
|
||||
static void
|
||||
OJPEGLibjpegJpegSourceMgrSkipInputData(tiff_ojpeg_decompress_struct *cinfo,
|
||||
long num_bytes);
|
||||
static boolean
|
||||
OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct *cinfo,
|
||||
OJPEGLibjpegJpegSourceMgrResyncToRestart(tiff_ojpeg_decompress_struct *cinfo,
|
||||
int desired);
|
||||
static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct *cinfo);
|
||||
static void
|
||||
OJPEGLibjpegJpegSourceMgrTermSource(tiff_ojpeg_decompress_struct *cinfo);
|
||||
|
||||
int TIFFInitOJPEG(TIFF *tif, int scheme)
|
||||
{
|
||||
@@ -473,7 +469,7 @@ int TIFFInitOJPEG(TIFF *tif, int scheme)
|
||||
}
|
||||
|
||||
/* state block */
|
||||
sp = _TIFFmallocExt(tif, sizeof(OJPEGState));
|
||||
sp = (OJPEGState *)_TIFFmallocExt(tif, sizeof(OJPEGState));
|
||||
if (sp == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "No space for OJPEG state block");
|
||||
@@ -724,9 +720,9 @@ static int OJPEGPreDecode(TIFF *tif, uint16_t s)
|
||||
return (0);
|
||||
}
|
||||
if (isTiled(tif))
|
||||
m = tif->tif_curtile;
|
||||
m = tif->tif_dir.td_curtile;
|
||||
else
|
||||
m = tif->tif_curstrip;
|
||||
m = tif->tif_dir.td_curstrip;
|
||||
if ((sp->writeheader_done != 0) &&
|
||||
((sp->write_cursample != s) || (sp->write_curstrile > m)))
|
||||
{
|
||||
@@ -797,7 +793,7 @@ static int OJPEGPreDecodeSkipRaw(TIFF *tif)
|
||||
{
|
||||
if (jpeg_read_raw_data_encap(sp, &(sp->libjpeg_jpeg_decompress_struct),
|
||||
sp->subsampling_convert_ycbcrimage,
|
||||
sp->subsampling_ver * 8) == 0)
|
||||
(uint32_t)sp->subsampling_ver * 8) == 0)
|
||||
return (0);
|
||||
m -= sp->subsampling_convert_clines;
|
||||
}
|
||||
@@ -805,7 +801,7 @@ static int OJPEGPreDecodeSkipRaw(TIFF *tif)
|
||||
{
|
||||
if (jpeg_read_raw_data_encap(sp, &(sp->libjpeg_jpeg_decompress_struct),
|
||||
sp->subsampling_convert_ycbcrimage,
|
||||
sp->subsampling_ver * 8) == 0)
|
||||
(uint32_t)sp->subsampling_ver * 8) == 0)
|
||||
return (0);
|
||||
sp->subsampling_convert_state = m;
|
||||
}
|
||||
@@ -819,7 +815,7 @@ static int OJPEGPreDecodeSkipScanlines(TIFF *tif)
|
||||
uint32_t m;
|
||||
if (sp->skip_buffer == NULL)
|
||||
{
|
||||
sp->skip_buffer = _TIFFmallocExt(tif, sp->bytes_per_line);
|
||||
sp->skip_buffer = (uint8_t *)_TIFFmallocExt(tif, sp->bytes_per_line);
|
||||
if (sp->skip_buffer == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -910,10 +906,10 @@ static int OJPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc)
|
||||
{
|
||||
if (sp->subsampling_convert_state == 0)
|
||||
{
|
||||
if (jpeg_read_raw_data_encap(sp,
|
||||
&(sp->libjpeg_jpeg_decompress_struct),
|
||||
sp->subsampling_convert_ycbcrimage,
|
||||
sp->subsampling_ver * 8) == 0)
|
||||
if (jpeg_read_raw_data_encap(
|
||||
sp, &(sp->libjpeg_jpeg_decompress_struct),
|
||||
sp->subsampling_convert_ycbcrimage,
|
||||
(uint32_t)sp->subsampling_ver * 8) == 0)
|
||||
{
|
||||
sp->error_in_raw_data_decoding = 1;
|
||||
return (0);
|
||||
@@ -1225,7 +1221,7 @@ static int OJPEGReadHeaderInfo(TIFF *tif)
|
||||
TIFFErrorExtR(tif, module, "Invalid subsampling values");
|
||||
return (0);
|
||||
}
|
||||
if (sp->strile_length % (sp->subsampling_ver * 8) != 0)
|
||||
if (sp->strile_length % ((uint32_t)sp->subsampling_ver * 8) != 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Incompatible vertical subsampling and image "
|
||||
@@ -1233,9 +1229,11 @@ static int OJPEGReadHeaderInfo(TIFF *tif)
|
||||
return (0);
|
||||
}
|
||||
sp->restart_interval =
|
||||
(uint16_t)(((sp->strile_width + sp->subsampling_hor * 8 - 1) /
|
||||
(sp->subsampling_hor * 8)) *
|
||||
(sp->strile_length / (sp->subsampling_ver * 8)));
|
||||
(uint16_t)(((sp->strile_width + (uint32_t)sp->subsampling_hor * 8 -
|
||||
1) /
|
||||
((uint32_t)sp->subsampling_hor * 8)) *
|
||||
(sp->strile_length /
|
||||
((uint32_t)sp->subsampling_ver * 8)));
|
||||
}
|
||||
if (OJPEGReadHeaderInfoSec(tif) == 0)
|
||||
return (0);
|
||||
@@ -1358,20 +1356,43 @@ static int OJPEGWriteHeaderInfo(TIFF *tif)
|
||||
/* Check for division by zero. */
|
||||
if (sp->subsampling_hor == 0 || sp->subsampling_ver == 0)
|
||||
return (0);
|
||||
/* Check for potential overflow in subsampling_convert_ylinelen
|
||||
* computation.
|
||||
*/
|
||||
if (sp->strile_width >
|
||||
UINT32_MAX - ((uint32_t)sp->subsampling_hor * 8 - 1))
|
||||
return (0);
|
||||
sp->subsampling_convert_ylinelen =
|
||||
((sp->strile_width + sp->subsampling_hor * 8 - 1) /
|
||||
(sp->subsampling_hor * 8) * sp->subsampling_hor * 8);
|
||||
sp->subsampling_convert_ylines = sp->subsampling_ver * 8;
|
||||
((sp->strile_width + (uint32_t)sp->subsampling_hor * 8 - 1) /
|
||||
((uint32_t)sp->subsampling_hor * 8) *
|
||||
((uint32_t)sp->subsampling_hor * 8));
|
||||
sp->subsampling_convert_ylines = (uint32_t)sp->subsampling_ver * 8;
|
||||
sp->subsampling_convert_clinelen =
|
||||
sp->subsampling_convert_ylinelen / sp->subsampling_hor;
|
||||
sp->subsampling_convert_clines = 8;
|
||||
sp->subsampling_convert_ybuflen = sp->subsampling_convert_ylinelen *
|
||||
sp->subsampling_convert_ylines;
|
||||
sp->subsampling_convert_cbuflen = sp->subsampling_convert_clinelen *
|
||||
sp->subsampling_convert_clines;
|
||||
sp->subsampling_convert_ycbcrbuflen =
|
||||
sp->subsampling_convert_ybuflen +
|
||||
2 * sp->subsampling_convert_cbuflen;
|
||||
/* Check for potential overflow in buffer length computations.
|
||||
* Use 64-bit intermediates to detect uint32_t overflow in
|
||||
* ylinelen * ylines, clinelen * clines, and their sum.
|
||||
*/
|
||||
{
|
||||
uint64_t ybuflen64 =
|
||||
(uint64_t)sp->subsampling_convert_ylinelen *
|
||||
sp->subsampling_convert_ylines;
|
||||
uint64_t cbuflen64 =
|
||||
(uint64_t)sp->subsampling_convert_clinelen *
|
||||
sp->subsampling_convert_clines;
|
||||
uint64_t ycbcrbuflen64 = ybuflen64 + 2 * cbuflen64;
|
||||
if (ybuflen64 > UINT32_MAX || cbuflen64 > UINT32_MAX ||
|
||||
ycbcrbuflen64 > UINT32_MAX)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Integer overflow in OJPEG buffer size");
|
||||
return (0);
|
||||
}
|
||||
sp->subsampling_convert_ybuflen = (uint32_t)ybuflen64;
|
||||
sp->subsampling_convert_cbuflen = (uint32_t)cbuflen64;
|
||||
sp->subsampling_convert_ycbcrbuflen = (uint32_t)ycbcrbuflen64;
|
||||
}
|
||||
/* The calloc is not normally necessary, except in some edge/broken
|
||||
* cases */
|
||||
/* for example for a tiled image of height 1 with a tile height of 1
|
||||
@@ -1383,8 +1404,8 @@ static int OJPEGWriteHeaderInfo(TIFF *tif)
|
||||
/* Even if this case is allowed (?), its handling is broken because
|
||||
* OJPEGPreDecode() should also likely */
|
||||
/* reset subsampling_convert_state to 0 when changing tile. */
|
||||
sp->subsampling_convert_ycbcrbuf =
|
||||
_TIFFcallocExt(tif, 1, sp->subsampling_convert_ycbcrbuflen);
|
||||
sp->subsampling_convert_ycbcrbuf = (uint8_t *)_TIFFcallocExt(
|
||||
tif, 1, sp->subsampling_convert_ycbcrbuflen);
|
||||
if (sp->subsampling_convert_ycbcrbuf == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -1398,8 +1419,9 @@ static int OJPEGWriteHeaderInfo(TIFF *tif)
|
||||
sp->subsampling_convert_ycbcrimagelen =
|
||||
3 + sp->subsampling_convert_ylines +
|
||||
2 * sp->subsampling_convert_clines;
|
||||
sp->subsampling_convert_ycbcrimage = _TIFFmallocExt(
|
||||
tif, sp->subsampling_convert_ycbcrimagelen * sizeof(uint8_t *));
|
||||
sp->subsampling_convert_ycbcrimage = (uint8_t **)_TIFFmallocExt(
|
||||
tif, (tmsize_t)((size_t)sp->subsampling_convert_ycbcrimagelen *
|
||||
sizeof(uint8_t *)));
|
||||
if (sp->subsampling_convert_ycbcrimage == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -1426,9 +1448,14 @@ static int OJPEGWriteHeaderInfo(TIFF *tif)
|
||||
((sp->strile_width % sp->subsampling_hor) != 0 ? 1 : 0);
|
||||
sp->subsampling_convert_state = 0;
|
||||
sp->error_in_raw_data_decoding = 0;
|
||||
sp->bytes_per_line =
|
||||
sp->subsampling_convert_clinelenout *
|
||||
(sp->subsampling_ver * sp->subsampling_hor + 2);
|
||||
|
||||
const uint64_t bpl =
|
||||
(uint64_t)sp->subsampling_convert_clinelenout *
|
||||
((uint64_t)sp->subsampling_ver * sp->subsampling_hor + 2);
|
||||
if (bpl > UINT32_MAX)
|
||||
return (0);
|
||||
sp->bytes_per_line = (uint32_t)bpl;
|
||||
|
||||
sp->lines_per_strile =
|
||||
sp->strile_length / sp->subsampling_ver +
|
||||
((sp->strile_length % sp->subsampling_ver) != 0 ? 1 : 0);
|
||||
@@ -1478,7 +1505,8 @@ static void OJPEGLibjpegSessionAbort(TIFF *tif)
|
||||
{
|
||||
OJPEGState *sp = (OJPEGState *)tif->tif_data;
|
||||
assert(sp->libjpeg_session_active != 0);
|
||||
jpeg_destroy((jpeg_common_struct *)(&(sp->libjpeg_jpeg_decompress_struct)));
|
||||
jpeg_destroy(
|
||||
(tiff_ojpeg_common_struct *)(&(sp->libjpeg_jpeg_decompress_struct)));
|
||||
sp->libjpeg_session_active = 0;
|
||||
}
|
||||
|
||||
@@ -1560,7 +1588,7 @@ static int OJPEGReadHeaderInfoSec(TIFF *tif)
|
||||
return (0);
|
||||
}
|
||||
if (n > 2)
|
||||
OJPEGReadSkip(sp, n - 2);
|
||||
OJPEGReadSkip(sp, (uint16_t)(n - 2));
|
||||
break;
|
||||
case JPEG_MARKER_DRI:
|
||||
if (OJPEGReadHeaderInfoSecStreamDri(tif) == 0)
|
||||
@@ -1603,8 +1631,9 @@ static int OJPEGReadHeaderInfoSec(TIFF *tif)
|
||||
return (0);
|
||||
sp->sof_marker_id = JPEG_MARKER_SOF0;
|
||||
for (o = 0; o < sp->samples_per_pixel; o++)
|
||||
sp->sof_c[o] = o;
|
||||
sp->sof_hv[0] = ((sp->subsampling_hor << 4) | sp->subsampling_ver);
|
||||
sp->sof_c[o] = (uint8_t)o;
|
||||
sp->sof_hv[0] =
|
||||
(uint8_t)((sp->subsampling_hor << 4) | sp->subsampling_ver);
|
||||
for (o = 1; o < sp->samples_per_pixel; o++)
|
||||
sp->sof_hv[o] = 17;
|
||||
sp->sof_x = sp->strile_width;
|
||||
@@ -1659,10 +1688,10 @@ static int OJPEGReadHeaderInfoSecStreamDqt(TIFF *tif)
|
||||
return (0);
|
||||
}
|
||||
if (sp->subsamplingcorrect != 0)
|
||||
OJPEGReadSkip(sp, m - 2);
|
||||
OJPEGReadSkip(sp, (uint16_t)(m - 2));
|
||||
else
|
||||
{
|
||||
m -= 2;
|
||||
m = (uint16_t)(m - 2);
|
||||
do
|
||||
{
|
||||
if (m < 65)
|
||||
@@ -1671,7 +1700,7 @@ static int OJPEGReadHeaderInfoSecStreamDqt(TIFF *tif)
|
||||
return (0);
|
||||
}
|
||||
na = sizeof(uint32_t) + 69;
|
||||
nb = _TIFFmallocExt(tif, na);
|
||||
nb = (uint8_t *)_TIFFmallocExt(tif, na);
|
||||
if (nb == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -1697,7 +1726,7 @@ static int OJPEGReadHeaderInfoSecStreamDqt(TIFF *tif)
|
||||
if (sp->qtable[o] != 0)
|
||||
_TIFFfreeExt(tif, sp->qtable[o]);
|
||||
sp->qtable[o] = nb;
|
||||
m -= 65;
|
||||
m = (uint16_t)(m - 65);
|
||||
} while (m > 0);
|
||||
}
|
||||
return (1);
|
||||
@@ -1725,12 +1754,12 @@ static int OJPEGReadHeaderInfoSecStreamDht(TIFF *tif)
|
||||
}
|
||||
if (sp->subsamplingcorrect != 0)
|
||||
{
|
||||
OJPEGReadSkip(sp, m - 2);
|
||||
OJPEGReadSkip(sp, (uint16_t)(m - 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
na = sizeof(uint32_t) + 2 + m;
|
||||
nb = _TIFFmallocExt(tif, na);
|
||||
na = (uint32_t)(sizeof(uint32_t) + 2 + m);
|
||||
nb = (uint8_t *)_TIFFmallocExt(tif, na);
|
||||
if (nb == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -1739,9 +1768,10 @@ static int OJPEGReadHeaderInfoSecStreamDht(TIFF *tif)
|
||||
*(uint32_t *)nb = na;
|
||||
nb[sizeof(uint32_t)] = 255;
|
||||
nb[sizeof(uint32_t) + 1] = JPEG_MARKER_DHT;
|
||||
nb[sizeof(uint32_t) + 2] = (m >> 8);
|
||||
nb[sizeof(uint32_t) + 3] = (m & 255);
|
||||
if (OJPEGReadBlock(sp, m - 2, &nb[sizeof(uint32_t) + 4]) == 0)
|
||||
nb[sizeof(uint32_t) + 2] = (uint8_t)(m >> 8);
|
||||
nb[sizeof(uint32_t) + 3] = (uint8_t)(m & 255);
|
||||
if (OJPEGReadBlock(sp, (uint16_t)(m - 2), &nb[sizeof(uint32_t) + 4]) ==
|
||||
0)
|
||||
{
|
||||
_TIFFfreeExt(tif, nb);
|
||||
return (0);
|
||||
@@ -1809,7 +1839,7 @@ static int OJPEGReadHeaderInfoSecStreamSof(TIFF *tif, uint8_t marker_id)
|
||||
TIFFErrorExtR(tif, module, "Corrupt SOF marker in JPEG data");
|
||||
return (0);
|
||||
}
|
||||
m -= 8;
|
||||
m = (uint16_t)(m - 8);
|
||||
if (m % 3 != 0)
|
||||
{
|
||||
if (sp->subsamplingcorrect == 0)
|
||||
@@ -2030,7 +2060,7 @@ static int OJPEGReadHeaderInfoSecTablesQTable(TIFF *tif)
|
||||
}
|
||||
}
|
||||
oa = sizeof(uint32_t) + 69;
|
||||
ob = _TIFFmallocExt(tif, oa);
|
||||
ob = (uint8_t *)_TIFFmallocExt(tif, oa);
|
||||
if (ob == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -2098,8 +2128,8 @@ static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF *tif)
|
||||
q = 0;
|
||||
for (n = 0; n < 16; n++)
|
||||
q += o[n];
|
||||
ra = sizeof(uint32_t) + 21 + q;
|
||||
rb = _TIFFmallocExt(tif, ra);
|
||||
ra = (uint32_t)(sizeof(uint32_t) + 21 + q);
|
||||
rb = (uint8_t *)_TIFFmallocExt(tif, ra);
|
||||
if (rb == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -2122,7 +2152,7 @@ static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF *tif)
|
||||
if (sp->dctable[m] != 0)
|
||||
_TIFFfreeExt(tif, sp->dctable[m]);
|
||||
sp->dctable[m] = rb;
|
||||
sp->sos_tda[m] = (m << 4);
|
||||
sp->sos_tda[m] = (uint8_t)(m << 4);
|
||||
}
|
||||
else
|
||||
sp->sos_tda[m] = sp->sos_tda[m - 1];
|
||||
@@ -2168,8 +2198,8 @@ static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF *tif)
|
||||
q = 0;
|
||||
for (n = 0; n < 16; n++)
|
||||
q += o[n];
|
||||
ra = sizeof(uint32_t) + 21 + q;
|
||||
rb = _TIFFmallocExt(tif, ra);
|
||||
ra = (uint32_t)(sizeof(uint32_t) + 21 + q);
|
||||
rb = (uint8_t *)_TIFFmallocExt(tif, ra);
|
||||
if (rb == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Out of memory");
|
||||
@@ -2220,7 +2250,7 @@ static int OJPEGReadBufferFill(OJPEGState *sp)
|
||||
if ((uint64_t)m > sp->in_buffer_file_togo)
|
||||
m = (uint16_t)sp->in_buffer_file_togo;
|
||||
n = TIFFReadFile(sp->tif, sp->in_buffer, (tmsize_t)m);
|
||||
if (n == 0)
|
||||
if (n <= 0)
|
||||
return (0);
|
||||
assert(n > 0);
|
||||
assert(n <= OJPEG_BUFFER);
|
||||
@@ -2286,6 +2316,7 @@ static int OJPEGReadBufferFill(OJPEGState *sp)
|
||||
sp->in_buffer_next_strile++;
|
||||
}
|
||||
break;
|
||||
case osibsEof:
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
@@ -2331,7 +2362,7 @@ static int OJPEGReadWord(OJPEGState *sp, uint16_t *word)
|
||||
uint8_t m;
|
||||
if (OJPEGReadByte(sp, &m) == 0)
|
||||
return (0);
|
||||
*word = (m << 8);
|
||||
*word = (uint16_t)(m << 8);
|
||||
if (OJPEGReadByte(sp, &m) == 0)
|
||||
return (0);
|
||||
*word |= m;
|
||||
@@ -2345,7 +2376,7 @@ static int OJPEGReadBlock(OJPEGState *sp, uint16_t len, void *mem)
|
||||
uint16_t n;
|
||||
assert(len > 0);
|
||||
mlen = len;
|
||||
mmem = mem;
|
||||
mmem = (uint8_t *)mem;
|
||||
do
|
||||
{
|
||||
if (sp->in_buffer_togo == 0)
|
||||
@@ -2359,8 +2390,8 @@ static int OJPEGReadBlock(OJPEGState *sp, uint16_t len, void *mem)
|
||||
n = sp->in_buffer_togo;
|
||||
_TIFFmemcpy(mmem, sp->in_buffer_cur, n);
|
||||
sp->in_buffer_cur += n;
|
||||
sp->in_buffer_togo -= n;
|
||||
mlen -= n;
|
||||
sp->in_buffer_togo = (uint16_t)(sp->in_buffer_togo - n);
|
||||
mlen = (uint16_t)(mlen - n);
|
||||
mmem += n;
|
||||
} while (mlen > 0);
|
||||
return (1);
|
||||
@@ -2375,8 +2406,8 @@ static void OJPEGReadSkip(OJPEGState *sp, uint16_t len)
|
||||
if (n > sp->in_buffer_togo)
|
||||
n = sp->in_buffer_togo;
|
||||
sp->in_buffer_cur += n;
|
||||
sp->in_buffer_togo -= n;
|
||||
m -= n;
|
||||
sp->in_buffer_togo = (uint16_t)(sp->in_buffer_togo - n);
|
||||
m = (uint16_t)(m - n);
|
||||
if (m > 0)
|
||||
{
|
||||
assert(sp->in_buffer_togo == 0);
|
||||
@@ -2462,6 +2493,8 @@ static int OJPEGWriteStream(TIFF *tif, void **mem, uint32_t *len)
|
||||
case ososEoi:
|
||||
OJPEGWriteStreamEoi(tif, mem, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} while (*len == 0);
|
||||
return (1);
|
||||
@@ -2475,7 +2508,7 @@ static void OJPEGWriteStreamSoi(TIFF *tif, void **mem, uint32_t *len)
|
||||
sp->out_buffer[1] = JPEG_MARKER_SOI;
|
||||
*len = 2;
|
||||
*mem = (void *)sp->out_buffer;
|
||||
sp->out_state++;
|
||||
sp->out_state = (OJPEGStateOutState)(sp->out_state + 1);
|
||||
}
|
||||
|
||||
static void OJPEGWriteStreamQTable(TIFF *tif, uint8_t table_index, void **mem,
|
||||
@@ -2485,9 +2518,10 @@ static void OJPEGWriteStreamQTable(TIFF *tif, uint8_t table_index, void **mem,
|
||||
if (sp->qtable[table_index] != 0)
|
||||
{
|
||||
*mem = (void *)(sp->qtable[table_index] + sizeof(uint32_t));
|
||||
*len = *((uint32_t *)sp->qtable[table_index]) - sizeof(uint32_t);
|
||||
*len = (uint32_t)(*((uint32_t *)sp->qtable[table_index]) -
|
||||
sizeof(uint32_t));
|
||||
}
|
||||
sp->out_state++;
|
||||
sp->out_state = (OJPEGStateOutState)(sp->out_state + 1);
|
||||
}
|
||||
|
||||
static void OJPEGWriteStreamDcTable(TIFF *tif, uint8_t table_index, void **mem,
|
||||
@@ -2497,9 +2531,10 @@ static void OJPEGWriteStreamDcTable(TIFF *tif, uint8_t table_index, void **mem,
|
||||
if (sp->dctable[table_index] != 0)
|
||||
{
|
||||
*mem = (void *)(sp->dctable[table_index] + sizeof(uint32_t));
|
||||
*len = *((uint32_t *)sp->dctable[table_index]) - sizeof(uint32_t);
|
||||
*len = (uint32_t)(*((uint32_t *)sp->dctable[table_index]) -
|
||||
sizeof(uint32_t));
|
||||
}
|
||||
sp->out_state++;
|
||||
sp->out_state = (OJPEGStateOutState)(sp->out_state + 1);
|
||||
}
|
||||
|
||||
static void OJPEGWriteStreamAcTable(TIFF *tif, uint8_t table_index, void **mem,
|
||||
@@ -2509,9 +2544,10 @@ static void OJPEGWriteStreamAcTable(TIFF *tif, uint8_t table_index, void **mem,
|
||||
if (sp->actable[table_index] != 0)
|
||||
{
|
||||
*mem = (void *)(sp->actable[table_index] + sizeof(uint32_t));
|
||||
*len = *((uint32_t *)sp->actable[table_index]) - sizeof(uint32_t);
|
||||
*len = (uint32_t)(*((uint32_t *)sp->actable[table_index]) -
|
||||
sizeof(uint32_t));
|
||||
}
|
||||
sp->out_state++;
|
||||
sp->out_state = (OJPEGStateOutState)(sp->out_state + 1);
|
||||
}
|
||||
|
||||
static void OJPEGWriteStreamDri(TIFF *tif, void **mem, uint32_t *len)
|
||||
@@ -2524,12 +2560,12 @@ static void OJPEGWriteStreamDri(TIFF *tif, void **mem, uint32_t *len)
|
||||
sp->out_buffer[1] = JPEG_MARKER_DRI;
|
||||
sp->out_buffer[2] = 0;
|
||||
sp->out_buffer[3] = 4;
|
||||
sp->out_buffer[4] = (sp->restart_interval >> 8);
|
||||
sp->out_buffer[5] = (sp->restart_interval & 255);
|
||||
sp->out_buffer[4] = (uint8_t)(sp->restart_interval >> 8);
|
||||
sp->out_buffer[5] = (uint8_t)(sp->restart_interval & 255);
|
||||
*len = 6;
|
||||
*mem = (void *)sp->out_buffer;
|
||||
}
|
||||
sp->out_state++;
|
||||
sp->out_state = (OJPEGStateOutState)(sp->out_state + 1);
|
||||
}
|
||||
|
||||
static void OJPEGWriteStreamSof(TIFF *tif, void **mem, uint32_t *len)
|
||||
@@ -2542,15 +2578,15 @@ static void OJPEGWriteStreamSof(TIFF *tif, void **mem, uint32_t *len)
|
||||
sp->out_buffer[1] = sp->sof_marker_id;
|
||||
/* Lf */
|
||||
sp->out_buffer[2] = 0;
|
||||
sp->out_buffer[3] = 8 + sp->samples_per_pixel_per_plane * 3;
|
||||
sp->out_buffer[3] = (uint8_t)(8 + sp->samples_per_pixel_per_plane * 3);
|
||||
/* P */
|
||||
sp->out_buffer[4] = 8;
|
||||
/* Y */
|
||||
sp->out_buffer[5] = (uint8_t)(sp->sof_y >> 8);
|
||||
sp->out_buffer[6] = (sp->sof_y & 255);
|
||||
sp->out_buffer[6] = (uint8_t)(sp->sof_y & 255);
|
||||
/* X */
|
||||
sp->out_buffer[7] = (uint8_t)(sp->sof_x >> 8);
|
||||
sp->out_buffer[8] = (sp->sof_x & 255);
|
||||
sp->out_buffer[8] = (uint8_t)(sp->sof_x & 255);
|
||||
/* Nf */
|
||||
sp->out_buffer[9] = sp->samples_per_pixel_per_plane;
|
||||
for (m = 0; m < sp->samples_per_pixel_per_plane; m++)
|
||||
@@ -2564,9 +2600,9 @@ static void OJPEGWriteStreamSof(TIFF *tif, void **mem, uint32_t *len)
|
||||
sp->out_buffer[10 + m * 3 + 2] =
|
||||
sp->sof_tq[sp->plane_sample_offset + m];
|
||||
}
|
||||
*len = 10 + sp->samples_per_pixel_per_plane * 3;
|
||||
*len = 10 + (uint32_t)sp->samples_per_pixel_per_plane * 3;
|
||||
*mem = (void *)sp->out_buffer;
|
||||
sp->out_state++;
|
||||
sp->out_state = (OJPEGStateOutState)(sp->out_state + 1);
|
||||
}
|
||||
|
||||
static void OJPEGWriteStreamSos(TIFF *tif, void **mem, uint32_t *len)
|
||||
@@ -2579,7 +2615,7 @@ static void OJPEGWriteStreamSos(TIFF *tif, void **mem, uint32_t *len)
|
||||
sp->out_buffer[1] = JPEG_MARKER_SOS;
|
||||
/* Ls */
|
||||
sp->out_buffer[2] = 0;
|
||||
sp->out_buffer[3] = 6 + sp->samples_per_pixel_per_plane * 2;
|
||||
sp->out_buffer[3] = (uint8_t)(6 + sp->samples_per_pixel_per_plane * 2);
|
||||
/* Ns */
|
||||
sp->out_buffer[4] = sp->samples_per_pixel_per_plane;
|
||||
for (m = 0; m < sp->samples_per_pixel_per_plane; m++)
|
||||
@@ -2596,9 +2632,9 @@ static void OJPEGWriteStreamSos(TIFF *tif, void **mem, uint32_t *len)
|
||||
sp->out_buffer[5 + sp->samples_per_pixel_per_plane * 2 + 1] = 63;
|
||||
/* Ah and Al */
|
||||
sp->out_buffer[5 + sp->samples_per_pixel_per_plane * 2 + 2] = 0;
|
||||
*len = 8 + sp->samples_per_pixel_per_plane * 2;
|
||||
*len = 8 + (uint32_t)sp->samples_per_pixel_per_plane * 2;
|
||||
*mem = (void *)sp->out_buffer;
|
||||
sp->out_state++;
|
||||
sp->out_state = (OJPEGStateOutState)(sp->out_state + 1);
|
||||
}
|
||||
|
||||
static int OJPEGWriteStreamCompressed(TIFF *tif, void **mem, uint32_t *len)
|
||||
@@ -2626,6 +2662,8 @@ static int OJPEGWriteStreamCompressed(TIFF *tif, void **mem, uint32_t *len)
|
||||
case osibsEof:
|
||||
sp->out_state = ososEoi;
|
||||
break;
|
||||
case osibsNotSetYet:
|
||||
case osibsJpegInterchangeFormat:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2638,7 +2676,7 @@ static void OJPEGWriteStreamRst(TIFF *tif, void **mem, uint32_t *len)
|
||||
OJPEGState *sp = (OJPEGState *)tif->tif_data;
|
||||
assert(OJPEG_BUFFER >= 2);
|
||||
sp->out_buffer[0] = 255;
|
||||
sp->out_buffer[1] = JPEG_MARKER_RST0 + sp->restart_index;
|
||||
sp->out_buffer[1] = (uint8_t)(JPEG_MARKER_RST0 + sp->restart_index);
|
||||
sp->restart_index++;
|
||||
if (sp->restart_index == 8)
|
||||
sp->restart_index = 0;
|
||||
@@ -2659,7 +2697,7 @@ static void OJPEGWriteStreamEoi(TIFF *tif, void **mem, uint32_t *len)
|
||||
|
||||
#ifndef LIBJPEG_ENCAP_EXTERNAL
|
||||
static int jpeg_create_decompress_encap(OJPEGState *sp,
|
||||
jpeg_decompress_struct *cinfo)
|
||||
tiff_ojpeg_decompress_struct *cinfo)
|
||||
{
|
||||
if (SETJMP(sp->exit_jmpbuf))
|
||||
return 0;
|
||||
@@ -2672,7 +2710,8 @@ static int jpeg_create_decompress_encap(OJPEGState *sp,
|
||||
#endif
|
||||
|
||||
#ifndef LIBJPEG_ENCAP_EXTERNAL
|
||||
static int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo,
|
||||
static int jpeg_read_header_encap(OJPEGState *sp,
|
||||
tiff_ojpeg_decompress_struct *cinfo,
|
||||
uint8_t require_image)
|
||||
{
|
||||
if (SETJMP(sp->exit_jmpbuf))
|
||||
@@ -2687,7 +2726,7 @@ static int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo,
|
||||
|
||||
#ifndef LIBJPEG_ENCAP_EXTERNAL
|
||||
static int jpeg_start_decompress_encap(OJPEGState *sp,
|
||||
jpeg_decompress_struct *cinfo)
|
||||
tiff_ojpeg_decompress_struct *cinfo)
|
||||
{
|
||||
if (SETJMP(sp->exit_jmpbuf))
|
||||
return 0;
|
||||
@@ -2701,14 +2740,14 @@ static int jpeg_start_decompress_encap(OJPEGState *sp,
|
||||
|
||||
#ifndef LIBJPEG_ENCAP_EXTERNAL
|
||||
static int jpeg_read_scanlines_encap(OJPEGState *sp,
|
||||
jpeg_decompress_struct *cinfo,
|
||||
tiff_ojpeg_decompress_struct *cinfo,
|
||||
void *scanlines, uint32_t max_lines)
|
||||
{
|
||||
if (SETJMP(sp->exit_jmpbuf))
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
jpeg_read_scanlines(cinfo, scanlines, max_lines);
|
||||
jpeg_read_scanlines(cinfo, (JSAMPARRAY)scanlines, max_lines);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -2716,14 +2755,14 @@ static int jpeg_read_scanlines_encap(OJPEGState *sp,
|
||||
|
||||
#ifndef LIBJPEG_ENCAP_EXTERNAL
|
||||
static int jpeg_read_raw_data_encap(OJPEGState *sp,
|
||||
jpeg_decompress_struct *cinfo, void *data,
|
||||
uint32_t max_lines)
|
||||
tiff_ojpeg_decompress_struct *cinfo,
|
||||
void *data, uint32_t max_lines)
|
||||
{
|
||||
if (SETJMP(sp->exit_jmpbuf))
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
jpeg_read_raw_data(cinfo, data, max_lines);
|
||||
jpeg_read_raw_data(cinfo, (JSAMPIMAGE)data, max_lines);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -2737,14 +2776,15 @@ static void jpeg_encap_unwind(TIFF *tif)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct *cinfo)
|
||||
static void
|
||||
OJPEGLibjpegJpegErrorMgrOutputMessage(tiff_ojpeg_common_struct *cinfo)
|
||||
{
|
||||
char buffer[JMSG_LENGTH_MAX];
|
||||
(*cinfo->err->format_message)(cinfo, buffer);
|
||||
TIFFWarningExtR(((TIFF *)(cinfo->client_data)), "LibJpeg", "%s", buffer);
|
||||
}
|
||||
|
||||
static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct *cinfo)
|
||||
static void OJPEGLibjpegJpegErrorMgrErrorExit(tiff_ojpeg_common_struct *cinfo)
|
||||
{
|
||||
char buffer[JMSG_LENGTH_MAX];
|
||||
(*cinfo->err->format_message)(cinfo, buffer);
|
||||
@@ -2752,13 +2792,14 @@ static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct *cinfo)
|
||||
jpeg_encap_unwind((TIFF *)(cinfo->client_data));
|
||||
}
|
||||
|
||||
static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct *cinfo)
|
||||
static void
|
||||
OJPEGLibjpegJpegSourceMgrInitSource(tiff_ojpeg_decompress_struct *cinfo)
|
||||
{
|
||||
(void)cinfo;
|
||||
}
|
||||
|
||||
static boolean
|
||||
OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct *cinfo)
|
||||
OJPEGLibjpegJpegSourceMgrFillInputBuffer(tiff_ojpeg_decompress_struct *cinfo)
|
||||
{
|
||||
TIFF *tif = (TIFF *)cinfo->client_data;
|
||||
OJPEGState *sp = (OJPEGState *)tif->tif_data;
|
||||
@@ -2770,12 +2811,12 @@ OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct *cinfo)
|
||||
jpeg_encap_unwind(tif);
|
||||
}
|
||||
sp->libjpeg_jpeg_source_mgr.bytes_in_buffer = len;
|
||||
sp->libjpeg_jpeg_source_mgr.next_input_byte = mem;
|
||||
sp->libjpeg_jpeg_source_mgr.next_input_byte = (const JOCTET *)mem;
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void
|
||||
OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct *cinfo,
|
||||
OJPEGLibjpegJpegSourceMgrSkipInputData(tiff_ojpeg_decompress_struct *cinfo,
|
||||
long num_bytes)
|
||||
{
|
||||
TIFF *tif = (TIFF *)cinfo->client_data;
|
||||
@@ -2789,7 +2830,7 @@ OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct *cinfo,
|
||||
#pragma warning(disable : 4702) /* unreachable code */
|
||||
#endif
|
||||
static boolean
|
||||
OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct *cinfo,
|
||||
OJPEGLibjpegJpegSourceMgrResyncToRestart(tiff_ojpeg_decompress_struct *cinfo,
|
||||
int desired)
|
||||
{
|
||||
TIFF *tif = (TIFF *)cinfo->client_data;
|
||||
@@ -2802,7 +2843,8 @@ OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct *cinfo,
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct *cinfo)
|
||||
static void
|
||||
OJPEGLibjpegJpegSourceMgrTermSource(tiff_ojpeg_decompress_struct *cinfo)
|
||||
{
|
||||
(void)cinfo;
|
||||
}
|
||||
|
||||
35
3rdparty/libtiff/tif_open.c
vendored
35
3rdparty/libtiff/tif_open.c
vendored
@@ -77,7 +77,7 @@ int _TIFFgetMode(TIFFOpenOptions *opts, thandle_t clientdata, const char *mode,
|
||||
return (m);
|
||||
}
|
||||
|
||||
TIFFOpenOptions *TIFFOpenOptionsAlloc()
|
||||
TIFFOpenOptions *TIFFOpenOptionsAlloc(void)
|
||||
{
|
||||
TIFFOpenOptions *opts =
|
||||
(TIFFOpenOptions *)_TIFFcalloc(1, sizeof(TIFFOpenOptions));
|
||||
@@ -308,6 +308,7 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
||||
TIFF *tif;
|
||||
int m;
|
||||
const char *cp;
|
||||
tmsize_t size_to_alloc;
|
||||
|
||||
/* The following are configuration checks. They should be redundant, but
|
||||
* should not compile to any actual code in an optimised release build
|
||||
@@ -330,7 +331,7 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
||||
n.a8[0] = 1;
|
||||
n.a8[1] = 0;
|
||||
(void)n;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#if WORDS_BIGENDIAN
|
||||
assert(n.a16 == 256);
|
||||
#else
|
||||
assert(n.a16 == 1);
|
||||
@@ -340,7 +341,7 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
||||
m = _TIFFgetMode(opts, clientdata, mode, module);
|
||||
if (m == -1)
|
||||
goto bad2;
|
||||
tmsize_t size_to_alloc = (tmsize_t)(sizeof(TIFF) + strlen(name) + 1);
|
||||
size_to_alloc = (tmsize_t)(sizeof(TIFF) + strlen(name) + 1);
|
||||
if (opts && opts->max_single_mem_alloc > 0 &&
|
||||
size_to_alloc > opts->max_single_mem_alloc)
|
||||
{
|
||||
@@ -377,8 +378,6 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
||||
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; /* non-existent directory */
|
||||
tif->tif_curdircount = TIFF_NON_EXISTENT_DIR_NUMBER;
|
||||
tif->tif_curoff = 0;
|
||||
tif->tif_curstrip = (uint32_t)-1; /* invalid strip */
|
||||
tif->tif_row = (uint32_t)-1; /* read/write pre-increment */
|
||||
tif->tif_clientdata = clientdata;
|
||||
tif->tif_readproc = readproc;
|
||||
tif->tif_writeproc = writeproc;
|
||||
@@ -398,6 +397,10 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
||||
tif->tif_warn_about_unknown_tags = opts->warn_about_unknown_tags;
|
||||
}
|
||||
|
||||
/* Reset tif->tif_dir structure to zero and
|
||||
* initialize some IFD strile counter and index parameters. */
|
||||
_TIFFResetTifDirAndInitStrileCounters(&tif->tif_dir);
|
||||
|
||||
if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
@@ -480,13 +483,13 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
||||
switch (*cp)
|
||||
{
|
||||
case 'b':
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
#if !WORDS_BIGENDIAN
|
||||
if (m & O_CREAT)
|
||||
tif->tif_flags |= TIFF_SWAB;
|
||||
#endif
|
||||
break;
|
||||
case 'l':
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#if WORDS_BIGENDIAN
|
||||
if ((m & O_CREAT))
|
||||
tif->tif_flags |= TIFF_SWAB;
|
||||
#endif
|
||||
@@ -536,7 +539,9 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
||||
case 'O':
|
||||
if (m == O_RDONLY)
|
||||
tif->tif_flags |=
|
||||
(TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD);
|
||||
(TIFF_LAZYSTRILELOAD_ASKED | TIFF_DEFERSTRILELOAD);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -561,7 +566,7 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
||||
/*
|
||||
* Setup header and write.
|
||||
*/
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#if WORDS_BIGENDIAN
|
||||
tif->tif_header.common.tiff_magic =
|
||||
(tif->tif_flags & TIFF_SWAB) ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
|
||||
#else
|
||||
@@ -654,13 +659,13 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
||||
}
|
||||
if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN)
|
||||
{
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
#if !WORDS_BIGENDIAN
|
||||
tif->tif_flags |= TIFF_SWAB;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#if WORDS_BIGENDIAN
|
||||
tif->tif_flags |= TIFF_SWAB;
|
||||
#endif
|
||||
}
|
||||
@@ -780,6 +785,8 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
|
||||
if (!TIFFDefaultDirectory(tif))
|
||||
goto bad;
|
||||
return (tif);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
bad:
|
||||
tif->tif_mode = O_RDONLY; /* XXX avoid flush */
|
||||
@@ -861,7 +868,7 @@ int TIFFIsTiled(TIFF *tif) { return (isTiled(tif)); }
|
||||
/*
|
||||
* Return current row being read/written.
|
||||
*/
|
||||
uint32_t TIFFCurrentRow(TIFF *tif) { return (tif->tif_row); }
|
||||
uint32_t TIFFCurrentRow(TIFF *tif) { return (tif->tif_dir.td_row); }
|
||||
|
||||
/*
|
||||
* Return index of the current directory.
|
||||
@@ -871,12 +878,12 @@ tdir_t TIFFCurrentDirectory(TIFF *tif) { return (tif->tif_curdir); }
|
||||
/*
|
||||
* Return current strip.
|
||||
*/
|
||||
uint32_t TIFFCurrentStrip(TIFF *tif) { return (tif->tif_curstrip); }
|
||||
uint32_t TIFFCurrentStrip(TIFF *tif) { return (tif->tif_dir.td_curstrip); }
|
||||
|
||||
/*
|
||||
* Return current tile.
|
||||
*/
|
||||
uint32_t TIFFCurrentTile(TIFF *tif) { return (tif->tif_curtile); }
|
||||
uint32_t TIFFCurrentTile(TIFF *tif) { return (tif->tif_dir.td_curtile); }
|
||||
|
||||
/*
|
||||
* Return nonzero if the file has byte-swapped data.
|
||||
|
||||
21
3rdparty/libtiff/tif_packbits.c
vendored
21
3rdparty/libtiff/tif_packbits.c
vendored
@@ -194,12 +194,17 @@ static int PackBitsEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
|
||||
*/
|
||||
if (n == 1 && op[-2] == (uint8_t)-1 && *lastliteral < 126)
|
||||
{
|
||||
state = (((*lastliteral) += 2) == 127 ? BASE : LITERAL);
|
||||
state =
|
||||
(((*lastliteral) = (uint8_t)(*lastliteral + 2)) == 127
|
||||
? BASE
|
||||
: LITERAL);
|
||||
op[-2] = op[-1]; /* replicate */
|
||||
}
|
||||
else
|
||||
state = RUN;
|
||||
goto again;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
|
||||
@@ -306,12 +311,22 @@ static int PackBitsDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32,
|
||||
tif->tif_row);
|
||||
tif->tif_dir.td_row);
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static uint64_t PackBitsGetMaxCompressionRatio(TIFF *tif)
|
||||
{
|
||||
(void)tif;
|
||||
|
||||
/* See README_for_libtiff_developpers.md for raw data used to estimate
|
||||
* the maximum compression rate. */
|
||||
|
||||
return 64;
|
||||
}
|
||||
|
||||
int TIFFInitPackBits(TIFF *tif, int scheme)
|
||||
{
|
||||
(void)scheme;
|
||||
@@ -325,6 +340,8 @@ int TIFFInitPackBits(TIFF *tif, int scheme)
|
||||
tif->tif_encodestrip = PackBitsEncodeChunk;
|
||||
tif->tif_encodetile = PackBitsEncodeChunk;
|
||||
#endif
|
||||
tif->tif_getmaxcompressionratio = PackBitsGetMaxCompressionRatio;
|
||||
|
||||
return (1);
|
||||
}
|
||||
#endif /* PACKBITS_SUPPORT */
|
||||
|
||||
237
3rdparty/libtiff/tif_pixarlog.c
vendored
237
3rdparty/libtiff/tif_pixarlog.c
vendored
@@ -117,11 +117,11 @@ static float LogK1, LogK2;
|
||||
} while (i > 0); \
|
||||
}
|
||||
|
||||
static void horizontalAccumulateF(uint16_t *wp, int n, int stride, float *op,
|
||||
float *ToLinearF)
|
||||
static void horizontalAccumulateF(uint16_t *wp, tmsize_t n, int stride,
|
||||
float *op, float *ToLinearF)
|
||||
{
|
||||
register unsigned int cr, cg, cb, ca, mask;
|
||||
register float t0, t1, t2, t3;
|
||||
unsigned int cr, cg, cb, ca, mask;
|
||||
float t0, t1, t2, t3;
|
||||
|
||||
if (n >= stride)
|
||||
{
|
||||
@@ -180,22 +180,22 @@ static void horizontalAccumulateF(uint16_t *wp, int n, int stride, float *op,
|
||||
n -= stride;
|
||||
while (n > 0)
|
||||
{
|
||||
REPEAT(stride, wp[stride] += *wp; *op = ToLinearF[*wp & mask];
|
||||
wp++; op++)
|
||||
REPEAT(stride, *wp = (uint16_t)(*wp + wp[-stride]);
|
||||
*op = ToLinearF[*wp & mask]; wp++; op++)
|
||||
n -= stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void horizontalAccumulate12(uint16_t *wp, int n, int stride, int16_t *op,
|
||||
float *ToLinearF)
|
||||
static void horizontalAccumulate12(uint16_t *wp, tmsize_t n, int stride,
|
||||
int16_t *op, float *ToLinearF)
|
||||
{
|
||||
register unsigned int cr, cg, cb, ca, mask;
|
||||
register float t0, t1, t2, t3;
|
||||
unsigned int cr, cg, cb, ca, mask;
|
||||
float t0, t1, t2, t3;
|
||||
|
||||
#define SCALE12 2048.0F
|
||||
#define CLAMP12(t) (((t) < 3071) ? (uint16_t)(t) : 3071)
|
||||
#define SCALE12 2048.0f
|
||||
#define CLAMP12(t) (((t) < 3071) ? (int16_t)(uint16_t)(t) : (int16_t)3071)
|
||||
|
||||
if (n >= stride)
|
||||
{
|
||||
@@ -255,19 +255,19 @@ static void horizontalAccumulate12(uint16_t *wp, int n, int stride, int16_t *op,
|
||||
n -= stride;
|
||||
while (n > 0)
|
||||
{
|
||||
REPEAT(stride, wp[stride] += *wp;
|
||||
t0 = ToLinearF[wp[stride] & mask] * SCALE12;
|
||||
*op = CLAMP12(t0); wp++; op++)
|
||||
REPEAT(stride, *wp = (uint16_t)(*wp + wp[-stride]);
|
||||
t0 = ToLinearF[*wp & mask] * SCALE12; *op = CLAMP12(t0);
|
||||
wp++; op++)
|
||||
n -= stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void horizontalAccumulate16(uint16_t *wp, int n, int stride,
|
||||
static void horizontalAccumulate16(uint16_t *wp, tmsize_t n, int stride,
|
||||
uint16_t *op, uint16_t *ToLinear16)
|
||||
{
|
||||
register unsigned int cr, cg, cb, ca, mask;
|
||||
unsigned int cr, cg, cb, ca, mask;
|
||||
|
||||
if (n >= stride)
|
||||
{
|
||||
@@ -312,8 +312,8 @@ static void horizontalAccumulate16(uint16_t *wp, int n, int stride,
|
||||
n -= stride;
|
||||
while (n > 0)
|
||||
{
|
||||
REPEAT(stride, wp[stride] += *wp; *op = ToLinear16[*wp & mask];
|
||||
wp++; op++)
|
||||
REPEAT(stride, *wp = (uint16_t)(*wp + wp[-stride]);
|
||||
*op = ToLinear16[*wp & mask]; wp++; op++)
|
||||
n -= stride;
|
||||
}
|
||||
}
|
||||
@@ -324,10 +324,10 @@ static void horizontalAccumulate16(uint16_t *wp, int n, int stride,
|
||||
* Returns the log encoded 11-bit values with the horizontal
|
||||
* differencing undone.
|
||||
*/
|
||||
static void horizontalAccumulate11(uint16_t *wp, int n, int stride,
|
||||
static void horizontalAccumulate11(uint16_t *wp, tmsize_t n, int stride,
|
||||
uint16_t *op)
|
||||
{
|
||||
register unsigned int cr, cg, cb, ca, mask;
|
||||
unsigned int cr, cg, cb, ca, mask;
|
||||
|
||||
if (n >= stride)
|
||||
{
|
||||
@@ -375,21 +375,22 @@ static void horizontalAccumulate11(uint16_t *wp, int n, int stride,
|
||||
}
|
||||
else
|
||||
{
|
||||
REPEAT(stride, *op = *wp & mask; wp++; op++)
|
||||
REPEAT(stride, *op = (uint16_t)(*wp & mask); wp++; op++)
|
||||
n -= stride;
|
||||
while (n > 0)
|
||||
{
|
||||
REPEAT(stride, wp[stride] += *wp; *op = *wp & mask; wp++; op++)
|
||||
REPEAT(stride, *wp = (uint16_t)(*wp + wp[-stride]);
|
||||
*op = (uint16_t)(*wp & mask); wp++; op++)
|
||||
n -= stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void horizontalAccumulate8(uint16_t *wp, int n, int stride,
|
||||
static void horizontalAccumulate8(uint16_t *wp, tmsize_t n, int stride,
|
||||
unsigned char *op, unsigned char *ToLinear8)
|
||||
{
|
||||
register unsigned int cr, cg, cb, ca, mask;
|
||||
unsigned int cr, cg, cb, ca, mask;
|
||||
|
||||
if (n >= stride)
|
||||
{
|
||||
@@ -434,20 +435,20 @@ static void horizontalAccumulate8(uint16_t *wp, int n, int stride,
|
||||
n -= stride;
|
||||
while (n > 0)
|
||||
{
|
||||
REPEAT(stride, wp[stride] += *wp; *op = ToLinear8[*wp & mask];
|
||||
wp++; op++)
|
||||
REPEAT(stride, *wp = (uint16_t)(*wp + wp[-stride]);
|
||||
*op = ToLinear8[*wp & mask]; wp++; op++)
|
||||
n -= stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void horizontalAccumulate8abgr(uint16_t *wp, int n, int stride,
|
||||
static void horizontalAccumulate8abgr(uint16_t *wp, tmsize_t n, int stride,
|
||||
unsigned char *op,
|
||||
unsigned char *ToLinear8)
|
||||
{
|
||||
register unsigned int cr, cg, cb, ca, mask;
|
||||
register unsigned char t0, t1, t2, t3;
|
||||
unsigned int cr, cg, cb, ca, mask;
|
||||
unsigned char t0, t1, t2, t3;
|
||||
|
||||
if (n >= stride)
|
||||
{
|
||||
@@ -508,8 +509,8 @@ static void horizontalAccumulate8abgr(uint16_t *wp, int n, int stride,
|
||||
n -= stride;
|
||||
while (n > 0)
|
||||
{
|
||||
REPEAT(stride, wp[stride] += *wp; *op = ToLinear8[*wp & mask];
|
||||
wp++; op++)
|
||||
REPEAT(stride, *wp = (uint16_t)(*wp + wp[-stride]);
|
||||
*op = ToLinear8[*wp & mask]; wp++; op++)
|
||||
n -= stride;
|
||||
}
|
||||
}
|
||||
@@ -577,7 +578,8 @@ static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp)
|
||||
LogK1 = (float)(1. / c); /* if (v >= 2) token = k1*log(v*k2) */
|
||||
LogK2 = (float)(1. / b);
|
||||
lt2size = (int)(2. / linstep) + 1;
|
||||
FromLT2 = (uint16_t *)_TIFFmallocExt(tif, lt2size * sizeof(uint16_t));
|
||||
FromLT2 = (uint16_t *)_TIFFmallocExt(
|
||||
tif, (tmsize_t)((size_t)lt2size * sizeof(uint16_t)));
|
||||
From14 = (uint16_t *)_TIFFmallocExt(tif, 16384 * sizeof(uint16_t));
|
||||
From8 = (uint16_t *)_TIFFmallocExt(tif, 256 * sizeof(uint16_t));
|
||||
ToLinearF = (float *)_TIFFmallocExt(tif, TSIZEP1 * sizeof(float));
|
||||
@@ -623,16 +625,17 @@ static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp)
|
||||
|
||||
for (i = 0; i < TSIZEP1; i++)
|
||||
{
|
||||
v = ToLinearF[i] * 65535.0 + 0.5;
|
||||
v = (double)ToLinearF[i] * 65535.0 + 0.5;
|
||||
ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16_t)v;
|
||||
v = ToLinearF[i] * 255.0 + 0.5;
|
||||
v = (double)ToLinearF[i] * 255.0 + 0.5;
|
||||
ToLinear8[i] = (v > 255.0) ? 255 : (unsigned char)v;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < lt2size; i++)
|
||||
{
|
||||
if ((i * linstep) * (i * linstep) > ToLinearF[j] * ToLinearF[j + 1])
|
||||
if ((i * linstep) * (i * linstep) >
|
||||
(double)ToLinearF[j] * (double)ToLinearF[j + 1])
|
||||
j++;
|
||||
FromLT2[i] = (uint16_t)j;
|
||||
}
|
||||
@@ -645,7 +648,8 @@ static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp)
|
||||
j = 0;
|
||||
for (i = 0; i < 16384; i++)
|
||||
{
|
||||
while ((i / 16383.) * (i / 16383.) > ToLinearF[j] * ToLinearF[j + 1])
|
||||
while ((i / 16383.) * (i / 16383.) >
|
||||
(double)ToLinearF[j] * (double)ToLinearF[j + 1])
|
||||
j++;
|
||||
From14[i] = (uint16_t)j;
|
||||
}
|
||||
@@ -653,7 +657,8 @@ static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp)
|
||||
j = 0;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
while ((i / 255.) * (i / 255.) > ToLinearF[j] * ToLinearF[j + 1])
|
||||
while ((i / 255.) * (i / 255.) >
|
||||
(double)ToLinearF[j] * (double)ToLinearF[j + 1])
|
||||
j++;
|
||||
From8[i] = (uint16_t)j;
|
||||
}
|
||||
@@ -708,6 +713,8 @@ static int PixarLogGuessDataFmt(TIFFDirectory *td)
|
||||
if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
|
||||
guess = PIXARLOGDATAFMT_8BIT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return guess;
|
||||
@@ -769,7 +776,8 @@ static int PixarLogSetupDecode(TIFF *tif)
|
||||
multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), strip_height),
|
||||
sizeof(uint16_t));
|
||||
/* add one more stride in case input ends mid-stride */
|
||||
tbuf_size = add_ms(tbuf_size, sizeof(uint16_t) * sp->stride);
|
||||
tbuf_size =
|
||||
add_ms(tbuf_size, (tmsize_t)(sizeof(uint16_t) * (size_t)sp->stride));
|
||||
if (tbuf_size == 0)
|
||||
return (0); /* TODO: this is an error return without error report
|
||||
through TIFFErrorExt */
|
||||
@@ -838,18 +846,21 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
PixarLogState *sp = PixarLogDecoderState(tif);
|
||||
tmsize_t i;
|
||||
tmsize_t nsamples;
|
||||
int llen;
|
||||
tmsize_t llen;
|
||||
uint16_t *up;
|
||||
|
||||
switch (sp->user_datafmt)
|
||||
{
|
||||
case PIXARLOGDATAFMT_FLOAT:
|
||||
nsamples = occ / sizeof(float); /* XXX float == 32 bits */
|
||||
nsamples = (tmsize_t)((uint64_t)occ /
|
||||
sizeof(float)); /* XXX float == 32 bits */
|
||||
break;
|
||||
case PIXARLOGDATAFMT_16BIT:
|
||||
case PIXARLOGDATAFMT_12BITPICIO:
|
||||
case PIXARLOGDATAFMT_11BITLOG:
|
||||
nsamples = occ / sizeof(uint16_t); /* XXX uint16_t == 16 bits */
|
||||
nsamples =
|
||||
(tmsize_t)((uint64_t)occ /
|
||||
sizeof(uint16_t)); /* XXX uint16_t == 16 bits */
|
||||
break;
|
||||
case PIXARLOGDATAFMT_8BIT:
|
||||
case PIXARLOGDATAFMT_8BITABGR:
|
||||
@@ -863,7 +874,55 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
llen = sp->stride * td->td_imagewidth;
|
||||
llen = (tmsize_t)sp->stride * td->td_imagewidth;
|
||||
|
||||
/* Fix: ABGR with stride=3 expands 3 samples to 4 output bytes per pixel */
|
||||
if (sp->user_datafmt == PIXARLOGDATAFMT_8BITABGR && sp->stride == 3)
|
||||
{
|
||||
tmsize_t required = (tmsize_t)td->td_imagewidth * 4;
|
||||
tmsize_t max_rows;
|
||||
tmsize_t max_nsamples;
|
||||
|
||||
/*
|
||||
* Ensure at least one expanded output row fits.
|
||||
*/
|
||||
if (occ < required)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Output buffer too small for PixarLog ABGR data");
|
||||
memset(op, 0, (size_t)occ);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* The caller-provided output buffer size must represent a whole
|
||||
* number of expanded ABGR scanlines.
|
||||
*/
|
||||
if (occ % required)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
tif, module,
|
||||
"Fractional scanline not supported for PixarLog ABGR data");
|
||||
memset(op, 0, (size_t)occ);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* PixarLogDecode() may process multiple rows per call
|
||||
* (e.g. strip decoding). Limit nsamples so the total
|
||||
* output written by the loop below never exceeds occ.
|
||||
*/
|
||||
max_rows = occ / required;
|
||||
max_nsamples = max_rows * llen;
|
||||
|
||||
if (nsamples > max_nsamples)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Output buffer too small for PixarLog ABGR data");
|
||||
memset(op, 0, (size_t)occ);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
(void)s;
|
||||
assert(sp != NULL);
|
||||
@@ -876,8 +935,8 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
we need to simplify this code to reflect a ZLib that is likely updated
|
||||
to deal with 8byte memory sizes, though this code will respond
|
||||
appropriately even before we simplify it */
|
||||
sp->stream.avail_out = (uInt)(nsamples * sizeof(uint16_t));
|
||||
if (sp->stream.avail_out != nsamples * sizeof(uint16_t))
|
||||
sp->stream.avail_out = (uInt)((unsigned long)nsamples * sizeof(uint16_t));
|
||||
if (sp->stream.avail_out != (unsigned long)nsamples * sizeof(uint16_t))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size");
|
||||
memset(op, 0, (size_t)occ);
|
||||
@@ -899,9 +958,10 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
}
|
||||
if (state == Z_DATA_ERROR)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
tif, module, "Decoding error at scanline %" PRIu32 ", %s",
|
||||
tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)");
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Decoding error at scanline %" PRIu32 ", %s",
|
||||
tif->tif_dir.td_row,
|
||||
sp->stream.msg ? sp->stream.msg : "(null)");
|
||||
memset(op, 0, (size_t)occ);
|
||||
return (0);
|
||||
}
|
||||
@@ -920,7 +980,7 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Not enough data at scanline %" PRIu32
|
||||
" (short %u bytes)",
|
||||
tif->tif_row, sp->stream.avail_out);
|
||||
tif->tif_dir.td_row, sp->stream.avail_out);
|
||||
memset(op, 0, (size_t)occ);
|
||||
return (0);
|
||||
}
|
||||
@@ -941,7 +1001,8 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
if (nsamples % llen)
|
||||
{
|
||||
TIFFWarningExtR(tif, module,
|
||||
"stride %d is not a multiple of sample count, "
|
||||
"stride %" TIFF_SSIZE_FORMAT
|
||||
" is not a multiple of sample count, "
|
||||
"%" TIFF_SSIZE_FORMAT ", data truncated.",
|
||||
llen, nsamples);
|
||||
nsamples -= nsamples % llen;
|
||||
@@ -954,31 +1015,37 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
case PIXARLOGDATAFMT_FLOAT:
|
||||
horizontalAccumulateF(up, llen, sp->stride, (float *)op,
|
||||
sp->ToLinearF);
|
||||
op += llen * sizeof(float);
|
||||
op += (unsigned long)llen * sizeof(float);
|
||||
break;
|
||||
case PIXARLOGDATAFMT_16BIT:
|
||||
horizontalAccumulate16(up, llen, sp->stride, (uint16_t *)op,
|
||||
sp->ToLinear16);
|
||||
op += llen * sizeof(uint16_t);
|
||||
op += (unsigned long)llen * sizeof(uint16_t);
|
||||
break;
|
||||
case PIXARLOGDATAFMT_12BITPICIO:
|
||||
horizontalAccumulate12(up, llen, sp->stride, (int16_t *)op,
|
||||
sp->ToLinearF);
|
||||
op += llen * sizeof(int16_t);
|
||||
op += (unsigned long)llen * sizeof(int16_t);
|
||||
break;
|
||||
case PIXARLOGDATAFMT_11BITLOG:
|
||||
horizontalAccumulate11(up, llen, sp->stride, (uint16_t *)op);
|
||||
op += llen * sizeof(uint16_t);
|
||||
op += (unsigned long)llen * sizeof(uint16_t);
|
||||
break;
|
||||
case PIXARLOGDATAFMT_8BIT:
|
||||
horizontalAccumulate8(up, llen, sp->stride, (unsigned char *)op,
|
||||
sp->ToLinear8);
|
||||
op += llen * sizeof(unsigned char);
|
||||
op += (unsigned long)llen * sizeof(unsigned char);
|
||||
break;
|
||||
case PIXARLOGDATAFMT_8BITABGR:
|
||||
horizontalAccumulate8abgr(up, llen, sp->stride,
|
||||
(unsigned char *)op, sp->ToLinear8);
|
||||
op += llen * sizeof(unsigned char);
|
||||
|
||||
/* For stride == 3 (RGB), horizontalAccumulate8abgr expands to 4
|
||||
* bytes/pixel (ABGR) */
|
||||
if (sp->stride == 3)
|
||||
op += (unsigned long)td->td_imagewidth * 4;
|
||||
else
|
||||
op += (unsigned long)llen * sizeof(unsigned char);
|
||||
break;
|
||||
default:
|
||||
TIFFErrorExtR(tif, module, "Unsupported bits/sample: %" PRIu16,
|
||||
@@ -1063,17 +1130,18 @@ static int PixarLogPreEncode(TIFF *tif, uint16_t s)
|
||||
return (deflateReset(&sp->stream) == Z_OK);
|
||||
}
|
||||
|
||||
static void horizontalDifferenceF(float *ip, int n, int stride, uint16_t *wp,
|
||||
uint16_t *FromLT2)
|
||||
static void horizontalDifferenceF(float *ip, tmsize_t n, int stride,
|
||||
uint16_t *wp, uint16_t *FromLT2)
|
||||
{
|
||||
int32_t r1, g1, b1, a1, r2, g2, b2, a2, mask;
|
||||
float fltsize = Fltsize;
|
||||
|
||||
#define CLAMP(v) \
|
||||
((v < (float)0.) ? 0 \
|
||||
: (v < (float)2.) ? FromLT2[(int)(v * fltsize)] \
|
||||
: (v > (float)24.2) ? 2047 \
|
||||
: LogK1 * log(v * LogK2) + 0.5)
|
||||
((v < (float)0.) ? 0 \
|
||||
: (v < (float)2.) ? FromLT2[(int)(v * fltsize)] \
|
||||
: (v > (float)24.2) \
|
||||
? 2047 \
|
||||
: (double)LogK1 * log((double)v * (double)LogK2) + 0.5)
|
||||
|
||||
mask = CODE_MASK;
|
||||
if (n >= stride)
|
||||
@@ -1143,10 +1211,10 @@ static void horizontalDifferenceF(float *ip, int n, int stride, uint16_t *wp,
|
||||
}
|
||||
}
|
||||
|
||||
static void horizontalDifference16(unsigned short *ip, int n, int stride,
|
||||
static void horizontalDifference16(unsigned short *ip, tmsize_t n, int stride,
|
||||
unsigned short *wp, uint16_t *From14)
|
||||
{
|
||||
register int r1, g1, b1, a1, r2, g2, b2, a2, mask;
|
||||
int r1, g1, b1, a1, r2, g2, b2, a2, mask;
|
||||
|
||||
/* assumption is unsigned pixel values */
|
||||
#undef CLAMP
|
||||
@@ -1219,10 +1287,10 @@ static void horizontalDifference16(unsigned short *ip, int n, int stride,
|
||||
}
|
||||
}
|
||||
|
||||
static void horizontalDifference8(unsigned char *ip, int n, int stride,
|
||||
static void horizontalDifference8(unsigned char *ip, tmsize_t n, int stride,
|
||||
unsigned short *wp, uint16_t *From8)
|
||||
{
|
||||
register int r1, g1, b1, a1, r2, g2, b2, a2, mask;
|
||||
int r1, g1, b1, a1, r2, g2, b2, a2, mask;
|
||||
|
||||
#undef CLAMP
|
||||
#define CLAMP(v) (From8[(v)])
|
||||
@@ -1304,7 +1372,7 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
PixarLogState *sp = PixarLogEncoderState(tif);
|
||||
tmsize_t i;
|
||||
tmsize_t n;
|
||||
int llen;
|
||||
tmsize_t llen;
|
||||
unsigned short *up;
|
||||
|
||||
(void)s;
|
||||
@@ -1312,12 +1380,14 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
switch (sp->user_datafmt)
|
||||
{
|
||||
case PIXARLOGDATAFMT_FLOAT:
|
||||
n = cc / sizeof(float); /* XXX float == 32 bits */
|
||||
n = (tmsize_t)((unsigned long)cc /
|
||||
sizeof(float)); /* XXX float == 32 bits */
|
||||
break;
|
||||
case PIXARLOGDATAFMT_16BIT:
|
||||
case PIXARLOGDATAFMT_12BITPICIO:
|
||||
case PIXARLOGDATAFMT_11BITLOG:
|
||||
n = cc / sizeof(uint16_t); /* XXX uint16_t == 16 bits */
|
||||
n = (tmsize_t)((unsigned long)cc /
|
||||
sizeof(uint16_t)); /* XXX uint16_t == 16 bits */
|
||||
break;
|
||||
case PIXARLOGDATAFMT_8BIT:
|
||||
case PIXARLOGDATAFMT_8BITABGR:
|
||||
@@ -1330,7 +1400,7 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
llen = sp->stride * td->td_imagewidth;
|
||||
llen = (tmsize_t)sp->stride * td->td_imagewidth;
|
||||
/* Check against the number of elements (of size uint16_t) of sp->tbuf */
|
||||
if (n > ((tmsize_t)td->td_rowsperstrip * llen))
|
||||
{
|
||||
@@ -1345,17 +1415,17 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
case PIXARLOGDATAFMT_FLOAT:
|
||||
horizontalDifferenceF((float *)bp, llen, sp->stride, up,
|
||||
sp->FromLT2);
|
||||
bp += llen * sizeof(float);
|
||||
bp += (unsigned long)llen * sizeof(float);
|
||||
break;
|
||||
case PIXARLOGDATAFMT_16BIT:
|
||||
horizontalDifference16((uint16_t *)bp, llen, sp->stride, up,
|
||||
sp->From14);
|
||||
bp += llen * sizeof(uint16_t);
|
||||
bp += (unsigned long)llen * sizeof(uint16_t);
|
||||
break;
|
||||
case PIXARLOGDATAFMT_8BIT:
|
||||
horizontalDifference8((unsigned char *)bp, llen, sp->stride, up,
|
||||
sp->From8);
|
||||
bp += llen * sizeof(unsigned char);
|
||||
bp += (unsigned long)llen * sizeof(unsigned char);
|
||||
break;
|
||||
default:
|
||||
TIFFErrorExtR(tif, module,
|
||||
@@ -1370,8 +1440,8 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
we need to simplify this code to reflect a ZLib that is likely updated
|
||||
to deal with 8byte memory sizes, though this code will respond
|
||||
appropriately even before we simplify it */
|
||||
sp->stream.avail_in = (uInt)(n * sizeof(uint16_t));
|
||||
if ((sp->stream.avail_in / sizeof(uint16_t)) != (uInt)n)
|
||||
sp->stream.avail_in = (uInt)((unsigned long)n * sizeof(uint16_t));
|
||||
if ((sp->stream.avail_in / sizeof(uint16_t)) != (unsigned long)n)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size");
|
||||
return (0);
|
||||
@@ -1562,13 +1632,15 @@ static int PixarLogVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT,
|
||||
SAMPLEFORMAT_IEEEFP);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Must recalculate sizes should bits/sample change.
|
||||
*/
|
||||
tif->tif_tilesize =
|
||||
tif->tif_dir.td_tilesize =
|
||||
isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);
|
||||
tif->tif_scanlinesize = TIFFScanlineSize(tif);
|
||||
tif->tif_dir.td_scanlinesize = TIFFScanlineSize(tif);
|
||||
result = 1; /* NB: pseudo tag */
|
||||
break;
|
||||
default:
|
||||
@@ -1601,6 +1673,16 @@ static const TIFFField pixarlogFields[] = {
|
||||
{TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO,
|
||||
FALSE, FALSE, "", NULL}};
|
||||
|
||||
static uint64_t PixarLogGetMaxCompressionRatio(TIFF *tif)
|
||||
{
|
||||
(void)tif;
|
||||
/* cf https://zlib.net/zlib_tech.html */
|
||||
const uint64_t MAX_DEFLATE_RATIO = 1032;
|
||||
|
||||
/* security margin as I don't understand what this codec does */
|
||||
return MAX_DEFLATE_RATIO * (uint64_t)4;
|
||||
}
|
||||
|
||||
int TIFFInitPixarLog(TIFF *tif, int scheme)
|
||||
{
|
||||
static const char module[] = "TIFFInitPixarLog";
|
||||
@@ -1648,6 +1730,7 @@ int TIFFInitPixarLog(TIFF *tif, int scheme)
|
||||
tif->tif_encodetile = PixarLogEncode;
|
||||
tif->tif_close = PixarLogClose;
|
||||
tif->tif_cleanup = PixarLogCleanup;
|
||||
tif->tif_getmaxcompressionratio = PixarLogGetMaxCompressionRatio;
|
||||
|
||||
/* Override SetField so we can handle our private pseudo-tag */
|
||||
sp->vgetparent = tif->tif_tagmethods.vgetfield;
|
||||
|
||||
16
3rdparty/libtiff/tif_predict.c
vendored
16
3rdparty/libtiff/tif_predict.c
vendored
@@ -30,7 +30,7 @@
|
||||
#include "tif_predict.h"
|
||||
#include "tiffiop.h"
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
#if defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC))
|
||||
#include <emmintrin.h>
|
||||
#endif
|
||||
|
||||
@@ -151,6 +151,8 @@ static int PredictorSetupDecode(TIFF *tif)
|
||||
case 64:
|
||||
sp->decodepfunc = horAcc64;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Override default decoding method with one that does the
|
||||
@@ -247,6 +249,8 @@ static int PredictorSetupEncode(TIFF *tif)
|
||||
case 64:
|
||||
sp->encodepfunc = horDiff64;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Override default encoding method with one that does the
|
||||
@@ -590,7 +594,7 @@ static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc)
|
||||
cp = (uint8_t *)cp0;
|
||||
count = 0;
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
#if defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC))
|
||||
if (bps == 4)
|
||||
{
|
||||
/* Optimization of general case */
|
||||
@@ -972,7 +976,7 @@ static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
(int64_t)cc);
|
||||
return 0;
|
||||
}
|
||||
memcpy(working_copy, bp, cc);
|
||||
memcpy(working_copy, bp, (size_t)cc);
|
||||
|
||||
if (!(*sp->encodepfunc)(tif, working_copy, cc))
|
||||
{
|
||||
@@ -1010,7 +1014,7 @@ static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0,
|
||||
(int64_t)cc0);
|
||||
return 0;
|
||||
}
|
||||
memcpy(working_copy, bp0, cc0);
|
||||
memcpy(working_copy, bp0, (size_t)cc0);
|
||||
bp = working_copy;
|
||||
|
||||
rowsize = sp->rowsize;
|
||||
@@ -1098,8 +1102,10 @@ static void PredictorPrintDir(TIFF *tif, FILE *fd, long flags)
|
||||
case 3:
|
||||
fprintf(fd, "floating point predictor ");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor);
|
||||
fprintf(fd, "%d (0x%x)\n", sp->predictor, (unsigned)sp->predictor);
|
||||
}
|
||||
if (sp->printdir)
|
||||
(*sp->printdir)(tif, fd, flags);
|
||||
|
||||
92
3rdparty/libtiff/tif_print.c
vendored
92
3rdparty/libtiff/tif_print.c
vendored
@@ -118,10 +118,10 @@ static void _TIFFPrintField(FILE *fd, const TIFFField *fip,
|
||||
if (tv_size == 8)
|
||||
fprintf(fd, "%lf", ((double *)raw_data)[j]);
|
||||
else
|
||||
fprintf(fd, "%f", ((float *)raw_data)[j]);
|
||||
fprintf(fd, "%f", (double)((float *)raw_data)[j]);
|
||||
}
|
||||
else if (fip->field_type == TIFF_FLOAT)
|
||||
fprintf(fd, "%f", ((float *)raw_data)[j]);
|
||||
fprintf(fd, "%f", (double)((float *)raw_data)[j]);
|
||||
else if (fip->field_type == TIFF_LONG8)
|
||||
fprintf(fd, "%" PRIu64, ((uint64_t *)raw_data)[j]);
|
||||
else if (fip->field_type == TIFF_SLONG8)
|
||||
@@ -193,8 +193,9 @@ static int _TIFFPrettyPrintField(TIFF *tif, const TIFFField *fip, FILE *fd,
|
||||
case TIFFTAG_WHITEPOINT:
|
||||
if (value_count == 2 && fip->field_type == TIFF_RATIONAL)
|
||||
{
|
||||
fprintf(fd, " White Point: %g-%g\n", ((float *)raw_data)[0],
|
||||
((float *)raw_data)[1]);
|
||||
fprintf(fd, " White Point: %g-%g\n",
|
||||
(double)((float *)raw_data)[0],
|
||||
(double)((float *)raw_data)[1]);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -232,6 +233,9 @@ static int _TIFFPrettyPrintField(TIFF *tif, const TIFFField *fip, FILE *fd,
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -244,8 +248,7 @@ static int _TIFFPrettyPrintField(TIFF *tif, const TIFFField *fip, FILE *fd,
|
||||
void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
|
||||
{
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
char *sep;
|
||||
long l, n;
|
||||
const char *sep;
|
||||
|
||||
fprintf(fd, "TIFF Directory at offset 0x%" PRIx64 " (%" PRIu64 ")\n",
|
||||
tif->tif_diroff, tif->tif_diroff);
|
||||
@@ -286,8 +289,8 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
|
||||
}
|
||||
if (TIFFFieldSet(tif, FIELD_RESOLUTION))
|
||||
{
|
||||
fprintf(fd, " Resolution: %g, %g", td->td_xresolution,
|
||||
td->td_yresolution);
|
||||
fprintf(fd, " Resolution: %g, %g", (double)td->td_xresolution,
|
||||
(double)td->td_yresolution);
|
||||
if (TIFFFieldSet(tif, FIELD_RESOLUTIONUNIT))
|
||||
{
|
||||
switch (td->td_resolutionunit)
|
||||
@@ -310,7 +313,8 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
|
||||
fprintf(fd, "\n");
|
||||
}
|
||||
if (TIFFFieldSet(tif, FIELD_POSITION))
|
||||
fprintf(fd, " Position: %g, %g\n", td->td_xposition, td->td_yposition);
|
||||
fprintf(fd, " Position: %g, %g\n", (double)td->td_xposition,
|
||||
(double)td->td_yposition);
|
||||
if (TIFFFieldSet(tif, FIELD_BITSPERSAMPLE))
|
||||
fprintf(fd, " Bits/Sample: %" PRIu16 "\n", td->td_bitspersample);
|
||||
if (TIFFFieldSet(tif, FIELD_SAMPLEFORMAT))
|
||||
@@ -374,7 +378,8 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES) && td->td_extrasamples)
|
||||
if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES) && td->td_extrasamples &&
|
||||
td->td_sampleinfo)
|
||||
{
|
||||
uint16_t i;
|
||||
fprintf(fd, " Extra Samples: %" PRIu16 "<", td->td_extrasamples);
|
||||
@@ -412,7 +417,8 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
|
||||
i > 0 && cp < td->td_inknames + td->td_inknameslen;
|
||||
cp = strchr(cp, '\0') + 1, i--)
|
||||
{
|
||||
size_t max_chars = td->td_inknameslen - (cp - td->td_inknames);
|
||||
size_t max_chars =
|
||||
(size_t)(td->td_inknameslen - (cp - td->td_inknames));
|
||||
fputs(sep, fd);
|
||||
_TIFFprintAsciiBounded(fd, cp, max_chars);
|
||||
sep = ", ";
|
||||
@@ -548,17 +554,25 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
|
||||
if (TIFFFieldSet(tif, FIELD_PAGENUMBER))
|
||||
fprintf(fd, " Page Number: %" PRIu16 "-%" PRIu16 "\n",
|
||||
td->td_pagenumber[0], td->td_pagenumber[1]);
|
||||
if (TIFFFieldSet(tif, FIELD_COLORMAP))
|
||||
if (TIFFFieldSet(tif, FIELD_COLORMAP) && td->td_colormap[0] &&
|
||||
td->td_colormap[1] && td->td_colormap[2])
|
||||
{
|
||||
fprintf(fd, " Color Map: ");
|
||||
if (flags & TIFFPRINT_COLORMAP)
|
||||
{
|
||||
fprintf(fd, "\n");
|
||||
n = 1L << td->td_bitspersample;
|
||||
for (l = 0; l < n; l++)
|
||||
fprintf(fd, " %5ld: %5" PRIu16 " %5" PRIu16 " %5" PRIu16 "\n",
|
||||
l, td->td_colormap[0][l], td->td_colormap[1][l],
|
||||
td->td_colormap[2][l]);
|
||||
if (td->td_bitspersample >= 64)
|
||||
fprintf(fd, " (BitsPerSample too large to print safely)\n");
|
||||
else
|
||||
{
|
||||
uint64_t n = 1ULL << td->td_bitspersample;
|
||||
for (uint64_t l = 0u; l < n; l++)
|
||||
fprintf(fd,
|
||||
" %5" PRIu64 ": %5" PRIu16 " %5" PRIu16
|
||||
" %5" PRIu16 "\n",
|
||||
l, td->td_colormap[0][l], td->td_colormap[1][l],
|
||||
td->td_colormap[2][l]);
|
||||
}
|
||||
}
|
||||
else
|
||||
fprintf(fd, "(present)\n");
|
||||
@@ -569,26 +583,37 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
|
||||
fprintf(fd, " Reference Black/White:\n");
|
||||
for (i = 0; i < 3; i++)
|
||||
fprintf(fd, " %2d: %5g %5g\n", i,
|
||||
td->td_refblackwhite[2 * i + 0],
|
||||
td->td_refblackwhite[2 * i + 1]);
|
||||
(double)td->td_refblackwhite[2 * i + 0],
|
||||
(double)td->td_refblackwhite[2 * i + 1]);
|
||||
}
|
||||
if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION))
|
||||
if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION) &&
|
||||
td->td_transferfunction[0] &&
|
||||
((td->td_samplesperpixel - td->td_extrasamples > 1 &&
|
||||
td->td_transferfunction[1] && td->td_transferfunction[2]) ||
|
||||
td->td_samplesperpixel - td->td_extrasamples <= 1))
|
||||
{
|
||||
fprintf(fd, " Transfer Function: ");
|
||||
if (flags & TIFFPRINT_CURVES)
|
||||
{
|
||||
fprintf(fd, "\n");
|
||||
n = 1L << td->td_bitspersample;
|
||||
for (l = 0; l < n; l++)
|
||||
if (td->td_bitspersample >= 64)
|
||||
fprintf(fd, " (BitsPerSample too large to print safely)\n");
|
||||
else
|
||||
{
|
||||
uint16_t i;
|
||||
fprintf(fd, " %2ld: %5" PRIu16, l,
|
||||
td->td_transferfunction[0][l]);
|
||||
for (i = 1;
|
||||
i < td->td_samplesperpixel - td->td_extrasamples && i < 3;
|
||||
i++)
|
||||
fprintf(fd, " %5" PRIu16, td->td_transferfunction[i][l]);
|
||||
fputc('\n', fd);
|
||||
uint64_t n = 1ULL << td->td_bitspersample;
|
||||
for (uint64_t l = 0; l < n; l++)
|
||||
{
|
||||
uint16_t i;
|
||||
fprintf(fd, " %2" PRIu64 ": %5" PRIu16, l,
|
||||
td->td_transferfunction[0][l]);
|
||||
for (i = 1;
|
||||
i < td->td_samplesperpixel - td->td_extrasamples &&
|
||||
i < 3;
|
||||
i++)
|
||||
fprintf(fd, " %5" PRIu16,
|
||||
td->td_transferfunction[i][l]);
|
||||
fputc('\n', fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -655,7 +680,7 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
|
||||
else if (fip->field_readcount == TIFF_SPP)
|
||||
value_count = td->td_samplesperpixel;
|
||||
else
|
||||
value_count = fip->field_readcount;
|
||||
value_count = (uint32_t)fip->field_readcount;
|
||||
if (fip->field_tag == TIFFTAG_DOTRANGE &&
|
||||
strcmp(fip->field_name, "DotRange") == 0)
|
||||
{
|
||||
@@ -680,7 +705,8 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
|
||||
* "set_get_field_type" to determine internal storage size.
|
||||
*/
|
||||
int tv_size = TIFFFieldSetGetSize(fip);
|
||||
raw_data = _TIFFmallocExt(tif, tv_size * value_count);
|
||||
raw_data = _TIFFCheckMalloc(tif, value_count, tv_size,
|
||||
"for tag data");
|
||||
mem_alloc = 1;
|
||||
if (TIFFGetField(tif, tag, raw_data) != 1)
|
||||
{
|
||||
@@ -744,7 +770,7 @@ static void _TIFFprintAsciiBounded(FILE *fd, const char *cp, size_t max_chars)
|
||||
if (*tp)
|
||||
fprintf(fd, "\\%c", *tp);
|
||||
else
|
||||
fprintf(fd, "\\%03o", *cp & 0xff);
|
||||
fprintf(fd, "\\%03o", (unsigned int)(*cp & 0xff));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
370
3rdparty/libtiff/tif_read.c
vendored
370
3rdparty/libtiff/tif_read.c
vendored
@@ -27,6 +27,7 @@
|
||||
* Scanline-oriented Read Support
|
||||
*/
|
||||
#include "tiffiop.h"
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int TIFFFillStrip(TIFF *tif, uint32_t strip);
|
||||
@@ -39,9 +40,6 @@ static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf,
|
||||
static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf,
|
||||
tmsize_t size, const char *module);
|
||||
|
||||
#define NOSTRIP ((uint32_t)(-1)) /* undefined state */
|
||||
#define NOTILE ((uint32_t)(-1)) /* undefined state */
|
||||
|
||||
#define INITIAL_THRESHOLD (1024 * 1024)
|
||||
#define THRESHOLD_MULTIPLIER 10
|
||||
#define MAX_THRESHOLD \
|
||||
@@ -99,7 +97,9 @@ static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset,
|
||||
uint8_t *new_rawdata;
|
||||
assert((tif->tif_flags & TIFF_MYBUFFER) != 0);
|
||||
tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64(
|
||||
(uint64_t)already_read + to_read + rawdata_offset, 1024);
|
||||
(uint64_t)already_read + (uint64_t)to_read +
|
||||
(uint64_t)rawdata_offset,
|
||||
1024);
|
||||
if (tif->tif_rawdatasize == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Invalid buffer size");
|
||||
@@ -111,7 +111,7 @@ static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset,
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"No space for data buffer at scanline %" PRIu32,
|
||||
tif->tif_row);
|
||||
tif->tif_dir.td_row);
|
||||
_TIFFfreeExt(tif, tif->tif_rawdata);
|
||||
tif->tif_rawdata = 0;
|
||||
tif->tif_rawdatasize = 0;
|
||||
@@ -127,18 +127,22 @@ static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset,
|
||||
|
||||
bytes_read = TIFFReadFile(
|
||||
tif, tif->tif_rawdata + rawdata_offset + already_read, to_read);
|
||||
if (bytes_read < 0)
|
||||
/* Treat read errors as short reads before updating offsets. */
|
||||
bytes_read = 0;
|
||||
already_read += bytes_read;
|
||||
if (bytes_read != to_read)
|
||||
{
|
||||
memset(tif->tif_rawdata + rawdata_offset + already_read, 0,
|
||||
tif->tif_rawdatasize - rawdata_offset - already_read);
|
||||
memset(
|
||||
tif->tif_rawdata + rawdata_offset + already_read, 0,
|
||||
(size_t)(tif->tif_rawdatasize - rawdata_offset - already_read));
|
||||
if (is_strip)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Read error at scanline %" PRIu32
|
||||
"; got %" TIFF_SSIZE_FORMAT " bytes, "
|
||||
"expected %" TIFF_SSIZE_FORMAT,
|
||||
tif->tif_row, already_read, size);
|
||||
tif->tif_dir.td_row, already_read, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -147,8 +151,8 @@ static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset,
|
||||
", tile %" PRIu32 "; "
|
||||
"got %" TIFF_SSIZE_FORMAT
|
||||
" bytes, expected %" TIFF_SSIZE_FORMAT "",
|
||||
tif->tif_row, tif->tif_col, strip_or_tile,
|
||||
already_read, size);
|
||||
tif->tif_dir.td_row, tif->tif_dir.td_col,
|
||||
strip_or_tile, already_read, size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -160,7 +164,7 @@ static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead,
|
||||
int restart)
|
||||
{
|
||||
static const char module[] = "TIFFFillStripPartial";
|
||||
register TIFFDirectory *td = &tif->tif_dir;
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
tmsize_t unused_data;
|
||||
uint64_t read_offset;
|
||||
tmsize_t to_read;
|
||||
@@ -185,7 +189,7 @@ static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead,
|
||||
{
|
||||
assert(restart);
|
||||
|
||||
tif->tif_curstrip = NOSTRIP;
|
||||
tif->tif_dir.td_curstrip = NOSTRIP;
|
||||
if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
@@ -214,20 +218,30 @@ static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead,
|
||||
if (unused_data > 0)
|
||||
{
|
||||
assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0);
|
||||
memmove(tif->tif_rawdata, tif->tif_rawcp, unused_data);
|
||||
memmove(tif->tif_rawdata, tif->tif_rawcp, (size_t)unused_data);
|
||||
}
|
||||
|
||||
/*
|
||||
** Seek to the point in the file where more data should be read.
|
||||
*/
|
||||
read_offset = TIFFGetStrileOffset(tif, strip) + tif->tif_rawdataoff +
|
||||
tif->tif_rawdataloaded;
|
||||
read_offset = TIFFGetStrileOffset(tif, (uint32_t)strip);
|
||||
if (read_offset > UINT64_MAX - (uint64_t)tif->tif_rawdataoff ||
|
||||
read_offset + (uint64_t)tif->tif_rawdataoff >
|
||||
UINT64_MAX - (uint64_t)tif->tif_rawdataloaded)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Seek error at scanline %" PRIu32 ", strip %d",
|
||||
tif->tif_dir.td_row, strip);
|
||||
return 0;
|
||||
}
|
||||
read_offset +=
|
||||
(uint64_t)tif->tif_rawdataoff + (uint64_t)tif->tif_rawdataloaded;
|
||||
|
||||
if (!SeekOK(tif, read_offset))
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Seek error at scanline %" PRIu32 ", strip %d",
|
||||
tif->tif_row, strip);
|
||||
tif->tif_dir.td_row, strip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -238,11 +252,13 @@ static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead,
|
||||
to_read = read_ahead_mod - unused_data;
|
||||
else
|
||||
to_read = tif->tif_rawdatasize - unused_data;
|
||||
if ((uint64_t)to_read > TIFFGetStrileByteCount(tif, strip) -
|
||||
tif->tif_rawdataoff - tif->tif_rawdataloaded)
|
||||
if ((uint64_t)to_read > TIFFGetStrileByteCount(tif, (uint32_t)strip) -
|
||||
(uint64_t)tif->tif_rawdataoff -
|
||||
(uint64_t)tif->tif_rawdataloaded)
|
||||
{
|
||||
to_read = (tmsize_t)TIFFGetStrileByteCount(tif, strip) -
|
||||
tif->tif_rawdataoff - tif->tif_rawdataloaded;
|
||||
to_read = (tmsize_t)(TIFFGetStrileByteCount(tif, (uint32_t)strip) -
|
||||
(uint64_t)tif->tif_rawdataoff -
|
||||
(uint64_t)tif->tif_rawdataloaded);
|
||||
}
|
||||
|
||||
assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0);
|
||||
@@ -281,16 +297,17 @@ static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead,
|
||||
/* For JPEG, if there are multiple scans (can generally be known */
|
||||
/* with the read_ahead used), we need to read the whole strip */
|
||||
if (tif->tif_dir.td_compression == COMPRESSION_JPEG &&
|
||||
(uint64_t)tif->tif_rawcc < TIFFGetStrileByteCount(tif, strip))
|
||||
(uint64_t)tif->tif_rawcc <
|
||||
TIFFGetStrileByteCount(tif, (uint32_t)strip))
|
||||
{
|
||||
if (TIFFJPEGIsFullStripRequired(tif))
|
||||
{
|
||||
return TIFFFillStrip(tif, strip);
|
||||
return TIFFFillStrip(tif, (uint32_t)strip);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return TIFFStartStrip(tif, strip);
|
||||
return TIFFStartStrip(tif, (uint32_t)strip);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -308,7 +325,7 @@ static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead,
|
||||
*/
|
||||
static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
|
||||
{
|
||||
register TIFFDirectory *td = &tif->tif_dir;
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
uint32_t strip;
|
||||
int whole_strip;
|
||||
tmsize_t read_ahead = 0;
|
||||
@@ -323,8 +340,16 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
|
||||
td->td_imagelength);
|
||||
return (0);
|
||||
}
|
||||
if (td->td_rowsperstrip == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, tif->tif_name,
|
||||
"Cannot compute strip: RowsPerStrip is zero");
|
||||
return (0);
|
||||
}
|
||||
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
|
||||
{
|
||||
uint64_t sample_offset;
|
||||
uint64_t strip64;
|
||||
if (sample >= td->td_samplesperpixel)
|
||||
{
|
||||
TIFFErrorExtR(tif, tif->tif_name,
|
||||
@@ -332,16 +357,26 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
|
||||
sample, td->td_samplesperpixel);
|
||||
return (0);
|
||||
}
|
||||
strip = (uint32_t)sample * td->td_stripsperimage +
|
||||
row / td->td_rowsperstrip;
|
||||
sample_offset =
|
||||
_TIFFMultiply64(tif, sample, td->td_stripsperimage, "TIFFSeek");
|
||||
if (sample_offset == 0 && sample != 0 && td->td_stripsperimage != 0)
|
||||
return (0);
|
||||
strip64 = _TIFFAdd64(tif, sample_offset, row / td->td_rowsperstrip,
|
||||
"TIFFSeek");
|
||||
if (strip64 == 0 &&
|
||||
(sample_offset != 0 || (row / td->td_rowsperstrip) != 0))
|
||||
return (0);
|
||||
strip = _TIFFCastUInt64ToUInt32(tif, strip64, "TIFFSeek");
|
||||
if (strip == 0 && strip64 != 0)
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
strip = row / td->td_rowsperstrip;
|
||||
|
||||
/*
|
||||
* Do we want to treat this strip as one whole chunk or
|
||||
* read it a few lines at a time?
|
||||
*/
|
||||
/*
|
||||
* Do we want to treat this strip as one whole chunk or
|
||||
* read it a few lines at a time?
|
||||
*/
|
||||
#if defined(CHUNKY_STRIP_READ_SUPPORT)
|
||||
whole_strip = TIFFGetStrileByteCount(tif, strip) < 10 || isMapped(tif);
|
||||
if (td->td_compression == COMPRESSION_LERC ||
|
||||
@@ -359,14 +394,14 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
|
||||
/* is some constant value, for example for JPEG tables */
|
||||
|
||||
/* coverity[dead_error_line:SUPPRESS] */
|
||||
if (tif->tif_scanlinesize < TIFF_TMSIZE_T_MAX / 16 &&
|
||||
tif->tif_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000)
|
||||
if (tif->tif_dir.td_scanlinesize < TIFF_TMSIZE_T_MAX / 16 &&
|
||||
tif->tif_dir.td_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000)
|
||||
{
|
||||
read_ahead = tif->tif_scanlinesize * 16 + 5000;
|
||||
read_ahead = tif->tif_dir.td_scanlinesize * 16 + 5000;
|
||||
}
|
||||
else
|
||||
{
|
||||
read_ahead = tif->tif_scanlinesize;
|
||||
read_ahead = tif->tif_dir.td_scanlinesize;
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -377,7 +412,7 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
|
||||
* If we haven't loaded this strip, do so now, possibly
|
||||
* only reading the first part.
|
||||
*/
|
||||
if (strip != tif->tif_curstrip)
|
||||
if (strip != tif->tif_dir.td_curstrip)
|
||||
{ /* different strip, refill */
|
||||
|
||||
if (whole_strip)
|
||||
@@ -412,7 +447,7 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (row < tif->tif_row)
|
||||
if (row < tif->tif_dir.td_row)
|
||||
{
|
||||
/*
|
||||
* Moving backwards within the same strip: backup
|
||||
@@ -425,7 +460,7 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
|
||||
|
||||
if (tif->tif_rawdataoff != 0)
|
||||
{
|
||||
if (!TIFFFillStripPartial(tif, strip, read_ahead, 1))
|
||||
if (!TIFFFillStripPartial(tif, (int)strip, read_ahead, 1))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
@@ -435,7 +470,7 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
|
||||
}
|
||||
}
|
||||
|
||||
if (row != tif->tif_row)
|
||||
if (row != tif->tif_dir.td_row)
|
||||
{
|
||||
/*
|
||||
* Seek forward to the desired row.
|
||||
@@ -443,9 +478,9 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
|
||||
|
||||
/* TODO: Will this really work with partial buffers? */
|
||||
|
||||
if (!(*tif->tif_seek)(tif, row - tif->tif_row))
|
||||
if (!(*tif->tif_seek)(tif, row - tif->tif_dir.td_row))
|
||||
return (0);
|
||||
tif->tif_row = row;
|
||||
tif->tif_dir.td_row = row;
|
||||
}
|
||||
|
||||
return (1);
|
||||
@@ -462,20 +497,21 @@ int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
|
||||
/*
|
||||
* Decompress desired row into user buffer.
|
||||
*/
|
||||
e = (*tif->tif_decoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize,
|
||||
sample);
|
||||
e = (*tif->tif_decoderow)(tif, (uint8_t *)buf,
|
||||
tif->tif_dir.td_scanlinesize, sample);
|
||||
|
||||
/* we are now poised at the beginning of the next row */
|
||||
tif->tif_row = row + 1;
|
||||
tif->tif_dir.td_row = row + 1;
|
||||
|
||||
if (e)
|
||||
(*tif->tif_postdecode)(tif, (uint8_t *)buf, tif->tif_scanlinesize);
|
||||
(*tif->tif_postdecode)(tif, (uint8_t *)buf,
|
||||
tif->tif_dir.td_scanlinesize);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* See TIFFReadEncodedStrip comment regarding TIFFTAG_FAXFILLFUNC. */
|
||||
if (buf)
|
||||
memset(buf, 0, (size_t)tif->tif_scanlinesize);
|
||||
memset(buf, 0, (size_t)tif->tif_dir.td_scanlinesize);
|
||||
}
|
||||
return (e > 0 ? 1 : -1);
|
||||
}
|
||||
@@ -553,9 +589,9 @@ tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf,
|
||||
|
||||
if (!isFillOrder(tif, td->td_fillorder) &&
|
||||
(tif->tif_flags & TIFF_NOBITREV) == 0)
|
||||
TIFFReverseBits(buf, stripsize);
|
||||
TIFFReverseBits((uint8_t *)buf, stripsize);
|
||||
|
||||
(*tif->tif_postdecode)(tif, buf, stripsize);
|
||||
(*tif->tif_postdecode)(tif, (uint8_t *)buf, stripsize);
|
||||
return (stripsize);
|
||||
}
|
||||
|
||||
@@ -569,9 +605,9 @@ tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf,
|
||||
memset(buf, 0, (size_t)stripsize);
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
if ((*tif->tif_decodestrip)(tif, buf, stripsize, plane) <= 0)
|
||||
if ((*tif->tif_decodestrip)(tif, (uint8_t *)buf, stripsize, plane) <= 0)
|
||||
return ((tmsize_t)(-1));
|
||||
(*tif->tif_postdecode)(tif, buf, stripsize);
|
||||
(*tif->tif_postdecode)(tif, (uint8_t *)buf, stripsize);
|
||||
return (stripsize);
|
||||
}
|
||||
|
||||
@@ -603,17 +639,39 @@ tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif, uint32_t strip,
|
||||
if (!TIFFFillStrip(tif, strip))
|
||||
return ((tmsize_t)(-1));
|
||||
|
||||
*buf = _TIFFmallocExt(tif, bufsizetoalloc);
|
||||
/* Sanity checks to avoid excessive memory allocation */
|
||||
/* Max compression ratio experimentally determined. Might be fragile...
|
||||
* Only apply this heuristics to situations where the memory allocation
|
||||
* would be big, to avoid breaking nominal use cases.
|
||||
*/
|
||||
if (bufsizetoalloc > 100 * 1024 * 1024)
|
||||
{
|
||||
const uint64_t maxCompressionRatio = TIFFGetMaxCompressionRatio(tif);
|
||||
if (maxCompressionRatio > 0 &&
|
||||
(uint64_t)tif->tif_rawdatasize <
|
||||
(uint64_t)this_stripsize / maxCompressionRatio)
|
||||
{
|
||||
TIFFErrorExtR(tif, TIFFFileName(tif),
|
||||
"Likely invalid strip byte count for strip %u. "
|
||||
"Uncompressed strip size is %" PRIu64 ", "
|
||||
"compressed one is %" PRIu64,
|
||||
strip, (uint64_t)this_stripsize,
|
||||
(uint64_t)tif->tif_rawdatasize);
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
}
|
||||
|
||||
*buf = _TIFFcallocExt(tif, 1, bufsizetoalloc);
|
||||
if (*buf == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, TIFFFileName(tif), "No space for strip buffer");
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
_TIFFmemset(*buf, 0, bufsizetoalloc);
|
||||
|
||||
if ((*tif->tif_decodestrip)(tif, *buf, this_stripsize, plane) <= 0)
|
||||
if ((*tif->tif_decodestrip)(tif, (uint8_t *)*buf, this_stripsize, plane) <=
|
||||
0)
|
||||
return ((tmsize_t)(-1));
|
||||
(*tif->tif_postdecode)(tif, *buf, this_stripsize);
|
||||
(*tif->tif_postdecode)(tif, (uint8_t *)*buf, this_stripsize);
|
||||
return (this_stripsize);
|
||||
}
|
||||
|
||||
@@ -629,7 +687,7 @@ static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf,
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Seek error at scanline %" PRIu32 ", strip %" PRIu32,
|
||||
tif->tif_row, strip);
|
||||
tif->tif_dir.td_row, strip);
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
cc = TIFFReadFile(tif, buf, size);
|
||||
@@ -639,7 +697,7 @@ static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf,
|
||||
"Read error at scanline %" PRIu32
|
||||
"; got %" TIFF_SSIZE_FORMAT
|
||||
" bytes, expected %" TIFF_SSIZE_FORMAT,
|
||||
tif->tif_row, cc, size);
|
||||
tif->tif_dir.td_row, cc, size);
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
}
|
||||
@@ -670,7 +728,7 @@ static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf,
|
||||
"Read error at scanline %" PRIu32 ", strip %" PRIu32
|
||||
"; got %" TIFF_SSIZE_FORMAT
|
||||
" bytes, expected %" TIFF_SSIZE_FORMAT,
|
||||
tif->tif_row, strip, n, size);
|
||||
tif->tif_dir.td_row, strip, n, size);
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
_TIFFmemcpy(buf, tif->tif_base + ma, size);
|
||||
@@ -691,14 +749,14 @@ static tmsize_t TIFFReadRawStripOrTile2(TIFF *tif, uint32_t strip_or_tile,
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Seek error at scanline %" PRIu32 ", strip %" PRIu32,
|
||||
tif->tif_row, strip_or_tile);
|
||||
tif->tif_dir.td_row, strip_or_tile);
|
||||
}
|
||||
else
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Seek error at row %" PRIu32 ", col %" PRIu32
|
||||
", tile %" PRIu32,
|
||||
tif->tif_row, tif->tif_col, strip_or_tile);
|
||||
TIFFErrorExtR(
|
||||
tif, module,
|
||||
"Seek error at row %" PRIu32 ", col %" PRIu32 ", tile %" PRIu32,
|
||||
tif->tif_dir.td_row, tif->tif_dir.td_col, strip_or_tile);
|
||||
}
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
@@ -774,22 +832,50 @@ int TIFFFillStrip(TIFF *tif, uint32_t strip)
|
||||
}
|
||||
|
||||
/* To avoid excessive memory allocations: */
|
||||
/* Byte count should normally not be larger than a number of */
|
||||
/* times the uncompressed size plus some margin */
|
||||
if (bytecount > 1024 * 1024)
|
||||
const tmsize_t stripsize = TIFFStripSize(tif);
|
||||
if (stripsize > 0)
|
||||
{
|
||||
/* 10 and 4096 are just values that could be adjusted. */
|
||||
/* Hopefully they are safe enough for all codecs */
|
||||
tmsize_t stripsize = TIFFStripSize(tif);
|
||||
if (stripsize != 0 && (bytecount - 4096) / 10 > (uint64_t)stripsize)
|
||||
if (bytecount > 1024 * 1024 &&
|
||||
(bytecount - 4096) / 10 > (uint64_t)stripsize)
|
||||
{
|
||||
/* Byte count should normally not be larger than a number of */
|
||||
/* times the uncompressed size plus some margin */
|
||||
/* 10 and 4096 are just values that could be adjusted. */
|
||||
/* Hopefully they are safe enough for all codecs */
|
||||
/* What happens next will depend on whether only the bytecount
|
||||
*/
|
||||
/* was corrupted to a large value but the strip/tile data is */
|
||||
/* fine. In that situation most codecs should work fine and */
|
||||
/* only used part of the tile/strip data. If the strip/tile */
|
||||
/* data is corrupted too, then codecs will later error out. */
|
||||
uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096;
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Too large strip byte count %" PRIu64
|
||||
", strip %" PRIu32 ". Limiting to %" PRIu64,
|
||||
bytecount, strip, newbytecount);
|
||||
TIFFWarningExtR(tif, module,
|
||||
"Too large strip byte count %" PRIu64
|
||||
", strip %" PRIu32 ". Limiting to %" PRIu64,
|
||||
bytecount, strip, newbytecount);
|
||||
bytecount = newbytecount;
|
||||
}
|
||||
else if (stripsize > 100 * 1024 * 1024)
|
||||
{
|
||||
/* Max compression ratio experimentally determined. Might be
|
||||
* fragile... Only apply this heuristics to situations where the
|
||||
* memory allocation would be big, to avoid breaking nominal use
|
||||
* cases.
|
||||
*/
|
||||
const uint64_t maxCompressionRatio =
|
||||
TIFFGetMaxCompressionRatio(tif);
|
||||
if (maxCompressionRatio > 0 &&
|
||||
bytecount < (uint64_t)stripsize / maxCompressionRatio)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
tif, module,
|
||||
"Likely invalid strip byte count for strip %u. "
|
||||
"Uncompressed strip size is %" PRIu64 ", "
|
||||
"compressed one is %" PRIu64,
|
||||
strip, (uint64_t)stripsize, bytecount);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isMapped(tif))
|
||||
@@ -818,10 +904,10 @@ int TIFFFillStrip(TIFF *tif, uint32_t strip)
|
||||
"Read error on strip %" PRIu32 "; "
|
||||
"got %" PRIu64 " bytes, expected %" PRIu64,
|
||||
strip,
|
||||
NoSanitizeSubUInt64(tif->tif_size,
|
||||
NoSanitizeSubUInt64((uint64_t)tif->tif_size,
|
||||
TIFFGetStrileOffset(tif, strip)),
|
||||
bytecount);
|
||||
tif->tif_curstrip = NOSTRIP;
|
||||
tif->tif_dir.td_curstrip = NOSTRIP;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
@@ -878,7 +964,7 @@ int TIFFFillStrip(TIFF *tif, uint32_t strip)
|
||||
}
|
||||
if (bytecountm > tif->tif_rawdatasize)
|
||||
{
|
||||
tif->tif_curstrip = NOSTRIP;
|
||||
tif->tif_dir.td_curstrip = NOSTRIP;
|
||||
if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
@@ -889,7 +975,7 @@ int TIFFFillStrip(TIFF *tif, uint32_t strip)
|
||||
}
|
||||
if (tif->tif_flags & TIFF_BUFFERMMAP)
|
||||
{
|
||||
tif->tif_curstrip = NOSTRIP;
|
||||
tif->tif_dir.td_curstrip = NOSTRIP;
|
||||
tif->tif_rawdata = NULL;
|
||||
tif->tif_rawdatasize = 0;
|
||||
tif->tif_flags &= ~TIFF_BUFFERMMAP;
|
||||
@@ -954,7 +1040,7 @@ tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size)
|
||||
{
|
||||
static const char module[] = "TIFFReadEncodedTile";
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
tmsize_t tilesize = tif->tif_tilesize;
|
||||
tmsize_t tilesize = tif->tif_dir.td_tilesize;
|
||||
|
||||
if (!TIFFCheckRead(tif, 1))
|
||||
return ((tmsize_t)(-1));
|
||||
@@ -976,9 +1062,9 @@ tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size)
|
||||
|
||||
if (!isFillOrder(tif, td->td_fillorder) &&
|
||||
(tif->tif_flags & TIFF_NOBITREV) == 0)
|
||||
TIFFReverseBits(buf, tilesize);
|
||||
TIFFReverseBits((uint8_t *)buf, tilesize);
|
||||
|
||||
(*tif->tif_postdecode)(tif, buf, tilesize);
|
||||
(*tif->tif_postdecode)(tif, (uint8_t *)buf, tilesize);
|
||||
return (tilesize);
|
||||
}
|
||||
|
||||
@@ -1032,7 +1118,7 @@ tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile,
|
||||
{
|
||||
static const char module[] = "_TIFFReadEncodedTileAndAllocBuffer";
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
tmsize_t tilesize = tif->tif_tilesize;
|
||||
tmsize_t tilesize = tif->tif_dir.td_tilesize;
|
||||
|
||||
if (*buf != NULL)
|
||||
{
|
||||
@@ -1072,25 +1158,22 @@ tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile,
|
||||
* Only apply this heuristics to situations where the memory allocation
|
||||
* would be big, to avoid breaking nominal use cases.
|
||||
*/
|
||||
const int maxCompressionRatio =
|
||||
td->td_compression == COMPRESSION_ZSTD ? 33000
|
||||
: td->td_compression == COMPRESSION_JXL
|
||||
?
|
||||
/* Evaluated on a 8000x8000 tile */
|
||||
25000 * (td->td_planarconfig == PLANARCONFIG_CONTIG
|
||||
? td->td_samplesperpixel
|
||||
: 1)
|
||||
: td->td_compression == COMPRESSION_LZMA ? 7000 : 1000;
|
||||
if (bufsizetoalloc > 100 * 1000 * 1000 &&
|
||||
tif->tif_rawdatasize < tilesize / maxCompressionRatio)
|
||||
if (bufsizetoalloc > 100 * 1024 * 1024)
|
||||
{
|
||||
TIFFErrorExtR(tif, TIFFFileName(tif),
|
||||
"Likely invalid tile byte count for tile %u. "
|
||||
"Uncompressed tile size is %" PRIu64 ", "
|
||||
"compressed one is %" PRIu64,
|
||||
tile, (uint64_t)tilesize,
|
||||
(uint64_t)tif->tif_rawdatasize);
|
||||
return ((tmsize_t)(-1));
|
||||
const uint64_t maxCompressionRatio =
|
||||
TIFFGetMaxCompressionRatio(tif);
|
||||
if (maxCompressionRatio > 0 &&
|
||||
(uint64_t)tif->tif_rawdatasize <
|
||||
(uint64_t)tilesize / maxCompressionRatio)
|
||||
{
|
||||
TIFFErrorExtR(tif, TIFFFileName(tif),
|
||||
"Likely invalid tile byte count for tile %u. "
|
||||
"Uncompressed tile size is %" PRIu64 ", "
|
||||
"compressed one is %" PRIu64,
|
||||
tile, (uint64_t)tilesize,
|
||||
(uint64_t)tif->tif_rawdatasize);
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1129,7 +1212,7 @@ static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf,
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Seek error at row %" PRIu32 ", col %" PRIu32
|
||||
", tile %" PRIu32,
|
||||
tif->tif_row, tif->tif_col, tile);
|
||||
tif->tif_dir.td_row, tif->tif_dir.td_col, tile);
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
cc = TIFFReadFile(tif, buf, size);
|
||||
@@ -1139,7 +1222,7 @@ static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf,
|
||||
"Read error at row %" PRIu32 ", col %" PRIu32
|
||||
"; got %" TIFF_SSIZE_FORMAT
|
||||
" bytes, expected %" TIFF_SSIZE_FORMAT,
|
||||
tif->tif_row, tif->tif_col, cc, size);
|
||||
tif->tif_dir.td_row, tif->tif_dir.td_col, cc, size);
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
}
|
||||
@@ -1162,7 +1245,8 @@ static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf,
|
||||
"Read error at row %" PRIu32 ", col %" PRIu32
|
||||
", tile %" PRIu32 "; got %" TIFF_SSIZE_FORMAT
|
||||
" bytes, expected %" TIFF_SSIZE_FORMAT,
|
||||
tif->tif_row, tif->tif_col, tile, n, size);
|
||||
tif->tif_dir.td_row, tif->tif_dir.td_col, tile, n,
|
||||
size);
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
_TIFFmemcpy(buf, tif->tif_base + ma, size);
|
||||
@@ -1229,22 +1313,49 @@ int TIFFFillTile(TIFF *tif, uint32_t tile)
|
||||
}
|
||||
|
||||
/* To avoid excessive memory allocations: */
|
||||
/* Byte count should normally not be larger than a number of */
|
||||
/* times the uncompressed size plus some margin */
|
||||
if (bytecount > 1024 * 1024)
|
||||
const tmsize_t tilesize = TIFFTileSize(tif);
|
||||
if (tilesize > 0)
|
||||
{
|
||||
/* 10 and 4096 are just values that could be adjusted. */
|
||||
/* Hopefully they are safe enough for all codecs */
|
||||
tmsize_t stripsize = TIFFTileSize(tif);
|
||||
if (stripsize != 0 && (bytecount - 4096) / 10 > (uint64_t)stripsize)
|
||||
if (bytecount > 1024 * 1024 &&
|
||||
(bytecount - 4096) / 10 > (uint64_t)tilesize)
|
||||
{
|
||||
uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096;
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Too large tile byte count %" PRIu64
|
||||
", tile %" PRIu32 ". Limiting to %" PRIu64,
|
||||
bytecount, tile, newbytecount);
|
||||
/* Byte count should normally not be larger than a number of */
|
||||
/* times the uncompressed size plus some margin */
|
||||
/* 10 and 4096 are just values that could be adjusted. */
|
||||
/* Hopefully they are safe enough for all codecs */
|
||||
/* What happens next will depend on whether only the bytecount
|
||||
*/
|
||||
/* was corrupted to a large value but the strip/tile data is */
|
||||
/* fine. In that situation most codecs should work fine and */
|
||||
/* only used part of the tile/strip data. If the strip/tile */
|
||||
/* data is corrupted too, then codecs will later error out. */
|
||||
uint64_t newbytecount = (uint64_t)tilesize * 10 + 4096;
|
||||
TIFFWarningExtR(tif, module,
|
||||
"Too large tile byte count %" PRIu64
|
||||
", tile %" PRIu32 ". Limiting to %" PRIu64,
|
||||
bytecount, tile, newbytecount);
|
||||
bytecount = newbytecount;
|
||||
}
|
||||
else if (tilesize > 100 * 1024 * 1024)
|
||||
{
|
||||
/* Max compression ratio experimentally determined. Might be
|
||||
* fragile... Only apply this heuristics to situations where the
|
||||
* memory allocation would be big, to avoid breaking nominal use
|
||||
* cases.
|
||||
*/
|
||||
const uint64_t maxCompressionRatio =
|
||||
TIFFGetMaxCompressionRatio(tif);
|
||||
if (maxCompressionRatio > 0 &&
|
||||
bytecount < (uint64_t)tilesize / maxCompressionRatio)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Likely invalid tile byte count for tile %u. "
|
||||
"Uncompressed tile size is %" PRIu64 ", "
|
||||
"compressed one is %" PRIu64,
|
||||
tile, (uint64_t)tilesize, bytecount);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isMapped(tif))
|
||||
@@ -1262,7 +1373,7 @@ int TIFFFillTile(TIFF *tif, uint32_t tile)
|
||||
TIFFGetStrileOffset(tif, tile) >
|
||||
(uint64_t)tif->tif_size - bytecount)
|
||||
{
|
||||
tif->tif_curtile = NOTILE;
|
||||
tif->tif_dir.td_curtile = NOTILE;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
@@ -1312,7 +1423,7 @@ int TIFFFillTile(TIFF *tif, uint32_t tile)
|
||||
}
|
||||
if (bytecountm > tif->tif_rawdatasize)
|
||||
{
|
||||
tif->tif_curtile = NOTILE;
|
||||
tif->tif_dir.td_curtile = NOTILE;
|
||||
if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
@@ -1323,7 +1434,7 @@ int TIFFFillTile(TIFF *tif, uint32_t tile)
|
||||
}
|
||||
if (tif->tif_flags & TIFF_BUFFERMMAP)
|
||||
{
|
||||
tif->tif_curtile = NOTILE;
|
||||
tif->tif_dir.td_curtile = NOTILE;
|
||||
tif->tif_rawdata = NULL;
|
||||
tif->tif_rawdatasize = 0;
|
||||
tif->tif_flags &= ~TIFF_BUFFERMMAP;
|
||||
@@ -1410,7 +1521,7 @@ int TIFFReadBufferSetup(TIFF *tif, void *bp, tmsize_t size)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"No space for data buffer at scanline %" PRIu32,
|
||||
tif->tif_row);
|
||||
tif->tif_dir.td_row);
|
||||
tif->tif_rawdatasize = 0;
|
||||
return (0);
|
||||
}
|
||||
@@ -1431,8 +1542,13 @@ static int TIFFStartStrip(TIFF *tif, uint32_t strip)
|
||||
return (0);
|
||||
tif->tif_flags |= TIFF_CODERSETUP;
|
||||
}
|
||||
tif->tif_curstrip = strip;
|
||||
tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
|
||||
if (td->td_stripsperimage == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, "TIFFStartStrip", "Zero strips per image");
|
||||
return 0;
|
||||
}
|
||||
tif->tif_dir.td_curstrip = strip;
|
||||
tif->tif_dir.td_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
|
||||
tif->tif_flags &= ~TIFF_BUF4WRITE;
|
||||
|
||||
if (tif->tif_flags & TIFF_NOREADRAW)
|
||||
@@ -1456,7 +1572,7 @@ static int TIFFStartStrip(TIFF *tif, uint32_t strip)
|
||||
*/
|
||||
/* tif_curstrip, we'd call tif_decoderow() on a possibly invalid */
|
||||
/* codec state. */
|
||||
tif->tif_curstrip = NOSTRIP;
|
||||
tif->tif_dir.td_curstrip = NOSTRIP;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -1478,7 +1594,7 @@ static int TIFFStartTile(TIFF *tif, uint32_t tile)
|
||||
return (0);
|
||||
tif->tif_flags |= TIFF_CODERSETUP;
|
||||
}
|
||||
tif->tif_curtile = tile;
|
||||
tif->tif_dir.td_curtile = tile;
|
||||
if (td->td_tilewidth == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Zero tilewidth");
|
||||
@@ -1490,14 +1606,14 @@ static int TIFFStartTile(TIFF *tif, uint32_t tile)
|
||||
TIFFErrorExtR(tif, module, "Zero tiles");
|
||||
return 0;
|
||||
}
|
||||
tif->tif_row = (tile % howmany32) * td->td_tilelength;
|
||||
tif->tif_dir.td_row = (tile % howmany32) * td->td_tilelength;
|
||||
howmany32 = TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
|
||||
if (howmany32 == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Zero tiles");
|
||||
return 0;
|
||||
}
|
||||
tif->tif_col = (tile % howmany32) * td->td_tilewidth;
|
||||
tif->tif_dir.td_col = (tile % howmany32) * td->td_tilewidth;
|
||||
tif->tif_flags &= ~TIFF_BUF4WRITE;
|
||||
if (tif->tif_flags & TIFF_NOREADRAW)
|
||||
{
|
||||
@@ -1568,14 +1684,14 @@ int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf,
|
||||
tif->tif_flags &= ~TIFF_MYBUFFER;
|
||||
tif->tif_flags |= TIFF_BUFFERMMAP;
|
||||
tif->tif_rawdatasize = insize;
|
||||
tif->tif_rawdata = inbuf;
|
||||
tif->tif_rawdata = (uint8_t *)inbuf;
|
||||
tif->tif_rawdataoff = 0;
|
||||
tif->tif_rawdataloaded = insize;
|
||||
|
||||
if (!isFillOrder(tif, td->td_fillorder) &&
|
||||
(tif->tif_flags & TIFF_NOBITREV) == 0)
|
||||
{
|
||||
TIFFReverseBits(inbuf, insize);
|
||||
TIFFReverseBits((uint8_t *)inbuf, insize);
|
||||
}
|
||||
|
||||
if (TIFFIsTiled(tif))
|
||||
@@ -1632,13 +1748,13 @@ int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf,
|
||||
if (!isFillOrder(tif, td->td_fillorder) &&
|
||||
(tif->tif_flags & TIFF_NOBITREV) == 0)
|
||||
{
|
||||
TIFFReverseBits(inbuf, insize);
|
||||
TIFFReverseBits((uint8_t *)inbuf, insize);
|
||||
}
|
||||
|
||||
tif->tif_flags = (old_tif_flags & (TIFF_MYBUFFER | TIFF_BUFFERMMAP)) |
|
||||
(tif->tif_flags & ~(TIFF_MYBUFFER | TIFF_BUFFERMMAP));
|
||||
tif->tif_rawdatasize = old_rawdatasize;
|
||||
tif->tif_rawdata = old_rawdata;
|
||||
tif->tif_rawdata = (uint8_t *)old_rawdata;
|
||||
tif->tif_rawdataoff = 0;
|
||||
tif->tif_rawdataloaded = 0;
|
||||
|
||||
|
||||
56
3rdparty/libtiff/tif_strip.c
vendored
56
3rdparty/libtiff/tif_strip.c
vendored
@@ -47,6 +47,8 @@ uint32_t TIFFComputeStrip(TIFF *tif, uint32_t row, uint16_t sample)
|
||||
strip = row / td->td_rowsperstrip;
|
||||
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
|
||||
{
|
||||
uint64_t sample_offset;
|
||||
uint64_t strip64;
|
||||
if (sample >= td->td_samplesperpixel)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu",
|
||||
@@ -54,7 +56,16 @@ uint32_t TIFFComputeStrip(TIFF *tif, uint32_t row, uint16_t sample)
|
||||
(unsigned long)td->td_samplesperpixel);
|
||||
return (0);
|
||||
}
|
||||
strip += (uint32_t)sample * td->td_stripsperimage;
|
||||
sample_offset = _TIFFMultiply64(tif, sample, td->td_stripsperimage,
|
||||
"TIFFComputeStrip");
|
||||
if (sample_offset == 0 && sample != 0 && td->td_stripsperimage != 0)
|
||||
return (0);
|
||||
strip64 = _TIFFAdd64(tif, sample_offset, strip, "TIFFComputeStrip");
|
||||
if (strip64 == 0 && (sample_offset != 0 || strip != 0))
|
||||
return (0);
|
||||
strip = _TIFFCastUInt64ToUInt32(tif, strip64, "TIFFComputeStrip");
|
||||
if (strip == 0 && strip64 != 0)
|
||||
return (0);
|
||||
}
|
||||
return (strip);
|
||||
}
|
||||
@@ -83,14 +94,24 @@ uint32_t TIFFNumberOfStrips(TIFF *tif)
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the # bytes in a variable height, row-aligned strip.
|
||||
* Compute the # bytes in a variable height, row-aligned strip if isStrip is
|
||||
* TRUE, or in a tile if isStrip is FALSE
|
||||
*/
|
||||
uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows)
|
||||
uint64_t _TIFFStrileSize64(TIFF *tif, uint32_t nrows, int isStrip)
|
||||
{
|
||||
static const char module[] = "TIFFVStripSize64";
|
||||
static const char module[] = "_TIFFStrileSize64";
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
if (nrows == (uint32_t)(-1))
|
||||
nrows = td->td_imagelength;
|
||||
if (isStrip)
|
||||
{
|
||||
if (nrows == (uint32_t)(-1))
|
||||
nrows = td->td_imagelength;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (td->td_tilelength == 0 || td->td_tilewidth == 0 ||
|
||||
td->td_tiledepth == 0)
|
||||
return (0);
|
||||
}
|
||||
if ((td->td_planarconfig == PLANARCONFIG_CONTIG) &&
|
||||
(td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif)))
|
||||
{
|
||||
@@ -125,9 +146,10 @@ uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows)
|
||||
ycbcrsubsampling[0], ycbcrsubsampling[1]);
|
||||
return 0;
|
||||
}
|
||||
samplingblock_samples = ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2;
|
||||
samplingblocks_hor =
|
||||
TIFFhowmany_32(td->td_imagewidth, ycbcrsubsampling[0]);
|
||||
samplingblock_samples =
|
||||
(uint16_t)(ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2);
|
||||
const uint32_t width = isStrip ? td->td_imagewidth : td->td_tilewidth;
|
||||
samplingblocks_hor = TIFFhowmany_32(width, ycbcrsubsampling[0]);
|
||||
samplingblocks_ver = TIFFhowmany_32(nrows, ycbcrsubsampling[1]);
|
||||
samplingrow_samples = _TIFFMultiply64(tif, samplingblocks_hor,
|
||||
samplingblock_samples, module);
|
||||
@@ -137,8 +159,20 @@ uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows)
|
||||
_TIFFMultiply64(tif, samplingrow_size, samplingblocks_ver, module));
|
||||
}
|
||||
else
|
||||
return (_TIFFMultiply64(tif, nrows, TIFFScanlineSize64(tif), module));
|
||||
return (_TIFFMultiply64(tif, nrows,
|
||||
isStrip ? TIFFScanlineSize64(tif)
|
||||
: TIFFTileRowSize64(tif),
|
||||
module));
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the # bytes in a variable height, row-aligned strip.
|
||||
*/
|
||||
uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows)
|
||||
{
|
||||
return _TIFFStrileSize64(tif, nrows, /* isStrip = */ TRUE);
|
||||
}
|
||||
|
||||
tmsize_t TIFFVStripSize(TIFF *tif, uint32_t nrows)
|
||||
{
|
||||
static const char module[] = "TIFFVStripSize";
|
||||
@@ -286,7 +320,7 @@ uint64_t TIFFScanlineSize64(TIFF *tif)
|
||||
return 0;
|
||||
}
|
||||
samplingblock_samples =
|
||||
ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2;
|
||||
(uint16_t)(ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2);
|
||||
samplingblocks_hor =
|
||||
TIFFhowmany_32(td->td_imagewidth, ycbcrsubsampling[0]);
|
||||
samplingrow_samples = _TIFFMultiply64(
|
||||
|
||||
40
3rdparty/libtiff/tif_swab.c
vendored
40
3rdparty/libtiff/tif_swab.c
vendored
@@ -32,7 +32,7 @@
|
||||
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabShort)
|
||||
void TIFFSwabShort(uint16_t *wp)
|
||||
{
|
||||
register unsigned char *cp = (unsigned char *)wp;
|
||||
unsigned char *cp = (unsigned char *)wp;
|
||||
unsigned char t;
|
||||
assert(sizeof(uint16_t) == 2);
|
||||
t = cp[1];
|
||||
@@ -44,7 +44,7 @@ void TIFFSwabShort(uint16_t *wp)
|
||||
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong)
|
||||
void TIFFSwabLong(uint32_t *lp)
|
||||
{
|
||||
register unsigned char *cp = (unsigned char *)lp;
|
||||
unsigned char *cp = (unsigned char *)lp;
|
||||
unsigned char t;
|
||||
assert(sizeof(uint32_t) == 4);
|
||||
t = cp[3];
|
||||
@@ -59,7 +59,7 @@ void TIFFSwabLong(uint32_t *lp)
|
||||
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong8)
|
||||
void TIFFSwabLong8(uint64_t *lp)
|
||||
{
|
||||
register unsigned char *cp = (unsigned char *)lp;
|
||||
unsigned char *cp = (unsigned char *)lp;
|
||||
unsigned char t;
|
||||
assert(sizeof(uint64_t) == 8);
|
||||
t = cp[7];
|
||||
@@ -78,10 +78,10 @@ void TIFFSwabLong8(uint64_t *lp)
|
||||
#endif
|
||||
|
||||
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfShort)
|
||||
void TIFFSwabArrayOfShort(register uint16_t *wp, tmsize_t n)
|
||||
void TIFFSwabArrayOfShort(uint16_t *wp, tmsize_t n)
|
||||
{
|
||||
register unsigned char *cp;
|
||||
register unsigned char t;
|
||||
unsigned char *cp;
|
||||
unsigned char t;
|
||||
assert(sizeof(uint16_t) == 2);
|
||||
/* XXX unroll loop some */
|
||||
while (n-- > 0)
|
||||
@@ -96,7 +96,7 @@ void TIFFSwabArrayOfShort(register uint16_t *wp, tmsize_t n)
|
||||
#endif
|
||||
|
||||
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfTriples)
|
||||
void TIFFSwabArrayOfTriples(register uint8_t *tp, tmsize_t n)
|
||||
void TIFFSwabArrayOfTriples(uint8_t *tp, tmsize_t n)
|
||||
{
|
||||
unsigned char *cp;
|
||||
unsigned char t;
|
||||
@@ -114,10 +114,10 @@ void TIFFSwabArrayOfTriples(register uint8_t *tp, tmsize_t n)
|
||||
#endif
|
||||
|
||||
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong)
|
||||
void TIFFSwabArrayOfLong(register uint32_t *lp, tmsize_t n)
|
||||
void TIFFSwabArrayOfLong(uint32_t *lp, tmsize_t n)
|
||||
{
|
||||
register unsigned char *cp;
|
||||
register unsigned char t;
|
||||
unsigned char *cp;
|
||||
unsigned char t;
|
||||
assert(sizeof(uint32_t) == 4);
|
||||
/* XXX unroll loop some */
|
||||
while (n-- > 0)
|
||||
@@ -135,10 +135,10 @@ void TIFFSwabArrayOfLong(register uint32_t *lp, tmsize_t n)
|
||||
#endif
|
||||
|
||||
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong8)
|
||||
void TIFFSwabArrayOfLong8(register uint64_t *lp, tmsize_t n)
|
||||
void TIFFSwabArrayOfLong8(uint64_t *lp, tmsize_t n)
|
||||
{
|
||||
register unsigned char *cp;
|
||||
register unsigned char t;
|
||||
unsigned char *cp;
|
||||
unsigned char t;
|
||||
assert(sizeof(uint64_t) == 8);
|
||||
/* XXX unroll loop some */
|
||||
while (n-- > 0)
|
||||
@@ -164,7 +164,7 @@ void TIFFSwabArrayOfLong8(register uint64_t *lp, tmsize_t n)
|
||||
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabFloat)
|
||||
void TIFFSwabFloat(float *fp)
|
||||
{
|
||||
register unsigned char *cp = (unsigned char *)fp;
|
||||
unsigned char *cp = (unsigned char *)fp;
|
||||
unsigned char t;
|
||||
assert(sizeof(float) == 4);
|
||||
t = cp[3];
|
||||
@@ -177,10 +177,10 @@ void TIFFSwabFloat(float *fp)
|
||||
#endif
|
||||
|
||||
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfFloat)
|
||||
void TIFFSwabArrayOfFloat(register float *fp, tmsize_t n)
|
||||
void TIFFSwabArrayOfFloat(float *fp, tmsize_t n)
|
||||
{
|
||||
register unsigned char *cp;
|
||||
register unsigned char t;
|
||||
unsigned char *cp;
|
||||
unsigned char t;
|
||||
assert(sizeof(float) == 4);
|
||||
/* XXX unroll loop some */
|
||||
while (n-- > 0)
|
||||
@@ -200,7 +200,7 @@ void TIFFSwabArrayOfFloat(register float *fp, tmsize_t n)
|
||||
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabDouble)
|
||||
void TIFFSwabDouble(double *dp)
|
||||
{
|
||||
register unsigned char *cp = (unsigned char *)dp;
|
||||
unsigned char *cp = (unsigned char *)dp;
|
||||
unsigned char t;
|
||||
assert(sizeof(double) == 8);
|
||||
t = cp[7];
|
||||
@@ -221,8 +221,8 @@ void TIFFSwabDouble(double *dp)
|
||||
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfDouble)
|
||||
void TIFFSwabArrayOfDouble(double *dp, tmsize_t n)
|
||||
{
|
||||
register unsigned char *cp;
|
||||
register unsigned char t;
|
||||
unsigned char *cp;
|
||||
unsigned char t;
|
||||
assert(sizeof(double) == 8);
|
||||
/* XXX unroll loop some */
|
||||
while (n-- > 0)
|
||||
|
||||
22
3rdparty/libtiff/tif_thunder.c
vendored
22
3rdparty/libtiff/tif_thunder.c
vendored
@@ -41,7 +41,7 @@
|
||||
* or 3-bit delta values are used, with the deltas packed
|
||||
* into a single byte.
|
||||
*/
|
||||
#define THUNDER_DATA 0x3f /* mask for 6-bit data */
|
||||
// #define THUNDER_DATA 0x3f /* mask for 6-bit data */
|
||||
#define THUNDER_CODE 0xc0 /* mask for 2-bit code word */
|
||||
/* code values */
|
||||
#define THUNDER_RUN 0x00 /* run of pixels w/ encoded count */
|
||||
@@ -56,11 +56,11 @@ static const int threebitdeltas[8] = {0, 1, 2, 3, 0, -3, -2, -1};
|
||||
|
||||
#define SETPIXEL(op, v) \
|
||||
{ \
|
||||
lastpixel = (v)&0xf; \
|
||||
lastpixel = (v) & 0xf; \
|
||||
if (npixels < maxpixels) \
|
||||
{ \
|
||||
if (npixels++ & 1) \
|
||||
*op++ |= lastpixel; \
|
||||
*op++ |= (uint8_t)lastpixel; \
|
||||
else \
|
||||
op[0] = (uint8_t)(lastpixel << 4); \
|
||||
} \
|
||||
@@ -85,8 +85,8 @@ static int ThunderSetupDecode(TIFF *tif)
|
||||
static int ThunderDecode(TIFF *tif, uint8_t *op0, tmsize_t maxpixels)
|
||||
{
|
||||
static const char module[] = "ThunderDecode";
|
||||
register unsigned char *bp;
|
||||
register tmsize_t cc;
|
||||
unsigned char *bp;
|
||||
tmsize_t cc;
|
||||
unsigned int lastpixel;
|
||||
tmsize_t npixels;
|
||||
uint8_t *op = op0;
|
||||
@@ -112,7 +112,7 @@ static int ThunderDecode(TIFF *tif, uint8_t *op0, tmsize_t maxpixels)
|
||||
break;
|
||||
if (npixels & 1)
|
||||
{
|
||||
op[0] |= lastpixel;
|
||||
op[0] |= (uint8_t)lastpixel;
|
||||
lastpixel = *op++;
|
||||
npixels++;
|
||||
n--;
|
||||
@@ -150,6 +150,8 @@ static int ThunderDecode(TIFF *tif, uint8_t *op0, tmsize_t maxpixels)
|
||||
case THUNDER_RAW: /* raw data */
|
||||
SETPIXEL(op, n);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
tif->tif_rawcp = (uint8_t *)bp;
|
||||
@@ -161,7 +163,7 @@ static int ThunderDecode(TIFF *tif, uint8_t *op0, tmsize_t maxpixels)
|
||||
TIFFErrorExtR(tif, module,
|
||||
"%s data at scanline %lu (%" PRIu64 " != %" PRIu64 ")",
|
||||
npixels < maxpixels ? "Not enough" : "Too much",
|
||||
(unsigned long)tif->tif_row, (uint64_t)npixels,
|
||||
(unsigned long)tif->tif_dir.td_row, (uint64_t)npixels,
|
||||
(uint64_t)maxpixels);
|
||||
return (0);
|
||||
}
|
||||
@@ -175,7 +177,7 @@ static int ThunderDecodeRow(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
||||
uint8_t *row = buf;
|
||||
|
||||
(void)s;
|
||||
if (occ % tif->tif_scanlinesize)
|
||||
if (occ % tif->tif_dir.td_scanlinesize)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
|
||||
return (0);
|
||||
@@ -184,8 +186,8 @@ static int ThunderDecodeRow(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
|
||||
{
|
||||
if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth))
|
||||
return (0);
|
||||
occ -= tif->tif_scanlinesize;
|
||||
row += tif->tif_scanlinesize;
|
||||
occ -= tif->tif_dir.td_scanlinesize;
|
||||
row += tif->tif_dir.td_scanlinesize;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
95
3rdparty/libtiff/tif_tile.c
vendored
95
3rdparty/libtiff/tif_tile.c
vendored
@@ -54,12 +54,50 @@ uint32_t TIFFComputeTile(TIFF *tif, uint32_t x, uint32_t y, uint32_t z,
|
||||
uint32_t xpt = TIFFhowmany_32(td->td_imagewidth, dx);
|
||||
uint32_t ypt = TIFFhowmany_32(td->td_imagelength, dy);
|
||||
uint32_t zpt = TIFFhowmany_32(td->td_imagedepth, dz);
|
||||
uint32_t xpt_ypt = _TIFFMultiply32(tif, xpt, ypt, "TIFFComputeTile");
|
||||
uint32_t xpt_ypt_zpt =
|
||||
_TIFFMultiply32(tif, xpt_ypt, zpt, "TIFFComputeTile");
|
||||
uint64_t z_offset;
|
||||
uint64_t y_offset;
|
||||
uint64_t tile64;
|
||||
|
||||
if ((xpt_ypt == 0 && xpt != 0 && ypt != 0) ||
|
||||
(xpt_ypt_zpt == 0 && xpt_ypt != 0 && zpt != 0))
|
||||
return (0);
|
||||
|
||||
z_offset = _TIFFMultiply64(tif, xpt_ypt, z / dz, "TIFFComputeTile");
|
||||
y_offset = _TIFFMultiply64(tif, xpt, y / dy, "TIFFComputeTile");
|
||||
if ((z_offset == 0 && xpt_ypt != 0 && (z / dz) != 0) ||
|
||||
(y_offset == 0 && xpt != 0 && (y / dy) != 0))
|
||||
return (0);
|
||||
tile64 = _TIFFAdd64(tif, z_offset, y_offset, "TIFFComputeTile");
|
||||
if (tile64 == 0 && (z_offset != 0 || y_offset != 0))
|
||||
return (0);
|
||||
tile64 = _TIFFAdd64(tif, tile64, x / dx, "TIFFComputeTile");
|
||||
if (tile64 == 0 && (z_offset != 0 || y_offset != 0 || (x / dx) != 0))
|
||||
return (0);
|
||||
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
|
||||
tile = (xpt * ypt * zpt) * s + (xpt * ypt) * (z / dz) +
|
||||
xpt * (y / dy) + x / dx;
|
||||
else
|
||||
tile = (xpt * ypt) * (z / dz) + xpt * (y / dy) + x / dx;
|
||||
{
|
||||
uint64_t sample_offset;
|
||||
if (s >= td->td_samplesperpixel)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
tif, "TIFFComputeTile", "%lu: Sample out of range, max %lu",
|
||||
(unsigned long)s, (unsigned long)td->td_samplesperpixel);
|
||||
return (0);
|
||||
}
|
||||
sample_offset =
|
||||
_TIFFMultiply64(tif, xpt_ypt_zpt, s, "TIFFComputeTile");
|
||||
if (sample_offset == 0 && xpt_ypt_zpt != 0 && s != 0)
|
||||
return (0);
|
||||
tile64 = _TIFFAdd64(tif, sample_offset, tile64, "TIFFComputeTile");
|
||||
if (tile64 == 0 && (sample_offset != 0 || z_offset != 0 ||
|
||||
y_offset != 0 || (x / dx) != 0))
|
||||
return (0);
|
||||
}
|
||||
tile = _TIFFCastUInt64ToUInt32(tif, tile64, "TIFFComputeTile");
|
||||
if (tile == 0 && tile64 != 0)
|
||||
return (0);
|
||||
}
|
||||
return (tile);
|
||||
}
|
||||
@@ -187,54 +225,9 @@ tmsize_t TIFFTileRowSize(TIFF *tif)
|
||||
*/
|
||||
uint64_t TIFFVTileSize64(TIFF *tif, uint32_t nrows)
|
||||
{
|
||||
static const char module[] = "TIFFVTileSize64";
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
if (td->td_tilelength == 0 || td->td_tilewidth == 0 ||
|
||||
td->td_tiledepth == 0)
|
||||
return (0);
|
||||
if ((td->td_planarconfig == PLANARCONFIG_CONTIG) &&
|
||||
(td->td_photometric == PHOTOMETRIC_YCBCR) &&
|
||||
(td->td_samplesperpixel == 3) && (!isUpSampled(tif)))
|
||||
{
|
||||
/*
|
||||
* Packed YCbCr data contain one Cb+Cr for every
|
||||
* HorizontalSampling*VerticalSampling Y values.
|
||||
* Must also roundup width and height when calculating
|
||||
* since images that are not a multiple of the
|
||||
* horizontal/vertical subsampling area include
|
||||
* YCbCr data for the extended image.
|
||||
*/
|
||||
uint16_t ycbcrsubsampling[2];
|
||||
uint16_t samplingblock_samples;
|
||||
uint32_t samplingblocks_hor;
|
||||
uint32_t samplingblocks_ver;
|
||||
uint64_t samplingrow_samples;
|
||||
uint64_t samplingrow_size;
|
||||
TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
|
||||
ycbcrsubsampling + 0, ycbcrsubsampling + 1);
|
||||
if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 &&
|
||||
ycbcrsubsampling[0] != 4) ||
|
||||
(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 &&
|
||||
ycbcrsubsampling[1] != 4))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling (%dx%d)",
|
||||
ycbcrsubsampling[0], ycbcrsubsampling[1]);
|
||||
return 0;
|
||||
}
|
||||
samplingblock_samples = ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2;
|
||||
samplingblocks_hor =
|
||||
TIFFhowmany_32(td->td_tilewidth, ycbcrsubsampling[0]);
|
||||
samplingblocks_ver = TIFFhowmany_32(nrows, ycbcrsubsampling[1]);
|
||||
samplingrow_samples = _TIFFMultiply64(tif, samplingblocks_hor,
|
||||
samplingblock_samples, module);
|
||||
samplingrow_size = TIFFhowmany8_64(_TIFFMultiply64(
|
||||
tif, samplingrow_samples, td->td_bitspersample, module));
|
||||
return (
|
||||
_TIFFMultiply64(tif, samplingrow_size, samplingblocks_ver, module));
|
||||
}
|
||||
else
|
||||
return (_TIFFMultiply64(tif, nrows, TIFFTileRowSize64(tif), module));
|
||||
return _TIFFStrileSize64(tif, nrows, /* isStrip = */ FALSE);
|
||||
}
|
||||
|
||||
tmsize_t TIFFVTileSize(TIFF *tif, uint32_t nrows)
|
||||
{
|
||||
static const char module[] = "TIFFVTileSize";
|
||||
|
||||
19
3rdparty/libtiff/tif_unix.c
vendored
19
3rdparty/libtiff/tif_unix.c
vendored
@@ -77,10 +77,10 @@ static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size)
|
||||
return (tmsize_t)-1;
|
||||
}
|
||||
fdh.h = fd;
|
||||
for (bytes_read = 0; bytes_read < bytes_total; bytes_read += count)
|
||||
for (bytes_read = 0; bytes_read < bytes_total; bytes_read += (size_t)count)
|
||||
{
|
||||
char *buf_offset = (char *)buf + bytes_read;
|
||||
size_t io_size = bytes_total - bytes_read;
|
||||
size_t io_size = (size_t)(bytes_total - bytes_read);
|
||||
if (io_size > TIFF_IO_MAX)
|
||||
io_size = TIFF_IO_MAX;
|
||||
/* Below is an obvious false positive of Coverity Scan */
|
||||
@@ -108,10 +108,11 @@ static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size)
|
||||
return (tmsize_t)-1;
|
||||
}
|
||||
fdh.h = fd;
|
||||
for (bytes_written = 0; bytes_written < bytes_total; bytes_written += count)
|
||||
for (bytes_written = 0; bytes_written < bytes_total;
|
||||
bytes_written += (size_t)count)
|
||||
{
|
||||
const char *buf_offset = (char *)buf + bytes_written;
|
||||
size_t io_size = bytes_total - bytes_written;
|
||||
size_t io_size = (size_t)(bytes_total - bytes_written);
|
||||
if (io_size > TIFF_IO_MAX)
|
||||
io_size = TIFF_IO_MAX;
|
||||
/* Below is an obvious false positive of Coverity Scan */
|
||||
@@ -174,7 +175,7 @@ static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize)
|
||||
(void *)mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, fdh.fd, 0);
|
||||
if (*pbase != (void *)-1)
|
||||
{
|
||||
*psize = (tmsize_t)sizem;
|
||||
*psize = (toff_t)sizem;
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
@@ -184,7 +185,7 @@ static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize)
|
||||
static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size)
|
||||
{
|
||||
(void)fd;
|
||||
(void)munmap(base, (off_t)size);
|
||||
(void)munmap(base, (size_t)size);
|
||||
}
|
||||
#else /* !HAVE_MMAP */
|
||||
static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize)
|
||||
@@ -362,7 +363,8 @@ int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c)
|
||||
return (memcmp(p1, p2, (size_t)c));
|
||||
}
|
||||
|
||||
static void unixWarningHandler(const char *module, const char *fmt, va_list ap)
|
||||
static void TIFF_ATTRIBUTE((__format__(__printf__, 2, 0)))
|
||||
unixWarningHandler(const char *module, const char *fmt, va_list ap)
|
||||
{
|
||||
if (module != NULL)
|
||||
fprintf(stderr, "%s: ", module);
|
||||
@@ -372,7 +374,8 @@ static void unixWarningHandler(const char *module, const char *fmt, va_list ap)
|
||||
}
|
||||
TIFFErrorHandler _TIFFwarningHandler = unixWarningHandler;
|
||||
|
||||
static void unixErrorHandler(const char *module, const char *fmt, va_list ap)
|
||||
static void TIFF_ATTRIBUTE((__format__(__printf__, 2, 0)))
|
||||
unixErrorHandler(const char *module, const char *fmt, va_list ap)
|
||||
{
|
||||
if (module != NULL)
|
||||
fprintf(stderr, "%s: ", module);
|
||||
|
||||
57
3rdparty/libtiff/tif_webp.c
vendored
57
3rdparty/libtiff/tif_webp.c
vendored
@@ -84,15 +84,16 @@ static int TWebPDatasetWriter(const uint8_t *data, size_t data_size,
|
||||
|
||||
if ((tif->tif_rawcc + (tmsize_t)data_size) > tif->tif_rawdatasize)
|
||||
{
|
||||
TIFFErrorExtR(
|
||||
tif, module, "Buffer too small by %" TIFF_SIZE_FORMAT " bytes.",
|
||||
(size_t)(tif->tif_rawcc + data_size - tif->tif_rawdatasize));
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Buffer too small by %" TIFF_SIZE_FORMAT " bytes.",
|
||||
(size_t)((uint64_t)tif->tif_rawcc + (uint64_t)data_size -
|
||||
(uint64_t)tif->tif_rawdatasize));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_TIFFmemcpy(tif->tif_rawcp, data, data_size);
|
||||
tif->tif_rawcc += data_size;
|
||||
_TIFFmemcpy(tif->tif_rawcp, data, (tmsize_t)data_size);
|
||||
tif->tif_rawcc += (tmsize_t)data_size;
|
||||
tif->tif_rawcp += data_size;
|
||||
return 1;
|
||||
}
|
||||
@@ -116,7 +117,7 @@ static int TWebPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(sp->pBuffer + sp->buffer_offset, bp, cc);
|
||||
memcpy(sp->pBuffer + sp->buffer_offset, bp, (size_t)cc);
|
||||
sp->buffer_offset += (unsigned)cc;
|
||||
|
||||
return 1;
|
||||
@@ -141,7 +142,7 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
TIFFErrorExtR(tif, module,
|
||||
"ZIPDecode: Scanline %" PRIu32 " cannot be read due to "
|
||||
"previous error",
|
||||
tif->tif_row);
|
||||
tif->tif_dir.td_row);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -158,7 +159,7 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
else
|
||||
{
|
||||
segment_width = td->td_imagewidth;
|
||||
segment_height = td->td_imagelength - tif->tif_row;
|
||||
segment_height = td->td_imagelength - tif->tif_dir.td_row;
|
||||
if (segment_height > td->td_rowsperstrip)
|
||||
segment_height = td->td_rowsperstrip;
|
||||
}
|
||||
@@ -246,7 +247,7 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
sp->pBuffer = NULL;
|
||||
}
|
||||
|
||||
sp->pBuffer = _TIFFmallocExt(tif, buffer_size);
|
||||
sp->pBuffer = (uint8_t *)_TIFFmallocExt(tif, buffer_size);
|
||||
if (!sp->pBuffer)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Cannot allocate buffer");
|
||||
@@ -262,10 +263,10 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
WebPInitDecBuffer(&sp->sDecBuffer);
|
||||
|
||||
sp->sDecBuffer.is_external_memory = 1;
|
||||
sp->sDecBuffer.width = segment_width;
|
||||
sp->sDecBuffer.height = segment_height;
|
||||
sp->sDecBuffer.width = (int)segment_width;
|
||||
sp->sDecBuffer.height = (int)segment_height;
|
||||
sp->sDecBuffer.u.RGBA.rgba = decode_whole_strile ? op : sp->pBuffer;
|
||||
sp->sDecBuffer.u.RGBA.stride = segment_width * sp->nSamples;
|
||||
sp->sDecBuffer.u.RGBA.stride = (int)(segment_width * sp->nSamples);
|
||||
sp->sDecBuffer.u.RGBA.size = buffer_size;
|
||||
|
||||
if (sp->nSamples > 3)
|
||||
@@ -298,7 +299,7 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = WebPIAppend(sp->psDecoder, tif->tif_rawcp, tif->tif_rawcc);
|
||||
status = WebPIAppend(sp->psDecoder, tif->tif_rawcp, (size_t)tif->tif_rawcc);
|
||||
|
||||
if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED)
|
||||
{
|
||||
@@ -345,7 +346,7 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(op, buf + (sp->last_y * stride), occ);
|
||||
memcpy(op, buf + (sp->last_y * stride), (size_t)occ);
|
||||
}
|
||||
|
||||
tif->tif_rawcp += tif->tif_rawcc;
|
||||
@@ -465,7 +466,7 @@ static int TWebPPreDecode(TIFF *tif, uint16_t s)
|
||||
else
|
||||
{
|
||||
segment_width = td->td_imagewidth;
|
||||
segment_height = td->td_imagelength - tif->tif_row;
|
||||
segment_height = td->td_imagelength - tif->tif_dir.td_row;
|
||||
if (segment_height > td->td_rowsperstrip)
|
||||
segment_height = td->td_rowsperstrip;
|
||||
}
|
||||
@@ -601,7 +602,7 @@ static int TWebPPreEncode(TIFF *tif, uint16_t s)
|
||||
else
|
||||
{
|
||||
segment_width = td->td_imagewidth;
|
||||
segment_height = td->td_imagelength - tif->tif_row;
|
||||
segment_height = td->td_imagelength - tif->tif_dir.td_row;
|
||||
if (segment_height > td->td_rowsperstrip)
|
||||
segment_height = td->td_rowsperstrip;
|
||||
}
|
||||
@@ -623,7 +624,7 @@ static int TWebPPreEncode(TIFF *tif, uint16_t s)
|
||||
sp->pBuffer = NULL;
|
||||
}
|
||||
|
||||
sp->pBuffer = _TIFFmallocExt(tif, sp->buffer_size);
|
||||
sp->pBuffer = (uint8_t *)_TIFFmallocExt(tif, sp->buffer_size);
|
||||
if (!sp->pBuffer)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Cannot allocate buffer");
|
||||
@@ -631,8 +632,8 @@ static int TWebPPreEncode(TIFF *tif, uint16_t s)
|
||||
}
|
||||
sp->buffer_offset = 0;
|
||||
|
||||
sp->sPicture.width = segment_width;
|
||||
sp->sPicture.height = segment_height;
|
||||
sp->sPicture.width = (int)segment_width;
|
||||
sp->sPicture.height = (int)segment_height;
|
||||
sp->sPicture.writer = TWebPDatasetWriter;
|
||||
sp->sPicture.custom_ptr = tif;
|
||||
|
||||
@@ -708,9 +709,11 @@ static int TWebPPostEncode(TIFF *tif)
|
||||
case VP8_ENC_ERROR_USER_ABORT:
|
||||
pszErrorMsg = "User interrupted";
|
||||
break;
|
||||
case VP8_ENC_OK:
|
||||
case VP8_ENC_ERROR_LAST:
|
||||
default:
|
||||
TIFFErrorExtR(tif, module,
|
||||
"WebPEncode returned an unknown error code: %d",
|
||||
"WebPEncode returned an unknown error code: %u",
|
||||
sp->sPicture.error_code);
|
||||
pszErrorMsg = "Unknown WebP error type.";
|
||||
break;
|
||||
@@ -776,7 +779,7 @@ static int TWebPVSetField(TIFF *tif, uint32_t tag, va_list ap)
|
||||
{
|
||||
case TIFFTAG_WEBP_LEVEL:
|
||||
sp->quality_level = (int)va_arg(ap, int);
|
||||
if (sp->quality_level <= 0 || sp->quality_level > 100.0f)
|
||||
if (sp->quality_level <= 0 || sp->quality_level > 100)
|
||||
{
|
||||
TIFFWarningExtR(tif, module,
|
||||
"WEBP_LEVEL should be between 1 and 100");
|
||||
@@ -844,6 +847,17 @@ static const TIFFField TWebPFields[] = {
|
||||
FIELD_PSEUDO, TRUE, FALSE, "WEBP exact lossless", NULL},
|
||||
};
|
||||
|
||||
static uint64_t TWebPGetMaxCompressionRatio(TIFF *tif)
|
||||
{
|
||||
/* See README_for_libtiff_developpers.md for raw data used to estimate
|
||||
* the maximum compression rate. */
|
||||
|
||||
/* lossy compression: */
|
||||
/* return (tif->tif_dir.td_samplesperpixel == 4) ? 2199 : 1685; */
|
||||
/* lossless compression: */
|
||||
return (tif->tif_dir.td_samplesperpixel == 4) ? 104194 : 78146;
|
||||
}
|
||||
|
||||
int TIFFInitWebP(TIFF *tif, int scheme)
|
||||
{
|
||||
static const char module[] = "TIFFInitWebP";
|
||||
@@ -907,6 +921,7 @@ int TIFFInitWebP(TIFF *tif, int scheme)
|
||||
tif->tif_encodestrip = TWebPEncode;
|
||||
tif->tif_encodetile = TWebPEncode;
|
||||
tif->tif_cleanup = TWebPCleanup;
|
||||
tif->tif_getmaxcompressionratio = TWebPGetMaxCompressionRatio;
|
||||
|
||||
return 1;
|
||||
bad:
|
||||
|
||||
15
3rdparty/libtiff/tif_win32.c
vendored
15
3rdparty/libtiff/tif_win32.c
vendored
@@ -5,6 +5,7 @@
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
@@ -72,7 +73,7 @@ static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size)
|
||||
DWORD o;
|
||||
tmsize_t p;
|
||||
ma = (uint8_t *)buf;
|
||||
mb = size;
|
||||
mb = (uint64_t)size;
|
||||
p = 0;
|
||||
while (mb > 0)
|
||||
{
|
||||
@@ -101,7 +102,7 @@ static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size)
|
||||
DWORD o;
|
||||
tmsize_t p;
|
||||
ma = (uint8_t *)buf;
|
||||
mb = size;
|
||||
mb = (uint64_t)size;
|
||||
p = 0;
|
||||
while (mb > 0)
|
||||
{
|
||||
@@ -123,7 +124,7 @@ static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence)
|
||||
{
|
||||
LARGE_INTEGER offli;
|
||||
DWORD dwMoveMethod;
|
||||
offli.QuadPart = off;
|
||||
offli.QuadPart = (LONGLONG)off;
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_SET:
|
||||
@@ -140,11 +141,11 @@ static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence)
|
||||
break;
|
||||
}
|
||||
offli.LowPart =
|
||||
SetFilePointer(fd, offli.LowPart, &offli.HighPart, dwMoveMethod);
|
||||
SetFilePointer(fd, (LONG)offli.LowPart, &offli.HighPart, dwMoveMethod);
|
||||
if ((offli.LowPart == INVALID_SET_FILE_POINTER) &&
|
||||
(GetLastError() != NO_ERROR))
|
||||
offli.QuadPart = 0;
|
||||
return (offli.QuadPart);
|
||||
return ((uint64_t)offli.QuadPart);
|
||||
}
|
||||
|
||||
static int _tiffCloseProc(thandle_t fd) { return (CloseHandle(fd) ? 0 : -1); }
|
||||
@@ -153,7 +154,7 @@ static uint64_t _tiffSizeProc(thandle_t fd)
|
||||
{
|
||||
LARGE_INTEGER m;
|
||||
if (GetFileSizeEx(fd, &m))
|
||||
return (m.QuadPart);
|
||||
return ((uint64_t)m.QuadPart);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
@@ -343,7 +344,7 @@ TIFF *TIFFOpenWExt(const wchar_t *name, const char *mode, TIFFOpenOptions *opts)
|
||||
NULL);
|
||||
if (fd == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
_TIFFErrorEarly(opts, NULL, module, "%S: Cannot open", name);
|
||||
_TIFFErrorEarly(opts, NULL, module, "%ls: Cannot open", name);
|
||||
return ((TIFF *)0);
|
||||
}
|
||||
|
||||
|
||||
181
3rdparty/libtiff/tif_write.c
vendored
181
3rdparty/libtiff/tif_write.c
vendored
@@ -30,7 +30,7 @@
|
||||
#include "tiffiop.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define STRIPINCR 20 /* expansion factor on strip array */
|
||||
#define NOSTRIP ((uint32_t)(-1)) /* undefined state */
|
||||
|
||||
#define WRITECHECKSTRIPS(tif, module) \
|
||||
(((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 0, module))
|
||||
@@ -38,7 +38,7 @@
|
||||
(((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 1, module))
|
||||
#define BUFFERCHECK(tif) \
|
||||
((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \
|
||||
TIFFWriteBufferSetup((tif), NULL, (tmsize_t)-1))
|
||||
TIFFWriteBufferSetup((tif), NULL, (tmsize_t)(-1)))
|
||||
|
||||
static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module);
|
||||
static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
|
||||
@@ -47,7 +47,7 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
|
||||
int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
|
||||
{
|
||||
static const char module[] = "TIFFWriteScanline";
|
||||
register TIFFDirectory *td;
|
||||
TIFFDirectory *td;
|
||||
int status, imagegrew = 0;
|
||||
uint32_t strip;
|
||||
|
||||
@@ -82,8 +82,16 @@ int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
|
||||
/*
|
||||
* Calculate strip and check for crossings.
|
||||
*/
|
||||
if (td->td_rowsperstrip == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Cannot compute strip: RowsPerStrip is zero");
|
||||
return (-1);
|
||||
}
|
||||
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
|
||||
{
|
||||
uint64_t sample_offset;
|
||||
uint64_t strip64;
|
||||
if (sample >= td->td_samplesperpixel)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu",
|
||||
@@ -91,7 +99,18 @@ int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
|
||||
(unsigned long)td->td_samplesperpixel);
|
||||
return (-1);
|
||||
}
|
||||
strip = sample * td->td_stripsperimage + row / td->td_rowsperstrip;
|
||||
sample_offset =
|
||||
_TIFFMultiply64(tif, sample, td->td_stripsperimage, module);
|
||||
if (sample_offset == 0 && sample != 0 && td->td_stripsperimage != 0)
|
||||
return (-1);
|
||||
strip64 =
|
||||
_TIFFAdd64(tif, sample_offset, row / td->td_rowsperstrip, module);
|
||||
if (strip64 == 0 &&
|
||||
(sample_offset != 0 || (row / td->td_rowsperstrip) != 0))
|
||||
return (-1);
|
||||
strip = _TIFFCastUInt64ToUInt32(tif, strip64, module);
|
||||
if (strip == 0 && strip64 != 0)
|
||||
return (-1);
|
||||
}
|
||||
else
|
||||
strip = row / td->td_rowsperstrip;
|
||||
@@ -104,14 +123,14 @@ int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
|
||||
*/
|
||||
if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module))
|
||||
return (-1);
|
||||
if (strip != tif->tif_curstrip)
|
||||
if (strip != tif->tif_dir.td_curstrip)
|
||||
{
|
||||
/*
|
||||
* Changing strips -- flush any data present.
|
||||
*/
|
||||
if (!TIFFFlushData(tif))
|
||||
return (-1);
|
||||
tif->tif_curstrip = strip;
|
||||
tif->tif_dir.td_curstrip = strip;
|
||||
/*
|
||||
* Watch out for a growing image. The value of strips/image
|
||||
* will initially be 1 (since it can't be deduced until the
|
||||
@@ -125,7 +144,8 @@ int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
|
||||
TIFFErrorExtR(tif, module, "Zero strips per image");
|
||||
return (-1);
|
||||
}
|
||||
tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
|
||||
tif->tif_dir.td_row =
|
||||
(strip % td->td_stripsperimage) * td->td_rowsperstrip;
|
||||
if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
|
||||
{
|
||||
if (!(*tif->tif_setupencode)(tif))
|
||||
@@ -148,35 +168,35 @@ int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
|
||||
* beginning of a strip (or that we can randomly
|
||||
* access the data -- i.e. no encoding).
|
||||
*/
|
||||
if (row != tif->tif_row)
|
||||
if (row != tif->tif_dir.td_row)
|
||||
{
|
||||
if (row < tif->tif_row)
|
||||
if (row < tif->tif_dir.td_row)
|
||||
{
|
||||
/*
|
||||
* Moving backwards within the same strip:
|
||||
* backup to the start and then decode
|
||||
* forward (below).
|
||||
*/
|
||||
tif->tif_row =
|
||||
tif->tif_dir.td_row =
|
||||
(strip % td->td_stripsperimage) * td->td_rowsperstrip;
|
||||
tif->tif_rawcp = tif->tif_rawdata;
|
||||
}
|
||||
/*
|
||||
* Seek forward to the desired row.
|
||||
*/
|
||||
if (!(*tif->tif_seek)(tif, row - tif->tif_row))
|
||||
if (!(*tif->tif_seek)(tif, row - tif->tif_dir.td_row))
|
||||
return (-1);
|
||||
tif->tif_row = row;
|
||||
tif->tif_dir.td_row = row;
|
||||
}
|
||||
|
||||
/* swab if needed - note that source buffer will be altered */
|
||||
tif->tif_postdecode(tif, (uint8_t *)buf, tif->tif_scanlinesize);
|
||||
tif->tif_postdecode(tif, (uint8_t *)buf, tif->tif_dir.td_scanlinesize);
|
||||
|
||||
status = (*tif->tif_encoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize,
|
||||
sample);
|
||||
status = (*tif->tif_encoderow)(tif, (uint8_t *)buf,
|
||||
tif->tif_dir.td_scanlinesize, sample);
|
||||
|
||||
/* we are now poised at the beginning of the next row */
|
||||
tif->tif_row = row + 1;
|
||||
tif->tif_dir.td_row = row + 1;
|
||||
return (status);
|
||||
}
|
||||
|
||||
@@ -188,7 +208,21 @@ int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
|
||||
/* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
|
||||
static int _TIFFReserveLargeEnoughWriteBuffer(TIFF *tif, uint32_t strip_or_tile)
|
||||
{
|
||||
static const char module[] = "_TIFFReserveLargeEnoughWriteBuffer";
|
||||
TIFFDirectory *td = &tif->tif_dir;
|
||||
|
||||
if (td->td_stripbytecount_p == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Strip bytecount array pointer is NULL");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strip_or_tile == NOSTRIP || strip_or_tile >= td->td_nstrips)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Strip/tile number not valid");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (td->td_stripbytecount_p[strip_or_tile] > 0)
|
||||
{
|
||||
/* The +1 is to ensure at least one extra bytes */
|
||||
@@ -254,7 +288,7 @@ tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data,
|
||||
|
||||
tif->tif_flags |= TIFF_BUF4WRITE;
|
||||
|
||||
tif->tif_curstrip = strip;
|
||||
tif->tif_dir.td_curstrip = strip;
|
||||
|
||||
/* this informs TIFFAppendToStrip() we have changed or reset strip */
|
||||
tif->tif_curoff = 0;
|
||||
@@ -273,7 +307,7 @@ tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data,
|
||||
return ((tmsize_t)-1);
|
||||
}
|
||||
|
||||
tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
|
||||
tif->tif_dir.td_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
|
||||
if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
|
||||
{
|
||||
if (!(*tif->tif_setupencode)(tif))
|
||||
@@ -362,9 +396,9 @@ tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data, tmsize_t cc)
|
||||
return ((tmsize_t)-1);
|
||||
}
|
||||
|
||||
if (tif->tif_curstrip != strip)
|
||||
if (tif->tif_dir.td_curstrip != strip)
|
||||
{
|
||||
tif->tif_curstrip = strip;
|
||||
tif->tif_dir.td_curstrip = strip;
|
||||
|
||||
/* this informs TIFFAppendToStrip() we have changed or reset strip */
|
||||
tif->tif_curoff = 0;
|
||||
@@ -375,7 +409,7 @@ tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data, tmsize_t cc)
|
||||
TIFFErrorExtR(tif, module, "Zero strips per image");
|
||||
return ((tmsize_t)-1);
|
||||
}
|
||||
tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
|
||||
tif->tif_dir.td_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
|
||||
return (TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc) ? cc
|
||||
: (tmsize_t)-1);
|
||||
}
|
||||
@@ -437,7 +471,7 @@ tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc)
|
||||
|
||||
tif->tif_flags |= TIFF_BUF4WRITE;
|
||||
|
||||
tif->tif_curtile = tile;
|
||||
tif->tif_dir.td_curtile = tile;
|
||||
|
||||
/* this informs TIFFAppendToStrip() we have changed or reset tile */
|
||||
tif->tif_curoff = 0;
|
||||
@@ -460,14 +494,14 @@ tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc)
|
||||
TIFFErrorExtR(tif, module, "Zero tiles");
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
tif->tif_row = (tile % howmany32) * td->td_tilelength;
|
||||
tif->tif_dir.td_row = (tile % howmany32) * td->td_tilelength;
|
||||
howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
|
||||
if (howmany32 == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Zero tiles");
|
||||
return ((tmsize_t)(-1));
|
||||
}
|
||||
tif->tif_col = (tile % howmany32) * td->td_tilewidth;
|
||||
tif->tif_dir.td_col = (tile % howmany32) * td->td_tilewidth;
|
||||
|
||||
if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
|
||||
{
|
||||
@@ -482,8 +516,8 @@ tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc)
|
||||
* done so that callers can pass in some large number
|
||||
* (e.g. -1) and have the tile size used instead.
|
||||
*/
|
||||
if (cc < 1 || cc > tif->tif_tilesize)
|
||||
cc = tif->tif_tilesize;
|
||||
if (cc < 1 || cc > tif->tif_dir.td_tilesize)
|
||||
cc = tif->tif_dir.td_tilesize;
|
||||
|
||||
/* shortcut to avoid an extra memcpy() */
|
||||
if (td->td_compression == COMPRESSION_NONE)
|
||||
@@ -588,8 +622,10 @@ int TIFFSetupStrips(TIFF *tif)
|
||||
* Place data at the end-of-file
|
||||
* (by setting offsets to zero).
|
||||
*/
|
||||
_TIFFmemset(td->td_stripoffset_p, 0, td->td_nstrips * sizeof(uint64_t));
|
||||
_TIFFmemset(td->td_stripbytecount_p, 0, td->td_nstrips * sizeof(uint64_t));
|
||||
_TIFFmemset(td->td_stripoffset_p, 0,
|
||||
(tmsize_t)((size_t)td->td_nstrips * sizeof(uint64_t)));
|
||||
_TIFFmemset(td->td_stripbytecount_p, 0,
|
||||
(tmsize_t)((size_t)td->td_nstrips * sizeof(uint64_t)));
|
||||
TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
|
||||
TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
|
||||
return (1);
|
||||
@@ -644,14 +680,14 @@ int TIFFWriteCheck(TIFF *tif, int tiles, const char *module)
|
||||
}
|
||||
if (isTiled(tif))
|
||||
{
|
||||
tif->tif_tilesize = TIFFTileSize(tif);
|
||||
if (tif->tif_tilesize == 0)
|
||||
tif->tif_dir.td_tilesize = TIFFTileSize(tif);
|
||||
if (tif->tif_dir.td_tilesize == 0)
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
tif->tif_tilesize = (tmsize_t)(-1);
|
||||
tif->tif_scanlinesize = TIFFScanlineSize(tif);
|
||||
if (tif->tif_scanlinesize == 0)
|
||||
tif->tif_dir.td_tilesize = (tmsize_t)(-1);
|
||||
tif->tif_dir.td_scanlinesize = TIFFScanlineSize(tif);
|
||||
if (tif->tif_dir.td_scanlinesize == 0)
|
||||
return (0);
|
||||
tif->tif_flags |= TIFF_BEENWRITING;
|
||||
|
||||
@@ -689,7 +725,7 @@ int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size)
|
||||
}
|
||||
if (size == (tmsize_t)(-1))
|
||||
{
|
||||
size = (isTiled(tif) ? tif->tif_tilesize : TIFFStripSize(tif));
|
||||
size = (isTiled(tif) ? tif->tif_dir.td_tilesize : TIFFStripSize(tif));
|
||||
|
||||
/* Adds 10% margin for cases where compression would expand a bit */
|
||||
if (size < TIFF_TMSIZE_T_MAX - size / 10)
|
||||
@@ -732,26 +768,31 @@ static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module)
|
||||
|
||||
assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
|
||||
new_stripoffset = (uint64_t *)_TIFFreallocExt(
|
||||
tif, td->td_stripoffset_p, (td->td_nstrips + delta) * sizeof(uint64_t));
|
||||
tif, td->td_stripoffset_p,
|
||||
(tmsize_t)(((size_t)td->td_nstrips + (size_t)delta) *
|
||||
sizeof(uint64_t)));
|
||||
/*
|
||||
* Update td_stripoffset_p immediately so the old pointer is not left
|
||||
* dangling if the second realloc fails.
|
||||
*/
|
||||
if (new_stripoffset)
|
||||
td->td_stripoffset_p = new_stripoffset;
|
||||
new_stripbytecount = (uint64_t *)_TIFFreallocExt(
|
||||
tif, td->td_stripbytecount_p,
|
||||
(td->td_nstrips + delta) * sizeof(uint64_t));
|
||||
(tmsize_t)(((size_t)td->td_nstrips + (size_t)delta) *
|
||||
sizeof(uint64_t)));
|
||||
if (new_stripbytecount)
|
||||
td->td_stripbytecount_p = new_stripbytecount;
|
||||
if (new_stripoffset == NULL || new_stripbytecount == NULL)
|
||||
{
|
||||
if (new_stripoffset)
|
||||
_TIFFfreeExt(tif, new_stripoffset);
|
||||
if (new_stripbytecount)
|
||||
_TIFFfreeExt(tif, new_stripbytecount);
|
||||
td->td_nstrips = 0;
|
||||
TIFFErrorExtR(tif, module, "No space to expand strip arrays");
|
||||
return (0);
|
||||
}
|
||||
td->td_stripoffset_p = new_stripoffset;
|
||||
td->td_stripbytecount_p = new_stripbytecount;
|
||||
_TIFFmemset(td->td_stripoffset_p + td->td_nstrips, 0,
|
||||
delta * sizeof(uint64_t));
|
||||
(tmsize_t)((size_t)delta * sizeof(uint64_t)));
|
||||
_TIFFmemset(td->td_stripbytecount_p + td->td_nstrips, 0,
|
||||
delta * sizeof(uint64_t));
|
||||
(tmsize_t)((size_t)delta * sizeof(uint64_t)));
|
||||
td->td_nstrips += delta;
|
||||
tif->tif_flags |= TIFF_DIRTYDIRECT;
|
||||
|
||||
@@ -769,6 +810,23 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
|
||||
uint64_t m;
|
||||
int64_t old_byte_count = -1;
|
||||
|
||||
/* Some security checks */
|
||||
if (td->td_stripoffset_p == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Strip offset array pointer is NULL");
|
||||
return (0);
|
||||
}
|
||||
if (td->td_stripbytecount_p == NULL)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Strip bytecount array pointer is NULL");
|
||||
return (0);
|
||||
}
|
||||
if (strip == NOSTRIP)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Strip number not valid (NOSTRIP)");
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (tif->tif_curoff == 0)
|
||||
tif->tif_lastvalidoff = 0;
|
||||
|
||||
@@ -790,7 +848,7 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
|
||||
if (!SeekOK(tif, td->td_stripoffset_p[strip]))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Seek error at scanline %lu",
|
||||
(unsigned long)tif->tif_row);
|
||||
(unsigned long)tif->tif_dir.td_row);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -812,11 +870,11 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
|
||||
/*
|
||||
* We are starting a fresh strip/tile, so set the size to zero.
|
||||
*/
|
||||
old_byte_count = td->td_stripbytecount_p[strip];
|
||||
old_byte_count = (int64_t)td->td_stripbytecount_p[strip];
|
||||
td->td_stripbytecount_p[strip] = 0;
|
||||
}
|
||||
|
||||
m = tif->tif_curoff + cc;
|
||||
m = tif->tif_curoff + (uint64_t)cc;
|
||||
if (!(tif->tif_flags & TIFF_BIGTIFF))
|
||||
m = (uint32_t)m;
|
||||
if ((m < tif->tif_curoff) || (m < (uint64_t)cc))
|
||||
@@ -850,7 +908,7 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
|
||||
offsetRead = td->td_stripoffset_p[strip];
|
||||
offsetWrite = TIFFSeekFile(tif, 0, SEEK_END);
|
||||
|
||||
m = offsetWrite + toCopy + cc;
|
||||
m = offsetWrite + (uint64_t)toCopy + (uint64_t)cc;
|
||||
if (!(tif->tif_flags & TIFF_BIGTIFF) && m != (uint32_t)m)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
|
||||
@@ -872,13 +930,15 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
|
||||
/* Move data written by previous calls to us at end of file */
|
||||
while (toCopy > 0)
|
||||
{
|
||||
tmsize_t chunkSize =
|
||||
toCopy < (uint64_t)tempSize ? (tmsize_t)toCopy : tempSize;
|
||||
if (!SeekOK(tif, offsetRead))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Seek error");
|
||||
_TIFFfreeExt(tif, temp);
|
||||
return (0);
|
||||
}
|
||||
if (!ReadOK(tif, temp, tempSize))
|
||||
if (!ReadOK(tif, temp, chunkSize))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Cannot read");
|
||||
_TIFFfreeExt(tif, temp);
|
||||
@@ -890,32 +950,32 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
|
||||
_TIFFfreeExt(tif, temp);
|
||||
return (0);
|
||||
}
|
||||
if (!WriteOK(tif, temp, tempSize))
|
||||
if (!WriteOK(tif, temp, chunkSize))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Cannot write");
|
||||
_TIFFfreeExt(tif, temp);
|
||||
return (0);
|
||||
}
|
||||
offsetRead += tempSize;
|
||||
offsetWrite += tempSize;
|
||||
td->td_stripbytecount_p[strip] += tempSize;
|
||||
toCopy -= tempSize;
|
||||
offsetRead += (uint64_t)chunkSize;
|
||||
offsetWrite += (uint64_t)chunkSize;
|
||||
td->td_stripbytecount_p[strip] += (uint64_t)chunkSize;
|
||||
toCopy -= (uint64_t)chunkSize;
|
||||
}
|
||||
_TIFFfreeExt(tif, temp);
|
||||
|
||||
/* Append the data of this call */
|
||||
offsetWrite += cc;
|
||||
offsetWrite += (uint64_t)cc;
|
||||
m = offsetWrite;
|
||||
}
|
||||
|
||||
if (!WriteOK(tif, data, cc))
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Write error at scanline %lu",
|
||||
(unsigned long)tif->tif_row);
|
||||
(unsigned long)tif->tif_dir.td_row);
|
||||
return (0);
|
||||
}
|
||||
tif->tif_curoff = m;
|
||||
td->td_stripbytecount_p[strip] += cc;
|
||||
td->td_stripbytecount_p[strip] += (uint64_t)cc;
|
||||
|
||||
if ((int64_t)td->td_stripbytecount_p[strip] != old_byte_count)
|
||||
tif->tif_flags |= TIFF_DIRTYSTRIP;
|
||||
@@ -935,9 +995,10 @@ int TIFFFlushData1(TIFF *tif)
|
||||
if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
|
||||
(tif->tif_flags & TIFF_NOBITREV) == 0)
|
||||
TIFFReverseBits((uint8_t *)tif->tif_rawdata, tif->tif_rawcc);
|
||||
if (!TIFFAppendToStrip(
|
||||
tif, isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
|
||||
tif->tif_rawdata, tif->tif_rawcc))
|
||||
if (!TIFFAppendToStrip(tif,
|
||||
isTiled(tif) ? tif->tif_dir.td_curtile
|
||||
: tif->tif_dir.td_curstrip,
|
||||
tif->tif_rawdata, tif->tif_rawcc))
|
||||
{
|
||||
/* We update those variables even in case of error since there's */
|
||||
/* code that doesn't really check the return code of this */
|
||||
|
||||
38
3rdparty/libtiff/tif_zip.c
vendored
38
3rdparty/libtiff/tif_zip.c
vendored
@@ -159,7 +159,8 @@ static int ZIPPreDecode(TIFF *tif, uint16_t s)
|
||||
we need to simplify this code to reflect a ZLib that is likely updated
|
||||
to deal with 8byte memory sizes, though this code will respond
|
||||
appropriately even before we simplify it */
|
||||
sp->stream.avail_in = TIFF_CLAMP_UINT64_TO_INT32_MAX(tif->tif_rawcc);
|
||||
sp->stream.avail_in =
|
||||
TIFF_CLAMP_UINT64_TO_INT32_MAX((uint64_t)tif->tif_rawcc);
|
||||
if (inflateReset(&sp->stream) == Z_OK)
|
||||
{
|
||||
sp->read_error = 0;
|
||||
@@ -183,7 +184,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
TIFFErrorExtR(tif, module,
|
||||
"ZIPDecode: Scanline %" PRIu32 " cannot be read due to "
|
||||
"previous error",
|
||||
tif->tif_row);
|
||||
tif->tif_dir.td_row);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -210,7 +211,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t strip_height = td->td_imagelength - tif->tif_row;
|
||||
uint32_t strip_height = td->td_imagelength - tif->tif_dir.td_row;
|
||||
if (strip_height > td->td_rowsperstrip)
|
||||
strip_height = td->td_rowsperstrip;
|
||||
if (TIFFVStripSize64(tif, strip_height) != (uint64_t)occ)
|
||||
@@ -254,7 +255,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
{
|
||||
memset(op, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module, "Decoding error at scanline %lu",
|
||||
(unsigned long)tif->tif_row);
|
||||
(unsigned long)tif->tif_dir.td_row);
|
||||
sp->read_error = 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -275,8 +276,9 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
do
|
||||
{
|
||||
int state;
|
||||
uInt avail_in_before = TIFF_CLAMP_UINT64_TO_INT32_MAX(tif->tif_rawcc);
|
||||
uInt avail_out_before = TIFF_CLAMP_UINT64_TO_INT32_MAX(occ);
|
||||
uInt avail_in_before =
|
||||
TIFF_CLAMP_UINT64_TO_INT32_MAX((uint64_t)tif->tif_rawcc);
|
||||
uInt avail_out_before = TIFF_CLAMP_UINT64_TO_INT32_MAX((uint64_t)occ);
|
||||
sp->stream.avail_in = avail_in_before;
|
||||
sp->stream.avail_out = avail_out_before;
|
||||
state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
|
||||
@@ -288,7 +290,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
{
|
||||
memset(sp->stream.next_out, 0, (size_t)occ);
|
||||
TIFFErrorExtR(tif, module, "Decoding error at scanline %lu, %s",
|
||||
(unsigned long)tif->tif_row, SAFE_MSG(sp));
|
||||
(unsigned long)tif->tif_dir.td_row, SAFE_MSG(sp));
|
||||
sp->read_error = 1;
|
||||
return (0);
|
||||
}
|
||||
@@ -305,7 +307,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Not enough data at scanline %lu (short %" PRIu64
|
||||
" bytes)",
|
||||
(unsigned long)tif->tif_row, (uint64_t)occ);
|
||||
(unsigned long)tif->tif_dir.td_row, (uint64_t)occ);
|
||||
memset(sp->stream.next_out, 0, (size_t)occ);
|
||||
sp->read_error = 1;
|
||||
return (0);
|
||||
@@ -411,7 +413,7 @@ static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t strip_height = td->td_imagelength - tif->tif_row;
|
||||
uint32_t strip_height = td->td_imagelength - tif->tif_dir.td_row;
|
||||
if (strip_height > td->td_rowsperstrip)
|
||||
strip_height = td->td_rowsperstrip;
|
||||
if (TIFFVStripSize64(tif, strip_height) != (uint64_t)cc)
|
||||
@@ -463,11 +465,11 @@ static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
if (nCompressedBytes == 0)
|
||||
{
|
||||
TIFFErrorExtR(tif, module, "Encoder error at scanline %lu",
|
||||
(unsigned long)tif->tif_row);
|
||||
(unsigned long)tif->tif_dir.td_row);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tif->tif_rawcc = nCompressedBytes;
|
||||
tif->tif_rawcc = (tmsize_t)nCompressedBytes;
|
||||
|
||||
if (!TIFFFlushData1(tif))
|
||||
return 0;
|
||||
@@ -485,7 +487,7 @@ static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
appropriately even before we simplify it */
|
||||
do
|
||||
{
|
||||
uInt avail_in_before = TIFF_CLAMP_UINT64_TO_INT32_MAX(cc);
|
||||
uInt avail_in_before = TIFF_CLAMP_UINT64_TO_INT32_MAX((uint64_t)cc);
|
||||
sp->stream.avail_in = avail_in_before;
|
||||
if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK)
|
||||
{
|
||||
@@ -499,7 +501,7 @@ static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
|
||||
return 0;
|
||||
sp->stream.next_out = tif->tif_rawdata;
|
||||
sp->stream.avail_out =
|
||||
TIFF_CLAMP_UINT64_TO_INT32_MAX(tif->tif_rawdatasize);
|
||||
TIFF_CLAMP_UINT64_TO_INT32_MAX((uint64_t)tif->tif_rawdatasize);
|
||||
}
|
||||
cc -= (avail_in_before - sp->stream.avail_in);
|
||||
} while (cc > 0);
|
||||
@@ -682,7 +684,7 @@ static const TIFFField zipFields[] = {
|
||||
static void *TIFF_zalloc(void *opaque, unsigned int items, unsigned int size)
|
||||
{
|
||||
static const char module[] = "TIFF_zalloc";
|
||||
TIFF *tif = opaque;
|
||||
TIFF *tif = (TIFF *)opaque;
|
||||
|
||||
if (items > ~(size_t)0 / size)
|
||||
{
|
||||
@@ -698,6 +700,13 @@ static void TIFF_zfree(void *opaque, void *ptr)
|
||||
_TIFFfreeExt((TIFF *)opaque, ptr);
|
||||
}
|
||||
|
||||
static uint64_t ZIPGetMaxCompressionRatio(TIFF *tif)
|
||||
{
|
||||
(void)tif;
|
||||
/* cf https://zlib.net/zlib_tech.html */
|
||||
return 1032;
|
||||
}
|
||||
|
||||
int TIFFInitZIP(TIFF *tif, int scheme)
|
||||
{
|
||||
static const char module[] = "TIFFInitZIP";
|
||||
@@ -764,6 +773,7 @@ int TIFFInitZIP(TIFF *tif, int scheme)
|
||||
tif->tif_encodestrip = ZIPEncode;
|
||||
tif->tif_encodetile = ZIPEncode;
|
||||
tif->tif_cleanup = ZIPCleanup;
|
||||
tif->tif_getmaxcompressionratio = ZIPGetMaxCompressionRatio;
|
||||
/*
|
||||
* Setup predictor setup.
|
||||
*/
|
||||
|
||||
6
3rdparty/libtiff/tif_zstd.c
vendored
6
3rdparty/libtiff/tif_zstd.c
vendored
@@ -159,13 +159,13 @@ static int ZSTDDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
|
||||
memset(op + out_buffer.pos, 0, out_buffer.size - out_buffer.pos);
|
||||
TIFFErrorExtR(tif, module,
|
||||
"Not enough data at scanline %lu (short %lu bytes)",
|
||||
(unsigned long)tif->tif_row,
|
||||
(unsigned long)tif->tif_dir.td_row,
|
||||
(unsigned long)((size_t)occ - out_buffer.pos));
|
||||
return 0;
|
||||
}
|
||||
|
||||
tif->tif_rawcp += in_buffer.pos;
|
||||
tif->tif_rawcc -= in_buffer.pos;
|
||||
tif->tif_rawcc -= (tmsize_t)in_buffer.pos;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -287,7 +287,7 @@ static int ZSTDPostEncode(TIFF *tif)
|
||||
}
|
||||
if (sp->out_buffer.pos > 0)
|
||||
{
|
||||
tif->tif_rawcc = sp->out_buffer.pos;
|
||||
tif->tif_rawcc = (tmsize_t)sp->out_buffer.pos;
|
||||
if (!TIFFFlushData1(tif))
|
||||
return 0;
|
||||
sp->out_buffer.dst = tif->tif_rawcp;
|
||||
|
||||
3
3rdparty/libtiff/tiffconf.h.cmake.in
vendored
3
3rdparty/libtiff/tiffconf.h.cmake.in
vendored
@@ -108,6 +108,9 @@
|
||||
/* Support libdeflate enhanced compression */
|
||||
#cmakedefine LIBDEFLATE_SUPPORT 1
|
||||
|
||||
/* Support webp compression */
|
||||
#cmakedefine WEBP_SUPPORT 1
|
||||
|
||||
/* Support strip chopping (whether or not to convert single-strip uncompressed
|
||||
images to multiple strips of ~8Kb to reduce memory usage) */
|
||||
#cmakedefine STRIPCHOP_DEFAULT TIFF_STRIPCHOP
|
||||
|
||||
19
3rdparty/libtiff/tiffio.h
vendored
19
3rdparty/libtiff/tiffio.h
vendored
@@ -125,13 +125,13 @@ typedef void *thandle_t; /* client data handle */
|
||||
*/
|
||||
|
||||
/* reference white */
|
||||
#define D65_X0 (95.0470F)
|
||||
#define D65_Y0 (100.0F)
|
||||
#define D65_Z0 (108.8827F)
|
||||
#define D65_X0 (95.0470f)
|
||||
#define D65_Y0 (100.0f)
|
||||
#define D65_Z0 (108.8827f)
|
||||
|
||||
#define D50_X0 (96.4250F)
|
||||
#define D50_Y0 (100.0F)
|
||||
#define D50_Z0 (82.4680F)
|
||||
#define D50_X0 (96.4250f)
|
||||
#define D50_Y0 (100.0f)
|
||||
#define D50_Z0 (82.4680f)
|
||||
|
||||
/* Structure for holding information about a display device. */
|
||||
|
||||
@@ -254,7 +254,7 @@ struct _TIFFRGBAImage
|
||||
* Macros for extracting components from the
|
||||
* packed ABGR form returned by TIFFReadRGBAImage.
|
||||
*/
|
||||
#define TIFFGetR(abgr) ((abgr)&0xff)
|
||||
#define TIFFGetR(abgr) ((abgr) & 0xff)
|
||||
#define TIFFGetG(abgr) (((abgr) >> 8) & 0xff)
|
||||
#define TIFFGetB(abgr) (((abgr) >> 16) & 0xff)
|
||||
#define TIFFGetA(abgr) (((abgr) >> 24) & 0xff)
|
||||
@@ -269,7 +269,7 @@ struct _TIFFRGBAImage
|
||||
typedef int (*TIFFInitMethod)(TIFF *, int);
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
const char *name;
|
||||
uint16_t scheme;
|
||||
TIFFInitMethod init;
|
||||
} TIFFCodec;
|
||||
@@ -584,6 +584,7 @@ extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *,
|
||||
tmsize_t cc);
|
||||
extern tmsize_t TIFFWriteRawTile(TIFF *tif, uint32_t tile, void *data,
|
||||
tmsize_t cc);
|
||||
extern uint64_t TIFFGetMaxCompressionRatio(TIFF *tif);
|
||||
extern int TIFFDataWidth(
|
||||
TIFFDataType); /* table of tag datatype widths within TIFF file. */
|
||||
extern void TIFFSetWriteOffset(TIFF *tif, toff_t off);
|
||||
@@ -659,7 +660,7 @@ extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *,
|
||||
unsigned short field_bit; /* bit in fieldsset bit vector */
|
||||
unsigned char field_oktochange; /* if true, can change while writing */
|
||||
unsigned char field_passcount; /* if true, pass dir count on set */
|
||||
char *field_name; /* ASCII name */
|
||||
const char *field_name; /* ASCII name */
|
||||
} TIFFFieldInfo;
|
||||
|
||||
extern int TIFFMergeFieldInfo(TIFF *, const TIFFFieldInfo[], uint32_t);
|
||||
|
||||
62
3rdparty/libtiff/tiffiop.h
vendored
62
3rdparty/libtiff/tiffiop.h
vendored
@@ -38,6 +38,7 @@
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_ASSERT_H
|
||||
@@ -94,6 +95,7 @@ typedef int (*TIFFSeekMethod)(TIFF *, uint32_t);
|
||||
typedef void (*TIFFPostMethod)(TIFF *tif, uint8_t *buf, tmsize_t size);
|
||||
typedef uint32_t (*TIFFStripMethod)(TIFF *, uint32_t);
|
||||
typedef void (*TIFFTileMethod)(TIFF *, uint32_t *, uint32_t *);
|
||||
typedef uint64_t (*TIFFGetMaxCompressionRatioMethod)(TIFF *);
|
||||
|
||||
struct TIFFOffsetAndDirNumber
|
||||
{
|
||||
@@ -143,13 +145,18 @@ struct tiff
|
||||
0x800000U /* read buffer (tif_rawdata) points into mmap() memory */
|
||||
#define TIFF_DEFERSTRILELOAD \
|
||||
0x1000000U /* defer strip/tile offset/bytecount array loading. */
|
||||
#define TIFF_LAZYSTRILELOAD \
|
||||
0x2000000U /* lazy/ondemand loading of strip/tile offset/bytecount values. \
|
||||
Only used if TIFF_DEFERSTRILELOAD is set and in read-only \
|
||||
mode */
|
||||
#define TIFF_LAZYSTRILELOAD_DONE \
|
||||
0x2000000U /* set when lazy/ondemand loading of strip/tile \
|
||||
offset/bytecount values has been done. Only used if \
|
||||
TIFF_DEFERSTRILELOAD is set and in read-only mode */
|
||||
#define TIFF_CHOPPEDUPARRAYS \
|
||||
0x4000000U /* set when allocChoppedUpStripArrays() has modified strip \
|
||||
array */
|
||||
#define TIFF_LAZYSTRILELOAD_ASKED \
|
||||
0x8000000U /* set when lazy/ondemand loading of strip/tile \
|
||||
offset/bytecount values has been requested on opening ('O' \
|
||||
flag) */
|
||||
|
||||
uint64_t tif_diroff; /* file offset of current directory */
|
||||
uint64_t tif_nextdiroff; /* file offset of following directory */
|
||||
uint64_t tif_lastdiroff; /* file offset of last directory written so far */
|
||||
@@ -162,7 +169,6 @@ struct tiff
|
||||
tif_customdir; /* custom IFDs are separated from the main ones */
|
||||
TIFFHeaderUnion tif_header; /* file's header block Classic/BigTIFF union */
|
||||
uint16_t tif_header_size; /* file's header block and its length */
|
||||
uint32_t tif_row; /* current scanline */
|
||||
|
||||
/* There are IFDs in the file and an "active" IFD in memory,
|
||||
* from which fields are "set" and "get".
|
||||
@@ -184,7 +190,6 @@ struct tiff
|
||||
* - TIFF_NON_EXISTENT_DIR_NUMBER means 'dont know number of IFDs'.
|
||||
* - 0 means 'empty file opened for writing, but no IFD written yet' */
|
||||
tdir_t tif_curdircount;
|
||||
uint32_t tif_curstrip; /* current strip for read/write */
|
||||
uint64_t tif_curoff; /* current offset for read/write */
|
||||
uint64_t tif_lastvalidoff; /* last valid offset allowed for rewrite in
|
||||
place. Used only by TIFFAppendToStrip() */
|
||||
@@ -192,10 +197,6 @@ struct tiff
|
||||
/* SubIFD support */
|
||||
uint16_t tif_nsubifd; /* remaining subifds to write */
|
||||
uint64_t tif_subifdoff; /* offset for patching SubIFD link */
|
||||
/* tiling support */
|
||||
uint32_t tif_col; /* current column (offset by row too) */
|
||||
uint32_t tif_curtile; /* current tile for read/write */
|
||||
tmsize_t tif_tilesize; /* # of bytes in a tile */
|
||||
/* compression scheme hooks */
|
||||
int tif_decodestatus;
|
||||
TIFFBoolMethod tif_fixuptags; /* called in TIFFReadDirectory */
|
||||
@@ -216,10 +217,10 @@ struct tiff
|
||||
TIFFVoidMethod tif_cleanup; /* cleanup state routine */
|
||||
TIFFStripMethod tif_defstripsize; /* calculate/constrain strip size */
|
||||
TIFFTileMethod tif_deftilesize; /* calculate/constrain tile size */
|
||||
uint8_t *tif_data; /* compression scheme private data */
|
||||
/* returns maximum compression ratio for current compression method */
|
||||
TIFFGetMaxCompressionRatioMethod tif_getmaxcompressionratio;
|
||||
uint8_t *tif_data; /* compression scheme private data */
|
||||
/* input/output buffering */
|
||||
tmsize_t tif_scanlinesize; /* # of bytes in a scanline */
|
||||
tmsize_t tif_scanlineskew; /* scanline skew for reading strips */
|
||||
uint8_t *tif_rawdata; /* raw data buffer */
|
||||
tmsize_t tif_rawdatasize; /* # of bytes in raw data buffer */
|
||||
tmsize_t tif_rawdataoff; /* rawdata offset within strip */
|
||||
@@ -295,13 +296,15 @@ struct TIFFOpenOptions
|
||||
* Default Read/Seek/Write definitions.
|
||||
*/
|
||||
#ifndef ReadOK
|
||||
#define ReadOK(tif, buf, size) (TIFFReadFile((tif), (buf), (size)) == (size))
|
||||
#define ReadOK(tif, buf, size) \
|
||||
(TIFFReadFile((tif), (buf), (size)) == (tmsize_t)(size))
|
||||
#endif
|
||||
#ifndef SeekOK
|
||||
#define SeekOK(tif, off) _TIFFSeekOK(tif, off)
|
||||
#endif
|
||||
#ifndef WriteOK
|
||||
#define WriteOK(tif, buf, size) (TIFFWriteFile((tif), (buf), (size)) == (size))
|
||||
#define WriteOK(tif, buf, size) \
|
||||
(TIFFWriteFile((tif), (buf), (size)) == (tmsize_t)(size))
|
||||
#endif
|
||||
|
||||
/* NB: the uint32_t casts are to silence certain ANSI-C compilers */
|
||||
@@ -315,19 +318,19 @@ struct TIFFOpenOptions
|
||||
(((uint32_t)(x) / (uint32_t)(y)) + \
|
||||
((((uint32_t)(x) % (uint32_t)(y)) != 0) ? 1 : 0))
|
||||
#define TIFFhowmany8_32(x) \
|
||||
(((x)&0x07) ? ((uint32_t)(x) >> 3) + 1 : (uint32_t)(x) >> 3)
|
||||
#define TIFFroundup_32(x, y) (TIFFhowmany_32(x, y) * (y))
|
||||
(((x) & 0x07) ? ((uint32_t)(x) >> 3) + 1 : (uint32_t)(x) >> 3)
|
||||
#define TIFFroundup_32(x, y) ((uint32_t)(TIFFhowmany_32(x, y) * (uint32_t)(y)))
|
||||
#define TIFFhowmany_64(x, y) \
|
||||
((((uint64_t)(x)) + (((uint64_t)(y)) - 1)) / ((uint64_t)(y)))
|
||||
#define TIFFhowmany8_64(x) \
|
||||
(((x)&0x07) ? ((uint64_t)(x) >> 3) + 1 : (uint64_t)(x) >> 3)
|
||||
#define TIFFroundup_64(x, y) (TIFFhowmany_64(x, y) * (y))
|
||||
(((x) & 0x07) ? ((uint64_t)(x) >> 3) + 1 : (uint64_t)(x) >> 3)
|
||||
#define TIFFroundup_64(x, y) ((uint64_t)(TIFFhowmany_64(x, y) * (uint64_t)(y)))
|
||||
|
||||
/* Safe multiply which returns zero if there is an *unsigned* integer overflow.
|
||||
* This macro is not safe for *signed* integer types */
|
||||
#define TIFFSafeMultiply(t, v, m) \
|
||||
((((t)(m) != (t)0) && (((t)(((v) * (m)) / (m))) == (t)(v))) \
|
||||
? (t)((v) * (m)) \
|
||||
((((t)(m) != (t)0) && (((t)((((t)(v)) * ((t)(m))) / ((t)(m)))) == (t)(v))) \
|
||||
? (t)(((t)(v)) * ((t)(m))) \
|
||||
: (t)0)
|
||||
|
||||
#define TIFFmax(A, B) ((A) > (B) ? (A) : (B))
|
||||
@@ -335,6 +338,10 @@ struct TIFFOpenOptions
|
||||
|
||||
#define TIFFArrayCount(a) (sizeof(a) / sizeof((a)[0]))
|
||||
|
||||
/* Float/double equality macros that suppress -Wfloat-equal warnings */
|
||||
#define TIFF_FLOAT_EQ(x, y) (!(fabsf((x) - (y)) > 0.0f))
|
||||
#define TIFF_DOUBLE_EQ(x, y) (!(fabs((x) - (y)) > 0.0))
|
||||
|
||||
/*
|
||||
Support for large files.
|
||||
|
||||
@@ -355,7 +362,7 @@ struct TIFFOpenOptions
|
||||
*/
|
||||
#if defined(HAVE_FSEEKO)
|
||||
#define fseek(stream, offset, whence) fseeko(stream, offset, whence)
|
||||
#define ftell(stream, offset, whence) ftello(stream, offset, whence)
|
||||
#define ftell(stream) ftello(stream)
|
||||
#endif
|
||||
#endif
|
||||
#if defined(_WIN32) && \
|
||||
@@ -459,9 +466,18 @@ extern "C"
|
||||
|
||||
extern uint32_t _TIFFMultiply32(TIFF *, uint32_t, uint32_t, const char *);
|
||||
extern uint64_t _TIFFMultiply64(TIFF *, uint64_t, uint64_t, const char *);
|
||||
extern uint64_t _TIFFAdd64(TIFF *, uint64_t, uint64_t, const char *);
|
||||
extern tmsize_t _TIFFMultiplySSize(TIFF *, tmsize_t, tmsize_t,
|
||||
const char *);
|
||||
extern tmsize_t _TIFFAddSSize(TIFF *, tmsize_t, tmsize_t, const char *);
|
||||
extern tmsize_t _TIFFCastUInt64ToSSize(TIFF *, uint64_t, const char *);
|
||||
extern uint32_t _TIFFCastUInt64ToUInt32(TIFF *, uint64_t, const char *);
|
||||
extern uint64_t _TIFFComputeRowSize64(TIFF *, uint32_t, uint16_t, uint16_t,
|
||||
const char *);
|
||||
extern tmsize_t _TIFFComputeRowOffset(TIFF *, tmsize_t rowstride, uint32_t,
|
||||
const char *);
|
||||
extern uint64_t _TIFFComputeBitOffset(TIFF *, uint32_t, uint16_t, uint16_t,
|
||||
const char *);
|
||||
extern void *_TIFFCheckMalloc(TIFF *, tmsize_t, tmsize_t, const char *);
|
||||
extern void *_TIFFCheckRealloc(TIFF *, void *, tmsize_t, tmsize_t,
|
||||
const char *);
|
||||
@@ -471,6 +487,8 @@ extern "C"
|
||||
|
||||
extern void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif);
|
||||
|
||||
extern uint64_t _TIFFStrileSize64(TIFF *tif, uint32_t nrows, int isStrip);
|
||||
|
||||
extern tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif,
|
||||
uint32_t strip,
|
||||
void **buf,
|
||||
|
||||
2
3rdparty/openjpeg/CMakeLists.txt
vendored
2
3rdparty/openjpeg/CMakeLists.txt
vendored
@@ -23,7 +23,7 @@ ocv_warnings_disable(CMAKE_C_FLAGS
|
||||
# OPENJPEG version number, useful for packaging and doxygen doc:
|
||||
set(OPENJPEG_VERSION_MAJOR 2)
|
||||
set(OPENJPEG_VERSION_MINOR 5)
|
||||
set(OPENJPEG_VERSION_BUILD 3)
|
||||
set(OPENJPEG_VERSION_BUILD 4)
|
||||
set(OPENJPEG_VERSION
|
||||
"${OPENJPEG_VERSION_MAJOR}.${OPENJPEG_VERSION_MINOR}.${OPENJPEG_VERSION_BUILD}")
|
||||
set(PACKAGE_VERSION
|
||||
|
||||
@@ -1542,11 +1542,7 @@ if(WITH_WEBP OR HAVE_WEBP)
|
||||
endif()
|
||||
|
||||
if(WITH_AVIF OR HAVE_AVIF)
|
||||
if(libavif_VERSION)
|
||||
status(" AVIF:" AVIF_FOUND THEN "${AVIF_LIBRARY} (ver ${libavif_VERSION})" ELSE "NO")
|
||||
else()
|
||||
status(" AVIF:" AVIF_FOUND THEN "${AVIF_LIBRARY}" ELSE "NO")
|
||||
endif()
|
||||
status(" AVIF:" AVIF_FOUND THEN "${AVIF_LIBRARY} (ver ${AVIF_VERSION})" ELSE "NO")
|
||||
endif()
|
||||
|
||||
if(WITH_SPNG)
|
||||
|
||||
10
README.md
10
README.md
@@ -7,7 +7,7 @@
|
||||
* Courses: <https://opencv.org/courses>
|
||||
* Docs: <https://docs.opencv.org/4.x/>
|
||||
* Q&A forum: <https://forum.opencv.org>
|
||||
* previous forum (read only): <http://answers.opencv.org>
|
||||
* previous forum (read only): <https://answers.opencv.org>
|
||||
* Issue tracking: <https://github.com/opencv/opencv/issues>
|
||||
* Additional OpenCV functionality: <https://github.com/opencv/opencv_contrib>
|
||||
* Donate to OpenCV: <https://opencv.org/support/>
|
||||
@@ -28,9 +28,9 @@ Please read the [contribution guidelines](https://github.com/opencv/opencv/wiki/
|
||||
### Additional Resources
|
||||
|
||||
* [Submit your OpenCV-based project](https://form.jotform.com/233105358823151) for inclusion in Community Friday on opencv.org
|
||||
* [Subscribe to the OpenCV YouTube Channel](http://youtube.com/@opencvofficial) featuring OpenCV Live, an hour-long streaming show
|
||||
* [Follow OpenCV on LinkedIn](http://linkedin.com/company/opencv/) for daily posts showing the state-of-the-art in computer vision & AI
|
||||
* [Subscribe to the OpenCV YouTube Channel](https://youtube.com/@opencvofficial) featuring OpenCV Live, an hour-long streaming show
|
||||
* [Follow OpenCV on LinkedIn](https://linkedin.com/company/opencv/) for daily posts showing the state-of-the-art in computer vision & AI
|
||||
* [Apply to be an OpenCV Volunteer](https://form.jotform.com/232745316792159) to help organize events and online campaigns as well as amplify them
|
||||
* [Follow OpenCV on Mastodon](http://mastodon.social/@opencv) in the Fediverse
|
||||
* [Follow OpenCV on Twitter](https://twitter.com/opencvlive)
|
||||
* [Follow OpenCV on Mastodon](https://mastodon.social/@opencv) in the Fediverse
|
||||
* [Follow OpenCV on X](https://x.com/opencvofficial)
|
||||
* [OpenCV.ai](https://opencv.ai): Computer Vision and AI development services from the OpenCV team.
|
||||
|
||||
@@ -872,20 +872,24 @@ macro(ocv_compiler_optimization_fill_cpu_config)
|
||||
# define CV_CPU_HAS_SUPPORT_${OPT} 1
|
||||
# define CV_CPU_CALL_${OPT}(fn, args) return (cpu_baseline::fn args)
|
||||
# define CV_CPU_CALL_${OPT}_(fn, args) return (opt_${OPT}::fn args)
|
||||
# define CV_CPU_GET_FN_PTR_${OPT}(fn) return (cpu_baseline::fn)
|
||||
#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_${OPT}
|
||||
# define CV_TRY_${OPT} 1
|
||||
# define CV_CPU_FORCE_${OPT} 0
|
||||
# define CV_CPU_HAS_SUPPORT_${OPT} (cv::checkHardwareSupport(CV_CPU_${OPT}))
|
||||
# define CV_CPU_CALL_${OPT}(fn, args) if (CV_CPU_HAS_SUPPORT_${OPT}) return (opt_${OPT}::fn args)
|
||||
# define CV_CPU_CALL_${OPT}_(fn, args) if (CV_CPU_HAS_SUPPORT_${OPT}) return (opt_${OPT}::fn args)
|
||||
# define CV_CPU_GET_FN_PTR_${OPT}(fn) if (CV_CPU_HAS_SUPPORT_${OPT}) return (opt_${OPT}::fn)
|
||||
#else
|
||||
# define CV_TRY_${OPT} 0
|
||||
# define CV_CPU_FORCE_${OPT} 0
|
||||
# define CV_CPU_HAS_SUPPORT_${OPT} 0
|
||||
# define CV_CPU_CALL_${OPT}(fn, args)
|
||||
# define CV_CPU_CALL_${OPT}_(fn, args)
|
||||
# define CV_CPU_GET_FN_PTR_${OPT}(fn)
|
||||
#endif
|
||||
#define __CV_CPU_DISPATCH_CHAIN_${OPT}(fn, args, mode, ...) CV_CPU_CALL_${OPT}(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__))
|
||||
#define __CV_CPU_DISPATCH_CHAIN_FN_${OPT}(fn, mode, ...) CV_CPU_GET_FN_PTR_${OPT}(fn); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_FN_ ## mode(fn, __VA_ARGS__))
|
||||
")
|
||||
endif()
|
||||
endforeach()
|
||||
@@ -893,6 +897,8 @@ macro(ocv_compiler_optimization_fill_cpu_config)
|
||||
set(OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE}
|
||||
#define CV_CPU_CALL_BASELINE(fn, args) return (cpu_baseline::fn args)
|
||||
#define __CV_CPU_DISPATCH_CHAIN_BASELINE(fn, args, mode, ...) CV_CPU_CALL_BASELINE(fn, args) /* last in sequence */
|
||||
#define CV_CPU_GET_FN_PTR_BASELINE(fn) return (cpu_baseline::fn)
|
||||
#define __CV_CPU_DISPATCH_CHAIN_FN_BASELINE(fn, mode, ...) CV_CPU_GET_FN_PTR_BASELINE(fn) /* last in sequence */
|
||||
")
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
# AVIF_INCLUDE_DIRS - where to find avif/avif.h, etc.
|
||||
# AVIF_LIBRARIES - List of libraries when using AVIF.
|
||||
# AVIF_FOUND - True if AVIF is found.
|
||||
# AVIF_VERSION - libavif version string (e.g. "1.4.0")
|
||||
#=============================================================================
|
||||
|
||||
# Look for the header file.
|
||||
@@ -40,7 +41,41 @@ else()
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(AVIF DEFAULT_MSG AVIF_LIBRARY AVIF_INCLUDE_DIR)
|
||||
|
||||
SET(AVIF_LIBRARIES ${AVIF_LIBRARY})
|
||||
SET(AVIF_INCLUDE_DIRS ${AVIF_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
if(NOT AVIF_FOUND)
|
||||
UNSET(AVIF_LIBRARIES)
|
||||
UNSET(AVIF_INCLUDE_DIRS)
|
||||
UNSET(AVIF_VERSION)
|
||||
return()
|
||||
endif()
|
||||
|
||||
SET(AVIF_LIBRARIES ${AVIF_LIBRARY})
|
||||
SET(AVIF_INCLUDE_DIRS ${AVIF_INCLUDE_DIR})
|
||||
|
||||
# unset(libavif_VERSION) # For debugging: uncomment to test fallback version extraction when find_package(libavif) cannot find libavif
|
||||
|
||||
if(NOT libavif_VERSION)
|
||||
find_file(AVIF_H NAMES avif/avif.h PATHS ${AVIF_INCLUDE_DIRS} NO_DEFAULT_PATH)
|
||||
|
||||
if(AVIF_H)
|
||||
file(STRINGS "${AVIF_H}" AVIF_MAJOR_LINE REGEX "^#define[ \t]+AVIF_VERSION_MAJOR[ \t]+[0-9]+")
|
||||
file(STRINGS "${AVIF_H}" AVIF_MINOR_LINE REGEX "^#define[ \t]+AVIF_VERSION_MINOR[ \t]+[0-9]+")
|
||||
file(STRINGS "${AVIF_H}" AVIF_PATCH_LINE REGEX "^#define[ \t]+AVIF_VERSION_PATCH[ \t]+[0-9]+")
|
||||
|
||||
string(REGEX REPLACE ".*AVIF_VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" AVIF_MAJOR "${AVIF_MAJOR_LINE}")
|
||||
string(REGEX REPLACE ".*AVIF_VERSION_MINOR[ \t]+([0-9]+).*" "\\1" AVIF_MINOR "${AVIF_MINOR_LINE}")
|
||||
string(REGEX REPLACE ".*AVIF_VERSION_PATCH[ \t]+([0-9]+).*" "\\1" AVIF_PATCH "${AVIF_PATCH_LINE}")
|
||||
|
||||
if(AVIF_MAJOR MATCHES "^[0-9]+$" AND AVIF_MINOR MATCHES "^[0-9]+$" AND AVIF_PATCH MATCHES "^[0-9]+$")
|
||||
SET(libavif_VERSION "${AVIF_MAJOR}.${AVIF_MINOR}.${AVIF_PATCH}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
UNSET(AVIF_H CACHE)
|
||||
UNSET(AVIF_H)
|
||||
endif()
|
||||
|
||||
if(libavif_VERSION)
|
||||
SET(AVIF_VERSION "${libavif_VERSION}")
|
||||
endif()
|
||||
|
||||
@@ -88,9 +88,7 @@ macro(ippiw_setup PATH BUILD)
|
||||
set(IPP_IW_LIBRARY ippiw)
|
||||
set(IPP_IW_INCLUDES "${IPP_IW_PATH}/include")
|
||||
set(IPP_IW_LIBRARIES ${IPP_IW_LIBRARY})
|
||||
if(NOT EXISTS "${IPP_IW_PATH}/CMakeLists.txt")
|
||||
file(COPY "${OpenCV_SOURCE_DIR}/3rdparty/ippicv/CMakeLists.txt" DESTINATION "${IPP_IW_PATH}")
|
||||
endif()
|
||||
file(COPY "${OpenCV_SOURCE_DIR}/3rdparty/ippicv/CMakeLists.txt" DESTINATION "${IPP_IW_PATH}") # always rewrite IPP cmake files
|
||||
add_subdirectory("${IPP_IW_PATH}/" ${OpenCV_BINARY_DIR}/3rdparty/ippiw)
|
||||
|
||||
set(HAVE_IPP_IW 1)
|
||||
|
||||
@@ -45,6 +45,11 @@ else()
|
||||
endif()
|
||||
|
||||
if(NOT ZLIB_FOUND)
|
||||
if(NOT BUILD_ZLIB)
|
||||
message(WARNING "ZLIB library has not been found, falling back to built-in version. "
|
||||
"Set ZLIB_ROOT or ZLIB_DIR variable so that find_package(ZLIB) would be able to find it. "
|
||||
"See find_package and FindZLIB cmake documentation for details.")
|
||||
endif()
|
||||
ocv_clear_vars(ZLIB_LIBRARY ZLIB_LIBRARIES ZLIB_INCLUDE_DIR)
|
||||
|
||||
set(ZLIB_LIBRARY zlib CACHE INTERNAL "")
|
||||
@@ -60,7 +65,7 @@ endif()
|
||||
# --- libavif (optional) ---
|
||||
|
||||
if(WITH_AVIF)
|
||||
ocv_clear_internal_cache_vars(AVIF_LIBRARY AVIF_INCLUDE_DIR)
|
||||
ocv_clear_internal_cache_vars(AVIF_LIBRARIES AVIF_INCLUDE_DIRS)
|
||||
include(cmake/OpenCVFindAVIF.cmake)
|
||||
if(AVIF_FOUND)
|
||||
set(HAVE_AVIF 1)
|
||||
@@ -83,6 +88,12 @@ if(WITH_JPEG)
|
||||
endif()
|
||||
|
||||
if(NOT JPEG_FOUND)
|
||||
if(NOT BUILD_JPEG)
|
||||
message(WARNING "JPEG library has not been found, falling back to built-in version. "
|
||||
"Add the external installation prefix to CMAKE_PREFIX_PATH, or set JPEG_INCLUDE_DIR "
|
||||
"and JPEG_LIBRARY, so that FindJPEG can locate it. "
|
||||
"See FindJPEG cmake documentation for details.")
|
||||
endif()
|
||||
ocv_clear_vars(JPEG_LIBRARY JPEG_INCLUDE_DIR)
|
||||
|
||||
if(NOT BUILD_JPEG_TURBO_DISABLE)
|
||||
@@ -134,55 +145,6 @@ if(WITH_JPEG)
|
||||
set(HAVE_JPEG YES)
|
||||
endif()
|
||||
|
||||
# --- libtiff (optional, should be searched after zlib and libjpeg) ---
|
||||
if(WITH_TIFF)
|
||||
if(BUILD_TIFF)
|
||||
ocv_clear_vars(TIFF_FOUND)
|
||||
else()
|
||||
ocv_clear_internal_cache_vars(TIFF_LIBRARY TIFF_INCLUDE_DIR)
|
||||
if(QNX)
|
||||
set(TIFF_LIBRARY tiff)
|
||||
set(TIFF_LIBRARIES tiff)
|
||||
set(TIFF_FOUND TRUE)
|
||||
else()
|
||||
include(FindTIFF)
|
||||
endif()
|
||||
if(TIFF_FOUND)
|
||||
ocv_parse_header("${TIFF_INCLUDE_DIR}/tiff.h" TIFF_VERSION_LINES TIFF_VERSION_CLASSIC TIFF_VERSION_BIG TIFF_VERSION TIFF_BIGTIFF_VERSION)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT TIFF_FOUND)
|
||||
ocv_clear_vars(TIFF_LIBRARY TIFF_LIBRARIES TIFF_INCLUDE_DIR)
|
||||
|
||||
set(TIFF_LIBRARY libtiff CACHE INTERNAL "")
|
||||
set(TIFF_LIBRARIES ${TIFF_LIBRARY})
|
||||
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libtiff")
|
||||
set(TIFF_INCLUDE_DIR "${${TIFF_LIBRARY}_SOURCE_DIR}" "${${TIFF_LIBRARY}_BINARY_DIR}" CACHE INTERNAL "")
|
||||
ocv_parse_header("${${TIFF_LIBRARY}_SOURCE_DIR}/tiff.h" TIFF_VERSION_LINES TIFF_VERSION_CLASSIC TIFF_VERSION_BIG TIFF_VERSION TIFF_BIGTIFF_VERSION)
|
||||
endif()
|
||||
|
||||
if(TIFF_VERSION_CLASSIC AND NOT TIFF_VERSION)
|
||||
set(TIFF_VERSION ${TIFF_VERSION_CLASSIC})
|
||||
endif()
|
||||
|
||||
if(TIFF_BIGTIFF_VERSION AND NOT TIFF_VERSION_BIG)
|
||||
set(TIFF_VERSION_BIG ${TIFF_BIGTIFF_VERSION})
|
||||
endif()
|
||||
|
||||
if(NOT TIFF_VERSION_STRING AND TIFF_INCLUDE_DIR)
|
||||
foreach(_TIFF_INCLUDE_DIR IN LISTS TIFF_INCLUDE_DIR)
|
||||
if(EXISTS "${_TIFF_INCLUDE_DIR}/tiffvers.h")
|
||||
file(STRINGS "${_TIFF_INCLUDE_DIR}/tiffvers.h" tiff_version_str REGEX "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version .*")
|
||||
string(REGEX REPLACE "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version +([^ \\n]*).*" "\\1" TIFF_VERSION_STRING "${tiff_version_str}")
|
||||
unset(tiff_version_str)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(HAVE_TIFF YES)
|
||||
endif()
|
||||
|
||||
# --- libwebp (optional) ---
|
||||
|
||||
if(WITH_WEBP)
|
||||
@@ -201,6 +163,11 @@ endif()
|
||||
if(WITH_WEBP AND NOT WEBP_FOUND
|
||||
AND (NOT ANDROID OR HAVE_CPUFEATURES)
|
||||
)
|
||||
if(NOT BUILD_WEBP)
|
||||
message(WARNING "WebP library has not been found, falling back to built-in version. "
|
||||
"Set WEBP_INCLUDE_DIR and WEBP_LIBRARY, or add the external installation prefix to "
|
||||
"CMAKE_PREFIX_PATH, so that the external WebP can be located.")
|
||||
endif()
|
||||
ocv_clear_vars(WEBP_LIBRARY WEBP_INCLUDE_DIR)
|
||||
set(WEBP_LIBRARY libwebp CACHE INTERNAL "")
|
||||
set(WEBP_LIBRARIES ${WEBP_LIBRARY})
|
||||
@@ -241,6 +208,61 @@ if(NOT WEBP_VERSION AND WEBP_INCLUDE_DIR)
|
||||
set(WEBP_VERSION "decoder: ${WEBP_DECODER_ABI_VERSION}, encoder: ${WEBP_ENCODER_ABI_VERSION}, demux: ${WEBP_DEMUX_ABI_VERSION}")
|
||||
endif()
|
||||
|
||||
# --- libtiff (optional, should be searched after zlib, libjpeg and libwebp) ---
|
||||
if(WITH_TIFF)
|
||||
if(BUILD_TIFF)
|
||||
ocv_clear_vars(TIFF_FOUND)
|
||||
else()
|
||||
ocv_clear_internal_cache_vars(TIFF_LIBRARY TIFF_INCLUDE_DIR)
|
||||
if(QNX)
|
||||
set(TIFF_LIBRARY tiff)
|
||||
set(TIFF_LIBRARIES tiff)
|
||||
set(TIFF_FOUND TRUE)
|
||||
else()
|
||||
include(FindTIFF)
|
||||
endif()
|
||||
if(TIFF_FOUND)
|
||||
ocv_parse_header("${TIFF_INCLUDE_DIR}/tiff.h" TIFF_VERSION_LINES TIFF_VERSION_CLASSIC TIFF_VERSION_BIG TIFF_VERSION TIFF_BIGTIFF_VERSION)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT TIFF_FOUND)
|
||||
if(NOT BUILD_TIFF)
|
||||
message(WARNING "TIFF library has not been found, falling back to built-in version. "
|
||||
"Add the external installation prefix to CMAKE_PREFIX_PATH, or set TIFF_INCLUDE_DIR "
|
||||
"and TIFF_LIBRARY, so that FindTIFF can locate it. "
|
||||
"See FindTIFF cmake documentation for details.")
|
||||
endif()
|
||||
ocv_clear_vars(TIFF_LIBRARY TIFF_LIBRARIES TIFF_INCLUDE_DIR)
|
||||
|
||||
set(TIFF_LIBRARY libtiff CACHE INTERNAL "")
|
||||
set(TIFF_LIBRARIES ${TIFF_LIBRARY})
|
||||
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libtiff")
|
||||
set(TIFF_INCLUDE_DIR "${${TIFF_LIBRARY}_SOURCE_DIR}" "${${TIFF_LIBRARY}_BINARY_DIR}" CACHE INTERNAL "")
|
||||
ocv_parse_header("${${TIFF_LIBRARY}_SOURCE_DIR}/tiff.h" TIFF_VERSION_LINES TIFF_VERSION_CLASSIC TIFF_VERSION_BIG TIFF_VERSION TIFF_BIGTIFF_VERSION)
|
||||
endif()
|
||||
|
||||
if(TIFF_VERSION_CLASSIC AND NOT TIFF_VERSION)
|
||||
set(TIFF_VERSION ${TIFF_VERSION_CLASSIC})
|
||||
endif()
|
||||
|
||||
if(TIFF_BIGTIFF_VERSION AND NOT TIFF_VERSION_BIG)
|
||||
set(TIFF_VERSION_BIG ${TIFF_BIGTIFF_VERSION})
|
||||
endif()
|
||||
|
||||
if(NOT TIFF_VERSION_STRING AND TIFF_INCLUDE_DIR)
|
||||
foreach(_TIFF_INCLUDE_DIR IN LISTS TIFF_INCLUDE_DIR)
|
||||
if(EXISTS "${_TIFF_INCLUDE_DIR}/tiffvers.h")
|
||||
file(STRINGS "${_TIFF_INCLUDE_DIR}/tiffvers.h" tiff_version_str REGEX "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version .*")
|
||||
string(REGEX REPLACE "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version +([^ \\n]*).*" "\\1" TIFF_VERSION_STRING "${tiff_version_str}")
|
||||
unset(tiff_version_str)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(HAVE_TIFF YES)
|
||||
endif()
|
||||
|
||||
# --- libjxl (optional) ---
|
||||
if(WITH_JPEGXL)
|
||||
ocv_clear_vars(HAVE_JPEGXL)
|
||||
@@ -353,6 +375,11 @@ if(NOT HAVE_SPNG AND WITH_PNG)
|
||||
endif()
|
||||
|
||||
if(NOT PNG_FOUND)
|
||||
if(NOT BUILD_PNG)
|
||||
message(WARNING "PNG library has not been found, falling back to built-in version. "
|
||||
"Set PNG_ROOT or PNG_DIR variable so that find_package(PNG) would be able to find it. "
|
||||
"See find_package and FindPNG cmake documentation for details.")
|
||||
endif()
|
||||
ocv_clear_vars(PNG_LIBRARY PNG_LIBRARIES PNG_INCLUDE_DIR PNG_DEFINITIONS)
|
||||
|
||||
set(PNG_LIBRARY libpng CACHE INTERNAL "")
|
||||
|
||||
@@ -224,6 +224,9 @@ if(WITH_KLEIDICV)
|
||||
set(HAVE_KLEIDICV ON)
|
||||
endif()
|
||||
endif()
|
||||
if(HAVE_KLEIDICV AND EXISTS "${KLEIDICV_SOURCE_PATH}/LICENSES/Apache-2.0.txt")
|
||||
ocv_install_3rdparty_licenses(KleidiCV "${KLEIDICV_SOURCE_PATH}/LICENSES/Apache-2.0.txt")
|
||||
endif()
|
||||
endif(WITH_KLEIDICV)
|
||||
|
||||
# --- FastCV ---
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#include <riscv_vector.h>
|
||||
|
||||
#ifdef __THEAD_VERSION__
|
||||
#if defined(__THEAD_VERSION__) && (defined(__riscv_v) && __riscv_v == 7000)
|
||||
int test()
|
||||
{
|
||||
const float src[] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
@@ -16,7 +16,7 @@ To Install Emscripten, follow instructions of [Emscripten SDK](https://emscripte
|
||||
|
||||
For example:
|
||||
@code{.bash}
|
||||
./emsdk update
|
||||
git pull # Note: ./emsdk update is deprecated in modern emsdk; use git pull to update the repository.
|
||||
./emsdk install latest
|
||||
./emsdk activate latest
|
||||
@endcode
|
||||
@@ -37,13 +37,14 @@ emcmake sh -c 'echo ${EMSCRIPTEN}'
|
||||
@endcode
|
||||
|
||||
|
||||
The version 2.0.10 of emscripten is verified for latest WebAssembly. Please check the version of Emscripten to use the newest features of WebAssembly.
|
||||
The Emscripten SDK is continuously updated. If you encounter build errors with the latest version, please install and activate a specific version explicitly.
|
||||
|
||||
For example:
|
||||
@code{.bash}
|
||||
./emsdk update
|
||||
./emsdk install 2.0.10
|
||||
./emsdk activate 2.0.10
|
||||
git pull
|
||||
./emsdk list # to show available versions. v6.0.9 is used in the following steps.
|
||||
./emsdk install 6.0.9
|
||||
./emsdk activate 6.0.9
|
||||
@endcode
|
||||
|
||||
Obtaining OpenCV Source Code
|
||||
|
||||
@@ -308,6 +308,16 @@
|
||||
publisher = {GitHub},
|
||||
howpublished = {\url{https://blog.chatfield.io/simple-method-for-distance-to-ellipse/}},
|
||||
}
|
||||
@inproceedings{Claus05a,
|
||||
author = {Claus, David and Fitzgibbon, Andrew W.},
|
||||
title = {A Rational Function Lens Distortion Model for General Cameras},
|
||||
booktitle = {IEEE Conference on Computer Vision and Pattern Recognition},
|
||||
volume = {1},
|
||||
pages = {213--219},
|
||||
year = {2005},
|
||||
publisher = {IEEE},
|
||||
doi = {10.1109/CVPR.2005.43},
|
||||
}
|
||||
@article{Chaumette06,
|
||||
author = {Chaumette, Fran{\c c}ois and Hutchinson, S.},
|
||||
title = {{Visual servo control, Part I: Basic approaches}},
|
||||
@@ -552,6 +562,16 @@
|
||||
publisher = {BMVA Press},
|
||||
url = {https://www.researchgate.net/profile/Robert_Fisher5/publication/2237785_A_Buyer's_Guide_to_Conic_Fitting/links/0fcfd50f59aeded518000000/A-Buyers-Guide-to-Conic-Fitting.pdf}
|
||||
}
|
||||
@inproceedings{Fitzgibbon01,
|
||||
author = {Fitzgibbon, Andrew W.},
|
||||
title = {Simultaneous Linear Estimation of Multiple View Geometry and Lens Distortion},
|
||||
booktitle = {IEEE Conference on Computer Vision and Pattern Recognition},
|
||||
volume = {1},
|
||||
pages = {125--132},
|
||||
year = {2001},
|
||||
publisher = {IEEE},
|
||||
doi = {10.1109/CVPR.2001.990465},
|
||||
}
|
||||
@inproceedings{oy1998NumericallySD,
|
||||
title = {Numerically Stable Direct Least Squares Fitting of Ellipses},
|
||||
author = {Radim Hal oy and Jan Flusser},
|
||||
|
||||
@@ -123,15 +123,22 @@ FourCC code is passed as `cv.VideoWriter_fourcc('M','J','P','G')` or
|
||||
`cv.VideoWriter_fourcc(*'MJPG')` for MJPG.
|
||||
|
||||
The below code captures from a camera, flips every frame in the vertical direction, and saves the video.
|
||||
|
||||
@note The frame size passed to `cv.VideoWriter` must match the resolution of the captured frames; otherwise, frame writing will fail.
|
||||
|
||||
@code{.py}
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
cap = cv.VideoCapture(0)
|
||||
|
||||
# Get camera frame resolution
|
||||
frame_width = int(cap.get(cv.CAP_PROP_FRAME_WIDTH))
|
||||
frame_height = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT))
|
||||
|
||||
# Define the codec and create VideoWriter object
|
||||
fourcc = cv.VideoWriter_fourcc(*'XVID')
|
||||
out = cv.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
|
||||
out = cv.VideoWriter('output.avi', fourcc, 20.0, (frame_width, frame_height))
|
||||
|
||||
while cap.isOpened():
|
||||
ret, frame = cap.read()
|
||||
@@ -151,4 +158,4 @@ while cap.isOpened():
|
||||
cap.release()
|
||||
out.release()
|
||||
cv.destroyAllWindows()
|
||||
@endcode
|
||||
@endcode
|
||||
@@ -107,8 +107,8 @@ In addition to this instruction you can use some video guide, for example [this
|
||||
|
||||

|
||||
|
||||
8. Before using any OpenCV function you have to load the library first. If you application includes other OpenCV-dependent native libraries you should load them ***after*** OpenCV initialization.
|
||||
Add the folowing code to load the library at app start:
|
||||
8. Before using any OpenCV function you have to load the library first. If your application includes other OpenCV-dependent native libraries you should load them ***after*** OpenCV initialization.
|
||||
Add the following code to load the library at app start:
|
||||
@snippet samples/android/tutorial-1-camerapreview/src/org/opencv/samples/tutorial1/Tutorial1Activity.java ocv_loader_init
|
||||
Like this:
|
||||

|
||||
@@ -143,8 +143,8 @@ but OpenCV loading with Maven Central.
|
||||
@endcode
|
||||
`4.9.0` may be replaced by any version available as [official release](https://central.sonatype.com/artifact/org.opencv/opencv).
|
||||
|
||||
4. Before using any OpenCV function you have to load the library first. If you application includes other
|
||||
OpenCV-dependent native libraries you should load them ***after*** OpenCV initialization. Add the folowing
|
||||
4. Before using any OpenCV function you have to load the library first. If your application includes other
|
||||
OpenCV-dependent native libraries you should load them ***after*** OpenCV initialization. Add the following
|
||||
code to load the library at app start:
|
||||
@snippet samples/android/tutorial-1-camerapreview/src/org/opencv/samples/tutorial1/Tutorial1Activity.java ocv_loader_init
|
||||
Like this:
|
||||
|
||||
@@ -86,6 +86,44 @@ int armpl_hal_dctFree2D(cvhalDFT *context);
|
||||
#undef cv_hal_dctFree2D
|
||||
#define cv_hal_dctFree2D armpl_hal_dctFree2D
|
||||
|
||||
int armpl_hal_gemm32f(const float* src1, size_t src1_step, const float* src2, size_t src2_step,
|
||||
float alpha, const float* src3, size_t src3_step, float beta, float* dst, size_t dst_step,
|
||||
int m, int n, int k, int flags);
|
||||
int armpl_hal_gemm64f(const double* src1, size_t src1_step, const double* src2, size_t src2_step,
|
||||
double alpha, const double* src3, size_t src3_step, double beta, double* dst, size_t dst_step,
|
||||
int m, int n, int k, int flags);
|
||||
int armpl_hal_gemm32fc(const float* src1, size_t src1_step, const float* src2, size_t src2_step,
|
||||
float alpha, const float* src3, size_t src3_step, float beta, float* dst, size_t dst_step,
|
||||
int m, int n, int k, int flags);
|
||||
int armpl_hal_gemm64fc(const double* src1, size_t src1_step, const double* src2, size_t src2_step,
|
||||
double alpha, const double* src3, size_t src3_step, double beta, double* dst, size_t dst_step,
|
||||
int m, int n, int k, int flags);
|
||||
|
||||
#undef cv_hal_gemm32f
|
||||
#define cv_hal_gemm32f armpl_hal_gemm32f
|
||||
#undef cv_hal_gemm64f
|
||||
#define cv_hal_gemm64f armpl_hal_gemm64f
|
||||
#undef cv_hal_gemm32fc
|
||||
#define cv_hal_gemm32fc armpl_hal_gemm32fc
|
||||
#undef cv_hal_gemm64fc
|
||||
#define cv_hal_gemm64fc armpl_hal_gemm64fc
|
||||
|
||||
int armpl_hal_SVD32f(float* src, size_t src_step, float* w, float* u, size_t u_step, float* vt, size_t vt_step, int m, int n, int flags);
|
||||
int armpl_hal_SVD64f(double* src, size_t src_step, double* w, double* u, size_t u_step, double* vt, size_t vt_step, int m, int n, int flags);
|
||||
|
||||
#undef cv_hal_SVD32f
|
||||
#define cv_hal_SVD32f armpl_hal_SVD32f
|
||||
#undef cv_hal_SVD64f
|
||||
#define cv_hal_SVD64f armpl_hal_SVD64f
|
||||
|
||||
int armpl_hal_LU32f(float* a, size_t a_step, int m, float* b, size_t b_step, int n, int* info);
|
||||
int armpl_hal_LU64f(double* a, size_t a_step, int m, double* b, size_t b_step, int n, int* info);
|
||||
|
||||
#undef cv_hal_LU32f
|
||||
#define cv_hal_LU32f armpl_hal_LU32f
|
||||
#undef cv_hal_LU64f
|
||||
#define cv_hal_LU64f armpl_hal_LU64f
|
||||
|
||||
#endif // HAVE_ARMPL
|
||||
|
||||
#endif // OPENCV_ARMPL_HAL_CORE_HPP
|
||||
|
||||
@@ -3,9 +3,322 @@
|
||||
#include "armpl_hal_core.hpp"
|
||||
|
||||
#include <fftw3.h>
|
||||
#include <cblas.h>
|
||||
#include <lapacke.h>
|
||||
#include <algorithm>
|
||||
#include <complex>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
|
||||
#define ARMPL_GEMM_MIN_WORK_VOLUME 10000
|
||||
#define ARMPL_SVD_SMALL_MATRIX_THRESH 33
|
||||
#define ARMPL_LU_SMALL_MATRIX_THRESH 100
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename fptype> static inline void
|
||||
armpl_transpose(const fptype *src, size_t src_ld, fptype *dst, size_t dst_ld, size_t m, size_t n)
|
||||
{
|
||||
for (size_t i = 0; i < m; i++)
|
||||
for (size_t j = 0; j < n; j++)
|
||||
dst[j*dst_ld + i] = src[i*src_ld + j];
|
||||
}
|
||||
|
||||
template <typename fptype> static inline void
|
||||
armpl_copy_matrix(const fptype *src, size_t src_ld, fptype *dst, size_t dst_ld, size_t m, size_t n)
|
||||
{
|
||||
for (size_t i = 0; i < m; i++)
|
||||
std::copy(src + i*src_ld, src + i*src_ld + n, dst + i*dst_ld);
|
||||
}
|
||||
|
||||
template <typename fptype> static inline void
|
||||
armpl_set_value(fptype *dst, size_t dst_ld, fptype value, size_t m, size_t n)
|
||||
{
|
||||
for (size_t i = 0; i < m; i++)
|
||||
std::fill(dst + i*dst_ld, dst + i*dst_ld + n, value);
|
||||
}
|
||||
|
||||
static inline void
|
||||
armpl_cblas_gemm(CBLAS_TRANSPOSE transA, CBLAS_TRANSPOSE transB, int a_m, int d_n, int a_n,
|
||||
float alpha, const float *src1, int ldsrc1, const float *src2, int ldsrc2,
|
||||
float beta, float *dst, int lddst)
|
||||
{
|
||||
cblas_sgemm(CblasRowMajor, transA, transB, a_m, d_n, a_n, alpha, src1, ldsrc1, src2, ldsrc2, beta, dst, lddst);
|
||||
}
|
||||
|
||||
static inline void
|
||||
armpl_cblas_gemm(CBLAS_TRANSPOSE transA, CBLAS_TRANSPOSE transB, int a_m, int d_n, int a_n,
|
||||
double alpha, const double *src1, int ldsrc1, const double *src2, int ldsrc2,
|
||||
double beta, double *dst, int lddst)
|
||||
{
|
||||
cblas_dgemm(CblasRowMajor, transA, transB, a_m, d_n, a_n, alpha, src1, ldsrc1, src2, ldsrc2, beta, dst, lddst);
|
||||
}
|
||||
|
||||
static inline void
|
||||
armpl_cblas_gemm(CBLAS_TRANSPOSE transA, CBLAS_TRANSPOSE transB, int a_m, int d_n, int a_n,
|
||||
std::complex<float> alpha, const std::complex<float> *src1, int ldsrc1,
|
||||
const std::complex<float> *src2, int ldsrc2,
|
||||
std::complex<float> beta, std::complex<float> *dst, int lddst)
|
||||
{
|
||||
cblas_cgemm(CblasRowMajor, transA, transB, a_m, d_n, a_n, &alpha, src1, ldsrc1, src2, ldsrc2, &beta, dst, lddst);
|
||||
}
|
||||
|
||||
static inline void
|
||||
armpl_cblas_gemm(CBLAS_TRANSPOSE transA, CBLAS_TRANSPOSE transB, int a_m, int d_n, int a_n,
|
||||
std::complex<double> alpha, const std::complex<double> *src1, int ldsrc1,
|
||||
const std::complex<double> *src2, int ldsrc2,
|
||||
std::complex<double> beta, std::complex<double> *dst, int lddst)
|
||||
{
|
||||
cblas_zgemm(CblasRowMajor, transA, transB, a_m, d_n, a_n, &alpha, src1, ldsrc1, src2, ldsrc2, &beta, dst, lddst);
|
||||
}
|
||||
|
||||
template <typename elemtype, typename scalartype> static inline int
|
||||
armpl_gemm_impl(const elemtype *src1, size_t src1_step, const elemtype *src2, size_t src2_step, scalartype alpha,
|
||||
const elemtype *src3, size_t src3_step, scalartype beta, elemtype *dst, size_t dst_step,
|
||||
int a_m, int a_n, int d_n, int flags)
|
||||
{
|
||||
int ldsrc1 = (int)(src1_step / sizeof(elemtype));
|
||||
int ldsrc2 = (int)(src2_step / sizeof(elemtype));
|
||||
int ldsrc3 = (int)(src3_step / sizeof(elemtype));
|
||||
int lddst = (int)(dst_step / sizeof(elemtype));
|
||||
int c_m, c_n, d_m;
|
||||
CBLAS_TRANSPOSE transA, transB;
|
||||
elemtype eAlpha = (elemtype)alpha;
|
||||
elemtype eBeta = (elemtype)beta;
|
||||
|
||||
transB = (flags & CV_HAL_GEMM_2_T) ? CblasTrans : CblasNoTrans;
|
||||
d_m = (flags & CV_HAL_GEMM_1_T) ? a_n : a_m;
|
||||
|
||||
if (flags & CV_HAL_GEMM_3_T)
|
||||
{
|
||||
c_m = d_n;
|
||||
c_n = d_m;
|
||||
}
|
||||
else
|
||||
{
|
||||
c_m = d_m;
|
||||
c_n = d_n;
|
||||
}
|
||||
|
||||
if (flags & CV_HAL_GEMM_1_T)
|
||||
{
|
||||
transA = CblasTrans;
|
||||
std::swap(a_n, a_m);
|
||||
}
|
||||
else
|
||||
{
|
||||
transA = CblasNoTrans;
|
||||
}
|
||||
|
||||
if (src3 != dst && beta != 0.0 && src3_step != 0)
|
||||
{
|
||||
if (flags & CV_HAL_GEMM_3_T)
|
||||
armpl_transpose(src3, ldsrc3, dst, lddst, c_m, c_n);
|
||||
else
|
||||
armpl_copy_matrix(src3, ldsrc3, dst, lddst, c_m, c_n);
|
||||
}
|
||||
else if (src3 == dst && (flags & CV_HAL_GEMM_3_T))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
else if (src3_step == 0 && beta != 0.0)
|
||||
armpl_set_value(dst, lddst, elemtype(), d_m, d_n);
|
||||
|
||||
armpl_cblas_gemm(transA, transB, a_m, d_n, a_n, eAlpha, src1, ldsrc1, src2, ldsrc2, eBeta, dst, lddst);
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool armpl_gemm_below_min_volume(int m, int n, int k)
|
||||
{
|
||||
return (double)m * n * k < ARMPL_GEMM_MIN_WORK_VOLUME;
|
||||
}
|
||||
|
||||
int armpl_hal_gemm32f(const float *src1, size_t src1_step, const float *src2, size_t src2_step, float alpha,
|
||||
const float *src3, size_t src3_step, float beta, float *dst, size_t dst_step,
|
||||
int m, int n, int k, int flags)
|
||||
{
|
||||
if (armpl_gemm_below_min_volume(m, n, k))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
return armpl_gemm_impl<float, float>(src1, src1_step, src2, src2_step, alpha, src3, src3_step, beta, dst, dst_step, m, n, k, flags);
|
||||
}
|
||||
|
||||
int armpl_hal_gemm64f(const double *src1, size_t src1_step, const double *src2, size_t src2_step, double alpha,
|
||||
const double *src3, size_t src3_step, double beta, double *dst, size_t dst_step,
|
||||
int m, int n, int k, int flags)
|
||||
{
|
||||
if (armpl_gemm_below_min_volume(m, n, k))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
return armpl_gemm_impl<double, double>(src1, src1_step, src2, src2_step, alpha, src3, src3_step, beta, dst, dst_step, m, n, k, flags);
|
||||
}
|
||||
|
||||
int armpl_hal_gemm32fc(const float *src1, size_t src1_step, const float *src2, size_t src2_step, float alpha,
|
||||
const float *src3, size_t src3_step, float beta, float *dst, size_t dst_step,
|
||||
int m, int n, int k, int flags)
|
||||
{
|
||||
if (armpl_gemm_below_min_volume(m, n, k))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
typedef std::complex<float> cplx;
|
||||
return armpl_gemm_impl<cplx, float>(reinterpret_cast<const cplx*>(src1), src1_step, reinterpret_cast<const cplx*>(src2), src2_step, alpha,
|
||||
reinterpret_cast<const cplx*>(src3), src3_step, beta, reinterpret_cast<cplx*>(dst), dst_step, m, n, k, flags);
|
||||
}
|
||||
|
||||
int armpl_hal_gemm64fc(const double *src1, size_t src1_step, const double *src2, size_t src2_step, double alpha,
|
||||
const double *src3, size_t src3_step, double beta, double *dst, size_t dst_step,
|
||||
int m, int n, int k, int flags)
|
||||
{
|
||||
if (armpl_gemm_below_min_volume(m, n, k))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
typedef std::complex<double> cplx;
|
||||
return armpl_gemm_impl<cplx, double>(reinterpret_cast<const cplx*>(src1), src1_step, reinterpret_cast<const cplx*>(src2), src2_step, alpha,
|
||||
reinterpret_cast<const cplx*>(src3), src3_step, beta, reinterpret_cast<cplx*>(dst), dst_step, m, n, k, flags);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
static inline armpl_int_t
|
||||
armpl_lapacke_gesdd(char jobz, int m, int n, float *a, int lda, float *s, float *u, int ldu, float *vt, int ldvt)
|
||||
{
|
||||
return LAPACKE_sgesdd(LAPACK_COL_MAJOR, jobz, m, n, a, lda, s, u, ldu, vt, ldvt);
|
||||
}
|
||||
|
||||
static inline armpl_int_t
|
||||
armpl_lapacke_gesdd(char jobz, int m, int n, double *a, int lda, double *s, double *u, int ldu, double *vt, int ldvt)
|
||||
{
|
||||
return LAPACKE_dgesdd(LAPACK_COL_MAJOR, jobz, m, n, a, lda, s, u, ldu, vt, ldvt);
|
||||
}
|
||||
|
||||
template <typename fptype> static inline void
|
||||
armpl_transpose_square_inplace(fptype *a, size_t lda, size_t n)
|
||||
{
|
||||
for (size_t i = 0; i < n - 1; i++)
|
||||
for (size_t j = i + 1; j < n; j++)
|
||||
std::swap(a[j*lda + i], a[i*lda + j]);
|
||||
}
|
||||
|
||||
template <typename fptype> static inline int
|
||||
armpl_svd(fptype *src, size_t src_step, fptype *w, fptype *u, size_t u_step, fptype *vt, size_t vt_step, int m, int n, int flags)
|
||||
{
|
||||
int lda = (int)(src_step / sizeof(fptype));
|
||||
int ldu = (int)(u_step / sizeof(fptype));
|
||||
int ldv = (int)(vt_step / sizeof(fptype));
|
||||
std::vector<fptype> ubuf;
|
||||
|
||||
char jobz = ' ';
|
||||
if (flags & CV_HAL_SVD_NO_UV)
|
||||
{
|
||||
ldv = 1;
|
||||
jobz = 'N';
|
||||
}
|
||||
else if ((flags & CV_HAL_SVD_SHORT_UV) && (flags & CV_HAL_SVD_MODIFY_A))
|
||||
jobz = 'O';
|
||||
else if ((flags & CV_HAL_SVD_SHORT_UV) && !(flags & CV_HAL_SVD_MODIFY_A))
|
||||
jobz = 'S';
|
||||
else if (flags & CV_HAL_SVD_FULL_UV)
|
||||
jobz = 'A';
|
||||
|
||||
if ((flags & CV_HAL_SVD_MODIFY_A) && (flags & CV_HAL_SVD_FULL_UV))
|
||||
{
|
||||
ubuf.resize((size_t)m * m);
|
||||
u = ubuf.data();
|
||||
ldu = m;
|
||||
}
|
||||
|
||||
armpl_int_t linfo = armpl_lapacke_gesdd(jobz, m, n, src, lda, w, u, ldu, vt, ldv);
|
||||
|
||||
if (linfo != 0)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
if (!(flags & CV_HAL_SVD_NO_UV))
|
||||
armpl_transpose_square_inplace(vt, ldv, n);
|
||||
|
||||
if ((flags & CV_HAL_SVD_MODIFY_A) && (flags & CV_HAL_SVD_FULL_UV))
|
||||
{
|
||||
for (int i = 0; i < m; i++)
|
||||
std::copy(u + i*m, u + i*m + m, src + i*lda);
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
static inline armpl_int_t armpl_lapacke_gesv(int m, int n, float *a, int lda, armpl_int_t *ipiv, float *b, int ldb){
|
||||
return LAPACKE_sgesv(LAPACK_ROW_MAJOR, m, n, a, lda, ipiv, b, ldb);
|
||||
}
|
||||
static inline armpl_int_t armpl_lapacke_gesv(int m, int n, double *a, int lda, armpl_int_t *ipiv, double *b, int ldb){
|
||||
return LAPACKE_dgesv(LAPACK_ROW_MAJOR, m, n, a, lda, ipiv, b, ldb);
|
||||
}
|
||||
static inline armpl_int_t armpl_lapacke_getrf(int m, float *a, int lda, armpl_int_t *ipiv){
|
||||
return LAPACKE_sgetrf(LAPACK_ROW_MAJOR, m, m, a, lda, ipiv);
|
||||
}
|
||||
static inline armpl_int_t armpl_lapacke_getrf(int m, double *a, int lda, armpl_int_t *ipiv){
|
||||
return LAPACKE_dgetrf(LAPACK_ROW_MAJOR, m, m, a, lda, ipiv);
|
||||
}
|
||||
|
||||
template <typename fptype> static inline int
|
||||
armpl_lu(fptype *a, size_t a_step, int m, fptype *b, size_t b_step, int n, int *info)
|
||||
{
|
||||
if(!info)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
int lda = (int)(a_step / sizeof(fptype));
|
||||
std::vector<armpl_int_t> ipiv(m);
|
||||
armpl_int_t linfo;
|
||||
|
||||
if (b)
|
||||
{
|
||||
int ldb = (int)(b_step / sizeof(fptype));
|
||||
linfo = armpl_lapacke_gesv(m, n, a, lda, ipiv.data(), b, ldb);
|
||||
}
|
||||
else
|
||||
{
|
||||
linfo = armpl_lapacke_getrf(m, a, lda, ipiv.data());
|
||||
}
|
||||
|
||||
if (linfo < 0)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
if (linfo == 0)
|
||||
{
|
||||
int sign = 0;
|
||||
for (int i = 0; i < m; i++)
|
||||
sign ^= (ipiv[i] != i + 1);
|
||||
*info = sign ? -1 : 1;
|
||||
}
|
||||
else
|
||||
*info = 0;
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int armpl_hal_SVD32f(float *src, size_t src_step, float *w, float *u, size_t u_step, float *vt, size_t vt_step, int m, int n, int flags)
|
||||
{
|
||||
if (m < ARMPL_SVD_SMALL_MATRIX_THRESH)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
return armpl_svd(src, src_step, w, u, u_step, vt, vt_step, m, n, flags);
|
||||
}
|
||||
|
||||
int armpl_hal_SVD64f(double *src, size_t src_step, double *w, double *u, size_t u_step, double *vt, size_t vt_step, int m, int n, int flags)
|
||||
{
|
||||
if (m < ARMPL_SVD_SMALL_MATRIX_THRESH)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
return armpl_svd(src, src_step, w, u, u_step, vt, vt_step, m, n, flags);
|
||||
}
|
||||
|
||||
int armpl_hal_LU32f(float *a, size_t a_step, int m, float *b, size_t b_step, int n, int *info) {
|
||||
if (m < ARMPL_LU_SMALL_MATRIX_THRESH)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
return armpl_lu(a, a_step, m, b, b_step, n, info);
|
||||
}
|
||||
int armpl_hal_LU64f(double *a, size_t a_step, int m, double *b, size_t b_step, int n, int *info) {
|
||||
if (m < ARMPL_LU_SMALL_MATRIX_THRESH)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
return armpl_lu(a, a_step, m, b, b_step, n, info);
|
||||
}
|
||||
|
||||
enum ArmPLDFTMode
|
||||
{
|
||||
ARMPL_DFT_C2C,
|
||||
|
||||
@@ -697,7 +697,7 @@ TegraBinaryOpScale_Invoker(addWeighted, addWeighted, 3, scales[0], scales[1], sc
|
||||
src1, sz1, \
|
||||
src2, sz2, \
|
||||
dst, sz, \
|
||||
scale, \
|
||||
(float)scale, \
|
||||
CAROTENE_NS::CONVERT_POLICY_SATURATE), \
|
||||
CV_HAL_ERROR_OK \
|
||||
: CV_HAL_ERROR_NOT_IMPLEMENTED \
|
||||
@@ -721,7 +721,7 @@ TegraBinaryOpScale_Invoker(addWeighted, addWeighted, 3, scales[0], scales[1], sc
|
||||
CAROTENE_NS::reciprocal(CAROTENE_NS::Size2D(w, h), \
|
||||
src2, sz2, \
|
||||
dst, sz, \
|
||||
scale, \
|
||||
(float)scale, \
|
||||
CAROTENE_NS::CONVERT_POLICY_SATURATE), \
|
||||
CV_HAL_ERROR_OK \
|
||||
: CV_HAL_ERROR_NOT_IMPLEMENTED \
|
||||
@@ -739,13 +739,13 @@ TegraBinaryOpScale_Invoker(addWeighted, addWeighted, 3, scales[0], scales[1], sc
|
||||
)
|
||||
|
||||
#undef cv_hal_mul8u
|
||||
#define cv_hal_mul8u TEGRA_MUL
|
||||
#define cv_hal_mul8u(src1, sz1, src2, sz2, dst, sz, w, h, scale) TEGRA_MUL(src1, sz1, src2, sz2, dst, sz, w, h, (float)(scale))
|
||||
#undef cv_hal_mul8s
|
||||
#define cv_hal_mul8s TEGRA_MUL
|
||||
#define cv_hal_mul8s(src1, sz1, src2, sz2, dst, sz, w, h, scale) TEGRA_MUL(src1, sz1, src2, sz2, dst, sz, w, h, (float)(scale))
|
||||
#undef cv_hal_mul16u
|
||||
#define cv_hal_mul16u TEGRA_MUL
|
||||
#define cv_hal_mul16u(src1, sz1, src2, sz2, dst, sz, w, h, scale) TEGRA_MUL(src1, sz1, src2, sz2, dst, sz, w, h, (float)(scale))
|
||||
#undef cv_hal_mul16s
|
||||
#define cv_hal_mul16s TEGRA_MUL
|
||||
#define cv_hal_mul16s(src1, sz1, src2, sz2, dst, sz, w, h, scale) TEGRA_MUL(src1, sz1, src2, sz2, dst, sz, w, h, (float)(scale))
|
||||
#undef cv_hal_mul32s
|
||||
#define cv_hal_mul32s TEGRA_MUL
|
||||
#undef cv_hal_mul32f
|
||||
@@ -788,7 +788,7 @@ TegraBinaryOpScale_Invoker(addWeighted, addWeighted, 3, scales[0], scales[1], sc
|
||||
src1, sz1, \
|
||||
src2, sz2, \
|
||||
dst, sz, \
|
||||
((double *)scales)[0], ((double *)scales)[1], ((double *)scales)[2]), \
|
||||
(float)((double *)scales)[0], (float)((double *)scales)[1], (float)((double *)scales)[2]), \
|
||||
CV_HAL_ERROR_OK \
|
||||
: CV_HAL_ERROR_NOT_IMPLEMENTED \
|
||||
)
|
||||
@@ -1029,7 +1029,7 @@ TegraRowOp_Invoker(combine4, combine4, 4, 1, 0, RANGE_DATA(ST, src1_data, sizeof
|
||||
|
||||
TegraRowOp_Invoker(phase, phase, 2, 1, 1, RANGE_DATA(ST, src1_data, sizeof(CAROTENE_NS::f32)), range.end-range.start,
|
||||
RANGE_DATA(ST, src2_data, sizeof(CAROTENE_NS::f32)), range.end-range.start,
|
||||
RANGE_DATA(DT, dst1_data, sizeof(CAROTENE_NS::f32)), range.end-range.start, val)
|
||||
RANGE_DATA(DT, dst1_data, sizeof(CAROTENE_NS::f32)), range.end-range.start, (float)val)
|
||||
#define TEGRA_FASTATAN(y, x, dst, len, angleInDegrees) \
|
||||
( \
|
||||
CAROTENE_NS::isSupportedConfiguration() ? \
|
||||
@@ -1441,13 +1441,13 @@ inline int TEGRA_MORPHFREE(cvhalFilter2D *context)
|
||||
(dst_width + 0.5)/inv_scale_x + 0.5 >= src_width && (dst_height + 0.5)/inv_scale_y + 0.5 >= src_height && \
|
||||
std::abs(dst_width / inv_scale_x - src_width) < 0.1 && std::abs(dst_height / inv_scale_y - src_height) < 0.1 ? \
|
||||
CAROTENE_NS::resizeLinearOpenCV(CAROTENE_NS::Size2D(src_width, src_height), CAROTENE_NS::Size2D(dst_width, dst_height), \
|
||||
src_data, src_step, dst_data, dst_step, 1.0/inv_scale_x, 1.0/inv_scale_y, ((src_type >> CV_CN_SHIFT) + 1)), \
|
||||
src_data, src_step, dst_data, dst_step, (float)(1.0/inv_scale_x), (float)(1.0/inv_scale_y), ((src_type >> CV_CN_SHIFT) + 1)), \
|
||||
CV_HAL_ERROR_OK : CV_HAL_ERROR_NOT_IMPLEMENTED : \
|
||||
interpolation == CV_HAL_INTER_AREA ? \
|
||||
CV_MAT_DEPTH(src_type) == CV_8U && CAROTENE_NS::isResizeAreaSupported(1.0/inv_scale_x, 1.0/inv_scale_y, ((src_type >> CV_CN_SHIFT) + 1)) && \
|
||||
CV_MAT_DEPTH(src_type) == CV_8U && CAROTENE_NS::isResizeAreaSupported((float)(1.0/inv_scale_x), (float)(1.0/inv_scale_y), ((src_type >> CV_CN_SHIFT) + 1)) && \
|
||||
std::abs(dst_width / inv_scale_x - src_width) < 0.1 && std::abs(dst_height / inv_scale_y - src_height) < 0.1 ? \
|
||||
CAROTENE_NS::resizeAreaOpenCV(CAROTENE_NS::Size2D(src_width, src_height), CAROTENE_NS::Size2D(dst_width, dst_height), \
|
||||
src_data, src_step, dst_data, dst_step, 1.0/inv_scale_x, 1.0/inv_scale_y, ((src_type >> CV_CN_SHIFT) + 1)), \
|
||||
src_data, src_step, dst_data, dst_step, (float)(1.0/inv_scale_x), (float)(1.0/inv_scale_y), ((src_type >> CV_CN_SHIFT) + 1)), \
|
||||
CV_HAL_ERROR_OK : CV_HAL_ERROR_NOT_IMPLEMENTED : \
|
||||
/*nearest neighbour interpolation disabled due to rounding accuracy issues*/ \
|
||||
/*interpolation == CV_HAL_INTER_NEAREST ? \
|
||||
|
||||
@@ -1607,6 +1607,15 @@ void downsample_bilinear_8uc1(const Size2D &ssize, const Size2D &dsize,
|
||||
|
||||
cwi[k] = (short)floorf((col2[k] - c) * (1 << SHIFT_BITS) + 0.5f);
|
||||
|
||||
// When the sample point falls left of the first source column
|
||||
// (c < 0, happens for the leftmost destination pixel when
|
||||
// upscaling horizontally, wr < 1), the left-column weight cwi
|
||||
// overflows past the full-scale value (1<<SHIFT_BITS) and the
|
||||
// interpolation extrapolates beyond the source range. Clamp the
|
||||
// weight so the leftmost pixel is taken as-is, matching the
|
||||
// OpenCV scalar / OpenCL behaviour (if (x<0) x=0, u=0).
|
||||
if(c < 0.f) cwi[k] = (1 << SHIFT_BITS);
|
||||
|
||||
if(col1[k] < 0) col1[k] = 0;
|
||||
if(col2[k] >= (ptrdiff_t)ssize.width) col2[k] = ssize.width-1;
|
||||
}
|
||||
@@ -1770,6 +1779,11 @@ downsample_bilinear_8uc1_col_loop8:
|
||||
|
||||
cwi[k] = (s16)floorf((col2[k] - c) * (1 << SHIFT_BITS) + 0.5f);
|
||||
|
||||
// See the 16-wide loop above: clamp the left-column weight when the
|
||||
// sample point is left of the first source column (horizontal
|
||||
// upscaling, wr < 1) to avoid extrapolation on the leftmost pixel.
|
||||
if(c < 0.f) cwi[k] = (1 << SHIFT_BITS);
|
||||
|
||||
if(col1[k] < 0) col1[k] = 0;
|
||||
if(col2[k] >= (ptrdiff_t)ssize.width) col2[k] = (ptrdiff_t)ssize.width-1;
|
||||
}
|
||||
|
||||
@@ -164,6 +164,9 @@ int fastcv_hal_transpose2d(
|
||||
if (src_data == dst_data)
|
||||
CV_HAL_RETURN_NOT_IMPLEMENTED("In-place not supported");
|
||||
|
||||
if (src_step % element_size != 0 || dst_step % element_size != 0)
|
||||
CV_HAL_RETURN_NOT_IMPLEMENTED("Row step not divisible by the element size is not supported");
|
||||
|
||||
fcvStatus status = FASTCV_SUCCESS;
|
||||
|
||||
switch (element_size)
|
||||
|
||||
@@ -19,6 +19,7 @@ add_library(ipphal STATIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/deriv_ipp.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/resize_ipp.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/box_filter_ipp.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/bilateral_filter_ipp.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/sum_ipp.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/color_ipp.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/filter_ipp.cpp"
|
||||
@@ -26,6 +27,8 @@ add_library(ipphal STATIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/canny_ipp.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/threshold_ipp.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/distancetransform_ipp.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/histogram_ipp.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/samplers_ipp.cpp"
|
||||
)
|
||||
|
||||
#TODO: HAVE_IPP_ICV and HAVE_IPP_IW added as private macro till OpenCV itself is
|
||||
@@ -45,6 +48,13 @@ if(WITH_IPP_CALLS_ENFORCED)
|
||||
message("WITH_IPP_CALLS_ENFORCED=${WITH_IPP_CALLS_ENFORCED}: enforced IPP calls are enabled in IPP HAL")
|
||||
endif()
|
||||
|
||||
# Enable cv::instr tracing of IPP calls inside the HAL so they show up in the
|
||||
# instrumentation trace / IPP weight. Reuses the engine exported from
|
||||
# opencv_core (symbols resolved at link time as ipphal is archived into core).
|
||||
if(ENABLE_INSTRUMENTATION)
|
||||
target_compile_definitions(ipphal PRIVATE ENABLE_INSTRUMENTATION)
|
||||
endif()
|
||||
|
||||
target_include_directories(ipphal PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-suggest-override)
|
||||
|
||||
|
||||
@@ -35,6 +35,14 @@ int ipp_hal_minMaxIdxMaskStep(const uchar* src_data, size_t src_step, int width,
|
||||
# define IPP_DISABLE_NORM_INF_16U_C1MR 0
|
||||
#endif
|
||||
|
||||
// segmentation fault in ippiNorm[Diff]_Inf_32f_C3CMR with the macOS ippicv (2021.9.1);
|
||||
// the newer Linux/Windows ippicv (2026.0.0) is not affected
|
||||
#if defined(__APPLE__)
|
||||
# define IPP_DISABLE_NORM_INF_32F_C3CMR 1
|
||||
# else
|
||||
# define IPP_DISABLE_NORM_INF_32F_C3CMR 0
|
||||
#endif
|
||||
|
||||
int ipp_hal_norm(const uchar* src, size_t src_step, const uchar* mask, size_t mask_step,
|
||||
int width, int height, int type, int norm_type, double* result);
|
||||
|
||||
|
||||
@@ -66,6 +66,16 @@ int ipp_hal_boxFilter(const uchar* src_data, size_t src_step, uchar* dst_data, s
|
||||
#define cv_hal_boxFilter ipp_hal_boxFilter
|
||||
#endif // defined(HAVE_IPP_IW) && !DISABLE_IPP_BOX_FILTER
|
||||
|
||||
#if defined(HAVE_IPP_IW)
|
||||
|
||||
int ipp_hal_bilateralFilter_offset(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step,
|
||||
int width, int height, int depth, int cn,
|
||||
int margin_left, int margin_top, int margin_right, int margin_bottom,
|
||||
int d, double sigma_color, double sigma_space, int border_type);
|
||||
#undef cv_hal_bilateralFilter_offset
|
||||
#define cv_hal_bilateralFilter_offset ipp_hal_bilateralFilter_offset
|
||||
#endif // HAVE_IPP_IW
|
||||
|
||||
int ipp_hal_remap32f(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height,
|
||||
uchar *dst_data, size_t dst_step, int dst_width, int dst_height,
|
||||
float* mapx, size_t mapx_step, float* mapy, size_t mapy_step,
|
||||
@@ -154,6 +164,17 @@ int ipp_hal_distanceTransform(const uchar* src_data, size_t src_step, uchar* dst
|
||||
#undef cv_hal_distanceTransform
|
||||
#define cv_hal_distanceTransform ipp_hal_distanceTransform
|
||||
|
||||
int ipp_hal_calcHist(const uchar* src_data, size_t src_step, int src_type, int src_width, int src_height,
|
||||
float* hist_data, int hist_size, const float** ranges, bool uniform, bool accumulate);
|
||||
#undef cv_hal_calcHist
|
||||
#define cv_hal_calcHist ipp_hal_calcHist
|
||||
|
||||
int ipp_hal_getRectSubPix(int src_type, const uchar* src_data, size_t src_step, int src_width, int src_height,
|
||||
int patch_type, uchar* patch_data, size_t patch_step, int patch_width, int patch_height,
|
||||
double center_x, double center_y);
|
||||
#undef cv_hal_getRectSubPix
|
||||
#define cv_hal_getRectSubPix ipp_hal_getRectSubPix
|
||||
|
||||
#endif // IPP_VERSION_X100 >= 700
|
||||
|
||||
#define IPP_DISABLE_PERF_CANNY_MT 1 // cv::Canny OpenCV MT performance is better
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
// Copyright (C) 2026, Intel Corporation, all rights reserved.
|
||||
|
||||
#ifndef __IPP_HAL_UTILS_HPP__
|
||||
#define __IPP_HAL_UTILS_HPP__
|
||||
@@ -23,7 +24,22 @@
|
||||
# include "ipp.h"
|
||||
#endif
|
||||
|
||||
// IPP call instrumentation for the standalone IPP HAL.
|
||||
//
|
||||
// The HAL is built as a separate static library that does not include the
|
||||
// internal core/private.hpp, so by default its IPP calls never appear in the
|
||||
// cv::instr trace (reported IPP weight = 0%). When the parent build enables
|
||||
// ENABLE_INSTRUMENTATION, the shared instrumentation.private.hpp provides the
|
||||
// exact same CV_INSTRUMENT_FUN_IPP macro used by core (backed by symbols exported
|
||||
// from libopencv_core, resolved at link time), so HAL IPP calls are traced
|
||||
// identically to in-module ones. Otherwise the no-op passthrough is used.
|
||||
#if !defined(CV_INSTRUMENT_FUN_IPP)
|
||||
#if defined(ENABLE_INSTRUMENTATION)
|
||||
#include "opencv2/core/utils/instrumentation.private.hpp"
|
||||
#else
|
||||
#define CV_INSTRUMENT_FUN_IPP(FUN, ...) ((FUN)(__VA_ARGS__))
|
||||
#endif // defined(ENABLE_INSTRUMENTATION)
|
||||
#endif // !defined(CV_INSTRUMENT_FUN_IPP)
|
||||
|
||||
#define CV_HAL_CHECK_USE_IPP() if(!cv::ipp::useIPP()) return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
|
||||
162
hal/ipp/src/bilateral_filter_ipp.cpp
Normal file
162
hal/ipp/src/bilateral_filter_ipp.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
// Copyright (C) 2026, BigVision LLC, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#include "ipp_hal_imgproc.hpp"
|
||||
|
||||
#ifdef HAVE_IPP_IW
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include "precomp_ipp.hpp"
|
||||
|
||||
#define IPP_BILATERAL_PARALLEL 1
|
||||
|
||||
class ipp_bilateralFilterParallel: public cv::ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
ipp_bilateralFilterParallel(::ipp::IwiImage &_src, ::ipp::IwiImage &_dst, int _radius, Ipp32f _valSquareSigma, Ipp32f _posSquareSigma, ::ipp::IwiBorderType _borderType, bool *_ok):
|
||||
src(_src), dst(_dst)
|
||||
{
|
||||
pOk = _ok;
|
||||
|
||||
radius = _radius;
|
||||
valSquareSigma = _valSquareSigma;
|
||||
posSquareSigma = _posSquareSigma;
|
||||
borderType = _borderType;
|
||||
|
||||
*pOk = true;
|
||||
}
|
||||
~ipp_bilateralFilterParallel() {}
|
||||
|
||||
virtual void operator() (const cv::Range& range) const CV_OVERRIDE
|
||||
{
|
||||
if(*pOk == false)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
::ipp::IwiTile tile = ::ipp::IwiRoi(0, range.start, dst.m_size.width, range.end - range.start);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterBilateral, src, dst, radius, valSquareSigma, posSquareSigma, ::ipp::IwDefault(), borderType, tile);
|
||||
}
|
||||
catch(const ::ipp::IwException &)
|
||||
{
|
||||
*pOk = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
private:
|
||||
::ipp::IwiImage &src;
|
||||
::ipp::IwiImage &dst;
|
||||
|
||||
int radius;
|
||||
Ipp32f valSquareSigma;
|
||||
Ipp32f posSquareSigma;
|
||||
::ipp::IwiBorderType borderType;
|
||||
|
||||
bool *pOk;
|
||||
const ipp_bilateralFilterParallel& operator= (const ipp_bilateralFilterParallel&);
|
||||
};
|
||||
|
||||
int ipp_hal_bilateralFilter_offset(const uchar* src_data, size_t src_step,
|
||||
uchar* dst_data, size_t dst_step,
|
||||
int width, int height, int depth, int cn,
|
||||
int margin_left, int margin_top, int margin_right, int margin_bottom,
|
||||
int d, double sigma_color, double sigma_space, int border_type)
|
||||
{
|
||||
CV_HAL_CHECK_USE_IPP();
|
||||
|
||||
if(!((depth == CV_8U || depth == CV_32F) && (cn == 1 || cn == 3)))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
constexpr double eps = 1e-6;
|
||||
if(sigma_color <= eps || sigma_space <= eps)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
int bt = border_type & ~cv::BORDER_ISOLATED;
|
||||
IppiBorderType ippBorderType =
|
||||
bt == cv::BORDER_CONSTANT ? ippBorderConst :
|
||||
bt == cv::BORDER_REPLICATE ? ippBorderRepl :
|
||||
bt == cv::BORDER_REFLECT_101 ? ippBorderMirror :
|
||||
bt == cv::BORDER_TRANSPARENT ? ippBorderTransp :
|
||||
(IppiBorderType)-1;
|
||||
if((int)ippBorderType == -1)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
int radius = IPP_MAX(((d <= 0) ? cvRound(sigma_space*1.5) : d/2), 1);
|
||||
Ipp32f valSquareSigma = (Ipp32f)(sigma_color*sigma_color);
|
||||
Ipp32f posSquareSigma = (Ipp32f)(sigma_space*sigma_space);
|
||||
|
||||
IwSize marginLeft = margin_left;
|
||||
IwSize marginTop = margin_top;
|
||||
IwSize marginRight = margin_right;
|
||||
IwSize marginBottom = margin_bottom;
|
||||
|
||||
try
|
||||
{
|
||||
::ipp::IwiBorderSize inMemBorder(marginLeft, marginTop, marginRight, marginBottom);
|
||||
|
||||
::ipp::IwiImage iwSrc, iwDst;
|
||||
iwSrc.Init(IwiSize{width, height}, ippiGetDataType(depth), cn,
|
||||
inMemBorder, (void*)src_data, IwSize(src_step));
|
||||
iwDst.Init(IwiSize{width, height}, ippiGetDataType(depth), cn,
|
||||
IwiBorderSize(), dst_data, IwSize(dst_step));
|
||||
|
||||
// already have physical border
|
||||
int inMemFlags = 0;
|
||||
if(!(border_type & cv::BORDER_ISOLATED))
|
||||
{
|
||||
if(marginLeft)
|
||||
{
|
||||
if(marginLeft >= radius) inMemFlags |= ippBorderInMemLeft;
|
||||
else return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
if(marginTop)
|
||||
{
|
||||
if(marginTop >= radius) inMemFlags |= ippBorderInMemTop;
|
||||
else return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
if(marginRight)
|
||||
{
|
||||
if(marginRight >= radius) inMemFlags |= ippBorderInMemRight;
|
||||
else return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
if(marginBottom)
|
||||
{
|
||||
if(marginBottom >= radius) inMemFlags |= ippBorderInMemBottom;
|
||||
else return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
|
||||
::ipp::IwiBorderType ippBorder((IppiBorderType)(ippBorderType | inMemFlags));
|
||||
|
||||
const int threads = ippiSuggestThreadsNum(iwDst, 2);
|
||||
if(IPP_BILATERAL_PARALLEL && threads > 1) {
|
||||
bool ok = true;
|
||||
cv::Range range(0, (int)iwDst.m_size.height);
|
||||
ipp_bilateralFilterParallel invoker(iwSrc, iwDst, radius, valSquareSigma, posSquareSigma, ippBorder, &ok);
|
||||
if(!ok)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
int maxTiles = (int)iwDst.m_size.height / radius;
|
||||
int numTiles = threads * 4;
|
||||
if(numTiles > maxTiles) {
|
||||
numTiles = (maxTiles / threads) * threads;
|
||||
}
|
||||
cv::parallel_for_(range, invoker, numTiles);
|
||||
|
||||
if(!ok)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
} else {
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterBilateral, iwSrc, iwDst, radius, valSquareSigma, posSquareSigma, ::ipp::IwDefault(), ippBorder);
|
||||
}
|
||||
}
|
||||
catch(const ::ipp::IwException &)
|
||||
{
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
223
hal/ipp/src/histogram_ipp.cpp
Normal file
223
hal/ipp/src/histogram_ipp.cpp
Normal file
@@ -0,0 +1,223 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
// Copyright (C) 2026, BigVision LLC, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#include "ipp_hal_imgproc.hpp"
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/core/utils/tls.hpp>
|
||||
#include "precomp_ipp.hpp"
|
||||
|
||||
#if IPP_VERSION_X100 >= 700
|
||||
|
||||
#define IPP_HISTOGRAM_PARALLEL 1
|
||||
|
||||
namespace cv { namespace ipp { unsigned long long getIppTopFeatures(); } }
|
||||
|
||||
using namespace cv;
|
||||
|
||||
namespace {
|
||||
|
||||
typedef IppStatus(CV_STDCALL * IppiHistogram_C1)(const void* pSrc, int srcStep,
|
||||
IppiSize roiSize, Ipp32u* pHist, const IppiHistogramSpec* pSpec, Ipp8u* pBuffer);
|
||||
|
||||
static IppiHistogram_C1 getIppiHistogramFunction_C1(int type)
|
||||
{
|
||||
IppiHistogram_C1 ippFunction =
|
||||
(type == CV_8UC1) ? (IppiHistogram_C1)ippiHistogram_8u_C1R :
|
||||
(type == CV_16UC1) ? (IppiHistogram_C1)ippiHistogram_16u_C1R :
|
||||
(type == CV_32FC1) ? (IppiHistogram_C1)ippiHistogram_32f_C1R :
|
||||
NULL;
|
||||
|
||||
return ippFunction;
|
||||
}
|
||||
|
||||
class ipp_calcHistParallelTLS
|
||||
{
|
||||
public:
|
||||
ipp_calcHistParallelTLS() {}
|
||||
|
||||
IppAutoBuffer<IppiHistogramSpec> spec;
|
||||
IppAutoBuffer<Ipp8u> buffer;
|
||||
IppAutoBuffer<Ipp32u> thist;
|
||||
};
|
||||
|
||||
class ipp_calcHistParallel: public ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
ipp_calcHistParallel(const Mat &src, Mat &hist, Ipp32s histSize, const float *ranges, bool uniform, bool &ok):
|
||||
ParallelLoopBody(), m_src(src), m_hist(hist), m_ok(ok)
|
||||
{
|
||||
ok = true;
|
||||
|
||||
m_uniform = uniform;
|
||||
m_ranges = ranges;
|
||||
m_histSize = histSize;
|
||||
m_type = ippiGetDataType(src.type());
|
||||
m_levelsNum = histSize+1;
|
||||
ippiHistogram_C1 = getIppiHistogramFunction_C1(src.type());
|
||||
m_fullRoi = ippiSize(src.size());
|
||||
m_bufferSize = 0;
|
||||
m_specSize = 0;
|
||||
if(!ippiHistogram_C1)
|
||||
{
|
||||
ok = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(ippiHistogramGetBufferSize(m_type, m_fullRoi, &m_levelsNum, 1, 1, &m_specSize, &m_bufferSize) < 0)
|
||||
{
|
||||
ok = false;
|
||||
return;
|
||||
}
|
||||
|
||||
hist.setTo(0);
|
||||
}
|
||||
|
||||
virtual void operator() (const Range & range) const CV_OVERRIDE
|
||||
{
|
||||
if(!m_ok)
|
||||
return;
|
||||
|
||||
ipp_calcHistParallelTLS *pTls = m_tls.get();
|
||||
|
||||
IppiSize roi = {m_src.cols, range.end - range.start };
|
||||
bool mtLoop = false;
|
||||
if(m_fullRoi.height != roi.height)
|
||||
mtLoop = true;
|
||||
|
||||
if(!pTls->spec)
|
||||
{
|
||||
pTls->spec.allocate(m_specSize);
|
||||
if(!pTls->spec.get())
|
||||
{
|
||||
m_ok = false;
|
||||
return;
|
||||
}
|
||||
|
||||
pTls->buffer.allocate(m_bufferSize);
|
||||
if(!pTls->buffer.get() && m_bufferSize)
|
||||
{
|
||||
m_ok = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_uniform)
|
||||
{
|
||||
if(ippiHistogramUniformInit(m_type, (Ipp32f*)&m_ranges[0], (Ipp32f*)&m_ranges[1], (Ipp32s*)&m_levelsNum, 1, pTls->spec) < 0)
|
||||
{
|
||||
m_ok = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ippiHistogramInit(m_type, (const Ipp32f**)&m_ranges, (Ipp32s*)&m_levelsNum, 1, pTls->spec) < 0)
|
||||
{
|
||||
m_ok = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pTls->thist.allocate(m_histSize*sizeof(Ipp32u));
|
||||
}
|
||||
|
||||
if(CV_INSTRUMENT_FUN_IPP(ippiHistogram_C1, m_src.ptr(range.start), (int)m_src.step, roi, pTls->thist, pTls->spec, pTls->buffer) < 0)
|
||||
{
|
||||
m_ok = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(mtLoop)
|
||||
{
|
||||
for(int i = 0; i < m_histSize; i++)
|
||||
CV_XADD((int*)(m_hist.ptr(i)), *(int*)((Ipp32u*)pTls->thist + i));
|
||||
}
|
||||
else
|
||||
ippiCopy_32s_C1R((Ipp32s*)pTls->thist.get(), sizeof(Ipp32u), (Ipp32s*)m_hist.ptr(), (int)m_hist.step, ippiSize(1, m_histSize));
|
||||
}
|
||||
|
||||
private:
|
||||
const Mat &m_src;
|
||||
Mat &m_hist;
|
||||
Ipp32s m_histSize;
|
||||
const float *m_ranges;
|
||||
bool m_uniform;
|
||||
|
||||
IppiHistogram_C1 ippiHistogram_C1;
|
||||
IppiSize m_fullRoi;
|
||||
IppDataType m_type;
|
||||
Ipp32s m_levelsNum;
|
||||
int m_bufferSize;
|
||||
int m_specSize;
|
||||
|
||||
mutable Mutex m_syncMutex;
|
||||
TLSData<ipp_calcHistParallelTLS> m_tls;
|
||||
|
||||
volatile bool &m_ok;
|
||||
const ipp_calcHistParallel & operator = (const ipp_calcHistParallel & );
|
||||
};
|
||||
|
||||
static bool ipp_calchist(const Mat &image, Mat &hist, int histSize, const float** ranges, bool uniform, bool accumulate)
|
||||
{
|
||||
#if IPP_VERSION_X100 < 201801
|
||||
// No SSE42 optimization for uniform 32f
|
||||
if(uniform && image.depth() == CV_32F && cv::ipp::getIppTopFeatures() == ippCPUID_SSE42)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
// IPP_DISABLE_HISTOGRAM - https://github.com/opencv/opencv/issues/11544
|
||||
// and https://github.com/opencv/opencv/issues/21595
|
||||
if ((uniform && (ranges[0][1] - ranges[0][0]) != histSize) || abs(ranges[0][0]) != cvFloor(ranges[0][0]))
|
||||
return false;
|
||||
|
||||
Mat ihist = hist;
|
||||
if(accumulate)
|
||||
ihist.create(1, &histSize, CV_32S);
|
||||
|
||||
bool ok = true;
|
||||
int threads = ippiSuggestThreadsNum(image.cols, image.rows, image.elemSize(), (1+((double)ihist.total()/image.total()))*2);
|
||||
Range range(0, image.rows);
|
||||
ipp_calcHistParallel invoker(image, ihist, histSize, ranges[0], uniform, ok);
|
||||
if(!ok)
|
||||
return false;
|
||||
|
||||
if(IPP_HISTOGRAM_PARALLEL && threads > 1)
|
||||
parallel_for_(range, invoker, threads*2);
|
||||
else
|
||||
invoker(range);
|
||||
|
||||
if(ok)
|
||||
{
|
||||
if(accumulate)
|
||||
{
|
||||
IppiSize histRoi = ippiSize(1, histSize);
|
||||
IppAutoBuffer<Ipp32f> fhist(histSize*sizeof(Ipp32f));
|
||||
CV_INSTRUMENT_FUN_IPP(ippiConvert_32s32f_C1R, (Ipp32s*)ihist.ptr(), (int)ihist.step, (Ipp32f*)fhist, sizeof(Ipp32f), histRoi);
|
||||
CV_INSTRUMENT_FUN_IPP(ippiAdd_32f_C1IR, (Ipp32f*)fhist, sizeof(Ipp32f), (Ipp32f*)hist.ptr(), (int)hist.step, histRoi);
|
||||
}
|
||||
else
|
||||
CV_INSTRUMENT_FUN_IPP(ippiConvert_32s32f_C1R, (Ipp32s*)ihist.ptr(), (int)ihist.step, (Ipp32f*)hist.ptr(), (int)hist.step, ippiSize(1, histSize));
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int ipp_hal_calcHist(const uchar* src_data, size_t src_step, int src_type, int src_width, int src_height,
|
||||
float* hist_data, int hist_size, const float** ranges, bool uniform, bool accumulate)
|
||||
{
|
||||
CV_HAL_CHECK_USE_IPP();
|
||||
|
||||
Mat image(src_height, src_width, src_type, (void*)src_data, src_step);
|
||||
Mat hist(1, &hist_size, CV_32F, (void*)hist_data);
|
||||
|
||||
if(ipp_calchist(image, hist, hist_size, ranges, uniform, accumulate))
|
||||
return CV_HAL_ERROR_OK;
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -114,10 +114,12 @@ int ipp_hal_matchTemplate(const uchar* src_data, size_t src_step, int src_width,
|
||||
if(templ.size().area()*4 > img.size().area())
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
#if IPP_VERSION_X100 < 202610
|
||||
// CV_8U SQDIFF/SQDIFF_NORMED suffer from float32 catastrophic cancellation
|
||||
// in IPP's internal accumulators; fall through to the double-precision path instead.
|
||||
// in IPP's internal accumulators (older versions); fall through to the double-precision path instead.
|
||||
if(depth == CV_8U && (method == cv::TM_SQDIFF || method == cv::TM_SQDIFF_NORMED))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
|
||||
if(method == cv::TM_SQDIFF)
|
||||
{
|
||||
|
||||
@@ -50,7 +50,9 @@ int ipp_hal_norm(const uchar* src, size_t src_step, const uchar* mask, size_t ma
|
||||
norm_type == cv::NORM_INF ?
|
||||
(type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_8u_C3CMR :
|
||||
type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_16u_C3CMR :
|
||||
#if (!IPP_DISABLE_NORM_INF_32F_C3CMR)
|
||||
type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_32f_C3CMR :
|
||||
#endif
|
||||
0) :
|
||||
norm_type == cv::NORM_L1 ?
|
||||
(type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_8u_C3CMR :
|
||||
@@ -265,7 +267,9 @@ int ipp_hal_normDiff(const uchar* src1, size_t src1_step, const uchar* src2, siz
|
||||
norm_type == cv::NORM_INF ?
|
||||
(type == CV_8UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_Inf_8u_C3CMR :
|
||||
type == CV_16UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_Inf_16u_C3CMR :
|
||||
#if (!IPP_DISABLE_NORM_INF_32F_C3CMR)
|
||||
type == CV_32FC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_Inf_32f_C3CMR :
|
||||
#endif
|
||||
0) :
|
||||
norm_type == cv::NORM_L1 ?
|
||||
(type == CV_8UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L1_8u_C3CMR :
|
||||
|
||||
@@ -120,4 +120,30 @@ static inline int ippiSuggestRowThreadsNum(const ::ipp::IwiImage &image, size_t
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IPP_VERSION_X100 >= 201700
|
||||
#define CV_IPP_MALLOC(SIZE) ippMalloc_L(SIZE)
|
||||
#else
|
||||
#define CV_IPP_MALLOC(SIZE) ippMalloc((int)SIZE)
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
class IppAutoBuffer
|
||||
{
|
||||
public:
|
||||
IppAutoBuffer() { m_size = 0; m_pBuffer = NULL; }
|
||||
explicit IppAutoBuffer(size_t size) { m_size = 0; m_pBuffer = NULL; allocate(size); }
|
||||
~IppAutoBuffer() { deallocate(); }
|
||||
T* allocate(size_t size) { if(m_size < size) { deallocate(); m_pBuffer = (T*)CV_IPP_MALLOC(size); m_size = size; } return m_pBuffer; }
|
||||
void deallocate() { if(m_pBuffer) { ippFree(m_pBuffer); m_pBuffer = NULL; } m_size = 0; }
|
||||
inline T* get() { return (T*)m_pBuffer;}
|
||||
inline operator T* () { return (T*)m_pBuffer;}
|
||||
inline operator const T* () const { return (const T*)m_pBuffer;}
|
||||
private:
|
||||
IppAutoBuffer(IppAutoBuffer &) {}
|
||||
IppAutoBuffer& operator =(const IppAutoBuffer &) {return *this;}
|
||||
|
||||
size_t m_size;
|
||||
T* m_pBuffer;
|
||||
};
|
||||
|
||||
#endif //__PRECOMP_IPP_HPP__
|
||||
|
||||
66
hal/ipp/src/samplers_ipp.cpp
Normal file
66
hal/ipp/src/samplers_ipp.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
// Copyright (C) 2026, BigVision LLC, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#include "ipp_hal_imgproc.hpp"
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include "precomp_ipp.hpp"
|
||||
|
||||
#if IPP_VERSION_X100 >= 700
|
||||
|
||||
using namespace cv;
|
||||
|
||||
int ipp_hal_getRectSubPix(int src_type, const uchar* src_data, size_t src_step, int src_width, int src_height,
|
||||
int patch_type, uchar* patch_data, size_t patch_step, int patch_width, int patch_height,
|
||||
double center_x, double center_y)
|
||||
{
|
||||
CV_HAL_CHECK_USE_IPP();
|
||||
|
||||
int ddepth = CV_MAT_DEPTH(patch_type);
|
||||
|
||||
// ippiCopySubpixIntersect replicates the border incorrectly in some cases, see
|
||||
// https://github.com/opencv/opencv/issues/30301. The window position is computed the same way as IPP does,
|
||||
// including (int)(x + w) - w, which is not equal to cvFloor() for some inputs.
|
||||
float fx = (float)center_x - 0.5f * (patch_width - 1);
|
||||
float fy = (float)center_y - 0.5f * (patch_height - 1);
|
||||
int sx = (int)(fx + patch_width) - patch_width;
|
||||
int sy = (int)(fy + patch_height) - patch_height;
|
||||
|
||||
// the window crosses the top edge and reaches the last column: the top rows get src(0, cols-2)
|
||||
// instead of src(0, cols-1), and for 1-column images IPP reads outside of the image
|
||||
if( sy < 0 && sx >= src_width - patch_width )
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
// 8u->8u, the window lies totally to the left of the image: the fixed-point weights overflow
|
||||
if( src_type == CV_8UC1 && ddepth == CV_8U && fx + patch_width < 0 )
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
typedef IppStatus (CV_STDCALL *ippiGetRectSubPixFunc)( const void* src, int src_step,
|
||||
IppiSize src_size, void* dst,
|
||||
int dst_step, IppiSize win_size,
|
||||
IppiPoint_32f center,
|
||||
IppiPoint* minpt, IppiPoint* maxpt );
|
||||
|
||||
ippiGetRectSubPixFunc ippiCopySubpixIntersect =
|
||||
src_type == CV_8UC1 && ddepth == CV_8U ? (ippiGetRectSubPixFunc)ippiCopySubpixIntersect_8u_C1R :
|
||||
src_type == CV_8UC1 && ddepth == CV_32F ? (ippiGetRectSubPixFunc)ippiCopySubpixIntersect_8u32f_C1R :
|
||||
src_type == CV_32FC1 && ddepth == CV_32F ? (ippiGetRectSubPixFunc)ippiCopySubpixIntersect_32f_C1R : 0;
|
||||
|
||||
if( ippiCopySubpixIntersect )
|
||||
{
|
||||
IppiPoint minpt = {0, 0}, maxpt = {0, 0};
|
||||
IppiPoint_32f icenter = {(float)center_x, (float)center_y};
|
||||
IppiSize src_size = {src_width, src_height}, win_size = {patch_width, patch_height};
|
||||
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiCopySubpixIntersect, src_data, (int)src_step, src_size, patch_data,
|
||||
(int)patch_step, win_size, icenter, &minpt, &maxpt) >= 0 )
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -99,14 +99,17 @@ int ipp_hal_warpAffine(int src_type, const uchar *src_data, size_t src_step, int
|
||||
{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //32F
|
||||
{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}}; //64F
|
||||
#else // IPP_CALLS_ENFORCED is not defined, results are strictly aligned to OpenCV implementation
|
||||
// NEAREST column kept 0 for all types: IPP's iwiWarpAffine rounds source coords at the
|
||||
// half-pixel boundary unlike the native kernel (warpAffineBlocklineNN), so its NN output
|
||||
// is not bit-exact. Forces fallback to native. See https://github.com/opencv/opencv/issues/29279
|
||||
/* C1 C2 C3 C4 */
|
||||
char impl[CV_DEPTH_MAX][4][3]={{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8U
|
||||
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8S
|
||||
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {1, 0, 0}}, //16U
|
||||
{{1, 0, 0}, {0, 0, 0}, {1, 0, 0}, {1, 0, 0}}, //16S
|
||||
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //16U
|
||||
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //16S
|
||||
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //32S
|
||||
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //32F
|
||||
{{1, 0, 0}, {0, 0, 0}, {1, 0, 0}, {1, 0, 0}}}; //64F
|
||||
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}; //64F
|
||||
#endif
|
||||
|
||||
if(impl[CV_TYPE(src_type)][CV_MAT_CN(src_type)-1][interpolation] == 0)
|
||||
@@ -232,10 +235,10 @@ int ipp_hal_warpPerspective(int src_type, const uchar *src_data, size_t src_step
|
||||
/* C1 C2 C3 C4 */
|
||||
char impl[CV_DEPTH_MAX][4][2]={{{0, 0}, {0, 0}, {0, 0}, {0, 0}}, //8U
|
||||
{{0, 0}, {0, 0}, {0, 0}, {0, 0}}, //8S
|
||||
{{0, 0}, {0, 0}, {0, 0}, {0, 1}}, //16U
|
||||
{{1, 1}, {0, 0}, {1, 0}, {1, 1}}, //16S
|
||||
{{0, 0}, {0, 0}, {0, 1}, {0, 1}}, //16U
|
||||
{{1, 1}, {0, 0}, {1, 1}, {1, 1}}, //16S
|
||||
{{1, 1}, {0, 0}, {1, 0}, {1, 1}}, //32S
|
||||
{{0, 0}, {0, 0}, {0, 0}, {0, 0}}, //32F
|
||||
{{1, 0}, {0, 0}, {0, 0}, {0, 0}}, //32F
|
||||
{{0, 0}, {0, 0}, {0, 0}, {0, 0}}}; //64F
|
||||
#endif
|
||||
|
||||
|
||||
@@ -189,7 +189,7 @@ int bilateralFilter(const uchar* src_data, size_t src_step,
|
||||
|
||||
// calculate source border
|
||||
std::vector<uchar> padding;
|
||||
padding.resize(cal_width * cal_height * cn);
|
||||
padding.resize((size_t)cal_width * cal_height * cn);
|
||||
uchar* pad_data = &padding[0];
|
||||
int pad_step = cal_width * cn;
|
||||
|
||||
|
||||
@@ -99,9 +99,18 @@ int fast_atan_64(const double* y, const double* x, double* dst, size_t n, bool a
|
||||
/* ############ split ############ */
|
||||
|
||||
int split8u(const uchar* src, uchar** dst, int len, int cn);
|
||||
int split16u(const ushort* src, ushort** dst, int len, int cn);
|
||||
int split32s(const int* src, int** dst, int len, int cn);
|
||||
int split64s(const int64* src, int64** dst, int len, int cn);
|
||||
|
||||
#undef cv_hal_split8u
|
||||
#define cv_hal_split8u cv::rvv_hal::core::split8u
|
||||
#undef cv_hal_split16u
|
||||
#define cv_hal_split16u cv::rvv_hal::core::split16u
|
||||
#undef cv_hal_split32s
|
||||
#define cv_hal_split32s cv::rvv_hal::core::split32s
|
||||
#undef cv_hal_split64s
|
||||
#define cv_hal_split64s cv::rvv_hal::core::split64s
|
||||
|
||||
/* ############ sqrt ############ */
|
||||
|
||||
@@ -325,6 +334,14 @@ int transpose2d(const uchar* src_data, size_t src_step, uchar* dst_data, size_t
|
||||
#undef cv_hal_transpose2d
|
||||
#define cv_hal_transpose2d cv::rvv_hal::core::transpose2d
|
||||
|
||||
/* ############ rotate90 ############ */
|
||||
|
||||
int rotate90(int src_type, const uchar* src_data, size_t src_step, int src_width, int src_height,
|
||||
uchar* dst_data, size_t dst_step, int angle);
|
||||
|
||||
#undef cv_hal_rotate90
|
||||
#define cv_hal_rotate90 cv::rvv_hal::core::rotate90
|
||||
|
||||
#endif // CV_HAL_RVV_1P0_ENABLED
|
||||
|
||||
}}} // cv::rvv_hal::core
|
||||
|
||||
@@ -221,6 +221,53 @@ inline int convertScale_16U32F(const uchar* src, size_t src_step, uchar* dst, si
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
inline int convertScale_16S8U(const uchar* src, size_t src_step, uchar* dst, size_t dst_step, int width, int height, double alpha, double beta)
|
||||
{
|
||||
if (alpha == 1.0 && beta == 0.0)
|
||||
{
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
const short* src_row = reinterpret_cast<const short*>(src + i * src_step);
|
||||
uchar* dst_row = dst + i * dst_step;
|
||||
int vl;
|
||||
for (int j = 0; j < width; j += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e16m4(width - j);
|
||||
auto vec_src = __riscv_vle16_v_i16m4(src_row + j, vl);
|
||||
// clamp the negative half to zero first: vnclipu would wrap it to 255
|
||||
auto vec_src_u16 = __riscv_vreinterpret_v_i16m4_u16m4(__riscv_vmax(vec_src, 0, vl));
|
||||
auto vec_dst = __riscv_vnclipu(vec_src_u16, 0, __RISCV_VXRM_RNU, vl);
|
||||
__riscv_vse8_v_u8m2(dst_row + j, vec_dst, vl);
|
||||
}
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
int vlmax = __riscv_vsetvlmax_e32m8();
|
||||
auto vec_b = __riscv_vfmv_v_f_f32m8(beta, vlmax);
|
||||
float a = alpha;
|
||||
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
const short* src_row = reinterpret_cast<const short*>(src + i * src_step);
|
||||
uchar* dst_row = dst + i * dst_step;
|
||||
int vl;
|
||||
for (int j = 0; j < width; j += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e16m4(width - j);
|
||||
auto vec_src = __riscv_vle16_v_i16m4(src_row + j, vl);
|
||||
auto vec_src_f32 = __riscv_vfwcvt_f(vec_src, vl);
|
||||
auto vec_fma = __riscv_vfmadd(vec_src_f32, a, vec_b, vl);
|
||||
auto vec_dst_u16 = __riscv_vfncvt_xu(vec_fma, vl);
|
||||
auto vec_dst = __riscv_vnclipu(vec_dst_u16, 0, __RISCV_VXRM_RNU, vl);
|
||||
__riscv_vse8_v_u8m2(dst_row + j, vec_dst, vl);
|
||||
}
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
inline int convertScale_16S32F(const uchar* src, size_t src_step, uchar* dst, size_t dst_step, int width, int height, double alpha, double beta)
|
||||
{
|
||||
int vlmax = __riscv_vsetvlmax_e32m8();
|
||||
@@ -333,6 +380,8 @@ int convertScale(const uchar* src, size_t src_step, uchar* dst, size_t dst_step,
|
||||
case CV_16S:
|
||||
switch (ddepth)
|
||||
{
|
||||
case CV_8U:
|
||||
return convertScale_16S8U(src, src_step, dst, dst_step, width, height, alpha, beta);
|
||||
case CV_32F:
|
||||
return convertScale_16S32F(src, src_step, dst, dst_step, width, height, alpha, beta);
|
||||
}
|
||||
|
||||
@@ -30,8 +30,27 @@ static int copyToMasked_e##X##c1(const uchar *src_data, size_t src_step, const u
|
||||
return CV_HAL_ERROR_OK; \
|
||||
}
|
||||
|
||||
CV_HAL_RVV_COPY_MASK_eXc1(8, 8)
|
||||
CV_HAL_RVV_COPY_MASK_eXc1(16, 4)
|
||||
#define CV_HAL_RVV_COPY_MASK_MERGE_eXc1(X, data_lmul, mask_lmul) \
|
||||
static int copyToMasked_e##X##c1(const uchar *src_data, size_t src_step, const uchar *mask_data, size_t mask_step, \
|
||||
uchar *dst_data, size_t dst_step, int width, int height) { \
|
||||
for (; height--; mask_data += mask_step, src_data += src_step, dst_data += dst_step) { \
|
||||
const uint##X##_t *src = (const uint##X##_t*)src_data; \
|
||||
uint##X##_t *dst = (uint##X##_t*)dst_data; \
|
||||
int vl; \
|
||||
for (int i = 0; i < width; i += vl) { \
|
||||
vl = __riscv_vsetvl_e##X##m##data_lmul(width - i); \
|
||||
auto m = __riscv_vmsne(__riscv_vle8_v_u8m##mask_lmul(mask_data + i, vl), 0, vl); \
|
||||
auto src_v = __riscv_vle##X##_v_u##X##m##data_lmul(src + i, vl); \
|
||||
auto dst_v = __riscv_vle##X##_v_u##X##m##data_lmul(dst + i, vl); \
|
||||
__riscv_vse##X##_v_u##X##m##data_lmul(dst + i, __riscv_vmerge(dst_v, src_v, m, vl), vl); \
|
||||
} \
|
||||
} \
|
||||
return CV_HAL_ERROR_OK; \
|
||||
}
|
||||
|
||||
CV_HAL_RVV_COPY_MASK_MERGE_eXc1(8, 8, 8)
|
||||
CV_HAL_RVV_COPY_MASK_MERGE_eXc1(16, 8, 4)
|
||||
|
||||
CV_HAL_RVV_COPY_MASK_eXc1(32, 2)
|
||||
CV_HAL_RVV_COPY_MASK_eXc1(64, 1)
|
||||
|
||||
|
||||
@@ -7,16 +7,7 @@
|
||||
|
||||
#include "rvv_hal.hpp"
|
||||
|
||||
#if defined (__clang__) && __clang_major__ < 18
|
||||
#define OPENCV_HAL_IMPL_RVV_VCREATE_x3(suffix, width, v0, v1, v2) \
|
||||
__riscv_vset_v_##suffix##m##width##_##suffix##m##width##x3(v, 0, v0); \
|
||||
v = __riscv_vset(v, 1, v1); \
|
||||
v = __riscv_vset(v, 2, v2);
|
||||
#define __riscv_vcreate_v_u8m2x3(v0, v1, v2) OPENCV_HAL_IMPL_RVV_VCREATE_x3(u8, 2, v0, v1, v2)
|
||||
#define __riscv_vcreate_v_u16m2x3(v0, v1, v2) OPENCV_HAL_IMPL_RVV_VCREATE_x3(u16, 2, v0, v1, v2)
|
||||
#define __riscv_vcreate_v_u32m2x3(v0, v1, v2) OPENCV_HAL_IMPL_RVV_VCREATE_x3(u32, 2, v0, v1, v2)
|
||||
#define __riscv_vcreate_v_u64m2x3(v0, v1, v2) OPENCV_HAL_IMPL_RVV_VCREATE_x3(u64, 2, v0, v1, v2)
|
||||
#endif
|
||||
#include "rvv_vcreate.hpp"
|
||||
|
||||
namespace cv { namespace rvv_hal { namespace core {
|
||||
|
||||
@@ -24,24 +15,50 @@ namespace cv { namespace rvv_hal { namespace core {
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename RVV>
|
||||
struct FlipC1 : RVV
|
||||
{
|
||||
static inline typename RVV::VecType gather(typename RVV::VecType v,
|
||||
typename RVV::VecType indices, size_t vl)
|
||||
{
|
||||
return __riscv_vrgather(v, indices, vl);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct FlipC1<RVV_U8M8> : RVV_U8M4
|
||||
{
|
||||
// e8,m4 data and e16,m8 indices have the same number of lanes.
|
||||
// 8-bit indices wrap when more than 256 bytes are reversed at once.
|
||||
static inline RVV_U16M8::VecType vid(size_t vl)
|
||||
{
|
||||
return RVV_U16M8::vid(vl);
|
||||
}
|
||||
|
||||
static inline VecType gather(VecType v, RVV_U16M8::VecType indices, size_t vl)
|
||||
{
|
||||
return __riscv_vrgatherei16(v, indices, vl);
|
||||
}
|
||||
};
|
||||
|
||||
#define CV_HAL_RVV_FLIP_C1(name, _Tps, RVV) \
|
||||
inline void flip_##name(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int src_width, int src_height, int flip_mode) { \
|
||||
for (int h = 0; h < src_height; h++) { \
|
||||
const _Tps* src_row = (const _Tps*)(src_data + src_step * h); \
|
||||
_Tps* dst_row = (_Tps*)(dst_data + dst_step * (flip_mode < 0 ? (src_height - h) : (h + 1))); \
|
||||
_Tps* dst_row = (_Tps*)(dst_data + dst_step * (flip_mode < 0 ? (src_height - 1 - h) : h)) + src_width; \
|
||||
int vl; \
|
||||
for (int w = 0; w < src_width; w += vl) { \
|
||||
vl = RVV::setvl(src_width - w); \
|
||||
RVV::VecType indices = __riscv_vrsub(RVV::vid(vl), vl - 1, vl); \
|
||||
auto indices = __riscv_vrsub(RVV::vid(vl), vl - 1, vl); \
|
||||
auto v = RVV::vload(src_row + w, vl); \
|
||||
RVV::vstore(dst_row - w - vl, __riscv_vrgather(v, indices, vl), vl); \
|
||||
RVV::vstore(dst_row - w - vl, RVV::gather(v, indices, vl), vl); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
CV_HAL_RVV_FLIP_C1(8UC1, uchar, RVV_U8M8)
|
||||
CV_HAL_RVV_FLIP_C1(16UC1, ushort, RVV_U16M8)
|
||||
CV_HAL_RVV_FLIP_C1(32UC1, unsigned, RVV_U32M8)
|
||||
CV_HAL_RVV_FLIP_C1(64UC1, uint64_t, RVV_U64M8)
|
||||
CV_HAL_RVV_FLIP_C1(8UC1, uchar, FlipC1<RVV_U8M8>)
|
||||
CV_HAL_RVV_FLIP_C1(16UC1, ushort, FlipC1<RVV_U16M8>)
|
||||
CV_HAL_RVV_FLIP_C1(32UC1, unsigned, FlipC1<RVV_U32M8>)
|
||||
CV_HAL_RVV_FLIP_C1(64UC1, uint64_t, FlipC1<RVV_U64M8>)
|
||||
|
||||
#define CV_HAL_RVV_FLIP_INPLACE_C1(name, _Tps, RVV) \
|
||||
inline void flip_inplace_##name(uchar* data, size_t step, int width, int height, int flip_mode) { \
|
||||
@@ -50,36 +67,36 @@ inline void flip_inplace_##name(uchar* data, size_t step, int width, int height,
|
||||
int h; \
|
||||
for (h = 0; h < new_height; h++) { \
|
||||
_Tps* row_begin = (_Tps*)(data + step * h); \
|
||||
_Tps* row_end = (_Tps*)(data + step * (flip_mode < 0 ? (height - h) : (h + 1))); \
|
||||
_Tps* row_end = (_Tps*)(data + step * (flip_mode < 0 ? (height - 1 - h) : h)) + width; \
|
||||
int vl; \
|
||||
for (int w = 0; w < new_width; w += vl) { \
|
||||
vl = RVV::setvl(new_width - w); \
|
||||
RVV::VecType indices = __riscv_vrsub(RVV::vid(vl), vl - 1, vl); \
|
||||
auto indices = __riscv_vrsub(RVV::vid(vl), vl - 1, vl); \
|
||||
auto v_left = RVV::vload(row_begin + w, vl); \
|
||||
auto v_right = RVV::vload(row_end - w - vl, vl); \
|
||||
RVV::vstore(row_begin + w, __riscv_vrgather(v_right, indices, vl), vl); \
|
||||
RVV::vstore(row_end - w - vl, __riscv_vrgather(v_left, indices, vl), vl); \
|
||||
RVV::vstore(row_begin + w, RVV::gather(v_right, indices, vl), vl); \
|
||||
RVV::vstore(row_end - w - vl, RVV::gather(v_left, indices, vl), vl); \
|
||||
} \
|
||||
} \
|
||||
if (flip_mode == -1 && new_height * 2 != height) { \
|
||||
_Tps* row_begin = (_Tps*)(data + step * h); \
|
||||
_Tps* row_end = (_Tps*)(data + step * (h + 1)); \
|
||||
_Tps* row_end = (_Tps*)(data + step * h) + width; \
|
||||
new_width /= 2; \
|
||||
int vl; \
|
||||
for (int w = 0; w < new_width; w += vl) { \
|
||||
vl = RVV::setvl(new_width - w); \
|
||||
RVV::VecType indices = __riscv_vrsub(RVV::vid(vl), vl - 1, vl); \
|
||||
auto indices = __riscv_vrsub(RVV::vid(vl), vl - 1, vl); \
|
||||
auto v_left = RVV::vload(row_begin + w, vl); \
|
||||
auto v_right = RVV::vload(row_end - w - vl, vl); \
|
||||
RVV::vstore(row_begin + w, __riscv_vrgather(v_right, indices, vl), vl); \
|
||||
RVV::vstore(row_end - w - vl, __riscv_vrgather(v_left, indices, vl), vl); \
|
||||
RVV::vstore(row_begin + w, RVV::gather(v_right, indices, vl), vl); \
|
||||
RVV::vstore(row_end - w - vl, RVV::gather(v_left, indices, vl), vl); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
CV_HAL_RVV_FLIP_INPLACE_C1(8UC1, uchar, RVV_U8M8)
|
||||
CV_HAL_RVV_FLIP_INPLACE_C1(16UC1, ushort, RVV_U16M8)
|
||||
CV_HAL_RVV_FLIP_INPLACE_C1(32UC1, unsigned, RVV_U32M8)
|
||||
CV_HAL_RVV_FLIP_INPLACE_C1(64UC1, uint64_t, RVV_U64M8)
|
||||
CV_HAL_RVV_FLIP_INPLACE_C1(8UC1, uchar, FlipC1<RVV_U8M8>)
|
||||
CV_HAL_RVV_FLIP_INPLACE_C1(16UC1, ushort, FlipC1<RVV_U16M8>)
|
||||
CV_HAL_RVV_FLIP_INPLACE_C1(32UC1, unsigned, FlipC1<RVV_U32M8>)
|
||||
CV_HAL_RVV_FLIP_INPLACE_C1(64UC1, uint64_t, FlipC1<RVV_U64M8>)
|
||||
|
||||
// Suppress warnings of "ignoring attributes applied to VecType after definition",
|
||||
// VecType is vuint8m2x3_t, vuint16m2x3_t, vuint32m2x3_t or vuint64m2x3_t
|
||||
@@ -113,7 +130,7 @@ CV_HAL_RVV_FLIP_C3_TYPES(64)
|
||||
inline void flip_##name(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int src_width, int src_height, int flip_mode) { \
|
||||
for (int h = 0; h < src_height; h++) { \
|
||||
const _Tps* src_row = (const _Tps*)(src_data + src_step * h); \
|
||||
_Tps* dst_row = (_Tps*)(dst_data + dst_step * (flip_mode < 0 ? (src_height - h) : (h + 1))); \
|
||||
_Tps* dst_row = (_Tps*)(dst_data + dst_step * (flip_mode < 0 ? (src_height - 1 - h) : h)) + 3 * src_width; \
|
||||
int vl; \
|
||||
for (int w = 0; w < src_width; w += vl) { \
|
||||
vl = RVV::setvl(src_width - w); \
|
||||
@@ -136,7 +153,7 @@ inline void flip_inplace_##name(uchar* data, size_t step, int width, int height,
|
||||
int h; \
|
||||
for (h = 0; h < new_height; h++) { \
|
||||
_Tps* row_begin = (_Tps*)(data + step * h); \
|
||||
_Tps* row_end = (_Tps*)(data + step * (flip_mode < 0 ? (height - h) : (h + 1))); \
|
||||
_Tps* row_end = (_Tps*)(data + step * (flip_mode < 0 ? (height - 1 - h) : h)) + 3 * width; \
|
||||
int vl; \
|
||||
for (int w = 0; w < new_width; w += vl) { \
|
||||
vl = RVV::setvl(new_width - w); \
|
||||
@@ -151,7 +168,7 @@ inline void flip_inplace_##name(uchar* data, size_t step, int width, int height,
|
||||
} \
|
||||
if (flip_mode == -1 && new_height * 2 != height) { \
|
||||
_Tps* row_begin = (_Tps*)(data + step * h); \
|
||||
_Tps* row_end = (_Tps*)(data + step * (h + 1)); \
|
||||
_Tps* row_end = (_Tps*)(data + step * h) + 3 * width; \
|
||||
new_width /= 2; \
|
||||
int vl; \
|
||||
for (int w = 0; w < new_width; w += vl) { \
|
||||
|
||||
@@ -28,6 +28,12 @@
|
||||
#define __riscv_vcreate_v_u16m4x2(v0, v1) OPENCV_HAL_IMPL_RVV_VCREATE_x2(u16, 4, v0, v1)
|
||||
#define __riscv_vcreate_v_u16m2x3(v0, v1, v2) OPENCV_HAL_IMPL_RVV_VCREATE_x3(u16, 2, v0, v1, v2)
|
||||
#define __riscv_vcreate_v_u16m2x4(v0, v1, v2, v3) OPENCV_HAL_IMPL_RVV_VCREATE_x4(u16, 2, v0, v1, v2, v3)
|
||||
#define __riscv_vcreate_v_i32m4x2(v0, v1) OPENCV_HAL_IMPL_RVV_VCREATE_x2(i32, 4, v0, v1)
|
||||
#define __riscv_vcreate_v_i32m2x3(v0, v1, v2) OPENCV_HAL_IMPL_RVV_VCREATE_x3(i32, 2, v0, v1, v2)
|
||||
#define __riscv_vcreate_v_i32m2x4(v0, v1, v2, v3) OPENCV_HAL_IMPL_RVV_VCREATE_x4(i32, 2, v0, v1, v2, v3)
|
||||
#define __riscv_vcreate_v_i64m4x2(v0, v1) OPENCV_HAL_IMPL_RVV_VCREATE_x2(i64, 4, v0, v1)
|
||||
#define __riscv_vcreate_v_i64m2x3(v0, v1, v2) OPENCV_HAL_IMPL_RVV_VCREATE_x3(i64, 2, v0, v1, v2)
|
||||
#define __riscv_vcreate_v_i64m2x4(v0, v1, v2, v3) OPENCV_HAL_IMPL_RVV_VCREATE_x4(i64, 2, v0, v1, v2, v3)
|
||||
#endif // clang < 18
|
||||
|
||||
namespace cv { namespace rvv_hal { namespace core {
|
||||
@@ -204,146 +210,177 @@ int merge16u(const ushort** src, ushort* dst, int len, int cn ) {
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
#if defined __GNUC__ && !defined(__clang__)
|
||||
__attribute__((optimize("no-tree-vectorize")))
|
||||
#endif
|
||||
int merge32s(const int** src, int* dst, int len, int cn ) {
|
||||
int k = cn % 4 ? cn % 4 : 4;
|
||||
int i, j;
|
||||
if( k == 1 )
|
||||
int vl = 0;
|
||||
if (cn == 1)
|
||||
{
|
||||
const int* src0 = src[0];
|
||||
#if defined(__clang__)
|
||||
#pragma clang loop vectorize(disable)
|
||||
#endif
|
||||
for( i = j = 0; i < len; i++, j += cn )
|
||||
dst[j] = src0[i];
|
||||
}
|
||||
else if( k == 2 )
|
||||
{
|
||||
const int *src0 = src[0], *src1 = src[1];
|
||||
i = j = 0;
|
||||
#if defined(__clang__)
|
||||
#pragma clang loop vectorize(disable)
|
||||
#endif
|
||||
for( ; i < len; i++, j += cn )
|
||||
for (int i = 0; i < len; i += vl)
|
||||
{
|
||||
dst[j] = src0[i];
|
||||
dst[j+1] = src1[i];
|
||||
vl = __riscv_vsetvl_e32m8(len - i);
|
||||
__riscv_vse32_v_i32m8(dst + i, __riscv_vle32_v_i32m8(src0 + i, vl), vl);
|
||||
}
|
||||
}
|
||||
else if( k == 3 )
|
||||
else if (cn == 2)
|
||||
{
|
||||
const int *src0 = src[0], *src1 = src[1];
|
||||
for (int i = 0; i < len; i += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e32m4(len - i);
|
||||
vint32m4x2_t seg = __riscv_vcreate_v_i32m4x2(
|
||||
__riscv_vle32_v_i32m4(src0 + i, vl),
|
||||
__riscv_vle32_v_i32m4(src1 + i, vl)
|
||||
);
|
||||
__riscv_vsseg2e32_v_i32m4x2(dst + i * cn, seg, vl);
|
||||
}
|
||||
}
|
||||
else if (cn == 3)
|
||||
{
|
||||
const int *src0 = src[0], *src1 = src[1], *src2 = src[2];
|
||||
i = j = 0;
|
||||
#if defined(__clang__)
|
||||
#pragma clang loop vectorize(disable)
|
||||
#endif
|
||||
for( ; i < len; i++, j += cn )
|
||||
for (int i = 0; i < len; i += vl)
|
||||
{
|
||||
dst[j] = src0[i];
|
||||
dst[j+1] = src1[i];
|
||||
dst[j+2] = src2[i];
|
||||
vl = __riscv_vsetvl_e32m2(len - i);
|
||||
vint32m2x3_t seg = __riscv_vcreate_v_i32m2x3(
|
||||
__riscv_vle32_v_i32m2(src0 + i, vl),
|
||||
__riscv_vle32_v_i32m2(src1 + i, vl),
|
||||
__riscv_vle32_v_i32m2(src2 + i, vl)
|
||||
);
|
||||
__riscv_vsseg3e32_v_i32m2x3(dst + i * cn, seg, vl);
|
||||
}
|
||||
}
|
||||
else if (cn == 4)
|
||||
{
|
||||
const int *src0 = src[0], *src1 = src[1], *src2 = src[2], *src3 = src[3];
|
||||
for (int i = 0; i < len; i += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e32m2(len - i);
|
||||
vint32m2x4_t seg = __riscv_vcreate_v_i32m2x4(
|
||||
__riscv_vle32_v_i32m2(src0 + i, vl),
|
||||
__riscv_vle32_v_i32m2(src1 + i, vl),
|
||||
__riscv_vle32_v_i32m2(src2 + i, vl),
|
||||
__riscv_vle32_v_i32m2(src3 + i, vl)
|
||||
);
|
||||
__riscv_vsseg4e32_v_i32m2x4(dst + i * cn, seg, vl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const int *src0 = src[0], *src1 = src[1], *src2 = src[2], *src3 = src[3];
|
||||
i = j = 0;
|
||||
#if defined(__clang__)
|
||||
#pragma clang loop vectorize(disable)
|
||||
#endif
|
||||
for( ; i < len; i++, j += cn )
|
||||
int k = 0;
|
||||
for (; k <= cn - 4; k += 4)
|
||||
{
|
||||
dst[j] = src0[i]; dst[j+1] = src1[i];
|
||||
dst[j+2] = src2[i]; dst[j+3] = src3[i];
|
||||
const int *src0 = src[k], *src1 = src[k + 1], *src2 = src[k + 2], *src3 = src[k + 3];
|
||||
for (int i = 0; i < len; i += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e32m2(len - i);
|
||||
vint32m2x4_t seg = __riscv_vcreate_v_i32m2x4(
|
||||
__riscv_vle32_v_i32m2(src0 + i, vl),
|
||||
__riscv_vle32_v_i32m2(src1 + i, vl),
|
||||
__riscv_vle32_v_i32m2(src2 + i, vl),
|
||||
__riscv_vle32_v_i32m2(src3 + i, vl)
|
||||
);
|
||||
__riscv_vssseg4e32_v_i32m2x4(dst + k + i * cn, cn * sizeof(int), seg, vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined(__clang__)
|
||||
#pragma clang loop vectorize(disable)
|
||||
#endif
|
||||
for( ; k < cn; k += 4 )
|
||||
{
|
||||
const int *src0 = src[k], *src1 = src[k+1], *src2 = src[k+2], *src3 = src[k+3];
|
||||
for( i = 0, j = k; i < len; i++, j += cn )
|
||||
for (; k < cn; ++k)
|
||||
{
|
||||
dst[j] = src0[i]; dst[j+1] = src1[i];
|
||||
dst[j+2] = src2[i]; dst[j+3] = src3[i];
|
||||
const int* srcK = src[k];
|
||||
for (int i = 0; i < len; i += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e32m2(len - i);
|
||||
vint32m2_t seg = __riscv_vle32_v_i32m2(srcK + i, vl);
|
||||
__riscv_vsse32_v_i32m2(dst + k + i * cn, cn * sizeof(int), seg, vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
#if defined __GNUC__ && !defined(__clang__)
|
||||
__attribute__((optimize("no-tree-vectorize")))
|
||||
#endif
|
||||
int merge64s(const int64** src, int64* dst, int len, int cn ) {
|
||||
int k = cn % 4 ? cn % 4 : 4;
|
||||
int i, j;
|
||||
if( k == 1 )
|
||||
int vl = 0;
|
||||
if (cn == 1)
|
||||
{
|
||||
const int64* src0 = src[0];
|
||||
#if defined(__clang__)
|
||||
#pragma clang loop vectorize(disable)
|
||||
#endif
|
||||
for( i = j = 0; i < len; i++, j += cn )
|
||||
dst[j] = src0[i];
|
||||
}
|
||||
else if( k == 2 )
|
||||
{
|
||||
const int64 *src0 = src[0], *src1 = src[1];
|
||||
i = j = 0;
|
||||
#if defined(__clang__)
|
||||
#pragma clang loop vectorize(disable)
|
||||
#endif
|
||||
for( ; i < len; i++, j += cn )
|
||||
for (int i = 0; i < len; i += vl)
|
||||
{
|
||||
dst[j] = src0[i];
|
||||
dst[j+1] = src1[i];
|
||||
vl = __riscv_vsetvl_e64m8(len - i);
|
||||
__riscv_vse64_v_i64m8(dst + i, __riscv_vle64_v_i64m8(src0 + i, vl), vl);
|
||||
}
|
||||
}
|
||||
else if( k == 3 )
|
||||
else if (cn == 2)
|
||||
{
|
||||
const int64 *src0 = src[0], *src1 = src[1];
|
||||
for (int i = 0; i < len; i += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e64m4(len - i);
|
||||
vint64m4x2_t seg = __riscv_vcreate_v_i64m4x2(
|
||||
__riscv_vle64_v_i64m4(src0 + i, vl),
|
||||
__riscv_vle64_v_i64m4(src1 + i, vl)
|
||||
);
|
||||
__riscv_vsseg2e64_v_i64m4x2(dst + i * cn, seg, vl);
|
||||
}
|
||||
}
|
||||
else if (cn == 3)
|
||||
{
|
||||
const int64 *src0 = src[0], *src1 = src[1], *src2 = src[2];
|
||||
i = j = 0;
|
||||
#if defined(__clang__)
|
||||
#pragma clang loop vectorize(disable)
|
||||
#endif
|
||||
for( ; i < len; i++, j += cn )
|
||||
for (int i = 0; i < len; i += vl)
|
||||
{
|
||||
dst[j] = src0[i];
|
||||
dst[j+1] = src1[i];
|
||||
dst[j+2] = src2[i];
|
||||
vl = __riscv_vsetvl_e64m2(len - i);
|
||||
vint64m2x3_t seg = __riscv_vcreate_v_i64m2x3(
|
||||
__riscv_vle64_v_i64m2(src0 + i, vl),
|
||||
__riscv_vle64_v_i64m2(src1 + i, vl),
|
||||
__riscv_vle64_v_i64m2(src2 + i, vl)
|
||||
);
|
||||
__riscv_vsseg3e64_v_i64m2x3(dst + i * cn, seg, vl);
|
||||
}
|
||||
}
|
||||
else if (cn == 4)
|
||||
{
|
||||
const int64 *src0 = src[0], *src1 = src[1], *src2 = src[2], *src3 = src[3];
|
||||
for (int i = 0; i < len; i += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e64m2(len - i);
|
||||
vint64m2x4_t seg = __riscv_vcreate_v_i64m2x4(
|
||||
__riscv_vle64_v_i64m2(src0 + i, vl),
|
||||
__riscv_vle64_v_i64m2(src1 + i, vl),
|
||||
__riscv_vle64_v_i64m2(src2 + i, vl),
|
||||
__riscv_vle64_v_i64m2(src3 + i, vl)
|
||||
);
|
||||
__riscv_vsseg4e64_v_i64m2x4(dst + i * cn, seg, vl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const int64 *src0 = src[0], *src1 = src[1], *src2 = src[2], *src3 = src[3];
|
||||
i = j = 0;
|
||||
#if defined(__clang__)
|
||||
#pragma clang loop vectorize(disable)
|
||||
#endif
|
||||
for( ; i < len; i++, j += cn )
|
||||
int k = 0;
|
||||
for (; k <= cn - 4; k += 4)
|
||||
{
|
||||
dst[j] = src0[i]; dst[j+1] = src1[i];
|
||||
dst[j+2] = src2[i]; dst[j+3] = src3[i];
|
||||
const int64 *src0 = src[k], *src1 = src[k + 1], *src2 = src[k + 2], *src3 = src[k + 3];
|
||||
for (int i = 0; i < len; i += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e64m2(len - i);
|
||||
vint64m2x4_t seg = __riscv_vcreate_v_i64m2x4(
|
||||
__riscv_vle64_v_i64m2(src0 + i, vl),
|
||||
__riscv_vle64_v_i64m2(src1 + i, vl),
|
||||
__riscv_vle64_v_i64m2(src2 + i, vl),
|
||||
__riscv_vle64_v_i64m2(src3 + i, vl)
|
||||
);
|
||||
__riscv_vssseg4e64_v_i64m2x4(dst + k + i * cn, cn * sizeof(int64), seg, vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined(__clang__)
|
||||
#pragma clang loop vectorize(disable)
|
||||
#endif
|
||||
for( ; k < cn; k += 4 )
|
||||
{
|
||||
const int64 *src0 = src[k], *src1 = src[k+1], *src2 = src[k+2], *src3 = src[k+3];
|
||||
for( i = 0, j = k; i < len; i++, j += cn )
|
||||
for (; k < cn; ++k)
|
||||
{
|
||||
dst[j] = src0[i]; dst[j+1] = src1[i];
|
||||
dst[j+2] = src2[i]; dst[j+3] = src3[i];
|
||||
const int64* srcK = src[k];
|
||||
for (int i = 0; i < len; i += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e64m2(len - i);
|
||||
vint64m2_t seg = __riscv_vle64_v_i64m2(srcK + i, vl);
|
||||
__riscv_vsse64_v_i64m2(dst + k + i * cn, cn * sizeof(int64), seg, vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
#endif // CV_HAL_RVV_1P0_ENABLED
|
||||
|
||||
}}} // cv::rvv_hal::core
|
||||
|
||||
115
hal/riscv-rvv/src/core/rotate.cpp
Normal file
115
hal/riscv-rvv/src/core/rotate.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "rvv_hal.hpp"
|
||||
#include "rvv_vcreate.hpp"
|
||||
|
||||
namespace cv { namespace rvv_hal { namespace core {
|
||||
|
||||
#if CV_HAL_RVV_1P0_ENABLED
|
||||
|
||||
namespace {
|
||||
|
||||
#define CV_HAL_RVV_ROTATE_8_ROWS(func, T, RVV, suffix, bits) \
|
||||
static void func(const uchar* src_data, size_t src_step, int src_width, int src_height, \
|
||||
uchar* dst_data, size_t dst_step, int angle) \
|
||||
{ \
|
||||
const size_t src_step_elems = src_step / sizeof(T); \
|
||||
int y = 0; \
|
||||
for (; y <= src_height - 8; y += 8) \
|
||||
{ \
|
||||
const T* src = reinterpret_cast<const T*>(src_data) + y * src_step_elems; \
|
||||
for (int x = 0; x < src_width; ) \
|
||||
{ \
|
||||
const size_t vl = __riscv_vsetvl_e##bits##m1(src_width - x); \
|
||||
auto v0 = __riscv_vle##bits##_v_##suffix##m1(src + x, vl); \
|
||||
auto v1 = __riscv_vle##bits##_v_##suffix##m1(src + src_step_elems + x, vl); \
|
||||
auto v2 = __riscv_vle##bits##_v_##suffix##m1(src + 2 * src_step_elems + x, vl); \
|
||||
auto v3 = __riscv_vle##bits##_v_##suffix##m1(src + 3 * src_step_elems + x, vl); \
|
||||
auto v4 = __riscv_vle##bits##_v_##suffix##m1(src + 4 * src_step_elems + x, vl); \
|
||||
auto v5 = __riscv_vle##bits##_v_##suffix##m1(src + 5 * src_step_elems + x, vl); \
|
||||
auto v6 = __riscv_vle##bits##_v_##suffix##m1(src + 6 * src_step_elems + x, vl); \
|
||||
auto v7 = __riscv_vle##bits##_v_##suffix##m1(src + 7 * src_step_elems + x, vl); \
|
||||
vuint##bits##m1x8_t v; \
|
||||
T* dst; \
|
||||
ptrdiff_t stride; \
|
||||
if (angle == 90) \
|
||||
{ \
|
||||
v = __riscv_vcreate_v_##suffix##m1x8(v7, v6, v5, v4, v3, v2, v1, v0); \
|
||||
dst = reinterpret_cast<T*>(dst_data + static_cast<size_t>(x) * dst_step) \
|
||||
+ src_height - y - 8; \
|
||||
stride = static_cast<ptrdiff_t>(dst_step); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
v = __riscv_vcreate_v_##suffix##m1x8(v0, v1, v2, v3, v4, v5, v6, v7); \
|
||||
dst = reinterpret_cast<T*>(dst_data + static_cast<size_t>(src_width - 1 - x) * dst_step) + y; \
|
||||
stride = -static_cast<ptrdiff_t>(dst_step); \
|
||||
} \
|
||||
__riscv_vssseg8e##bits(dst, stride, v, vl); \
|
||||
x += static_cast<int>(vl); \
|
||||
} \
|
||||
} \
|
||||
for (; y < src_height; ++y) \
|
||||
{ \
|
||||
const T* src = reinterpret_cast<const T*>(src_data + static_cast<size_t>(y) * src_step); \
|
||||
for (int x = 0; x < src_width; ) \
|
||||
{ \
|
||||
const size_t vl = RVV::setvl(src_width - x); \
|
||||
auto v = RVV::vload(src + x, vl); \
|
||||
T* dst; \
|
||||
ptrdiff_t stride; \
|
||||
if (angle == 90) \
|
||||
{ \
|
||||
dst = reinterpret_cast<T*>(dst_data + static_cast<size_t>(x) * dst_step) \
|
||||
+ src_height - 1 - y; \
|
||||
stride = static_cast<ptrdiff_t>(dst_step); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
dst = reinterpret_cast<T*>(dst_data + static_cast<size_t>(src_width - 1 - x) * dst_step) + y; \
|
||||
stride = -static_cast<ptrdiff_t>(dst_step); \
|
||||
} \
|
||||
RVV::vstore_stride(dst, stride, v, vl); \
|
||||
x += static_cast<int>(vl); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
CV_HAL_RVV_ROTATE_8_ROWS(rotate90_8u, uint8_t, RVV_U8M8, u8, 8)
|
||||
CV_HAL_RVV_ROTATE_8_ROWS(rotate90_16u, uint16_t, RVV_U16M8, u16, 16)
|
||||
CV_HAL_RVV_ROTATE_8_ROWS(rotate90_32u, uint32_t, RVV_U32M8, u32, 32)
|
||||
CV_HAL_RVV_ROTATE_8_ROWS(rotate90_64u, uint64_t, RVV_U64M8, u64, 64)
|
||||
|
||||
#undef CV_HAL_RVV_ROTATE_8_ROWS
|
||||
|
||||
} // namespace
|
||||
|
||||
int rotate90(int src_type, const uchar* src_data, size_t src_step, int src_width, int src_height,
|
||||
uchar* dst_data, size_t dst_step, int angle)
|
||||
{
|
||||
if (src_data == dst_data || (angle != 90 && angle != 270))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
const size_t element_size = CV_ELEM_SIZE(src_type);
|
||||
if (src_step % element_size != 0 || dst_step % element_size != 0)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
using RotateFunc = void (*)(const uchar*, size_t, int, int, uchar*, size_t, int);
|
||||
static RotateFunc rotate90Funcs[] = {
|
||||
nullptr, rotate90_8u, rotate90_16u, nullptr, rotate90_32u,
|
||||
nullptr, nullptr, nullptr, rotate90_64u
|
||||
};
|
||||
RotateFunc func = element_size < sizeof(rotate90Funcs) / sizeof(rotate90Funcs[0])
|
||||
? rotate90Funcs[element_size] : nullptr;
|
||||
if (!func)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
func(src_data, src_step, src_width, src_height, dst_data, dst_step, angle);
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
#endif // CV_HAL_RVV_1P0_ENABLED
|
||||
|
||||
}}} // cv::rvv_hal::core
|
||||
48
hal/riscv-rvv/src/core/rvv_vcreate.hpp
Normal file
48
hal/riscv-rvv/src/core/rvv_vcreate.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2025, Institute of Software, Chinese Academy of Sciences.
|
||||
// Copyright (C) 2025, SpaceMIT Inc., all rights reserved.
|
||||
|
||||
#ifndef OPENCV_HAL_RVV_VCREATE_HPP_INCLUDED
|
||||
#define OPENCV_HAL_RVV_VCREATE_HPP_INCLUDED
|
||||
|
||||
// Tuple creation intrinsics were added in Clang 18.
|
||||
// These shims are shared by flip, transpose and rotate.
|
||||
#if defined(__clang__) && __clang_major__ < 18
|
||||
#define OPENCV_HAL_IMPL_RVV_VCREATE_x3(suffix, width, v0, v1, v2) \
|
||||
__riscv_vset_v_##suffix##m##width##_##suffix##m##width##x3(v, 0, v0); \
|
||||
v = __riscv_vset(v, 1, v1); \
|
||||
v = __riscv_vset(v, 2, v2);
|
||||
#define __riscv_vcreate_v_u8m2x3(v0, v1, v2) OPENCV_HAL_IMPL_RVV_VCREATE_x3(u8, 2, v0, v1, v2)
|
||||
#define __riscv_vcreate_v_u16m2x3(v0, v1, v2) OPENCV_HAL_IMPL_RVV_VCREATE_x3(u16, 2, v0, v1, v2)
|
||||
#define __riscv_vcreate_v_u32m2x3(v0, v1, v2) OPENCV_HAL_IMPL_RVV_VCREATE_x3(u32, 2, v0, v1, v2)
|
||||
#define __riscv_vcreate_v_u64m2x3(v0, v1, v2) OPENCV_HAL_IMPL_RVV_VCREATE_x3(u64, 2, v0, v1, v2)
|
||||
|
||||
#define OPENCV_HAL_IMPL_RVV_VCREATE_x4(suffix, width, v0, v1, v2, v3) \
|
||||
__riscv_vset_v_##suffix##m##width##_##suffix##m##width##x4(v, 0, v0); \
|
||||
v = __riscv_vset(v, 1, v1); \
|
||||
v = __riscv_vset(v, 2, v2); \
|
||||
v = __riscv_vset(v, 3, v3);
|
||||
|
||||
#define OPENCV_HAL_IMPL_RVV_VCREATE_x8(suffix, width, v0, v1, v2, v3, v4, v5, v6, v7) \
|
||||
__riscv_vset_v_##suffix##m##width##_##suffix##m##width##x8(v, 0, v0); \
|
||||
v = __riscv_vset(v, 1, v1); \
|
||||
v = __riscv_vset(v, 2, v2); \
|
||||
v = __riscv_vset(v, 3, v3); \
|
||||
v = __riscv_vset(v, 4, v4); \
|
||||
v = __riscv_vset(v, 5, v5); \
|
||||
v = __riscv_vset(v, 6, v6); \
|
||||
v = __riscv_vset(v, 7, v7);
|
||||
|
||||
#define __riscv_vcreate_v_u8m1x8(v0, v1, v2, v3, v4, v5, v6, v7) OPENCV_HAL_IMPL_RVV_VCREATE_x8(u8, 1, v0, v1, v2, v3, v4, v5, v6, v7)
|
||||
#define __riscv_vcreate_v_u16m1x8(v0, v1, v2, v3, v4, v5, v6, v7) OPENCV_HAL_IMPL_RVV_VCREATE_x8(u16, 1, v0, v1, v2, v3, v4, v5, v6, v7)
|
||||
#define __riscv_vcreate_v_i32m1x4(v0, v1, v2, v3) OPENCV_HAL_IMPL_RVV_VCREATE_x4(i32, 1, v0, v1, v2, v3)
|
||||
#define __riscv_vcreate_v_i64m1x8(v0, v1, v2, v3, v4, v5, v6, v7) OPENCV_HAL_IMPL_RVV_VCREATE_x8(i64, 1, v0, v1, v2, v3, v4, v5, v6, v7)
|
||||
|
||||
#define __riscv_vcreate_v_u32m1x8(v0, v1, v2, v3, v4, v5, v6, v7) OPENCV_HAL_IMPL_RVV_VCREATE_x8(u32, 1, v0, v1, v2, v3, v4, v5, v6, v7)
|
||||
#define __riscv_vcreate_v_u64m1x8(v0, v1, v2, v3, v4, v5, v6, v7) OPENCV_HAL_IMPL_RVV_VCREATE_x8(u64, 1, v0, v1, v2, v3, v4, v5, v6, v7)
|
||||
#endif
|
||||
|
||||
#endif // OPENCV_HAL_RVV_VCREATE_HPP_INCLUDED
|
||||
@@ -8,84 +8,92 @@ namespace cv { namespace rvv_hal { namespace core {
|
||||
|
||||
#if CV_HAL_RVV_1P0_ENABLED
|
||||
|
||||
int split8u(const uchar* src, uchar** dst, int len, int cn)
|
||||
{
|
||||
int vl = 0;
|
||||
if (cn == 1)
|
||||
{
|
||||
uchar* dst0 = dst[0];
|
||||
for (int i = 0; i < len; i += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e8m8(len - i);
|
||||
__riscv_vse8_v_u8m8(dst0 + i, __riscv_vle8_v_u8m8(src + i, vl), vl);
|
||||
}
|
||||
}
|
||||
else if (cn == 2)
|
||||
{
|
||||
uchar *dst0 = dst[0], *dst1 = dst[1];
|
||||
for (int i = 0; i < len; i += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e8m4(len - i);
|
||||
vuint8m4x2_t seg = __riscv_vlseg2e8_v_u8m4x2(src + i * cn, vl);
|
||||
__riscv_vse8_v_u8m4(dst0 + i, __riscv_vget_v_u8m4x2_u8m4(seg, 0), vl);
|
||||
__riscv_vse8_v_u8m4(dst1 + i, __riscv_vget_v_u8m4x2_u8m4(seg, 1), vl);
|
||||
}
|
||||
}
|
||||
else if (cn == 3)
|
||||
{
|
||||
uchar *dst0 = dst[0], *dst1 = dst[1], *dst2 = dst[2];
|
||||
for (int i = 0; i < len; i += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e8m2(len - i);
|
||||
vuint8m2x3_t seg = __riscv_vlseg3e8_v_u8m2x3(src + i * cn, vl);
|
||||
__riscv_vse8_v_u8m2(dst0 + i, __riscv_vget_v_u8m2x3_u8m2(seg, 0), vl);
|
||||
__riscv_vse8_v_u8m2(dst1 + i, __riscv_vget_v_u8m2x3_u8m2(seg, 1), vl);
|
||||
__riscv_vse8_v_u8m2(dst2 + i, __riscv_vget_v_u8m2x3_u8m2(seg, 2), vl);
|
||||
}
|
||||
}
|
||||
else if (cn == 4)
|
||||
{
|
||||
uchar *dst0 = dst[0], *dst1 = dst[1], *dst2 = dst[2], *dst3 = dst[3];
|
||||
for (int i = 0; i < len; i += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e8m2(len - i);
|
||||
vuint8m2x4_t seg = __riscv_vlseg4e8_v_u8m2x4(src + i * cn, vl);
|
||||
__riscv_vse8_v_u8m2(dst0 + i, __riscv_vget_v_u8m2x4_u8m2(seg, 0), vl);
|
||||
__riscv_vse8_v_u8m2(dst1 + i, __riscv_vget_v_u8m2x4_u8m2(seg, 1), vl);
|
||||
__riscv_vse8_v_u8m2(dst2 + i, __riscv_vget_v_u8m2x4_u8m2(seg, 2), vl);
|
||||
__riscv_vse8_v_u8m2(dst3 + i, __riscv_vget_v_u8m2x4_u8m2(seg, 3), vl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int k = 0;
|
||||
for (; k <= cn - 4; k += 4)
|
||||
{
|
||||
uchar *dst0 = dst[k], *dst1 = dst[k + 1], *dst2 = dst[k + 2], *dst3 = dst[k + 3];
|
||||
for (int i = 0; i < len; i += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e8m2(len - i);
|
||||
vuint8m2x4_t seg = __riscv_vlsseg4e8_v_u8m2x4(src + k + i * cn, cn, vl);
|
||||
__riscv_vse8_v_u8m2(dst0 + i, __riscv_vget_v_u8m2x4_u8m2(seg, 0), vl);
|
||||
__riscv_vse8_v_u8m2(dst1 + i, __riscv_vget_v_u8m2x4_u8m2(seg, 1), vl);
|
||||
__riscv_vse8_v_u8m2(dst2 + i, __riscv_vget_v_u8m2x4_u8m2(seg, 2), vl);
|
||||
__riscv_vse8_v_u8m2(dst3 + i, __riscv_vget_v_u8m2x4_u8m2(seg, 3), vl);
|
||||
}
|
||||
}
|
||||
for (; k < cn; ++k)
|
||||
{
|
||||
uchar* dstK = dst[k];
|
||||
for (int i = 0; i < len; i += vl)
|
||||
{
|
||||
vl = __riscv_vsetvl_e8m2(len - i);
|
||||
vuint8m2_t seg = __riscv_vlse8_v_u8m2(src + k + i * cn, cn, vl);
|
||||
__riscv_vse8_v_u8m2(dstK + i, seg, vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
return CV_HAL_ERROR_OK;
|
||||
#define OPENCV_HAL_IMPL_RVV_SPLIT(func, T, vtype, suffix, width) \
|
||||
int func(const T* src, T** dst, int len, int cn) \
|
||||
{ \
|
||||
int vl = 0; \
|
||||
if (cn == 1) \
|
||||
{ \
|
||||
T* dst0 = dst[0]; \
|
||||
for (int i = 0; i < len; i += vl) \
|
||||
{ \
|
||||
vl = __riscv_vsetvl_e##width##m8(len - i); \
|
||||
__riscv_vse##width##_v_##suffix##m8(dst0 + i, __riscv_vle##width##_v_##suffix##m8(src + i, vl), vl); \
|
||||
} \
|
||||
} \
|
||||
else if (cn == 2) \
|
||||
{ \
|
||||
T *dst0 = dst[0], *dst1 = dst[1]; \
|
||||
for (int i = 0; i < len; i += vl) \
|
||||
{ \
|
||||
vl = __riscv_vsetvl_e##width##m4(len - i); \
|
||||
v##vtype##m4x2_t seg = __riscv_vlseg2e##width##_v_##suffix##m4x2(src + i * cn, vl); \
|
||||
__riscv_vse##width##_v_##suffix##m4(dst0 + i, __riscv_vget_v_##suffix##m4x2_##suffix##m4(seg, 0), vl); \
|
||||
__riscv_vse##width##_v_##suffix##m4(dst1 + i, __riscv_vget_v_##suffix##m4x2_##suffix##m4(seg, 1), vl); \
|
||||
} \
|
||||
} \
|
||||
else if (cn == 3) \
|
||||
{ \
|
||||
T *dst0 = dst[0], *dst1 = dst[1], *dst2 = dst[2]; \
|
||||
for (int i = 0; i < len; i += vl) \
|
||||
{ \
|
||||
vl = __riscv_vsetvl_e##width##m2(len - i); \
|
||||
v##vtype##m2x3_t seg = __riscv_vlseg3e##width##_v_##suffix##m2x3(src + i * cn, vl); \
|
||||
__riscv_vse##width##_v_##suffix##m2(dst0 + i, __riscv_vget_v_##suffix##m2x3_##suffix##m2(seg, 0), vl); \
|
||||
__riscv_vse##width##_v_##suffix##m2(dst1 + i, __riscv_vget_v_##suffix##m2x3_##suffix##m2(seg, 1), vl); \
|
||||
__riscv_vse##width##_v_##suffix##m2(dst2 + i, __riscv_vget_v_##suffix##m2x3_##suffix##m2(seg, 2), vl); \
|
||||
} \
|
||||
} \
|
||||
else if (cn == 4) \
|
||||
{ \
|
||||
T *dst0 = dst[0], *dst1 = dst[1], *dst2 = dst[2], *dst3 = dst[3]; \
|
||||
for (int i = 0; i < len; i += vl) \
|
||||
{ \
|
||||
vl = __riscv_vsetvl_e##width##m2(len - i); \
|
||||
v##vtype##m2x4_t seg = __riscv_vlseg4e##width##_v_##suffix##m2x4(src + i * cn, vl); \
|
||||
__riscv_vse##width##_v_##suffix##m2(dst0 + i, __riscv_vget_v_##suffix##m2x4_##suffix##m2(seg, 0), vl); \
|
||||
__riscv_vse##width##_v_##suffix##m2(dst1 + i, __riscv_vget_v_##suffix##m2x4_##suffix##m2(seg, 1), vl); \
|
||||
__riscv_vse##width##_v_##suffix##m2(dst2 + i, __riscv_vget_v_##suffix##m2x4_##suffix##m2(seg, 2), vl); \
|
||||
__riscv_vse##width##_v_##suffix##m2(dst3 + i, __riscv_vget_v_##suffix##m2x4_##suffix##m2(seg, 3), vl); \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
int k = 0; \
|
||||
for (; k <= cn - 4; k += 4) \
|
||||
{ \
|
||||
T *dst0 = dst[k], *dst1 = dst[k + 1], *dst2 = dst[k + 2], *dst3 = dst[k + 3]; \
|
||||
for (int i = 0; i < len; i += vl) \
|
||||
{ \
|
||||
vl = __riscv_vsetvl_e##width##m2(len - i); \
|
||||
v##vtype##m2x4_t seg = __riscv_vlsseg4e##width##_v_##suffix##m2x4(src + k + i * cn, cn * sizeof(T), vl); \
|
||||
__riscv_vse##width##_v_##suffix##m2(dst0 + i, __riscv_vget_v_##suffix##m2x4_##suffix##m2(seg, 0), vl); \
|
||||
__riscv_vse##width##_v_##suffix##m2(dst1 + i, __riscv_vget_v_##suffix##m2x4_##suffix##m2(seg, 1), vl); \
|
||||
__riscv_vse##width##_v_##suffix##m2(dst2 + i, __riscv_vget_v_##suffix##m2x4_##suffix##m2(seg, 2), vl); \
|
||||
__riscv_vse##width##_v_##suffix##m2(dst3 + i, __riscv_vget_v_##suffix##m2x4_##suffix##m2(seg, 3), vl); \
|
||||
} \
|
||||
} \
|
||||
for (; k < cn; ++k) \
|
||||
{ \
|
||||
T* dstK = dst[k]; \
|
||||
for (int i = 0; i < len; i += vl) \
|
||||
{ \
|
||||
vl = __riscv_vsetvl_e##width##m2(len - i); \
|
||||
v##vtype##m2_t seg = __riscv_vlse##width##_v_##suffix##m2(src + k + i * cn, cn * sizeof(T), vl); \
|
||||
__riscv_vse##width##_v_##suffix##m2(dstK + i, seg, vl); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
return CV_HAL_ERROR_OK; \
|
||||
}
|
||||
|
||||
OPENCV_HAL_IMPL_RVV_SPLIT(split8u, uchar, uint8, u8, 8)
|
||||
OPENCV_HAL_IMPL_RVV_SPLIT(split16u, ushort, uint16, u16, 16)
|
||||
OPENCV_HAL_IMPL_RVV_SPLIT(split32s, int, int32, i32, 32)
|
||||
OPENCV_HAL_IMPL_RVV_SPLIT(split64s, int64, int64, i64, 64)
|
||||
|
||||
#undef OPENCV_HAL_IMPL_RVV_SPLIT
|
||||
|
||||
#endif // CV_HAL_RVV_1P0_ENABLED
|
||||
|
||||
}}} // cv::rvv_hal::core
|
||||
|
||||
@@ -7,28 +7,7 @@
|
||||
|
||||
#include "rvv_hal.hpp"
|
||||
|
||||
#if defined (__clang__) && __clang_major__ < 18
|
||||
#define OPENCV_HAL_IMPL_RVV_VCREATE_x4(suffix, width, v0, v1, v2, v3) \
|
||||
__riscv_vset_v_##suffix##m##width##_##suffix##m##width##x4(v, 0, v0); \
|
||||
v = __riscv_vset(v, 1, v1); \
|
||||
v = __riscv_vset(v, 2, v2); \
|
||||
v = __riscv_vset(v, 3, v3);
|
||||
|
||||
#define OPENCV_HAL_IMPL_RVV_VCREATE_x8(suffix, width, v0, v1, v2, v3, v4, v5, v6, v7) \
|
||||
__riscv_vset_v_##suffix##m##width##_##suffix##m##width##x8(v, 0, v0); \
|
||||
v = __riscv_vset(v, 1, v1); \
|
||||
v = __riscv_vset(v, 2, v2); \
|
||||
v = __riscv_vset(v, 3, v3); \
|
||||
v = __riscv_vset(v, 4, v4); \
|
||||
v = __riscv_vset(v, 5, v5); \
|
||||
v = __riscv_vset(v, 6, v6); \
|
||||
v = __riscv_vset(v, 7, v7);
|
||||
|
||||
#define __riscv_vcreate_v_u8m1x8(v0, v1, v2, v3, v4, v5, v6, v7) OPENCV_HAL_IMPL_RVV_VCREATE_x8(u8, 1, v0, v1, v2, v3, v4, v5, v6, v7)
|
||||
#define __riscv_vcreate_v_u16m1x8(v0, v1, v2, v3, v4, v5, v6, v7) OPENCV_HAL_IMPL_RVV_VCREATE_x8(u16, 1, v0, v1, v2, v3, v4, v5, v6, v7)
|
||||
#define __riscv_vcreate_v_i32m1x4(v0, v1, v2, v3) OPENCV_HAL_IMPL_RVV_VCREATE_x4(i32, 1, v0, v1, v2, v3)
|
||||
#define __riscv_vcreate_v_i64m1x8(v0, v1, v2, v3, v4, v5, v6, v7) OPENCV_HAL_IMPL_RVV_VCREATE_x8(i64, 1, v0, v1, v2, v3, v4, v5, v6, v7)
|
||||
#endif
|
||||
#include "rvv_vcreate.hpp"
|
||||
|
||||
namespace cv { namespace rvv_hal { namespace core {
|
||||
|
||||
@@ -186,7 +165,8 @@ static void transpose2d_32sC2(const uchar *src_data, size_t src_step, uchar *dst
|
||||
using Transpose2dFunc = void (*)(const uchar*, size_t, uchar*, size_t, int, int);
|
||||
int transpose2d(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step,
|
||||
int src_width, int src_height, int element_size) {
|
||||
if (src_data == dst_data) {
|
||||
if (src_data == dst_data || element_size <= 0 ||
|
||||
src_step % element_size != 0 || dst_step % element_size != 0) {
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
@@ -3855,6 +3855,11 @@ map_y(u,v) \leftarrow y''' f_y + c_y
|
||||
where \f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$
|
||||
are the distortion coefficients.
|
||||
|
||||
@note The rational distortion model used by OpenCV can be seen as a
|
||||
combination of the Brown-Conrady Model and the Division Model @cite Fitzgibbon01.
|
||||
It should not be confused with the Rational Function Model @cite Claus05a, which
|
||||
uses conics to represent lens distortion.
|
||||
|
||||
In case of a stereo camera, this function is called twice: once for each camera head, after
|
||||
#stereoRectify, which in its turn is called after #stereoCalibrate. But if the stereo camera
|
||||
was not calibrated, it is still possible to compute the rectification transformations directly from
|
||||
|
||||
@@ -92,5 +92,85 @@ class calibration_test(NewOpenCVTests):
|
||||
self.assertTrue(isinstance(dist, (float, np.floating)))
|
||||
self.assertGreaterEqual(dist, 0.0)
|
||||
|
||||
@staticmethod
|
||||
def _random_rt():
|
||||
# random rotation (axis-angle) + random translation
|
||||
axis = np.random.uniform(-1, 1, 3)
|
||||
axis /= np.linalg.norm(axis)
|
||||
angle = np.random.uniform(0.2, 1.0) * (1 if np.random.rand() > 0.5 else -1)
|
||||
rvec = (axis * angle).astype(np.float64)
|
||||
R, _ = cv.Rodrigues(rvec)
|
||||
t = np.random.uniform(-100, 100, 3).astype(np.float64)
|
||||
return R, t
|
||||
|
||||
@staticmethod
|
||||
def _to_T(R, t):
|
||||
T = np.eye(4)
|
||||
T[:3, :3] = R
|
||||
T[:3, 3] = t
|
||||
return T
|
||||
|
||||
def test_calibrateHandEye(self):
|
||||
# Ground truth camera-to-gripper transform (what calibrateHandEye should recover)
|
||||
R_cam2gripper_gt, t_cam2gripper_gt = self._random_rt()
|
||||
X = self._to_T(R_cam2gripper_gt, t_cam2gripper_gt)
|
||||
|
||||
# Arbitrary fixed target-to-base transform (the calibration board doesn't move)
|
||||
R_target2base, t_target2base = self._random_rt()
|
||||
Wt = self._to_T(R_target2base, t_target2base)
|
||||
|
||||
n_poses = 10
|
||||
Rs_gripper2base, ts_gripper2base = [], []
|
||||
Rs_target2cam, ts_target2cam = [], []
|
||||
for _ in range(n_poses):
|
||||
R_g2b, t_g2b = self._random_rt()
|
||||
G = self._to_T(R_g2b, t_g2b)
|
||||
# Consistent synthetic data: Wt == G @ X @ T_target2cam for every pose
|
||||
T_target2cam = np.linalg.inv(X) @ np.linalg.inv(G) @ Wt
|
||||
|
||||
Rs_gripper2base.append(R_g2b)
|
||||
ts_gripper2base.append(t_g2b)
|
||||
Rs_target2cam.append(T_target2cam[:3, :3])
|
||||
ts_target2cam.append(T_target2cam[:3, 3])
|
||||
|
||||
R_cam2gripper, t_cam2gripper = cv.calibrateHandEye(
|
||||
Rs_gripper2base, ts_gripper2base, Rs_target2cam, ts_target2cam)
|
||||
|
||||
self.assertLess(cv.norm(R_cam2gripper - R_cam2gripper_gt, cv.NORM_L1), 1e-3)
|
||||
self.assertLess(cv.norm(t_cam2gripper.flatten() - t_cam2gripper_gt, cv.NORM_L1), 1e-3)
|
||||
|
||||
def test_calibrateRobotWorldHandEye(self):
|
||||
# Ground truth outputs (what calibrateRobotWorldHandEye should recover)
|
||||
R_base2world_gt, t_base2world_gt = self._random_rt()
|
||||
X = self._to_T(R_base2world_gt, t_base2world_gt)
|
||||
|
||||
R_gripper2cam_gt, t_gripper2cam_gt = self._random_rt()
|
||||
Z = self._to_T(R_gripper2cam_gt, t_gripper2cam_gt)
|
||||
|
||||
n_poses = 10
|
||||
Rs_world2cam, ts_world2cam = [], []
|
||||
Rs_base2gripper, ts_base2gripper = [], []
|
||||
for _ in range(n_poses):
|
||||
R_b2g, t_b2g = self._random_rt()
|
||||
B = self._to_T(R_b2g, t_b2g)
|
||||
# Consistent synthetic data: A_i @ X == Z @ B_i => A_i = Z @ B_i @ inv(X)
|
||||
A = Z @ B @ np.linalg.inv(X)
|
||||
|
||||
Rs_world2cam.append(A[:3, :3])
|
||||
# NOTE: unlike calibrateHandEye, calibrateRobotWorldHandEye's Shah/Li
|
||||
# solvers require translations as explicit (3,1) column vectors, not
|
||||
# flat (3,) arrays -- passing (3,) raises a gemm shape-assertion error.
|
||||
ts_world2cam.append(A[:3, 3].reshape(3, 1))
|
||||
Rs_base2gripper.append(R_b2g)
|
||||
ts_base2gripper.append(t_b2g.reshape(3, 1))
|
||||
|
||||
R_base2world, t_base2world, R_gripper2cam, t_gripper2cam = cv.calibrateRobotWorldHandEye(
|
||||
Rs_world2cam, ts_world2cam, Rs_base2gripper, ts_base2gripper)
|
||||
|
||||
self.assertLess(cv.norm(R_base2world - R_base2world_gt, cv.NORM_L1), 1e-3)
|
||||
self.assertLess(cv.norm(t_base2world.flatten() - t_base2world_gt, cv.NORM_L1), 1e-3)
|
||||
self.assertLess(cv.norm(R_gripper2cam - R_gripper2cam_gt, cv.NORM_L1), 1e-3)
|
||||
self.assertLess(cv.norm(t_gripper2cam.flatten() - t_gripper2cam_gt, cv.NORM_L1), 1e-3)
|
||||
|
||||
if __name__ == '__main__':
|
||||
NewOpenCVTests.bootstrap()
|
||||
|
||||
41
modules/calib3d/perf/perf_filterspeckles.cpp
Normal file
41
modules/calib3d/perf/perf_filterspeckles.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
// Copyright (C) 2026, Intel Corporation, all rights reserved.
|
||||
#include "perf_precomp.hpp"
|
||||
|
||||
namespace opencv_test
|
||||
{
|
||||
using namespace perf;
|
||||
|
||||
#define FILTERSPECKLES_TYPES CV_8UC1, CV_16SC1
|
||||
|
||||
typedef tuple<Size, MatType> Size_MatType_t;
|
||||
typedef perf::TestBaseWithParam<Size_MatType_t> Size_MatType_FilterSpeckles;
|
||||
|
||||
PERF_TEST_P(Size_MatType_FilterSpeckles, filterSpeckles,
|
||||
testing::Combine(
|
||||
testing::Values(szVGA, sz720p, sz1080p),
|
||||
testing::Values(FILTERSPECKLES_TYPES)
|
||||
))
|
||||
{
|
||||
Size sz = get<0>(GetParam());
|
||||
int type = get<1>(GetParam());
|
||||
|
||||
// filterSpeckles works in place on a disparity map.
|
||||
Mat src(sz, type);
|
||||
Mat dst(sz, type);
|
||||
declare.in(src, WARMUP_RNG).out(dst);
|
||||
|
||||
while (next())
|
||||
{
|
||||
src.copyTo(dst);
|
||||
startTimer();
|
||||
cv::filterSpeckles(dst, 0, 2, 2);
|
||||
stopTimer();
|
||||
}
|
||||
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -2471,14 +2471,14 @@ static void collectCalibrationData( InputArrayOfArrays objectPoints,
|
||||
Mat objectPoint = objectPoints.getMat(i);
|
||||
if (objectPoint.empty())
|
||||
CV_Error(cv::Error::StsBadSize, "objectPoints should not contain empty vector of vectors of points");
|
||||
int numberOfObjectPoints = objectPoint.checkVector(3, CV_32F);
|
||||
int numberOfObjectPoints = objectPoint.checkVector(3, CV_32F, false);
|
||||
if (numberOfObjectPoints <= 0)
|
||||
CV_Error(cv::Error::StsUnsupportedFormat, "objectPoints should contain vector of vectors of points of type Point3f");
|
||||
|
||||
Mat imagePoint1 = imagePoints1.getMat(i);
|
||||
if (imagePoint1.empty())
|
||||
CV_Error(cv::Error::StsBadSize, "imagePoints1 should not contain empty vector of vectors of points");
|
||||
int numberOfImagePoints = imagePoint1.checkVector(2, CV_32F);
|
||||
int numberOfImagePoints = imagePoint1.checkVector(2, CV_32F, false);
|
||||
if (numberOfImagePoints <= 0)
|
||||
CV_Error(cv::Error::StsUnsupportedFormat, "imagePoints1 should contain vector of vectors of points of type Point2f");
|
||||
CV_CheckEQ(numberOfObjectPoints, numberOfImagePoints, "Number of object and image points must be equal");
|
||||
@@ -2507,7 +2507,11 @@ static void collectCalibrationData( InputArrayOfArrays objectPoints,
|
||||
{
|
||||
Mat objpt = objectPoints.getMat(i);
|
||||
Mat imgpt1 = imagePoints1.getMat(i);
|
||||
int numberOfObjectPoints = objpt.checkVector(3, CV_32F);
|
||||
int numberOfObjectPoints = objpt.checkVector(3, CV_32F, false);
|
||||
if (!objpt.isContinuous())
|
||||
objpt = objpt.clone();
|
||||
if (!imgpt1.isContinuous())
|
||||
imgpt1 = imgpt1.clone();
|
||||
nPointsMat.at<int>(i) = numberOfObjectPoints;
|
||||
for (int n = 0; n < numberOfObjectPoints; ++n)
|
||||
{
|
||||
@@ -2518,8 +2522,10 @@ static void collectCalibrationData( InputArrayOfArrays objectPoints,
|
||||
if (imgPtData2)
|
||||
{
|
||||
Mat imgpt2 = imagePoints2.getMat(i);
|
||||
int numberOfImage2Points = imgpt2.checkVector(2, CV_32F);
|
||||
int numberOfImage2Points = imgpt2.checkVector(2, CV_32F, false);
|
||||
CV_CheckEQ(numberOfObjectPoints, numberOfImage2Points, "Number of object and image(2) points must be equal");
|
||||
if (!imgpt2.isContinuous())
|
||||
imgpt2 = imgpt2.clone();
|
||||
for (int n = 0; n < numberOfImage2Points; ++n)
|
||||
{
|
||||
imgPtData2[j + n] = imgpt2.ptr<Point2f>()[n];
|
||||
|
||||
@@ -55,6 +55,99 @@ namespace cv { namespace
|
||||
};
|
||||
}}
|
||||
|
||||
namespace cv { namespace
|
||||
{
|
||||
|
||||
static double normalizePoints(const Mat& points,
|
||||
Mat& normalizedPoints,
|
||||
Mat& pointMean)
|
||||
{
|
||||
using std::fpclassify;
|
||||
using std::sqrt;
|
||||
constexpr double defaultPointScale = 1.0;
|
||||
const Mat pointCoordinates =
|
||||
points.reshape(1, static_cast<int>(points.total()));
|
||||
reduce(pointCoordinates, pointMean, 0, REDUCE_AVG);
|
||||
|
||||
Mat centeredPoints = pointCoordinates -
|
||||
Mat::ones(pointCoordinates.rows, 1, CV_64F) * pointMean;
|
||||
// Apply Hartley normalization. The maximum coordinate is an intermediate
|
||||
// preconditioner that prevents the squared norm from underflowing.
|
||||
double maximumCoordinate = norm(centeredPoints, NORM_INF);
|
||||
if (fpclassify(maximumCoordinate) == FP_ZERO)
|
||||
{
|
||||
maximumCoordinate = defaultPointScale;
|
||||
}
|
||||
Mat scaledPoints = centeredPoints / maximumCoordinate;
|
||||
double standardDeviation =
|
||||
norm(scaledPoints, NORM_L2) / sqrt(scaledPoints.total());
|
||||
if (fpclassify(standardDeviation) == FP_ZERO)
|
||||
{
|
||||
standardDeviation = defaultPointScale;
|
||||
}
|
||||
scaledPoints = scaledPoints / standardDeviation;
|
||||
normalizedPoints = scaledPoints.reshape(points.channels(), points.rows);
|
||||
// Restore the standard deviation to the original coordinate scale.
|
||||
return maximumCoordinate * standardDeviation;
|
||||
}
|
||||
|
||||
class ExtrinsicsCallback : public LMSolver::Callback
|
||||
{
|
||||
public:
|
||||
ExtrinsicsCallback(Mat imagePoints, Mat objectPoints,
|
||||
internal::IntrinsicParams params)
|
||||
: imagePoints_(imagePoints)
|
||||
, objectPoints_(objectPoints)
|
||||
, params_(params)
|
||||
{
|
||||
}
|
||||
|
||||
bool compute(InputArray extrinsics, OutputArray residuals,
|
||||
OutputArray J) const override
|
||||
{
|
||||
Vec6d rtvec;
|
||||
extrinsics.copyTo(rtvec);
|
||||
|
||||
const Vec3d rvec(rtvec.val);
|
||||
const Vec3d tvec(rtvec.val + 3);
|
||||
|
||||
Mat expected;
|
||||
|
||||
if (J.needed())
|
||||
{
|
||||
Mat jacobians;
|
||||
internal::projectPoints(objectPoints_, expected, rvec, tvec,
|
||||
params_, jacobians);
|
||||
|
||||
jacobians.colRange(8, 14).copyTo(J);
|
||||
}
|
||||
else
|
||||
{
|
||||
internal::projectPoints(objectPoints_, expected, rvec, tvec,
|
||||
params_, noArray());
|
||||
}
|
||||
|
||||
if (residuals.needed())
|
||||
{
|
||||
Mat residualDifference;
|
||||
// LMSolver expects the Jacobian of the ideal projection.
|
||||
subtract(expected, imagePoints_, residualDifference);
|
||||
|
||||
residualDifference = residualDifference.reshape(1);
|
||||
transpose(residualDifference, residuals);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
Mat imagePoints_;
|
||||
Mat objectPoints_;
|
||||
internal::IntrinsicParams params_;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// cv::fisheye::projectPoints
|
||||
|
||||
@@ -786,9 +879,32 @@ double cv::fisheye::calibrate(InputArrayOfArrays objectPoints, InputArrayOfArray
|
||||
|
||||
errors.isEstimate = finalParam.isEstimate;
|
||||
|
||||
std::vector<Vec3d> omc(objectPoints.total()), Tc(objectPoints.total());
|
||||
// Keep each view normalized through calibration to avoid scale-dependent
|
||||
// overflow in the Jacobian and uncertainty calculations.
|
||||
const size_t numberOfViews = objectPoints.total();
|
||||
std::vector<Mat> normalizedObjectPoints(numberOfViews);
|
||||
std::vector<Vec3d> objectPointMeans(numberOfViews);
|
||||
std::vector<double> objectPointScales(numberOfViews);
|
||||
for (size_t image_idx = 0; image_idx < numberOfViews; ++image_idx)
|
||||
{
|
||||
Mat object;
|
||||
objectPoints.getMat(static_cast<int>(image_idx)).convertTo(object,
|
||||
CV_64FC3);
|
||||
Mat objectPointMean;
|
||||
objectPointScales[image_idx] =
|
||||
normalizePoints(object, normalizedObjectPoints[image_idx],
|
||||
objectPointMean);
|
||||
objectPointMeans[image_idx] =
|
||||
Vec3d(objectPointMean.at<double>(0, 0),
|
||||
objectPointMean.at<double>(0, 1),
|
||||
objectPointMean.at<double>(0, 2));
|
||||
}
|
||||
|
||||
CalibrateExtrinsics(objectPoints, imagePoints, finalParam, check_cond, thresh_cond, omc, Tc);
|
||||
std::vector<Vec3d> omc(numberOfViews);
|
||||
std::vector<Vec3d> Tc(numberOfViews);
|
||||
|
||||
CalibrateExtrinsics(normalizedObjectPoints, imagePoints, finalParam,
|
||||
check_cond, thresh_cond, omc, Tc);
|
||||
|
||||
|
||||
//-------------------------------Optimization
|
||||
@@ -802,7 +918,8 @@ double cv::fisheye::calibrate(InputArrayOfArrays objectPoints, InputArrayOfArray
|
||||
double alpha_smooth2 = 1 - std::pow(1 - alpha_smooth, iter + 1.0);
|
||||
|
||||
Mat JJ2, ex3;
|
||||
ComputeJacobians(objectPoints, imagePoints, finalParam, omc, Tc, check_cond,thresh_cond, JJ2, ex3);
|
||||
ComputeJacobians(normalizedObjectPoints, imagePoints, finalParam, omc,
|
||||
Tc, check_cond, thresh_cond, JJ2, ex3);
|
||||
|
||||
Mat G;
|
||||
solve(JJ2, ex3, G);
|
||||
@@ -816,15 +933,25 @@ double cv::fisheye::calibrate(InputArrayOfArrays objectPoints, InputArrayOfArray
|
||||
|
||||
if (recompute_extrinsic)
|
||||
{
|
||||
CalibrateExtrinsics(objectPoints, imagePoints, finalParam, check_cond,
|
||||
thresh_cond, omc, Tc);
|
||||
CalibrateExtrinsics(normalizedObjectPoints, imagePoints, finalParam,
|
||||
check_cond, thresh_cond, omc, Tc);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------Validation
|
||||
double rms;
|
||||
EstimateUncertainties(objectPoints, imagePoints, finalParam, omc, Tc, errors, err_std, thresh_cond,
|
||||
check_cond, rms);
|
||||
EstimateUncertainties(normalizedObjectPoints, imagePoints, finalParam, omc,
|
||||
Tc, errors, err_std, thresh_cond, check_cond, rms);
|
||||
|
||||
std::vector<Vec3d> physicalTranslations(numberOfViews);
|
||||
for (size_t image_idx = 0; image_idx < numberOfViews; ++image_idx)
|
||||
{
|
||||
Matx33d rotationMatrix;
|
||||
Rodrigues(omc[image_idx], rotationMatrix);
|
||||
physicalTranslations[image_idx] =
|
||||
objectPointScales[image_idx] * Tc[image_idx] -
|
||||
rotationMatrix * objectPointMeans[image_idx];
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
_K = Matx33d(finalParam.f[0], finalParam.f[0] * finalParam.alpha, finalParam.c[0],
|
||||
@@ -835,7 +962,7 @@ double cv::fisheye::calibrate(InputArrayOfArrays objectPoints, InputArrayOfArray
|
||||
if (D.needed()) cv::Mat(finalParam.k).convertTo(D, D.empty() ? CV_64FC1 : D.type());
|
||||
if (rvecs.isMatVector())
|
||||
{
|
||||
int N = (int)objectPoints.total();
|
||||
int N = static_cast<int>(numberOfViews);
|
||||
|
||||
if(rvecs.empty())
|
||||
rvecs.create(N, 1, CV_64FC3);
|
||||
@@ -848,13 +975,16 @@ double cv::fisheye::calibrate(InputArrayOfArrays objectPoints, InputArrayOfArray
|
||||
rvecs.create(3, 1, CV_64F, i, true);
|
||||
tvecs.create(3, 1, CV_64F, i, true);
|
||||
memcpy(rvecs.getMat(i).ptr(), omc[i].val, sizeof(Vec3d));
|
||||
memcpy(tvecs.getMat(i).ptr(), Tc[i].val, sizeof(Vec3d));
|
||||
memcpy(tvecs.getMat(i).ptr(), physicalTranslations[i].val,
|
||||
sizeof(Vec3d));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rvecs.needed()) cv::Mat(omc).convertTo(rvecs, rvecs.empty() ? CV_64FC3 : rvecs.type());
|
||||
if (tvecs.needed()) cv::Mat(Tc).convertTo(tvecs, tvecs.empty() ? CV_64FC3 : tvecs.type());
|
||||
if (tvecs.needed())
|
||||
cv::Mat(physicalTranslations).convertTo(
|
||||
tvecs, tvecs.empty() ? CV_64FC3 : tvecs.type());
|
||||
}
|
||||
|
||||
return rms;
|
||||
@@ -1264,46 +1394,32 @@ void cv::internal::projectPoints(cv::InputArray objectPoints, cv::OutputArray im
|
||||
|
||||
void cv::internal::ComputeExtrinsicRefine(const Mat& imagePoints, const Mat& objectPoints, Mat& rvec,
|
||||
Mat& tvec, Mat& J, const int MaxIter,
|
||||
const IntrinsicParams& param, const double thresh_cond)
|
||||
const IntrinsicParams& param)
|
||||
{
|
||||
CV_Assert(!objectPoints.empty() && objectPoints.type() == CV_64FC3);
|
||||
CV_Assert(!imagePoints.empty() && imagePoints.type() == CV_64FC2);
|
||||
CV_Assert(rvec.total() > 2 && tvec.total() > 2);
|
||||
Vec6d extrinsics(rvec.at<double>(0), rvec.at<double>(1), rvec.at<double>(2),
|
||||
tvec.at<double>(0), tvec.at<double>(1), tvec.at<double>(2));
|
||||
double change = 1;
|
||||
int iter = 0;
|
||||
tvec.at<double>(0), tvec.at<double>(1),
|
||||
tvec.at<double>(2));
|
||||
|
||||
while (change > 1e-10 && iter < MaxIter)
|
||||
{
|
||||
std::vector<Point2d> x;
|
||||
Mat jacobians;
|
||||
projectPoints(objectPoints, x, rvec, tvec, param, jacobians);
|
||||
auto callback =
|
||||
cv::makePtr<ExtrinsicsCallback>(imagePoints, objectPoints,
|
||||
param);
|
||||
const double solverEpsilon = std::numeric_limits<double>::epsilon();
|
||||
auto solver = LMSolver::create(callback, MaxIter, solverEpsilon);
|
||||
solver->run(extrinsics);
|
||||
|
||||
Mat ex = imagePoints - Mat(x).t();
|
||||
ex = ex.reshape(1, 2);
|
||||
// Copy back refined parameters
|
||||
const cv::Vec3d r(extrinsics.val);
|
||||
const cv::Vec3d t(extrinsics.val + 3);
|
||||
|
||||
J = jacobians.colRange(8, 14).clone();
|
||||
cv::copyTo(r, rvec, cv::noArray());
|
||||
cv::copyTo(t, tvec, cv::noArray());
|
||||
|
||||
SVD svd(J, SVD::NO_UV);
|
||||
double condJJ = svd.w.at<double>(0)/svd.w.at<double>(5);
|
||||
|
||||
if (condJJ > thresh_cond)
|
||||
change = 0;
|
||||
else
|
||||
{
|
||||
Vec6d param_innov;
|
||||
solve(J, ex.reshape(1, (int)ex.total()), param_innov, DECOMP_SVD + DECOMP_NORMAL);
|
||||
|
||||
Vec6d param_up = extrinsics + param_innov;
|
||||
change = norm(param_innov)/norm(param_up);
|
||||
extrinsics = param_up;
|
||||
iter = iter + 1;
|
||||
|
||||
rvec = Mat(Vec3d(extrinsics.val));
|
||||
tvec = Mat(Vec3d(extrinsics.val+3));
|
||||
}
|
||||
}
|
||||
// Avoid caching, which would require mutable state, at the expense of
|
||||
// one final recomputation.
|
||||
callback->compute(extrinsics, noArray(), J);
|
||||
}
|
||||
|
||||
cv::Mat cv::internal::ComputeHomography(Mat m, Mat M)
|
||||
@@ -1493,7 +1609,7 @@ void cv::internal::CalibrateExtrinsics(InputArrayOfArrays objectPoints, InputArr
|
||||
|
||||
InitExtrinsics(imT ? image.t() : image, obT ? object.t() : object, param, omckk, Tckk);
|
||||
|
||||
ComputeExtrinsicRefine(!imT ? image.t() : image, !obT ? object.t() : object, omckk, Tckk, JJ_kk, maxIter, param, thresh_cond);
|
||||
ComputeExtrinsicRefine(!imT ? image.t() : image, !obT ? object.t() : object, omckk, Tckk, JJ_kk, maxIter, param);
|
||||
if (check_cond)
|
||||
{
|
||||
SVD svd(JJ_kk, SVD::NO_UV);
|
||||
|
||||
@@ -25,7 +25,7 @@ void projectPoints(cv::InputArray objectPoints, cv::OutputArray imagePoints,
|
||||
|
||||
void ComputeExtrinsicRefine(const Mat& imagePoints, const Mat& objectPoints, Mat& rvec,
|
||||
Mat& tvec, Mat& J, const int MaxIter,
|
||||
const IntrinsicParams& param, const double thresh_cond);
|
||||
const IntrinsicParams& param);
|
||||
CV_EXPORTS Mat ComputeHomography(Mat m, Mat M);
|
||||
|
||||
CV_EXPORTS Mat NormalizePixels(const Mat& imagePoints, const IntrinsicParams& param);
|
||||
|
||||
@@ -303,13 +303,17 @@ void PoseSolver::rot2vec(InputArray _R, OutputArray _r)
|
||||
Mat rvec = _r.getMat();
|
||||
|
||||
double trace = R.at<double>(0, 0) + R.at<double>(1, 1) + R.at<double>(2, 2);
|
||||
double w_norm = acos((trace - 1.0) / 2.0);
|
||||
double w_norm = acos(std::min(std::max((trace - 1.0) / 2.0, -1.0), 1.0));
|
||||
double eps = std::numeric_limits<float>::epsilon();
|
||||
double d = 1 / (2 * sin(w_norm)) * w_norm;
|
||||
if (w_norm < eps) //rotation is the identity
|
||||
{
|
||||
rvec.setTo(0);
|
||||
}
|
||||
else if (sin(w_norm) < 1e-5) //close to 180 degrees, the axis can't be read from R - R^T
|
||||
{
|
||||
Rodrigues(R, rvec);
|
||||
}
|
||||
else
|
||||
{
|
||||
double c0 = R.at<double>(2, 1) - R.at<double>(1, 2);
|
||||
|
||||
@@ -750,14 +750,14 @@ static void solvePnPRefine(InputArray _objectPoints, InputArray _imagePoints,
|
||||
Mat params(6, 1, CV_64FC1);
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
params.at<double>(i,0) = rvec.at<double>(i,0);
|
||||
params.at<double>(i+3,0) = tvec.at<double>(i,0);
|
||||
params.at<double>(i,0) = rvec.at<double>(i);
|
||||
params.at<double>(i+3,0) = tvec.at<double>(i);
|
||||
}
|
||||
|
||||
LMSolver::create(makePtr<SolvePnPRefineLMCallback>(opoints, ipoints, cameraMatrix, distCoeffs), _criteria.maxCount, _criteria.epsilon)->run(params);
|
||||
|
||||
params.rowRange(0, 3).convertTo(rvec0, rvec0.depth());
|
||||
params.rowRange(3, 6).convertTo(tvec0, tvec0.depth());
|
||||
params.rowRange(0, 3).reshape(1, rvec0.rows).convertTo(rvec0, rvec0.depth());
|
||||
params.rowRange(3, 6).reshape(1, tvec0.rows).convertTo(tvec0, tvec0.depth());
|
||||
}
|
||||
else if (_flags == SOLVEPNP_REFINE_VVS)
|
||||
{
|
||||
@@ -765,6 +765,10 @@ static void solvePnPRefine(InputArray _objectPoints, InputArray _imagePoints,
|
||||
Mat rvec, tvec;
|
||||
rvec0.convertTo(rvec, CV_64F);
|
||||
tvec0.convertTo(tvec, CV_64F);
|
||||
// tvec is used in matrix arithmetic below (R1 * tvec) which requires
|
||||
// a Size(3,1) column vector; rvec0/tvec0 (and hence rvec/tvec) may
|
||||
// be Size(1,3) row vectors per this function's own precondition check.
|
||||
tvec = tvec.reshape(1, 3);
|
||||
|
||||
std::vector<Point2d> ipoints_normalized;
|
||||
undistortPoints(ipoints, ipoints_normalized, cameraMatrix, distCoeffs);
|
||||
@@ -799,8 +803,8 @@ static void solvePnPRefine(InputArray _objectPoints, InputArray _imagePoints,
|
||||
}
|
||||
|
||||
Rodrigues(R, rvec);
|
||||
rvec.convertTo(rvec0, rvec0.depth());
|
||||
tvec.convertTo(tvec0, tvec0.depth());
|
||||
rvec.reshape(1, rvec0.rows).convertTo(rvec0, rvec0.depth());
|
||||
tvec.reshape(1, tvec0.rows).convertTo(tvec0, tvec0.depth());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include <iterator>
|
||||
|
||||
namespace cv {
|
||||
|
||||
|
||||
@@ -2074,41 +2074,44 @@ void SGBM3WayMainLoop::impl(const Range& range) const
|
||||
{
|
||||
d = 0;
|
||||
#if (CV_SIMD || CV_SIMD_SCALABLE)
|
||||
horPassCostVolume+=x;
|
||||
int thresh = (100*min_cost)/(100-uniquenessRatio);
|
||||
v_int16 thresh_reg = vx_setall_s16((short)(thresh+1));
|
||||
v_int16 d1 = vx_setall_s16((short)(best_d-1));
|
||||
v_int16 d2 = vx_setall_s16((short)(best_d+1));
|
||||
v_int16 eight_reg = vx_setall_s16((short)VTraits<v_int16>::vlanes());
|
||||
v_int16 cur_d = vx_load(idx_row);
|
||||
v_int16 mask;
|
||||
if(uniquenessRatio<100)
|
||||
{
|
||||
horPassCostVolume+=x;
|
||||
int thresh = (100*min_cost)/(100-uniquenessRatio);
|
||||
v_int16 thresh_reg = vx_setall_s16(saturate_cast<short>(thresh+1));
|
||||
v_int16 d1 = vx_setall_s16((short)(best_d-1));
|
||||
v_int16 d2 = vx_setall_s16((short)(best_d+1));
|
||||
v_int16 eight_reg = vx_setall_s16((short)VTraits<v_int16>::vlanes());
|
||||
v_int16 cur_d = vx_load(idx_row);
|
||||
v_int16 mask;
|
||||
|
||||
for( ; d <= D - 2*VTraits<v_int16>::vlanes(); d+=2*VTraits<v_int16>::vlanes() )
|
||||
{
|
||||
mask = v_and(v_lt(vx_load_aligned(horPassCostVolume + d), thresh_reg), v_or(v_lt(cur_d, d1), v_gt(cur_d, d2)));
|
||||
cur_d = v_add(cur_d, eight_reg);
|
||||
if( v_check_any(mask) )
|
||||
break;
|
||||
mask = v_and(v_lt(vx_load_aligned(horPassCostVolume + d + VTraits<v_int16>::vlanes()), thresh_reg), v_or(v_lt(cur_d, d1), v_gt(cur_d, d2)));
|
||||
cur_d = v_add(cur_d, eight_reg);
|
||||
if( v_check_any(mask) )
|
||||
break;
|
||||
}
|
||||
if( d <= D - 2*VTraits<v_int16>::vlanes() )
|
||||
{
|
||||
horPassCostVolume-=x;
|
||||
continue;
|
||||
}
|
||||
if( d <= D - VTraits<v_int16>::vlanes() )
|
||||
{
|
||||
if( v_check_any(v_and(v_lt(vx_load_aligned(horPassCostVolume + d), thresh_reg), v_or(v_lt(cur_d, d1), v_gt(cur_d, d2)))) )
|
||||
for( ; d <= D - 2*VTraits<v_int16>::vlanes(); d+=2*VTraits<v_int16>::vlanes() )
|
||||
{
|
||||
mask = v_and(v_lt(vx_load_aligned(horPassCostVolume + d), thresh_reg), v_or(v_lt(cur_d, d1), v_gt(cur_d, d2)));
|
||||
cur_d = v_add(cur_d, eight_reg);
|
||||
if( v_check_any(mask) )
|
||||
break;
|
||||
mask = v_and(v_lt(vx_load_aligned(horPassCostVolume + d + VTraits<v_int16>::vlanes()), thresh_reg), v_or(v_lt(cur_d, d1), v_gt(cur_d, d2)));
|
||||
cur_d = v_add(cur_d, eight_reg);
|
||||
if( v_check_any(mask) )
|
||||
break;
|
||||
}
|
||||
if( d <= D - 2*VTraits<v_int16>::vlanes() )
|
||||
{
|
||||
horPassCostVolume-=x;
|
||||
continue;
|
||||
}
|
||||
d+=VTraits<v_int16>::vlanes();
|
||||
if( d <= D - VTraits<v_int16>::vlanes() )
|
||||
{
|
||||
if( v_check_any(v_and(v_lt(vx_load_aligned(horPassCostVolume + d), thresh_reg), v_or(v_lt(cur_d, d1), v_gt(cur_d, d2)))) )
|
||||
{
|
||||
horPassCostVolume-=x;
|
||||
continue;
|
||||
}
|
||||
d+=VTraits<v_int16>::vlanes();
|
||||
}
|
||||
horPassCostVolume-=x;
|
||||
}
|
||||
horPassCostVolume-=x;
|
||||
#endif
|
||||
for( ; d < D; d++ )
|
||||
{
|
||||
@@ -2553,6 +2556,9 @@ void cv::validateDisparity( InputOutputArray _disp, InputArray _cost, int minDis
|
||||
|
||||
int x2 = x - ((d + DISP_SCALE/2) >> DISP_SHIFT);
|
||||
|
||||
if( (unsigned)x2 >= (unsigned)cols )
|
||||
continue;
|
||||
|
||||
if( disp2cost[x2] > c )
|
||||
{
|
||||
disp2cost[x2] = c;
|
||||
@@ -2573,6 +2579,9 @@ void cv::validateDisparity( InputOutputArray _disp, InputArray _cost, int minDis
|
||||
|
||||
int x2 = x - ((d + DISP_SCALE/2) >> DISP_SHIFT);
|
||||
|
||||
if( (unsigned)x2 >= (unsigned)cols )
|
||||
continue;
|
||||
|
||||
if( disp2cost[x2] > c )
|
||||
{
|
||||
disp2cost[x2] = c;
|
||||
|
||||
@@ -1851,6 +1851,89 @@ void CV_StereoCalibrationTest_CPP::correct( const Mat& F,
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST(Calib3d_CalibrateCamera_CPP, regression) { CV_CameraCalibrationTest_CPP test; test.safe_run(); }
|
||||
|
||||
TEST(Calib3d_CalibrateCamera_CPP, nonContinuousPointVectors)
|
||||
{
|
||||
const Size imageSize(640, 480);
|
||||
const Mat cameraTruth = Mat(Matx33d(800.0, 0.0, 320.0,
|
||||
0.0, 810.0, 240.0,
|
||||
0.0, 0.0, 1.0));
|
||||
const Mat distTruth = Mat::zeros(5, 1, CV_64F);
|
||||
|
||||
vector<Point3f> board;
|
||||
for (int y = 0; y < 6; ++y)
|
||||
for (int x = 0; x < 7; ++x)
|
||||
board.push_back(Point3f((x - 3) * 0.04f, (y - 2.5f) * 0.04f, 0.0f));
|
||||
|
||||
const Vec3d rotations[] = {
|
||||
Vec3d(-0.20, 0.10, 0.02), Vec3d( 0.15, -0.12, -0.04),
|
||||
Vec3d(-0.08, -0.18, 0.08), Vec3d( 0.22, 0.05, -0.10),
|
||||
Vec3d(-0.16, 0.20, 0.12), Vec3d( 0.10, 0.16, -0.07)
|
||||
};
|
||||
const Vec3d translations[] = {
|
||||
Vec3d(-0.08, -0.04, 1.10), Vec3d( 0.06, -0.03, 1.25),
|
||||
Vec3d(-0.04, 0.07, 1.35), Vec3d( 0.08, 0.05, 1.20),
|
||||
Vec3d( 0.00, -0.08, 1.40), Vec3d(-0.06, 0.02, 1.15)
|
||||
};
|
||||
|
||||
vector<Mat> objectContinuous, imageContinuous;
|
||||
vector<Mat> objectBacking, imageBacking, objectBackingBefore, imageBackingBefore;
|
||||
vector<Mat> objectRoi, imageRoi;
|
||||
for (size_t i = 0; i < sizeof(rotations) / sizeof(rotations[0]); ++i)
|
||||
{
|
||||
vector<Point2f> projected;
|
||||
projectPoints(board, rotations[i], translations[i], cameraTruth, distTruth, projected);
|
||||
|
||||
objectContinuous.push_back(Mat(board).clone());
|
||||
imageContinuous.push_back(Mat(projected).clone());
|
||||
|
||||
Mat objectStorage((int)board.size(), 2, CV_32FC3, Scalar(-11.0f, -22.0f, -33.0f));
|
||||
Mat imageStorage((int)board.size(), 2, CV_32FC2, Scalar(-44.0f, -55.0f));
|
||||
objectContinuous.back().copyTo(objectStorage.col(0));
|
||||
imageContinuous.back().copyTo(imageStorage.col(0));
|
||||
objectBacking.push_back(objectStorage);
|
||||
imageBacking.push_back(imageStorage);
|
||||
objectBackingBefore.push_back(objectStorage.clone());
|
||||
imageBackingBefore.push_back(imageStorage.clone());
|
||||
objectRoi.push_back(objectStorage.col(0));
|
||||
imageRoi.push_back(imageStorage.col(0));
|
||||
|
||||
ASSERT_TRUE(objectContinuous.back().isContinuous());
|
||||
ASSERT_TRUE(imageContinuous.back().isContinuous());
|
||||
ASSERT_FALSE(objectRoi.back().isContinuous());
|
||||
ASSERT_FALSE(imageRoi.back().isContinuous());
|
||||
ASSERT_EQ(objectContinuous.back().size(), objectRoi.back().size());
|
||||
ASSERT_EQ(imageContinuous.back().size(), imageRoi.back().size());
|
||||
ASSERT_EQ(objectContinuous.back().type(), objectRoi.back().type());
|
||||
ASSERT_EQ(imageContinuous.back().type(), imageRoi.back().type());
|
||||
EXPECT_EQ(0.0, cv::norm(objectContinuous.back(), objectRoi.back(), NORM_INF));
|
||||
EXPECT_EQ(0.0, cv::norm(imageContinuous.back(), imageRoi.back(), NORM_INF));
|
||||
}
|
||||
|
||||
Mat cameraContinuous, distContinuous;
|
||||
const double rmsContinuous = calibrateCamera(objectContinuous, imageContinuous, imageSize,
|
||||
cameraContinuous, distContinuous,
|
||||
noArray(), noArray());
|
||||
EXPECT_LT(rmsContinuous, 1e-4);
|
||||
|
||||
Mat cameraRoi, distRoi;
|
||||
double rmsRoi = -1.0;
|
||||
SCOPED_TRACE(format("continuous RMS: %.12g", rmsContinuous));
|
||||
ASSERT_NO_THROW(rmsRoi = calibrateCamera(objectRoi, imageRoi, imageSize,
|
||||
cameraRoi, distRoi, noArray(), noArray()));
|
||||
|
||||
EXPECT_LT(rmsRoi, 1e-4);
|
||||
EXPECT_NEAR(rmsContinuous, rmsRoi, 1e-12);
|
||||
EXPECT_LE(cv::norm(cameraContinuous, cameraRoi, NORM_INF), 2e-9);
|
||||
EXPECT_LE(cv::norm(distContinuous, distRoi, NORM_INF), 2e-9);
|
||||
|
||||
for (size_t i = 0; i < objectBacking.size(); ++i)
|
||||
{
|
||||
EXPECT_EQ(0.0, cv::norm(objectBacking[i], objectBackingBefore[i], NORM_INF));
|
||||
EXPECT_EQ(0.0, cv::norm(imageBacking[i], imageBackingBefore[i], NORM_INF));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Calib3d_CalibrationMatrixValues_CPP, accuracy) { CV_CalibrationMatrixValuesTest_CPP test; test.safe_run(); }
|
||||
TEST(Calib3d_ProjectPoints_CPP, regression) { CV_ProjectPointsTest_CPP test; test.safe_run(); }
|
||||
|
||||
|
||||
@@ -66,6 +66,57 @@ protected:
|
||||
static void merge4(const cv::Mat& tl, const cv::Mat& tr, const cv::Mat& bl, const cv::Mat& br, cv::Mat& merged);
|
||||
};
|
||||
|
||||
static int fixedIntrinsicCalibrationFlags(const bool checkCondition)
|
||||
{
|
||||
int flags = cv::fisheye::CALIB_USE_INTRINSIC_GUESS |
|
||||
cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC |
|
||||
cv::fisheye::CALIB_FIX_FOCAL_LENGTH |
|
||||
cv::fisheye::CALIB_FIX_PRINCIPAL_POINT |
|
||||
cv::fisheye::CALIB_FIX_SKEW |
|
||||
cv::fisheye::CALIB_FIX_K1 |
|
||||
cv::fisheye::CALIB_FIX_K2 |
|
||||
cv::fisheye::CALIB_FIX_K3 |
|
||||
cv::fisheye::CALIB_FIX_K4;
|
||||
if (checkCondition)
|
||||
{
|
||||
flags |= cv::fisheye::CALIB_CHECK_COND;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
static void createNearCollinearView(cv::Matx33d& cameraMatrix,
|
||||
cv::Vec4d& distortion,
|
||||
cv::Size& imageSize,
|
||||
std::vector<cv::Point3d>& objectPoints,
|
||||
std::vector<cv::Point2d>& imagePoints)
|
||||
{
|
||||
const double focalLengthX = 600.0;
|
||||
const double focalLengthY = 610.0;
|
||||
const double principalPointX = 320.0;
|
||||
const double principalPointY = 240.0;
|
||||
const double lateralPerturbation = 1e-8;
|
||||
|
||||
cameraMatrix = cv::Matx33d(focalLengthX, 0.0, principalPointX,
|
||||
0.0, focalLengthY, principalPointY,
|
||||
0.0, 0.0, 1.0);
|
||||
distortion = cv::Vec4d::all(0);
|
||||
const cv::Vec3d trueR(0.2, -0.15, 0.1);
|
||||
const cv::Vec3d trueT(0.1, -0.2, 3.0);
|
||||
imageSize = cv::Size(640, 480);
|
||||
objectPoints = {
|
||||
{-0.4, -lateralPerturbation, 0.0},
|
||||
{-0.3, lateralPerturbation, 0.1},
|
||||
{-0.2, -lateralPerturbation, 0.2},
|
||||
{-0.1, lateralPerturbation, 0.3},
|
||||
{0.0, -lateralPerturbation, 0.4},
|
||||
{0.1, lateralPerturbation, 0.5},
|
||||
{0.2, -lateralPerturbation, 0.6},
|
||||
{0.3, lateralPerturbation, 0.7},
|
||||
{0.4, -lateralPerturbation, 0.8}};
|
||||
cv::fisheye::projectPoints(objectPoints, imagePoints, trueR, trueT,
|
||||
cameraMatrix, distortion);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// TESTS::
|
||||
|
||||
@@ -561,6 +612,182 @@ TEST_F(fisheyeTest, jacobians)
|
||||
CV_Assert (cv::norm(x2 - xpred) < 1e-10);
|
||||
}
|
||||
|
||||
class FisheyeExtrinsicRefinementScaleTest
|
||||
: public fisheyeTest,
|
||||
public ::testing::WithParamInterface<double>
|
||||
{
|
||||
};
|
||||
|
||||
TEST_P(FisheyeExtrinsicRefinementScaleTest, IsInvariantToObjectPointScale)
|
||||
{
|
||||
const cv::Matx33d cameraMatrix(600.0, 0.0, 320.0,
|
||||
0.0, 610.0, 240.0,
|
||||
0.0, 0.0, 1.0);
|
||||
const cv::Vec4d distortion = cv::Vec4d::all(0);
|
||||
const std::vector<cv::Vec3d> trueR = {
|
||||
{0.15, -0.1, 0.08}, {-0.1, 0.12, -0.06}};
|
||||
const std::vector<cv::Vec3d> trueT = {
|
||||
{0.2, -0.15, 3.0}, {-0.3, 0.1, 2.5}};
|
||||
const cv::Size testImageSize(640, 480);
|
||||
const int maxIterations = 1;
|
||||
const double scale = GetParam();
|
||||
const std::vector<cv::Point3d> baseObjectPoints = {
|
||||
{-0.4, -0.3, 0.0}, {0.0, -0.3, 0.1}, {0.4, -0.3, 0.0},
|
||||
{-0.4, 0.0, 0.1}, {0.0, 0.0, 0.0}, {0.4, 0.0, 0.1},
|
||||
{-0.4, 0.3, 0.0}, {0.0, 0.3, 0.1}, {0.4, 0.3, 0.0}};
|
||||
|
||||
std::vector<std::vector<cv::Point3d> > objectPoints(2);
|
||||
std::vector<std::vector<cv::Point2d> > imagePoints(2);
|
||||
for (size_t view = 0; view < trueR.size(); ++view)
|
||||
{
|
||||
for (const cv::Point3d& point : baseObjectPoints)
|
||||
{
|
||||
objectPoints[view].emplace_back(point * scale);
|
||||
}
|
||||
|
||||
const cv::Vec3d scaledTrueT = trueT[view] * scale;
|
||||
cv::fisheye::projectPoints(objectPoints[view], imagePoints[view],
|
||||
trueR[view], scaledTrueT,
|
||||
cameraMatrix, distortion);
|
||||
}
|
||||
|
||||
cv::Mat estimatedK = cv::Mat(cameraMatrix);
|
||||
cv::Mat estimatedD = cv::Mat(distortion);
|
||||
std::vector<cv::Vec3d> estimatedR;
|
||||
std::vector<cv::Vec3d> estimatedT;
|
||||
const int flags = fixedIntrinsicCalibrationFlags(false);
|
||||
cv::fisheye::calibrate(objectPoints, imagePoints, testImageSize, estimatedK,
|
||||
estimatedD, estimatedR, estimatedT, flags,
|
||||
cv::TermCriteria(cv::TermCriteria::COUNT,
|
||||
maxIterations, 0));
|
||||
|
||||
double rms = 0;
|
||||
for (size_t view = 0; view < objectPoints.size(); ++view)
|
||||
{
|
||||
std::vector<cv::Point2d> reprojected;
|
||||
cv::fisheye::projectPoints(objectPoints[view], reprojected,
|
||||
estimatedR[view], estimatedT[view],
|
||||
cameraMatrix, distortion);
|
||||
rms += cv::norm(cv::Mat(reprojected) - cv::Mat(imagePoints[view]),
|
||||
cv::NORM_L2SQR);
|
||||
}
|
||||
EXPECT_NEAR(std::sqrt(rms / (2 * baseObjectPoints.size())), 0.0, 1e-8);
|
||||
}
|
||||
|
||||
constexpr double normalObjectPointScale = 1.0;
|
||||
constexpr double smallObjectPointScale = 1e-7;
|
||||
constexpr double smallestNormalObjectPointScale =
|
||||
std::numeric_limits<double>::min();
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Fisheye, FisheyeExtrinsicRefinementScaleTest,
|
||||
::testing::Values(normalObjectPointScale,
|
||||
smallObjectPointScale,
|
||||
smallestNormalObjectPointScale));
|
||||
|
||||
TEST_F(fisheyeTest, CalibrationHandlesTranslatedObjectPoints)
|
||||
{
|
||||
const cv::Matx33d cameraMatrix(600.0, 0.0, 320.0,
|
||||
0.0, 610.0, 240.0,
|
||||
0.0, 0.0, 1.0);
|
||||
const cv::Vec4d distortion = cv::Vec4d::all(0);
|
||||
const cv::Vec3d trueR(0.15, -0.1, 0.08);
|
||||
const cv::Vec3d trueT(0.2, -0.15, 3.0);
|
||||
constexpr double objectPointOffsetMagnitude = 1e6;
|
||||
constexpr double reprojectionTolerance = 1e-7;
|
||||
const cv::Vec3d objectPointOffset(objectPointOffsetMagnitude,
|
||||
-2.0 * objectPointOffsetMagnitude,
|
||||
3.0 * objectPointOffsetMagnitude);
|
||||
const cv::Size testImageSize(640, 480);
|
||||
const int maxIterations = 1;
|
||||
const std::vector<cv::Point3d> baseObjectPoints = {
|
||||
{-0.4, -0.3, 0.0}, {0.0, -0.3, 0.1}, {0.4, -0.3, 0.0},
|
||||
{-0.4, 0.0, 0.1}, {0.0, 0.0, 0.0}, {0.4, 0.0, 0.1},
|
||||
{-0.4, 0.3, 0.0}, {0.0, 0.3, 0.1}, {0.4, 0.3, 0.0}};
|
||||
|
||||
cv::Matx33d rotationMatrix;
|
||||
cv::Rodrigues(trueR, rotationMatrix);
|
||||
const cv::Vec3d rotatedOffset = rotationMatrix * objectPointOffset;
|
||||
const cv::Vec3d shiftedTrueT = trueT - rotatedOffset;
|
||||
std::vector<cv::Point3d> objectPoints;
|
||||
for (const cv::Point3d& point : baseObjectPoints)
|
||||
{
|
||||
objectPoints.emplace_back(point + cv::Point3d(objectPointOffset));
|
||||
}
|
||||
|
||||
std::vector<cv::Point2d> imagePoints;
|
||||
cv::fisheye::projectPoints(objectPoints, imagePoints, trueR, shiftedTrueT,
|
||||
cameraMatrix, distortion);
|
||||
|
||||
cv::Mat estimatedK = cv::Mat(cameraMatrix);
|
||||
cv::Mat estimatedD = cv::Mat(distortion);
|
||||
std::vector<cv::Vec3d> estimatedR;
|
||||
std::vector<cv::Vec3d> estimatedT;
|
||||
const int flags = fixedIntrinsicCalibrationFlags(false);
|
||||
cv::fisheye::calibrate(
|
||||
std::vector<std::vector<cv::Point3d> >(1, objectPoints),
|
||||
std::vector<std::vector<cv::Point2d> >(1, imagePoints),
|
||||
testImageSize, estimatedK, estimatedD, estimatedR, estimatedT, flags,
|
||||
cv::TermCriteria(cv::TermCriteria::COUNT, maxIterations, 0));
|
||||
|
||||
std::vector<cv::Point2d> reprojected;
|
||||
cv::fisheye::projectPoints(objectPoints, reprojected, estimatedR[0],
|
||||
estimatedT[0], cameraMatrix, distortion);
|
||||
const double rms = cv::norm(cv::Mat(reprojected) - cv::Mat(imagePoints),
|
||||
cv::NORM_L2SQR);
|
||||
const double reprojectionRms =
|
||||
std::sqrt(rms / (2 * baseObjectPoints.size()));
|
||||
EXPECT_NEAR(reprojectionRms, 0.0, reprojectionTolerance);
|
||||
}
|
||||
|
||||
TEST_F(fisheyeTest, CalibrationRefinesNearCollinearView)
|
||||
{
|
||||
cv::Matx33d cameraMatrix;
|
||||
cv::Vec4d distortion;
|
||||
cv::Size testImageSize;
|
||||
std::vector<cv::Point3d> objectPoints;
|
||||
std::vector<cv::Point2d> imagePoints;
|
||||
createNearCollinearView(cameraMatrix, distortion, testImageSize,
|
||||
objectPoints, imagePoints);
|
||||
|
||||
cv::Mat estimatedK = cv::Mat(cameraMatrix);
|
||||
cv::Mat estimatedD = cv::Mat(distortion);
|
||||
std::vector<cv::Vec3d> estimatedR;
|
||||
std::vector<cv::Vec3d> estimatedT;
|
||||
const int flags = fixedIntrinsicCalibrationFlags(false);
|
||||
|
||||
const double rms = cv::fisheye::calibrate(
|
||||
std::vector<std::vector<cv::Point3d> >(1, objectPoints),
|
||||
std::vector<std::vector<cv::Point2d> >(1, imagePoints),
|
||||
testImageSize, estimatedK, estimatedD, estimatedR, estimatedT, flags,
|
||||
cv::TermCriteria(cv::TermCriteria::COUNT, 20, 0));
|
||||
|
||||
EXPECT_LT(rms, 1e-8);
|
||||
}
|
||||
|
||||
TEST_F(fisheyeTest, CalibrationCheckCondRejectsNearCollinearView)
|
||||
{
|
||||
cv::Matx33d cameraMatrix;
|
||||
cv::Vec4d distortion;
|
||||
cv::Size testImageSize;
|
||||
std::vector<cv::Point3d> objectPoints;
|
||||
std::vector<cv::Point2d> imagePoints;
|
||||
createNearCollinearView(cameraMatrix, distortion, testImageSize,
|
||||
objectPoints, imagePoints);
|
||||
|
||||
cv::Mat estimatedK = cv::Mat(cameraMatrix);
|
||||
cv::Mat estimatedD = cv::Mat(distortion);
|
||||
const int flags = fixedIntrinsicCalibrationFlags(true);
|
||||
|
||||
EXPECT_THROW(
|
||||
cv::fisheye::calibrate(
|
||||
std::vector<std::vector<cv::Point3d> >(1, objectPoints),
|
||||
std::vector<std::vector<cv::Point2d> >(1, imagePoints),
|
||||
testImageSize, estimatedK, estimatedD, cv::noArray(),
|
||||
cv::noArray(), flags,
|
||||
cv::TermCriteria(cv::TermCriteria::COUNT, 20, 0)),
|
||||
cv::Exception);
|
||||
}
|
||||
|
||||
TEST_F(fisheyeTest, Calibration)
|
||||
{
|
||||
const int n_images = 34;
|
||||
|
||||
@@ -2110,6 +2110,61 @@ TEST(Calib3d_SolvePnPRansac, inputShape)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Calib3d_SolvePnP, refine_row_vector)
|
||||
{
|
||||
// solvePnPRefineLM()/VVS() explicitly accept rvec/tvec as either
|
||||
// Size(1,3) (row vector) or Size(3,1) (column vector) per their
|
||||
// own precondition check, but historically only the column-vector
|
||||
// shape was exercised. Verify both orientations converge to the
|
||||
// same, correct result.
|
||||
Matx33d intrinsics(605.4, 0.0, 317.35,
|
||||
0.0, 601.2, 242.63,
|
||||
0.0, 0.0, 1.0);
|
||||
|
||||
double L = 0.1;
|
||||
vector<Point3d> p3d;
|
||||
p3d.push_back(Point3d(-L, -L, 0.0));
|
||||
p3d.push_back(Point3d(L, -L, 0.0));
|
||||
p3d.push_back(Point3d(L, L, 0.0));
|
||||
p3d.push_back(Point3d(-L, L, L/2));
|
||||
p3d.push_back(Point3d(0, 0, -L/2));
|
||||
|
||||
Mat rvec_ground_truth = (Mat_<double>(3,1) << 0.3, -0.2, 0.75);
|
||||
Mat tvec_ground_truth = (Mat_<double>(3,1) << 0.15, -0.2, 1.5);
|
||||
|
||||
vector<Point2d> p2d;
|
||||
projectPoints(p3d, rvec_ground_truth, tvec_ground_truth, intrinsics, noArray(), p2d);
|
||||
|
||||
for (int method = 0; method < 2; method++)
|
||||
{
|
||||
Mat rvec_col = (Mat_<double>(3,1) << 0.1, -0.1, 0.1);
|
||||
Mat tvec_col = (Mat_<double>(3,1) << 0.0, -0.5, 1.0);
|
||||
Mat rvec_row = rvec_col.reshape(1, 1).clone();
|
||||
Mat tvec_row = tvec_col.reshape(1, 1).clone();
|
||||
|
||||
if (method == 0)
|
||||
{
|
||||
solvePnPRefineLM(p3d, p2d, intrinsics, noArray(), rvec_col, tvec_col);
|
||||
solvePnPRefineLM(p3d, p2d, intrinsics, noArray(), rvec_row, tvec_row);
|
||||
}
|
||||
else
|
||||
{
|
||||
solvePnPRefineVVS(p3d, p2d, intrinsics, noArray(), rvec_col, tvec_col);
|
||||
solvePnPRefineVVS(p3d, p2d, intrinsics, noArray(), rvec_row, tvec_row);
|
||||
}
|
||||
|
||||
EXPECT_LE(cvtest::norm(rvec_ground_truth, rvec_col, NORM_INF), 1e-6);
|
||||
EXPECT_LE(cvtest::norm(tvec_ground_truth, tvec_col, NORM_INF), 1e-6);
|
||||
|
||||
// the row-vector call must converge to the same result as the
|
||||
// column-vector call, and must actually write back into rvec_row/
|
||||
// tvec_row (a shape mismatch during write-back previously left
|
||||
// these unmodified even after fixing the read-side OOB)
|
||||
EXPECT_LE(cvtest::norm(rvec_col, rvec_row.reshape(1, 3), NORM_INF), 1e-9);
|
||||
EXPECT_LE(cvtest::norm(tvec_col, tvec_row.reshape(1, 3), NORM_INF), 1e-9);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Calib3d_SolvePnP, inputShape)
|
||||
{
|
||||
//https://github.com/opencv/opencv/issues/14423
|
||||
@@ -2349,4 +2404,30 @@ TEST(AP3P, ctheta1p_nan_23607)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Calib3d_SolvePnP, regression_30402)
|
||||
{
|
||||
// A tag seen exactly head-on: the pose has a 180 degree rotation about X.
|
||||
const double L = 0.05;
|
||||
std::vector<Point3d> objectPoints = {
|
||||
Point3d(-L, L, 0), Point3d( L, L, 0), Point3d( L, -L, 0), Point3d(-L, -L, 0)
|
||||
};
|
||||
Matx33d intrinsics(800, 0, 320,
|
||||
0, 800, 240,
|
||||
0, 0, 1);
|
||||
Vec3d rvecGT(CV_PI, 0, 0), tvecGT(0, 0, 0.5);
|
||||
|
||||
std::vector<Point2d> imagePoints;
|
||||
projectPoints(objectPoints, rvecGT, tvecGT, intrinsics, noArray(), imagePoints);
|
||||
|
||||
Mat rvec, tvec;
|
||||
ASSERT_TRUE(solvePnP(objectPoints, imagePoints, intrinsics, noArray(), rvec, tvec,
|
||||
false, SOLVEPNP_IPPE_SQUARE));
|
||||
|
||||
Mat R, RGT;
|
||||
cv::Rodrigues(rvec, R);
|
||||
cv::Rodrigues(rvecGT, RGT);
|
||||
EXPECT_LE(cvtest::norm(R, RGT, NORM_INF), 1e-6);
|
||||
EXPECT_LE(cvtest::norm(tvec, Mat(tvecGT), NORM_INF), 1e-6);
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
||||
@@ -952,6 +952,73 @@ TEST(Calib3d_StereoSGBM, deterministic) {
|
||||
|
||||
}
|
||||
|
||||
TEST(Calib3d_StereoSGBM, regression_29761)
|
||||
{
|
||||
Mat leftImg(256, 256, CV_8UC1), rightImg(256, 256, CV_8UC1);
|
||||
randu(leftImg, Scalar(0), Scalar(255));
|
||||
randu(rightImg, Scalar(0), Scalar(255));
|
||||
|
||||
Ptr<StereoSGBM> sgbm = StereoSGBM::create( 0, 64, 5, 100, 200, 1, 31, 100, 0, 0, StereoSGBM::MODE_SGBM_3WAY);
|
||||
Mat leftDisp;
|
||||
sgbm->compute( leftImg, rightImg, leftDisp);
|
||||
EXPECT_EQ(countNonZero(leftDisp != -StereoMatcher::DISP_SCALE), 0);
|
||||
}
|
||||
|
||||
/* < cost type, x2 is past the last column (otherwise it is before the first one) > */
|
||||
typedef tuple < int, bool > ValidateDisparity_Params_t;
|
||||
|
||||
typedef testing::TestWithParam< ValidateDisparity_Params_t > Calib3d_ValidateDisparity;
|
||||
|
||||
TEST_P(Calib3d_ValidateDisparity, out_of_range_disparity)
|
||||
{
|
||||
const int costType = get<0>(GetParam());
|
||||
const bool pastEnd = get<1>(GetParam());
|
||||
|
||||
// The row is wide enough for validateDisparity to allocate its work buffer on the heap.
|
||||
const int cols = 160, numberOfDisparities = 16, disp12MaxDiff = 0;
|
||||
const int minDisparity = pastEnd ? 0 : 2;
|
||||
const short invalid = (short)((minDisparity - 1)*16);
|
||||
|
||||
struct Px { int x; short d; int cost; short expected; };
|
||||
std::vector<Px> pixels;
|
||||
if( pastEnd )
|
||||
{
|
||||
// disparity -2 at x = 159 gives x2 = 161 >= cols
|
||||
pixels.push_back({100, 80, 0, 80});
|
||||
pixels.push_back({159, -32, 0, -32});
|
||||
}
|
||||
else
|
||||
{
|
||||
// x = 154 and x = 155 both map to slot 152, 154 has the lower cost, so 155 fails the cross-check.
|
||||
// x = 159 gives x2 = -8, which is outside the buffer and used to overwrite the cost of slot 152.
|
||||
pixels.push_back({154, 32, 0, 32});
|
||||
pixels.push_back({155, 48, 10, invalid});
|
||||
pixels.push_back({159, 2672, 0, 2672});
|
||||
}
|
||||
|
||||
Mat1s disp(1, cols, invalid), expected(1, cols, invalid);
|
||||
Mat1i cost32(1, cols, 0);
|
||||
for( size_t i = 0; i < pixels.size(); i++ )
|
||||
{
|
||||
disp(0, pixels[i].x) = pixels[i].d;
|
||||
cost32(0, pixels[i].x) = pixels[i].cost;
|
||||
expected(0, pixels[i].x) = pixels[i].expected;
|
||||
}
|
||||
Mat cost;
|
||||
cost32.convertTo(cost, costType);
|
||||
|
||||
validateDisparity(disp, cost, minDisparity, numberOfDisparities, disp12MaxDiff);
|
||||
|
||||
EXPECT_EQ(0, cvtest::norm(disp, expected, NORM_INF));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/*nothing*/, Calib3d_ValidateDisparity,
|
||||
testing::Combine(
|
||||
testing::Values(CV_16S, CV_32S),
|
||||
testing::Bool()
|
||||
)
|
||||
);
|
||||
|
||||
TEST(Calib3d_StereoSGBM_HH4, regression)
|
||||
{
|
||||
String path = cvtest::TS::ptr()->get_data_path() + "cv/stereomatching/datasets/teddy/";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user