mirror of
https://github.com/opencv/opencv.git
synced 2026-07-22 20:03:03 +04:00
Compare commits
336 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b1cf550123 | |||
| 17bd9a1fa1 | |||
| 0321644bbd | |||
| 81e7988eb9 | |||
| 4985311d46 | |||
| 05348f3250 | |||
| 003609e565 | |||
| 9537a909f7 | |||
| 8c2dd5fb9a | |||
| 27545dcc86 | |||
| 724e04e979 | |||
| dfc94c58f0 | |||
| fac895d7ba | |||
| 04b40ff221 | |||
| a3d7811f24 | |||
| 755e0143fb | |||
| dfa48094dc | |||
| e585192eeb | |||
| 646924fce8 | |||
| c63aa7f085 | |||
| c54abde1bd | |||
| 95c1d2a887 | |||
| ebef84e9ea | |||
| b1a772d194 | |||
| f11f2bfb56 | |||
| 24f43e7ae9 | |||
| d94d469c86 | |||
| d20c9bde7e | |||
| 62414e3073 | |||
| 48c985e775 | |||
| 7358fffb0f | |||
| de5b6386e0 | |||
| 1de2d5c2b6 | |||
| ef53a9229f | |||
| 259c39a63a | |||
| 327b98eb13 | |||
| f977d10a19 | |||
| a0cf8c322d | |||
| 1e74f5850b | |||
| 9b76872708 | |||
| 4d587c341b | |||
| 846317ef37 | |||
| 7e62789edf | |||
| 852663f6d2 | |||
| a9b30984a3 | |||
| 2f83c3b689 | |||
| b25ad12f1a | |||
| d95e43a6a1 | |||
| 2cc14bd0fb | |||
| fdc8ed8d05 | |||
| 236c64a17d | |||
| f96569da1e | |||
| 91ff45fbde | |||
| 45aabc5d0d | |||
| f9bd83c854 | |||
| 86a51015b1 | |||
| 998406d20e | |||
| f7b4b750d8 | |||
| a4e2c56317 | |||
| 9c5d7716e2 | |||
| 46fd26e366 | |||
| c410d7a97d | |||
| 6fa63dcc0c | |||
| 96f25332ea | |||
| 3385d38648 | |||
| 1618c963e4 | |||
| 1e3be09b3b | |||
| 6e66a9222a | |||
| 9d1e8b1e1d | |||
| f605373a2b | |||
| 56b7622612 | |||
| 696a6ccd57 | |||
| 51b03b87e6 | |||
| aa7ba0bc1a | |||
| 07e4076585 | |||
| de1a459879 | |||
| 1aacb9bb15 | |||
| 9b4ecc96f6 | |||
| e3f4f874c5 | |||
| 6ace801418 | |||
| d31b93b513 | |||
| ac0fd6aa9a | |||
| 068f33cfdf | |||
| 4807cd8a6e | |||
| 35e824c287 | |||
| 1e0d290f2e | |||
| 0097a8d097 | |||
| 36cc43170d | |||
| 5578ad5e14 | |||
| d11f0a709d | |||
| 0a43b23275 | |||
| 7967683296 | |||
| 5b2c016834 | |||
| aaff125608 | |||
| 407adc7061 | |||
| d0e612dc36 | |||
| 7c23ec90a9 | |||
| 390957fec4 | |||
| 060a76dc3e | |||
| 6625810d2a | |||
| edc442afdb | |||
| 16b9514543 | |||
| 95c7f4a7f0 | |||
| ae6fabc6fe | |||
| 7eaadf616c | |||
| 8fed5fc5ae | |||
| f25951c412 | |||
| 1259a474ba | |||
| 3995deaf76 | |||
| 076587425e | |||
| da6aeaca46 | |||
| 8ee33ca551 | |||
| ea7f13922b | |||
| 38d0063c36 | |||
| df83459721 | |||
| 54a9e00970 | |||
| 9bda96d39e | |||
| 77a5c43d50 | |||
| f28e4b86fb | |||
| b675e6ab77 | |||
| d6306f8ccb | |||
| a9817e9127 | |||
| c08897cd10 | |||
| 384875f4fc | |||
| 9cfa84313c | |||
| fe625a558e | |||
| 9ef41f68fb | |||
| cfb36443fb | |||
| 9d3826c676 | |||
| 4300bb2e1f | |||
| 6edc438789 | |||
| 25cd7c7c50 | |||
| 732cb6c45c | |||
| 266a868ba9 | |||
| 8199967b31 | |||
| 9d61c18143 | |||
| 221bfa4c67 | |||
| 1a8b7f7513 | |||
| 992b47b991 | |||
| 739ff84732 | |||
| 2a177052de | |||
| f7c82baee9 | |||
| 2b34e0abdc | |||
| 633fedaa96 | |||
| 65134c793b | |||
| d5f34cf34c | |||
| cefa602601 | |||
| d773691848 | |||
| f40707dc68 | |||
| 2d8ce500fa | |||
| ddf1b04cce | |||
| ad5b3a4753 | |||
| 531ea5b3a2 | |||
| b468468e7e | |||
| cff0168f3a | |||
| d83901e665 | |||
| 1e1984a586 | |||
| 06dcc5a2c6 | |||
| 000f762fb9 | |||
| 3bc3eeb5da | |||
| 4e5699fa71 | |||
| a76274b549 | |||
| 803ff8ebb9 | |||
| b42152ffeb | |||
| 024b43ca06 | |||
| 9448fe3db4 | |||
| 3817f3a89b | |||
| 2062a7ca8f | |||
| 8334ee18e6 | |||
| cc2592f582 | |||
| 96d35f7c54 | |||
| 98c5fc6ae2 | |||
| fbde0c6c96 | |||
| 602e7c83e2 | |||
| eb9218a86b | |||
| 9f2dcc3f13 | |||
| bc210b292b | |||
| 2113af9c52 | |||
| 6f417b57c1 | |||
| 0acd06d13c | |||
| fd22e98298 | |||
| 167a12028d | |||
| 6af2faebd2 | |||
| fd16222613 | |||
| 1ba6cd8423 | |||
| 4788de784b | |||
| 926535469d | |||
| 5627a0cbdf | |||
| 9a9954a036 | |||
| 591708903b | |||
| f9d62fba7a | |||
| 9d039c206b | |||
| 4c3f9b2ef4 | |||
| 0e523618a1 | |||
| 3b26105f68 | |||
| 0f2f966a91 | |||
| d7d491d445 | |||
| 9b0d6862c4 | |||
| 890fcdf842 | |||
| 18dbac203f | |||
| 8d1f254dcc | |||
| 90df3af6cf | |||
| b699fe7a9d | |||
| b2ed5c3070 | |||
| 5b8c10f2f8 | |||
| 24983f62e2 | |||
| f2057ce1ab | |||
| 6797fd65a5 | |||
| 947e06a860 | |||
| 04d5ba266f | |||
| 90be83ae99 | |||
| 5e80bd3cc9 | |||
| db4b1e613c | |||
| 7d842f5bcf | |||
| 828304d587 | |||
| 9d584475f6 | |||
| bb60cb0bf9 | |||
| 55e1dfb778 | |||
| c2263db7bc | |||
| 7bbbda71df | |||
| 8e0baf257c | |||
| c8268e65fd | |||
| 3cf4375387 | |||
| c1adbe3189 | |||
| 7ee1816612 | |||
| 8f4f834ce6 | |||
| 2b84c97a78 | |||
| 3ddf84534b | |||
| bd26104088 | |||
| 5f80f43ff5 | |||
| b221143c0f | |||
| 995841624c | |||
| bbcd06f42f | |||
| 43940f7ffc | |||
| f4a79b0554 | |||
| 411fd2b761 | |||
| 61e30c15a9 | |||
| d332f33346 | |||
| 636db09d73 | |||
| 64c018507b | |||
| c34445a496 | |||
| ff60abb575 | |||
| 7d91dfe339 | |||
| 15af65d4cf | |||
| 81afeda537 | |||
| e10de25e86 | |||
| 746bd47ce5 | |||
| dcb4cabb26 | |||
| 59b4baee0c | |||
| bb3bbd192b | |||
| 1212aef03b | |||
| 814550d2a6 | |||
| fb68fe8930 | |||
| d3be58b6d7 | |||
| 8ecfbdb4ff | |||
| 63256a00ff | |||
| 450dc92452 | |||
| 3d2f4fa164 | |||
| 3d394943e6 | |||
| 3e25f32c9b | |||
| 81567a9d3e | |||
| 4a2adba8f4 | |||
| 84f78059d3 | |||
| 7499a15c92 | |||
| 5f4e55bc68 | |||
| c621384707 | |||
| c0162a64d1 | |||
| 1ae16beb06 | |||
| e53a4ce64d | |||
| 72655a9eea | |||
| 125f890dc3 | |||
| 101d50703c | |||
| 901ed5545f | |||
| 699b4b9fc5 | |||
| 1d7d18afba | |||
| b335fe67b0 | |||
| dde029f105 | |||
| 302c2354a3 | |||
| 158b13e0ba | |||
| b1dc7ed873 | |||
| 1bced43e96 | |||
| 8550f7e04d | |||
| 9f3e83baf6 | |||
| 17ab61a40d | |||
| 1b844f8413 | |||
| baa22fa808 | |||
| f78cebfc98 | |||
| d2a9ca13f1 | |||
| 71bae7c23f | |||
| d4f104f17f | |||
| fd44ba296d | |||
| b04d6a2d9b | |||
| a08eac452e | |||
| 7021ea6748 | |||
| 55aa1d4852 | |||
| 159534313e | |||
| 2f68c43e39 | |||
| e2483aa072 | |||
| c69f37343c | |||
| aec62a7fc5 | |||
| bf26050f7e | |||
| 402bce1a31 | |||
| 8868350888 | |||
| 1b64851fa8 | |||
| 2e143b8799 | |||
| 3930c9a492 | |||
| f0839d2703 | |||
| 405e820fe1 | |||
| 6598e9d506 | |||
| 8c2cf89845 | |||
| aeb8dfc52d | |||
| 0649a2fbdb | |||
| ec32061f5f | |||
| f2da1a0a7a | |||
| fda1e6f148 | |||
| 2a48730166 | |||
| 0bdbc745c4 | |||
| 6f70b0524a | |||
| b9b19185bc | |||
| 63ba9970bd | |||
| a9a6801c6d | |||
| 222af8e7e4 | |||
| ec8b7c933a | |||
| 76860933f0 | |||
| 19a936fc03 | |||
| be17fce657 | |||
| 9a1d7736f8 | |||
| 9f295b2c91 | |||
| 3a8154051f | |||
| f3f46096d6 | |||
| ace37df941 | |||
| ac9182f20d | |||
| 2cf1a13755 | |||
| 6465e393b6 | |||
| 6e6c0f31f7 | |||
| d0e3e638c3 |
Vendored
+22
-17
@@ -1778,30 +1778,30 @@ TegraCvtColor_Invoker(bgrx2hsvf, bgrx2hsv, src_data + static_cast<size_t>(range.
|
||||
: CV_HAL_ERROR_NOT_IMPLEMENTED \
|
||||
)
|
||||
|
||||
#define TEGRA_CVT2PYUVTOBGR(src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx) \
|
||||
#define TEGRA_CVT2PYUVTOBGR_EX(y_data, y_step, uv_data, uv_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx) \
|
||||
( \
|
||||
CAROTENE_NS::isSupportedConfiguration() ? \
|
||||
dcn == 3 ? \
|
||||
uIdx == 0 ? \
|
||||
(swapBlue ? \
|
||||
CAROTENE_NS::yuv420i2rgb(CAROTENE_NS::Size2D(dst_width, dst_height), \
|
||||
src_data, src_step, \
|
||||
src_data + src_step * dst_height, src_step, \
|
||||
y_data, y_step, \
|
||||
uv_data, uv_step, \
|
||||
dst_data, dst_step) : \
|
||||
CAROTENE_NS::yuv420i2bgr(CAROTENE_NS::Size2D(dst_width, dst_height), \
|
||||
src_data, src_step, \
|
||||
src_data + src_step * dst_height, src_step, \
|
||||
y_data, y_step, \
|
||||
uv_data, uv_step, \
|
||||
dst_data, dst_step)), \
|
||||
CV_HAL_ERROR_OK : \
|
||||
uIdx == 1 ? \
|
||||
(swapBlue ? \
|
||||
CAROTENE_NS::yuv420sp2rgb(CAROTENE_NS::Size2D(dst_width, dst_height), \
|
||||
src_data, src_step, \
|
||||
src_data + src_step * dst_height, src_step, \
|
||||
y_data, y_step, \
|
||||
uv_data, uv_step, \
|
||||
dst_data, dst_step) : \
|
||||
CAROTENE_NS::yuv420sp2bgr(CAROTENE_NS::Size2D(dst_width, dst_height), \
|
||||
src_data, src_step, \
|
||||
src_data + src_step * dst_height, src_step, \
|
||||
y_data, y_step, \
|
||||
uv_data, uv_step, \
|
||||
dst_data, dst_step)), \
|
||||
CV_HAL_ERROR_OK : \
|
||||
CV_HAL_ERROR_NOT_IMPLEMENTED : \
|
||||
@@ -1809,29 +1809,32 @@ TegraCvtColor_Invoker(bgrx2hsvf, bgrx2hsv, src_data + static_cast<size_t>(range.
|
||||
uIdx == 0 ? \
|
||||
(swapBlue ? \
|
||||
CAROTENE_NS::yuv420i2rgbx(CAROTENE_NS::Size2D(dst_width, dst_height), \
|
||||
src_data, src_step, \
|
||||
src_data + src_step * dst_height, src_step, \
|
||||
y_data, y_step, \
|
||||
uv_data, uv_step, \
|
||||
dst_data, dst_step) : \
|
||||
CAROTENE_NS::yuv420i2bgrx(CAROTENE_NS::Size2D(dst_width, dst_height), \
|
||||
src_data, src_step, \
|
||||
src_data + src_step * dst_height, src_step, \
|
||||
y_data, y_step, \
|
||||
uv_data, uv_step, \
|
||||
dst_data, dst_step)), \
|
||||
CV_HAL_ERROR_OK : \
|
||||
uIdx == 1 ? \
|
||||
(swapBlue ? \
|
||||
CAROTENE_NS::yuv420sp2rgbx(CAROTENE_NS::Size2D(dst_width, dst_height), \
|
||||
src_data, src_step, \
|
||||
src_data + src_step * dst_height, src_step, \
|
||||
y_data, y_step, \
|
||||
uv_data, uv_step, \
|
||||
dst_data, dst_step) : \
|
||||
CAROTENE_NS::yuv420sp2bgrx(CAROTENE_NS::Size2D(dst_width, dst_height), \
|
||||
src_data, src_step, \
|
||||
src_data + src_step * dst_height, src_step, \
|
||||
y_data, y_step, \
|
||||
uv_data, uv_step, \
|
||||
dst_data, dst_step)), \
|
||||
CV_HAL_ERROR_OK : \
|
||||
CV_HAL_ERROR_NOT_IMPLEMENTED : \
|
||||
CV_HAL_ERROR_NOT_IMPLEMENTED \
|
||||
: CV_HAL_ERROR_NOT_IMPLEMENTED \
|
||||
)
|
||||
#define TEGRA_CVT2PYUVTOBGR(src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx) \
|
||||
TEGRA_CVT2PYUVTOBGR_EX(src_data, src_step, src_data + src_step * dst_height, src_step, dst_data, dst_step, \
|
||||
dst_width, dst_height, dcn, swapBlue, uIdx);
|
||||
|
||||
#undef cv_hal_cvtBGRtoBGR
|
||||
#define cv_hal_cvtBGRtoBGR TEGRA_CVTBGRTOBGR
|
||||
@@ -1847,6 +1850,8 @@ TegraCvtColor_Invoker(bgrx2hsvf, bgrx2hsv, src_data + static_cast<size_t>(range.
|
||||
#define cv_hal_cvtBGRtoHSV TEGRA_CVTBGRTOHSV
|
||||
#undef cv_hal_cvtTwoPlaneYUVtoBGR
|
||||
#define cv_hal_cvtTwoPlaneYUVtoBGR TEGRA_CVT2PYUVTOBGR
|
||||
#undef cv_hal_cvtTwoPlaneYUVtoBGREx
|
||||
#define cv_hal_cvtTwoPlaneYUVtoBGREx TEGRA_CVT2PYUVTOBGR_EX
|
||||
|
||||
#endif // OPENCV_IMGPROC_HAL_INTERFACE_H
|
||||
|
||||
|
||||
Vendored
+5
-5
@@ -1,8 +1,8 @@
|
||||
# Binaries branch name: ffmpeg/3.4_20210302
|
||||
# Binaries were created for OpenCV: 2ab1f3f166fccc3a01497209cc01c5cea44ff201
|
||||
ocv_update(FFMPEG_BINARIES_COMMIT "e99214251d9f3cde7c48abd46b2259bddc9885b6")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN32 "fad5ada9be36120bba8966709e7953a8")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN64 "650e2272728491923e566f784f79cfef")
|
||||
# Binaries branch name: ffmpeg/3.4_20211005
|
||||
# Binaries were created for OpenCV: 95c1d2a8872b222f32bd88db9f1efcbd9f70a9cf
|
||||
ocv_update(FFMPEG_BINARIES_COMMIT "0bf6c0753d435d2c82c03c48db0c6e18ac79976c")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN32 "55c25bbc13e4a12d4339b70d3b76987f")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN64 "67caee9231c6843483b4de9815d6526e")
|
||||
ocv_update(FFMPEG_FILE_HASH_CMAKE "3b90f67f4b429e77d3da36698cef700c")
|
||||
|
||||
function(download_win_ffmpeg script_var)
|
||||
|
||||
+3
-4
@@ -3,10 +3,10 @@ project(${JPEG_LIBRARY} C)
|
||||
ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter -Wsign-compare -Wshorten-64-to-32 -Wimplicit-fallthrough)
|
||||
|
||||
set(VERSION_MAJOR 2)
|
||||
set(VERSION_MINOR 0)
|
||||
set(VERSION_REVISION 6)
|
||||
set(VERSION_MINOR 1)
|
||||
set(VERSION_REVISION 0)
|
||||
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION})
|
||||
set(LIBJPEG_TURBO_VERSION_NUMBER 2000006)
|
||||
set(LIBJPEG_TURBO_VERSION_NUMBER 2001000)
|
||||
|
||||
string(TIMESTAMP BUILD "opencv-${OPENCV_VERSION}-libjpeg-turbo")
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
@@ -46,7 +46,6 @@ if(UNIX)
|
||||
ocv_update(HAVE_UNSIGNED_SHORT 1)
|
||||
# undef INCOMPLETE_TYPES_BROKEN
|
||||
ocv_update(RIGHT_SHIFT_IS_UNSIGNED 0)
|
||||
ocv_update(__CHAR_UNSIGNED__ 0)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -91,7 +91,7 @@ best of our understanding.
|
||||
The Modified (3-clause) BSD License
|
||||
===================================
|
||||
|
||||
Copyright (C)2009-2020 D. R. Commander. All Rights Reserved.
|
||||
Copyright (C)2009-2021 D. R. Commander. All Rights Reserved.<br>
|
||||
Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
Vendored
+1
-14
@@ -128,7 +128,7 @@ with respect to this software, its quality, accuracy, merchantability, or
|
||||
fitness for a particular purpose. This software is provided "AS IS", and you,
|
||||
its user, assume the entire risk as to its quality and accuracy.
|
||||
|
||||
This software is copyright (C) 1991-2016, Thomas G. Lane, Guido Vollbeding.
|
||||
This software is copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding.
|
||||
All Rights Reserved except as specified below.
|
||||
|
||||
Permission is hereby granted to use, copy, modify, and distribute this
|
||||
@@ -159,19 +159,6 @@ commercial products, provided that all warranty or liability claims are
|
||||
assumed by the product vendor.
|
||||
|
||||
|
||||
The IJG distribution formerly included code to read and write GIF files.
|
||||
To avoid entanglement with the Unisys LZW patent (now expired), GIF reading
|
||||
support has been removed altogether, and the GIF writer has been simplified
|
||||
to produce "uncompressed GIFs". This technique does not use the LZW
|
||||
algorithm; the resulting GIF files are larger than usual, but are readable
|
||||
by all standard GIF decoders.
|
||||
|
||||
We are required to state that
|
||||
"The Graphics Interchange Format(c) is the Copyright property of
|
||||
CompuServe Incorporated. GIF(sm) is a Service Mark property of
|
||||
CompuServe Incorporated."
|
||||
|
||||
|
||||
REFERENCES
|
||||
==========
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -3,7 +3,7 @@ Background
|
||||
|
||||
libjpeg-turbo is a JPEG image codec that uses SIMD instructions to accelerate
|
||||
baseline JPEG compression and decompression on x86, x86-64, Arm, PowerPC, and
|
||||
MIPS systems, as well as progressive JPEG compression on x86 and x86-64
|
||||
MIPS systems, as well as progressive JPEG compression on x86, x86-64, and Arm
|
||||
systems. On such systems, libjpeg-turbo is generally 2-6x as fast as libjpeg,
|
||||
all else being equal. On other types of systems, libjpeg-turbo can still
|
||||
outperform libjpeg by a significant amount, by virtue of its highly-optimized
|
||||
|
||||
Vendored
-5
@@ -61,11 +61,6 @@
|
||||
unsigned. */
|
||||
#cmakedefine RIGHT_SHIFT_IS_UNSIGNED 1
|
||||
|
||||
/* Define to 1 if type `char' is unsigned and you are not using gcc. */
|
||||
#ifndef __CHAR_UNSIGNED__
|
||||
#cmakedefine __CHAR_UNSIGNED__ 1
|
||||
#endif
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
||||
|
||||
-1
@@ -18,7 +18,6 @@
|
||||
#define HAVE_UNSIGNED_SHORT
|
||||
#undef INCOMPLETE_TYPES_BROKEN
|
||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
||||
#undef __CHAR_UNSIGNED__
|
||||
|
||||
/* Define "boolean" as unsigned char, not int, per Windows custom */
|
||||
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
|
||||
|
||||
+9
-9
@@ -48,9 +48,9 @@ rgb_ycc_convert_internal(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
outptr2 = output_buf[2][output_row];
|
||||
output_row++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
r = GETJSAMPLE(inptr[RGB_RED]);
|
||||
g = GETJSAMPLE(inptr[RGB_GREEN]);
|
||||
b = GETJSAMPLE(inptr[RGB_BLUE]);
|
||||
r = inptr[RGB_RED];
|
||||
g = inptr[RGB_GREEN];
|
||||
b = inptr[RGB_BLUE];
|
||||
inptr += RGB_PIXELSIZE;
|
||||
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
|
||||
* must be too; we do not need an explicit range-limiting operation.
|
||||
@@ -100,9 +100,9 @@ rgb_gray_convert_internal(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
outptr = output_buf[0][output_row];
|
||||
output_row++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
r = GETJSAMPLE(inptr[RGB_RED]);
|
||||
g = GETJSAMPLE(inptr[RGB_GREEN]);
|
||||
b = GETJSAMPLE(inptr[RGB_BLUE]);
|
||||
r = inptr[RGB_RED];
|
||||
g = inptr[RGB_GREEN];
|
||||
b = inptr[RGB_BLUE];
|
||||
inptr += RGB_PIXELSIZE;
|
||||
/* Y */
|
||||
outptr[col] = (JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +
|
||||
@@ -135,9 +135,9 @@ rgb_rgb_convert_internal(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
outptr2 = output_buf[2][output_row];
|
||||
output_row++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
outptr0[col] = GETJSAMPLE(inptr[RGB_RED]);
|
||||
outptr1[col] = GETJSAMPLE(inptr[RGB_GREEN]);
|
||||
outptr2[col] = GETJSAMPLE(inptr[RGB_BLUE]);
|
||||
outptr0[col] = inptr[RGB_RED];
|
||||
outptr1[col] = inptr[RGB_GREEN];
|
||||
outptr2[col] = inptr[RGB_BLUE];
|
||||
inptr += RGB_PIXELSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+6
-6
@@ -392,11 +392,11 @@ cmyk_ycck_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
outptr3 = output_buf[3][output_row];
|
||||
output_row++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
r = MAXJSAMPLE - GETJSAMPLE(inptr[0]);
|
||||
g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);
|
||||
b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
|
||||
r = MAXJSAMPLE - inptr[0];
|
||||
g = MAXJSAMPLE - inptr[1];
|
||||
b = MAXJSAMPLE - inptr[2];
|
||||
/* K passes through as-is */
|
||||
outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */
|
||||
outptr3[col] = inptr[3];
|
||||
inptr += 4;
|
||||
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
|
||||
* must be too; we do not need an explicit range-limiting operation.
|
||||
@@ -438,7 +438,7 @@ grayscale_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
outptr = output_buf[0][output_row];
|
||||
output_row++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */
|
||||
outptr[col] = inptr[0];
|
||||
inptr += instride;
|
||||
}
|
||||
}
|
||||
@@ -497,7 +497,7 @@ null_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
|
||||
inptr = *input_buf;
|
||||
outptr = output_buf[ci][output_row];
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */
|
||||
outptr[col] = inptr[ci];
|
||||
inptr += nc;
|
||||
}
|
||||
}
|
||||
|
||||
+18
-19
@@ -381,19 +381,19 @@ convsamp(JSAMPARRAY sample_data, JDIMENSION start_col, DCTELEM *workspace)
|
||||
elemptr = sample_data[elemr] + start_col;
|
||||
|
||||
#if DCTSIZE == 8 /* unroll the inner loop */
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
|
||||
#else
|
||||
{
|
||||
register int elemc;
|
||||
for (elemc = DCTSIZE; elemc > 0; elemc--)
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -533,20 +533,19 @@ convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
|
||||
for (elemr = 0; elemr < DCTSIZE; elemr++) {
|
||||
elemptr = sample_data[elemr] + start_col;
|
||||
#if DCTSIZE == 8 /* unroll the inner loop */
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
|
||||
#else
|
||||
{
|
||||
register int elemc;
|
||||
for (elemc = DCTSIZE; elemc > 0; elemc--)
|
||||
*workspaceptr++ = (FAST_FLOAT)
|
||||
(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Vendored
+220
-180
@@ -4,8 +4,10 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009-2011, 2014-2016, 2018-2019, D. R. Commander.
|
||||
* Copyright (C) 2009-2011, 2014-2016, 2018-2021, D. R. Commander.
|
||||
* Copyright (C) 2015, Matthieu Darbois.
|
||||
* Copyright (C) 2018, Matthias Räncker.
|
||||
* Copyright (C) 2020, Arm Limited.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -42,15 +44,19 @@
|
||||
* flags (this defines __thumb__).
|
||||
*/
|
||||
|
||||
/* NOTE: Both GCC and Clang define __GNUC__ */
|
||||
#if defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))
|
||||
#if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) || \
|
||||
defined(_M_ARM64)
|
||||
#if !defined(__thumb__) || defined(__thumb2__)
|
||||
#define USE_CLZ_INTRINSIC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_CLZ_INTRINSIC
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x))
|
||||
#else
|
||||
#define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x))
|
||||
#endif
|
||||
#define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0)
|
||||
#else
|
||||
#include "jpeg_nbits_table.h"
|
||||
@@ -65,32 +71,43 @@
|
||||
* but must not be updated permanently until we complete the MCU.
|
||||
*/
|
||||
|
||||
#if defined(__x86_64__) && defined(__ILP32__)
|
||||
typedef unsigned long long bit_buf_type;
|
||||
#else
|
||||
typedef size_t bit_buf_type;
|
||||
#endif
|
||||
|
||||
/* NOTE: The more optimal Huffman encoding algorithm is only used by the
|
||||
* intrinsics implementation of the Arm Neon SIMD extensions, which is why we
|
||||
* retain the old Huffman encoder behavior when using the GAS implementation.
|
||||
*/
|
||||
#if defined(WITH_SIMD) && !(defined(__arm__) || defined(__aarch64__) || \
|
||||
defined(_M_ARM) || defined(_M_ARM64))
|
||||
typedef unsigned long long simd_bit_buf_type;
|
||||
#else
|
||||
typedef bit_buf_type simd_bit_buf_type;
|
||||
#endif
|
||||
|
||||
#if (defined(SIZEOF_SIZE_T) && SIZEOF_SIZE_T == 8) || defined(_WIN64) || \
|
||||
(defined(__x86_64__) && defined(__ILP32__))
|
||||
#define BIT_BUF_SIZE 64
|
||||
#elif (defined(SIZEOF_SIZE_T) && SIZEOF_SIZE_T == 4) || defined(_WIN32)
|
||||
#define BIT_BUF_SIZE 32
|
||||
#else
|
||||
#error Cannot determine word size
|
||||
#endif
|
||||
#define SIMD_BIT_BUF_SIZE (sizeof(simd_bit_buf_type) * 8)
|
||||
|
||||
typedef struct {
|
||||
size_t put_buffer; /* current bit-accumulation buffer */
|
||||
int put_bits; /* # of bits now in it */
|
||||
union {
|
||||
bit_buf_type c;
|
||||
simd_bit_buf_type simd;
|
||||
} put_buffer; /* current bit accumulation buffer */
|
||||
int free_bits; /* # of bits available in it */
|
||||
/* (Neon GAS: # of bits now in it) */
|
||||
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
|
||||
} savable_state;
|
||||
|
||||
/* This macro is to work around compilers with missing or broken
|
||||
* structure assignment. You'll need to fix this code if you have
|
||||
* such a compiler and you change MAX_COMPS_IN_SCAN.
|
||||
*/
|
||||
|
||||
#ifndef NO_STRUCT_ASSIGN
|
||||
#define ASSIGN_STATE(dest, src) ((dest) = (src))
|
||||
#else
|
||||
#if MAX_COMPS_IN_SCAN == 4
|
||||
#define ASSIGN_STATE(dest, src) \
|
||||
((dest).put_buffer = (src).put_buffer, \
|
||||
(dest).put_bits = (src).put_bits, \
|
||||
(dest).last_dc_val[0] = (src).last_dc_val[0], \
|
||||
(dest).last_dc_val[1] = (src).last_dc_val[1], \
|
||||
(dest).last_dc_val[2] = (src).last_dc_val[2], \
|
||||
(dest).last_dc_val[3] = (src).last_dc_val[3])
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_entropy_encoder pub; /* public fields */
|
||||
|
||||
@@ -123,6 +140,7 @@ typedef struct {
|
||||
size_t free_in_buffer; /* # of byte spaces remaining in buffer */
|
||||
savable_state cur; /* Current bit buffer & DC state */
|
||||
j_compress_ptr cinfo; /* dump_buffer needs access to this */
|
||||
int simd;
|
||||
} working_state;
|
||||
|
||||
|
||||
@@ -201,8 +219,17 @@ start_pass_huff(j_compress_ptr cinfo, boolean gather_statistics)
|
||||
}
|
||||
|
||||
/* Initialize bit buffer to empty */
|
||||
entropy->saved.put_buffer = 0;
|
||||
entropy->saved.put_bits = 0;
|
||||
if (entropy->simd) {
|
||||
entropy->saved.put_buffer.simd = 0;
|
||||
#if defined(__aarch64__) && !defined(NEON_INTRINSICS)
|
||||
entropy->saved.free_bits = 0;
|
||||
#else
|
||||
entropy->saved.free_bits = SIMD_BIT_BUF_SIZE;
|
||||
#endif
|
||||
} else {
|
||||
entropy->saved.put_buffer.c = 0;
|
||||
entropy->saved.free_bits = BIT_BUF_SIZE;
|
||||
}
|
||||
|
||||
/* Initialize restart stuff */
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
@@ -287,6 +314,7 @@ jpeg_make_c_derived_tbl(j_compress_ptr cinfo, boolean isDC, int tblno,
|
||||
* this lets us detect duplicate VAL entries here, and later
|
||||
* allows emit_bits to detect any attempt to emit such symbols.
|
||||
*/
|
||||
MEMZERO(dtbl->ehufco, sizeof(dtbl->ehufco));
|
||||
MEMZERO(dtbl->ehufsi, sizeof(dtbl->ehufsi));
|
||||
|
||||
/* This is also a convenient place to check for out-of-range
|
||||
@@ -334,94 +362,94 @@ dump_buffer(working_state *state)
|
||||
|
||||
/* Outputting bits to the file */
|
||||
|
||||
/* These macros perform the same task as the emit_bits() function in the
|
||||
* original libjpeg code. In addition to reducing overhead by explicitly
|
||||
* inlining the code, additional performance is achieved by taking into
|
||||
* account the size of the bit buffer and waiting until it is almost full
|
||||
* before emptying it. This mostly benefits 64-bit platforms, since 6
|
||||
* bytes can be stored in a 64-bit bit buffer before it has to be emptied.
|
||||
/* Output byte b and, speculatively, an additional 0 byte. 0xFF must be
|
||||
* encoded as 0xFF 0x00, so the output buffer pointer is advanced by 2 if the
|
||||
* byte is 0xFF. Otherwise, the output buffer pointer is advanced by 1, and
|
||||
* the speculative 0 byte will be overwritten by the next byte.
|
||||
*/
|
||||
|
||||
#define EMIT_BYTE() { \
|
||||
JOCTET c; \
|
||||
put_bits -= 8; \
|
||||
c = (JOCTET)GETJOCTET(put_buffer >> put_bits); \
|
||||
*buffer++ = c; \
|
||||
if (c == 0xFF) /* need to stuff a zero byte? */ \
|
||||
*buffer++ = 0; \
|
||||
#define EMIT_BYTE(b) { \
|
||||
buffer[0] = (JOCTET)(b); \
|
||||
buffer[1] = 0; \
|
||||
buffer -= -2 + ((JOCTET)(b) < 0xFF); \
|
||||
}
|
||||
|
||||
#define PUT_BITS(code, size) { \
|
||||
put_bits += size; \
|
||||
put_buffer = (put_buffer << size) | code; \
|
||||
}
|
||||
/* Output the entire bit buffer. If there are no 0xFF bytes in it, then write
|
||||
* directly to the output buffer. Otherwise, use the EMIT_BYTE() macro to
|
||||
* encode 0xFF as 0xFF 0x00.
|
||||
*/
|
||||
#if BIT_BUF_SIZE == 64
|
||||
|
||||
#if SIZEOF_SIZE_T != 8 && !defined(_WIN64)
|
||||
|
||||
#define CHECKBUF15() { \
|
||||
if (put_bits > 15) { \
|
||||
EMIT_BYTE() \
|
||||
EMIT_BYTE() \
|
||||
#define FLUSH() { \
|
||||
if (put_buffer & 0x8080808080808080 & ~(put_buffer + 0x0101010101010101)) { \
|
||||
EMIT_BYTE(put_buffer >> 56) \
|
||||
EMIT_BYTE(put_buffer >> 48) \
|
||||
EMIT_BYTE(put_buffer >> 40) \
|
||||
EMIT_BYTE(put_buffer >> 32) \
|
||||
EMIT_BYTE(put_buffer >> 24) \
|
||||
EMIT_BYTE(put_buffer >> 16) \
|
||||
EMIT_BYTE(put_buffer >> 8) \
|
||||
EMIT_BYTE(put_buffer ) \
|
||||
} else { \
|
||||
buffer[0] = (JOCTET)(put_buffer >> 56); \
|
||||
buffer[1] = (JOCTET)(put_buffer >> 48); \
|
||||
buffer[2] = (JOCTET)(put_buffer >> 40); \
|
||||
buffer[3] = (JOCTET)(put_buffer >> 32); \
|
||||
buffer[4] = (JOCTET)(put_buffer >> 24); \
|
||||
buffer[5] = (JOCTET)(put_buffer >> 16); \
|
||||
buffer[6] = (JOCTET)(put_buffer >> 8); \
|
||||
buffer[7] = (JOCTET)(put_buffer); \
|
||||
buffer += 8; \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define CHECKBUF31() { \
|
||||
if (put_bits > 31) { \
|
||||
EMIT_BYTE() \
|
||||
EMIT_BYTE() \
|
||||
EMIT_BYTE() \
|
||||
EMIT_BYTE() \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CHECKBUF47() { \
|
||||
if (put_bits > 47) { \
|
||||
EMIT_BYTE() \
|
||||
EMIT_BYTE() \
|
||||
EMIT_BYTE() \
|
||||
EMIT_BYTE() \
|
||||
EMIT_BYTE() \
|
||||
EMIT_BYTE() \
|
||||
} \
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) && !defined(SIZEOF_SIZE_T)
|
||||
#error Cannot determine word size
|
||||
#endif
|
||||
|
||||
#if SIZEOF_SIZE_T == 8 || defined(_WIN64)
|
||||
|
||||
#define EMIT_BITS(code, size) { \
|
||||
CHECKBUF47() \
|
||||
PUT_BITS(code, size) \
|
||||
}
|
||||
|
||||
#define EMIT_CODE(code, size) { \
|
||||
temp2 &= (((JLONG)1) << nbits) - 1; \
|
||||
CHECKBUF31() \
|
||||
PUT_BITS(code, size) \
|
||||
PUT_BITS(temp2, nbits) \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define EMIT_BITS(code, size) { \
|
||||
PUT_BITS(code, size) \
|
||||
CHECKBUF15() \
|
||||
}
|
||||
|
||||
#define EMIT_CODE(code, size) { \
|
||||
temp2 &= (((JLONG)1) << nbits) - 1; \
|
||||
PUT_BITS(code, size) \
|
||||
CHECKBUF15() \
|
||||
PUT_BITS(temp2, nbits) \
|
||||
CHECKBUF15() \
|
||||
#define FLUSH() { \
|
||||
if (put_buffer & 0x80808080 & ~(put_buffer + 0x01010101)) { \
|
||||
EMIT_BYTE(put_buffer >> 24) \
|
||||
EMIT_BYTE(put_buffer >> 16) \
|
||||
EMIT_BYTE(put_buffer >> 8) \
|
||||
EMIT_BYTE(put_buffer ) \
|
||||
} else { \
|
||||
buffer[0] = (JOCTET)(put_buffer >> 24); \
|
||||
buffer[1] = (JOCTET)(put_buffer >> 16); \
|
||||
buffer[2] = (JOCTET)(put_buffer >> 8); \
|
||||
buffer[3] = (JOCTET)(put_buffer); \
|
||||
buffer += 4; \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Fill the bit buffer to capacity with the leading bits from code, then output
|
||||
* the bit buffer and put the remaining bits from code into the bit buffer.
|
||||
*/
|
||||
#define PUT_AND_FLUSH(code, size) { \
|
||||
put_buffer = (put_buffer << (size + free_bits)) | (code >> -free_bits); \
|
||||
FLUSH() \
|
||||
free_bits += BIT_BUF_SIZE; \
|
||||
put_buffer = code; \
|
||||
}
|
||||
|
||||
/* Insert code into the bit buffer and output the bit buffer if needed.
|
||||
* NOTE: We can't flush with free_bits == 0, since the left shift in
|
||||
* PUT_AND_FLUSH() would have undefined behavior.
|
||||
*/
|
||||
#define PUT_BITS(code, size) { \
|
||||
free_bits -= size; \
|
||||
if (free_bits < 0) \
|
||||
PUT_AND_FLUSH(code, size) \
|
||||
else \
|
||||
put_buffer = (put_buffer << size) | code; \
|
||||
}
|
||||
|
||||
#define PUT_CODE(code, size) { \
|
||||
temp &= (((JLONG)1) << nbits) - 1; \
|
||||
temp |= code << nbits; \
|
||||
nbits += size; \
|
||||
PUT_BITS(temp, nbits) \
|
||||
}
|
||||
|
||||
|
||||
/* Although it is exceedingly rare, it is possible for a Huffman-encoded
|
||||
* coefficient block to be larger than the 128-byte unencoded block. For each
|
||||
@@ -444,6 +472,7 @@ dump_buffer(working_state *state)
|
||||
|
||||
#define STORE_BUFFER() { \
|
||||
if (localbuf) { \
|
||||
size_t bytes, bytestocopy; \
|
||||
bytes = buffer - _buffer; \
|
||||
buffer = _buffer; \
|
||||
while (bytes > 0) { \
|
||||
@@ -466,20 +495,46 @@ dump_buffer(working_state *state)
|
||||
LOCAL(boolean)
|
||||
flush_bits(working_state *state)
|
||||
{
|
||||
JOCTET _buffer[BUFSIZE], *buffer;
|
||||
size_t put_buffer; int put_bits;
|
||||
size_t bytes, bytestocopy; int localbuf = 0;
|
||||
JOCTET _buffer[BUFSIZE], *buffer, temp;
|
||||
simd_bit_buf_type put_buffer; int put_bits;
|
||||
int localbuf = 0;
|
||||
|
||||
if (state->simd) {
|
||||
#if defined(__aarch64__) && !defined(NEON_INTRINSICS)
|
||||
put_bits = state->cur.free_bits;
|
||||
#else
|
||||
put_bits = SIMD_BIT_BUF_SIZE - state->cur.free_bits;
|
||||
#endif
|
||||
put_buffer = state->cur.put_buffer.simd;
|
||||
} else {
|
||||
put_bits = BIT_BUF_SIZE - state->cur.free_bits;
|
||||
put_buffer = state->cur.put_buffer.c;
|
||||
}
|
||||
|
||||
put_buffer = state->cur.put_buffer;
|
||||
put_bits = state->cur.put_bits;
|
||||
LOAD_BUFFER()
|
||||
|
||||
/* fill any partial byte with ones */
|
||||
PUT_BITS(0x7F, 7)
|
||||
while (put_bits >= 8) EMIT_BYTE()
|
||||
while (put_bits >= 8) {
|
||||
put_bits -= 8;
|
||||
temp = (JOCTET)(put_buffer >> put_bits);
|
||||
EMIT_BYTE(temp)
|
||||
}
|
||||
if (put_bits) {
|
||||
/* fill partial byte with ones */
|
||||
temp = (JOCTET)((put_buffer << (8 - put_bits)) | (0xFF >> put_bits));
|
||||
EMIT_BYTE(temp)
|
||||
}
|
||||
|
||||
state->cur.put_buffer = 0; /* and reset bit-buffer to empty */
|
||||
state->cur.put_bits = 0;
|
||||
if (state->simd) { /* and reset bit buffer to empty */
|
||||
state->cur.put_buffer.simd = 0;
|
||||
#if defined(__aarch64__) && !defined(NEON_INTRINSICS)
|
||||
state->cur.free_bits = 0;
|
||||
#else
|
||||
state->cur.free_bits = SIMD_BIT_BUF_SIZE;
|
||||
#endif
|
||||
} else {
|
||||
state->cur.put_buffer.c = 0;
|
||||
state->cur.free_bits = BIT_BUF_SIZE;
|
||||
}
|
||||
STORE_BUFFER()
|
||||
|
||||
return TRUE;
|
||||
@@ -493,7 +548,7 @@ encode_one_block_simd(working_state *state, JCOEFPTR block, int last_dc_val,
|
||||
c_derived_tbl *dctbl, c_derived_tbl *actbl)
|
||||
{
|
||||
JOCTET _buffer[BUFSIZE], *buffer;
|
||||
size_t bytes, bytestocopy; int localbuf = 0;
|
||||
int localbuf = 0;
|
||||
|
||||
LOAD_BUFFER()
|
||||
|
||||
@@ -509,53 +564,41 @@ LOCAL(boolean)
|
||||
encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val,
|
||||
c_derived_tbl *dctbl, c_derived_tbl *actbl)
|
||||
{
|
||||
int temp, temp2, temp3;
|
||||
int nbits;
|
||||
int r, code, size;
|
||||
int temp, nbits, free_bits;
|
||||
bit_buf_type put_buffer;
|
||||
JOCTET _buffer[BUFSIZE], *buffer;
|
||||
size_t put_buffer; int put_bits;
|
||||
int code_0xf0 = actbl->ehufco[0xf0], size_0xf0 = actbl->ehufsi[0xf0];
|
||||
size_t bytes, bytestocopy; int localbuf = 0;
|
||||
int localbuf = 0;
|
||||
|
||||
put_buffer = state->cur.put_buffer;
|
||||
put_bits = state->cur.put_bits;
|
||||
free_bits = state->cur.free_bits;
|
||||
put_buffer = state->cur.put_buffer.c;
|
||||
LOAD_BUFFER()
|
||||
|
||||
/* Encode the DC coefficient difference per section F.1.2.1 */
|
||||
|
||||
temp = temp2 = block[0] - last_dc_val;
|
||||
temp = block[0] - last_dc_val;
|
||||
|
||||
/* This is a well-known technique for obtaining the absolute value without a
|
||||
* branch. It is derived from an assembly language technique presented in
|
||||
* "How to Optimize for the Pentium Processors", Copyright (c) 1996, 1997 by
|
||||
* Agner Fog.
|
||||
* Agner Fog. This code assumes we are on a two's complement machine.
|
||||
*/
|
||||
temp3 = temp >> (CHAR_BIT * sizeof(int) - 1);
|
||||
temp ^= temp3;
|
||||
temp -= temp3;
|
||||
|
||||
/* For a negative input, want temp2 = bitwise complement of abs(input) */
|
||||
/* This code assumes we are on a two's complement machine */
|
||||
temp2 += temp3;
|
||||
nbits = temp >> (CHAR_BIT * sizeof(int) - 1);
|
||||
temp += nbits;
|
||||
nbits ^= temp;
|
||||
|
||||
/* Find the number of bits needed for the magnitude of the coefficient */
|
||||
nbits = JPEG_NBITS(temp);
|
||||
nbits = JPEG_NBITS(nbits);
|
||||
|
||||
/* Emit the Huffman-coded symbol for the number of bits */
|
||||
code = dctbl->ehufco[nbits];
|
||||
size = dctbl->ehufsi[nbits];
|
||||
EMIT_BITS(code, size)
|
||||
|
||||
/* Mask off any extra bits in code */
|
||||
temp2 &= (((JLONG)1) << nbits) - 1;
|
||||
|
||||
/* Emit that number of bits of the value, if positive, */
|
||||
/* or the complement of its magnitude, if negative. */
|
||||
EMIT_BITS(temp2, nbits)
|
||||
/* Emit the Huffman-coded symbol for the number of bits.
|
||||
* Emit that number of bits of the value, if positive,
|
||||
* or the complement of its magnitude, if negative.
|
||||
*/
|
||||
PUT_CODE(dctbl->ehufco[nbits], dctbl->ehufsi[nbits])
|
||||
|
||||
/* Encode the AC coefficients per section F.1.2.2 */
|
||||
|
||||
r = 0; /* r = run length of zeros */
|
||||
{
|
||||
int r = 0; /* r = run length of zeros */
|
||||
|
||||
/* Manually unroll the k loop to eliminate the counter variable. This
|
||||
* improves performance greatly on systems with a limited number of
|
||||
@@ -563,51 +606,46 @@ encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val,
|
||||
*/
|
||||
#define kloop(jpeg_natural_order_of_k) { \
|
||||
if ((temp = block[jpeg_natural_order_of_k]) == 0) { \
|
||||
r++; \
|
||||
r += 16; \
|
||||
} else { \
|
||||
temp2 = temp; \
|
||||
/* Branch-less absolute value, bitwise complement, etc., same as above */ \
|
||||
temp3 = temp >> (CHAR_BIT * sizeof(int) - 1); \
|
||||
temp ^= temp3; \
|
||||
temp -= temp3; \
|
||||
temp2 += temp3; \
|
||||
nbits = JPEG_NBITS_NONZERO(temp); \
|
||||
nbits = temp >> (CHAR_BIT * sizeof(int) - 1); \
|
||||
temp += nbits; \
|
||||
nbits ^= temp; \
|
||||
nbits = JPEG_NBITS_NONZERO(nbits); \
|
||||
/* if run length > 15, must emit special run-length-16 codes (0xF0) */ \
|
||||
while (r > 15) { \
|
||||
EMIT_BITS(code_0xf0, size_0xf0) \
|
||||
r -= 16; \
|
||||
while (r >= 16 * 16) { \
|
||||
r -= 16 * 16; \
|
||||
PUT_BITS(actbl->ehufco[0xf0], actbl->ehufsi[0xf0]) \
|
||||
} \
|
||||
/* Emit Huffman symbol for run length / number of bits */ \
|
||||
temp3 = (r << 4) + nbits; \
|
||||
code = actbl->ehufco[temp3]; \
|
||||
size = actbl->ehufsi[temp3]; \
|
||||
EMIT_CODE(code, size) \
|
||||
r += nbits; \
|
||||
PUT_CODE(actbl->ehufco[r], actbl->ehufsi[r]) \
|
||||
r = 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* One iteration for each value in jpeg_natural_order[] */
|
||||
kloop(1); kloop(8); kloop(16); kloop(9); kloop(2); kloop(3);
|
||||
kloop(10); kloop(17); kloop(24); kloop(32); kloop(25); kloop(18);
|
||||
kloop(11); kloop(4); kloop(5); kloop(12); kloop(19); kloop(26);
|
||||
kloop(33); kloop(40); kloop(48); kloop(41); kloop(34); kloop(27);
|
||||
kloop(20); kloop(13); kloop(6); kloop(7); kloop(14); kloop(21);
|
||||
kloop(28); kloop(35); kloop(42); kloop(49); kloop(56); kloop(57);
|
||||
kloop(50); kloop(43); kloop(36); kloop(29); kloop(22); kloop(15);
|
||||
kloop(23); kloop(30); kloop(37); kloop(44); kloop(51); kloop(58);
|
||||
kloop(59); kloop(52); kloop(45); kloop(38); kloop(31); kloop(39);
|
||||
kloop(46); kloop(53); kloop(60); kloop(61); kloop(54); kloop(47);
|
||||
kloop(55); kloop(62); kloop(63);
|
||||
/* One iteration for each value in jpeg_natural_order[] */
|
||||
kloop(1); kloop(8); kloop(16); kloop(9); kloop(2); kloop(3);
|
||||
kloop(10); kloop(17); kloop(24); kloop(32); kloop(25); kloop(18);
|
||||
kloop(11); kloop(4); kloop(5); kloop(12); kloop(19); kloop(26);
|
||||
kloop(33); kloop(40); kloop(48); kloop(41); kloop(34); kloop(27);
|
||||
kloop(20); kloop(13); kloop(6); kloop(7); kloop(14); kloop(21);
|
||||
kloop(28); kloop(35); kloop(42); kloop(49); kloop(56); kloop(57);
|
||||
kloop(50); kloop(43); kloop(36); kloop(29); kloop(22); kloop(15);
|
||||
kloop(23); kloop(30); kloop(37); kloop(44); kloop(51); kloop(58);
|
||||
kloop(59); kloop(52); kloop(45); kloop(38); kloop(31); kloop(39);
|
||||
kloop(46); kloop(53); kloop(60); kloop(61); kloop(54); kloop(47);
|
||||
kloop(55); kloop(62); kloop(63);
|
||||
|
||||
/* If the last coef(s) were zero, emit an end-of-block code */
|
||||
if (r > 0) {
|
||||
code = actbl->ehufco[0];
|
||||
size = actbl->ehufsi[0];
|
||||
EMIT_BITS(code, size)
|
||||
/* If the last coef(s) were zero, emit an end-of-block code */
|
||||
if (r > 0) {
|
||||
PUT_BITS(actbl->ehufco[0], actbl->ehufsi[0])
|
||||
}
|
||||
}
|
||||
|
||||
state->cur.put_buffer = put_buffer;
|
||||
state->cur.put_bits = put_bits;
|
||||
state->cur.put_buffer.c = put_buffer;
|
||||
state->cur.free_bits = free_bits;
|
||||
STORE_BUFFER()
|
||||
|
||||
return TRUE;
|
||||
@@ -654,8 +692,9 @@ encode_mcu_huff(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
/* Load up working state */
|
||||
state.next_output_byte = cinfo->dest->next_output_byte;
|
||||
state.free_in_buffer = cinfo->dest->free_in_buffer;
|
||||
ASSIGN_STATE(state.cur, entropy->saved);
|
||||
state.cur = entropy->saved;
|
||||
state.cinfo = cinfo;
|
||||
state.simd = entropy->simd;
|
||||
|
||||
/* Emit restart marker if needed */
|
||||
if (cinfo->restart_interval) {
|
||||
@@ -694,7 +733,7 @@ encode_mcu_huff(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
/* Completed MCU, so update state */
|
||||
cinfo->dest->next_output_byte = state.next_output_byte;
|
||||
cinfo->dest->free_in_buffer = state.free_in_buffer;
|
||||
ASSIGN_STATE(entropy->saved, state.cur);
|
||||
entropy->saved = state.cur;
|
||||
|
||||
/* Update restart-interval state too */
|
||||
if (cinfo->restart_interval) {
|
||||
@@ -723,8 +762,9 @@ finish_pass_huff(j_compress_ptr cinfo)
|
||||
/* Load up working state ... flush_bits needs it */
|
||||
state.next_output_byte = cinfo->dest->next_output_byte;
|
||||
state.free_in_buffer = cinfo->dest->free_in_buffer;
|
||||
ASSIGN_STATE(state.cur, entropy->saved);
|
||||
state.cur = entropy->saved;
|
||||
state.cinfo = cinfo;
|
||||
state.simd = entropy->simd;
|
||||
|
||||
/* Flush out the last data */
|
||||
if (!flush_bits(&state))
|
||||
@@ -733,7 +773,7 @@ finish_pass_huff(j_compress_ptr cinfo)
|
||||
/* Update state */
|
||||
cinfo->dest->next_output_byte = state.next_output_byte;
|
||||
cinfo->dest->free_in_buffer = state.free_in_buffer;
|
||||
ASSIGN_STATE(entropy->saved, state.cur);
|
||||
entropy->saved = state.cur;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vendored
+16
-9
@@ -4,8 +4,9 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1995-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2011, 2015, 2018, D. R. Commander.
|
||||
* Copyright (C) 2011, 2015, 2018, 2021, D. R. Commander.
|
||||
* Copyright (C) 2016, 2018, Matthieu Darbois.
|
||||
* Copyright (C) 2020, Arm Limited.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -51,15 +52,19 @@
|
||||
* flags (this defines __thumb__).
|
||||
*/
|
||||
|
||||
/* NOTE: Both GCC and Clang define __GNUC__ */
|
||||
#if defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))
|
||||
#if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) || \
|
||||
defined(_M_ARM64)
|
||||
#if !defined(__thumb__) || defined(__thumb2__)
|
||||
#define USE_CLZ_INTRINSIC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_CLZ_INTRINSIC
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x))
|
||||
#else
|
||||
#define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x))
|
||||
#endif
|
||||
#define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0)
|
||||
#else
|
||||
#include "jpeg_nbits_table.h"
|
||||
@@ -169,24 +174,26 @@ INLINE
|
||||
METHODDEF(int)
|
||||
count_zeroes(size_t *x)
|
||||
{
|
||||
int result;
|
||||
#if defined(HAVE_BUILTIN_CTZL)
|
||||
int result;
|
||||
result = __builtin_ctzl(*x);
|
||||
*x >>= result;
|
||||
#elif defined(HAVE_BITSCANFORWARD64)
|
||||
unsigned long result;
|
||||
_BitScanForward64(&result, *x);
|
||||
*x >>= result;
|
||||
#elif defined(HAVE_BITSCANFORWARD)
|
||||
unsigned long result;
|
||||
_BitScanForward(&result, *x);
|
||||
*x >>= result;
|
||||
#else
|
||||
result = 0;
|
||||
int result = 0;
|
||||
while ((*x & 1) == 0) {
|
||||
++result;
|
||||
*x >>= 1;
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
return (int)result;
|
||||
}
|
||||
|
||||
|
||||
@@ -860,7 +867,7 @@ encode_mcu_AC_refine_prepare(const JCOEF *block,
|
||||
|
||||
#define ENCODE_COEFS_AC_REFINE(label) { \
|
||||
while (zerobits) { \
|
||||
int idx = count_zeroes(&zerobits); \
|
||||
idx = count_zeroes(&zerobits); \
|
||||
r += idx; \
|
||||
cabsvalue += idx; \
|
||||
signbits >>= idx; \
|
||||
@@ -917,7 +924,7 @@ METHODDEF(boolean)
|
||||
encode_mcu_AC_refine(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
phuff_entropy_ptr entropy = (phuff_entropy_ptr)cinfo->entropy;
|
||||
register int temp, r;
|
||||
register int temp, r, idx;
|
||||
char *BR_buffer;
|
||||
unsigned int BR;
|
||||
int Sl = cinfo->Se - cinfo->Ss + 1;
|
||||
@@ -968,7 +975,7 @@ encode_mcu_AC_refine(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
|
||||
if (zerobits) {
|
||||
int diff = ((absvalues + DCTSIZE2 / 2) - cabsvalue);
|
||||
int idx = count_zeroes(&zerobits);
|
||||
idx = count_zeroes(&zerobits);
|
||||
signbits >>= idx;
|
||||
idx += diff;
|
||||
r += idx;
|
||||
|
||||
+23
-40
@@ -6,7 +6,7 @@
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2014, MIPS Technologies, Inc., California.
|
||||
* Copyright (C) 2015, D. R. Commander.
|
||||
* Copyright (C) 2015, 2019, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -103,7 +103,7 @@ expand_right_edge(JSAMPARRAY image_data, int num_rows, JDIMENSION input_cols,
|
||||
if (numcols > 0) {
|
||||
for (row = 0; row < num_rows; row++) {
|
||||
ptr = image_data[row] + input_cols;
|
||||
pixval = ptr[-1]; /* don't need GETJSAMPLE() here */
|
||||
pixval = ptr[-1];
|
||||
for (count = numcols; count > 0; count--)
|
||||
*ptr++ = pixval;
|
||||
}
|
||||
@@ -174,7 +174,7 @@ int_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
for (v = 0; v < v_expand; v++) {
|
||||
inptr = input_data[inrow + v] + outcol_h;
|
||||
for (h = 0; h < h_expand; h++) {
|
||||
outvalue += (JLONG)GETJSAMPLE(*inptr++);
|
||||
outvalue += (JLONG)(*inptr++);
|
||||
}
|
||||
}
|
||||
*outptr++ = (JSAMPLE)((outvalue + numpix2) / numpix);
|
||||
@@ -237,8 +237,7 @@ h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
inptr = input_data[outrow];
|
||||
bias = 0; /* bias = 0,1,0,1,... for successive samples */
|
||||
for (outcol = 0; outcol < output_cols; outcol++) {
|
||||
*outptr++ =
|
||||
(JSAMPLE)((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1]) + bias) >> 1);
|
||||
*outptr++ = (JSAMPLE)((inptr[0] + inptr[1] + bias) >> 1);
|
||||
bias ^= 1; /* 0=>1, 1=>0 */
|
||||
inptr += 2;
|
||||
}
|
||||
@@ -277,8 +276,7 @@ h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
bias = 1; /* bias = 1,2,1,2,... for successive samples */
|
||||
for (outcol = 0; outcol < output_cols; outcol++) {
|
||||
*outptr++ =
|
||||
(JSAMPLE)((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
|
||||
GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]) + bias) >> 2);
|
||||
(JSAMPLE)((inptr0[0] + inptr0[1] + inptr1[0] + inptr1[1] + bias) >> 2);
|
||||
bias ^= 3; /* 1=>2, 2=>1 */
|
||||
inptr0 += 2; inptr1 += 2;
|
||||
}
|
||||
@@ -337,33 +335,25 @@ h2v2_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
below_ptr = input_data[inrow + 2];
|
||||
|
||||
/* Special case for first column: pretend column -1 is same as column 0 */
|
||||
membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
|
||||
GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
|
||||
neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
|
||||
GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
|
||||
GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) +
|
||||
GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]);
|
||||
membersum = inptr0[0] + inptr0[1] + inptr1[0] + inptr1[1];
|
||||
neighsum = above_ptr[0] + above_ptr[1] + below_ptr[0] + below_ptr[1] +
|
||||
inptr0[0] + inptr0[2] + inptr1[0] + inptr1[2];
|
||||
neighsum += neighsum;
|
||||
neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) +
|
||||
GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]);
|
||||
neighsum += above_ptr[0] + above_ptr[2] + below_ptr[0] + below_ptr[2];
|
||||
membersum = membersum * memberscale + neighsum * neighscale;
|
||||
*outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
|
||||
inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
|
||||
|
||||
for (colctr = output_cols - 2; colctr > 0; colctr--) {
|
||||
/* sum of pixels directly mapped to this output element */
|
||||
membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
|
||||
GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
|
||||
membersum = inptr0[0] + inptr0[1] + inptr1[0] + inptr1[1];
|
||||
/* sum of edge-neighbor pixels */
|
||||
neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
|
||||
GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
|
||||
GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) +
|
||||
GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]);
|
||||
neighsum = above_ptr[0] + above_ptr[1] + below_ptr[0] + below_ptr[1] +
|
||||
inptr0[-1] + inptr0[2] + inptr1[-1] + inptr1[2];
|
||||
/* The edge-neighbors count twice as much as corner-neighbors */
|
||||
neighsum += neighsum;
|
||||
/* Add in the corner-neighbors */
|
||||
neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) +
|
||||
GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]);
|
||||
neighsum += above_ptr[-1] + above_ptr[2] + below_ptr[-1] + below_ptr[2];
|
||||
/* form final output scaled up by 2^16 */
|
||||
membersum = membersum * memberscale + neighsum * neighscale;
|
||||
/* round, descale and output it */
|
||||
@@ -372,15 +362,11 @@ h2v2_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
}
|
||||
|
||||
/* Special case for last column */
|
||||
membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
|
||||
GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
|
||||
neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
|
||||
GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
|
||||
GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) +
|
||||
GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]);
|
||||
membersum = inptr0[0] + inptr0[1] + inptr1[0] + inptr1[1];
|
||||
neighsum = above_ptr[0] + above_ptr[1] + below_ptr[0] + below_ptr[1] +
|
||||
inptr0[-1] + inptr0[1] + inptr1[-1] + inptr1[1];
|
||||
neighsum += neighsum;
|
||||
neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) +
|
||||
GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]);
|
||||
neighsum += above_ptr[-1] + above_ptr[1] + below_ptr[-1] + below_ptr[1];
|
||||
membersum = membersum * memberscale + neighsum * neighscale;
|
||||
*outptr = (JSAMPLE)((membersum + 32768) >> 16);
|
||||
|
||||
@@ -429,21 +415,18 @@ fullsize_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
below_ptr = input_data[outrow + 1];
|
||||
|
||||
/* Special case for first column */
|
||||
colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) +
|
||||
GETJSAMPLE(*inptr);
|
||||
membersum = GETJSAMPLE(*inptr++);
|
||||
nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
|
||||
GETJSAMPLE(*inptr);
|
||||
colsum = (*above_ptr++) + (*below_ptr++) + inptr[0];
|
||||
membersum = *inptr++;
|
||||
nextcolsum = above_ptr[0] + below_ptr[0] + inptr[0];
|
||||
neighsum = colsum + (colsum - membersum) + nextcolsum;
|
||||
membersum = membersum * memberscale + neighsum * neighscale;
|
||||
*outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
|
||||
lastcolsum = colsum; colsum = nextcolsum;
|
||||
|
||||
for (colctr = output_cols - 2; colctr > 0; colctr--) {
|
||||
membersum = GETJSAMPLE(*inptr++);
|
||||
membersum = *inptr++;
|
||||
above_ptr++; below_ptr++;
|
||||
nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
|
||||
GETJSAMPLE(*inptr);
|
||||
nextcolsum = above_ptr[0] + below_ptr[0] + inptr[0];
|
||||
neighsum = lastcolsum + (colsum - membersum) + nextcolsum;
|
||||
membersum = membersum * memberscale + neighsum * neighscale;
|
||||
*outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
|
||||
@@ -451,7 +434,7 @@ fullsize_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
}
|
||||
|
||||
/* Special case for last column */
|
||||
membersum = GETJSAMPLE(*inptr);
|
||||
membersum = *inptr;
|
||||
neighsum = lastcolsum + (colsum - membersum) + colsum;
|
||||
membersum = membersum * memberscale + neighsum * neighscale;
|
||||
*outptr = (JSAMPLE)((membersum + 32768) >> 16);
|
||||
|
||||
+9
-1
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010, 2015-2018, 2020, D. R. Commander.
|
||||
* Copyright (C) 2010, 2015-2020, D. R. Commander.
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
@@ -319,6 +319,8 @@ read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
|
||||
{
|
||||
JDIMENSION n;
|
||||
my_master_ptr master = (my_master_ptr)cinfo->master;
|
||||
JSAMPLE dummy_sample[1] = { 0 };
|
||||
JSAMPROW dummy_row = dummy_sample;
|
||||
JSAMPARRAY scanlines = NULL;
|
||||
void (*color_convert) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf,
|
||||
@@ -329,6 +331,10 @@ read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
|
||||
if (cinfo->cconvert && cinfo->cconvert->color_convert) {
|
||||
color_convert = cinfo->cconvert->color_convert;
|
||||
cinfo->cconvert->color_convert = noop_convert;
|
||||
/* This just prevents UBSan from complaining about adding 0 to a NULL
|
||||
* pointer. The pointer isn't actually used.
|
||||
*/
|
||||
scanlines = &dummy_row;
|
||||
}
|
||||
|
||||
if (cinfo->cquantize && cinfo->cquantize->color_quantize) {
|
||||
@@ -532,6 +538,8 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
|
||||
* decoded coefficients. This is ~5% faster for large subsets, but
|
||||
* it's tough to tell a difference for smaller images.
|
||||
*/
|
||||
if (!cinfo->entropy->insufficient_data)
|
||||
cinfo->master->last_good_iMCU_row = cinfo->input_iMCU_row;
|
||||
(*cinfo->entropy->decode_mcu) (cinfo, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+12
-3
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Developed 1997-2015 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2015-2018, D. R. Commander.
|
||||
* Copyright (C) 2015-2020, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -80,7 +80,7 @@ get_byte(j_decompress_ptr cinfo)
|
||||
if (!(*src->fill_input_buffer) (cinfo))
|
||||
ERREXIT(cinfo, JERR_CANT_SUSPEND);
|
||||
src->bytes_in_buffer--;
|
||||
return GETJOCTET(*src->next_input_byte++);
|
||||
return *src->next_input_byte++;
|
||||
}
|
||||
|
||||
|
||||
@@ -665,8 +665,16 @@ bad:
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
int coefi, cindex = cinfo->cur_comp_info[ci]->component_index;
|
||||
int *coef_bit_ptr = &cinfo->coef_bits[cindex][0];
|
||||
int *prev_coef_bit_ptr =
|
||||
&cinfo->coef_bits[cindex + cinfo->num_components][0];
|
||||
if (cinfo->Ss && coef_bit_ptr[0] < 0) /* AC without prior DC scan */
|
||||
WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0);
|
||||
for (coefi = MIN(cinfo->Ss, 1); coefi <= MAX(cinfo->Se, 9); coefi++) {
|
||||
if (cinfo->input_scan_number > 1)
|
||||
prev_coef_bit_ptr[coefi] = coef_bit_ptr[coefi];
|
||||
else
|
||||
prev_coef_bit_ptr[coefi] = 0;
|
||||
}
|
||||
for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) {
|
||||
int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi];
|
||||
if (cinfo->Ah != expected)
|
||||
@@ -727,6 +735,7 @@ bad:
|
||||
entropy->c = 0;
|
||||
entropy->a = 0;
|
||||
entropy->ct = -16; /* force reading 2 initial bytes to fill C */
|
||||
entropy->pub.insufficient_data = FALSE;
|
||||
|
||||
/* Initialize restart counter */
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
@@ -763,7 +772,7 @@ jinit_arith_decoder(j_decompress_ptr cinfo)
|
||||
int *coef_bit_ptr, ci;
|
||||
cinfo->coef_bits = (int (*)[DCTSIZE2])
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
cinfo->num_components * DCTSIZE2 *
|
||||
cinfo->num_components * 2 * DCTSIZE2 *
|
||||
sizeof(int));
|
||||
coef_bit_ptr = &cinfo->coef_bits[0][0];
|
||||
for (ci = 0; ci < cinfo->num_components; ci++)
|
||||
|
||||
+237
-53
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 1994-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2010, 2015-2016, D. R. Commander.
|
||||
* Copyright (C) 2010, 2015-2016, 2019-2020, D. R. Commander.
|
||||
* Copyright (C) 2015, 2020, Google, Inc.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
@@ -102,6 +102,8 @@ decompress_onepass(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
/* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */
|
||||
jzero_far((void *)coef->MCU_buffer[0],
|
||||
(size_t)(cinfo->blocks_in_MCU * sizeof(JBLOCK)));
|
||||
if (!cinfo->entropy->insufficient_data)
|
||||
cinfo->master->last_good_iMCU_row = cinfo->input_iMCU_row;
|
||||
if (!(*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
|
||||
/* Suspension forced; update state counters and exit */
|
||||
coef->MCU_vert_offset = yoffset;
|
||||
@@ -227,6 +229,8 @@ consume_data(j_decompress_ptr cinfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cinfo->entropy->insufficient_data)
|
||||
cinfo->master->last_good_iMCU_row = cinfo->input_iMCU_row;
|
||||
/* Try to fetch the MCU. */
|
||||
if (!(*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
|
||||
/* Suspension forced; update state counters and exit */
|
||||
@@ -326,19 +330,22 @@ decompress_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
#ifdef BLOCK_SMOOTHING_SUPPORTED
|
||||
|
||||
/*
|
||||
* This code applies interblock smoothing as described by section K.8
|
||||
* of the JPEG standard: the first 5 AC coefficients are estimated from
|
||||
* the DC values of a DCT block and its 8 neighboring blocks.
|
||||
* This code applies interblock smoothing; the first 9 AC coefficients are
|
||||
* estimated from the DC values of a DCT block and its 24 neighboring blocks.
|
||||
* We apply smoothing only for progressive JPEG decoding, and only if
|
||||
* the coefficients it can estimate are not yet known to full precision.
|
||||
*/
|
||||
|
||||
/* Natural-order array positions of the first 5 zigzag-order coefficients */
|
||||
/* Natural-order array positions of the first 9 zigzag-order coefficients */
|
||||
#define Q01_POS 1
|
||||
#define Q10_POS 8
|
||||
#define Q20_POS 16
|
||||
#define Q11_POS 9
|
||||
#define Q02_POS 2
|
||||
#define Q03_POS 3
|
||||
#define Q12_POS 10
|
||||
#define Q21_POS 17
|
||||
#define Q30_POS 24
|
||||
|
||||
/*
|
||||
* Determine whether block smoothing is applicable and safe.
|
||||
@@ -356,8 +363,8 @@ smoothing_ok(j_decompress_ptr cinfo)
|
||||
int ci, coefi;
|
||||
jpeg_component_info *compptr;
|
||||
JQUANT_TBL *qtable;
|
||||
int *coef_bits;
|
||||
int *coef_bits_latch;
|
||||
int *coef_bits, *prev_coef_bits;
|
||||
int *coef_bits_latch, *prev_coef_bits_latch;
|
||||
|
||||
if (!cinfo->progressive_mode || cinfo->coef_bits == NULL)
|
||||
return FALSE;
|
||||
@@ -366,34 +373,47 @@ smoothing_ok(j_decompress_ptr cinfo)
|
||||
if (coef->coef_bits_latch == NULL)
|
||||
coef->coef_bits_latch = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
cinfo->num_components *
|
||||
cinfo->num_components * 2 *
|
||||
(SAVED_COEFS * sizeof(int)));
|
||||
coef_bits_latch = coef->coef_bits_latch;
|
||||
prev_coef_bits_latch =
|
||||
&coef->coef_bits_latch[cinfo->num_components * SAVED_COEFS];
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* All components' quantization values must already be latched. */
|
||||
if ((qtable = compptr->quant_table) == NULL)
|
||||
return FALSE;
|
||||
/* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */
|
||||
/* Verify DC & first 9 AC quantizers are nonzero to avoid zero-divide. */
|
||||
if (qtable->quantval[0] == 0 ||
|
||||
qtable->quantval[Q01_POS] == 0 ||
|
||||
qtable->quantval[Q10_POS] == 0 ||
|
||||
qtable->quantval[Q20_POS] == 0 ||
|
||||
qtable->quantval[Q11_POS] == 0 ||
|
||||
qtable->quantval[Q02_POS] == 0)
|
||||
qtable->quantval[Q02_POS] == 0 ||
|
||||
qtable->quantval[Q03_POS] == 0 ||
|
||||
qtable->quantval[Q12_POS] == 0 ||
|
||||
qtable->quantval[Q21_POS] == 0 ||
|
||||
qtable->quantval[Q30_POS] == 0)
|
||||
return FALSE;
|
||||
/* DC values must be at least partly known for all components. */
|
||||
coef_bits = cinfo->coef_bits[ci];
|
||||
prev_coef_bits = cinfo->coef_bits[ci + cinfo->num_components];
|
||||
if (coef_bits[0] < 0)
|
||||
return FALSE;
|
||||
coef_bits_latch[0] = coef_bits[0];
|
||||
/* Block smoothing is helpful if some AC coefficients remain inaccurate. */
|
||||
for (coefi = 1; coefi <= 5; coefi++) {
|
||||
for (coefi = 1; coefi < SAVED_COEFS; coefi++) {
|
||||
if (cinfo->input_scan_number > 1)
|
||||
prev_coef_bits_latch[coefi] = prev_coef_bits[coefi];
|
||||
else
|
||||
prev_coef_bits_latch[coefi] = -1;
|
||||
coef_bits_latch[coefi] = coef_bits[coefi];
|
||||
if (coef_bits[coefi] != 0)
|
||||
smoothing_useful = TRUE;
|
||||
}
|
||||
coef_bits_latch += SAVED_COEFS;
|
||||
prev_coef_bits_latch += SAVED_COEFS;
|
||||
}
|
||||
|
||||
return smoothing_useful;
|
||||
@@ -412,17 +432,20 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
JDIMENSION block_num, last_block_column;
|
||||
int ci, block_row, block_rows, access_rows;
|
||||
JBLOCKARRAY buffer;
|
||||
JBLOCKROW buffer_ptr, prev_block_row, next_block_row;
|
||||
JBLOCKROW buffer_ptr, prev_prev_block_row, prev_block_row;
|
||||
JBLOCKROW next_block_row, next_next_block_row;
|
||||
JSAMPARRAY output_ptr;
|
||||
JDIMENSION output_col;
|
||||
jpeg_component_info *compptr;
|
||||
inverse_DCT_method_ptr inverse_DCT;
|
||||
boolean first_row, last_row;
|
||||
boolean change_dc;
|
||||
JCOEF *workspace;
|
||||
int *coef_bits;
|
||||
JQUANT_TBL *quanttbl;
|
||||
JLONG Q00, Q01, Q02, Q10, Q11, Q20, num;
|
||||
int DC1, DC2, DC3, DC4, DC5, DC6, DC7, DC8, DC9;
|
||||
JLONG Q00, Q01, Q02, Q03 = 0, Q10, Q11, Q12 = 0, Q20, Q21 = 0, Q30 = 0, num;
|
||||
int DC01, DC02, DC03, DC04, DC05, DC06, DC07, DC08, DC09, DC10, DC11, DC12,
|
||||
DC13, DC14, DC15, DC16, DC17, DC18, DC19, DC20, DC21, DC22, DC23, DC24,
|
||||
DC25;
|
||||
int Al, pred;
|
||||
|
||||
/* Keep a local variable to avoid looking it up more than once */
|
||||
@@ -434,10 +457,10 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
if (cinfo->input_scan_number == cinfo->output_scan_number) {
|
||||
/* If input is working on current scan, we ordinarily want it to
|
||||
* have completed the current row. But if input scan is DC,
|
||||
* we want it to keep one row ahead so that next block row's DC
|
||||
* we want it to keep two rows ahead so that next two block rows' DC
|
||||
* values are up to date.
|
||||
*/
|
||||
JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0;
|
||||
JDIMENSION delta = (cinfo->Ss == 0) ? 2 : 0;
|
||||
if (cinfo->input_iMCU_row > cinfo->output_iMCU_row + delta)
|
||||
break;
|
||||
}
|
||||
@@ -452,34 +475,53 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
if (!compptr->component_needed)
|
||||
continue;
|
||||
/* Count non-dummy DCT block rows in this iMCU row. */
|
||||
if (cinfo->output_iMCU_row < last_iMCU_row) {
|
||||
if (cinfo->output_iMCU_row < last_iMCU_row - 1) {
|
||||
block_rows = compptr->v_samp_factor;
|
||||
access_rows = block_rows * 3; /* this and next two iMCU rows */
|
||||
} else if (cinfo->output_iMCU_row < last_iMCU_row) {
|
||||
block_rows = compptr->v_samp_factor;
|
||||
access_rows = block_rows * 2; /* this and next iMCU row */
|
||||
last_row = FALSE;
|
||||
} else {
|
||||
/* NB: can't use last_row_height here; it is input-side-dependent! */
|
||||
block_rows = (int)(compptr->height_in_blocks % compptr->v_samp_factor);
|
||||
if (block_rows == 0) block_rows = compptr->v_samp_factor;
|
||||
access_rows = block_rows; /* this iMCU row only */
|
||||
last_row = TRUE;
|
||||
}
|
||||
/* Align the virtual buffer for this component. */
|
||||
if (cinfo->output_iMCU_row > 0) {
|
||||
access_rows += compptr->v_samp_factor; /* prior iMCU row too */
|
||||
if (cinfo->output_iMCU_row > 1) {
|
||||
access_rows += 2 * compptr->v_samp_factor; /* prior two iMCU rows too */
|
||||
buffer = (*cinfo->mem->access_virt_barray)
|
||||
((j_common_ptr)cinfo, coef->whole_image[ci],
|
||||
(cinfo->output_iMCU_row - 2) * compptr->v_samp_factor,
|
||||
(JDIMENSION)access_rows, FALSE);
|
||||
buffer += 2 * compptr->v_samp_factor; /* point to current iMCU row */
|
||||
} else if (cinfo->output_iMCU_row > 0) {
|
||||
buffer = (*cinfo->mem->access_virt_barray)
|
||||
((j_common_ptr)cinfo, coef->whole_image[ci],
|
||||
(cinfo->output_iMCU_row - 1) * compptr->v_samp_factor,
|
||||
(JDIMENSION)access_rows, FALSE);
|
||||
buffer += compptr->v_samp_factor; /* point to current iMCU row */
|
||||
first_row = FALSE;
|
||||
} else {
|
||||
buffer = (*cinfo->mem->access_virt_barray)
|
||||
((j_common_ptr)cinfo, coef->whole_image[ci],
|
||||
(JDIMENSION)0, (JDIMENSION)access_rows, FALSE);
|
||||
first_row = TRUE;
|
||||
}
|
||||
/* Fetch component-dependent info */
|
||||
coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS);
|
||||
/* Fetch component-dependent info.
|
||||
* If the current scan is incomplete, then we use the component-dependent
|
||||
* info from the previous scan.
|
||||
*/
|
||||
if (cinfo->output_iMCU_row > cinfo->master->last_good_iMCU_row)
|
||||
coef_bits =
|
||||
coef->coef_bits_latch + ((ci + cinfo->num_components) * SAVED_COEFS);
|
||||
else
|
||||
coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS);
|
||||
|
||||
/* We only do DC interpolation if no AC coefficient data is available. */
|
||||
change_dc =
|
||||
coef_bits[1] == -1 && coef_bits[2] == -1 && coef_bits[3] == -1 &&
|
||||
coef_bits[4] == -1 && coef_bits[5] == -1 && coef_bits[6] == -1 &&
|
||||
coef_bits[7] == -1 && coef_bits[8] == -1 && coef_bits[9] == -1;
|
||||
|
||||
quanttbl = compptr->quant_table;
|
||||
Q00 = quanttbl->quantval[0];
|
||||
Q01 = quanttbl->quantval[Q01_POS];
|
||||
@@ -487,27 +529,51 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
Q20 = quanttbl->quantval[Q20_POS];
|
||||
Q11 = quanttbl->quantval[Q11_POS];
|
||||
Q02 = quanttbl->quantval[Q02_POS];
|
||||
if (change_dc) {
|
||||
Q03 = quanttbl->quantval[Q03_POS];
|
||||
Q12 = quanttbl->quantval[Q12_POS];
|
||||
Q21 = quanttbl->quantval[Q21_POS];
|
||||
Q30 = quanttbl->quantval[Q30_POS];
|
||||
}
|
||||
inverse_DCT = cinfo->idct->inverse_DCT[ci];
|
||||
output_ptr = output_buf[ci];
|
||||
/* Loop over all DCT blocks to be processed. */
|
||||
for (block_row = 0; block_row < block_rows; block_row++) {
|
||||
buffer_ptr = buffer[block_row] + cinfo->master->first_MCU_col[ci];
|
||||
if (first_row && block_row == 0)
|
||||
|
||||
if (block_row > 0 || cinfo->output_iMCU_row > 0)
|
||||
prev_block_row =
|
||||
buffer[block_row - 1] + cinfo->master->first_MCU_col[ci];
|
||||
else
|
||||
prev_block_row = buffer_ptr;
|
||||
|
||||
if (block_row > 1 || cinfo->output_iMCU_row > 1)
|
||||
prev_prev_block_row =
|
||||
buffer[block_row - 2] + cinfo->master->first_MCU_col[ci];
|
||||
else
|
||||
prev_prev_block_row = prev_block_row;
|
||||
|
||||
if (block_row < block_rows - 1 || cinfo->output_iMCU_row < last_iMCU_row)
|
||||
next_block_row =
|
||||
buffer[block_row + 1] + cinfo->master->first_MCU_col[ci];
|
||||
else
|
||||
prev_block_row = buffer[block_row - 1] +
|
||||
cinfo->master->first_MCU_col[ci];
|
||||
if (last_row && block_row == block_rows - 1)
|
||||
next_block_row = buffer_ptr;
|
||||
|
||||
if (block_row < block_rows - 2 ||
|
||||
cinfo->output_iMCU_row < last_iMCU_row - 1)
|
||||
next_next_block_row =
|
||||
buffer[block_row + 2] + cinfo->master->first_MCU_col[ci];
|
||||
else
|
||||
next_block_row = buffer[block_row + 1] +
|
||||
cinfo->master->first_MCU_col[ci];
|
||||
next_next_block_row = next_block_row;
|
||||
|
||||
/* We fetch the surrounding DC values using a sliding-register approach.
|
||||
* Initialize all nine here so as to do the right thing on narrow pics.
|
||||
* Initialize all 25 here so as to do the right thing on narrow pics.
|
||||
*/
|
||||
DC1 = DC2 = DC3 = (int)prev_block_row[0][0];
|
||||
DC4 = DC5 = DC6 = (int)buffer_ptr[0][0];
|
||||
DC7 = DC8 = DC9 = (int)next_block_row[0][0];
|
||||
DC01 = DC02 = DC03 = DC04 = DC05 = (int)prev_prev_block_row[0][0];
|
||||
DC06 = DC07 = DC08 = DC09 = DC10 = (int)prev_block_row[0][0];
|
||||
DC11 = DC12 = DC13 = DC14 = DC15 = (int)buffer_ptr[0][0];
|
||||
DC16 = DC17 = DC18 = DC19 = DC20 = (int)next_block_row[0][0];
|
||||
DC21 = DC22 = DC23 = DC24 = DC25 = (int)next_next_block_row[0][0];
|
||||
output_col = 0;
|
||||
last_block_column = compptr->width_in_blocks - 1;
|
||||
for (block_num = cinfo->master->first_MCU_col[ci];
|
||||
@@ -515,18 +581,39 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
/* Fetch current DCT block into workspace so we can modify it. */
|
||||
jcopy_block_row(buffer_ptr, (JBLOCKROW)workspace, (JDIMENSION)1);
|
||||
/* Update DC values */
|
||||
if (block_num < last_block_column) {
|
||||
DC3 = (int)prev_block_row[1][0];
|
||||
DC6 = (int)buffer_ptr[1][0];
|
||||
DC9 = (int)next_block_row[1][0];
|
||||
if (block_num == cinfo->master->first_MCU_col[ci] &&
|
||||
block_num < last_block_column) {
|
||||
DC04 = (int)prev_prev_block_row[1][0];
|
||||
DC09 = (int)prev_block_row[1][0];
|
||||
DC14 = (int)buffer_ptr[1][0];
|
||||
DC19 = (int)next_block_row[1][0];
|
||||
DC24 = (int)next_next_block_row[1][0];
|
||||
}
|
||||
/* Compute coefficient estimates per K.8.
|
||||
* An estimate is applied only if coefficient is still zero,
|
||||
* and is not known to be fully accurate.
|
||||
if (block_num + 1 < last_block_column) {
|
||||
DC05 = (int)prev_prev_block_row[2][0];
|
||||
DC10 = (int)prev_block_row[2][0];
|
||||
DC15 = (int)buffer_ptr[2][0];
|
||||
DC20 = (int)next_block_row[2][0];
|
||||
DC25 = (int)next_next_block_row[2][0];
|
||||
}
|
||||
/* If DC interpolation is enabled, compute coefficient estimates using
|
||||
* a Gaussian-like kernel, keeping the averages of the DC values.
|
||||
*
|
||||
* If DC interpolation is disabled, compute coefficient estimates using
|
||||
* an algorithm similar to the one described in Section K.8 of the JPEG
|
||||
* standard, except applied to a 5x5 window rather than a 3x3 window.
|
||||
*
|
||||
* An estimate is applied only if the coefficient is still zero and is
|
||||
* not known to be fully accurate.
|
||||
*/
|
||||
/* AC01 */
|
||||
if ((Al = coef_bits[1]) != 0 && workspace[1] == 0) {
|
||||
num = 36 * Q00 * (DC4 - DC6);
|
||||
num = Q00 * (change_dc ?
|
||||
(-DC01 - DC02 + DC04 + DC05 - 3 * DC06 + 13 * DC07 -
|
||||
13 * DC09 + 3 * DC10 - 3 * DC11 + 38 * DC12 - 38 * DC14 +
|
||||
3 * DC15 - 3 * DC16 + 13 * DC17 - 13 * DC19 + 3 * DC20 -
|
||||
DC21 - DC22 + DC24 + DC25) :
|
||||
(-7 * DC11 + 50 * DC12 - 50 * DC14 + 7 * DC15));
|
||||
if (num >= 0) {
|
||||
pred = (int)(((Q01 << 7) + num) / (Q01 << 8));
|
||||
if (Al > 0 && pred >= (1 << Al))
|
||||
@@ -541,7 +628,12 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
}
|
||||
/* AC10 */
|
||||
if ((Al = coef_bits[2]) != 0 && workspace[8] == 0) {
|
||||
num = 36 * Q00 * (DC2 - DC8);
|
||||
num = Q00 * (change_dc ?
|
||||
(-DC01 - 3 * DC02 - 3 * DC03 - 3 * DC04 - DC05 - DC06 +
|
||||
13 * DC07 + 38 * DC08 + 13 * DC09 - DC10 + DC16 -
|
||||
13 * DC17 - 38 * DC18 - 13 * DC19 + DC20 + DC21 +
|
||||
3 * DC22 + 3 * DC23 + 3 * DC24 + DC25) :
|
||||
(-7 * DC03 + 50 * DC08 - 50 * DC18 + 7 * DC23));
|
||||
if (num >= 0) {
|
||||
pred = (int)(((Q10 << 7) + num) / (Q10 << 8));
|
||||
if (Al > 0 && pred >= (1 << Al))
|
||||
@@ -556,7 +648,10 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
}
|
||||
/* AC20 */
|
||||
if ((Al = coef_bits[3]) != 0 && workspace[16] == 0) {
|
||||
num = 9 * Q00 * (DC2 + DC8 - 2 * DC5);
|
||||
num = Q00 * (change_dc ?
|
||||
(DC03 + 2 * DC07 + 7 * DC08 + 2 * DC09 - 5 * DC12 - 14 * DC13 -
|
||||
5 * DC14 + 2 * DC17 + 7 * DC18 + 2 * DC19 + DC23) :
|
||||
(-DC03 + 13 * DC08 - 24 * DC13 + 13 * DC18 - DC23));
|
||||
if (num >= 0) {
|
||||
pred = (int)(((Q20 << 7) + num) / (Q20 << 8));
|
||||
if (Al > 0 && pred >= (1 << Al))
|
||||
@@ -571,7 +666,11 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
}
|
||||
/* AC11 */
|
||||
if ((Al = coef_bits[4]) != 0 && workspace[9] == 0) {
|
||||
num = 5 * Q00 * (DC1 - DC3 - DC7 + DC9);
|
||||
num = Q00 * (change_dc ?
|
||||
(-DC01 + DC05 + 9 * DC07 - 9 * DC09 - 9 * DC17 +
|
||||
9 * DC19 + DC21 - DC25) :
|
||||
(DC10 + DC16 - 10 * DC17 + 10 * DC19 - DC02 - DC20 + DC22 -
|
||||
DC24 + DC04 - DC06 + 10 * DC07 - 10 * DC09));
|
||||
if (num >= 0) {
|
||||
pred = (int)(((Q11 << 7) + num) / (Q11 << 8));
|
||||
if (Al > 0 && pred >= (1 << Al))
|
||||
@@ -586,7 +685,10 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
}
|
||||
/* AC02 */
|
||||
if ((Al = coef_bits[5]) != 0 && workspace[2] == 0) {
|
||||
num = 9 * Q00 * (DC4 + DC6 - 2 * DC5);
|
||||
num = Q00 * (change_dc ?
|
||||
(2 * DC07 - 5 * DC08 + 2 * DC09 + DC11 + 7 * DC12 - 14 * DC13 +
|
||||
7 * DC14 + DC15 + 2 * DC17 - 5 * DC18 + 2 * DC19) :
|
||||
(-DC11 + 13 * DC12 - 24 * DC13 + 13 * DC14 - DC15));
|
||||
if (num >= 0) {
|
||||
pred = (int)(((Q02 << 7) + num) / (Q02 << 8));
|
||||
if (Al > 0 && pred >= (1 << Al))
|
||||
@@ -599,14 +701,96 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
}
|
||||
workspace[2] = (JCOEF)pred;
|
||||
}
|
||||
if (change_dc) {
|
||||
/* AC03 */
|
||||
if ((Al = coef_bits[6]) != 0 && workspace[3] == 0) {
|
||||
num = Q00 * (DC07 - DC09 + 2 * DC12 - 2 * DC14 + DC17 - DC19);
|
||||
if (num >= 0) {
|
||||
pred = (int)(((Q03 << 7) + num) / (Q03 << 8));
|
||||
if (Al > 0 && pred >= (1 << Al))
|
||||
pred = (1 << Al) - 1;
|
||||
} else {
|
||||
pred = (int)(((Q03 << 7) - num) / (Q03 << 8));
|
||||
if (Al > 0 && pred >= (1 << Al))
|
||||
pred = (1 << Al) - 1;
|
||||
pred = -pred;
|
||||
}
|
||||
workspace[3] = (JCOEF)pred;
|
||||
}
|
||||
/* AC12 */
|
||||
if ((Al = coef_bits[7]) != 0 && workspace[10] == 0) {
|
||||
num = Q00 * (DC07 - 3 * DC08 + DC09 - DC17 + 3 * DC18 - DC19);
|
||||
if (num >= 0) {
|
||||
pred = (int)(((Q12 << 7) + num) / (Q12 << 8));
|
||||
if (Al > 0 && pred >= (1 << Al))
|
||||
pred = (1 << Al) - 1;
|
||||
} else {
|
||||
pred = (int)(((Q12 << 7) - num) / (Q12 << 8));
|
||||
if (Al > 0 && pred >= (1 << Al))
|
||||
pred = (1 << Al) - 1;
|
||||
pred = -pred;
|
||||
}
|
||||
workspace[10] = (JCOEF)pred;
|
||||
}
|
||||
/* AC21 */
|
||||
if ((Al = coef_bits[8]) != 0 && workspace[17] == 0) {
|
||||
num = Q00 * (DC07 - DC09 - 3 * DC12 + 3 * DC14 + DC17 - DC19);
|
||||
if (num >= 0) {
|
||||
pred = (int)(((Q21 << 7) + num) / (Q21 << 8));
|
||||
if (Al > 0 && pred >= (1 << Al))
|
||||
pred = (1 << Al) - 1;
|
||||
} else {
|
||||
pred = (int)(((Q21 << 7) - num) / (Q21 << 8));
|
||||
if (Al > 0 && pred >= (1 << Al))
|
||||
pred = (1 << Al) - 1;
|
||||
pred = -pred;
|
||||
}
|
||||
workspace[17] = (JCOEF)pred;
|
||||
}
|
||||
/* AC30 */
|
||||
if ((Al = coef_bits[9]) != 0 && workspace[24] == 0) {
|
||||
num = Q00 * (DC07 + 2 * DC08 + DC09 - DC17 - 2 * DC18 - DC19);
|
||||
if (num >= 0) {
|
||||
pred = (int)(((Q30 << 7) + num) / (Q30 << 8));
|
||||
if (Al > 0 && pred >= (1 << Al))
|
||||
pred = (1 << Al) - 1;
|
||||
} else {
|
||||
pred = (int)(((Q30 << 7) - num) / (Q30 << 8));
|
||||
if (Al > 0 && pred >= (1 << Al))
|
||||
pred = (1 << Al) - 1;
|
||||
pred = -pred;
|
||||
}
|
||||
workspace[24] = (JCOEF)pred;
|
||||
}
|
||||
/* coef_bits[0] is non-negative. Otherwise this function would not
|
||||
* be called.
|
||||
*/
|
||||
num = Q00 *
|
||||
(-2 * DC01 - 6 * DC02 - 8 * DC03 - 6 * DC04 - 2 * DC05 -
|
||||
6 * DC06 + 6 * DC07 + 42 * DC08 + 6 * DC09 - 6 * DC10 -
|
||||
8 * DC11 + 42 * DC12 + 152 * DC13 + 42 * DC14 - 8 * DC15 -
|
||||
6 * DC16 + 6 * DC17 + 42 * DC18 + 6 * DC19 - 6 * DC20 -
|
||||
2 * DC21 - 6 * DC22 - 8 * DC23 - 6 * DC24 - 2 * DC25);
|
||||
if (num >= 0) {
|
||||
pred = (int)(((Q00 << 7) + num) / (Q00 << 8));
|
||||
} else {
|
||||
pred = (int)(((Q00 << 7) - num) / (Q00 << 8));
|
||||
pred = -pred;
|
||||
}
|
||||
workspace[0] = (JCOEF)pred;
|
||||
} /* change_dc */
|
||||
|
||||
/* OK, do the IDCT */
|
||||
(*inverse_DCT) (cinfo, compptr, (JCOEFPTR)workspace, output_ptr,
|
||||
output_col);
|
||||
/* Advance for next column */
|
||||
DC1 = DC2; DC2 = DC3;
|
||||
DC4 = DC5; DC5 = DC6;
|
||||
DC7 = DC8; DC8 = DC9;
|
||||
buffer_ptr++, prev_block_row++, next_block_row++;
|
||||
DC01 = DC02; DC02 = DC03; DC03 = DC04; DC04 = DC05;
|
||||
DC06 = DC07; DC07 = DC08; DC08 = DC09; DC09 = DC10;
|
||||
DC11 = DC12; DC12 = DC13; DC13 = DC14; DC14 = DC15;
|
||||
DC16 = DC17; DC17 = DC18; DC18 = DC19; DC19 = DC20;
|
||||
DC21 = DC22; DC22 = DC23; DC23 = DC24; DC24 = DC25;
|
||||
buffer_ptr++, prev_block_row++, next_block_row++,
|
||||
prev_prev_block_row++, next_next_block_row++;
|
||||
output_col += compptr->_DCT_scaled_size;
|
||||
}
|
||||
output_ptr += compptr->_DCT_scaled_size;
|
||||
@@ -655,7 +839,7 @@ jinit_d_coef_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
|
||||
#ifdef BLOCK_SMOOTHING_SUPPORTED
|
||||
/* If block smoothing could be used, need a bigger window */
|
||||
if (cinfo->progressive_mode)
|
||||
access_rows *= 3;
|
||||
access_rows *= 5;
|
||||
#endif
|
||||
coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE, TRUE,
|
||||
|
||||
+2
-1
@@ -5,6 +5,7 @@
|
||||
* Copyright (C) 1994-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2020, Google, Inc.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*/
|
||||
@@ -51,7 +52,7 @@ typedef struct {
|
||||
#ifdef BLOCK_SMOOTHING_SUPPORTED
|
||||
/* When doing block smoothing, we latch coefficient Al values here */
|
||||
int *coef_bits_latch;
|
||||
#define SAVED_COEFS 6 /* we save coef_bits[0..5] */
|
||||
#define SAVED_COEFS 10 /* we save coef_bits[0..9] */
|
||||
#endif
|
||||
} my_coef_controller;
|
||||
|
||||
|
||||
+48
-48
@@ -45,9 +45,9 @@ ycc_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
outptr = *output_buf++;
|
||||
|
||||
if (PACK_NEED_ALIGNMENT(outptr)) {
|
||||
y = GETJSAMPLE(*inptr0++);
|
||||
cb = GETJSAMPLE(*inptr1++);
|
||||
cr = GETJSAMPLE(*inptr2++);
|
||||
y = *inptr0++;
|
||||
cb = *inptr1++;
|
||||
cr = *inptr2++;
|
||||
r = range_limit[y + Crrtab[cr]];
|
||||
g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
||||
SCALEBITS))];
|
||||
@@ -58,18 +58,18 @@ ycc_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
num_cols--;
|
||||
}
|
||||
for (col = 0; col < (num_cols >> 1); col++) {
|
||||
y = GETJSAMPLE(*inptr0++);
|
||||
cb = GETJSAMPLE(*inptr1++);
|
||||
cr = GETJSAMPLE(*inptr2++);
|
||||
y = *inptr0++;
|
||||
cb = *inptr1++;
|
||||
cr = *inptr2++;
|
||||
r = range_limit[y + Crrtab[cr]];
|
||||
g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
||||
SCALEBITS))];
|
||||
b = range_limit[y + Cbbtab[cb]];
|
||||
rgb = PACK_SHORT_565(r, g, b);
|
||||
|
||||
y = GETJSAMPLE(*inptr0++);
|
||||
cb = GETJSAMPLE(*inptr1++);
|
||||
cr = GETJSAMPLE(*inptr2++);
|
||||
y = *inptr0++;
|
||||
cb = *inptr1++;
|
||||
cr = *inptr2++;
|
||||
r = range_limit[y + Crrtab[cr]];
|
||||
g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
||||
SCALEBITS))];
|
||||
@@ -80,9 +80,9 @@ ycc_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
outptr += 4;
|
||||
}
|
||||
if (num_cols & 1) {
|
||||
y = GETJSAMPLE(*inptr0);
|
||||
cb = GETJSAMPLE(*inptr1);
|
||||
cr = GETJSAMPLE(*inptr2);
|
||||
y = *inptr0;
|
||||
cb = *inptr1;
|
||||
cr = *inptr2;
|
||||
r = range_limit[y + Crrtab[cr]];
|
||||
g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
||||
SCALEBITS))];
|
||||
@@ -125,9 +125,9 @@ ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
input_row++;
|
||||
outptr = *output_buf++;
|
||||
if (PACK_NEED_ALIGNMENT(outptr)) {
|
||||
y = GETJSAMPLE(*inptr0++);
|
||||
cb = GETJSAMPLE(*inptr1++);
|
||||
cr = GETJSAMPLE(*inptr2++);
|
||||
y = *inptr0++;
|
||||
cb = *inptr1++;
|
||||
cr = *inptr2++;
|
||||
r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
|
||||
g = range_limit[DITHER_565_G(y +
|
||||
((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
||||
@@ -139,9 +139,9 @@ ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
num_cols--;
|
||||
}
|
||||
for (col = 0; col < (num_cols >> 1); col++) {
|
||||
y = GETJSAMPLE(*inptr0++);
|
||||
cb = GETJSAMPLE(*inptr1++);
|
||||
cr = GETJSAMPLE(*inptr2++);
|
||||
y = *inptr0++;
|
||||
cb = *inptr1++;
|
||||
cr = *inptr2++;
|
||||
r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
|
||||
g = range_limit[DITHER_565_G(y +
|
||||
((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
||||
@@ -150,9 +150,9 @@ ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
d0 = DITHER_ROTATE(d0);
|
||||
rgb = PACK_SHORT_565(r, g, b);
|
||||
|
||||
y = GETJSAMPLE(*inptr0++);
|
||||
cb = GETJSAMPLE(*inptr1++);
|
||||
cr = GETJSAMPLE(*inptr2++);
|
||||
y = *inptr0++;
|
||||
cb = *inptr1++;
|
||||
cr = *inptr2++;
|
||||
r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
|
||||
g = range_limit[DITHER_565_G(y +
|
||||
((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
||||
@@ -165,9 +165,9 @@ ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
outptr += 4;
|
||||
}
|
||||
if (num_cols & 1) {
|
||||
y = GETJSAMPLE(*inptr0);
|
||||
cb = GETJSAMPLE(*inptr1);
|
||||
cr = GETJSAMPLE(*inptr2);
|
||||
y = *inptr0;
|
||||
cb = *inptr1;
|
||||
cr = *inptr2;
|
||||
r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
|
||||
g = range_limit[DITHER_565_G(y +
|
||||
((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
||||
@@ -202,32 +202,32 @@ rgb_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
input_row++;
|
||||
outptr = *output_buf++;
|
||||
if (PACK_NEED_ALIGNMENT(outptr)) {
|
||||
r = GETJSAMPLE(*inptr0++);
|
||||
g = GETJSAMPLE(*inptr1++);
|
||||
b = GETJSAMPLE(*inptr2++);
|
||||
r = *inptr0++;
|
||||
g = *inptr1++;
|
||||
b = *inptr2++;
|
||||
rgb = PACK_SHORT_565(r, g, b);
|
||||
*(INT16 *)outptr = (INT16)rgb;
|
||||
outptr += 2;
|
||||
num_cols--;
|
||||
}
|
||||
for (col = 0; col < (num_cols >> 1); col++) {
|
||||
r = GETJSAMPLE(*inptr0++);
|
||||
g = GETJSAMPLE(*inptr1++);
|
||||
b = GETJSAMPLE(*inptr2++);
|
||||
r = *inptr0++;
|
||||
g = *inptr1++;
|
||||
b = *inptr2++;
|
||||
rgb = PACK_SHORT_565(r, g, b);
|
||||
|
||||
r = GETJSAMPLE(*inptr0++);
|
||||
g = GETJSAMPLE(*inptr1++);
|
||||
b = GETJSAMPLE(*inptr2++);
|
||||
r = *inptr0++;
|
||||
g = *inptr1++;
|
||||
b = *inptr2++;
|
||||
rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
|
||||
|
||||
WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
|
||||
outptr += 4;
|
||||
}
|
||||
if (num_cols & 1) {
|
||||
r = GETJSAMPLE(*inptr0);
|
||||
g = GETJSAMPLE(*inptr1);
|
||||
b = GETJSAMPLE(*inptr2);
|
||||
r = *inptr0;
|
||||
g = *inptr1;
|
||||
b = *inptr2;
|
||||
rgb = PACK_SHORT_565(r, g, b);
|
||||
*(INT16 *)outptr = (INT16)rgb;
|
||||
}
|
||||
@@ -259,24 +259,24 @@ rgb_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
input_row++;
|
||||
outptr = *output_buf++;
|
||||
if (PACK_NEED_ALIGNMENT(outptr)) {
|
||||
r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
|
||||
g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
|
||||
b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
|
||||
r = range_limit[DITHER_565_R(*inptr0++, d0)];
|
||||
g = range_limit[DITHER_565_G(*inptr1++, d0)];
|
||||
b = range_limit[DITHER_565_B(*inptr2++, d0)];
|
||||
rgb = PACK_SHORT_565(r, g, b);
|
||||
*(INT16 *)outptr = (INT16)rgb;
|
||||
outptr += 2;
|
||||
num_cols--;
|
||||
}
|
||||
for (col = 0; col < (num_cols >> 1); col++) {
|
||||
r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
|
||||
g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
|
||||
b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
|
||||
r = range_limit[DITHER_565_R(*inptr0++, d0)];
|
||||
g = range_limit[DITHER_565_G(*inptr1++, d0)];
|
||||
b = range_limit[DITHER_565_B(*inptr2++, d0)];
|
||||
d0 = DITHER_ROTATE(d0);
|
||||
rgb = PACK_SHORT_565(r, g, b);
|
||||
|
||||
r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
|
||||
g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
|
||||
b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
|
||||
r = range_limit[DITHER_565_R(*inptr0++, d0)];
|
||||
g = range_limit[DITHER_565_G(*inptr1++, d0)];
|
||||
b = range_limit[DITHER_565_B(*inptr2++, d0)];
|
||||
d0 = DITHER_ROTATE(d0);
|
||||
rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
|
||||
|
||||
@@ -284,9 +284,9 @@ rgb_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
outptr += 4;
|
||||
}
|
||||
if (num_cols & 1) {
|
||||
r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0), d0)];
|
||||
g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1), d0)];
|
||||
b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2), d0)];
|
||||
r = range_limit[DITHER_565_R(*inptr0, d0)];
|
||||
g = range_limit[DITHER_565_G(*inptr1, d0)];
|
||||
b = range_limit[DITHER_565_B(*inptr2, d0)];
|
||||
rgb = PACK_SHORT_565(r, g, b);
|
||||
*(INT16 *)outptr = (INT16)rgb;
|
||||
}
|
||||
|
||||
+3
-5
@@ -53,9 +53,9 @@ ycc_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
input_row++;
|
||||
outptr = *output_buf++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
y = GETJSAMPLE(inptr0[col]);
|
||||
cb = GETJSAMPLE(inptr1[col]);
|
||||
cr = GETJSAMPLE(inptr2[col]);
|
||||
y = inptr0[col];
|
||||
cb = inptr1[col];
|
||||
cr = inptr2[col];
|
||||
/* Range-limiting is essential due to noise introduced by DCT losses. */
|
||||
outptr[RGB_RED] = range_limit[y + Crrtab[cr]];
|
||||
outptr[RGB_GREEN] = range_limit[y +
|
||||
@@ -93,7 +93,6 @@ gray_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
inptr = input_buf[0][input_row++];
|
||||
outptr = *output_buf++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
/* We can dispense with GETJSAMPLE() here */
|
||||
outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
|
||||
/* Set unused byte to 0xFF so it can be interpreted as an opaque */
|
||||
/* alpha channel value */
|
||||
@@ -128,7 +127,6 @@ rgb_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
input_row++;
|
||||
outptr = *output_buf++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
/* We can dispense with GETJSAMPLE() here */
|
||||
outptr[RGB_RED] = inptr0[col];
|
||||
outptr[RGB_GREEN] = inptr1[col];
|
||||
outptr[RGB_BLUE] = inptr2[col];
|
||||
|
||||
Vendored
+7
-7
@@ -341,9 +341,9 @@ rgb_gray_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
input_row++;
|
||||
outptr = *output_buf++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
r = GETJSAMPLE(inptr0[col]);
|
||||
g = GETJSAMPLE(inptr1[col]);
|
||||
b = GETJSAMPLE(inptr2[col]);
|
||||
r = inptr0[col];
|
||||
g = inptr1[col];
|
||||
b = inptr2[col];
|
||||
/* Y */
|
||||
outptr[col] = (JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +
|
||||
ctab[b + B_Y_OFF]) >> SCALEBITS);
|
||||
@@ -550,9 +550,9 @@ ycck_cmyk_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
input_row++;
|
||||
outptr = *output_buf++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
y = GETJSAMPLE(inptr0[col]);
|
||||
cb = GETJSAMPLE(inptr1[col]);
|
||||
cr = GETJSAMPLE(inptr2[col]);
|
||||
y = inptr0[col];
|
||||
cb = inptr1[col];
|
||||
cr = inptr2[col];
|
||||
/* Range-limiting is essential due to noise introduced by DCT losses. */
|
||||
outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */
|
||||
outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */
|
||||
@@ -560,7 +560,7 @@ ycck_cmyk_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
SCALEBITS)))];
|
||||
outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */
|
||||
/* K passes through unchanged */
|
||||
outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */
|
||||
outptr[3] = inptr3[col];
|
||||
outptr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+27
-33
@@ -5,6 +5,7 @@
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009-2011, 2016, 2018-2019, D. R. Commander.
|
||||
* Copyright (C) 2018, Matthias Räncker.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -39,24 +40,6 @@ typedef struct {
|
||||
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
|
||||
} savable_state;
|
||||
|
||||
/* This macro is to work around compilers with missing or broken
|
||||
* structure assignment. You'll need to fix this code if you have
|
||||
* such a compiler and you change MAX_COMPS_IN_SCAN.
|
||||
*/
|
||||
|
||||
#ifndef NO_STRUCT_ASSIGN
|
||||
#define ASSIGN_STATE(dest, src) ((dest) = (src))
|
||||
#else
|
||||
#if MAX_COMPS_IN_SCAN == 4
|
||||
#define ASSIGN_STATE(dest, src) \
|
||||
((dest).last_dc_val[0] = (src).last_dc_val[0], \
|
||||
(dest).last_dc_val[1] = (src).last_dc_val[1], \
|
||||
(dest).last_dc_val[2] = (src).last_dc_val[2], \
|
||||
(dest).last_dc_val[3] = (src).last_dc_val[3])
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_entropy_decoder pub; /* public fields */
|
||||
|
||||
@@ -325,7 +308,7 @@ jpeg_fill_bit_buffer(bitread_working_state *state,
|
||||
bytes_in_buffer = cinfo->src->bytes_in_buffer;
|
||||
}
|
||||
bytes_in_buffer--;
|
||||
c = GETJOCTET(*next_input_byte++);
|
||||
c = *next_input_byte++;
|
||||
|
||||
/* If it's 0xFF, check and discard stuffed zero byte */
|
||||
if (c == 0xFF) {
|
||||
@@ -342,7 +325,7 @@ jpeg_fill_bit_buffer(bitread_working_state *state,
|
||||
bytes_in_buffer = cinfo->src->bytes_in_buffer;
|
||||
}
|
||||
bytes_in_buffer--;
|
||||
c = GETJOCTET(*next_input_byte++);
|
||||
c = *next_input_byte++;
|
||||
} while (c == 0xFF);
|
||||
|
||||
if (c == 0) {
|
||||
@@ -405,8 +388,8 @@ no_more_bytes:
|
||||
|
||||
#define GET_BYTE { \
|
||||
register int c0, c1; \
|
||||
c0 = GETJOCTET(*buffer++); \
|
||||
c1 = GETJOCTET(*buffer); \
|
||||
c0 = *buffer++; \
|
||||
c1 = *buffer; \
|
||||
/* Pre-execute most common case */ \
|
||||
get_buffer = (get_buffer << 8) | c0; \
|
||||
bits_left += 8; \
|
||||
@@ -423,7 +406,7 @@ no_more_bytes:
|
||||
} \
|
||||
}
|
||||
|
||||
#if SIZEOF_SIZE_T == 8 || defined(_WIN64)
|
||||
#if SIZEOF_SIZE_T == 8 || defined(_WIN64) || (defined(__x86_64__) && defined(__ILP32__))
|
||||
|
||||
/* Pre-fetch 48 bytes, because the holding register is 64-bit */
|
||||
#define FILL_BIT_BUFFER_FAST \
|
||||
@@ -557,6 +540,12 @@ process_restart(j_decompress_ptr cinfo)
|
||||
}
|
||||
|
||||
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(undefined_behavior_sanitizer)
|
||||
__attribute__((no_sanitize("signed-integer-overflow"),
|
||||
no_sanitize("unsigned-integer-overflow")))
|
||||
#endif
|
||||
#endif
|
||||
LOCAL(boolean)
|
||||
decode_mcu_slow(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
@@ -568,7 +557,7 @@ decode_mcu_slow(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
|
||||
/* Load up working state */
|
||||
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
|
||||
ASSIGN_STATE(state, entropy->saved);
|
||||
state = entropy->saved;
|
||||
|
||||
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
|
||||
JBLOCKROW block = MCU_data ? MCU_data[blkn] : NULL;
|
||||
@@ -589,11 +578,15 @@ decode_mcu_slow(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
if (entropy->dc_needed[blkn]) {
|
||||
/* Convert DC difference to actual value, update last_dc_val */
|
||||
int ci = cinfo->MCU_membership[blkn];
|
||||
/* This is really just
|
||||
* s += state.last_dc_val[ci];
|
||||
* It is written this way in order to shut up UBSan.
|
||||
/* Certain malformed JPEG images produce repeated DC coefficient
|
||||
* differences of 2047 or -2047, which causes state.last_dc_val[ci] to
|
||||
* grow until it overflows or underflows a 32-bit signed integer. This
|
||||
* behavior is, to the best of our understanding, innocuous, and it is
|
||||
* unclear how to work around it without potentially affecting
|
||||
* performance. Thus, we (hopefully temporarily) suppress UBSan integer
|
||||
* overflow errors for this function.
|
||||
*/
|
||||
s = (int)((unsigned int)s + (unsigned int)state.last_dc_val[ci]);
|
||||
s += state.last_dc_val[ci];
|
||||
state.last_dc_val[ci] = s;
|
||||
if (block) {
|
||||
/* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */
|
||||
@@ -653,7 +646,7 @@ decode_mcu_slow(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
|
||||
/* Completed MCU, so update state */
|
||||
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
|
||||
ASSIGN_STATE(entropy->saved, state);
|
||||
entropy->saved = state;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -671,7 +664,7 @@ decode_mcu_fast(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
/* Load up working state */
|
||||
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
|
||||
buffer = (JOCTET *)br_state.next_input_byte;
|
||||
ASSIGN_STATE(state, entropy->saved);
|
||||
state = entropy->saved;
|
||||
|
||||
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
|
||||
JBLOCKROW block = MCU_data ? MCU_data[blkn] : NULL;
|
||||
@@ -688,7 +681,7 @@ decode_mcu_fast(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
|
||||
if (entropy->dc_needed[blkn]) {
|
||||
int ci = cinfo->MCU_membership[blkn];
|
||||
s = (int)((unsigned int)s + (unsigned int)state.last_dc_val[ci]);
|
||||
s += state.last_dc_val[ci];
|
||||
state.last_dc_val[ci] = s;
|
||||
if (block)
|
||||
(*block)[0] = (JCOEF)s;
|
||||
@@ -740,7 +733,7 @@ decode_mcu_fast(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
br_state.bytes_in_buffer -= (buffer - br_state.next_input_byte);
|
||||
br_state.next_input_byte = buffer;
|
||||
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
|
||||
ASSIGN_STATE(entropy->saved, state);
|
||||
entropy->saved = state;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -795,7 +788,8 @@ use_slow:
|
||||
}
|
||||
|
||||
/* Account for restart interval (no-op if not using restarts) */
|
||||
entropy->restarts_to_go--;
|
||||
if (cinfo->restart_interval)
|
||||
entropy->restarts_to_go--;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Vendored
+11
-2
@@ -4,7 +4,8 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010-2011, 2015-2016, D. R. Commander.
|
||||
* Copyright (C) 2010-2011, 2015-2016, 2021, D. R. Commander.
|
||||
* Copyright (C) 2018, Matthias Räncker.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -78,6 +79,11 @@ EXTERN(void) jpeg_make_d_derived_tbl(j_decompress_ptr cinfo, boolean isDC,
|
||||
typedef size_t bit_buf_type; /* type of bit-extraction buffer */
|
||||
#define BIT_BUF_SIZE 64 /* size of buffer in bits */
|
||||
|
||||
#elif defined(__x86_64__) && defined(__ILP32__)
|
||||
|
||||
typedef unsigned long long bit_buf_type; /* type of bit-extraction buffer */
|
||||
#define BIT_BUF_SIZE 64 /* size of buffer in bits */
|
||||
|
||||
#else
|
||||
|
||||
typedef unsigned long bit_buf_type; /* type of bit-extraction buffer */
|
||||
@@ -228,7 +234,10 @@ slowlabel: \
|
||||
s |= GET_BITS(1); \
|
||||
nb++; \
|
||||
} \
|
||||
s = htbl->pub->huffval[(int)(s + htbl->valoffset[nb]) & 0xFF]; \
|
||||
if (nb > 16) \
|
||||
s = 0; \
|
||||
else \
|
||||
s = htbl->pub->huffval[(int)(s + htbl->valoffset[nb]) & 0xFF]; \
|
||||
}
|
||||
|
||||
/* Out-of-line case for Huffman code fetching */
|
||||
|
||||
Vendored
+16
-16
@@ -38,18 +38,18 @@ marker_is_icc(jpeg_saved_marker_ptr marker)
|
||||
marker->marker == ICC_MARKER &&
|
||||
marker->data_length >= ICC_OVERHEAD_LEN &&
|
||||
/* verify the identifying string */
|
||||
GETJOCTET(marker->data[0]) == 0x49 &&
|
||||
GETJOCTET(marker->data[1]) == 0x43 &&
|
||||
GETJOCTET(marker->data[2]) == 0x43 &&
|
||||
GETJOCTET(marker->data[3]) == 0x5F &&
|
||||
GETJOCTET(marker->data[4]) == 0x50 &&
|
||||
GETJOCTET(marker->data[5]) == 0x52 &&
|
||||
GETJOCTET(marker->data[6]) == 0x4F &&
|
||||
GETJOCTET(marker->data[7]) == 0x46 &&
|
||||
GETJOCTET(marker->data[8]) == 0x49 &&
|
||||
GETJOCTET(marker->data[9]) == 0x4C &&
|
||||
GETJOCTET(marker->data[10]) == 0x45 &&
|
||||
GETJOCTET(marker->data[11]) == 0x0;
|
||||
marker->data[0] == 0x49 &&
|
||||
marker->data[1] == 0x43 &&
|
||||
marker->data[2] == 0x43 &&
|
||||
marker->data[3] == 0x5F &&
|
||||
marker->data[4] == 0x50 &&
|
||||
marker->data[5] == 0x52 &&
|
||||
marker->data[6] == 0x4F &&
|
||||
marker->data[7] == 0x46 &&
|
||||
marker->data[8] == 0x49 &&
|
||||
marker->data[9] == 0x4C &&
|
||||
marker->data[10] == 0x45 &&
|
||||
marker->data[11] == 0x0;
|
||||
}
|
||||
|
||||
|
||||
@@ -102,12 +102,12 @@ jpeg_read_icc_profile(j_decompress_ptr cinfo, JOCTET **icc_data_ptr,
|
||||
for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
|
||||
if (marker_is_icc(marker)) {
|
||||
if (num_markers == 0)
|
||||
num_markers = GETJOCTET(marker->data[13]);
|
||||
else if (num_markers != GETJOCTET(marker->data[13])) {
|
||||
num_markers = marker->data[13];
|
||||
else if (num_markers != marker->data[13]) {
|
||||
WARNMS(cinfo, JWRN_BOGUS_ICC); /* inconsistent num_markers fields */
|
||||
return FALSE;
|
||||
}
|
||||
seq_no = GETJOCTET(marker->data[12]);
|
||||
seq_no = marker->data[12];
|
||||
if (seq_no <= 0 || seq_no > num_markers) {
|
||||
WARNMS(cinfo, JWRN_BOGUS_ICC); /* bogus sequence number */
|
||||
return FALSE;
|
||||
@@ -154,7 +154,7 @@ jpeg_read_icc_profile(j_decompress_ptr cinfo, JOCTET **icc_data_ptr,
|
||||
JOCTET FAR *src_ptr;
|
||||
JOCTET *dst_ptr;
|
||||
unsigned int length;
|
||||
seq_no = GETJOCTET(marker->data[12]);
|
||||
seq_no = marker->data[12];
|
||||
dst_ptr = icc_data + data_offset[seq_no];
|
||||
src_ptr = marker->data + ICC_OVERHEAD_LEN;
|
||||
length = data_length[seq_no];
|
||||
|
||||
+32
-35
@@ -151,7 +151,7 @@ typedef my_marker_reader *my_marker_ptr;
|
||||
#define INPUT_BYTE(cinfo, V, action) \
|
||||
MAKESTMT( MAKE_BYTE_AVAIL(cinfo, action); \
|
||||
bytes_in_buffer--; \
|
||||
V = GETJOCTET(*next_input_byte++); )
|
||||
V = *next_input_byte++; )
|
||||
|
||||
/* As above, but read two bytes interpreted as an unsigned 16-bit integer.
|
||||
* V should be declared unsigned int or perhaps JLONG.
|
||||
@@ -159,10 +159,10 @@ typedef my_marker_reader *my_marker_ptr;
|
||||
#define INPUT_2BYTES(cinfo, V, action) \
|
||||
MAKESTMT( MAKE_BYTE_AVAIL(cinfo, action); \
|
||||
bytes_in_buffer--; \
|
||||
V = ((unsigned int)GETJOCTET(*next_input_byte++)) << 8; \
|
||||
V = ((unsigned int)(*next_input_byte++)) << 8; \
|
||||
MAKE_BYTE_AVAIL(cinfo, action); \
|
||||
bytes_in_buffer--; \
|
||||
V += GETJOCTET(*next_input_byte++); )
|
||||
V += *next_input_byte++; )
|
||||
|
||||
|
||||
/*
|
||||
@@ -608,18 +608,18 @@ examine_app0(j_decompress_ptr cinfo, JOCTET *data, unsigned int datalen,
|
||||
JLONG totallen = (JLONG)datalen + remaining;
|
||||
|
||||
if (datalen >= APP0_DATA_LEN &&
|
||||
GETJOCTET(data[0]) == 0x4A &&
|
||||
GETJOCTET(data[1]) == 0x46 &&
|
||||
GETJOCTET(data[2]) == 0x49 &&
|
||||
GETJOCTET(data[3]) == 0x46 &&
|
||||
GETJOCTET(data[4]) == 0) {
|
||||
data[0] == 0x4A &&
|
||||
data[1] == 0x46 &&
|
||||
data[2] == 0x49 &&
|
||||
data[3] == 0x46 &&
|
||||
data[4] == 0) {
|
||||
/* Found JFIF APP0 marker: save info */
|
||||
cinfo->saw_JFIF_marker = TRUE;
|
||||
cinfo->JFIF_major_version = GETJOCTET(data[5]);
|
||||
cinfo->JFIF_minor_version = GETJOCTET(data[6]);
|
||||
cinfo->density_unit = GETJOCTET(data[7]);
|
||||
cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]);
|
||||
cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]);
|
||||
cinfo->JFIF_major_version = data[5];
|
||||
cinfo->JFIF_minor_version = data[6];
|
||||
cinfo->density_unit = data[7];
|
||||
cinfo->X_density = (data[8] << 8) + data[9];
|
||||
cinfo->Y_density = (data[10] << 8) + data[11];
|
||||
/* Check version.
|
||||
* Major version must be 1, anything else signals an incompatible change.
|
||||
* (We used to treat this as an error, but now it's a nonfatal warning,
|
||||
@@ -634,24 +634,22 @@ examine_app0(j_decompress_ptr cinfo, JOCTET *data, unsigned int datalen,
|
||||
cinfo->JFIF_major_version, cinfo->JFIF_minor_version,
|
||||
cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
|
||||
/* Validate thumbnail dimensions and issue appropriate messages */
|
||||
if (GETJOCTET(data[12]) | GETJOCTET(data[13]))
|
||||
TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL,
|
||||
GETJOCTET(data[12]), GETJOCTET(data[13]));
|
||||
if (data[12] | data[13])
|
||||
TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL, data[12], data[13]);
|
||||
totallen -= APP0_DATA_LEN;
|
||||
if (totallen !=
|
||||
((JLONG)GETJOCTET(data[12]) * (JLONG)GETJOCTET(data[13]) * (JLONG)3))
|
||||
if (totallen != ((JLONG)data[12] * (JLONG)data[13] * (JLONG)3))
|
||||
TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int)totallen);
|
||||
} else if (datalen >= 6 &&
|
||||
GETJOCTET(data[0]) == 0x4A &&
|
||||
GETJOCTET(data[1]) == 0x46 &&
|
||||
GETJOCTET(data[2]) == 0x58 &&
|
||||
GETJOCTET(data[3]) == 0x58 &&
|
||||
GETJOCTET(data[4]) == 0) {
|
||||
data[0] == 0x4A &&
|
||||
data[1] == 0x46 &&
|
||||
data[2] == 0x58 &&
|
||||
data[3] == 0x58 &&
|
||||
data[4] == 0) {
|
||||
/* Found JFIF "JFXX" extension APP0 marker */
|
||||
/* The library doesn't actually do anything with these,
|
||||
* but we try to produce a helpful trace message.
|
||||
*/
|
||||
switch (GETJOCTET(data[5])) {
|
||||
switch (data[5]) {
|
||||
case 0x10:
|
||||
TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int)totallen);
|
||||
break;
|
||||
@@ -662,8 +660,7 @@ examine_app0(j_decompress_ptr cinfo, JOCTET *data, unsigned int datalen,
|
||||
TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int)totallen);
|
||||
break;
|
||||
default:
|
||||
TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,
|
||||
GETJOCTET(data[5]), (int)totallen);
|
||||
TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION, data[5], (int)totallen);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@@ -684,16 +681,16 @@ examine_app14(j_decompress_ptr cinfo, JOCTET *data, unsigned int datalen,
|
||||
unsigned int version, flags0, flags1, transform;
|
||||
|
||||
if (datalen >= APP14_DATA_LEN &&
|
||||
GETJOCTET(data[0]) == 0x41 &&
|
||||
GETJOCTET(data[1]) == 0x64 &&
|
||||
GETJOCTET(data[2]) == 0x6F &&
|
||||
GETJOCTET(data[3]) == 0x62 &&
|
||||
GETJOCTET(data[4]) == 0x65) {
|
||||
data[0] == 0x41 &&
|
||||
data[1] == 0x64 &&
|
||||
data[2] == 0x6F &&
|
||||
data[3] == 0x62 &&
|
||||
data[4] == 0x65) {
|
||||
/* Found Adobe APP14 marker */
|
||||
version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]);
|
||||
flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]);
|
||||
flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]);
|
||||
transform = GETJOCTET(data[11]);
|
||||
version = (data[5] << 8) + data[6];
|
||||
flags0 = (data[7] << 8) + data[8];
|
||||
flags1 = (data[9] << 8) + data[10];
|
||||
transform = data[11];
|
||||
TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);
|
||||
cinfo->saw_Adobe_marker = TRUE;
|
||||
cinfo->Adobe_transform = (UINT8)transform;
|
||||
|
||||
+2
-13
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 2002-2009 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009-2011, 2016, D. R. Commander.
|
||||
* Copyright (C) 2009-2011, 2016, 2019, D. R. Commander.
|
||||
* Copyright (C) 2013, Linaro Limited.
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "jpeglib.h"
|
||||
#include "jpegcomp.h"
|
||||
#include "jdmaster.h"
|
||||
#include "jsimd.h"
|
||||
|
||||
|
||||
/*
|
||||
@@ -70,17 +69,6 @@ use_merged_upsample(j_decompress_ptr cinfo)
|
||||
cinfo->comp_info[1]._DCT_scaled_size != cinfo->_min_DCT_scaled_size ||
|
||||
cinfo->comp_info[2]._DCT_scaled_size != cinfo->_min_DCT_scaled_size)
|
||||
return FALSE;
|
||||
#ifdef WITH_SIMD
|
||||
/* If YCbCr-to-RGB color conversion is SIMD-accelerated but merged upsampling
|
||||
isn't, then disabling merged upsampling is likely to be faster when
|
||||
decompressing YCbCr JPEG images. */
|
||||
if (!jsimd_can_h2v2_merged_upsample() && !jsimd_can_h2v1_merged_upsample() &&
|
||||
jsimd_can_ycc_rgb() && cinfo->jpeg_color_space == JCS_YCbCr &&
|
||||
(cinfo->out_color_space == JCS_RGB ||
|
||||
(cinfo->out_color_space >= JCS_EXT_RGB &&
|
||||
cinfo->out_color_space <= JCS_EXT_ARGB)))
|
||||
return FALSE;
|
||||
#endif
|
||||
/* ??? also need to test for upsample-time rescaling, when & if supported */
|
||||
return TRUE; /* by golly, it'll work... */
|
||||
#else
|
||||
@@ -580,6 +568,7 @@ master_selection(j_decompress_ptr cinfo)
|
||||
*/
|
||||
cinfo->master->first_iMCU_col = 0;
|
||||
cinfo->master->last_iMCU_col = cinfo->MCUs_per_row - 1;
|
||||
cinfo->master->last_good_iMCU_row = 0;
|
||||
|
||||
#ifdef D_MULTISCAN_FILES_SUPPORTED
|
||||
/* If jpeg_start_decompress will read the whole file, initialize
|
||||
|
||||
+34
-34
@@ -43,20 +43,20 @@ h2v1_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
/* Loop for each pair of output pixels */
|
||||
for (col = cinfo->output_width >> 1; col > 0; col--) {
|
||||
/* Do the chroma part of the calculation */
|
||||
cb = GETJSAMPLE(*inptr1++);
|
||||
cr = GETJSAMPLE(*inptr2++);
|
||||
cb = *inptr1++;
|
||||
cr = *inptr2++;
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
|
||||
/* Fetch 2 Y values and emit 2 pixels */
|
||||
y = GETJSAMPLE(*inptr0++);
|
||||
y = *inptr0++;
|
||||
r = range_limit[y + cred];
|
||||
g = range_limit[y + cgreen];
|
||||
b = range_limit[y + cblue];
|
||||
rgb = PACK_SHORT_565(r, g, b);
|
||||
|
||||
y = GETJSAMPLE(*inptr0++);
|
||||
y = *inptr0++;
|
||||
r = range_limit[y + cred];
|
||||
g = range_limit[y + cgreen];
|
||||
b = range_limit[y + cblue];
|
||||
@@ -68,12 +68,12 @@ h2v1_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
|
||||
/* If image width is odd, do the last output column separately */
|
||||
if (cinfo->output_width & 1) {
|
||||
cb = GETJSAMPLE(*inptr1);
|
||||
cr = GETJSAMPLE(*inptr2);
|
||||
cb = *inptr1;
|
||||
cr = *inptr2;
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
y = GETJSAMPLE(*inptr0);
|
||||
y = *inptr0;
|
||||
r = range_limit[y + cred];
|
||||
g = range_limit[y + cgreen];
|
||||
b = range_limit[y + cblue];
|
||||
@@ -115,21 +115,21 @@ h2v1_merged_upsample_565D_internal(j_decompress_ptr cinfo,
|
||||
/* Loop for each pair of output pixels */
|
||||
for (col = cinfo->output_width >> 1; col > 0; col--) {
|
||||
/* Do the chroma part of the calculation */
|
||||
cb = GETJSAMPLE(*inptr1++);
|
||||
cr = GETJSAMPLE(*inptr2++);
|
||||
cb = *inptr1++;
|
||||
cr = *inptr2++;
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
|
||||
/* Fetch 2 Y values and emit 2 pixels */
|
||||
y = GETJSAMPLE(*inptr0++);
|
||||
y = *inptr0++;
|
||||
r = range_limit[DITHER_565_R(y + cred, d0)];
|
||||
g = range_limit[DITHER_565_G(y + cgreen, d0)];
|
||||
b = range_limit[DITHER_565_B(y + cblue, d0)];
|
||||
d0 = DITHER_ROTATE(d0);
|
||||
rgb = PACK_SHORT_565(r, g, b);
|
||||
|
||||
y = GETJSAMPLE(*inptr0++);
|
||||
y = *inptr0++;
|
||||
r = range_limit[DITHER_565_R(y + cred, d0)];
|
||||
g = range_limit[DITHER_565_G(y + cgreen, d0)];
|
||||
b = range_limit[DITHER_565_B(y + cblue, d0)];
|
||||
@@ -142,12 +142,12 @@ h2v1_merged_upsample_565D_internal(j_decompress_ptr cinfo,
|
||||
|
||||
/* If image width is odd, do the last output column separately */
|
||||
if (cinfo->output_width & 1) {
|
||||
cb = GETJSAMPLE(*inptr1);
|
||||
cr = GETJSAMPLE(*inptr2);
|
||||
cb = *inptr1;
|
||||
cr = *inptr2;
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
y = GETJSAMPLE(*inptr0);
|
||||
y = *inptr0;
|
||||
r = range_limit[DITHER_565_R(y + cred, d0)];
|
||||
g = range_limit[DITHER_565_G(y + cgreen, d0)];
|
||||
b = range_limit[DITHER_565_B(y + cblue, d0)];
|
||||
@@ -189,20 +189,20 @@ h2v2_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
/* Loop for each group of output pixels */
|
||||
for (col = cinfo->output_width >> 1; col > 0; col--) {
|
||||
/* Do the chroma part of the calculation */
|
||||
cb = GETJSAMPLE(*inptr1++);
|
||||
cr = GETJSAMPLE(*inptr2++);
|
||||
cb = *inptr1++;
|
||||
cr = *inptr2++;
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
|
||||
/* Fetch 4 Y values and emit 4 pixels */
|
||||
y = GETJSAMPLE(*inptr00++);
|
||||
y = *inptr00++;
|
||||
r = range_limit[y + cred];
|
||||
g = range_limit[y + cgreen];
|
||||
b = range_limit[y + cblue];
|
||||
rgb = PACK_SHORT_565(r, g, b);
|
||||
|
||||
y = GETJSAMPLE(*inptr00++);
|
||||
y = *inptr00++;
|
||||
r = range_limit[y + cred];
|
||||
g = range_limit[y + cgreen];
|
||||
b = range_limit[y + cblue];
|
||||
@@ -211,13 +211,13 @@ h2v2_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
WRITE_TWO_PIXELS(outptr0, rgb);
|
||||
outptr0 += 4;
|
||||
|
||||
y = GETJSAMPLE(*inptr01++);
|
||||
y = *inptr01++;
|
||||
r = range_limit[y + cred];
|
||||
g = range_limit[y + cgreen];
|
||||
b = range_limit[y + cblue];
|
||||
rgb = PACK_SHORT_565(r, g, b);
|
||||
|
||||
y = GETJSAMPLE(*inptr01++);
|
||||
y = *inptr01++;
|
||||
r = range_limit[y + cred];
|
||||
g = range_limit[y + cgreen];
|
||||
b = range_limit[y + cblue];
|
||||
@@ -229,20 +229,20 @@ h2v2_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
|
||||
/* If image width is odd, do the last output column separately */
|
||||
if (cinfo->output_width & 1) {
|
||||
cb = GETJSAMPLE(*inptr1);
|
||||
cr = GETJSAMPLE(*inptr2);
|
||||
cb = *inptr1;
|
||||
cr = *inptr2;
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
|
||||
y = GETJSAMPLE(*inptr00);
|
||||
y = *inptr00;
|
||||
r = range_limit[y + cred];
|
||||
g = range_limit[y + cgreen];
|
||||
b = range_limit[y + cblue];
|
||||
rgb = PACK_SHORT_565(r, g, b);
|
||||
*(INT16 *)outptr0 = (INT16)rgb;
|
||||
|
||||
y = GETJSAMPLE(*inptr01);
|
||||
y = *inptr01;
|
||||
r = range_limit[y + cred];
|
||||
g = range_limit[y + cgreen];
|
||||
b = range_limit[y + cblue];
|
||||
@@ -287,21 +287,21 @@ h2v2_merged_upsample_565D_internal(j_decompress_ptr cinfo,
|
||||
/* Loop for each group of output pixels */
|
||||
for (col = cinfo->output_width >> 1; col > 0; col--) {
|
||||
/* Do the chroma part of the calculation */
|
||||
cb = GETJSAMPLE(*inptr1++);
|
||||
cr = GETJSAMPLE(*inptr2++);
|
||||
cb = *inptr1++;
|
||||
cr = *inptr2++;
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
|
||||
/* Fetch 4 Y values and emit 4 pixels */
|
||||
y = GETJSAMPLE(*inptr00++);
|
||||
y = *inptr00++;
|
||||
r = range_limit[DITHER_565_R(y + cred, d0)];
|
||||
g = range_limit[DITHER_565_G(y + cgreen, d0)];
|
||||
b = range_limit[DITHER_565_B(y + cblue, d0)];
|
||||
d0 = DITHER_ROTATE(d0);
|
||||
rgb = PACK_SHORT_565(r, g, b);
|
||||
|
||||
y = GETJSAMPLE(*inptr00++);
|
||||
y = *inptr00++;
|
||||
r = range_limit[DITHER_565_R(y + cred, d0)];
|
||||
g = range_limit[DITHER_565_G(y + cgreen, d0)];
|
||||
b = range_limit[DITHER_565_B(y + cblue, d0)];
|
||||
@@ -311,14 +311,14 @@ h2v2_merged_upsample_565D_internal(j_decompress_ptr cinfo,
|
||||
WRITE_TWO_PIXELS(outptr0, rgb);
|
||||
outptr0 += 4;
|
||||
|
||||
y = GETJSAMPLE(*inptr01++);
|
||||
y = *inptr01++;
|
||||
r = range_limit[DITHER_565_R(y + cred, d1)];
|
||||
g = range_limit[DITHER_565_G(y + cgreen, d1)];
|
||||
b = range_limit[DITHER_565_B(y + cblue, d1)];
|
||||
d1 = DITHER_ROTATE(d1);
|
||||
rgb = PACK_SHORT_565(r, g, b);
|
||||
|
||||
y = GETJSAMPLE(*inptr01++);
|
||||
y = *inptr01++;
|
||||
r = range_limit[DITHER_565_R(y + cred, d1)];
|
||||
g = range_limit[DITHER_565_G(y + cgreen, d1)];
|
||||
b = range_limit[DITHER_565_B(y + cblue, d1)];
|
||||
@@ -331,20 +331,20 @@ h2v2_merged_upsample_565D_internal(j_decompress_ptr cinfo,
|
||||
|
||||
/* If image width is odd, do the last output column separately */
|
||||
if (cinfo->output_width & 1) {
|
||||
cb = GETJSAMPLE(*inptr1);
|
||||
cr = GETJSAMPLE(*inptr2);
|
||||
cb = *inptr1;
|
||||
cr = *inptr2;
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
|
||||
y = GETJSAMPLE(*inptr00);
|
||||
y = *inptr00;
|
||||
r = range_limit[DITHER_565_R(y + cred, d0)];
|
||||
g = range_limit[DITHER_565_G(y + cgreen, d0)];
|
||||
b = range_limit[DITHER_565_B(y + cblue, d0)];
|
||||
rgb = PACK_SHORT_565(r, g, b);
|
||||
*(INT16 *)outptr0 = (INT16)rgb;
|
||||
|
||||
y = GETJSAMPLE(*inptr01);
|
||||
y = *inptr01;
|
||||
r = range_limit[DITHER_565_R(y + cred, d1)];
|
||||
g = range_limit[DITHER_565_G(y + cgreen, d1)];
|
||||
b = range_limit[DITHER_565_B(y + cblue, d1)];
|
||||
|
||||
+17
-17
@@ -46,13 +46,13 @@ h2v1_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
/* Loop for each pair of output pixels */
|
||||
for (col = cinfo->output_width >> 1; col > 0; col--) {
|
||||
/* Do the chroma part of the calculation */
|
||||
cb = GETJSAMPLE(*inptr1++);
|
||||
cr = GETJSAMPLE(*inptr2++);
|
||||
cb = *inptr1++;
|
||||
cr = *inptr2++;
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
/* Fetch 2 Y values and emit 2 pixels */
|
||||
y = GETJSAMPLE(*inptr0++);
|
||||
y = *inptr0++;
|
||||
outptr[RGB_RED] = range_limit[y + cred];
|
||||
outptr[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr[RGB_BLUE] = range_limit[y + cblue];
|
||||
@@ -60,7 +60,7 @@ h2v1_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
outptr[RGB_ALPHA] = 0xFF;
|
||||
#endif
|
||||
outptr += RGB_PIXELSIZE;
|
||||
y = GETJSAMPLE(*inptr0++);
|
||||
y = *inptr0++;
|
||||
outptr[RGB_RED] = range_limit[y + cred];
|
||||
outptr[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr[RGB_BLUE] = range_limit[y + cblue];
|
||||
@@ -71,12 +71,12 @@ h2v1_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
}
|
||||
/* If image width is odd, do the last output column separately */
|
||||
if (cinfo->output_width & 1) {
|
||||
cb = GETJSAMPLE(*inptr1);
|
||||
cr = GETJSAMPLE(*inptr2);
|
||||
cb = *inptr1;
|
||||
cr = *inptr2;
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
y = GETJSAMPLE(*inptr0);
|
||||
y = *inptr0;
|
||||
outptr[RGB_RED] = range_limit[y + cred];
|
||||
outptr[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr[RGB_BLUE] = range_limit[y + cblue];
|
||||
@@ -120,13 +120,13 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
/* Loop for each group of output pixels */
|
||||
for (col = cinfo->output_width >> 1; col > 0; col--) {
|
||||
/* Do the chroma part of the calculation */
|
||||
cb = GETJSAMPLE(*inptr1++);
|
||||
cr = GETJSAMPLE(*inptr2++);
|
||||
cb = *inptr1++;
|
||||
cr = *inptr2++;
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
/* Fetch 4 Y values and emit 4 pixels */
|
||||
y = GETJSAMPLE(*inptr00++);
|
||||
y = *inptr00++;
|
||||
outptr0[RGB_RED] = range_limit[y + cred];
|
||||
outptr0[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr0[RGB_BLUE] = range_limit[y + cblue];
|
||||
@@ -134,7 +134,7 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
outptr0[RGB_ALPHA] = 0xFF;
|
||||
#endif
|
||||
outptr0 += RGB_PIXELSIZE;
|
||||
y = GETJSAMPLE(*inptr00++);
|
||||
y = *inptr00++;
|
||||
outptr0[RGB_RED] = range_limit[y + cred];
|
||||
outptr0[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr0[RGB_BLUE] = range_limit[y + cblue];
|
||||
@@ -142,7 +142,7 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
outptr0[RGB_ALPHA] = 0xFF;
|
||||
#endif
|
||||
outptr0 += RGB_PIXELSIZE;
|
||||
y = GETJSAMPLE(*inptr01++);
|
||||
y = *inptr01++;
|
||||
outptr1[RGB_RED] = range_limit[y + cred];
|
||||
outptr1[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr1[RGB_BLUE] = range_limit[y + cblue];
|
||||
@@ -150,7 +150,7 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
outptr1[RGB_ALPHA] = 0xFF;
|
||||
#endif
|
||||
outptr1 += RGB_PIXELSIZE;
|
||||
y = GETJSAMPLE(*inptr01++);
|
||||
y = *inptr01++;
|
||||
outptr1[RGB_RED] = range_limit[y + cred];
|
||||
outptr1[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr1[RGB_BLUE] = range_limit[y + cblue];
|
||||
@@ -161,19 +161,19 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
}
|
||||
/* If image width is odd, do the last output column separately */
|
||||
if (cinfo->output_width & 1) {
|
||||
cb = GETJSAMPLE(*inptr1);
|
||||
cr = GETJSAMPLE(*inptr2);
|
||||
cb = *inptr1;
|
||||
cr = *inptr2;
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
y = GETJSAMPLE(*inptr00);
|
||||
y = *inptr00;
|
||||
outptr0[RGB_RED] = range_limit[y + cred];
|
||||
outptr0[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr0[RGB_BLUE] = range_limit[y + cblue];
|
||||
#ifdef RGB_ALPHA
|
||||
outptr0[RGB_ALPHA] = 0xFF;
|
||||
#endif
|
||||
y = GETJSAMPLE(*inptr01);
|
||||
y = *inptr01;
|
||||
outptr1[RGB_RED] = range_limit[y + cred];
|
||||
outptr1[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr1[RGB_BLUE] = range_limit[y + cblue];
|
||||
|
||||
Vendored
+20
-28
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1995-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2015-2016, 2018, D. R. Commander.
|
||||
* Copyright (C) 2015-2016, 2018-2021, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -41,25 +41,6 @@ typedef struct {
|
||||
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
|
||||
} savable_state;
|
||||
|
||||
/* This macro is to work around compilers with missing or broken
|
||||
* structure assignment. You'll need to fix this code if you have
|
||||
* such a compiler and you change MAX_COMPS_IN_SCAN.
|
||||
*/
|
||||
|
||||
#ifndef NO_STRUCT_ASSIGN
|
||||
#define ASSIGN_STATE(dest, src) ((dest) = (src))
|
||||
#else
|
||||
#if MAX_COMPS_IN_SCAN == 4
|
||||
#define ASSIGN_STATE(dest, src) \
|
||||
((dest).EOBRUN = (src).EOBRUN, \
|
||||
(dest).last_dc_val[0] = (src).last_dc_val[0], \
|
||||
(dest).last_dc_val[1] = (src).last_dc_val[1], \
|
||||
(dest).last_dc_val[2] = (src).last_dc_val[2], \
|
||||
(dest).last_dc_val[3] = (src).last_dc_val[3])
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_entropy_decoder pub; /* public fields */
|
||||
|
||||
@@ -102,7 +83,7 @@ start_pass_phuff_decoder(j_decompress_ptr cinfo)
|
||||
boolean is_DC_band, bad;
|
||||
int ci, coefi, tbl;
|
||||
d_derived_tbl **pdtbl;
|
||||
int *coef_bit_ptr;
|
||||
int *coef_bit_ptr, *prev_coef_bit_ptr;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
is_DC_band = (cinfo->Ss == 0);
|
||||
@@ -143,8 +124,15 @@ start_pass_phuff_decoder(j_decompress_ptr cinfo)
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
int cindex = cinfo->cur_comp_info[ci]->component_index;
|
||||
coef_bit_ptr = &cinfo->coef_bits[cindex][0];
|
||||
prev_coef_bit_ptr = &cinfo->coef_bits[cindex + cinfo->num_components][0];
|
||||
if (!is_DC_band && coef_bit_ptr[0] < 0) /* AC without prior DC scan */
|
||||
WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0);
|
||||
for (coefi = MIN(cinfo->Ss, 1); coefi <= MAX(cinfo->Se, 9); coefi++) {
|
||||
if (cinfo->input_scan_number > 1)
|
||||
prev_coef_bit_ptr[coefi] = coef_bit_ptr[coefi];
|
||||
else
|
||||
prev_coef_bit_ptr[coefi] = 0;
|
||||
}
|
||||
for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) {
|
||||
int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi];
|
||||
if (cinfo->Ah != expected)
|
||||
@@ -323,7 +311,7 @@ decode_mcu_DC_first(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
|
||||
/* Load up working state */
|
||||
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
|
||||
ASSIGN_STATE(state, entropy->saved);
|
||||
state = entropy->saved;
|
||||
|
||||
/* Outer loop handles each block in the MCU */
|
||||
|
||||
@@ -356,11 +344,12 @@ decode_mcu_DC_first(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
|
||||
/* Completed MCU, so update state */
|
||||
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
|
||||
ASSIGN_STATE(entropy->saved, state);
|
||||
entropy->saved = state;
|
||||
}
|
||||
|
||||
/* Account for restart interval (no-op if not using restarts) */
|
||||
entropy->restarts_to_go--;
|
||||
if (cinfo->restart_interval)
|
||||
entropy->restarts_to_go--;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -444,7 +433,8 @@ decode_mcu_AC_first(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
}
|
||||
|
||||
/* Account for restart interval (no-op if not using restarts) */
|
||||
entropy->restarts_to_go--;
|
||||
if (cinfo->restart_interval)
|
||||
entropy->restarts_to_go--;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -495,7 +485,8 @@ decode_mcu_DC_refine(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
|
||||
|
||||
/* Account for restart interval (no-op if not using restarts) */
|
||||
entropy->restarts_to_go--;
|
||||
if (cinfo->restart_interval)
|
||||
entropy->restarts_to_go--;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -638,7 +629,8 @@ decode_mcu_AC_refine(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
}
|
||||
|
||||
/* Account for restart interval (no-op if not using restarts) */
|
||||
entropy->restarts_to_go--;
|
||||
if (cinfo->restart_interval)
|
||||
entropy->restarts_to_go--;
|
||||
|
||||
return TRUE;
|
||||
|
||||
@@ -676,7 +668,7 @@ jinit_phuff_decoder(j_decompress_ptr cinfo)
|
||||
/* Create progression status table */
|
||||
cinfo->coef_bits = (int (*)[DCTSIZE2])
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
cinfo->num_components * DCTSIZE2 *
|
||||
cinfo->num_components * 2 * DCTSIZE2 *
|
||||
sizeof(int));
|
||||
coef_bit_ptr = &cinfo->coef_bits[0][0];
|
||||
for (ci = 0; ci < cinfo->num_components; ci++)
|
||||
|
||||
+22
-16
@@ -8,7 +8,7 @@
|
||||
* Copyright (C) 2010, 2015-2016, D. R. Commander.
|
||||
* Copyright (C) 2014, MIPS Technologies, Inc., California.
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
* Copyright (C) 2019, Arm Limited.
|
||||
* Copyright (C) 2019-2020, Arm Limited.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -177,7 +177,7 @@ int_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
outptr = output_data[outrow];
|
||||
outend = outptr + cinfo->output_width;
|
||||
while (outptr < outend) {
|
||||
invalue = *inptr++; /* don't need GETJSAMPLE() here */
|
||||
invalue = *inptr++;
|
||||
for (h = h_expand; h > 0; h--) {
|
||||
*outptr++ = invalue;
|
||||
}
|
||||
@@ -213,7 +213,7 @@ h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
outptr = output_data[inrow];
|
||||
outend = outptr + cinfo->output_width;
|
||||
while (outptr < outend) {
|
||||
invalue = *inptr++; /* don't need GETJSAMPLE() here */
|
||||
invalue = *inptr++;
|
||||
*outptr++ = invalue;
|
||||
*outptr++ = invalue;
|
||||
}
|
||||
@@ -242,7 +242,7 @@ h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
outptr = output_data[outrow];
|
||||
outend = outptr + cinfo->output_width;
|
||||
while (outptr < outend) {
|
||||
invalue = *inptr++; /* don't need GETJSAMPLE() here */
|
||||
invalue = *inptr++;
|
||||
*outptr++ = invalue;
|
||||
*outptr++ = invalue;
|
||||
}
|
||||
@@ -283,20 +283,20 @@ h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
inptr = input_data[inrow];
|
||||
outptr = output_data[inrow];
|
||||
/* Special case for first column */
|
||||
invalue = GETJSAMPLE(*inptr++);
|
||||
invalue = *inptr++;
|
||||
*outptr++ = (JSAMPLE)invalue;
|
||||
*outptr++ = (JSAMPLE)((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
|
||||
*outptr++ = (JSAMPLE)((invalue * 3 + inptr[0] + 2) >> 2);
|
||||
|
||||
for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
|
||||
/* General case: 3/4 * nearer pixel + 1/4 * further pixel */
|
||||
invalue = GETJSAMPLE(*inptr++) * 3;
|
||||
*outptr++ = (JSAMPLE)((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);
|
||||
*outptr++ = (JSAMPLE)((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
|
||||
invalue = (*inptr++) * 3;
|
||||
*outptr++ = (JSAMPLE)((invalue + inptr[-2] + 1) >> 2);
|
||||
*outptr++ = (JSAMPLE)((invalue + inptr[0] + 2) >> 2);
|
||||
}
|
||||
|
||||
/* Special case for last column */
|
||||
invalue = GETJSAMPLE(*inptr);
|
||||
*outptr++ = (JSAMPLE)((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);
|
||||
invalue = *inptr;
|
||||
*outptr++ = (JSAMPLE)((invalue * 3 + inptr[-1] + 1) >> 2);
|
||||
*outptr++ = (JSAMPLE)invalue;
|
||||
}
|
||||
}
|
||||
@@ -338,7 +338,7 @@ h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
outptr = output_data[outrow++];
|
||||
|
||||
for (colctr = 0; colctr < compptr->downsampled_width; colctr++) {
|
||||
thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
|
||||
thiscolsum = (*inptr0++) * 3 + (*inptr1++);
|
||||
*outptr++ = (JSAMPLE)((thiscolsum + bias) >> 2);
|
||||
}
|
||||
}
|
||||
@@ -381,8 +381,8 @@ h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
outptr = output_data[outrow++];
|
||||
|
||||
/* Special case for first column */
|
||||
thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
|
||||
nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
|
||||
thiscolsum = (*inptr0++) * 3 + (*inptr1++);
|
||||
nextcolsum = (*inptr0++) * 3 + (*inptr1++);
|
||||
*outptr++ = (JSAMPLE)((thiscolsum * 4 + 8) >> 4);
|
||||
*outptr++ = (JSAMPLE)((thiscolsum * 3 + nextcolsum + 7) >> 4);
|
||||
lastcolsum = thiscolsum; thiscolsum = nextcolsum;
|
||||
@@ -390,7 +390,7 @@ h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
|
||||
/* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
|
||||
/* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
|
||||
nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
|
||||
nextcolsum = (*inptr0++) * 3 + (*inptr1++);
|
||||
*outptr++ = (JSAMPLE)((thiscolsum * 3 + lastcolsum + 8) >> 4);
|
||||
*outptr++ = (JSAMPLE)((thiscolsum * 3 + nextcolsum + 7) >> 4);
|
||||
lastcolsum = thiscolsum; thiscolsum = nextcolsum;
|
||||
@@ -477,7 +477,13 @@ jinit_upsampler(j_decompress_ptr cinfo)
|
||||
} else if (h_in_group == h_out_group &&
|
||||
v_in_group * 2 == v_out_group && do_fancy) {
|
||||
/* Non-fancy upsampling is handled by the generic method */
|
||||
upsample->methods[ci] = h1v2_fancy_upsample;
|
||||
#if defined(__arm__) || defined(__aarch64__) || \
|
||||
defined(_M_ARM) || defined(_M_ARM64)
|
||||
if (jsimd_can_h1v2_fancy_upsample())
|
||||
upsample->methods[ci] = jsimd_h1v2_fancy_upsample;
|
||||
else
|
||||
#endif
|
||||
upsample->methods[ci] = h1v2_fancy_upsample;
|
||||
upsample->pub.need_context_rows = TRUE;
|
||||
} else if (h_in_group * 2 == h_out_group &&
|
||||
v_in_group * 2 == v_out_group) {
|
||||
|
||||
Vendored
+13
@@ -207,6 +207,10 @@ JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code")
|
||||
#endif
|
||||
#endif
|
||||
JMESSAGE(JWRN_BOGUS_ICC, "Corrupt JPEG data: bad ICC marker")
|
||||
#if JPEG_LIB_VERSION < 70
|
||||
JMESSAGE(JERR_BAD_DROP_SAMPLING,
|
||||
"Component index %d: mismatching sampling ratio %d:%d, %d:%d, %c")
|
||||
#endif
|
||||
|
||||
#ifdef JMAKE_ENUM_LIST
|
||||
|
||||
@@ -252,6 +256,15 @@ JMESSAGE(JWRN_BOGUS_ICC, "Corrupt JPEG data: bad ICC marker")
|
||||
(cinfo)->err->msg_parm.i[2] = (p3), \
|
||||
(cinfo)->err->msg_parm.i[3] = (p4), \
|
||||
(*(cinfo)->err->error_exit) ((j_common_ptr)(cinfo)))
|
||||
#define ERREXIT6(cinfo, code, p1, p2, p3, p4, p5, p6) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
||||
(cinfo)->err->msg_parm.i[2] = (p3), \
|
||||
(cinfo)->err->msg_parm.i[3] = (p4), \
|
||||
(cinfo)->err->msg_parm.i[4] = (p5), \
|
||||
(cinfo)->err->msg_parm.i[5] = (p6), \
|
||||
(*(cinfo)->err->error_exit) ((j_common_ptr)(cinfo)))
|
||||
#define ERREXITS(cinfo, code, str) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
|
||||
|
||||
+4
-4
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* Modification developed 2002-2009 by Guido Vollbeding.
|
||||
* Modification developed 2002-2018 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2015, 2020, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
@@ -417,7 +417,7 @@ jpeg_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients,
|
||||
* producing a 7x7 output block.
|
||||
* producing a reduced-size 7x7 output block.
|
||||
*
|
||||
* Optimized algorithm with 12 multiplications in the 1-D kernel.
|
||||
* cK represents sqrt(2) * cos(K*pi/14).
|
||||
@@ -1258,7 +1258,7 @@ jpeg_idct_10x10(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients,
|
||||
* producing a 11x11 output block.
|
||||
* producing an 11x11 output block.
|
||||
*
|
||||
* Optimized algorithm with 24 multiplications in the 1-D kernel.
|
||||
* cK represents sqrt(2) * cos(K*pi/22).
|
||||
@@ -2398,7 +2398,7 @@ jpeg_idct_16x16(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
tmp0 = DEQUANTIZE(inptr[DCTSIZE * 0], quantptr[DCTSIZE * 0]);
|
||||
tmp0 = LEFT_SHIFT(tmp0, CONST_BITS);
|
||||
/* Add fudge factor here for final descale. */
|
||||
tmp0 += 1 << (CONST_BITS - PASS1_BITS - 1);
|
||||
tmp0 += ONE << (CONST_BITS - PASS1_BITS - 1);
|
||||
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE * 4], quantptr[DCTSIZE * 4]);
|
||||
tmp1 = MULTIPLY(z1, FIX(1.306562965)); /* c4[16] = c2[8] */
|
||||
|
||||
-35
@@ -43,25 +43,11 @@
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
/* JSAMPLE should be the smallest type that will hold the values 0..255.
|
||||
* You can use a signed char by having GETJSAMPLE mask it with 0xFF.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_UNSIGNED_CHAR
|
||||
|
||||
typedef unsigned char JSAMPLE;
|
||||
#define GETJSAMPLE(value) ((int)(value))
|
||||
|
||||
#else /* not HAVE_UNSIGNED_CHAR */
|
||||
|
||||
typedef char JSAMPLE;
|
||||
#ifdef __CHAR_UNSIGNED__
|
||||
#define GETJSAMPLE(value) ((int)(value))
|
||||
#else
|
||||
#define GETJSAMPLE(value) ((int)(value) & 0xFF)
|
||||
#endif /* __CHAR_UNSIGNED__ */
|
||||
|
||||
#endif /* HAVE_UNSIGNED_CHAR */
|
||||
|
||||
#define MAXJSAMPLE 255
|
||||
#define CENTERJSAMPLE 128
|
||||
|
||||
@@ -97,22 +83,9 @@ typedef short JCOEF;
|
||||
* managers, this is also the data type passed to fread/fwrite.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_UNSIGNED_CHAR
|
||||
|
||||
typedef unsigned char JOCTET;
|
||||
#define GETJOCTET(value) (value)
|
||||
|
||||
#else /* not HAVE_UNSIGNED_CHAR */
|
||||
|
||||
typedef char JOCTET;
|
||||
#ifdef __CHAR_UNSIGNED__
|
||||
#define GETJOCTET(value) (value)
|
||||
#else
|
||||
#define GETJOCTET(value) ((value) & 0xFF)
|
||||
#endif /* __CHAR_UNSIGNED__ */
|
||||
|
||||
#endif /* HAVE_UNSIGNED_CHAR */
|
||||
|
||||
|
||||
/* These typedefs are used for various table entries and so forth.
|
||||
* They must be at least as wide as specified; but making them too big
|
||||
@@ -123,15 +96,7 @@ typedef char JOCTET;
|
||||
|
||||
/* UINT8 must hold at least the values 0..255. */
|
||||
|
||||
#ifdef HAVE_UNSIGNED_CHAR
|
||||
typedef unsigned char UINT8;
|
||||
#else /* not HAVE_UNSIGNED_CHAR */
|
||||
#ifdef __CHAR_UNSIGNED__
|
||||
typedef char UINT8;
|
||||
#else /* not __CHAR_UNSIGNED__ */
|
||||
typedef short UINT8;
|
||||
#endif /* __CHAR_UNSIGNED__ */
|
||||
#endif /* HAVE_UNSIGNED_CHAR */
|
||||
|
||||
/* UINT16 must hold at least the values 0..65535. */
|
||||
|
||||
|
||||
Vendored
+4
-1
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 1997-2009 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2015-2016, D. R. Commander.
|
||||
* Copyright (C) 2015-2016, 2019, D. R. Commander.
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
@@ -158,6 +158,9 @@ struct jpeg_decomp_master {
|
||||
JDIMENSION first_MCU_col[MAX_COMPONENTS];
|
||||
JDIMENSION last_MCU_col[MAX_COMPONENTS];
|
||||
boolean jinit_upsampler_no_alloc;
|
||||
|
||||
/* Last iMCU row that was successfully decoded */
|
||||
JDIMENSION last_good_iMCU_row;
|
||||
};
|
||||
|
||||
/* Input control module */
|
||||
|
||||
Vendored
+12
-15
@@ -479,7 +479,7 @@ color_quantize(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
for (col = width; col > 0; col--) {
|
||||
pixcode = 0;
|
||||
for (ci = 0; ci < nc; ci++) {
|
||||
pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]);
|
||||
pixcode += colorindex[ci][*ptrin++];
|
||||
}
|
||||
*ptrout++ = (JSAMPLE)pixcode;
|
||||
}
|
||||
@@ -506,9 +506,9 @@ color_quantize3(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
ptrin = input_buf[row];
|
||||
ptrout = output_buf[row];
|
||||
for (col = width; col > 0; col--) {
|
||||
pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]);
|
||||
pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]);
|
||||
pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]);
|
||||
pixcode = colorindex0[*ptrin++];
|
||||
pixcode += colorindex1[*ptrin++];
|
||||
pixcode += colorindex2[*ptrin++];
|
||||
*ptrout++ = (JSAMPLE)pixcode;
|
||||
}
|
||||
}
|
||||
@@ -552,7 +552,7 @@ quantize_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
* required amount of padding.
|
||||
*/
|
||||
*output_ptr +=
|
||||
colorindex_ci[GETJSAMPLE(*input_ptr) + dither[col_index]];
|
||||
colorindex_ci[*input_ptr + dither[col_index]];
|
||||
input_ptr += nc;
|
||||
output_ptr++;
|
||||
col_index = (col_index + 1) & ODITHER_MASK;
|
||||
@@ -595,12 +595,9 @@ quantize3_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
col_index = 0;
|
||||
|
||||
for (col = width; col > 0; col--) {
|
||||
pixcode =
|
||||
GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) + dither0[col_index]]);
|
||||
pixcode +=
|
||||
GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) + dither1[col_index]]);
|
||||
pixcode +=
|
||||
GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) + dither2[col_index]]);
|
||||
pixcode = colorindex0[(*input_ptr++) + dither0[col_index]];
|
||||
pixcode += colorindex1[(*input_ptr++) + dither1[col_index]];
|
||||
pixcode += colorindex2[(*input_ptr++) + dither2[col_index]];
|
||||
*output_ptr++ = (JSAMPLE)pixcode;
|
||||
col_index = (col_index + 1) & ODITHER_MASK;
|
||||
}
|
||||
@@ -677,15 +674,15 @@ quantize_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
* The maximum error is +- MAXJSAMPLE; this sets the required size
|
||||
* of the range_limit array.
|
||||
*/
|
||||
cur += GETJSAMPLE(*input_ptr);
|
||||
cur = GETJSAMPLE(range_limit[cur]);
|
||||
cur += *input_ptr;
|
||||
cur = range_limit[cur];
|
||||
/* Select output value, accumulate into output code for this pixel */
|
||||
pixcode = GETJSAMPLE(colorindex_ci[cur]);
|
||||
pixcode = colorindex_ci[cur];
|
||||
*output_ptr += (JSAMPLE)pixcode;
|
||||
/* Compute actual representation error at this pixel */
|
||||
/* Note: we can do this even though we don't have the final */
|
||||
/* pixel code, because the colormap is orthogonal. */
|
||||
cur -= GETJSAMPLE(colormap_ci[pixcode]);
|
||||
cur -= colormap_ci[pixcode];
|
||||
/* Compute error fractions to be propagated to adjacent pixels.
|
||||
* Add these into the running sums, and simultaneously shift the
|
||||
* next-line error sums left by 1 column.
|
||||
|
||||
Vendored
+23
-23
@@ -215,9 +215,9 @@ prescan_quantize(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
ptr = input_buf[row];
|
||||
for (col = width; col > 0; col--) {
|
||||
/* get pixel value and index into the histogram */
|
||||
histp = &histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT]
|
||||
[GETJSAMPLE(ptr[1]) >> C1_SHIFT]
|
||||
[GETJSAMPLE(ptr[2]) >> C2_SHIFT];
|
||||
histp = &histogram[ptr[0] >> C0_SHIFT]
|
||||
[ptr[1] >> C1_SHIFT]
|
||||
[ptr[2] >> C2_SHIFT];
|
||||
/* increment, check for overflow and undo increment if so. */
|
||||
if (++(*histp) <= 0)
|
||||
(*histp)--;
|
||||
@@ -665,7 +665,7 @@ find_nearby_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
|
||||
|
||||
for (i = 0; i < numcolors; i++) {
|
||||
/* We compute the squared-c0-distance term, then add in the other two. */
|
||||
x = GETJSAMPLE(cinfo->colormap[0][i]);
|
||||
x = cinfo->colormap[0][i];
|
||||
if (x < minc0) {
|
||||
tdist = (x - minc0) * C0_SCALE;
|
||||
min_dist = tdist * tdist;
|
||||
@@ -688,7 +688,7 @@ find_nearby_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
|
||||
}
|
||||
}
|
||||
|
||||
x = GETJSAMPLE(cinfo->colormap[1][i]);
|
||||
x = cinfo->colormap[1][i];
|
||||
if (x < minc1) {
|
||||
tdist = (x - minc1) * C1_SCALE;
|
||||
min_dist += tdist * tdist;
|
||||
@@ -710,7 +710,7 @@ find_nearby_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
|
||||
}
|
||||
}
|
||||
|
||||
x = GETJSAMPLE(cinfo->colormap[2][i]);
|
||||
x = cinfo->colormap[2][i];
|
||||
if (x < minc2) {
|
||||
tdist = (x - minc2) * C2_SCALE;
|
||||
min_dist += tdist * tdist;
|
||||
@@ -788,13 +788,13 @@ find_best_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
|
||||
#define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE)
|
||||
|
||||
for (i = 0; i < numcolors; i++) {
|
||||
icolor = GETJSAMPLE(colorlist[i]);
|
||||
icolor = colorlist[i];
|
||||
/* Compute (square of) distance from minc0/c1/c2 to this color */
|
||||
inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE;
|
||||
inc0 = (minc0 - cinfo->colormap[0][icolor]) * C0_SCALE;
|
||||
dist0 = inc0 * inc0;
|
||||
inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE;
|
||||
inc1 = (minc1 - cinfo->colormap[1][icolor]) * C1_SCALE;
|
||||
dist0 += inc1 * inc1;
|
||||
inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE;
|
||||
inc2 = (minc2 - cinfo->colormap[2][icolor]) * C2_SCALE;
|
||||
dist0 += inc2 * inc2;
|
||||
/* Form the initial difference increments */
|
||||
inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0;
|
||||
@@ -879,7 +879,7 @@ fill_inverse_cmap(j_decompress_ptr cinfo, int c0, int c1, int c2)
|
||||
for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) {
|
||||
cachep = &histogram[c0 + ic0][c1 + ic1][c2];
|
||||
for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) {
|
||||
*cachep++ = (histcell)(GETJSAMPLE(*cptr++) + 1);
|
||||
*cachep++ = (histcell)((*cptr++) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -909,9 +909,9 @@ pass2_no_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
outptr = output_buf[row];
|
||||
for (col = width; col > 0; col--) {
|
||||
/* get pixel value and index into the cache */
|
||||
c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT;
|
||||
c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT;
|
||||
c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT;
|
||||
c0 = (*inptr++) >> C0_SHIFT;
|
||||
c1 = (*inptr++) >> C1_SHIFT;
|
||||
c2 = (*inptr++) >> C2_SHIFT;
|
||||
cachep = &histogram[c0][c1][c2];
|
||||
/* If we have not seen this color before, find nearest colormap entry */
|
||||
/* and update the cache */
|
||||
@@ -996,12 +996,12 @@ pass2_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
* The maximum error is +- MAXJSAMPLE (or less with error limiting);
|
||||
* this sets the required size of the range_limit array.
|
||||
*/
|
||||
cur0 += GETJSAMPLE(inptr[0]);
|
||||
cur1 += GETJSAMPLE(inptr[1]);
|
||||
cur2 += GETJSAMPLE(inptr[2]);
|
||||
cur0 = GETJSAMPLE(range_limit[cur0]);
|
||||
cur1 = GETJSAMPLE(range_limit[cur1]);
|
||||
cur2 = GETJSAMPLE(range_limit[cur2]);
|
||||
cur0 += inptr[0];
|
||||
cur1 += inptr[1];
|
||||
cur2 += inptr[2];
|
||||
cur0 = range_limit[cur0];
|
||||
cur1 = range_limit[cur1];
|
||||
cur2 = range_limit[cur2];
|
||||
/* Index into the cache with adjusted pixel value */
|
||||
cachep =
|
||||
&histogram[cur0 >> C0_SHIFT][cur1 >> C1_SHIFT][cur2 >> C2_SHIFT];
|
||||
@@ -1015,9 +1015,9 @@ pass2_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
register int pixcode = *cachep - 1;
|
||||
*outptr = (JSAMPLE)pixcode;
|
||||
/* Compute representation error for this pixel */
|
||||
cur0 -= GETJSAMPLE(colormap0[pixcode]);
|
||||
cur1 -= GETJSAMPLE(colormap1[pixcode]);
|
||||
cur2 -= GETJSAMPLE(colormap2[pixcode]);
|
||||
cur0 -= colormap0[pixcode];
|
||||
cur1 -= colormap1[pixcode];
|
||||
cur2 -= colormap2[pixcode];
|
||||
}
|
||||
/* Compute error fractions to be propagated to adjacent pixels.
|
||||
* Add these into the running sums, and simultaneously shift the
|
||||
|
||||
Vendored
+6
@@ -4,6 +4,7 @@
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2011, 2014, D. R. Commander.
|
||||
* Copyright (C) 2015-2016, 2018, Matthieu Darbois.
|
||||
* Copyright (C) 2020, Arm Limited.
|
||||
*
|
||||
* Based on the x86 SIMD extension for IJG JPEG library,
|
||||
* Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
@@ -75,6 +76,7 @@ EXTERN(void) jsimd_int_upsample(j_decompress_ptr cinfo,
|
||||
|
||||
EXTERN(int) jsimd_can_h2v2_fancy_upsample(void);
|
||||
EXTERN(int) jsimd_can_h2v1_fancy_upsample(void);
|
||||
EXTERN(int) jsimd_can_h1v2_fancy_upsample(void);
|
||||
|
||||
EXTERN(void) jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr,
|
||||
@@ -84,6 +86,10 @@ EXTERN(void) jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data,
|
||||
JSAMPARRAY *output_data_ptr);
|
||||
EXTERN(void) jsimd_h1v2_fancy_upsample(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data,
|
||||
JSAMPARRAY *output_data_ptr);
|
||||
|
||||
EXTERN(int) jsimd_can_h2v2_merged_upsample(void);
|
||||
EXTERN(int) jsimd_can_h2v1_merged_upsample(void);
|
||||
|
||||
+13
@@ -4,6 +4,7 @@
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2009-2011, 2014, D. R. Commander.
|
||||
* Copyright (C) 2015-2016, 2018, Matthieu Darbois.
|
||||
* Copyright (C) 2020, Arm Limited.
|
||||
*
|
||||
* Based on the x86 SIMD extension for IJG JPEG library,
|
||||
* Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
@@ -169,6 +170,12 @@ jsimd_can_h2v1_fancy_upsample(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h1v2_fancy_upsample(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
@@ -181,6 +188,12 @@ jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h2v2_merged_upsample(void)
|
||||
{
|
||||
|
||||
+6
-6
@@ -2,9 +2,9 @@
|
||||
* jversion.h
|
||||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding.
|
||||
* Copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010, 2012-2020, D. R. Commander.
|
||||
* Copyright (C) 2010, 2012-2021, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -37,9 +37,9 @@
|
||||
*/
|
||||
|
||||
#define JCOPYRIGHT \
|
||||
"Copyright (C) 2009-2020 D. R. Commander\n" \
|
||||
"Copyright (C) 2009-2021 D. R. Commander\n" \
|
||||
"Copyright (C) 2015, 2020 Google, Inc.\n" \
|
||||
"Copyright (C) 2019 Arm Limited\n" \
|
||||
"Copyright (C) 2019-2020 Arm Limited\n" \
|
||||
"Copyright (C) 2015-2016, 2018 Matthieu Darbois\n" \
|
||||
"Copyright (C) 2011-2016 Siarhei Siamashka\n" \
|
||||
"Copyright (C) 2015 Intel Corporation\n" \
|
||||
@@ -48,7 +48,7 @@
|
||||
"Copyright (C) 2009, 2012 Pierre Ossman for Cendio AB\n" \
|
||||
"Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)\n" \
|
||||
"Copyright (C) 1999-2006 MIYASAKA Masaru\n" \
|
||||
"Copyright (C) 1991-2017 Thomas G. Lane, Guido Vollbeding"
|
||||
"Copyright (C) 1991-2020 Thomas G. Lane, Guido Vollbeding"
|
||||
|
||||
#define JCOPYRIGHT_SHORT \
|
||||
"Copyright (C) 1991-2020 The libjpeg-turbo Project and many others"
|
||||
"Copyright (C) 1991-2021 The libjpeg-turbo Project and many others"
|
||||
|
||||
Vendored
+9
-5
@@ -923,6 +923,11 @@ int ovx_hal_cvtGraytoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep,
|
||||
}
|
||||
|
||||
int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx)
|
||||
{
|
||||
return ovx_hal_cvtTwoPlaneYUVtoBGREx(a, astep, a + h * astep, astep, b, bstep, w, h, bcn, swapBlue, uIdx);
|
||||
}
|
||||
|
||||
int ovx_hal_cvtTwoPlaneYUVtoBGREx(const uchar * a, size_t astep, const uchar * b, size_t bstep, uchar * c, size_t cstep, int w, int h, int bcn, bool swapBlue, int uIdx)
|
||||
{
|
||||
if (skipSmallImages<VX_KERNEL_COLOR_CONVERT>(w, h))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
@@ -933,8 +938,7 @@ int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t
|
||||
|
||||
if (w & 1 || h & 1) // It's not described in spec but sample implementation unable to convert odd sized images
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
refineStep(w, h, uIdx ? VX_DF_IMAGE_NV21 : VX_DF_IMAGE_NV12, astep);
|
||||
refineStep(w, h, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, bstep);
|
||||
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
@@ -943,8 +947,8 @@ int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t
|
||||
std::vector<void *> ptrs;
|
||||
addr.push_back(ivx::Image::createAddressing(w, h, 1, (vx_int32)astep));
|
||||
ptrs.push_back((void*)a);
|
||||
addr.push_back(ivx::Image::createAddressing(w / 2, h / 2, 2, (vx_int32)astep));
|
||||
ptrs.push_back((void*)(a + h * astep));
|
||||
addr.push_back(ivx::Image::createAddressing(w / 2, h / 2, 2, (vx_int32)bstep));
|
||||
ptrs.push_back((void*)b);
|
||||
|
||||
vxImage
|
||||
ia = ivx::Image::createFromHandle(ctx, uIdx ? VX_DF_IMAGE_NV21 : VX_DF_IMAGE_NV12, addr, ptrs);
|
||||
@@ -952,7 +956,7 @@ int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED; // OpenCV store NV12/NV21 as RANGE_RESTRICTED while OpenVX expect RANGE_FULL
|
||||
vxImage
|
||||
ib = ivx::Image::createFromHandle(ctx, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX,
|
||||
ivx::Image::createAddressing(w, h, bcn, (vx_int32)bstep), b);
|
||||
ivx::Image::createAddressing(w, h, bcn, (vx_int32)cstep), c);
|
||||
ivx::IVX_CHECK_STATUS(vxuColorConvert(ctx, ia, ib));
|
||||
}
|
||||
catch (ivx::RuntimeError & e)
|
||||
|
||||
Vendored
+3
@@ -49,6 +49,7 @@ int ovx_hal_morph(cvhalFilter2D *filter_context, uchar *a, size_t astep, uchar *
|
||||
int ovx_hal_cvtBGRtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int acn, int bcn, bool swapBlue);
|
||||
int ovx_hal_cvtGraytoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int bcn);
|
||||
int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx);
|
||||
int ovx_hal_cvtTwoPlaneYUVtoBGREx(const uchar * a, size_t astep, const uchar * b, size_t bstep, uchar * c, size_t cstep, int w, int h, int bcn, bool swapBlue, int uIdx);
|
||||
int ovx_hal_cvtThreePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx);
|
||||
int ovx_hal_cvtBGRtoThreePlaneYUV(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int acn, bool swapBlue, int uIdx);
|
||||
int ovx_hal_cvtOnePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx, int ycn);
|
||||
@@ -130,6 +131,8 @@ int ovx_hal_integral(int depth, int sdepth, int, const uchar * a, size_t astep,
|
||||
#define cv_hal_cvtGraytoBGR ovx_hal_cvtGraytoBGR
|
||||
#undef cv_hal_cvtTwoPlaneYUVtoBGR
|
||||
#define cv_hal_cvtTwoPlaneYUVtoBGR ovx_hal_cvtTwoPlaneYUVtoBGR
|
||||
#undef cv_hal_cvtTwoPlaneYUVtoBGREx
|
||||
#define cv_hal_cvtTwoPlaneYUVtoBGREx ovx_hal_cvtTwoPlaneYUVtoBGREx
|
||||
#undef cv_hal_cvtThreePlaneYUVtoBGR
|
||||
#define cv_hal_cvtThreePlaneYUVtoBGR ovx_hal_cvtThreePlaneYUVtoBGR
|
||||
#undef cv_hal_cvtBGRtoThreePlaneYUV
|
||||
|
||||
Vendored
+4
-2
@@ -31,7 +31,7 @@ libpng Portable Network Graphics library.
|
||||
libtiff Tag Image File Format (TIFF) Software
|
||||
Copyright (c) 1988-1997 Sam Leffler
|
||||
Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
See libtiff home page http://www.remotesensing.org/libtiff/
|
||||
See libtiff home page http://www.libtiff.org/
|
||||
for details and links to the source code
|
||||
|
||||
WITH_TIFF CMake option must be ON to add libtiff & zlib support to imgcodecs.
|
||||
@@ -51,7 +51,9 @@ jasper JasPer is a collection of software
|
||||
Copyright (c) 1999-2000 The University of British Columbia
|
||||
Copyright (c) 2001-2003 Michael David Adams
|
||||
|
||||
The JasPer license can be found in libjasper.
|
||||
See JasPer official GitHub repository
|
||||
https://github.com/jasper-software/jasper.git
|
||||
for details and links to source code
|
||||
------------------------------------------------------------------------------------
|
||||
openexr OpenEXR is a high dynamic-range (HDR) image file format developed
|
||||
by Industrial Light & Magic for use in computer imaging applications.
|
||||
|
||||
+12
-5
@@ -648,6 +648,8 @@ if(UNIX)
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} m pthread)
|
||||
elseif(EMSCRIPTEN)
|
||||
# no need to link to system libs with emscripten
|
||||
elseif(QNXNTO)
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} m)
|
||||
else()
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} dl m pthread rt)
|
||||
endif()
|
||||
@@ -1230,12 +1232,17 @@ status("")
|
||||
status(" GUI: ")
|
||||
|
||||
if(WITH_QT OR HAVE_QT)
|
||||
if(HAVE_QT5)
|
||||
status(" QT:" "YES (ver ${Qt5Core_VERSION_STRING})")
|
||||
status(" QT OpenGL support:" HAVE_QT_OPENGL THEN "YES (${Qt5OpenGL_LIBRARIES} ${Qt5OpenGL_VERSION_STRING})" ELSE NO)
|
||||
elseif(HAVE_QT)
|
||||
if(HAVE_QT)
|
||||
status(" QT:" "YES (ver ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH} ${QT_EDITION})")
|
||||
status(" QT OpenGL support:" HAVE_QT_OPENGL THEN "YES (${QT_QTOPENGL_LIBRARY})" ELSE NO)
|
||||
if(HAVE_QT_OPENGL)
|
||||
if(Qt${QT_VERSION_MAJOR}OpenGL_LIBRARIES)
|
||||
status(" QT OpenGL support:" HAVE_QT_OPENGL THEN "YES (${Qt${QT_VERSION_MAJOR}OpenGL_LIBRARIES} ${Qt${QT_VERSION_MAJOR}OpenGL_VERSION_STRING})" ELSE NO)
|
||||
else()
|
||||
status(" QT OpenGL support:" HAVE_QT_OPENGL THEN "YES (${QT_QTOPENGL_LIBRARY})" ELSE NO)
|
||||
endif()
|
||||
else()
|
||||
status(" QT OpenGL support:" "NO")
|
||||
endif()
|
||||
else()
|
||||
status(" QT:" "NO")
|
||||
endif()
|
||||
|
||||
@@ -177,7 +177,13 @@ if(CV_GCC OR CV_CLANG)
|
||||
endif()
|
||||
|
||||
# We need pthread's
|
||||
if(UNIX AND NOT ANDROID AND NOT (APPLE AND CV_CLANG)) # TODO
|
||||
if((UNIX
|
||||
AND NOT ANDROID
|
||||
AND NOT (APPLE AND CV_CLANG)
|
||||
AND NOT EMSCRIPTEN
|
||||
)
|
||||
OR (EMSCRIPTEN AND WITH_PTHREADS_PF) # https://github.com/opencv/opencv/issues/20285
|
||||
)
|
||||
add_extra_compiler_option(-pthread)
|
||||
endif()
|
||||
|
||||
@@ -225,9 +231,11 @@ if(CV_GCC OR CV_CLANG)
|
||||
if(APPLE)
|
||||
set(OPENCV_EXTRA_EXE_LINKER_FLAGS "${OPENCV_EXTRA_EXE_LINKER_FLAGS} -Wl,-dead_strip")
|
||||
set(OPENCV_EXTRA_SHARED_LINKER_FLAGS "${OPENCV_EXTRA_SHARED_LINKER_FLAGS} -Wl,-dead_strip")
|
||||
set(OPENCV_EXTRA_MODULE_LINKER_FLAGS "${OPENCV_EXTRA_MODULE_LINKER_FLAGS} -Wl,-dead_strip")
|
||||
else()
|
||||
set(OPENCV_EXTRA_EXE_LINKER_FLAGS "${OPENCV_EXTRA_EXE_LINKER_FLAGS} -Wl,--gc-sections")
|
||||
set(OPENCV_EXTRA_SHARED_LINKER_FLAGS "${OPENCV_EXTRA_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
|
||||
set(OPENCV_EXTRA_MODULE_LINKER_FLAGS "${OPENCV_EXTRA_MODULE_LINKER_FLAGS} -Wl,--gc-sections")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
@@ -279,6 +287,7 @@ if(MSVC)
|
||||
set(OPENCV_EXTRA_FLAGS_RELEASE "${OPENCV_EXTRA_FLAGS_RELEASE} /Zi")
|
||||
set(OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE "${OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE} /debug")
|
||||
set(OPENCV_EXTRA_SHARED_LINKER_FLAGS_RELEASE "${OPENCV_EXTRA_SHARED_LINKER_FLAGS_RELEASE} /debug")
|
||||
set(OPENCV_EXTRA_MODULE_LINKER_FLAGS_RELEASE "${OPENCV_EXTRA_MODULE_LINKER_FLAGS_RELEASE} /debug")
|
||||
endif()
|
||||
|
||||
# Remove unreferenced functions: function level linking
|
||||
@@ -346,6 +355,7 @@ if(NOT OPENCV_SKIP_LINK_AS_NEEDED)
|
||||
if(HAVE_LINK_AS_NEEDED)
|
||||
set(OPENCV_EXTRA_EXE_LINKER_FLAGS "${OPENCV_EXTRA_EXE_LINKER_FLAGS} ${_option}")
|
||||
set(OPENCV_EXTRA_SHARED_LINKER_FLAGS "${OPENCV_EXTRA_SHARED_LINKER_FLAGS} ${_option}")
|
||||
set(OPENCV_EXTRA_MODULE_LINKER_FLAGS "${OPENCV_EXTRA_MODULE_LINKER_FLAGS} ${_option}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
@@ -364,6 +374,9 @@ if(NOT OPENCV_SKIP_EXTRA_COMPILER_FLAGS)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${OPENCV_EXTRA_SHARED_LINKER_FLAGS}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} ${OPENCV_EXTRA_SHARED_LINKER_FLAGS_RELEASE}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} ${OPENCV_EXTRA_SHARED_LINKER_FLAGS_DEBUG}")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${OPENCV_EXTRA_MODULE_LINKER_FLAGS}")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} ${OPENCV_EXTRA_MODULE_LINKER_FLAGS_RELEASE}")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} ${OPENCV_EXTRA_MODULE_LINKER_FLAGS_DEBUG}")
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
@@ -387,6 +400,9 @@ if(MSVC)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Enable [[attribute]] syntax checking to prevent silent failure: "attribute is ignored in this syntactic position"
|
||||
add_extra_compiler_option("/w15240")
|
||||
|
||||
if(NOT ENABLE_NOISY_WARNINGS)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127) # conditional expression is constant
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4251) # class 'std::XXX' needs to have dll-interface to be used by clients of YYY
|
||||
|
||||
@@ -102,7 +102,7 @@ if(CUDA_FOUND)
|
||||
if(CUDA_GENERATION)
|
||||
if(NOT ";${_generations};" MATCHES ";${CUDA_GENERATION};")
|
||||
string(REPLACE ";" ", " _generations "${_generations}")
|
||||
message(FATAL_ERROR "ERROR: ${_generations} Generations are suppered.")
|
||||
message(FATAL_ERROR "ERROR: ${_generations} Generations are supported.")
|
||||
endif()
|
||||
unset(CUDA_ARCH_BIN CACHE)
|
||||
unset(CUDA_ARCH_PTX CACHE)
|
||||
|
||||
@@ -169,6 +169,8 @@ elseif(MSVC)
|
||||
set(OpenCV_RUNTIME vc15)
|
||||
elseif(MSVC_VERSION MATCHES "^192[0-9]$")
|
||||
set(OpenCV_RUNTIME vc16)
|
||||
elseif(MSVC_VERSION MATCHES "^193[0-9]$")
|
||||
set(OpenCV_RUNTIME vc17)
|
||||
else()
|
||||
message(WARNING "OpenCV does not recognize MSVC_VERSION \"${MSVC_VERSION}\". Cannot set OpenCV_RUNTIME")
|
||||
endif()
|
||||
|
||||
@@ -9,9 +9,14 @@ set(HALIDE_ROOT_DIR "${HALIDE_ROOT_DIR}" CACHE PATH "Halide root directory")
|
||||
if(NOT HAVE_HALIDE)
|
||||
find_package(Halide QUIET) # Try CMake-based config files
|
||||
if(Halide_FOUND)
|
||||
set(HALIDE_INCLUDE_DIRS "${Halide_INCLUDE_DIRS}" CACHE PATH "Halide include directories" FORCE)
|
||||
set(HALIDE_LIBRARIES "${Halide_LIBRARIES}" CACHE PATH "Halide libraries" FORCE)
|
||||
set(HAVE_HALIDE TRUE)
|
||||
if(TARGET Halide::Halide) # modern Halide scripts defines imported target
|
||||
set(HALIDE_INCLUDE_DIRS "")
|
||||
set(HALIDE_LIBRARIES "Halide::Halide")
|
||||
set(HAVE_HALIDE TRUE)
|
||||
else()
|
||||
# using HALIDE_INCLUDE_DIRS / Halide_LIBRARIES
|
||||
set(HAVE_HALIDE TRUE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -28,18 +33,15 @@ if(NOT HAVE_HALIDE AND HALIDE_ROOT_DIR)
|
||||
)
|
||||
if(HALIDE_LIBRARY AND HALIDE_INCLUDE_DIR)
|
||||
# TODO try_compile
|
||||
set(HALIDE_INCLUDE_DIRS "${HALIDE_INCLUDE_DIR}" CACHE PATH "Halide include directories" FORCE)
|
||||
set(HALIDE_LIBRARIES "${HALIDE_LIBRARY}" CACHE PATH "Halide libraries" FORCE)
|
||||
set(HALIDE_INCLUDE_DIRS "${HALIDE_INCLUDE_DIR}")
|
||||
set(HALIDE_LIBRARIES "${HALIDE_LIBRARY}")
|
||||
set(HAVE_HALIDE TRUE)
|
||||
endif()
|
||||
if(NOT HAVE_HALIDE)
|
||||
ocv_clear_vars(HALIDE_LIBRARIES HALIDE_INCLUDE_DIRS CACHE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(HAVE_HALIDE)
|
||||
include_directories(${HALIDE_INCLUDE_DIRS})
|
||||
if(HALIDE_INCLUDE_DIRS)
|
||||
include_directories(${HALIDE_INCLUDE_DIRS})
|
||||
endif()
|
||||
list(APPEND OPENCV_LINKER_LIBS ${HALIDE_LIBRARIES})
|
||||
else()
|
||||
ocv_clear_vars(HALIDE_INCLUDE_DIRS HALIDE_LIBRARIES)
|
||||
endif()
|
||||
|
||||
@@ -105,6 +105,20 @@ if(InferenceEngine_FOUND)
|
||||
message(STATUS "Detected InferenceEngine: cmake package (${InferenceEngine_VERSION})")
|
||||
endif()
|
||||
|
||||
if(DEFINED InferenceEngine_VERSION)
|
||||
message(STATUS "InferenceEngine: ${InferenceEngine_VERSION}")
|
||||
if(NOT INF_ENGINE_RELEASE AND NOT (InferenceEngine_VERSION VERSION_LESS "2021.4"))
|
||||
math(EXPR INF_ENGINE_RELEASE_INIT "${InferenceEngine_VERSION_MAJOR} * 1000000 + ${InferenceEngine_VERSION_MINOR} * 10000 + ${InferenceEngine_VERSION_PATCH} * 100")
|
||||
endif()
|
||||
endif()
|
||||
if(NOT INF_ENGINE_RELEASE AND NOT INF_ENGINE_RELEASE_INIT)
|
||||
message(STATUS "WARNING: InferenceEngine version has not been set, 2021.4.1 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
|
||||
set(INF_ENGINE_RELEASE_INIT "2021040100")
|
||||
elseif(DEFINED INF_ENGINE_RELEASE)
|
||||
set(INF_ENGINE_RELEASE_INIT "${INF_ENGINE_RELEASE}")
|
||||
endif()
|
||||
set(INF_ENGINE_RELEASE "${INF_ENGINE_RELEASE_INIT}" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2020.1.0.2 -> 2020010002)")
|
||||
|
||||
if(NOT INF_ENGINE_TARGET AND INF_ENGINE_LIB_DIRS AND INF_ENGINE_INCLUDE_DIRS)
|
||||
find_path(ie_custom_inc "inference_engine.hpp" PATHS "${INF_ENGINE_INCLUDE_DIRS}" NO_DEFAULT_PATH)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
@@ -140,12 +154,8 @@ endif()
|
||||
# Add more features to the target
|
||||
|
||||
if(INF_ENGINE_TARGET)
|
||||
if(NOT INF_ENGINE_RELEASE)
|
||||
message(WARNING "InferenceEngine version has not been set, 2021.3 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
|
||||
endif()
|
||||
set(INF_ENGINE_RELEASE "2021030000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2020.1.0.2 -> 2020010002)")
|
||||
set_target_properties(${INF_ENGINE_TARGET} PROPERTIES
|
||||
INTERFACE_COMPILE_DEFINITIONS "HAVE_INF_ENGINE=1;INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}"
|
||||
INTERFACE_COMPILE_DEFINITIONS "HAVE_INF_ENGINE=1;INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}"
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -26,31 +26,14 @@ if(VTK_VERSION VERSION_LESS "5.8.0")
|
||||
endif()
|
||||
|
||||
# Different Qt versions can't be linked together
|
||||
if(HAVE_QT5 AND VTK_VERSION VERSION_LESS "6.0.0")
|
||||
if(VTK_USE_QT)
|
||||
message(STATUS "VTK support is disabled. Incompatible combination: OpenCV + Qt5 and VTK ver.${VTK_VERSION} + Qt4")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Different Qt versions can't be linked together. VTK 6.0.0 doesn't provide a way to get Qt version it was linked with
|
||||
if(HAVE_QT5 AND VTK_VERSION VERSION_EQUAL "6.0.0" AND NOT DEFINED FORCE_VTK)
|
||||
message(STATUS "VTK support is disabled. Possible incompatible combination: OpenCV+Qt5, and VTK ver.${VTK_VERSION} with Qt4")
|
||||
message(STATUS "If it is known that VTK was compiled without Qt4, please define '-DFORCE_VTK=TRUE' flag in CMake")
|
||||
if((HAVE_QT AND VTK_USE_QT)
|
||||
AND NOT DEFINED FORCE_VTK # deprecated
|
||||
AND NOT DEFINED OPENCV_FORCE_VTK
|
||||
)
|
||||
message(STATUS "VTK support is disabled. Possible incompatible combination: OpenCV+Qt, and VTK ver.${VTK_VERSION} with Qt")
|
||||
message(STATUS "If it is known that VTK was compiled without Qt4, please define '-DOPENCV_FORCE_VTK=TRUE' flag in CMake")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Different Qt versions can't be linked together
|
||||
if(HAVE_QT AND VTK_VERSION VERSION_GREATER "6.0.0" AND NOT ${VTK_QT_VERSION} STREQUAL "")
|
||||
if(HAVE_QT5 AND ${VTK_QT_VERSION} EQUAL "4")
|
||||
message(STATUS "VTK support is disabled. Incompatible combination: OpenCV + Qt5 and VTK ver.${VTK_VERSION} + Qt4")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_QT5 AND ${VTK_QT_VERSION} EQUAL "5")
|
||||
message(STATUS "VTK support is disabled. Incompatible combination: OpenCV + Qt4 and VTK ver.${VTK_VERSION} + Qt5")
|
||||
return()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(HAVE_VTK ON)
|
||||
message(STATUS "Found VTK ${VTK_VERSION} (${VTK_USE_FILE})")
|
||||
|
||||
@@ -23,7 +23,7 @@ set(OPENCV_DOWNLOAD_LOG "${OpenCV_BINARY_DIR}/CMakeDownloadLog.txt")
|
||||
set(OPENCV_DOWNLOAD_WITH_CURL "${OpenCV_BINARY_DIR}/download_with_curl.sh")
|
||||
set(OPENCV_DOWNLOAD_WITH_WGET "${OpenCV_BINARY_DIR}/download_with_wget.sh")
|
||||
set(OPENCV_DOWNLOAD_TRIES_LIST 1 CACHE STRING "List of download tries") # a list
|
||||
set(OPENCV_DOWNLOAD_PARAMS INACTIVITY_TIMEOUT 60 TIMEOUT 600 CACHE STRING "Download parameters to be passed to file(DOWNLAOD ...)")
|
||||
set(OPENCV_DOWNLOAD_PARAMS INACTIVITY_TIMEOUT 60 TIMEOUT 600 CACHE STRING "Download parameters to be passed to file(DOWNLOAD ...)")
|
||||
mark_as_advanced(OPENCV_DOWNLOAD_TRIES_LIST OPENCV_DOWNLOAD_PARAMS)
|
||||
|
||||
# Init download cache directory and log file and helper scripts
|
||||
|
||||
@@ -151,7 +151,7 @@ macro(ipp_detect_version)
|
||||
if("${name}" STREQUAL "core") # https://github.com/opencv/opencv/pull/19681
|
||||
if(OPENCV_FORCE_IPP_EXCLUDE_LIBS OR OPENCV_FORCE_IPP_EXCLUDE_LIBS_CORE
|
||||
OR (UNIX AND NOT ANDROID AND NOT APPLE
|
||||
AND (CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|Intel"
|
||||
)
|
||||
AND NOT OPENCV_SKIP_IPP_EXCLUDE_LIBS_CORE
|
||||
)
|
||||
|
||||
@@ -11,25 +11,50 @@ if(WITH_WIN32UI)
|
||||
CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=user32;gdi32")
|
||||
endif()
|
||||
|
||||
# --- QT4 ---
|
||||
ocv_clear_vars(HAVE_QT HAVE_QT5)
|
||||
if(WITH_QT)
|
||||
if(NOT WITH_QT EQUAL 4)
|
||||
find_package(Qt5 COMPONENTS Core Gui Widgets Test Concurrent REQUIRED NO_MODULE)
|
||||
if(Qt5_FOUND)
|
||||
set(HAVE_QT5 ON)
|
||||
set(HAVE_QT ON)
|
||||
find_package(Qt5 COMPONENTS OpenGL QUIET)
|
||||
if(Qt5OpenGL_FOUND)
|
||||
set(QT_QTOPENGL_FOUND ON)
|
||||
endif()
|
||||
endif()
|
||||
macro(ocv_find_package_Qt4)
|
||||
find_package(Qt4 COMPONENTS QtCore QtGui QtTest ${ARGN})
|
||||
if(QT4_FOUND)
|
||||
set(QT_FOUND 1)
|
||||
ocv_assert(QT_VERSION_MAJOR EQUAL 4)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
if(NOT HAVE_QT)
|
||||
find_package(Qt4 REQUIRED QtCore QtGui QtTest)
|
||||
if(QT4_FOUND)
|
||||
set(HAVE_QT TRUE)
|
||||
macro(ocv_find_package_Qt OCV_QT_VER)
|
||||
find_package(Qt${OCV_QT_VER} COMPONENTS Core Gui Widgets Test Concurrent ${ARGN} NO_MODULE)
|
||||
if(Qt${OCV_QT_VER}_FOUND)
|
||||
set(QT_FOUND 1)
|
||||
set(QT_VERSION "${Qt${OCV_QT_VER}_VERSION}")
|
||||
set(QT_VERSION_MAJOR "${Qt${OCV_QT_VER}_VERSION_MAJOR}")
|
||||
set(QT_VERSION_MINOR "${Qt${OCV_QT_VER}_VERSION_MINOR}")
|
||||
set(QT_VERSION_PATCH "${Qt${OCV_QT_VER}_VERSION_PATCH}")
|
||||
set(QT_VERSION_TWEAK "${Qt${OCV_QT_VER}_VERSION_TWEAK}")
|
||||
set(QT_VERSION_COUNT "${Qt${OCV_QT_VER}_VERSION_COUNT}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# --- QT4 ---
|
||||
if(WITH_QT)
|
||||
if(NOT WITH_QT GREATER 0)
|
||||
# BUG: Qt5Config.cmake script can't handle components properly: find_package(QT NAMES Qt6 Qt5 REQUIRED NO_MODULE COMPONENTS Core Gui Widgets Test Concurrent)
|
||||
ocv_find_package_Qt(6 QUIET)
|
||||
if(NOT QT_FOUND)
|
||||
ocv_find_package_Qt(5 QUIET)
|
||||
endif()
|
||||
if(NOT QT_FOUND)
|
||||
ocv_find_package_Qt4(QUIET)
|
||||
endif()
|
||||
elseif(WITH_QT EQUAL 4)
|
||||
ocv_find_package_Qt4(REQUIRED)
|
||||
else() # WITH_QT=<major version>
|
||||
ocv_find_package_Qt("${WITH_QT}" REQUIRED)
|
||||
endif()
|
||||
if(QT_FOUND)
|
||||
set(HAVE_QT ON)
|
||||
if(QT_VERSION_MAJOR GREATER 4)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS OpenGL QUIET)
|
||||
if(Qt${QT_VERSION_MAJOR}OpenGL_FOUND)
|
||||
set(QT_QTOPENGL_FOUND ON) # HAVE_QT_OPENGL is defined below
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -29,7 +29,7 @@ if(WITH_IPP)
|
||||
if(OPENCV_FORCE_IPP_EXCLUDE_LIBS
|
||||
OR (HAVE_IPP_ICV
|
||||
AND UNIX AND NOT ANDROID AND NOT APPLE
|
||||
AND (CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|Intel"
|
||||
)
|
||||
AND NOT OPENCV_SKIP_IPP_EXCLUDE_LIBS
|
||||
)
|
||||
|
||||
@@ -877,7 +877,9 @@ macro(_ocv_create_module)
|
||||
|
||||
ocv_compiler_optimization_process_sources(OPENCV_MODULE_${the_module}_SOURCES OPENCV_MODULE_${the_module}_DEPS_EXT ${the_module})
|
||||
set(__module_headers ${OPENCV_MODULE_${the_module}_HEADERS})
|
||||
list(SORT __module_headers) # fix headers order, useful for bindings
|
||||
if(__module_headers)
|
||||
list(SORT __module_headers) # fix headers order, useful for bindings
|
||||
endif()
|
||||
set(OPENCV_MODULE_${the_module}_HEADERS ${__module_headers} CACHE INTERNAL "List of header files for ${the_module}")
|
||||
set(OPENCV_MODULE_${the_module}_SOURCES ${OPENCV_MODULE_${the_module}_SOURCES} CACHE INTERNAL "List of source files for ${the_module}")
|
||||
|
||||
|
||||
@@ -1488,8 +1488,8 @@ function(ocv_target_link_libraries target)
|
||||
if(NOT LINK_PENDING STREQUAL "")
|
||||
__ocv_push_target_link_libraries(${LINK_MODE} ${LINK_PENDING})
|
||||
set(LINK_PENDING "")
|
||||
set(LINK_MODE "${dep}")
|
||||
endif()
|
||||
set(LINK_MODE "${dep}")
|
||||
else()
|
||||
if(BUILD_opencv_world)
|
||||
if(OPENCV_MODULE_${dep}_IS_PART_OF_WORLD)
|
||||
|
||||
@@ -137,6 +137,20 @@ elseif(MSVC)
|
||||
set(OpenCV_RUNTIME vc14) # selecting previous compatible runtime version
|
||||
endif()
|
||||
endif()
|
||||
elseif(MSVC_VERSION MATCHES "^193[0-9]$")
|
||||
set(OpenCV_RUNTIME vc17)
|
||||
check_one_config(has_VS2022)
|
||||
if(NOT has_VS2022)
|
||||
set(OpenCV_RUNTIME vc16)
|
||||
check_one_config(has_VS2019)
|
||||
if(NOT has_VS2019)
|
||||
set(OpenCV_RUNTIME vc15) # selecting previous compatible runtime version
|
||||
check_one_config(has_VS2017)
|
||||
if(NOT has_VS2017)
|
||||
set(OpenCV_RUNTIME vc14) # selecting previous compatible runtime version
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
elseif(MINGW)
|
||||
set(OpenCV_RUNTIME mingw)
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ MULTILINE_CPP_IS_BRIEF = NO
|
||||
INHERIT_DOCS = YES
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 4
|
||||
ALIASES += add_toggle{1}="@htmlonly[block] <div class='newInnerHTML'>\1</div><div> <script type="text/javascript"> addToggle(); </script>@endhtmlonly"
|
||||
ALIASES += add_toggle{1}="@htmlonly[block] <div class='newInnerHTML'>\1</div><div> <script type='text/javascript'> addToggle(); </script>@endhtmlonly"
|
||||
ALIASES += add_toggle_cpp="@htmlonly[block] <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'>@endhtmlonly"
|
||||
ALIASES += add_toggle_java="@htmlonly[block] <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'>@endhtmlonly"
|
||||
ALIASES += add_toggle_python="@htmlonly[block] <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'>@endhtmlonly"
|
||||
|
||||
+3
@@ -1,6 +1,9 @@
|
||||
Contour Features {#tutorial_js_contour_features}
|
||||
================
|
||||
|
||||
@prev_tutorial{tutorial_js_contours_begin}
|
||||
@next_tutorial{tutorial_js_contour_properties}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
+3
@@ -1,6 +1,9 @@
|
||||
Contour Properties {#tutorial_js_contour_properties}
|
||||
==================
|
||||
|
||||
@prev_tutorial{tutorial_js_contour_features}
|
||||
@next_tutorial{tutorial_js_contours_more_functions}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
Contours : Getting Started {#tutorial_js_contours_begin}
|
||||
==========================
|
||||
|
||||
@next_tutorial{tutorial_js_contour_features}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
+2
@@ -1,6 +1,8 @@
|
||||
Contours Hierarchy {#tutorial_js_contours_hierarchy}
|
||||
==================
|
||||
|
||||
@prev_tutorial{tutorial_js_contours_more_functions}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
+3
@@ -1,6 +1,9 @@
|
||||
Contours : More Functions {#tutorial_js_contours_more_functions}
|
||||
=========================
|
||||
|
||||
@prev_tutorial{tutorial_js_contour_properties}
|
||||
@next_tutorial{tutorial_js_contours_hierarchy}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
+4
-4
@@ -835,12 +835,12 @@
|
||||
journal = {IEEE Transactions on Robotics and Automation},
|
||||
title = {Robot sensor calibration: solving AX=XB on the Euclidean group},
|
||||
year = {1994},
|
||||
month = oct,
|
||||
volume = {10},
|
||||
number = {5},
|
||||
pages = {717-721},
|
||||
doi = {10.1109/70.326576},
|
||||
ISSN = {1042-296X},
|
||||
month = {Oct}
|
||||
issn = {1042-296X}
|
||||
}
|
||||
@inproceedings{PM03,
|
||||
author = {P{\'e}rez, Patrick and Gangnet, Michel and Blake, Andrew},
|
||||
@@ -1028,12 +1028,12 @@
|
||||
journal = {IEEE Transactions on Robotics and Automation},
|
||||
title = {A new technique for fully autonomous and efficient 3D robotics hand/eye calibration},
|
||||
year = {1989},
|
||||
month = jun,
|
||||
volume = {5},
|
||||
number = {3},
|
||||
pages = {345-358},
|
||||
doi = {10.1109/70.34770},
|
||||
ISSN = {1042-296X},
|
||||
month = {June}
|
||||
issn = {1042-296X}
|
||||
}
|
||||
@inproceedings{UES01,
|
||||
author = {Uyttendaele, Matthew and Eden, Ashley and Skeliski, R},
|
||||
|
||||
@@ -98,7 +98,7 @@ import numpy as np
|
||||
import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('simple.jpg',0)
|
||||
img = cv.imread('blox.jpg',0) # `<opencv_root>/samples/data/blox.jpg`
|
||||
|
||||
# Initiate FAST object with default values
|
||||
fast = cv.FastFeatureDetector_create()
|
||||
@@ -113,17 +113,17 @@ print( "nonmaxSuppression:{}".format(fast.getNonmaxSuppression()) )
|
||||
print( "neighborhood: {}".format(fast.getType()) )
|
||||
print( "Total Keypoints with nonmaxSuppression: {}".format(len(kp)) )
|
||||
|
||||
cv.imwrite('fast_true.png',img2)
|
||||
cv.imwrite('fast_true.png', img2)
|
||||
|
||||
# Disable nonmaxSuppression
|
||||
fast.setNonmaxSuppression(0)
|
||||
kp = fast.detect(img,None)
|
||||
kp = fast.detect(img, None)
|
||||
|
||||
print( "Total Keypoints without nonmaxSuppression: {}".format(len(kp)) )
|
||||
|
||||
img3 = cv.drawKeypoints(img, kp, None, color=(255,0,0))
|
||||
|
||||
cv.imwrite('fast_false.png',img3)
|
||||
cv.imwrite('fast_false.png', img3)
|
||||
@endcode
|
||||
See the results. First image shows FAST with nonmaxSuppression and second one without
|
||||
nonmaxSuppression:
|
||||
|
||||
@@ -40,12 +40,12 @@ using **cv.Sobel()**).
|
||||
Then comes the main part. After this, they created a score, basically an equation, which
|
||||
determines if a window can contain a corner or not.
|
||||
|
||||
\f[R = det(M) - k(trace(M))^2\f]
|
||||
\f[R = \det(M) - k(\operatorname{trace}(M))^2\f]
|
||||
|
||||
where
|
||||
- \f$det(M) = \lambda_1 \lambda_2\f$
|
||||
- \f$trace(M) = \lambda_1 + \lambda_2\f$
|
||||
- \f$\lambda_1\f$ and \f$\lambda_2\f$ are the eigenvalues of M
|
||||
- \f$\det(M) = \lambda_1 \lambda_2\f$
|
||||
- \f$\operatorname{trace}(M) = \lambda_1 + \lambda_2\f$
|
||||
- \f$\lambda_1\f$ and \f$\lambda_2\f$ are the eigenvalues of \f$M\f$
|
||||
|
||||
So the magnitudes of these eigenvalues decide whether a region is a corner, an edge, or flat.
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Harris Corner Detector. The scoring function in Harris Corner Detector was given
|
||||
|
||||
Instead of this, Shi-Tomasi proposed:
|
||||
|
||||
\f[R = min(\lambda_1, \lambda_2)\f]
|
||||
\f[R = \min(\lambda_1, \lambda_2)\f]
|
||||
|
||||
If it is a greater than a threshold value, it is considered as a corner. If we plot it in
|
||||
\f$\lambda_1 - \lambda_2\f$ space as we did in Harris Corner Detector, we get an image as below:
|
||||
@@ -28,7 +28,7 @@ If it is a greater than a threshold value, it is considered as a corner. If we p
|
||||

|
||||
|
||||
From the figure, you can see that only when \f$\lambda_1\f$ and \f$\lambda_2\f$ are above a minimum value,
|
||||
\f$\lambda_{min}\f$, it is considered as a corner(green region).
|
||||
\f$\lambda_{\min}\f$, it is considered as a corner(green region).
|
||||
|
||||
Code
|
||||
----
|
||||
|
||||
@@ -156,7 +156,7 @@ sift = cv.SIFT_create()
|
||||
kp, des = sift.detectAndCompute(gray,None)
|
||||
@endcode
|
||||
Here kp will be a list of keypoints and des is a numpy array of shape
|
||||
\f$Number\_of\_Keypoints \times 128\f$.
|
||||
\f$\text{(Number of Keypoints)} \times 128\f$.
|
||||
|
||||
So we got keypoints, descriptors etc. Now we want to see how to match keypoints in different images.
|
||||
That we will learn in coming chapters.
|
||||
|
||||
@@ -74,7 +74,7 @@ Canny Edge Detection in OpenCV
|
||||
|
||||
OpenCV puts all the above in single function, **cv.Canny()**. We will see how to use it. First
|
||||
argument is our input image. Second and third arguments are our minVal and maxVal respectively.
|
||||
Third argument is aperture_size. It is the size of Sobel kernel used for find image gradients. By
|
||||
Fourth argument is aperture_size. It is the size of Sobel kernel used for find image gradients. By
|
||||
default it is 3. Last argument is L2gradient which specifies the equation for finding gradient
|
||||
magnitude. If it is True, it uses the equation mentioned above which is more accurate, otherwise it
|
||||
uses this function: \f$Edge\_Gradient \; (G) = |G_x| + |G_y|\f$. By default, it is False.
|
||||
|
||||
+4
-1
@@ -1,6 +1,9 @@
|
||||
Contour Features {#tutorial_py_contour_features}
|
||||
================
|
||||
|
||||
@prev_tutorial{tutorial_py_contours_begin}
|
||||
@next_tutorial{tutorial_py_contour_properties}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
@@ -91,7 +94,7 @@ convexity defects, which are the local maximum deviations of hull from contours.
|
||||
|
||||
There is a little bit things to discuss about it its syntax:
|
||||
@code{.py}
|
||||
hull = cv.convexHull(points[, hull[, clockwise[, returnPoints]]
|
||||
hull = cv.convexHull(points[, hull[, clockwise[, returnPoints]]])
|
||||
@endcode
|
||||
Arguments details:
|
||||
|
||||
|
||||
+3
@@ -1,6 +1,9 @@
|
||||
Contour Properties {#tutorial_py_contour_properties}
|
||||
==================
|
||||
|
||||
@prev_tutorial{tutorial_py_contour_features}
|
||||
@next_tutorial{tutorial_py_contours_more_functions}
|
||||
|
||||
Here we will learn to extract some frequently used properties of objects like Solidity, Equivalent
|
||||
Diameter, Mask image, Mean Intensity etc. More features can be found at [Matlab regionprops
|
||||
documentation](http://www.mathworks.in/help/images/ref/regionprops.html).
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
Contours : Getting Started {#tutorial_py_contours_begin}
|
||||
==========================
|
||||
|
||||
@next_tutorial{tutorial_py_contour_features}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
+2
@@ -1,6 +1,8 @@
|
||||
Contours Hierarchy {#tutorial_py_contours_hierarchy}
|
||||
==================
|
||||
|
||||
@prev_tutorial{tutorial_py_contours_more_functions}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
+4
@@ -1,6 +1,10 @@
|
||||
Contours : More Functions {#tutorial_py_contours_more_functions}
|
||||
=========================
|
||||
|
||||
@prev_tutorial{tutorial_py_contour_properties}
|
||||
@next_tutorial{tutorial_py_contours_hierarchy}
|
||||
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -107,17 +107,10 @@ def add_signature_to_table(soup, table, signature, language, type):
|
||||
""" Add a signature to an html table"""
|
||||
row = soup.new_tag('tr')
|
||||
row.append(soup.new_tag('td', style='width: 20px;'))
|
||||
|
||||
if 'ret' in signature:
|
||||
row.append(append(soup.new_tag('td'), signature['ret']))
|
||||
row.append(append(soup.new_tag('td'), '='))
|
||||
else:
|
||||
row.append(soup.new_tag('td')) # return values
|
||||
row.append(soup.new_tag('td')) # '='
|
||||
|
||||
row.append(append(soup.new_tag('td'), signature['name'] + '('))
|
||||
row.append(append(soup.new_tag('td', **{'class': 'paramname'}), signature['arg']))
|
||||
row.append(append(soup.new_tag('td'), ')'))
|
||||
row.append(append(soup.new_tag('td'), ') -> '))
|
||||
row.append(append(soup.new_tag('td'), signature['ret']))
|
||||
table.append(row)
|
||||
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ The tutorial consists of two main programs:
|
||||
|
||||
The application starts up extracting the ORB features and descriptors from the input image and
|
||||
then uses the mesh along with the [Möller–Trumbore intersection
|
||||
algorithm](http://http://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm/)
|
||||
algorithm](http://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm/)
|
||||
to compute the 3D coordinates of the found features. Finally, the 3D points and the descriptors
|
||||
are stored in different lists in a file with YAML format which each row is a different point. The
|
||||
technical background on how to store the files can be found in the @ref tutorial_file_input_output_with_xml_yml
|
||||
|
||||
+9
-9
@@ -84,8 +84,8 @@ a new header with the new boundaries:
|
||||
Mat D (A, Rect(10, 10, 100, 100) ); // using a rectangle
|
||||
Mat E = A(Range::all(), Range(1,3)); // using row and column boundaries
|
||||
@endcode
|
||||
Now you may ask -- if the matrix itself may belong to multiple *Mat* objects who takes responsibility
|
||||
for cleaning it up when it's no longer needed. The short answer is: the last object that used it.
|
||||
Now you may ask -- if the matrix itself may belong to multiple *Mat* objects, who takes responsibility
|
||||
for cleaning it up when it's no longer needed? The short answer is: the last object that used it.
|
||||
This is handled by using a reference counting mechanism. Whenever somebody copies a header of a
|
||||
*Mat* object, a counter is increased for the matrix. Whenever a header is cleaned, this counter
|
||||
is decreased. When the counter reaches zero the matrix is freed. Sometimes you will want to copy
|
||||
@@ -95,12 +95,12 @@ Mat F = A.clone();
|
||||
Mat G;
|
||||
A.copyTo(G);
|
||||
@endcode
|
||||
Now modifying *F* or *G* will not affect the matrix pointed by the *A*'s header. What you need to
|
||||
Now modifying *F* or *G* will not affect the matrix pointed to by the *A*'s header. What you need to
|
||||
remember from all this is that:
|
||||
|
||||
- Output image allocation for OpenCV functions is automatic (unless specified otherwise).
|
||||
- You do not need to think about memory management with OpenCV's C++ interface.
|
||||
- The assignment operator and the copy constructor only copies the header.
|
||||
- The assignment operator and the copy constructor only copy the header.
|
||||
- The underlying matrix of an image may be copied using the @ref cv::Mat::clone() and @ref cv::Mat::copyTo()
|
||||
functions.
|
||||
|
||||
@@ -115,10 +115,10 @@ of these allows us to create many shades of gray.
|
||||
For *colorful* ways we have a lot more methods to choose from. Each of them breaks it down to three
|
||||
or four basic components and we can use the combination of these to create the others. The most
|
||||
popular one is RGB, mainly because this is also how our eye builds up colors. Its base colors are
|
||||
red, green and blue. To code the transparency of a color sometimes a fourth element: alpha (A) is
|
||||
red, green and blue. To code the transparency of a color sometimes a fourth element, alpha (A), is
|
||||
added.
|
||||
|
||||
There are, however, many other color systems each with their own advantages:
|
||||
There are, however, many other color systems, each with their own advantages:
|
||||
|
||||
- RGB is the most common as our eyes use something similar, however keep in mind that OpenCV standard display
|
||||
system composes colors using the BGR color space (red and blue channels are swapped places).
|
||||
@@ -132,11 +132,11 @@ There are, however, many other color systems each with their own advantages:
|
||||
Each of the building components has its own valid domains. This leads to the data type used. How
|
||||
we store a component defines the control we have over its domain. The smallest data type possible is
|
||||
*char*, which means one byte or 8 bits. This may be unsigned (so can store values from 0 to 255) or
|
||||
signed (values from -127 to +127). Although in case of three components this already gives 16
|
||||
million possible colors to represent (like in case of RGB) we may acquire an even finer control by
|
||||
signed (values from -127 to +127). Although this width, in the case of three components (like RGB), already gives 16
|
||||
million possible colors to represent, we may acquire an even finer control by
|
||||
using the float (4 byte = 32 bit) or double (8 byte = 64 bit) data types for each component.
|
||||
Nevertheless, remember that increasing the size of a component also increases the size of the whole
|
||||
picture in the memory.
|
||||
picture in memory.
|
||||
|
||||
Creating a Mat object explicitly
|
||||
----------------------------------
|
||||
|
||||
@@ -39,14 +39,14 @@ Open your Doxyfile using your favorite text editor and search for the key
|
||||
`TAGFILES`. Change it as follows:
|
||||
|
||||
@code
|
||||
TAGFILES = ./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/3.4.14
|
||||
TAGFILES = ./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/3.4.16
|
||||
@endcode
|
||||
|
||||
If you had other definitions already, you can append the line using a `\`:
|
||||
|
||||
@code
|
||||
TAGFILES = ./docs/doxygen-tags/libstdc++.tag=https://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen \
|
||||
./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/3.4.14
|
||||
./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/3.4.16
|
||||
@endcode
|
||||
|
||||
Doxygen can now use the information from the tag file to link to the OpenCV
|
||||
|
||||
@@ -10,6 +10,8 @@ Working with a boosted cascade of weak classifiers includes two major stages: th
|
||||
|
||||
To support this tutorial, several official OpenCV applications will be used: [opencv_createsamples](https://github.com/opencv/opencv/tree/3.4/apps/createsamples), [opencv_annotation](https://github.com/opencv/opencv/tree/3.4/apps/annotation), [opencv_traincascade](https://github.com/opencv/opencv/tree/3.4/apps/traincascade) and [opencv_visualisation](https://github.com/opencv/opencv/tree/3.4/apps/visualisation).
|
||||
|
||||
@note Createsamples and traincascade are disabled since OpenCV 4.0. Consider using these apps for training from 3.4 branch for Cascade Classifier. Model format is the same between 3.4 and 4.x.
|
||||
|
||||
### Important notes
|
||||
|
||||
- If you come across any tutorial mentioning the old opencv_haartraining tool <i>(which is deprecated and still using the OpenCV1.x interface)</i>, then please ignore that tutorial and stick to the opencv_traincascade tool. This tool is a newer version, written in C++ in accordance to the OpenCV 2.x and OpenCV 3.x API. The opencv_traincascade supports both HAAR like wavelet features @cite Viola01 and LBP (Local Binary Patterns) @cite Liao2007 features. LBP features yield integer precision in contrast to HAAR features, yielding floating point precision, so both training and detection with LBP are several times faster then with HAAR features. Regarding the LBP and HAAR detection quality, it mainly depends on the training data used and the training parameters selected. It's possible to train a LBP-based classifier that will provide almost the same quality as HAAR-based one, within a percentage of the training time.
|
||||
|
||||
@@ -180,7 +180,7 @@ implementation below.
|
||||
|
||||
This will return a similarity index for each channel of the image. This value is between zero and
|
||||
one, where one corresponds to perfect fit. Unfortunately, the many Gaussian blurring is quite
|
||||
costly, so while the PSNR may work in a real time like environment (24 frame per second) this will
|
||||
costly, so while the PSNR may work in a real time like environment (24 frames per second) this will
|
||||
take significantly more than to accomplish similar performance results.
|
||||
|
||||
Therefore, the source code presented at the start of the tutorial will perform the PSNR measurement
|
||||
|
||||
@@ -1510,8 +1510,8 @@ concatenated together.
|
||||
@param imageSize Size of the image used only to initialize the camera intrinsic matrix.
|
||||
@param cameraMatrix Input/output 3x3 floating-point camera intrinsic matrix
|
||||
\f$\cameramatrix{A}\f$ . If @ref CALIB_USE_INTRINSIC_GUESS
|
||||
and/or @ref CALIB_FIX_ASPECT_RATIO are specified, some or all of fx, fy, cx, cy must be
|
||||
initialized before calling the function.
|
||||
and/or @ref CALIB_FIX_ASPECT_RATIO, @ref CALIB_FIX_PRINCIPAL_POINT or @ref CALIB_FIX_FOCAL_LENGTH
|
||||
are specified, some or all of fx, fy, cx, cy must be initialized before calling the function.
|
||||
@param distCoeffs Input/output vector of distortion coefficients
|
||||
\f$\distcoeffs\f$.
|
||||
@param rvecs Output vector of rotation vectors (@ref Rodrigues ) estimated for each pattern view
|
||||
@@ -1537,7 +1537,7 @@ the number of pattern views. \f$R_i, T_i\f$ are concatenated 1x3 vectors.
|
||||
fx, fy, cx, cy that are optimized further. Otherwise, (cx, cy) is initially set to the image
|
||||
center ( imageSize is used), and focal distances are computed in a least-squares fashion.
|
||||
Note, that if intrinsic parameters are known, there is no need to use this function just to
|
||||
estimate extrinsic parameters. Use solvePnP instead.
|
||||
estimate extrinsic parameters. Use @ref solvePnP instead.
|
||||
- @ref CALIB_FIX_PRINCIPAL_POINT The principal point is not changed during the global
|
||||
optimization. It stays at the center or at a different location specified when
|
||||
@ref CALIB_USE_INTRINSIC_GUESS is set too.
|
||||
@@ -1547,24 +1547,23 @@ ratio fx/fy stays the same as in the input cameraMatrix . When
|
||||
ignored, only their ratio is computed and used further.
|
||||
- @ref CALIB_ZERO_TANGENT_DIST Tangential distortion coefficients \f$(p_1, p_2)\f$ are set
|
||||
to zeros and stay zero.
|
||||
- @ref CALIB_FIX_FOCAL_LENGTH The focal length is not changed during the global optimization if
|
||||
@ref CALIB_USE_INTRINSIC_GUESS is set.
|
||||
- @ref CALIB_FIX_K1,..., @ref CALIB_FIX_K6 The corresponding radial distortion
|
||||
coefficient is not changed during the optimization. If @ref CALIB_USE_INTRINSIC_GUESS is
|
||||
set, the coefficient from the supplied distCoeffs matrix is used. Otherwise, it is set to 0.
|
||||
- @ref CALIB_RATIONAL_MODEL Coefficients k4, k5, and k6 are enabled. To provide the
|
||||
backward compatibility, this extra flag should be explicitly specified to make the
|
||||
calibration function use the rational model and return 8 coefficients. If the flag is not
|
||||
set, the function computes and returns only 5 distortion coefficients.
|
||||
calibration function use the rational model and return 8 coefficients or more.
|
||||
- @ref CALIB_THIN_PRISM_MODEL Coefficients s1, s2, s3 and s4 are enabled. To provide the
|
||||
backward compatibility, this extra flag should be explicitly specified to make the
|
||||
calibration function use the thin prism model and return 12 coefficients. If the flag is not
|
||||
set, the function computes and returns only 5 distortion coefficients.
|
||||
calibration function use the thin prism model and return 12 coefficients or more.
|
||||
- @ref CALIB_FIX_S1_S2_S3_S4 The thin prism distortion coefficients are not changed during
|
||||
the optimization. If @ref CALIB_USE_INTRINSIC_GUESS is set, the coefficient from the
|
||||
supplied distCoeffs matrix is used. Otherwise, it is set to 0.
|
||||
- @ref CALIB_TILTED_MODEL Coefficients tauX and tauY are enabled. To provide the
|
||||
backward compatibility, this extra flag should be explicitly specified to make the
|
||||
calibration function use the tilted sensor model and return 14 coefficients. If the flag is not
|
||||
set, the function computes and returns only 5 distortion coefficients.
|
||||
calibration function use the tilted sensor model and return 14 coefficients.
|
||||
- @ref CALIB_FIX_TAUX_TAUY The coefficients of the tilted sensor model are not changed during
|
||||
the optimization. If @ref CALIB_USE_INTRINSIC_GUESS is set, the coefficient from the
|
||||
supplied distCoeffs matrix is used. Otherwise, it is set to 0.
|
||||
@@ -1589,12 +1588,12 @@ The algorithm performs the following steps:
|
||||
zeros initially unless some of CALIB_FIX_K? are specified.
|
||||
|
||||
- Estimate the initial camera pose as if the intrinsic parameters have been already known. This is
|
||||
done using solvePnP .
|
||||
done using @ref solvePnP .
|
||||
|
||||
- Run the global Levenberg-Marquardt optimization algorithm to minimize the reprojection error,
|
||||
that is, the total sum of squared distances between the observed feature points imagePoints and
|
||||
the projected (using the current estimates for camera parameters and the poses) object points
|
||||
objectPoints. See projectPoints for details.
|
||||
objectPoints. See @ref projectPoints for details.
|
||||
|
||||
@note
|
||||
If you use a non-square (i.e. non-N-by-N) grid and @ref findChessboardCorners for calibration,
|
||||
@@ -2241,6 +2240,7 @@ final fundamental matrix. It can be set to something like 1-3, depending on the
|
||||
point localization, image resolution, and the image noise.
|
||||
@param mask Output array of N elements, every element of which is set to 0 for outliers and to 1
|
||||
for the other points. The array is computed only in the RANSAC and LMedS methods.
|
||||
@param maxIters The maximum number of robust method iterations.
|
||||
|
||||
This function estimates essential matrix based on the five-point algorithm solver in @cite Nister03 .
|
||||
@cite SteweniusCFS is also a related. The epipolar geometry is described by the following equation:
|
||||
@@ -2251,6 +2251,12 @@ where \f$E\f$ is an essential matrix, \f$p_1\f$ and \f$p_2\f$ are corresponding
|
||||
second images, respectively. The result of this function may be passed further to
|
||||
decomposeEssentialMat or recoverPose to recover the relative pose between cameras.
|
||||
*/
|
||||
CV_EXPORTS_W Mat findEssentialMat( InputArray points1, InputArray points2,
|
||||
InputArray cameraMatrix, int method,
|
||||
double prob, double threshold,
|
||||
int maxIters, OutputArray mask = noArray() );
|
||||
|
||||
/** @overload */
|
||||
CV_EXPORTS_W Mat findEssentialMat( InputArray points1, InputArray points2,
|
||||
InputArray cameraMatrix, int method = RANSAC,
|
||||
double prob = 0.999, double threshold = 1.0,
|
||||
@@ -2274,6 +2280,7 @@ point localization, image resolution, and the image noise.
|
||||
confidence (probability) that the estimated matrix is correct.
|
||||
@param mask Output array of N elements, every element of which is set to 0 for outliers and to 1
|
||||
for the other points. The array is computed only in the RANSAC and LMedS methods.
|
||||
@param maxIters The maximum number of robust method iterations.
|
||||
|
||||
This function differs from the one above that it computes camera intrinsic matrix from focal length and
|
||||
principal point:
|
||||
@@ -2285,6 +2292,13 @@ f & 0 & x_{pp} \\
|
||||
0 & 0 & 1
|
||||
\end{bmatrix}\f]
|
||||
*/
|
||||
CV_EXPORTS_W Mat findEssentialMat( InputArray points1, InputArray points2,
|
||||
double focal, Point2d pp,
|
||||
int method, double prob,
|
||||
double threshold, int maxIters,
|
||||
OutputArray mask = noArray() );
|
||||
|
||||
/** @overload */
|
||||
CV_EXPORTS_W Mat findEssentialMat( InputArray points1, InputArray points2,
|
||||
double focal = 1.0, Point2d pp = Point2d(0, 0),
|
||||
int method = RANSAC, double prob = 0.999,
|
||||
|
||||
@@ -403,7 +403,8 @@ protected:
|
||||
|
||||
// Input should be a vector of n 2D points or a Nx2 matrix
|
||||
cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2, InputArray _cameraMatrix,
|
||||
int method, double prob, double threshold, OutputArray _mask)
|
||||
int method, double prob, double threshold,
|
||||
int maxIters, OutputArray _mask)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
@@ -442,20 +443,36 @@ cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2, InputArr
|
||||
|
||||
Mat E;
|
||||
if( method == RANSAC )
|
||||
createRANSACPointSetRegistrator(makePtr<EMEstimatorCallback>(), 5, threshold, prob)->run(points1, points2, E, _mask);
|
||||
createRANSACPointSetRegistrator(makePtr<EMEstimatorCallback>(), 5, threshold, prob, maxIters)->run(points1, points2, E, _mask);
|
||||
else
|
||||
createLMeDSPointSetRegistrator(makePtr<EMEstimatorCallback>(), 5, prob)->run(points1, points2, E, _mask);
|
||||
createLMeDSPointSetRegistrator(makePtr<EMEstimatorCallback>(), 5, prob, maxIters)->run(points1, points2, E, _mask);
|
||||
|
||||
return E;
|
||||
}
|
||||
|
||||
cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2, InputArray _cameraMatrix,
|
||||
int method, double prob, double threshold,
|
||||
OutputArray _mask)
|
||||
{
|
||||
return cv::findEssentialMat(_points1, _points2, _cameraMatrix, method, prob, threshold, 1000, _mask);
|
||||
}
|
||||
|
||||
cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2, double focal, Point2d pp,
|
||||
int method, double prob, double threshold, int maxIters, OutputArray _mask)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
Mat cameraMatrix = (Mat_<double>(3,3) << focal, 0, pp.x, 0, focal, pp.y, 0, 0, 1);
|
||||
return cv::findEssentialMat(_points1, _points2, cameraMatrix, method, prob, threshold, maxIters, _mask);
|
||||
}
|
||||
|
||||
cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2, double focal, Point2d pp,
|
||||
int method, double prob, double threshold, OutputArray _mask)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
Mat cameraMatrix = (Mat_<double>(3,3) << focal, 0, pp.x, 0, focal, pp.y, 0, 0, 1);
|
||||
return cv::findEssentialMat(_points1, _points2, cameraMatrix, method, prob, threshold, _mask);
|
||||
return cv::findEssentialMat(_points1, _points2, cameraMatrix, method, prob, threshold, 1000, _mask);
|
||||
}
|
||||
|
||||
int cv::recoverPose( InputArray E, InputArray _points1, InputArray _points2,
|
||||
|
||||
@@ -866,7 +866,7 @@ cv::Mat cv::findFundamentalMat( InputArray _points1, InputArray _points2,
|
||||
if( (method & ~3) == FM_RANSAC && npoints >= 15 )
|
||||
result = createRANSACPointSetRegistrator(cb, 7, ransacReprojThreshold, confidence, maxIters)->run(m1, m2, F, _mask);
|
||||
else
|
||||
result = createLMeDSPointSetRegistrator(cb, 7, confidence)->run(m1, m2, F, _mask);
|
||||
result = createLMeDSPointSetRegistrator(cb, 7, confidence, maxIters)->run(m1, m2, F, _mask);
|
||||
}
|
||||
|
||||
if( result <= 0 )
|
||||
|
||||
@@ -116,6 +116,59 @@ String dumpRange(const Range& argument)
|
||||
}
|
||||
}
|
||||
|
||||
CV_WRAP static inline
|
||||
String testReservedKeywordConversion(int positional_argument, int lambda = 2, int from = 3)
|
||||
{
|
||||
return format("arg=%d, lambda=%d, from=%d", positional_argument, lambda, from);
|
||||
}
|
||||
|
||||
CV_EXPORTS_W String dumpVectorOfInt(const std::vector<int>& vec);
|
||||
|
||||
CV_EXPORTS_W String dumpVectorOfDouble(const std::vector<double>& vec);
|
||||
|
||||
CV_EXPORTS_W String dumpVectorOfRect(const std::vector<Rect>& vec);
|
||||
|
||||
CV_WRAP static inline
|
||||
void generateVectorOfRect(size_t len, CV_OUT std::vector<Rect>& vec)
|
||||
{
|
||||
vec.resize(len);
|
||||
if (len > 0)
|
||||
{
|
||||
RNG rng(12345);
|
||||
Mat tmp(static_cast<int>(len), 1, CV_32SC4);
|
||||
rng.fill(tmp, RNG::UNIFORM, 10, 20);
|
||||
tmp.copyTo(vec);
|
||||
}
|
||||
}
|
||||
|
||||
CV_WRAP static inline
|
||||
void generateVectorOfInt(size_t len, CV_OUT std::vector<int>& vec)
|
||||
{
|
||||
vec.resize(len);
|
||||
if (len > 0)
|
||||
{
|
||||
RNG rng(554433);
|
||||
Mat tmp(static_cast<int>(len), 1, CV_32SC1);
|
||||
rng.fill(tmp, RNG::UNIFORM, -10, 10);
|
||||
tmp.copyTo(vec);
|
||||
}
|
||||
}
|
||||
|
||||
CV_WRAP static inline
|
||||
void generateVectorOfMat(size_t len, int rows, int cols, int dtype, CV_OUT std::vector<Mat>& vec)
|
||||
{
|
||||
vec.resize(len);
|
||||
if (len > 0)
|
||||
{
|
||||
RNG rng(65431);
|
||||
for (size_t i = 0; i < len; ++i)
|
||||
{
|
||||
vec[i].create(rows, cols, dtype);
|
||||
rng.fill(vec[i], RNG::UNIFORM, 0, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CV_WRAP static inline
|
||||
void testRaiseGeneralException()
|
||||
{
|
||||
|
||||
@@ -554,7 +554,7 @@ Cv64suf;
|
||||
# define CV_XADD(addr, delta) (int)_InterlockedExchangeAdd((long volatile*)addr, delta)
|
||||
#else
|
||||
#ifdef OPENCV_FORCE_UNSAFE_XADD
|
||||
CV_INLINE CV_XADD(int* addr, int delta) { int tmp = *addr; *addr += delta; return tmp; }
|
||||
CV_INLINE int CV_XADD(int* addr, int delta) { int tmp = *addr; *addr += delta; return tmp; }
|
||||
#else
|
||||
#error "OpenCV: can't define safe CV_XADD macro for current platform (unsupported). Define CV_XADD macro through custom port header (see OPENCV_INCLUDE_PORT_FILE)"
|
||||
#endif
|
||||
@@ -575,14 +575,47 @@ Cv64suf;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************************\
|
||||
* CV_NODISCARD_STD attribute (C++17) *
|
||||
* encourages the compiler to issue a warning if the return value is discarded *
|
||||
\****************************************************************************************/
|
||||
#ifndef CV_NODISCARD_STD
|
||||
# ifndef __has_cpp_attribute
|
||||
// workaround preprocessor non-compliance https://reviews.llvm.org/D57851
|
||||
# define __has_cpp_attribute(__x) 0
|
||||
# endif
|
||||
# if __has_cpp_attribute(nodiscard)
|
||||
# define CV_NODISCARD_STD [[nodiscard]]
|
||||
# elif __cplusplus >= 201703L
|
||||
// available when compiler is C++17 compliant
|
||||
# define CV_NODISCARD_STD [[nodiscard]]
|
||||
# elif defined(_MSC_VER) && _MSC_VER >= 1911 && _MSVC_LANG >= 201703L
|
||||
// available with VS2017 v15.3+ with /std:c++17 or higher; works on functions and classes
|
||||
# define CV_NODISCARD_STD [[nodiscard]]
|
||||
# elif defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 700) && (__cplusplus >= 201103L)
|
||||
// available with GCC 7.0+; works on functions, works or silently fails on classes
|
||||
# define CV_NODISCARD_STD [[nodiscard]]
|
||||
# elif defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 408) && (__cplusplus >= 201103L)
|
||||
// available with GCC 4.8+ but it usually does nothing and can fail noisily -- therefore not used
|
||||
// define CV_NODISCARD_STD [[gnu::warn_unused_result]]
|
||||
# endif
|
||||
#endif
|
||||
#ifndef CV_NODISCARD_STD
|
||||
# define CV_NODISCARD_STD /* nothing by default */
|
||||
#endif
|
||||
|
||||
|
||||
/****************************************************************************************\
|
||||
* CV_NODISCARD attribute *
|
||||
* encourages the compiler to issue a warning if the return value is discarded (C++17) *
|
||||
* CV_NODISCARD attribute (deprecated, GCC only) *
|
||||
* DONT USE: use instead the standard CV_NODISCARD_STD macro above *
|
||||
* this legacy method silently fails to issue warning until some version *
|
||||
* after gcc 6.3.0. Yet with gcc 7+ you can use the above standard method *
|
||||
* which makes this method useless. Don't use it. *
|
||||
* @deprecated use instead CV_NODISCARD_STD *
|
||||
\****************************************************************************************/
|
||||
#ifndef CV_NODISCARD
|
||||
# if defined(__GNUC__)
|
||||
# define CV_NODISCARD __attribute__((__warn_unused_result__)) // at least available with GCC 3.4
|
||||
# define CV_NODISCARD __attribute__((__warn_unused_result__))
|
||||
# elif defined(__clang__) && defined(__has_attribute)
|
||||
# if __has_attribute(__warn_unused_result__)
|
||||
# define CV_NODISCARD __attribute__((__warn_unused_result__))
|
||||
|
||||
@@ -538,49 +538,81 @@ inline void v_mul_expand(const v_int8x16& a, const v_int8x16& b,
|
||||
v_int16x8& c, v_int16x8& d)
|
||||
{
|
||||
c.val = vmull_s8(vget_low_s8(a.val), vget_low_s8(b.val));
|
||||
#if CV_NEON_AARCH64
|
||||
d.val = vmull_high_s8(a.val, b.val);
|
||||
#else // #if CV_NEON_AARCH64
|
||||
d.val = vmull_s8(vget_high_s8(a.val), vget_high_s8(b.val));
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
|
||||
inline void v_mul_expand(const v_uint8x16& a, const v_uint8x16& b,
|
||||
v_uint16x8& c, v_uint16x8& d)
|
||||
{
|
||||
c.val = vmull_u8(vget_low_u8(a.val), vget_low_u8(b.val));
|
||||
#if CV_NEON_AARCH64
|
||||
d.val = vmull_high_u8(a.val, b.val);
|
||||
#else // #if CV_NEON_AARCH64
|
||||
d.val = vmull_u8(vget_high_u8(a.val), vget_high_u8(b.val));
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
|
||||
inline void v_mul_expand(const v_int16x8& a, const v_int16x8& b,
|
||||
v_int32x4& c, v_int32x4& d)
|
||||
{
|
||||
c.val = vmull_s16(vget_low_s16(a.val), vget_low_s16(b.val));
|
||||
#if CV_NEON_AARCH64
|
||||
d.val = vmull_high_s16(a.val, b.val);
|
||||
#else // #if CV_NEON_AARCH64
|
||||
d.val = vmull_s16(vget_high_s16(a.val), vget_high_s16(b.val));
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
|
||||
inline void v_mul_expand(const v_uint16x8& a, const v_uint16x8& b,
|
||||
v_uint32x4& c, v_uint32x4& d)
|
||||
{
|
||||
c.val = vmull_u16(vget_low_u16(a.val), vget_low_u16(b.val));
|
||||
#if CV_NEON_AARCH64
|
||||
d.val = vmull_high_u16(a.val, b.val);
|
||||
#else // #if CV_NEON_AARCH64
|
||||
d.val = vmull_u16(vget_high_u16(a.val), vget_high_u16(b.val));
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
|
||||
inline void v_mul_expand(const v_uint32x4& a, const v_uint32x4& b,
|
||||
v_uint64x2& c, v_uint64x2& d)
|
||||
{
|
||||
c.val = vmull_u32(vget_low_u32(a.val), vget_low_u32(b.val));
|
||||
#if CV_NEON_AARCH64
|
||||
d.val = vmull_high_u32(a.val, b.val);
|
||||
#else // #if CV_NEON_AARCH64
|
||||
d.val = vmull_u32(vget_high_u32(a.val), vget_high_u32(b.val));
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
|
||||
inline v_int16x8 v_mul_hi(const v_int16x8& a, const v_int16x8& b)
|
||||
{
|
||||
return v_int16x8(vcombine_s16(
|
||||
vshrn_n_s32(vmull_s16( vget_low_s16(a.val), vget_low_s16(b.val)), 16),
|
||||
vshrn_n_s32(vmull_s16(vget_high_s16(a.val), vget_high_s16(b.val)), 16)
|
||||
vshrn_n_s32(
|
||||
#if CV_NEON_AARCH64
|
||||
vmull_high_s16(a.val, b.val)
|
||||
#else // #if CV_NEON_AARCH64
|
||||
vmull_s16(vget_high_s16(a.val), vget_high_s16(b.val))
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
, 16)
|
||||
));
|
||||
}
|
||||
inline v_uint16x8 v_mul_hi(const v_uint16x8& a, const v_uint16x8& b)
|
||||
{
|
||||
return v_uint16x8(vcombine_u16(
|
||||
vshrn_n_u32(vmull_u16( vget_low_u16(a.val), vget_low_u16(b.val)), 16),
|
||||
vshrn_n_u32(vmull_u16(vget_high_u16(a.val), vget_high_u16(b.val)), 16)
|
||||
vshrn_n_u32(
|
||||
#if CV_NEON_AARCH64
|
||||
vmull_high_u16(a.val, b.val)
|
||||
#else // #if CV_NEON_AARCH64
|
||||
vmull_u16(vget_high_u16(a.val), vget_high_u16(b.val))
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
, 16)
|
||||
));
|
||||
}
|
||||
|
||||
@@ -1254,29 +1286,56 @@ OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_float64x2, double, f64)
|
||||
|
||||
inline unsigned v_reduce_sum(const v_uint8x16& a)
|
||||
{
|
||||
#if CV_NEON_AARCH64
|
||||
uint16_t t0 = vaddlvq_u8(a.val);
|
||||
return t0;
|
||||
#else // #if CV_NEON_AARCH64
|
||||
uint32x4_t t0 = vpaddlq_u16(vpaddlq_u8(a.val));
|
||||
uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0));
|
||||
return vget_lane_u32(vpadd_u32(t1, t1), 0);
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
inline int v_reduce_sum(const v_int8x16& a)
|
||||
{
|
||||
#if CV_NEON_AARCH64
|
||||
int16_t t0 = vaddlvq_s8(a.val);
|
||||
return t0;
|
||||
#else // #if CV_NEON_AARCH64
|
||||
int32x4_t t0 = vpaddlq_s16(vpaddlq_s8(a.val));
|
||||
int32x2_t t1 = vpadd_s32(vget_low_s32(t0), vget_high_s32(t0));
|
||||
return vget_lane_s32(vpadd_s32(t1, t1), 0);
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
inline unsigned v_reduce_sum(const v_uint16x8& a)
|
||||
{
|
||||
#if CV_NEON_AARCH64
|
||||
uint32_t t0 = vaddlvq_u16(a.val);
|
||||
return t0;
|
||||
#else // #if CV_NEON_AARCH64
|
||||
uint32x4_t t0 = vpaddlq_u16(a.val);
|
||||
uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0));
|
||||
return vget_lane_u32(vpadd_u32(t1, t1), 0);
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
inline int v_reduce_sum(const v_int16x8& a)
|
||||
{
|
||||
#if CV_NEON_AARCH64
|
||||
int32_t t0 = vaddlvq_s16(a.val);
|
||||
return t0;
|
||||
#else // #if CV_NEON_AARCH64
|
||||
int32x4_t t0 = vpaddlq_s16(a.val);
|
||||
int32x2_t t1 = vpadd_s32(vget_low_s32(t0), vget_high_s32(t0));
|
||||
return vget_lane_s32(vpadd_s32(t1, t1), 0);
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
|
||||
#if CV_NEON_AARCH64
|
||||
#define OPENCV_HAL_IMPL_NEON_REDUCE_OP_16(_Tpvec, _Tpnvec, scalartype, func, vectorfunc, suffix) \
|
||||
inline scalartype v_reduce_##func(const _Tpvec& a) \
|
||||
{ \
|
||||
return v##vectorfunc##vq_##suffix(a.val); \
|
||||
}
|
||||
#else // #if CV_NEON_AARCH64
|
||||
#define OPENCV_HAL_IMPL_NEON_REDUCE_OP_16(_Tpvec, _Tpnvec, scalartype, func, vectorfunc, suffix) \
|
||||
inline scalartype v_reduce_##func(const _Tpvec& a) \
|
||||
{ \
|
||||
@@ -1285,12 +1344,20 @@ inline scalartype v_reduce_##func(const _Tpvec& a) \
|
||||
a0 = vp##vectorfunc##_##suffix(a0, a0); \
|
||||
return (scalartype)vget_lane_##suffix(vp##vectorfunc##_##suffix(a0, a0),0); \
|
||||
}
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
|
||||
OPENCV_HAL_IMPL_NEON_REDUCE_OP_16(v_uint8x16, uint8x8, uchar, max, max, u8)
|
||||
OPENCV_HAL_IMPL_NEON_REDUCE_OP_16(v_uint8x16, uint8x8, uchar, min, min, u8)
|
||||
OPENCV_HAL_IMPL_NEON_REDUCE_OP_16(v_int8x16, int8x8, schar, max, max, s8)
|
||||
OPENCV_HAL_IMPL_NEON_REDUCE_OP_16(v_int8x16, int8x8, schar, min, min, s8)
|
||||
|
||||
#if CV_NEON_AARCH64
|
||||
#define OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(_Tpvec, _Tpnvec, scalartype, func, vectorfunc, suffix) \
|
||||
inline scalartype v_reduce_##func(const _Tpvec& a) \
|
||||
{ \
|
||||
return v##vectorfunc##vq_##suffix(a.val); \
|
||||
}
|
||||
#else // #if CV_NEON_AARCH64
|
||||
#define OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(_Tpvec, _Tpnvec, scalartype, func, vectorfunc, suffix) \
|
||||
inline scalartype v_reduce_##func(const _Tpvec& a) \
|
||||
{ \
|
||||
@@ -1298,18 +1365,27 @@ inline scalartype v_reduce_##func(const _Tpvec& a) \
|
||||
a0 = vp##vectorfunc##_##suffix(a0, a0); \
|
||||
return (scalartype)vget_lane_##suffix(vp##vectorfunc##_##suffix(a0, a0),0); \
|
||||
}
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
|
||||
OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_uint16x8, uint16x4, ushort, max, max, u16)
|
||||
OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_uint16x8, uint16x4, ushort, min, min, u16)
|
||||
OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_int16x8, int16x4, short, max, max, s16)
|
||||
OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_int16x8, int16x4, short, min, min, s16)
|
||||
|
||||
#if CV_NEON_AARCH64
|
||||
#define OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(_Tpvec, _Tpnvec, scalartype, func, vectorfunc, suffix) \
|
||||
inline scalartype v_reduce_##func(const _Tpvec& a) \
|
||||
{ \
|
||||
return v##vectorfunc##vq_##suffix(a.val); \
|
||||
}
|
||||
#else // #if CV_NEON_AARCH64
|
||||
#define OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(_Tpvec, _Tpnvec, scalartype, func, vectorfunc, suffix) \
|
||||
inline scalartype v_reduce_##func(const _Tpvec& a) \
|
||||
{ \
|
||||
_Tpnvec##_t a0 = vp##vectorfunc##_##suffix(vget_low_##suffix(a.val), vget_high_##suffix(a.val)); \
|
||||
return (scalartype)vget_lane_##suffix(vp##vectorfunc##_##suffix(a0, vget_high_##suffix(a.val)),0); \
|
||||
}
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
|
||||
OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_uint32x4, uint32x2, unsigned, sum, add, u32)
|
||||
OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_uint32x4, uint32x2, unsigned, max, max, u32)
|
||||
@@ -1322,9 +1398,21 @@ OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_float32x4, float32x2, float, max, max, f32)
|
||||
OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_float32x4, float32x2, float, min, min, f32)
|
||||
|
||||
inline uint64 v_reduce_sum(const v_uint64x2& a)
|
||||
{ return vget_lane_u64(vadd_u64(vget_low_u64(a.val), vget_high_u64(a.val)),0); }
|
||||
{
|
||||
#if CV_NEON_AARCH64
|
||||
return vaddvq_u64(a.val);
|
||||
#else // #if CV_NEON_AARCH64
|
||||
return vget_lane_u64(vadd_u64(vget_low_u64(a.val), vget_high_u64(a.val)),0);
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
inline int64 v_reduce_sum(const v_int64x2& a)
|
||||
{ return vget_lane_s64(vadd_s64(vget_low_s64(a.val), vget_high_s64(a.val)),0); }
|
||||
{
|
||||
#if CV_NEON_AARCH64
|
||||
return vaddvq_s64(a.val);
|
||||
#else // #if CV_NEON_AARCH64
|
||||
return vget_lane_s64(vadd_s64(vget_low_s64(a.val), vget_high_s64(a.val)),0);
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
#if CV_SIMD128_64F
|
||||
inline double v_reduce_sum(const v_float64x2& a)
|
||||
{
|
||||
@@ -1335,6 +1423,11 @@ inline double v_reduce_sum(const v_float64x2& a)
|
||||
inline v_float32x4 v_reduce_sum4(const v_float32x4& a, const v_float32x4& b,
|
||||
const v_float32x4& c, const v_float32x4& d)
|
||||
{
|
||||
#if CV_NEON_AARCH64
|
||||
float32x4_t ab = vpaddq_f32(a.val, b.val); // a0+a1 a2+a3 b0+b1 b2+b3
|
||||
float32x4_t cd = vpaddq_f32(c.val, d.val); // c0+c1 d0+d1 c2+c3 d2+d3
|
||||
return v_float32x4(vpaddq_f32(ab, cd)); // sumA sumB sumC sumD
|
||||
#else // #if CV_NEON_AARCH64
|
||||
float32x4x2_t ab = vtrnq_f32(a.val, b.val);
|
||||
float32x4x2_t cd = vtrnq_f32(c.val, d.val);
|
||||
|
||||
@@ -1345,49 +1438,91 @@ inline v_float32x4 v_reduce_sum4(const v_float32x4& a, const v_float32x4& b,
|
||||
float32x4_t v1 = vcombine_f32(vget_high_f32(u0), vget_high_f32(u1));
|
||||
|
||||
return v_float32x4(vaddq_f32(v0, v1));
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
|
||||
inline unsigned v_reduce_sad(const v_uint8x16& a, const v_uint8x16& b)
|
||||
{
|
||||
#if CV_NEON_AARCH64
|
||||
uint8x16_t t0 = vabdq_u8(a.val, b.val);
|
||||
uint16_t t1 = vaddlvq_u8(t0);
|
||||
return t1;
|
||||
#else // #if CV_NEON_AARCH64
|
||||
uint32x4_t t0 = vpaddlq_u16(vpaddlq_u8(vabdq_u8(a.val, b.val)));
|
||||
uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0));
|
||||
return vget_lane_u32(vpadd_u32(t1, t1), 0);
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
inline unsigned v_reduce_sad(const v_int8x16& a, const v_int8x16& b)
|
||||
{
|
||||
#if CV_NEON_AARCH64
|
||||
uint8x16_t t0 = vreinterpretq_u8_s8(vabdq_s8(a.val, b.val));
|
||||
uint16_t t1 = vaddlvq_u8(t0);
|
||||
return t1;
|
||||
#else // #if CV_NEON_AARCH64
|
||||
uint32x4_t t0 = vpaddlq_u16(vpaddlq_u8(vreinterpretq_u8_s8(vabdq_s8(a.val, b.val))));
|
||||
uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0));
|
||||
return vget_lane_u32(vpadd_u32(t1, t1), 0);
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
inline unsigned v_reduce_sad(const v_uint16x8& a, const v_uint16x8& b)
|
||||
{
|
||||
#if CV_NEON_AARCH64
|
||||
uint16x8_t t0 = vabdq_u16(a.val, b.val);
|
||||
uint32_t t1 = vaddlvq_u16(t0);
|
||||
return t1;
|
||||
#else // #if CV_NEON_AARCH64
|
||||
uint32x4_t t0 = vpaddlq_u16(vabdq_u16(a.val, b.val));
|
||||
uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0));
|
||||
return vget_lane_u32(vpadd_u32(t1, t1), 0);
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
inline unsigned v_reduce_sad(const v_int16x8& a, const v_int16x8& b)
|
||||
{
|
||||
#if CV_NEON_AARCH64
|
||||
uint16x8_t t0 = vreinterpretq_u16_s16(vabdq_s16(a.val, b.val));
|
||||
uint32_t t1 = vaddlvq_u16(t0);
|
||||
return t1;
|
||||
#else // #if CV_NEON_AARCH64
|
||||
uint32x4_t t0 = vpaddlq_u16(vreinterpretq_u16_s16(vabdq_s16(a.val, b.val)));
|
||||
uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0));
|
||||
return vget_lane_u32(vpadd_u32(t1, t1), 0);
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
inline unsigned v_reduce_sad(const v_uint32x4& a, const v_uint32x4& b)
|
||||
{
|
||||
#if CV_NEON_AARCH64
|
||||
uint32x4_t t0 = vabdq_u32(a.val, b.val);
|
||||
uint32_t t1 = vaddvq_u32(t0);
|
||||
return t1;
|
||||
#else // #if CV_NEON_AARCH64
|
||||
uint32x4_t t0 = vabdq_u32(a.val, b.val);
|
||||
uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0));
|
||||
return vget_lane_u32(vpadd_u32(t1, t1), 0);
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
inline unsigned v_reduce_sad(const v_int32x4& a, const v_int32x4& b)
|
||||
{
|
||||
#if CV_NEON_AARCH64
|
||||
uint32x4_t t0 = vreinterpretq_u32_s32(vabdq_s32(a.val, b.val));
|
||||
uint32_t t1 = vaddvq_u32(t0);
|
||||
return t1;
|
||||
#else // #if CV_NEON_AARCH64
|
||||
uint32x4_t t0 = vreinterpretq_u32_s32(vabdq_s32(a.val, b.val));
|
||||
uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0));
|
||||
return vget_lane_u32(vpadd_u32(t1, t1), 0);
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
inline float v_reduce_sad(const v_float32x4& a, const v_float32x4& b)
|
||||
{
|
||||
#if CV_NEON_AARCH64
|
||||
float32x4_t t0 = vabdq_f32(a.val, b.val);
|
||||
return vaddvq_f32(t0);
|
||||
#else // #if CV_NEON_AARCH64
|
||||
float32x4_t t0 = vabdq_f32(a.val, b.val);
|
||||
float32x2_t t1 = vpadd_f32(vget_low_f32(t0), vget_high_f32(t0));
|
||||
return vget_lane_f32(vpadd_f32(t1, t1), 0);
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
|
||||
inline v_uint8x16 v_popcount(const v_uint8x16& a)
|
||||
@@ -1409,30 +1544,54 @@ inline v_uint64x2 v_popcount(const v_int64x2& a)
|
||||
|
||||
inline int v_signmask(const v_uint8x16& a)
|
||||
{
|
||||
#if CV_NEON_AARCH64
|
||||
const int8x16_t signPosition = {0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7};
|
||||
const uint8x16_t byteOrder = {0,8,1,9,2,10,3,11,4,12,5,13,6,14,7,15};
|
||||
uint8x16_t v0 = vshlq_u8(vshrq_n_u8(a.val, 7), signPosition);
|
||||
uint8x16_t v1 = vqtbl1q_u8(v0, byteOrder);
|
||||
uint32_t t0 = vaddlvq_u16(vreinterpretq_u16_u8(v1));
|
||||
return t0;
|
||||
#else // #if CV_NEON_AARCH64
|
||||
int8x8_t m0 = vcreate_s8(CV_BIG_UINT(0x0706050403020100));
|
||||
uint8x16_t v0 = vshlq_u8(vshrq_n_u8(a.val, 7), vcombine_s8(m0, m0));
|
||||
uint64x2_t v1 = vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(v0)));
|
||||
return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 8);
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
|
||||
inline int v_signmask(const v_int8x16& a)
|
||||
{ return v_signmask(v_reinterpret_as_u8(a)); }
|
||||
|
||||
inline int v_signmask(const v_uint16x8& a)
|
||||
{
|
||||
#if CV_NEON_AARCH64
|
||||
const int16x8_t signPosition = {0,1,2,3,4,5,6,7};
|
||||
uint16x8_t v0 = vshlq_u16(vshrq_n_u16(a.val, 15), signPosition);
|
||||
uint32_t t0 = vaddlvq_u16(v0);
|
||||
return t0;
|
||||
#else // #if CV_NEON_AARCH64
|
||||
int16x4_t m0 = vcreate_s16(CV_BIG_UINT(0x0003000200010000));
|
||||
uint16x8_t v0 = vshlq_u16(vshrq_n_u16(a.val, 15), vcombine_s16(m0, m0));
|
||||
uint64x2_t v1 = vpaddlq_u32(vpaddlq_u16(v0));
|
||||
return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 4);
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
inline int v_signmask(const v_int16x8& a)
|
||||
{ return v_signmask(v_reinterpret_as_u16(a)); }
|
||||
|
||||
inline int v_signmask(const v_uint32x4& a)
|
||||
{
|
||||
#if CV_NEON_AARCH64
|
||||
const int32x4_t signPosition = {0,1,2,3};
|
||||
uint32x4_t v0 = vshlq_u32(vshrq_n_u32(a.val, 31), signPosition);
|
||||
uint32_t t0 = vaddvq_u32(v0);
|
||||
return t0;
|
||||
#else // #if CV_NEON_AARCH64
|
||||
int32x2_t m0 = vcreate_s32(CV_BIG_UINT(0x0000000100000000));
|
||||
uint32x4_t v0 = vshlq_u32(vshrq_n_u32(a.val, 31), vcombine_s32(m0, m0));
|
||||
uint64x2_t v1 = vpaddlq_u32(v0);
|
||||
return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 2);
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
inline int v_signmask(const v_int32x4& a)
|
||||
{ return v_signmask(v_reinterpret_as_u32(a)); }
|
||||
@@ -1440,9 +1599,16 @@ inline int v_signmask(const v_float32x4& a)
|
||||
{ return v_signmask(v_reinterpret_as_u32(a)); }
|
||||
inline int v_signmask(const v_uint64x2& a)
|
||||
{
|
||||
#if CV_NEON_AARCH64
|
||||
const int64x2_t signPosition = {0,1};
|
||||
uint64x2_t v0 = vshlq_u64(vshrq_n_u64(a.val, 63), signPosition);
|
||||
uint64_t t0 = vaddvq_u64(v0);
|
||||
return t0;
|
||||
#else // #if CV_NEON_AARCH64
|
||||
int64x1_t m0 = vdup_n_s64(0);
|
||||
uint64x2_t v0 = vshlq_u64(vshrq_n_u64(a.val, 63), vcombine_s64(m0, m0));
|
||||
return (int)vgetq_lane_u64(v0, 0) + ((int)vgetq_lane_u64(v0, 1) << 1);
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
}
|
||||
inline int v_signmask(const v_int64x2& a)
|
||||
{ return v_signmask(v_reinterpret_as_u64(a)); }
|
||||
@@ -1464,19 +1630,31 @@ inline int v_scan_forward(const v_uint64x2& a) { return trailingZeros32(v_signma
|
||||
inline int v_scan_forward(const v_float64x2& a) { return trailingZeros32(v_signmask(a)); }
|
||||
#endif
|
||||
|
||||
#define OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(_Tpvec, suffix, shift) \
|
||||
inline bool v_check_all(const v_##_Tpvec& a) \
|
||||
{ \
|
||||
_Tpvec##_t v0 = vshrq_n_##suffix(vmvnq_##suffix(a.val), shift); \
|
||||
uint64x2_t v1 = vreinterpretq_u64_##suffix(v0); \
|
||||
return (vgetq_lane_u64(v1, 0) | vgetq_lane_u64(v1, 1)) == 0; \
|
||||
} \
|
||||
inline bool v_check_any(const v_##_Tpvec& a) \
|
||||
{ \
|
||||
_Tpvec##_t v0 = vshrq_n_##suffix(a.val, shift); \
|
||||
uint64x2_t v1 = vreinterpretq_u64_##suffix(v0); \
|
||||
return (vgetq_lane_u64(v1, 0) | vgetq_lane_u64(v1, 1)) != 0; \
|
||||
}
|
||||
#if CV_NEON_AARCH64
|
||||
#define OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(_Tpvec, suffix, shift) \
|
||||
inline bool v_check_all(const v_##_Tpvec& a) \
|
||||
{ \
|
||||
return (vminvq_##suffix(a.val) >> shift) != 0; \
|
||||
} \
|
||||
inline bool v_check_any(const v_##_Tpvec& a) \
|
||||
{ \
|
||||
return (vmaxvq_##suffix(a.val) >> shift) != 0; \
|
||||
}
|
||||
#else // #if CV_NEON_AARCH64
|
||||
#define OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(_Tpvec, suffix, shift) \
|
||||
inline bool v_check_all(const v_##_Tpvec& a) \
|
||||
{ \
|
||||
_Tpvec##_t v0 = vshrq_n_##suffix(vmvnq_##suffix(a.val), shift); \
|
||||
uint64x2_t v1 = vreinterpretq_u64_##suffix(v0); \
|
||||
return (vgetq_lane_u64(v1, 0) | vgetq_lane_u64(v1, 1)) == 0; \
|
||||
} \
|
||||
inline bool v_check_any(const v_##_Tpvec& a) \
|
||||
{ \
|
||||
_Tpvec##_t v0 = vshrq_n_##suffix(a.val, shift); \
|
||||
uint64x2_t v1 = vreinterpretq_u64_##suffix(v0); \
|
||||
return (vgetq_lane_u64(v1, 0) | vgetq_lane_u64(v1, 1)) != 0; \
|
||||
}
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
|
||||
OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(uint8x16, u8, 7)
|
||||
OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(uint16x8, u16, 15)
|
||||
@@ -1829,6 +2007,37 @@ inline v_int32x4 v_trunc(const v_float64x2& a)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CV_NEON_AARCH64
|
||||
#define OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(_Tpvec, suffix) \
|
||||
inline void v_transpose4x4(const v_##_Tpvec& a0, const v_##_Tpvec& a1, \
|
||||
const v_##_Tpvec& a2, const v_##_Tpvec& a3, \
|
||||
v_##_Tpvec& b0, v_##_Tpvec& b1, \
|
||||
v_##_Tpvec& b2, v_##_Tpvec& b3) \
|
||||
{ \
|
||||
/* -- Pass 1: 64b transpose */ \
|
||||
_Tpvec##_t t0 = vreinterpretq_##suffix##32_##suffix##64( \
|
||||
vtrn1q_##suffix##64(vreinterpretq_##suffix##64_##suffix##32(a0.val), \
|
||||
vreinterpretq_##suffix##64_##suffix##32(a2.val))); \
|
||||
_Tpvec##_t t1 = vreinterpretq_##suffix##32_##suffix##64( \
|
||||
vtrn1q_##suffix##64(vreinterpretq_##suffix##64_##suffix##32(a1.val), \
|
||||
vreinterpretq_##suffix##64_##suffix##32(a3.val))); \
|
||||
_Tpvec##_t t2 = vreinterpretq_##suffix##32_##suffix##64( \
|
||||
vtrn2q_##suffix##64(vreinterpretq_##suffix##64_##suffix##32(a0.val), \
|
||||
vreinterpretq_##suffix##64_##suffix##32(a2.val))); \
|
||||
_Tpvec##_t t3 = vreinterpretq_##suffix##32_##suffix##64( \
|
||||
vtrn2q_##suffix##64(vreinterpretq_##suffix##64_##suffix##32(a1.val), \
|
||||
vreinterpretq_##suffix##64_##suffix##32(a3.val))); \
|
||||
/* -- Pass 2: 32b transpose */ \
|
||||
b0.val = vtrn1q_##suffix##32(t0, t1); \
|
||||
b1.val = vtrn2q_##suffix##32(t0, t1); \
|
||||
b2.val = vtrn1q_##suffix##32(t2, t3); \
|
||||
b3.val = vtrn2q_##suffix##32(t2, t3); \
|
||||
}
|
||||
|
||||
OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(uint32x4, u)
|
||||
OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(int32x4, s)
|
||||
OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(float32x4, f)
|
||||
#else // #if CV_NEON_AARCH64
|
||||
#define OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(_Tpvec, suffix) \
|
||||
inline void v_transpose4x4(const v_##_Tpvec& a0, const v_##_Tpvec& a1, \
|
||||
const v_##_Tpvec& a2, const v_##_Tpvec& a3, \
|
||||
@@ -1854,6 +2063,7 @@ inline void v_transpose4x4(const v_##_Tpvec& a0, const v_##_Tpvec& a1, \
|
||||
OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(uint32x4, u32)
|
||||
OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(int32x4, s32)
|
||||
OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(float32x4, f32)
|
||||
#endif // #if CV_NEON_AARCH64
|
||||
|
||||
#define OPENCV_HAL_IMPL_NEON_INTERLEAVED(_Tpvec, _Tp, suffix) \
|
||||
inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec& a, v_##_Tpvec& b) \
|
||||
|
||||
@@ -1204,14 +1204,14 @@ public:
|
||||
The method creates a square diagonal matrix from specified main diagonal.
|
||||
@param d One-dimensional matrix that represents the main diagonal.
|
||||
*/
|
||||
static Mat diag(const Mat& d);
|
||||
CV_NODISCARD_STD static Mat diag(const Mat& d);
|
||||
|
||||
/** @brief Creates a full copy of the array and the underlying data.
|
||||
|
||||
The method creates a full copy of the array. The original step[] is not taken into account. So, the
|
||||
array copy is a continuous array occupying total()*elemSize() bytes.
|
||||
*/
|
||||
Mat clone() const CV_NODISCARD;
|
||||
CV_NODISCARD_STD Mat clone() const;
|
||||
|
||||
/** @brief Copies the matrix to another one.
|
||||
|
||||
@@ -1375,20 +1375,20 @@ public:
|
||||
@param cols Number of columns.
|
||||
@param type Created matrix type.
|
||||
*/
|
||||
static MatExpr zeros(int rows, int cols, int type);
|
||||
CV_NODISCARD_STD static MatExpr zeros(int rows, int cols, int type);
|
||||
|
||||
/** @overload
|
||||
@param size Alternative to the matrix size specification Size(cols, rows) .
|
||||
@param type Created matrix type.
|
||||
*/
|
||||
static MatExpr zeros(Size size, int type);
|
||||
CV_NODISCARD_STD static MatExpr zeros(Size size, int type);
|
||||
|
||||
/** @overload
|
||||
@param ndims Array dimensionality.
|
||||
@param sz Array of integers specifying the array shape.
|
||||
@param type Created matrix type.
|
||||
*/
|
||||
static MatExpr zeros(int ndims, const int* sz, int type);
|
||||
CV_NODISCARD_STD static MatExpr zeros(int ndims, const int* sz, int type);
|
||||
|
||||
/** @brief Returns an array of all 1's of the specified size and type.
|
||||
|
||||
@@ -1406,20 +1406,20 @@ public:
|
||||
@param cols Number of columns.
|
||||
@param type Created matrix type.
|
||||
*/
|
||||
static MatExpr ones(int rows, int cols, int type);
|
||||
CV_NODISCARD_STD static MatExpr ones(int rows, int cols, int type);
|
||||
|
||||
/** @overload
|
||||
@param size Alternative to the matrix size specification Size(cols, rows) .
|
||||
@param type Created matrix type.
|
||||
*/
|
||||
static MatExpr ones(Size size, int type);
|
||||
CV_NODISCARD_STD static MatExpr ones(Size size, int type);
|
||||
|
||||
/** @overload
|
||||
@param ndims Array dimensionality.
|
||||
@param sz Array of integers specifying the array shape.
|
||||
@param type Created matrix type.
|
||||
*/
|
||||
static MatExpr ones(int ndims, const int* sz, int type);
|
||||
CV_NODISCARD_STD static MatExpr ones(int ndims, const int* sz, int type);
|
||||
|
||||
/** @brief Returns an identity matrix of the specified size and type.
|
||||
|
||||
@@ -1435,13 +1435,13 @@ public:
|
||||
@param cols Number of columns.
|
||||
@param type Created matrix type.
|
||||
*/
|
||||
static MatExpr eye(int rows, int cols, int type);
|
||||
CV_NODISCARD_STD static MatExpr eye(int rows, int cols, int type);
|
||||
|
||||
/** @overload
|
||||
@param size Alternative matrix size specification as Size(cols, rows) .
|
||||
@param type Created matrix type.
|
||||
*/
|
||||
static MatExpr eye(Size size, int type);
|
||||
CV_NODISCARD_STD static MatExpr eye(Size size, int type);
|
||||
|
||||
/** @brief Allocates new array data if needed.
|
||||
|
||||
@@ -2302,7 +2302,7 @@ public:
|
||||
Mat_ row(int y) const;
|
||||
Mat_ col(int x) const;
|
||||
Mat_ diag(int d=0) const;
|
||||
Mat_ clone() const CV_NODISCARD;
|
||||
CV_NODISCARD_STD Mat_ clone() const;
|
||||
|
||||
//! overridden forms of Mat::elemSize() etc.
|
||||
size_t elemSize() const;
|
||||
@@ -2315,14 +2315,14 @@ public:
|
||||
size_t stepT(int i=0) const;
|
||||
|
||||
//! overridden forms of Mat::zeros() etc. Data type is omitted, of course
|
||||
static MatExpr zeros(int rows, int cols);
|
||||
static MatExpr zeros(Size size);
|
||||
static MatExpr zeros(int _ndims, const int* _sizes);
|
||||
static MatExpr ones(int rows, int cols);
|
||||
static MatExpr ones(Size size);
|
||||
static MatExpr ones(int _ndims, const int* _sizes);
|
||||
static MatExpr eye(int rows, int cols);
|
||||
static MatExpr eye(Size size);
|
||||
CV_NODISCARD_STD static MatExpr zeros(int rows, int cols);
|
||||
CV_NODISCARD_STD static MatExpr zeros(Size size);
|
||||
CV_NODISCARD_STD static MatExpr zeros(int _ndims, const int* _sizes);
|
||||
CV_NODISCARD_STD static MatExpr ones(int rows, int cols);
|
||||
CV_NODISCARD_STD static MatExpr ones(Size size);
|
||||
CV_NODISCARD_STD static MatExpr ones(int _ndims, const int* _sizes);
|
||||
CV_NODISCARD_STD static MatExpr eye(int rows, int cols);
|
||||
CV_NODISCARD_STD static MatExpr eye(Size size);
|
||||
|
||||
//! some more overridden methods
|
||||
Mat_& adjustROI( int dtop, int dbottom, int dleft, int dright );
|
||||
@@ -2469,10 +2469,10 @@ public:
|
||||
//! <0 - a diagonal from the lower half)
|
||||
UMat diag(int d=0) const;
|
||||
//! constructs a square diagonal matrix which main diagonal is vector "d"
|
||||
static UMat diag(const UMat& d);
|
||||
CV_NODISCARD_STD static UMat diag(const UMat& d);
|
||||
|
||||
//! returns deep copy of the matrix, i.e. the data is copied
|
||||
UMat clone() const CV_NODISCARD;
|
||||
CV_NODISCARD_STD UMat clone() const;
|
||||
//! copies the matrix content to "m".
|
||||
// It calls m.create(this->size(), this->type()).
|
||||
void copyTo( OutputArray m ) const;
|
||||
@@ -2503,14 +2503,14 @@ public:
|
||||
double dot(InputArray m) const;
|
||||
|
||||
//! Matlab-style matrix initialization
|
||||
static UMat zeros(int rows, int cols, int type);
|
||||
static UMat zeros(Size size, int type);
|
||||
static UMat zeros(int ndims, const int* sz, int type);
|
||||
static UMat ones(int rows, int cols, int type);
|
||||
static UMat ones(Size size, int type);
|
||||
static UMat ones(int ndims, const int* sz, int type);
|
||||
static UMat eye(int rows, int cols, int type);
|
||||
static UMat eye(Size size, int type);
|
||||
CV_NODISCARD_STD static UMat zeros(int rows, int cols, int type);
|
||||
CV_NODISCARD_STD static UMat zeros(Size size, int type);
|
||||
CV_NODISCARD_STD static UMat zeros(int ndims, const int* sz, int type);
|
||||
CV_NODISCARD_STD static UMat ones(int rows, int cols, int type);
|
||||
CV_NODISCARD_STD static UMat ones(Size size, int type);
|
||||
CV_NODISCARD_STD static UMat ones(int ndims, const int* sz, int type);
|
||||
CV_NODISCARD_STD static UMat eye(int rows, int cols, int type);
|
||||
CV_NODISCARD_STD static UMat eye(Size size, int type);
|
||||
|
||||
//! allocates new matrix data unless the matrix already has specified size and type.
|
||||
// previous data is unreferenced if needed.
|
||||
@@ -2767,7 +2767,7 @@ public:
|
||||
SparseMat& operator = (const Mat& m);
|
||||
|
||||
//! creates full copy of the matrix
|
||||
SparseMat clone() const CV_NODISCARD;
|
||||
CV_NODISCARD_STD SparseMat clone() const;
|
||||
|
||||
//! copies all the data to the destination matrix. All the previous content of m is erased
|
||||
void copyTo( SparseMat& m ) const;
|
||||
@@ -3004,7 +3004,7 @@ public:
|
||||
SparseMat_& operator = (const Mat& m);
|
||||
|
||||
//! makes full copy of the matrix. All the elements are duplicated
|
||||
SparseMat_ clone() const CV_NODISCARD;
|
||||
CV_NODISCARD_STD SparseMat_ clone() const;
|
||||
//! equivalent to cv::SparseMat::create(dims, _sizes, DataType<_Tp>::type)
|
||||
void create(int dims, const int* _sizes);
|
||||
//! converts sparse matrix to the old-style CvSparseMat. All the elements are copied
|
||||
|
||||
@@ -898,6 +898,33 @@ const _Tp* Mat::ptr(const int* idx) const
|
||||
return (const _Tp*)p;
|
||||
}
|
||||
|
||||
template<int n> inline
|
||||
uchar* Mat::ptr(const Vec<int, n>& idx)
|
||||
{
|
||||
return Mat::ptr(idx.val);
|
||||
}
|
||||
|
||||
template<int n> inline
|
||||
const uchar* Mat::ptr(const Vec<int, n>& idx) const
|
||||
{
|
||||
return Mat::ptr(idx.val);
|
||||
}
|
||||
|
||||
template<typename _Tp, int n> inline
|
||||
_Tp* Mat::ptr(const Vec<int, n>& idx)
|
||||
{
|
||||
CV_DbgAssert( elemSize() == sizeof(_Tp) );
|
||||
return Mat::ptr<_Tp>(idx.val);
|
||||
}
|
||||
|
||||
template<typename _Tp, int n> inline
|
||||
const _Tp* Mat::ptr(const Vec<int, n>& idx) const
|
||||
{
|
||||
CV_DbgAssert( elemSize() == sizeof(_Tp) );
|
||||
return Mat::ptr<_Tp>(idx.val);
|
||||
}
|
||||
|
||||
|
||||
template<typename _Tp> inline
|
||||
_Tp& Mat::at(int i0, int i1)
|
||||
{
|
||||
|
||||
@@ -146,22 +146,22 @@ public:
|
||||
Matx(std::initializer_list<_Tp>); //!< initialize from an initializer list
|
||||
#endif
|
||||
|
||||
static Matx all(_Tp alpha);
|
||||
static Matx zeros();
|
||||
static Matx ones();
|
||||
static Matx eye();
|
||||
static Matx diag(const diag_type& d);
|
||||
CV_NODISCARD_STD static Matx all(_Tp alpha);
|
||||
CV_NODISCARD_STD static Matx zeros();
|
||||
CV_NODISCARD_STD static Matx ones();
|
||||
CV_NODISCARD_STD static Matx eye();
|
||||
CV_NODISCARD_STD static Matx diag(const diag_type& d);
|
||||
/** @brief Generates uniformly distributed random numbers
|
||||
@param a Range boundary.
|
||||
@param b The other range boundary (boundaries don't have to be ordered, the lower boundary is inclusive,
|
||||
the upper one is exclusive).
|
||||
*/
|
||||
static Matx randu(_Tp a, _Tp b);
|
||||
CV_NODISCARD_STD static Matx randu(_Tp a, _Tp b);
|
||||
/** @brief Generates normally distributed random numbers
|
||||
@param a Mean value.
|
||||
@param b Standard deviation.
|
||||
*/
|
||||
static Matx randn(_Tp a, _Tp b);
|
||||
CV_NODISCARD_STD static Matx randn(_Tp a, _Tp b);
|
||||
|
||||
//! dot product computed with the default precision
|
||||
_Tp dot(const Matx<_Tp, m, n>& v) const;
|
||||
|
||||
@@ -562,7 +562,9 @@ public:
|
||||
i = set(i, a6); i = set(i, a7); i = set(i, a8); i = set(i, a9); i = set(i, a10); i = set(i, a11);
|
||||
i = set(i, a12); i = set(i, a13); i = set(i, a14); set(i, a15); return *this;
|
||||
}
|
||||
/** @brief Run the OpenCL kernel.
|
||||
|
||||
/** @brief Run the OpenCL kernel (globalsize value may be adjusted)
|
||||
|
||||
@param dims the work problem dimensions. It is the length of globalsize and localsize. It can be either 1, 2 or 3.
|
||||
@param globalsize work items for each dimension. It is not the final globalsize passed to
|
||||
OpenCL. Each dimension will be adjusted to the nearest integer divisible by the corresponding
|
||||
@@ -571,12 +573,26 @@ public:
|
||||
@param localsize work-group size for each dimension.
|
||||
@param sync specify whether to wait for OpenCL computation to finish before return.
|
||||
@param q command queue
|
||||
|
||||
@note Use run_() if your kernel code doesn't support adjusted globalsize.
|
||||
*/
|
||||
bool run(int dims, size_t globalsize[],
|
||||
size_t localsize[], bool sync, const Queue& q=Queue());
|
||||
|
||||
/** @brief Run the OpenCL kernel
|
||||
*
|
||||
* @param dims the work problem dimensions. It is the length of globalsize and localsize. It can be either 1, 2 or 3.
|
||||
* @param globalsize work items for each dimension. This value is passed to OpenCL without changes.
|
||||
* @param localsize work-group size for each dimension.
|
||||
* @param sync specify whether to wait for OpenCL computation to finish before return.
|
||||
* @param q command queue
|
||||
*/
|
||||
bool run_(int dims, size_t globalsize[], size_t localsize[], bool sync, const Queue& q=Queue());
|
||||
|
||||
bool runTask(bool sync, const Queue& q=Queue());
|
||||
|
||||
/** @brief Similar to synchronized run() call with returning of kernel execution time
|
||||
/** @brief Similar to synchronized run_() call with returning of kernel execution time
|
||||
*
|
||||
* Separate OpenCL command queue may be used (with CL_QUEUE_PROFILING_ENABLE)
|
||||
* @return Execution time in nanoseconds or negative number on error
|
||||
*/
|
||||
|
||||
@@ -702,24 +702,24 @@ public:
|
||||
//! the default constructor
|
||||
CV_WRAP KeyPoint();
|
||||
/**
|
||||
@param _pt x & y coordinates of the keypoint
|
||||
@param _size keypoint diameter
|
||||
@param _angle keypoint orientation
|
||||
@param _response keypoint detector response on the keypoint (that is, strength of the keypoint)
|
||||
@param _octave pyramid octave in which the keypoint has been detected
|
||||
@param _class_id object id
|
||||
@param pt x & y coordinates of the keypoint
|
||||
@param size keypoint diameter
|
||||
@param angle keypoint orientation
|
||||
@param response keypoint detector response on the keypoint (that is, strength of the keypoint)
|
||||
@param octave pyramid octave in which the keypoint has been detected
|
||||
@param class_id object id
|
||||
*/
|
||||
KeyPoint(Point2f _pt, float _size, float _angle=-1, float _response=0, int _octave=0, int _class_id=-1);
|
||||
KeyPoint(Point2f pt, float size, float angle=-1, float response=0, int octave=0, int class_id=-1);
|
||||
/**
|
||||
@param x x-coordinate of the keypoint
|
||||
@param y y-coordinate of the keypoint
|
||||
@param _size keypoint diameter
|
||||
@param _angle keypoint orientation
|
||||
@param _response keypoint detector response on the keypoint (that is, strength of the keypoint)
|
||||
@param _octave pyramid octave in which the keypoint has been detected
|
||||
@param _class_id object id
|
||||
@param size keypoint diameter
|
||||
@param angle keypoint orientation
|
||||
@param response keypoint detector response on the keypoint (that is, strength of the keypoint)
|
||||
@param octave pyramid octave in which the keypoint has been detected
|
||||
@param class_id object id
|
||||
*/
|
||||
CV_WRAP KeyPoint(float x, float y, float _size, float _angle=-1, float _response=0, int _octave=0, int _class_id=-1);
|
||||
CV_WRAP KeyPoint(float x, float y, float size, float angle=-1, float response=0, int octave=0, int class_id=-1);
|
||||
|
||||
size_t hash() const;
|
||||
|
||||
|
||||
@@ -358,7 +358,11 @@ _IplImage
|
||||
needed for correct deallocation */
|
||||
|
||||
#if defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)
|
||||
_IplImage() {}
|
||||
_IplImage()
|
||||
{
|
||||
memset(this, 0, sizeof(*this)); // valid for POD structure
|
||||
nSize = sizeof(IplImage);
|
||||
}
|
||||
_IplImage(const cv::Mat& m) { *this = cvIplImage(m); }
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# define OPENCV_HAVE_FILESYSTEM_SUPPORT 1
|
||||
# elif defined(__APPLE__)
|
||||
# include <TargetConditionals.h>
|
||||
# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX) || (!defined(TARGET_OS_OSX) && !TARGET_OS_IPHONE)
|
||||
# define OPENCV_HAVE_FILESYSTEM_SUPPORT 1 // OSX only
|
||||
# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX) || (defined(TARGET_OS_IOS) && TARGET_OS_IOS)
|
||||
# define OPENCV_HAVE_FILESYSTEM_SUPPORT 1 // OSX, iOS only
|
||||
# endif
|
||||
# else
|
||||
/* unknown */
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
#define CV_VERSION_MAJOR 3
|
||||
#define CV_VERSION_MINOR 4
|
||||
#define CV_VERSION_REVISION 14
|
||||
#define CV_VERSION_STATUS "-pre"
|
||||
#define CV_VERSION_REVISION 16
|
||||
#define CV_VERSION_STATUS ""
|
||||
|
||||
#define CVAUX_STR_EXP(__A) #__A
|
||||
#define CVAUX_STR(__A) CVAUX_STR_EXP(__A)
|
||||
|
||||
@@ -678,7 +678,12 @@ OCL_PERF_TEST_P(SqrtFixture, Sqrt, ::testing::Combine(
|
||||
|
||||
OCL_TEST_CYCLE() cv::sqrt(src, dst);
|
||||
|
||||
if (CV_MAT_DEPTH(type) >= CV_32F)
|
||||
// To square root 32 bit floats we use native_sqrt, which has implementation
|
||||
// defined accuracy. We know intel devices have accurate native_sqrt, but
|
||||
// otherwise stick to a relaxed sanity check. For types larger than 32 bits
|
||||
// we can do the accuracy check for all devices as normal.
|
||||
if (CV_MAT_DEPTH(type) > CV_32F || !ocl::useOpenCL() ||
|
||||
ocl::Device::getDefault().isIntel())
|
||||
SANITY_CHECK(dst, 1e-5, ERROR_RELATIVE);
|
||||
else
|
||||
SANITY_CHECK(dst, 1);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "precomp.hpp"
|
||||
#include "opencv2/core/bindings_utils.hpp"
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace cv { namespace utils {
|
||||
|
||||
@@ -208,4 +209,50 @@ CV_EXPORTS_W String dumpInputOutputArrayOfArrays(InputOutputArrayOfArrays argume
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
static inline std::ostream& operator<<(std::ostream& os, const cv::Rect& rect)
|
||||
{
|
||||
return os << "[x=" << rect.x << ", y=" << rect.y << ", w=" << rect.width << ", h=" << rect.height << ']';
|
||||
}
|
||||
|
||||
template <class T, class Formatter>
|
||||
static inline String dumpVector(const std::vector<T>& vec, Formatter format)
|
||||
{
|
||||
std::ostringstream oss("[", std::ios::ate);
|
||||
if (!vec.empty())
|
||||
{
|
||||
oss << format << vec[0];
|
||||
for (std::size_t i = 1; i < vec.size(); ++i)
|
||||
{
|
||||
oss << ", " << format << vec[i];
|
||||
}
|
||||
}
|
||||
oss << "]";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
static inline std::ostream& noFormat(std::ostream& os)
|
||||
{
|
||||
return os;
|
||||
}
|
||||
|
||||
static inline std::ostream& floatFormat(std::ostream& os)
|
||||
{
|
||||
return os << std::fixed << std::setprecision(2);
|
||||
}
|
||||
|
||||
String dumpVectorOfInt(const std::vector<int>& vec)
|
||||
{
|
||||
return dumpVector(vec, &noFormat);
|
||||
}
|
||||
|
||||
String dumpVectorOfDouble(const std::vector<double>& vec)
|
||||
{
|
||||
return dumpVector(vec, &floatFormat);
|
||||
}
|
||||
|
||||
String dumpVectorOfRect(const std::vector<Rect>& vec)
|
||||
{
|
||||
return dumpVector(vec, &noFormat);
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
||||
@@ -24,11 +24,6 @@
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
|
||||
#include <sstream>
|
||||
#include "opencl_kernels_core.hpp"
|
||||
#include "opencv2/core/opencl/runtime/opencl_clamdblas.hpp"
|
||||
#include "opencv2/core/opencl/runtime/opencl_core.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
@@ -37,52 +32,75 @@ static bool intel_gpu_gemm(
|
||||
UMat B, Size sizeB,
|
||||
UMat D, Size sizeD,
|
||||
double alpha, double beta,
|
||||
bool atrans, bool btrans)
|
||||
bool atrans, bool btrans,
|
||||
bool& isPropagatedC2D
|
||||
)
|
||||
{
|
||||
CV_UNUSED(sizeB);
|
||||
|
||||
int M = sizeD.height, N = sizeD.width, K = ((atrans)? sizeA.height : sizeA.width);
|
||||
|
||||
std::string kernelName;
|
||||
bool ret = true;
|
||||
if (M < 4 || N < 4 || K < 4) // vload4
|
||||
return false;
|
||||
|
||||
size_t lx = 8, ly = 4;
|
||||
size_t dx = 4, dy = 8;
|
||||
CV_LOG_VERBOSE(NULL, 0, "M=" << M << " N=" << N << " K=" << K);
|
||||
|
||||
std::string kernelName;
|
||||
|
||||
unsigned int lx = 8, ly = 4;
|
||||
unsigned int dx = 4, dy = 8;
|
||||
|
||||
if(!atrans && !btrans)
|
||||
{
|
||||
|
||||
if (M % 32 == 0 && N % 32 == 0 && K % 16 == 0)
|
||||
{
|
||||
kernelName = "intelblas_gemm_buffer_NN_sp";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (M % 2 != 0)
|
||||
return false;
|
||||
// vload4(0, dst_write0) - 4 cols
|
||||
// multiply by lx: 8
|
||||
if (N % (4*8) != 0)
|
||||
return false;
|
||||
kernelName = "intelblas_gemm_buffer_NN";
|
||||
}
|
||||
}
|
||||
else if(atrans && !btrans)
|
||||
{
|
||||
if (M % 32 != 0)
|
||||
return false;
|
||||
if (N % 32 != 0)
|
||||
return false;
|
||||
kernelName = "intelblas_gemm_buffer_TN";
|
||||
}
|
||||
else if(!atrans && btrans)
|
||||
{
|
||||
if (K % 4 != 0)
|
||||
return false;
|
||||
kernelName = "intelblas_gemm_buffer_NT";
|
||||
ly = 16;
|
||||
dx = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (M % 32 != 0)
|
||||
return false;
|
||||
if (N % 32 != 0)
|
||||
return false;
|
||||
if (K % 16 != 0)
|
||||
return false;
|
||||
kernelName = "intelblas_gemm_buffer_TT";
|
||||
}
|
||||
|
||||
const size_t gx = (size_t)(N + dx - 1) / dx;
|
||||
const size_t gy = (size_t)(M + dy - 1) / dy;
|
||||
CV_LOG_DEBUG(NULL, "kernel: " << kernelName << " (M=" << M << " N=" << N << " K=" << K << ")");
|
||||
|
||||
const size_t gx = divUp((size_t)N, dx);
|
||||
const size_t gy = divUp((size_t)M, dy);
|
||||
|
||||
size_t local[] = {lx, ly, 1};
|
||||
size_t global[] = {(gx + lx - 1) / lx * lx, (gy + ly - 1) / ly * ly, 1};
|
||||
|
||||
int stride = (M * N < 1024 * 1024) ? 10000000 : 256;
|
||||
size_t global[] = {roundUp(gx, lx), roundUp(gy, ly), 1};
|
||||
|
||||
ocl::Queue q;
|
||||
String errmsg;
|
||||
@@ -110,10 +128,13 @@ static bool intel_gpu_gemm(
|
||||
(int)(D.step / sizeof(float))
|
||||
);
|
||||
|
||||
ret = k.run(2, global, local, false, q);
|
||||
bool ret = k.run(2, global, local, false, q);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
int stride = (M * N < 1024 * 1024) ? 10000000 : 256;
|
||||
|
||||
for(int start_index = 0; start_index < K; start_index += stride)
|
||||
{
|
||||
ocl::Kernel k(kernelName.c_str(), program);
|
||||
@@ -132,12 +153,16 @@ static bool intel_gpu_gemm(
|
||||
(int) start_index, // 14 start_index
|
||||
stride);
|
||||
|
||||
ret = k.run(2, global, local, false, q);
|
||||
if (!ret) return ret;
|
||||
bool ret = k.run(2, global, local, false, q);
|
||||
if (!ret)
|
||||
{
|
||||
if (start_index != 0)
|
||||
isPropagatedC2D = false; // D array content is changed, need to rewrite
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace cv
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
#include "opencl_kernels_core.hpp"
|
||||
#include "opencv2/core/opencl/runtime/opencl_clamdblas.hpp"
|
||||
#include "opencv2/core/opencl/runtime/opencl_core.hpp"
|
||||
@@ -155,10 +157,12 @@ static bool ocl_gemm_amdblas( InputArray matA, InputArray matB, double alpha,
|
||||
static bool ocl_gemm( InputArray matA, InputArray matB, double alpha,
|
||||
InputArray matC, double beta, OutputArray matD, int flags )
|
||||
{
|
||||
int depth = matA.depth(), cn = matA.channels();
|
||||
int type = CV_MAKETYPE(depth, cn);
|
||||
int type = matA.type();
|
||||
int depth = CV_MAT_DEPTH(type);
|
||||
int cn = CV_MAT_CN(type);
|
||||
|
||||
CV_Assert_N( type == matB.type(), (type == CV_32FC1 || type == CV_64FC1 || type == CV_32FC2 || type == CV_64FC2) );
|
||||
CV_CheckTypeEQ(type, matB.type(), "");
|
||||
CV_CheckType(type, type == CV_32FC1 || type == CV_64FC1 || type == CV_32FC2 || type == CV_64FC2, "");
|
||||
|
||||
const ocl::Device & dev = ocl::Device::getDefault();
|
||||
bool doubleSupport = dev.doubleFPConfig() > 0;
|
||||
@@ -170,88 +174,103 @@ static bool ocl_gemm( InputArray matA, InputArray matB, double alpha,
|
||||
Size sizeA = matA.size(), sizeB = matB.size(), sizeC = haveC ? matC.size() : Size(0, 0);
|
||||
bool atrans = (flags & GEMM_1_T) != 0, btrans = (flags & GEMM_2_T) != 0, ctrans = (flags & GEMM_3_T) != 0;
|
||||
|
||||
CV_Assert( !haveC || matC.type() == type );
|
||||
if (haveC)
|
||||
CV_CheckTypeEQ(type, matC.type(), "");
|
||||
|
||||
Size sizeD(((btrans) ? sizeB.height : sizeB.width),
|
||||
((atrans) ? sizeA.width : sizeA.height));
|
||||
|
||||
if (atrans)
|
||||
sizeA = Size(sizeA.height, sizeA.width);
|
||||
if (btrans)
|
||||
sizeB = Size(sizeB.height, sizeB.width);
|
||||
if (haveC && ctrans)
|
||||
sizeC = Size(sizeC.height, sizeC.width);
|
||||
|
||||
CV_CheckEQ(sizeA.width, sizeB.height, "");
|
||||
if (haveC)
|
||||
CV_CheckEQ(sizeC, sizeD, "");
|
||||
|
||||
UMat A = matA.getUMat();
|
||||
UMat B = matB.getUMat();
|
||||
|
||||
Size sizeD(((btrans)? sizeB.height : sizeB.width),
|
||||
((atrans)? sizeA.width : sizeA.height));
|
||||
matD.create(sizeD, type);
|
||||
UMat D = matD.getUMat();
|
||||
|
||||
UMat A = matA.getUMat(), B = matB.getUMat(), D = matD.getUMat();
|
||||
bool isPropagatedC2D = false; // D content is updated with C / C.t()
|
||||
|
||||
|
||||
if (!dev.intelSubgroupsSupport() || (depth == CV_64F) || cn != 1)
|
||||
{
|
||||
String opts;
|
||||
|
||||
if (atrans)
|
||||
sizeA = Size(sizeA.height, sizeA.width);
|
||||
if (btrans)
|
||||
sizeB = Size(sizeB.height, sizeB.width);
|
||||
if (haveC && ctrans)
|
||||
sizeC = Size(sizeC.height, sizeC.width);
|
||||
|
||||
CV_Assert( sizeA.width == sizeB.height && (!haveC || sizeC == sizeD) );
|
||||
|
||||
int max_wg_size = (int)dev.maxWorkGroupSize();
|
||||
int block_size = (max_wg_size / (32*cn) < 32) ? (max_wg_size / (16*cn) < 16) ? (max_wg_size / (8*cn) < 8) ? 1 : 8 : 16 : 32;
|
||||
|
||||
if (atrans)
|
||||
A = A.t();
|
||||
|
||||
if (btrans)
|
||||
B = B.t();
|
||||
|
||||
if (haveC)
|
||||
ctrans ? transpose(matC, D) : matC.copyTo(D);
|
||||
|
||||
int vectorWidths[] = { 4, 4, 2, 2, 1, 4, cn, -1 };
|
||||
int kercn = ocl::checkOptimalVectorWidth(vectorWidths, B, D);
|
||||
|
||||
opts += format(" -D T=%s -D T1=%s -D WT=%s -D cn=%d -D kercn=%d -D LOCAL_SIZE=%d%s%s%s",
|
||||
ocl::typeToStr(type), ocl::typeToStr(depth), ocl::typeToStr(CV_MAKETYPE(depth, kercn)),
|
||||
cn, kercn, block_size,
|
||||
(sizeA.width % block_size !=0) ? " -D NO_MULT" : "",
|
||||
haveC ? " -D HAVE_C" : "",
|
||||
doubleSupport ? " -D DOUBLE_SUPPORT" : "");
|
||||
|
||||
ocl::Kernel k("gemm", cv::ocl::core::gemm_oclsrc, opts);
|
||||
if (k.empty())
|
||||
return false;
|
||||
|
||||
if (depth == CV_64F)
|
||||
k.args(ocl::KernelArg::ReadOnlyNoSize(A),
|
||||
ocl::KernelArg::ReadOnlyNoSize(B, cn, kercn),
|
||||
ocl::KernelArg::ReadWrite(D, cn, kercn),
|
||||
sizeA.width, alpha, beta);
|
||||
else
|
||||
k.args(ocl::KernelArg::ReadOnlyNoSize(A),
|
||||
ocl::KernelArg::ReadOnlyNoSize(B, cn, kercn),
|
||||
ocl::KernelArg::ReadWrite(D, cn, kercn),
|
||||
sizeA.width, (float)alpha, (float)beta);
|
||||
|
||||
size_t globalsize[2] = { (size_t)sizeD.width * cn / kercn, (size_t)sizeD.height};
|
||||
size_t localsize[2] = { (size_t)block_size, (size_t)block_size};
|
||||
|
||||
return k.run(2, globalsize, block_size!=1 ? localsize : NULL, false);
|
||||
}
|
||||
else
|
||||
if (dev.intelSubgroupsSupport() && (depth == CV_32F) && cn == 1)
|
||||
{
|
||||
if (haveC && beta != 0.0)
|
||||
{
|
||||
ctrans ? transpose(matC, D) : matC.copyTo(D);
|
||||
isPropagatedC2D = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
beta = 0.0;
|
||||
}
|
||||
|
||||
return intel_gpu_gemm(A, sizeA,
|
||||
B, sizeB,
|
||||
D, sizeD,
|
||||
alpha,
|
||||
beta,
|
||||
atrans, btrans);
|
||||
bool res = intel_gpu_gemm(A, matA.size(),
|
||||
B, matB.size(),
|
||||
D, sizeD,
|
||||
alpha,
|
||||
beta,
|
||||
atrans, btrans,
|
||||
isPropagatedC2D);
|
||||
if (res)
|
||||
return true;
|
||||
// fallback on generic OpenCL code
|
||||
}
|
||||
|
||||
if (sizeD.width < 8 || sizeD.height < 8)
|
||||
return false;
|
||||
|
||||
String opts;
|
||||
|
||||
int wg_size = (int)dev.maxWorkGroupSize();
|
||||
int sizeDmin = std::min(sizeD.width, sizeD.height);
|
||||
wg_size = std::min(wg_size, sizeDmin * sizeDmin);
|
||||
int block_size = (wg_size / (32*cn) < 32) ? (wg_size / (16*cn) < 16) ? (wg_size / (8*cn) < 8) ? 1 : 8 : 16 : 32;
|
||||
|
||||
if (atrans)
|
||||
A = A.t();
|
||||
|
||||
if (btrans)
|
||||
B = B.t();
|
||||
|
||||
if (haveC && !isPropagatedC2D)
|
||||
ctrans ? transpose(matC, D) : matC.copyTo(D);
|
||||
|
||||
int vectorWidths[] = { 4, 4, 2, 2, 1, 4, cn, -1 };
|
||||
int kercn = ocl::checkOptimalVectorWidth(vectorWidths, B, D);
|
||||
|
||||
opts += format(" -D T=%s -D T1=%s -D WT=%s -D cn=%d -D kercn=%d -D LOCAL_SIZE=%d%s%s%s",
|
||||
ocl::typeToStr(type), ocl::typeToStr(depth), ocl::typeToStr(CV_MAKETYPE(depth, kercn)),
|
||||
cn, kercn, block_size,
|
||||
(sizeA.width % block_size !=0) ? " -D NO_MULT" : "",
|
||||
haveC ? " -D HAVE_C" : "",
|
||||
doubleSupport ? " -D DOUBLE_SUPPORT" : "");
|
||||
|
||||
ocl::Kernel k("gemm", cv::ocl::core::gemm_oclsrc, opts);
|
||||
if (k.empty())
|
||||
return false;
|
||||
|
||||
if (depth == CV_64F)
|
||||
k.args(ocl::KernelArg::ReadOnlyNoSize(A),
|
||||
ocl::KernelArg::ReadOnlyNoSize(B, cn, kercn),
|
||||
ocl::KernelArg::ReadWrite(D, cn, kercn),
|
||||
sizeA.width, alpha, beta);
|
||||
else
|
||||
k.args(ocl::KernelArg::ReadOnlyNoSize(A),
|
||||
ocl::KernelArg::ReadOnlyNoSize(B, cn, kercn),
|
||||
ocl::KernelArg::ReadWrite(D, cn, kercn),
|
||||
sizeA.width, (float)alpha, (float)beta);
|
||||
|
||||
size_t globalsize[2] = { (size_t)sizeD.width * cn / kercn, (size_t)sizeD.height};
|
||||
size_t localsize[2] = { (size_t)block_size, (size_t)block_size};
|
||||
|
||||
return k.run(2, globalsize, block_size !=1 ? localsize : NULL, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -749,18 +749,17 @@ Mat::Mat(const Mat& m, const Rect& roi)
|
||||
data += roi.x*esz;
|
||||
CV_Assert( 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols &&
|
||||
0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows );
|
||||
if( u )
|
||||
CV_XADD(&u->refcount, 1);
|
||||
if( roi.width < m.cols || roi.height < m.rows )
|
||||
flags |= SUBMATRIX_FLAG;
|
||||
|
||||
step[0] = m.step[0]; step[1] = esz;
|
||||
updateContinuityFlag();
|
||||
|
||||
addref();
|
||||
if( rows <= 0 || cols <= 0 )
|
||||
{
|
||||
release();
|
||||
rows = cols = 0;
|
||||
release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1171,7 +1171,7 @@ double norm( InputArray _src1, InputArray _src2, int normType, InputArray _mask
|
||||
// special case to handle "integer" overflow in accumulator
|
||||
const size_t esz = src1.elemSize();
|
||||
const int total = (int)it.size;
|
||||
const int intSumBlockSize = normType == NORM_L1 && depth <= CV_8S ? (1 << 23) : (1 << 15);
|
||||
const int intSumBlockSize = (normType == NORM_L1 && depth <= CV_8S ? (1 << 23) : (1 << 15))/cn;
|
||||
const int blockSize = std::min(total, intSumBlockSize);
|
||||
int isum = 0;
|
||||
int count = 0;
|
||||
|
||||
+94
-33
@@ -76,8 +76,11 @@
|
||||
#undef CV__ALLOCATOR_STATS_LOG
|
||||
|
||||
#define CV_OPENCL_ALWAYS_SHOW_BUILD_LOG 0
|
||||
#define CV_OPENCL_SHOW_BUILD_OPTIONS 0
|
||||
#define CV_OPENCL_SHOW_BUILD_KERNELS 0
|
||||
|
||||
#define CV_OPENCL_SHOW_RUN_KERNELS 0
|
||||
#define CV_OPENCL_SYNC_RUN_KERNELS 0
|
||||
#define CV_OPENCL_TRACE_CHECK 0
|
||||
|
||||
#define CV_OPENCL_VALIDATE_BINARY_PROGRAMS 1
|
||||
@@ -1667,7 +1670,7 @@ static bool parseOpenCLDeviceConfiguration(const std::string& configurationStr,
|
||||
split(configurationStr, ':', parts);
|
||||
if (parts.size() > 3)
|
||||
{
|
||||
std::cerr << "ERROR: Invalid configuration string for OpenCL device" << std::endl;
|
||||
CV_LOG_ERROR(NULL, "OpenCL: Invalid configuration string for OpenCL device: " << configurationStr);
|
||||
return false;
|
||||
}
|
||||
if (parts.size() > 2)
|
||||
@@ -1684,22 +1687,20 @@ static bool parseOpenCLDeviceConfiguration(const std::string& configurationStr,
|
||||
}
|
||||
|
||||
#if defined WINRT || defined _WIN32_WCE
|
||||
static cl_device_id selectOpenCLDevice()
|
||||
static cl_device_id selectOpenCLDevice(const char* configuration = NULL)
|
||||
{
|
||||
CV_UNUSED(configuration)
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
// std::tolower is int->int
|
||||
static char char_tolower(char ch)
|
||||
{
|
||||
return (char)std::tolower((int)ch);
|
||||
}
|
||||
static cl_device_id selectOpenCLDevice()
|
||||
static cl_device_id selectOpenCLDevice(const char* configuration = NULL)
|
||||
{
|
||||
std::string platform, deviceName;
|
||||
std::vector<std::string> deviceTypes;
|
||||
|
||||
const char* configuration = getenv("OPENCV_OPENCL_DEVICE");
|
||||
if (!configuration)
|
||||
configuration = getenv("OPENCV_OPENCL_DEVICE");
|
||||
|
||||
if (configuration &&
|
||||
(strcmp(configuration, "disabled") == 0 ||
|
||||
!parseOpenCLDeviceConfiguration(std::string(configuration), platform, deviceTypes, deviceName)
|
||||
@@ -1744,22 +1745,24 @@ static cl_device_id selectOpenCLDevice()
|
||||
platforms.resize(numPlatforms);
|
||||
}
|
||||
|
||||
int selectedPlatform = -1;
|
||||
if (platform.length() > 0)
|
||||
{
|
||||
for (size_t i = 0; i < platforms.size(); i++)
|
||||
for (std::vector<cl_platform_id>::iterator currentPlatform = platforms.begin(); currentPlatform != platforms.end();)
|
||||
{
|
||||
std::string name;
|
||||
CV_OCL_DBG_CHECK(getStringInfo(clGetPlatformInfo, platforms[i], CL_PLATFORM_NAME, name));
|
||||
CV_OCL_DBG_CHECK(getStringInfo(clGetPlatformInfo, *currentPlatform, CL_PLATFORM_NAME, name));
|
||||
if (name.find(platform) != std::string::npos)
|
||||
{
|
||||
selectedPlatform = (int)i;
|
||||
break;
|
||||
++currentPlatform;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentPlatform = platforms.erase(currentPlatform);
|
||||
}
|
||||
}
|
||||
if (selectedPlatform == -1)
|
||||
if (platforms.size() == 0)
|
||||
{
|
||||
std::cerr << "ERROR: Can't find OpenCL platform by name: " << platform << std::endl;
|
||||
CV_LOG_ERROR(NULL, "OpenCL: Can't find OpenCL platform by name: " << platform);
|
||||
goto not_found;
|
||||
}
|
||||
}
|
||||
@@ -1778,7 +1781,7 @@ static cl_device_id selectOpenCLDevice()
|
||||
{
|
||||
int deviceType = 0;
|
||||
std::string tempStrDeviceType = deviceTypes[t];
|
||||
std::transform(tempStrDeviceType.begin(), tempStrDeviceType.end(), tempStrDeviceType.begin(), char_tolower);
|
||||
std::transform(tempStrDeviceType.begin(), tempStrDeviceType.end(), tempStrDeviceType.begin(), details::char_tolower);
|
||||
|
||||
if (tempStrDeviceType == "gpu" || tempStrDeviceType == "dgpu" || tempStrDeviceType == "igpu")
|
||||
deviceType = Device::TYPE_GPU;
|
||||
@@ -1790,17 +1793,15 @@ static cl_device_id selectOpenCLDevice()
|
||||
deviceType = Device::TYPE_ALL;
|
||||
else
|
||||
{
|
||||
std::cerr << "ERROR: Unsupported device type for OpenCL device (GPU, CPU, ACCELERATOR): " << deviceTypes[t] << std::endl;
|
||||
CV_LOG_ERROR(NULL, "OpenCL: Unsupported device type for OpenCL device (GPU, CPU, ACCELERATOR): " << deviceTypes[t]);
|
||||
goto not_found;
|
||||
}
|
||||
|
||||
std::vector<cl_device_id> devices; // TODO Use clReleaseDevice to cleanup
|
||||
for (int i = selectedPlatform >= 0 ? selectedPlatform : 0;
|
||||
(selectedPlatform >= 0 ? i == selectedPlatform : true) && (i < (int)platforms.size());
|
||||
i++)
|
||||
std::vector<cl_device_id> devices;
|
||||
for (std::vector<cl_platform_id>::iterator currentPlatform = platforms.begin(); currentPlatform != platforms.end(); ++currentPlatform)
|
||||
{
|
||||
cl_uint count = 0;
|
||||
cl_int status = clGetDeviceIDs(platforms[i], deviceType, 0, NULL, &count);
|
||||
cl_int status = clGetDeviceIDs(*currentPlatform, deviceType, 0, NULL, &count);
|
||||
if (!(status == CL_SUCCESS || status == CL_DEVICE_NOT_FOUND))
|
||||
{
|
||||
CV_OCL_DBG_CHECK_RESULT(status, "clGetDeviceIDs get count");
|
||||
@@ -1809,7 +1810,7 @@ static cl_device_id selectOpenCLDevice()
|
||||
continue;
|
||||
size_t base = devices.size();
|
||||
devices.resize(base + count);
|
||||
status = clGetDeviceIDs(platforms[i], deviceType, count, &devices[base], &count);
|
||||
status = clGetDeviceIDs(*currentPlatform, deviceType, count, &devices[base], &count);
|
||||
if (!(status == CL_SUCCESS || status == CL_DEVICE_NOT_FOUND))
|
||||
{
|
||||
CV_OCL_DBG_CHECK_RESULT(status, "clGetDeviceIDs get IDs");
|
||||
@@ -1841,13 +1842,16 @@ not_found:
|
||||
if (!configuration)
|
||||
return NULL; // suppress messages on stderr
|
||||
|
||||
std::cerr << "ERROR: Requested OpenCL device not found, check configuration: " << configuration << std::endl
|
||||
<< " Platform: " << (platform.length() == 0 ? "any" : platform) << std::endl
|
||||
<< " Device types: ";
|
||||
std::ostringstream msg;
|
||||
msg << "ERROR: Requested OpenCL device not found, check configuration: '" << configuration << "'" << std::endl
|
||||
<< " Platform: " << (platform.length() == 0 ? "any" : platform) << std::endl
|
||||
<< " Device types:";
|
||||
for (size_t t = 0; t < deviceTypes.size(); t++)
|
||||
std::cerr << deviceTypes[t] << " ";
|
||||
msg << ' ' << deviceTypes[t];
|
||||
|
||||
std::cerr << std::endl << " Device name: " << (deviceName.length() == 0 ? "any" : deviceName) << std::endl;
|
||||
msg << std::endl << " Device name: " << (deviceName.length() == 0 ? "any" : deviceName);
|
||||
|
||||
CV_LOG_ERROR(NULL, msg.str());
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
@@ -2774,19 +2778,33 @@ struct Kernel::Impl
|
||||
|
||||
void cleanupUMats()
|
||||
{
|
||||
bool exceptionOccurred = false;
|
||||
for( int i = 0; i < MAX_ARRS; i++ )
|
||||
{
|
||||
if( u[i] )
|
||||
{
|
||||
if( CV_XADD(&u[i]->urefcount, -1) == 1 )
|
||||
{
|
||||
u[i]->flags |= UMatData::ASYNC_CLEANUP;
|
||||
u[i]->currAllocator->deallocate(u[i]);
|
||||
try
|
||||
{
|
||||
u[i]->currAllocator->deallocate(u[i]);
|
||||
}
|
||||
catch(const std::exception& exc)
|
||||
{
|
||||
// limited by legacy before C++11, therefore log and
|
||||
// remember some exception occurred to throw below
|
||||
CV_LOG_ERROR(NULL, "OCL: Unexpected C++ exception in OpenCL Kernel::Impl::cleanupUMats(): " << exc.what());
|
||||
exceptionOccurred = true;
|
||||
}
|
||||
}
|
||||
u[i] = 0;
|
||||
}
|
||||
}
|
||||
nu = 0;
|
||||
haveTempDstUMats = false;
|
||||
haveTempSrcUMats = false;
|
||||
CV_Assert(!exceptionOccurred);
|
||||
}
|
||||
|
||||
void addUMat(const UMat& m, bool dst)
|
||||
@@ -2805,7 +2823,6 @@ struct Kernel::Impl
|
||||
void registerImageArgument(int arg, const Image2D& image)
|
||||
{
|
||||
CV_CheckGE(arg, 0, "");
|
||||
CV_CheckLT(arg, (int)MAX_ARRS, "");
|
||||
if (arg < (int)shadow_images.size() && shadow_images[arg].ptr() != image.ptr()) // TODO future: replace ptr => impl (more strong check)
|
||||
{
|
||||
CV_Check(arg, !isInProgress, "ocl::Kernel: clearing of pending Image2D arguments is not allowed");
|
||||
@@ -2818,8 +2835,16 @@ struct Kernel::Impl
|
||||
void finit(cl_event e)
|
||||
{
|
||||
CV_UNUSED(e);
|
||||
cleanupUMats();
|
||||
isInProgress = false;
|
||||
try
|
||||
{
|
||||
cleanupUMats();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
release();
|
||||
throw;
|
||||
}
|
||||
release();
|
||||
}
|
||||
|
||||
@@ -2960,6 +2985,10 @@ bool Kernel::empty() const
|
||||
|
||||
static cv::String dumpValue(size_t sz, const void* p)
|
||||
{
|
||||
if (!p)
|
||||
return "NULL";
|
||||
if (sz == 2)
|
||||
return cv::format("%d / %uu / 0x%04x", *(short*)p, *(unsigned short*)p, *(short*)p);
|
||||
if (sz == 4)
|
||||
return cv::format("%d / %uu / 0x%08x / %g", *(int*)p, *(int*)p, *(int*)p, *(float*)p);
|
||||
if (sz == 8)
|
||||
@@ -3132,6 +3161,14 @@ bool Kernel::run(int dims, size_t _globalsize[], size_t _localsize[],
|
||||
}
|
||||
|
||||
|
||||
bool Kernel::run_(int dims, size_t _globalsize[], size_t _localsize[],
|
||||
bool sync, const Queue& q)
|
||||
{
|
||||
CV_Assert(p);
|
||||
return p->run(dims, _globalsize, _localsize, sync, NULL, q);
|
||||
}
|
||||
|
||||
|
||||
static bool isRaiseErrorOnReuseAsyncKernel()
|
||||
{
|
||||
static bool initialized = false;
|
||||
@@ -3172,6 +3209,10 @@ bool Kernel::Impl::run(int dims, size_t globalsize[], size_t localsize[],
|
||||
return false; // OpenCV 5.0: raise error
|
||||
}
|
||||
|
||||
#if CV_OPENCL_SYNC_RUN_KERNELS
|
||||
sync = true;
|
||||
#endif
|
||||
|
||||
cl_command_queue qq = getQueue(q);
|
||||
if (haveTempDstUMats)
|
||||
sync = true;
|
||||
@@ -3602,7 +3643,28 @@ struct Program::Impl
|
||||
if (!param_buildExtraOptions.empty())
|
||||
buildflags = joinBuildOptions(buildflags, param_buildExtraOptions);
|
||||
}
|
||||
#if CV_OPENCL_SHOW_BUILD_OPTIONS
|
||||
CV_LOG_INFO(NULL, "OpenCL program '" << sourceModule_ << "/" << sourceName_ << "' options:" << buildflags);
|
||||
#endif
|
||||
compile(ctx, src_, errmsg);
|
||||
#if CV_OPENCL_SHOW_BUILD_KERNELS
|
||||
if (handle)
|
||||
{
|
||||
size_t retsz = 0;
|
||||
char kernels_buffer[4096] = {0};
|
||||
cl_int result = clGetProgramInfo(handle, CL_PROGRAM_KERNEL_NAMES, sizeof(kernels_buffer), &kernels_buffer[0], &retsz);
|
||||
CV_OCL_DBG_CHECK_RESULT(result, cv::format("clGetProgramInfo(CL_PROGRAM_KERNEL_NAMES: %s/%s)", sourceModule_.c_str(), sourceName_.c_str()).c_str());
|
||||
if (result == CL_SUCCESS && retsz < sizeof(kernels_buffer))
|
||||
{
|
||||
kernels_buffer[retsz] = 0;
|
||||
CV_LOG_INFO(NULL, "OpenCL program '" << sourceModule_ << "/" << sourceName_ << "' kernels: '" << kernels_buffer << "'");
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_LOG_ERROR(NULL, "OpenCL program '" << sourceModule_ << "/" << sourceName_ << "' can't retrieve kernel names!");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool compile(const Context& ctx, const ProgramSource::Impl* src_, String& errmsg)
|
||||
@@ -3834,7 +3896,6 @@ struct Program::Impl
|
||||
CV_LOG_INFO(NULL, result << ": Kernels='" << kernels_buffer << "'");
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
return handle != NULL;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user