mirror of
https://github.com/opencv/opencv.git
synced 2026-07-23 04:13:04 +04:00
Compare commits
5548 Commits
3.0.0-beta
...
3.2.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 70bbf17b13 | |||
| 0bd68671bd | |||
| d0f883524e | |||
| ad74fdd7cc | |||
| ce06fbdf77 | |||
| 090c46eca2 | |||
| dc31ddc80a | |||
| ca6beb9ca8 | |||
| be7d060ea4 | |||
| b3900c5dfe | |||
| a4db9833f7 | |||
| ece08374a1 | |||
| c64ac42b27 | |||
| 01de65c2e9 | |||
| 8d6500be20 | |||
| 0d32bec5c3 | |||
| 2312131e27 | |||
| bbfbdd9da1 | |||
| ccd32f6608 | |||
| d85c11e525 | |||
| 3e1695d6e3 | |||
| 2638abe12b | |||
| 86bb523991 | |||
| 5a07e102fa | |||
| ae9f80c1a9 | |||
| 35308bc45f | |||
| 07004a46ca | |||
| d71ec0cd1d | |||
| 85e01f3ffe | |||
| dd482c6a29 | |||
| 9e57d1ae34 | |||
| 6a537e3986 | |||
| 328151c8a4 | |||
| fcdbe16252 | |||
| de059567d7 | |||
| ef08110182 | |||
| 862c3aa6e1 | |||
| c9237a6f48 | |||
| 13b9dd3963 | |||
| 0a4694d6e0 | |||
| 0e4dde1781 | |||
| d2e5bea1fb | |||
| c7ae26bf24 | |||
| a206e12174 | |||
| cf5e976fad | |||
| a2646062b2 | |||
| 1e2ad7e3e3 | |||
| ee77538cf9 | |||
| 3f1734bbc7 | |||
| 77f99358df | |||
| 5f4112a1cf | |||
| 75eeb25c1e | |||
| 8444c23803 | |||
| 969c55da58 | |||
| c038d1be60 | |||
| faefbf93bc | |||
| 5372c8b331 | |||
| 9c7088d95f | |||
| a615d79f2d | |||
| f7d956ea3e | |||
| 22df206e1f | |||
| b06bd50144 | |||
| cc09f5a7de | |||
| 49e6bb2993 | |||
| 667cb2e9fc | |||
| bfde5cdde0 | |||
| eb04b2bfa9 | |||
| a8c7a1029e | |||
| 7d5fd6a800 | |||
| 041502e42c | |||
| 737fa519d1 | |||
| ceb5210bfb | |||
| dbbbad40fb | |||
| 540ece74a5 | |||
| 3fc06f14d4 | |||
| d206e84a13 | |||
| 03beff06ff | |||
| 6d34d6b47e | |||
| fcddfa4f86 | |||
| 45d3286168 | |||
| 4e7b521438 | |||
| fa6692afcf | |||
| 36b5abf6b7 | |||
| 059c2a8328 | |||
| daa97021bd | |||
| 8b9422a052 | |||
| f5bf1e510b | |||
| 5592142511 | |||
| 3c5eb513dd | |||
| f8b4d28745 | |||
| 138f0cbf3c | |||
| 53f72f18f5 | |||
| 965deaba8d | |||
| 8b92151ef0 | |||
| 7db13c7aab | |||
| af0ee306cf | |||
| 1451f7d0ec | |||
| 19c8cc8f13 | |||
| 8f83d97adc | |||
| c977af8ee8 | |||
| dd99b7c1cb | |||
| 7241b90dec | |||
| 2c89b39eee | |||
| a24ebc9952 | |||
| 7a3b5b308c | |||
| fbf2383d5d | |||
| cb1d4e692b | |||
| 188ccac2f3 | |||
| 069d51d23b | |||
| 1473f032b7 | |||
| 166d75e3c5 | |||
| 12383a124b | |||
| ffcf866e2f | |||
| 34c07f6aaf | |||
| ec859ceb2c | |||
| 3aedc134c2 | |||
| fb223784a6 | |||
| 03bcfe4107 | |||
| 21683a550a | |||
| a5d857eda8 | |||
| 3f7cde0485 | |||
| 120531cb46 | |||
| 4a3da1c4ed | |||
| 7bceef715c | |||
| 26fbaada0a | |||
| 2fded5d8fb | |||
| 5f57d0295e | |||
| f55e966210 | |||
| c98330b2d1 | |||
| c447e5f615 | |||
| a93c70f533 | |||
| a99118c4c7 | |||
| 4246d3667f | |||
| 76c38f0c80 | |||
| f3ec56fcee | |||
| 541d5b02d9 | |||
| ccd8031a33 | |||
| 1e2ddc30b1 | |||
| 98181e9d7f | |||
| 7e0f1ec00a | |||
| bcbe2f123f | |||
| 781ab3d481 | |||
| beea04cc89 | |||
| 48bff3bfd3 | |||
| a1d68ff361 | |||
| 5cc2d7ad7c | |||
| 6946f510fe | |||
| e941259434 | |||
| 036dd8d48f | |||
| ee265962b2 | |||
| 79857f1e38 | |||
| c4d4158bd8 | |||
| 62c9ff25e5 | |||
| ab429d2e73 | |||
| 21f3531b17 | |||
| 7be4a0ee2f | |||
| 25727454d9 | |||
| 29f5294fd2 | |||
| cf97e6e00f | |||
| bc96997410 | |||
| 2341222672 | |||
| d37106e008 | |||
| c6af179afc | |||
| 300f92397e | |||
| ab260dafd2 | |||
| 10d1b33a80 | |||
| a05444618c | |||
| d42d155c16 | |||
| 61792a839f | |||
| 695b20172b | |||
| cb46946d34 | |||
| fef94315af | |||
| 2bfcbe1459 | |||
| 2d28bb4171 | |||
| 396921dd23 | |||
| bd0a8c7e3f | |||
| 37cbcf024c | |||
| 10ccd0328c | |||
| c48d7f86ba | |||
| fefc348040 | |||
| 0724d13bcd | |||
| 44d9d59f08 | |||
| 380cc520f3 | |||
| 4a095e4d66 | |||
| 5025ca497c | |||
| 5032dae9ed | |||
| a0e771f545 | |||
| b87cee8b9a | |||
| f84dc354f6 | |||
| 537db2d53f | |||
| 39ca6a0137 | |||
| afc7396975 | |||
| ced81f72bc | |||
| 49194023b5 | |||
| 025ceb4d27 | |||
| a09288c673 | |||
| 2e8b9b1891 | |||
| b69cdb2434 | |||
| 3ae1990727 | |||
| 735f5a01ec | |||
| 5e75503fc2 | |||
| 4f7453be86 | |||
| c99097f89a | |||
| b0d2217c65 | |||
| 1d45726f47 | |||
| e623e710be | |||
| 32f48a8d9c | |||
| 924ac10159 | |||
| 0a775e43e1 | |||
| 8968318dfc | |||
| ddc5155a85 | |||
| 39ff8a0d26 | |||
| 817a17b218 | |||
| 5985d71657 | |||
| 19959cbfc9 | |||
| b5b3a0474d | |||
| 695c518384 | |||
| e547bbbc3f | |||
| c560ff23ad | |||
| 47f53b675d | |||
| 46a333ed94 | |||
| e4985f604a | |||
| 5b85adaab1 | |||
| 45e18eed29 | |||
| 6d55e99291 | |||
| 179a6e0cca | |||
| 2ca5a7e862 | |||
| 71b2409df0 | |||
| 6c524e8444 | |||
| 3d8395cae9 | |||
| c47267ef7f | |||
| 57aaec1ee8 | |||
| 78b80b6abd | |||
| 0ac934d09a | |||
| 7c2734ff14 | |||
| 2b56b174e8 | |||
| 0a6958813c | |||
| a4b9eb23d1 | |||
| 0cd3788624 | |||
| e9cc0f6a4c | |||
| 9200db778c | |||
| e8f3469096 | |||
| 90b52cd9b8 | |||
| 159b29e9b1 | |||
| c56c0e140b | |||
| b72d196753 | |||
| 4a7d441b37 | |||
| be0865406f | |||
| 2af4dc7249 | |||
| 5cead19006 | |||
| 7e38a2f0bb | |||
| 2c03c8d71f | |||
| 35db7f67e0 | |||
| ff2747dff5 | |||
| e8f591143c | |||
| 32f568308a | |||
| 5ac15f09ed | |||
| 36d7712c2c | |||
| e5041abe55 | |||
| 90da593316 | |||
| e04eb8cc04 | |||
| fa757ebd92 | |||
| ac118aee78 | |||
| 954082d891 | |||
| f6d5a1dd2c | |||
| 1a3f1a31b2 | |||
| 3f37e34e76 | |||
| 56ed8b1721 | |||
| e878b60dbc | |||
| 8098e5b045 | |||
| 7dc673fd56 | |||
| a53f93ff8d | |||
| b38d29b2e4 | |||
| 7ad8e378ce | |||
| 11b642fb8c | |||
| 6fb75c677b | |||
| 4a759abe39 | |||
| 88ef8c996e | |||
| 979b0ae9ce | |||
| 408e4a7c27 | |||
| f5f91ed7f6 | |||
| e1503cc29e | |||
| 12e0bc0fe7 | |||
| 4c5c722939 | |||
| e69253a4fb | |||
| 4fd00c1ae1 | |||
| 7db43f9fff | |||
| b8c875d4a1 | |||
| da75d129fe | |||
| a3bfa6f566 | |||
| b879126584 | |||
| 8e22b17919 | |||
| 0bdea2b714 | |||
| 8019498c6e | |||
| fe29080d59 | |||
| d65df72754 | |||
| a936cb087e | |||
| 69949025db | |||
| 8d662a1a28 | |||
| 284006e336 | |||
| 8151be9abc | |||
| c1ee798213 | |||
| f89ea6d7fa | |||
| 1c9262dce4 | |||
| fa8add8686 | |||
| bfecea489e | |||
| d7db220196 | |||
| 289d879d48 | |||
| 2c63d2bd72 | |||
| e8d2aad978 | |||
| 9032a7ab81 | |||
| 5c969d1972 | |||
| af22b6c4a9 | |||
| b54bc2db1e | |||
| 81fc6b3fde | |||
| 3f224abb37 | |||
| 9638dfcd85 | |||
| af8e6b06f7 | |||
| 54d215902f | |||
| 511c0c2e71 | |||
| 7b13550bdd | |||
| 7adb52b427 | |||
| 9cdab426b1 | |||
| 62b2039040 | |||
| dfb9c574a4 | |||
| 771fa5b8ac | |||
| f21f153a5f | |||
| 3ea4f72e35 | |||
| fb456eb69c | |||
| 866f8eb1e7 | |||
| b1c8557401 | |||
| 0a543c5531 | |||
| a42be1f9bd | |||
| 19270eeab4 | |||
| 497d0fd2e7 | |||
| 21167b1bf1 | |||
| 39d7ecc93b | |||
| dac37a0bc9 | |||
| 30807b26c7 | |||
| 14d2046f80 | |||
| 30cdcfa554 | |||
| 40aa8aa862 | |||
| 12569dc730 | |||
| a19cb20b23 | |||
| 6cb73356b1 | |||
| e6f2729c7a | |||
| 1f1dc42534 | |||
| 7c266ffffe | |||
| 876c2c0efd | |||
| 4d041e6809 | |||
| c3f0ee0768 | |||
| cf5c400ecb | |||
| 4d84e6efee | |||
| a49e50a33b | |||
| e79f83e573 | |||
| 94b5a74067 | |||
| 8f4251fbfa | |||
| c93fb14dd2 | |||
| ad888c80cf | |||
| 099be88f02 | |||
| 5bb08bae28 | |||
| 8d4a7d3dcc | |||
| a909527a39 | |||
| 614ce7743e | |||
| a679e4ca7c | |||
| b587c57b2a | |||
| 6b7d570c34 | |||
| 6df723e42d | |||
| c3fc115551 | |||
| a88b94cc44 | |||
| 4ebdf4938a | |||
| 4f8c3d7d97 | |||
| 64a2d1904b | |||
| 879315f2fe | |||
| 24379fcb5f | |||
| 9eac0f0575 | |||
| 88ea9f5dd7 | |||
| 850d12ae69 | |||
| cd1b324e5e | |||
| ca1ce5fa5c | |||
| acaa1e1b29 | |||
| b2e0873af1 | |||
| a2d6d96ef1 | |||
| 67c404632a | |||
| 04ddbf565e | |||
| fddc9c5839 | |||
| cc121e06de | |||
| edcbc15a90 | |||
| a50bc7d824 | |||
| 40778fa30a | |||
| 4a9c84c570 | |||
| 3e0252ebcc | |||
| 45bf60d18c | |||
| a01a4c4b3b | |||
| bdf661538d | |||
| 26899bb345 | |||
| f893ee5cec | |||
| 3609343acf | |||
| 6991c24a27 | |||
| 17ffb28807 | |||
| 25061b4280 | |||
| f1d93cb23b | |||
| b2fa82ffcd | |||
| 183c75358b | |||
| d4b501e734 | |||
| 349d5ba012 | |||
| 8f63f51e81 | |||
| 442380bfac | |||
| 3e28d51779 | |||
| 35198b84a4 | |||
| 17df65e666 | |||
| d1bbc0b6e6 | |||
| 676736bdb2 | |||
| 3dc022ae84 | |||
| 712fa9a73c | |||
| ad5c50a923 | |||
| 280cdb5b94 | |||
| 9ee6f10896 | |||
| 6fceb1dd59 | |||
| 545f573a6c | |||
| bebd49d91b | |||
| 050731c4d2 | |||
| baf613bc5c | |||
| e955d17c51 | |||
| 38483fe7a7 | |||
| af01267f23 | |||
| 33d82da436 | |||
| f632f5c552 | |||
| 8944875258 | |||
| 94d879737b | |||
| 01f355dfaa | |||
| 7dd99258c7 | |||
| a7db950b66 | |||
| 6c12533160 | |||
| 811eb76277 | |||
| 6d460bb602 | |||
| 752b10e410 | |||
| 72e4e9d43d | |||
| 25f740ea5a | |||
| 62c28c5b92 | |||
| 049a894986 | |||
| 522cfa77b8 | |||
| d00dcb1b3a | |||
| f978ee613e | |||
| 78874c568e | |||
| 4c66772783 | |||
| 51f2b27bcb | |||
| c1c7c7f83e | |||
| 7fe0fb6be7 | |||
| 7b532cea89 | |||
| 2b7866f21b | |||
| b077d6a192 | |||
| 6f3483ade3 | |||
| 992795d47d | |||
| cba22349b7 | |||
| ecb8fb964d | |||
| bbd4a0eb51 | |||
| b823c8e95c | |||
| 7f2ac764ae | |||
| 358ec04413 | |||
| 56c133d459 | |||
| bec3479f9e | |||
| f888f47102 | |||
| 03a9fd46c7 | |||
| bdfb4decb2 | |||
| f0d592e6b6 | |||
| 76f28fd48f | |||
| c585d3890e | |||
| 33a5778a0e | |||
| 9b2b8404a0 | |||
| f07525031b | |||
| c93de78ff6 | |||
| ad6af6b9e4 | |||
| 41c47a84fc | |||
| d0474a9b81 | |||
| 8333ea41e2 | |||
| 5728f796f6 | |||
| 3607da9f6b | |||
| 689cf79625 | |||
| 118c1b4ace | |||
| 5ebdf6cedd | |||
| ddf0554fff | |||
| dc9602ee84 | |||
| c55890f637 | |||
| 34df4ae02a | |||
| 1f4f50b9dc | |||
| f5592fd21b | |||
| 2038434c7e | |||
| 2a91453ef1 | |||
| 6f7bf653f7 | |||
| de35c59ba4 | |||
| ecac70f120 | |||
| c17afe0fab | |||
| e77bc24b96 | |||
| c6772a8f5d | |||
| 44e5d26312 | |||
| c31f89f0de | |||
| f129950dec | |||
| c724d61219 | |||
| 17398c1e36 | |||
| 943ac96526 | |||
| 8842b9b2b2 | |||
| c57f145e90 | |||
| a901cc542b | |||
| 43c48e2ed1 | |||
| ee4b78fcce | |||
| 4439ba09f9 | |||
| db451f20df | |||
| 7a9ed39655 | |||
| 5bafc1db75 | |||
| abad2ca76c | |||
| 8577f71810 | |||
| 6f00e53159 | |||
| 7793299e53 | |||
| 052e62532a | |||
| d18e45b442 | |||
| a89aa8c90a | |||
| 971a7c88dc | |||
| 01b592c8e1 | |||
| bd50553149 | |||
| 157a90ac46 | |||
| 3a3dfcbdce | |||
| c72fbd7a14 | |||
| df2b591896 | |||
| 07711e404b | |||
| e15acd4fcf | |||
| 5dfb810327 | |||
| 8213e57f3b | |||
| 505c19bc20 | |||
| 27c8f8a1d4 | |||
| 6a66af72c8 | |||
| 058f93d9e8 | |||
| ef47bcc88b | |||
| 422154dc97 | |||
| 50486bd34d | |||
| 1c409abe9c | |||
| c419552002 | |||
| 18327aed30 | |||
| 4ea27061ee | |||
| 8da1303179 | |||
| adbb1471fc | |||
| ea4ff91861 | |||
| 316fece020 | |||
| 1ae27eb696 | |||
| e2e1485373 | |||
| 9c6d063750 | |||
| 4207ebbce7 | |||
| d1e8651aae | |||
| 1d045f2731 | |||
| 26c9889c6b | |||
| de85680a6a | |||
| a37a6bd783 | |||
| 8cc09f1784 | |||
| 18bd47c9b9 | |||
| fa32abe5f3 | |||
| 0d0a399a13 | |||
| 699c25a4be | |||
| 28b64f6f13 | |||
| ca762a6ba7 | |||
| 084c595855 | |||
| 4c8d25878b | |||
| 4ed40fd694 | |||
| 4acda3f609 | |||
| c16c803fe9 | |||
| 994815fbd4 | |||
| 994c682b77 | |||
| 685a050339 | |||
| 8e701a948b | |||
| 4e7f28811c | |||
| 0f387cda8f | |||
| 016359f406 | |||
| 6373e24bd3 | |||
| 114d378cfc | |||
| 1ef740fa2c | |||
| ea6410d1e7 | |||
| 789b35d813 | |||
| 73a8fa8e6e | |||
| f11715b6c3 | |||
| fe8501c931 | |||
| 218f7574f9 | |||
| b0e9346eee | |||
| 947f32d2e0 | |||
| 5e8486f68c | |||
| 19bc3f4d17 | |||
| ce7811e5dd | |||
| 8bd595acfe | |||
| d9f6a06773 | |||
| 48ae99ecef | |||
| 714db4cf0d | |||
| 5da8d65371 | |||
| 6cfe4a85f7 | |||
| d80fd0c85c | |||
| be028d0774 | |||
| 70c12e5407 | |||
| 797030aa90 | |||
| 57be99ff18 | |||
| 9b4cf896fd | |||
| dd379ec9fd | |||
| 84699e0e18 | |||
| 294bea11a5 | |||
| 8ee459207e | |||
| 285e6ad15b | |||
| c7c831bca5 | |||
| 018485050f | |||
| 770c69a978 | |||
| 524c61279b | |||
| 80f03f58e7 | |||
| d6bcab3c7b | |||
| a799cc13d9 | |||
| fad0598634 | |||
| 0f03f692a9 | |||
| 880ace2eb3 | |||
| db8b3252bf | |||
| 913b9cd661 | |||
| c1745539c4 | |||
| 42fbfb9be0 | |||
| 43b60f4617 | |||
| 33ce36397c | |||
| 2b01e316b3 | |||
| a5f493a763 | |||
| bdf82149e9 | |||
| 83f2eb79f1 | |||
| f6350bdfa8 | |||
| b640e72877 | |||
| 47c792ecc0 | |||
| e0435d3b8a | |||
| eddd417d74 | |||
| a34b8d4abf | |||
| 81938af5d0 | |||
| 72066a5111 | |||
| 3bd5055af1 | |||
| a3d44d523d | |||
| 2e2ac54eca | |||
| 72becbbb1f | |||
| 706862d5ba | |||
| 0ce3686a37 | |||
| 6f4a29d547 | |||
| cecc1857dd | |||
| c181f2f493 | |||
| 9c90a5f5e7 | |||
| 21d9412c93 | |||
| fef677f51a | |||
| 841ccccada | |||
| e310c3f9f4 | |||
| fa87422026 | |||
| 36db16a00d | |||
| 26a32dcbf6 | |||
| 411e551335 | |||
| a0add98b30 | |||
| 39467d84bf | |||
| a719a6f17c | |||
| 991c41c849 | |||
| b741ec2dc1 | |||
| 1c18b1d245 | |||
| 16b4ccb846 | |||
| 1a51a96de2 | |||
| f1009e2234 | |||
| 12e00827be | |||
| a3f74aaaaf | |||
| 2dd77f886a | |||
| 7a7a2749e0 | |||
| c2513ffb5f | |||
| a34fbf7bb1 | |||
| 63280767f1 | |||
| ba23dec78a | |||
| a9ab629f60 | |||
| 2f6c37b806 | |||
| e1b4f5aeb6 | |||
| 55e3deac46 | |||
| 3d5c0f1faf | |||
| b78f1ad823 | |||
| 6970469299 | |||
| 696972bf8e | |||
| a595ea208d | |||
| c0216c518f | |||
| 25b014691f | |||
| 73e1d64ae0 | |||
| f4b84dd45d | |||
| 4a5b775a8d | |||
| 91002393a5 | |||
| d34f2cfefe | |||
| 809bbb472b | |||
| 7840b07d2f | |||
| c7cb116dc0 | |||
| 7f14a278a7 | |||
| b8bce55270 | |||
| ee7e231e8b | |||
| 9e27f82ee2 | |||
| f50f34016e | |||
| c66efd05fa | |||
| fbc44bcb78 | |||
| 7366be696a | |||
| 0330322dbd | |||
| 8283ddb52f | |||
| de9c0d9926 | |||
| ef6b696446 | |||
| a12207c3ad | |||
| f5a0b226f2 | |||
| 9ff63a46fc | |||
| 4ccde1330d | |||
| cde9d640fe | |||
| 2073af2f05 | |||
| ae28345ca5 | |||
| 3f990accb0 | |||
| 9b12bd915b | |||
| b2314c9ae5 | |||
| b43989bdaf | |||
| 17f0c93b37 | |||
| 5728795cf7 | |||
| c314178e7a | |||
| 3648c61172 | |||
| 31bd84de12 | |||
| cd6e7ac46e | |||
| 86f01c254d | |||
| 0d85d2cc0a | |||
| 4f22f48e63 | |||
| 401537ebab | |||
| 0fc187d7a3 | |||
| 1f8aa4f7d3 | |||
| 37be868679 | |||
| 4540260df9 | |||
| dc3d0cbc22 | |||
| d68e350227 | |||
| 14ac55d05e | |||
| d5c202e46b | |||
| fb912e1ba7 | |||
| 2d10336601 | |||
| 4d17051f14 | |||
| 9285dddbaa | |||
| 48f132f35f | |||
| 26ecf2f374 | |||
| a35bec1e0a | |||
| 1f6cf50be3 | |||
| 0a9470bf09 | |||
| 0d626c8fef | |||
| 0db4b7cebb | |||
| aac745c8e4 | |||
| 60b33046a7 | |||
| a4a6ee34bf | |||
| 32df09c275 | |||
| 5357e28a2f | |||
| c68b9328ca | |||
| 50d02b9f84 | |||
| 05b15943d6 | |||
| d1492eefca | |||
| 975d2e4294 | |||
| ab3814f9b9 | |||
| 6a1e549ffe | |||
| 0d3b6465bd | |||
| 2f01930ecc | |||
| 52535d3ef1 | |||
| a554941737 | |||
| adbf2dc9f1 | |||
| f1dcf71dd7 | |||
| ec40b85e75 | |||
| 2935fcea62 | |||
| a865876c0f | |||
| 2879eada25 | |||
| 473dba1189 | |||
| ca9183d567 | |||
| a65f2b4bd3 | |||
| aaa255465e | |||
| b632f95f8d | |||
| a9ab869800 | |||
| 4e918fb987 | |||
| be65701908 | |||
| f85e33f4af | |||
| c1024b112e | |||
| 6dd609a709 | |||
| 06e0fb25e9 | |||
| 311a232a09 | |||
| 186f6977bc | |||
| 14fd22e664 | |||
| d402bac69d | |||
| ca4b7e1e0f | |||
| fb3140ceef | |||
| 5ec47299e2 | |||
| c9229f7543 | |||
| 4170c97984 | |||
| 11a65475d8 | |||
| e5e30253ef | |||
| c7f5bc3624 | |||
| d855608e6e | |||
| 10d18a315c | |||
| 03767340bb | |||
| 6d54abbd0f | |||
| 4bccd9a92a | |||
| 4013ce570f | |||
| 0bb85a0ec8 | |||
| d5603caa0b | |||
| f6208e3dea | |||
| 125e2dcbba | |||
| fd1370b92b | |||
| c8d77fd961 | |||
| c562f0ad38 | |||
| 27ae1578ac | |||
| b8b7f155a5 | |||
| 27dd27400a | |||
| 6d691f2e05 | |||
| 9840825743 | |||
| ce2733bb37 | |||
| 48af5e5579 | |||
| c16f96cb5b | |||
| 8b222ac014 | |||
| a92aed45a4 | |||
| e2de96289b | |||
| 41431e11f5 | |||
| 4e513a3346 | |||
| 6172803012 | |||
| cb52d249fe | |||
| c7045184ce | |||
| dfe4519c07 | |||
| 9e61a28b2e | |||
| c62931f000 | |||
| 765dd30981 | |||
| 903789f7af | |||
| aaa335b617 | |||
| 0a3a2df433 | |||
| b28d13430c | |||
| fd6f54c895 | |||
| 726efee4d2 | |||
| f6451c7ae6 | |||
| 25cf33d5c8 | |||
| 0acd818efc | |||
| 8af8c4d0aa | |||
| cfcf8abbb6 | |||
| 62cabb58a9 | |||
| d102ea96c0 | |||
| 8104db2232 | |||
| f773f45d90 | |||
| a5dcefd50e | |||
| 28db4a2207 | |||
| 1ac1e5be08 | |||
| be7c924e7c | |||
| e06a9e9009 | |||
| 3335963987 | |||
| 671e95d59e | |||
| dc704d77ac | |||
| a986db56c6 | |||
| 0a30f64f12 | |||
| a6e5ebafcf | |||
| 595fd2757c | |||
| d4ae7f32e3 | |||
| d2e23008ab | |||
| 464d289fa9 | |||
| 7fef96be1e | |||
| acb62692e4 | |||
| 6825375694 | |||
| 4e8f8922e2 | |||
| da0e07bc1b | |||
| a278abdc76 | |||
| a21b8ed92c | |||
| 5a71bde79a | |||
| 517be4bfa9 | |||
| 31e790da33 | |||
| 9df8400f3d | |||
| 7de2e1e795 | |||
| 9678d48e1a | |||
| 69c7eea694 | |||
| ec5ae4af1d | |||
| a88bf4e5aa | |||
| 40b870704e | |||
| 5ddd25313f | |||
| 4f0f5a24ef | |||
| e00e8ebea9 | |||
| 2b6da67e17 | |||
| 3ed948a822 | |||
| e21fed3c4f | |||
| db6d94a7b0 | |||
| f1db065c10 | |||
| 5383a625a7 | |||
| ae3dfa80db | |||
| 554017673a | |||
| 063ac74369 | |||
| da5ead2c23 | |||
| b0a3b42287 | |||
| c5d7791b67 | |||
| b03e3abd62 | |||
| 47f2e618ee | |||
| e5175dbc1e | |||
| b1302cdb06 | |||
| 0882936707 | |||
| a92da54e79 | |||
| fcc28fecb6 | |||
| 574f319c74 | |||
| 767780a4b2 | |||
| b3b434e221 | |||
| 2d0fe514a0 | |||
| 3d5700655f | |||
| 01d2e7af71 | |||
| 4c75872e0f | |||
| 5ee2051863 | |||
| d482b5c102 | |||
| 413e985907 | |||
| b4b83f2f29 | |||
| 5903c7257e | |||
| 30a6cee2fe | |||
| 86a515fdae | |||
| bf4c5bef7f | |||
| 680ca88ce0 | |||
| f189ffe9af | |||
| 0f716cdf33 | |||
| 93e5947f55 | |||
| fd1da009a8 | |||
| 2f069c108f | |||
| d22c6855c3 | |||
| ea1f885be1 | |||
| 66e94467dc | |||
| 2a4252e117 | |||
| 9e6575428d | |||
| 8568914c03 | |||
| 0f8023967c | |||
| ce818dc01f | |||
| 46bd49ef8a | |||
| 46bfdbaf82 | |||
| 241df6c6a8 | |||
| 5d7ee48031 | |||
| 185fe7aa1b | |||
| fde4e8fed9 | |||
| a462d76a95 | |||
| e4cf3297c7 | |||
| 89833fa073 | |||
| a3b4d4608d | |||
| ca318e7099 | |||
| 45a21555c7 | |||
| d1d8c7d8a6 | |||
| 4b099e8ade | |||
| ab8de8f506 | |||
| 0a1812c257 | |||
| 48aa1234d9 | |||
| 84d71fae48 | |||
| 84e1712659 | |||
| 42b763e6b7 | |||
| e884bbabcb | |||
| bb6f65c199 | |||
| 62c1a5a152 | |||
| 3faaabd6f4 | |||
| cd943cc60d | |||
| 031076ab93 | |||
| b9ea59df35 | |||
| 4f7679cf51 | |||
| ac2d79fd67 | |||
| 3860b8db02 | |||
| 020b47c41a | |||
| 658e4c3db6 | |||
| 1b3f634843 | |||
| 1fb1088b7d | |||
| 9db93d773d | |||
| d8dc6caf09 | |||
| 8bcec7d77f | |||
| 00045bbf27 | |||
| 86108012ce | |||
| 3ea02018b5 | |||
| 74e997f15b | |||
| cf30c582c6 | |||
| 13d2154f9a | |||
| 648bac2cc4 | |||
| 07cffc9df2 | |||
| 1734f435f7 | |||
| c2394339a8 | |||
| de0909e03c | |||
| b75bac7975 | |||
| 8e06ae2762 | |||
| 5cc1ef9022 | |||
| a893395da8 | |||
| d99832163a | |||
| 8596e82d98 | |||
| 26a8c45e23 | |||
| f210602d1e | |||
| f8b185b55f | |||
| 0dd00321e0 | |||
| df665e2386 | |||
| 96d48331da | |||
| 923967403e | |||
| 1aa14e4929 | |||
| ba73249dc0 | |||
| 8b155b1c6d | |||
| 5eee757658 | |||
| 99374598b3 | |||
| a113d9bcc1 | |||
| 83b36bfd79 | |||
| 44bda8fbb7 | |||
| f2e41ce391 | |||
| 5590421a5d | |||
| a0ff9f69ef | |||
| 32c239085d | |||
| 042b0a584d | |||
| b8e08d5d3c | |||
| 677f242761 | |||
| 3debc78a5f | |||
| e37c53d13e | |||
| c1d73e4fca | |||
| 35acfcf791 | |||
| 0d8a21efd5 | |||
| 28d28a2607 | |||
| b316aa3710 | |||
| a95d63dab6 | |||
| 39ebca5dbf | |||
| ad974de165 | |||
| c61f4e8863 | |||
| 2833aeb310 | |||
| fc6c55f070 | |||
| 443f302414 | |||
| 9c90b6271c | |||
| 2ad411f914 | |||
| 46c8b09453 | |||
| 79d8d0da3b | |||
| d2a1994d71 | |||
| ba14895fd7 | |||
| 74b899d8b0 | |||
| c3d2921971 | |||
| c2e5418e51 | |||
| 5f30a0a076 | |||
| 723b42e0da | |||
| 2db2d137ce | |||
| b12286329f | |||
| 2812762d6b | |||
| 37cccf17c0 | |||
| 1da8a19af3 | |||
| 86238d2748 | |||
| b42288c2de | |||
| 18e7afdfd9 | |||
| 35d0a45df6 | |||
| d67e6f5cc9 | |||
| 1ae9a5d1d8 | |||
| 29afb83f24 | |||
| 065d631f0e | |||
| d7ee62f03b | |||
| e42750c63c | |||
| b2698f24b0 | |||
| 7eee5cb724 | |||
| b8d743bf50 | |||
| 0a7e53da0a | |||
| 03d6c5e473 | |||
| 6a69852df1 | |||
| 1a18a33688 | |||
| 87ca607fd4 | |||
| ba5f9d68c4 | |||
| 3d19de2b58 | |||
| 0b4e06ad3c | |||
| 5775ace5e0 | |||
| fc742da6e3 | |||
| 562c15cbe9 | |||
| 15dabc11b5 | |||
| d8698fc359 | |||
| da2810918c | |||
| 4f7b3e8a56 | |||
| 6e931aaab7 | |||
| 2974b049e7 | |||
| 4ae4a705d5 | |||
| 0af9bf457a | |||
| 7429ed07be | |||
| 3935855365 | |||
| 08911cbfae | |||
| f2e9588c93 | |||
| c57f8780e9 | |||
| 3b1803f6b1 | |||
| f96b5652ce | |||
| b721269c29 | |||
| 8124b5600f | |||
| f9e02aa612 | |||
| bae8b2a9b0 | |||
| 8cdd91cd23 | |||
| 6cff909bc8 | |||
| 328da251ed | |||
| 085ea5049b | |||
| 81e6ef2958 | |||
| e0f19ec48a | |||
| ecfd4ad11e | |||
| 6df12a0507 | |||
| 64dbf6c987 | |||
| 718891d937 | |||
| c6f790ce12 | |||
| 9ad0dcb57f | |||
| e072fa8121 | |||
| 72672c293f | |||
| ce66de8e3d | |||
| 31fb82176d | |||
| 52444bf8d0 | |||
| 0df9cbc954 | |||
| 23fd32056e | |||
| 891c83ff35 | |||
| 1001b05def | |||
| 70dcd107d0 | |||
| 941090861e | |||
| d394d26b46 | |||
| 4423a5edad | |||
| fa42a1cfc2 | |||
| df9120768d | |||
| 5f33d0c75b | |||
| 531b8e2320 | |||
| 80951bd091 | |||
| 134154ec6d | |||
| ecfabd7aac | |||
| 13aef2c0cf | |||
| 82e4e1816f | |||
| 313f54bc39 | |||
| b3d55489d3 | |||
| 371096493c | |||
| 6b09ada5d4 | |||
| 167a4e6592 | |||
| 1fc655a58f | |||
| 440ba2e4a7 | |||
| 57d1591957 | |||
| daf1879a2e | |||
| 2acfb263bb | |||
| 60676dbbe8 | |||
| 2ec63e4dd1 | |||
| c4cc54e5da | |||
| cc5c5f7da9 | |||
| a455858dd9 | |||
| 848c66babd | |||
| 8a65e73bfd | |||
| 71cbd6f02e | |||
| b436f4b995 | |||
| 0e9c8e2dd5 | |||
| b34272f8a2 | |||
| abbc988fb5 | |||
| 6d65f7a261 | |||
| 705e776f09 | |||
| b0cc495698 | |||
| 96edb270a6 | |||
| e20a93f7d6 | |||
| 575de89ee2 | |||
| 460b1dc2fa | |||
| 27b924e99e | |||
| d06b8c4ea9 | |||
| a2921fdede | |||
| 6c42ad5b90 | |||
| cf2d6f6721 | |||
| 6d9c6e9c7a | |||
| 5d3860703d | |||
| 78ca5ddd45 | |||
| 22919c39ad | |||
| 2dec662ebf | |||
| d5179b8218 | |||
| 5ee61219c8 | |||
| 644c0dd5f4 | |||
| 42d5b1fb3b | |||
| 87ae4e0564 | |||
| 0823ec0ef0 | |||
| 617df09143 | |||
| 744f907815 | |||
| ce05d6cb89 | |||
| 26bf5b5de3 | |||
| 1e17ffe9ac | |||
| 0d7c16b5fd | |||
| 34d68edd1a | |||
| b6f21a6cac | |||
| 48b747903b | |||
| a86a5c798b | |||
| b28194addc | |||
| 77f9bb7b76 | |||
| d62b0bd363 | |||
| 4da91f9e6d | |||
| 89c9e7c2e6 | |||
| b747633584 | |||
| d99821aa44 | |||
| 55d0945149 | |||
| 13d1ee10be | |||
| 0015a09987 | |||
| 36f1881925 | |||
| 070f0f8445 | |||
| bc6d5cc113 | |||
| 474868a892 | |||
| 1efa7f4d27 | |||
| 2deda0e868 | |||
| a25dba001d | |||
| 7f64f31f66 | |||
| 87d06eab82 | |||
| d9a56f6590 | |||
| 6f8695c178 | |||
| 7b2ef647aa | |||
| 69c4e84dad | |||
| 5e4d3559be | |||
| 464aa5e555 | |||
| bd7c21d83e | |||
| bfb4ebfa03 | |||
| 99b0845cd5 | |||
| 0e6aa189cb | |||
| 91d80d0309 | |||
| 63d8290491 | |||
| 9f3b1f7e50 | |||
| 9e65216108 | |||
| 957bf1452c | |||
| 3bf16da92d | |||
| a9b4cdd36f | |||
| 75b93b17ee | |||
| 2d964f800d | |||
| b0fa477614 | |||
| 154d61edf9 | |||
| 9e7124127f | |||
| b542914057 | |||
| 3c2f7ecc97 | |||
| f3494647c5 | |||
| fc890bd941 | |||
| f695d4f04b | |||
| 0af3947468 | |||
| 033c01afe2 | |||
| ea911d34c6 | |||
| c634e39299 | |||
| 1c8b1b2d2b | |||
| 9bda0546f8 | |||
| df5d51f1c0 | |||
| d40e46bc9b | |||
| 998c43ffea | |||
| c4b57d0ded | |||
| bb41df9d5f | |||
| a00f0c44ae | |||
| 7d007d212c | |||
| 79f8e516b8 | |||
| bfd6ae77f5 | |||
| 4d053405cf | |||
| 07b18b0e8a | |||
| 9e8d060314 | |||
| f698bc1cc2 | |||
| 3e77731f7e | |||
| 525e04cfcc | |||
| 95da5ec245 | |||
| 3bfe76e24c | |||
| b000663a88 | |||
| e871045b46 | |||
| 9c92f65c0b | |||
| a9353ad2ec | |||
| 53f4eaa7a7 | |||
| 6c4b634cfe | |||
| d76f258aeb | |||
| 112903c2bd | |||
| 8215d20dbf | |||
| 2a350b11dd | |||
| 9fca953e62 | |||
| b2dd128ec5 | |||
| 20b9ff4ff6 | |||
| f75f894d73 | |||
| dce310e03c | |||
| 3c1a002dab | |||
| 5e94243222 | |||
| 07ef396fbb | |||
| 91d8405e52 | |||
| 74b83cfce5 | |||
| ee9a42e9cd | |||
| 3590c3c48e | |||
| 491b6543da | |||
| 1f26e73478 | |||
| 5bc10ef796 | |||
| bb5e25ba7c | |||
| ddc0b42bc3 | |||
| 6c6badb6a6 | |||
| bcc9010630 | |||
| 0ed250cb5d | |||
| 02aabcca87 | |||
| 39acd4a3fd | |||
| c1b90a1c22 | |||
| a6b33c3590 | |||
| 7176c1327e | |||
| 9b3d65c5e4 | |||
| f9ab93bf0f | |||
| c48e237dd0 | |||
| 88da03722f | |||
| 9ed1474340 | |||
| 88e3d07178 | |||
| c8693f01a3 | |||
| 479f933970 | |||
| e233f7d199 | |||
| 1095076d7f | |||
| 59fabb2767 | |||
| d06bdd5bf6 | |||
| 67a7826da3 | |||
| dcaac98569 | |||
| 5f269d08b4 | |||
| f3bd508e6d | |||
| 0fd0acf2e3 | |||
| 6f22f49c02 | |||
| 04c7d03188 | |||
| 00112bbe10 | |||
| e3f5bbd217 | |||
| 627e2b15b3 | |||
| c61f7e5334 | |||
| 630406e006 | |||
| 3e649895e5 | |||
| c0fe374490 | |||
| 62a87ce38c | |||
| 4382302a6b | |||
| 7f896643e9 | |||
| a6ade2b914 | |||
| a2ec23c112 | |||
| f5b96eb828 | |||
| 179998a8a2 | |||
| 8f91529edf | |||
| c65d2a0d86 | |||
| 688bd28987 | |||
| 8d43e2b945 | |||
| 22682f933a | |||
| 56aa03b0e1 | |||
| da69cd08db | |||
| 4e63bd04e5 | |||
| f29fd63f13 | |||
| 0e380ff15d | |||
| 96919156e7 | |||
| 040409aac5 | |||
| 1f2e159054 | |||
| 7dcac647e5 | |||
| b3475cbf32 | |||
| 393cd6242e | |||
| 61390e407d | |||
| 3f2ab5d3b5 | |||
| 3844ee780c | |||
| 7dc5332a92 | |||
| 8b05a4bf93 | |||
| 330e4bb48a | |||
| 8865528dc2 | |||
| 2b08f29543 | |||
| ee4f409584 | |||
| b23527bf02 | |||
| 7fea7e0629 | |||
| e4cd24537e | |||
| 1432471650 | |||
| 8184535de1 | |||
| babaa00ac1 | |||
| 7c64e03cc9 | |||
| 882e120a9d | |||
| 5346870920 | |||
| 639c8fc6d6 | |||
| b7735b3400 | |||
| 4aa9b230b8 | |||
| 8bb8f8dcae | |||
| c3dc7266d1 | |||
| e98c1bfb53 | |||
| 9564531ec8 | |||
| 81c69ecd16 | |||
| 930d96f684 | |||
| 69bd6dad1f | |||
| cb48183d02 | |||
| c7fc9dc42f | |||
| 78a5aacb22 | |||
| 73e16dbc3f | |||
| bbc327aaed | |||
| adcdab394b | |||
| c5a8619493 | |||
| 02edfc8df2 | |||
| 6b511751f5 | |||
| f274c592e4 | |||
| 6c3d8abe2c | |||
| f9e6741807 | |||
| 86b54a52f0 | |||
| 6489d8a96f | |||
| e7ec580318 | |||
| a4e9712006 | |||
| 43dca117b9 | |||
| 11ca1c95f8 | |||
| 1b22783d46 | |||
| fd78e2cc6c | |||
| 3cbd14d61a | |||
| 6020dacc11 | |||
| df5a7c8ee9 | |||
| 677d4d20ce | |||
| 959002fb96 | |||
| 7c92ee2e6e | |||
| 0e436c3fe9 | |||
| d2bad6febb | |||
| eaec95dcf2 | |||
| 0ebe387cb2 | |||
| f0dc7a25e7 | |||
| f57e3ce5f3 | |||
| 09ce987552 | |||
| f861d0d643 | |||
| a76fd43599 | |||
| 33ab236ed3 | |||
| 09c2a8b7ad | |||
| be38a524a8 | |||
| 61492ea0dc | |||
| 96937bac74 | |||
| 89cd74093e | |||
| 7284a77cd3 | |||
| e8bfb48490 | |||
| 9b959072a2 | |||
| 2fb670cf09 | |||
| f5306a0740 | |||
| 4597b94099 | |||
| c6c651212c | |||
| 7188e6e2ac | |||
| 29921d055d | |||
| 9faa2a7fd0 | |||
| 958263d245 | |||
| 882e4221e7 | |||
| d1b097f409 | |||
| 7b1f7c8d8e | |||
| ecd827fc8e | |||
| 31952fbf1c | |||
| bd9cc2dfc6 | |||
| 54f190cba3 | |||
| 6677f81779 | |||
| 547a2d29c3 | |||
| 4142e737b0 | |||
| dafb4b81da | |||
| 7fadf570b8 | |||
| c6be51eecd | |||
| aa861520f6 | |||
| 777e1d38ba | |||
| e0d64df763 | |||
| addb15383a | |||
| c3456c0754 | |||
| 68c63188eb | |||
| 45bd56e28a | |||
| f4ebc504d1 | |||
| 0637ca21dc | |||
| 4fa86dad26 | |||
| 445349dd7d | |||
| c5bbc0353c | |||
| 4a529cd641 | |||
| c62eda023d | |||
| e5d12502c5 | |||
| 87d0c91dcf | |||
| 25e2e8aa3c | |||
| d0a8390963 | |||
| e3844e0f26 | |||
| 77849d0033 | |||
| 9fee699693 | |||
| 2577194c70 | |||
| 1b6e02793c | |||
| fd76ed5c0f | |||
| 6f6eebbcb9 | |||
| 46fb46c54e | |||
| 055f5c7395 | |||
| d1c1c01761 | |||
| fbfd3158a7 | |||
| 15f8bc6f37 | |||
| 532885c12b | |||
| 89a1e806b7 | |||
| 4239bac4ed | |||
| eccf2fa4c3 | |||
| 43d5988df6 | |||
| 7c5b981c17 | |||
| 2717ba735a | |||
| 901e1e4608 | |||
| a2d0cc878c | |||
| c03d778ec7 | |||
| d913463932 | |||
| 14deab252b | |||
| cf0df733da | |||
| 5d4f22e096 | |||
| 98dce911ca | |||
| e1ba4399e8 | |||
| 070e4d754e | |||
| d3930cdee1 | |||
| a2d8e7fa6e | |||
| 7f9319924b | |||
| 40686415f9 | |||
| 904cfa576c | |||
| ff0601cda5 | |||
| 1e667de1f3 | |||
| f6fa1cee2b | |||
| ef45005056 | |||
| c344435378 | |||
| 7f52a553d4 | |||
| a2b353d178 | |||
| 9e53f03968 | |||
| 78de75397e | |||
| e59da10bf1 | |||
| 19e79d6727 | |||
| a8b2b4dba1 | |||
| dfd5191e8b | |||
| eca752368b | |||
| 4547427946 | |||
| 0a48b9ae77 | |||
| 60f799ada5 | |||
| bbeac745ca | |||
| cbf2b79e1f | |||
| bf688da50b | |||
| 0cb1e96472 | |||
| 0fc26f80d7 | |||
| 90b844792d | |||
| 98c9d47537 | |||
| a191c043ae | |||
| 64a5126ff8 | |||
| 308b47ce58 | |||
| c393a7a98f | |||
| 5c54360fb9 | |||
| e2939f7788 | |||
| b2ad7cd9c0 | |||
| c6e6d4c822 | |||
| abab67b574 | |||
| 60dc8bcf8e | |||
| b07944df23 | |||
| a0a8acadb7 | |||
| a812989436 | |||
| 2bb520e277 | |||
| 4951543441 | |||
| 16f4baa3f6 | |||
| bfcb40ad77 | |||
| 6c4aae98f7 | |||
| e646f9d2f1 | |||
| d72625d506 | |||
| d043a61897 | |||
| c3d1f94ee6 | |||
| 2124cb1192 | |||
| 1f1464c925 | |||
| 66549414dd | |||
| 3b2a194c30 | |||
| ef0931be44 | |||
| 8011be2810 | |||
| 6930325847 | |||
| e4f207c4b4 | |||
| 764a1f5947 | |||
| 3092a0982a | |||
| fb598bb76a | |||
| b6a093fba1 | |||
| a0fdc91a14 | |||
| d6b8563530 | |||
| 925d8c1dec | |||
| 688ebd8960 | |||
| 03e4b7552e | |||
| 7077d1de63 | |||
| 72ec643129 | |||
| 79134b6ae6 | |||
| 02fe93a399 | |||
| 3db19c046b | |||
| af64ecdf25 | |||
| 10896129b3 | |||
| 855c058d6e | |||
| 11e563fd5d | |||
| a29c814bd8 | |||
| 8ceac4b73b | |||
| 39f7eccdb0 | |||
| 8ed1945ccd | |||
| 86959310f9 | |||
| 6e5e5d87df | |||
| 5ed4e1b887 | |||
| df6eb101e1 | |||
| e587721d1c | |||
| 8cfddcfeb7 | |||
| 681fd7f214 | |||
| 25e0c12274 | |||
| f4e00bd60f | |||
| cef45bd2ad | |||
| 904381c602 | |||
| ccadad4222 | |||
| 8d4cebe077 | |||
| 5a0c04409b | |||
| d66ed313cb | |||
| db9f611767 | |||
| f87b175a19 | |||
| d3aaf8acf3 | |||
| 43f854bc5f | |||
| 67a734ce73 | |||
| bb8faec885 | |||
| 94a9e16943 | |||
| b973b73ae7 | |||
| 59975db6a4 | |||
| ec2ff7f0c0 | |||
| 5d038686b1 | |||
| 6084901610 | |||
| ec63343f34 | |||
| 9ebe29a8f1 | |||
| e58c28974b | |||
| 1b4bd6a905 | |||
| 67fe57a0a3 | |||
| 76ced14b3b | |||
| 5a938309c1 | |||
| 11378fcb17 | |||
| db0ae2ca50 | |||
| 289b6ff2a5 | |||
| 9e9165c25e | |||
| de164b0ccf | |||
| 5e9192287d | |||
| 3287ab386c | |||
| d02f17c39d | |||
| 194f1beae8 | |||
| c52759432d | |||
| 08761f5fb5 | |||
| 68b7323b4e | |||
| c02d89bf2d | |||
| a513f482c0 | |||
| 9393a0c5bb | |||
| 809c159e11 | |||
| ba3b1de93f | |||
| 169b5e9fde | |||
| 98239664f6 | |||
| 3bd6912e01 | |||
| 1a41ed2fda | |||
| e9461d3feb | |||
| 0df901b389 | |||
| ccff20328d | |||
| ac32450c38 | |||
| 88c0d64b4e | |||
| c34bb0ed03 | |||
| 9be6b4f2d1 | |||
| 372890f1d7 | |||
| 9d71c19939 | |||
| fc5e32c7ac | |||
| 4a9170ba42 | |||
| 5b73f3a316 | |||
| ed508dc8ed | |||
| fc55e54aa1 | |||
| 98763528ab | |||
| 96d747f030 | |||
| b99d010977 | |||
| b922d49a28 | |||
| 49b4af1e5c | |||
| d8629b0fa4 | |||
| fc9f7cc925 | |||
| cc7a1a2ab7 | |||
| 5164c4ba31 | |||
| edb6a0e889 | |||
| 9744073b95 | |||
| 36477fdefa | |||
| ee9f88902c | |||
| 8f6e102331 | |||
| 13858cd561 | |||
| 772d9689e9 | |||
| 9dd962ca1a | |||
| 1307bb1d03 | |||
| 2b29db860c | |||
| 91678ff828 | |||
| ff3bb9f4e6 | |||
| e90b697cb0 | |||
| e489f29d0f | |||
| 2f0676fb88 | |||
| 70bc268c1a | |||
| 1b3a967223 | |||
| b6d8c9d990 | |||
| 78286f3a44 | |||
| 47c4ee974a | |||
| 233612efd7 | |||
| f40d701427 | |||
| 15783cf668 | |||
| 008abd28fd | |||
| a7ce9a176b | |||
| 695e33b25b | |||
| 5877debb6f | |||
| 06ea0aa02b | |||
| 2d41321ca0 | |||
| 7783836fff | |||
| a7fe73f284 | |||
| 52ba3778e3 | |||
| c7b6353a3c | |||
| 1f7fea9092 | |||
| 34b3d31f54 | |||
| 6f139b4f8e | |||
| 7d4a8bc437 | |||
| 7d9a480597 | |||
| 46d218bcec | |||
| 0c068768a5 | |||
| fbbe75895a | |||
| 21513caf3f | |||
| 0634808bf3 | |||
| 873884aa47 | |||
| ab3fb8b2f8 | |||
| a5af69de6a | |||
| a821fde44e | |||
| a056c9b113 | |||
| f635381662 | |||
| 493ac1df37 | |||
| 9c3f790edb | |||
| d046602ea4 | |||
| 1740218ee0 | |||
| 86a725933a | |||
| 2be805ce29 | |||
| 64f02aa72d | |||
| ff0d115800 | |||
| 12a8f5486d | |||
| 97ac59cb73 | |||
| ee92a36123 | |||
| 72ed4173df | |||
| 0712bccf52 | |||
| 93ff1fb2f2 | |||
| 68d97502fe | |||
| 1e1dc1429f | |||
| 481473eb12 | |||
| ee123b8a9e | |||
| 362d52a3cb | |||
| a490b64e9b | |||
| 05384f05cc | |||
| 50edaae06c | |||
| 0ac31a0bd7 | |||
| 762965897a | |||
| 1f8fd5382c | |||
| 0b389b24f6 | |||
| 79ffaa8ce9 | |||
| 727743809e | |||
| ea3746bd15 | |||
| 9dc14b3efc | |||
| e792ee89de | |||
| e547916e88 | |||
| d2d5d32fe0 | |||
| 688b4d9d7a | |||
| 278747ba45 | |||
| ef2a376baf | |||
| dc8bb23a7d | |||
| fd1b66b37d | |||
| 26416343c4 | |||
| f3127521f3 | |||
| a4e35d83ff | |||
| 3b6190dfad | |||
| 83379695a0 | |||
| bebab8d647 | |||
| e0c65499fd | |||
| 40eb613bbf | |||
| 24361733e4 | |||
| 4e479d58f8 | |||
| fd61978795 | |||
| da189ce1e0 | |||
| 2a0a27d3f2 | |||
| b5fbb2b1c8 | |||
| b8ce65bec8 | |||
| 2f4e38c831 | |||
| 96903dc4ad | |||
| da669569e1 | |||
| 1bd8bcbdd9 | |||
| f715e5b0b2 | |||
| 00ea7fe99c | |||
| eb40afa26a | |||
| 93e50dabcd | |||
| d6060bbb7f | |||
| 08d5ab577c | |||
| 421fcf9e35 | |||
| d142c05d61 | |||
| 150a9e8e14 | |||
| 81b11ee463 | |||
| 74490399db | |||
| 9a5d7f1a0b | |||
| dd510e1de9 | |||
| 1d21493302 | |||
| a21ede9452 | |||
| 7a934f9ee0 | |||
| a8ca560684 | |||
| 79ecefb51f | |||
| 97d8ca3464 | |||
| 0b08d2559e | |||
| 947307baae | |||
| 42c36c0c80 | |||
| 7783206934 | |||
| 5517ea0adb | |||
| a90a576d76 | |||
| 695a430007 | |||
| 708761b219 | |||
| 4f9e1a9a58 | |||
| 9d49cef29e | |||
| cc3433f349 | |||
| 45f9d32866 | |||
| 79ac072e6c | |||
| 4555f9ac25 | |||
| 826b5a2ef1 | |||
| 1fbc6ab05d | |||
| fbc221d334 | |||
| cd1426ba8d | |||
| c186f424c5 | |||
| c9db05de22 | |||
| bad09e5f58 | |||
| 93c4dfb16d | |||
| da82acda6b | |||
| f819323296 | |||
| 52b9207105 | |||
| d2e451e877 | |||
| c41dc915fd | |||
| 00e91fd3d0 | |||
| afc62f076a | |||
| 9c4204b89e | |||
| bcca213b88 | |||
| 508c382673 | |||
| 3afb5a6006 | |||
| 108ddc199a | |||
| 7e44faf635 | |||
| 8cfc87cf01 | |||
| a7d28f3b1f | |||
| cbd0ee21d5 | |||
| e2434ab7c3 | |||
| 78475a47a5 | |||
| 9b8013d193 | |||
| f4b502dd03 | |||
| 2144afd836 | |||
| 9ebbfc7bdb | |||
| b47f2600cd | |||
| ea049e147d | |||
| 05a68fd82b | |||
| eeec404b9a | |||
| e587c24f9e | |||
| 8266903ee9 | |||
| ec66a3700f | |||
| 98fff4a601 | |||
| 17cd1dac06 | |||
| 85b2c2ae58 | |||
| 8414c6518f | |||
| 27abd4d3a3 | |||
| 275bfcf99c | |||
| dccbf50059 | |||
| 60f73eee7e | |||
| 7842c0d792 | |||
| 88a33a4e4f | |||
| c1f3c41bab | |||
| d29eb2938c | |||
| 22b028b64b | |||
| e4fed417d2 | |||
| 0c6e09f060 | |||
| 87fc75c6d7 | |||
| 4e3a6328ba | |||
| 54c07ba0ff | |||
| 86868176a2 | |||
| e90dc20361 | |||
| d579f08093 | |||
| 3a51cae208 | |||
| cb7cc81653 | |||
| aaa43dc84f | |||
| 56571561b4 | |||
| 5625d79508 | |||
| ab4d375349 | |||
| ff77f4d9ef | |||
| a61b19b524 | |||
| bc6ed1467b | |||
| 7f4a1bcac7 | |||
| 77f54e0f3e | |||
| 5e631d5cd7 | |||
| 238b47dfce | |||
| 2234016a22 | |||
| 410eb30c26 | |||
| cb012010c6 | |||
| fa1426f123 | |||
| 34b8f1d595 | |||
| 318671d9b5 | |||
| 7600757d07 | |||
| cd1aef77ea | |||
| d64b35f11d | |||
| 23ba94140e | |||
| f4f1561781 | |||
| d2e5f90f32 | |||
| 3f0a51bda1 | |||
| 25b4d8a1b5 | |||
| aaa30dc5b6 | |||
| e0f426f78b | |||
| 53711ec29d | |||
| d484893839 | |||
| 74c87a26a5 | |||
| 81f21e6e6c | |||
| 171541777e | |||
| 3a92371b60 | |||
| 3cc234588a | |||
| ee2f8d006f | |||
| bb605279b6 | |||
| 068677ad50 | |||
| 9d9a5bbbfd | |||
| f3c4a6aab8 | |||
| 7ff93600b8 | |||
| 74ee9ac572 | |||
| 177aef05b6 | |||
| 95608b1b84 | |||
| 7ad849718c | |||
| 3f1eeba39d | |||
| 46662ccd99 | |||
| 9a44e92193 | |||
| c0e34934c8 | |||
| da93a5527d | |||
| 06ea7094f5 | |||
| e55a053d71 | |||
| 2549bafe4f | |||
| 03d6d2041a | |||
| a54870aace | |||
| 8c591ebd77 | |||
| 8a09d95eab | |||
| d1a2c73228 | |||
| 1aeff45631 | |||
| 8c29380471 | |||
| 02cd8cf039 | |||
| 77fa8d9d5a | |||
| ff54952769 | |||
| 335f7e7916 | |||
| d7e57f2152 | |||
| 4c5af4f361 | |||
| 4546139844 | |||
| 28dd315ef3 | |||
| 84bf7680c7 | |||
| 232f564011 | |||
| 068769263e | |||
| 6c0c0466c6 | |||
| 359acc0d33 | |||
| f48cda2f95 | |||
| 54abb83c82 | |||
| 15793b1301 | |||
| 80102b76f9 | |||
| 5384a2205a | |||
| b2ca10a81f | |||
| c7bdbef504 | |||
| 87bbaa2c27 | |||
| 2c4ed7f8a5 | |||
| 5efadcb335 | |||
| 8ac96eecd2 | |||
| 5496dedd6a | |||
| 0307dd19fd | |||
| 617dd5db5b | |||
| c522172367 | |||
| 05353a1492 | |||
| 41c0a38344 | |||
| bfdca05f25 | |||
| acd74037b3 | |||
| 40bf97c6d1 | |||
| a2f0963d66 | |||
| 6a0d3b3e42 | |||
| b529b37d06 | |||
| 9ac35173e3 | |||
| 1dac67f013 | |||
| de8b3ee231 | |||
| c21657336b | |||
| 46e08d34dd | |||
| e4dc479e95 | |||
| afdcfccdae | |||
| 21e9edd1a3 | |||
| 7ba9b4fd1a | |||
| 112aa49104 | |||
| cd96df1407 | |||
| b030ac0433 | |||
| a70c54f2c5 | |||
| 544824ffc1 | |||
| 4f5497837a | |||
| f9f5313670 | |||
| 4a5ed70175 | |||
| c09b6000c6 | |||
| c10c8db97d | |||
| e04f372083 | |||
| 0e909aa676 | |||
| 873399705d | |||
| 6cdf3116c4 | |||
| b148ef2b1f | |||
| da48061910 | |||
| b2d44663fd | |||
| ea8f9b032f | |||
| 89df7923a7 | |||
| 56c89e0a98 | |||
| dabce70325 | |||
| 194b865daf | |||
| 7e472fbf68 | |||
| 6f51dd1258 | |||
| a2bda99921 | |||
| 35014a9742 | |||
| d6e2097435 | |||
| e0baa02193 | |||
| 43a1874e33 | |||
| cf43790a27 | |||
| db6e095fcc | |||
| bf604f1780 | |||
| 69eaa89e22 | |||
| ed8368fed7 | |||
| a4692a0da5 | |||
| 1a0282df21 | |||
| 4894aac50d | |||
| e22b838af8 | |||
| 9b70c44f00 | |||
| 6e3b90de9b | |||
| be4312ec3d | |||
| 2978a16c85 | |||
| 96f5a930f4 | |||
| a387d6fa26 | |||
| 34c006fcc4 | |||
| 05cfe28612 | |||
| 2f5ea3437e | |||
| c35b00a97e | |||
| e835878661 | |||
| 912592de4c | |||
| 85793d0138 | |||
| a57b03c356 | |||
| 5a5378b3bf | |||
| 1cd3c6f364 | |||
| c5531a7a2f | |||
| f01f1bc5e6 | |||
| 75b709328e | |||
| 85c7190e41 | |||
| 5c8907c0e1 | |||
| 9bee835dac | |||
| f2e4bec925 | |||
| b6c5936704 | |||
| 4a8d1147c2 | |||
| 24bbdeb0c8 | |||
| bb1c2d71a8 | |||
| cc3b2f6197 | |||
| 347ffbb0eb | |||
| be565c2235 | |||
| bdb9cf4d47 | |||
| 1b5352688f | |||
| 474c53ac71 | |||
| 3f8d5be56f | |||
| 8203b82f86 | |||
| 389f176a67 | |||
| 9a783d2a8e | |||
| 68eab8ea00 | |||
| 5312db93b4 | |||
| 64057965f5 | |||
| ec1e1c6fe9 | |||
| c75f9c80c7 | |||
| 5c21ca2697 | |||
| 8f37a3a37c | |||
| 9cd6731894 | |||
| 9d4ee2f54d | |||
| c35ddcba1a | |||
| 4f5d585184 | |||
| 243c513eea | |||
| fcbb57a63f | |||
| df89e76fb1 | |||
| bc46682b28 | |||
| c8ff7a4867 | |||
| c3ad8af42a | |||
| cb0b2bd1af | |||
| a1d7e38adb | |||
| 0655a2dc20 | |||
| d6134a0089 | |||
| cda8e449ec | |||
| 7494fa33c6 | |||
| c7ccde69a8 | |||
| 47cdb041f2 | |||
| 542f2b2e3c | |||
| e67178c696 | |||
| 3d2fc6c2fd | |||
| e6ac2ca3c9 | |||
| c7481c55f7 | |||
| e3690db4bd | |||
| 5a998335a6 | |||
| 3e176bbfa0 | |||
| 285eb0a539 | |||
| e784ea7178 | |||
| 0c9c7d5f3b | |||
| 70cb17bf64 | |||
| c01fd16291 | |||
| 49d3e39bc4 | |||
| 1e0928633d | |||
| 537d1322b4 | |||
| 7a62a8213b | |||
| 43033f0b1d | |||
| ec466ed1e0 | |||
| 8a803865cf | |||
| 22acd964cb | |||
| a8b27ae303 | |||
| 3f172731b2 | |||
| 6e22020dad | |||
| 4e469f2866 | |||
| 551b5d3e1a | |||
| 66eda72f66 | |||
| 6c8bc6a25b | |||
| 262a52f306 | |||
| 3405a865c4 | |||
| a7aa198b4c | |||
| 345678770b | |||
| 430e2f205e | |||
| 5afd0e211e | |||
| fade402899 | |||
| 1e4ad333a1 | |||
| c06eaf83da | |||
| 290b4d61b5 | |||
| 76c9714516 | |||
| 512e73db89 | |||
| 9012ff4711 | |||
| f9e2b036a5 | |||
| 8531e6d9fc | |||
| 029dfbc89d | |||
| 2d1cb14e61 | |||
| 5427ede6a1 | |||
| cdb9c60dcb | |||
| 66738d748f | |||
| 64a57f7c38 | |||
| 24da1ba3dc | |||
| 17e4d33b0e | |||
| 4db6d9986d | |||
| 6997d423c8 | |||
| 6b4d4a85b5 | |||
| 3d85e7ac0d | |||
| ac481e6174 | |||
| 8d79285d02 | |||
| 5fa64235b1 | |||
| f91ada572a | |||
| 25b044e6c3 | |||
| e607a85df6 | |||
| f7c8f74ac1 | |||
| 9c58741dba | |||
| a4aeba37fb | |||
| 8c545c055d | |||
| f26d0c5857 | |||
| d16723f493 | |||
| c4e80952ce | |||
| b3bbe7704d | |||
| 1ba2286c6d | |||
| bb78b01ace | |||
| a7d3e30404 | |||
| 178ed63e1a | |||
| f550ddb3fd | |||
| 24dbb43c09 | |||
| e85b23573b | |||
| 46edb54ac3 | |||
| 9636b5e821 | |||
| 4f3b58d1e7 | |||
| afdbd855ee | |||
| 923632272f | |||
| 7cb78451d1 | |||
| fb63cbb74b | |||
| 4cfe2b4dea | |||
| 22599a2812 | |||
| 387214a3c5 | |||
| 96654f0084 | |||
| 92387b1ef8 | |||
| 8d1f5b5490 | |||
| 4e669f59a0 | |||
| 2f4b334ef2 | |||
| 94e4498cfd | |||
| b4432c4fd7 | |||
| 3ee90a1ff4 | |||
| 613b289325 | |||
| 4fa91e468b | |||
| 34957bcfed | |||
| d34297b516 | |||
| 97dc5be841 | |||
| ec0e43a95b | |||
| a8e2922467 | |||
| 323e24e3ef | |||
| 2ecb48921b | |||
| d02627ea89 | |||
| 0c5d9e18d1 | |||
| af5bec70cd | |||
| 03e74330fa | |||
| 9aeb8c8d5a | |||
| 5021350082 | |||
| 297808e6b9 | |||
| 932043fdc2 | |||
| be23846c4e | |||
| c04d62db8b | |||
| 437fbe2594 | |||
| ddd1a816a0 | |||
| 1f6893e4dc | |||
| d214770d5b | |||
| 0862e8e34c | |||
| 84f37d352f | |||
| 32737df1b5 | |||
| 4474845dd5 | |||
| 3c6aa650a1 | |||
| 491a3fdebc | |||
| 6f2632ca2e | |||
| 2897da037e | |||
| b2bb7d075a | |||
| 3bbd22cb63 | |||
| 3b87e3fa20 | |||
| 74cb74dc0a | |||
| 5ebc7f0b72 | |||
| 5502f0b45d | |||
| 8f60740205 | |||
| 1434f55cb9 | |||
| 0d9938dab5 | |||
| 31d0dcf28e | |||
| 574280cd3a | |||
| 76e4b0a8fe | |||
| 1e443a6ea6 | |||
| f93a4dfbc9 | |||
| 34129d8e83 | |||
| dbfd6a3dde | |||
| c5d4ecae37 | |||
| d19189e80f | |||
| d1ac75cabd | |||
| b6ce4a527e | |||
| 14c5ef8db4 | |||
| 006d5ac0a5 | |||
| a1173dfa27 | |||
| 08b30580b7 | |||
| aee03cd5e5 | |||
| d366cb960d | |||
| 5ac1d8323e | |||
| e4fea5abab | |||
| 1305962af7 | |||
| fd0773eb32 | |||
| 6882c10b45 | |||
| ba71caca04 | |||
| 0db10a3052 | |||
| 4c1c0b108d | |||
| f0c14888d5 | |||
| 5c15461595 | |||
| 5d346128f7 | |||
| e37a58df3c | |||
| 4ed2d6328b | |||
| 2bfad68812 | |||
| a153871940 | |||
| 7afce8e003 | |||
| 1836d41b5c | |||
| fe2f5c175a | |||
| 8f732f2cfe | |||
| 5053aeeb19 | |||
| 5cdf0e3e89 | |||
| c22673e999 | |||
| e0395a79ec | |||
| 60c06e551a | |||
| 205775ed52 | |||
| c2a86a6a84 | |||
| dbc0aa6c7b | |||
| 0831bd3990 | |||
| 21b415f6be | |||
| 286ba8cffd | |||
| b5ddaae427 | |||
| 4c251bd260 | |||
| 22b64e2c28 | |||
| 9d89c369f8 | |||
| 7a7b0bcfcb | |||
| 0d706f6796 | |||
| 544990e377 | |||
| fda17273de | |||
| d8e3971e7f | |||
| d2e169929c | |||
| bb4b4acce5 | |||
| bfe5ed23cd | |||
| 5576c0866a | |||
| a0f6cd8df5 | |||
| 6ead99985f | |||
| 5aa4b74115 | |||
| 3c8bd19e56 | |||
| 5d6292fc97 | |||
| b26580cc7b | |||
| 46ec9c386b | |||
| 8e67f0ba84 | |||
| 05531cd7c4 | |||
| 919fc443fb | |||
| 35d4f998fd | |||
| 2cda78ffac | |||
| 832a03821d | |||
| 4a294775da | |||
| a9607c8531 | |||
| a921761d18 | |||
| f814218640 | |||
| 715887fcd5 | |||
| fc641e2bde | |||
| 6dd5e7749b | |||
| 4fa14f75b8 | |||
| bcf78daed2 | |||
| 1ab7acf015 | |||
| 02bb287802 | |||
| 9d8118dee5 | |||
| 2e9ef3f9e3 | |||
| 0087c57e0d | |||
| d6f8a75e91 | |||
| 237f33d4f0 | |||
| a15707bc57 | |||
| 9d624f82c0 | |||
| 893fa4cf84 | |||
| 76760470f3 | |||
| 4f373a4284 | |||
| e0b7389dc3 | |||
| a69eeb6b1f | |||
| 5d5cf32e22 | |||
| 0de6165863 | |||
| 9c0a5523e4 | |||
| 6c4232dcf3 | |||
| 78376c0f63 | |||
| ffe0631518 | |||
| f95203e93f | |||
| 387935e94c | |||
| 878ec080c7 | |||
| d86d8ed909 | |||
| 056a111788 | |||
| a87ae5910f | |||
| 2f0a598ac8 | |||
| eaa573f56a | |||
| 5772cb52e3 | |||
| 421c922539 | |||
| 9abdf39c90 | |||
| efacf7b6de | |||
| 8a36402ec0 | |||
| d68c392b42 | |||
| 7172c16435 | |||
| d19897b734 | |||
| d4245aa45c | |||
| 0886f6fe62 | |||
| 6423b366eb | |||
| 54c1637ba1 | |||
| 4448cbffd2 | |||
| be8ca7ad81 | |||
| 1621043bd2 | |||
| b81598bc03 | |||
| c68d15bebe | |||
| 8418d564a8 | |||
| 0e5c710757 | |||
| 5c5d0e6743 | |||
| 5473dbebed | |||
| b5d6d7016c | |||
| 98f5fcd86e | |||
| b4bcdd10a1 | |||
| e8742be30b | |||
| 681df84036 | |||
| 8026824563 | |||
| 0ba66aa5b9 | |||
| d5894ef2a8 | |||
| 0c471515fd | |||
| c7cb028035 | |||
| 8d921129a7 | |||
| 767bae44ae | |||
| 07a58c47cb | |||
| 84f9578fbb | |||
| 8562bb7092 | |||
| 38bbfe0bb8 | |||
| 2b27f7dbb3 | |||
| 5a72be08fd | |||
| a0f8645541 | |||
| 8524d46fee | |||
| e860ed7689 | |||
| 53ed1a8c03 | |||
| 1bef1b8d16 | |||
| 2b26094cf5 | |||
| 2afb02fcb4 | |||
| 4d598719da | |||
| 5c8683139f | |||
| 130d4b1bdf | |||
| 16fcd78f03 | |||
| 7ddc2cc073 | |||
| 81c746c2a8 | |||
| bef009c9dd | |||
| fedf064088 | |||
| b3e8c65e5e | |||
| 4cf7ddfd87 | |||
| c4edd86aeb | |||
| 152874eaed | |||
| 76f54b51c1 | |||
| c9cba6433e | |||
| 313dc32606 | |||
| 42001234ab | |||
| 6e885e5775 | |||
| d4d1d03455 | |||
| 7375383d26 | |||
| 9a66191ea8 | |||
| bd53a30e76 | |||
| e679d97100 | |||
| 04f70c92a8 | |||
| 0d29774401 | |||
| 3ae21095df | |||
| 626ccfe410 | |||
| ddf293a081 | |||
| cefa1dc5cb | |||
| 3e96b724c2 | |||
| b96def885f | |||
| 5c0cdd4d2d | |||
| f019de6900 | |||
| 51797d133a | |||
| 3cb76d5c66 | |||
| 047bda32d8 | |||
| 3cfd7fcbbf | |||
| 559e1f76f9 | |||
| 9acf93b7c6 | |||
| 969f0c4456 | |||
| c3cf1be344 | |||
| e35959fad2 | |||
| 7452f9a56e | |||
| 1c804124d1 | |||
| 980d84e4a2 | |||
| bf5e930468 | |||
| 9f82ac18d4 | |||
| 739d7caa32 | |||
| 6148c3525e | |||
| a6bbe06379 | |||
| cc5a1d612e | |||
| ae66ce9d22 | |||
| 99a286ef24 | |||
| 8b554d3c2d | |||
| df55aaec1e | |||
| eebd4cad66 | |||
| e8bf4417ef | |||
| 7df392bfd8 | |||
| 4d3915f69a | |||
| 81e814d9ed | |||
| 0050df8750 | |||
| 97878645bc | |||
| 01b5971c94 | |||
| c209f795b5 | |||
| d3b0bda011 | |||
| b48b2d43b0 | |||
| 0baf0bdc24 | |||
| 39854ceda4 | |||
| 8d3850ac02 | |||
| 1862d1995f | |||
| fc1694c97c | |||
| 9233472bdd | |||
| f0434d60b0 | |||
| 2799829bc9 | |||
| 933dfed4b8 | |||
| d5e6503fe5 | |||
| 6441620f45 | |||
| aa14b6d2f3 | |||
| 01f40cfafc | |||
| b4112a5878 | |||
| 3942b1f362 | |||
| 1eb9ef6bbf | |||
| 38909d7959 | |||
| 18f4e55692 | |||
| 0f288d1082 | |||
| 82c1c68560 | |||
| 780b713016 | |||
| 9ab59fb22e | |||
| 7b022371ea | |||
| 286055b0d8 | |||
| 2cebe5a3b0 | |||
| 2998248dd3 | |||
| 352b121202 | |||
| 4194b7effe | |||
| 742fb559f7 | |||
| 955f489621 | |||
| 05f52b697f | |||
| ad68b79630 | |||
| 8527d895bb | |||
| f50817120e | |||
| 93d6e800b6 | |||
| a581ddd896 | |||
| 1b6dd03fd7 | |||
| 28974e7290 | |||
| ffb9e877e9 | |||
| 1e879e1ab1 | |||
| 57829d81ea | |||
| a20a273982 | |||
| e9b31a70bf | |||
| a1532582a6 | |||
| 68bcff26fb | |||
| 691fb1ffae | |||
| 7392ce0a81 | |||
| 80df9ddedb | |||
| 1260060d7d | |||
| 433bc81b30 | |||
| c8bf176558 | |||
| cfd5caf29d | |||
| f461d0cb7a | |||
| 09b0193186 | |||
| 252feb4774 | |||
| 537a978dcf | |||
| 16a3773a34 | |||
| 01c5a0ed12 | |||
| b3ac274617 | |||
| de49ed3c15 | |||
| 33dc41056f | |||
| 4514158e43 | |||
| 5a918986cc | |||
| 9c6ff4d955 | |||
| d367e159c1 | |||
| db78fcd11a | |||
| dc1b01e002 | |||
| 979f88f6db | |||
| 8512ca7490 | |||
| 67ef84d883 | |||
| 4d7f9e06e8 | |||
| b6e8a47fca | |||
| ed0065266e | |||
| b5fd7868a8 | |||
| c21ed69731 | |||
| 7ca9e49749 | |||
| a69fd6029a | |||
| 3c31d6add3 | |||
| 7323823b38 | |||
| b2f6aedec9 | |||
| 46dd502f4a | |||
| 39346f3204 | |||
| 32b44173e7 | |||
| 00f222a9b4 | |||
| 920427af5e | |||
| d55e44f0b7 | |||
| 92298c88bd | |||
| c963757b43 | |||
| 47b2511f07 | |||
| 52b4fe63c1 | |||
| 46be45b4f7 | |||
| 64eb69cb15 | |||
| 03e7b71707 | |||
| e06c696b3c | |||
| 40ce9f97d6 | |||
| 0bc44376a5 | |||
| fdf549b921 | |||
| f50858dd24 | |||
| 0f8a266787 | |||
| a242556b1d | |||
| decdae515b | |||
| 9ff14bc411 | |||
| f609ddba05 | |||
| cc903d0605 | |||
| a8e550f5bf | |||
| 021ff0efa6 | |||
| 6e2a68fdf3 | |||
| 1048b235bf | |||
| 5ae3693567 | |||
| 1e869c5e49 | |||
| f49936a849 | |||
| 90c74e3be0 | |||
| ca599eee40 | |||
| e38b54a786 | |||
| b9b40a73ba | |||
| 4552ca98c4 | |||
| 9e2395e7e0 | |||
| 05945bf00e | |||
| 9d78a1ea9f | |||
| dfec99691b | |||
| 8e40becab1 | |||
| 60eda6f25c | |||
| 2e78a3e5e9 | |||
| 966d35a9fb | |||
| 42447a7610 | |||
| ca50969c2b | |||
| 2d3e170370 | |||
| 8a37fc8223 | |||
| a5c20f8592 | |||
| 96a2edb375 | |||
| 15b313ce4b | |||
| 1ea6568951 | |||
| 56654ae360 | |||
| 9a3e53e738 | |||
| 2243bfa181 | |||
| 33cd7f38a8 | |||
| 2fc0ce5c24 | |||
| c5d009d6c4 | |||
| 7d28541bbe | |||
| 8c2d712fb0 | |||
| c3eb1254cf | |||
| 89697310b0 | |||
| e6615c5825 | |||
| 7cff60f4f6 | |||
| 251610f6a1 | |||
| fb03330ea3 | |||
| cfd498a8eb | |||
| baa21484a1 | |||
| 0a306f8804 | |||
| 9a0beda037 | |||
| 09e6c82190 | |||
| 95d6002f16 | |||
| e245aed6bb | |||
| e9ec52368f | |||
| 0ef7387298 | |||
| debe99f1a4 | |||
| 031568831c | |||
| 497d92e7d1 | |||
| 1cb0dfa669 | |||
| 4e7a14355d | |||
| 490b327be9 | |||
| ff35726fc3 | |||
| 31e0d90da6 | |||
| b34f0d99bb | |||
| 66f2000548 | |||
| 91e9e6489b | |||
| f820df2ea0 | |||
| a91dcb015d | |||
| 781931a671 | |||
| 4dc2313527 | |||
| fd4761ba31 | |||
| 3119f0a61b | |||
| 6e9d0d9a0c | |||
| 938d42a89f | |||
| 1648e9292c | |||
| d5e314e728 | |||
| 937a096bf1 | |||
| b0209ad7f7 | |||
| f5b98bea41 | |||
| 51e687f7a9 | |||
| eac5cab5cb | |||
| 5e62e71b13 | |||
| 54e7f08760 | |||
| 838947bb8e | |||
| 80747088e3 | |||
| 56dd7eda0d | |||
| 588eba3b37 | |||
| 5525cc4d09 | |||
| c0fe522c9d | |||
| 18034a5138 | |||
| f7981a8ae8 | |||
| 78a566611d | |||
| 73240b736b | |||
| f260b13a6f | |||
| 3e0b1f2845 | |||
| bf41e791ff | |||
| bac151675a | |||
| d5d16bb3b1 | |||
| aeb260a3f9 | |||
| 7be3d3ab2c | |||
| 216baf5b11 | |||
| 341e7b3be2 | |||
| 37ce3b8cfe | |||
| 33f77774c5 | |||
| 98c26d95e5 | |||
| bba8c0beac | |||
| 885ce6b348 | |||
| dcca0b499c | |||
| bd34f6dd98 | |||
| d8c352d20d | |||
| c1545c6f2a | |||
| 1e9bd59f07 | |||
| 55a9fdf051 | |||
| 066c775321 | |||
| d8e470fc30 | |||
| d16fb30512 | |||
| 02c48ab7d6 | |||
| d81d51d155 | |||
| 466a98f7c3 | |||
| 8b23d1ec64 | |||
| 0098c4b571 | |||
| 7e3d7677ae | |||
| ff00220302 | |||
| 8ed25ad75f | |||
| 0a708e4070 | |||
| 408107ce6d | |||
| 40b2dfae09 | |||
| 3558da9ab7 | |||
| 9d24b3c3b0 | |||
| 0d791189ee | |||
| 411be4fde8 | |||
| ddd91bcebf | |||
| 1e1f20cfee | |||
| a21be6706d | |||
| 779dad12fb | |||
| 297a92cd94 | |||
| 89eee6ca99 | |||
| 0d5b739d35 | |||
| ec5244a73a | |||
| 13a0a37e63 | |||
| 846e6f731a | |||
| 7b0b12de58 | |||
| 3d1355efc1 | |||
| dbcc55a196 | |||
| 0f1fdd885d | |||
| 441eeef319 | |||
| a8d0c18248 | |||
| bbe007159a | |||
| 24ca6aaada | |||
| 913c266b4a | |||
| 23fea91e84 | |||
| 47db20eced | |||
| a041105491 | |||
| 484c68cbb8 | |||
| 56e8827ce0 | |||
| ea535abd50 | |||
| 15db8243ef | |||
| fe00689757 | |||
| 454e5e5fa4 | |||
| 706b8a6266 | |||
| 559b538be8 | |||
| bb9bd3132a | |||
| f2decec3e8 | |||
| 514b202d7b | |||
| dff7037156 | |||
| 9da4fe4b02 | |||
| 6025738b8b | |||
| 7a4b2e18a7 | |||
| a3fda24597 | |||
| f332f98757 | |||
| 4760d32937 | |||
| 33f5ac5c15 | |||
| 59a41c1c51 | |||
| 345cd1242f | |||
| 3d2a24f61d | |||
| 50a0a167f0 | |||
| e2e25e9af3 | |||
| 76afd9a1b5 | |||
| b37387ef90 | |||
| 21c0acff24 | |||
| 1bf811c3f1 | |||
| 587dca9b1c | |||
| e539a9632d | |||
| 6a0d3b06f2 | |||
| b71a27b96c | |||
| 406cfc48c9 | |||
| d69b7c332a | |||
| 05846438e3 | |||
| af5e631a7a | |||
| c29b09d093 | |||
| c2caea4818 | |||
| e837d69f8f | |||
| 34e4e66bf1 | |||
| 9b6424e0c6 | |||
| 62854dcc0d | |||
| 75c7917643 | |||
| ddf82d0b15 | |||
| 59082c8ee8 | |||
| e4184195a2 | |||
| f4c9bc8bc4 | |||
| cb1dc7cb6e | |||
| 7c226ed7a2 | |||
| 1bd18836d7 | |||
| dd9da53860 | |||
| fdbed4a473 | |||
| 14b006e808 | |||
| 2177c7c5a8 | |||
| 750162acb3 | |||
| 3efe131480 | |||
| ab84de967e | |||
| 58a11ac079 | |||
| 69d84c8f3e | |||
| 3a3f4038bf | |||
| 09ba5a28d0 | |||
| 79ab6567ee | |||
| 7376c5311b | |||
| 46ada3886f | |||
| 60a689d27c | |||
| 7d7f5c196d | |||
| 12dcb1555e | |||
| 00c2930709 | |||
| 23fc5930b7 | |||
| 09d392f09d | |||
| a80e0cf8bd | |||
| f52cac9d47 | |||
| 9633e2c93e | |||
| acec99876d | |||
| db78de9c3b | |||
| 5df2713b16 | |||
| 5feca50f58 | |||
| 1dd7f546af | |||
| 769fe82743 | |||
| e5ece03db1 | |||
| 6f04385a0e | |||
| 134a3f165d | |||
| 74fc9acdd1 | |||
| a388806555 | |||
| 2ced3ba276 | |||
| eb2e061e3f | |||
| d430e802f2 | |||
| 12f01b778b | |||
| 21e38f2949 | |||
| be507b20cd | |||
| 9f697510ca | |||
| 4bb4c92f68 | |||
| 4a68cc1675 | |||
| 33e659786f | |||
| f838a832b2 | |||
| d945aff132 | |||
| a9b91bb400 | |||
| c9ccf3b55d | |||
| 706828a6d9 | |||
| 01345fc159 | |||
| 6f2fb383e6 | |||
| 44ab680613 | |||
| ddf220e136 | |||
| 32a4ec156b | |||
| 2eab5eb6c0 | |||
| 7749eb5d1f | |||
| bd5a222d84 | |||
| c7bfdc2063 | |||
| 55df326589 | |||
| 6282ff0887 | |||
| ea35fee5b8 | |||
| 0e5fec288c | |||
| c0cc51cb4b | |||
| 5dd76a4791 | |||
| 2bc4486966 | |||
| 344d9fd83f | |||
| 4a0152c731 | |||
| 7d245e0f29 | |||
| 5de01fde53 | |||
| 108bb75430 | |||
| 4613d37eba | |||
| 05b1636780 | |||
| 2f7c926670 | |||
| dff9d2288b | |||
| d3071db0d7 | |||
| 8e088d38a5 | |||
| 31da833574 | |||
| 96cc618410 | |||
| 08dd126f08 | |||
| 0051208684 | |||
| d2b10d8aa1 | |||
| e1b0d341e4 | |||
| 1b2c11e7b3 | |||
| 4094b2d7a5 | |||
| af0942c78f | |||
| f0282337e3 | |||
| f88e9a748a | |||
| 08ad3b500b | |||
| 56f17e4921 | |||
| 293ea03dcc | |||
| aa485ccd75 | |||
| e9037644c3 | |||
| bef1b5322e | |||
| e6f3f3c029 | |||
| 7746d9b7cc | |||
| 3494d640df | |||
| c22cc67ba8 | |||
| 558054a53d | |||
| c7b471f10f | |||
| f4ffcae8d9 | |||
| 0422054aa1 | |||
| a81f0a5123 | |||
| c36582d2df | |||
| d50c07e303 | |||
| 54693b3fa7 | |||
| 3c3bc123fc | |||
| ac33cd688c | |||
| b5e42d8cc1 | |||
| 7e4e8921bc | |||
| 6dcd455ac4 | |||
| 1d58e1a14a | |||
| d122510c4f | |||
| 6613d14261 | |||
| a14e524b32 | |||
| 226ff93917 | |||
| d28e6c9b36 | |||
| c16f465ff5 | |||
| 3231c2f995 | |||
| 16bcc30e42 | |||
| 69c50e0181 | |||
| 486c40f578 | |||
| 08e38e9ff9 | |||
| ba3b902da7 | |||
| bf94e6a91c | |||
| ecc53dd7a4 | |||
| fc0e0239b8 | |||
| 1a18fa1c94 | |||
| 7825cbeb7d | |||
| d38fee7599 | |||
| e0ef293645 | |||
| fcf971bded | |||
| 9533982729 | |||
| fb4b4cbf58 | |||
| 21d06f5ab2 | |||
| 07a4f571d9 | |||
| 5e2c578b50 | |||
| bf42b9603b | |||
| 603864dba2 | |||
| 4f2612fcfd | |||
| a413423ff6 | |||
| 1a8d7f9587 | |||
| 7213e5f68a | |||
| 37d300f250 | |||
| b57be28920 | |||
| 5eb67cc2cb | |||
| 3143f2fb50 | |||
| df21a24f81 | |||
| ee2008abe8 | |||
| 1d77d697ef | |||
| cf0f47f589 | |||
| f7d36bbad5 | |||
| 274b361ca3 | |||
| d81a0df489 | |||
| e7ac52d17a | |||
| 7e26cf569f | |||
| e390c8c728 | |||
| b23e536894 | |||
| 5547398786 | |||
| 7eba9055e0 | |||
| 2a8ef1d065 | |||
| 0303e8067e | |||
| 11981c31f0 | |||
| cd13b30fde | |||
| ec0508269a | |||
| a3b515c524 | |||
| e1be6d0888 | |||
| a275489f0a | |||
| 190d00ea3e | |||
| 31fbe8caeb | |||
| 1862c5fbb2 | |||
| 8b33c6fa8f | |||
| 1c3d83df54 | |||
| 22bb5d1fcc | |||
| b29cde552a | |||
| 10d8e956f4 | |||
| f533c05644 | |||
| 933ad0e710 | |||
| d2add41b6b | |||
| 0a6e93dd3a | |||
| 3ef067cc65 | |||
| f903192c17 | |||
| e2a9df408f | |||
| ad70ab404c | |||
| cea2dafa0f | |||
| 536634b1fe | |||
| cdfdf29eca | |||
| 32c386786e | |||
| 6208ab4e49 | |||
| 79100efec6 | |||
| cba401fe53 | |||
| 8660d550d3 | |||
| 666de1b087 | |||
| f3af90c6c7 | |||
| b15a9d675e | |||
| e0b3751c17 | |||
| 894f922cfb | |||
| 5937e58a11 | |||
| 949410b347 | |||
| 5618f4a0ac | |||
| 036c3b4e6d | |||
| 9df5400200 | |||
| c63f443bba | |||
| e15dabf1db | |||
| abf30e44cd | |||
| 602bd60c3a | |||
| 6fefc53e56 | |||
| d0e16b21d4 | |||
| 76235cbb70 | |||
| 9d006f6a1d | |||
| dc265071d0 | |||
| 68a0347ff9 | |||
| a28a556f60 | |||
| f034320731 | |||
| 6a05939e1c | |||
| 7b1eb3af7b | |||
| 319b6a447f | |||
| b484f377dd | |||
| 3934d61de7 | |||
| 4ecc023219 | |||
| 8694ba0978 | |||
| c1392f64a4 | |||
| 4e7bd86fad | |||
| 9c3f95782d | |||
| a98ee0d3b2 | |||
| 73a8e65cbd | |||
| ae0d428b62 | |||
| 32d7c1950a | |||
| 5603617b7c | |||
| 43aae3fee8 | |||
| a7a4a2ae30 | |||
| 1b8c2589c0 | |||
| 8c65f8a0d1 | |||
| 887736bcd4 | |||
| 5b1967f80c | |||
| 3a1bb93340 | |||
| dfb49097e3 | |||
| e009d79cc8 | |||
| d7bb1025f3 | |||
| 771af4f32d | |||
| dc441f50cd | |||
| be499b42d9 | |||
| c223c05b82 | |||
| 84850ae714 | |||
| 7c16ad3f49 | |||
| 74f5eaf70c | |||
| faa6684373 | |||
| a78da45fec | |||
| 7ddc0bdd37 | |||
| 74fcefedcb | |||
| 8031742817 | |||
| 43b76e548b | |||
| 016011fdf8 | |||
| 4b0f3bf188 | |||
| 072b1469e7 | |||
| bd43c62a75 | |||
| a11ff876d4 | |||
| 94cf5430d0 | |||
| af9c558764 | |||
| 0be2d4188e | |||
| f660461bb3 | |||
| b78eb49178 | |||
| 4ab2771957 | |||
| 4aefb9f2fc | |||
| bbff288447 | |||
| 7bb3feff45 | |||
| b33853c5be | |||
| 587b0cc7b4 | |||
| bef2b27155 | |||
| 69db797ebb | |||
| 96fa0ef752 | |||
| 3656a1aa66 | |||
| 84ecf4b1dd | |||
| ef1d4eba84 | |||
| edcd2c0408 | |||
| e2b677ddcf | |||
| b6869df556 | |||
| 622301c78a | |||
| f6b758699b | |||
| 784f77a4a5 | |||
| bd8bac27d5 | |||
| 1b1246cbae | |||
| 702afcd760 | |||
| ff8aa6662e | |||
| c385ac575d | |||
| 9d01818e8a | |||
| 6c42112555 | |||
| b668d3f693 | |||
| 0629add3f7 | |||
| 85cc11e3b2 | |||
| 680efe1a97 | |||
| b8956d0111 | |||
| 44f8670719 | |||
| 14c0bfce2f | |||
| a8656ea20f | |||
| 9734abdc1a | |||
| 1f7fc6875f | |||
| 3b97549bb1 | |||
| c1778f1199 | |||
| fc0b997064 | |||
| 3afe8832c5 | |||
| 58e5aca631 | |||
| 4722b2d0e5 | |||
| f100cdb6d4 | |||
| 973abf0d62 | |||
| 4a067dca58 | |||
| 887d8d091b | |||
| 76da19d543 | |||
| be89b0505a | |||
| a33d98c13a | |||
| a00b37d209 | |||
| b757359ff8 | |||
| ca5e07d342 | |||
| 3172e6d54b | |||
| 365603e1c2 | |||
| 421e1b237c | |||
| 9449af8ada | |||
| 5ee00ec5c6 | |||
| 58934f1e16 | |||
| 8e5ce69ee8 | |||
| 9b0f5e61d1 | |||
| d8d78b4a98 | |||
| 7da16d6f47 | |||
| 75fcedf0ed | |||
| c19ed39a78 | |||
| 0e4bd80b80 | |||
| 793bdaada7 | |||
| dbd7912b88 | |||
| e65de8d1da | |||
| ac37b77452 | |||
| 306aa0e699 | |||
| 1afc9eb730 | |||
| 5a0af53683 | |||
| 370d1ff21a | |||
| 6d68f72473 | |||
| 47cee8715b | |||
| 56cdd6f14f | |||
| b70e27e076 | |||
| d1b882ddcf | |||
| b2489d31d6 | |||
| 7719da9552 | |||
| 079ceea616 | |||
| 8d264d9f64 | |||
| 612822367d | |||
| 855765986e | |||
| e866680d96 | |||
| 30e6725006 | |||
| d0210f510e | |||
| fbcf5f0918 | |||
| cf4025c224 | |||
| 68f8d1cef0 | |||
| 9e4c62967b | |||
| 53a92983a4 | |||
| 9e065bc802 | |||
| 03bab0fc0d | |||
| 11a829f9de | |||
| 6483919b17 | |||
| d674965bf9 | |||
| e0b327aafe | |||
| e1ad86c1fa | |||
| 34aa4e4578 | |||
| d789c810bf | |||
| cb324b4ec3 | |||
| 2255472e31 | |||
| ef16650f5c | |||
| 89889ae8ea | |||
| c119e04947 | |||
| e8a1bc2bd9 | |||
| 6bb8afde96 | |||
| 131d7c394e | |||
| ef0d1c1c3f | |||
| cda9ed449f | |||
| 09b9b0fb9e | |||
| 3316e58314 | |||
| 447b8bf58a | |||
| aed9f5d5e8 | |||
| 894c2468df | |||
| 9b2a7fe723 | |||
| e9539061db | |||
| 11b3529b39 | |||
| 53effc529b | |||
| 0dab097a26 | |||
| b09f591dda | |||
| c7f420ba75 | |||
| 98078c231e | |||
| 1d92a73a55 | |||
| dd8589c352 | |||
| 29db3c2f17 | |||
| 8293ed7f9b | |||
| d0344cd308 | |||
| ba7bf1ef68 | |||
| 67ca143a0b | |||
| 573858f134 | |||
| b76d351419 | |||
| 4a2aad5bba | |||
| 9ff69dbf4a | |||
| 5a53f41622 | |||
| 21467d817b | |||
| e976c448b7 | |||
| a64d096369 | |||
| c545857ea6 | |||
| 4cd78bc7ad | |||
| fe62243805 | |||
| 2cb47b4191 | |||
| da0c159557 | |||
| 63bae5da71 | |||
| 80844fd554 | |||
| d83d2d4c2f | |||
| bd4c685553 | |||
| da948c82b4 | |||
| 0f8c46f368 | |||
| 3f65a86977 | |||
| c10230f81c | |||
| 02906bf23a | |||
| 5262371660 | |||
| 2de3a24f46 | |||
| 57bff43aec | |||
| 5c4c8bcea3 | |||
| 157c94c03e | |||
| a96a6bf149 | |||
| e05b6bb6e7 | |||
| c4c3f1b25e | |||
| 56bde913d4 | |||
| 9ab291ea1c | |||
| fe0a17e78f | |||
| 0185cb27eb | |||
| ea10290153 | |||
| 1704aea6a0 | |||
| 429d280501 | |||
| b7c9aaa471 | |||
| 1245cd1752 | |||
| 6922b94894 | |||
| 2b2bc83b61 | |||
| 9dd41a8187 | |||
| 1f5fd865aa | |||
| 9a3dccab20 | |||
| ac6ca660f4 | |||
| 383b7e9dd1 | |||
| 6bd01a96d9 | |||
| d4774ead43 | |||
| 6f47c26acf | |||
| 945663bc9b | |||
| 0263b49298 | |||
| c2f59a0f73 | |||
| 2838ccc78e | |||
| 0a4830b3d5 | |||
| b102bc6678 | |||
| c8f863dfc5 | |||
| 4eef486afe | |||
| 9bcccb028b | |||
| cd5c70691a | |||
| b36f565d13 | |||
| ed7907e46c | |||
| 1ef8cf5a23 | |||
| b2c592255a | |||
| 47e7a7a7ce | |||
| c94945f892 | |||
| 6b8e13d017 | |||
| 0e4bb2b49f | |||
| 274aba1a89 | |||
| 2a6d4b6ee2 | |||
| d9148ea604 | |||
| ecd3661119 | |||
| 9eda260495 | |||
| 3ed54b9008 | |||
| be70df1187 | |||
| 6a6ccf6032 | |||
| f40b580bb8 | |||
| aea4157340 | |||
| 11c3fa527a | |||
| 132416ebe9 | |||
| 46e457d340 | |||
| 14d7b38613 | |||
| 6b954cd24e | |||
| 42ba5c7d16 | |||
| 72ddeea479 | |||
| 6d3bc7c82d | |||
| 9ad84896da | |||
| f53d3de73e | |||
| 869dda4117 | |||
| 07de67c32f | |||
| a00eb1e9f5 | |||
| ec0f901153 | |||
| c0b544af70 | |||
| c1c0f23fd1 | |||
| c467d0d553 | |||
| c0ee03fab2 | |||
| c976c1192d | |||
| 61c0ff007a | |||
| 03824682ad | |||
| a7805301cb | |||
| e26b941e66 | |||
| 89392b2a6d | |||
| 0906744788 | |||
| b6d88f21af | |||
| ef05318c69 | |||
| 6c452addfe | |||
| dac071ed78 | |||
| 76296fb672 | |||
| bbe75fe1d2 | |||
| 7522527827 | |||
| 2b7637df36 | |||
| 2c1650ad33 | |||
| 7b7d54df68 | |||
| 4691d98e19 | |||
| f363670934 | |||
| b8f93e08e9 | |||
| 2c2645191a | |||
| 67158b12cd | |||
| 0726c4d4ea | |||
| ae71f0c086 | |||
| beed99dbc1 | |||
| e0cea92f6e | |||
| 00b72df6c5 | |||
| 4c1cbffd2a | |||
| 9e50cf5375 | |||
| dee05f982b | |||
| 4bf82e50d0 | |||
| 0688bb61ed | |||
| f77926675f | |||
| ed574171bb | |||
| aa871ca506 | |||
| 6116a2fcf8 | |||
| fcc842f08b | |||
| 38723b0339 | |||
| 2e86d46cf2 | |||
| 88e66697a7 | |||
| ff90f2736b | |||
| 06617392e0 | |||
| a6f46d7bb1 | |||
| 0b99f70773 | |||
| b1842a4b89 | |||
| 2909e07cb2 | |||
| 41d8c4d879 | |||
| cd8143be0a | |||
| 4997f5dfe9 | |||
| 743160b6ac | |||
| 92777281a7 | |||
| 40fcc9d149 | |||
| 8bede85f60 | |||
| c0d61964d6 | |||
| e2fe0ca835 | |||
| 2ba0d31785 | |||
| 56ad207d37 | |||
| 2f0de3aa2c | |||
| ca692b9804 | |||
| f4cb8c0dfb | |||
| 885114ed2c | |||
| 3ebb5d0e3b | |||
| 172c00faa6 | |||
| 30a5a9ed34 | |||
| c81b064727 | |||
| ca8312b0b3 | |||
| b29e473c21 | |||
| e379ea6ed6 | |||
| 80eec9d531 | |||
| 0ed0f2953a | |||
| 426b3f6198 | |||
| d5afd070ce | |||
| 20bf88bad1 | |||
| 9dfa9a81e9 | |||
| 90c398ea67 | |||
| ff1687d378 | |||
| 6a6d58d389 | |||
| 65e0387aa5 | |||
| 12362f76b1 | |||
| 790ef21a60 | |||
| ed38ca5179 | |||
| 8869150649 | |||
| 5dddb47863 | |||
| 50b453e5c2 | |||
| cf0fdfa2bb | |||
| 658f96b447 | |||
| d0c43f16e0 | |||
| fb4698e7fd | |||
| 8ed45609d0 | |||
| 15ea401087 | |||
| db0cc56c52 | |||
| f958f29c55 | |||
| ccdd1126f6 | |||
| face069874 | |||
| f56563d6fe | |||
| 898b257261 | |||
| 62cad09c64 | |||
| 8a21726ae5 | |||
| febd0f14c6 | |||
| f92e2ed57a | |||
| 7b01e32fe8 | |||
| 6803d1ed28 | |||
| 3f68787051 | |||
| 04b2edcc8c | |||
| ee68d26f99 | |||
| e66a4a0e12 | |||
| 24e2a008c3 | |||
| eb4bd6b4fb | |||
| bb556b8f55 | |||
| bc544e2a70 | |||
| 7b784fa2ea | |||
| ca0114228c | |||
| 851f20e40c | |||
| 8298644b85 | |||
| 56e637d5f4 | |||
| b6e5e66661 | |||
| 6eb8d0aa51 | |||
| e02195b3dc | |||
| e57609836c | |||
| 101607a7d0 | |||
| 8439b5942b | |||
| 53fc5440d7 | |||
| 7761331a75 | |||
| 56b2b450ce | |||
| c8167c0b99 | |||
| 2f8ef61618 | |||
| 945aa06f58 | |||
| 707d10f115 | |||
| 81e1c043cc | |||
| bd90425f71 | |||
| 0f59bbbee6 | |||
| a1cdbd4d84 | |||
| 73031f9ab0 | |||
| d64c8aad99 | |||
| 902e381264 | |||
| 2ff614dfab | |||
| 83b2621de4 | |||
| 83a4ad5f51 | |||
| e7b82a8561 | |||
| 59ed7d06bf | |||
| 217dd63e02 | |||
| e633c991b0 | |||
| 815cd8970d | |||
| b5c4355c13 | |||
| f9c4c96663 | |||
| a2dbd2f10e | |||
| 88bc88125a | |||
| 770e742e04 | |||
| 11fb1f74cc | |||
| 6ab9df5208 | |||
| 9f1c641199 | |||
| 00fb8a3abf | |||
| 032b6322fc | |||
| a5a21019b2 | |||
| a55a8c9aa5 | |||
| b98a54fbe0 | |||
| 11ca4e61a7 | |||
| 2bc16e83d6 | |||
| f11ed4b91d | |||
| 80bd67c36b | |||
| 83b882039e | |||
| a816a4b964 | |||
| bfa77ff5a4 | |||
| c79ad45fce | |||
| 48cc53bf2e | |||
| f63dde2f43 | |||
| 7bfd070864 | |||
| 1ce0ef9d41 | |||
| f30bf39bd4 | |||
| bf8434770f | |||
| e055128d0d | |||
| 66216ea2be | |||
| d882797fbd | |||
| 220bb14d10 | |||
| 0824ed595b | |||
| fd225469bc | |||
| 12e6efc6e4 | |||
| 0fcc5face3 | |||
| 125782c061 | |||
| fef7509eed | |||
| 546e68dc65 | |||
| 510dec4927 | |||
| 9394486147 | |||
| 01c3ed6157 | |||
| b7c2a46830 | |||
| 719099ad6d | |||
| a003d1d758 | |||
| 2e9004813e | |||
| f824db4803 | |||
| 0c67c6c136 | |||
| f846bb2b49 | |||
| e79c184b2d | |||
| 6724a0b8cd | |||
| 5123c3e52e | |||
| def2256609 | |||
| c613ee2da4 | |||
| a482dcce46 | |||
| d647261de2 | |||
| b7cfd5a7da | |||
| caa0058d5b | |||
| dac715ad1f | |||
| 061131a5ee | |||
| 26d9a7cd40 | |||
| caaf60ba00 | |||
| 3e2515d735 | |||
| 3f2666778a | |||
| 959d575292 | |||
| 50842b9036 | |||
| 3d6413cfc6 | |||
| 799622affd | |||
| 57ab0d4d17 | |||
| 1f983ec39c | |||
| a345d16cc1 | |||
| 02f8b85dd9 | |||
| 1fbdca0c9b | |||
| 0d821f04fd | |||
| 8184e57dd6 | |||
| 78ddc567f9 | |||
| 424c2bddb3 | |||
| c12243cf4f | |||
| 39fdcf4df3 | |||
| fd1b30fc6f | |||
| 7ee79b73f6 | |||
| 1f3043f618 | |||
| 1d7d22e117 | |||
| 9eaac6105f | |||
| 33ab9ea188 | |||
| af62624849 | |||
| 8ad6ba82fc | |||
| 83ace8d580 | |||
| 851ce27240 | |||
| 737a1e2f12 | |||
| 850e3c1ca2 | |||
| 7541c590e5 | |||
| caffbaafbe | |||
| f57fb2375e | |||
| a28c8d002d | |||
| a4073ed676 | |||
| 78e07d3210 | |||
| 41af58d1d5 | |||
| bf5393ae58 | |||
| b866e2672a | |||
| 1df0f1da97 | |||
| 535dc1e874 | |||
| 24dea1c616 | |||
| 70f8d807c8 | |||
| 96c3f16a90 | |||
| fd860d7cd0 | |||
| b46719b093 | |||
| 8b8fc9e66b | |||
| 882c0321f4 | |||
| 8c3c6b31fc | |||
| 5a94a95fbf | |||
| 036c438904 | |||
| 5e095c8fbd | |||
| 665a317f1c | |||
| daa21a4385 | |||
| f7ad192842 | |||
| 58cf11bd44 | |||
| 549ef8f141 | |||
| 176dd96698 | |||
| 5f8f56ea0e | |||
| 47d8187bc3 | |||
| 481f786fe7 | |||
| 3408114602 | |||
| bd2c2f3bd1 | |||
| a4a2659dff | |||
| aa932eab41 | |||
| 565d3dde40 | |||
| 85c08dd170 | |||
| 8bc21fc2f0 | |||
| 57c3e917e2 | |||
| 7658c2e2d5 | |||
| 993e0b0bf9 | |||
| 9aaa27d46b | |||
| 6c55e7c039 | |||
| 1df244b6f4 | |||
| 13cef0cdfc | |||
| 75558ae75c | |||
| eb40dde688 | |||
| bb72206ec5 | |||
| e9c765ee2c | |||
| 83723c15be | |||
| 8454a8f2d1 | |||
| 6aedd4f7b0 | |||
| e96b8ce781 | |||
| b0cbec922b | |||
| 083aced3b4 | |||
| 0f7de40e66 | |||
| 5ad4bed70a | |||
| 330b3e87eb | |||
| 8fb37606f6 | |||
| dc587992a0 | |||
| 72ec9c159e | |||
| 5b00d9da49 | |||
| c1c03e16f4 | |||
| 6006790c18 | |||
| bb2e40b999 | |||
| b1a8e4f760 | |||
| ca1d8c1737 | |||
| ff6881efbf | |||
| 3c85200989 | |||
| e944533f01 | |||
| 85149f8686 | |||
| a12ec66a04 | |||
| 9d90b0549c | |||
| 3bc5958c58 | |||
| 2952c10ced | |||
| 55d1f0b7d6 | |||
| 60064b3de7 | |||
| 02eb8e7c70 | |||
| 786d62e3e5 | |||
| 13cd052990 | |||
| a4e5b09ea4 | |||
| 3ec0e0943c | |||
| 653810e4df | |||
| efa2baed83 | |||
| c9481b0fd7 | |||
| 8138e26163 | |||
| a04a0514b9 | |||
| a9ae0c8e82 | |||
| 3c2e12a744 | |||
| cb55d60f98 | |||
| 6e1a595342 | |||
| 5141141e2b | |||
| 7e6947a940 | |||
| bb989f2034 | |||
| 9c8255feeb | |||
| 4f95e6c70b | |||
| 55a5e6be2c | |||
| 607d3b54ce | |||
| 7ca0557b40 | |||
| 25b4cface0 | |||
| e9bc9c47c2 | |||
| 6a50a51b4e | |||
| 22c0238bf1 | |||
| acbc7362db | |||
| 2466ca02bf | |||
| 7fd5b3a0c5 | |||
| 74bb0beeb0 | |||
| a1a35ca5f7 | |||
| 90a78585fb | |||
| f5be8f6c77 | |||
| 526defab85 | |||
| 44d1738d47 | |||
| f32f0486e2 | |||
| 8e392251ba | |||
| 3863dc5b2b | |||
| 671a630f47 | |||
| d2aaa70e93 | |||
| 4418ee6c77 | |||
| c64a15294d | |||
| ef8182e12a | |||
| b204013483 | |||
| af47b6551f | |||
| 892684ebe5 | |||
| 4c67ae1a0b | |||
| 021473e93e | |||
| 08714c510f | |||
| b116d6c6e8 | |||
| 6b04c2b904 | |||
| acfbed8654 | |||
| 7061bf0000 | |||
| 6212084046 | |||
| dab78c26b1 | |||
| a6a0fc5b21 | |||
| d89b6226a3 | |||
| 11d1909e6b | |||
| fede94e979 | |||
| 6d0407b65e | |||
| 05a45ef6dc | |||
| 3c6fe75149 | |||
| 298c98ea32 | |||
| 00d9f690f6 | |||
| ae79fe10dc | |||
| 62fc342d35 | |||
| 36924d6dbb | |||
| ede4943d7e | |||
| 9d148c76ca | |||
| ab8afc3bcc | |||
| 21d8b588a2 | |||
| 5d66b1130b | |||
| 0550b2c1fe | |||
| d58d277707 | |||
| 95eed59f2d | |||
| 62bc647731 | |||
| af806bc816 | |||
| d67d32af48 | |||
| 7f63776395 | |||
| 6ac4a4ceb6 | |||
| 5cb70d34d7 | |||
| b5a7122855 | |||
| e936670571 | |||
| fc06a2384b | |||
| 432cf1152a | |||
| b9792fdc14 | |||
| 3136010e1a | |||
| 2fc92448df | |||
| e22979f334 | |||
| 0410fe6978 | |||
| a5242265d7 | |||
| 8b791477df | |||
| 268283ff16 | |||
| 6613519c2e | |||
| e0136e39f4 | |||
| 546f70a6f0 | |||
| f85eb23c3b | |||
| 78e89ba3ff | |||
| eb41a574b7 | |||
| 187ab0ca61 | |||
| 7cf5de0ed0 | |||
| 68e9d19743 | |||
| f0197006e0 | |||
| a85bb091c8 | |||
| 3d20157d4f | |||
| 55f78f8a83 | |||
| d08cb6b357 | |||
| d40eefd5a4 | |||
| 4a9b244577 | |||
| cc086b9452 | |||
| 35884a7e3f | |||
| 3109c77013 | |||
| a26ab3ab16 | |||
| 66eb270cf7 | |||
| 354ed5c4d6 | |||
| c52092e6f8 | |||
| 52fa55a770 | |||
| a87e1c2f90 | |||
| cc92cd07e8 | |||
| 7dd67f4997 | |||
| 3c769edea0 | |||
| 3c7f7de477 | |||
| ffabbfa778 | |||
| ca90667723 | |||
| 05d888316a | |||
| b37aaa8303 | |||
| 3cb4954d70 | |||
| feb5b6aa93 | |||
| 2e7e754032 | |||
| cab0ecdf19 | |||
| d3b0cb878a | |||
| 71002e0e79 | |||
| a41ac8fd40 | |||
| 8b3b2a52f0 | |||
| fe0ce9282a | |||
| 25bcca2edb | |||
| 31ef944176 | |||
| 06b0fa6fc2 | |||
| 6d1cbc6458 | |||
| 3f91b0d340 | |||
| a7160d9b12 | |||
| e22c09c601 | |||
| 61293a09ff | |||
| c8cb03fd8f | |||
| 6425ac3b13 | |||
| cbaf0ecaf6 | |||
| b95769333c | |||
| 242e64c08d | |||
| 4743184078 | |||
| 3f180b0ad9 | |||
| 1e00a93f97 | |||
| 450a276f87 | |||
| 0f53526598 | |||
| 780f4ae7c5 | |||
| 4af2eb22ab | |||
| cc94b393c5 | |||
| 5de9d8e6e1 | |||
| d3ef3cff94 | |||
| 568303ac7f | |||
| 09c26d6805 | |||
| 939c1d2474 | |||
| b8d40b4ad5 | |||
| ae933db526 | |||
| dfc508bb15 | |||
| 05bc7621e6 | |||
| a94fdbe0f0 | |||
| e7fcffeead | |||
| 8e82bed459 | |||
| 3fe69f4e67 | |||
| ab40c2acf7 | |||
| 7cd198623e | |||
| 16e20e5c73 | |||
| 9e97d7b4db | |||
| 58dd70e8dc | |||
| 53ff537f1c | |||
| 26d7da68fc | |||
| f6f5b6035b | |||
| 966d50762d | |||
| 01c3d491e7 | |||
| f052b0bc4d | |||
| a31b29308f | |||
| 3a53e726dd | |||
| d59a6b29d5 | |||
| a5814871d9 | |||
| cfcef3ec98 | |||
| f49544f310 | |||
| 1aa03cecf1 | |||
| 171b58e2ca | |||
| 7a3c0cb70e | |||
| f10537cdd6 | |||
| 9d294cbcf5 | |||
| f1bec940b1 | |||
| dd93d48be4 | |||
| ad3123adfd | |||
| f939d80f4c | |||
| ee316758ca | |||
| 6d7a61cbdc | |||
| b44b1ab47b | |||
| 2e47a1a61b | |||
| 72685cf01c | |||
| 612888c066 | |||
| e7b55f4982 | |||
| 3004f5fa30 | |||
| 9682d2afff | |||
| 87d655325c | |||
| db25e44a17 | |||
| b7a9e672c5 | |||
| 8e49ab1d3b | |||
| 00c36e88ef | |||
| cde697dd14 | |||
| 1756590117 | |||
| e49e75da06 | |||
| 1d40946959 | |||
| 2598392295 | |||
| 17cc5e2c40 | |||
| 4b14400976 | |||
| 4704a254f7 | |||
| 7708e9882e | |||
| fe1bd0cc2f | |||
| a752f25944 | |||
| bb44316028 | |||
| 0b2cfcfda2 | |||
| 9c02caf392 | |||
| c137ba53a0 | |||
| d87c30dc84 | |||
| 63d6cc5ca6 | |||
| 6b1d5e48b6 | |||
| fb56d5c482 | |||
| d280205245 | |||
| 0ee8634b2f | |||
| 9682430a69 | |||
| 73f760fdf0 | |||
| 931a519969 | |||
| 0baaf0a60f | |||
| 63a63e3eaa | |||
| 6b9e273f92 | |||
| 2c6114f58d | |||
| b69ffe6376 | |||
| 8ba1ec22e4 | |||
| 1f72815637 | |||
| 90c3d7d361 | |||
| 4bf6bd3d37 | |||
| 09930938e8 | |||
| 09e9e8ad9f | |||
| f4eebc46b2 | |||
| 34dacdea32 | |||
| 9ddb8bdb8b | |||
| 56856a1810 | |||
| 341de5d53f | |||
| b28056e3dd | |||
| 3e25c085ba | |||
| 5b9182ba43 | |||
| 5a31f6b4e1 | |||
| 2ec92ba440 | |||
| 01e351de37 | |||
| 441f93d58d | |||
| a33d7928a4 | |||
| 9c0b740b84 | |||
| 96b5ec14d4 | |||
| 79ac0d05ce | |||
| 40b765b7c2 | |||
| 2b1103c1d3 | |||
| f426778160 | |||
| f148eaace9 | |||
| 9b87c22e01 | |||
| 9fbd1d68ad | |||
| e01b485ac6 | |||
| 007a3ef8b6 | |||
| 83eb1d3608 | |||
| bbdf21679f | |||
| e2f74309f7 | |||
| 0ec5561b4e | |||
| 74e2b8cbcb | |||
| 7918267d02 | |||
| 135fa85e8f | |||
| d8f360316d | |||
| b73894b271 | |||
| 0746ec7035 | |||
| a8226814c5 | |||
| 30a3ff0de6 | |||
| dadf53f17c | |||
| 5c12c92243 | |||
| f39d351d04 | |||
| 0039690f11 | |||
| 9e29762838 | |||
| 07e07655d4 | |||
| e60dcc9b3b | |||
| 7245803405 | |||
| da229cce9a | |||
| 36af97d00c | |||
| d705c651f2 | |||
| ce7812fcb0 | |||
| 08848c56b7 | |||
| ebe979090e | |||
| bcf02ae439 | |||
| 8919c3162d | |||
| 2200e0fb7e | |||
| 0ded2984b8 | |||
| 5e44aa37ff | |||
| 9efc57f24b | |||
| 20156d1eeb | |||
| 1138a38dbe | |||
| 63dbeeaac5 | |||
| 655b28ee0c | |||
| 5455e38e15 | |||
| b99f7a29df | |||
| b599774e30 | |||
| e6f7e96ff4 | |||
| b4c7c011b7 | |||
| 3b5530fb67 | |||
| 2c73e49dac | |||
| 901d4995e3 | |||
| aad95c7d8c | |||
| d9b7b300b4 | |||
| 044de4105e | |||
| 7a5aa06b9e | |||
| a21fb63c28 | |||
| eaa9b78121 | |||
| fd4df0f67d | |||
| d6c95621e8 | |||
| 6decc2596d | |||
| 41b920344d | |||
| b94c513cee | |||
| 82668e06d4 | |||
| 614edafe73 | |||
| a81374c1d7 | |||
| 66fc6126d2 | |||
| 8b58b59df4 | |||
| f0595b8254 | |||
| 1e01441767 | |||
| c797746b6e | |||
| 1bf4427a5c | |||
| ac3ec0d96d | |||
| 5c6c537044 | |||
| f8c82fc214 | |||
| 9f7548ab89 | |||
| d2409d12c6 | |||
| 40b762bceb | |||
| 6a5f413f27 | |||
| 89e3c508d8 | |||
| 755527a90a | |||
| 1e90b2f51d | |||
| cbdddb473c | |||
| b4c2891ef3 | |||
| f57063efa2 | |||
| b057a62c8b | |||
| 1325213303 | |||
| fb15bdfb21 | |||
| 9d2d173485 | |||
| 12a3156aff | |||
| eee210f3b5 | |||
| 34bc3b8595 | |||
| 26e3bcb9de | |||
| 960dee8ab8 | |||
| 847976de4e | |||
| d825b7ee9a | |||
| 5ffb53f229 | |||
| ceec0eb33a | |||
| dcf177e372 | |||
| 30912b49f3 | |||
| 882dc0a7f6 | |||
| 4840c4ae6f | |||
| d8f62673d7 | |||
| 2b2e3ee93c | |||
| 08925330e0 | |||
| 1ea41e7246 | |||
| 02e29fc99c | |||
| 7dd19f6d97 | |||
| 415a212d09 | |||
| bac4999ae4 | |||
| 0b20ce696a | |||
| a69b435c92 | |||
| 063e4004ba | |||
| dce0405c4d | |||
| 8e493ef370 | |||
| 887fe932cc | |||
| 0f13208d81 | |||
| 737d866197 | |||
| 4c875dc393 | |||
| 60a51b82d7 | |||
| 99d0fcf49d | |||
| faf84e7100 | |||
| d01ee09fd6 | |||
| 926754a66e | |||
| 78eac67a01 | |||
| fa41653420 | |||
| cca78e0601 | |||
| 7ce116695d | |||
| 0fd1203b3b | |||
| b27467d9f9 | |||
| b4aa37aa30 | |||
| c879b1ab09 | |||
| 6916a1438f | |||
| ca9a2887fc | |||
| a984da911b | |||
| df55be3c3d | |||
| 55339de684 | |||
| f08dd510fa | |||
| de8d8720a2 | |||
| d308ed3712 | |||
| 6d0f8aa893 | |||
| bea98bd22a | |||
| 4539607ab1 | |||
| b320138dba | |||
| 95ea12588e | |||
| bcd08b5d18 | |||
| 19298ae3cb | |||
| 5e06da3050 | |||
| 17ac18a7b9 | |||
| c259590b26 | |||
| 3f3ca85103 | |||
| 05ddc16eaa | |||
| 2ba77614aa | |||
| ef347aa6a4 | |||
| b1cdb91139 | |||
| a09ad35d98 | |||
| 1b5835cd35 | |||
| 9932bbad3a | |||
| 39ac84ff04 | |||
| fcbefaff86 | |||
| bf2256fb89 | |||
| b0b2fc9e3f | |||
| 1ccd64e102 | |||
| 23bf3e337a | |||
| 3cf265992f | |||
| a855d230ec | |||
| 37f77e7397 | |||
| 5a552b6d8d | |||
| b02fc039cd | |||
| a362aca783 | |||
| 46a6f70d88 | |||
| 316d76bdb6 | |||
| 92f2ad0a11 | |||
| 17675b4cb8 | |||
| ce7590bd24 | |||
| bfbf864a73 | |||
| 1fcc83b84b | |||
| c7121e8772 | |||
| ee11a2d266 | |||
| 103336c76e | |||
| b80142be69 | |||
| bb0631a365 | |||
| 2358c79db2 | |||
| 00094a8792 | |||
| a0bc0ab7cb | |||
| cb00c7036f | |||
| a2bba1b9e6 | |||
| 81c5d58035 | |||
| 723c317108 | |||
| 17bedd72f0 | |||
| 4686b935c1 | |||
| 6a6619ec1e | |||
| 3b177eaaa3 | |||
| 3c797b0ca5 | |||
| 8c2bde2af4 | |||
| d22516872c | |||
| 17608f7ade | |||
| 81ebe28c24 | |||
| 2f95acf273 | |||
| dee3a4b528 | |||
| 26997f32c6 | |||
| b639353193 | |||
| 443b3157e0 | |||
| c094c58b51 | |||
| 740ae3581c | |||
| 97c78838a4 | |||
| 369a3d1426 | |||
| 728bd0ba84 | |||
| c436cac797 | |||
| e7c02f376f | |||
| f803c2a7bb | |||
| e630375fd6 | |||
| 4a65f3cee2 | |||
| 5c379aa1b8 | |||
| e800800bec | |||
| 5b3f89df0a | |||
| edb4a7ad03 | |||
| 259e41da73 | |||
| 35b2139929 | |||
| 052593c760 | |||
| 3646967deb | |||
| 0c24ccf538 | |||
| 225da0226e | |||
| f7792f0be2 | |||
| 27302c367c | |||
| 44f112a9de | |||
| bd2be9c79c | |||
| a153948a19 | |||
| 4273534c92 | |||
| 7274e2ff1a | |||
| 52c727f09a | |||
| 2d8b4fea9f | |||
| 9cccd87e79 | |||
| 581923fa57 | |||
| 979721c979 | |||
| ac22c524fc | |||
| 0e8bfff386 | |||
| 08c84e0c34 | |||
| caa03f72b7 | |||
| f75f2ffd48 | |||
| 54ab3137d5 | |||
| 6fd2fdc2e6 | |||
| 03ea24f298 | |||
| 8c55d7be5e | |||
| 58f20a3b7f | |||
| 085b4ca741 | |||
| f6de017171 | |||
| be9c6bdd67 | |||
| cc63452f65 | |||
| ed9f933d41 | |||
| eeae81e903 | |||
| 796c15d3e6 | |||
| e30139edc3 | |||
| f01b2413c3 | |||
| 240b52151d | |||
| 559dfa297d | |||
| 7e35f76d06 | |||
| 772fcf4088 | |||
| a035d39158 | |||
| 246b7abe7e | |||
| da0e2c5bf3 | |||
| 38ce0fe954 | |||
| b8c00854fe | |||
| d2dc7f4c27 | |||
| 0df9dc8fb9 | |||
| 6593422c05 | |||
| 952f9dbe62 | |||
| ba0a8dc723 | |||
| 100c2dd91c | |||
| 5ab26e3202 | |||
| 6aaa6a50e3 | |||
| 58c9135626 | |||
| 80c79d4021 | |||
| ae090fe10d | |||
| 1f04f9d63b | |||
| 75850a1351 | |||
| 7c5084e385 | |||
| 412a2aa4ab | |||
| 6e121b2e29 | |||
| 149c1c16ba | |||
| afd9de6f1b | |||
| 66e653d24d | |||
| 3fff0e5b3c | |||
| 8f84a73b82 | |||
| 2e86cedef2 | |||
| 864b4e3b26 | |||
| 13a9d4a61f | |||
| d326c77007 | |||
| e6619cf580 | |||
| 122b9f8e17 | |||
| 4b0543c887 | |||
| fa9c9e791b | |||
| ff682a30b3 | |||
| d948b2a235 | |||
| ebd7d08408 | |||
| d279f127c1 | |||
| 602d2c33c0 | |||
| 140051b18c | |||
| b7276359e9 | |||
| 56b02331f7 | |||
| fab2a947ca | |||
| 5e354fa844 | |||
| 77cbddf715 | |||
| 83d6d70a56 | |||
| 1381564a84 | |||
| 10e0540e61 | |||
| b123870871 | |||
| b91313a84e | |||
| eff302a231 | |||
| 8d1232cc7a | |||
| 109b696599 | |||
| e94dfcee0d | |||
| 82adf7955f | |||
| 3df6b6fdcf | |||
| 32da602bf7 | |||
| a9d4e05346 | |||
| 75a65542ba | |||
| 97bdc92d1b | |||
| 313e799df5 | |||
| 3465cef689 | |||
| e5e6367223 | |||
| 86c7d601b0 | |||
| 0545aeb11b | |||
| 5678ba1227 | |||
| b01f067614 | |||
| bd7c78ffd5 | |||
| 65b0ecfec5 | |||
| 6318409a5d | |||
| d1902a1276 | |||
| 56cae1b293 | |||
| 7c740b6a31 | |||
| f6c561a01b | |||
| dddba2637f | |||
| 5501cfd809 | |||
| 7ea0239776 | |||
| 3c51fdffac | |||
| f7f10a7d2c | |||
| d7cb99254e | |||
| 70ff448067 | |||
| 54deb5ed5a | |||
| 72b3dcd8b5 | |||
| 174593643c | |||
| dec722b2ee | |||
| f18eba44f8 | |||
| d430664791 | |||
| 02c3d8d792 | |||
| 660a53e0e0 | |||
| b9b743bbe3 | |||
| d057828ee3 | |||
| 01d3df0d00 | |||
| 70a64ebe72 | |||
| 5f8d688664 | |||
| 9fff7896c5 | |||
| c196df6db0 | |||
| 17d36b7835 | |||
| e64188021a | |||
| 796bf01797 | |||
| 433c3da7cf | |||
| 5a0c7a1330 | |||
| 7ab7322915 | |||
| c9bb18b9f7 | |||
| daa99514fa | |||
| f815bbab24 | |||
| 91bd7df8c1 | |||
| fb8478eb7b | |||
| d2da7dc3e5 | |||
| ce167e233b | |||
| b5529aef9c | |||
| 297e2b6f1a | |||
| 3853a18e0e | |||
| 8616cd875b | |||
| 226b4e3ed5 | |||
| 072a4b5497 | |||
| 86fb9f8409 | |||
| ff48387a8a | |||
| 756c1a22d9 | |||
| a7bf1d53d8 | |||
| 7711cd284b | |||
| 80069f384a | |||
| decbdd1abb | |||
| 8755ffbf31 | |||
| 9683f93a76 | |||
| ee4bea72bf | |||
| 9997e6d337 | |||
| 9f08310307 | |||
| e92645c588 | |||
| e157d70d43 | |||
| 231685133e | |||
| 9b9ebe0999 | |||
| 69344f175b | |||
| 5709ec85d7 | |||
| fab51ac0af | |||
| 5247eacc3c | |||
| 4d7d354498 | |||
| 8779d029b2 | |||
| d14a1de947 | |||
| 349e3b546a | |||
| d5b954c2d4 | |||
| 7335a40a61 | |||
| 5ec908c5f0 | |||
| d1a8171011 | |||
| 8a1d8c8470 | |||
| 6d27d488bf | |||
| 514b3b520c | |||
| e0efda7145 | |||
| 9fbc92aace | |||
| 0c5faa6d24 | |||
| e12a04ac7e | |||
| 4a6b1805e0 | |||
| 903f10c237 | |||
| 0f4d57d59e | |||
| b708969326 | |||
| 8cf45ce0af | |||
| d0ad599a24 | |||
| 52a8d37f11 | |||
| ca19ae8b5a | |||
| 4ab525c880 | |||
| 5c352c9146 | |||
| 3c54c50c5a | |||
| f80e7530f3 | |||
| c6e9280373 | |||
| f9b2444735 | |||
| 259a54a6dd | |||
| a1f86d01e2 | |||
| cdc9bc397d | |||
| ac1099deb8 | |||
| 7e3cc44738 | |||
| 8ed4bae4dd | |||
| dcc2512f58 | |||
| 7d665a4754 | |||
| 3d2c0ed97f | |||
| f7d52c774e | |||
| 8efdfd9dfc | |||
| cd42e38013 | |||
| 1760078f67 | |||
| 79f512337d | |||
| 7e07220440 | |||
| 930808c22b | |||
| 04f16965d5 | |||
| 133bd56436 | |||
| 18904036dc | |||
| 6cef4eba29 | |||
| 632afe6ae3 | |||
| 50b99e5aef | |||
| 339e6aa782 | |||
| 085409340e | |||
| 309eb3c122 | |||
| 2594e5e384 | |||
| 74e88cc0f1 | |||
| 79a77cb91f | |||
| 06703c9d56 | |||
| 362c1a23ea | |||
| 518fd59a10 | |||
| 49b38fe793 | |||
| b21b24fd8a | |||
| 6f8b3fc633 | |||
| b194812f5a | |||
| 211a131351 | |||
| 052c010d3f | |||
| deb2cb752b | |||
| c71e94f054 | |||
| 8a732e306f | |||
| 87eb3f6e68 | |||
| 35760bb6bf | |||
| 592122bf4f | |||
| 1a3273a7e3 | |||
| 34ad2e0fa4 | |||
| 1858b5cfba | |||
| 6274e1fc5f | |||
| 6b8ebf3e94 | |||
| 3a7ea37090 | |||
| 82c54104d6 | |||
| 812edb5fdc | |||
| 8aa0783995 | |||
| baf191fab2 | |||
| 3ee03a860d | |||
| 368213290f | |||
| 192e630cb8 | |||
| a9ce2333c3 | |||
| 64bd77cf4d | |||
| 5a7118a88b | |||
| b471f9ee26 | |||
| 1af4521239 | |||
| 4b5753daea | |||
| a594a0677a | |||
| c44488629a | |||
| bf16f74618 | |||
| 9f0cd9ee10 | |||
| f94b22fa5e | |||
| 0e5c7720a4 | |||
| ee55e4595c | |||
| 13694c8ae8 | |||
| dde7c22fad | |||
| 5e3d986ad8 | |||
| 9f1eb70dbc | |||
| 21160137d4 | |||
| cc8d94c6fc | |||
| 324fa26848 | |||
| 9c432f4f75 | |||
| 29e7eb7719 | |||
| d6534912d8 | |||
| 2113636d29 | |||
| fcdbacdbb0 | |||
| 41ffcc27dd | |||
| 135701feac | |||
| 643bbb2d93 | |||
| 441cd22343 | |||
| 1e82a67cc4 | |||
| ee2d7a1f39 | |||
| 451972f3cf | |||
| 3419c704a9 | |||
| a58bfbf3c7 | |||
| 4aa6d10a60 | |||
| cef2cf2852 | |||
| 5d8a1bf813 | |||
| cdbb661eab | |||
| 361eb633f6 | |||
| fd7a76fe5d | |||
| 092f599aac | |||
| a65dbc5dcd | |||
| 8c69266cbf | |||
| 2fb4178f7c | |||
| 32d56c6b43 | |||
| 20efcff166 | |||
| c41efe4e30 | |||
| 4e87deae28 | |||
| 7a52c3d9f1 | |||
| 1f53b65511 | |||
| 217f628915 | |||
| afdf319f36 | |||
| 18be52c05b | |||
| 305cff36e2 | |||
| 2baf1a3c9f | |||
| aa113c5a85 | |||
| b7f2a4da69 | |||
| d164d51380 | |||
| f9b8ce1d25 | |||
| 4f24dc0959 | |||
| 0b99f6bcd6 | |||
| cf4c79ebdd | |||
| 488babf3b3 | |||
| e4bc592c46 | |||
| ebac739a35 | |||
| 52e67c1a29 | |||
| f8c454733b | |||
| 27fd810b6f | |||
| 736b42b372 | |||
| 3a4d9a77b2 | |||
| 408f93340a | |||
| f592321771 | |||
| 4bb496409c | |||
| c9ea878d10 | |||
| 4701b22e14 | |||
| bb01231990 | |||
| e7d5e57264 | |||
| 16f36a5fda | |||
| e1abc416cf | |||
| 0f6ea38eac | |||
| a2affe70d9 | |||
| dcff28b778 | |||
| c587bae997 | |||
| b229d6b7ac | |||
| 62b8895814 | |||
| 6820292256 | |||
| d3b74cdcb2 | |||
| 2c57717ca2 | |||
| f38339c089 | |||
| 26eebb3ee3 | |||
| 1b7066fc95 | |||
| 69eae13ff3 | |||
| d56d04e41b | |||
| ac6771f975 | |||
| ae08884854 | |||
| ed2a23768e | |||
| 87760d13fb | |||
| 7c7a63bebc | |||
| aa506c6521 | |||
| ad1149ff12 | |||
| 530c8dc0c0 | |||
| 22a30af353 | |||
| 213a6bc5c4 | |||
| 59d6a281cd | |||
| 5810845777 | |||
| 86ebf4a2d8 | |||
| cdd23440c9 | |||
| e9b4813bb2 | |||
| 37c74e38f4 | |||
| 457123027e | |||
| 50bb14a0a8 | |||
| ffc453ebfd | |||
| 4e582b131b | |||
| 9185b62a1d | |||
| 5850a9b8c3 | |||
| 22ad72d08e | |||
| ac8045b9c6 | |||
| 417f1e51a4 | |||
| e28a5803d9 | |||
| e9d30a9383 | |||
| e43a14ccd2 | |||
| de0997ab32 | |||
| b595812bd0 | |||
| 0172bd6beb | |||
| 8e37a693e5 | |||
| 845d3edb67 | |||
| e02d6e2c8f | |||
| 0a5df01626 | |||
| f3f2f8ba97 | |||
| 7458dfc082 | |||
| 7b0abf52b3 | |||
| bed8cb42be | |||
| c849492dfa | |||
| 73663dcdd1 | |||
| 3bde9e9365 | |||
| a9ff335a89 | |||
| 9f7cac8c59 | |||
| 0fdb95e195 | |||
| 094f143735 | |||
| 7d4d286050 | |||
| 4f5d30a865 | |||
| aea328e326 | |||
| 2c0ef660bf | |||
| 21bbed7baf | |||
| 4254e35f6a | |||
| 4800a34be3 | |||
| c10f1851cb | |||
| cda6fed41f | |||
| 5748cea80d | |||
| 43a4124bdd | |||
| 98d7e52b0a | |||
| d696fac8b8 | |||
| c5a80193a8 | |||
| 57b8640a76 | |||
| 12180bd7b1 | |||
| 44e41baffe | |||
| f8484e3266 | |||
| f73c6e6147 | |||
| 79bc85fb09 | |||
| 1e95c964f3 | |||
| 59d6279d4b | |||
| b963d84b41 | |||
| 191336de97 | |||
| 2c9547e314 | |||
| eb30799aed | |||
| f73a97b53b | |||
| 0833352660 | |||
| 387a0f26fb | |||
| c147ab1e85 | |||
| 2311504c44 | |||
| a5b293b412 | |||
| 7d4cbbd7aa | |||
| b7be49426d | |||
| 52effe9e72 | |||
| bdb088dcca | |||
| 457758b537 | |||
| b64b82a1ef | |||
| 0016f6d73d | |||
| 5dc569866e | |||
| 96d7bcc2a9 | |||
| 2d2ecbf3ee | |||
| 96c824f375 | |||
| e03136e951 | |||
| 90fb43cd11 | |||
| 1c6e9fdfae | |||
| 1a795ac2ea | |||
| 1fe1ebf20c | |||
| d56dd0e091 | |||
| baabd95f30 | |||
| 02488215e6 | |||
| 877058aaed | |||
| 42b1c6440c | |||
| 35a89b1541 | |||
| 998a909705 | |||
| 6902fa6b1c | |||
| 370389c7af | |||
| 7401b02022 | |||
| 8ae6402799 | |||
| 720fd144ef | |||
| a07d7a70a0 | |||
| 58b3869730 | |||
| 0832b47d21 | |||
| eb7a7884f6 | |||
| f454929d9c | |||
| dcc569ee5c | |||
| 0cbe2f2eab | |||
| 3df13ff564 | |||
| 08dd1e085b | |||
| b8f65d0252 | |||
| c2944dbc0c | |||
| 6447c7b2f4 | |||
| c059f7ddcd | |||
| cf54e3b97e | |||
| 6d52ea8984 | |||
| b8c60234c3 | |||
| 53566f2ec0 | |||
| 2136c3f3c8 | |||
| ea54c01125 | |||
| 0ea009f611 | |||
| a46166d30f | |||
| 5f7a994ad1 | |||
| 85fd599939 | |||
| 350dccf84a | |||
| f3210b58a1 | |||
| d34a52042e | |||
| 99ae48f0b4 | |||
| 96e5300fdd | |||
| 5d97dd0ea5 | |||
| 4f621de849 | |||
| 3649a1a179 | |||
| 352485fc54 | |||
| c83044d45a | |||
| c1e3ca170e | |||
| 9665e08bac | |||
| 7b270f4c69 | |||
| 65e4df751c | |||
| 0a1da4461b | |||
| aec8fd3243 | |||
| cfccdc9b0c | |||
| 453f384bd7 | |||
| 4a1adab9b4 | |||
| 98a8045aaf | |||
| e6876fecd3 | |||
| f148f23382 | |||
| 4e8aac5308 | |||
| c4c3e4fe83 | |||
| e57359a3a0 | |||
| 8e7aff4486 | |||
| 6ff2f395e6 | |||
| a649aea82a | |||
| 009ab70272 | |||
| b64e106bb1 | |||
| 1d356b6a48 | |||
| 6b371865af | |||
| 4fcfcfd002 | |||
| 87f86b31fa | |||
| 4f8bf98e6f | |||
| 2085251df2 | |||
| c41db69f98 | |||
| 553020c448 | |||
| 1944443d10 | |||
| e647b7c7e8 | |||
| baf266c29e | |||
| 671b59aa9d | |||
| 4ce31c7c1a | |||
| 49bc100e51 | |||
| 437ef99ba5 | |||
| 2738939126 | |||
| f5a14e5594 | |||
| 79e8f0680c | |||
| dc21a0a6b5 | |||
| b51805e245 | |||
| d218f28070 | |||
| e8a7394009 | |||
| d1a15097fe | |||
| 21ee113af3 | |||
| 103687871d | |||
| da383e65e2 | |||
| fdf31ec14f | |||
| d509ecd19a | |||
| 6a3a6416d7 | |||
| 23633c1945 | |||
| edab3916aa | |||
| 9e3a826263 | |||
| 7164f22347 | |||
| a932d8aba1 | |||
| 8714219dab | |||
| 6c4b3c1efe | |||
| 86b6cab7fa | |||
| 5d79b1092f | |||
| e5696bc5e6 | |||
| c339720af9 | |||
| 49fe496914 | |||
| 77578d415f | |||
| 5070f2a334 | |||
| 44f906eb35 | |||
| e22678018b | |||
| 42176f8eb1 | |||
| 9a555063e8 | |||
| 584372bbf2 | |||
| 6b04351ce1 | |||
| 6dbf13d7b5 | |||
| ff4c42d182 | |||
| d588c717da | |||
| 42db9e7153 | |||
| 49e93747b1 | |||
| ff2509af56 | |||
| 8368fb9ea8 | |||
| c3f8fc41b7 | |||
| e178294b49 | |||
| 3d46c1f960 | |||
| 0387f8ad56 | |||
| a5a510da4b | |||
| 5466e321b8 | |||
| f6b82d99ad | |||
| dd1878c64f | |||
| 9a62173a5b | |||
| 6a3f33090d | |||
| 682fdcfc9b | |||
| b9a6edfe3d | |||
| ea48fcfc9f | |||
| 05e404c2ff | |||
| 606a646435 | |||
| 79416cdf10 | |||
| ccd33a721e | |||
| 7e273396c1 | |||
| adac8c04bb | |||
| 8c7b3b91fa | |||
| 6c8681a472 | |||
| 098389d8eb | |||
| 94d14c637f | |||
| 1e47c6cc56 | |||
| cd1ca7b08b | |||
| bbec7f8e89 | |||
| 5524e8d2c0 | |||
| 98f9a013d1 | |||
| 3f86e7b75a | |||
| 7854ef3840 | |||
| 87c2b8197a | |||
| b90800f0c7 | |||
| c60fa84027 | |||
| 50eb661df8 | |||
| a87ccb9ac0 | |||
| 8e1b1a845b | |||
| 5253265342 | |||
| 2054123890 | |||
| a9325102a2 | |||
| 2b303f38a8 | |||
| e6ac64008b | |||
| 7bb8c50080 | |||
| 2609e77af7 | |||
| ce0570b777 | |||
| 8c68f1f626 | |||
| 98a157f589 | |||
| 69b146412a | |||
| 8907e6feac | |||
| f5987c258f | |||
| c85197da55 | |||
| a1cc9380e5 | |||
| e938563de5 | |||
| 4c52dfc956 | |||
| 0ab4bbf771 | |||
| 94431c23f6 | |||
| e64fb44f67 | |||
| 71a333dd78 | |||
| 72194b2115 | |||
| bbf3607fa8 | |||
| 99aaf4030a | |||
| ab40630ff4 | |||
| 8548a8430e | |||
| 9944f46b47 | |||
| 06b97b7b67 | |||
| cf852972d1 | |||
| 1f47c22371 | |||
| 602b034a03 | |||
| 8764b17ffc | |||
| ddc1b965b6 | |||
| be6b847675 | |||
| 0d72420480 | |||
| 52535b356c | |||
| 9206ec30a2 | |||
| a7e9760316 | |||
| 7e1068919b | |||
| 30d46313ec | |||
| f282fd0ebf | |||
| 97aa8d3341 | |||
| bdebf4cea7 | |||
| f3311f9e2a | |||
| 7d7d323f53 | |||
| 5cbdce97aa | |||
| c1252a1089 | |||
| cf0a29ce4d | |||
| 10639c9526 | |||
| be1728fba1 | |||
| a86dc747b3 | |||
| c481e06e87 | |||
| 4ea2eceb70 | |||
| d08589d435 | |||
| 3bfe4f711d | |||
| 6e565ab4a4 | |||
| f1fb474459 | |||
| 482feb7266 | |||
| 53c9460454 | |||
| 0a07d780e0 | |||
| fa23a01775 | |||
| 58ad952b1a | |||
| dcb0c68ed3 | |||
| 5245c7454c | |||
| c9e07bbc95 | |||
| 8914fa51ff | |||
| 6ebc95470b | |||
| 2660eee961 | |||
| a0691289f9 | |||
| 124ac15f1e | |||
| ce0e595a4f | |||
| f1e1785386 | |||
| b416e8715d | |||
| 3f1fb281be | |||
| 9c81338cb9 | |||
| f93be25cc8 | |||
| df697f6520 | |||
| 4949f70860 | |||
| 710617034b | |||
| 63ff39f9f3 | |||
| b3a743f09a | |||
| 62f8240b00 | |||
| 03ae1e5aae | |||
| 2dc3b0f7f9 | |||
| 381216aa54 | |||
| 19c6bbe7d9 | |||
| c4b2058d23 | |||
| 71c391cd8d | |||
| 036b13ee05 | |||
| cc1090cf3b | |||
| bd4580a242 | |||
| 03fc3d1ceb | |||
| adbe84425f | |||
| b49fa7d384 | |||
| 479cac2a14 | |||
| 2fabe56bbe | |||
| 1a15596f21 | |||
| 8722faa167 | |||
| 7a3ca99894 | |||
| 045f8294bb | |||
| e9a6c5db21 | |||
| b5bd2fd880 | |||
| 1ded2de2dd | |||
| 2ca39c910d | |||
| cf5a7b9679 | |||
| 95ecdc3af9 | |||
| 579ce93885 | |||
| 21a9a17478 | |||
| e501c61c04 | |||
| 9a6a046caf | |||
| aacb9b7cf5 | |||
| c29c52a216 | |||
| f647054c8c | |||
| 52d3afd798 | |||
| 696a6561d3 | |||
| ea38f7fa66 | |||
| f5b21e8141 | |||
| e97d18ba81 | |||
| 5422cbcecb | |||
| 3f8cefea0e | |||
| 5e92a777ef | |||
| 07c9a88d9c | |||
| dae188d14f | |||
| 17b1152fa3 | |||
| 381917b762 | |||
| 5cc4aa0e93 | |||
| dc27a13426 | |||
| 225c3e78cb | |||
| f3439de480 | |||
| 219d315c8d | |||
| 28dd3aae79 | |||
| fe2a7d23a5 | |||
| 49f2bd6f17 | |||
| bcfcc779f6 | |||
| 3a84444488 | |||
| b6023eab9c | |||
| 5978ef1df5 | |||
| 0a5b200da2 | |||
| 052fe626b3 | |||
| 9e9327e2f8 | |||
| 9fb0f5ac51 | |||
| cc97c57fd4 | |||
| 911be68a41 | |||
| 9a0e038a48 | |||
| 91fbe00caa | |||
| 9a1a9d9aff | |||
| 10cc7c78dd | |||
| 72d90ba8d2 | |||
| d277a1ba75 | |||
| 396f7e1a17 | |||
| 698c367d8d | |||
| 12a3eb776d | |||
| 46ed461e22 | |||
| 595ec6b852 | |||
| f676bfb3d7 | |||
| 0376a8643e | |||
| a524a677e4 | |||
| c120001178 | |||
| 14e15fb4f7 | |||
| d84d3a519b | |||
| f48befc6f0 | |||
| df57d038b8 | |||
| 713aa5c5b9 | |||
| 61f111143a | |||
| 6628714fc6 | |||
| 997dded1ac | |||
| 187befd665 | |||
| 16b56e71d9 | |||
| c58373dbea | |||
| 1c9668b371 | |||
| bd6ad79759 | |||
| ce5e2697cb | |||
| bcc9dac087 | |||
| fd60e98c5b | |||
| 02124f19e6 | |||
| dccdadc38a | |||
| d5092a6f7c | |||
| 54f52c3f45 | |||
| 734212a402 | |||
| 8257dc3c1e | |||
| 0af7597d36 | |||
| f126f371b2 | |||
| 1264be8785 | |||
| 01717c83d7 | |||
| 07ab0c1c53 | |||
| efc7dbaae2 | |||
| ff91af825d | |||
| 8a5182662e | |||
| 1292fdf71a | |||
| 5f1282afdb | |||
| 8a178da1a4 | |||
| 764d55b81d | |||
| f960a5707d | |||
| 554ddd2ec4 | |||
| 9f77ffb03f | |||
| 14ef62ed66 | |||
| 6f91b7f6a4 | |||
| 1421e306fb | |||
| ecee388236 | |||
| 4cc7b0a74f | |||
| b2a5e66fc5 | |||
| 3425c90b66 | |||
| b0c5f49170 | |||
| 9cadc1e530 | |||
| f566f6baa9 | |||
| 2ecca8f59c | |||
| 60cedd7a68 | |||
| bc23f29b27 | |||
| c0d76ef984 | |||
| 72063bf136 | |||
| 7b0d1c932e | |||
| 81f786393a | |||
| 1fa37fe733 | |||
| f73b48b8b6 | |||
| 4401095b38 | |||
| 390f17d1e0 | |||
| 36c1dce264 | |||
| 9eba746eb8 | |||
| 7fca146b21 | |||
| 33a3fba2d1 | |||
| 8c94568cc3 | |||
| 33176db5dc | |||
| 6bce6ee34a | |||
| 1d3c860411 | |||
| 3b23e57925 | |||
| 0fd8f50522 | |||
| d92f67ee2c | |||
| ef29b15c9a | |||
| 44d89638fd | |||
| 7b060d9122 | |||
| f2cd65cf1e | |||
| 25e99c453f | |||
| 70933ea999 | |||
| 612b8ce2cb | |||
| b2f851af06 | |||
| d87457a025 | |||
| fc0869735d | |||
| 31827d8dfe | |||
| bc394e7516 | |||
| 3a426660ea | |||
| a340ea872e | |||
| e20613a776 | |||
| 584eed633e | |||
| 05e21015e9 | |||
| 51684c109e | |||
| 51e7fb76b6 | |||
| c4c86a8990 | |||
| 93f8800844 | |||
| e1773749ae | |||
| 1c9e886a6a | |||
| 97fad1cb53 | |||
| b99396ab12 | |||
| 940f1e7914 | |||
| fe371bf624 | |||
| 9cacd3261d | |||
| edee922b59 | |||
| 5f2135695e | |||
| bfb45b27e6 | |||
| 1ca35b7424 | |||
| 56f3c92737 | |||
| 63fc6ef316 | |||
| 8870ef4159 | |||
| 116fb275a8 | |||
| 19e77e4787 | |||
| b758dbd384 | |||
| 3a78a22733 | |||
| 5578088983 | |||
| 972ff1d0c4 | |||
| 0a5c9cf145 | |||
| 6ab928fb39 | |||
| a2a8ba17fc | |||
| 8d48632ebe | |||
| d8272b9395 | |||
| c175a86cbb | |||
| 4762728fd5 | |||
| 964d5a20e9 | |||
| 177478a8ad | |||
| 75c99d65a5 | |||
| 75277bb770 | |||
| a1c5740044 | |||
| 042ff210d5 | |||
| a11c02497f | |||
| c7b2e48efe | |||
| 28833421ae | |||
| e607a4ec02 | |||
| 379de5708f | |||
| fd1cae0dcc | |||
| 091c7a3821 | |||
| c778011f14 | |||
| 473964806c | |||
| 61ca38103c | |||
| ecf359b8c9 | |||
| ac47c0c624 | |||
| 68962adc54 | |||
| 60f2f7898a | |||
| 6cb93445e1 | |||
| 2f6db4dfac | |||
| 33a6e5ac04 | |||
| 4e9cb475da | |||
| 38d37d2b00 | |||
| d004ee58c5 | |||
| 1c8493fb0d | |||
| c937e15763 | |||
| f792fdc3e0 | |||
| 2bddbd2cb5 | |||
| ba8a971742 | |||
| 2b30759af0 | |||
| 622cf566b9 | |||
| 9c872f5316 | |||
| e02418e904 | |||
| 840088e021 | |||
| 083d8645a5 | |||
| f50a061225 | |||
| 220d937d9a | |||
| e23ba9215d | |||
| 2fd01ee24e | |||
| ad71efb2cb | |||
| 34f0da6010 | |||
| f8d09945ac | |||
| b4e7ee46c6 | |||
| cd0e95de16 | |||
| a4e598f474 | |||
| 7454189c2a | |||
| 3d0410c147 | |||
| 00e7816c1b | |||
| d04fc15e06 | |||
| 02b2fdeda9 | |||
| 9699fde8d2 | |||
| 46631c4b18 | |||
| 042895977e | |||
| f57136fd79 | |||
| f6b3bc01e5 | |||
| e3b32cce80 | |||
| 9436103ed6 | |||
| 1af7d397d4 | |||
| 8acd4c3ff4 | |||
| 0f263e125b | |||
| 82bd82e2f8 | |||
| c0a8d4e1ef | |||
| 2d5e3b57ea | |||
| 2d16026df6 | |||
| b7a3204c57 | |||
| a963ade012 | |||
| 450ba8b43f | |||
| 11591b3e9d | |||
| 3ffae9f7b7 | |||
| b4050c775e | |||
| ec9a17e71a | |||
| ad6a80f68c | |||
| bebf6c47c6 | |||
| d01bedbc61 | |||
| 61991a3330 | |||
| 27b224ac74 | |||
| 61886a61de | |||
| 9c2ef369ed | |||
| a5969aec96 | |||
| 0ff67253f7 | |||
| f85838087a | |||
| b01cdf28ca | |||
| ba84eb58f2 | |||
| 18025c2908 | |||
| 63fc313d02 | |||
| fe3f236aa5 | |||
| f36546dbd2 | |||
| 7c901e39e1 | |||
| 18d1be4530 | |||
| 26afa49d71 | |||
| 9b8c3fd675 | |||
| d00f36ec75 | |||
| 7ec6d8a336 | |||
| c105b72945 | |||
| 128e509527 | |||
| 1bdd86edeb | |||
| cddee22cf2 | |||
| 214f633dd4 | |||
| 5d15676b7b | |||
| 1ed22204c8 | |||
| 8d4d36f805 | |||
| 034ff3ce13 | |||
| 1386489f41 | |||
| e4d0652899 | |||
| c4246bc59c | |||
| e7e0da0153 | |||
| b33f3bb2cc | |||
| 8237418be6 | |||
| f054d6316a | |||
| 2f8e1798ca | |||
| 1be1a28920 | |||
| 53862687d5 | |||
| 9210d8e542 | |||
| 1d82aecf45 | |||
| b5ab82fdbd | |||
| 68e08bbecd | |||
| 05d40946f3 | |||
| 7ed38b97c3 | |||
| b75b0c822d | |||
| 864ec5ef45 | |||
| fd6ef87c32 | |||
| 95ec92994d | |||
| d71e001736 | |||
| 08da247a87 | |||
| 06c2a70c49 | |||
| 637b615e08 | |||
| d9f159a554 | |||
| c0005fd293 | |||
| f12bd999bf | |||
| a1df295079 | |||
| 63bc4d4b7f | |||
| cc024d3ef2 | |||
| 7b20ce4952 | |||
| 20d957d212 | |||
| 432546e4c4 | |||
| 03df7831ab | |||
| 700a388173 | |||
| 2425dac9a1 | |||
| 5fea331d42 | |||
| 9071598a65 | |||
| 1ab551487d | |||
| 060d67517a | |||
| 199f1aec2e | |||
| 35d730bf2b | |||
| 16ce114e0c | |||
| ec33c4ae36 | |||
| 25f33a7e30 | |||
| 48c9c24da6 | |||
| fffe2464cd | |||
| 9811a739b0 | |||
| 9c6da03504 | |||
| 13c0855114 | |||
| ed0ce48179 | |||
| a2a131799f | |||
| 37e018454d | |||
| 4443d6b0a1 | |||
| 99e782e62c | |||
| 33dfeb85be | |||
| 61a7f48bf4 | |||
| 4f906372e2 | |||
| 80a0364465 | |||
| 4f5916f12d | |||
| 1fb966dc61 | |||
| 2e7b9a2c0f | |||
| 969a218057 | |||
| c0019a42e4 | |||
| cb48d7798d | |||
| 0ba3b06efd | |||
| c485aee464 | |||
| b15cf355af | |||
| 96adeb71ca | |||
| 79f770455b | |||
| 183454a723 | |||
| ba612fc9bd | |||
| 13c04120dd | |||
| 1ad1b737c2 | |||
| 620a969285 | |||
| 854a722c70 | |||
| f87f0cc481 | |||
| 91e21847e2 | |||
| efa84d8225 | |||
| fd2d800c06 | |||
| 0b429fee7b | |||
| 241991c677 | |||
| 009aec5164 | |||
| 3c74c23bad | |||
| d54b069ae1 | |||
| 4ef03ccbe1 | |||
| bcc630a8dc | |||
| 73d1ea9a52 | |||
| edb608d206 | |||
| db9a0cfbc0 | |||
| 4d12beb723 | |||
| ff7ea605ef | |||
| bb873b1de5 | |||
| 5a43c7a28e | |||
| 6cc5959356 | |||
| ce81433aff | |||
| c48f30d4ec | |||
| fed1b3fd59 | |||
| 25378587e2 | |||
| 10dc5a3759 | |||
| 9582c33eab | |||
| 0f7721e915 | |||
| f269828160 | |||
| b35f5d115f | |||
| c762da9893 | |||
| 63c49be487 | |||
| 006384edaf | |||
| 0a4c616d43 | |||
| ef347f4b62 | |||
| e0ab007b2b | |||
| ef534537b4 | |||
| 4f82b3588a | |||
| bada364eb3 | |||
| 3481c1caec | |||
| 51963f95dd | |||
| 35f96d6da7 | |||
| c28fea32c7 | |||
| 893deb4040 | |||
| 1252e870f9 | |||
| ecfd056111 | |||
| 05bc48e8f4 | |||
| fac99de7ec | |||
| 2bda7aaf61 | |||
| 2df606f098 | |||
| 1c9f956b88 | |||
| 2d8c89c40b | |||
| f54b80d2c8 | |||
| 3212dd5465 | |||
| 84379140ba | |||
| b3bba3476d | |||
| 270af2ca79 | |||
| bcca34bc96 | |||
| 7efc917ee0 | |||
| 146d66267f | |||
| ec57a938c0 | |||
| a1e04c98aa | |||
| 6d282ddf72 | |||
| cb049657e5 | |||
| be5c910358 | |||
| f61db41d25 | |||
| 46858c4328 | |||
| 726ed2632d | |||
| bf5ff7fcd0 | |||
| d3beb755df | |||
| c669b7e4cd | |||
| 4ccbd44559 | |||
| 41afe54696 | |||
| 812ce48c36 | |||
| 875f922332 | |||
| 36a04ef8de | |||
| c5536534d8 | |||
| 8375182e34 | |||
| 220f671655 | |||
| 03e213ccae | |||
| 1523fdcc1c | |||
| f9a83c28e5 | |||
| 6dcafe0c2d | |||
| 397bf7f2b7 | |||
| 9d89f8d3dc | |||
| ceb6e8bd94 | |||
| 472c210687 | |||
| 8e9ea0e3d1 | |||
| c5a698fb54 | |||
| dcae7698ad | |||
| 1f43999f2a | |||
| aadab03b7b | |||
| 02f4f2f96d | |||
| d368a7ceb4 | |||
| c5b6c0456d | |||
| 1b73530b75 | |||
| 2f4c11b5e5 | |||
| 7106d3e8c2 | |||
| 6b0952b9bd | |||
| 2dd438c230 | |||
| 88f67ce6b1 | |||
| 44f629f99c | |||
| 3fa02787ac | |||
| b14f7c99d2 | |||
| 8c919ed248 | |||
| 553bb7956e | |||
| 180e54d09d | |||
| 50c9367d7a | |||
| 123ca7e1c5 | |||
| c52a3f7634 | |||
| e88bf2bc30 | |||
| 4ff8a3ad92 | |||
| 6e7050555e | |||
| 6d78cfc0d9 | |||
| 7512b5fdde | |||
| eeb997261d | |||
| f14b8b4341 | |||
| 3dd1afe4ec | |||
| 73ba435610 | |||
| 15952d7188 | |||
| 38e3f2c7f5 | |||
| aad98e545f | |||
| a7757b0eb6 | |||
| ba9bc2d72f | |||
| b009e8d0fb | |||
| 7ed5284ae6 | |||
| f151b1d277 | |||
| f4ba8b13c7 | |||
| 1744098438 | |||
| 555fdf893a | |||
| 68e59d6154 | |||
| 32348604e3 | |||
| 799646e5d0 | |||
| 047b1ca457 | |||
| d48e0a04ae | |||
| 986878a881 | |||
| 8ebd474c0e | |||
| 9086d6a230 | |||
| 303868b3c4 | |||
| d9164bdd4c | |||
| a9a45e1546 | |||
| 28944336d4 | |||
| 42b1bd56cc | |||
| eedde323ce | |||
| da6a38f9f6 | |||
| 92e08c9863 | |||
| 4b97e8c51c | |||
| d4db7807df | |||
| 773e621190 | |||
| d2f19a3a0d | |||
| a16a11f32b | |||
| a3f05474c9 | |||
| 2d8673197c | |||
| d8ca61b01b | |||
| 1189606cd8 | |||
| ec335b7398 | |||
| a8b4c99ed6 | |||
| 7d8e5f623a | |||
| 2b8229f716 | |||
| 4763d8033a | |||
| 6aa7a86ae9 | |||
| 23a81c0fb8 | |||
| 184b6e314c | |||
| 77be6d64c1 | |||
| b3a60b9c22 | |||
| 28103ad386 | |||
| bea86deea9 | |||
| b80a3a91a8 | |||
| 8340e31f1f | |||
| 13d67b6ae7 | |||
| 701d2386ce | |||
| 7127634aa0 | |||
| 6550cb2a90 | |||
| e05a0bc6c5 | |||
| a181835549 | |||
| 34f23b5917 | |||
| 60cacbfd66 | |||
| ed55d13112 | |||
| 2e05f1e3f8 | |||
| 2981ee00d9 | |||
| 3da1144cef | |||
| b476bf2a00 | |||
| 23b28a6700 | |||
| eceada586b | |||
| 67635c6d65 | |||
| a26e496d00 | |||
| d579d3e596 | |||
| 5a77176654 | |||
| 323c922322 | |||
| a28cde9c3b | |||
| 529af7a90e | |||
| 8bf58937a9 | |||
| 7dce2d0b8f | |||
| 2e393ab833 | |||
| 0c3722be82 | |||
| 09fb7512ed | |||
| b59aaae2dc | |||
| d77088b19b | |||
| b5a6df4966 | |||
| 67e50b4415 | |||
| 0cf170587f | |||
| 0c2ccd3bae | |||
| 1692801fc5 | |||
| 84f33d0578 | |||
| 5c07e0b6d3 | |||
| e0827069c1 | |||
| 9b55c09999 | |||
| 6bb6039ebb | |||
| ba7c92b0e8 | |||
| 4f8a1213bd | |||
| edf54ac3a9 | |||
| f44c29ad7d | |||
| 0c57dc2e00 | |||
| 07bd58a0e8 | |||
| 7bff337828 | |||
| 24580e348a | |||
| cfdcf9f2d2 | |||
| 63ac69cadf | |||
| 263621aed8 | |||
| 40efd17be4 | |||
| 0f2b7fbc45 | |||
| 1ce31dcd62 | |||
| f55c1cc0fb | |||
| 81c0537b0c | |||
| 32f978ff4b | |||
| 8f3b876ee6 | |||
| 6b0cd392f0 | |||
| ea50be0529 | |||
| b11b08b478 | |||
| a5e89bf724 | |||
| 0d196529f7 | |||
| 77b57459c4 | |||
| 5dde172452 | |||
| d83372a8dc | |||
| 5a797ae7de | |||
| ff8e32453b | |||
| fb2012def2 | |||
| d7ba03a9cb | |||
| 1e744bf5b1 | |||
| 8364ea3954 | |||
| c24e6f7ae9 | |||
| ed2fb773cd | |||
| afb164cc15 | |||
| 474897ff01 | |||
| 29fb2b6e47 | |||
| af72e6b8f4 | |||
| 38bb0db9db | |||
| 2ad8c6dbd0 | |||
| 5c96021172 | |||
| 4b1bb702ce | |||
| a77a2f357c | |||
| 7e78b5d06e | |||
| 11c81067dc | |||
| 7018f94959 | |||
| 533fde66e3 | |||
| 5bd18155be | |||
| aa6b5ac124 | |||
| ca40a749b6 | |||
| d54d580f79 | |||
| 774d6c1d0a | |||
| 302d80d744 | |||
| 286c6b496d | |||
| 44da1f795f | |||
| 71c4e96e17 | |||
| 60fd5c2a3a | |||
| 8271c4e9c4 | |||
| 1f4fe3bb27 | |||
| a0431acb37 | |||
| e3f1d722e7 | |||
| 1c3c94fd2c | |||
| 45a1063c4a | |||
| 1cc80f10ba | |||
| a160158cb3 | |||
| 6a53cb9307 | |||
| 1920232268 | |||
| 7f4eb4f6c6 | |||
| de6edcc48a | |||
| e88a36621e | |||
| e9f7c4aeba | |||
| 467f5fc90f | |||
| ad018da224 | |||
| 90a1c6b1f0 | |||
| 93d1ceae43 | |||
| 073a7ff95a | |||
| 5bf1a4c08c | |||
| 562ff9d111 | |||
| 32f6e1a554 | |||
| 10bbcca11e | |||
| 19b3aab23f | |||
| df28bb5ccd | |||
| d4ec359f11 | |||
| 3603102c89 | |||
| a615102947 | |||
| 9c91d0103f | |||
| 37a1767286 | |||
| 03662c0589 | |||
| 7c354c14f7 | |||
| d2ba09e6ff | |||
| 934394c5e2 | |||
| 6c3cadbd73 | |||
| 4dda2002f6 | |||
| 539f8032dc | |||
| f8c5128729 | |||
| 150487feda | |||
| b767613d20 | |||
| 197b2e75e1 | |||
| 3516e14e05 | |||
| d82b918a7b | |||
| f60726b090 | |||
| 1675b23a64 | |||
| aa9da6e433 | |||
| 772f6208db | |||
| 0cf1de8eea | |||
| 5947519ff4 | |||
| 084835ec30 | |||
| a67484668e | |||
| 26fd37b27d | |||
| ccaedaedc8 | |||
| c5de129c36 | |||
| 533dd85299 | |||
| 48dc18ed59 | |||
| bac492fff6 | |||
| 1d2d579bd6 | |||
| 80687c8a56 | |||
| 8a1d3929cc | |||
| 281ce7a054 | |||
| 343f4b3026 | |||
| 882426a9b2 | |||
| cf15b9e8ad | |||
| f4f7522fe7 | |||
| 1b4e3ec35a | |||
| b9d5f3f6e9 | |||
| 587402859e | |||
| 0421da78b3 | |||
| b027a84fa1 | |||
| fbbf4e380f | |||
| faed8f43d6 | |||
| 9a15c7a899 | |||
| 35768ed638 | |||
| 161f50962d | |||
| e638b9e805 | |||
| d7737528d1 | |||
| 18c0511d3c | |||
| 06a1c90679 | |||
| e929dd4d98 | |||
| bdb82d181f | |||
| 10a2c51c52 | |||
| 4664a339ae | |||
| fb81e4df1c | |||
| 89833853fa | |||
| cb1e9adc63 | |||
| 562796e41b | |||
| bb93c53948 | |||
| 00575b346d | |||
| 25d125fba1 | |||
| 7316676c41 | |||
| d1229efeec | |||
| fd7a2defae | |||
| fcc481e751 | |||
| 1984aacb27 | |||
| eaaa2d27d5 | |||
| 77585bf8af | |||
| c821cb1489 | |||
| 86c1babd03 | |||
| 2205b2f5bc | |||
| 975e40f1c0 | |||
| 74d8527f8a | |||
| 57cf3d1766 | |||
| f81b3101e8 | |||
| 81aefed13a | |||
| 41040e589f | |||
| 6eb26c1519 | |||
| ad7a871708 | |||
| 634ffed488 | |||
| ebe36d6e7c | |||
| d68e62c968 | |||
| b027eac173 | |||
| 2ed24876af | |||
| b08a6ccd9d | |||
| d558260a8e | |||
| 023a42ba55 | |||
| 7409f21e9f | |||
| 62f27b28ed | |||
| 599f5ef51b | |||
| 86e12b6074 | |||
| 5dff283b39 | |||
| 341c3d5933 | |||
| 628b23acc8 | |||
| 988555a5d9 | |||
| e11333dd83 | |||
| af2434c547 | |||
| a4c883c098 | |||
| 0a531815c5 | |||
| a15db2d9cf | |||
| efc1c39315 | |||
| 3334b1437b | |||
| 34103ef1cb | |||
| e7f348e720 | |||
| da9be8231f | |||
| ed2cdb71e5 | |||
| bbe48eaac6 | |||
| bab826a381 | |||
| 77294855d7 | |||
| d8187f7518 | |||
| 9e83463128 | |||
| e98c9a7ce3 | |||
| 204651e0e2 | |||
| 042892f0d7 | |||
| 7cefaa49dd | |||
| fc41e8850b | |||
| 38b3698b97 | |||
| c2746b5d2a | |||
| daff2a0674 | |||
| ad5c2de97c | |||
| f8758da289 | |||
| ca9c52ac97 | |||
| 9c285da329 | |||
| de37cfc224 | |||
| 946c09f58c | |||
| 4e168ffdf3 | |||
| d7bbafd683 | |||
| e90c233551 | |||
| 06897dbdb5 | |||
| 39020fc9cf | |||
| d5489f3a68 | |||
| 5a5a487612 | |||
| 46775ad186 | |||
| 901d9b70b0 | |||
| 0b4e043442 | |||
| d0c3c4c373 | |||
| 6c5dc17a1e | |||
| cf3757448d | |||
| 8578f9c565 | |||
| c9c09262f7 | |||
| faac7f18c7 | |||
| b2790973a3 | |||
| 8d58b238ca | |||
| 51bd56f19d | |||
| b111fb94b7 | |||
| 544dd8b130 | |||
| 246a793d82 | |||
| e650d87e47 | |||
| feb74b125d | |||
| 3c0b0b0f94 | |||
| d31a0eab9e | |||
| ccbc764c02 | |||
| 60a5ada454 | |||
| d3c2b15f82 | |||
| b030d7e6a1 | |||
| 64d8cf1e2e | |||
| d262b04d99 | |||
| cce2d9927e | |||
| 79878a57a9 | |||
| 03fe86f0a3 | |||
| 13a0c14e6c | |||
| 6e022dcb06 | |||
| c38023f4e7 | |||
| cbb5fc0acc | |||
| 2df3abe16b | |||
| ecec53f509 | |||
| 023102c804 | |||
| 52c05e75cc | |||
| 3d48994a72 | |||
| 7b160fa3cb | |||
| 71d3654832 | |||
| 2c29ee9e00 | |||
| aafda43df1 | |||
| 39127d942e | |||
| b068e63618 | |||
| 4b8fb6c246 | |||
| 939c60bcaa | |||
| 7936faf9a3 | |||
| 5c85f816c9 | |||
| 56683e6d11 | |||
| fbac578c79 | |||
| ade46bd428 | |||
| 6882970248 | |||
| 11a09ef5cc | |||
| 1a1cd9b4e9 | |||
| cd3aa0184a | |||
| 1020a93fa3 | |||
| 8a3b93773d | |||
| bcd63766ce | |||
| ca40d635e4 | |||
| 942401de16 | |||
| f9ff9c5618 | |||
| 6fb83f869c | |||
| 0c30b18769 | |||
| b4845d8c9f | |||
| ea51396731 | |||
| aa82f921cc | |||
| 2da7eae2c4 | |||
| 25159d8e81 | |||
| f40ffe4763 | |||
| 116311b7b4 | |||
| f1ef3a4865 | |||
| 9997aa8187 | |||
| f15b42018c | |||
| f9e9ae85bd | |||
| a49beb7c73 | |||
| 51dff5b9e8 | |||
| 826fc00374 | |||
| c10692deff | |||
| daa7b9ce5f | |||
| 1ab02631b0 | |||
| 3e755b2290 | |||
| f15a167df4 | |||
| f6367a2ea5 | |||
| 5f88e2b496 | |||
| 2c7cf52e3b | |||
| b7c5083a87 | |||
| d5d88efd5d | |||
| 6cb7a7be18 | |||
| cdea6b532f | |||
| d01e3529a6 | |||
| 7c13d3277c | |||
| 345b3b0bdd | |||
| a65d7d4dd3 | |||
| 5e986f3347 | |||
| 27a8bb471b | |||
| 7868733002 | |||
| 469aef2e5e | |||
| 5e00fc6afe | |||
| 5170f0b5da | |||
| dc2dbb4173 | |||
| 79e4f7eb78 | |||
| cc73c7000f | |||
| 8bb26fa5de | |||
| 48612d7c58 | |||
| 8ba84f4b47 | |||
| bc653add74 | |||
| 215f78eee2 | |||
| 4425dac7f4 | |||
| 4f79b9de48 | |||
| 397ac5e68f | |||
| 43c75c64b5 | |||
| c319625a07 | |||
| a7d0448faa | |||
| ca10e5e8ae | |||
| 32414afe72 | |||
| ed10f50d25 | |||
| 48d9be70d5 | |||
| c6b31481b6 | |||
| 514b714cc2 | |||
| 7fec87d3f6 | |||
| 00d555f051 | |||
| 6cf7d6ef4e | |||
| 3ebdcafdd3 | |||
| a348f3eeaa | |||
| 33f423de04 | |||
| d6ba52c3f9 | |||
| e9638d0997 | |||
| 5cb0084547 |
@@ -0,0 +1,30 @@
|
||||
<!--
|
||||
If you have a question rather than reporting a bug please go to http://answers.opencv.org where you get much faster responses.
|
||||
If you need further assistance please read [How To Contribute](https://github.com/opencv/opencv/wiki/How_to_contribute).
|
||||
|
||||
This is a template helping you to create an issue which can be processed as quickly as possible. This is the bug reporting section for the OpenCV library.
|
||||
-->
|
||||
|
||||
##### System information (version)
|
||||
<!-- Example
|
||||
- OpenCV => 3.1
|
||||
- Operating System / Platform => Windows 64 Bit
|
||||
- Compiler => Visual Studio 2015
|
||||
-->
|
||||
|
||||
- OpenCV => :grey_question:
|
||||
- Operating System / Platform => :grey_question:
|
||||
- Compiler => :grey_question:
|
||||
|
||||
##### Detailed description
|
||||
|
||||
<!-- your description -->
|
||||
|
||||
##### Steps to reproduce
|
||||
|
||||
<!-- to add code example fence it with triple backticks and optional file extension
|
||||
```.cpp
|
||||
// C++ code example
|
||||
```
|
||||
or attach as .txt or .zip file
|
||||
-->
|
||||
@@ -0,0 +1,9 @@
|
||||
<!-- Please use this line to close one or multiple issues when this pullrequest gets merged
|
||||
You can add another line right under the first one:
|
||||
resolves #1234
|
||||
resolves #1235
|
||||
-->
|
||||
|
||||
### This pullrequest changes
|
||||
|
||||
<!-- Please describe what your pullrequest is changing -->
|
||||
+15
@@ -8,3 +8,18 @@
|
||||
Thumbs.db
|
||||
tags
|
||||
tegra/
|
||||
bin/
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.obj
|
||||
*.stamp
|
||||
*.depend
|
||||
*.rule
|
||||
*.tmp
|
||||
*/debug
|
||||
*/CMakeFiles
|
||||
CMakeCache.txt
|
||||
*.suo
|
||||
*.log
|
||||
*.tlog
|
||||
build
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
# Gedit temp files
|
||||
*~
|
||||
|
||||
# Qt Creator file
|
||||
*.user
|
||||
|
||||
# MacOS-specific (Desktop Services Store)
|
||||
.DS_Store
|
||||
Vendored
+42
@@ -0,0 +1,42 @@
|
||||
cmake_minimum_required(VERSION 2.8.11 FATAL_ERROR)
|
||||
|
||||
project(Carotene)
|
||||
|
||||
set(CAROTENE_NS "carotene" CACHE STRING "Namespace for Carotene definitions")
|
||||
|
||||
set(CAROTENE_INCLUDE_DIR include)
|
||||
set(CAROTENE_SOURCE_DIR src)
|
||||
|
||||
file(GLOB_RECURSE carotene_headers RELATIVE "${CMAKE_CURRENT_LIST_DIR}" "${CAROTENE_INCLUDE_DIR}/*.hpp")
|
||||
file(GLOB_RECURSE carotene_sources RELATIVE "${CMAKE_CURRENT_LIST_DIR}" "${CAROTENE_SOURCE_DIR}/*.cpp"
|
||||
"${CAROTENE_SOURCE_DIR}/*.hpp")
|
||||
|
||||
include_directories(${CAROTENE_INCLUDE_DIR})
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
set(CMAKE_CXX_FLAGS "-fvisibility=hidden ${CMAKE_CXX_FLAGS}")
|
||||
|
||||
# allow more inlines - these parameters improve performance for:
|
||||
# - matchTemplate about 5-10%
|
||||
# - goodFeaturesToTrack 10-20%
|
||||
# - cornerHarris 30% for some cases
|
||||
|
||||
set_source_files_properties(${carotene_sources} COMPILE_FLAGS "--param ipcp-unit-growth=100000 --param inline-unit-growth=100000 --param large-stack-frame-growth=5000")
|
||||
endif()
|
||||
|
||||
add_library(carotene_objs OBJECT
|
||||
${carotene_headers}
|
||||
${carotene_sources}
|
||||
)
|
||||
|
||||
if(NOT CAROTENE_NS STREQUAL "carotene")
|
||||
target_compile_definitions(carotene_objs PUBLIC "-DCAROTENE_NS=${CAROTENE_NS}")
|
||||
endif()
|
||||
|
||||
if(WITH_NEON)
|
||||
target_compile_definitions(carotene_objs PRIVATE "-DWITH_NEON")
|
||||
endif()
|
||||
|
||||
set_target_properties(carotene_objs PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
|
||||
|
||||
add_library(carotene STATIC EXCLUDE_FROM_ALL "$<TARGET_OBJECTS:carotene_objs>")
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
This is Carotene, a low-level library containing optimized CPU routines
|
||||
that are useful for computer vision algorithms.
|
||||
Vendored
+114
@@ -0,0 +1,114 @@
|
||||
cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
set(TEGRA_HAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
set(CAROTENE_DIR "${TEGRA_HAL_DIR}/../")
|
||||
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm.*|ARM.*)")
|
||||
set(ARM TRUE)
|
||||
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64.*|AARCH64.*")
|
||||
set(AARCH64 TRUE)
|
||||
endif()
|
||||
|
||||
set(TEGRA_COMPILER_FLAGS "")
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
# Generate unwind information even for functions that can't throw/propagate exceptions.
|
||||
# This lets debuggers and such get non-broken backtraces for such functions, even without debugging symbols.
|
||||
list(APPEND TEGRA_COMPILER_FLAGS -funwind-tables)
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
if(X86 OR ARMEABI_V6 OR (MIPS AND ANDROID_COMPILER_VERSION VERSION_LESS "4.6"))
|
||||
list(APPEND TEGRA_COMPILER_FLAGS -fweb -fwrapv -frename-registers -fsched-stalled-insns-dep=100 -fsched-stalled-insns=2)
|
||||
elseif(CMAKE_COMPILER_IS_CLANGCXX)
|
||||
list(APPEND TEGRA_COMPILER_FLAGS -fwrapv)
|
||||
else()
|
||||
list(APPEND TEGRA_COMPILER_FLAGS -fweb -fwrapv -frename-registers -fsched2-use-superblocks -fsched2-use-traces
|
||||
-fsched-stalled-insns-dep=100 -fsched-stalled-insns=2)
|
||||
endif()
|
||||
if((ANDROID_COMPILER_IS_CLANG OR NOT ANDROID_COMPILER_VERSION VERSION_LESS "4.7") AND ANDROID_NDK_RELEASE STRGREATER "r8d" )
|
||||
list(APPEND TEGRA_COMPILER_FLAGS -fgraphite -fgraphite-identity -floop-block -floop-flatten -floop-interchange
|
||||
-floop-strip-mine -floop-parallelize-all -ftree-loop-linear)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
string(REPLACE ";" " " TEGRA_COMPILER_FLAGS "${TEGRA_COMPILER_FLAGS}")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TEGRA_COMPILER_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TEGRA_COMPILER_FLAGS}")
|
||||
|
||||
if(ARMEABI_V7A)
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-tree-vectorize" )
|
||||
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-tree-vectorize" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_LOGS)
|
||||
add_definitions(-DHAVE_LOGS)
|
||||
endif()
|
||||
|
||||
set(CAROTENE_NS "carotene_o4t" CACHE STRING "" FORCE)
|
||||
|
||||
function(compile_carotene)
|
||||
if(ENABLE_NEON)
|
||||
set(WITH_NEON ON)
|
||||
endif()
|
||||
|
||||
add_subdirectory("${CAROTENE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/carotene")
|
||||
|
||||
if(ARM OR AARCH64)
|
||||
if(CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_TRY_COMPILE_CONFIGURATION ${CMAKE_BUILD_TYPE})
|
||||
endif()
|
||||
check_cxx_compiler_flag("-mfpu=neon" CXX_HAS_MFPU_NEON)
|
||||
check_c_compiler_flag("-mfpu=neon" C_HAS_MFPU_NEON)
|
||||
if(${CXX_HAS_MFPU_NEON} AND ${C_HAS_MFPU_NEON})
|
||||
get_target_property(old_flags "carotene_objs" COMPILE_FLAGS)
|
||||
if(old_flags)
|
||||
set_target_properties("carotene_objs" PROPERTIES COMPILE_FLAGS "${old_flags} -mfpu=neon")
|
||||
else()
|
||||
set_target_properties("carotene_objs" PROPERTIES COMPILE_FLAGS "-mfpu=neon")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
compile_carotene()
|
||||
|
||||
include_directories("${CAROTENE_DIR}/include")
|
||||
|
||||
get_target_property(carotene_defs carotene_objs INTERFACE_COMPILE_DEFINITIONS)
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS ${carotene_defs})
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
# allow more inlines - these parameters improve performance for:
|
||||
# matchTemplate about 5-10%
|
||||
# goodFeaturesToTrack 10-20%
|
||||
# cornerHarris 30% for some cases
|
||||
set_source_files_properties(impl.cpp $<TARGET_OBJECTS:carotene_objs> COMPILE_FLAGS "--param ipcp-unit-growth=100000 --param inline-unit-growth=100000 --param large-stack-frame-growth=5000")
|
||||
# set_source_files_properties(impl.cpp $<TARGET_OBJECTS:carotene_objs> COMPILE_FLAGS "--param ipcp-unit-growth=100000 --param inline-unit-growth=100000 --param large-stack-frame-growth=5000")
|
||||
endif()
|
||||
|
||||
add_library(tegra_hal STATIC $<TARGET_OBJECTS:carotene_objs>)
|
||||
set_target_properties(tegra_hal PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
|
||||
set_target_properties(tegra_hal PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH})
|
||||
set(OPENCV_SRC_DIR "${CMAKE_SOURCE_DIR}")
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
ocv_install_target(tegra_hal EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
|
||||
endif()
|
||||
target_include_directories(tegra_hal PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${OPENCV_SRC_DIR}/modules/core/include)
|
||||
|
||||
set(CAROTENE_HAL_VERSION "0.0.1" PARENT_SCOPE)
|
||||
set(CAROTENE_HAL_LIBRARIES "tegra_hal" PARENT_SCOPE)
|
||||
set(CAROTENE_HAL_HEADERS "carotene/tegra_hal.hpp" PARENT_SCOPE)
|
||||
set(CAROTENE_HAL_INCLUDE_DIRS "${CMAKE_BINARY_DIR}" PARENT_SCOPE)
|
||||
|
||||
configure_file("tegra_hal.hpp" "${CMAKE_BINARY_DIR}/carotene/tegra_hal.hpp" COPYONLY)
|
||||
configure_file("${CAROTENE_DIR}/include/carotene/definitions.hpp" "${CMAKE_BINARY_DIR}/carotene/definitions.hpp" COPYONLY)
|
||||
configure_file("${CAROTENE_DIR}/include/carotene/functions.hpp" "${CMAKE_BINARY_DIR}/carotene/functions.hpp" COPYONLY)
|
||||
configure_file("${CAROTENE_DIR}/include/carotene/types.hpp" "${CMAKE_BINARY_DIR}/carotene/types.hpp" COPYONLY)
|
||||
Vendored
+1851
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#ifndef CAROTENE_DEFINITIONS_HPP
|
||||
#define CAROTENE_DEFINITIONS_HPP
|
||||
|
||||
#ifndef CAROTENE_NS
|
||||
#define CAROTENE_NS carotene
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+2492
File diff suppressed because it is too large
Load Diff
+125
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#ifndef CAROTENE_TYPES_HPP
|
||||
#define CAROTENE_TYPES_HPP
|
||||
|
||||
#include <carotene/definitions.hpp>
|
||||
#include <stdint.h>
|
||||
#include <cstddef>
|
||||
|
||||
#ifndef UINT32_MAX
|
||||
#define UINT32_MAX (4294967295U)
|
||||
#endif
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
using std::size_t;
|
||||
using std::ptrdiff_t;
|
||||
|
||||
typedef int8_t s8;
|
||||
typedef uint8_t u8;
|
||||
typedef int16_t s16;
|
||||
typedef uint16_t u16;
|
||||
typedef int32_t s32;
|
||||
typedef uint32_t u32;
|
||||
typedef float f32;
|
||||
typedef int64_t s64;
|
||||
typedef uint64_t u64;
|
||||
typedef double f64;
|
||||
|
||||
typedef ptrdiff_t stride_t;
|
||||
|
||||
enum CONVERT_POLICY
|
||||
{
|
||||
CONVERT_POLICY_WRAP,
|
||||
CONVERT_POLICY_SATURATE
|
||||
};
|
||||
|
||||
enum BORDER_MODE
|
||||
{
|
||||
BORDER_MODE_UNDEFINED,
|
||||
BORDER_MODE_CONSTANT,
|
||||
BORDER_MODE_REPLICATE,
|
||||
BORDER_MODE_REFLECT,
|
||||
BORDER_MODE_REFLECT101,
|
||||
BORDER_MODE_WRAP
|
||||
};
|
||||
|
||||
enum FLIP_MODE
|
||||
{
|
||||
FLIP_HORIZONTAL_MODE = 1,
|
||||
FLIP_VERTICAL_MODE = 2,
|
||||
FLIP_BOTH_MODE = FLIP_HORIZONTAL_MODE | FLIP_VERTICAL_MODE
|
||||
};
|
||||
|
||||
enum COLOR_SPACE
|
||||
{
|
||||
COLOR_SPACE_BT601,
|
||||
COLOR_SPACE_BT709
|
||||
};
|
||||
|
||||
struct Size2D {
|
||||
Size2D() : width(0), height(0) {}
|
||||
Size2D(size_t width_, size_t height_) : width(width_), height(height_) {}
|
||||
|
||||
size_t width;
|
||||
size_t height;
|
||||
|
||||
inline size_t total() const
|
||||
{
|
||||
return width * height;
|
||||
}
|
||||
};
|
||||
|
||||
struct Margin {
|
||||
Margin() : left(0), right(0), top(0), bottom(0) {}
|
||||
Margin(size_t left_, size_t right_, size_t top_, size_t bottom_)
|
||||
: left(left_), right(right_), top(top_), bottom(bottom_) {}
|
||||
|
||||
// these are measured in elements
|
||||
size_t left, right, top, bottom;
|
||||
};
|
||||
|
||||
struct KeypointStore {
|
||||
virtual void push(f32 kpX, f32 kpY, f32 kpSize, f32 kpAngle=-1, f32 kpResponse=0, s32 kpOctave=0, s32 kpClass_id=-1) = 0;
|
||||
virtual ~KeypointStore() {};
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
Vendored
+241
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "common.hpp"
|
||||
#include "vtransform.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
struct AbsDiff
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec128 & v_src0,
|
||||
const typename internal::VecTraits<T>::vec128 & v_src1,
|
||||
typename internal::VecTraits<T>::vec128 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vabdq(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec64 & v_src0,
|
||||
const typename internal::VecTraits<T>::vec64 & v_src1,
|
||||
typename internal::VecTraits<T>::vec64 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vabd(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const T * src0, const T * src1, T * dst) const
|
||||
{
|
||||
dst[0] = src0[0] >= src1[0] ? src0[0] - src1[0] : src1[0] - src0[0];
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct AbsDiffSigned
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec128 & v_src0,
|
||||
const typename internal::VecTraits<T>::vec128 & v_src1,
|
||||
typename internal::VecTraits<T>::vec128 & v_dst) const
|
||||
{
|
||||
typename internal::VecTraits<T>::vec128 v_min = internal::vminq(v_src0, v_src1);
|
||||
typename internal::VecTraits<T>::vec128 v_max = internal::vmaxq(v_src0, v_src1);
|
||||
v_dst = internal::vqsubq(v_max, v_min);
|
||||
}
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec64 & v_src0,
|
||||
const typename internal::VecTraits<T>::vec64 & v_src1,
|
||||
typename internal::VecTraits<T>::vec64 & v_dst) const
|
||||
{
|
||||
typename internal::VecTraits<T>::vec64 v_min = internal::vmin(v_src0, v_src1);
|
||||
typename internal::VecTraits<T>::vec64 v_max = internal::vmax(v_src0, v_src1);
|
||||
v_dst = internal::vqsub(v_max, v_min);
|
||||
}
|
||||
|
||||
void operator() (const T * src0, const T * src1, T * dst) const
|
||||
{
|
||||
dst[0] = internal::saturate_cast<T>(src0[0] >= src1[0] ? (s64)src0[0] - src1[0] : (s64)src1[0] - src0[0]);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
void absDiff(const Size2D &size,
|
||||
const u8 *src0Base, ptrdiff_t src0Stride,
|
||||
const u8 *src1Base, ptrdiff_t src1Stride,
|
||||
u8 *dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride, AbsDiff<u8>());
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
void absDiff(const Size2D &size,
|
||||
const u16 *src0Base, ptrdiff_t src0Stride,
|
||||
const u16 *src1Base, ptrdiff_t src1Stride,
|
||||
u16 *dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride, AbsDiff<u16>());
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
void absDiff(const Size2D &size,
|
||||
const s8 *src0Base, ptrdiff_t src0Stride,
|
||||
const s8 *src1Base, ptrdiff_t src1Stride,
|
||||
s8 *dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride, AbsDiffSigned<s8>());
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
void absDiff(const Size2D &size,
|
||||
const s16 *src0Base, ptrdiff_t src0Stride,
|
||||
const s16 *src1Base, ptrdiff_t src1Stride,
|
||||
s16 *dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride, AbsDiffSigned<s16>());
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
void absDiff(const Size2D &size,
|
||||
const s32 *src0Base, ptrdiff_t src0Stride,
|
||||
const s32 *src1Base, ptrdiff_t src1Stride,
|
||||
s32 *dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride, AbsDiffSigned<s32>());
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
void absDiff(const Size2D &size,
|
||||
const f32 * src0Base, ptrdiff_t src0Stride,
|
||||
const f32 * src1Base, ptrdiff_t src1Stride,
|
||||
f32 * dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride, AbsDiff<f32>());
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+408
@@ -0,0 +1,408 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "common.hpp"
|
||||
#include "vtransform.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
void accumulate(const Size2D &size,
|
||||
const u8 *srcBase, ptrdiff_t srcStride,
|
||||
s16 *dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
size_t roiw16 = size.width >= 15 ? size.width - 15 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const u8* src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
s16* dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for (; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
internal::prefetch(dst + j);
|
||||
uint8x16_t v_src = vld1q_u8(src + j);
|
||||
int16x8_t v_dst0 = vld1q_s16(dst + j);
|
||||
int16x8_t v_dst1 = vld1q_s16(dst + j + 8);
|
||||
int16x8_t v_src0 = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(v_src)));
|
||||
int16x8_t v_src1 = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(v_src)));
|
||||
v_dst0 = vqaddq_s16(v_dst0, v_src0);
|
||||
v_dst1 = vqaddq_s16(v_dst1, v_src1);
|
||||
vst1q_s16(dst + j, v_dst0);
|
||||
vst1q_s16(dst + j + 8, v_dst1);
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
uint8x8_t v_src = vld1_u8(src + j);
|
||||
int16x8_t v_src16 = vreinterpretq_s16_u16(vmovl_u8(v_src));
|
||||
int16x8_t v_dst = vld1q_s16(dst + j);
|
||||
v_dst = vqaddq_s16(v_dst, v_src16);
|
||||
vst1q_s16(dst + j, v_dst);
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
dst[j] = internal::saturate_cast<s16>(src[j] + dst[j]);
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace {
|
||||
|
||||
template <int shift>
|
||||
void accumulateSquareConst(const Size2D &size,
|
||||
const u8 *srcBase, ptrdiff_t srcStride,
|
||||
s16 *dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
size_t roiw16 = size.width >= 15 ? size.width - 15 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const u8* src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
s16* dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for (; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
internal::prefetch(dst + j);
|
||||
uint8x16_t v_src = vld1q_u8(src + j);
|
||||
int16x8_t v_dst0 = vld1q_s16(dst + j), v_dst1 = vld1q_s16(dst + j + 8);
|
||||
int16x8_t v_src0 = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(v_src)));
|
||||
int16x8_t v_src1 = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(v_src)));
|
||||
|
||||
int16x4_t v_srclo = vget_low_s16(v_src0), v_srchi = vget_high_s16(v_src0);
|
||||
v_dst0 = vcombine_s16(vqmovn_s32(vaddw_s16(vshrq_n_s32(vmull_s16(v_srclo, v_srclo), shift), vget_low_s16(v_dst0))),
|
||||
vqmovn_s32(vaddw_s16(vshrq_n_s32(vmull_s16(v_srchi, v_srchi), shift), vget_high_s16(v_dst0))));
|
||||
|
||||
v_srclo = vget_low_s16(v_src1);
|
||||
v_srchi = vget_high_s16(v_src1);
|
||||
v_dst1 = vcombine_s16(vqmovn_s32(vaddw_s16(vshrq_n_s32(vmull_s16(v_srclo, v_srclo), shift), vget_low_s16(v_dst1))),
|
||||
vqmovn_s32(vaddw_s16(vshrq_n_s32(vmull_s16(v_srchi, v_srchi), shift), vget_high_s16(v_dst1))));
|
||||
|
||||
vst1q_s16(dst + j, v_dst0);
|
||||
vst1q_s16(dst + j + 8, v_dst1);
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
int16x8_t v_src = vreinterpretq_s16_u16(vmovl_u8(vld1_u8(src + j)));
|
||||
int16x8_t v_dst = vld1q_s16(dst + j);
|
||||
int16x4_t v_srclo = vget_low_s16(v_src), v_srchi = vget_high_s16(v_src);
|
||||
v_dst = vcombine_s16(vqmovn_s32(vaddw_s16(vshrq_n_s32(vmull_s16(v_srclo, v_srclo), shift), vget_low_s16(v_dst))),
|
||||
vqmovn_s32(vaddw_s16(vshrq_n_s32(vmull_s16(v_srchi, v_srchi), shift), vget_high_s16(v_dst))));
|
||||
vst1q_s16(dst + j, v_dst);
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
s32 srcVal = src[j];
|
||||
dst[j] = internal::saturate_cast<s16>(dst[j] + ((srcVal * srcVal) >> shift));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void accumulateSquareConst<0>(const Size2D &size,
|
||||
const u8 *srcBase, ptrdiff_t srcStride,
|
||||
s16 *dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
size_t roiw16 = size.width >= 15 ? size.width - 15 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const u8* src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
s16* dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for (; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
internal::prefetch(dst + j);
|
||||
uint8x16_t v_src = vld1q_u8(src + j);
|
||||
int16x8_t v_dst0 = vld1q_s16(dst + j), v_dst1 = vld1q_s16(dst + j + 8);
|
||||
int16x8_t v_src0 = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(v_src)));
|
||||
int16x8_t v_src1 = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(v_src)));
|
||||
|
||||
int16x4_t v_srclo = vget_low_s16(v_src0), v_srchi = vget_high_s16(v_src0);
|
||||
v_dst0 = vcombine_s16(vqmovn_s32(vaddw_s16(vmull_s16(v_srclo, v_srclo), vget_low_s16(v_dst0))),
|
||||
vqmovn_s32(vaddw_s16(vmull_s16(v_srchi, v_srchi), vget_high_s16(v_dst0))));
|
||||
|
||||
v_srclo = vget_low_s16(v_src1);
|
||||
v_srchi = vget_high_s16(v_src1);
|
||||
v_dst1 = vcombine_s16(vqmovn_s32(vaddw_s16(vmull_s16(v_srclo, v_srclo), vget_low_s16(v_dst1))),
|
||||
vqmovn_s32(vaddw_s16(vmull_s16(v_srchi, v_srchi), vget_high_s16(v_dst1))));
|
||||
|
||||
vst1q_s16(dst + j, v_dst0);
|
||||
vst1q_s16(dst + j + 8, v_dst1);
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
int16x8_t v_src = vreinterpretq_s16_u16(vmovl_u8(vld1_u8(src + j)));
|
||||
int16x8_t v_dst = vld1q_s16(dst + j);
|
||||
int16x4_t v_srclo = vget_low_s16(v_src), v_srchi = vget_high_s16(v_src);
|
||||
v_dst = vcombine_s16(vqmovn_s32(vaddw_s16(vmull_s16(v_srclo, v_srclo), vget_low_s16(v_dst))),
|
||||
vqmovn_s32(vaddw_s16(vmull_s16(v_srchi, v_srchi), vget_high_s16(v_dst))));
|
||||
vst1q_s16(dst + j, v_dst);
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
s32 srcVal = src[j];
|
||||
dst[j] = internal::saturate_cast<s16>(dst[j] + srcVal * srcVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (* accumulateSquareConstFunc)(const Size2D &size,
|
||||
const u8 *srcBase, ptrdiff_t srcStride,
|
||||
s16 *dstBase, ptrdiff_t dstStride);
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
void accumulateSquare(const Size2D &size,
|
||||
const u8 *srcBase, ptrdiff_t srcStride,
|
||||
s16 *dstBase, ptrdiff_t dstStride,
|
||||
u32 shift)
|
||||
{
|
||||
if (shift >= 16)
|
||||
{
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
s16 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
std::memset(dst, 0, sizeof(s16) * size.width);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
internal::assertSupportedConfiguration();
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
// this ugly contruction is needed to avoid:
|
||||
// /usr/lib/gcc/arm-linux-gnueabihf/4.8/include/arm_neon.h:3581:59: error: argument must be a constant
|
||||
// return (int16x8_t)__builtin_neon_vshr_nv8hi (__a, __b, 1);
|
||||
|
||||
accumulateSquareConstFunc funcs[16] =
|
||||
{
|
||||
accumulateSquareConst<0>,
|
||||
accumulateSquareConst<1>,
|
||||
accumulateSquareConst<2>,
|
||||
accumulateSquareConst<3>,
|
||||
accumulateSquareConst<4>,
|
||||
accumulateSquareConst<5>,
|
||||
accumulateSquareConst<6>,
|
||||
accumulateSquareConst<7>,
|
||||
accumulateSquareConst<8>,
|
||||
accumulateSquareConst<9>,
|
||||
accumulateSquareConst<10>,
|
||||
accumulateSquareConst<11>,
|
||||
accumulateSquareConst<12>,
|
||||
accumulateSquareConst<13>,
|
||||
accumulateSquareConst<14>,
|
||||
accumulateSquareConst<15>
|
||||
}, func = funcs[shift];
|
||||
|
||||
func(size, srcBase, srcStride, dstBase, dstStride);
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)shift;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace {
|
||||
|
||||
struct AccumulateWeightedHalf
|
||||
{
|
||||
typedef u8 type;
|
||||
|
||||
void operator() (const uint8x16_t & v_src0, const uint8x16_t & v_src1,
|
||||
uint8x16_t & v_dst) const
|
||||
{
|
||||
v_dst = vhaddq_u8(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const uint8x8_t & v_src0, const uint8x8_t & v_src1,
|
||||
uint8x8_t & v_dst) const
|
||||
{
|
||||
v_dst = vhadd_u8(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const u8 * src0, const u8 * src1, u8 * dst) const
|
||||
{
|
||||
dst[0] = ((u16)(src0[0]) + src1[0]) >> 1;
|
||||
}
|
||||
};
|
||||
|
||||
struct AccumulateWeighted
|
||||
{
|
||||
typedef u8 type;
|
||||
|
||||
float alpha, beta;
|
||||
float32x4_t v_alpha, v_beta;
|
||||
|
||||
explicit AccumulateWeighted(float _alpha) :
|
||||
alpha(_alpha), beta(1 - _alpha)
|
||||
{
|
||||
v_alpha = vdupq_n_f32(alpha);
|
||||
v_beta = vdupq_n_f32(beta);
|
||||
}
|
||||
|
||||
void operator() (const uint8x16_t & v_src0, const uint8x16_t & v_src1,
|
||||
uint8x16_t & v_dst) const
|
||||
{
|
||||
uint16x8_t v_src0_p = vmovl_u8(vget_low_u8(v_src0));
|
||||
uint16x8_t v_src1_p = vmovl_u8(vget_low_u8(v_src1));
|
||||
float32x4_t v_dst0f = vmlaq_f32(vmulq_f32(vcvtq_f32_u32(vmovl_u16(vget_low_u16(v_src1_p))), v_beta),
|
||||
v_alpha, vcvtq_f32_u32(vmovl_u16(vget_low_u16(v_src0_p))));
|
||||
float32x4_t v_dst1f = vmlaq_f32(vmulq_f32(vcvtq_f32_u32(vmovl_u16(vget_high_u16(v_src1_p))), v_beta),
|
||||
v_alpha, vcvtq_f32_u32(vmovl_u16(vget_high_u16(v_src0_p))));
|
||||
uint16x8_t v_dst0 = vcombine_u16(vmovn_u32(vcvtq_u32_f32(v_dst0f)),
|
||||
vmovn_u32(vcvtq_u32_f32(v_dst1f)));
|
||||
|
||||
v_src0_p = vmovl_u8(vget_high_u8(v_src0));
|
||||
v_src1_p = vmovl_u8(vget_high_u8(v_src1));
|
||||
v_dst0f = vmlaq_f32(vmulq_f32(vcvtq_f32_u32(vmovl_u16(vget_low_u16(v_src1_p))), v_beta),
|
||||
v_alpha, vcvtq_f32_u32(vmovl_u16(vget_low_u16(v_src0_p))));
|
||||
v_dst1f = vmlaq_f32(vmulq_f32(vcvtq_f32_u32(vmovl_u16(vget_high_u16(v_src1_p))), v_beta),
|
||||
v_alpha, vcvtq_f32_u32(vmovl_u16(vget_high_u16(v_src0_p))));
|
||||
uint16x8_t v_dst1 = vcombine_u16(vmovn_u32(vcvtq_u32_f32(v_dst0f)),
|
||||
vmovn_u32(vcvtq_u32_f32(v_dst1f)));
|
||||
|
||||
v_dst = vcombine_u8(vmovn_u16(v_dst0), vmovn_u16(v_dst1));
|
||||
}
|
||||
|
||||
void operator() (const uint8x8_t & _v_src0, const uint8x8_t & _v_src1,
|
||||
uint8x8_t & v_dst) const
|
||||
{
|
||||
uint16x8_t v_src0 = vmovl_u8(_v_src0), v_src1 = vmovl_u8(_v_src1);
|
||||
|
||||
float32x4_t v_dst0f = vmlaq_f32(vmulq_f32(vcvtq_f32_u32(vmovl_u16(vget_low_u16(v_src1))), v_beta),
|
||||
v_alpha, vcvtq_f32_u32(vmovl_u16(vget_low_u16(v_src0))));
|
||||
float32x4_t v_dst1f = vmlaq_f32(vmulq_f32(vcvtq_f32_u32(vmovl_u16(vget_high_u16(v_src1))), v_beta),
|
||||
v_alpha, vcvtq_f32_u32(vmovl_u16(vget_high_u16(v_src0))));
|
||||
uint16x8_t _v_dst = vcombine_u16(vmovn_u32(vcvtq_u32_f32(v_dst0f)),
|
||||
vmovn_u32(vcvtq_u32_f32(v_dst1f)));
|
||||
|
||||
v_dst = vmovn_u16(_v_dst);
|
||||
}
|
||||
|
||||
void operator() (const u8 * src0, const u8 * src1, u8 * dst) const
|
||||
{
|
||||
dst[0] = beta * src1[0] + alpha * src0[0];
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
void accumulateWeighted(const Size2D &size,
|
||||
const u8 *srcBase, ptrdiff_t srcStride,
|
||||
u8 *dstBase, ptrdiff_t dstStride,
|
||||
f32 alpha)
|
||||
{
|
||||
if (alpha == 0.0f)
|
||||
return;
|
||||
if (alpha == 1.0f)
|
||||
{
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const u8 * src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
u8 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
std::memcpy(dst, src, sizeof(u8) * size.width);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
internal::assertSupportedConfiguration();
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
// in this case we can use the following scheme:
|
||||
// dst[p] = (src[p] + dst[p]) >> 1
|
||||
// which is faster
|
||||
if (alpha == 0.5f)
|
||||
{
|
||||
internal::vtransform(size,
|
||||
srcBase, srcStride,
|
||||
dstBase, dstStride,
|
||||
dstBase, dstStride,
|
||||
AccumulateWeightedHalf());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
internal::vtransform(size,
|
||||
srcBase, srcStride,
|
||||
dstBase, dstStride,
|
||||
dstBase, dstStride,
|
||||
AccumulateWeighted(alpha));
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)alpha;
|
||||
#endif
|
||||
}
|
||||
|
||||
} //namespace CAROTENE_NS
|
||||
Vendored
+475
@@ -0,0 +1,475 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "vtransform.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T, typename WT>
|
||||
struct AddWrap
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec128 & v_src0,
|
||||
const typename internal::VecTraits<T>::vec128 & v_src1,
|
||||
typename internal::VecTraits<T>::vec128 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vaddq(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec64 & v_src0,
|
||||
const typename internal::VecTraits<T>::vec64 & v_src1,
|
||||
typename internal::VecTraits<T>::vec64 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vadd(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const T * src0, const T * src1, T * dst) const
|
||||
{
|
||||
dst[0] = (T)((WT)src0[0] + (WT)src1[0]);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename WT>
|
||||
struct AddSaturate
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec128 & v_src0,
|
||||
const typename internal::VecTraits<T>::vec128 & v_src1,
|
||||
typename internal::VecTraits<T>::vec128 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vqaddq(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec64 & v_src0,
|
||||
const typename internal::VecTraits<T>::vec64 & v_src1,
|
||||
typename internal::VecTraits<T>::vec64 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vqadd(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const T * src0, const T * src1, T * dst) const
|
||||
{
|
||||
dst[0] = internal::saturate_cast<T>((WT)src0[0] + (WT)src1[0]);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
void add(const Size2D &size,
|
||||
const u8 * src0Base, ptrdiff_t src0Stride,
|
||||
const u8 * src1Base, ptrdiff_t src1Stride,
|
||||
u8 *dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY policy)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
if (policy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
AddSaturate<u8, u16>());
|
||||
}
|
||||
else
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
AddWrap<u8, u16>());
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)policy;
|
||||
#endif
|
||||
}
|
||||
|
||||
void add(const Size2D &size,
|
||||
const s8 * src0Base, ptrdiff_t src0Stride,
|
||||
const s8 * src1Base, ptrdiff_t src1Stride,
|
||||
s8 *dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY policy)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
if (policy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
AddSaturate<s8, s16>());
|
||||
}
|
||||
else
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
AddWrap<s8, s16>());
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)policy;
|
||||
#endif
|
||||
}
|
||||
|
||||
void add(const Size2D &size,
|
||||
const u8 * src0Base, ptrdiff_t src0Stride,
|
||||
const u8 * src1Base, ptrdiff_t src1Stride,
|
||||
s16 *dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
size_t roiw32 = size.width >= 31 ? size.width - 31 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const u8 * src0 = internal::getRowPtr(src0Base, src0Stride, i);
|
||||
const u8 * src1 = internal::getRowPtr(src1Base, src1Stride, i);
|
||||
u16 * dst = internal::getRowPtr((u16 *)dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for (; j < roiw32; j += 32)
|
||||
{
|
||||
internal::prefetch(src0 + j);
|
||||
internal::prefetch(src1 + j);
|
||||
uint8x16_t v_src00 = vld1q_u8(src0 + j), v_src01 = vld1q_u8(src0 + j + 16);
|
||||
uint8x16_t v_src10 = vld1q_u8(src1 + j), v_src11 = vld1q_u8(src1 + j + 16);
|
||||
vst1q_u16(dst + j, vaddl_u8(vget_low_u8(v_src00), vget_low_u8(v_src10)));
|
||||
vst1q_u16(dst + j + 8, vaddl_u8(vget_high_u8(v_src00), vget_high_u8(v_src10)));
|
||||
vst1q_u16(dst + j + 16, vaddl_u8(vget_low_u8(v_src01), vget_low_u8(v_src11)));
|
||||
vst1q_u16(dst + j + 24, vaddl_u8(vget_high_u8(v_src01), vget_high_u8(v_src11)));
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
uint8x8_t v_src0 = vld1_u8(src0 + j);
|
||||
uint8x8_t v_src1 = vld1_u8(src1 + j);
|
||||
vst1q_u16(dst + j, vaddl_u8(v_src0, v_src1));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
dst[j] = (u16)src0[j] + (u16)src1[j];
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
void add(const Size2D &size,
|
||||
const u8 * src0Base, ptrdiff_t src0Stride,
|
||||
const s16 * src1Base, ptrdiff_t src1Stride,
|
||||
s16 *dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY policy)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
size_t roiw16 = size.width >= 15 ? size.width - 15 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const u8 * src0 = internal::getRowPtr(src0Base, src0Stride, i);
|
||||
const s16 * src1 = internal::getRowPtr(src1Base, src1Stride, i);
|
||||
s16 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
if (policy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
for (; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src0 + j);
|
||||
internal::prefetch(src1 + j);
|
||||
uint8x16_t v_src0 = vld1q_u8(src0 + j);
|
||||
int16x8_t v_src00 = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(v_src0)));
|
||||
int16x8_t v_src01 = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(v_src0)));
|
||||
int16x8_t v_src10 = vld1q_s16(src1 + j), v_src11 = vld1q_s16(src1 + j + 8);
|
||||
int16x8_t v_dst0 = vqaddq_s16(v_src00, v_src10);
|
||||
int16x8_t v_dst1 = vqaddq_s16(v_src01, v_src11);
|
||||
vst1q_s16(dst + j, v_dst0);
|
||||
vst1q_s16(dst + j + 8, v_dst1);
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
int16x8_t v_src0 = vreinterpretq_s16_u16(vmovl_u8(vld1_u8(src0 + j)));
|
||||
int16x8_t v_src1 = vld1q_s16(src1 + j);
|
||||
int16x8_t v_dst = vqaddq_s16(v_src0, v_src1);
|
||||
vst1q_s16(dst + j, v_dst);
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
dst[j] = internal::saturate_cast<s16>((s32)src0[j] + (s32)src1[j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src0 + j);
|
||||
internal::prefetch(src1 + j);
|
||||
uint8x16_t v_src0 = vld1q_u8(src0 + j);
|
||||
int16x8_t v_src00 = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(v_src0)));
|
||||
int16x8_t v_src01 = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(v_src0)));
|
||||
int16x8_t v_src10 = vld1q_s16(src1 + j), v_src11 = vld1q_s16(src1 + j + 8);
|
||||
int16x8_t v_dst0 = vaddq_s16(v_src00, v_src10);
|
||||
int16x8_t v_dst1 = vaddq_s16(v_src01, v_src11);
|
||||
vst1q_s16(dst + j, v_dst0);
|
||||
vst1q_s16(dst + j + 8, v_dst1);
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
int16x8_t v_src0 = vreinterpretq_s16_u16(vmovl_u8(vld1_u8(src0 + j)));
|
||||
int16x8_t v_src1 = vld1q_s16(src1 + j);
|
||||
int16x8_t v_dst = vaddq_s16(v_src0, v_src1);
|
||||
vst1q_s16(dst + j, v_dst);
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
dst[j] = (s16)((s32)src0[j] + (s32)src1[j]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)policy;
|
||||
#endif
|
||||
}
|
||||
|
||||
void add(const Size2D &size,
|
||||
const s16 * src0Base, ptrdiff_t src0Stride,
|
||||
const s16 * src1Base, ptrdiff_t src1Stride,
|
||||
s16 *dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY policy)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
if (policy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
AddSaturate<s16, s32>());
|
||||
}
|
||||
else
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
AddWrap<s16, s32>());
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)policy;
|
||||
#endif
|
||||
}
|
||||
|
||||
void add(const Size2D &size,
|
||||
const u16 * src0Base, ptrdiff_t src0Stride,
|
||||
const u16 * src1Base, ptrdiff_t src1Stride,
|
||||
u16 * dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY policy)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
if (policy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
AddSaturate<u16, u32>());
|
||||
}
|
||||
else
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
AddWrap<u16, u32>());
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)policy;
|
||||
#endif
|
||||
}
|
||||
|
||||
void add(const Size2D &size,
|
||||
const s32 * src0Base, ptrdiff_t src0Stride,
|
||||
const s32 * src1Base, ptrdiff_t src1Stride,
|
||||
s32 *dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY policy)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
if (policy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
AddSaturate<s32, s64>());
|
||||
}
|
||||
else
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
AddWrap<s32, s64>());
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)policy;
|
||||
#endif
|
||||
}
|
||||
|
||||
void add(const Size2D &size,
|
||||
const u32 * src0Base, ptrdiff_t src0Stride,
|
||||
const u32 * src1Base, ptrdiff_t src1Stride,
|
||||
u32 * dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY policy)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
if (policy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
AddSaturate<u32, u64>());
|
||||
}
|
||||
else
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
AddWrap<u32, u64>());
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)policy;
|
||||
#endif
|
||||
}
|
||||
|
||||
void add(const Size2D &size,
|
||||
const f32 * src0Base, ptrdiff_t src0Stride,
|
||||
const f32 * src1Base, ptrdiff_t src1Stride,
|
||||
f32 * dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
AddWrap<f32, f32>());
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
+265
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2012-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "vtransform.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace internal;
|
||||
|
||||
template <typename T> struct TypeTraits;
|
||||
template <> struct TypeTraits< u8> { typedef u16 wide; typedef u8 unsign; typedef uint8x16_t vec128; };
|
||||
template <> struct TypeTraits< s8> { typedef s16 wide; typedef u8 unsign; typedef int8x16_t vec128; };
|
||||
template <> struct TypeTraits<u16> { typedef u32 wide; typedef u8 narrow; typedef u16 unsign; typedef uint16x8_t vec128; };
|
||||
template <> struct TypeTraits<s16> { typedef s32 wide; typedef s8 narrow; typedef u16 unsign; typedef int16x8_t vec128; };
|
||||
template <> struct TypeTraits<u32> { typedef u64 wide; typedef u16 narrow; typedef u32 unsign; typedef uint32x4_t vec128; };
|
||||
template <> struct TypeTraits<s32> { typedef s64 wide; typedef s16 narrow; typedef u32 unsign; typedef int32x4_t vec128; };
|
||||
template <> struct TypeTraits<f32> { typedef f64 wide; typedef float32x4_t vec128; };
|
||||
|
||||
template <typename T> struct wAdd
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
f32 alpha, beta, gamma;
|
||||
typedef typename TypeTraits<T>::wide wtype;
|
||||
wAdd<wtype> wideAdd;
|
||||
wAdd(f32 _alpha, f32 _beta, f32 _gamma):
|
||||
alpha(_alpha), beta(_beta), gamma(_gamma),
|
||||
wideAdd(_alpha, _beta, _gamma) {}
|
||||
|
||||
void operator() (const typename VecTraits<T>::vec128 & v_src0,
|
||||
const typename VecTraits<T>::vec128 & v_src1,
|
||||
typename VecTraits<T>::vec128 & v_dst) const
|
||||
{
|
||||
typename VecTraits<wtype>::vec128 vrl, vrh;
|
||||
wideAdd(vmovl( vget_low(v_src0)), vmovl( vget_low(v_src1)), vrl);
|
||||
wideAdd(vmovl(vget_high(v_src0)), vmovl(vget_high(v_src1)), vrh);
|
||||
|
||||
v_dst = vcombine(vqmovn(vrl), vqmovn(vrh));
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<T>::vec64 & v_src0,
|
||||
const typename VecTraits<T>::vec64 & v_src1,
|
||||
typename VecTraits<T>::vec64 & v_dst) const
|
||||
{
|
||||
typename VecTraits<wtype>::vec128 vr;
|
||||
wideAdd(vmovl(v_src0), vmovl(v_src1), vr);
|
||||
|
||||
v_dst = vqmovn(vr);
|
||||
}
|
||||
|
||||
void operator() (const T * src0, const T * src1, T * dst) const
|
||||
{
|
||||
dst[0] = saturate_cast<T>(alpha*src0[0] + beta*src1[0] + gamma);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct wAdd<s32>
|
||||
{
|
||||
typedef s32 type;
|
||||
|
||||
f32 alpha, beta, gamma;
|
||||
float32x4_t valpha, vbeta, vgamma;
|
||||
wAdd(f32 _alpha, f32 _beta, f32 _gamma):
|
||||
alpha(_alpha), beta(_beta), gamma(_gamma)
|
||||
{
|
||||
valpha = vdupq_n_f32(_alpha);
|
||||
vbeta = vdupq_n_f32(_beta);
|
||||
vgamma = vdupq_n_f32(_gamma + 0.5);
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<s32>::vec128 & v_src0,
|
||||
const typename VecTraits<s32>::vec128 & v_src1,
|
||||
typename VecTraits<s32>::vec128 & v_dst) const
|
||||
{
|
||||
float32x4_t vs1 = vcvtq_f32_s32(v_src0);
|
||||
float32x4_t vs2 = vcvtq_f32_s32(v_src1);
|
||||
|
||||
vs1 = vmlaq_f32(vgamma, vs1, valpha);
|
||||
vs1 = vmlaq_f32(vs1, vs2, vbeta);
|
||||
v_dst = vcvtq_s32_f32(vs1);
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<s32>::vec64 & v_src0,
|
||||
const typename VecTraits<s32>::vec64 & v_src1,
|
||||
typename VecTraits<s32>::vec64 & v_dst) const
|
||||
{
|
||||
float32x2_t vs1 = vcvt_f32_s32(v_src0);
|
||||
float32x2_t vs2 = vcvt_f32_s32(v_src1);
|
||||
|
||||
vs1 = vmla_f32(vget_low(vgamma), vs1, vget_low(valpha));
|
||||
vs1 = vmla_f32(vs1, vs2, vget_low(vbeta));
|
||||
v_dst = vcvt_s32_f32(vs1);
|
||||
}
|
||||
|
||||
void operator() (const s32 * src0, const s32 * src1, s32 * dst) const
|
||||
{
|
||||
dst[0] = saturate_cast<s32>(alpha*src0[0] + beta*src1[0] + gamma);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct wAdd<u32>
|
||||
{
|
||||
typedef u32 type;
|
||||
|
||||
f32 alpha, beta, gamma;
|
||||
float32x4_t valpha, vbeta, vgamma;
|
||||
wAdd(f32 _alpha, f32 _beta, f32 _gamma):
|
||||
alpha(_alpha), beta(_beta), gamma(_gamma)
|
||||
{
|
||||
valpha = vdupq_n_f32(_alpha);
|
||||
vbeta = vdupq_n_f32(_beta);
|
||||
vgamma = vdupq_n_f32(_gamma + 0.5);
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<u32>::vec128 & v_src0,
|
||||
const typename VecTraits<u32>::vec128 & v_src1,
|
||||
typename VecTraits<u32>::vec128 & v_dst) const
|
||||
{
|
||||
float32x4_t vs1 = vcvtq_f32_u32(v_src0);
|
||||
float32x4_t vs2 = vcvtq_f32_u32(v_src1);
|
||||
|
||||
vs1 = vmlaq_f32(vgamma, vs1, valpha);
|
||||
vs1 = vmlaq_f32(vs1, vs2, vbeta);
|
||||
v_dst = vcvtq_u32_f32(vs1);
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<u32>::vec64 & v_src0,
|
||||
const typename VecTraits<u32>::vec64 & v_src1,
|
||||
typename VecTraits<u32>::vec64 & v_dst) const
|
||||
{
|
||||
float32x2_t vs1 = vcvt_f32_u32(v_src0);
|
||||
float32x2_t vs2 = vcvt_f32_u32(v_src1);
|
||||
|
||||
vs1 = vmla_f32(vget_low(vgamma), vs1, vget_low(valpha));
|
||||
vs1 = vmla_f32(vs1, vs2, vget_low(vbeta));
|
||||
v_dst = vcvt_u32_f32(vs1);
|
||||
}
|
||||
|
||||
void operator() (const u32 * src0, const u32 * src1, u32 * dst) const
|
||||
{
|
||||
dst[0] = saturate_cast<u32>(alpha*src0[0] + beta*src1[0] + gamma);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct wAdd<f32>
|
||||
{
|
||||
typedef f32 type;
|
||||
|
||||
f32 alpha, beta, gamma;
|
||||
float32x4_t valpha, vbeta, vgamma;
|
||||
wAdd(f32 _alpha, f32 _beta, f32 _gamma):
|
||||
alpha(_alpha), beta(_beta), gamma(_gamma)
|
||||
{
|
||||
valpha = vdupq_n_f32(_alpha);
|
||||
vbeta = vdupq_n_f32(_beta);
|
||||
vgamma = vdupq_n_f32(_gamma + 0.5);
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<f32>::vec128 & v_src0,
|
||||
const typename VecTraits<f32>::vec128 & v_src1,
|
||||
typename VecTraits<f32>::vec128 & v_dst) const
|
||||
{
|
||||
float32x4_t vs1 = vmlaq_f32(vgamma, v_src0, valpha);
|
||||
v_dst = vmlaq_f32(vs1, v_src1, vbeta);
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<f32>::vec64 & v_src0,
|
||||
const typename VecTraits<f32>::vec64 & v_src1,
|
||||
typename VecTraits<f32>::vec64 & v_dst) const
|
||||
{
|
||||
float32x2_t vs1 = vmla_f32(vget_low(vgamma), v_src0, vget_low(valpha));
|
||||
v_dst = vmla_f32(vs1, v_src1, vget_low(vbeta));
|
||||
|
||||
}
|
||||
|
||||
void operator() (const f32 * src0, const f32 * src1, f32 * dst) const
|
||||
{
|
||||
dst[0] = alpha*src0[0] + beta*src1[0] + gamma;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#define IMPL_ADDWEIGHTED(type) \
|
||||
void addWeighted(const Size2D &size, \
|
||||
const type * src0Base, ptrdiff_t src0Stride, \
|
||||
const type * src1Base, ptrdiff_t src1Stride, \
|
||||
type * dstBase, ptrdiff_t dstStride, \
|
||||
f32 alpha, f32 beta, f32 gamma) \
|
||||
{ \
|
||||
internal::assertSupportedConfiguration(); \
|
||||
wAdd<type> wgtAdd(alpha, \
|
||||
beta, \
|
||||
gamma); \
|
||||
internal::vtransform(size, \
|
||||
src0Base, src0Stride, \
|
||||
src1Base, src1Stride, \
|
||||
dstBase, dstStride, \
|
||||
wgtAdd); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define IMPL_ADDWEIGHTED(type) \
|
||||
void addWeighted(const Size2D &, \
|
||||
const type *, ptrdiff_t, \
|
||||
const type *, ptrdiff_t, \
|
||||
type *, ptrdiff_t, \
|
||||
f32, f32, f32) \
|
||||
{ \
|
||||
internal::assertSupportedConfiguration(); \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
IMPL_ADDWEIGHTED(u8)
|
||||
IMPL_ADDWEIGHTED(s8)
|
||||
IMPL_ADDWEIGHTED(u16)
|
||||
IMPL_ADDWEIGHTED(s16)
|
||||
IMPL_ADDWEIGHTED(u32)
|
||||
IMPL_ADDWEIGHTED(s32)
|
||||
IMPL_ADDWEIGHTED(f32)
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+225
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "vtransform.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
struct BitwiseAnd
|
||||
{
|
||||
typedef u8 type;
|
||||
|
||||
void operator() (const uint8x16_t & v_src0, const uint8x16_t & v_src1,
|
||||
uint8x16_t & v_dst) const
|
||||
{
|
||||
v_dst = vandq_u8(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const uint8x8_t & v_src0, const uint8x8_t & v_src1,
|
||||
uint8x8_t & v_dst) const
|
||||
{
|
||||
v_dst = vand_u8(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const u8 * src0, const u8 * src1, u8 * dst) const
|
||||
{
|
||||
dst[0] = src0[0] & src1[0];
|
||||
}
|
||||
};
|
||||
|
||||
struct BitwiseOr
|
||||
{
|
||||
typedef u8 type;
|
||||
|
||||
void operator() (const uint8x16_t & v_src0, const uint8x16_t & v_src1,
|
||||
uint8x16_t & v_dst) const
|
||||
{
|
||||
v_dst = vorrq_u8(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const uint8x8_t & v_src0, const uint8x8_t & v_src1,
|
||||
uint8x8_t & v_dst) const
|
||||
{
|
||||
v_dst = vorr_u8(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const u8 * src0, const u8 * src1, u8 * dst) const
|
||||
{
|
||||
dst[0] = src0[0] | src1[0];
|
||||
}
|
||||
};
|
||||
|
||||
struct BitwiseXor
|
||||
{
|
||||
typedef u8 type;
|
||||
|
||||
void operator() (const uint8x16_t & v_src0, const uint8x16_t & v_src1,
|
||||
uint8x16_t & v_dst) const
|
||||
{
|
||||
v_dst = veorq_u8(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const uint8x8_t & v_src0, const uint8x8_t & v_src1,
|
||||
uint8x8_t & v_dst) const
|
||||
{
|
||||
v_dst = veor_u8(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const u8 * src0, const u8 * src1, u8 * dst) const
|
||||
{
|
||||
dst[0] = src0[0] ^ src1[0];
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
void bitwiseNot(const Size2D &size,
|
||||
const u8 *srcBase, ptrdiff_t srcStride,
|
||||
u8 *dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
size_t roiw32 = size.width >= 31 ? size.width - 31 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const u8* src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
u8* dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for (; j < roiw32; j += 32)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
uint8x16_t v_src0 = vld1q_u8(src + j), v_src1 = vld1q_u8(src + j + 16);
|
||||
uint8x16_t v_dst0 = vmvnq_u8(v_src0), v_dst1 = vmvnq_u8(v_src1);
|
||||
vst1q_u8(dst + j, v_dst0);
|
||||
vst1q_u8(dst + j + 16, v_dst1);
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
uint8x8_t v_src = vld1_u8(src + j);
|
||||
uint8x8_t v_dst = vmvn_u8(v_src);
|
||||
vst1_u8(dst + j, v_dst);
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = ~src[j];
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
void bitwiseAnd(const Size2D &size,
|
||||
const u8 *src0Base, ptrdiff_t src0Stride,
|
||||
const u8 *src1Base, ptrdiff_t src1Stride,
|
||||
u8 *dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride, BitwiseAnd());
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
void bitwiseOr(const Size2D &size,
|
||||
const u8 *src0Base, ptrdiff_t src0Stride,
|
||||
const u8 *src1Base, ptrdiff_t src1Stride,
|
||||
u8 *dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride, BitwiseOr());
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
void bitwiseXor(const Size2D &size,
|
||||
const u8 *src0Base, ptrdiff_t src0Stride,
|
||||
const u8 *src1Base, ptrdiff_t src1Stride,
|
||||
u8 *dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride, BitwiseXor());
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+1337
File diff suppressed because it is too large
Load Diff
Vendored
+773
@@ -0,0 +1,773 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2012-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include "saturate_cast.hpp"
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
namespace {
|
||||
struct RowFilter3x3Canny
|
||||
{
|
||||
inline RowFilter3x3Canny(const ptrdiff_t borderxl, const ptrdiff_t borderxr)
|
||||
{
|
||||
vfmask = vreinterpret_u8_u64(vmov_n_u64(borderxl ? 0x0000FFffFFffFFffULL : 0x0100FFffFFffFFffULL));
|
||||
vtmask = vreinterpret_u8_u64(vmov_n_u64(borderxr ? 0x0707060504030201ULL : 0x0706050403020100ULL));
|
||||
lookLeft = offsetk - borderxl;
|
||||
lookRight = offsetk - borderxr;
|
||||
}
|
||||
|
||||
inline void operator()(const u8* src, s16* dstx, s16* dsty, ptrdiff_t width)
|
||||
{
|
||||
uint8x8_t l = vtbl1_u8(vld1_u8(src - lookLeft), vfmask);
|
||||
ptrdiff_t i = 0;
|
||||
for (; i < width - 8 + lookRight; i += 8)
|
||||
{
|
||||
internal::prefetch(src + i);
|
||||
uint8x8_t l18u = vld1_u8(src + i + 1);
|
||||
|
||||
uint8x8_t l2 = l18u;
|
||||
uint8x8_t l0 = vext_u8(l, l18u, 6);
|
||||
int16x8_t l1x2 = vreinterpretq_s16_u16(vshll_n_u8(vext_u8(l, l18u, 7), 1));
|
||||
|
||||
l = l18u;
|
||||
|
||||
int16x8_t l02 = vreinterpretq_s16_u16(vaddl_u8(l2, l0));
|
||||
int16x8_t ldx = vreinterpretq_s16_u16(vsubl_u8(l2, l0));
|
||||
int16x8_t ldy = vaddq_s16(l02, l1x2);
|
||||
|
||||
vst1q_s16(dstx + i, ldx);
|
||||
vst1q_s16(dsty + i, ldy);
|
||||
}
|
||||
|
||||
//tail
|
||||
if (lookRight == 0 || i != width)
|
||||
{
|
||||
uint8x8_t tail0 = vld1_u8(src + (width - 9));//can't get left 1 pixel another way if width==8*k+1
|
||||
uint8x8_t tail2 = vtbl1_u8(vld1_u8(src + (width - 8 + lookRight)), vtmask);
|
||||
uint8x8_t tail1 = vext_u8(vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(tail0), 8*6)), tail2, 7);
|
||||
|
||||
int16x8_t tail02 = vreinterpretq_s16_u16(vaddl_u8(tail2, tail0));
|
||||
int16x8_t tail1x2 = vreinterpretq_s16_u16(vshll_n_u8(tail1, 1));
|
||||
int16x8_t taildx = vreinterpretq_s16_u16(vsubl_u8(tail2, tail0));
|
||||
int16x8_t taildy = vqaddq_s16(tail02, tail1x2);
|
||||
|
||||
vst1q_s16(dstx + (width - 8), taildx);
|
||||
vst1q_s16(dsty + (width - 8), taildy);
|
||||
}
|
||||
}
|
||||
|
||||
uint8x8_t vfmask;
|
||||
uint8x8_t vtmask;
|
||||
enum { offsetk = 1};
|
||||
ptrdiff_t lookLeft;
|
||||
ptrdiff_t lookRight;
|
||||
};
|
||||
|
||||
template <bool L2gradient>
|
||||
inline void ColFilter3x3Canny(const s16* src0, const s16* src1, const s16* src2, s16* dstx, s16* dsty, s32* mag, ptrdiff_t width)
|
||||
{
|
||||
ptrdiff_t j = 0;
|
||||
for (; j <= width - 8; j += 8)
|
||||
{
|
||||
ColFilter3x3CannyL1Loop:
|
||||
int16x8_t line0x = vld1q_s16(src0 + j);
|
||||
int16x8_t line1x = vld1q_s16(src1 + j);
|
||||
int16x8_t line2x = vld1q_s16(src2 + j);
|
||||
int16x8_t line0y = vld1q_s16(src0 + j + width);
|
||||
int16x8_t line2y = vld1q_s16(src2 + j + width);
|
||||
|
||||
int16x8_t l02 = vaddq_s16(line0x, line2x);
|
||||
int16x8_t l1x2 = vshlq_n_s16(line1x, 1);
|
||||
int16x8_t dy = vsubq_s16(line2y, line0y);
|
||||
int16x8_t dx = vaddq_s16(l1x2, l02);
|
||||
|
||||
int16x8_t dya = vabsq_s16(dy);
|
||||
int16x8_t dxa = vabsq_s16(dx);
|
||||
int16x8_t norm = vaddq_s16(dya, dxa);
|
||||
|
||||
int32x4_t normh = vmovl_s16(vget_high_s16(norm));
|
||||
int32x4_t norml = vmovl_s16(vget_low_s16(norm));
|
||||
|
||||
vst1q_s16(dsty + j, dy);
|
||||
vst1q_s16(dstx + j, dx);
|
||||
vst1q_s32(mag + j + 4, normh);
|
||||
vst1q_s32(mag + j, norml);
|
||||
}
|
||||
if (j != width)
|
||||
{
|
||||
j = width - 8;
|
||||
goto ColFilter3x3CannyL1Loop;
|
||||
}
|
||||
}
|
||||
template <>
|
||||
inline void ColFilter3x3Canny<true>(const s16* src0, const s16* src1, const s16* src2, s16* dstx, s16* dsty, s32* mag, ptrdiff_t width)
|
||||
{
|
||||
ptrdiff_t j = 0;
|
||||
for (; j <= width - 8; j += 8)
|
||||
{
|
||||
ColFilter3x3CannyL2Loop:
|
||||
int16x8_t line0x = vld1q_s16(src0 + j);
|
||||
int16x8_t line1x = vld1q_s16(src1 + j);
|
||||
int16x8_t line2x = vld1q_s16(src2 + j);
|
||||
int16x8_t line0y = vld1q_s16(src0 + j + width);
|
||||
int16x8_t line2y = vld1q_s16(src2 + j + width);
|
||||
|
||||
int16x8_t l02 = vaddq_s16(line0x, line2x);
|
||||
int16x8_t l1x2 = vshlq_n_s16(line1x, 1);
|
||||
int16x8_t dy = vsubq_s16(line2y, line0y);
|
||||
int16x8_t dx = vaddq_s16(l1x2, l02);
|
||||
|
||||
int32x4_t norml = vmull_s16(vget_low_s16(dx), vget_low_s16(dx));
|
||||
int32x4_t normh = vmull_s16(vget_high_s16(dy), vget_high_s16(dy));
|
||||
|
||||
norml = vmlal_s16(norml, vget_low_s16(dy), vget_low_s16(dy));
|
||||
normh = vmlal_s16(normh, vget_high_s16(dx), vget_high_s16(dx));
|
||||
|
||||
vst1q_s16(dsty + j, dy);
|
||||
vst1q_s16(dstx + j, dx);
|
||||
vst1q_s32(mag + j, norml);
|
||||
vst1q_s32(mag + j + 4, normh);
|
||||
}
|
||||
if (j != width)
|
||||
{
|
||||
j = width - 8;
|
||||
goto ColFilter3x3CannyL2Loop;
|
||||
}
|
||||
}
|
||||
|
||||
template <bool L2gradient>
|
||||
inline void NormCanny(const ptrdiff_t colscn, s16* _dx, s16* _dy, s32* _norm)
|
||||
{
|
||||
ptrdiff_t j = 0;
|
||||
if (colscn >= 8)
|
||||
{
|
||||
int16x8_t vx = vld1q_s16(_dx);
|
||||
int16x8_t vy = vld1q_s16(_dy);
|
||||
for (; j <= colscn - 16; j+=8)
|
||||
{
|
||||
internal::prefetch(_dx);
|
||||
internal::prefetch(_dy);
|
||||
|
||||
int16x8_t vx2 = vld1q_s16(_dx + j + 8);
|
||||
int16x8_t vy2 = vld1q_s16(_dy + j + 8);
|
||||
|
||||
int16x8_t vabsx = vabsq_s16(vx);
|
||||
int16x8_t vabsy = vabsq_s16(vy);
|
||||
|
||||
int16x8_t norm = vaddq_s16(vabsx, vabsy);
|
||||
|
||||
int32x4_t normh = vmovl_s16(vget_high_s16(norm));
|
||||
int32x4_t norml = vmovl_s16(vget_low_s16(norm));
|
||||
|
||||
vst1q_s32(_norm + j + 4, normh);
|
||||
vst1q_s32(_norm + j + 0, norml);
|
||||
|
||||
vx = vx2;
|
||||
vy = vy2;
|
||||
}
|
||||
int16x8_t vabsx = vabsq_s16(vx);
|
||||
int16x8_t vabsy = vabsq_s16(vy);
|
||||
|
||||
int16x8_t norm = vaddq_s16(vabsx, vabsy);
|
||||
|
||||
int32x4_t normh = vmovl_s16(vget_high_s16(norm));
|
||||
int32x4_t norml = vmovl_s16(vget_low_s16(norm));
|
||||
|
||||
vst1q_s32(_norm + j + 4, normh);
|
||||
vst1q_s32(_norm + j + 0, norml);
|
||||
}
|
||||
for (; j < colscn; j++)
|
||||
_norm[j] = std::abs(s32(_dx[j])) + std::abs(s32(_dy[j]));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void NormCanny<true>(const ptrdiff_t colscn, s16* _dx, s16* _dy, s32* _norm)
|
||||
{
|
||||
ptrdiff_t j = 0;
|
||||
if (colscn >= 8)
|
||||
{
|
||||
int16x8_t vx = vld1q_s16(_dx);
|
||||
int16x8_t vy = vld1q_s16(_dy);
|
||||
|
||||
for (; j <= colscn - 16; j+=8)
|
||||
{
|
||||
internal::prefetch(_dx);
|
||||
internal::prefetch(_dy);
|
||||
|
||||
int16x8_t vxnext = vld1q_s16(_dx + j + 8);
|
||||
int16x8_t vynext = vld1q_s16(_dy + j + 8);
|
||||
|
||||
int32x4_t norml = vmull_s16(vget_low_s16(vx), vget_low_s16(vx));
|
||||
int32x4_t normh = vmull_s16(vget_high_s16(vy), vget_high_s16(vy));
|
||||
|
||||
norml = vmlal_s16(norml, vget_low_s16(vy), vget_low_s16(vy));
|
||||
normh = vmlal_s16(normh, vget_high_s16(vx), vget_high_s16(vx));
|
||||
|
||||
vst1q_s32(_norm + j + 0, norml);
|
||||
vst1q_s32(_norm + j + 4, normh);
|
||||
|
||||
vx = vxnext;
|
||||
vy = vynext;
|
||||
}
|
||||
int32x4_t norml = vmull_s16(vget_low_s16(vx), vget_low_s16(vx));
|
||||
int32x4_t normh = vmull_s16(vget_high_s16(vy), vget_high_s16(vy));
|
||||
|
||||
norml = vmlal_s16(norml, vget_low_s16(vy), vget_low_s16(vy));
|
||||
normh = vmlal_s16(normh, vget_high_s16(vx), vget_high_s16(vx));
|
||||
|
||||
vst1q_s32(_norm + j + 0, norml);
|
||||
vst1q_s32(_norm + j + 4, normh);
|
||||
}
|
||||
for (; j < colscn; j++)
|
||||
_norm[j] = s32(_dx[j])*_dx[j] + s32(_dy[j])*_dy[j];
|
||||
}
|
||||
|
||||
template <bool L2gradient>
|
||||
inline void prepareThresh(f64 low_thresh, f64 high_thresh,
|
||||
s32 &low, s32 &high)
|
||||
{
|
||||
if (low_thresh > high_thresh)
|
||||
std::swap(low_thresh, high_thresh);
|
||||
#if defined __GNUC__
|
||||
low = (s32)low_thresh;
|
||||
high = (s32)high_thresh;
|
||||
low -= (low > low_thresh);
|
||||
high -= (high > high_thresh);
|
||||
#else
|
||||
low = internal::round(low_thresh);
|
||||
high = internal::round(high_thresh);
|
||||
f32 ldiff = (f32)(low_thresh - low);
|
||||
f32 hdiff = (f32)(high_thresh - high);
|
||||
low -= (ldiff < 0);
|
||||
high -= (hdiff < 0);
|
||||
#endif
|
||||
}
|
||||
template <>
|
||||
inline void prepareThresh<true>(f64 low_thresh, f64 high_thresh,
|
||||
s32 &low, s32 &high)
|
||||
{
|
||||
if (low_thresh > high_thresh)
|
||||
std::swap(low_thresh, high_thresh);
|
||||
if (low_thresh > 0) low_thresh *= low_thresh;
|
||||
if (high_thresh > 0) high_thresh *= high_thresh;
|
||||
#if defined __GNUC__
|
||||
low = (s32)low_thresh;
|
||||
high = (s32)high_thresh;
|
||||
low -= (low > low_thresh);
|
||||
high -= (high > high_thresh);
|
||||
#else
|
||||
low = internal::round(low_thresh);
|
||||
high = internal::round(high_thresh);
|
||||
f32 ldiff = (f32)(low_thresh - low);
|
||||
f32 hdiff = (f32)(high_thresh - high);
|
||||
low -= (ldiff < 0);
|
||||
high -= (hdiff < 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <bool L2gradient, bool externalSobel>
|
||||
struct _normEstimator
|
||||
{
|
||||
ptrdiff_t magstep;
|
||||
ptrdiff_t dxOffset;
|
||||
ptrdiff_t dyOffset;
|
||||
ptrdiff_t shxOffset;
|
||||
ptrdiff_t shyOffset;
|
||||
std::vector<u8> buffer;
|
||||
const ptrdiff_t offsetk;
|
||||
ptrdiff_t borderyt, borderyb;
|
||||
RowFilter3x3Canny sobelRow;
|
||||
|
||||
inline _normEstimator(const Size2D &size, s32, Margin borderMargin,
|
||||
ptrdiff_t &mapstep, s32** mag_buf, u8* &map):
|
||||
offsetk(1),
|
||||
sobelRow(std::max<ptrdiff_t>(0, offsetk - (ptrdiff_t)borderMargin.left),
|
||||
std::max<ptrdiff_t>(0, offsetk - (ptrdiff_t)borderMargin.right))
|
||||
{
|
||||
mapstep = size.width + 2;
|
||||
magstep = size.width + 2 + size.width * (4 * sizeof(s16)/sizeof(s32));
|
||||
dxOffset = mapstep * sizeof(s32)/sizeof(s16);
|
||||
dyOffset = dxOffset + size.width * 1;
|
||||
shxOffset = dxOffset + size.width * 2;
|
||||
shyOffset = dxOffset + size.width * 3;
|
||||
buffer.resize( (size.width+2)*(size.height+2) + magstep*3*sizeof(s32) );
|
||||
mag_buf[0] = (s32*)&buffer[0];
|
||||
mag_buf[1] = mag_buf[0] + magstep;
|
||||
mag_buf[2] = mag_buf[1] + magstep;
|
||||
memset(mag_buf[0], 0, mapstep * sizeof(s32));
|
||||
|
||||
map = (u8*)(mag_buf[2] + magstep);
|
||||
memset(map, 1, mapstep);
|
||||
memset(map + mapstep*(size.height + 1), 1, mapstep);
|
||||
borderyt = std::max<ptrdiff_t>(0, offsetk - (ptrdiff_t)borderMargin.top);
|
||||
borderyb = std::max<ptrdiff_t>(0, offsetk - (ptrdiff_t)borderMargin.bottom);
|
||||
}
|
||||
inline void firstRow(const Size2D &size, s32,
|
||||
const u8 *srcBase, ptrdiff_t srcStride,
|
||||
s16*, ptrdiff_t,
|
||||
s16*, ptrdiff_t,
|
||||
s32** mag_buf)
|
||||
{
|
||||
//sobelH row #0
|
||||
const u8* _src = internal::getRowPtr(srcBase, srcStride, 0);
|
||||
sobelRow(_src, ((s16*)mag_buf[0]) + shxOffset, ((s16*)mag_buf[0]) + shyOffset, size.width);
|
||||
//sobelH row #1
|
||||
_src = internal::getRowPtr(srcBase, srcStride, 1);
|
||||
sobelRow(_src, ((s16*)mag_buf[1]) + shxOffset, ((s16*)mag_buf[1]) + shyOffset, size.width);
|
||||
|
||||
mag_buf[1][0] = mag_buf[1][size.width+1] = 0;
|
||||
if (borderyt == 0)
|
||||
{
|
||||
//sobelH row #-1
|
||||
_src = internal::getRowPtr(srcBase, srcStride, -1);
|
||||
sobelRow(_src, ((s16*)mag_buf[2]) + shxOffset, ((s16*)mag_buf[2]) + shyOffset, size.width);
|
||||
|
||||
ColFilter3x3Canny<L2gradient>( ((s16*)mag_buf[2]) + shxOffset, ((s16*)mag_buf[0]) + shxOffset, ((s16*)mag_buf[1]) + shxOffset,
|
||||
((s16*)mag_buf[1]) + dxOffset, ((s16*)mag_buf[1]) + dyOffset, mag_buf[1] + 1, size.width);
|
||||
}
|
||||
else
|
||||
{
|
||||
ColFilter3x3Canny<L2gradient>( ((s16*)mag_buf[0]) + shxOffset, ((s16*)mag_buf[0]) + shxOffset, ((s16*)mag_buf[1]) + shxOffset,
|
||||
((s16*)mag_buf[1]) + dxOffset, ((s16*)mag_buf[1]) + dyOffset, mag_buf[1] + 1, size.width);
|
||||
}
|
||||
}
|
||||
inline void nextRow(const Size2D &size, s32,
|
||||
const u8 *srcBase, ptrdiff_t srcStride,
|
||||
s16*, ptrdiff_t,
|
||||
s16*, ptrdiff_t,
|
||||
const ptrdiff_t &mapstep, s32** mag_buf,
|
||||
size_t i, const s16* &_x, const s16* &_y)
|
||||
{
|
||||
mag_buf[2][0] = mag_buf[2][size.width+1] = 0;
|
||||
if (i < size.height - borderyb)
|
||||
{
|
||||
const u8* _src = internal::getRowPtr(srcBase, srcStride, i+1);
|
||||
//sobelH row #i+1
|
||||
sobelRow(_src, ((s16*)mag_buf[2]) + shxOffset, ((s16*)mag_buf[2]) + shyOffset, size.width);
|
||||
|
||||
ColFilter3x3Canny<L2gradient>( ((s16*)mag_buf[0]) + shxOffset, ((s16*)mag_buf[1]) + shxOffset, ((s16*)mag_buf[2]) + shxOffset,
|
||||
((s16*)mag_buf[2]) + dxOffset, ((s16*)mag_buf[2]) + dyOffset, mag_buf[2] + 1, size.width);
|
||||
}
|
||||
else if (i < size.height)
|
||||
{
|
||||
ColFilter3x3Canny<L2gradient>( ((s16*)mag_buf[0]) + shxOffset, ((s16*)mag_buf[1]) + shxOffset, ((s16*)mag_buf[1]) + shxOffset,
|
||||
((s16*)mag_buf[2]) + dxOffset, ((s16*)mag_buf[2]) + dyOffset, mag_buf[2] + 1, size.width);
|
||||
}
|
||||
else
|
||||
memset(mag_buf[2], 0, mapstep*sizeof(s32));
|
||||
_x = ((s16*)mag_buf[1]) + dxOffset;
|
||||
_y = ((s16*)mag_buf[1]) + dyOffset;
|
||||
}
|
||||
};
|
||||
template <bool L2gradient>
|
||||
struct _normEstimator<L2gradient, true>
|
||||
{
|
||||
std::vector<u8> buffer;
|
||||
|
||||
inline _normEstimator(const Size2D &size, s32 cn, Margin,
|
||||
ptrdiff_t &mapstep, s32** mag_buf, u8* &map)
|
||||
{
|
||||
mapstep = size.width + 2;
|
||||
buffer.resize( (size.width+2)*(size.height+2) + cn*mapstep*3*sizeof(s32) );
|
||||
mag_buf[0] = (s32*)&buffer[0];
|
||||
mag_buf[1] = mag_buf[0] + mapstep*cn;
|
||||
mag_buf[2] = mag_buf[1] + mapstep*cn;
|
||||
memset(mag_buf[0], 0, /* cn* */mapstep * sizeof(s32));
|
||||
|
||||
map = (u8*)(mag_buf[2] + mapstep*cn);
|
||||
memset(map, 1, mapstep);
|
||||
memset(map + mapstep*(size.height + 1), 1, mapstep);
|
||||
}
|
||||
inline void firstRow(const Size2D &size, s32 cn,
|
||||
const u8 *, ptrdiff_t,
|
||||
s16* dxBase, ptrdiff_t dxStride,
|
||||
s16* dyBase, ptrdiff_t dyStride,
|
||||
s32** mag_buf)
|
||||
{
|
||||
s32* _norm = mag_buf[1] + 1;
|
||||
|
||||
s16* _dx = internal::getRowPtr(dxBase, dxStride, 0);
|
||||
s16* _dy = internal::getRowPtr(dyBase, dyStride, 0);
|
||||
|
||||
NormCanny<L2gradient>(size.width*cn, _dx, _dy, _norm);
|
||||
|
||||
if(cn > 1)
|
||||
{
|
||||
for(size_t j = 0, jn = 0; j < size.width; ++j, jn += cn)
|
||||
{
|
||||
size_t maxIdx = jn;
|
||||
for(s32 k = 1; k < cn; ++k)
|
||||
if(_norm[jn + k] > _norm[maxIdx]) maxIdx = jn + k;
|
||||
_norm[j] = _norm[maxIdx];
|
||||
_dx[j] = _dx[maxIdx];
|
||||
_dy[j] = _dy[maxIdx];
|
||||
}
|
||||
}
|
||||
|
||||
_norm[-1] = _norm[size.width] = 0;
|
||||
}
|
||||
inline void nextRow(const Size2D &size, s32 cn,
|
||||
const u8 *, ptrdiff_t,
|
||||
s16* dxBase, ptrdiff_t dxStride,
|
||||
s16* dyBase, ptrdiff_t dyStride,
|
||||
const ptrdiff_t &mapstep, s32** mag_buf,
|
||||
size_t i, const s16* &_x, const s16* &_y)
|
||||
{
|
||||
s32* _norm = mag_buf[(i > 0) + 1] + 1;
|
||||
if (i < size.height)
|
||||
{
|
||||
s16* _dx = internal::getRowPtr(dxBase, dxStride, i);
|
||||
s16* _dy = internal::getRowPtr(dyBase, dyStride, i);
|
||||
|
||||
NormCanny<L2gradient>(size.width*cn, _dx, _dy, _norm);
|
||||
|
||||
if(cn > 1)
|
||||
{
|
||||
for(size_t j = 0, jn = 0; j < size.width; ++j, jn += cn)
|
||||
{
|
||||
size_t maxIdx = jn;
|
||||
for(s32 k = 1; k < cn; ++k)
|
||||
if(_norm[jn + k] > _norm[maxIdx]) maxIdx = jn + k;
|
||||
_norm[j] = _norm[maxIdx];
|
||||
_dx[j] = _dx[maxIdx];
|
||||
_dy[j] = _dy[maxIdx];
|
||||
}
|
||||
}
|
||||
|
||||
_norm[-1] = _norm[size.width] = 0;
|
||||
}
|
||||
else
|
||||
memset(_norm-1, 0, /* cn* */mapstep*sizeof(s32));
|
||||
|
||||
_x = internal::getRowPtr(dxBase, dxStride, i-1);
|
||||
_y = internal::getRowPtr(dyBase, dyStride, i-1);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool L2gradient, bool externalSobel>
|
||||
inline void Canny3x3(const Size2D &size, s32 cn,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
s16 * dxBase, ptrdiff_t dxStride,
|
||||
s16 * dyBase, ptrdiff_t dyStride,
|
||||
f64 low_thresh, f64 high_thresh,
|
||||
Margin borderMargin)
|
||||
{
|
||||
s32 low, high;
|
||||
prepareThresh<L2gradient>(low_thresh, high_thresh, low, high);
|
||||
|
||||
ptrdiff_t mapstep;
|
||||
s32* mag_buf[3];
|
||||
u8* map;
|
||||
_normEstimator<L2gradient, externalSobel> normEstimator(size, cn, borderMargin, mapstep, mag_buf, map);
|
||||
|
||||
size_t maxsize = std::max<size_t>( 1u << 10, size.width * size.height / 10 );
|
||||
std::vector<u8*> stack( maxsize );
|
||||
u8 **stack_top = &stack[0];
|
||||
u8 **stack_bottom = &stack[0];
|
||||
|
||||
/* sector numbers
|
||||
(Top-Left Origin)
|
||||
|
||||
1 2 3
|
||||
* * *
|
||||
* * *
|
||||
0*******0
|
||||
* * *
|
||||
* * *
|
||||
3 2 1
|
||||
*/
|
||||
|
||||
#define CANNY_PUSH(d) *(d) = u8(2), *stack_top++ = (d)
|
||||
#define CANNY_POP(d) (d) = *--stack_top
|
||||
|
||||
//i == 0
|
||||
normEstimator.firstRow(size, cn, srcBase, srcStride, dxBase, dxStride, dyBase, dyStride, mag_buf);
|
||||
// calculate magnitude and angle of gradient, perform non-maxima supression.
|
||||
// fill the map with one of the following values:
|
||||
// 0 - the pixel might belong to an edge
|
||||
// 1 - the pixel can not belong to an edge
|
||||
// 2 - the pixel does belong to an edge
|
||||
for (size_t i = 1; i <= size.height; i++)
|
||||
{
|
||||
const s16 *_x, *_y;
|
||||
normEstimator.nextRow(size, cn, srcBase, srcStride, dxBase, dxStride, dyBase, dyStride, mapstep, mag_buf, i, _x, _y);
|
||||
|
||||
u8* _map = map + mapstep*i + 1;
|
||||
_map[-1] = _map[size.width] = 1;
|
||||
|
||||
s32* _mag = mag_buf[1] + 1; // take the central row
|
||||
ptrdiff_t magstep1 = mag_buf[2] - mag_buf[1];
|
||||
ptrdiff_t magstep2 = mag_buf[0] - mag_buf[1];
|
||||
|
||||
if ((stack_top - stack_bottom) + size.width > maxsize)
|
||||
{
|
||||
ptrdiff_t sz = (ptrdiff_t)(stack_top - stack_bottom);
|
||||
maxsize = maxsize * 3/2;
|
||||
stack.resize(maxsize);
|
||||
stack_bottom = &stack[0];
|
||||
stack_top = stack_bottom + sz;
|
||||
}
|
||||
|
||||
s32 prev_flag = 0;
|
||||
for (ptrdiff_t j = 0; j < (ptrdiff_t)size.width; j++)
|
||||
{
|
||||
#define CANNY_SHIFT 15
|
||||
const s32 TG22 = (s32)(0.4142135623730950488016887242097*(1<<CANNY_SHIFT) + 0.5);
|
||||
|
||||
s32 m = _mag[j];
|
||||
|
||||
if (m > low)
|
||||
{
|
||||
s32 xs = _x[j];
|
||||
s32 ys = _y[j];
|
||||
s32 x = abs(xs);
|
||||
s32 y = abs(ys) << CANNY_SHIFT;
|
||||
|
||||
s32 tg22x = x * TG22;
|
||||
|
||||
if (y < tg22x)
|
||||
{
|
||||
if (m > _mag[j-1] && m >= _mag[j+1]) goto __push;
|
||||
}
|
||||
else
|
||||
{
|
||||
s32 tg67x = tg22x + (x << (CANNY_SHIFT+1));
|
||||
if (y > tg67x)
|
||||
{
|
||||
if (m > _mag[j+magstep2] && m >= _mag[j+magstep1]) goto __push;
|
||||
}
|
||||
else
|
||||
{
|
||||
s32 s = (xs ^ ys) < 0 ? -1 : 1;
|
||||
if(m > _mag[j+magstep2-s] && m > _mag[j+magstep1+s]) goto __push;
|
||||
}
|
||||
}
|
||||
}
|
||||
prev_flag = 0;
|
||||
_map[j] = u8(1);
|
||||
continue;
|
||||
__push:
|
||||
if (!prev_flag && m > high && _map[j-mapstep] != 2)
|
||||
{
|
||||
CANNY_PUSH(_map + j);
|
||||
prev_flag = 1;
|
||||
}
|
||||
else
|
||||
_map[j] = 0;
|
||||
}
|
||||
|
||||
// scroll the ring buffer
|
||||
_mag = mag_buf[0];
|
||||
mag_buf[0] = mag_buf[1];
|
||||
mag_buf[1] = mag_buf[2];
|
||||
mag_buf[2] = _mag;
|
||||
}
|
||||
|
||||
// now track the edges (hysteresis thresholding)
|
||||
while (stack_top > stack_bottom)
|
||||
{
|
||||
u8* m;
|
||||
if ((size_t)(stack_top - stack_bottom) + 8u > maxsize)
|
||||
{
|
||||
ptrdiff_t sz = (ptrdiff_t)(stack_top - stack_bottom);
|
||||
maxsize = maxsize * 3/2;
|
||||
stack.resize(maxsize);
|
||||
stack_bottom = &stack[0];
|
||||
stack_top = stack_bottom + sz;
|
||||
}
|
||||
|
||||
CANNY_POP(m);
|
||||
|
||||
if (!m[-1]) CANNY_PUSH(m - 1);
|
||||
if (!m[1]) CANNY_PUSH(m + 1);
|
||||
if (!m[-mapstep-1]) CANNY_PUSH(m - mapstep - 1);
|
||||
if (!m[-mapstep]) CANNY_PUSH(m - mapstep);
|
||||
if (!m[-mapstep+1]) CANNY_PUSH(m - mapstep + 1);
|
||||
if (!m[mapstep-1]) CANNY_PUSH(m + mapstep - 1);
|
||||
if (!m[mapstep]) CANNY_PUSH(m + mapstep);
|
||||
if (!m[mapstep+1]) CANNY_PUSH(m + mapstep + 1);
|
||||
}
|
||||
|
||||
// the final pass, form the final image
|
||||
uint8x16_t v2 = vmovq_n_u8(2);
|
||||
const u8* ptrmap = map + mapstep + 1;
|
||||
for (size_t i = 0; i < size.height; i++, ptrmap += mapstep)
|
||||
{
|
||||
u8* _dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
ptrdiff_t j = 0;
|
||||
for (; j < (ptrdiff_t)size.width - 16; j += 16)
|
||||
{
|
||||
internal::prefetch(ptrmap);
|
||||
uint8x16_t vmap = vld1q_u8(ptrmap + j);
|
||||
uint8x16_t vdst = vceqq_u8(vmap, v2);
|
||||
vst1q_u8(_dst+j, vdst);
|
||||
}
|
||||
for (; j < (ptrdiff_t)size.width; j++)
|
||||
_dst[j] = (u8)-(ptrmap[j] >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
bool isCanny3x3Supported(const Size2D &size)
|
||||
{
|
||||
return isSupportedConfiguration() &&
|
||||
size.height >= 2 && size.width >= 9;
|
||||
}
|
||||
|
||||
void Canny3x3L1(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
f64 low_thresh, f64 high_thresh,
|
||||
Margin borderMargin)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isCanny3x3Supported(size));
|
||||
#ifdef CAROTENE_NEON
|
||||
Canny3x3<false, false>(size, 1,
|
||||
srcBase, srcStride,
|
||||
dstBase, dstStride,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
low_thresh, high_thresh,
|
||||
borderMargin);
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)low_thresh;
|
||||
(void)high_thresh;
|
||||
(void)borderMargin;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Canny3x3L2(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
f64 low_thresh, f64 high_thresh,
|
||||
Margin borderMargin)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isCanny3x3Supported(size));
|
||||
#ifdef CAROTENE_NEON
|
||||
Canny3x3<true, false>(size, 1,
|
||||
srcBase, srcStride,
|
||||
dstBase, dstStride,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
low_thresh, high_thresh,
|
||||
borderMargin);
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)low_thresh;
|
||||
(void)high_thresh;
|
||||
(void)borderMargin;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Canny3x3L1(const Size2D &size, s32 cn,
|
||||
s16 * dxBase, ptrdiff_t dxStride,
|
||||
s16 * dyBase, ptrdiff_t dyStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
f64 low_thresh, f64 high_thresh)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
Canny3x3<false, true>(size, cn,
|
||||
NULL, 0,
|
||||
dstBase, dstStride,
|
||||
dxBase, dxStride,
|
||||
dyBase, dyStride,
|
||||
low_thresh, high_thresh,
|
||||
Margin());
|
||||
#else
|
||||
(void)size;
|
||||
(void)cn;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)dxBase;
|
||||
(void)dxStride;
|
||||
(void)dyBase;
|
||||
(void)dyStride;
|
||||
(void)low_thresh;
|
||||
(void)high_thresh;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Canny3x3L2(const Size2D &size, s32 cn,
|
||||
s16 * dxBase, ptrdiff_t dxStride,
|
||||
s16 * dyBase, ptrdiff_t dyStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
f64 low_thresh, f64 high_thresh)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
Canny3x3<true, true>(size, cn,
|
||||
NULL, 0,
|
||||
dstBase, dstStride,
|
||||
dxBase, dxStride,
|
||||
dyBase, dyStride,
|
||||
low_thresh, high_thresh,
|
||||
Margin());
|
||||
#else
|
||||
(void)size;
|
||||
(void)cn;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)dxBase;
|
||||
(void)dxStride;
|
||||
(void)dyBase;
|
||||
(void)dyStride;
|
||||
(void)low_thresh;
|
||||
(void)high_thresh;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
+486
@@ -0,0 +1,486 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "vtransform.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
void extract2(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
u32 coi)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
#ifndef ANDROID
|
||||
size_t roiw32 = size.width >= 31 ? size.width - 31 : 0;
|
||||
#endif
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0u; i < size.height; ++i)
|
||||
{
|
||||
const u8 * src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
u8 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t sj = 0u, dj = 0u;
|
||||
|
||||
#ifndef ANDROID
|
||||
for (; dj < roiw32; sj += 64, dj += 32)
|
||||
{
|
||||
internal::prefetch(src + sj);
|
||||
|
||||
uint8x16x2_t v_src = vld2q_u8(src + sj);
|
||||
vst1q_u8(dst + dj, v_src.val[coi]);
|
||||
|
||||
v_src = vld2q_u8(src + sj + 32);
|
||||
vst1q_u8(dst + dj + 16, v_src.val[coi]);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; dj < roiw8; sj += 16, dj += 8)
|
||||
{
|
||||
uint8x8x2_t v_src = vld2_u8(src + sj);
|
||||
vst1_u8(dst + dj, v_src.val[coi]);
|
||||
}
|
||||
|
||||
for (; dj < size.width; sj += 2, ++dj)
|
||||
{
|
||||
dst[dj] = src[sj + coi];
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)coi;
|
||||
#endif
|
||||
}
|
||||
|
||||
void extract3(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
u32 coi)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
#ifndef ANDROID
|
||||
size_t roiw32 = size.width >= 31 ? size.width - 31 : 0;
|
||||
#endif
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0u; i < size.height; ++i)
|
||||
{
|
||||
const u8 * src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
u8 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t sj = 0u, dj = 0u;
|
||||
|
||||
#ifndef ANDROID
|
||||
for (; dj < roiw32; sj += 96, dj += 32)
|
||||
{
|
||||
internal::prefetch(src + sj);
|
||||
|
||||
uint8x16x3_t v_src = vld3q_u8(src + sj);
|
||||
vst1q_u8(dst + dj, v_src.val[coi]);
|
||||
|
||||
v_src = vld3q_u8(src + sj + 48);
|
||||
vst1q_u8(dst + dj + 16, v_src.val[coi]);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; dj < roiw8; sj += 24, dj += 8)
|
||||
{
|
||||
uint8x8x3_t v_src = vld3_u8(src + sj);
|
||||
vst1_u8(dst + dj, v_src.val[coi]);
|
||||
}
|
||||
|
||||
for (; dj < size.width; sj += 3, ++dj)
|
||||
{
|
||||
dst[dj] = src[sj + coi];
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)coi;
|
||||
#endif
|
||||
}
|
||||
|
||||
void extract4(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
u32 coi)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
#ifndef ANDROID
|
||||
size_t roiw32 = size.width >= 31 ? size.width - 31 : 0;
|
||||
#endif
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0u; i < size.height; ++i)
|
||||
{
|
||||
const u8 * src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
u8 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t sj = 0u, dj = 0u;
|
||||
|
||||
#ifndef ANDROID
|
||||
for (; dj < roiw32; sj += 128, dj += 32)
|
||||
{
|
||||
internal::prefetch(src + sj);
|
||||
|
||||
uint8x16x4_t v_src = vld4q_u8(src + sj);
|
||||
vst1q_u8(dst + dj, v_src.val[coi]);
|
||||
|
||||
v_src = vld4q_u8(src + sj + 64);
|
||||
vst1q_u8(dst + dj + 16, v_src.val[coi]);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; dj < roiw8; sj += 32, dj += 8)
|
||||
{
|
||||
uint8x8x4_t v_src = vld4_u8(src + sj);
|
||||
vst1_u8(dst + dj, v_src.val[coi]);
|
||||
}
|
||||
|
||||
for (; dj < size.width; sj += 4, ++dj)
|
||||
{
|
||||
dst[dj] = src[sj + coi];
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)coi;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define FILL_LINES2(macro,type) \
|
||||
macro##_LINE(type,0) \
|
||||
macro##_LINE(type,1)
|
||||
#define FILL_LINES3(macro,type) \
|
||||
FILL_LINES2(macro,type) \
|
||||
macro##_LINE(type,2)
|
||||
#define FILL_LINES4(macro,type) \
|
||||
FILL_LINES3(macro,type) \
|
||||
macro##_LINE(type,3)
|
||||
|
||||
#define FARG_LINE(type, n) , type * dst##n##Base, ptrdiff_t dst##n##Stride
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
#define VROW_LINE(type, n) type * dst##n = internal::getRowPtr(dst##n##Base, dst##n##Stride, i);
|
||||
#define VST1Q_LINE(type, n) vst1q_##type(dst##n + dj, v_src.val[n]);
|
||||
#define VST1_LINE(type, n) vst1_##type(dst##n + dj, v_src.val[n]);
|
||||
#define SST_LINE(type, n) dst##n[dj] = src[sj + n];
|
||||
|
||||
#define MUL2(val) (val << 1)
|
||||
#define MUL3(val) (MUL2(val) + val)
|
||||
#define MUL4(val) (val << 2)
|
||||
|
||||
#define CONTDST2 srcStride == dst0Stride && \
|
||||
srcStride == dst1Stride &&
|
||||
#define CONTDST3 srcStride == dst0Stride && \
|
||||
srcStride == dst1Stride && \
|
||||
srcStride == dst2Stride &&
|
||||
#define CONTDST4 srcStride == dst0Stride && \
|
||||
srcStride == dst1Stride && \
|
||||
srcStride == dst2Stride && \
|
||||
srcStride == dst3Stride &&
|
||||
|
||||
#if __GNUC__ == 4 && __GNUC_MINOR__ < 7
|
||||
|
||||
#define SPLIT_ASM2(sgn, bits) __asm__ ( \
|
||||
"vld2." #bits " {d0, d2}, [%[in0]] \n\t" \
|
||||
"vld2." #bits " {d1, d3}, [%[in1]] \n\t" \
|
||||
"vst1." #bits " {d0-d1}, [%[out0]] \n\t" \
|
||||
"vst1." #bits " {d2-d3}, [%[out1]] \n\t" \
|
||||
: \
|
||||
: [out0] "r" (dst0 + dj), [out1] "r" (dst1 + dj), \
|
||||
[in0] "r" (src + sj), [in1] "r" (src + sj + MUL2(8)/sizeof(sgn##bits)) \
|
||||
: "d0","d1","d2","d3" \
|
||||
);
|
||||
#define SPLIT_ASM3(sgn, bits) __asm__ ( \
|
||||
"vld3." #bits " {d0, d2, d4}, [%[in0]] \n\t" \
|
||||
"vld3." #bits " {d1, d3, d5}, [%[in1]] \n\t" \
|
||||
"vst1." #bits " {d0-d1}, [%[out0]] \n\t" \
|
||||
"vst1." #bits " {d2-d3}, [%[out1]] \n\t" \
|
||||
"vst1." #bits " {d4-d5}, [%[out2]] \n\t" \
|
||||
: \
|
||||
: [out0] "r" (dst0 + dj), [out1] "r" (dst1 + dj), [out2] "r" (dst2 + dj), \
|
||||
[in0] "r" (src + sj), [in1] "r" (src + sj + MUL3(8)/sizeof(sgn##bits)) \
|
||||
: "d0","d1","d2","d3","d4","d5" \
|
||||
);
|
||||
#define SPLIT_ASM4(sgn, bits) __asm__ ( \
|
||||
"vld4." #bits " {d0, d2, d4, d6}, [%[in0]] \n\t" \
|
||||
"vld4." #bits " {d1, d3, d5, d7}, [%[in1]] \n\t" \
|
||||
"vst1." #bits " {d0-d1}, [%[out0]] \n\t" \
|
||||
"vst1." #bits " {d2-d3}, [%[out1]] \n\t" \
|
||||
"vst1." #bits " {d4-d5}, [%[out2]] \n\t" \
|
||||
"vst1." #bits " {d6-d7}, [%[out3]] \n\t" \
|
||||
: \
|
||||
: [out0] "r" (dst0 + dj), [out1] "r" (dst1 + dj), [out2] "r" (dst2 + dj), [out3] "r" (dst3 + dj), \
|
||||
[in0] "r" (src + sj), [in1] "r" (src + sj + MUL4(8)/sizeof(sgn##bits)) \
|
||||
: "d0","d1","d2","d3","d4","d5","d6","d7" \
|
||||
);
|
||||
|
||||
#define SPLIT_QUAD(sgn, bits, n) { \
|
||||
internal::prefetch(src + sj); \
|
||||
SPLIT_ASM##n(sgn, bits) \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define SPLIT_QUAD(sgn, bits, n) { \
|
||||
internal::prefetch(src + sj); \
|
||||
vec128 v_src = vld##n##q_##sgn##bits(src + sj); \
|
||||
FILL_LINES##n(VST1Q, sgn##bits) \
|
||||
}
|
||||
|
||||
#endif // __GNUC__ == 4 && __GNUC_MINOR__ < 7
|
||||
|
||||
#define SPLIT(sgn,bits,n) void split##n(const Size2D &_size, \
|
||||
const sgn##bits * srcBase, ptrdiff_t srcStride \
|
||||
FILL_LINES##n(FARG, sgn##bits) ) \
|
||||
{ \
|
||||
internal::assertSupportedConfiguration(); \
|
||||
Size2D size(_size); \
|
||||
if (CONTDST##n \
|
||||
dst0Stride == (ptrdiff_t)(size.width)) \
|
||||
{ \
|
||||
size.width *= size.height; \
|
||||
size.height = 1; \
|
||||
} \
|
||||
typedef internal::VecTraits<sgn##bits, n>::vec128 vec128; \
|
||||
size_t roiw16 = size.width >= (16/sizeof(sgn##bits)-1) ? size.width - (16/sizeof(sgn##bits)-1) : 0; \
|
||||
typedef internal::VecTraits<sgn##bits, n>::vec64 vec64; \
|
||||
size_t roiw8 = size.width >= (8/sizeof(sgn##bits)-1) ? size.width - (8/sizeof(sgn##bits)-1) : 0; \
|
||||
\
|
||||
for (size_t i = 0u; i < size.height; ++i) \
|
||||
{ \
|
||||
const sgn##bits * src = internal::getRowPtr(srcBase, srcStride, i); \
|
||||
FILL_LINES##n(VROW, sgn##bits) \
|
||||
size_t sj = 0u, dj = 0u; \
|
||||
\
|
||||
for (; dj < roiw16; sj += MUL##n(16)/sizeof(sgn##bits), dj += 16/sizeof(sgn##bits)) \
|
||||
SPLIT_QUAD(sgn, bits, n) \
|
||||
\
|
||||
if (dj < roiw8) \
|
||||
{ \
|
||||
vec64 v_src = vld##n##_##sgn##bits(src + sj); \
|
||||
FILL_LINES##n(VST1, sgn##bits) \
|
||||
sj += MUL##n(8)/sizeof(sgn##bits); \
|
||||
dj += 8/sizeof(sgn##bits); \
|
||||
} \
|
||||
\
|
||||
for (; dj < size.width; sj += n, ++dj) \
|
||||
{ \
|
||||
FILL_LINES##n(SST, sgn##bits) \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SPLIT64(sgn,n) void split##n(const Size2D &_size, \
|
||||
const sgn##64 * srcBase, ptrdiff_t srcStride \
|
||||
FILL_LINES##n(FARG, sgn##64) ) \
|
||||
{ \
|
||||
internal::assertSupportedConfiguration(); \
|
||||
Size2D size(_size); \
|
||||
if (CONTDST##n \
|
||||
dst0Stride == (ptrdiff_t)(size.width)) \
|
||||
{ \
|
||||
size.width *= size.height; \
|
||||
size.height = 1; \
|
||||
} \
|
||||
typedef internal::VecTraits<sgn##64, n>::vec64 vec64; \
|
||||
\
|
||||
for (size_t i = 0u; i < size.height; ++i) \
|
||||
{ \
|
||||
const sgn##64 * src = internal::getRowPtr(srcBase, srcStride, i); \
|
||||
FILL_LINES##n(VROW, sgn##64) \
|
||||
size_t sj = 0u, dj = 0u; \
|
||||
\
|
||||
for (; dj < size.width; sj += n, ++dj) \
|
||||
{ \
|
||||
vec64 v_src = vld##n##_##sgn##64(src + sj); \
|
||||
FILL_LINES##n(VST1, sgn##64) \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#if __GNUC__ == 4 && __GNUC_MINOR__ < 7
|
||||
|
||||
#define ALPHA_QUAD(sgn, bits) { \
|
||||
internal::prefetch(src + sj); \
|
||||
__asm__ ( \
|
||||
"vld4." #bits " {d0, d2, d4, d6}, [%[in0]] \n\t" \
|
||||
"vld4." #bits " {d1, d3, d5, d7}, [%[in1]] \n\t" \
|
||||
"vst3." #bits " {d0, d2, d4}, [%[out3_1]] \n\t" \
|
||||
"vst3." #bits " {d1, d3, d5}, [%[out3_2]] \n\t" \
|
||||
"vst1." #bits " {d6-d7}, [%[out1]] \n\t" \
|
||||
: \
|
||||
: [out3_1] "r" (dst3 + d3j), [out3_2] "r" (dst3 + d3j + 24/sizeof(sgn##bits)), [out1] "r" (dst1 + d1j), \
|
||||
[in0] "r" (src + sj), [in1] "r" (src + sj + 32/sizeof(sgn##bits)) \
|
||||
: "d0","d1","d2","d3","d4","d5","d6","d7" \
|
||||
); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define ALPHA_QUAD(sgn, bits) { \
|
||||
internal::prefetch(src + sj); \
|
||||
union { vec128_4 v4; vec128_3 v3; } vals; \
|
||||
vals.v4 = vld4q_##sgn##bits(src + sj); \
|
||||
vst3q_##sgn##bits(dst3 + d3j, vals.v3); \
|
||||
vst1q_##sgn##bits(dst1 + d1j, vals.v4.val[3]); \
|
||||
}
|
||||
|
||||
#endif // __GNUC__ == 4 && __GNUC_MINOR__ < 7
|
||||
|
||||
#define SPLIT4ALPHA(sgn,bits) void split4(const Size2D &_size, \
|
||||
const sgn##bits * srcBase, ptrdiff_t srcStride, \
|
||||
sgn##bits * dst3Base, ptrdiff_t dst3Stride, \
|
||||
sgn##bits * dst1Base, ptrdiff_t dst1Stride) \
|
||||
{ \
|
||||
internal::assertSupportedConfiguration(); \
|
||||
Size2D size(_size); \
|
||||
if (srcStride == dst3Stride && \
|
||||
srcStride == dst1Stride && \
|
||||
srcStride == (ptrdiff_t)(size.width)) \
|
||||
{ \
|
||||
size.width *= size.height; \
|
||||
size.height = 1; \
|
||||
} \
|
||||
typedef internal::VecTraits<sgn##bits, 4>::vec128 vec128_4; \
|
||||
typedef internal::VecTraits<sgn##bits, 3>::vec128 vec128_3; \
|
||||
size_t roiw16 = size.width >= (16/sizeof(sgn##bits)-1) ? size.width - (16/sizeof(sgn##bits)-1) : 0; \
|
||||
typedef internal::VecTraits<sgn##bits, 4>::vec64 vec64_4; \
|
||||
typedef internal::VecTraits<sgn##bits, 3>::vec64 vec64_3; \
|
||||
size_t roiw8 = size.width >= (8/sizeof(sgn##bits)-1) ? size.width - (8/sizeof(sgn##bits)-1) : 0; \
|
||||
\
|
||||
for (size_t i = 0u; i < size.height; ++i) \
|
||||
{ \
|
||||
const sgn##bits * src = internal::getRowPtr(srcBase, srcStride, i); \
|
||||
sgn##bits * dst3 = internal::getRowPtr(dst3Base, dst3Stride, i); \
|
||||
sgn##bits * dst1 = internal::getRowPtr(dst1Base, dst1Stride, i); \
|
||||
size_t sj = 0u, d3j = 0u, d1j = 0u; \
|
||||
\
|
||||
for (; d1j < roiw16; sj += MUL4(16)/sizeof(sgn##bits), d3j += MUL3(16)/sizeof(sgn##bits), \
|
||||
d1j += 16/sizeof(sgn##bits)) \
|
||||
ALPHA_QUAD(sgn, bits) \
|
||||
\
|
||||
if (d1j < roiw8) \
|
||||
{ \
|
||||
union { vec64_4 v4; vec64_3 v3; } vals; \
|
||||
vals.v4 = vld4_##sgn##bits(src + sj); \
|
||||
vst3_u8(dst3 + d3j, vals.v3); \
|
||||
vst1_u8(dst1 + d1j, vals.v4.val[3]); \
|
||||
sj += MUL4(8)/sizeof(sgn##bits); \
|
||||
d3j += MUL3(8)/sizeof(sgn##bits); \
|
||||
d1j += 8/sizeof(sgn##bits); \
|
||||
} \
|
||||
\
|
||||
for (; d1j < size.width; sj += 4, d3j += 3, ++d1j) \
|
||||
{ \
|
||||
dst3[d3j+0] = src[sj + 0]; \
|
||||
dst3[d3j+1] = src[sj + 1]; \
|
||||
dst3[d3j+2] = src[sj + 2]; \
|
||||
dst1[d1j] = src[sj + 3]; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define VOID_LINE(type, n) (void)dst##n##Base; (void)dst##n##Stride;
|
||||
|
||||
#define SPLIT(sgn,bits,n) void split##n(const Size2D &size, \
|
||||
const sgn##bits * srcBase, ptrdiff_t srcStride \
|
||||
FILL_LINES##n(FARG, sgn##bits) ) \
|
||||
{ \
|
||||
internal::assertSupportedConfiguration(); \
|
||||
(void)size; \
|
||||
(void)srcBase; \
|
||||
(void)srcStride; \
|
||||
FILL_LINES##n(VOID, sgn##bits) \
|
||||
}
|
||||
|
||||
#define SPLIT64(sgn,n) SPLIT(sgn,64,n)
|
||||
|
||||
#define SPLIT4ALPHA(sgn,bits) void split4(const Size2D &size, \
|
||||
const sgn##bits * srcBase, ptrdiff_t srcStride, \
|
||||
sgn##bits * dst3Base, ptrdiff_t dst3Stride, \
|
||||
sgn##bits * dst1Base, ptrdiff_t dst1Stride) \
|
||||
{ \
|
||||
internal::assertSupportedConfiguration(); \
|
||||
(void)size; \
|
||||
(void)srcBase; \
|
||||
(void)srcStride; \
|
||||
(void)dst3Base; \
|
||||
(void)dst3Stride; \
|
||||
(void)dst1Base; \
|
||||
(void)dst1Stride; \
|
||||
}
|
||||
|
||||
#endif //CAROTENE_NEON
|
||||
|
||||
SPLIT(u, 8,2)
|
||||
SPLIT(u, 8,3)
|
||||
SPLIT(u, 8,4)
|
||||
SPLIT(u,16,2)
|
||||
SPLIT(u,16,3)
|
||||
SPLIT(u,16,4)
|
||||
SPLIT(s,32,2)
|
||||
SPLIT(s,32,3)
|
||||
SPLIT(s,32,4)
|
||||
|
||||
SPLIT64(s, 2)
|
||||
SPLIT64(s, 3)
|
||||
SPLIT64(s, 4)
|
||||
|
||||
SPLIT4ALPHA(u,8)
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
+389
@@ -0,0 +1,389 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "vtransform.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#define FILL_LINES2(macro,type) \
|
||||
macro##_LINE(type,0) \
|
||||
macro##_LINE(type,1)
|
||||
#define FILL_LINES3(macro,type) \
|
||||
FILL_LINES2(macro,type) \
|
||||
macro##_LINE(type,2)
|
||||
#define FILL_LINES4(macro,type) \
|
||||
FILL_LINES3(macro,type) \
|
||||
macro##_LINE(type,3)
|
||||
|
||||
#define FARG_LINE(type, n) , const type * src##n##Base, ptrdiff_t src##n##Stride
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
#define VROW_LINE(type, n) const type * src##n = internal::getRowPtr(src##n##Base, src##n##Stride, i);
|
||||
#define PREF_LINE(type, n) internal::prefetch(src##n + sj);
|
||||
#define VLD1Q_LINE(type, n) v_dst.val[n] = vld1q_##type(src##n + sj);
|
||||
#define PRLD_LINE(type, n) internal::prefetch(src##n + sj); v_dst.val[n] = vld1q_##type(src##n + sj);
|
||||
#define VLD1_LINE(type, n) v_dst.val[n] = vld1_##type(src##n + sj);
|
||||
#define SLD_LINE(type, n) dst[dj + n] = src##n[sj];
|
||||
|
||||
#define MUL2(val) (val << 1)
|
||||
#define MUL3(val) (MUL2(val) + val)
|
||||
#define MUL4(val) (val << 2)
|
||||
|
||||
#define CONTSRC2 dstStride == src0Stride && \
|
||||
dstStride == src1Stride &&
|
||||
#define CONTSRC3 dstStride == src0Stride && \
|
||||
dstStride == src1Stride && \
|
||||
dstStride == src2Stride &&
|
||||
#define CONTSRC4 dstStride == src0Stride && \
|
||||
dstStride == src1Stride && \
|
||||
dstStride == src2Stride && \
|
||||
dstStride == src3Stride &&
|
||||
|
||||
#if __GNUC__ == 4 && __GNUC_MINOR__ < 7
|
||||
|
||||
#define MERGE_ASM2(sgn, bits) __asm__ ( \
|
||||
"vld1." #bits " {d0-d1}, [%[in0]] \n\t" \
|
||||
"vld1." #bits " {d2-d3}, [%[in1]] \n\t" \
|
||||
"vst2." #bits " {d0, d2}, [%[out0]] \n\t" \
|
||||
"vst2." #bits " {d1, d3}, [%[out1]] \n\t" \
|
||||
: \
|
||||
: [in0] "r" (src0 + sj), [in1] "r" (src1 + sj), \
|
||||
[out0] "r" (dst + dj), [out1] "r" (dst + dj + MUL2(8)/sizeof(sgn##bits)) \
|
||||
: "d0","d1","d2","d3" \
|
||||
);
|
||||
#define MERGE_ASM3(sgn, bits) __asm__ ( \
|
||||
"vld1." #bits " {d0-d1}, [%[in0]] \n\t" \
|
||||
"vld1." #bits " {d2-d3}, [%[in1]] \n\t" \
|
||||
"vld1." #bits " {d4-d5}, [%[in2]] \n\t" \
|
||||
"vst3." #bits " {d0, d2, d4}, [%[out0]] \n\t" \
|
||||
"vst3." #bits " {d1, d3, d5}, [%[out1]] \n\t" \
|
||||
: \
|
||||
: [in0] "r" (src0 + sj), [in1] "r" (src1 + sj), [in2] "r" (src2 + sj), \
|
||||
[out0] "r" (dst + dj), [out1] "r" (dst + dj + MUL3(8)/sizeof(sgn##bits)) \
|
||||
: "d0","d1","d2","d3","d4","d5" \
|
||||
);
|
||||
#define MERGE_ASM4(sgn, bits) __asm__ ( \
|
||||
"vld1." #bits " {d0-d1}, [%[in0]] \n\t" \
|
||||
"vld1." #bits " {d2-d3}, [%[in1]] \n\t" \
|
||||
"vld1." #bits " {d4-d5}, [%[in2]] \n\t" \
|
||||
"vld1." #bits " {d6-d7}, [%[in3]] \n\t" \
|
||||
"vst4." #bits " {d0, d2, d4, d6}, [%[out0]] \n\t" \
|
||||
"vst4." #bits " {d1, d3, d5, d7}, [%[out1]] \n\t" \
|
||||
: \
|
||||
: [in0] "r" (src0 + sj), [in1] "r" (src1 + sj), [in2] "r" (src2 + sj), [in3] "r" (src3 + sj), \
|
||||
[out0] "r" (dst + dj), [out1] "r" (dst + dj + MUL4(8)/sizeof(sgn##bits)) \
|
||||
: "d0","d1","d2","d3","d4","d5","d6","d7" \
|
||||
);
|
||||
|
||||
#define MERGE_QUAD(sgn, bits, n) { \
|
||||
FILL_LINES##n(PREF, sgn##bits) \
|
||||
MERGE_ASM##n(sgn, bits) \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define MERGE_QUAD(sgn, bits, n) { \
|
||||
vec128 v_dst; \
|
||||
/*FILL_LINES##n(PREF, sgn##bits) \
|
||||
FILL_LINES##n(VLD1Q, sgn##bits)*/ \
|
||||
FILL_LINES##n(PRLD, sgn##bits) \
|
||||
vst##n##q_##sgn##bits(dst + dj, v_dst); \
|
||||
}
|
||||
|
||||
#endif // __GNUC__ == 4 && __GNUC_MINOR__ < 7
|
||||
|
||||
#define COMBINE(sgn,bits,n) void combine##n(const Size2D &_size \
|
||||
FILL_LINES##n(FARG, sgn##bits), \
|
||||
sgn##bits * dstBase, ptrdiff_t dstStride) \
|
||||
{ \
|
||||
internal::assertSupportedConfiguration(); \
|
||||
Size2D size(_size); \
|
||||
if (CONTSRC##n \
|
||||
dstStride == (ptrdiff_t)(size.width)) \
|
||||
{ \
|
||||
size.width *= size.height; \
|
||||
size.height = 1; \
|
||||
} \
|
||||
typedef internal::VecTraits<sgn##bits, n>::vec128 vec128; \
|
||||
size_t roiw16 = size.width >= (16/sizeof(sgn##bits) - 1) ? size.width - (16/sizeof(sgn##bits) - 1) : 0; \
|
||||
typedef internal::VecTraits<sgn##bits, n>::vec64 vec64; \
|
||||
size_t roiw8 = size.width >= (8/sizeof(sgn##bits) - 1) ? size.width - (8/sizeof(sgn##bits) - 1) : 0; \
|
||||
\
|
||||
for (size_t i = 0u; i < size.height; ++i) \
|
||||
{ \
|
||||
FILL_LINES##n(VROW, sgn##bits) \
|
||||
sgn##bits * dst = internal::getRowPtr(dstBase, dstStride, i); \
|
||||
size_t sj = 0u, dj = 0u; \
|
||||
\
|
||||
for (; sj < roiw16; sj += 16/sizeof(sgn##bits), dj += MUL##n(16)/sizeof(sgn##bits)) \
|
||||
MERGE_QUAD(sgn, bits, n) \
|
||||
\
|
||||
if ( sj < roiw8 ) \
|
||||
{ \
|
||||
vec64 v_dst; \
|
||||
FILL_LINES##n(VLD1, sgn##bits) \
|
||||
vst##n##_##sgn##bits(dst + dj, v_dst); \
|
||||
sj += 8/sizeof(sgn##bits); dj += MUL##n(8)/sizeof(sgn##bits); \
|
||||
} \
|
||||
\
|
||||
for (; sj < size.width; ++sj, dj += n) \
|
||||
{ \
|
||||
FILL_LINES##n(SLD, sgn##bits) \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define COMBINE64(sgn,n) void combine##n(const Size2D &_size \
|
||||
FILL_LINES##n(FARG, sgn##64), \
|
||||
sgn##64 * dstBase, ptrdiff_t dstStride) \
|
||||
{ \
|
||||
internal::assertSupportedConfiguration(); \
|
||||
Size2D size(_size); \
|
||||
if (CONTSRC##n \
|
||||
dstStride == (ptrdiff_t)(size.width)) \
|
||||
{ \
|
||||
size.width *= size.height; \
|
||||
size.height = 1; \
|
||||
} \
|
||||
typedef internal::VecTraits<sgn##64, n>::vec64 vec64; \
|
||||
\
|
||||
for (size_t i = 0u; i < size.height; ++i) \
|
||||
{ \
|
||||
FILL_LINES##n(VROW, sgn##64) \
|
||||
sgn##64 * dst = internal::getRowPtr(dstBase, dstStride, i); \
|
||||
size_t sj = 0u, dj = 0u; \
|
||||
\
|
||||
for (; sj < size.width; ++sj, dj += n) \
|
||||
{ \
|
||||
vec64 v_dst; \
|
||||
FILL_LINES##n(VLD1, sgn##64) \
|
||||
vst##n##_##sgn##64(dst + dj, v_dst); \
|
||||
/*FILL_LINES##n(SLD, sgn##64)*/ \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define VOID_LINE(type, n) (void)src##n##Base; (void)src##n##Stride;
|
||||
|
||||
#define COMBINE(sgn,bits,n) void combine##n(const Size2D &size \
|
||||
FILL_LINES##n(FARG, sgn##bits), \
|
||||
sgn##bits * dstBase, ptrdiff_t dstStride) \
|
||||
{ \
|
||||
internal::assertSupportedConfiguration(); \
|
||||
(void)size; \
|
||||
FILL_LINES##n(VOID, sgn##bits) \
|
||||
(void)dstBase; \
|
||||
(void)dstStride; \
|
||||
}
|
||||
#define COMBINE64(sgn,n) COMBINE(sgn,64,n)
|
||||
|
||||
#endif //CAROTENE_NEON
|
||||
|
||||
COMBINE(u, 8,2)
|
||||
COMBINE(u, 8,3)
|
||||
COMBINE(u, 8,4)
|
||||
COMBINE(u,16,2)
|
||||
COMBINE(u,16,3)
|
||||
COMBINE(u,16,4)
|
||||
COMBINE(s,32,2)
|
||||
COMBINE(s,32,3)
|
||||
COMBINE(s,32,4)
|
||||
COMBINE64(s, 2)
|
||||
COMBINE64(s, 3)
|
||||
COMBINE64(s, 4)
|
||||
|
||||
void combineYUYV(const Size2D &size,
|
||||
const u8 * srcyBase, ptrdiff_t srcyStride,
|
||||
const u8 * srcuBase, ptrdiff_t srcuStride,
|
||||
const u8 * srcvBase, ptrdiff_t srcvStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
#ifndef ANDROID
|
||||
size_t roiw32 = size.width >= 31 ? size.width - 31 : 0;
|
||||
#endif
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0u; i < size.height; i += 1)
|
||||
{
|
||||
const u8 * srcy = internal::getRowPtr(srcyBase, srcyStride, i);
|
||||
const u8 * srcu = internal::getRowPtr(srcuBase, srcuStride, i);
|
||||
const u8 * srcv = internal::getRowPtr(srcvBase, srcvStride, i);
|
||||
u8 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t syj = 0u, sj = 0u, dj = 0u;
|
||||
|
||||
#ifndef ANDROID
|
||||
for (; sj < roiw32; sj += 32, syj += 64, dj += 128)
|
||||
{
|
||||
internal::prefetch(srcy + syj);
|
||||
internal::prefetch(srcu + sj);
|
||||
internal::prefetch(srcv + sj);
|
||||
|
||||
uint8x16x2_t v_y = vld2q_u8(srcy + syj);
|
||||
uint8x16x4_t v_dst;
|
||||
v_dst.val[0] = v_y.val[0];
|
||||
v_dst.val[1] = vld1q_u8(srcu + sj);
|
||||
v_dst.val[2] = v_y.val[1];
|
||||
v_dst.val[3] = vld1q_u8(srcv + sj);
|
||||
vst4q_u8(dst + dj, v_dst);
|
||||
|
||||
v_y = vld2q_u8(srcy + syj + 32);
|
||||
v_dst.val[0] = v_y.val[0];
|
||||
v_dst.val[1] = vld1q_u8(srcu + sj + 16);
|
||||
v_dst.val[2] = v_y.val[1];
|
||||
v_dst.val[3] = vld1q_u8(srcv + sj + 16);
|
||||
vst4q_u8(dst + dj + 64, v_dst);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; sj < roiw8; sj += 8, syj += 16, dj += 32)
|
||||
{
|
||||
uint8x8x2_t v_y = vld2_u8(srcy + syj);
|
||||
uint8x8x4_t v_dst;
|
||||
v_dst.val[0] = v_y.val[0];
|
||||
v_dst.val[1] = vld1_u8(srcu + sj);
|
||||
v_dst.val[2] = v_y.val[1];
|
||||
v_dst.val[3] = vld1_u8(srcv + sj);
|
||||
vst4_u8(dst + dj, v_dst);
|
||||
}
|
||||
|
||||
for (; sj < size.width; ++sj, syj += 2, dj += 4)
|
||||
{
|
||||
dst[dj] = srcy[syj];
|
||||
dst[dj + 1] = srcu[sj];
|
||||
dst[dj + 2] = srcy[syj + 1];
|
||||
dst[dj + 3] = srcv[sj];
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcyBase;
|
||||
(void)srcyStride;
|
||||
(void)srcuBase;
|
||||
(void)srcuStride;
|
||||
(void)srcvBase;
|
||||
(void)srcvStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
void combineUYVY(const Size2D &size,
|
||||
const u8 * srcyBase, ptrdiff_t srcyStride,
|
||||
const u8 * srcuBase, ptrdiff_t srcuStride,
|
||||
const u8 * srcvBase, ptrdiff_t srcvStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
#ifndef ANDROID
|
||||
size_t roiw32 = size.width >= 31 ? size.width - 31 : 0;
|
||||
#endif
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0u; i < size.height; ++i)
|
||||
{
|
||||
const u8 * srcy = internal::getRowPtr(srcyBase, srcyStride, i);
|
||||
const u8 * srcu = internal::getRowPtr(srcuBase, srcuStride, i);
|
||||
const u8 * srcv = internal::getRowPtr(srcvBase, srcvStride, i);
|
||||
u8 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t syj = 0u, sj = 0u, dj = 0u;
|
||||
|
||||
#ifndef ANDROID
|
||||
for (; sj < roiw32; sj += 32, syj += 64, dj += 128)
|
||||
{
|
||||
internal::prefetch(srcy + syj);
|
||||
internal::prefetch(srcu + sj);
|
||||
internal::prefetch(srcv + sj);
|
||||
|
||||
uint8x16x2_t v_y = vld2q_u8(srcy + syj);
|
||||
uint8x16x4_t v_dst;
|
||||
v_dst.val[0] = vld1q_u8(srcu + sj);
|
||||
v_dst.val[1] = v_y.val[0];
|
||||
v_dst.val[2] = vld1q_u8(srcv + sj);
|
||||
v_dst.val[3] = v_y.val[1];
|
||||
vst4q_u8(dst + dj, v_dst);
|
||||
|
||||
v_y = vld2q_u8(srcy + syj + 32);
|
||||
v_dst.val[0] = vld1q_u8(srcu + sj + 16);
|
||||
v_dst.val[1] = v_y.val[0];
|
||||
v_dst.val[2] = vld1q_u8(srcv + sj + 16);
|
||||
v_dst.val[3] = v_y.val[1];
|
||||
vst4q_u8(dst + dj + 64, v_dst);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; sj < roiw8; sj += 8, syj += 16, dj += 32)
|
||||
{
|
||||
uint8x8x2_t v_y = vld2_u8(srcy + syj);
|
||||
uint8x8x4_t v_dst;
|
||||
v_dst.val[0] = vld1_u8(srcu + sj);
|
||||
v_dst.val[1] = v_y.val[0];
|
||||
v_dst.val[2] = vld1_u8(srcv + sj);
|
||||
v_dst.val[3] = v_y.val[1];
|
||||
vst4_u8(dst + dj, v_dst);
|
||||
}
|
||||
|
||||
for (; sj < size.width; ++sj, syj += 2, dj += 4)
|
||||
{
|
||||
dst[dj] = srcu[sj];
|
||||
dst[dj + 1] = srcy[syj];
|
||||
dst[dj + 2] = srcv[sj];
|
||||
dst[dj + 3] = srcy[syj + 1];
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcyBase;
|
||||
(void)srcyStride;
|
||||
(void)srcuBase;
|
||||
(void)srcuStride;
|
||||
(void)srcvBase;
|
||||
(void)srcvStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+340
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "vtransform.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace {
|
||||
|
||||
inline void vnst(u8* dst, uint8x16_t v1, uint8x16_t v2) { vst1q_u8(dst, v1); vst1q_u8(dst+16, v2); }
|
||||
inline void vnst(u8* dst, uint16x8_t v1, uint16x8_t v2) { vst1q_u8(dst, vcombine_u8(vmovn_u16(v1), vmovn_u16(v2))); }
|
||||
inline void vnst(u8* dst, uint32x4_t v1, uint32x4_t v2) { vst1_u8(dst, vmovn_u16(vcombine_u16(vmovn_u32(v1), vmovn_u32(v2)))); }
|
||||
|
||||
template <typename Op, int elsize> struct vtail
|
||||
{
|
||||
static inline void compare(const typename Op::type * src0, const typename Op::type * src1,
|
||||
u8 * dst, const Op & op,
|
||||
size_t &x, size_t width)
|
||||
{
|
||||
//do nothing since there couldn't be enough data
|
||||
(void)src0;
|
||||
(void)src1;
|
||||
(void)dst;
|
||||
(void)op;
|
||||
(void)x;
|
||||
(void)width;
|
||||
}
|
||||
};
|
||||
template <typename Op> struct vtail<Op, 2>
|
||||
{
|
||||
static inline void compare(const typename Op::type * src0, const typename Op::type * src1,
|
||||
u8 * dst, const Op & op,
|
||||
size_t &x, size_t width)
|
||||
{
|
||||
typedef typename Op::type type;
|
||||
typedef typename internal::VecTraits<type>::vec128 vec128;
|
||||
typedef typename internal::VecTraits<type>::unsign::vec128 uvec128;
|
||||
//There no more than 15 elements in the tail, so we could handle 8 element vector only once
|
||||
if( x + 8 < width)
|
||||
{
|
||||
vec128 v_src0, v_src1;
|
||||
uvec128 v_dst;
|
||||
|
||||
v_src0 = internal::vld1q(src0 + x);
|
||||
v_src1 = internal::vld1q(src1 + x);
|
||||
op(v_src0, v_src1, v_dst);
|
||||
internal::vst1(dst + x, internal::vmovn(v_dst));
|
||||
x+=8;
|
||||
}
|
||||
}
|
||||
};
|
||||
template <typename Op> struct vtail<Op, 1>
|
||||
{
|
||||
static inline void compare(const typename Op::type * src0, const typename Op::type * src1,
|
||||
u8 * dst, const Op & op,
|
||||
size_t &x, size_t width)
|
||||
{
|
||||
typedef typename Op::type type;
|
||||
typedef typename internal::VecTraits<type>::vec128 vec128;
|
||||
typedef typename internal::VecTraits<type>::unsign::vec128 uvec128;
|
||||
typedef typename internal::VecTraits<type>::vec64 vec64;
|
||||
typedef typename internal::VecTraits<type>::unsign::vec64 uvec64;
|
||||
//There no more than 31 elements in the tail, so we could handle once 16+8 or 16 or 8 elements
|
||||
if( x + 16 < width)
|
||||
{
|
||||
vec128 v_src0, v_src1;
|
||||
uvec128 v_dst;
|
||||
|
||||
v_src0 = internal::vld1q(src0 + x);
|
||||
v_src1 = internal::vld1q(src1 + x);
|
||||
op(v_src0, v_src1, v_dst);
|
||||
internal::vst1q(dst + x, v_dst);
|
||||
x+=16;
|
||||
}
|
||||
if( x + 8 < width)
|
||||
{
|
||||
vec64 v_src0, v_src1;
|
||||
uvec64 v_dst;
|
||||
|
||||
v_src0 = internal::vld1(src0 + x);
|
||||
v_src1 = internal::vld1(src1 + x);
|
||||
op(v_src0, v_src1, v_dst);
|
||||
internal::vst1(dst + x, v_dst);
|
||||
x+=8;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Op>
|
||||
void vcompare(Size2D size,
|
||||
const typename Op::type * src0Base, ptrdiff_t src0Stride,
|
||||
const typename Op::type * src1Base, ptrdiff_t src1Stride,
|
||||
u8 * dstBase, ptrdiff_t dstStride, const Op & op)
|
||||
{
|
||||
typedef typename Op::type type;
|
||||
typedef typename internal::VecTraits<type>::vec128 vec128;
|
||||
typedef typename internal::VecTraits<type>::unsign::vec128 uvec128;
|
||||
|
||||
if (src0Stride == src1Stride && src0Stride == dstStride &&
|
||||
src0Stride == (ptrdiff_t)(size.width * sizeof(type)))
|
||||
{
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
}
|
||||
|
||||
const u32 step_base = 32 / sizeof(type);
|
||||
size_t roiw_base = size.width >= (step_base - 1) ? size.width - step_base + 1 : 0;
|
||||
|
||||
for (size_t y = 0; y < size.height; ++y)
|
||||
{
|
||||
const type * src0 = internal::getRowPtr(src0Base, src0Stride, y);
|
||||
const type * src1 = internal::getRowPtr(src1Base, src1Stride, y);
|
||||
u8 * dst = internal::getRowPtr(dstBase, dstStride, y);
|
||||
size_t x = 0;
|
||||
|
||||
for( ; x < roiw_base; x += step_base )
|
||||
{
|
||||
internal::prefetch(src0 + x);
|
||||
internal::prefetch(src1 + x);
|
||||
|
||||
vec128 v_src00 = internal::vld1q(src0 + x), v_src01 = internal::vld1q(src0 + x + 16 / sizeof(type));
|
||||
vec128 v_src10 = internal::vld1q(src1 + x), v_src11 = internal::vld1q(src1 + x + 16 / sizeof(type));
|
||||
uvec128 v_dst0;
|
||||
uvec128 v_dst1;
|
||||
|
||||
op(v_src00, v_src10, v_dst0);
|
||||
op(v_src01, v_src11, v_dst1);
|
||||
|
||||
vnst(dst + x, v_dst0, v_dst1);
|
||||
}
|
||||
|
||||
vtail<Op, sizeof(type)>::compare(src0, src1, dst, op, x, size.width);
|
||||
|
||||
for (; x < size.width; ++x)
|
||||
{
|
||||
op(src0 + x, src1 + x, dst + x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct OpCmpEQ
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec128 & v_src0, const typename internal::VecTraits<T>::vec128 & v_src1,
|
||||
typename internal::VecTraits<T>::unsign::vec128 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vceqq(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec64 & v_src0, const typename internal::VecTraits<T>::vec64 & v_src1,
|
||||
typename internal::VecTraits<T>::unsign::vec64 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vceq(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const T * src0, const T * src1, u8 * dst) const
|
||||
{
|
||||
dst[0] = src0[0] == src1[0] ? 255 : 0;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct OpCmpNE
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec128 & v_src0, const typename internal::VecTraits<T>::vec128 & v_src1,
|
||||
typename internal::VecTraits<T>::unsign::vec128 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vmvnq(internal::vceqq(v_src0, v_src1));
|
||||
}
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec64 & v_src0, const typename internal::VecTraits<T>::vec64 & v_src1,
|
||||
typename internal::VecTraits<T>::unsign::vec64 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vmvn(internal::vceq(v_src0, v_src1));
|
||||
}
|
||||
|
||||
void operator() (const T * src0, const T * src1, u8 * dst) const
|
||||
{
|
||||
dst[0] = src0[0] == src1[0] ? 0 : 255;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct OpCmpGT
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec128 & v_src0, const typename internal::VecTraits<T>::vec128 & v_src1,
|
||||
typename internal::VecTraits<T>::unsign::vec128 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vcgtq(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec64 & v_src0, const typename internal::VecTraits<T>::vec64 & v_src1,
|
||||
typename internal::VecTraits<T>::unsign::vec64 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vcgt(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const T * src0, const T * src1, u8 * dst) const
|
||||
{
|
||||
dst[0] = src0[0] > src1[0] ? 255 : 0;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct OpCmpGE
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec128 & v_src0, const typename internal::VecTraits<T>::vec128 & v_src1,
|
||||
typename internal::VecTraits<T>::unsign::vec128 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vcgeq(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec64 & v_src0, const typename internal::VecTraits<T>::vec64 & v_src1,
|
||||
typename internal::VecTraits<T>::unsign::vec64 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vcge(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const T * src0, const T * src1, u8 * dst) const
|
||||
{
|
||||
dst[0] = src0[0] >= src1[0] ? 255 : 0;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define IMPL_CMPOP(op, type) \
|
||||
void cmp##op(const Size2D &size, \
|
||||
const type * src0Base, ptrdiff_t src0Stride, \
|
||||
const type * src1Base, ptrdiff_t src1Stride, \
|
||||
u8 *dstBase, ptrdiff_t dstStride) \
|
||||
{ \
|
||||
internal::assertSupportedConfiguration(); \
|
||||
vcompare(size, \
|
||||
src0Base, src0Stride, \
|
||||
src1Base, src1Stride, \
|
||||
dstBase, dstStride, \
|
||||
OpCmp##op<type>()); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define IMPL_CMPOP(op, type) \
|
||||
void cmp##op(const Size2D &size, \
|
||||
const type * src0Base, ptrdiff_t src0Stride, \
|
||||
const type * src1Base, ptrdiff_t src1Stride, \
|
||||
u8 *dstBase, ptrdiff_t dstStride) \
|
||||
{ \
|
||||
internal::assertSupportedConfiguration(); \
|
||||
(void)size; \
|
||||
(void)src0Base; \
|
||||
(void)src0Stride; \
|
||||
(void)src1Base; \
|
||||
(void)src1Stride; \
|
||||
(void)dstBase; \
|
||||
(void)dstStride; \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
IMPL_CMPOP(EQ, u8)
|
||||
IMPL_CMPOP(EQ, s8)
|
||||
IMPL_CMPOP(EQ, u16)
|
||||
IMPL_CMPOP(EQ, s16)
|
||||
IMPL_CMPOP(EQ, u32)
|
||||
IMPL_CMPOP(EQ, s32)
|
||||
IMPL_CMPOP(EQ, f32)
|
||||
|
||||
IMPL_CMPOP(NE, u8)
|
||||
IMPL_CMPOP(NE, s8)
|
||||
IMPL_CMPOP(NE, u16)
|
||||
IMPL_CMPOP(NE, s16)
|
||||
IMPL_CMPOP(NE, u32)
|
||||
IMPL_CMPOP(NE, s32)
|
||||
IMPL_CMPOP(NE, f32)
|
||||
|
||||
IMPL_CMPOP(GT, u8)
|
||||
IMPL_CMPOP(GT, s8)
|
||||
IMPL_CMPOP(GT, u16)
|
||||
IMPL_CMPOP(GT, s16)
|
||||
IMPL_CMPOP(GT, u32)
|
||||
IMPL_CMPOP(GT, s32)
|
||||
IMPL_CMPOP(GT, f32)
|
||||
|
||||
IMPL_CMPOP(GE, u8)
|
||||
IMPL_CMPOP(GE, s8)
|
||||
IMPL_CMPOP(GE, u16)
|
||||
IMPL_CMPOP(GE, s16)
|
||||
IMPL_CMPOP(GE, u32)
|
||||
IMPL_CMPOP(GE, s32)
|
||||
IMPL_CMPOP(GE, f32)
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
+2846
File diff suppressed because it is too large
Load Diff
Vendored
+108
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
bool isSupportedConfiguration()
|
||||
{
|
||||
#ifdef CAROTENE_NEON
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
void assertSupportedConfiguration(bool parametersSupported)
|
||||
{
|
||||
if (!isSupportedConfiguration()) {
|
||||
std::cerr << "internal error: attempted to use an unavailable function" << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
|
||||
if (!parametersSupported) {
|
||||
std::cerr << "internal error: attempted to use a function with unsupported parameters" << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
|
||||
ptrdiff_t borderInterpolate(ptrdiff_t _p, size_t _len, BORDER_MODE borderType, size_t startMargin, size_t endMargin)
|
||||
{
|
||||
ptrdiff_t p = _p + (ptrdiff_t)startMargin;
|
||||
size_t len = _len + startMargin + endMargin;
|
||||
if( (size_t)p < len )
|
||||
return _p;
|
||||
else if( borderType == BORDER_MODE_REPLICATE )
|
||||
p = p < 0 ? 0 : (ptrdiff_t)len - 1;
|
||||
else if( borderType == BORDER_MODE_REFLECT || borderType == BORDER_MODE_REFLECT101 )
|
||||
{
|
||||
s32 delta = borderType == BORDER_MODE_REFLECT101;
|
||||
if( len == 1 )
|
||||
return 0;
|
||||
do
|
||||
{
|
||||
if( p < 0 )
|
||||
p = -p - 1 + delta;
|
||||
else
|
||||
p = (ptrdiff_t)len - 1 - (p - (ptrdiff_t)len) - delta;
|
||||
}
|
||||
while( (size_t)p >= len );
|
||||
}
|
||||
else if( borderType == BORDER_MODE_WRAP )
|
||||
{
|
||||
if( p < 0 )
|
||||
p -= ((p-(ptrdiff_t)len+1)/(ptrdiff_t)len)*(ptrdiff_t)len;
|
||||
if( p >= (ptrdiff_t)len )
|
||||
p %= (ptrdiff_t)len;
|
||||
}
|
||||
else if( borderType == BORDER_MODE_CONSTANT )
|
||||
p = -1;
|
||||
else
|
||||
internal::assertSupportedConfiguration(false);
|
||||
return p - (ptrdiff_t)startMargin;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+97
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#ifndef CAROTENE_SRC_COMMON_HPP
|
||||
#define CAROTENE_SRC_COMMON_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
|
||||
#if defined WITH_NEON && (defined __ARM_NEON__ || defined __ARM_NEON)
|
||||
#define CAROTENE_NEON
|
||||
#endif
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
#include <arm_neon.h>
|
||||
#include "intrinsics.hpp"
|
||||
#endif
|
||||
|
||||
#include <carotene/functions.hpp>
|
||||
#include "saturate_cast.hpp"
|
||||
|
||||
namespace CAROTENE_NS { namespace internal {
|
||||
|
||||
inline void prefetch(const void *ptr, size_t offset = 32*10)
|
||||
{
|
||||
#if defined __GNUC__
|
||||
__builtin_prefetch(reinterpret_cast<const char*>(ptr) + offset);
|
||||
#elif defined _MSC_VER && defined CAROTENE_NEON
|
||||
__prefetch(reinterpret_cast<const char*>(ptr) + offset);
|
||||
#else
|
||||
(void)ptr;
|
||||
(void)offset;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T *getRowPtr(T *base, ptrdiff_t stride, size_t row)
|
||||
{
|
||||
char *baseRaw = const_cast<char *>(reinterpret_cast<const char *>(base));
|
||||
return reinterpret_cast<T *>(baseRaw + ptrdiff_t(row) * stride);
|
||||
}
|
||||
|
||||
void assertSupportedConfiguration(bool parametersSupported = true);
|
||||
|
||||
ptrdiff_t borderInterpolate(ptrdiff_t _p, size_t _len, BORDER_MODE borderType, size_t startMargin = 0, size_t endMargin = 0);
|
||||
|
||||
/*!
|
||||
* Aligns pointer by the certain number of bytes
|
||||
*
|
||||
* This small inline function aligns the pointer by the certain number of bytes by shifting
|
||||
* it forward by 0 or a positive offset.
|
||||
*/
|
||||
template<typename T> inline T* alignPtr(T* ptr, size_t n=sizeof(T))
|
||||
{
|
||||
return (T*)(((size_t)ptr + n-1) & -n);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
Vendored
+1331
File diff suppressed because it is too large
Load Diff
+399
@@ -0,0 +1,399 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace {
|
||||
|
||||
template <int shift>
|
||||
void lshiftConst(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
s16 * dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
size_t roiw16 = size.width >= 15 ? size.width - 15 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const u8 * src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
s16 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for (; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
uint8x16_t v_src = vld1q_u8(src + j);
|
||||
int16x8_t v_dst0 = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(v_src)));
|
||||
int16x8_t v_dst1 = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(v_src)));
|
||||
|
||||
vst1q_s16(dst + j, vshlq_n_s16(v_dst0, shift));
|
||||
vst1q_s16(dst + j + 8, vshlq_n_s16(v_dst1, shift));
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
int16x8_t v_dst = vreinterpretq_s16_u16(vmovl_u8(vld1_u8(src + j)));
|
||||
vst1q_s16(dst + j, vshlq_n_s16(v_dst, shift));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = ((s16)src[j] << shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void lshiftConst<0>(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
s16 * dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
size_t roiw16 = size.width >= 15 ? size.width - 15 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const u8 * src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
s16 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for (; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
uint8x16_t v_src = vld1q_u8(src + j);
|
||||
int16x8_t v_dst0 = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(v_src)));
|
||||
int16x8_t v_dst1 = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(v_src)));
|
||||
|
||||
vst1q_s16(dst + j, v_dst0);
|
||||
vst1q_s16(dst + j + 8, v_dst1);
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
int16x8_t v_dst = vreinterpretq_s16_u16(vmovl_u8(vld1_u8(src + j)));
|
||||
vst1q_s16(dst + j, v_dst);
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = (s16)src[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <int shift>
|
||||
void rshiftConst(const Size2D &size,
|
||||
const s16 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY cpolicy)
|
||||
{
|
||||
size_t roiw16 = size.width >= 15 ? size.width - 15 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const s16 * src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
u8 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
if (cpolicy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
for (; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
int16x8_t v_src0 = vshrq_n_s16(vld1q_s16(src + j), shift),
|
||||
v_src1 = vshrq_n_s16(vld1q_s16(src + j + 8), shift);
|
||||
uint8x16_t v_dst = vcombine_u8(vqmovun_s16(v_src0),
|
||||
vqmovun_s16(v_src1));
|
||||
vst1q_u8(dst + j, v_dst);
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
int16x8_t v_src = vshrq_n_s16(vld1q_s16(src + j), shift);
|
||||
vst1_u8(dst + j, vqmovun_s16(v_src));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = internal::saturate_cast<u8>((src[j] >> shift));
|
||||
}
|
||||
}
|
||||
else // CONVERT_POLICY_WRAP
|
||||
{
|
||||
for (; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
int16x8_t v_src0 = vshrq_n_s16(vld1q_s16(src + j), shift),
|
||||
v_src1 = vshrq_n_s16(vld1q_s16(src + j + 8), shift);
|
||||
int8x16_t v_dst = vcombine_s8(vmovn_s16(v_src0),
|
||||
vmovn_s16(v_src1));
|
||||
vst1q_u8(dst + j, vreinterpretq_u8_s8(v_dst));
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
int16x8_t v_src = vshrq_n_s16(vld1q_s16(src + j), shift);
|
||||
vst1_u8(dst + j, vreinterpret_u8_s8(vmovn_s16(v_src)));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = (u8)((src[j] >> shift));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void rshiftConst<0>(const Size2D &size,
|
||||
const s16 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY cpolicy)
|
||||
{
|
||||
size_t roiw16 = size.width >= 15 ? size.width - 15 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const s16 * src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
u8 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
if (cpolicy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
for (; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
int16x8_t v_src0 = vld1q_s16(src + j), v_src1 = vld1q_s16(src + j + 8);
|
||||
uint8x16_t v_dst = vcombine_u8(vqmovun_s16(v_src0), vqmovun_s16(v_src1));
|
||||
vst1q_u8(dst + j, v_dst);
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
int16x8_t v_src = vld1q_s16(src + j);
|
||||
vst1_u8(dst + j, vqmovun_s16(v_src));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = internal::saturate_cast<u8>(src[j]);
|
||||
}
|
||||
}
|
||||
else // CONVERT_POLICY_WRAP
|
||||
{
|
||||
for (; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
int16x8_t v_src0 = vld1q_s16(src + j), v_src1 = vld1q_s16(src + j + 8);
|
||||
int8x16_t v_dst = vcombine_s8(vmovn_s16(v_src0), vmovn_s16(v_src1));
|
||||
vst1q_u8(dst + j, vreinterpretq_u8_s8(v_dst));
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
int16x8_t v_src = vld1q_s16(src + j);
|
||||
vst1_u8(dst + j, vreinterpret_u8_s8(vmovn_s16(v_src)));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = (u8)src[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (* lshiftConstFunc)(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
s16 * dstBase, ptrdiff_t dstStride);
|
||||
|
||||
typedef void (* rshiftConstFunc)(const Size2D &size,
|
||||
const s16 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY cpolicy);
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
void lshift(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
s16 * dstBase, ptrdiff_t dstStride,
|
||||
u32 shift)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
if (shift >= 16u)
|
||||
{
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
s16 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
std::memset(dst, 0, sizeof(s16) * size.width);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// this ugly contruction is needed to avoid:
|
||||
// /usr/lib/gcc/arm-linux-gnueabihf/4.8/include/arm_neon.h:3581:59: error: argument must be a constant
|
||||
// return (int16x8_t)__builtin_neon_vshl_nv8hi (__a, __b, 1);
|
||||
|
||||
lshiftConstFunc funcs[16] =
|
||||
{
|
||||
lshiftConst<0>,
|
||||
lshiftConst<1>,
|
||||
lshiftConst<2>,
|
||||
lshiftConst<3>,
|
||||
lshiftConst<4>,
|
||||
lshiftConst<5>,
|
||||
lshiftConst<6>,
|
||||
lshiftConst<7>,
|
||||
lshiftConst<8>,
|
||||
lshiftConst<9>,
|
||||
lshiftConst<10>,
|
||||
lshiftConst<11>,
|
||||
lshiftConst<12>,
|
||||
lshiftConst<13>,
|
||||
lshiftConst<14>,
|
||||
lshiftConst<15>
|
||||
}, func = funcs[shift];
|
||||
|
||||
func(size, srcBase, srcStride, dstBase, dstStride);
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)shift;
|
||||
#endif
|
||||
}
|
||||
|
||||
void rshift(const Size2D &size,
|
||||
const s16 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
u32 shift, CONVERT_POLICY cpolicy)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
if (shift >= 16)
|
||||
{
|
||||
if (cpolicy == CONVERT_POLICY_WRAP)
|
||||
{
|
||||
size_t roiw16 = size.width >= 15 ? size.width - 15 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
int16x8_t v_zero = vdupq_n_s16(0);
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const s16 * src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
u8 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for (; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
int16x8_t v_src0 = vld1q_s16(src + j), v_src1 = vld1q_s16(src + j + 8);
|
||||
uint8x16_t v_dst = vcombine_u8(vmovn_u16(vcltq_s16(v_src0, v_zero)),
|
||||
vmovn_u16(vcltq_s16(v_src1, v_zero)));
|
||||
vst1q_u8(dst + j, v_dst);
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
int16x8_t v_src = vld1q_s16(src + j);
|
||||
vst1_u8(dst + j, vmovn_u16(vcltq_s16(v_src, v_zero)));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = src[j] >= 0 ? 0 : 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
u8 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
std::memset(dst, 0, sizeof(u8) * size.width);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// this ugly contruction is needed to avoid:
|
||||
// /usr/lib/gcc/arm-linux-gnueabihf/4.8/include/arm_neon.h:3581:59: error: argument must be a constant
|
||||
// return (int16x8_t)__builtin_neon_vshr_nv8hi (__a, __b, 1);
|
||||
|
||||
rshiftConstFunc funcs[16] =
|
||||
{
|
||||
rshiftConst<0>,
|
||||
rshiftConst<1>,
|
||||
rshiftConst<2>,
|
||||
rshiftConst<3>,
|
||||
rshiftConst<4>,
|
||||
rshiftConst<5>,
|
||||
rshiftConst<6>,
|
||||
rshiftConst<7>,
|
||||
rshiftConst<8>,
|
||||
rshiftConst<9>,
|
||||
rshiftConst<10>,
|
||||
rshiftConst<11>,
|
||||
rshiftConst<12>,
|
||||
rshiftConst<13>,
|
||||
rshiftConst<14>,
|
||||
rshiftConst<15>
|
||||
}, func = funcs[shift];
|
||||
|
||||
func(size, srcBase, srcStride, dstBase, dstStride, cpolicy);
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)shift;
|
||||
(void)cpolicy;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
+2498
File diff suppressed because it is too large
Load Diff
+340
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "saturate_cast.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
bool isConvolutionSupported(const Size2D &size, const Size2D &ksize,
|
||||
BORDER_MODE border)
|
||||
{
|
||||
return isSupportedConfiguration() && size.width >= 8 &&
|
||||
(border == BORDER_MODE_CONSTANT ||
|
||||
border == BORDER_MODE_REPLICATE) &&
|
||||
(ksize.width == 3) && (ksize.height == 3);
|
||||
}
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace {
|
||||
|
||||
template <int shift>
|
||||
int32x4_t vshrq_s32(int32x4_t value)
|
||||
{
|
||||
return vshrq_n_s32(value, shift);
|
||||
}
|
||||
|
||||
template <>
|
||||
int32x4_t vshrq_s32<0>(int32x4_t value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
typedef int32x4_t (* vshrq_s32_func)(int32x4_t value);
|
||||
|
||||
#endif
|
||||
|
||||
void convolution(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
BORDER_MODE border, u8 borderValue,
|
||||
const Size2D & ksize, s16 * kernelBase, u32 scale)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isConvolutionSupported(size, ksize, border));
|
||||
#ifdef CAROTENE_NEON
|
||||
const uint8x8_t v_zero_u8 = vdup_n_u8(0);
|
||||
const uint8x8_t v_border = vdup_n_u8(borderValue);
|
||||
const int32x4_t v_zero_s32 = vdupq_n_s32(0);
|
||||
|
||||
uint8x8_t tprev[3] = { v_zero_u8, v_zero_u8, v_zero_u8 },
|
||||
tcurr[3] = { v_zero_u8, v_zero_u8, v_zero_u8 },
|
||||
tnext[3] = { v_zero_u8, v_zero_u8, v_zero_u8 };
|
||||
uint8x8_t t0 = v_zero_u8, t1 = v_zero_u8, t2 = v_zero_u8;
|
||||
|
||||
ptrdiff_t width = (ptrdiff_t)size.width, height = (ptrdiff_t)size.height;
|
||||
static const vshrq_s32_func vshrq_s32_a[33] =
|
||||
{
|
||||
vshrq_s32<0>,
|
||||
vshrq_s32<1>,
|
||||
vshrq_s32<2>,
|
||||
vshrq_s32<3>,
|
||||
vshrq_s32<4>,
|
||||
vshrq_s32<5>,
|
||||
vshrq_s32<6>,
|
||||
vshrq_s32<7>,
|
||||
vshrq_s32<8>,
|
||||
vshrq_s32<9>,
|
||||
vshrq_s32<10>,
|
||||
vshrq_s32<11>,
|
||||
vshrq_s32<12>,
|
||||
vshrq_s32<13>,
|
||||
vshrq_s32<14>,
|
||||
vshrq_s32<15>,
|
||||
vshrq_s32<16>,
|
||||
vshrq_s32<17>,
|
||||
vshrq_s32<18>,
|
||||
vshrq_s32<19>,
|
||||
vshrq_s32<20>,
|
||||
vshrq_s32<21>,
|
||||
vshrq_s32<22>,
|
||||
vshrq_s32<23>,
|
||||
vshrq_s32<24>,
|
||||
vshrq_s32<25>,
|
||||
vshrq_s32<26>,
|
||||
vshrq_s32<27>,
|
||||
vshrq_s32<28>,
|
||||
vshrq_s32<29>,
|
||||
vshrq_s32<30>,
|
||||
vshrq_s32<31>,
|
||||
vshrq_s32<32>
|
||||
};
|
||||
vshrq_s32_func vshrq_s32_p = vshrq_s32_a[scale];
|
||||
|
||||
for (ptrdiff_t y = 0; y < height; ++y)
|
||||
{
|
||||
const u8 * srow0 = y == 0 && border == BORDER_MODE_CONSTANT ? NULL : internal::getRowPtr(srcBase, srcStride, std::max<ptrdiff_t>(y - 1, 0));
|
||||
const u8 * srow1 = internal::getRowPtr(srcBase, srcStride, y);
|
||||
const u8 * srow2 = y + 1 == height && border == BORDER_MODE_CONSTANT ? NULL : internal::getRowPtr(srcBase, srcStride, std::min(y + 1, height - 1));
|
||||
u8 * drow = internal::getRowPtr(dstBase, dstStride, y);
|
||||
|
||||
u8 prevx[3] = { 0, 0, 0 },
|
||||
currx[3] = { 0, 0, 0 },
|
||||
nextx[3] = { 0, 0, 0 };
|
||||
ptrdiff_t x = 0;
|
||||
const ptrdiff_t bwidth = y + 2 < height ? width : (width - 8);
|
||||
|
||||
// perform vertical convolution
|
||||
for ( ; x <= bwidth; x += 8)
|
||||
{
|
||||
internal::prefetch(srow0 + x);
|
||||
internal::prefetch(srow1 + x);
|
||||
internal::prefetch(srow2 + x);
|
||||
|
||||
uint8x8_t x0 = !srow0 ? v_border : vld1_u8(srow0 + x);
|
||||
uint8x8_t x1 = vld1_u8(srow1 + x);
|
||||
uint8x8_t x2 = !srow2 ? v_border : vld1_u8(srow2 + x);
|
||||
|
||||
// calculate values for plain CPU part below if needed
|
||||
if (x + 8 >= bwidth)
|
||||
{
|
||||
ptrdiff_t x3 = x == width ? width - 1 : x;
|
||||
ptrdiff_t x4 = border == BORDER_MODE_CONSTANT ? x3 - 1 : std::max<ptrdiff_t>(x3 - 1, 0);
|
||||
|
||||
if (border == BORDER_MODE_CONSTANT && x4 < 0)
|
||||
prevx[0] = prevx[1] = prevx[2] = borderValue;
|
||||
else
|
||||
{
|
||||
prevx[0] = srow0 ? srow0[x4] : borderValue;
|
||||
prevx[1] = srow1[x4] ;
|
||||
prevx[2] = srow2 ? srow2[x4] : borderValue;
|
||||
}
|
||||
|
||||
currx[0] = srow0 ? srow0[x3] : borderValue;
|
||||
currx[1] = srow1[x3] ;
|
||||
currx[2] = srow2 ? srow2[x3] : borderValue;
|
||||
}
|
||||
|
||||
// make shift
|
||||
if (x)
|
||||
{
|
||||
tprev[0] = tcurr[0];
|
||||
tcurr[0] = tnext[0];
|
||||
|
||||
tprev[1] = tcurr[1];
|
||||
tcurr[1] = tnext[1];
|
||||
|
||||
tprev[2] = tcurr[2];
|
||||
tcurr[2] = tnext[2];
|
||||
}
|
||||
|
||||
tnext[0] = x0;
|
||||
tnext[1] = x1;
|
||||
tnext[2] = x2;
|
||||
|
||||
// make extrapolation for the first elements
|
||||
if (!x)
|
||||
{
|
||||
// make border
|
||||
if (border == BORDER_MODE_CONSTANT)
|
||||
tcurr[0] = tcurr[1] = tcurr[2] = v_border;
|
||||
else if (border == BORDER_MODE_REPLICATE)
|
||||
{
|
||||
tcurr[0] = vdup_n_u8(vget_lane_u8(tnext[0], 0));
|
||||
tcurr[1] = vdup_n_u8(vget_lane_u8(tnext[1], 0));
|
||||
tcurr[2] = vdup_n_u8(vget_lane_u8(tnext[2], 0));
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
int32x4_t v_dst0 = v_zero_s32, v_dst1 = v_zero_s32;
|
||||
|
||||
{
|
||||
// combine 3 "shifted" vectors
|
||||
t0 = vext_u8(tprev[0], tcurr[0], 7);
|
||||
t1 = tcurr[0];
|
||||
t2 = vext_u8(tcurr[0], tnext[0], 1);
|
||||
|
||||
int16x8_t t0_16s = vreinterpretq_s16_u16(vmovl_u8(t0));
|
||||
int16x8_t t1_16s = vreinterpretq_s16_u16(vmovl_u8(t1));
|
||||
int16x8_t t2_16s = vreinterpretq_s16_u16(vmovl_u8(t2));
|
||||
|
||||
v_dst0 = vmlal_n_s16(v_dst0, vget_low_s16(t0_16s), kernelBase[8]);
|
||||
v_dst0 = vmlal_n_s16(v_dst0, vget_low_s16(t1_16s), kernelBase[7]);
|
||||
v_dst0 = vmlal_n_s16(v_dst0, vget_low_s16(t2_16s), kernelBase[6]);
|
||||
|
||||
v_dst1 = vmlal_n_s16(v_dst1, vget_high_s16(t0_16s), kernelBase[8]);
|
||||
v_dst1 = vmlal_n_s16(v_dst1, vget_high_s16(t1_16s), kernelBase[7]);
|
||||
v_dst1 = vmlal_n_s16(v_dst1, vget_high_s16(t2_16s), kernelBase[6]);
|
||||
}
|
||||
|
||||
{
|
||||
// combine 3 "shifted" vectors
|
||||
t0 = vext_u8(tprev[1], tcurr[1], 7);
|
||||
t1 = tcurr[1];
|
||||
t2 = vext_u8(tcurr[1], tnext[1], 1);
|
||||
|
||||
int16x8_t t0_16s = vreinterpretq_s16_u16(vmovl_u8(t0));
|
||||
int16x8_t t1_16s = vreinterpretq_s16_u16(vmovl_u8(t1));
|
||||
int16x8_t t2_16s = vreinterpretq_s16_u16(vmovl_u8(t2));
|
||||
|
||||
v_dst0 = vmlal_n_s16(v_dst0, vget_low_s16(t0_16s), kernelBase[5]);
|
||||
v_dst0 = vmlal_n_s16(v_dst0, vget_low_s16(t1_16s), kernelBase[4]);
|
||||
v_dst0 = vmlal_n_s16(v_dst0, vget_low_s16(t2_16s), kernelBase[3]);
|
||||
|
||||
v_dst1 = vmlal_n_s16(v_dst1, vget_high_s16(t0_16s), kernelBase[5]);
|
||||
v_dst1 = vmlal_n_s16(v_dst1, vget_high_s16(t1_16s), kernelBase[4]);
|
||||
v_dst1 = vmlal_n_s16(v_dst1, vget_high_s16(t2_16s), kernelBase[3]);
|
||||
}
|
||||
|
||||
{
|
||||
// combine 3 "shifted" vectors
|
||||
t0 = vext_u8(tprev[2], tcurr[2], 7);
|
||||
t1 = tcurr[2];
|
||||
t2 = vext_u8(tcurr[2], tnext[2], 1);
|
||||
|
||||
int16x8_t t0_16s = vreinterpretq_s16_u16(vmovl_u8(t0));
|
||||
int16x8_t t1_16s = vreinterpretq_s16_u16(vmovl_u8(t1));
|
||||
int16x8_t t2_16s = vreinterpretq_s16_u16(vmovl_u8(t2));
|
||||
|
||||
v_dst0 = vmlal_n_s16(v_dst0, vget_low_s16(t0_16s), kernelBase[2]);
|
||||
v_dst0 = vmlal_n_s16(v_dst0, vget_low_s16(t1_16s), kernelBase[1]);
|
||||
v_dst0 = vmlal_n_s16(v_dst0, vget_low_s16(t2_16s), kernelBase[0]);
|
||||
|
||||
v_dst1 = vmlal_n_s16(v_dst1, vget_high_s16(t0_16s), kernelBase[2]);
|
||||
v_dst1 = vmlal_n_s16(v_dst1, vget_high_s16(t1_16s), kernelBase[1]);
|
||||
v_dst1 = vmlal_n_s16(v_dst1, vget_high_s16(t2_16s), kernelBase[0]);
|
||||
}
|
||||
|
||||
|
||||
// make scale
|
||||
v_dst0 = vshrq_s32_p(v_dst0);
|
||||
v_dst1 = vshrq_s32_p(v_dst1);
|
||||
|
||||
// and add them
|
||||
vst1_u8(drow + x - 8, vqmovn_u16(vcombine_u16(vqmovun_s32(v_dst0),
|
||||
vqmovun_s32(v_dst1))));
|
||||
}
|
||||
|
||||
x -= 8;
|
||||
if (x == width)
|
||||
--x;
|
||||
|
||||
for ( ; x < width; ++x)
|
||||
{
|
||||
// make extrapolation for the last elements
|
||||
if (x + 1 >= width)
|
||||
{
|
||||
if (border == BORDER_MODE_CONSTANT)
|
||||
{
|
||||
nextx[0] = borderValue;
|
||||
nextx[1] = borderValue;
|
||||
nextx[2] = borderValue;
|
||||
}
|
||||
else if (border == BORDER_MODE_REPLICATE)
|
||||
{
|
||||
nextx[0] = srow0[x];
|
||||
nextx[1] = srow1[x];
|
||||
nextx[2] = srow2[x];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nextx[0] = srow0 ? srow0[x + 1] : borderValue;
|
||||
nextx[1] = srow1[x + 1] ;
|
||||
nextx[2] = srow2 ? srow2[x + 1] : borderValue;
|
||||
}
|
||||
|
||||
s32 val = 0;
|
||||
for (s32 _y = 0; _y < 3; ++_y)
|
||||
val += prevx[_y] * kernelBase[(2 - _y) * 3 + 2] +
|
||||
currx[_y] * kernelBase[(2 - _y) * 3 + 1] +
|
||||
nextx[_y] * kernelBase[(2 - _y) * 3 + 0];
|
||||
|
||||
drow[x] = internal::saturate_cast<u8>(val >> scale);
|
||||
|
||||
// make shift
|
||||
prevx[0] = currx[0];
|
||||
currx[0] = nextx[0];
|
||||
|
||||
prevx[1] = currx[1];
|
||||
currx[1] = nextx[1];
|
||||
|
||||
prevx[2] = currx[2];
|
||||
currx[2] = nextx[2];
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)border;
|
||||
(void)borderValue;
|
||||
(void)ksize;
|
||||
(void)kernelBase;
|
||||
(void)scale;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
+430
@@ -0,0 +1,430 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2012-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
s32 countNonZero(const Size2D &_size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
Size2D size(_size);
|
||||
if (srcStride == (ptrdiff_t)(size.width))
|
||||
{
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
}
|
||||
size_t roiw16 = size.width & ~15u;
|
||||
s32 result = 0;
|
||||
for(size_t k = 0; k < size.height; ++k)
|
||||
{
|
||||
const u8* src = internal::getRowPtr( srcBase, srcStride, k);
|
||||
size_t i = 0;
|
||||
|
||||
#define COUNTNONZERO8U_BLOCK_SIZE (16*255)
|
||||
uint8x16_t vc1 = vmovq_n_u8(1);
|
||||
for (; i < roiw16;)
|
||||
{
|
||||
size_t lim = std::min(i + COUNTNONZERO8U_BLOCK_SIZE, size.width) - 16;
|
||||
uint8x16_t vs = vmovq_n_u8(0);
|
||||
|
||||
for (; i <= lim; i+= 16)
|
||||
{
|
||||
internal::prefetch(src + i);
|
||||
uint8x16_t vln = vld1q_u8(src + i);
|
||||
uint8x16_t vnz = vminq_u8(vln, vc1);
|
||||
vs = vaddq_u8(vs, vnz);
|
||||
}
|
||||
|
||||
uint32x4_t vs4 = vpaddlq_u16(vpaddlq_u8(vs));
|
||||
uint32x2_t vs2 = vadd_u32(vget_low_u32(vs4), vget_high_u32(vs4));
|
||||
|
||||
s32 s[2];
|
||||
vst1_u32((u32*)s, vs2);
|
||||
|
||||
if (s[0] < 0 || s[1] < 0)//saturate in case of overflow ~ 2GB of non-zeros...
|
||||
{
|
||||
return 0x7fFFffFF;
|
||||
}
|
||||
result += (s[0] += s[1]);
|
||||
if (s[0] < 0 || result < 0)
|
||||
{
|
||||
return 0x7fFFffFF;
|
||||
}
|
||||
}
|
||||
for (; i < size.width; i++)
|
||||
result += (src[i] != 0)?1:0;
|
||||
if (result < 0)//saturate in case of overflow ~ 2GB of non-zeros...
|
||||
{
|
||||
return 0x7fFFffFF;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
(void)_size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 countNonZero(const Size2D &_size,
|
||||
const u16 * srcBase, ptrdiff_t srcStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
Size2D size(_size);
|
||||
if (srcStride == (ptrdiff_t)(size.width))
|
||||
{
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
}
|
||||
size_t roiw8 = size.width & ~7u;
|
||||
s32 result = 0;
|
||||
for(size_t k = 0; k < size.height; ++k)
|
||||
{
|
||||
const u16* src = internal::getRowPtr( srcBase, srcStride, k);
|
||||
size_t i = 0;
|
||||
|
||||
#define COUNTNONZERO16U_BLOCK_SIZE (8*(256*256-1))
|
||||
uint16x8_t vc1 = vmovq_n_u16(1);
|
||||
for (; i < roiw8;)
|
||||
{
|
||||
size_t lim = std::min(i + COUNTNONZERO16U_BLOCK_SIZE, size.width) - 8;
|
||||
uint16x8_t vs = vmovq_n_u16(0);
|
||||
|
||||
for (; i <= lim; i+= 8)
|
||||
{
|
||||
internal::prefetch(src + i);
|
||||
uint16x8_t vln = vld1q_u16(src + i);
|
||||
uint16x8_t vnz = vminq_u16(vln, vc1);
|
||||
vs = vaddq_u16(vs, vnz);
|
||||
}
|
||||
|
||||
uint32x4_t vs4 = vpaddlq_u16(vs);
|
||||
uint32x2_t vs2 = vadd_u32(vget_low_u32(vs4), vget_high_u32(vs4));
|
||||
|
||||
s32 s[2];
|
||||
vst1_u32((u32*)s, vs2);
|
||||
|
||||
if (s[0] < 0 || s[1] < 0)//saturate in case of overflow ~ 4GB of non-zeros...
|
||||
{
|
||||
return 0x7fFFffFF;
|
||||
}
|
||||
result += (s[0] += s[1]);
|
||||
if (s[0] < 0 || result < 0)
|
||||
{
|
||||
return 0x7fFFffFF;
|
||||
}
|
||||
}
|
||||
for (; i < size.width; i++)
|
||||
result += (src[i] != 0)?1:0;
|
||||
if (result < 0)//saturate in case of overflow ~ 4GB of non-zeros...
|
||||
{
|
||||
return 0x7fFFffFF;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
(void)_size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 countNonZero(const Size2D &_size,
|
||||
const s32 * srcBase, ptrdiff_t srcStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
Size2D size(_size);
|
||||
if (srcStride == (ptrdiff_t)(size.width))
|
||||
{
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
}
|
||||
size_t roiw4 = size.width & ~3u;
|
||||
s32 result = 0;
|
||||
for(size_t k = 0; k < size.height; ++k)
|
||||
{
|
||||
const u32* src = (const u32*)internal::getRowPtr( srcBase, srcStride, k);
|
||||
u32 i = 0;
|
||||
|
||||
uint32x4_t vc1 = vmovq_n_u32(1);
|
||||
uint32x4_t vs = vmovq_n_u32(0);
|
||||
|
||||
for (; i < roiw4; i += 4 )
|
||||
{
|
||||
internal::prefetch(src + i);
|
||||
uint32x4_t vln = vld1q_u32(src + i);
|
||||
uint32x4_t vnz = vminq_u32(vln, vc1);
|
||||
vs = vqaddq_u32(vs, vnz);
|
||||
}
|
||||
|
||||
uint32x2_t vs2 = vqadd_u32(vget_low_u32(vs), vget_high_u32(vs));
|
||||
|
||||
s32 s[2];
|
||||
vst1_u32((u32*)s, vs2);
|
||||
|
||||
if (s[0] < 0 || s[1] < 0)//saturate in case of overflow ~ 8GB of non-zeros...
|
||||
{
|
||||
return 0x7fFFffFF;
|
||||
}
|
||||
result += (s[0] += s[1]);
|
||||
if (s[0] < 0 || result < 0)
|
||||
{
|
||||
return 0x7fFFffFF;
|
||||
}
|
||||
|
||||
for (; i < size.width; i++)
|
||||
result += (src[i] != 0)?1:0;
|
||||
if (result < 0)//saturate in case of overflow ~ 8GB of non-zeros...
|
||||
{
|
||||
return 0x7fFFffFF;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
(void)_size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 countNonZero(const Size2D &_size,
|
||||
const f32 * srcBase, ptrdiff_t srcStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
Size2D size(_size);
|
||||
if (srcStride == (ptrdiff_t)(size.width))
|
||||
{
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
}
|
||||
size_t roiw4 = size.width & ~3u;
|
||||
s32 result = 0;
|
||||
for(size_t k = 0; k < size.height; ++k)
|
||||
{
|
||||
const f32* src = internal::getRowPtr( srcBase, srcStride, k);
|
||||
size_t i = 0;
|
||||
|
||||
float32x4_t vc0 = vmovq_n_f32(0);
|
||||
int32x4_t vs = vmovq_n_s32(0);
|
||||
|
||||
for (; i < roiw4; i += 4 )
|
||||
{
|
||||
internal::prefetch(src + i);
|
||||
float32x4_t vln = vld1q_f32(src + i);
|
||||
int32x4_t vnz = vreinterpretq_s32_u32(vmvnq_u32(vceqq_f32(vln, vc0)));
|
||||
vs = vqaddq_s32(vs, vnz);
|
||||
}
|
||||
|
||||
int32x2_t vs2 = vqneg_s32(vqadd_s32(vget_low_s32(vs), vget_high_s32(vs)));
|
||||
|
||||
int s[2];
|
||||
vst1_s32(s, vs2);
|
||||
|
||||
result += (s[0] += s[1]);
|
||||
if (s[0] < 0 || result < 0)//case of overflow ~ 8GB of non-zeros...
|
||||
{
|
||||
return 0x7fFFffFF;
|
||||
}
|
||||
|
||||
for (; i < size.width; i++)
|
||||
result += (src[i] < std::numeric_limits<float>::min() && src[i] > -std::numeric_limits<float>::min())?0:1;
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
return 0x7fFFffFF;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
(void)_size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 countNonZero(const Size2D &_size,
|
||||
const f64 * srcBase, ptrdiff_t srcStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
Size2D size(_size);
|
||||
if (srcStride == (ptrdiff_t)(size.width))
|
||||
{
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
}
|
||||
size_t roiw8 = size.width & ~7u;
|
||||
size_t roiw4 = size.width & ~3u;
|
||||
size_t roiw2 = size.width & ~1u;
|
||||
uint64x2_t vmask1 = vdupq_n_u64(0x7fFFffFFffFFffFFULL); //will treat denormals as non-zero
|
||||
uint32x4_t vc0 = vmovq_n_u32(0);
|
||||
|
||||
s32 result = 0;
|
||||
for(size_t k = 0; k < size.height; ++k)
|
||||
{
|
||||
const f64* src = internal::getRowPtr( srcBase, srcStride, k);
|
||||
size_t i = 0;
|
||||
|
||||
int32x2_t vs1 = vmov_n_s32(0);
|
||||
int32x2_t vs2 = vmov_n_s32(0);
|
||||
int32x2_t vs3 = vmov_n_s32(0);
|
||||
int32x2_t vs4 = vmov_n_s32(0);
|
||||
|
||||
for (; i < roiw8; i += 8 )
|
||||
{
|
||||
internal::prefetch(src + i + 6);
|
||||
uint64x2_t vln1 = vld1q_u64((const u64*)(src + i));
|
||||
uint64x2_t vln2 = vld1q_u64((const u64*)(src + i + 2));
|
||||
uint64x2_t vln3 = vld1q_u64((const u64*)(src + i + 4));
|
||||
uint64x2_t vln4 = vld1q_u64((const u64*)(src + i + 6));
|
||||
|
||||
uint64x2_t vm1 = vandq_u64(vln1, vmask1);
|
||||
uint64x2_t vm2 = vandq_u64(vln2, vmask1);
|
||||
uint64x2_t vm3 = vandq_u64(vln3, vmask1);
|
||||
uint64x2_t vm4 = vandq_u64(vln4, vmask1);
|
||||
|
||||
uint32x4_t vequ1 = vceqq_u32(vreinterpretq_u32_u64(vm1), vc0);
|
||||
uint32x4_t vequ2 = vceqq_u32(vreinterpretq_u32_u64(vm2), vc0);
|
||||
uint32x4_t vequ3 = vceqq_u32(vreinterpretq_u32_u64(vm3), vc0);
|
||||
uint32x4_t vequ4 = vceqq_u32(vreinterpretq_u32_u64(vm4), vc0);
|
||||
|
||||
uint32x4_t vlx1 = vmvnq_u32(vequ1);
|
||||
uint32x4_t vlx2 = vmvnq_u32(vequ2);
|
||||
uint32x4_t vlx3 = vmvnq_u32(vequ3);
|
||||
uint32x4_t vlx4 = vmvnq_u32(vequ4);
|
||||
|
||||
int32x2_t vnz1 = vreinterpret_s32_u32(vpmax_u32(vget_low_u32(vlx1), vget_high_u32(vlx1)));
|
||||
int32x2_t vnz2 = vreinterpret_s32_u32(vpmax_u32(vget_low_u32(vlx2), vget_high_u32(vlx2)));
|
||||
int32x2_t vnz3 = vreinterpret_s32_u32(vpmax_u32(vget_low_u32(vlx3), vget_high_u32(vlx3)));
|
||||
int32x2_t vnz4 = vreinterpret_s32_u32(vpmax_u32(vget_low_u32(vlx4), vget_high_u32(vlx4)));
|
||||
|
||||
vs1 = vqadd_s32(vs1, vnz1);
|
||||
vs2 = vqadd_s32(vs2, vnz2);
|
||||
vs3 = vqadd_s32(vs3, vnz3);
|
||||
vs4 = vqadd_s32(vs4, vnz4);
|
||||
}
|
||||
|
||||
if (i < roiw4)
|
||||
{
|
||||
internal::prefetch(src + i + 2);
|
||||
uint64x2_t vln1 = vld1q_u64((const u64*)(src + i));
|
||||
uint64x2_t vln2 = vld1q_u64((const u64*)(src + i + 2));
|
||||
|
||||
uint64x2_t vm1 = vandq_u64(vln1, vmask1);
|
||||
uint64x2_t vm2 = vandq_u64(vln2, vmask1);
|
||||
|
||||
uint32x4_t vequ1 = vceqq_u32(vreinterpretq_u32_u64(vm1), vc0);
|
||||
uint32x4_t vequ2 = vceqq_u32(vreinterpretq_u32_u64(vm2), vc0);
|
||||
|
||||
uint32x4_t vlx1 = vmvnq_u32(vequ1);
|
||||
uint32x4_t vlx2 = vmvnq_u32(vequ2);
|
||||
|
||||
int32x2_t vnz1 = vreinterpret_s32_u32(vpmax_u32(vget_low_u32(vlx1), vget_high_u32(vlx1)));
|
||||
int32x2_t vnz2 = vreinterpret_s32_u32(vpmax_u32(vget_low_u32(vlx2), vget_high_u32(vlx2)));
|
||||
|
||||
vs1 = vqadd_s32(vs1, vnz1);
|
||||
vs2 = vqadd_s32(vs2, vnz2);
|
||||
i += 4;
|
||||
}
|
||||
|
||||
if (i < roiw2)
|
||||
{
|
||||
internal::prefetch(src + i);
|
||||
uint64x2_t vln1 = vld1q_u64((const u64*)(src + i));
|
||||
|
||||
uint64x2_t vm1 = vandq_u64(vln1, vmask1);
|
||||
|
||||
uint32x4_t vequ1 = vceqq_u32(vreinterpretq_u32_u64(vm1), vc0);
|
||||
|
||||
uint32x4_t vlx1 = vmvnq_u32(vequ1);
|
||||
|
||||
int32x2_t vnz1 = vreinterpret_s32_u32(vpmax_u32(vget_low_u32(vlx1), vget_high_u32(vlx1)));
|
||||
|
||||
vs1 = vqadd_s32(vs1, vnz1);
|
||||
i += 2;
|
||||
}
|
||||
|
||||
vs1 = vqadd_s32(vs1, vs2);
|
||||
vs3 = vqadd_s32(vs3, vs4);
|
||||
vs1 = vqadd_s32(vs1, vs3);
|
||||
int32x2_t vsneg = vqneg_s32(vs1);
|
||||
|
||||
s32 s[2];
|
||||
vst1_s32(s, vsneg);
|
||||
|
||||
result += (s[0] += s[1]);
|
||||
if (s[0] < 0 || result < 0)//case of overflow ~ 16GB of non-zeros...
|
||||
{
|
||||
return 0x7fFFffFF;
|
||||
}
|
||||
|
||||
for (; i < size.width; i++)
|
||||
result += (src[i] < std::numeric_limits<double>::min() && src[i] > -std::numeric_limits<double>::min())?0:1;
|
||||
if (result < 0)
|
||||
{
|
||||
return 0x7fFFffFF;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
(void)_size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+708
@@ -0,0 +1,708 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2016, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "vtransform.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <cfloat>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
namespace {
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
inline float32x4_t vroundq(const float32x4_t& v)
|
||||
{
|
||||
const int32x4_t signMask = vdupq_n_s32(1 << 31), half = vreinterpretq_s32_f32(vdupq_n_f32(0.5f));
|
||||
float32x4_t v_addition = vreinterpretq_f32_s32(vorrq_s32(half, vandq_s32(signMask, vreinterpretq_s32_f32(v))));
|
||||
return vaddq_f32(v, v_addition);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T divSaturateQ(const T &v1, const T &v2, const float scale)
|
||||
{
|
||||
return internal::vcombine(internal::vqmovn(divSaturateQ(internal::vmovl(internal::vget_low(v1)),
|
||||
internal::vmovl(internal::vget_low(v2)), scale)),
|
||||
internal::vqmovn(divSaturateQ(internal::vmovl(internal::vget_high(v1)),
|
||||
internal::vmovl(internal::vget_high(v2)), scale))
|
||||
);
|
||||
}
|
||||
template <>
|
||||
inline int32x4_t divSaturateQ<int32x4_t>(const int32x4_t &v1, const int32x4_t &v2, const float scale)
|
||||
{ return vcvtq_s32_f32(vroundq(vmulq_f32(vmulq_n_f32(vcvtq_f32_s32(v1), scale), internal::vrecpq_f32(vcvtq_f32_s32(v2))))); }
|
||||
template <>
|
||||
inline uint32x4_t divSaturateQ<uint32x4_t>(const uint32x4_t &v1, const uint32x4_t &v2, const float scale)
|
||||
{ return vcvtq_u32_f32(vroundq(vmulq_f32(vmulq_n_f32(vcvtq_f32_u32(v1), scale), internal::vrecpq_f32(vcvtq_f32_u32(v2))))); }
|
||||
|
||||
inline float32x2_t vround(const float32x2_t& v)
|
||||
{
|
||||
const int32x2_t signMask = vdup_n_s32(1 << 31), half = vreinterpret_s32_f32(vdup_n_f32(0.5f));
|
||||
float32x2_t v_addition = vreinterpret_f32_s32(vorr_s32(half, vand_s32(signMask, vreinterpret_s32_f32(v))));
|
||||
return vadd_f32(v, v_addition);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T divSaturate(const T &v1, const T &v2, const float scale)
|
||||
{
|
||||
return internal::vqmovn(divSaturateQ(internal::vmovl(v1), internal::vmovl(v2), scale));
|
||||
}
|
||||
template <>
|
||||
inline int32x2_t divSaturate<int32x2_t>(const int32x2_t &v1, const int32x2_t &v2, const float scale)
|
||||
{ return vcvt_s32_f32(vround(vmul_f32(vmul_n_f32(vcvt_f32_s32(v1), scale), internal::vrecp_f32(vcvt_f32_s32(v2))))); }
|
||||
template <>
|
||||
inline uint32x2_t divSaturate<uint32x2_t>(const uint32x2_t &v1, const uint32x2_t &v2, const float scale)
|
||||
{ return vcvt_u32_f32(vround(vmul_f32(vmul_n_f32(vcvt_f32_u32(v1), scale), internal::vrecp_f32(vcvt_f32_u32(v2))))); }
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline T divWrapQ(const T &v1, const T &v2, const float scale)
|
||||
{
|
||||
return internal::vcombine(internal::vmovn(divWrapQ(internal::vmovl(internal::vget_low(v1)),
|
||||
internal::vmovl(internal::vget_low(v2)), scale)),
|
||||
internal::vmovn(divWrapQ(internal::vmovl(internal::vget_high(v1)),
|
||||
internal::vmovl(internal::vget_high(v2)), scale))
|
||||
);
|
||||
}
|
||||
template <>
|
||||
inline int32x4_t divWrapQ<int32x4_t>(const int32x4_t &v1, const int32x4_t &v2, const float scale)
|
||||
{ return vcvtq_s32_f32(vmulq_f32(vmulq_n_f32(vcvtq_f32_s32(v1), scale), internal::vrecpq_f32(vcvtq_f32_s32(v2)))); }
|
||||
template <>
|
||||
inline uint32x4_t divWrapQ<uint32x4_t>(const uint32x4_t &v1, const uint32x4_t &v2, const float scale)
|
||||
{ return vcvtq_u32_f32(vmulq_f32(vmulq_n_f32(vcvtq_f32_u32(v1), scale), internal::vrecpq_f32(vcvtq_f32_u32(v2)))); }
|
||||
|
||||
template <typename T>
|
||||
inline T divWrap(const T &v1, const T &v2, const float scale)
|
||||
{
|
||||
return internal::vmovn(divWrapQ(internal::vmovl(v1), internal::vmovl(v2), scale));
|
||||
}
|
||||
template <>
|
||||
inline int32x2_t divWrap<int32x2_t>(const int32x2_t &v1, const int32x2_t &v2, const float scale)
|
||||
{ return vcvt_s32_f32(vmul_f32(vmul_n_f32(vcvt_f32_s32(v1), scale), internal::vrecp_f32(vcvt_f32_s32(v2)))); }
|
||||
template <>
|
||||
inline uint32x2_t divWrap<uint32x2_t>(const uint32x2_t &v1, const uint32x2_t &v2, const float scale)
|
||||
{ return vcvt_u32_f32(vmul_f32(vmul_n_f32(vcvt_f32_u32(v1), scale), internal::vrecp_f32(vcvt_f32_u32(v2)))); }
|
||||
|
||||
inline uint8x16_t vtstq(const uint8x16_t & v0, const uint8x16_t & v1) { return vtstq_u8 (v0, v1); }
|
||||
inline uint16x8_t vtstq(const uint16x8_t & v0, const uint16x8_t & v1) { return vtstq_u16(v0, v1); }
|
||||
inline uint32x4_t vtstq(const uint32x4_t & v0, const uint32x4_t & v1) { return vtstq_u32(v0, v1); }
|
||||
inline int8x16_t vtstq(const int8x16_t & v0, const int8x16_t & v1) { return vreinterpretq_s8_u8 (vtstq_s8 (v0, v1)); }
|
||||
inline int16x8_t vtstq(const int16x8_t & v0, const int16x8_t & v1) { return vreinterpretq_s16_u16(vtstq_s16(v0, v1)); }
|
||||
inline int32x4_t vtstq(const int32x4_t & v0, const int32x4_t & v1) { return vreinterpretq_s32_u32(vtstq_s32(v0, v1)); }
|
||||
|
||||
inline uint8x8_t vtst(const uint8x8_t & v0, const uint8x8_t & v1) { return vtst_u8 (v0, v1); }
|
||||
inline uint16x4_t vtst(const uint16x4_t & v0, const uint16x4_t & v1) { return vtst_u16(v0, v1); }
|
||||
inline uint32x2_t vtst(const uint32x2_t & v0, const uint32x2_t & v1) { return vtst_u32(v0, v1); }
|
||||
inline int8x8_t vtst(const int8x8_t & v0, const int8x8_t & v1) { return vreinterpret_s8_u8 (vtst_s8 (v0, v1)); }
|
||||
inline int16x4_t vtst(const int16x4_t & v0, const int16x4_t & v1) { return vreinterpret_s16_u16(vtst_s16(v0, v1)); }
|
||||
inline int32x2_t vtst(const int32x2_t & v0, const int32x2_t & v1) { return vreinterpret_s32_u32(vtst_s32(v0, v1)); }
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
void div(const Size2D &size,
|
||||
const T * src0Base, ptrdiff_t src0Stride,
|
||||
const T * src1Base, ptrdiff_t src1Stride,
|
||||
T * dstBase, ptrdiff_t dstStride,
|
||||
f32 scale,
|
||||
CONVERT_POLICY cpolicy)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
typedef typename internal::VecTraits<T>::vec128 vec128;
|
||||
typedef typename internal::VecTraits<T>::vec64 vec64;
|
||||
|
||||
if (scale == 0.0f ||
|
||||
(std::numeric_limits<T>::is_integer &&
|
||||
(scale * std::numeric_limits<T>::max()) < 1.0f &&
|
||||
(scale * std::numeric_limits<T>::max()) > -1.0f))
|
||||
{
|
||||
for (size_t y = 0; y < size.height; ++y)
|
||||
{
|
||||
T * dst = internal::getRowPtr(dstBase, dstStride, y);
|
||||
std::memset(dst, 0, sizeof(T) * size.width);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t step128 = 16 / sizeof(T);
|
||||
size_t roiw128 = size.width >= (step128 - 1) ? size.width - step128 + 1 : 0;
|
||||
const size_t step64 = 8 / sizeof(T);
|
||||
size_t roiw64 = size.width >= (step64 - 1) ? size.width - step64 + 1 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const T * src0 = internal::getRowPtr(src0Base, src0Stride, i);
|
||||
const T * src1 = internal::getRowPtr(src1Base, src1Stride, i);
|
||||
T * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
if (cpolicy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
for (; j < roiw128; j += step128)
|
||||
{
|
||||
internal::prefetch(src0 + j);
|
||||
internal::prefetch(src1 + j);
|
||||
|
||||
vec128 v_src0 = internal::vld1q(src0 + j);
|
||||
vec128 v_src1 = internal::vld1q(src1 + j);
|
||||
|
||||
vec128 v_mask = vtstq(v_src1,v_src1);
|
||||
internal::vst1q(dst + j, internal::vandq(v_mask, divSaturateQ(v_src0, v_src1, scale)));
|
||||
}
|
||||
for (; j < roiw64; j += step64)
|
||||
{
|
||||
vec64 v_src0 = internal::vld1(src0 + j);
|
||||
vec64 v_src1 = internal::vld1(src1 + j);
|
||||
|
||||
vec64 v_mask = vtst(v_src1,v_src1);
|
||||
internal::vst1(dst + j, internal::vand(v_mask,divSaturate(v_src0, v_src1, scale)));
|
||||
}
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = src1[j] ? internal::saturate_cast<T>(scale * src0[j] / src1[j]) : 0;
|
||||
}
|
||||
}
|
||||
else // CONVERT_POLICY_WRAP
|
||||
{
|
||||
for (; j < roiw128; j += step128)
|
||||
{
|
||||
internal::prefetch(src0 + j);
|
||||
internal::prefetch(src1 + j);
|
||||
|
||||
vec128 v_src0 = internal::vld1q(src0 + j);
|
||||
vec128 v_src1 = internal::vld1q(src1 + j);
|
||||
|
||||
vec128 v_mask = vtstq(v_src1,v_src1);
|
||||
internal::vst1q(dst + j, internal::vandq(v_mask, divWrapQ(v_src0, v_src1, scale)));
|
||||
}
|
||||
for (; j < roiw64; j += step64)
|
||||
{
|
||||
vec64 v_src0 = internal::vld1(src0 + j);
|
||||
vec64 v_src1 = internal::vld1(src1 + j);
|
||||
|
||||
vec64 v_mask = vtst(v_src1,v_src1);
|
||||
internal::vst1(dst + j, internal::vand(v_mask,divWrap(v_src0, v_src1, scale)));
|
||||
}
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = src1[j] ? (T)((s32)trunc(scale * src0[j] / src1[j])) : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)cpolicy;
|
||||
(void)scale;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
template <typename T>
|
||||
inline T recipSaturateQ(const T &v2, const float scale)
|
||||
{
|
||||
return internal::vcombine(internal::vqmovn(recipSaturateQ(internal::vmovl(internal::vget_low(v2)), scale)),
|
||||
internal::vqmovn(recipSaturateQ(internal::vmovl(internal::vget_high(v2)), scale))
|
||||
);
|
||||
}
|
||||
template <>
|
||||
inline int32x4_t recipSaturateQ<int32x4_t>(const int32x4_t &v2, const float scale)
|
||||
{ return vcvtq_s32_f32(vmulq_n_f32(internal::vrecpq_f32(vcvtq_f32_s32(v2)), scale)); }
|
||||
template <>
|
||||
inline uint32x4_t recipSaturateQ<uint32x4_t>(const uint32x4_t &v2, const float scale)
|
||||
{ return vcvtq_u32_f32(vmulq_n_f32(internal::vrecpq_f32(vcvtq_f32_u32(v2)), scale)); }
|
||||
|
||||
template <typename T>
|
||||
inline T recipSaturate(const T &v2, const float scale)
|
||||
{
|
||||
return internal::vqmovn(recipSaturateQ(internal::vmovl(v2), scale));
|
||||
}
|
||||
template <>
|
||||
inline int32x2_t recipSaturate<int32x2_t>(const int32x2_t &v2, const float scale)
|
||||
{ return vcvt_s32_f32(vmul_n_f32(internal::vrecp_f32(vcvt_f32_s32(v2)), scale)); }
|
||||
template <>
|
||||
inline uint32x2_t recipSaturate<uint32x2_t>(const uint32x2_t &v2, const float scale)
|
||||
{ return vcvt_u32_f32(vmul_n_f32(internal::vrecp_f32(vcvt_f32_u32(v2)), scale)); }
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline T recipWrapQ(const T &v2, const float scale)
|
||||
{
|
||||
return internal::vcombine(internal::vmovn(recipWrapQ(internal::vmovl(internal::vget_low(v2)), scale)),
|
||||
internal::vmovn(recipWrapQ(internal::vmovl(internal::vget_high(v2)), scale))
|
||||
);
|
||||
}
|
||||
template <>
|
||||
inline int32x4_t recipWrapQ<int32x4_t>(const int32x4_t &v2, const float scale)
|
||||
{ return vcvtq_s32_f32(vmulq_n_f32(internal::vrecpq_f32(vcvtq_f32_s32(v2)), scale)); }
|
||||
template <>
|
||||
inline uint32x4_t recipWrapQ<uint32x4_t>(const uint32x4_t &v2, const float scale)
|
||||
{ return vcvtq_u32_f32(vmulq_n_f32(internal::vrecpq_f32(vcvtq_f32_u32(v2)), scale)); }
|
||||
|
||||
template <typename T>
|
||||
inline T recipWrap(const T &v2, const float scale)
|
||||
{
|
||||
return internal::vmovn(recipWrapQ(internal::vmovl(v2), scale));
|
||||
}
|
||||
template <>
|
||||
inline int32x2_t recipWrap<int32x2_t>(const int32x2_t &v2, const float scale)
|
||||
{ return vcvt_s32_f32(vmul_n_f32(internal::vrecp_f32(vcvt_f32_s32(v2)), scale)); }
|
||||
template <>
|
||||
inline uint32x2_t recipWrap<uint32x2_t>(const uint32x2_t &v2, const float scale)
|
||||
{ return vcvt_u32_f32(vmul_n_f32(internal::vrecp_f32(vcvt_f32_u32(v2)), scale)); }
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
void recip(const Size2D &size,
|
||||
const T * src1Base, ptrdiff_t src1Stride,
|
||||
T * dstBase, ptrdiff_t dstStride,
|
||||
f32 scale,
|
||||
CONVERT_POLICY cpolicy)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
typedef typename internal::VecTraits<T>::vec128 vec128;
|
||||
typedef typename internal::VecTraits<T>::vec64 vec64;
|
||||
|
||||
if (scale == 0.0f ||
|
||||
(std::numeric_limits<T>::is_integer &&
|
||||
scale < 1.0f &&
|
||||
scale > -1.0f))
|
||||
{
|
||||
for (size_t y = 0; y < size.height; ++y)
|
||||
{
|
||||
T * dst = internal::getRowPtr(dstBase, dstStride, y);
|
||||
std::memset(dst, 0, sizeof(T) * size.width);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t step128 = 16 / sizeof(T);
|
||||
size_t roiw128 = size.width >= (step128 - 1) ? size.width - step128 + 1 : 0;
|
||||
const size_t step64 = 8 / sizeof(T);
|
||||
size_t roiw64 = size.width >= (step64 - 1) ? size.width - step64 + 1 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const T * src1 = internal::getRowPtr(src1Base, src1Stride, i);
|
||||
T * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
if (cpolicy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
for (; j < roiw128; j += step128)
|
||||
{
|
||||
internal::prefetch(src1 + j);
|
||||
|
||||
vec128 v_src1 = internal::vld1q(src1 + j);
|
||||
|
||||
vec128 v_mask = vtstq(v_src1,v_src1);
|
||||
internal::vst1q(dst + j, internal::vandq(v_mask, recipSaturateQ(v_src1, scale)));
|
||||
}
|
||||
for (; j < roiw64; j += step64)
|
||||
{
|
||||
vec64 v_src1 = internal::vld1(src1 + j);
|
||||
|
||||
vec64 v_mask = vtst(v_src1,v_src1);
|
||||
internal::vst1(dst + j, internal::vand(v_mask, recipSaturate(v_src1, scale)));
|
||||
}
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = src1[j] ? internal::saturate_cast<T>(scale / src1[j]) : 0;
|
||||
}
|
||||
}
|
||||
else // CONVERT_POLICY_WRAP
|
||||
{
|
||||
for (; j < roiw128; j += step128)
|
||||
{
|
||||
internal::prefetch(src1 + j);
|
||||
|
||||
vec128 v_src1 = internal::vld1q(src1 + j);
|
||||
|
||||
vec128 v_mask = vtstq(v_src1,v_src1);
|
||||
internal::vst1q(dst + j, internal::vandq(v_mask, recipWrapQ(v_src1, scale)));
|
||||
}
|
||||
for (; j < roiw64; j += step64)
|
||||
{
|
||||
vec64 v_src1 = internal::vld1(src1 + j);
|
||||
|
||||
vec64 v_mask = vtst(v_src1,v_src1);
|
||||
internal::vst1(dst + j, internal::vand(v_mask, recipWrap(v_src1, scale)));
|
||||
}
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = src1[j] ? (T)((s32)trunc(scale / src1[j])) : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)cpolicy;
|
||||
(void)scale;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void div(const Size2D &size,
|
||||
const u8 * src0Base, ptrdiff_t src0Stride,
|
||||
const u8 * src1Base, ptrdiff_t src1Stride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
f32 scale,
|
||||
CONVERT_POLICY cpolicy)
|
||||
{
|
||||
div<u8>(size, src0Base, src0Stride, src1Base, src1Stride, dstBase, dstStride, scale, cpolicy);
|
||||
}
|
||||
|
||||
void div(const Size2D &size,
|
||||
const s8 * src0Base, ptrdiff_t src0Stride,
|
||||
const s8 * src1Base, ptrdiff_t src1Stride,
|
||||
s8 * dstBase, ptrdiff_t dstStride,
|
||||
f32 scale,
|
||||
CONVERT_POLICY cpolicy)
|
||||
{
|
||||
div<s8>(size, src0Base, src0Stride, src1Base, src1Stride, dstBase, dstStride, scale, cpolicy);
|
||||
}
|
||||
|
||||
void div(const Size2D &size,
|
||||
const u16 * src0Base, ptrdiff_t src0Stride,
|
||||
const u16 * src1Base, ptrdiff_t src1Stride,
|
||||
u16 * dstBase, ptrdiff_t dstStride,
|
||||
f32 scale,
|
||||
CONVERT_POLICY cpolicy)
|
||||
{
|
||||
div<u16>(size, src0Base, src0Stride, src1Base, src1Stride, dstBase, dstStride, scale, cpolicy);
|
||||
}
|
||||
|
||||
void div(const Size2D &size,
|
||||
const s16 * src0Base, ptrdiff_t src0Stride,
|
||||
const s16 * src1Base, ptrdiff_t src1Stride,
|
||||
s16 * dstBase, ptrdiff_t dstStride,
|
||||
f32 scale,
|
||||
CONVERT_POLICY cpolicy)
|
||||
{
|
||||
div<s16>(size, src0Base, src0Stride, src1Base, src1Stride, dstBase, dstStride, scale, cpolicy);
|
||||
}
|
||||
|
||||
void div(const Size2D &size,
|
||||
const s32 * src0Base, ptrdiff_t src0Stride,
|
||||
const s32 * src1Base, ptrdiff_t src1Stride,
|
||||
s32 * dstBase, ptrdiff_t dstStride,
|
||||
f32 scale,
|
||||
CONVERT_POLICY cpolicy)
|
||||
{
|
||||
div<s32>(size, src0Base, src0Stride, src1Base, src1Stride, dstBase, dstStride, scale, cpolicy);
|
||||
}
|
||||
|
||||
void div(const Size2D &size,
|
||||
const f32 * src0Base, ptrdiff_t src0Stride,
|
||||
const f32 * src1Base, ptrdiff_t src1Stride,
|
||||
f32 * dstBase, ptrdiff_t dstStride,
|
||||
f32 scale)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
if (scale == 0.0f)
|
||||
{
|
||||
for (size_t y = 0; y < size.height; ++y)
|
||||
{
|
||||
f32 * dst = internal::getRowPtr(dstBase, dstStride, y);
|
||||
std::memset(dst, 0, sizeof(f32) * size.width);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float32x4_t v_zero = vdupq_n_f32(0.0f);
|
||||
|
||||
size_t roiw128 = size.width >= 3 ? size.width - 3 : 0;
|
||||
size_t roiw64 = size.width >= 1 ? size.width - 1 : 0;
|
||||
|
||||
if (std::fabs(scale - 1.0f) < FLT_EPSILON)
|
||||
{
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const f32 * src0 = internal::getRowPtr(src0Base, src0Stride, i);
|
||||
const f32 * src1 = internal::getRowPtr(src1Base, src1Stride, i);
|
||||
f32 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for (; j < roiw128; j += 4)
|
||||
{
|
||||
internal::prefetch(src0 + j);
|
||||
internal::prefetch(src1 + j);
|
||||
|
||||
float32x4_t v_src0 = vld1q_f32(src0 + j);
|
||||
float32x4_t v_src1 = vld1q_f32(src1 + j);
|
||||
|
||||
uint32x4_t v_mask = vceqq_f32(v_src1,v_zero);
|
||||
vst1q_f32(dst + j, vreinterpretq_f32_u32(vbicq_u32(
|
||||
vreinterpretq_u32_f32(vmulq_f32(v_src0, internal::vrecpq_f32(v_src1))), v_mask)));
|
||||
}
|
||||
|
||||
for (; j < roiw64; j += 2)
|
||||
{
|
||||
float32x2_t v_src0 = vld1_f32(src0 + j);
|
||||
float32x2_t v_src1 = vld1_f32(src1 + j);
|
||||
|
||||
uint32x2_t v_mask = vceq_f32(v_src1,vget_low_f32(v_zero));
|
||||
vst1_f32(dst + j, vreinterpret_f32_u32(vbic_u32(
|
||||
vreinterpret_u32_f32(vmul_f32(v_src0, internal::vrecp_f32(v_src1))), v_mask)));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = src1[j] ? src0[j] / src1[j] : 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const f32 * src0 = internal::getRowPtr(src0Base, src0Stride, i);
|
||||
const f32 * src1 = internal::getRowPtr(src1Base, src1Stride, i);
|
||||
f32 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for (; j < roiw128; j += 4)
|
||||
{
|
||||
internal::prefetch(src0 + j);
|
||||
internal::prefetch(src1 + j);
|
||||
|
||||
float32x4_t v_src0 = vld1q_f32(src0 + j);
|
||||
float32x4_t v_src1 = vld1q_f32(src1 + j);
|
||||
|
||||
uint32x4_t v_mask = vceqq_f32(v_src1,v_zero);
|
||||
vst1q_f32(dst + j, vreinterpretq_f32_u32(vbicq_u32(
|
||||
vreinterpretq_u32_f32(vmulq_f32(vmulq_n_f32(v_src0, scale),
|
||||
internal::vrecpq_f32(v_src1))), v_mask)));
|
||||
}
|
||||
|
||||
for (; j < roiw64; j += 2)
|
||||
{
|
||||
float32x2_t v_src0 = vld1_f32(src0 + j);
|
||||
float32x2_t v_src1 = vld1_f32(src1 + j);
|
||||
|
||||
uint32x2_t v_mask = vceq_f32(v_src1,vget_low_f32(v_zero));
|
||||
vst1_f32(dst + j, vreinterpret_f32_u32(vbic_u32(
|
||||
vreinterpret_u32_f32(vmul_f32(vmul_n_f32(v_src0, scale),
|
||||
internal::vrecp_f32(v_src1))), v_mask)));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = src1[j] ? src0[j] * scale / src1[j] : 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)scale;
|
||||
#endif
|
||||
}
|
||||
|
||||
void reciprocal(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
f32 scale,
|
||||
CONVERT_POLICY cpolicy)
|
||||
{
|
||||
recip<u8>(size, srcBase, srcStride, dstBase, dstStride, scale, cpolicy);
|
||||
}
|
||||
|
||||
void reciprocal(const Size2D &size,
|
||||
const s8 * srcBase, ptrdiff_t srcStride,
|
||||
s8 * dstBase, ptrdiff_t dstStride,
|
||||
f32 scale,
|
||||
CONVERT_POLICY cpolicy)
|
||||
{
|
||||
recip<s8>(size, srcBase, srcStride, dstBase, dstStride, scale, cpolicy);
|
||||
}
|
||||
|
||||
void reciprocal(const Size2D &size,
|
||||
const u16 * srcBase, ptrdiff_t srcStride,
|
||||
u16 * dstBase, ptrdiff_t dstStride,
|
||||
f32 scale,
|
||||
CONVERT_POLICY cpolicy)
|
||||
{
|
||||
recip<u16>(size, srcBase, srcStride, dstBase, dstStride, scale, cpolicy);
|
||||
}
|
||||
|
||||
void reciprocal(const Size2D &size,
|
||||
const s16 * srcBase, ptrdiff_t srcStride,
|
||||
s16 * dstBase, ptrdiff_t dstStride,
|
||||
f32 scale,
|
||||
CONVERT_POLICY cpolicy)
|
||||
{
|
||||
recip<s16>(size, srcBase, srcStride, dstBase, dstStride, scale, cpolicy);
|
||||
}
|
||||
|
||||
void reciprocal(const Size2D &size,
|
||||
const s32 * srcBase, ptrdiff_t srcStride,
|
||||
s32 * dstBase, ptrdiff_t dstStride,
|
||||
f32 scale,
|
||||
CONVERT_POLICY cpolicy)
|
||||
{
|
||||
recip<s32>(size, srcBase, srcStride, dstBase, dstStride, scale, cpolicy);
|
||||
}
|
||||
|
||||
void reciprocal(const Size2D &size,
|
||||
const f32 * srcBase, ptrdiff_t srcStride,
|
||||
f32 * dstBase, ptrdiff_t dstStride,
|
||||
f32 scale)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
if (scale == 0.0f)
|
||||
{
|
||||
for (size_t y = 0; y < size.height; ++y)
|
||||
{
|
||||
f32 * dst = internal::getRowPtr(dstBase, dstStride, y);
|
||||
std::memset(dst, 0, sizeof(f32) * size.width);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float32x4_t v_zero = vdupq_n_f32(0.0f);
|
||||
|
||||
size_t roiw128 = size.width >= 3 ? size.width - 3 : 0;
|
||||
size_t roiw64 = size.width >= 1 ? size.width - 1 : 0;
|
||||
|
||||
if (std::fabs(scale - 1.0f) < FLT_EPSILON)
|
||||
{
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const f32 * src1 = internal::getRowPtr(srcBase, srcStride, i);
|
||||
f32 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for (; j < roiw128; j += 4)
|
||||
{
|
||||
internal::prefetch(src1 + j);
|
||||
|
||||
float32x4_t v_src1 = vld1q_f32(src1 + j);
|
||||
|
||||
uint32x4_t v_mask = vceqq_f32(v_src1,v_zero);
|
||||
vst1q_f32(dst + j, vreinterpretq_f32_u32(vbicq_u32(
|
||||
vreinterpretq_u32_f32(internal::vrecpq_f32(v_src1)), v_mask)));
|
||||
}
|
||||
|
||||
for (; j < roiw64; j += 2)
|
||||
{
|
||||
float32x2_t v_src1 = vld1_f32(src1 + j);
|
||||
|
||||
uint32x2_t v_mask = vceq_f32(v_src1,vget_low_f32(v_zero));
|
||||
vst1_f32(dst + j, vreinterpret_f32_u32(vbic_u32(
|
||||
vreinterpret_u32_f32(internal::vrecp_f32(v_src1)), v_mask)));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = src1[j] ? 1.0f / src1[j] : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const f32 * src1 = internal::getRowPtr(srcBase, srcStride, i);
|
||||
f32 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for (; j < roiw128; j += 4)
|
||||
{
|
||||
internal::prefetch(src1 + j);
|
||||
|
||||
float32x4_t v_src1 = vld1q_f32(src1 + j);
|
||||
|
||||
uint32x4_t v_mask = vceqq_f32(v_src1,v_zero);
|
||||
vst1q_f32(dst + j, vreinterpretq_f32_u32(vbicq_u32(
|
||||
vreinterpretq_u32_f32(vmulq_n_f32(internal::vrecpq_f32(v_src1),
|
||||
scale)),v_mask)));
|
||||
}
|
||||
|
||||
for (; j < roiw64; j += 2)
|
||||
{
|
||||
float32x2_t v_src1 = vld1_f32(src1 + j);
|
||||
|
||||
uint32x2_t v_mask = vceq_f32(v_src1,vget_low_f32(v_zero));
|
||||
vst1_f32(dst + j, vreinterpret_f32_u32(vbic_u32(
|
||||
vreinterpret_u32_f32(vmul_n_f32(internal::vrecp_f32(v_src1),
|
||||
scale)), v_mask)));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = src1[j] ? scale / src1[j] : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)scale;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
+260
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2012-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
f64 dotProduct(const Size2D &_size,
|
||||
const u8 * src0Base, ptrdiff_t src0Stride,
|
||||
const u8 * src1Base, ptrdiff_t src1Stride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
Size2D size(_size);
|
||||
if (src0Stride == src1Stride &&
|
||||
src0Stride == (ptrdiff_t)(size.width))
|
||||
{
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
}
|
||||
|
||||
// It is possible to accumulate up to 66051 uchar multiplication results in uint32 without overflow
|
||||
// We process 16 elements and accumulate two new elements per step. So we could handle 66051/2*16 elements
|
||||
#define DOT_UINT_BLOCKSIZE 66050*8
|
||||
f64 result = 0.0;
|
||||
for (size_t row = 0; row < size.height; ++row)
|
||||
{
|
||||
const u8 * src0 = internal::getRowPtr(src0Base, src0Stride, row);
|
||||
const u8 * src1 = internal::getRowPtr(src1Base, src1Stride, row);
|
||||
|
||||
size_t i = 0;
|
||||
uint64x2_t ws = vmovq_n_u64(0);
|
||||
|
||||
while(i + 16 <= size.width)
|
||||
{
|
||||
size_t lim = std::min(i + DOT_UINT_BLOCKSIZE, size.width) - 16;
|
||||
|
||||
uint32x4_t s1 = vmovq_n_u32(0);
|
||||
uint32x4_t s2 = vmovq_n_u32(0);
|
||||
|
||||
for (; i <= lim; i += 16)
|
||||
{
|
||||
internal::prefetch(src0 + i);
|
||||
internal::prefetch(src1 + i);
|
||||
|
||||
uint8x16_t vs1 = vld1q_u8(src0 + i);
|
||||
uint8x16_t vs2 = vld1q_u8(src1 + i);
|
||||
|
||||
uint16x8_t vdot1 = vmull_u8(vget_low_u8(vs1), vget_low_u8(vs2));
|
||||
uint16x8_t vdot2 = vmull_u8(vget_high_u8(vs1), vget_high_u8(vs2));
|
||||
|
||||
s1 = vpadalq_u16(s1, vdot1);
|
||||
s2 = vpadalq_u16(s2, vdot2);
|
||||
}
|
||||
|
||||
ws = vpadalq_u32(ws, s1);
|
||||
ws = vpadalq_u32(ws, s2);
|
||||
}
|
||||
|
||||
if(i + 8 <= size.width)
|
||||
{
|
||||
uint8x8_t vs1 = vld1_u8(src0 + i);
|
||||
uint8x8_t vs2 = vld1_u8(src1 + i);
|
||||
|
||||
ws = vpadalq_u32(ws, vpaddlq_u16(vmull_u8(vs1, vs2)));
|
||||
i += 8;
|
||||
}
|
||||
|
||||
result += (double)vget_lane_u64(vadd_u64(vget_low_u64(ws), vget_high_u64(ws)), 0);
|
||||
|
||||
for (; i < size.width; ++i)
|
||||
result += s32(src0[i]) * s32(src1[i]);
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
(void)_size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
f64 dotProduct(const Size2D &_size,
|
||||
const s8 * src0Base, ptrdiff_t src0Stride,
|
||||
const s8 * src1Base, ptrdiff_t src1Stride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
Size2D size(_size);
|
||||
if (src0Stride == src1Stride &&
|
||||
src0Stride == (ptrdiff_t)(size.width))
|
||||
{
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
}
|
||||
|
||||
// It is possible to accumulate up to 131071 schar multiplication results in sint32 without overflow
|
||||
// We process 16 elements and accumulate two new elements per step. So we could handle 131071/2*16 elements
|
||||
#define DOT_INT_BLOCKSIZE 131070*8
|
||||
f64 result = 0.0;
|
||||
for (size_t row = 0; row < size.height; ++row)
|
||||
{
|
||||
const s8 * src0 = internal::getRowPtr(src0Base, src0Stride, row);
|
||||
const s8 * src1 = internal::getRowPtr(src1Base, src1Stride, row);
|
||||
|
||||
size_t i = 0;
|
||||
int64x2_t ws = vmovq_n_s64(0);
|
||||
|
||||
while(i + 16 <= size.width)
|
||||
{
|
||||
size_t lim = std::min(i + DOT_UINT_BLOCKSIZE, size.width) - 16;
|
||||
|
||||
int32x4_t s1 = vmovq_n_s32(0);
|
||||
int32x4_t s2 = vmovq_n_s32(0);
|
||||
|
||||
for (; i <= lim; i += 16)
|
||||
{
|
||||
internal::prefetch(src0 + i);
|
||||
internal::prefetch(src1 + i);
|
||||
|
||||
int8x16_t vs1 = vld1q_s8(src0 + i);
|
||||
int8x16_t vs2 = vld1q_s8(src1 + i);
|
||||
|
||||
int16x8_t vdot1 = vmull_s8(vget_low_s8(vs1), vget_low_s8(vs2));
|
||||
int16x8_t vdot2 = vmull_s8(vget_high_s8(vs1), vget_high_s8(vs2));
|
||||
|
||||
s1 = vpadalq_s16(s1, vdot1);
|
||||
s2 = vpadalq_s16(s2, vdot2);
|
||||
}
|
||||
|
||||
ws = vpadalq_s32(ws, s1);
|
||||
ws = vpadalq_s32(ws, s2);
|
||||
}
|
||||
|
||||
if(i + 8 <= size.width)
|
||||
{
|
||||
int8x8_t vs1 = vld1_s8(src0 + i);
|
||||
int8x8_t vs2 = vld1_s8(src1 + i);
|
||||
|
||||
ws = vpadalq_s32(ws, vpaddlq_s16(vmull_s8(vs1, vs2)));
|
||||
i += 8;
|
||||
}
|
||||
|
||||
result += (double)vget_lane_s64(vadd_s64(vget_low_s64(ws), vget_high_s64(ws)), 0);
|
||||
|
||||
for (; i < size.width; ++i)
|
||||
result += s32(src0[i]) * s32(src1[i]);
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
(void)_size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
f64 dotProduct(const Size2D &_size,
|
||||
const f32 * src0Base, ptrdiff_t src0Stride,
|
||||
const f32 * src1Base, ptrdiff_t src1Stride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
Size2D size(_size);
|
||||
if (src0Stride == src1Stride &&
|
||||
src0Stride == (ptrdiff_t)(size.width * sizeof(f32)))
|
||||
{
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
}
|
||||
|
||||
#define DOT_FLOAT_BLOCKSIZE (1 << 13)
|
||||
f64 result = 0.0;
|
||||
for (size_t row = 0; row < size.height; ++row)
|
||||
{
|
||||
const f32 * src0 = internal::getRowPtr(src0Base, src0Stride, row);
|
||||
const f32 * src1 = internal::getRowPtr(src1Base, src1Stride, row);
|
||||
|
||||
size_t i = 0;
|
||||
while(i + 4 <= size.width)
|
||||
{
|
||||
size_t lim = std::min(i + DOT_FLOAT_BLOCKSIZE, size.width) - 4;
|
||||
float32x4_t v_sum = vdupq_n_f32(0.0f);
|
||||
|
||||
for( ; i <= lim; i += 4 )
|
||||
{
|
||||
internal::prefetch(src0 + i);
|
||||
internal::prefetch(src1 + i);
|
||||
v_sum = vmlaq_f32(v_sum, vld1q_f32(src0 + i), vld1q_f32(src1 + i));
|
||||
}
|
||||
|
||||
float32x2_t vres = vpadd_f32(vget_low_f32(v_sum),vget_high_f32(v_sum));
|
||||
result += vget_lane_f32(vres, 0) + vget_lane_f32(vres, 1);
|
||||
}
|
||||
|
||||
if(i + 2 <= size.width)
|
||||
{
|
||||
float32x2_t vres = vmul_f32(vld1_f32(src0 + i), vld1_f32(src1 + i));
|
||||
result += vget_lane_f32(vres, 0) + vget_lane_f32(vres, 1);
|
||||
i += 2;
|
||||
}
|
||||
|
||||
for (; i < size.width; ++i)
|
||||
result += src0[i] * src1[i];
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
(void)_size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+428
@@ -0,0 +1,428 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2012-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
|
||||
/* This is FAST corner detector, contributed to OpenCV by the author, Edward Rosten.
|
||||
Below is the original copyright and the references */
|
||||
|
||||
/*
|
||||
Copyright (c) 2006, 2008 Edward Rosten
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
*Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
*Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
*Neither the name of the University of Cambridge nor the names of
|
||||
its contributors may 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 COPYRIGHT OWNER 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
The references are:
|
||||
* Machine learning for high-speed corner detection,
|
||||
E. Rosten and T. Drummond, ECCV 2006
|
||||
* Faster and better: A machine learning approach to corner detection
|
||||
E. Rosten, R. Porter and T. Drummond, PAMI, 2009
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
namespace
|
||||
{
|
||||
|
||||
void makeOffsets(ptrdiff_t pixel[], ptrdiff_t row_stride)
|
||||
{
|
||||
pixel[0] = 0 + row_stride * 3;
|
||||
pixel[1] = 1 + row_stride * 3;
|
||||
pixel[2] = 2 + row_stride * 2;
|
||||
pixel[3] = 3 + row_stride * 1;
|
||||
pixel[4] = 3 + row_stride * 0;
|
||||
pixel[5] = 3 + row_stride * -1;
|
||||
pixel[6] = 2 + row_stride * -2;
|
||||
pixel[7] = 1 + row_stride * -3;
|
||||
pixel[8] = 0 + row_stride * -3;
|
||||
pixel[9] = -1 + row_stride * -3;
|
||||
pixel[10] = -2 + row_stride * -2;
|
||||
pixel[11] = -3 + row_stride * -1;
|
||||
pixel[12] = -3 + row_stride * 0;
|
||||
pixel[13] = -3 + row_stride * 1;
|
||||
pixel[14] = -2 + row_stride * 2;
|
||||
pixel[15] = -1 + row_stride * 3;
|
||||
}
|
||||
|
||||
u8 cornerScore(const u8* ptr, const ptrdiff_t pixel[])
|
||||
{
|
||||
const s32 K = 8, N = 16 + K + 1;
|
||||
s32 k, v = ptr[0];
|
||||
s16 d[(N + 7) & ~7];
|
||||
for( k = 0; k < N; k++ )
|
||||
d[k] = (s16)(v - ptr[pixel[k]]);
|
||||
|
||||
int16x8_t q0 = vdupq_n_s16((s16)(-1000));
|
||||
int16x8_t q1 = vdupq_n_s16((s16)(1000));
|
||||
|
||||
int16x8_t d0_7 = vld1q_s16(d + 0);
|
||||
int16x8_t d8_15 = vld1q_s16(d + 8);
|
||||
int16x8_t d16_23 = vld1q_s16(d + 16);
|
||||
int16x8_t d24 = vld1q_s16(d + 24);
|
||||
|
||||
//k == 0
|
||||
int16x8_t v0k0 = vextq_s16(d0_7, d8_15, 1);
|
||||
int16x8_t v1k0 = vextq_s16(d0_7, d8_15, 2);
|
||||
int16x8_t ak0 = vminq_s16(v0k0, v1k0);
|
||||
int16x8_t bk0 = vmaxq_s16(v0k0, v1k0);
|
||||
|
||||
v0k0 = vextq_s16(d0_7, d8_15, 3);
|
||||
ak0 = vminq_s16(ak0, v0k0);
|
||||
bk0 = vmaxq_s16(bk0, v0k0);
|
||||
|
||||
v1k0 = vextq_s16(d0_7, d8_15, 4);
|
||||
ak0 = vminq_s16(ak0, v1k0);
|
||||
bk0 = vmaxq_s16(bk0, v1k0);
|
||||
|
||||
v0k0 = vextq_s16(d0_7, d8_15, 5);
|
||||
ak0 = vminq_s16(ak0, v0k0);
|
||||
bk0 = vmaxq_s16(bk0, v0k0);
|
||||
|
||||
v1k0 = vextq_s16(d0_7, d8_15, 6);
|
||||
ak0 = vminq_s16(ak0, v1k0);
|
||||
bk0 = vmaxq_s16(bk0, v1k0);
|
||||
|
||||
v0k0 = vextq_s16(d0_7, d8_15, 7);
|
||||
ak0 = vminq_s16(ak0, v0k0);
|
||||
bk0 = vmaxq_s16(bk0, v0k0);
|
||||
|
||||
ak0 = vminq_s16(ak0, d8_15);
|
||||
bk0 = vmaxq_s16(bk0, d8_15);
|
||||
|
||||
q0 = vmaxq_s16(q0, vminq_s16(ak0, d0_7));
|
||||
q1 = vminq_s16(q1, vmaxq_s16(bk0, d0_7));
|
||||
|
||||
v1k0 = vextq_s16(d8_15, d16_23, 1);
|
||||
q0 = vmaxq_s16(q0, vminq_s16(ak0, v1k0));
|
||||
q1 = vminq_s16(q1, vmaxq_s16(bk0, v1k0));
|
||||
|
||||
//k == 8
|
||||
int16x8_t v0k8 = v1k0;
|
||||
int16x8_t v1k8 = vextq_s16(d8_15, d16_23, 2);
|
||||
int16x8_t ak8 = vminq_s16(v0k8, v1k8);
|
||||
int16x8_t bk8 = vmaxq_s16(v0k8, v1k8);
|
||||
|
||||
v0k8 = vextq_s16(d8_15, d16_23, 3);
|
||||
ak8 = vminq_s16(ak8, v0k8);
|
||||
bk8 = vmaxq_s16(bk8, v0k8);
|
||||
|
||||
v1k8 = vextq_s16(d8_15, d16_23, 4);
|
||||
ak8 = vminq_s16(ak8, v1k8);
|
||||
bk8 = vmaxq_s16(bk8, v1k8);
|
||||
|
||||
v0k8 = vextq_s16(d8_15, d16_23, 5);
|
||||
ak8 = vminq_s16(ak8, v0k8);
|
||||
bk8 = vmaxq_s16(bk8, v0k8);
|
||||
|
||||
v1k8 = vextq_s16(d8_15, d16_23, 6);
|
||||
ak8 = vminq_s16(ak8, v1k8);
|
||||
bk8 = vmaxq_s16(bk8, v1k8);
|
||||
|
||||
v0k8 = vextq_s16(d8_15, d16_23, 7);
|
||||
ak8 = vminq_s16(ak8, v0k8);
|
||||
bk8 = vmaxq_s16(bk8, v0k8);
|
||||
|
||||
ak8 = vminq_s16(ak8, d16_23);
|
||||
bk8 = vmaxq_s16(bk8, d16_23);
|
||||
|
||||
q0 = vmaxq_s16(q0, vminq_s16(ak8, d8_15));
|
||||
q1 = vminq_s16(q1, vmaxq_s16(bk8, d8_15));
|
||||
|
||||
v1k8 = vextq_s16(d16_23, d24, 1);
|
||||
q0 = vmaxq_s16(q0, vminq_s16(ak8, v1k8));
|
||||
q1 = vminq_s16(q1, vmaxq_s16(bk8, v1k8));
|
||||
|
||||
//fin
|
||||
int16x8_t q = vmaxq_s16(q0, vsubq_s16(vmovq_n_s16(0), q1));
|
||||
int16x4_t q2 = vmax_s16(vget_low_s16(q), vget_high_s16(q));
|
||||
int32x4_t q2w = vmovl_s16(q2);
|
||||
int32x2_t q4 = vmax_s32(vget_low_s32(q2w), vget_high_s32(q2w));
|
||||
int32x2_t q8 = vmax_s32(q4, vreinterpret_s32_s64(vshr_n_s64(vreinterpret_s64_s32(q4), 32)));
|
||||
|
||||
return (u8)(vget_lane_s32(q8, 0) - 1);
|
||||
}
|
||||
|
||||
} //namespace
|
||||
#endif
|
||||
|
||||
void FAST(const Size2D &size,
|
||||
u8 *srcBase, ptrdiff_t srcStride,
|
||||
KeypointStore *keypoints,
|
||||
u8 threshold, bool nonmax_suppression)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
//keypoints.clear();
|
||||
|
||||
const s32 K = 8, N = 16 + K + 1;
|
||||
ptrdiff_t i, j, k, pixel[N];
|
||||
makeOffsets(pixel, srcStride);
|
||||
for(k = 16; k < N; k++)
|
||||
pixel[k] = pixel[k - 16];
|
||||
|
||||
uint8x16_t delta = vdupq_n_u8(128);
|
||||
uint8x16_t t = vdupq_n_u8(threshold);
|
||||
uint8x16_t K16 = vdupq_n_u8((u8)K);
|
||||
|
||||
u8 threshold_tab[512];
|
||||
for( i = -255; i <= 255; i++ )
|
||||
threshold_tab[i+255] = (u8)(i < -threshold ? 1 : i > threshold ? 2 : 0);
|
||||
|
||||
std::vector<u8> _buf((size.width+16)*3*(sizeof(ptrdiff_t) + sizeof(u8)) + 128);
|
||||
u8* buf[3];
|
||||
buf[0] = &_buf[0]; buf[1] = buf[0] + size.width; buf[2] = buf[1] + size.width;
|
||||
ptrdiff_t* cpbuf[3];
|
||||
cpbuf[0] = (ptrdiff_t*)internal::alignPtr(buf[2] + size.width, sizeof(ptrdiff_t)) + 1;
|
||||
cpbuf[1] = cpbuf[0] + size.width + 1;
|
||||
cpbuf[2] = cpbuf[1] + size.width + 1;
|
||||
memset(buf[0], 0, size.width*3);
|
||||
|
||||
for(i = 3; i < (ptrdiff_t)size.height-2; i++)
|
||||
{
|
||||
const u8* ptr = internal::getRowPtr(srcBase, srcStride, i) + 3;
|
||||
u8* curr = buf[(i - 3)%3];
|
||||
ptrdiff_t* cornerpos = cpbuf[(i - 3)%3];
|
||||
memset(curr, 0, size.width);
|
||||
ptrdiff_t ncorners = 0;
|
||||
|
||||
if( i < (ptrdiff_t)size.height - 3 )
|
||||
{
|
||||
j = 3;
|
||||
|
||||
for(; j < (ptrdiff_t)size.width - 16 - 3; j += 16, ptr += 16)
|
||||
{
|
||||
internal::prefetch(ptr);
|
||||
internal::prefetch(ptr + pixel[0]);
|
||||
internal::prefetch(ptr + pixel[2]);
|
||||
|
||||
uint8x16_t v0 = vld1q_u8(ptr);
|
||||
int8x16_t v1 = vreinterpretq_s8_u8(veorq_u8(vqsubq_u8(v0, t), delta));
|
||||
int8x16_t v2 = vreinterpretq_s8_u8(veorq_u8(vqaddq_u8(v0, t), delta));
|
||||
|
||||
int8x16_t x0 = vreinterpretq_s8_u8(vsubq_u8(vld1q_u8(ptr + pixel[0]), delta));
|
||||
int8x16_t x1 = vreinterpretq_s8_u8(vsubq_u8(vld1q_u8(ptr + pixel[4]), delta));
|
||||
int8x16_t x2 = vreinterpretq_s8_u8(vsubq_u8(vld1q_u8(ptr + pixel[8]), delta));
|
||||
int8x16_t x3 = vreinterpretq_s8_u8(vsubq_u8(vld1q_u8(ptr + pixel[12]), delta));
|
||||
|
||||
uint8x16_t m0 = vandq_u8(vcgtq_s8(x0, v2), vcgtq_s8(x1, v2));
|
||||
uint8x16_t m1 = vandq_u8(vcgtq_s8(v1, x0), vcgtq_s8(v1, x1));
|
||||
m0 = vorrq_u8(m0, vandq_u8(vcgtq_s8(x1, v2), vcgtq_s8(x2, v2)));
|
||||
m1 = vorrq_u8(m1, vandq_u8(vcgtq_s8(v1, x1), vcgtq_s8(v1, x2)));
|
||||
m0 = vorrq_u8(m0, vandq_u8(vcgtq_s8(x2, v2), vcgtq_s8(x3, v2)));
|
||||
m1 = vorrq_u8(m1, vandq_u8(vcgtq_s8(v1, x2), vcgtq_s8(v1, x3)));
|
||||
m0 = vorrq_u8(m0, vandq_u8(vcgtq_s8(x3, v2), vcgtq_s8(x0, v2)));
|
||||
m1 = vorrq_u8(m1, vandq_u8(vcgtq_s8(v1, x3), vcgtq_s8(v1, x0)));
|
||||
m0 = vorrq_u8(m0, m1);
|
||||
|
||||
u64 mask[2];
|
||||
vst1q_u64(mask, vreinterpretq_u64_u8(m0));
|
||||
|
||||
if( mask[0] == 0 )
|
||||
{
|
||||
if (mask[1] != 0)
|
||||
{
|
||||
j -= 8;
|
||||
ptr -= 8;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
uint8x16_t c0 = vmovq_n_u8(0);
|
||||
uint8x16_t c1 = vmovq_n_u8(0);
|
||||
uint8x16_t max0 = vmovq_n_u8(0);
|
||||
uint8x16_t max1 = vmovq_n_u8(0);
|
||||
for( k = 0; k < N; k++ )
|
||||
{
|
||||
int8x16_t x = vreinterpretq_s8_u8(veorq_u8(vld1q_u8(ptr + pixel[k]), delta));
|
||||
m0 = vcgtq_s8(x, v2);
|
||||
m1 = vcgtq_s8(v1, x);
|
||||
|
||||
c0 = vandq_u8(vsubq_u8(c0, m0), m0);
|
||||
c1 = vandq_u8(vsubq_u8(c1, m1), m1);
|
||||
|
||||
max0 = vmaxq_u8(max0, c0);
|
||||
max1 = vmaxq_u8(max1, c1);
|
||||
}
|
||||
|
||||
max0 = vmaxq_u8(max0, max1);
|
||||
u8 m[16];
|
||||
vst1q_u8(m, vcgtq_u8(max0, K16));
|
||||
|
||||
for( k = 0; k < 16; ++k )
|
||||
if(m[k])
|
||||
{
|
||||
cornerpos[ncorners++] = j+k;
|
||||
if(nonmax_suppression)
|
||||
curr[j+k] = cornerScore(ptr+k, pixel);
|
||||
}
|
||||
}
|
||||
|
||||
for( ; j < (s32)size.width - 3; j++, ptr++ )
|
||||
{
|
||||
s32 v = ptr[0];
|
||||
const u8* tab = &threshold_tab[0] - v + 255;
|
||||
s32 d = tab[ptr[pixel[0]]] | tab[ptr[pixel[8]]];
|
||||
|
||||
if( d == 0 )
|
||||
continue;
|
||||
|
||||
d &= tab[ptr[pixel[2]]] | tab[ptr[pixel[10]]];
|
||||
d &= tab[ptr[pixel[4]]] | tab[ptr[pixel[12]]];
|
||||
d &= tab[ptr[pixel[6]]] | tab[ptr[pixel[14]]];
|
||||
|
||||
if( d == 0 )
|
||||
continue;
|
||||
|
||||
d &= tab[ptr[pixel[1]]] | tab[ptr[pixel[9]]];
|
||||
d &= tab[ptr[pixel[3]]] | tab[ptr[pixel[11]]];
|
||||
d &= tab[ptr[pixel[5]]] | tab[ptr[pixel[13]]];
|
||||
d &= tab[ptr[pixel[7]]] | tab[ptr[pixel[15]]];
|
||||
|
||||
if( d & 1 )
|
||||
{
|
||||
s32 vt = v - threshold, count = 0;
|
||||
|
||||
for( k = 0; k < N; k++ )
|
||||
{
|
||||
s32 x = ptr[pixel[k]];
|
||||
if(x < vt)
|
||||
{
|
||||
if( ++count > K )
|
||||
{
|
||||
cornerpos[ncorners++] = j;
|
||||
if(nonmax_suppression)
|
||||
curr[j] = cornerScore(ptr, pixel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( d & 2 )
|
||||
{
|
||||
s32 vt = v + threshold, count = 0;
|
||||
|
||||
for( k = 0; k < N; k++ )
|
||||
{
|
||||
s32 x = ptr[pixel[k]];
|
||||
if(x > vt)
|
||||
{
|
||||
if( ++count > K )
|
||||
{
|
||||
cornerpos[ncorners++] = j;
|
||||
if(nonmax_suppression)
|
||||
curr[j] = cornerScore(ptr, pixel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cornerpos[-1] = ncorners;
|
||||
|
||||
if( i == 3 )
|
||||
continue;
|
||||
|
||||
const u8* prev = buf[(i - 4 + 3)%3];
|
||||
const u8* pprev = buf[(i - 5 + 3)%3];
|
||||
cornerpos = cpbuf[(i - 4 + 3)%3];
|
||||
ncorners = cornerpos[-1];
|
||||
|
||||
for( k = 0; k < ncorners; k++ )
|
||||
{
|
||||
j = cornerpos[k];
|
||||
s32 score = prev[j];
|
||||
if( !nonmax_suppression ||
|
||||
(score > prev[j+1] && score > prev[j-1] &&
|
||||
score > pprev[j-1] && score > pprev[j] && score > pprev[j+1] &&
|
||||
score > curr[j-1] && score > curr[j] && score > curr[j+1]) )
|
||||
{
|
||||
keypoints->push((f32)j, (f32)(i-1), 7.f, -1, (f32)score);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)keypoints;
|
||||
(void)threshold;
|
||||
(void)nonmax_suppression;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
+442
@@ -0,0 +1,442 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
void process(const T * src, size_t j0, size_t j1, size_t i,
|
||||
T minVal, size_t * minLocPtr, s32 & minLocCount, s32 minLocCapacity,
|
||||
T maxVal, size_t * maxLocPtr, s32 & maxLocCount, s32 maxLocCapacity)
|
||||
{
|
||||
for (size_t j = j0; j < j1; ++j)
|
||||
{
|
||||
T val = src[j];
|
||||
|
||||
if (val == maxVal)
|
||||
{
|
||||
if (maxLocCount < maxLocCapacity)
|
||||
{
|
||||
maxLocPtr[maxLocCount] = j;
|
||||
maxLocPtr[maxLocCount + 1] = i;
|
||||
}
|
||||
maxLocCount += 2;
|
||||
}
|
||||
|
||||
if (val == minVal)
|
||||
{
|
||||
if (minLocCount < minLocCapacity)
|
||||
{
|
||||
minLocPtr[minLocCount] = j;
|
||||
minLocPtr[minLocCount + 1] = i;
|
||||
}
|
||||
minLocCount += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
void fillMinMaxLocs(const Size2D & size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 minVal, size_t * minLocPtr, s32 & minLocCount, s32 minLocCapacity,
|
||||
u8 maxVal, size_t * maxLocPtr, s32 & maxLocCount, s32 maxLocCapacity)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
size_t roiw16 = size.width >= 15 ? size.width - 15 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
uint8x16_t v_maxval16 = vdupq_n_u8(maxVal), v_minval16 = vdupq_n_u8(minVal);
|
||||
uint8x8_t v_maxval8 = vdup_n_u8(maxVal), v_minval8 = vdup_n_u8(minVal);
|
||||
|
||||
u64 mask[2] = { 0ul };
|
||||
|
||||
minLocCapacity <<= 1;
|
||||
maxLocCapacity <<= 1;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const u8 * src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for ( ; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
uint8x16_t v_src = vld1q_u8(src + j);
|
||||
|
||||
uint8x16_t v_maxmask = vceqq_u8(v_src, v_maxval16);
|
||||
uint8x16_t v_minmask = vceqq_u8(v_src, v_minval16);
|
||||
uint8x16_t v_mask = vorrq_u8(v_maxmask, v_minmask);
|
||||
|
||||
vst1q_u8((u8 *)&mask[0], v_mask);
|
||||
|
||||
if (mask[0])
|
||||
process(src, j, j + 8, i,
|
||||
minVal, minLocPtr, minLocCount, minLocCapacity,
|
||||
maxVal, maxLocPtr, maxLocCount, maxLocCapacity);
|
||||
if (mask[1])
|
||||
process(src, j + 8, j + 16, i,
|
||||
minVal, minLocPtr, minLocCount, minLocCapacity,
|
||||
maxVal, maxLocPtr, maxLocCount, maxLocCapacity);
|
||||
}
|
||||
for ( ; j < roiw8; j += 8)
|
||||
{
|
||||
uint8x8_t v_src = vld1_u8(src + j);
|
||||
|
||||
uint8x8_t v_maxmask = vceq_u8(v_src, v_maxval8);
|
||||
uint8x8_t v_minmask = vceq_u8(v_src, v_minval8);
|
||||
uint8x8_t v_mask = vorr_u8(v_maxmask, v_minmask);
|
||||
|
||||
vst1_u8((u8 *)&mask[0], v_mask);
|
||||
|
||||
if (mask[0])
|
||||
process(src, j, j + 8, i,
|
||||
minVal, minLocPtr, minLocCount, minLocCapacity,
|
||||
maxVal, maxLocPtr, maxLocCount, maxLocCapacity);
|
||||
}
|
||||
|
||||
process(src, j, size.width, i,
|
||||
minVal, minLocPtr, minLocCount, minLocCapacity,
|
||||
maxVal, maxLocPtr, maxLocCount, maxLocCapacity);
|
||||
}
|
||||
|
||||
minLocCount >>= 1;
|
||||
maxLocCount >>= 1;
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)minVal;
|
||||
(void)minLocPtr;
|
||||
(void)minLocCount;
|
||||
(void)minLocCapacity;
|
||||
(void)maxVal;
|
||||
(void)maxLocPtr;
|
||||
(void)maxLocCount;
|
||||
(void)maxLocCapacity;
|
||||
#endif
|
||||
}
|
||||
|
||||
void fillMinMaxLocs(const Size2D & size,
|
||||
const u16 * srcBase, ptrdiff_t srcStride,
|
||||
u16 minVal, size_t * minLocPtr, s32 & minLocCount, s32 minLocCapacity,
|
||||
u16 maxVal, size_t * maxLocPtr, s32 & maxLocCount, s32 maxLocCapacity)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
size_t roiw16 = size.width >= 15 ? size.width - 15 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
uint16x8_t v_maxval8 = vdupq_n_u16(maxVal),
|
||||
v_minval8 = vdupq_n_u16(minVal);
|
||||
u64 mask[2] = { 0ul };
|
||||
|
||||
minLocCapacity <<= 1;
|
||||
maxLocCapacity <<= 1;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const u16 * src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for ( ; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
uint16x8_t v_src0 = vld1q_u16(src + j), v_src1 = vld1q_u16(src + j + 8);
|
||||
|
||||
uint16x8_t v_mask0 = vorrq_u16(vceqq_u16(v_src0, v_maxval8), vceqq_u16(v_src0, v_minval8));
|
||||
uint16x8_t v_mask1 = vorrq_u16(vceqq_u16(v_src1, v_maxval8), vceqq_u16(v_src1, v_minval8));
|
||||
|
||||
vst1q_u8((u8 *)&mask[0], vcombine_u8(vmovn_u16(v_mask0), vmovn_u16(v_mask1)));
|
||||
|
||||
if (mask[0])
|
||||
process(src, j, j + 8, i,
|
||||
minVal, minLocPtr, minLocCount, minLocCapacity,
|
||||
maxVal, maxLocPtr, maxLocCount, maxLocCapacity);
|
||||
if (mask[1])
|
||||
process(src, j + 8, j + 16, i,
|
||||
minVal, minLocPtr, minLocCount, minLocCapacity,
|
||||
maxVal, maxLocPtr, maxLocCount, maxLocCapacity);
|
||||
}
|
||||
for ( ; j < roiw8; j += 8)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
uint16x8_t v_src = vld1q_u16(src + j);
|
||||
|
||||
uint16x8_t v_maxmask = vceqq_u16(v_src, v_maxval8);
|
||||
uint16x8_t v_minmask = vceqq_u16(v_src, v_minval8);
|
||||
uint16x8_t v_mask = vorrq_u16(v_maxmask, v_minmask);
|
||||
|
||||
vst1_u8((u8 *)&mask[0], vmovn_u16(v_mask));
|
||||
|
||||
if (mask[0])
|
||||
process(src, j, j + 8, i,
|
||||
minVal, minLocPtr, minLocCount, minLocCapacity,
|
||||
maxVal, maxLocPtr, maxLocCount, maxLocCapacity);
|
||||
}
|
||||
|
||||
process(src, j, size.width, i,
|
||||
minVal, minLocPtr, minLocCount, minLocCapacity,
|
||||
maxVal, maxLocPtr, maxLocCount, maxLocCapacity);
|
||||
}
|
||||
|
||||
minLocCount >>= 1;
|
||||
maxLocCount >>= 1;
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)minVal;
|
||||
(void)minLocPtr;
|
||||
(void)minLocCount;
|
||||
(void)minLocCapacity;
|
||||
(void)maxVal;
|
||||
(void)maxLocPtr;
|
||||
(void)maxLocCount;
|
||||
(void)maxLocCapacity;
|
||||
#endif
|
||||
}
|
||||
|
||||
void fillMinMaxLocs(const Size2D & size,
|
||||
const s16 * srcBase, ptrdiff_t srcStride,
|
||||
s16 minVal, size_t * minLocPtr, s32 & minLocCount, s32 minLocCapacity,
|
||||
s16 maxVal, size_t * maxLocPtr, s32 & maxLocCount, s32 maxLocCapacity)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
size_t roiw16 = size.width >= 15 ? size.width - 15 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
int16x8_t v_maxval8 = vdupq_n_s16(maxVal),
|
||||
v_minval8 = vdupq_n_s16(minVal);
|
||||
u64 mask[2] = { 0ul };
|
||||
|
||||
minLocCapacity <<= 1;
|
||||
maxLocCapacity <<= 1;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const s16 * src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for ( ; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
int16x8_t v_src0 = vld1q_s16(src + j), v_src1 = vld1q_s16(src + j + 8);
|
||||
|
||||
uint16x8_t v_mask0 = vorrq_u16(vceqq_s16(v_src0, v_maxval8), vceqq_s16(v_src0, v_minval8));
|
||||
uint16x8_t v_mask1 = vorrq_u16(vceqq_s16(v_src1, v_maxval8), vceqq_s16(v_src1, v_minval8));
|
||||
|
||||
vst1q_u8((u8 *)&mask[0], vcombine_u8(vmovn_u16(v_mask0), vmovn_u16(v_mask1)));
|
||||
|
||||
if (mask[0])
|
||||
process(src, j, j + 8, i,
|
||||
minVal, minLocPtr, minLocCount, minLocCapacity,
|
||||
maxVal, maxLocPtr, maxLocCount, maxLocCapacity);
|
||||
if (mask[1])
|
||||
process(src, j + 8, j + 16, i,
|
||||
minVal, minLocPtr, minLocCount, minLocCapacity,
|
||||
maxVal, maxLocPtr, maxLocCount, maxLocCapacity);
|
||||
}
|
||||
for ( ; j < roiw8; j += 8)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
int16x8_t v_src = vld1q_s16(src + j);
|
||||
|
||||
uint16x8_t v_maxmask = vceqq_s16(v_src, v_maxval8);
|
||||
uint16x8_t v_minmask = vceqq_s16(v_src, v_minval8);
|
||||
uint16x8_t v_mask = vorrq_u16(v_maxmask, v_minmask);
|
||||
|
||||
vst1_u8((u8 *)&mask[0], vmovn_u16(v_mask));
|
||||
|
||||
if (mask[0])
|
||||
process(src, j, j + 8, i,
|
||||
minVal, minLocPtr, minLocCount, minLocCapacity,
|
||||
maxVal, maxLocPtr, maxLocCount, maxLocCapacity);
|
||||
}
|
||||
|
||||
process(src, j, size.width, i,
|
||||
minVal, minLocPtr, minLocCount, minLocCapacity,
|
||||
maxVal, maxLocPtr, maxLocCount, maxLocCapacity);
|
||||
}
|
||||
|
||||
minLocCount >>= 1;
|
||||
maxLocCount >>= 1;
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)minVal;
|
||||
(void)minLocPtr;
|
||||
(void)minLocCount;
|
||||
(void)minLocCapacity;
|
||||
(void)maxVal;
|
||||
(void)maxLocPtr;
|
||||
(void)maxLocCount;
|
||||
(void)maxLocCapacity;
|
||||
#endif
|
||||
}
|
||||
|
||||
void fillMinMaxLocs(const Size2D & size,
|
||||
const s32 * srcBase, ptrdiff_t srcStride,
|
||||
s32 minVal, size_t * minLocPtr, s32 & minLocCount, s32 minLocCapacity,
|
||||
s32 maxVal, size_t * maxLocPtr, s32 & maxLocCount, s32 maxLocCapacity)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
int32x4_t v_maxval4 = vdupq_n_s32(maxVal),
|
||||
v_minval4 = vdupq_n_s32(minVal);
|
||||
u64 mask = 0ul;
|
||||
|
||||
minLocCapacity <<= 1;
|
||||
maxLocCapacity <<= 1;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const s32 * src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for ( ; j < roiw8; j += 8)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
int32x4_t v_src0 = vld1q_s32(src + j), v_src1 = vld1q_s32(src + j + 4);
|
||||
|
||||
uint32x4_t v_mask0 = vorrq_u32(vceqq_s32(v_src0, v_maxval4), vceqq_s32(v_src0, v_minval4));
|
||||
uint32x4_t v_mask1 = vorrq_u32(vceqq_s32(v_src1, v_maxval4), vceqq_s32(v_src1, v_minval4));
|
||||
|
||||
vst1_u8((u8 *)&mask, vmovn_u16(vcombine_u16(vmovn_u32(v_mask0), vmovn_u32(v_mask1))));
|
||||
|
||||
if (mask)
|
||||
process(src, j, j + 8, i,
|
||||
minVal, minLocPtr, minLocCount, minLocCapacity,
|
||||
maxVal, maxLocPtr, maxLocCount, maxLocCapacity);
|
||||
}
|
||||
|
||||
process(src, j, size.width, i,
|
||||
minVal, minLocPtr, minLocCount, minLocCapacity,
|
||||
maxVal, maxLocPtr, maxLocCount, maxLocCapacity);
|
||||
}
|
||||
|
||||
minLocCount >>= 1;
|
||||
maxLocCount >>= 1;
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)minVal;
|
||||
(void)minLocPtr;
|
||||
(void)minLocCount;
|
||||
(void)minLocCapacity;
|
||||
(void)maxVal;
|
||||
(void)maxLocPtr;
|
||||
(void)maxLocCount;
|
||||
(void)maxLocCapacity;
|
||||
#endif
|
||||
}
|
||||
|
||||
void fillMinMaxLocs(const Size2D & size,
|
||||
const u32 * srcBase, ptrdiff_t srcStride,
|
||||
u32 minVal, size_t * minLocPtr, s32 & minLocCount, s32 minLocCapacity,
|
||||
u32 maxVal, size_t * maxLocPtr, s32 & maxLocCount, s32 maxLocCapacity)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
uint32x4_t v_maxval4 = vdupq_n_u32(maxVal),
|
||||
v_minval4 = vdupq_n_u32(minVal);
|
||||
u64 mask = 0ul;
|
||||
|
||||
minLocCapacity <<= 1;
|
||||
maxLocCapacity <<= 1;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const u32 * src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for ( ; j < roiw8; j += 8)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
uint32x4_t v_src0 = vld1q_u32(src + j), v_src1 = vld1q_u32(src + j + 4);
|
||||
|
||||
uint32x4_t v_mask0 = vorrq_u32(vceqq_u32(v_src0, v_maxval4), vceqq_u32(v_src0, v_minval4));
|
||||
uint32x4_t v_mask1 = vorrq_u32(vceqq_u32(v_src1, v_maxval4), vceqq_u32(v_src1, v_minval4));
|
||||
|
||||
vst1_u8((u8 *)&mask, vmovn_u16(vcombine_u16(vmovn_u32(v_mask0), vmovn_u32(v_mask1))));
|
||||
|
||||
if (mask)
|
||||
process(src, j, j + 8, i,
|
||||
minVal, minLocPtr, minLocCount, minLocCapacity,
|
||||
maxVal, maxLocPtr, maxLocCount, maxLocCapacity);
|
||||
}
|
||||
|
||||
process(src, j, size.width, i,
|
||||
minVal, minLocPtr, minLocCount, minLocCapacity,
|
||||
maxVal, maxLocPtr, maxLocCount, maxLocCapacity);
|
||||
}
|
||||
|
||||
minLocCount >>= 1;
|
||||
maxLocCount >>= 1;
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)minVal;
|
||||
(void)minLocPtr;
|
||||
(void)minLocCount;
|
||||
(void)minLocCapacity;
|
||||
(void)maxVal;
|
||||
(void)maxLocPtr;
|
||||
(void)maxLocCount;
|
||||
(void)maxLocCapacity;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+222
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "vtransform.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
bool isFlipSupported(FLIP_MODE flipMode, u32 elemSize)
|
||||
{
|
||||
bool supportedElemSize = (elemSize == 1) || (elemSize == 2) || (elemSize == 3) || (elemSize == 4);
|
||||
return isSupportedConfiguration() &&
|
||||
((supportedElemSize && ((flipMode == FLIP_BOTH_MODE) || (flipMode == FLIP_HORIZONTAL_MODE))) ||
|
||||
(flipMode == FLIP_VERTICAL_MODE));
|
||||
}
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
void flip(const Size2D & size,
|
||||
const void * srcBase, ptrdiff_t srcStride,
|
||||
void * dstBase, ptrdiff_t dstStride,
|
||||
FLIP_MODE flipMode)
|
||||
{
|
||||
using namespace internal;
|
||||
|
||||
typedef typename VecTraits<T>::vec128 vec128;
|
||||
typedef typename VecTraits<T>::vec64 vec64;
|
||||
|
||||
u32 step_base = 16 / sizeof(T), step_tail = 8 / sizeof(T);
|
||||
size_t roiw_base = size.width >= (step_base - 1) ? size.width - step_base + 1 : 0;
|
||||
size_t roiw_tail = size.width >= (step_tail - 1) ? size.width - step_tail + 1 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const T * src = getRowPtr((const T *)srcBase, srcStride, i);
|
||||
T * dst = getRowPtr((T *)dstBase, dstStride, (flipMode & FLIP_VERTICAL_MODE) != 0 ? size.height - i - 1 : i);
|
||||
size_t js = 0, jd = size.width;
|
||||
|
||||
for (; js < roiw_base; js += step_base, jd -= step_base)
|
||||
{
|
||||
prefetch(src + js);
|
||||
|
||||
vec128 v_src = vld1q(src + js);
|
||||
vec128 v_dst = vrev64q(v_src);
|
||||
v_dst = vcombine(vget_high(v_dst), vget_low(v_dst));
|
||||
vst1q(dst + jd - step_base, v_dst);
|
||||
}
|
||||
for (; js < roiw_tail; js += step_tail, jd -= step_tail)
|
||||
{
|
||||
vec64 v_src = vld1(src + js);
|
||||
vst1(dst + jd - step_tail, vrev64(v_src));
|
||||
}
|
||||
|
||||
for (--jd; js < size.width; ++js, --jd)
|
||||
dst[jd] = src[js];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void flip3(const Size2D & size,
|
||||
const void * srcBase, ptrdiff_t srcStride,
|
||||
void * dstBase, ptrdiff_t dstStride,
|
||||
FLIP_MODE flipMode)
|
||||
{
|
||||
using namespace internal;
|
||||
|
||||
#ifndef ANDROID
|
||||
typedef typename VecTraits<T, 3>::vec128 vec128;
|
||||
#endif
|
||||
typedef typename VecTraits<T, 3>::vec64 vec64;
|
||||
|
||||
#ifndef ANDROID
|
||||
u32 step_base = 16 / sizeof(T), step_base3 = step_base * 3;
|
||||
size_t roiw_base = size.width >= (step_base - 1) ? size.width - step_base + 1 : 0;
|
||||
#endif
|
||||
u32 step_tail = 8 / sizeof(T), step_tail3 = step_tail * 3;
|
||||
size_t roiw_tail = size.width >= (step_tail - 1) ? size.width - step_tail + 1 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const T * src = getRowPtr((const T *)srcBase, srcStride, i);
|
||||
T * dst = getRowPtr((T *)dstBase, dstStride, (flipMode & FLIP_VERTICAL_MODE) != 0 ? size.height - i - 1 : i);
|
||||
size_t j = 0, js = 0, jd = size.width * 3;
|
||||
|
||||
#ifndef ANDROID
|
||||
for (; j < roiw_base; j += step_base, js += step_base3, jd -= step_base3)
|
||||
{
|
||||
prefetch(src + js);
|
||||
|
||||
vec128 v_src = vld3q(src + js), v_dst;
|
||||
v_src.val[0] = vrev64q(v_src.val[0]);
|
||||
v_src.val[1] = vrev64q(v_src.val[1]);
|
||||
v_src.val[2] = vrev64q(v_src.val[2]);
|
||||
|
||||
v_dst.val[0] = vcombine(vget_high(v_src.val[0]), vget_low(v_src.val[0]));
|
||||
v_dst.val[1] = vcombine(vget_high(v_src.val[1]), vget_low(v_src.val[1]));
|
||||
v_dst.val[2] = vcombine(vget_high(v_src.val[2]), vget_low(v_src.val[2]));
|
||||
|
||||
vst3q(dst + jd - step_base3, v_dst);
|
||||
}
|
||||
#endif // ANDROID
|
||||
|
||||
for (; j < roiw_tail; j += step_tail, js += step_tail3, jd -= step_tail3)
|
||||
{
|
||||
vec64 v_src = vld3(src + js), v_dst;
|
||||
v_dst.val[0] = vrev64(v_src.val[0]);
|
||||
v_dst.val[1] = vrev64(v_src.val[1]);
|
||||
v_dst.val[2] = vrev64(v_src.val[2]);
|
||||
|
||||
vst3(dst + jd - step_tail3, v_dst);
|
||||
}
|
||||
|
||||
for (jd -= 3; j < size.width; ++j, js += 3, jd -= 3)
|
||||
{
|
||||
dst[jd] = src[js];
|
||||
dst[jd + 1] = src[js + 1];
|
||||
dst[jd + 2] = src[js + 2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (* flipFunc)(const Size2D &size,
|
||||
const void * srcBase, ptrdiff_t srcStride,
|
||||
void * dstBase, ptrdiff_t dstStride,
|
||||
FLIP_MODE flipMode);
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
void flip(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
FLIP_MODE flipMode, u32 elemSize)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isFlipSupported(flipMode, elemSize));
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
if (flipMode == FLIP_VERTICAL_MODE)
|
||||
{
|
||||
for (size_t y = 0; y < size.height; ++y)
|
||||
{
|
||||
const u8 * src_row = internal::getRowPtr(srcBase, srcStride, y);
|
||||
u8 * dst_row = internal::getRowPtr(dstBase, dstStride, size.height - y - 1);
|
||||
|
||||
std::memcpy(dst_row, src_row, elemSize * size.width);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
flipFunc func = NULL;
|
||||
|
||||
if (elemSize == (u32)sizeof(u8))
|
||||
func = &flip<u8>;
|
||||
if (elemSize == (u32)sizeof(u16))
|
||||
func = &flip<u16>;
|
||||
if (elemSize == (u32)sizeof(u32))
|
||||
func = &flip<u32>;
|
||||
if (elemSize == (u32)sizeof(u8) * 3)
|
||||
func = &flip3<u8>;
|
||||
|
||||
if (func == NULL)
|
||||
return;
|
||||
|
||||
func(size,
|
||||
srcBase, srcStride,
|
||||
dstBase, dstStride,
|
||||
flipMode);
|
||||
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)flipMode;
|
||||
(void)elemSize;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
+1059
File diff suppressed because it is too large
Load Diff
Vendored
+195
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2012-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include "vtransform.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace {
|
||||
|
||||
inline void vnst(u8* dst, uint8x16_t v1, uint8x16_t v2) { vst1q_u8(dst, v1); vst1q_u8(dst+16, v2); }
|
||||
inline void vnst(u8* dst, uint16x8_t v1, uint16x8_t v2) { vst1q_u8(dst, vcombine_u8(vmovn_u16(v1), vmovn_u16(v2))); }
|
||||
inline void vnst(u8* dst, uint32x4_t v1, uint32x4_t v2) { vst1_u8(dst, vmovn_u16(vcombine_u16(vmovn_u32(v1), vmovn_u32(v2)))); }
|
||||
|
||||
template <typename T, int elsize> struct vtail
|
||||
{
|
||||
static inline void inRange(const T *, const T *, const T *,
|
||||
u8 *, size_t &, size_t)
|
||||
{
|
||||
//do nothing since there couldn't be enough data
|
||||
}
|
||||
};
|
||||
template <typename T> struct vtail<T, 2>
|
||||
{
|
||||
static inline void inRange(const T * src, const T * rng1, const T * rng2,
|
||||
u8 * dst, size_t &x, size_t width)
|
||||
{
|
||||
typedef typename internal::VecTraits<T>::vec128 vec128;
|
||||
typedef typename internal::VecTraits<T>::unsign::vec128 uvec128;
|
||||
//There no more than 15 elements in the tail, so we could handle 8 element vector only once
|
||||
if( x + 8 < width)
|
||||
{
|
||||
vec128 vs = internal::vld1q( src + x);
|
||||
vec128 vr1 = internal::vld1q(rng1 + x);
|
||||
vec128 vr2 = internal::vld1q(rng2 + x);
|
||||
uvec128 vd = internal::vandq(internal::vcgeq(vs, vr1), internal::vcgeq(vr2, vs));
|
||||
internal::vst1(dst + x, internal::vmovn(vd));
|
||||
x+=8;
|
||||
}
|
||||
}
|
||||
};
|
||||
template <typename T> struct vtail<T, 1>
|
||||
{
|
||||
static inline void inRange(const T * src, const T * rng1, const T * rng2,
|
||||
u8 * dst, size_t &x, size_t width)
|
||||
{
|
||||
typedef typename internal::VecTraits<T>::vec128 vec128;
|
||||
typedef typename internal::VecTraits<T>::unsign::vec128 uvec128;
|
||||
typedef typename internal::VecTraits<T>::vec64 vec64;
|
||||
typedef typename internal::VecTraits<T>::unsign::vec64 uvec64;
|
||||
//There no more than 31 elements in the tail, so we could handle once 16+8 or 16 or 8 elements
|
||||
if( x + 16 < width)
|
||||
{
|
||||
vec128 vs = internal::vld1q( src + x);
|
||||
vec128 vr1 = internal::vld1q(rng1 + x);
|
||||
vec128 vr2 = internal::vld1q(rng2 + x);
|
||||
uvec128 vd = internal::vandq(internal::vcgeq(vs, vr1), internal::vcgeq(vr2, vs));
|
||||
internal::vst1q(dst + x, vd);
|
||||
x+=16;
|
||||
}
|
||||
if( x + 8 < width)
|
||||
{
|
||||
vec64 vs = internal::vld1( src + x);
|
||||
vec64 vr1 = internal::vld1(rng1 + x);
|
||||
vec64 vr2 = internal::vld1(rng2 + x);
|
||||
uvec64 vd = internal::vand(internal::vcge(vs, vr1), internal::vcge(vr2, vs));
|
||||
internal::vst1(dst + x, vd);
|
||||
x+=8;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline void inRangeCheck(const Size2D &_size,
|
||||
const T * srcBase, ptrdiff_t srcStride,
|
||||
const T * rng1Base, ptrdiff_t rng1Stride,
|
||||
const T * rng2Base, ptrdiff_t rng2Stride,
|
||||
u8 * dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
typedef typename internal::VecTraits<T>::vec128 vec128;
|
||||
typedef typename internal::VecTraits<T>::unsign::vec128 uvec128;
|
||||
|
||||
Size2D size(_size);
|
||||
if (srcStride == dstStride &&
|
||||
srcStride == rng1Stride &&
|
||||
srcStride == rng2Stride &&
|
||||
srcStride == (ptrdiff_t)(size.width))
|
||||
{
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
}
|
||||
const size_t width = size.width & ~( 32/sizeof(T) - 1 );
|
||||
|
||||
for(size_t j = 0; j < size.height; ++j)
|
||||
{
|
||||
const T * src = internal::getRowPtr( srcBase, srcStride, j);
|
||||
const T * rng1 = internal::getRowPtr(rng1Base, rng1Stride, j);
|
||||
const T * rng2 = internal::getRowPtr(rng2Base, rng2Stride, j);
|
||||
u8 * dst = internal::getRowPtr( dstBase, dstStride, j);
|
||||
size_t i = 0;
|
||||
for( ; i < width; i += 32/sizeof(T) )
|
||||
{
|
||||
internal::prefetch(src + i);
|
||||
internal::prefetch(rng1 + i);
|
||||
internal::prefetch(rng2 + i);
|
||||
|
||||
vec128 vs = internal::vld1q( src + i);
|
||||
vec128 vr1 = internal::vld1q(rng1 + i);
|
||||
vec128 vr2 = internal::vld1q(rng2 + i);
|
||||
uvec128 vd1 = internal::vandq(internal::vcgeq(vs, vr1), internal::vcgeq(vr2, vs));
|
||||
vs = internal::vld1q( src + i + 16/sizeof(T));
|
||||
vr1 = internal::vld1q(rng1 + i + 16/sizeof(T));
|
||||
vr2 = internal::vld1q(rng2 + i + 16/sizeof(T));
|
||||
uvec128 vd2 = internal::vandq(internal::vcgeq(vs, vr1), internal::vcgeq(vr2, vs));
|
||||
vnst(dst + i, vd1, vd2);
|
||||
}
|
||||
vtail<T, sizeof(T)>::inRange(src, rng1, rng2, dst, i, size.width);
|
||||
for( ; i < size.width; i++ )
|
||||
dst[i] = (u8)(-(rng1[i] <= src[i] && src[i] <= rng2[i]));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define INRANGEFUNC(T) \
|
||||
void inRange(const Size2D &_size, \
|
||||
const T * srcBase, ptrdiff_t srcStride, \
|
||||
const T * rng1Base, ptrdiff_t rng1Stride, \
|
||||
const T * rng2Base, ptrdiff_t rng2Stride, \
|
||||
u8 * dstBase, ptrdiff_t dstStride) \
|
||||
{ \
|
||||
internal::assertSupportedConfiguration(); \
|
||||
inRangeCheck(_size, srcBase, srcStride, \
|
||||
rng1Base, rng1Stride, rng2Base, rng2Stride, \
|
||||
dstBase, dstStride); \
|
||||
}
|
||||
#else
|
||||
#define INRANGEFUNC(T) \
|
||||
void inRange(const Size2D &, \
|
||||
const T *, ptrdiff_t, \
|
||||
const T *, ptrdiff_t, \
|
||||
const T *, ptrdiff_t, \
|
||||
u8 *, ptrdiff_t) \
|
||||
{ \
|
||||
internal::assertSupportedConfiguration(); \
|
||||
}
|
||||
#endif
|
||||
|
||||
INRANGEFUNC(u8)
|
||||
INRANGEFUNC(s8)
|
||||
INRANGEFUNC(u16)
|
||||
INRANGEFUNC(s16)
|
||||
INRANGEFUNC(s32)
|
||||
INRANGEFUNC(f32)
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+238
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2012-2014, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
void integral(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u32 * sumBase, ptrdiff_t sumStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
uint32x4_t v_zero = vmovq_n_u32(0u);
|
||||
|
||||
// the first iteration
|
||||
const u8 * src = internal::getRowPtr(srcBase, srcStride, 0);
|
||||
u32 * sum = internal::getRowPtr(sumBase, sumStride, 0);
|
||||
|
||||
uint32x4_t prev = v_zero;
|
||||
size_t j = 0u;
|
||||
|
||||
for ( ; j + 7 < size.width; j += 8)
|
||||
{
|
||||
internal::prefetch(sum + j);
|
||||
internal::prefetch(src + j);
|
||||
|
||||
uint8x8_t el8shr0 = vld1_u8(src + j);
|
||||
uint8x8_t el8shr1 = vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(el8shr0), 8));
|
||||
uint8x8_t el8shr2 = vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(el8shr0), 16));
|
||||
uint8x8_t el8shr3 = vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(el8shr0), 24));
|
||||
|
||||
uint16x8_t el8shr12 = vaddl_u8(el8shr1, el8shr2);
|
||||
uint16x8_t el8shr03 = vaddl_u8(el8shr0, el8shr3);
|
||||
|
||||
uint16x8_t el8 = vaddq_u16(el8shr12, el8shr03);
|
||||
uint16x4_t el4h = vadd_u16(vget_low_u16(el8), vget_high_u16(el8));
|
||||
|
||||
uint32x4_t vsuml = vaddw_u16(prev, vget_low_u16(el8));
|
||||
uint32x4_t vsumh = vaddw_u16(prev, el4h);
|
||||
|
||||
vst1q_u32(sum + j, vsuml);
|
||||
vst1q_u32(sum + j + 4, vsumh);
|
||||
|
||||
prev = vaddw_u16(prev, vdup_lane_u16(el4h, 3));
|
||||
}
|
||||
|
||||
for (u32 v = vgetq_lane_u32(prev, 3); j < size.width; ++j)
|
||||
sum[j] = (v += src[j]);
|
||||
|
||||
// the others
|
||||
for (size_t i = 1; i < size.height ; ++i)
|
||||
{
|
||||
src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
u32 * prevSum = internal::getRowPtr(sumBase, sumStride, i - 1);
|
||||
sum = internal::getRowPtr(sumBase, sumStride, i);
|
||||
|
||||
prev = v_zero;
|
||||
j = 0u;
|
||||
|
||||
for ( ; j + 7 < size.width; j += 8)
|
||||
{
|
||||
internal::prefetch(sum + j);
|
||||
internal::prefetch(src + j);
|
||||
|
||||
uint32x4_t vsuml = vld1q_u32(prevSum + j);
|
||||
uint32x4_t vsumh = vld1q_u32(prevSum + j + 4);
|
||||
|
||||
uint8x8_t el8shr0 = vld1_u8(src + j);
|
||||
uint8x8_t el8shr1 = vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(el8shr0), 8));
|
||||
uint8x8_t el8shr2 = vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(el8shr0), 16));
|
||||
uint8x8_t el8shr3 = vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(el8shr0), 24));
|
||||
|
||||
vsuml = vaddq_u32(vsuml, prev);
|
||||
vsumh = vaddq_u32(vsumh, prev);
|
||||
|
||||
uint16x8_t el8shr12 = vaddl_u8(el8shr1, el8shr2);
|
||||
uint16x8_t el8shr03 = vaddl_u8(el8shr0, el8shr3);
|
||||
|
||||
uint16x8_t el8 = vaddq_u16(el8shr12, el8shr03);
|
||||
uint16x4_t el4h = vadd_u16(vget_low_u16(el8), vget_high_u16(el8));
|
||||
|
||||
vsuml = vaddw_u16(vsuml, vget_low_u16(el8));
|
||||
vsumh = vaddw_u16(vsumh, el4h);
|
||||
|
||||
vst1q_u32(sum + j, vsuml);
|
||||
vst1q_u32(sum + j + 4, vsumh);
|
||||
|
||||
prev = vaddw_u16(prev, vdup_lane_u16(el4h, 3));
|
||||
}
|
||||
|
||||
for (u32 v = vgetq_lane_u32(prev, 3); j < size.width; ++j)
|
||||
sum[j] = (v += src[j]) + prevSum[j];
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)sumBase;
|
||||
(void)sumStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sqrIntegral(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
f64 * sqsumBase, ptrdiff_t sqsumStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
uint16x8_t v_zero8 = vmovq_n_u16(0u);
|
||||
|
||||
// the first iteration
|
||||
const u8 * src = internal::getRowPtr(srcBase, srcStride, 0);
|
||||
f64 * sqsum = internal::getRowPtr(sqsumBase, sqsumStride, 0);
|
||||
|
||||
double prev = 0.;
|
||||
size_t j = 0u;
|
||||
|
||||
for ( ; j + 7 < size.width; j += 8)
|
||||
{
|
||||
internal::prefetch(sqsum + j);
|
||||
internal::prefetch(src + j);
|
||||
|
||||
uint8x8_t vsrc = vld1_u8(src + j);
|
||||
|
||||
uint16x8_t el8shr0 = vmull_u8(vsrc, vsrc);
|
||||
uint16x8_t el8shr1 = vextq_u16(v_zero8, el8shr0, 7);
|
||||
|
||||
uint32x4_t el8shr01l = vaddl_u16(vget_low_u16(el8shr0), vget_low_u16(el8shr1));
|
||||
uint32x4_t el8shr01h = vaddl_u16(vget_high_u16(el8shr0), vget_high_u16(el8shr1));
|
||||
|
||||
uint32x4_t el4h = vaddq_u32(el8shr01l, el8shr01h);
|
||||
|
||||
uint32x2_t el2l = vadd_u32(vget_low_u32(el8shr01l), vget_high_u32(el8shr01l));
|
||||
uint32x2_t el2hl = vadd_u32(vget_low_u32(el4h), vget_high_u32(el8shr01l));
|
||||
uint32x2_t el2hh = vadd_u32(vget_low_u32(el4h), vget_high_u32(el4h));
|
||||
|
||||
u32 buf[8];
|
||||
vst1_u32(buf, vget_low_u32(el8shr01l));
|
||||
vst1_u32(buf+2, el2l);
|
||||
vst1_u32(buf+4, el2hl);
|
||||
vst1_u32(buf+6, el2hh);
|
||||
for(u32 k=0; k < 8; k++)
|
||||
sqsum[j+k] = prev + buf[k];
|
||||
prev += buf[7];
|
||||
}
|
||||
|
||||
for (; j < size.width; ++j)
|
||||
sqsum[j] = (prev += src[j]*src[j]);
|
||||
|
||||
// the others
|
||||
for (size_t i = 1; i < size.height ; ++i)
|
||||
{
|
||||
src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
f64 * prevSqSum = internal::getRowPtr(sqsumBase, sqsumStride, i - 1);
|
||||
sqsum = internal::getRowPtr(sqsumBase, sqsumStride, i);
|
||||
|
||||
prev = 0.;
|
||||
j = 0u;
|
||||
|
||||
for ( ; j + 7 < size.width; j += 8)
|
||||
{
|
||||
internal::prefetch(sqsum + j);
|
||||
internal::prefetch(src + j);
|
||||
|
||||
uint8x8_t vsrc = vld1_u8(src + j);
|
||||
|
||||
uint16x8_t el8shr0 = vmull_u8(vsrc, vsrc);
|
||||
uint16x8_t el8shr1 = vextq_u16(v_zero8, el8shr0, 7);
|
||||
|
||||
uint32x4_t el8shr01l = vaddl_u16(vget_low_u16(el8shr0), vget_low_u16(el8shr1));
|
||||
uint32x4_t el8shr01h = vaddl_u16(vget_high_u16(el8shr0), vget_high_u16(el8shr1));
|
||||
|
||||
uint32x4_t el4h = vaddq_u32(el8shr01l, el8shr01h);
|
||||
|
||||
uint32x2_t el2l = vadd_u32(vget_low_u32(el8shr01l), vget_high_u32(el8shr01l));
|
||||
uint32x2_t el2hl = vadd_u32(vget_low_u32(el4h), vget_high_u32(el8shr01l));
|
||||
uint32x2_t el2hh = vadd_u32(vget_low_u32(el4h), vget_high_u32(el4h));
|
||||
|
||||
u32 buf[8];
|
||||
vst1_u32(buf, vget_low_u32(el8shr01l));
|
||||
vst1_u32(buf+2, el2l);
|
||||
vst1_u32(buf+4, el2hl);
|
||||
vst1_u32(buf+6, el2hh);
|
||||
for(u32 k=0; k < 8; k++)
|
||||
sqsum[j+k] = prev + prevSqSum[j+k] + buf[k];
|
||||
prev += buf[7];
|
||||
}
|
||||
|
||||
for (; j < size.width; ++j)
|
||||
sqsum[j] = (prev += src[j]*src[j]) + prevSqSum[j];
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)sqsumBase;
|
||||
(void)sqsumStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+112
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#ifndef CAROTENE_INTRINSICS_HPP
|
||||
#define CAROTENE_INTRINSICS_HPP
|
||||
|
||||
#include <carotene/definitions.hpp>
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
namespace CAROTENE_NS { namespace internal {
|
||||
|
||||
/////////////// Custom NEON intrinsics ///////////////////
|
||||
|
||||
// calculate reciprocal value
|
||||
|
||||
inline float32x4_t vrecpq_f32(float32x4_t val)
|
||||
{
|
||||
float32x4_t reciprocal = vrecpeq_f32(val);
|
||||
reciprocal = vmulq_f32(vrecpsq_f32(val, reciprocal), reciprocal);
|
||||
reciprocal = vmulq_f32(vrecpsq_f32(val, reciprocal), reciprocal);
|
||||
return reciprocal;
|
||||
}
|
||||
|
||||
inline float32x2_t vrecp_f32(float32x2_t val)
|
||||
{
|
||||
float32x2_t reciprocal = vrecpe_f32(val);
|
||||
reciprocal = vmul_f32(vrecps_f32(val, reciprocal), reciprocal);
|
||||
reciprocal = vmul_f32(vrecps_f32(val, reciprocal), reciprocal);
|
||||
return reciprocal;
|
||||
}
|
||||
|
||||
// caclulate sqrt value
|
||||
|
||||
inline float32x4_t vrsqrtq_f32(float32x4_t val)
|
||||
{
|
||||
float32x4_t e = vrsqrteq_f32(val);
|
||||
e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(e, e), val), e);
|
||||
e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(e, e), val), e);
|
||||
return e;
|
||||
}
|
||||
|
||||
inline float32x2_t vrsqrt_f32(float32x2_t val)
|
||||
{
|
||||
float32x2_t e = vrsqrte_f32(val);
|
||||
e = vmul_f32(vrsqrts_f32(vmul_f32(e, e), val), e);
|
||||
e = vmul_f32(vrsqrts_f32(vmul_f32(e, e), val), e);
|
||||
return e;
|
||||
}
|
||||
|
||||
inline float32x4_t vsqrtq_f32(float32x4_t val)
|
||||
{
|
||||
return vrecpq_f32(vrsqrtq_f32(val));
|
||||
}
|
||||
|
||||
inline float32x2_t vsqrt_f32(float32x2_t val)
|
||||
{
|
||||
return vrecp_f32(vrsqrt_f32(val));
|
||||
}
|
||||
|
||||
// table lookup with the table in a 128-bit register
|
||||
|
||||
inline uint8x8_t vqtbl1_u8 (uint8x16_t a, uint8x8_t b)
|
||||
{
|
||||
#ifdef __aarch64__
|
||||
// AArch64 supports this natively
|
||||
return ::vqtbl1_u8(a, b);
|
||||
#else
|
||||
union { uint8x16_t v; uint8x8x2_t w; } u = { a };
|
||||
return vtbl2_u8(u.w, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
} }
|
||||
|
||||
#endif
|
||||
Vendored
+713
@@ -0,0 +1,713 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "saturate_cast.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
bool isLaplacian3x3Supported(const Size2D &size, BORDER_MODE border)
|
||||
{
|
||||
return isSupportedConfiguration() && size.width >= 8 &&
|
||||
(border == BORDER_MODE_CONSTANT ||
|
||||
border == BORDER_MODE_REPLICATE);
|
||||
}
|
||||
|
||||
void Laplacian3x3(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
BORDER_MODE border, u8 borderValue)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isLaplacian3x3Supported(size, border));
|
||||
#ifdef CAROTENE_NEON
|
||||
const uint16x8_t v_border_x3 = vdupq_n_u16(borderValue * 3);
|
||||
const uint16x8_t v_zero = vdupq_n_u16(0);
|
||||
const uint8x8_t v_border = vdup_n_u8(borderValue);
|
||||
|
||||
uint8x8_t vsub;
|
||||
uint16x8_t tprev = v_zero, tcurr = v_zero, tnext = v_zero;
|
||||
uint16x8_t t0 = v_zero, t1 = v_zero, t2 = v_zero;
|
||||
|
||||
ptrdiff_t width = (ptrdiff_t)size.width, height = (ptrdiff_t)size.height;
|
||||
|
||||
for (ptrdiff_t y = 0; y < height; ++y)
|
||||
{
|
||||
const u8 * srow0 = y == 0 && border == BORDER_MODE_CONSTANT ? NULL : internal::getRowPtr(srcBase, srcStride, std::max<ptrdiff_t>(y - 1, 0));
|
||||
const u8 * srow1 = internal::getRowPtr(srcBase, srcStride, y);
|
||||
const u8 * srow2 = y + 1 == height && border == BORDER_MODE_CONSTANT ? NULL : internal::getRowPtr(srcBase, srcStride, std::min(y + 1, height - 1));
|
||||
u8 * drow = internal::getRowPtr(dstBase, dstStride, y);
|
||||
|
||||
s16 prevx = 0, currx = 0, nextx = 0;
|
||||
ptrdiff_t x = 0;
|
||||
const ptrdiff_t bwidth = y + 2 < height ? width : (width - 8);
|
||||
|
||||
// perform vertical convolution
|
||||
for ( ; x <= bwidth; x += 8)
|
||||
{
|
||||
internal::prefetch(srow0 + x);
|
||||
internal::prefetch(srow1 + x);
|
||||
internal::prefetch(srow2 + x);
|
||||
|
||||
uint8x8_t x0 = !srow0 ? v_border : vld1_u8(srow0 + x);
|
||||
uint8x8_t x1 = vld1_u8(srow1 + x);
|
||||
uint8x8_t x2 = !srow2 ? v_border : vld1_u8(srow2 + x);
|
||||
|
||||
// calculate values for plain CPU part below if needed
|
||||
if (x + 8 >= bwidth)
|
||||
{
|
||||
ptrdiff_t x3 = x == width ? width - 1 : x;
|
||||
ptrdiff_t x4 = border == BORDER_MODE_CONSTANT ? x3 - 1 : std::max<ptrdiff_t>(x3 - 1, 0);
|
||||
|
||||
if (border == BORDER_MODE_CONSTANT && x4 < 0)
|
||||
prevx = borderValue;
|
||||
else
|
||||
prevx = (srow2 ? srow2[x4] : borderValue) + srow1[x4] + (srow0 ? srow0[x4] : borderValue);
|
||||
|
||||
currx = (srow2 ? srow2[x3] : borderValue) + srow1[x3] + (srow0 ? srow0[x3] : borderValue);
|
||||
}
|
||||
|
||||
// make shift
|
||||
if (x)
|
||||
{
|
||||
tprev = tcurr;
|
||||
tcurr = tnext;
|
||||
}
|
||||
|
||||
// and calculate next value
|
||||
tnext = vaddw_u8(vaddl_u8(x0, x1), x2);
|
||||
|
||||
// make extrapolation for the first elements
|
||||
if (!x)
|
||||
{
|
||||
// make border
|
||||
if (border == BORDER_MODE_CONSTANT)
|
||||
tcurr = v_border_x3;
|
||||
else if (border == BORDER_MODE_REPLICATE)
|
||||
tcurr = vdupq_n_u16(vgetq_lane_u16(tnext, 0));
|
||||
|
||||
vsub = x1;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// combine 3 "shifted" vectors
|
||||
t0 = vextq_u16(tprev, tcurr, 7);
|
||||
t1 = tcurr;
|
||||
t2 = vextq_u16(tcurr, tnext, 1);
|
||||
|
||||
// and add them
|
||||
t0 = vqaddq_u16(t0, vqaddq_u16(t1, t2));
|
||||
|
||||
int16x8_t tt0 = vsubq_s16(vreinterpretq_s16_u16(t0),
|
||||
vreinterpretq_s16_u16(vaddw_u8(vshll_n_u8(vsub, 3), vsub)));
|
||||
uint8x8_t it0 = vqmovun_s16(tt0);
|
||||
vst1_u8(drow + x - 8, it0);
|
||||
|
||||
vsub = x1;
|
||||
}
|
||||
|
||||
x -= 8;
|
||||
if (x == width)
|
||||
--x;
|
||||
|
||||
for ( ; x < width; ++x)
|
||||
{
|
||||
// make extrapolation for the last elements
|
||||
if (x + 1 >= width)
|
||||
{
|
||||
if (border == BORDER_MODE_CONSTANT)
|
||||
nextx = borderValue * 3;
|
||||
else if (border == BORDER_MODE_REPLICATE)
|
||||
nextx = srow2[x] + srow1[x] + srow0[x];
|
||||
}
|
||||
else
|
||||
{
|
||||
nextx = (srow2 ? srow2[x + 1] : borderValue) +
|
||||
srow1[x + 1] +
|
||||
(srow0 ? srow0[x + 1] : borderValue);
|
||||
}
|
||||
|
||||
s32 val = (prevx + currx + nextx) - 9 * srow1[x];
|
||||
drow[x] = internal::saturate_cast<u8>((s32)val);
|
||||
|
||||
// make shift
|
||||
prevx = currx;
|
||||
currx = nextx;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)border;
|
||||
(void)borderValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isLaplacianOpenCVSupported(const Size2D &size, BORDER_MODE border)
|
||||
{
|
||||
return isSupportedConfiguration() &&
|
||||
size.width >= 8 && size.height >= 1 &&
|
||||
(border == BORDER_MODE_CONSTANT ||
|
||||
border == BORDER_MODE_REFLECT ||
|
||||
border == BORDER_MODE_REFLECT101 ||
|
||||
border == BORDER_MODE_REPLICATE);
|
||||
}
|
||||
|
||||
void Laplacian1OpenCV(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
s16 * dstBase, ptrdiff_t dstStride,
|
||||
BORDER_MODE border, u8 borderValue)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isLaplacianOpenCVSupported(size, border));
|
||||
#ifdef CAROTENE_NEON
|
||||
ptrdiff_t rows = size.height, cols = size.width;
|
||||
|
||||
std::vector<u8> _tmp;
|
||||
u8 *tmp = 0;
|
||||
if (border == BORDER_MODE_CONSTANT)
|
||||
{
|
||||
_tmp.assign(cols + 4,borderValue);
|
||||
tmp = &_tmp[2];
|
||||
}
|
||||
|
||||
for( ptrdiff_t y = 0; y < rows; y++ )
|
||||
{
|
||||
const u8* v0 = 0;
|
||||
const u8* v1 = internal::getRowPtr(srcBase, srcStride, y);
|
||||
const u8* v2 = 0;
|
||||
// make border
|
||||
if (border == BORDER_MODE_REFLECT101) {
|
||||
v0 = internal::getRowPtr(srcBase, srcStride, y > 0 ? y-1 : y+1);
|
||||
v2 = internal::getRowPtr(srcBase, srcStride, y < rows-1 ? y+1 : rows > 1 ? rows-2 : 0);
|
||||
} else if (border == BORDER_MODE_CONSTANT) {
|
||||
v0 = y > 0 ? internal::getRowPtr(srcBase, srcStride, y-1) : tmp;
|
||||
v2 = y < rows-1 ? internal::getRowPtr(srcBase, srcStride, y+1) : tmp;
|
||||
} else {
|
||||
v0 = internal::getRowPtr(srcBase, srcStride, y > 0 ? y-1 : 0);
|
||||
v2 = internal::getRowPtr(srcBase, srcStride, y < rows-1 ? y+1 : rows > 0 ? rows-1 : 0);
|
||||
}
|
||||
s16* drow = internal::getRowPtr(dstBase, dstStride, y);
|
||||
|
||||
int16x8_t tcurr = vmovq_n_s16(0x0);
|
||||
int16x8_t tnext = vmovq_n_s16(0x0);
|
||||
int16x8_t t0, t2;
|
||||
uint8x8_t xx0 = vmov_n_u8(0x0);
|
||||
uint8x8_t xx1 = vmov_n_u8(0x0);
|
||||
uint8x8_t xx2 = vmov_n_u8(0x0);
|
||||
ptrdiff_t x = 0;
|
||||
const ptrdiff_t bcols = y + 2 < rows ? cols : (cols - 8);
|
||||
for( ; x <= bcols; x += 8 )
|
||||
{
|
||||
internal::prefetch(v0 + x);
|
||||
internal::prefetch(v1 + x);
|
||||
internal::prefetch(v2 + x);
|
||||
|
||||
uint8x8_t x0 = vld1_u8(v0 + x);
|
||||
uint8x8_t x1 = vld1_u8(v1 + x);
|
||||
uint8x8_t x2 = vld1_u8(v2 + x);
|
||||
|
||||
if(x) {
|
||||
xx0 = xx1;
|
||||
xx1 = xx2;
|
||||
} else {
|
||||
xx1 = x1;
|
||||
// make border
|
||||
if (border == BORDER_MODE_REPLICATE || border == BORDER_MODE_REFLECT)
|
||||
{
|
||||
xx1 = vset_lane_u8(vget_lane_u8(x1, 0),x1, 7);
|
||||
}
|
||||
else if (border == BORDER_MODE_CONSTANT)
|
||||
{
|
||||
xx1 = vset_lane_u8(borderValue, x1, 7);
|
||||
}
|
||||
else if (border == BORDER_MODE_REFLECT101)
|
||||
{
|
||||
xx1 = vset_lane_u8(vget_lane_u8(x1, 1),x1, 7);
|
||||
}
|
||||
}
|
||||
xx2 = x1;
|
||||
|
||||
if(x) {
|
||||
tcurr = tnext;
|
||||
}
|
||||
tnext = vsubq_s16(vreinterpretq_s16_u16(vaddl_u8(x0, x2)),
|
||||
vreinterpretq_s16_u16(vshll_n_u8(x1, 2)));
|
||||
|
||||
if(!x) {
|
||||
tcurr = tnext;
|
||||
continue;
|
||||
}
|
||||
t0 = vreinterpretq_s16_u16(vmovl_u8(vext_u8(xx0, xx1, 7)));
|
||||
t2 = vreinterpretq_s16_u16(vmovl_u8(vext_u8(xx1, xx2, 1)));
|
||||
t0 = vaddq_s16(vqaddq_s16(t0, t2), tcurr);
|
||||
|
||||
vst1q_s16(drow + x - 8, t0);
|
||||
}
|
||||
|
||||
x -= 8;
|
||||
if(x == cols){
|
||||
x--;
|
||||
}
|
||||
|
||||
for( ; x < cols; x++ )
|
||||
{
|
||||
s16 nextx;
|
||||
s16 prevx;
|
||||
// make border
|
||||
if (border == BORDER_MODE_REPLICATE || border == BORDER_MODE_REFLECT)
|
||||
{
|
||||
prevx = x == 0 ? v1[0] : v1[x-1];
|
||||
nextx = x == cols-1 ? v1[x] : v1[x+1];
|
||||
}
|
||||
else if (border == BORDER_MODE_REFLECT101)
|
||||
{
|
||||
prevx = x == 0 ? v1[1] : v1[x-1];
|
||||
nextx = x == cols-1 ? v1[x-1] : v1[x+1];
|
||||
}
|
||||
else //if (border == BORDER_MODE_CONSTANT)
|
||||
{
|
||||
prevx = x == 0 ? borderValue : v1[x-1];
|
||||
nextx = x == cols-1 ? borderValue : v1[x+1];
|
||||
}
|
||||
*(drow+x) = prevx + nextx - 4*v1[x] + v0[x] + v2[x];
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)border;
|
||||
(void)borderValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Laplacian3OpenCV(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
s16 * dstBase, ptrdiff_t dstStride,
|
||||
BORDER_MODE border, u8 borderValue)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isLaplacianOpenCVSupported(size, border));
|
||||
#ifdef CAROTENE_NEON
|
||||
ptrdiff_t rows = size.height, cols = size.width;
|
||||
|
||||
std::vector<u8> _tmp;
|
||||
u8 *tmp = 0;
|
||||
if (border == BORDER_MODE_CONSTANT)
|
||||
{
|
||||
_tmp.assign(cols + 4,borderValue);
|
||||
tmp = &_tmp[2];
|
||||
}
|
||||
|
||||
for( ptrdiff_t y = 0; y < rows; y++ )
|
||||
{
|
||||
const u8* v0 = 0;
|
||||
const u8* v1 = internal::getRowPtr(srcBase, srcStride, y);
|
||||
const u8* v2 = 0;
|
||||
// make border
|
||||
if (border == BORDER_MODE_REFLECT101) {
|
||||
v0 = internal::getRowPtr(srcBase, srcStride, y > 0 ? y-1 : y+1);
|
||||
v2 = internal::getRowPtr(srcBase, srcStride, y < rows-1 ? y+1 : rows > 1 ? rows-2 : 0);
|
||||
} else if (border == BORDER_MODE_CONSTANT) {
|
||||
v0 = y > 0 ? internal::getRowPtr(srcBase, srcStride, y-1) : tmp;
|
||||
v2 = y < rows-1 ? internal::getRowPtr(srcBase, srcStride, y+1) : tmp;
|
||||
} else {
|
||||
v0 = internal::getRowPtr(srcBase, srcStride, y > 0 ? y-1 : 0);
|
||||
v2 = internal::getRowPtr(srcBase, srcStride, y < rows-1 ? y+1 : rows > 0 ? rows-1 : 0);
|
||||
}
|
||||
s16* drow = internal::getRowPtr(dstBase, dstStride, y);
|
||||
|
||||
int16x8_t tprev = vmovq_n_s16(0x0);
|
||||
int16x8_t tcurr = vmovq_n_s16(0x0);
|
||||
int16x8_t tnext = vmovq_n_s16(0x0);
|
||||
int16x8_t tc = vmovq_n_s16(0x0);
|
||||
int16x8_t t0, t2, tcnext;
|
||||
ptrdiff_t x = 0;
|
||||
const ptrdiff_t bcols = y + 2 < rows ? cols : (cols - 8);
|
||||
for( ; x <= bcols; x += 8 )
|
||||
{
|
||||
internal::prefetch(v0 + x);
|
||||
internal::prefetch(v1 + x);
|
||||
internal::prefetch(v2 + x);
|
||||
|
||||
uint8x8_t x0 = vld1_u8(v0 + x);
|
||||
uint8x8_t x1 = vld1_u8(v1 + x);
|
||||
uint8x8_t x2 = vld1_u8(v2 + x);
|
||||
tcnext = vreinterpretq_s16_u16(vshll_n_u8(x1, 2));
|
||||
|
||||
if(x) {
|
||||
tprev = tcurr;
|
||||
tcurr = tnext;
|
||||
}
|
||||
tnext = vreinterpretq_s16_u16(vaddl_u8(x0, x2));
|
||||
|
||||
if(!x) {
|
||||
tcurr = tnext;
|
||||
tc = tcnext;
|
||||
|
||||
// make border
|
||||
if (border == BORDER_MODE_REPLICATE || border == BORDER_MODE_REFLECT)
|
||||
{
|
||||
tcurr = vsetq_lane_s16(vgetq_lane_s16(tcurr, 0),tcurr, 7);
|
||||
}
|
||||
else if (border == BORDER_MODE_CONSTANT)
|
||||
{
|
||||
tcurr = vsetq_lane_s16(borderValue, tcurr, 7);
|
||||
}
|
||||
else if (border == BORDER_MODE_REFLECT101)
|
||||
{
|
||||
tcurr = vsetq_lane_s16(vgetq_lane_s16(tcurr, 1),tcurr, 7);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
t0 = vextq_s16(tprev, tcurr, 7);
|
||||
t2 = vextq_s16(tcurr, tnext, 1);
|
||||
|
||||
t0 = vsubq_s16(vqaddq_s16(t0, t2), tc);
|
||||
tc = tcnext;
|
||||
|
||||
t0 = vshlq_n_s16(t0, 1);
|
||||
vst1q_s16(drow + x - 8, t0);
|
||||
}
|
||||
x -= 8;
|
||||
if(x == cols){
|
||||
x--;
|
||||
}
|
||||
|
||||
for( ; x < cols; x++ )
|
||||
{
|
||||
s16 nextx, nextx2;
|
||||
s16 prevx, prevx2;
|
||||
// make border
|
||||
if (border == BORDER_MODE_REPLICATE || border == BORDER_MODE_REFLECT)
|
||||
{
|
||||
prevx = x == 0 ? v0[0] : v0[x-1];
|
||||
prevx2 = x == 0 ? v2[0] : v2[x-1];
|
||||
nextx = x == cols-1 ? v0[x] : v0[x+1];
|
||||
nextx2 = x == cols-1 ? v2[x] : v2[x+1];
|
||||
}
|
||||
else if (border == BORDER_MODE_REFLECT101)
|
||||
{
|
||||
prevx = x == 0 ? v0[1] : v0[x-1];
|
||||
prevx2 = x == 0 ? v2[1] : v2[x-1];
|
||||
nextx = x == cols-1 ? v0[x-1] : v0[x+1];
|
||||
nextx2 = x == cols-1 ? v2[x-1] : v2[x+1];
|
||||
}
|
||||
else //if (border == BORDER_MODE_CONSTANT)
|
||||
{
|
||||
prevx = x == 0 ? borderValue : v0[x-1];
|
||||
prevx2 = x == 0 ? borderValue : v2[x-1];
|
||||
nextx = x == cols-1 ? borderValue : v0[x+1];
|
||||
nextx2 = x == cols-1 ? borderValue : v2[x+1];
|
||||
}
|
||||
s16 res = prevx + nextx - 4*v1[x] + prevx2 + nextx2;
|
||||
*(drow+x) = 2*res;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)border;
|
||||
(void)borderValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Laplacian5OpenCV(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
s16 * dstBase, ptrdiff_t dstStride,
|
||||
BORDER_MODE border, u8 borderValue)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isLaplacianOpenCVSupported(size, border));
|
||||
#ifdef CAROTENE_NEON
|
||||
ptrdiff_t rows = size.height, cols = size.width;
|
||||
|
||||
std::vector<u8> _tmp;
|
||||
u8 *tmp = 0;
|
||||
if (border == BORDER_MODE_CONSTANT)
|
||||
{
|
||||
_tmp.assign(cols + 4,borderValue);
|
||||
tmp = &_tmp[2];
|
||||
}
|
||||
|
||||
for( ptrdiff_t y = 0; y < rows; y++ )
|
||||
{
|
||||
const u8* v0 = 0;
|
||||
const u8* v1 = 0;
|
||||
const u8* v2 = internal::getRowPtr(srcBase, srcStride, y);
|
||||
const u8* v3 = 0;
|
||||
const u8* v4 = 0;
|
||||
// make border
|
||||
if (border == BORDER_MODE_REPLICATE) {
|
||||
v0 = internal::getRowPtr(srcBase, srcStride, y > 1 ? y-2 : 0);
|
||||
v1 = internal::getRowPtr(srcBase, srcStride, y > 0 ? y-1 : 0);
|
||||
v3 = internal::getRowPtr(srcBase, srcStride, y < rows-1 ? y+1 : rows > 0 ? rows-1 : 0);
|
||||
v4 = internal::getRowPtr(srcBase, srcStride, y < rows-2 ? y+2 : rows > 0 ? rows-1 : 0);
|
||||
} else if (border == BORDER_MODE_REFLECT) {
|
||||
v0 = internal::getRowPtr(srcBase, srcStride, y > 1 ? y-2 : rows > 1 ? 1-y : 0);
|
||||
v1 = internal::getRowPtr(srcBase, srcStride, y > 0 ? y-1 : 0);
|
||||
v3 = internal::getRowPtr(srcBase, srcStride, y < rows-1 ? y+1 : rows > 0 ? rows-1 : 0);
|
||||
v4 = internal::getRowPtr(srcBase, srcStride, y < rows-2 ? y+2 : rows > 1 ? 2*rows-(y+3) : 0);
|
||||
} else if (border == BORDER_MODE_REFLECT101) {
|
||||
v0 = internal::getRowPtr(srcBase, srcStride, y > 1 ? y-2 : rows > 2-y ? 2-y : 0); ///check
|
||||
v1 = internal::getRowPtr(srcBase, srcStride, y > 0 ? y-1 : rows > 1 ? 1 : 0);
|
||||
v3 = internal::getRowPtr(srcBase, srcStride, y < rows-1 ? y+1 : rows > 1 ? rows-2 : 0);
|
||||
v4 = internal::getRowPtr(srcBase, srcStride, y < rows-2 ? y+2 : rows > 2 ? 2*rows-(y+4) : 0);///bad if rows=2 y=1 rows - 4 + (2,1)
|
||||
} else if (border == BORDER_MODE_CONSTANT) {
|
||||
v0 = y > 1 ? internal::getRowPtr(srcBase, srcStride, y-2) : tmp;
|
||||
v1 = y > 0 ? internal::getRowPtr(srcBase, srcStride, y-1) : tmp;
|
||||
v3 = y < rows-1 ? internal::getRowPtr(srcBase, srcStride, y+1) : tmp;
|
||||
v4 = y < rows-2 ? internal::getRowPtr(srcBase, srcStride, y+2) : tmp;
|
||||
}
|
||||
s16* drow = internal::getRowPtr(dstBase, dstStride, y);
|
||||
|
||||
int16x8_t tnext, tc, t0;
|
||||
int16x8_t tnext2, tnext3;
|
||||
int16x8_t tnext1Old, tnext2Old, tnext3Old;
|
||||
int16x8_t tnext4OldOldOld, tnext5OldOldOld;
|
||||
|
||||
int16x8_t tcurr1 = vmovq_n_s16(0x0);
|
||||
int16x8_t tnext1 = vmovq_n_s16(0x0);
|
||||
int16x8_t tprev1 = vmovq_n_s16(0x0);
|
||||
int16x8_t tpprev1 = vmovq_n_s16(0x0);
|
||||
int16x8_t tppprev1 = vmovq_n_s16(0x0);
|
||||
|
||||
int16x8_t tnext4Old = vmovq_n_s16(0x0);
|
||||
int16x8_t tnext5Old = vmovq_n_s16(0x0);
|
||||
int16x8_t tnext1OldOld = vmovq_n_s16(0x0);
|
||||
int16x8_t tnext2OldOld = vmovq_n_s16(0x0);
|
||||
int16x8_t tnext3OldOld = vmovq_n_s16(0x0);
|
||||
int16x8_t tnext4OldOld = vmovq_n_s16(0x0);
|
||||
int16x8_t tnext5OldOld = vmovq_n_s16(0x0);
|
||||
|
||||
// do vertical convolution
|
||||
ptrdiff_t x = 0;
|
||||
const ptrdiff_t bcols = y + 3 < rows ? cols : (cols - 8);
|
||||
for( ; x <= bcols; x += 8 )
|
||||
{
|
||||
internal::prefetch(v0 + x);
|
||||
internal::prefetch(v1 + x);
|
||||
internal::prefetch(v2 + x);
|
||||
internal::prefetch(v3 + x);
|
||||
internal::prefetch(v4 + x);
|
||||
|
||||
uint8x8_t x0 = vld1_u8(v0 + x);
|
||||
uint8x8_t x1 = vld1_u8(v1 + x);
|
||||
uint8x8_t x2 = vld1_u8(v2 + x);
|
||||
uint8x8_t x3 = vld1_u8(v3 + x);
|
||||
uint8x8_t x4 = vld1_u8(v4 + x);
|
||||
if(x) {
|
||||
tcurr1 = tnext1;
|
||||
}
|
||||
|
||||
tnext4OldOldOld = tnext4Old;
|
||||
tnext5OldOldOld = tnext5Old;
|
||||
tnext1Old = tnext1OldOld;
|
||||
tnext2Old = tnext2OldOld;
|
||||
tnext3Old = tnext3OldOld;
|
||||
tnext4Old = tnext4OldOld;
|
||||
tnext5Old = tnext5OldOld;
|
||||
|
||||
tnext3 = vreinterpretq_s16_u16(vaddq_u16(vaddl_u8(x3, x2),vaddl_u8(x2, x1)));
|
||||
tnext3 = vshlq_n_s16(tnext3, 1);
|
||||
|
||||
tc = vreinterpretq_s16_u16(vsubl_u8(x4, x2));
|
||||
tnext = vreinterpretq_s16_u16(vsubl_u8(x2, x0));
|
||||
tnext2 = vsubq_s16(tc, tnext);
|
||||
|
||||
tnext1 = vaddq_s16(tnext3, tnext2);
|
||||
// tnext1 = x0 + 2*x1 + 2*x2 + 2*x3 + x4
|
||||
|
||||
tnext2 = vshlq_n_s16(tnext2, 1);
|
||||
// tnext2 = 2*x4 - 4*x2 + 2*x0
|
||||
|
||||
tnext3 = vsubq_s16(tnext2, vshlq_n_s16(tnext3, 1));
|
||||
// tnext3 = 2*x0 - 4*x1 - 12*x2 - 4*x3 + 2*x4
|
||||
|
||||
tnext1OldOld = tnext1;
|
||||
tnext2OldOld = tnext2;
|
||||
tnext3OldOld = tnext3;
|
||||
tnext4OldOld = tnext2;
|
||||
tnext5OldOld = tnext1;
|
||||
|
||||
if(x) {
|
||||
tnext1 = vextq_s16(tnext1Old, tnext1, 2);
|
||||
tcurr1 = vextq_s16(tnext2Old, tnext2, 1);
|
||||
tprev1 = tnext3Old;
|
||||
|
||||
if(x!=8) {
|
||||
tpprev1 = vextq_s16(tnext4OldOldOld, tnext4Old, 7);
|
||||
tppprev1 = vextq_s16(tnext5OldOldOld, tnext5Old, 6);
|
||||
}
|
||||
}
|
||||
|
||||
if(!x) {
|
||||
// make border
|
||||
if (border == BORDER_MODE_REPLICATE) {
|
||||
tpprev1 = vextq_s16(tnext2, tnext2, 7);
|
||||
tpprev1 = vsetq_lane_s16(vgetq_lane_s16(tpprev1, 1),tpprev1, 0);
|
||||
|
||||
tprev1 = vextq_s16(tnext1, tnext1, 6);
|
||||
tprev1 = vsetq_lane_s16(vgetq_lane_s16(tprev1, 2),tprev1, 0);
|
||||
tprev1 = vsetq_lane_s16(vgetq_lane_s16(tprev1, 2),tprev1, 1);
|
||||
} else if (border == BORDER_MODE_REFLECT) {
|
||||
tpprev1 = vextq_s16(tnext2, tnext2, 7);
|
||||
tpprev1 = vsetq_lane_s16(vgetq_lane_s16(tpprev1, 1),tpprev1, 0);
|
||||
|
||||
tprev1 = vextq_s16(tnext1, tnext1, 6);
|
||||
tprev1 = vsetq_lane_s16(vgetq_lane_s16(tprev1, 3),tprev1, 0);
|
||||
tprev1 = vsetq_lane_s16(vgetq_lane_s16(tprev1, 2),tprev1, 1);
|
||||
} else if (border == BORDER_MODE_REFLECT101) {
|
||||
tpprev1 = vextq_s16(tnext2, tnext2, 7);
|
||||
tpprev1 = vsetq_lane_s16(vgetq_lane_s16(tpprev1, 2),tpprev1, 0);
|
||||
|
||||
tprev1 = vextq_s16(tnext1, tnext1, 6);
|
||||
tprev1 = vsetq_lane_s16(vgetq_lane_s16(tprev1, 3),tprev1, 1);
|
||||
tprev1 = vsetq_lane_s16(vgetq_lane_s16(tprev1, 4),tprev1, 0);
|
||||
} else if (border == BORDER_MODE_CONSTANT) {
|
||||
tpprev1 = vextq_s16(tnext2, tnext2, 7);
|
||||
tpprev1 = vsetq_lane_s16(borderValue, tpprev1, 0);
|
||||
|
||||
tprev1 = vextq_s16(tnext1, tnext1, 6);
|
||||
tprev1 = vsetq_lane_s16(borderValue, tprev1, 0);
|
||||
tprev1 = vsetq_lane_s16(borderValue, tprev1, 1);
|
||||
}
|
||||
tppprev1 = tprev1;
|
||||
continue;
|
||||
}
|
||||
|
||||
t0 = vaddq_s16(vaddq_s16(vqaddq_s16(tcurr1, tprev1), vqaddq_s16(tpprev1, tppprev1)), tnext1);
|
||||
t0 = vaddq_s16(t0, t0);
|
||||
vst1q_s16(drow + x - 8, t0);
|
||||
}
|
||||
x -= 8;
|
||||
if(x >= cols - 1)
|
||||
x = cols-2;
|
||||
|
||||
s16 pprevx = 0;
|
||||
s16 prevx = 0;
|
||||
s16 nextx = 0;
|
||||
s16 nnextx = 0;
|
||||
|
||||
for( ; x < cols; x++ )
|
||||
{
|
||||
if (x == 0) {
|
||||
// make border
|
||||
if (border == BORDER_MODE_REPLICATE) {
|
||||
pprevx = v0[0] + 2*v1[0] + 2*v2[0] + 2*v3[0] + v4[0];
|
||||
prevx = 2*v0[0] - 4*v2[0] + 2*v4[0];
|
||||
} else if (border == BORDER_MODE_REFLECT) {
|
||||
pprevx = v0[1] + 2*v1[1] + 2*v2[1] + 2*v3[1] + v4[1];
|
||||
prevx = 2*v0[0] - 4*v2[0] + 2*v4[0];
|
||||
} else if (border == BORDER_MODE_REFLECT101) {
|
||||
pprevx = v0[2] + 2*v1[2] + 2*v2[2] + 2*v3[2] + v4[2];
|
||||
prevx = 2*v0[1] - 4*v2[1] + 2*v4[1];
|
||||
} else if (border == BORDER_MODE_CONSTANT) {
|
||||
pprevx = 8 * borderValue;
|
||||
prevx = 0;
|
||||
}
|
||||
} else if (x == 1) {
|
||||
// make border
|
||||
if (border == BORDER_MODE_REPLICATE || border == BORDER_MODE_REFLECT) {
|
||||
pprevx = v0[0] + 2*v1[0] + 2*v2[0] + 2*v3[0] + v4[0];
|
||||
} else if (border == BORDER_MODE_REFLECT101) {
|
||||
pprevx = v0[1] + 2*v1[1] + 2*v2[1] + 2*v3[1] + v4[1];
|
||||
} else if (border == BORDER_MODE_CONSTANT) {
|
||||
pprevx = 8 * borderValue;
|
||||
}
|
||||
prevx = 2*v0[0] - 4*v2[0] + 2*v4[0];
|
||||
} else {
|
||||
pprevx = v0[x-2] + 2*v1[x-2] + 2*v2[x-2] + 2*v3[x-2] + v4[x-2];
|
||||
prevx = 2*v0[x-1] - 4*v2[x-1] + 2*v4[x-1];
|
||||
}
|
||||
s16 currx = 2*v0[x] - 4*v1[x] - 12*v2[x] - 4*v3[x] + 2*v4[x];
|
||||
if (x == cols-1) {
|
||||
// make border
|
||||
if (border == BORDER_MODE_REPLICATE) {
|
||||
nextx = 2*v0[x] - 4*v2[x] + 2*v4[x];
|
||||
nnextx = v0[x] + 2*v1[x] + 2*v2[x] + 2*v3[x] + v4[x];
|
||||
} else if (border == BORDER_MODE_REFLECT) {
|
||||
nextx = 2*v0[x] - 4*v2[x] + 2*v4[x];
|
||||
nnextx = v0[x-1] + 2*v1[x-1] + 2*v2[x-1] + 2*v3[x-1] + v4[x-1];
|
||||
} else if (border == BORDER_MODE_REFLECT101) {
|
||||
nextx = 2*v0[x-1] - 4*v2[x-1] + 2*v4[x-1];
|
||||
nnextx = v0[x-2] + 2*v1[x-2] + 2*v2[x-2] + 2*v3[x-2] + v4[x-2];
|
||||
} else if (border == BORDER_MODE_CONSTANT) {
|
||||
nextx = 0;
|
||||
nnextx = 8 * borderValue;
|
||||
}
|
||||
} else if (x == cols-2) {
|
||||
// make border
|
||||
if (border == BORDER_MODE_REPLICATE || border == BORDER_MODE_REFLECT) {
|
||||
nnextx = v0[x+1] + 2*v1[x+1] + 2*v2[x+1] + 2*v3[x+1] + v4[x+1];
|
||||
} else if (border == BORDER_MODE_REFLECT101) {
|
||||
nnextx = v0[x] + 2*v1[x] + 2*v2[x] + 2*v3[x] + v4[x];
|
||||
} else if (border == BORDER_MODE_CONSTANT) {
|
||||
nnextx = 8 * borderValue;
|
||||
}
|
||||
nextx = 2*v0[x+1] - 4*v2[x+1] + 2*v4[x+1];
|
||||
} else {
|
||||
nextx = 2*v0[x+1] - 4*v2[x+1] + 2*v4[x+1];
|
||||
nnextx = v0[x+2] + 2*v1[x+2] + 2*v2[x+2] + 2*v3[x+2] + v4[x+2];
|
||||
}
|
||||
s16 res = pprevx + prevx + currx + nextx + nnextx;
|
||||
*(drow+x) = 2*res;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)border;
|
||||
(void)borderValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+160
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "vtransform.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace {
|
||||
|
||||
struct Magnitude
|
||||
{
|
||||
typedef s16 type;
|
||||
|
||||
void operator() (const int16x8_t & v_src0, const int16x8_t & v_src1,
|
||||
int16x8_t & v_dst) const
|
||||
{
|
||||
int16x4_t v_src0_p = vget_low_s16(v_src0), v_src1_p = vget_low_s16(v_src1);
|
||||
float32x4_t v_sqr0 = vaddq_f32(vcvtq_f32_s32(vmull_s16(v_src0_p, v_src0_p)),
|
||||
vcvtq_f32_s32(vmull_s16(v_src1_p, v_src1_p)));
|
||||
v_src0_p = vget_high_s16(v_src0);
|
||||
v_src1_p = vget_high_s16(v_src1);
|
||||
float32x4_t v_sqr1 = vaddq_f32(vcvtq_f32_s32(vmull_s16(v_src0_p, v_src0_p)),
|
||||
vcvtq_f32_s32(vmull_s16(v_src1_p, v_src1_p)));
|
||||
|
||||
int32x4_t v_sqrt0 = vcvtq_s32_f32(internal::vsqrtq_f32(v_sqr0));
|
||||
int32x4_t v_sqrt1 = vcvtq_s32_f32(internal::vsqrtq_f32(v_sqr1));
|
||||
|
||||
v_dst = vcombine_s16(vqmovn_s32(v_sqrt0), vqmovn_s32(v_sqrt1));
|
||||
}
|
||||
|
||||
void operator() (const int16x4_t & v_src0, const int16x4_t & v_src1,
|
||||
int16x4_t & v_dst) const
|
||||
{
|
||||
float32x4_t v_tmp = vaddq_f32(vcvtq_f32_s32(vmull_s16(v_src0, v_src0)),
|
||||
vcvtq_f32_s32(vmull_s16(v_src1, v_src1)));
|
||||
int32x4_t v_sqrt = vcvtq_s32_f32(internal::vsqrtq_f32(v_tmp));
|
||||
v_dst = vqmovn_s32(v_sqrt);
|
||||
}
|
||||
|
||||
void operator() (const short * src0, const short * src1, short * dst) const
|
||||
{
|
||||
f32 src0val = (f32)src0[0], src1val = (f32)src1[0];
|
||||
dst[0] = internal::saturate_cast<s16>((s32)sqrtf(src0val * src0val + src1val * src1val));
|
||||
}
|
||||
};
|
||||
|
||||
struct MagnitudeF32
|
||||
{
|
||||
typedef f32 type;
|
||||
|
||||
void operator() (const float32x4_t & v_src0, const float32x4_t & v_src1,
|
||||
float32x4_t & v_dst) const
|
||||
{
|
||||
v_dst = internal::vsqrtq_f32(vaddq_f32(vmulq_f32(v_src0, v_src0), vmulq_f32(v_src1, v_src1)));
|
||||
}
|
||||
|
||||
void operator() (const float32x2_t & v_src0, const float32x2_t & v_src1,
|
||||
float32x2_t & v_dst) const
|
||||
{
|
||||
v_dst = internal::vsqrt_f32(vadd_f32(vmul_f32(v_src0, v_src0), vmul_f32(v_src1, v_src1)));
|
||||
}
|
||||
|
||||
void operator() (const f32 * src0, const f32 * src1, f32 * dst) const
|
||||
{
|
||||
dst[0] = sqrtf(src0[0] * src0[0] + src1[0] * src1[0]);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
void magnitude(const Size2D &size,
|
||||
const s16 * src0Base, ptrdiff_t src0Stride,
|
||||
const s16 * src1Base, ptrdiff_t src1Stride,
|
||||
s16 * dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
Magnitude());
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
void magnitude(const Size2D &size,
|
||||
const f32 * src0Base, ptrdiff_t src0Stride,
|
||||
const f32 * src1Base, ptrdiff_t src1Stride,
|
||||
f32 * dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
MagnitudeF32());
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+163
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
void meanStdDev(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
f32 * pMean, f32 * pStdDev)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
f64 fsum = 0.0f, fsqsum = 0.0f;
|
||||
sqsum(size, srcBase, srcStride, &fsum, &fsqsum, 1);
|
||||
|
||||
// calc mean and stddev
|
||||
f64 itotal = 1.0 / size.total();
|
||||
f64 mean = fsum * itotal;
|
||||
f64 stddev = sqrt(std::max(fsqsum * itotal - mean * mean, 0.0));
|
||||
|
||||
if (pMean)
|
||||
*pMean = mean;
|
||||
if (pStdDev)
|
||||
*pStdDev = stddev;
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)pMean;
|
||||
(void)pStdDev;
|
||||
#endif
|
||||
}
|
||||
|
||||
void meanStdDev(const Size2D &size,
|
||||
const u16 * srcBase, ptrdiff_t srcStride,
|
||||
f32 * pMean, f32 * pStdDev)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
size_t blockSize0 = 1 << 10, roiw4 = size.width & ~3;
|
||||
f64 fsum = 0.0f, fsqsum = 0.0f;
|
||||
|
||||
f32 arsum[8];
|
||||
uint32x4_t v_zero = vdupq_n_u32(0u), v_sum;
|
||||
float32x4_t v_zero_f = vdupq_n_f32(0.0f), v_sqsum;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const u16 * src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
size_t j = 0u;
|
||||
|
||||
while (j < roiw4)
|
||||
{
|
||||
size_t blockSize = std::min(roiw4 - j, blockSize0) + j;
|
||||
v_sum = v_zero;
|
||||
v_sqsum = v_zero_f;
|
||||
|
||||
for ( ; j + 16 < blockSize ; j += 16)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
uint16x8_t v_src0 = vld1q_u16(src + j), v_src1 = vld1q_u16(src + j + 8);
|
||||
|
||||
// 0
|
||||
uint32x4_t v_srclo = vmovl_u16(vget_low_u16(v_src0));
|
||||
uint32x4_t v_srchi = vmovl_u16(vget_high_u16(v_src0));
|
||||
v_sum = vaddq_u32(v_sum, vaddq_u32(v_srclo, v_srchi));
|
||||
float32x4_t v_srclo_f = vcvtq_f32_u32(v_srclo);
|
||||
float32x4_t v_srchi_f = vcvtq_f32_u32(v_srchi);
|
||||
v_sqsum = vmlaq_f32(v_sqsum, v_srclo_f, v_srclo_f);
|
||||
v_sqsum = vmlaq_f32(v_sqsum, v_srchi_f, v_srchi_f);
|
||||
|
||||
// 1
|
||||
v_srclo = vmovl_u16(vget_low_u16(v_src1));
|
||||
v_srchi = vmovl_u16(vget_high_u16(v_src1));
|
||||
v_sum = vaddq_u32(v_sum, vaddq_u32(v_srclo, v_srchi));
|
||||
v_srclo_f = vcvtq_f32_u32(v_srclo);
|
||||
v_srchi_f = vcvtq_f32_u32(v_srchi);
|
||||
v_sqsum = vmlaq_f32(v_sqsum, v_srclo_f, v_srclo_f);
|
||||
v_sqsum = vmlaq_f32(v_sqsum, v_srchi_f, v_srchi_f);
|
||||
}
|
||||
|
||||
for ( ; j < blockSize; j += 4)
|
||||
{
|
||||
uint32x4_t v_src = vmovl_u16(vld1_u16(src + j));
|
||||
float32x4_t v_src_f = vcvtq_f32_u32(v_src);
|
||||
v_sum = vaddq_u32(v_sum, v_src);
|
||||
v_sqsum = vmlaq_f32(v_sqsum, v_src_f, v_src_f);
|
||||
}
|
||||
|
||||
vst1q_f32(arsum, vcvtq_f32_u32(v_sum));
|
||||
vst1q_f32(arsum + 4, v_sqsum);
|
||||
|
||||
fsum += (f64)arsum[0] + arsum[1] + arsum[2] + arsum[3];
|
||||
fsqsum += (f64)arsum[4] + arsum[5] + arsum[6] + arsum[7];
|
||||
}
|
||||
|
||||
// collect a few last elements in the current row
|
||||
for ( ; j < size.width; ++j)
|
||||
{
|
||||
f32 srcval = src[j];
|
||||
fsum += srcval;
|
||||
fsqsum += srcval * srcval;
|
||||
}
|
||||
}
|
||||
|
||||
// calc mean and stddev
|
||||
f64 itotal = 1.0 / size.total();
|
||||
f64 mean = fsum * itotal;
|
||||
f64 stddev = sqrt(std::max(fsqsum * itotal - mean * mean, 0.0));
|
||||
|
||||
if (pMean)
|
||||
*pMean = mean;
|
||||
if (pStdDev)
|
||||
*pStdDev = stddev;
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)pMean;
|
||||
(void)pStdDev;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
+227
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2012-2014, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
/*
|
||||
* The code here is based on the code in
|
||||
* <http://ndevilla.free.fr/median/median/src/optmed.c>, which is in public domain.
|
||||
* See also <http://ndevilla.free.fr/median/median/index.html>.
|
||||
*/
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
namespace {
|
||||
|
||||
uint8x16_t getLeftReplicate(uint8x16_t r, u32 cn)
|
||||
{
|
||||
u8 buf[16+8];
|
||||
vst1q_u8(buf+cn, r);
|
||||
for (u32 i = 0; i < cn; ++i) buf[i] = buf[cn+i];
|
||||
return vld1q_u8(buf);
|
||||
}
|
||||
|
||||
uint8x8_t getRightReplicate(uint8x8_t r, u32 cn)
|
||||
{
|
||||
u8 buf[8+8];
|
||||
vst1_u8(buf, r);
|
||||
for (u32 i = 0; i < cn; ++i) buf[8+i] = buf[8-cn+i];
|
||||
return vld1_u8(buf+cn);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
//o------^-------^-----------------------------o 0
|
||||
// | |
|
||||
//o--^---v---^---|-------^---------------------o 1
|
||||
// | | | |
|
||||
//o--v-------v---|-------|-^-------^-------^---o 2
|
||||
// | | | | |
|
||||
//o------^-------v-----^-|-|-------|-------|---o 3
|
||||
// | | | | | |
|
||||
//o--^---v---^-----^---|-v-|---^---v---^---v---o 4
|
||||
// | | | | | | |
|
||||
//o--v-------v---^-|---|---v---|-------|-------o 5
|
||||
// | | | | |
|
||||
//o------^-------|-|---v-------|-------v-------o 6
|
||||
// | | | |
|
||||
//o--^---v---^---|-v-----------v---------------o 7
|
||||
// | | |
|
||||
//o--v-------v---v-----------------------------o 8
|
||||
|
||||
#define ELT(num, level) v ## num ## _lv ## level
|
||||
#define PIX_SORT(a, alvl, b, blvl, newlvl) \
|
||||
PIX_MIN(a, alvl, b, blvl, newlvl); \
|
||||
PIX_MAX(a, alvl, b, blvl, newlvl);
|
||||
|
||||
#define SORT9 \
|
||||
PIX_SORT(1, 00, 2, 00, 01); \
|
||||
PIX_SORT(4, 00, 5, 00, 02); \
|
||||
PIX_SORT(7, 00, 8, 00, 03); \
|
||||
PIX_SORT(0, 00, 1, 01, 04); \
|
||||
PIX_SORT(3, 00, 4, 02, 05); \
|
||||
PIX_SORT(6, 00, 7, 03, 06); \
|
||||
PIX_SORT(1, 04, 2, 01, 07); \
|
||||
PIX_SORT(4, 05, 5, 02, 08); \
|
||||
PIX_SORT(7, 06, 8, 03, 09); \
|
||||
PIX_MAX (0, 04, 3, 05, 10); \
|
||||
PIX_MIN (5, 08, 8, 09, 11); \
|
||||
PIX_SORT(4, 08, 7, 09, 12); \
|
||||
PIX_MAX (3, 10, 6, 06, 13); \
|
||||
PIX_MAX (1, 07, 4, 12, 14); \
|
||||
PIX_MIN (2, 07, 5, 11, 15); \
|
||||
PIX_MIN (4, 14, 7, 12, 16); \
|
||||
PIX_SORT(4, 16, 2, 15, 17); \
|
||||
PIX_MAX (6, 13, 4, 17, 18); \
|
||||
PIX_MIN (4, 18, 2, 17, 19);
|
||||
|
||||
#endif
|
||||
|
||||
bool isMedianFilter3x3Supported(const Size2D &size, u32 numChannels)
|
||||
{
|
||||
return isSupportedConfiguration() && size.width >= 16 + numChannels && numChannels <= 8;
|
||||
}
|
||||
|
||||
void medianFilter3x3(const Size2D &size, u32 numChannels,
|
||||
const u8 *srcBase, ptrdiff_t srcStride,
|
||||
const Margin &srcMargin,
|
||||
u8 *dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isMedianFilter3x3Supported(size, numChannels));
|
||||
#ifdef CAROTENE_NEON
|
||||
u32 cn = numChannels;
|
||||
size_t colsn = size.width * cn;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i) {
|
||||
const u8* psrc1 = internal::getRowPtr(srcBase, srcStride, i);
|
||||
const u8* psrc0 = i == 0 && srcMargin.top == 0 ? psrc1 : psrc1 - srcStride;
|
||||
const u8* psrc2 = i + 1 == size.height && srcMargin.bottom == 0 ? psrc1 : psrc1 + srcStride;
|
||||
u8* pdst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
{
|
||||
uint8x16_t v3_lv00 = vld1q_u8(psrc0);
|
||||
uint8x16_t v4_lv00 = vld1q_u8(psrc1);
|
||||
uint8x16_t v5_lv00 = vld1q_u8(psrc2);
|
||||
uint8x16_t v6_lv00 = vld1q_u8(psrc0 + cn);
|
||||
uint8x16_t v7_lv00 = vld1q_u8(psrc1 + cn);
|
||||
uint8x16_t v8_lv00 = vld1q_u8(psrc2 + cn);
|
||||
uint8x16_t v0_lv00 = srcMargin.left > 0 ? vld1q_u8(psrc0 - cn) : getLeftReplicate(v3_lv00, cn);
|
||||
uint8x16_t v1_lv00 = srcMargin.left > 0 ? vld1q_u8(psrc1 - cn) : getLeftReplicate(v4_lv00, cn);
|
||||
uint8x16_t v2_lv00 = srcMargin.left > 0 ? vld1q_u8(psrc2 - cn) : getLeftReplicate(v5_lv00, cn);
|
||||
|
||||
goto medianBlur3x3_mainBody;
|
||||
|
||||
for (; j < colsn - 16; j += 16) {
|
||||
internal::prefetch(psrc0 + j);
|
||||
internal::prefetch(psrc1 + j);
|
||||
internal::prefetch(psrc2 + j);
|
||||
|
||||
v0_lv00 = vld1q_u8(psrc0 + j - cn);
|
||||
v1_lv00 = vld1q_u8(psrc1 + j - cn);
|
||||
v2_lv00 = vld1q_u8(psrc2 + j - cn);
|
||||
v3_lv00 = vld1q_u8(psrc0 + j);
|
||||
v4_lv00 = vld1q_u8(psrc1 + j);
|
||||
v5_lv00 = vld1q_u8(psrc2 + j);
|
||||
v6_lv00 = vld1q_u8(psrc0 + j + cn);
|
||||
v7_lv00 = vld1q_u8(psrc1 + j + cn);
|
||||
v8_lv00 = vld1q_u8(psrc2 + j + cn);
|
||||
|
||||
medianBlur3x3_mainBody:
|
||||
|
||||
#define PIX_MIN(a, alvl, b, blvl, newlvl) uint8x16_t ELT(a, newlvl) = vminq_u8(ELT(a, alvl), ELT(b, blvl))
|
||||
#define PIX_MAX(a, alvl, b, blvl, newlvl) uint8x16_t ELT(b, newlvl) = vmaxq_u8(ELT(a, alvl), ELT(b, blvl))
|
||||
SORT9;
|
||||
#undef PIX_MAX
|
||||
#undef PIX_MIN
|
||||
|
||||
vst1q_u8(pdst + j, v4_lv19);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
size_t k = colsn - 8;
|
||||
uint8x8_t v0_lv00 = vld1_u8(psrc0 + k - cn);
|
||||
uint8x8_t v1_lv00 = vld1_u8(psrc1 + k - cn);
|
||||
uint8x8_t v2_lv00 = vld1_u8(psrc2 + k - cn);
|
||||
uint8x8_t v3_lv00 = vld1_u8(psrc0 + k);
|
||||
uint8x8_t v4_lv00 = vld1_u8(psrc1 + k);
|
||||
uint8x8_t v5_lv00 = vld1_u8(psrc2 + k);
|
||||
uint8x8_t v6_lv00 = srcMargin.right > 0 ? vld1_u8(psrc0 + k + cn) : getRightReplicate(v3_lv00, cn);
|
||||
uint8x8_t v7_lv00 = srcMargin.right > 0 ? vld1_u8(psrc1 + k + cn) : getRightReplicate(v4_lv00, cn);
|
||||
uint8x8_t v8_lv00 = srcMargin.right > 0 ? vld1_u8(psrc2 + k + cn) : getRightReplicate(v5_lv00, cn);
|
||||
|
||||
goto medianBlur3x3_tailBody;
|
||||
|
||||
for (; k >= j - 8; k -= 8) {
|
||||
v0_lv00 = vld1_u8(psrc0 + k - cn);
|
||||
v1_lv00 = vld1_u8(psrc1 + k - cn);
|
||||
v2_lv00 = vld1_u8(psrc2 + k - cn);
|
||||
v3_lv00 = vld1_u8(psrc0 + k);
|
||||
v4_lv00 = vld1_u8(psrc1 + k);
|
||||
v5_lv00 = vld1_u8(psrc2 + k);
|
||||
v6_lv00 = vld1_u8(psrc0 + k + cn);
|
||||
v7_lv00 = vld1_u8(psrc1 + k + cn);
|
||||
v8_lv00 = vld1_u8(psrc2 + k + cn);
|
||||
|
||||
medianBlur3x3_tailBody:
|
||||
|
||||
#define PIX_MIN(a, alvl, b, blvl, newlvl) uint8x8_t ELT(a, newlvl) = vmin_u8(ELT(a, alvl), ELT(b, blvl))
|
||||
#define PIX_MAX(a, alvl, b, blvl, newlvl) uint8x8_t ELT(b, newlvl) = vmax_u8(ELT(a, alvl), ELT(b, blvl))
|
||||
SORT9;
|
||||
#undef PIX_MAX
|
||||
#undef PIX_MIN
|
||||
|
||||
vst1_u8(pdst + k, v4_lv19);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)numChannels;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)srcMargin;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+139
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "common.hpp"
|
||||
#include "vtransform.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
struct Min
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec128 & v_src0,
|
||||
const typename internal::VecTraits<T>::vec128 & v_src1,
|
||||
typename internal::VecTraits<T>::vec128 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vminq(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec64 & v_src0,
|
||||
const typename internal::VecTraits<T>::vec64 & v_src1,
|
||||
typename internal::VecTraits<T>::vec64 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vmin(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const T * src0, const T * src1, T * dst) const
|
||||
{
|
||||
dst[0] = std::min(src0[0], src1[0]);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Max
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec128 & v_src0,
|
||||
const typename internal::VecTraits<T>::vec128 & v_src1,
|
||||
typename internal::VecTraits<T>::vec128 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vmaxq(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec64 & v_src0,
|
||||
const typename internal::VecTraits<T>::vec64 & v_src1,
|
||||
typename internal::VecTraits<T>::vec64 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vmax(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const T * src0, const T * src1, T * dst) const
|
||||
{
|
||||
dst[0] = std::max(src0[0], src1[0]);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#define IMPL_OP(fun, op, type) \
|
||||
void fun(const Size2D &size, \
|
||||
const type * src0Base, ptrdiff_t src0Stride, \
|
||||
const type * src1Base, ptrdiff_t src1Stride, \
|
||||
type * dstBase, ptrdiff_t dstStride) \
|
||||
{ \
|
||||
internal::assertSupportedConfiguration(); \
|
||||
internal::vtransform(size, \
|
||||
src0Base, src0Stride, \
|
||||
src1Base, src1Stride, \
|
||||
dstBase, dstStride, op<type>()); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define IMPL_OP(fun, op, type) \
|
||||
void fun(const Size2D &, \
|
||||
const type *, ptrdiff_t, \
|
||||
const type *, ptrdiff_t, \
|
||||
type *, ptrdiff_t) \
|
||||
{ \
|
||||
internal::assertSupportedConfiguration(); \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define IMPL_MINMAX(type) IMPL_OP(min, Min, type) IMPL_OP(max, Max, type)
|
||||
|
||||
IMPL_MINMAX(u8)
|
||||
IMPL_MINMAX(s8)
|
||||
IMPL_MINMAX(u16)
|
||||
IMPL_MINMAX(s16)
|
||||
IMPL_MINMAX(u32)
|
||||
IMPL_MINMAX(s32)
|
||||
IMPL_MINMAX(f32)
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+1340
File diff suppressed because it is too large
Load Diff
Vendored
+728
@@ -0,0 +1,728 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
bool isMorph3x3Supported(const Size2D &size, BORDER_MODE border)
|
||||
{
|
||||
return isSupportedConfiguration() && size.width >= 16 &&
|
||||
(border == BORDER_MODE_CONSTANT ||
|
||||
border == BORDER_MODE_REPLICATE);
|
||||
}
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace {
|
||||
|
||||
struct ErodeVecOp
|
||||
{
|
||||
ErodeVecOp():borderValue(0){}
|
||||
|
||||
ErodeVecOp(BORDER_MODE border, u8 borderValue_) :
|
||||
borderValue(borderValue_)
|
||||
{
|
||||
if (border == BORDER_MODE_REPLICATE)
|
||||
borderValue = std::numeric_limits<u8>::max();
|
||||
}
|
||||
|
||||
inline uint8x16_t operator()(uint8x16_t a, uint8x16_t b) const
|
||||
{
|
||||
return vminq_u8(a, b);
|
||||
}
|
||||
|
||||
inline uint8x8_t operator()(uint8x8_t a, uint8x8_t b) const
|
||||
{
|
||||
return vmin_u8(a, b);
|
||||
}
|
||||
|
||||
inline u8 operator()(u8 a, u8 b) const
|
||||
{
|
||||
return std::min(a, b);
|
||||
}
|
||||
|
||||
u8 borderValue;
|
||||
};
|
||||
|
||||
struct DilateVecOp
|
||||
{
|
||||
DilateVecOp():borderValue(0){}
|
||||
|
||||
DilateVecOp(BORDER_MODE border, u8 borderValue_) :
|
||||
borderValue(borderValue_)
|
||||
{
|
||||
if (border == BORDER_MODE_REPLICATE)
|
||||
borderValue = std::numeric_limits<u8>::min();
|
||||
}
|
||||
|
||||
inline uint8x16_t operator()(uint8x16_t a, uint8x16_t b) const
|
||||
{
|
||||
return vmaxq_u8(a, b);
|
||||
}
|
||||
|
||||
inline uint8x8_t operator()(uint8x8_t a, uint8x8_t b) const
|
||||
{
|
||||
return vmax_u8(a, b);
|
||||
}
|
||||
|
||||
inline u8 operator()(u8 a, u8 b) const
|
||||
{
|
||||
return std::max(a, b);
|
||||
}
|
||||
|
||||
u8 borderValue;
|
||||
};
|
||||
|
||||
template <typename VecOp>
|
||||
void morph3x3(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
BORDER_MODE border, const VecOp & vop)
|
||||
{
|
||||
u8 borderValue = vop.borderValue;
|
||||
ptrdiff_t width = (ptrdiff_t)size.width, height = (ptrdiff_t)size.height;
|
||||
|
||||
const uint8x16_t v_zero = vdupq_n_u8(0);
|
||||
const uint8x16_t v_border = vdupq_n_u8(borderValue);
|
||||
|
||||
uint8x16_t tprev = v_zero, tcurr = v_zero, tnext = v_zero;
|
||||
uint8x16_t t0 = v_zero, t1 = v_zero, t2 = v_zero;
|
||||
|
||||
for (ptrdiff_t y = 0; y < height; ++y)
|
||||
{
|
||||
const u8 * srow0 = y == 0 && border == BORDER_MODE_CONSTANT ? NULL : internal::getRowPtr(srcBase, srcStride, std::max<ptrdiff_t>(y - 1, 0));
|
||||
const u8 * srow1 = internal::getRowPtr(srcBase, srcStride, y);
|
||||
const u8 * srow2 = y + 1 == height && border == BORDER_MODE_CONSTANT ? NULL : internal::getRowPtr(srcBase, srcStride, std::min(y + 1, height - 1));
|
||||
u8 * drow = internal::getRowPtr(dstBase, dstStride, y);
|
||||
|
||||
u8 prevx = 0, currx = 0, nextx = 0;
|
||||
ptrdiff_t x = 0;
|
||||
const ptrdiff_t bwidth = y + 2 < height ? width : (width - 16);
|
||||
|
||||
// perform vertical convolution
|
||||
for ( ; x <= bwidth; x += 16)
|
||||
{
|
||||
internal::prefetch(srow0 + x);
|
||||
internal::prefetch(srow1 + x);
|
||||
internal::prefetch(srow2 + x);
|
||||
|
||||
uint8x16_t x0 = !srow0 ? v_border : vld1q_u8(srow0 + x);
|
||||
uint8x16_t x1 = vld1q_u8(srow1 + x);
|
||||
uint8x16_t x2 = !srow2 ? v_border : vld1q_u8(srow2 + x);
|
||||
|
||||
// calculate values for plain CPU part below if needed
|
||||
if (x + 16 >= bwidth)
|
||||
{
|
||||
ptrdiff_t x3 = x == width ? width - 1 : x;
|
||||
ptrdiff_t x4 = border == BORDER_MODE_CONSTANT ? x3 - 1 : std::max<ptrdiff_t>(x3 - 1, 0);
|
||||
|
||||
if (border == BORDER_MODE_CONSTANT && x4 < 0)
|
||||
prevx = borderValue;
|
||||
else
|
||||
prevx = vop(srow1[x4],
|
||||
vop(srow2 ? srow2[x4] : borderValue,
|
||||
srow0 ? srow0[x4] : borderValue));
|
||||
|
||||
currx = vop(srow2 ? srow2[x3] : borderValue, vop(srow1[x3], srow0 ? srow0[x3] : borderValue));
|
||||
}
|
||||
|
||||
// make shift
|
||||
if (x)
|
||||
{
|
||||
tprev = tcurr;
|
||||
tcurr = tnext;
|
||||
}
|
||||
|
||||
// and calculate next value
|
||||
tnext = vop(vop(x0, x1), x2);
|
||||
|
||||
// make extrapolation for the first elements
|
||||
if (!x)
|
||||
{
|
||||
// make border
|
||||
if (border == BORDER_MODE_CONSTANT)
|
||||
tcurr = v_border;
|
||||
else if (border == BORDER_MODE_REPLICATE)
|
||||
tcurr = vdupq_n_u8(vgetq_lane_u8(tnext, 0));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// combine 3 "shifted" vectors
|
||||
t0 = vextq_u8(tprev, tcurr, 15);
|
||||
t1 = tcurr;
|
||||
t2 = vextq_u8(tcurr, tnext, 1);
|
||||
|
||||
// and add them
|
||||
t0 = vop(t0, vop(t1, t2));
|
||||
|
||||
vst1q_u8(drow + x - 16, t0);
|
||||
}
|
||||
|
||||
x -= 16;
|
||||
if (x == width)
|
||||
--x;
|
||||
|
||||
for ( ; x < width; ++x)
|
||||
{
|
||||
// make extrapolation for the last elements
|
||||
if (x + 1 >= width)
|
||||
{
|
||||
if (border == BORDER_MODE_CONSTANT)
|
||||
nextx = borderValue;
|
||||
else if (border == BORDER_MODE_REPLICATE)
|
||||
nextx = vop(srow2[x], vop(srow1[x], srow0[x]));
|
||||
}
|
||||
else
|
||||
nextx = vop(vop(srow2 ? srow2[x + 1] : borderValue,
|
||||
srow0 ? srow0[x + 1] : borderValue),
|
||||
srow1[x + 1]);
|
||||
|
||||
drow[x] = vop(prevx, vop(currx, nextx));
|
||||
|
||||
// make shift
|
||||
prevx = currx;
|
||||
currx = nextx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
void erode3x3(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
BORDER_MODE border, u8 borderValue)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isMorph3x3Supported(size, border));
|
||||
#ifdef CAROTENE_NEON
|
||||
morph3x3(size,
|
||||
srcBase, srcStride,
|
||||
dstBase, dstStride,
|
||||
border, ErodeVecOp(border, borderValue));
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)border;
|
||||
(void)borderValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
void dilate3x3(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
BORDER_MODE border, u8 borderValue)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isMorph3x3Supported(size, border));
|
||||
#ifdef CAROTENE_NEON
|
||||
morph3x3(size,
|
||||
srcBase, srcStride,
|
||||
dstBase, dstStride,
|
||||
border, DilateVecOp(border, borderValue));
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)border;
|
||||
(void)borderValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
namespace {
|
||||
|
||||
template<class VecUpdate>
|
||||
void MorphRow(const u8* src, u8* dst, size_t width, s32 cn, size_t ksize)
|
||||
{
|
||||
size_t i, j, k;
|
||||
size_t width16 = (width & -16) * cn;
|
||||
size_t width8 = (width & -8) * cn;
|
||||
width *= cn;
|
||||
|
||||
if (ksize == 1)
|
||||
{
|
||||
for (i = 0; i < width; i++)
|
||||
dst[i] = src[i];
|
||||
return;
|
||||
}
|
||||
|
||||
ksize = ksize*cn;
|
||||
VecUpdate updateOp;
|
||||
switch(cn)
|
||||
{
|
||||
case 1:
|
||||
for (i = 0; i < width16; i += 16)
|
||||
{
|
||||
const u8* sptr = src + i;
|
||||
uint8x16_t s = vld1q_u8(sptr);
|
||||
internal::prefetch(sptr);
|
||||
|
||||
for( k = 1; k < ksize; ++k)
|
||||
s = updateOp(s, vld1q_u8(sptr + k));
|
||||
|
||||
vst1q_u8(dst + i, s);
|
||||
}
|
||||
|
||||
for (; i < width8; i += 8)
|
||||
{
|
||||
const u8* sptr = src + i;
|
||||
uint8x8_t s = vld1_u8(sptr);
|
||||
internal::prefetch(sptr);
|
||||
|
||||
for( k = 1; k < ksize; ++k)
|
||||
s = updateOp(s, vld1_u8(sptr + k));
|
||||
|
||||
vst1_u8(dst + i, s);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (i = 0; i < width16; i += 16)
|
||||
{
|
||||
uint8x16_t s = vld1q_u8(src + i);
|
||||
internal::prefetch(src + i);
|
||||
|
||||
for (k = cn; k < ksize; k += cn)
|
||||
s = updateOp(s, vld1q_u8(src + i + k));
|
||||
|
||||
vst1q_u8(dst + i, s);
|
||||
}
|
||||
|
||||
for (; i < width8; i += 8)
|
||||
{
|
||||
uint8x8_t s = vld1_u8(src + i);
|
||||
internal::prefetch(src + i);
|
||||
|
||||
for (k = cn; k < ksize; k += cn)
|
||||
s = updateOp(s, vld1_u8(src + i + k));
|
||||
|
||||
vst1_u8(dst + i, s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ptrdiff_t i0 = i;
|
||||
for( k = 0; k < (size_t)cn; k++, src++, dst++ )
|
||||
{
|
||||
for( i = i0; i <= width - cn*2; i += cn*2 )
|
||||
{
|
||||
const u8* s = src + i;
|
||||
u8 m = s[cn];
|
||||
for( j = cn*2; j < ksize; j += cn )
|
||||
m = updateOp(m, s[j]);
|
||||
dst[i] = updateOp(m, s[0]);
|
||||
dst[i+cn] = updateOp(m, s[j]);
|
||||
}
|
||||
|
||||
for( ; i < width; i += cn )
|
||||
{
|
||||
const u8* s = src + i;
|
||||
u8 m = s[0];
|
||||
for( j = cn; j < ksize; j += cn )
|
||||
m = updateOp(m, s[j]);
|
||||
dst[i] = m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class VecUpdate>
|
||||
void MorphColumn(const u8** src, u8* dst, ptrdiff_t dststep, size_t count, size_t width, size_t ksize)
|
||||
{
|
||||
size_t i, k;
|
||||
size_t width32 = width & -32;
|
||||
VecUpdate updateOp;
|
||||
|
||||
uint8x16_t x0,x1,s0,s1;
|
||||
if (ksize == 3)
|
||||
{
|
||||
for (; count > 1; count -= 2, dst += dststep * 2, src += 2)
|
||||
{
|
||||
for (i = 0; i < width32; i += 32)
|
||||
{
|
||||
const u8* sptr = src[1] + i;
|
||||
s0 = vld1q_u8(sptr);
|
||||
s1 = vld1q_u8(sptr + 16);
|
||||
internal::prefetch(sptr);
|
||||
|
||||
sptr = src[2] + i;
|
||||
x0 = vld1q_u8(sptr);
|
||||
x1 = vld1q_u8(sptr + 16);
|
||||
internal::prefetch(sptr);
|
||||
|
||||
s0 = updateOp(s0, x0);
|
||||
s1 = updateOp(s1, x1);
|
||||
|
||||
sptr = src[0] + i;
|
||||
x0 = vld1q_u8(sptr);
|
||||
x1 = vld1q_u8(sptr + 16);
|
||||
internal::prefetch(sptr);
|
||||
|
||||
vst1q_u8(dst+i, updateOp(s0, x0));
|
||||
vst1q_u8(dst+i+16, updateOp(s1, x1));
|
||||
|
||||
sptr = src[3] + i;
|
||||
x0 = vld1q_u8(sptr);
|
||||
x1 = vld1q_u8(sptr + 16);
|
||||
internal::prefetch(sptr);
|
||||
vst1q_u8(dst + dststep + i, updateOp(s0, x0));
|
||||
vst1q_u8(dst + dststep + i + 16, updateOp(s1, x1));
|
||||
|
||||
}
|
||||
for(; i < width; i++ )
|
||||
{
|
||||
u8 s = src[1][i];
|
||||
|
||||
for( k = 2; k < ksize; k++ )
|
||||
s = updateOp(s, src[k][i]);
|
||||
|
||||
dst[i] = updateOp(s, src[0][i]);
|
||||
dst[i+dststep] = updateOp(s, src[k][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ksize > 1)
|
||||
for (; count > 1; count -= 2, dst += dststep*2, src += 2)
|
||||
{
|
||||
for (i = 0; i < width32; i += 32)
|
||||
{
|
||||
const u8* sptr = src[1] + i;
|
||||
s0 = vld1q_u8(sptr);
|
||||
s1 = vld1q_u8(sptr + 16);
|
||||
internal::prefetch(sptr);
|
||||
for (k = 2; k < ksize; k++)
|
||||
{
|
||||
sptr = src[k] + i;
|
||||
x0 = vld1q_u8(sptr);
|
||||
x1 = vld1q_u8(sptr + 16);
|
||||
internal::prefetch(sptr);
|
||||
|
||||
s0 = updateOp(s0, x0);
|
||||
s1 = updateOp(s1, x1);
|
||||
}
|
||||
|
||||
sptr = src[0] + i;
|
||||
x0 = vld1q_u8(sptr);
|
||||
x1 = vld1q_u8(sptr + 16);
|
||||
internal::prefetch(sptr);
|
||||
|
||||
vst1q_u8(dst+i, updateOp(s0, x0));
|
||||
vst1q_u8(dst+i+16, updateOp(s1, x1));
|
||||
|
||||
sptr = src[k] + i;
|
||||
x0 = vld1q_u8(sptr);
|
||||
x1 = vld1q_u8(sptr + 16);
|
||||
internal::prefetch(sptr);
|
||||
vst1q_u8(dst + dststep + i, updateOp(s0, x0));
|
||||
vst1q_u8(dst + dststep + i + 16, updateOp(s1, x1));
|
||||
}
|
||||
for(; i < width; i++ )
|
||||
{
|
||||
u8 s = src[1][i];
|
||||
|
||||
for( k = 2; k < ksize; k++ )
|
||||
s = updateOp(s, src[k][i]);
|
||||
|
||||
dst[i] = updateOp(s, src[0][i]);
|
||||
dst[i+dststep] = updateOp(s, src[k][i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (; count > 0; count--, dst += dststep, src++)
|
||||
{
|
||||
for (i = 0; i < width32; i += 32)
|
||||
{
|
||||
const u8* sptr = src[0] + i;
|
||||
s0 = vld1q_u8(sptr);
|
||||
s1 = vld1q_u8(sptr + 16);
|
||||
internal::prefetch(sptr);
|
||||
|
||||
for (k = 1; k < ksize; k++)
|
||||
{
|
||||
sptr = src[k] + i;
|
||||
x0 = vld1q_u8(sptr);
|
||||
x1 = vld1q_u8(sptr + 16);
|
||||
internal::prefetch(sptr);
|
||||
s0 = updateOp(s0, x0);
|
||||
s1 = updateOp(s1, x1);
|
||||
}
|
||||
|
||||
vst1q_u8(dst + i, s0);
|
||||
vst1q_u8(dst + i + 16, s1);
|
||||
}
|
||||
for(; i < width; i++ )
|
||||
{
|
||||
u8 s = src[0][i];
|
||||
for( k = 1; k < ksize; k++ )
|
||||
s = updateOp(s, src[k][i]);
|
||||
dst[i] = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Op>
|
||||
inline void morphology(const Size2D &ssize, u32 cn,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
const Size2D &ksize,
|
||||
size_t anchorX, size_t anchorY,
|
||||
BORDER_MODE rowBorderType, BORDER_MODE columnBorderType,
|
||||
const u8 * borderValues, Margin borderMargin)
|
||||
{
|
||||
//Temporary buffers common for all iterations
|
||||
std::vector<u8> _srcRow(cn*(ssize.width + ksize.width - 1));
|
||||
u8* srcRow = &_srcRow[0];
|
||||
|
||||
size_t bufRows = std::max<size_t>(ksize.height + 3, std::max<size_t>(anchorY, ksize.height-anchorY-1)*2+1);
|
||||
std::vector<u8*> _rows(bufRows);
|
||||
u8** rows = &_rows[0];
|
||||
|
||||
// adjust swidthcn so that the used part of buffers stays compact in memory
|
||||
ptrdiff_t swidthcn = cn*((ssize.width + 15) & -16);// cn * (aligned ssize.width size)
|
||||
std::vector<u8> _ringBuf(swidthcn*bufRows+16);
|
||||
u8 * ringBuf = internal::alignPtr(&_ringBuf[0], 16);
|
||||
|
||||
size_t borderLength = std::max<size_t>(ksize.width - 1, 1) * cn;
|
||||
std::vector<ptrdiff_t> _borderTab(borderLength);
|
||||
ptrdiff_t * borderTab = &_borderTab[0];
|
||||
|
||||
std::vector<u8> _constBorderValue;
|
||||
std::vector<u8> _constBorderRow;
|
||||
u8 * constBorderValue = NULL;
|
||||
u8 * constBorderRow = NULL;
|
||||
if( rowBorderType == BORDER_MODE_CONSTANT || columnBorderType == BORDER_MODE_CONSTANT )
|
||||
{
|
||||
_constBorderValue.resize(borderLength);
|
||||
constBorderValue = &_constBorderValue[0];
|
||||
size_t i;
|
||||
for(i = 0; i < cn; i++)
|
||||
constBorderValue[i] = borderValues[i];
|
||||
for(; i < borderLength; i++)
|
||||
constBorderValue[i] = constBorderValue[i-cn];
|
||||
|
||||
if( columnBorderType == BORDER_MODE_CONSTANT )
|
||||
{
|
||||
_constBorderRow.resize(cn*(ssize.width + ksize.width - 1 + 16));
|
||||
constBorderRow = internal::alignPtr(&_constBorderRow[0], 16);
|
||||
size_t N = (ssize.width + ksize.width - 1)*cn;
|
||||
for( i = 0; i < N; i += borderLength )
|
||||
{
|
||||
size_t n = std::min( borderLength, N - i );
|
||||
for(size_t j = 0; j < n; j++)
|
||||
srcRow[i+j] = constBorderValue[j];
|
||||
}
|
||||
MorphRow<Op>(srcRow, constBorderRow, ssize.width, cn, ksize.width);
|
||||
}
|
||||
}
|
||||
|
||||
Size2D wholeSize(ssize.width + borderMargin.left + borderMargin.right,
|
||||
ssize.height + borderMargin.top + borderMargin.bottom);
|
||||
|
||||
ptrdiff_t dx1 = std::max<ptrdiff_t>(anchorX - (ptrdiff_t)borderMargin.left, 0);
|
||||
ptrdiff_t dx2 = std::max<ptrdiff_t>((ptrdiff_t)ksize.width - anchorX - 1 - (ptrdiff_t)borderMargin.right, 0);
|
||||
// recompute border tables
|
||||
if( dx1 > 0 || dx2 > 0 )
|
||||
{
|
||||
if( rowBorderType == BORDER_MODE_CONSTANT )
|
||||
{
|
||||
memcpy( srcRow, &constBorderValue[0], dx1*cn );
|
||||
memcpy( srcRow + (ssize.width + ksize.width - 1 - dx2)*cn, &constBorderValue[0], dx2*cn );
|
||||
}
|
||||
else
|
||||
{
|
||||
ptrdiff_t xofs1 = std::min<ptrdiff_t>(borderMargin.left, anchorX) - borderMargin.left;
|
||||
|
||||
ptrdiff_t wholeWidth = wholeSize.width;
|
||||
|
||||
ptrdiff_t i, j;
|
||||
for( i = 0; i < dx1; i++ )
|
||||
{
|
||||
ptrdiff_t p0 = (internal::borderInterpolate(i-dx1, wholeWidth, rowBorderType) + xofs1)*cn;
|
||||
for( j = 0; j < (ptrdiff_t)cn; j++ )
|
||||
borderTab[i*cn + j] = p0 + j;
|
||||
}
|
||||
|
||||
for( i = 0; i < dx2; i++ )
|
||||
{
|
||||
ptrdiff_t p0 = (internal::borderInterpolate(wholeWidth + i, wholeWidth, rowBorderType) + xofs1)*cn;
|
||||
for( j = 0; j < (ptrdiff_t)cn; j++ )
|
||||
borderTab[(i + dx1)*cn + j] = p0 + j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ptrdiff_t startY, startY0, endY, rowCount;
|
||||
startY = startY0 = std::max<ptrdiff_t>(borderMargin.top - anchorY, 0);
|
||||
endY = std::min<ptrdiff_t>(borderMargin.top + ssize.height + ksize.height - anchorY - 1, wholeSize.height);
|
||||
|
||||
const u8* src = srcBase + (startY - borderMargin.top)*srcStride;
|
||||
u8* dst = dstBase;
|
||||
|
||||
ptrdiff_t width = ssize.width, kwidth = ksize.width;
|
||||
ptrdiff_t kheight = ksize.height, ay = anchorY;
|
||||
ptrdiff_t width1 = ssize.width + kwidth - 1;
|
||||
ptrdiff_t xofs1 = std::min<ptrdiff_t>(borderMargin.left, anchorX);
|
||||
bool makeBorder = (dx1 > 0 || dx2 > 0) && rowBorderType != BORDER_MODE_CONSTANT;
|
||||
ptrdiff_t dy = 0, i = 0;
|
||||
|
||||
src -= xofs1*cn;
|
||||
ptrdiff_t count = endY - startY;
|
||||
|
||||
rowCount = 0;
|
||||
for(;; dst += dstStride*i, dy += i)
|
||||
{
|
||||
ptrdiff_t dcount = bufRows - ay - startY - rowCount + borderMargin.top;
|
||||
dcount = dcount > 0 ? dcount : bufRows - kheight + 1;
|
||||
dcount = std::min(dcount, count);
|
||||
count -= dcount;
|
||||
for( ; dcount-- > 0; src += srcStride )
|
||||
{
|
||||
ptrdiff_t bi = (startY - startY0 + rowCount) % bufRows;
|
||||
u8* brow = ringBuf + bi*swidthcn;
|
||||
|
||||
if( (size_t)(++rowCount) > bufRows )
|
||||
{
|
||||
--rowCount;
|
||||
++startY;
|
||||
}
|
||||
|
||||
memcpy( srcRow + dx1*cn, src, (width1 - dx2 - dx1)*cn );
|
||||
|
||||
if( makeBorder )
|
||||
{
|
||||
for( i = 0; i < (ptrdiff_t)(dx1*cn); i++ )
|
||||
srcRow[i] = src[borderTab[i]];
|
||||
for( i = 0; i < (ptrdiff_t)(dx2*cn); i++ )
|
||||
srcRow[i + (width1 - dx2)*cn] = src[borderTab[i+dx1*cn]];
|
||||
}
|
||||
|
||||
MorphRow<Op>(srcRow, brow, width, cn, ksize.width);
|
||||
}
|
||||
|
||||
ptrdiff_t max_i = std::min<ptrdiff_t>(bufRows, ssize.height - dy + (kheight - 1));
|
||||
for( i = 0; i < max_i; i++ )
|
||||
{
|
||||
ptrdiff_t srcY = internal::borderInterpolate(dy + i + borderMargin.top - ay,
|
||||
wholeSize.height, columnBorderType);
|
||||
if( srcY < 0 ) // can happen only with constant border type
|
||||
rows[i] = constBorderRow;
|
||||
else
|
||||
{
|
||||
if( srcY >= startY + rowCount )
|
||||
break;
|
||||
ptrdiff_t bi = (srcY - startY0) % bufRows;
|
||||
rows[i] = ringBuf + bi*swidthcn;
|
||||
}
|
||||
}
|
||||
if( i < kheight )
|
||||
break;
|
||||
i -= kheight - 1;
|
||||
MorphColumn<Op>((const u8**)rows, dst, dstStride, i, ssize.width*cn, ksize.height);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
#endif // CAROTENE_NEON
|
||||
|
||||
void erode(const Size2D &ssize, u32 cn,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
const Size2D &ksize,
|
||||
size_t anchorX, size_t anchorY,
|
||||
BORDER_MODE rowBorderType, BORDER_MODE columnBorderType,
|
||||
const u8 * borderValues, Margin borderMargin)
|
||||
{
|
||||
internal::assertSupportedConfiguration(ssize.width > 0 && ssize.height > 0 &&
|
||||
anchorX < ksize.width && anchorY < ksize.height);
|
||||
#ifdef CAROTENE_NEON
|
||||
morphology<ErodeVecOp>(ssize, cn, srcBase, srcStride, dstBase, dstStride,
|
||||
ksize, anchorX, anchorY, rowBorderType, columnBorderType,
|
||||
borderValues, borderMargin);
|
||||
#else
|
||||
(void)cn;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)rowBorderType;
|
||||
(void)columnBorderType;
|
||||
(void)borderValues;
|
||||
(void)borderMargin;
|
||||
#endif
|
||||
}
|
||||
|
||||
void dilate(const Size2D &ssize, u32 cn,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
const Size2D &ksize,
|
||||
size_t anchorX, size_t anchorY,
|
||||
BORDER_MODE rowBorderType, BORDER_MODE columnBorderType,
|
||||
const u8 * borderValues, Margin borderMargin)
|
||||
{
|
||||
internal::assertSupportedConfiguration(ssize.width > 0 && ssize.height > 0 &&
|
||||
anchorX < ksize.width && anchorY < ksize.height);
|
||||
#ifdef CAROTENE_NEON
|
||||
morphology<DilateVecOp>(ssize, cn, srcBase, srcStride, dstBase, dstStride,
|
||||
ksize, anchorX, anchorY, rowBorderType, columnBorderType,
|
||||
borderValues, borderMargin);
|
||||
#else
|
||||
(void)cn;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)rowBorderType;
|
||||
(void)columnBorderType;
|
||||
(void)borderValues;
|
||||
(void)borderMargin;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+1572
File diff suppressed because it is too large
Load Diff
Vendored
+1310
File diff suppressed because it is too large
Load Diff
+539
@@ -0,0 +1,539 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2012-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "saturate_cast.hpp"
|
||||
#include <vector>
|
||||
#include <float.h> // For FLT_EPSILON
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#define CV_DESCALE(x,n) (((x) + (1 << ((n)-1))) >> (n))
|
||||
|
||||
/*
|
||||
* Pyramidal Lucas-Kanade Optical Flow level processing
|
||||
*/
|
||||
void pyrLKOptFlowLevel(const Size2D &size, s32 cn,
|
||||
const u8 *prevData, ptrdiff_t prevStride,
|
||||
const s16 *prevDerivData, ptrdiff_t prevDerivStride,
|
||||
const u8 *nextData, ptrdiff_t nextStride,
|
||||
u32 ptCount,
|
||||
const f32 *prevPts, f32 *nextPts,
|
||||
u8 *status, f32 *err,
|
||||
const Size2D &winSize,
|
||||
u32 terminationCount, f64 terminationEpsilon,
|
||||
u32 level, u32 maxLevel, bool useInitialFlow, bool getMinEigenVals,
|
||||
f32 minEigThreshold)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
f32 halfWinX = (winSize.width-1)*0.5f, halfWinY = (winSize.height-1)*0.5f;
|
||||
s32 cn2 = cn*2;
|
||||
|
||||
std::vector<s16> _buf(winSize.total()*(cn + cn2));
|
||||
s16* IWinBuf = &_buf[0];
|
||||
s32 IWinBufStride = winSize.width*cn;
|
||||
s16* derivIWinBuf = &_buf[winSize.total()*cn];
|
||||
s32 derivIWinBufStride = winSize.width*cn2;
|
||||
|
||||
for( u32 ptidx = 0; ptidx < ptCount; ptidx++ )
|
||||
{
|
||||
f32 levscale = (1./(1 << level));
|
||||
u32 ptref = ptidx << 1;
|
||||
f32 prevPtX = prevPts[ptref+0]*levscale;
|
||||
f32 prevPtY = prevPts[ptref+1]*levscale;
|
||||
f32 nextPtX;
|
||||
f32 nextPtY;
|
||||
if( level == maxLevel )
|
||||
{
|
||||
if( useInitialFlow )
|
||||
{
|
||||
nextPtX = nextPts[ptref+0]*levscale;
|
||||
nextPtY = nextPts[ptref+1]*levscale;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextPtX = prevPtX;
|
||||
nextPtY = prevPtY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nextPtX = nextPts[ptref+0]*2.f;
|
||||
nextPtY = nextPts[ptref+1]*2.f;
|
||||
}
|
||||
nextPts[ptref+0] = nextPtX;
|
||||
nextPts[ptref+1] = nextPtY;
|
||||
|
||||
s32 iprevPtX, iprevPtY;
|
||||
s32 inextPtX, inextPtY;
|
||||
prevPtX -= halfWinX;
|
||||
prevPtY -= halfWinY;
|
||||
iprevPtX = floor(prevPtX);
|
||||
iprevPtY = floor(prevPtY);
|
||||
|
||||
if( iprevPtX < -(s32)winSize.width || iprevPtX >= (s32)size.width ||
|
||||
iprevPtY < -(s32)winSize.height || iprevPtY >= (s32)size.height )
|
||||
{
|
||||
if( level == 0 )
|
||||
{
|
||||
if( status )
|
||||
status[ptidx] = false;
|
||||
if( err )
|
||||
err[ptidx] = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
f32 a = prevPtX - iprevPtX;
|
||||
f32 b = prevPtY - iprevPtY;
|
||||
const s32 W_BITS = 14, W_BITS1 = 14;
|
||||
const f32 FLT_SCALE = 1.f/(1 << 20);
|
||||
s32 iw00 = round((1.f - a)*(1.f - b)*(1 << W_BITS));
|
||||
s32 iw01 = round(a*(1.f - b)*(1 << W_BITS));
|
||||
s32 iw10 = round((1.f - a)*b*(1 << W_BITS));
|
||||
s32 iw11 = (1 << W_BITS) - iw00 - iw01 - iw10;
|
||||
|
||||
s32 dstep = prevDerivStride/sizeof(s16);
|
||||
f32 A11 = 0, A12 = 0, A22 = 0;
|
||||
|
||||
int16x4_t viw00 = vmov_n_s16((s16)iw00);
|
||||
int16x4_t viw01 = vmov_n_s16((s16)iw01);
|
||||
int16x4_t viw10 = vmov_n_s16((s16)iw10);
|
||||
int16x4_t viw11 = vmov_n_s16((s16)iw11);
|
||||
|
||||
float32x4_t vA11 = vmovq_n_f32(0);
|
||||
float32x4_t vA12 = vmovq_n_f32(0);
|
||||
float32x4_t vA22 = vmovq_n_f32(0);
|
||||
|
||||
s32 wwcn = winSize.width*cn;
|
||||
|
||||
// extract the patch from the first image, compute covariation matrix of derivatives
|
||||
s32 x = 0;
|
||||
for(s32 y = 0; y < (s32)winSize.height; y++ )
|
||||
{
|
||||
const u8* src = prevData + prevStride*(y + iprevPtY) + iprevPtX*cn;
|
||||
const s16* dsrc = prevDerivData + dstep*(y + iprevPtY) + iprevPtX*cn2;
|
||||
|
||||
s16* Iptr = IWinBuf + y*IWinBufStride;
|
||||
s16* dIptr = derivIWinBuf + y*derivIWinBufStride;
|
||||
|
||||
internal::prefetch(src + x + prevStride * 2, 0);
|
||||
for(x = 0; x <= wwcn - 8; x += 8)
|
||||
{
|
||||
uint8x8_t vsrc00 = vld1_u8(src + x);
|
||||
uint8x8_t vsrc10 = vld1_u8(src + x + prevStride);
|
||||
uint8x8_t vsrc01 = vld1_u8(src + x + cn);
|
||||
uint8x8_t vsrc11 = vld1_u8(src + x + prevStride + cn);
|
||||
|
||||
int16x8_t vs00 = vreinterpretq_s16_u16(vmovl_u8(vsrc00));
|
||||
int16x8_t vs10 = vreinterpretq_s16_u16(vmovl_u8(vsrc10));
|
||||
int16x8_t vs01 = vreinterpretq_s16_u16(vmovl_u8(vsrc01));
|
||||
int16x8_t vs11 = vreinterpretq_s16_u16(vmovl_u8(vsrc11));
|
||||
|
||||
int32x4_t vsuml = vmull_s16(vget_low_s16(vs00), viw00);
|
||||
int32x4_t vsumh = vmull_s16(vget_high_s16(vs10), viw10);
|
||||
|
||||
vsuml = vmlal_s16(vsuml, vget_low_s16(vs01), viw01);
|
||||
vsumh = vmlal_s16(vsumh, vget_high_s16(vs11), viw11);
|
||||
|
||||
vsuml = vmlal_s16(vsuml, vget_low_s16(vs10), viw10);
|
||||
vsumh = vmlal_s16(vsumh, vget_high_s16(vs00), viw00);
|
||||
|
||||
vsuml = vmlal_s16(vsuml, vget_low_s16(vs11), viw11);
|
||||
vsumh = vmlal_s16(vsumh, vget_high_s16(vs01), viw01);
|
||||
|
||||
int16x4_t vsumnl = vrshrn_n_s32(vsuml, W_BITS1-5);
|
||||
int16x4_t vsumnh = vrshrn_n_s32(vsumh, W_BITS1-5);
|
||||
|
||||
vst1q_s16(Iptr + x, vcombine_s16(vsumnl, vsumnh));
|
||||
}
|
||||
for(; x <= wwcn - 4; x += 4)
|
||||
{
|
||||
uint8x8_t vsrc00 = vld1_u8(src + x);
|
||||
uint8x8_t vsrc10 = vld1_u8(src + x + prevStride);
|
||||
uint8x8_t vsrc01 = vld1_u8(src + x + cn);
|
||||
uint8x8_t vsrc11 = vld1_u8(src + x + prevStride + cn);
|
||||
|
||||
int16x4_t vs00 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(vsrc00)));
|
||||
int16x4_t vs10 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(vsrc10)));
|
||||
int16x4_t vs01 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(vsrc01)));
|
||||
int16x4_t vs11 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(vsrc11)));
|
||||
|
||||
int32x4_t vsuml1 = vmull_s16(vs00, viw00);
|
||||
int32x4_t vsuml2 = vmull_s16(vs01, viw01);
|
||||
vsuml1 = vmlal_s16(vsuml1, vs10, viw10);
|
||||
vsuml2 = vmlal_s16(vsuml2, vs11, viw11);
|
||||
int32x4_t vsuml = vaddq_s32(vsuml1, vsuml2);
|
||||
|
||||
int16x4_t vsumnl = vrshrn_n_s32(vsuml, W_BITS1-5);
|
||||
|
||||
vst1_s16(Iptr + x, vsumnl);
|
||||
}
|
||||
|
||||
internal::prefetch(dsrc + dstep * 2, 0);
|
||||
for(x = 0; x <= wwcn - 4; x += 4, dsrc += 4*2, dIptr += 4*2 )
|
||||
{
|
||||
#if __GNUC_MINOR__ < 0
|
||||
__asm__ (
|
||||
"vld2.16 {d0-d1}, [%[dsrc00]] \n\t"
|
||||
"vld2.16 {d2-d3}, [%[dsrc10]] \n\t"
|
||||
"vld2.16 {d4-d5}, [%[dsrc01]] \n\t"
|
||||
"vld2.16 {d6-d7}, [%[dsrc11]] \n\t"
|
||||
"vmull.s16 q4, d3, %P[viw10] \n\t"
|
||||
"vmull.s16 q5, d0, %P[viw00] \n\t"
|
||||
"vmlal.s16 q4, d7, %P[viw11] \n\t"
|
||||
"vmlal.s16 q5, d4, %P[viw01] \n\t"
|
||||
"vmlal.s16 q4, d1, %P[viw00] \n\t"
|
||||
"vmlal.s16 q5, d2, %P[viw10] \n\t"
|
||||
"vmlal.s16 q4, d5, %P[viw01] \n\t"
|
||||
"vmlal.s16 q5, d6, %P[viw11] \n\t"
|
||||
"vrshrn.s32 d13, q4, %[W_BITS1] \n\t"
|
||||
"vrshrn.s32 d12, q5, %[W_BITS1] \n\t"
|
||||
"vmull.s16 q3, d13, d13 \n\t"
|
||||
"vmull.s16 q4, d12, d12 \n\t"
|
||||
"vmull.s16 q5, d13, d12 \n\t"
|
||||
"vcvt.f32.s32 q3, q3 \n\t"
|
||||
"vcvt.f32.s32 q4, q4 \n\t"
|
||||
"vcvt.f32.s32 q5, q5 \n\t"
|
||||
"vadd.f32 %q[vA22], q3 \n\t"
|
||||
"vadd.f32 %q[vA11], q4 \n\t"
|
||||
"vadd.f32 %q[vA12], q5 \n\t"
|
||||
"vst2.16 {d12-d13}, [%[out]] \n\t"
|
||||
: [vA22] "=w" (vA22),
|
||||
[vA11] "=w" (vA11),
|
||||
[vA12] "=w" (vA12)
|
||||
: "0" (vA22),
|
||||
"1" (vA11),
|
||||
"2" (vA12),
|
||||
[out] "r" (dIptr),
|
||||
[dsrc00] "r" (dsrc),
|
||||
[dsrc10] "r" (dsrc + dstep),
|
||||
[dsrc01] "r" (dsrc + cn2),
|
||||
[dsrc11] "r" (dsrc + dstep + cn2),
|
||||
[viw00] "w" (viw00),
|
||||
[viw10] "w" (viw10),
|
||||
[viw01] "w" (viw01),
|
||||
[viw11] "w" (viw11),
|
||||
[W_BITS1] "I" (W_BITS1)
|
||||
: "d0","d1","d2","d3","d4","d5","d6","d7","d8","d9","d10","d11","d12","d13"
|
||||
);
|
||||
#else
|
||||
int16x4x2_t vdsrc00 = vld2_s16(dsrc);
|
||||
int16x4x2_t vdsrc10 = vld2_s16(dsrc + dstep);
|
||||
int16x4x2_t vdsrc01 = vld2_s16(dsrc + cn2);
|
||||
int16x4x2_t vdsrc11 = vld2_s16(dsrc + dstep + cn2);
|
||||
|
||||
int32x4_t vsumy = vmull_s16(vdsrc10.val[1], viw10);
|
||||
int32x4_t vsumx = vmull_s16(vdsrc00.val[0], viw00);
|
||||
|
||||
vsumy = vmlal_s16(vsumy, vdsrc11.val[1], viw11);
|
||||
vsumx = vmlal_s16(vsumx, vdsrc01.val[0], viw01);
|
||||
|
||||
vsumy = vmlal_s16(vsumy, vdsrc00.val[1], viw00);
|
||||
vsumx = vmlal_s16(vsumx, vdsrc10.val[0], viw10);
|
||||
|
||||
vsumy = vmlal_s16(vsumy, vdsrc01.val[1], viw01);
|
||||
vsumx = vmlal_s16(vsumx, vdsrc11.val[0], viw11);
|
||||
|
||||
int16x4_t vsumny = vrshrn_n_s32(vsumy, W_BITS1);
|
||||
int16x4_t vsumnx = vrshrn_n_s32(vsumx, W_BITS1);
|
||||
|
||||
int32x4_t va22i = vmull_s16(vsumny, vsumny);
|
||||
int32x4_t va11i = vmull_s16(vsumnx, vsumnx);
|
||||
int32x4_t va12i = vmull_s16(vsumnx, vsumny);
|
||||
|
||||
float32x4_t va22f = vcvtq_f32_s32(va22i);
|
||||
float32x4_t va11f = vcvtq_f32_s32(va11i);
|
||||
float32x4_t va12f = vcvtq_f32_s32(va12i);
|
||||
|
||||
vA22 = vaddq_f32(vA22, va22f);
|
||||
vA11 = vaddq_f32(vA11, va11f);
|
||||
vA12 = vaddq_f32(vA12, va12f);
|
||||
|
||||
int16x4x2_t vsum;
|
||||
vsum.val[0] = vsumnx;
|
||||
vsum.val[1] = vsumny;
|
||||
vst2_s16(dIptr, vsum);
|
||||
#endif
|
||||
}
|
||||
|
||||
for( ; x < wwcn; x++, dsrc += 2, dIptr += 2 )
|
||||
{
|
||||
s32 ival = CV_DESCALE(src[x]*iw00 + src[x+cn]*iw01 +
|
||||
src[x+prevStride]*iw10 + src[x+prevStride+cn]*iw11, W_BITS1-5);
|
||||
s32 ixval = CV_DESCALE(dsrc[0]*iw00 + dsrc[cn2]*iw01 +
|
||||
dsrc[dstep]*iw10 + dsrc[dstep+cn2]*iw11, W_BITS1);
|
||||
s32 iyval = CV_DESCALE(dsrc[1]*iw00 + dsrc[cn2+1]*iw01 + dsrc[dstep+1]*iw10 +
|
||||
dsrc[dstep+cn2+1]*iw11, W_BITS1);
|
||||
Iptr[x] = (s16)ival;
|
||||
dIptr[0] = (s16)ixval;
|
||||
dIptr[1] = (s16)iyval;
|
||||
|
||||
A11 += (f32)(ixval*ixval);
|
||||
A12 += (f32)(ixval*iyval);
|
||||
A22 += (f32)(iyval*iyval);
|
||||
}
|
||||
}
|
||||
|
||||
f32 A11buf[2], A12buf[2], A22buf[2];
|
||||
vst1_f32(A11buf, vadd_f32(vget_low_f32(vA11), vget_high_f32(vA11)));
|
||||
vst1_f32(A12buf, vadd_f32(vget_low_f32(vA12), vget_high_f32(vA12)));
|
||||
vst1_f32(A22buf, vadd_f32(vget_low_f32(vA22), vget_high_f32(vA22)));
|
||||
A11 += A11buf[0] + A11buf[1];
|
||||
A12 += A12buf[0] + A12buf[1];
|
||||
A22 += A22buf[0] + A22buf[1];
|
||||
|
||||
A11 *= FLT_SCALE;
|
||||
A12 *= FLT_SCALE;
|
||||
A22 *= FLT_SCALE;
|
||||
|
||||
f32 D = A11*A22 - A12*A12;
|
||||
f32 minEig = (A22 + A11 - std::sqrt((A11-A22)*(A11-A22) +
|
||||
4.f*A12*A12))/(2*winSize.width*winSize.height);
|
||||
|
||||
if( err && getMinEigenVals )
|
||||
err[ptidx] = (f32)minEig;
|
||||
|
||||
if( minEig < minEigThreshold || D < FLT_EPSILON )
|
||||
{
|
||||
if( level == 0 && status )
|
||||
status[ptidx] = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
D = 1.f/D;
|
||||
|
||||
nextPtX -= halfWinX;
|
||||
nextPtY -= halfWinY;
|
||||
f32 prevDeltaX = 0;
|
||||
f32 prevDeltaY = 0;
|
||||
|
||||
for(u32 j = 0; j < terminationCount; j++ )
|
||||
{
|
||||
inextPtX = floor(nextPtX);
|
||||
inextPtY = floor(nextPtY);
|
||||
|
||||
if( inextPtX < -(s32)winSize.width || inextPtX >= (s32)size.width ||
|
||||
inextPtY < -(s32)winSize.height || inextPtY >= (s32)size.height )
|
||||
{
|
||||
if( level == 0 && status )
|
||||
status[ptidx] = false;
|
||||
break;
|
||||
}
|
||||
|
||||
a = nextPtX - inextPtX;
|
||||
b = nextPtY - inextPtY;
|
||||
iw00 = round((1.f - a)*(1.f - b)*(1 << W_BITS));
|
||||
iw01 = round(a*(1.f - b)*(1 << W_BITS));
|
||||
iw10 = round((1.f - a)*b*(1 << W_BITS));
|
||||
iw11 = (1 << W_BITS) - iw00 - iw01 - iw10;
|
||||
f32 b1 = 0, b2 = 0;
|
||||
|
||||
viw00 = vmov_n_s16((s16)iw00);
|
||||
viw01 = vmov_n_s16((s16)iw01);
|
||||
viw10 = vmov_n_s16((s16)iw10);
|
||||
viw11 = vmov_n_s16((s16)iw11);
|
||||
|
||||
float32x4_t vb1 = vmovq_n_f32(0);
|
||||
float32x4_t vb2 = vmovq_n_f32(0);
|
||||
|
||||
for(s32 y = 0; y < (s32)winSize.height; y++ )
|
||||
{
|
||||
const u8* Jptr = nextData + nextStride*(y + inextPtY) + inextPtX*cn;
|
||||
const s16* Iptr = IWinBuf + y*IWinBufStride;
|
||||
const s16* dIptr = derivIWinBuf + y*derivIWinBufStride;
|
||||
|
||||
x = 0;
|
||||
|
||||
internal::prefetch(Jptr, nextStride * 2);
|
||||
internal::prefetch(Iptr, IWinBufStride/2);
|
||||
internal::prefetch(dIptr, derivIWinBufStride/2);
|
||||
|
||||
for( ; x <= wwcn - 8; x += 8, dIptr += 8*2 )
|
||||
{
|
||||
uint8x8_t vj00 = vld1_u8(Jptr + x);
|
||||
uint8x8_t vj10 = vld1_u8(Jptr + x + nextStride);
|
||||
uint8x8_t vj01 = vld1_u8(Jptr + x + cn);
|
||||
uint8x8_t vj11 = vld1_u8(Jptr + x + nextStride + cn);
|
||||
int16x8_t vI = vld1q_s16(Iptr + x);
|
||||
int16x8x2_t vDerivI = vld2q_s16(dIptr);
|
||||
|
||||
int16x8_t vs00 = vreinterpretq_s16_u16(vmovl_u8(vj00));
|
||||
int16x8_t vs10 = vreinterpretq_s16_u16(vmovl_u8(vj10));
|
||||
int16x8_t vs01 = vreinterpretq_s16_u16(vmovl_u8(vj01));
|
||||
int16x8_t vs11 = vreinterpretq_s16_u16(vmovl_u8(vj11));
|
||||
|
||||
int32x4_t vsuml = vmull_s16(vget_low_s16(vs00), viw00);
|
||||
int32x4_t vsumh = vmull_s16(vget_high_s16(vs10), viw10);
|
||||
|
||||
vsuml = vmlal_s16(vsuml, vget_low_s16(vs01), viw01);
|
||||
vsumh = vmlal_s16(vsumh, vget_high_s16(vs11), viw11);
|
||||
|
||||
vsuml = vmlal_s16(vsuml, vget_low_s16(vs10), viw10);
|
||||
vsumh = vmlal_s16(vsumh, vget_high_s16(vs00), viw00);
|
||||
|
||||
vsuml = vmlal_s16(vsuml, vget_low_s16(vs11), viw11);
|
||||
vsumh = vmlal_s16(vsumh, vget_high_s16(vs01), viw01);
|
||||
|
||||
int16x4_t vsumnl = vrshrn_n_s32(vsuml, W_BITS1-5);
|
||||
int16x4_t vsumnh = vrshrn_n_s32(vsumh, W_BITS1-5);
|
||||
|
||||
int16x8_t diff = vqsubq_s16(vcombine_s16(vsumnl, vsumnh), vI);
|
||||
|
||||
int32x4_t vb1l = vmull_s16(vget_low_s16(diff), vget_low_s16(vDerivI.val[0]));
|
||||
int32x4_t vb2h = vmull_s16(vget_high_s16(diff), vget_high_s16(vDerivI.val[1]));
|
||||
int32x4_t vb1i = vmlal_s16(vb1l, vget_high_s16(diff), vget_high_s16(vDerivI.val[0]));
|
||||
int32x4_t vb2i = vmlal_s16(vb2h, vget_low_s16(diff), vget_low_s16(vDerivI.val[1]));
|
||||
|
||||
float32x4_t vb1f = vcvtq_f32_s32(vb1i);
|
||||
float32x4_t vb2f = vcvtq_f32_s32(vb2i);
|
||||
|
||||
vb1 = vaddq_f32(vb1, vb1f);
|
||||
vb2 = vaddq_f32(vb2, vb2f);
|
||||
}
|
||||
|
||||
for( ; x < wwcn; x++, dIptr += 2 )
|
||||
{
|
||||
s32 diff = CV_DESCALE(Jptr[x]*iw00 + Jptr[x+cn]*iw01 +
|
||||
Jptr[x+nextStride]*iw10 + Jptr[x+nextStride+cn]*iw11,
|
||||
W_BITS1-5) - Iptr[x];
|
||||
b1 += (f32)(diff*dIptr[0]);
|
||||
b2 += (f32)(diff*dIptr[1]);
|
||||
}
|
||||
}
|
||||
|
||||
f32 bbuf[2];
|
||||
float32x2_t vb = vpadd_f32(vadd_f32(vget_low_f32(vb1), vget_high_f32(vb1)), vadd_f32(vget_low_f32(vb2), vget_high_f32(vb2)));
|
||||
vst1_f32(bbuf, vb);
|
||||
b1 += bbuf[0];
|
||||
b2 += bbuf[1];
|
||||
|
||||
b1 *= FLT_SCALE;
|
||||
b2 *= FLT_SCALE;
|
||||
|
||||
f32 deltaX = (f32)((A12*b2 - A22*b1) * D);
|
||||
f32 deltaY = (f32)((A12*b1 - A11*b2) * D);
|
||||
|
||||
nextPtX += deltaX;
|
||||
nextPtY += deltaY;
|
||||
nextPts[ptref+0] = nextPtX + halfWinX;
|
||||
nextPts[ptref+1] = nextPtY + halfWinY;
|
||||
|
||||
if( ((double)deltaX*deltaX + (double)deltaY*deltaY) <= terminationEpsilon )
|
||||
break;
|
||||
|
||||
if( j > 0 && std::abs(deltaX + prevDeltaX) < 0.01 &&
|
||||
std::abs(deltaY + prevDeltaY) < 0.01 )
|
||||
{
|
||||
nextPts[ptref+0] -= deltaX*0.5f;
|
||||
nextPts[ptref+1] -= deltaY*0.5f;
|
||||
break;
|
||||
}
|
||||
prevDeltaX = deltaX;
|
||||
prevDeltaY = deltaY;
|
||||
}
|
||||
|
||||
if( status && status[ptidx] && err && level == 0 && !getMinEigenVals )
|
||||
{
|
||||
f32 nextPointX = nextPts[ptref+0] - halfWinX;
|
||||
f32 nextPointY = nextPts[ptref+1] - halfWinY;
|
||||
|
||||
s32 inextPointX = floor(nextPointX);
|
||||
s32 inextPointY = floor(nextPointY);
|
||||
|
||||
if( inextPointX < -(s32)winSize.width || inextPointX >= (s32)size.width ||
|
||||
inextPointY < -(s32)winSize.height || inextPointY >= (s32)size.height )
|
||||
{
|
||||
if( status )
|
||||
status[ptidx] = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
f32 aa = nextPointX - inextPointX;
|
||||
f32 bb = nextPointY - inextPointY;
|
||||
iw00 = round((1.f - aa)*(1.f - bb)*(1 << W_BITS));
|
||||
iw01 = round(aa*(1.f - bb)*(1 << W_BITS));
|
||||
iw10 = round((1.f - aa)*bb*(1 << W_BITS));
|
||||
iw11 = (1 << W_BITS) - iw00 - iw01 - iw10;
|
||||
f32 errval = 0.f;
|
||||
|
||||
for(s32 y = 0; y < (s32)winSize.height; y++ )
|
||||
{
|
||||
const u8* Jptr = nextData + nextStride*(y + inextPointY) + inextPointX*cn;
|
||||
const s16* Iptr = IWinBuf + y*IWinBufStride;
|
||||
|
||||
for( x = 0; x < wwcn; x++ )
|
||||
{
|
||||
s32 diff = CV_DESCALE(Jptr[x]*iw00 + Jptr[x+cn]*iw01 +
|
||||
Jptr[x+nextStride]*iw10 + Jptr[x+nextStride+cn]*iw11,
|
||||
W_BITS1-5) - Iptr[x];
|
||||
errval += std::abs((f32)diff);
|
||||
}
|
||||
}
|
||||
err[ptidx] = errval / (32*wwcn*winSize.height);
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)cn;
|
||||
(void)prevData;
|
||||
(void)prevStride;
|
||||
(void)prevDerivData;
|
||||
(void)prevDerivStride;
|
||||
(void)nextData;
|
||||
(void)nextStride;
|
||||
(void)prevPts;
|
||||
(void)nextPts;
|
||||
(void)status;
|
||||
(void)err;
|
||||
(void)winSize;
|
||||
(void)terminationCount;
|
||||
(void)terminationEpsilon;
|
||||
(void)level;
|
||||
(void)maxLevel;
|
||||
(void)useInitialFlow;
|
||||
(void)getMinEigenVals;
|
||||
(void)minEigThreshold;
|
||||
(void)ptCount;
|
||||
#endif
|
||||
}
|
||||
|
||||
}//CAROTENE_NS
|
||||
|
||||
Vendored
+274
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2012-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include <cfloat>
|
||||
#include <cmath>
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace {
|
||||
|
||||
#define FASTATAN2CONST(scale) \
|
||||
f32 P1((f32)( 0.9997878412794807 * (180.0 / M_PI) * scale)), \
|
||||
P3((f32)(-0.3258083974640975 * (180.0 / M_PI) * scale)), \
|
||||
P5((f32)( 0.1555786518463281 * (180.0 / M_PI) * scale)), \
|
||||
P7((f32)(-0.04432655554792128 * (180.0 / M_PI) * scale)), \
|
||||
A_90((f32)(90.f * scale)), \
|
||||
A_180((f32)(180.f * scale)), \
|
||||
A_360((f32)(360.f * scale)); \
|
||||
float32x4_t eps(vdupq_n_f32((float)DBL_EPSILON)), \
|
||||
_90(vdupq_n_f32(A_90)), \
|
||||
_180(vdupq_n_f32(A_180)), \
|
||||
_360(vdupq_n_f32(A_360)), \
|
||||
z(vdupq_n_f32(0.0f)), \
|
||||
p1(vdupq_n_f32(P1)), \
|
||||
p3(vdupq_n_f32(P3)), \
|
||||
p5(vdupq_n_f32(P5)), \
|
||||
p7(vdupq_n_f32(P7));
|
||||
|
||||
#define FASTATAN2SCALAR(y, x, a) \
|
||||
{ \
|
||||
f32 ax = std::abs(x), ay = std::abs(y); \
|
||||
f32 c, c2; \
|
||||
if (ax >= ay) \
|
||||
{ \
|
||||
c = ay / (ax + (float)DBL_EPSILON); \
|
||||
c2 = c * c; \
|
||||
a = (((P7 * c2 + P5) * c2 + P3) * c2 + P1) * c; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
c = ax / (ay + (float)DBL_EPSILON); \
|
||||
c2 = c * c; \
|
||||
a = A_90 - (((P7 * c2 + P5) * c2 + P3) * c2 + P1) * c; \
|
||||
} \
|
||||
if (x < 0) \
|
||||
a = A_180 - a; \
|
||||
if (y < 0) \
|
||||
a = A_360 - a; \
|
||||
}
|
||||
|
||||
#define FASTATAN2VECTOR(v_y, v_x, a) \
|
||||
{ \
|
||||
float32x4_t ax = vabsq_f32(v_x), ay = vabsq_f32(v_y); \
|
||||
float32x4_t tmin = vminq_f32(ax, ay), tmax = vmaxq_f32(ax, ay); \
|
||||
float32x4_t c = vmulq_f32(tmin, internal::vrecpq_f32(vaddq_f32(tmax, eps))); \
|
||||
float32x4_t c2 = vmulq_f32(c, c); \
|
||||
a = vmulq_f32(c2, p7); \
|
||||
\
|
||||
a = vmulq_f32(vaddq_f32(a, p5), c2); \
|
||||
a = vmulq_f32(vaddq_f32(a, p3), c2); \
|
||||
a = vmulq_f32(vaddq_f32(a, p1), c); \
|
||||
\
|
||||
a = vbslq_f32(vcgeq_f32(ax, ay), a, vsubq_f32(_90, a)); \
|
||||
a = vbslq_f32(vcltq_f32(v_x, z), vsubq_f32(_180, a), a); \
|
||||
a = vbslq_f32(vcltq_f32(v_y, z), vsubq_f32(_360, a), a); \
|
||||
\
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
void phase(const Size2D &size,
|
||||
const s16 * src0Base, ptrdiff_t src0Stride,
|
||||
const s16 * src1Base, ptrdiff_t src1Stride,
|
||||
u8 * dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
FASTATAN2CONST(256.0f / 360.0f)
|
||||
size_t roiw16 = size.width >= 15 ? size.width - 15 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
float32x4_t v_05 = vdupq_n_f32(0.5f);
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const s16 * src0 = internal::getRowPtr(src0Base, src0Stride, i);
|
||||
const s16 * src1 = internal::getRowPtr(src1Base, src1Stride, i);
|
||||
u8 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for (; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src0 + j);
|
||||
internal::prefetch(src1 + j);
|
||||
|
||||
int16x8_t v_src00 = vld1q_s16(src0 + j), v_src01 = vld1q_s16(src0 + j + 8);
|
||||
int16x8_t v_src10 = vld1q_s16(src1 + j), v_src11 = vld1q_s16(src1 + j + 8);
|
||||
|
||||
// 0
|
||||
float32x4_t v_src0_p = vcvtq_f32_s32(vmovl_s16(vget_low_s16(v_src00)));
|
||||
float32x4_t v_src1_p = vcvtq_f32_s32(vmovl_s16(vget_low_s16(v_src10)));
|
||||
float32x4_t v_dst32f0;
|
||||
FASTATAN2VECTOR(v_src1_p, v_src0_p, v_dst32f0)
|
||||
|
||||
v_src0_p = vcvtq_f32_s32(vmovl_s16(vget_high_s16(v_src00)));
|
||||
v_src1_p = vcvtq_f32_s32(vmovl_s16(vget_high_s16(v_src10)));
|
||||
float32x4_t v_dst32f1;
|
||||
FASTATAN2VECTOR(v_src1_p, v_src0_p, v_dst32f1)
|
||||
|
||||
uint16x8_t v_dst16s0 = vcombine_u16(vmovn_u32(vcvtq_u32_f32(vaddq_f32(v_dst32f0, v_05))),
|
||||
vmovn_u32(vcvtq_u32_f32(vaddq_f32(v_dst32f1, v_05))));
|
||||
|
||||
// 1
|
||||
v_src0_p = vcvtq_f32_s32(vmovl_s16(vget_low_s16(v_src01)));
|
||||
v_src1_p = vcvtq_f32_s32(vmovl_s16(vget_low_s16(v_src11)));
|
||||
FASTATAN2VECTOR(v_src1_p, v_src0_p, v_dst32f0)
|
||||
|
||||
v_src0_p = vcvtq_f32_s32(vmovl_s16(vget_high_s16(v_src01)));
|
||||
v_src1_p = vcvtq_f32_s32(vmovl_s16(vget_high_s16(v_src11)));
|
||||
FASTATAN2VECTOR(v_src1_p, v_src0_p, v_dst32f1)
|
||||
|
||||
uint16x8_t v_dst16s1 = vcombine_u16(vmovn_u32(vcvtq_u32_f32(vaddq_f32(v_dst32f0, v_05))),
|
||||
vmovn_u32(vcvtq_u32_f32(vaddq_f32(v_dst32f1, v_05))));
|
||||
|
||||
vst1q_u8(dst + j, vcombine_u8(vmovn_u16(v_dst16s0),
|
||||
vmovn_u16(v_dst16s1)));
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
int16x8_t v_src0 = vld1q_s16(src0 + j);
|
||||
int16x8_t v_src1 = vld1q_s16(src1 + j);
|
||||
|
||||
float32x4_t v_src0_p = vcvtq_f32_s32(vmovl_s16(vget_low_s16(v_src0)));
|
||||
float32x4_t v_src1_p = vcvtq_f32_s32(vmovl_s16(vget_low_s16(v_src1)));
|
||||
float32x4_t v_dst32f0;
|
||||
FASTATAN2VECTOR(v_src1_p, v_src0_p, v_dst32f0)
|
||||
|
||||
v_src0_p = vcvtq_f32_s32(vmovl_s16(vget_high_s16(v_src0)));
|
||||
v_src1_p = vcvtq_f32_s32(vmovl_s16(vget_high_s16(v_src1)));
|
||||
float32x4_t v_dst32f1;
|
||||
FASTATAN2VECTOR(v_src1_p, v_src0_p, v_dst32f1)
|
||||
|
||||
uint16x8_t v_dst = vcombine_u16(vmovn_u32(vcvtq_u32_f32(vaddq_f32(v_dst32f0, v_05))),
|
||||
vmovn_u32(vcvtq_u32_f32(vaddq_f32(v_dst32f1, v_05))));
|
||||
|
||||
vst1_u8(dst + j, vmovn_u16(v_dst));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
f32 x = src0[j], y = src1[j];
|
||||
f32 a;
|
||||
FASTATAN2SCALAR(y, x, a)
|
||||
dst[j] = (u8)(s32)floor(a + 0.5f);
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
void phase(const Size2D &size,
|
||||
const f32 * src0Base, ptrdiff_t src0Stride,
|
||||
const f32 * src1Base, ptrdiff_t src1Stride,
|
||||
f32 * dstBase, ptrdiff_t dstStride,
|
||||
f32 scale)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
FASTATAN2CONST(scale)
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const f32 * src0 = internal::getRowPtr(src0Base, src0Stride, i);
|
||||
const f32 * src1 = internal::getRowPtr(src1Base, src1Stride, i);
|
||||
f32 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
internal::prefetch(src0 + j);
|
||||
internal::prefetch(src1 + j);
|
||||
|
||||
float32x4_t v_src00 = vld1q_f32(src0 + j), v_src01 = vld1q_f32(src0 + j + 4);
|
||||
float32x4_t v_src10 = vld1q_f32(src1 + j), v_src11 = vld1q_f32(src1 + j + 4);
|
||||
|
||||
float32x4_t v_dst32f;
|
||||
// 0
|
||||
FASTATAN2VECTOR(v_src10, v_src00, v_dst32f)
|
||||
vst1q_f32(dst + j, v_dst32f);
|
||||
// 1
|
||||
FASTATAN2VECTOR(v_src11, v_src01, v_dst32f)
|
||||
vst1q_f32(dst + j + 4, v_dst32f);
|
||||
}
|
||||
if(j + 4 <= size.width)
|
||||
{
|
||||
float32x4_t v_src0 = vld1q_f32(src0 + j);
|
||||
float32x4_t v_src1 = vld1q_f32(src1 + j);
|
||||
|
||||
float32x4_t v_dst32f;
|
||||
FASTATAN2VECTOR(v_src1, v_src0, v_dst32f)
|
||||
vst1q_f32(dst + j, v_dst32f);
|
||||
j += 4;
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
f32 a;
|
||||
FASTATAN2SCALAR(src1[j], src0[j], a)
|
||||
dst[j] = a;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)scale;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+1414
File diff suppressed because it is too large
Load Diff
Vendored
+460
@@ -0,0 +1,460 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2012-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
void reduceColSum(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
s32 * dstBase)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
memset(dstBase, 0, size.width*sizeof(s32));
|
||||
size_t i = 0;
|
||||
for (; i + 16 <= size.width; i += 16)
|
||||
{
|
||||
const u8* src_address = srcBase + i;
|
||||
|
||||
int32x4_t sll = vmovq_n_s32(0);
|
||||
int32x4_t slh = vmovq_n_s32(0);
|
||||
int32x4_t shl = vmovq_n_s32(0);
|
||||
int32x4_t shh = vmovq_n_s32(0);
|
||||
|
||||
for (size_t h = 0; h < size.height; h += 256)
|
||||
{
|
||||
size_t lim = std::min(h + 256, size.height);
|
||||
|
||||
uint16x8_t sl = vmovq_n_u16(0);
|
||||
uint16x8_t sh = vmovq_n_u16(0);
|
||||
|
||||
for (size_t k = h; k < lim; ++k, src_address += srcStride)
|
||||
{
|
||||
internal::prefetch(src_address + srcStride, 0);
|
||||
|
||||
uint8x16_t v = vld1q_u8(src_address);
|
||||
|
||||
sl = vaddw_u8(sl, vget_low_u8(v));
|
||||
sh = vaddw_u8(sh, vget_high_u8(v));
|
||||
}
|
||||
|
||||
int32x4_t vsll = vreinterpretq_s32_u32(vmovl_u16(vget_low_u16(sl)));
|
||||
int32x4_t vslh = vreinterpretq_s32_u32(vmovl_u16(vget_high_u16(sl)));
|
||||
int32x4_t vshl = vreinterpretq_s32_u32(vmovl_u16(vget_low_u16(sh)));
|
||||
int32x4_t vshh = vreinterpretq_s32_u32(vmovl_u16(vget_high_u16(sh)));
|
||||
|
||||
sll = vqaddq_s32(sll, vsll);
|
||||
slh = vqaddq_s32(slh, vslh);
|
||||
shl = vqaddq_s32(shl, vshl);
|
||||
shh = vqaddq_s32(shh, vshh);
|
||||
}
|
||||
|
||||
vst1q_s32(dstBase + i + 0, sll);
|
||||
vst1q_s32(dstBase + i + 4, slh);
|
||||
vst1q_s32(dstBase + i + 8, shl);
|
||||
vst1q_s32(dstBase + i + 12, shh);
|
||||
}
|
||||
|
||||
for(size_t h = 0; h < size.height; ++h)
|
||||
{
|
||||
for(size_t j = i ; j < size.width; j++ )
|
||||
{
|
||||
if (((u32)(dstBase[j] += srcBase[j + srcStride * h])) > 0x7fFFffFFu)
|
||||
dstBase[j] = 0x7fFFffFF;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
#endif
|
||||
}
|
||||
|
||||
void reduceColMax(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
memcpy(dstBase, srcBase, size.width);
|
||||
size_t i = 0;
|
||||
for (; i + 16*4 <= size.width; i += 16*4)
|
||||
{
|
||||
const u8* src_address = srcBase + i;
|
||||
|
||||
uint8x16_t s1 = vld1q_u8(src_address + 0);
|
||||
uint8x16_t s2 = vld1q_u8(src_address + 16);
|
||||
uint8x16_t s3 = vld1q_u8(src_address + 32);
|
||||
uint8x16_t s4 = vld1q_u8(src_address + 48);
|
||||
|
||||
src_address += srcStride;
|
||||
|
||||
for(size_t h = 1; h < size.height; ++h, src_address += srcStride)
|
||||
{
|
||||
internal::prefetch(src_address + srcStride, 0);
|
||||
internal::prefetch(src_address + srcStride, 32);
|
||||
|
||||
uint8x16_t v1 = vld1q_u8(src_address + 0);
|
||||
uint8x16_t v2 = vld1q_u8(src_address + 16);
|
||||
uint8x16_t v3 = vld1q_u8(src_address + 32);
|
||||
uint8x16_t v4 = vld1q_u8(src_address + 48);
|
||||
|
||||
s1 = vmaxq_u8(s1, v1);
|
||||
s2 = vmaxq_u8(s2, v2);
|
||||
s3 = vmaxq_u8(s3, v3);
|
||||
s4 = vmaxq_u8(s4, v4);
|
||||
}
|
||||
|
||||
vst1q_u8(dstBase + i + 0, s1);
|
||||
vst1q_u8(dstBase + i + 16, s2);
|
||||
vst1q_u8(dstBase + i + 32, s3);
|
||||
vst1q_u8(dstBase + i + 48, s4);
|
||||
}
|
||||
|
||||
for (; i + 16 <= size.width; i += 16)
|
||||
{
|
||||
const u8* src_address = srcBase + i;
|
||||
uint8x16_t s1 = vld1q_u8(src_address);
|
||||
src_address += srcStride;
|
||||
for(size_t h = 1; h < size.height; ++h, src_address += srcStride)
|
||||
{
|
||||
internal::prefetch(src_address + srcStride, 0);
|
||||
|
||||
uint8x16_t v1 = vld1q_u8(src_address);
|
||||
s1 = vmaxq_u8(s1, v1);
|
||||
}
|
||||
vst1q_u8(dstBase + i, s1);
|
||||
}
|
||||
|
||||
if (i < size.width)
|
||||
for(size_t h = 1; h < size.height; ++h)
|
||||
for(size_t j = i ; j < size.width; j++ )
|
||||
dstBase[j] = std::max(dstBase[j], srcBase[j + srcStride * h]);
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
#endif
|
||||
}
|
||||
|
||||
void reduceColMin(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u8 * dstBase)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
memcpy(dstBase, srcBase, size.width);
|
||||
size_t i = 0;
|
||||
for (; i + 16*4 <= size.width; i += 16*4)
|
||||
{
|
||||
const u8* src_address = srcBase + i;
|
||||
|
||||
uint8x16_t s1 = vld1q_u8(src_address + 0);
|
||||
uint8x16_t s2 = vld1q_u8(src_address + 16);
|
||||
uint8x16_t s3 = vld1q_u8(src_address + 32);
|
||||
uint8x16_t s4 = vld1q_u8(src_address + 48);
|
||||
|
||||
src_address += srcStride;
|
||||
|
||||
for(size_t h = 1; h < size.height; ++h, src_address += srcStride)
|
||||
{
|
||||
internal::prefetch(src_address + srcStride, 0);
|
||||
internal::prefetch(src_address + srcStride, 32);
|
||||
|
||||
uint8x16_t v1 = vld1q_u8(src_address + 0);
|
||||
uint8x16_t v2 = vld1q_u8(src_address + 16);
|
||||
uint8x16_t v3 = vld1q_u8(src_address + 32);
|
||||
uint8x16_t v4 = vld1q_u8(src_address + 48);
|
||||
|
||||
s1 = vminq_u8(s1, v1);
|
||||
s2 = vminq_u8(s2, v2);
|
||||
s3 = vminq_u8(s3, v3);
|
||||
s4 = vminq_u8(s4, v4);
|
||||
}
|
||||
|
||||
vst1q_u8(dstBase + i + 0, s1);
|
||||
vst1q_u8(dstBase + i + 16, s2);
|
||||
vst1q_u8(dstBase + i + 32, s3);
|
||||
vst1q_u8(dstBase + i + 48, s4);
|
||||
}
|
||||
|
||||
for (; i + 16 <= size.width; i += 16)
|
||||
{
|
||||
const u8* src_address = srcBase + i;
|
||||
uint8x16_t s1 = vld1q_u8(src_address);
|
||||
src_address += srcStride;
|
||||
for(size_t h = 1; h < size.height; ++h, src_address += srcStride)
|
||||
{
|
||||
internal::prefetch(src_address + srcStride, 0);
|
||||
|
||||
uint8x16_t v1 = vld1q_u8(src_address);
|
||||
s1 = vminq_u8(s1, v1);
|
||||
}
|
||||
vst1q_u8(dstBase + i, s1);
|
||||
}
|
||||
|
||||
if (i < size.width)
|
||||
for(size_t h = 1; h < size.height; ++h)
|
||||
for(size_t j = i ; j < size.width; j++ )
|
||||
dstBase[j] = std::min(dstBase[j], srcBase[j + srcStride * h]);
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
#endif
|
||||
}
|
||||
|
||||
void reduceColSum(const Size2D &size,
|
||||
const f32 * srcBase, ptrdiff_t srcStride,
|
||||
f32 * dstBase)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
memcpy(dstBase, srcBase, size.width*sizeof(f32));
|
||||
size_t srcstep = srcStride/sizeof(f32);
|
||||
size_t i = 0;
|
||||
for (; i + 16 <= size.width; i += 16)
|
||||
{
|
||||
const f32* src_address = srcBase + i;
|
||||
|
||||
float32x4_t s1 = vld1q_f32(src_address + 0);
|
||||
float32x4_t s2 = vld1q_f32(src_address + 4);
|
||||
float32x4_t s3 = vld1q_f32(src_address + 8);
|
||||
float32x4_t s4 = vld1q_f32(src_address + 12);
|
||||
|
||||
src_address += srcstep;
|
||||
|
||||
for(size_t h = 1; h < size.height; ++h, src_address += srcstep)
|
||||
{
|
||||
internal::prefetch(src_address + srcstep, 0);
|
||||
internal::prefetch(src_address + srcstep, 32);
|
||||
|
||||
float32x4_t v1 = vld1q_f32(src_address + 0);
|
||||
float32x4_t v2 = vld1q_f32(src_address + 4);
|
||||
float32x4_t v3 = vld1q_f32(src_address + 8);
|
||||
float32x4_t v4 = vld1q_f32(src_address + 12);
|
||||
|
||||
s1 = vaddq_f32(s1, v1);
|
||||
s2 = vaddq_f32(s2, v2);
|
||||
s3 = vaddq_f32(s3, v3);
|
||||
s4 = vaddq_f32(s4, v4);
|
||||
}
|
||||
|
||||
vst1q_f32(dstBase + i + 0, s1);
|
||||
vst1q_f32(dstBase + i + 4, s2);
|
||||
vst1q_f32(dstBase + i + 8, s3);
|
||||
vst1q_f32(dstBase + i + 12, s4);
|
||||
}
|
||||
|
||||
for (; i + 4 <= size.width; i += 4)
|
||||
{
|
||||
const f32* src_address = srcBase + i;
|
||||
float32x4_t s1 = vld1q_f32(src_address);
|
||||
src_address += srcstep;
|
||||
for(size_t h = 1; h < size.height; ++h, src_address += srcstep)
|
||||
{
|
||||
internal::prefetch(src_address + srcstep, 0);
|
||||
|
||||
float32x4_t v1 = vld1q_f32(src_address);
|
||||
s1 = vaddq_f32(s1, v1);
|
||||
}
|
||||
vst1q_f32(dstBase + i, s1);
|
||||
}
|
||||
|
||||
if (i < size.width)
|
||||
for(size_t h = 1; h < size.height; ++h)
|
||||
{
|
||||
for(size_t j = i ; j < size.width; j++ )
|
||||
{
|
||||
dstBase[j] += srcBase[j + srcstep * h];
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
#endif
|
||||
}
|
||||
|
||||
void reduceColMax(const Size2D &size,
|
||||
const f32 * srcBase, ptrdiff_t srcStride,
|
||||
f32 * dstBase)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
memcpy(dstBase, srcBase, size.width*sizeof(f32));
|
||||
size_t srcstep = srcStride/sizeof(f32);
|
||||
size_t i = 0;
|
||||
for (; i + 16 <= size.width; i += 16)
|
||||
{
|
||||
const f32* src_address = srcBase + i;
|
||||
|
||||
float32x4_t s1 = vld1q_f32(src_address + 0);
|
||||
float32x4_t s2 = vld1q_f32(src_address + 4);
|
||||
float32x4_t s3 = vld1q_f32(src_address + 8);
|
||||
float32x4_t s4 = vld1q_f32(src_address + 12);
|
||||
|
||||
src_address += srcstep;
|
||||
|
||||
for(size_t h = 1; h < size.height; ++h, src_address += srcstep)
|
||||
{
|
||||
internal::prefetch(src_address + srcstep, 0);
|
||||
internal::prefetch(src_address + srcstep, 32);
|
||||
|
||||
float32x4_t v1 = vld1q_f32(src_address + 0);
|
||||
float32x4_t v2 = vld1q_f32(src_address + 4);
|
||||
float32x4_t v3 = vld1q_f32(src_address + 8);
|
||||
float32x4_t v4 = vld1q_f32(src_address + 12);
|
||||
|
||||
s1 = vmaxq_f32(s1, v1);
|
||||
s2 = vmaxq_f32(s2, v2);
|
||||
s3 = vmaxq_f32(s3, v3);
|
||||
s4 = vmaxq_f32(s4, v4);
|
||||
}
|
||||
|
||||
vst1q_f32(dstBase + i + 0, s1);
|
||||
vst1q_f32(dstBase + i + 4, s2);
|
||||
vst1q_f32(dstBase + i + 8, s3);
|
||||
vst1q_f32(dstBase + i + 12, s4);
|
||||
}
|
||||
|
||||
for (; i + 4 <= size.width; i += 4)
|
||||
{
|
||||
const f32* src_address = srcBase + i;
|
||||
float32x4_t s1 = vld1q_f32(src_address);
|
||||
src_address += srcstep;
|
||||
for(size_t h = 1; h < size.height; ++h, src_address += srcstep)
|
||||
{
|
||||
internal::prefetch(src_address + srcstep, 0);
|
||||
|
||||
float32x4_t v1 = vld1q_f32(src_address);
|
||||
s1 = vmaxq_f32(s1, v1);
|
||||
}
|
||||
vst1q_f32(dstBase + i, s1);
|
||||
}
|
||||
|
||||
if (i < size.width)
|
||||
for(size_t h = 1; h < size.height; ++h)
|
||||
for(size_t j = i ; j < size.width; j++ )
|
||||
dstBase[j] = std::max(dstBase[j], srcBase[j + srcstep * h]);
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
#endif
|
||||
}
|
||||
|
||||
void reduceColMin(const Size2D &size,
|
||||
const f32 * srcBase, ptrdiff_t srcStride,
|
||||
f32 * dstBase)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
memcpy(dstBase, srcBase, size.width*sizeof(f32));
|
||||
size_t srcstep = srcStride/sizeof(f32);
|
||||
size_t i = 0;
|
||||
for (; i + 16 <= size.width; i += 16)
|
||||
{
|
||||
const f32* src_address = srcBase + i;
|
||||
|
||||
float32x4_t s1 = vld1q_f32(src_address + 0);
|
||||
float32x4_t s2 = vld1q_f32(src_address + 4);
|
||||
float32x4_t s3 = vld1q_f32(src_address + 8);
|
||||
float32x4_t s4 = vld1q_f32(src_address + 12);
|
||||
|
||||
src_address += srcstep;
|
||||
|
||||
for(size_t h = 1; h < size.height; ++h, src_address += srcstep)
|
||||
{
|
||||
internal::prefetch(src_address + srcstep, 0);
|
||||
internal::prefetch(src_address + srcstep, 32);
|
||||
|
||||
float32x4_t v1 = vld1q_f32(src_address + 0);
|
||||
float32x4_t v2 = vld1q_f32(src_address + 4);
|
||||
float32x4_t v3 = vld1q_f32(src_address + 8);
|
||||
float32x4_t v4 = vld1q_f32(src_address + 12);
|
||||
|
||||
s1 = vminq_f32(s1, v1);
|
||||
s2 = vminq_f32(s2, v2);
|
||||
s3 = vminq_f32(s3, v3);
|
||||
s4 = vminq_f32(s4, v4);
|
||||
}
|
||||
|
||||
vst1q_f32(dstBase + i + 0, s1);
|
||||
vst1q_f32(dstBase + i + 4, s2);
|
||||
vst1q_f32(dstBase + i + 8, s3);
|
||||
vst1q_f32(dstBase + i + 12, s4);
|
||||
}
|
||||
|
||||
for (; i + 4 <= size.width; i += 4)
|
||||
{
|
||||
const f32* src_address = srcBase + i;
|
||||
float32x4_t s1 = vld1q_f32(src_address);
|
||||
src_address += srcstep;
|
||||
for(size_t h = 1; h < size.height; ++h, src_address += srcstep)
|
||||
{
|
||||
internal::prefetch(src_address + srcstep, 0);
|
||||
|
||||
float32x4_t v1 = vld1q_f32(src_address);
|
||||
s1 = vminq_f32(s1, v1);
|
||||
}
|
||||
vst1q_f32(dstBase + i, s1);
|
||||
}
|
||||
|
||||
if (i < size.width)
|
||||
for(size_t h = 1; h < size.height; ++h)
|
||||
for(size_t j = i ; j < size.width; j++ )
|
||||
dstBase[j] = std::min(dstBase[j], srcBase[j + srcstep * h]);
|
||||
#else
|
||||
(void)size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+694
@@ -0,0 +1,694 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "remap.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace internal {
|
||||
|
||||
void remapNearestNeighborReplicate(const Size2D size,
|
||||
const u8 * srcBase,
|
||||
const s32 * map,
|
||||
u8 * dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
for (size_t y = 0; y < size.height; ++y)
|
||||
{
|
||||
const s32 * map_row = internal::getRowPtr(map, size.width * sizeof(s32), y);
|
||||
u8 * dst_row = internal::getRowPtr(dstBase, dstStride, y);
|
||||
|
||||
for (size_t x = 0; x < size.width; ++x)
|
||||
{
|
||||
dst_row[x] = srcBase[map_row[x]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void remapNearestNeighborConst(const Size2D size,
|
||||
const u8 * srcBase,
|
||||
const s32 * map,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
u8 borderValue)
|
||||
{
|
||||
for (size_t y = 0; y < size.height; ++y)
|
||||
{
|
||||
const s32 * map_row = internal::getRowPtr(map, size.width * sizeof(s32), y);
|
||||
u8 * dst_row = internal::getRowPtr(dstBase, dstStride, y);
|
||||
|
||||
for (size_t x = 0; x < size.width; ++x)
|
||||
{
|
||||
s32 src_idx = map_row[x];
|
||||
dst_row[x] = src_idx >= 0 ? srcBase[map_row[x]] : borderValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void remapLinearReplicate(const Size2D size,
|
||||
const u8 * srcBase,
|
||||
const s32 * map,
|
||||
const f32 * coeffs,
|
||||
u8 * dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
int16x8_t v_zero16 = vdupq_n_s16(0);
|
||||
|
||||
for (size_t y = 0; y < size.height; ++y)
|
||||
{
|
||||
const s32 * map_row = internal::getRowPtr(map, size.width * sizeof(s32) * 4, y);
|
||||
const f32 * coeff_row = internal::getRowPtr(coeffs, size.width * sizeof(f32) * 2, y);
|
||||
|
||||
u8 * dst_row = internal::getRowPtr(dstBase, dstStride, y);
|
||||
|
||||
size_t x = 0;
|
||||
for ( ; x + 8 < size.width; x += 8)
|
||||
{
|
||||
int16x8_t v_src00 = vsetq_lane_s16(srcBase[map_row[(x << 2)]], v_zero16, 0);
|
||||
v_src00 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 4]], v_src00, 1);
|
||||
v_src00 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 8]], v_src00, 2);
|
||||
v_src00 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 12]], v_src00, 3);
|
||||
v_src00 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 16]], v_src00, 4);
|
||||
v_src00 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 20]], v_src00, 5);
|
||||
v_src00 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 24]], v_src00, 6);
|
||||
v_src00 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 28]], v_src00, 7);
|
||||
|
||||
int16x8_t v_src01 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 1]], v_zero16, 0);
|
||||
v_src01 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 5]], v_src01, 1);
|
||||
v_src01 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 9]], v_src01, 2);
|
||||
v_src01 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 13]], v_src01, 3);
|
||||
v_src01 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 17]], v_src01, 4);
|
||||
v_src01 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 21]], v_src01, 5);
|
||||
v_src01 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 25]], v_src01, 6);
|
||||
v_src01 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 29]], v_src01, 7);
|
||||
|
||||
int16x8_t v_src10 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 2]], v_zero16, 0);
|
||||
v_src10 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 6]], v_src10, 1);
|
||||
v_src10 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 10]], v_src10, 2);
|
||||
v_src10 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 14]], v_src10, 3);
|
||||
v_src10 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 18]], v_src10, 4);
|
||||
v_src10 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 22]], v_src10, 5);
|
||||
v_src10 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 26]], v_src10, 6);
|
||||
v_src10 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 30]], v_src10, 7);
|
||||
|
||||
int16x8_t v_src11 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 3]], v_zero16, 0);
|
||||
v_src11 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 7]], v_src11, 1);
|
||||
v_src11 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 11]], v_src11, 2);
|
||||
v_src11 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 15]], v_src11, 3);
|
||||
v_src11 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 19]], v_src11, 4);
|
||||
v_src11 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 23]], v_src11, 5);
|
||||
v_src11 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 27]], v_src11, 6);
|
||||
v_src11 = vsetq_lane_s16(srcBase[map_row[(x << 2) + 31]], v_src11, 7);
|
||||
|
||||
// first part
|
||||
float32x4_t v_src00_f = vcvtq_f32_s32(vmovl_s16(vget_low_s16(v_src00)));
|
||||
float32x4_t v_src10_f = vcvtq_f32_s32(vmovl_s16(vget_low_s16(v_src10)));
|
||||
|
||||
float32x4x2_t v_coeff = vld2q_f32(coeff_row + (x << 1));
|
||||
float32x4_t v_dst_0 = vmlaq_f32(v_src00_f, vcvtq_f32_s32(vsubl_s16(vget_low_s16(v_src01),
|
||||
vget_low_s16(v_src00))), v_coeff.val[0]);
|
||||
float32x4_t v_dst_1 = vmlaq_f32(v_src10_f, vcvtq_f32_s32(vsubl_s16(vget_low_s16(v_src11),
|
||||
vget_low_s16(v_src10))), v_coeff.val[0]);
|
||||
|
||||
float32x4_t v_dst = vmlaq_f32(v_dst_0, vsubq_f32(v_dst_1, v_dst_0), v_coeff.val[1]);
|
||||
uint16x4_t v_dst0 = vmovn_u32(vcvtq_u32_f32(v_dst));
|
||||
|
||||
// second part
|
||||
v_src00_f = vcvtq_f32_s32(vmovl_s16(vget_high_s16(v_src00)));
|
||||
v_src10_f = vcvtq_f32_s32(vmovl_s16(vget_high_s16(v_src10)));
|
||||
|
||||
v_coeff = vld2q_f32(coeff_row + (x << 1) + 8);
|
||||
v_dst_0 = vmlaq_f32(v_src00_f, vcvtq_f32_s32(vsubl_s16(vget_high_s16(v_src01),
|
||||
vget_high_s16(v_src00))), v_coeff.val[0]);
|
||||
v_dst_1 = vmlaq_f32(v_src10_f, vcvtq_f32_s32(vsubl_s16(vget_high_s16(v_src11),
|
||||
vget_high_s16(v_src10))), v_coeff.val[0]);
|
||||
|
||||
v_dst = vmlaq_f32(v_dst_0, vsubq_f32(v_dst_1, v_dst_0), v_coeff.val[1]);
|
||||
uint16x4_t v_dst1 = vmovn_u32(vcvtq_u32_f32(v_dst));
|
||||
|
||||
// store
|
||||
vst1_u8(dst_row + x, vmovn_u16(vcombine_u16(v_dst0, v_dst1)));
|
||||
}
|
||||
|
||||
for ( ; x < size.width; ++x)
|
||||
{
|
||||
s32 src00_index = map_row[(x << 2)];
|
||||
s32 src10_index = map_row[(x << 2) + 2];
|
||||
f32 dst_val_0 = (srcBase[map_row[(x << 2) + 1]] - srcBase[src00_index]) * coeff_row[x << 1] +
|
||||
srcBase[src00_index];
|
||||
f32 dst_val_1 = (srcBase[map_row[(x << 2) + 3]] - srcBase[src10_index]) * coeff_row[x << 1] +
|
||||
srcBase[src10_index];
|
||||
dst_row[x] = floorf((dst_val_1 - dst_val_0) * coeff_row[(x << 1) + 1] + dst_val_0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void remapLinearConst(const Size2D size,
|
||||
const u8 * srcBase,
|
||||
const s32 * map,
|
||||
const f32 * coeffs,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
u8 borderValue)
|
||||
{
|
||||
int16x8_t v_zero16 = vdupq_n_s16(0);
|
||||
|
||||
for (size_t y = 0; y < size.height; ++y)
|
||||
{
|
||||
const s32 * map_row = internal::getRowPtr(map, size.width * sizeof(s32) * 4, y);
|
||||
const f32 * coeff_row = internal::getRowPtr(coeffs, size.width * sizeof(f32) * 2, y);
|
||||
|
||||
u8 * dst_row = internal::getRowPtr(dstBase, dstStride, y);
|
||||
|
||||
size_t x = 0;
|
||||
for ( ; x + 8 < size.width; x += 8)
|
||||
{
|
||||
int16x8_t v_src00 = vsetq_lane_s16(map_row[(x << 2)] >= 0 ? srcBase[map_row[(x << 2)]] : borderValue, v_zero16, 0);
|
||||
v_src00 = vsetq_lane_s16(map_row[(x << 2) + 4] >= 0 ? srcBase[map_row[(x << 2) + 4]] : borderValue, v_src00, 1);
|
||||
v_src00 = vsetq_lane_s16(map_row[(x << 2) + 8] >= 0 ? srcBase[map_row[(x << 2) + 8]] : borderValue, v_src00, 2);
|
||||
v_src00 = vsetq_lane_s16(map_row[(x << 2) + 12] >= 0 ? srcBase[map_row[(x << 2) + 12]] : borderValue, v_src00, 3);
|
||||
v_src00 = vsetq_lane_s16(map_row[(x << 2) + 16] >= 0 ? srcBase[map_row[(x << 2) + 16]] : borderValue, v_src00, 4);
|
||||
v_src00 = vsetq_lane_s16(map_row[(x << 2) + 20] >= 0 ? srcBase[map_row[(x << 2) + 20]] : borderValue, v_src00, 5);
|
||||
v_src00 = vsetq_lane_s16(map_row[(x << 2) + 24] >= 0 ? srcBase[map_row[(x << 2) + 24]] : borderValue, v_src00, 6);
|
||||
v_src00 = vsetq_lane_s16(map_row[(x << 2) + 28] >= 0 ? srcBase[map_row[(x << 2) + 28]] : borderValue, v_src00, 7);
|
||||
|
||||
int16x8_t v_src01 = vsetq_lane_s16(map_row[(x << 2) + 1] >= 0 ? srcBase[map_row[(x << 2) + 1]] : borderValue, v_zero16, 0);
|
||||
v_src01 = vsetq_lane_s16(map_row[(x << 2) + 5] >= 0 ? srcBase[map_row[(x << 2) + 5]] : borderValue, v_src01, 1);
|
||||
v_src01 = vsetq_lane_s16(map_row[(x << 2) + 9] >= 0 ? srcBase[map_row[(x << 2) + 9]] : borderValue, v_src01, 2);
|
||||
v_src01 = vsetq_lane_s16(map_row[(x << 2) + 13] >= 0 ? srcBase[map_row[(x << 2) + 13]] : borderValue, v_src01, 3);
|
||||
v_src01 = vsetq_lane_s16(map_row[(x << 2) + 17] >= 0 ? srcBase[map_row[(x << 2) + 17]] : borderValue, v_src01, 4);
|
||||
v_src01 = vsetq_lane_s16(map_row[(x << 2) + 21] >= 0 ? srcBase[map_row[(x << 2) + 21]] : borderValue, v_src01, 5);
|
||||
v_src01 = vsetq_lane_s16(map_row[(x << 2) + 25] >= 0 ? srcBase[map_row[(x << 2) + 25]] : borderValue, v_src01, 6);
|
||||
v_src01 = vsetq_lane_s16(map_row[(x << 2) + 29] >= 0 ? srcBase[map_row[(x << 2) + 29]] : borderValue, v_src01, 7);
|
||||
|
||||
int16x8_t v_src10 = vsetq_lane_s16(map_row[(x << 2) + 2] >= 0 ? srcBase[map_row[(x << 2) + 2]] : borderValue, v_zero16, 0);
|
||||
v_src10 = vsetq_lane_s16(map_row[(x << 2) + 6] >= 0 ? srcBase[map_row[(x << 2) + 6]] : borderValue, v_src10, 1);
|
||||
v_src10 = vsetq_lane_s16(map_row[(x << 2) + 10] >= 0 ? srcBase[map_row[(x << 2) + 10]] : borderValue, v_src10, 2);
|
||||
v_src10 = vsetq_lane_s16(map_row[(x << 2) + 14] >= 0 ? srcBase[map_row[(x << 2) + 14]] : borderValue, v_src10, 3);
|
||||
v_src10 = vsetq_lane_s16(map_row[(x << 2) + 18] >= 0 ? srcBase[map_row[(x << 2) + 18]] : borderValue, v_src10, 4);
|
||||
v_src10 = vsetq_lane_s16(map_row[(x << 2) + 22] >= 0 ? srcBase[map_row[(x << 2) + 22]] : borderValue, v_src10, 5);
|
||||
v_src10 = vsetq_lane_s16(map_row[(x << 2) + 26] >= 0 ? srcBase[map_row[(x << 2) + 26]] : borderValue, v_src10, 6);
|
||||
v_src10 = vsetq_lane_s16(map_row[(x << 2) + 30] >= 0 ? srcBase[map_row[(x << 2) + 30]] : borderValue, v_src10, 7);
|
||||
|
||||
int16x8_t v_src11 = vsetq_lane_s16(map_row[(x << 2) + 3] >= 0 ? srcBase[map_row[(x << 2) + 3]] : borderValue, v_zero16, 0);
|
||||
v_src11 = vsetq_lane_s16(map_row[(x << 2) + 7] >= 0 ? srcBase[map_row[(x << 2) + 7]] : borderValue, v_src11, 1);
|
||||
v_src11 = vsetq_lane_s16(map_row[(x << 2) + 11] >= 0 ? srcBase[map_row[(x << 2) + 11]] : borderValue, v_src11, 2);
|
||||
v_src11 = vsetq_lane_s16(map_row[(x << 2) + 15] >= 0 ? srcBase[map_row[(x << 2) + 15]] : borderValue, v_src11, 3);
|
||||
v_src11 = vsetq_lane_s16(map_row[(x << 2) + 19] >= 0 ? srcBase[map_row[(x << 2) + 19]] : borderValue, v_src11, 4);
|
||||
v_src11 = vsetq_lane_s16(map_row[(x << 2) + 23] >= 0 ? srcBase[map_row[(x << 2) + 23]] : borderValue, v_src11, 5);
|
||||
v_src11 = vsetq_lane_s16(map_row[(x << 2) + 27] >= 0 ? srcBase[map_row[(x << 2) + 27]] : borderValue, v_src11, 6);
|
||||
v_src11 = vsetq_lane_s16(map_row[(x << 2) + 31] >= 0 ? srcBase[map_row[(x << 2) + 31]] : borderValue, v_src11, 7);
|
||||
|
||||
// first part
|
||||
float32x4_t v_src00_f = vcvtq_f32_s32(vmovl_s16(vget_low_s16(v_src00)));
|
||||
float32x4_t v_src10_f = vcvtq_f32_s32(vmovl_s16(vget_low_s16(v_src10)));
|
||||
|
||||
float32x4x2_t v_coeff = vld2q_f32(coeff_row + (x << 1));
|
||||
float32x4_t v_dst_0 = vmlaq_f32(v_src00_f, vcvtq_f32_s32(vsubl_s16(vget_low_s16(v_src01),
|
||||
vget_low_s16(v_src00))), v_coeff.val[0]);
|
||||
float32x4_t v_dst_1 = vmlaq_f32(v_src10_f, vcvtq_f32_s32(vsubl_s16(vget_low_s16(v_src11),
|
||||
vget_low_s16(v_src10))), v_coeff.val[0]);
|
||||
|
||||
float32x4_t v_dst = vmlaq_f32(v_dst_0, vsubq_f32(v_dst_1, v_dst_0), v_coeff.val[1]);
|
||||
uint16x4_t v_dst0 = vmovn_u32(vcvtq_u32_f32(v_dst));
|
||||
|
||||
// second part
|
||||
v_src00_f = vcvtq_f32_s32(vmovl_s16(vget_high_s16(v_src00)));
|
||||
v_src10_f = vcvtq_f32_s32(vmovl_s16(vget_high_s16(v_src10)));
|
||||
|
||||
v_coeff = vld2q_f32(coeff_row + (x << 1) + 8);
|
||||
v_dst_0 = vmlaq_f32(v_src00_f, vcvtq_f32_s32(vsubl_s16(vget_high_s16(v_src01),
|
||||
vget_high_s16(v_src00))), v_coeff.val[0]);
|
||||
v_dst_1 = vmlaq_f32(v_src10_f, vcvtq_f32_s32(vsubl_s16(vget_high_s16(v_src11),
|
||||
vget_high_s16(v_src10))), v_coeff.val[0]);
|
||||
|
||||
v_dst = vmlaq_f32(v_dst_0, vsubq_f32(v_dst_1, v_dst_0), v_coeff.val[1]);
|
||||
uint16x4_t v_dst1 = vmovn_u32(vcvtq_u32_f32(v_dst));
|
||||
|
||||
// store
|
||||
vst1_u8(dst_row + x, vmovn_u16(vcombine_u16(v_dst0, v_dst1)));
|
||||
}
|
||||
|
||||
for ( ; x < size.width; ++x)
|
||||
{
|
||||
s16 src00 = map_row[(x << 2) + 0] >= 0 ? srcBase[map_row[(x << 2) + 0]] : borderValue;
|
||||
s16 src01 = map_row[(x << 2) + 1] >= 0 ? srcBase[map_row[(x << 2) + 1]] : borderValue;
|
||||
s16 src10 = map_row[(x << 2) + 2] >= 0 ? srcBase[map_row[(x << 2) + 2]] : borderValue;
|
||||
s16 src11 = map_row[(x << 2) + 3] >= 0 ? srcBase[map_row[(x << 2) + 3]] : borderValue;
|
||||
|
||||
f32 dst_val_0 = (src01 - src00) * coeff_row[(x << 1)] + src00;
|
||||
f32 dst_val_1 = (src11 - src10) * coeff_row[(x << 1)] + src10;
|
||||
dst_row[x] = floorf((dst_val_1 - dst_val_0) * coeff_row[(x << 1) + 1] + dst_val_0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
#endif // CAROTENE_NEON
|
||||
|
||||
bool isRemapNearestNeighborSupported(const Size2D &ssize)
|
||||
{
|
||||
#if SIZE_MAX > UINT32_MAX
|
||||
return !(ssize.width > 0xffffFFFF || ssize.height > 0xffffFFFF) && // Restrict image size since internal index evaluation
|
||||
// is performed with u32
|
||||
isSupportedConfiguration();
|
||||
#else
|
||||
(void)ssize;
|
||||
return isSupportedConfiguration();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isRemapLinearSupported(const Size2D &ssize)
|
||||
{
|
||||
#if SIZE_MAX > UINT32_MAX
|
||||
return !(ssize.width > 0xffffFFFF || ssize.height > 0xffffFFFF) && // Restrict image size since internal index evaluation
|
||||
// is performed with u32
|
||||
isSupportedConfiguration();
|
||||
#else
|
||||
(void)ssize;
|
||||
return isSupportedConfiguration();
|
||||
#endif
|
||||
}
|
||||
|
||||
void remapNearestNeighbor(const Size2D &ssize, const Size2D &dsize,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
const f32 * tableBase, ptrdiff_t tableStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
BORDER_MODE borderMode, u8 borderValue)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isRemapNearestNeighborSupported(ssize));
|
||||
#ifdef CAROTENE_NEON
|
||||
using namespace internal;
|
||||
|
||||
s32 _map[BLOCK_SIZE * BLOCK_SIZE + 16];
|
||||
s32 * map = alignPtr(_map, 16);
|
||||
|
||||
int32x4_t v_width4 = vdupq_n_s32(ssize.width - 1), v_height4 = vdupq_n_s32(ssize.height - 1);
|
||||
int32x2_t v_width2 = vdup_n_s32(ssize.width - 1), v_height2 = vdup_n_s32(ssize.height - 1);
|
||||
int32x4_t v_step4 = vdupq_n_s32(srcStride);
|
||||
int32x2_t v_step2 = vdup_n_s32(srcStride);
|
||||
|
||||
if (borderMode == BORDER_MODE_REPLICATE)
|
||||
{
|
||||
int32x4_t v_zero4 = vdupq_n_s32(0);
|
||||
int32x2_t v_zero2 = vdup_n_s32(0);
|
||||
|
||||
for (size_t i = 0; i < dsize.height; i += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockHeight = std::min<size_t>(BLOCK_SIZE, dsize.height - i);
|
||||
for (size_t j = 0; j < dsize.width; j += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockWidth = std::min<size_t>(BLOCK_SIZE, dsize.width - j);
|
||||
|
||||
// compute table
|
||||
for (size_t y = 0; y < blockHeight; ++y)
|
||||
{
|
||||
const f32 * table_row = getRowPtr(tableBase, tableStride, i + y) + (j << 1);
|
||||
s32 * map_row = getRowPtr(&map[0], blockWidth * sizeof(s32), y);
|
||||
|
||||
size_t x = 0;
|
||||
for ( ; x + 8 <= blockWidth; x += 8)
|
||||
{
|
||||
float32x4x2_t v_table0 = vld2q_f32(table_row + (x << 1)),
|
||||
v_table1 = vld2q_f32(table_row + (x << 1) + 8);
|
||||
|
||||
int32x4_t v_dst_x = vmaxq_s32(v_zero4, vminq_s32(v_width4, vcvtq_s32_f32(v_table0.val[0])));
|
||||
int32x4_t v_dst_y = vmaxq_s32(v_zero4, vminq_s32(v_height4, vcvtq_s32_f32(v_table0.val[1])));
|
||||
int32x4_t v_dst_index = vmlaq_s32(v_dst_x, v_dst_y, v_step4);
|
||||
vst1q_s32(map_row + x, v_dst_index);
|
||||
|
||||
v_dst_x = vmaxq_s32(v_zero4, vminq_s32(v_width4, vcvtq_s32_f32(v_table1.val[0])));
|
||||
v_dst_y = vmaxq_s32(v_zero4, vminq_s32(v_height4, vcvtq_s32_f32(v_table1.val[1])));
|
||||
v_dst_index = vmlaq_s32(v_dst_x, v_dst_y, v_step4);
|
||||
vst1q_s32(map_row + x + 4, v_dst_index);
|
||||
}
|
||||
|
||||
for ( ; x + 4 <= blockWidth; x += 4)
|
||||
{
|
||||
float32x4x2_t v_table0 = vld2q_f32(table_row + (x << 1));
|
||||
|
||||
int32x4_t v_dst_x = vmaxq_s32(v_zero4, vminq_s32(v_width4, vcvtq_s32_f32(v_table0.val[0])));
|
||||
int32x4_t v_dst_y = vmaxq_s32(v_zero4, vminq_s32(v_height4, vcvtq_s32_f32(v_table0.val[1])));
|
||||
int32x4_t v_dst_index = vmlaq_s32(v_dst_x, v_dst_y, v_step4);
|
||||
vst1q_s32(map_row + x, v_dst_index);
|
||||
}
|
||||
|
||||
for ( ; x + 2 <= blockWidth; x += 2)
|
||||
{
|
||||
float32x2x2_t v_table0 = vld2_f32(table_row + (x << 1));
|
||||
|
||||
int32x2_t v_dst_x = vmax_s32(v_zero2, vmin_s32(v_width2, vcvt_s32_f32(v_table0.val[0])));
|
||||
int32x2_t v_dst_y = vmax_s32(v_zero2, vmin_s32(v_height2, vcvt_s32_f32(v_table0.val[1])));
|
||||
int32x2_t v_dst_index = vmla_s32(v_dst_x, v_dst_y, v_step2);
|
||||
vst1_s32(map_row + x, v_dst_index);
|
||||
}
|
||||
|
||||
for ( ; x < blockWidth; ++x)
|
||||
{
|
||||
s32 src_x = std::max(0, std::min<s32>(ssize.width - 1, (s32)floorf(table_row[(x << 1) + 0])));
|
||||
s32 src_y = std::max(0, std::min<s32>(ssize.height - 1, (s32)floorf(table_row[(x << 1) + 1])));
|
||||
map_row[x] = src_y * srcStride + src_x;
|
||||
}
|
||||
}
|
||||
|
||||
// make remap
|
||||
remapNearestNeighborReplicate(Size2D(blockWidth, blockHeight), srcBase, &map[0],
|
||||
getRowPtr(dstBase, dstStride, i) + j, dstStride);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (borderMode == BORDER_MODE_CONSTANT)
|
||||
{
|
||||
int32x4_t v_m1_4 = vdupq_n_s32(-1);
|
||||
int32x2_t v_m1_2 = vdup_n_s32(-1);
|
||||
float32x4_t v_zero4 = vdupq_n_f32(0.0f);
|
||||
float32x2_t v_zero2 = vdup_n_f32(0.0f);
|
||||
|
||||
for (size_t i = 0; i < dsize.height; i += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockHeight = std::min<size_t>(BLOCK_SIZE, dsize.height - i);
|
||||
for (size_t j = 0; j < dsize.width; j += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockWidth = std::min<size_t>(BLOCK_SIZE, dsize.width - j);
|
||||
|
||||
// compute table
|
||||
for (size_t y = 0; y < blockHeight; ++y)
|
||||
{
|
||||
const f32 * table_row = getRowPtr(tableBase, tableStride, i + y) + (j << 1);
|
||||
s32 * map_row = getRowPtr(&map[0], blockWidth * sizeof(s32), y);
|
||||
|
||||
size_t x = 0;
|
||||
for ( ; x + 8 <= blockWidth; x += 8)
|
||||
{
|
||||
float32x4x2_t v_table0 = vld2q_f32(table_row + (x << 1)),
|
||||
v_table1 = vld2q_f32(table_row + (x << 1) + 8);
|
||||
|
||||
int32x4_t v_dst_x = vcvtq_s32_f32(v_table0.val[0]);
|
||||
int32x4_t v_dst_y = vcvtq_s32_f32(v_table0.val[1]);
|
||||
uint32x4_t v_mask = vandq_u32(vandq_u32(vcgeq_f32(v_table0.val[0], v_zero4), vcleq_s32(v_dst_x, v_width4)),
|
||||
vandq_u32(vcgeq_f32(v_table0.val[1], v_zero4), vcleq_s32(v_dst_y, v_height4)));
|
||||
int32x4_t v_dst_index = vbslq_s32(v_mask, vmlaq_s32(v_dst_x, v_dst_y, v_step4), v_m1_4);
|
||||
vst1q_s32(map_row + x, v_dst_index);
|
||||
|
||||
v_dst_x = vcvtq_s32_f32(v_table1.val[0]);
|
||||
v_dst_y = vcvtq_s32_f32(v_table1.val[1]);
|
||||
v_mask = vandq_u32(vandq_u32(vcgeq_f32(v_table1.val[0], v_zero4), vcleq_s32(v_dst_x, v_width4)),
|
||||
vandq_u32(vcgeq_f32(v_table1.val[1], v_zero4), vcleq_s32(v_dst_y, v_height4)));
|
||||
v_dst_index = vbslq_s32(v_mask, vmlaq_s32(v_dst_x, v_dst_y, v_step4), v_m1_4);
|
||||
vst1q_s32(map_row + x + 4, v_dst_index);
|
||||
}
|
||||
|
||||
for ( ; x + 4 <= blockWidth; x += 4)
|
||||
{
|
||||
float32x4x2_t v_table0 = vld2q_f32(table_row + (x << 1));
|
||||
|
||||
int32x4_t v_dst_x = vcvtq_s32_f32(v_table0.val[0]);
|
||||
int32x4_t v_dst_y = vcvtq_s32_f32(v_table0.val[1]);
|
||||
uint32x4_t v_mask = vandq_u32(vandq_u32(vcgeq_f32(v_table0.val[0], v_zero4), vcleq_s32(v_dst_x, v_width4)),
|
||||
vandq_u32(vcgeq_f32(v_table0.val[1], v_zero4), vcleq_s32(v_dst_y, v_height4)));
|
||||
int32x4_t v_dst_index = vbslq_s32(v_mask, vmlaq_s32(v_dst_x, v_dst_y, v_step4), v_m1_4);
|
||||
vst1q_s32(map_row + x, v_dst_index);
|
||||
}
|
||||
|
||||
for ( ; x + 2 <= blockWidth; x += 2)
|
||||
{
|
||||
float32x2x2_t v_table0 = vld2_f32(table_row + (x << 1));
|
||||
|
||||
int32x2_t v_dst_x = vcvt_s32_f32(v_table0.val[0]);
|
||||
int32x2_t v_dst_y = vcvt_s32_f32(v_table0.val[1]);
|
||||
uint32x2_t v_mask = vand_u32(vand_u32(vcge_f32(v_table0.val[0], v_zero2), vcle_s32(v_dst_x, v_width2)),
|
||||
vand_u32(vcge_f32(v_table0.val[1], v_zero2), vcle_s32(v_dst_y, v_height2)));
|
||||
int32x2_t v_dst_index = vbsl_s32(v_mask, vmla_s32(v_dst_x, v_dst_y, v_step2), v_m1_2);
|
||||
vst1_s32(map_row + x, v_dst_index);
|
||||
}
|
||||
|
||||
for ( ; x < blockWidth; ++x)
|
||||
{
|
||||
s32 src_x = (s32)floorf(table_row[(x << 1) + 0]);
|
||||
s32 src_y = (s32)floorf(table_row[(x << 1) + 1]);
|
||||
map_row[x] = (src_x >= 0) && (src_x < (s32)ssize.width) &&
|
||||
(src_y >= 0) && (src_y < (s32)ssize.height) ? src_y * srcStride + src_x : -1;
|
||||
}
|
||||
}
|
||||
|
||||
// make remap
|
||||
remapNearestNeighborConst(Size2D(blockWidth, blockHeight), srcBase, &map[0],
|
||||
getRowPtr(dstBase, dstStride, i) + j, dstStride, borderValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
(void)ssize;
|
||||
(void)dsize;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)tableBase;
|
||||
(void)tableStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)borderMode;
|
||||
(void)borderValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
void remapLinear(const Size2D &ssize, const Size2D &dsize,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
const f32 * tableBase, ptrdiff_t tableStride,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
BORDER_MODE borderMode, u8 borderValue)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isRemapLinearSupported(ssize));
|
||||
#ifdef CAROTENE_NEON
|
||||
using namespace internal;
|
||||
|
||||
s32 _map[((BLOCK_SIZE * BLOCK_SIZE) << 2) + 16];
|
||||
f32 _coeffs[((BLOCK_SIZE * BLOCK_SIZE) << 1) + 16];
|
||||
|
||||
s32 * map = alignPtr(_map, 16);
|
||||
f32 * coeffs = alignPtr(_coeffs, 16);
|
||||
|
||||
int32x4_t v_width4 = vdupq_n_s32(ssize.width - 1), v_height4 = vdupq_n_s32(ssize.height - 1);
|
||||
int32x4_t v_step4 = vdupq_n_s32(srcStride), v_1 = vdupq_n_s32(1);
|
||||
float32x4_t v_zero4f = vdupq_n_f32(0.0f), v_one4f = vdupq_n_f32(1.0f);
|
||||
|
||||
if (borderMode == BORDER_MODE_REPLICATE)
|
||||
{
|
||||
int32x4_t v_zero4 = vdupq_n_s32(0);
|
||||
|
||||
for (size_t i = 0; i < dsize.height; i += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockHeight = std::min<size_t>(BLOCK_SIZE, dsize.height - i);
|
||||
for (size_t j = 0; j < dsize.width; j += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockWidth = std::min<size_t>(BLOCK_SIZE, dsize.width - j);
|
||||
|
||||
// compute table
|
||||
for (size_t y = 0; y < blockHeight; ++y)
|
||||
{
|
||||
const f32 * table_row = getRowPtr(tableBase, tableStride, i + y) + (j << 1);
|
||||
|
||||
s32 * map_row = getRowPtr(map, blockWidth * sizeof(s32) * 4, y);
|
||||
f32 * coeff_row = getRowPtr(coeffs, blockWidth * sizeof(f32) * 2, y);
|
||||
|
||||
size_t x = 0;
|
||||
for ( ; x + 4 <= blockWidth; x += 4)
|
||||
{
|
||||
float32x4x2_t v_table = vld2q_f32(table_row + (x << 1));
|
||||
|
||||
int32x4_t v_src_x = vcvtq_s32_f32(v_table.val[0]);
|
||||
int32x4_t v_src_y = vcvtq_s32_f32(v_table.val[1]);
|
||||
|
||||
float32x4x2_t v_coeff;
|
||||
v_coeff.val[0] = vsubq_f32(v_table.val[0], vcvtq_f32_s32(v_src_x));
|
||||
v_coeff.val[1] = vsubq_f32(v_table.val[1], vcvtq_f32_s32(v_src_y));
|
||||
uint32x4_t v_maskx = vcltq_f32(v_coeff.val[0], v_zero4f);
|
||||
uint32x4_t v_masky = vcltq_f32(v_coeff.val[1], v_zero4f);
|
||||
v_coeff.val[0] = vbslq_f32(v_maskx, vaddq_f32(v_one4f, v_coeff.val[0]), v_coeff.val[0]);
|
||||
v_coeff.val[1] = vbslq_f32(v_masky, vaddq_f32(v_one4f, v_coeff.val[1]), v_coeff.val[1]);
|
||||
v_src_x = vbslq_s32(v_maskx, vsubq_s32(v_src_x, v_1), v_src_x);
|
||||
v_src_y = vbslq_s32(v_masky, vsubq_s32(v_src_y, v_1), v_src_y);
|
||||
|
||||
int32x4_t v_dst0_x = vmaxq_s32(v_zero4, vminq_s32(v_width4, v_src_x));
|
||||
int32x4_t v_dst0_y = vmaxq_s32(v_zero4, vminq_s32(v_height4, v_src_y));
|
||||
int32x4_t v_dst1_x = vmaxq_s32(v_zero4, vminq_s32(v_width4, vaddq_s32(v_1, v_src_x)));
|
||||
int32x4_t v_dst1_y = vmaxq_s32(v_zero4, vminq_s32(v_height4, vaddq_s32(v_1, v_src_y)));
|
||||
|
||||
int32x4x4_t v_dst_index;
|
||||
v_dst_index.val[0] = vmlaq_s32(v_dst0_x, v_dst0_y, v_step4);
|
||||
v_dst_index.val[1] = vmlaq_s32(v_dst1_x, v_dst0_y, v_step4);
|
||||
v_dst_index.val[2] = vmlaq_s32(v_dst0_x, v_dst1_y, v_step4);
|
||||
v_dst_index.val[3] = vmlaq_s32(v_dst1_x, v_dst1_y, v_step4);
|
||||
|
||||
vst2q_f32(coeff_row + (x << 1), v_coeff);
|
||||
vst4q_s32(map_row + (x << 2), v_dst_index);
|
||||
}
|
||||
|
||||
for ( ; x < blockWidth; ++x)
|
||||
{
|
||||
f32 src_x_f = table_row[(x << 1) + 0];
|
||||
f32 src_y_f = table_row[(x << 1) + 1];
|
||||
|
||||
s32 src0_x = (s32)floorf(src_x_f);
|
||||
s32 src0_y = (s32)floorf(src_y_f);
|
||||
|
||||
coeff_row[x << 1] = src_x_f - src0_x;
|
||||
coeff_row[(x << 1) + 1] = src_y_f - src0_y;
|
||||
|
||||
s32 src1_y = std::max(0, std::min<s32>(ssize.height - 1, src0_y + 1));
|
||||
src0_y = std::max(0, std::min<s32>(ssize.height - 1, src0_y));
|
||||
s32 src1_x = std::max(0, std::min<s32>(ssize.width - 1, src0_x + 1));
|
||||
src0_x = std::max(0, std::min<s32>(ssize.width - 1, src0_x));
|
||||
|
||||
map_row[(x << 2) + 0] = src0_y * srcStride + src0_x;
|
||||
map_row[(x << 2) + 1] = src0_y * srcStride + src1_x;
|
||||
map_row[(x << 2) + 2] = src1_y * srcStride + src0_x;
|
||||
map_row[(x << 2) + 3] = src1_y * srcStride + src1_x;
|
||||
}
|
||||
}
|
||||
|
||||
remapLinearReplicate(Size2D(blockWidth, blockHeight),
|
||||
srcBase, &map[0], &coeffs[0],
|
||||
getRowPtr(dstBase, dstStride, i) + j, dstStride);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (borderMode == BORDER_MODE_CONSTANT)
|
||||
{
|
||||
float32x4_t v_zero4 = vdupq_n_f32(0.0f);
|
||||
int32x4_t v_m1_4 = vdupq_n_s32(-1);
|
||||
|
||||
for (size_t i = 0; i < dsize.height; i += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockHeight = std::min<size_t>(BLOCK_SIZE, dsize.height - i);
|
||||
for (size_t j = 0; j < dsize.width; j += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockWidth = std::min<size_t>(BLOCK_SIZE, dsize.width - j);
|
||||
|
||||
// compute table
|
||||
for (size_t y = 0; y < blockHeight; ++y)
|
||||
{
|
||||
const f32 * table_row = getRowPtr(tableBase, tableStride, i + y) + (j << 1);
|
||||
|
||||
s32 * map_row = getRowPtr(map, blockWidth * sizeof(s32) * 4, y);
|
||||
f32 * coeff_row = getRowPtr(coeffs, blockWidth * sizeof(f32) * 2, y);
|
||||
|
||||
size_t x = 0;
|
||||
for ( ; x + 4 <= blockWidth; x += 4)
|
||||
{
|
||||
float32x4x2_t v_table = vld2q_f32(table_row + (x << 1));
|
||||
|
||||
int32x4_t v_src_x0 = vcvtq_s32_f32(v_table.val[0]);
|
||||
int32x4_t v_src_y0 = vcvtq_s32_f32(v_table.val[1]);
|
||||
|
||||
float32x4x2_t v_coeff;
|
||||
v_coeff.val[0] = vsubq_f32(v_table.val[0], vcvtq_f32_s32(v_src_x0));
|
||||
v_coeff.val[1] = vsubq_f32(v_table.val[1], vcvtq_f32_s32(v_src_y0));
|
||||
uint32x4_t v_maskx = vcltq_f32(v_coeff.val[0], v_zero4f);
|
||||
uint32x4_t v_masky = vcltq_f32(v_coeff.val[1], v_zero4f);
|
||||
v_coeff.val[0] = vbslq_f32(v_maskx, vaddq_f32(v_one4f, v_coeff.val[0]), v_coeff.val[0]);
|
||||
v_coeff.val[1] = vbslq_f32(v_masky, vaddq_f32(v_one4f, v_coeff.val[1]), v_coeff.val[1]);
|
||||
v_src_x0 = vbslq_s32(v_maskx, vsubq_s32(v_src_x0, v_1), v_src_x0);
|
||||
v_src_y0 = vbslq_s32(v_masky, vsubq_s32(v_src_y0, v_1), v_src_y0);
|
||||
|
||||
int32x4_t v_src_x1 = vaddq_s32(v_src_x0, v_1);
|
||||
int32x4_t v_src_y1 = vaddq_s32(v_src_y0, v_1);
|
||||
|
||||
int32x4x4_t v_dst_index;
|
||||
v_dst_index.val[0] = vmlaq_s32(v_src_x0, v_src_y0, v_step4);
|
||||
v_dst_index.val[1] = vmlaq_s32(v_src_x1, v_src_y0, v_step4);
|
||||
v_dst_index.val[2] = vmlaq_s32(v_src_x0, v_src_y1, v_step4);
|
||||
v_dst_index.val[3] = vmlaq_s32(v_src_x1, v_src_y1, v_step4);
|
||||
|
||||
uint32x4_t v_mask_x0 = vandq_u32(vcgeq_f32(v_table.val[0], v_zero4), vcleq_s32(v_src_x0, v_width4));
|
||||
uint32x4_t v_mask_x1 = vandq_u32(vcgeq_f32(vaddq_f32(v_table.val[0], v_one4f), v_zero4), vcleq_s32(v_src_x1, v_width4));
|
||||
uint32x4_t v_mask_y0 = vandq_u32(vcgeq_f32(v_table.val[1], v_zero4), vcleq_s32(v_src_y0, v_height4));
|
||||
uint32x4_t v_mask_y1 = vandq_u32(vcgeq_f32(vaddq_f32(v_table.val[1], v_one4f), v_zero4), vcleq_s32(v_src_y1, v_height4));
|
||||
|
||||
v_dst_index.val[0] = vbslq_s32(vandq_u32(v_mask_x0, v_mask_y0), v_dst_index.val[0], v_m1_4);
|
||||
v_dst_index.val[1] = vbslq_s32(vandq_u32(v_mask_x1, v_mask_y0), v_dst_index.val[1], v_m1_4);
|
||||
v_dst_index.val[2] = vbslq_s32(vandq_u32(v_mask_x0, v_mask_y1), v_dst_index.val[2], v_m1_4);
|
||||
v_dst_index.val[3] = vbslq_s32(vandq_u32(v_mask_x1, v_mask_y1), v_dst_index.val[3], v_m1_4);
|
||||
|
||||
vst2q_f32(coeff_row + (x << 1), v_coeff);
|
||||
vst4q_s32(map_row + (x << 2), v_dst_index);
|
||||
}
|
||||
|
||||
for ( ; x < blockWidth; ++x)
|
||||
{
|
||||
f32 src_x_f = table_row[(x << 1) + 0];
|
||||
f32 src_y_f = table_row[(x << 1) + 1];
|
||||
|
||||
s32 src0_x = (s32)floorf(src_x_f), src1_x = src0_x + 1;
|
||||
s32 src0_y = (s32)floorf(src_y_f), src1_y = src0_y + 1;
|
||||
|
||||
coeff_row[(x << 1)] = src_x_f - src0_x;
|
||||
coeff_row[(x << 1) + 1] = src_y_f - src0_y;
|
||||
|
||||
map_row[(x << 2) + 0] = (src0_x >= 0) && (src0_x < (s32)ssize.width) &&
|
||||
(src0_y >= 0) && (src0_y < (s32)ssize.height) ? src0_y * srcStride + src0_x : -1;
|
||||
map_row[(x << 2) + 1] = (src1_x >= 0) && (src1_x < (s32)ssize.width) &&
|
||||
(src0_y >= 0) && (src0_y < (s32)ssize.height) ? src0_y * srcStride + src1_x : -1;
|
||||
map_row[(x << 2) + 2] = (src0_x >= 0) && (src0_x < (s32)ssize.width) &&
|
||||
(src1_y >= 0) && (src1_y < (s32)ssize.height) ? src1_y * srcStride + src0_x : -1;
|
||||
map_row[(x << 2) + 3] = (src1_x >= 0) && (src1_x < (s32)ssize.width) &&
|
||||
(src1_y >= 0) && (src1_y < (s32)ssize.height) ? src1_y * srcStride + src1_x : -1;
|
||||
}
|
||||
}
|
||||
|
||||
remapLinearConst(Size2D(blockWidth, blockHeight),
|
||||
srcBase, &map[0], &coeffs[0],
|
||||
getRowPtr(dstBase, dstStride, i) + j, dstStride, borderValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)ssize;
|
||||
(void)dsize;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)tableBase;
|
||||
(void)tableStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)borderMode;
|
||||
(void)borderValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#ifndef CAROTENE_SRC_REMAP_HPP
|
||||
#define CAROTENE_SRC_REMAP_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace CAROTENE_NS { namespace internal {
|
||||
|
||||
enum
|
||||
{
|
||||
BLOCK_SIZE = 32
|
||||
};
|
||||
|
||||
|
||||
void remapNearestNeighborReplicate(const Size2D size,
|
||||
const u8 * srcBase,
|
||||
const s32 * map,
|
||||
u8 * dstBase, ptrdiff_t dstStride);
|
||||
|
||||
void remapNearestNeighborConst(const Size2D size,
|
||||
const u8 * srcBase,
|
||||
const s32 * map,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
u8 borderValue);
|
||||
|
||||
void remapLinearReplicate(const Size2D size,
|
||||
const u8 * srcBase,
|
||||
const s32 * map,
|
||||
const f32 * coeffs,
|
||||
u8 * dstBase, ptrdiff_t dstStride);
|
||||
|
||||
void remapLinearConst(const Size2D size,
|
||||
const u8 * srcBase,
|
||||
const s32 * map,
|
||||
const f32 * coeffs,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
u8 borderValue);
|
||||
|
||||
} }
|
||||
|
||||
#endif // CAROTENE_NEON
|
||||
|
||||
#endif // CAROTENE_SRC_REMAP_HPP
|
||||
Vendored
+2191
File diff suppressed because it is too large
Load Diff
+199
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2012-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#ifndef CAROTENE_SATURATE_CAST_HPP
|
||||
#define CAROTENE_SATURATE_CAST_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <climits>
|
||||
#include <cmath>
|
||||
|
||||
#if defined _MSC_VER && defined _M_ARM
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
|
||||
#include <carotene/definitions.hpp>
|
||||
#include <carotene/types.hpp>
|
||||
|
||||
namespace CAROTENE_NS { namespace internal {
|
||||
|
||||
#if defined _MSC_VER && defined _M_ARM
|
||||
|
||||
__declspec(naked) static void vcvtr_s32_f64_imp(f64 d)
|
||||
{
|
||||
(void)d;
|
||||
__emit(0xEEBD); // vcvtr.s32.f64 s0, d0
|
||||
__emit(0x0B40);
|
||||
__emit(0xEE10); // vmov r0, s0
|
||||
__emit(0x0A10);
|
||||
__emit(0x4770); // bx lr
|
||||
}
|
||||
|
||||
# define CAROTENE_ROUND_FLT(x) return ((s32 (*)(f64))vcvtr_s32_f64_imp)((f64)x);
|
||||
# define CAROTENE_ROUND_DBL(x) return ((s32 (*)(f64))vcvtr_s32_f64_imp)(x);
|
||||
|
||||
#elif defined CV_ICC || defined __GNUC__
|
||||
|
||||
# if defined(__VFP_FP__) && !defined(__SOFTFP__) && !(defined _DEBUG || defined DEBUG) && !defined(__CUDACC__)
|
||||
# define CAROTENE_ROUND_FLT(value) { \
|
||||
register union { f32 f; s32 i; } result; \
|
||||
asm ("ftosis %0, %1 \n" : "=w" (result.f) : "w" (value) ); \
|
||||
return result.i; }
|
||||
# define CAROTENE_ROUND_DBL(value) { \
|
||||
register union {f32 f; s32 i;} __tegra_result; \
|
||||
asm ( \
|
||||
"ftosid %0, %P1\n" \
|
||||
: "=w" (__tegra_result.f) \
|
||||
: "w" (value) \
|
||||
); \
|
||||
return __tegra_result.i; \
|
||||
}
|
||||
# else
|
||||
# define CAROTENE_ROUND_FLT(x) return (s32)lrintf(value);
|
||||
# define CAROTENE_ROUND_DBL(value) return (s32)lrint(value);
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
inline s32 round(f32 value)
|
||||
{
|
||||
#ifdef CAROTENE_ROUND_FLT
|
||||
CAROTENE_ROUND_FLT(value)
|
||||
#else
|
||||
s32 intpart = (s32)(value);
|
||||
f32 fractpart = value - intpart;
|
||||
if ((fractpart != 0.5 && fractpart != -0.5) || ((intpart % 2) != 0))
|
||||
return (s32)(value + (value >= 0 ? 0.5 : -0.5));
|
||||
else
|
||||
return intpart;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline s32 round(f64 value)
|
||||
{
|
||||
#ifdef CAROTENE_ROUND_DBL
|
||||
CAROTENE_ROUND_DBL(value)
|
||||
#else
|
||||
s32 intpart = (s32)(value);
|
||||
f64 fractpart = value - intpart;
|
||||
if ((fractpart != 0.5 && fractpart != -0.5) || ((intpart % 2) != 0))
|
||||
return (s32)(value + (value >= 0 ? 0.5 : -0.5));
|
||||
else
|
||||
return intpart;
|
||||
#endif
|
||||
}
|
||||
/////////////// saturate_cast (used in image & signal processing) ///////////////////
|
||||
|
||||
template<typename _Tp> inline _Tp saturate_cast(u8 v) { return _Tp(v); }
|
||||
template<typename _Tp> inline _Tp saturate_cast(s8 v) { return _Tp(v); }
|
||||
template<typename _Tp> inline _Tp saturate_cast(u16 v) { return _Tp(v); }
|
||||
template<typename _Tp> inline _Tp saturate_cast(s16 v) { return _Tp(v); }
|
||||
template<typename _Tp> inline _Tp saturate_cast(u32 v) { return _Tp(v); }
|
||||
template<typename _Tp> inline _Tp saturate_cast(s32 v) { return _Tp(v); }
|
||||
template<typename _Tp> inline _Tp saturate_cast(s64 v) { return _Tp(v); }
|
||||
template<typename _Tp> inline _Tp saturate_cast(u64 v) { return _Tp(v); }
|
||||
template<typename _Tp> inline _Tp saturate_cast(f32 v) { return _Tp(v); }
|
||||
template<typename _Tp> inline _Tp saturate_cast(f64 v) { return _Tp(v); }
|
||||
|
||||
template<> inline u8 saturate_cast<u8>(s8 v) { return (u8)std::max((s32)v, 0); }
|
||||
template<> inline u8 saturate_cast<u8>(u16 v) { return (u8)std::min((u32)v, (u32)UCHAR_MAX); }
|
||||
template<> inline u8 saturate_cast<u8>(s32 v) { return (u8)((u32)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
|
||||
template<> inline u8 saturate_cast<u8>(s16 v) { return saturate_cast<u8>((s32)v); }
|
||||
template<> inline u8 saturate_cast<u8>(u32 v) { return (u8)std::min(v, (u32)UCHAR_MAX); }
|
||||
template<> inline u8 saturate_cast<u8>(s64 v) { return (u8)((u64)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
|
||||
template<> inline u8 saturate_cast<u8>(u64 v) { return (u8)std::min(v, (u64)UCHAR_MAX); }
|
||||
template<> inline u8 saturate_cast<u8>(f32 v) { return saturate_cast<u8>(round(v)); }
|
||||
template<> inline u8 saturate_cast<u8>(f64 v) { return saturate_cast<u8>(round(v)); }
|
||||
|
||||
template<> inline s8 saturate_cast<s8>(u8 v) { return (s8)std::min((s32)v, SCHAR_MAX); }
|
||||
template<> inline s8 saturate_cast<s8>(u16 v) { return (s8)std::min((u32)v, (u32)SCHAR_MAX); }
|
||||
template<> inline s8 saturate_cast<s8>(s32 v) { return (s8)((u32)(v-SCHAR_MIN) <= (u32)UCHAR_MAX ? v : v > 0 ? SCHAR_MAX : SCHAR_MIN); }
|
||||
template<> inline s8 saturate_cast<s8>(s16 v) { return saturate_cast<s8>((s32)v); }
|
||||
template<> inline s8 saturate_cast<s8>(u32 v) { return (s8)std::min(v, (u32)SCHAR_MAX); }
|
||||
template<> inline s8 saturate_cast<s8>(s64 v) { return (s8)((u64)(v-SCHAR_MIN) <= (u64)UCHAR_MAX ? v : v > 0 ? SCHAR_MAX : SCHAR_MIN); }
|
||||
template<> inline s8 saturate_cast<s8>(u64 v) { return (s8)std::min(v, (u64)SCHAR_MAX); }
|
||||
template<> inline s8 saturate_cast<s8>(f32 v) { return saturate_cast<s8>(round(v)); }
|
||||
template<> inline s8 saturate_cast<s8>(f64 v) { return saturate_cast<s8>(round(v)); }
|
||||
|
||||
template<> inline u16 saturate_cast<u16>(s8 v) { return (u16)std::max((s32)v, 0); }
|
||||
template<> inline u16 saturate_cast<u16>(s16 v) { return (u16)std::max((s32)v, 0); }
|
||||
template<> inline u16 saturate_cast<u16>(s32 v) { return (u16)((u32)v <= (u32)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); }
|
||||
template<> inline u16 saturate_cast<u16>(u32 v) { return (u16)std::min(v, (u32)USHRT_MAX); }
|
||||
template<> inline u16 saturate_cast<u16>(s64 v) { return (u16)((u64)v <= (u64)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); }
|
||||
template<> inline u16 saturate_cast<u16>(u64 v) { return (u16)std::min(v, (u64)USHRT_MAX); }
|
||||
template<> inline u16 saturate_cast<u16>(f32 v) { return saturate_cast<u16>(round(v)); }
|
||||
template<> inline u16 saturate_cast<u16>(f64 v) { return saturate_cast<u16>(round(v)); }
|
||||
|
||||
template<> inline s16 saturate_cast<s16>(u16 v) { return (s16)std::min((s32)v, SHRT_MAX); }
|
||||
template<> inline s16 saturate_cast<s16>(s32 v) { return (s16)((u32)(v - SHRT_MIN) <= (u32)USHRT_MAX ? v : v > 0 ? SHRT_MAX : SHRT_MIN); }
|
||||
template<> inline s16 saturate_cast<s16>(u32 v) { return (s16)std::min(v, (u32)SHRT_MAX); }
|
||||
template<> inline s16 saturate_cast<s16>(s64 v) { return (s16)((u64)(v - SHRT_MIN) <= (u64)USHRT_MAX ? v : v > 0 ? SHRT_MAX : SHRT_MIN); }
|
||||
template<> inline s16 saturate_cast<s16>(u64 v) { return (s16)std::min(v, (u64)SHRT_MAX); }
|
||||
template<> inline s16 saturate_cast<s16>(f32 v) { return saturate_cast<s16>(round(v)); }
|
||||
template<> inline s16 saturate_cast<s16>(f64 v) { return saturate_cast<s16>(round(v)); }
|
||||
|
||||
template<> inline u32 saturate_cast<u32>(s8 v) { return (u32)std::max(v, (s8)0); }
|
||||
template<> inline u32 saturate_cast<u32>(s16 v) { return (u32)std::max(v, (s16)0); }
|
||||
template<> inline u32 saturate_cast<u32>(s32 v) { return (u32)std::max(v, (s32)0); }
|
||||
template<> inline u32 saturate_cast<u32>(s64 v) { return (u32)((u64)v <= (u64)UINT_MAX ? v : v > 0 ? UINT_MAX : 0); }
|
||||
template<> inline u32 saturate_cast<u32>(u64 v) { return (u32)std::min(v, (u64)UINT_MAX); }
|
||||
//OpenCV like f32/f64 -> u32 conversion
|
||||
//we intentionally do not clip negative numbers, to make -1 become 0xffffffff etc.
|
||||
template<> inline u32 saturate_cast<u32>(f32 v) { return round(v); }
|
||||
template<> inline u32 saturate_cast<u32>(f64 v) { return round(v); }
|
||||
//Negative clipping implementation
|
||||
//template<> inline u32 saturate_cast<u32>(f32 v) { return saturate_cast<u32>(round(v)); }
|
||||
//template<> inline u32 saturate_cast<u32>(f64 v) { return saturate_cast<u32>(round(v)); }
|
||||
|
||||
template<> inline s32 saturate_cast<s32>(u32 v) { return (s32)std::min(v, (u32)INT_MAX); }
|
||||
template<> inline s32 saturate_cast<s32>(s64 v) { return (s32)((u64)(v - INT_MIN) <= (u64)UINT_MAX ? v : v > 0 ? INT_MAX : INT_MIN); }
|
||||
template<> inline s32 saturate_cast<s32>(u64 v) { return (s32)std::min(v, (u64)INT_MAX); }
|
||||
template<> inline s32 saturate_cast<s32>(f32 v) { return round(v); }
|
||||
template<> inline s32 saturate_cast<s32>(f64 v) { return round(v); }
|
||||
|
||||
template<> inline u64 saturate_cast<u64>(s8 v) { return (u64)std::max(v, (s8)0); }
|
||||
template<> inline u64 saturate_cast<u64>(s16 v) { return (u64)std::max(v, (s16)0); }
|
||||
template<> inline u64 saturate_cast<u64>(s32 v) { return (u64)std::max(v, (s32)0); }
|
||||
template<> inline u64 saturate_cast<u64>(s64 v) { return (u64)std::max(v, (s64)0); }
|
||||
|
||||
template<> inline s64 saturate_cast<s64>(u64 v) { return (s64)std::min(v, (u64)LLONG_MAX); }
|
||||
|
||||
} }
|
||||
|
||||
#endif
|
||||
Vendored
+219
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2012-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
bool isScharr3x3Supported(const Size2D &size, BORDER_MODE border, s32 dx, s32 dy, Margin borderMargin)
|
||||
{
|
||||
return (dx == 0 && dy == 1 &&
|
||||
isSeparableFilter3x3Supported(size, border, 3, 1, borderMargin)) ||
|
||||
(dx == 1 && dy == 0 &&
|
||||
isSeparableFilter3x3Supported(size, border, 1, 3, borderMargin));
|
||||
}
|
||||
|
||||
void Scharr3x3(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
s16 * dstBase, ptrdiff_t dstStride,
|
||||
s32 dx, s32 dy,
|
||||
BORDER_MODE border, u8 borderValue, Margin borderMargin)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isScharr3x3Supported(size, border, dx, dy, borderMargin));
|
||||
#ifdef CAROTENE_NEON
|
||||
static s16 dw[] = {3, 10, 3};
|
||||
|
||||
if (dy == 1)
|
||||
SeparableFilter3x3(size, srcBase, srcStride, dstBase, dstStride,
|
||||
3, 1, dw, 0,
|
||||
border, borderValue, borderMargin);
|
||||
else
|
||||
SeparableFilter3x3(size, srcBase, srcStride, dstBase, dstStride,
|
||||
1, 3, 0, dw,
|
||||
border, borderValue, borderMargin);
|
||||
#else
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)borderValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ScharrDeriv(const Size2D &size, s32 cn,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
s16 * dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
size_t colsn = size.width*cn;
|
||||
size_t roiw8 = colsn > 7 ? colsn - 7 : 0;
|
||||
|
||||
ptrdiff_t delta = (ptrdiff_t)(((size.width + 2)*cn + 15) & -16);//align size
|
||||
std::vector<s16> _tempBuf((delta << 1) + 64);
|
||||
s16 *trow0 = internal::alignPtr(&_tempBuf[cn], 16), *trow1 = internal::alignPtr(trow0 + delta, 16);
|
||||
|
||||
int16x8_t vc3 = vmovq_n_s16(3);
|
||||
int16x8_t vc10 = vmovq_n_s16(10);
|
||||
uint8x8_t v8c10 = vmov_n_u8(10);
|
||||
|
||||
for(size_t y = 0; y < size.height; y++ )
|
||||
{
|
||||
const u8* srow0 = internal::getRowPtr(srcBase, srcStride, y > 0 ? y-1 : size.height > 1 ? 1 : 0);
|
||||
const u8* srow1 = internal::getRowPtr(srcBase, srcStride, y);
|
||||
const u8* srow2 = internal::getRowPtr(srcBase, srcStride, y < size.height-1 ? y+1 : size.height > 1 ? size.height-2 : 0);
|
||||
s16* drow = internal::getRowPtr(dstBase, dstStride, y);
|
||||
|
||||
// do vertical convolution
|
||||
size_t x = 0;
|
||||
for( ; x < roiw8; x += 8 )
|
||||
{
|
||||
internal::prefetch(srow0 + x);
|
||||
internal::prefetch(srow1 + x);
|
||||
internal::prefetch(srow2 + x);
|
||||
#if __GNUC_MINOR__ < 7
|
||||
__asm__ (
|
||||
"vld1.8 {d0}, [%[src0]] \n\t"
|
||||
"vld1.8 {d2}, [%[src2]] \n\t"
|
||||
"vld1.8 {d1}, [%[src1]] \n\t"
|
||||
"vaddl.u8 q2, d2, d0 \n\t"
|
||||
"vmull.u8 q3, d1, %[vc10] \n\t"
|
||||
"vsubl.u8 q4, d2, d0 \n\t"
|
||||
"vmla.s16 q3, q2, %q[vc3] \n\t"
|
||||
"vst1.16 {d8-d9}, [%[out1],:128] \n\t"
|
||||
"vst1.16 {d6-d7}, [%[out0],:128] \n\t"
|
||||
:
|
||||
: [out0] "r" (trow0 + x),
|
||||
[out1] "r" (trow1 + x),
|
||||
[src0] "r" (srow0 + x),
|
||||
[src1] "r" (srow1 + x),
|
||||
[src2] "r" (srow2 + x),
|
||||
[vc10] "w" (v8c10), [vc3] "w" (vc3)
|
||||
: "d0","d1","d2","d3","d4","d5","d6","d7","d8","d9","d10","d11","d12","d13","d14","d15"
|
||||
);
|
||||
#else
|
||||
uint8x8_t s0 = vld1_u8(srow0 + x);
|
||||
uint8x8_t s1 = vld1_u8(srow1 + x);
|
||||
uint8x8_t s2 = vld1_u8(srow2 + x);
|
||||
|
||||
int16x8_t s1x10 = vreinterpretq_s16_u16(vmull_u8(s1, v8c10));
|
||||
int16x8_t s02 = vreinterpretq_s16_u16(vaddl_u8(s2, s0));
|
||||
int16x8_t t1 = vreinterpretq_s16_u16(vsubl_u8(s2, s0));
|
||||
int16x8_t t0 = vmlaq_s16(s1x10, s02, vc3);
|
||||
|
||||
vst1q_s16(trow1 + x, t1);
|
||||
vst1q_s16(trow0 + x, t0);
|
||||
#endif
|
||||
}
|
||||
for( ; x < colsn; x++ )
|
||||
{
|
||||
trow0[x] = (s16)((srow0[x] + srow2[x])*3 + srow1[x]*10);
|
||||
trow1[x] = (s16)(srow2[x] - srow0[x]);
|
||||
}
|
||||
|
||||
// make border
|
||||
size_t x0 = (size.width > 1 ? cn : 0), x1 = (size.width > 1 ? (size.width-2)*cn : 0);
|
||||
for( s32 k = 0; k < cn; k++ )
|
||||
{
|
||||
trow0[-cn + k] = trow0[x0 + k]; trow0[colsn + k] = trow0[x1 + k];
|
||||
trow1[-cn + k] = trow1[x0 + k]; trow1[colsn + k] = trow1[x1 + k];
|
||||
}
|
||||
|
||||
// do horizontal convolution, interleave the results and store them to dst
|
||||
x = 0;
|
||||
for( ; x < roiw8; x += 8 )
|
||||
{
|
||||
#if __GNUC_MINOR__ < 6
|
||||
__asm__ (
|
||||
"vld1.16 {d4-d5}, [%[s2ptr]] \n\t"
|
||||
"vld1.16 {d8-d9}, [%[s4ptr]] \n\t"
|
||||
"vld1.16 {d6-d7}, [%[s3ptr],:128] \n\t"
|
||||
"vld1.16 {d0-d1}, [%[s0ptr]] \n\t"
|
||||
"vld1.16 {d2-d3}, [%[s1ptr]] \n\t"
|
||||
"vadd.i16 q7, q2, q4 \n\t"
|
||||
"vmul.s16 q6, q3, %q[vc10] \n\t"
|
||||
"vsub.s16 q5, q1, q0 \n\t"
|
||||
"vmla.s16 q6, q7, %q[vc3] \n\t"
|
||||
"vst2.16 {d10-d13}, [%[out]] \n\t"
|
||||
:
|
||||
: [out] "r" (drow + x * 2),
|
||||
[s0ptr] "r" (trow0 + x - cn),
|
||||
[s1ptr] "r" (trow0 + x + cn),
|
||||
[s2ptr] "r" (trow1 + x - cn),
|
||||
[s3ptr] "r" (trow1 + x),
|
||||
[s4ptr] "r" (trow1 + x + cn),
|
||||
[vc10] "w" (vc10), [vc3] "w" (vc3)
|
||||
: "d0","d1","d2","d3","d4","d5","d6","d7","d8","d9","d10","d11","d12","d13","d14","d15"
|
||||
);
|
||||
#else
|
||||
int16x8_t s0 = vld1q_s16(trow0 + x - cn);
|
||||
int16x8_t s1 = vld1q_s16(trow0 + x + cn);
|
||||
int16x8_t s2 = vld1q_s16(trow1 + x - cn);
|
||||
int16x8_t s3 = vld1q_s16(trow1 + x);
|
||||
int16x8_t s4 = vld1q_s16(trow1 + x + cn);
|
||||
|
||||
int16x8_t s3x10 = vmulq_s16(s3, vc10);
|
||||
int16x8_t s24 = vaddq_s16(s2, s4);
|
||||
|
||||
int16x8x2_t vr;
|
||||
vr.val[0] = vsubq_s16(s1, s0);
|
||||
vr.val[1] = vmlaq_s16(s3x10, s24, vc3);
|
||||
|
||||
vst2q_s16(drow + x*2, vr);
|
||||
#endif //__GNUC_MINOR__ < 6
|
||||
}
|
||||
for( ; x < colsn; x++ )
|
||||
{
|
||||
drow[x*2] = (s16)(trow0[x+cn] - trow0[x-cn]);
|
||||
drow[x*2+1] = (s16)((trow1[x+cn] + trow1[x-cn])*3 + trow1[x]*10);
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)cn;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include "separable_filter.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
bool isSeparableFilter3x3Supported(const Size2D &size, BORDER_MODE border, s32 dx, s32 dy, Margin borderMargin)
|
||||
{
|
||||
return isSupportedConfiguration() &&
|
||||
size.width >= 9 && size.height >= 1 &&
|
||||
(size.height + borderMargin.top + borderMargin.bottom) >= 2 &&
|
||||
(dx >= 0) && (dx < 4) && (dy >= 0) && (dy < 4) &&
|
||||
(border == BORDER_MODE_CONSTANT ||
|
||||
border == BORDER_MODE_REFLECT ||
|
||||
border == BORDER_MODE_REFLECT101 ||
|
||||
border == BORDER_MODE_REPLICATE );
|
||||
}
|
||||
|
||||
void SeparableFilter3x3(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
s16 * dstBase, ptrdiff_t dstStride,
|
||||
const u8 rowFilter, const u8 colFilter, const s16 *xw, const s16 *yw,
|
||||
BORDER_MODE border, u8 borderValue, Margin borderMargin)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isSeparableFilter3x3Supported(size, border, rowFilter, colFilter, borderMargin));
|
||||
#ifdef CAROTENE_NEON
|
||||
if(!((xw || rowFilter < 3) && (yw || colFilter < 3)))
|
||||
std::abort();//Couldn't call generic filter without provided weights
|
||||
|
||||
typedef void (*sepFilter3x3_8u16s_func)(const Size2D&, const u8*, ptrdiff_t, s16*, ptrdiff_t,
|
||||
const s16*, const s16*, BORDER_MODE, u8, Margin);
|
||||
|
||||
static sepFilter3x3_8u16s_func quickFilters[4][4]=
|
||||
{
|
||||
/*d0y*/{ /*d0x*/ internal::sepFilter3x3<internal::RowFilter3x3S16_121, internal::ColFilter3x3S16_121>::process,
|
||||
/*dx*/ internal::sepFilter3x3<internal::RowFilter3x3S16_m101, internal::ColFilter3x3S16_121>::process,
|
||||
/*d2x*/ internal::sepFilter3x3<internal::RowFilter3x3S16_1m21, internal::ColFilter3x3S16_121>::process,
|
||||
/*dNx*/ internal::sepFilter3x3<internal::RowFilter3x3S16Generic, internal::ColFilter3x3S16_121>::process},
|
||||
|
||||
/*dy */{ /*d0x*/ internal::sepFilter3x3<internal::RowFilter3x3S16_121, internal::ColFilter3x3S16_m101>::process,
|
||||
/*dx*/ internal::sepFilter3x3<internal::RowFilter3x3S16_m101, internal::ColFilter3x3S16_m101>::process,
|
||||
/*d2x*/ internal::sepFilter3x3<internal::RowFilter3x3S16_1m21, internal::ColFilter3x3S16_m101>::process,
|
||||
/*dNx*/ internal::sepFilter3x3<internal::RowFilter3x3S16Generic, internal::ColFilter3x3S16_m101>::process},
|
||||
|
||||
/*d2y*/{ /*d0x*/ internal::sepFilter3x3<internal::RowFilter3x3S16_121, internal::ColFilter3x3S16_1m21>::process,
|
||||
/*dx*/ internal::sepFilter3x3<internal::RowFilter3x3S16_m101, internal::ColFilter3x3S16_1m21>::process,
|
||||
/*d2x*/ internal::sepFilter3x3<internal::RowFilter3x3S16_1m21, internal::ColFilter3x3S16_1m21>::process,
|
||||
/*dNx*/ internal::sepFilter3x3<internal::RowFilter3x3S16Generic, internal::ColFilter3x3S16_1m21>::process},
|
||||
|
||||
/*dNy*/{ /*d0x*/ internal::sepFilter3x3<internal::RowFilter3x3S16_121, internal::ColFilter3x3S16Generic>::process,
|
||||
/*dx*/ internal::sepFilter3x3<internal::RowFilter3x3S16_m101, internal::ColFilter3x3S16Generic>::process,
|
||||
/*d2x*/ internal::sepFilter3x3<internal::RowFilter3x3S16_1m21, internal::ColFilter3x3S16Generic>::process,
|
||||
/*dNx*/ internal::sepFilter3x3<internal::RowFilter3x3S16Generic, internal::ColFilter3x3S16Generic>::process}
|
||||
};
|
||||
|
||||
quickFilters[colFilter][rowFilter](size, srcBase, srcStride, dstBase, dstStride,
|
||||
xw, yw, border, borderValue, borderMargin);
|
||||
#else
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)xw;
|
||||
(void)yw;
|
||||
(void)borderValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
+1161
File diff suppressed because it is too large
Load Diff
Vendored
+317
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2012-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
bool isSobel3x3Supported(const Size2D &size, BORDER_MODE border,
|
||||
s32 dx, s32 dy, Margin borderMargin)
|
||||
{
|
||||
return dx < 3 && dx >= 0 &&
|
||||
dy < 3 && dy >= 0 &&
|
||||
(dx + dy) > 0 &&
|
||||
isSeparableFilter3x3Supported(size, border, dx, dy, borderMargin);
|
||||
}
|
||||
|
||||
void Sobel3x3(const Size2D &size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
s16 * dstBase, ptrdiff_t dstStride,
|
||||
s32 dx, s32 dy,
|
||||
BORDER_MODE borderType, u8 borderValue, Margin borderMargin)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isSobel3x3Supported(size, borderType, dx, dy, borderMargin));
|
||||
#ifdef CAROTENE_NEON
|
||||
SeparableFilter3x3(size, srcBase, srcStride, dstBase, dstStride,
|
||||
dx, dy, 0, 0,
|
||||
borderType, borderValue, borderMargin);
|
||||
#else
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)borderValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isSobel3x3f32Supported(const Size2D &size, BORDER_MODE border,
|
||||
s32 dx, s32 dy)
|
||||
{
|
||||
return isSupportedConfiguration() &&
|
||||
dx < 3 && dx >= 0 &&
|
||||
dy < 3 && dy >= 0 &&
|
||||
(dx + dy) > 0 &&
|
||||
size.width >= 4 && size.height >= 2 &&
|
||||
(border == BORDER_MODE_CONSTANT ||
|
||||
border == BORDER_MODE_REFLECT ||
|
||||
border == BORDER_MODE_REFLECT101 ||
|
||||
border == BORDER_MODE_REPLICATE );
|
||||
}
|
||||
|
||||
void Sobel3x3(const Size2D &size,
|
||||
const f32 * srcBase, ptrdiff_t srcStride,
|
||||
f32 * dstBase, ptrdiff_t dstStride,
|
||||
s32 dx, s32 dy,
|
||||
BORDER_MODE borderType, f32 borderValue)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isSobel3x3f32Supported(size, borderType, dx, dy));
|
||||
#ifdef CAROTENE_NEON
|
||||
std::vector<f32> _tmp;
|
||||
f32 *tmp = 0;
|
||||
if (borderType == BORDER_MODE_CONSTANT)
|
||||
{
|
||||
_tmp.assign(size.width + 2, borderValue);
|
||||
tmp = &_tmp[1];
|
||||
}
|
||||
|
||||
ptrdiff_t delta = (ptrdiff_t)((size.width + 2 + 31) & -32);//align size
|
||||
std::vector<f32> _tempBuf((delta << 1) + 64);
|
||||
f32 *trow0 = internal::alignPtr(&_tempBuf[1], 32), *trow1 = internal::alignPtr(trow0 + delta, 32);
|
||||
|
||||
for( size_t y = 0; y < size.height; y++ )
|
||||
{
|
||||
const f32* srow0;
|
||||
const f32* srow1 = internal::getRowPtr(srcBase, srcStride, y);
|
||||
const f32* srow2;
|
||||
f32* drow = internal::getRowPtr(dstBase, dstStride, y > 0 ? y-1 : 0);
|
||||
f32* drow1 = internal::getRowPtr(dstBase, dstStride, y);
|
||||
if (borderType == BORDER_MODE_REFLECT101) {
|
||||
srow0 = internal::getRowPtr(srcBase, srcStride, y > 0 ? y-1 : 1);
|
||||
srow2 = internal::getRowPtr(srcBase, srcStride, y < size.height-1 ? y+1 : size.height-2);
|
||||
} else if (borderType == BORDER_MODE_CONSTANT) {
|
||||
srow0 = y > 0 ? internal::getRowPtr(srcBase, srcStride, y-1) : tmp;
|
||||
srow2 = y < size.height-1 ? internal::getRowPtr(srcBase, srcStride, y+1) : tmp;
|
||||
} else { // BORDER_MODE_REFLECT || BORDER_MODE_REPLICATE
|
||||
srow0 = internal::getRowPtr(srcBase, srcStride, y > 0 ? y-1 : 0);
|
||||
srow2 = internal::getRowPtr(srcBase, srcStride, y < size.height-1 ? y+1 : size.height-1);
|
||||
}
|
||||
|
||||
float32x4_t tprev = vmovq_n_f32(0.f);
|
||||
float32x4_t tcurr = vmovq_n_f32(0.f);
|
||||
float32x4_t tnext = vmovq_n_f32(0.f);
|
||||
float32x4_t t0, t1, t2;
|
||||
// do vertical convolution
|
||||
size_t x = 0, bcolsn = y + 2 < size.height ? size.width : (size.width - 4);
|
||||
for( ; x <= bcolsn; x += 4 )
|
||||
{
|
||||
internal::prefetch(srow0 + x);
|
||||
internal::prefetch(srow1 + x);
|
||||
internal::prefetch(srow2 + x);
|
||||
|
||||
float32x4_t x0 = vld1q_f32(srow0 + x);
|
||||
float32x4_t x1 = vld1q_f32(srow1 + x);
|
||||
float32x4_t x2 = vld1q_f32(srow2 + x);
|
||||
|
||||
tprev = tcurr;
|
||||
tcurr = tnext;
|
||||
if(!dy)
|
||||
{
|
||||
tnext = vaddq_f32(vaddq_f32(vaddq_f32(x1, x1), x2), x0);
|
||||
}
|
||||
else if(dy == 2)
|
||||
{
|
||||
tnext = vsubq_f32(vsubq_f32(x2, x1), vsubq_f32(x1, x0));
|
||||
}
|
||||
else
|
||||
{
|
||||
tnext = vsubq_f32(x2, x0);
|
||||
}
|
||||
|
||||
if(!x) {
|
||||
tcurr = tnext;
|
||||
// make border
|
||||
if (borderType == BORDER_MODE_CONSTANT)
|
||||
{
|
||||
tcurr = vsetq_lane_f32(borderValue,tcurr, 3);
|
||||
}
|
||||
else if (borderType == BORDER_MODE_REFLECT101)
|
||||
{
|
||||
tcurr = vsetq_lane_f32(vgetq_lane_f32(tcurr, 1),tcurr, 3);
|
||||
}
|
||||
else // BORDER_MODE_REFLECT || BORDER_MODE_REPLICATE
|
||||
{
|
||||
tcurr = vsetq_lane_f32(vgetq_lane_f32(tcurr, 0),tcurr, 3);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
internal::prefetch(trow0 + x);
|
||||
internal::prefetch(trow1 + x);
|
||||
|
||||
t0 = vextq_f32(tprev, tcurr, 3);
|
||||
t1 = tcurr;
|
||||
t2 = vextq_f32(tcurr, tnext, 1);
|
||||
if(!dx)
|
||||
{
|
||||
t0 = vaddq_f32(t0, vaddq_f32(vaddq_f32(t1, t1), t2));
|
||||
}
|
||||
else if(dx == 2)
|
||||
{
|
||||
t0 = vsubq_f32(vsubq_f32(t2, t1), vsubq_f32(t1, t0));
|
||||
}
|
||||
else
|
||||
{
|
||||
t0 = vsubq_f32(t2, t0);
|
||||
}
|
||||
|
||||
if(!(y%2))
|
||||
{
|
||||
vst1q_f32(trow0 + x - 4, t0);
|
||||
}
|
||||
else
|
||||
{
|
||||
vst1q_f32(trow1 + x - 4, t0);
|
||||
}
|
||||
}
|
||||
x -= 4;
|
||||
if(x == size.width){
|
||||
x--;
|
||||
}
|
||||
f32 prevx = 0, rowx = 0, nextx = 0;
|
||||
if(!dy)
|
||||
{
|
||||
prevx = x > 0 ? srow2[x-1] + 2*srow1[x-1] + srow0[x-1] :
|
||||
(borderType == BORDER_MODE_REFLECT101 ? srow2[1] + 2*srow1[1] + srow0[1] :
|
||||
(borderType == BORDER_MODE_CONSTANT ? 4*borderValue :
|
||||
srow2[0] + 2*srow1[0] + srow0[0]) );
|
||||
rowx = srow2[x] + 2*srow1[x] + srow0[x];
|
||||
}
|
||||
else if(dy == 2)
|
||||
{
|
||||
prevx = x > 0 ? srow2[x-1] - 2*srow1[x-1] + srow0[x-1] :
|
||||
(borderType == BORDER_MODE_REFLECT101 ? srow2[1] - 2*srow1[1] + srow0[1] :
|
||||
(borderType == BORDER_MODE_CONSTANT ? 0.f :
|
||||
srow2[0] - 2*srow1[0] + srow0[0]) );
|
||||
rowx = srow2[x] - 2*srow1[x] + srow0[x];
|
||||
}
|
||||
else
|
||||
{
|
||||
prevx = x > 0 ? srow2[x-1] - srow0[x-1] :
|
||||
(borderType == BORDER_MODE_REFLECT101 ? srow2[1] - srow0[1] :
|
||||
(borderType == BORDER_MODE_CONSTANT ? 0.f :
|
||||
srow2[0] - srow0[0]) );
|
||||
rowx = srow2[x] - srow0[x];
|
||||
}
|
||||
|
||||
for( ; x < size.width; x++ )
|
||||
{
|
||||
if(x+1 == size.width) {
|
||||
// make border
|
||||
if (borderType == BORDER_MODE_CONSTANT)
|
||||
{
|
||||
if(!dy) {
|
||||
nextx = 4*borderValue;
|
||||
} else {
|
||||
nextx = 0.f;
|
||||
}
|
||||
} else if (borderType == BORDER_MODE_REFLECT101)
|
||||
{
|
||||
if(!dy) {
|
||||
nextx = srow2[x-1] + 2*srow1[x-1] + srow0[x-1];
|
||||
} else if(dy == 2) {
|
||||
nextx = srow2[x-1] - 2*srow1[x-1] + srow0[x-1];
|
||||
} else {
|
||||
nextx = srow2[x-1] - srow0[x-1];
|
||||
}
|
||||
} else {
|
||||
if(!dy) {
|
||||
nextx = srow2[x] + 2*srow1[x] + srow0[x];
|
||||
} else if(dy == 2) {
|
||||
nextx = srow2[x] - 2*srow1[x] + srow0[x];
|
||||
} else {
|
||||
nextx = srow2[x] - srow0[x];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(!dy) {
|
||||
nextx = srow2[x+1] + 2*srow1[x+1] + srow0[x+1];
|
||||
} else if(dy == 2) {
|
||||
nextx = srow2[x+1] - 2*srow1[x+1] + srow0[x+1];
|
||||
} else {
|
||||
nextx = srow2[x+1] - srow0[x+1];
|
||||
}
|
||||
}
|
||||
f32 res;
|
||||
if(dx==1) {
|
||||
res = nextx - prevx;
|
||||
} else if(!dx) {
|
||||
res = prevx + 2*rowx + nextx;
|
||||
} else {
|
||||
res = prevx - 2*rowx + nextx;
|
||||
}
|
||||
if(!(y%2)) {
|
||||
*(trow0+x) = res;
|
||||
} else {
|
||||
*(trow1+x) = res;
|
||||
}
|
||||
prevx = rowx;
|
||||
rowx = nextx;
|
||||
}
|
||||
|
||||
if(y>0) {
|
||||
for(size_t x1 = 0; x1 < size.width; x1++ )
|
||||
{
|
||||
if(y%2)
|
||||
*(drow + x1) = trow0[x1];
|
||||
else
|
||||
*(drow + x1) = trow1[x1];
|
||||
}
|
||||
}
|
||||
if(y == size.height-1) {
|
||||
for(size_t x1 = 0; x1 < size.width; x1++ )
|
||||
{
|
||||
if(!(y%2))
|
||||
*(drow1 + x1) = trow0[x1];
|
||||
else
|
||||
*(drow1 + x1) = trow1[x1];
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)borderValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+621
@@ -0,0 +1,621 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "vtransform.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T, typename WT>
|
||||
struct SubWrap
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec128 & v_src0,
|
||||
const typename internal::VecTraits<T>::vec128 & v_src1,
|
||||
typename internal::VecTraits<T>::vec128 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vsubq(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec64 & v_src0,
|
||||
const typename internal::VecTraits<T>::vec64 & v_src1,
|
||||
typename internal::VecTraits<T>::vec64 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vsub(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const T * src0, const T * src1, T * dst) const
|
||||
{
|
||||
dst[0] = (T)((WT)src0[0] - (WT)src1[0]);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename WT>
|
||||
struct SubSaturate
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec128 & v_src0,
|
||||
const typename internal::VecTraits<T>::vec128 & v_src1,
|
||||
typename internal::VecTraits<T>::vec128 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vqsubq(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const typename internal::VecTraits<T>::vec64 & v_src0,
|
||||
const typename internal::VecTraits<T>::vec64 & v_src1,
|
||||
typename internal::VecTraits<T>::vec64 & v_dst) const
|
||||
{
|
||||
v_dst = internal::vqsub(v_src0, v_src1);
|
||||
}
|
||||
|
||||
void operator() (const T * src0, const T * src1, T * dst) const
|
||||
{
|
||||
dst[0] = internal::saturate_cast<T>((WT)src0[0] - (WT)src1[0]);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
void sub(const Size2D &size,
|
||||
const u8 * src0Base, ptrdiff_t src0Stride,
|
||||
const u8 * src1Base, ptrdiff_t src1Stride,
|
||||
u8 *dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY policy)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
if (policy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
SubSaturate<u8, s16>());
|
||||
}
|
||||
else
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
SubWrap<u8, s16>());
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)policy;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sub(const Size2D &size,
|
||||
const u8 * src0Base, ptrdiff_t src0Stride,
|
||||
const u8 * src1Base, ptrdiff_t src1Stride,
|
||||
s16 *dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
size_t roiw32 = size.width >= 31 ? size.width - 31 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const u8 * src0 = internal::getRowPtr(src0Base, src0Stride, i);
|
||||
const u8 * src1 = internal::getRowPtr(src1Base, src1Stride, i);
|
||||
u16 * dstu16 = internal::getRowPtr((u16 *)dstBase, dstStride, i);
|
||||
s16 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for (; j < roiw32; j += 32)
|
||||
{
|
||||
internal::prefetch(src0 + j);
|
||||
internal::prefetch(src1 + j);
|
||||
uint8x16_t v_src00 = vld1q_u8(src0 + j), v_src01 = vld1q_u8(src0 + j + 16);
|
||||
uint8x16_t v_src10 = vld1q_u8(src1 + j), v_src11 = vld1q_u8(src1 + j + 16);
|
||||
vst1q_u16(dstu16 + j, vsubl_u8(vget_low_u8(v_src00), vget_low_u8(v_src10)));
|
||||
vst1q_u16(dstu16 + j + 8, vsubl_u8(vget_high_u8(v_src00), vget_high_u8(v_src10)));
|
||||
vst1q_u16(dstu16 + j + 16, vsubl_u8(vget_low_u8(v_src01), vget_low_u8(v_src11)));
|
||||
vst1q_u16(dstu16 + j + 24, vsubl_u8(vget_high_u8(v_src01), vget_high_u8(v_src11)));
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
uint8x8_t v_src0 = vld1_u8(src0 + j);
|
||||
uint8x8_t v_src1 = vld1_u8(src1 + j);
|
||||
vst1q_u16(dstu16 + j, vsubl_u8(v_src0, v_src1));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
dst[j] = (s16)src0[j] - (s16)src1[j];
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sub(const Size2D &size,
|
||||
const u8 * src0Base, ptrdiff_t src0Stride,
|
||||
const u8 * src1Base, ptrdiff_t src1Stride,
|
||||
f32 *dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
size_t roiw32 = size.width >= 31 ? size.width - 31 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const u8 * src0 = internal::getRowPtr(src0Base, src0Stride, i);
|
||||
const u8 * src1 = internal::getRowPtr(src1Base, src1Stride, i);
|
||||
f32 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
for (; j < roiw32; j += 32)
|
||||
{
|
||||
internal::prefetch(src0 + j);
|
||||
internal::prefetch(src1 + j);
|
||||
uint8x16_t v_src00 = vld1q_u8(src0 + j), v_src01 = vld1q_u8(src0 + j + 16);
|
||||
uint8x16_t v_src10 = vld1q_u8(src1 + j), v_src11 = vld1q_u8(src1 + j + 16);
|
||||
int16x8_t vsl = vreinterpretq_s16_u16(vsubl_u8( vget_low_u8(v_src00), vget_low_u8(v_src10)));
|
||||
int16x8_t vsh = vreinterpretq_s16_u16(vsubl_u8(vget_high_u8(v_src00), vget_high_u8(v_src10)));
|
||||
|
||||
vst1q_f32(dst + j + 0, vcvtq_f32_s32(vmovl_s16( vget_low_s16(vsl) )));
|
||||
vst1q_f32(dst + j + 4, vcvtq_f32_s32(vmovl_s16( vget_high_s16(vsl) )));
|
||||
vst1q_f32(dst + j + 8, vcvtq_f32_s32(vmovl_s16( vget_low_s16(vsh) )));
|
||||
vst1q_f32(dst + j + 12, vcvtq_f32_s32(vmovl_s16( vget_high_s16(vsh) )));
|
||||
|
||||
vsl = vreinterpretq_s16_u16(vsubl_u8( vget_low_u8(v_src01), vget_low_u8(v_src11)));
|
||||
vsh = vreinterpretq_s16_u16(vsubl_u8(vget_high_u8(v_src01), vget_high_u8(v_src11)));
|
||||
|
||||
vst1q_f32(dst + j + 16, vcvtq_f32_s32(vmovl_s16( vget_low_s16(vsl) )));
|
||||
vst1q_f32(dst + j + 20, vcvtq_f32_s32(vmovl_s16( vget_high_s16(vsl) )));
|
||||
vst1q_f32(dst + j + 24, vcvtq_f32_s32(vmovl_s16( vget_low_s16(vsh) )));
|
||||
vst1q_f32(dst + j + 28, vcvtq_f32_s32(vmovl_s16( vget_high_s16(vsh) )));
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
uint8x8_t v_src0 = vld1_u8(src0 + j);
|
||||
uint8x8_t v_src1 = vld1_u8(src1 + j);
|
||||
|
||||
int16x8_t vs = vreinterpretq_s16_u16(vsubl_u8(v_src0, v_src1));
|
||||
vst1q_f32(dst + j + 0, vcvtq_f32_s32(vmovl_s16( vget_low_s16(vs) )));
|
||||
vst1q_f32(dst + j + 4, vcvtq_f32_s32(vmovl_s16( vget_high_s16(vs) )));
|
||||
}
|
||||
for(; j < size.width; j++)
|
||||
dst[j] = (f32)src0[j] - (f32)src1[j];
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sub(const Size2D &size,
|
||||
const u8 * src0Base, ptrdiff_t src0Stride,
|
||||
const s16 * src1Base, ptrdiff_t src1Stride,
|
||||
s16 *dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY policy)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
size_t roiw16 = size.width >= 15 ? size.width - 15 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const u8 * src0 = internal::getRowPtr(src0Base, src0Stride, i);
|
||||
const s16 * src1 = internal::getRowPtr(src1Base, src1Stride, i);
|
||||
s16 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
if (policy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
for (; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src0 + j);
|
||||
internal::prefetch(src1 + j);
|
||||
uint8x16_t v_src0 = vld1q_u8(src0 + j);
|
||||
int16x8_t v_src00 = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(v_src0)));
|
||||
int16x8_t v_src01 = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(v_src0)));
|
||||
int16x8_t v_src10 = vld1q_s16(src1 + j), v_src11 = vld1q_s16(src1 + j + 8);
|
||||
int16x8_t v_dst0 = vqsubq_s16(v_src00, v_src10);
|
||||
int16x8_t v_dst1 = vqsubq_s16(v_src01, v_src11);
|
||||
vst1q_s16(dst + j, v_dst0);
|
||||
vst1q_s16(dst + j + 8, v_dst1);
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
int16x8_t v_src0 = vreinterpretq_s16_u16(vmovl_u8(vld1_u8(src0 + j)));
|
||||
int16x8_t v_src1 = vld1q_s16(src1 + j);
|
||||
int16x8_t v_dst = vqsubq_s16(v_src0, v_src1);
|
||||
vst1q_s16(dst + j, v_dst);
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
dst[j] = internal::saturate_cast<s16>((s32)src0[j] - (s32)src1[j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src0 + j);
|
||||
internal::prefetch(src1 + j);
|
||||
uint8x16_t v_src0 = vld1q_u8(src0 + j);
|
||||
int16x8_t v_src00 = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(v_src0)));
|
||||
int16x8_t v_src01 = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(v_src0)));
|
||||
int16x8_t v_src10 = vld1q_s16(src1 + j), v_src11 = vld1q_s16(src1 + j + 8);
|
||||
int16x8_t v_dst0 = vsubq_s16(v_src00, v_src10);
|
||||
int16x8_t v_dst1 = vsubq_s16(v_src01, v_src11);
|
||||
vst1q_s16(dst + j, v_dst0);
|
||||
vst1q_s16(dst + j + 8, v_dst1);
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
int16x8_t v_src0 = vreinterpretq_s16_u16(vmovl_u8(vld1_u8(src0 + j)));
|
||||
int16x8_t v_src1 = vld1q_s16(src1 + j);
|
||||
int16x8_t v_dst = vsubq_s16(v_src0, v_src1);
|
||||
vst1q_s16(dst + j, v_dst);
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
dst[j] = (s16)((s32)src0[j] - (s32)src1[j]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)policy;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sub(const Size2D &size,
|
||||
const s16 * src0Base, ptrdiff_t src0Stride,
|
||||
const u8 * src1Base, ptrdiff_t src1Stride,
|
||||
s16 *dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY policy)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
size_t roiw16 = size.width >= 15 ? size.width - 15 : 0;
|
||||
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const s16 * src0 = internal::getRowPtr(src0Base, src0Stride, i);
|
||||
const u8 * src1 = internal::getRowPtr(src1Base, src1Stride, i);
|
||||
s16 * dst = internal::getRowPtr(dstBase, dstStride, i);
|
||||
size_t j = 0;
|
||||
|
||||
if (policy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
for (; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src0 + j);
|
||||
internal::prefetch(src1 + j);
|
||||
int16x8_t v_src00 = vld1q_s16(src0 + j), v_src01 = vld1q_s16(src0 + j + 8);
|
||||
uint8x16_t v_src1 = vld1q_u8(src1 + j);
|
||||
int16x8_t v_src10 = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(v_src1)));
|
||||
int16x8_t v_src11 = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(v_src1)));
|
||||
int16x8_t v_dst0 = vqsubq_s16(v_src00, v_src10);
|
||||
int16x8_t v_dst1 = vqsubq_s16(v_src01, v_src11);
|
||||
vst1q_s16(dst + j, v_dst0);
|
||||
vst1q_s16(dst + j + 8, v_dst1);
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
int16x8_t v_src0 = vld1q_s16(src0 + j);
|
||||
int16x8_t v_src1 = vreinterpretq_s16_u16(vmovl_u8(vld1_u8(src1 + j)));
|
||||
int16x8_t v_dst = vqsubq_s16(v_src0, v_src1);
|
||||
vst1q_s16(dst + j, v_dst);
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
dst[j] = internal::saturate_cast<s16>((s32)src0[j] - (s32)src1[j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; j < roiw16; j += 16)
|
||||
{
|
||||
internal::prefetch(src0 + j);
|
||||
internal::prefetch(src1 + j);
|
||||
int16x8_t v_src00 = vld1q_s16(src0 + j), v_src01 = vld1q_s16(src0 + j + 8);
|
||||
uint8x16_t v_src1 = vld1q_u8(src1 + j);
|
||||
int16x8_t v_src10 = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(v_src1)));
|
||||
int16x8_t v_src11 = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(v_src1)));
|
||||
int16x8_t v_dst0 = vsubq_s16(v_src00, v_src10);
|
||||
int16x8_t v_dst1 = vsubq_s16(v_src01, v_src11);
|
||||
vst1q_s16(dst + j, v_dst0);
|
||||
vst1q_s16(dst + j + 8, v_dst1);
|
||||
}
|
||||
for (; j < roiw8; j += 8)
|
||||
{
|
||||
int16x8_t v_src0 = vld1q_s16(src0 + j);
|
||||
int16x8_t v_src1 = vreinterpretq_s16_u16(vmovl_u8(vld1_u8(src1 + j)));
|
||||
int16x8_t v_dst = vsubq_s16(v_src0, v_src1);
|
||||
vst1q_s16(dst + j, v_dst);
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
dst[j] = (s16)((s32)src0[j] - (s32)src1[j]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)policy;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sub(const Size2D &size,
|
||||
const s8 * src0Base, ptrdiff_t src0Stride,
|
||||
const s8 * src1Base, ptrdiff_t src1Stride,
|
||||
s8 *dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY policy)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
if (policy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
SubSaturate<s8, s16>());
|
||||
}
|
||||
else
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
SubWrap<s8, s16>());
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)policy;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sub(const Size2D &size,
|
||||
const s16 * src0Base, ptrdiff_t src0Stride,
|
||||
const s16 * src1Base, ptrdiff_t src1Stride,
|
||||
s16 *dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY policy)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
if (policy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
SubSaturate<s16, s32>());
|
||||
}
|
||||
else
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
SubWrap<s16, s32>());
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)policy;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sub(const Size2D &size,
|
||||
const u16 * src0Base, ptrdiff_t src0Stride,
|
||||
const u16 * src1Base, ptrdiff_t src1Stride,
|
||||
u16 *dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY policy)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
if (policy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
SubSaturate<u16, s32>());
|
||||
}
|
||||
else
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
SubWrap<u16, s32>());
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)policy;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sub(const Size2D &size,
|
||||
const s32 * src0Base, ptrdiff_t src0Stride,
|
||||
const s32 * src1Base, ptrdiff_t src1Stride,
|
||||
s32 *dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY policy)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
if (policy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
SubSaturate<s32, s64>());
|
||||
}
|
||||
else
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
SubWrap<s32, s64>());
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)policy;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sub(const Size2D &size,
|
||||
const u32 * src0Base, ptrdiff_t src0Stride,
|
||||
const u32 * src1Base, ptrdiff_t src1Stride,
|
||||
u32 *dstBase, ptrdiff_t dstStride,
|
||||
CONVERT_POLICY policy)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
if (policy == CONVERT_POLICY_SATURATE)
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
SubSaturate<u32, s64>());
|
||||
}
|
||||
else
|
||||
{
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
SubWrap<u32, s64>());
|
||||
}
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)policy;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sub(const Size2D &size,
|
||||
const f32 * src0Base, ptrdiff_t src0Stride,
|
||||
const f32 * src1Base, ptrdiff_t src1Stride,
|
||||
f32 *dstBase, ptrdiff_t dstStride)
|
||||
{
|
||||
internal::assertSupportedConfiguration();
|
||||
#ifdef CAROTENE_NEON
|
||||
internal::vtransform(size,
|
||||
src0Base, src0Stride,
|
||||
src1Base, src1Stride,
|
||||
dstBase, dstStride,
|
||||
SubWrap<f32, f32>());
|
||||
#else
|
||||
(void)size;
|
||||
(void)src0Base;
|
||||
(void)src0Stride;
|
||||
(void)src1Base;
|
||||
(void)src1Stride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+385
@@ -0,0 +1,385 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2012-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include "vtransform.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
bool isSumSupported(u32 channels)
|
||||
{
|
||||
return (channels && channels < 5);
|
||||
}
|
||||
|
||||
void sum(const Size2D &_size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
u32 * sumdst, u32 channels)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isSumSupported(channels));
|
||||
#ifdef CAROTENE_NEON
|
||||
Size2D size(_size);
|
||||
if (srcStride == (ptrdiff_t)(size.width))
|
||||
{
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
}
|
||||
const ptrdiff_t width = size.width * channels;
|
||||
|
||||
for(size_t k = 0; k < size.height; ++k)
|
||||
{
|
||||
const u8* src = internal::getRowPtr( srcBase, srcStride, k);
|
||||
ptrdiff_t i = 0;
|
||||
|
||||
if (channels == 3)
|
||||
{
|
||||
uint32x4_t vs1231 = vdupq_n_u32(0);
|
||||
uint32x4_t vs3123 = vdupq_n_u32(0);
|
||||
uint32x4_t vs2312 = vdupq_n_u32(0);
|
||||
for (; i <= width - 257*8*3; i += 257*8*3, src += 257*8*3)
|
||||
{
|
||||
uint16x8_t s1 = vmovl_u8(vld1_u8(src + 0));
|
||||
uint16x8_t s2 = vmovl_u8(vld1_u8(src + 8));
|
||||
uint16x8_t s3 = vmovl_u8(vld1_u8(src + 16));
|
||||
|
||||
for (ptrdiff_t j = 8*3; j < 257*8*3; j+= 8*3)
|
||||
{
|
||||
internal::prefetch(src + j + 24);
|
||||
s1 = vaddw_u8(s1, vld1_u8(src + j + 0));
|
||||
s2 = vaddw_u8(s2, vld1_u8(src + j + 8));
|
||||
s3 = vaddw_u8(s3, vld1_u8(src + j + 16));
|
||||
}
|
||||
|
||||
vs1231 = vqaddq_u32(vs1231, vaddl_u16(vget_low_u16(s1), vget_high_u16(s2)));
|
||||
vs3123 = vqaddq_u32(vs3123, vaddl_u16(vget_low_u16(s2), vget_high_u16(s3)));
|
||||
vs2312 = vqaddq_u32(vs2312, vaddl_u16(vget_low_u16(s3), vget_high_u16(s1)));
|
||||
}
|
||||
if (i <= width - 8*3)
|
||||
{
|
||||
uint16x8_t s1 = vmovl_u8(vld1_u8(src + 0));
|
||||
uint16x8_t s2 = vmovl_u8(vld1_u8(src + 8));
|
||||
uint16x8_t s3 = vmovl_u8(vld1_u8(src + 16));
|
||||
|
||||
for (i += 8*3, src += 8*3; i <= width - 8*3; i += 8*3, src += 8*3)
|
||||
{
|
||||
internal::prefetch(src + 24);
|
||||
s1 = vaddw_u8(s1, vld1_u8(src + 0));
|
||||
s2 = vaddw_u8(s2, vld1_u8(src + 8));
|
||||
s3 = vaddw_u8(s3, vld1_u8(src + 16));
|
||||
}
|
||||
|
||||
vs1231 = vqaddq_u32(vs1231, vaddl_u16(vget_low_u16(s1), vget_high_u16(s2)));
|
||||
vs3123 = vqaddq_u32(vs3123, vaddl_u16(vget_low_u16(s2), vget_high_u16(s3)));
|
||||
vs2312 = vqaddq_u32(vs2312, vaddl_u16(vget_low_u16(s3), vget_high_u16(s1)));
|
||||
}
|
||||
|
||||
u32 sum[12];
|
||||
vst1q_u32(sum+0, vs1231);
|
||||
vst1q_u32(sum+4, vs2312);
|
||||
vst1q_u32(sum+8, vs3123);
|
||||
|
||||
for (; i < width; i += 3, src += 3)
|
||||
{
|
||||
sumdst[0] += src[0];
|
||||
sumdst[1] += src[1];
|
||||
sumdst[2] += src[2];
|
||||
}
|
||||
|
||||
sumdst[0] += sum[0] + sum[3] + sum[6] + sum[9];
|
||||
sumdst[1] += sum[1] + sum[4] + sum[7] + sum[10];
|
||||
sumdst[2] += sum[2] + sum[5] + sum[8] + sum[11];
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32x4_t vs = vdupq_n_u32(0);
|
||||
for (; i <= width - 257*8; i += 257*8, src += 257 * 8)
|
||||
{
|
||||
uint16x8_t s1 = vmovl_u8(vld1_u8(src));
|
||||
|
||||
for (int j = 8; j < 257 * 8; j += 8)
|
||||
{
|
||||
internal::prefetch(src + j);
|
||||
s1 = vaddw_u8(s1, vld1_u8(src + j));
|
||||
}
|
||||
|
||||
vs = vqaddq_u32(vs, vaddl_u16(vget_low_u16(s1), vget_high_u16(s1)));
|
||||
}
|
||||
if (i < width - 7)
|
||||
{
|
||||
uint16x8_t s1 = vmovl_u8(vld1_u8(src));
|
||||
|
||||
for(i+=8,src+=8; i < width-7; i+=8,src+=8)
|
||||
{
|
||||
internal::prefetch(src);
|
||||
s1 = vaddw_u8(s1, vld1_u8(src));
|
||||
}
|
||||
vs = vqaddq_u32(vs, vaddl_u16(vget_low_u16(s1), vget_high_u16(s1)));
|
||||
}
|
||||
|
||||
if (channels == 1)
|
||||
{
|
||||
uint32x2_t vs2 = vqadd_u32(vget_low_u32(vs), vget_high_u32(vs));
|
||||
uint32x2_t vs1 = vreinterpret_u32_u64(vpaddl_u32(vs2));
|
||||
|
||||
u32 s0 = vget_lane_u32(vs1, 0);
|
||||
for(; i < width; ++i,++src)
|
||||
s0 += src[0];
|
||||
sumdst[0] += s0;
|
||||
}
|
||||
else if (channels == 4)
|
||||
{
|
||||
vst1q_u32(sumdst, vqaddq_u32(vs, vld1q_u32(sumdst)));
|
||||
|
||||
for(; i < width; i+=4,src+=4)
|
||||
{
|
||||
sumdst[0] += src[0];
|
||||
sumdst[1] += src[1];
|
||||
sumdst[2] += src[2];
|
||||
sumdst[3] += src[3];
|
||||
}
|
||||
}
|
||||
else//if (channels == 2)
|
||||
{
|
||||
uint32x2_t vs2 = vqadd_u32(vget_low_u32(vs), vget_high_u32(vs));
|
||||
vst1_u32(sumdst, vqadd_u32(vs2, vld1_u32(sumdst)));
|
||||
|
||||
for(; i < width; i+=2,src+=2)
|
||||
{
|
||||
sumdst[0] += src[0];
|
||||
sumdst[1] += src[1];
|
||||
}
|
||||
}
|
||||
}//channels != 3
|
||||
}
|
||||
#else
|
||||
(void)_size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)sumdst;
|
||||
(void)channels;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sum(const Size2D &_size,
|
||||
const f32 * srcBase, ptrdiff_t srcStride,
|
||||
f64 * sumdst, u32 channels)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isSumSupported(channels));
|
||||
#ifdef CAROTENE_NEON
|
||||
Size2D size(_size);
|
||||
if (srcStride == (ptrdiff_t)(size.width))
|
||||
{
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
}
|
||||
const ptrdiff_t width = size.width * channels;
|
||||
|
||||
for(size_t k = 0; k < size.height; ++k)
|
||||
{
|
||||
const f32* src = internal::getRowPtr( srcBase, srcStride, k);
|
||||
ptrdiff_t i = 0;
|
||||
|
||||
if (channels == 3)
|
||||
{
|
||||
float32x4_t vs1231 = vdupq_n_f32(0);
|
||||
float32x4_t vs2312 = vdupq_n_f32(0);
|
||||
float32x4_t vs3123 = vdupq_n_f32(0);
|
||||
for(; i <= width-12; i += 12)
|
||||
{
|
||||
internal::prefetch(src + i + 12);
|
||||
vs1231 = vaddq_f32(vs1231, vld1q_f32(src + i + 0));
|
||||
vs2312 = vaddq_f32(vs2312, vld1q_f32(src + i + 4));
|
||||
vs3123 = vaddq_f32(vs3123, vld1q_f32(src + i + 8));
|
||||
}
|
||||
|
||||
f32 s[12];
|
||||
vst1q_f32(s + 0, vs1231);
|
||||
vst1q_f32(s + 4, vs2312);
|
||||
vst1q_f32(s + 8, vs3123);
|
||||
|
||||
sumdst[0] += s[0] + s[3] + s[6] + s[9];
|
||||
sumdst[1] += s[1] + s[4] + s[7] + s[10];
|
||||
sumdst[2] += s[2] + s[5] + s[8] + s[11];
|
||||
for( ; i < width; i+=3)
|
||||
{
|
||||
sumdst[0] += src[i];
|
||||
sumdst[1] += src[i+1];
|
||||
sumdst[2] += src[i+2];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float32x4_t vs = vdupq_n_f32(0);
|
||||
for(; i <= width-4; i += 4)
|
||||
{
|
||||
internal::prefetch(src + i);
|
||||
vs = vaddq_f32(vs, vld1q_f32(src+i));
|
||||
}
|
||||
|
||||
if (channels == 1)
|
||||
{
|
||||
float32x2_t vs2 = vpadd_f32(vget_low_f32(vs), vget_high_f32(vs));
|
||||
f32 s[2];
|
||||
vst1_f32(s, vs2);
|
||||
|
||||
sumdst[0] += s[0] + s[1];
|
||||
for( ; i < width; i++)
|
||||
sumdst[0] += src[i];
|
||||
}
|
||||
else if (channels == 4)
|
||||
{
|
||||
f32 s[4];
|
||||
vst1q_f32(s, vs);
|
||||
|
||||
sumdst[0] += s[0];
|
||||
sumdst[1] += s[1];
|
||||
sumdst[2] += s[2];
|
||||
sumdst[3] += s[3];
|
||||
}
|
||||
else//if (channels == 2)
|
||||
{
|
||||
float32x2_t vs2 = vadd_f32(vget_low_f32(vs), vget_high_f32(vs));
|
||||
f32 s[2];
|
||||
vst1_f32(s, vs2);
|
||||
|
||||
sumdst[0] += s[0];
|
||||
sumdst[1] += s[1];
|
||||
|
||||
if(i < width)
|
||||
{
|
||||
sumdst[0] += src[i];
|
||||
sumdst[1] += src[i+1];
|
||||
}
|
||||
}
|
||||
}//channels != 3
|
||||
}
|
||||
#else
|
||||
(void)_size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)sumdst;
|
||||
(void)channels;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isSqsumSupported(u32 channels)
|
||||
{
|
||||
return (channels && ((4/channels)*channels == 4));
|
||||
}
|
||||
|
||||
void sqsum(const Size2D &_size,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
f64 * sumdst, f64 * sqsumdst, u32 channels)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isSqsumSupported(channels));
|
||||
#ifdef CAROTENE_NEON
|
||||
Size2D size(_size);
|
||||
if (srcStride == (ptrdiff_t)(size.width*channels))
|
||||
{
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
}
|
||||
const size_t width = size.width * channels;
|
||||
|
||||
size_t blockSize0 = 1 << 23;
|
||||
size_t roiw8 = width & ~7;
|
||||
|
||||
uint32x4_t v_zero = vdupq_n_u32(0u);
|
||||
|
||||
for (size_t i = 0; i < size.height; ++i)
|
||||
{
|
||||
const u8 * src = internal::getRowPtr(srcBase, srcStride, i);
|
||||
size_t j = 0u;
|
||||
|
||||
while (j < roiw8)
|
||||
{
|
||||
size_t blockSize = std::min(roiw8 - j, blockSize0) + j;
|
||||
uint32x4_t v_sum = v_zero;
|
||||
uint32x4_t v_sqsum = v_zero;
|
||||
|
||||
for ( ; j < blockSize ; j += 8, src += 8)
|
||||
{
|
||||
internal::prefetch(src);
|
||||
uint8x8_t v_src0 = vld1_u8(src);
|
||||
|
||||
uint16x8_t v_src = vmovl_u8(v_src0);
|
||||
uint16x4_t v_srclo = vget_low_u16(v_src), v_srchi = vget_high_u16(v_src);
|
||||
v_sum = vaddq_u32(v_sum, vaddl_u16(v_srclo, v_srchi));
|
||||
v_sqsum = vmlal_u16(v_sqsum, v_srclo, v_srclo);
|
||||
v_sqsum = vmlal_u16(v_sqsum, v_srchi, v_srchi);
|
||||
}
|
||||
|
||||
u32 arsum[8];
|
||||
vst1q_u32(arsum, v_sum);
|
||||
vst1q_u32(arsum + 4, v_sqsum);
|
||||
|
||||
sumdst[0] += (f64)arsum[0];
|
||||
sumdst[1 % channels] += (f64)arsum[1];
|
||||
sumdst[2 % channels] += (f64)arsum[2];
|
||||
sumdst[3 % channels] += (f64)arsum[3];
|
||||
sqsumdst[0] += (f64)arsum[4];
|
||||
sqsumdst[1 % channels] += (f64)arsum[5];
|
||||
sqsumdst[2 % channels] += (f64)arsum[6];
|
||||
sqsumdst[3 % channels] += (f64)arsum[7];
|
||||
}
|
||||
// collect a few last elements in the current row
|
||||
// it's ok to process channels elements per step
|
||||
// since we could handle 1,2 or 4 channels
|
||||
// we always have channels-fold amount of elements remaining
|
||||
for ( ; j < width; j+=channels, src+=channels)
|
||||
{
|
||||
for (u32 kk = 0; kk < channels; kk++)
|
||||
{
|
||||
u32 srcval = src[kk];
|
||||
sumdst[kk] += srcval;
|
||||
sqsumdst[kk] += srcval * srcval;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)_size;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)sumdst;
|
||||
(void)sqsumdst;
|
||||
(void)channels;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2013-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
#define ENABLE4LINESMATCHING false //Disabled since overall time for simultaneous 4 lines matching is greater than
|
||||
//time for simultaneous 2 lines matching for the same amount of data
|
||||
|
||||
bool isMatchTemplateSupported(const Size2D &tmplSize)
|
||||
{
|
||||
return isSupportedConfiguration() &&
|
||||
tmplSize.width >= 8 && // Actually the function could process even shorter templates
|
||||
// but there will be no NEON optimization in this case
|
||||
(tmplSize.width * tmplSize.height) <= 256;
|
||||
}
|
||||
|
||||
void matchTemplate(const Size2D &srcSize,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
const Size2D &tmplSize,
|
||||
const u8 * tmplBase, ptrdiff_t tmplStride,
|
||||
f32 * dstBase, ptrdiff_t dstStride,
|
||||
bool normalize)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isMatchTemplateSupported(tmplSize));
|
||||
#ifdef CAROTENE_NEON
|
||||
const size_t tmplW = tmplSize.width;
|
||||
const size_t tmplH = tmplSize.height;
|
||||
const size_t dstW = srcSize.width - tmplSize.width + 1;
|
||||
const size_t dstH = srcSize.height - tmplSize.height + 1;
|
||||
|
||||
//template correlation part
|
||||
{
|
||||
#if ENABLE4LINESMATCHING
|
||||
const size_t dstroiw4 = dstW & ~3u;
|
||||
#endif
|
||||
const size_t dstroiw2 = dstW & ~1u;
|
||||
const size_t tmplroiw = tmplW & ~7u;
|
||||
const size_t dstride = dstStride >> 2;
|
||||
|
||||
f32 *corr = dstBase;
|
||||
const u8 *imgrrow = srcBase;
|
||||
for(size_t r = 0; r < dstH; ++r, corr+=dstride, imgrrow+=srcStride)
|
||||
{
|
||||
size_t c = 0;
|
||||
#if ENABLE4LINESMATCHING
|
||||
for(; c < dstroiw4; c+=4)
|
||||
{
|
||||
u32 dot[4] = {0, 0, 0, 0};
|
||||
uint32x4_t vdot0 = vmovq_n_u32(0);
|
||||
uint32x4_t vdot1 = vmovq_n_u32(0);
|
||||
uint32x4_t vdot2 = vmovq_n_u32(0);
|
||||
uint32x4_t vdot3 = vmovq_n_u32(0);
|
||||
|
||||
const u8 *img = imgrrow;
|
||||
const u8 *tmpl = tmplBase;
|
||||
for(size_t i = 0; i < tmplH; ++i, tmpl+=tmplStride, img+=srcStride)
|
||||
{
|
||||
size_t j = 0;
|
||||
for(; j < tmplroiw; j+=8)
|
||||
{
|
||||
uint8x8_t vtmpl = vld1_u8(tmpl + j);
|
||||
|
||||
uint8x8_t vimg0 = vld1_u8(img + j + c + 0);
|
||||
uint8x8_t vimg1 = vld1_u8(img + j + c + 1);
|
||||
uint8x8_t vimg2 = vld1_u8(img + j + c + 2);
|
||||
uint8x8_t vimg3 = vld1_u8(img + j + c + 3);
|
||||
|
||||
uint16x8_t vd0 = vmull_u8(vtmpl, vimg0);
|
||||
uint16x8_t vd1 = vmull_u8(vtmpl, vimg1);
|
||||
uint16x8_t vd2 = vmull_u8(vtmpl, vimg2);
|
||||
uint16x8_t vd3 = vmull_u8(vtmpl, vimg3);
|
||||
|
||||
vdot0 = vpadalq_u16(vdot0, vd0);
|
||||
vdot1 = vpadalq_u16(vdot1, vd1);
|
||||
vdot2 = vpadalq_u16(vdot2, vd2);
|
||||
vdot3 = vpadalq_u16(vdot3, vd3);
|
||||
}
|
||||
for(; j < tmplW; ++j)
|
||||
{
|
||||
dot[0] += tmpl[j] * img[j + c + 0];
|
||||
dot[1] += tmpl[j] * img[j + c + 1];
|
||||
dot[2] += tmpl[j] * img[j + c + 2];
|
||||
dot[3] += tmpl[j] * img[j + c + 3];
|
||||
}
|
||||
}
|
||||
uint32x4_t vdotx = vld1q_u32(dot);
|
||||
uint32x2_t vdot_0 = vpadd_u32(vget_low_u32(vdot0), vget_high_u32(vdot0));
|
||||
uint32x2_t vdot_1 = vpadd_u32(vget_low_u32(vdot1), vget_high_u32(vdot1));
|
||||
uint32x2_t vdot_2 = vpadd_u32(vget_low_u32(vdot2), vget_high_u32(vdot2));
|
||||
uint32x2_t vdot_3 = vpadd_u32(vget_low_u32(vdot3), vget_high_u32(vdot3));
|
||||
uint32x2_t vdot_01 = vpadd_u32(vdot_0, vdot_1);
|
||||
uint32x2_t vdot_23 = vpadd_u32(vdot_2, vdot_3);
|
||||
|
||||
vst1q_f32(corr + c, vcvtq_f32_u32(vaddq_u32(vdotx, vcombine_u32(vdot_01, vdot_23))));
|
||||
}
|
||||
#endif
|
||||
|
||||
for(; c < dstroiw2; c+=2)
|
||||
{
|
||||
u32 dot[2] = {0, 0};
|
||||
uint32x4_t vdot0 = vmovq_n_u32(0);
|
||||
uint32x4_t vdot1 = vmovq_n_u32(0);
|
||||
const u8 *img = imgrrow;
|
||||
const u8 *tmpl = tmplBase;
|
||||
for(size_t i = 0; i < tmplH; ++i, tmpl+=tmplStride, img+=srcStride)
|
||||
{
|
||||
size_t j = 0;
|
||||
for(; j < tmplroiw; j+=8)
|
||||
{
|
||||
uint8x8_t vtmpl = vld1_u8(tmpl + j);
|
||||
|
||||
uint8x8_t vimg0 = vld1_u8(img + j + c + 0);
|
||||
uint8x8_t vimg1 = vld1_u8(img + j + c + 1);
|
||||
|
||||
uint16x8_t vd0 = vmull_u8(vtmpl, vimg0);
|
||||
uint16x8_t vd1 = vmull_u8(vtmpl, vimg1);
|
||||
|
||||
vdot0 = vpadalq_u16(vdot0, vd0);
|
||||
vdot1 = vpadalq_u16(vdot1, vd1);
|
||||
}
|
||||
for(; j < tmplW; ++j)
|
||||
{
|
||||
dot[0] += tmpl[j] * img[j + c + 0];
|
||||
dot[1] += tmpl[j] * img[j + c + 1];
|
||||
}
|
||||
}
|
||||
uint32x2_t vdotx = vld1_u32(dot);
|
||||
uint32x2_t vdot_0 = vpadd_u32(vget_low_u32(vdot0), vget_high_u32(vdot0));
|
||||
uint32x2_t vdot_1 = vpadd_u32(vget_low_u32(vdot1), vget_high_u32(vdot1));
|
||||
uint32x2_t vdot_ = vpadd_u32(vdot_0, vdot_1);
|
||||
vst1_f32(corr + c, vcvt_f32_u32(vadd_u32(vdotx, vdot_)));
|
||||
}
|
||||
|
||||
for(; c < dstW; ++c)
|
||||
{
|
||||
u32 dot = 0;
|
||||
uint32x4_t vdot = vmovq_n_u32(0);
|
||||
const u8 *img = imgrrow;
|
||||
const u8 *tmpl = tmplBase;
|
||||
for(size_t i = 0; i < tmplH; ++i, tmpl+=tmplStride, img+=srcStride)
|
||||
{
|
||||
size_t j = 0;
|
||||
for(; j < tmplroiw; j+=8)
|
||||
{
|
||||
uint8x8_t vtmpl = vld1_u8(tmpl + j);
|
||||
uint8x8_t vimg = vld1_u8(img + j + c);
|
||||
uint16x8_t vd = vmull_u8(vtmpl, vimg);
|
||||
vdot = vpadalq_u16(vdot, vd);
|
||||
}
|
||||
for(; j < tmplW; ++j)
|
||||
dot += tmpl[j] * img[j + c];
|
||||
}
|
||||
u32 wdot[2];
|
||||
vst1_u32(wdot, vpadd_u32(vget_low_u32(vdot), vget_high_u32(vdot)));
|
||||
dot += wdot[0] + wdot[1];
|
||||
corr[c] = (f32)dot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(normalize)
|
||||
{
|
||||
f32 tn = std::sqrt((f32)normL2(tmplSize, tmplBase, tmplStride));
|
||||
|
||||
size_t iw = srcSize.width+1;
|
||||
size_t ih = srcSize.height+1;
|
||||
std::vector<f64> _sqsum(iw*ih);
|
||||
f64 *sqsum = &_sqsum[0];
|
||||
memset(sqsum, 0, iw*sizeof(f64));
|
||||
for(size_t i = 1; i < ih; ++i)
|
||||
sqsum[iw*i] = 0.;
|
||||
sqrIntegral(srcSize, srcBase, srcStride, sqsum + iw + 1, iw*sizeof(f64));
|
||||
|
||||
for(size_t i = 0; i < dstH; ++i)
|
||||
{
|
||||
f32 *result = internal::getRowPtr(dstBase, dstStride, i);
|
||||
for(size_t j = 0; j < dstW; ++j)
|
||||
{
|
||||
double s2 = sqsum[iw*i + j] +
|
||||
sqsum[iw*(i + tmplSize.height) + j + tmplSize.width] -
|
||||
sqsum[iw*(i + tmplSize.height) + j] -
|
||||
sqsum[iw*i + j + tmplSize.width];
|
||||
|
||||
result[j] /= tn * std::sqrt(s2);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)srcSize;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)tmplBase;
|
||||
(void)tmplStride;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)normalize;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
Vendored
+1627
File diff suppressed because it is too large
Load Diff
Vendored
+689
@@ -0,0 +1,689 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2014-2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#ifndef CAROTENE_SRC_VTRANSFORM_HPP
|
||||
#define CAROTENE_SRC_VTRANSFORM_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <carotene/types.hpp>
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
namespace CAROTENE_NS { namespace internal {
|
||||
|
||||
////////////////////////////// Type Traits ///////////////////////
|
||||
|
||||
template <typename T, int cn = 1>
|
||||
struct VecTraits;
|
||||
|
||||
template <> struct VecTraits< u8, 1> { typedef uint8x16_t vec128; typedef uint8x8_t vec64; typedef VecTraits< u8, 1> unsign; };
|
||||
template <> struct VecTraits< s8, 1> { typedef int8x16_t vec128; typedef int8x8_t vec64; typedef VecTraits< u8, 1> unsign; };
|
||||
template <> struct VecTraits<u16, 1> { typedef uint16x8_t vec128; typedef uint16x4_t vec64; typedef VecTraits< u16, 1> unsign; };
|
||||
template <> struct VecTraits<s16, 1> { typedef int16x8_t vec128; typedef int16x4_t vec64; typedef VecTraits< u16, 1> unsign; };
|
||||
template <> struct VecTraits<s32, 1> { typedef int32x4_t vec128; typedef int32x2_t vec64; typedef VecTraits< u32, 1> unsign; };
|
||||
template <> struct VecTraits<u32, 1> { typedef uint32x4_t vec128; typedef uint32x2_t vec64; typedef VecTraits< u32, 1> unsign; };
|
||||
template <> struct VecTraits<s64, 1> { typedef int64x2_t vec128; typedef int64x1_t vec64; typedef VecTraits< u64, 1> unsign; };
|
||||
template <> struct VecTraits<u64, 1> { typedef uint64x2_t vec128; typedef uint64x1_t vec64; typedef VecTraits< u64, 1> unsign; };
|
||||
template <> struct VecTraits<f32, 1> { typedef float32x4_t vec128; typedef float32x2_t vec64; typedef VecTraits< u32, 1> unsign; };
|
||||
|
||||
template <> struct VecTraits< u8, 2> { typedef uint8x16x2_t vec128; typedef uint8x8x2_t vec64; typedef VecTraits< u8, 2> unsign; };
|
||||
template <> struct VecTraits< s8, 2> { typedef int8x16x2_t vec128; typedef int8x8x2_t vec64; typedef VecTraits< u8, 2> unsign; };
|
||||
template <> struct VecTraits<u16, 2> { typedef uint16x8x2_t vec128; typedef uint16x4x2_t vec64; typedef VecTraits< u16, 2> unsign; };
|
||||
template <> struct VecTraits<s16, 2> { typedef int16x8x2_t vec128; typedef int16x4x2_t vec64; typedef VecTraits< u16, 2> unsign; };
|
||||
template <> struct VecTraits<s32, 2> { typedef int32x4x2_t vec128; typedef int32x2x2_t vec64; typedef VecTraits< u32, 2> unsign; };
|
||||
template <> struct VecTraits<u32, 2> { typedef uint32x4x2_t vec128; typedef uint32x2x2_t vec64; typedef VecTraits< u32, 2> unsign; };
|
||||
template <> struct VecTraits<s64, 2> { typedef int64x2x2_t vec128; typedef int64x1x2_t vec64; typedef VecTraits< u64, 2> unsign; };
|
||||
template <> struct VecTraits<u64, 2> { typedef uint64x2x2_t vec128; typedef uint64x1x2_t vec64; typedef VecTraits< u64, 2> unsign; };
|
||||
template <> struct VecTraits<f32, 2> { typedef float32x4x2_t vec128; typedef float32x2x2_t vec64; typedef VecTraits< u32, 2> unsign; };
|
||||
|
||||
template <> struct VecTraits< u8, 3> { typedef uint8x16x3_t vec128; typedef uint8x8x3_t vec64; typedef VecTraits< u8, 3> unsign; };
|
||||
template <> struct VecTraits< s8, 3> { typedef int8x16x3_t vec128; typedef int8x8x3_t vec64; typedef VecTraits< u8, 3> unsign; };
|
||||
template <> struct VecTraits<u16, 3> { typedef uint16x8x3_t vec128; typedef uint16x4x3_t vec64; typedef VecTraits< u16, 3> unsign; };
|
||||
template <> struct VecTraits<s16, 3> { typedef int16x8x3_t vec128; typedef int16x4x3_t vec64; typedef VecTraits< u16, 3> unsign; };
|
||||
template <> struct VecTraits<s32, 3> { typedef int32x4x3_t vec128; typedef int32x2x3_t vec64; typedef VecTraits< u32, 3> unsign; };
|
||||
template <> struct VecTraits<u32, 3> { typedef uint32x4x3_t vec128; typedef uint32x2x3_t vec64; typedef VecTraits< u32, 3> unsign; };
|
||||
template <> struct VecTraits<s64, 3> { typedef int64x2x3_t vec128; typedef int64x1x3_t vec64; typedef VecTraits< u64, 2> unsign; };
|
||||
template <> struct VecTraits<u64, 3> { typedef uint64x2x3_t vec128; typedef uint64x1x3_t vec64; typedef VecTraits< u64, 2> unsign; };
|
||||
template <> struct VecTraits<f32, 3> { typedef float32x4x3_t vec128; typedef float32x2x3_t vec64; typedef VecTraits< u32, 3> unsign; };
|
||||
|
||||
template <> struct VecTraits< u8, 4> { typedef uint8x16x4_t vec128; typedef uint8x8x4_t vec64; typedef VecTraits< u8, 3> unsign; };
|
||||
template <> struct VecTraits< s8, 4> { typedef int8x16x4_t vec128; typedef int8x8x4_t vec64; typedef VecTraits< u8, 3> unsign; };
|
||||
template <> struct VecTraits<u16, 4> { typedef uint16x8x4_t vec128; typedef uint16x4x4_t vec64; typedef VecTraits< u16, 3> unsign; };
|
||||
template <> struct VecTraits<s16, 4> { typedef int16x8x4_t vec128; typedef int16x4x4_t vec64; typedef VecTraits< u16, 3> unsign; };
|
||||
template <> struct VecTraits<s32, 4> { typedef int32x4x4_t vec128; typedef int32x2x4_t vec64; typedef VecTraits< u32, 3> unsign; };
|
||||
template <> struct VecTraits<u32, 4> { typedef uint32x4x4_t vec128; typedef uint32x2x4_t vec64; typedef VecTraits< u32, 3> unsign; };
|
||||
template <> struct VecTraits<s64, 4> { typedef int64x2x4_t vec128; typedef int64x1x4_t vec64; typedef VecTraits< u64, 2> unsign; };
|
||||
template <> struct VecTraits<u64, 4> { typedef uint64x2x4_t vec128; typedef uint64x1x4_t vec64; typedef VecTraits< u64, 2> unsign; };
|
||||
template <> struct VecTraits<f32, 4> { typedef float32x4x4_t vec128; typedef float32x2x4_t vec64; typedef VecTraits< u32, 3> unsign; };
|
||||
|
||||
////////////////////////////// vld1q ///////////////////////
|
||||
|
||||
inline uint8x16_t vld1q(const u8 * ptr) { return vld1q_u8(ptr); }
|
||||
inline int8x16_t vld1q(const s8 * ptr) { return vld1q_s8(ptr); }
|
||||
inline uint16x8_t vld1q(const u16 * ptr) { return vld1q_u16(ptr); }
|
||||
inline int16x8_t vld1q(const s16 * ptr) { return vld1q_s16(ptr); }
|
||||
inline uint32x4_t vld1q(const u32 * ptr) { return vld1q_u32(ptr); }
|
||||
inline int32x4_t vld1q(const s32 * ptr) { return vld1q_s32(ptr); }
|
||||
inline float32x4_t vld1q(const f32 * ptr) { return vld1q_f32(ptr); }
|
||||
|
||||
////////////////////////////// vld1 ///////////////////////
|
||||
|
||||
inline uint8x8_t vld1(const u8 * ptr) { return vld1_u8(ptr); }
|
||||
inline int8x8_t vld1(const s8 * ptr) { return vld1_s8(ptr); }
|
||||
inline uint16x4_t vld1(const u16 * ptr) { return vld1_u16(ptr); }
|
||||
inline int16x4_t vld1(const s16 * ptr) { return vld1_s16(ptr); }
|
||||
inline uint32x2_t vld1(const u32 * ptr) { return vld1_u32(ptr); }
|
||||
inline int32x2_t vld1(const s32 * ptr) { return vld1_s32(ptr); }
|
||||
inline float32x2_t vld1(const f32 * ptr) { return vld1_f32(ptr); }
|
||||
|
||||
////////////////////////////// vld2q ///////////////////////
|
||||
|
||||
inline uint8x16x2_t vld2q(const u8 * ptr) { return vld2q_u8(ptr); }
|
||||
inline int8x16x2_t vld2q(const s8 * ptr) { return vld2q_s8(ptr); }
|
||||
inline uint16x8x2_t vld2q(const u16 * ptr) { return vld2q_u16(ptr); }
|
||||
inline int16x8x2_t vld2q(const s16 * ptr) { return vld2q_s16(ptr); }
|
||||
inline uint32x4x2_t vld2q(const u32 * ptr) { return vld2q_u32(ptr); }
|
||||
inline int32x4x2_t vld2q(const s32 * ptr) { return vld2q_s32(ptr); }
|
||||
inline float32x4x2_t vld2q(const f32 * ptr) { return vld2q_f32(ptr); }
|
||||
|
||||
////////////////////////////// vld2 ///////////////////////
|
||||
|
||||
inline uint8x8x2_t vld2(const u8 * ptr) { return vld2_u8(ptr); }
|
||||
inline int8x8x2_t vld2(const s8 * ptr) { return vld2_s8(ptr); }
|
||||
inline uint16x4x2_t vld2(const u16 * ptr) { return vld2_u16(ptr); }
|
||||
inline int16x4x2_t vld2(const s16 * ptr) { return vld2_s16(ptr); }
|
||||
inline uint32x2x2_t vld2(const u32 * ptr) { return vld2_u32(ptr); }
|
||||
inline int32x2x2_t vld2(const s32 * ptr) { return vld2_s32(ptr); }
|
||||
inline float32x2x2_t vld2(const f32 * ptr) { return vld2_f32(ptr); }
|
||||
|
||||
////////////////////////////// vld3q ///////////////////////
|
||||
|
||||
inline uint8x16x3_t vld3q(const u8 * ptr) { return vld3q_u8(ptr); }
|
||||
inline int8x16x3_t vld3q(const s8 * ptr) { return vld3q_s8(ptr); }
|
||||
inline uint16x8x3_t vld3q(const u16 * ptr) { return vld3q_u16(ptr); }
|
||||
inline int16x8x3_t vld3q(const s16 * ptr) { return vld3q_s16(ptr); }
|
||||
inline uint32x4x3_t vld3q(const u32 * ptr) { return vld3q_u32(ptr); }
|
||||
inline int32x4x3_t vld3q(const s32 * ptr) { return vld3q_s32(ptr); }
|
||||
inline float32x4x3_t vld3q(const f32 * ptr) { return vld3q_f32(ptr); }
|
||||
|
||||
////////////////////////////// vld3 ///////////////////////
|
||||
|
||||
inline uint8x8x3_t vld3(const u8 * ptr) { return vld3_u8(ptr); }
|
||||
inline int8x8x3_t vld3(const s8 * ptr) { return vld3_s8(ptr); }
|
||||
inline uint16x4x3_t vld3(const u16 * ptr) { return vld3_u16(ptr); }
|
||||
inline int16x4x3_t vld3(const s16 * ptr) { return vld3_s16(ptr); }
|
||||
inline uint32x2x3_t vld3(const u32 * ptr) { return vld3_u32(ptr); }
|
||||
inline int32x2x3_t vld3(const s32 * ptr) { return vld3_s32(ptr); }
|
||||
inline float32x2x3_t vld3(const f32 * ptr) { return vld3_f32(ptr); }
|
||||
|
||||
////////////////////////////// vld4q ///////////////////////
|
||||
|
||||
inline uint8x16x4_t vld4q(const u8 * ptr) { return vld4q_u8(ptr); }
|
||||
inline int8x16x4_t vld4q(const s8 * ptr) { return vld4q_s8(ptr); }
|
||||
inline uint16x8x4_t vld4q(const u16 * ptr) { return vld4q_u16(ptr); }
|
||||
inline int16x8x4_t vld4q(const s16 * ptr) { return vld4q_s16(ptr); }
|
||||
inline uint32x4x4_t vld4q(const u32 * ptr) { return vld4q_u32(ptr); }
|
||||
inline int32x4x4_t vld4q(const s32 * ptr) { return vld4q_s32(ptr); }
|
||||
inline float32x4x4_t vld4q(const f32 * ptr) { return vld4q_f32(ptr); }
|
||||
|
||||
////////////////////////////// vld4 ///////////////////////
|
||||
|
||||
inline uint8x8x4_t vld4(const u8 * ptr) { return vld4_u8(ptr); }
|
||||
inline int8x8x4_t vld4(const s8 * ptr) { return vld4_s8(ptr); }
|
||||
inline uint16x4x4_t vld4(const u16 * ptr) { return vld4_u16(ptr); }
|
||||
inline int16x4x4_t vld4(const s16 * ptr) { return vld4_s16(ptr); }
|
||||
inline uint32x2x4_t vld4(const u32 * ptr) { return vld4_u32(ptr); }
|
||||
inline int32x2x4_t vld4(const s32 * ptr) { return vld4_s32(ptr); }
|
||||
inline float32x2x4_t vld4(const f32 * ptr) { return vld4_f32(ptr); }
|
||||
|
||||
////////////////////////////// vst1q ///////////////////////
|
||||
|
||||
inline void vst1q(u8 * ptr, const uint8x16_t & v) { return vst1q_u8(ptr, v); }
|
||||
inline void vst1q(s8 * ptr, const int8x16_t & v) { return vst1q_s8(ptr, v); }
|
||||
inline void vst1q(u16 * ptr, const uint16x8_t & v) { return vst1q_u16(ptr, v); }
|
||||
inline void vst1q(s16 * ptr, const int16x8_t & v) { return vst1q_s16(ptr, v); }
|
||||
inline void vst1q(u32 * ptr, const uint32x4_t & v) { return vst1q_u32(ptr, v); }
|
||||
inline void vst1q(s32 * ptr, const int32x4_t & v) { return vst1q_s32(ptr, v); }
|
||||
inline void vst1q(f32 * ptr, const float32x4_t & v) { return vst1q_f32(ptr, v); }
|
||||
|
||||
////////////////////////////// vst1 ///////////////////////
|
||||
|
||||
inline void vst1(u8 * ptr, const uint8x8_t & v) { return vst1_u8(ptr, v); }
|
||||
inline void vst1(s8 * ptr, const int8x8_t & v) { return vst1_s8(ptr, v); }
|
||||
inline void vst1(u16 * ptr, const uint16x4_t & v) { return vst1_u16(ptr, v); }
|
||||
inline void vst1(s16 * ptr, const int16x4_t & v) { return vst1_s16(ptr, v); }
|
||||
inline void vst1(u32 * ptr, const uint32x2_t & v) { return vst1_u32(ptr, v); }
|
||||
inline void vst1(s32 * ptr, const int32x2_t & v) { return vst1_s32(ptr, v); }
|
||||
inline void vst1(f32 * ptr, const float32x2_t & v) { return vst1_f32(ptr, v); }
|
||||
|
||||
////////////////////////////// vst2q ///////////////////////
|
||||
|
||||
inline void vst2q(u8 * ptr, const uint8x16x2_t & v) { return vst2q_u8(ptr, v); }
|
||||
inline void vst2q(s8 * ptr, const int8x16x2_t & v) { return vst2q_s8(ptr, v); }
|
||||
inline void vst2q(u16 * ptr, const uint16x8x2_t & v) { return vst2q_u16(ptr, v); }
|
||||
inline void vst2q(s16 * ptr, const int16x8x2_t & v) { return vst2q_s16(ptr, v); }
|
||||
inline void vst2q(u32 * ptr, const uint32x4x2_t & v) { return vst2q_u32(ptr, v); }
|
||||
inline void vst2q(s32 * ptr, const int32x4x2_t & v) { return vst2q_s32(ptr, v); }
|
||||
inline void vst2q(f32 * ptr, const float32x4x2_t & v) { return vst2q_f32(ptr, v); }
|
||||
|
||||
////////////////////////////// vst2 ///////////////////////
|
||||
|
||||
inline void vst2(u8 * ptr, const uint8x8x2_t & v) { return vst2_u8(ptr, v); }
|
||||
inline void vst2(s8 * ptr, const int8x8x2_t & v) { return vst2_s8(ptr, v); }
|
||||
inline void vst2(u16 * ptr, const uint16x4x2_t & v) { return vst2_u16(ptr, v); }
|
||||
inline void vst2(s16 * ptr, const int16x4x2_t & v) { return vst2_s16(ptr, v); }
|
||||
inline void vst2(u32 * ptr, const uint32x2x2_t & v) { return vst2_u32(ptr, v); }
|
||||
inline void vst2(s32 * ptr, const int32x2x2_t & v) { return vst2_s32(ptr, v); }
|
||||
inline void vst2(f32 * ptr, const float32x2x2_t & v) { return vst2_f32(ptr, v); }
|
||||
|
||||
////////////////////////////// vst3q ///////////////////////
|
||||
|
||||
inline void vst3q(u8 * ptr, const uint8x16x3_t & v) { return vst3q_u8(ptr, v); }
|
||||
inline void vst3q(s8 * ptr, const int8x16x3_t & v) { return vst3q_s8(ptr, v); }
|
||||
inline void vst3q(u16 * ptr, const uint16x8x3_t & v) { return vst3q_u16(ptr, v); }
|
||||
inline void vst3q(s16 * ptr, const int16x8x3_t & v) { return vst3q_s16(ptr, v); }
|
||||
inline void vst3q(u32 * ptr, const uint32x4x3_t & v) { return vst3q_u32(ptr, v); }
|
||||
inline void vst3q(s32 * ptr, const int32x4x3_t & v) { return vst3q_s32(ptr, v); }
|
||||
inline void vst3q(f32 * ptr, const float32x4x3_t & v) { return vst3q_f32(ptr, v); }
|
||||
|
||||
////////////////////////////// vst3 ///////////////////////
|
||||
|
||||
inline void vst3(u8 * ptr, const uint8x8x3_t & v) { return vst3_u8(ptr, v); }
|
||||
inline void vst3(s8 * ptr, const int8x8x3_t & v) { return vst3_s8(ptr, v); }
|
||||
inline void vst3(u16 * ptr, const uint16x4x3_t & v) { return vst3_u16(ptr, v); }
|
||||
inline void vst3(s16 * ptr, const int16x4x3_t & v) { return vst3_s16(ptr, v); }
|
||||
inline void vst3(u32 * ptr, const uint32x2x3_t & v) { return vst3_u32(ptr, v); }
|
||||
inline void vst3(s32 * ptr, const int32x2x3_t & v) { return vst3_s32(ptr, v); }
|
||||
inline void vst3(f32 * ptr, const float32x2x3_t & v) { return vst3_f32(ptr, v); }
|
||||
|
||||
////////////////////////////// vst4q ///////////////////////
|
||||
|
||||
inline void vst4q(u8 * ptr, const uint8x16x4_t & v) { return vst4q_u8(ptr, v); }
|
||||
inline void vst4q(s8 * ptr, const int8x16x4_t & v) { return vst4q_s8(ptr, v); }
|
||||
inline void vst4q(u16 * ptr, const uint16x8x4_t & v) { return vst4q_u16(ptr, v); }
|
||||
inline void vst4q(s16 * ptr, const int16x8x4_t & v) { return vst4q_s16(ptr, v); }
|
||||
inline void vst4q(u32 * ptr, const uint32x4x4_t & v) { return vst4q_u32(ptr, v); }
|
||||
inline void vst4q(s32 * ptr, const int32x4x4_t & v) { return vst4q_s32(ptr, v); }
|
||||
inline void vst4q(f32 * ptr, const float32x4x4_t & v) { return vst4q_f32(ptr, v); }
|
||||
|
||||
////////////////////////////// vst4 ///////////////////////
|
||||
|
||||
inline void vst4(u8 * ptr, const uint8x8x4_t & v) { return vst4_u8(ptr, v); }
|
||||
inline void vst4(s8 * ptr, const int8x8x4_t & v) { return vst4_s8(ptr, v); }
|
||||
inline void vst4(u16 * ptr, const uint16x4x4_t & v) { return vst4_u16(ptr, v); }
|
||||
inline void vst4(s16 * ptr, const int16x4x4_t & v) { return vst4_s16(ptr, v); }
|
||||
inline void vst4(u32 * ptr, const uint32x2x4_t & v) { return vst4_u32(ptr, v); }
|
||||
inline void vst4(s32 * ptr, const int32x2x4_t & v) { return vst4_s32(ptr, v); }
|
||||
inline void vst4(f32 * ptr, const float32x2x4_t & v) { return vst4_f32(ptr, v); }
|
||||
|
||||
////////////////////////////// vabdq ///////////////////////
|
||||
|
||||
inline uint8x16_t vabdq(const uint8x16_t & v0, const uint8x16_t & v1) { return vabdq_u8 (v0, v1); }
|
||||
inline int8x16_t vabdq(const int8x16_t & v0, const int8x16_t & v1) { return vabdq_s8 (v0, v1); }
|
||||
inline uint16x8_t vabdq(const uint16x8_t & v0, const uint16x8_t & v1) { return vabdq_u16(v0, v1); }
|
||||
inline int16x8_t vabdq(const int16x8_t & v0, const int16x8_t & v1) { return vabdq_s16(v0, v1); }
|
||||
inline uint32x4_t vabdq(const uint32x4_t & v0, const uint32x4_t & v1) { return vabdq_u32(v0, v1); }
|
||||
inline int32x4_t vabdq(const int32x4_t & v0, const int32x4_t & v1) { return vabdq_s32(v0, v1); }
|
||||
inline float32x4_t vabdq(const float32x4_t & v0, const float32x4_t & v1) { return vabdq_f32(v0, v1); }
|
||||
|
||||
////////////////////////////// vabd ///////////////////////
|
||||
|
||||
inline uint8x8_t vabd(const uint8x8_t & v0, const uint8x8_t & v1) { return vabd_u8 (v0, v1); }
|
||||
inline int8x8_t vabd(const int8x8_t & v0, const int8x8_t & v1) { return vabd_s8 (v0, v1); }
|
||||
inline uint16x4_t vabd(const uint16x4_t & v0, const uint16x4_t & v1) { return vabd_u16(v0, v1); }
|
||||
inline int16x4_t vabd(const int16x4_t & v0, const int16x4_t & v1) { return vabd_s16(v0, v1); }
|
||||
inline uint32x2_t vabd(const uint32x2_t & v0, const uint32x2_t & v1) { return vabd_u32(v0, v1); }
|
||||
inline int32x2_t vabd(const int32x2_t & v0, const int32x2_t & v1) { return vabd_s32(v0, v1); }
|
||||
inline float32x2_t vabd(const float32x2_t & v0, const float32x2_t & v1) { return vabd_f32(v0, v1); }
|
||||
|
||||
////////////////////////////// vminq ///////////////////////
|
||||
|
||||
inline uint8x16_t vminq(const uint8x16_t & v0, const uint8x16_t & v1) { return vminq_u8 (v0, v1); }
|
||||
inline int8x16_t vminq(const int8x16_t & v0, const int8x16_t & v1) { return vminq_s8 (v0, v1); }
|
||||
inline uint16x8_t vminq(const uint16x8_t & v0, const uint16x8_t & v1) { return vminq_u16(v0, v1); }
|
||||
inline int16x8_t vminq(const int16x8_t & v0, const int16x8_t & v1) { return vminq_s16(v0, v1); }
|
||||
inline uint32x4_t vminq(const uint32x4_t & v0, const uint32x4_t & v1) { return vminq_u32(v0, v1); }
|
||||
inline int32x4_t vminq(const int32x4_t & v0, const int32x4_t & v1) { return vminq_s32(v0, v1); }
|
||||
inline float32x4_t vminq(const float32x4_t & v0, const float32x4_t & v1) { return vminq_f32(v0, v1); }
|
||||
|
||||
////////////////////////////// vmin ///////////////////////
|
||||
|
||||
inline uint8x8_t vmin(const uint8x8_t & v0, const uint8x8_t & v1) { return vmin_u8 (v0, v1); }
|
||||
inline int8x8_t vmin(const int8x8_t & v0, const int8x8_t & v1) { return vmin_s8 (v0, v1); }
|
||||
inline uint16x4_t vmin(const uint16x4_t & v0, const uint16x4_t & v1) { return vmin_u16(v0, v1); }
|
||||
inline int16x4_t vmin(const int16x4_t & v0, const int16x4_t & v1) { return vmin_s16(v0, v1); }
|
||||
inline uint32x2_t vmin(const uint32x2_t & v0, const uint32x2_t & v1) { return vmin_u32(v0, v1); }
|
||||
inline int32x2_t vmin(const int32x2_t & v0, const int32x2_t & v1) { return vmin_s32(v0, v1); }
|
||||
inline float32x2_t vmin(const float32x2_t & v0, const float32x2_t & v1) { return vmin_f32(v0, v1); }
|
||||
|
||||
////////////////////////////// vmaxq ///////////////////////
|
||||
|
||||
inline uint8x16_t vmaxq(const uint8x16_t & v0, const uint8x16_t & v1) { return vmaxq_u8 (v0, v1); }
|
||||
inline int8x16_t vmaxq(const int8x16_t & v0, const int8x16_t & v1) { return vmaxq_s8 (v0, v1); }
|
||||
inline uint16x8_t vmaxq(const uint16x8_t & v0, const uint16x8_t & v1) { return vmaxq_u16(v0, v1); }
|
||||
inline int16x8_t vmaxq(const int16x8_t & v0, const int16x8_t & v1) { return vmaxq_s16(v0, v1); }
|
||||
inline uint32x4_t vmaxq(const uint32x4_t & v0, const uint32x4_t & v1) { return vmaxq_u32(v0, v1); }
|
||||
inline int32x4_t vmaxq(const int32x4_t & v0, const int32x4_t & v1) { return vmaxq_s32(v0, v1); }
|
||||
inline float32x4_t vmaxq(const float32x4_t & v0, const float32x4_t & v1) { return vmaxq_f32(v0, v1); }
|
||||
|
||||
////////////////////////////// vmax ///////////////////////
|
||||
|
||||
inline uint8x8_t vmax(const uint8x8_t & v0, const uint8x8_t & v1) { return vmax_u8 (v0, v1); }
|
||||
inline int8x8_t vmax(const int8x8_t & v0, const int8x8_t & v1) { return vmax_s8 (v0, v1); }
|
||||
inline uint16x4_t vmax(const uint16x4_t & v0, const uint16x4_t & v1) { return vmax_u16(v0, v1); }
|
||||
inline int16x4_t vmax(const int16x4_t & v0, const int16x4_t & v1) { return vmax_s16(v0, v1); }
|
||||
inline uint32x2_t vmax(const uint32x2_t & v0, const uint32x2_t & v1) { return vmax_u32(v0, v1); }
|
||||
inline int32x2_t vmax(const int32x2_t & v0, const int32x2_t & v1) { return vmax_s32(v0, v1); }
|
||||
inline float32x2_t vmax(const float32x2_t & v0, const float32x2_t & v1) { return vmax_f32(v0, v1); }
|
||||
|
||||
////////////////////////////// vdupq_n ///////////////////////
|
||||
|
||||
inline uint8x16_t vdupq_n(const u8 & val) { return vdupq_n_u8(val); }
|
||||
inline int8x16_t vdupq_n(const s8 & val) { return vdupq_n_s8(val); }
|
||||
inline uint16x8_t vdupq_n(const u16 & val) { return vdupq_n_u16(val); }
|
||||
inline int16x8_t vdupq_n(const s16 & val) { return vdupq_n_s16(val); }
|
||||
inline uint32x4_t vdupq_n(const u32 & val) { return vdupq_n_u32(val); }
|
||||
inline int32x4_t vdupq_n(const s32 & val) { return vdupq_n_s32(val); }
|
||||
inline uint64x2_t vdupq_n(const u64 & val) { return vdupq_n_u64(val); }
|
||||
inline int64x2_t vdupq_n(const s64 & val) { return vdupq_n_s64(val); }
|
||||
inline float32x4_t vdupq_n(const f32 & val) { return vdupq_n_f32(val); }
|
||||
|
||||
////////////////////////////// vdup_n ///////////////////////
|
||||
|
||||
inline uint8x8_t vdup_n(const u8 & val) { return vdup_n_u8(val); }
|
||||
inline int8x8_t vdup_n(const s8 & val) { return vdup_n_s8(val); }
|
||||
inline uint16x4_t vdup_n(const u16 & val) { return vdup_n_u16(val); }
|
||||
inline int16x4_t vdup_n(const s16 & val) { return vdup_n_s16(val); }
|
||||
inline uint32x2_t vdup_n(const u32 & val) { return vdup_n_u32(val); }
|
||||
inline int32x2_t vdup_n(const s32 & val) { return vdup_n_s32(val); }
|
||||
inline uint64x1_t vdup_n(const u64 & val) { return vdup_n_u64(val); }
|
||||
inline int64x1_t vdup_n(const s64 & val) { return vdup_n_s64(val); }
|
||||
inline float32x2_t vdup_n(const f32 & val) { return vdup_n_f32(val); }
|
||||
|
||||
////////////////////////////// vget_low ///////////////////////
|
||||
|
||||
inline uint8x8_t vget_low(const uint8x16_t & v) { return vget_low_u8 (v); }
|
||||
inline int8x8_t vget_low(const int8x16_t & v) { return vget_low_s8 (v); }
|
||||
inline uint16x4_t vget_low(const uint16x8_t & v) { return vget_low_u16(v); }
|
||||
inline int16x4_t vget_low(const int16x8_t & v) { return vget_low_s16(v); }
|
||||
inline uint32x2_t vget_low(const uint32x4_t & v) { return vget_low_u32(v); }
|
||||
inline int32x2_t vget_low(const int32x4_t & v) { return vget_low_s32(v); }
|
||||
inline float32x2_t vget_low(const float32x4_t & v) { return vget_low_f32(v); }
|
||||
|
||||
////////////////////////////// vget_high ///////////////////////
|
||||
|
||||
inline uint8x8_t vget_high(const uint8x16_t & v) { return vget_high_u8 (v); }
|
||||
inline int8x8_t vget_high(const int8x16_t & v) { return vget_high_s8 (v); }
|
||||
inline uint16x4_t vget_high(const uint16x8_t & v) { return vget_high_u16(v); }
|
||||
inline int16x4_t vget_high(const int16x8_t & v) { return vget_high_s16(v); }
|
||||
inline uint32x2_t vget_high(const uint32x4_t & v) { return vget_high_u32(v); }
|
||||
inline int32x2_t vget_high(const int32x4_t & v) { return vget_high_s32(v); }
|
||||
inline float32x2_t vget_high(const float32x4_t & v) { return vget_high_f32(v); }
|
||||
|
||||
////////////////////////////// vcombine ///////////////////////
|
||||
|
||||
inline uint8x16_t vcombine(const uint8x8_t & v0, const uint8x8_t & v1) { return vcombine_u8 (v0, v1); }
|
||||
inline int8x16_t vcombine(const int8x8_t & v0, const int8x8_t & v1) { return vcombine_s8 (v0, v1); }
|
||||
inline uint16x8_t vcombine(const uint16x4_t & v0, const uint16x4_t & v1) { return vcombine_u16(v0, v1); }
|
||||
inline int16x8_t vcombine(const int16x4_t & v0, const int16x4_t & v1) { return vcombine_s16(v0, v1); }
|
||||
inline uint32x4_t vcombine(const uint32x2_t & v0, const uint32x2_t & v1) { return vcombine_u32(v0, v1); }
|
||||
inline int32x4_t vcombine(const int32x2_t & v0, const int32x2_t & v1) { return vcombine_s32(v0, v1); }
|
||||
inline float32x4_t vcombine(const float32x2_t & v0, const float32x2_t & v1) { return vcombine_f32(v0, v1); }
|
||||
|
||||
////////////////////////////// vaddq ///////////////////////
|
||||
|
||||
inline uint8x16_t vaddq(const uint8x16_t & v0, const uint8x16_t & v1) { return vaddq_u8 (v0, v1); }
|
||||
inline int8x16_t vaddq(const int8x16_t & v0, const int8x16_t & v1) { return vaddq_s8 (v0, v1); }
|
||||
inline uint16x8_t vaddq(const uint16x8_t & v0, const uint16x8_t & v1) { return vaddq_u16(v0, v1); }
|
||||
inline int16x8_t vaddq(const int16x8_t & v0, const int16x8_t & v1) { return vaddq_s16(v0, v1); }
|
||||
inline uint32x4_t vaddq(const uint32x4_t & v0, const uint32x4_t & v1) { return vaddq_u32(v0, v1); }
|
||||
inline int32x4_t vaddq(const int32x4_t & v0, const int32x4_t & v1) { return vaddq_s32(v0, v1); }
|
||||
inline float32x4_t vaddq(const float32x4_t & v0, const float32x4_t & v1) { return vaddq_f32(v0, v1); }
|
||||
|
||||
////////////////////////////// vadd ///////////////////////
|
||||
|
||||
inline uint8x8_t vadd(const uint8x8_t & v0, const uint8x8_t & v1) { return vadd_u8 (v0, v1); }
|
||||
inline int8x8_t vadd(const int8x8_t & v0, const int8x8_t & v1) { return vadd_s8 (v0, v1); }
|
||||
inline uint16x4_t vadd(const uint16x4_t & v0, const uint16x4_t & v1) { return vadd_u16(v0, v1); }
|
||||
inline int16x4_t vadd(const int16x4_t & v0, const int16x4_t & v1) { return vadd_s16(v0, v1); }
|
||||
inline uint32x2_t vadd(const uint32x2_t & v0, const uint32x2_t & v1) { return vadd_u32(v0, v1); }
|
||||
inline int32x2_t vadd(const int32x2_t & v0, const int32x2_t & v1) { return vadd_s32(v0, v1); }
|
||||
inline float32x2_t vadd(const float32x2_t & v0, const float32x2_t & v1) { return vadd_f32(v0, v1); }
|
||||
|
||||
////////////////////////////// vqaddq ///////////////////////
|
||||
|
||||
inline uint8x16_t vqaddq(const uint8x16_t & v0, const uint8x16_t & v1) { return vqaddq_u8 (v0, v1); }
|
||||
inline int8x16_t vqaddq(const int8x16_t & v0, const int8x16_t & v1) { return vqaddq_s8 (v0, v1); }
|
||||
inline uint16x8_t vqaddq(const uint16x8_t & v0, const uint16x8_t & v1) { return vqaddq_u16(v0, v1); }
|
||||
inline int16x8_t vqaddq(const int16x8_t & v0, const int16x8_t & v1) { return vqaddq_s16(v0, v1); }
|
||||
inline uint32x4_t vqaddq(const uint32x4_t & v0, const uint32x4_t & v1) { return vqaddq_u32(v0, v1); }
|
||||
inline int32x4_t vqaddq(const int32x4_t & v0, const int32x4_t & v1) { return vqaddq_s32(v0, v1); }
|
||||
|
||||
////////////////////////////// vqadd ///////////////////////
|
||||
|
||||
inline uint8x8_t vqadd(const uint8x8_t & v0, const uint8x8_t & v1) { return vqadd_u8 (v0, v1); }
|
||||
inline int8x8_t vqadd(const int8x8_t & v0, const int8x8_t & v1) { return vqadd_s8 (v0, v1); }
|
||||
inline uint16x4_t vqadd(const uint16x4_t & v0, const uint16x4_t & v1) { return vqadd_u16(v0, v1); }
|
||||
inline int16x4_t vqadd(const int16x4_t & v0, const int16x4_t & v1) { return vqadd_s16(v0, v1); }
|
||||
inline uint32x2_t vqadd(const uint32x2_t & v0, const uint32x2_t & v1) { return vqadd_u32(v0, v1); }
|
||||
inline int32x2_t vqadd(const int32x2_t & v0, const int32x2_t & v1) { return vqadd_s32(v0, v1); }
|
||||
|
||||
////////////////////////////// vsubq ///////////////////////
|
||||
|
||||
inline uint8x16_t vsubq(const uint8x16_t & v0, const uint8x16_t & v1) { return vsubq_u8 (v0, v1); }
|
||||
inline int8x16_t vsubq(const int8x16_t & v0, const int8x16_t & v1) { return vsubq_s8 (v0, v1); }
|
||||
inline uint16x8_t vsubq(const uint16x8_t & v0, const uint16x8_t & v1) { return vsubq_u16(v0, v1); }
|
||||
inline int16x8_t vsubq(const int16x8_t & v0, const int16x8_t & v1) { return vsubq_s16(v0, v1); }
|
||||
inline uint32x4_t vsubq(const uint32x4_t & v0, const uint32x4_t & v1) { return vsubq_u32(v0, v1); }
|
||||
inline int32x4_t vsubq(const int32x4_t & v0, const int32x4_t & v1) { return vsubq_s32(v0, v1); }
|
||||
inline float32x4_t vsubq(const float32x4_t & v0, const float32x4_t & v1) { return vsubq_f32(v0, v1); }
|
||||
|
||||
////////////////////////////// vsub ///////////////////////
|
||||
|
||||
inline uint8x8_t vsub(const uint8x8_t & v0, const uint8x8_t & v1) { return vsub_u8 (v0, v1); }
|
||||
inline int8x8_t vsub(const int8x8_t & v0, const int8x8_t & v1) { return vsub_s8 (v0, v1); }
|
||||
inline uint16x4_t vsub(const uint16x4_t & v0, const uint16x4_t & v1) { return vsub_u16(v0, v1); }
|
||||
inline int16x4_t vsub(const int16x4_t & v0, const int16x4_t & v1) { return vsub_s16(v0, v1); }
|
||||
inline uint32x2_t vsub(const uint32x2_t & v0, const uint32x2_t & v1) { return vsub_u32(v0, v1); }
|
||||
inline int32x2_t vsub(const int32x2_t & v0, const int32x2_t & v1) { return vsub_s32(v0, v1); }
|
||||
inline float32x2_t vsub(const float32x2_t & v0, const float32x2_t & v1) { return vsub_f32(v0, v1); }
|
||||
|
||||
////////////////////////////// vqsubq ///////////////////////
|
||||
|
||||
inline uint8x16_t vqsubq(const uint8x16_t & v0, const uint8x16_t & v1) { return vqsubq_u8 (v0, v1); }
|
||||
inline int8x16_t vqsubq(const int8x16_t & v0, const int8x16_t & v1) { return vqsubq_s8 (v0, v1); }
|
||||
inline uint16x8_t vqsubq(const uint16x8_t & v0, const uint16x8_t & v1) { return vqsubq_u16(v0, v1); }
|
||||
inline int16x8_t vqsubq(const int16x8_t & v0, const int16x8_t & v1) { return vqsubq_s16(v0, v1); }
|
||||
inline uint32x4_t vqsubq(const uint32x4_t & v0, const uint32x4_t & v1) { return vqsubq_u32(v0, v1); }
|
||||
inline int32x4_t vqsubq(const int32x4_t & v0, const int32x4_t & v1) { return vqsubq_s32(v0, v1); }
|
||||
inline uint64x2_t vqsubq(const uint64x2_t & v0, const uint64x2_t & v1) { return vqsubq_u64(v0, v1); }
|
||||
inline int64x2_t vqsubq(const int64x2_t & v0, const int64x2_t & v1) { return vqsubq_s64(v0, v1); }
|
||||
|
||||
////////////////////////////// vqsub ///////////////////////
|
||||
|
||||
inline uint8x8_t vqsub(const uint8x8_t & v0, const uint8x8_t & v1) { return vqsub_u8 (v0, v1); }
|
||||
inline int8x8_t vqsub(const int8x8_t & v0, const int8x8_t & v1) { return vqsub_s8 (v0, v1); }
|
||||
inline uint16x4_t vqsub(const uint16x4_t & v0, const uint16x4_t & v1) { return vqsub_u16(v0, v1); }
|
||||
inline int16x4_t vqsub(const int16x4_t & v0, const int16x4_t & v1) { return vqsub_s16(v0, v1); }
|
||||
inline uint32x2_t vqsub(const uint32x2_t & v0, const uint32x2_t & v1) { return vqsub_u32(v0, v1); }
|
||||
inline int32x2_t vqsub(const int32x2_t & v0, const int32x2_t & v1) { return vqsub_s32(v0, v1); }
|
||||
inline uint64x1_t vqsub(const uint64x1_t & v0, const uint64x1_t & v1) { return vqsub_u64(v0, v1); }
|
||||
inline int64x1_t vqsub(const int64x1_t & v0, const int64x1_t & v1) { return vqsub_s64(v0, v1); }
|
||||
|
||||
////////////////////////////// vmull ///////////////////////
|
||||
|
||||
inline uint16x8_t vmull(const uint8x8_t & v0, const uint8x8_t & v1) { return vmull_u8 (v0, v1); }
|
||||
inline int16x8_t vmull(const int8x8_t & v0, const int8x8_t & v1) { return vmull_s8 (v0, v1); }
|
||||
inline uint32x4_t vmull(const uint16x4_t & v0, const uint16x4_t & v1) { return vmull_u16(v0, v1); }
|
||||
inline int32x4_t vmull(const int16x4_t & v0, const int16x4_t & v1) { return vmull_s16(v0, v1); }
|
||||
inline uint64x2_t vmull(const uint32x2_t & v0, const uint32x2_t & v1) { return vmull_u32(v0, v1); }
|
||||
inline int64x2_t vmull(const int32x2_t & v0, const int32x2_t & v1) { return vmull_s32(v0, v1); }
|
||||
|
||||
////////////////////////////// vrev64q ///////////////////////
|
||||
|
||||
inline uint8x16_t vrev64q(const uint8x16_t & v) { return vrev64q_u8 (v); }
|
||||
inline int8x16_t vrev64q(const int8x16_t & v) { return vrev64q_s8 (v); }
|
||||
inline uint16x8_t vrev64q(const uint16x8_t & v) { return vrev64q_u16(v); }
|
||||
inline int16x8_t vrev64q(const int16x8_t & v) { return vrev64q_s16(v); }
|
||||
inline uint32x4_t vrev64q(const uint32x4_t & v) { return vrev64q_u32(v); }
|
||||
inline int32x4_t vrev64q(const int32x4_t & v) { return vrev64q_s32(v); }
|
||||
inline float32x4_t vrev64q(const float32x4_t & v) { return vrev64q_f32(v); }
|
||||
|
||||
////////////////////////////// vrev64 ///////////////////////
|
||||
|
||||
inline uint8x8_t vrev64(const uint8x8_t & v) { return vrev64_u8 (v); }
|
||||
inline int8x8_t vrev64(const int8x8_t & v) { return vrev64_s8 (v); }
|
||||
inline uint16x4_t vrev64(const uint16x4_t & v) { return vrev64_u16(v); }
|
||||
inline int16x4_t vrev64(const int16x4_t & v) { return vrev64_s16(v); }
|
||||
inline uint32x2_t vrev64(const uint32x2_t & v) { return vrev64_u32(v); }
|
||||
inline int32x2_t vrev64(const int32x2_t & v) { return vrev64_s32(v); }
|
||||
inline float32x2_t vrev64(const float32x2_t & v) { return vrev64_f32(v); }
|
||||
|
||||
////////////////////////////// vceqq ///////////////////////
|
||||
|
||||
inline uint8x16_t vceqq(const uint8x16_t & v0, const uint8x16_t & v1) { return vceqq_u8 (v0, v1); }
|
||||
inline uint8x16_t vceqq(const int8x16_t & v0, const int8x16_t & v1) { return vceqq_s8 (v0, v1); }
|
||||
inline uint16x8_t vceqq(const uint16x8_t & v0, const uint16x8_t & v1) { return vceqq_u16(v0, v1); }
|
||||
inline uint16x8_t vceqq(const int16x8_t & v0, const int16x8_t & v1) { return vceqq_s16(v0, v1); }
|
||||
inline uint32x4_t vceqq(const uint32x4_t & v0, const uint32x4_t & v1) { return vceqq_u32(v0, v1); }
|
||||
inline uint32x4_t vceqq(const int32x4_t & v0, const int32x4_t & v1) { return vceqq_s32(v0, v1); }
|
||||
inline uint32x4_t vceqq(const float32x4_t & v0, const float32x4_t & v1) { return vceqq_f32(v0, v1); }
|
||||
|
||||
////////////////////////////// vceq ///////////////////////
|
||||
|
||||
inline uint8x8_t vceq(const uint8x8_t & v0, const uint8x8_t & v1) { return vceq_u8 (v0, v1); }
|
||||
inline uint8x8_t vceq(const int8x8_t & v0, const int8x8_t & v1) { return vceq_s8 (v0, v1); }
|
||||
inline uint16x4_t vceq(const uint16x4_t & v0, const uint16x4_t & v1) { return vceq_u16(v0, v1); }
|
||||
inline uint16x4_t vceq(const int16x4_t & v0, const int16x4_t & v1) { return vceq_s16(v0, v1); }
|
||||
inline uint32x2_t vceq(const uint32x2_t & v0, const uint32x2_t & v1) { return vceq_u32(v0, v1); }
|
||||
inline uint32x2_t vceq(const int32x2_t & v0, const int32x2_t & v1) { return vceq_s32(v0, v1); }
|
||||
inline uint32x2_t vceq(const float32x2_t & v0, const float32x2_t & v1) { return vceq_f32(v0, v1); }
|
||||
|
||||
////////////////////////////// vcgtq ///////////////////////
|
||||
|
||||
inline uint8x16_t vcgtq(const uint8x16_t & v0, const uint8x16_t & v1) { return vcgtq_u8 (v0, v1); }
|
||||
inline uint8x16_t vcgtq(const int8x16_t & v0, const int8x16_t & v1) { return vcgtq_s8 (v0, v1); }
|
||||
inline uint16x8_t vcgtq(const uint16x8_t & v0, const uint16x8_t & v1) { return vcgtq_u16(v0, v1); }
|
||||
inline uint16x8_t vcgtq(const int16x8_t & v0, const int16x8_t & v1) { return vcgtq_s16(v0, v1); }
|
||||
inline uint32x4_t vcgtq(const uint32x4_t & v0, const uint32x4_t & v1) { return vcgtq_u32(v0, v1); }
|
||||
inline uint32x4_t vcgtq(const int32x4_t & v0, const int32x4_t & v1) { return vcgtq_s32(v0, v1); }
|
||||
inline uint32x4_t vcgtq(const float32x4_t & v0, const float32x4_t & v1) { return vcgtq_f32(v0, v1); }
|
||||
|
||||
////////////////////////////// vcgt ///////////////////////
|
||||
|
||||
inline uint8x8_t vcgt(const uint8x8_t & v0, const uint8x8_t & v1) { return vcgt_u8 (v0, v1); }
|
||||
inline uint8x8_t vcgt(const int8x8_t & v0, const int8x8_t & v1) { return vcgt_s8 (v0, v1); }
|
||||
inline uint16x4_t vcgt(const uint16x4_t & v0, const uint16x4_t & v1) { return vcgt_u16(v0, v1); }
|
||||
inline uint16x4_t vcgt(const int16x4_t & v0, const int16x4_t & v1) { return vcgt_s16(v0, v1); }
|
||||
inline uint32x2_t vcgt(const uint32x2_t & v0, const uint32x2_t & v1) { return vcgt_u32(v0, v1); }
|
||||
inline uint32x2_t vcgt(const int32x2_t & v0, const int32x2_t & v1) { return vcgt_s32(v0, v1); }
|
||||
inline uint32x2_t vcgt(const float32x2_t & v0, const float32x2_t & v1) { return vcgt_f32(v0, v1); }
|
||||
|
||||
////////////////////////////// vcgeq ///////////////////////
|
||||
|
||||
inline uint8x16_t vcgeq(const uint8x16_t & v0, const uint8x16_t & v1) { return vcgeq_u8 (v0, v1); }
|
||||
inline uint8x16_t vcgeq(const int8x16_t & v0, const int8x16_t & v1) { return vcgeq_s8 (v0, v1); }
|
||||
inline uint16x8_t vcgeq(const uint16x8_t & v0, const uint16x8_t & v1) { return vcgeq_u16(v0, v1); }
|
||||
inline uint16x8_t vcgeq(const int16x8_t & v0, const int16x8_t & v1) { return vcgeq_s16(v0, v1); }
|
||||
inline uint32x4_t vcgeq(const uint32x4_t & v0, const uint32x4_t & v1) { return vcgeq_u32(v0, v1); }
|
||||
inline uint32x4_t vcgeq(const int32x4_t & v0, const int32x4_t & v1) { return vcgeq_s32(v0, v1); }
|
||||
inline uint32x4_t vcgeq(const float32x4_t & v0, const float32x4_t & v1) { return vcgeq_f32(v0, v1); }
|
||||
|
||||
////////////////////////////// vcge ///////////////////////
|
||||
|
||||
inline uint8x8_t vcge(const uint8x8_t & v0, const uint8x8_t & v1) { return vcge_u8 (v0, v1); }
|
||||
inline uint8x8_t vcge(const int8x8_t & v0, const int8x8_t & v1) { return vcge_s8 (v0, v1); }
|
||||
inline uint16x4_t vcge(const uint16x4_t & v0, const uint16x4_t & v1) { return vcge_u16(v0, v1); }
|
||||
inline uint16x4_t vcge(const int16x4_t & v0, const int16x4_t & v1) { return vcge_s16(v0, v1); }
|
||||
inline uint32x2_t vcge(const uint32x2_t & v0, const uint32x2_t & v1) { return vcge_u32(v0, v1); }
|
||||
inline uint32x2_t vcge(const int32x2_t & v0, const int32x2_t & v1) { return vcge_s32(v0, v1); }
|
||||
inline uint32x2_t vcge(const float32x2_t & v0, const float32x2_t & v1) { return vcge_f32(v0, v1); }
|
||||
|
||||
////////////////////////////// vandq ///////////////////////
|
||||
|
||||
inline uint8x16_t vandq(const uint8x16_t & v0, const uint8x16_t & v1) { return vandq_u8 (v0, v1); }
|
||||
inline int8x16_t vandq(const int8x16_t & v0, const int8x16_t & v1) { return vandq_s8 (v0, v1); }
|
||||
inline uint16x8_t vandq(const uint16x8_t & v0, const uint16x8_t & v1) { return vandq_u16(v0, v1); }
|
||||
inline int16x8_t vandq(const int16x8_t & v0, const int16x8_t & v1) { return vandq_s16(v0, v1); }
|
||||
inline uint32x4_t vandq(const uint32x4_t & v0, const uint32x4_t & v1) { return vandq_u32(v0, v1); }
|
||||
inline int32x4_t vandq(const int32x4_t & v0, const int32x4_t & v1) { return vandq_s32(v0, v1); }
|
||||
|
||||
////////////////////////////// vand ///////////////////////
|
||||
|
||||
inline uint8x8_t vand(const uint8x8_t & v0, const uint8x8_t & v1) { return vand_u8 (v0, v1); }
|
||||
inline int8x8_t vand(const int8x8_t & v0, const int8x8_t & v1) { return vand_s8 (v0, v1); }
|
||||
inline uint16x4_t vand(const uint16x4_t & v0, const uint16x4_t & v1) { return vand_u16(v0, v1); }
|
||||
inline int16x4_t vand(const int16x4_t & v0, const int16x4_t & v1) { return vand_s16(v0, v1); }
|
||||
inline uint32x2_t vand(const uint32x2_t & v0, const uint32x2_t & v1) { return vand_u32(v0, v1); }
|
||||
inline int32x2_t vand(const int32x2_t & v0, const int32x2_t & v1) { return vand_s32(v0, v1); }
|
||||
|
||||
////////////////////////////// vmovn ///////////////////////
|
||||
|
||||
inline uint8x8_t vmovn(const uint16x8_t & v) { return vmovn_u16(v); }
|
||||
inline int8x8_t vmovn(const int16x8_t & v) { return vmovn_s16(v); }
|
||||
inline uint16x4_t vmovn(const uint32x4_t & v) { return vmovn_u32(v); }
|
||||
inline int16x4_t vmovn(const int32x4_t & v) { return vmovn_s32(v); }
|
||||
inline uint32x2_t vmovn(const uint64x2_t & v) { return vmovn_u64(v); }
|
||||
inline int32x2_t vmovn(const int64x2_t & v) { return vmovn_s64(v); }
|
||||
|
||||
////////////////////////////// vqmovn ///////////////////////
|
||||
|
||||
inline uint8x8_t vqmovn(const uint16x8_t & v) { return vqmovn_u16(v); }
|
||||
inline int8x8_t vqmovn(const int16x8_t & v) { return vqmovn_s16(v); }
|
||||
inline uint16x4_t vqmovn(const uint32x4_t & v) { return vqmovn_u32(v); }
|
||||
inline int16x4_t vqmovn(const int32x4_t & v) { return vqmovn_s32(v); }
|
||||
inline uint32x2_t vqmovn(const uint64x2_t & v) { return vqmovn_u64(v); }
|
||||
inline int32x2_t vqmovn(const int64x2_t & v) { return vqmovn_s64(v); }
|
||||
|
||||
////////////////////////////// vmovl ///////////////////////
|
||||
|
||||
inline uint16x8_t vmovl(const uint8x8_t & v) { return vmovl_u8(v); }
|
||||
inline int16x8_t vmovl(const int8x8_t & v) { return vmovl_s8(v); }
|
||||
inline uint32x4_t vmovl(const uint16x4_t & v) { return vmovl_u16(v); }
|
||||
inline int32x4_t vmovl(const int16x4_t & v) { return vmovl_s16(v); }
|
||||
|
||||
////////////////////////////// vmvnq ///////////////////////
|
||||
|
||||
inline uint8x16_t vmvnq(const uint8x16_t & v) { return vmvnq_u8 (v); }
|
||||
inline int8x16_t vmvnq(const int8x16_t & v) { return vmvnq_s8 (v); }
|
||||
inline uint16x8_t vmvnq(const uint16x8_t & v) { return vmvnq_u16(v); }
|
||||
inline int16x8_t vmvnq(const int16x8_t & v) { return vmvnq_s16(v); }
|
||||
inline uint32x4_t vmvnq(const uint32x4_t & v) { return vmvnq_u32(v); }
|
||||
inline int32x4_t vmvnq(const int32x4_t & v) { return vmvnq_s32(v); }
|
||||
|
||||
////////////////////////////// vmvn ///////////////////////
|
||||
|
||||
inline uint8x8_t vmvn(const uint8x8_t & v) { return vmvn_u8 (v); }
|
||||
inline int8x8_t vmvn(const int8x8_t & v) { return vmvn_s8 (v); }
|
||||
inline uint16x4_t vmvn(const uint16x4_t & v) { return vmvn_u16(v); }
|
||||
inline int16x4_t vmvn(const int16x4_t & v) { return vmvn_s16(v); }
|
||||
inline uint32x2_t vmvn(const uint32x2_t & v) { return vmvn_u32(v); }
|
||||
inline int32x2_t vmvn(const int32x2_t & v) { return vmvn_s32(v); }
|
||||
|
||||
////////////////////////////// vbicq ///////////////////////
|
||||
|
||||
inline uint8x16_t vbicq(const uint8x16_t & v0, const uint8x16_t & v1) { return vbicq_u8 (v0, v1); }
|
||||
inline int8x16_t vbicq(const int8x16_t & v0, const int8x16_t & v1) { return vbicq_s8 (v0, v1); }
|
||||
inline uint16x8_t vbicq(const uint16x8_t & v0, const uint16x8_t & v1) { return vbicq_u16(v0, v1); }
|
||||
inline int16x8_t vbicq(const int16x8_t & v0, const int16x8_t & v1) { return vbicq_s16(v0, v1); }
|
||||
inline uint32x4_t vbicq(const uint32x4_t & v0, const uint32x4_t & v1) { return vbicq_u32(v0, v1); }
|
||||
inline int32x4_t vbicq(const int32x4_t & v0, const int32x4_t & v1) { return vbicq_s32(v0, v1); }
|
||||
inline uint64x2_t vbicq(const uint64x2_t & v0, const uint64x2_t & v1) { return vbicq_u64(v0, v1); }
|
||||
inline int64x2_t vbicq(const int64x2_t & v0, const int64x2_t & v1) { return vbicq_s64(v0, v1); }
|
||||
|
||||
////////////////////////////// vbic ///////////////////////
|
||||
|
||||
inline uint8x8_t vbic(const uint8x8_t & v0, const uint8x8_t & v1) { return vbic_u8 (v0, v1); }
|
||||
inline int8x8_t vbic(const int8x8_t & v0, const int8x8_t & v1) { return vbic_s8 (v0, v1); }
|
||||
inline uint16x4_t vbic(const uint16x4_t & v0, const uint16x4_t & v1) { return vbic_u16(v0, v1); }
|
||||
inline int16x4_t vbic(const int16x4_t & v0, const int16x4_t & v1) { return vbic_s16(v0, v1); }
|
||||
inline uint32x2_t vbic(const uint32x2_t & v0, const uint32x2_t & v1) { return vbic_u32(v0, v1); }
|
||||
inline int32x2_t vbic(const int32x2_t & v0, const int32x2_t & v1) { return vbic_s32(v0, v1); }
|
||||
inline uint64x1_t vbic(const uint64x1_t & v0, const uint64x1_t & v1) { return vbic_u64(v0, v1); }
|
||||
inline int64x1_t vbic(const int64x1_t & v0, const int64x1_t & v1) { return vbic_s64(v0, v1); }
|
||||
|
||||
////////////////////////////// vtransform ///////////////////////
|
||||
|
||||
template <typename Op>
|
||||
void vtransform(Size2D size,
|
||||
const typename Op::type * src0Base, ptrdiff_t src0Stride,
|
||||
const typename Op::type * src1Base, ptrdiff_t src1Stride,
|
||||
typename Op::type * dstBase, ptrdiff_t dstStride, const Op & op)
|
||||
{
|
||||
typedef typename Op::type type;
|
||||
typedef typename VecTraits<type>::vec128 vec128;
|
||||
typedef typename VecTraits<type>::vec64 vec64;
|
||||
|
||||
if (src0Stride == src1Stride && src0Stride == dstStride &&
|
||||
src0Stride == (ptrdiff_t)(size.width * sizeof(type)))
|
||||
{
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
}
|
||||
|
||||
const size_t step_base = 32 / sizeof(type);
|
||||
size_t roiw_base = size.width >= (step_base - 1) ? size.width - step_base + 1 : 0;
|
||||
const size_t step_tail = 8 / sizeof(type);
|
||||
size_t roiw_tail = size.width >= (step_tail - 1) ? size.width - step_tail + 1 : 0;
|
||||
|
||||
for (size_t y = 0; y < size.height; ++y)
|
||||
{
|
||||
const type * src0 = internal::getRowPtr(src0Base, src0Stride, y);
|
||||
const type * src1 = internal::getRowPtr(src1Base, src1Stride, y);
|
||||
typename Op::type * dst = internal::getRowPtr(dstBase, dstStride, y);
|
||||
size_t x = 0;
|
||||
|
||||
for( ; x < roiw_base; x += step_base )
|
||||
{
|
||||
internal::prefetch(src0 + x);
|
||||
internal::prefetch(src1 + x);
|
||||
|
||||
vec128 v_src00 = vld1q(src0 + x), v_src01 = vld1q(src0 + x + 16 / sizeof(type));
|
||||
vec128 v_src10 = vld1q(src1 + x), v_src11 = vld1q(src1 + x + 16 / sizeof(type));
|
||||
vec128 v_dst;
|
||||
|
||||
op(v_src00, v_src10, v_dst);
|
||||
vst1q(dst + x, v_dst);
|
||||
|
||||
op(v_src01, v_src11, v_dst);
|
||||
vst1q(dst + x + 16 / sizeof(type), v_dst);
|
||||
}
|
||||
for( ; x < roiw_tail; x += step_tail )
|
||||
{
|
||||
vec64 v_src0 = vld1(src0 + x);
|
||||
vec64 v_src1 = vld1(src1 + x);
|
||||
vec64 v_dst;
|
||||
|
||||
op(v_src0, v_src1, v_dst);
|
||||
vst1(dst + x, v_dst);
|
||||
}
|
||||
|
||||
for (; x < size.width; ++x)
|
||||
{
|
||||
op(src0 + x, src1 + x, dst + x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} }
|
||||
|
||||
#endif // CAROTENE_NEON
|
||||
|
||||
#endif
|
||||
+434
@@ -0,0 +1,434 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
#include "remap.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
bool isWarpAffineNearestNeighborSupported(const Size2D &ssize)
|
||||
{
|
||||
#if SIZE_MAX > UINT32_MAX
|
||||
return !(ssize.width > 0xffffFFFF || ssize.height > 0xffffFFFF) && // Restrict image size since internal index evaluation
|
||||
// is performed with u32
|
||||
isSupportedConfiguration();
|
||||
#else
|
||||
(void)ssize;
|
||||
return isSupportedConfiguration();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isWarpAffineLinearSupported(const Size2D &ssize)
|
||||
{
|
||||
#if SIZE_MAX > UINT32_MAX
|
||||
return !(ssize.width > 0xffffFFFF || ssize.height > 0xffffFFFF) && // Restrict image size since internal index evaluation
|
||||
// is performed with u32
|
||||
isSupportedConfiguration();
|
||||
#else
|
||||
(void)ssize;
|
||||
return isSupportedConfiguration();
|
||||
#endif
|
||||
}
|
||||
|
||||
void warpAffineNearestNeighbor(const Size2D &ssize, const Size2D &dsize,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
const f32 * m,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
BORDER_MODE borderMode, u8 borderValue)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isWarpAffineNearestNeighborSupported(ssize));
|
||||
#ifdef CAROTENE_NEON
|
||||
using namespace internal;
|
||||
|
||||
s32 _map[BLOCK_SIZE * BLOCK_SIZE + 16];
|
||||
s32 * map = alignPtr(_map, 16);
|
||||
|
||||
int32x4_t v_width4 = vdupq_n_s32(ssize.width - 1), v_height4 = vdupq_n_s32(ssize.height - 1);
|
||||
int32x4_t v_step4 = vdupq_n_s32(srcStride);
|
||||
float32x4_t v_4 = vdupq_n_f32(4.0f);
|
||||
|
||||
float32x4_t v_m0 = vdupq_n_f32(m[0]);
|
||||
float32x4_t v_m1 = vdupq_n_f32(m[1]);
|
||||
float32x4_t v_m2 = vdupq_n_f32(m[2]);
|
||||
float32x4_t v_m3 = vdupq_n_f32(m[3]);
|
||||
float32x4_t v_m4 = vdupq_n_f32(m[4]);
|
||||
float32x4_t v_m5 = vdupq_n_f32(m[5]);
|
||||
|
||||
if (borderMode == BORDER_MODE_REPLICATE)
|
||||
{
|
||||
int32x4_t v_zero4 = vdupq_n_s32(0);
|
||||
|
||||
for (size_t i = 0; i < dsize.height; i += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockHeight = std::min<size_t>(BLOCK_SIZE, dsize.height - i);
|
||||
for (size_t j = 0; j < dsize.width; j += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockWidth = std::min<size_t>(BLOCK_SIZE, dsize.width - j);
|
||||
|
||||
// compute table
|
||||
for (size_t y = 0; y < blockHeight; ++y)
|
||||
{
|
||||
s32 * map_row = getRowPtr(&map[0], blockWidth * sizeof(s32), y);
|
||||
|
||||
size_t x = 0, y_ = y + i;
|
||||
f32 indeces[4] = { j + 0.0f, j + 1.0f, j + 2.0f, j + 3.0f };
|
||||
float32x4_t v_x = vld1q_f32(indeces), v_y = vdupq_n_f32(y_);
|
||||
float32x4_t v_yx = vmlaq_f32(v_m4, v_m2, v_y), v_yy = vmlaq_f32(v_m5, v_m3, v_y);
|
||||
|
||||
for ( ; x + 4 <= blockWidth; x += 4)
|
||||
{
|
||||
float32x4_t v_src_xf = vmlaq_f32(v_yx, v_m0, v_x);
|
||||
float32x4_t v_src_yf = vmlaq_f32(v_yy, v_m1, v_x);
|
||||
|
||||
int32x4_t v_src_x = vmaxq_s32(v_zero4, vminq_s32(v_width4, vcvtq_s32_f32(v_src_xf)));
|
||||
int32x4_t v_src_y = vmaxq_s32(v_zero4, vminq_s32(v_height4, vcvtq_s32_f32(v_src_yf)));
|
||||
int32x4_t v_src_index = vmlaq_s32(v_src_x, v_src_y, v_step4);
|
||||
vst1q_s32(map_row + x, v_src_index);
|
||||
|
||||
v_x = vaddq_f32(v_x, v_4);
|
||||
}
|
||||
|
||||
f32 yx = m[2] * y_ + m[4], yy = m[3] * y_ + m[5];
|
||||
for (ptrdiff_t x_ = x + j; x < blockWidth; ++x, ++x_)
|
||||
{
|
||||
f32 src_x_f = m[0] * x_ + yx;
|
||||
f32 src_y_f = m[1] * x_ + yy;
|
||||
s32 src_x = floorf(src_x_f), src_y = floorf(src_y_f);
|
||||
|
||||
src_x = std::max(0, std::min<s32>(ssize.width - 1, src_x));
|
||||
src_y = std::max(0, std::min<s32>(ssize.height - 1, src_y));
|
||||
map_row[x] = src_y * srcStride + src_x;
|
||||
}
|
||||
}
|
||||
|
||||
// make remap
|
||||
remapNearestNeighborReplicate(Size2D(blockWidth, blockHeight), srcBase, &map[0],
|
||||
getRowPtr(dstBase, dstStride, i) + j, dstStride);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (borderMode == BORDER_MODE_CONSTANT)
|
||||
{
|
||||
int32x4_t v_m1_4 = vdupq_n_s32(-1);
|
||||
float32x4_t v_zero4 = vdupq_n_f32(0.0f);
|
||||
|
||||
for (size_t i = 0; i < dsize.height; i += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockHeight = std::min<size_t>(BLOCK_SIZE, dsize.height - i);
|
||||
for (size_t j = 0; j < dsize.width; j += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockWidth = std::min<size_t>(BLOCK_SIZE, dsize.width - j);
|
||||
|
||||
// compute table
|
||||
for (size_t y = 0; y < blockHeight; ++y)
|
||||
{
|
||||
s32 * map_row = getRowPtr(&map[0], blockWidth * sizeof(s32), y);
|
||||
|
||||
size_t x = 0, y_ = y + i;
|
||||
f32 indeces[4] = { j + 0.0f, j + 1.0f, j + 2.0f, j + 3.0f };
|
||||
float32x4_t v_x = vld1q_f32(indeces), v_y = vdupq_n_f32(y_);
|
||||
float32x4_t v_yx = vmlaq_f32(v_m4, v_m2, v_y), v_yy = vmlaq_f32(v_m5, v_m3, v_y);
|
||||
|
||||
for ( ; x + 4 <= blockWidth; x += 4)
|
||||
{
|
||||
float32x4_t v_src_xf = vmlaq_f32(v_yx, v_m0, v_x);
|
||||
float32x4_t v_src_yf = vmlaq_f32(v_yy, v_m1, v_x);
|
||||
|
||||
int32x4_t v_src_x = vcvtq_s32_f32(v_src_xf);
|
||||
int32x4_t v_src_y = vcvtq_s32_f32(v_src_yf);
|
||||
uint32x4_t v_mask = vandq_u32(vandq_u32(vcgeq_f32(v_src_xf, v_zero4), vcleq_s32(v_src_x, v_width4)),
|
||||
vandq_u32(vcgeq_f32(v_src_yf, v_zero4), vcleq_s32(v_src_y, v_height4)));
|
||||
int32x4_t v_src_index = vbslq_s32(v_mask, vmlaq_s32(v_src_x, v_src_y, v_step4), v_m1_4);
|
||||
vst1q_s32(map_row + x, v_src_index);
|
||||
|
||||
v_x = vaddq_f32(v_x, v_4);
|
||||
}
|
||||
|
||||
f32 yx = m[2] * y_ + m[4], yy = m[3] * y_ + m[5];
|
||||
for (ptrdiff_t x_ = x + j; x < blockWidth; ++x, ++x_)
|
||||
{
|
||||
f32 src_x_f = m[0] * x_ + yx;
|
||||
f32 src_y_f = m[1] * x_ + yy;
|
||||
s32 src_x = floorf(src_x_f), src_y = floorf(src_y_f);
|
||||
|
||||
map_row[x] = (src_x >= 0) && (src_x < (s32)ssize.width) &&
|
||||
(src_y >= 0) && (src_y < (s32)ssize.height) ? src_y * srcStride + src_x : -1;
|
||||
}
|
||||
}
|
||||
|
||||
// make remap
|
||||
remapNearestNeighborConst(Size2D(blockWidth, blockHeight), srcBase, &map[0],
|
||||
getRowPtr(dstBase, dstStride, i) + j, dstStride, borderValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)ssize;
|
||||
(void)dsize;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)m;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)borderMode;
|
||||
(void)borderValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
void warpAffineLinear(const Size2D &ssize, const Size2D &dsize,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
const f32 * m,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
BORDER_MODE borderMode, u8 borderValue)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isWarpAffineLinearSupported(ssize));
|
||||
#ifdef CAROTENE_NEON
|
||||
using namespace internal;
|
||||
|
||||
s32 _map[((BLOCK_SIZE * BLOCK_SIZE) << 2) + 16];
|
||||
f32 _coeffs[((BLOCK_SIZE * BLOCK_SIZE) << 1) + 16];
|
||||
s32 * map = alignPtr(_map, 16);
|
||||
f32 * coeffs = alignPtr(_coeffs, 16);
|
||||
|
||||
int32x4_t v_width4 = vdupq_n_s32(ssize.width - 1), v_height4 = vdupq_n_s32(ssize.height - 1);
|
||||
int32x4_t v_step4 = vdupq_n_s32(srcStride), v_1 = vdupq_n_s32(1);
|
||||
float32x4_t v_zero4f = vdupq_n_f32(0.0f), v_one4f = vdupq_n_f32(1.0f);
|
||||
|
||||
float32x4_t v_m0 = vdupq_n_f32(m[0]);
|
||||
float32x4_t v_m1 = vdupq_n_f32(m[1]);
|
||||
float32x4_t v_m2 = vdupq_n_f32(m[2]);
|
||||
float32x4_t v_m3 = vdupq_n_f32(m[3]);
|
||||
float32x4_t v_m4 = vdupq_n_f32(m[4]);
|
||||
float32x4_t v_m5 = vdupq_n_f32(m[5]);
|
||||
|
||||
if (borderMode == BORDER_MODE_REPLICATE)
|
||||
{
|
||||
int32x4_t v_zero4 = vdupq_n_s32(0);
|
||||
|
||||
for (size_t i = 0; i < dsize.height; i += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockHeight = std::min<size_t>(BLOCK_SIZE, dsize.height - i);
|
||||
for (size_t j = 0; j < dsize.width; j += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockWidth = std::min<size_t>(BLOCK_SIZE, dsize.width - j);
|
||||
|
||||
// compute table
|
||||
for (size_t y = 0; y < blockHeight; ++y)
|
||||
{
|
||||
s32 * map_row = getRowPtr(map, blockWidth * sizeof(s32) * 4, y);
|
||||
f32 * coeff_row = getRowPtr(coeffs, blockWidth * sizeof(f32) * 2, y);
|
||||
|
||||
size_t x = 0, y_ = y + i;
|
||||
f32 indeces[4] = { j + 0.0f, j + 1.0f, j + 2.0f, j + 3.0f };
|
||||
float32x4_t v_x = vld1q_f32(indeces), v_y = vdupq_n_f32(y_), v_4 = vdupq_n_f32(4.0f);
|
||||
float32x4_t v_yx = vmlaq_f32(v_m4, v_m2, v_y), v_yy = vmlaq_f32(v_m5, v_m3, v_y);
|
||||
|
||||
for ( ; x + 4 <= blockWidth; x += 4)
|
||||
{
|
||||
float32x4_t v_src_xf = vmlaq_f32(v_yx, v_m0, v_x);
|
||||
float32x4_t v_src_yf = vmlaq_f32(v_yy, v_m1, v_x);
|
||||
|
||||
int32x4_t v_src_x = vcvtq_s32_f32(v_src_xf);
|
||||
int32x4_t v_src_y = vcvtq_s32_f32(v_src_yf);
|
||||
|
||||
float32x4x2_t v_coeff;
|
||||
v_coeff.val[0] = vsubq_f32(v_src_xf, vcvtq_f32_s32(v_src_x));
|
||||
v_coeff.val[1] = vsubq_f32(v_src_yf, vcvtq_f32_s32(v_src_y));
|
||||
uint32x4_t v_maskx = vcltq_f32(v_coeff.val[0], v_zero4f);
|
||||
uint32x4_t v_masky = vcltq_f32(v_coeff.val[1], v_zero4f);
|
||||
v_coeff.val[0] = vbslq_f32(v_maskx, vaddq_f32(v_one4f, v_coeff.val[0]), v_coeff.val[0]);
|
||||
v_coeff.val[1] = vbslq_f32(v_masky, vaddq_f32(v_one4f, v_coeff.val[1]), v_coeff.val[1]);
|
||||
v_src_x = vbslq_s32(v_maskx, vsubq_s32(v_src_x, v_1), v_src_x);
|
||||
v_src_y = vbslq_s32(v_masky, vsubq_s32(v_src_y, v_1), v_src_y);
|
||||
|
||||
int32x4_t v_dst0_x = vmaxq_s32(v_zero4, vminq_s32(v_width4, v_src_x));
|
||||
int32x4_t v_dst0_y = vmaxq_s32(v_zero4, vminq_s32(v_height4, v_src_y));
|
||||
int32x4_t v_dst1_x = vmaxq_s32(v_zero4, vminq_s32(v_width4, vaddq_s32(v_1, v_src_x)));
|
||||
int32x4_t v_dst1_y = vmaxq_s32(v_zero4, vminq_s32(v_height4, vaddq_s32(v_1, v_src_y)));
|
||||
|
||||
int32x4x4_t v_dst_index;
|
||||
v_dst_index.val[0] = vmlaq_s32(v_dst0_x, v_dst0_y, v_step4);
|
||||
v_dst_index.val[1] = vmlaq_s32(v_dst1_x, v_dst0_y, v_step4);
|
||||
v_dst_index.val[2] = vmlaq_s32(v_dst0_x, v_dst1_y, v_step4);
|
||||
v_dst_index.val[3] = vmlaq_s32(v_dst1_x, v_dst1_y, v_step4);
|
||||
|
||||
vst2q_f32(coeff_row + (x << 1), v_coeff);
|
||||
vst4q_s32(map_row + (x << 2), v_dst_index);
|
||||
|
||||
v_x = vaddq_f32(v_x, v_4);
|
||||
}
|
||||
|
||||
f32 yx = m[2] * y_ + m[4], yy = m[3] * y_ + m[5];
|
||||
for (ptrdiff_t x_ = x + j; x < blockWidth; ++x, ++x_)
|
||||
{
|
||||
f32 src_x_f = m[0] * x_ + yx;
|
||||
f32 src_y_f = m[1] * x_ + yy;
|
||||
|
||||
s32 src0_x = (s32)floorf(src_x_f);
|
||||
s32 src0_y = (s32)floorf(src_y_f);
|
||||
|
||||
coeff_row[(x << 1) + 0] = src_x_f - src0_x;
|
||||
coeff_row[(x << 1) + 1] = src_y_f - src0_y;
|
||||
|
||||
s32 src1_y = std::max(0, std::min<s32>(ssize.height - 1, src0_y + 1));
|
||||
src0_y = std::max(0, std::min<s32>(ssize.height - 1, src0_y));
|
||||
s32 src1_x = std::max(0, std::min<s32>(ssize.width - 1, src0_x + 1));
|
||||
src0_x = std::max(0, std::min<s32>(ssize.width - 1, src0_x));
|
||||
|
||||
map_row[(x << 2) + 0] = src0_y * srcStride + src0_x;
|
||||
map_row[(x << 2) + 1] = src0_y * srcStride + src1_x;
|
||||
map_row[(x << 2) + 2] = src1_y * srcStride + src0_x;
|
||||
map_row[(x << 2) + 3] = src1_y * srcStride + src1_x;
|
||||
}
|
||||
}
|
||||
|
||||
remapLinearReplicate(Size2D(blockWidth, blockHeight),
|
||||
srcBase, &map[0], &coeffs[0],
|
||||
getRowPtr(dstBase, dstStride, i) + j, dstStride);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (borderMode == BORDER_MODE_CONSTANT)
|
||||
{
|
||||
float32x4_t v_zero4 = vdupq_n_f32(0.0f);
|
||||
int32x4_t v_m1_4 = vdupq_n_s32(-1);
|
||||
|
||||
for (size_t i = 0; i < dsize.height; i += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockHeight = std::min<size_t>(BLOCK_SIZE, dsize.height - i);
|
||||
for (size_t j = 0; j < dsize.width; j += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockWidth = std::min<size_t>(BLOCK_SIZE, dsize.width - j);
|
||||
|
||||
// compute table
|
||||
for (size_t y = 0; y < blockHeight; ++y)
|
||||
{
|
||||
s32 * map_row = getRowPtr(map, blockWidth * sizeof(s32) * 4, y);
|
||||
f32 * coeff_row = getRowPtr(coeffs, blockWidth * sizeof(f32) * 2, y);
|
||||
|
||||
size_t x = 0, y_ = y + i;
|
||||
f32 indeces[4] = { j + 0.0f, j + 1.0f, j + 2.0f, j + 3.0f };
|
||||
float32x4_t v_x = vld1q_f32(indeces), v_y = vdupq_n_f32(y_), v_4 = vdupq_n_f32(4.0f);
|
||||
float32x4_t v_yx = vmlaq_f32(v_m4, v_m2, v_y), v_yy = vmlaq_f32(v_m5, v_m3, v_y);
|
||||
|
||||
for ( ; x + 4 <= blockWidth; x += 4)
|
||||
{
|
||||
float32x4_t v_src_xf = vmlaq_f32(v_yx, v_m0, v_x);
|
||||
float32x4_t v_src_yf = vmlaq_f32(v_yy, v_m1, v_x);
|
||||
|
||||
int32x4_t v_src_x0 = vcvtq_s32_f32(v_src_xf);
|
||||
int32x4_t v_src_y0 = vcvtq_s32_f32(v_src_yf);
|
||||
|
||||
float32x4x2_t v_coeff;
|
||||
v_coeff.val[0] = vsubq_f32(v_src_xf, vcvtq_f32_s32(v_src_x0));
|
||||
v_coeff.val[1] = vsubq_f32(v_src_yf, vcvtq_f32_s32(v_src_y0));
|
||||
uint32x4_t v_maskx = vcltq_f32(v_coeff.val[0], v_zero4f);
|
||||
uint32x4_t v_masky = vcltq_f32(v_coeff.val[1], v_zero4f);
|
||||
v_coeff.val[0] = vbslq_f32(v_maskx, vaddq_f32(v_one4f, v_coeff.val[0]), v_coeff.val[0]);
|
||||
v_coeff.val[1] = vbslq_f32(v_masky, vaddq_f32(v_one4f, v_coeff.val[1]), v_coeff.val[1]);
|
||||
v_src_x0 = vbslq_s32(v_maskx, vsubq_s32(v_src_x0, v_1), v_src_x0);
|
||||
v_src_y0 = vbslq_s32(v_masky, vsubq_s32(v_src_y0, v_1), v_src_y0);
|
||||
|
||||
int32x4_t v_src_x1 = vaddq_s32(v_src_x0, v_1);
|
||||
int32x4_t v_src_y1 = vaddq_s32(v_src_y0, v_1);
|
||||
|
||||
int32x4x4_t v_dst_index;
|
||||
v_dst_index.val[0] = vmlaq_s32(v_src_x0, v_src_y0, v_step4);
|
||||
v_dst_index.val[1] = vmlaq_s32(v_src_x1, v_src_y0, v_step4);
|
||||
v_dst_index.val[2] = vmlaq_s32(v_src_x0, v_src_y1, v_step4);
|
||||
v_dst_index.val[3] = vmlaq_s32(v_src_x1, v_src_y1, v_step4);
|
||||
|
||||
uint32x4_t v_mask_x0 = vandq_u32(vcgeq_f32(v_src_xf, v_zero4), vcleq_s32(v_src_x0, v_width4));
|
||||
uint32x4_t v_mask_x1 = vandq_u32(vcgeq_f32(vaddq_f32(v_src_xf, v_one4f), v_zero4), vcleq_s32(v_src_x1, v_width4));
|
||||
uint32x4_t v_mask_y0 = vandq_u32(vcgeq_f32(v_src_yf, v_zero4), vcleq_s32(v_src_y0, v_height4));
|
||||
uint32x4_t v_mask_y1 = vandq_u32(vcgeq_f32(vaddq_f32(v_src_yf, v_one4f), v_zero4), vcleq_s32(v_src_y1, v_height4));
|
||||
|
||||
v_dst_index.val[0] = vbslq_s32(vandq_u32(v_mask_x0, v_mask_y0), v_dst_index.val[0], v_m1_4);
|
||||
v_dst_index.val[1] = vbslq_s32(vandq_u32(v_mask_x1, v_mask_y0), v_dst_index.val[1], v_m1_4);
|
||||
v_dst_index.val[2] = vbslq_s32(vandq_u32(v_mask_x0, v_mask_y1), v_dst_index.val[2], v_m1_4);
|
||||
v_dst_index.val[3] = vbslq_s32(vandq_u32(v_mask_x1, v_mask_y1), v_dst_index.val[3], v_m1_4);
|
||||
|
||||
vst2q_f32(coeff_row + (x << 1), v_coeff);
|
||||
vst4q_s32(map_row + (x << 2), v_dst_index);
|
||||
|
||||
v_x = vaddq_f32(v_x, v_4);
|
||||
}
|
||||
|
||||
f32 yx = m[2] * y_ + m[4], yy = m[3] * y_ + m[5];
|
||||
for (ptrdiff_t x_ = x + j; x < blockWidth; ++x, ++x_)
|
||||
{
|
||||
f32 src_x_f = m[0] * x_ + yx;
|
||||
f32 src_y_f = m[1] * x_ + yy;
|
||||
|
||||
s32 src0_x = (s32)floorf(src_x_f), src1_x = src0_x + 1;
|
||||
s32 src0_y = (s32)floorf(src_y_f), src1_y = src0_y + 1;
|
||||
|
||||
coeff_row[(x << 1) + 0] = src_x_f - src0_x;
|
||||
coeff_row[(x << 1) + 1] = src_y_f - src0_y;
|
||||
|
||||
map_row[(x << 2) + 0] = (src0_x >= 0) && (src0_x < (s32)ssize.width) &&
|
||||
(src0_y >= 0) && (src0_y < (s32)ssize.height) ? src0_y * srcStride + src0_x : -1;
|
||||
map_row[(x << 2) + 1] = (src1_x >= 0) && (src1_x < (s32)ssize.width) &&
|
||||
(src0_y >= 0) && (src0_y < (s32)ssize.height) ? src0_y * srcStride + src1_x : -1;
|
||||
map_row[(x << 2) + 2] = (src0_x >= 0) && (src0_x < (s32)ssize.width) &&
|
||||
(src1_y >= 0) && (src1_y < (s32)ssize.height) ? src1_y * srcStride + src0_x : -1;
|
||||
map_row[(x << 2) + 3] = (src1_x >= 0) && (src1_x < (s32)ssize.width) &&
|
||||
(src1_y >= 0) && (src1_y < (s32)ssize.height) ? src1_y * srcStride + src1_x : -1;
|
||||
}
|
||||
}
|
||||
|
||||
remapLinearConst(Size2D(blockWidth, blockHeight),
|
||||
srcBase, &map[0], &coeffs[0],
|
||||
getRowPtr(dstBase, dstStride, i) + j, dstStride, borderValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)ssize;
|
||||
(void)dsize;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)m;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)borderMode;
|
||||
(void)borderValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
+464
@@ -0,0 +1,464 @@
|
||||
/*
|
||||
* 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
|
||||
* (3-clause BSD License)
|
||||
*
|
||||
* Copyright (C) 2015, NVIDIA Corporation, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the names of the copyright holders nor the names of the contributors
|
||||
* may 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 copyright holders 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "remap.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
bool isWarpPerspectiveNearestNeighborSupported(const Size2D &ssize)
|
||||
{
|
||||
#if SIZE_MAX > UINT32_MAX
|
||||
return !(ssize.width > 0xffffFFFF || ssize.height > 0xffffFFFF) && // Restrict image size since internal index evaluation
|
||||
// is performed with u32
|
||||
isSupportedConfiguration();
|
||||
#else
|
||||
(void)ssize;
|
||||
return isSupportedConfiguration();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isWarpPerspectiveLinearSupported(const Size2D &ssize)
|
||||
{
|
||||
#if SIZE_MAX > UINT32_MAX
|
||||
return !(ssize.width > 0xffffFFFF || ssize.height > 0xffffFFFF) && // Restrict image size since internal index evaluation
|
||||
// is performed with u32
|
||||
isSupportedConfiguration();
|
||||
#else
|
||||
(void)ssize;
|
||||
return isSupportedConfiguration();
|
||||
#endif
|
||||
}
|
||||
|
||||
void warpPerspectiveNearestNeighbor(const Size2D &ssize, const Size2D &dsize,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
const f32 * m,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
BORDER_MODE borderMode, u8 borderValue)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isWarpPerspectiveNearestNeighborSupported(ssize));
|
||||
#ifdef CAROTENE_NEON
|
||||
using namespace internal;
|
||||
|
||||
s32 _map[BLOCK_SIZE * BLOCK_SIZE + 16];
|
||||
s32 * map = alignPtr(_map, 16);
|
||||
|
||||
int32x4_t v_width4 = vdupq_n_s32(ssize.width - 1), v_height4 = vdupq_n_s32(ssize.height - 1);
|
||||
int32x4_t v_step4 = vdupq_n_s32(srcStride);
|
||||
float32x4_t v_4 = vdupq_n_f32(4.0f);
|
||||
|
||||
float32x4_t v_m0 = vdupq_n_f32(m[0]);
|
||||
float32x4_t v_m1 = vdupq_n_f32(m[1]);
|
||||
float32x4_t v_m2 = vdupq_n_f32(m[2]);
|
||||
float32x4_t v_m3 = vdupq_n_f32(m[3]);
|
||||
float32x4_t v_m4 = vdupq_n_f32(m[4]);
|
||||
float32x4_t v_m5 = vdupq_n_f32(m[5]);
|
||||
float32x4_t v_m6 = vdupq_n_f32(m[6]);
|
||||
float32x4_t v_m7 = vdupq_n_f32(m[7]);
|
||||
float32x4_t v_m8 = vdupq_n_f32(m[8]);
|
||||
|
||||
if (borderMode == BORDER_MODE_REPLICATE)
|
||||
{
|
||||
int32x4_t v_zero4 = vdupq_n_s32(0);
|
||||
|
||||
for (size_t i = 0; i < dsize.height; i += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockHeight = std::min<size_t>(BLOCK_SIZE, dsize.height - i);
|
||||
for (size_t j = 0; j < dsize.width; j += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockWidth = std::min<size_t>(BLOCK_SIZE, dsize.width - j);
|
||||
|
||||
// compute table
|
||||
for (size_t y = 0; y < blockHeight; ++y)
|
||||
{
|
||||
s32 * map_row = getRowPtr(&map[0], blockWidth * sizeof(s32), y);
|
||||
|
||||
size_t x = 0, y_ = y + i;
|
||||
f32 indeces[4] = { j + 0.0f, j + 1.0f, j + 2.0f, j + 3.0f };
|
||||
float32x4_t v_x = vld1q_f32(indeces), v_y = vdupq_n_f32(y_);
|
||||
float32x4_t v_yx = vmlaq_f32(v_m6, v_m3, v_y), v_yy = vmlaq_f32(v_m7, v_m4, v_y),
|
||||
v_yw = vmlaq_f32(v_m8, v_m5, v_y);
|
||||
|
||||
for ( ; x + 4 <= blockWidth; x += 4)
|
||||
{
|
||||
float32x4_t v_src_xf = vmlaq_f32(v_yx, v_m0, v_x);
|
||||
float32x4_t v_src_yf = vmlaq_f32(v_yy, v_m1, v_x);
|
||||
float32x4_t v_wf = vrecpq_f32(vmlaq_f32(v_yw, v_m2, v_x));
|
||||
v_src_xf = vmulq_f32(v_wf, v_src_xf);
|
||||
v_src_yf = vmulq_f32(v_wf, v_src_yf);
|
||||
|
||||
int32x4_t v_src_x = vmaxq_s32(v_zero4, vminq_s32(v_width4, vcvtq_s32_f32(v_src_xf)));
|
||||
int32x4_t v_src_y = vmaxq_s32(v_zero4, vminq_s32(v_height4, vcvtq_s32_f32(v_src_yf)));
|
||||
int32x4_t v_src_index = vmlaq_s32(v_src_x, v_src_y, v_step4);
|
||||
vst1q_s32(map_row + x, v_src_index);
|
||||
|
||||
v_x = vaddq_f32(v_x, v_4);
|
||||
}
|
||||
|
||||
f32 yx = m[3] * y_ + m[6], yy = m[4] * y_ + m[7], yw = m[5] * y_ + m[8];
|
||||
for (ptrdiff_t x_ = x + j; x < blockWidth; ++x, ++x_)
|
||||
{
|
||||
f32 w_f = 1.0f / (m[2] * x_ + yw);
|
||||
f32 src_x_f = (m[0] * x_ + yx) * w_f;
|
||||
f32 src_y_f = (m[1] * x_ + yy) * w_f;
|
||||
s32 src_x = floorf(src_x_f), src_y = floorf(src_y_f);
|
||||
|
||||
src_x = std::max(0, std::min<s32>(ssize.width - 1, src_x));
|
||||
src_y = std::max(0, std::min<s32>(ssize.height - 1, src_y));
|
||||
map_row[x] = src_y * srcStride + src_x;
|
||||
}
|
||||
}
|
||||
|
||||
// make remap
|
||||
remapNearestNeighborReplicate(Size2D(blockWidth, blockHeight), srcBase, &map[0],
|
||||
getRowPtr(dstBase, dstStride, i) + j, dstStride);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (borderMode == BORDER_MODE_CONSTANT)
|
||||
{
|
||||
int32x4_t v_m1_4 = vdupq_n_s32(-1);
|
||||
float32x4_t v_zero4 = vdupq_n_f32(0.0f);
|
||||
|
||||
for (size_t i = 0; i < dsize.height; i += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockHeight = std::min<size_t>(BLOCK_SIZE, dsize.height - i);
|
||||
for (size_t j = 0; j < dsize.width; j += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockWidth = std::min<size_t>(BLOCK_SIZE, dsize.width - j);
|
||||
|
||||
// compute table
|
||||
for (size_t y = 0; y < blockHeight; ++y)
|
||||
{
|
||||
s32 * map_row = getRowPtr(&map[0], blockWidth * sizeof(s32), y);
|
||||
|
||||
size_t x = 0, y_ = y + i;
|
||||
f32 indeces[4] = { j + 0.0f, j + 1.0f, j + 2.0f, j + 3.0f };
|
||||
float32x4_t v_x = vld1q_f32(indeces), v_y = vdupq_n_f32(y_);
|
||||
float32x4_t v_yx = vmlaq_f32(v_m6, v_m3, v_y), v_yy = vmlaq_f32(v_m7, v_m4, v_y),
|
||||
v_yw = vmlaq_f32(v_m8, v_m5, v_y);
|
||||
|
||||
for ( ; x + 4 <= blockWidth; x += 4)
|
||||
{
|
||||
float32x4_t v_src_xf = vmlaq_f32(v_yx, v_m0, v_x);
|
||||
float32x4_t v_src_yf = vmlaq_f32(v_yy, v_m1, v_x);
|
||||
float32x4_t v_wf = vrecpq_f32(vmlaq_f32(v_yw, v_m2, v_x));
|
||||
v_src_xf = vmulq_f32(v_wf, v_src_xf);
|
||||
v_src_yf = vmulq_f32(v_wf, v_src_yf);
|
||||
|
||||
int32x4_t v_src_x = vcvtq_s32_f32(v_src_xf);
|
||||
int32x4_t v_src_y = vcvtq_s32_f32(v_src_yf);
|
||||
uint32x4_t v_mask = vandq_u32(vandq_u32(vcgeq_f32(v_src_xf, v_zero4), vcleq_s32(v_src_x, v_width4)),
|
||||
vandq_u32(vcgeq_f32(v_src_yf, v_zero4), vcleq_s32(v_src_y, v_height4)));
|
||||
int32x4_t v_src_index = vbslq_s32(v_mask, vmlaq_s32(v_src_x, v_src_y, v_step4), v_m1_4);
|
||||
vst1q_s32(map_row + x, v_src_index);
|
||||
|
||||
v_x = vaddq_f32(v_x, v_4);
|
||||
}
|
||||
|
||||
f32 yx = m[3] * y_ + m[6], yy = m[4] * y_ + m[7], yw = m[5] * y_ + m[8];
|
||||
for (ptrdiff_t x_ = x + j; x < blockWidth; ++x, ++x_)
|
||||
{
|
||||
f32 w_f = 1.0f / (m[2] * x_ + yw);
|
||||
f32 src_x_f = (m[0] * x_ + yx) * w_f;
|
||||
f32 src_y_f = (m[1] * x_ + yy) * w_f;
|
||||
s32 src_x = floorf(src_x_f), src_y = floorf(src_y_f);
|
||||
|
||||
map_row[x] = (src_x >= 0) && (src_x < (s32)ssize.width) &&
|
||||
(src_y >= 0) && (src_y < (s32)ssize.height) ? src_y * srcStride + src_x : -1;
|
||||
}
|
||||
}
|
||||
|
||||
// make remap
|
||||
remapNearestNeighborConst(Size2D(blockWidth, blockHeight), srcBase, &map[0],
|
||||
getRowPtr(dstBase, dstStride, i) + j, dstStride, borderValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)ssize;
|
||||
(void)dsize;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)m;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)borderMode;
|
||||
(void)borderValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
void warpPerspectiveLinear(const Size2D &ssize, const Size2D &dsize,
|
||||
const u8 * srcBase, ptrdiff_t srcStride,
|
||||
const f32 * m,
|
||||
u8 * dstBase, ptrdiff_t dstStride,
|
||||
BORDER_MODE borderMode, u8 borderValue)
|
||||
{
|
||||
internal::assertSupportedConfiguration(isWarpPerspectiveLinearSupported(ssize));
|
||||
#ifdef CAROTENE_NEON
|
||||
using namespace internal;
|
||||
|
||||
s32 _map[((BLOCK_SIZE * BLOCK_SIZE) << 2) + 16];
|
||||
f32 _coeffs[((BLOCK_SIZE * BLOCK_SIZE) << 1) + 16];
|
||||
s32 * map = alignPtr(_map, 16);
|
||||
f32 * coeffs = alignPtr(_coeffs, 16);
|
||||
|
||||
int32x4_t v_width4 = vdupq_n_s32(ssize.width - 1), v_height4 = vdupq_n_s32(ssize.height - 1);
|
||||
int32x4_t v_step4 = vdupq_n_s32(srcStride), v_1 = vdupq_n_s32(1);
|
||||
float32x4_t v_zero4f = vdupq_n_f32(0.0f), v_one4f = vdupq_n_f32(1.0f);
|
||||
|
||||
float32x4_t v_4 = vdupq_n_f32(4.0f);
|
||||
|
||||
float32x4_t v_m0 = vdupq_n_f32(m[0]);
|
||||
float32x4_t v_m1 = vdupq_n_f32(m[1]);
|
||||
float32x4_t v_m2 = vdupq_n_f32(m[2]);
|
||||
float32x4_t v_m3 = vdupq_n_f32(m[3]);
|
||||
float32x4_t v_m4 = vdupq_n_f32(m[4]);
|
||||
float32x4_t v_m5 = vdupq_n_f32(m[5]);
|
||||
float32x4_t v_m6 = vdupq_n_f32(m[6]);
|
||||
float32x4_t v_m7 = vdupq_n_f32(m[7]);
|
||||
float32x4_t v_m8 = vdupq_n_f32(m[8]);
|
||||
|
||||
if (borderMode == BORDER_MODE_REPLICATE)
|
||||
{
|
||||
int32x4_t v_zero4 = vdupq_n_s32(0);
|
||||
|
||||
for (size_t i = 0; i < dsize.height; i += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockHeight = std::min<size_t>(BLOCK_SIZE, dsize.height - i);
|
||||
for (size_t j = 0; j < dsize.width; j += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockWidth = std::min<size_t>(BLOCK_SIZE, dsize.width - j);
|
||||
|
||||
// compute table
|
||||
for (size_t y = 0; y < blockHeight; ++y)
|
||||
{
|
||||
s32 * map_row = getRowPtr(map, blockWidth * sizeof(s32) * 4, y);
|
||||
f32 * coeff_row = getRowPtr(coeffs, blockWidth * sizeof(f32) * 2, y);
|
||||
|
||||
size_t x = 0, y_ = y + i;
|
||||
f32 indeces[4] = { j + 0.0f, j + 1.0f, j + 2.0f, j + 3.0f };
|
||||
float32x4_t v_x = vld1q_f32(indeces), v_y = vdupq_n_f32(y_);
|
||||
float32x4_t v_yx = vmlaq_f32(v_m6, v_m3, v_y), v_yy = vmlaq_f32(v_m7, v_m4, v_y),
|
||||
v_yw = vmlaq_f32(v_m8, v_m5, v_y);
|
||||
|
||||
for ( ; x + 4 <= blockWidth; x += 4)
|
||||
{
|
||||
float32x4_t v_src_xf = vmlaq_f32(v_yx, v_m0, v_x);
|
||||
float32x4_t v_src_yf = vmlaq_f32(v_yy, v_m1, v_x);
|
||||
float32x4_t v_wf = vrecpq_f32(vmlaq_f32(v_yw, v_m2, v_x));
|
||||
v_src_xf = vmulq_f32(v_wf, v_src_xf);
|
||||
v_src_yf = vmulq_f32(v_wf, v_src_yf);
|
||||
|
||||
int32x4_t v_src_x = vcvtq_s32_f32(v_src_xf);
|
||||
int32x4_t v_src_y = vcvtq_s32_f32(v_src_yf);
|
||||
|
||||
float32x4x2_t v_coeff;
|
||||
v_coeff.val[0] = vsubq_f32(v_src_xf, vcvtq_f32_s32(v_src_x));
|
||||
v_coeff.val[1] = vsubq_f32(v_src_yf, vcvtq_f32_s32(v_src_y));
|
||||
uint32x4_t v_maskx = vcltq_f32(v_coeff.val[0], v_zero4f);
|
||||
uint32x4_t v_masky = vcltq_f32(v_coeff.val[1], v_zero4f);
|
||||
v_coeff.val[0] = vbslq_f32(v_maskx, vaddq_f32(v_one4f, v_coeff.val[0]), v_coeff.val[0]);
|
||||
v_coeff.val[1] = vbslq_f32(v_masky, vaddq_f32(v_one4f, v_coeff.val[1]), v_coeff.val[1]);
|
||||
v_src_x = vbslq_s32(v_maskx, vsubq_s32(v_src_x, v_1), v_src_x);
|
||||
v_src_y = vbslq_s32(v_masky, vsubq_s32(v_src_y, v_1), v_src_y);
|
||||
|
||||
int32x4_t v_dst0_x = vmaxq_s32(v_zero4, vminq_s32(v_width4, v_src_x));
|
||||
int32x4_t v_dst0_y = vmaxq_s32(v_zero4, vminq_s32(v_height4, v_src_y));
|
||||
int32x4_t v_dst1_x = vmaxq_s32(v_zero4, vminq_s32(v_width4, vaddq_s32(v_1, v_src_x)));
|
||||
int32x4_t v_dst1_y = vmaxq_s32(v_zero4, vminq_s32(v_height4, vaddq_s32(v_1, v_src_y)));
|
||||
|
||||
int32x4x4_t v_dst_index;
|
||||
v_dst_index.val[0] = vmlaq_s32(v_dst0_x, v_dst0_y, v_step4);
|
||||
v_dst_index.val[1] = vmlaq_s32(v_dst1_x, v_dst0_y, v_step4);
|
||||
v_dst_index.val[2] = vmlaq_s32(v_dst0_x, v_dst1_y, v_step4);
|
||||
v_dst_index.val[3] = vmlaq_s32(v_dst1_x, v_dst1_y, v_step4);
|
||||
|
||||
vst2q_f32(coeff_row + (x << 1), v_coeff);
|
||||
vst4q_s32(map_row + (x << 2), v_dst_index);
|
||||
|
||||
v_x = vaddq_f32(v_x, v_4);
|
||||
}
|
||||
|
||||
f32 yx = m[3] * y_ + m[6], yy = m[4] * y_ + m[7], yw = m[5] * y_ + m[8];
|
||||
for (ptrdiff_t x_ = x + j; x < blockWidth; ++x, ++x_)
|
||||
{
|
||||
f32 w_f = 1.0f / (m[2] * x_ + yw);
|
||||
f32 src_x_f = (m[0] * x_ + yx) * w_f;
|
||||
f32 src_y_f = (m[1] * x_ + yy) * w_f;
|
||||
|
||||
s32 src0_x = (s32)floorf(src_x_f);
|
||||
s32 src0_y = (s32)floorf(src_y_f);
|
||||
|
||||
coeff_row[(x << 1) + 0] = src_x_f - src0_x;
|
||||
coeff_row[(x << 1) + 1] = src_y_f - src0_y;
|
||||
|
||||
s32 src1_y = std::max(0, std::min<s32>(ssize.height - 1, src0_y + 1));
|
||||
src0_y = std::max(0, std::min<s32>(ssize.height - 1, src0_y));
|
||||
s32 src1_x = std::max(0, std::min<s32>(ssize.width - 1, src0_x + 1));
|
||||
src0_x = std::max(0, std::min<s32>(ssize.width - 1, src0_x));
|
||||
|
||||
map_row[(x << 2) + 0] = src0_y * srcStride + src0_x;
|
||||
map_row[(x << 2) + 1] = src0_y * srcStride + src1_x;
|
||||
map_row[(x << 2) + 2] = src1_y * srcStride + src0_x;
|
||||
map_row[(x << 2) + 3] = src1_y * srcStride + src1_x;
|
||||
}
|
||||
}
|
||||
|
||||
remapLinearReplicate(Size2D(blockWidth, blockHeight),
|
||||
srcBase, &map[0], &coeffs[0],
|
||||
getRowPtr(dstBase, dstStride, i) + j, dstStride);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (borderMode == BORDER_MODE_CONSTANT)
|
||||
{
|
||||
float32x4_t v_zero4 = vdupq_n_f32(0.0f);
|
||||
int32x4_t v_m1_4 = vdupq_n_s32(-1);
|
||||
|
||||
for (size_t i = 0; i < dsize.height; i += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockHeight = std::min<size_t>(BLOCK_SIZE, dsize.height - i);
|
||||
for (size_t j = 0; j < dsize.width; j += BLOCK_SIZE)
|
||||
{
|
||||
size_t blockWidth = std::min<size_t>(BLOCK_SIZE, dsize.width - j);
|
||||
|
||||
// compute table
|
||||
for (size_t y = 0; y < blockHeight; ++y)
|
||||
{
|
||||
s32 * map_row = getRowPtr(map, blockWidth * sizeof(s32) * 4, y);
|
||||
f32 * coeff_row = getRowPtr(coeffs, blockWidth * sizeof(f32) * 2, y);
|
||||
|
||||
size_t x = 0, y_ = y + i;
|
||||
f32 indeces[4] = { j + 0.0f, j + 1.0f, j + 2.0f, j + 3.0f };
|
||||
float32x4_t v_x = vld1q_f32(indeces), v_y = vdupq_n_f32(y_);
|
||||
float32x4_t v_yx = vmlaq_f32(v_m6, v_m3, v_y), v_yy = vmlaq_f32(v_m7, v_m4, v_y),
|
||||
v_yw = vmlaq_f32(v_m8, v_m5, v_y);
|
||||
|
||||
for ( ; x + 4 <= blockWidth; x += 4)
|
||||
{
|
||||
float32x4_t v_src_xf = vmlaq_f32(v_yx, v_m0, v_x);
|
||||
float32x4_t v_src_yf = vmlaq_f32(v_yy, v_m1, v_x);
|
||||
float32x4_t v_wf = vrecpq_f32(vmlaq_f32(v_yw, v_m2, v_x));
|
||||
v_src_xf = vmulq_f32(v_wf, v_src_xf);
|
||||
v_src_yf = vmulq_f32(v_wf, v_src_yf);
|
||||
|
||||
int32x4_t v_src_x0 = vcvtq_s32_f32(v_src_xf);
|
||||
int32x4_t v_src_y0 = vcvtq_s32_f32(v_src_yf);
|
||||
|
||||
float32x4x2_t v_coeff;
|
||||
v_coeff.val[0] = vsubq_f32(v_src_xf, vcvtq_f32_s32(v_src_x0));
|
||||
v_coeff.val[1] = vsubq_f32(v_src_yf, vcvtq_f32_s32(v_src_y0));
|
||||
uint32x4_t v_maskx = vcltq_f32(v_coeff.val[0], v_zero4f);
|
||||
uint32x4_t v_masky = vcltq_f32(v_coeff.val[1], v_zero4f);
|
||||
v_coeff.val[0] = vbslq_f32(v_maskx, vaddq_f32(v_one4f, v_coeff.val[0]), v_coeff.val[0]);
|
||||
v_coeff.val[1] = vbslq_f32(v_masky, vaddq_f32(v_one4f, v_coeff.val[1]), v_coeff.val[1]);
|
||||
v_src_x0 = vbslq_s32(v_maskx, vsubq_s32(v_src_x0, v_1), v_src_x0);
|
||||
v_src_y0 = vbslq_s32(v_masky, vsubq_s32(v_src_y0, v_1), v_src_y0);
|
||||
|
||||
int32x4_t v_src_x1 = vaddq_s32(v_src_x0, v_1);
|
||||
int32x4_t v_src_y1 = vaddq_s32(v_src_y0, v_1);
|
||||
|
||||
int32x4x4_t v_dst_index;
|
||||
v_dst_index.val[0] = vmlaq_s32(v_src_x0, v_src_y0, v_step4);
|
||||
v_dst_index.val[1] = vmlaq_s32(v_src_x1, v_src_y0, v_step4);
|
||||
v_dst_index.val[2] = vmlaq_s32(v_src_x0, v_src_y1, v_step4);
|
||||
v_dst_index.val[3] = vmlaq_s32(v_src_x1, v_src_y1, v_step4);
|
||||
|
||||
uint32x4_t v_mask_x0 = vandq_u32(vcgeq_f32(v_src_xf, v_zero4), vcleq_s32(v_src_x0, v_width4));
|
||||
uint32x4_t v_mask_x1 = vandq_u32(vcgeq_f32(vaddq_f32(v_src_xf, v_one4f), v_zero4), vcleq_s32(v_src_x1, v_width4));
|
||||
uint32x4_t v_mask_y0 = vandq_u32(vcgeq_f32(v_src_yf, v_zero4), vcleq_s32(v_src_y0, v_height4));
|
||||
uint32x4_t v_mask_y1 = vandq_u32(vcgeq_f32(vaddq_f32(v_src_yf, v_one4f), v_zero4), vcleq_s32(v_src_y1, v_height4));
|
||||
|
||||
v_dst_index.val[0] = vbslq_s32(vandq_u32(v_mask_x0, v_mask_y0), v_dst_index.val[0], v_m1_4);
|
||||
v_dst_index.val[1] = vbslq_s32(vandq_u32(v_mask_x1, v_mask_y0), v_dst_index.val[1], v_m1_4);
|
||||
v_dst_index.val[2] = vbslq_s32(vandq_u32(v_mask_x0, v_mask_y1), v_dst_index.val[2], v_m1_4);
|
||||
v_dst_index.val[3] = vbslq_s32(vandq_u32(v_mask_x1, v_mask_y1), v_dst_index.val[3], v_m1_4);
|
||||
|
||||
vst2q_f32(coeff_row + (x << 1), v_coeff);
|
||||
vst4q_s32(map_row + (x << 2), v_dst_index);
|
||||
|
||||
v_x = vaddq_f32(v_x, v_4);
|
||||
}
|
||||
|
||||
f32 yx = m[3] * y_ + m[6], yy = m[4] * y_ + m[7], yw = m[5] * y_ + m[8];
|
||||
for (ptrdiff_t x_ = x + j; x < blockWidth; ++x, ++x_)
|
||||
{
|
||||
f32 w_f = 1.0f / (m[2] * x_ + yw);
|
||||
f32 src_x_f = (m[0] * x_ + yx) * w_f;
|
||||
f32 src_y_f = (m[1] * x_ + yy) * w_f;
|
||||
|
||||
s32 src0_x = (s32)floorf(src_x_f), src1_x = src0_x + 1;
|
||||
s32 src0_y = (s32)floorf(src_y_f), src1_y = src0_y + 1;
|
||||
|
||||
coeff_row[(x << 1) + 0] = src_x_f - src0_x;
|
||||
coeff_row[(x << 1) + 1] = src_y_f - src0_y;
|
||||
|
||||
map_row[(x << 2) + 0] = (src0_x >= 0) && (src0_x < (s32)ssize.width) &&
|
||||
(src0_y >= 0) && (src0_y < (s32)ssize.height) ? src0_y * srcStride + src0_x : -1;
|
||||
map_row[(x << 2) + 1] = (src1_x >= 0) && (src1_x < (s32)ssize.width) &&
|
||||
(src0_y >= 0) && (src0_y < (s32)ssize.height) ? src0_y * srcStride + src1_x : -1;
|
||||
map_row[(x << 2) + 2] = (src0_x >= 0) && (src0_x < (s32)ssize.width) &&
|
||||
(src1_y >= 0) && (src1_y < (s32)ssize.height) ? src1_y * srcStride + src0_x : -1;
|
||||
map_row[(x << 2) + 3] = (src1_x >= 0) && (src1_x < (s32)ssize.width) &&
|
||||
(src1_y >= 0) && (src1_y < (s32)ssize.height) ? src1_y * srcStride + src1_x : -1;
|
||||
}
|
||||
}
|
||||
|
||||
remapLinearConst(Size2D(blockWidth, blockHeight),
|
||||
srcBase, &map[0], &coeffs[0],
|
||||
getRowPtr(dstBase, dstStride, i) + j, dstStride, borderValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)ssize;
|
||||
(void)dsize;
|
||||
(void)srcBase;
|
||||
(void)srcStride;
|
||||
(void)m;
|
||||
(void)dstBase;
|
||||
(void)dstStride;
|
||||
(void)borderMode;
|
||||
(void)borderValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace CAROTENE_NS
|
||||
@@ -0,0 +1,3 @@
|
||||
downloads/
|
||||
*.dll
|
||||
ffmpeg_version.cmake
|
||||
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
# Binary branch name: ffmpeg/master_20161202
|
||||
# Binaries were created for OpenCV: 594c136d1fcbb5816c57516e50f9cbeffbd90835
|
||||
set(FFMPEG_BINARIES_COMMIT "2a19d0006415955c79431116e4634f04d5eb5a74")
|
||||
set(FFMPEG_FILE_HASH_BIN32 "f081abd9d6ca7e425d340ce586f9c090")
|
||||
set(FFMPEG_FILE_HASH_BIN64 "a423363a6eb76d362ca6c406c96c8db6")
|
||||
set(FFMPEG_FILE_HASH_CMAKE "5346ae1854fc7aa569a722e85af480ec")
|
||||
|
||||
set(FFMPEG_DOWNLOAD_URL ${OPENCV_FFMPEG_URL};$ENV{OPENCV_FFMPEG_URL};https://raw.githubusercontent.com/opencv/opencv_3rdparty/${FFMPEG_BINARIES_COMMIT}/ffmpeg/)
|
||||
|
||||
ocv_download(PACKAGE opencv_ffmpeg.dll
|
||||
HASH ${FFMPEG_FILE_HASH_BIN32}
|
||||
URL ${FFMPEG_DOWNLOAD_URL}
|
||||
DESTINATION_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
ocv_download(PACKAGE opencv_ffmpeg_64.dll
|
||||
HASH ${FFMPEG_FILE_HASH_BIN64}
|
||||
URL ${FFMPEG_DOWNLOAD_URL}
|
||||
DESTINATION_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
ocv_download(PACKAGE ffmpeg_version.cmake
|
||||
HASH ${FFMPEG_FILE_HASH_CMAKE}
|
||||
URL ${FFMPEG_DOWNLOAD_URL}
|
||||
DESTINATION_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/ffmpeg_version.cmake)
|
||||
Vendored
-11
@@ -1,11 +0,0 @@
|
||||
set(HAVE_FFMPEG 1)
|
||||
set(HAVE_FFMPEG_CODEC 1)
|
||||
set(HAVE_FFMPEG_FORMAT 1)
|
||||
set(HAVE_FFMPEG_UTIL 1)
|
||||
set(HAVE_FFMPEG_SWSCALE 1)
|
||||
set(HAVE_GENTOO_FFMPEG 1)
|
||||
|
||||
set(ALIASOF_libavcodec_VERSION 55.18.102)
|
||||
set(ALIASOF_libavformat_VERSION 55.12.100)
|
||||
set(ALIASOF_libavutil_VERSION 52.38.100)
|
||||
set(ALIASOF_libswscale_VERSION 2.3.100)
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
#include "cap_ffmpeg_impl.hpp"
|
||||
Vendored
+520
@@ -0,0 +1,520 @@
|
||||
Copyright (C) 2001 Fabrice Bellard
|
||||
|
||||
FFmpeg is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
FFmpeg is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with FFmpeg; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
==================================================================================
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
Vendored
-2
@@ -1,2 +0,0 @@
|
||||
set path=c:\dev\msys32\bin;%path% & gcc -Wall -shared -o opencv_ffmpeg.dll -O2 -x c++ -I../include -I../include/ffmpeg_ -I../../modules/highgui/src ffopencv.c -L../lib -lavformat -lavcodec -lavdevice -lswscale -lavutil -lws2_32
|
||||
set path=c:\dev\msys64\bin;%path% & gcc -m64 -Wall -shared -o opencv_ffmpeg_64.dll -O2 -x c++ -I../include -I../include/ffmpeg_ -I../../modules/highgui/src ffopencv.c -L../lib -lavformat64 -lavcodec64 -lavdevice64 -lswscale64 -lavutil64 -lws2_32
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
+30
-34
@@ -1,42 +1,38 @@
|
||||
The build script is to be fixed.
|
||||
Right now it assumes that 32-bit MinGW is in the system path and
|
||||
64-bit mingw is installed to c:\Apps\MinGW64.
|
||||
* On Linux and other Unix flavors OpenCV uses default or user-built ffmpeg/libav libraries.
|
||||
If user builds ffmpeg/libav from source and wants OpenCV to stay BSD library, not GPL/LGPL,
|
||||
he/she should use --enabled-shared configure flag and make sure that no GPL components are
|
||||
enabled (some notable examples are x264 (H264 encoder) and libac3 (Dolby AC3 audio codec)).
|
||||
See https://www.ffmpeg.org/legal.html for details.
|
||||
|
||||
It is important that gcc is used, not g++!
|
||||
Otherwise the produced DLL will likely be dependent on libgcc_s_dw2-1.dll or similar DLL.
|
||||
While we want to make the DLLs with minimum dependencies: Win32 libraries + msvcrt.dll.
|
||||
If you want to play very safe and do not want to use FFMPEG at all, regardless of whether it's installed on
|
||||
your system or not, configure and build OpenCV using CMake with WITH_FFMPEG=OFF flag. OpenCV will then use
|
||||
AVFoundation (OSX), GStreamer (Linux) or other available backends supported by opencv_videoio module.
|
||||
|
||||
ffopencv.c is really a C++ source, hence -x c++ is used.
|
||||
There is also our self-contained motion jpeg codec, which you can use without any worries.
|
||||
It handles CV_FOURCC('M', 'J', 'P', 'G') streams within an AVI container (".avi").
|
||||
|
||||
How to update opencv_ffmpeg.dll and opencv_ffmpeg_64.dll when a new version of FFMPEG is release?
|
||||
* On Windows OpenCV uses pre-built ffmpeg binaries, built with proper flags (without GPL components) and
|
||||
wrapped with simple, stable OpenCV-compatible API.
|
||||
The binaries are opencv_ffmpeg.dll (version for 32-bit Windows) and
|
||||
opencv_ffmpeg_64.dll (version for 64-bit Windows).
|
||||
|
||||
1. Install 32-bit MinGW + MSYS from
|
||||
http://sourceforge.net/projects/mingw/files/Automated%20MinGW%20Installer/mingw-get-inst/
|
||||
Let's assume, it's installed in C:\MSYS32.
|
||||
2. Install 64-bit MinGW. http://mingw-w64.sourceforge.net/
|
||||
Let's assume, it's installed in C:\MSYS64
|
||||
3. Copy C:\MSYS32\msys to C:\MSYS64\msys. Edit C:\MSYS64\msys\etc\fstab, change C:\MSYS32 to C:\MSYS64.
|
||||
See build_win32.txt for the build instructions, if you want to rebuild opencv_ffmpeg*.dll from scratch.
|
||||
|
||||
4. Now you have working MSYS32 and MSYS64 environments.
|
||||
Launch, one by one, C:\MSYS32\msys\msys.bat and C:\MSYS64\msys\msys.bat to create your home directories.
|
||||
The pre-built opencv_ffmpeg*.dll is:
|
||||
* LGPL library, not BSD libraries.
|
||||
* Loaded at runtime by opencv_videoio module.
|
||||
If it succeeds, ffmpeg can be used to decode/encode videos;
|
||||
otherwise, other API is used.
|
||||
|
||||
4. Download ffmpeg-x.y.z.tar.gz (where x.y.z denotes the actual ffmpeg version).
|
||||
Copy it to C:\MSYS{32|64}\msys\home\<loginname> directory.
|
||||
FFMPEG build contains H264 encoder based on the OpenH264 library, that should be installed separatelly.
|
||||
OpenH264 Video Codec provided by Cisco Systems, Inc.
|
||||
See https://github.com/cisco/openh264/releases for details and OpenH264 license.
|
||||
Downloaded binary file can be placed into global system path (System32 or SysWOW64) or near application binaries.
|
||||
You can also specify location of binary file via OPENH264_LIBRARY_PATH environment variable.
|
||||
|
||||
5. To build 32-bit ffmpeg libraries, run C:\MSYS32\msys\msys.bat and type the following commands:
|
||||
If LGPL/GPL software can not be supplied with your OpenCV-based product, simply exclude
|
||||
opencv_ffmpeg*.dll from your distribution; OpenCV will stay fully functional except for the ability to
|
||||
decode/encode videos using FFMPEG (though, it may still be able to do that using other API,
|
||||
such as Video for Windows, Windows Media Foundation or our self-contained motion jpeg codec).
|
||||
|
||||
5.1. tar -xzf ffmpeg-x.y.z.tar.gz
|
||||
5.2. mkdir build
|
||||
5.3. cd build
|
||||
5.4. ../ffmpeg-x.y.z/configure --enable-w32threads
|
||||
5.5. make
|
||||
5.6. make install
|
||||
5.7. cd /local/lib
|
||||
5.8. strip -g *.a
|
||||
|
||||
6. Then repeat the same for 64-bit case. The output libs: libavcodec.a etc. need to be renamed to libavcodec64.a etc.
|
||||
|
||||
7. Then, copy all those libs to <opencv>\3rdparty\lib\, copy the headers to <opencv>\3rdparty\include\ffmpeg_.
|
||||
|
||||
8. Then, go to <opencv>\3rdparty\ffmpeg, edit make.bat
|
||||
(change paths to the actual paths to your msys32 and msys64 distributions) and then run make.bat
|
||||
See license.txt for the FFMPEG copyright notice and the licensing terms.
|
||||
|
||||
-4863
File diff suppressed because it is too large
Load Diff
-116
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AVFFT_H
|
||||
#define AVCODEC_AVFFT_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @ingroup lavc_fft
|
||||
* FFT functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup lavc_fft FFT functions
|
||||
* @ingroup lavc_misc
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef float FFTSample;
|
||||
|
||||
typedef struct FFTComplex {
|
||||
FFTSample re, im;
|
||||
} FFTComplex;
|
||||
|
||||
typedef struct FFTContext FFTContext;
|
||||
|
||||
/**
|
||||
* Set up a complex FFT.
|
||||
* @param nbits log2 of the length of the input array
|
||||
* @param inverse if 0 perform the forward transform, if 1 perform the inverse
|
||||
*/
|
||||
FFTContext *av_fft_init(int nbits, int inverse);
|
||||
|
||||
/**
|
||||
* Do the permutation needed BEFORE calling ff_fft_calc().
|
||||
*/
|
||||
void av_fft_permute(FFTContext *s, FFTComplex *z);
|
||||
|
||||
/**
|
||||
* Do a complex FFT with the parameters defined in av_fft_init(). The
|
||||
* input data must be permuted before. No 1.0/sqrt(n) normalization is done.
|
||||
*/
|
||||
void av_fft_calc(FFTContext *s, FFTComplex *z);
|
||||
|
||||
void av_fft_end(FFTContext *s);
|
||||
|
||||
FFTContext *av_mdct_init(int nbits, int inverse, double scale);
|
||||
void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input);
|
||||
void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input);
|
||||
void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input);
|
||||
void av_mdct_end(FFTContext *s);
|
||||
|
||||
/* Real Discrete Fourier Transform */
|
||||
|
||||
enum RDFTransformType {
|
||||
DFT_R2C,
|
||||
IDFT_C2R,
|
||||
IDFT_R2C,
|
||||
DFT_C2R,
|
||||
};
|
||||
|
||||
typedef struct RDFTContext RDFTContext;
|
||||
|
||||
/**
|
||||
* Set up a real FFT.
|
||||
* @param nbits log2 of the length of the input array
|
||||
* @param trans the type of transform
|
||||
*/
|
||||
RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans);
|
||||
void av_rdft_calc(RDFTContext *s, FFTSample *data);
|
||||
void av_rdft_end(RDFTContext *s);
|
||||
|
||||
/* Discrete Cosine Transform */
|
||||
|
||||
typedef struct DCTContext DCTContext;
|
||||
|
||||
enum DCTTransformType {
|
||||
DCT_II = 0,
|
||||
DCT_III,
|
||||
DCT_I,
|
||||
DST_I,
|
||||
};
|
||||
|
||||
/**
|
||||
* Set up DCT.
|
||||
* @param nbits size of the input array:
|
||||
* (1 << nbits) for DCT-II, DCT-III and DST-I
|
||||
* (1 << nbits) + 1 for DCT-I
|
||||
*
|
||||
* @note the first element of the input of DST-I is ignored
|
||||
*/
|
||||
DCTContext *av_dct_init(int nbits, enum DCTTransformType type);
|
||||
void av_dct_calc(DCTContext *s, FFTSample *data);
|
||||
void av_dct_end (DCTContext *s);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* AVCODEC_AVFFT_H */
|
||||
-95
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* DXVA2 HW acceleration
|
||||
*
|
||||
* copyright (c) 2009 Laurent Aimar
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_DXVA_H
|
||||
#define AVCODEC_DXVA_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @ingroup lavc_codec_hwaccel_dxva2
|
||||
* Public libavcodec DXVA2 header.
|
||||
*/
|
||||
|
||||
#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32_WINNT)
|
||||
#define _WIN32_WINNT 0x0600
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <d3d9.h>
|
||||
#include <dxva2api.h>
|
||||
|
||||
/**
|
||||
* @defgroup lavc_codec_hwaccel_dxva2 DXVA2
|
||||
* @ingroup lavc_codec_hwaccel
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG 1 ///< Work around for DXVA2 and old UVD/UVD+ ATI video cards
|
||||
|
||||
/**
|
||||
* This structure is used to provides the necessary configurations and data
|
||||
* to the DXVA2 FFmpeg HWAccel implementation.
|
||||
*
|
||||
* The application must make it available as AVCodecContext.hwaccel_context.
|
||||
*/
|
||||
struct dxva_context {
|
||||
/**
|
||||
* DXVA2 decoder object
|
||||
*/
|
||||
IDirectXVideoDecoder *decoder;
|
||||
|
||||
/**
|
||||
* DXVA2 configuration used to create the decoder
|
||||
*/
|
||||
const DXVA2_ConfigPictureDecode *cfg;
|
||||
|
||||
/**
|
||||
* The number of surface in the surface array
|
||||
*/
|
||||
unsigned surface_count;
|
||||
|
||||
/**
|
||||
* The array of Direct3D surfaces used to create the decoder
|
||||
*/
|
||||
LPDIRECT3DSURFACE9 *surface;
|
||||
|
||||
/**
|
||||
* A bit field configuring the workarounds needed for using the decoder
|
||||
*/
|
||||
uint64_t workaround;
|
||||
|
||||
/**
|
||||
* Private to the FFmpeg AVHWAccel implementation
|
||||
*/
|
||||
unsigned report_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* AVCODEC_DXVA_H */
|
||||
-397
@@ -1,397 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_OLD_CODEC_IDS_H
|
||||
#define AVCODEC_OLD_CODEC_IDS_H
|
||||
|
||||
#include "libavutil/common.h"
|
||||
|
||||
/*
|
||||
* This header exists to prevent new codec IDs from being accidentally added to
|
||||
* the deprecated list.
|
||||
* Do not include it directly. It will be removed on next major bump
|
||||
*
|
||||
* Do not add new items to this list. Use the AVCodecID enum instead.
|
||||
*/
|
||||
|
||||
CODEC_ID_NONE = AV_CODEC_ID_NONE,
|
||||
|
||||
/* video codecs */
|
||||
CODEC_ID_MPEG1VIDEO,
|
||||
CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding
|
||||
CODEC_ID_MPEG2VIDEO_XVMC,
|
||||
CODEC_ID_H261,
|
||||
CODEC_ID_H263,
|
||||
CODEC_ID_RV10,
|
||||
CODEC_ID_RV20,
|
||||
CODEC_ID_MJPEG,
|
||||
CODEC_ID_MJPEGB,
|
||||
CODEC_ID_LJPEG,
|
||||
CODEC_ID_SP5X,
|
||||
CODEC_ID_JPEGLS,
|
||||
CODEC_ID_MPEG4,
|
||||
CODEC_ID_RAWVIDEO,
|
||||
CODEC_ID_MSMPEG4V1,
|
||||
CODEC_ID_MSMPEG4V2,
|
||||
CODEC_ID_MSMPEG4V3,
|
||||
CODEC_ID_WMV1,
|
||||
CODEC_ID_WMV2,
|
||||
CODEC_ID_H263P,
|
||||
CODEC_ID_H263I,
|
||||
CODEC_ID_FLV1,
|
||||
CODEC_ID_SVQ1,
|
||||
CODEC_ID_SVQ3,
|
||||
CODEC_ID_DVVIDEO,
|
||||
CODEC_ID_HUFFYUV,
|
||||
CODEC_ID_CYUV,
|
||||
CODEC_ID_H264,
|
||||
CODEC_ID_INDEO3,
|
||||
CODEC_ID_VP3,
|
||||
CODEC_ID_THEORA,
|
||||
CODEC_ID_ASV1,
|
||||
CODEC_ID_ASV2,
|
||||
CODEC_ID_FFV1,
|
||||
CODEC_ID_4XM,
|
||||
CODEC_ID_VCR1,
|
||||
CODEC_ID_CLJR,
|
||||
CODEC_ID_MDEC,
|
||||
CODEC_ID_ROQ,
|
||||
CODEC_ID_INTERPLAY_VIDEO,
|
||||
CODEC_ID_XAN_WC3,
|
||||
CODEC_ID_XAN_WC4,
|
||||
CODEC_ID_RPZA,
|
||||
CODEC_ID_CINEPAK,
|
||||
CODEC_ID_WS_VQA,
|
||||
CODEC_ID_MSRLE,
|
||||
CODEC_ID_MSVIDEO1,
|
||||
CODEC_ID_IDCIN,
|
||||
CODEC_ID_8BPS,
|
||||
CODEC_ID_SMC,
|
||||
CODEC_ID_FLIC,
|
||||
CODEC_ID_TRUEMOTION1,
|
||||
CODEC_ID_VMDVIDEO,
|
||||
CODEC_ID_MSZH,
|
||||
CODEC_ID_ZLIB,
|
||||
CODEC_ID_QTRLE,
|
||||
CODEC_ID_TSCC,
|
||||
CODEC_ID_ULTI,
|
||||
CODEC_ID_QDRAW,
|
||||
CODEC_ID_VIXL,
|
||||
CODEC_ID_QPEG,
|
||||
CODEC_ID_PNG,
|
||||
CODEC_ID_PPM,
|
||||
CODEC_ID_PBM,
|
||||
CODEC_ID_PGM,
|
||||
CODEC_ID_PGMYUV,
|
||||
CODEC_ID_PAM,
|
||||
CODEC_ID_FFVHUFF,
|
||||
CODEC_ID_RV30,
|
||||
CODEC_ID_RV40,
|
||||
CODEC_ID_VC1,
|
||||
CODEC_ID_WMV3,
|
||||
CODEC_ID_LOCO,
|
||||
CODEC_ID_WNV1,
|
||||
CODEC_ID_AASC,
|
||||
CODEC_ID_INDEO2,
|
||||
CODEC_ID_FRAPS,
|
||||
CODEC_ID_TRUEMOTION2,
|
||||
CODEC_ID_BMP,
|
||||
CODEC_ID_CSCD,
|
||||
CODEC_ID_MMVIDEO,
|
||||
CODEC_ID_ZMBV,
|
||||
CODEC_ID_AVS,
|
||||
CODEC_ID_SMACKVIDEO,
|
||||
CODEC_ID_NUV,
|
||||
CODEC_ID_KMVC,
|
||||
CODEC_ID_FLASHSV,
|
||||
CODEC_ID_CAVS,
|
||||
CODEC_ID_JPEG2000,
|
||||
CODEC_ID_VMNC,
|
||||
CODEC_ID_VP5,
|
||||
CODEC_ID_VP6,
|
||||
CODEC_ID_VP6F,
|
||||
CODEC_ID_TARGA,
|
||||
CODEC_ID_DSICINVIDEO,
|
||||
CODEC_ID_TIERTEXSEQVIDEO,
|
||||
CODEC_ID_TIFF,
|
||||
CODEC_ID_GIF,
|
||||
CODEC_ID_DXA,
|
||||
CODEC_ID_DNXHD,
|
||||
CODEC_ID_THP,
|
||||
CODEC_ID_SGI,
|
||||
CODEC_ID_C93,
|
||||
CODEC_ID_BETHSOFTVID,
|
||||
CODEC_ID_PTX,
|
||||
CODEC_ID_TXD,
|
||||
CODEC_ID_VP6A,
|
||||
CODEC_ID_AMV,
|
||||
CODEC_ID_VB,
|
||||
CODEC_ID_PCX,
|
||||
CODEC_ID_SUNRAST,
|
||||
CODEC_ID_INDEO4,
|
||||
CODEC_ID_INDEO5,
|
||||
CODEC_ID_MIMIC,
|
||||
CODEC_ID_RL2,
|
||||
CODEC_ID_ESCAPE124,
|
||||
CODEC_ID_DIRAC,
|
||||
CODEC_ID_BFI,
|
||||
CODEC_ID_CMV,
|
||||
CODEC_ID_MOTIONPIXELS,
|
||||
CODEC_ID_TGV,
|
||||
CODEC_ID_TGQ,
|
||||
CODEC_ID_TQI,
|
||||
CODEC_ID_AURA,
|
||||
CODEC_ID_AURA2,
|
||||
CODEC_ID_V210X,
|
||||
CODEC_ID_TMV,
|
||||
CODEC_ID_V210,
|
||||
CODEC_ID_DPX,
|
||||
CODEC_ID_MAD,
|
||||
CODEC_ID_FRWU,
|
||||
CODEC_ID_FLASHSV2,
|
||||
CODEC_ID_CDGRAPHICS,
|
||||
CODEC_ID_R210,
|
||||
CODEC_ID_ANM,
|
||||
CODEC_ID_BINKVIDEO,
|
||||
CODEC_ID_IFF_ILBM,
|
||||
CODEC_ID_IFF_BYTERUN1,
|
||||
CODEC_ID_KGV1,
|
||||
CODEC_ID_YOP,
|
||||
CODEC_ID_VP8,
|
||||
CODEC_ID_PICTOR,
|
||||
CODEC_ID_ANSI,
|
||||
CODEC_ID_A64_MULTI,
|
||||
CODEC_ID_A64_MULTI5,
|
||||
CODEC_ID_R10K,
|
||||
CODEC_ID_MXPEG,
|
||||
CODEC_ID_LAGARITH,
|
||||
CODEC_ID_PRORES,
|
||||
CODEC_ID_JV,
|
||||
CODEC_ID_DFA,
|
||||
CODEC_ID_WMV3IMAGE,
|
||||
CODEC_ID_VC1IMAGE,
|
||||
CODEC_ID_UTVIDEO,
|
||||
CODEC_ID_BMV_VIDEO,
|
||||
CODEC_ID_VBLE,
|
||||
CODEC_ID_DXTORY,
|
||||
CODEC_ID_V410,
|
||||
CODEC_ID_XWD,
|
||||
CODEC_ID_CDXL,
|
||||
CODEC_ID_XBM,
|
||||
CODEC_ID_ZEROCODEC,
|
||||
CODEC_ID_MSS1,
|
||||
CODEC_ID_MSA1,
|
||||
CODEC_ID_TSCC2,
|
||||
CODEC_ID_MTS2,
|
||||
CODEC_ID_CLLC,
|
||||
CODEC_ID_Y41P = MKBETAG('Y','4','1','P'),
|
||||
CODEC_ID_ESCAPE130 = MKBETAG('E','1','3','0'),
|
||||
CODEC_ID_EXR = MKBETAG('0','E','X','R'),
|
||||
CODEC_ID_AVRP = MKBETAG('A','V','R','P'),
|
||||
|
||||
CODEC_ID_G2M = MKBETAG( 0 ,'G','2','M'),
|
||||
CODEC_ID_AVUI = MKBETAG('A','V','U','I'),
|
||||
CODEC_ID_AYUV = MKBETAG('A','Y','U','V'),
|
||||
CODEC_ID_V308 = MKBETAG('V','3','0','8'),
|
||||
CODEC_ID_V408 = MKBETAG('V','4','0','8'),
|
||||
CODEC_ID_YUV4 = MKBETAG('Y','U','V','4'),
|
||||
CODEC_ID_SANM = MKBETAG('S','A','N','M'),
|
||||
CODEC_ID_PAF_VIDEO = MKBETAG('P','A','F','V'),
|
||||
CODEC_ID_SNOW = AV_CODEC_ID_SNOW,
|
||||
|
||||
/* various PCM "codecs" */
|
||||
CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
|
||||
CODEC_ID_PCM_S16LE = 0x10000,
|
||||
CODEC_ID_PCM_S16BE,
|
||||
CODEC_ID_PCM_U16LE,
|
||||
CODEC_ID_PCM_U16BE,
|
||||
CODEC_ID_PCM_S8,
|
||||
CODEC_ID_PCM_U8,
|
||||
CODEC_ID_PCM_MULAW,
|
||||
CODEC_ID_PCM_ALAW,
|
||||
CODEC_ID_PCM_S32LE,
|
||||
CODEC_ID_PCM_S32BE,
|
||||
CODEC_ID_PCM_U32LE,
|
||||
CODEC_ID_PCM_U32BE,
|
||||
CODEC_ID_PCM_S24LE,
|
||||
CODEC_ID_PCM_S24BE,
|
||||
CODEC_ID_PCM_U24LE,
|
||||
CODEC_ID_PCM_U24BE,
|
||||
CODEC_ID_PCM_S24DAUD,
|
||||
CODEC_ID_PCM_ZORK,
|
||||
CODEC_ID_PCM_S16LE_PLANAR,
|
||||
CODEC_ID_PCM_DVD,
|
||||
CODEC_ID_PCM_F32BE,
|
||||
CODEC_ID_PCM_F32LE,
|
||||
CODEC_ID_PCM_F64BE,
|
||||
CODEC_ID_PCM_F64LE,
|
||||
CODEC_ID_PCM_BLURAY,
|
||||
CODEC_ID_PCM_LXF,
|
||||
CODEC_ID_S302M,
|
||||
CODEC_ID_PCM_S8_PLANAR,
|
||||
|
||||
/* various ADPCM codecs */
|
||||
CODEC_ID_ADPCM_IMA_QT = 0x11000,
|
||||
CODEC_ID_ADPCM_IMA_WAV,
|
||||
CODEC_ID_ADPCM_IMA_DK3,
|
||||
CODEC_ID_ADPCM_IMA_DK4,
|
||||
CODEC_ID_ADPCM_IMA_WS,
|
||||
CODEC_ID_ADPCM_IMA_SMJPEG,
|
||||
CODEC_ID_ADPCM_MS,
|
||||
CODEC_ID_ADPCM_4XM,
|
||||
CODEC_ID_ADPCM_XA,
|
||||
CODEC_ID_ADPCM_ADX,
|
||||
CODEC_ID_ADPCM_EA,
|
||||
CODEC_ID_ADPCM_G726,
|
||||
CODEC_ID_ADPCM_CT,
|
||||
CODEC_ID_ADPCM_SWF,
|
||||
CODEC_ID_ADPCM_YAMAHA,
|
||||
CODEC_ID_ADPCM_SBPRO_4,
|
||||
CODEC_ID_ADPCM_SBPRO_3,
|
||||
CODEC_ID_ADPCM_SBPRO_2,
|
||||
CODEC_ID_ADPCM_THP,
|
||||
CODEC_ID_ADPCM_IMA_AMV,
|
||||
CODEC_ID_ADPCM_EA_R1,
|
||||
CODEC_ID_ADPCM_EA_R3,
|
||||
CODEC_ID_ADPCM_EA_R2,
|
||||
CODEC_ID_ADPCM_IMA_EA_SEAD,
|
||||
CODEC_ID_ADPCM_IMA_EA_EACS,
|
||||
CODEC_ID_ADPCM_EA_XAS,
|
||||
CODEC_ID_ADPCM_EA_MAXIS_XA,
|
||||
CODEC_ID_ADPCM_IMA_ISS,
|
||||
CODEC_ID_ADPCM_G722,
|
||||
CODEC_ID_ADPCM_IMA_APC,
|
||||
CODEC_ID_VIMA = MKBETAG('V','I','M','A'),
|
||||
|
||||
/* AMR */
|
||||
CODEC_ID_AMR_NB = 0x12000,
|
||||
CODEC_ID_AMR_WB,
|
||||
|
||||
/* RealAudio codecs*/
|
||||
CODEC_ID_RA_144 = 0x13000,
|
||||
CODEC_ID_RA_288,
|
||||
|
||||
/* various DPCM codecs */
|
||||
CODEC_ID_ROQ_DPCM = 0x14000,
|
||||
CODEC_ID_INTERPLAY_DPCM,
|
||||
CODEC_ID_XAN_DPCM,
|
||||
CODEC_ID_SOL_DPCM,
|
||||
|
||||
/* audio codecs */
|
||||
CODEC_ID_MP2 = 0x15000,
|
||||
CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3
|
||||
CODEC_ID_AAC,
|
||||
CODEC_ID_AC3,
|
||||
CODEC_ID_DTS,
|
||||
CODEC_ID_VORBIS,
|
||||
CODEC_ID_DVAUDIO,
|
||||
CODEC_ID_WMAV1,
|
||||
CODEC_ID_WMAV2,
|
||||
CODEC_ID_MACE3,
|
||||
CODEC_ID_MACE6,
|
||||
CODEC_ID_VMDAUDIO,
|
||||
CODEC_ID_FLAC,
|
||||
CODEC_ID_MP3ADU,
|
||||
CODEC_ID_MP3ON4,
|
||||
CODEC_ID_SHORTEN,
|
||||
CODEC_ID_ALAC,
|
||||
CODEC_ID_WESTWOOD_SND1,
|
||||
CODEC_ID_GSM, ///< as in Berlin toast format
|
||||
CODEC_ID_QDM2,
|
||||
CODEC_ID_COOK,
|
||||
CODEC_ID_TRUESPEECH,
|
||||
CODEC_ID_TTA,
|
||||
CODEC_ID_SMACKAUDIO,
|
||||
CODEC_ID_QCELP,
|
||||
CODEC_ID_WAVPACK,
|
||||
CODEC_ID_DSICINAUDIO,
|
||||
CODEC_ID_IMC,
|
||||
CODEC_ID_MUSEPACK7,
|
||||
CODEC_ID_MLP,
|
||||
CODEC_ID_GSM_MS, /* as found in WAV */
|
||||
CODEC_ID_ATRAC3,
|
||||
CODEC_ID_VOXWARE,
|
||||
CODEC_ID_APE,
|
||||
CODEC_ID_NELLYMOSER,
|
||||
CODEC_ID_MUSEPACK8,
|
||||
CODEC_ID_SPEEX,
|
||||
CODEC_ID_WMAVOICE,
|
||||
CODEC_ID_WMAPRO,
|
||||
CODEC_ID_WMALOSSLESS,
|
||||
CODEC_ID_ATRAC3P,
|
||||
CODEC_ID_EAC3,
|
||||
CODEC_ID_SIPR,
|
||||
CODEC_ID_MP1,
|
||||
CODEC_ID_TWINVQ,
|
||||
CODEC_ID_TRUEHD,
|
||||
CODEC_ID_MP4ALS,
|
||||
CODEC_ID_ATRAC1,
|
||||
CODEC_ID_BINKAUDIO_RDFT,
|
||||
CODEC_ID_BINKAUDIO_DCT,
|
||||
CODEC_ID_AAC_LATM,
|
||||
CODEC_ID_QDMC,
|
||||
CODEC_ID_CELT,
|
||||
CODEC_ID_G723_1,
|
||||
CODEC_ID_G729,
|
||||
CODEC_ID_8SVX_EXP,
|
||||
CODEC_ID_8SVX_FIB,
|
||||
CODEC_ID_BMV_AUDIO,
|
||||
CODEC_ID_RALF,
|
||||
CODEC_ID_IAC,
|
||||
CODEC_ID_ILBC,
|
||||
CODEC_ID_FFWAVESYNTH = MKBETAG('F','F','W','S'),
|
||||
CODEC_ID_SONIC = MKBETAG('S','O','N','C'),
|
||||
CODEC_ID_SONIC_LS = MKBETAG('S','O','N','L'),
|
||||
CODEC_ID_PAF_AUDIO = MKBETAG('P','A','F','A'),
|
||||
CODEC_ID_OPUS = MKBETAG('O','P','U','S'),
|
||||
|
||||
/* subtitle codecs */
|
||||
CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs.
|
||||
CODEC_ID_DVD_SUBTITLE = 0x17000,
|
||||
CODEC_ID_DVB_SUBTITLE,
|
||||
CODEC_ID_TEXT, ///< raw UTF-8 text
|
||||
CODEC_ID_XSUB,
|
||||
CODEC_ID_SSA,
|
||||
CODEC_ID_MOV_TEXT,
|
||||
CODEC_ID_HDMV_PGS_SUBTITLE,
|
||||
CODEC_ID_DVB_TELETEXT,
|
||||
CODEC_ID_SRT,
|
||||
CODEC_ID_MICRODVD = MKBETAG('m','D','V','D'),
|
||||
CODEC_ID_EIA_608 = MKBETAG('c','6','0','8'),
|
||||
CODEC_ID_JACOSUB = MKBETAG('J','S','U','B'),
|
||||
CODEC_ID_SAMI = MKBETAG('S','A','M','I'),
|
||||
CODEC_ID_REALTEXT = MKBETAG('R','T','X','T'),
|
||||
CODEC_ID_SUBVIEWER = MKBETAG('S','u','b','V'),
|
||||
|
||||
/* other specific kind of codecs (generally used for attachments) */
|
||||
CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs.
|
||||
CODEC_ID_TTF = 0x18000,
|
||||
CODEC_ID_BINTEXT = MKBETAG('B','T','X','T'),
|
||||
CODEC_ID_XBIN = MKBETAG('X','B','I','N'),
|
||||
CODEC_ID_IDF = MKBETAG( 0 ,'I','D','F'),
|
||||
CODEC_ID_OTF = MKBETAG( 0 ,'O','T','F'),
|
||||
|
||||
CODEC_ID_PROBE = 0x19000, ///< codec_id is not known (like CODEC_ID_NONE) but lavf should attempt to identify it
|
||||
|
||||
CODEC_ID_MPEG2TS = 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS
|
||||
* stream (only used by libavformat) */
|
||||
CODEC_ID_MPEG4SYSTEMS = 0x20001, /**< _FAKE_ codec to indicate a MPEG-4 Systems
|
||||
* stream (only used by libavformat) */
|
||||
CODEC_ID_FFMETADATA = 0x21000, ///< Dummy codec for streams containing only metadata information.
|
||||
|
||||
#endif /* AVCODEC_OLD_CODEC_IDS_H */
|
||||
-173
@@ -1,173 +0,0 @@
|
||||
/*
|
||||
* Video Acceleration API (shared data between FFmpeg and the video player)
|
||||
* HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1
|
||||
*
|
||||
* Copyright (C) 2008-2009 Splitted-Desktop Systems
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_VAAPI_H
|
||||
#define AVCODEC_VAAPI_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @ingroup lavc_codec_hwaccel_vaapi
|
||||
* Public libavcodec VA API header.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @defgroup lavc_codec_hwaccel_vaapi VA API Decoding
|
||||
* @ingroup lavc_codec_hwaccel
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* This structure is used to share data between the FFmpeg library and
|
||||
* the client video application.
|
||||
* This shall be zero-allocated and available as
|
||||
* AVCodecContext.hwaccel_context. All user members can be set once
|
||||
* during initialization or through each AVCodecContext.get_buffer()
|
||||
* function call. In any case, they must be valid prior to calling
|
||||
* decoding functions.
|
||||
*/
|
||||
struct vaapi_context {
|
||||
/**
|
||||
* Window system dependent data
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set by user
|
||||
*/
|
||||
void *display;
|
||||
|
||||
/**
|
||||
* Configuration ID
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set by user
|
||||
*/
|
||||
uint32_t config_id;
|
||||
|
||||
/**
|
||||
* Context ID (video decode pipeline)
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set by user
|
||||
*/
|
||||
uint32_t context_id;
|
||||
|
||||
/**
|
||||
* VAPictureParameterBuffer ID
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set by libavcodec
|
||||
*/
|
||||
uint32_t pic_param_buf_id;
|
||||
|
||||
/**
|
||||
* VAIQMatrixBuffer ID
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set by libavcodec
|
||||
*/
|
||||
uint32_t iq_matrix_buf_id;
|
||||
|
||||
/**
|
||||
* VABitPlaneBuffer ID (for VC-1 decoding)
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set by libavcodec
|
||||
*/
|
||||
uint32_t bitplane_buf_id;
|
||||
|
||||
/**
|
||||
* Slice parameter/data buffer IDs
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set by libavcodec
|
||||
*/
|
||||
uint32_t *slice_buf_ids;
|
||||
|
||||
/**
|
||||
* Number of effective slice buffer IDs to send to the HW
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set by libavcodec
|
||||
*/
|
||||
unsigned int n_slice_buf_ids;
|
||||
|
||||
/**
|
||||
* Size of pre-allocated slice_buf_ids
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set by libavcodec
|
||||
*/
|
||||
unsigned int slice_buf_ids_alloc;
|
||||
|
||||
/**
|
||||
* Pointer to VASliceParameterBuffers
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set by libavcodec
|
||||
*/
|
||||
void *slice_params;
|
||||
|
||||
/**
|
||||
* Size of a VASliceParameterBuffer element
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set by libavcodec
|
||||
*/
|
||||
unsigned int slice_param_size;
|
||||
|
||||
/**
|
||||
* Size of pre-allocated slice_params
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set by libavcodec
|
||||
*/
|
||||
unsigned int slice_params_alloc;
|
||||
|
||||
/**
|
||||
* Number of slices currently filled in
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set by libavcodec
|
||||
*/
|
||||
unsigned int slice_count;
|
||||
|
||||
/**
|
||||
* Pointer to slice data buffer base
|
||||
* - encoding: unused
|
||||
* - decoding: Set by libavcodec
|
||||
*/
|
||||
const uint8_t *slice_data;
|
||||
|
||||
/**
|
||||
* Current size of slice data
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set by libavcodec
|
||||
*/
|
||||
uint32_t slice_data_size;
|
||||
};
|
||||
|
||||
/* @} */
|
||||
|
||||
#endif /* AVCODEC_VAAPI_H */
|
||||
-162
@@ -1,162 +0,0 @@
|
||||
/*
|
||||
* VDA HW acceleration
|
||||
*
|
||||
* copyright (c) 2011 Sebastien Zwickert
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_VDA_H
|
||||
#define AVCODEC_VDA_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @ingroup lavc_codec_hwaccel_vda
|
||||
* Public libavcodec VDA header.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// emmintrin.h is unable to compile with -std=c99 -Werror=missing-prototypes
|
||||
// http://openradar.appspot.com/8026390
|
||||
#undef __GNUC_STDC_INLINE__
|
||||
|
||||
#define Picture QuickdrawPicture
|
||||
#include <VideoDecodeAcceleration/VDADecoder.h>
|
||||
#undef Picture
|
||||
|
||||
#include "libavcodec/version.h"
|
||||
|
||||
/**
|
||||
* @defgroup lavc_codec_hwaccel_vda VDA
|
||||
* @ingroup lavc_codec_hwaccel
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* This structure is used to provide the necessary configurations and data
|
||||
* to the VDA FFmpeg HWAccel implementation.
|
||||
*
|
||||
* The application must make it available as AVCodecContext.hwaccel_context.
|
||||
*/
|
||||
struct vda_context {
|
||||
/**
|
||||
* VDA decoder object.
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set/Unset by libavcodec.
|
||||
*/
|
||||
VDADecoder decoder;
|
||||
|
||||
/**
|
||||
* The Core Video pixel buffer that contains the current image data.
|
||||
*
|
||||
* encoding: unused
|
||||
* decoding: Set by libavcodec. Unset by user.
|
||||
*/
|
||||
CVPixelBufferRef cv_buffer;
|
||||
|
||||
/**
|
||||
* Use the hardware decoder in synchronous mode.
|
||||
*
|
||||
* encoding: unused
|
||||
* decoding: Set by user.
|
||||
*/
|
||||
int use_sync_decoding;
|
||||
|
||||
/**
|
||||
* The frame width.
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set/Unset by user.
|
||||
*/
|
||||
int width;
|
||||
|
||||
/**
|
||||
* The frame height.
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set/Unset by user.
|
||||
*/
|
||||
int height;
|
||||
|
||||
/**
|
||||
* The frame format.
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set/Unset by user.
|
||||
*/
|
||||
int format;
|
||||
|
||||
/**
|
||||
* The pixel format for output image buffers.
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set/Unset by user.
|
||||
*/
|
||||
OSType cv_pix_fmt_type;
|
||||
|
||||
/**
|
||||
* The current bitstream buffer.
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set/Unset by libavcodec.
|
||||
*/
|
||||
uint8_t *priv_bitstream;
|
||||
|
||||
/**
|
||||
* The current size of the bitstream.
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set/Unset by libavcodec.
|
||||
*/
|
||||
int priv_bitstream_size;
|
||||
|
||||
/**
|
||||
* The reference size used for fast reallocation.
|
||||
*
|
||||
* - encoding: unused
|
||||
* - decoding: Set/Unset by libavcodec.
|
||||
*/
|
||||
int priv_allocated_size;
|
||||
|
||||
/**
|
||||
* Use av_buffer to manage buffer.
|
||||
* When the flag is set, the CVPixelBuffers returned by the decoder will
|
||||
* be released automatically, so you have to retain them if necessary.
|
||||
* Not setting this flag may cause memory leak.
|
||||
*
|
||||
* encoding: unused
|
||||
* decoding: Set by user.
|
||||
*/
|
||||
int use_ref_buffer;
|
||||
};
|
||||
|
||||
/** Create the video decoder. */
|
||||
int ff_vda_create_decoder(struct vda_context *vda_ctx,
|
||||
uint8_t *extradata,
|
||||
int extradata_size);
|
||||
|
||||
/** Destroy the video decoder. */
|
||||
int ff_vda_destroy_decoder(struct vda_context *vda_ctx);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* AVCODEC_VDA_H */
|
||||
-159
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
* The Video Decode and Presentation API for UNIX (VDPAU) is used for
|
||||
* hardware-accelerated decoding of MPEG-1/2, H.264 and VC-1.
|
||||
*
|
||||
* Copyright (C) 2008 NVIDIA
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_VDPAU_H
|
||||
#define AVCODEC_VDPAU_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @ingroup lavc_codec_hwaccel_vdpau
|
||||
* Public libavcodec VDPAU header.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup lavc_codec_hwaccel_vdpau VDPAU Decoder and Renderer
|
||||
* @ingroup lavc_codec_hwaccel
|
||||
*
|
||||
* VDPAU hardware acceleration has two modules
|
||||
* - VDPAU decoding
|
||||
* - VDPAU presentation
|
||||
*
|
||||
* The VDPAU decoding module parses all headers using FFmpeg
|
||||
* parsing mechanisms and uses VDPAU for the actual decoding.
|
||||
*
|
||||
* As per the current implementation, the actual decoding
|
||||
* and rendering (API calls) are done as part of the VDPAU
|
||||
* presentation (vo_vdpau.c) module.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <vdpau/vdpau.h>
|
||||
#include <vdpau/vdpau_x11.h>
|
||||
#include "libavutil/avconfig.h"
|
||||
|
||||
union FFVdpPictureInfo {
|
||||
VdpPictureInfoH264 h264;
|
||||
VdpPictureInfoMPEG1Or2 mpeg;
|
||||
VdpPictureInfoVC1 vc1;
|
||||
VdpPictureInfoMPEG4Part2 mpeg4;
|
||||
};
|
||||
|
||||
/**
|
||||
* This structure is used to share data between the libavcodec library and
|
||||
* the client video application.
|
||||
* The user shall zero-allocate the structure and make it available as
|
||||
* AVCodecContext.hwaccel_context. Members can be set by the user once
|
||||
* during initialization or through each AVCodecContext.get_buffer()
|
||||
* function call. In any case, they must be valid prior to calling
|
||||
* decoding functions.
|
||||
*/
|
||||
typedef struct AVVDPAUContext {
|
||||
/**
|
||||
* VDPAU decoder handle
|
||||
*
|
||||
* Set by user.
|
||||
*/
|
||||
VdpDecoder decoder;
|
||||
|
||||
/**
|
||||
* VDPAU decoder render callback
|
||||
*
|
||||
* Set by the user.
|
||||
*/
|
||||
VdpDecoderRender *render;
|
||||
|
||||
/**
|
||||
* VDPAU picture information
|
||||
*
|
||||
* Set by libavcodec.
|
||||
*/
|
||||
union FFVdpPictureInfo info;
|
||||
|
||||
/**
|
||||
* Allocated size of the bitstream_buffers table.
|
||||
*
|
||||
* Set by libavcodec.
|
||||
*/
|
||||
int bitstream_buffers_allocated;
|
||||
|
||||
/**
|
||||
* Useful bitstream buffers in the bitstream buffers table.
|
||||
*
|
||||
* Set by libavcodec.
|
||||
*/
|
||||
int bitstream_buffers_used;
|
||||
|
||||
/**
|
||||
* Table of bitstream buffers.
|
||||
* The user is responsible for freeing this buffer using av_freep().
|
||||
*
|
||||
* Set by libavcodec.
|
||||
*/
|
||||
VdpBitstreamBuffer *bitstream_buffers;
|
||||
} AVVDPAUContext;
|
||||
|
||||
|
||||
/** @brief The videoSurface is used for rendering. */
|
||||
#define FF_VDPAU_STATE_USED_FOR_RENDER 1
|
||||
|
||||
/**
|
||||
* @brief The videoSurface is needed for reference/prediction.
|
||||
* The codec manipulates this.
|
||||
*/
|
||||
#define FF_VDPAU_STATE_USED_FOR_REFERENCE 2
|
||||
|
||||
/**
|
||||
* @brief This structure is used as a callback between the FFmpeg
|
||||
* decoder (vd_) and presentation (vo_) module.
|
||||
* This is used for defining a video frame containing surface,
|
||||
* picture parameter, bitstream information etc which are passed
|
||||
* between the FFmpeg decoder and its clients.
|
||||
*/
|
||||
struct vdpau_render_state {
|
||||
VdpVideoSurface surface; ///< Used as rendered surface, never changed.
|
||||
|
||||
int state; ///< Holds FF_VDPAU_STATE_* values.
|
||||
|
||||
#if AV_HAVE_INCOMPATIBLE_LIBAV_ABI
|
||||
/** picture parameter information for all supported codecs */
|
||||
union FFVdpPictureInfo info;
|
||||
#endif
|
||||
|
||||
/** Describe size/location of the compressed video data.
|
||||
Set to 0 when freeing bitstream_buffers. */
|
||||
int bitstream_buffers_allocated;
|
||||
int bitstream_buffers_used;
|
||||
/** The user is responsible for freeing this buffer using av_freep(). */
|
||||
VdpBitstreamBuffer *bitstream_buffers;
|
||||
|
||||
#if !AV_HAVE_INCOMPATIBLE_LIBAV_ABI
|
||||
/** picture parameter information for all supported codecs */
|
||||
union FFVdpPictureInfo info;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* @}*/
|
||||
|
||||
#endif /* AVCODEC_VDPAU_H */
|
||||
-95
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_VERSION_H
|
||||
#define AVCODEC_VERSION_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @ingroup libavc
|
||||
* Libavcodec version macros.
|
||||
*/
|
||||
|
||||
#include "libavutil/avutil.h"
|
||||
|
||||
#define LIBAVCODEC_VERSION_MAJOR 55
|
||||
#define LIBAVCODEC_VERSION_MINOR 18
|
||||
#define LIBAVCODEC_VERSION_MICRO 102
|
||||
|
||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||
LIBAVCODEC_VERSION_MINOR, \
|
||||
LIBAVCODEC_VERSION_MICRO)
|
||||
#define LIBAVCODEC_VERSION AV_VERSION(LIBAVCODEC_VERSION_MAJOR, \
|
||||
LIBAVCODEC_VERSION_MINOR, \
|
||||
LIBAVCODEC_VERSION_MICRO)
|
||||
#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT
|
||||
|
||||
#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION)
|
||||
|
||||
/**
|
||||
* FF_API_* defines may be placed below to indicate public API that will be
|
||||
* dropped at a future version bump. The defines themselves are not part of
|
||||
* the public API and may change, break or disappear at any time.
|
||||
*/
|
||||
|
||||
#ifndef FF_API_REQUEST_CHANNELS
|
||||
#define FF_API_REQUEST_CHANNELS (LIBAVCODEC_VERSION_MAJOR < 56)
|
||||
#endif
|
||||
#ifndef FF_API_ALLOC_CONTEXT
|
||||
#define FF_API_ALLOC_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 55)
|
||||
#endif
|
||||
#ifndef FF_API_AVCODEC_OPEN
|
||||
#define FF_API_AVCODEC_OPEN (LIBAVCODEC_VERSION_MAJOR < 55)
|
||||
#endif
|
||||
#ifndef FF_API_OLD_DECODE_AUDIO
|
||||
#define FF_API_OLD_DECODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 56)
|
||||
#endif
|
||||
#ifndef FF_API_OLD_TIMECODE
|
||||
#define FF_API_OLD_TIMECODE (LIBAVCODEC_VERSION_MAJOR < 55)
|
||||
#endif
|
||||
|
||||
#ifndef FF_API_OLD_ENCODE_AUDIO
|
||||
#define FF_API_OLD_ENCODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 56)
|
||||
#endif
|
||||
#ifndef FF_API_OLD_ENCODE_VIDEO
|
||||
#define FF_API_OLD_ENCODE_VIDEO (LIBAVCODEC_VERSION_MAJOR < 56)
|
||||
#endif
|
||||
#ifndef FF_API_CODEC_ID
|
||||
#define FF_API_CODEC_ID (LIBAVCODEC_VERSION_MAJOR < 56)
|
||||
#endif
|
||||
#ifndef FF_API_AVCODEC_RESAMPLE
|
||||
#define FF_API_AVCODEC_RESAMPLE (LIBAVCODEC_VERSION_MAJOR < 56)
|
||||
#endif
|
||||
#ifndef FF_API_DEINTERLACE
|
||||
#define FF_API_DEINTERLACE (LIBAVCODEC_VERSION_MAJOR < 56)
|
||||
#endif
|
||||
#ifndef FF_API_DESTRUCT_PACKET
|
||||
#define FF_API_DESTRUCT_PACKET (LIBAVCODEC_VERSION_MAJOR < 56)
|
||||
#endif
|
||||
#ifndef FF_API_GET_BUFFER
|
||||
#define FF_API_GET_BUFFER (LIBAVCODEC_VERSION_MAJOR < 56)
|
||||
#endif
|
||||
#ifndef FF_API_MISSING_SAMPLE
|
||||
#define FF_API_MISSING_SAMPLE (LIBAVCODEC_VERSION_MAJOR < 56)
|
||||
#endif
|
||||
#ifndef FF_API_LOWRES
|
||||
#define FF_API_LOWRES (LIBAVCODEC_VERSION_MAJOR < 56)
|
||||
#endif
|
||||
|
||||
#endif /* AVCODEC_VERSION_H */
|
||||
-168
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2003 Ivan Kalvachev
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_XVMC_H
|
||||
#define AVCODEC_XVMC_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @ingroup lavc_codec_hwaccel_xvmc
|
||||
* Public libavcodec XvMC header.
|
||||
*/
|
||||
|
||||
#include <X11/extensions/XvMC.h>
|
||||
|
||||
#include "avcodec.h"
|
||||
|
||||
/**
|
||||
* @defgroup lavc_codec_hwaccel_xvmc XvMC
|
||||
* @ingroup lavc_codec_hwaccel
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define AV_XVMC_ID 0x1DC711C0 /**< special value to ensure that regular pixel routines haven't corrupted the struct
|
||||
the number is 1337 speak for the letters IDCT MCo (motion compensation) */
|
||||
|
||||
struct xvmc_pix_fmt {
|
||||
/** The field contains the special constant value AV_XVMC_ID.
|
||||
It is used as a test that the application correctly uses the API,
|
||||
and that there is no corruption caused by pixel routines.
|
||||
- application - set during initialization
|
||||
- libavcodec - unchanged
|
||||
*/
|
||||
int xvmc_id;
|
||||
|
||||
/** Pointer to the block array allocated by XvMCCreateBlocks().
|
||||
The array has to be freed by XvMCDestroyBlocks().
|
||||
Each group of 64 values represents one data block of differential
|
||||
pixel information (in MoCo mode) or coefficients for IDCT.
|
||||
- application - set the pointer during initialization
|
||||
- libavcodec - fills coefficients/pixel data into the array
|
||||
*/
|
||||
short* data_blocks;
|
||||
|
||||
/** Pointer to the macroblock description array allocated by
|
||||
XvMCCreateMacroBlocks() and freed by XvMCDestroyMacroBlocks().
|
||||
- application - set the pointer during initialization
|
||||
- libavcodec - fills description data into the array
|
||||
*/
|
||||
XvMCMacroBlock* mv_blocks;
|
||||
|
||||
/** Number of macroblock descriptions that can be stored in the mv_blocks
|
||||
array.
|
||||
- application - set during initialization
|
||||
- libavcodec - unchanged
|
||||
*/
|
||||
int allocated_mv_blocks;
|
||||
|
||||
/** Number of blocks that can be stored at once in the data_blocks array.
|
||||
- application - set during initialization
|
||||
- libavcodec - unchanged
|
||||
*/
|
||||
int allocated_data_blocks;
|
||||
|
||||
/** Indicate that the hardware would interpret data_blocks as IDCT
|
||||
coefficients and perform IDCT on them.
|
||||
- application - set during initialization
|
||||
- libavcodec - unchanged
|
||||
*/
|
||||
int idct;
|
||||
|
||||
/** In MoCo mode it indicates that intra macroblocks are assumed to be in
|
||||
unsigned format; same as the XVMC_INTRA_UNSIGNED flag.
|
||||
- application - set during initialization
|
||||
- libavcodec - unchanged
|
||||
*/
|
||||
int unsigned_intra;
|
||||
|
||||
/** Pointer to the surface allocated by XvMCCreateSurface().
|
||||
It has to be freed by XvMCDestroySurface() on application exit.
|
||||
It identifies the frame and its state on the video hardware.
|
||||
- application - set during initialization
|
||||
- libavcodec - unchanged
|
||||
*/
|
||||
XvMCSurface* p_surface;
|
||||
|
||||
/** Set by the decoder before calling ff_draw_horiz_band(),
|
||||
needed by the XvMCRenderSurface function. */
|
||||
//@{
|
||||
/** Pointer to the surface used as past reference
|
||||
- application - unchanged
|
||||
- libavcodec - set
|
||||
*/
|
||||
XvMCSurface* p_past_surface;
|
||||
|
||||
/** Pointer to the surface used as future reference
|
||||
- application - unchanged
|
||||
- libavcodec - set
|
||||
*/
|
||||
XvMCSurface* p_future_surface;
|
||||
|
||||
/** top/bottom field or frame
|
||||
- application - unchanged
|
||||
- libavcodec - set
|
||||
*/
|
||||
unsigned int picture_structure;
|
||||
|
||||
/** XVMC_SECOND_FIELD - 1st or 2nd field in the sequence
|
||||
- application - unchanged
|
||||
- libavcodec - set
|
||||
*/
|
||||
unsigned int flags;
|
||||
//}@
|
||||
|
||||
/** Number of macroblock descriptions in the mv_blocks array
|
||||
that have already been passed to the hardware.
|
||||
- application - zeroes it on get_buffer().
|
||||
A successful ff_draw_horiz_band() may increment it
|
||||
with filled_mb_block_num or zero both.
|
||||
- libavcodec - unchanged
|
||||
*/
|
||||
int start_mv_blocks_num;
|
||||
|
||||
/** Number of new macroblock descriptions in the mv_blocks array (after
|
||||
start_mv_blocks_num) that are filled by libavcodec and have to be
|
||||
passed to the hardware.
|
||||
- application - zeroes it on get_buffer() or after successful
|
||||
ff_draw_horiz_band().
|
||||
- libavcodec - increment with one of each stored MB
|
||||
*/
|
||||
int filled_mv_blocks_num;
|
||||
|
||||
/** Number of the next free data block; one data block consists of
|
||||
64 short values in the data_blocks array.
|
||||
All blocks before this one have already been claimed by placing their
|
||||
position into the corresponding block description structure field,
|
||||
that are part of the mv_blocks array.
|
||||
- application - zeroes it on get_buffer().
|
||||
A successful ff_draw_horiz_band() may zero it together
|
||||
with start_mb_blocks_num.
|
||||
- libavcodec - each decoded macroblock increases it by the number
|
||||
of coded blocks it contains.
|
||||
*/
|
||||
int next_free_data_block_num;
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* AVCODEC_XVMC_H */
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVDEVICE_AVDEVICE_H
|
||||
#define AVDEVICE_AVDEVICE_H
|
||||
|
||||
#include "version.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @ingroup lavd
|
||||
* Main libavdevice API header
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup lavd Special devices muxing/demuxing library
|
||||
* @{
|
||||
* Libavdevice is a complementary library to @ref libavf "libavformat". It
|
||||
* provides various "special" platform-specific muxers and demuxers, e.g. for
|
||||
* grabbing devices, audio capture and playback etc. As a consequence, the
|
||||
* (de)muxers in libavdevice are of the AVFMT_NOFILE type (they use their own
|
||||
* I/O functions). The filename passed to avformat_open_input() often does not
|
||||
* refer to an actually existing file, but has some special device-specific
|
||||
* meaning - e.g. for x11grab it is the display name.
|
||||
*
|
||||
* To use libavdevice, simply call avdevice_register_all() to register all
|
||||
* compiled muxers and demuxers. They all use standard libavformat API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
|
||||
/**
|
||||
* Return the LIBAVDEVICE_VERSION_INT constant.
|
||||
*/
|
||||
unsigned avdevice_version(void);
|
||||
|
||||
/**
|
||||
* Return the libavdevice build-time configuration.
|
||||
*/
|
||||
const char *avdevice_configuration(void);
|
||||
|
||||
/**
|
||||
* Return the libavdevice license.
|
||||
*/
|
||||
const char *avdevice_license(void);
|
||||
|
||||
/**
|
||||
* Initialize libavdevice and register all the input and output devices.
|
||||
* @warning This function is not thread safe.
|
||||
*/
|
||||
void avdevice_register_all(void);
|
||||
|
||||
#endif /* AVDEVICE_AVDEVICE_H */
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVDEVICE_VERSION_H
|
||||
#define AVDEVICE_VERSION_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @ingroup lavd
|
||||
* Libavdevice version macros
|
||||
*/
|
||||
|
||||
#include "libavutil/avutil.h"
|
||||
|
||||
#define LIBAVDEVICE_VERSION_MAJOR 55
|
||||
#define LIBAVDEVICE_VERSION_MINOR 3
|
||||
#define LIBAVDEVICE_VERSION_MICRO 100
|
||||
|
||||
#define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
|
||||
LIBAVDEVICE_VERSION_MINOR, \
|
||||
LIBAVDEVICE_VERSION_MICRO)
|
||||
#define LIBAVDEVICE_VERSION AV_VERSION(LIBAVDEVICE_VERSION_MAJOR, \
|
||||
LIBAVDEVICE_VERSION_MINOR, \
|
||||
LIBAVDEVICE_VERSION_MICRO)
|
||||
#define LIBAVDEVICE_BUILD LIBAVDEVICE_VERSION_INT
|
||||
|
||||
#define LIBAVDEVICE_IDENT "Lavd" AV_STRINGIFY(LIBAVDEVICE_VERSION)
|
||||
|
||||
/**
|
||||
* FF_API_* defines may be placed below to indicate public API that will be
|
||||
* dropped at a future version bump. The defines themselves are not part of
|
||||
* the public API and may change, break or disappear at any time.
|
||||
*/
|
||||
|
||||
#endif /* AVDEVICE_VERSION_H */
|
||||
-2181
File diff suppressed because it is too large
Load Diff
-481
@@ -1,481 +0,0 @@
|
||||
/*
|
||||
* copyright (c) 2001 Fabrice Bellard
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef AVFORMAT_AVIO_H
|
||||
#define AVFORMAT_AVIO_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @ingroup lavf_io
|
||||
* Buffered I/O operations
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "libavutil/common.h"
|
||||
#include "libavutil/dict.h"
|
||||
#include "libavutil/log.h"
|
||||
|
||||
#include "libavformat/version.h"
|
||||
|
||||
|
||||
#define AVIO_SEEKABLE_NORMAL 0x0001 /**< Seeking works like for a local file */
|
||||
|
||||
/**
|
||||
* Callback for checking whether to abort blocking functions.
|
||||
* AVERROR_EXIT is returned in this case by the interrupted
|
||||
* function. During blocking operations, callback is called with
|
||||
* opaque as parameter. If the callback returns 1, the
|
||||
* blocking operation will be aborted.
|
||||
*
|
||||
* No members can be added to this struct without a major bump, if
|
||||
* new elements have been added after this struct in AVFormatContext
|
||||
* or AVIOContext.
|
||||
*/
|
||||
typedef struct AVIOInterruptCB {
|
||||
int (*callback)(void*);
|
||||
void *opaque;
|
||||
} AVIOInterruptCB;
|
||||
|
||||
/**
|
||||
* Bytestream IO Context.
|
||||
* New fields can be added to the end with minor version bumps.
|
||||
* Removal, reordering and changes to existing fields require a major
|
||||
* version bump.
|
||||
* sizeof(AVIOContext) must not be used outside libav*.
|
||||
*
|
||||
* @note None of the function pointers in AVIOContext should be called
|
||||
* directly, they should only be set by the client application
|
||||
* when implementing custom I/O. Normally these are set to the
|
||||
* function pointers specified in avio_alloc_context()
|
||||
*/
|
||||
typedef struct AVIOContext {
|
||||
/**
|
||||
* A class for private options.
|
||||
*
|
||||
* If this AVIOContext is created by avio_open2(), av_class is set and
|
||||
* passes the options down to protocols.
|
||||
*
|
||||
* If this AVIOContext is manually allocated, then av_class may be set by
|
||||
* the caller.
|
||||
*
|
||||
* warning -- this field can be NULL, be sure to not pass this AVIOContext
|
||||
* to any av_opt_* functions in that case.
|
||||
*/
|
||||
const AVClass *av_class;
|
||||
unsigned char *buffer; /**< Start of the buffer. */
|
||||
int buffer_size; /**< Maximum buffer size */
|
||||
unsigned char *buf_ptr; /**< Current position in the buffer */
|
||||
unsigned char *buf_end; /**< End of the data, may be less than
|
||||
buffer+buffer_size if the read function returned
|
||||
less data than requested, e.g. for streams where
|
||||
no more data has been received yet. */
|
||||
void *opaque; /**< A private pointer, passed to the read/write/seek/...
|
||||
functions. */
|
||||
int (*read_packet)(void *opaque, uint8_t *buf, int buf_size);
|
||||
int (*write_packet)(void *opaque, uint8_t *buf, int buf_size);
|
||||
int64_t (*seek)(void *opaque, int64_t offset, int whence);
|
||||
int64_t pos; /**< position in the file of the current buffer */
|
||||
int must_flush; /**< true if the next seek should flush */
|
||||
int eof_reached; /**< true if eof reached */
|
||||
int write_flag; /**< true if open for writing */
|
||||
int max_packet_size;
|
||||
unsigned long checksum;
|
||||
unsigned char *checksum_ptr;
|
||||
unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size);
|
||||
int error; /**< contains the error code or 0 if no error happened */
|
||||
/**
|
||||
* Pause or resume playback for network streaming protocols - e.g. MMS.
|
||||
*/
|
||||
int (*read_pause)(void *opaque, int pause);
|
||||
/**
|
||||
* Seek to a given timestamp in stream with the specified stream_index.
|
||||
* Needed for some network streaming protocols which don't support seeking
|
||||
* to byte position.
|
||||
*/
|
||||
int64_t (*read_seek)(void *opaque, int stream_index,
|
||||
int64_t timestamp, int flags);
|
||||
/**
|
||||
* A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
|
||||
*/
|
||||
int seekable;
|
||||
|
||||
/**
|
||||
* max filesize, used to limit allocations
|
||||
* This field is internal to libavformat and access from outside is not allowed.
|
||||
*/
|
||||
int64_t maxsize;
|
||||
|
||||
/**
|
||||
* avio_read and avio_write should if possible be satisfied directly
|
||||
* instead of going through a buffer, and avio_seek will always
|
||||
* call the underlying seek function directly.
|
||||
*/
|
||||
int direct;
|
||||
|
||||
/**
|
||||
* Bytes read statistic
|
||||
* This field is internal to libavformat and access from outside is not allowed.
|
||||
*/
|
||||
int64_t bytes_read;
|
||||
|
||||
/**
|
||||
* seek statistic
|
||||
* This field is internal to libavformat and access from outside is not allowed.
|
||||
*/
|
||||
int seek_count;
|
||||
|
||||
/**
|
||||
* writeout statistic
|
||||
* This field is internal to libavformat and access from outside is not allowed.
|
||||
*/
|
||||
int writeout_count;
|
||||
} AVIOContext;
|
||||
|
||||
/* unbuffered I/O */
|
||||
|
||||
/**
|
||||
* Return AVIO_FLAG_* access flags corresponding to the access permissions
|
||||
* of the resource in url, or a negative value corresponding to an
|
||||
* AVERROR code in case of failure. The returned access flags are
|
||||
* masked by the value in flags.
|
||||
*
|
||||
* @note This function is intrinsically unsafe, in the sense that the
|
||||
* checked resource may change its existence or permission status from
|
||||
* one call to another. Thus you should not trust the returned value,
|
||||
* unless you are sure that no other processes are accessing the
|
||||
* checked resource.
|
||||
*/
|
||||
int avio_check(const char *url, int flags);
|
||||
|
||||
/**
|
||||
* Allocate and initialize an AVIOContext for buffered I/O. It must be later
|
||||
* freed with av_free().
|
||||
*
|
||||
* @param buffer Memory block for input/output operations via AVIOContext.
|
||||
* The buffer must be allocated with av_malloc() and friends.
|
||||
* @param buffer_size The buffer size is very important for performance.
|
||||
* For protocols with fixed blocksize it should be set to this blocksize.
|
||||
* For others a typical size is a cache page, e.g. 4kb.
|
||||
* @param write_flag Set to 1 if the buffer should be writable, 0 otherwise.
|
||||
* @param opaque An opaque pointer to user-specific data.
|
||||
* @param read_packet A function for refilling the buffer, may be NULL.
|
||||
* @param write_packet A function for writing the buffer contents, may be NULL.
|
||||
* The function may not change the input buffers content.
|
||||
* @param seek A function for seeking to specified byte position, may be NULL.
|
||||
*
|
||||
* @return Allocated AVIOContext or NULL on failure.
|
||||
*/
|
||||
AVIOContext *avio_alloc_context(
|
||||
unsigned char *buffer,
|
||||
int buffer_size,
|
||||
int write_flag,
|
||||
void *opaque,
|
||||
int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
|
||||
int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
|
||||
int64_t (*seek)(void *opaque, int64_t offset, int whence));
|
||||
|
||||
void avio_w8(AVIOContext *s, int b);
|
||||
void avio_write(AVIOContext *s, const unsigned char *buf, int size);
|
||||
void avio_wl64(AVIOContext *s, uint64_t val);
|
||||
void avio_wb64(AVIOContext *s, uint64_t val);
|
||||
void avio_wl32(AVIOContext *s, unsigned int val);
|
||||
void avio_wb32(AVIOContext *s, unsigned int val);
|
||||
void avio_wl24(AVIOContext *s, unsigned int val);
|
||||
void avio_wb24(AVIOContext *s, unsigned int val);
|
||||
void avio_wl16(AVIOContext *s, unsigned int val);
|
||||
void avio_wb16(AVIOContext *s, unsigned int val);
|
||||
|
||||
/**
|
||||
* Write a NULL-terminated string.
|
||||
* @return number of bytes written.
|
||||
*/
|
||||
int avio_put_str(AVIOContext *s, const char *str);
|
||||
|
||||
/**
|
||||
* Convert an UTF-8 string to UTF-16LE and write it.
|
||||
* @return number of bytes written.
|
||||
*/
|
||||
int avio_put_str16le(AVIOContext *s, const char *str);
|
||||
|
||||
/**
|
||||
* Passing this as the "whence" parameter to a seek function causes it to
|
||||
* return the filesize without seeking anywhere. Supporting this is optional.
|
||||
* If it is not supported then the seek function will return <0.
|
||||
*/
|
||||
#define AVSEEK_SIZE 0x10000
|
||||
|
||||
/**
|
||||
* Oring this flag as into the "whence" parameter to a seek function causes it to
|
||||
* seek by any means (like reopening and linear reading) or other normally unreasonable
|
||||
* means that can be extremely slow.
|
||||
* This may be ignored by the seek code.
|
||||
*/
|
||||
#define AVSEEK_FORCE 0x20000
|
||||
|
||||
/**
|
||||
* fseek() equivalent for AVIOContext.
|
||||
* @return new position or AVERROR.
|
||||
*/
|
||||
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence);
|
||||
|
||||
/**
|
||||
* Skip given number of bytes forward
|
||||
* @return new position or AVERROR.
|
||||
*/
|
||||
int64_t avio_skip(AVIOContext *s, int64_t offset);
|
||||
|
||||
/**
|
||||
* ftell() equivalent for AVIOContext.
|
||||
* @return position or AVERROR.
|
||||
*/
|
||||
static av_always_inline int64_t avio_tell(AVIOContext *s)
|
||||
{
|
||||
return avio_seek(s, 0, SEEK_CUR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filesize.
|
||||
* @return filesize or AVERROR
|
||||
*/
|
||||
int64_t avio_size(AVIOContext *s);
|
||||
|
||||
/**
|
||||
* feof() equivalent for AVIOContext.
|
||||
* @return non zero if and only if end of file
|
||||
*/
|
||||
int url_feof(AVIOContext *s);
|
||||
|
||||
/** @warning currently size is limited */
|
||||
int avio_printf(AVIOContext *s, const char *fmt, ...) av_printf_format(2, 3);
|
||||
|
||||
/**
|
||||
* Force flushing of buffered data to the output s.
|
||||
*
|
||||
* Force the buffered data to be immediately written to the output,
|
||||
* without to wait to fill the internal buffer.
|
||||
*/
|
||||
void avio_flush(AVIOContext *s);
|
||||
|
||||
/**
|
||||
* Read size bytes from AVIOContext into buf.
|
||||
* @return number of bytes read or AVERROR
|
||||
*/
|
||||
int avio_read(AVIOContext *s, unsigned char *buf, int size);
|
||||
|
||||
/**
|
||||
* @name Functions for reading from AVIOContext
|
||||
* @{
|
||||
*
|
||||
* @note return 0 if EOF, so you cannot use it if EOF handling is
|
||||
* necessary
|
||||
*/
|
||||
int avio_r8 (AVIOContext *s);
|
||||
unsigned int avio_rl16(AVIOContext *s);
|
||||
unsigned int avio_rl24(AVIOContext *s);
|
||||
unsigned int avio_rl32(AVIOContext *s);
|
||||
uint64_t avio_rl64(AVIOContext *s);
|
||||
unsigned int avio_rb16(AVIOContext *s);
|
||||
unsigned int avio_rb24(AVIOContext *s);
|
||||
unsigned int avio_rb32(AVIOContext *s);
|
||||
uint64_t avio_rb64(AVIOContext *s);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Read a string from pb into buf. The reading will terminate when either
|
||||
* a NULL character was encountered, maxlen bytes have been read, or nothing
|
||||
* more can be read from pb. The result is guaranteed to be NULL-terminated, it
|
||||
* will be truncated if buf is too small.
|
||||
* Note that the string is not interpreted or validated in any way, it
|
||||
* might get truncated in the middle of a sequence for multi-byte encodings.
|
||||
*
|
||||
* @return number of bytes read (is always <= maxlen).
|
||||
* If reading ends on EOF or error, the return value will be one more than
|
||||
* bytes actually read.
|
||||
*/
|
||||
int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen);
|
||||
|
||||
/**
|
||||
* Read a UTF-16 string from pb and convert it to UTF-8.
|
||||
* The reading will terminate when either a null or invalid character was
|
||||
* encountered or maxlen bytes have been read.
|
||||
* @return number of bytes read (is always <= maxlen)
|
||||
*/
|
||||
int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen);
|
||||
int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen);
|
||||
|
||||
|
||||
/**
|
||||
* @name URL open modes
|
||||
* The flags argument to avio_open must be one of the following
|
||||
* constants, optionally ORed with other flags.
|
||||
* @{
|
||||
*/
|
||||
#define AVIO_FLAG_READ 1 /**< read-only */
|
||||
#define AVIO_FLAG_WRITE 2 /**< write-only */
|
||||
#define AVIO_FLAG_READ_WRITE (AVIO_FLAG_READ|AVIO_FLAG_WRITE) /**< read-write pseudo flag */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Use non-blocking mode.
|
||||
* If this flag is set, operations on the context will return
|
||||
* AVERROR(EAGAIN) if they can not be performed immediately.
|
||||
* If this flag is not set, operations on the context will never return
|
||||
* AVERROR(EAGAIN).
|
||||
* Note that this flag does not affect the opening/connecting of the
|
||||
* context. Connecting a protocol will always block if necessary (e.g. on
|
||||
* network protocols) but never hang (e.g. on busy devices).
|
||||
* Warning: non-blocking protocols is work-in-progress; this flag may be
|
||||
* silently ignored.
|
||||
*/
|
||||
#define AVIO_FLAG_NONBLOCK 8
|
||||
|
||||
/**
|
||||
* Use direct mode.
|
||||
* avio_read and avio_write should if possible be satisfied directly
|
||||
* instead of going through a buffer, and avio_seek will always
|
||||
* call the underlying seek function directly.
|
||||
*/
|
||||
#define AVIO_FLAG_DIRECT 0x8000
|
||||
|
||||
/**
|
||||
* Create and initialize a AVIOContext for accessing the
|
||||
* resource indicated by url.
|
||||
* @note When the resource indicated by url has been opened in
|
||||
* read+write mode, the AVIOContext can be used only for writing.
|
||||
*
|
||||
* @param s Used to return the pointer to the created AVIOContext.
|
||||
* In case of failure the pointed to value is set to NULL.
|
||||
* @param flags flags which control how the resource indicated by url
|
||||
* is to be opened
|
||||
* @return 0 in case of success, a negative value corresponding to an
|
||||
* AVERROR code in case of failure
|
||||
*/
|
||||
int avio_open(AVIOContext **s, const char *url, int flags);
|
||||
|
||||
/**
|
||||
* Create and initialize a AVIOContext for accessing the
|
||||
* resource indicated by url.
|
||||
* @note When the resource indicated by url has been opened in
|
||||
* read+write mode, the AVIOContext can be used only for writing.
|
||||
*
|
||||
* @param s Used to return the pointer to the created AVIOContext.
|
||||
* In case of failure the pointed to value is set to NULL.
|
||||
* @param flags flags which control how the resource indicated by url
|
||||
* is to be opened
|
||||
* @param int_cb an interrupt callback to be used at the protocols level
|
||||
* @param options A dictionary filled with protocol-private options. On return
|
||||
* this parameter will be destroyed and replaced with a dict containing options
|
||||
* that were not found. May be NULL.
|
||||
* @return 0 in case of success, a negative value corresponding to an
|
||||
* AVERROR code in case of failure
|
||||
*/
|
||||
int avio_open2(AVIOContext **s, const char *url, int flags,
|
||||
const AVIOInterruptCB *int_cb, AVDictionary **options);
|
||||
|
||||
/**
|
||||
* Close the resource accessed by the AVIOContext s and free it.
|
||||
* This function can only be used if s was opened by avio_open().
|
||||
*
|
||||
* The internal buffer is automatically flushed before closing the
|
||||
* resource.
|
||||
*
|
||||
* @return 0 on success, an AVERROR < 0 on error.
|
||||
* @see avio_closep
|
||||
*/
|
||||
int avio_close(AVIOContext *s);
|
||||
|
||||
/**
|
||||
* Close the resource accessed by the AVIOContext *s, free it
|
||||
* and set the pointer pointing to it to NULL.
|
||||
* This function can only be used if s was opened by avio_open().
|
||||
*
|
||||
* The internal buffer is automatically flushed before closing the
|
||||
* resource.
|
||||
*
|
||||
* @return 0 on success, an AVERROR < 0 on error.
|
||||
* @see avio_close
|
||||
*/
|
||||
int avio_closep(AVIOContext **s);
|
||||
|
||||
|
||||
/**
|
||||
* Open a write only memory stream.
|
||||
*
|
||||
* @param s new IO context
|
||||
* @return zero if no error.
|
||||
*/
|
||||
int avio_open_dyn_buf(AVIOContext **s);
|
||||
|
||||
/**
|
||||
* Return the written size and a pointer to the buffer. The buffer
|
||||
* must be freed with av_free().
|
||||
* Padding of FF_INPUT_BUFFER_PADDING_SIZE is added to the buffer.
|
||||
*
|
||||
* @param s IO context
|
||||
* @param pbuffer pointer to a byte buffer
|
||||
* @return the length of the byte buffer
|
||||
*/
|
||||
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer);
|
||||
|
||||
/**
|
||||
* Iterate through names of available protocols.
|
||||
*
|
||||
* @param opaque A private pointer representing current protocol.
|
||||
* It must be a pointer to NULL on first iteration and will
|
||||
* be updated by successive calls to avio_enum_protocols.
|
||||
* @param output If set to 1, iterate over output protocols,
|
||||
* otherwise over input protocols.
|
||||
*
|
||||
* @return A static string containing the name of current protocol or NULL
|
||||
*/
|
||||
const char *avio_enum_protocols(void **opaque, int output);
|
||||
|
||||
/**
|
||||
* Pause and resume playing - only meaningful if using a network streaming
|
||||
* protocol (e.g. MMS).
|
||||
* @param pause 1 for pause, 0 for resume
|
||||
*/
|
||||
int avio_pause(AVIOContext *h, int pause);
|
||||
|
||||
/**
|
||||
* Seek to a given timestamp relative to some component stream.
|
||||
* Only meaningful if using a network streaming protocol (e.g. MMS.).
|
||||
* @param stream_index The stream index that the timestamp is relative to.
|
||||
* If stream_index is (-1) the timestamp should be in AV_TIME_BASE
|
||||
* units from the beginning of the presentation.
|
||||
* If a stream_index >= 0 is used and the protocol does not support
|
||||
* seeking based on component streams, the call will fail.
|
||||
* @param timestamp timestamp in AVStream.time_base units
|
||||
* or if there is no stream specified then in AV_TIME_BASE units.
|
||||
* @param flags Optional combination of AVSEEK_FLAG_BACKWARD, AVSEEK_FLAG_BYTE
|
||||
* and AVSEEK_FLAG_ANY. The protocol may silently ignore
|
||||
* AVSEEK_FLAG_BACKWARD and AVSEEK_FLAG_ANY, but AVSEEK_FLAG_BYTE will
|
||||
* fail if used and not supported.
|
||||
* @return >= 0 on success
|
||||
* @see AVInputFormat::read_seek
|
||||
*/
|
||||
int64_t avio_seek_time(AVIOContext *h, int stream_index,
|
||||
int64_t timestamp, int flags);
|
||||
|
||||
#endif /* AVFORMAT_AVIO_H */
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Version macros.
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVFORMAT_VERSION_H
|
||||
#define AVFORMAT_VERSION_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @ingroup libavf
|
||||
* Libavformat version macros
|
||||
*/
|
||||
|
||||
#include "libavutil/avutil.h"
|
||||
|
||||
#define LIBAVFORMAT_VERSION_MAJOR 55
|
||||
#define LIBAVFORMAT_VERSION_MINOR 12
|
||||
#define LIBAVFORMAT_VERSION_MICRO 100
|
||||
|
||||
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
||||
LIBAVFORMAT_VERSION_MINOR, \
|
||||
LIBAVFORMAT_VERSION_MICRO)
|
||||
#define LIBAVFORMAT_VERSION AV_VERSION(LIBAVFORMAT_VERSION_MAJOR, \
|
||||
LIBAVFORMAT_VERSION_MINOR, \
|
||||
LIBAVFORMAT_VERSION_MICRO)
|
||||
#define LIBAVFORMAT_BUILD LIBAVFORMAT_VERSION_INT
|
||||
|
||||
#define LIBAVFORMAT_IDENT "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION)
|
||||
|
||||
/**
|
||||
* FF_API_* defines may be placed below to indicate public API that will be
|
||||
* dropped at a future version bump. The defines themselves are not part of
|
||||
* the public API and may change, break or disappear at any time.
|
||||
*/
|
||||
|
||||
#ifndef FF_API_OLD_AVIO
|
||||
#define FF_API_OLD_AVIO (LIBAVFORMAT_VERSION_MAJOR < 55)
|
||||
#endif
|
||||
#ifndef FF_API_PKT_DUMP
|
||||
#define FF_API_PKT_DUMP (LIBAVFORMAT_VERSION_MAJOR < 54)
|
||||
#endif
|
||||
#ifndef FF_API_ALLOC_OUTPUT_CONTEXT
|
||||
#define FF_API_ALLOC_OUTPUT_CONTEXT (LIBAVFORMAT_VERSION_MAJOR < 56)
|
||||
#endif
|
||||
#ifndef FF_API_FORMAT_PARAMETERS
|
||||
#define FF_API_FORMAT_PARAMETERS (LIBAVFORMAT_VERSION_MAJOR < 56)
|
||||
#endif
|
||||
#ifndef FF_API_NEW_STREAM
|
||||
#define FF_API_NEW_STREAM (LIBAVFORMAT_VERSION_MAJOR < 56)
|
||||
#endif
|
||||
#ifndef FF_API_SET_PTS_INFO
|
||||
#define FF_API_SET_PTS_INFO (LIBAVFORMAT_VERSION_MAJOR < 56)
|
||||
#endif
|
||||
#ifndef FF_API_CLOSE_INPUT_FILE
|
||||
#define FF_API_CLOSE_INPUT_FILE (LIBAVFORMAT_VERSION_MAJOR < 56)
|
||||
#endif
|
||||
#ifndef FF_API_READ_PACKET
|
||||
#define FF_API_READ_PACKET (LIBAVFORMAT_VERSION_MAJOR < 56)
|
||||
#endif
|
||||
#ifndef FF_API_ASS_SSA
|
||||
#define FF_API_ASS_SSA (LIBAVFORMAT_VERSION_MAJOR < 56)
|
||||
#endif
|
||||
#ifndef FF_API_R_FRAME_RATE
|
||||
#define FF_API_R_FRAME_RATE 1
|
||||
#endif
|
||||
#endif /* AVFORMAT_VERSION_H */
|
||||
-52
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* copyright (c) 2006 Mans Rullgard
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVUTIL_ADLER32_H
|
||||
#define AVUTIL_ADLER32_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "attributes.h"
|
||||
|
||||
/**
|
||||
* @defgroup lavu_adler32 Adler32
|
||||
* @ingroup lavu_crypto
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Calculate the Adler32 checksum of a buffer.
|
||||
*
|
||||
* Passing the return value to a subsequent av_adler32_update() call
|
||||
* allows the checksum of multiple buffers to be calculated as though
|
||||
* they were concatenated.
|
||||
*
|
||||
* @param adler initial checksum value
|
||||
* @param buf pointer to input buffer
|
||||
* @param len size of input buffer
|
||||
* @return updated checksum
|
||||
*/
|
||||
unsigned long av_adler32_update(unsigned long adler, const uint8_t *buf,
|
||||
unsigned int len) av_pure;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* AVUTIL_ADLER32_H */
|
||||
-65
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* copyright (c) 2007 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVUTIL_AES_H
|
||||
#define AVUTIL_AES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "attributes.h"
|
||||
#include "version.h"
|
||||
|
||||
/**
|
||||
* @defgroup lavu_aes AES
|
||||
* @ingroup lavu_crypto
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern const int av_aes_size;
|
||||
|
||||
struct AVAES;
|
||||
|
||||
/**
|
||||
* Allocate an AVAES context.
|
||||
*/
|
||||
struct AVAES *av_aes_alloc(void);
|
||||
|
||||
/**
|
||||
* Initialize an AVAES context.
|
||||
* @param key_bits 128, 192 or 256
|
||||
* @param decrypt 0 for encryption, 1 for decryption
|
||||
*/
|
||||
int av_aes_init(struct AVAES *a, const uint8_t *key, int key_bits, int decrypt);
|
||||
|
||||
/**
|
||||
* Encrypt or decrypt a buffer using a previously initialized context.
|
||||
* @param count number of 16 byte blocks
|
||||
* @param dst destination array, can be equal to src
|
||||
* @param src source array, can be equal to dst
|
||||
* @param iv initialization vector for CBC mode, if NULL then ECB will be used
|
||||
* @param decrypt 0 for encryption, 1 for decryption
|
||||
*/
|
||||
void av_aes_crypt(struct AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* AVUTIL_AES_H */
|
||||
-154
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
* copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Macro definitions for various function/variable attributes
|
||||
*/
|
||||
|
||||
#ifndef AVUTIL_ATTRIBUTES_H
|
||||
#define AVUTIL_ATTRIBUTES_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define AV_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > x || __GNUC__ == x && __GNUC_MINOR__ >= y)
|
||||
#else
|
||||
# define AV_GCC_VERSION_AT_LEAST(x,y) 0
|
||||
#endif
|
||||
|
||||
#ifndef av_always_inline
|
||||
#if AV_GCC_VERSION_AT_LEAST(3,1)
|
||||
# define av_always_inline __attribute__((always_inline)) inline
|
||||
#elif defined(_MSC_VER)
|
||||
# define av_always_inline __forceinline
|
||||
#else
|
||||
# define av_always_inline inline
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef av_extern_inline
|
||||
#if defined(__ICL) && __ICL >= 1210 || defined(__GNUC_STDC_INLINE__)
|
||||
# define av_extern_inline extern inline
|
||||
#else
|
||||
# define av_extern_inline inline
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if AV_GCC_VERSION_AT_LEAST(3,1)
|
||||
# define av_noinline __attribute__((noinline))
|
||||
#else
|
||||
# define av_noinline
|
||||
#endif
|
||||
|
||||
#if AV_GCC_VERSION_AT_LEAST(3,1)
|
||||
# define av_pure __attribute__((pure))
|
||||
#else
|
||||
# define av_pure
|
||||
#endif
|
||||
|
||||
#ifndef av_restrict
|
||||
#define av_restrict restrict
|
||||
#endif
|
||||
|
||||
#if AV_GCC_VERSION_AT_LEAST(2,6)
|
||||
# define av_const __attribute__((const))
|
||||
#else
|
||||
# define av_const
|
||||
#endif
|
||||
|
||||
#if AV_GCC_VERSION_AT_LEAST(4,3)
|
||||
# define av_cold __attribute__((cold))
|
||||
#else
|
||||
# define av_cold
|
||||
#endif
|
||||
|
||||
#if AV_GCC_VERSION_AT_LEAST(4,1)
|
||||
# define av_flatten __attribute__((flatten))
|
||||
#else
|
||||
# define av_flatten
|
||||
#endif
|
||||
|
||||
#if AV_GCC_VERSION_AT_LEAST(3,1)
|
||||
# define attribute_deprecated __attribute__((deprecated))
|
||||
#else
|
||||
# define attribute_deprecated
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Disable warnings about deprecated features
|
||||
* This is useful for sections of code kept for backward compatibility and
|
||||
* scheduled for removal.
|
||||
*/
|
||||
#ifndef AV_NOWARN_DEPRECATED
|
||||
#if AV_GCC_VERSION_AT_LEAST(4,6)
|
||||
# define AV_NOWARN_DEPRECATED(code) \
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") \
|
||||
code \
|
||||
_Pragma("GCC diagnostic pop")
|
||||
#else
|
||||
# define AV_NOWARN_DEPRECATED(code) code
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# define av_unused __attribute__((unused))
|
||||
#else
|
||||
# define av_unused
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Mark a variable as used and prevent the compiler from optimizing it
|
||||
* away. This is useful for variables accessed only from inline
|
||||
* assembler without the compiler being aware.
|
||||
*/
|
||||
#if AV_GCC_VERSION_AT_LEAST(3,1)
|
||||
# define av_used __attribute__((used))
|
||||
#else
|
||||
# define av_used
|
||||
#endif
|
||||
|
||||
#if AV_GCC_VERSION_AT_LEAST(3,3)
|
||||
# define av_alias __attribute__((may_alias))
|
||||
#else
|
||||
# define av_alias
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
|
||||
# define av_uninit(x) x=x
|
||||
#else
|
||||
# define av_uninit(x) x
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define av_builtin_constant_p __builtin_constant_p
|
||||
# define av_printf_format(fmtpos, attrpos) __attribute__((__format__(__printf__, fmtpos, attrpos)))
|
||||
#else
|
||||
# define av_builtin_constant_p(x) 0
|
||||
# define av_printf_format(fmtpos, attrpos)
|
||||
#endif
|
||||
|
||||
#if AV_GCC_VERSION_AT_LEAST(2,5)
|
||||
# define av_noreturn __attribute__((noreturn))
|
||||
#else
|
||||
# define av_noreturn
|
||||
#endif
|
||||
|
||||
#endif /* AVUTIL_ATTRIBUTES_H */
|
||||
-149
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* Audio FIFO
|
||||
* Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
|
||||
*
|
||||
* This file is part of Libav.
|
||||
*
|
||||
* Libav is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* Libav is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with Libav; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Audio FIFO Buffer
|
||||
*/
|
||||
|
||||
#ifndef AVUTIL_AUDIO_FIFO_H
|
||||
#define AVUTIL_AUDIO_FIFO_H
|
||||
|
||||
#include "avutil.h"
|
||||
#include "fifo.h"
|
||||
#include "samplefmt.h"
|
||||
|
||||
/**
|
||||
* @addtogroup lavu_audio
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Context for an Audio FIFO Buffer.
|
||||
*
|
||||
* - Operates at the sample level rather than the byte level.
|
||||
* - Supports multiple channels with either planar or packed sample format.
|
||||
* - Automatic reallocation when writing to a full buffer.
|
||||
*/
|
||||
typedef struct AVAudioFifo AVAudioFifo;
|
||||
|
||||
/**
|
||||
* Free an AVAudioFifo.
|
||||
*
|
||||
* @param af AVAudioFifo to free
|
||||
*/
|
||||
void av_audio_fifo_free(AVAudioFifo *af);
|
||||
|
||||
/**
|
||||
* Allocate an AVAudioFifo.
|
||||
*
|
||||
* @param sample_fmt sample format
|
||||
* @param channels number of channels
|
||||
* @param nb_samples initial allocation size, in samples
|
||||
* @return newly allocated AVAudioFifo, or NULL on error
|
||||
*/
|
||||
AVAudioFifo *av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels,
|
||||
int nb_samples);
|
||||
|
||||
/**
|
||||
* Reallocate an AVAudioFifo.
|
||||
*
|
||||
* @param af AVAudioFifo to reallocate
|
||||
* @param nb_samples new allocation size, in samples
|
||||
* @return 0 if OK, or negative AVERROR code on failure
|
||||
*/
|
||||
int av_audio_fifo_realloc(AVAudioFifo *af, int nb_samples);
|
||||
|
||||
/**
|
||||
* Write data to an AVAudioFifo.
|
||||
*
|
||||
* The AVAudioFifo will be reallocated automatically if the available space
|
||||
* is less than nb_samples.
|
||||
*
|
||||
* @see enum AVSampleFormat
|
||||
* The documentation for AVSampleFormat describes the data layout.
|
||||
*
|
||||
* @param af AVAudioFifo to write to
|
||||
* @param data audio data plane pointers
|
||||
* @param nb_samples number of samples to write
|
||||
* @return number of samples actually written, or negative AVERROR
|
||||
* code on failure. If successful, the number of samples
|
||||
* actually written will always be nb_samples.
|
||||
*/
|
||||
int av_audio_fifo_write(AVAudioFifo *af, void **data, int nb_samples);
|
||||
|
||||
/**
|
||||
* Read data from an AVAudioFifo.
|
||||
*
|
||||
* @see enum AVSampleFormat
|
||||
* The documentation for AVSampleFormat describes the data layout.
|
||||
*
|
||||
* @param af AVAudioFifo to read from
|
||||
* @param data audio data plane pointers
|
||||
* @param nb_samples number of samples to read
|
||||
* @return number of samples actually read, or negative AVERROR code
|
||||
* on failure. The number of samples actually read will not
|
||||
* be greater than nb_samples, and will only be less than
|
||||
* nb_samples if av_audio_fifo_size is less than nb_samples.
|
||||
*/
|
||||
int av_audio_fifo_read(AVAudioFifo *af, void **data, int nb_samples);
|
||||
|
||||
/**
|
||||
* Drain data from an AVAudioFifo.
|
||||
*
|
||||
* Removes the data without reading it.
|
||||
*
|
||||
* @param af AVAudioFifo to drain
|
||||
* @param nb_samples number of samples to drain
|
||||
* @return 0 if OK, or negative AVERROR code on failure
|
||||
*/
|
||||
int av_audio_fifo_drain(AVAudioFifo *af, int nb_samples);
|
||||
|
||||
/**
|
||||
* Reset the AVAudioFifo buffer.
|
||||
*
|
||||
* This empties all data in the buffer.
|
||||
*
|
||||
* @param af AVAudioFifo to reset
|
||||
*/
|
||||
void av_audio_fifo_reset(AVAudioFifo *af);
|
||||
|
||||
/**
|
||||
* Get the current number of samples in the AVAudioFifo available for reading.
|
||||
*
|
||||
* @param af the AVAudioFifo to query
|
||||
* @return number of samples available for reading
|
||||
*/
|
||||
int av_audio_fifo_size(AVAudioFifo *af);
|
||||
|
||||
/**
|
||||
* Get the current number of samples in the AVAudioFifo available for writing.
|
||||
*
|
||||
* @param af the AVAudioFifo to query
|
||||
* @return number of samples available for writing
|
||||
*/
|
||||
int av_audio_fifo_space(AVAudioFifo *af);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* AVUTIL_AUDIO_FIFO_H */
|
||||
@@ -1,6 +0,0 @@
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#if FF_API_AUDIOCONVERT
|
||||
#include "channel_layout.h"
|
||||
#endif
|
||||
-66
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* copyright (c) 2010 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* simple assert() macros that are a bit more flexible than ISO C assert().
|
||||
* @author Michael Niedermayer <michaelni@gmx.at>
|
||||
*/
|
||||
|
||||
#ifndef AVUTIL_AVASSERT_H
|
||||
#define AVUTIL_AVASSERT_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "avutil.h"
|
||||
#include "log.h"
|
||||
|
||||
/**
|
||||
* assert() equivalent, that is always enabled.
|
||||
*/
|
||||
#define av_assert0(cond) do { \
|
||||
if (!(cond)) { \
|
||||
av_log(NULL, AV_LOG_PANIC, "Assertion %s failed at %s:%d\n", \
|
||||
AV_STRINGIFY(cond), __FILE__, __LINE__); \
|
||||
abort(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**
|
||||
* assert() equivalent, that does not lie in speed critical code.
|
||||
* These asserts() thus can be enabled without fearing speedloss.
|
||||
*/
|
||||
#if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 0
|
||||
#define av_assert1(cond) av_assert0(cond)
|
||||
#else
|
||||
#define av_assert1(cond) ((void)0)
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* assert() equivalent, that does lie in speed critical code.
|
||||
*/
|
||||
#if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1
|
||||
#define av_assert2(cond) av_assert0(cond)
|
||||
#else
|
||||
#define av_assert2(cond) ((void)0)
|
||||
#endif
|
||||
|
||||
#endif /* AVUTIL_AVASSERT_H */
|
||||
@@ -1,8 +0,0 @@
|
||||
/* Generated by ffconf */
|
||||
#ifndef AVUTIL_AVCONFIG_H
|
||||
#define AVUTIL_AVCONFIG_H
|
||||
#define AV_HAVE_BIGENDIAN 0
|
||||
#define AV_HAVE_FAST_UNALIGNED 1
|
||||
#define AV_HAVE_INCOMPATIBLE_LIBAV_ABI 0
|
||||
#define AV_HAVE_INCOMPATIBLE_FORK_ABI 0
|
||||
#endif /* AVUTIL_AVCONFIG_H */
|
||||
-302
@@ -1,302 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Mans Rullgard
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVUTIL_AVSTRING_H
|
||||
#define AVUTIL_AVSTRING_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "attributes.h"
|
||||
|
||||
/**
|
||||
* @addtogroup lavu_string
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return non-zero if pfx is a prefix of str. If it is, *ptr is set to
|
||||
* the address of the first character in str after the prefix.
|
||||
*
|
||||
* @param str input string
|
||||
* @param pfx prefix to test
|
||||
* @param ptr updated if the prefix is matched inside str
|
||||
* @return non-zero if the prefix matches, zero otherwise
|
||||
*/
|
||||
int av_strstart(const char *str, const char *pfx, const char **ptr);
|
||||
|
||||
/**
|
||||
* Return non-zero if pfx is a prefix of str independent of case. If
|
||||
* it is, *ptr is set to the address of the first character in str
|
||||
* after the prefix.
|
||||
*
|
||||
* @param str input string
|
||||
* @param pfx prefix to test
|
||||
* @param ptr updated if the prefix is matched inside str
|
||||
* @return non-zero if the prefix matches, zero otherwise
|
||||
*/
|
||||
int av_stristart(const char *str, const char *pfx, const char **ptr);
|
||||
|
||||
/**
|
||||
* Locate the first case-independent occurrence in the string haystack
|
||||
* of the string needle. A zero-length string needle is considered to
|
||||
* match at the start of haystack.
|
||||
*
|
||||
* This function is a case-insensitive version of the standard strstr().
|
||||
*
|
||||
* @param haystack string to search in
|
||||
* @param needle string to search for
|
||||
* @return pointer to the located match within haystack
|
||||
* or a null pointer if no match
|
||||
*/
|
||||
char *av_stristr(const char *haystack, const char *needle);
|
||||
|
||||
/**
|
||||
* Locate the first occurrence of the string needle in the string haystack
|
||||
* where not more than hay_length characters are searched. A zero-length
|
||||
* string needle is considered to match at the start of haystack.
|
||||
*
|
||||
* This function is a length-limited version of the standard strstr().
|
||||
*
|
||||
* @param haystack string to search in
|
||||
* @param needle string to search for
|
||||
* @param hay_length length of string to search in
|
||||
* @return pointer to the located match within haystack
|
||||
* or a null pointer if no match
|
||||
*/
|
||||
char *av_strnstr(const char *haystack, const char *needle, size_t hay_length);
|
||||
|
||||
/**
|
||||
* Copy the string src to dst, but no more than size - 1 bytes, and
|
||||
* null-terminate dst.
|
||||
*
|
||||
* This function is the same as BSD strlcpy().
|
||||
*
|
||||
* @param dst destination buffer
|
||||
* @param src source string
|
||||
* @param size size of destination buffer
|
||||
* @return the length of src
|
||||
*
|
||||
* @warning since the return value is the length of src, src absolutely
|
||||
* _must_ be a properly 0-terminated string, otherwise this will read beyond
|
||||
* the end of the buffer and possibly crash.
|
||||
*/
|
||||
size_t av_strlcpy(char *dst, const char *src, size_t size);
|
||||
|
||||
/**
|
||||
* Append the string src to the string dst, but to a total length of
|
||||
* no more than size - 1 bytes, and null-terminate dst.
|
||||
*
|
||||
* This function is similar to BSD strlcat(), but differs when
|
||||
* size <= strlen(dst).
|
||||
*
|
||||
* @param dst destination buffer
|
||||
* @param src source string
|
||||
* @param size size of destination buffer
|
||||
* @return the total length of src and dst
|
||||
*
|
||||
* @warning since the return value use the length of src and dst, these
|
||||
* absolutely _must_ be a properly 0-terminated strings, otherwise this
|
||||
* will read beyond the end of the buffer and possibly crash.
|
||||
*/
|
||||
size_t av_strlcat(char *dst, const char *src, size_t size);
|
||||
|
||||
/**
|
||||
* Append output to a string, according to a format. Never write out of
|
||||
* the destination buffer, and always put a terminating 0 within
|
||||
* the buffer.
|
||||
* @param dst destination buffer (string to which the output is
|
||||
* appended)
|
||||
* @param size total size of the destination buffer
|
||||
* @param fmt printf-compatible format string, specifying how the
|
||||
* following parameters are used
|
||||
* @return the length of the string that would have been generated
|
||||
* if enough space had been available
|
||||
*/
|
||||
size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...) av_printf_format(3, 4);
|
||||
|
||||
/**
|
||||
* Print arguments following specified format into a large enough auto
|
||||
* allocated buffer. It is similar to GNU asprintf().
|
||||
* @param fmt printf-compatible format string, specifying how the
|
||||
* following parameters are used.
|
||||
* @return the allocated string
|
||||
* @note You have to free the string yourself with av_free().
|
||||
*/
|
||||
char *av_asprintf(const char *fmt, ...) av_printf_format(1, 2);
|
||||
|
||||
/**
|
||||
* Convert a number to a av_malloced string.
|
||||
*/
|
||||
char *av_d2str(double d);
|
||||
|
||||
/**
|
||||
* Unescape the given string until a non escaped terminating char,
|
||||
* and return the token corresponding to the unescaped string.
|
||||
*
|
||||
* The normal \ and ' escaping is supported. Leading and trailing
|
||||
* whitespaces are removed, unless they are escaped with '\' or are
|
||||
* enclosed between ''.
|
||||
*
|
||||
* @param buf the buffer to parse, buf will be updated to point to the
|
||||
* terminating char
|
||||
* @param term a 0-terminated list of terminating chars
|
||||
* @return the malloced unescaped string, which must be av_freed by
|
||||
* the user, NULL in case of allocation failure
|
||||
*/
|
||||
char *av_get_token(const char **buf, const char *term);
|
||||
|
||||
/**
|
||||
* Split the string into several tokens which can be accessed by
|
||||
* successive calls to av_strtok().
|
||||
*
|
||||
* A token is defined as a sequence of characters not belonging to the
|
||||
* set specified in delim.
|
||||
*
|
||||
* On the first call to av_strtok(), s should point to the string to
|
||||
* parse, and the value of saveptr is ignored. In subsequent calls, s
|
||||
* should be NULL, and saveptr should be unchanged since the previous
|
||||
* call.
|
||||
*
|
||||
* This function is similar to strtok_r() defined in POSIX.1.
|
||||
*
|
||||
* @param s the string to parse, may be NULL
|
||||
* @param delim 0-terminated list of token delimiters, must be non-NULL
|
||||
* @param saveptr user-provided pointer which points to stored
|
||||
* information necessary for av_strtok() to continue scanning the same
|
||||
* string. saveptr is updated to point to the next character after the
|
||||
* first delimiter found, or to NULL if the string was terminated
|
||||
* @return the found token, or NULL when no token is found
|
||||
*/
|
||||
char *av_strtok(char *s, const char *delim, char **saveptr);
|
||||
|
||||
/**
|
||||
* Locale-independent conversion of ASCII isdigit.
|
||||
*/
|
||||
int av_isdigit(int c);
|
||||
|
||||
/**
|
||||
* Locale-independent conversion of ASCII isgraph.
|
||||
*/
|
||||
int av_isgraph(int c);
|
||||
|
||||
/**
|
||||
* Locale-independent conversion of ASCII isspace.
|
||||
*/
|
||||
int av_isspace(int c);
|
||||
|
||||
/**
|
||||
* Locale-independent conversion of ASCII characters to uppercase.
|
||||
*/
|
||||
static inline int av_toupper(int c)
|
||||
{
|
||||
if (c >= 'a' && c <= 'z')
|
||||
c ^= 0x20;
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locale-independent conversion of ASCII characters to lowercase.
|
||||
*/
|
||||
static inline int av_tolower(int c)
|
||||
{
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
c ^= 0x20;
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locale-independent conversion of ASCII isxdigit.
|
||||
*/
|
||||
int av_isxdigit(int c);
|
||||
|
||||
/**
|
||||
* Locale-independent case-insensitive compare.
|
||||
* @note This means only ASCII-range characters are case-insensitive
|
||||
*/
|
||||
int av_strcasecmp(const char *a, const char *b);
|
||||
|
||||
/**
|
||||
* Locale-independent case-insensitive compare.
|
||||
* @note This means only ASCII-range characters are case-insensitive
|
||||
*/
|
||||
int av_strncasecmp(const char *a, const char *b, size_t n);
|
||||
|
||||
|
||||
/**
|
||||
* Thread safe basename.
|
||||
* @param path the path, on DOS both \ and / are considered separators.
|
||||
* @return pointer to the basename substring.
|
||||
*/
|
||||
const char *av_basename(const char *path);
|
||||
|
||||
/**
|
||||
* Thread safe dirname.
|
||||
* @param path the path, on DOS both \ and / are considered separators.
|
||||
* @return the path with the separator replaced by the string terminator or ".".
|
||||
* @note the function may change the input string.
|
||||
*/
|
||||
const char *av_dirname(char *path);
|
||||
|
||||
enum AVEscapeMode {
|
||||
AV_ESCAPE_MODE_AUTO, ///< Use auto-selected escaping mode.
|
||||
AV_ESCAPE_MODE_BACKSLASH, ///< Use backslash escaping.
|
||||
AV_ESCAPE_MODE_QUOTE, ///< Use single-quote escaping.
|
||||
};
|
||||
|
||||
/**
|
||||
* Consider spaces special and escape them even in the middle of the
|
||||
* string.
|
||||
*
|
||||
* This is equivalent to adding the whitespace characters to the special
|
||||
* characters lists, except it is guaranteed to use the exact same list
|
||||
* of whitespace characters as the rest of libavutil.
|
||||
*/
|
||||
#define AV_ESCAPE_FLAG_WHITESPACE 0x01
|
||||
|
||||
/**
|
||||
* Escape only specified special characters.
|
||||
* Without this flag, escape also any characters that may be considered
|
||||
* special by av_get_token(), such as the single quote.
|
||||
*/
|
||||
#define AV_ESCAPE_FLAG_STRICT 0x02
|
||||
|
||||
/**
|
||||
* Escape string in src, and put the escaped string in an allocated
|
||||
* string in *dst, which must be freed with av_free().
|
||||
*
|
||||
* @param dst pointer where an allocated string is put
|
||||
* @param src string to escape, must be non-NULL
|
||||
* @param special_chars string containing the special characters which
|
||||
* need to be escaped, can be NULL
|
||||
* @param mode escape mode to employ, see AV_ESCAPE_MODE_* macros.
|
||||
* Any unknown value for mode will be considered equivalent to
|
||||
* AV_ESCAPE_MODE_BACKSLASH, but this behaviour can change without
|
||||
* notice.
|
||||
* @param flags flags which control how to escape, see AV_ESCAPE_FLAG_ macros
|
||||
* @return the length of the allocated string, or a negative error code in case of error
|
||||
* @see av_bprint_escape()
|
||||
*/
|
||||
int av_escape(char **dst, const char *src, const char *special_chars,
|
||||
enum AVEscapeMode mode, int flags);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* AVUTIL_AVSTRING_H */
|
||||
-314
@@ -1,314 +0,0 @@
|
||||
/*
|
||||
* copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVUTIL_AVUTIL_H
|
||||
#define AVUTIL_AVUTIL_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* external API header
|
||||
*/
|
||||
|
||||
/**
|
||||
* @mainpage
|
||||
*
|
||||
* @section ffmpeg_intro Introduction
|
||||
*
|
||||
* This document describes the usage of the different libraries
|
||||
* provided by FFmpeg.
|
||||
*
|
||||
* @li @ref libavc "libavcodec" encoding/decoding library
|
||||
* @li @ref lavfi "libavfilter" graph-based frame editing library
|
||||
* @li @ref libavf "libavformat" I/O and muxing/demuxing library
|
||||
* @li @ref lavd "libavdevice" special devices muxing/demuxing library
|
||||
* @li @ref lavu "libavutil" common utility library
|
||||
* @li @ref lswr "libswresample" audio resampling, format conversion and mixing
|
||||
* @li @ref lpp "libpostproc" post processing library
|
||||
* @li @ref lsws "libswscale" color conversion and scaling library
|
||||
*
|
||||
* @section ffmpeg_versioning Versioning and compatibility
|
||||
*
|
||||
* Each of the FFmpeg libraries contains a version.h header, which defines a
|
||||
* major, minor and micro version number with the
|
||||
* <em>LIBRARYNAME_VERSION_{MAJOR,MINOR,MICRO}</em> macros. The major version
|
||||
* number is incremented with backward incompatible changes - e.g. removing
|
||||
* parts of the public API, reordering public struct members, etc. The minor
|
||||
* version number is incremented for backward compatible API changes or major
|
||||
* new features - e.g. adding a new public function or a new decoder. The micro
|
||||
* version number is incremented for smaller changes that a calling program
|
||||
* might still want to check for - e.g. changing behavior in a previously
|
||||
* unspecified situation.
|
||||
*
|
||||
* FFmpeg guarantees backward API and ABI compatibility for each library as long
|
||||
* as its major version number is unchanged. This means that no public symbols
|
||||
* will be removed or renamed. Types and names of the public struct members and
|
||||
* values of public macros and enums will remain the same (unless they were
|
||||
* explicitly declared as not part of the public API). Documented behavior will
|
||||
* not change.
|
||||
*
|
||||
* In other words, any correct program that works with a given FFmpeg snapshot
|
||||
* should work just as well without any changes with any later snapshot with the
|
||||
* same major versions. This applies to both rebuilding the program against new
|
||||
* FFmpeg versions or to replacing the dynamic FFmpeg libraries that a program
|
||||
* links against.
|
||||
*
|
||||
* However, new public symbols may be added and new members may be appended to
|
||||
* public structs whose size is not part of public ABI (most public structs in
|
||||
* FFmpeg). New macros and enum values may be added. Behavior in undocumented
|
||||
* situations may change slightly (and be documented). All those are accompanied
|
||||
* by an entry in doc/APIchanges and incrementing either the minor or micro
|
||||
* version number.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup lavu Common utility functions
|
||||
*
|
||||
* @brief
|
||||
* libavutil contains the code shared across all the other FFmpeg
|
||||
* libraries
|
||||
*
|
||||
* @note In order to use the functions provided by avutil you must include
|
||||
* the specific header.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @defgroup lavu_crypto Crypto and Hashing
|
||||
*
|
||||
* @{
|
||||
* @}
|
||||
*
|
||||
* @defgroup lavu_math Maths
|
||||
* @{
|
||||
*
|
||||
* @}
|
||||
*
|
||||
* @defgroup lavu_string String Manipulation
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @}
|
||||
*
|
||||
* @defgroup lavu_mem Memory Management
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @}
|
||||
*
|
||||
* @defgroup lavu_data Data Structures
|
||||
* @{
|
||||
*
|
||||
* @}
|
||||
*
|
||||
* @defgroup lavu_audio Audio related
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @}
|
||||
*
|
||||
* @defgroup lavu_error Error Codes
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @}
|
||||
*
|
||||
* @defgroup lavu_misc Other
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @defgroup lavu_internal Internal
|
||||
*
|
||||
* Not exported functions, for internal usage only
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup lavu_ver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return the LIBAVUTIL_VERSION_INT constant.
|
||||
*/
|
||||
unsigned avutil_version(void);
|
||||
|
||||
/**
|
||||
* Return the libavutil build-time configuration.
|
||||
*/
|
||||
const char *avutil_configuration(void);
|
||||
|
||||
/**
|
||||
* Return the libavutil license.
|
||||
*/
|
||||
const char *avutil_license(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup lavu_media Media Type
|
||||
* @brief Media Type
|
||||
*/
|
||||
|
||||
enum AVMediaType {
|
||||
AVMEDIA_TYPE_UNKNOWN = -1, ///< Usually treated as AVMEDIA_TYPE_DATA
|
||||
AVMEDIA_TYPE_VIDEO,
|
||||
AVMEDIA_TYPE_AUDIO,
|
||||
AVMEDIA_TYPE_DATA, ///< Opaque data information usually continuous
|
||||
AVMEDIA_TYPE_SUBTITLE,
|
||||
AVMEDIA_TYPE_ATTACHMENT, ///< Opaque data information usually sparse
|
||||
AVMEDIA_TYPE_NB
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a string describing the media_type enum, NULL if media_type
|
||||
* is unknown.
|
||||
*/
|
||||
const char *av_get_media_type_string(enum AVMediaType media_type);
|
||||
|
||||
/**
|
||||
* @defgroup lavu_const Constants
|
||||
* @{
|
||||
*
|
||||
* @defgroup lavu_enc Encoding specific
|
||||
*
|
||||
* @note those definition should move to avcodec
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define FF_LAMBDA_SHIFT 7
|
||||
#define FF_LAMBDA_SCALE (1<<FF_LAMBDA_SHIFT)
|
||||
#define FF_QP2LAMBDA 118 ///< factor to convert from H.263 QP to lambda
|
||||
#define FF_LAMBDA_MAX (256*128-1)
|
||||
|
||||
#define FF_QUALITY_SCALE FF_LAMBDA_SCALE //FIXME maybe remove
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @defgroup lavu_time Timestamp specific
|
||||
*
|
||||
* FFmpeg internal timebase and timestamp definitions
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Undefined timestamp value
|
||||
*
|
||||
* Usually reported by demuxer that work on containers that do not provide
|
||||
* either pts or dts.
|
||||
*/
|
||||
|
||||
#define AV_NOPTS_VALUE ((int64_t)UINT64_C(0x8000000000000000))
|
||||
|
||||
/**
|
||||
* Internal time base represented as integer
|
||||
*/
|
||||
|
||||
#define AV_TIME_BASE 1000000
|
||||
|
||||
/**
|
||||
* Internal time base represented as fractional value
|
||||
*/
|
||||
|
||||
#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE}
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
* @defgroup lavu_picture Image related
|
||||
*
|
||||
* AVPicture types, pixel formats and basic image planes manipulation.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
enum AVPictureType {
|
||||
AV_PICTURE_TYPE_NONE = 0, ///< Undefined
|
||||
AV_PICTURE_TYPE_I, ///< Intra
|
||||
AV_PICTURE_TYPE_P, ///< Predicted
|
||||
AV_PICTURE_TYPE_B, ///< Bi-dir predicted
|
||||
AV_PICTURE_TYPE_S, ///< S(GMC)-VOP MPEG4
|
||||
AV_PICTURE_TYPE_SI, ///< Switching Intra
|
||||
AV_PICTURE_TYPE_SP, ///< Switching Predicted
|
||||
AV_PICTURE_TYPE_BI, ///< BI type
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a single letter to describe the given picture type
|
||||
* pict_type.
|
||||
*
|
||||
* @param[in] pict_type the picture type @return a single character
|
||||
* representing the picture type, '?' if pict_type is unknown
|
||||
*/
|
||||
char av_get_picture_type_char(enum AVPictureType pict_type);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "error.h"
|
||||
#include "version.h"
|
||||
#include "mathematics.h"
|
||||
#include "rational.h"
|
||||
#include "intfloat_readwrite.h"
|
||||
#include "log.h"
|
||||
#include "pixfmt.h"
|
||||
|
||||
/**
|
||||
* Return x default pointer in case p is NULL.
|
||||
*/
|
||||
static inline void *av_x_if_null(const void *p, const void *x)
|
||||
{
|
||||
return (void *)(intptr_t)(p ? p : x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the length of an integer list.
|
||||
*
|
||||
* @param elsize size in bytes of each list element (only 1, 2, 4 or 8)
|
||||
* @param term list terminator (usually 0 or -1)
|
||||
* @param list pointer to the list
|
||||
* @return length of the list, in elements, not counting the terminator
|
||||
*/
|
||||
unsigned av_int_list_length_for_size(unsigned elsize,
|
||||
const void *list, uint64_t term) av_pure;
|
||||
|
||||
/**
|
||||
* Compute the length of an integer list.
|
||||
*
|
||||
* @param term list terminator (usually 0 or -1)
|
||||
* @param list pointer to the list
|
||||
* @return length of the list, in elements, not counting the terminator
|
||||
*/
|
||||
#define av_int_list_length(list, term) \
|
||||
av_int_list_length_for_size(sizeof(*(list)), list, term)
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* AVUTIL_AVUTIL_H */
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com)
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVUTIL_BASE64_H
|
||||
#define AVUTIL_BASE64_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @defgroup lavu_base64 Base64
|
||||
* @ingroup lavu_crypto
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Decode a base64-encoded string.
|
||||
*
|
||||
* @param out buffer for decoded data
|
||||
* @param in null-terminated input string
|
||||
* @param out_size size in bytes of the out buffer, must be at
|
||||
* least 3/4 of the length of in
|
||||
* @return number of bytes written, or a negative value in case of
|
||||
* invalid input
|
||||
*/
|
||||
int av_base64_decode(uint8_t *out, const char *in, int out_size);
|
||||
|
||||
/**
|
||||
* Encode data to base64 and null-terminate.
|
||||
*
|
||||
* @param out buffer for encoded data
|
||||
* @param out_size size in bytes of the out buffer (including the
|
||||
* null terminator), must be at least AV_BASE64_SIZE(in_size)
|
||||
* @param in input buffer containing the data to encode
|
||||
* @param in_size size in bytes of the in buffer
|
||||
* @return out or NULL in case of error
|
||||
*/
|
||||
char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size);
|
||||
|
||||
/**
|
||||
* Calculate the output size needed to base64-encode x bytes to a
|
||||
* null-terminated string.
|
||||
*/
|
||||
#define AV_BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* AVUTIL_BASE64_H */
|
||||
-77
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Blowfish algorithm
|
||||
* Copyright (c) 2012 Samuel Pitoiset
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVUTIL_BLOWFISH_H
|
||||
#define AVUTIL_BLOWFISH_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @defgroup lavu_blowfish Blowfish
|
||||
* @ingroup lavu_crypto
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define AV_BF_ROUNDS 16
|
||||
|
||||
typedef struct AVBlowfish {
|
||||
uint32_t p[AV_BF_ROUNDS + 2];
|
||||
uint32_t s[4][256];
|
||||
} AVBlowfish;
|
||||
|
||||
/**
|
||||
* Initialize an AVBlowfish context.
|
||||
*
|
||||
* @param ctx an AVBlowfish context
|
||||
* @param key a key
|
||||
* @param key_len length of the key
|
||||
*/
|
||||
void av_blowfish_init(struct AVBlowfish *ctx, const uint8_t *key, int key_len);
|
||||
|
||||
/**
|
||||
* Encrypt or decrypt a buffer using a previously initialized context.
|
||||
*
|
||||
* @param ctx an AVBlowfish context
|
||||
* @param xl left four bytes halves of input to be encrypted
|
||||
* @param xr right four bytes halves of input to be encrypted
|
||||
* @param decrypt 0 for encryption, 1 for decryption
|
||||
*/
|
||||
void av_blowfish_crypt_ecb(struct AVBlowfish *ctx, uint32_t *xl, uint32_t *xr,
|
||||
int decrypt);
|
||||
|
||||
/**
|
||||
* Encrypt or decrypt a buffer using a previously initialized context.
|
||||
*
|
||||
* @param ctx an AVBlowfish context
|
||||
* @param dst destination array, can be equal to src
|
||||
* @param src source array, can be equal to dst
|
||||
* @param count number of 8 byte blocks
|
||||
* @param iv initialization vector for CBC mode, if NULL ECB will be used
|
||||
* @param decrypt 0 for encryption, 1 for decryption
|
||||
*/
|
||||
void av_blowfish_crypt(struct AVBlowfish *ctx, uint8_t *dst, const uint8_t *src,
|
||||
int count, uint8_t *iv, int decrypt);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* AVUTIL_BLOWFISH_H */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user