mirror of
https://github.com/opencv/opencv.git
synced 2026-07-23 04:13:04 +04:00
Compare commits
1112 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| dad8af6b17 | |||
| afe7c8b560 | |||
| e5b5984f3c | |||
| 881cd02fe2 | |||
| 49a0877b8c | |||
| 1453e79ecc | |||
| 212795db64 | |||
| e80b7940ef | |||
| c3f75c2952 | |||
| 56aae015cd | |||
| 221b5c086c | |||
| e019a6738d | |||
| 5510e2556a | |||
| 7d681cf80d | |||
| 03d1760dd5 | |||
| 8c22b4b54b | |||
| 46792849d4 | |||
| 43007af42e | |||
| b59eca22ae | |||
| 62f1a7410d | |||
| b407c58b96 | |||
| f978c99523 | |||
| bb5b5bb24d | |||
| 639fd80aa3 | |||
| c38eff62b4 | |||
| dba7186378 | |||
| d9d402916a | |||
| f49b26182b | |||
| 96b894e0e1 | |||
| f8502d45f9 | |||
| 049cd86ddd | |||
| 4884083019 | |||
| 00d7a19ec9 | |||
| 4546f40d8b | |||
| 315d0f581e | |||
| 953dddd26b | |||
| f399bdfa1a | |||
| 2320eef72d | |||
| 938bc4d503 | |||
| 4ee4479cd7 | |||
| a050285058 | |||
| 027aee8ad4 | |||
| 4453c157fc | |||
| 53cd921ab4 | |||
| 6d2064b32f | |||
| 853e5dfcdf | |||
| 35e2ef8019 | |||
| 3a600db4ab | |||
| f5d8245801 | |||
| 011fd39091 | |||
| 3340c71a2a | |||
| c9bb92d58b | |||
| 99c94d3d83 | |||
| 8fc31ee9df | |||
| 40137b2e9e | |||
| c930f54063 | |||
| f0d3bbddff | |||
| adde942e34 | |||
| b1f67c83af | |||
| 0521a3a384 | |||
| e64c5dc4c6 | |||
| bee183f9bb | |||
| 9434c89ba0 | |||
| 3d9cb5329c | |||
| abbd878eb5 | |||
| 181850e808 | |||
| a61306f79a | |||
| 70b87804cf | |||
| c92815238e | |||
| d20727a5be | |||
| 3e6dcdc0a4 | |||
| fa5ed62a66 | |||
| 465e601e10 | |||
| dfc61fbfaa | |||
| 509c1afb8d | |||
| f1d33410fd | |||
| 283407e1ff | |||
| baf07f9a03 | |||
| b6ec9b9d8c | |||
| 7892517b3d | |||
| 398611b7e8 | |||
| 70618cb7bf | |||
| bc12e4fe55 | |||
| eb736c272e | |||
| ea3164ac77 | |||
| ccc97b5c46 | |||
| 1cca4bef64 | |||
| 915e39cdf0 | |||
| 1017ea4f83 | |||
| 0735d7b328 | |||
| 6ae1709c6a | |||
| fb9f75c5ba | |||
| 3d1f6465da | |||
| 9a47e1764a | |||
| 14688e95ea | |||
| fdfe64e5f2 | |||
| 500fd453a1 | |||
| 2e37a697b9 | |||
| 42ab298f01 | |||
| 992c527c91 | |||
| 46743c1701 | |||
| 850be1e087 | |||
| 5498f419df | |||
| bf72e9d625 | |||
| 556f539531 | |||
| 9bbc890d96 | |||
| 3c1423c970 | |||
| 9814a514fa | |||
| 6ee71fee88 | |||
| b6b40a85e4 | |||
| b1b59c87b9 | |||
| d3dd2e463c | |||
| 06ff35c9af | |||
| 308f00f158 | |||
| 72a987ef5a | |||
| e5468a88e6 | |||
| 098efb6d3d | |||
| 8b577ab983 | |||
| b13514e33c | |||
| ac4b26a561 | |||
| 850ebec135 | |||
| 55923c8dc7 | |||
| 681ee0ef11 | |||
| d9933c5403 | |||
| b7348e1b65 | |||
| 0bf519dd05 | |||
| 1cfd5acb41 | |||
| 13c2320e38 | |||
| 2146bbb7bd | |||
| 2f0de10120 | |||
| ad079ea5da | |||
| dc0c59fdc6 | |||
| a2edf4d929 | |||
| f5ec92e4ca | |||
| 938951f4f0 | |||
| 22edfd2628 | |||
| 60d7dbb647 | |||
| 55d248941b | |||
| 463affcebf | |||
| b259342737 | |||
| b1441c9d6a | |||
| e70c8e5f0e | |||
| 7f0a094e4e | |||
| 903b66906e | |||
| d36b959dd1 | |||
| 1bf4f2386a | |||
| 7f3b6c177f | |||
| 70e55fd7c6 | |||
| 81656597e9 | |||
| 48e6be822c | |||
| c7ed293484 | |||
| 408730b7ab | |||
| 21d5a41e92 | |||
| 4cfbc5af08 | |||
| 3893936243 | |||
| ac649b2ffd | |||
| 1db23e0f12 | |||
| 9d454fed93 | |||
| e20250139a | |||
| 10c43e5642 | |||
| d97ed516a8 | |||
| 2b85894826 | |||
| 0812659e92 | |||
| 5df28f1eaa | |||
| 79797a3eb6 | |||
| 0a862b5295 | |||
| 7833c63388 | |||
| 34c406ea3a | |||
| 7b1a5fb3de | |||
| 75f619fe00 | |||
| 1ef8175c49 | |||
| 1c4f441507 | |||
| 06f62a3dd1 | |||
| 49463c4420 | |||
| f7d69085af | |||
| 5278560252 | |||
| 9bb0a8d9e9 | |||
| aa6b399b5a | |||
| 07da2c9d10 | |||
| 9517fcf80d | |||
| 88d3e7a7ba | |||
| e9f35610a5 | |||
| d296d29a1c | |||
| 332748dd55 | |||
| 848dd12a1f | |||
| 2830551e89 | |||
| ce0516282a | |||
| 2c1ec4245d | |||
| d05fb709f9 | |||
| fba3c947ef | |||
| 8bbf08f0de | |||
| a57ea2b775 | |||
| c19adb4953 | |||
| 16928806f9 | |||
| 23481b716b | |||
| b913e73d04 | |||
| a478757483 | |||
| 6c57ce9e09 | |||
| fad0dbb9ac | |||
| 8c10545d3c | |||
| 83d70b0f36 | |||
| 0e151e3c88 | |||
| 024dfd54af | |||
| ec97c38ff9 | |||
| 4a69877eaa | |||
| 5156222a92 | |||
| 4c7d77372e | |||
| 3f013e4cf5 | |||
| adc55608f1 | |||
| 7cd4fc2fb8 | |||
| 9c86d68b4c | |||
| 031846f2e1 | |||
| 9b97c97bd1 | |||
| 960a926055 | |||
| 53f2131681 | |||
| ceebfa1bee | |||
| 93ba5c9175 | |||
| 064fdba120 | |||
| 84590f96e5 | |||
| b3791dc4be | |||
| bc54f76875 | |||
| b7ec2ebb55 | |||
| 41c335e5a5 | |||
| b203c7c3e2 | |||
| 8df76fe0cb | |||
| 5b0ad6b5e8 | |||
| b1e0c4d119 | |||
| f85cf5d7f9 | |||
| 9d0c8a9edb | |||
| 81907af74c | |||
| fb352e3098 | |||
| 26f3514992 | |||
| 6079e22523 | |||
| 30549d65c2 | |||
| ee0822dc4d | |||
| 832f738db0 | |||
| ed52f7feea | |||
| e95c0055af | |||
| 6a65678592 | |||
| fa56623458 | |||
| fe4d518d85 | |||
| ea47cb3ffe | |||
| 451ee3991e | |||
| 7c9231ffba | |||
| 2e49bf311a | |||
| f530a24544 | |||
| abc4eeb9a7 | |||
| c91af16fa7 | |||
| e202116b56 | |||
| bd565df379 | |||
| a3ebc0ae7f | |||
| e9e6b1e22c | |||
| 617d7ff575 | |||
| 77a0ffc71d | |||
| 52c33f4af3 | |||
| 1911c63826 | |||
| cac1695099 | |||
| 38bc519e4a | |||
| a3b3a589f9 | |||
| 1fe0fc224c | |||
| 44c254c09d | |||
| 8b47361873 | |||
| 3429c27477 | |||
| 099e002667 | |||
| 3c9c964630 | |||
| c2f909fc86 | |||
| d142a796d8 | |||
| 996b6c37c7 | |||
| 1c0ca41b6e | |||
| b44cb33d2f | |||
| 1aa4621777 | |||
| fcdaaabf7c | |||
| c96f48e7c9 | |||
| a9664abb57 | |||
| 5bffcdf7e8 | |||
| f2ef81a179 | |||
| 6e4280ea81 | |||
| ba4d6c859d | |||
| 2f1d529a71 | |||
| 240b245105 | |||
| c6fa9931ed | |||
| 014e8485b5 | |||
| 7757759205 | |||
| 14b21f7271 | |||
| 2f63c58380 | |||
| 3ebcd94535 | |||
| ce2b9f83f7 | |||
| 331763a48b | |||
| a287605c3e | |||
| 0507043a55 | |||
| 58285e5468 | |||
| cd7cbe3d41 | |||
| b3d3acf75f | |||
| 5ddf3de4ce | |||
| 3859ac921a | |||
| 7e17f01b7b | |||
| a1028efdcf | |||
| 590f150d5e | |||
| 631f229827 | |||
| 8edf37903d | |||
| fd4af21350 | |||
| 5fb3869775 | |||
| 24fd39538e | |||
| 07bf9cb013 | |||
| 3dcaf1f287 | |||
| 2c92eb3175 | |||
| 33d64d0491 | |||
| 7b6d65cf20 | |||
| 62b5470b78 | |||
| 670c52f75e | |||
| 6bcf3d4311 | |||
| 3d0e2cc46c | |||
| d752bac43f | |||
| 1bccc14e05 | |||
| 9f74982a54 | |||
| 00ca8f455e | |||
| 4708d1aed7 | |||
| 9bd14d5417 | |||
| c497fe05a0 | |||
| 4e60392040 | |||
| e5b114e5b8 | |||
| 63819c1e1f | |||
| 2af5815d47 | |||
| f3c724d449 | |||
| 5caee5cc64 | |||
| fb0479da23 | |||
| 8a8c0d285e | |||
| c7ec0d599a | |||
| b8d4ac589d | |||
| 0433fe539c | |||
| 7fa0493ca0 | |||
| 7b399c4248 | |||
| 1baaac295a | |||
| 307324f4ac | |||
| 43036e0031 | |||
| 2b6d0f36f0 | |||
| bb171a0c05 | |||
| 9942757bab | |||
| f2962e5875 | |||
| aa143a3dd1 | |||
| 72e7672a6c | |||
| 3889dcf3f8 | |||
| 865e7cacca | |||
| 419060da84 | |||
| b51a78d439 | |||
| 6295f7d05b | |||
| 219a34261f | |||
| 224dac9427 | |||
| d78637102c | |||
| 60ae973142 | |||
| 799bb0cd18 | |||
| 8a96e34e33 | |||
| 70d7e83dca | |||
| 320c0bf419 | |||
| b870ad46bf | |||
| f617fbe166 | |||
| 8f2e6640e3 | |||
| e16ca08b33 | |||
| 9b5a719d80 | |||
| 157b0e7760 | |||
| 0a53afe8ba | |||
| 6bc369fc56 | |||
| 687fc11626 | |||
| 638c575c73 | |||
| d4cb564ce2 | |||
| 5e9191558d | |||
| 515f119a59 | |||
| 3880d059b3 | |||
| ec1c0608bc | |||
| fa81936a5b | |||
| c5edd20354 | |||
| 1e54e56579 | |||
| 347a1e2913 | |||
| 4790a3732e | |||
| eb20bb3b23 | |||
| 97614920ef | |||
| ae1d1b6d55 | |||
| 6694d87a23 | |||
| ee867ead1d | |||
| 62c0556c58 | |||
| 02525abd9f | |||
| c552e9eede | |||
| 5dc5b27858 | |||
| c319735d9b | |||
| 1a8d37d19e | |||
| 91cf0d1843 | |||
| 910db5c9b7 | |||
| e60825e75b | |||
| 5a042af7e3 | |||
| 0367a12b92 | |||
| 757d296382 | |||
| ceeb01dce5 | |||
| e5ff41ec9b | |||
| e8f94182f5 | |||
| 5c9f58e124 | |||
| d0de575aef | |||
| 1ebea1e0f0 | |||
| 5350fba319 | |||
| 8a415c881a | |||
| 674c618471 | |||
| f64738218a | |||
| 494d201fda | |||
| 91808e64a1 | |||
| 178fdbbda8 | |||
| 2c53e3f53d | |||
| af9be78ead | |||
| c9d70d46b1 | |||
| c4c2e2e796 | |||
| cca4ee2e46 | |||
| 21fb10c6a3 | |||
| 639836ebf0 | |||
| 6ae7caaa01 | |||
| f280e3cbd9 | |||
| 9eba360eab | |||
| 84f32bbb24 | |||
| c91c631ae2 | |||
| ca527040e2 | |||
| 114c23e411 | |||
| 748279d5f1 | |||
| e274e72869 | |||
| 4dd755443a | |||
| d19fc1264b | |||
| d3bccd7b23 | |||
| 72bb8bb73c | |||
| c53b3c5f84 | |||
| a308dfca98 | |||
| c20febdbb0 | |||
| 8a1b998b2b | |||
| 4b1a4bdb49 | |||
| 588ddf1b18 | |||
| 81cc89a3ce | |||
| bb43927077 | |||
| a0debc3a9a | |||
| ca0bd70cde | |||
| 613ff7c85d | |||
| d88ad46978 | |||
| bb7c35b99f | |||
| 2b87e78e18 | |||
| 6b3b8c59c3 | |||
| 70a58d7198 | |||
| 4761c28143 | |||
| f5a14532c2 | |||
| d792ebc5d2 | |||
| abda763073 | |||
| 8ad5eb521a | |||
| 8d1c73a912 | |||
| 16681d1080 | |||
| 8e52c0155b | |||
| ace781740c | |||
| ad7ecf1dba | |||
| fb34f36c69 | |||
| a301d1c298 | |||
| 27d718b223 | |||
| a300e7e945 | |||
| 358e3065ab | |||
| 747b7cab6c | |||
| 232c67bf76 | |||
| 5b41134ee7 | |||
| 0dd7769bb1 | |||
| 82de5b3a67 | |||
| 3421b950ce | |||
| 53dfd9536a | |||
| f834736307 | |||
| 4a12707103 | |||
| eccfd98b92 | |||
| 9b5b2540a4 | |||
| ba70ec99b3 | |||
| 7d59db4ec4 | |||
| afb406f1de | |||
| 87b7ce4415 | |||
| 2ff16d4c45 | |||
| 5466fd2606 | |||
| 4b8aeb1129 | |||
| 96f23e3da1 | |||
| e4ad7e3778 | |||
| 0245c0cd10 | |||
| 195aad8e6a | |||
| f46f7eff0c | |||
| e1d0f07c90 | |||
| 0883c6a913 | |||
| bea0c1b660 | |||
| 9fc83ac544 | |||
| e0e537d94e | |||
| ab8cb6f8a9 | |||
| 68968eda8d | |||
| 6791284994 | |||
| 08d457edcf | |||
| 0323761ea6 | |||
| 15815fb54d | |||
| 677a28fd2a | |||
| ab6bffc6f8 | |||
| 5fc2564c92 | |||
| 0c5d74ec1a | |||
| 5c090b9eec | |||
| e59b8cd905 | |||
| 95b2820214 | |||
| 91749a284b | |||
| 94de7e5d21 | |||
| dad72fd47b | |||
| a817813b50 | |||
| a25e809da1 | |||
| 46841df978 | |||
| be29c99d5a | |||
| b22c2505a8 | |||
| e5e1a3bfde | |||
| a5ba18c20e | |||
| c9a4775d49 | |||
| 12acf5603a | |||
| 0bcd66d553 | |||
| d69c1d8652 | |||
| d4af868528 | |||
| 2fc7d21971 | |||
| ec7689421d | |||
| d96ff496b4 | |||
| e3cb5f80e7 | |||
| 09d2f4ea46 | |||
| 5261961a6e | |||
| 3cce299a78 | |||
| e41ba90f17 | |||
| 423ab8ddb8 | |||
| 20784d3da2 | |||
| 1794cdc03c | |||
| c792233d9c | |||
| 4c568e6ed3 | |||
| 9519e67ad2 | |||
| b0cbd6ef77 | |||
| 23f27d8dbe | |||
| 0519e05432 | |||
| 81f07f001e | |||
| 55906457e6 | |||
| 1f82550cc8 | |||
| e00c904585 | |||
| 1920993525 | |||
| 1f7025f028 | |||
| 4ee0f212cc | |||
| 7819ec784b | |||
| 52d9685cb9 | |||
| 3aeaa34023 | |||
| c12e1ecb86 | |||
| 0fef0f2ae0 | |||
| bd2695f01b | |||
| d60107ab7a | |||
| fdfb875208 | |||
| 85f0074f23 | |||
| 0f17851562 | |||
| 53af876999 | |||
| 9c4c3eadf7 | |||
| 0f665b3f15 | |||
| 3f0707234f | |||
| cd9f85dbda | |||
| 99058ee30b | |||
| 7b4b7ceb7e | |||
| 48c52c8bbb | |||
| 40727c8369 | |||
| e3c1405254 | |||
| 37aa823112 | |||
| ef9d14f181 | |||
| 87f8cdd699 | |||
| a00818047f | |||
| 6af4a02941 | |||
| 6ff5245cf2 | |||
| 2af6775c14 | |||
| f89b705049 | |||
| bb61cc0dba | |||
| 953de60ff0 | |||
| 986e379f28 | |||
| de8e6abd1e | |||
| a6df336477 | |||
| 8097bdc2f4 | |||
| fdc0c12b7f | |||
| 05becd56e5 | |||
| d2951d6d4c | |||
| 09944a83d9 | |||
| e43bc88fc3 | |||
| cb2e831da4 | |||
| 601a159f25 | |||
| 8931f08362 | |||
| 2d92f42878 | |||
| 10294a84fa | |||
| b8e3bc9dd8 | |||
| 32251c9b04 | |||
| 9f87475129 | |||
| 71796edf95 | |||
| 8839bd572e | |||
| c9d8b541fc | |||
| 356e5d3028 | |||
| a58214f015 | |||
| 67faf1610e | |||
| 377be68d92 | |||
| aea44efaa6 | |||
| 0661aff4a5 | |||
| e9414169a3 | |||
| 64be9c8bf6 | |||
| 50fc68b981 | |||
| 1d9c0d3e12 | |||
| d25d44156b | |||
| bca5868817 | |||
| 7f6c95f2d7 | |||
| 131dab774c | |||
| f9a59f2592 | |||
| b8b8c7c9e5 | |||
| d17507052e | |||
| 49ee4d4ade | |||
| 1eb1d4c370 | |||
| c982be3924 | |||
| 85ea247cc6 | |||
| bf06bc92aa | |||
| aff420329c | |||
| 21d79abb1f | |||
| d9a5603fa3 | |||
| ee97dd5211 | |||
| 29388f80a5 | |||
| e7501b69ea | |||
| c0fda696f3 | |||
| d4f81c6d24 | |||
| 3b264d5877 | |||
| 0866a135c6 | |||
| 2849a774e3 | |||
| affc69bf1f | |||
| 22b747eae2 | |||
| 426b088754 | |||
| 60848519b5 | |||
| 61d48dd0f8 | |||
| eba8450995 | |||
| 1656e7573e | |||
| b7947d861c | |||
| 1db1422fbd | |||
| fc810434de | |||
| fe93724d3f | |||
| 65b957a5b3 | |||
| 9eaa7bd566 | |||
| 94211fb8b0 | |||
| f20edba925 | |||
| fe4f5b539e | |||
| 4e31bc5cf5 | |||
| 06b40aef91 | |||
| c97c22b7cf | |||
| 51702ffd92 | |||
| 805946baaf | |||
| 726ba0210e | |||
| 71790e12ad | |||
| 0cf45b89ec | |||
| 004801f1c5 | |||
| ddcbd2cc26 | |||
| d6d15c136a | |||
| f2f00259da | |||
| a4a739b99e | |||
| c0d4e16833 | |||
| 94703fc5b0 | |||
| 496474392e | |||
| 433c364456 | |||
| ec95efca10 | |||
| 003d048b0d | |||
| b6d1402361 | |||
| 67fd2d02ef | |||
| 1eaa074a49 | |||
| 024c836462 | |||
| 44881592c3 | |||
| 3c0b71bcec | |||
| a9d547dfee | |||
| 69ebecc54f | |||
| 8762c37c22 | |||
| a3b6a5b606 | |||
| e625b32841 | |||
| 924c01dbec | |||
| 0d7c039ea1 | |||
| 291689a178 | |||
| 1acbeb217b | |||
| 2b3424b536 | |||
| 538b13aeec | |||
| 0dde3b65d5 | |||
| 463cd09811 | |||
| 5859a531e5 | |||
| 8e8638431d | |||
| fc2d933224 | |||
| 52f46589a0 | |||
| 6909fffde1 | |||
| 19f4f2eb92 | |||
| b854d4ecd8 | |||
| b522148bd9 | |||
| 170cc0360b | |||
| a371bdac9d | |||
| 3af6001a75 | |||
| 134d0b74d3 | |||
| 3f4ec3596e | |||
| 843daca26e | |||
| f9d7f47e28 | |||
| e60a7c0d49 | |||
| e9c18c76c7 | |||
| 37459f89c9 | |||
| 4622f1e89b | |||
| dc37883702 | |||
| 6ca697bc12 | |||
| 57da72d444 | |||
| fe14e7ab24 | |||
| 61488885b5 | |||
| 472aad46a6 | |||
| 0c8e6e0e68 | |||
| 60b806f9b8 | |||
| e1ce2146f5 | |||
| eec8a20c33 | |||
| 5d913f4d72 | |||
| b729d8e821 | |||
| 6d2cbc4055 | |||
| 6d0add4285 | |||
| f597838685 | |||
| af95395fe7 | |||
| 5f8e43da85 | |||
| 6b53fe8f7b | |||
| d3e7968927 | |||
| b9ce87e8e2 | |||
| af03e000c7 | |||
| 635bbfe92b | |||
| adab462e42 | |||
| b5ac7ef2f2 | |||
| 983925c685 | |||
| 84457a5dcd | |||
| 385003e9fe | |||
| 9fa014edcd | |||
| 5330112f05 | |||
| 66f86e898c | |||
| 36d6ca529d | |||
| 2104d61d4a | |||
| fe7c5e3f64 | |||
| 0787c31f41 | |||
| 2f805ff7ad | |||
| 6d3dd24622 | |||
| fc5d412ba7 | |||
| 93d490213f | |||
| c55aee1e79 | |||
| 0442c6fa81 | |||
| 1457320702 | |||
| ecd2e8ff47 | |||
| 02397ef851 | |||
| f1076541d1 | |||
| b5e9eb742c | |||
| 6ad77b2319 | |||
| 67e0ed93a9 | |||
| 1bffe170e1 | |||
| 7b998c30e7 | |||
| 2083fdc9c0 | |||
| d1b158b9dd | |||
| 380caa1a87 | |||
| 900f17d563 | |||
| c97942cf78 | |||
| 6157db6462 | |||
| a9424868a1 | |||
| 749935866d | |||
| cbda161c39 | |||
| a63636171e | |||
| cf0ba039c3 | |||
| c75d0b8ca3 | |||
| a2b679bc26 | |||
| 45dcd156b7 | |||
| e6282b8ace | |||
| 87331ca1a0 | |||
| 65487946cc | |||
| 4823285b55 | |||
| 26a7b332cb | |||
| f07b01cc34 | |||
| bbda6f4c57 | |||
| 29b2f77b5f | |||
| 537060d96f | |||
| dbd1811d53 | |||
| 4384e77bd1 | |||
| dc714c1181 | |||
| d4861bfd1f | |||
| c07145fe28 | |||
| e09684647a | |||
| 98d678c2d2 | |||
| 4a559bc2ab | |||
| 044a322519 | |||
| e3c5c0906b | |||
| 2e9eb05751 | |||
| b122a4b436 | |||
| d00a96315e | |||
| 04970490ec | |||
| 9976074271 | |||
| 7539abecdb | |||
| d79a6eddf2 | |||
| 3f3c821800 | |||
| 97c021b17a | |||
| c946285a07 | |||
| c92135bdd1 | |||
| 9931da772d | |||
| f2311d1bfd | |||
| 5025f29378 | |||
| 435ccfdd51 | |||
| af14780526 | |||
| 2b9d2c726a | |||
| d847f4f0fd | |||
| 340e999c45 | |||
| d2143bcd44 | |||
| 53b678d5cf | |||
| d2618bfe11 | |||
| ae8c90301f | |||
| 4eec739624 | |||
| eefee8574a | |||
| be84824530 | |||
| 5229312ad2 | |||
| 99ef35a353 | |||
| 05084aa63e | |||
| 001a2c5195 | |||
| bcb49d71b4 | |||
| 59ca444b26 | |||
| 04d71da6e7 | |||
| fa5c5f4105 | |||
| 91b6c8507a | |||
| 4e27fc93f8 | |||
| 0800574c12 | |||
| 2c4079fa4b | |||
| fc43e51331 | |||
| a8d3d1f6f9 | |||
| 46991bcd62 | |||
| 85b04f0b4d | |||
| 233478e689 | |||
| 676afdc494 | |||
| 8baabdfb57 | |||
| e5e4424f11 | |||
| a44a6f6c87 | |||
| 85cc4086c8 | |||
| 97d7a4a86e | |||
| 4ed07411c3 | |||
| d6dc91b4d4 | |||
| f7bee7883b | |||
| f7e52076b6 | |||
| 88bb007d2b | |||
| ee9449c504 | |||
| 25c28c5da4 | |||
| 0513741a85 | |||
| 351589e5fb | |||
| dabf960b32 | |||
| a2be9e9fc1 | |||
| 6160104fd7 | |||
| e55784a1e8 | |||
| 868787c364 | |||
| 27e10efa66 | |||
| 3c76b33532 | |||
| 685a47b2e2 | |||
| 658f18c713 | |||
| 8be93a6de7 | |||
| 6dd8a9b6ad | |||
| 23b819efb8 | |||
| 9161e40aa0 | |||
| 5ccb4e0487 | |||
| 6dbc5e032f | |||
| af1c63c0a0 | |||
| 4ba06c3ed0 | |||
| 46e2b67ecb | |||
| 58e4a880a2 | |||
| df99e4e88d | |||
| a174a6c0b5 | |||
| d4f29a6361 | |||
| 3b1ee0549b | |||
| 871f931e95 | |||
| e3e1f704a4 | |||
| d19a05734e | |||
| 38e35d5137 | |||
| aa57833ad5 | |||
| e4e774d42b | |||
| 89c5a7584a | |||
| a4a9f56c8b | |||
| e4360294c5 | |||
| 1d02146810 | |||
| 9ab0ff6cf2 | |||
| 601778e0e6 | |||
| 810096c276 | |||
| e4a29d93fe | |||
| 54e1a8709d | |||
| 4c06a721ef | |||
| 3113b49159 | |||
| 3c1fcd5deb | |||
| b3a2444bcf | |||
| 277d64af88 | |||
| 7bd9dae53d | |||
| a33b2bed52 | |||
| b0eddeba2d | |||
| cfa5a270d3 | |||
| a7c6fedebd | |||
| b68aa12572 | |||
| 47bea69322 | |||
| aa2fabcba5 | |||
| 8512deb3cc | |||
| 7867da47cf | |||
| a788cc526b | |||
| aa17f881b1 | |||
| 4f99e5ab37 | |||
| 88cacd35c5 | |||
| 61d255887c | |||
| f1dbc7d724 | |||
| 24387c25db | |||
| 1a5820aa01 | |||
| 097891e311 | |||
| 1af084cb65 | |||
| 136121f6ee | |||
| ebde9a5e6d | |||
| 66abbf4122 | |||
| 0f984ea0f0 | |||
| 3f02c9d5b9 | |||
| 4f77434da1 | |||
| 51281f8d69 | |||
| d2dbaa4cd1 | |||
| 88a7e8cdf5 | |||
| f9ce3f4b91 | |||
| daf9de7463 | |||
| 8a95f4f0e6 | |||
| d30830d0a6 | |||
| f5a92cb43f | |||
| 3bcc3e70f1 | |||
| fd8b346c3e | |||
| 4c2584d729 | |||
| 72c715ff4f | |||
| ce01123db2 | |||
| 3a83a35ab0 | |||
| 8336a96cb9 | |||
| 9742c73254 | |||
| 793c966c40 | |||
| dafd9e3408 | |||
| b12c14514a | |||
| b4e3359448 | |||
| bac7180e02 | |||
| 2b32eee3f4 | |||
| 51f5ee6f19 | |||
| 66a5ecb7ec | |||
| 4e050e85ad | |||
| b34fc422a2 | |||
| 3871984028 | |||
| 3ac06bf063 | |||
| 20eee64426 | |||
| 85a04185d3 | |||
| 57460b1e30 | |||
| d8c80ff5a4 | |||
| 26ca124150 | |||
| 6d93a0e42c | |||
| 3f7d319fff | |||
| 3cf367c9c4 | |||
| c643af0b85 | |||
| 5e1d33329b | |||
| 9cfced4650 | |||
| a809ae4e88 | |||
| 1c6c3dfa8d | |||
| 83a49b4f6a | |||
| 352f92e437 | |||
| f5fd3e7d65 | |||
| ee302b063f | |||
| d7dd014a6e | |||
| b56a52c49b | |||
| 0bb84096a2 | |||
| 36a03dbdbf | |||
| 02bdc10062 | |||
| d3cc507380 | |||
| 1af790ecc3 | |||
| 8c64adb000 | |||
| 6ffe686ba8 | |||
| a94cd6d6e8 | |||
| ea7efd57d8 | |||
| c9e42c5050 | |||
| 6033599c88 | |||
| a924bbfc30 | |||
| 0d2f21b51e | |||
| 5c5ef9746c | |||
| 42793e16dd | |||
| a4ff46aab7 | |||
| e6bd4c9f85 | |||
| 0d082ce6fd | |||
| 5df6b4a756 | |||
| 8483f2ef2f | |||
| a60408cda5 | |||
| 68926d595c | |||
| da3a4dcbc1 | |||
| abfa5c586a | |||
| a1b4aa5e88 | |||
| c4226f0457 | |||
| aef1fc087d | |||
| 752ac19a2f | |||
| a2e04718ec | |||
| 94b3bad3c9 | |||
| 2e927c2dbd | |||
| 69fd82fc46 | |||
| 68e2df56e7 | |||
| 86fa0308fc | |||
| 0d455e05c1 | |||
| 924a65413a | |||
| 6bac5453d1 | |||
| ccbc784195 | |||
| 56a4877e30 | |||
| b204c39815 | |||
| bb917c8391 | |||
| 386be97ce2 | |||
| 7d032de7e8 | |||
| de2f7666fb | |||
| 95f087cd0b | |||
| 22a52766dc | |||
| b94e13c8ae | |||
| ee3740af00 | |||
| 9f2182abbb | |||
| 6c763e1ea5 | |||
| e03e2e7f94 | |||
| c6e5f60525 | |||
| 29cc675375 | |||
| 7ea6b356c7 | |||
| 8ad8ec679f | |||
| 0052d46b8e | |||
| a035608100 | |||
| fe59a5695f | |||
| a5f04f9e17 | |||
| b3c9842a98 | |||
| 9eb5e39ff3 | |||
| 5a227352b4 | |||
| bdff0949bb | |||
| 4262127854 | |||
| ca48e217f1 | |||
| f48939c2d7 | |||
| 39e2ebbde4 | |||
| 903ec0ec60 | |||
| 20dac7ea48 | |||
| 642942a72f | |||
| 923dbcc58f | |||
| 2ab7b7c09e | |||
| 6b5be4f1a7 | |||
| 6c235c8edb | |||
| a87b9fb4b6 | |||
| 58d8a2702a | |||
| f1f14ce403 | |||
| 76350cd30f | |||
| 47293f28cf | |||
| 325fe7e663 | |||
| 56102737d7 | |||
| c2b7c1f13b | |||
| c8f5e228fc | |||
| d3c6b85638 | |||
| 96a45e842e | |||
| c280cd7290 | |||
| 44290af516 | |||
| 649841e6bf | |||
| 606c80344a | |||
| 6ea22535e2 | |||
| e4acd74e87 | |||
| b07031b594 | |||
| 0981814473 | |||
| 3d635cb4a7 | |||
| b0aace31ec | |||
| 9eb78eeb18 | |||
| 6dfa647f05 | |||
| f8f425e34c | |||
| 206a3fcea8 | |||
| c855dcc52f | |||
| cb2052dbfe | |||
| 400572b19f | |||
| a6b178a3d9 | |||
| 4718a4bf81 | |||
| 9efaa3cce7 | |||
| ff8af10cfe | |||
| cd44aa0bb1 | |||
| d3ae175bca | |||
| deaf632881 | |||
| c67d4fc633 | |||
| f45a12439a | |||
| bd9d60c4c6 | |||
| 4d918ba40b | |||
| bf29a4d746 | |||
| 743d4ecf7b | |||
| 52855a39ad | |||
| cb7fe597a5 | |||
| 8ffc06ff72 | |||
| 186c18668c | |||
| 4009bca59a | |||
| 18cbfa4a4f | |||
| b71a168937 | |||
| 35c17f35be | |||
| 3085fc6345 | |||
| 17e860a288 | |||
| e200b88a5a | |||
| 1833b034fe | |||
| 69020666fe | |||
| 53144ee0eb | |||
| 952962a111 | |||
| c664cf3717 | |||
| dbdd357b0a | |||
| f3a03aefad | |||
| c1e5c16ff3 | |||
| c63d79c5b1 | |||
| a9d02f096e | |||
| 6a7d54f550 | |||
| 3d5e3a910f | |||
| ef0fcb9238 | |||
| b5bf756ca0 | |||
| ad8f8b0c8c | |||
| 840b1d5c94 | |||
| 974102bc7f | |||
| 5bacd8753b | |||
| cbc9745b79 | |||
| 65c2d6a2be | |||
| b16a4ba25b | |||
| 927aa1e617 | |||
| fdf2151d9f | |||
| e0aa677388 | |||
| 2ab46d9553 | |||
| 36815fe3f3 | |||
| a64b51dd94 | |||
| 55534eeb06 | |||
| b5a0d2b580 | |||
| 82616eec41 | |||
| 7e52003533 | |||
| 7b7774476e | |||
| 4df6e39bab | |||
| 54449b614b | |||
| a2fc479c0b | |||
| 9208dcb07c | |||
| 2eb7bf4cfa | |||
| c8561eae2d | |||
| 5acf351e4b |
@@ -0,0 +1,3 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: opencv
|
||||
@@ -15,12 +15,12 @@ body:
|
||||
Please provide the following system information to help us diagnose the bug. For example:
|
||||
|
||||
// example for c++ user
|
||||
OpenCV version: 4.6.0
|
||||
OpenCV version: 4.8.0
|
||||
Operating System / Platform: Ubuntu 20.04
|
||||
Compiler & compiler version: GCC 9.3.0
|
||||
|
||||
// example for python user
|
||||
OpenCV python version: 4.6.0.66
|
||||
OpenCV python version: 4.8.0.74
|
||||
Operating System / Platform: Ubuntu 20.04
|
||||
Python version: 3.9.6
|
||||
validations:
|
||||
|
||||
@@ -10,9 +10,9 @@ body:
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Descripe the doc issue
|
||||
label: Describe the doc issue
|
||||
description: >
|
||||
Please provide a clear and concise description of what content in https://docs.opencv.org/ is an issue. Note that there are multiple active branches, such as 3.4, 4.x and 5.x, so please specify the branch with the problem.
|
||||
Please provide a clear and concise description of what content in https://docs.opencv.org/ is an issue. Note that there are multiple active branches, such as 4.x and 5.x, so please specify the branch with the problem.
|
||||
placeholder: |
|
||||
A clear and concise description of what content in https://docs.opencv.org/ is an issue.
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ body:
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Descripe the feature and motivation
|
||||
label: Describe the feature and motivation
|
||||
description: |
|
||||
Please provide a clear and concise proposal of the feature and outline the motivation.
|
||||
validations:
|
||||
|
||||
@@ -15,6 +15,12 @@ jobs:
|
||||
Ubuntu2004-x64:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-U20.yaml@main
|
||||
|
||||
Ubuntu2004-x64-OpenVINO:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-U20-OpenVINO.yaml@main
|
||||
|
||||
Ubuntu2204-x64:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-U22.yaml@main
|
||||
|
||||
Ubuntu2004-x64-CUDA:
|
||||
if: "${{ contains(github.event.pull_request.labels.*.name, 'category: dnn') }} || ${{ contains(github.event.pull_request.labels.*.name, 'category: dnn (onnx)') }}"
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-U20-Cuda.yaml@main
|
||||
@@ -22,12 +28,18 @@ jobs:
|
||||
Windows10-x64:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-W10.yaml@main
|
||||
|
||||
Windows10-x64-Vulkan:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-W10-Vulkan.yaml@main
|
||||
|
||||
macOS-ARM64:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-macOS-ARM64.yaml@main
|
||||
|
||||
macOS-x64:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-macOS-x86_64.yaml@main
|
||||
|
||||
macOS-ARM64-Vulkan:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-macOS-ARM64-Vulkan.yaml@main
|
||||
|
||||
iOS:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-iOS.yaml@main
|
||||
|
||||
@@ -39,3 +51,6 @@ jobs:
|
||||
|
||||
docs:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-docs.yaml@main
|
||||
|
||||
Linux-RISC-V-Clang:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-RISCV.yaml@main
|
||||
|
||||
Vendored
+8
@@ -42,6 +42,14 @@ endif()
|
||||
|
||||
if(WITH_NEON)
|
||||
target_compile_definitions(carotene_objs PRIVATE "-DWITH_NEON")
|
||||
if(NOT DEFINED CAROTENE_NEON_ARCH )
|
||||
elseif(CAROTENE_NEON_ARCH EQUAL 8)
|
||||
target_compile_definitions(carotene_objs PRIVATE "-DCAROTENE_NEON_ARCH=8")
|
||||
elseif(CAROTENE_NEON_ARCH EQUAL 7)
|
||||
target_compile_definitions(carotene_objs PRIVATE "-DCAROTENE_NEON_ARCH=7")
|
||||
else()
|
||||
target_compile_definitions(carotene_objs PRIVATE "-DCAROTENE_NEON_ARCH=0")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# we add dummy file to fix XCode build
|
||||
|
||||
+7
-6
@@ -39,6 +39,7 @@
|
||||
|
||||
#include "common.hpp"
|
||||
#include "vtransform.hpp"
|
||||
#include "vround_helper.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
@@ -106,7 +107,7 @@ template <> struct wAdd<s32>
|
||||
{
|
||||
valpha = vdupq_n_f32(_alpha);
|
||||
vbeta = vdupq_n_f32(_beta);
|
||||
vgamma = vdupq_n_f32(_gamma + 0.5);
|
||||
vgamma = vdupq_n_f32(_gamma);
|
||||
}
|
||||
|
||||
void operator() (const VecTraits<s32>::vec128 & v_src0,
|
||||
@@ -118,7 +119,7 @@ template <> struct wAdd<s32>
|
||||
|
||||
vs1 = vmlaq_f32(vgamma, vs1, valpha);
|
||||
vs1 = vmlaq_f32(vs1, vs2, vbeta);
|
||||
v_dst = vcvtq_s32_f32(vs1);
|
||||
v_dst = vroundq_s32_f32(vs1);
|
||||
}
|
||||
|
||||
void operator() (const VecTraits<s32>::vec64 & v_src0,
|
||||
@@ -130,7 +131,7 @@ template <> struct wAdd<s32>
|
||||
|
||||
vs1 = vmla_f32(vget_low(vgamma), vs1, vget_low(valpha));
|
||||
vs1 = vmla_f32(vs1, vs2, vget_low(vbeta));
|
||||
v_dst = vcvt_s32_f32(vs1);
|
||||
v_dst = vround_s32_f32(vs1);
|
||||
}
|
||||
|
||||
void operator() (const s32 * src0, const s32 * src1, s32 * dst) const
|
||||
@@ -150,7 +151,7 @@ template <> struct wAdd<u32>
|
||||
{
|
||||
valpha = vdupq_n_f32(_alpha);
|
||||
vbeta = vdupq_n_f32(_beta);
|
||||
vgamma = vdupq_n_f32(_gamma + 0.5);
|
||||
vgamma = vdupq_n_f32(_gamma);
|
||||
}
|
||||
|
||||
void operator() (const VecTraits<u32>::vec128 & v_src0,
|
||||
@@ -162,7 +163,7 @@ template <> struct wAdd<u32>
|
||||
|
||||
vs1 = vmlaq_f32(vgamma, vs1, valpha);
|
||||
vs1 = vmlaq_f32(vs1, vs2, vbeta);
|
||||
v_dst = vcvtq_u32_f32(vs1);
|
||||
v_dst = vroundq_u32_f32(vs1);
|
||||
}
|
||||
|
||||
void operator() (const VecTraits<u32>::vec64 & v_src0,
|
||||
@@ -174,7 +175,7 @@ template <> struct wAdd<u32>
|
||||
|
||||
vs1 = vmla_f32(vget_low(vgamma), vs1, vget_low(valpha));
|
||||
vs1 = vmla_f32(vs1, vs2, vget_low(vbeta));
|
||||
v_dst = vcvt_u32_f32(vs1);
|
||||
v_dst = vround_u32_f32(vs1);
|
||||
}
|
||||
|
||||
void operator() (const u32 * src0, const u32 * src1, u32 * dst) const
|
||||
|
||||
Vendored
+7
-8
@@ -41,6 +41,7 @@
|
||||
|
||||
#include "common.hpp"
|
||||
#include "saturate_cast.hpp"
|
||||
#include "vround_helper.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
@@ -198,7 +199,6 @@ void blur3x3(const Size2D &size, s32 cn,
|
||||
//#define FLOAT_VARIANT_1_9
|
||||
#ifdef FLOAT_VARIANT_1_9
|
||||
float32x4_t v1_9 = vdupq_n_f32 (1.0/9.0);
|
||||
float32x4_t v0_5 = vdupq_n_f32 (.5);
|
||||
#else
|
||||
const int16x8_t vScale = vmovq_n_s16(3640);
|
||||
#endif
|
||||
@@ -283,8 +283,8 @@ void blur3x3(const Size2D &size, s32 cn,
|
||||
uint32x4_t tres2 = vmovl_u16(vget_high_u16(t0));
|
||||
float32x4_t vf1 = vmulq_f32(v1_9, vcvtq_f32_u32(tres1));
|
||||
float32x4_t vf2 = vmulq_f32(v1_9, vcvtq_f32_u32(tres2));
|
||||
tres1 = vcvtq_u32_f32(vaddq_f32(vf1, v0_5));
|
||||
tres2 = vcvtq_u32_f32(vaddq_f32(vf2, v0_5));
|
||||
tres1 = internal::vroundq_u32_f32(vf1);
|
||||
tres2 = internal::vroundq_u32_f32(vf2);
|
||||
t0 = vcombine_u16(vmovn_u32(tres1),vmovn_u32(tres2));
|
||||
vst1_u8(drow + x - 8, vmovn_u16(t0));
|
||||
#else
|
||||
@@ -445,8 +445,8 @@ void blur3x3(const Size2D &size, s32 cn,
|
||||
uint32x4_t tres2 = vmovl_u16(vget_high_u16(t0));
|
||||
float32x4_t vf1 = vmulq_f32(v1_9, vcvtq_f32_u32(tres1));
|
||||
float32x4_t vf2 = vmulq_f32(v1_9, vcvtq_f32_u32(tres2));
|
||||
tres1 = vcvtq_u32_f32(vaddq_f32(vf1, v0_5));
|
||||
tres2 = vcvtq_u32_f32(vaddq_f32(vf2, v0_5));
|
||||
tres1 = internal::vroundq_u32_f32(vf1);
|
||||
tres2 = internal::vroundq_u32_f32(vf2);
|
||||
t0 = vcombine_u16(vmovn_u32(tres1),vmovn_u32(tres2));
|
||||
vst1_u8(drow + x - 8, vmovn_u16(t0));
|
||||
#else
|
||||
@@ -508,7 +508,6 @@ void blur5x5(const Size2D &size, s32 cn,
|
||||
#define FLOAT_VARIANT_1_25
|
||||
#ifdef FLOAT_VARIANT_1_25
|
||||
float32x4_t v1_25 = vdupq_n_f32 (1.0f/25.0f);
|
||||
float32x4_t v0_5 = vdupq_n_f32 (.5f);
|
||||
#else
|
||||
const int16x8_t vScale = vmovq_n_s16(1310);
|
||||
#endif
|
||||
@@ -752,8 +751,8 @@ void blur5x5(const Size2D &size, s32 cn,
|
||||
uint32x4_t tres2 = vmovl_u16(vget_high_u16(t0));
|
||||
float32x4_t vf1 = vmulq_f32(v1_25, vcvtq_f32_u32(tres1));
|
||||
float32x4_t vf2 = vmulq_f32(v1_25, vcvtq_f32_u32(tres2));
|
||||
tres1 = vcvtq_u32_f32(vaddq_f32(vf1, v0_5));
|
||||
tres2 = vcvtq_u32_f32(vaddq_f32(vf2, v0_5));
|
||||
tres1 = internal::vroundq_u32_f32(vf1);
|
||||
tres2 = internal::vroundq_u32_f32(vf2);
|
||||
t0 = vcombine_u16(vmovn_u32(tres1),vmovn_u32(tres2));
|
||||
vst1_u8(drow + x - 8, vmovn_u16(t0));
|
||||
#else
|
||||
|
||||
+5
-11
@@ -40,6 +40,7 @@
|
||||
#include "common.hpp"
|
||||
|
||||
#include "saturate_cast.hpp"
|
||||
#include "vround_helper.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
@@ -1166,17 +1167,10 @@ inline uint8x8x3_t convertToHSV(const uint8x8_t vR, const uint8x8_t vG, const ui
|
||||
vSt3 = vmulq_f32(vHF1, vDivTab);
|
||||
vSt4 = vmulq_f32(vHF2, vDivTab);
|
||||
|
||||
float32x4_t bias = vdupq_n_f32(0.5f);
|
||||
|
||||
vSt1 = vaddq_f32(vSt1, bias);
|
||||
vSt2 = vaddq_f32(vSt2, bias);
|
||||
vSt3 = vaddq_f32(vSt3, bias);
|
||||
vSt4 = vaddq_f32(vSt4, bias);
|
||||
|
||||
uint32x4_t vRes1 = vcvtq_u32_f32(vSt1);
|
||||
uint32x4_t vRes2 = vcvtq_u32_f32(vSt2);
|
||||
uint32x4_t vRes3 = vcvtq_u32_f32(vSt3);
|
||||
uint32x4_t vRes4 = vcvtq_u32_f32(vSt4);
|
||||
uint32x4_t vRes1 = internal::vroundq_u32_f32(vSt1);
|
||||
uint32x4_t vRes2 = internal::vroundq_u32_f32(vSt2);
|
||||
uint32x4_t vRes3 = internal::vroundq_u32_f32(vSt3);
|
||||
uint32x4_t vRes4 = internal::vroundq_u32_f32(vSt4);
|
||||
|
||||
int32x4_t vH_L = vmovl_s16(vget_low_s16(vDiff4));
|
||||
int32x4_t vH_H = vmovl_s16(vget_high_s16(vDiff4));
|
||||
|
||||
Vendored
+11
@@ -58,6 +58,17 @@
|
||||
|
||||
namespace CAROTENE_NS { namespace internal {
|
||||
|
||||
#ifndef CAROTENE_NEON_ARCH
|
||||
# if defined(__aarch64__) || defined(__aarch32__)
|
||||
# define CAROTENE_NEON_ARCH 8
|
||||
# else
|
||||
# define CAROTENE_NEON_ARCH 7
|
||||
# endif
|
||||
#endif
|
||||
#if ( !defined(__aarch64__) && !defined(__aarch32__) ) && (CAROTENE_NEON_ARCH == 8 )
|
||||
# error("ARMv7 doen't support A32/A64 Neon instructions")
|
||||
#endif
|
||||
|
||||
inline void prefetch(const void *ptr, size_t offset = 32*10)
|
||||
{
|
||||
#if defined __GNUC__
|
||||
|
||||
+108
-107
@@ -38,6 +38,7 @@
|
||||
*/
|
||||
|
||||
#include "common.hpp"
|
||||
#include "vround_helper.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
@@ -185,7 +186,7 @@ CVTS_FUNC1(u8, 16,
|
||||
#else
|
||||
CVTS_FUNC1(u8, 16,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 16)
|
||||
{
|
||||
@@ -209,10 +210,10 @@ CVTS_FUNC1(u8, 16,
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline3_f32 = vaddq_f32(vline3_f32, vshift);
|
||||
vline4_f32 = vaddq_f32(vline4_f32, vshift);
|
||||
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
int32x4_t vline3_s32 = vcvtq_s32_f32(vline3_f32);
|
||||
int32x4_t vline4_s32 = vcvtq_s32_f32(vline4_f32);
|
||||
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
int32x4_t vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
|
||||
int32x4_t vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
|
||||
uint16x8_t vRes1_u16 = vcombine_u16(vqmovun_s32(vline1_s32), vqmovun_s32(vline2_s32));
|
||||
uint16x8_t vRes2_u16 = vcombine_u16(vqmovun_s32(vline3_s32), vqmovun_s32(vline4_s32));
|
||||
vst1q_u8(_dst + i, vcombine_u8(vqmovn_u16(vRes1_u16), vqmovn_u16(vRes2_u16)));
|
||||
@@ -270,7 +271,7 @@ CVTS_FUNC(u8, s8, 16,
|
||||
#else
|
||||
CVTS_FUNC(u8, s8, 16,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 16)
|
||||
{
|
||||
@@ -294,10 +295,10 @@ CVTS_FUNC(u8, s8, 16,
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline3_f32 = vaddq_f32(vline3_f32, vshift);
|
||||
vline4_f32 = vaddq_f32(vline4_f32, vshift);
|
||||
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
int32x4_t vline3_s32 = vcvtq_s32_f32(vline3_f32);
|
||||
int32x4_t vline4_s32 = vcvtq_s32_f32(vline4_f32);
|
||||
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
int32x4_t vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
|
||||
int32x4_t vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
|
||||
int16x8_t vRes1_u16 = vcombine_s16(vqmovn_s32(vline1_s32), vqmovn_s32(vline2_s32));
|
||||
int16x8_t vRes2_u16 = vcombine_s16(vqmovn_s32(vline3_s32), vqmovn_s32(vline4_s32));
|
||||
vst1q_s8(_dst + i, vcombine_s8(vqmovn_s16(vRes1_u16), vqmovn_s16(vRes2_u16)));
|
||||
@@ -355,7 +356,7 @@ CVTS_FUNC(u8, u16, 16,
|
||||
#else
|
||||
CVTS_FUNC(u8, u16, 16,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 16)
|
||||
{
|
||||
@@ -379,10 +380,10 @@ CVTS_FUNC(u8, u16, 16,
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline3_f32 = vaddq_f32(vline3_f32, vshift);
|
||||
vline4_f32 = vaddq_f32(vline4_f32, vshift);
|
||||
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
int32x4_t vline3_s32 = vcvtq_s32_f32(vline3_f32);
|
||||
int32x4_t vline4_s32 = vcvtq_s32_f32(vline4_f32);
|
||||
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
int32x4_t vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
|
||||
int32x4_t vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
|
||||
vst1q_u16(_dst + i + 0, vcombine_u16(vqmovun_s32(vline1_s32), vqmovun_s32(vline2_s32)));
|
||||
vst1q_u16(_dst + i + 8, vcombine_u16(vqmovun_s32(vline3_s32), vqmovun_s32(vline4_s32)));
|
||||
}
|
||||
@@ -439,7 +440,7 @@ CVTS_FUNC(u8, s16, 16,
|
||||
#else
|
||||
CVTS_FUNC(u8, s16, 16,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 16)
|
||||
{
|
||||
@@ -463,10 +464,10 @@ CVTS_FUNC(u8, s16, 16,
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline3_f32 = vaddq_f32(vline3_f32, vshift);
|
||||
vline4_f32 = vaddq_f32(vline4_f32, vshift);
|
||||
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
int32x4_t vline3_s32 = vcvtq_s32_f32(vline3_f32);
|
||||
int32x4_t vline4_s32 = vcvtq_s32_f32(vline4_f32);
|
||||
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
int32x4_t vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
|
||||
int32x4_t vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
|
||||
vst1q_s16(_dst + i + 0, vcombine_s16(vqmovn_s32(vline1_s32), vqmovn_s32(vline2_s32)));
|
||||
vst1q_s16(_dst + i + 8, vcombine_s16(vqmovn_s32(vline3_s32), vqmovn_s32(vline4_s32)));
|
||||
}
|
||||
@@ -526,7 +527,7 @@ CVTS_FUNC(u8, s32, 16,
|
||||
#else
|
||||
CVTS_FUNC(u8, s32, 16,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 16)
|
||||
{
|
||||
@@ -550,10 +551,10 @@ CVTS_FUNC(u8, s32, 16,
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline3_f32 = vaddq_f32(vline3_f32, vshift);
|
||||
vline4_f32 = vaddq_f32(vline4_f32, vshift);
|
||||
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
int32x4_t vline3_s32 = vcvtq_s32_f32(vline3_f32);
|
||||
int32x4_t vline4_s32 = vcvtq_s32_f32(vline4_f32);
|
||||
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
int32x4_t vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
|
||||
int32x4_t vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
|
||||
vst1q_s32(_dst + i + 0, vline1_s32);
|
||||
vst1q_s32(_dst + i + 4, vline2_s32);
|
||||
vst1q_s32(_dst + i + 8, vline3_s32);
|
||||
@@ -693,7 +694,7 @@ CVTS_FUNC(s8, u8, 16,
|
||||
#else
|
||||
CVTS_FUNC(s8, u8, 16,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 16)
|
||||
{
|
||||
@@ -717,10 +718,10 @@ CVTS_FUNC(s8, u8, 16,
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline3_f32 = vaddq_f32(vline3_f32, vshift);
|
||||
vline4_f32 = vaddq_f32(vline4_f32, vshift);
|
||||
vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
vline3_s32 = vcvtq_s32_f32(vline3_f32);
|
||||
vline4_s32 = vcvtq_s32_f32(vline4_f32);
|
||||
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
|
||||
vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
|
||||
uint16x8_t vRes1_u16 = vcombine_u16(vqmovun_s32(vline1_s32), vqmovun_s32(vline2_s32));
|
||||
uint16x8_t vRes2_u16 = vcombine_u16(vqmovun_s32(vline3_s32), vqmovun_s32(vline4_s32));
|
||||
vst1q_u8(_dst + i, vcombine_u8(vqmovn_u16(vRes1_u16), vqmovn_u16(vRes2_u16)));
|
||||
@@ -778,7 +779,7 @@ CVTS_FUNC1(s8, 16,
|
||||
#else
|
||||
CVTS_FUNC1(s8, 16,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 16)
|
||||
{
|
||||
@@ -802,10 +803,10 @@ CVTS_FUNC1(s8, 16,
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline3_f32 = vaddq_f32(vline3_f32, vshift);
|
||||
vline4_f32 = vaddq_f32(vline4_f32, vshift);
|
||||
vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
vline3_s32 = vcvtq_s32_f32(vline3_f32);
|
||||
vline4_s32 = vcvtq_s32_f32(vline4_f32);
|
||||
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
|
||||
vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
|
||||
int16x8_t vRes1_s16 = vcombine_s16(vqmovn_s32(vline1_s32), vqmovn_s32(vline2_s32));
|
||||
int16x8_t vRes2_s16 = vcombine_s16(vqmovn_s32(vline3_s32), vqmovn_s32(vline4_s32));
|
||||
vst1q_s8(_dst + i, vcombine_s8(vqmovn_s16(vRes1_s16), vqmovn_s16(vRes2_s16)));
|
||||
@@ -863,7 +864,7 @@ CVTS_FUNC(s8, u16, 16,
|
||||
#else
|
||||
CVTS_FUNC(s8, u16, 16,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 16)
|
||||
{
|
||||
@@ -887,10 +888,10 @@ CVTS_FUNC(s8, u16, 16,
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline3_f32 = vaddq_f32(vline3_f32, vshift);
|
||||
vline4_f32 = vaddq_f32(vline4_f32, vshift);
|
||||
vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
vline3_s32 = vcvtq_s32_f32(vline3_f32);
|
||||
vline4_s32 = vcvtq_s32_f32(vline4_f32);
|
||||
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
|
||||
vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
|
||||
uint16x8_t vRes1_u16 = vcombine_u16(vqmovun_s32(vline1_s32), vqmovun_s32(vline2_s32));
|
||||
uint16x8_t vRes2_u16 = vcombine_u16(vqmovun_s32(vline3_s32), vqmovun_s32(vline4_s32));
|
||||
vst1q_u16(_dst + i + 0, vRes1_u16);
|
||||
@@ -949,7 +950,7 @@ CVTS_FUNC(s8, s16, 16,
|
||||
#else
|
||||
CVTS_FUNC(s8, s16, 16,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 16)
|
||||
{
|
||||
@@ -973,10 +974,10 @@ CVTS_FUNC(s8, s16, 16,
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline3_f32 = vaddq_f32(vline3_f32, vshift);
|
||||
vline4_f32 = vaddq_f32(vline4_f32, vshift);
|
||||
vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
vline3_s32 = vcvtq_s32_f32(vline3_f32);
|
||||
vline4_s32 = vcvtq_s32_f32(vline4_f32);
|
||||
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
|
||||
vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
|
||||
int16x8_t vRes1_s16 = vcombine_s16(vqmovn_s32(vline1_s32), vqmovn_s32(vline2_s32));
|
||||
int16x8_t vRes2_s16 = vcombine_s16(vqmovn_s32(vline3_s32), vqmovn_s32(vline4_s32));
|
||||
vst1q_s16(_dst + i + 0, vRes1_s16);
|
||||
@@ -1038,7 +1039,7 @@ CVTS_FUNC(s8, s32, 16,
|
||||
#else
|
||||
CVTS_FUNC(s8, s32, 16,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 16)
|
||||
{
|
||||
@@ -1062,10 +1063,10 @@ CVTS_FUNC(s8, s32, 16,
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline3_f32 = vaddq_f32(vline3_f32, vshift);
|
||||
vline4_f32 = vaddq_f32(vline4_f32, vshift);
|
||||
vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
vline3_s32 = vcvtq_s32_f32(vline3_f32);
|
||||
vline4_s32 = vcvtq_s32_f32(vline4_f32);
|
||||
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
vline3_s32 = internal::vroundq_s32_f32(vline3_f32);
|
||||
vline4_s32 = internal::vroundq_s32_f32(vline4_f32);
|
||||
vst1q_s32(_dst + i + 0, vline1_s32);
|
||||
vst1q_s32(_dst + i + 4, vline2_s32);
|
||||
vst1q_s32(_dst + i + 8, vline3_s32);
|
||||
@@ -1190,7 +1191,7 @@ CVTS_FUNC(u16, u8, 16,
|
||||
#else
|
||||
CVTS_FUNC(u16, u8, 16,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -1204,8 +1205,8 @@ CVTS_FUNC(u16, u8, 16,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
|
||||
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
|
||||
uint8x8_t vRes = vqmovun_s16(vcombine_s16(vRes1, vRes2));
|
||||
@@ -1249,7 +1250,7 @@ CVTS_FUNC(u16, s8, 16,
|
||||
#else
|
||||
CVTS_FUNC(u16, s8, 16,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -1263,8 +1264,8 @@ CVTS_FUNC(u16, s8, 16,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
|
||||
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
|
||||
int8x8_t vRes = vqmovn_s16(vcombine_s16(vRes1, vRes2));
|
||||
@@ -1307,7 +1308,7 @@ CVTS_FUNC1(u16, 16,
|
||||
#else
|
||||
CVTS_FUNC1(u16, 16,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -1321,8 +1322,8 @@ CVTS_FUNC1(u16, 16,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
uint16x4_t vRes1 = vqmovun_s32(vline1_s32);
|
||||
uint16x4_t vRes2 = vqmovun_s32(vline2_s32);
|
||||
vst1q_u16(_dst + i, vcombine_u16(vRes1, vRes2));
|
||||
@@ -1364,7 +1365,7 @@ CVTS_FUNC(u16, s16, 8,
|
||||
#else
|
||||
CVTS_FUNC(u16, s16, 8,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -1378,8 +1379,8 @@ CVTS_FUNC(u16, s16, 8,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
|
||||
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
|
||||
vst1q_s16(_dst + i, vcombine_s16(vRes1, vRes2));
|
||||
@@ -1421,7 +1422,7 @@ CVTS_FUNC(u16, s32, 8,
|
||||
#else
|
||||
CVTS_FUNC(u16, s32, 8,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -1435,8 +1436,8 @@ CVTS_FUNC(u16, s32, 8,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
vst1q_s32(_dst + i + 0, vline1_s32);
|
||||
vst1q_s32(_dst + i + 4, vline2_s32);
|
||||
}
|
||||
@@ -1530,7 +1531,7 @@ CVTS_FUNC(s16, u8, 16,
|
||||
#else
|
||||
CVTS_FUNC(s16, u8, 16,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -1544,8 +1545,8 @@ CVTS_FUNC(s16, u8, 16,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
|
||||
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
|
||||
uint8x8_t vRes = vqmovun_s16(vcombine_s16(vRes1, vRes2));
|
||||
@@ -1589,7 +1590,7 @@ CVTS_FUNC(s16, s8, 16,
|
||||
#else
|
||||
CVTS_FUNC(s16, s8, 16,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -1603,8 +1604,8 @@ CVTS_FUNC(s16, s8, 16,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
|
||||
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
|
||||
int8x8_t vRes = vqmovn_s16(vcombine_s16(vRes1, vRes2));
|
||||
@@ -1647,7 +1648,7 @@ CVTS_FUNC(s16, u16, 8,
|
||||
#else
|
||||
CVTS_FUNC(s16, u16, 8,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -1661,8 +1662,8 @@ CVTS_FUNC(s16, u16, 8,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
uint16x4_t vRes1 = vqmovun_s32(vline1_s32);
|
||||
uint16x4_t vRes2 = vqmovun_s32(vline2_s32);
|
||||
vst1q_u16(_dst + i, vcombine_u16(vRes1, vRes2));
|
||||
@@ -1704,7 +1705,7 @@ CVTS_FUNC1(s16, 16,
|
||||
#else
|
||||
CVTS_FUNC1(s16, 16,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -1718,8 +1719,8 @@ CVTS_FUNC1(s16, 16,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
|
||||
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
|
||||
vst1q_s16(_dst + i, vcombine_s16(vRes1, vRes2));
|
||||
@@ -1761,7 +1762,7 @@ CVTS_FUNC(s16, s32, 8,
|
||||
#else
|
||||
CVTS_FUNC(s16, s32, 8,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -1775,8 +1776,8 @@ CVTS_FUNC(s16, s32, 8,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
vst1q_s32(_dst + i + 0, vline1_s32);
|
||||
vst1q_s32(_dst + i + 4, vline2_s32);
|
||||
}
|
||||
@@ -1870,7 +1871,7 @@ CVTS_FUNC(s32, u8, 8,
|
||||
#else
|
||||
CVTS_FUNC(s32, u8, 8,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -1883,8 +1884,8 @@ CVTS_FUNC(s32, u8, 8,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
uint16x4_t vRes1 = vqmovun_s32(vline1_s32);
|
||||
uint16x4_t vRes2 = vqmovun_s32(vline2_s32);
|
||||
uint8x8_t vRes = vqmovn_u16(vcombine_u16(vRes1, vRes2));
|
||||
@@ -1928,7 +1929,7 @@ CVTS_FUNC(s32, s8, 8,
|
||||
#else
|
||||
CVTS_FUNC(s32, s8, 8,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -1941,8 +1942,8 @@ CVTS_FUNC(s32, s8, 8,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
|
||||
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
|
||||
int8x8_t vRes = vqmovn_s16(vcombine_s16(vRes1, vRes2));
|
||||
@@ -1985,7 +1986,7 @@ CVTS_FUNC(s32, u16, 8,
|
||||
#else
|
||||
CVTS_FUNC(s32, u16, 8,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -1998,8 +1999,8 @@ CVTS_FUNC(s32, u16, 8,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
uint16x4_t vRes1 = vqmovun_s32(vline1_s32);
|
||||
uint16x4_t vRes2 = vqmovun_s32(vline2_s32);
|
||||
vst1q_u16(_dst + i, vcombine_u16(vRes1, vRes2));
|
||||
@@ -2041,7 +2042,7 @@ CVTS_FUNC(s32, s16, 8,
|
||||
#else
|
||||
CVTS_FUNC(s32, s16, 8,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -2054,8 +2055,8 @@ CVTS_FUNC(s32, s16, 8,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
|
||||
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
|
||||
vst1q_s16(_dst + i, vcombine_s16(vRes1, vRes2));
|
||||
@@ -2097,7 +2098,7 @@ CVTS_FUNC1(s32, 8,
|
||||
#else
|
||||
CVTS_FUNC1(s32, 8,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -2110,8 +2111,8 @@ CVTS_FUNC1(s32, 8,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
vst1q_s32(_dst + i + 0, vline1_s32);
|
||||
vst1q_s32(_dst + i + 4, vline2_s32);
|
||||
}
|
||||
@@ -2272,7 +2273,7 @@ CVTS_FUNC(f32, s8, 8,
|
||||
#else
|
||||
CVTS_FUNC(f32, s8, 8,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -2283,8 +2284,8 @@ CVTS_FUNC(f32, s8, 8,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
|
||||
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
|
||||
int8x8_t vRes = vqmovn_s16(vcombine_s16(vRes1, vRes2));
|
||||
@@ -2325,7 +2326,7 @@ CVTS_FUNC(f32, u16, 8,
|
||||
#else
|
||||
CVTS_FUNC(f32, u16, 8,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -2336,8 +2337,8 @@ CVTS_FUNC(f32, u16, 8,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
uint32x4_t vline1_u32 = vcvtq_u32_f32(vline1_f32);
|
||||
uint32x4_t vline2_u32 = vcvtq_u32_f32(vline2_f32);
|
||||
uint32x4_t vline1_u32 = internal::vroundq_u32_f32(vline1_f32);
|
||||
uint32x4_t vline2_u32 = internal::vroundq_u32_f32(vline2_f32);
|
||||
uint16x4_t vRes1 = vqmovn_u32(vline1_u32);
|
||||
uint16x4_t vRes2 = vqmovn_u32(vline2_u32);
|
||||
vst1q_u16(_dst + i, vcombine_u16(vRes1, vRes2));
|
||||
@@ -2377,7 +2378,7 @@ CVTS_FUNC(f32, s16, 8,
|
||||
#else
|
||||
CVTS_FUNC(f32, s16, 8,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -2388,8 +2389,8 @@ CVTS_FUNC(f32, s16, 8,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
int16x4_t vRes1 = vqmovn_s32(vline1_s32);
|
||||
int16x4_t vRes2 = vqmovn_s32(vline2_s32);
|
||||
vst1q_s16(_dst + i, vcombine_s16(vRes1, vRes2));
|
||||
@@ -2429,7 +2430,7 @@ CVTS_FUNC(f32, s32, 8,
|
||||
#else
|
||||
CVTS_FUNC(f32, s32, 8,
|
||||
float32x4_t vscale = vdupq_n_f32((f32)alpha);
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta + 0.5f);,
|
||||
float32x4_t vshift = vdupq_n_f32((f32)beta);,
|
||||
{
|
||||
for (size_t i = 0; i < w; i += 8)
|
||||
{
|
||||
@@ -2440,8 +2441,8 @@ CVTS_FUNC(f32, s32, 8,
|
||||
vline2_f32 = vmulq_f32(vline2_f32, vscale);
|
||||
vline1_f32 = vaddq_f32(vline1_f32, vshift);
|
||||
vline2_f32 = vaddq_f32(vline2_f32, vshift);
|
||||
int32x4_t vline1_s32 = vcvtq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = vcvtq_s32_f32(vline2_f32);
|
||||
int32x4_t vline1_s32 = internal::vroundq_s32_f32(vline1_f32);
|
||||
int32x4_t vline2_s32 = internal::vroundq_s32_f32(vline2_f32);
|
||||
vst1q_s32(_dst + i + 0, vline1_s32);
|
||||
vst1q_s32(_dst + i + 4, vline2_s32);
|
||||
}
|
||||
|
||||
Vendored
+7
-20
@@ -39,6 +39,7 @@
|
||||
|
||||
#include "common.hpp"
|
||||
#include "vtransform.hpp"
|
||||
#include "vround_helper.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <cfloat>
|
||||
@@ -51,13 +52,6 @@ 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)
|
||||
{
|
||||
@@ -69,17 +63,10 @@ inline T divSaturateQ(const T &v1, const T &v2, const float 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))))); }
|
||||
{ return internal::vroundq_s32_f32(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);
|
||||
}
|
||||
{ return internal::vroundq_u32_f32(vmulq_f32(vmulq_n_f32(vcvtq_f32_u32(v1), scale), internal::vrecpq_f32(vcvtq_f32_u32(v2)))); }
|
||||
|
||||
template <typename T>
|
||||
inline T divSaturate(const T &v1, const T &v2, const float scale)
|
||||
@@ -88,10 +75,10 @@ inline T divSaturate(const T &v1, const T &v2, const float 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))))); }
|
||||
{ return internal::vround_s32_f32(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))))); }
|
||||
{ return internal::vround_u32_f32(vmul_f32(vmul_n_f32(vcvt_f32_u32(v1), scale), internal::vrecp_f32(vcvt_f32_u32(v2)))); }
|
||||
|
||||
|
||||
template <typename T>
|
||||
@@ -157,8 +144,8 @@ void div(const Size2D &size,
|
||||
|
||||
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))
|
||||
(scale * static_cast<float>(std::numeric_limits<T>::max())) < 1.0f &&
|
||||
(scale * static_cast<float>(std::numeric_limits<T>::max())) > -1.0f))
|
||||
{
|
||||
for (size_t y = 0; y < size.height; ++y)
|
||||
{
|
||||
|
||||
Vendored
+7
-8
@@ -41,6 +41,7 @@
|
||||
#include <cmath>
|
||||
|
||||
#include "common.hpp"
|
||||
#include "vround_helper.hpp"
|
||||
|
||||
namespace CAROTENE_NS {
|
||||
|
||||
@@ -121,8 +122,6 @@ void phase(const Size2D &size,
|
||||
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);
|
||||
@@ -149,8 +148,8 @@ void phase(const Size2D &size,
|
||||
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))));
|
||||
uint16x8_t v_dst16s0 = vcombine_u16(vmovn_u32(internal::vroundq_u32_f32(v_dst32f0)),
|
||||
vmovn_u32(internal::vroundq_u32_f32(v_dst32f1)));
|
||||
|
||||
// 1
|
||||
v_src0_p = vcvtq_f32_s32(vmovl_s16(vget_low_s16(v_src01)));
|
||||
@@ -161,8 +160,8 @@ void phase(const Size2D &size,
|
||||
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))));
|
||||
uint16x8_t v_dst16s1 = vcombine_u16(vmovn_u32(internal::vroundq_u32_f32(v_dst32f0)),
|
||||
vmovn_u32(internal::vroundq_u32_f32(v_dst32f1)));
|
||||
|
||||
vst1q_u8(dst + j, vcombine_u8(vmovn_u16(v_dst16s0),
|
||||
vmovn_u16(v_dst16s1)));
|
||||
@@ -182,8 +181,8 @@ void phase(const Size2D &size,
|
||||
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))));
|
||||
uint16x8_t v_dst = vcombine_u16(vmovn_u32(internal::vroundq_u32_f32(v_dst32f0)),
|
||||
vmovn_u32(internal::vroundq_u32_f32(v_dst32f1)));
|
||||
|
||||
vst1_u8(dst + j, vmovn_u16(v_dst));
|
||||
}
|
||||
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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_VROUND_HELPER_HPP
|
||||
#define CAROTENE_SRC_VROUND_HELPER_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
#include "vtransform.hpp"
|
||||
|
||||
#ifdef CAROTENE_NEON
|
||||
|
||||
/**
|
||||
* This helper header is for rounding from float32xN to uin32xN or int32xN to nearest, ties to even.
|
||||
* See https://en.wikipedia.org/wiki/Rounding#Rounding_half_to_even
|
||||
*/
|
||||
|
||||
// See https://github.com/opencv/opencv/pull/24271#issuecomment-1867318007
|
||||
#define CAROTENE_ROUND_DELTA (12582912.0f)
|
||||
|
||||
namespace CAROTENE_NS { namespace internal {
|
||||
|
||||
inline uint32x4_t vroundq_u32_f32(const float32x4_t val)
|
||||
{
|
||||
#if CAROTENE_NEON_ARCH >= 8 /* get ready for ARMv9 */
|
||||
return vcvtnq_u32_f32(val);
|
||||
#else
|
||||
const float32x4_t delta = vdupq_n_f32(CAROTENE_ROUND_DELTA);
|
||||
return vcvtq_u32_f32(vsubq_f32(vaddq_f32(val, delta), delta));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint32x2_t vround_u32_f32(const float32x2_t val)
|
||||
{
|
||||
#if CAROTENE_NEON_ARCH >= 8 /* get ready for ARMv9 */
|
||||
return vcvtn_u32_f32(val);
|
||||
#else
|
||||
const float32x2_t delta = vdup_n_f32(CAROTENE_ROUND_DELTA);
|
||||
return vcvt_u32_f32(vsub_f32(vadd_f32(val, delta), delta));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int32x4_t vroundq_s32_f32(const float32x4_t val)
|
||||
{
|
||||
#if CAROTENE_NEON_ARCH >= 8 /* get ready for ARMv9 */
|
||||
return vcvtnq_s32_f32(val);
|
||||
#else
|
||||
const float32x4_t delta = vdupq_n_f32(CAROTENE_ROUND_DELTA);
|
||||
return vcvtq_s32_f32(vsubq_f32(vaddq_f32(val, delta), delta));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int32x2_t vround_s32_f32(const float32x2_t val)
|
||||
{
|
||||
#if CAROTENE_NEON_ARCH >= 8 /* get ready for ARMv9 */
|
||||
return vcvtn_s32_f32(val);
|
||||
#else
|
||||
const float32x2_t delta = vdup_n_f32(CAROTENE_ROUND_DELTA);
|
||||
return vcvt_s32_f32(vsub_f32(vadd_f32(val, delta), delta));
|
||||
#endif
|
||||
}
|
||||
|
||||
} }
|
||||
|
||||
#endif // CAROTENE_NEON
|
||||
|
||||
#endif
|
||||
Vendored
+5
-5
@@ -1,8 +1,8 @@
|
||||
# Binaries branch name: ffmpeg/4.x_20221225
|
||||
# Binaries were created for OpenCV: 4abe6dc48d4ec6229f332cc6cf6c7e234ac8027e
|
||||
ocv_update(FFMPEG_BINARIES_COMMIT "7dd0d4f1d6fe75f05f3d3b5e38cbc96c1a2d2809")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN32 "e598ae2ece1ddf310bc49b58202fd87a")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN64 "b2a40c142c20aef9fd663fc8f85c2971")
|
||||
# Binaries branch name: ffmpeg/4.x_20231225
|
||||
# Binaries were created for OpenCV: 62f1a7410d5e5e03d6cee5c95549bf61d5ee98db
|
||||
ocv_update(FFMPEG_BINARIES_COMMIT "fbac408a47977ee4265f39e7659d33f1dfef5216")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN32 "9b755ecbbade0a5b78332e9b4ef2dd1b")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN64 "cb4db51ee9a423e6168b9d08bee61efc")
|
||||
ocv_update(FFMPEG_FILE_HASH_CMAKE "8862c87496e2e8c375965e1277dee1c7")
|
||||
|
||||
function(download_win_ffmpeg script_var)
|
||||
|
||||
Vendored
+202
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
Origin: https://github.com/google/flatbuffers/tree/v23.5.9
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLATBUFFERS_ALLOCATOR_H_
|
||||
#define FLATBUFFERS_ALLOCATOR_H_
|
||||
|
||||
#include "flatbuffers/base.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
// Allocator interface. This is flatbuffers-specific and meant only for
|
||||
// `vector_downward` usage.
|
||||
class Allocator {
|
||||
public:
|
||||
virtual ~Allocator() {}
|
||||
|
||||
// Allocate `size` bytes of memory.
|
||||
virtual uint8_t *allocate(size_t size) = 0;
|
||||
|
||||
// Deallocate `size` bytes of memory at `p` allocated by this allocator.
|
||||
virtual void deallocate(uint8_t *p, size_t size) = 0;
|
||||
|
||||
// Reallocate `new_size` bytes of memory, replacing the old region of size
|
||||
// `old_size` at `p`. In contrast to a normal realloc, this grows downwards,
|
||||
// and is intended specifcally for `vector_downward` use.
|
||||
// `in_use_back` and `in_use_front` indicate how much of `old_size` is
|
||||
// actually in use at each end, and needs to be copied.
|
||||
virtual uint8_t *reallocate_downward(uint8_t *old_p, size_t old_size,
|
||||
size_t new_size, size_t in_use_back,
|
||||
size_t in_use_front) {
|
||||
FLATBUFFERS_ASSERT(new_size > old_size); // vector_downward only grows
|
||||
uint8_t *new_p = allocate(new_size);
|
||||
memcpy_downward(old_p, old_size, new_p, new_size, in_use_back,
|
||||
in_use_front);
|
||||
deallocate(old_p, old_size);
|
||||
return new_p;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Called by `reallocate_downward` to copy memory from `old_p` of `old_size`
|
||||
// to `new_p` of `new_size`. Only memory of size `in_use_front` and
|
||||
// `in_use_back` will be copied from the front and back of the old memory
|
||||
// allocation.
|
||||
void memcpy_downward(uint8_t *old_p, size_t old_size, uint8_t *new_p,
|
||||
size_t new_size, size_t in_use_back,
|
||||
size_t in_use_front) {
|
||||
memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back,
|
||||
in_use_back);
|
||||
memcpy(new_p, old_p, in_use_front);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_ALLOCATOR_H_
|
||||
+256
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLATBUFFERS_ARRAY_H_
|
||||
#define FLATBUFFERS_ARRAY_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "flatbuffers/base.h"
|
||||
#include "flatbuffers/stl_emulation.h"
|
||||
#include "flatbuffers/vector.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
// This is used as a helper type for accessing arrays.
|
||||
template<typename T, uint16_t length> class Array {
|
||||
// Array<T> can carry only POD data types (scalars or structs).
|
||||
typedef typename flatbuffers::bool_constant<flatbuffers::is_scalar<T>::value>
|
||||
scalar_tag;
|
||||
typedef
|
||||
typename flatbuffers::conditional<scalar_tag::value, T, const T *>::type
|
||||
IndirectHelperType;
|
||||
|
||||
public:
|
||||
typedef uint16_t size_type;
|
||||
typedef typename IndirectHelper<IndirectHelperType>::return_type return_type;
|
||||
typedef VectorConstIterator<T, return_type, uoffset_t> const_iterator;
|
||||
typedef VectorReverseIterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
// If T is a LE-scalar or a struct (!scalar_tag::value).
|
||||
static FLATBUFFERS_CONSTEXPR bool is_span_observable =
|
||||
(scalar_tag::value && (FLATBUFFERS_LITTLEENDIAN || sizeof(T) == 1)) ||
|
||||
!scalar_tag::value;
|
||||
|
||||
FLATBUFFERS_CONSTEXPR uint16_t size() const { return length; }
|
||||
|
||||
return_type Get(uoffset_t i) const {
|
||||
FLATBUFFERS_ASSERT(i < size());
|
||||
return IndirectHelper<IndirectHelperType>::Read(Data(), i);
|
||||
}
|
||||
|
||||
return_type operator[](uoffset_t i) const { return Get(i); }
|
||||
|
||||
// If this is a Vector of enums, T will be its storage type, not the enum
|
||||
// type. This function makes it convenient to retrieve value with enum
|
||||
// type E.
|
||||
template<typename E> E GetEnum(uoffset_t i) const {
|
||||
return static_cast<E>(Get(i));
|
||||
}
|
||||
|
||||
const_iterator begin() const { return const_iterator(Data(), 0); }
|
||||
const_iterator end() const { return const_iterator(Data(), size()); }
|
||||
|
||||
const_reverse_iterator rbegin() const {
|
||||
return const_reverse_iterator(end());
|
||||
}
|
||||
const_reverse_iterator rend() const {
|
||||
return const_reverse_iterator(begin());
|
||||
}
|
||||
|
||||
const_iterator cbegin() const { return begin(); }
|
||||
const_iterator cend() const { return end(); }
|
||||
|
||||
const_reverse_iterator crbegin() const { return rbegin(); }
|
||||
const_reverse_iterator crend() const { return rend(); }
|
||||
|
||||
// Get a mutable pointer to elements inside this array.
|
||||
// This method used to mutate arrays of structs followed by a @p Mutate
|
||||
// operation. For primitive types use @p Mutate directly.
|
||||
// @warning Assignments and reads to/from the dereferenced pointer are not
|
||||
// automatically converted to the correct endianness.
|
||||
typename flatbuffers::conditional<scalar_tag::value, void, T *>::type
|
||||
GetMutablePointer(uoffset_t i) const {
|
||||
FLATBUFFERS_ASSERT(i < size());
|
||||
return const_cast<T *>(&data()[i]);
|
||||
}
|
||||
|
||||
// Change elements if you have a non-const pointer to this object.
|
||||
void Mutate(uoffset_t i, const T &val) { MutateImpl(scalar_tag(), i, val); }
|
||||
|
||||
// The raw data in little endian format. Use with care.
|
||||
const uint8_t *Data() const { return data_; }
|
||||
|
||||
uint8_t *Data() { return data_; }
|
||||
|
||||
// Similarly, but typed, much like std::vector::data
|
||||
const T *data() const { return reinterpret_cast<const T *>(Data()); }
|
||||
T *data() { return reinterpret_cast<T *>(Data()); }
|
||||
|
||||
// Copy data from a span with endian conversion.
|
||||
// If this Array and the span overlap, the behavior is undefined.
|
||||
void CopyFromSpan(flatbuffers::span<const T, length> src) {
|
||||
const auto p1 = reinterpret_cast<const uint8_t *>(src.data());
|
||||
const auto p2 = Data();
|
||||
FLATBUFFERS_ASSERT(!(p1 >= p2 && p1 < (p2 + length)) &&
|
||||
!(p2 >= p1 && p2 < (p1 + length)));
|
||||
(void)p1;
|
||||
(void)p2;
|
||||
CopyFromSpanImpl(flatbuffers::bool_constant<is_span_observable>(), src);
|
||||
}
|
||||
|
||||
protected:
|
||||
void MutateImpl(flatbuffers::true_type, uoffset_t i, const T &val) {
|
||||
FLATBUFFERS_ASSERT(i < size());
|
||||
WriteScalar(data() + i, val);
|
||||
}
|
||||
|
||||
void MutateImpl(flatbuffers::false_type, uoffset_t i, const T &val) {
|
||||
*(GetMutablePointer(i)) = val;
|
||||
}
|
||||
|
||||
void CopyFromSpanImpl(flatbuffers::true_type,
|
||||
flatbuffers::span<const T, length> src) {
|
||||
// Use std::memcpy() instead of std::copy() to avoid performance degradation
|
||||
// due to aliasing if T is char or unsigned char.
|
||||
// The size is known at compile time, so memcpy would be inlined.
|
||||
std::memcpy(data(), src.data(), length * sizeof(T));
|
||||
}
|
||||
|
||||
// Copy data from flatbuffers::span with endian conversion.
|
||||
void CopyFromSpanImpl(flatbuffers::false_type,
|
||||
flatbuffers::span<const T, length> src) {
|
||||
for (size_type k = 0; k < length; k++) { Mutate(k, src[k]); }
|
||||
}
|
||||
|
||||
// This class is only used to access pre-existing data. Don't ever
|
||||
// try to construct these manually.
|
||||
// 'constexpr' allows us to use 'size()' at compile time.
|
||||
// @note Must not use 'FLATBUFFERS_CONSTEXPR' here, as const is not allowed on
|
||||
// a constructor.
|
||||
#if defined(__cpp_constexpr)
|
||||
constexpr Array();
|
||||
#else
|
||||
Array();
|
||||
#endif
|
||||
|
||||
uint8_t data_[length * sizeof(T)];
|
||||
|
||||
private:
|
||||
// This class is a pointer. Copying will therefore create an invalid object.
|
||||
// Private and unimplemented copy constructor.
|
||||
Array(const Array &);
|
||||
Array &operator=(const Array &);
|
||||
};
|
||||
|
||||
// Specialization for Array[struct] with access using Offset<void> pointer.
|
||||
// This specialization used by idl_gen_text.cpp.
|
||||
template<typename T, uint16_t length, template<typename> class OffsetT>
|
||||
class Array<OffsetT<T>, length> {
|
||||
static_assert(flatbuffers::is_same<T, void>::value, "unexpected type T");
|
||||
|
||||
public:
|
||||
typedef const void *return_type;
|
||||
typedef uint16_t size_type;
|
||||
|
||||
const uint8_t *Data() const { return data_; }
|
||||
|
||||
// Make idl_gen_text.cpp::PrintContainer happy.
|
||||
return_type operator[](uoffset_t) const {
|
||||
FLATBUFFERS_ASSERT(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
// This class is only used to access pre-existing data.
|
||||
Array();
|
||||
Array(const Array &);
|
||||
Array &operator=(const Array &);
|
||||
|
||||
uint8_t data_[1];
|
||||
};
|
||||
|
||||
template<class U, uint16_t N>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U, N> make_span(Array<U, N> &arr)
|
||||
FLATBUFFERS_NOEXCEPT {
|
||||
static_assert(
|
||||
Array<U, N>::is_span_observable,
|
||||
"wrong type U, only plain struct, LE-scalar, or byte types are allowed");
|
||||
return span<U, N>(arr.data(), N);
|
||||
}
|
||||
|
||||
template<class U, uint16_t N>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U, N> make_span(
|
||||
const Array<U, N> &arr) FLATBUFFERS_NOEXCEPT {
|
||||
static_assert(
|
||||
Array<U, N>::is_span_observable,
|
||||
"wrong type U, only plain struct, LE-scalar, or byte types are allowed");
|
||||
return span<const U, N>(arr.data(), N);
|
||||
}
|
||||
|
||||
template<class U, uint16_t N>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<uint8_t, sizeof(U) * N>
|
||||
make_bytes_span(Array<U, N> &arr) FLATBUFFERS_NOEXCEPT {
|
||||
static_assert(Array<U, N>::is_span_observable,
|
||||
"internal error, Array<T> might hold only scalars or structs");
|
||||
return span<uint8_t, sizeof(U) * N>(arr.Data(), sizeof(U) * N);
|
||||
}
|
||||
|
||||
template<class U, uint16_t N>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const uint8_t, sizeof(U) * N>
|
||||
make_bytes_span(const Array<U, N> &arr) FLATBUFFERS_NOEXCEPT {
|
||||
static_assert(Array<U, N>::is_span_observable,
|
||||
"internal error, Array<T> might hold only scalars or structs");
|
||||
return span<const uint8_t, sizeof(U) * N>(arr.Data(), sizeof(U) * N);
|
||||
}
|
||||
|
||||
// Cast a raw T[length] to a raw flatbuffers::Array<T, length>
|
||||
// without endian conversion. Use with care.
|
||||
// TODO: move these Cast-methods to `internal` namespace.
|
||||
template<typename T, uint16_t length>
|
||||
Array<T, length> &CastToArray(T (&arr)[length]) {
|
||||
return *reinterpret_cast<Array<T, length> *>(arr);
|
||||
}
|
||||
|
||||
template<typename T, uint16_t length>
|
||||
const Array<T, length> &CastToArray(const T (&arr)[length]) {
|
||||
return *reinterpret_cast<const Array<T, length> *>(arr);
|
||||
}
|
||||
|
||||
template<typename E, typename T, uint16_t length>
|
||||
Array<E, length> &CastToArrayOfEnum(T (&arr)[length]) {
|
||||
static_assert(sizeof(E) == sizeof(T), "invalid enum type E");
|
||||
return *reinterpret_cast<Array<E, length> *>(arr);
|
||||
}
|
||||
|
||||
template<typename E, typename T, uint16_t length>
|
||||
const Array<E, length> &CastToArrayOfEnum(const T (&arr)[length]) {
|
||||
static_assert(sizeof(E) == sizeof(T), "invalid enum type E");
|
||||
return *reinterpret_cast<const Array<E, length> *>(arr);
|
||||
}
|
||||
|
||||
template<typename T, uint16_t length>
|
||||
bool operator==(const Array<T, length> &lhs,
|
||||
const Array<T, length> &rhs) noexcept {
|
||||
return std::addressof(lhs) == std::addressof(rhs) ||
|
||||
(lhs.size() == rhs.size() &&
|
||||
std::memcmp(lhs.Data(), rhs.Data(), rhs.size() * sizeof(T)) == 0);
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_ARRAY_H_
|
||||
+495
@@ -0,0 +1,495 @@
|
||||
#ifndef FLATBUFFERS_BASE_H_
|
||||
#define FLATBUFFERS_BASE_H_
|
||||
|
||||
// clang-format off
|
||||
|
||||
// If activate should be declared and included first.
|
||||
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \
|
||||
defined(_MSC_VER) && defined(_DEBUG)
|
||||
// The _CRTDBG_MAP_ALLOC inside <crtdbg.h> will replace
|
||||
// calloc/free (etc) to its debug version using #define directives.
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <stdlib.h>
|
||||
#include <crtdbg.h>
|
||||
// Replace operator new by trace-enabled version.
|
||||
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
|
||||
#define new DEBUG_NEW
|
||||
#endif
|
||||
|
||||
#if !defined(FLATBUFFERS_ASSERT)
|
||||
#include <assert.h>
|
||||
#define FLATBUFFERS_ASSERT assert
|
||||
#elif defined(FLATBUFFERS_ASSERT_INCLUDE)
|
||||
// Include file with forward declaration
|
||||
#include FLATBUFFERS_ASSERT_INCLUDE
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINO
|
||||
#include <cstdint>
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#if defined(ARDUINO) && !defined(ARDUINOSTL_M_H) && defined(__AVR__)
|
||||
#include <utility.h>
|
||||
#else
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
|
||||
#if defined(__unix__) && !defined(FLATBUFFERS_LOCALE_INDEPENDENT)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android/api-level.h>
|
||||
#endif
|
||||
|
||||
#if defined(__ICCARM__)
|
||||
#include <intrinsics.h>
|
||||
#endif
|
||||
|
||||
// Note the __clang__ check is needed, because clang presents itself
|
||||
// as an older GNUC compiler (4.2).
|
||||
// Clang 3.3 and later implement all of the ISO C++ 2011 standard.
|
||||
// Clang 3.4 and later implement all of the ISO C++ 2014 standard.
|
||||
// http://clang.llvm.org/cxx_status.html
|
||||
|
||||
// Note the MSVC value '__cplusplus' may be incorrect:
|
||||
// The '__cplusplus' predefined macro in the MSVC stuck at the value 199711L,
|
||||
// indicating (erroneously!) that the compiler conformed to the C++98 Standard.
|
||||
// This value should be correct starting from MSVC2017-15.7-Preview-3.
|
||||
// The '__cplusplus' will be valid only if MSVC2017-15.7-P3 and the `/Zc:__cplusplus` switch is set.
|
||||
// Workaround (for details see MSDN):
|
||||
// Use the _MSC_VER and _MSVC_LANG definition instead of the __cplusplus for compatibility.
|
||||
// The _MSVC_LANG macro reports the Standard version regardless of the '/Zc:__cplusplus' switch.
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#define FLATBUFFERS_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||
#else
|
||||
#define FLATBUFFERS_GCC 0
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
#define FLATBUFFERS_CLANG (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
|
||||
#else
|
||||
#define FLATBUFFERS_CLANG 0
|
||||
#endif
|
||||
|
||||
/// @cond FLATBUFFERS_INTERNAL
|
||||
#if __cplusplus <= 199711L && \
|
||||
(!defined(_MSC_VER) || _MSC_VER < 1600) && \
|
||||
(!defined(__GNUC__) || \
|
||||
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40400))
|
||||
#error A C++11 compatible compiler with support for the auto typing is \
|
||||
required for FlatBuffers.
|
||||
#error __cplusplus _MSC_VER __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__
|
||||
#endif
|
||||
|
||||
#if !defined(__clang__) && \
|
||||
defined(__GNUC__) && \
|
||||
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600)
|
||||
// Backwards compatibility for g++ 4.4, and 4.5 which don't have the nullptr
|
||||
// and constexpr keywords. Note the __clang__ check is needed, because clang
|
||||
// presents itself as an older GNUC compiler.
|
||||
#ifndef nullptr_t
|
||||
const class nullptr_t {
|
||||
public:
|
||||
template<class T> inline operator T*() const { return 0; }
|
||||
private:
|
||||
void operator&() const;
|
||||
} nullptr = {};
|
||||
#endif
|
||||
#ifndef constexpr
|
||||
#define constexpr const
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// The wire format uses a little endian encoding (since that's efficient for
|
||||
// the common platforms).
|
||||
#if defined(__s390x__)
|
||||
#define FLATBUFFERS_LITTLEENDIAN 0
|
||||
#endif // __s390x__
|
||||
#if !defined(FLATBUFFERS_LITTLEENDIAN)
|
||||
#if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
|
||||
#if (defined(__BIG_ENDIAN__) || \
|
||||
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
|
||||
#define FLATBUFFERS_LITTLEENDIAN 0
|
||||
#else
|
||||
#define FLATBUFFERS_LITTLEENDIAN 1
|
||||
#endif // __BIG_ENDIAN__
|
||||
#elif defined(_MSC_VER)
|
||||
#if defined(_M_PPC)
|
||||
#define FLATBUFFERS_LITTLEENDIAN 0
|
||||
#else
|
||||
#define FLATBUFFERS_LITTLEENDIAN 1
|
||||
#endif
|
||||
#else
|
||||
#error Unable to determine endianness, define FLATBUFFERS_LITTLEENDIAN.
|
||||
#endif
|
||||
#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
|
||||
|
||||
#define FLATBUFFERS_VERSION_MAJOR 23
|
||||
#define FLATBUFFERS_VERSION_MINOR 5
|
||||
#define FLATBUFFERS_VERSION_REVISION 9
|
||||
#define FLATBUFFERS_STRING_EXPAND(X) #X
|
||||
#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
|
||||
namespace flatbuffers {
|
||||
// Returns version as string "MAJOR.MINOR.REVISION".
|
||||
const char* FLATBUFFERS_VERSION();
|
||||
}
|
||||
|
||||
#if (!defined(_MSC_VER) || _MSC_VER > 1600) && \
|
||||
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 407)) || \
|
||||
defined(__clang__)
|
||||
#define FLATBUFFERS_FINAL_CLASS final
|
||||
#define FLATBUFFERS_OVERRIDE override
|
||||
#define FLATBUFFERS_EXPLICIT_CPP11 explicit
|
||||
#define FLATBUFFERS_VTABLE_UNDERLYING_TYPE : flatbuffers::voffset_t
|
||||
#else
|
||||
#define FLATBUFFERS_FINAL_CLASS
|
||||
#define FLATBUFFERS_OVERRIDE
|
||||
#define FLATBUFFERS_EXPLICIT_CPP11
|
||||
#define FLATBUFFERS_VTABLE_UNDERLYING_TYPE
|
||||
#endif
|
||||
|
||||
#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \
|
||||
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \
|
||||
(defined(__cpp_constexpr) && __cpp_constexpr >= 200704)
|
||||
#define FLATBUFFERS_CONSTEXPR constexpr
|
||||
#define FLATBUFFERS_CONSTEXPR_CPP11 constexpr
|
||||
#define FLATBUFFERS_CONSTEXPR_DEFINED
|
||||
#else
|
||||
#define FLATBUFFERS_CONSTEXPR const
|
||||
#define FLATBUFFERS_CONSTEXPR_CPP11
|
||||
#endif
|
||||
|
||||
#if (defined(__cplusplus) && __cplusplus >= 201402L) || \
|
||||
(defined(__cpp_constexpr) && __cpp_constexpr >= 201304)
|
||||
#define FLATBUFFERS_CONSTEXPR_CPP14 FLATBUFFERS_CONSTEXPR_CPP11
|
||||
#else
|
||||
#define FLATBUFFERS_CONSTEXPR_CPP14
|
||||
#endif
|
||||
|
||||
#if (defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \
|
||||
(defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023026)) || \
|
||||
defined(__clang__)
|
||||
#define FLATBUFFERS_NOEXCEPT noexcept
|
||||
#else
|
||||
#define FLATBUFFERS_NOEXCEPT
|
||||
#endif
|
||||
|
||||
// NOTE: the FLATBUFFERS_DELETE_FUNC macro may change the access mode to
|
||||
// private, so be sure to put it at the end or reset access mode explicitly.
|
||||
#if (!defined(_MSC_VER) || _MSC_FULL_VER >= 180020827) && \
|
||||
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)) || \
|
||||
defined(__clang__)
|
||||
#define FLATBUFFERS_DELETE_FUNC(func) func = delete
|
||||
#else
|
||||
#define FLATBUFFERS_DELETE_FUNC(func) private: func
|
||||
#endif
|
||||
|
||||
#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \
|
||||
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)) || \
|
||||
defined(__clang__)
|
||||
#define FLATBUFFERS_DEFAULT_DECLARATION
|
||||
#endif
|
||||
|
||||
// Check if we can use template aliases
|
||||
// Not possible if Microsoft Compiler before 2012
|
||||
// Possible is the language feature __cpp_alias_templates is defined well
|
||||
// Or possible if the C++ std is C+11 or newer
|
||||
#if (defined(_MSC_VER) && _MSC_VER > 1700 /* MSVC2012 */) \
|
||||
|| (defined(__cpp_alias_templates) && __cpp_alias_templates >= 200704) \
|
||||
|| (defined(__cplusplus) && __cplusplus >= 201103L)
|
||||
#define FLATBUFFERS_TEMPLATES_ALIASES
|
||||
#endif
|
||||
|
||||
#ifndef FLATBUFFERS_HAS_STRING_VIEW
|
||||
// Only provide flatbuffers::string_view if __has_include can be used
|
||||
// to detect a header that provides an implementation
|
||||
#if defined(__has_include)
|
||||
// Check for std::string_view (in c++17)
|
||||
#if __has_include(<string_view>) && (__cplusplus >= 201606 || (defined(_HAS_CXX17) && _HAS_CXX17))
|
||||
#include <string_view>
|
||||
namespace flatbuffers {
|
||||
typedef std::string_view string_view;
|
||||
}
|
||||
#define FLATBUFFERS_HAS_STRING_VIEW 1
|
||||
// Check for std::experimental::string_view (in c++14, compiler-dependent)
|
||||
#elif __has_include(<experimental/string_view>) && (__cplusplus >= 201411)
|
||||
#include <experimental/string_view>
|
||||
namespace flatbuffers {
|
||||
typedef std::experimental::string_view string_view;
|
||||
}
|
||||
#define FLATBUFFERS_HAS_STRING_VIEW 1
|
||||
// Check for absl::string_view
|
||||
#elif __has_include("absl/strings/string_view.h") && \
|
||||
__has_include("absl/base/config.h") && \
|
||||
(__cplusplus >= 201411)
|
||||
#include "absl/base/config.h"
|
||||
#if !defined(ABSL_USES_STD_STRING_VIEW)
|
||||
#include "absl/strings/string_view.h"
|
||||
namespace flatbuffers {
|
||||
typedef absl::string_view string_view;
|
||||
}
|
||||
#define FLATBUFFERS_HAS_STRING_VIEW 1
|
||||
#endif
|
||||
#endif
|
||||
#endif // __has_include
|
||||
#endif // !FLATBUFFERS_HAS_STRING_VIEW
|
||||
|
||||
#ifndef FLATBUFFERS_GENERAL_HEAP_ALLOC_OK
|
||||
// Allow heap allocations to be used
|
||||
#define FLATBUFFERS_GENERAL_HEAP_ALLOC_OK 1
|
||||
#endif // !FLATBUFFERS_GENERAL_HEAP_ALLOC_OK
|
||||
|
||||
#ifndef FLATBUFFERS_HAS_NEW_STRTOD
|
||||
// Modern (C++11) strtod and strtof functions are available for use.
|
||||
// 1) nan/inf strings as argument of strtod;
|
||||
// 2) hex-float as argument of strtod/strtof.
|
||||
#if (defined(_MSC_VER) && _MSC_VER >= 1900) || \
|
||||
(defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)) || \
|
||||
(defined(__clang__))
|
||||
#define FLATBUFFERS_HAS_NEW_STRTOD 1
|
||||
#endif
|
||||
#endif // !FLATBUFFERS_HAS_NEW_STRTOD
|
||||
|
||||
#ifndef FLATBUFFERS_LOCALE_INDEPENDENT
|
||||
// Enable locale independent functions {strtof_l, strtod_l,strtoll_l,
|
||||
// strtoull_l}.
|
||||
#if (defined(_MSC_VER) && _MSC_VER >= 1800) || \
|
||||
(defined(__ANDROID_API__) && __ANDROID_API__>= 21) || \
|
||||
(defined(_XOPEN_VERSION) && (_XOPEN_VERSION >= 700)) && \
|
||||
(!defined(__Fuchsia__) && !defined(__ANDROID_API__))
|
||||
#define FLATBUFFERS_LOCALE_INDEPENDENT 1
|
||||
#else
|
||||
#define FLATBUFFERS_LOCALE_INDEPENDENT 0
|
||||
#endif
|
||||
#endif // !FLATBUFFERS_LOCALE_INDEPENDENT
|
||||
|
||||
// Suppress Undefined Behavior Sanitizer (recoverable only). Usage:
|
||||
// - __suppress_ubsan__("undefined")
|
||||
// - __suppress_ubsan__("signed-integer-overflow")
|
||||
#if defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >=7))
|
||||
#define __suppress_ubsan__(type) __attribute__((no_sanitize(type)))
|
||||
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)
|
||||
#define __suppress_ubsan__(type) __attribute__((no_sanitize_undefined))
|
||||
#else
|
||||
#define __suppress_ubsan__(type)
|
||||
#endif
|
||||
|
||||
// This is constexpr function used for checking compile-time constants.
|
||||
// Avoid `#pragma warning(disable: 4127) // C4127: expression is constant`.
|
||||
template<typename T> FLATBUFFERS_CONSTEXPR inline bool IsConstTrue(T t) {
|
||||
return !!t;
|
||||
}
|
||||
|
||||
// Enable C++ attribute [[]] if std:c++17 or higher.
|
||||
#if ((__cplusplus >= 201703L) \
|
||||
|| (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L)))
|
||||
// All attributes unknown to an implementation are ignored without causing an error.
|
||||
#define FLATBUFFERS_ATTRIBUTE(attr) attr
|
||||
|
||||
#define FLATBUFFERS_FALLTHROUGH() [[fallthrough]]
|
||||
#else
|
||||
#define FLATBUFFERS_ATTRIBUTE(attr)
|
||||
|
||||
#if FLATBUFFERS_CLANG >= 30800
|
||||
#define FLATBUFFERS_FALLTHROUGH() [[clang::fallthrough]]
|
||||
#elif FLATBUFFERS_GCC >= 70300
|
||||
#define FLATBUFFERS_FALLTHROUGH() [[gnu::fallthrough]]
|
||||
#else
|
||||
#define FLATBUFFERS_FALLTHROUGH()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/// @endcond
|
||||
|
||||
/// @file
|
||||
namespace flatbuffers {
|
||||
|
||||
/// @cond FLATBUFFERS_INTERNAL
|
||||
// Our default offset / size type, 32bit on purpose on 64bit systems.
|
||||
// Also, using a consistent offset type maintains compatibility of serialized
|
||||
// offset values between 32bit and 64bit systems.
|
||||
typedef uint32_t uoffset_t;
|
||||
typedef uint64_t uoffset64_t;
|
||||
|
||||
// Signed offsets for references that can go in both directions.
|
||||
typedef int32_t soffset_t;
|
||||
typedef int64_t soffset64_t;
|
||||
|
||||
// Offset/index used in v-tables, can be changed to uint8_t in
|
||||
// format forks to save a bit of space if desired.
|
||||
typedef uint16_t voffset_t;
|
||||
|
||||
typedef uintmax_t largest_scalar_t;
|
||||
|
||||
// In 32bits, this evaluates to 2GB - 1
|
||||
#define FLATBUFFERS_MAX_BUFFER_SIZE std::numeric_limits<::flatbuffers::soffset_t>::max()
|
||||
#define FLATBUFFERS_MAX_64_BUFFER_SIZE std::numeric_limits<::flatbuffers::soffset64_t>::max()
|
||||
|
||||
// The minimum size buffer that can be a valid flatbuffer.
|
||||
// Includes the offset to the root table (uoffset_t), the offset to the vtable
|
||||
// of the root table (soffset_t), the size of the vtable (uint16_t), and the
|
||||
// size of the referring table (uint16_t).
|
||||
#define FLATBUFFERS_MIN_BUFFER_SIZE sizeof(uoffset_t) + sizeof(soffset_t) + \
|
||||
sizeof(uint16_t) + sizeof(uint16_t)
|
||||
|
||||
// We support aligning the contents of buffers up to this size.
|
||||
#ifndef FLATBUFFERS_MAX_ALIGNMENT
|
||||
#define FLATBUFFERS_MAX_ALIGNMENT 32
|
||||
#endif
|
||||
|
||||
/// @brief The length of a FlatBuffer file header.
|
||||
static const size_t kFileIdentifierLength = 4;
|
||||
|
||||
inline bool VerifyAlignmentRequirements(size_t align, size_t min_align = 1) {
|
||||
return (min_align <= align) && (align <= (FLATBUFFERS_MAX_ALIGNMENT)) &&
|
||||
(align & (align - 1)) == 0; // must be power of 2
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable: 4351) // C4351: new behavior: elements of array ... will be default initialized
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4127) // C4127: conditional expression is constant
|
||||
#endif
|
||||
|
||||
template<typename T> T EndianSwap(T t) {
|
||||
#if defined(_MSC_VER)
|
||||
#define FLATBUFFERS_BYTESWAP16 _byteswap_ushort
|
||||
#define FLATBUFFERS_BYTESWAP32 _byteswap_ulong
|
||||
#define FLATBUFFERS_BYTESWAP64 _byteswap_uint64
|
||||
#elif defined(__ICCARM__)
|
||||
#define FLATBUFFERS_BYTESWAP16 __REV16
|
||||
#define FLATBUFFERS_BYTESWAP32 __REV
|
||||
#define FLATBUFFERS_BYTESWAP64(x) \
|
||||
((__REV(static_cast<uint32_t>(x >> 32U))) | (static_cast<uint64_t>(__REV(static_cast<uint32_t>(x)))) << 32U)
|
||||
#else
|
||||
#if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__)
|
||||
// __builtin_bswap16 was missing prior to GCC 4.8.
|
||||
#define FLATBUFFERS_BYTESWAP16(x) \
|
||||
static_cast<uint16_t>(__builtin_bswap32(static_cast<uint32_t>(x) << 16))
|
||||
#else
|
||||
#define FLATBUFFERS_BYTESWAP16 __builtin_bswap16
|
||||
#endif
|
||||
#define FLATBUFFERS_BYTESWAP32 __builtin_bswap32
|
||||
#define FLATBUFFERS_BYTESWAP64 __builtin_bswap64
|
||||
#endif
|
||||
if (sizeof(T) == 1) { // Compile-time if-then's.
|
||||
return t;
|
||||
} else if (sizeof(T) == 2) {
|
||||
union { T t; uint16_t i; } u = { t };
|
||||
u.i = FLATBUFFERS_BYTESWAP16(u.i);
|
||||
return u.t;
|
||||
} else if (sizeof(T) == 4) {
|
||||
union { T t; uint32_t i; } u = { t };
|
||||
u.i = FLATBUFFERS_BYTESWAP32(u.i);
|
||||
return u.t;
|
||||
} else if (sizeof(T) == 8) {
|
||||
union { T t; uint64_t i; } u = { t };
|
||||
u.i = FLATBUFFERS_BYTESWAP64(u.i);
|
||||
return u.t;
|
||||
} else {
|
||||
FLATBUFFERS_ASSERT(0);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
template<typename T> T EndianScalar(T t) {
|
||||
#if FLATBUFFERS_LITTLEENDIAN
|
||||
return t;
|
||||
#else
|
||||
return EndianSwap(t);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
// UBSAN: C++ aliasing type rules, see std::bit_cast<> for details.
|
||||
__suppress_ubsan__("alignment")
|
||||
T ReadScalar(const void *p) {
|
||||
return EndianScalar(*reinterpret_cast<const T *>(p));
|
||||
}
|
||||
|
||||
// See https://github.com/google/flatbuffers/issues/5950
|
||||
|
||||
#if (FLATBUFFERS_GCC >= 100000) && (FLATBUFFERS_GCC < 110000)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-overflow"
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
// UBSAN: C++ aliasing type rules, see std::bit_cast<> for details.
|
||||
__suppress_ubsan__("alignment")
|
||||
void WriteScalar(void *p, T t) {
|
||||
*reinterpret_cast<T *>(p) = EndianScalar(t);
|
||||
}
|
||||
|
||||
template<typename T> struct Offset;
|
||||
template<typename T> __suppress_ubsan__("alignment") void WriteScalar(void *p, Offset<T> t) {
|
||||
*reinterpret_cast<uoffset_t *>(p) = EndianScalar(t.o);
|
||||
}
|
||||
|
||||
#if (FLATBUFFERS_GCC >= 100000) && (FLATBUFFERS_GCC < 110000)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
// Computes how many bytes you'd have to pad to be able to write an
|
||||
// "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in
|
||||
// memory).
|
||||
__suppress_ubsan__("unsigned-integer-overflow")
|
||||
inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) {
|
||||
return ((~buf_size) + 1) & (scalar_size - 1);
|
||||
}
|
||||
|
||||
// Generic 'operator==' with conditional specialisations.
|
||||
// T e - new value of a scalar field.
|
||||
// T def - default of scalar (is known at compile-time).
|
||||
template<typename T> inline bool IsTheSameAs(T e, T def) { return e == def; }
|
||||
|
||||
#if defined(FLATBUFFERS_NAN_DEFAULTS) && \
|
||||
defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
|
||||
// Like `operator==(e, def)` with weak NaN if T=(float|double).
|
||||
template<typename T> inline bool IsFloatTheSameAs(T e, T def) {
|
||||
return (e == def) || ((def != def) && (e != e));
|
||||
}
|
||||
template<> inline bool IsTheSameAs<float>(float e, float def) {
|
||||
return IsFloatTheSameAs(e, def);
|
||||
}
|
||||
template<> inline bool IsTheSameAs<double>(double e, double def) {
|
||||
return IsFloatTheSameAs(e, def);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check 'v' is out of closed range [low; high].
|
||||
// Workaround for GCC warning [-Werror=type-limits]:
|
||||
// comparison is always true due to limited range of data type.
|
||||
template<typename T>
|
||||
inline bool IsOutRange(const T &v, const T &low, const T &high) {
|
||||
return (v < low) || (high < v);
|
||||
}
|
||||
|
||||
// Check 'v' is in closed range [low; high].
|
||||
template<typename T>
|
||||
inline bool IsInRange(const T &v, const T &low, const T &high) {
|
||||
return !IsOutRange(v, low, high);
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
#endif // FLATBUFFERS_BASE_H_
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLATBUFFERS_BUFFER_H_
|
||||
#define FLATBUFFERS_BUFFER_H_
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "flatbuffers/base.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
// Wrapper for uoffset_t to allow safe template specialization.
|
||||
// Value is allowed to be 0 to indicate a null object (see e.g. AddOffset).
|
||||
template<typename T = void> struct Offset {
|
||||
// The type of offset to use.
|
||||
typedef uoffset_t offset_type;
|
||||
|
||||
offset_type o;
|
||||
Offset() : o(0) {}
|
||||
Offset(const offset_type _o) : o(_o) {}
|
||||
Offset<> Union() const { return o; }
|
||||
bool IsNull() const { return !o; }
|
||||
};
|
||||
|
||||
// Wrapper for uoffset64_t Offsets.
|
||||
template<typename T = void> struct Offset64 {
|
||||
// The type of offset to use.
|
||||
typedef uoffset64_t offset_type;
|
||||
|
||||
offset_type o;
|
||||
Offset64() : o(0) {}
|
||||
Offset64(const offset_type offset) : o(offset) {}
|
||||
Offset64<> Union() const { return o; }
|
||||
bool IsNull() const { return !o; }
|
||||
};
|
||||
|
||||
// Litmus check for ensuring the Offsets are the expected size.
|
||||
static_assert(sizeof(Offset<>) == 4, "Offset has wrong size");
|
||||
static_assert(sizeof(Offset64<>) == 8, "Offset64 has wrong size");
|
||||
|
||||
inline void EndianCheck() {
|
||||
int endiantest = 1;
|
||||
// If this fails, see FLATBUFFERS_LITTLEENDIAN above.
|
||||
FLATBUFFERS_ASSERT(*reinterpret_cast<char *>(&endiantest) ==
|
||||
FLATBUFFERS_LITTLEENDIAN);
|
||||
(void)endiantest;
|
||||
}
|
||||
|
||||
template<typename T> FLATBUFFERS_CONSTEXPR size_t AlignOf() {
|
||||
// clang-format off
|
||||
#ifdef _MSC_VER
|
||||
return __alignof(T);
|
||||
#else
|
||||
#ifndef alignof
|
||||
return __alignof__(T);
|
||||
#else
|
||||
return alignof(T);
|
||||
#endif
|
||||
#endif
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
// Lexicographically compare two strings (possibly containing nulls), and
|
||||
// return true if the first is less than the second.
|
||||
static inline bool StringLessThan(const char *a_data, uoffset_t a_size,
|
||||
const char *b_data, uoffset_t b_size) {
|
||||
const auto cmp = memcmp(a_data, b_data, (std::min)(a_size, b_size));
|
||||
return cmp == 0 ? a_size < b_size : cmp < 0;
|
||||
}
|
||||
|
||||
// When we read serialized data from memory, in the case of most scalars,
|
||||
// we want to just read T, but in the case of Offset, we want to actually
|
||||
// perform the indirection and return a pointer.
|
||||
// The template specialization below does just that.
|
||||
// It is wrapped in a struct since function templates can't overload on the
|
||||
// return type like this.
|
||||
// The typedef is for the convenience of callers of this function
|
||||
// (avoiding the need for a trailing return decltype)
|
||||
template<typename T> struct IndirectHelper {
|
||||
typedef T return_type;
|
||||
typedef T mutable_return_type;
|
||||
static const size_t element_stride = sizeof(T);
|
||||
|
||||
static return_type Read(const uint8_t *p, const size_t i) {
|
||||
return EndianScalar((reinterpret_cast<const T *>(p))[i]);
|
||||
}
|
||||
static mutable_return_type Read(uint8_t *p, const size_t i) {
|
||||
return reinterpret_cast<mutable_return_type>(
|
||||
Read(const_cast<const uint8_t *>(p), i));
|
||||
}
|
||||
};
|
||||
|
||||
// For vector of Offsets.
|
||||
template<typename T, template<typename> class OffsetT>
|
||||
struct IndirectHelper<OffsetT<T>> {
|
||||
typedef const T *return_type;
|
||||
typedef T *mutable_return_type;
|
||||
typedef typename OffsetT<T>::offset_type offset_type;
|
||||
static const offset_type element_stride = sizeof(offset_type);
|
||||
|
||||
static return_type Read(const uint8_t *const p, const offset_type i) {
|
||||
// Offsets are relative to themselves, so first update the pointer to
|
||||
// point to the offset location.
|
||||
const uint8_t *const offset_location = p + i * element_stride;
|
||||
|
||||
// Then read the scalar value of the offset (which may be 32 or 64-bits) and
|
||||
// then determine the relative location from the offset location.
|
||||
return reinterpret_cast<return_type>(
|
||||
offset_location + ReadScalar<offset_type>(offset_location));
|
||||
}
|
||||
static mutable_return_type Read(uint8_t *const p, const offset_type i) {
|
||||
// Offsets are relative to themselves, so first update the pointer to
|
||||
// point to the offset location.
|
||||
uint8_t *const offset_location = p + i * element_stride;
|
||||
|
||||
// Then read the scalar value of the offset (which may be 32 or 64-bits) and
|
||||
// then determine the relative location from the offset location.
|
||||
return reinterpret_cast<mutable_return_type>(
|
||||
offset_location + ReadScalar<offset_type>(offset_location));
|
||||
}
|
||||
};
|
||||
|
||||
// For vector of structs.
|
||||
template<typename T> struct IndirectHelper<const T *> {
|
||||
typedef const T *return_type;
|
||||
typedef T *mutable_return_type;
|
||||
static const size_t element_stride = sizeof(T);
|
||||
|
||||
static return_type Read(const uint8_t *const p, const size_t i) {
|
||||
// Structs are stored inline, relative to the first struct pointer.
|
||||
return reinterpret_cast<return_type>(p + i * element_stride);
|
||||
}
|
||||
static mutable_return_type Read(uint8_t *const p, const size_t i) {
|
||||
// Structs are stored inline, relative to the first struct pointer.
|
||||
return reinterpret_cast<mutable_return_type>(p + i * element_stride);
|
||||
}
|
||||
};
|
||||
|
||||
/// @brief Get a pointer to the file_identifier section of the buffer.
|
||||
/// @return Returns a const char pointer to the start of the file_identifier
|
||||
/// characters in the buffer. The returned char * has length
|
||||
/// 'flatbuffers::FlatBufferBuilder::kFileIdentifierLength'.
|
||||
/// This function is UNDEFINED for FlatBuffers whose schema does not include
|
||||
/// a file_identifier (likely points at padding or the start of a the root
|
||||
/// vtable).
|
||||
inline const char *GetBufferIdentifier(const void *buf,
|
||||
bool size_prefixed = false) {
|
||||
return reinterpret_cast<const char *>(buf) +
|
||||
((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t));
|
||||
}
|
||||
|
||||
// Helper to see if the identifier in a buffer has the expected value.
|
||||
inline bool BufferHasIdentifier(const void *buf, const char *identifier,
|
||||
bool size_prefixed = false) {
|
||||
return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier,
|
||||
flatbuffers::kFileIdentifierLength) == 0;
|
||||
}
|
||||
|
||||
/// @cond FLATBUFFERS_INTERNAL
|
||||
// Helpers to get a typed pointer to the root object contained in the buffer.
|
||||
template<typename T> T *GetMutableRoot(void *buf) {
|
||||
if (!buf) return nullptr;
|
||||
EndianCheck();
|
||||
return reinterpret_cast<T *>(
|
||||
reinterpret_cast<uint8_t *>(buf) +
|
||||
EndianScalar(*reinterpret_cast<uoffset_t *>(buf)));
|
||||
}
|
||||
|
||||
template<typename T, typename SizeT = uoffset_t>
|
||||
T *GetMutableSizePrefixedRoot(void *buf) {
|
||||
return GetMutableRoot<T>(reinterpret_cast<uint8_t *>(buf) + sizeof(SizeT));
|
||||
}
|
||||
|
||||
template<typename T> const T *GetRoot(const void *buf) {
|
||||
return GetMutableRoot<T>(const_cast<void *>(buf));
|
||||
}
|
||||
|
||||
template<typename T, typename SizeT = uoffset_t>
|
||||
const T *GetSizePrefixedRoot(const void *buf) {
|
||||
return GetRoot<T>(reinterpret_cast<const uint8_t *>(buf) + sizeof(SizeT));
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_BUFFER_H_
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLATBUFFERS_BUFFER_REF_H_
|
||||
#define FLATBUFFERS_BUFFER_REF_H_
|
||||
|
||||
#include "flatbuffers/base.h"
|
||||
#include "flatbuffers/verifier.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
// Convenient way to bundle a buffer and its length, to pass it around
|
||||
// typed by its root.
|
||||
// A BufferRef does not own its buffer.
|
||||
struct BufferRefBase {}; // for std::is_base_of
|
||||
|
||||
template<typename T> struct BufferRef : BufferRefBase {
|
||||
BufferRef() : buf(nullptr), len(0), must_free(false) {}
|
||||
BufferRef(uint8_t *_buf, uoffset_t _len)
|
||||
: buf(_buf), len(_len), must_free(false) {}
|
||||
|
||||
~BufferRef() {
|
||||
if (must_free) free(buf);
|
||||
}
|
||||
|
||||
const T *GetRoot() const { return flatbuffers::GetRoot<T>(buf); }
|
||||
|
||||
bool Verify() {
|
||||
Verifier verifier(buf, len);
|
||||
return verifier.VerifyBuffer<T>(nullptr);
|
||||
}
|
||||
|
||||
uint8_t *buf;
|
||||
uoffset_t len;
|
||||
bool must_free;
|
||||
};
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_BUFFER_REF_H_
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLATBUFFERS_DEFAULT_ALLOCATOR_H_
|
||||
#define FLATBUFFERS_DEFAULT_ALLOCATOR_H_
|
||||
|
||||
#include "flatbuffers/allocator.h"
|
||||
#include "flatbuffers/base.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
// DefaultAllocator uses new/delete to allocate memory regions
|
||||
class DefaultAllocator : public Allocator {
|
||||
public:
|
||||
uint8_t *allocate(size_t size) FLATBUFFERS_OVERRIDE {
|
||||
return new uint8_t[size];
|
||||
}
|
||||
|
||||
void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE { delete[] p; }
|
||||
|
||||
static void dealloc(void *p, size_t) { delete[] static_cast<uint8_t *>(p); }
|
||||
};
|
||||
|
||||
// These functions allow for a null allocator to mean use the default allocator,
|
||||
// as used by DetachedBuffer and vector_downward below.
|
||||
// This is to avoid having a statically or dynamically allocated default
|
||||
// allocator, or having to move it between the classes that may own it.
|
||||
inline uint8_t *Allocate(Allocator *allocator, size_t size) {
|
||||
return allocator ? allocator->allocate(size)
|
||||
: DefaultAllocator().allocate(size);
|
||||
}
|
||||
|
||||
inline void Deallocate(Allocator *allocator, uint8_t *p, size_t size) {
|
||||
if (allocator)
|
||||
allocator->deallocate(p, size);
|
||||
else
|
||||
DefaultAllocator().deallocate(p, size);
|
||||
}
|
||||
|
||||
inline uint8_t *ReallocateDownward(Allocator *allocator, uint8_t *old_p,
|
||||
size_t old_size, size_t new_size,
|
||||
size_t in_use_back, size_t in_use_front) {
|
||||
return allocator ? allocator->reallocate_downward(old_p, old_size, new_size,
|
||||
in_use_back, in_use_front)
|
||||
: DefaultAllocator().reallocate_downward(
|
||||
old_p, old_size, new_size, in_use_back, in_use_front);
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_DEFAULT_ALLOCATOR_H_
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLATBUFFERS_DETACHED_BUFFER_H_
|
||||
#define FLATBUFFERS_DETACHED_BUFFER_H_
|
||||
|
||||
#include "flatbuffers/allocator.h"
|
||||
#include "flatbuffers/base.h"
|
||||
#include "flatbuffers/default_allocator.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
// DetachedBuffer is a finished flatbuffer memory region, detached from its
|
||||
// builder. The original memory region and allocator are also stored so that
|
||||
// the DetachedBuffer can manage the memory lifetime.
|
||||
class DetachedBuffer {
|
||||
public:
|
||||
DetachedBuffer()
|
||||
: allocator_(nullptr),
|
||||
own_allocator_(false),
|
||||
buf_(nullptr),
|
||||
reserved_(0),
|
||||
cur_(nullptr),
|
||||
size_(0) {}
|
||||
|
||||
DetachedBuffer(Allocator *allocator, bool own_allocator, uint8_t *buf,
|
||||
size_t reserved, uint8_t *cur, size_t sz)
|
||||
: allocator_(allocator),
|
||||
own_allocator_(own_allocator),
|
||||
buf_(buf),
|
||||
reserved_(reserved),
|
||||
cur_(cur),
|
||||
size_(sz) {}
|
||||
|
||||
DetachedBuffer(DetachedBuffer &&other) noexcept
|
||||
: allocator_(other.allocator_),
|
||||
own_allocator_(other.own_allocator_),
|
||||
buf_(other.buf_),
|
||||
reserved_(other.reserved_),
|
||||
cur_(other.cur_),
|
||||
size_(other.size_) {
|
||||
other.reset();
|
||||
}
|
||||
|
||||
DetachedBuffer &operator=(DetachedBuffer &&other) noexcept {
|
||||
if (this == &other) return *this;
|
||||
|
||||
destroy();
|
||||
|
||||
allocator_ = other.allocator_;
|
||||
own_allocator_ = other.own_allocator_;
|
||||
buf_ = other.buf_;
|
||||
reserved_ = other.reserved_;
|
||||
cur_ = other.cur_;
|
||||
size_ = other.size_;
|
||||
|
||||
other.reset();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
~DetachedBuffer() { destroy(); }
|
||||
|
||||
const uint8_t *data() const { return cur_; }
|
||||
|
||||
uint8_t *data() { return cur_; }
|
||||
|
||||
size_t size() const { return size_; }
|
||||
|
||||
// These may change access mode, leave these at end of public section
|
||||
FLATBUFFERS_DELETE_FUNC(DetachedBuffer(const DetachedBuffer &other));
|
||||
FLATBUFFERS_DELETE_FUNC(
|
||||
DetachedBuffer &operator=(const DetachedBuffer &other));
|
||||
|
||||
protected:
|
||||
Allocator *allocator_;
|
||||
bool own_allocator_;
|
||||
uint8_t *buf_;
|
||||
size_t reserved_;
|
||||
uint8_t *cur_;
|
||||
size_t size_;
|
||||
|
||||
inline void destroy() {
|
||||
if (buf_) Deallocate(allocator_, buf_, reserved_);
|
||||
if (own_allocator_ && allocator_) { delete allocator_; }
|
||||
reset();
|
||||
}
|
||||
|
||||
inline void reset() {
|
||||
allocator_ = nullptr;
|
||||
own_allocator_ = false;
|
||||
buf_ = nullptr;
|
||||
reserved_ = 0;
|
||||
cur_ = nullptr;
|
||||
size_ = 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_DETACHED_BUFFER_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLATBUFFERS_H_
|
||||
#define FLATBUFFERS_H_
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
// TODO: These includes are for mitigating the pains of users editing their
|
||||
// source because they relied on flatbuffers.h to include everything for them.
|
||||
#include "flatbuffers/array.h"
|
||||
#include "flatbuffers/base.h"
|
||||
#include "flatbuffers/buffer.h"
|
||||
#include "flatbuffers/buffer_ref.h"
|
||||
#include "flatbuffers/detached_buffer.h"
|
||||
#include "flatbuffers/flatbuffer_builder.h"
|
||||
#include "flatbuffers/stl_emulation.h"
|
||||
#include "flatbuffers/string.h"
|
||||
#include "flatbuffers/struct.h"
|
||||
#include "flatbuffers/table.h"
|
||||
#include "flatbuffers/vector.h"
|
||||
#include "flatbuffers/vector_downward.h"
|
||||
#include "flatbuffers/verifier.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
/// @brief This can compute the start of a FlatBuffer from a root pointer, i.e.
|
||||
/// it is the opposite transformation of GetRoot().
|
||||
/// This may be useful if you want to pass on a root and have the recipient
|
||||
/// delete the buffer afterwards.
|
||||
inline const uint8_t *GetBufferStartFromRootPointer(const void *root) {
|
||||
auto table = reinterpret_cast<const Table *>(root);
|
||||
auto vtable = table->GetVTable();
|
||||
// Either the vtable is before the root or after the root.
|
||||
auto start = (std::min)(vtable, reinterpret_cast<const uint8_t *>(root));
|
||||
// Align to at least sizeof(uoffset_t).
|
||||
start = reinterpret_cast<const uint8_t *>(reinterpret_cast<uintptr_t>(start) &
|
||||
~(sizeof(uoffset_t) - 1));
|
||||
// Additionally, there may be a file_identifier in the buffer, and the root
|
||||
// offset. The buffer may have been aligned to any size between
|
||||
// sizeof(uoffset_t) and FLATBUFFERS_MAX_ALIGNMENT (see "force_align").
|
||||
// Sadly, the exact alignment is only known when constructing the buffer,
|
||||
// since it depends on the presence of values with said alignment properties.
|
||||
// So instead, we simply look at the next uoffset_t values (root,
|
||||
// file_identifier, and alignment padding) to see which points to the root.
|
||||
// None of the other values can "impersonate" the root since they will either
|
||||
// be 0 or four ASCII characters.
|
||||
static_assert(flatbuffers::kFileIdentifierLength == sizeof(uoffset_t),
|
||||
"file_identifier is assumed to be the same size as uoffset_t");
|
||||
for (auto possible_roots = FLATBUFFERS_MAX_ALIGNMENT / sizeof(uoffset_t) + 1;
|
||||
possible_roots; possible_roots--) {
|
||||
start -= sizeof(uoffset_t);
|
||||
if (ReadScalar<uoffset_t>(start) + start ==
|
||||
reinterpret_cast<const uint8_t *>(root))
|
||||
return start;
|
||||
}
|
||||
// We didn't find the root, either the "root" passed isn't really a root,
|
||||
// or the buffer is corrupt.
|
||||
// Assert, because calling this function with bad data may cause reads
|
||||
// outside of buffer boundaries.
|
||||
FLATBUFFERS_ASSERT(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// @brief This return the prefixed size of a FlatBuffer.
|
||||
template<typename SizeT = uoffset_t>
|
||||
inline SizeT GetPrefixedSize(const uint8_t *buf) {
|
||||
return ReadScalar<SizeT>(buf);
|
||||
}
|
||||
|
||||
// Base class for native objects (FlatBuffer data de-serialized into native
|
||||
// C++ data structures).
|
||||
// Contains no functionality, purely documentative.
|
||||
struct NativeTable {};
|
||||
|
||||
/// @brief Function types to be used with resolving hashes into objects and
|
||||
/// back again. The resolver gets a pointer to a field inside an object API
|
||||
/// object that is of the type specified in the schema using the attribute
|
||||
/// `cpp_type` (it is thus important whatever you write to this address
|
||||
/// matches that type). The value of this field is initially null, so you
|
||||
/// may choose to implement a delayed binding lookup using this function
|
||||
/// if you wish. The resolver does the opposite lookup, for when the object
|
||||
/// is being serialized again.
|
||||
typedef uint64_t hash_value_t;
|
||||
typedef std::function<void(void **pointer_adr, hash_value_t hash)>
|
||||
resolver_function_t;
|
||||
typedef std::function<hash_value_t(void *pointer)> rehasher_function_t;
|
||||
|
||||
// Helper function to test if a field is present, using any of the field
|
||||
// enums in the generated code.
|
||||
// `table` must be a generated table type. Since this is a template parameter,
|
||||
// this is not typechecked to be a subclass of Table, so beware!
|
||||
// Note: this function will return false for fields equal to the default
|
||||
// value, since they're not stored in the buffer (unless force_defaults was
|
||||
// used).
|
||||
template<typename T>
|
||||
bool IsFieldPresent(const T *table, typename T::FlatBuffersVTableOffset field) {
|
||||
// Cast, since Table is a private baseclass of any table types.
|
||||
return reinterpret_cast<const Table *>(table)->CheckField(
|
||||
static_cast<voffset_t>(field));
|
||||
}
|
||||
|
||||
// Utility function for reverse lookups on the EnumNames*() functions
|
||||
// (in the generated C++ code)
|
||||
// names must be NULL terminated.
|
||||
inline int LookupEnum(const char **names, const char *name) {
|
||||
for (const char **p = names; *p; p++)
|
||||
if (!strcmp(*p, name)) return static_cast<int>(p - names);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// These macros allow us to layout a struct with a guarantee that they'll end
|
||||
// up looking the same on different compilers and platforms.
|
||||
// It does this by disallowing the compiler to do any padding, and then
|
||||
// does padding itself by inserting extra padding fields that make every
|
||||
// element aligned to its own size.
|
||||
// Additionally, it manually sets the alignment of the struct as a whole,
|
||||
// which is typically its largest element, or a custom size set in the schema
|
||||
// by the force_align attribute.
|
||||
// These are used in the generated code only.
|
||||
|
||||
// clang-format off
|
||||
#if defined(_MSC_VER)
|
||||
#define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \
|
||||
__pragma(pack(1)) \
|
||||
struct __declspec(align(alignment))
|
||||
#define FLATBUFFERS_STRUCT_END(name, size) \
|
||||
__pragma(pack()) \
|
||||
static_assert(sizeof(name) == size, "compiler breaks packing rules")
|
||||
#elif defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
|
||||
#define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \
|
||||
_Pragma("pack(1)") \
|
||||
struct __attribute__((aligned(alignment)))
|
||||
#define FLATBUFFERS_STRUCT_END(name, size) \
|
||||
_Pragma("pack()") \
|
||||
static_assert(sizeof(name) == size, "compiler breaks packing rules")
|
||||
#else
|
||||
#error Unknown compiler, please define structure alignment macros
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
// Minimal reflection via code generation.
|
||||
// Besides full-fat reflection (see reflection.h) and parsing/printing by
|
||||
// loading schemas (see idl.h), we can also have code generation for minimal
|
||||
// reflection data which allows pretty-printing and other uses without needing
|
||||
// a schema or a parser.
|
||||
// Generate code with --reflect-types (types only) or --reflect-names (names
|
||||
// also) to enable.
|
||||
// See minireflect.h for utilities using this functionality.
|
||||
|
||||
// These types are organized slightly differently as the ones in idl.h.
|
||||
enum SequenceType { ST_TABLE, ST_STRUCT, ST_UNION, ST_ENUM };
|
||||
|
||||
// Scalars have the same order as in idl.h
|
||||
// clang-format off
|
||||
#define FLATBUFFERS_GEN_ELEMENTARY_TYPES(ET) \
|
||||
ET(ET_UTYPE) \
|
||||
ET(ET_BOOL) \
|
||||
ET(ET_CHAR) \
|
||||
ET(ET_UCHAR) \
|
||||
ET(ET_SHORT) \
|
||||
ET(ET_USHORT) \
|
||||
ET(ET_INT) \
|
||||
ET(ET_UINT) \
|
||||
ET(ET_LONG) \
|
||||
ET(ET_ULONG) \
|
||||
ET(ET_FLOAT) \
|
||||
ET(ET_DOUBLE) \
|
||||
ET(ET_STRING) \
|
||||
ET(ET_SEQUENCE) // See SequenceType.
|
||||
|
||||
enum ElementaryType {
|
||||
#define FLATBUFFERS_ET(E) E,
|
||||
FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET)
|
||||
#undef FLATBUFFERS_ET
|
||||
};
|
||||
|
||||
inline const char * const *ElementaryTypeNames() {
|
||||
static const char * const names[] = {
|
||||
#define FLATBUFFERS_ET(E) #E,
|
||||
FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET)
|
||||
#undef FLATBUFFERS_ET
|
||||
};
|
||||
return names;
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
// Basic type info cost just 16bits per field!
|
||||
// We're explicitly defining the signedness since the signedness of integer
|
||||
// bitfields is otherwise implementation-defined and causes warnings on older
|
||||
// GCC compilers.
|
||||
struct TypeCode {
|
||||
// ElementaryType
|
||||
unsigned short base_type : 4;
|
||||
// Either vector (in table) or array (in struct)
|
||||
unsigned short is_repeating : 1;
|
||||
// Index into type_refs below, or -1 for none.
|
||||
signed short sequence_ref : 11;
|
||||
};
|
||||
|
||||
static_assert(sizeof(TypeCode) == 2, "TypeCode");
|
||||
|
||||
struct TypeTable;
|
||||
|
||||
// Signature of the static method present in each type.
|
||||
typedef const TypeTable *(*TypeFunction)();
|
||||
|
||||
struct TypeTable {
|
||||
SequenceType st;
|
||||
size_t num_elems; // of type_codes, values, names (but not type_refs).
|
||||
const TypeCode *type_codes; // num_elems count
|
||||
const TypeFunction *type_refs; // less than num_elems entries (see TypeCode).
|
||||
const int16_t *array_sizes; // less than num_elems entries (see TypeCode).
|
||||
const int64_t *values; // Only set for non-consecutive enum/union or structs.
|
||||
const char *const *names; // Only set if compiled with --reflect-names.
|
||||
};
|
||||
|
||||
// String which identifies the current version of FlatBuffers.
|
||||
inline const char *flatbuffers_version_string() {
|
||||
return "FlatBuffers " FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "."
|
||||
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "."
|
||||
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
#define FLATBUFFERS_DEFINE_BITMASK_OPERATORS(E, T)\
|
||||
inline E operator | (E lhs, E rhs){\
|
||||
return E(T(lhs) | T(rhs));\
|
||||
}\
|
||||
inline E operator & (E lhs, E rhs){\
|
||||
return E(T(lhs) & T(rhs));\
|
||||
}\
|
||||
inline E operator ^ (E lhs, E rhs){\
|
||||
return E(T(lhs) ^ T(rhs));\
|
||||
}\
|
||||
inline E operator ~ (E lhs){\
|
||||
return E(~T(lhs));\
|
||||
}\
|
||||
inline E operator |= (E &lhs, E rhs){\
|
||||
lhs = lhs | rhs;\
|
||||
return lhs;\
|
||||
}\
|
||||
inline E operator &= (E &lhs, E rhs){\
|
||||
lhs = lhs & rhs;\
|
||||
return lhs;\
|
||||
}\
|
||||
inline E operator ^= (E &lhs, E rhs){\
|
||||
lhs = lhs ^ rhs;\
|
||||
return lhs;\
|
||||
}\
|
||||
inline bool operator !(E rhs) \
|
||||
{\
|
||||
return !bool(T(rhs)); \
|
||||
}
|
||||
/// @endcond
|
||||
} // namespace flatbuffers
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif // FLATBUFFERS_H_
|
||||
@@ -0,0 +1,513 @@
|
||||
/*
|
||||
* Copyright 2017 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLATBUFFERS_STL_EMULATION_H_
|
||||
#define FLATBUFFERS_STL_EMULATION_H_
|
||||
|
||||
// clang-format off
|
||||
#include "flatbuffers/base.h"
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <limits>
|
||||
|
||||
#ifndef FLATBUFFERS_USE_STD_OPTIONAL
|
||||
// Detect C++17 compatible compiler.
|
||||
// __cplusplus >= 201703L - a compiler has support of 'static inline' variables.
|
||||
#if (defined(__cplusplus) && __cplusplus >= 201703L) \
|
||||
|| (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
|
||||
#define FLATBUFFERS_USE_STD_OPTIONAL 1
|
||||
#else
|
||||
#define FLATBUFFERS_USE_STD_OPTIONAL 0
|
||||
#endif // (defined(__cplusplus) && __cplusplus >= 201703L) ...
|
||||
#endif // FLATBUFFERS_USE_STD_OPTIONAL
|
||||
|
||||
#if FLATBUFFERS_USE_STD_OPTIONAL
|
||||
#include <optional>
|
||||
#endif
|
||||
|
||||
#ifndef FLATBUFFERS_USE_STD_SPAN
|
||||
// Testing __cpp_lib_span requires including either <version> or <span>,
|
||||
// both of which were added in C++20.
|
||||
// See: https://en.cppreference.com/w/cpp/utility/feature_test
|
||||
#if defined(__cplusplus) && __cplusplus >= 202002L
|
||||
#define FLATBUFFERS_USE_STD_SPAN 1
|
||||
#endif
|
||||
#endif // FLATBUFFERS_USE_STD_SPAN
|
||||
|
||||
#if defined(FLATBUFFERS_USE_STD_SPAN)
|
||||
#include <array>
|
||||
#include <span>
|
||||
#else
|
||||
// Disable non-trivial ctors if FLATBUFFERS_SPAN_MINIMAL defined.
|
||||
#if !defined(FLATBUFFERS_TEMPLATES_ALIASES)
|
||||
#define FLATBUFFERS_SPAN_MINIMAL
|
||||
#else
|
||||
// Enable implicit construction of a span<T,N> from a std::array<T,N>.
|
||||
#include <array>
|
||||
#endif
|
||||
#endif // defined(FLATBUFFERS_USE_STD_SPAN)
|
||||
|
||||
// This header provides backwards compatibility for older versions of the STL.
|
||||
namespace flatbuffers {
|
||||
|
||||
#if defined(FLATBUFFERS_TEMPLATES_ALIASES)
|
||||
template <typename T>
|
||||
using numeric_limits = std::numeric_limits<T>;
|
||||
#else
|
||||
template <typename T> class numeric_limits :
|
||||
public std::numeric_limits<T> {};
|
||||
#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
|
||||
|
||||
#if defined(FLATBUFFERS_TEMPLATES_ALIASES)
|
||||
template <typename T> using is_scalar = std::is_scalar<T>;
|
||||
template <typename T, typename U> using is_same = std::is_same<T,U>;
|
||||
template <typename T> using is_floating_point = std::is_floating_point<T>;
|
||||
template <typename T> using is_unsigned = std::is_unsigned<T>;
|
||||
template <typename T> using is_enum = std::is_enum<T>;
|
||||
template <typename T> using make_unsigned = std::make_unsigned<T>;
|
||||
template<bool B, class T, class F>
|
||||
using conditional = std::conditional<B, T, F>;
|
||||
template<class T, T v>
|
||||
using integral_constant = std::integral_constant<T, v>;
|
||||
template <bool B>
|
||||
using bool_constant = integral_constant<bool, B>;
|
||||
using true_type = std::true_type;
|
||||
using false_type = std::false_type;
|
||||
#else
|
||||
// MSVC 2010 doesn't support C++11 aliases.
|
||||
template <typename T> struct is_scalar : public std::is_scalar<T> {};
|
||||
template <typename T, typename U> struct is_same : public std::is_same<T,U> {};
|
||||
template <typename T> struct is_floating_point :
|
||||
public std::is_floating_point<T> {};
|
||||
template <typename T> struct is_unsigned : public std::is_unsigned<T> {};
|
||||
template <typename T> struct is_enum : public std::is_enum<T> {};
|
||||
template <typename T> struct make_unsigned : public std::make_unsigned<T> {};
|
||||
template<bool B, class T, class F>
|
||||
struct conditional : public std::conditional<B, T, F> {};
|
||||
template<class T, T v>
|
||||
struct integral_constant : public std::integral_constant<T, v> {};
|
||||
template <bool B>
|
||||
struct bool_constant : public integral_constant<bool, B> {};
|
||||
typedef bool_constant<true> true_type;
|
||||
typedef bool_constant<false> false_type;
|
||||
#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
|
||||
|
||||
#if defined(FLATBUFFERS_TEMPLATES_ALIASES)
|
||||
template <class T> using unique_ptr = std::unique_ptr<T>;
|
||||
#else
|
||||
// MSVC 2010 doesn't support C++11 aliases.
|
||||
// We're manually "aliasing" the class here as we want to bring unique_ptr
|
||||
// into the flatbuffers namespace. We have unique_ptr in the flatbuffers
|
||||
// namespace we have a completely independent implementation (see below)
|
||||
// for C++98 STL implementations.
|
||||
template <class T> class unique_ptr : public std::unique_ptr<T> {
|
||||
public:
|
||||
unique_ptr() {}
|
||||
explicit unique_ptr(T* p) : std::unique_ptr<T>(p) {}
|
||||
unique_ptr(std::unique_ptr<T>&& u) { *this = std::move(u); }
|
||||
unique_ptr(unique_ptr&& u) { *this = std::move(u); }
|
||||
unique_ptr& operator=(std::unique_ptr<T>&& u) {
|
||||
std::unique_ptr<T>::reset(u.release());
|
||||
return *this;
|
||||
}
|
||||
unique_ptr& operator=(unique_ptr&& u) {
|
||||
std::unique_ptr<T>::reset(u.release());
|
||||
return *this;
|
||||
}
|
||||
unique_ptr& operator=(T* p) {
|
||||
return std::unique_ptr<T>::operator=(p);
|
||||
}
|
||||
};
|
||||
#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
|
||||
|
||||
#if FLATBUFFERS_USE_STD_OPTIONAL
|
||||
template<class T>
|
||||
using Optional = std::optional<T>;
|
||||
using nullopt_t = std::nullopt_t;
|
||||
inline constexpr nullopt_t nullopt = std::nullopt;
|
||||
|
||||
#else
|
||||
// Limited implementation of Optional<T> type for a scalar T.
|
||||
// This implementation limited by trivial types compatible with
|
||||
// std::is_arithmetic<T> or std::is_enum<T> type traits.
|
||||
|
||||
// A tag to indicate an empty flatbuffers::optional<T>.
|
||||
struct nullopt_t {
|
||||
explicit FLATBUFFERS_CONSTEXPR_CPP11 nullopt_t(int) {}
|
||||
};
|
||||
|
||||
#if defined(FLATBUFFERS_CONSTEXPR_DEFINED)
|
||||
namespace internal {
|
||||
template <class> struct nullopt_holder {
|
||||
static constexpr nullopt_t instance_ = nullopt_t(0);
|
||||
};
|
||||
template<class Dummy>
|
||||
constexpr nullopt_t nullopt_holder<Dummy>::instance_;
|
||||
}
|
||||
static constexpr const nullopt_t &nullopt = internal::nullopt_holder<void>::instance_;
|
||||
|
||||
#else
|
||||
namespace internal {
|
||||
template <class> struct nullopt_holder {
|
||||
static const nullopt_t instance_;
|
||||
};
|
||||
template<class Dummy>
|
||||
const nullopt_t nullopt_holder<Dummy>::instance_ = nullopt_t(0);
|
||||
}
|
||||
static const nullopt_t &nullopt = internal::nullopt_holder<void>::instance_;
|
||||
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
class Optional FLATBUFFERS_FINAL_CLASS {
|
||||
// Non-scalar 'T' would extremely complicated Optional<T>.
|
||||
// Use is_scalar<T> checking because flatbuffers flatbuffers::is_arithmetic<T>
|
||||
// isn't implemented.
|
||||
static_assert(flatbuffers::is_scalar<T>::value, "unexpected type T");
|
||||
|
||||
public:
|
||||
~Optional() {}
|
||||
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 Optional() FLATBUFFERS_NOEXCEPT
|
||||
: value_(), has_value_(false) {}
|
||||
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 Optional(nullopt_t) FLATBUFFERS_NOEXCEPT
|
||||
: value_(), has_value_(false) {}
|
||||
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 Optional(T val) FLATBUFFERS_NOEXCEPT
|
||||
: value_(val), has_value_(true) {}
|
||||
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 Optional(const Optional &other) FLATBUFFERS_NOEXCEPT
|
||||
: value_(other.value_), has_value_(other.has_value_) {}
|
||||
|
||||
FLATBUFFERS_CONSTEXPR_CPP14 Optional &operator=(const Optional &other) FLATBUFFERS_NOEXCEPT {
|
||||
value_ = other.value_;
|
||||
has_value_ = other.has_value_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FLATBUFFERS_CONSTEXPR_CPP14 Optional &operator=(nullopt_t) FLATBUFFERS_NOEXCEPT {
|
||||
value_ = T();
|
||||
has_value_ = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FLATBUFFERS_CONSTEXPR_CPP14 Optional &operator=(T val) FLATBUFFERS_NOEXCEPT {
|
||||
value_ = val;
|
||||
has_value_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset() FLATBUFFERS_NOEXCEPT {
|
||||
*this = nullopt;
|
||||
}
|
||||
|
||||
void swap(Optional &other) FLATBUFFERS_NOEXCEPT {
|
||||
std::swap(value_, other.value_);
|
||||
std::swap(has_value_, other.has_value_);
|
||||
}
|
||||
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 FLATBUFFERS_EXPLICIT_CPP11 operator bool() const FLATBUFFERS_NOEXCEPT {
|
||||
return has_value_;
|
||||
}
|
||||
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 bool has_value() const FLATBUFFERS_NOEXCEPT {
|
||||
return has_value_;
|
||||
}
|
||||
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 const T& operator*() const FLATBUFFERS_NOEXCEPT {
|
||||
return value_;
|
||||
}
|
||||
|
||||
const T& value() const {
|
||||
FLATBUFFERS_ASSERT(has_value());
|
||||
return value_;
|
||||
}
|
||||
|
||||
T value_or(T default_value) const FLATBUFFERS_NOEXCEPT {
|
||||
return has_value() ? value_ : default_value;
|
||||
}
|
||||
|
||||
private:
|
||||
T value_;
|
||||
bool has_value_;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 bool operator==(const Optional<T>& opt, nullopt_t) FLATBUFFERS_NOEXCEPT {
|
||||
return !opt;
|
||||
}
|
||||
template<class T>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 bool operator==(nullopt_t, const Optional<T>& opt) FLATBUFFERS_NOEXCEPT {
|
||||
return !opt;
|
||||
}
|
||||
|
||||
template<class T, class U>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 bool operator==(const Optional<T>& lhs, const U& rhs) FLATBUFFERS_NOEXCEPT {
|
||||
return static_cast<bool>(lhs) && (*lhs == rhs);
|
||||
}
|
||||
|
||||
template<class T, class U>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 bool operator==(const T& lhs, const Optional<U>& rhs) FLATBUFFERS_NOEXCEPT {
|
||||
return static_cast<bool>(rhs) && (lhs == *rhs);
|
||||
}
|
||||
|
||||
template<class T, class U>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 bool operator==(const Optional<T>& lhs, const Optional<U>& rhs) FLATBUFFERS_NOEXCEPT {
|
||||
return static_cast<bool>(lhs) != static_cast<bool>(rhs)
|
||||
? false
|
||||
: !static_cast<bool>(lhs) ? false : (*lhs == *rhs);
|
||||
}
|
||||
#endif // FLATBUFFERS_USE_STD_OPTIONAL
|
||||
|
||||
|
||||
// Very limited and naive partial implementation of C++20 std::span<T,Extent>.
|
||||
#if defined(FLATBUFFERS_USE_STD_SPAN)
|
||||
inline constexpr std::size_t dynamic_extent = std::dynamic_extent;
|
||||
template<class T, std::size_t Extent = std::dynamic_extent>
|
||||
using span = std::span<T, Extent>;
|
||||
|
||||
#else // !defined(FLATBUFFERS_USE_STD_SPAN)
|
||||
FLATBUFFERS_CONSTEXPR std::size_t dynamic_extent = static_cast<std::size_t>(-1);
|
||||
|
||||
// Exclude this code if MSVC2010 or non-STL Android is active.
|
||||
// The non-STL Android doesn't have `std::is_convertible` required for SFINAE.
|
||||
#if !defined(FLATBUFFERS_SPAN_MINIMAL)
|
||||
namespace internal {
|
||||
// This is SFINAE helper class for checking of a common condition:
|
||||
// > This overload only participates in overload resolution
|
||||
// > Check whether a pointer to an array of From can be converted
|
||||
// > to a pointer to an array of To.
|
||||
// This helper is used for checking of 'From -> const From'.
|
||||
template<class To, std::size_t Extent, class From, std::size_t N>
|
||||
struct is_span_convertible {
|
||||
using type =
|
||||
typename std::conditional<std::is_convertible<From (*)[], To (*)[]>::value
|
||||
&& (Extent == dynamic_extent || N == Extent),
|
||||
int, void>::type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct SpanIterator {
|
||||
// TODO: upgrade to std::random_access_iterator_tag.
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = typename std::remove_cv<T>::type;
|
||||
using reference = T&;
|
||||
using pointer = T*;
|
||||
|
||||
// Convince MSVC compiler that this iterator is trusted (it is verified).
|
||||
#ifdef _MSC_VER
|
||||
using _Unchecked_type = pointer;
|
||||
#endif // _MSC_VER
|
||||
|
||||
SpanIterator(pointer ptr) : ptr_(ptr) {}
|
||||
reference operator*() const { return *ptr_; }
|
||||
pointer operator->() { return ptr_; }
|
||||
SpanIterator& operator++() { ptr_++; return *this; }
|
||||
SpanIterator operator++(int) { auto tmp = *this; ++(*this); return tmp; }
|
||||
|
||||
friend bool operator== (const SpanIterator& lhs, const SpanIterator& rhs) { return lhs.ptr_ == rhs.ptr_; }
|
||||
friend bool operator!= (const SpanIterator& lhs, const SpanIterator& rhs) { return lhs.ptr_ != rhs.ptr_; }
|
||||
|
||||
private:
|
||||
pointer ptr_;
|
||||
};
|
||||
} // namespace internal
|
||||
#endif // !defined(FLATBUFFERS_SPAN_MINIMAL)
|
||||
|
||||
// T - element type; must be a complete type that is not an abstract
|
||||
// class type.
|
||||
// Extent - the number of elements in the sequence, or dynamic.
|
||||
template<class T, std::size_t Extent = dynamic_extent>
|
||||
class span FLATBUFFERS_FINAL_CLASS {
|
||||
public:
|
||||
typedef T element_type;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef std::size_t size_type;
|
||||
|
||||
static FLATBUFFERS_CONSTEXPR size_type extent = Extent;
|
||||
|
||||
// Returns the number of elements in the span.
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 size_type size() const FLATBUFFERS_NOEXCEPT {
|
||||
return count_;
|
||||
}
|
||||
|
||||
// Returns the size of the sequence in bytes.
|
||||
FLATBUFFERS_CONSTEXPR_CPP11
|
||||
size_type size_bytes() const FLATBUFFERS_NOEXCEPT {
|
||||
return size() * sizeof(element_type);
|
||||
}
|
||||
|
||||
// Checks if the span is empty.
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 bool empty() const FLATBUFFERS_NOEXCEPT {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
// Returns a pointer to the beginning of the sequence.
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 pointer data() const FLATBUFFERS_NOEXCEPT {
|
||||
return data_;
|
||||
}
|
||||
|
||||
#if !defined(FLATBUFFERS_SPAN_MINIMAL)
|
||||
using Iterator = internal::SpanIterator<T>;
|
||||
|
||||
Iterator begin() const { return Iterator(data()); }
|
||||
Iterator end() const { return Iterator(data() + size()); }
|
||||
#endif
|
||||
|
||||
// Returns a reference to the idx-th element of the sequence.
|
||||
// The behavior is undefined if the idx is greater than or equal to size().
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 reference operator[](size_type idx) const {
|
||||
return data()[idx];
|
||||
}
|
||||
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 span(const span &other) FLATBUFFERS_NOEXCEPT
|
||||
: data_(other.data_), count_(other.count_) {}
|
||||
|
||||
FLATBUFFERS_CONSTEXPR_CPP14 span &operator=(const span &other)
|
||||
FLATBUFFERS_NOEXCEPT {
|
||||
data_ = other.data_;
|
||||
count_ = other.count_;
|
||||
}
|
||||
|
||||
// Limited implementation of
|
||||
// `template <class It> constexpr std::span(It first, size_type count);`.
|
||||
//
|
||||
// Constructs a span that is a view over the range [first, first + count);
|
||||
// the resulting span has: data() == first and size() == count.
|
||||
// The behavior is undefined if [first, first + count) is not a valid range,
|
||||
// or if (extent != flatbuffers::dynamic_extent && count != extent).
|
||||
FLATBUFFERS_CONSTEXPR_CPP11
|
||||
explicit span(pointer first, size_type count) FLATBUFFERS_NOEXCEPT
|
||||
: data_ (Extent == dynamic_extent ? first : (Extent == count ? first : nullptr)),
|
||||
count_(Extent == dynamic_extent ? count : (Extent == count ? Extent : 0)) {
|
||||
// Make span empty if the count argument is incompatible with span<T,N>.
|
||||
}
|
||||
|
||||
// Exclude this code if MSVC2010 is active. The MSVC2010 isn't C++11
|
||||
// compliant, it doesn't support default template arguments for functions.
|
||||
#if defined(FLATBUFFERS_SPAN_MINIMAL)
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 span() FLATBUFFERS_NOEXCEPT : data_(nullptr),
|
||||
count_(0) {
|
||||
static_assert(extent == 0 || extent == dynamic_extent, "invalid span");
|
||||
}
|
||||
|
||||
#else
|
||||
// Constructs an empty span whose data() == nullptr and size() == 0.
|
||||
// This overload only participates in overload resolution if
|
||||
// extent == 0 || extent == flatbuffers::dynamic_extent.
|
||||
// A dummy template argument N is need dependency for SFINAE.
|
||||
template<std::size_t N = 0,
|
||||
typename internal::is_span_convertible<element_type, Extent, element_type, (N - N)>::type = 0>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 span() FLATBUFFERS_NOEXCEPT : data_(nullptr),
|
||||
count_(0) {
|
||||
static_assert(extent == 0 || extent == dynamic_extent, "invalid span");
|
||||
}
|
||||
|
||||
// Constructs a span that is a view over the array arr; the resulting span
|
||||
// has size() == N and data() == std::data(arr). These overloads only
|
||||
// participate in overload resolution if
|
||||
// extent == std::dynamic_extent || N == extent is true and
|
||||
// std::remove_pointer_t<decltype(std::data(arr))>(*)[]
|
||||
// is convertible to element_type (*)[].
|
||||
template<std::size_t N,
|
||||
typename internal::is_span_convertible<element_type, Extent, element_type, N>::type = 0>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 span(element_type (&arr)[N]) FLATBUFFERS_NOEXCEPT
|
||||
: data_(arr), count_(N) {}
|
||||
|
||||
template<class U, std::size_t N,
|
||||
typename internal::is_span_convertible<element_type, Extent, U, N>::type = 0>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 span(std::array<U, N> &arr) FLATBUFFERS_NOEXCEPT
|
||||
: data_(arr.data()), count_(N) {}
|
||||
|
||||
//template<class U, std::size_t N,
|
||||
// int = 0>
|
||||
//FLATBUFFERS_CONSTEXPR_CPP11 span(std::array<U, N> &arr) FLATBUFFERS_NOEXCEPT
|
||||
// : data_(arr.data()), count_(N) {}
|
||||
|
||||
template<class U, std::size_t N,
|
||||
typename internal::is_span_convertible<element_type, Extent, U, N>::type = 0>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 span(const std::array<U, N> &arr) FLATBUFFERS_NOEXCEPT
|
||||
: data_(arr.data()), count_(N) {}
|
||||
|
||||
// Converting constructor from another span s;
|
||||
// the resulting span has size() == s.size() and data() == s.data().
|
||||
// This overload only participates in overload resolution
|
||||
// if extent == std::dynamic_extent || N == extent is true and U (*)[]
|
||||
// is convertible to element_type (*)[].
|
||||
template<class U, std::size_t N,
|
||||
typename internal::is_span_convertible<element_type, Extent, U, N>::type = 0>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 span(const flatbuffers::span<U, N> &s) FLATBUFFERS_NOEXCEPT
|
||||
: span(s.data(), s.size()) {
|
||||
}
|
||||
|
||||
#endif // !defined(FLATBUFFERS_SPAN_MINIMAL)
|
||||
|
||||
private:
|
||||
// This is a naive implementation with 'count_' member even if (Extent != dynamic_extent).
|
||||
pointer const data_;
|
||||
size_type count_;
|
||||
};
|
||||
#endif // defined(FLATBUFFERS_USE_STD_SPAN)
|
||||
|
||||
#if !defined(FLATBUFFERS_SPAN_MINIMAL)
|
||||
template<class ElementType, std::size_t Extent>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11
|
||||
flatbuffers::span<ElementType, Extent> make_span(ElementType(&arr)[Extent]) FLATBUFFERS_NOEXCEPT {
|
||||
return span<ElementType, Extent>(arr);
|
||||
}
|
||||
|
||||
template<class ElementType, std::size_t Extent>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11
|
||||
flatbuffers::span<const ElementType, Extent> make_span(const ElementType(&arr)[Extent]) FLATBUFFERS_NOEXCEPT {
|
||||
return span<const ElementType, Extent>(arr);
|
||||
}
|
||||
|
||||
template<class ElementType, std::size_t Extent>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11
|
||||
flatbuffers::span<ElementType, Extent> make_span(std::array<ElementType, Extent> &arr) FLATBUFFERS_NOEXCEPT {
|
||||
return span<ElementType, Extent>(arr);
|
||||
}
|
||||
|
||||
template<class ElementType, std::size_t Extent>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11
|
||||
flatbuffers::span<const ElementType, Extent> make_span(const std::array<ElementType, Extent> &arr) FLATBUFFERS_NOEXCEPT {
|
||||
return span<const ElementType, Extent>(arr);
|
||||
}
|
||||
|
||||
template<class ElementType, std::size_t Extent>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11
|
||||
flatbuffers::span<ElementType, dynamic_extent> make_span(ElementType *first, std::size_t count) FLATBUFFERS_NOEXCEPT {
|
||||
return span<ElementType, dynamic_extent>(first, count);
|
||||
}
|
||||
|
||||
template<class ElementType, std::size_t Extent>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11
|
||||
flatbuffers::span<const ElementType, dynamic_extent> make_span(const ElementType *first, std::size_t count) FLATBUFFERS_NOEXCEPT {
|
||||
return span<const ElementType, dynamic_extent>(first, count);
|
||||
}
|
||||
#endif // !defined(FLATBUFFERS_SPAN_MINIMAL)
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_STL_EMULATION_H_
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLATBUFFERS_STRING_H_
|
||||
#define FLATBUFFERS_STRING_H_
|
||||
|
||||
#include "flatbuffers/base.h"
|
||||
#include "flatbuffers/vector.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
struct String : public Vector<char> {
|
||||
const char *c_str() const { return reinterpret_cast<const char *>(Data()); }
|
||||
std::string str() const { return std::string(c_str(), size()); }
|
||||
|
||||
// clang-format off
|
||||
#ifdef FLATBUFFERS_HAS_STRING_VIEW
|
||||
flatbuffers::string_view string_view() const {
|
||||
return flatbuffers::string_view(c_str(), size());
|
||||
}
|
||||
#endif // FLATBUFFERS_HAS_STRING_VIEW
|
||||
// clang-format on
|
||||
|
||||
bool operator<(const String &o) const {
|
||||
return StringLessThan(this->data(), this->size(), o.data(), o.size());
|
||||
}
|
||||
};
|
||||
|
||||
// Convenience function to get std::string from a String returning an empty
|
||||
// string on null pointer.
|
||||
static inline std::string GetString(const String *str) {
|
||||
return str ? str->str() : "";
|
||||
}
|
||||
|
||||
// Convenience function to get char* from a String returning an empty string on
|
||||
// null pointer.
|
||||
static inline const char *GetCstring(const String *str) {
|
||||
return str ? str->c_str() : "";
|
||||
}
|
||||
|
||||
#ifdef FLATBUFFERS_HAS_STRING_VIEW
|
||||
// Convenience function to get string_view from a String returning an empty
|
||||
// string_view on null pointer.
|
||||
static inline flatbuffers::string_view GetStringView(const String *str) {
|
||||
return str ? str->string_view() : flatbuffers::string_view();
|
||||
}
|
||||
#endif // FLATBUFFERS_HAS_STRING_VIEW
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_STRING_H_
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLATBUFFERS_STRUCT_H_
|
||||
#define FLATBUFFERS_STRUCT_H_
|
||||
|
||||
#include "flatbuffers/base.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
// "structs" are flat structures that do not have an offset table, thus
|
||||
// always have all members present and do not support forwards/backwards
|
||||
// compatible extensions.
|
||||
|
||||
class Struct FLATBUFFERS_FINAL_CLASS {
|
||||
public:
|
||||
template<typename T> T GetField(uoffset_t o) const {
|
||||
return ReadScalar<T>(&data_[o]);
|
||||
}
|
||||
|
||||
template<typename T> T GetStruct(uoffset_t o) const {
|
||||
return reinterpret_cast<T>(&data_[o]);
|
||||
}
|
||||
|
||||
const uint8_t *GetAddressOf(uoffset_t o) const { return &data_[o]; }
|
||||
uint8_t *GetAddressOf(uoffset_t o) { return &data_[o]; }
|
||||
|
||||
private:
|
||||
// private constructor & copy constructor: you obtain instances of this
|
||||
// class by pointing to existing data only
|
||||
Struct();
|
||||
Struct(const Struct &);
|
||||
Struct &operator=(const Struct &);
|
||||
|
||||
uint8_t data_[1];
|
||||
};
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_STRUCT_H_
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLATBUFFERS_TABLE_H_
|
||||
#define FLATBUFFERS_TABLE_H_
|
||||
|
||||
#include "flatbuffers/base.h"
|
||||
#include "flatbuffers/verifier.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
// "tables" use an offset table (possibly shared) that allows fields to be
|
||||
// omitted and added at will, but uses an extra indirection to read.
|
||||
class Table {
|
||||
public:
|
||||
const uint8_t *GetVTable() const {
|
||||
return data_ - ReadScalar<soffset_t>(data_);
|
||||
}
|
||||
|
||||
// This gets the field offset for any of the functions below it, or 0
|
||||
// if the field was not present.
|
||||
voffset_t GetOptionalFieldOffset(voffset_t field) const {
|
||||
// The vtable offset is always at the start.
|
||||
auto vtable = GetVTable();
|
||||
// The first element is the size of the vtable (fields + type id + itself).
|
||||
auto vtsize = ReadScalar<voffset_t>(vtable);
|
||||
// If the field we're accessing is outside the vtable, we're reading older
|
||||
// data, so it's the same as if the offset was 0 (not present).
|
||||
return field < vtsize ? ReadScalar<voffset_t>(vtable + field) : 0;
|
||||
}
|
||||
|
||||
template<typename T> T GetField(voffset_t field, T defaultval) const {
|
||||
auto field_offset = GetOptionalFieldOffset(field);
|
||||
return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval;
|
||||
}
|
||||
|
||||
template<typename P, typename OffsetSize = uoffset_t>
|
||||
P GetPointer(voffset_t field) {
|
||||
auto field_offset = GetOptionalFieldOffset(field);
|
||||
auto p = data_ + field_offset;
|
||||
return field_offset ? reinterpret_cast<P>(p + ReadScalar<OffsetSize>(p))
|
||||
: nullptr;
|
||||
}
|
||||
template<typename P, typename OffsetSize = uoffset_t>
|
||||
P GetPointer(voffset_t field) const {
|
||||
return const_cast<Table *>(this)->GetPointer<P, OffsetSize>(field);
|
||||
}
|
||||
|
||||
template<typename P> P GetPointer64(voffset_t field) {
|
||||
return GetPointer<P, uoffset64_t>(field);
|
||||
}
|
||||
|
||||
template<typename P> P GetPointer64(voffset_t field) const {
|
||||
return GetPointer<P, uoffset64_t>(field);
|
||||
}
|
||||
|
||||
template<typename P> P GetStruct(voffset_t field) const {
|
||||
auto field_offset = GetOptionalFieldOffset(field);
|
||||
auto p = const_cast<uint8_t *>(data_ + field_offset);
|
||||
return field_offset ? reinterpret_cast<P>(p) : nullptr;
|
||||
}
|
||||
|
||||
template<typename Raw, typename Face>
|
||||
flatbuffers::Optional<Face> GetOptional(voffset_t field) const {
|
||||
auto field_offset = GetOptionalFieldOffset(field);
|
||||
auto p = data_ + field_offset;
|
||||
return field_offset ? Optional<Face>(static_cast<Face>(ReadScalar<Raw>(p)))
|
||||
: Optional<Face>();
|
||||
}
|
||||
|
||||
template<typename T> bool SetField(voffset_t field, T val, T def) {
|
||||
auto field_offset = GetOptionalFieldOffset(field);
|
||||
if (!field_offset) return IsTheSameAs(val, def);
|
||||
WriteScalar(data_ + field_offset, val);
|
||||
return true;
|
||||
}
|
||||
template<typename T> bool SetField(voffset_t field, T val) {
|
||||
auto field_offset = GetOptionalFieldOffset(field);
|
||||
if (!field_offset) return false;
|
||||
WriteScalar(data_ + field_offset, val);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetPointer(voffset_t field, const uint8_t *val) {
|
||||
auto field_offset = GetOptionalFieldOffset(field);
|
||||
if (!field_offset) return false;
|
||||
WriteScalar(data_ + field_offset,
|
||||
static_cast<uoffset_t>(val - (data_ + field_offset)));
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t *GetAddressOf(voffset_t field) {
|
||||
auto field_offset = GetOptionalFieldOffset(field);
|
||||
return field_offset ? data_ + field_offset : nullptr;
|
||||
}
|
||||
const uint8_t *GetAddressOf(voffset_t field) const {
|
||||
return const_cast<Table *>(this)->GetAddressOf(field);
|
||||
}
|
||||
|
||||
bool CheckField(voffset_t field) const {
|
||||
return GetOptionalFieldOffset(field) != 0;
|
||||
}
|
||||
|
||||
// Verify the vtable of this table.
|
||||
// Call this once per table, followed by VerifyField once per field.
|
||||
bool VerifyTableStart(Verifier &verifier) const {
|
||||
return verifier.VerifyTableStart(data_);
|
||||
}
|
||||
|
||||
// Verify a particular field.
|
||||
template<typename T>
|
||||
bool VerifyField(const Verifier &verifier, voffset_t field,
|
||||
size_t align) const {
|
||||
// Calling GetOptionalFieldOffset should be safe now thanks to
|
||||
// VerifyTable().
|
||||
auto field_offset = GetOptionalFieldOffset(field);
|
||||
// Check the actual field.
|
||||
return !field_offset || verifier.VerifyField<T>(data_, field_offset, align);
|
||||
}
|
||||
|
||||
// VerifyField for required fields.
|
||||
template<typename T>
|
||||
bool VerifyFieldRequired(const Verifier &verifier, voffset_t field,
|
||||
size_t align) const {
|
||||
auto field_offset = GetOptionalFieldOffset(field);
|
||||
return verifier.Check(field_offset != 0) &&
|
||||
verifier.VerifyField<T>(data_, field_offset, align);
|
||||
}
|
||||
|
||||
// Versions for offsets.
|
||||
template<typename OffsetT = uoffset_t>
|
||||
bool VerifyOffset(const Verifier &verifier, voffset_t field) const {
|
||||
auto field_offset = GetOptionalFieldOffset(field);
|
||||
return !field_offset || verifier.VerifyOffset<OffsetT>(data_, field_offset);
|
||||
}
|
||||
|
||||
template<typename OffsetT = uoffset_t>
|
||||
bool VerifyOffsetRequired(const Verifier &verifier, voffset_t field) const {
|
||||
auto field_offset = GetOptionalFieldOffset(field);
|
||||
return verifier.Check(field_offset != 0) &&
|
||||
verifier.VerifyOffset<OffsetT>(data_, field_offset);
|
||||
}
|
||||
|
||||
bool VerifyOffset64(const Verifier &verifier, voffset_t field) const {
|
||||
return VerifyOffset<uoffset64_t>(verifier, field);
|
||||
}
|
||||
|
||||
bool VerifyOffset64Required(const Verifier &verifier, voffset_t field) const {
|
||||
return VerifyOffsetRequired<uoffset64_t>(verifier, field);
|
||||
}
|
||||
|
||||
private:
|
||||
// private constructor & copy constructor: you obtain instances of this
|
||||
// class by pointing to existing data only
|
||||
Table();
|
||||
Table(const Table &other);
|
||||
Table &operator=(const Table &);
|
||||
|
||||
uint8_t data_[1];
|
||||
};
|
||||
|
||||
// This specialization allows avoiding warnings like:
|
||||
// MSVC C4800: type: forcing value to bool 'true' or 'false'.
|
||||
template<>
|
||||
inline flatbuffers::Optional<bool> Table::GetOptional<uint8_t, bool>(
|
||||
voffset_t field) const {
|
||||
auto field_offset = GetOptionalFieldOffset(field);
|
||||
auto p = data_ + field_offset;
|
||||
return field_offset ? Optional<bool>(ReadScalar<uint8_t>(p) != 0)
|
||||
: Optional<bool>();
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_TABLE_H_
|
||||
+400
@@ -0,0 +1,400 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLATBUFFERS_VECTOR_H_
|
||||
#define FLATBUFFERS_VECTOR_H_
|
||||
|
||||
#include "flatbuffers/base.h"
|
||||
#include "flatbuffers/buffer.h"
|
||||
#include "flatbuffers/stl_emulation.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
struct String;
|
||||
|
||||
// An STL compatible iterator implementation for Vector below, effectively
|
||||
// calling Get() for every element.
|
||||
template<typename T, typename IT, typename Data = uint8_t *,
|
||||
typename SizeT = uoffset_t>
|
||||
struct VectorIterator {
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef IT value_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef IT *pointer;
|
||||
typedef IT &reference;
|
||||
|
||||
static const SizeT element_stride = IndirectHelper<T>::element_stride;
|
||||
|
||||
VectorIterator(Data data, SizeT i) : data_(data + element_stride * i) {}
|
||||
VectorIterator(const VectorIterator &other) : data_(other.data_) {}
|
||||
VectorIterator() : data_(nullptr) {}
|
||||
|
||||
VectorIterator &operator=(const VectorIterator &other) {
|
||||
data_ = other.data_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VectorIterator &operator=(VectorIterator &&other) {
|
||||
data_ = other.data_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const VectorIterator &other) const {
|
||||
return data_ == other.data_;
|
||||
}
|
||||
|
||||
bool operator<(const VectorIterator &other) const {
|
||||
return data_ < other.data_;
|
||||
}
|
||||
|
||||
bool operator!=(const VectorIterator &other) const {
|
||||
return data_ != other.data_;
|
||||
}
|
||||
|
||||
difference_type operator-(const VectorIterator &other) const {
|
||||
return (data_ - other.data_) / element_stride;
|
||||
}
|
||||
|
||||
// Note: return type is incompatible with the standard
|
||||
// `reference operator*()`.
|
||||
IT operator*() const { return IndirectHelper<T>::Read(data_, 0); }
|
||||
|
||||
// Note: return type is incompatible with the standard
|
||||
// `pointer operator->()`.
|
||||
IT operator->() const { return IndirectHelper<T>::Read(data_, 0); }
|
||||
|
||||
VectorIterator &operator++() {
|
||||
data_ += element_stride;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VectorIterator operator++(int) {
|
||||
VectorIterator temp(data_, 0);
|
||||
data_ += element_stride;
|
||||
return temp;
|
||||
}
|
||||
|
||||
VectorIterator operator+(const SizeT &offset) const {
|
||||
return VectorIterator(data_ + offset * element_stride, 0);
|
||||
}
|
||||
|
||||
VectorIterator &operator+=(const SizeT &offset) {
|
||||
data_ += offset * element_stride;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VectorIterator &operator--() {
|
||||
data_ -= element_stride;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VectorIterator operator--(int) {
|
||||
VectorIterator temp(data_, 0);
|
||||
data_ -= element_stride;
|
||||
return temp;
|
||||
}
|
||||
|
||||
VectorIterator operator-(const SizeT &offset) const {
|
||||
return VectorIterator(data_ - offset * element_stride, 0);
|
||||
}
|
||||
|
||||
VectorIterator &operator-=(const SizeT &offset) {
|
||||
data_ -= offset * element_stride;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
Data data_;
|
||||
};
|
||||
|
||||
template<typename T, typename IT, typename SizeT = uoffset_t>
|
||||
using VectorConstIterator = VectorIterator<T, IT, const uint8_t *, SizeT>;
|
||||
|
||||
template<typename Iterator>
|
||||
struct VectorReverseIterator : public std::reverse_iterator<Iterator> {
|
||||
explicit VectorReverseIterator(Iterator iter)
|
||||
: std::reverse_iterator<Iterator>(iter) {}
|
||||
|
||||
// Note: return type is incompatible with the standard
|
||||
// `reference operator*()`.
|
||||
typename Iterator::value_type operator*() const {
|
||||
auto tmp = std::reverse_iterator<Iterator>::current;
|
||||
return *--tmp;
|
||||
}
|
||||
|
||||
// Note: return type is incompatible with the standard
|
||||
// `pointer operator->()`.
|
||||
typename Iterator::value_type operator->() const {
|
||||
auto tmp = std::reverse_iterator<Iterator>::current;
|
||||
return *--tmp;
|
||||
}
|
||||
};
|
||||
|
||||
// This is used as a helper type for accessing vectors.
|
||||
// Vector::data() assumes the vector elements start after the length field.
|
||||
template<typename T, typename SizeT = uoffset_t> class Vector {
|
||||
public:
|
||||
typedef VectorIterator<T,
|
||||
typename IndirectHelper<T>::mutable_return_type,
|
||||
uint8_t *, SizeT>
|
||||
iterator;
|
||||
typedef VectorConstIterator<T, typename IndirectHelper<T>::return_type,
|
||||
SizeT>
|
||||
const_iterator;
|
||||
typedef VectorReverseIterator<iterator> reverse_iterator;
|
||||
typedef VectorReverseIterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
typedef typename flatbuffers::bool_constant<flatbuffers::is_scalar<T>::value>
|
||||
scalar_tag;
|
||||
|
||||
static FLATBUFFERS_CONSTEXPR bool is_span_observable =
|
||||
scalar_tag::value && (FLATBUFFERS_LITTLEENDIAN || sizeof(T) == 1);
|
||||
|
||||
SizeT size() const { return EndianScalar(length_); }
|
||||
|
||||
// Deprecated: use size(). Here for backwards compatibility.
|
||||
FLATBUFFERS_ATTRIBUTE([[deprecated("use size() instead")]])
|
||||
SizeT Length() const { return size(); }
|
||||
|
||||
typedef SizeT size_type;
|
||||
typedef typename IndirectHelper<T>::return_type return_type;
|
||||
typedef typename IndirectHelper<T>::mutable_return_type
|
||||
mutable_return_type;
|
||||
typedef return_type value_type;
|
||||
|
||||
return_type Get(SizeT i) const {
|
||||
FLATBUFFERS_ASSERT(i < size());
|
||||
return IndirectHelper<T>::Read(Data(), i);
|
||||
}
|
||||
|
||||
return_type operator[](SizeT i) const { return Get(i); }
|
||||
|
||||
// If this is a Vector of enums, T will be its storage type, not the enum
|
||||
// type. This function makes it convenient to retrieve value with enum
|
||||
// type E.
|
||||
template<typename E> E GetEnum(SizeT i) const {
|
||||
return static_cast<E>(Get(i));
|
||||
}
|
||||
|
||||
// If this a vector of unions, this does the cast for you. There's no check
|
||||
// to make sure this is the right type!
|
||||
template<typename U> const U *GetAs(SizeT i) const {
|
||||
return reinterpret_cast<const U *>(Get(i));
|
||||
}
|
||||
|
||||
// If this a vector of unions, this does the cast for you. There's no check
|
||||
// to make sure this is actually a string!
|
||||
const String *GetAsString(SizeT i) const {
|
||||
return reinterpret_cast<const String *>(Get(i));
|
||||
}
|
||||
|
||||
const void *GetStructFromOffset(size_t o) const {
|
||||
return reinterpret_cast<const void *>(Data() + o);
|
||||
}
|
||||
|
||||
iterator begin() { return iterator(Data(), 0); }
|
||||
const_iterator begin() const { return const_iterator(Data(), 0); }
|
||||
|
||||
iterator end() { return iterator(Data(), size()); }
|
||||
const_iterator end() const { return const_iterator(Data(), size()); }
|
||||
|
||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
const_reverse_iterator rbegin() const {
|
||||
return const_reverse_iterator(end());
|
||||
}
|
||||
|
||||
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator rend() const {
|
||||
return const_reverse_iterator(begin());
|
||||
}
|
||||
|
||||
const_iterator cbegin() const { return begin(); }
|
||||
|
||||
const_iterator cend() const { return end(); }
|
||||
|
||||
const_reverse_iterator crbegin() const { return rbegin(); }
|
||||
|
||||
const_reverse_iterator crend() const { return rend(); }
|
||||
|
||||
// Change elements if you have a non-const pointer to this object.
|
||||
// Scalars only. See reflection.h, and the documentation.
|
||||
void Mutate(SizeT i, const T &val) {
|
||||
FLATBUFFERS_ASSERT(i < size());
|
||||
WriteScalar(data() + i, val);
|
||||
}
|
||||
|
||||
// Change an element of a vector of tables (or strings).
|
||||
// "val" points to the new table/string, as you can obtain from
|
||||
// e.g. reflection::AddFlatBuffer().
|
||||
void MutateOffset(SizeT i, const uint8_t *val) {
|
||||
FLATBUFFERS_ASSERT(i < size());
|
||||
static_assert(sizeof(T) == sizeof(SizeT), "Unrelated types");
|
||||
WriteScalar(data() + i,
|
||||
static_cast<SizeT>(val - (Data() + i * sizeof(SizeT))));
|
||||
}
|
||||
|
||||
// Get a mutable pointer to tables/strings inside this vector.
|
||||
mutable_return_type GetMutableObject(SizeT i) const {
|
||||
FLATBUFFERS_ASSERT(i < size());
|
||||
return const_cast<mutable_return_type>(IndirectHelper<T>::Read(Data(), i));
|
||||
}
|
||||
|
||||
// The raw data in little endian format. Use with care.
|
||||
const uint8_t *Data() const {
|
||||
return reinterpret_cast<const uint8_t *>(&length_ + 1);
|
||||
}
|
||||
|
||||
uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); }
|
||||
|
||||
// Similarly, but typed, much like std::vector::data
|
||||
const T *data() const { return reinterpret_cast<const T *>(Data()); }
|
||||
T *data() { return reinterpret_cast<T *>(Data()); }
|
||||
|
||||
template<typename K> return_type LookupByKey(K key) const {
|
||||
void *search_result = std::bsearch(
|
||||
&key, Data(), size(), IndirectHelper<T>::element_stride, KeyCompare<K>);
|
||||
|
||||
if (!search_result) {
|
||||
return nullptr; // Key not found.
|
||||
}
|
||||
|
||||
const uint8_t *element = reinterpret_cast<const uint8_t *>(search_result);
|
||||
|
||||
return IndirectHelper<T>::Read(element, 0);
|
||||
}
|
||||
|
||||
template<typename K> mutable_return_type MutableLookupByKey(K key) {
|
||||
return const_cast<mutable_return_type>(LookupByKey(key));
|
||||
}
|
||||
|
||||
protected:
|
||||
// This class is only used to access pre-existing data. Don't ever
|
||||
// try to construct these manually.
|
||||
Vector();
|
||||
|
||||
SizeT length_;
|
||||
|
||||
private:
|
||||
// This class is a pointer. Copying will therefore create an invalid object.
|
||||
// Private and unimplemented copy constructor.
|
||||
Vector(const Vector &);
|
||||
Vector &operator=(const Vector &);
|
||||
|
||||
template<typename K> static int KeyCompare(const void *ap, const void *bp) {
|
||||
const K *key = reinterpret_cast<const K *>(ap);
|
||||
const uint8_t *data = reinterpret_cast<const uint8_t *>(bp);
|
||||
auto table = IndirectHelper<T>::Read(data, 0);
|
||||
|
||||
// std::bsearch compares with the operands transposed, so we negate the
|
||||
// result here.
|
||||
return -table->KeyCompareWithValue(*key);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> using Vector64 = Vector<T, uoffset64_t>;
|
||||
|
||||
template<class U>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_span(Vector<U> &vec)
|
||||
FLATBUFFERS_NOEXCEPT {
|
||||
static_assert(Vector<U>::is_span_observable,
|
||||
"wrong type U, only LE-scalar, or byte types are allowed");
|
||||
return span<U>(vec.data(), vec.size());
|
||||
}
|
||||
|
||||
template<class U>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U> make_span(
|
||||
const Vector<U> &vec) FLATBUFFERS_NOEXCEPT {
|
||||
static_assert(Vector<U>::is_span_observable,
|
||||
"wrong type U, only LE-scalar, or byte types are allowed");
|
||||
return span<const U>(vec.data(), vec.size());
|
||||
}
|
||||
|
||||
template<class U>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<uint8_t> make_bytes_span(
|
||||
Vector<U> &vec) FLATBUFFERS_NOEXCEPT {
|
||||
static_assert(Vector<U>::scalar_tag::value,
|
||||
"wrong type U, only LE-scalar, or byte types are allowed");
|
||||
return span<uint8_t>(vec.Data(), vec.size() * sizeof(U));
|
||||
}
|
||||
|
||||
template<class U>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const uint8_t> make_bytes_span(
|
||||
const Vector<U> &vec) FLATBUFFERS_NOEXCEPT {
|
||||
static_assert(Vector<U>::scalar_tag::value,
|
||||
"wrong type U, only LE-scalar, or byte types are allowed");
|
||||
return span<const uint8_t>(vec.Data(), vec.size() * sizeof(U));
|
||||
}
|
||||
|
||||
// Convenient helper functions to get a span of any vector, regardless
|
||||
// of whether it is null or not (the field is not set).
|
||||
template<class U>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_span(Vector<U> *ptr)
|
||||
FLATBUFFERS_NOEXCEPT {
|
||||
static_assert(Vector<U>::is_span_observable,
|
||||
"wrong type U, only LE-scalar, or byte types are allowed");
|
||||
return ptr ? make_span(*ptr) : span<U>();
|
||||
}
|
||||
|
||||
template<class U>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U> make_span(
|
||||
const Vector<U> *ptr) FLATBUFFERS_NOEXCEPT {
|
||||
static_assert(Vector<U>::is_span_observable,
|
||||
"wrong type U, only LE-scalar, or byte types are allowed");
|
||||
return ptr ? make_span(*ptr) : span<const U>();
|
||||
}
|
||||
|
||||
// Represent a vector much like the template above, but in this case we
|
||||
// don't know what the element types are (used with reflection.h).
|
||||
class VectorOfAny {
|
||||
public:
|
||||
uoffset_t size() const { return EndianScalar(length_); }
|
||||
|
||||
const uint8_t *Data() const {
|
||||
return reinterpret_cast<const uint8_t *>(&length_ + 1);
|
||||
}
|
||||
uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); }
|
||||
|
||||
protected:
|
||||
VectorOfAny();
|
||||
|
||||
uoffset_t length_;
|
||||
|
||||
private:
|
||||
VectorOfAny(const VectorOfAny &);
|
||||
VectorOfAny &operator=(const VectorOfAny &);
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
Vector<Offset<T>> *VectorCast(Vector<Offset<U>> *ptr) {
|
||||
static_assert(std::is_base_of<T, U>::value, "Unrelated types");
|
||||
return reinterpret_cast<Vector<Offset<T>> *>(ptr);
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
const Vector<Offset<T>> *VectorCast(const Vector<Offset<U>> *ptr) {
|
||||
static_assert(std::is_base_of<T, U>::value, "Unrelated types");
|
||||
return reinterpret_cast<const Vector<Offset<T>> *>(ptr);
|
||||
}
|
||||
|
||||
// Convenient helper function to get the length of any vector, regardless
|
||||
// of whether it is null or not (the field is not set).
|
||||
template<typename T> static inline size_t VectorLength(const Vector<T> *v) {
|
||||
return v ? v->size() : 0;
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_VERIFIER_H_
|
||||
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLATBUFFERS_VECTOR_DOWNWARD_H_
|
||||
#define FLATBUFFERS_VECTOR_DOWNWARD_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "flatbuffers/base.h"
|
||||
#include "flatbuffers/default_allocator.h"
|
||||
#include "flatbuffers/detached_buffer.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
// This is a minimal replication of std::vector<uint8_t> functionality,
|
||||
// except growing from higher to lower addresses. i.e. push_back() inserts data
|
||||
// in the lowest address in the vector.
|
||||
// Since this vector leaves the lower part unused, we support a "scratch-pad"
|
||||
// that can be stored there for temporary data, to share the allocated space.
|
||||
// Essentially, this supports 2 std::vectors in a single buffer.
|
||||
template<typename SizeT = uoffset_t> class vector_downward {
|
||||
public:
|
||||
explicit vector_downward(size_t initial_size, Allocator *allocator,
|
||||
bool own_allocator, size_t buffer_minalign,
|
||||
const SizeT max_size = FLATBUFFERS_MAX_BUFFER_SIZE)
|
||||
: allocator_(allocator),
|
||||
own_allocator_(own_allocator),
|
||||
initial_size_(initial_size),
|
||||
max_size_(max_size),
|
||||
buffer_minalign_(buffer_minalign),
|
||||
reserved_(0),
|
||||
size_(0),
|
||||
buf_(nullptr),
|
||||
cur_(nullptr),
|
||||
scratch_(nullptr) {}
|
||||
|
||||
vector_downward(vector_downward &&other) noexcept
|
||||
// clang-format on
|
||||
: allocator_(other.allocator_),
|
||||
own_allocator_(other.own_allocator_),
|
||||
initial_size_(other.initial_size_),
|
||||
max_size_(other.max_size_),
|
||||
buffer_minalign_(other.buffer_minalign_),
|
||||
reserved_(other.reserved_),
|
||||
size_(other.size_),
|
||||
buf_(other.buf_),
|
||||
cur_(other.cur_),
|
||||
scratch_(other.scratch_) {
|
||||
// No change in other.allocator_
|
||||
// No change in other.initial_size_
|
||||
// No change in other.buffer_minalign_
|
||||
other.own_allocator_ = false;
|
||||
other.reserved_ = 0;
|
||||
other.buf_ = nullptr;
|
||||
other.cur_ = nullptr;
|
||||
other.scratch_ = nullptr;
|
||||
}
|
||||
|
||||
vector_downward &operator=(vector_downward &&other) noexcept {
|
||||
// Move construct a temporary and swap idiom
|
||||
vector_downward temp(std::move(other));
|
||||
swap(temp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~vector_downward() {
|
||||
clear_buffer();
|
||||
clear_allocator();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
clear_buffer();
|
||||
clear();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
if (buf_) {
|
||||
cur_ = buf_ + reserved_;
|
||||
} else {
|
||||
reserved_ = 0;
|
||||
cur_ = nullptr;
|
||||
}
|
||||
size_ = 0;
|
||||
clear_scratch();
|
||||
}
|
||||
|
||||
void clear_scratch() { scratch_ = buf_; }
|
||||
|
||||
void clear_allocator() {
|
||||
if (own_allocator_ && allocator_) { delete allocator_; }
|
||||
allocator_ = nullptr;
|
||||
own_allocator_ = false;
|
||||
}
|
||||
|
||||
void clear_buffer() {
|
||||
if (buf_) Deallocate(allocator_, buf_, reserved_);
|
||||
buf_ = nullptr;
|
||||
}
|
||||
|
||||
// Relinquish the pointer to the caller.
|
||||
uint8_t *release_raw(size_t &allocated_bytes, size_t &offset) {
|
||||
auto *buf = buf_;
|
||||
allocated_bytes = reserved_;
|
||||
offset = vector_downward::offset();
|
||||
|
||||
// release_raw only relinquishes the buffer ownership.
|
||||
// Does not deallocate or reset the allocator. Destructor will do that.
|
||||
buf_ = nullptr;
|
||||
clear();
|
||||
return buf;
|
||||
}
|
||||
|
||||
// Relinquish the pointer to the caller.
|
||||
DetachedBuffer release() {
|
||||
// allocator ownership (if any) is transferred to DetachedBuffer.
|
||||
DetachedBuffer fb(allocator_, own_allocator_, buf_, reserved_, cur_,
|
||||
size());
|
||||
if (own_allocator_) {
|
||||
allocator_ = nullptr;
|
||||
own_allocator_ = false;
|
||||
}
|
||||
buf_ = nullptr;
|
||||
clear();
|
||||
return fb;
|
||||
}
|
||||
|
||||
size_t ensure_space(size_t len) {
|
||||
FLATBUFFERS_ASSERT(cur_ >= scratch_ && scratch_ >= buf_);
|
||||
// If the length is larger than the unused part of the buffer, we need to
|
||||
// grow.
|
||||
if (len > unused_buffer_size()) { reallocate(len); }
|
||||
FLATBUFFERS_ASSERT(size() < max_size_);
|
||||
return len;
|
||||
}
|
||||
|
||||
inline uint8_t *make_space(size_t len) {
|
||||
if (len) {
|
||||
ensure_space(len);
|
||||
cur_ -= len;
|
||||
size_ += static_cast<SizeT>(len);
|
||||
}
|
||||
return cur_;
|
||||
}
|
||||
|
||||
// Returns nullptr if using the DefaultAllocator.
|
||||
Allocator *get_custom_allocator() { return allocator_; }
|
||||
|
||||
// The current offset into the buffer.
|
||||
size_t offset() const { return cur_ - buf_; }
|
||||
|
||||
// The total size of the vector (both the buffer and scratch parts).
|
||||
inline SizeT size() const { return size_; }
|
||||
|
||||
// The size of the buffer part of the vector that is currently unused.
|
||||
SizeT unused_buffer_size() const { return static_cast<SizeT>(cur_ - scratch_); }
|
||||
|
||||
// The size of the scratch part of the vector.
|
||||
SizeT scratch_size() const { return static_cast<SizeT>(scratch_ - buf_); }
|
||||
|
||||
size_t capacity() const { return reserved_; }
|
||||
|
||||
uint8_t *data() const {
|
||||
FLATBUFFERS_ASSERT(cur_);
|
||||
return cur_;
|
||||
}
|
||||
|
||||
uint8_t *scratch_data() const {
|
||||
FLATBUFFERS_ASSERT(buf_);
|
||||
return buf_;
|
||||
}
|
||||
|
||||
uint8_t *scratch_end() const {
|
||||
FLATBUFFERS_ASSERT(scratch_);
|
||||
return scratch_;
|
||||
}
|
||||
|
||||
uint8_t *data_at(size_t offset) const { return buf_ + reserved_ - offset; }
|
||||
|
||||
void push(const uint8_t *bytes, size_t num) {
|
||||
if (num > 0) { memcpy(make_space(num), bytes, num); }
|
||||
}
|
||||
|
||||
// Specialized version of push() that avoids memcpy call for small data.
|
||||
template<typename T> void push_small(const T &little_endian_t) {
|
||||
make_space(sizeof(T));
|
||||
*reinterpret_cast<T *>(cur_) = little_endian_t;
|
||||
}
|
||||
|
||||
template<typename T> void scratch_push_small(const T &t) {
|
||||
ensure_space(sizeof(T));
|
||||
*reinterpret_cast<T *>(scratch_) = t;
|
||||
scratch_ += sizeof(T);
|
||||
}
|
||||
|
||||
// fill() is most frequently called with small byte counts (<= 4),
|
||||
// which is why we're using loops rather than calling memset.
|
||||
void fill(size_t zero_pad_bytes) {
|
||||
make_space(zero_pad_bytes);
|
||||
for (size_t i = 0; i < zero_pad_bytes; i++) cur_[i] = 0;
|
||||
}
|
||||
|
||||
// Version for when we know the size is larger.
|
||||
// Precondition: zero_pad_bytes > 0
|
||||
void fill_big(size_t zero_pad_bytes) {
|
||||
memset(make_space(zero_pad_bytes), 0, zero_pad_bytes);
|
||||
}
|
||||
|
||||
void pop(size_t bytes_to_remove) {
|
||||
cur_ += bytes_to_remove;
|
||||
size_ -= static_cast<SizeT>(bytes_to_remove);
|
||||
}
|
||||
|
||||
void scratch_pop(size_t bytes_to_remove) { scratch_ -= bytes_to_remove; }
|
||||
|
||||
void swap(vector_downward &other) {
|
||||
using std::swap;
|
||||
swap(allocator_, other.allocator_);
|
||||
swap(own_allocator_, other.own_allocator_);
|
||||
swap(initial_size_, other.initial_size_);
|
||||
swap(buffer_minalign_, other.buffer_minalign_);
|
||||
swap(reserved_, other.reserved_);
|
||||
swap(size_, other.size_);
|
||||
swap(max_size_, other.max_size_);
|
||||
swap(buf_, other.buf_);
|
||||
swap(cur_, other.cur_);
|
||||
swap(scratch_, other.scratch_);
|
||||
}
|
||||
|
||||
void swap_allocator(vector_downward &other) {
|
||||
using std::swap;
|
||||
swap(allocator_, other.allocator_);
|
||||
swap(own_allocator_, other.own_allocator_);
|
||||
}
|
||||
|
||||
private:
|
||||
// You shouldn't really be copying instances of this class.
|
||||
FLATBUFFERS_DELETE_FUNC(vector_downward(const vector_downward &));
|
||||
FLATBUFFERS_DELETE_FUNC(vector_downward &operator=(const vector_downward &));
|
||||
|
||||
Allocator *allocator_;
|
||||
bool own_allocator_;
|
||||
size_t initial_size_;
|
||||
|
||||
// The maximum size the vector can be.
|
||||
SizeT max_size_;
|
||||
size_t buffer_minalign_;
|
||||
size_t reserved_;
|
||||
SizeT size_;
|
||||
uint8_t *buf_;
|
||||
uint8_t *cur_; // Points at location between empty (below) and used (above).
|
||||
uint8_t *scratch_; // Points to the end of the scratchpad in use.
|
||||
|
||||
void reallocate(size_t len) {
|
||||
auto old_reserved = reserved_;
|
||||
auto old_size = size();
|
||||
auto old_scratch_size = scratch_size();
|
||||
reserved_ +=
|
||||
(std::max)(len, old_reserved ? old_reserved / 2 : initial_size_);
|
||||
reserved_ = (reserved_ + buffer_minalign_ - 1) & ~(buffer_minalign_ - 1);
|
||||
if (buf_) {
|
||||
buf_ = ReallocateDownward(allocator_, buf_, old_reserved, reserved_,
|
||||
old_size, old_scratch_size);
|
||||
} else {
|
||||
buf_ = Allocate(allocator_, reserved_);
|
||||
}
|
||||
cur_ = buf_ + reserved_ - old_size;
|
||||
scratch_ = buf_ + old_scratch_size;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_VECTOR_DOWNWARD_H_
|
||||
+330
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLATBUFFERS_VERIFIER_H_
|
||||
#define FLATBUFFERS_VERIFIER_H_
|
||||
|
||||
#include "flatbuffers/base.h"
|
||||
#include "flatbuffers/vector.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
// Helper class to verify the integrity of a FlatBuffer
|
||||
class Verifier FLATBUFFERS_FINAL_CLASS {
|
||||
public:
|
||||
struct Options {
|
||||
// The maximum nesting of tables and vectors before we call it invalid.
|
||||
uoffset_t max_depth = 64;
|
||||
// The maximum number of tables we will verify before we call it invalid.
|
||||
uoffset_t max_tables = 1000000;
|
||||
// If true, verify all data is aligned.
|
||||
bool check_alignment = true;
|
||||
// If true, run verifier on nested flatbuffers
|
||||
bool check_nested_flatbuffers = true;
|
||||
// The maximum size of a buffer.
|
||||
size_t max_size = FLATBUFFERS_MAX_BUFFER_SIZE;
|
||||
// Use assertions to check for errors.
|
||||
bool assert = false;
|
||||
};
|
||||
|
||||
explicit Verifier(const uint8_t *const buf, const size_t buf_len,
|
||||
const Options &opts)
|
||||
: buf_(buf), size_(buf_len), opts_(opts) {
|
||||
FLATBUFFERS_ASSERT(size_ < opts.max_size);
|
||||
}
|
||||
|
||||
// Deprecated API, please construct with Verifier::Options.
|
||||
Verifier(const uint8_t *const buf, const size_t buf_len,
|
||||
const uoffset_t max_depth = 64, const uoffset_t max_tables = 1000000,
|
||||
const bool check_alignment = true)
|
||||
: Verifier(buf, buf_len, [&] {
|
||||
Options opts;
|
||||
opts.max_depth = max_depth;
|
||||
opts.max_tables = max_tables;
|
||||
opts.check_alignment = check_alignment;
|
||||
return opts;
|
||||
}()) {}
|
||||
|
||||
// Central location where any verification failures register.
|
||||
bool Check(const bool ok) const {
|
||||
// clang-format off
|
||||
#ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE
|
||||
if (opts_.assert) { FLATBUFFERS_ASSERT(ok); }
|
||||
#endif
|
||||
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||
if (!ok)
|
||||
upper_bound_ = 0;
|
||||
#endif
|
||||
// clang-format on
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Verify any range within the buffer.
|
||||
bool Verify(const size_t elem, const size_t elem_len) const {
|
||||
// clang-format off
|
||||
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||
auto upper_bound = elem + elem_len;
|
||||
if (upper_bound_ < upper_bound)
|
||||
upper_bound_ = upper_bound;
|
||||
#endif
|
||||
// clang-format on
|
||||
return Check(elem_len < size_ && elem <= size_ - elem_len);
|
||||
}
|
||||
|
||||
bool VerifyAlignment(const size_t elem, const size_t align) const {
|
||||
return Check((elem & (align - 1)) == 0 || !opts_.check_alignment);
|
||||
}
|
||||
|
||||
// Verify a range indicated by sizeof(T).
|
||||
template<typename T> bool Verify(const size_t elem) const {
|
||||
return VerifyAlignment(elem, sizeof(T)) && Verify(elem, sizeof(T));
|
||||
}
|
||||
|
||||
bool VerifyFromPointer(const uint8_t *const p, const size_t len) {
|
||||
return Verify(static_cast<size_t>(p - buf_), len);
|
||||
}
|
||||
|
||||
// Verify relative to a known-good base pointer.
|
||||
bool VerifyFieldStruct(const uint8_t *const base, const voffset_t elem_off,
|
||||
const size_t elem_len, const size_t align) const {
|
||||
const auto f = static_cast<size_t>(base - buf_) + elem_off;
|
||||
return VerifyAlignment(f, align) && Verify(f, elem_len);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool VerifyField(const uint8_t *const base, const voffset_t elem_off,
|
||||
const size_t align) const {
|
||||
const auto f = static_cast<size_t>(base - buf_) + elem_off;
|
||||
return VerifyAlignment(f, align) && Verify(f, sizeof(T));
|
||||
}
|
||||
|
||||
// Verify a pointer (may be NULL) of a table type.
|
||||
template<typename T> bool VerifyTable(const T *const table) {
|
||||
return !table || table->Verify(*this);
|
||||
}
|
||||
|
||||
// Verify a pointer (may be NULL) of any vector type.
|
||||
template<int &..., typename T, typename LenT>
|
||||
bool VerifyVector(const Vector<T, LenT> *const vec) const {
|
||||
return !vec || VerifyVectorOrString<LenT>(
|
||||
reinterpret_cast<const uint8_t *>(vec), sizeof(T));
|
||||
}
|
||||
|
||||
// Verify a pointer (may be NULL) of a vector to struct.
|
||||
template<int &..., typename T, typename LenT>
|
||||
bool VerifyVector(const Vector<const T *, LenT> *const vec) const {
|
||||
return VerifyVector(reinterpret_cast<const Vector<T, LenT> *>(vec));
|
||||
}
|
||||
|
||||
// Verify a pointer (may be NULL) to string.
|
||||
bool VerifyString(const String *const str) const {
|
||||
size_t end;
|
||||
return !str || (VerifyVectorOrString<uoffset_t>(
|
||||
reinterpret_cast<const uint8_t *>(str), 1, &end) &&
|
||||
Verify(end, 1) && // Must have terminator
|
||||
Check(buf_[end] == '\0')); // Terminating byte must be 0.
|
||||
}
|
||||
|
||||
// Common code between vectors and strings.
|
||||
template<typename LenT = uoffset_t>
|
||||
bool VerifyVectorOrString(const uint8_t *const vec, const size_t elem_size,
|
||||
size_t *const end = nullptr) const {
|
||||
const auto vec_offset = static_cast<size_t>(vec - buf_);
|
||||
// Check we can read the size field.
|
||||
if (!Verify<LenT>(vec_offset)) return false;
|
||||
// Check the whole array. If this is a string, the byte past the array must
|
||||
// be 0.
|
||||
const LenT size = ReadScalar<LenT>(vec);
|
||||
const auto max_elems = opts_.max_size / elem_size;
|
||||
if (!Check(size < max_elems))
|
||||
return false; // Protect against byte_size overflowing.
|
||||
const auto byte_size = sizeof(LenT) + elem_size * size;
|
||||
if (end) *end = vec_offset + byte_size;
|
||||
return Verify(vec_offset, byte_size);
|
||||
}
|
||||
|
||||
// Special case for string contents, after the above has been called.
|
||||
bool VerifyVectorOfStrings(const Vector<Offset<String>> *const vec) const {
|
||||
if (vec) {
|
||||
for (uoffset_t i = 0; i < vec->size(); i++) {
|
||||
if (!VerifyString(vec->Get(i))) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Special case for table contents, after the above has been called.
|
||||
template<typename T>
|
||||
bool VerifyVectorOfTables(const Vector<Offset<T>> *const vec) {
|
||||
if (vec) {
|
||||
for (uoffset_t i = 0; i < vec->size(); i++) {
|
||||
if (!vec->Get(i)->Verify(*this)) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
__suppress_ubsan__("unsigned-integer-overflow") bool VerifyTableStart(
|
||||
const uint8_t *const table) {
|
||||
// Check the vtable offset.
|
||||
const auto tableo = static_cast<size_t>(table - buf_);
|
||||
if (!Verify<soffset_t>(tableo)) return false;
|
||||
// This offset may be signed, but doing the subtraction unsigned always
|
||||
// gives the result we want.
|
||||
const auto vtableo =
|
||||
tableo - static_cast<size_t>(ReadScalar<soffset_t>(table));
|
||||
// Check the vtable size field, then check vtable fits in its entirety.
|
||||
if (!(VerifyComplexity() && Verify<voffset_t>(vtableo) &&
|
||||
VerifyAlignment(ReadScalar<voffset_t>(buf_ + vtableo),
|
||||
sizeof(voffset_t))))
|
||||
return false;
|
||||
const auto vsize = ReadScalar<voffset_t>(buf_ + vtableo);
|
||||
return Check((vsize & 1) == 0) && Verify(vtableo, vsize);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool VerifyBufferFromStart(const char *const identifier, const size_t start) {
|
||||
// Buffers have to be of some size to be valid. The reason it is a runtime
|
||||
// check instead of static_assert, is that nested flatbuffers go through
|
||||
// this call and their size is determined at runtime.
|
||||
if (!Check(size_ >= FLATBUFFERS_MIN_BUFFER_SIZE)) return false;
|
||||
|
||||
// If an identifier is provided, check that we have a buffer
|
||||
if (identifier && !Check((size_ >= 2 * sizeof(flatbuffers::uoffset_t) &&
|
||||
BufferHasIdentifier(buf_ + start, identifier)))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Call T::Verify, which must be in the generated code for this type.
|
||||
const auto o = VerifyOffset<uoffset_t>(start);
|
||||
return Check(o != 0) &&
|
||||
reinterpret_cast<const T *>(buf_ + start + o)->Verify(*this)
|
||||
// clang-format off
|
||||
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||
&& GetComputedSize()
|
||||
#endif
|
||||
;
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
template<typename T, int &..., typename SizeT>
|
||||
bool VerifyNestedFlatBuffer(const Vector<uint8_t, SizeT> *const buf,
|
||||
const char *const identifier) {
|
||||
// Caller opted out of this.
|
||||
if (!opts_.check_nested_flatbuffers) return true;
|
||||
|
||||
// An empty buffer is OK as it indicates not present.
|
||||
if (!buf) return true;
|
||||
|
||||
// If there is a nested buffer, it must be greater than the min size.
|
||||
if (!Check(buf->size() >= FLATBUFFERS_MIN_BUFFER_SIZE)) return false;
|
||||
|
||||
Verifier nested_verifier(buf->data(), buf->size(), opts_);
|
||||
return nested_verifier.VerifyBuffer<T>(identifier);
|
||||
}
|
||||
|
||||
// Verify this whole buffer, starting with root type T.
|
||||
template<typename T> bool VerifyBuffer() { return VerifyBuffer<T>(nullptr); }
|
||||
|
||||
template<typename T> bool VerifyBuffer(const char *const identifier) {
|
||||
return VerifyBufferFromStart<T>(identifier, 0);
|
||||
}
|
||||
|
||||
template<typename T, typename SizeT = uoffset_t>
|
||||
bool VerifySizePrefixedBuffer(const char *const identifier) {
|
||||
return Verify<SizeT>(0U) &&
|
||||
Check(ReadScalar<SizeT>(buf_) == size_ - sizeof(SizeT)) &&
|
||||
VerifyBufferFromStart<T>(identifier, sizeof(SizeT));
|
||||
}
|
||||
|
||||
template<typename OffsetT = uoffset_t, typename SOffsetT = soffset_t>
|
||||
size_t VerifyOffset(const size_t start) const {
|
||||
if (!Verify<OffsetT>(start)) return 0;
|
||||
const auto o = ReadScalar<OffsetT>(buf_ + start);
|
||||
// May not point to itself.
|
||||
if (!Check(o != 0)) return 0;
|
||||
// Can't wrap around larger than the max size.
|
||||
if (!Check(static_cast<SOffsetT>(o) >= 0)) return 0;
|
||||
// Must be inside the buffer to create a pointer from it (pointer outside
|
||||
// buffer is UB).
|
||||
if (!Verify(start + o, 1)) return 0;
|
||||
return o;
|
||||
}
|
||||
|
||||
template<typename OffsetT = uoffset_t>
|
||||
size_t VerifyOffset(const uint8_t *const base, const voffset_t start) const {
|
||||
return VerifyOffset<OffsetT>(static_cast<size_t>(base - buf_) + start);
|
||||
}
|
||||
|
||||
// Called at the start of a table to increase counters measuring data
|
||||
// structure depth and amount, and possibly bails out with false if limits set
|
||||
// by the constructor have been hit. Needs to be balanced with EndTable().
|
||||
bool VerifyComplexity() {
|
||||
depth_++;
|
||||
num_tables_++;
|
||||
return Check(depth_ <= opts_.max_depth && num_tables_ <= opts_.max_tables);
|
||||
}
|
||||
|
||||
// Called at the end of a table to pop the depth count.
|
||||
bool EndTable() {
|
||||
depth_--;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns the message size in bytes
|
||||
size_t GetComputedSize() const {
|
||||
// clang-format off
|
||||
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||
uintptr_t size = upper_bound_;
|
||||
// Align the size to uoffset_t
|
||||
size = (size - 1 + sizeof(uoffset_t)) & ~(sizeof(uoffset_t) - 1);
|
||||
return (size > size_) ? 0 : size;
|
||||
#else
|
||||
// Must turn on FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE for this to work.
|
||||
(void)upper_bound_;
|
||||
FLATBUFFERS_ASSERT(false);
|
||||
return 0;
|
||||
#endif
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
std::vector<uint8_t> *GetFlexReuseTracker() { return flex_reuse_tracker_; }
|
||||
|
||||
void SetFlexReuseTracker(std::vector<uint8_t> *const rt) {
|
||||
flex_reuse_tracker_ = rt;
|
||||
}
|
||||
|
||||
private:
|
||||
const uint8_t *buf_;
|
||||
const size_t size_;
|
||||
const Options opts_;
|
||||
|
||||
mutable size_t upper_bound_ = 0;
|
||||
|
||||
uoffset_t depth_ = 0;
|
||||
uoffset_t num_tables_ = 0;
|
||||
std::vector<uint8_t> *flex_reuse_tracker_ = nullptr;
|
||||
};
|
||||
|
||||
// Specialization for 64-bit offsets.
|
||||
template<>
|
||||
inline size_t Verifier::VerifyOffset<uoffset64_t>(const size_t start) const {
|
||||
return VerifyOffset<uoffset64_t, soffset64_t>(start);
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_VERIFIER_H_
|
||||
+6
-14
@@ -2,19 +2,9 @@
|
||||
// File: vk_platform.h
|
||||
//
|
||||
/*
|
||||
** Copyright (c) 2014-2017 The Khronos Group Inc.
|
||||
** Copyright 2014-2023 The Khronos Group Inc.
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -52,7 +42,7 @@ extern "C"
|
||||
#define VKAPI_CALL __stdcall
|
||||
#define VKAPI_PTR VKAPI_CALL
|
||||
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
|
||||
#error "Vulkan isn't supported for the 'armeabi' NDK ABI"
|
||||
#error "Vulkan is not supported for the 'armeabi' NDK ABI"
|
||||
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
|
||||
// On Android 32-bit ARM targets, Vulkan functions use the "hardfloat"
|
||||
// calling convention, i.e. float parameters are passed in registers. This
|
||||
@@ -68,7 +58,9 @@ extern "C"
|
||||
#define VKAPI_PTR
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#if !defined(VK_NO_STDDEF_H)
|
||||
#include <stddef.h>
|
||||
#endif // !defined(VK_NO_STDDEF_H)
|
||||
|
||||
#if !defined(VK_NO_STDINT_H)
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1600)
|
||||
|
||||
Vendored
+34
-18
@@ -2,19 +2,9 @@
|
||||
#define VULKAN_H_ 1
|
||||
|
||||
/*
|
||||
** Copyright (c) 2015-2018 The Khronos Group Inc.
|
||||
** Copyright 2015-2023 The Khronos Group Inc.
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "vk_platform.h"
|
||||
@@ -38,20 +28,16 @@
|
||||
#include "vulkan_macos.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef VK_USE_PLATFORM_MIR_KHR
|
||||
#include <mir_toolkit/client_types.h>
|
||||
#include "vulkan_mir.h"
|
||||
#ifdef VK_USE_PLATFORM_METAL_EXT
|
||||
#include "vulkan_metal.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef VK_USE_PLATFORM_VI_NN
|
||||
#include "vulkan_vi.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#include <wayland-client.h>
|
||||
#include "vulkan_wayland.h"
|
||||
#endif
|
||||
|
||||
@@ -74,10 +60,40 @@
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
|
||||
#include <directfb.h>
|
||||
#include "vulkan_directfb.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include "vulkan_xlib_xrandr.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef VK_USE_PLATFORM_GGP
|
||||
#include <ggp_c/vulkan_types.h>
|
||||
#include "vulkan_ggp.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef VK_USE_PLATFORM_SCREEN_QNX
|
||||
#include <screen/screen.h>
|
||||
#include "vulkan_screen.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef VK_USE_PLATFORM_SCI
|
||||
#include <nvscisync.h>
|
||||
#include <nvscibuf.h>
|
||||
#include "vulkan_sci.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
#include "vulkan_beta.h"
|
||||
#endif
|
||||
|
||||
#endif // VULKAN_H_
|
||||
|
||||
+22
-23
@@ -1,24 +1,10 @@
|
||||
#ifndef VULKAN_ANDROID_H_
|
||||
#define VULKAN_ANDROID_H_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2015-2018 The Khronos Group Inc.
|
||||
** Copyright 2015-2023 The Khronos Group Inc.
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -27,14 +13,17 @@ extern "C" {
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define VK_KHR_android_surface 1
|
||||
struct ANativeWindow;
|
||||
|
||||
#define VK_KHR_ANDROID_SURFACE_SPEC_VERSION 6
|
||||
#define VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "VK_KHR_android_surface"
|
||||
|
||||
typedef VkFlags VkAndroidSurfaceCreateFlagsKHR;
|
||||
|
||||
typedef struct VkAndroidSurfaceCreateInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
@@ -42,7 +31,6 @@ typedef struct VkAndroidSurfaceCreateInfoKHR {
|
||||
struct ANativeWindow* window;
|
||||
} VkAndroidSurfaceCreateInfoKHR;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateAndroidSurfaceKHR)(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
@@ -53,12 +41,11 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR(
|
||||
VkSurfaceKHR* pSurface);
|
||||
#endif
|
||||
|
||||
|
||||
#define VK_ANDROID_external_memory_android_hardware_buffer 1
|
||||
struct AHardwareBuffer;
|
||||
|
||||
#define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION 3
|
||||
#define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION 5
|
||||
#define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME "VK_ANDROID_external_memory_android_hardware_buffer"
|
||||
|
||||
typedef struct VkAndroidHardwareBufferUsageANDROID {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
@@ -103,6 +90,18 @@ typedef struct VkExternalFormatANDROID {
|
||||
uint64_t externalFormat;
|
||||
} VkExternalFormatANDROID;
|
||||
|
||||
typedef struct VkAndroidHardwareBufferFormatProperties2ANDROID {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkFormat format;
|
||||
uint64_t externalFormat;
|
||||
VkFormatFeatureFlags2 formatFeatures;
|
||||
VkComponentMapping samplerYcbcrConversionComponents;
|
||||
VkSamplerYcbcrModelConversion suggestedYcbcrModel;
|
||||
VkSamplerYcbcrRange suggestedYcbcrRange;
|
||||
VkChromaLocation suggestedXChromaOffset;
|
||||
VkChromaLocation suggestedYChromaOffset;
|
||||
} VkAndroidHardwareBufferFormatProperties2ANDROID;
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetAndroidHardwareBufferPropertiesANDROID)(VkDevice device, const struct AHardwareBuffer* buffer, VkAndroidHardwareBufferPropertiesANDROID* pProperties);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryAndroidHardwareBufferANDROID)(VkDevice device, const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo, struct AHardwareBuffer** pBuffer);
|
||||
|
||||
+492
@@ -0,0 +1,492 @@
|
||||
#ifndef VULKAN_BETA_H_
|
||||
#define VULKAN_BETA_H_ 1
|
||||
|
||||
/*
|
||||
** Copyright 2015-2023 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
** This header is generated from the Khronos Vulkan XML API Registry.
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define VK_KHR_portability_subset 1
|
||||
#define VK_KHR_PORTABILITY_SUBSET_SPEC_VERSION 1
|
||||
#define VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME "VK_KHR_portability_subset"
|
||||
typedef struct VkPhysicalDevicePortabilitySubsetFeaturesKHR {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkBool32 constantAlphaColorBlendFactors;
|
||||
VkBool32 events;
|
||||
VkBool32 imageViewFormatReinterpretation;
|
||||
VkBool32 imageViewFormatSwizzle;
|
||||
VkBool32 imageView2DOn3DImage;
|
||||
VkBool32 multisampleArrayImage;
|
||||
VkBool32 mutableComparisonSamplers;
|
||||
VkBool32 pointPolygons;
|
||||
VkBool32 samplerMipLodBias;
|
||||
VkBool32 separateStencilMaskRef;
|
||||
VkBool32 shaderSampleRateInterpolationFunctions;
|
||||
VkBool32 tessellationIsolines;
|
||||
VkBool32 tessellationPointMode;
|
||||
VkBool32 triangleFans;
|
||||
VkBool32 vertexAttributeAccessBeyondStride;
|
||||
} VkPhysicalDevicePortabilitySubsetFeaturesKHR;
|
||||
|
||||
typedef struct VkPhysicalDevicePortabilitySubsetPropertiesKHR {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
uint32_t minVertexInputBindingStrideAlignment;
|
||||
} VkPhysicalDevicePortabilitySubsetPropertiesKHR;
|
||||
|
||||
|
||||
|
||||
#define VK_KHR_video_encode_queue 1
|
||||
#define VK_KHR_VIDEO_ENCODE_QUEUE_SPEC_VERSION 8
|
||||
#define VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME "VK_KHR_video_encode_queue"
|
||||
|
||||
typedef enum VkVideoEncodeTuningModeKHR {
|
||||
VK_VIDEO_ENCODE_TUNING_MODE_DEFAULT_KHR = 0,
|
||||
VK_VIDEO_ENCODE_TUNING_MODE_HIGH_QUALITY_KHR = 1,
|
||||
VK_VIDEO_ENCODE_TUNING_MODE_LOW_LATENCY_KHR = 2,
|
||||
VK_VIDEO_ENCODE_TUNING_MODE_ULTRA_LOW_LATENCY_KHR = 3,
|
||||
VK_VIDEO_ENCODE_TUNING_MODE_LOSSLESS_KHR = 4,
|
||||
VK_VIDEO_ENCODE_TUNING_MODE_MAX_ENUM_KHR = 0x7FFFFFFF
|
||||
} VkVideoEncodeTuningModeKHR;
|
||||
typedef VkFlags VkVideoEncodeFlagsKHR;
|
||||
|
||||
typedef enum VkVideoEncodeCapabilityFlagBitsKHR {
|
||||
VK_VIDEO_ENCODE_CAPABILITY_PRECEDING_EXTERNALLY_ENCODED_BYTES_BIT_KHR = 0x00000001,
|
||||
VK_VIDEO_ENCODE_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
|
||||
} VkVideoEncodeCapabilityFlagBitsKHR;
|
||||
typedef VkFlags VkVideoEncodeCapabilityFlagsKHR;
|
||||
|
||||
typedef enum VkVideoEncodeRateControlModeFlagBitsKHR {
|
||||
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR = 0,
|
||||
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR = 0x00000001,
|
||||
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR = 0x00000002,
|
||||
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR = 0x00000004,
|
||||
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
|
||||
} VkVideoEncodeRateControlModeFlagBitsKHR;
|
||||
typedef VkFlags VkVideoEncodeRateControlModeFlagsKHR;
|
||||
|
||||
typedef enum VkVideoEncodeFeedbackFlagBitsKHR {
|
||||
VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR = 0x00000001,
|
||||
VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR = 0x00000002,
|
||||
VK_VIDEO_ENCODE_FEEDBACK_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
|
||||
} VkVideoEncodeFeedbackFlagBitsKHR;
|
||||
typedef VkFlags VkVideoEncodeFeedbackFlagsKHR;
|
||||
|
||||
typedef enum VkVideoEncodeUsageFlagBitsKHR {
|
||||
VK_VIDEO_ENCODE_USAGE_DEFAULT_KHR = 0,
|
||||
VK_VIDEO_ENCODE_USAGE_TRANSCODING_BIT_KHR = 0x00000001,
|
||||
VK_VIDEO_ENCODE_USAGE_STREAMING_BIT_KHR = 0x00000002,
|
||||
VK_VIDEO_ENCODE_USAGE_RECORDING_BIT_KHR = 0x00000004,
|
||||
VK_VIDEO_ENCODE_USAGE_CONFERENCING_BIT_KHR = 0x00000008,
|
||||
VK_VIDEO_ENCODE_USAGE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
|
||||
} VkVideoEncodeUsageFlagBitsKHR;
|
||||
typedef VkFlags VkVideoEncodeUsageFlagsKHR;
|
||||
|
||||
typedef enum VkVideoEncodeContentFlagBitsKHR {
|
||||
VK_VIDEO_ENCODE_CONTENT_DEFAULT_KHR = 0,
|
||||
VK_VIDEO_ENCODE_CONTENT_CAMERA_BIT_KHR = 0x00000001,
|
||||
VK_VIDEO_ENCODE_CONTENT_DESKTOP_BIT_KHR = 0x00000002,
|
||||
VK_VIDEO_ENCODE_CONTENT_RENDERED_BIT_KHR = 0x00000004,
|
||||
VK_VIDEO_ENCODE_CONTENT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
|
||||
} VkVideoEncodeContentFlagBitsKHR;
|
||||
typedef VkFlags VkVideoEncodeContentFlagsKHR;
|
||||
typedef VkFlags VkVideoEncodeRateControlFlagsKHR;
|
||||
typedef struct VkVideoEncodeInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkVideoEncodeFlagsKHR flags;
|
||||
uint32_t qualityLevel;
|
||||
VkBuffer dstBuffer;
|
||||
VkDeviceSize dstBufferOffset;
|
||||
VkDeviceSize dstBufferRange;
|
||||
VkVideoPictureResourceInfoKHR srcPictureResource;
|
||||
const VkVideoReferenceSlotInfoKHR* pSetupReferenceSlot;
|
||||
uint32_t referenceSlotCount;
|
||||
const VkVideoReferenceSlotInfoKHR* pReferenceSlots;
|
||||
uint32_t precedingExternallyEncodedBytes;
|
||||
} VkVideoEncodeInfoKHR;
|
||||
|
||||
typedef struct VkVideoEncodeCapabilitiesKHR {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkVideoEncodeCapabilityFlagsKHR flags;
|
||||
VkVideoEncodeRateControlModeFlagsKHR rateControlModes;
|
||||
uint32_t maxRateControlLayers;
|
||||
uint32_t maxQualityLevels;
|
||||
VkExtent2D inputImageDataFillAlignment;
|
||||
VkVideoEncodeFeedbackFlagsKHR supportedEncodeFeedbackFlags;
|
||||
} VkVideoEncodeCapabilitiesKHR;
|
||||
|
||||
typedef struct VkQueryPoolVideoEncodeFeedbackCreateInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkVideoEncodeFeedbackFlagsKHR encodeFeedbackFlags;
|
||||
} VkQueryPoolVideoEncodeFeedbackCreateInfoKHR;
|
||||
|
||||
typedef struct VkVideoEncodeUsageInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkVideoEncodeUsageFlagsKHR videoUsageHints;
|
||||
VkVideoEncodeContentFlagsKHR videoContentHints;
|
||||
VkVideoEncodeTuningModeKHR tuningMode;
|
||||
} VkVideoEncodeUsageInfoKHR;
|
||||
|
||||
typedef struct VkVideoEncodeRateControlLayerInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint64_t averageBitrate;
|
||||
uint64_t maxBitrate;
|
||||
uint32_t frameRateNumerator;
|
||||
uint32_t frameRateDenominator;
|
||||
uint32_t virtualBufferSizeInMs;
|
||||
uint32_t initialVirtualBufferSizeInMs;
|
||||
} VkVideoEncodeRateControlLayerInfoKHR;
|
||||
|
||||
typedef struct VkVideoEncodeRateControlInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkVideoEncodeRateControlFlagsKHR flags;
|
||||
VkVideoEncodeRateControlModeFlagBitsKHR rateControlMode;
|
||||
uint32_t layerCount;
|
||||
const VkVideoEncodeRateControlLayerInfoKHR* pLayers;
|
||||
} VkVideoEncodeRateControlInfoKHR;
|
||||
|
||||
typedef void (VKAPI_PTR *PFN_vkCmdEncodeVideoKHR)(VkCommandBuffer commandBuffer, const VkVideoEncodeInfoKHR* pEncodeInfo);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR void VKAPI_CALL vkCmdEncodeVideoKHR(
|
||||
VkCommandBuffer commandBuffer,
|
||||
const VkVideoEncodeInfoKHR* pEncodeInfo);
|
||||
#endif
|
||||
|
||||
|
||||
#define VK_EXT_video_encode_h264 1
|
||||
#include "vk_video/vulkan_video_codec_h264std.h"
|
||||
#include "vk_video/vulkan_video_codec_h264std_encode.h"
|
||||
#define VK_EXT_VIDEO_ENCODE_H264_SPEC_VERSION 10
|
||||
#define VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME "VK_EXT_video_encode_h264"
|
||||
|
||||
typedef enum VkVideoEncodeH264RateControlStructureEXT {
|
||||
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_UNKNOWN_EXT = 0,
|
||||
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_FLAT_EXT = 1,
|
||||
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_DYADIC_EXT = 2,
|
||||
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_MAX_ENUM_EXT = 0x7FFFFFFF
|
||||
} VkVideoEncodeH264RateControlStructureEXT;
|
||||
|
||||
typedef enum VkVideoEncodeH264CapabilityFlagBitsEXT {
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_DIRECT_8X8_INFERENCE_ENABLED_BIT_EXT = 0x00000001,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_DIRECT_8X8_INFERENCE_DISABLED_BIT_EXT = 0x00000002,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_SEPARATE_COLOUR_PLANE_BIT_EXT = 0x00000004,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_QPPRIME_Y_ZERO_TRANSFORM_BYPASS_BIT_EXT = 0x00000008,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_SCALING_LISTS_BIT_EXT = 0x00000010,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_HRD_COMPLIANCE_BIT_EXT = 0x00000020,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_CHROMA_QP_OFFSET_BIT_EXT = 0x00000040,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_SECOND_CHROMA_QP_OFFSET_BIT_EXT = 0x00000080,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_PIC_INIT_QP_MINUS26_BIT_EXT = 0x00000100,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_PRED_BIT_EXT = 0x00000200,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BIPRED_EXPLICIT_BIT_EXT = 0x00000400,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BIPRED_IMPLICIT_BIT_EXT = 0x00000800,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_PRED_NO_TABLE_BIT_EXT = 0x00001000,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_TRANSFORM_8X8_BIT_EXT = 0x00002000,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_CABAC_BIT_EXT = 0x00004000,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_CAVLC_BIT_EXT = 0x00008000,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_DISABLED_BIT_EXT = 0x00010000,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_ENABLED_BIT_EXT = 0x00020000,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_PARTIAL_BIT_EXT = 0x00040000,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_DISABLE_DIRECT_SPATIAL_MV_PRED_BIT_EXT = 0x00080000,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_MULTIPLE_SLICE_PER_FRAME_BIT_EXT = 0x00100000,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_SLICE_MB_COUNT_BIT_EXT = 0x00200000,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_ROW_UNALIGNED_SLICE_BIT_EXT = 0x00400000,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_DIFFERENT_SLICE_TYPE_BIT_EXT = 0x00800000,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_B_FRAME_IN_L1_LIST_BIT_EXT = 0x01000000,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_DIFFERENT_REFERENCE_FINAL_LISTS_BIT_EXT = 0x02000000,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
|
||||
} VkVideoEncodeH264CapabilityFlagBitsEXT;
|
||||
typedef VkFlags VkVideoEncodeH264CapabilityFlagsEXT;
|
||||
typedef struct VkVideoEncodeH264CapabilitiesEXT {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkVideoEncodeH264CapabilityFlagsEXT flags;
|
||||
uint32_t maxPPictureL0ReferenceCount;
|
||||
uint32_t maxBPictureL0ReferenceCount;
|
||||
uint32_t maxL1ReferenceCount;
|
||||
VkBool32 motionVectorsOverPicBoundariesFlag;
|
||||
uint32_t maxBytesPerPicDenom;
|
||||
uint32_t maxBitsPerMbDenom;
|
||||
uint32_t log2MaxMvLengthHorizontal;
|
||||
uint32_t log2MaxMvLengthVertical;
|
||||
} VkVideoEncodeH264CapabilitiesEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH264SessionParametersAddInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t stdSPSCount;
|
||||
const StdVideoH264SequenceParameterSet* pStdSPSs;
|
||||
uint32_t stdPPSCount;
|
||||
const StdVideoH264PictureParameterSet* pStdPPSs;
|
||||
} VkVideoEncodeH264SessionParametersAddInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH264SessionParametersCreateInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t maxStdSPSCount;
|
||||
uint32_t maxStdPPSCount;
|
||||
const VkVideoEncodeH264SessionParametersAddInfoEXT* pParametersAddInfo;
|
||||
} VkVideoEncodeH264SessionParametersCreateInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH264NaluSliceInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t mbCount;
|
||||
const StdVideoEncodeH264ReferenceListsInfo* pStdReferenceFinalLists;
|
||||
const StdVideoEncodeH264SliceHeader* pStdSliceHeader;
|
||||
} VkVideoEncodeH264NaluSliceInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH264VclFrameInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
const StdVideoEncodeH264ReferenceListsInfo* pStdReferenceFinalLists;
|
||||
uint32_t naluSliceEntryCount;
|
||||
const VkVideoEncodeH264NaluSliceInfoEXT* pNaluSliceEntries;
|
||||
const StdVideoEncodeH264PictureInfo* pStdPictureInfo;
|
||||
} VkVideoEncodeH264VclFrameInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH264DpbSlotInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
const StdVideoEncodeH264ReferenceInfo* pStdReferenceInfo;
|
||||
} VkVideoEncodeH264DpbSlotInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH264ProfileInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
StdVideoH264ProfileIdc stdProfileIdc;
|
||||
} VkVideoEncodeH264ProfileInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH264RateControlInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t gopFrameCount;
|
||||
uint32_t idrPeriod;
|
||||
uint32_t consecutiveBFrameCount;
|
||||
VkVideoEncodeH264RateControlStructureEXT rateControlStructure;
|
||||
uint32_t temporalLayerCount;
|
||||
} VkVideoEncodeH264RateControlInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH264QpEXT {
|
||||
int32_t qpI;
|
||||
int32_t qpP;
|
||||
int32_t qpB;
|
||||
} VkVideoEncodeH264QpEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH264FrameSizeEXT {
|
||||
uint32_t frameISize;
|
||||
uint32_t framePSize;
|
||||
uint32_t frameBSize;
|
||||
} VkVideoEncodeH264FrameSizeEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH264RateControlLayerInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t temporalLayerId;
|
||||
VkBool32 useInitialRcQp;
|
||||
VkVideoEncodeH264QpEXT initialRcQp;
|
||||
VkBool32 useMinQp;
|
||||
VkVideoEncodeH264QpEXT minQp;
|
||||
VkBool32 useMaxQp;
|
||||
VkVideoEncodeH264QpEXT maxQp;
|
||||
VkBool32 useMaxFrameSize;
|
||||
VkVideoEncodeH264FrameSizeEXT maxFrameSize;
|
||||
} VkVideoEncodeH264RateControlLayerInfoEXT;
|
||||
|
||||
|
||||
|
||||
#define VK_EXT_video_encode_h265 1
|
||||
#include "vk_video/vulkan_video_codec_h265std.h"
|
||||
#include "vk_video/vulkan_video_codec_h265std_encode.h"
|
||||
#define VK_EXT_VIDEO_ENCODE_H265_SPEC_VERSION 10
|
||||
#define VK_EXT_VIDEO_ENCODE_H265_EXTENSION_NAME "VK_EXT_video_encode_h265"
|
||||
|
||||
typedef enum VkVideoEncodeH265RateControlStructureEXT {
|
||||
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_UNKNOWN_EXT = 0,
|
||||
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_FLAT_EXT = 1,
|
||||
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_DYADIC_EXT = 2,
|
||||
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_MAX_ENUM_EXT = 0x7FFFFFFF
|
||||
} VkVideoEncodeH265RateControlStructureEXT;
|
||||
|
||||
typedef enum VkVideoEncodeH265CapabilityFlagBitsEXT {
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_SEPARATE_COLOUR_PLANE_BIT_EXT = 0x00000001,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_SCALING_LISTS_BIT_EXT = 0x00000002,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_SAMPLE_ADAPTIVE_OFFSET_ENABLED_BIT_EXT = 0x00000004,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_PCM_ENABLE_BIT_EXT = 0x00000008,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_SPS_TEMPORAL_MVP_ENABLED_BIT_EXT = 0x00000010,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_HRD_COMPLIANCE_BIT_EXT = 0x00000020,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_INIT_QP_MINUS26_BIT_EXT = 0x00000040,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_LOG2_PARALLEL_MERGE_LEVEL_MINUS2_BIT_EXT = 0x00000080,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_SIGN_DATA_HIDING_ENABLED_BIT_EXT = 0x00000100,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_TRANSFORM_SKIP_ENABLED_BIT_EXT = 0x00000200,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_TRANSFORM_SKIP_DISABLED_BIT_EXT = 0x00000400,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT_BIT_EXT = 0x00000800,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_WEIGHTED_PRED_BIT_EXT = 0x00001000,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_WEIGHTED_BIPRED_BIT_EXT = 0x00002000,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_WEIGHTED_PRED_NO_TABLE_BIT_EXT = 0x00004000,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_TRANSQUANT_BYPASS_ENABLED_BIT_EXT = 0x00008000,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_ENTROPY_CODING_SYNC_ENABLED_BIT_EXT = 0x00010000,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_DEBLOCKING_FILTER_OVERRIDE_ENABLED_BIT_EXT = 0x00020000,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_TILE_PER_FRAME_BIT_EXT = 0x00040000,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_SLICE_PER_TILE_BIT_EXT = 0x00080000,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_TILE_PER_SLICE_BIT_EXT = 0x00100000,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_SLICE_SEGMENT_CTB_COUNT_BIT_EXT = 0x00200000,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_ROW_UNALIGNED_SLICE_SEGMENT_BIT_EXT = 0x00400000,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_DEPENDENT_SLICE_SEGMENT_BIT_EXT = 0x00800000,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_DIFFERENT_SLICE_TYPE_BIT_EXT = 0x01000000,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_B_FRAME_IN_L1_LIST_BIT_EXT = 0x02000000,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_DIFFERENT_REFERENCE_FINAL_LISTS_BIT_EXT = 0x04000000,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
|
||||
} VkVideoEncodeH265CapabilityFlagBitsEXT;
|
||||
typedef VkFlags VkVideoEncodeH265CapabilityFlagsEXT;
|
||||
|
||||
typedef enum VkVideoEncodeH265CtbSizeFlagBitsEXT {
|
||||
VK_VIDEO_ENCODE_H265_CTB_SIZE_16_BIT_EXT = 0x00000001,
|
||||
VK_VIDEO_ENCODE_H265_CTB_SIZE_32_BIT_EXT = 0x00000002,
|
||||
VK_VIDEO_ENCODE_H265_CTB_SIZE_64_BIT_EXT = 0x00000004,
|
||||
VK_VIDEO_ENCODE_H265_CTB_SIZE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
|
||||
} VkVideoEncodeH265CtbSizeFlagBitsEXT;
|
||||
typedef VkFlags VkVideoEncodeH265CtbSizeFlagsEXT;
|
||||
|
||||
typedef enum VkVideoEncodeH265TransformBlockSizeFlagBitsEXT {
|
||||
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_4_BIT_EXT = 0x00000001,
|
||||
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_8_BIT_EXT = 0x00000002,
|
||||
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_16_BIT_EXT = 0x00000004,
|
||||
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_32_BIT_EXT = 0x00000008,
|
||||
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
|
||||
} VkVideoEncodeH265TransformBlockSizeFlagBitsEXT;
|
||||
typedef VkFlags VkVideoEncodeH265TransformBlockSizeFlagsEXT;
|
||||
typedef struct VkVideoEncodeH265CapabilitiesEXT {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkVideoEncodeH265CapabilityFlagsEXT flags;
|
||||
VkVideoEncodeH265CtbSizeFlagsEXT ctbSizes;
|
||||
VkVideoEncodeH265TransformBlockSizeFlagsEXT transformBlockSizes;
|
||||
uint32_t maxPPictureL0ReferenceCount;
|
||||
uint32_t maxBPictureL0ReferenceCount;
|
||||
uint32_t maxL1ReferenceCount;
|
||||
uint32_t maxSubLayersCount;
|
||||
uint32_t minLog2MinLumaCodingBlockSizeMinus3;
|
||||
uint32_t maxLog2MinLumaCodingBlockSizeMinus3;
|
||||
uint32_t minLog2MinLumaTransformBlockSizeMinus2;
|
||||
uint32_t maxLog2MinLumaTransformBlockSizeMinus2;
|
||||
uint32_t minMaxTransformHierarchyDepthInter;
|
||||
uint32_t maxMaxTransformHierarchyDepthInter;
|
||||
uint32_t minMaxTransformHierarchyDepthIntra;
|
||||
uint32_t maxMaxTransformHierarchyDepthIntra;
|
||||
uint32_t maxDiffCuQpDeltaDepth;
|
||||
uint32_t minMaxNumMergeCand;
|
||||
uint32_t maxMaxNumMergeCand;
|
||||
} VkVideoEncodeH265CapabilitiesEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH265SessionParametersAddInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t stdVPSCount;
|
||||
const StdVideoH265VideoParameterSet* pStdVPSs;
|
||||
uint32_t stdSPSCount;
|
||||
const StdVideoH265SequenceParameterSet* pStdSPSs;
|
||||
uint32_t stdPPSCount;
|
||||
const StdVideoH265PictureParameterSet* pStdPPSs;
|
||||
} VkVideoEncodeH265SessionParametersAddInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH265SessionParametersCreateInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t maxStdVPSCount;
|
||||
uint32_t maxStdSPSCount;
|
||||
uint32_t maxStdPPSCount;
|
||||
const VkVideoEncodeH265SessionParametersAddInfoEXT* pParametersAddInfo;
|
||||
} VkVideoEncodeH265SessionParametersCreateInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH265NaluSliceSegmentInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t ctbCount;
|
||||
const StdVideoEncodeH265ReferenceListsInfo* pStdReferenceFinalLists;
|
||||
const StdVideoEncodeH265SliceSegmentHeader* pStdSliceSegmentHeader;
|
||||
} VkVideoEncodeH265NaluSliceSegmentInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH265VclFrameInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
const StdVideoEncodeH265ReferenceListsInfo* pStdReferenceFinalLists;
|
||||
uint32_t naluSliceSegmentEntryCount;
|
||||
const VkVideoEncodeH265NaluSliceSegmentInfoEXT* pNaluSliceSegmentEntries;
|
||||
const StdVideoEncodeH265PictureInfo* pStdPictureInfo;
|
||||
} VkVideoEncodeH265VclFrameInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH265DpbSlotInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
const StdVideoEncodeH265ReferenceInfo* pStdReferenceInfo;
|
||||
} VkVideoEncodeH265DpbSlotInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH265ProfileInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
StdVideoH265ProfileIdc stdProfileIdc;
|
||||
} VkVideoEncodeH265ProfileInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH265RateControlInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t gopFrameCount;
|
||||
uint32_t idrPeriod;
|
||||
uint32_t consecutiveBFrameCount;
|
||||
VkVideoEncodeH265RateControlStructureEXT rateControlStructure;
|
||||
uint32_t subLayerCount;
|
||||
} VkVideoEncodeH265RateControlInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH265QpEXT {
|
||||
int32_t qpI;
|
||||
int32_t qpP;
|
||||
int32_t qpB;
|
||||
} VkVideoEncodeH265QpEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH265FrameSizeEXT {
|
||||
uint32_t frameISize;
|
||||
uint32_t framePSize;
|
||||
uint32_t frameBSize;
|
||||
} VkVideoEncodeH265FrameSizeEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH265RateControlLayerInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t temporalId;
|
||||
VkBool32 useInitialRcQp;
|
||||
VkVideoEncodeH265QpEXT initialRcQp;
|
||||
VkBool32 useMinQp;
|
||||
VkVideoEncodeH265QpEXT minQp;
|
||||
VkBool32 useMaxQp;
|
||||
VkVideoEncodeH265QpEXT maxQp;
|
||||
VkBool32 useMaxFrameSize;
|
||||
VkVideoEncodeH265FrameSizeEXT maxFrameSize;
|
||||
} VkVideoEncodeH265RateControlLayerInfoEXT;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+10286
-1804
File diff suppressed because it is too large
Load Diff
+54
@@ -0,0 +1,54 @@
|
||||
#ifndef VULKAN_DIRECTFB_H_
|
||||
#define VULKAN_DIRECTFB_H_ 1
|
||||
|
||||
/*
|
||||
** Copyright 2015-2023 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
** This header is generated from the Khronos Vulkan XML API Registry.
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define VK_EXT_directfb_surface 1
|
||||
#define VK_EXT_DIRECTFB_SURFACE_SPEC_VERSION 1
|
||||
#define VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME "VK_EXT_directfb_surface"
|
||||
typedef VkFlags VkDirectFBSurfaceCreateFlagsEXT;
|
||||
typedef struct VkDirectFBSurfaceCreateInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkDirectFBSurfaceCreateFlagsEXT flags;
|
||||
IDirectFB* dfb;
|
||||
IDirectFBSurface* surface;
|
||||
} VkDirectFBSurfaceCreateInfoEXT;
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateDirectFBSurfaceEXT)(VkInstance instance, const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, IDirectFB* dfb);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDirectFBSurfaceEXT(
|
||||
VkInstance instance,
|
||||
const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSurfaceKHR* pSurface);
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceDirectFBPresentationSupportEXT(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
uint32_t queueFamilyIndex,
|
||||
IDirectFB* dfb);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+219
-19
@@ -1,24 +1,10 @@
|
||||
#ifndef VULKAN_FUCHSIA_H_
|
||||
#define VULKAN_FUCHSIA_H_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2015-2018 The Khronos Group Inc.
|
||||
** Copyright 2015-2023 The Khronos Group Inc.
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -27,12 +13,16 @@ extern "C" {
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define VK_FUCHSIA_imagepipe_surface 1
|
||||
#define VK_FUCHSIA_IMAGEPIPE_SURFACE_SPEC_VERSION 1
|
||||
#define VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME "VK_FUCHSIA_imagepipe_surface"
|
||||
|
||||
typedef VkFlags VkImagePipeSurfaceCreateFlagsFUCHSIA;
|
||||
|
||||
typedef struct VkImagePipeSurfaceCreateInfoFUCHSIA {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
@@ -40,7 +30,6 @@ typedef struct VkImagePipeSurfaceCreateInfoFUCHSIA {
|
||||
zx_handle_t imagePipeHandle;
|
||||
} VkImagePipeSurfaceCreateInfoFUCHSIA;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateImagePipeSurfaceFUCHSIA)(VkInstance instance, const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
@@ -51,6 +40,217 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateImagePipeSurfaceFUCHSIA(
|
||||
VkSurfaceKHR* pSurface);
|
||||
#endif
|
||||
|
||||
|
||||
#define VK_FUCHSIA_external_memory 1
|
||||
#define VK_FUCHSIA_EXTERNAL_MEMORY_SPEC_VERSION 1
|
||||
#define VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME "VK_FUCHSIA_external_memory"
|
||||
typedef struct VkImportMemoryZirconHandleInfoFUCHSIA {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkExternalMemoryHandleTypeFlagBits handleType;
|
||||
zx_handle_t handle;
|
||||
} VkImportMemoryZirconHandleInfoFUCHSIA;
|
||||
|
||||
typedef struct VkMemoryZirconHandlePropertiesFUCHSIA {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
uint32_t memoryTypeBits;
|
||||
} VkMemoryZirconHandlePropertiesFUCHSIA;
|
||||
|
||||
typedef struct VkMemoryGetZirconHandleInfoFUCHSIA {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkDeviceMemory memory;
|
||||
VkExternalMemoryHandleTypeFlagBits handleType;
|
||||
} VkMemoryGetZirconHandleInfoFUCHSIA;
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryZirconHandleFUCHSIA)(VkDevice device, const VkMemoryGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, zx_handle_t* pZirconHandle);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, zx_handle_t zirconHandle, VkMemoryZirconHandlePropertiesFUCHSIA* pMemoryZirconHandleProperties);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryZirconHandleFUCHSIA(
|
||||
VkDevice device,
|
||||
const VkMemoryGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo,
|
||||
zx_handle_t* pZirconHandle);
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryZirconHandlePropertiesFUCHSIA(
|
||||
VkDevice device,
|
||||
VkExternalMemoryHandleTypeFlagBits handleType,
|
||||
zx_handle_t zirconHandle,
|
||||
VkMemoryZirconHandlePropertiesFUCHSIA* pMemoryZirconHandleProperties);
|
||||
#endif
|
||||
|
||||
|
||||
#define VK_FUCHSIA_external_semaphore 1
|
||||
#define VK_FUCHSIA_EXTERNAL_SEMAPHORE_SPEC_VERSION 1
|
||||
#define VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME "VK_FUCHSIA_external_semaphore"
|
||||
typedef struct VkImportSemaphoreZirconHandleInfoFUCHSIA {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkSemaphore semaphore;
|
||||
VkSemaphoreImportFlags flags;
|
||||
VkExternalSemaphoreHandleTypeFlagBits handleType;
|
||||
zx_handle_t zirconHandle;
|
||||
} VkImportSemaphoreZirconHandleInfoFUCHSIA;
|
||||
|
||||
typedef struct VkSemaphoreGetZirconHandleInfoFUCHSIA {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkSemaphore semaphore;
|
||||
VkExternalSemaphoreHandleTypeFlagBits handleType;
|
||||
} VkSemaphoreGetZirconHandleInfoFUCHSIA;
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreZirconHandleFUCHSIA)(VkDevice device, const VkImportSemaphoreZirconHandleInfoFUCHSIA* pImportSemaphoreZirconHandleInfo);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreZirconHandleFUCHSIA)(VkDevice device, const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, zx_handle_t* pZirconHandle);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreZirconHandleFUCHSIA(
|
||||
VkDevice device,
|
||||
const VkImportSemaphoreZirconHandleInfoFUCHSIA* pImportSemaphoreZirconHandleInfo);
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreZirconHandleFUCHSIA(
|
||||
VkDevice device,
|
||||
const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo,
|
||||
zx_handle_t* pZirconHandle);
|
||||
#endif
|
||||
|
||||
|
||||
#define VK_FUCHSIA_buffer_collection 1
|
||||
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferCollectionFUCHSIA)
|
||||
#define VK_FUCHSIA_BUFFER_COLLECTION_SPEC_VERSION 2
|
||||
#define VK_FUCHSIA_BUFFER_COLLECTION_EXTENSION_NAME "VK_FUCHSIA_buffer_collection"
|
||||
typedef VkFlags VkImageFormatConstraintsFlagsFUCHSIA;
|
||||
|
||||
typedef enum VkImageConstraintsInfoFlagBitsFUCHSIA {
|
||||
VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_RARELY_FUCHSIA = 0x00000001,
|
||||
VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_OFTEN_FUCHSIA = 0x00000002,
|
||||
VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_RARELY_FUCHSIA = 0x00000004,
|
||||
VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_OFTEN_FUCHSIA = 0x00000008,
|
||||
VK_IMAGE_CONSTRAINTS_INFO_PROTECTED_OPTIONAL_FUCHSIA = 0x00000010,
|
||||
VK_IMAGE_CONSTRAINTS_INFO_FLAG_BITS_MAX_ENUM_FUCHSIA = 0x7FFFFFFF
|
||||
} VkImageConstraintsInfoFlagBitsFUCHSIA;
|
||||
typedef VkFlags VkImageConstraintsInfoFlagsFUCHSIA;
|
||||
typedef struct VkBufferCollectionCreateInfoFUCHSIA {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
zx_handle_t collectionToken;
|
||||
} VkBufferCollectionCreateInfoFUCHSIA;
|
||||
|
||||
typedef struct VkImportMemoryBufferCollectionFUCHSIA {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkBufferCollectionFUCHSIA collection;
|
||||
uint32_t index;
|
||||
} VkImportMemoryBufferCollectionFUCHSIA;
|
||||
|
||||
typedef struct VkBufferCollectionImageCreateInfoFUCHSIA {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkBufferCollectionFUCHSIA collection;
|
||||
uint32_t index;
|
||||
} VkBufferCollectionImageCreateInfoFUCHSIA;
|
||||
|
||||
typedef struct VkBufferCollectionConstraintsInfoFUCHSIA {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t minBufferCount;
|
||||
uint32_t maxBufferCount;
|
||||
uint32_t minBufferCountForCamping;
|
||||
uint32_t minBufferCountForDedicatedSlack;
|
||||
uint32_t minBufferCountForSharedSlack;
|
||||
} VkBufferCollectionConstraintsInfoFUCHSIA;
|
||||
|
||||
typedef struct VkBufferConstraintsInfoFUCHSIA {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkBufferCreateInfo createInfo;
|
||||
VkFormatFeatureFlags requiredFormatFeatures;
|
||||
VkBufferCollectionConstraintsInfoFUCHSIA bufferCollectionConstraints;
|
||||
} VkBufferConstraintsInfoFUCHSIA;
|
||||
|
||||
typedef struct VkBufferCollectionBufferCreateInfoFUCHSIA {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkBufferCollectionFUCHSIA collection;
|
||||
uint32_t index;
|
||||
} VkBufferCollectionBufferCreateInfoFUCHSIA;
|
||||
|
||||
typedef struct VkSysmemColorSpaceFUCHSIA {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t colorSpace;
|
||||
} VkSysmemColorSpaceFUCHSIA;
|
||||
|
||||
typedef struct VkBufferCollectionPropertiesFUCHSIA {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
uint32_t memoryTypeBits;
|
||||
uint32_t bufferCount;
|
||||
uint32_t createInfoIndex;
|
||||
uint64_t sysmemPixelFormat;
|
||||
VkFormatFeatureFlags formatFeatures;
|
||||
VkSysmemColorSpaceFUCHSIA sysmemColorSpaceIndex;
|
||||
VkComponentMapping samplerYcbcrConversionComponents;
|
||||
VkSamplerYcbcrModelConversion suggestedYcbcrModel;
|
||||
VkSamplerYcbcrRange suggestedYcbcrRange;
|
||||
VkChromaLocation suggestedXChromaOffset;
|
||||
VkChromaLocation suggestedYChromaOffset;
|
||||
} VkBufferCollectionPropertiesFUCHSIA;
|
||||
|
||||
typedef struct VkImageFormatConstraintsInfoFUCHSIA {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkImageCreateInfo imageCreateInfo;
|
||||
VkFormatFeatureFlags requiredFormatFeatures;
|
||||
VkImageFormatConstraintsFlagsFUCHSIA flags;
|
||||
uint64_t sysmemPixelFormat;
|
||||
uint32_t colorSpaceCount;
|
||||
const VkSysmemColorSpaceFUCHSIA* pColorSpaces;
|
||||
} VkImageFormatConstraintsInfoFUCHSIA;
|
||||
|
||||
typedef struct VkImageConstraintsInfoFUCHSIA {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t formatConstraintsCount;
|
||||
const VkImageFormatConstraintsInfoFUCHSIA* pFormatConstraints;
|
||||
VkBufferCollectionConstraintsInfoFUCHSIA bufferCollectionConstraints;
|
||||
VkImageConstraintsInfoFlagsFUCHSIA flags;
|
||||
} VkImageConstraintsInfoFUCHSIA;
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateBufferCollectionFUCHSIA)(VkDevice device, const VkBufferCollectionCreateInfoFUCHSIA* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferCollectionFUCHSIA* pCollection);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkSetBufferCollectionImageConstraintsFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkSetBufferCollectionBufferConstraintsFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo);
|
||||
typedef void (VKAPI_PTR *PFN_vkDestroyBufferCollectionFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, const VkAllocationCallbacks* pAllocator);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetBufferCollectionPropertiesFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, VkBufferCollectionPropertiesFUCHSIA* pProperties);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferCollectionFUCHSIA(
|
||||
VkDevice device,
|
||||
const VkBufferCollectionCreateInfoFUCHSIA* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkBufferCollectionFUCHSIA* pCollection);
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkSetBufferCollectionImageConstraintsFUCHSIA(
|
||||
VkDevice device,
|
||||
VkBufferCollectionFUCHSIA collection,
|
||||
const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo);
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkSetBufferCollectionBufferConstraintsFUCHSIA(
|
||||
VkDevice device,
|
||||
VkBufferCollectionFUCHSIA collection,
|
||||
const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo);
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL vkDestroyBufferCollectionFUCHSIA(
|
||||
VkDevice device,
|
||||
VkBufferCollectionFUCHSIA collection,
|
||||
const VkAllocationCallbacks* pAllocator);
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetBufferCollectionPropertiesFUCHSIA(
|
||||
VkDevice device,
|
||||
VkBufferCollectionFUCHSIA collection,
|
||||
VkBufferCollectionPropertiesFUCHSIA* pProperties);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Vendored
+58
@@ -0,0 +1,58 @@
|
||||
#ifndef VULKAN_GGP_H_
|
||||
#define VULKAN_GGP_H_ 1
|
||||
|
||||
/*
|
||||
** Copyright 2015-2023 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
** This header is generated from the Khronos Vulkan XML API Registry.
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define VK_GGP_stream_descriptor_surface 1
|
||||
#define VK_GGP_STREAM_DESCRIPTOR_SURFACE_SPEC_VERSION 1
|
||||
#define VK_GGP_STREAM_DESCRIPTOR_SURFACE_EXTENSION_NAME "VK_GGP_stream_descriptor_surface"
|
||||
typedef VkFlags VkStreamDescriptorSurfaceCreateFlagsGGP;
|
||||
typedef struct VkStreamDescriptorSurfaceCreateInfoGGP {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkStreamDescriptorSurfaceCreateFlagsGGP flags;
|
||||
GgpStreamDescriptor streamDescriptor;
|
||||
} VkStreamDescriptorSurfaceCreateInfoGGP;
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateStreamDescriptorSurfaceGGP)(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateStreamDescriptorSurfaceGGP(
|
||||
VkInstance instance,
|
||||
const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSurfaceKHR* pSurface);
|
||||
#endif
|
||||
|
||||
|
||||
#define VK_GGP_frame_token 1
|
||||
#define VK_GGP_FRAME_TOKEN_SPEC_VERSION 1
|
||||
#define VK_GGP_FRAME_TOKEN_EXTENSION_NAME "VK_GGP_frame_token"
|
||||
typedef struct VkPresentFrameTokenGGP {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
GgpFrameToken frameToken;
|
||||
} VkPresentFrameTokenGGP;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Vendored
+9
-20
@@ -1,24 +1,10 @@
|
||||
#ifndef VULKAN_IOS_H_
|
||||
#define VULKAN_IOS_H_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2015-2018 The Khronos Group Inc.
|
||||
** Copyright 2015-2023 The Khronos Group Inc.
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -27,12 +13,16 @@ extern "C" {
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define VK_MVK_ios_surface 1
|
||||
#define VK_MVK_IOS_SURFACE_SPEC_VERSION 2
|
||||
#define VK_MVK_IOS_SURFACE_SPEC_VERSION 3
|
||||
#define VK_MVK_IOS_SURFACE_EXTENSION_NAME "VK_MVK_ios_surface"
|
||||
|
||||
typedef VkFlags VkIOSSurfaceCreateFlagsMVK;
|
||||
|
||||
typedef struct VkIOSSurfaceCreateInfoMVK {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
@@ -40,7 +30,6 @@ typedef struct VkIOSSurfaceCreateInfoMVK {
|
||||
const void* pView;
|
||||
} VkIOSSurfaceCreateInfoMVK;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateIOSSurfaceMVK)(VkInstance instance, const VkIOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
|
||||
+9
-20
@@ -1,24 +1,10 @@
|
||||
#ifndef VULKAN_MACOS_H_
|
||||
#define VULKAN_MACOS_H_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2015-2018 The Khronos Group Inc.
|
||||
** Copyright 2015-2023 The Khronos Group Inc.
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -27,12 +13,16 @@ extern "C" {
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define VK_MVK_macos_surface 1
|
||||
#define VK_MVK_MACOS_SURFACE_SPEC_VERSION 2
|
||||
#define VK_MVK_MACOS_SURFACE_SPEC_VERSION 3
|
||||
#define VK_MVK_MACOS_SURFACE_EXTENSION_NAME "VK_MVK_macos_surface"
|
||||
|
||||
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
|
||||
|
||||
typedef struct VkMacOSSurfaceCreateInfoMVK {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
@@ -40,7 +30,6 @@ typedef struct VkMacOSSurfaceCreateInfoMVK {
|
||||
const void* pView;
|
||||
} VkMacOSSurfaceCreateInfoMVK;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateMacOSSurfaceMVK)(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
#ifndef VULKAN_METAL_H_
|
||||
#define VULKAN_METAL_H_ 1
|
||||
|
||||
/*
|
||||
** Copyright 2015-2023 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
** This header is generated from the Khronos Vulkan XML API Registry.
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define VK_EXT_metal_surface 1
|
||||
#ifdef __OBJC__
|
||||
@class CAMetalLayer;
|
||||
#else
|
||||
typedef void CAMetalLayer;
|
||||
#endif
|
||||
|
||||
#define VK_EXT_METAL_SURFACE_SPEC_VERSION 1
|
||||
#define VK_EXT_METAL_SURFACE_EXTENSION_NAME "VK_EXT_metal_surface"
|
||||
typedef VkFlags VkMetalSurfaceCreateFlagsEXT;
|
||||
typedef struct VkMetalSurfaceCreateInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkMetalSurfaceCreateFlagsEXT flags;
|
||||
const CAMetalLayer* pLayer;
|
||||
} VkMetalSurfaceCreateInfoEXT;
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateMetalSurfaceEXT)(VkInstance instance, const VkMetalSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT(
|
||||
VkInstance instance,
|
||||
const VkMetalSurfaceCreateInfoEXT* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSurfaceKHR* pSurface);
|
||||
#endif
|
||||
|
||||
|
||||
#define VK_EXT_metal_objects 1
|
||||
#ifdef __OBJC__
|
||||
@protocol MTLDevice;
|
||||
typedef id<MTLDevice> MTLDevice_id;
|
||||
#else
|
||||
typedef void* MTLDevice_id;
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
@protocol MTLCommandQueue;
|
||||
typedef id<MTLCommandQueue> MTLCommandQueue_id;
|
||||
#else
|
||||
typedef void* MTLCommandQueue_id;
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
@protocol MTLBuffer;
|
||||
typedef id<MTLBuffer> MTLBuffer_id;
|
||||
#else
|
||||
typedef void* MTLBuffer_id;
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
@protocol MTLTexture;
|
||||
typedef id<MTLTexture> MTLTexture_id;
|
||||
#else
|
||||
typedef void* MTLTexture_id;
|
||||
#endif
|
||||
|
||||
typedef struct __IOSurface* IOSurfaceRef;
|
||||
#ifdef __OBJC__
|
||||
@protocol MTLSharedEvent;
|
||||
typedef id<MTLSharedEvent> MTLSharedEvent_id;
|
||||
#else
|
||||
typedef void* MTLSharedEvent_id;
|
||||
#endif
|
||||
|
||||
#define VK_EXT_METAL_OBJECTS_SPEC_VERSION 1
|
||||
#define VK_EXT_METAL_OBJECTS_EXTENSION_NAME "VK_EXT_metal_objects"
|
||||
|
||||
typedef enum VkExportMetalObjectTypeFlagBitsEXT {
|
||||
VK_EXPORT_METAL_OBJECT_TYPE_METAL_DEVICE_BIT_EXT = 0x00000001,
|
||||
VK_EXPORT_METAL_OBJECT_TYPE_METAL_COMMAND_QUEUE_BIT_EXT = 0x00000002,
|
||||
VK_EXPORT_METAL_OBJECT_TYPE_METAL_BUFFER_BIT_EXT = 0x00000004,
|
||||
VK_EXPORT_METAL_OBJECT_TYPE_METAL_TEXTURE_BIT_EXT = 0x00000008,
|
||||
VK_EXPORT_METAL_OBJECT_TYPE_METAL_IOSURFACE_BIT_EXT = 0x00000010,
|
||||
VK_EXPORT_METAL_OBJECT_TYPE_METAL_SHARED_EVENT_BIT_EXT = 0x00000020,
|
||||
VK_EXPORT_METAL_OBJECT_TYPE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
|
||||
} VkExportMetalObjectTypeFlagBitsEXT;
|
||||
typedef VkFlags VkExportMetalObjectTypeFlagsEXT;
|
||||
typedef struct VkExportMetalObjectCreateInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkExportMetalObjectTypeFlagBitsEXT exportObjectType;
|
||||
} VkExportMetalObjectCreateInfoEXT;
|
||||
|
||||
typedef struct VkExportMetalObjectsInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
} VkExportMetalObjectsInfoEXT;
|
||||
|
||||
typedef struct VkExportMetalDeviceInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
MTLDevice_id mtlDevice;
|
||||
} VkExportMetalDeviceInfoEXT;
|
||||
|
||||
typedef struct VkExportMetalCommandQueueInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkQueue queue;
|
||||
MTLCommandQueue_id mtlCommandQueue;
|
||||
} VkExportMetalCommandQueueInfoEXT;
|
||||
|
||||
typedef struct VkExportMetalBufferInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkDeviceMemory memory;
|
||||
MTLBuffer_id mtlBuffer;
|
||||
} VkExportMetalBufferInfoEXT;
|
||||
|
||||
typedef struct VkImportMetalBufferInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
MTLBuffer_id mtlBuffer;
|
||||
} VkImportMetalBufferInfoEXT;
|
||||
|
||||
typedef struct VkExportMetalTextureInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkImage image;
|
||||
VkImageView imageView;
|
||||
VkBufferView bufferView;
|
||||
VkImageAspectFlagBits plane;
|
||||
MTLTexture_id mtlTexture;
|
||||
} VkExportMetalTextureInfoEXT;
|
||||
|
||||
typedef struct VkImportMetalTextureInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkImageAspectFlagBits plane;
|
||||
MTLTexture_id mtlTexture;
|
||||
} VkImportMetalTextureInfoEXT;
|
||||
|
||||
typedef struct VkExportMetalIOSurfaceInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkImage image;
|
||||
IOSurfaceRef ioSurface;
|
||||
} VkExportMetalIOSurfaceInfoEXT;
|
||||
|
||||
typedef struct VkImportMetalIOSurfaceInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
IOSurfaceRef ioSurface;
|
||||
} VkImportMetalIOSurfaceInfoEXT;
|
||||
|
||||
typedef struct VkExportMetalSharedEventInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkSemaphore semaphore;
|
||||
VkEvent event;
|
||||
MTLSharedEvent_id mtlSharedEvent;
|
||||
} VkExportMetalSharedEventInfoEXT;
|
||||
|
||||
typedef struct VkImportMetalSharedEventInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
MTLSharedEvent_id mtlSharedEvent;
|
||||
} VkImportMetalSharedEventInfoEXT;
|
||||
|
||||
typedef void (VKAPI_PTR *PFN_vkExportMetalObjectsEXT)(VkDevice device, VkExportMetalObjectsInfoEXT* pMetalObjectsInfo);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR void VKAPI_CALL vkExportMetalObjectsEXT(
|
||||
VkDevice device,
|
||||
VkExportMetalObjectsInfoEXT* pMetalObjectsInfo);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Vendored
-65
@@ -1,65 +0,0 @@
|
||||
#ifndef VULKAN_MIR_H_
|
||||
#define VULKAN_MIR_H_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2015-2018 The Khronos Group Inc.
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
** This header is generated from the Khronos Vulkan XML API Registry.
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#define VK_KHR_mir_surface 1
|
||||
#define VK_KHR_MIR_SURFACE_SPEC_VERSION 4
|
||||
#define VK_KHR_MIR_SURFACE_EXTENSION_NAME "VK_KHR_mir_surface"
|
||||
|
||||
typedef VkFlags VkMirSurfaceCreateFlagsKHR;
|
||||
|
||||
typedef struct VkMirSurfaceCreateInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkMirSurfaceCreateFlagsKHR flags;
|
||||
MirConnection* connection;
|
||||
MirSurface* mirSurface;
|
||||
} VkMirSurfaceCreateInfoKHR;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateMirSurfaceKHR)(VkInstance instance, const VkMirSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, MirConnection* connection);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR(
|
||||
VkInstance instance,
|
||||
const VkMirSurfaceCreateInfoKHR* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSurfaceKHR* pSurface);
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceMirPresentationSupportKHR(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
uint32_t queueFamilyIndex,
|
||||
MirConnection* connection);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
#ifndef VULKAN_SCREEN_H_
|
||||
#define VULKAN_SCREEN_H_ 1
|
||||
|
||||
/*
|
||||
** Copyright 2015-2023 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
** This header is generated from the Khronos Vulkan XML API Registry.
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define VK_QNX_screen_surface 1
|
||||
#define VK_QNX_SCREEN_SURFACE_SPEC_VERSION 1
|
||||
#define VK_QNX_SCREEN_SURFACE_EXTENSION_NAME "VK_QNX_screen_surface"
|
||||
typedef VkFlags VkScreenSurfaceCreateFlagsQNX;
|
||||
typedef struct VkScreenSurfaceCreateInfoQNX {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkScreenSurfaceCreateFlagsQNX flags;
|
||||
struct _screen_context* context;
|
||||
struct _screen_window* window;
|
||||
} VkScreenSurfaceCreateInfoQNX;
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateScreenSurfaceQNX)(VkInstance instance, const VkScreenSurfaceCreateInfoQNX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct _screen_window* window);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateScreenSurfaceQNX(
|
||||
VkInstance instance,
|
||||
const VkScreenSurfaceCreateInfoQNX* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSurfaceKHR* pSurface);
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceScreenPresentationSupportQNX(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
uint32_t queueFamilyIndex,
|
||||
struct _screen_window* window);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Vendored
+8
-19
@@ -1,24 +1,10 @@
|
||||
#ifndef VULKAN_VI_H_
|
||||
#define VULKAN_VI_H_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2015-2018 The Khronos Group Inc.
|
||||
** Copyright 2015-2023 The Khronos Group Inc.
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -27,12 +13,16 @@ extern "C" {
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define VK_NN_vi_surface 1
|
||||
#define VK_NN_VI_SURFACE_SPEC_VERSION 1
|
||||
#define VK_NN_VI_SURFACE_EXTENSION_NAME "VK_NN_vi_surface"
|
||||
|
||||
typedef VkFlags VkViSurfaceCreateFlagsNN;
|
||||
|
||||
typedef struct VkViSurfaceCreateInfoNN {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
@@ -40,7 +30,6 @@ typedef struct VkViSurfaceCreateInfoNN {
|
||||
void* window;
|
||||
} VkViSurfaceCreateInfoNN;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateViSurfaceNN)(VkInstance instance, const VkViSurfaceCreateInfoNN* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
|
||||
+8
-19
@@ -1,24 +1,10 @@
|
||||
#ifndef VULKAN_WAYLAND_H_
|
||||
#define VULKAN_WAYLAND_H_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2015-2018 The Khronos Group Inc.
|
||||
** Copyright 2015-2023 The Khronos Group Inc.
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -27,12 +13,16 @@ extern "C" {
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define VK_KHR_wayland_surface 1
|
||||
#define VK_KHR_WAYLAND_SURFACE_SPEC_VERSION 6
|
||||
#define VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "VK_KHR_wayland_surface"
|
||||
|
||||
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
|
||||
|
||||
typedef struct VkWaylandSurfaceCreateInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
@@ -41,7 +31,6 @@ typedef struct VkWaylandSurfaceCreateInfoKHR {
|
||||
struct wl_surface* surface;
|
||||
} VkWaylandSurfaceCreateInfoKHR;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateWaylandSurfaceKHR)(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display* display);
|
||||
|
||||
|
||||
+88
-31
@@ -1,24 +1,10 @@
|
||||
#ifndef VULKAN_WIN32_H_
|
||||
#define VULKAN_WIN32_H_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2015-2018 The Khronos Group Inc.
|
||||
** Copyright 2015-2023 The Khronos Group Inc.
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -27,12 +13,16 @@ extern "C" {
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define VK_KHR_win32_surface 1
|
||||
#define VK_KHR_WIN32_SURFACE_SPEC_VERSION 6
|
||||
#define VK_KHR_WIN32_SURFACE_EXTENSION_NAME "VK_KHR_win32_surface"
|
||||
|
||||
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
|
||||
|
||||
typedef struct VkWin32SurfaceCreateInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
@@ -41,7 +31,6 @@ typedef struct VkWin32SurfaceCreateInfoKHR {
|
||||
HWND hwnd;
|
||||
} VkWin32SurfaceCreateInfoKHR;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateWin32SurfaceKHR)(VkInstance instance, const VkWin32SurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex);
|
||||
|
||||
@@ -57,10 +46,10 @@ VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR(
|
||||
uint32_t queueFamilyIndex);
|
||||
#endif
|
||||
|
||||
|
||||
#define VK_KHR_external_memory_win32 1
|
||||
#define VK_KHR_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1
|
||||
#define VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_KHR_external_memory_win32"
|
||||
|
||||
typedef struct VkImportMemoryWin32HandleInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
@@ -90,7 +79,6 @@ typedef struct VkMemoryGetWin32HandleInfoKHR {
|
||||
VkExternalMemoryHandleTypeFlagBits handleType;
|
||||
} VkMemoryGetWin32HandleInfoKHR;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleKHR)(VkDevice device, const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandlePropertiesKHR)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE handle, VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties);
|
||||
|
||||
@@ -107,10 +95,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandlePropertiesKHR(
|
||||
VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties);
|
||||
#endif
|
||||
|
||||
|
||||
#define VK_KHR_win32_keyed_mutex 1
|
||||
#define VK_KHR_WIN32_KEYED_MUTEX_SPEC_VERSION 1
|
||||
#define VK_KHR_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_KHR_win32_keyed_mutex"
|
||||
|
||||
typedef struct VkWin32KeyedMutexAcquireReleaseInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
@@ -128,7 +116,6 @@ typedef struct VkWin32KeyedMutexAcquireReleaseInfoKHR {
|
||||
#define VK_KHR_external_semaphore_win32 1
|
||||
#define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_SPEC_VERSION 1
|
||||
#define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME "VK_KHR_external_semaphore_win32"
|
||||
|
||||
typedef struct VkImportSemaphoreWin32HandleInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
@@ -163,7 +150,6 @@ typedef struct VkSemaphoreGetWin32HandleInfoKHR {
|
||||
VkExternalSemaphoreHandleTypeFlagBits handleType;
|
||||
} VkSemaphoreGetWin32HandleInfoKHR;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreWin32HandleKHR)(VkDevice device, const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreWin32HandleKHR)(VkDevice device, const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle);
|
||||
|
||||
@@ -178,10 +164,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreWin32HandleKHR(
|
||||
HANDLE* pHandle);
|
||||
#endif
|
||||
|
||||
|
||||
#define VK_KHR_external_fence_win32 1
|
||||
#define VK_KHR_EXTERNAL_FENCE_WIN32_SPEC_VERSION 1
|
||||
#define VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME "VK_KHR_external_fence_win32"
|
||||
|
||||
typedef struct VkImportFenceWin32HandleInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
@@ -207,7 +193,6 @@ typedef struct VkFenceGetWin32HandleInfoKHR {
|
||||
VkExternalFenceHandleTypeFlagBits handleType;
|
||||
} VkFenceGetWin32HandleInfoKHR;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkImportFenceWin32HandleKHR)(VkDevice device, const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetFenceWin32HandleKHR)(VkDevice device, const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle);
|
||||
|
||||
@@ -222,10 +207,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceWin32HandleKHR(
|
||||
HANDLE* pHandle);
|
||||
#endif
|
||||
|
||||
|
||||
#define VK_NV_external_memory_win32 1
|
||||
#define VK_NV_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1
|
||||
#define VK_NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_NV_external_memory_win32"
|
||||
|
||||
typedef struct VkImportMemoryWin32HandleInfoNV {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
@@ -240,7 +225,6 @@ typedef struct VkExportMemoryWin32HandleInfoNV {
|
||||
DWORD dwAccess;
|
||||
} VkExportMemoryWin32HandleInfoNV;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleNV)(VkDevice device, VkDeviceMemory memory, VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE* pHandle);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
@@ -251,10 +235,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleNV(
|
||||
HANDLE* pHandle);
|
||||
#endif
|
||||
|
||||
#define VK_NV_win32_keyed_mutex 1
|
||||
#define VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION 1
|
||||
#define VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_NV_win32_keyed_mutex"
|
||||
|
||||
#define VK_NV_win32_keyed_mutex 1
|
||||
#define VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION 2
|
||||
#define VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_NV_win32_keyed_mutex"
|
||||
typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
@@ -269,6 +253,79 @@ typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV {
|
||||
|
||||
|
||||
|
||||
#define VK_EXT_full_screen_exclusive 1
|
||||
#define VK_EXT_FULL_SCREEN_EXCLUSIVE_SPEC_VERSION 4
|
||||
#define VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME "VK_EXT_full_screen_exclusive"
|
||||
|
||||
typedef enum VkFullScreenExclusiveEXT {
|
||||
VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT = 0,
|
||||
VK_FULL_SCREEN_EXCLUSIVE_ALLOWED_EXT = 1,
|
||||
VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT = 2,
|
||||
VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT = 3,
|
||||
VK_FULL_SCREEN_EXCLUSIVE_MAX_ENUM_EXT = 0x7FFFFFFF
|
||||
} VkFullScreenExclusiveEXT;
|
||||
typedef struct VkSurfaceFullScreenExclusiveInfoEXT {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkFullScreenExclusiveEXT fullScreenExclusive;
|
||||
} VkSurfaceFullScreenExclusiveInfoEXT;
|
||||
|
||||
typedef struct VkSurfaceCapabilitiesFullScreenExclusiveEXT {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkBool32 fullScreenExclusiveSupported;
|
||||
} VkSurfaceCapabilitiesFullScreenExclusiveEXT;
|
||||
|
||||
typedef struct VkSurfaceFullScreenExclusiveWin32InfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
HMONITOR hmonitor;
|
||||
} VkSurfaceFullScreenExclusiveWin32InfoEXT;
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkAcquireFullScreenExclusiveModeEXT)(VkDevice device, VkSwapchainKHR swapchain);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkReleaseFullScreenExclusiveModeEXT)(VkDevice device, VkSwapchainKHR swapchain);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupSurfacePresentModes2EXT)(VkDevice device, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkDeviceGroupPresentModeFlagsKHR* pModes);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModes2EXT(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
|
||||
uint32_t* pPresentModeCount,
|
||||
VkPresentModeKHR* pPresentModes);
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkAcquireFullScreenExclusiveModeEXT(
|
||||
VkDevice device,
|
||||
VkSwapchainKHR swapchain);
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkReleaseFullScreenExclusiveModeEXT(
|
||||
VkDevice device,
|
||||
VkSwapchainKHR swapchain);
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModes2EXT(
|
||||
VkDevice device,
|
||||
const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
|
||||
VkDeviceGroupPresentModeFlagsKHR* pModes);
|
||||
#endif
|
||||
|
||||
|
||||
#define VK_NV_acquire_winrt_display 1
|
||||
#define VK_NV_ACQUIRE_WINRT_DISPLAY_SPEC_VERSION 1
|
||||
#define VK_NV_ACQUIRE_WINRT_DISPLAY_EXTENSION_NAME "VK_NV_acquire_winrt_display"
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkAcquireWinrtDisplayNV)(VkPhysicalDevice physicalDevice, VkDisplayKHR display);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetWinrtDisplayNV)(VkPhysicalDevice physicalDevice, uint32_t deviceRelativeId, VkDisplayKHR* pDisplay);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkAcquireWinrtDisplayNV(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VkDisplayKHR display);
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetWinrtDisplayNV(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
uint32_t deviceRelativeId,
|
||||
VkDisplayKHR* pDisplay);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Vendored
+8
-19
@@ -1,24 +1,10 @@
|
||||
#ifndef VULKAN_XCB_H_
|
||||
#define VULKAN_XCB_H_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2015-2018 The Khronos Group Inc.
|
||||
** Copyright 2015-2023 The Khronos Group Inc.
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -27,12 +13,16 @@ extern "C" {
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define VK_KHR_xcb_surface 1
|
||||
#define VK_KHR_XCB_SURFACE_SPEC_VERSION 6
|
||||
#define VK_KHR_XCB_SURFACE_EXTENSION_NAME "VK_KHR_xcb_surface"
|
||||
|
||||
typedef VkFlags VkXcbSurfaceCreateFlagsKHR;
|
||||
|
||||
typedef struct VkXcbSurfaceCreateInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
@@ -41,7 +31,6 @@ typedef struct VkXcbSurfaceCreateInfoKHR {
|
||||
xcb_window_t window;
|
||||
} VkXcbSurfaceCreateInfoKHR;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateXcbSurfaceKHR)(VkInstance instance, const VkXcbSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t* connection, xcb_visualid_t visual_id);
|
||||
|
||||
|
||||
+8
-19
@@ -1,24 +1,10 @@
|
||||
#ifndef VULKAN_XLIB_H_
|
||||
#define VULKAN_XLIB_H_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2015-2018 The Khronos Group Inc.
|
||||
** Copyright 2015-2023 The Khronos Group Inc.
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -27,12 +13,16 @@ extern "C" {
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define VK_KHR_xlib_surface 1
|
||||
#define VK_KHR_XLIB_SURFACE_SPEC_VERSION 6
|
||||
#define VK_KHR_XLIB_SURFACE_EXTENSION_NAME "VK_KHR_xlib_surface"
|
||||
|
||||
typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
|
||||
|
||||
typedef struct VkXlibSurfaceCreateInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
@@ -41,7 +31,6 @@ typedef struct VkXlibSurfaceCreateInfoKHR {
|
||||
Window window;
|
||||
} VkXlibSurfaceCreateInfoKHR;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateXlibSurfaceKHR)(VkInstance instance, const VkXlibSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display* dpy, VisualID visualID);
|
||||
|
||||
|
||||
+8
-17
@@ -1,24 +1,10 @@
|
||||
#ifndef VULKAN_XLIB_XRANDR_H_
|
||||
#define VULKAN_XLIB_XRANDR_H_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2015-2018 The Khronos Group Inc.
|
||||
** Copyright 2015-2023 The Khronos Group Inc.
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -27,10 +13,15 @@ extern "C" {
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define VK_EXT_acquire_xlib_display 1
|
||||
#define VK_EXT_ACQUIRE_XLIB_DISPLAY_SPEC_VERSION 1
|
||||
#define VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME "VK_EXT_acquire_xlib_display"
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkAcquireXlibDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, VkDisplayKHR display);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetRandROutputDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, RROutput rrOutput, VkDisplayKHR* pDisplay);
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -24,7 +24,7 @@ if(UNIX)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function -Wno-missing-braces -Wno-missing-field-initializers")
|
||||
endif()
|
||||
if(CV_CLANG)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-self-assign")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-self-assign -Wno-strict-prototypes")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
Vendored
+11
-11
@@ -2,32 +2,32 @@ function(download_ippicv root_var)
|
||||
set(${root_var} "" PARENT_SCOPE)
|
||||
|
||||
# Commit SHA in the opencv_3rdparty repo
|
||||
set(IPPICV_COMMIT "a56b6ac6f030c312b2dce17430eef13aed9af274")
|
||||
set(IPPICV_COMMIT "0cc4aa06bf2bef4b05d237c69a5a96b9cd0cb85a")
|
||||
# Define actual ICV versions
|
||||
if(APPLE)
|
||||
set(OPENCV_ICV_PLATFORM "macosx")
|
||||
set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_mac")
|
||||
set(OPENCV_ICV_NAME "ippicv_2020_mac_intel64_20191018_general.tgz")
|
||||
set(OPENCV_ICV_HASH "1c3d675c2a2395d094d523024896e01b")
|
||||
set(OPENCV_ICV_NAME "ippicv_2021.9.1_mac_intel64_20230919_general.tgz")
|
||||
set(OPENCV_ICV_HASH "14f01c5a4780bfae9dde9b0aaf5e56fc")
|
||||
elseif((UNIX AND NOT ANDROID) OR (UNIX AND ANDROID_ABI MATCHES "x86"))
|
||||
set(OPENCV_ICV_PLATFORM "linux")
|
||||
set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_lnx")
|
||||
if(X86_64)
|
||||
set(OPENCV_ICV_NAME "ippicv_2020_lnx_intel64_20191018_general.tgz")
|
||||
set(OPENCV_ICV_HASH "7421de0095c7a39162ae13a6098782f9")
|
||||
set(OPENCV_ICV_NAME "ippicv_2021.10.0_lnx_intel64_20230919_general.tgz")
|
||||
set(OPENCV_ICV_HASH "606a19b207ebedfe42d59fd916cc4850")
|
||||
else()
|
||||
set(OPENCV_ICV_NAME "ippicv_2020_lnx_ia32_20191018_general.tgz")
|
||||
set(OPENCV_ICV_HASH "ad189a940fb60eb71f291321322fe3e8")
|
||||
set(OPENCV_ICV_NAME "ippicv_2021.10.0_lnx_ia32_20230919_general.tgz")
|
||||
set(OPENCV_ICV_HASH "ea08487b810baad2f68aca87b74a2db9")
|
||||
endif()
|
||||
elseif(WIN32 AND NOT ARM)
|
||||
set(OPENCV_ICV_PLATFORM "windows")
|
||||
set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_win")
|
||||
if(X86_64)
|
||||
set(OPENCV_ICV_NAME "ippicv_2020_win_intel64_20191018_general.zip")
|
||||
set(OPENCV_ICV_HASH "879741a7946b814455eee6c6ffde2984")
|
||||
set(OPENCV_ICV_NAME "ippicv_2021.10.0_win_intel64_20230919_general.zip")
|
||||
set(OPENCV_ICV_HASH "538a819ec84193a9c9f3c0f8df0be8b7")
|
||||
else()
|
||||
set(OPENCV_ICV_NAME "ippicv_2020_win_ia32_20191018_general.zip")
|
||||
set(OPENCV_ICV_HASH "cd39bdf0c2e1cac9a61101dad7a2413e")
|
||||
set(OPENCV_ICV_NAME "ippicv_2021.10.0_win_ia32_20230919_general.zip")
|
||||
set(OPENCV_ICV_HASH "8ff93c69415ab0835cc1e94dc5660f5d")
|
||||
endif()
|
||||
else()
|
||||
return()
|
||||
|
||||
Vendored
-1
@@ -23,7 +23,6 @@ if(MSVC)
|
||||
endif(MSVC)
|
||||
|
||||
add_library(${SPNG_LIBRARY} STATIC ${OPENCV_3RDPARTY_EXCLUDE_FROM_ALL} ${spng_headers} ${spng_sources})
|
||||
ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-variable)
|
||||
target_link_libraries(${SPNG_LIBRARY} ${ZLIB_LIBRARIES})
|
||||
|
||||
set_target_properties(${SPNG_LIBRARY}
|
||||
|
||||
Vendored
+1
-1
@@ -1,6 +1,6 @@
|
||||
BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2018-2022, Randy <randy408@protonmail.com>
|
||||
Copyright (c) 2018-2023, Randy <randy408@protonmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
Vendored
+5
-3
@@ -2691,6 +2691,7 @@ static int read_non_idat_chunks(spng_ctx *ctx)
|
||||
if(!memcmp(chunk.type, type_exif, 4))
|
||||
{
|
||||
if(ctx->file.exif) return SPNG_EDUP_EXIF;
|
||||
if(!chunk.length) return SPNG_EEXIF;
|
||||
|
||||
ctx->file.exif = 1;
|
||||
|
||||
@@ -4999,11 +5000,11 @@ void spng_ctx_free(spng_ctx *ctx)
|
||||
spng__free(ctx, ctx->prev_scanline_buf);
|
||||
spng__free(ctx, ctx->filtered_scanline_buf);
|
||||
|
||||
spng_free_fn *free_func = ctx->alloc.free_fn;
|
||||
spng_free_fn *free_fn = ctx->alloc.free_fn;
|
||||
|
||||
memset(ctx, 0, sizeof(spng_ctx));
|
||||
|
||||
free_func(ctx);
|
||||
free_fn(ctx);
|
||||
}
|
||||
|
||||
static int buffer_read_fn(spng_ctx *ctx, void *user, void *data, size_t n)
|
||||
@@ -5743,7 +5744,8 @@ int spng_set_iccp(spng_ctx *ctx, struct spng_iccp *iccp)
|
||||
SPNG_SET_CHUNK_BOILERPLATE(iccp);
|
||||
|
||||
if(check_png_keyword(iccp->profile_name)) return SPNG_EICCP_NAME;
|
||||
if(!iccp->profile_len || iccp->profile_len > UINT_MAX) return 1;
|
||||
if(!iccp->profile_len) return SPNG_ECHUNK_SIZE;
|
||||
if(iccp->profile_len > spng_u32max) return SPNG_ECHUNK_STDLEN;
|
||||
|
||||
if(ctx->iccp.profile && !ctx->user.iccp) spng__free(ctx, ctx->iccp.profile);
|
||||
|
||||
|
||||
Vendored
+2
-2
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: (BSD-2-Clause AND libpng-2.0) */
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
#ifndef SPNG_H
|
||||
#define SPNG_H
|
||||
|
||||
@@ -28,7 +28,7 @@ extern "C" {
|
||||
|
||||
#define SPNG_VERSION_MAJOR 0
|
||||
#define SPNG_VERSION_MINOR 7
|
||||
#define SPNG_VERSION_PATCH 3
|
||||
#define SPNG_VERSION_PATCH 4
|
||||
|
||||
enum spng_errno
|
||||
{
|
||||
|
||||
Vendored
-80
@@ -1,80 +0,0 @@
|
||||
# COPYRIGHT
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# License); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# Copyright (c) 2020, OPEN AI LAB
|
||||
# Author: qtang@openailab.com or https://github.com/BUG1989
|
||||
# qli@openailab.com
|
||||
# sqfu@openailab.com
|
||||
|
||||
SET(TENGINE_COMMIT_VERSION "e89cf8870de2ff0a80cfe626c0b52b2a16fb302e")
|
||||
SET(OCV_TENGINE_DIR "${OpenCV_BINARY_DIR}/3rdparty/libtengine")
|
||||
SET(OCV_TENGINE_SOURCE_PATH "${OCV_TENGINE_DIR}/Tengine-${TENGINE_COMMIT_VERSION}")
|
||||
|
||||
IF(EXISTS "${OCV_TENGINE_SOURCE_PATH}")
|
||||
MESSAGE(STATUS "Tengine is exist already at: ${OCV_TENGINE_SOURCE_PATH}")
|
||||
|
||||
SET(Tengine_FOUND ON)
|
||||
SET(BUILD_TENGINE ON)
|
||||
ELSE()
|
||||
SET(OCV_TENGINE_FILENAME "${TENGINE_COMMIT_VERSION}.zip")#name
|
||||
SET(OCV_TENGINE_URL "https://github.com/OAID/Tengine/archive/") #url
|
||||
SET(tengine_md5sum 23f61ebb1dd419f1207d8876496289c5) #md5sum
|
||||
|
||||
ocv_download(FILENAME ${OCV_TENGINE_FILENAME}
|
||||
HASH ${tengine_md5sum}
|
||||
URL
|
||||
"${OPENCV_TENGINE_URL}"
|
||||
"$ENV{OPENCV_TENGINE_URL}"
|
||||
"${OCV_TENGINE_URL}"
|
||||
DESTINATION_DIR "${OCV_TENGINE_DIR}"
|
||||
ID TENGINE
|
||||
STATUS res
|
||||
UNPACK RELATIVE_URL)
|
||||
|
||||
if (NOT res)
|
||||
MESSAGE(STATUS "TENGINE DOWNLOAD FAILED. Turning Tengine_FOUND off.")
|
||||
SET(Tengine_FOUND OFF)
|
||||
else ()
|
||||
MESSAGE(STATUS "TENGINE DOWNLOAD success . ")
|
||||
|
||||
SET(Tengine_FOUND ON)
|
||||
SET(BUILD_TENGINE ON)
|
||||
endif()
|
||||
ENDIF()
|
||||
|
||||
if(BUILD_TENGINE)
|
||||
SET(HAVE_TENGINE 1)
|
||||
|
||||
if(NOT ANDROID)
|
||||
# linux system
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL arm)
|
||||
SET(TENGINE_TOOLCHAIN_FLAG "-march=armv7-a")
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64) ## AARCH64
|
||||
SET(TENGINE_TOOLCHAIN_FLAG "-march=armv8-a")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
SET(BUILT_IN_OPENCV ON) ## set for tengine compile discern .
|
||||
SET(Tengine_INCLUDE_DIR "${OCV_TENGINE_SOURCE_PATH}/include" CACHE INTERNAL "")
|
||||
if(EXISTS "${OCV_TENGINE_SOURCE_PATH}/CMakeLists.txt")
|
||||
add_subdirectory("${OCV_TENGINE_SOURCE_PATH}" "${OCV_TENGINE_DIR}/build")
|
||||
else()
|
||||
message(WARNING "TENGINE: Missing 'CMakeLists.txt' in source code package: ${OCV_TENGINE_SOURCE_PATH}")
|
||||
endif()
|
||||
SET(Tengine_LIB "tengine" CACHE INTERNAL "")
|
||||
endif()
|
||||
Vendored
+1
-1
@@ -4371,7 +4371,7 @@ static void
|
||||
TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
|
||||
{
|
||||
static const char module[] = "TIFFReadDirectoryCheckOrder";
|
||||
uint16 m;
|
||||
uint32 m;
|
||||
uint16 n;
|
||||
TIFFDirEntry* o;
|
||||
m=0;
|
||||
|
||||
Vendored
+2
-8
@@ -9,8 +9,8 @@ if(ANDROID)
|
||||
ocv_include_directories(${CPUFEATURES_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
file(GLOB lib_srcs src/dec/*.c src/demux/*.c src/dsp/*.c src/enc/*.c src/mux/*.c src/utils/*.c src/webp/*.c)
|
||||
file(GLOB lib_hdrs src/dec/*.h src/demux/*.h src/dsp/*.h src/enc/*.h src/mux/*.h src/utils/*.h src/webp/*.h)
|
||||
file(GLOB lib_srcs sharpyuv/*.c src/dec/*.c src/demux/*.c src/dsp/*.c src/enc/*.c src/mux/*.c src/utils/*.c src/webp/*.c)
|
||||
file(GLOB lib_hdrs sharpyuv/*.h src/dec/*.h src/demux/*.h src/dsp/*.h src/enc/*.h src/mux/*.h src/utils/*.h src/webp/*.h)
|
||||
|
||||
# FIXIT
|
||||
if(ANDROID AND ARMEABI_V7A AND NOT NEON)
|
||||
@@ -21,12 +21,6 @@ if(ANDROID AND ARMEABI_V7A AND NOT NEON)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# FIX for quant.h - requires C99 for() loops
|
||||
ocv_check_flag_support(C "-std=c99" _varname "${CMAKE_C_FLAGS}")
|
||||
if(${_varname})
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
|
||||
endif()
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------
|
||||
# Define the library target:
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
diff --git a/3rdparty/libwebp/src/dsp/msa_macro.h b/3rdparty/libwebp/src/dsp/msa_macro.h
|
||||
index de026a1d9e..a16c0bb300 100644
|
||||
--- a/3rdparty/libwebp/src/dsp/msa_macro.h
|
||||
+++ b/3rdparty/libwebp/src/dsp/msa_macro.h
|
||||
@@ -73,7 +73,7 @@
|
||||
static inline TYPE FUNC_NAME(const void* const psrc) { \
|
||||
const uint8_t* const psrc_m = (const uint8_t*)psrc; \
|
||||
TYPE val_m; \
|
||||
- asm volatile ( \
|
||||
+ __asm__ volatile ( \
|
||||
"" #INSTR " %[val_m], %[psrc_m] \n\t" \
|
||||
: [val_m] "=r" (val_m) \
|
||||
: [psrc_m] "m" (*psrc_m)); \
|
||||
@@ -86,7 +86,7 @@
|
||||
static inline void FUNC_NAME(TYPE val, void* const pdst) { \
|
||||
uint8_t* const pdst_m = (uint8_t*)pdst; \
|
||||
TYPE val_m = val; \
|
||||
- asm volatile ( \
|
||||
+ __asm__ volatile ( \
|
||||
" " #INSTR " %[val_m], %[pdst_m] \n\t" \
|
||||
: [pdst_m] "=m" (*pdst_m) \
|
||||
: [val_m] "r" (val_m)); \
|
||||
Vendored
+565
@@ -0,0 +1,565 @@
|
||||
// Copyright 2022 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Sharp RGB to YUV conversion.
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "sharpyuv/sharpyuv.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "src/webp/types.h"
|
||||
#include "sharpyuv/sharpyuv_cpu.h"
|
||||
#include "sharpyuv/sharpyuv_dsp.h"
|
||||
#include "sharpyuv/sharpyuv_gamma.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int SharpYuvGetVersion(void) {
|
||||
return SHARPYUV_VERSION;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Sharp RGB->YUV conversion
|
||||
|
||||
static const int kNumIterations = 4;
|
||||
|
||||
#define YUV_FIX 16 // fixed-point precision for RGB->YUV
|
||||
static const int kYuvHalf = 1 << (YUV_FIX - 1);
|
||||
|
||||
// Max bit depth so that intermediate calculations fit in 16 bits.
|
||||
static const int kMaxBitDepth = 14;
|
||||
|
||||
// Returns the precision shift to use based on the input rgb_bit_depth.
|
||||
static int GetPrecisionShift(int rgb_bit_depth) {
|
||||
// Try to add 2 bits of precision if it fits in kMaxBitDepth. Otherwise remove
|
||||
// bits if needed.
|
||||
return ((rgb_bit_depth + 2) <= kMaxBitDepth) ? 2
|
||||
: (kMaxBitDepth - rgb_bit_depth);
|
||||
}
|
||||
|
||||
typedef int16_t fixed_t; // signed type with extra precision for UV
|
||||
typedef uint16_t fixed_y_t; // unsigned type with extra precision for W
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static uint8_t clip_8b(fixed_t v) {
|
||||
return (!(v & ~0xff)) ? (uint8_t)v : (v < 0) ? 0u : 255u;
|
||||
}
|
||||
|
||||
static uint16_t clip(fixed_t v, int max) {
|
||||
return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v;
|
||||
}
|
||||
|
||||
static fixed_y_t clip_bit_depth(int y, int bit_depth) {
|
||||
const int max = (1 << bit_depth) - 1;
|
||||
return (!(y & ~max)) ? (fixed_y_t)y : (y < 0) ? 0 : max;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static int RGBToGray(int64_t r, int64_t g, int64_t b) {
|
||||
const int64_t luma = 13933 * r + 46871 * g + 4732 * b + kYuvHalf;
|
||||
return (int)(luma >> YUV_FIX);
|
||||
}
|
||||
|
||||
static uint32_t ScaleDown(uint16_t a, uint16_t b, uint16_t c, uint16_t d,
|
||||
int rgb_bit_depth,
|
||||
SharpYuvTransferFunctionType transfer_type) {
|
||||
const int bit_depth = rgb_bit_depth + GetPrecisionShift(rgb_bit_depth);
|
||||
const uint32_t A = SharpYuvGammaToLinear(a, bit_depth, transfer_type);
|
||||
const uint32_t B = SharpYuvGammaToLinear(b, bit_depth, transfer_type);
|
||||
const uint32_t C = SharpYuvGammaToLinear(c, bit_depth, transfer_type);
|
||||
const uint32_t D = SharpYuvGammaToLinear(d, bit_depth, transfer_type);
|
||||
return SharpYuvLinearToGamma((A + B + C + D + 2) >> 2, bit_depth,
|
||||
transfer_type);
|
||||
}
|
||||
|
||||
static WEBP_INLINE void UpdateW(const fixed_y_t* src, fixed_y_t* dst, int w,
|
||||
int rgb_bit_depth,
|
||||
SharpYuvTransferFunctionType transfer_type) {
|
||||
const int bit_depth = rgb_bit_depth + GetPrecisionShift(rgb_bit_depth);
|
||||
int i;
|
||||
for (i = 0; i < w; ++i) {
|
||||
const uint32_t R =
|
||||
SharpYuvGammaToLinear(src[0 * w + i], bit_depth, transfer_type);
|
||||
const uint32_t G =
|
||||
SharpYuvGammaToLinear(src[1 * w + i], bit_depth, transfer_type);
|
||||
const uint32_t B =
|
||||
SharpYuvGammaToLinear(src[2 * w + i], bit_depth, transfer_type);
|
||||
const uint32_t Y = RGBToGray(R, G, B);
|
||||
dst[i] = (fixed_y_t)SharpYuvLinearToGamma(Y, bit_depth, transfer_type);
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateChroma(const fixed_y_t* src1, const fixed_y_t* src2,
|
||||
fixed_t* dst, int uv_w, int rgb_bit_depth,
|
||||
SharpYuvTransferFunctionType transfer_type) {
|
||||
int i;
|
||||
for (i = 0; i < uv_w; ++i) {
|
||||
const int r =
|
||||
ScaleDown(src1[0 * uv_w + 0], src1[0 * uv_w + 1], src2[0 * uv_w + 0],
|
||||
src2[0 * uv_w + 1], rgb_bit_depth, transfer_type);
|
||||
const int g =
|
||||
ScaleDown(src1[2 * uv_w + 0], src1[2 * uv_w + 1], src2[2 * uv_w + 0],
|
||||
src2[2 * uv_w + 1], rgb_bit_depth, transfer_type);
|
||||
const int b =
|
||||
ScaleDown(src1[4 * uv_w + 0], src1[4 * uv_w + 1], src2[4 * uv_w + 0],
|
||||
src2[4 * uv_w + 1], rgb_bit_depth, transfer_type);
|
||||
const int W = RGBToGray(r, g, b);
|
||||
dst[0 * uv_w] = (fixed_t)(r - W);
|
||||
dst[1 * uv_w] = (fixed_t)(g - W);
|
||||
dst[2 * uv_w] = (fixed_t)(b - W);
|
||||
dst += 1;
|
||||
src1 += 2;
|
||||
src2 += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void StoreGray(const fixed_y_t* rgb, fixed_y_t* y, int w) {
|
||||
int i;
|
||||
assert(w > 0);
|
||||
for (i = 0; i < w; ++i) {
|
||||
y[i] = RGBToGray(rgb[0 * w + i], rgb[1 * w + i], rgb[2 * w + i]);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static WEBP_INLINE fixed_y_t Filter2(int A, int B, int W0, int bit_depth) {
|
||||
const int v0 = (A * 3 + B + 2) >> 2;
|
||||
return clip_bit_depth(v0 + W0, bit_depth);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static WEBP_INLINE int Shift(int v, int shift) {
|
||||
return (shift >= 0) ? (v << shift) : (v >> -shift);
|
||||
}
|
||||
|
||||
static void ImportOneRow(const uint8_t* const r_ptr,
|
||||
const uint8_t* const g_ptr,
|
||||
const uint8_t* const b_ptr,
|
||||
int rgb_step,
|
||||
int rgb_bit_depth,
|
||||
int pic_width,
|
||||
fixed_y_t* const dst) {
|
||||
// Convert the rgb_step from a number of bytes to a number of uint8_t or
|
||||
// uint16_t values depending the bit depth.
|
||||
const int step = (rgb_bit_depth > 8) ? rgb_step / 2 : rgb_step;
|
||||
int i;
|
||||
const int w = (pic_width + 1) & ~1;
|
||||
for (i = 0; i < pic_width; ++i) {
|
||||
const int off = i * step;
|
||||
const int shift = GetPrecisionShift(rgb_bit_depth);
|
||||
if (rgb_bit_depth == 8) {
|
||||
dst[i + 0 * w] = Shift(r_ptr[off], shift);
|
||||
dst[i + 1 * w] = Shift(g_ptr[off], shift);
|
||||
dst[i + 2 * w] = Shift(b_ptr[off], shift);
|
||||
} else {
|
||||
dst[i + 0 * w] = Shift(((uint16_t*)r_ptr)[off], shift);
|
||||
dst[i + 1 * w] = Shift(((uint16_t*)g_ptr)[off], shift);
|
||||
dst[i + 2 * w] = Shift(((uint16_t*)b_ptr)[off], shift);
|
||||
}
|
||||
}
|
||||
if (pic_width & 1) { // replicate rightmost pixel
|
||||
dst[pic_width + 0 * w] = dst[pic_width + 0 * w - 1];
|
||||
dst[pic_width + 1 * w] = dst[pic_width + 1 * w - 1];
|
||||
dst[pic_width + 2 * w] = dst[pic_width + 2 * w - 1];
|
||||
}
|
||||
}
|
||||
|
||||
static void InterpolateTwoRows(const fixed_y_t* const best_y,
|
||||
const fixed_t* prev_uv,
|
||||
const fixed_t* cur_uv,
|
||||
const fixed_t* next_uv,
|
||||
int w,
|
||||
fixed_y_t* out1,
|
||||
fixed_y_t* out2,
|
||||
int rgb_bit_depth) {
|
||||
const int uv_w = w >> 1;
|
||||
const int len = (w - 1) >> 1; // length to filter
|
||||
int k = 3;
|
||||
const int bit_depth = rgb_bit_depth + GetPrecisionShift(rgb_bit_depth);
|
||||
while (k-- > 0) { // process each R/G/B segments in turn
|
||||
// special boundary case for i==0
|
||||
out1[0] = Filter2(cur_uv[0], prev_uv[0], best_y[0], bit_depth);
|
||||
out2[0] = Filter2(cur_uv[0], next_uv[0], best_y[w], bit_depth);
|
||||
|
||||
SharpYuvFilterRow(cur_uv, prev_uv, len, best_y + 0 + 1, out1 + 1,
|
||||
bit_depth);
|
||||
SharpYuvFilterRow(cur_uv, next_uv, len, best_y + w + 1, out2 + 1,
|
||||
bit_depth);
|
||||
|
||||
// special boundary case for i == w - 1 when w is even
|
||||
if (!(w & 1)) {
|
||||
out1[w - 1] = Filter2(cur_uv[uv_w - 1], prev_uv[uv_w - 1],
|
||||
best_y[w - 1 + 0], bit_depth);
|
||||
out2[w - 1] = Filter2(cur_uv[uv_w - 1], next_uv[uv_w - 1],
|
||||
best_y[w - 1 + w], bit_depth);
|
||||
}
|
||||
out1 += w;
|
||||
out2 += w;
|
||||
prev_uv += uv_w;
|
||||
cur_uv += uv_w;
|
||||
next_uv += uv_w;
|
||||
}
|
||||
}
|
||||
|
||||
static WEBP_INLINE int RGBToYUVComponent(int r, int g, int b,
|
||||
const int coeffs[4], int sfix) {
|
||||
const int srounder = 1 << (YUV_FIX + sfix - 1);
|
||||
const int luma = coeffs[0] * r + coeffs[1] * g + coeffs[2] * b +
|
||||
coeffs[3] + srounder;
|
||||
return (luma >> (YUV_FIX + sfix));
|
||||
}
|
||||
|
||||
static int ConvertWRGBToYUV(const fixed_y_t* best_y, const fixed_t* best_uv,
|
||||
uint8_t* y_ptr, int y_stride, uint8_t* u_ptr,
|
||||
int u_stride, uint8_t* v_ptr, int v_stride,
|
||||
int rgb_bit_depth,
|
||||
int yuv_bit_depth, int width, int height,
|
||||
const SharpYuvConversionMatrix* yuv_matrix) {
|
||||
int i, j;
|
||||
const fixed_t* const best_uv_base = best_uv;
|
||||
const int w = (width + 1) & ~1;
|
||||
const int h = (height + 1) & ~1;
|
||||
const int uv_w = w >> 1;
|
||||
const int uv_h = h >> 1;
|
||||
const int sfix = GetPrecisionShift(rgb_bit_depth);
|
||||
const int yuv_max = (1 << yuv_bit_depth) - 1;
|
||||
|
||||
for (best_uv = best_uv_base, j = 0; j < height; ++j) {
|
||||
for (i = 0; i < width; ++i) {
|
||||
const int off = (i >> 1);
|
||||
const int W = best_y[i];
|
||||
const int r = best_uv[off + 0 * uv_w] + W;
|
||||
const int g = best_uv[off + 1 * uv_w] + W;
|
||||
const int b = best_uv[off + 2 * uv_w] + W;
|
||||
const int y = RGBToYUVComponent(r, g, b, yuv_matrix->rgb_to_y, sfix);
|
||||
if (yuv_bit_depth <= 8) {
|
||||
y_ptr[i] = clip_8b(y);
|
||||
} else {
|
||||
((uint16_t*)y_ptr)[i] = clip(y, yuv_max);
|
||||
}
|
||||
}
|
||||
best_y += w;
|
||||
best_uv += (j & 1) * 3 * uv_w;
|
||||
y_ptr += y_stride;
|
||||
}
|
||||
for (best_uv = best_uv_base, j = 0; j < uv_h; ++j) {
|
||||
for (i = 0; i < uv_w; ++i) {
|
||||
const int off = i;
|
||||
// Note r, g and b values here are off by W, but a constant offset on all
|
||||
// 3 components doesn't change the value of u and v with a YCbCr matrix.
|
||||
const int r = best_uv[off + 0 * uv_w];
|
||||
const int g = best_uv[off + 1 * uv_w];
|
||||
const int b = best_uv[off + 2 * uv_w];
|
||||
const int u = RGBToYUVComponent(r, g, b, yuv_matrix->rgb_to_u, sfix);
|
||||
const int v = RGBToYUVComponent(r, g, b, yuv_matrix->rgb_to_v, sfix);
|
||||
if (yuv_bit_depth <= 8) {
|
||||
u_ptr[i] = clip_8b(u);
|
||||
v_ptr[i] = clip_8b(v);
|
||||
} else {
|
||||
((uint16_t*)u_ptr)[i] = clip(u, yuv_max);
|
||||
((uint16_t*)v_ptr)[i] = clip(v, yuv_max);
|
||||
}
|
||||
}
|
||||
best_uv += 3 * uv_w;
|
||||
u_ptr += u_stride;
|
||||
v_ptr += v_stride;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Main function
|
||||
|
||||
static void* SafeMalloc(uint64_t nmemb, size_t size) {
|
||||
const uint64_t total_size = nmemb * (uint64_t)size;
|
||||
if (total_size != (size_t)total_size) return NULL;
|
||||
return malloc((size_t)total_size);
|
||||
}
|
||||
|
||||
#define SAFE_ALLOC(W, H, T) ((T*)SafeMalloc((W) * (H), sizeof(T)))
|
||||
|
||||
static int DoSharpArgbToYuv(const uint8_t* r_ptr, const uint8_t* g_ptr,
|
||||
const uint8_t* b_ptr, int rgb_step, int rgb_stride,
|
||||
int rgb_bit_depth, uint8_t* y_ptr, int y_stride,
|
||||
uint8_t* u_ptr, int u_stride, uint8_t* v_ptr,
|
||||
int v_stride, int yuv_bit_depth, int width,
|
||||
int height,
|
||||
const SharpYuvConversionMatrix* yuv_matrix,
|
||||
SharpYuvTransferFunctionType transfer_type) {
|
||||
// we expand the right/bottom border if needed
|
||||
const int w = (width + 1) & ~1;
|
||||
const int h = (height + 1) & ~1;
|
||||
const int uv_w = w >> 1;
|
||||
const int uv_h = h >> 1;
|
||||
uint64_t prev_diff_y_sum = ~0;
|
||||
int j, iter;
|
||||
|
||||
// TODO(skal): allocate one big memory chunk. But for now, it's easier
|
||||
// for valgrind debugging to have several chunks.
|
||||
fixed_y_t* const tmp_buffer = SAFE_ALLOC(w * 3, 2, fixed_y_t); // scratch
|
||||
fixed_y_t* const best_y_base = SAFE_ALLOC(w, h, fixed_y_t);
|
||||
fixed_y_t* const target_y_base = SAFE_ALLOC(w, h, fixed_y_t);
|
||||
fixed_y_t* const best_rgb_y = SAFE_ALLOC(w, 2, fixed_y_t);
|
||||
fixed_t* const best_uv_base = SAFE_ALLOC(uv_w * 3, uv_h, fixed_t);
|
||||
fixed_t* const target_uv_base = SAFE_ALLOC(uv_w * 3, uv_h, fixed_t);
|
||||
fixed_t* const best_rgb_uv = SAFE_ALLOC(uv_w * 3, 1, fixed_t);
|
||||
fixed_y_t* best_y = best_y_base;
|
||||
fixed_y_t* target_y = target_y_base;
|
||||
fixed_t* best_uv = best_uv_base;
|
||||
fixed_t* target_uv = target_uv_base;
|
||||
const uint64_t diff_y_threshold = (uint64_t)(3.0 * w * h);
|
||||
int ok;
|
||||
assert(w > 0);
|
||||
assert(h > 0);
|
||||
|
||||
if (best_y_base == NULL || best_uv_base == NULL ||
|
||||
target_y_base == NULL || target_uv_base == NULL ||
|
||||
best_rgb_y == NULL || best_rgb_uv == NULL ||
|
||||
tmp_buffer == NULL) {
|
||||
ok = 0;
|
||||
goto End;
|
||||
}
|
||||
|
||||
// Import RGB samples to W/RGB representation.
|
||||
for (j = 0; j < height; j += 2) {
|
||||
const int is_last_row = (j == height - 1);
|
||||
fixed_y_t* const src1 = tmp_buffer + 0 * w;
|
||||
fixed_y_t* const src2 = tmp_buffer + 3 * w;
|
||||
|
||||
// prepare two rows of input
|
||||
ImportOneRow(r_ptr, g_ptr, b_ptr, rgb_step, rgb_bit_depth, width,
|
||||
src1);
|
||||
if (!is_last_row) {
|
||||
ImportOneRow(r_ptr + rgb_stride, g_ptr + rgb_stride, b_ptr + rgb_stride,
|
||||
rgb_step, rgb_bit_depth, width, src2);
|
||||
} else {
|
||||
memcpy(src2, src1, 3 * w * sizeof(*src2));
|
||||
}
|
||||
StoreGray(src1, best_y + 0, w);
|
||||
StoreGray(src2, best_y + w, w);
|
||||
|
||||
UpdateW(src1, target_y, w, rgb_bit_depth, transfer_type);
|
||||
UpdateW(src2, target_y + w, w, rgb_bit_depth, transfer_type);
|
||||
UpdateChroma(src1, src2, target_uv, uv_w, rgb_bit_depth, transfer_type);
|
||||
memcpy(best_uv, target_uv, 3 * uv_w * sizeof(*best_uv));
|
||||
best_y += 2 * w;
|
||||
best_uv += 3 * uv_w;
|
||||
target_y += 2 * w;
|
||||
target_uv += 3 * uv_w;
|
||||
r_ptr += 2 * rgb_stride;
|
||||
g_ptr += 2 * rgb_stride;
|
||||
b_ptr += 2 * rgb_stride;
|
||||
}
|
||||
|
||||
// Iterate and resolve clipping conflicts.
|
||||
for (iter = 0; iter < kNumIterations; ++iter) {
|
||||
const fixed_t* cur_uv = best_uv_base;
|
||||
const fixed_t* prev_uv = best_uv_base;
|
||||
uint64_t diff_y_sum = 0;
|
||||
|
||||
best_y = best_y_base;
|
||||
best_uv = best_uv_base;
|
||||
target_y = target_y_base;
|
||||
target_uv = target_uv_base;
|
||||
for (j = 0; j < h; j += 2) {
|
||||
fixed_y_t* const src1 = tmp_buffer + 0 * w;
|
||||
fixed_y_t* const src2 = tmp_buffer + 3 * w;
|
||||
{
|
||||
const fixed_t* const next_uv = cur_uv + ((j < h - 2) ? 3 * uv_w : 0);
|
||||
InterpolateTwoRows(best_y, prev_uv, cur_uv, next_uv, w,
|
||||
src1, src2, rgb_bit_depth);
|
||||
prev_uv = cur_uv;
|
||||
cur_uv = next_uv;
|
||||
}
|
||||
|
||||
UpdateW(src1, best_rgb_y + 0 * w, w, rgb_bit_depth, transfer_type);
|
||||
UpdateW(src2, best_rgb_y + 1 * w, w, rgb_bit_depth, transfer_type);
|
||||
UpdateChroma(src1, src2, best_rgb_uv, uv_w, rgb_bit_depth, transfer_type);
|
||||
|
||||
// update two rows of Y and one row of RGB
|
||||
diff_y_sum +=
|
||||
SharpYuvUpdateY(target_y, best_rgb_y, best_y, 2 * w,
|
||||
rgb_bit_depth + GetPrecisionShift(rgb_bit_depth));
|
||||
SharpYuvUpdateRGB(target_uv, best_rgb_uv, best_uv, 3 * uv_w);
|
||||
|
||||
best_y += 2 * w;
|
||||
best_uv += 3 * uv_w;
|
||||
target_y += 2 * w;
|
||||
target_uv += 3 * uv_w;
|
||||
}
|
||||
// test exit condition
|
||||
if (iter > 0) {
|
||||
if (diff_y_sum < diff_y_threshold) break;
|
||||
if (diff_y_sum > prev_diff_y_sum) break;
|
||||
}
|
||||
prev_diff_y_sum = diff_y_sum;
|
||||
}
|
||||
|
||||
// final reconstruction
|
||||
ok = ConvertWRGBToYUV(best_y_base, best_uv_base, y_ptr, y_stride, u_ptr,
|
||||
u_stride, v_ptr, v_stride, rgb_bit_depth, yuv_bit_depth,
|
||||
width, height, yuv_matrix);
|
||||
|
||||
End:
|
||||
free(best_y_base);
|
||||
free(best_uv_base);
|
||||
free(target_y_base);
|
||||
free(target_uv_base);
|
||||
free(best_rgb_y);
|
||||
free(best_rgb_uv);
|
||||
free(tmp_buffer);
|
||||
return ok;
|
||||
}
|
||||
#undef SAFE_ALLOC
|
||||
|
||||
#if defined(WEBP_USE_THREAD) && !defined(_WIN32)
|
||||
#include <pthread.h> // NOLINT
|
||||
|
||||
#define LOCK_ACCESS \
|
||||
static pthread_mutex_t sharpyuv_lock = PTHREAD_MUTEX_INITIALIZER; \
|
||||
if (pthread_mutex_lock(&sharpyuv_lock)) return
|
||||
#define UNLOCK_ACCESS_AND_RETURN \
|
||||
do { \
|
||||
(void)pthread_mutex_unlock(&sharpyuv_lock); \
|
||||
return; \
|
||||
} while (0)
|
||||
#else // !(defined(WEBP_USE_THREAD) && !defined(_WIN32))
|
||||
#define LOCK_ACCESS do {} while (0)
|
||||
#define UNLOCK_ACCESS_AND_RETURN return
|
||||
#endif // defined(WEBP_USE_THREAD) && !defined(_WIN32)
|
||||
|
||||
// Hidden exported init function.
|
||||
// By default SharpYuvConvert calls it with SharpYuvGetCPUInfo. If needed,
|
||||
// users can declare it as extern and call it with an alternate VP8CPUInfo
|
||||
// function.
|
||||
extern VP8CPUInfo SharpYuvGetCPUInfo;
|
||||
SHARPYUV_EXTERN void SharpYuvInit(VP8CPUInfo cpu_info_func);
|
||||
void SharpYuvInit(VP8CPUInfo cpu_info_func) {
|
||||
static volatile VP8CPUInfo sharpyuv_last_cpuinfo_used =
|
||||
(VP8CPUInfo)&sharpyuv_last_cpuinfo_used;
|
||||
LOCK_ACCESS;
|
||||
// Only update SharpYuvGetCPUInfo when called from external code to avoid a
|
||||
// race on reading the value in SharpYuvConvert().
|
||||
if (cpu_info_func != (VP8CPUInfo)&SharpYuvGetCPUInfo) {
|
||||
SharpYuvGetCPUInfo = cpu_info_func;
|
||||
}
|
||||
if (sharpyuv_last_cpuinfo_used == SharpYuvGetCPUInfo) {
|
||||
UNLOCK_ACCESS_AND_RETURN;
|
||||
}
|
||||
|
||||
SharpYuvInitDsp();
|
||||
SharpYuvInitGammaTables();
|
||||
|
||||
sharpyuv_last_cpuinfo_used = SharpYuvGetCPUInfo;
|
||||
UNLOCK_ACCESS_AND_RETURN;
|
||||
}
|
||||
|
||||
int SharpYuvConvert(const void* r_ptr, const void* g_ptr, const void* b_ptr,
|
||||
int rgb_step, int rgb_stride, int rgb_bit_depth,
|
||||
void* y_ptr, int y_stride, void* u_ptr, int u_stride,
|
||||
void* v_ptr, int v_stride, int yuv_bit_depth, int width,
|
||||
int height, const SharpYuvConversionMatrix* yuv_matrix) {
|
||||
SharpYuvOptions options;
|
||||
options.yuv_matrix = yuv_matrix;
|
||||
options.transfer_type = kSharpYuvTransferFunctionSrgb;
|
||||
return SharpYuvConvertWithOptions(
|
||||
r_ptr, g_ptr, b_ptr, rgb_step, rgb_stride, rgb_bit_depth, y_ptr, y_stride,
|
||||
u_ptr, u_stride, v_ptr, v_stride, yuv_bit_depth, width, height, &options);
|
||||
}
|
||||
|
||||
int SharpYuvOptionsInitInternal(const SharpYuvConversionMatrix* yuv_matrix,
|
||||
SharpYuvOptions* options, int version) {
|
||||
const int major = (version >> 24);
|
||||
const int minor = (version >> 16) & 0xff;
|
||||
if (options == NULL || yuv_matrix == NULL ||
|
||||
(major == SHARPYUV_VERSION_MAJOR && major == 0 &&
|
||||
minor != SHARPYUV_VERSION_MINOR) ||
|
||||
(major != SHARPYUV_VERSION_MAJOR)) {
|
||||
return 0;
|
||||
}
|
||||
options->yuv_matrix = yuv_matrix;
|
||||
options->transfer_type = kSharpYuvTransferFunctionSrgb;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SharpYuvConvertWithOptions(const void* r_ptr, const void* g_ptr,
|
||||
const void* b_ptr, int rgb_step, int rgb_stride,
|
||||
int rgb_bit_depth, void* y_ptr, int y_stride,
|
||||
void* u_ptr, int u_stride, void* v_ptr,
|
||||
int v_stride, int yuv_bit_depth, int width,
|
||||
int height, const SharpYuvOptions* options) {
|
||||
const SharpYuvConversionMatrix* yuv_matrix = options->yuv_matrix;
|
||||
SharpYuvTransferFunctionType transfer_type = options->transfer_type;
|
||||
SharpYuvConversionMatrix scaled_matrix;
|
||||
const int rgb_max = (1 << rgb_bit_depth) - 1;
|
||||
const int rgb_round = 1 << (rgb_bit_depth - 1);
|
||||
const int yuv_max = (1 << yuv_bit_depth) - 1;
|
||||
const int sfix = GetPrecisionShift(rgb_bit_depth);
|
||||
|
||||
if (width < 1 || height < 1 || width == INT_MAX || height == INT_MAX ||
|
||||
r_ptr == NULL || g_ptr == NULL || b_ptr == NULL || y_ptr == NULL ||
|
||||
u_ptr == NULL || v_ptr == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (rgb_bit_depth != 8 && rgb_bit_depth != 10 && rgb_bit_depth != 12 &&
|
||||
rgb_bit_depth != 16) {
|
||||
return 0;
|
||||
}
|
||||
if (yuv_bit_depth != 8 && yuv_bit_depth != 10 && yuv_bit_depth != 12) {
|
||||
return 0;
|
||||
}
|
||||
if (rgb_bit_depth > 8 && (rgb_step % 2 != 0 || rgb_stride %2 != 0)) {
|
||||
// Step/stride should be even for uint16_t buffers.
|
||||
return 0;
|
||||
}
|
||||
if (yuv_bit_depth > 8 &&
|
||||
(y_stride % 2 != 0 || u_stride % 2 != 0 || v_stride % 2 != 0)) {
|
||||
// Stride should be even for uint16_t buffers.
|
||||
return 0;
|
||||
}
|
||||
// The address of the function pointer is used to avoid a read race.
|
||||
SharpYuvInit((VP8CPUInfo)&SharpYuvGetCPUInfo);
|
||||
|
||||
// Add scaling factor to go from rgb_bit_depth to yuv_bit_depth, to the
|
||||
// rgb->yuv conversion matrix.
|
||||
if (rgb_bit_depth == yuv_bit_depth) {
|
||||
memcpy(&scaled_matrix, yuv_matrix, sizeof(scaled_matrix));
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < 3; ++i) {
|
||||
scaled_matrix.rgb_to_y[i] =
|
||||
(yuv_matrix->rgb_to_y[i] * yuv_max + rgb_round) / rgb_max;
|
||||
scaled_matrix.rgb_to_u[i] =
|
||||
(yuv_matrix->rgb_to_u[i] * yuv_max + rgb_round) / rgb_max;
|
||||
scaled_matrix.rgb_to_v[i] =
|
||||
(yuv_matrix->rgb_to_v[i] * yuv_max + rgb_round) / rgb_max;
|
||||
}
|
||||
}
|
||||
// Also incorporate precision change scaling.
|
||||
scaled_matrix.rgb_to_y[3] = Shift(yuv_matrix->rgb_to_y[3], sfix);
|
||||
scaled_matrix.rgb_to_u[3] = Shift(yuv_matrix->rgb_to_u[3], sfix);
|
||||
scaled_matrix.rgb_to_v[3] = Shift(yuv_matrix->rgb_to_v[3], sfix);
|
||||
|
||||
return DoSharpArgbToYuv(r_ptr, g_ptr, b_ptr, rgb_step, rgb_stride,
|
||||
rgb_bit_depth, y_ptr, y_stride, u_ptr, u_stride,
|
||||
v_ptr, v_stride, yuv_bit_depth, width, height,
|
||||
&scaled_matrix, transfer_type);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Vendored
+174
@@ -0,0 +1,174 @@
|
||||
// Copyright 2022 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Sharp RGB to YUV conversion.
|
||||
|
||||
#ifndef WEBP_SHARPYUV_SHARPYUV_H_
|
||||
#define WEBP_SHARPYUV_SHARPYUV_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef SHARPYUV_EXTERN
|
||||
#ifdef WEBP_EXTERN
|
||||
#define SHARPYUV_EXTERN WEBP_EXTERN
|
||||
#else
|
||||
// This explicitly marks library functions and allows for changing the
|
||||
// signature for e.g., Windows DLL builds.
|
||||
#if defined(__GNUC__) && __GNUC__ >= 4
|
||||
#define SHARPYUV_EXTERN extern __attribute__((visibility("default")))
|
||||
#else
|
||||
#if defined(_MSC_VER) && defined(WEBP_DLL)
|
||||
#define SHARPYUV_EXTERN __declspec(dllexport)
|
||||
#else
|
||||
#define SHARPYUV_EXTERN extern
|
||||
#endif /* _MSC_VER && WEBP_DLL */
|
||||
#endif /* __GNUC__ >= 4 */
|
||||
#endif /* WEBP_EXTERN */
|
||||
#endif /* SHARPYUV_EXTERN */
|
||||
|
||||
#ifndef SHARPYUV_INLINE
|
||||
#ifdef WEBP_INLINE
|
||||
#define SHARPYUV_INLINE WEBP_INLINE
|
||||
#else
|
||||
#ifndef _MSC_VER
|
||||
#if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \
|
||||
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
|
||||
#define SHARPYUV_INLINE inline
|
||||
#else
|
||||
#define SHARPYUV_INLINE
|
||||
#endif
|
||||
#else
|
||||
#define SHARPYUV_INLINE __forceinline
|
||||
#endif /* _MSC_VER */
|
||||
#endif /* WEBP_INLINE */
|
||||
#endif /* SHARPYUV_INLINE */
|
||||
|
||||
// SharpYUV API version following the convention from semver.org
|
||||
#define SHARPYUV_VERSION_MAJOR 0
|
||||
#define SHARPYUV_VERSION_MINOR 4
|
||||
#define SHARPYUV_VERSION_PATCH 0
|
||||
// Version as a uint32_t. The major number is the high 8 bits.
|
||||
// The minor number is the middle 8 bits. The patch number is the low 16 bits.
|
||||
#define SHARPYUV_MAKE_VERSION(MAJOR, MINOR, PATCH) \
|
||||
(((MAJOR) << 24) | ((MINOR) << 16) | (PATCH))
|
||||
#define SHARPYUV_VERSION \
|
||||
SHARPYUV_MAKE_VERSION(SHARPYUV_VERSION_MAJOR, SHARPYUV_VERSION_MINOR, \
|
||||
SHARPYUV_VERSION_PATCH)
|
||||
|
||||
// Returns the library's version number, packed in hexadecimal. See
|
||||
// SHARPYUV_VERSION.
|
||||
SHARPYUV_EXTERN int SharpYuvGetVersion(void);
|
||||
|
||||
// RGB to YUV conversion matrix, in 16 bit fixed point.
|
||||
// y = rgb_to_y[0] * r + rgb_to_y[1] * g + rgb_to_y[2] * b + rgb_to_y[3]
|
||||
// u = rgb_to_u[0] * r + rgb_to_u[1] * g + rgb_to_u[2] * b + rgb_to_u[3]
|
||||
// v = rgb_to_v[0] * r + rgb_to_v[1] * g + rgb_to_v[2] * b + rgb_to_v[3]
|
||||
// Then y, u and v values are divided by 1<<16 and rounded.
|
||||
typedef struct {
|
||||
int rgb_to_y[4];
|
||||
int rgb_to_u[4];
|
||||
int rgb_to_v[4];
|
||||
} SharpYuvConversionMatrix;
|
||||
|
||||
typedef struct SharpYuvOptions SharpYuvOptions;
|
||||
|
||||
// Enums for transfer functions, as defined in H.273,
|
||||
// https://www.itu.int/rec/T-REC-H.273-202107-I/en
|
||||
typedef enum SharpYuvTransferFunctionType {
|
||||
// 0 is reserved
|
||||
kSharpYuvTransferFunctionBt709 = 1,
|
||||
// 2 is unspecified
|
||||
// 3 is reserved
|
||||
kSharpYuvTransferFunctionBt470M = 4,
|
||||
kSharpYuvTransferFunctionBt470Bg = 5,
|
||||
kSharpYuvTransferFunctionBt601 = 6,
|
||||
kSharpYuvTransferFunctionSmpte240 = 7,
|
||||
kSharpYuvTransferFunctionLinear = 8,
|
||||
kSharpYuvTransferFunctionLog100 = 9,
|
||||
kSharpYuvTransferFunctionLog100_Sqrt10 = 10,
|
||||
kSharpYuvTransferFunctionIec61966 = 11,
|
||||
kSharpYuvTransferFunctionBt1361 = 12,
|
||||
kSharpYuvTransferFunctionSrgb = 13,
|
||||
kSharpYuvTransferFunctionBt2020_10Bit = 14,
|
||||
kSharpYuvTransferFunctionBt2020_12Bit = 15,
|
||||
kSharpYuvTransferFunctionSmpte2084 = 16, // PQ
|
||||
kSharpYuvTransferFunctionSmpte428 = 17,
|
||||
kSharpYuvTransferFunctionHlg = 18,
|
||||
kSharpYuvTransferFunctionNum
|
||||
} SharpYuvTransferFunctionType;
|
||||
|
||||
// Converts RGB to YUV420 using a downsampling algorithm that minimizes
|
||||
// artefacts caused by chroma subsampling.
|
||||
// This is slower than standard downsampling (averaging of 4 UV values).
|
||||
// Assumes that the image will be upsampled using a bilinear filter. If nearest
|
||||
// neighbor is used instead, the upsampled image might look worse than with
|
||||
// standard downsampling.
|
||||
// r_ptr, g_ptr, b_ptr: pointers to the source r, g and b channels. Should point
|
||||
// to uint8_t buffers if rgb_bit_depth is 8, or uint16_t buffers otherwise.
|
||||
// rgb_step: distance in bytes between two horizontally adjacent pixels on the
|
||||
// r, g and b channels. If rgb_bit_depth is > 8, it should be a
|
||||
// multiple of 2.
|
||||
// rgb_stride: distance in bytes between two vertically adjacent pixels on the
|
||||
// r, g, and b channels. If rgb_bit_depth is > 8, it should be a
|
||||
// multiple of 2.
|
||||
// rgb_bit_depth: number of bits for each r/g/b value. One of: 8, 10, 12, 16.
|
||||
// Note: 16 bit input is truncated to 14 bits before conversion to yuv.
|
||||
// yuv_bit_depth: number of bits for each y/u/v value. One of: 8, 10, 12.
|
||||
// y_ptr, u_ptr, v_ptr: pointers to the destination y, u and v channels. Should
|
||||
// point to uint8_t buffers if yuv_bit_depth is 8, or uint16_t buffers
|
||||
// otherwise.
|
||||
// y_stride, u_stride, v_stride: distance in bytes between two vertically
|
||||
// adjacent pixels on the y, u and v channels. If yuv_bit_depth > 8, they
|
||||
// should be multiples of 2.
|
||||
// width, height: width and height of the image in pixels
|
||||
// This function calls SharpYuvConvertWithOptions with a default transfer
|
||||
// function of kSharpYuvTransferFunctionSrgb.
|
||||
SHARPYUV_EXTERN int SharpYuvConvert(const void* r_ptr, const void* g_ptr,
|
||||
const void* b_ptr, int rgb_step,
|
||||
int rgb_stride, int rgb_bit_depth,
|
||||
void* y_ptr, int y_stride, void* u_ptr,
|
||||
int u_stride, void* v_ptr, int v_stride,
|
||||
int yuv_bit_depth, int width, int height,
|
||||
const SharpYuvConversionMatrix* yuv_matrix);
|
||||
|
||||
struct SharpYuvOptions {
|
||||
// This matrix cannot be NULL and can be initialized by
|
||||
// SharpYuvComputeConversionMatrix.
|
||||
const SharpYuvConversionMatrix* yuv_matrix;
|
||||
SharpYuvTransferFunctionType transfer_type;
|
||||
};
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
SHARPYUV_EXTERN int SharpYuvOptionsInitInternal(const SharpYuvConversionMatrix*,
|
||||
SharpYuvOptions*, int);
|
||||
|
||||
// Should always be called, to initialize a fresh SharpYuvOptions
|
||||
// structure before modification. SharpYuvOptionsInit() must have succeeded
|
||||
// before using the 'options' object.
|
||||
static SHARPYUV_INLINE int SharpYuvOptionsInit(
|
||||
const SharpYuvConversionMatrix* yuv_matrix, SharpYuvOptions* options) {
|
||||
return SharpYuvOptionsInitInternal(yuv_matrix, options, SHARPYUV_VERSION);
|
||||
}
|
||||
|
||||
SHARPYUV_EXTERN int SharpYuvConvertWithOptions(
|
||||
const void* r_ptr, const void* g_ptr, const void* b_ptr, int rgb_step,
|
||||
int rgb_stride, int rgb_bit_depth, void* y_ptr, int y_stride, void* u_ptr,
|
||||
int u_stride, void* v_ptr, int v_stride, int yuv_bit_depth, int width,
|
||||
int height, const SharpYuvOptions* options);
|
||||
|
||||
// TODO(b/194336375): Add YUV444 to YUV420 conversion. Maybe also add 422
|
||||
// support (it's rarely used in practice, especially for images).
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // WEBP_SHARPYUV_SHARPYUV_H_
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// Copyright 2022 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
#include "sharpyuv/sharpyuv_cpu.h"
|
||||
|
||||
// Include src/dsp/cpu.c to create SharpYuvGetCPUInfo from VP8GetCPUInfo. The
|
||||
// function pointer is renamed in sharpyuv_cpu.h.
|
||||
#include "src/dsp/cpu.c"
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// Copyright 2022 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
#ifndef WEBP_SHARPYUV_SHARPYUV_CPU_H_
|
||||
#define WEBP_SHARPYUV_SHARPYUV_CPU_H_
|
||||
|
||||
#include "sharpyuv/sharpyuv.h"
|
||||
|
||||
// Avoid exporting SharpYuvGetCPUInfo in shared object / DLL builds.
|
||||
// SharpYuvInit() replaces the use of the function pointer.
|
||||
#undef WEBP_EXTERN
|
||||
#define WEBP_EXTERN extern
|
||||
#define VP8GetCPUInfo SharpYuvGetCPUInfo
|
||||
#include "src/dsp/cpu.h"
|
||||
|
||||
#endif // WEBP_SHARPYUV_SHARPYUV_CPU_H_
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
// Copyright 2022 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Colorspace utilities.
|
||||
|
||||
#include "sharpyuv/sharpyuv_csp.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
|
||||
static int ToFixed16(float f) { return (int)floor(f * (1 << 16) + 0.5f); }
|
||||
|
||||
void SharpYuvComputeConversionMatrix(const SharpYuvColorSpace* yuv_color_space,
|
||||
SharpYuvConversionMatrix* matrix) {
|
||||
const float kr = yuv_color_space->kr;
|
||||
const float kb = yuv_color_space->kb;
|
||||
const float kg = 1.0f - kr - kb;
|
||||
const float cr = 0.5f / (1.0f - kb);
|
||||
const float cb = 0.5f / (1.0f - kr);
|
||||
|
||||
const int shift = yuv_color_space->bit_depth - 8;
|
||||
|
||||
const float denom = (float)((1 << yuv_color_space->bit_depth) - 1);
|
||||
float scale_y = 1.0f;
|
||||
float add_y = 0.0f;
|
||||
float scale_u = cr;
|
||||
float scale_v = cb;
|
||||
float add_uv = (float)(128 << shift);
|
||||
assert(yuv_color_space->bit_depth >= 8);
|
||||
|
||||
if (yuv_color_space->range == kSharpYuvRangeLimited) {
|
||||
scale_y *= (219 << shift) / denom;
|
||||
scale_u *= (224 << shift) / denom;
|
||||
scale_v *= (224 << shift) / denom;
|
||||
add_y = (float)(16 << shift);
|
||||
}
|
||||
|
||||
matrix->rgb_to_y[0] = ToFixed16(kr * scale_y);
|
||||
matrix->rgb_to_y[1] = ToFixed16(kg * scale_y);
|
||||
matrix->rgb_to_y[2] = ToFixed16(kb * scale_y);
|
||||
matrix->rgb_to_y[3] = ToFixed16(add_y);
|
||||
|
||||
matrix->rgb_to_u[0] = ToFixed16(-kr * scale_u);
|
||||
matrix->rgb_to_u[1] = ToFixed16(-kg * scale_u);
|
||||
matrix->rgb_to_u[2] = ToFixed16((1 - kb) * scale_u);
|
||||
matrix->rgb_to_u[3] = ToFixed16(add_uv);
|
||||
|
||||
matrix->rgb_to_v[0] = ToFixed16((1 - kr) * scale_v);
|
||||
matrix->rgb_to_v[1] = ToFixed16(-kg * scale_v);
|
||||
matrix->rgb_to_v[2] = ToFixed16(-kb * scale_v);
|
||||
matrix->rgb_to_v[3] = ToFixed16(add_uv);
|
||||
}
|
||||
|
||||
// Matrices are in YUV_FIX fixed point precision.
|
||||
// WebP's matrix, similar but not identical to kRec601LimitedMatrix.
|
||||
static const SharpYuvConversionMatrix kWebpMatrix = {
|
||||
{16839, 33059, 6420, 16 << 16},
|
||||
{-9719, -19081, 28800, 128 << 16},
|
||||
{28800, -24116, -4684, 128 << 16},
|
||||
};
|
||||
// Kr=0.2990f Kb=0.1140f bits=8 range=kSharpYuvRangeLimited
|
||||
static const SharpYuvConversionMatrix kRec601LimitedMatrix = {
|
||||
{16829, 33039, 6416, 16 << 16},
|
||||
{-9714, -19071, 28784, 128 << 16},
|
||||
{28784, -24103, -4681, 128 << 16},
|
||||
};
|
||||
// Kr=0.2990f Kb=0.1140f bits=8 range=kSharpYuvRangeFull
|
||||
static const SharpYuvConversionMatrix kRec601FullMatrix = {
|
||||
{19595, 38470, 7471, 0},
|
||||
{-11058, -21710, 32768, 128 << 16},
|
||||
{32768, -27439, -5329, 128 << 16},
|
||||
};
|
||||
// Kr=0.2126f Kb=0.0722f bits=8 range=kSharpYuvRangeLimited
|
||||
static const SharpYuvConversionMatrix kRec709LimitedMatrix = {
|
||||
{11966, 40254, 4064, 16 << 16},
|
||||
{-6596, -22189, 28784, 128 << 16},
|
||||
{28784, -26145, -2639, 128 << 16},
|
||||
};
|
||||
// Kr=0.2126f Kb=0.0722f bits=8 range=kSharpYuvRangeFull
|
||||
static const SharpYuvConversionMatrix kRec709FullMatrix = {
|
||||
{13933, 46871, 4732, 0},
|
||||
{-7509, -25259, 32768, 128 << 16},
|
||||
{32768, -29763, -3005, 128 << 16},
|
||||
};
|
||||
|
||||
const SharpYuvConversionMatrix* SharpYuvGetConversionMatrix(
|
||||
SharpYuvMatrixType matrix_type) {
|
||||
switch (matrix_type) {
|
||||
case kSharpYuvMatrixWebp:
|
||||
return &kWebpMatrix;
|
||||
case kSharpYuvMatrixRec601Limited:
|
||||
return &kRec601LimitedMatrix;
|
||||
case kSharpYuvMatrixRec601Full:
|
||||
return &kRec601FullMatrix;
|
||||
case kSharpYuvMatrixRec709Limited:
|
||||
return &kRec709LimitedMatrix;
|
||||
case kSharpYuvMatrixRec709Full:
|
||||
return &kRec709FullMatrix;
|
||||
case kSharpYuvMatrixNum:
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
// Copyright 2022 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Colorspace utilities.
|
||||
|
||||
#ifndef WEBP_SHARPYUV_SHARPYUV_CSP_H_
|
||||
#define WEBP_SHARPYUV_SHARPYUV_CSP_H_
|
||||
|
||||
#include "sharpyuv/sharpyuv.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Range of YUV values.
|
||||
typedef enum {
|
||||
kSharpYuvRangeFull, // YUV values between [0;255] (for 8 bit)
|
||||
kSharpYuvRangeLimited // Y in [16;235], YUV in [16;240] (for 8 bit)
|
||||
} SharpYuvRange;
|
||||
|
||||
// Constants that define a YUV color space.
|
||||
typedef struct {
|
||||
// Kr and Kb are defined such that:
|
||||
// Y = Kr * r + Kg * g + Kb * b where Kg = 1 - Kr - Kb.
|
||||
float kr;
|
||||
float kb;
|
||||
int bit_depth; // 8, 10 or 12
|
||||
SharpYuvRange range;
|
||||
} SharpYuvColorSpace;
|
||||
|
||||
// Fills in 'matrix' for the given YUVColorSpace.
|
||||
SHARPYUV_EXTERN void SharpYuvComputeConversionMatrix(
|
||||
const SharpYuvColorSpace* yuv_color_space,
|
||||
SharpYuvConversionMatrix* matrix);
|
||||
|
||||
// Enums for precomputed conversion matrices.
|
||||
typedef enum {
|
||||
kSharpYuvMatrixWebp = 0,
|
||||
kSharpYuvMatrixRec601Limited,
|
||||
kSharpYuvMatrixRec601Full,
|
||||
kSharpYuvMatrixRec709Limited,
|
||||
kSharpYuvMatrixRec709Full,
|
||||
kSharpYuvMatrixNum
|
||||
} SharpYuvMatrixType;
|
||||
|
||||
// Returns a pointer to a matrix for one of the predefined colorspaces.
|
||||
SHARPYUV_EXTERN const SharpYuvConversionMatrix* SharpYuvGetConversionMatrix(
|
||||
SharpYuvMatrixType matrix_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // WEBP_SHARPYUV_SHARPYUV_CSP_H_
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
// Copyright 2022 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Speed-critical functions for Sharp YUV.
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "sharpyuv/sharpyuv_dsp.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "sharpyuv/sharpyuv_cpu.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
static uint16_t clip(int v, int max) {
|
||||
return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v;
|
||||
}
|
||||
|
||||
static uint64_t SharpYuvUpdateY_C(const uint16_t* ref, const uint16_t* src,
|
||||
uint16_t* dst, int len, int bit_depth) {
|
||||
uint64_t diff = 0;
|
||||
int i;
|
||||
const int max_y = (1 << bit_depth) - 1;
|
||||
for (i = 0; i < len; ++i) {
|
||||
const int diff_y = ref[i] - src[i];
|
||||
const int new_y = (int)dst[i] + diff_y;
|
||||
dst[i] = clip(new_y, max_y);
|
||||
diff += (uint64_t)abs(diff_y);
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
static void SharpYuvUpdateRGB_C(const int16_t* ref, const int16_t* src,
|
||||
int16_t* dst, int len) {
|
||||
int i;
|
||||
for (i = 0; i < len; ++i) {
|
||||
const int diff_uv = ref[i] - src[i];
|
||||
dst[i] += diff_uv;
|
||||
}
|
||||
}
|
||||
|
||||
static void SharpYuvFilterRow_C(const int16_t* A, const int16_t* B, int len,
|
||||
const uint16_t* best_y, uint16_t* out,
|
||||
int bit_depth) {
|
||||
int i;
|
||||
const int max_y = (1 << bit_depth) - 1;
|
||||
for (i = 0; i < len; ++i, ++A, ++B) {
|
||||
const int v0 = (A[0] * 9 + A[1] * 3 + B[0] * 3 + B[1] + 8) >> 4;
|
||||
const int v1 = (A[1] * 9 + A[0] * 3 + B[1] * 3 + B[0] + 8) >> 4;
|
||||
out[2 * i + 0] = clip(best_y[2 * i + 0] + v0, max_y);
|
||||
out[2 * i + 1] = clip(best_y[2 * i + 1] + v1, max_y);
|
||||
}
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
uint64_t (*SharpYuvUpdateY)(const uint16_t* src, const uint16_t* ref,
|
||||
uint16_t* dst, int len, int bit_depth);
|
||||
void (*SharpYuvUpdateRGB)(const int16_t* src, const int16_t* ref, int16_t* dst,
|
||||
int len);
|
||||
void (*SharpYuvFilterRow)(const int16_t* A, const int16_t* B, int len,
|
||||
const uint16_t* best_y, uint16_t* out,
|
||||
int bit_depth);
|
||||
|
||||
extern VP8CPUInfo SharpYuvGetCPUInfo;
|
||||
extern void InitSharpYuvSSE2(void);
|
||||
extern void InitSharpYuvNEON(void);
|
||||
|
||||
void SharpYuvInitDsp(void) {
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
SharpYuvUpdateY = SharpYuvUpdateY_C;
|
||||
SharpYuvUpdateRGB = SharpYuvUpdateRGB_C;
|
||||
SharpYuvFilterRow = SharpYuvFilterRow_C;
|
||||
#endif
|
||||
|
||||
if (SharpYuvGetCPUInfo != NULL) {
|
||||
#if defined(WEBP_HAVE_SSE2)
|
||||
if (SharpYuvGetCPUInfo(kSSE2)) {
|
||||
InitSharpYuvSSE2();
|
||||
}
|
||||
#endif // WEBP_HAVE_SSE2
|
||||
}
|
||||
|
||||
#if defined(WEBP_HAVE_NEON)
|
||||
if (WEBP_NEON_OMIT_C_CODE ||
|
||||
(SharpYuvGetCPUInfo != NULL && SharpYuvGetCPUInfo(kNEON))) {
|
||||
InitSharpYuvNEON();
|
||||
}
|
||||
#endif // WEBP_HAVE_NEON
|
||||
|
||||
assert(SharpYuvUpdateY != NULL);
|
||||
assert(SharpYuvUpdateRGB != NULL);
|
||||
assert(SharpYuvFilterRow != NULL);
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
// Copyright 2022 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Speed-critical functions for Sharp YUV.
|
||||
|
||||
#ifndef WEBP_SHARPYUV_SHARPYUV_DSP_H_
|
||||
#define WEBP_SHARPYUV_SHARPYUV_DSP_H_
|
||||
|
||||
#include "sharpyuv/sharpyuv_cpu.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
extern uint64_t (*SharpYuvUpdateY)(const uint16_t* src, const uint16_t* ref,
|
||||
uint16_t* dst, int len, int bit_depth);
|
||||
extern void (*SharpYuvUpdateRGB)(const int16_t* src, const int16_t* ref,
|
||||
int16_t* dst, int len);
|
||||
extern void (*SharpYuvFilterRow)(const int16_t* A, const int16_t* B, int len,
|
||||
const uint16_t* best_y, uint16_t* out,
|
||||
int bit_depth);
|
||||
|
||||
void SharpYuvInitDsp(void);
|
||||
|
||||
#endif // WEBP_SHARPYUV_SHARPYUV_DSP_H_
|
||||
+419
@@ -0,0 +1,419 @@
|
||||
// Copyright 2022 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Gamma correction utilities.
|
||||
|
||||
#include "sharpyuv/sharpyuv_gamma.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "src/webp/types.h"
|
||||
|
||||
// Gamma correction compensates loss of resolution during chroma subsampling.
|
||||
// Size of pre-computed table for converting from gamma to linear.
|
||||
#define GAMMA_TO_LINEAR_TAB_BITS 10
|
||||
#define GAMMA_TO_LINEAR_TAB_SIZE (1 << GAMMA_TO_LINEAR_TAB_BITS)
|
||||
static uint32_t kGammaToLinearTabS[GAMMA_TO_LINEAR_TAB_SIZE + 2];
|
||||
#define LINEAR_TO_GAMMA_TAB_BITS 9
|
||||
#define LINEAR_TO_GAMMA_TAB_SIZE (1 << LINEAR_TO_GAMMA_TAB_BITS)
|
||||
static uint32_t kLinearToGammaTabS[LINEAR_TO_GAMMA_TAB_SIZE + 2];
|
||||
|
||||
static const double kGammaF = 1. / 0.45;
|
||||
#define GAMMA_TO_LINEAR_BITS 16
|
||||
|
||||
static volatile int kGammaTablesSOk = 0;
|
||||
void SharpYuvInitGammaTables(void) {
|
||||
assert(GAMMA_TO_LINEAR_BITS <= 16);
|
||||
if (!kGammaTablesSOk) {
|
||||
int v;
|
||||
const double a = 0.09929682680944;
|
||||
const double thresh = 0.018053968510807;
|
||||
const double final_scale = 1 << GAMMA_TO_LINEAR_BITS;
|
||||
// Precompute gamma to linear table.
|
||||
{
|
||||
const double norm = 1. / GAMMA_TO_LINEAR_TAB_SIZE;
|
||||
const double a_rec = 1. / (1. + a);
|
||||
for (v = 0; v <= GAMMA_TO_LINEAR_TAB_SIZE; ++v) {
|
||||
const double g = norm * v;
|
||||
double value;
|
||||
if (g <= thresh * 4.5) {
|
||||
value = g / 4.5;
|
||||
} else {
|
||||
value = pow(a_rec * (g + a), kGammaF);
|
||||
}
|
||||
kGammaToLinearTabS[v] = (uint32_t)(value * final_scale + .5);
|
||||
}
|
||||
// to prevent small rounding errors to cause read-overflow:
|
||||
kGammaToLinearTabS[GAMMA_TO_LINEAR_TAB_SIZE + 1] =
|
||||
kGammaToLinearTabS[GAMMA_TO_LINEAR_TAB_SIZE];
|
||||
}
|
||||
// Precompute linear to gamma table.
|
||||
{
|
||||
const double scale = 1. / LINEAR_TO_GAMMA_TAB_SIZE;
|
||||
for (v = 0; v <= LINEAR_TO_GAMMA_TAB_SIZE; ++v) {
|
||||
const double g = scale * v;
|
||||
double value;
|
||||
if (g <= thresh) {
|
||||
value = 4.5 * g;
|
||||
} else {
|
||||
value = (1. + a) * pow(g, 1. / kGammaF) - a;
|
||||
}
|
||||
kLinearToGammaTabS[v] =
|
||||
(uint32_t)(final_scale * value + 0.5);
|
||||
}
|
||||
// to prevent small rounding errors to cause read-overflow:
|
||||
kLinearToGammaTabS[LINEAR_TO_GAMMA_TAB_SIZE + 1] =
|
||||
kLinearToGammaTabS[LINEAR_TO_GAMMA_TAB_SIZE];
|
||||
}
|
||||
kGammaTablesSOk = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static WEBP_INLINE int Shift(int v, int shift) {
|
||||
return (shift >= 0) ? (v << shift) : (v >> -shift);
|
||||
}
|
||||
|
||||
static WEBP_INLINE uint32_t FixedPointInterpolation(int v, uint32_t* tab,
|
||||
int tab_pos_shift_right,
|
||||
int tab_value_shift) {
|
||||
const uint32_t tab_pos = Shift(v, -tab_pos_shift_right);
|
||||
// fractional part, in 'tab_pos_shift' fixed-point precision
|
||||
const uint32_t x = v - (tab_pos << tab_pos_shift_right); // fractional part
|
||||
// v0 / v1 are in kGammaToLinearBits fixed-point precision (range [0..1])
|
||||
const uint32_t v0 = Shift(tab[tab_pos + 0], tab_value_shift);
|
||||
const uint32_t v1 = Shift(tab[tab_pos + 1], tab_value_shift);
|
||||
// Final interpolation.
|
||||
const uint32_t v2 = (v1 - v0) * x; // note: v1 >= v0.
|
||||
const int half =
|
||||
(tab_pos_shift_right > 0) ? 1 << (tab_pos_shift_right - 1) : 0;
|
||||
const uint32_t result = v0 + ((v2 + half) >> tab_pos_shift_right);
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint32_t ToLinearSrgb(uint16_t v, int bit_depth) {
|
||||
const int shift = GAMMA_TO_LINEAR_TAB_BITS - bit_depth;
|
||||
if (shift > 0) {
|
||||
return kGammaToLinearTabS[v << shift];
|
||||
}
|
||||
return FixedPointInterpolation(v, kGammaToLinearTabS, -shift, 0);
|
||||
}
|
||||
|
||||
static uint16_t FromLinearSrgb(uint32_t value, int bit_depth) {
|
||||
return FixedPointInterpolation(
|
||||
value, kLinearToGammaTabS,
|
||||
(GAMMA_TO_LINEAR_BITS - LINEAR_TO_GAMMA_TAB_BITS),
|
||||
bit_depth - GAMMA_TO_LINEAR_BITS);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define CLAMP(x, low, high) \
|
||||
(((x) < (low)) ? (low) : (((high) < (x)) ? (high) : (x)))
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
static WEBP_INLINE float Roundf(float x) {
|
||||
if (x < 0)
|
||||
return (float)ceil((double)(x - 0.5f));
|
||||
else
|
||||
return (float)floor((double)(x + 0.5f));
|
||||
}
|
||||
|
||||
static WEBP_INLINE float Powf(float base, float exp) {
|
||||
return (float)pow((double)base, (double)exp);
|
||||
}
|
||||
|
||||
static WEBP_INLINE float Log10f(float x) { return (float)log10((double)x); }
|
||||
|
||||
static float ToLinear709(float gamma) {
|
||||
if (gamma < 0.f) {
|
||||
return 0.f;
|
||||
} else if (gamma < 4.5f * 0.018053968510807f) {
|
||||
return gamma / 4.5f;
|
||||
} else if (gamma < 1.f) {
|
||||
return Powf((gamma + 0.09929682680944f) / 1.09929682680944f, 1.f / 0.45f);
|
||||
}
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
static float FromLinear709(float linear) {
|
||||
if (linear < 0.f) {
|
||||
return 0.f;
|
||||
} else if (linear < 0.018053968510807f) {
|
||||
return linear * 4.5f;
|
||||
} else if (linear < 1.f) {
|
||||
return 1.09929682680944f * Powf(linear, 0.45f) - 0.09929682680944f;
|
||||
}
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
static float ToLinear470M(float gamma) {
|
||||
return Powf(CLAMP(gamma, 0.f, 1.f), 1.f / 2.2f);
|
||||
}
|
||||
|
||||
static float FromLinear470M(float linear) {
|
||||
return Powf(CLAMP(linear, 0.f, 1.f), 2.2f);
|
||||
}
|
||||
|
||||
static float ToLinear470Bg(float gamma) {
|
||||
return Powf(CLAMP(gamma, 0.f, 1.f), 1.f / 2.8f);
|
||||
}
|
||||
|
||||
static float FromLinear470Bg(float linear) {
|
||||
return Powf(CLAMP(linear, 0.f, 1.f), 2.8f);
|
||||
}
|
||||
|
||||
static float ToLinearSmpte240(float gamma) {
|
||||
if (gamma < 0.f) {
|
||||
return 0.f;
|
||||
} else if (gamma < 4.f * 0.022821585529445f) {
|
||||
return gamma / 4.f;
|
||||
} else if (gamma < 1.f) {
|
||||
return Powf((gamma + 0.111572195921731f) / 1.111572195921731f, 1.f / 0.45f);
|
||||
}
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
static float FromLinearSmpte240(float linear) {
|
||||
if (linear < 0.f) {
|
||||
return 0.f;
|
||||
} else if (linear < 0.022821585529445f) {
|
||||
return linear * 4.f;
|
||||
} else if (linear < 1.f) {
|
||||
return 1.111572195921731f * Powf(linear, 0.45f) - 0.111572195921731f;
|
||||
}
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
static float ToLinearLog100(float gamma) {
|
||||
return (gamma < 0.01f) ? 0.0f : 1.0f + Log10f(MIN(gamma, 1.f)) / 2.0f;
|
||||
}
|
||||
|
||||
static float FromLinearLog100(float linear) {
|
||||
// The function is non-bijective so choose the middle of [0, 0.01].
|
||||
const float mid_interval = 0.01f / 2.f;
|
||||
return (linear <= 0.0f) ? mid_interval
|
||||
: Powf(10.0f, 2.f * (MIN(linear, 1.f) - 1.0f));
|
||||
}
|
||||
|
||||
static float ToLinearLog100Sqrt10(float gamma) {
|
||||
return (gamma < 0.00316227766f) ? 0.0f
|
||||
: 1.0f + Log10f(MIN(gamma, 1.f)) / 2.5f;
|
||||
}
|
||||
|
||||
static float FromLinearLog100Sqrt10(float linear) {
|
||||
// The function is non-bijective so choose the middle of [0, 0.00316227766f[.
|
||||
const float mid_interval = 0.00316227766f / 2.f;
|
||||
return (linear < 0.0f) ? mid_interval
|
||||
: Powf(10.0f, 2.5f * (MIN(linear, 1.f) - 1.0f));
|
||||
}
|
||||
|
||||
static float ToLinearIec61966(float gamma) {
|
||||
if (gamma <= -4.5f * 0.018053968510807f) {
|
||||
return Powf((-gamma + 0.09929682680944f) / -1.09929682680944f, 1.f / 0.45f);
|
||||
} else if (gamma < 4.5f * 0.018053968510807f) {
|
||||
return gamma / 4.5f;
|
||||
}
|
||||
return Powf((gamma + 0.09929682680944f) / 1.09929682680944f, 1.f / 0.45f);
|
||||
}
|
||||
|
||||
static float FromLinearIec61966(float linear) {
|
||||
if (linear <= -0.018053968510807f) {
|
||||
return -1.09929682680944f * Powf(-linear, 0.45f) + 0.09929682680944f;
|
||||
} else if (linear < 0.018053968510807f) {
|
||||
return linear * 4.5f;
|
||||
}
|
||||
return 1.09929682680944f * Powf(linear, 0.45f) - 0.09929682680944f;
|
||||
}
|
||||
|
||||
static float ToLinearBt1361(float gamma) {
|
||||
if (gamma < -0.25f) {
|
||||
return -0.25f;
|
||||
} else if (gamma < 0.f) {
|
||||
return Powf((gamma - 0.02482420670236f) / -0.27482420670236f, 1.f / 0.45f) /
|
||||
-4.f;
|
||||
} else if (gamma < 4.5f * 0.018053968510807f) {
|
||||
return gamma / 4.5f;
|
||||
} else if (gamma < 1.f) {
|
||||
return Powf((gamma + 0.09929682680944f) / 1.09929682680944f, 1.f / 0.45f);
|
||||
}
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
static float FromLinearBt1361(float linear) {
|
||||
if (linear < -0.25f) {
|
||||
return -0.25f;
|
||||
} else if (linear < 0.f) {
|
||||
return -0.27482420670236f * Powf(-4.f * linear, 0.45f) + 0.02482420670236f;
|
||||
} else if (linear < 0.018053968510807f) {
|
||||
return linear * 4.5f;
|
||||
} else if (linear < 1.f) {
|
||||
return 1.09929682680944f * Powf(linear, 0.45f) - 0.09929682680944f;
|
||||
}
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
static float ToLinearPq(float gamma) {
|
||||
if (gamma > 0.f) {
|
||||
const float pow_gamma = Powf(gamma, 32.f / 2523.f);
|
||||
const float num = MAX(pow_gamma - 107.f / 128.f, 0.0f);
|
||||
const float den = MAX(2413.f / 128.f - 2392.f / 128.f * pow_gamma, FLT_MIN);
|
||||
return Powf(num / den, 4096.f / 653.f);
|
||||
}
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
static float FromLinearPq(float linear) {
|
||||
if (linear > 0.f) {
|
||||
const float pow_linear = Powf(linear, 653.f / 4096.f);
|
||||
const float num = 107.f / 128.f + 2413.f / 128.f * pow_linear;
|
||||
const float den = 1.0f + 2392.f / 128.f * pow_linear;
|
||||
return Powf(num / den, 2523.f / 32.f);
|
||||
}
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
static float ToLinearSmpte428(float gamma) {
|
||||
return Powf(0.91655527974030934f * MAX(gamma, 0.f), 1.f / 2.6f);
|
||||
}
|
||||
|
||||
static float FromLinearSmpte428(float linear) {
|
||||
return Powf(MAX(linear, 0.f), 2.6f) / 0.91655527974030934f;
|
||||
}
|
||||
|
||||
// Conversion in BT.2100 requires RGB info. Simplify to gamma correction here.
|
||||
static float ToLinearHlg(float gamma) {
|
||||
if (gamma < 0.f) {
|
||||
return 0.f;
|
||||
} else if (gamma <= 0.5f) {
|
||||
return Powf((gamma * gamma) * (1.f / 3.f), 1.2f);
|
||||
}
|
||||
return Powf((expf((gamma - 0.55991073f) / 0.17883277f) + 0.28466892f) / 12.0f,
|
||||
1.2f);
|
||||
}
|
||||
|
||||
static float FromLinearHlg(float linear) {
|
||||
linear = Powf(linear, 1.f / 1.2f);
|
||||
if (linear < 0.f) {
|
||||
return 0.f;
|
||||
} else if (linear <= (1.f / 12.f)) {
|
||||
return sqrtf(3.f * linear);
|
||||
}
|
||||
return 0.17883277f * logf(12.f * linear - 0.28466892f) + 0.55991073f;
|
||||
}
|
||||
|
||||
uint32_t SharpYuvGammaToLinear(uint16_t v, int bit_depth,
|
||||
SharpYuvTransferFunctionType transfer_type) {
|
||||
float v_float, linear;
|
||||
if (transfer_type == kSharpYuvTransferFunctionSrgb) {
|
||||
return ToLinearSrgb(v, bit_depth);
|
||||
}
|
||||
v_float = (float)v / ((1 << bit_depth) - 1);
|
||||
switch (transfer_type) {
|
||||
case kSharpYuvTransferFunctionBt709:
|
||||
case kSharpYuvTransferFunctionBt601:
|
||||
case kSharpYuvTransferFunctionBt2020_10Bit:
|
||||
case kSharpYuvTransferFunctionBt2020_12Bit:
|
||||
linear = ToLinear709(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionBt470M:
|
||||
linear = ToLinear470M(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionBt470Bg:
|
||||
linear = ToLinear470Bg(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionSmpte240:
|
||||
linear = ToLinearSmpte240(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionLinear:
|
||||
return v;
|
||||
case kSharpYuvTransferFunctionLog100:
|
||||
linear = ToLinearLog100(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionLog100_Sqrt10:
|
||||
linear = ToLinearLog100Sqrt10(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionIec61966:
|
||||
linear = ToLinearIec61966(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionBt1361:
|
||||
linear = ToLinearBt1361(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionSmpte2084:
|
||||
linear = ToLinearPq(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionSmpte428:
|
||||
linear = ToLinearSmpte428(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionHlg:
|
||||
linear = ToLinearHlg(v_float);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
linear = 0;
|
||||
break;
|
||||
}
|
||||
return (uint32_t)Roundf(linear * ((1 << 16) - 1));
|
||||
}
|
||||
|
||||
uint16_t SharpYuvLinearToGamma(uint32_t v, int bit_depth,
|
||||
SharpYuvTransferFunctionType transfer_type) {
|
||||
float v_float, linear;
|
||||
if (transfer_type == kSharpYuvTransferFunctionSrgb) {
|
||||
return FromLinearSrgb(v, bit_depth);
|
||||
}
|
||||
v_float = (float)v / ((1 << 16) - 1);
|
||||
switch (transfer_type) {
|
||||
case kSharpYuvTransferFunctionBt709:
|
||||
case kSharpYuvTransferFunctionBt601:
|
||||
case kSharpYuvTransferFunctionBt2020_10Bit:
|
||||
case kSharpYuvTransferFunctionBt2020_12Bit:
|
||||
linear = FromLinear709(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionBt470M:
|
||||
linear = FromLinear470M(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionBt470Bg:
|
||||
linear = FromLinear470Bg(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionSmpte240:
|
||||
linear = FromLinearSmpte240(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionLinear:
|
||||
return v;
|
||||
case kSharpYuvTransferFunctionLog100:
|
||||
linear = FromLinearLog100(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionLog100_Sqrt10:
|
||||
linear = FromLinearLog100Sqrt10(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionIec61966:
|
||||
linear = FromLinearIec61966(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionBt1361:
|
||||
linear = FromLinearBt1361(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionSmpte2084:
|
||||
linear = FromLinearPq(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionSmpte428:
|
||||
linear = FromLinearSmpte428(v_float);
|
||||
break;
|
||||
case kSharpYuvTransferFunctionHlg:
|
||||
linear = FromLinearHlg(v_float);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
linear = 0;
|
||||
break;
|
||||
}
|
||||
return (uint16_t)Roundf(linear * ((1 << bit_depth) - 1));
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
// Copyright 2022 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Gamma correction utilities.
|
||||
|
||||
#ifndef WEBP_SHARPYUV_SHARPYUV_GAMMA_H_
|
||||
#define WEBP_SHARPYUV_SHARPYUV_GAMMA_H_
|
||||
|
||||
#include "sharpyuv/sharpyuv.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Initializes precomputed tables. Must be called once before calling
|
||||
// SharpYuvGammaToLinear or SharpYuvLinearToGamma.
|
||||
void SharpYuvInitGammaTables(void);
|
||||
|
||||
// Converts a 'bit_depth'-bit gamma color value to a 16-bit linear value.
|
||||
uint32_t SharpYuvGammaToLinear(uint16_t v, int bit_depth,
|
||||
SharpYuvTransferFunctionType transfer_type);
|
||||
|
||||
// Converts a 16-bit linear color value to a 'bit_depth'-bit gamma value.
|
||||
uint16_t SharpYuvLinearToGamma(uint32_t value, int bit_depth,
|
||||
SharpYuvTransferFunctionType transfer_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // WEBP_SHARPYUV_SHARPYUV_GAMMA_H_
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
// Copyright 2022 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Speed-critical functions for Sharp YUV.
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "sharpyuv/sharpyuv_dsp.h"
|
||||
|
||||
#if defined(WEBP_USE_NEON)
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <arm_neon.h>
|
||||
|
||||
static uint16_t clip_NEON(int v, int max) {
|
||||
return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v;
|
||||
}
|
||||
|
||||
static uint64_t SharpYuvUpdateY_NEON(const uint16_t* ref, const uint16_t* src,
|
||||
uint16_t* dst, int len, int bit_depth) {
|
||||
const int max_y = (1 << bit_depth) - 1;
|
||||
int i;
|
||||
const int16x8_t zero = vdupq_n_s16(0);
|
||||
const int16x8_t max = vdupq_n_s16(max_y);
|
||||
uint64x2_t sum = vdupq_n_u64(0);
|
||||
uint64_t diff;
|
||||
|
||||
for (i = 0; i + 8 <= len; i += 8) {
|
||||
const int16x8_t A = vreinterpretq_s16_u16(vld1q_u16(ref + i));
|
||||
const int16x8_t B = vreinterpretq_s16_u16(vld1q_u16(src + i));
|
||||
const int16x8_t C = vreinterpretq_s16_u16(vld1q_u16(dst + i));
|
||||
const int16x8_t D = vsubq_s16(A, B); // diff_y
|
||||
const int16x8_t F = vaddq_s16(C, D); // new_y
|
||||
const uint16x8_t H =
|
||||
vreinterpretq_u16_s16(vmaxq_s16(vminq_s16(F, max), zero));
|
||||
const int16x8_t I = vabsq_s16(D); // abs(diff_y)
|
||||
vst1q_u16(dst + i, H);
|
||||
sum = vpadalq_u32(sum, vpaddlq_u16(vreinterpretq_u16_s16(I)));
|
||||
}
|
||||
diff = vgetq_lane_u64(sum, 0) + vgetq_lane_u64(sum, 1);
|
||||
for (; i < len; ++i) {
|
||||
const int diff_y = ref[i] - src[i];
|
||||
const int new_y = (int)(dst[i]) + diff_y;
|
||||
dst[i] = clip_NEON(new_y, max_y);
|
||||
diff += (uint64_t)(abs(diff_y));
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
static void SharpYuvUpdateRGB_NEON(const int16_t* ref, const int16_t* src,
|
||||
int16_t* dst, int len) {
|
||||
int i;
|
||||
for (i = 0; i + 8 <= len; i += 8) {
|
||||
const int16x8_t A = vld1q_s16(ref + i);
|
||||
const int16x8_t B = vld1q_s16(src + i);
|
||||
const int16x8_t C = vld1q_s16(dst + i);
|
||||
const int16x8_t D = vsubq_s16(A, B); // diff_uv
|
||||
const int16x8_t E = vaddq_s16(C, D); // new_uv
|
||||
vst1q_s16(dst + i, E);
|
||||
}
|
||||
for (; i < len; ++i) {
|
||||
const int diff_uv = ref[i] - src[i];
|
||||
dst[i] += diff_uv;
|
||||
}
|
||||
}
|
||||
|
||||
static void SharpYuvFilterRow16_NEON(const int16_t* A, const int16_t* B,
|
||||
int len, const uint16_t* best_y,
|
||||
uint16_t* out, int bit_depth) {
|
||||
const int max_y = (1 << bit_depth) - 1;
|
||||
int i;
|
||||
const int16x8_t max = vdupq_n_s16(max_y);
|
||||
const int16x8_t zero = vdupq_n_s16(0);
|
||||
for (i = 0; i + 8 <= len; i += 8) {
|
||||
const int16x8_t a0 = vld1q_s16(A + i + 0);
|
||||
const int16x8_t a1 = vld1q_s16(A + i + 1);
|
||||
const int16x8_t b0 = vld1q_s16(B + i + 0);
|
||||
const int16x8_t b1 = vld1q_s16(B + i + 1);
|
||||
const int16x8_t a0b1 = vaddq_s16(a0, b1);
|
||||
const int16x8_t a1b0 = vaddq_s16(a1, b0);
|
||||
const int16x8_t a0a1b0b1 = vaddq_s16(a0b1, a1b0); // A0+A1+B0+B1
|
||||
const int16x8_t a0b1_2 = vaddq_s16(a0b1, a0b1); // 2*(A0+B1)
|
||||
const int16x8_t a1b0_2 = vaddq_s16(a1b0, a1b0); // 2*(A1+B0)
|
||||
const int16x8_t c0 = vshrq_n_s16(vaddq_s16(a0b1_2, a0a1b0b1), 3);
|
||||
const int16x8_t c1 = vshrq_n_s16(vaddq_s16(a1b0_2, a0a1b0b1), 3);
|
||||
const int16x8_t e0 = vrhaddq_s16(c1, a0);
|
||||
const int16x8_t e1 = vrhaddq_s16(c0, a1);
|
||||
const int16x8x2_t f = vzipq_s16(e0, e1);
|
||||
const int16x8_t g0 = vreinterpretq_s16_u16(vld1q_u16(best_y + 2 * i + 0));
|
||||
const int16x8_t g1 = vreinterpretq_s16_u16(vld1q_u16(best_y + 2 * i + 8));
|
||||
const int16x8_t h0 = vaddq_s16(g0, f.val[0]);
|
||||
const int16x8_t h1 = vaddq_s16(g1, f.val[1]);
|
||||
const int16x8_t i0 = vmaxq_s16(vminq_s16(h0, max), zero);
|
||||
const int16x8_t i1 = vmaxq_s16(vminq_s16(h1, max), zero);
|
||||
vst1q_u16(out + 2 * i + 0, vreinterpretq_u16_s16(i0));
|
||||
vst1q_u16(out + 2 * i + 8, vreinterpretq_u16_s16(i1));
|
||||
}
|
||||
for (; i < len; ++i) {
|
||||
const int a0b1 = A[i + 0] + B[i + 1];
|
||||
const int a1b0 = A[i + 1] + B[i + 0];
|
||||
const int a0a1b0b1 = a0b1 + a1b0 + 8;
|
||||
const int v0 = (8 * A[i + 0] + 2 * a1b0 + a0a1b0b1) >> 4;
|
||||
const int v1 = (8 * A[i + 1] + 2 * a0b1 + a0a1b0b1) >> 4;
|
||||
out[2 * i + 0] = clip_NEON(best_y[2 * i + 0] + v0, max_y);
|
||||
out[2 * i + 1] = clip_NEON(best_y[2 * i + 1] + v1, max_y);
|
||||
}
|
||||
}
|
||||
|
||||
static void SharpYuvFilterRow32_NEON(const int16_t* A, const int16_t* B,
|
||||
int len, const uint16_t* best_y,
|
||||
uint16_t* out, int bit_depth) {
|
||||
const int max_y = (1 << bit_depth) - 1;
|
||||
int i;
|
||||
const uint16x8_t max = vdupq_n_u16(max_y);
|
||||
for (i = 0; i + 4 <= len; i += 4) {
|
||||
const int16x4_t a0 = vld1_s16(A + i + 0);
|
||||
const int16x4_t a1 = vld1_s16(A + i + 1);
|
||||
const int16x4_t b0 = vld1_s16(B + i + 0);
|
||||
const int16x4_t b1 = vld1_s16(B + i + 1);
|
||||
const int32x4_t a0b1 = vaddl_s16(a0, b1);
|
||||
const int32x4_t a1b0 = vaddl_s16(a1, b0);
|
||||
const int32x4_t a0a1b0b1 = vaddq_s32(a0b1, a1b0); // A0+A1+B0+B1
|
||||
const int32x4_t a0b1_2 = vaddq_s32(a0b1, a0b1); // 2*(A0+B1)
|
||||
const int32x4_t a1b0_2 = vaddq_s32(a1b0, a1b0); // 2*(A1+B0)
|
||||
const int32x4_t c0 = vshrq_n_s32(vaddq_s32(a0b1_2, a0a1b0b1), 3);
|
||||
const int32x4_t c1 = vshrq_n_s32(vaddq_s32(a1b0_2, a0a1b0b1), 3);
|
||||
const int32x4_t e0 = vrhaddq_s32(c1, vmovl_s16(a0));
|
||||
const int32x4_t e1 = vrhaddq_s32(c0, vmovl_s16(a1));
|
||||
const int32x4x2_t f = vzipq_s32(e0, e1);
|
||||
|
||||
const int16x8_t g = vreinterpretq_s16_u16(vld1q_u16(best_y + 2 * i));
|
||||
const int32x4_t h0 = vaddw_s16(f.val[0], vget_low_s16(g));
|
||||
const int32x4_t h1 = vaddw_s16(f.val[1], vget_high_s16(g));
|
||||
const uint16x8_t i_16 = vcombine_u16(vqmovun_s32(h0), vqmovun_s32(h1));
|
||||
const uint16x8_t i_clamped = vminq_u16(i_16, max);
|
||||
vst1q_u16(out + 2 * i + 0, i_clamped);
|
||||
}
|
||||
for (; i < len; ++i) {
|
||||
const int a0b1 = A[i + 0] + B[i + 1];
|
||||
const int a1b0 = A[i + 1] + B[i + 0];
|
||||
const int a0a1b0b1 = a0b1 + a1b0 + 8;
|
||||
const int v0 = (8 * A[i + 0] + 2 * a1b0 + a0a1b0b1) >> 4;
|
||||
const int v1 = (8 * A[i + 1] + 2 * a0b1 + a0a1b0b1) >> 4;
|
||||
out[2 * i + 0] = clip_NEON(best_y[2 * i + 0] + v0, max_y);
|
||||
out[2 * i + 1] = clip_NEON(best_y[2 * i + 1] + v1, max_y);
|
||||
}
|
||||
}
|
||||
|
||||
static void SharpYuvFilterRow_NEON(const int16_t* A, const int16_t* B, int len,
|
||||
const uint16_t* best_y, uint16_t* out,
|
||||
int bit_depth) {
|
||||
if (bit_depth <= 10) {
|
||||
SharpYuvFilterRow16_NEON(A, B, len, best_y, out, bit_depth);
|
||||
} else {
|
||||
SharpYuvFilterRow32_NEON(A, B, len, best_y, out, bit_depth);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
extern void InitSharpYuvNEON(void);
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void InitSharpYuvNEON(void) {
|
||||
SharpYuvUpdateY = SharpYuvUpdateY_NEON;
|
||||
SharpYuvUpdateRGB = SharpYuvUpdateRGB_NEON;
|
||||
SharpYuvFilterRow = SharpYuvFilterRow_NEON;
|
||||
}
|
||||
|
||||
#else // !WEBP_USE_NEON
|
||||
|
||||
extern void InitSharpYuvNEON(void);
|
||||
|
||||
void InitSharpYuvNEON(void) {}
|
||||
|
||||
#endif // WEBP_USE_NEON
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
// Copyright 2022 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Speed-critical functions for Sharp YUV.
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "sharpyuv/sharpyuv_dsp.h"
|
||||
|
||||
#if defined(WEBP_USE_SSE2)
|
||||
#include <stdlib.h>
|
||||
#include <emmintrin.h>
|
||||
|
||||
static uint16_t clip_SSE2(int v, int max) {
|
||||
return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v;
|
||||
}
|
||||
|
||||
static uint64_t SharpYuvUpdateY_SSE2(const uint16_t* ref, const uint16_t* src,
|
||||
uint16_t* dst, int len, int bit_depth) {
|
||||
const int max_y = (1 << bit_depth) - 1;
|
||||
uint64_t diff = 0;
|
||||
uint32_t tmp[4];
|
||||
int i;
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
const __m128i max = _mm_set1_epi16(max_y);
|
||||
const __m128i one = _mm_set1_epi16(1);
|
||||
__m128i sum = zero;
|
||||
|
||||
for (i = 0; i + 8 <= len; i += 8) {
|
||||
const __m128i A = _mm_loadu_si128((const __m128i*)(ref + i));
|
||||
const __m128i B = _mm_loadu_si128((const __m128i*)(src + i));
|
||||
const __m128i C = _mm_loadu_si128((const __m128i*)(dst + i));
|
||||
const __m128i D = _mm_sub_epi16(A, B); // diff_y
|
||||
const __m128i E = _mm_cmpgt_epi16(zero, D); // sign (-1 or 0)
|
||||
const __m128i F = _mm_add_epi16(C, D); // new_y
|
||||
const __m128i G = _mm_or_si128(E, one); // -1 or 1
|
||||
const __m128i H = _mm_max_epi16(_mm_min_epi16(F, max), zero);
|
||||
const __m128i I = _mm_madd_epi16(D, G); // sum(abs(...))
|
||||
_mm_storeu_si128((__m128i*)(dst + i), H);
|
||||
sum = _mm_add_epi32(sum, I);
|
||||
}
|
||||
_mm_storeu_si128((__m128i*)tmp, sum);
|
||||
diff = tmp[3] + tmp[2] + tmp[1] + tmp[0];
|
||||
for (; i < len; ++i) {
|
||||
const int diff_y = ref[i] - src[i];
|
||||
const int new_y = (int)dst[i] + diff_y;
|
||||
dst[i] = clip_SSE2(new_y, max_y);
|
||||
diff += (uint64_t)abs(diff_y);
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
static void SharpYuvUpdateRGB_SSE2(const int16_t* ref, const int16_t* src,
|
||||
int16_t* dst, int len) {
|
||||
int i = 0;
|
||||
for (i = 0; i + 8 <= len; i += 8) {
|
||||
const __m128i A = _mm_loadu_si128((const __m128i*)(ref + i));
|
||||
const __m128i B = _mm_loadu_si128((const __m128i*)(src + i));
|
||||
const __m128i C = _mm_loadu_si128((const __m128i*)(dst + i));
|
||||
const __m128i D = _mm_sub_epi16(A, B); // diff_uv
|
||||
const __m128i E = _mm_add_epi16(C, D); // new_uv
|
||||
_mm_storeu_si128((__m128i*)(dst + i), E);
|
||||
}
|
||||
for (; i < len; ++i) {
|
||||
const int diff_uv = ref[i] - src[i];
|
||||
dst[i] += diff_uv;
|
||||
}
|
||||
}
|
||||
|
||||
static void SharpYuvFilterRow16_SSE2(const int16_t* A, const int16_t* B,
|
||||
int len, const uint16_t* best_y,
|
||||
uint16_t* out, int bit_depth) {
|
||||
const int max_y = (1 << bit_depth) - 1;
|
||||
int i;
|
||||
const __m128i kCst8 = _mm_set1_epi16(8);
|
||||
const __m128i max = _mm_set1_epi16(max_y);
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
for (i = 0; i + 8 <= len; i += 8) {
|
||||
const __m128i a0 = _mm_loadu_si128((const __m128i*)(A + i + 0));
|
||||
const __m128i a1 = _mm_loadu_si128((const __m128i*)(A + i + 1));
|
||||
const __m128i b0 = _mm_loadu_si128((const __m128i*)(B + i + 0));
|
||||
const __m128i b1 = _mm_loadu_si128((const __m128i*)(B + i + 1));
|
||||
const __m128i a0b1 = _mm_add_epi16(a0, b1);
|
||||
const __m128i a1b0 = _mm_add_epi16(a1, b0);
|
||||
const __m128i a0a1b0b1 = _mm_add_epi16(a0b1, a1b0); // A0+A1+B0+B1
|
||||
const __m128i a0a1b0b1_8 = _mm_add_epi16(a0a1b0b1, kCst8);
|
||||
const __m128i a0b1_2 = _mm_add_epi16(a0b1, a0b1); // 2*(A0+B1)
|
||||
const __m128i a1b0_2 = _mm_add_epi16(a1b0, a1b0); // 2*(A1+B0)
|
||||
const __m128i c0 = _mm_srai_epi16(_mm_add_epi16(a0b1_2, a0a1b0b1_8), 3);
|
||||
const __m128i c1 = _mm_srai_epi16(_mm_add_epi16(a1b0_2, a0a1b0b1_8), 3);
|
||||
const __m128i d0 = _mm_add_epi16(c1, a0);
|
||||
const __m128i d1 = _mm_add_epi16(c0, a1);
|
||||
const __m128i e0 = _mm_srai_epi16(d0, 1);
|
||||
const __m128i e1 = _mm_srai_epi16(d1, 1);
|
||||
const __m128i f0 = _mm_unpacklo_epi16(e0, e1);
|
||||
const __m128i f1 = _mm_unpackhi_epi16(e0, e1);
|
||||
const __m128i g0 = _mm_loadu_si128((const __m128i*)(best_y + 2 * i + 0));
|
||||
const __m128i g1 = _mm_loadu_si128((const __m128i*)(best_y + 2 * i + 8));
|
||||
const __m128i h0 = _mm_add_epi16(g0, f0);
|
||||
const __m128i h1 = _mm_add_epi16(g1, f1);
|
||||
const __m128i i0 = _mm_max_epi16(_mm_min_epi16(h0, max), zero);
|
||||
const __m128i i1 = _mm_max_epi16(_mm_min_epi16(h1, max), zero);
|
||||
_mm_storeu_si128((__m128i*)(out + 2 * i + 0), i0);
|
||||
_mm_storeu_si128((__m128i*)(out + 2 * i + 8), i1);
|
||||
}
|
||||
for (; i < len; ++i) {
|
||||
// (9 * A0 + 3 * A1 + 3 * B0 + B1 + 8) >> 4 =
|
||||
// = (8 * A0 + 2 * (A1 + B0) + (A0 + A1 + B0 + B1 + 8)) >> 4
|
||||
// We reuse the common sub-expressions.
|
||||
const int a0b1 = A[i + 0] + B[i + 1];
|
||||
const int a1b0 = A[i + 1] + B[i + 0];
|
||||
const int a0a1b0b1 = a0b1 + a1b0 + 8;
|
||||
const int v0 = (8 * A[i + 0] + 2 * a1b0 + a0a1b0b1) >> 4;
|
||||
const int v1 = (8 * A[i + 1] + 2 * a0b1 + a0a1b0b1) >> 4;
|
||||
out[2 * i + 0] = clip_SSE2(best_y[2 * i + 0] + v0, max_y);
|
||||
out[2 * i + 1] = clip_SSE2(best_y[2 * i + 1] + v1, max_y);
|
||||
}
|
||||
}
|
||||
|
||||
static WEBP_INLINE __m128i s16_to_s32(__m128i in) {
|
||||
return _mm_srai_epi32(_mm_unpacklo_epi16(in, in), 16);
|
||||
}
|
||||
|
||||
static void SharpYuvFilterRow32_SSE2(const int16_t* A, const int16_t* B,
|
||||
int len, const uint16_t* best_y,
|
||||
uint16_t* out, int bit_depth) {
|
||||
const int max_y = (1 << bit_depth) - 1;
|
||||
int i;
|
||||
const __m128i kCst8 = _mm_set1_epi32(8);
|
||||
const __m128i max = _mm_set1_epi16(max_y);
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
for (i = 0; i + 4 <= len; i += 4) {
|
||||
const __m128i a0 = s16_to_s32(_mm_loadl_epi64((const __m128i*)(A + i + 0)));
|
||||
const __m128i a1 = s16_to_s32(_mm_loadl_epi64((const __m128i*)(A + i + 1)));
|
||||
const __m128i b0 = s16_to_s32(_mm_loadl_epi64((const __m128i*)(B + i + 0)));
|
||||
const __m128i b1 = s16_to_s32(_mm_loadl_epi64((const __m128i*)(B + i + 1)));
|
||||
const __m128i a0b1 = _mm_add_epi32(a0, b1);
|
||||
const __m128i a1b0 = _mm_add_epi32(a1, b0);
|
||||
const __m128i a0a1b0b1 = _mm_add_epi32(a0b1, a1b0); // A0+A1+B0+B1
|
||||
const __m128i a0a1b0b1_8 = _mm_add_epi32(a0a1b0b1, kCst8);
|
||||
const __m128i a0b1_2 = _mm_add_epi32(a0b1, a0b1); // 2*(A0+B1)
|
||||
const __m128i a1b0_2 = _mm_add_epi32(a1b0, a1b0); // 2*(A1+B0)
|
||||
const __m128i c0 = _mm_srai_epi32(_mm_add_epi32(a0b1_2, a0a1b0b1_8), 3);
|
||||
const __m128i c1 = _mm_srai_epi32(_mm_add_epi32(a1b0_2, a0a1b0b1_8), 3);
|
||||
const __m128i d0 = _mm_add_epi32(c1, a0);
|
||||
const __m128i d1 = _mm_add_epi32(c0, a1);
|
||||
const __m128i e0 = _mm_srai_epi32(d0, 1);
|
||||
const __m128i e1 = _mm_srai_epi32(d1, 1);
|
||||
const __m128i f0 = _mm_unpacklo_epi32(e0, e1);
|
||||
const __m128i f1 = _mm_unpackhi_epi32(e0, e1);
|
||||
const __m128i g = _mm_loadu_si128((const __m128i*)(best_y + 2 * i + 0));
|
||||
const __m128i h_16 = _mm_add_epi16(g, _mm_packs_epi32(f0, f1));
|
||||
const __m128i final = _mm_max_epi16(_mm_min_epi16(h_16, max), zero);
|
||||
_mm_storeu_si128((__m128i*)(out + 2 * i + 0), final);
|
||||
}
|
||||
for (; i < len; ++i) {
|
||||
// (9 * A0 + 3 * A1 + 3 * B0 + B1 + 8) >> 4 =
|
||||
// = (8 * A0 + 2 * (A1 + B0) + (A0 + A1 + B0 + B1 + 8)) >> 4
|
||||
// We reuse the common sub-expressions.
|
||||
const int a0b1 = A[i + 0] + B[i + 1];
|
||||
const int a1b0 = A[i + 1] + B[i + 0];
|
||||
const int a0a1b0b1 = a0b1 + a1b0 + 8;
|
||||
const int v0 = (8 * A[i + 0] + 2 * a1b0 + a0a1b0b1) >> 4;
|
||||
const int v1 = (8 * A[i + 1] + 2 * a0b1 + a0a1b0b1) >> 4;
|
||||
out[2 * i + 0] = clip_SSE2(best_y[2 * i + 0] + v0, max_y);
|
||||
out[2 * i + 1] = clip_SSE2(best_y[2 * i + 1] + v1, max_y);
|
||||
}
|
||||
}
|
||||
|
||||
static void SharpYuvFilterRow_SSE2(const int16_t* A, const int16_t* B, int len,
|
||||
const uint16_t* best_y, uint16_t* out,
|
||||
int bit_depth) {
|
||||
if (bit_depth <= 10) {
|
||||
SharpYuvFilterRow16_SSE2(A, B, len, best_y, out, bit_depth);
|
||||
} else {
|
||||
SharpYuvFilterRow32_SSE2(A, B, len, best_y, out, bit_depth);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
extern void InitSharpYuvSSE2(void);
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void InitSharpYuvSSE2(void) {
|
||||
SharpYuvUpdateY = SharpYuvUpdateY_SSE2;
|
||||
SharpYuvUpdateRGB = SharpYuvUpdateRGB_SSE2;
|
||||
SharpYuvFilterRow = SharpYuvFilterRow_SSE2;
|
||||
}
|
||||
#else // !WEBP_USE_SSE2
|
||||
|
||||
extern void InitSharpYuvSSE2(void);
|
||||
|
||||
void InitSharpYuvSSE2(void) {}
|
||||
|
||||
#endif // WEBP_USE_SSE2
|
||||
Vendored
+19
-18
@@ -117,21 +117,12 @@ static int ALPHDecode(VP8Decoder* const dec, int row, int num_rows) {
|
||||
const uint8_t* deltas = dec->alpha_data_ + ALPHA_HEADER_LEN + row * width;
|
||||
uint8_t* dst = dec->alpha_plane_ + row * width;
|
||||
assert(deltas <= &dec->alpha_data_[dec->alpha_data_size_]);
|
||||
if (alph_dec->filter_ != WEBP_FILTER_NONE) {
|
||||
assert(WebPUnfilters[alph_dec->filter_] != NULL);
|
||||
for (y = 0; y < num_rows; ++y) {
|
||||
WebPUnfilters[alph_dec->filter_](prev_line, deltas, dst, width);
|
||||
prev_line = dst;
|
||||
dst += width;
|
||||
deltas += width;
|
||||
}
|
||||
} else {
|
||||
for (y = 0; y < num_rows; ++y) {
|
||||
memcpy(dst, deltas, width * sizeof(*dst));
|
||||
prev_line = dst;
|
||||
dst += width;
|
||||
deltas += width;
|
||||
}
|
||||
assert(WebPUnfilters[alph_dec->filter_] != NULL);
|
||||
for (y = 0; y < num_rows; ++y) {
|
||||
WebPUnfilters[alph_dec->filter_](prev_line, deltas, dst, width);
|
||||
prev_line = dst;
|
||||
dst += width;
|
||||
deltas += width;
|
||||
}
|
||||
dec->alpha_prev_line_ = prev_line;
|
||||
} else { // alph_dec->method_ == ALPHA_LOSSLESS_COMPRESSION
|
||||
@@ -155,7 +146,8 @@ static int AllocateAlphaPlane(VP8Decoder* const dec, const VP8Io* const io) {
|
||||
dec->alpha_plane_mem_ =
|
||||
(uint8_t*)WebPSafeMalloc(alpha_size, sizeof(*dec->alpha_plane_));
|
||||
if (dec->alpha_plane_mem_ == NULL) {
|
||||
return 0;
|
||||
return VP8SetError(dec, VP8_STATUS_OUT_OF_MEMORY,
|
||||
"Alpha decoder initialization failed.");
|
||||
}
|
||||
dec->alpha_plane_ = dec->alpha_plane_mem_;
|
||||
dec->alpha_prev_line_ = NULL;
|
||||
@@ -183,16 +175,25 @@ const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
|
||||
assert(dec != NULL && io != NULL);
|
||||
|
||||
if (row < 0 || num_rows <= 0 || row + num_rows > height) {
|
||||
return NULL; // sanity check.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!dec->is_alpha_decoded_) {
|
||||
if (dec->alph_dec_ == NULL) { // Initialize decoder.
|
||||
dec->alph_dec_ = ALPHNew();
|
||||
if (dec->alph_dec_ == NULL) return NULL;
|
||||
if (dec->alph_dec_ == NULL) {
|
||||
VP8SetError(dec, VP8_STATUS_OUT_OF_MEMORY,
|
||||
"Alpha decoder initialization failed.");
|
||||
return NULL;
|
||||
}
|
||||
if (!AllocateAlphaPlane(dec, io)) goto Error;
|
||||
if (!ALPHInit(dec->alph_dec_, dec->alpha_data_, dec->alpha_data_size_,
|
||||
io, dec->alpha_plane_)) {
|
||||
VP8LDecoder* const vp8l_dec = dec->alph_dec_->vp8l_dec_;
|
||||
VP8SetError(dec,
|
||||
(vp8l_dec == NULL) ? VP8_STATUS_OUT_OF_MEMORY
|
||||
: vp8l_dec->status_,
|
||||
"Alpha decoder initialization failed.");
|
||||
goto Error;
|
||||
}
|
||||
// if we allowed use of alpha dithering, check whether it's needed at all
|
||||
|
||||
+5
-7
@@ -75,7 +75,7 @@ static VP8StatusCode CheckDecBuffer(const WebPDecBuffer* const buffer) {
|
||||
const WebPRGBABuffer* const buf = &buffer->u.RGBA;
|
||||
const int stride = abs(buf->stride);
|
||||
const uint64_t size =
|
||||
MIN_BUFFER_SIZE(width * kModeBpp[mode], height, stride);
|
||||
MIN_BUFFER_SIZE((uint64_t)width * kModeBpp[mode], height, stride);
|
||||
ok &= (size <= buf->size);
|
||||
ok &= (stride >= width * kModeBpp[mode]);
|
||||
ok &= (buf->rgba != NULL);
|
||||
@@ -102,7 +102,7 @@ static VP8StatusCode AllocateBuffer(WebPDecBuffer* const buffer) {
|
||||
int stride;
|
||||
uint64_t size;
|
||||
|
||||
if ((uint64_t)w * kModeBpp[mode] >= (1ull << 32)) {
|
||||
if ((uint64_t)w * kModeBpp[mode] >= (1ull << 31)) {
|
||||
return VP8_STATUS_INVALID_PARAM;
|
||||
}
|
||||
stride = w * kModeBpp[mode];
|
||||
@@ -117,7 +117,6 @@ static VP8StatusCode AllocateBuffer(WebPDecBuffer* const buffer) {
|
||||
}
|
||||
total_size = size + 2 * uv_size + a_size;
|
||||
|
||||
// Security/sanity checks
|
||||
output = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*output));
|
||||
if (output == NULL) {
|
||||
return VP8_STATUS_OUT_OF_MEMORY;
|
||||
@@ -156,11 +155,11 @@ VP8StatusCode WebPFlipBuffer(WebPDecBuffer* const buffer) {
|
||||
}
|
||||
if (WebPIsRGBMode(buffer->colorspace)) {
|
||||
WebPRGBABuffer* const buf = &buffer->u.RGBA;
|
||||
buf->rgba += (buffer->height - 1) * buf->stride;
|
||||
buf->rgba += (int64_t)(buffer->height - 1) * buf->stride;
|
||||
buf->stride = -buf->stride;
|
||||
} else {
|
||||
WebPYUVABuffer* const buf = &buffer->u.YUVA;
|
||||
const int H = buffer->height;
|
||||
const int64_t H = buffer->height;
|
||||
buf->y += (H - 1) * buf->y_stride;
|
||||
buf->y_stride = -buf->y_stride;
|
||||
buf->u += ((H - 1) >> 1) * buf->u_stride;
|
||||
@@ -188,8 +187,7 @@ VP8StatusCode WebPAllocateDecBuffer(int width, int height,
|
||||
const int ch = options->crop_height;
|
||||
const int x = options->crop_left & ~1;
|
||||
const int y = options->crop_top & ~1;
|
||||
if (x < 0 || y < 0 || cw <= 0 || ch <= 0 ||
|
||||
x + cw > width || y + ch > height) {
|
||||
if (!WebPCheckCropDimensions(width, height, x, y, cw, ch)) {
|
||||
return VP8_STATUS_INVALID_PARAM; // out of frame boundary.
|
||||
}
|
||||
width = cw;
|
||||
|
||||
Vendored
+1
-1
@@ -705,7 +705,7 @@ static int AllocateMemory(VP8Decoder* const dec) {
|
||||
+ cache_size + alpha_size + WEBP_ALIGN_CST;
|
||||
uint8_t* mem;
|
||||
|
||||
if (needed != (size_t)needed) return 0; // check for overflow
|
||||
if (!CheckSizeOverflow(needed)) return 0; // check for overflow
|
||||
if (needed > dec->mem_size_) {
|
||||
WebPSafeFree(dec->mem_);
|
||||
dec->mem_size_ = 0;
|
||||
|
||||
Vendored
+58
-40
@@ -298,46 +298,57 @@ static int InitYUVRescaler(const VP8Io* const io, WebPDecParams* const p) {
|
||||
const int uv_out_height = (out_height + 1) >> 1;
|
||||
const int uv_in_width = (io->mb_w + 1) >> 1;
|
||||
const int uv_in_height = (io->mb_h + 1) >> 1;
|
||||
const size_t work_size = 2 * out_width; // scratch memory for luma rescaler
|
||||
// scratch memory for luma rescaler
|
||||
const size_t work_size = 2 * (size_t)out_width;
|
||||
const size_t uv_work_size = 2 * uv_out_width; // and for each u/v ones
|
||||
size_t tmp_size, rescaler_size;
|
||||
uint64_t total_size;
|
||||
size_t rescaler_size;
|
||||
rescaler_t* work;
|
||||
WebPRescaler* scalers;
|
||||
const int num_rescalers = has_alpha ? 4 : 3;
|
||||
|
||||
tmp_size = (work_size + 2 * uv_work_size) * sizeof(*work);
|
||||
total_size = ((uint64_t)work_size + 2 * uv_work_size) * sizeof(*work);
|
||||
if (has_alpha) {
|
||||
tmp_size += work_size * sizeof(*work);
|
||||
total_size += (uint64_t)work_size * sizeof(*work);
|
||||
}
|
||||
rescaler_size = num_rescalers * sizeof(*p->scaler_y) + WEBP_ALIGN_CST;
|
||||
total_size += rescaler_size;
|
||||
if (!CheckSizeOverflow(total_size)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
p->memory = WebPSafeMalloc(1ULL, tmp_size + rescaler_size);
|
||||
p->memory = WebPSafeMalloc(1ULL, (size_t)total_size);
|
||||
if (p->memory == NULL) {
|
||||
return 0; // memory error
|
||||
}
|
||||
work = (rescaler_t*)p->memory;
|
||||
|
||||
scalers = (WebPRescaler*)WEBP_ALIGN((const uint8_t*)work + tmp_size);
|
||||
scalers = (WebPRescaler*)WEBP_ALIGN(
|
||||
(const uint8_t*)work + total_size - rescaler_size);
|
||||
p->scaler_y = &scalers[0];
|
||||
p->scaler_u = &scalers[1];
|
||||
p->scaler_v = &scalers[2];
|
||||
p->scaler_a = has_alpha ? &scalers[3] : NULL;
|
||||
|
||||
WebPRescalerInit(p->scaler_y, io->mb_w, io->mb_h,
|
||||
buf->y, out_width, out_height, buf->y_stride, 1,
|
||||
work);
|
||||
WebPRescalerInit(p->scaler_u, uv_in_width, uv_in_height,
|
||||
buf->u, uv_out_width, uv_out_height, buf->u_stride, 1,
|
||||
work + work_size);
|
||||
WebPRescalerInit(p->scaler_v, uv_in_width, uv_in_height,
|
||||
buf->v, uv_out_width, uv_out_height, buf->v_stride, 1,
|
||||
work + work_size + uv_work_size);
|
||||
if (!WebPRescalerInit(p->scaler_y, io->mb_w, io->mb_h,
|
||||
buf->y, out_width, out_height, buf->y_stride, 1,
|
||||
work) ||
|
||||
!WebPRescalerInit(p->scaler_u, uv_in_width, uv_in_height,
|
||||
buf->u, uv_out_width, uv_out_height, buf->u_stride, 1,
|
||||
work + work_size) ||
|
||||
!WebPRescalerInit(p->scaler_v, uv_in_width, uv_in_height,
|
||||
buf->v, uv_out_width, uv_out_height, buf->v_stride, 1,
|
||||
work + work_size + uv_work_size)) {
|
||||
return 0;
|
||||
}
|
||||
p->emit = EmitRescaledYUV;
|
||||
|
||||
if (has_alpha) {
|
||||
WebPRescalerInit(p->scaler_a, io->mb_w, io->mb_h,
|
||||
buf->a, out_width, out_height, buf->a_stride, 1,
|
||||
work + work_size + 2 * uv_work_size);
|
||||
if (!WebPRescalerInit(p->scaler_a, io->mb_w, io->mb_h,
|
||||
buf->a, out_width, out_height, buf->a_stride, 1,
|
||||
work + work_size + 2 * uv_work_size)) {
|
||||
return 0;
|
||||
}
|
||||
p->emit_alpha = EmitRescaledAlphaYUV;
|
||||
WebPInitAlphaProcessing();
|
||||
}
|
||||
@@ -480,51 +491,58 @@ static int InitRGBRescaler(const VP8Io* const io, WebPDecParams* const p) {
|
||||
const int out_height = io->scaled_height;
|
||||
const int uv_in_width = (io->mb_w + 1) >> 1;
|
||||
const int uv_in_height = (io->mb_h + 1) >> 1;
|
||||
const size_t work_size = 2 * out_width; // scratch memory for one rescaler
|
||||
// scratch memory for one rescaler
|
||||
const size_t work_size = 2 * (size_t)out_width;
|
||||
rescaler_t* work; // rescalers work area
|
||||
uint8_t* tmp; // tmp storage for scaled YUV444 samples before RGB conversion
|
||||
size_t tmp_size1, tmp_size2, total_size, rescaler_size;
|
||||
uint64_t tmp_size1, tmp_size2, total_size;
|
||||
size_t rescaler_size;
|
||||
WebPRescaler* scalers;
|
||||
const int num_rescalers = has_alpha ? 4 : 3;
|
||||
|
||||
tmp_size1 = 3 * work_size;
|
||||
tmp_size2 = 3 * out_width;
|
||||
if (has_alpha) {
|
||||
tmp_size1 += work_size;
|
||||
tmp_size2 += out_width;
|
||||
}
|
||||
tmp_size1 = (uint64_t)num_rescalers * work_size;
|
||||
tmp_size2 = (uint64_t)num_rescalers * out_width;
|
||||
total_size = tmp_size1 * sizeof(*work) + tmp_size2 * sizeof(*tmp);
|
||||
rescaler_size = num_rescalers * sizeof(*p->scaler_y) + WEBP_ALIGN_CST;
|
||||
total_size += rescaler_size;
|
||||
if (!CheckSizeOverflow(total_size)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
p->memory = WebPSafeMalloc(1ULL, total_size + rescaler_size);
|
||||
p->memory = WebPSafeMalloc(1ULL, (size_t)total_size);
|
||||
if (p->memory == NULL) {
|
||||
return 0; // memory error
|
||||
}
|
||||
work = (rescaler_t*)p->memory;
|
||||
tmp = (uint8_t*)(work + tmp_size1);
|
||||
|
||||
scalers = (WebPRescaler*)WEBP_ALIGN((const uint8_t*)work + total_size);
|
||||
scalers = (WebPRescaler*)WEBP_ALIGN(
|
||||
(const uint8_t*)work + total_size - rescaler_size);
|
||||
p->scaler_y = &scalers[0];
|
||||
p->scaler_u = &scalers[1];
|
||||
p->scaler_v = &scalers[2];
|
||||
p->scaler_a = has_alpha ? &scalers[3] : NULL;
|
||||
|
||||
WebPRescalerInit(p->scaler_y, io->mb_w, io->mb_h,
|
||||
tmp + 0 * out_width, out_width, out_height, 0, 1,
|
||||
work + 0 * work_size);
|
||||
WebPRescalerInit(p->scaler_u, uv_in_width, uv_in_height,
|
||||
tmp + 1 * out_width, out_width, out_height, 0, 1,
|
||||
work + 1 * work_size);
|
||||
WebPRescalerInit(p->scaler_v, uv_in_width, uv_in_height,
|
||||
tmp + 2 * out_width, out_width, out_height, 0, 1,
|
||||
work + 2 * work_size);
|
||||
if (!WebPRescalerInit(p->scaler_y, io->mb_w, io->mb_h,
|
||||
tmp + 0 * out_width, out_width, out_height, 0, 1,
|
||||
work + 0 * work_size) ||
|
||||
!WebPRescalerInit(p->scaler_u, uv_in_width, uv_in_height,
|
||||
tmp + 1 * out_width, out_width, out_height, 0, 1,
|
||||
work + 1 * work_size) ||
|
||||
!WebPRescalerInit(p->scaler_v, uv_in_width, uv_in_height,
|
||||
tmp + 2 * out_width, out_width, out_height, 0, 1,
|
||||
work + 2 * work_size)) {
|
||||
return 0;
|
||||
}
|
||||
p->emit = EmitRescaledRGB;
|
||||
WebPInitYUV444Converters();
|
||||
|
||||
if (has_alpha) {
|
||||
WebPRescalerInit(p->scaler_a, io->mb_w, io->mb_h,
|
||||
tmp + 3 * out_width, out_width, out_height, 0, 1,
|
||||
work + 3 * work_size);
|
||||
if (!WebPRescalerInit(p->scaler_a, io->mb_w, io->mb_h,
|
||||
tmp + 3 * out_width, out_width, out_height, 0, 1,
|
||||
work + 3 * work_size)) {
|
||||
return 0;
|
||||
}
|
||||
p->emit_alpha = EmitRescaledAlphaRGB;
|
||||
if (p->output->colorspace == MODE_RGBA_4444 ||
|
||||
p->output->colorspace == MODE_rgbA_4444) {
|
||||
|
||||
Vendored
+2
-1
@@ -12,10 +12,11 @@
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/dsp/cpu.h"
|
||||
#include "src/utils/bit_reader_inl_utils.h"
|
||||
|
||||
#if !defined(USE_GENERIC_TREE)
|
||||
#if !defined(__arm__) && !defined(_M_ARM) && !defined(__aarch64__)
|
||||
#if !defined(__arm__) && !defined(_M_ARM) && !WEBP_AARCH64
|
||||
// using a table is ~1-2% slower on ARM. Prefer the coded-tree approach then.
|
||||
#define USE_GENERIC_TREE 1 // ALTERNATE_CODE
|
||||
#else
|
||||
|
||||
Vendored
+4
-2
@@ -335,7 +335,7 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
|
||||
io->scaled_width = io->width;
|
||||
io->scaled_height = io->height;
|
||||
|
||||
io->mb_w = io->width; // sanity check
|
||||
io->mb_w = io->width; // for soundness
|
||||
io->mb_h = io->height; // ditto
|
||||
|
||||
VP8ResetProba(&dec->proba_);
|
||||
@@ -403,7 +403,7 @@ static const uint8_t kZigzag[16] = {
|
||||
0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
|
||||
};
|
||||
|
||||
// See section 13-2: http://tools.ietf.org/html/rfc6386#section-13.2
|
||||
// See section 13-2: https://datatracker.ietf.org/doc/html/rfc6386#section-13.2
|
||||
static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) {
|
||||
int v;
|
||||
if (!VP8GetBit(br, p[3], "coeffs")) {
|
||||
@@ -494,6 +494,8 @@ static int GetCoeffsAlt(VP8BitReader* const br,
|
||||
return 16;
|
||||
}
|
||||
|
||||
extern VP8CPUInfo VP8GetCPUInfo;
|
||||
|
||||
WEBP_DSP_INIT_FUNC(InitGetCoeffs) {
|
||||
if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) {
|
||||
GetCoeffs = GetCoeffsAlt;
|
||||
|
||||
Vendored
+2
-2
@@ -31,8 +31,8 @@ extern "C" {
|
||||
|
||||
// version numbers
|
||||
#define DEC_MAJ_VERSION 1
|
||||
#define DEC_MIN_VERSION 2
|
||||
#define DEC_REV_VERSION 0
|
||||
#define DEC_MIN_VERSION 3
|
||||
#define DEC_REV_VERSION 1
|
||||
|
||||
// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
|
||||
// Constraints are: We need to store one 16x16 block of luma samples (y),
|
||||
|
||||
Vendored
+142
-102
@@ -12,6 +12,7 @@
|
||||
// Authors: Vikas Arora (vikaas.arora@gmail.com)
|
||||
// Jyrki Alakuijala (jyrki@google.com)
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "src/dec/alphai_dec.h"
|
||||
@@ -84,7 +85,7 @@ static const uint8_t kCodeToPlane[CODE_TO_PLANE_CODES] = {
|
||||
// to 256 (green component values) + 24 (length prefix values)
|
||||
// + color_cache_size (between 0 and 2048).
|
||||
// All values computed for 8-bit first level lookup with Mark Adler's tool:
|
||||
// http://www.hdfgroup.org/ftp/lib-external/zlib/zlib-1.2.5/examples/enough.c
|
||||
// https://github.com/madler/zlib/blob/v1.2.5/examples/enough.c
|
||||
#define FIXED_TABLE_SIZE (630 * 3 + 410)
|
||||
static const uint16_t kTableSize[12] = {
|
||||
FIXED_TABLE_SIZE + 654,
|
||||
@@ -101,6 +102,14 @@ static const uint16_t kTableSize[12] = {
|
||||
FIXED_TABLE_SIZE + 2704
|
||||
};
|
||||
|
||||
static int VP8LSetError(VP8LDecoder* const dec, VP8StatusCode error) {
|
||||
// The oldest error reported takes precedence over the new one.
|
||||
if (dec->status_ == VP8_STATUS_OK || dec->status_ == VP8_STATUS_SUSPENDED) {
|
||||
dec->status_ = error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int DecodeImageStream(int xsize, int ysize,
|
||||
int is_level0,
|
||||
VP8LDecoder* const dec,
|
||||
@@ -178,7 +187,7 @@ static WEBP_INLINE int PlaneCodeToDistance(int xsize, int plane_code) {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Decodes the next Huffman code from bit-stream.
|
||||
// FillBitWindow(br) needs to be called at minimum every second call
|
||||
// VP8LFillBitWindow(br) needs to be called at minimum every second call
|
||||
// to ReadSymbol, in order to pre-fetch enough bits.
|
||||
static WEBP_INLINE int ReadSymbol(const HuffmanCode* table,
|
||||
VP8LBitReader* const br) {
|
||||
@@ -253,11 +262,11 @@ static int ReadHuffmanCodeLengths(
|
||||
int symbol;
|
||||
int max_symbol;
|
||||
int prev_code_len = DEFAULT_CODE_LENGTH;
|
||||
HuffmanCode table[1 << LENGTHS_TABLE_BITS];
|
||||
HuffmanTables tables;
|
||||
|
||||
if (!VP8LBuildHuffmanTable(table, LENGTHS_TABLE_BITS,
|
||||
code_length_code_lengths,
|
||||
NUM_CODE_LENGTH_CODES)) {
|
||||
if (!VP8LHuffmanTablesAllocate(1 << LENGTHS_TABLE_BITS, &tables) ||
|
||||
!VP8LBuildHuffmanTable(&tables, LENGTHS_TABLE_BITS,
|
||||
code_length_code_lengths, NUM_CODE_LENGTH_CODES)) {
|
||||
goto End;
|
||||
}
|
||||
|
||||
@@ -277,7 +286,7 @@ static int ReadHuffmanCodeLengths(
|
||||
int code_len;
|
||||
if (max_symbol-- == 0) break;
|
||||
VP8LFillBitWindow(br);
|
||||
p = &table[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
|
||||
p = &tables.curr_segment->start[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
|
||||
VP8LSetBitPos(br, br->bit_pos_ + p->bits);
|
||||
code_len = p->value;
|
||||
if (code_len < kCodeLengthLiterals) {
|
||||
@@ -300,14 +309,16 @@ static int ReadHuffmanCodeLengths(
|
||||
ok = 1;
|
||||
|
||||
End:
|
||||
if (!ok) dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
|
||||
VP8LHuffmanTablesDeallocate(&tables);
|
||||
if (!ok) return VP8LSetError(dec, VP8_STATUS_BITSTREAM_ERROR);
|
||||
return ok;
|
||||
}
|
||||
|
||||
// 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman
|
||||
// tree.
|
||||
static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
|
||||
int* const code_lengths, HuffmanCode* const table) {
|
||||
int* const code_lengths,
|
||||
HuffmanTables* const table) {
|
||||
int ok = 0;
|
||||
int size = 0;
|
||||
VP8LBitReader* const br = &dec->br_;
|
||||
@@ -321,7 +332,7 @@ static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
|
||||
// The first code is either 1 bit or 8 bit code.
|
||||
int symbol = VP8LReadBits(br, (first_symbol_len_code == 0) ? 1 : 8);
|
||||
code_lengths[symbol] = 1;
|
||||
// The second code (if present), is always 8 bit long.
|
||||
// The second code (if present), is always 8 bits long.
|
||||
if (num_symbols == 2) {
|
||||
symbol = VP8LReadBits(br, 8);
|
||||
code_lengths[symbol] = 1;
|
||||
@@ -331,10 +342,7 @@ static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
|
||||
int i;
|
||||
int code_length_code_lengths[NUM_CODE_LENGTH_CODES] = { 0 };
|
||||
const int num_codes = VP8LReadBits(br, 4) + 4;
|
||||
if (num_codes > NUM_CODE_LENGTH_CODES) {
|
||||
dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
|
||||
return 0;
|
||||
}
|
||||
assert(num_codes <= NUM_CODE_LENGTH_CODES);
|
||||
|
||||
for (i = 0; i < num_codes; ++i) {
|
||||
code_length_code_lengths[kCodeLengthCodeOrder[i]] = VP8LReadBits(br, 3);
|
||||
@@ -349,36 +357,35 @@ static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
|
||||
code_lengths, alphabet_size);
|
||||
}
|
||||
if (!ok || size == 0) {
|
||||
dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
|
||||
return 0;
|
||||
return VP8LSetError(dec, VP8_STATUS_BITSTREAM_ERROR);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
||||
int color_cache_bits, int allow_recursion) {
|
||||
int i, j;
|
||||
int i;
|
||||
VP8LBitReader* const br = &dec->br_;
|
||||
VP8LMetadata* const hdr = &dec->hdr_;
|
||||
uint32_t* huffman_image = NULL;
|
||||
HTreeGroup* htree_groups = NULL;
|
||||
HuffmanCode* huffman_tables = NULL;
|
||||
HuffmanCode* huffman_table = NULL;
|
||||
HuffmanTables* huffman_tables = &hdr->huffman_tables_;
|
||||
int num_htree_groups = 1;
|
||||
int num_htree_groups_max = 1;
|
||||
int max_alphabet_size = 0;
|
||||
int* code_lengths = NULL;
|
||||
const int table_size = kTableSize[color_cache_bits];
|
||||
int* mapping = NULL;
|
||||
int ok = 0;
|
||||
|
||||
// Check the table has been 0 initialized (through InitMetadata).
|
||||
assert(huffman_tables->root.start == NULL);
|
||||
assert(huffman_tables->curr_segment == NULL);
|
||||
|
||||
if (allow_recursion && VP8LReadBits(br, 1)) {
|
||||
// use meta Huffman codes.
|
||||
const int huffman_precision = VP8LReadBits(br, 3) + 2;
|
||||
const int huffman_xsize = VP8LSubSampleSize(xsize, huffman_precision);
|
||||
const int huffman_ysize = VP8LSubSampleSize(ysize, huffman_precision);
|
||||
const int huffman_pixs = huffman_xsize * huffman_ysize;
|
||||
if (!DecodeImageStream(huffman_xsize, huffman_ysize, 0, dec,
|
||||
if (!DecodeImageStream(huffman_xsize, huffman_ysize, /*is_level0=*/0, dec,
|
||||
&huffman_image)) {
|
||||
goto Error;
|
||||
}
|
||||
@@ -402,7 +409,7 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
||||
// values [0, num_htree_groups)
|
||||
mapping = (int*)WebPSafeMalloc(num_htree_groups_max, sizeof(*mapping));
|
||||
if (mapping == NULL) {
|
||||
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
||||
VP8LSetError(dec, VP8_STATUS_OUT_OF_MEMORY);
|
||||
goto Error;
|
||||
}
|
||||
// -1 means a value is unmapped, and therefore unused in the Huffman
|
||||
@@ -421,29 +428,55 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
||||
|
||||
if (br->eos_) goto Error;
|
||||
|
||||
// Find maximum alphabet size for the htree group.
|
||||
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
|
||||
int alphabet_size = kAlphabetSize[j];
|
||||
if (j == 0 && color_cache_bits > 0) {
|
||||
alphabet_size += 1 << color_cache_bits;
|
||||
}
|
||||
if (max_alphabet_size < alphabet_size) {
|
||||
max_alphabet_size = alphabet_size;
|
||||
}
|
||||
if (!ReadHuffmanCodesHelper(color_cache_bits, num_htree_groups,
|
||||
num_htree_groups_max, mapping, dec,
|
||||
huffman_tables, &htree_groups)) {
|
||||
goto Error;
|
||||
}
|
||||
ok = 1;
|
||||
|
||||
code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
|
||||
sizeof(*code_lengths));
|
||||
huffman_tables = (HuffmanCode*)WebPSafeMalloc(num_htree_groups * table_size,
|
||||
sizeof(*huffman_tables));
|
||||
htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
|
||||
// All OK. Finalize pointers.
|
||||
hdr->huffman_image_ = huffman_image;
|
||||
hdr->num_htree_groups_ = num_htree_groups;
|
||||
hdr->htree_groups_ = htree_groups;
|
||||
|
||||
if (htree_groups == NULL || code_lengths == NULL || huffman_tables == NULL) {
|
||||
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
||||
Error:
|
||||
WebPSafeFree(mapping);
|
||||
if (!ok) {
|
||||
WebPSafeFree(huffman_image);
|
||||
VP8LHuffmanTablesDeallocate(huffman_tables);
|
||||
VP8LHtreeGroupsFree(htree_groups);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
int ReadHuffmanCodesHelper(int color_cache_bits, int num_htree_groups,
|
||||
int num_htree_groups_max, const int* const mapping,
|
||||
VP8LDecoder* const dec,
|
||||
HuffmanTables* const huffman_tables,
|
||||
HTreeGroup** const htree_groups) {
|
||||
int i, j, ok = 0;
|
||||
const int max_alphabet_size =
|
||||
kAlphabetSize[0] + ((color_cache_bits > 0) ? 1 << color_cache_bits : 0);
|
||||
const int table_size = kTableSize[color_cache_bits];
|
||||
int* code_lengths = NULL;
|
||||
|
||||
if ((mapping == NULL && num_htree_groups != num_htree_groups_max) ||
|
||||
num_htree_groups > num_htree_groups_max) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
code_lengths =
|
||||
(int*)WebPSafeCalloc((uint64_t)max_alphabet_size, sizeof(*code_lengths));
|
||||
*htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
|
||||
|
||||
if (*htree_groups == NULL || code_lengths == NULL ||
|
||||
!VP8LHuffmanTablesAllocate(num_htree_groups * table_size,
|
||||
huffman_tables)) {
|
||||
VP8LSetError(dec, VP8_STATUS_OUT_OF_MEMORY);
|
||||
goto Error;
|
||||
}
|
||||
|
||||
huffman_table = huffman_tables;
|
||||
for (i = 0; i < num_htree_groups_max; ++i) {
|
||||
// If the index "i" is unused in the Huffman image, just make sure the
|
||||
// coefficients are valid but do not store them.
|
||||
@@ -460,7 +493,7 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
||||
}
|
||||
} else {
|
||||
HTreeGroup* const htree_group =
|
||||
&htree_groups[(mapping == NULL) ? i : mapping[i]];
|
||||
&(*htree_groups)[(mapping == NULL) ? i : mapping[i]];
|
||||
HuffmanCode** const htrees = htree_group->htrees;
|
||||
int size;
|
||||
int total_size = 0;
|
||||
@@ -468,19 +501,20 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
||||
int max_bits = 0;
|
||||
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
|
||||
int alphabet_size = kAlphabetSize[j];
|
||||
htrees[j] = huffman_table;
|
||||
if (j == 0 && color_cache_bits > 0) {
|
||||
alphabet_size += (1 << color_cache_bits);
|
||||
}
|
||||
size = ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_table);
|
||||
size =
|
||||
ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_tables);
|
||||
htrees[j] = huffman_tables->curr_segment->curr_table;
|
||||
if (size == 0) {
|
||||
goto Error;
|
||||
}
|
||||
if (is_trivial_literal && kLiteralMap[j] == 1) {
|
||||
is_trivial_literal = (huffman_table->bits == 0);
|
||||
is_trivial_literal = (htrees[j]->bits == 0);
|
||||
}
|
||||
total_size += huffman_table->bits;
|
||||
huffman_table += size;
|
||||
total_size += htrees[j]->bits;
|
||||
huffman_tables->curr_segment->curr_table += size;
|
||||
if (j <= ALPHA) {
|
||||
int local_max_bits = code_lengths[0];
|
||||
int k;
|
||||
@@ -511,19 +545,12 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
||||
}
|
||||
ok = 1;
|
||||
|
||||
// All OK. Finalize pointers.
|
||||
hdr->huffman_image_ = huffman_image;
|
||||
hdr->num_htree_groups_ = num_htree_groups;
|
||||
hdr->htree_groups_ = htree_groups;
|
||||
hdr->huffman_tables_ = huffman_tables;
|
||||
|
||||
Error:
|
||||
WebPSafeFree(code_lengths);
|
||||
WebPSafeFree(mapping);
|
||||
if (!ok) {
|
||||
WebPSafeFree(huffman_image);
|
||||
WebPSafeFree(huffman_tables);
|
||||
VP8LHtreeGroupsFree(htree_groups);
|
||||
VP8LHuffmanTablesDeallocate(huffman_tables);
|
||||
VP8LHtreeGroupsFree(*htree_groups);
|
||||
*htree_groups = NULL;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
@@ -547,8 +574,7 @@ static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) {
|
||||
scaled_data_size * sizeof(*scaled_data);
|
||||
uint8_t* memory = (uint8_t*)WebPSafeMalloc(memory_size, sizeof(*memory));
|
||||
if (memory == NULL) {
|
||||
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
||||
return 0;
|
||||
return VP8LSetError(dec, VP8_STATUS_OUT_OF_MEMORY);
|
||||
}
|
||||
assert(dec->rescaler_memory == NULL);
|
||||
dec->rescaler_memory = memory;
|
||||
@@ -559,8 +585,11 @@ static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) {
|
||||
memory += work_size * sizeof(*work);
|
||||
scaled_data = (uint32_t*)memory;
|
||||
|
||||
WebPRescalerInit(dec->rescaler, in_width, in_height, (uint8_t*)scaled_data,
|
||||
out_width, out_height, 0, num_channels, work);
|
||||
if (!WebPRescalerInit(dec->rescaler, in_width, in_height,
|
||||
(uint8_t*)scaled_data, out_width, out_height,
|
||||
0, num_channels, work)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif // WEBP_REDUCE_SIZE
|
||||
@@ -574,13 +603,14 @@ static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) {
|
||||
static int Export(WebPRescaler* const rescaler, WEBP_CSP_MODE colorspace,
|
||||
int rgba_stride, uint8_t* const rgba) {
|
||||
uint32_t* const src = (uint32_t*)rescaler->dst;
|
||||
uint8_t* dst = rgba;
|
||||
const int dst_width = rescaler->dst_width;
|
||||
int num_lines_out = 0;
|
||||
while (WebPRescalerHasPendingOutput(rescaler)) {
|
||||
uint8_t* const dst = rgba + num_lines_out * rgba_stride;
|
||||
WebPRescalerExportRow(rescaler);
|
||||
WebPMultARGBRow(src, dst_width, 1);
|
||||
VP8LConvertFromBGRA(src, dst_width, colorspace, dst);
|
||||
dst += rgba_stride;
|
||||
++num_lines_out;
|
||||
}
|
||||
return num_lines_out;
|
||||
@@ -594,8 +624,8 @@ static int EmitRescaledRowsRGBA(const VP8LDecoder* const dec,
|
||||
int num_lines_in = 0;
|
||||
int num_lines_out = 0;
|
||||
while (num_lines_in < mb_h) {
|
||||
uint8_t* const row_in = in + num_lines_in * in_stride;
|
||||
uint8_t* const row_out = out + num_lines_out * out_stride;
|
||||
uint8_t* const row_in = in + (uint64_t)num_lines_in * in_stride;
|
||||
uint8_t* const row_out = out + (uint64_t)num_lines_out * out_stride;
|
||||
const int lines_left = mb_h - num_lines_in;
|
||||
const int needed_lines = WebPRescaleNeededLines(dec->rescaler, lines_left);
|
||||
int lines_imported;
|
||||
@@ -796,7 +826,8 @@ static void ProcessRows(VP8LDecoder* const dec, int row) {
|
||||
const WebPDecBuffer* const output = dec->output_;
|
||||
if (WebPIsRGBMode(output->colorspace)) { // convert to RGBA
|
||||
const WebPRGBABuffer* const buf = &output->u.RGBA;
|
||||
uint8_t* const rgba = buf->rgba + dec->last_out_row_ * buf->stride;
|
||||
uint8_t* const rgba =
|
||||
buf->rgba + (int64_t)dec->last_out_row_ * buf->stride;
|
||||
const int num_rows_out =
|
||||
#if !defined(WEBP_REDUCE_SIZE)
|
||||
io->use_scaling ?
|
||||
@@ -1077,12 +1108,10 @@ static int DecodeAlphaData(VP8LDecoder* const dec, uint8_t* const data,
|
||||
End:
|
||||
br->eos_ = VP8LIsEndOfStream(br);
|
||||
if (!ok || (br->eos_ && pos < end)) {
|
||||
ok = 0;
|
||||
dec->status_ = br->eos_ ? VP8_STATUS_SUSPENDED
|
||||
: VP8_STATUS_BITSTREAM_ERROR;
|
||||
} else {
|
||||
dec->last_pixel_ = pos;
|
||||
return VP8LSetError(
|
||||
dec, br->eos_ ? VP8_STATUS_SUSPENDED : VP8_STATUS_BITSTREAM_ERROR);
|
||||
}
|
||||
dec->last_pixel_ = pos;
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -1232,9 +1261,20 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
|
||||
}
|
||||
|
||||
br->eos_ = VP8LIsEndOfStream(br);
|
||||
if (dec->incremental_ && br->eos_ && src < src_end) {
|
||||
// In incremental decoding:
|
||||
// br->eos_ && src < src_last: if 'br' reached the end of the buffer and
|
||||
// 'src_last' has not been reached yet, there is not enough data. 'dec' has to
|
||||
// be reset until there is more data.
|
||||
// !br->eos_ && src < src_last: this cannot happen as either the buffer is
|
||||
// fully read, either enough has been read to reach 'src_last'.
|
||||
// src >= src_last: 'src_last' is reached, all is fine. 'src' can actually go
|
||||
// beyond 'src_last' in case the image is cropped and an LZ77 goes further.
|
||||
// The buffer might have been enough or there is some left. 'br->eos_' does
|
||||
// not matter.
|
||||
assert(!dec->incremental_ || (br->eos_ && src < src_last) || src >= src_last);
|
||||
if (dec->incremental_ && br->eos_ && src < src_last) {
|
||||
RestoreState(dec);
|
||||
} else if (!br->eos_) {
|
||||
} else if ((dec->incremental_ && src >= src_last) || !br->eos_) {
|
||||
// Process the remaining rows corresponding to last row-block.
|
||||
if (process_func != NULL) {
|
||||
process_func(dec, row > last_row ? last_row : row);
|
||||
@@ -1249,8 +1289,7 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
|
||||
return 1;
|
||||
|
||||
Error:
|
||||
dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
|
||||
return 0;
|
||||
return VP8LSetError(dec, VP8_STATUS_BITSTREAM_ERROR);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -1276,7 +1315,7 @@ static int ExpandColorMap(int num_colors, VP8LTransform* const transform) {
|
||||
uint8_t* const new_data = (uint8_t*)new_color_map;
|
||||
new_color_map[0] = transform->data_[0];
|
||||
for (i = 4; i < 4 * num_colors; ++i) {
|
||||
// Equivalent to AddPixelEq(), on a byte-basis.
|
||||
// Equivalent to VP8LAddPixels(), on a byte-basis.
|
||||
new_data[i] = (data[i] + new_data[i - 4]) & 0xff;
|
||||
}
|
||||
for (; i < 4 * final_num_colors; ++i) {
|
||||
@@ -1317,7 +1356,7 @@ static int ReadTransform(int* const xsize, int const* ysize,
|
||||
transform->bits_),
|
||||
VP8LSubSampleSize(transform->ysize_,
|
||||
transform->bits_),
|
||||
0, dec, &transform->data_);
|
||||
/*is_level0=*/0, dec, &transform->data_);
|
||||
break;
|
||||
case COLOR_INDEXING_TRANSFORM: {
|
||||
const int num_colors = VP8LReadBits(br, 8) + 1;
|
||||
@@ -1327,11 +1366,14 @@ static int ReadTransform(int* const xsize, int const* ysize,
|
||||
: 3;
|
||||
*xsize = VP8LSubSampleSize(transform->xsize_, bits);
|
||||
transform->bits_ = bits;
|
||||
ok = DecodeImageStream(num_colors, 1, 0, dec, &transform->data_);
|
||||
ok = ok && ExpandColorMap(num_colors, transform);
|
||||
ok = DecodeImageStream(num_colors, /*ysize=*/1, /*is_level0=*/0, dec,
|
||||
&transform->data_);
|
||||
if (ok && !ExpandColorMap(num_colors, transform)) {
|
||||
return VP8LSetError(dec, VP8_STATUS_OUT_OF_MEMORY);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SUBTRACT_GREEN:
|
||||
case SUBTRACT_GREEN_TRANSFORM:
|
||||
break;
|
||||
default:
|
||||
assert(0); // can't happen
|
||||
@@ -1353,7 +1395,7 @@ static void ClearMetadata(VP8LMetadata* const hdr) {
|
||||
assert(hdr != NULL);
|
||||
|
||||
WebPSafeFree(hdr->huffman_image_);
|
||||
WebPSafeFree(hdr->huffman_tables_);
|
||||
VP8LHuffmanTablesDeallocate(&hdr->huffman_tables_);
|
||||
VP8LHtreeGroupsFree(hdr->htree_groups_);
|
||||
VP8LColorCacheClear(&hdr->color_cache_);
|
||||
VP8LColorCacheClear(&hdr->saved_color_cache_);
|
||||
@@ -1434,7 +1476,7 @@ static int DecodeImageStream(int xsize, int ysize,
|
||||
color_cache_bits = VP8LReadBits(br, 4);
|
||||
ok = (color_cache_bits >= 1 && color_cache_bits <= MAX_CACHE_BITS);
|
||||
if (!ok) {
|
||||
dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
|
||||
VP8LSetError(dec, VP8_STATUS_BITSTREAM_ERROR);
|
||||
goto End;
|
||||
}
|
||||
}
|
||||
@@ -1443,7 +1485,7 @@ static int DecodeImageStream(int xsize, int ysize,
|
||||
ok = ok && ReadHuffmanCodes(dec, transform_xsize, transform_ysize,
|
||||
color_cache_bits, is_level0);
|
||||
if (!ok) {
|
||||
dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
|
||||
VP8LSetError(dec, VP8_STATUS_BITSTREAM_ERROR);
|
||||
goto End;
|
||||
}
|
||||
|
||||
@@ -1451,8 +1493,7 @@ static int DecodeImageStream(int xsize, int ysize,
|
||||
if (color_cache_bits > 0) {
|
||||
hdr->color_cache_size_ = 1 << color_cache_bits;
|
||||
if (!VP8LColorCacheInit(&hdr->color_cache_, color_cache_bits)) {
|
||||
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
||||
ok = 0;
|
||||
ok = VP8LSetError(dec, VP8_STATUS_OUT_OF_MEMORY);
|
||||
goto End;
|
||||
}
|
||||
} else {
|
||||
@@ -1469,8 +1510,7 @@ static int DecodeImageStream(int xsize, int ysize,
|
||||
const uint64_t total_size = (uint64_t)transform_xsize * transform_ysize;
|
||||
data = (uint32_t*)WebPSafeMalloc(total_size, sizeof(*data));
|
||||
if (data == NULL) {
|
||||
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
||||
ok = 0;
|
||||
ok = VP8LSetError(dec, VP8_STATUS_OUT_OF_MEMORY);
|
||||
goto End;
|
||||
}
|
||||
}
|
||||
@@ -1514,9 +1554,8 @@ static int AllocateInternalBuffers32b(VP8LDecoder* const dec, int final_width) {
|
||||
assert(dec->width_ <= final_width);
|
||||
dec->pixels_ = (uint32_t*)WebPSafeMalloc(total_num_pixels, sizeof(uint32_t));
|
||||
if (dec->pixels_ == NULL) {
|
||||
dec->argb_cache_ = NULL; // for sanity check
|
||||
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
||||
return 0;
|
||||
dec->argb_cache_ = NULL; // for soundness
|
||||
return VP8LSetError(dec, VP8_STATUS_OUT_OF_MEMORY);
|
||||
}
|
||||
dec->argb_cache_ = dec->pixels_ + num_pixels + cache_top_pixels;
|
||||
return 1;
|
||||
@@ -1524,11 +1563,10 @@ static int AllocateInternalBuffers32b(VP8LDecoder* const dec, int final_width) {
|
||||
|
||||
static int AllocateInternalBuffers8b(VP8LDecoder* const dec) {
|
||||
const uint64_t total_num_pixels = (uint64_t)dec->width_ * dec->height_;
|
||||
dec->argb_cache_ = NULL; // for sanity check
|
||||
dec->argb_cache_ = NULL; // for soundness
|
||||
dec->pixels_ = (uint32_t*)WebPSafeMalloc(total_num_pixels, sizeof(uint8_t));
|
||||
if (dec->pixels_ == NULL) {
|
||||
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
||||
return 0;
|
||||
return VP8LSetError(dec, VP8_STATUS_OUT_OF_MEMORY);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -1583,7 +1621,8 @@ int VP8LDecodeAlphaHeader(ALPHDecoder* const alph_dec,
|
||||
dec->status_ = VP8_STATUS_OK;
|
||||
VP8LInitBitReader(&dec->br_, data, data_size);
|
||||
|
||||
if (!DecodeImageStream(alph_dec->width_, alph_dec->height_, 1, dec, NULL)) {
|
||||
if (!DecodeImageStream(alph_dec->width_, alph_dec->height_, /*is_level0=*/1,
|
||||
dec, /*decoded_data=*/NULL)) {
|
||||
goto Err;
|
||||
}
|
||||
|
||||
@@ -1638,22 +1677,24 @@ int VP8LDecodeHeader(VP8LDecoder* const dec, VP8Io* const io) {
|
||||
|
||||
if (dec == NULL) return 0;
|
||||
if (io == NULL) {
|
||||
dec->status_ = VP8_STATUS_INVALID_PARAM;
|
||||
return 0;
|
||||
return VP8LSetError(dec, VP8_STATUS_INVALID_PARAM);
|
||||
}
|
||||
|
||||
dec->io_ = io;
|
||||
dec->status_ = VP8_STATUS_OK;
|
||||
VP8LInitBitReader(&dec->br_, io->data, io->data_size);
|
||||
if (!ReadImageInfo(&dec->br_, &width, &height, &has_alpha)) {
|
||||
dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
|
||||
VP8LSetError(dec, VP8_STATUS_BITSTREAM_ERROR);
|
||||
goto Error;
|
||||
}
|
||||
dec->state_ = READ_DIM;
|
||||
io->width = width;
|
||||
io->height = height;
|
||||
|
||||
if (!DecodeImageStream(width, height, 1, dec, NULL)) goto Error;
|
||||
if (!DecodeImageStream(width, height, /*is_level0=*/1, dec,
|
||||
/*decoded_data=*/NULL)) {
|
||||
goto Error;
|
||||
}
|
||||
return 1;
|
||||
|
||||
Error:
|
||||
@@ -1666,10 +1707,9 @@ int VP8LDecodeImage(VP8LDecoder* const dec) {
|
||||
VP8Io* io = NULL;
|
||||
WebPDecParams* params = NULL;
|
||||
|
||||
// Sanity checks.
|
||||
if (dec == NULL) return 0;
|
||||
|
||||
assert(dec->hdr_.huffman_tables_ != NULL);
|
||||
assert(dec->hdr_.huffman_tables_.root.start != NULL);
|
||||
assert(dec->hdr_.htree_groups_ != NULL);
|
||||
assert(dec->hdr_.num_htree_groups_ > 0);
|
||||
|
||||
@@ -1684,7 +1724,7 @@ int VP8LDecodeImage(VP8LDecoder* const dec) {
|
||||
assert(dec->output_ != NULL);
|
||||
|
||||
if (!WebPIoInitFromOptions(params->options, io, MODE_BGRA)) {
|
||||
dec->status_ = VP8_STATUS_INVALID_PARAM;
|
||||
VP8LSetError(dec, VP8_STATUS_INVALID_PARAM);
|
||||
goto Err;
|
||||
}
|
||||
|
||||
@@ -1694,7 +1734,7 @@ int VP8LDecodeImage(VP8LDecoder* const dec) {
|
||||
if (io->use_scaling && !AllocateAndInitRescaler(dec, io)) goto Err;
|
||||
#else
|
||||
if (io->use_scaling) {
|
||||
dec->status_ = VP8_STATUS_INVALID_PARAM;
|
||||
VP8LSetError(dec, VP8_STATUS_INVALID_PARAM);
|
||||
goto Err;
|
||||
}
|
||||
#endif
|
||||
@@ -1712,7 +1752,7 @@ int VP8LDecodeImage(VP8LDecoder* const dec) {
|
||||
dec->hdr_.saved_color_cache_.colors_ == NULL) {
|
||||
if (!VP8LColorCacheInit(&dec->hdr_.saved_color_cache_,
|
||||
dec->hdr_.color_cache_.hash_bits_)) {
|
||||
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
||||
VP8LSetError(dec, VP8_STATUS_OUT_OF_MEMORY);
|
||||
goto Err;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+14
-1
@@ -51,7 +51,7 @@ typedef struct {
|
||||
uint32_t* huffman_image_;
|
||||
int num_htree_groups_;
|
||||
HTreeGroup* htree_groups_;
|
||||
HuffmanCode* huffman_tables_;
|
||||
HuffmanTables huffman_tables_;
|
||||
} VP8LMetadata;
|
||||
|
||||
typedef struct VP8LDecoder VP8LDecoder;
|
||||
@@ -126,6 +126,19 @@ void VP8LClear(VP8LDecoder* const dec);
|
||||
// Clears and deallocate a lossless decoder instance.
|
||||
void VP8LDelete(VP8LDecoder* const dec);
|
||||
|
||||
// Helper function for reading the different Huffman codes and storing them in
|
||||
// 'huffman_tables' and 'htree_groups'.
|
||||
// If mapping is NULL 'num_htree_groups_max' must equal 'num_htree_groups'.
|
||||
// If it is not NULL, it maps 'num_htree_groups_max' indices to the
|
||||
// 'num_htree_groups' groups. If 'num_htree_groups_max' > 'num_htree_groups',
|
||||
// some of those indices map to -1. This is used for non-balanced codes to
|
||||
// limit memory usage.
|
||||
int ReadHuffmanCodesHelper(int color_cache_bits, int num_htree_groups,
|
||||
int num_htree_groups_max, const int* const mapping,
|
||||
VP8LDecoder* const dec,
|
||||
HuffmanTables* const huffman_tables,
|
||||
HTreeGroup** const htree_groups);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
Vendored
+32
-18
@@ -179,7 +179,7 @@ static VP8StatusCode ParseOptionalChunks(const uint8_t** const data,
|
||||
return VP8_STATUS_BITSTREAM_ERROR; // Not a valid chunk size.
|
||||
}
|
||||
// For odd-sized chunk-payload, there's one byte padding at the end.
|
||||
disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1;
|
||||
disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1u;
|
||||
total_size += disk_chunk_size;
|
||||
|
||||
// Check that total bytes skipped so far does not exceed riff_size.
|
||||
@@ -658,19 +658,26 @@ uint8_t* WebPDecodeBGRA(const uint8_t* data, size_t data_size,
|
||||
uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size,
|
||||
int* width, int* height, uint8_t** u, uint8_t** v,
|
||||
int* stride, int* uv_stride) {
|
||||
WebPDecBuffer output; // only to preserve the side-infos
|
||||
uint8_t* const out = Decode(MODE_YUV, data, data_size,
|
||||
width, height, &output);
|
||||
|
||||
if (out != NULL) {
|
||||
const WebPYUVABuffer* const buf = &output.u.YUVA;
|
||||
*u = buf->u;
|
||||
*v = buf->v;
|
||||
*stride = buf->y_stride;
|
||||
*uv_stride = buf->u_stride;
|
||||
assert(buf->u_stride == buf->v_stride);
|
||||
// data, width and height are checked by Decode().
|
||||
if (u == NULL || v == NULL || stride == NULL || uv_stride == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
{
|
||||
WebPDecBuffer output; // only to preserve the side-infos
|
||||
uint8_t* const out = Decode(MODE_YUV, data, data_size,
|
||||
width, height, &output);
|
||||
|
||||
if (out != NULL) {
|
||||
const WebPYUVABuffer* const buf = &output.u.YUVA;
|
||||
*u = buf->u;
|
||||
*v = buf->v;
|
||||
*stride = buf->y_stride;
|
||||
*uv_stride = buf->u_stride;
|
||||
assert(buf->u_stride == buf->v_stride);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static void DefaultFeatures(WebPBitstreamFeatures* const features) {
|
||||
@@ -785,6 +792,13 @@ VP8StatusCode WebPDecode(const uint8_t* data, size_t data_size,
|
||||
//------------------------------------------------------------------------------
|
||||
// Cropping and rescaling.
|
||||
|
||||
int WebPCheckCropDimensions(int image_width, int image_height,
|
||||
int x, int y, int w, int h) {
|
||||
return !(x < 0 || y < 0 || w <= 0 || h <= 0 ||
|
||||
x >= image_width || w > image_width || w > image_width - x ||
|
||||
y >= image_height || h > image_height || h > image_height - y);
|
||||
}
|
||||
|
||||
int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
|
||||
VP8Io* const io, WEBP_CSP_MODE src_colorspace) {
|
||||
const int W = io->width;
|
||||
@@ -792,7 +806,7 @@ int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
|
||||
int x = 0, y = 0, w = W, h = H;
|
||||
|
||||
// Cropping
|
||||
io->use_cropping = (options != NULL) && (options->use_cropping > 0);
|
||||
io->use_cropping = (options != NULL) && options->use_cropping;
|
||||
if (io->use_cropping) {
|
||||
w = options->crop_width;
|
||||
h = options->crop_height;
|
||||
@@ -802,7 +816,7 @@ int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
|
||||
x &= ~1;
|
||||
y &= ~1;
|
||||
}
|
||||
if (x < 0 || y < 0 || w <= 0 || h <= 0 || x + w > W || y + h > H) {
|
||||
if (!WebPCheckCropDimensions(W, H, x, y, w, h)) {
|
||||
return 0; // out of frame boundary error
|
||||
}
|
||||
}
|
||||
@@ -814,7 +828,7 @@ int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
|
||||
io->mb_h = h;
|
||||
|
||||
// Scaling
|
||||
io->use_scaling = (options != NULL) && (options->use_scaling > 0);
|
||||
io->use_scaling = (options != NULL) && options->use_scaling;
|
||||
if (io->use_scaling) {
|
||||
int scaled_width = options->scaled_width;
|
||||
int scaled_height = options->scaled_height;
|
||||
@@ -835,8 +849,8 @@ int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
|
||||
|
||||
if (io->use_scaling) {
|
||||
// disable filter (only for large downscaling ratio).
|
||||
io->bypass_filtering = (io->scaled_width < W * 3 / 4) &&
|
||||
(io->scaled_height < H * 3 / 4);
|
||||
io->bypass_filtering |= (io->scaled_width < W * 3 / 4) &&
|
||||
(io->scaled_height < H * 3 / 4);
|
||||
io->fancy_upsampling = 0;
|
||||
}
|
||||
return 1;
|
||||
|
||||
Vendored
+4
@@ -77,6 +77,10 @@ VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers);
|
||||
//------------------------------------------------------------------------------
|
||||
// Misc utils
|
||||
|
||||
// Returns true if crop dimensions are within image bounds.
|
||||
int WebPCheckCropDimensions(int image_width, int image_height,
|
||||
int x, int y, int w, int h);
|
||||
|
||||
// Initializes VP8Io with custom setup, io and teardown functions. The default
|
||||
// hooks will use the supplied 'params' as io->opaque handle.
|
||||
void WebPInitCustomIo(WebPDecParams* const params, VP8Io* const io);
|
||||
|
||||
+34
-18
@@ -23,6 +23,14 @@
|
||||
|
||||
#define NUM_CHANNELS 4
|
||||
|
||||
// Channel extraction from a uint32_t representation of a uint8_t RGBA/BGRA
|
||||
// buffer.
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define CHANNEL_SHIFT(i) (24 - (i) * 8)
|
||||
#else
|
||||
#define CHANNEL_SHIFT(i) ((i) * 8)
|
||||
#endif
|
||||
|
||||
typedef void (*BlendRowFunc)(uint32_t* const, const uint32_t* const, int);
|
||||
static void BlendPixelRowNonPremult(uint32_t* const src,
|
||||
const uint32_t* const dst, int num_pixels);
|
||||
@@ -87,11 +95,19 @@ WebPAnimDecoder* WebPAnimDecoderNewInternal(
|
||||
int abi_version) {
|
||||
WebPAnimDecoderOptions options;
|
||||
WebPAnimDecoder* dec = NULL;
|
||||
WebPBitstreamFeatures features;
|
||||
if (webp_data == NULL ||
|
||||
WEBP_ABI_IS_INCOMPATIBLE(abi_version, WEBP_DEMUX_ABI_VERSION)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Validate the bitstream before doing expensive allocations. The demuxer may
|
||||
// be more tolerant than the decoder.
|
||||
if (WebPGetFeatures(webp_data->bytes, webp_data->size, &features) !=
|
||||
VP8_STATUS_OK) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Note: calloc() so that the pointer members are initialized to NULL.
|
||||
dec = (WebPAnimDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
|
||||
if (dec == NULL) goto Error;
|
||||
@@ -145,7 +161,7 @@ static int ZeroFillCanvas(uint8_t* buf, uint32_t canvas_width,
|
||||
uint32_t canvas_height) {
|
||||
const uint64_t size =
|
||||
(uint64_t)canvas_width * canvas_height * NUM_CHANNELS * sizeof(*buf);
|
||||
if (size != (size_t)size) return 0;
|
||||
if (!CheckSizeOverflow(size)) return 0;
|
||||
memset(buf, 0, (size_t)size);
|
||||
return 1;
|
||||
}
|
||||
@@ -166,7 +182,7 @@ static void ZeroFillFrameRect(uint8_t* buf, int buf_stride, int x_offset,
|
||||
static int CopyCanvas(const uint8_t* src, uint8_t* dst,
|
||||
uint32_t width, uint32_t height) {
|
||||
const uint64_t size = (uint64_t)width * height * NUM_CHANNELS;
|
||||
if (size != (size_t)size) return 0;
|
||||
if (!CheckSizeOverflow(size)) return 0;
|
||||
assert(src != NULL && dst != NULL);
|
||||
memcpy(dst, src, (size_t)size);
|
||||
return 1;
|
||||
@@ -201,35 +217,35 @@ static uint8_t BlendChannelNonPremult(uint32_t src, uint8_t src_a,
|
||||
const uint8_t dst_channel = (dst >> shift) & 0xff;
|
||||
const uint32_t blend_unscaled = src_channel * src_a + dst_channel * dst_a;
|
||||
assert(blend_unscaled < (1ULL << 32) / scale);
|
||||
return (blend_unscaled * scale) >> 24;
|
||||
return (blend_unscaled * scale) >> CHANNEL_SHIFT(3);
|
||||
}
|
||||
|
||||
// Blend 'src' over 'dst' assuming they are NOT pre-multiplied by alpha.
|
||||
static uint32_t BlendPixelNonPremult(uint32_t src, uint32_t dst) {
|
||||
const uint8_t src_a = (src >> 24) & 0xff;
|
||||
const uint8_t src_a = (src >> CHANNEL_SHIFT(3)) & 0xff;
|
||||
|
||||
if (src_a == 0) {
|
||||
return dst;
|
||||
} else {
|
||||
const uint8_t dst_a = (dst >> 24) & 0xff;
|
||||
const uint8_t dst_a = (dst >> CHANNEL_SHIFT(3)) & 0xff;
|
||||
// This is the approximate integer arithmetic for the actual formula:
|
||||
// dst_factor_a = (dst_a * (255 - src_a)) / 255.
|
||||
const uint8_t dst_factor_a = (dst_a * (256 - src_a)) >> 8;
|
||||
const uint8_t blend_a = src_a + dst_factor_a;
|
||||
const uint32_t scale = (1UL << 24) / blend_a;
|
||||
|
||||
const uint8_t blend_r =
|
||||
BlendChannelNonPremult(src, src_a, dst, dst_factor_a, scale, 0);
|
||||
const uint8_t blend_g =
|
||||
BlendChannelNonPremult(src, src_a, dst, dst_factor_a, scale, 8);
|
||||
const uint8_t blend_b =
|
||||
BlendChannelNonPremult(src, src_a, dst, dst_factor_a, scale, 16);
|
||||
const uint8_t blend_r = BlendChannelNonPremult(
|
||||
src, src_a, dst, dst_factor_a, scale, CHANNEL_SHIFT(0));
|
||||
const uint8_t blend_g = BlendChannelNonPremult(
|
||||
src, src_a, dst, dst_factor_a, scale, CHANNEL_SHIFT(1));
|
||||
const uint8_t blend_b = BlendChannelNonPremult(
|
||||
src, src_a, dst, dst_factor_a, scale, CHANNEL_SHIFT(2));
|
||||
assert(src_a + dst_factor_a < 256);
|
||||
|
||||
return (blend_r << 0) |
|
||||
(blend_g << 8) |
|
||||
(blend_b << 16) |
|
||||
((uint32_t)blend_a << 24);
|
||||
return ((uint32_t)blend_r << CHANNEL_SHIFT(0)) |
|
||||
((uint32_t)blend_g << CHANNEL_SHIFT(1)) |
|
||||
((uint32_t)blend_b << CHANNEL_SHIFT(2)) |
|
||||
((uint32_t)blend_a << CHANNEL_SHIFT(3));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +255,7 @@ static void BlendPixelRowNonPremult(uint32_t* const src,
|
||||
const uint32_t* const dst, int num_pixels) {
|
||||
int i;
|
||||
for (i = 0; i < num_pixels; ++i) {
|
||||
const uint8_t src_alpha = (src[i] >> 24) & 0xff;
|
||||
const uint8_t src_alpha = (src[i] >> CHANNEL_SHIFT(3)) & 0xff;
|
||||
if (src_alpha != 0xff) {
|
||||
src[i] = BlendPixelNonPremult(src[i], dst[i]);
|
||||
}
|
||||
@@ -256,7 +272,7 @@ static WEBP_INLINE uint32_t ChannelwiseMultiply(uint32_t pix, uint32_t scale) {
|
||||
|
||||
// Blend 'src' over 'dst' assuming they are pre-multiplied by alpha.
|
||||
static uint32_t BlendPixelPremult(uint32_t src, uint32_t dst) {
|
||||
const uint8_t src_a = (src >> 24) & 0xff;
|
||||
const uint8_t src_a = (src >> CHANNEL_SHIFT(3)) & 0xff;
|
||||
return src + ChannelwiseMultiply(dst, 256 - src_a);
|
||||
}
|
||||
|
||||
@@ -266,7 +282,7 @@ static void BlendPixelRowPremult(uint32_t* const src, const uint32_t* const dst,
|
||||
int num_pixels) {
|
||||
int i;
|
||||
for (i = 0; i < num_pixels; ++i) {
|
||||
const uint8_t src_alpha = (src[i] >> 24) & 0xff;
|
||||
const uint8_t src_alpha = (src[i] >> CHANNEL_SHIFT(3)) & 0xff;
|
||||
if (src_alpha != 0xff) {
|
||||
src[i] = BlendPixelPremult(src[i], dst[i]);
|
||||
}
|
||||
|
||||
Vendored
+13
-10
@@ -24,8 +24,8 @@
|
||||
#include "src/webp/format_constants.h"
|
||||
|
||||
#define DMUX_MAJ_VERSION 1
|
||||
#define DMUX_MIN_VERSION 2
|
||||
#define DMUX_REV_VERSION 0
|
||||
#define DMUX_MIN_VERSION 3
|
||||
#define DMUX_REV_VERSION 1
|
||||
|
||||
typedef struct {
|
||||
size_t start_; // start location of the data
|
||||
@@ -221,12 +221,16 @@ static ParseStatus StoreFrame(int frame_num, uint32_t min_size,
|
||||
const size_t chunk_start_offset = mem->start_;
|
||||
const uint32_t fourcc = ReadLE32(mem);
|
||||
const uint32_t payload_size = ReadLE32(mem);
|
||||
const uint32_t payload_size_padded = payload_size + (payload_size & 1);
|
||||
const size_t payload_available = (payload_size_padded > MemDataSize(mem))
|
||||
? MemDataSize(mem) : payload_size_padded;
|
||||
const size_t chunk_size = CHUNK_HEADER_SIZE + payload_available;
|
||||
uint32_t payload_size_padded;
|
||||
size_t payload_available;
|
||||
size_t chunk_size;
|
||||
|
||||
if (payload_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
|
||||
|
||||
payload_size_padded = payload_size + (payload_size & 1);
|
||||
payload_available = (payload_size_padded > MemDataSize(mem))
|
||||
? MemDataSize(mem) : payload_size_padded;
|
||||
chunk_size = CHUNK_HEADER_SIZE + payload_available;
|
||||
if (SizeIsInvalid(mem, payload_size_padded)) return PARSE_ERROR;
|
||||
if (payload_size_padded > MemDataSize(mem)) status = PARSE_NEED_MORE_DATA;
|
||||
|
||||
@@ -451,9 +455,11 @@ static ParseStatus ParseVP8XChunks(WebPDemuxer* const dmux) {
|
||||
const size_t chunk_start_offset = mem->start_;
|
||||
const uint32_t fourcc = ReadLE32(mem);
|
||||
const uint32_t chunk_size = ReadLE32(mem);
|
||||
const uint32_t chunk_size_padded = chunk_size + (chunk_size & 1);
|
||||
uint32_t chunk_size_padded;
|
||||
|
||||
if (chunk_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
|
||||
|
||||
chunk_size_padded = chunk_size + (chunk_size & 1);
|
||||
if (SizeIsInvalid(mem, chunk_size_padded)) return PARSE_ERROR;
|
||||
|
||||
switch (fourcc) {
|
||||
@@ -608,7 +614,6 @@ static int IsValidExtendedFormat(const WebPDemuxer* const dmux) {
|
||||
|
||||
while (f != NULL) {
|
||||
const int cur_frame_set = f->frame_num_;
|
||||
int frame_count = 0;
|
||||
|
||||
// Check frame properties.
|
||||
for (; f != NULL && f->frame_num_ == cur_frame_set; f = f->next_) {
|
||||
@@ -643,8 +648,6 @@ static int IsValidExtendedFormat(const WebPDemuxer* const dmux) {
|
||||
dmux->canvas_width_, dmux->canvas_height_)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
++frame_count;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
+41
-25
@@ -157,7 +157,8 @@ void WebPMultARGBRow_C(uint32_t* const ptr, int width, int inverse) {
|
||||
}
|
||||
}
|
||||
|
||||
void WebPMultRow_C(uint8_t* const ptr, const uint8_t* const alpha,
|
||||
void WebPMultRow_C(uint8_t* WEBP_RESTRICT const ptr,
|
||||
const uint8_t* WEBP_RESTRICT const alpha,
|
||||
int width, int inverse) {
|
||||
int x;
|
||||
for (x = 0; x < width; ++x) {
|
||||
@@ -178,7 +179,8 @@ void WebPMultRow_C(uint8_t* const ptr, const uint8_t* const alpha,
|
||||
#undef MFIX
|
||||
|
||||
void (*WebPMultARGBRow)(uint32_t* const ptr, int width, int inverse);
|
||||
void (*WebPMultRow)(uint8_t* const ptr, const uint8_t* const alpha,
|
||||
void (*WebPMultRow)(uint8_t* WEBP_RESTRICT const ptr,
|
||||
const uint8_t* WEBP_RESTRICT const alpha,
|
||||
int width, int inverse);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -193,8 +195,8 @@ void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows,
|
||||
}
|
||||
}
|
||||
|
||||
void WebPMultRows(uint8_t* ptr, int stride,
|
||||
const uint8_t* alpha, int alpha_stride,
|
||||
void WebPMultRows(uint8_t* WEBP_RESTRICT ptr, int stride,
|
||||
const uint8_t* WEBP_RESTRICT alpha, int alpha_stride,
|
||||
int width, int num_rows, int inverse) {
|
||||
int n;
|
||||
for (n = 0; n < num_rows; ++n) {
|
||||
@@ -290,9 +292,9 @@ static void ApplyAlphaMultiply_16b_C(uint8_t* rgba4444,
|
||||
}
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
static int DispatchAlpha_C(const uint8_t* alpha, int alpha_stride,
|
||||
static int DispatchAlpha_C(const uint8_t* WEBP_RESTRICT alpha, int alpha_stride,
|
||||
int width, int height,
|
||||
uint8_t* dst, int dst_stride) {
|
||||
uint8_t* WEBP_RESTRICT dst, int dst_stride) {
|
||||
uint32_t alpha_mask = 0xff;
|
||||
int i, j;
|
||||
|
||||
@@ -309,9 +311,10 @@ static int DispatchAlpha_C(const uint8_t* alpha, int alpha_stride,
|
||||
return (alpha_mask != 0xff);
|
||||
}
|
||||
|
||||
static void DispatchAlphaToGreen_C(const uint8_t* alpha, int alpha_stride,
|
||||
int width, int height,
|
||||
uint32_t* dst, int dst_stride) {
|
||||
static void DispatchAlphaToGreen_C(const uint8_t* WEBP_RESTRICT alpha,
|
||||
int alpha_stride, int width, int height,
|
||||
uint32_t* WEBP_RESTRICT dst,
|
||||
int dst_stride) {
|
||||
int i, j;
|
||||
for (j = 0; j < height; ++j) {
|
||||
for (i = 0; i < width; ++i) {
|
||||
@@ -322,9 +325,9 @@ static void DispatchAlphaToGreen_C(const uint8_t* alpha, int alpha_stride,
|
||||
}
|
||||
}
|
||||
|
||||
static int ExtractAlpha_C(const uint8_t* argb, int argb_stride,
|
||||
static int ExtractAlpha_C(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
|
||||
int width, int height,
|
||||
uint8_t* alpha, int alpha_stride) {
|
||||
uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
|
||||
uint8_t alpha_mask = 0xff;
|
||||
int i, j;
|
||||
|
||||
@@ -340,7 +343,8 @@ static int ExtractAlpha_C(const uint8_t* argb, int argb_stride,
|
||||
return (alpha_mask == 0xff);
|
||||
}
|
||||
|
||||
static void ExtractGreen_C(const uint32_t* argb, uint8_t* alpha, int size) {
|
||||
static void ExtractGreen_C(const uint32_t* WEBP_RESTRICT argb,
|
||||
uint8_t* WEBP_RESTRICT alpha, int size) {
|
||||
int i;
|
||||
for (i = 0; i < size; ++i) alpha[i] = argb[i] >> 8;
|
||||
}
|
||||
@@ -372,8 +376,11 @@ static WEBP_INLINE uint32_t MakeARGB32(int a, int r, int g, int b) {
|
||||
}
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
static void PackARGB_C(const uint8_t* a, const uint8_t* r, const uint8_t* g,
|
||||
const uint8_t* b, int len, uint32_t* out) {
|
||||
static void PackARGB_C(const uint8_t* WEBP_RESTRICT a,
|
||||
const uint8_t* WEBP_RESTRICT r,
|
||||
const uint8_t* WEBP_RESTRICT g,
|
||||
const uint8_t* WEBP_RESTRICT b,
|
||||
int len, uint32_t* WEBP_RESTRICT out) {
|
||||
int i;
|
||||
for (i = 0; i < len; ++i) {
|
||||
out[i] = MakeARGB32(a[4 * i], r[4 * i], g[4 * i], b[4 * i]);
|
||||
@@ -381,8 +388,10 @@ static void PackARGB_C(const uint8_t* a, const uint8_t* r, const uint8_t* g,
|
||||
}
|
||||
#endif
|
||||
|
||||
static void PackRGB_C(const uint8_t* r, const uint8_t* g, const uint8_t* b,
|
||||
int len, int step, uint32_t* out) {
|
||||
static void PackRGB_C(const uint8_t* WEBP_RESTRICT r,
|
||||
const uint8_t* WEBP_RESTRICT g,
|
||||
const uint8_t* WEBP_RESTRICT b,
|
||||
int len, int step, uint32_t* WEBP_RESTRICT out) {
|
||||
int i, offset = 0;
|
||||
for (i = 0; i < len; ++i) {
|
||||
out[i] = MakeARGB32(0xff, r[offset], g[offset], b[offset]);
|
||||
@@ -392,16 +401,22 @@ static void PackRGB_C(const uint8_t* r, const uint8_t* g, const uint8_t* b,
|
||||
|
||||
void (*WebPApplyAlphaMultiply)(uint8_t*, int, int, int, int);
|
||||
void (*WebPApplyAlphaMultiply4444)(uint8_t*, int, int, int);
|
||||
int (*WebPDispatchAlpha)(const uint8_t*, int, int, int, uint8_t*, int);
|
||||
void (*WebPDispatchAlphaToGreen)(const uint8_t*, int, int, int, uint32_t*, int);
|
||||
int (*WebPExtractAlpha)(const uint8_t*, int, int, int, uint8_t*, int);
|
||||
void (*WebPExtractGreen)(const uint32_t* argb, uint8_t* alpha, int size);
|
||||
int (*WebPDispatchAlpha)(const uint8_t* WEBP_RESTRICT, int, int, int,
|
||||
uint8_t* WEBP_RESTRICT, int);
|
||||
void (*WebPDispatchAlphaToGreen)(const uint8_t* WEBP_RESTRICT, int, int, int,
|
||||
uint32_t* WEBP_RESTRICT, int);
|
||||
int (*WebPExtractAlpha)(const uint8_t* WEBP_RESTRICT, int, int, int,
|
||||
uint8_t* WEBP_RESTRICT, int);
|
||||
void (*WebPExtractGreen)(const uint32_t* WEBP_RESTRICT argb,
|
||||
uint8_t* WEBP_RESTRICT alpha, int size);
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
void (*WebPPackARGB)(const uint8_t* a, const uint8_t* r, const uint8_t* g,
|
||||
const uint8_t* b, int, uint32_t*);
|
||||
#endif
|
||||
void (*WebPPackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b,
|
||||
int len, int step, uint32_t* out);
|
||||
void (*WebPPackRGB)(const uint8_t* WEBP_RESTRICT r,
|
||||
const uint8_t* WEBP_RESTRICT g,
|
||||
const uint8_t* WEBP_RESTRICT b,
|
||||
int len, int step, uint32_t* WEBP_RESTRICT out);
|
||||
|
||||
int (*WebPHasAlpha8b)(const uint8_t* src, int length);
|
||||
int (*WebPHasAlpha32b)(const uint8_t* src, int length);
|
||||
@@ -410,6 +425,7 @@ void (*WebPAlphaReplace)(uint32_t* src, int length, uint32_t color);
|
||||
//------------------------------------------------------------------------------
|
||||
// Init function
|
||||
|
||||
extern VP8CPUInfo VP8GetCPUInfo;
|
||||
extern void WebPInitAlphaProcessingMIPSdspR2(void);
|
||||
extern void WebPInitAlphaProcessingSSE2(void);
|
||||
extern void WebPInitAlphaProcessingSSE41(void);
|
||||
@@ -438,10 +454,10 @@ WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) {
|
||||
|
||||
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
||||
if (VP8GetCPUInfo != NULL) {
|
||||
#if defined(WEBP_USE_SSE2)
|
||||
#if defined(WEBP_HAVE_SSE2)
|
||||
if (VP8GetCPUInfo(kSSE2)) {
|
||||
WebPInitAlphaProcessingSSE2();
|
||||
#if defined(WEBP_USE_SSE41)
|
||||
#if defined(WEBP_HAVE_SSE41)
|
||||
if (VP8GetCPUInfo(kSSE4_1)) {
|
||||
WebPInitAlphaProcessingSSE41();
|
||||
}
|
||||
@@ -455,7 +471,7 @@ WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(WEBP_USE_NEON)
|
||||
#if defined(WEBP_HAVE_NEON)
|
||||
if (WEBP_NEON_OMIT_C_CODE ||
|
||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||
WebPInitAlphaProcessingNEON();
|
||||
|
||||
+15
-12
@@ -80,10 +80,10 @@ static void ApplyAlphaMultiply_NEON(uint8_t* rgba, int alpha_first,
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static int DispatchAlpha_NEON(const uint8_t* alpha, int alpha_stride,
|
||||
int width, int height,
|
||||
uint8_t* dst, int dst_stride) {
|
||||
uint32_t alpha_mask = 0xffffffffu;
|
||||
static int DispatchAlpha_NEON(const uint8_t* WEBP_RESTRICT alpha,
|
||||
int alpha_stride, int width, int height,
|
||||
uint8_t* WEBP_RESTRICT dst, int dst_stride) {
|
||||
uint32_t alpha_mask = 0xffu;
|
||||
uint8x8_t mask8 = vdup_n_u8(0xff);
|
||||
uint32_t tmp[2];
|
||||
int i, j;
|
||||
@@ -107,14 +107,16 @@ static int DispatchAlpha_NEON(const uint8_t* alpha, int alpha_stride,
|
||||
dst += dst_stride;
|
||||
}
|
||||
vst1_u8((uint8_t*)tmp, mask8);
|
||||
alpha_mask *= 0x01010101;
|
||||
alpha_mask &= tmp[0];
|
||||
alpha_mask &= tmp[1];
|
||||
return (alpha_mask != 0xffffffffu);
|
||||
}
|
||||
|
||||
static void DispatchAlphaToGreen_NEON(const uint8_t* alpha, int alpha_stride,
|
||||
int width, int height,
|
||||
uint32_t* dst, int dst_stride) {
|
||||
static void DispatchAlphaToGreen_NEON(const uint8_t* WEBP_RESTRICT alpha,
|
||||
int alpha_stride, int width, int height,
|
||||
uint32_t* WEBP_RESTRICT dst,
|
||||
int dst_stride) {
|
||||
int i, j;
|
||||
uint8x8x4_t greens; // leave A/R/B channels zero'd.
|
||||
greens.val[0] = vdup_n_u8(0);
|
||||
@@ -131,10 +133,10 @@ static void DispatchAlphaToGreen_NEON(const uint8_t* alpha, int alpha_stride,
|
||||
}
|
||||
}
|
||||
|
||||
static int ExtractAlpha_NEON(const uint8_t* argb, int argb_stride,
|
||||
static int ExtractAlpha_NEON(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
|
||||
int width, int height,
|
||||
uint8_t* alpha, int alpha_stride) {
|
||||
uint32_t alpha_mask = 0xffffffffu;
|
||||
uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
|
||||
uint32_t alpha_mask = 0xffu;
|
||||
uint8x8_t mask8 = vdup_n_u8(0xff);
|
||||
uint32_t tmp[2];
|
||||
int i, j;
|
||||
@@ -156,13 +158,14 @@ static int ExtractAlpha_NEON(const uint8_t* argb, int argb_stride,
|
||||
alpha += alpha_stride;
|
||||
}
|
||||
vst1_u8((uint8_t*)tmp, mask8);
|
||||
alpha_mask *= 0x01010101;
|
||||
alpha_mask &= tmp[0];
|
||||
alpha_mask &= tmp[1];
|
||||
return (alpha_mask == 0xffffffffu);
|
||||
}
|
||||
|
||||
static void ExtractGreen_NEON(const uint32_t* argb,
|
||||
uint8_t* alpha, int size) {
|
||||
static void ExtractGreen_NEON(const uint32_t* WEBP_RESTRICT argb,
|
||||
uint8_t* WEBP_RESTRICT alpha, int size) {
|
||||
int i;
|
||||
for (i = 0; i + 16 <= size; i += 16) {
|
||||
const uint8x16x4_t rgbX = vld4q_u8((const uint8_t*)(argb + i));
|
||||
|
||||
+58
-15
@@ -18,16 +18,16 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static int DispatchAlpha_SSE2(const uint8_t* alpha, int alpha_stride,
|
||||
int width, int height,
|
||||
uint8_t* dst, int dst_stride) {
|
||||
static int DispatchAlpha_SSE2(const uint8_t* WEBP_RESTRICT alpha,
|
||||
int alpha_stride, int width, int height,
|
||||
uint8_t* WEBP_RESTRICT dst, int dst_stride) {
|
||||
// alpha_and stores an 'and' operation of all the alpha[] values. The final
|
||||
// value is not 0xff if any of the alpha[] is not equal to 0xff.
|
||||
uint32_t alpha_and = 0xff;
|
||||
int i, j;
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
const __m128i rgb_mask = _mm_set1_epi32(0xffffff00u); // to preserve RGB
|
||||
const __m128i all_0xff = _mm_set_epi32(0, 0, ~0u, ~0u);
|
||||
const __m128i rgb_mask = _mm_set1_epi32((int)0xffffff00); // to preserve RGB
|
||||
const __m128i all_0xff = _mm_set_epi32(0, 0, ~0, ~0);
|
||||
__m128i all_alphas = all_0xff;
|
||||
|
||||
// We must be able to access 3 extra bytes after the last written byte
|
||||
@@ -72,9 +72,10 @@ static int DispatchAlpha_SSE2(const uint8_t* alpha, int alpha_stride,
|
||||
return (alpha_and != 0xff);
|
||||
}
|
||||
|
||||
static void DispatchAlphaToGreen_SSE2(const uint8_t* alpha, int alpha_stride,
|
||||
int width, int height,
|
||||
uint32_t* dst, int dst_stride) {
|
||||
static void DispatchAlphaToGreen_SSE2(const uint8_t* WEBP_RESTRICT alpha,
|
||||
int alpha_stride, int width, int height,
|
||||
uint32_t* WEBP_RESTRICT dst,
|
||||
int dst_stride) {
|
||||
int i, j;
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
const int limit = width & ~15;
|
||||
@@ -98,15 +99,15 @@ static void DispatchAlphaToGreen_SSE2(const uint8_t* alpha, int alpha_stride,
|
||||
}
|
||||
}
|
||||
|
||||
static int ExtractAlpha_SSE2(const uint8_t* argb, int argb_stride,
|
||||
static int ExtractAlpha_SSE2(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
|
||||
int width, int height,
|
||||
uint8_t* alpha, int alpha_stride) {
|
||||
uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
|
||||
// alpha_and stores an 'and' operation of all the alpha[] values. The final
|
||||
// value is not 0xff if any of the alpha[] is not equal to 0xff.
|
||||
uint32_t alpha_and = 0xff;
|
||||
int i, j;
|
||||
const __m128i a_mask = _mm_set1_epi32(0xffu); // to preserve alpha
|
||||
const __m128i all_0xff = _mm_set_epi32(0, 0, ~0u, ~0u);
|
||||
const __m128i a_mask = _mm_set1_epi32(0xff); // to preserve alpha
|
||||
const __m128i all_0xff = _mm_set_epi32(0, 0, ~0, ~0);
|
||||
__m128i all_alphas = all_0xff;
|
||||
|
||||
// We must be able to access 3 extra bytes after the last written byte
|
||||
@@ -143,6 +144,46 @@ static int ExtractAlpha_SSE2(const uint8_t* argb, int argb_stride,
|
||||
return (alpha_and == 0xff);
|
||||
}
|
||||
|
||||
static void ExtractGreen_SSE2(const uint32_t* WEBP_RESTRICT argb,
|
||||
uint8_t* WEBP_RESTRICT alpha, int size) {
|
||||
int i;
|
||||
const __m128i mask = _mm_set1_epi32(0xff);
|
||||
const __m128i* src = (const __m128i*)argb;
|
||||
|
||||
for (i = 0; i + 16 <= size; i += 16, src += 4) {
|
||||
const __m128i a0 = _mm_loadu_si128(src + 0);
|
||||
const __m128i a1 = _mm_loadu_si128(src + 1);
|
||||
const __m128i a2 = _mm_loadu_si128(src + 2);
|
||||
const __m128i a3 = _mm_loadu_si128(src + 3);
|
||||
const __m128i b0 = _mm_srli_epi32(a0, 8);
|
||||
const __m128i b1 = _mm_srli_epi32(a1, 8);
|
||||
const __m128i b2 = _mm_srli_epi32(a2, 8);
|
||||
const __m128i b3 = _mm_srli_epi32(a3, 8);
|
||||
const __m128i c0 = _mm_and_si128(b0, mask);
|
||||
const __m128i c1 = _mm_and_si128(b1, mask);
|
||||
const __m128i c2 = _mm_and_si128(b2, mask);
|
||||
const __m128i c3 = _mm_and_si128(b3, mask);
|
||||
const __m128i d0 = _mm_packs_epi32(c0, c1);
|
||||
const __m128i d1 = _mm_packs_epi32(c2, c3);
|
||||
const __m128i e = _mm_packus_epi16(d0, d1);
|
||||
// store
|
||||
_mm_storeu_si128((__m128i*)&alpha[i], e);
|
||||
}
|
||||
if (i + 8 <= size) {
|
||||
const __m128i a0 = _mm_loadu_si128(src + 0);
|
||||
const __m128i a1 = _mm_loadu_si128(src + 1);
|
||||
const __m128i b0 = _mm_srli_epi32(a0, 8);
|
||||
const __m128i b1 = _mm_srli_epi32(a1, 8);
|
||||
const __m128i c0 = _mm_and_si128(b0, mask);
|
||||
const __m128i c1 = _mm_and_si128(b1, mask);
|
||||
const __m128i d = _mm_packs_epi32(c0, c1);
|
||||
const __m128i e = _mm_packus_epi16(d, d);
|
||||
_mm_storel_epi64((__m128i*)&alpha[i], e);
|
||||
i += 8;
|
||||
}
|
||||
for (; i < size; ++i) alpha[i] = argb[i] >> 8;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Non-dither premultiplied modes
|
||||
|
||||
@@ -177,7 +218,7 @@ static int ExtractAlpha_SSE2(const uint8_t* argb, int argb_stride,
|
||||
static void ApplyAlphaMultiply_SSE2(uint8_t* rgba, int alpha_first,
|
||||
int w, int h, int stride) {
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
const __m128i kMult = _mm_set1_epi16(0x8081u);
|
||||
const __m128i kMult = _mm_set1_epi16((short)0x8081);
|
||||
const __m128i kMask = _mm_set_epi16(0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0);
|
||||
const int kSpan = 4;
|
||||
while (h-- > 0) {
|
||||
@@ -266,7 +307,7 @@ static int HasAlpha32b_SSE2(const uint8_t* src, int length) {
|
||||
}
|
||||
|
||||
static void AlphaReplace_SSE2(uint32_t* src, int length, uint32_t color) {
|
||||
const __m128i m_color = _mm_set1_epi32(color);
|
||||
const __m128i m_color = _mm_set1_epi32((int)color);
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
int i = 0;
|
||||
for (; i + 8 <= length; i += 8) {
|
||||
@@ -317,7 +358,8 @@ static void MultARGBRow_SSE2(uint32_t* const ptr, int width, int inverse) {
|
||||
if (width > 0) WebPMultARGBRow_C(ptr + x, width, inverse);
|
||||
}
|
||||
|
||||
static void MultRow_SSE2(uint8_t* const ptr, const uint8_t* const alpha,
|
||||
static void MultRow_SSE2(uint8_t* WEBP_RESTRICT const ptr,
|
||||
const uint8_t* WEBP_RESTRICT const alpha,
|
||||
int width, int inverse) {
|
||||
int x = 0;
|
||||
if (!inverse) {
|
||||
@@ -352,6 +394,7 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingSSE2(void) {
|
||||
WebPDispatchAlpha = DispatchAlpha_SSE2;
|
||||
WebPDispatchAlphaToGreen = DispatchAlphaToGreen_SSE2;
|
||||
WebPExtractAlpha = ExtractAlpha_SSE2;
|
||||
WebPExtractGreen = ExtractGreen_SSE2;
|
||||
|
||||
WebPHasAlpha8b = HasAlpha8b_SSE2;
|
||||
WebPHasAlpha32b = HasAlpha32b_SSE2;
|
||||
|
||||
+4
-4
@@ -19,14 +19,14 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static int ExtractAlpha_SSE41(const uint8_t* argb, int argb_stride,
|
||||
int width, int height,
|
||||
uint8_t* alpha, int alpha_stride) {
|
||||
static int ExtractAlpha_SSE41(const uint8_t* WEBP_RESTRICT argb,
|
||||
int argb_stride, int width, int height,
|
||||
uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
|
||||
// alpha_and stores an 'and' operation of all the alpha[] values. The final
|
||||
// value is not 0xff if any of the alpha[] is not equal to 0xff.
|
||||
uint32_t alpha_and = 0xff;
|
||||
int i, j;
|
||||
const __m128i all_0xff = _mm_set1_epi32(~0u);
|
||||
const __m128i all_0xff = _mm_set1_epi32(~0);
|
||||
__m128i all_alphas = all_0xff;
|
||||
|
||||
// We must be able to access 3 extra bytes after the last written byte
|
||||
|
||||
Vendored
+3
-2
@@ -374,6 +374,7 @@ static void SetResidualCoeffs_C(const int16_t* const coeffs,
|
||||
VP8GetResidualCostFunc VP8GetResidualCost;
|
||||
VP8SetResidualCoeffsFunc VP8SetResidualCoeffs;
|
||||
|
||||
extern VP8CPUInfo VP8GetCPUInfo;
|
||||
extern void VP8EncDspCostInitMIPS32(void);
|
||||
extern void VP8EncDspCostInitMIPSdspR2(void);
|
||||
extern void VP8EncDspCostInitSSE2(void);
|
||||
@@ -395,12 +396,12 @@ WEBP_DSP_INIT_FUNC(VP8EncDspCostInit) {
|
||||
VP8EncDspCostInitMIPSdspR2();
|
||||
}
|
||||
#endif
|
||||
#if defined(WEBP_USE_SSE2)
|
||||
#if defined(WEBP_HAVE_SSE2)
|
||||
if (VP8GetCPUInfo(kSSE2)) {
|
||||
VP8EncDspCostInitSSE2();
|
||||
}
|
||||
#endif
|
||||
#if defined(WEBP_USE_NEON)
|
||||
#if defined(WEBP_HAVE_NEON)
|
||||
if (VP8GetCPUInfo(kNEON)) {
|
||||
VP8EncDspCostInitNEON();
|
||||
}
|
||||
|
||||
Vendored
+2
-2
@@ -29,7 +29,7 @@ static void SetResidualCoeffs_NEON(const int16_t* const coeffs,
|
||||
const uint8x16_t eob = vcombine_u8(vqmovn_u16(eob_0), vqmovn_u16(eob_1));
|
||||
const uint8x16_t masked = vandq_u8(eob, vld1q_u8(position));
|
||||
|
||||
#ifdef __aarch64__
|
||||
#if WEBP_AARCH64
|
||||
res->last = vmaxvq_u8(masked) - 1;
|
||||
#else
|
||||
const uint8x8_t eob_8x8 = vmax_u8(vget_low_u8(masked), vget_high_u8(masked));
|
||||
@@ -43,7 +43,7 @@ static void SetResidualCoeffs_NEON(const int16_t* const coeffs,
|
||||
|
||||
vst1_lane_s32(&res->last, vreinterpret_s32_u32(eob_32x2), 0);
|
||||
--res->last;
|
||||
#endif // __aarch64__
|
||||
#endif // WEBP_AARCH64
|
||||
|
||||
res->coeffs = coeffs;
|
||||
}
|
||||
|
||||
Vendored
+14
-7
@@ -11,7 +11,7 @@
|
||||
//
|
||||
// Author: Christian Duvivier (cduvivier@google.com)
|
||||
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "src/dsp/cpu.h"
|
||||
|
||||
#if defined(WEBP_HAVE_NEON_RTCD)
|
||||
#include <stdio.h>
|
||||
@@ -173,6 +173,7 @@ static int x86CPUInfo(CPUFeature feature) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
|
||||
VP8CPUInfo VP8GetCPUInfo = x86CPUInfo;
|
||||
#elif defined(WEBP_ANDROID_NEON) // NB: needs to be before generic NEON test.
|
||||
static int AndroidCPUInfo(CPUFeature feature) {
|
||||
@@ -184,22 +185,23 @@ static int AndroidCPUInfo(CPUFeature feature) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
|
||||
VP8CPUInfo VP8GetCPUInfo = AndroidCPUInfo;
|
||||
#elif defined(EMSCRIPTEN) // also needs to be before generic NEON test
|
||||
// Use compile flags as an indicator of SIMD support instead of a runtime check.
|
||||
static int wasmCPUInfo(CPUFeature feature) {
|
||||
switch (feature) {
|
||||
#ifdef WEBP_USE_SSE2
|
||||
#ifdef WEBP_HAVE_SSE2
|
||||
case kSSE2:
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef WEBP_USE_SSE41
|
||||
#ifdef WEBP_HAVE_SSE41
|
||||
case kSSE3:
|
||||
case kSlowSSSE3:
|
||||
case kSSE4_1:
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef WEBP_USE_NEON
|
||||
#ifdef WEBP_HAVE_NEON
|
||||
case kNEON:
|
||||
return 1;
|
||||
#endif
|
||||
@@ -208,10 +210,12 @@ static int wasmCPUInfo(CPUFeature feature) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
|
||||
VP8CPUInfo VP8GetCPUInfo = wasmCPUInfo;
|
||||
#elif defined(WEBP_USE_NEON)
|
||||
// define a dummy function to enable turning off NEON at runtime by setting
|
||||
// VP8DecGetCPUInfo = NULL
|
||||
#elif defined(WEBP_HAVE_NEON)
|
||||
// In most cases this function doesn't check for NEON support (it's assumed by
|
||||
// the configuration), but enables turning off NEON at runtime, for testing
|
||||
// purposes, by setting VP8GetCPUInfo = NULL.
|
||||
static int armCPUInfo(CPUFeature feature) {
|
||||
if (feature != kNEON) return 0;
|
||||
#if defined(__linux__) && defined(WEBP_HAVE_NEON_RTCD)
|
||||
@@ -235,6 +239,7 @@ static int armCPUInfo(CPUFeature feature) {
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
|
||||
VP8CPUInfo VP8GetCPUInfo = armCPUInfo;
|
||||
#elif defined(WEBP_USE_MIPS32) || defined(WEBP_USE_MIPS_DSP_R2) || \
|
||||
defined(WEBP_USE_MSA)
|
||||
@@ -246,7 +251,9 @@ static int mipsCPUInfo(CPUFeature feature) {
|
||||
}
|
||||
|
||||
}
|
||||
WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
|
||||
VP8CPUInfo VP8GetCPUInfo = mipsCPUInfo;
|
||||
#else
|
||||
WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
|
||||
VP8CPUInfo VP8GetCPUInfo = NULL;
|
||||
#endif
|
||||
|
||||
Vendored
+266
@@ -0,0 +1,266 @@
|
||||
// Copyright 2022 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// CPU detection functions and macros.
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#ifndef WEBP_DSP_CPU_H_
|
||||
#define WEBP_DSP_CPU_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "src/webp/config.h"
|
||||
#endif
|
||||
|
||||
#include "src/webp/types.h"
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define LOCAL_GCC_VERSION ((__GNUC__ << 8) | __GNUC_MINOR__)
|
||||
#define LOCAL_GCC_PREREQ(maj, min) (LOCAL_GCC_VERSION >= (((maj) << 8) | (min)))
|
||||
#else
|
||||
#define LOCAL_GCC_VERSION 0
|
||||
#define LOCAL_GCC_PREREQ(maj, min) 0
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
#define LOCAL_CLANG_VERSION ((__clang_major__ << 8) | __clang_minor__)
|
||||
#define LOCAL_CLANG_PREREQ(maj, min) \
|
||||
(LOCAL_CLANG_VERSION >= (((maj) << 8) | (min)))
|
||||
#else
|
||||
#define LOCAL_CLANG_VERSION 0
|
||||
#define LOCAL_CLANG_PREREQ(maj, min) 0
|
||||
#endif
|
||||
|
||||
#ifndef __has_builtin
|
||||
#define __has_builtin(x) 0
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// x86 defines.
|
||||
|
||||
#if !defined(HAVE_CONFIG_H)
|
||||
#if defined(_MSC_VER) && _MSC_VER > 1310 && \
|
||||
(defined(_M_X64) || defined(_M_IX86))
|
||||
#define WEBP_MSC_SSE2 // Visual C++ SSE2 targets
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1500 && \
|
||||
(defined(_M_X64) || defined(_M_IX86))
|
||||
#define WEBP_MSC_SSE41 // Visual C++ SSE4.1 targets
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// WEBP_HAVE_* are used to indicate the presence of the instruction set in dsp
|
||||
// files without intrinsics, allowing the corresponding Init() to be called.
|
||||
// Files containing intrinsics will need to be built targeting the instruction
|
||||
// set so should succeed on one of the earlier tests.
|
||||
#if (defined(__SSE2__) || defined(WEBP_MSC_SSE2)) && \
|
||||
(!defined(HAVE_CONFIG_H) || defined(WEBP_HAVE_SSE2))
|
||||
#define WEBP_USE_SSE2
|
||||
#endif
|
||||
|
||||
#if defined(WEBP_USE_SSE2) && !defined(WEBP_HAVE_SSE2)
|
||||
#define WEBP_HAVE_SSE2
|
||||
#endif
|
||||
|
||||
#if (defined(__SSE4_1__) || defined(WEBP_MSC_SSE41)) && \
|
||||
(!defined(HAVE_CONFIG_H) || defined(WEBP_HAVE_SSE41))
|
||||
#define WEBP_USE_SSE41
|
||||
#endif
|
||||
|
||||
#if defined(WEBP_USE_SSE41) && !defined(WEBP_HAVE_SSE41)
|
||||
#define WEBP_HAVE_SSE41
|
||||
#endif
|
||||
|
||||
#undef WEBP_MSC_SSE41
|
||||
#undef WEBP_MSC_SSE2
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Arm defines.
|
||||
|
||||
// The intrinsics currently cause compiler errors with arm-nacl-gcc and the
|
||||
// inline assembly would need to be modified for use with Native Client.
|
||||
#if ((defined(__ARM_NEON__) || defined(__aarch64__)) && \
|
||||
(!defined(HAVE_CONFIG_H) || defined(WEBP_HAVE_NEON))) && \
|
||||
!defined(__native_client__)
|
||||
#define WEBP_USE_NEON
|
||||
#endif
|
||||
|
||||
#if !defined(WEBP_USE_NEON) && defined(__ANDROID__) && \
|
||||
defined(__ARM_ARCH_7A__) && defined(HAVE_CPU_FEATURES_H)
|
||||
#define WEBP_ANDROID_NEON // Android targets that may have NEON
|
||||
#define WEBP_USE_NEON
|
||||
#endif
|
||||
|
||||
// Note: ARM64 is supported in Visual Studio 2017, but requires the direct
|
||||
// inclusion of arm64_neon.h; Visual Studio 2019 includes this file in
|
||||
// arm_neon.h. Compile errors were seen with Visual Studio 2019 16.4 with
|
||||
// vtbl4_u8(); a fix was made in 16.6.
|
||||
#if defined(_MSC_VER) && \
|
||||
((_MSC_VER >= 1700 && defined(_M_ARM)) || \
|
||||
(_MSC_VER >= 1926 && (defined(_M_ARM64) || defined(_M_ARM64EC))))
|
||||
#define WEBP_USE_NEON
|
||||
#define WEBP_USE_INTRINSICS
|
||||
#endif
|
||||
|
||||
#if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
|
||||
#define WEBP_AARCH64 1
|
||||
#else
|
||||
#define WEBP_AARCH64 0
|
||||
#endif
|
||||
|
||||
#if defined(WEBP_USE_NEON) && !defined(WEBP_HAVE_NEON)
|
||||
#define WEBP_HAVE_NEON
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// MIPS defines.
|
||||
|
||||
#if defined(__mips__) && !defined(__mips64) && defined(__mips_isa_rev) && \
|
||||
(__mips_isa_rev >= 1) && (__mips_isa_rev < 6)
|
||||
#define WEBP_USE_MIPS32
|
||||
#if (__mips_isa_rev >= 2)
|
||||
#define WEBP_USE_MIPS32_R2
|
||||
#if defined(__mips_dspr2) || (defined(__mips_dsp_rev) && __mips_dsp_rev >= 2)
|
||||
#define WEBP_USE_MIPS_DSP_R2
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__mips_msa) && defined(__mips_isa_rev) && (__mips_isa_rev >= 5)
|
||||
#define WEBP_USE_MSA
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef WEBP_DSP_OMIT_C_CODE
|
||||
#define WEBP_DSP_OMIT_C_CODE 1
|
||||
#endif
|
||||
|
||||
#if defined(WEBP_USE_NEON) && WEBP_DSP_OMIT_C_CODE
|
||||
#define WEBP_NEON_OMIT_C_CODE 1
|
||||
#else
|
||||
#define WEBP_NEON_OMIT_C_CODE 0
|
||||
#endif
|
||||
|
||||
#if !(LOCAL_CLANG_PREREQ(3, 8) || LOCAL_GCC_PREREQ(4, 8) || WEBP_AARCH64)
|
||||
#define WEBP_NEON_WORK_AROUND_GCC 1
|
||||
#else
|
||||
#define WEBP_NEON_WORK_AROUND_GCC 0
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// This macro prevents thread_sanitizer from reporting known concurrent writes.
|
||||
#define WEBP_TSAN_IGNORE_FUNCTION
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(thread_sanitizer)
|
||||
#undef WEBP_TSAN_IGNORE_FUNCTION
|
||||
#define WEBP_TSAN_IGNORE_FUNCTION __attribute__((no_sanitize_thread))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(memory_sanitizer)
|
||||
#define WEBP_MSAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(WEBP_USE_THREAD) && !defined(_WIN32)
|
||||
#include <pthread.h> // NOLINT
|
||||
|
||||
#define WEBP_DSP_INIT(func) \
|
||||
do { \
|
||||
static volatile VP8CPUInfo func##_last_cpuinfo_used = \
|
||||
(VP8CPUInfo)&func##_last_cpuinfo_used; \
|
||||
static pthread_mutex_t func##_lock = PTHREAD_MUTEX_INITIALIZER; \
|
||||
if (pthread_mutex_lock(&func##_lock)) break; \
|
||||
if (func##_last_cpuinfo_used != VP8GetCPUInfo) func(); \
|
||||
func##_last_cpuinfo_used = VP8GetCPUInfo; \
|
||||
(void)pthread_mutex_unlock(&func##_lock); \
|
||||
} while (0)
|
||||
#else // !(defined(WEBP_USE_THREAD) && !defined(_WIN32))
|
||||
#define WEBP_DSP_INIT(func) \
|
||||
do { \
|
||||
static volatile VP8CPUInfo func##_last_cpuinfo_used = \
|
||||
(VP8CPUInfo)&func##_last_cpuinfo_used; \
|
||||
if (func##_last_cpuinfo_used == VP8GetCPUInfo) break; \
|
||||
func(); \
|
||||
func##_last_cpuinfo_used = VP8GetCPUInfo; \
|
||||
} while (0)
|
||||
#endif // defined(WEBP_USE_THREAD) && !defined(_WIN32)
|
||||
|
||||
// Defines an Init + helper function that control multiple initialization of
|
||||
// function pointers / tables.
|
||||
/* Usage:
|
||||
WEBP_DSP_INIT_FUNC(InitFunc) {
|
||||
...function body
|
||||
}
|
||||
*/
|
||||
#define WEBP_DSP_INIT_FUNC(name) \
|
||||
static WEBP_TSAN_IGNORE_FUNCTION void name##_body(void); \
|
||||
WEBP_TSAN_IGNORE_FUNCTION void name(void) { WEBP_DSP_INIT(name##_body); } \
|
||||
static WEBP_TSAN_IGNORE_FUNCTION void name##_body(void)
|
||||
|
||||
#define WEBP_UBSAN_IGNORE_UNDEF
|
||||
#define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW
|
||||
#if defined(__clang__) && defined(__has_attribute)
|
||||
#if __has_attribute(no_sanitize)
|
||||
// This macro prevents the undefined behavior sanitizer from reporting
|
||||
// failures. This is only meant to silence unaligned loads on platforms that
|
||||
// are known to support them.
|
||||
#undef WEBP_UBSAN_IGNORE_UNDEF
|
||||
#define WEBP_UBSAN_IGNORE_UNDEF __attribute__((no_sanitize("undefined")))
|
||||
|
||||
// This macro prevents the undefined behavior sanitizer from reporting
|
||||
// failures related to unsigned integer overflows. This is only meant to
|
||||
// silence cases where this well defined behavior is expected.
|
||||
#undef WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW
|
||||
#define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW \
|
||||
__attribute__((no_sanitize("unsigned-integer-overflow")))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// If 'ptr' is NULL, returns NULL. Otherwise returns 'ptr + off'.
|
||||
// Prevents undefined behavior sanitizer nullptr-with-nonzero-offset warning.
|
||||
#if !defined(WEBP_OFFSET_PTR)
|
||||
#define WEBP_OFFSET_PTR(ptr, off) (((ptr) == NULL) ? NULL : ((ptr) + (off)))
|
||||
#endif
|
||||
|
||||
// Regularize the definition of WEBP_SWAP_16BIT_CSP (backward compatibility)
|
||||
#if !defined(WEBP_SWAP_16BIT_CSP)
|
||||
#define WEBP_SWAP_16BIT_CSP 0
|
||||
#endif
|
||||
|
||||
// some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__)
|
||||
#if !defined(WORDS_BIGENDIAN) && \
|
||||
(defined(__BIG_ENDIAN__) || defined(_M_PPC) || \
|
||||
(defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)))
|
||||
#define WORDS_BIGENDIAN
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
kSSE2,
|
||||
kSSE3,
|
||||
kSlowSSSE3, // special feature for slow SSSE3 architectures
|
||||
kSSE4_1,
|
||||
kAVX,
|
||||
kAVX2,
|
||||
kNEON,
|
||||
kMIPS32,
|
||||
kMIPSdspR2,
|
||||
kMSA
|
||||
} CPUFeature;
|
||||
|
||||
// returns true if the CPU supports the feature.
|
||||
typedef int (*VP8CPUInfo)(CPUFeature feature);
|
||||
|
||||
#endif // WEBP_DSP_CPU_H_
|
||||
Vendored
+4
-3
@@ -734,6 +734,7 @@ VP8SimpleFilterFunc VP8SimpleHFilter16i;
|
||||
void (*VP8DitherCombine8x8)(const uint8_t* dither, uint8_t* dst,
|
||||
int dst_stride);
|
||||
|
||||
extern VP8CPUInfo VP8GetCPUInfo;
|
||||
extern void VP8DspInitSSE2(void);
|
||||
extern void VP8DspInitSSE41(void);
|
||||
extern void VP8DspInitNEON(void);
|
||||
@@ -807,10 +808,10 @@ WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
||||
|
||||
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
||||
if (VP8GetCPUInfo != NULL) {
|
||||
#if defined(WEBP_USE_SSE2)
|
||||
#if defined(WEBP_HAVE_SSE2)
|
||||
if (VP8GetCPUInfo(kSSE2)) {
|
||||
VP8DspInitSSE2();
|
||||
#if defined(WEBP_USE_SSE41)
|
||||
#if defined(WEBP_HAVE_SSE41)
|
||||
if (VP8GetCPUInfo(kSSE4_1)) {
|
||||
VP8DspInitSSE41();
|
||||
}
|
||||
@@ -834,7 +835,7 @@ WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(WEBP_USE_NEON)
|
||||
#if defined(WEBP_HAVE_NEON)
|
||||
if (WEBP_NEON_OMIT_C_CODE ||
|
||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||
VP8DspInitNEON();
|
||||
|
||||
Vendored
+2
-2
@@ -1428,7 +1428,7 @@ static WEBP_INLINE void DC8_NEON(uint8_t* dst, int do_top, int do_left) {
|
||||
|
||||
if (do_top) {
|
||||
const uint8x8_t A = vld1_u8(dst - BPS); // top row
|
||||
#if defined(__aarch64__)
|
||||
#if WEBP_AARCH64
|
||||
const uint16_t p2 = vaddlv_u8(A);
|
||||
sum_top = vdupq_n_u16(p2);
|
||||
#else
|
||||
@@ -1511,7 +1511,7 @@ static WEBP_INLINE void DC16_NEON(uint8_t* dst, int do_top, int do_left) {
|
||||
|
||||
if (do_top) {
|
||||
const uint8x16_t A = vld1q_u8(dst - BPS); // top row
|
||||
#if defined(__aarch64__)
|
||||
#if WEBP_AARCH64
|
||||
const uint16_t p3 = vaddlvq_u8(A);
|
||||
sum_top = vdupq_n_u16(p3);
|
||||
#else
|
||||
|
||||
Vendored
+47
-46
@@ -158,10 +158,10 @@ static void Transform_SSE2(const int16_t* in, uint8_t* dst, int do_two) {
|
||||
dst3 = _mm_loadl_epi64((__m128i*)(dst + 3 * BPS));
|
||||
} else {
|
||||
// Load four bytes/pixels per line.
|
||||
dst0 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 0 * BPS));
|
||||
dst1 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 1 * BPS));
|
||||
dst2 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 2 * BPS));
|
||||
dst3 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 3 * BPS));
|
||||
dst0 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 0 * BPS));
|
||||
dst1 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 1 * BPS));
|
||||
dst2 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 2 * BPS));
|
||||
dst3 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 3 * BPS));
|
||||
}
|
||||
// Convert to 16b.
|
||||
dst0 = _mm_unpacklo_epi8(dst0, zero);
|
||||
@@ -187,10 +187,10 @@ static void Transform_SSE2(const int16_t* in, uint8_t* dst, int do_two) {
|
||||
_mm_storel_epi64((__m128i*)(dst + 3 * BPS), dst3);
|
||||
} else {
|
||||
// Store four bytes/pixels per line.
|
||||
WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
|
||||
WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
|
||||
WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
|
||||
WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
|
||||
WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
|
||||
WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
|
||||
WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
|
||||
WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,10 +213,10 @@ static void TransformAC3(const int16_t* in, uint8_t* dst) {
|
||||
const __m128i m3 = _mm_subs_epi16(B, d4);
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
// Load the source pixels.
|
||||
__m128i dst0 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 0 * BPS));
|
||||
__m128i dst1 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 1 * BPS));
|
||||
__m128i dst2 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 2 * BPS));
|
||||
__m128i dst3 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 3 * BPS));
|
||||
__m128i dst0 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 0 * BPS));
|
||||
__m128i dst1 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 1 * BPS));
|
||||
__m128i dst2 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 2 * BPS));
|
||||
__m128i dst3 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 3 * BPS));
|
||||
// Convert to 16b.
|
||||
dst0 = _mm_unpacklo_epi8(dst0, zero);
|
||||
dst1 = _mm_unpacklo_epi8(dst1, zero);
|
||||
@@ -233,10 +233,10 @@ static void TransformAC3(const int16_t* in, uint8_t* dst) {
|
||||
dst2 = _mm_packus_epi16(dst2, dst2);
|
||||
dst3 = _mm_packus_epi16(dst3, dst3);
|
||||
// Store the results.
|
||||
WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
|
||||
WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
|
||||
WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
|
||||
WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
|
||||
WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
|
||||
WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
|
||||
WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
|
||||
WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
|
||||
}
|
||||
#undef MUL
|
||||
#endif // USE_TRANSFORM_AC3
|
||||
@@ -477,11 +477,11 @@ static WEBP_INLINE void Load8x4_SSE2(const uint8_t* const b, int stride,
|
||||
// A0 = 63 62 61 60 23 22 21 20 43 42 41 40 03 02 01 00
|
||||
// A1 = 73 72 71 70 33 32 31 30 53 52 51 50 13 12 11 10
|
||||
const __m128i A0 = _mm_set_epi32(
|
||||
WebPMemToUint32(&b[6 * stride]), WebPMemToUint32(&b[2 * stride]),
|
||||
WebPMemToUint32(&b[4 * stride]), WebPMemToUint32(&b[0 * stride]));
|
||||
WebPMemToInt32(&b[6 * stride]), WebPMemToInt32(&b[2 * stride]),
|
||||
WebPMemToInt32(&b[4 * stride]), WebPMemToInt32(&b[0 * stride]));
|
||||
const __m128i A1 = _mm_set_epi32(
|
||||
WebPMemToUint32(&b[7 * stride]), WebPMemToUint32(&b[3 * stride]),
|
||||
WebPMemToUint32(&b[5 * stride]), WebPMemToUint32(&b[1 * stride]));
|
||||
WebPMemToInt32(&b[7 * stride]), WebPMemToInt32(&b[3 * stride]),
|
||||
WebPMemToInt32(&b[5 * stride]), WebPMemToInt32(&b[1 * stride]));
|
||||
|
||||
// B0 = 53 43 52 42 51 41 50 40 13 03 12 02 11 01 10 00
|
||||
// B1 = 73 63 72 62 71 61 70 60 33 23 32 22 31 21 30 20
|
||||
@@ -540,7 +540,7 @@ static WEBP_INLINE void Store4x4_SSE2(__m128i* const x,
|
||||
uint8_t* dst, int stride) {
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i, dst += stride) {
|
||||
WebPUint32ToMem(dst, _mm_cvtsi128_si32(*x));
|
||||
WebPInt32ToMem(dst, _mm_cvtsi128_si32(*x));
|
||||
*x = _mm_srli_si128(*x, 4);
|
||||
}
|
||||
}
|
||||
@@ -908,10 +908,10 @@ static void VE4_SSE2(uint8_t* dst) { // vertical
|
||||
const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGH00), one);
|
||||
const __m128i b = _mm_subs_epu8(a, lsb);
|
||||
const __m128i avg = _mm_avg_epu8(b, BCDEFGH0);
|
||||
const uint32_t vals = _mm_cvtsi128_si32(avg);
|
||||
const int vals = _mm_cvtsi128_si32(avg);
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
WebPUint32ToMem(dst + i * BPS, vals);
|
||||
WebPInt32ToMem(dst + i * BPS, vals);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -925,10 +925,10 @@ static void LD4_SSE2(uint8_t* dst) { // Down-Left
|
||||
const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGHH0), one);
|
||||
const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
|
||||
const __m128i abcdefg = _mm_avg_epu8(avg2, BCDEFGH0);
|
||||
WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcdefg ));
|
||||
WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
|
||||
WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
|
||||
WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
|
||||
WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcdefg ));
|
||||
WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
|
||||
WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
|
||||
WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
|
||||
}
|
||||
|
||||
static void VR4_SSE2(uint8_t* dst) { // Vertical-Right
|
||||
@@ -946,10 +946,10 @@ static void VR4_SSE2(uint8_t* dst) { // Vertical-Right
|
||||
const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one);
|
||||
const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
|
||||
const __m128i efgh = _mm_avg_epu8(avg2, XABCD);
|
||||
WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcd ));
|
||||
WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( efgh ));
|
||||
WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1)));
|
||||
WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1)));
|
||||
WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcd ));
|
||||
WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( efgh ));
|
||||
WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1)));
|
||||
WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1)));
|
||||
|
||||
// these two are hard to implement in SSE2, so we keep the C-version:
|
||||
DST(0, 2) = AVG3(J, I, X);
|
||||
@@ -970,11 +970,12 @@ static void VL4_SSE2(uint8_t* dst) { // Vertical-Left
|
||||
const __m128i abbc = _mm_or_si128(ab, bc);
|
||||
const __m128i lsb2 = _mm_and_si128(abbc, lsb1);
|
||||
const __m128i avg4 = _mm_subs_epu8(avg3, lsb2);
|
||||
const uint32_t extra_out = _mm_cvtsi128_si32(_mm_srli_si128(avg4, 4));
|
||||
WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( avg1 ));
|
||||
WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( avg4 ));
|
||||
WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1)));
|
||||
WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1)));
|
||||
const uint32_t extra_out =
|
||||
(uint32_t)_mm_cvtsi128_si32(_mm_srli_si128(avg4, 4));
|
||||
WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( avg1 ));
|
||||
WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( avg4 ));
|
||||
WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1)));
|
||||
WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1)));
|
||||
|
||||
// these two are hard to get and irregular
|
||||
DST(3, 2) = (extra_out >> 0) & 0xff;
|
||||
@@ -990,7 +991,7 @@ static void RD4_SSE2(uint8_t* dst) { // Down-right
|
||||
const uint32_t K = dst[-1 + 2 * BPS];
|
||||
const uint32_t L = dst[-1 + 3 * BPS];
|
||||
const __m128i LKJI_____ =
|
||||
_mm_cvtsi32_si128(L | (K << 8) | (J << 16) | (I << 24));
|
||||
_mm_cvtsi32_si128((int)(L | (K << 8) | (J << 16) | (I << 24)));
|
||||
const __m128i LKJIXABCD = _mm_or_si128(LKJI_____, ____XABCD);
|
||||
const __m128i KJIXABCD_ = _mm_srli_si128(LKJIXABCD, 1);
|
||||
const __m128i JIXABCD__ = _mm_srli_si128(LKJIXABCD, 2);
|
||||
@@ -998,10 +999,10 @@ static void RD4_SSE2(uint8_t* dst) { // Down-right
|
||||
const __m128i lsb = _mm_and_si128(_mm_xor_si128(JIXABCD__, LKJIXABCD), one);
|
||||
const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
|
||||
const __m128i abcdefg = _mm_avg_epu8(avg2, KJIXABCD_);
|
||||
WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32( abcdefg ));
|
||||
WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
|
||||
WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
|
||||
WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
|
||||
WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32( abcdefg ));
|
||||
WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
|
||||
WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
|
||||
WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
|
||||
}
|
||||
|
||||
#undef DST
|
||||
@@ -1015,13 +1016,13 @@ static WEBP_INLINE void TrueMotion_SSE2(uint8_t* dst, int size) {
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
int y;
|
||||
if (size == 4) {
|
||||
const __m128i top_values = _mm_cvtsi32_si128(WebPMemToUint32(top));
|
||||
const __m128i top_values = _mm_cvtsi32_si128(WebPMemToInt32(top));
|
||||
const __m128i top_base = _mm_unpacklo_epi8(top_values, zero);
|
||||
for (y = 0; y < 4; ++y, dst += BPS) {
|
||||
const int val = dst[-1] - top[-1];
|
||||
const __m128i base = _mm_set1_epi16(val);
|
||||
const __m128i out = _mm_packus_epi16(_mm_add_epi16(base, top_base), zero);
|
||||
WebPUint32ToMem(dst, _mm_cvtsi128_si32(out));
|
||||
WebPInt32ToMem(dst, _mm_cvtsi128_si32(out));
|
||||
}
|
||||
} else if (size == 8) {
|
||||
const __m128i top_values = _mm_loadl_epi64((const __m128i*)top);
|
||||
@@ -1062,7 +1063,7 @@ static void VE16_SSE2(uint8_t* dst) {
|
||||
static void HE16_SSE2(uint8_t* dst) { // horizontal
|
||||
int j;
|
||||
for (j = 16; j > 0; --j) {
|
||||
const __m128i values = _mm_set1_epi8(dst[-1]);
|
||||
const __m128i values = _mm_set1_epi8((char)dst[-1]);
|
||||
_mm_storeu_si128((__m128i*)dst, values);
|
||||
dst += BPS;
|
||||
}
|
||||
@@ -1070,7 +1071,7 @@ static void HE16_SSE2(uint8_t* dst) { // horizontal
|
||||
|
||||
static WEBP_INLINE void Put16_SSE2(uint8_t v, uint8_t* dst) {
|
||||
int j;
|
||||
const __m128i values = _mm_set1_epi8(v);
|
||||
const __m128i values = _mm_set1_epi8((char)v);
|
||||
for (j = 0; j < 16; ++j) {
|
||||
_mm_storeu_si128((__m128i*)(dst + j * BPS), values);
|
||||
}
|
||||
@@ -1130,7 +1131,7 @@ static void VE8uv_SSE2(uint8_t* dst) { // vertical
|
||||
// helper for chroma-DC predictions
|
||||
static WEBP_INLINE void Put8x8uv_SSE2(uint8_t v, uint8_t* dst) {
|
||||
int j;
|
||||
const __m128i values = _mm_set1_epi8(v);
|
||||
const __m128i values = _mm_set1_epi8((char)v);
|
||||
for (j = 0; j < 8; ++j) {
|
||||
_mm_storel_epi64((__m128i*)(dst + j * BPS), values);
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -23,7 +23,7 @@ static void HE16_SSE41(uint8_t* dst) { // horizontal
|
||||
int j;
|
||||
const __m128i kShuffle3 = _mm_set1_epi8(3);
|
||||
for (j = 16; j > 0; --j) {
|
||||
const __m128i in = _mm_cvtsi32_si128(WebPMemToUint32(dst - 4));
|
||||
const __m128i in = _mm_cvtsi32_si128(WebPMemToInt32(dst - 4));
|
||||
const __m128i values = _mm_shuffle_epi8(in, kShuffle3);
|
||||
_mm_storeu_si128((__m128i*)dst, values);
|
||||
dst += BPS;
|
||||
|
||||
Vendored
+40
-222
@@ -18,6 +18,7 @@
|
||||
#include "src/webp/config.h"
|
||||
#endif
|
||||
|
||||
#include "src/dsp/cpu.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -27,205 +28,22 @@ extern "C" {
|
||||
#define BPS 32 // this is the common stride for enc/dec
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CPU detection
|
||||
// WEBP_RESTRICT
|
||||
|
||||
// Declares a pointer with the restrict type qualifier if available.
|
||||
// This allows code to hint to the compiler that only this pointer references a
|
||||
// particular object or memory region within the scope of the block in which it
|
||||
// is declared. This may allow for improved optimizations due to the lack of
|
||||
// pointer aliasing. See also:
|
||||
// https://en.cppreference.com/w/c/language/restrict
|
||||
#if defined(__GNUC__)
|
||||
# define LOCAL_GCC_VERSION ((__GNUC__ << 8) | __GNUC_MINOR__)
|
||||
# define LOCAL_GCC_PREREQ(maj, min) \
|
||||
(LOCAL_GCC_VERSION >= (((maj) << 8) | (min)))
|
||||
#define WEBP_RESTRICT __restrict__
|
||||
#elif defined(_MSC_VER)
|
||||
#define WEBP_RESTRICT __restrict
|
||||
#else
|
||||
# define LOCAL_GCC_VERSION 0
|
||||
# define LOCAL_GCC_PREREQ(maj, min) 0
|
||||
#define WEBP_RESTRICT
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
# define LOCAL_CLANG_VERSION ((__clang_major__ << 8) | __clang_minor__)
|
||||
# define LOCAL_CLANG_PREREQ(maj, min) \
|
||||
(LOCAL_CLANG_VERSION >= (((maj) << 8) | (min)))
|
||||
#else
|
||||
# define LOCAL_CLANG_VERSION 0
|
||||
# define LOCAL_CLANG_PREREQ(maj, min) 0
|
||||
#endif
|
||||
|
||||
#ifndef __has_builtin
|
||||
# define __has_builtin(x) 0
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_CONFIG_H)
|
||||
#if defined(_MSC_VER) && _MSC_VER > 1310 && \
|
||||
(defined(_M_X64) || defined(_M_IX86))
|
||||
#define WEBP_MSC_SSE2 // Visual C++ SSE2 targets
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1500 && \
|
||||
(defined(_M_X64) || defined(_M_IX86))
|
||||
#define WEBP_MSC_SSE41 // Visual C++ SSE4.1 targets
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// WEBP_HAVE_* are used to indicate the presence of the instruction set in dsp
|
||||
// files without intrinsics, allowing the corresponding Init() to be called.
|
||||
// Files containing intrinsics will need to be built targeting the instruction
|
||||
// set so should succeed on one of the earlier tests.
|
||||
#if defined(__SSE2__) || defined(WEBP_MSC_SSE2) || defined(WEBP_HAVE_SSE2)
|
||||
#define WEBP_USE_SSE2
|
||||
#endif
|
||||
|
||||
#if defined(__SSE4_1__) || defined(WEBP_MSC_SSE41) || defined(WEBP_HAVE_SSE41)
|
||||
#define WEBP_USE_SSE41
|
||||
#endif
|
||||
|
||||
#undef WEBP_MSC_SSE41
|
||||
#undef WEBP_MSC_SSE2
|
||||
|
||||
// The intrinsics currently cause compiler errors with arm-nacl-gcc and the
|
||||
// inline assembly would need to be modified for use with Native Client.
|
||||
#if (defined(__ARM_NEON__) || \
|
||||
defined(__aarch64__) || defined(WEBP_HAVE_NEON)) && \
|
||||
!defined(__native_client__)
|
||||
#define WEBP_USE_NEON
|
||||
#endif
|
||||
|
||||
#if !defined(WEBP_USE_NEON) && defined(__ANDROID__) && \
|
||||
defined(__ARM_ARCH_7A__) && defined(HAVE_CPU_FEATURES_H)
|
||||
#define WEBP_ANDROID_NEON // Android targets that may have NEON
|
||||
#define WEBP_USE_NEON
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
|
||||
#define WEBP_USE_NEON
|
||||
#define WEBP_USE_INTRINSICS
|
||||
#endif
|
||||
|
||||
#if defined(__mips__) && !defined(__mips64) && \
|
||||
defined(__mips_isa_rev) && (__mips_isa_rev >= 1) && (__mips_isa_rev < 6)
|
||||
#define WEBP_USE_MIPS32
|
||||
#if (__mips_isa_rev >= 2)
|
||||
#define WEBP_USE_MIPS32_R2
|
||||
#if defined(__mips_dspr2) || (defined(__mips_dsp_rev) && __mips_dsp_rev >= 2)
|
||||
#define WEBP_USE_MIPS_DSP_R2
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__mips_msa) && defined(__mips_isa_rev) && (__mips_isa_rev >= 5)
|
||||
#define WEBP_USE_MSA
|
||||
#endif
|
||||
|
||||
#ifndef WEBP_DSP_OMIT_C_CODE
|
||||
#define WEBP_DSP_OMIT_C_CODE 1
|
||||
#endif
|
||||
|
||||
#if (defined(__aarch64__) || defined(__ARM_NEON__)) && WEBP_DSP_OMIT_C_CODE
|
||||
#define WEBP_NEON_OMIT_C_CODE 1
|
||||
#else
|
||||
#define WEBP_NEON_OMIT_C_CODE 0
|
||||
#endif
|
||||
|
||||
#if !(LOCAL_CLANG_PREREQ(3,8) || LOCAL_GCC_PREREQ(4,8) || defined(__aarch64__))
|
||||
#define WEBP_NEON_WORK_AROUND_GCC 1
|
||||
#else
|
||||
#define WEBP_NEON_WORK_AROUND_GCC 0
|
||||
#endif
|
||||
|
||||
// This macro prevents thread_sanitizer from reporting known concurrent writes.
|
||||
#define WEBP_TSAN_IGNORE_FUNCTION
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(thread_sanitizer)
|
||||
#undef WEBP_TSAN_IGNORE_FUNCTION
|
||||
#define WEBP_TSAN_IGNORE_FUNCTION __attribute__((no_sanitize_thread))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(WEBP_USE_THREAD) && !defined(_WIN32)
|
||||
#include <pthread.h> // NOLINT
|
||||
|
||||
#define WEBP_DSP_INIT(func) do { \
|
||||
static volatile VP8CPUInfo func ## _last_cpuinfo_used = \
|
||||
(VP8CPUInfo)&func ## _last_cpuinfo_used; \
|
||||
static pthread_mutex_t func ## _lock = PTHREAD_MUTEX_INITIALIZER; \
|
||||
if (pthread_mutex_lock(&func ## _lock)) break; \
|
||||
if (func ## _last_cpuinfo_used != VP8GetCPUInfo) func(); \
|
||||
func ## _last_cpuinfo_used = VP8GetCPUInfo; \
|
||||
(void)pthread_mutex_unlock(&func ## _lock); \
|
||||
} while (0)
|
||||
#else // !(defined(WEBP_USE_THREAD) && !defined(_WIN32))
|
||||
#define WEBP_DSP_INIT(func) do { \
|
||||
static volatile VP8CPUInfo func ## _last_cpuinfo_used = \
|
||||
(VP8CPUInfo)&func ## _last_cpuinfo_used; \
|
||||
if (func ## _last_cpuinfo_used == VP8GetCPUInfo) break; \
|
||||
func(); \
|
||||
func ## _last_cpuinfo_used = VP8GetCPUInfo; \
|
||||
} while (0)
|
||||
#endif // defined(WEBP_USE_THREAD) && !defined(_WIN32)
|
||||
|
||||
// Defines an Init + helper function that control multiple initialization of
|
||||
// function pointers / tables.
|
||||
/* Usage:
|
||||
WEBP_DSP_INIT_FUNC(InitFunc) {
|
||||
...function body
|
||||
}
|
||||
*/
|
||||
#define WEBP_DSP_INIT_FUNC(name) \
|
||||
static WEBP_TSAN_IGNORE_FUNCTION void name ## _body(void); \
|
||||
WEBP_TSAN_IGNORE_FUNCTION void name(void) { \
|
||||
WEBP_DSP_INIT(name ## _body); \
|
||||
} \
|
||||
static WEBP_TSAN_IGNORE_FUNCTION void name ## _body(void)
|
||||
|
||||
#define WEBP_UBSAN_IGNORE_UNDEF
|
||||
#define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW
|
||||
#if defined(__clang__) && defined(__has_attribute)
|
||||
#if __has_attribute(no_sanitize)
|
||||
// This macro prevents the undefined behavior sanitizer from reporting
|
||||
// failures. This is only meant to silence unaligned loads on platforms that
|
||||
// are known to support them.
|
||||
#undef WEBP_UBSAN_IGNORE_UNDEF
|
||||
#define WEBP_UBSAN_IGNORE_UNDEF \
|
||||
__attribute__((no_sanitize("undefined")))
|
||||
|
||||
// This macro prevents the undefined behavior sanitizer from reporting
|
||||
// failures related to unsigned integer overflows. This is only meant to
|
||||
// silence cases where this well defined behavior is expected.
|
||||
#undef WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW
|
||||
#define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW \
|
||||
__attribute__((no_sanitize("unsigned-integer-overflow")))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// If 'ptr' is NULL, returns NULL. Otherwise returns 'ptr + off'.
|
||||
// Prevents undefined behavior sanitizer nullptr-with-nonzero-offset warning.
|
||||
#if !defined(WEBP_OFFSET_PTR)
|
||||
#define WEBP_OFFSET_PTR(ptr, off) (((ptr) == NULL) ? NULL : ((ptr) + (off)))
|
||||
#endif
|
||||
|
||||
// Regularize the definition of WEBP_SWAP_16BIT_CSP (backward compatibility)
|
||||
#if !defined(WEBP_SWAP_16BIT_CSP)
|
||||
#define WEBP_SWAP_16BIT_CSP 0
|
||||
#endif
|
||||
|
||||
// some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__)
|
||||
#if !defined(WORDS_BIGENDIAN) && \
|
||||
(defined(__BIG_ENDIAN__) || defined(_M_PPC) || \
|
||||
(defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)))
|
||||
#define WORDS_BIGENDIAN
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
kSSE2,
|
||||
kSSE3,
|
||||
kSlowSSSE3, // special feature for slow SSSE3 architectures
|
||||
kSSE4_1,
|
||||
kAVX,
|
||||
kAVX2,
|
||||
kNEON,
|
||||
kMIPS32,
|
||||
kMIPSdspR2,
|
||||
kMSA
|
||||
} CPUFeature;
|
||||
// returns true if the CPU supports the feature.
|
||||
typedef int (*VP8CPUInfo)(CPUFeature feature);
|
||||
WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Init stub generator
|
||||
@@ -514,15 +332,6 @@ extern void WebPConvertARGBToUV_C(const uint32_t* argb, uint8_t* u, uint8_t* v,
|
||||
extern void WebPConvertRGBA32ToUV_C(const uint16_t* rgb,
|
||||
uint8_t* u, uint8_t* v, int width);
|
||||
|
||||
// utilities for accurate RGB->YUV conversion
|
||||
extern uint64_t (*WebPSharpYUVUpdateY)(const uint16_t* src, const uint16_t* ref,
|
||||
uint16_t* dst, int len);
|
||||
extern void (*WebPSharpYUVUpdateRGB)(const int16_t* src, const int16_t* ref,
|
||||
int16_t* dst, int len);
|
||||
extern void (*WebPSharpYUVFilterRow)(const int16_t* A, const int16_t* B,
|
||||
int len,
|
||||
const uint16_t* best_y, uint16_t* out);
|
||||
|
||||
// Must be called before using the above.
|
||||
void WebPInitConvertARGBToYUV(void);
|
||||
|
||||
@@ -578,26 +387,29 @@ extern void (*WebPApplyAlphaMultiply4444)(
|
||||
|
||||
// Dispatch the values from alpha[] plane to the ARGB destination 'dst'.
|
||||
// Returns true if alpha[] plane has non-trivial values different from 0xff.
|
||||
extern int (*WebPDispatchAlpha)(const uint8_t* alpha, int alpha_stride,
|
||||
int width, int height,
|
||||
uint8_t* dst, int dst_stride);
|
||||
extern int (*WebPDispatchAlpha)(const uint8_t* WEBP_RESTRICT alpha,
|
||||
int alpha_stride, int width, int height,
|
||||
uint8_t* WEBP_RESTRICT dst, int dst_stride);
|
||||
|
||||
// Transfer packed 8b alpha[] values to green channel in dst[], zero'ing the
|
||||
// A/R/B values. 'dst_stride' is the stride for dst[] in uint32_t units.
|
||||
extern void (*WebPDispatchAlphaToGreen)(const uint8_t* alpha, int alpha_stride,
|
||||
int width, int height,
|
||||
uint32_t* dst, int dst_stride);
|
||||
extern void (*WebPDispatchAlphaToGreen)(const uint8_t* WEBP_RESTRICT alpha,
|
||||
int alpha_stride, int width, int height,
|
||||
uint32_t* WEBP_RESTRICT dst,
|
||||
int dst_stride);
|
||||
|
||||
// Extract the alpha values from 32b values in argb[] and pack them into alpha[]
|
||||
// (this is the opposite of WebPDispatchAlpha).
|
||||
// Returns true if there's only trivial 0xff alpha values.
|
||||
extern int (*WebPExtractAlpha)(const uint8_t* argb, int argb_stride,
|
||||
int width, int height,
|
||||
uint8_t* alpha, int alpha_stride);
|
||||
extern int (*WebPExtractAlpha)(const uint8_t* WEBP_RESTRICT argb,
|
||||
int argb_stride, int width, int height,
|
||||
uint8_t* WEBP_RESTRICT alpha,
|
||||
int alpha_stride);
|
||||
|
||||
// Extract the green values from 32b values in argb[] and pack them into alpha[]
|
||||
// (this is the opposite of WebPDispatchAlphaToGreen).
|
||||
extern void (*WebPExtractGreen)(const uint32_t* argb, uint8_t* alpha, int size);
|
||||
extern void (*WebPExtractGreen)(const uint32_t* WEBP_RESTRICT argb,
|
||||
uint8_t* WEBP_RESTRICT alpha, int size);
|
||||
|
||||
// Pre-Multiply operation transforms x into x * A / 255 (where x=Y,R,G or B).
|
||||
// Un-Multiply operation transforms x into x * 255 / A.
|
||||
@@ -610,29 +422,35 @@ void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows,
|
||||
int inverse);
|
||||
|
||||
// Same for a row of single values, with side alpha values.
|
||||
extern void (*WebPMultRow)(uint8_t* const ptr, const uint8_t* const alpha,
|
||||
extern void (*WebPMultRow)(uint8_t* WEBP_RESTRICT const ptr,
|
||||
const uint8_t* WEBP_RESTRICT const alpha,
|
||||
int width, int inverse);
|
||||
|
||||
// Same a WebPMultRow(), but for several 'num_rows' rows.
|
||||
void WebPMultRows(uint8_t* ptr, int stride,
|
||||
const uint8_t* alpha, int alpha_stride,
|
||||
void WebPMultRows(uint8_t* WEBP_RESTRICT ptr, int stride,
|
||||
const uint8_t* WEBP_RESTRICT alpha, int alpha_stride,
|
||||
int width, int num_rows, int inverse);
|
||||
|
||||
// Plain-C versions, used as fallback by some implementations.
|
||||
void WebPMultRow_C(uint8_t* const ptr, const uint8_t* const alpha,
|
||||
void WebPMultRow_C(uint8_t* WEBP_RESTRICT const ptr,
|
||||
const uint8_t* WEBP_RESTRICT const alpha,
|
||||
int width, int inverse);
|
||||
void WebPMultARGBRow_C(uint32_t* const ptr, int width, int inverse);
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
// ARGB packing function: a/r/g/b input is rgba or bgra order.
|
||||
extern void (*WebPPackARGB)(const uint8_t* a, const uint8_t* r,
|
||||
const uint8_t* g, const uint8_t* b, int len,
|
||||
uint32_t* out);
|
||||
extern void (*WebPPackARGB)(const uint8_t* WEBP_RESTRICT a,
|
||||
const uint8_t* WEBP_RESTRICT r,
|
||||
const uint8_t* WEBP_RESTRICT g,
|
||||
const uint8_t* WEBP_RESTRICT b,
|
||||
int len, uint32_t* WEBP_RESTRICT out);
|
||||
#endif
|
||||
|
||||
// RGB packing function. 'step' can be 3 or 4. r/g/b input is rgb or bgr order.
|
||||
extern void (*WebPPackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b,
|
||||
int len, int step, uint32_t* out);
|
||||
extern void (*WebPPackRGB)(const uint8_t* WEBP_RESTRICT r,
|
||||
const uint8_t* WEBP_RESTRICT g,
|
||||
const uint8_t* WEBP_RESTRICT b,
|
||||
int len, int step, uint32_t* WEBP_RESTRICT out);
|
||||
|
||||
// This function returns true if src[i] contains a value different from 0xff.
|
||||
extern int (*WebPHasAlpha8b)(const uint8_t* src, int length);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user