1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-22 03:43:03 +04:00

Compare commits

...

144 Commits

Author SHA1 Message Date
Alexander Alekhin e8d4259f9a release: OpenCV 3.4.11 2020-07-17 00:34:46 +00:00
Alexander Alekhin 8086afc60a Merge pull request #17865 from alalek:add_missing_check_17036 2020-07-17 00:28:33 +00:00
Alexander Alekhin b2ebd37ee2 Merge pull request #17856 from alalek:dnn_openvino_2020.4.0 2020-07-16 20:08:00 +00:00
Alexander Alekhin 83e6813345 imgproc: add missing check into cvtColorTwoPlane() 2020-07-16 20:01:44 +00:00
Alexander Alekhin 09f24a851e Merge pull request #17764 from alalek:issue_17762 2020-07-16 15:27:21 +00:00
Alexander Alekhin 81e027eef7 dnn: fix OpenCL implementation of Slice layer 2020-07-16 04:33:52 +00:00
Alexander Alekhin 1c371d07b5 dnn(test): adjust tests for OpenVINO 2020.4 2020-07-15 23:47:40 +00:00
Alexander Alekhin 55e8549839 dnn: eliminate IE deprecation warning 2020-07-15 23:39:06 +00:00
Alexander Alekhin f8d6c5b330 winpack_dldt: switch defaults to OpenVINO 2020.4 2020-07-15 22:13:19 +00:00
Alexander Alekhin 435b6df989 dnn: use OpenVINO 2020.4 defines
original commit: 2813aa7eb9
2020-07-15 20:13:40 +00:00
Alexander Alekhin bf8136eaa6 Merge pull request #17849 from dkurt:fix_17848 2020-07-15 18:53:46 +00:00
Dmitry Kurtaev cc584760d3 Fix TensorFlow->ONNX imports 2020-07-15 14:36:13 +03:00
Alexander Alekhin d41b20b268 Merge pull request #17830 from alalek:fix_17815 2020-07-13 18:52:34 +00:00
Alexander Alekhin 36da867caf features2d: v_fma => v_muladd for integers 2020-07-13 17:31:08 +00:00
Alexander Alekhin c5f540e3d7 Merge pull request #17806 from alalek:dnn_ie_num_threads_windows 2020-07-13 17:12:31 +00:00
pemmanuelviel c90e824342 Merge pull request #17639 from pemmanuelviel:pev--binary-kmeans
Pev binary kmeans

* Ongoing work transposing kmeans clustering method for bitfields: the computeClustering method

Ongoing work transposing kmeans clustering method for bitfields: interface computeBitfieldClustering

Fix genericity of computeNodeStatistics

Ongoing work transposing kmeans clustering method for bitfields: adapt computeNodeStatistics()

Ongoing work transposing kmeans clustering method for bitfields: adapt findNN() method

Ongoing work transposing kmeans clustering method for bitfields: allow kmeans with Hamming distance

Ongoing work transposing kmeans clustering method for bitfields: adapt distances code

Ongoing work transposing kmeans clustering method for bitfields: adapt load/save code

Ongoing work transposing kmeans clustering method for bitfields: adapt kmeans hierarchicalClustring()

PivotType -> CentersType Renaming

Fix type casting for ARM SIMD implementation of Hamming

Fix warnings with Win32 compilation

Fix warnings with Win64 compilation

Fix wrong parenthesis position on rounding

* Ensure proper rounding when CentersType is integral
2020-07-13 12:59:10 +00:00
jasonKercher 749bd80091 Merge pull request #17770 from jasonKercher:3.4_triggered
3.4 Allow first capture to return false

* fix first capture timeout

* fix first capture timeout
2020-07-13 12:29:54 +00:00
Alexander Alekhin 1c0b70bbd2 Merge pull request #17822 from alalek:issue_17792 2020-07-13 11:08:33 +00:00
Alexander Alekhin b75f6c05c0 Merge pull request #17805 from tomoaki0705:fixCUDAHostCompilerIssue 2020-07-12 13:05:14 +00:00
Tomoaki Teshima 269b810601 re-enable automatic CC detection on Jetson
* treat both CMAKE_C_COMPILER and c_compiler_realpath as candidate
2020-07-12 21:22:12 +09:00
Alexander Alekhin e54040d540 core: use lazy on-demand initialization for param_traceEnable 2020-07-12 11:53:46 +00:00
Alexander Alekhin b96e9a4a4a Merge pull request #17800 from Yosshi999:gsoc_sift-universal-intrinsic 2020-07-11 19:09:21 +00:00
Alexander Alekhin e18df87a15 Merge pull request #17635 from jsxyhelu:3.4 2020-07-10 15:11:53 +00:00
Alexander Alekhin 5cb8619eca dnn(ie): enable KEY_CPU_THREADS_NUM for Windows 2020-07-10 14:29:21 +00:00
jsxyhelu 476094ad5a Use“ moms” replace "contourArea"
double area = moms.m00;
is same as
double area = contourArea(contours[contourIdx]);
Not to mention
"moms" already calculated here,"contourArea" should not apply
2020-07-10 11:05:24 +00:00
Alexander Alekhin d2469edd10 Merge pull request #17772 from mshabunin:fix-match-umat-mask 2020-07-10 10:53:56 +00:00
Yosshi999 0df8fb70b4 use bufferarea for allocating buffer 2020-07-09 16:50:20 +00:00
Maksim Shabunin 4dd9a36a3c Added test for checkMasks with UMat train descs 2020-07-09 16:22:19 +03:00
Maksim Shabunin 41678fe3d3 Fixed checkMasks in DescriptorMatcher with train descs in UMats 2020-07-09 16:05:20 +03:00
Alexander Alekhin 5bc6b6fc26 Merge pull request #17737 from pemmanuelviel:pev--fix-trees-descent 2020-07-08 20:59:29 +00:00
Alexander Alekhin 8931c68b20 Merge pull request #17707 from Yosshi999:gsoc_sift-universal-intrinsic 2020-07-08 20:33:40 +00:00
Alexander Alekhin f78f908c09 Merge pull request #17674 from alalek:issue_16214 2020-07-08 20:01:35 +00:00
Alexander Alekhin 5487bca4f3 Merge pull request #17777 from alalek:backport_cuda_cmake 2020-07-08 20:00:13 +00:00
Alexander Alekhin 762a5c8334 imgproc: align GaussianBlur/sepFilter2D OpenCL with CPU version 2020-07-08 15:13:48 +00:00
Alexander Alekhin 2fed41dfa5 imgproc(test): test bitExact cases in OCL/sepFilter2D 2020-07-08 10:14:56 +00:00
Alexander Alekhin e0f9eac521 cmake: backport CUDA scripts 2020-07-08 07:33:54 +00:00
Alexander Alekhin b90a2a8497 Merge pull request #17759 from alalek:build_opencv_winpack_dldt_2020.4.0 2020-07-07 19:28:53 +00:00
Alexander Alekhin 950a916952 Merge pull request #17752 from YashasSamaga:generalize-concat-fusion-3.4 2020-07-07 10:36:02 +00:00
Alexander Alekhin 3f13339071 Merge pull request #17728 from sturkmen72:patch-4 2020-07-06 23:01:27 +00:00
Alexander Alekhin eb6678ebef Merge pull request #17699 from alalek:build_core_cuda
* core(cuda): fix build

- MSVS 19.25.28612.0
- CUDA release 11.0, V11.0.167

* cmake(cuda): backport workaround for CUDA 11

* cmake(cuda): call CUDA_BUILD_CLEAN_TARGET() on finalize

* cmake(cuda): use CMAKE_SUPPRESS_REGENERATION with MSVS
2020-07-06 22:58:17 +00:00
Alexander Alekhin d62e0a3695 Merge pull request #17743 from alalek:test_17666 2020-07-06 22:36:35 +00:00
Alexander Alekhin dcb7fd8520 Merge pull request #17766 from alalek:backport_17756 2020-07-06 21:50:24 +00:00
Alexander Alekhin d5713c657b dnn(slice): disable buggy OCV/OCL implementation 2020-07-06 21:36:19 +00:00
Alexander Alekhin 99c4b76a6d dnn(test): add YOLOv4-tiny tests 2020-07-06 21:36:19 +00:00
Alexander Alekhin e4887aaa5b Merge pull request #17761 from mshabunin:test-wo-jpg-png 2020-07-06 20:02:15 +00:00
Ilya Churaev d69a7a3bbf Fixed header paths for some nGraph ops
* Added dependency on IE version

backport of commit: 992c908b56
2020-07-06 19:51:57 +00:00
Alexander Alekhin ccf6dd07b3 build: winpack_dldt with dldt 2020.4.0 2020-07-06 14:08:54 +00:00
Maksim Shabunin e8129429e9 imgcodecs: fix test build with disabled JPEG and PNG libs 2020-07-06 14:52:52 +03:00
Suleyman TURKMEN 2566d13100 Update documentation of imwrite() 2020-07-06 11:02:50 +03:00
Alexander Alekhin 5a15369d4d Merge pull request #17729 from modeste2015:3.4 2020-07-04 17:17:57 +00:00
Alexander Alekhin deaf1dd458 Merge pull request #17724 from pemmanuelviel:pev--fix-mix-of-types 2020-07-04 17:16:57 +00:00
pemmanuelviel 65f87b114b Merge pull request #17722 from pemmanuelviel:pev--replace-asserts
* Clean: replace C style asserts by CV_Assert and CV_DbgAssert

* Try fixing warning on Windows compilation

* Another way trying to fix warnings on Win

* Fixing warnings with some compilers:
Some compilers warn on systematic exit preventing to execute the code that follows.
This is why assert(0) that exits only in debug was working, but not CV_Assert or CV_Error
that exit both in release and debug, even if with different behavior.
In addition, other compilers complain when return 0 is removed from getKey(),
even if before we have a statement leading to systematic exit.

* Disable "unreachable code" warnings for Win compilers so we can use proper CV_Error
2020-07-04 20:15:44 +03:00
Alexander Alekhin 8f5b453a96 Merge pull request #17719 from pemmanuelviel:pev--fix-computeNodeStatistics-genericity 2020-07-04 17:14:35 +00:00
YashasSamaga b7eec216e9 generalize axis for concat fusion 2020-07-04 18:57:28 +05:30
Alexander Alekhin dc57707e60 Merge pull request #17744 from alalek:issue_17657 2020-07-03 21:21:27 +00:00
Alexander Alekhin 56b5a7d977 cmake: fix ENABLE_PROFILING 2020-07-03 19:31:41 +00:00
Liubov Batanina 65dbbf712d Merge pull request #17733 from l-bat:tiny_yolov4
* Supported yolov4-tiny

* Added comments
2020-07-03 18:07:08 +00:00
Alexander Alekhin 49497d8e7c Merge pull request #17725 from pemmanuelviel:pev--precompute-divisor 2020-07-03 11:24:11 +00:00
Pierre-Emmanuel Viel 728684840c Fix trees parsing behavior in hierarchical_clustering_index:
Before, when maxCheck was reached in the first descent of a tree, time was still wasted parsing
the next trees till their best leaves whose points were not used at all.
2020-07-03 01:19:10 +02:00
Alexander Alekhin 73f7d091f8 Merge pull request #17721 from pemmanuelviel:pev--fix-hist-intersect-arguments 2020-07-02 11:54:28 +00:00
Ken Shirriff 00e1bc49c8 Merge pull request #17708 from shirriff:patch-1
Clarify component statistics documentation

* Change ConnectedComponentsTypes documentation

Change from "algorithm output formats" to "statistics" because it specifies types of statistics, not formats.

* Documentation: clarify component statistics

Explain that ConnectedComponentTypes selects a statistic.
2020-07-02 13:58:53 +03:00
Heritier Kinke cb3a098b25 forget to look in sub folder of include/openblas 2020-07-02 03:33:07 +02:00
Alexander Alekhin 5a7045181a Merge pull request #17723 from pemmanuelviel:pev--remove-duplicate 2020-07-01 18:14:08 +00:00
Pierre-Emmanuel Viel 6a045fd678 Fix arguments list in loadindex for histogram intersection 2020-07-01 18:59:45 +02:00
Pierre-Emmanuel Viel 327f92cc46 Precompute the divisor to ensure that no kind of compiler would process it on the fly at each call. 2020-07-01 18:52:05 +02:00
Pierre-Emmanuel Viel 482cacd420 Mix of 32 and 64bits vector types prevents vectorisation for distance computation.
Argument "a" is of type ElementType* that is either int* or float*, while b was double*.
Mixing types prevents the possibility to use SSE or AVX instructions.
On implementation without SIMD instructions, this doesn't show any impact on performance.
2020-07-01 18:27:07 +02:00
Pierre-Emmanuel Viel 93a6be836c Remove duplicate line 2020-07-01 18:15:01 +02:00
Pierre-Emmanuel Viel ef7185ce43 Fix genericity of computeNodeStatistics that couldn't compute stats properly on sub-nodes 2020-07-01 12:14:15 +02:00
Yosshi999 920c180052 use universal SIMD intrinsics for SIFT 2020-06-30 06:44:12 +00:00
Alexander Alekhin a84afb6334 Merge pull request #17640 from pemmanuelviel:pev--fix-lsh-bad-any-cast 2020-06-29 20:53:34 +00:00
Pierre-Emmanuel Viel cdac7c7bec Add test checking we don't throw when creating GenericIndex with LshIndexParams() 2020-06-28 19:51:04 +00:00
Pierre-Emmanuel Viel fe09c79f4b Fix the 'cvflann::anyimpl::bad_any_cast' error using Lsh 2020-06-28 19:51:04 +00:00
Alexander Alekhin cabad90d6c Merge pull request #17636 from okamotoR:3.4 2020-06-27 20:17:16 +00:00
Alexander Alekhin 6dba1733f0 Merge pull request #17567 from dev-tronifier:new_branch 2020-06-27 20:08:37 +00:00
pemmanuelviel daa88c6b9e Merge pull request #17642 from pemmanuelviel:pev--fixes-and-clean
* Clean: make the use of the indices array length consistent

Either we don't want this method to be used in the future for any other node
than the root node, and so we replace indices_length by size_ and remove it as
argument, or we want to be able to use it potentially for other nodes, and
so using size_ instead of indices_length would have lead to a bug.

* Fix: b was not an address

* Fix: transpose the Flann repo commit "Fixes in accum_dist methods" from Adil Ibragimov

Avoids trying to compute log(ratio) with ratio = 0

* Fix: transpose the Flann repo commit "result_set bugfix" from Jack Rae

* Fix Jack Rae commit as the initial i - 1 index was decremented before entering the loop body

* Clean: transpose the Flann repo commit "Updated comments in lsh_index" from Richard McPherson

* Fix: Transpose the Flann repo commit "Fixing unreachable code in lsh_table.h" from hypevr

* Fix warning the same way it was done in flann standalone repo

* Change the return value in case of unsupported type
2020-06-26 22:34:52 +00:00
dev-tronifier 9b727fa1f3 Increased portability of CV_Func 2020-06-26 19:45:58 +00:00
Alexander Alekhin e45d74c8f9 Merge pull request #17638 from pemmanuelviel:pev--avoid-branching-in-loop 2020-06-26 19:22:20 +00:00
Alexander Alekhin 923009b5ff Merge pull request #17663 from alalek:backport_17658 2020-06-26 17:41:53 +00:00
Yosshi999 4064d4c7eb Merge pull request #17618 from Yosshi999:gsoc_sift-better-test
Added/Fixed testcases for SIFT

* merge perf_sift into conventional perf tests

* Fix disabled SIFT scale invariance tests

allows trainIdx duplication in matching scaled keypoints
2020-06-25 11:34:31 +00:00
Ilya Lavrenov e58ce89b10 Conditional compilation for IR v7 support
backported commit 86905754e4
2020-06-25 10:05:14 +00:00
Alexander Alekhin 6259ba1bfd Merge pull request #17641 from pemmanuelviel:pev--fix-middleSplit-for-kdtree-single 2020-06-25 09:12:40 +00:00
Alexander Alekhin cd8262eb79 Merge pull request #17650 from alalek:update_libjpeg-turbo 2020-06-24 10:57:37 +00:00
Alexander Alekhin d2b854674e Merge pull request #17648 from alalek:update_libjpeg 2020-06-24 10:57:07 +00:00
Alexander Alekhin ad930f6216 3rdparty: libjpeg-turbo 2.0.4 => 2.0.5
https://github.com/libjpeg-turbo/libjpeg-turbo/releases/tag/2.0.5
2020-06-24 06:28:16 +00:00
Alexander Alekhin f061a0ab36 3rdparty: libjpeg 9d
http://www.ijg.org/files/jpegsrc.v9d.tar.gz
2020-06-23 20:35:56 +00:00
Alexander Alekhin 2e165053ef Merge pull request #17624 from dkurt:dnn_optimize_mish 2020-06-23 18:43:51 +00:00
Alexander Alekhin 8cc8b0d2b4 Merge pull request #17633 from alalek:backport_17616 2020-06-23 18:29:55 +00:00
Pierre-Emmanuel Viel 06b4292534 Fix: error in the dimension used for computeMinMax
Instead of using the current dimension for which we just got a big span,
we were computing Min and Max for the previous dimension stored in cutfeat
(and using 0 instead of the dimension indice for the very first dimension
with "span > (1-eps)max_span")
2020-06-23 15:47:27 +02:00
Pierre-Emmanuel Viel 29f883feee Optim: test that could be done once has been extracted from the loop 2020-06-23 15:43:38 +02:00
okamotoR 0e69cddda2 add if block for indexed color images 2020-06-23 21:36:47 +09:00
Ilya Lavrenov ad5e70f94e Conditional compilation for network reader
origibal commit: 63e92cccf2
2020-06-23 14:15:52 +03:00
Alexander Alekhin 7fae2e834c Merge pull request #17622 from dkurt:dnn_ie_cpu_ext_update 2020-06-23 11:01:47 +00:00
Dmitry Kurtaev 8e3f5fb209 Remove deprecated Inference Engine CPU extensions 2020-06-23 10:10:29 +03:00
Dmitry Kurtaev 1491934d17 Optimize Mish for CPU backend 2020-06-22 23:27:47 +03:00
Alexander Alekhin fce486c4f9 Merge pull request #17592 from l-bat:disable_nms_in_yolo_layer 2020-06-22 10:31:33 +00:00
Alexander Alekhin 1b4955342f Merge pull request #17599 from tomoaki0705:fixCUDAFailSafePath 2020-06-21 17:49:14 +00:00
Tomoaki Teshima 95ac650af6 make the fail safe path actually safe
* use only supported CC in the list
  * workaround of #17526
2020-06-21 07:20:47 +09:00
Alexander Alekhin 2b98aa403e Merge pull request #17593 from tomoaki0705:addAmpereCUDA 2020-06-20 22:01:36 +00:00
Alexander Alekhin 425c653a14 Merge pull request #17580 from sitic:bibfix 2020-06-19 21:35:07 +00:00
Tomoaki Teshima 52844614c4 add Ampere CC
* Ampere has CC 8.0
  * Arm64 server support has been added in CUDA 11 (only V100 for now)
2020-06-19 20:46:18 +09:00
Liubov Batanina 85c0c8c7ed Disabling dafault NMS in yolo layer 2020-06-19 14:34:13 +03:00
Jan Lebert a8f04359e8 docs: linkfix in bibliography
The [current link](https://arxiv.org/pdf/1808.01752) goes to a
random unrelated paper.
2020-06-19 11:44:35 +02:00
Alexander Alekhin cb54f4c2ec Merge pull request #17587 from tomoaki0705:fixCUDAOptflowJetson 2020-06-19 07:21:19 +00:00
Tomoaki Teshima 77fa1a20bf fix build on Jetson TX1 and TX2
* enable_if_t is a c++14 feature
2020-06-19 07:56:37 +09:00
Alexander Alekhin a7cdc42140 Merge pull request #17581 from tomoaki0705:fixCudaAsync 2020-06-18 20:54:28 +00:00
Alexander Alekhin a8aa9d5ecb Merge pull request #17578 from Bleach665:fix_win_eigen_build 2020-06-18 20:52:33 +00:00
Alexander Alekhin 52fbfb3ec0 Merge pull request #17577 from philippefoubert:branch_color_yuv_simd 2020-06-18 20:51:52 +00:00
Philippe FOUBERT d25293b721 Fix the build of imgproc using MinGW (variables with the same name as symbols defined in MinGW headers) 2020-06-18 20:13:34 +00:00
Tomoaki Teshima c07af090f5 fix build error on Jetson TX1 and TX2
* enable_if_t and is_base_of is c++14 feature
 * override is c++11 feature
2020-06-18 21:25:15 +09:00
Yuriy Obukh 456e88a8a4 fix VS Windows build with eigen. https://github.com/opencv/opencv/issues/17548 2020-06-18 14:31:11 +03:00
Alex Cohn a7cc1159cd Merge pull request #17573 from alexcohn:fix/android_windows_build
* fixing #17572

https://github.com/opencv/opencv/issues/17572 Build for Android failed: "can't concat str to bytes"

on Windows 10 64bit with python 3.6.6

* similar to changes in platforms/winpack_dldt/build_package.py
2020-06-18 10:40:43 +03:00
Alexander Alekhin 6bd87e8146 Merge pull request #17571 from tomoaki0705:fixAutomaticCC 2020-06-18 07:39:14 +00:00
Alexander Alekhin 42a4c3fba6 Merge pull request #17568 from alalek:cleanup_17527 2020-06-18 07:38:16 +00:00
Tomoaki Teshima 1cba763189 fix build error of automatic CC detection 2020-06-17 22:02:51 +09:00
Alexander Alekhin d01cbe9320 cudacodec(build): fix detection in CMake, cleanup duplicate includes 2020-06-17 09:09:40 +00:00
NesQl b10ab79743 Merge pull request #17468 from liqi-c:sharedlib_build_problem
TEngine installation rules fix for static build

* Modify cmake config error for -DBUILD_SHARED_LIBS=OFF

* Modify for not install tengine include directory

* Update compile error.

* move install command to tengine/CMakeLists.txt

* rm include dir when make install,only build static lib will install libtengine.a
2020-06-17 09:05:04 +00:00
Alexander Alekhin 619462b029 Merge pull request #17564 from l-bat:fix_yolov4 2020-06-17 08:45:56 +00:00
Liubov Batanina d93b6be3cc Changed StridedSlice to VariadicSplit in Region layer 2020-06-17 10:02:53 +03:00
Alexander Alekhin 9755ab160d Merge pull request #17556 from nglee:dev_optFlowTVL1Async 2020-06-16 20:06:56 +00:00
Namgoo Lee 2043e06102 cuda optflow tvl1 : async safety
also modify cuda canny to use createTextureObjectPitch2D, etc.
2020-06-17 01:04:22 +09:00
Alexander Alekhin c7dcdc0e88 Merge pull request #17557 from alalek:backport_17554 2020-06-15 19:26:11 +00:00
Alexander Alekhin eb67dc9f50 Merge pull request #17533 from alalek:fix_dumpInputArray_nd_case 2020-06-15 18:38:19 +00:00
Ilya Lavrenov 676b818d6a Removed plugin dispatcher
backport of commit 74113737f3
2020-06-15 18:03:14 +00:00
Namgoo Lee 411ce04f54 CUDA_OptFlow/OpticalFlowDual_TVL1 Asynchronous test 2020-06-16 01:43:51 +09:00
Alexander Alekhin d321a34f7c Merge pull request #17527 from tomoaki0705:detectCuvidHeader 2020-06-14 11:08:16 +00:00
Alexander Alekhin fb1a58ac76 Merge pull request #17537 from Murazaki:patch-1 2020-06-13 18:36:34 +00:00
Alexander Alekhin 1644af841b Merge pull request #17536 from ilya-lavrenov:remove-error-listener 2020-06-12 22:18:04 +00:00
Mehdi Zakaria Benadel b0def9617f Fix typo
This typo just made me lose my mind on the conan package update. please merge.
2020-06-12 23:52:06 +02:00
Alexander Alekhin c2664d912a Merge pull request #17538 from alalek:dnn_openvino_2020.3.0 2020-06-12 21:24:35 +00:00
Ilya Lavrenov 9697e3ac24 Removed error lisneter usage 2020-06-12 20:29:11 +00:00
Alexander Alekhin d2a9efd039 dnn: use OpenVINO 2020.3 defines 2020-06-12 20:24:08 +00:00
Alexander Alekhin 442999dcdb core: fix handling of ND-arrays in dumpInputArray() helpers 2020-06-12 10:23:32 +00:00
Alexander Alekhin d753ae1489 Merge pull request #17143 from cyyever:detect_mkl_installed_by_nuget 2020-06-12 09:44:42 +00:00
cyy db3e3be8ee improve the mkl search procedure 2020-06-12 06:59:27 +00:00
Alexander Alekhin 0c8da03869 Merge pull request #17341 from hunter-college-ossd-spr-2020:3.4-1 2020-06-12 06:58:14 +00:00
Jessica Wong 0417c8c9c7 Added information to OpenCV documentation [MacOS]
Added and Edited specific information to the "Installation in MacOS" OpenCV documentation.
Closes #17340
2020-06-11 23:36:06 -04:00
Tomoaki Teshima d4af89781b fix corner case of libnvcuvid
* detect header automatically and not based on version number
2020-06-11 23:06:18 +09:00
Alexander Alekhin a8c1cdf88e Merge pull request #17511 from mshabunin:fix-kw-issues-34 2020-06-10 12:13:06 +00:00
Maksim Shabunin 7a187e9b5e QRDetectMulti: refactored checkPoints method 2020-06-10 13:48:24 +03:00
Maksim Shabunin 9096b1c768 dnn/NGraph: added nullptr checks 2020-06-10 13:48:24 +03:00
Rasmus 781fbde449 Merge pull request #17368 from themightyoarfish:cv2eigen-doc
* Add documentation about usage of cv2eigen functions in eigen.hpp

* Fixed Doxygen syntax.

Co-authored-by: Alexander Smorkalov <smorkalov.a.m@gmail.com>
2020-06-10 07:53:18 +00:00
Gourav Roy 1b336bb602 Merge pull request #16955 from themechanicalcoder:text_recognition
* add text recognition sample

* fix pylint warning

* made changes according to the c++ example

* fix errors

* add text recognition sample

* update text detection sample
2020-06-10 06:53:18 +00:00
Alexander Alekhin 0fb3b8db72 Merge pull request #17504 from alalek:update_ffmpeg_3.4 2020-06-09 07:51:59 +00:00
Alexander Alekhin b44302382d ffmpeg/3.4: update FFmpeg wrapper
- FFmpeg 3.4.7
2020-06-08 21:03:05 +00:00
142 changed files with 4092 additions and 1645 deletions
+5 -5
View File
@@ -1,8 +1,8 @@
# Binaries branch name: ffmpeg/3.4_20200310
# Binaries were created for OpenCV: 4966186e10e2a940514d8c20447ca4a828af5f46
ocv_update(FFMPEG_BINARIES_COMMIT "e81ccda615672833b578c6cefdb859ad69c560ba")
ocv_update(FFMPEG_FILE_HASH_BIN32 "301ae2000e25f800ab8e0065f277ad28")
ocv_update(FFMPEG_FILE_HASH_BIN64 "d87ce032289c3f811d02f0c3d8dbe366")
# Binaries branch name: ffmpeg/3.4_20200608
# Binaries were created for OpenCV: 458f1d5ebe31e22789d9d781d0ca2ca936758fde
ocv_update(FFMPEG_BINARIES_COMMIT "57064cd66d98994503b34aade3c8d8ff25007b46")
ocv_update(FFMPEG_FILE_HASH_BIN32 "6fff20f5617bd1b7362058790db52caa")
ocv_update(FFMPEG_FILE_HASH_BIN64 "15df55131471191b575668a424dff385")
ocv_update(FFMPEG_FILE_HASH_CMAKE "3b90f67f4b429e77d3da36698cef700c")
function(download_win_ffmpeg script_var)
+4 -2
View File
@@ -4,9 +4,9 @@ ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter -Wsign-compare -Wshorten-6
set(VERSION_MAJOR 2)
set(VERSION_MINOR 0)
set(VERSION_REVISION 4)
set(VERSION_REVISION 5)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION})
set(LIBJPEG_TURBO_VERSION_NUMBER 2000004)
set(LIBJPEG_TURBO_VERSION_NUMBER 2000005)
string(TIMESTAMP BUILD "opencv-${OPENCV_VERSION}-libjpeg-turbo")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
@@ -65,6 +65,8 @@ set(JPEG_LIB_VERSION 62)
# OpenCV
set(JPEG_LIB_VERSION "${VERSION}-${JPEG_LIB_VERSION}" PARENT_SCOPE)
set(THREAD_LOCAL "") # WITH_TURBOJPEG is not used
if(MSVC)
add_definitions(-W3 -wd4996 -wd4018)
endif()
+3
View File
@@ -15,6 +15,9 @@
#endif
#endif
/* How to obtain thread-local storage */
#define THREAD_LOCAL @THREAD_LOCAL@
/* Define to the full name of this package. */
#define PACKAGE_NAME "@CMAKE_PROJECT_NAME@"
+1 -2
View File
@@ -143,8 +143,7 @@ empty_mem_output_buffer(j_compress_ptr cinfo)
MEMCOPY(nextbuffer, dest->buffer, dest->bufsize);
if (dest->newbuffer != NULL)
free(dest->newbuffer);
free(dest->newbuffer);
dest->newbuffer = nextbuffer;
+3 -3
View File
@@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2010, 2012-2019, D. R. Commander.
* Copyright (C) 2010, 2012-2020, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -36,7 +36,7 @@
*/
#define JCOPYRIGHT \
"Copyright (C) 2009-2019 D. R. Commander\n" \
"Copyright (C) 2009-2020 D. R. Commander\n" \
"Copyright (C) 2011-2016 Siarhei Siamashka\n" \
"Copyright (C) 2015-2016, 2018 Matthieu Darbois\n" \
"Copyright (C) 2015 Intel Corporation\n" \
@@ -49,4 +49,4 @@
"Copyright (C) 1991-2016 Thomas G. Lane, Guido Vollbeding"
#define JCOPYRIGHT_SHORT \
"Copyright (C) 1991-2019 The libjpeg-turbo Project and many others"
"Copyright (C) 1991-2020 The libjpeg-turbo Project and many others"
+6 -13
View File
@@ -1,7 +1,7 @@
The Independent JPEG Group's JPEG software
==========================================
README for release 9c of 14-Jan-2018
README for release 9d of 12-Jan-2020
====================================
This distribution contains the ninth public release of the Independent JPEG
@@ -10,8 +10,8 @@ to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
This software is the work of Tom Lane, Guido Vollbeding, Philip Gladstone,
Bill Allombert, Jim Boucher, Lee Crocker, Bob Friesenhahn, Ben Jackson,
Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, Ge' Weijers,
and other members of the Independent JPEG Group.
John Korejwa, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi,
Ge' Weijers, and other members of the Independent JPEG Group.
IJG is not affiliated with the ISO/IEC JTC1/SC29/WG1 standards committee
(previously known as JPEG, together with ITU-T SG16).
@@ -115,7 +115,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-2018, 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
@@ -152,13 +152,6 @@ The same holds for its supporting scripts (config.guess, config.sub,
ltmain.sh). Another support script, install-sh, is copyright by X Consortium
but is also freely distributable.
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.
REFERENCES
==========
@@ -246,8 +239,8 @@ ARCHIVE LOCATIONS
The "official" archive site for this software is www.ijg.org.
The most recent released version can always be found there in
directory "files". This particular version will be archived as
http://www.ijg.org/files/jpegsrc.v9c.tar.gz, and in Windows-compatible
"zip" archive format as http://www.ijg.org/files/jpegsr9c.zip.
http://www.ijg.org/files/jpegsrc.v9d.tar.gz, and in Windows-compatible
"zip" archive format as http://www.ijg.org/files/jpegsr9d.zip.
The JPEG FAQ (Frequently Asked Questions) article is a source of some
general information about JPEG.
+49
View File
@@ -1,6 +1,55 @@
CHANGE LOG for Independent JPEG Group's JPEG software
Version 9d 12-Jan-2020
-----------------------
Optimize the optimal Huffman code table generation to produce
slightly smaller files. Thank to John Korejwa for suggestion.
Note: Requires rebuild of testimgp.jpg.
Decoding Huffman: Use default tables if tables are not defined.
Thank to Simone Azzalin for report (Motion JPEG),
and to Martin Strunz for hint.
Add sanity check in optimal Huffman code table generation.
Thank to Adam Farley for suggestion.
rdtarga.c: use read_byte(), with EOF check, instead of getc()
in read_*_pixel().
Thank to Chijin Zhou for cjpeg potential vulnerability report.
jmemnobs.c: respect the max_memory_to_use setting in
jpeg_mem_available() computation. Thank to Sheng Shu and
Dongdong She for djpeg potential vulnerability report.
jdarith.c, jdhuff.c: avoid left shift of negative value
compiler warning in decode_mcu_AC_refine().
Thank to Indu Bhagat for suggestion.
Add x64 (64-bit) platform support, avoid compiler warnings.
Thank to Jonathan Potter, Feiyun Wang, and Sheng Shu for suggestion.
Adjust libjpeg version specification for pkg-config file.
Thank to Chen Chen for suggestion.
Restore GIF read and write support from libjpeg version 6a.
Thank to Wolfgang Werner (W.W.) Heinz for suggestion.
Improve consistency in raw (downsampled) image data processing mode.
Thank to Zhongyuan Zhou for hint.
Avoid out of bounds array read (AC derived table pointers)
in start pass in jdhuff.c. Thank to Peng Li for report.
Improve code sanity (jdhuff.c).
Thank to Reza Mirzazade farkhani for reports.
Add jpegtran -drop option; add options to the crop extension and wipe
to fill the extra area with content from the source image region,
instead of gray out.
Version 9c 14-Jan-2018
-----------------------
+9 -8
View File
@@ -1,7 +1,7 @@
/*
* jcarith.c
*
* Developed 1997-2013 by Guido Vollbeding.
* Developed 1997-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -181,11 +181,11 @@ finish_pass (j_compress_ptr cinfo)
if (e->zc) /* output final pending zero bytes */
do emit_byte(0x00, cinfo);
while (--e->zc);
emit_byte((e->c >> 19) & 0xFF, cinfo);
emit_byte((int) ((e->c >> 19) & 0xFF), cinfo);
if (((e->c >> 19) & 0xFF) == 0xFF)
emit_byte(0x00, cinfo);
if (e->c & 0x7F800L) {
emit_byte((e->c >> 11) & 0xFF, cinfo);
emit_byte((int) ((e->c >> 11) & 0xFF), cinfo);
if (((e->c >> 11) & 0xFF) == 0xFF)
emit_byte(0x00, cinfo);
}
@@ -280,7 +280,8 @@ arith_encode (j_compress_ptr cinfo, unsigned char *st, int val)
/* Note: The 3 spacer bits in the C register guarantee
* that the new buffer byte can't be 0xFF here
* (see page 160 in the P&M JPEG book). */
e->buffer = temp & 0xFF; /* new output byte, might overflow later */
/* New output byte, might overflow later */
e->buffer = (int) (temp & 0xFF);
} else if (temp == 0xFF) {
++e->sc; /* stack 0xFF byte (which might overflow later) */
} else {
@@ -302,7 +303,8 @@ arith_encode (j_compress_ptr cinfo, unsigned char *st, int val)
emit_byte(0x00, cinfo);
} while (--e->sc);
}
e->buffer = temp & 0xFF; /* new output byte (can still overflow) */
/* New output byte (can still overflow) */
e->buffer = (int) (temp & 0xFF);
}
e->c &= 0x7FFFFL;
e->ct += 8;
@@ -926,9 +928,8 @@ jinit_arith_encoder (j_compress_ptr cinfo)
arith_entropy_ptr entropy;
int i;
entropy = (arith_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(arith_entropy_encoder));
entropy = (arith_entropy_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(arith_entropy_encoder));
cinfo->entropy = &entropy->pub;
entropy->pub.start_pass = start_pass;
entropy->pub.finish_pass = finish_pass;
+47 -50
View File
@@ -2,7 +2,7 @@
* jccolor.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2011-2013 by Guido Vollbeding.
* Modified 2011-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -105,14 +105,14 @@ rgb_ycc_start (j_compress_ptr cinfo)
/* Allocate and fill in the conversion tables. */
cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(TABLE_SIZE * SIZEOF(INT32)));
TABLE_SIZE * SIZEOF(INT32));
for (i = 0; i <= MAXJSAMPLE; i++) {
rgb_ycc_tab[i+R_Y_OFF] = FIX(0.299) * i;
rgb_ycc_tab[i+G_Y_OFF] = FIX(0.587) * i;
rgb_ycc_tab[i+B_Y_OFF] = FIX(0.114) * i + ONE_HALF;
rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.168735892)) * i;
rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.331264108)) * i;
rgb_ycc_tab[i+R_CB_OFF] = (- FIX(0.168735892)) * i;
rgb_ycc_tab[i+G_CB_OFF] = (- FIX(0.331264108)) * i;
/* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
* This ensures that the maximum output will round to MAXJSAMPLE
* not MAXJSAMPLE+1, and thus that we don't have to range-limit.
@@ -121,8 +121,8 @@ rgb_ycc_start (j_compress_ptr cinfo)
/* B=>Cb and R=>Cr tables are the same
rgb_ycc_tab[i+R_CR_OFF] = FIX(0.5) * i + CBCR_OFFSET + ONE_HALF-1;
*/
rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.418687589)) * i;
rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.081312411)) * i;
rgb_ycc_tab[i+G_CR_OFF] = (- FIX(0.418687589)) * i;
rgb_ycc_tab[i+B_CR_OFF] = (- FIX(0.081312411)) * i;
}
}
@@ -131,12 +131,12 @@ rgb_ycc_start (j_compress_ptr cinfo)
* Convert some rows of samples to the JPEG colorspace.
*
* Note that we change from the application's interleaved-pixel format
* to our internal noninterleaved, one-plane-per-component format.
* The input buffer is therefore three times as wide as the output buffer.
* to our internal noninterleaved, one-plane-per-component format. The
* input buffer is therefore three times as wide as the output buffer.
*
* A starting row offset is provided only for the output buffer. The caller
* can easily adjust the passed input_buf value to accommodate any row
* offset required on that side.
* A starting row offset is provided only for the output buffer. The
* caller can easily adjust the passed input_buf value to accommodate
* any row offset required on that side.
*/
METHODDEF(void)
@@ -145,8 +145,8 @@ rgb_ycc_convert (j_compress_ptr cinfo,
JDIMENSION output_row, int num_rows)
{
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
register INT32 * ctab = cconvert->rgb_ycc_tab;
register int r, g, b;
register INT32 * ctab = cconvert->rgb_ycc_tab;
register JSAMPROW inptr;
register JSAMPROW outptr0, outptr1, outptr2;
register JDIMENSION col;
@@ -162,6 +162,7 @@ rgb_ycc_convert (j_compress_ptr cinfo,
r = GETJSAMPLE(inptr[RGB_RED]);
g = GETJSAMPLE(inptr[RGB_GREEN]);
b = GETJSAMPLE(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.
* Hence the value being shifted is never negative, and we don't
@@ -179,7 +180,6 @@ rgb_ycc_convert (j_compress_ptr cinfo,
outptr2[col] = (JSAMPLE)
((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
>> SCALEBITS);
inptr += RGB_PIXELSIZE;
}
}
}
@@ -201,8 +201,8 @@ rgb_gray_convert (j_compress_ptr cinfo,
JDIMENSION output_row, int num_rows)
{
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
register INT32 * ctab = cconvert->rgb_ycc_tab;
register int r, g, b;
register INT32 * ctab = cconvert->rgb_ycc_tab;
register JSAMPROW inptr;
register JSAMPROW outptr;
register JDIMENSION col;
@@ -215,11 +215,11 @@ rgb_gray_convert (j_compress_ptr cinfo,
r = GETJSAMPLE(inptr[RGB_RED]);
g = GETJSAMPLE(inptr[RGB_GREEN]);
b = GETJSAMPLE(inptr[RGB_BLUE]);
inptr += RGB_PIXELSIZE;
/* Y */
outptr[col] = (JSAMPLE)
((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
>> SCALEBITS);
inptr += RGB_PIXELSIZE;
}
}
}
@@ -228,8 +228,8 @@ rgb_gray_convert (j_compress_ptr cinfo,
/*
* Convert some rows of samples to the JPEG colorspace.
* This version handles Adobe-style CMYK->YCCK conversion,
* where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
* conversion as above, while passing K (black) unchanged.
* where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the
* same conversion as above, while passing K (black) unchanged.
* We assume rgb_ycc_start has been called.
*/
@@ -239,8 +239,8 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
JDIMENSION output_row, int num_rows)
{
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
register INT32 * ctab = cconvert->rgb_ycc_tab;
register int r, g, b;
register INT32 * ctab = cconvert->rgb_ycc_tab;
register JSAMPROW inptr;
register JSAMPROW outptr0, outptr1, outptr2, outptr3;
register JDIMENSION col;
@@ -259,6 +259,7 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
/* K passes through as-is */
outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */
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.
* Hence the value being shifted is never negative, and we don't
@@ -276,7 +277,6 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
outptr2[col] = (JSAMPLE)
((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
>> SCALEBITS);
inptr += 4;
}
}
}
@@ -312,13 +312,13 @@ rgb_rgb1_convert (j_compress_ptr cinfo,
r = GETJSAMPLE(inptr[RGB_RED]);
g = GETJSAMPLE(inptr[RGB_GREEN]);
b = GETJSAMPLE(inptr[RGB_BLUE]);
inptr += RGB_PIXELSIZE;
/* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD
* (modulo) operator is equivalent to the bitmask operator AND.
*/
outptr0[col] = (JSAMPLE) ((r - g + CENTERJSAMPLE) & MAXJSAMPLE);
outptr1[col] = (JSAMPLE) g;
outptr2[col] = (JSAMPLE) ((b - g + CENTERJSAMPLE) & MAXJSAMPLE);
inptr += RGB_PIXELSIZE;
}
}
}
@@ -335,17 +335,17 @@ grayscale_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows)
{
int instride = cinfo->input_components;
register JSAMPROW inptr;
register JSAMPROW outptr;
register JDIMENSION col;
register JDIMENSION count;
register int instride = cinfo->input_components;
JDIMENSION num_cols = cinfo->image_width;
while (--num_rows >= 0) {
inptr = *input_buf++;
outptr = output_buf[0][output_row++];
for (col = 0; col < num_cols; col++) {
outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */
for (count = num_cols; count > 0; count--) {
*outptr++ = *inptr; /* don't need GETJSAMPLE() here */
inptr += instride;
}
}
@@ -396,21 +396,21 @@ null_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows)
{
int ci;
register int nc = cinfo->num_components;
register JSAMPROW inptr;
register JSAMPROW outptr;
register JDIMENSION col;
register JDIMENSION count;
register int num_comps = cinfo->num_components;
JDIMENSION num_cols = cinfo->image_width;
int ci;
while (--num_rows >= 0) {
/* It seems fastest to make a separate pass for each component. */
for (ci = 0; ci < nc; ci++) {
for (ci = 0; ci < num_comps; ci++) {
inptr = input_buf[0] + ci;
outptr = output_buf[ci][output_row];
for (col = 0; col < num_cols; col++) {
for (count = num_cols; count > 0; count--) {
*outptr++ = *inptr; /* don't need GETJSAMPLE() here */
inptr += nc;
inptr += num_comps;
}
}
input_buf++;
@@ -439,9 +439,8 @@ jinit_color_converter (j_compress_ptr cinfo)
{
my_cconvert_ptr cconvert;
cconvert = (my_cconvert_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_color_converter));
cconvert = (my_cconvert_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_color_converter));
cinfo->cconvert = &cconvert->pub;
/* set start_pass to null method until we find out differently */
cconvert->pub.start_pass = null_method;
@@ -455,9 +454,11 @@ jinit_color_converter (j_compress_ptr cinfo)
case JCS_RGB:
case JCS_BG_RGB:
#if RGB_PIXELSIZE != 3
if (cinfo->input_components != RGB_PIXELSIZE)
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
break;
#endif /* else share code with YCbCr */
case JCS_YCbCr:
case JCS_BG_YCC:
@@ -474,7 +475,6 @@ jinit_color_converter (j_compress_ptr cinfo)
default: /* JCS_UNKNOWN can be anything */
if (cinfo->input_components < 1)
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
break;
}
/* Support color transform only for RGB colorspaces */
@@ -507,19 +507,18 @@ jinit_color_converter (j_compress_ptr cinfo)
case JCS_BG_RGB:
if (cinfo->num_components != 3)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (cinfo->in_color_space == cinfo->jpeg_color_space) {
switch (cinfo->color_transform) {
case JCT_NONE:
cconvert->pub.color_convert = rgb_convert;
break;
case JCT_SUBTRACT_GREEN:
cconvert->pub.color_convert = rgb_rgb1_convert;
break;
default:
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
}
} else
if (cinfo->in_color_space != cinfo->jpeg_color_space)
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
switch (cinfo->color_transform) {
case JCT_NONE:
cconvert->pub.color_convert = rgb_convert;
break;
case JCT_SUBTRACT_GREEN:
cconvert->pub.color_convert = rgb_rgb1_convert;
break;
default:
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
}
break;
case JCS_YCbCr:
@@ -572,10 +571,9 @@ jinit_color_converter (j_compress_ptr cinfo)
case JCS_CMYK:
if (cinfo->num_components != 4)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (cinfo->in_color_space == JCS_CMYK)
cconvert->pub.color_convert = null_convert;
else
if (cinfo->in_color_space != JCS_CMYK)
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
cconvert->pub.color_convert = null_convert;
break;
case JCS_YCCK:
@@ -599,6 +597,5 @@ jinit_color_converter (j_compress_ptr cinfo)
cinfo->num_components != cinfo->input_components)
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
cconvert->pub.color_convert = null_convert;
break;
}
}
+109 -42
View File
@@ -2,7 +2,7 @@
* jchuff.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2006-2013 by Guido Vollbeding.
* Modified 2006-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -178,13 +178,12 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno,
htbl =
isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
if (htbl == NULL)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
htbl = jpeg_std_huff_table((j_common_ptr) cinfo, isDC, tblno);
/* Allocate a workspace if we haven't already done so. */
if (*pdtbl == NULL)
*pdtbl = (c_derived_tbl *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(c_derived_tbl));
*pdtbl = (c_derived_tbl *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(c_derived_tbl));
dtbl = *pdtbl;
/* Figure C.1: make table of Huffman code length for each symbol */
@@ -1256,22 +1255,88 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
UINT8 bits[MAX_CLEN+1]; /* bits[k] = # of symbols with code length k */
int codesize[257]; /* codesize[k] = code length of symbol k */
int others[257]; /* next symbol in current branch of tree */
int c1, c2;
int p, i, j;
int c1, c2, i, j;
UINT8 *p;
long v;
freq[256] = 1; /* make sure 256 has a nonzero count */
/* Including the pseudo-symbol 256 in the Huffman procedure guarantees
* that no real symbol is given code-value of all ones, because 256
* will be placed last in the largest codeword category.
* In the symbol list build procedure this element serves as sentinel
* for the zero run loop.
*/
#ifndef DONT_USE_FANCY_HUFF_OPT
/* Build list of symbols sorted in order of descending frequency */
/* This approach has several benefits (thank to John Korejwa for the idea):
* 1.
* If a codelength category is split during the length limiting procedure
* below, the feature that more frequent symbols are assigned shorter
* codewords remains valid for the adjusted code.
* 2.
* To reduce consecutive ones in a Huffman data stream (thus reducing the
* number of stuff bytes in JPEG) it is preferable to follow 0 branches
* (and avoid 1 branches) as much as possible. This is easily done by
* assigning symbols to leaves of the Huffman tree in order of decreasing
* frequency, with no secondary sort based on codelengths.
* 3.
* The symbol list can be built independently from the assignment of code
* lengths by the Huffman procedure below.
* Note: The symbol list build procedure must be performed first, because
* the Huffman procedure assigning the codelengths clobbers the frequency
* counts!
*/
/* Here we use the others array as a linked list of nonzero frequencies
* to be sorted. Already sorted elements are removed from the list.
*/
/* Building list */
/* This item does not correspond to a valid symbol frequency and is used
* as starting index.
*/
j = 256;
for (i = 0;; i++) {
if (freq[i] == 0) /* skip zero frequencies */
continue;
if (i > 255)
break;
others[j] = i; /* this symbol value */
j = i; /* previous symbol value */
}
others[j] = -1; /* mark end of list */
/* Sorting list */
p = htbl->huffval;
while ((c1 = others[256]) >= 0) {
v = freq[c1];
i = c1; /* first symbol value */
j = 256; /* pseudo symbol value for starting index */
while ((c2 = others[c1]) >= 0) {
if (freq[c2] > v) {
v = freq[c2];
i = c2; /* this symbol value */
j = c1; /* previous symbol value */
}
c1 = c2;
}
others[j] = others[i]; /* remove this symbol i from list */
*p++ = (UINT8) i;
}
#endif /* DONT_USE_FANCY_HUFF_OPT */
/* This algorithm is explained in section K.2 of the JPEG standard */
MEMZERO(bits, SIZEOF(bits));
MEMZERO(codesize, SIZEOF(codesize));
for (i = 0; i < 257; i++)
others[i] = -1; /* init links to empty */
freq[256] = 1; /* make sure 256 has a nonzero count */
/* Including the pseudo-symbol 256 in the Huffman procedure guarantees
* that no real symbol is given code-value of all ones, because 256
* will be placed last in the largest codeword category.
*/
/* Huffman's basic algorithm to assign optimal code lengths to symbols */
@@ -1301,7 +1366,7 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
/* Done if we've merged everything into one frequency */
if (c2 < 0)
break;
/* Else merge the two counts/trees */
freq[c1] += freq[c2];
freq[c2] = 0;
@@ -1312,9 +1377,9 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
c1 = others[c1];
codesize[c1]++;
}
others[c1] = c2; /* chain c2 onto c1's tree branch */
/* Increment the codesize of everything in c2's tree branch */
codesize[c2]++;
while (others[c2] >= 0) {
@@ -1329,7 +1394,7 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
/* The JPEG standard seems to think that this can't happen, */
/* but I'm paranoid... */
if (codesize[i] > MAX_CLEN)
ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW);
ERREXIT(cinfo, JERR_HUFF_CLEN_OUTOFBOUNDS);
bits[codesize[i]]++;
}
@@ -1345,13 +1410,16 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
* shortest nonzero BITS entry is converted into a prefix for two code words
* one bit longer.
*/
for (i = MAX_CLEN; i > 16; i--) {
while (bits[i] > 0) {
j = i - 2; /* find length of new prefix to be used */
while (bits[j] == 0)
while (bits[j] == 0) {
if (j == 0)
ERREXIT(cinfo, JERR_HUFF_CLEN_OUTOFBOUNDS);
j--;
}
bits[i] -= 2; /* remove two symbols */
bits[i-1]++; /* one goes in this length */
bits[j+1] += 2; /* two new symbols in this length */
@@ -1363,24 +1431,27 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
while (bits[i] == 0) /* find largest codelength still in use */
i--;
bits[i]--;
/* Return final symbol counts (only for lengths 0..16) */
MEMCOPY(htbl->bits, bits, SIZEOF(htbl->bits));
#ifdef DONT_USE_FANCY_HUFF_OPT
/* Return a list of the symbols sorted by code length */
/* It's not real clear to me why we don't need to consider the codelength
* changes made above, but the JPEG spec seems to think this works.
/* Note: Due to the codelength changes made above, it can happen
* that more frequent symbols are assigned longer codewords.
*/
p = 0;
p = htbl->huffval;
for (i = 1; i <= MAX_CLEN; i++) {
for (j = 0; j <= 255; j++) {
if (codesize[j] == i) {
htbl->huffval[p] = (UINT8) j;
p++;
*p++ = (UINT8) j;
}
}
}
#endif /* DONT_USE_FANCY_HUFF_OPT */
/* Set sent_table FALSE so updated table will be written to JPEG file. */
htbl->sent_table = FALSE;
}
@@ -1400,13 +1471,13 @@ finish_pass_gather (j_compress_ptr cinfo)
boolean did_dc[NUM_HUFF_TBLS];
boolean did_ac[NUM_HUFF_TBLS];
/* It's important not to apply jpeg_gen_optimal_table more than once
* per table, because it clobbers the input frequency counts!
*/
if (cinfo->progressive_mode)
/* Flush out buffered data (all we care about is counting the EOB symbol) */
emit_eobrun(entropy);
/* It's important not to apply jpeg_gen_optimal_table more than once
* per table, because it clobbers the input frequency counts!
*/
MEMZERO(did_dc, SIZEOF(did_dc));
MEMZERO(did_ac, SIZEOF(did_ac));
@@ -1475,9 +1546,8 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
entropy->pub.encode_mcu = encode_mcu_AC_refine;
/* AC refinement needs a correction bit buffer */
if (entropy->bit_buffer == NULL)
entropy->bit_buffer = (char *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
MAX_CORR_BITS * SIZEOF(char));
entropy->bit_buffer = (char *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, MAX_CORR_BITS * SIZEOF(char));
}
}
@@ -1505,9 +1575,8 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
/* Allocate and zero the statistics tables */
/* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
if (entropy->dc_count_ptrs[tbl] == NULL)
entropy->dc_count_ptrs[tbl] = (long *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
257 * SIZEOF(long));
entropy->dc_count_ptrs[tbl] = (long *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, 257 * SIZEOF(long));
MEMZERO(entropy->dc_count_ptrs[tbl], 257 * SIZEOF(long));
} else {
/* Compute derived values for Huffman tables */
@@ -1525,9 +1594,8 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
if (tbl < 0 || tbl >= NUM_HUFF_TBLS)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
if (entropy->ac_count_ptrs[tbl] == NULL)
entropy->ac_count_ptrs[tbl] = (long *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
257 * SIZEOF(long));
entropy->ac_count_ptrs[tbl] = (long *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, 257 * SIZEOF(long));
MEMZERO(entropy->ac_count_ptrs[tbl], 257 * SIZEOF(long));
} else {
jpeg_make_c_derived_tbl(cinfo, FALSE, tbl,
@@ -1556,9 +1624,8 @@ jinit_huff_encoder (j_compress_ptr cinfo)
huff_entropy_ptr entropy;
int i;
entropy = (huff_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(huff_entropy_encoder));
entropy = (huff_entropy_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(huff_entropy_encoder));
cinfo->entropy = &entropy->pub;
entropy->pub.start_pass = start_pass_huff;
+3 -5
View File
@@ -2,7 +2,7 @@
* jcmarker.c
*
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2013 by Guido Vollbeding.
* Modified 2003-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -471,7 +471,6 @@ emit_adobe_app14 (j_compress_ptr cinfo)
break;
default:
emit_byte(cinfo, 0); /* Color transform = 0 */
break;
}
}
@@ -702,9 +701,8 @@ jinit_marker_writer (j_compress_ptr cinfo)
my_marker_ptr marker;
/* Create the subobject */
marker = (my_marker_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_marker_writer));
marker = (my_marker_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_marker_writer));
cinfo->marker = &marker->pub;
/* Initialize method pointers */
marker->pub.write_file_header = write_file_header;
+18 -15
View File
@@ -2,7 +2,7 @@
* jcmaster.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2003-2017 by Guido Vollbeding.
* Modified 2003-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -62,7 +62,7 @@ initial_setup (j_compress_ptr cinfo)
case 5: cinfo->natural_order = jpeg_natural_order5; break;
case 6: cinfo->natural_order = jpeg_natural_order6; break;
case 7: cinfo->natural_order = jpeg_natural_order7; break;
default: cinfo->natural_order = jpeg_natural_order; break;
default: cinfo->natural_order = jpeg_natural_order;
}
/* Derive lim_Se from block_size */
@@ -114,20 +114,24 @@ initial_setup (j_compress_ptr cinfo)
*/
ssize = 1;
#ifdef DCT_SCALING_SUPPORTED
while (cinfo->min_DCT_h_scaled_size * ssize <=
(cinfo->do_fancy_downsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) == 0) {
ssize = ssize * 2;
}
if (! cinfo->raw_data_in)
while (cinfo->min_DCT_h_scaled_size * ssize <=
(cinfo->do_fancy_downsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) ==
0) {
ssize = ssize * 2;
}
#endif
compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size * ssize;
ssize = 1;
#ifdef DCT_SCALING_SUPPORTED
while (cinfo->min_DCT_v_scaled_size * ssize <=
(cinfo->do_fancy_downsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) == 0) {
ssize = ssize * 2;
}
if (! cinfo->raw_data_in)
while (cinfo->min_DCT_v_scaled_size * ssize <=
(cinfo->do_fancy_downsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) ==
0) {
ssize = ssize * 2;
}
#endif
compptr->DCT_v_scaled_size = cinfo->min_DCT_v_scaled_size * ssize;
@@ -620,9 +624,8 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
{
my_master_ptr master;
master = (my_master_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_comp_master));
master = (my_master_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_comp_master));
cinfo->master = &master->pub;
master->pub.prepare_for_pass = prepare_for_pass;
master->pub.pass_startup = pass_startup;
+138
View File
@@ -2,6 +2,7 @@
* jcomapi.c
*
* Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -104,3 +105,140 @@ jpeg_alloc_huff_table (j_common_ptr cinfo)
tbl->sent_table = FALSE; /* make sure this is false in any new table */
return tbl;
}
/*
* Set up the standard Huffman tables (cf. JPEG standard section K.3).
* IMPORTANT: these are only valid for 8-bit data precision!
* (Would jutils.c be a more reasonable place to put this?)
*/
GLOBAL(JHUFF_TBL *)
jpeg_std_huff_table (j_common_ptr cinfo, boolean isDC, int tblno)
{
JHUFF_TBL **htblptr, *htbl;
const UINT8 *bits, *val;
int nsymbols, len;
static const UINT8 bits_dc_luminance[17] =
{ /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
static const UINT8 val_dc_luminance[] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
static const UINT8 bits_dc_chrominance[17] =
{ /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
static const UINT8 val_dc_chrominance[] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
static const UINT8 bits_ac_luminance[17] =
{ /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
static const UINT8 val_ac_luminance[] =
{ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa };
static const UINT8 bits_ac_chrominance[17] =
{ /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
static const UINT8 val_ac_chrominance[] =
{ 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa };
if (cinfo->is_decompressor) {
if (isDC)
htblptr = ((j_decompress_ptr) cinfo)->dc_huff_tbl_ptrs;
else
htblptr = ((j_decompress_ptr) cinfo)->ac_huff_tbl_ptrs;
} else {
if (isDC)
htblptr = ((j_compress_ptr) cinfo)->dc_huff_tbl_ptrs;
else
htblptr = ((j_compress_ptr) cinfo)->ac_huff_tbl_ptrs;
}
switch (tblno) {
case 0:
if (isDC) {
bits = bits_dc_luminance;
val = val_dc_luminance;
} else {
bits = bits_ac_luminance;
val = val_ac_luminance;
}
break;
case 1:
if (isDC) {
bits = bits_dc_chrominance;
val = val_dc_chrominance;
} else {
bits = bits_ac_chrominance;
val = val_ac_chrominance;
}
break;
default:
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
return NULL; /* avoid compiler warnings for uninitialized variables */
}
if (htblptr[tblno] == NULL)
htblptr[tblno] = jpeg_alloc_huff_table(cinfo);
htbl = htblptr[tblno];
/* Copy the number-of-symbols-of-each-code-length counts */
MEMCOPY(htbl->bits, bits, SIZEOF(htbl->bits));
/* Validate the counts. We do this here mainly so we can copy the right
* number of symbols from the val[] array, without risking marching off
* the end of memory. jxhuff.c will do a more thorough test later.
*/
nsymbols = 0;
for (len = 1; len <= 16; len++)
nsymbols += bits[len];
if (nsymbols > 256)
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
if (nsymbols > 0)
MEMCOPY(htbl->huffval, val, nsymbols * SIZEOF(UINT8));
/* Initialize sent_table FALSE so table will be written to JPEG file. */
htbl->sent_table = FALSE;
return htbl;
}
+14 -103
View File
@@ -2,7 +2,7 @@
* jcparam.c
*
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2013 by Guido Vollbeding.
* Modified 2003-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -162,112 +162,23 @@ jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
/*
* Huffman table setup routines
* Reset standard Huffman tables
*/
LOCAL(void)
add_huff_table (j_compress_ptr cinfo,
JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
/* Define a Huffman table */
{
int nsymbols, len;
if (*htblptr == NULL)
*htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
/* Copy the number-of-symbols-of-each-code-length counts */
MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
/* Validate the counts. We do this here mainly so we can copy the right
* number of symbols from the val[] array, without risking marching off
* the end of memory. jchuff.c will do a more thorough test later.
*/
nsymbols = 0;
for (len = 1; len <= 16; len++)
nsymbols += bits[len];
if (nsymbols < 1 || nsymbols > 256)
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
MEMCOPY((*htblptr)->huffval, val, nsymbols * SIZEOF(UINT8));
/* Initialize sent_table FALSE so table will be written to JPEG file. */
(*htblptr)->sent_table = FALSE;
}
LOCAL(void)
std_huff_tables (j_compress_ptr cinfo)
/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
/* IMPORTANT: these are only valid for 8-bit data precision! */
{
static const UINT8 bits_dc_luminance[17] =
{ /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
static const UINT8 val_dc_luminance[] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
static const UINT8 bits_dc_chrominance[17] =
{ /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
static const UINT8 val_dc_chrominance[] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
static const UINT8 bits_ac_luminance[17] =
{ /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
static const UINT8 val_ac_luminance[] =
{ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa };
static const UINT8 bits_ac_chrominance[17] =
{ /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
static const UINT8 val_ac_chrominance[] =
{ 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa };
add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0],
bits_dc_luminance, val_dc_luminance);
add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0],
bits_ac_luminance, val_ac_luminance);
add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1],
bits_dc_chrominance, val_dc_chrominance);
add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1],
bits_ac_chrominance, val_ac_chrominance);
if (cinfo->dc_huff_tbl_ptrs[0] != NULL)
(void) jpeg_std_huff_table((j_common_ptr) cinfo, TRUE, 0);
if (cinfo->ac_huff_tbl_ptrs[0] != NULL)
(void) jpeg_std_huff_table((j_common_ptr) cinfo, FALSE, 0);
if (cinfo->dc_huff_tbl_ptrs[1] != NULL)
(void) jpeg_std_huff_table((j_common_ptr) cinfo, TRUE, 1);
if (cinfo->ac_huff_tbl_ptrs[1] != NULL)
(void) jpeg_std_huff_table((j_common_ptr) cinfo, FALSE, 1);
}
@@ -306,7 +217,7 @@ jpeg_set_defaults (j_compress_ptr cinfo)
cinfo->data_precision = BITS_IN_JSAMPLE;
/* Set up two quantization tables using default quality of 75 */
jpeg_set_quality(cinfo, 75, TRUE);
/* Set up two Huffman tables */
/* Reset standard Huffman tables */
std_huff_tables(cinfo);
/* Initialize default arithmetic coding conditioning */
+14 -14
View File
@@ -1,7 +1,7 @@
/*
* jdarith.c
*
* Developed 1997-2015 by Guido Vollbeding.
* Developed 1997-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -280,7 +280,7 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
if ((m = arith_decode(cinfo, st)) != 0) {
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
while (arith_decode(cinfo, st)) {
if ((m <<= 1) == 0x8000) {
if ((m <<= 1) == (int) 0x8000U) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* magnitude overflow */
return TRUE;
@@ -370,7 +370,7 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
st = entropy->ac_stats[tbl] +
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
while (arith_decode(cinfo, st)) {
if ((m <<= 1) == 0x8000) {
if ((m <<= 1) == (int) 0x8000U) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* magnitude overflow */
return TRUE;
@@ -404,7 +404,8 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
unsigned char *st;
int p1, blkn;
JCOEF p1;
int blkn;
/* Process restart marker if needed */
if (cinfo->restart_interval) {
@@ -440,7 +441,7 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
JCOEFPTR thiscoef;
unsigned char *st;
int tbl, k, kex;
int p1, m1;
JCOEF p1, m1;
const int * natural_order;
/* Process restart marker if needed */
@@ -459,7 +460,7 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */
m1 = -p1; /* -1 in the bit position being coded */
/* Establish EOBx (previous stage end-of-block) index */
kex = cinfo->Se;
@@ -555,7 +556,7 @@ decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
if ((m = arith_decode(cinfo, st)) != 0) {
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
while (arith_decode(cinfo, st)) {
if ((m <<= 1) == 0x8000) {
if ((m <<= 1) == (int) 0x8000U) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* magnitude overflow */
return TRUE;
@@ -612,7 +613,7 @@ decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
st = entropy->ac_stats[tbl] +
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
while (arith_decode(cinfo, st)) {
if ((m <<= 1) == 0x8000) {
if ((m <<= 1) == (int) 0x8000U) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* magnitude overflow */
return TRUE;
@@ -766,9 +767,8 @@ jinit_arith_decoder (j_decompress_ptr cinfo)
arith_entropy_ptr entropy;
int i;
entropy = (arith_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(arith_entropy_decoder));
entropy = (arith_entropy_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(arith_entropy_decoder));
cinfo->entropy = &entropy->pub;
entropy->pub.start_pass = start_pass;
entropy->pub.finish_pass = finish_pass;
@@ -785,9 +785,9 @@ jinit_arith_decoder (j_decompress_ptr cinfo)
if (cinfo->progressive_mode) {
/* Create progression status table */
int *coef_bit_ptr, ci;
cinfo->coef_bits = (int (*)[DCTSIZE2])
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
cinfo->num_components*DCTSIZE2*SIZEOF(int));
cinfo->coef_bits = (int (*)[DCTSIZE2]) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE,
cinfo->num_components * DCTSIZE2 * SIZEOF(int));
coef_bit_ptr = & cinfo->coef_bits[0][0];
for (ci = 0; ci < cinfo->num_components; ci++)
for (i = 0; i < DCTSIZE2; i++)
+10 -13
View File
@@ -2,7 +2,7 @@
* jdatadst.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2009-2017 by Guido Vollbeding.
* Modified 2009-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -46,7 +46,7 @@ typedef struct {
struct jpeg_destination_mgr pub; /* public fields */
unsigned char ** outbuffer; /* target buffer */
unsigned long * outsize;
size_t * outsize;
unsigned char * newbuffer; /* newly allocated buffer */
JOCTET * buffer; /* start of buffer */
size_t bufsize;
@@ -66,9 +66,8 @@ init_destination (j_compress_ptr cinfo)
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
/* Allocate the output buffer --- it will be released when done with image */
dest->buffer = (JOCTET *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
OUTPUT_BUF_SIZE * SIZEOF(JOCTET));
dest->buffer = (JOCTET *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, OUTPUT_BUF_SIZE * SIZEOF(JOCTET));
dest->pub.next_output_byte = dest->buffer;
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
@@ -131,7 +130,7 @@ empty_mem_output_buffer (j_compress_ptr cinfo)
nextbuffer = (JOCTET *) malloc(nextsize);
if (nextbuffer == NULL)
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 11);
MEMCOPY(nextbuffer, dest->buffer, dest->bufsize);
@@ -204,9 +203,8 @@ jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
* sizes may be different. Caveat programmer.
*/
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
cinfo->dest = (struct jpeg_destination_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(my_destination_mgr));
cinfo->dest = (struct jpeg_destination_mgr *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_destination_mgr));
}
dest = (my_dest_ptr) cinfo->dest;
@@ -233,7 +231,7 @@ jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
GLOBAL(void)
jpeg_mem_dest (j_compress_ptr cinfo,
unsigned char ** outbuffer, unsigned long * outsize)
unsigned char ** outbuffer, size_t * outsize)
{
my_mem_dest_ptr dest;
@@ -244,9 +242,8 @@ jpeg_mem_dest (j_compress_ptr cinfo,
* can be written to the same buffer without re-executing jpeg_mem_dest.
*/
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
cinfo->dest = (struct jpeg_destination_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(my_mem_destination_mgr));
cinfo->dest = (struct jpeg_destination_mgr *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_mem_destination_mgr));
}
dest = (my_mem_dest_ptr) cinfo->dest;
+15 -16
View File
@@ -2,7 +2,7 @@
* jdatasrc.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2009-2015 by Guido Vollbeding.
* Modified 2009-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -156,21 +156,23 @@ METHODDEF(void)
skip_input_data (j_decompress_ptr cinfo, long num_bytes)
{
struct jpeg_source_mgr * src = cinfo->src;
size_t nbytes;
/* Just a dumb implementation for now. Could use fseek() except
* it doesn't work on pipes. Not clear that being smart is worth
* any trouble anyway --- large skips are infrequent.
*/
if (num_bytes > 0) {
while (num_bytes > (long) src->bytes_in_buffer) {
num_bytes -= (long) src->bytes_in_buffer;
nbytes = (size_t) num_bytes;
while (nbytes > src->bytes_in_buffer) {
nbytes -= src->bytes_in_buffer;
(void) (*src->fill_input_buffer) (cinfo);
/* note we assume that fill_input_buffer will never return FALSE,
* so suspension need not be handled.
*/
}
src->next_input_byte += (size_t) num_bytes;
src->bytes_in_buffer -= (size_t) num_bytes;
src->next_input_byte += nbytes;
src->bytes_in_buffer -= nbytes;
}
}
@@ -219,13 +221,11 @@ jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
* manager serially with the same JPEG object. Caveat programmer.
*/
if (cinfo->src == NULL) { /* first time for this JPEG object? */
cinfo->src = (struct jpeg_source_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(my_source_mgr));
cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_source_mgr));
src = (my_src_ptr) cinfo->src;
src->buffer = (JOCTET *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
INPUT_BUF_SIZE * SIZEOF(JOCTET));
src->buffer = (JOCTET *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_PERMANENT, INPUT_BUF_SIZE * SIZEOF(JOCTET));
}
src = (my_src_ptr) cinfo->src;
@@ -247,7 +247,7 @@ jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
GLOBAL(void)
jpeg_mem_src (j_decompress_ptr cinfo,
const unsigned char * inbuffer, unsigned long insize)
const unsigned char * inbuffer, size_t insize)
{
struct jpeg_source_mgr * src;
@@ -259,9 +259,8 @@ jpeg_mem_src (j_decompress_ptr cinfo,
* the first one.
*/
if (cinfo->src == NULL) { /* first time for this JPEG object? */
cinfo->src = (struct jpeg_source_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(struct jpeg_source_mgr));
cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(struct jpeg_source_mgr));
}
src = cinfo->src;
@@ -270,6 +269,6 @@ jpeg_mem_src (j_decompress_ptr cinfo,
src->skip_input_data = skip_input_data;
src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
src->term_source = term_source;
src->bytes_in_buffer = (size_t) insize;
src->bytes_in_buffer = insize;
src->next_input_byte = (const JOCTET *) inbuffer;
}
+59 -71
View File
@@ -2,7 +2,7 @@
* jdcolor.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2011-2017 by Guido Vollbeding.
* Modified 2011-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -124,28 +124,22 @@ build_ycc_rgb_table (j_decompress_ptr cinfo)
INT32 x;
SHIFT_TEMPS
cconvert->Cr_r_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
cconvert->Cb_b_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
cconvert->Cr_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
cconvert->Cb_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
cconvert->Cr_r_tab = (int *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
cconvert->Cb_b_tab = (int *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
cconvert->Cr_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
cconvert->Cb_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
/* Cr=>R value is nearest int to 1.402 * x */
cconvert->Cr_r_tab[i] = (int)
RIGHT_SHIFT(FIX(1.402) * x + ONE_HALF, SCALEBITS);
cconvert->Cr_r_tab[i] = (int) DESCALE(FIX(1.402) * x, SCALEBITS);
/* Cb=>B value is nearest int to 1.772 * x */
cconvert->Cb_b_tab[i] = (int)
RIGHT_SHIFT(FIX(1.772) * x + ONE_HALF, SCALEBITS);
cconvert->Cb_b_tab[i] = (int) DESCALE(FIX(1.772) * x, SCALEBITS);
/* Cr=>G value is scaled-up -0.714136286 * x */
cconvert->Cr_g_tab[i] = (- FIX(0.714136286)) * x;
/* Cb=>G value is scaled-up -0.344136286 * x */
@@ -164,28 +158,22 @@ build_bg_ycc_rgb_table (j_decompress_ptr cinfo)
INT32 x;
SHIFT_TEMPS
cconvert->Cr_r_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
cconvert->Cb_b_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
cconvert->Cr_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
cconvert->Cb_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
cconvert->Cr_r_tab = (int *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
cconvert->Cb_b_tab = (int *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
cconvert->Cr_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
cconvert->Cb_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
/* Cr=>R value is nearest int to 2.804 * x */
cconvert->Cr_r_tab[i] = (int)
RIGHT_SHIFT(FIX(2.804) * x + ONE_HALF, SCALEBITS);
cconvert->Cr_r_tab[i] = (int) DESCALE(FIX(2.804) * x, SCALEBITS);
/* Cb=>B value is nearest int to 3.544 * x */
cconvert->Cb_b_tab[i] = (int)
RIGHT_SHIFT(FIX(3.544) * x + ONE_HALF, SCALEBITS);
cconvert->Cb_b_tab[i] = (int) DESCALE(FIX(3.544) * x, SCALEBITS);
/* Cr=>G value is scaled-up -1.428272572 * x */
cconvert->Cr_g_tab[i] = (- FIX(1.428272572)) * x;
/* Cb=>G value is scaled-up -0.688272572 * x */
@@ -201,6 +189,7 @@ build_bg_ycc_rgb_table (j_decompress_ptr cinfo)
* Note that we change from noninterleaved, one-plane-per-component format
* to interleaved-pixel format. The output buffer is therefore three times
* as wide as the input buffer.
*
* A starting row offset is provided only for the input buffer. The caller
* can easily adjust the passed output_buf value to accommodate any row
* offset required on that side.
@@ -264,9 +253,8 @@ build_rgb_y_table (j_decompress_ptr cinfo)
INT32 i;
/* Allocate and fill in the conversion tables. */
cconvert->rgb_y_tab = rgb_y_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(TABLE_SIZE * SIZEOF(INT32)));
cconvert->rgb_y_tab = rgb_y_tab = (INT32 *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, TABLE_SIZE * SIZEOF(INT32));
for (i = 0; i <= MAXJSAMPLE; i++) {
rgb_y_tab[i+R_Y_OFF] = FIX(0.299) * i;
@@ -286,8 +274,8 @@ rgb_gray_convert (j_decompress_ptr cinfo,
JSAMPARRAY output_buf, int num_rows)
{
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
register INT32 * ctab = cconvert->rgb_y_tab;
register int r, g, b;
register INT32 * ctab = cconvert->rgb_y_tab;
register JSAMPROW outptr;
register JSAMPROW inptr0, inptr1, inptr2;
register JDIMENSION col;
@@ -313,6 +301,7 @@ rgb_gray_convert (j_decompress_ptr cinfo,
/*
* Convert some rows of samples to the output colorspace.
* [R-G,G,B-G] to [R,G,B] conversion with modulo calculation
* (inverse color transform).
* This can be seen as an adaption of the general YCbCr->RGB
@@ -364,8 +353,8 @@ rgb1_gray_convert (j_decompress_ptr cinfo,
JSAMPARRAY output_buf, int num_rows)
{
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
register INT32 * ctab = cconvert->rgb_y_tab;
register int r, g, b;
register INT32 * ctab = cconvert->rgb_y_tab;
register JSAMPROW outptr;
register JSAMPROW inptr0, inptr1, inptr2;
register JDIMENSION col;
@@ -396,6 +385,7 @@ rgb1_gray_convert (j_decompress_ptr cinfo,
/*
* Convert some rows of samples to the output colorspace.
* No colorspace change, but conversion from separate-planes
* to interleaved representation.
*/
@@ -430,6 +420,7 @@ rgb_convert (j_decompress_ptr cinfo,
/*
* Color conversion for no colorspace change: just copy the data,
* converting from separate-planes to interleaved representation.
* We assume out_color_components == num_components.
*/
METHODDEF(void)
@@ -437,20 +428,21 @@ null_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows)
{
int ci;
register int nc = cinfo->num_components;
register JSAMPROW outptr;
register JSAMPROW inptr;
register JDIMENSION col;
register JDIMENSION count;
register int num_comps = cinfo->num_components;
JDIMENSION num_cols = cinfo->output_width;
int ci;
while (--num_rows >= 0) {
for (ci = 0; ci < nc; ci++) {
/* It seems fastest to make a separate pass for each component. */
for (ci = 0; ci < num_comps; ci++) {
inptr = input_buf[ci][input_row];
outptr = output_buf[0] + ci;
for (col = 0; col < num_cols; col++) {
*outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */
outptr += nc;
for (count = num_cols; count > 0; count--) {
*outptr = *inptr++; /* don't need GETJSAMPLE() here */
outptr += num_comps;
}
}
input_row++;
@@ -504,9 +496,10 @@ gray_rgb_convert (j_decompress_ptr cinfo,
/*
* Adobe-style YCCK->CMYK conversion.
* We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
* conversion as above, while passing K (black) unchanged.
* Convert some rows of samples to the output colorspace.
* This version handles Adobe-style YCCK->CMYK conversion,
* where we convert YCbCr to R=1-C, G=1-M, and B=1-Y using the
* same conversion as above, while passing K (black) unchanged.
* We assume build_ycc_rgb_table has been called.
*/
@@ -577,9 +570,8 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
my_cconvert_ptr cconvert;
int ci;
cconvert = (my_cconvert_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_color_deconverter));
cconvert = (my_cconvert_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_color_deconverter));
cinfo->cconvert = &cconvert->pub;
cconvert->pub.start_pass = start_pass_dcolor;
@@ -607,7 +599,6 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
default: /* JCS_UNKNOWN can be anything */
if (cinfo->num_components < 1)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
break;
}
/* Support color transform only for RGB colorspaces */
@@ -684,19 +675,18 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
case JCS_BG_RGB:
cinfo->out_color_components = RGB_PIXELSIZE;
if (cinfo->jpeg_color_space == JCS_BG_RGB) {
switch (cinfo->color_transform) {
case JCT_NONE:
cconvert->pub.color_convert = rgb_convert;
break;
case JCT_SUBTRACT_GREEN:
cconvert->pub.color_convert = rgb1_rgb_convert;
break;
default:
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
}
} else
if (cinfo->jpeg_color_space != JCS_BG_RGB)
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
switch (cinfo->color_transform) {
case JCT_NONE:
cconvert->pub.color_convert = rgb_convert;
break;
case JCT_SUBTRACT_GREEN:
cconvert->pub.color_convert = rgb1_rgb_convert;
break;
default:
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
}
break;
case JCS_CMYK:
@@ -714,14 +704,12 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
}
break;
default:
/* Permit null conversion to same output space */
if (cinfo->out_color_space == cinfo->jpeg_color_space) {
cinfo->out_color_components = cinfo->num_components;
cconvert->pub.color_convert = null_convert;
} else /* unsupported non-null conversion */
default: /* permit null conversion to same output space */
if (cinfo->out_color_space != cinfo->jpeg_color_space)
/* unsupported non-null conversion */
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break;
cinfo->out_color_components = cinfo->num_components;
cconvert->pub.color_convert = null_convert;
}
if (cinfo->quantize_colors)
+1 -8
View File
@@ -2,7 +2,7 @@
* jdct.h
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2002-2017 by Guido Vollbeding.
* Modified 2002-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -358,13 +358,6 @@ EXTERN(void) jpeg_idct_1x2
#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5))
/* Descale and correctly round an INT32 value that's scaled by N bits.
* We assume RIGHT_SHIFT rounds towards minus infinity, so adding
* the fudge factor is correct for either sign of X.
*/
#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
* This macro is used only when the two inputs will actually be no more than
* 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a
+56 -50
View File
@@ -2,7 +2,7 @@
* jdhuff.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2006-2016 by Guido Vollbeding.
* Modified 2006-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -341,13 +341,12 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno,
htbl =
isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
if (htbl == NULL)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
htbl = jpeg_std_huff_table((j_common_ptr) cinfo, isDC, tblno);
/* Allocate a workspace if we haven't already done so. */
if (*pdtbl == NULL)
*pdtbl = (d_derived_tbl *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(d_derived_tbl));
*pdtbl = (d_derived_tbl *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(d_derived_tbl));
dtbl = *pdtbl;
dtbl->pub = htbl; /* fill in back link */
@@ -706,7 +705,7 @@ process_restart (j_decompress_ptr cinfo)
METHODDEF(boolean)
decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
int Al = cinfo->Al;
register int s, r;
@@ -730,7 +729,7 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
if (! entropy->insufficient_data) {
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
ASSIGN_STATE(state, entropy->saved);
/* Outer loop handles each block in the MCU */
@@ -759,12 +758,13 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
}
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
ASSIGN_STATE(entropy->saved, state);
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
/* Account for restart interval if using restarts */
if (cinfo->restart_interval)
entropy->restarts_to_go--;
return TRUE;
}
@@ -777,7 +777,7 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
METHODDEF(boolean)
decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
register int s, k, r;
unsigned int EOBRUN;
@@ -809,7 +809,7 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
if (EOBRUN) /* if it's a band of zeroes... */
EOBRUN--; /* ...process it now (we do nothing) */
else {
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
Se = cinfo->Se;
Al = cinfo->Al;
natural_order = cinfo->natural_order;
@@ -842,15 +842,16 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
}
}
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
}
/* Completed MCU, so update state */
entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
/* Account for restart interval if using restarts */
if (cinfo->restart_interval)
entropy->restarts_to_go--;
return TRUE;
}
@@ -864,9 +865,10 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
METHODDEF(boolean)
decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
int p1, blkn;
JCOEF p1;
int blkn;
BITREAD_STATE_VARS;
/* Process restart marker if needed; may have to suspend */
@@ -881,7 +883,7 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
*/
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
@@ -896,10 +898,11 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
}
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
/* Account for restart interval if using restarts */
if (cinfo->restart_interval)
entropy->restarts_to_go--;
return TRUE;
}
@@ -911,11 +914,12 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
METHODDEF(boolean)
decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
register int s, k, r;
unsigned int EOBRUN;
int Se, p1, m1;
int Se;
JCOEF p1, m1;
const int * natural_order;
JBLOCKROW block;
JCOEFPTR thiscoef;
@@ -937,11 +941,11 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
Se = cinfo->Se;
p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */
m1 = -p1; /* -1 in the bit position being coded */
natural_order = cinfo->natural_order;
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
/* There is always only one block per MCU */
@@ -1043,12 +1047,13 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
}
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
/* Account for restart interval if using restarts */
if (cinfo->restart_interval)
entropy->restarts_to_go--;
return TRUE;
@@ -1091,7 +1096,7 @@ decode_mcu_sub (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
Se = cinfo->lim_Se;
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
ASSIGN_STATE(state, entropy->saved);
/* Outer loop handles each block in the MCU */
@@ -1178,12 +1183,13 @@ decode_mcu_sub (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
}
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
ASSIGN_STATE(entropy->saved, state);
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
/* Account for restart interval if using restarts */
if (cinfo->restart_interval)
entropy->restarts_to_go--;
return TRUE;
}
@@ -1215,7 +1221,7 @@ decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
if (! entropy->insufficient_data) {
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
ASSIGN_STATE(state, entropy->saved);
/* Outer loop handles each block in the MCU */
@@ -1302,12 +1308,13 @@ decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
}
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
ASSIGN_STATE(entropy->saved, state);
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
/* Account for restart interval if using restarts */
if (cinfo->restart_interval)
entropy->restarts_to_go--;
return TRUE;
}
@@ -1343,11 +1350,11 @@ start_pass_huff_decoder (j_decompress_ptr cinfo)
goto bad;
}
if (cinfo->Al > 13) { /* need not check for < 0 */
/* Arguably the maximum Al value should be less than 13 for 8-bit precision,
* but the spec doesn't say so, and we try to be liberal about what we
* accept. Note: large Al values could result in out-of-range DC
* coefficients during early scans, leading to bizarre displays due to
* overflows in the IDCT math. But we won't crash.
/* Arguably the maximum Al value should be less than 13 for 8-bit
* precision, but the spec doesn't say so, and we try to be liberal
* about what we accept. Note: large Al values could result in
* out-of-range DC coefficients during early scans, leading to bizarre
* displays due to overflows in the IDCT math. But we won't crash.
*/
bad:
ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
@@ -1451,7 +1458,8 @@ start_pass_huff_decoder (j_decompress_ptr cinfo)
compptr = cinfo->cur_comp_info[ci];
/* Precalculate which table to use for each block */
entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no];
entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no];
entropy->ac_cur_tbls[blkn] = /* AC needs no table when not present */
cinfo->lim_Se ? entropy->ac_derived_tbls[compptr->ac_tbl_no] : NULL;
/* Decide whether we really care about the coefficient values */
if (compptr->component_needed) {
ci = compptr->DCT_v_scaled_size;
@@ -1494,7 +1502,6 @@ start_pass_huff_decoder (j_decompress_ptr cinfo)
if (ci <= 0 || ci > 8) ci = 8;
if (i <= 0 || i > 8) i = 8;
entropy->coef_limit[blkn] = 1 + jpeg_zigzag_order[ci - 1][i - 1];
break;
}
} else {
entropy->coef_limit[blkn] = 0;
@@ -1522,9 +1529,8 @@ jinit_huff_decoder (j_decompress_ptr cinfo)
huff_entropy_ptr entropy;
int i;
entropy = (huff_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(huff_entropy_decoder));
entropy = (huff_entropy_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(huff_entropy_decoder));
cinfo->entropy = &entropy->pub;
entropy->pub.start_pass = start_pass_huff_decoder;
entropy->pub.finish_pass = finish_pass_huff;
@@ -1532,9 +1538,9 @@ jinit_huff_decoder (j_decompress_ptr cinfo)
if (cinfo->progressive_mode) {
/* Create progression status table */
int *coef_bit_ptr, ci;
cinfo->coef_bits = (int (*)[DCTSIZE2])
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
cinfo->num_components*DCTSIZE2*SIZEOF(int));
cinfo->coef_bits = (int (*)[DCTSIZE2]) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE,
cinfo->num_components * DCTSIZE2 * SIZEOF(int));
coef_bit_ptr = & cinfo->coef_bits[0][0];
for (ci = 0; ci < cinfo->num_components; ci++)
for (i = 0; i < DCTSIZE2; i++)
@@ -1545,7 +1551,7 @@ jinit_huff_decoder (j_decompress_ptr cinfo)
entropy->derived_tbls[i] = NULL;
}
} else {
/* Mark tables unallocated */
/* Mark derived tables unallocated */
for (i = 0; i < NUM_HUFF_TBLS; i++) {
entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
}
+7 -13
View File
@@ -2,7 +2,7 @@
* jdmarker.c
*
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2009-2013 by Guido Vollbeding.
* Modified 2009-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -496,8 +496,6 @@ get_dht (j_decompress_ptr cinfo)
if (count > 256 || ((INT32) count) > length)
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
MEMZERO(huffval, SIZEOF(huffval)); /* pre-zero array for later copy */
for (i = 0; i < count; i++)
INPUT_BYTE(cinfo, huffval[i], return FALSE);
@@ -517,7 +515,8 @@ get_dht (j_decompress_ptr cinfo)
*htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));
if (count > 0)
MEMCOPY((*htblptr)->huffval, huffval, count * SIZEOF(UINT8));
}
if (length != 0)
@@ -577,14 +576,14 @@ get_dqt (j_decompress_ptr cinfo)
count = DCTSIZE2;
}
switch (count) {
switch ((int) count) {
case (2*2): natural_order = jpeg_natural_order2; break;
case (3*3): natural_order = jpeg_natural_order3; break;
case (4*4): natural_order = jpeg_natural_order4; break;
case (5*5): natural_order = jpeg_natural_order5; break;
case (6*6): natural_order = jpeg_natural_order6; break;
case (7*7): natural_order = jpeg_natural_order7; break;
default: natural_order = jpeg_natural_order; break;
default: natural_order = jpeg_natural_order;
}
for (i = 0; i < count; i++) {
@@ -784,7 +783,6 @@ examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data,
default:
TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,
GETJOCTET(data[5]), (int) totallen);
break;
}
} else {
/* Start of APP0 does not match "JFIF" or "JFXX", or too short */
@@ -858,7 +856,6 @@ get_interesting_appn (j_decompress_ptr cinfo)
default:
/* can't get here unless jpeg_save_markers chooses wrong processor */
ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
break;
}
/* skip any remaining data -- could be lots */
@@ -964,7 +961,6 @@ save_marker (j_decompress_ptr cinfo)
default:
TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker,
(int) (data_length + length));
break;
}
/* skip any remaining data -- could be lots */
@@ -1240,7 +1236,6 @@ read_markers (j_decompress_ptr cinfo)
* ought to change!
*/
ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
break;
}
/* Successfully processed marker, so reset state variable */
cinfo->unread_marker = 0;
@@ -1416,9 +1411,8 @@ jinit_marker_reader (j_decompress_ptr cinfo)
int i;
/* Create subobject in permanent pool */
marker = (my_marker_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(my_marker_reader));
marker = (my_marker_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_marker_reader));
cinfo->marker = &marker->pub;
/* Initialize public method pointers */
marker->pub.reset_marker_reader = reset_marker_reader;
+24 -23
View File
@@ -2,7 +2,7 @@
* jdmaster.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2002-2017 by Guido Vollbeding.
* Modified 2002-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -104,7 +104,7 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
*/
{
#ifdef IDCT_SCALING_SUPPORTED
int ci;
int ci, ssize;
jpeg_component_info *compptr;
#endif
@@ -124,19 +124,23 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
*/
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
int ssize = 1;
while (cinfo->min_DCT_h_scaled_size * ssize <=
(cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) == 0) {
ssize = ssize * 2;
}
ssize = 1;
if (! cinfo->raw_data_out)
while (cinfo->min_DCT_h_scaled_size * ssize <=
(cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) ==
0) {
ssize = ssize * 2;
}
compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size * ssize;
ssize = 1;
while (cinfo->min_DCT_v_scaled_size * ssize <=
(cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) == 0) {
ssize = ssize * 2;
}
if (! cinfo->raw_data_out)
while (cinfo->min_DCT_v_scaled_size * ssize <=
(cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) ==
0) {
ssize = ssize * 2;
}
compptr->DCT_v_scaled_size = cinfo->min_DCT_v_scaled_size * ssize;
/* We don't support IDCT ratios larger than 2. */
@@ -144,13 +148,10 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size * 2;
else if (compptr->DCT_v_scaled_size > compptr->DCT_h_scaled_size * 2)
compptr->DCT_v_scaled_size = compptr->DCT_h_scaled_size * 2;
}
/* Recompute downsampled dimensions of components;
* application needs to know these if using raw downsampled data.
*/
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* Recompute downsampled dimensions of components;
* application needs to know these if using raw downsampled data.
*/
/* Size in samples, after IDCT scaling */
compptr->downsampled_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width *
@@ -172,8 +173,10 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
break;
case JCS_RGB:
case JCS_BG_RGB:
#if RGB_PIXELSIZE != 3
cinfo->out_color_components = RGB_PIXELSIZE;
break;
#endif /* else share code with YCbCr */
case JCS_YCbCr:
case JCS_BG_YCC:
cinfo->out_color_components = 3;
@@ -184,7 +187,6 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
break;
default: /* else must be same colorspace as in file */
cinfo->out_color_components = cinfo->num_components;
break;
}
cinfo->output_components = (cinfo->quantize_colors ? 1 :
cinfo->out_color_components);
@@ -525,9 +527,8 @@ jinit_master_decompress (j_decompress_ptr cinfo)
{
my_master_ptr master;
master = (my_master_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_decomp_master));
master = (my_master_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_decomp_master));
cinfo->master = &master->pub;
master->pub.prepare_for_output_pass = prepare_for_output_pass;
master->pub.finish_output_pass = finish_output_pass;
+26 -39
View File
@@ -2,7 +2,7 @@
* jdmerge.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2013-2017 by Guido Vollbeding.
* Modified 2013-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -95,28 +95,22 @@ build_ycc_rgb_table (j_decompress_ptr cinfo)
INT32 x;
SHIFT_TEMPS
upsample->Cr_r_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
upsample->Cb_b_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
upsample->Cr_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
upsample->Cb_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
upsample->Cr_r_tab = (int *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
upsample->Cb_b_tab = (int *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
upsample->Cr_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
upsample->Cb_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
/* Cr=>R value is nearest int to 1.402 * x */
upsample->Cr_r_tab[i] = (int)
RIGHT_SHIFT(FIX(1.402) * x + ONE_HALF, SCALEBITS);
upsample->Cr_r_tab[i] = (int) DESCALE(FIX(1.402) * x, SCALEBITS);
/* Cb=>B value is nearest int to 1.772 * x */
upsample->Cb_b_tab[i] = (int)
RIGHT_SHIFT(FIX(1.772) * x + ONE_HALF, SCALEBITS);
upsample->Cb_b_tab[i] = (int) DESCALE(FIX(1.772) * x, SCALEBITS);
/* Cr=>G value is scaled-up -0.714136286 * x */
upsample->Cr_g_tab[i] = (- FIX(0.714136286)) * x;
/* Cb=>G value is scaled-up -0.344136286 * x */
@@ -135,28 +129,22 @@ build_bg_ycc_rgb_table (j_decompress_ptr cinfo)
INT32 x;
SHIFT_TEMPS
upsample->Cr_r_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
upsample->Cb_b_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
upsample->Cr_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
upsample->Cb_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
upsample->Cr_r_tab = (int *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
upsample->Cb_b_tab = (int *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
upsample->Cr_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
upsample->Cb_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
/* Cr=>R value is nearest int to 2.804 * x */
upsample->Cr_r_tab[i] = (int)
RIGHT_SHIFT(FIX(2.804) * x + ONE_HALF, SCALEBITS);
upsample->Cr_r_tab[i] = (int) DESCALE(FIX(2.804) * x, SCALEBITS);
/* Cb=>B value is nearest int to 3.544 * x */
upsample->Cb_b_tab[i] = (int)
RIGHT_SHIFT(FIX(3.544) * x + ONE_HALF, SCALEBITS);
upsample->Cb_b_tab[i] = (int) DESCALE(FIX(3.544) * x, SCALEBITS);
/* Cr=>G value is scaled-up -1.428272572 * x */
upsample->Cr_g_tab[i] = (- FIX(1.428272572)) * x;
/* Cb=>G value is scaled-up -0.688272572 * x */
@@ -419,9 +407,8 @@ jinit_merged_upsampler (j_decompress_ptr cinfo)
{
my_upsample_ptr upsample;
upsample = (my_upsample_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_upsampler));
upsample = (my_upsample_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_upsampler));
cinfo->upsample = &upsample->pub;
upsample->pub.start_pass = start_pass_merged_upsample;
upsample->pub.need_context_rows = FALSE;
@@ -432,9 +419,9 @@ jinit_merged_upsampler (j_decompress_ptr cinfo)
upsample->pub.upsample = merged_2v_upsample;
upsample->upmethod = h2v2_merged_upsample;
/* Allocate a spare row buffer */
upsample->spare_row = (JSAMPROW)
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
upsample->spare_row = (JSAMPROW) (*cinfo->mem->alloc_large)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(size_t) upsample->out_row_width * SIZEOF(JSAMPLE));
} else {
upsample->pub.upsample = merged_1v_upsample;
upsample->upmethod = h2v1_merged_upsample;
+2 -2
View File
@@ -2,7 +2,7 @@
* jerror.h
*
* Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 1997-2012 by Guido Vollbeding.
* Modified 1997-2018 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -84,7 +84,7 @@ JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan")
JMESSAGE(JERR_FILE_READ, "Input file read error")
JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?")
JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet")
JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow")
JMESSAGE(JERR_HUFF_CLEN_OUTOFBOUNDS, "Huffman code size table out of bounds")
JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry")
JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels")
JMESSAGE(JERR_INPUT_EMPTY, "Empty input file")
+61 -55
View File
@@ -2,7 +2,7 @@
* jfdctint.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modification developed 2003-2015 by Guido Vollbeding.
* Modification developed 2003-2018 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -3261,78 +3261,84 @@ jpeg_fdct_6x3 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
GLOBAL(void)
jpeg_fdct_4x2 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
{
INT32 tmp0, tmp1;
INT32 tmp10, tmp11;
DCTELEM *dataptr;
DCTELEM tmp0, tmp2, tmp10, tmp12, tmp4, tmp5;
INT32 tmp1, tmp3, tmp11, tmp13;
INT32 z1, z2, z3;
JSAMPROW elemptr;
int ctr;
SHIFT_TEMPS
/* Pre-zero output coefficient block. */
MEMZERO(data, SIZEOF(DCTELEM) * DCTSIZE2);
/* Pass 1: process rows.
* Note results are scaled up by sqrt(8) compared to a true DCT;
* furthermore, we scale the results by 2**PASS1_BITS.
* We must also scale the output by (8/4)*(8/2) = 2**3, which we add here.
* Note results are scaled up by sqrt(8) compared to a true DCT.
* 4-point FDCT kernel,
* cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point FDCT].
*/
dataptr = data;
for (ctr = 0; ctr < 2; ctr++) {
elemptr = sample_data[ctr] + start_col;
/* Row 0 */
elemptr = sample_data[0] + start_col;
/* Even part */
/* Even part */
tmp0 = GETJSAMPLE(elemptr[0]) + GETJSAMPLE(elemptr[3]);
tmp1 = GETJSAMPLE(elemptr[1]) + GETJSAMPLE(elemptr[2]);
tmp4 = GETJSAMPLE(elemptr[0]) + GETJSAMPLE(elemptr[3]);
tmp5 = GETJSAMPLE(elemptr[1]) + GETJSAMPLE(elemptr[2]);
tmp10 = GETJSAMPLE(elemptr[0]) - GETJSAMPLE(elemptr[3]);
tmp11 = GETJSAMPLE(elemptr[1]) - GETJSAMPLE(elemptr[2]);
tmp0 = tmp4 + tmp5;
tmp2 = tmp4 - tmp5;
/* Apply unsigned->signed conversion. */
dataptr[0] = (DCTELEM)
((tmp0 + tmp1 - 4 * CENTERJSAMPLE) << (PASS1_BITS+3));
dataptr[2] = (DCTELEM) ((tmp0 - tmp1) << (PASS1_BITS+3));
/* Odd part */
/* Odd part */
z2 = GETJSAMPLE(elemptr[0]) - GETJSAMPLE(elemptr[3]);
z3 = GETJSAMPLE(elemptr[1]) - GETJSAMPLE(elemptr[2]);
tmp0 = MULTIPLY(tmp10 + tmp11, FIX_0_541196100); /* c6 */
/* Add fudge factor here for final descale. */
tmp0 += ONE << (CONST_BITS-PASS1_BITS-4);
z1 = MULTIPLY(z2 + z3, FIX_0_541196100); /* c6 */
/* Add fudge factor here for final descale. */
z1 += ONE << (CONST_BITS-3-1);
tmp1 = z1 + MULTIPLY(z2, FIX_0_765366865); /* c2-c6 */
tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065); /* c2+c6 */
dataptr[1] = (DCTELEM)
RIGHT_SHIFT(tmp0 + MULTIPLY(tmp10, FIX_0_765366865), /* c2-c6 */
CONST_BITS-PASS1_BITS-3);
dataptr[3] = (DCTELEM)
RIGHT_SHIFT(tmp0 - MULTIPLY(tmp11, FIX_1_847759065), /* c2+c6 */
CONST_BITS-PASS1_BITS-3);
/* Row 1 */
elemptr = sample_data[1] + start_col;
dataptr += DCTSIZE; /* advance pointer to next row */
}
/* Even part */
tmp4 = GETJSAMPLE(elemptr[0]) + GETJSAMPLE(elemptr[3]);
tmp5 = GETJSAMPLE(elemptr[1]) + GETJSAMPLE(elemptr[2]);
tmp10 = tmp4 + tmp5;
tmp12 = tmp4 - tmp5;
/* Odd part */
z2 = GETJSAMPLE(elemptr[0]) - GETJSAMPLE(elemptr[3]);
z3 = GETJSAMPLE(elemptr[1]) - GETJSAMPLE(elemptr[2]);
z1 = MULTIPLY(z2 + z3, FIX_0_541196100); /* c6 */
tmp11 = z1 + MULTIPLY(z2, FIX_0_765366865); /* c2-c6 */
tmp13 = z1 - MULTIPLY(z3, FIX_1_847759065); /* c2+c6 */
/* Pass 2: process columns.
* We remove the PASS1_BITS scaling, but leave the results scaled up
* by an overall factor of 8.
* We leave the results scaled up by an overall factor of 8.
* We must also scale the output by (8/4)*(8/2) = 2**3.
*/
dataptr = data;
for (ctr = 0; ctr < 4; ctr++) {
/* Even part */
/* Column 0 */
/* Apply unsigned->signed conversion. */
data[DCTSIZE*0] = (tmp0 + tmp10 - 8 * CENTERJSAMPLE) << 3;
data[DCTSIZE*1] = (tmp0 - tmp10) << 3;
/* Add fudge factor here for final descale. */
tmp0 = dataptr[DCTSIZE*0] + (ONE << (PASS1_BITS-1));
tmp1 = dataptr[DCTSIZE*1];
/* Column 1 */
data[DCTSIZE*0+1] = (DCTELEM) RIGHT_SHIFT(tmp1 + tmp11, CONST_BITS-3);
data[DCTSIZE*1+1] = (DCTELEM) RIGHT_SHIFT(tmp1 - tmp11, CONST_BITS-3);
dataptr[DCTSIZE*0] = (DCTELEM) RIGHT_SHIFT(tmp0 + tmp1, PASS1_BITS);
/* Column 2 */
data[DCTSIZE*0+2] = (tmp2 + tmp12) << 3;
data[DCTSIZE*1+2] = (tmp2 - tmp12) << 3;
/* Odd part */
dataptr[DCTSIZE*1] = (DCTELEM) RIGHT_SHIFT(tmp0 - tmp1, PASS1_BITS);
dataptr++; /* advance pointer to next column */
}
/* Column 3 */
data[DCTSIZE*0+3] = (DCTELEM) RIGHT_SHIFT(tmp3 + tmp13, CONST_BITS-3);
data[DCTSIZE*1+3] = (DCTELEM) RIGHT_SHIFT(tmp3 - tmp13, CONST_BITS-3);
}
@@ -4312,7 +4318,6 @@ jpeg_fdct_2x4 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
/* Pass 1: process rows.
* Note results are scaled up by sqrt(8) compared to a true DCT.
* We must also scale the output by (8/2)*(8/4) = 2**3, which we add here.
*/
dataptr = data;
@@ -4325,17 +4330,18 @@ jpeg_fdct_2x4 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
tmp1 = GETJSAMPLE(elemptr[1]);
/* Apply unsigned->signed conversion. */
dataptr[0] = (DCTELEM) ((tmp0 + tmp1 - 2 * CENTERJSAMPLE) << 3);
dataptr[0] = (DCTELEM) (tmp0 + tmp1 - 2 * CENTERJSAMPLE);
/* Odd part */
dataptr[1] = (DCTELEM) ((tmp0 - tmp1) << 3);
dataptr[1] = (DCTELEM) (tmp0 - tmp1);
dataptr += DCTSIZE; /* advance pointer to next row */
}
/* Pass 2: process columns.
* We leave the results scaled up by an overall factor of 8.
* We must also scale the output by (8/2)*(8/4) = 2**3.
* 4-point FDCT kernel,
* cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point FDCT].
*/
@@ -4350,21 +4356,21 @@ jpeg_fdct_2x4 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
tmp10 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*3];
tmp11 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*2];
dataptr[DCTSIZE*0] = (DCTELEM) (tmp0 + tmp1);
dataptr[DCTSIZE*2] = (DCTELEM) (tmp0 - tmp1);
dataptr[DCTSIZE*0] = (DCTELEM) ((tmp0 + tmp1) << 3);
dataptr[DCTSIZE*2] = (DCTELEM) ((tmp0 - tmp1) << 3);
/* Odd part */
tmp0 = MULTIPLY(tmp10 + tmp11, FIX_0_541196100); /* c6 */
/* Add fudge factor here for final descale. */
tmp0 += ONE << (CONST_BITS-1);
tmp0 += ONE << (CONST_BITS-3-1);
dataptr[DCTSIZE*1] = (DCTELEM)
RIGHT_SHIFT(tmp0 + MULTIPLY(tmp10, FIX_0_765366865), /* c2-c6 */
CONST_BITS);
CONST_BITS-3);
dataptr[DCTSIZE*3] = (DCTELEM)
RIGHT_SHIFT(tmp0 - MULTIPLY(tmp11, FIX_1_847759065), /* c2+c6 */
CONST_BITS);
CONST_BITS-3);
dataptr++; /* advance pointer to next column */
}
+6 -6
View File
@@ -2,7 +2,7 @@
* jidctint.c
*
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modification developed 2002-2016 by Guido Vollbeding.
* Modification developed 2002-2018 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -1474,7 +1474,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).
@@ -3675,7 +3675,7 @@ jpeg_idct_10x5 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
/*
* Perform dequantization and inverse DCT on one block of coefficients,
* producing a 8x4 output block.
* producing an 8x4 output block.
*
* 4-point IDCT in pass 1 (columns), 8-point in pass 2 (rows).
*/
@@ -3835,7 +3835,7 @@ jpeg_idct_8x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
/*
* Perform dequantization and inverse DCT on one block of coefficients,
* producing a reduced-size 6x3 output block.
* producing a 6x3 output block.
*
* 3-point IDCT in pass 1 (columns), 6-point in pass 2 (rows).
*/
@@ -4082,7 +4082,7 @@ jpeg_idct_2x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
/*
* Perform dequantization and inverse DCT on one block of coefficients,
* producing a 8x16 output block.
* producing an 8x16 output block.
*
* 16-point IDCT in pass 1 (columns), 8-point in pass 2 (rows).
*/
@@ -5004,7 +5004,7 @@ jpeg_idct_4x8 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
/*
* Perform dequantization and inverse DCT on one block of coefficients,
* producing a reduced-size 3x6 output block.
* producing a 3x6 output block.
*
* 6-point IDCT in pass 1 (columns), 3-point in pass 2 (rows).
*/
+28 -32
View File
@@ -2,7 +2,7 @@
* jmemmgr.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2011-2012 by Guido Vollbeding.
* Modified 2011-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -130,7 +130,7 @@ typedef struct {
jvirt_barray_ptr virt_barray_list;
/* This counts total space obtained from jpeg_get_small/large */
long total_space_allocated;
size_t total_space_allocated;
/* alloc_sarray and alloc_barray set this value for use by virtual
* array routines.
@@ -195,7 +195,7 @@ print_mem_stats (j_common_ptr cinfo, int pool_id)
* This is helpful because message parm array can't handle longs.
*/
fprintf(stderr, "Freeing pool %d, total space = %ld\n",
pool_id, mem->total_space_allocated);
pool_id, (long) mem->total_space_allocated);
for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL;
lhdr_ptr = lhdr_ptr->hdr.next) {
@@ -260,11 +260,11 @@ alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
{
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
small_pool_ptr hdr_ptr, prev_hdr_ptr;
char * data_ptr;
size_t odd_bytes, min_request, slop;
char * data_ptr;
/* Check for unsatisfiable request (do now to ensure no overflow below) */
if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr)))
if (sizeofobject > (size_t) MAX_ALLOC_CHUNK - SIZEOF(small_pool_hdr))
out_of_memory(cinfo, 1); /* request exceeds malloc's ability */
/* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
@@ -293,8 +293,8 @@ alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
else
slop = extra_pool_slop[pool_id];
/* Don't ask for more than MAX_ALLOC_CHUNK */
if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request))
slop = (size_t) (MAX_ALLOC_CHUNK-min_request);
if (slop > (size_t) MAX_ALLOC_CHUNK - min_request)
slop = (size_t) MAX_ALLOC_CHUNK - min_request;
/* Try to get space, if fail reduce slop and try again */
for (;;) {
hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop);
@@ -348,7 +348,7 @@ alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
size_t odd_bytes;
/* Check for unsatisfiable request (do now to ensure no overflow below) */
if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)))
if (sizeofobject > (size_t) MAX_ALLOC_CHUNK - SIZEOF(large_pool_hdr))
out_of_memory(cinfo, 3); /* request exceeds malloc's ability */
/* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
@@ -404,7 +404,7 @@ alloc_sarray (j_common_ptr cinfo, int pool_id,
long ltemp;
/* Calculate max # of rows allowed in one allocation chunk */
ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
ltemp = (MAX_ALLOC_CHUNK - SIZEOF(large_pool_hdr)) /
((long) samplesperrow * SIZEOF(JSAMPLE));
if (ltemp <= 0)
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
@@ -416,15 +416,14 @@ alloc_sarray (j_common_ptr cinfo, int pool_id,
/* Get space for row pointers (small object) */
result = (JSAMPARRAY) alloc_small(cinfo, pool_id,
(size_t) (numrows * SIZEOF(JSAMPROW)));
(size_t) numrows * SIZEOF(JSAMPROW));
/* Get the rows themselves (large objects) */
currow = 0;
while (currow < numrows) {
rowsperchunk = MIN(rowsperchunk, numrows - currow);
workspace = (JSAMPROW) alloc_large(cinfo, pool_id,
(size_t) ((size_t) rowsperchunk * (size_t) samplesperrow
* SIZEOF(JSAMPLE)));
(size_t) rowsperchunk * (size_t) samplesperrow * SIZEOF(JSAMPLE));
for (i = rowsperchunk; i > 0; i--) {
result[currow++] = workspace;
workspace += samplesperrow;
@@ -452,7 +451,7 @@ alloc_barray (j_common_ptr cinfo, int pool_id,
long ltemp;
/* Calculate max # of rows allowed in one allocation chunk */
ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
ltemp = (MAX_ALLOC_CHUNK - SIZEOF(large_pool_hdr)) /
((long) blocksperrow * SIZEOF(JBLOCK));
if (ltemp <= 0)
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
@@ -464,15 +463,14 @@ alloc_barray (j_common_ptr cinfo, int pool_id,
/* Get space for row pointers (small object) */
result = (JBLOCKARRAY) alloc_small(cinfo, pool_id,
(size_t) (numrows * SIZEOF(JBLOCKROW)));
(size_t) numrows * SIZEOF(JBLOCKROW));
/* Get the rows themselves (large objects) */
currow = 0;
while (currow < numrows) {
rowsperchunk = MIN(rowsperchunk, numrows - currow);
workspace = (JBLOCKROW) alloc_large(cinfo, pool_id,
(size_t) ((size_t) rowsperchunk * (size_t) blocksperrow
* SIZEOF(JBLOCK)));
(size_t) rowsperchunk * (size_t) blocksperrow * SIZEOF(JBLOCK));
for (i = rowsperchunk; i > 0; i--) {
result[currow++] = workspace;
workspace += blocksperrow;
@@ -585,8 +583,8 @@ realize_virt_arrays (j_common_ptr cinfo)
/* Allocate the in-memory buffers for any unrealized virtual arrays */
{
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
long space_per_minheight, maximum_space, avail_mem;
long minheights, max_minheights;
long bytesperrow, space_per_minheight, maximum_space;
long avail_mem, minheights, max_minheights;
jvirt_sarray_ptr sptr;
jvirt_barray_ptr bptr;
@@ -598,18 +596,16 @@ realize_virt_arrays (j_common_ptr cinfo)
maximum_space = 0;
for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
if (sptr->mem_buffer == NULL) { /* if not realized yet */
space_per_minheight += (long) sptr->maxaccess *
(long) sptr->samplesperrow * SIZEOF(JSAMPLE);
maximum_space += (long) sptr->rows_in_array *
(long) sptr->samplesperrow * SIZEOF(JSAMPLE);
bytesperrow = (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
space_per_minheight += (long) sptr->maxaccess * bytesperrow;
maximum_space += (long) sptr->rows_in_array * bytesperrow;
}
}
for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
if (bptr->mem_buffer == NULL) { /* if not realized yet */
space_per_minheight += (long) bptr->maxaccess *
(long) bptr->blocksperrow * SIZEOF(JBLOCK);
maximum_space += (long) bptr->rows_in_array *
(long) bptr->blocksperrow * SIZEOF(JBLOCK);
bytesperrow = (long) bptr->blocksperrow * SIZEOF(JBLOCK);
space_per_minheight += (long) bptr->maxaccess * bytesperrow;
maximum_space += (long) bptr->rows_in_array * bytesperrow;
}
}
@@ -618,7 +614,7 @@ realize_virt_arrays (j_common_ptr cinfo)
/* Determine amount of memory to actually use; this is system-dependent. */
avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space,
mem->total_space_allocated);
(long) mem->total_space_allocated);
/* If the maximum space needed is available, make all the buffers full
* height; otherwise parcel it out with the same number of minheights
@@ -694,7 +690,7 @@ do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
long bytesperrow, file_offset, byte_count, rows, thisrow, i;
bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE);
file_offset = ptr->cur_start_row * bytesperrow;
file_offset = (long) ptr->cur_start_row * bytesperrow;
/* Loop to read or write each allocation chunk in mem_buffer */
for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
/* One chunk, but check for short chunk at end of buffer */
@@ -727,7 +723,7 @@ do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing)
long bytesperrow, file_offset, byte_count, rows, thisrow, i;
bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK);
file_offset = ptr->cur_start_row * bytesperrow;
file_offset = (long) ptr->cur_start_row * bytesperrow;
/* Loop to read or write each allocation chunk in mem_buffer */
for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
/* One chunk, but check for short chunk at end of buffer */
@@ -771,7 +767,7 @@ access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
/* Make the desired part of the virtual array accessible */
if (start_row < ptr->cur_start_row ||
end_row > ptr->cur_start_row+ptr->rows_in_mem) {
end_row > ptr->cur_start_row + ptr->rows_in_mem) {
if (! ptr->b_s_open)
ERREXIT(cinfo, JERR_VIRTUAL_BUG);
/* Flush old buffer contents if necessary */
@@ -856,7 +852,7 @@ access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
/* Make the desired part of the virtual array accessible */
if (start_row < ptr->cur_start_row ||
end_row > ptr->cur_start_row+ptr->rows_in_mem) {
end_row > ptr->cur_start_row + ptr->rows_in_mem) {
if (! ptr->b_s_open)
ERREXIT(cinfo, JERR_VIRTUAL_BUG);
/* Flush old buffer contents if necessary */
@@ -1093,7 +1089,7 @@ jinit_memory_mgr (j_common_ptr cinfo)
mem->total_space_allocated = SIZEOF(my_memory_mgr);
/* Declare ourselves open for business */
cinfo->mem = & mem->pub;
cinfo->mem = &mem->pub;
/* Check for an environment variable JPEGMEM; if found, override the
* default max_memory setting from jpeg_mem_init. Note that the
+6 -2
View File
@@ -2,6 +2,7 @@
* jmemnobs.c
*
* Copyright (C) 1992-1996, Thomas G. Lane.
* Modified 2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -12,7 +13,7 @@
* This is very portable in the sense that it'll compile on almost anything,
* but you'd better have lots of main memory (or virtual memory) if you want
* to process big images.
* Note that the max_memory_to_use option is ignored by this implementation.
* Note that the max_memory_to_use option is respected by this implementation.
*/
#define JPEG_INTERNALS
@@ -66,13 +67,16 @@ jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
/*
* This routine computes the total memory space available for allocation.
* Here we always say, "we got all you want bud!"
*/
GLOBAL(long)
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
long max_bytes_needed, long already_allocated)
{
if (cinfo->mem->max_memory_to_use)
return cinfo->mem->max_memory_to_use - already_allocated;
/* Here we say, "we got all you want bud!" */
return max_bytes_needed;
}
+8 -1
View File
@@ -2,7 +2,7 @@
* jpegint.h
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 1997-2017 by Guido Vollbeding.
* Modified 1997-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -302,6 +302,13 @@ struct jpeg_color_quantizer {
#define RIGHT_SHIFT(x,shft) ((x) >> (shft))
#endif
/* Descale and correctly round an INT32 value that's scaled by N bits.
* We assume RIGHT_SHIFT rounds towards minus infinity, so adding
* the fudge factor is correct for either sign of X.
*/
#define DESCALE(x,n) RIGHT_SHIFT((x) + ((INT32) 1 << ((n)-1)), n)
/* Short forms of external names for systems with brain-damaged linkers. */
+7 -4
View File
@@ -2,7 +2,7 @@
* jpeglib.h
*
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2002-2017 by Guido Vollbeding.
* Modified 2002-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -39,7 +39,7 @@ extern "C" {
#define JPEG_LIB_VERSION 90 /* Compatibility version 9.0 */
#define JPEG_LIB_VERSION_MAJOR 9
#define JPEG_LIB_VERSION_MINOR 3
#define JPEG_LIB_VERSION_MINOR 4
/* Various constants determining the sizes of things.
@@ -909,6 +909,7 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
#define jpeg_suppress_tables jSuppressTables
#define jpeg_alloc_quant_table jAlcQTable
#define jpeg_alloc_huff_table jAlcHTable
#define jpeg_std_huff_table jStdHTable
#define jpeg_start_compress jStrtCompress
#define jpeg_write_scanlines jWrtScanlines
#define jpeg_finish_compress jFinCompress
@@ -977,10 +978,10 @@ EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile));
/* Data source and destination managers: memory buffers. */
EXTERN(void) jpeg_mem_dest JPP((j_compress_ptr cinfo,
unsigned char ** outbuffer,
unsigned long * outsize));
size_t * outsize));
EXTERN(void) jpeg_mem_src JPP((j_decompress_ptr cinfo,
const unsigned char * inbuffer,
unsigned long insize));
size_t insize));
/* Default parameter setup for compression */
EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo));
@@ -1005,6 +1006,8 @@ EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo,
boolean suppress));
EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo));
EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo));
EXTERN(JHUFF_TBL *) jpeg_std_huff_table JPP((j_common_ptr cinfo,
boolean isDC, int tblno));
/* Main entry points for compression */
EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo,
+3 -3
View File
@@ -2,7 +2,7 @@
* jutils.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2009-2011 by Guido Vollbeding.
* Modified 2009-2019 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -185,7 +185,7 @@ jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
{
register JSAMPROW inptr, outptr;
#ifdef FMEMCOPY
register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE));
register size_t count = (size_t) num_cols * SIZEOF(JSAMPLE);
#else
register JDIMENSION count;
#endif
@@ -213,7 +213,7 @@ jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
/* Copy a row of coefficient blocks from one place to another. */
{
#ifdef FMEMCOPY
FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
FMEMCOPY(output_row, input_row, (size_t) num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
#else
register JCOEFPTR inptr, outptr;
register long count;
+3 -3
View File
@@ -1,7 +1,7 @@
/*
* jversion.h
*
* Copyright (C) 1991-2018, Thomas G. Lane, Guido Vollbeding.
* Copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -9,6 +9,6 @@
*/
#define JVERSION "9c 14-Jan-2018"
#define JVERSION "9d 12-Jan-2020"
#define JCOPYRIGHT "Copyright (C) 2018, Thomas G. Lane, Guido Vollbeding"
#define JCOPYRIGHT "Copyright (C) 2020, Thomas G. Lane, Guido Vollbeding"
+3 -5
View File
@@ -22,7 +22,7 @@
# sqfu@openailab.com
#
SET(TENGINE_COMMIT_VERSION "2f3cd86217f3530c8e4a82f3ed5af14c7a4e3943")
SET(TENGINE_COMMIT_VERSION "8a4c58e0e05cd850f4bb0936a330edc86dc0e28c")
SET(OCV_TENGINE_DIR "${OpenCV_BINARY_DIR}/3rdparty/libtengine")
SET(OCV_TENGINE_SOURCE_PATH "${OCV_TENGINE_DIR}/Tengine-${TENGINE_COMMIT_VERSION}")
@@ -34,7 +34,7 @@ IF(EXISTS "${OCV_TENGINE_SOURCE_PATH}")
ELSE()
SET(OCV_TENGINE_FILENAME "${TENGINE_COMMIT_VERSION}.zip")#name2
SET(OCV_TENGINE_URL "https://github.com/OAID/Tengine/archive/") #url2
SET(tengine_md5sum 9124324b6e2b350012e46ae1db4bad7d) #md5sum2
SET(tengine_md5sum f51ca8f3963faeeff3f019a6f6edc206) #md5sum2
#MESSAGE(STATUS "**** TENGINE DOWNLOAD BEGIN ****")
ocv_download(FILENAME ${OCV_TENGINE_FILENAME}
@@ -69,7 +69,6 @@ if(BUILD_TENGINE)
elseif(${ANDROID_ABI} STREQUAL "arm64-v8a")
SET(CONFIG_ARCH_ARM64 ON)
endif()
SET(Tengine_LIB "tengine" CACHE INTERNAL "")
else()
# linux system
if(CMAKE_SYSTEM_PROCESSOR STREQUAL arm)
@@ -77,7 +76,6 @@ if(BUILD_TENGINE)
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64) ## AARCH64
SET(CONFIG_ARCH_ARM64 ON)
endif()
SET(Tengine_LIB "tengine" CACHE INTERNAL "")
endif()
SET(BUILT_IN_OPENCV ON) ## set for tengine compile discern .
@@ -86,6 +84,6 @@ if(BUILD_TENGINE)
add_subdirectory("${OCV_TENGINE_SOURCE_PATH}" "${OCV_TENGINE_DIR}/build")
else()
message(WARNING "TENGINE: Missing 'CMakeLists.txt' in source code package: ${OCV_TENGINE_SOURCE_PATH}")
SET(HAVE_TENGINE 1)
endif()
SET(Tengine_LIB "tengine" CACHE INTERNAL "")
endif()
+4
View File
@@ -1652,6 +1652,10 @@ if(ENABLE_CONFIG_VERIFICATION)
ocv_verify_config()
endif()
if(HAVE_CUDA AND COMMAND CUDA_BUILD_CLEAN_TARGET)
CUDA_BUILD_CLEAN_TARGET()
endif()
ocv_cmake_hook(POST_FINALIZE)
# ----------------------------------------------------------------------------
+3 -1
View File
@@ -189,7 +189,6 @@ if(CV_GCC OR CV_CLANG)
# Profiling?
if(ENABLE_PROFILING)
add_extra_compiler_option("-pg -g")
# turn off incompatible options
foreach(flags CMAKE_CXX_FLAGS CMAKE_C_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG
OPENCV_EXTRA_FLAGS_RELEASE OPENCV_EXTRA_FLAGS_DEBUG OPENCV_EXTRA_C_FLAGS OPENCV_EXTRA_CXX_FLAGS)
@@ -197,6 +196,9 @@ if(CV_GCC OR CV_CLANG)
string(REPLACE "-ffunction-sections" "" ${flags} "${${flags}}")
string(REPLACE "-fdata-sections" "" ${flags} "${${flags}}")
endforeach()
# -pg should be placed both in the linker and in the compiler settings
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg")
add_extra_compiler_option("-pg -g")
else()
if(MSVC)
# TODO: Clang/C2 is not supported
+198 -26
View File
@@ -1,13 +1,14 @@
if(WIN32 AND NOT MSVC)
if((WIN32 AND NOT MSVC) OR OPENCV_CMAKE_FORCE_CUDA)
message(STATUS "CUDA compilation is disabled (due to only Visual Studio compiler supported on your platform).")
return()
endif()
if(NOT UNIX AND CV_CLANG)
if((NOT UNIX AND CV_CLANG) OR OPENCV_CMAKE_FORCE_CUDA)
message(STATUS "CUDA compilation is disabled (due to Clang unsupported on your platform).")
return()
endif()
#set(OPENCV_CMAKE_CUDA_DEBUG 1)
if(((NOT CMAKE_VERSION VERSION_LESS "3.9.0") # requires https://gitlab.kitware.com/cmake/cmake/merge_requests/663
OR OPENCV_CUDA_FORCE_EXTERNAL_CMAKE_MODULE)
@@ -28,6 +29,11 @@ endif()
if(CUDA_FOUND)
set(HAVE_CUDA 1)
if(NOT CUDA_VERSION VERSION_LESS 11.0)
# CUDA 11.0 removes nppicom
ocv_list_filterout(CUDA_nppi_LIBRARY "nppicom")
ocv_list_filterout(CUDA_npp_LIBRARY "nppicom")
endif()
if(WITH_CUFFT)
set(HAVE_CUFFT 1)
@@ -38,11 +44,31 @@ if(CUDA_FOUND)
endif()
if(WITH_NVCUVID)
macro(ocv_cuda_SEARCH_NVCUVID_HEADER _filename _result)
# place header file under CUDA_TOOLKIT_TARGET_DIR or CUDA_TOOLKIT_ROOT_DIR
find_path(_header_result
${_filename}
PATHS "${CUDA_TOOLKIT_TARGET_DIR}" "${CUDA_TOOLKIT_ROOT_DIR}"
ENV CUDA_PATH
ENV CUDA_INC_PATH
PATH_SUFFIXES include
NO_DEFAULT_PATH
)
if("x${_header_result}" STREQUAL "x_header_result-NOTFOUND")
set(${_result} 0)
else()
set(${_result} 1)
endif()
unset(_header_result CACHE)
endmacro()
ocv_cuda_SEARCH_NVCUVID_HEADER("nvcuvid.h" HAVE_NVCUVID_HEADER)
ocv_cuda_SEARCH_NVCUVID_HEADER("dynlink_nvcuvid.h" HAVE_DYNLINK_NVCUVID_HEADER)
find_cuda_helper_libs(nvcuvid)
if(WIN32)
find_cuda_helper_libs(nvcuvenc)
endif()
if(CUDA_nvcuvid_LIBRARY)
if(CUDA_nvcuvid_LIBRARY AND (${HAVE_NVCUVID_HEADER} OR ${HAVE_DYNLINK_NVCUVID_HEADER}))
# make sure to have both header and library before enabling
set(HAVE_NVCUVID 1)
endif()
if(CUDA_nvcuvenc_LIBRARY)
@@ -52,13 +78,14 @@ if(CUDA_FOUND)
message(STATUS "CUDA detected: " ${CUDA_VERSION})
set(_generations "Fermi" "Kepler" "Maxwell" "Pascal" "Volta" "Turing")
set(_generations "Fermi" "Kepler" "Maxwell" "Pascal" "Volta" "Turing" "Ampere")
set(_arch_fermi "2.0")
set(_arch_kepler "3.0;3.5;3.7")
set(_arch_maxwell "5.0;5.2")
set(_arch_pascal "6.0;6.1")
set(_arch_volta "7.0")
set(_arch_turing "7.5")
set(_arch_ampere "8.0")
if(NOT CMAKE_CROSSCOMPILING)
list(APPEND _generations "Auto")
endif()
@@ -76,36 +103,104 @@ if(CUDA_FOUND)
unset(CUDA_ARCH_PTX CACHE)
endif()
if(OPENCV_CUDA_DETECTION_NVCC_FLAGS MATCHES "-ccbin")
# already specified by user
elseif(CUDA_HOST_COMPILER AND EXISTS "${CUDA_HOST_COMPILER}")
get_filename_component(c_compiler_realpath "${CMAKE_C_COMPILER}" REALPATH)
# C compiler doesn't work with --run option, forcing C++ compiler instead
if(CUDA_HOST_COMPILER STREQUAL c_compiler_realpath OR CUDA_HOST_COMPILER STREQUAL CMAKE_C_COMPILER)
if(DEFINED CMAKE_CXX_COMPILER)
get_filename_component(cxx_compiler_realpath "${CMAKE_CXX_COMPILER}" REALPATH)
LIST(APPEND OPENCV_CUDA_DETECTION_NVCC_FLAGS -ccbin "${cxx_compiler_realpath}")
else()
message(STATUS "CUDA: CMAKE_CXX_COMPILER is not available. You may need to specify CUDA_HOST_COMPILER.")
endif()
else()
LIST(APPEND OPENCV_CUDA_DETECTION_NVCC_FLAGS -ccbin "${CUDA_HOST_COMPILER}")
endif()
elseif(WIN32 AND CMAKE_LINKER) # Workaround for VS cl.exe not being in the env. path
get_filename_component(host_compiler_bindir ${CMAKE_LINKER} DIRECTORY)
LIST(APPEND OPENCV_CUDA_DETECTION_NVCC_FLAGS -ccbin "${host_compiler_bindir}")
else()
if(CUDA_HOST_COMPILER)
message(STATUS "CUDA: CUDA_HOST_COMPILER='${CUDA_HOST_COMPILER}' is not valid, autodetection may not work. Specify OPENCV_CUDA_DETECTION_NVCC_FLAGS with -ccbin option for fix that")
endif()
endif()
macro(ocv_filter_available_architecture result_list)
if(DEFINED CUDA_SUPPORTED_CC)
set(${result_list} "${CUDA_SUPPORTED_CC}")
set(__cache_key_check "${ARGN} : ${CUDA_NVCC_EXECUTABLE} ${OPENCV_CUDA_DETECTION_NVCC_FLAGS}")
if(DEFINED OPENCV_CACHE_CUDA_SUPPORTED_CC AND OPENCV_CACHE_CUDA_SUPPORTED_CC_check STREQUAL __cache_key_check)
set(${result_list} "${OPENCV_CACHE_CUDA_SUPPORTED_CC}")
else()
set(CC_LIST ${ARGN})
foreach(target_arch ${CC_LIST})
string(REPLACE "." "" target_arch_short ${target_arch})
string(REPLACE "." "" target_arch_short "${target_arch}")
set(NVCC_OPTION "-gencode;arch=compute_${target_arch_short},code=sm_${target_arch_short}")
execute_process( COMMAND "${CUDA_NVCC_EXECUTABLE}" ${NVCC_OPTION} "${OpenCV_SOURCE_DIR}/cmake/checks/OpenCVDetectCudaArch.cu"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
RESULT_VARIABLE _nvcc_res OUTPUT_VARIABLE _nvcc_out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
set(_cmd "${CUDA_NVCC_EXECUTABLE}" ${OPENCV_CUDA_DETECTION_NVCC_FLAGS} ${NVCC_OPTION} "${OpenCV_SOURCE_DIR}/cmake/checks/OpenCVDetectCudaArch.cu" --compile)
execute_process(
COMMAND ${_cmd}
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
RESULT_VARIABLE _nvcc_res
OUTPUT_VARIABLE _nvcc_out
ERROR_VARIABLE _nvcc_err
#ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(OPENCV_CMAKE_CUDA_DEBUG)
message(WARNING "COMMAND: ${_cmd}")
message(STATUS "Result: ${_nvcc_res}")
message(STATUS "Out: ${_nvcc_out}")
message(STATUS "Err: ${_nvcc_err}")
endif()
if(_nvcc_res EQUAL 0)
set(${result_list} "${${result_list}} ${target_arch}")
LIST(APPEND ${result_list} "${target_arch}")
endif()
endforeach()
string(STRIP ${${result_list}} ${result_list})
set(CUDA_SUPPORTED_CC ${${result_list}} CACHE INTERNAL "List of supported compute capability")
string(STRIP "${${result_list}}" ${result_list})
if(" ${${result_list}}" STREQUAL " ")
message(WARNING "CUDA: Autodetection arch list is empty. Please enable OPENCV_CMAKE_CUDA_DEBUG=1 and check/specify OPENCV_CUDA_DETECTION_NVCC_FLAGS variable")
endif()
# cache detected values
set(OPENCV_CACHE_CUDA_SUPPORTED_CC ${${result_list}} CACHE INTERNAL "")
set(OPENCV_CACHE_CUDA_SUPPORTED_CC_check "${__cache_key_check}" CACHE INTERNAL "")
endif()
endmacro()
macro(ocv_detect_native_cuda_arch status output)
execute_process( COMMAND "${CUDA_NVCC_EXECUTABLE}" ${CUDA_NVCC_FLAGS} "${OpenCV_SOURCE_DIR}/cmake/checks/OpenCVDetectCudaArch.cu" "--run"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
RESULT_VARIABLE ${status} OUTPUT_VARIABLE ${output}
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
set(OPENCV_CUDA_DETECT_ARCHS_COMMAND "${CUDA_NVCC_EXECUTABLE}" ${OPENCV_CUDA_DETECTION_NVCC_FLAGS} "${OpenCV_SOURCE_DIR}/cmake/checks/OpenCVDetectCudaArch.cu" "--run")
set(__cache_key_check "${OPENCV_CUDA_DETECT_ARCHS_COMMAND}")
if(DEFINED OPENCV_CACHE_CUDA_ACTIVE_CC AND OPENCV_CACHE_CUDA_ACTIVE_CC_check STREQUAL __cache_key_check)
set(${output} "${OPENCV_CACHE_CUDA_ACTIVE_CC}")
set(${status} 0)
else()
execute_process(
COMMAND ${OPENCV_CUDA_DETECT_ARCHS_COMMAND}
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
RESULT_VARIABLE ${status}
OUTPUT_VARIABLE _nvcc_out
ERROR_VARIABLE _nvcc_err
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(OPENCV_CMAKE_CUDA_DEBUG)
message(WARNING "COMMAND: ${OPENCV_CUDA_DETECT_ARCHS_COMMAND}")
message(STATUS "Result: ${${status}}")
message(STATUS "Out: ${_nvcc_out}")
message(STATUS "Err: ${_nvcc_err}")
endif()
string(REGEX REPLACE ".*\n" "" ${output} "${_nvcc_out}") #Strip leading warning messages, if any
if(${status} EQUAL 0)
# cache detected values
set(OPENCV_CACHE_CUDA_ACTIVE_CC ${${result_list}} CACHE INTERNAL "")
set(OPENCV_CACHE_CUDA_ACTIVE_CC_check "${__cache_key_check}" CACHE INTERNAL "")
endif()
endif()
endmacro()
macro(ocv_wipeout_deprecated _arch_bin_list)
string(REPLACE "2.1" "2.1(2.0)" ${_arch_bin_list} ${${_arch_bin_list}})
string(REPLACE "2.1" "2.1(2.0)" ${_arch_bin_list} "${${_arch_bin_list}}")
endmacro()
set(__cuda_arch_ptx "")
@@ -121,6 +216,8 @@ if(CUDA_FOUND)
set(__cuda_arch_bin ${_arch_volta})
elseif(CUDA_GENERATION STREQUAL "Turing")
set(__cuda_arch_bin ${_arch_turing})
elseif(CUDA_GENERATION STREQUAL "Ampere")
set(__cuda_arch_bin ${_arch_ampere})
elseif(CUDA_GENERATION STREQUAL "Auto")
ocv_detect_native_cuda_arch(_nvcc_res _nvcc_out)
if(NOT _nvcc_res EQUAL 0)
@@ -128,6 +225,9 @@ if(CUDA_FOUND)
else()
string(REGEX MATCHALL "[0-9]+\\.[0-9]" __cuda_arch_bin "${_nvcc_out}")
endif()
elseif(CUDA_ARCH_BIN)
message(STATUS "CUDA: Using CUDA_ARCH_BIN=${CUDA_ARCH_BIN}")
set(__cuda_arch_bin ${CUDA_ARCH_BIN})
endif()
if(NOT DEFINED __cuda_arch_bin)
@@ -135,10 +235,20 @@ if(CUDA_FOUND)
set(__cuda_arch_bin "3.2")
set(__cuda_arch_ptx "")
elseif(AARCH64)
ocv_detect_native_cuda_arch(_nvcc_res _nvcc_out)
if(NOT CMAKE_CROSSCOMPILING)
ocv_detect_native_cuda_arch(_nvcc_res _nvcc_out)
else()
set(_nvcc_res -1) # emulate error, see below
endif()
if(NOT _nvcc_res EQUAL 0)
message(STATUS "Automatic detection of CUDA generation failed. Going to build for all known architectures.")
set(__cuda_arch_bin "5.3 6.2 7.2")
# TX1 (5.3) TX2 (6.2) Xavier (7.2) V100 (7.0)
ocv_filter_available_architecture(__cuda_arch_bin
5.3
6.2
7.2
7.0
)
else()
set(__cuda_arch_bin "${_nvcc_out}")
endif()
@@ -151,6 +261,7 @@ if(CUDA_FOUND)
${_arch_pascal}
${_arch_volta}
${_arch_turing}
${_arch_ampere}
)
endif()
endif()
@@ -162,11 +273,9 @@ if(CUDA_FOUND)
string(REGEX REPLACE "\\." "" ARCH_BIN_NO_POINTS "${CUDA_ARCH_BIN}")
string(REGEX REPLACE "\\." "" ARCH_PTX_NO_POINTS "${CUDA_ARCH_PTX}")
# Ckeck if user specified 1.0 compute capability: we don't support it
string(REGEX MATCH "1.0" HAS_ARCH_10 "${CUDA_ARCH_BIN} ${CUDA_ARCH_PTX}")
set(CUDA_ARCH_BIN_OR_PTX_10 0)
if(NOT ${HAS_ARCH_10} STREQUAL "")
set(CUDA_ARCH_BIN_OR_PTX_10 1)
# Check if user specified 1.0 compute capability: we don't support it
if(" ${CUDA_ARCH_BIN} ${CUDA_ARCH_PTX}" MATCHES " 1.0")
message(SEND_ERROR "CUDA: 1.0 compute capability is not supported - exclude it from ARCH/PTX list are re-run CMake")
endif()
# NVCC flags to be set
@@ -277,6 +386,16 @@ if(CUDA_FOUND)
if(UNIX OR APPLE)
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -fPIC)
if(
ENABLE_CXX11
AND NOT " ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_DEBUG} ${CUDA_NVCC_FLAGS}" MATCHES "-std="
)
if(CUDA_VERSION VERSION_LESS "11.0")
list(APPEND CUDA_NVCC_FLAGS "--std=c++11")
else()
list(APPEND CUDA_NVCC_FLAGS "--std=c++14")
endif()
endif()
endif()
if(APPLE)
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -fno-finite-math-only)
@@ -340,4 +459,57 @@ if(HAVE_CUDA)
set(CUDA_cufft_LIBRARY_ABS ${CUDA_cufft_LIBRARY})
ocv_convert_to_lib_name(CUDA_cufft_LIBRARY ${CUDA_cufft_LIBRARY})
endif()
if(CMAKE_GENERATOR MATCHES "Visual Studio"
AND NOT OPENCV_SKIP_CUDA_CMAKE_SUPPRESS_REGENERATION
)
message(STATUS "CUDA: MSVS generator is detected. Disabling CMake re-run checks (CMAKE_SUPPRESS_REGENERATION=ON). You need to run CMake manually if updates are required.")
set(CMAKE_SUPPRESS_REGENERATION ON)
endif()
endif()
# ----------------------------------------------------------------------------
# Add CUDA libraries (needed for apps/tools, samples)
# ----------------------------------------------------------------------------
if(HAVE_CUDA)
# details: https://github.com/NVIDIA/nvidia-docker/issues/775
if(" ${CUDA_CUDA_LIBRARY}" MATCHES "/stubs/libcuda.so" AND NOT OPENCV_SKIP_CUDA_STUB_WORKAROUND)
set(CUDA_STUB_ENABLED_LINK_WORKAROUND 1)
if(EXISTS "${CUDA_CUDA_LIBRARY}" AND NOT OPENCV_SKIP_CUDA_STUB_WORKAROUND_RPATH_LINK)
set(CUDA_STUB_TARGET_PATH "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/")
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CUDA_CUDA_LIBRARY}" "${CUDA_STUB_TARGET_PATH}/libcuda.so.1"
RESULT_VARIABLE CUDA_STUB_SYMLINK_RESULT)
if(NOT CUDA_STUB_SYMLINK_RESULT EQUAL 0)
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CUDA_CUDA_LIBRARY}" "${CUDA_STUB_TARGET_PATH}/libcuda.so.1"
RESULT_VARIABLE CUDA_STUB_COPY_RESULT)
if(NOT CUDA_STUB_COPY_RESULT EQUAL 0)
set(CUDA_STUB_ENABLED_LINK_WORKAROUND 0)
endif()
endif()
if(CUDA_STUB_ENABLED_LINK_WORKAROUND)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath-link,\"${CUDA_STUB_TARGET_PATH}\"")
endif()
else()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-shlib-undefined")
endif()
if(NOT CUDA_STUB_ENABLED_LINK_WORKAROUND)
message(WARNING "CUDA: workaround for stubs/libcuda.so.1 is not applied")
endif()
endif()
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
if(HAVE_CUBLAS)
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cublas_LIBRARY})
endif()
if(HAVE_CUFFT)
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cufft_LIBRARY})
endif()
foreach(p ${CUDA_LIBS_PATH})
if(MSVC AND CMAKE_GENERATOR MATCHES "Ninja|JOM")
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CMAKE_LIBRARY_PATH_FLAG}"${p}")
else()
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CMAKE_LIBRARY_PATH_FLAG}${p})
endif()
endforeach()
endif()
+2 -2
View File
@@ -135,9 +135,9 @@ endif()
if(INF_ENGINE_TARGET)
if(NOT INF_ENGINE_RELEASE)
message(WARNING "InferenceEngine version has not been set, 2020.2 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
message(WARNING "InferenceEngine version has not been set, 2020.4 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
endif()
set(INF_ENGINE_RELEASE "2020020000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2020.1.0.2 -> 2020010002)")
set(INF_ENGINE_RELEASE "2020040000" 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}"
)
+13 -7
View File
@@ -79,9 +79,10 @@ get_mkl_version(${MKL_INCLUDE_DIRS}/mkl_version.h)
#determine arch
if(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
set(MKL_X64 1)
set(MKL_ARCH "intel64")
set(MKL_ARCH_LIST "intel64")
if(MSVC)
list(APPEND MKL_ARCH_LIST "win-x64")
endif()
include(CheckTypeSize)
CHECK_TYPE_SIZE(int _sizeof_int)
if (_sizeof_int EQUAL 4)
@@ -90,14 +91,19 @@ if(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
set(MKL_ARCH_SUFFIX "ilp64")
endif()
else()
set(MKL_ARCH "ia32")
set(MKL_ARCH_LIST "ia32")
set(MKL_ARCH_SUFFIX "c")
endif()
if(MKL_VERSION_STR VERSION_GREATER "11.3.0" OR MKL_VERSION_STR VERSION_EQUAL "11.3.0")
set(mkl_lib_find_paths
${MKL_ROOT_DIR}/lib
${MKL_ROOT_DIR}/lib/${MKL_ARCH} ${MKL_ROOT_DIR}/../tbb/lib/${MKL_ARCH})
${MKL_ROOT_DIR}/lib)
foreach(MKL_ARCH ${MKL_ARCH_LIST})
list(APPEND mkl_lib_find_paths
${MKL_ROOT_DIR}/lib/${MKL_ARCH}
${MKL_ROOT_DIR}/../tbb/lib/${MKL_ARCH}
${MKL_ROOT_DIR}/${MKL_ARCH})
endforeach()
set(mkl_lib_list "mkl_intel_${MKL_ARCH_SUFFIX}")
@@ -121,7 +127,7 @@ endif()
set(MKL_LIBRARIES "")
foreach(lib ${mkl_lib_list})
find_library(${lib} ${lib} ${mkl_lib_find_paths})
find_library(${lib} NAMES ${lib} ${lib}_dll HINTS ${mkl_lib_find_paths})
mark_as_advanced(${lib})
if(NOT ${lib})
mkl_fail()
+2 -1
View File
@@ -46,6 +46,7 @@
SET(Open_BLAS_INCLUDE_SEARCH_PATHS
$ENV{OpenBLAS_HOME}
$ENV{OpenBLAS_HOME}/include
$ENV{OpenBLAS_HOME}/include/openblas
/opt/OpenBLAS/include
/usr/local/include/openblas
/usr/include/openblas
@@ -103,4 +104,4 @@ MARK_AS_ADVANCED(
OpenBLAS_INCLUDE_DIR
OpenBLAS_LIB
OpenBLAS
)
)
+1 -1
View File
@@ -88,7 +88,7 @@ FOREACH(SEARCH_PATH ${SEARCH_PATHS})
ocv_find_openexr("-${OPENEXR_VERSION}")
ocv_find_openexr("-${OPENEXR_VERSION}_s")
ocv_find_openexr("-${OPENEXR_VERSION}_d")
ocv_find_openexr("-${OPEXEXR_VERSION}_s_d")
ocv_find_openexr("-${OPENEXR_VERSION}_s_d")
ocv_find_openexr("")
ocv_find_openexr("_s")
ocv_find_openexr("_d")
+2 -3
View File
@@ -13,9 +13,6 @@
/* Compile for 'real' NVIDIA GPU architectures */
#define CUDA_ARCH_BIN "${OPENCV_CUDA_ARCH_BIN}"
/* Create PTX or BIN for 1.0 compute capability */
#cmakedefine CUDA_ARCH_BIN_OR_PTX_10
/* NVIDIA GPU features are used */
#define CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES}"
@@ -127,6 +124,8 @@
/* NVIDIA Video Decoding API*/
#cmakedefine HAVE_NVCUVID
#cmakedefine HAVE_NVCUVID_HEADER
#cmakedefine HAVE_DYNLINK_NVCUVID_HEADER
/* NVIDIA Video Encoding API*/
#cmakedefine HAVE_NVCUVENC
+2 -1
View File
@@ -346,7 +346,8 @@
year = {2003},
pages = {363--370},
publisher = {Springer},
url = {https://arxiv.org/pdf/1808.01752}
url = {https://doi.org/10.1007/3-540-45103-X_50},
doi = {10.1007/3-540-45103-X_50}
}
@inproceedings{Farsiu03,
author = {Farsiu, Sina and Robinson, Dirk and Elad, Michael and Milanfar, Peyman},
@@ -30,7 +30,7 @@ Installing CMake
-# Install the dmg package and launch it from Applications. That will give you the UI app of CMake
-# From the CMake app window, choose menu Tools --> Install For Command Line Use.
-# From the CMake app window, choose menu Tools --> How to Install For Command Line Use. Then, follow the instructions from the pop-up there.
-# Install folder will be /usr/bin/ by default, submit it by choosing Install command line links.
@@ -66,7 +66,7 @@ git clone https://github.com/opencv/opencv_contrib.git
Building OpenCV from Source Using CMake
---------------------------------------
-# Create a temporary directory, which we denote as `<cmake_build_dir>`, where you want to put
-# Create a temporary directory, which we denote as `build_opencv`, where you want to put
the generated Makefiles, project files as well the object files and output binaries and enter
there.
@@ -87,8 +87,8 @@ Building OpenCV from Source Using CMake
or cmake-gui
- set full path to OpenCV source code, e.g. `/home/user/opencv`
- set full path to `<cmake_build_dir>`, e.g. `/home/user/build_opencv`
- set the OpenCV source code path to, e.g. `/home/user/opencv`
- set the binary build path to your CMake build directory, e.g. `/home/user/build_opencv`
- set optional parameters
- run: "Configure"
- run: "Generate"
@@ -101,6 +101,20 @@ namespace cv { namespace cuda
cudaChannelFormatDesc desc = cudaCreateChannelDesc<T>();
cudaSafeCall( cudaBindTexture2D(0, tex, img.ptr(), &desc, img.cols, img.rows, img.step) );
}
template<class T> inline void createTextureObjectPitch2D(cudaTextureObject_t* tex, PtrStepSz<T>& img, const cudaTextureDesc& texDesc)
{
cudaResourceDesc resDesc;
memset(&resDesc, 0, sizeof(resDesc));
resDesc.resType = cudaResourceTypePitch2D;
resDesc.res.pitch2D.devPtr = static_cast<void*>(img.ptr());
resDesc.res.pitch2D.height = img.rows;
resDesc.res.pitch2D.width = img.cols;
resDesc.res.pitch2D.pitchInBytes = img.step;
resDesc.res.pitch2D.desc = cudaCreateChannelDesc<T>();
cudaSafeCall( cudaCreateTextureObject(tex, &resDesc, &texDesc, NULL) );
}
}
}}
@@ -106,8 +106,8 @@ namespace cv
size_t step;
__CV_CUDA_HOST_DEVICE__ T* ptr(int y = 0) { return ( T*)( ( char*)DevPtr<T>::data + y * step); }
__CV_CUDA_HOST_DEVICE__ const T* ptr(int y = 0) const { return (const T*)( (const char*)DevPtr<T>::data + y * step); }
__CV_CUDA_HOST_DEVICE__ T* ptr(int y = 0) { return ( T*)( ( char*)(((DevPtr<T>*)this)->data) + y * step); }
__CV_CUDA_HOST_DEVICE__ const T* ptr(int y = 0) const { return (const T*)( (const char*)(((DevPtr<T>*)this)->data) + y * step); }
__CV_CUDA_HOST_DEVICE__ T& operator ()(int y, int x) { return ptr(y)[x]; }
__CV_CUDA_HOST_DEVICE__ const T& operator ()(int y, int x) const { return ptr(y)[x]; }
+14 -2
View File
@@ -86,12 +86,24 @@ namespace cv { namespace debug_build_guard { } using namespace debug_build_guard
#define __CV_VA_NUM_ARGS_HELPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
#define __CV_VA_NUM_ARGS(...) __CV_VA_NUM_ARGS_HELPER(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#if defined __GNUC__
#ifdef CV_Func
// keep current value (through OpenCV port file)
#elif defined __GNUC__ || (defined (__cpluscplus) && (__cpluscplus >= 201103))
#define CV_Func __func__
#elif defined __clang__ && (__clang_minor__ * 100 + __clang_major >= 305)
#define CV_Func __func__
#elif defined(__STDC_VERSION__) && (__STDC_VERSION >= 199901)
#define CV_Func __func__
#elif defined _MSC_VER
#define CV_Func __FUNCTION__
#elif defined(__INTEL_COMPILER) && (_INTEL_COMPILER >= 600)
#define CV_Func __FUNCTION__
#elif defined __IBMCPP__ && __IBMCPP__ >=500
#define CV_Func __FUNCTION__
#elif defined __BORLAND__ && (__BORLANDC__ >= 0x550)
#define CV_Func __FUNC__
#else
#define CV_Func ""
#define CV_Func "<unknown>"
#endif
//! @cond IGNORED
+17 -8
View File
@@ -51,25 +51,34 @@
#include "opencv2/core.hpp"
#if defined _MSC_VER && _MSC_VER >= 1200
#define NOMINMAX // fix https://github.com/opencv/opencv/issues/17548
#pragma warning( disable: 4714 ) //__forceinline is not inlined
#pragma warning( disable: 4127 ) //conditional expression is constant
#pragma warning( disable: 4244 ) //conversion from '__int64' to 'int', possible loss of data
#endif
#if EIGEN_WORLD_VERSION == 3 && EIGEN_MAJOR_VERSION >= 3 \
&& defined(CV_CXX11) && defined(CV_CXX_STD_ARRAY)
#include <unsupported/Eigen/CXX11/Tensor>
#define OPENCV_EIGEN_TENSOR_SUPPORT
#endif // EIGEN_WORLD_VERSION == 3 && EIGEN_MAJOR_VERSION >= 3
#if defined _MSC_VER && _MSC_VER >= 1200
#pragma warning( disable: 4714 ) //__forceinline is not inlined
#pragma warning( disable: 4127 ) //conditional expression is constant
#pragma warning( disable: 4244 ) //conversion from '__int64' to 'int', possible loss of data
#endif
namespace cv
{
//! @addtogroup core_eigen
/** @addtogroup core_eigen
These functions are provided for OpenCV-Eigen interoperability. They convert `Mat`
objects to corresponding `Eigen::Matrix` objects and vice-versa. Consult the [Eigen
documentation](https://eigen.tuxfamily.org/dox/group__TutorialMatrixClass.html) for
information about the `Matrix` template type.
@note Using these functions requires the `Eigen/Dense` or similar header to be
included before this header.
*/
//! @{
#ifdef OPENCV_EIGEN_TENSOR_SUPPORT
#if defined(OPENCV_EIGEN_TENSOR_SUPPORT) || defined(CV_DOXYGEN)
/** @brief Converts an Eigen::Tensor to a cv::Mat.
The method converts an Eigen::Tensor with shape (H x W x C) to a cv::Mat where:
@@ -82,9 +82,6 @@
# error "Insufficient Cuda Runtime library version, please update it."
# endif
# if defined(CUDA_ARCH_BIN_OR_PTX_10)
# error "OpenCV CUDA module doesn't support NVIDIA compute capability 1.0"
# endif
#endif
//! @cond IGNORED
@@ -8,7 +8,7 @@
#define CV_VERSION_MAJOR 3
#define CV_VERSION_MINOR 4
#define CV_VERSION_REVISION 11
#define CV_VERSION_STATUS "-pre"
#define CV_VERSION_STATUS ""
#define CVAUX_STR_EXP(__A) #__A
#define CVAUX_STR(__A) CVAUX_STR_EXP(__A)
+80 -14
View File
@@ -25,9 +25,26 @@ String dumpInputArray(InputArray argument)
break; // done
}
ss << cv::format(" total(-1)=%lld", (long long int)argument.total(-1));
ss << cv::format(" dims(-1)=%d", argument.dims(-1));
Size size = argument.size(-1);
ss << cv::format(" size(-1)=%dx%d", size.width, size.height);
int dims = argument.dims(-1);
ss << cv::format(" dims(-1)=%d", dims);
if (dims <= 2)
{
Size size = argument.size(-1);
ss << cv::format(" size(-1)=%dx%d", size.width, size.height);
}
else
{
int sz[CV_MAX_DIM] = {0};
argument.sizend(sz, -1);
ss << " size(-1)=[";
for (int i = 0; i < dims; i++)
{
if (i > 0)
ss << ' ';
ss << sz[i];
}
ss << "]";
}
ss << " type(-1)=" << cv::typeToString(argument.type(-1));
} while (0);
}
@@ -61,10 +78,26 @@ CV_EXPORTS_W String dumpInputArrayOfArrays(InputArrayOfArrays argument)
if (argument.total(-1) > 0)
{
ss << " type(0)=" << cv::typeToString(argument.type(0));
ss << cv::format(" dims(0)=%d", argument.dims(0));
size = argument.size(0);
ss << cv::format(" size(0)=%dx%d", size.width, size.height);
ss << " type(0)=" << cv::typeToString(argument.type(0));
int dims = argument.dims(0);
ss << cv::format(" dims(0)=%d", dims);
if (dims <= 2)
{
Size size0 = argument.size(0);
ss << cv::format(" size(0)=%dx%d", size0.width, size0.height);
}
else
{
int sz[CV_MAX_DIM] = {0};
argument.sizend(sz, 0);
ss << " size(0)=[";
for (int i = 0; i < dims; i++)
{
if (i > 0)
ss << ' ';
ss << sz[i];
}
ss << "]";
}
}
} while (0);
}
@@ -92,9 +125,26 @@ CV_EXPORTS_W String dumpInputOutputArray(InputOutputArray argument)
break; // done
}
ss << cv::format(" total(-1)=%lld", (long long int)argument.total(-1));
ss << cv::format(" dims(-1)=%d", argument.dims(-1));
Size size = argument.size(-1);
ss << cv::format(" size(-1)=%dx%d", size.width, size.height);
int dims = argument.dims(-1);
ss << cv::format(" dims(-1)=%d", dims);
if (dims <= 2)
{
Size size = argument.size(-1);
ss << cv::format(" size(-1)=%dx%d", size.width, size.height);
}
else
{
int sz[CV_MAX_DIM] = {0};
argument.sizend(sz, -1);
ss << " size(-1)=[";
for (int i = 0; i < dims; i++)
{
if (i > 0)
ss << ' ';
ss << sz[i];
}
ss << "]";
}
ss << " type(-1)=" << cv::typeToString(argument.type(-1));
} while (0);
}
@@ -128,10 +178,26 @@ CV_EXPORTS_W String dumpInputOutputArrayOfArrays(InputOutputArrayOfArrays argume
if (argument.total(-1) > 0)
{
ss << " type(0)=" << cv::typeToString(argument.type(0));
ss << cv::format(" dims(0)=%d", argument.dims(0));
size = argument.size(0);
ss << cv::format(" size(0)=%dx%d", size.width, size.height);
ss << " type(0)=" << cv::typeToString(argument.type(0));
int dims = argument.dims(0);
ss << cv::format(" dims(0)=%d", dims);
if (dims <= 2)
{
Size size0 = argument.size(0);
ss << cv::format(" size(0)=%dx%d", size0.width, size0.height);
}
else
{
int sz[CV_MAX_DIM] = {0};
argument.sizend(sz, 0);
ss << " size(0)=[";
for (int i = 0; i < dims; i++)
{
if (i > 0)
ss << ' ';
ss << sz[i];
}
ss << "]";
}
}
} while (0);
}
+7 -3
View File
@@ -72,9 +72,13 @@ static int64 getTimestamp()
return (int64)((t - g_zero_timestamp) * tick_to_ns);
}
// TODO lazy configuration flags
static bool param_traceEnable = utils::getConfigurationParameterBool("OPENCV_TRACE", false);
static bool getParameterTraceEnable()
{
static bool param_traceEnable = utils::getConfigurationParameterBool("OPENCV_TRACE", false);
return param_traceEnable;
}
// TODO lazy configuration flags
static int param_maxRegionDepthOpenCV = (int)utils::getConfigurationParameterSizeT("OPENCV_TRACE_DEPTH_OPENCV", 1);
static int param_maxRegionChildrenOpenCV = (int)utils::getConfigurationParameterSizeT("OPENCV_TRACE_MAX_CHILDREN_OPENCV", 1000);
static int param_maxRegionChildren = (int)utils::getConfigurationParameterSizeT("OPENCV_TRACE_MAX_CHILDREN", 10000);
@@ -841,7 +845,7 @@ TraceManager::TraceManager()
CV_LOG("TraceManager ctor: " << (void*)this);
CV_LOG("TraceManager configure()");
activated = param_traceEnable;
activated = getParameterTraceEnable();
if (activated)
trace_storage.reset(new SyncTraceStorage(std::string(param_traceLocation) + ".txt"));
+1 -9
View File
@@ -44,17 +44,9 @@
#ifndef __CUVID_VIDEO_SOURCE_HPP__
#define __CUVID_VIDEO_SOURCE_HPP__
#if CUDA_VERSION >= 9000 && CUDA_VERSION < 10000
#include <dynlink_nvcuvid.h>
#else
#include <nvcuvid.h>
#endif
#include "opencv2/core/private.cuda.hpp"
#include "opencv2/cudacodec.hpp"
#include "video_source.hpp"
namespace cv { namespace cudacodec { namespace detail
{
namespace cv { namespace cudacodec { namespace detail {
class CuvidVideoSource : public VideoSource
{
+1 -9
View File
@@ -45,16 +45,8 @@
#define __FRAME_QUEUE_HPP__
#include "opencv2/core/utility.hpp"
#include "opencv2/core/private.cuda.hpp"
#if CUDA_VERSION >= 9000 && CUDA_VERSION < 10000
#include <dynlink_nvcuvid.h>
#else
#include <nvcuvid.h>
#endif
namespace cv { namespace cudacodec { namespace detail
{
namespace cv { namespace cudacodec { namespace detail {
class FrameQueue
{
+2 -2
View File
@@ -56,9 +56,9 @@
#include "opencv2/core/private.cuda.hpp"
#ifdef HAVE_NVCUVID
#if CUDA_VERSION >= 9000 && CUDA_VERSION < 10000
#if defined(HAVE_DYNLINK_NVCUVID_HEADER)
#include <dynlink_nvcuvid.h>
#else
#elif defined(HAVE_NVCUVID_HEADER)
#include <nvcuvid.h>
#endif
+1 -11
View File
@@ -44,17 +44,7 @@
#ifndef __VIDEO_DECODER_HPP__
#define __VIDEO_DECODER_HPP__
#if CUDA_VERSION >= 9000 && CUDA_VERSION < 10000
#include <dynlink_nvcuvid.h>
#else
#include <nvcuvid.h>
#endif
#include "opencv2/core/private.cuda.hpp"
#include "opencv2/cudacodec.hpp"
namespace cv { namespace cudacodec { namespace detail
{
namespace cv { namespace cudacodec { namespace detail {
class VideoDecoder
{
+1 -10
View File
@@ -44,19 +44,10 @@
#ifndef __VIDEO_PARSER_HPP__
#define __VIDEO_PARSER_HPP__
#if CUDA_VERSION >= 9000 && CUDA_VERSION < 10000
#include <dynlink_nvcuvid.h>
#else
#include <nvcuvid.h>
#endif
#include "opencv2/core/private.cuda.hpp"
#include "opencv2/cudacodec.hpp"
#include "frame_queue.hpp"
#include "video_decoder.hpp"
namespace cv { namespace cudacodec { namespace detail
{
namespace cv { namespace cudacodec { namespace detail {
class VideoParser
{
+1 -4
View File
@@ -44,12 +44,9 @@
#ifndef __CUDACODEC_VIDEO_SOURCE_H__
#define __CUDACODEC_VIDEO_SOURCE_H__
#include "opencv2/core/private.cuda.hpp"
#include "opencv2/cudacodec.hpp"
#include "thread.hpp"
namespace cv { namespace cudacodec { namespace detail
{
namespace cv { namespace cudacodec { namespace detail {
class VideoParser;
+23 -39
View File
@@ -90,12 +90,22 @@ namespace cv { namespace cuda { namespace device
namespace canny
{
texture<uchar, cudaTextureType2D, cudaReadModeElementType> tex_src(false, cudaFilterModePoint, cudaAddressModeClamp);
struct SrcTex
{
virtual ~SrcTex() {}
__host__ SrcTex(int _xoff, int _yoff) : xoff(_xoff), yoff(_yoff) {}
__device__ __forceinline__ virtual int operator ()(int y, int x) const = 0;
int xoff;
int yoff;
__host__ SrcTex(int _xoff, int _yoff) : xoff(_xoff), yoff(_yoff) {}
};
texture<uchar, cudaTextureType2D, cudaReadModeElementType> tex_src(false, cudaFilterModePoint, cudaAddressModeClamp);
struct SrcTexRef : SrcTex
{
__host__ SrcTexRef(int _xoff, int _yoff) : SrcTex(_xoff, _yoff) {}
__device__ __forceinline__ int operator ()(int y, int x) const
{
@@ -103,40 +113,23 @@ namespace canny
}
};
struct SrcTexObject
struct SrcTexObj : SrcTex
{
int xoff;
int yoff;
cudaTextureObject_t tex_src_object;
__host__ SrcTexObject(int _xoff, int _yoff, cudaTextureObject_t _tex_src_object) : xoff(_xoff), yoff(_yoff), tex_src_object(_tex_src_object) { }
__host__ SrcTexObj(int _xoff, int _yoff, cudaTextureObject_t _tex_src_object) : SrcTex(_xoff, _yoff), tex_src_object(_tex_src_object) { }
__device__ __forceinline__ int operator ()(int y, int x) const
{
return tex2D<uchar>(tex_src_object, x + xoff, y + yoff);
}
cudaTextureObject_t tex_src_object;
};
template <class Norm> __global__
void calcMagnitudeKernel(const SrcTex src, PtrStepi dx, PtrStepi dy, PtrStepSzf mag, const Norm norm)
{
const int x = blockIdx.x * blockDim.x + threadIdx.x;
const int y = blockIdx.y * blockDim.y + threadIdx.y;
if (y >= mag.rows || x >= mag.cols)
return;
int dxVal = (src(y - 1, x + 1) + 2 * src(y, x + 1) + src(y + 1, x + 1)) - (src(y - 1, x - 1) + 2 * src(y, x - 1) + src(y + 1, x - 1));
int dyVal = (src(y + 1, x - 1) + 2 * src(y + 1, x) + src(y + 1, x + 1)) - (src(y - 1, x - 1) + 2 * src(y - 1, x) + src(y - 1, x + 1));
dx(y, x) = dxVal;
dy(y, x) = dyVal;
mag(y, x) = norm(dxVal, dyVal);
}
template <class Norm> __global__
void calcMagnitudeKernel(const SrcTexObject src, PtrStepi dx, PtrStepi dy, PtrStepSzf mag, const Norm norm)
template <
class T,
class Norm
>
__global__ void calcMagnitudeKernel(const T src, PtrStepi dx, PtrStepi dy, PtrStepSzf mag, const Norm norm)
{
const int x = blockIdx.x * blockDim.x + threadIdx.x;
const int y = blockIdx.y * blockDim.y + threadIdx.y;
@@ -162,15 +155,6 @@ namespace canny
if (cc30)
{
cudaResourceDesc resDesc;
memset(&resDesc, 0, sizeof(resDesc));
resDesc.resType = cudaResourceTypePitch2D;
resDesc.res.pitch2D.devPtr = srcWhole.ptr();
resDesc.res.pitch2D.height = srcWhole.rows;
resDesc.res.pitch2D.width = srcWhole.cols;
resDesc.res.pitch2D.pitchInBytes = srcWhole.step;
resDesc.res.pitch2D.desc = cudaCreateChannelDesc<uchar>();
cudaTextureDesc texDesc;
memset(&texDesc, 0, sizeof(texDesc));
texDesc.addressMode[0] = cudaAddressModeClamp;
@@ -178,9 +162,9 @@ namespace canny
texDesc.addressMode[2] = cudaAddressModeClamp;
cudaTextureObject_t tex = 0;
cudaCreateTextureObject(&tex, &resDesc, &texDesc, NULL);
createTextureObjectPitch2D(&tex, srcWhole, texDesc);
SrcTexObject src(xoff, yoff, tex);
SrcTexObj src(xoff, yoff, tex);
if (L2Grad)
{
@@ -205,7 +189,7 @@ namespace canny
else
{
bindTexture(&tex_src, srcWhole);
SrcTex src(xoff, yoff);
SrcTexRef src(xoff, yoff);
if (L2Grad)
{
+1 -1
View File
@@ -116,7 +116,7 @@ protected:
bool useL2gradient;
};
#define NUM_STREAMS 64
#define NUM_STREAMS 128
CUDA_TEST_P(Canny, Async)
{
+95 -11
View File
@@ -45,6 +45,7 @@
#include "opencv2/core/cuda/common.hpp"
#include "opencv2/core/cuda/border_interpolate.hpp"
#include "opencv2/core/cuda/limits.hpp"
#include "opencv2/core/cuda.hpp"
using namespace cv::cuda;
using namespace cv::cuda::device;
@@ -101,11 +102,63 @@ namespace tvl1flow
}
}
struct SrcTex
{
virtual ~SrcTex() {}
__device__ __forceinline__ virtual float I1(float x, float y) const = 0;
__device__ __forceinline__ virtual float I1x(float x, float y) const = 0;
__device__ __forceinline__ virtual float I1y(float x, float y) const = 0;
};
texture<float, cudaTextureType2D, cudaReadModeElementType> tex_I1 (false, cudaFilterModePoint, cudaAddressModeClamp);
texture<float, cudaTextureType2D, cudaReadModeElementType> tex_I1x(false, cudaFilterModePoint, cudaAddressModeClamp);
texture<float, cudaTextureType2D, cudaReadModeElementType> tex_I1y(false, cudaFilterModePoint, cudaAddressModeClamp);
struct SrcTexRef : SrcTex
{
__device__ __forceinline__ float I1(float x, float y) const override
{
return tex2D(tex_I1, x, y);
}
__device__ __forceinline__ float I1x(float x, float y) const override
{
return tex2D(tex_I1x, x, y);
}
__device__ __forceinline__ float I1y(float x, float y) const override
{
return tex2D(tex_I1y, x, y);
}
};
__global__ void warpBackwardKernel(const PtrStepSzf I0, const PtrStepf u1, const PtrStepf u2, PtrStepf I1w, PtrStepf I1wx, PtrStepf I1wy, PtrStepf grad, PtrStepf rho)
struct SrcTexObj : SrcTex
{
__host__ SrcTexObj(cudaTextureObject_t tex_obj_I1_, cudaTextureObject_t tex_obj_I1x_, cudaTextureObject_t tex_obj_I1y_)
: tex_obj_I1(tex_obj_I1_), tex_obj_I1x(tex_obj_I1x_), tex_obj_I1y(tex_obj_I1y_) {}
__device__ __forceinline__ float I1(float x, float y) const override
{
return tex2D<float>(tex_obj_I1, x, y);
}
__device__ __forceinline__ float I1x(float x, float y) const override
{
return tex2D<float>(tex_obj_I1x, x, y);
}
__device__ __forceinline__ float I1y(float x, float y) const override
{
return tex2D<float>(tex_obj_I1y, x, y);
}
cudaTextureObject_t tex_obj_I1;
cudaTextureObject_t tex_obj_I1x;
cudaTextureObject_t tex_obj_I1y;
};
template <
typename T
>
__global__ void warpBackwardKernel(
const PtrStepSzf I0, const T src, const PtrStepf u1, const PtrStepf u2,
PtrStepf I1w, PtrStepf I1wx, PtrStepf I1wy, PtrStepf grad, PtrStepf rho)
{
const int x = blockIdx.x * blockDim.x + threadIdx.x;
const int y = blockIdx.y * blockDim.y + threadIdx.y;
@@ -136,9 +189,9 @@ namespace tvl1flow
{
const float w = bicubicCoeff(wx - cx) * bicubicCoeff(wy - cy);
sum += w * tex2D(tex_I1 , cx, cy);
sumx += w * tex2D(tex_I1x, cx, cy);
sumy += w * tex2D(tex_I1y, cx, cy);
sum += w * src.I1(cx, cy);
sumx += w * src.I1x(cx, cy);
sumy += w * src.I1y(cx, cy);
wsum += w;
}
@@ -173,15 +226,46 @@ namespace tvl1flow
const dim3 block(32, 8);
const dim3 grid(divUp(I0.cols, block.x), divUp(I0.rows, block.y));
bindTexture(&tex_I1 , I1);
bindTexture(&tex_I1x, I1x);
bindTexture(&tex_I1y, I1y);
bool cc30 = deviceSupports(FEATURE_SET_COMPUTE_30);
warpBackwardKernel<<<grid, block, 0, stream>>>(I0, u1, u2, I1w, I1wx, I1wy, grad, rho);
cudaSafeCall( cudaGetLastError() );
if (cc30)
{
cudaTextureDesc texDesc;
memset(&texDesc, 0, sizeof(texDesc));
texDesc.addressMode[0] = cudaAddressModeClamp;
texDesc.addressMode[1] = cudaAddressModeClamp;
texDesc.addressMode[2] = cudaAddressModeClamp;
if (!stream)
cudaSafeCall( cudaDeviceSynchronize() );
cudaTextureObject_t texObj_I1 = 0, texObj_I1x = 0, texObj_I1y = 0;
createTextureObjectPitch2D(&texObj_I1, I1, texDesc);
createTextureObjectPitch2D(&texObj_I1x, I1x, texDesc);
createTextureObjectPitch2D(&texObj_I1y, I1y, texDesc);
warpBackwardKernel << <grid, block, 0, stream >> > (I0, SrcTexObj(texObj_I1, texObj_I1x, texObj_I1y), u1, u2, I1w, I1wx, I1wy, grad, rho);
cudaSafeCall(cudaGetLastError());
if (!stream)
cudaSafeCall(cudaDeviceSynchronize());
else
cudaSafeCall(cudaStreamSynchronize(stream));
cudaSafeCall(cudaDestroyTextureObject(texObj_I1));
cudaSafeCall(cudaDestroyTextureObject(texObj_I1x));
cudaSafeCall(cudaDestroyTextureObject(texObj_I1y));
}
else
{
bindTexture(&tex_I1, I1);
bindTexture(&tex_I1x, I1x);
bindTexture(&tex_I1y, I1y);
warpBackwardKernel << <grid, block, 0, stream >> > (I0, SrcTexRef(), u1, u2, I1w, I1wx, I1wy, grad, rho);
cudaSafeCall(cudaGetLastError());
if (!stream)
cudaSafeCall(cudaDeviceSynchronize());
}
}
}
+62 -1
View File
@@ -405,10 +405,71 @@ CUDA_TEST_P(OpticalFlowDual_TVL1, Accuracy)
EXPECT_MAT_SIMILAR(flow, d_flow, 4e-3);
}
class TVL1AsyncParallelLoopBody : public cv::ParallelLoopBody
{
public:
TVL1AsyncParallelLoopBody(const cv::cuda::GpuMat& d_img1_, const cv::cuda::GpuMat& d_img2_, cv::cuda::GpuMat* d_flow_, int iterations_, double gamma_)
: d_img1(d_img1_), d_img2(d_img2_), d_flow(d_flow_), iterations(iterations_), gamma(gamma_) {}
~TVL1AsyncParallelLoopBody() {}
void operator()(const cv::Range& r) const
{
for (int i = r.start; i < r.end; i++) {
cv::cuda::Stream stream;
cv::Ptr<cv::cuda::OpticalFlowDual_TVL1> d_alg = cv::cuda::OpticalFlowDual_TVL1::create();
d_alg->setNumIterations(iterations);
d_alg->setGamma(gamma);
d_alg->calc(d_img1, d_img2, d_flow[i], stream);
stream.waitForCompletion();
}
}
protected:
const cv::cuda::GpuMat& d_img1;
const cv::cuda::GpuMat& d_img2;
cv::cuda::GpuMat* d_flow;
int iterations;
double gamma;
};
#define NUM_STREAMS 16
CUDA_TEST_P(OpticalFlowDual_TVL1, Async)
{
if (!supportFeature(devInfo, cv::cuda::FEATURE_SET_COMPUTE_30))
{
throw SkipTestException("CUDA device doesn't support texture objects");
}
else
{
cv::Mat frame0 = readImage("opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
ASSERT_FALSE(frame0.empty());
cv::Mat frame1 = readImage("opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE);
ASSERT_FALSE(frame1.empty());
const int iterations = 10;
// Synchronous call
cv::Ptr<cv::cuda::OpticalFlowDual_TVL1> d_alg =
cv::cuda::OpticalFlowDual_TVL1::create();
d_alg->setNumIterations(iterations);
d_alg->setGamma(gamma);
cv::cuda::GpuMat d_flow_gold;
d_alg->calc(loadMat(frame0), loadMat(frame1), d_flow_gold);
// Asynchronous call
cv::cuda::GpuMat d_flow[NUM_STREAMS];
cv::parallel_for_(cv::Range(0, NUM_STREAMS), TVL1AsyncParallelLoopBody(loadMat(frame0), loadMat(frame1), d_flow, iterations, gamma));
// Compare the results of synchronous call and asynchronous call
for (int i = 0; i < NUM_STREAMS; i++)
EXPECT_MAT_NEAR(d_flow_gold, d_flow[i], 0.0);
}
}
INSTANTIATE_TEST_CASE_P(CUDA_OptFlow, OpticalFlowDual_TVL1, testing::Combine(
ALL_DEVICES,
testing::Values(Gamma(0.0), Gamma(1.0))));
}} // namespace
#endif // HAVE_CUDA
+95
View File
@@ -0,0 +1,95 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
#include <opencv2/dnn/shape_utils.hpp>
namespace opencv_test {
struct Layer_Slice : public TestBaseWithParam<tuple<Backend, Target> >
{
template<int DIMS>
void test_slice(const int* inputShape, const int* begin, const int* end)
{
int backendId = get<0>(GetParam());
int targetId = get<1>(GetParam());
Mat input(DIMS, inputShape, CV_32FC1, Scalar::all(0));
for (int i = 0; i < (int)input.total(); ++i)
input.ptr<float>()[i] = (float)(i & 4095);
std::vector<Range> range(DIMS);
for (int i = 0; i < DIMS; ++i)
range[i] = Range(begin[i], end[i]);
Net net;
LayerParams lp;
lp.type = "Slice";
lp.name = "testLayer";
lp.set("begin", DictValue::arrayInt<int*>((int*)&begin[0], DIMS));
lp.set("end", DictValue::arrayInt<int*>((int*)&end[0], DIMS));
net.addLayerToPrev(lp.name, lp.type, lp);
// warmup
{
net.setInput(input);
net.setPreferableBackend(backendId);
net.setPreferableTarget(targetId);
Mat out = net.forward();
EXPECT_GT(cv::norm(out, NORM_INF), 0);
#if 0
//normAssert(out, input(range));
cout << input(range).clone().reshape(1, 1) << endl;
cout << out.reshape(1, 1) << endl;
#endif
}
TEST_CYCLE()
{
Mat res = net.forward();
}
SANITY_CHECK_NOTHING();
}
};
PERF_TEST_P_(Layer_Slice, YOLOv4_tiny_1)
{
const int inputShape[4] = {1, 64, 104, 104};
const int begin[] = {0, 32, 0, 0};
const int end[] = {1, 64, 104, 104};
test_slice<4>(inputShape, begin, end);
}
PERF_TEST_P_(Layer_Slice, YOLOv4_tiny_2)
{
const int inputShape[4] = {1, 128, 52, 52};
const int begin[] = {0, 64, 0, 0};
const int end[] = {1, 128, 52, 52};
test_slice<4>(inputShape, begin, end);
}
PERF_TEST_P_(Layer_Slice, YOLOv4_tiny_3)
{
const int inputShape[4] = {1, 256, 26, 26};
const int begin[] = {0, 128, 0, 0};
const int end[] = {1, 256, 26, 26};
test_slice<4>(inputShape, begin, end);
}
PERF_TEST_P_(Layer_Slice, FastNeuralStyle_eccv16)
{
const int inputShape[4] = {1, 128, 80, 100};
const int begin[] = {0, 0, 2, 2};
const int end[] = {1, 128, 76, 96};
test_slice<4>(inputShape, begin, end);
}
INSTANTIATE_TEST_CASE_P(/**/, Layer_Slice, dnnBackendsAndTargets(false, false));
} // namespace
+24
View File
@@ -196,6 +196,13 @@ PERF_TEST_P_(DNNTestNetwork, YOLOv3)
{
if (backend == DNN_BACKEND_HALIDE)
throw SkipTestException("");
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
throw SkipTestException("Test is disabled in OpenVINO 2020.4");
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
throw SkipTestException("Test is disabled in OpenVINO 2020.4");
#endif
Mat sample = imread(findDataFile("dnn/dog416.png"));
cvtColor(sample, sample, COLOR_BGR2RGB);
Mat inp;
@@ -209,6 +216,12 @@ PERF_TEST_P_(DNNTestNetwork, YOLOv4)
throw SkipTestException("");
if (target == DNN_TARGET_MYRIAD)
throw SkipTestException("");
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
throw SkipTestException("Test is disabled in OpenVINO 2020.4");
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
throw SkipTestException("Test is disabled in OpenVINO 2020.4");
#endif
Mat sample = imread(findDataFile("dnn/dog416.png"));
cvtColor(sample, sample, COLOR_BGR2RGB);
Mat inp;
@@ -216,6 +229,17 @@ PERF_TEST_P_(DNNTestNetwork, YOLOv4)
processNet("dnn/yolov4.weights", "dnn/yolov4.cfg", "", inp);
}
PERF_TEST_P_(DNNTestNetwork, YOLOv4_tiny)
{
if (backend == DNN_BACKEND_HALIDE)
throw SkipTestException("");
Mat sample = imread(findDataFile("dnn/dog416.png"));
cvtColor(sample, sample, COLOR_BGR2RGB);
Mat inp;
sample.convertTo(inp, CV_32FC3, 1.0f / 255, 0);
processNet("dnn/yolov4-tiny.weights", "dnn/yolov4-tiny.cfg", "", inp);
}
PERF_TEST_P_(DNNTestNetwork, EAST_text_detection)
{
if (backend == DNN_BACKEND_HALIDE)
+48 -4
View File
@@ -363,6 +363,28 @@ namespace cv {
fused_layer_names.push_back(last_layer);
}
void setSlice(int input_index, int split_size, int group_id)
{
int begin[] = {0, split_size * group_id, 0, 0};
cv::dnn::DictValue paramBegin = cv::dnn::DictValue::arrayInt(begin, 4);
int end[] = {-1, begin[1] + split_size, -1, -1};
cv::dnn::DictValue paramEnd = cv::dnn::DictValue::arrayInt(end, 4);
darknet::LayerParameter lp;
lp.layer_name = cv::format("slice_%d", layer_id);
lp.layer_type = "Slice";
lp.layerParams.set("begin", paramBegin);
lp.layerParams.set("end", paramEnd);
lp.bottom_indexes.push_back(fused_layer_names.at(input_index));
net->layers.push_back(lp);
layer_id++;
last_layer = lp.layer_name;
fused_layer_names.push_back(last_layer);
}
void setReorg(int stride)
{
cv::dnn::LayerParams reorg_params;
@@ -717,6 +739,7 @@ namespace cv {
{
std::string bottom_layers = getParam<std::string>(layer_params, "layers", "");
CV_Assert(!bottom_layers.empty());
int groups = getParam<int>(layer_params, "groups", 1);
std::vector<int> layers_vec = getNumbers<int>(bottom_layers);
tensor_shape[0] = 0;
@@ -725,10 +748,31 @@ namespace cv {
tensor_shape[0] += net->out_channels_vec[layers_vec[k]];
}
if (layers_vec.size() == 1)
setParams.setIdentity(layers_vec.at(0));
if (groups > 1)
{
int group_id = getParam<int>(layer_params, "group_id", 0);
tensor_shape[0] /= groups;
int split_size = tensor_shape[0] / layers_vec.size();
for (size_t k = 0; k < layers_vec.size(); ++k)
setParams.setSlice(layers_vec[k], split_size, group_id);
if (layers_vec.size() > 1)
{
// layer ids in layers_vec - inputs of Slice layers
// after adding offset to layers_vec: layer ids - ouputs of Slice layers
for (size_t k = 0; k < layers_vec.size(); ++k)
layers_vec[k] += layers_vec.size();
setParams.setConcat(layers_vec.size(), layers_vec.data());
}
}
else
setParams.setConcat(layers_vec.size(), layers_vec.data());
{
if (layers_vec.size() == 1)
setParams.setIdentity(layers_vec.at(0));
else
setParams.setConcat(layers_vec.size(), layers_vec.data());
}
}
else if (layer_type == "dropout" || layer_type == "cost")
{
@@ -797,7 +841,7 @@ namespace cv {
int classes = getParam<int>(layer_params, "classes", -1);
int num_of_anchors = getParam<int>(layer_params, "num", -1);
float thresh = getParam<float>(layer_params, "thresh", 0.2);
float nms_threshold = getParam<float>(layer_params, "nms_threshold", 0.4);
float nms_threshold = getParam<float>(layer_params, "nms_threshold", 0.0);
float scale_x_y = getParam<float>(layer_params, "scale_x_y", 1.0);
std::string anchors_values = getParam<std::string>(layer_params, "anchors", std::string());
+14 -7
View File
@@ -2023,6 +2023,7 @@ struct Net::Impl : public detail::NetImplBase
Ptr<BackendNode> inpNode = inpLd.backendNodes[preferableBackend];
if (!inpNode.empty()) {
Ptr<InfEngineNgraphNode> ieNode = inpNode.dynamicCast<InfEngineNgraphNode>();
CV_Assert(!ieNode.empty());
ieNode->net->setUnconnectedNodes(ieNode);
}
}
@@ -2067,6 +2068,7 @@ struct Net::Impl : public detail::NetImplBase
int cons_inp = cons->oid;
Ptr<NgraphBackendWrapper> inpWrapper = inpLd.outputBlobsWrappers[cons_inp].
dynamicCast<NgraphBackendWrapper>();
CV_Assert(!inpWrapper.empty());
auto iter = std::find(inputNames.begin(), inputNames.end(),
inpWrapper->dataPtr->getName());
if (iter == inputNames.end()) {
@@ -2111,7 +2113,7 @@ struct Net::Impl : public detail::NetImplBase
auto ieInpNode = inputNodes[i].dynamicCast<InfEngineNgraphNode>();
CV_Assert(oid < ieInpNode->node->get_output_size());
#if INF_ENGINE_VER_MAJOR_GT(2020030000)
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_3)
inputNodes[i] = Ptr<BackendNode>(new InfEngineNgraphNode(ieInpNode->node->get_output_as_single_output_node(oid)));
#else
inputNodes[i] = Ptr<BackendNode>(new InfEngineNgraphNode(ieInpNode->node->get_output_as_single_output_node(oid, false)));
@@ -2523,8 +2525,7 @@ struct Net::Impl : public detail::NetImplBase
// (and so we eliminate the concatenation layer, because the channels
// are concatenated implicitly).
Ptr<ConcatLayer> concatLayer = ld.layerInstance.dynamicCast<ConcatLayer>();
if( !concatLayer.empty() && concatLayer->axis == 1 && !concatLayer->padding &&
ld.outputBlobs.size() == 1 )
if( !concatLayer.empty() && !concatLayer->padding && ld.outputBlobs.size() == 1 )
{
Mat& output = ld.outputBlobs[0];
UMat umat_output;
@@ -2561,7 +2562,8 @@ struct Net::Impl : public detail::NetImplBase
// the concatenation optimization is applied with batch_size > 1.
// so, for now, we only apply this optimization in the most popular
// case batch_size == 1.
if( output.dims == 4 && output.size[0] == 1 )
int axis = clamp(concatLayer->axis, output.dims);
if( output.total(0, axis) == 1 )
{
size_t i, ninputs = ld.inputBlobsId.size();
std::vector<LayerPin> realinputs(ninputs);
@@ -2600,14 +2602,14 @@ struct Net::Impl : public detail::NetImplBase
OpenCLBackendWrapper::update(ld.outputBlobsWrappers, umats);
}
#endif
Range chrange[] = { Range::all(), Range::all(), Range::all(), Range::all() };
std::vector<Range> chrange(output.dims, Range::all());
int ofs = 0;
for( i = 0; i < ninputs; i++ )
{
LayerPin pin = realinputs[i];
LayerData* inp_i_data = &layers[pin.lid];
int channels_i = ld.inputBlobs[i]->size[1];
chrange[1] = Range(ofs, ofs + channels_i);
int channels_i = ld.inputBlobs[i]->size[axis];
chrange[axis] = Range(ofs, ofs + channels_i);
printf_(("\toutput %s(%d) to channels (%d, %d)\n", inp_i_data->layerInstance->name.c_str(),
pin.oid, ofs, ofs + channels_i));
ofs += channels_i;
@@ -3261,6 +3263,9 @@ Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNe
}
else
{
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4)
CV_Error(Error::StsNotImplemented, "This OpenCV version is built with Inference Engine which has dropped IR v7 support");
#else
CV_TRACE_REGION("legacy_cnn_layer");
try
{
@@ -3276,6 +3281,8 @@ Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNe
CV_LOG_DEBUG(NULL, "IE layer extraction failure: '" << name << "' - " << e.what());
return false;
}
#endif
}
};
-3
View File
@@ -63,9 +63,6 @@ int Subgraph::getInputNodeId(const Ptr<ImportGraphWrapper>& net,
{
CV_Assert(inpId < node->getNumInputs());
std::string name = node->getInputName(inpId);
// If operation produces several tensors, they are specified by index
// after ':' character. In example, "input:0".
name = name.substr(0, name.rfind(':'));
const int numNodes = net->getNumNodes();
for (int i = 0; i < numNodes; ++i)
{
+63 -9
View File
@@ -15,7 +15,6 @@
#ifdef HAVE_DNN_NGRAPH
#include <ie_extension.h>
#include <ie_plugin_dispatcher.hpp>
#endif // HAVE_DNN_NGRAPH
#include <opencv2/core/utils/configuration.private.hpp>
@@ -82,7 +81,7 @@ public:
return type_info;
}
#if INF_ENGINE_VER_MAJOR_GT(2020020000)
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_3)
NgraphCustomOp(const ngraph::OutputVector& inputs,
#else
NgraphCustomOp(const ngraph::NodeVector& inputs,
@@ -112,7 +111,7 @@ public:
std::shared_ptr<ngraph::Node> copy_with_new_args(const ngraph::NodeVector& new_args) const override
{
#if INF_ENGINE_VER_MAJOR_GT(2020020000)
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_3)
return std::make_shared<NgraphCustomOp>(ngraph::as_output_vector(new_args), params);
#else
return std::make_shared<NgraphCustomOp>(new_args, params);
@@ -129,7 +128,6 @@ public:
return true;
}
private:
std::map<std::string, InferenceEngine::Parameter> params;
};
@@ -137,15 +135,28 @@ private:
class InfEngineNgraphCustomLayer : public InferenceEngine::ILayerExecImpl
{
public:
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2)
explicit InfEngineNgraphCustomLayer(const std::shared_ptr<ngraph::Node>& _node)
{
node = std::dynamic_pointer_cast<NgraphCustomOp>(_node);
CV_Assert(node);
std::string implStr = node->params["impl"];
std::istringstream iss(implStr);
#else
explicit InfEngineNgraphCustomLayer(const InferenceEngine::CNNLayer& layer) : cnnLayer(layer)
{
std::istringstream iss(layer.GetParamAsString("impl"));
#endif
size_t ptr;
iss >> ptr;
cvLayer = (Layer*)ptr;
std::vector<std::vector<size_t> > shapes;
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2)
strToShapes(node->params["internals"], shapes);
#else
strToShapes(layer.GetParamAsString("internals"), shapes);
#endif
internals.resize(shapes.size());
for (int i = 0; i < shapes.size(); ++i)
internals[i].create(std::vector<int>(shapes[i].begin(), shapes[i].end()), CV_32F);
@@ -181,6 +192,29 @@ public:
{
std::vector<InferenceEngine::DataConfig> inDataConfig;
std::vector<InferenceEngine::DataConfig> outDataConfig;
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2)
InferenceEngine::SizeVector order;
size_t offset = std::numeric_limits<size_t>::max();
for (int i = 0; i < node->get_input_size(); ++i)
{
InferenceEngine::DataConfig conf;
auto shape = node->input_value(i).get_shape();
order.resize(shape.size());
std::iota(order.begin(), order.end(), 0);
conf.desc = InferenceEngine::TensorDesc(InferenceEngine::Precision::FP32, shape, {shape, order, offset});
inDataConfig.push_back(conf);
}
for (int i = 0; i < node->get_output_size(); ++i)
{
InferenceEngine::DataConfig conf;
auto shape = node->output(i).get_shape();
order.resize(shape.size());
std::iota(order.begin(), order.end(), 0);
conf.desc = InferenceEngine::TensorDesc(InferenceEngine::Precision::FP32, shape, {shape, order, offset});
outDataConfig.push_back(conf);
}
#else
for (auto& it : cnnLayer.insData)
{
InferenceEngine::DataConfig conf;
@@ -194,6 +228,7 @@ public:
conf.desc = it->getTensorDesc();
outDataConfig.push_back(conf);
}
#endif
InferenceEngine::LayerConfig layerConfig;
layerConfig.inConfs = inDataConfig;
@@ -210,12 +245,16 @@ public:
}
private:
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2)
std::shared_ptr<NgraphCustomOp> node;
#else
InferenceEngine::CNNLayer cnnLayer;
#endif
dnn::Layer* cvLayer;
std::vector<Mat> internals;
};
#if INF_ENGINE_VER_MAJOR_LT(INF_ENGINE_RELEASE_2020_2)
class InfEngineNgraphCustomLayerFactory : public InferenceEngine::ILayerImplFactory {
public:
explicit InfEngineNgraphCustomLayerFactory(const InferenceEngine::CNNLayer* layer) : cnnLayer(*layer)
@@ -234,15 +273,29 @@ public:
private:
InferenceEngine::CNNLayer cnnLayer;
};
#endif
class InfEngineNgraphExtension : public InferenceEngine::IExtension
{
public:
void Unload() noexcept override {}
void Release() noexcept override { delete this; }
void GetVersion(const InferenceEngine::Version*&) const noexcept override {}
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2)
std::vector<std::string> getImplTypes(const std::shared_ptr<ngraph::Node>& node) override {
return {"CPU"};
}
InferenceEngine::ILayerImpl::Ptr getImplementation(const std::shared_ptr<ngraph::Node>& node, const std::string& implType) override {
if (std::dynamic_pointer_cast<NgraphCustomOp>(node) && implType == "CPU") {
return std::make_shared<InfEngineNgraphCustomLayer>(node);
}
return nullptr;
}
#else
virtual void SetLogCallback(InferenceEngine::IErrorListener&) noexcept {}
virtual void Unload() noexcept {}
virtual void Release() noexcept {}
virtual void GetVersion(const InferenceEngine::Version*&) const noexcept {}
virtual InferenceEngine::StatusCode getPrimitiveTypes(char**&, unsigned int&,
InferenceEngine::ResponseDesc*) noexcept
@@ -259,6 +312,7 @@ public:
factory = new InfEngineNgraphCustomLayerFactory(cnnLayer);
return InferenceEngine::StatusCode::OK;
}
#endif
};
@@ -283,7 +337,7 @@ InfEngineNgraphNode::InfEngineNgraphNode(const std::vector<Ptr<BackendNode> >& n
{"internals", shapesToStr(internals)}
};
#if INF_ENGINE_VER_MAJOR_GT(2020020000)
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_3)
ngraph::OutputVector inp_nodes;
#else
ngraph::NodeVector inp_nodes;
@@ -54,9 +54,14 @@
#ifdef HAVE_DNN_NGRAPH
#include "../ie_ngraph.hpp"
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4)
#include <ngraph/op/detection_output.hpp>
#else
#include <ngraph/op/experimental/layers/detection_output.hpp>
#endif
#endif
namespace cv
{
namespace dnn
@@ -667,8 +667,11 @@ struct MishFunctor : public BaseFunctor
{
for( int i = 0; i < len; i++ )
{
// Use fast approximation introduced in https://github.com/opencv/opencv/pull/17200
float x = srcptr[i];
dstptr[i] = x * tanh(log(1.0f + exp(x)));
float eX = exp(std::min(x, 20.f));
float n = (eX + 2) * eX;
dstptr[i] = (x * n) / (n + 2);
}
}
}
+5
View File
@@ -48,9 +48,14 @@
#ifdef HAVE_DNN_NGRAPH
#include "../ie_ngraph.hpp"
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4)
#include <ngraph/op/roi_pooling.hpp>
#include <ngraph/op/psroi_pooling.hpp>
#else
#include <ngraph/op/experimental/layers/roi_pooling.hpp>
#include <ngraph/op/experimental/layers/psroi_pooling.hpp>
#endif
#endif
#include <float.h>
#include <algorithm>
@@ -46,9 +46,14 @@
#ifdef HAVE_DNN_NGRAPH
#include "../ie_ngraph.hpp"
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4)
#include <ngraph/op/prior_box.hpp>
#include <ngraph/op/prior_box_clustered.hpp>
#else
#include <ngraph/op/experimental/layers/prior_box.hpp>
#include <ngraph/op/experimental/layers/prior_box_clustered.hpp>
#endif
#endif
#include <float.h>
#include <algorithm>
@@ -10,8 +10,12 @@
#ifdef HAVE_DNN_NGRAPH
#include "../ie_ngraph.hpp"
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4)
#include <ngraph/op/proposal.hpp>
#else
#include <ngraph/op/experimental/layers/proposal.hpp>
#endif
#endif
namespace cv { namespace dnn {
+16 -32
View File
@@ -412,12 +412,12 @@ public:
auto scale_x_y_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{1}, &scale_x_y);
auto shift_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{1}, std::vector<float>{0.5});
auto axis = ngraph::op::Constant::create<int64_t>(ngraph::element::i64, ngraph::Shape{}, {0});
auto splits = ngraph::op::Constant::create<int64_t>(ngraph::element::i64, ngraph::Shape{5}, {1, 1, 1, 1, rows - 4});
auto split = std::make_shared<ngraph::op::v1::VariadicSplit>(input2d, axis, splits);
std::shared_ptr<ngraph::Node> box_x;
{
auto lower_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{0, 0});
auto upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{1, cols});
box_x = std::make_shared<ngraph::op::v1::StridedSlice>(input2d, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
box_x = std::make_shared<ngraph::op::Sigmoid>(box_x);
box_x = std::make_shared<ngraph::op::Sigmoid>(split->output(0));
box_x = std::make_shared<ngraph::op::v1::Subtract>(box_x, shift_node, ngraph::op::AutoBroadcastType::NUMPY);
box_x = std::make_shared<ngraph::op::v1::Multiply>(box_x, scale_x_y_node, ngraph::op::AutoBroadcastType::NUMPY);
box_x = std::make_shared<ngraph::op::v1::Add>(box_x, shift_node, ngraph::op::AutoBroadcastType::NUMPY);
@@ -443,10 +443,7 @@ public:
std::shared_ptr<ngraph::Node> box_y;
{
auto lower_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{1, 0});
auto upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{2, cols});
box_y = std::make_shared<ngraph::op::v1::StridedSlice>(input2d, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
box_y = std::make_shared<ngraph::op::Sigmoid>(box_y);
box_y = std::make_shared<ngraph::op::Sigmoid>(split->output(1));
box_y = std::make_shared<ngraph::op::v1::Subtract>(box_y, shift_node, ngraph::op::AutoBroadcastType::NUMPY);
box_y = std::make_shared<ngraph::op::v1::Multiply>(box_y, scale_x_y_node, ngraph::op::AutoBroadcastType::NUMPY);
box_y = std::make_shared<ngraph::op::v1::Add>(box_y, shift_node, ngraph::op::AutoBroadcastType::NUMPY);
@@ -499,45 +496,32 @@ public:
std::copy(bias_h.begin(), bias_h.begin() + h * anchors, bias_h.begin() + i * h * anchors);
}
auto lower_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{2, 0});
auto upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{3, cols});
box_w = std::make_shared<ngraph::op::v1::StridedSlice>(input2d, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
box_w = std::make_shared<ngraph::op::v0::Exp>(box_w);
box_w = std::make_shared<ngraph::op::v0::Exp>(split->output(2));
box_w = std::make_shared<ngraph::op::v1::Reshape>(box_w, shape_3d, true);
auto anchor_w_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, box_broad_shape, bias_w.data());
box_w = std::make_shared<ngraph::op::v1::Multiply>(box_w, anchor_w_node, ngraph::op::AutoBroadcastType::NUMPY);
lower_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{3, 0});
upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{4, cols});
box_h = std::make_shared<ngraph::op::v1::StridedSlice>(input2d, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
box_h = std::make_shared<ngraph::op::v0::Exp>(box_h);
box_h = std::make_shared<ngraph::op::v0::Exp>(split->output(3));
box_h = std::make_shared<ngraph::op::v1::Reshape>(box_h, shape_3d, true);
auto anchor_h_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, box_broad_shape, bias_h.data());
box_h = std::make_shared<ngraph::op::v1::Multiply>(box_h, anchor_h_node, ngraph::op::AutoBroadcastType::NUMPY);
}
auto region_splits = ngraph::op::Constant::create<int64_t>(ngraph::element::i64, ngraph::Shape{3}, {4, 1, rows - 5});
auto region_split = std::make_shared<ngraph::op::v1::VariadicSplit>(region, axis, region_splits);
std::shared_ptr<ngraph::Node> scale;
{
auto lower_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{4, 0});
auto upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{5, cols});
scale = std::make_shared<ngraph::op::v1::StridedSlice>(region, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
if (classfix == -1)
{
auto thresh_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{1}, std::vector<float>{0.5});
auto mask = std::make_shared<ngraph::op::v1::Less>(scale, thresh_node);
auto zero_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, mask->get_shape(), std::vector<float>(b * cols, 0));
scale = std::make_shared<ngraph::op::v1::Select>(mask, scale, zero_node);
}
float thr = classfix == -1 ? 0.5 : 0;
auto thresh_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{1}, std::vector<float>{thr});
auto mask = std::make_shared<ngraph::op::v1::Less>(region_split->output(1), thresh_node);
auto zero_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, mask->get_shape(), std::vector<float>(cols, 0));
scale = std::make_shared<ngraph::op::v1::Select>(mask, zero_node, region_split->output(1));
}
std::shared_ptr<ngraph::Node> probs;
{
auto lower_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{5, 0});
auto upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{rows, cols});
auto classes = std::make_shared<ngraph::op::v1::StridedSlice>(region, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
probs = std::make_shared<ngraph::op::v1::Multiply>(classes, scale, ngraph::op::AutoBroadcastType::NUMPY);
probs = std::make_shared<ngraph::op::v1::Multiply>(region_split->output(2), scale, ngraph::op::AutoBroadcastType::NUMPY);
auto thresh_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{1}, &thresh);
auto mask = std::make_shared<ngraph::op::v1::Greater>(probs, thresh_node);
auto zero_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, mask->get_shape(), std::vector<float>((rows - 5) * cols, 0));
+5 -1
View File
@@ -41,7 +41,6 @@
//M*/
#include "../precomp.hpp"
#include "../op_inf_engine.hpp"
#include <opencv2/dnn/shape_utils.hpp>
#include <opencv2/dnn/all_layers.hpp>
@@ -50,10 +49,15 @@
#include "opencl_kernels_dnn.hpp"
#endif
#include "../op_inf_engine.hpp"
#ifdef HAVE_DNN_NGRAPH
#include "../ie_ngraph.hpp"
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4)
#include <ngraph/op/reorg_yolo.hpp>
#else
#include <ngraph/op/experimental/layers/reorg_yolo.hpp>
#endif
#endif
namespace cv
{
+4
View File
@@ -11,8 +11,12 @@
#ifdef HAVE_DNN_NGRAPH
#include "../ie_ngraph.hpp"
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4)
#include <ngraph/op/interpolate.hpp>
#else
#include <ngraph/op/experimental/layers/interpolate.hpp>
#endif
#endif
namespace cv { namespace dnn {
+149 -32
View File
@@ -47,6 +47,8 @@
#include "layers_common.hpp"
#include <opencv2/dnn/shape_utils.hpp>
#include <opencv2/core/utils/logger.hpp>
#ifdef HAVE_OPENCL
#include "opencl_kernels_dnn.hpp"
#endif
@@ -197,6 +199,18 @@ public:
finalSliceRanges[i][j] = clamp(finalSliceRanges[i][j], inpShape[j]);
}
}
#if 0
std::cout << "DEBUG: DNN/Slice: " << outputs.size() << " inpShape=" << inpShape << std::endl;
for (int i = 0; i < outputs.size(); ++i)
{
for (int j = 0; j < finalSliceRanges[i].size(); ++j)
{
std::cout << finalSliceRanges[i][j];
}
std::cout << std::endl;
}
#endif
}
#ifdef HAVE_OPENCL
@@ -205,46 +219,149 @@ public:
std::vector<UMat> inputs;
std::vector<UMat> outputs;
bool use_half = (inputs_.depth() == CV_16S);
inputs_.getUMatVector(inputs);
outputs_.getUMatVector(outputs);
if (inputs[0].dims < 4 || (total(shape(outputs[0]), 0, 2) % 4 != 0) ||
(total(shape(outputs[0]), 2) % 4 != 0))
return false;
CV_Assert(outputs.size() == finalSliceRanges.size());
String opts;
if (use_half)
opts = "-DDtype=half -DDtype4=half4 -DDtype8=half8";
else
opts = "-DDtype=float -DDtype4=float4 -DDtype8=float8";
const UMat& inpMat = inputs[0];
for (size_t i = 0; i < outputs.size(); i++)
const UMat& input = inputs[0];
if (input.dims > 5)
{
int groups = outputs[i].size[0];
int channels = outputs[i].size[1];
int rows = outputs[i].size[2];
int cols = outputs[i].size[3];
ocl::Kernel kernel("slice", ocl::dnn::slice_oclsrc, opts);
size_t local[] = { 128 };
size_t global[] = { (size_t)groups * channels / 4 * local[0] };
int idx = 0;
kernel.set(idx++, ocl::KernelArg::PtrReadOnly(inpMat));
kernel.set(idx++, (int)(inpMat.size[2] * inpMat.size[3]));
kernel.set(idx++, (int)(rows * cols));
kernel.set(idx++, (int)inpMat.size[3]);
kernel.set(idx++, (int)cols);
kernel.set(idx++, (int)finalSliceRanges[i][2].start);
kernel.set(idx++, (int)finalSliceRanges[i][3].start);
kernel.set(idx++, ocl::KernelArg::PtrWriteOnly(outputs[i]));
bool ret = kernel.run(1, global, local, false);
if (!ret)
return false;
CV_LOG_INFO(NULL, "DNN/OpenCL/Slice: implementation doesn't support dims=" << input.dims << ". Fallback to CPU");
return false;
}
size_t WSZ = 128;
const int dims = input.dims;
const int elemSize = (int)input.elemSize();
String opts0 = cv::format(
"-DDIMS=%d -DELEMSIZE=%d",
dims, elemSize
);
for (int d = 0; d < dims; d++)
{
opts0 += cv::format(" -DSRC_STEP_%d=%d", d, (int)input.step[dims - 1 - d]);
}
String kname = cv::format("slice_%d", dims);
for (size_t i = 0; i < outputs.size(); i++)
{
UMat& output = outputs[i];
const std::vector<Range>& range = finalSliceRanges[i];
String opts = opts0;
CV_CheckEQ(output.dims, dims, "");
for (int d = 0; d < dims; d++)
{
opts += cv::format(" -DDST_STEP_%d=%d -DDST_SZ_%d=%d -DSRC_START_%d=%d",
d, (int)output.step[dims - 1 - d],
d, (int)output.size[dims - 1 - d],
d, (int)range[dims - 1 - d].start
);
CV_CheckEQ(range[d].size(), (int)output.size[d], "");
}
int block_dims = 0;
size_t block_size = elemSize;
for (int i = dims - 1; i >= 0; --i)
{
if (input.step[i] != output.step[i])
break;
block_size *= output.size[i];
block_dims++;
}
const size_t total = output.total() * elemSize;
size_t num_blocks = total / block_size;
if ((num_blocks <= 8 && block_size >= WSZ * 4) || (block_size >= WSZ * 64))
{
// use 1D copy mode
opts += cv::format(" -DUSE_COPY_1D=1");
opts += cv::format(" -DBLOCK_DIMS=%d", block_dims);
opts += cv::format(" -DBLOCK_DIMS_CONTIGUOUS=%d", block_dims);
opts += cv::format(" -DBLOCK_SIZE=%d", (int)block_size);
opts += cv::format(" -DBLOCK_COLS=%d", (int)block_size);
}
else
{
// use 2D copy mode
int block_cols = block_size;
int block_dims_contiguous = block_dims;
size_t input_base_step = input.step[dims - 1 - block_dims_contiguous];
size_t output_base_step = output.step[dims - 1 - block_dims_contiguous];
size_t block_rows = 1;
for (int i = dims - 1 - block_dims_contiguous; i >= 0; --i)
{
if (input.step[i] * output_base_step != output.step[i] * input_base_step)
break;
block_rows *= output.size[i];
block_dims++;
}
block_size *= block_rows;
num_blocks = total / block_size;
if (block_rows > 1)
{
opts += cv::format(" -DBLOCK_DIMS=%d", block_dims);
opts += cv::format(" -DBLOCK_DIMS_CONTIGUOUS=%d", block_dims_contiguous);
opts += cv::format(" -DBLOCK_SIZE=%d", (int)block_size);
opts += cv::format(" -DBLOCK_COLS=%d", (int)block_cols);
opts += cv::format(" -DBLOCK_ROWS=%d", (int)block_rows);
opts += cv::format(" -DBLOCK_SRC_STRIDE=%d", (int)input_base_step);
}
else
{
// use 1D copy mode
opts += cv::format(" -DUSE_COPY_1D=1");
opts += cv::format(" -DBLOCK_DIMS=%d", block_dims_contiguous);
opts += cv::format(" -DBLOCK_DIMS_CONTIGUOUS=%d", block_dims_contiguous);
opts += cv::format(" -DBLOCK_SIZE=%d", (int)block_size);
opts += cv::format(" -DBLOCK_COLS=%d", (int)block_size);
}
}
const size_t MIN_WORK_ITEMS = 16;
if (block_size <= 4 * MIN_WORK_ITEMS)
WSZ = 4;
else if (block_size <= 8 * MIN_WORK_ITEMS)
WSZ = 8;
else if (block_size <= 16 * MIN_WORK_ITEMS)
WSZ = 16;
else if (block_size <= 32 * MIN_WORK_ITEMS)
WSZ = 32;
else if (block_size <= 64 * MIN_WORK_ITEMS)
WSZ = 64;
opts += cv::format(" -DWSZ=%d", (int)WSZ);
size_t local[] = { WSZ, 1 };
size_t global[] = { WSZ, num_blocks };
ocl::Kernel kernel(kname.c_str(), ocl::dnn::slice_oclsrc, opts);
if (kernel.empty())
return false;
bool ret = kernel.args(
ocl::KernelArg::PtrReadOnly(input),
ocl::KernelArg::PtrWriteOnly(output)
)
.run(2, global, local, false);
if (!ret)
return false;
} // for outputs.size()
return true;
}
}
#endif
void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE
+2 -3
View File
@@ -11,7 +11,6 @@
#ifdef HAVE_INF_ENGINE
#include <ie_extension.h>
#include <ie_plugin_dispatcher.hpp>
#endif // HAVE_INF_ENGINE
#include <opencv2/core/utils/configuration.private.hpp>
@@ -832,18 +831,18 @@ void InfEngineBackendNet::initPlugin(InferenceEngine::CNNNetwork& net)
CV_LOG_INFO(NULL, "DNN-IE: Can't register OpenCV custom layers extension: " << e.what());
}
#endif
#ifndef _WIN32
// Limit the number of CPU threads.
#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2019R1)
#ifndef _WIN32
enginePtr->SetConfig({{
InferenceEngine::PluginConfigParams::KEY_CPU_THREADS_NUM, format("%d", getNumThreads()),
}}, 0);
#endif // _WIN32
#else
if (device_name == "CPU")
ie.SetConfig({{
InferenceEngine::PluginConfigParams::KEY_CPU_THREADS_NUM, format("%d", getNumThreads()),
}}, device_name);
#endif
#endif
}
#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2019R1)
+8 -4
View File
@@ -25,10 +25,12 @@
#define INF_ENGINE_RELEASE_2019R3 2019030000
#define INF_ENGINE_RELEASE_2020_1 2020010000
#define INF_ENGINE_RELEASE_2020_2 2020020000
#define INF_ENGINE_RELEASE_2020_3 2020030000
#define INF_ENGINE_RELEASE_2020_4 2020040000
#ifndef INF_ENGINE_RELEASE
#warning("IE version have not been provided via command-line. Using 2020.2 by default")
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2020_2
#warning("IE version have not been provided via command-line. Using 2020.4 by default")
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2020_4
#endif
#define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000))
@@ -42,7 +44,7 @@
#pragma GCC diagnostic ignored "-Wsuggest-override"
#endif
#ifdef HAVE_DNN_IE_NN_BUILDER_2019
#if defined(HAVE_DNN_IE_NN_BUILDER_2019) || INF_ENGINE_VER_MAJOR_EQ(INF_ENGINE_RELEASE_2020_4)
//#define INFERENCE_ENGINE_DEPRECATED // turn off deprecation warnings from IE
//there is no way to suppress warnings from IE only at this moment, so we are forced to suppress warnings globally
#if defined(__GNUC__)
@@ -51,7 +53,7 @@
#ifdef _MSC_VER
#pragma warning(disable: 4996) // was declared deprecated
#endif
#endif // HAVE_DNN_IE_NN_BUILDER_2019
#endif
#if defined(__GNUC__) && INF_ENGINE_VER_MAJOR_LT(INF_ENGINE_RELEASE_2020_1)
#pragma GCC visibility push(default)
@@ -225,7 +227,9 @@ private:
class InfEngineExtension : public InferenceEngine::IExtension
{
public:
#if INF_ENGINE_VER_MAJOR_LT(INF_ENGINE_RELEASE_2020_2)
virtual void SetLogCallback(InferenceEngine::IErrorListener&) noexcept {}
#endif
virtual void Unload() noexcept {}
virtual void Release() noexcept {}
virtual void GetVersion(const InferenceEngine::Version*&) const noexcept {}
+274 -72
View File
@@ -1,81 +1,283 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2017, Intel Corporation, all rights reserved.
// Copyright (c) 2016-2017 Fabian David Tschopp, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#if defined(cl_khr_fp16)
#pragma OPENCL EXTENSION cl_khr_fp16 : enable
// Copyright (C) 2020, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
/*
Specialization constants:
- WSZ: size of OpenCL local group
- DIMS: number of working dimensions
- ELEMSIZE: element size in bytes
- DST_SZ_<i>: dst sizes
- SRC_START_<i>: src index shift (slice .start value)
- SRC_STEP_<i>: src steps (bytes)
- DST_STEP_<i>: dst steps (bytes), derived from DST_SZ_<i> and ELEMSIZE
- BLOCK_DIMS: number of dims for copy block (argmax(count(SRC_STEP_<i> != DST_STEP_<i>) <= 1))
- BLOCK_DIMS_CONTIGUOUS (<= BLOCK_DIMS): SRC_STEP_<i> == DST_STEP_<i> for i in [0, BLOCK_DIMS_CONTIGUOUS)
derived specialization constants:
- BLOCK_SIZE: ELEMSIZE * mul(DST_SZ_<i>) for i in [0, BLOCK_DIMS)
- USE_COPY_1D iff BLOCK_DIMS == BLOCK_DIMS_CONTIGUOUS
- BLOCK_COLS:
* with USE_COPY_1D: BLOCK_SIZE
* w/o USE_COPY_1D: ELEMSIZE * mul(DST_SZ_<i>) for i in [0, BLOCK_DIMS_CONTIGUOUS)
- BLOCK_ROWS:
* with USE_COPY_1D: N/A
* w/o USE_COPY_1D: ELEMSIZE * mul(DST_SZ_<i>) for i in [BLOCK_DIMS_CONTIGUOUS, BLOCK_DIMS)
- BLOCK_SRC_STRIDE:
* with USE_COPY_1D: N/A
* w/o USE_COPY_1D: ELEMSIZE * mul(SRC_STEP_<i>) for i in [0, BLOCK_DIMS_CONTIGUOUS)
Note: SZ, STEP values are in reversed order than OpenCV Mat:
- NCHW SZ: [cols, rows, channels, batch]
- NCHW STEP: [elemsize, cols * elemsize, rows * cols * elemsize, ...] (DIMS+1 value)
*/
/*
local: <WSZ, 1, 1>
global: <WSZ, number_of_copy_blocks, 1>
*/
#define CONCAT_(A, B) A##B
#define CONCAT(A, B) CONCAT_(A, B)
#define BLOCK_COLS_X4 (BLOCK_COLS / 4)
#define BLOCK_COLS_X16 (BLOCK_COLS / 16)
#ifdef USE_COPY_1D
static inline
__attribute__((always_inline))
void copy_block_1d(
__global const uchar* src0,
const uint src_offset,
__global uchar* dst0,
const uint dst_offset
)
{
__global const uchar* src = src0 + src_offset;
__global uchar* dst = dst0 + dst_offset;
uint processed = 0;
#if BLOCK_COLS_X16 >= 4
{
// uchar16 x 4rows per iteration
uint i = get_local_id(0) * 16; // uchar16
while (i < BLOCK_COLS_X16 * 16)
{
uint4 idx = (uint4)(i, i + 16 * WSZ, i + 32 * WSZ, i + 48 * WSZ);
idx = select((uint4)i, idx, idx < (BLOCK_COLS_X16 * 16));
uchar16 a0 = vload16(0, src + idx.s0);
uchar16 a1 = vload16(0, src + idx.s1);
uchar16 a2 = vload16(0, src + idx.s2);
uchar16 a3 = vload16(0, src + idx.s3);
vstore16(a0, 0, dst + idx.s0);
vstore16(a1, 0, dst + idx.s1);
vstore16(a2, 0, dst + idx.s2);
vstore16(a3, 0, dst + idx.s3);
i += WSZ * 16 * 4;
}
processed = BLOCK_COLS_X16 * 16;
}
#else
#define SKIP_1D_BLOCK_COLS_X16 1
#endif
__kernel void slice(__global const Dtype* src,
const int src_plane_size,
const int dst_plane_size,
const int src_cols,
const int dst_cols,
const int row_offset,
const int col_offset,
__global Dtype* dst)
{
unsigned int row_gid = get_group_id(0);
unsigned int lid = get_local_id(0);
const __global Dtype *src_read = src + row_gid * 4 * src_plane_size;
__global Dtype *dst_read = dst + row_gid * 4 * dst_plane_size;
Dtype4 a0, a1, a2, a3;
int i = lid;
while( i < dst_plane_size / 4)
#if BLOCK_COLS_X4 > 0 && (defined(SKIP_1D_BLOCK_COLS_X16) || (BLOCK_COLS_X16 * 16 != BLOCK_COLS_X4 * 4))
{
int row = (4 * i) / dst_cols + row_offset;
int col = (4 * i) % dst_cols + col_offset;
int src_index = row * src_cols + col;
// uchar4 x 4rows per iteration
uint i = get_local_id(0) * 4 + processed; // uchar4
while (i < BLOCK_COLS_X4 * 4)
{
uint4 idx = (uint4)(i, i + 4 * WSZ, i + 8 * WSZ, i + 12 * WSZ);
idx = select((uint4)i, idx, idx < (BLOCK_COLS_X4 * 4));
a0 = vload4(0, src_read + src_index);
a1 = vload4(0, src_read + src_index + src_plane_size);
a2 = vload4(0, src_read + src_index + 2 * src_plane_size);
a3 = vload4(0, src_read + src_index + 3 * src_plane_size);
uchar4 a0 = vload4(0, src + idx.s0);
uchar4 a1 = vload4(0, src + idx.s1);
uchar4 a2 = vload4(0, src + idx.s2);
uchar4 a3 = vload4(0, src + idx.s3);
vstore4(a0, i, dst_read);
vstore4(a1, i, dst_read + dst_plane_size);
vstore4(a2, i, dst_read + 2 * dst_plane_size);
vstore4(a3, i, dst_read + 3 * dst_plane_size);
vstore4(a0, 0, dst + idx.s0);
vstore4(a1, 0, dst + idx.s1);
vstore4(a2, 0, dst + idx.s2);
vstore4(a3, 0, dst + idx.s3);
i += get_local_size(0);
i += WSZ * 4 * 4;
}
processed = BLOCK_COLS_X4 * 4;
}
#else
#define SKIP_1D_BLOCK_COLS_X4 1
#endif // BLOCK_COLS_X4 > 0
#if (defined(SKIP_1D_BLOCK_COLS_X16) && defined(SKIP_1D_BLOCK_COLS_X4)) || BLOCK_COLS_X4 * 4 != BLOCK_COLS
{
uint i = get_local_id(0) + processed;
while (i < BLOCK_COLS)
{
uchar a0 = src[i];
dst[i] = a0;
i += WSZ;
}
}
#endif
}
#else // USE_COPY_1D
static inline
__attribute__((always_inline))
void copy_block_2d(
__global const uchar* src0,
const uint src_offset0,
__global uchar* dst0,
const uint dst_offset0
)
{
__global const uchar* src = src0 + src_offset0;
__global uchar* dst = dst0 + dst_offset0;
uint i = get_local_id(0) * 4;
#define BLOCK_COLS_FILL_X4 (((BLOCK_COLS + 3) / 4) * 4)
#define BLOCK_SIZE_FILL_X4 (BLOCK_COLS_FILL_X4 * BLOCK_ROWS)
while (i < BLOCK_SIZE_FILL_X4)
{
int row = i / BLOCK_COLS_FILL_X4;
int col = i % BLOCK_COLS_FILL_X4;
uint src_offset = row * BLOCK_SRC_STRIDE + col;
#if BLOCK_COLS_FILL_X4 == BLOCK_COLS
uint dst_offset = i;
#else
uint dst_offset = row * BLOCK_COLS + col;
#endif
#if BLOCK_COLS_FILL_X4 != BLOCK_COLS
if (col <= BLOCK_COLS - 4)
#endif
{
uchar4 a = vload4(0, src + src_offset);
vstore4(a, 0, dst + dst_offset);
}
#if BLOCK_COLS_FILL_X4 != BLOCK_COLS
else
{
/* non-optimized reference code
while (col < BLOCK_COLS)
{
uchar a = src[src_offset];
dst[dst_offset] = a;
col++;
src_offset++;
dst_offset++;
}
*/
uint4 shift = (uint4)(0, 1, 2, 3);
shift = select((uint4)0, shift, col + shift < BLOCK_COLS);
dst[dst_offset + shift.s0] = src[src_offset + shift.s0];
#if BLOCK_COLS_FILL_X4 - BLOCK_COLS <= 2
dst[dst_offset + shift.s1] = src[src_offset + shift.s1];
#endif
#if BLOCK_COLS_FILL_X4 - BLOCK_COLS <= 1
dst[dst_offset + shift.s2] = src[src_offset + shift.s2];
#endif
}
#endif // BLOCK_COLS_FILL_X4 != BLOCK_COLS
i += WSZ * 4;
}
}
#endif // USE_COPY_1D
__kernel void
CONCAT(slice_, DIMS)(
__global const uchar* src,
__global uchar* dst
)
{
uint block_id = get_global_id(1);
uint dst_offset = block_id * BLOCK_SIZE;
uint src_offset = 0;
#define CALC_SRC_INDEX(dim) \
{ \
uint plane_sz = CONCAT(DST_STEP_, dim) / BLOCK_SIZE; \
CONCAT(idx_, dim) = block_id / plane_sz; \
block_id = block_id - CONCAT(idx_, dim) * plane_sz; \
}
#define UPDATE_SRC_OFFSET(dim) \
src_offset = mad24((uint)(CONCAT(idx_, dim) + CONCAT(SRC_START_, dim)), (uint)CONCAT(SRC_STEP_, dim), (uint)src_offset);
/*
if (get_global_id(0) == 0 && get_global_id(1) == 0) \
printf("(%d, %d): @%d src_offset=%d idx_dim=%d block_id=%d\n", \
get_global_id(0), get_global_id(1), \
dim, src_offset, CONCAT(idx_, dim), block_id \
);
*/
#if DIMS > 5
#error "invalid configuration"
#endif
#if DIMS > 4
uint idx_4 = 0;
#if BLOCK_DIMS <= 4
CALC_SRC_INDEX(4)
#endif
UPDATE_SRC_OFFSET(4)
#endif
#if DIMS > 3
uint idx_3 = 0;
#if BLOCK_DIMS <= 3
CALC_SRC_INDEX(3)
#endif
UPDATE_SRC_OFFSET(3)
#endif
#if DIMS > 2
uint idx_2 = 0;
#if BLOCK_DIMS <= 2
CALC_SRC_INDEX(2)
#endif
UPDATE_SRC_OFFSET(2)
#endif
#if DIMS > 1
uint idx_1 = 0;
#if BLOCK_DIMS <= 1
CALC_SRC_INDEX(1)
#endif
UPDATE_SRC_OFFSET(1)
#endif
#if DIMS > 0
uint idx_0 = 0;
UPDATE_SRC_OFFSET(0)
#endif
/*
if (get_global_id(0) == 0)
printf("(%d, %d): src_offset=%d dst_offset=%d\n",
get_global_id(0), get_global_id(1),
src_offset, dst_offset
);
*/
#ifdef USE_COPY_1D
copy_block_1d(src, src_offset, dst, dst_offset);
#else
copy_block_2d(src, src_offset, dst, dst_offset);
#endif
}
@@ -31,7 +31,10 @@ public:
virtual std::string getInputName(int idx) const CV_OVERRIDE
{
return node->input(idx);
// If operation produces several tensors, they are specified by index
// after ':' character. In example, "input:0".
std::string name = node->input(idx);
return name.substr(0, name.rfind(':'));
}
virtual std::string getType() const CV_OVERRIDE
+2
View File
@@ -390,6 +390,8 @@ TEST_P(DNNTestNetwork, DenseNet_121)
if (target == DNN_TARGET_OPENCL_FP16)
{
l1 = 2e-2; lInf = 9e-2;
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
lInf = 0.1f;
}
else if (target == DNN_TARGET_MYRIAD)
{
+7 -2
View File
@@ -489,6 +489,11 @@ TEST_P(Test_Caffe_nets, Colorization)
{
l1 = 0.5; lInf = 11;
}
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
{
l1 = 0.26; lInf = 6.5;
}
normAssert(out, ref, "", l1, lInf);
expectNoFallbacksFromIE(net);
}
@@ -515,8 +520,8 @@ TEST_P(Test_Caffe_nets, DenseNet_121)
float l1 = default_l1, lInf = default_lInf;
if (target == DNN_TARGET_OPENCL_FP16)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000)
l1 = 0.04; lInf = 0.21;
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019020000)
l1 = 0.045; lInf = 0.21;
#else
l1 = 0.017; lInf = 0.0795;
#endif
+7 -1
View File
@@ -96,9 +96,12 @@ void normAssertDetections(
const char *comment /*= ""*/, double confThreshold /*= 0.0*/,
double scores_diff /*= 1e-5*/, double boxes_iou_diff /*= 1e-4*/)
{
ASSERT_FALSE(testClassIds.empty()) << "No detections";
std::vector<bool> matchedRefBoxes(refBoxes.size(), false);
std::vector<double> refBoxesIoUDiff(refBoxes.size(), 1.0);
for (int i = 0; i < testBoxes.size(); ++i)
{
//cout << "Test[i=" << i << "]: score=" << testScores[i] << " id=" << testClassIds[i] << " box " << testBoxes[i] << endl;
double testScore = testScores[i];
if (testScore < confThreshold)
continue;
@@ -115,6 +118,7 @@ void normAssertDetections(
double interArea = (testBox & refBoxes[j]).area();
double iou = interArea / (testBox.area() + refBoxes[j].area() - interArea);
topIoU = std::max(topIoU, iou);
refBoxesIoUDiff[j] = std::min(refBoxesIoUDiff[j], 1.0f - iou);
if (1.0 - iou < boxes_iou_diff)
{
matched = true;
@@ -137,7 +141,9 @@ void normAssertDetections(
if (!matchedRefBoxes[i] && refScores[i] > confThreshold)
{
std::cout << cv::format("Unmatched reference: class %d score %f box ",
refClassIds[i], refScores[i]) << refBoxes[i] << std::endl;
refClassIds[i], refScores[i]) << refBoxes[i]
<< " IoU diff: " << refBoxesIoUDiff[i]
<< std::endl;
EXPECT_LE(refScores[i], confThreshold) << comment;
}
}
+96 -1
View File
@@ -254,6 +254,13 @@ public:
}
if (cvIsNaN(iouDiff))
{
if (b == 0)
std::cout << "Skip accuracy checks" << std::endl;
continue;
}
normAssertDetections(refClassIds[b], refConfidences[b], refBoxes[b], nms_classIds,
nms_confidences, nms_boxes, format("batch size %d, sample %d\n", batch_size, b).c_str(), confThreshold, scoreDiff, iouDiff);
}
@@ -316,6 +323,12 @@ TEST_P(Test_Darknet_nets, YoloVoc)
CV_TEST_TAG_LONG
);
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
@@ -356,6 +369,12 @@ TEST_P(Test_Darknet_nets, TinyYoloVoc)
{
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
#if defined(INF_ENGINE_RELEASE)
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 || backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) &&
target == DNN_TARGET_MYRIAD && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
@@ -449,7 +468,7 @@ TEST_P(Test_Darknet_nets_async, Accuracy)
}
INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_nets_async, Combine(
Values("yolo-voc", "tiny-yolo-voc", "yolov3", "yolov4"),
Values("yolo-voc", "tiny-yolo-voc", "yolov3", "yolov4", "yolov4-tiny"),
dnnBackendsAndTargets()
));
@@ -459,6 +478,13 @@ TEST_P(Test_Darknet_nets, YOLOv3)
{
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB));
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
@@ -523,6 +549,12 @@ TEST_P(Test_Darknet_nets, YOLOv4)
{
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB));
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
#if defined(INF_ENGINE_RELEASE)
if (target == DNN_TARGET_MYRIAD) // NC_OUT_OF_MEMORY
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
@@ -587,6 +619,63 @@ TEST_P(Test_Darknet_nets, YOLOv4)
}
}
TEST_P(Test_Darknet_nets, YOLOv4_tiny)
{
applyTestTag(
target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB
);
const double confThreshold = 0.5;
// batchId, classId, confidence, left, top, right, bottom
const int N0 = 2;
const int N1 = 3;
static const float ref_[/* (N0 + N1) * 7 */] = {
0, 7, 0.85935f, 0.593484f, 0.141211f, 0.920356f, 0.291593f,
0, 16, 0.795188f, 0.169207f, 0.386886f, 0.423753f, 0.933004f,
1, 2, 0.996832f, 0.653802f, 0.464573f, 0.815193f, 0.653292f,
1, 2, 0.963325f, 0.451151f, 0.458915f, 0.496255f, 0.52241f,
1, 0, 0.926244f, 0.194851f, 0.361743f, 0.260277f, 0.632364f,
};
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
double scoreDiff = 0.01f;
double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.15 : 0.01f;
std::string config_file = "yolov4-tiny.cfg";
std::string weights_file = "yolov4-tiny.weights";
#if defined(INF_ENGINE_RELEASE)
if (target == DNN_TARGET_MYRIAD) // bad accuracy
iouDiff = std::numeric_limits<double>::quiet_NaN();
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL)
iouDiff = std::numeric_limits<double>::quiet_NaN();
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_OPENCL_FP16)
iouDiff = std::numeric_limits<double>::quiet_NaN();
#endif
{
SCOPED_TRACE("batch size 1");
testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, iouDiff, confThreshold);
}
{
SCOPED_TRACE("batch size 2");
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff, confThreshold);
}
#if defined(INF_ENGINE_RELEASE)
if (target == DNN_TARGET_MYRIAD) // bad accuracy
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_OPENCL_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
}
INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_nets, dnnBackendsAndTargets());
@@ -627,6 +716,12 @@ TEST_P(Test_Darknet_layers, reorg)
testDarknetLayer("reorg");
}
TEST_P(Test_Darknet_layers, route)
{
testDarknetLayer("route");
testDarknetLayer("route_multi");
}
TEST_P(Test_Darknet_layers, maxpool)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020020000)
+18 -7
View File
@@ -73,7 +73,8 @@ struct OpenVINOModelTestCaseInfo
static const std::map<std::string, OpenVINOModelTestCaseInfo>& getOpenVINOTestModels()
{
static std::map<std::string, OpenVINOModelTestCaseInfo> g_models {
#if INF_ENGINE_RELEASE >= 2018050000
#if INF_ENGINE_RELEASE >= 2018050000 && \
INF_ENGINE_RELEASE <= 2020999999 // don't use IRv5 models with 2020.1+
// layout is defined by open_model_zoo/model_downloader
// Downloaded using these parameters for Open Model Zoo downloader (2019R1):
// ./downloader.py -o ${OPENCV_DNN_TEST_DATA_PATH}/omz_intel_models --cache_dir ${OPENCV_DNN_TEST_DATA_PATH}/.omz_cache/ \
@@ -136,12 +137,6 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath
{
SCOPED_TRACE("runIE");
CNNNetReader reader;
reader.ReadNetwork(xmlPath);
reader.ReadWeights(binPath);
CNNNetwork net = reader.getNetwork();
std::string device_name;
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GT(2019010000)
@@ -150,6 +145,17 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath
InferenceEnginePluginPtr enginePtr;
InferencePlugin plugin;
#endif
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GT(2019030000)
CNNNetwork net = ie.ReadNetwork(xmlPath, binPath);
#else
CNNNetReader reader;
reader.ReadNetwork(xmlPath);
reader.ReadWeights(binPath);
CNNNetwork net = reader.getNetwork();
#endif
ExecutableNetwork netExec;
InferRequest infRequest;
@@ -290,6 +296,11 @@ TEST_P(DNNTestOpenVINO, models)
}
#endif
#if INF_ENGINE_VER_MAJOR_EQ(2020040000)
if (targetId == DNN_TARGET_MYRIAD && modelName == "person-detection-retail-0002") // IRv5, OpenVINO 2020.4 regression
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API);
else if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
+119 -1
View File
@@ -364,6 +364,16 @@ TEST_P(Test_Caffe_layers, layer_prelu_fc)
// Reference output values are in range [-0.0001, 10.3906]
double l1 = (target == DNN_TARGET_MYRIAD) ? 0.005 : 0.0;
double lInf = (target == DNN_TARGET_MYRIAD) ? 0.021 : 0.0;
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
{
l1 = 0.006f; lInf = 0.05f;
}
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
{
l1 = 0.01f; lInf = 0.05f;
}
#endif
testLayerUsingCaffeModels("layer_prelu_fc", true, false, l1, lInf);
}
@@ -1837,7 +1847,115 @@ TEST_P(Layer_Test_Resize, change_input)
INSTANTIATE_TEST_CASE_P(/**/, Layer_Test_Resize, dnnBackendsAndTargets());
typedef testing::TestWithParam<tuple<Backend, Target> > Layer_Test_Slice;
struct Layer_Test_Slice : public testing::TestWithParam<tuple<Backend, Target> >
{
template<int DIMS>
void test_slice(const int* inputShape, const int* begin, const int* end)
{
int backendId = get<0>(GetParam());
int targetId = get<1>(GetParam());
Mat input(DIMS, inputShape, CV_32FC1, Scalar::all(0));
for (int i = 0; i < (int)input.total(); ++i)
input.ptr<float>()[i] = (float)i;
std::vector<Range> range(DIMS);
for (int i = 0; i < DIMS; ++i)
range[i] = Range(begin[i], end[i]);
Net net;
LayerParams lp;
lp.type = "Slice";
lp.name = "testLayer";
lp.set("begin", DictValue::arrayInt<int*>((int*)&begin[0], DIMS));
lp.set("end", DictValue::arrayInt<int*>((int*)&end[0], DIMS));
net.addLayerToPrev(lp.name, lp.type, lp);
{
net.setInput(input);
net.setPreferableBackend(backendId);
net.setPreferableTarget(targetId);
Mat out = net.forward();
EXPECT_GT(cv::norm(out, NORM_INF), 0);
normAssert(out, input(range));
#if 0
cout << input(range).clone().reshape(1, 1) << endl;
cout << out.reshape(1, 1) << endl;
#endif
}
}
};
TEST_P(Layer_Test_Slice, slice_channels_17762)
{
const int inputShape[4] = {1, 16, 6, 8};
const int begin[] = {0, 4, 0, 0};
const int end[] = {1, 8, 6, 8};
test_slice<4>(inputShape, begin, end);
}
TEST_P(Layer_Test_Slice, slice_channels_with_batch_17762)
{
const int inputShape[4] = {4, 4, 3, 4};
const int begin[] = {0, 1, 0, 0};
const int end[] = {4, 3, 3, 4};
test_slice<4>(inputShape, begin, end);
}
TEST_P(Layer_Test_Slice, slice_channels_and_batch_17762)
{
int backend = get<0>(GetParam());
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
const int inputShape[4] = {4, 4, 3, 4};
const int begin[] = {2, 1, 0, 0};
const int end[] = {4, 3, 3, 4};
test_slice<4>(inputShape, begin, end);
}
TEST_P(Layer_Test_Slice, slice_rows)
{
const int inputShape[4] = {1, 2, 6, 4};
const int begin[] = {0, 0, 4, 0};
const int end[] = {1, 2, 6, 4};
test_slice<4>(inputShape, begin, end);
}
TEST_P(Layer_Test_Slice, slice_cols)
{
const int inputShape[4] = {1, 2, 3, 8};
const int begin[] = {0, 0, 0, 4};
const int end[] = {1, 2, 3, 8};
test_slice<4>(inputShape, begin, end);
}
TEST_P(Layer_Test_Slice, slice_complex_1_unaligned)
{
const int inputShape[4] = {1, 4, 2, 3};
const int begin[] = {0, 2, 1, 0};
const int end[] = {1, 3, 2, 2};
test_slice<4>(inputShape, begin, end);
}
TEST_P(Layer_Test_Slice, slice_complex_2_x4)
{
const int inputShape[4] = {1, 3, 2, 4};
const int begin[] = {0, 2, 1, 0};
const int end[] = {1, 3, 2, 2};
test_slice<4>(inputShape, begin, end);
}
TEST_P(Layer_Test_Slice, slice_complex_3)
{
const int inputShape[4] = {1, 6, 4, 8};
const int begin[] = {0, 2, 1, 4};
const int end[] = {1, 4, 3, 8};
test_slice<4>(inputShape, begin, end);
}
TEST_P(Layer_Test_Slice, variable_input_shape)
{
int backendId = get<0>(GetParam());
+14
View File
@@ -704,6 +704,13 @@ TEST_P(Test_ONNX_nets, TinyYolov2)
// output range: [-11; 8]
double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.017 : default_l1;
double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.14 : default_lInf;
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
{
l1 = 0.018f; lInf = 0.16f;
}
#endif
testONNXModels("tiny_yolo2", pb, l1, lInf);
}
@@ -781,6 +788,13 @@ TEST_P(Test_ONNX_nets, Emotion_ferplus)
l1 = 2.4e-4;
lInf = 6e-4;
}
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
{
l1 = 0.012f; lInf = 0.035f;
}
#endif
testONNXModels("emotion_ferplus", pb, l1, lInf);
}
@@ -261,6 +261,10 @@ public:
@param contrastThreshold The contrast threshold used to filter out weak features in semi-uniform
(low-contrast) regions. The larger the threshold, the less features are produced by the detector.
@note The contrast threshold will be divided by nOctaveLayers when the filtering is applied. When
nOctaveLayers is set to default and if you want to use the value used in D. Lowe paper, 0.03, set
this argument to 0.09.
@param edgeThreshold The threshold used to filter out edge-like features. Note that the its meaning
is different from the contrastThreshold, i.e. the larger the edgeThreshold, the less features are
filtered out (more features are retained).
@@ -271,6 +275,8 @@ public:
CV_WRAP static Ptr<SIFT> create(int nfeatures = 0, int nOctaveLayers = 3,
double contrastThreshold = 0.04, double edgeThreshold = 10,
double sigma = 1.6);
CV_WRAP virtual String getDefaultName() const CV_OVERRIDE;
};
typedef SIFT SiftFeatureDetector;
+4 -1
View File
@@ -21,7 +21,8 @@ namespace opencv_test
ORB_DEFAULT, ORB_1500_13_1, \
AKAZE_DEFAULT, AKAZE_DESCRIPTOR_KAZE, \
BRISK_DEFAULT, \
KAZE_DEFAULT
KAZE_DEFAULT, \
SIFT_DEFAULT
#define CV_ENUM_EXPAND(name, ...) CV_ENUM(name, __VA_ARGS__)
@@ -77,6 +78,8 @@ static inline Ptr<Feature2D> getFeature2D(Feature2DType type)
return KAZE::create();
case MSER_DEFAULT:
return MSER::create();
case SIFT_DEFAULT:
return SIFT::create();
default:
return Ptr<Feature2D>();
}
-85
View File
@@ -1,85 +0,0 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
namespace opencv_test { namespace {
typedef perf::TestBaseWithParam<std::string> SIFT_detect;
typedef perf::TestBaseWithParam<std::string> SIFT_extract;
typedef perf::TestBaseWithParam<std::string> SIFT_full;
#define SIFT_IMAGES \
"cv/detectors_descriptors_evaluation/images_datasets/leuven/img1.png",\
"stitching/a3.png"
PERF_TEST_P_(SIFT_detect, SIFT)
{
string filename = getDataPath(GetParam());
Mat frame = imread(filename, IMREAD_GRAYSCALE);
ASSERT_FALSE(frame.empty()) << "Unable to load source image " << filename;
Mat mask;
declare.in(frame).time(90);
Ptr<SIFT> detector = SIFT::create();
vector<KeyPoint> points;
PERF_SAMPLE_BEGIN();
detector->detect(frame, points, mask);
PERF_SAMPLE_END();
SANITY_CHECK_NOTHING();
}
PERF_TEST_P_(SIFT_extract, SIFT)
{
string filename = getDataPath(GetParam());
Mat frame = imread(filename, IMREAD_GRAYSCALE);
ASSERT_FALSE(frame.empty()) << "Unable to load source image " << filename;
Mat mask;
declare.in(frame).time(90);
Ptr<SIFT> detector = SIFT::create();
vector<KeyPoint> points;
Mat descriptors;
detector->detect(frame, points, mask);
PERF_SAMPLE_BEGIN();
detector->compute(frame, points, descriptors);
PERF_SAMPLE_END();
SANITY_CHECK_NOTHING();
}
PERF_TEST_P_(SIFT_full, SIFT)
{
string filename = getDataPath(GetParam());
Mat frame = imread(filename, IMREAD_GRAYSCALE);
ASSERT_FALSE(frame.empty()) << "Unable to load source image " << filename;
Mat mask;
declare.in(frame).time(90);
Ptr<SIFT> detector = SIFT::create();
vector<KeyPoint> points;
Mat descriptors;
PERF_SAMPLE_BEGIN();
detector->detectAndCompute(frame, mask, points, descriptors, false);
PERF_SAMPLE_END();
SANITY_CHECK_NOTHING();
}
INSTANTIATE_TEST_CASE_P(/*nothing*/, SIFT_detect,
testing::Values(SIFT_IMAGES)
);
INSTANTIATE_TEST_CASE_P(/*nothing*/, SIFT_extract,
testing::Values(SIFT_IMAGES)
);
INSTANTIATE_TEST_CASE_P(/*nothing*/, SIFT_full,
testing::Values(SIFT_IMAGES)
);
}} // namespace
+1 -1
View File
@@ -257,7 +257,7 @@ void SimpleBlobDetectorImpl::findBlobs(InputArray _image, InputArray _binaryImag
{
std::vector < Point > hull;
convexHull(contours[contourIdx], hull);
double area = contourArea(contours[contourIdx]);
double area = moms.m00;
double hullArea = contourArea(hull);
if (fabs(hullArea) < DBL_EPSILON)
continue;
+10 -5
View File
@@ -622,15 +622,20 @@ void DescriptorMatcher::checkMasks( InputArrayOfArrays _masks, int queryDescript
if( isMaskSupported() && !masks.empty() )
{
// Check masks
size_t imageCount = std::max(trainDescCollection.size(), utrainDescCollection.size() );
const size_t imageCount = std::max(trainDescCollection.size(), utrainDescCollection.size() );
CV_Assert( masks.size() == imageCount );
for( size_t i = 0; i < imageCount; i++ )
{
if( !masks[i].empty() && (!trainDescCollection[i].empty() || !utrainDescCollection[i].empty() ) )
if (masks[i].empty())
continue;
const bool hasTrainDesc = !trainDescCollection.empty() && !trainDescCollection[i].empty();
const bool hasUTrainDesc = !utrainDescCollection.empty() && !utrainDescCollection[i].empty();
if (hasTrainDesc || hasUTrainDesc)
{
int rows = trainDescCollection[i].empty() ? utrainDescCollection[i].rows : trainDescCollection[i].rows;
CV_Assert( masks[i].rows == queryDescriptorsCount &&
masks[i].cols == rows && masks[i].type() == CV_8UC1);
const int rows = hasTrainDesc ? trainDescCollection[i].rows : utrainDescCollection[i].rows;
CV_Assert(masks[i].type() == CV_8UC1
&& masks[i].rows == queryDescriptorsCount
&& masks[i].cols == rows);
}
}
}
+5
View File
@@ -126,6 +126,11 @@ Ptr<SIFT> SIFT::create( int _nfeatures, int _nOctaveLayers,
return makePtr<SIFT_Impl>(_nfeatures, _nOctaveLayers, _contrastThreshold, _edgeThreshold, _sigma);
}
String SIFT::getDefaultName() const
{
return (Feature2D::getDefaultName() + ".SIFT");
}
static inline void
unpackOctave(const KeyPoint& kpt, int& octave, int& layer, float& scale)
{
+114 -155
View File
@@ -73,6 +73,7 @@
#include <opencv2/core/hal/hal.hpp>
#include "opencv2/core/hal/intrin.hpp"
#include <opencv2/core/utils/buffer_area.private.hpp>
namespace cv {
@@ -167,9 +168,17 @@ float calcOrientationHist(
int i, j, k, len = (radius*2+1)*(radius*2+1);
float expf_scale = -1.f/(2.f * sigma * sigma);
AutoBuffer<float> buf(len*4 + n+4);
float *X = buf.data(), *Y = X + len, *Mag = X, *Ori = Y + len, *W = Ori + len;
float* temphist = W + len + 2;
cv::utils::BufferArea area;
float *X = 0, *Y = 0, *Mag, *Ori = 0, *W = 0, *temphist = 0;
area.allocate(X, len, CV_SIMD_WIDTH);
area.allocate(Y, len, CV_SIMD_WIDTH);
area.allocate(Ori, len, CV_SIMD_WIDTH);
area.allocate(W, len, CV_SIMD_WIDTH);
area.allocate(temphist, n+4, CV_SIMD_WIDTH);
area.commit();
temphist += 2;
Mag = X;
for( i = 0; i < n; i++ )
temphist[i] = 0.f;
@@ -201,32 +210,29 @@ float calcOrientationHist(
cv::hal::magnitude32f(X, Y, Mag, len);
k = 0;
#if CV_AVX2
#if CV_SIMD
const int vecsize = v_float32::nlanes;
v_float32 nd360 = vx_setall_f32(n/360.f);
v_int32 __n = vx_setall_s32(n);
int CV_DECL_ALIGNED(CV_SIMD_WIDTH) bin_buf[vecsize];
float CV_DECL_ALIGNED(CV_SIMD_WIDTH) w_mul_mag_buf[vecsize];
for( ; k <= len - vecsize; k += vecsize )
{
__m256 __nd360 = _mm256_set1_ps(n/360.f);
__m256i __n = _mm256_set1_epi32(n);
int CV_DECL_ALIGNED(32) bin_buf[8];
float CV_DECL_ALIGNED(32) w_mul_mag_buf[8];
for ( ; k <= len - 8; k+=8 )
v_float32 w = vx_load_aligned( W + k );
v_float32 mag = vx_load_aligned( Mag + k );
v_float32 ori = vx_load_aligned( Ori + k );
v_int32 bin = v_round( nd360 * ori );
bin = v_select(bin >= __n, bin - __n, bin);
bin = v_select(bin < vx_setzero_s32(), bin + __n, bin);
w = w * mag;
v_store_aligned(bin_buf, bin);
v_store_aligned(w_mul_mag_buf, w);
for(int vi = 0; vi < vecsize; vi++)
{
__m256i __bin = _mm256_cvtps_epi32(_mm256_mul_ps(__nd360, _mm256_loadu_ps(&Ori[k])));
__bin = _mm256_sub_epi32(__bin, _mm256_andnot_si256(_mm256_cmpgt_epi32(__n, __bin), __n));
__bin = _mm256_add_epi32(__bin, _mm256_and_si256(__n, _mm256_cmpgt_epi32(_mm256_setzero_si256(), __bin)));
__m256 __w_mul_mag = _mm256_mul_ps(_mm256_loadu_ps(&W[k]), _mm256_loadu_ps(&Mag[k]));
_mm256_store_si256((__m256i *) bin_buf, __bin);
_mm256_store_ps(w_mul_mag_buf, __w_mul_mag);
temphist[bin_buf[0]] += w_mul_mag_buf[0];
temphist[bin_buf[1]] += w_mul_mag_buf[1];
temphist[bin_buf[2]] += w_mul_mag_buf[2];
temphist[bin_buf[3]] += w_mul_mag_buf[3];
temphist[bin_buf[4]] += w_mul_mag_buf[4];
temphist[bin_buf[5]] += w_mul_mag_buf[5];
temphist[bin_buf[6]] += w_mul_mag_buf[6];
temphist[bin_buf[7]] += w_mul_mag_buf[7];
temphist[bin_buf[vi]] += w_mul_mag_buf[vi];
}
}
#endif
@@ -247,34 +253,20 @@ float calcOrientationHist(
temphist[n+1] = temphist[1];
i = 0;
#if CV_AVX2
#if CV_SIMD
v_float32 d_1_16 = vx_setall_f32(1.f/16.f);
v_float32 d_4_16 = vx_setall_f32(4.f/16.f);
v_float32 d_6_16 = vx_setall_f32(6.f/16.f);
for( ; i <= n - v_float32::nlanes; i += v_float32::nlanes )
{
__m256 __d_1_16 = _mm256_set1_ps(1.f/16.f);
__m256 __d_4_16 = _mm256_set1_ps(4.f/16.f);
__m256 __d_6_16 = _mm256_set1_ps(6.f/16.f);
for( ; i <= n - 8; i+=8 )
{
#if CV_FMA3
__m256 __hist = _mm256_fmadd_ps(
_mm256_add_ps(_mm256_loadu_ps(&temphist[i-2]), _mm256_loadu_ps(&temphist[i+2])),
__d_1_16,
_mm256_fmadd_ps(
_mm256_add_ps(_mm256_loadu_ps(&temphist[i-1]), _mm256_loadu_ps(&temphist[i+1])),
__d_4_16,
_mm256_mul_ps(_mm256_loadu_ps(&temphist[i]), __d_6_16)));
#else
__m256 __hist = _mm256_add_ps(
_mm256_mul_ps(
_mm256_add_ps(_mm256_loadu_ps(&temphist[i-2]), _mm256_loadu_ps(&temphist[i+2])),
__d_1_16),
_mm256_add_ps(
_mm256_mul_ps(
_mm256_add_ps(_mm256_loadu_ps(&temphist[i-1]), _mm256_loadu_ps(&temphist[i+1])),
__d_4_16),
_mm256_mul_ps(_mm256_loadu_ps(&temphist[i]), __d_6_16)));
#endif
_mm256_storeu_ps(&hist[i], __hist);
}
v_float32 tn2 = vx_load_aligned(temphist + i-2);
v_float32 tn1 = vx_load(temphist + i-1);
v_float32 t0 = vx_load(temphist + i);
v_float32 t1 = vx_load(temphist + i+1);
v_float32 t2 = vx_load(temphist + i+2);
v_float32 _hist = v_fma(tn2 + t2, d_1_16,
v_fma(tn1 + t1, d_4_16, t0 * d_6_16));
v_store(hist + i, _hist);
}
#endif
for( ; i < n; i++ )
@@ -623,91 +615,65 @@ void calcSIFTDescriptor(
cv::hal::exp32f(W, W, len);
k = 0;
#if CV_AVX2
#if CV_SIMD
{
int CV_DECL_ALIGNED(32) idx_buf[8];
float CV_DECL_ALIGNED(32) rco_buf[64];
const __m256 __ori = _mm256_set1_ps(ori);
const __m256 __bins_per_rad = _mm256_set1_ps(bins_per_rad);
const __m256i __n = _mm256_set1_epi32(n);
for( ; k <= len - 8; k+=8 )
const int vecsize = v_float32::nlanes;
int CV_DECL_ALIGNED(CV_SIMD_WIDTH) idx_buf[vecsize];
float CV_DECL_ALIGNED(CV_SIMD_WIDTH) rco_buf[8*vecsize];
const v_float32 __ori = vx_setall_f32(ori);
const v_float32 __bins_per_rad = vx_setall_f32(bins_per_rad);
const v_int32 __n = vx_setall_s32(n);
const v_int32 __1 = vx_setall_s32(1);
const v_int32 __d_plus_2 = vx_setall_s32(d+2);
const v_int32 __n_plus_2 = vx_setall_s32(n+2);
for( ; k <= len - vecsize; k += vecsize )
{
__m256 __rbin = _mm256_loadu_ps(&RBin[k]);
__m256 __cbin = _mm256_loadu_ps(&CBin[k]);
__m256 __obin = _mm256_mul_ps(_mm256_sub_ps(_mm256_loadu_ps(&Ori[k]), __ori), __bins_per_rad);
__m256 __mag = _mm256_mul_ps(_mm256_loadu_ps(&Mag[k]), _mm256_loadu_ps(&W[k]));
v_float32 rbin = vx_load(RBin + k);
v_float32 cbin = vx_load(CBin + k);
v_float32 obin = (vx_load(Ori + k) - __ori) * __bins_per_rad;
v_float32 mag = vx_load(Mag + k) * vx_load(W + k);
__m256 __r0 = _mm256_floor_ps(__rbin);
__rbin = _mm256_sub_ps(__rbin, __r0);
__m256 __c0 = _mm256_floor_ps(__cbin);
__cbin = _mm256_sub_ps(__cbin, __c0);
__m256 __o0 = _mm256_floor_ps(__obin);
__obin = _mm256_sub_ps(__obin, __o0);
v_int32 r0 = v_floor(rbin);
v_int32 c0 = v_floor(cbin);
v_int32 o0 = v_floor(obin);
rbin -= v_cvt_f32(r0);
cbin -= v_cvt_f32(c0);
obin -= v_cvt_f32(o0);
__m256i __o0i = _mm256_cvtps_epi32(__o0);
__o0i = _mm256_add_epi32(__o0i, _mm256_and_si256(__n, _mm256_cmpgt_epi32(_mm256_setzero_si256(), __o0i)));
__o0i = _mm256_sub_epi32(__o0i, _mm256_andnot_si256(_mm256_cmpgt_epi32(__n, __o0i), __n));
o0 = v_select(o0 < vx_setzero_s32(), o0 + __n, o0);
o0 = v_select(o0 >= __n, o0 - __n, o0);
__m256 __v_r1 = _mm256_mul_ps(__mag, __rbin);
__m256 __v_r0 = _mm256_sub_ps(__mag, __v_r1);
v_float32 v_r1 = mag*rbin, v_r0 = mag - v_r1;
v_float32 v_rc11 = v_r1*cbin, v_rc10 = v_r1 - v_rc11;
v_float32 v_rc01 = v_r0*cbin, v_rc00 = v_r0 - v_rc01;
v_float32 v_rco111 = v_rc11*obin, v_rco110 = v_rc11 - v_rco111;
v_float32 v_rco101 = v_rc10*obin, v_rco100 = v_rc10 - v_rco101;
v_float32 v_rco011 = v_rc01*obin, v_rco010 = v_rc01 - v_rco011;
v_float32 v_rco001 = v_rc00*obin, v_rco000 = v_rc00 - v_rco001;
__m256 __v_rc11 = _mm256_mul_ps(__v_r1, __cbin);
__m256 __v_rc10 = _mm256_sub_ps(__v_r1, __v_rc11);
v_int32 idx = v_muladd(v_muladd(r0+__1, __d_plus_2, c0+__1), __n_plus_2, o0);
v_store_aligned(idx_buf, idx);
__m256 __v_rc01 = _mm256_mul_ps(__v_r0, __cbin);
__m256 __v_rc00 = _mm256_sub_ps(__v_r0, __v_rc01);
v_store_aligned(rco_buf, v_rco000);
v_store_aligned(rco_buf+vecsize, v_rco001);
v_store_aligned(rco_buf+vecsize*2, v_rco010);
v_store_aligned(rco_buf+vecsize*3, v_rco011);
v_store_aligned(rco_buf+vecsize*4, v_rco100);
v_store_aligned(rco_buf+vecsize*5, v_rco101);
v_store_aligned(rco_buf+vecsize*6, v_rco110);
v_store_aligned(rco_buf+vecsize*7, v_rco111);
__m256 __v_rco111 = _mm256_mul_ps(__v_rc11, __obin);
__m256 __v_rco110 = _mm256_sub_ps(__v_rc11, __v_rco111);
__m256 __v_rco101 = _mm256_mul_ps(__v_rc10, __obin);
__m256 __v_rco100 = _mm256_sub_ps(__v_rc10, __v_rco101);
__m256 __v_rco011 = _mm256_mul_ps(__v_rc01, __obin);
__m256 __v_rco010 = _mm256_sub_ps(__v_rc01, __v_rco011);
__m256 __v_rco001 = _mm256_mul_ps(__v_rc00, __obin);
__m256 __v_rco000 = _mm256_sub_ps(__v_rc00, __v_rco001);
__m256i __one = _mm256_set1_epi32(1);
__m256i __idx = _mm256_add_epi32(
_mm256_mullo_epi32(
_mm256_add_epi32(
_mm256_mullo_epi32(_mm256_add_epi32(_mm256_cvtps_epi32(__r0), __one), _mm256_set1_epi32(d + 2)),
_mm256_add_epi32(_mm256_cvtps_epi32(__c0), __one)),
_mm256_set1_epi32(n + 2)),
__o0i);
_mm256_store_si256((__m256i *)idx_buf, __idx);
_mm256_store_ps(&(rco_buf[0]), __v_rco000);
_mm256_store_ps(&(rco_buf[8]), __v_rco001);
_mm256_store_ps(&(rco_buf[16]), __v_rco010);
_mm256_store_ps(&(rco_buf[24]), __v_rco011);
_mm256_store_ps(&(rco_buf[32]), __v_rco100);
_mm256_store_ps(&(rco_buf[40]), __v_rco101);
_mm256_store_ps(&(rco_buf[48]), __v_rco110);
_mm256_store_ps(&(rco_buf[56]), __v_rco111);
#define HIST_SUM_HELPER(id) \
hist[idx_buf[(id)]] += rco_buf[(id)]; \
hist[idx_buf[(id)]+1] += rco_buf[8 + (id)]; \
hist[idx_buf[(id)]+(n+2)] += rco_buf[16 + (id)]; \
hist[idx_buf[(id)]+(n+3)] += rco_buf[24 + (id)]; \
hist[idx_buf[(id)]+(d+2)*(n+2)] += rco_buf[32 + (id)]; \
hist[idx_buf[(id)]+(d+2)*(n+2)+1] += rco_buf[40 + (id)]; \
hist[idx_buf[(id)]+(d+3)*(n+2)] += rco_buf[48 + (id)]; \
hist[idx_buf[(id)]+(d+3)*(n+2)+1] += rco_buf[56 + (id)];
HIST_SUM_HELPER(0);
HIST_SUM_HELPER(1);
HIST_SUM_HELPER(2);
HIST_SUM_HELPER(3);
HIST_SUM_HELPER(4);
HIST_SUM_HELPER(5);
HIST_SUM_HELPER(6);
HIST_SUM_HELPER(7);
#undef HIST_SUM_HELPER
for(int id = 0; id < vecsize; id++)
{
hist[idx_buf[id]] += rco_buf[id];
hist[idx_buf[id]+1] += rco_buf[vecsize + id];
hist[idx_buf[id]+(n+2)] += rco_buf[2*vecsize + id];
hist[idx_buf[id]+(n+3)] += rco_buf[3*vecsize + id];
hist[idx_buf[id]+(d+2)*(n+2)] += rco_buf[4*vecsize + id];
hist[idx_buf[id]+(d+2)*(n+2)+1] += rco_buf[5*vecsize + id];
hist[idx_buf[id]+(d+3)*(n+2)] += rco_buf[6*vecsize + id];
hist[idx_buf[id]+(d+3)*(n+2)+1] += rco_buf[7*vecsize + id];
}
}
}
#endif
@@ -766,23 +732,16 @@ void calcSIFTDescriptor(
float nrm2 = 0;
len = d*d*n;
k = 0;
#if CV_AVX2
#if CV_SIMD
{
float CV_DECL_ALIGNED(32) nrm2_buf[8];
__m256 __nrm2 = _mm256_setzero_ps();
__m256 __dst;
for( ; k <= len - 8; k += 8 )
v_float32 __nrm2 = vx_setzero_f32();
v_float32 __dst;
for( ; k <= len - v_float32::nlanes; k += v_float32::nlanes )
{
__dst = _mm256_loadu_ps(&dst[k]);
#if CV_FMA3
__nrm2 = _mm256_fmadd_ps(__dst, __dst, __nrm2);
#else
__nrm2 = _mm256_add_ps(__nrm2, _mm256_mul_ps(__dst, __dst));
#endif
__dst = vx_load(dst + k);
__nrm2 = v_fma(__dst, __dst, __nrm2);
}
_mm256_store_ps(nrm2_buf, __nrm2);
nrm2 = nrm2_buf[0] + nrm2_buf[1] + nrm2_buf[2] + nrm2_buf[3] +
nrm2_buf[4] + nrm2_buf[5] + nrm2_buf[6] + nrm2_buf[7];
nrm2 = (float)v_reduce_sum(__nrm2);
}
#endif
for( ; k < len; k++ )
@@ -795,7 +754,7 @@ void calcSIFTDescriptor(
// This code cannot be enabled because it sums nrm2 in a different order,
// thus producing slightly different results
{
float CV_DECL_ALIGNED(32) nrm2_buf[8];
float CV_DECL_ALIGNED(CV_SIMD_WIDTH) nrm2_buf[8];
__m256 __dst;
__m256 __nrm2 = _mm256_setzero_ps();
__m256 __thr = _mm256_set1_ps(thr);
@@ -825,17 +784,17 @@ void calcSIFTDescriptor(
#if 1
k = 0;
#if CV_AVX2
#if CV_SIMD
{
__m256 __dst;
__m256 __min = _mm256_setzero_ps();
__m256 __max = _mm256_set1_ps(255.0f); // max of uchar
__m256 __nrm2 = _mm256_set1_ps(nrm2);
for( k = 0; k <= len - 8; k+=8 )
v_float32 __dst;
v_float32 __min = vx_setzero_f32();
v_float32 __max = vx_setall_f32(255.0f); // max of uchar
v_float32 __nrm2 = vx_setall_f32(nrm2);
for( k = 0; k <= len - v_float32::nlanes; k += v_float32::nlanes )
{
__dst = _mm256_loadu_ps(&dst[k]);
__dst = _mm256_min_ps(_mm256_max_ps(_mm256_round_ps(_mm256_mul_ps(__dst, __nrm2), _MM_FROUND_TO_NEAREST_INT |_MM_FROUND_NO_EXC), __min), __max);
_mm256_storeu_ps(&dst[k], __dst);
__dst = vx_load(dst + k);
__dst = v_min(v_max(v_cvt_f32(v_round(__dst * __nrm2)), __min), __max);
v_store(dst + k, __dst);
}
}
#endif
@@ -15,6 +15,26 @@ const static std::string IMAGE_TSUKUBA = "features2d/tsukuba.png";
const static std::string IMAGE_BIKES = "detectors_descriptors_evaluation/images_datasets/bikes/img1.png";
#define Value(...) Values(String_FeatureDetector_DescriptorExtractor_Float_t(__VA_ARGS__))
static
void SetSuitableSIFTOctave(vector<KeyPoint>& keypoints,
int firstOctave = -1, int nOctaveLayers = 3, double sigma = 1.6)
{
for (size_t i = 0; i < keypoints.size(); i++ )
{
int octv, layer;
KeyPoint& kpt = keypoints[i];
double octv_layer = std::log(kpt.size / sigma) / std::log(2.) - 1;
octv = cvFloor(octv_layer);
layer = cvRound( (octv_layer - octv) * nOctaveLayers );
if (octv < firstOctave)
{
octv = firstOctave;
layer = 0;
}
kpt.octave = (layer << 8) | (octv & 255);
}
}
static
void rotateKeyPoints(const vector<KeyPoint>& src, const Mat& H, float angle, vector<KeyPoint>& dst)
{
@@ -132,6 +152,10 @@ TEST_P(DescriptorScaleInvariance, scale)
vector<KeyPoint> keypoints1;
scaleKeyPoints(keypoints0, keypoints1, 1.0f/scale);
if (featureDetector->getDefaultName() == "Feature2D.SIFT")
{
SetSuitableSIFTOctave(keypoints1);
}
Mat descriptors1;
descriptorExtractor->compute(image1, keypoints1, descriptors1);
@@ -186,9 +210,8 @@ INSTANTIATE_TEST_CASE_P(AKAZE_DESCRIPTOR_KAZE, DescriptorRotationInvariance,
* Descriptor's scale invariance check
*/
// TODO: Expected: (descInliersRatio) >= (minInliersRatio), actual: 0.330378 vs 0.78
INSTANTIATE_TEST_CASE_P(DISABLED_SIFT, DescriptorScaleInvariance,
Value(IMAGE_BIKES, SIFT::create(), SIFT::create(), 0.78f));
INSTANTIATE_TEST_CASE_P(SIFT, DescriptorScaleInvariance,
Value(IMAGE_BIKES, SIFT::create(0, 3, 0.09), SIFT::create(0, 3, 0.09), 0.78f));
INSTANTIATE_TEST_CASE_P(AKAZE, DescriptorScaleInvariance,
Value(IMAGE_BIKES, AKAZE::create(), AKAZE::create(), 0.6f));
@@ -29,7 +29,6 @@ void matchKeyPoints(const vector<KeyPoint>& keypoints0, const Mat& H,
perspectiveTransform(Mat(points0), points0t, H);
matches.clear();
vector<uchar> usedMask(keypoints1.size(), 0);
for(int i0 = 0; i0 < static_cast<int>(keypoints0.size()); i0++)
{
int nearestPointIndex = -1;
@@ -37,8 +36,6 @@ void matchKeyPoints(const vector<KeyPoint>& keypoints0, const Mat& H,
const float r0 = 0.5f * keypoints0[i0].size;
for(size_t i1 = 0; i1 < keypoints1.size(); i1++)
{
if(nearestPointIndex >= 0 && usedMask[i1])
continue;
float r1 = 0.5f * keypoints1[i1].size;
float intersectRatio = calcIntersectRatio(points0t.at<Point2f>(i0), r0,
@@ -51,8 +48,6 @@ void matchKeyPoints(const vector<KeyPoint>& keypoints0, const Mat& H,
}
matches.push_back(DMatch(i0, nearestPointIndex, maxIntersectRatio));
if(nearestPointIndex >= 0)
usedMask[nearestPointIndex] = 1;
}
}
@@ -239,9 +234,8 @@ INSTANTIATE_TEST_CASE_P(AKAZE_DESCRIPTOR_KAZE, DetectorRotationInvariance,
* Detector's scale invariance check
*/
// TODO: Expected: (keyPointMatchesRatio) >= (minKeyPointMatchesRatio), actual: 0.596752 vs 0.69
INSTANTIATE_TEST_CASE_P(DISABLED_SIFT, DetectorScaleInvariance,
Value(IMAGE_BIKES, SIFT::create(), 0.69f, 0.98f));
INSTANTIATE_TEST_CASE_P(SIFT, DetectorScaleInvariance,
Value(IMAGE_BIKES, SIFT::create(0, 3, 0.09), 0.69f, 0.98f));
INSTANTIATE_TEST_CASE_P(BRISK, DetectorScaleInvariance,
Value(IMAGE_BIKES, BRISK::create(), 0.08f, 0.49f));
@@ -565,7 +565,6 @@ TEST(Features2d_DMatch, issue_11855)
1, 1, 1);
Mat targets = (Mat_<uchar>(2, 3) << 1, 1, 1,
0, 0, 0);
Ptr<BFMatcher> bf = BFMatcher::create(NORM_HAMMING, true);
vector<vector<DMatch> > match;
bf->knnMatch(sources, targets, match, 1, noArray(), true);
@@ -577,4 +576,18 @@ TEST(Features2d_DMatch, issue_11855)
EXPECT_EQ(0.0f, match[0][0].distance);
}
TEST(Features2d_DMatch, issue_17771)
{
Mat sources = (Mat_<uchar>(2, 3) << 1, 1, 0,
1, 1, 1);
Mat targets = (Mat_<uchar>(2, 3) << 1, 1, 1,
0, 0, 0);
UMat usources = sources.getUMat(ACCESS_READ);
UMat utargets = targets.getUMat(ACCESS_READ);
vector<vector<DMatch> > match;
Ptr<BFMatcher> ubf = BFMatcher::create(NORM_HAMMING);
Mat mask = (Mat_<uchar>(2, 2) << 1, 0, 0, 1);
EXPECT_NO_THROW(ubf->knnMatch(usources, utargets, match, 1, mask, true));
}
}} // namespace
+4 -4
View File
@@ -536,7 +536,7 @@ private:
@param features The points to be clustered. The matrix must have elements of type
Distance::ElementType.
@param centers The centers of the clusters obtained. The matrix must have type
Distance::ResultType. The number of rows in this matrix represents the number of clusters desired,
Distance::CentersType. The number of rows in this matrix represents the number of clusters desired,
however, because of the way the cut in the hierarchical tree is chosen, the number of clusters
computed will be the highest number of the form (branching-1)\*k+1 that's lower than the number of
clusters desired, where branching is the tree's branching factor (see description of the
@@ -553,15 +553,15 @@ int hierarchicalClustering(const Mat& features, Mat& centers, const ::cvflann::K
Distance d = Distance())
{
typedef typename Distance::ElementType ElementType;
typedef typename Distance::ResultType DistanceType;
typedef typename Distance::CentersType CentersType;
CV_Assert(features.type() == CvType<ElementType>::type());
CV_Assert(features.isContinuous());
::cvflann::Matrix<ElementType> m_features((ElementType*)features.ptr<ElementType>(0), features.rows, features.cols);
CV_Assert(centers.type() == CvType<DistanceType>::type());
CV_Assert(centers.type() == CvType<CentersType>::type());
CV_Assert(centers.isContinuous());
::cvflann::Matrix<DistanceType> m_centers((DistanceType*)centers.ptr<DistanceType>(0), centers.rows, centers.cols);
::cvflann::Matrix<CentersType> m_centers((CentersType*)centers.ptr<CentersType>(0), centers.rows, centers.cols);
return ::cvflann::hierarchicalClustering<Distance>(m_features, m_centers, params, d);
}
@@ -130,6 +130,9 @@ struct index_creator<False,False,Distance>
case FLANN_INDEX_LINEAR:
nnIndex = new LinearIndex<Distance>(dataset, params, distance);
break;
case FLANN_INDEX_KMEANS:
nnIndex = new KMeansIndex<Distance>(dataset, params, distance);
break;
case FLANN_INDEX_HIERARCHICAL:
nnIndex = new HierarchicalClusteringIndex<Distance>(dataset, params, distance);
break;
@@ -497,7 +497,7 @@ private:
const int nn = 1;
const size_t SAMPLE_COUNT = 1000;
assert(bestIndex_ != NULL); // must have a valid index
CV_Assert(bestIndex_ != NULL && "Requires a valid index"); // must have a valid index
float speedup = 0;

Some files were not shown because too many files have changed in this diff Show More