mirror of
https://github.com/opencv/opencv.git
synced 2026-07-23 04:13:04 +04:00
Compare commits
3852 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 725e440d27 | |||
| 121034876d | |||
| 9627ab9462 | |||
| 499035c6ea | |||
| 71765858dc | |||
| 9a2a34f94e | |||
| 838c34eee1 | |||
| 253429d3f1 | |||
| 38f7cd7173 | |||
| eab7faf536 | |||
| 83391ac59d | |||
| a8a93a57e7 | |||
| f637629c5a | |||
| 93aa94e71e | |||
| 86b46a27cf | |||
| 1bc3077890 | |||
| fc27a343e9 | |||
| 692d6168b3 | |||
| de9787a6ac | |||
| d2bf2be8e6 | |||
| b7292bc899 | |||
| dbd4a0e5e6 | |||
| b361209d52 | |||
| 4abe6dc48d | |||
| 26f36f2ff9 | |||
| b42c11de82 | |||
| a494c75bfe | |||
| bc8c912c7a | |||
| 5247237bf0 | |||
| 8e6aae0d7a | |||
| 8681686d8f | |||
| 9012e6dd9b | |||
| 139bd30247 | |||
| 4930516652 | |||
| ad568edd7f | |||
| 62b3a20da5 | |||
| 1f41d06f9a | |||
| 1339c7f30c | |||
| 734fb18c4d | |||
| 71c6339af0 | |||
| 34a0897f90 | |||
| a32100d9ba | |||
| b5400902a7 | |||
| d35fbe6bfc | |||
| 645930387c | |||
| 44dfe62af0 | |||
| 4acb267cf4 | |||
| 8676d19dc3 | |||
| 6b4f3e5fab | |||
| dafc4e456d | |||
| 2a884cc179 | |||
| b774753922 | |||
| 5e03305da5 | |||
| 3ff1ec99ac | |||
| bc8d494617 | |||
| 35e771daab | |||
| 1ab259df9a | |||
| 0bd54a60e9 | |||
| 63b6b24cd0 | |||
| 8e49560709 | |||
| b8f57c9a96 | |||
| c6a15e1835 | |||
| 05f4416ba0 | |||
| 91ac790249 | |||
| 3cfe737581 | |||
| a2b3acfc6e | |||
| f4b23de9dd | |||
| a08c98cdfb | |||
| 279e2be56b | |||
| cdbb893b27 | |||
| 41d172f22d | |||
| 3f7ec99166 | |||
| 1102b7eff8 | |||
| da43778c1f | |||
| 9aa5ab7557 | |||
| d44c58a1fb | |||
| 7463e9b8bb | |||
| 9f201a8ebe | |||
| 91998d6424 | |||
| 420db56ffd | |||
| 07ed5e5346 | |||
| 4824ce300f | |||
| 5855eba9f3 | |||
| cdaf4c7321 | |||
| eace6adb6d | |||
| 6db9fcbc30 | |||
| b4b35cff15 | |||
| 47fb79bd8c | |||
| 6b50410336 | |||
| 6e3700593f | |||
| 6a8c5a1d27 | |||
| 50da209dc4 | |||
| b7b08fa0c3 | |||
| b1288dad40 | |||
| ac6fb17784 | |||
| 3f22f4727c | |||
| 0153e796cc | |||
| 4891818114 | |||
| db4a557187 | |||
| 04c3a534af | |||
| a32143003d | |||
| 8bd17163c7 | |||
| 81aaca8c04 | |||
| 189e1b228d | |||
| 52709c7771 | |||
| 7dbb125a34 | |||
| aff375808d | |||
| 3f5f09e730 | |||
| 332ff4bf1c | |||
| 253a4c113e | |||
| 1788c93aea | |||
| c2ecbc76ce | |||
| 4203c903f8 | |||
| 727feda935 | |||
| 39087fecdc | |||
| c725771e11 | |||
| 103212f209 | |||
| be326ff752 | |||
| ebaee3ea21 | |||
| 423bc515e5 | |||
| 941d89e06d | |||
| 281b790618 | |||
| f5d7c5f103 | |||
| 93c4bca04d | |||
| 726f0adde3 | |||
| 24d7eb0ca5 | |||
| 8ba44e7d55 | |||
| 49f539cb46 | |||
| 0a650b573b | |||
| 7e3c53b9d3 | |||
| ab912329b6 | |||
| 6ad216576d | |||
| c5a4df30c6 | |||
| cb8f1dca3b | |||
| d1ff87d94d | |||
| b16f76eede | |||
| 4792837f2e | |||
| 416830fb59 | |||
| 07b1bc2e88 | |||
| d16b3b2487 | |||
| 74d0b4cc78 | |||
| 8832a9dbd5 | |||
| c55613ccf7 | |||
| 6c399aa62a | |||
| 5862b50217 | |||
| 5696629b13 | |||
| 3a15152be5 | |||
| f1055a7e91 | |||
| d4dc6b509b | |||
| 1192779d05 | |||
| 71a1150c95 | |||
| e14ca39fd7 | |||
| 421ba8730a | |||
| 0d56524b72 | |||
| 9fded9ca53 | |||
| 441624a5fb | |||
| 25ac77e010 | |||
| 77d887898d | |||
| a32f2cd24a | |||
| eb68de9268 | |||
| ed3810f7a5 | |||
| 1c3e287d32 | |||
| 5044af69d1 | |||
| bc6544c0bc | |||
| a462f49b99 | |||
| 7622fbf895 | |||
| 3f371fe2dd | |||
| 6ca205a029 | |||
| aba2167d9c | |||
| 5db4f1f7df | |||
| a0a8d2160d | |||
| 2a5da50902 | |||
| 51758b2dd6 | |||
| 90b144cf0a | |||
| 529bd0425e | |||
| 6c36cd5d6e | |||
| c102720af4 | |||
| c63a6c472d | |||
| 5b3f721efa | |||
| e5bea2bde4 | |||
| e9d64e0a8c | |||
| f0df78b7e7 | |||
| e93d976d00 | |||
| 64aad34cb4 | |||
| 7592d58f0c | |||
| 08906ddd4b | |||
| d21761c0fd | |||
| 277ead95d9 | |||
| 5d14cc68b7 | |||
| ce80e0dc57 | |||
| 4c74e6d89d | |||
| 45d04175d4 | |||
| 687c9b7b29 | |||
| d9f66413ee | |||
| 1b1bbe4262 | |||
| 3edf7c25d4 | |||
| 54531f8e3b | |||
| b5a68f235a | |||
| 5bf64e7dfe | |||
| 51b897b672 | |||
| da4ac6b7ef | |||
| 1ba0984203 | |||
| f5e852cdf0 | |||
| ef2677b0a6 | |||
| 2aad039b4f | |||
| 8a90948a1c | |||
| 63bff33e85 | |||
| 21133a2091 | |||
| 39f995e319 | |||
| 91624e87ab | |||
| 11d492b0b9 | |||
| 17f2b56291 | |||
| d1d8ac57f3 | |||
| b418eb112c | |||
| ee9137f176 | |||
| 903bf0147e | |||
| 540aa13300 | |||
| bbbf1168dc | |||
| 18fbb72f7d | |||
| 0b5fd4f6bb | |||
| 87360c2ae5 | |||
| 17b98dd005 | |||
| 1293e99ad8 | |||
| 028d4d83d3 | |||
| be670e168a | |||
| b619477be9 | |||
| 778faddbd8 | |||
| f644634aa6 | |||
| 547f4c2c5a | |||
| 5462a6be6e | |||
| a60496f9df | |||
| acd8d3a617 | |||
| 0c92305a4b | |||
| 1ecfff0fa0 | |||
| d933034ad4 | |||
| a6fadfe1c2 | |||
| aae317c017 | |||
| 37683aca56 | |||
| 22f8fb4d5c | |||
| 7d1589d407 | |||
| b35018d955 | |||
| c29a3aa0a0 | |||
| eae5fd81e5 | |||
| 23edec83fb | |||
| e4cd430710 | |||
| 35b2cff295 | |||
| 8e5f37f87c | |||
| cee8c86b6e | |||
| c0a84dcc85 | |||
| e80b443cd9 | |||
| e309a06b47 | |||
| 86dad3aebe | |||
| 5a9fe9dedb | |||
| c7d24c0fb3 | |||
| 5d292826b2 | |||
| f378f02954 | |||
| ba575fd4ad | |||
| dd14cf6a9c | |||
| 2c81cb2f76 | |||
| 6eb34716b8 | |||
| 871bc98933 | |||
| ec7fc5adca | |||
| c0c3f4cbac | |||
| 02143cd0e2 | |||
| 1c5dcbcac8 | |||
| d24d8f2abe | |||
| 584ea43b2f | |||
| 292f62c5cc | |||
| 762481411d | |||
| d816442e4d | |||
| ea5ca16036 | |||
| 2991717191 | |||
| 0fa43e3aac | |||
| 085fb78e85 | |||
| a565aa6db9 | |||
| 2763f988da | |||
| 82ac7ea236 | |||
| f89dee4f3e | |||
| 70779d4e66 | |||
| c0ecf08ca0 | |||
| 35f43cc429 | |||
| cfafd0493c | |||
| 9119692bb8 | |||
| 8b0aa6a64d | |||
| ec26541771 | |||
| 1c825dd509 | |||
| d9eff7daeb | |||
| 3419e64dcf | |||
| 1e2ceca4df | |||
| 347246901e | |||
| 68bd156a71 | |||
| 9821fae59d | |||
| 43b2bb2c25 | |||
| a3ebafbdeb | |||
| 5cd07006f6 | |||
| 3d350a002e | |||
| f18b8cd569 | |||
| 5389d9e0d4 | |||
| 07c795408d | |||
| 5f50e7bafe | |||
| e92716a1b6 | |||
| bbcc1752b1 | |||
| 40ae06091d | |||
| d480e2e51b | |||
| 839321642e | |||
| 9f88a65873 | |||
| b77330bafc | |||
| 4a4b2a0ce6 | |||
| 0ae126d3b8 | |||
| af9332dfaf | |||
| 4103567776 | |||
| 8f0edf6a1c | |||
| ab5279f4ad | |||
| 1113c9ab10 | |||
| bf5d7c0c10 | |||
| fef8d4c990 | |||
| 5a0c85b3ef | |||
| 9fd877acc9 | |||
| ed3b56d763 | |||
| 2f79b1b087 | |||
| 7208f63221 | |||
| 572d4f4491 | |||
| 0cd4396180 | |||
| aafb7567c1 | |||
| 468431cd8f | |||
| cf5db9b94f | |||
| 589b6c15f0 | |||
| 2af0813634 | |||
| 15d2a5faf8 | |||
| b1d28d5b4a | |||
| a6fbd8287c | |||
| b0b77b3047 | |||
| 96844b0ca5 | |||
| 7fc6146973 | |||
| 6cf0910842 | |||
| 692c536ac5 | |||
| 1646a21197 | |||
| 4557971481 | |||
| 8baf46c0a8 | |||
| 0c0083ba72 | |||
| d18362c726 | |||
| b403d37267 | |||
| 2d189e24ee | |||
| c8c29b0f1a | |||
| 784dd55d88 | |||
| adb916ce82 | |||
| 15cfafb360 | |||
| d43cb4fe7c | |||
| 38c9c20a35 | |||
| 935acc500f | |||
| c189f31f23 | |||
| cbf43a54fb | |||
| 2918071a3e | |||
| 1829eba584 | |||
| 3a64607d94 | |||
| 64649a1207 | |||
| 4dfbbabf8b | |||
| 72f1ce6550 | |||
| c34c4b50d0 | |||
| 4521d66103 | |||
| 0c238c9e72 | |||
| 3d9f27b877 | |||
| 50e66a2e53 | |||
| a682f02f59 | |||
| df24bd295d | |||
| 04ebedb6f0 | |||
| 71ae1cac5f | |||
| e0b21dccf1 | |||
| bfeeb0ad70 | |||
| 2273af0166 | |||
| 604192337f | |||
| ccfc34b13f | |||
| 3f4abcb228 | |||
| f2ccce23f3 | |||
| 7d96ef2671 | |||
| 2882725927 | |||
| 062cee2933 | |||
| fcf9f117b0 | |||
| 0f1cb5ad7c | |||
| 0ab4872032 | |||
| a6274647a4 | |||
| 65f71ce2eb | |||
| 6aefb8e86f | |||
| 4aef9b1c93 | |||
| 0ac67ee8d9 | |||
| 66b3155a48 | |||
| b3adffe437 | |||
| ec92f3fefa | |||
| fb85a83108 | |||
| 41ef2bfb16 | |||
| 1ae801554d | |||
| 65998d8076 | |||
| 45a7b71cac | |||
| e1e9261450 | |||
| 819e5b19b3 | |||
| a3cb2020bc | |||
| a6017ac550 | |||
| 7faeb82585 | |||
| 48e50a7674 | |||
| dc9d775f88 | |||
| 66cbb7b911 | |||
| 9ca3a3139a | |||
| 6fb465cb4e | |||
| 8ae03fcd6e | |||
| 122250b554 | |||
| eb8883160d | |||
| 8af4fe9ed3 | |||
| adb5971494 | |||
| 377fdf5ae5 | |||
| e1272d73fe | |||
| e3e61078a5 | |||
| 13823f117b | |||
| 2e15582799 | |||
| 65bdb3a544 | |||
| ac91c45b0f | |||
| 6481cfd048 | |||
| 0f6b01a531 | |||
| 364b3f181d | |||
| 04849f26b2 | |||
| 26a7647e0e | |||
| 8eb036fb3c | |||
| fce8349c99 | |||
| 5ea912e778 | |||
| c2c8da2517 | |||
| 1be40554af | |||
| d717de5719 | |||
| bcc19a622d | |||
| fb3fc5322c | |||
| 2eff70fbf4 | |||
| d885242b61 | |||
| 46d988e2cb | |||
| 7a5122121b | |||
| 7fc14504b1 | |||
| cb1a1e9a51 | |||
| 619e038de9 | |||
| 4154bd0667 | |||
| 5408949951 | |||
| 866191478f | |||
| c9060b053d | |||
| 9dc844a6e1 | |||
| e2a9cff3dc | |||
| c3b83b8354 | |||
| e24382691f | |||
| 9074b3e980 | |||
| 65d66a05dd | |||
| 7de7891c4d | |||
| 4bec43cf79 | |||
| 6cc0107693 | |||
| ca7f964104 | |||
| b26fc6f31b | |||
| 5fa624f35e | |||
| 7955469f7c | |||
| ce62fc8371 | |||
| 2e40b7f113 | |||
| 2ac62bccec | |||
| 22eb91a7e0 | |||
| 448e3a7e58 | |||
| bf54a370e5 | |||
| 337452b4c0 | |||
| 5bb098ba5d | |||
| 4159842195 | |||
| b69b1eae8f | |||
| c4a6e1fd4d | |||
| 3456d28cc2 | |||
| f376bfe95d | |||
| a72074b33f | |||
| 5185544864 | |||
| 7834a465d5 | |||
| 1f0bfc8d83 | |||
| a122f0f248 | |||
| a31fb88fd0 | |||
| 70fb1cd603 | |||
| d2c48b898c | |||
| 2d837efba7 | |||
| 1852d0b9b8 | |||
| 837e41f9a7 | |||
| 1fd45a1b85 | |||
| 2cd7e17b65 | |||
| 8eb4f72531 | |||
| 2619099fe5 | |||
| 2959286eb5 | |||
| a4b191a7e0 | |||
| 3929e26276 | |||
| a1d5565e65 | |||
| 9638e34ab0 | |||
| ed9d4c0b2b | |||
| bb64db98d8 | |||
| 88115811a9 | |||
| 67fa8a2f47 | |||
| 560eba91e5 | |||
| 42561e1233 | |||
| 7e2c8cc9f4 | |||
| eea05f5078 | |||
| 7eaec9dd22 | |||
| e1305e8d05 | |||
| 2dd3408caa | |||
| 3651831e7e | |||
| a1d752bfc0 | |||
| d10832074e | |||
| a001ab3a44 | |||
| ef570e4e13 | |||
| 7831aae5dd | |||
| 1336da9450 | |||
| 6432f02996 | |||
| 1fb8d60fd2 | |||
| 5e92bf8e41 | |||
| 7e5d012f75 | |||
| 925ff6241f | |||
| e14c3cff85 | |||
| 984e42b0bc | |||
| 0702685e7e | |||
| 7deb8f568f | |||
| d8434e6875 | |||
| b9a1039566 | |||
| 03130548ea | |||
| 11c5a6bb4d | |||
| 8dc332721f | |||
| 189f647264 | |||
| 56baf4ed87 | |||
| 7ffb103758 | |||
| 9fcf015214 | |||
| 27bfab4e6e | |||
| ffccfa2ee9 | |||
| d3dcef4b8b | |||
| 3cd36ebc7b | |||
| 2ebdc04787 | |||
| cc8add9f66 | |||
| c2c539e3cc | |||
| 0cdff46725 | |||
| d0d115321d | |||
| 99683e958a | |||
| f572ae3474 | |||
| e65ad44b32 | |||
| 3d8614cb47 | |||
| d09cc0f30c | |||
| 80c82e10aa | |||
| 2fb652ce09 | |||
| 1bab920cf5 | |||
| bb71cb200e | |||
| 48afe1586a | |||
| e7e814fa8c | |||
| 496eed950f | |||
| f0d29cd33c | |||
| 75bb6aa9a1 | |||
| 44b2f9637a | |||
| 0643165519 | |||
| cde18648dc | |||
| 04e01e2b31 | |||
| 348b7383f9 | |||
| b2b7193374 | |||
| 47a59d72c9 | |||
| 163770f99a | |||
| 4c1e064a2b | |||
| 88555948d0 | |||
| 1893b37e23 | |||
| c3cbd302cb | |||
| 2ffa7ac0da | |||
| 885a446b10 | |||
| 8bfe620fcc | |||
| 129319b0bc | |||
| 7ce83f2a95 | |||
| 4b05765174 | |||
| 3390da6beb | |||
| 50707a2741 | |||
| 0614c40b42 | |||
| facd07a732 | |||
| 26ac81df3e | |||
| 1ec10ca565 | |||
| 26a39c733b | |||
| 15f0e2e7cb | |||
| d4640f4647 | |||
| 4c9364a803 | |||
| e951edeed3 | |||
| e7a787aa41 | |||
| 500e24d6cd | |||
| 759cbd7486 | |||
| 57545653b1 | |||
| 3c5377ca1b | |||
| a89868928b | |||
| 5bf3991f55 | |||
| 08696d92ea | |||
| 2c2466fb25 | |||
| fc3e393516 | |||
| ebaf8cc06c | |||
| 0862d69a6e | |||
| b8106e4ba4 | |||
| 6ce2f1316f | |||
| 294348939b | |||
| e2db95184f | |||
| f8597fc150 | |||
| 85b0b0cd77 | |||
| 2bd72af2ef | |||
| f729202272 | |||
| 47f30a04d2 | |||
| a42b35598e | |||
| db53f4533e | |||
| 71e33265f5 | |||
| a016f6022c | |||
| 3e3b53f815 | |||
| e2bfe0ce76 | |||
| 98c33c605d | |||
| b3269b08a1 | |||
| e59cff47d4 | |||
| 47912431e6 | |||
| 0ef803950b | |||
| 3c23a44786 | |||
| 701d0d9905 | |||
| d4e1d89901 | |||
| 14aa9eaadd | |||
| 1feabf4275 | |||
| 65c173f2a3 | |||
| 697acf7f6a | |||
| ed69bcae2d | |||
| 728545468c | |||
| 33b1e76e48 | |||
| 1d134025a5 | |||
| 96a9cfab36 | |||
| c9e10e1d0b | |||
| 60846b2b7a | |||
| 6fe7886e2b | |||
| 199c2d2fd0 | |||
| bd54ba911d | |||
| a9354fc743 | |||
| b4b69ae484 | |||
| 1c7b71bf9e | |||
| 1377f0147e | |||
| d2b1e38207 | |||
| 9ffb67478f | |||
| 1dee848d3e | |||
| afe1c70f2d | |||
| 1b8fba8e26 | |||
| 45fbb67aba | |||
| 914005174f | |||
| 2a82467a6f | |||
| a233232b7d | |||
| ed4bf13960 | |||
| 3135063100 | |||
| 87ef6a9cc1 | |||
| ff31f90b7e | |||
| 2b2ba534e2 | |||
| 3635b3dee7 | |||
| fa613e393f | |||
| 7d3dbcb027 | |||
| db70676933 | |||
| b3b235ebc0 | |||
| 70492c2127 | |||
| f562264674 | |||
| 0a88f84847 | |||
| 139c443770 | |||
| a630ad73cb | |||
| 366e8217c2 | |||
| 01226cb8ac | |||
| 3891b72f33 | |||
| a80fcacd90 | |||
| c54ccaac31 | |||
| 79731cb0ff | |||
| 16b5fd4bf2 | |||
| fb9463c55f | |||
| 2920a8e0ec | |||
| 6a4c3b61e6 | |||
| 6360c3bf46 | |||
| e313603aac | |||
| 0f3de805f4 | |||
| 3bf22d0024 | |||
| 66567933d7 | |||
| 56e19e3494 | |||
| d2f5a10f5d | |||
| 32bb4fa950 | |||
| 8ae06b4648 | |||
| 652396678d | |||
| 59b870a87a | |||
| 0f067fd0a6 | |||
| b91f173680 | |||
| a311d1bdc0 | |||
| eb7add1828 | |||
| b152b8cbcd | |||
| 2336b0706d | |||
| 300b57dd70 | |||
| 0769bf416f | |||
| 90f2e1f8b5 | |||
| 2a4926f417 | |||
| 5e1c9099e8 | |||
| 397e9bc8d6 | |||
| 2366f2cb2e | |||
| 35f1a90df7 | |||
| 9faefa0c96 | |||
| b5adffd5c2 | |||
| 82010bf5c1 | |||
| 6234f01a6d | |||
| 44c2519d75 | |||
| ef94275eb6 | |||
| a6ca48a1c2 | |||
| 24a66a44bf | |||
| 2411b825b4 | |||
| dd7b9000ad | |||
| f1328c7395 | |||
| 9d06e58c3c | |||
| 711b136191 | |||
| a04f9e7a59 | |||
| db5b22e895 | |||
| 0d52c37e11 | |||
| 734e309b3e | |||
| 3efc645975 | |||
| 572812217b | |||
| 008507327c | |||
| f4a6c3e7ea | |||
| ff41fbc5c1 | |||
| cac864192c | |||
| b19683eb41 | |||
| 7a46d7efde | |||
| d09bd6f862 | |||
| 7676be5570 | |||
| ed9524e125 | |||
| 533bb035cf | |||
| dda2e9374b | |||
| 14754deb21 | |||
| b0dc474160 | |||
| adf89bbb33 | |||
| c103b63fe1 | |||
| a3d0882317 | |||
| 583bd1a6e2 | |||
| 53eda42da7 | |||
| c26c4a61c6 | |||
| ea2527c2d1 | |||
| 65fcf22670 | |||
| d0572538ff | |||
| 3577265508 | |||
| f28e191d70 | |||
| 38b6c44b4c | |||
| 1a24e316d5 | |||
| 9da9e8244b | |||
| 8d51ef0f35 | |||
| 9cfae823a7 | |||
| d6151eae23 | |||
| 4a0a3281c6 | |||
| 1230075011 | |||
| 7459954377 | |||
| cf38098ba8 | |||
| 8ca394efaf | |||
| f9c7931800 | |||
| 24547f40ff | |||
| 72debee125 | |||
| a3d6994afa | |||
| 08c270f65a | |||
| e585453c2e | |||
| 86f4524010 | |||
| 6d098cc230 | |||
| 434c96e625 | |||
| d6e9616256 | |||
| e9187ae38c | |||
| 978dc76653 | |||
| b409fd32ac | |||
| a2ad997e97 | |||
| e9428726ca | |||
| 400906b433 | |||
| 50d7c61c01 | |||
| d9bf522b27 | |||
| 93dc0679ec | |||
| 1ddc51cfd1 | |||
| 50bf0e10f5 | |||
| d1ccb7e47f | |||
| 6a22c5b2b5 | |||
| 7e845a3b87 | |||
| ea1c970190 | |||
| 3d207ccf11 | |||
| aaf7f5ae02 | |||
| 50e8ad285b | |||
| bb5462e327 | |||
| df2e7fa6eb | |||
| 11f36bdf9a | |||
| bc0d4585b3 | |||
| 70917f291c | |||
| 9f6f0c7424 | |||
| 4722a8df3c | |||
| 7be8a71c60 | |||
| ce859edba8 | |||
| 90820cd044 | |||
| c929f1b62f | |||
| ff88132620 | |||
| 89f8d4ae12 | |||
| 3f4ffe7844 | |||
| ed567a2dd1 | |||
| 22a00036e2 | |||
| 2aac0a5a26 | |||
| 07ad6a437e | |||
| d9a444ca1a | |||
| 766f58ed7e | |||
| 1099b4c881 | |||
| 7c0f49fc36 | |||
| 761e796201 | |||
| 8d0fbc6a1e | |||
| affcea8822 | |||
| 53f0be00a9 | |||
| 602caa9cd6 | |||
| f35ec8c955 | |||
| 1316491e50 | |||
| 2cc4309bf8 | |||
| 612d43f284 | |||
| 56824d1769 | |||
| 2238ac7d59 | |||
| 2b5b192cd7 | |||
| 64e1d23cba | |||
| 40d2904f3d | |||
| 9712cc479b | |||
| 0ef1fb0b67 | |||
| 2b67bc448d | |||
| a3f81b79ed | |||
| 8d0dae4cec | |||
| dda96264df | |||
| 4af8e5c5c4 | |||
| eff5605be5 | |||
| 2b53ab23c0 | |||
| 2010de9104 | |||
| 280a99b3b6 | |||
| 646025589b | |||
| 4502003e61 | |||
| 07abb6240e | |||
| dea0815199 | |||
| e4ed2d2e42 | |||
| c8228e5789 | |||
| 667e5e4f89 | |||
| ada703a73a | |||
| 2b8094f915 | |||
| 9e1e960116 | |||
| 82ae9ef541 | |||
| 1b07274e34 | |||
| 15ac54d5d6 | |||
| 1cdd8510fd | |||
| 039f3d01a0 | |||
| f63feea05e | |||
| fbac38d98b | |||
| ca2ab3387f | |||
| 64ded50bbf | |||
| d44ac61033 | |||
| 18ada77d8a | |||
| 6d0f1275c2 | |||
| a848eccfc6 | |||
| 2402fa4824 | |||
| 2bf4135afc | |||
| c677f132cd | |||
| ec4015d73c | |||
| 8c42dbf71c | |||
| 4ca679180d | |||
| 64da959619 | |||
| 88123e2512 | |||
| 87e98e8788 | |||
| 767857c516 | |||
| 2b60166e5c | |||
| 2e41db39f5 | |||
| a55fa8389e | |||
| d23142027f | |||
| 438fe3f9db | |||
| 5cc154147f | |||
| 9cd5a0a1e6 | |||
| 2958142e31 | |||
| 27c15bed60 | |||
| 2985739b8c | |||
| 2465d93330 | |||
| 556d211136 | |||
| 0ee2a58cdc | |||
| 7daf84fb44 | |||
| 9aff01c9a9 | |||
| a2b84e9897 | |||
| 66f3c2673c | |||
| 554d08c3a1 | |||
| 3a595ea5c4 | |||
| 03c9648f2e | |||
| e3a55af336 | |||
| be4a432bea | |||
| 0d32a24cba | |||
| e36948cfbc | |||
| 9aa647068b | |||
| 092030c1ca | |||
| 0bd261ded4 | |||
| 7ed557497d | |||
| d793ec2ffe | |||
| 271f7df343 | |||
| 08d44f588f | |||
| 84b4a5a495 | |||
| b2e20a82ba | |||
| 1b3a06a02a | |||
| 91a5e75151 | |||
| 4754b0e253 | |||
| 84b517f5a0 | |||
| 8ac88cf069 | |||
| 13a995cc1d | |||
| a93fb52632 | |||
| 4d927e73f1 | |||
| 38228709c8 | |||
| 38788a3161 | |||
| 46b6973c05 | |||
| af2b7708a8 | |||
| a233982931 | |||
| ed1439fbc6 | |||
| b379b67a32 | |||
| f3945fbddb | |||
| 8b44ee2ce1 | |||
| 7b582b71ba | |||
| 4e8c507276 | |||
| 9390c56831 | |||
| abebbf04b1 | |||
| 5e434073d4 | |||
| 3e4a566e46 | |||
| 6f5cf8c15f | |||
| b687bc807a | |||
| 5440fd6cb4 | |||
| b060151625 | |||
| be38d4ea93 | |||
| 56f21c4fd5 | |||
| 386df457a9 | |||
| e4abf6e723 | |||
| 1339ebaa84 | |||
| c9b90884da | |||
| 9b2b2c88df | |||
| e5bdab0355 | |||
| 4d46958c82 | |||
| 9dd8e4df7f | |||
| d98e07c3d3 | |||
| 78bc11465b | |||
| 8e8e4bbabc | |||
| 90671233c6 | |||
| 12bae51384 | |||
| 7b848e215f | |||
| 21872e2fb0 | |||
| 2a218b96c4 | |||
| e76cda6923 | |||
| 9d16612a9b | |||
| 63c865ace6 | |||
| 0a62de0d4f | |||
| 593996216f | |||
| 4eae23a2cc | |||
| f3699b5ac8 | |||
| 9ce0e51305 | |||
| 4c79318694 | |||
| f7ac724c5d | |||
| ee9fe1239a | |||
| b6b5c27cec | |||
| 632e07b749 | |||
| 48cd2d190f | |||
| 685797f403 | |||
| ef6f421f89 | |||
| e0ffd3e8a5 | |||
| 0d16b5fc38 | |||
| ac8a27cba9 | |||
| e5f2a8ebf2 | |||
| 54733eba6f | |||
| 93353aea70 | |||
| e16cb8b4a2 | |||
| 5bf3c1df24 | |||
| 419918076e | |||
| fb768c420d | |||
| eb067fee55 | |||
| 6390b50d6e | |||
| 5d8134ed32 | |||
| 852904e1a4 | |||
| a120adde63 | |||
| a80af177b6 | |||
| 8db7d435b9 | |||
| 901e0ddfe4 | |||
| ecb30409f6 | |||
| 44c2c77548 | |||
| 5be5efdacf | |||
| 057c3da82a | |||
| 8fa429caef | |||
| 87f526d82f | |||
| 1ae2320e09 | |||
| 54693cf7b1 | |||
| a082375d57 | |||
| 9c7adb7248 | |||
| ccebbbc0ac | |||
| ebb6915e58 | |||
| 5cc27fd3b5 | |||
| a332509e02 | |||
| 375fe81311 | |||
| d354ad1c34 | |||
| 119d8b3aca | |||
| cd9edba26f | |||
| 8f1c502d2b | |||
| 92312fbc0c | |||
| 2efcaa9e8e | |||
| aa53541235 | |||
| b863c25d21 | |||
| f77c3574af | |||
| f5105bac65 | |||
| 5a86592e93 | |||
| 2c83cfc14c | |||
| 863546e125 | |||
| 9198e30688 | |||
| 1890157faa | |||
| 0898f372b1 | |||
| b9e5256cf9 | |||
| 6b6d89b911 | |||
| d3e0193c8a | |||
| 31881209d6 | |||
| 5c7e893393 | |||
| 3c814ebf87 | |||
| 5cf1dca36e | |||
| 12338c1dc4 | |||
| 5b23752205 | |||
| 4e53f301d8 | |||
| 2b7803dbac | |||
| 446a278f3d | |||
| 0047d3f81a | |||
| 4e1f17d65b | |||
| f9b1dbe2ac | |||
| a251474144 | |||
| 8d88bb06b2 | |||
| 9f2ff3ed22 | |||
| 45cbf70265 | |||
| 59e16b88ae | |||
| 33f219dfe6 | |||
| 44db2eea70 | |||
| 12ab54648c | |||
| 19926e2979 | |||
| 1620a1e014 | |||
| 888546b6f5 | |||
| 3215db26aa | |||
| 76aff84788 | |||
| fc28ba3156 | |||
| effce0573b | |||
| e8db363431 | |||
| 9603b6877d | |||
| d5ecb5ff5a | |||
| dae73938e8 | |||
| 619b6dfae3 | |||
| 8f9c36b730 | |||
| 3eeec4faae | |||
| 972a4b95b6 | |||
| ffee1a4126 | |||
| 96e23c2ff6 | |||
| 08356007c9 | |||
| 5064b6f747 | |||
| 57d3002ee1 | |||
| a00a0dbfcd | |||
| b41d2c5c14 | |||
| 1da48beeec | |||
| b57ff73086 | |||
| 67978b5746 | |||
| 062f305d1a | |||
| 1f70d4e2a5 | |||
| aa5bc20c83 | |||
| 09af10f635 | |||
| 4d7953aa56 | |||
| 46e1560678 | |||
| 4d0148b417 | |||
| 1605d1d24d | |||
| 5190043e56 | |||
| f66a2ffa1e | |||
| d1e76a34a0 | |||
| 5b3d5f9f3c | |||
| 415a42f327 | |||
| 09f6e55338 | |||
| a351e05a17 | |||
| d37bcbdc92 | |||
| 437af37b13 | |||
| c62367612d | |||
| a92cba8484 | |||
| 5f7d922b10 | |||
| dc29632d4e | |||
| f4a7754cc0 | |||
| 6811d3d80b | |||
| 245f6273bd | |||
| 870c8d3c4e | |||
| d573472a86 | |||
| 441b6dbda0 | |||
| a7e6a1059c | |||
| 85719a0a5d | |||
| b5b52afd35 | |||
| dc35633aa4 | |||
| 9e3ba487fa | |||
| aee8425b68 | |||
| 94229bb262 | |||
| 1f6444fbea | |||
| 439ef6447d | |||
| 9cab808c5d | |||
| d41fcf7345 | |||
| ac51ba38f9 | |||
| ef85b24a78 | |||
| d88730685e | |||
| 16661847a7 | |||
| 7f782a1a24 | |||
| 9188ce68aa | |||
| 2b79a6ff8f | |||
| 70b0274c8e | |||
| 83ce1de8e7 | |||
| b1d484f827 | |||
| 123519165d | |||
| 30ff9c6775 | |||
| 906f5f7e96 | |||
| 9238316cf1 | |||
| 5e89b9a455 | |||
| e3a4ff33d2 | |||
| 5d9ea394ba | |||
| abb5c9fd92 | |||
| 266835cd2e | |||
| 92af03579c | |||
| 2e20f2b89f | |||
| e67593673f | |||
| d1b533d399 | |||
| 2647902fee | |||
| 574320ec3f | |||
| 3f2377017c | |||
| 2b5bb02817 | |||
| 302d14adef | |||
| b796ededae | |||
| f811ba8777 | |||
| eb7b45d26b | |||
| 17b2d92a3d | |||
| 22f0bcaf8f | |||
| e61277002c | |||
| ca5258f140 | |||
| 8f4473b3e3 | |||
| 51e8af9e5f | |||
| 82818e7324 | |||
| 6ae8103022 | |||
| eca2d92791 | |||
| 6778e19710 | |||
| 25f25275cd | |||
| 7e746ad2a6 | |||
| 6ffa2b01e1 | |||
| ed6ca0d7fa | |||
| 8e2a3c1d2f | |||
| 7f6dcc2745 | |||
| 76e34d6f2c | |||
| e613b17c05 | |||
| 5ba9a089e1 | |||
| f2d5d6d24e | |||
| a1ec4ea3a9 | |||
| 0fe7420638 | |||
| b304730225 | |||
| 4801526f35 | |||
| f1857030b5 | |||
| b5b3f4e1c6 | |||
| 172bb7887c | |||
| 60228d30d1 | |||
| 9592537840 | |||
| 8768a80242 | |||
| d5f73f89d8 | |||
| 19bbe6c67d | |||
| aebb65e983 | |||
| 5e327af327 | |||
| bc1f8813c2 | |||
| 80d9f624d0 | |||
| e9c46f38fc | |||
| ecfbaa267d | |||
| c25fd3349b | |||
| c3e27bcf87 | |||
| a5894f3e6b | |||
| 4db3a388dd | |||
| 6fd1a2ef52 | |||
| fe2a259eb1 | |||
| 1ba7c2f276 | |||
| 649f747f8a | |||
| 05dbaf7672 | |||
| 742a08229e | |||
| 5602d2c7bb | |||
| f3e0479a8f | |||
| a1143c4ea0 | |||
| 0314d1dd01 | |||
| 751b3f502d | |||
| bf5e09d5ab | |||
| 14e4a10312 | |||
| 53b89e1ee4 | |||
| 370f878a36 | |||
| 6e4d61c1fd | |||
| f6fe5c07f6 | |||
| c685293297 | |||
| 0e6a2c0491 | |||
| c2209ad5e4 | |||
| 5f249a3e67 | |||
| 76fb3652fc | |||
| 92925e846d | |||
| 43c04c29ce | |||
| 06b74c87da | |||
| 7f075b0b15 | |||
| c5a86c22a4 | |||
| 3621c6234c | |||
| 80c2fefc43 | |||
| a47952146a | |||
| a55950865e | |||
| ab181ac329 | |||
| db172d1053 | |||
| dad26339a9 | |||
| 3b0ed61826 | |||
| 9699e2b483 | |||
| 3048188b5b | |||
| 547bb3b053 | |||
| 7c2087cf05 | |||
| 217fea9667 | |||
| 523c3cd50b | |||
| c68fec7e97 | |||
| ded0efb955 | |||
| 9777fbacf6 | |||
| 643b4dd126 | |||
| c78a8dfd2d | |||
| be110d0464 | |||
| f948a2d0c0 | |||
| 2aa47554fc | |||
| c80b270678 | |||
| dcc32e84b9 | |||
| 4dbba5ac98 | |||
| 374cc4183e | |||
| c4c43c3d26 | |||
| 0e274fc4be | |||
| bc3da25a4a | |||
| 80492d663e | |||
| 172c539a5a | |||
| 30df77fa4c | |||
| 71a22e45b0 | |||
| defd8a527b | |||
| 3ce29236f3 | |||
| 04ee99f1a3 | |||
| c39b83667b | |||
| 1bd382c1d0 | |||
| 249c508126 | |||
| 04b27525fa | |||
| 07dca8cc03 | |||
| db4ab1c936 | |||
| 622b9d9276 | |||
| 05bfdeab7a | |||
| b4bb98ea60 | |||
| a079c2eb7c | |||
| f7aa91e660 | |||
| 6d677bbd63 | |||
| 299f9837b7 | |||
| 498f1525b2 | |||
| d8b1fc45aa | |||
| 295da7e5f3 | |||
| 952f8e38cf | |||
| 052d209901 | |||
| e9c45ff406 | |||
| f1053d48a2 | |||
| ba12f52f6c | |||
| 456137fa24 | |||
| 692059e899 | |||
| 252ce0b581 | |||
| d24befa0bc | |||
| 81a6d1b0d4 | |||
| 6e50e4b9ee | |||
| 1599f9f0c0 | |||
| 0c5b6e5556 | |||
| e3e04f5dae | |||
| 17bc8565f6 | |||
| c08954c18b | |||
| 7ba56a4b88 | |||
| b70370f3fd | |||
| 4d3cf77ad5 | |||
| b2005ccaef | |||
| 9bcb006ec7 | |||
| 02ac6ec81c | |||
| 5c91f5b71d | |||
| 41d108ead6 | |||
| 0c9dbc61a1 | |||
| 6788fdb0d6 | |||
| 3a4b61579d | |||
| 51d7ba7446 | |||
| e608adea60 | |||
| 8dd6882222 | |||
| a4d6bcba09 | |||
| f09a577ab5 | |||
| 973e1acb67 | |||
| 676a724491 | |||
| 73318fd514 | |||
| cb08c15616 | |||
| d2f87ca76c | |||
| 4935b14539 | |||
| 0835611d3a | |||
| 8b4fa2605e | |||
| c3910807c5 | |||
| c5b8b5687f | |||
| f61883b227 | |||
| d206350738 | |||
| 2da1f9181a | |||
| f55c9ed1ba | |||
| 369b260e12 | |||
| d9e7c1626a | |||
| 4995aecd62 | |||
| 66b2140892 | |||
| 68667d6057 | |||
| d58b5ef74b | |||
| f044037ec5 | |||
| a97f21ba4e | |||
| b594ed99b8 | |||
| 15073d63d9 | |||
| 31b2d6be75 | |||
| 57ee14d62d | |||
| d470cfe86e | |||
| c15218e37a | |||
| d668aa7c24 | |||
| e20fe421e7 | |||
| 2deb38d615 | |||
| b95d71af2b | |||
| cc1fbe0956 | |||
| 97c6ec6d49 | |||
| 1fcf7ba5bc | |||
| 12c1e1d149 | |||
| fa222b0ea2 | |||
| a6dbef89c2 | |||
| 02f08879a4 | |||
| ac4b592b4e | |||
| f5de714451 | |||
| 091461cece | |||
| d228c5459d | |||
| 3d5d3ea20c | |||
| 4b6047e746 | |||
| c47673bf10 | |||
| 2f6d2b08aa | |||
| c7df82460c | |||
| b19697e3ac | |||
| 2b2e515a30 | |||
| 394e640909 | |||
| b48eb4e88b | |||
| b525480b25 | |||
| 45f18eaa52 | |||
| 4c92a2869b | |||
| 8251fc0811 | |||
| 827ff80c06 | |||
| 18ca998f67 | |||
| 8444470e3a | |||
| da6344297a | |||
| 3cfca01372 | |||
| d934bb15b0 | |||
| 0c0a8392e5 | |||
| 58043dac0f | |||
| d2c1f1131b | |||
| fa5c7a9e75 | |||
| ceb94d52a1 | |||
| a2716712ab | |||
| 7842181b47 | |||
| 635990a5b0 | |||
| 562f2375c5 | |||
| 17234f82d0 | |||
| 7b57df02a7 | |||
| b65ae3b036 | |||
| 66f3e97457 | |||
| 1ceba29f4b | |||
| 40c748a2ae | |||
| 69d0bc8fd5 | |||
| 6a73e5a720 | |||
| e70ba29d95 | |||
| 9637cf0574 | |||
| eb152d7431 | |||
| 83afd09f13 | |||
| 96488c1c74 | |||
| 244ba1a61a | |||
| 9dadc06e64 | |||
| 60f949e36f | |||
| af154e3053 | |||
| 9e6c290696 | |||
| 0a71063530 | |||
| 0b1ae11498 | |||
| 017a4e7c30 | |||
| 3891f18e71 | |||
| 6a2077cbd8 | |||
| 9267536fee | |||
| 0a58d6812a | |||
| d376fe9e17 | |||
| 7febec49b2 | |||
| 14d5098ca2 | |||
| c0c71d6b3a | |||
| bac1c6d12f | |||
| 4176a0ade3 | |||
| ec10f2e72b | |||
| f36c268b9e | |||
| 824392a1c2 | |||
| 1f9a7b8fd3 | |||
| 9379e85e23 | |||
| 805c2832c1 | |||
| d33a048d89 | |||
| 6d5fdfbf73 | |||
| b5a9a6793b | |||
| 0cf79155d4 | |||
| 1926e919be | |||
| 0e86e292e4 | |||
| a590682764 | |||
| 31c40fa4cc | |||
| 1feb3838b5 | |||
| 39c3334147 | |||
| 4223495e6c | |||
| 023e86d68f | |||
| ac57be91e1 | |||
| c2e65bafb5 | |||
| 74161b2122 | |||
| 39ee5c5a46 | |||
| 788f330d07 | |||
| af56151231 | |||
| 34d359fe03 | |||
| 4672dbda2a | |||
| 9c84749e2c | |||
| cca4c47781 | |||
| e0cfaee7aa | |||
| e75387f029 | |||
| 4b0f8d76f4 | |||
| d023f316ac | |||
| 03a08435e2 | |||
| 4dd3ab8f32 | |||
| 8e0660ad54 | |||
| 1f42512199 | |||
| 1a29ea1038 | |||
| eab2b9dc09 | |||
| 94e92cd6c0 | |||
| 57cd6d2de1 | |||
| 822d468232 | |||
| bdaa6a1910 | |||
| 2221dcc9f2 | |||
| 2eb1ee967c | |||
| c49cfefe88 | |||
| c6a6f39d29 | |||
| eb56ca3b0d | |||
| 13c6eb42e9 | |||
| e5fb50476c | |||
| 073c590d0b | |||
| c832e62db0 | |||
| b7a7119b1f | |||
| 19a880bb91 | |||
| 672399c751 | |||
| 3e6f27522b | |||
| 1b70f94282 | |||
| 87d4970e8b | |||
| 4938765eb3 | |||
| cce78cc5e2 | |||
| 9085b933d8 | |||
| 59502594f8 | |||
| 505dde09de | |||
| 603d623eda | |||
| 87ebf2e50b | |||
| 37c3f0d8a0 | |||
| 4d87f6025e | |||
| 627be179c1 | |||
| 6d83a73858 | |||
| 9b093c9a12 | |||
| f8f6cd6ef5 | |||
| cf08eac15e | |||
| 9a8552e8ae | |||
| 5865af7f6e | |||
| c1148c4ea6 | |||
| 280dc77f8b | |||
| 27df987211 | |||
| 982745fb83 | |||
| 8fa8d471af | |||
| 98ad72b096 | |||
| 24fcb7f813 | |||
| 9e835e8edb | |||
| 1261f250c6 | |||
| 3673b45437 | |||
| 499d8adb75 | |||
| 54386c82fd | |||
| 38b9ec7a18 | |||
| 2558ab3de7 | |||
| 0c10ae1861 | |||
| b3cc828995 | |||
| ba8f9d8620 | |||
| 3c89a28a06 | |||
| 41a2eb5245 | |||
| 3d7670a6ba | |||
| 50462dcdc6 | |||
| c3ac834526 | |||
| c7e0888982 | |||
| c703f1eed6 | |||
| 5ac5da3524 | |||
| 0c13d34ade | |||
| 5aa7435d25 | |||
| c11195d5e3 | |||
| 2ed5cba110 | |||
| 4c05a697fa | |||
| 56d0d5986f | |||
| 053470d5a8 | |||
| 6f4160c014 | |||
| 65ef82a946 | |||
| b509a7060a | |||
| 5ad6ff239b | |||
| fdaa6ff9e3 | |||
| 2f31763335 | |||
| 350562919c | |||
| aa5c4945d6 | |||
| 6fbfc58602 | |||
| 6801dd043d | |||
| bb5f33d13c | |||
| f787c49b53 | |||
| fa90e14b06 | |||
| 03b989251d | |||
| 95919051e0 | |||
| 46fb88c76f | |||
| 210bfaf8d6 | |||
| a50dec88d5 | |||
| 8dcec034ed | |||
| 05d733e707 | |||
| 4bbe28bdf0 | |||
| 0c01cf7c85 | |||
| 917cd13ce2 | |||
| 955cf35d5f | |||
| 0f8efb07c7 | |||
| 4d63a89fa6 | |||
| 7c73e28a6d | |||
| aaca4987c9 | |||
| 21d0f40751 | |||
| 5e7f06397f | |||
| adaace4ab8 | |||
| 424eaba4c5 | |||
| e1cafa3834 | |||
| ba539eb9aa | |||
| 24de676a64 | |||
| 0c2741f7ad | |||
| 6306bc3ddc | |||
| ea068dcc2c | |||
| 4ff76cad2a | |||
| 5af09e73f2 | |||
| 6a2e559222 | |||
| da07ad16c1 | |||
| ba0cea6826 | |||
| d52e4e5df3 | |||
| 907743eee7 | |||
| 610e3dccb7 | |||
| 27392f832d | |||
| e9db7fea5b | |||
| bdd3930855 | |||
| 70d5c88026 | |||
| 2f180cea7f | |||
| f4d6a3ec4e | |||
| 7aa922ceac | |||
| acc576658a | |||
| 4015a5486c | |||
| aae48e6fd7 | |||
| d29c7e7871 | |||
| 755f4f324b | |||
| 863ab0e72e | |||
| 4ab0377c6e | |||
| b61a55eebf | |||
| c30078c5a3 | |||
| 39b91c97f0 | |||
| a7742d7d63 | |||
| 5179e37bd1 | |||
| a7b17bfaf0 | |||
| 4af1f31a3f | |||
| 9e42e04b4a | |||
| 9103837228 | |||
| 3f3c5de851 | |||
| 34b65be44a | |||
| b928ebdd53 | |||
| b42623ff9d | |||
| 59ae0e0013 | |||
| c0f63eb21f | |||
| ed2a698392 | |||
| aaad1791d9 | |||
| ad6e82942b | |||
| d60bb57d4b | |||
| 85dde8a800 | |||
| cbff19ff1a | |||
| 167bac23aa | |||
| 5d0cfa2527 | |||
| 821fae0d94 | |||
| 41effbe2da | |||
| e5841d3126 | |||
| 11cc36d770 | |||
| 05f1939b02 | |||
| 050ea9762f | |||
| 0f24d4d2a1 | |||
| fc799191f4 | |||
| 8fad85edda | |||
| d70053aba5 | |||
| 94c67faaea | |||
| 9fe49497bb | |||
| bf489feef1 | |||
| 6a3d925a47 | |||
| fb7ef76e74 | |||
| ee39081b11 | |||
| 4eac198270 | |||
| faac32418c | |||
| 42810621df | |||
| 61a5378aeb | |||
| 42d644ef91 | |||
| c95a56450d | |||
| dc5199feea | |||
| f88fdf6a1b | |||
| b68057d927 | |||
| e9a860d9cb | |||
| 8be86cbdfd | |||
| 5091e64a42 | |||
| 25f908b320 | |||
| 9b7dca2fa1 | |||
| 735a79ae83 | |||
| ef2b400c61 | |||
| 53eca2ff5b | |||
| 3a15a3821a | |||
| 9557b9f70f | |||
| 464441d8c3 | |||
| f30f1afd47 | |||
| b3db37b99d | |||
| 7a276f39fb | |||
| 415668ecf0 | |||
| 651967b95c | |||
| 438e2dc228 | |||
| b4084491e5 | |||
| cb97421edf | |||
| e461031d40 | |||
| c82e4596e4 | |||
| 15ba3e123f | |||
| 2db243b8ed | |||
| b57b64b7a3 | |||
| 8e386ac71f | |||
| bc1af6227a | |||
| 4c2dff88de | |||
| 80238880e6 | |||
| f4abafb093 | |||
| 3e538355e2 | |||
| 76e9da3fe9 | |||
| cafa04f842 | |||
| fef84f69ec | |||
| ba98cd97e5 | |||
| 81b897c291 | |||
| 1c4d70896a | |||
| 039bcd932a | |||
| eaa9228a4f | |||
| a8757df963 | |||
| 2c796de92b | |||
| 6f2a64a511 | |||
| f5f675ef6c | |||
| bdc8e9118b | |||
| d9ed9a9a83 | |||
| b57faa41c2 | |||
| 1b5fe91624 | |||
| 1a305cadb3 | |||
| 34183237ce | |||
| 286ec92967 | |||
| b05631432b | |||
| dc92886ab6 | |||
| 993416d9cf | |||
| 327109f327 | |||
| f1f9121bc7 | |||
| 3b42e19505 | |||
| 709156ee65 | |||
| 472030907b | |||
| 3e513ee6ab | |||
| c2ce3d927a | |||
| 0e8431d17b | |||
| 826fdaf06c | |||
| a4d0a1483a | |||
| 2610724ee0 | |||
| 61359a5bd0 | |||
| de781b306f | |||
| 478663b08c | |||
| fb9a00c36d | |||
| 73ee01a7f4 | |||
| eb9b5fa9a5 | |||
| 8bd5405228 | |||
| cb51a155b2 | |||
| 9c16408e91 | |||
| d42a2b2d16 | |||
| cf96a9fd27 | |||
| 76e81dfbb0 | |||
| 684ba6fe14 | |||
| 830cb5cad7 | |||
| 2b06208bbd | |||
| 5f637e5a02 | |||
| cc712a165d | |||
| b67c0e5f4a | |||
| 1e1ddd3279 | |||
| 70f69cb265 | |||
| ae4cc404c1 | |||
| 32df5faa25 | |||
| ac8e7d57dc | |||
| da4a531717 | |||
| fea12f7806 | |||
| 115e471515 | |||
| c4df8989e9 | |||
| 0f11b1fc0d | |||
| 527d86a93d | |||
| 7d66f1e391 | |||
| 6265155ce4 | |||
| 70d1ff7155 | |||
| 4753206783 | |||
| 6376a3aef2 | |||
| a604d44d06 | |||
| bb92eb5a93 | |||
| 1fb3133ec5 | |||
| fea45c6911 | |||
| aadbebf9d8 | |||
| 7e12af2448 | |||
| 776d92e797 | |||
| 7ffc02283b | |||
| 7a31a6edee | |||
| df05bc65c5 | |||
| 3a49ff9e72 | |||
| 71e2a17fdb | |||
| 7de627c504 | |||
| 6a4bfc0863 | |||
| 170bf6d7af | |||
| 1dacea3a20 | |||
| 083a7c8f0a | |||
| 4ed91ce7ed | |||
| 15e2f991dd | |||
| 0c171c0749 | |||
| dbd65a3b01 | |||
| 971dacaf41 | |||
| 6c53af8e41 | |||
| c4ca9a7bae | |||
| e68657cdb2 | |||
| e00cfe067d | |||
| fcaeeac931 | |||
| a53582d706 | |||
| e655083e3c | |||
| 40a7c70969 | |||
| 5105a937d1 | |||
| 29fb4f98b1 | |||
| 3386efddba | |||
| c41650db20 | |||
| a0ff55db7d | |||
| 896bffb543 | |||
| 0df6159149 | |||
| cfb77091ca | |||
| 1f726e81f9 | |||
| df71853075 | |||
| bfb10d74eb | |||
| 68d15fc62e | |||
| f479935cda | |||
| 6e8daaec0f | |||
| de7377485b | |||
| e23578acd9 | |||
| 770445ae2a | |||
| b9b65e9392 | |||
| 125b9f6057 | |||
| 69357b1e88 | |||
| e9e9e3898a | |||
| 9ef20ad20e | |||
| 1263949e70 | |||
| 12d80b9e64 | |||
| ad333e0d22 | |||
| 34a8a45a6a | |||
| 1e51f87298 | |||
| 8095f601d1 | |||
| b40d24ad75 | |||
| f839fa4070 | |||
| 32d51313d0 | |||
| 69341edfe6 | |||
| 81f0b0e0dc | |||
| 28f919d9d2 | |||
| 3e1673e8b2 | |||
| 174753921d | |||
| aa32e3deb1 | |||
| 47fe017a6c | |||
| 7baae20c20 | |||
| 921c4551d9 | |||
| c20a424e3a | |||
| 2e005f5dc2 | |||
| 9f13fdb840 | |||
| e6f52b0996 | |||
| e11408f6ad | |||
| 61a4100d0c | |||
| 69fc0acd1a | |||
| 3f14cb073b | |||
| 5ffe32439d | |||
| 76a9c0ccb0 | |||
| c89084e6b7 | |||
| 64072e44cc | |||
| e7007668a6 | |||
| 105b57c8d9 | |||
| 79d4a38d87 | |||
| e08de1101d | |||
| b5339cc01b | |||
| 35eaacd1db | |||
| ad2f5ccc66 | |||
| 77bfd9434b | |||
| 6ba99068c9 | |||
| b7f6584dab | |||
| 3290a5f370 | |||
| 0753408e10 | |||
| b62d015285 | |||
| 24002a5dfe | |||
| 7c4b873ba3 | |||
| 7949983c41 | |||
| b0d66e06f4 | |||
| a00d6b8377 | |||
| ca8c3dd9b5 | |||
| c434ca74a2 | |||
| 94f00cf096 | |||
| 50a264d832 | |||
| 3f52d0e46c | |||
| 716bdd5ee5 | |||
| bad08d26da | |||
| a41394c885 | |||
| dc31e20925 | |||
| af63fffb63 | |||
| 0a6adedaf1 | |||
| b19f860384 | |||
| 4c1d5840bb | |||
| c5c2b6f9bf | |||
| 0f4b27c300 | |||
| fbb38cc245 | |||
| c1a57a10a4 | |||
| 12fa8d8444 | |||
| ddd2447192 | |||
| 04d907fb97 | |||
| e2610df073 | |||
| 4287961aed | |||
| d643a90efa | |||
| d0fe6ad109 | |||
| b450dd7a87 | |||
| 2e429268ff | |||
| e2ca50f1cb | |||
| be24659c03 | |||
| 2dc157246b | |||
| b6670f3ac3 | |||
| d2ac304ade | |||
| 16c3522f4e | |||
| 7ac6abe02a | |||
| 6af20d3907 | |||
| a823b06fa5 | |||
| cbb0151303 | |||
| ec4baf337a | |||
| 325bdf952c | |||
| 6fbf93750b | |||
| 65eb946756 | |||
| 137ec1c846 | |||
| b0afb4d63c | |||
| 51fd26b19b | |||
| 1b0f781b7c | |||
| d1c04af603 | |||
| eb82ba36a3 | |||
| 7bcb51eded | |||
| f70e80a6ba | |||
| e0265c67c6 | |||
| 28c064f345 | |||
| c7f03814ea | |||
| 90623498a2 | |||
| 21b2e33ebb | |||
| 0553543e6e | |||
| 543379d343 | |||
| 37eba84056 | |||
| 293e777fce | |||
| dd5976162b | |||
| 7328600a7a | |||
| 3d0a421ab4 | |||
| 831d48d971 | |||
| 3a062eed5b | |||
| 52a6a823ad | |||
| 9d61b1e754 | |||
| b89410a266 | |||
| 317db39a5e | |||
| 9d89edff2f | |||
| 599d64a405 | |||
| 0a6f216f83 | |||
| 1d0334fc07 | |||
| 6c57428742 | |||
| 0f35412dcd | |||
| 6d81a88288 | |||
| 96a15434a2 | |||
| 6111935835 | |||
| c131c12fd7 | |||
| ca7518c13b | |||
| 77e26a7db3 | |||
| a7c1838c69 | |||
| 54d80d9168 | |||
| db2cefd12b | |||
| a40d308d6a | |||
| 3dd55d284d | |||
| 504ff978c5 | |||
| 9a7df7a85d | |||
| b5a4bd22fb | |||
| 0aca3fb5af | |||
| b50c1ba9e6 | |||
| 413c056504 | |||
| 20d5d1c4c2 | |||
| 928d5ae315 | |||
| 0cdbdfdf9f | |||
| 47426a8ae5 | |||
| cc73c36e32 | |||
| fdd5c26eb8 | |||
| ad66b070a7 | |||
| 6f6dd227f8 | |||
| 3d5f9e8b14 | |||
| 2cb48e034e | |||
| e5d78960c6 | |||
| ba8d20e9ae | |||
| 767127c92e | |||
| 65b5d34aee | |||
| 107f233626 | |||
| 0677f3e21c | |||
| 1162cef978 | |||
| c527b3cefd | |||
| 8fa013309e | |||
| 7ab3a80d0a | |||
| e5518ee657 | |||
| 0c31c0756c | |||
| 7405075ede | |||
| 6b474c4051 | |||
| a9c954e821 | |||
| b6933dbf3a | |||
| f46b1252c4 | |||
| e6959055b5 | |||
| 7ea21c4b3c | |||
| 9d227641c9 | |||
| 2a2e4e78bf | |||
| fb3b297369 | |||
| 050327a1e2 | |||
| fcff767a7f | |||
| 7a282a8892 | |||
| 3e34cec96b | |||
| 6ca46afa63 | |||
| ab0e1c573a | |||
| 26da491053 | |||
| 674ecc5581 | |||
| eced4dd023 | |||
| 94e1126678 | |||
| 2b787eb4b8 | |||
| e250bae356 | |||
| 1a5b411ae4 | |||
| 4c7f56263e | |||
| 6be9496d73 | |||
| 46b2da409b | |||
| 694fe3e7d2 | |||
| 900051cd04 | |||
| 34c3f0f495 | |||
| e705414bea | |||
| 467870415b | |||
| 37c12db366 | |||
| b73bf03bfc | |||
| 8c221981bf | |||
| e85b41f9be | |||
| f54f6627c3 | |||
| 13a1105318 | |||
| 8e5e1b62aa | |||
| 19ef9505e8 | |||
| e982ad2284 | |||
| 7825abd540 | |||
| cd59516433 | |||
| 1a3a25f825 | |||
| b4e941d431 | |||
| ea41f89b40 | |||
| 7a790d0d35 | |||
| 995c308a49 | |||
| 1d5589296e | |||
| 8a44e712f8 | |||
| e4e10e54df | |||
| d93790717d | |||
| 5e5f47321b | |||
| 109637e213 | |||
| e49ae68524 | |||
| 49127b6a26 | |||
| 255853a819 | |||
| 28c0cd8460 | |||
| 10ef76905c | |||
| e43375cc68 | |||
| 63bb2abada | |||
| 5202186681 | |||
| 98889e41b0 | |||
| 962cdc2d98 | |||
| 71acf078ba | |||
| b3233de1c2 | |||
| 63982d6771 | |||
| 2cd540b9c4 | |||
| bbdae291ed | |||
| f9f33a7bb5 | |||
| d34a34f328 | |||
| 3eaeca58da | |||
| d3bc563c6e | |||
| 941a9792f7 | |||
| 646a023ff4 | |||
| 005508a07b | |||
| 701744c621 | |||
| e4c7fca755 | |||
| bec7b297ed | |||
| ee17b5de6e | |||
| a0041125c6 | |||
| 378a634de8 | |||
| 8a05850302 | |||
| 8c74d7e4fa | |||
| ba3f150b14 | |||
| 2f8c62999f | |||
| 3eea3dd46b | |||
| ba2b331461 | |||
| a6f7dca685 | |||
| 282605ea76 | |||
| 244511e434 | |||
| 656b20a169 | |||
| 50bb344a9d | |||
| 1c078c59e3 | |||
| cd68cc1f46 | |||
| e80f6624ed | |||
| 109255a730 | |||
| b13b5d86f6 | |||
| 15265918a7 | |||
| ed00088f17 | |||
| 3ed376d103 | |||
| e2930c7898 | |||
| 84676fefe3 | |||
| 1363496c11 | |||
| a029f03edc | |||
| 03df48899c | |||
| cdbea6f0a0 | |||
| 6659d55a9d | |||
| b4795086fe | |||
| a6b5771297 | |||
| dac298ef41 | |||
| 3e9158acd6 | |||
| b82700ae41 | |||
| 009860e98a | |||
| 624d532000 | |||
| c51f5e8d76 | |||
| ba7dbca018 | |||
| 7d7ab462d6 | |||
| c4c21c2fa7 | |||
| e06a497c7c | |||
| f7cab121fe | |||
| bb59b81d82 | |||
| b74804f61f | |||
| 50baf76cc2 | |||
| fcdd69fd97 | |||
| 46e275dfe4 | |||
| 743f1810c7 | |||
| dd1494eebf | |||
| 5bb45baa6c | |||
| a04479746a | |||
| 8ac304517e | |||
| e52291cbcc | |||
| 79b4dc14a3 | |||
| 8ed0fc6f0c | |||
| 9f01b97e14 | |||
| 9f52244574 | |||
| fce8d8e090 | |||
| 8ff27a07bb | |||
| d1ea2ad143 | |||
| de385009ae | |||
| 114848d313 | |||
| a55150b1bc | |||
| b5a9ef6b7b | |||
| 8ebe320270 | |||
| f41327df0c | |||
| f77276311d | |||
| da5bfefc78 | |||
| 619cc01ca1 | |||
| ad94d8cc4f | |||
| c3cebc3ac5 | |||
| 02488c5cbb | |||
| 40ca8f4695 | |||
| cf28b5e5be | |||
| c79a1528ad | |||
| 31619faa70 | |||
| 9e6b7f5dc1 | |||
| 541a09b7ac | |||
| d1b5a78171 | |||
| 753ccd6b17 | |||
| 08bee40fa2 | |||
| 461e26b60b | |||
| 6fdb7aee84 | |||
| 22d64ae08f | |||
| 5ecf693774 | |||
| b7a70fda79 | |||
| b023fcd264 | |||
| e98c845f0b | |||
| e4ed1d08f4 | |||
| 8e32566583 | |||
| a3de45741e | |||
| 7d7d907de7 | |||
| 673e4e20f0 | |||
| 38a4eaf8a3 | |||
| 29b453eb86 | |||
| ef0eed8d3c | |||
| 9d37cdaa66 | |||
| 3f686a6ab8 | |||
| db3e3a766a | |||
| 9cef41000a | |||
| fc54853d44 | |||
| 6f5af6eb42 | |||
| eb6d8e6af2 | |||
| 446f344818 | |||
| 3c40f87af3 | |||
| 69e1167882 | |||
| e726ff3296 | |||
| 56568dae31 | |||
| 74b6646737 | |||
| 986ad4ff06 | |||
| 95ce8f45ea | |||
| 7521f207b1 | |||
| 2155296a13 | |||
| 23be514886 | |||
| 77b986c7a1 | |||
| f90673ef4c | |||
| df18431b45 | |||
| 5c987e4c75 | |||
| 7efc0011fd | |||
| ece14eae24 | |||
| 3c9d03c36f | |||
| 7afd48658c | |||
| d65c6af3a5 | |||
| c08e38acd0 | |||
| 85b0fb2a9c | |||
| 19d825aa16 | |||
| e1a8fc0417 | |||
| eafe6ccdbe | |||
| 0f8ab0557e | |||
| 0105f8fa38 | |||
| 049b50d9c0 | |||
| 12fd382fec | |||
| c996fd1c06 | |||
| c4c9cdd2b1 | |||
| 34c4e454c5 | |||
| 11cfa64a10 | |||
| adafb20d1e | |||
| dbfa1bfba4 | |||
| f8c7862f69 | |||
| b86f129393 | |||
| e8536c4a0e | |||
| 2687a2b6dc | |||
| aab6362705 | |||
| 94e8a08d1d | |||
| ce8027c6fb | |||
| 9acbfc6e05 | |||
| a316b11aaa | |||
| 2c6a2f0381 | |||
| b866d0dc38 | |||
| 23baf1a75e | |||
| b5c162175b | |||
| 60c76cc289 | |||
| efd556b1a9 | |||
| b4b2a276c8 | |||
| 464d53bb16 | |||
| 4c9e3723e8 | |||
| 06477743ab | |||
| e4a9ad1730 | |||
| d0b6637c1d | |||
| 58268b6eef | |||
| 14aa8affe5 | |||
| 56074c2eb3 | |||
| 3da1e8b2f8 | |||
| 786cecfe66 | |||
| dde3cb3b99 | |||
| 24f2b7dd3f | |||
| 936530f795 | |||
| cfbdbffcad | |||
| 71db9d3b57 | |||
| b455e1cf52 | |||
| 90bea15e35 | |||
| 892cac9e1b | |||
| f58f36dc88 | |||
| 9e84b860f2 | |||
| 2e7ef6f4e8 | |||
| cea137f313 | |||
| 79a82013ad | |||
| 3826158547 | |||
| a7c150ec66 | |||
| 389495f76a | |||
| a3f3fbe05d | |||
| 4d00ed8df7 | |||
| 41e906d1a4 | |||
| 0e4b5b88dc | |||
| 011d8e80d8 | |||
| 1f8f0abe92 | |||
| d9c5b85671 | |||
| 76cf31bee7 | |||
| d986cc4861 | |||
| 724001aa0f | |||
| 5564d73071 | |||
| 3fc1c73064 | |||
| 1b0dca9c2c | |||
| ef32d7fd16 | |||
| 5f1ca33c6f | |||
| e12adcdf08 | |||
| 527cedd848 | |||
| ec5065eb53 | |||
| 90524a8528 | |||
| eb24575e2c | |||
| d9877efe1d | |||
| 7459613623 | |||
| 07736c912f | |||
| a110ede0a2 | |||
| 2a3cdba724 | |||
| 099ad1a259 | |||
| 6df92b3bca | |||
| 48ccbe39b4 | |||
| 691c3d1e3c | |||
| ca8bb8d053 | |||
| 56d2b7137c | |||
| d9a62c42e5 | |||
| 978f387961 | |||
| 209f6cdcc7 | |||
| 1fe276d041 | |||
| f345ed564a | |||
| 3d4563913d | |||
| 93c3775927 | |||
| afbf383ba3 | |||
| 36598677cf | |||
| 72dfd4846e | |||
| bd40952097 | |||
| ea1e3fb90d | |||
| 3a99fb9d34 | |||
| e1b56e376e | |||
| e8058b9fdb | |||
| d31b6c3480 | |||
| 95ff928228 | |||
| 510dc17c2e | |||
| 2669d8ce73 | |||
| 1729297ef3 | |||
| b87f7a625e | |||
| c3e8790dfd | |||
| bf49149c97 | |||
| 49d5960a32 | |||
| dcfa23d5d2 | |||
| 5ac0712cf1 | |||
| adac1da64e | |||
| 9c8626bf3c | |||
| ef21fd3cf8 | |||
| aa51382dbc | |||
| 8bf451a3e0 | |||
| 0d3e05f9b3 | |||
| 06a09d5991 | |||
| 57c894f44d | |||
| 7de189114b | |||
| 4c048a487e | |||
| 09a62012b2 | |||
| b494de6a01 | |||
| dbeec7715d | |||
| 1048feac3b | |||
| 78476a0fe2 | |||
| d5fd2f0155 | |||
| c8ebe0eb86 | |||
| 16561ed71e | |||
| 4bfdf7cf2a | |||
| e58da86efc | |||
| 2dd2d60955 | |||
| 1b443219ed | |||
| 76be3529f4 | |||
| 6a51e3b39a | |||
| ae265a48c7 | |||
| af2f8c69f0 | |||
| 46ccde82cf | |||
| 537494f4dd | |||
| 39d5e14c1f | |||
| d5dce63254 | |||
| 01981ed290 | |||
| 6f5d56d994 | |||
| 793b2b9ad9 | |||
| 050c960dfc | |||
| aabeb8a18e | |||
| d7d51e4cc7 | |||
| 5224d016e9 | |||
| 199687a1c5 | |||
| b5a6c8e2b2 | |||
| 955909bdb5 | |||
| e3da18121f | |||
| 0c4a8e2ca8 | |||
| a3e7c2d8e3 | |||
| 40b8b58bc6 | |||
| fc1a156262 | |||
| 8cbd20b380 | |||
| 43d306fc2d | |||
| 01e23a2222 | |||
| f88d89ad82 | |||
| b29f73d5e0 | |||
| e998d89e88 | |||
| b91e701f35 | |||
| 295afd5882 | |||
| 8da1b9aafa | |||
| 19f4cc57c1 | |||
| 80d4d4d92c | |||
| 6a7df4e973 | |||
| 098f07664d | |||
| 4dbb8ac4b2 | |||
| e7f2af5fdb | |||
| 4419f4093e | |||
| c945ea125a | |||
| c32e349332 | |||
| 118218754b | |||
| 00c61cf197 | |||
| f6901ab877 | |||
| 862fc06b6f | |||
| 89ed813585 | |||
| 0dc28d3446 | |||
| 50657e2324 | |||
| 7c22cd49a7 | |||
| c012490399 | |||
| e937d9b559 | |||
| 688aea6bec | |||
| 7186c46377 | |||
| 3fc1487cc9 | |||
| 48ddb53332 | |||
| f584c6d723 | |||
| 3ea9022c5f | |||
| 45ee8e2532 | |||
| f7b8f522ff | |||
| f6aa9ac304 | |||
| 6c575e8826 | |||
| f52a2cf5e1 | |||
| 5bfb779d82 | |||
| 95fd61c9b4 | |||
| d1cdef596c | |||
| 7163781639 | |||
| a63cee2139 | |||
| 830d8d6b75 | |||
| a07f064e50 | |||
| ea4b491a73 | |||
| 986bc65e1f | |||
| 5218443784 | |||
| 3b00ee2afb | |||
| 7d832337ae | |||
| a258404a58 | |||
| a3048239b3 | |||
| f787c73841 | |||
| 1604ea3b27 | |||
| b23d377567 | |||
| f445b826d0 | |||
| a12ceb04bb | |||
| 623aaaccd4 | |||
| da0fd62c23 | |||
| a10d289997 | |||
| 750b1aba8d | |||
| a3e8c6e866 | |||
| bfd056ceb1 | |||
| 620629593b | |||
| 05ad3a535f | |||
| 5c76f99fdd | |||
| 36915db699 | |||
| 17640d6008 | |||
| 8711653530 | |||
| 7e019af50d | |||
| 8b61719a9d | |||
| 5ae9892170 | |||
| 6426101433 | |||
| cf8322c0d3 | |||
| 0384eb7d8c | |||
| 0c84b91dde | |||
| 7a796b20ea | |||
| 71f665bd8c | |||
| 2129c72bc0 | |||
| 0428dce27d | |||
| 60354e3901 | |||
| 2e6e9c14b5 | |||
| 721ab68bec | |||
| 192e5c8166 | |||
| bce5d364df | |||
| 2dfb163281 | |||
| 417d7a38de | |||
| ba147d2be2 | |||
| 1192cbe4ab | |||
| 458bd1652d | |||
| e5e08ec523 | |||
| 3547ac4b49 | |||
| f6c2bf21c8 | |||
| 397ba2d9aa | |||
| 8cc2cbf1c4 | |||
| d696d7f9ea | |||
| 41548a091b | |||
| c9e1386e44 | |||
| 5108e3ced6 | |||
| 8753203df0 | |||
| a66f61748f | |||
| b45273eccb | |||
| 7fe87d9a5b | |||
| a37f7cce52 | |||
| 949fe93d5a | |||
| b4e9b4fe7d | |||
| c3ced6db4e | |||
| 0b38571920 | |||
| 2ffe15f22f | |||
| 31ddd98c8e | |||
| 759c9522fd | |||
| f0149cdae2 | |||
| bedabc15ae | |||
| 565f14655c | |||
| 760e7e8efa | |||
| fa25faa2d2 | |||
| dbab8d8c38 | |||
| 9f02b8742e | |||
| 422f802ec9 | |||
| 5fd3d36fe8 | |||
| 11eff8bae0 | |||
| 27b2059662 | |||
| e6ec42d462 | |||
| ff4c3873f2 | |||
| 1192734131 | |||
| 29976a04c5 | |||
| a3106d424b | |||
| 77b01deb80 | |||
| f53f491cd2 | |||
| e421233a1d | |||
| a2f7ef9d21 | |||
| c708f506a4 | |||
| ae293f27cf | |||
| afe9993376 | |||
| a9f5c19239 | |||
| 53bfdc318a | |||
| 4cf76754d3 | |||
| b698d0a6ee | |||
| 11fb04c2f7 | |||
| aaf65bb3af | |||
| 9d38a95292 | |||
| 0291dd3ef8 | |||
| a46ca98c57 | |||
| e65e23b9c0 | |||
| d8b2f11cc8 | |||
| c3bb57afea | |||
| 8a480ac3c1 | |||
| ffe0d50447 | |||
| a199d7adf1 | |||
| 348414dc62 | |||
| 243ce78508 | |||
| 33db2ac928 | |||
| 1fabe92ace | |||
| 4564b8a224 | |||
| 971cc3354b | |||
| 9b7b22ee0e | |||
| d17ab271e8 | |||
| a216b8bf87 | |||
| af9ee90091 | |||
| cb2e276bff | |||
| cd0f0384ef | |||
| 5924770504 | |||
| 111cdd7a32 | |||
| 89a17b4232 | |||
| f0c411d8b5 | |||
| e5e767abc1 | |||
| 521aac9665 | |||
| 1949056423 | |||
| 3d50bde46e | |||
| 0b454486cf | |||
| ead1dcf308 | |||
| 553259ef99 | |||
| ff992183b2 | |||
| 37e2afb8f6 | |||
| d0e6d2438c | |||
| a724dc99e8 | |||
| 44d473fba0 | |||
| 988bc804bf | |||
| 52ac3661b0 | |||
| 27f1ab5a70 | |||
| 8bf1b9a422 | |||
| 524a2fffe9 | |||
| 6781ca7d55 | |||
| 0970ef57bd | |||
| f98c97f796 | |||
| 46d3637609 | |||
| 992c908b56 | |||
| cbdaa93e54 | |||
| 4988e131fd | |||
| 657c8d1c65 | |||
| e03891b744 | |||
| a5fdcf9881 | |||
| 62a63021c7 | |||
| 33fab84473 | |||
| 0ccc839397 | |||
| a711e2aa41 | |||
| ab4065fa1c | |||
| ee73b0bd08 | |||
| e58977a3de | |||
| 31bee49371 | |||
| 48ef6df842 | |||
| 98ad7d01d5 | |||
| 206c843f36 | |||
| 4e6a108bda | |||
| c62e63909a | |||
| 7566921364 | |||
| 4cec9e5ff1 | |||
| 59ba33658a | |||
| 085bd5f55f | |||
| 86905754e4 | |||
| 6044395986 | |||
| eff259b047 | |||
| 4f03f70968 | |||
| c81d785ada | |||
| 6fb46bb34b | |||
| 365a10f58c | |||
| 3bdd7bfbea | |||
| 6573b9ace0 | |||
| ee5ff71d55 | |||
| 6e5f0a2a58 | |||
| 721fac5542 | |||
| 99bc35a883 | |||
| 63e92cccf2 | |||
| a74ed58893 | |||
| 5ed65460d1 | |||
| 0eb7060205 | |||
| e3d502310f | |||
| 9ba5581d17 | |||
| 6fdddd53a1 | |||
| 88a187a737 | |||
| 57f5700e18 | |||
| d84b213f59 | |||
| 177fbc7bbb | |||
| 56373428dc | |||
| 13962b8533 | |||
| 04bee3f9b7 | |||
| 305a245530 | |||
| 74113737f3 | |||
| c244b456f0 | |||
| 87ab4ee567 | |||
| 0cbaaba4b1 | |||
| 6fbf7042b5 | |||
| 265acccd56 | |||
| c6638d62e6 | |||
| 55ca0fcc27 | |||
| 25f3a11a16 | |||
| b1706bc7e5 | |||
| 579d74d35b | |||
| 7ce518106b | |||
| 171cba4947 | |||
| fd498501d6 | |||
| 51bfe74ce1 | |||
| 5f3012fc9a | |||
| 0f3c82e73b | |||
| 02385472b6 | |||
| f30b5995b6 | |||
| 89a6937c00 | |||
| 08a3eef62a | |||
| 434014b05e | |||
| 29ff1129fb | |||
| 5906b49bd1 | |||
| b03ed532cf | |||
| 7d30e19b3e | |||
| b083c20eb2 | |||
| 7722a2b8a8 | |||
| 977e5afbac | |||
| a17d1843fb | |||
| c3e8a82c9c | |||
| d3aaf2d3a3 | |||
| 515a06cedf | |||
| 9f177b2bcd | |||
| 765f333a1d | |||
| 4e97c69792 | |||
| 88d8a48b09 | |||
| 6202556fc0 | |||
| be9f3826d7 | |||
| 7f453ade73 | |||
| b3a261c7ce | |||
| 6b0fff72d9 | |||
| 21e28adb87 | |||
| 57ca10636c | |||
| e96a58f091 | |||
| e02318d384 | |||
| 9039284d96 | |||
| 593af7287b | |||
| c0f435349a | |||
| 5ecf5f106a | |||
| 5b095dfcb6 | |||
| 7c41b54e3d | |||
| 486de65067 | |||
| 06bff34a6b | |||
| 77ddfa2fc9 | |||
| 7386d8523b | |||
| 713577b257 | |||
| 583f4b9633 | |||
| 45a6386e45 | |||
| 3c35b563d7 | |||
| d981d04c76 | |||
| 666be238d8 | |||
| 3e3d4ad797 | |||
| 6e5437a582 | |||
| 09799402f9 | |||
| c722625f28 | |||
| 1d30a524fa | |||
| 7f90f04df2 | |||
| 7228d2a824 | |||
| 152e6476d9 | |||
| 15b948d109 | |||
| aff2c7c43c | |||
| 51a42c0647 | |||
| 189fc43765 | |||
| a1641f938e | |||
| 351fb8c058 | |||
| 561421f748 | |||
| 9415560250 | |||
| 511d0fe198 | |||
| bfcc136dc7 | |||
| 94e36d8c8d | |||
| 4ee6852a1e | |||
| 05d5c284f6 | |||
| f19d0ae41d | |||
| 850b1ea2d7 | |||
| 10d2bcc8a2 | |||
| 7ce1bd5d88 | |||
| 2cef100303 | |||
| fecebea2e3 | |||
| 07a0274507 | |||
| 8ff0399432 | |||
| dd2c7c5140 | |||
| ca9756f6a1 | |||
| f351653589 | |||
| 0556450801 | |||
| 1537a5f253 | |||
| ce772b346c | |||
| b1f42a6506 | |||
| cb5921b375 | |||
| 016f9ab16e | |||
| 499e20da4f | |||
| d50c21e571 | |||
| 676d1dfd5b | |||
| acede976e4 | |||
| 90e7c29c46 | |||
| ca6a11e4d2 | |||
| b8579f12be | |||
| 31ec9b2aa7 | |||
| 0c2a43923c | |||
| 63320aba6c | |||
| 2fe9c87433 | |||
| ab4dbff150 | |||
| 01a85736e6 | |||
| 7d5a8053d7 | |||
| b8cf5d8d5f | |||
| 43df944eb4 | |||
| 763a1d7392 | |||
| 5db3092a1f | |||
| be1615b1c3 | |||
| ca9fd66744 | |||
| bdc95d2c66 | |||
| a10385543b | |||
| e80adc0bc6 | |||
| 1b5730a799 | |||
| 01dcfb0825 | |||
| 01b2c5a77c | |||
| 3a45a65625 | |||
| c8776e6ebd | |||
| cf2a3c8e74 | |||
| 277f0d270f | |||
| 3ffed0bf6e | |||
| 557ac3dbaf | |||
| d448a636f8 | |||
| 3c5fec6746 | |||
| 95a07ca11c | |||
| 72c5ac37de | |||
| 1eba7f60c2 | |||
| 0c00d082cf | |||
| faceb05775 | |||
| 8d78400052 | |||
| b4b4d21212 | |||
| 99502e99cc | |||
| 99436bb8cf | |||
| c303aaa94d | |||
| b0563ce368 | |||
| 673eb2b006 | |||
| ef395c3866 | |||
| 4d3d6230c5 | |||
| ea34b2fefb | |||
| 978666c816 | |||
| 0b4c101e8a | |||
| 4e8cd4629c | |||
| 4dfa798e75 | |||
| 2aeb32d2d1 | |||
| 760e9e0943 | |||
| 4cdb4652cf | |||
| 020be63df5 | |||
| 31d624f9a8 | |||
| dbb30134bc | |||
| 8fe9674301 | |||
| 2160f9b20e | |||
| 034a43e7f7 | |||
| ca23c0e630 | |||
| c48473dfe4 | |||
| 7e7bb3027c | |||
| 2a52e44bc6 | |||
| 3af63fe052 | |||
| a1230ad0a0 | |||
| 448a5452d0 | |||
| 4cebef9090 | |||
| d3b68b059b | |||
| 866b15ddb8 | |||
| 7d1c42afe1 | |||
| d594e72586 | |||
| 3ba6b41961 | |||
| 034a5f140c | |||
| 11b08b5ff3 | |||
| 850414a501 | |||
| a560ebf09d | |||
| 72fedbe096 | |||
| d00e58cdb0 | |||
| 3c85745e22 | |||
| 3befdb4ae8 | |||
| 27b71d6368 | |||
| 9b3be01b83 | |||
| 44560c3e50 | |||
| 198b5096aa | |||
| 619180dffd | |||
| 6271192a32 | |||
| c9296e599f | |||
| 90a4d67e8d | |||
| 23bc89d6fc | |||
| 73ddc091a2 | |||
| bce9837604 | |||
| f3a50224f2 | |||
| d4a17da7b2 | |||
| bc036e1e86 | |||
| 8ed89bae84 | |||
| 29d214474f | |||
| 8808aaccff | |||
| 831153d5fb | |||
| 333a767be4 | |||
| db5f1c3554 | |||
| 9c4b1d0a51 | |||
| 98b5fb4b9f | |||
| e93c51762b | |||
| b16c1096d1 | |||
| 4d8d152461 | |||
| cc0066d38d | |||
| b17e9c614b | |||
| 45d073f889 | |||
| 95aa6d7307 | |||
| 2617c9aa64 | |||
| 84bb67e49b | |||
| f2d3edec80 | |||
| 53c0189ed7 | |||
| 43a907ddda | |||
| 5e082ab852 | |||
| 8eafddf211 | |||
| c23ab37355 | |||
| 102ef39a27 | |||
| a41cbbdc99 | |||
| 96b26dc8f4 | |||
| 4fdf4d380c | |||
| 1f695c4532 | |||
| 77dd40c96c | |||
| dae1fc8889 | |||
| a6ef9b4584 | |||
| f3237fdc6e | |||
| cc259e49f6 | |||
| 3efa78311a | |||
| aa2777ed61 | |||
| 8a588f2c0b | |||
| a631196155 | |||
| 98d96f2cc8 | |||
| bd6ab6d38e | |||
| f791cf825f | |||
| 7d998336d3 | |||
| d0d676929d | |||
| 4dffcbd9f0 | |||
| 5baa2c0706 | |||
| 225566da7b | |||
| 0dd1ce1a4f | |||
| c56e91dcc0 | |||
| 20fb9281f4 | |||
| a173ea36f7 | |||
| e569e9dcbd | |||
| 01c1b341a8 | |||
| a9a33d9a5f | |||
| 57c9991413 | |||
| bf2f7b0f8b | |||
| 27edba495a | |||
| 0d456f9111 | |||
| 2ced568d34 | |||
| e037800e46 | |||
| 5542dcb2bc | |||
| 560f85f8e5 | |||
| f856c964e2 | |||
| 5d01821d9f | |||
| 4b2363de5c | |||
| 5265db82c7 | |||
| 1358c0ae66 | |||
| e5ed22bd5b | |||
| 3d14dd4e39 | |||
| 3fe9dfaa2e | |||
| 8b3042da63 | |||
| 65ccafd494 | |||
| 6c93e42d94 | |||
| 7dad0f23d6 | |||
| b3a07166ba | |||
| 282fcb90dc | |||
| a696348ec5 | |||
| d85e67d3ec | |||
| c30af724ef | |||
| 1f8802b94d | |||
| 2b9cfe1e1c | |||
| ed377ac1e8 | |||
| ced3df73da | |||
| 4057e81b76 | |||
| 24ca53183d | |||
| fd369a5004 | |||
| a90dacdf75 | |||
| 4e2ef8c8f5 | |||
| afc8dd5661 | |||
| 52f930cca7 | |||
| 4cb9faf6c9 | |||
| f163778da7 | |||
| 55f2370f36 | |||
| fb61f88b9c | |||
| 1e32781b54 | |||
| e57ceea3d3 | |||
| 1f2b2c5242 | |||
| e4a64760db | |||
| 43a91f82fe | |||
| ccfca869e5 | |||
| f6ec467f19 | |||
| 1996ae4a42 | |||
| dec25e8531 | |||
| 48eecafc89 | |||
| 7b12cbd7dc | |||
| 01f97f150c | |||
| 17a35587e1 | |||
| d76f24567b | |||
| 03a602b6ef | |||
| 9ec3d76b21 | |||
| c4c94f891e | |||
| 4ebd91e637 | |||
| 659ffaddb4 | |||
| 2da7360b63 | |||
| 16bc505d26 | |||
| 89d3f95a8e | |||
| bda89a6469 | |||
| ee4feb4b09 | |||
| 1fac1421e5 | |||
| 4de1efd3c8 | |||
| 545f8a8c93 | |||
| 97b6068c46 | |||
| 71ef76ecad | |||
| 4c86fc13cb | |||
| b379969c63 | |||
| b8e0898c7c | |||
| 61969dc158 | |||
| 8f910d2d49 | |||
| fd4fac946a | |||
| 287874a444 | |||
| c6c8783c60 | |||
| a11f9e1963 | |||
| d427cebd12 | |||
| e5b58b1020 | |||
| 2c0d9fa81f | |||
| cf93df41fc | |||
| ba7b0f4c54 | |||
| 17c485eb03 | |||
| 5b0b59ecfb | |||
| c2b6c67431 | |||
| 4a4ff6749b | |||
| f270e8d040 | |||
| 3cd8976493 | |||
| 92b9888837 | |||
| 121bc50ca9 | |||
| 0d19fa0720 | |||
| b8ef2036b0 | |||
| 8b9982a0a5 | |||
| 6b6c2f6087 | |||
| 9a18330f3a | |||
| c89780dfe0 | |||
| 3fddd3bf93 | |||
| b505cf84de | |||
| 476a02739e | |||
| 544ceedcac | |||
| e0e683aedf | |||
| dd3f517fe9 | |||
| 65d606630d | |||
| ad56838040 | |||
| 202ba124a5 | |||
| a91eca6ec2 | |||
| c0503718cd | |||
| 1ddcfc5c68 | |||
| 9b8ddba4d1 | |||
| b2b6f52d14 | |||
| 15621532b8 | |||
| 774d28efb1 | |||
| c3023fb52b | |||
| ccf415c341 | |||
| 8108fb0575 | |||
| b4a3c92867 | |||
| 72315e7b00 | |||
| 1633c29f29 | |||
| 529a241a26 | |||
| 5e3a7ac8a7 | |||
| 63b154396a | |||
| fbb3f64a1a | |||
| 0dc0bc80ae | |||
| 4b0132ed7a | |||
| 78c5e41c23 | |||
| 01a28db949 | |||
| 53b6fb465c | |||
| a7acb8805f | |||
| fb5e7964b3 | |||
| d9efb55d29 | |||
| 9276f1910b | |||
| ad0ab4109a | |||
| a4d16acd00 | |||
| 744798aadd | |||
| 318cba4ce3 | |||
| cf93217365 | |||
| 0867e3188d | |||
| 1261559305 | |||
| af230ec133 | |||
| fc41c18c6f | |||
| 1acadd363b | |||
| ac2dc29525 | |||
| d1c4e4b5a5 | |||
| beb14c70da | |||
| b5426a8679 | |||
| 7a52a4c134 | |||
| 363976694e | |||
| b6a58818bb | |||
| 5dd3e6052e | |||
| 3d47e043af | |||
| 895fc72a0b | |||
| f42d5399aa | |||
| ad5874779c | |||
| d19bccad74 | |||
| 417034518c | |||
| dcf72e49e2 | |||
| c4c4ac28dc | |||
| a165f55579 | |||
| 0d7f770996 | |||
| 0ca5f68d72 | |||
| 48073e6d95 | |||
| 469addeca3 | |||
| c394847c35 | |||
| ea64bb58a5 | |||
| ea5499fa51 | |||
| 278b4ca40c | |||
| cd6d79d106 | |||
| 02f4d6ca53 | |||
| 8dfba51884 | |||
| 055ffc0425 | |||
| 61d7d67c39 | |||
| 87a692b89e | |||
| 09619c1c45 | |||
| 8bf5bed0a9 | |||
| 5ffeebabad | |||
| e89c1103ff | |||
| fe4f27b99b | |||
| 471b40040a | |||
| 613c12e590 | |||
| 8ec6544624 | |||
| da0fec7308 | |||
| 2477103707 | |||
| 2ff12c4981 | |||
| 194304bbe4 | |||
| cc9b199ecb | |||
| a84969bdcd | |||
| 823e767eed | |||
| e42560bed5 | |||
| d6630ab35b | |||
| 2f30c3fd4f | |||
| 2f9351d995 | |||
| 230e44b01d | |||
| 46206b4814 | |||
| 4c71dbf0af | |||
| 0cf77c3916 | |||
| 9efafc3e33 | |||
| 65573784c4 | |||
| 40215f99d7 | |||
| 9ab5e52f04 | |||
| ec37364762 | |||
| 23288b7cb5 | |||
| 626bfbf309 | |||
| c54753c185 | |||
| 8115b004b9 | |||
| 4429352125 | |||
| c9b2cedebd | |||
| f0058bbed3 | |||
| 3c50d24d8e | |||
| 53c88f0f9e | |||
| d50babfc99 | |||
| 3fb6617d62 | |||
| 3133bb49aa | |||
| 06067efa3f | |||
| 6aa689f87c | |||
| fba9fdfd27 | |||
| 507ca291e1 | |||
| bc927f9788 | |||
| e2a5a6a05c | |||
| 9f4f9000bc | |||
| 6e246ee58c | |||
| 2fef9bc1d8 | |||
| bab8addcbb | |||
| a74fe2ec01 | |||
| a052567db8 | |||
| 2d2330382d | |||
| ee23a7575d | |||
| 9fa6c2ac04 | |||
| 3ece62cb9c | |||
| cd7fa04985 | |||
| b8d4664e6e | |||
| bd5d16ce36 | |||
| e98852a389 | |||
| 08e4ffdf79 | |||
| b4c5b50a3e | |||
| 3ddb005480 | |||
| 1e410ed826 | |||
| 95a55250a7 | |||
| 349f0cf5e9 | |||
| 57b16a4b6e | |||
| 758156a9b6 | |||
| 8747082091 | |||
| 4de115c08c | |||
| 60488ffbbd | |||
| 8b42995e8b | |||
| 84c3bbd934 | |||
| a0d227714e | |||
| bea2c75452 | |||
| 00f36a261b | |||
| b17d16623a | |||
| 61cc855564 | |||
| e736f590f7 | |||
| 6d669dcd7d | |||
| 55c1720719 | |||
| 07f0225ca6 | |||
| f7b5900671 | |||
| 8a7e74673e | |||
| 3c62f3a8e3 | |||
| 48d41ab088 | |||
| e98e58c65a | |||
| 3b9f981358 | |||
| 1661e83939 | |||
| 834c992553 | |||
| 1ae001d10a | |||
| 4e67eb6c42 | |||
| a7b954f655 | |||
| 576644a197 | |||
| 410583e5f9 | |||
| ccecd3405a | |||
| 4700722444 | |||
| 0e92ac2af7 | |||
| b77a0039ee | |||
| b2274a63cd | |||
| 6a439ae53d | |||
| 19a4b51371 | |||
| a41b79d43e | |||
| ec43292e1e | |||
| ea667d82b3 | |||
| 0a02dd5f58 | |||
| 32aba5e64b | |||
| dbf8e22fad | |||
| 0b5d0b83be | |||
| 35e5f00cac | |||
| 290da93845 | |||
| f6bb900259 | |||
| f7f2438478 | |||
| 2ad0487cec | |||
| 72ccb5fe6e | |||
| bf0765fc7f | |||
| 59de4d9ad8 | |||
| 4c168e95de | |||
| 183fc43a67 | |||
| c95407f1bc | |||
| f1ea9d86b9 | |||
| e06efd5329 | |||
| 358d69956a | |||
| 212f0fb509 | |||
| 487d331d74 | |||
| 5e527d22e3 | |||
| 816929c704 | |||
| a9839af903 | |||
| 174b4ce29d | |||
| bca49b99ca | |||
| 6427744063 | |||
| 0757a51e2b | |||
| 290078e0d0 | |||
| 59b0314a0e | |||
| 95eb199f41 | |||
| d659eb9327 | |||
| f17a6b478b | |||
| f18cbd036a | |||
| f9cefc84a3 | |||
| fc85f3644d | |||
| 304e3ac12f | |||
| 778f42ad34 | |||
| f482050f9a | |||
| 4e998c9ade | |||
| 3debb98805 | |||
| ddbd10c001 | |||
| 7c0a43d425 | |||
| 0cf479dd5c | |||
| 1f736a95a7 | |||
| 79859ebca3 | |||
| 5691d998ea | |||
| b10ec8ef8b | |||
| 8313209704 | |||
| 89f23a35c5 | |||
| 293729f48a | |||
| 79310a0051 | |||
| b69bf8a897 | |||
| 426482e05b | |||
| 2734291b35 | |||
| 95c65aff75 | |||
| 3361c59576 | |||
| 8936d55675 | |||
| 199ddff13b | |||
| 985e5014bc | |||
| 8b341884d2 | |||
| a897fc91ec | |||
| e7bb0ecee0 | |||
| 4a28ef8034 | |||
| f6ec0cd827 | |||
| add1df4bcb | |||
| 65d148d9a8 | |||
| c9bd43c0f6 | |||
| c11423df1e | |||
| e629785a97 | |||
| 3a2a74b655 | |||
| 97e88bd769 | |||
| d4501f08b8 | |||
| 2df7736562 | |||
| ee1de8f30d | |||
| bee510dbce | |||
| 571b69bdb6 | |||
| 095f44f4b2 | |||
| 95415ac3a5 | |||
| f6c573880e | |||
| f663e8f903 | |||
| de4d304d90 | |||
| 2a9521661e | |||
| 693877212d | |||
| 8408587341 | |||
| 0fc584961c | |||
| d7744aca02 | |||
| db211446f3 | |||
| 43eba3d750 | |||
| ad49138fae | |||
| 097d81363b | |||
| 2bf8793632 | |||
| bff90d4684 | |||
| 65552bf403 | |||
| 6fdce865b8 | |||
| 453466eb1a | |||
| 49805f976a | |||
| 1666195984 | |||
| 3d345ca4c4 | |||
| 8dd596b7ba | |||
| 719912e46e | |||
| 75c567b6ab | |||
| 0e9a865bbf | |||
| b95e93c20a | |||
| b58b2c5ae8 | |||
| de60600126 | |||
| f4ca2c8e72 | |||
| 46205a7235 | |||
| 974491f93d | |||
| 442bc80cd7 | |||
| f84b08ff08 | |||
| f33f88de31 | |||
| e69ff71302 | |||
| 2b2633c11f | |||
| 729848caeb | |||
| 9cb239247d | |||
| 1b7b2c3a62 | |||
| 7c0a9ff4c1 | |||
| 8d75bfae47 | |||
| 1d2ef6b2a1 | |||
| 7f9a9f2a09 | |||
| 26dfa5e77c | |||
| 7b099e0fe2 | |||
| 66d7956e67 | |||
| 3df83dce7e | |||
| d3c0f4ef98 | |||
| cf9bddcb89 | |||
| 3af1b6ecdc | |||
| 4623e6220f | |||
| ae31115017 | |||
| 6389303c1c | |||
| 5015829ce8 | |||
| 81fad9e247 | |||
| e7dbc4ff28 | |||
| b4d3ff378e | |||
| 6c8ffe81d0 | |||
| 1706a7609a | |||
| d60ac98ef2 | |||
| 3f67623c26 | |||
| 59f4a2e0f3 | |||
| d3d13c41c4 | |||
| f6230ae019 | |||
| 11b020b9f9 | |||
| 987061d800 | |||
| f99f58d99f | |||
| 1aefa6779f | |||
| ddcf388270 | |||
| f3de2b4be7 | |||
| 25e4bce1a6 | |||
| e329c84d5e | |||
| 03a3be0844 | |||
| 76fca0e755 | |||
| db900af8c7 | |||
| 9fd95b93f7 | |||
| ae279966c2 | |||
| 3ccb1d67c2 | |||
| d2d8535a31 | |||
| 419a6d51b3 | |||
| 9f68376c91 | |||
| 216988b0b1 | |||
| 53c771551c | |||
| 43467a2ac7 | |||
| ed96864892 | |||
| d1615ba11a | |||
| 6c6dd16acf | |||
| a6144b8e1a | |||
| 166ecaeda8 | |||
| 2080e06f7b | |||
| 1050b5351e | |||
| 8bf9dda604 | |||
| 54ff72a1cc | |||
| cbb699efd2 | |||
| d9dac9cd1b | |||
| bcf7286ad9 | |||
| 935c02c0a3 | |||
| de977cc9c8 | |||
| e4b9a58c15 | |||
| 3c1267dbe6 | |||
| b4ec8fe3ef | |||
| 6fc6207e93 | |||
| 9003b60d65 | |||
| d93588dfeb | |||
| e21262deba | |||
| b8f9076de0 | |||
| d784b40e24 | |||
| 50af4df1d7 | |||
| b2abd8ca41 | |||
| 2aed9aea47 | |||
| c2e26c1527 | |||
| 610f5481c1 | |||
| 03ec1ca0a4 | |||
| 04caf0549d | |||
| 0e1dd63f5e | |||
| e28e3c9491 | |||
| 076ee65c85 | |||
| 834d438d6e | |||
| f5801ee7da | |||
| faca45a7ea | |||
| e8ac7a34dd | |||
| c9f3f4d1d3 | |||
| 7b8ce63730 | |||
| ffaf4d5da4 | |||
| fb326a3589 | |||
| f81886d17c | |||
| d0032b0717 | |||
| 8120595c3e | |||
| 44bd849697 | |||
| 8af96248bf | |||
| f439fc4306 | |||
| 25247b9f6e | |||
| c024edb9a8 | |||
| 1f517b8a02 | |||
| 7ad5d21900 | |||
| a56c12278e | |||
| 4635356435 | |||
| d68e722b71 | |||
| 5cb0eded64 | |||
| 15bb0b86ce | |||
| 64168fc20a | |||
| 072b524e02 | |||
| 371bba8f54 | |||
| 2eaf35eb63 | |||
| 0b9d53829f | |||
| c9fc27b337 | |||
| aa1359dc19 | |||
| 4c2100e02c | |||
| 473941c341 | |||
| 4001346a30 | |||
| ee7255aac4 | |||
| 5dc606097c | |||
| 14843679af | |||
| 785a540ebd | |||
| d2854448c2 | |||
| cd6d8048bb | |||
| 3d7a3a51a7 | |||
| b4e2c99346 | |||
| 33dde339fe | |||
| 066c074b66 | |||
| 142a524d2f | |||
| 7142f46d1c | |||
| f2803aba07 | |||
| 45428b897f | |||
| 50a6f9d251 | |||
| 360758e8ae | |||
| 8afb2f0cb7 | |||
| 7442100caa | |||
| 52cd1dacbf | |||
| 62775660d1 | |||
| f75152a597 | |||
| b761ec0132 | |||
| c7c987843c | |||
| 73191ad3ec | |||
| 769d2f4c44 | |||
| 90df5e00b4 | |||
| 8c25a8eb7b | |||
| f147ba16e2 | |||
| c43371f190 | |||
| fbed33cc1f | |||
| a509ec0d91 | |||
| 40da61a314 | |||
| f473b61585 | |||
| 6501cb93a4 | |||
| 0d1a0b126b | |||
| 9a202c1522 | |||
| e8a0bc5794 | |||
| e783e6677e | |||
| 8518d078d7 | |||
| 3a1ccd5f43 | |||
| 6e90b85cae | |||
| dd2823aaec | |||
| 00171ca935 | |||
| 9c748beef5 | |||
| 26087e28ad | |||
| 17ad33c919 | |||
| 1ed47900d8 | |||
| d338644159 | |||
| bd1fd59fc1 | |||
| 1fa3d21f6a | |||
| 3f42122387 | |||
| f73b4f4a26 | |||
| a534af68b8 | |||
| 6e2ede8c56 | |||
| 8c0b0714e7 | |||
| 55f02d8c66 | |||
| 49093d6d38 | |||
| d71977b4dd | |||
| a1ef612662 | |||
| 4f9a99141e | |||
| 713d91b04e | |||
| 332c37f332 | |||
| b46fa2e556 | |||
| 25a9a32f8e | |||
| 11fd9e5fdc | |||
| 403f11fdbf | |||
| b4cba524d3 | |||
| 746cd1e1e6 | |||
| 19cf511895 | |||
| 6b31f58092 | |||
| 7444f0c651 | |||
| dd37c10d4a | |||
| dd262b7087 | |||
| 65e76adeda | |||
| c0d41f05d6 | |||
| 9a6f2630b2 | |||
| 939ea4ba30 | |||
| c3cf35ab63 | |||
| 4188e8aaf9 | |||
| 9702987209 | |||
| 8bde6aea4b | |||
| f1d9666a20 | |||
| c0076b58cd | |||
| 00e8c7810f | |||
| 322115bfcf | |||
| a6160b6994 | |||
| abfcb60118 | |||
| 406392e13d | |||
| 7b7d21ebef | |||
| 54a1bbe1c4 | |||
| caf438c63b | |||
| dfef04b325 | |||
| f8ac46ba07 | |||
| 997b7b18af | |||
| f414c16c13 | |||
| c6f39870ff | |||
| b1cc114b7b | |||
| 766fd20faa | |||
| 315e7fbbee | |||
| fcec053d59 | |||
| d073215f10 | |||
| 665408e57f | |||
| ea3dc78986 | |||
| a65ccc0603 | |||
| e2dbf054ac | |||
| 62f3c9bfa9 | |||
| 287ee9d0ea | |||
| 3c6d5aba22 | |||
| eeb6f7726e | |||
| 631b246881 | |||
| e1c8256602 | |||
| 5728679fd5 | |||
| a6af9c75e9 | |||
| 6de86e325f | |||
| 48e471fdd4 | |||
| e5917a8fa5 | |||
| 49a43dfc8f | |||
| 40959fcc61 | |||
| 55770c9853 | |||
| 2ea4626911 | |||
| c8a89134a7 | |||
| 53c2ebf7f6 | |||
| 7e2ebecd52 | |||
| 581d0ef8a9 | |||
| a9c1af39d6 | |||
| 5f419c014f | |||
| ed7607935e | |||
| 78da679472 | |||
| 2f89158339 | |||
| 27d15894d8 | |||
| 79e13be04c | |||
| c72a855214 | |||
| fd08d0d80d | |||
| d93ec07dd8 | |||
| 6b96512d46 | |||
| a9cf01113a | |||
| 85ade61ef7 | |||
| 3d44e9ad92 | |||
| a8fb72a807 | |||
| 73959fed45 | |||
| e267342108 | |||
| 757411bffc | |||
| 6142b21dd5 | |||
| b363489702 | |||
| dae03273cd | |||
| be6a837e15 | |||
| e1f5b886fb | |||
| c9ad5779f2 | |||
| 26c5b0c71f | |||
| 1dee705074 | |||
| f9c951440d | |||
| 578ea4bae9 | |||
| 6bcf0b5519 | |||
| e82d03ef61 | |||
| eedd7bfd50 | |||
| cbf80117af | |||
| 2b35c1708b | |||
| e093a19c70 | |||
| 6fbcb283b9 | |||
| 7fb70e1701 | |||
| 2fb409b286 | |||
| d5f430cc11 | |||
| fd27d5ea00 | |||
| 493611ace5 | |||
| e058febaad | |||
| d7f60f69f1 | |||
| 4b33910449 | |||
| 0c16d8f6c3 | |||
| 5340073770 | |||
| 384ac63490 | |||
| d38676085a | |||
| d8583b2c7a | |||
| 82227b5ace | |||
| c8f934b5b1 | |||
| a4111fab39 | |||
| 54de51ef3c | |||
| 0915df5b18 | |||
| 81e7c7d8c8 | |||
| ea64e860de | |||
| e70786e05e | |||
| cab15f6c5e | |||
| e82e672a93 | |||
| 93971a53d9 | |||
| 09b3dcb6db | |||
| ef42baf9f0 | |||
| e55ad25355 | |||
| 80a3d7bffa | |||
| 6481397710 | |||
| 388ccda85d | |||
| 2e0150e601 | |||
| 2dc5e245d0 | |||
| ea3a5950a3 | |||
| 4e8311085f | |||
| cf0be1a0af | |||
| c577c2cc6a | |||
| 905d96dd4a | |||
| 197285d12a | |||
| ab430b8c87 | |||
| d1029faa90 | |||
| 6374b99a1a | |||
| 4fb9bce79f | |||
| 487f631243 | |||
| c928c21fe7 | |||
| 59fa477edb | |||
| 992d5b8bcd | |||
| 6808d33b2f | |||
| 966f27df34 | |||
| 21bb17e3ee | |||
| 4ba4901ca9 | |||
| 9de63c1edd | |||
| 51cc78b2a2 | |||
| 8f4e5c2fb8 | |||
| db1c8b3f9e | |||
| f07856eab9 | |||
| dd952f6d68 | |||
| e63efe2978 | |||
| fb6929ac3d | |||
| 4e65283081 | |||
| c6daa4aa16 | |||
| c0016d7fe9 | |||
| a518e7063d | |||
| de8696aa43 | |||
| 02cc1cd6e6 | |||
| 0e6cf41923 | |||
| 7579cd8068 | |||
| b6a447798a | |||
| 9344d0d0e3 | |||
| 7fa7fa0226 | |||
| a3df05d93b | |||
| 798e2779f2 | |||
| 1b13df5368 | |||
| 083332f85f | |||
| 6757c2c5a6 | |||
| 59e2ca16d9 | |||
| 75ed282b20 | |||
| 754956857c | |||
| f6ee03471d | |||
| a4ab60920f | |||
| a574788e89 | |||
| 22dbcf98c5 | |||
| d7540c9a3c | |||
| bea312bd65 | |||
| 3705648c9b | |||
| 940dc1f2b7 | |||
| f54b230906 | |||
| 3bbc4e44c3 | |||
| f81370232a | |||
| 85fad1504a | |||
| 1d10d56651 | |||
| ef5d921eac | |||
| 8409aa9eba | |||
| ca9aa180c1 | |||
| ce46cc9852 | |||
| 39f327acdb | |||
| 6189b47648 | |||
| dd6f5949c2 | |||
| a62539489d | |||
| d6b2739525 | |||
| 846a500fb4 | |||
| 8b7f805642 | |||
| cc5190eb91 | |||
| 4eff798270 | |||
| 4e40e5bb88 | |||
| a456b968cf | |||
| a6387c3012 | |||
| 5f2074d757 | |||
| 2a9c81eb25 | |||
| 65fb8ae33e | |||
| dc88c9f3a2 | |||
| fc3fc6005e | |||
| 27fd913c86 | |||
| e0e828ef5c | |||
| 9992c4d275 | |||
| ab65b9745b | |||
| 4e3ab026fe | |||
| f5b212a9d4 | |||
| e31eb46123 | |||
| 326be0d7ba | |||
| e5c39ed48a | |||
| 0d65397ae7 | |||
| a7f30391d0 | |||
| c96850ba59 | |||
| 5459c11e99 | |||
| e755a2a6e4 | |||
| 1913482cf5 | |||
| c7d04c6c5c | |||
| 1ba7c728a6 | |||
| be9b676db3 | |||
| 75a6eaf147 | |||
| 10e1c2b3cd | |||
| a1dd30ed50 | |||
| f74f1a94fe | |||
| 96bf26611e | |||
| 841741aa52 | |||
| 8f15a609af | |||
| 8cdf7bb84b | |||
| 6fb780eae6 | |||
| 858ba6c798 | |||
| 386733aea1 | |||
| 11eafca3e2 | |||
| 5087ff0814 | |||
| ebc8015638 | |||
| 35c7cab742 | |||
| c1921f1b12 | |||
| 9b978afaa2 | |||
| 997ad12730 | |||
| 777eaa7352 | |||
| bb61a2547a | |||
| 5869415a57 | |||
| b5248da826 | |||
| b059a361dd | |||
| 3c99dc96b1 | |||
| dadba232de | |||
| 787f5236a9 | |||
| 31498ebbea | |||
| 9636ffc471 | |||
| b17e1531d2 | |||
| 05dc645b81 | |||
| d4f038dfcc | |||
| c972c94662 | |||
| 33c9d57c6f | |||
| 2c6f1ab57d | |||
| 000110e760 | |||
| 7a686a0c43 | |||
| 835e4b6de9 | |||
| 0a5301bc5b | |||
| 3a4bc0d41e | |||
| cfb02b5370 | |||
| b8175f8976 | |||
| 182f43b6f9 | |||
| 6d2a97e954 | |||
| 66e4ace39f | |||
| a920ed9e1e | |||
| 6c8ec5336f | |||
| 687fa6a8ca | |||
| 32797515de | |||
| 0f622206e4 | |||
| ca55982669 | |||
| ea67060081 | |||
| 2dfaad3259 | |||
| 06ffa408ce | |||
| 34e9d1eb3c | |||
| 3914c17b0d | |||
| c92e0838c1 | |||
| 443fed796a | |||
| 08536943ad | |||
| 936523ae52 | |||
| 7fff245f87 | |||
| 6e3ea8b49d | |||
| 220b278575 | |||
| 2b022311a4 | |||
| 853f5111c2 | |||
| 65ab6ed59f | |||
| 389aae59ae | |||
| c9abb823a7 | |||
| e6dd9a78ae | |||
| e0c888acf7 | |||
| 50bec53afc | |||
| 828091cfbb | |||
| eb981cc7d7 | |||
| 31be03a805 | |||
| ca3848d773 | |||
| e6d9486a6c | |||
| 9a8e47a766 | |||
| 13f244b6a5 | |||
| 28556f1498 | |||
| 0ccd810738 | |||
| e959f449ae | |||
| e4aea680b9 | |||
| 5d3822f15e | |||
| 465ae048a0 | |||
| 71009c9b4d | |||
| dbed39a931 | |||
| ea31c09384 | |||
| 329a1fb781 | |||
| 043e7e3516 | |||
| 9c23f2f1a6 | |||
| 5e9750d1f5 | |||
| 2180a67670 | |||
| 1188c6fe14 | |||
| a2e754c136 | |||
| 5339ef3004 | |||
| 6a2b3c8d4c | |||
| edacd91a27 | |||
| 5dd46b54c1 | |||
| ea502b6e84 | |||
| 954536073d | |||
| cc45c10f3d | |||
| 13aa23f706 | |||
| 78b51fb574 | |||
| 922d5796b9 | |||
| f0ddc2a53c | |||
| d5d059690f | |||
| fd832bb57d | |||
| 09cb329d73 | |||
| 4a9291fd89 | |||
| 5115e5decb | |||
| 1ed9ff17e1 | |||
| f1fdfa1a51 | |||
| 0f3fe957f5 | |||
| fc4679d4cf | |||
| 35c53204cb | |||
| f731515628 | |||
| 59bf2a34fa | |||
| abbb73e894 | |||
| dada5a422d | |||
| 8bb3d363a4 | |||
| 1522722fab | |||
| 8f1f4273a2 | |||
| a9c8a526cf | |||
| 699db77293 | |||
| 690fb0544c | |||
| ae4c72a153 | |||
| ea92c2b1a6 | |||
| 9ac7aea930 | |||
| 5f17cc1abd | |||
| 8f6695acc7 | |||
| 9524abcd28 | |||
| 83efde6243 | |||
| 8eb987e393 | |||
| 2c6ab65476 | |||
| 66fdddc339 | |||
| 5575171652 | |||
| a8b0db4e5d | |||
| e104fcc000 | |||
| e4f71994c2 | |||
| 29e88e50ff | |||
| 852f061b26 | |||
| f0d277e452 | |||
| 2e8483bd1c | |||
| 3eec8fd0eb | |||
| d8d025c33b | |||
| 8811dabbac | |||
| efca746d36 | |||
| e0f524d3b7 | |||
| d1c842cf29 | |||
| 4d23a5d92d | |||
| 0739d1c2eb | |||
| 475c775b25 | |||
| b7e8ce4523 | |||
| e8fcd721b8 | |||
| ef5579dc86 | |||
| 84ae8097b1 | |||
| 295b988657 | |||
| 68942affdb | |||
| e0980c4d73 | |||
| c5920df159 | |||
| 86ddff0b88 | |||
| 908978d00b | |||
| a956732874 | |||
| 879e046b22 | |||
| 5fb0f34e8a | |||
| 861415133e | |||
| fce75cd858 | |||
| b6d5565df1 | |||
| 53ad291ef1 | |||
| 145d3ba99d | |||
| e6171d17f8 | |||
| aa1c86f95e | |||
| 699565828d | |||
| 38de2a8754 | |||
| 8b661cde15 | |||
| e628fd7bce | |||
| 808ba552c5 | |||
| a024593fa6 | |||
| 87b5737293 | |||
| b80c978f5d | |||
| 10ae0c4364 | |||
| cb3ae1232b | |||
| e73e393c82 | |||
| b01f63835e | |||
| 6d7f5871db | |||
| 89720ae24d | |||
| 9097ccf515 | |||
| dca657a2fd | |||
| df8b057b44 | |||
| 64b3c1e691 | |||
| 15aee09c7f | |||
| 80610ca054 | |||
| fd0df5a89b | |||
| b487e2df0b | |||
| c6ed2bf9aa | |||
| 40b1dc12de | |||
| 8eba3c1e7e | |||
| b50c70bbfa | |||
| af021e79d9 | |||
| 73bfe68821 | |||
| 4a73b4859f | |||
| f5d181db3a | |||
| da7e1cfb49 | |||
| 43b64140ae | |||
| d74b98c3d9 | |||
| e0bfe44cac | |||
| 10fb88d027 | |||
| f826709452 | |||
| f10fd64630 | |||
| 09837928d9 | |||
| dce4e94f02 | |||
| ee6415bd1c | |||
| 78835ad87a | |||
| 4e6be21a44 | |||
| f89e4e7dd0 | |||
| dfa8467a08 | |||
| 669ee0415a | |||
| 367668710c | |||
| 94dea84915 | |||
| 9f1218b00b | |||
| fcfa488250 | |||
| 2bbe31a8f6 | |||
| 7cdb0eafeb | |||
| 90f47eb952 | |||
| 15e57d28f5 | |||
| 532eace7d6 | |||
| d4ac4fcde1 | |||
| c1db75e0c7 | |||
| acfdd0e1fc | |||
| 9fb8f6347f | |||
| 7f73b105ca | |||
| ae8dcdf40d | |||
| ee1e1ce377 | |||
| 6d165dae5e | |||
| 335e61dc47 | |||
| 64380baa85 | |||
| b5eb65e53e | |||
| f1ca05c822 | |||
| 900df21b7d | |||
| 93bad514a8 | |||
| d8cd1d8fcc | |||
| 6356403964 | |||
| e8a14a775e | |||
| 7b90a1e85a | |||
| 49283ec035 | |||
| 7d4bb9428b | |||
| 76eb389761 | |||
| e9a1ccb89a | |||
| db262fa76a | |||
| 4e59d6fd12 | |||
| e136c11c7c | |||
| 0e80f56e44 | |||
| 94758c18de | |||
| e76b375a31 | |||
| 9f5f64e14e | |||
| 4eb2966559 | |||
| 293facbae7 | |||
| 053259fd92 | |||
| da41ac9e60 | |||
| 82c477c9f7 | |||
| 57bead3a5e | |||
| d044ac1c66 | |||
| 9787ab598b | |||
| 7e9b5d9e30 | |||
| 3d141280aa | |||
| 9df7517dea | |||
| 4560909a5e | |||
| 3f65924c45 | |||
| 5e31c82b5b | |||
| 4382bdc859 | |||
| fa66c6b797 | |||
| 2da96be217 | |||
| 43f821afb9 | |||
| 3165baa1f1 | |||
| 9a8a964b69 | |||
| 17888ce0fd | |||
| 051b40f956 | |||
| cc8db99695 | |||
| b39cd06249 | |||
| 46def2fdc1 | |||
| 2195f0cc62 | |||
| 387e92353c | |||
| 2047abd9c3 | |||
| 64f2b1b250 | |||
| 577546ccd9 | |||
| e858c21e1f | |||
| 0d6518aaa0 | |||
| d1a598c652 | |||
| bfc227b8d4 | |||
| 45dd575ed2 | |||
| 80709697e5 | |||
| 1b53a4fccc | |||
| 4bb220bb90 | |||
| e1b3cf5c14 | |||
| 0f298a4203 | |||
| 5e68f35500 | |||
| ba1bd64bf9 | |||
| db88cd1b25 | |||
| 936d2963a2 | |||
| 4378b4d03d | |||
| 6ddef3b7a9 | |||
| 68c92908d5 | |||
| 51e543050c | |||
| 000a13b6a3 | |||
| 84b3b5b4a4 | |||
| 4e83f4c579 | |||
| cd2b188c9a | |||
| 1e0a60be2a | |||
| fc5bba66af | |||
| 4d7d630e92 | |||
| 4b2d1aaeea | |||
| 7e5581cd86 | |||
| 8b6a6d4546 | |||
| 7ae83df8aa | |||
| 779a42678d | |||
| 10ba6a93a6 | |||
| c917be2189 | |||
| c6aa97c9aa | |||
| 250941bd47 | |||
| 5b17a60dde | |||
| b07f772f36 | |||
| d4688e6474 | |||
| e7e29cb63c | |||
| ca922443db | |||
| 2385a5870e | |||
| e567135ed3 | |||
| 98c8584b88 | |||
| 2b2fa58f97 | |||
| 2d54fed3cc | |||
| 964a4d75b4 |
@@ -7,9 +7,9 @@ This is a template helping you to create an issue which can be processed as quic
|
||||
|
||||
##### System information (version)
|
||||
<!-- Example
|
||||
- OpenCV => 3.1
|
||||
- OpenCV => 4.2
|
||||
- Operating System / Platform => Windows 64 Bit
|
||||
- Compiler => Visual Studio 2015
|
||||
- Compiler => Visual Studio 2017
|
||||
-->
|
||||
|
||||
- OpenCV => :grey_question:
|
||||
@@ -28,3 +28,42 @@ This is a template helping you to create an issue which can be processed as quic
|
||||
```
|
||||
or attach as .txt or .zip file
|
||||
-->
|
||||
|
||||
##### Issue submission checklist
|
||||
|
||||
- [ ] I report the issue, it's not a question
|
||||
<!--
|
||||
OpenCV team works with forum.opencv.org, Stack Overflow and other communities
|
||||
to discuss problems. Tickets with questions without a real issue statement will be
|
||||
closed.
|
||||
-->
|
||||
- [ ] I checked the problem with documentation, FAQ, open issues,
|
||||
forum.opencv.org, Stack Overflow, etc and have not found any solution
|
||||
<!--
|
||||
Places to check:
|
||||
* OpenCV documentation: https://docs.opencv.org
|
||||
* FAQ page: https://github.com/opencv/opencv/wiki/FAQ
|
||||
* OpenCV forum: https://forum.opencv.org
|
||||
* OpenCV issue tracker: https://github.com/opencv/opencv/issues?q=is%3Aissue
|
||||
* Stack Overflow branch: https://stackoverflow.com/questions/tagged/opencv
|
||||
-->
|
||||
- [ ] I updated to the latest OpenCV version and the issue is still there
|
||||
<!--
|
||||
master branch for OpenCV 4.x and 3.4 branch for OpenCV 3.x releases.
|
||||
OpenCV team supports only the latest release for each branch.
|
||||
The ticket is closed if the problem is not reproduced with the modern version.
|
||||
-->
|
||||
- [ ] There is reproducer code and related data files: videos, images, onnx, etc
|
||||
<!--
|
||||
The best reproducer -- test case for OpenCV that we can add to the library.
|
||||
Recommendations for media files and binary files:
|
||||
* Try to reproduce the issue with images and videos in opencv_extra repository
|
||||
to reduce attachment size
|
||||
* Use PNG for images, if you report some CV related bug, but not image reader
|
||||
issue
|
||||
* Attach the image as an archive to the ticket, if you report some reader issue.
|
||||
Image hosting services compress images and it breaks the repro code.
|
||||
* Provide ONNX file for some public model or ONNX file with random weights,
|
||||
if you report ONNX parsing or handling issue. Architecture details diagram
|
||||
from netron tool can be very useful too. See https://lutzroeder.github.io/netron/
|
||||
-->
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
name: Bug Report
|
||||
description: Create a report to help us reproduce and fix the bug
|
||||
labels: ["bug"]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
#### Thank you for contributing! Before reporting a bug, please have a look at the [FAQ](https://github.com/opencv/opencv/wiki/FAQ), make sure the issue has no duplicate and hasn't been already addressed by searching through [the existing and past issues](https://github.com/opencv/opencv/issues?page=1&q=is%3Aissue+sort%3Acreated-desc).
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: System Information
|
||||
description: |
|
||||
Please provide the following system information to help us diagnose the bug. For example:
|
||||
|
||||
// example for c++ user
|
||||
OpenCV version: 4.6.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
|
||||
Operating System / Platform: Ubuntu 20.04
|
||||
Python version: 3.9.6
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Detailed description
|
||||
description: |
|
||||
Please provide a clear and concise description of what the bug is and paste the error log below. It helps improving readability if the error log is wrapped in ```` ```triple quotes blocks``` ````.
|
||||
placeholder: |
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
```
|
||||
# error log
|
||||
```
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: |
|
||||
Please provide a minimal example to help us reproduce the bug. Code should be wrapped with ```` ```triple quotes blocks``` ```` to improve readability. If the code is too long, please attach as a file or create and link a public gist: https://gist.github.com.
|
||||
|
||||
Related data files (images, onnx, etc) should be attached below as well. If the data files are too big, feel free to upload them to a online drive, share them and put the link below.
|
||||
placeholder: |
|
||||
```cpp (replace cpp with python if python code)
|
||||
# sample code to reproduce the bug
|
||||
```
|
||||
|
||||
Test data: [image](https://link/to/the/image), [model.onnx](htts://link/to/the/onnx/model)
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Issue submission checklist
|
||||
options:
|
||||
- label: I report the issue, it's not a question
|
||||
required: true
|
||||
- label: I checked the problem with documentation, FAQ, open issues, forum.opencv.org, Stack Overflow, etc and have not found any solution
|
||||
- label: I updated to the latest OpenCV version and the issue is still there
|
||||
- label: There is reproducer code and related data files (videos, images, onnx, etc)
|
||||
@@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Questions
|
||||
url: https://forum.opencv.org/
|
||||
about: Ask questions and discuss with OpenCV community members
|
||||
@@ -0,0 +1,26 @@
|
||||
name: Documentation
|
||||
description: Report an issue related to https://docs.opencv.org/
|
||||
labels: ["category: documentation"]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
#### Thank you for contributing! Before submitting a doc issue, please make sure it has no duplicate by searching through [the existing and past issues](https://github.com/opencv/opencv/issues?page=1&q=is%3Aissue+sort%3Acreated-desc)
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Descripe 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.
|
||||
placeholder: |
|
||||
A clear and concise description of what content in https://docs.opencv.org/ is an issue.
|
||||
|
||||
Link to the doc: https://docs.opencv.org/4.x/d3/d63/classcv_1_1Mat.html
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Fix suggestion
|
||||
description: >
|
||||
Tell us how we could improve the documentation in this regard.
|
||||
@@ -0,0 +1,22 @@
|
||||
name: Feature request
|
||||
description: Submit a request for a new OpenCV feature
|
||||
labels: ["feature"]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
#### Thank you for contributing! Before submitting a feature request, please make sure the request has no duplicate by searching through [the existing and past issues](https://github.com/opencv/opencv/issues?page=1&q=is%3Aissue+sort%3Acreated-desc)
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Descripe the feature and motivation
|
||||
description: |
|
||||
Please provide a clear and concise proposal of the feature and outline the motivation.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: |
|
||||
Add any other context, such as pseudo code, links, diagram, screenshots, to help the community better understand the feature request.
|
||||
@@ -1,9 +1,11 @@
|
||||
<!-- Please use this line to close one or multiple issues when this pullrequest gets merged
|
||||
You can add another line right under the first one:
|
||||
resolves #1234
|
||||
resolves #1235
|
||||
-->
|
||||
### Pull Request Readiness Checklist
|
||||
|
||||
### This pullrequest changes
|
||||
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
|
||||
|
||||
<!-- Please describe what your pullrequest is changing -->
|
||||
- [ ] I agree to contribute to the project under Apache 2 License.
|
||||
- [ ] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
|
||||
- [ ] The PR is proposed to the proper branch
|
||||
- [ ] There is a reference to the original bug report and related work
|
||||
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
|
||||
Patch to opencv_extra has the same branch name.
|
||||
- [ ] The feature is well documented and sample code can be built with the project CMake
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
name: PR:4.x
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- 4.x
|
||||
|
||||
jobs:
|
||||
Ubuntu2004-ARM64:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-ARM64.yaml@main
|
||||
|
||||
Ubuntu2004-ARM64-Debug:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-ARM64-Debug.yaml@main
|
||||
|
||||
Ubuntu2004-x64:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-U20.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
|
||||
|
||||
Windows10-x64:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-W10.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
|
||||
|
||||
iOS:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-iOS.yaml@main
|
||||
|
||||
Android:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-Android.yaml@main
|
||||
|
||||
TIM-VX:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-timvx-backend-tests-4.x.yml@main
|
||||
|
||||
docs:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-4.x-docs.yaml@main
|
||||
@@ -0,0 +1,50 @@
|
||||
name: arm64 build checks
|
||||
|
||||
on: workflow_dispatch
|
||||
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-18.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install dependency packages
|
||||
run: |
|
||||
sudo sed -i -E 's|^deb ([^ ]+) (.*)$|deb [arch=amd64] \1 \2\ndeb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ \2|' /etc/apt/sources.list
|
||||
sudo dpkg --add-architecture arm64
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
crossbuild-essential-arm64 \
|
||||
git \
|
||||
cmake \
|
||||
libpython-dev:arm64 \
|
||||
libpython3-dev:arm64 \
|
||||
python-numpy \
|
||||
python3-numpy
|
||||
|
||||
- name: Fetch opencv_contrib
|
||||
run: |
|
||||
git clone --depth 1 https://github.com/opencv/opencv_contrib.git ../opencv_contrib
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DPYTHON2_INCLUDE_PATH=/usr/include/python2.7/ \
|
||||
-DPYTHON2_LIBRARIES=/usr/lib/aarch64-linux-gnu/libpython2.7.so \
|
||||
-DPYTHON2_NUMPY_INCLUDE_DIRS=/usr/lib/python2.7/dist-packages/numpy/core/include \
|
||||
-DPYTHON3_INCLUDE_PATH=/usr/include/python3.6m/ \
|
||||
-DPYTHON3_LIBRARIES=/usr/lib/aarch64-linux-gnu/libpython3.6m.so \
|
||||
-DPYTHON3_NUMPY_INCLUDE_DIRS=/usr/lib/python3/dist-packages/numpy/core/include \
|
||||
-DCMAKE_TOOLCHAIN_FILE=../platforms/linux/aarch64-gnu.toolchain.cmake \
|
||||
-DOPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules \
|
||||
../
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cd build
|
||||
make -j$(nproc --all)
|
||||
@@ -0,0 +1,27 @@
|
||||
name: lint_python
|
||||
on: workflow_dispatch
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
jobs:
|
||||
lint_python:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- run: pip install --upgrade pip wheel
|
||||
- run: pip install bandit black codespell flake8 flake8-2020 flake8-bugbear
|
||||
flake8-comprehensions isort mypy pytest pyupgrade safety
|
||||
- run: bandit --recursive --skip B101 . || true # B101 is assert statements
|
||||
- run: black --check . || true
|
||||
- run: codespell || true # --ignore-words-list="" --skip="*.css,*.js,*.lock"
|
||||
- run: flake8 . --count --select=E9,F63,F7 --show-source --statistics
|
||||
- run: flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88
|
||||
--show-source --statistics
|
||||
- run: isort --check-only --profile black . || true
|
||||
- run: pip install -r requirements.txt || pip install --editable . || true
|
||||
- run: mkdir --parents --verbose .mypy_cache
|
||||
- run: mypy --ignore-missing-imports --install-types --non-interactive . || true
|
||||
- run: pytest . || true
|
||||
- run: pytest --doctest-modules . || true
|
||||
- run: shopt -s globstar && pyupgrade --py36-plus **/*.py || true
|
||||
- run: safety check
|
||||
@@ -24,3 +24,4 @@ bin/
|
||||
build
|
||||
node_modules
|
||||
CMakeSettings.json
|
||||
xcuserdata/
|
||||
|
||||
Vendored
+5
-1
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 2.8.11 FATAL_ERROR)
|
||||
cmake_minimum_required(VERSION ${MIN_VER_CMAKE} FATAL_ERROR)
|
||||
|
||||
project(Carotene)
|
||||
|
||||
@@ -27,6 +27,10 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(APPLE AND CV_CLANG AND WITH_NEON)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-unused-function)
|
||||
endif()
|
||||
|
||||
add_library(carotene_objs OBJECT EXCLUDE_FROM_ALL
|
||||
${carotene_headers}
|
||||
${carotene_sources}
|
||||
|
||||
Vendored
+3
-1
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)
|
||||
cmake_minimum_required(VERSION ${MIN_VER_CMAKE} FATAL_ERROR)
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckCXXCompilerFlag)
|
||||
@@ -12,6 +12,8 @@ elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64.*|AARCH64.*")
|
||||
set(AARCH64 TRUE)
|
||||
endif()
|
||||
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wunused-function)
|
||||
|
||||
set(TEGRA_COMPILER_FLAGS "")
|
||||
|
||||
if(CV_GCC OR CV_CLANG)
|
||||
|
||||
Vendored
+2
-2
@@ -1296,13 +1296,13 @@ struct MorphCtx
|
||||
CAROTENE_NS::BORDER_MODE border;
|
||||
uchar borderValues[4];
|
||||
};
|
||||
inline int TEGRA_MORPHINIT(cvhalFilter2D **context, int operation, int src_type, int dst_type, int, int,
|
||||
inline int TEGRA_MORPHINIT(cvhalFilter2D **context, int operation, int src_type, int dst_type, int width, int height,
|
||||
int kernel_type, uchar *kernel_data, size_t kernel_step, int kernel_width, int kernel_height, int anchor_x, int anchor_y,
|
||||
int borderType, const double borderValue[4], int iterations, bool allowSubmatrix, bool allowInplace)
|
||||
{
|
||||
if(!context || !kernel_data || src_type != dst_type ||
|
||||
CV_MAT_DEPTH(src_type) != CV_8U || src_type < 0 || (src_type >> CV_CN_SHIFT) > 3 ||
|
||||
|
||||
width < kernel_width || height < kernel_height ||
|
||||
allowSubmatrix || allowInplace || iterations != 1 ||
|
||||
!CAROTENE_NS::isSupportedConfiguration())
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
+18
-18
@@ -109,9 +109,9 @@ template <> struct wAdd<s32>
|
||||
vgamma = vdupq_n_f32(_gamma + 0.5);
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<s32>::vec128 & v_src0,
|
||||
const typename VecTraits<s32>::vec128 & v_src1,
|
||||
typename VecTraits<s32>::vec128 & v_dst) const
|
||||
void operator() (const VecTraits<s32>::vec128 & v_src0,
|
||||
const VecTraits<s32>::vec128 & v_src1,
|
||||
VecTraits<s32>::vec128 & v_dst) const
|
||||
{
|
||||
float32x4_t vs1 = vcvtq_f32_s32(v_src0);
|
||||
float32x4_t vs2 = vcvtq_f32_s32(v_src1);
|
||||
@@ -121,9 +121,9 @@ template <> struct wAdd<s32>
|
||||
v_dst = vcvtq_s32_f32(vs1);
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<s32>::vec64 & v_src0,
|
||||
const typename VecTraits<s32>::vec64 & v_src1,
|
||||
typename VecTraits<s32>::vec64 & v_dst) const
|
||||
void operator() (const VecTraits<s32>::vec64 & v_src0,
|
||||
const VecTraits<s32>::vec64 & v_src1,
|
||||
VecTraits<s32>::vec64 & v_dst) const
|
||||
{
|
||||
float32x2_t vs1 = vcvt_f32_s32(v_src0);
|
||||
float32x2_t vs2 = vcvt_f32_s32(v_src1);
|
||||
@@ -153,9 +153,9 @@ template <> struct wAdd<u32>
|
||||
vgamma = vdupq_n_f32(_gamma + 0.5);
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<u32>::vec128 & v_src0,
|
||||
const typename VecTraits<u32>::vec128 & v_src1,
|
||||
typename VecTraits<u32>::vec128 & v_dst) const
|
||||
void operator() (const VecTraits<u32>::vec128 & v_src0,
|
||||
const VecTraits<u32>::vec128 & v_src1,
|
||||
VecTraits<u32>::vec128 & v_dst) const
|
||||
{
|
||||
float32x4_t vs1 = vcvtq_f32_u32(v_src0);
|
||||
float32x4_t vs2 = vcvtq_f32_u32(v_src1);
|
||||
@@ -165,9 +165,9 @@ template <> struct wAdd<u32>
|
||||
v_dst = vcvtq_u32_f32(vs1);
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<u32>::vec64 & v_src0,
|
||||
const typename VecTraits<u32>::vec64 & v_src1,
|
||||
typename VecTraits<u32>::vec64 & v_dst) const
|
||||
void operator() (const VecTraits<u32>::vec64 & v_src0,
|
||||
const VecTraits<u32>::vec64 & v_src1,
|
||||
VecTraits<u32>::vec64 & v_dst) const
|
||||
{
|
||||
float32x2_t vs1 = vcvt_f32_u32(v_src0);
|
||||
float32x2_t vs2 = vcvt_f32_u32(v_src1);
|
||||
@@ -197,17 +197,17 @@ template <> struct wAdd<f32>
|
||||
vgamma = vdupq_n_f32(_gamma + 0.5);
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<f32>::vec128 & v_src0,
|
||||
const typename VecTraits<f32>::vec128 & v_src1,
|
||||
typename VecTraits<f32>::vec128 & v_dst) const
|
||||
void operator() (const VecTraits<f32>::vec128 & v_src0,
|
||||
const VecTraits<f32>::vec128 & v_src1,
|
||||
VecTraits<f32>::vec128 & v_dst) const
|
||||
{
|
||||
float32x4_t vs1 = vmlaq_f32(vgamma, v_src0, valpha);
|
||||
v_dst = vmlaq_f32(vs1, v_src1, vbeta);
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<f32>::vec64 & v_src0,
|
||||
const typename VecTraits<f32>::vec64 & v_src1,
|
||||
typename VecTraits<f32>::vec64 & v_dst) const
|
||||
void operator() (const VecTraits<f32>::vec64 & v_src0,
|
||||
const VecTraits<f32>::vec64 & v_src1,
|
||||
VecTraits<f32>::vec64 & v_dst) const
|
||||
{
|
||||
float32x2_t vs1 = vmla_f32(vget_low(vgamma), v_src0, vget_low(valpha));
|
||||
v_dst = vmla_f32(vs1, v_src1, vget_low(vbeta));
|
||||
|
||||
Vendored
+1
-1
@@ -391,9 +391,9 @@ void blur3x3(const Size2D &size, s32 cn,
|
||||
}
|
||||
else if (borderType == BORDER_MODE_REFLECT101)
|
||||
{
|
||||
tcurr = vsetq_lane_u16(vgetq_lane_u16(tcurr, 3),tcurr, 5);
|
||||
tcurr = vsetq_lane_u16(vgetq_lane_u16(tcurr, 4),tcurr, 6);
|
||||
tcurr = vsetq_lane_u16(vgetq_lane_u16(tcurr, 5),tcurr, 7);
|
||||
tcurr = vsetq_lane_u16(vgetq_lane_u16(tcurr, 3),tcurr, 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+4
-4
@@ -49,12 +49,12 @@ namespace {
|
||||
|
||||
enum
|
||||
{
|
||||
SHIFT = 14,
|
||||
SHIFT = 15,
|
||||
SHIFT_DELTA = 1 << (SHIFT - 1),
|
||||
|
||||
R2Y_BT601 = 4899,
|
||||
G2Y_BT601 = 9617,
|
||||
B2Y_BT601 = 1868,
|
||||
R2Y_BT601 = 9798,
|
||||
G2Y_BT601 = 19235,
|
||||
B2Y_BT601 = 3735,
|
||||
|
||||
R2Y_BT709 = 3483,
|
||||
G2Y_BT709 = 11718,
|
||||
|
||||
Vendored
+22
-36
@@ -151,6 +151,10 @@ void div(const Size2D &size,
|
||||
typedef typename internal::VecTraits<T>::vec128 vec128;
|
||||
typedef typename internal::VecTraits<T>::vec64 vec64;
|
||||
|
||||
#if defined(__GNUC__) && (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L)
|
||||
static_assert(std::numeric_limits<T>::is_integer, "template implementation is for integer types only");
|
||||
#endif
|
||||
|
||||
if (scale == 0.0f ||
|
||||
(std::numeric_limits<T>::is_integer &&
|
||||
(scale * std::numeric_limits<T>::max()) < 1.0f &&
|
||||
@@ -311,6 +315,10 @@ void recip(const Size2D &size,
|
||||
typedef typename internal::VecTraits<T>::vec128 vec128;
|
||||
typedef typename internal::VecTraits<T>::vec64 vec64;
|
||||
|
||||
#if defined(__GNUC__) && (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L)
|
||||
static_assert(std::numeric_limits<T>::is_integer, "template implementation is for integer types only");
|
||||
#endif
|
||||
|
||||
if (scale == 0.0f ||
|
||||
(std::numeric_limits<T>::is_integer &&
|
||||
scale < 1.0f &&
|
||||
@@ -463,8 +471,6 @@ void div(const Size2D &size,
|
||||
return;
|
||||
}
|
||||
|
||||
float32x4_t v_zero = vdupq_n_f32(0.0f);
|
||||
|
||||
size_t roiw128 = size.width >= 3 ? size.width - 3 : 0;
|
||||
size_t roiw64 = size.width >= 1 ? size.width - 1 : 0;
|
||||
|
||||
@@ -485,9 +491,7 @@ void div(const Size2D &size,
|
||||
float32x4_t v_src0 = vld1q_f32(src0 + j);
|
||||
float32x4_t v_src1 = vld1q_f32(src1 + j);
|
||||
|
||||
uint32x4_t v_mask = vceqq_f32(v_src1,v_zero);
|
||||
vst1q_f32(dst + j, vreinterpretq_f32_u32(vbicq_u32(
|
||||
vreinterpretq_u32_f32(vmulq_f32(v_src0, internal::vrecpq_f32(v_src1))), v_mask)));
|
||||
vst1q_f32(dst + j, vmulq_f32(v_src0, internal::vrecpq_f32(v_src1)));
|
||||
}
|
||||
|
||||
for (; j < roiw64; j += 2)
|
||||
@@ -495,14 +499,12 @@ void div(const Size2D &size,
|
||||
float32x2_t v_src0 = vld1_f32(src0 + j);
|
||||
float32x2_t v_src1 = vld1_f32(src1 + j);
|
||||
|
||||
uint32x2_t v_mask = vceq_f32(v_src1,vget_low_f32(v_zero));
|
||||
vst1_f32(dst + j, vreinterpret_f32_u32(vbic_u32(
|
||||
vreinterpret_u32_f32(vmul_f32(v_src0, internal::vrecp_f32(v_src1))), v_mask)));
|
||||
vst1_f32(dst + j, vmul_f32(v_src0, internal::vrecp_f32(v_src1)));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = src1[j] ? src0[j] / src1[j] : 0.0f;
|
||||
dst[j] = src0[j] / src1[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -523,10 +525,8 @@ void div(const Size2D &size,
|
||||
float32x4_t v_src0 = vld1q_f32(src0 + j);
|
||||
float32x4_t v_src1 = vld1q_f32(src1 + j);
|
||||
|
||||
uint32x4_t v_mask = vceqq_f32(v_src1,v_zero);
|
||||
vst1q_f32(dst + j, vreinterpretq_f32_u32(vbicq_u32(
|
||||
vreinterpretq_u32_f32(vmulq_f32(vmulq_n_f32(v_src0, scale),
|
||||
internal::vrecpq_f32(v_src1))), v_mask)));
|
||||
vst1q_f32(dst + j, vmulq_f32(vmulq_n_f32(v_src0, scale),
|
||||
internal::vrecpq_f32(v_src1)));
|
||||
}
|
||||
|
||||
for (; j < roiw64; j += 2)
|
||||
@@ -534,15 +534,13 @@ void div(const Size2D &size,
|
||||
float32x2_t v_src0 = vld1_f32(src0 + j);
|
||||
float32x2_t v_src1 = vld1_f32(src1 + j);
|
||||
|
||||
uint32x2_t v_mask = vceq_f32(v_src1,vget_low_f32(v_zero));
|
||||
vst1_f32(dst + j, vreinterpret_f32_u32(vbic_u32(
|
||||
vreinterpret_u32_f32(vmul_f32(vmul_n_f32(v_src0, scale),
|
||||
internal::vrecp_f32(v_src1))), v_mask)));
|
||||
vst1_f32(dst + j, vmul_f32(vmul_n_f32(v_src0, scale),
|
||||
internal::vrecp_f32(v_src1)));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = src1[j] ? src0[j] * scale / src1[j] : 0.0f;
|
||||
dst[j] = src0[j] * scale / src1[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -620,8 +618,6 @@ void reciprocal(const Size2D &size,
|
||||
return;
|
||||
}
|
||||
|
||||
float32x4_t v_zero = vdupq_n_f32(0.0f);
|
||||
|
||||
size_t roiw128 = size.width >= 3 ? size.width - 3 : 0;
|
||||
size_t roiw64 = size.width >= 1 ? size.width - 1 : 0;
|
||||
|
||||
@@ -639,23 +635,19 @@ void reciprocal(const Size2D &size,
|
||||
|
||||
float32x4_t v_src1 = vld1q_f32(src1 + j);
|
||||
|
||||
uint32x4_t v_mask = vceqq_f32(v_src1,v_zero);
|
||||
vst1q_f32(dst + j, vreinterpretq_f32_u32(vbicq_u32(
|
||||
vreinterpretq_u32_f32(internal::vrecpq_f32(v_src1)), v_mask)));
|
||||
vst1q_f32(dst + j, internal::vrecpq_f32(v_src1));
|
||||
}
|
||||
|
||||
for (; j < roiw64; j += 2)
|
||||
{
|
||||
float32x2_t v_src1 = vld1_f32(src1 + j);
|
||||
|
||||
uint32x2_t v_mask = vceq_f32(v_src1,vget_low_f32(v_zero));
|
||||
vst1_f32(dst + j, vreinterpret_f32_u32(vbic_u32(
|
||||
vreinterpret_u32_f32(internal::vrecp_f32(v_src1)), v_mask)));
|
||||
vst1_f32(dst + j, internal::vrecp_f32(v_src1));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = src1[j] ? 1.0f / src1[j] : 0;
|
||||
dst[j] = 1.0f / src1[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -673,25 +665,19 @@ void reciprocal(const Size2D &size,
|
||||
|
||||
float32x4_t v_src1 = vld1q_f32(src1 + j);
|
||||
|
||||
uint32x4_t v_mask = vceqq_f32(v_src1,v_zero);
|
||||
vst1q_f32(dst + j, vreinterpretq_f32_u32(vbicq_u32(
|
||||
vreinterpretq_u32_f32(vmulq_n_f32(internal::vrecpq_f32(v_src1),
|
||||
scale)),v_mask)));
|
||||
vst1q_f32(dst + j, vmulq_n_f32(internal::vrecpq_f32(v_src1), scale));
|
||||
}
|
||||
|
||||
for (; j < roiw64; j += 2)
|
||||
{
|
||||
float32x2_t v_src1 = vld1_f32(src1 + j);
|
||||
|
||||
uint32x2_t v_mask = vceq_f32(v_src1,vget_low_f32(v_zero));
|
||||
vst1_f32(dst + j, vreinterpret_f32_u32(vbic_u32(
|
||||
vreinterpret_u32_f32(vmul_n_f32(internal::vrecp_f32(v_src1),
|
||||
scale)), v_mask)));
|
||||
vst1_f32(dst + j, vmul_n_f32(internal::vrecp_f32(v_src1), scale));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = src1[j] ? scale / src1[j] : 0;
|
||||
dst[j] = scale / src1[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+1
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
$url = "https://raw.githubusercontent.com/opencv/opencv_3rdparty/@FFMPEG_BINARIES_COMMIT@/ffmpeg/opencv_ffmpeg_64.dll"
|
||||
$url = "https://raw.githubusercontent.com/opencv/opencv_3rdparty/@FFMPEG_BINARIES_COMMIT@/ffmpeg/opencv_videoio_ffmpeg_64.dll"
|
||||
$expected_md5 = "@FFMPEG_FILE_HASH_BIN64@"
|
||||
$output = "$PSScriptRoot\@OPENCV_BIN_INSTALL_PATH@\opencv_ffmpeg@OPENCV_DLLVERSION@_64.dll"
|
||||
$output = "$PSScriptRoot\@OPENCV_BIN_INSTALL_PATH@\opencv_videoio_ffmpeg@OPENCV_DLLVERSION@_64.dll"
|
||||
|
||||
Write-Output ("=" * 120)
|
||||
try {
|
||||
|
||||
Vendored
+8
-8
@@ -1,16 +1,16 @@
|
||||
# Binaries branch name: ffmpeg/3.4_20211220
|
||||
# Binaries were created for OpenCV: a22dd28e0272ec0f1cfee8811d3f5f0392827c65
|
||||
ocv_update(FFMPEG_BINARIES_COMMIT "5a7644ec3940c6eed41c6ebb5a0602a5615fdb3f")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN32 "8ad9de6f1f2ca77786748d1f3a4e83ea")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN64 "2c670f068252e7cd28d3883993dc1d6e")
|
||||
ocv_update(FFMPEG_FILE_HASH_CMAKE "3b90f67f4b429e77d3da36698cef700c")
|
||||
# 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")
|
||||
ocv_update(FFMPEG_FILE_HASH_CMAKE "8862c87496e2e8c375965e1277dee1c7")
|
||||
|
||||
function(download_win_ffmpeg script_var)
|
||||
set(${script_var} "" PARENT_SCOPE)
|
||||
|
||||
set(ids BIN32 BIN64 CMAKE)
|
||||
set(name_BIN32 "opencv_ffmpeg.dll")
|
||||
set(name_BIN64 "opencv_ffmpeg_64.dll")
|
||||
set(name_BIN32 "opencv_videoio_ffmpeg.dll")
|
||||
set(name_BIN64 "opencv_videoio_ffmpeg_64.dll")
|
||||
set(name_CMAKE "ffmpeg_version.cmake")
|
||||
|
||||
set(FFMPEG_DOWNLOAD_DIR "${OpenCV_BINARY_DIR}/3rdparty/ffmpeg")
|
||||
|
||||
Vendored
+4
-4
@@ -13,10 +13,10 @@
|
||||
|
||||
* On Windows OpenCV uses pre-built ffmpeg binaries, built with proper flags (without GPL components) and
|
||||
wrapped with simple, stable OpenCV-compatible API.
|
||||
The binaries are opencv_ffmpeg.dll (version for 32-bit Windows) and
|
||||
opencv_ffmpeg_64.dll (version for 64-bit Windows).
|
||||
The binaries are opencv_videoio_ffmpeg.dll (version for 32-bit Windows) and
|
||||
opencv_videoio_ffmpeg_64.dll (version for 64-bit Windows).
|
||||
|
||||
The pre-built opencv_ffmpeg*.dll is:
|
||||
The pre-built opencv_videoio_ffmpeg*.dll is:
|
||||
* LGPL library, not BSD libraries.
|
||||
* Loaded at runtime by opencv_videoio module.
|
||||
If it succeeds, ffmpeg can be used to decode/encode videos;
|
||||
@@ -30,7 +30,7 @@
|
||||
Or you can specify location of binary file via OPENH264_LIBRARY environment variable.
|
||||
|
||||
If LGPL/GPL software can not be supplied with your OpenCV-based product, simply exclude
|
||||
opencv_ffmpeg*.dll from your distribution; OpenCV will stay fully functional except for the ability to
|
||||
opencv_videoio_ffmpeg*.dll from your distribution; OpenCV will stay fully functional except for the ability to
|
||||
decode/encode videos using FFMPEG (though, it may still be able to do that using other API,
|
||||
such as Video for Windows, Windows Media Foundation or our self-contained motion jpeg codec).
|
||||
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2008-2020 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.
|
||||
******************************************************************************/
|
||||
/*****************************************************************************\
|
||||
|
||||
Copyright (c) 2013-2019 Intel Corporation All Rights Reserved.
|
||||
|
||||
THESE MATERIALS ARE 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 INTEL OR ITS
|
||||
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 THESE
|
||||
MATERIALS, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
File Name: cl_va_api_media_sharing_intel.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Notes:
|
||||
|
||||
\*****************************************************************************/
|
||||
|
||||
|
||||
#ifndef __OPENCL_CL_VA_API_MEDIA_SHARING_INTEL_H
|
||||
#define __OPENCL_CL_VA_API_MEDIA_SHARING_INTEL_H
|
||||
|
||||
#include <CL/cl.h>
|
||||
#include <CL/cl_platform.h>
|
||||
#include <va/va.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************
|
||||
* cl_intel_va_api_media_sharing extension *
|
||||
*******************************************/
|
||||
|
||||
#define cl_intel_va_api_media_sharing 1
|
||||
|
||||
/* error codes */
|
||||
#define CL_INVALID_VA_API_MEDIA_ADAPTER_INTEL -1098
|
||||
#define CL_INVALID_VA_API_MEDIA_SURFACE_INTEL -1099
|
||||
#define CL_VA_API_MEDIA_SURFACE_ALREADY_ACQUIRED_INTEL -1100
|
||||
#define CL_VA_API_MEDIA_SURFACE_NOT_ACQUIRED_INTEL -1101
|
||||
|
||||
/* cl_va_api_device_source_intel */
|
||||
#define CL_VA_API_DISPLAY_INTEL 0x4094
|
||||
|
||||
/* cl_va_api_device_set_intel */
|
||||
#define CL_PREFERRED_DEVICES_FOR_VA_API_INTEL 0x4095
|
||||
#define CL_ALL_DEVICES_FOR_VA_API_INTEL 0x4096
|
||||
|
||||
/* cl_context_info */
|
||||
#define CL_CONTEXT_VA_API_DISPLAY_INTEL 0x4097
|
||||
|
||||
/* cl_mem_info */
|
||||
#define CL_MEM_VA_API_MEDIA_SURFACE_INTEL 0x4098
|
||||
|
||||
/* cl_image_info */
|
||||
#define CL_IMAGE_VA_API_PLANE_INTEL 0x4099
|
||||
|
||||
/* cl_command_type */
|
||||
#define CL_COMMAND_ACQUIRE_VA_API_MEDIA_SURFACES_INTEL 0x409A
|
||||
#define CL_COMMAND_RELEASE_VA_API_MEDIA_SURFACES_INTEL 0x409B
|
||||
|
||||
typedef cl_uint cl_va_api_device_source_intel;
|
||||
typedef cl_uint cl_va_api_device_set_intel;
|
||||
|
||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
||||
clGetDeviceIDsFromVA_APIMediaAdapterINTEL(
|
||||
cl_platform_id platform,
|
||||
cl_va_api_device_source_intel media_adapter_type,
|
||||
void* media_adapter,
|
||||
cl_va_api_device_set_intel media_adapter_set,
|
||||
cl_uint num_entries,
|
||||
cl_device_id* devices,
|
||||
cl_uint* num_devices) CL_EXT_SUFFIX__VERSION_1_2;
|
||||
|
||||
typedef CL_API_ENTRY cl_int (CL_API_CALL * clGetDeviceIDsFromVA_APIMediaAdapterINTEL_fn)(
|
||||
cl_platform_id platform,
|
||||
cl_va_api_device_source_intel media_adapter_type,
|
||||
void* media_adapter,
|
||||
cl_va_api_device_set_intel media_adapter_set,
|
||||
cl_uint num_entries,
|
||||
cl_device_id* devices,
|
||||
cl_uint* num_devices) CL_EXT_SUFFIX__VERSION_1_2;
|
||||
|
||||
extern CL_API_ENTRY cl_mem CL_API_CALL
|
||||
clCreateFromVA_APIMediaSurfaceINTEL(
|
||||
cl_context context,
|
||||
cl_mem_flags flags,
|
||||
VASurfaceID* surface,
|
||||
cl_uint plane,
|
||||
cl_int* errcode_ret) CL_EXT_SUFFIX__VERSION_1_2;
|
||||
|
||||
typedef CL_API_ENTRY cl_mem (CL_API_CALL * clCreateFromVA_APIMediaSurfaceINTEL_fn)(
|
||||
cl_context context,
|
||||
cl_mem_flags flags,
|
||||
VASurfaceID* surface,
|
||||
cl_uint plane,
|
||||
cl_int* errcode_ret) CL_EXT_SUFFIX__VERSION_1_2;
|
||||
|
||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
||||
clEnqueueAcquireVA_APIMediaSurfacesINTEL(
|
||||
cl_command_queue command_queue,
|
||||
cl_uint num_objects,
|
||||
const cl_mem* mem_objects,
|
||||
cl_uint num_events_in_wait_list,
|
||||
const cl_event* event_wait_list,
|
||||
cl_event* event) CL_EXT_SUFFIX__VERSION_1_2;
|
||||
|
||||
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueAcquireVA_APIMediaSurfacesINTEL_fn)(
|
||||
cl_command_queue command_queue,
|
||||
cl_uint num_objects,
|
||||
const cl_mem* mem_objects,
|
||||
cl_uint num_events_in_wait_list,
|
||||
const cl_event* event_wait_list,
|
||||
cl_event* event) CL_EXT_SUFFIX__VERSION_1_2;
|
||||
|
||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
||||
clEnqueueReleaseVA_APIMediaSurfacesINTEL(
|
||||
cl_command_queue command_queue,
|
||||
cl_uint num_objects,
|
||||
const cl_mem* mem_objects,
|
||||
cl_uint num_events_in_wait_list,
|
||||
const cl_event* event_wait_list,
|
||||
cl_event* event) CL_EXT_SUFFIX__VERSION_1_2;
|
||||
|
||||
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueReleaseVA_APIMediaSurfacesINTEL_fn)(
|
||||
cl_command_queue command_queue,
|
||||
cl_uint num_objects,
|
||||
const cl_mem* mem_objects,
|
||||
cl_uint num_events_in_wait_list,
|
||||
const cl_event* event_wait_list,
|
||||
cl_event* event) CL_EXT_SUFFIX__VERSION_1_2;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __OPENCL_CL_VA_API_MEDIA_SHARING_INTEL_H */
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
//
|
||||
// File: vk_platform.h
|
||||
//
|
||||
/*
|
||||
** Copyright (c) 2014-2017 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef VK_PLATFORM_H_
|
||||
#define VK_PLATFORM_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif // __cplusplus
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* Platform-specific directives and type declarations
|
||||
***************************************************************************************************
|
||||
*/
|
||||
|
||||
/* Platform-specific calling convention macros.
|
||||
*
|
||||
* Platforms should define these so that Vulkan clients call Vulkan commands
|
||||
* with the same calling conventions that the Vulkan implementation expects.
|
||||
*
|
||||
* VKAPI_ATTR - Placed before the return type in function declarations.
|
||||
* Useful for C++11 and GCC/Clang-style function attribute syntax.
|
||||
* VKAPI_CALL - Placed after the return type in function declarations.
|
||||
* Useful for MSVC-style calling convention syntax.
|
||||
* VKAPI_PTR - Placed between the '(' and '*' in function pointer types.
|
||||
*
|
||||
* Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void);
|
||||
* Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
|
||||
*/
|
||||
#if defined(_WIN32)
|
||||
// On Windows, Vulkan commands use the stdcall convention
|
||||
#define VKAPI_ATTR
|
||||
#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"
|
||||
#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
|
||||
// is true even if the rest of the application passes floats on the stack,
|
||||
// as it does by default when compiling for the armeabi-v7a NDK ABI.
|
||||
#define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
|
||||
#define VKAPI_CALL
|
||||
#define VKAPI_PTR VKAPI_ATTR
|
||||
#else
|
||||
// On other platforms, use the default calling convention
|
||||
#define VKAPI_ATTR
|
||||
#define VKAPI_CALL
|
||||
#define VKAPI_PTR
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#if !defined(VK_NO_STDINT_H)
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1600)
|
||||
typedef signed __int8 int8_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef signed __int16 int16_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef signed __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef signed __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#endif // !defined(VK_NO_STDINT_H)
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
Vendored
+83
@@ -0,0 +1,83 @@
|
||||
#ifndef VULKAN_H_
|
||||
#define VULKAN_H_ 1
|
||||
|
||||
/*
|
||||
** 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.
|
||||
*/
|
||||
|
||||
#include "vk_platform.h"
|
||||
#include "vulkan_core.h"
|
||||
|
||||
#ifdef VK_USE_PLATFORM_ANDROID_KHR
|
||||
#include "vulkan_android.h"
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_FUCHSIA
|
||||
#include <zircon/types.h>
|
||||
#include "vulkan_fuchsia.h"
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_IOS_MVK
|
||||
#include "vulkan_ios.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef VK_USE_PLATFORM_MACOS_MVK
|
||||
#include "vulkan_macos.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef VK_USE_PLATFORM_MIR_KHR
|
||||
#include <mir_toolkit/client_types.h>
|
||||
#include "vulkan_mir.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
|
||||
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#include <windows.h>
|
||||
#include "vulkan_win32.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
#include <xcb/xcb.h>
|
||||
#include "vulkan_xcb.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
#include <X11/Xlib.h>
|
||||
#include "vulkan_xlib.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include "vulkan_xlib_xrandr.h"
|
||||
#endif
|
||||
|
||||
#endif // VULKAN_H_
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
#ifndef VULKAN_ANDROID_H_
|
||||
#define VULKAN_ANDROID_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_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;
|
||||
VkAndroidSurfaceCreateFlagsKHR flags;
|
||||
struct ANativeWindow* window;
|
||||
} VkAndroidSurfaceCreateInfoKHR;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateAndroidSurfaceKHR)(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR(
|
||||
VkInstance instance,
|
||||
const VkAndroidSurfaceCreateInfoKHR* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
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_EXTENSION_NAME "VK_ANDROID_external_memory_android_hardware_buffer"
|
||||
|
||||
typedef struct VkAndroidHardwareBufferUsageANDROID {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
uint64_t androidHardwareBufferUsage;
|
||||
} VkAndroidHardwareBufferUsageANDROID;
|
||||
|
||||
typedef struct VkAndroidHardwareBufferPropertiesANDROID {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkDeviceSize allocationSize;
|
||||
uint32_t memoryTypeBits;
|
||||
} VkAndroidHardwareBufferPropertiesANDROID;
|
||||
|
||||
typedef struct VkAndroidHardwareBufferFormatPropertiesANDROID {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkFormat format;
|
||||
uint64_t externalFormat;
|
||||
VkFormatFeatureFlags formatFeatures;
|
||||
VkComponentMapping samplerYcbcrConversionComponents;
|
||||
VkSamplerYcbcrModelConversion suggestedYcbcrModel;
|
||||
VkSamplerYcbcrRange suggestedYcbcrRange;
|
||||
VkChromaLocation suggestedXChromaOffset;
|
||||
VkChromaLocation suggestedYChromaOffset;
|
||||
} VkAndroidHardwareBufferFormatPropertiesANDROID;
|
||||
|
||||
typedef struct VkImportAndroidHardwareBufferInfoANDROID {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
struct AHardwareBuffer* buffer;
|
||||
} VkImportAndroidHardwareBufferInfoANDROID;
|
||||
|
||||
typedef struct VkMemoryGetAndroidHardwareBufferInfoANDROID {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkDeviceMemory memory;
|
||||
} VkMemoryGetAndroidHardwareBufferInfoANDROID;
|
||||
|
||||
typedef struct VkExternalFormatANDROID {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
uint64_t externalFormat;
|
||||
} VkExternalFormatANDROID;
|
||||
|
||||
|
||||
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);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetAndroidHardwareBufferPropertiesANDROID(
|
||||
VkDevice device,
|
||||
const struct AHardwareBuffer* buffer,
|
||||
VkAndroidHardwareBufferPropertiesANDROID* pProperties);
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryAndroidHardwareBufferANDROID(
|
||||
VkDevice device,
|
||||
const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo,
|
||||
struct AHardwareBuffer** pBuffer);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+8524
File diff suppressed because it is too large
Load Diff
+58
@@ -0,0 +1,58 @@
|
||||
#ifndef VULKAN_FUCHSIA_H_
|
||||
#define VULKAN_FUCHSIA_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_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;
|
||||
VkImagePipeSurfaceCreateFlagsFUCHSIA flags;
|
||||
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
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateImagePipeSurfaceFUCHSIA(
|
||||
VkInstance instance,
|
||||
const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSurfaceKHR* pSurface);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Vendored
+58
@@ -0,0 +1,58 @@
|
||||
#ifndef VULKAN_IOS_H_
|
||||
#define VULKAN_IOS_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_MVK_ios_surface 1
|
||||
#define VK_MVK_IOS_SURFACE_SPEC_VERSION 2
|
||||
#define VK_MVK_IOS_SURFACE_EXTENSION_NAME "VK_MVK_ios_surface"
|
||||
|
||||
typedef VkFlags VkIOSSurfaceCreateFlagsMVK;
|
||||
|
||||
typedef struct VkIOSSurfaceCreateInfoMVK {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkIOSSurfaceCreateFlagsMVK flags;
|
||||
const void* pView;
|
||||
} VkIOSSurfaceCreateInfoMVK;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateIOSSurfaceMVK)(VkInstance instance, const VkIOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateIOSSurfaceMVK(
|
||||
VkInstance instance,
|
||||
const VkIOSSurfaceCreateInfoMVK* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSurfaceKHR* pSurface);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
#ifndef VULKAN_MACOS_H_
|
||||
#define VULKAN_MACOS_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_MVK_macos_surface 1
|
||||
#define VK_MVK_MACOS_SURFACE_SPEC_VERSION 2
|
||||
#define VK_MVK_MACOS_SURFACE_EXTENSION_NAME "VK_MVK_macos_surface"
|
||||
|
||||
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
|
||||
|
||||
typedef struct VkMacOSSurfaceCreateInfoMVK {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkMacOSSurfaceCreateFlagsMVK flags;
|
||||
const void* pView;
|
||||
} VkMacOSSurfaceCreateInfoMVK;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateMacOSSurfaceMVK)(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK(
|
||||
VkInstance instance,
|
||||
const VkMacOSSurfaceCreateInfoMVK* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSurfaceKHR* pSurface);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Vendored
+65
@@ -0,0 +1,65 @@
|
||||
#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
|
||||
Vendored
+58
@@ -0,0 +1,58 @@
|
||||
#ifndef VULKAN_VI_H_
|
||||
#define VULKAN_VI_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_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;
|
||||
VkViSurfaceCreateFlagsNN flags;
|
||||
void* window;
|
||||
} VkViSurfaceCreateInfoNN;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateViSurfaceNN)(VkInstance instance, const VkViSurfaceCreateInfoNN* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateViSurfaceNN(
|
||||
VkInstance instance,
|
||||
const VkViSurfaceCreateInfoNN* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSurfaceKHR* pSurface);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
#ifndef VULKAN_WAYLAND_H_
|
||||
#define VULKAN_WAYLAND_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_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;
|
||||
VkWaylandSurfaceCreateFlagsKHR flags;
|
||||
struct wl_display* display;
|
||||
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);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR(
|
||||
VkInstance instance,
|
||||
const VkWaylandSurfaceCreateInfoKHR* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSurfaceKHR* pSurface);
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
uint32_t queueFamilyIndex,
|
||||
struct wl_display* display);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+276
@@ -0,0 +1,276 @@
|
||||
#ifndef VULKAN_WIN32_H_
|
||||
#define VULKAN_WIN32_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_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;
|
||||
VkWin32SurfaceCreateFlagsKHR flags;
|
||||
HINSTANCE hinstance;
|
||||
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);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(
|
||||
VkInstance instance,
|
||||
const VkWin32SurfaceCreateInfoKHR* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSurfaceKHR* pSurface);
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
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;
|
||||
VkExternalMemoryHandleTypeFlagBits handleType;
|
||||
HANDLE handle;
|
||||
LPCWSTR name;
|
||||
} VkImportMemoryWin32HandleInfoKHR;
|
||||
|
||||
typedef struct VkExportMemoryWin32HandleInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
const SECURITY_ATTRIBUTES* pAttributes;
|
||||
DWORD dwAccess;
|
||||
LPCWSTR name;
|
||||
} VkExportMemoryWin32HandleInfoKHR;
|
||||
|
||||
typedef struct VkMemoryWin32HandlePropertiesKHR {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
uint32_t memoryTypeBits;
|
||||
} VkMemoryWin32HandlePropertiesKHR;
|
||||
|
||||
typedef struct VkMemoryGetWin32HandleInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkDeviceMemory memory;
|
||||
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);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleKHR(
|
||||
VkDevice device,
|
||||
const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo,
|
||||
HANDLE* pHandle);
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandlePropertiesKHR(
|
||||
VkDevice device,
|
||||
VkExternalMemoryHandleTypeFlagBits handleType,
|
||||
HANDLE handle,
|
||||
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;
|
||||
uint32_t acquireCount;
|
||||
const VkDeviceMemory* pAcquireSyncs;
|
||||
const uint64_t* pAcquireKeys;
|
||||
const uint32_t* pAcquireTimeouts;
|
||||
uint32_t releaseCount;
|
||||
const VkDeviceMemory* pReleaseSyncs;
|
||||
const uint64_t* pReleaseKeys;
|
||||
} 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;
|
||||
VkSemaphore semaphore;
|
||||
VkSemaphoreImportFlags flags;
|
||||
VkExternalSemaphoreHandleTypeFlagBits handleType;
|
||||
HANDLE handle;
|
||||
LPCWSTR name;
|
||||
} VkImportSemaphoreWin32HandleInfoKHR;
|
||||
|
||||
typedef struct VkExportSemaphoreWin32HandleInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
const SECURITY_ATTRIBUTES* pAttributes;
|
||||
DWORD dwAccess;
|
||||
LPCWSTR name;
|
||||
} VkExportSemaphoreWin32HandleInfoKHR;
|
||||
|
||||
typedef struct VkD3D12FenceSubmitInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t waitSemaphoreValuesCount;
|
||||
const uint64_t* pWaitSemaphoreValues;
|
||||
uint32_t signalSemaphoreValuesCount;
|
||||
const uint64_t* pSignalSemaphoreValues;
|
||||
} VkD3D12FenceSubmitInfoKHR;
|
||||
|
||||
typedef struct VkSemaphoreGetWin32HandleInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkSemaphore semaphore;
|
||||
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);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreWin32HandleKHR(
|
||||
VkDevice device,
|
||||
const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo);
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreWin32HandleKHR(
|
||||
VkDevice device,
|
||||
const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo,
|
||||
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;
|
||||
VkFence fence;
|
||||
VkFenceImportFlags flags;
|
||||
VkExternalFenceHandleTypeFlagBits handleType;
|
||||
HANDLE handle;
|
||||
LPCWSTR name;
|
||||
} VkImportFenceWin32HandleInfoKHR;
|
||||
|
||||
typedef struct VkExportFenceWin32HandleInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
const SECURITY_ATTRIBUTES* pAttributes;
|
||||
DWORD dwAccess;
|
||||
LPCWSTR name;
|
||||
} VkExportFenceWin32HandleInfoKHR;
|
||||
|
||||
typedef struct VkFenceGetWin32HandleInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkFence fence;
|
||||
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);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkImportFenceWin32HandleKHR(
|
||||
VkDevice device,
|
||||
const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo);
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceWin32HandleKHR(
|
||||
VkDevice device,
|
||||
const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo,
|
||||
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;
|
||||
VkExternalMemoryHandleTypeFlagsNV handleType;
|
||||
HANDLE handle;
|
||||
} VkImportMemoryWin32HandleInfoNV;
|
||||
|
||||
typedef struct VkExportMemoryWin32HandleInfoNV {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
const SECURITY_ATTRIBUTES* pAttributes;
|
||||
DWORD dwAccess;
|
||||
} VkExportMemoryWin32HandleInfoNV;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleNV)(VkDevice device, VkDeviceMemory memory, VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE* pHandle);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleNV(
|
||||
VkDevice device,
|
||||
VkDeviceMemory memory,
|
||||
VkExternalMemoryHandleTypeFlagsNV handleType,
|
||||
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"
|
||||
|
||||
typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t acquireCount;
|
||||
const VkDeviceMemory* pAcquireSyncs;
|
||||
const uint64_t* pAcquireKeys;
|
||||
const uint32_t* pAcquireTimeoutMilliseconds;
|
||||
uint32_t releaseCount;
|
||||
const VkDeviceMemory* pReleaseSyncs;
|
||||
const uint64_t* pReleaseKeys;
|
||||
} VkWin32KeyedMutexAcquireReleaseInfoNV;
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Vendored
+66
@@ -0,0 +1,66 @@
|
||||
#ifndef VULKAN_XCB_H_
|
||||
#define VULKAN_XCB_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_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;
|
||||
VkXcbSurfaceCreateFlagsKHR flags;
|
||||
xcb_connection_t* connection;
|
||||
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);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(
|
||||
VkInstance instance,
|
||||
const VkXcbSurfaceCreateInfoKHR* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSurfaceKHR* pSurface);
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
uint32_t queueFamilyIndex,
|
||||
xcb_connection_t* connection,
|
||||
xcb_visualid_t visual_id);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
#ifndef VULKAN_XLIB_H_
|
||||
#define VULKAN_XLIB_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_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;
|
||||
VkXlibSurfaceCreateFlagsKHR flags;
|
||||
Display* dpy;
|
||||
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);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(
|
||||
VkInstance instance,
|
||||
const VkXlibSurfaceCreateInfoKHR* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSurfaceKHR* pSurface);
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
uint32_t queueFamilyIndex,
|
||||
Display* dpy,
|
||||
VisualID visualID);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
#ifndef VULKAN_XLIB_XRANDR_H_
|
||||
#define VULKAN_XLIB_XRANDR_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_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);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkAcquireXlibDisplayEXT(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
Display* dpy,
|
||||
VkDisplayKHR display);
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetRandROutputDisplayEXT(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
Display* dpy,
|
||||
RROutput rrOutput,
|
||||
VkDisplayKHR* pDisplay);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Vendored
+1
@@ -54,6 +54,7 @@ set_target_properties(${ITT_LIBRARY} PROPERTIES
|
||||
)
|
||||
|
||||
ocv_warnings_disable(CMAKE_C_FLAGS -Wundef -Wsign-compare)
|
||||
ocv_warnings_disable(CMAKE_C_FLAGS -Wstrict-prototypes) # clang15
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(${ITT_LIBRARY} PROPERTIES FOLDER "3rdparty")
|
||||
|
||||
+102
-13
@@ -4,9 +4,9 @@ ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter -Wsign-compare -Wshorten-6
|
||||
|
||||
set(VERSION_MAJOR 2)
|
||||
set(VERSION_MINOR 1)
|
||||
set(VERSION_REVISION 2)
|
||||
set(VERSION_REVISION 3)
|
||||
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION})
|
||||
set(LIBJPEG_TURBO_VERSION_NUMBER 2001002)
|
||||
set(LIBJPEG_TURBO_VERSION_NUMBER 2001003)
|
||||
|
||||
string(TIMESTAMP BUILD "opencv-${OPENCV_VERSION}-libjpeg-turbo")
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
@@ -15,8 +15,53 @@ endif()
|
||||
|
||||
message(STATUS "libjpeg-turbo: VERSION = ${VERSION}, BUILD = ${BUILD}")
|
||||
|
||||
math(EXPR BITS "${CMAKE_SIZEOF_VOID_P} * 8")
|
||||
string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} CMAKE_SYSTEM_PROCESSOR_LC)
|
||||
|
||||
if(CMAKE_SYSTEM_PROCESSOR_LC MATCHES "x86_64" OR
|
||||
CMAKE_SYSTEM_PROCESSOR_LC MATCHES "amd64" OR
|
||||
CMAKE_SYSTEM_PROCESSOR_LC MATCHES "i[0-9]86" OR
|
||||
CMAKE_SYSTEM_PROCESSOR_LC MATCHES "x86" OR
|
||||
CMAKE_SYSTEM_PROCESSOR_LC MATCHES "ia32")
|
||||
if(BITS EQUAL 64 OR CMAKE_C_COMPILER_ABI MATCHES "ELF X32")
|
||||
set(CPU_TYPE x86_64)
|
||||
else()
|
||||
set(CPU_TYPE i386)
|
||||
endif()
|
||||
if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL ${CPU_TYPE})
|
||||
set(CMAKE_SYSTEM_PROCESSOR ${CPU_TYPE})
|
||||
endif()
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR_LC STREQUAL "aarch64" OR
|
||||
CMAKE_SYSTEM_PROCESSOR_LC MATCHES "^arm")
|
||||
if(BITS EQUAL 64)
|
||||
set(CPU_TYPE arm64)
|
||||
else()
|
||||
set(CPU_TYPE arm)
|
||||
endif()
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR_LC MATCHES "^ppc" OR
|
||||
CMAKE_SYSTEM_PROCESSOR_LC MATCHES "^powerpc")
|
||||
set(CPU_TYPE powerpc)
|
||||
else()
|
||||
set(CPU_TYPE ${CMAKE_SYSTEM_PROCESSOR_LC})
|
||||
endif()
|
||||
if(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64" OR
|
||||
CMAKE_OSX_ARCHITECTURES MATCHES "arm64" OR
|
||||
CMAKE_OSX_ARCHITECTURES MATCHES "i386")
|
||||
set(CPU_TYPE ${CMAKE_OSX_ARCHITECTURES})
|
||||
endif()
|
||||
if(CMAKE_OSX_ARCHITECTURES MATCHES "ppc")
|
||||
set(CPU_TYPE powerpc)
|
||||
endif()
|
||||
if(MSVC_IDE AND CMAKE_GENERATOR_PLATFORM MATCHES "arm64")
|
||||
set(CPU_TYPE arm64)
|
||||
endif()
|
||||
|
||||
OCV_OPTION(ENABLE_LIBJPEG_TURBO_SIMD "Include SIMD extensions for libjpeg-turbo, if available for this platform" (NOT CV_DISABLE_OPTIMIZATION)
|
||||
VISIBLE_IF BUILD_JPEG)
|
||||
option(WITH_ARITH_ENC "Include arithmetic encoding support when emulating the libjpeg v6b API/ABI" TRUE)
|
||||
option(WITH_ARITH_DEC "Include arithmetic decoding support when emulating the libjpeg v6b API/ABI" TRUE)
|
||||
set(WITH_SIMD 1)
|
||||
set(HAVE_LIBJPEG_TURBO_SIMD 0 PARENT_SCOPE)
|
||||
|
||||
include(CheckCSourceCompiles)
|
||||
include(CheckIncludeFiles)
|
||||
@@ -79,14 +124,13 @@ configure_file(jconfigint.h.in jconfigint.h)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||
|
||||
set(JPEG_SOURCES
|
||||
jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c jcicc.c
|
||||
jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c jcphuff.c
|
||||
jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c jdatadst.c jdatasrc.c
|
||||
jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c jdicc.c jdinput.c jdmainct.c jdmarker.c
|
||||
jdmaster.c jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c jerror.c
|
||||
jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c
|
||||
jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c)
|
||||
set(JPEG_SOURCES jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c
|
||||
jcicc.c jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c
|
||||
jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c jdatadst.c
|
||||
jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c jdicc.c jdinput.c
|
||||
jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c jdpostct.c jdsample.c
|
||||
jdtrans.c jerror.c jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c
|
||||
jidctint.c jidctred.c jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c)
|
||||
|
||||
if(WITH_ARITH_ENC OR WITH_ARITH_DEC)
|
||||
set(JPEG_SOURCES ${JPEG_SOURCES} jaricom.c)
|
||||
@@ -100,12 +144,57 @@ if(WITH_ARITH_DEC)
|
||||
set(JPEG_SOURCES ${JPEG_SOURCES} jdarith.c)
|
||||
endif()
|
||||
|
||||
# No SIMD
|
||||
set(JPEG_SOURCES ${JPEG_SOURCES} jsimd_none.c)
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
# Use the maximum optimization level for release builds
|
||||
foreach(var CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO)
|
||||
if(${var} MATCHES "-O2")
|
||||
string(REGEX REPLACE "-O2" "-O3" ${var} "${${var}}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "SunPro")
|
||||
# Use the maximum optimization level for release builds
|
||||
foreach(var CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO)
|
||||
if(${var} MATCHES "-xO3")
|
||||
string(REGEX REPLACE "-xO3" "-xO5" ${var} "${${var}}")
|
||||
endif()
|
||||
if(${var} MATCHES "-xO2")
|
||||
string(REGEX REPLACE "-xO2" "-xO5" ${var} "${${var}}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_LIBJPEG_TURBO_SIMD)
|
||||
add_subdirectory(src/simd)
|
||||
if(NEON_INTRINSICS)
|
||||
add_definitions(-DNEON_INTRINSICS)
|
||||
endif()
|
||||
else()
|
||||
set(WITH_SIMD 0)
|
||||
endif()
|
||||
|
||||
if(WITH_SIMD)
|
||||
message(STATUS "SIMD extensions: ${CPU_TYPE} (WITH_SIMD = ${WITH_SIMD})")
|
||||
set(HAVE_LIBJPEG_TURBO_SIMD 1 PARENT_SCOPE)
|
||||
if(MSVC_IDE OR XCODE)
|
||||
set_source_files_properties(${SIMD_OBJS} PROPERTIES GENERATED 1)
|
||||
endif()
|
||||
else()
|
||||
add_library(jsimd OBJECT src/jsimd_none.c)
|
||||
set_target_properties(jsimd PROPERTIES FOLDER "3rdparty")
|
||||
if(NOT WIN32 AND (CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED))
|
||||
set_target_properties(jsimd PROPERTIES POSITION_INDEPENDENT_CODE 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
ocv_list_add_prefix(JPEG_SOURCES src/)
|
||||
|
||||
add_library(${JPEG_LIBRARY} STATIC ${OPENCV_3RDPARTY_EXCLUDE_FROM_ALL} ${JPEG_SOURCES} ${SIMD_OBJS})
|
||||
set(JPEG_SOURCES ${JPEG_SOURCES} ${SIMD_OBJS})
|
||||
|
||||
add_library(${JPEG_LIBRARY} STATIC ${OPENCV_3RDPARTY_EXCLUDE_FROM_ALL} ${JPEG_SOURCES} $<TARGET_OBJECTS:jsimd> ${SIMD_OBJS})
|
||||
|
||||
set_target_properties(${JPEG_LIBRARY}
|
||||
PROPERTIES OUTPUT_NAME ${JPEG_LIBRARY}
|
||||
|
||||
Vendored
+1
-1
@@ -91,7 +91,7 @@ best of our understanding.
|
||||
The Modified (3-clause) BSD License
|
||||
===================================
|
||||
|
||||
Copyright (C)2009-2021 D. R. Commander. All Rights Reserved.<br>
|
||||
Copyright (C)2009-2022 D. R. Commander. All Rights Reserved.<br>
|
||||
Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
+3
-3
@@ -4,8 +4,8 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1998, Thomas G. Lane.
|
||||
* Modified 2003-2010 by Guido Vollbeding.
|
||||
* It was modified by The libjpeg-turbo Project to include only code relevant
|
||||
* to libjpeg-turbo.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -52,7 +52,7 @@ jpeg_CreateCompress(j_compress_ptr cinfo, int version, size_t structsize)
|
||||
{
|
||||
struct jpeg_error_mgr *err = cinfo->err;
|
||||
void *client_data = cinfo->client_data; /* ignore Purify complaint here */
|
||||
MEMZERO(cinfo, sizeof(struct jpeg_compress_struct));
|
||||
memset(cinfo, 0, sizeof(struct jpeg_compress_struct));
|
||||
cinfo->err = err;
|
||||
cinfo->client_data = client_data;
|
||||
}
|
||||
|
||||
Vendored
+6
-6
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Developed 1997-2009 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2015, 2018, D. R. Commander.
|
||||
* Copyright (C) 2015, 2018, 2021-2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -338,14 +338,14 @@ emit_restart(j_compress_ptr cinfo, int restart_num)
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
/* DC needs no table for refinement scan */
|
||||
if (cinfo->progressive_mode == 0 || (cinfo->Ss == 0 && cinfo->Ah == 0)) {
|
||||
MEMZERO(entropy->dc_stats[compptr->dc_tbl_no], DC_STAT_BINS);
|
||||
memset(entropy->dc_stats[compptr->dc_tbl_no], 0, DC_STAT_BINS);
|
||||
/* Reset DC predictions to 0 */
|
||||
entropy->last_dc_val[ci] = 0;
|
||||
entropy->dc_context[ci] = 0;
|
||||
}
|
||||
/* AC needs no table when not present */
|
||||
if (cinfo->progressive_mode == 0 || cinfo->Se) {
|
||||
MEMZERO(entropy->ac_stats[compptr->ac_tbl_no], AC_STAT_BINS);
|
||||
memset(entropy->ac_stats[compptr->ac_tbl_no], 0, AC_STAT_BINS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -836,7 +836,7 @@ start_pass(j_compress_ptr cinfo, boolean gather_statistics)
|
||||
* We are fully adaptive here and need no extra
|
||||
* statistics gathering pass!
|
||||
*/
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
ERREXIT(cinfo, JERR_NOTIMPL);
|
||||
|
||||
/* We assume jcmaster.c already validated the progressive scan parameters. */
|
||||
|
||||
@@ -867,7 +867,7 @@ start_pass(j_compress_ptr cinfo, boolean gather_statistics)
|
||||
if (entropy->dc_stats[tbl] == NULL)
|
||||
entropy->dc_stats[tbl] = (unsigned char *)(*cinfo->mem->alloc_small)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE, DC_STAT_BINS);
|
||||
MEMZERO(entropy->dc_stats[tbl], DC_STAT_BINS);
|
||||
memset(entropy->dc_stats[tbl], 0, DC_STAT_BINS);
|
||||
/* Initialize DC predictions to 0 */
|
||||
entropy->last_dc_val[ci] = 0;
|
||||
entropy->dc_context[ci] = 0;
|
||||
@@ -880,7 +880,7 @@ start_pass(j_compress_ptr cinfo, boolean gather_statistics)
|
||||
if (entropy->ac_stats[tbl] == NULL)
|
||||
entropy->ac_stats[tbl] = (unsigned char *)(*cinfo->mem->alloc_small)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE, AC_STAT_BINS);
|
||||
MEMZERO(entropy->ac_stats[tbl], AC_STAT_BINS);
|
||||
memset(entropy->ac_stats[tbl], 0, AC_STAT_BINS);
|
||||
#ifdef CALCULATE_SPECTRAL_CONDITIONING
|
||||
if (cinfo->progressive_mode)
|
||||
/* Section G.1.3.2: Set appropriate arithmetic conditioning value Kx */
|
||||
|
||||
Vendored
+11
-11
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009-2011, 2014-2016, 2018-2021, D. R. Commander.
|
||||
* Copyright (C) 2009-2011, 2014-2016, 2018-2022, D. R. Commander.
|
||||
* Copyright (C) 2015, Matthieu Darbois.
|
||||
* Copyright (C) 2018, Matthias Räncker.
|
||||
* Copyright (C) 2020, Arm Limited.
|
||||
@@ -200,12 +200,12 @@ start_pass_huff(j_compress_ptr cinfo, boolean gather_statistics)
|
||||
entropy->dc_count_ptrs[dctbl] = (long *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
257 * sizeof(long));
|
||||
MEMZERO(entropy->dc_count_ptrs[dctbl], 257 * sizeof(long));
|
||||
memset(entropy->dc_count_ptrs[dctbl], 0, 257 * sizeof(long));
|
||||
if (entropy->ac_count_ptrs[actbl] == NULL)
|
||||
entropy->ac_count_ptrs[actbl] = (long *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
257 * sizeof(long));
|
||||
MEMZERO(entropy->ac_count_ptrs[actbl], 257 * sizeof(long));
|
||||
memset(entropy->ac_count_ptrs[actbl], 0, 257 * sizeof(long));
|
||||
#endif
|
||||
} else {
|
||||
/* Compute derived values for Huffman tables */
|
||||
@@ -315,8 +315,8 @@ jpeg_make_c_derived_tbl(j_compress_ptr cinfo, boolean isDC, int tblno,
|
||||
* this lets us detect duplicate VAL entries here, and later
|
||||
* allows emit_bits to detect any attempt to emit such symbols.
|
||||
*/
|
||||
MEMZERO(dtbl->ehufco, sizeof(dtbl->ehufco));
|
||||
MEMZERO(dtbl->ehufsi, sizeof(dtbl->ehufsi));
|
||||
memset(dtbl->ehufco, 0, sizeof(dtbl->ehufco));
|
||||
memset(dtbl->ehufsi, 0, sizeof(dtbl->ehufsi));
|
||||
|
||||
/* This is also a convenient place to check for out-of-range
|
||||
* and duplicated VAL entries. We allow 0..255 for AC symbols
|
||||
@@ -478,7 +478,7 @@ dump_buffer(working_state *state)
|
||||
buffer = _buffer; \
|
||||
while (bytes > 0) { \
|
||||
bytestocopy = MIN(bytes, state->free_in_buffer); \
|
||||
MEMCOPY(state->next_output_byte, buffer, bytestocopy); \
|
||||
memcpy(state->next_output_byte, buffer, bytestocopy); \
|
||||
state->next_output_byte += bytestocopy; \
|
||||
buffer += bytestocopy; \
|
||||
state->free_in_buffer -= bytestocopy; \
|
||||
@@ -941,8 +941,8 @@ jpeg_gen_optimal_table(j_compress_ptr cinfo, JHUFF_TBL *htbl, long freq[])
|
||||
|
||||
/* This algorithm is explained in section K.2 of the JPEG standard */
|
||||
|
||||
MEMZERO(bits, sizeof(bits));
|
||||
MEMZERO(codesize, sizeof(codesize));
|
||||
memset(bits, 0, sizeof(bits));
|
||||
memset(codesize, 0, sizeof(codesize));
|
||||
for (i = 0; i < 257; i++)
|
||||
others[i] = -1; /* init links to empty */
|
||||
|
||||
@@ -1044,7 +1044,7 @@ jpeg_gen_optimal_table(j_compress_ptr cinfo, JHUFF_TBL *htbl, long freq[])
|
||||
bits[i]--;
|
||||
|
||||
/* Return final symbol counts (only for lengths 0..16) */
|
||||
MEMCOPY(htbl->bits, bits, sizeof(htbl->bits));
|
||||
memcpy(htbl->bits, bits, sizeof(htbl->bits));
|
||||
|
||||
/* Return a list of the symbols sorted by code length */
|
||||
/* It's not real clear to me why we don't need to consider the codelength
|
||||
@@ -1083,8 +1083,8 @@ finish_pass_gather(j_compress_ptr cinfo)
|
||||
/* It's important not to apply jpeg_gen_optimal_table more than once
|
||||
* per table, because it clobbers the input frequency counts!
|
||||
*/
|
||||
MEMZERO(did_dc, sizeof(did_dc));
|
||||
MEMZERO(did_ac, sizeof(did_ac));
|
||||
memset(did_dc, 0, sizeof(did_dc));
|
||||
memset(did_ac, 0, sizeof(did_ac));
|
||||
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
|
||||
Vendored
+5
-5
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1995-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2011, 2015, 2018, 2021, D. R. Commander.
|
||||
* Copyright (C) 2011, 2015, 2018, 2021-2022, D. R. Commander.
|
||||
* Copyright (C) 2016, 2018, Matthieu Darbois.
|
||||
* Copyright (C) 2020, Arm Limited.
|
||||
* Copyright (C) 2021, Alex Richardson.
|
||||
@@ -275,7 +275,7 @@ start_pass_phuff(j_compress_ptr cinfo, boolean gather_statistics)
|
||||
entropy->count_ptrs[tbl] = (long *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
257 * sizeof(long));
|
||||
MEMZERO(entropy->count_ptrs[tbl], 257 * sizeof(long));
|
||||
memset(entropy->count_ptrs[tbl], 0, 257 * sizeof(long));
|
||||
} else {
|
||||
/* Compute derived values for Huffman table */
|
||||
/* We may do this more than once for a table, but it's not expensive */
|
||||
@@ -584,8 +584,8 @@ encode_mcu_DC_first(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
continue; \
|
||||
/* For a negative coef, want temp2 = bitwise complement of abs(coef) */ \
|
||||
temp2 ^= temp; \
|
||||
values[k] = temp; \
|
||||
values[k + DCTSIZE2] = temp2; \
|
||||
values[k] = (JCOEF)temp; \
|
||||
values[k + DCTSIZE2] = (JCOEF)temp2; \
|
||||
zerobits |= ((size_t)1U) << k; \
|
||||
} \
|
||||
}
|
||||
@@ -1062,7 +1062,7 @@ finish_pass_gather_phuff(j_compress_ptr cinfo)
|
||||
/* It's important not to apply jpeg_gen_optimal_table more than once
|
||||
* per table, because it clobbers the input frequency counts!
|
||||
*/
|
||||
MEMZERO(did, sizeof(did));
|
||||
memset(did, 0, sizeof(did));
|
||||
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
|
||||
+4
-4
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* This file is part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* It was modified by The libjpeg-turbo Project to include only code relevant
|
||||
* to libjpeg-turbo.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -289,8 +289,8 @@ create_context_buffer(j_compress_ptr cinfo)
|
||||
cinfo->max_h_samp_factor) / compptr->h_samp_factor),
|
||||
(JDIMENSION)(3 * rgroup_height));
|
||||
/* Copy true buffer row pointers into the middle of the fake row array */
|
||||
MEMCOPY(fake_buffer + rgroup_height, true_buffer,
|
||||
3 * rgroup_height * sizeof(JSAMPROW));
|
||||
memcpy(fake_buffer + rgroup_height, true_buffer,
|
||||
3 * rgroup_height * sizeof(JSAMPROW));
|
||||
/* Fill in the above and below wraparound pointers */
|
||||
for (i = 0; i < rgroup_height; i++) {
|
||||
fake_buffer[i] = true_buffer[2 * rgroup_height + i];
|
||||
|
||||
Vendored
+3
-3
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 1995-1998, Thomas G. Lane.
|
||||
* Modified 2000-2009 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2020, D. R. Commander.
|
||||
* Copyright (C) 2020, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -100,8 +100,8 @@ jpeg_copy_critical_parameters(j_decompress_ptr srcinfo, j_compress_ptr dstinfo)
|
||||
qtblptr = &dstinfo->quant_tbl_ptrs[tblno];
|
||||
if (*qtblptr == NULL)
|
||||
*qtblptr = jpeg_alloc_quant_table((j_common_ptr)dstinfo);
|
||||
MEMCOPY((*qtblptr)->quantval, srcinfo->quant_tbl_ptrs[tblno]->quantval,
|
||||
sizeof((*qtblptr)->quantval));
|
||||
memcpy((*qtblptr)->quantval, srcinfo->quant_tbl_ptrs[tblno]->quantval,
|
||||
sizeof((*qtblptr)->quantval));
|
||||
(*qtblptr)->sent_table = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1998, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2016, D. R. Commander.
|
||||
* Copyright (C) 2016, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -53,7 +53,7 @@ jpeg_CreateDecompress(j_decompress_ptr cinfo, int version, size_t structsize)
|
||||
{
|
||||
struct jpeg_error_mgr *err = cinfo->err;
|
||||
void *client_data = cinfo->client_data; /* ignore Purify complaint here */
|
||||
MEMZERO(cinfo, sizeof(struct jpeg_decompress_struct));
|
||||
memset(cinfo, 0, sizeof(struct jpeg_decompress_struct));
|
||||
cinfo->err = err;
|
||||
cinfo->client_data = client_data;
|
||||
}
|
||||
@@ -92,7 +92,7 @@ jpeg_CreateDecompress(j_decompress_ptr cinfo, int version, size_t structsize)
|
||||
cinfo->master = (struct jpeg_decomp_master *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT,
|
||||
sizeof(my_decomp_master));
|
||||
MEMZERO(cinfo->master, sizeof(my_decomp_master));
|
||||
memset(cinfo->master, 0, sizeof(my_decomp_master));
|
||||
}
|
||||
|
||||
|
||||
|
||||
+7
-1
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010, 2015-2020, D. R. Commander.
|
||||
* Copyright (C) 2010, 2015-2020, 2022, D. R. Commander.
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
@@ -159,6 +159,7 @@ jpeg_crop_scanline(j_decompress_ptr cinfo, JDIMENSION *xoffset,
|
||||
JDIMENSION input_xoffset;
|
||||
boolean reinit_upsampler = FALSE;
|
||||
jpeg_component_info *compptr;
|
||||
my_master_ptr master = (my_master_ptr)cinfo->master;
|
||||
|
||||
if (cinfo->global_state != DSTATE_SCANNING || cinfo->output_scanline != 0)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
@@ -208,6 +209,11 @@ jpeg_crop_scanline(j_decompress_ptr cinfo, JDIMENSION *xoffset,
|
||||
*/
|
||||
*width = *width + input_xoffset - *xoffset;
|
||||
cinfo->output_width = *width;
|
||||
if (master->using_merged_upsample && cinfo->max_v_samp_factor == 2) {
|
||||
my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
|
||||
upsample->out_row_width =
|
||||
cinfo->output_width * cinfo->out_color_components;
|
||||
}
|
||||
|
||||
/* Set the first and last iMCU columns that we must decompress. These values
|
||||
* will be used in single-scan decompressions.
|
||||
|
||||
Vendored
+11
-11
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Developed 1997-2015 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2015-2020, D. R. Commander.
|
||||
* Copyright (C) 2015-2020, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -210,13 +210,13 @@ process_restart(j_decompress_ptr cinfo)
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
if (!cinfo->progressive_mode || (cinfo->Ss == 0 && cinfo->Ah == 0)) {
|
||||
MEMZERO(entropy->dc_stats[compptr->dc_tbl_no], DC_STAT_BINS);
|
||||
memset(entropy->dc_stats[compptr->dc_tbl_no], 0, DC_STAT_BINS);
|
||||
/* Reset DC predictions to 0 */
|
||||
entropy->last_dc_val[ci] = 0;
|
||||
entropy->dc_context[ci] = 0;
|
||||
}
|
||||
if (!cinfo->progressive_mode || cinfo->Ss) {
|
||||
MEMZERO(entropy->ac_stats[compptr->ac_tbl_no], AC_STAT_BINS);
|
||||
memset(entropy->ac_stats[compptr->ac_tbl_no], 0, AC_STAT_BINS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,17 +471,17 @@ decode_mcu_AC_refine(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
if (*thiscoef) { /* previously nonzero coef */
|
||||
if (arith_decode(cinfo, st + 2)) {
|
||||
if (*thiscoef < 0)
|
||||
*thiscoef += m1;
|
||||
*thiscoef += (JCOEF)m1;
|
||||
else
|
||||
*thiscoef += p1;
|
||||
*thiscoef += (JCOEF)p1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (arith_decode(cinfo, st + 1)) { /* newly nonzero coef */
|
||||
if (arith_decode(cinfo, entropy->fixed_bin))
|
||||
*thiscoef = m1;
|
||||
*thiscoef = (JCOEF)m1;
|
||||
else
|
||||
*thiscoef = p1;
|
||||
*thiscoef = (JCOEF)p1;
|
||||
break;
|
||||
}
|
||||
st += 3; k++;
|
||||
@@ -698,8 +698,8 @@ bad:
|
||||
/* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG.
|
||||
* This ought to be an error condition, but we make it a warning.
|
||||
*/
|
||||
if (cinfo->Ss != 0 || cinfo->Ah != 0 || cinfo->Al != 0 ||
|
||||
(cinfo->Se < DCTSIZE2 && cinfo->Se != DCTSIZE2 - 1))
|
||||
if (cinfo->Ss != 0 || cinfo->Se != DCTSIZE2 - 1 ||
|
||||
cinfo->Ah != 0 || cinfo->Al != 0)
|
||||
WARNMS(cinfo, JWRN_NOT_SEQUENTIAL);
|
||||
/* Select MCU decoding routine */
|
||||
entropy->pub.decode_mcu = decode_mcu;
|
||||
@@ -715,7 +715,7 @@ bad:
|
||||
if (entropy->dc_stats[tbl] == NULL)
|
||||
entropy->dc_stats[tbl] = (unsigned char *)(*cinfo->mem->alloc_small)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE, DC_STAT_BINS);
|
||||
MEMZERO(entropy->dc_stats[tbl], DC_STAT_BINS);
|
||||
memset(entropy->dc_stats[tbl], 0, DC_STAT_BINS);
|
||||
/* Initialize DC predictions to 0 */
|
||||
entropy->last_dc_val[ci] = 0;
|
||||
entropy->dc_context[ci] = 0;
|
||||
@@ -727,7 +727,7 @@ bad:
|
||||
if (entropy->ac_stats[tbl] == NULL)
|
||||
entropy->ac_stats[tbl] = (unsigned char *)(*cinfo->mem->alloc_small)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE, AC_STAT_BINS);
|
||||
MEMZERO(entropy->ac_stats[tbl], AC_STAT_BINS);
|
||||
memset(entropy->ac_stats[tbl], 0, AC_STAT_BINS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-9
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* Modified 2009-2012 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2013, 2016, D. R. Commander.
|
||||
* Copyright (C) 2013, 2016, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -23,11 +23,6 @@
|
||||
#include "jpeglib.h"
|
||||
#include "jerror.h"
|
||||
|
||||
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
|
||||
extern void *malloc(size_t size);
|
||||
extern void free(void *ptr);
|
||||
#endif
|
||||
|
||||
|
||||
/* Expanded data destination object for stdio output */
|
||||
|
||||
@@ -116,7 +111,7 @@ empty_output_buffer(j_compress_ptr cinfo)
|
||||
{
|
||||
my_dest_ptr dest = (my_dest_ptr)cinfo->dest;
|
||||
|
||||
if (JFWRITE(dest->outfile, dest->buffer, OUTPUT_BUF_SIZE) !=
|
||||
if (fwrite(dest->buffer, 1, OUTPUT_BUF_SIZE, dest->outfile) !=
|
||||
(size_t)OUTPUT_BUF_SIZE)
|
||||
ERREXIT(cinfo, JERR_FILE_WRITE);
|
||||
|
||||
@@ -141,7 +136,7 @@ empty_mem_output_buffer(j_compress_ptr cinfo)
|
||||
if (nextbuffer == NULL)
|
||||
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
|
||||
|
||||
MEMCOPY(nextbuffer, dest->buffer, dest->bufsize);
|
||||
memcpy(nextbuffer, dest->buffer, dest->bufsize);
|
||||
|
||||
free(dest->newbuffer);
|
||||
|
||||
@@ -175,7 +170,7 @@ term_destination(j_compress_ptr cinfo)
|
||||
|
||||
/* Write any data remaining in the buffer */
|
||||
if (datacount > 0) {
|
||||
if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount)
|
||||
if (fwrite(dest->buffer, 1, datacount, dest->outfile) != datacount)
|
||||
ERREXIT(cinfo, JERR_FILE_WRITE);
|
||||
}
|
||||
fflush(dest->outfile);
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* Modified 2009-2011 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2013, 2016, D. R. Commander.
|
||||
* Copyright (C) 2013, 2016, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -104,7 +104,7 @@ fill_input_buffer(j_decompress_ptr cinfo)
|
||||
my_src_ptr src = (my_src_ptr)cinfo->src;
|
||||
size_t nbytes;
|
||||
|
||||
nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE);
|
||||
nbytes = fread(src->buffer, 1, INPUT_BUF_SIZE, src->infile);
|
||||
|
||||
if (nbytes <= 0) {
|
||||
if (src->start_of_file) /* Treat empty input file as fatal error */
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
* Modified 2002-2010 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2010, 2015, D. R. Commander.
|
||||
* Copyright (C) 2010, 2015, 2022, D. R. Commander.
|
||||
* Copyright (C) 2013, MIPS Technologies, Inc., California.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
@@ -345,7 +345,7 @@ jinit_inverse_dct(j_decompress_ptr cinfo)
|
||||
compptr->dct_table =
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(multiplier_table));
|
||||
MEMZERO(compptr->dct_table, sizeof(multiplier_table));
|
||||
memset(compptr->dct_table, 0, sizeof(multiplier_table));
|
||||
/* Mark multiplier table not yet set up for any method */
|
||||
idct->cur_method[ci] = -1;
|
||||
}
|
||||
|
||||
Vendored
-4
@@ -18,10 +18,6 @@
|
||||
#include "jpeglib.h"
|
||||
#include "jerror.h"
|
||||
|
||||
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc() */
|
||||
extern void *malloc(size_t size);
|
||||
#endif
|
||||
|
||||
|
||||
#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */
|
||||
#define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */
|
||||
|
||||
Vendored
+2
-2
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010, 2016, 2018, D. R. Commander.
|
||||
* Copyright (C) 2010, 2016, 2018, 2022, D. R. Commander.
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
@@ -264,7 +264,7 @@ latch_quant_tables(j_decompress_ptr cinfo)
|
||||
qtbl = (JQUANT_TBL *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(JQUANT_TBL));
|
||||
MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], sizeof(JQUANT_TBL));
|
||||
memcpy(qtbl, cinfo->quant_tbl_ptrs[qtblno], sizeof(JQUANT_TBL));
|
||||
compptr->quant_table = qtbl;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2012, 2015, D. R. Commander.
|
||||
* Copyright (C) 2012, 2015, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -473,7 +473,7 @@ get_dht(j_decompress_ptr cinfo)
|
||||
for (i = 0; i < count; i++)
|
||||
INPUT_BYTE(cinfo, huffval[i], return FALSE);
|
||||
|
||||
MEMZERO(&huffval[count], (256 - count) * sizeof(UINT8));
|
||||
memset(&huffval[count], 0, (256 - count) * sizeof(UINT8));
|
||||
|
||||
length -= count;
|
||||
|
||||
@@ -491,8 +491,8 @@ get_dht(j_decompress_ptr cinfo)
|
||||
if (*htblptr == NULL)
|
||||
*htblptr = jpeg_alloc_huff_table((j_common_ptr)cinfo);
|
||||
|
||||
MEMCOPY((*htblptr)->bits, bits, sizeof((*htblptr)->bits));
|
||||
MEMCOPY((*htblptr)->huffval, huffval, sizeof((*htblptr)->huffval));
|
||||
memcpy((*htblptr)->bits, bits, sizeof((*htblptr)->bits));
|
||||
memcpy((*htblptr)->huffval, huffval, sizeof((*htblptr)->huffval));
|
||||
}
|
||||
|
||||
if (length != 0)
|
||||
|
||||
+6
-6
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 2002-2009 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009-2011, 2016, 2019, D. R. Commander.
|
||||
* Copyright (C) 2009-2011, 2016, 2019, 2022, D. R. Commander.
|
||||
* Copyright (C) 2013, Linaro Limited.
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
@@ -417,7 +417,7 @@ prepare_range_limit_table(j_decompress_ptr cinfo)
|
||||
table += (MAXJSAMPLE + 1); /* allow negative subscripts of simple table */
|
||||
cinfo->sample_range_limit = table;
|
||||
/* First segment of "simple" table: limit[x] = 0 for x < 0 */
|
||||
MEMZERO(table - (MAXJSAMPLE + 1), (MAXJSAMPLE + 1) * sizeof(JSAMPLE));
|
||||
memset(table - (MAXJSAMPLE + 1), 0, (MAXJSAMPLE + 1) * sizeof(JSAMPLE));
|
||||
/* Main part of "simple" table: limit[x] = x */
|
||||
for (i = 0; i <= MAXJSAMPLE; i++)
|
||||
table[i] = (JSAMPLE)i;
|
||||
@@ -426,10 +426,10 @@ prepare_range_limit_table(j_decompress_ptr cinfo)
|
||||
for (i = CENTERJSAMPLE; i < 2 * (MAXJSAMPLE + 1); i++)
|
||||
table[i] = MAXJSAMPLE;
|
||||
/* Second half of post-IDCT table */
|
||||
MEMZERO(table + (2 * (MAXJSAMPLE + 1)),
|
||||
(2 * (MAXJSAMPLE + 1) - CENTERJSAMPLE) * sizeof(JSAMPLE));
|
||||
MEMCOPY(table + (4 * (MAXJSAMPLE + 1) - CENTERJSAMPLE),
|
||||
cinfo->sample_range_limit, CENTERJSAMPLE * sizeof(JSAMPLE));
|
||||
memset(table + (2 * (MAXJSAMPLE + 1)), 0,
|
||||
(2 * (MAXJSAMPLE + 1) - CENTERJSAMPLE) * sizeof(JSAMPLE));
|
||||
memcpy(table + (4 * (MAXJSAMPLE + 1) - CENTERJSAMPLE),
|
||||
cinfo->sample_range_limit, CENTERJSAMPLE * sizeof(JSAMPLE));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vendored
+5
-5
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1995-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2015-2016, 2018-2021, D. R. Commander.
|
||||
* Copyright (C) 2015-2016, 2018-2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -578,9 +578,9 @@ decode_mcu_AC_refine(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
if (GET_BITS(1)) {
|
||||
if ((*thiscoef & p1) == 0) { /* do nothing if already set it */
|
||||
if (*thiscoef >= 0)
|
||||
*thiscoef += p1;
|
||||
*thiscoef += (JCOEF)p1;
|
||||
else
|
||||
*thiscoef += m1;
|
||||
*thiscoef += (JCOEF)m1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -612,9 +612,9 @@ decode_mcu_AC_refine(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
if (GET_BITS(1)) {
|
||||
if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */
|
||||
if (*thiscoef >= 0)
|
||||
*thiscoef += p1;
|
||||
*thiscoef += (JCOEF)p1;
|
||||
else
|
||||
*thiscoef += m1;
|
||||
*thiscoef += (JCOEF)m1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+8
-8
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* It was modified by The libjpeg-turbo Project to include only code relevant
|
||||
* to libjpeg-turbo.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -189,13 +189,13 @@ format_message(j_common_ptr cinfo, char *buffer)
|
||||
|
||||
/* Format the message into the passed buffer */
|
||||
if (isstring)
|
||||
sprintf(buffer, msgtext, err->msg_parm.s);
|
||||
snprintf(buffer, JMSG_LENGTH_MAX, msgtext, err->msg_parm.s);
|
||||
else
|
||||
sprintf(buffer, msgtext,
|
||||
err->msg_parm.i[0], err->msg_parm.i[1],
|
||||
err->msg_parm.i[2], err->msg_parm.i[3],
|
||||
err->msg_parm.i[4], err->msg_parm.i[5],
|
||||
err->msg_parm.i[6], err->msg_parm.i[7]);
|
||||
snprintf(buffer, JMSG_LENGTH_MAX, msgtext,
|
||||
err->msg_parm.i[0], err->msg_parm.i[1],
|
||||
err->msg_parm.i[2], err->msg_parm.i[3],
|
||||
err->msg_parm.i[4], err->msg_parm.i[5],
|
||||
err->msg_parm.i[6], err->msg_parm.i[7]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vendored
+4
-2
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 1994-1997, Thomas G. Lane.
|
||||
* Modified 1997-2009 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2014, 2017, D. R. Commander.
|
||||
* Copyright (C) 2014, 2017, 2021-2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -103,7 +103,7 @@ JMESSAGE(JERR_MISMATCHED_QUANT_TABLE,
|
||||
"Cannot transcode due to multiple use of quantization table %d")
|
||||
JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data")
|
||||
JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change")
|
||||
JMESSAGE(JERR_NOTIMPL, "Not implemented yet")
|
||||
JMESSAGE(JERR_NOTIMPL, "Requested features are incompatible")
|
||||
JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time")
|
||||
#if JPEG_LIB_VERSION >= 70
|
||||
JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined")
|
||||
@@ -268,6 +268,7 @@ JMESSAGE(JERR_BAD_DROP_SAMPLING,
|
||||
#define ERREXITS(cinfo, code, str) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
|
||||
(cinfo)->err->msg_parm.s[JMSG_STR_PARM_MAX - 1] = '\0', \
|
||||
(*(cinfo)->err->error_exit) ((j_common_ptr)(cinfo)))
|
||||
|
||||
#define MAKESTMT(stuff) do { stuff } while (0)
|
||||
@@ -324,6 +325,7 @@ JMESSAGE(JERR_BAD_DROP_SAMPLING,
|
||||
#define TRACEMSS(cinfo, lvl, code, str) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
|
||||
(cinfo)->err->msg_parm.s[JMSG_STR_PARM_MAX - 1] = '\0', \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr)(cinfo), (lvl)))
|
||||
|
||||
#endif /* JERROR_H */
|
||||
|
||||
+95
-50
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1994, Thomas G. Lane.
|
||||
* It was modified by The libjpeg-turbo Project to include only code relevant
|
||||
* to libjpeg-turbo.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -17,72 +17,117 @@
|
||||
* JPEG library. Most applications need only include jpeglib.h.
|
||||
*/
|
||||
|
||||
#ifndef __JINCLUDE_H__
|
||||
#define __JINCLUDE_H__
|
||||
|
||||
/* Include auto-config file to find out which system include files we need. */
|
||||
|
||||
#include "jconfig.h" /* auto configuration options */
|
||||
#include "jconfigint.h"
|
||||
#define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */
|
||||
|
||||
/*
|
||||
* We need the NULL macro and size_t typedef.
|
||||
* On an ANSI-conforming system it is sufficient to include <stddef.h>.
|
||||
* Otherwise, we get them from <stdlib.h> or <stdio.h>; we may have to
|
||||
* pull in <sys/types.h> as well.
|
||||
* Note that the core JPEG library does not require <stdio.h>;
|
||||
* only the default error handler and data source/destination modules do.
|
||||
* But we must pull it in because of the references to FILE in jpeglib.h.
|
||||
* You can remove those references if you want to compile without <stdio.h>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_STDDEF_H
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef NEED_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* We need memory copying and zeroing functions, plus strncpy().
|
||||
* ANSI and System V implementations declare these in <string.h>.
|
||||
* BSD doesn't have the mem() functions, but it does have bcopy()/bzero().
|
||||
* Some systems may declare memset and memcpy in <memory.h>.
|
||||
*
|
||||
* NOTE: we assume the size parameters to these functions are of type size_t.
|
||||
* Change the casts in these macros if not!
|
||||
*/
|
||||
|
||||
#ifdef NEED_BSD_STRINGS
|
||||
|
||||
#include <strings.h>
|
||||
#define MEMZERO(target, size) \
|
||||
bzero((void *)(target), (size_t)(size))
|
||||
#define MEMCOPY(dest, src, size) \
|
||||
bcopy((const void *)(src), (void *)(dest), (size_t)(size))
|
||||
|
||||
#else /* not BSD, assume ANSI/SysV string lib */
|
||||
|
||||
#include <string.h>
|
||||
#define MEMZERO(target, size) \
|
||||
memset((void *)(target), 0, (size_t)(size))
|
||||
#define MEMCOPY(dest, src, size) \
|
||||
memcpy((void *)(dest), (const void *)(src), (size_t)(size))
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The modules that use fread() and fwrite() always invoke them through
|
||||
* these macros. On some systems you may need to twiddle the argument casts.
|
||||
* CAUTION: argument order is different from underlying functions!
|
||||
* These macros/inline functions facilitate using Microsoft's "safe string"
|
||||
* functions with Visual Studio builds without the need to scatter #ifdefs
|
||||
* throughout the code base.
|
||||
*/
|
||||
|
||||
#define JFREAD(file, buf, sizeofbuf) \
|
||||
((size_t)fread((void *)(buf), (size_t)1, (size_t)(sizeofbuf), (file)))
|
||||
#define JFWRITE(file, buf, sizeofbuf) \
|
||||
((size_t)fwrite((const void *)(buf), (size_t)1, (size_t)(sizeofbuf), (file)))
|
||||
|
||||
#ifndef NO_GETENV
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
static INLINE int GETENV_S(char *buffer, size_t buffer_size, const char *name)
|
||||
{
|
||||
size_t required_size;
|
||||
|
||||
return (int)getenv_s(&required_size, buffer, buffer_size, name);
|
||||
}
|
||||
|
||||
#else /* _MSC_VER */
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/* This provides a similar interface to the Microsoft/C11 getenv_s() function,
|
||||
* but other than parameter validation, it has no advantages over getenv().
|
||||
*/
|
||||
|
||||
static INLINE int GETENV_S(char *buffer, size_t buffer_size, const char *name)
|
||||
{
|
||||
char *env;
|
||||
|
||||
if (!buffer) {
|
||||
if (buffer_size == 0)
|
||||
return 0;
|
||||
else
|
||||
return (errno = EINVAL);
|
||||
}
|
||||
if (buffer_size == 0)
|
||||
return (errno = EINVAL);
|
||||
if (!name) {
|
||||
*buffer = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
env = getenv(name);
|
||||
if (!env)
|
||||
{
|
||||
*buffer = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strlen(env) + 1 > buffer_size) {
|
||||
*buffer = 0;
|
||||
return ERANGE;
|
||||
}
|
||||
|
||||
strncpy(buffer, env, buffer_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#endif /* NO_GETENV */
|
||||
|
||||
|
||||
#ifndef NO_PUTENV
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define PUTENV_S(name, value) _putenv_s(name, value)
|
||||
|
||||
#else
|
||||
|
||||
/* This provides a similar interface to the Microsoft _putenv_s() function, but
|
||||
* other than parameter validation, it has no advantages over setenv().
|
||||
*/
|
||||
|
||||
static INLINE int PUTENV_S(const char *name, const char *value)
|
||||
{
|
||||
if (!name || !value)
|
||||
return (errno = EINVAL);
|
||||
|
||||
setenv(name, value, 1);
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#endif /* NO_PUTENV */
|
||||
|
||||
|
||||
#endif /* JINCLUDE_H */
|
||||
|
||||
Vendored
+7
-9
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2016, 2021, D. R. Commander.
|
||||
* Copyright (C) 2016, 2021-2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -37,12 +37,6 @@
|
||||
#endif
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef NO_GETENV
|
||||
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare getenv() */
|
||||
extern char *getenv(const char *name);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
LOCAL(size_t)
|
||||
round_up_pow2(size_t a, size_t b)
|
||||
@@ -1162,12 +1156,16 @@ jinit_memory_mgr(j_common_ptr cinfo)
|
||||
*/
|
||||
#ifndef NO_GETENV
|
||||
{
|
||||
char *memenv;
|
||||
char memenv[30] = { 0 };
|
||||
|
||||
if ((memenv = getenv("JPEGMEM")) != NULL) {
|
||||
if (!GETENV_S(memenv, 30, "JPEGMEM") && strlen(memenv) > 0) {
|
||||
char ch = 'x';
|
||||
|
||||
#ifdef _MSC_VER
|
||||
if (sscanf_s(memenv, "%ld%c", &max_to_use, &ch, 1) > 0) {
|
||||
#else
|
||||
if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) {
|
||||
#endif
|
||||
if (ch == 'm' || ch == 'M')
|
||||
max_to_use *= 1000L;
|
||||
mem->pub.max_memory_to_use = max_to_use * 1000L;
|
||||
|
||||
-5
@@ -22,11 +22,6 @@
|
||||
#include "jpeglib.h"
|
||||
#include "jmemsys.h" /* import the system-dependent declarations */
|
||||
|
||||
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
|
||||
extern void *malloc(size_t size);
|
||||
extern void free(void *ptr);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Memory allocation and freeing are controlled by the regular library
|
||||
|
||||
-4
@@ -100,11 +100,7 @@ typedef unsigned char UINT8;
|
||||
|
||||
/* UINT16 must hold at least the values 0..65535. */
|
||||
|
||||
#ifdef HAVE_UNSIGNED_SHORT
|
||||
typedef unsigned short UINT16;
|
||||
#else /* not HAVE_UNSIGNED_SHORT */
|
||||
typedef unsigned int UINT16;
|
||||
#endif /* HAVE_UNSIGNED_SHORT */
|
||||
|
||||
/* INT16 must hold at least the values -32768..32767. */
|
||||
|
||||
|
||||
Vendored
-9
@@ -373,12 +373,3 @@ extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */
|
||||
|
||||
/* Arithmetic coding probability estimation tables in jaricom.c */
|
||||
extern const JLONG jpeg_aritab[];
|
||||
|
||||
/* Suppress undefined-structure complaints if necessary. */
|
||||
|
||||
#ifdef INCOMPLETE_TYPES_BROKEN
|
||||
#ifndef AM_MEMORY_MANAGER /* only jmemmgr.c defines these */
|
||||
struct jvirt_sarray_control { long dummy; };
|
||||
struct jvirt_barray_control { long dummy; };
|
||||
#endif
|
||||
#endif /* INCOMPLETE_TYPES_BROKEN */
|
||||
|
||||
+5
-4
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2013, D. R. Commander.
|
||||
* Copyright (C) 2013, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -29,7 +29,7 @@ add_huff_table(j_common_ptr cinfo, JHUFF_TBL **htblptr, const UINT8 *bits,
|
||||
return;
|
||||
|
||||
/* Copy the number-of-symbols-of-each-code-length counts */
|
||||
MEMCOPY((*htblptr)->bits, bits, sizeof((*htblptr)->bits));
|
||||
memcpy((*htblptr)->bits, bits, sizeof((*htblptr)->bits));
|
||||
|
||||
/* Validate the counts. We do this here mainly so we can copy the right
|
||||
* number of symbols from the val[] array, without risking marching off
|
||||
@@ -41,8 +41,9 @@ add_huff_table(j_common_ptr cinfo, JHUFF_TBL **htblptr, const UINT8 *bits,
|
||||
if (nsymbols < 1 || nsymbols > 256)
|
||||
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
|
||||
|
||||
MEMCOPY((*htblptr)->huffval, val, nsymbols * sizeof(UINT8));
|
||||
MEMZERO(&((*htblptr)->huffval[nsymbols]), (256 - nsymbols) * sizeof(UINT8));
|
||||
memcpy((*htblptr)->huffval, val, nsymbols * sizeof(UINT8));
|
||||
memset(&((*htblptr)->huffval[nsymbols]), 0,
|
||||
(256 - nsymbols) * sizeof(UINT8));
|
||||
|
||||
/* Initialize sent_table FALSE so table will be written to JPEG file. */
|
||||
(*htblptr)->sent_table = FALSE;
|
||||
|
||||
Vendored
+5
-5
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
||||
* It was modified by The libjpeg-turbo Project to include only code
|
||||
* relevant to libjpeg-turbo.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -110,7 +110,7 @@ jcopy_sample_rows(JSAMPARRAY input_array, int source_row,
|
||||
for (row = num_rows; row > 0; row--) {
|
||||
inptr = *input_array++;
|
||||
outptr = *output_array++;
|
||||
MEMCOPY(outptr, inptr, count);
|
||||
memcpy(outptr, inptr, count);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ jcopy_block_row(JBLOCKROW input_row, JBLOCKROW output_row,
|
||||
JDIMENSION num_blocks)
|
||||
/* Copy a row of coefficient blocks from one place to another. */
|
||||
{
|
||||
MEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * sizeof(JCOEF)));
|
||||
memcpy(output_row, input_row, num_blocks * (DCTSIZE2 * sizeof(JCOEF)));
|
||||
}
|
||||
|
||||
|
||||
@@ -129,5 +129,5 @@ jzero_far(void *target, size_t bytestozero)
|
||||
/* Zero out a chunk of memory. */
|
||||
/* This might be sample-array data, block-array data, or alloc_large data. */
|
||||
{
|
||||
MEMZERO(target, bytestozero);
|
||||
memset(target, 0, bytestozero);
|
||||
}
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* jversion.h
|
||||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010, 2012-2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
* This file contains software version identification.
|
||||
*/
|
||||
|
||||
|
||||
#if JPEG_LIB_VERSION >= 80
|
||||
|
||||
#define JVERSION "8d 15-Jan-2012"
|
||||
|
||||
#elif JPEG_LIB_VERSION >= 70
|
||||
|
||||
#define JVERSION "7 27-Jun-2009"
|
||||
|
||||
#else
|
||||
|
||||
#define JVERSION "6b 27-Mar-1998"
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NOTE: It is our convention to place the authors in the following order:
|
||||
* - libjpeg-turbo authors (2009-) in descending order of the date of their
|
||||
* most recent contribution to the project, then in ascending order of the
|
||||
* date of their first contribution to the project, then in alphabetical
|
||||
* order
|
||||
* - Upstream authors in descending order of the date of the first inclusion of
|
||||
* their code
|
||||
*/
|
||||
|
||||
#define JCOPYRIGHT \
|
||||
"Copyright (C) 2009-2022 D. R. Commander\n" \
|
||||
"Copyright (C) 2015, 2020 Google, Inc.\n" \
|
||||
"Copyright (C) 2019-2020 Arm Limited\n" \
|
||||
"Copyright (C) 2015-2016, 2018 Matthieu Darbois\n" \
|
||||
"Copyright (C) 2011-2016 Siarhei Siamashka\n" \
|
||||
"Copyright (C) 2015 Intel Corporation\n" \
|
||||
"Copyright (C) 2013-2014 Linaro Limited\n" \
|
||||
"Copyright (C) 2013-2014 MIPS Technologies, Inc.\n" \
|
||||
"Copyright (C) 2009, 2012 Pierre Ossman for Cendio AB\n" \
|
||||
"Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)\n" \
|
||||
"Copyright (C) 1999-2006 MIYASAKA Masaru\n" \
|
||||
"Copyright (C) 1991-2020 Thomas G. Lane, Guido Vollbeding"
|
||||
|
||||
#define JCOPYRIGHT_SHORT \
|
||||
"Copyright (C) @COPYRIGHT_YEAR@ The libjpeg-turbo Project and many others"
|
||||
+545
@@ -0,0 +1,545 @@
|
||||
macro(simd_fail message)
|
||||
message(STATUS "libjpeg-turbo(SIMD): ${message}. Performance will suffer.")
|
||||
set(WITH_SIMD 0 PARENT_SCOPE)
|
||||
endmacro()
|
||||
|
||||
macro(boolean_number var)
|
||||
if(${var})
|
||||
set(${var} 1 ${ARGN})
|
||||
else()
|
||||
set(${var} 0 ${ARGN})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
###############################################################################
|
||||
# x86[-64] (NASM)
|
||||
###############################################################################
|
||||
|
||||
if(CPU_TYPE STREQUAL "x86_64" OR CPU_TYPE STREQUAL "i386")
|
||||
|
||||
set(CMAKE_ASM_NASM_FLAGS_DEBUG_INIT "-g")
|
||||
set(CMAKE_ASM_NASM_FLAGS_RELWITHDEBINFO_INIT "-g")
|
||||
|
||||
# Allow the location of the NASM executable to be specified using the ASM_NASM
|
||||
# environment variable. This should happen automatically, but unfortunately
|
||||
# enable_language(ASM_NASM) doesn't parse the ASM_NASM environment variable
|
||||
# until after CMAKE_ASM_NASM_COMPILER has been populated with the results of
|
||||
# searching for NASM or Yasm in the PATH.
|
||||
if(NOT DEFINED CMAKE_ASM_NASM_COMPILER AND DEFINED ENV{ASM_NASM})
|
||||
set(CMAKE_ASM_NASM_COMPILER $ENV{ASM_NASM})
|
||||
endif()
|
||||
|
||||
if(CPU_TYPE STREQUAL "x86_64")
|
||||
if(CYGWIN)
|
||||
set(CMAKE_ASM_NASM_OBJECT_FORMAT win64)
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_ABI MATCHES "ELF X32")
|
||||
set(CMAKE_ASM_NASM_OBJECT_FORMAT elfx32)
|
||||
endif()
|
||||
elseif(CPU_TYPE STREQUAL "i386")
|
||||
if(BORLAND)
|
||||
set(CMAKE_ASM_NASM_OBJECT_FORMAT obj)
|
||||
elseif(CYGWIN)
|
||||
set(CMAKE_ASM_NASM_OBJECT_FORMAT win32)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
include(CheckLanguage)
|
||||
check_language(ASM_NASM)
|
||||
if(NOT CMAKE_ASM_NASM_COMPILER)
|
||||
simd_fail("SIMD extensions disabled: could not find NASM compiler")
|
||||
return()
|
||||
endif()
|
||||
|
||||
enable_language(ASM_NASM)
|
||||
message(STATUS "CMAKE_ASM_NASM_COMPILER = ${CMAKE_ASM_NASM_COMPILER}")
|
||||
|
||||
if(CMAKE_ASM_NASM_OBJECT_FORMAT MATCHES "^macho")
|
||||
set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DMACHO")
|
||||
elseif(CMAKE_ASM_NASM_OBJECT_FORMAT MATCHES "^elf")
|
||||
set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DELF")
|
||||
set(CMAKE_ASM_NASM_DEBUG_FORMAT "dwarf2")
|
||||
endif()
|
||||
if(CPU_TYPE STREQUAL "x86_64")
|
||||
if(WIN32 OR CYGWIN)
|
||||
set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DWIN64")
|
||||
endif()
|
||||
set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -D__x86_64__")
|
||||
elseif(CPU_TYPE STREQUAL "i386")
|
||||
if(BORLAND)
|
||||
set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DOBJ32")
|
||||
elseif(WIN32 OR CYGWIN)
|
||||
set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DWIN32")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_ASM_NASM_OBJECT_FORMAT)
|
||||
simd_fail("SIMD extensions disabled: could not determine NASM object format")
|
||||
return()
|
||||
endif()
|
||||
|
||||
get_filename_component(CMAKE_ASM_NASM_COMPILER_TYPE
|
||||
"${CMAKE_ASM_NASM_COMPILER}" NAME_WE)
|
||||
if(CMAKE_ASM_NASM_COMPILER_TYPE MATCHES "yasm")
|
||||
foreach(var CMAKE_ASM_NASM_FLAGS_DEBUG CMAKE_ASM_NASM_FLAGS_RELWITHDEBINFO)
|
||||
if(${var} STREQUAL "-g")
|
||||
if(CMAKE_ASM_NASM_DEBUG_FORMAT)
|
||||
set_property(CACHE ${var} PROPERTY VALUE "-g ${CMAKE_ASM_NASM_DEBUG_FORMAT}")
|
||||
else()
|
||||
set_property(CACHE ${var} PROPERTY VALUE "")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(NOT WIN32 AND (CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED))
|
||||
set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DPIC")
|
||||
endif()
|
||||
|
||||
string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
|
||||
set(EFFECTIVE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} ${CMAKE_ASM_NASM_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
|
||||
|
||||
set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -I\"${CMAKE_CURRENT_SOURCE_DIR}/nasm/\" -I\"${CMAKE_CURRENT_SOURCE_DIR}/${CPU_TYPE}/\"")
|
||||
|
||||
set(GREP grep)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
|
||||
set(GREP ggrep)
|
||||
endif()
|
||||
add_custom_target(jsimdcfg COMMAND
|
||||
${CMAKE_C_COMPILER} -E -I${CMAKE_BINARY_DIR} -I${CMAKE_CURRENT_BINARY_DIR}
|
||||
-I${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/nasm/jsimdcfg.inc.h |
|
||||
${GREP} -E '^[\;%]|^\ %' | sed 's%_cpp_protection_%%' |
|
||||
sed 's@% define@%define@g' >${CMAKE_CURRENT_SOURCE_DIR}/nasm/jsimdcfg.inc)
|
||||
set_target_properties(jsimdcfg PROPERTIES FOLDER "3rdparty")
|
||||
|
||||
if(CPU_TYPE STREQUAL "x86_64")
|
||||
set(SIMD_SOURCES x86_64/jsimdcpu.asm x86_64/jfdctflt-sse.asm
|
||||
x86_64/jccolor-sse2.asm x86_64/jcgray-sse2.asm x86_64/jchuff-sse2.asm
|
||||
x86_64/jcphuff-sse2.asm x86_64/jcsample-sse2.asm x86_64/jdcolor-sse2.asm
|
||||
x86_64/jdmerge-sse2.asm x86_64/jdsample-sse2.asm x86_64/jfdctfst-sse2.asm
|
||||
x86_64/jfdctint-sse2.asm x86_64/jidctflt-sse2.asm x86_64/jidctfst-sse2.asm
|
||||
x86_64/jidctint-sse2.asm x86_64/jidctred-sse2.asm x86_64/jquantf-sse2.asm
|
||||
x86_64/jquanti-sse2.asm
|
||||
x86_64/jccolor-avx2.asm x86_64/jcgray-avx2.asm x86_64/jcsample-avx2.asm
|
||||
x86_64/jdcolor-avx2.asm x86_64/jdmerge-avx2.asm x86_64/jdsample-avx2.asm
|
||||
x86_64/jfdctint-avx2.asm x86_64/jidctint-avx2.asm x86_64/jquanti-avx2.asm)
|
||||
else()
|
||||
set(SIMD_SOURCES i386/jsimdcpu.asm i386/jfdctflt-3dn.asm
|
||||
i386/jidctflt-3dn.asm i386/jquant-3dn.asm
|
||||
i386/jccolor-mmx.asm i386/jcgray-mmx.asm i386/jcsample-mmx.asm
|
||||
i386/jdcolor-mmx.asm i386/jdmerge-mmx.asm i386/jdsample-mmx.asm
|
||||
i386/jfdctfst-mmx.asm i386/jfdctint-mmx.asm i386/jidctfst-mmx.asm
|
||||
i386/jidctint-mmx.asm i386/jidctred-mmx.asm i386/jquant-mmx.asm
|
||||
i386/jfdctflt-sse.asm i386/jidctflt-sse.asm i386/jquant-sse.asm
|
||||
i386/jccolor-sse2.asm i386/jcgray-sse2.asm i386/jchuff-sse2.asm
|
||||
i386/jcphuff-sse2.asm i386/jcsample-sse2.asm i386/jdcolor-sse2.asm
|
||||
i386/jdmerge-sse2.asm i386/jdsample-sse2.asm i386/jfdctfst-sse2.asm
|
||||
i386/jfdctint-sse2.asm i386/jidctflt-sse2.asm i386/jidctfst-sse2.asm
|
||||
i386/jidctint-sse2.asm i386/jidctred-sse2.asm i386/jquantf-sse2.asm
|
||||
i386/jquanti-sse2.asm
|
||||
i386/jccolor-avx2.asm i386/jcgray-avx2.asm i386/jcsample-avx2.asm
|
||||
i386/jdcolor-avx2.asm i386/jdmerge-avx2.asm i386/jdsample-avx2.asm
|
||||
i386/jfdctint-avx2.asm i386/jidctint-avx2.asm i386/jquanti-avx2.asm)
|
||||
endif()
|
||||
|
||||
if(MSVC_IDE)
|
||||
set(OBJDIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
|
||||
string(REGEX REPLACE " " ";" CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS}")
|
||||
elseif(XCODE)
|
||||
set(OBJDIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
string(REGEX REPLACE " " ";" CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS}")
|
||||
endif()
|
||||
|
||||
file(GLOB INC_FILES nasm/*.inc)
|
||||
|
||||
foreach(file ${SIMD_SOURCES})
|
||||
set(OBJECT_DEPENDS "")
|
||||
if(${file} MATCHES jccolor)
|
||||
string(REGEX REPLACE "jccolor" "jccolext" DEPFILE ${file})
|
||||
set(OBJECT_DEPENDS ${OBJECT_DEPENDS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE})
|
||||
endif()
|
||||
if(${file} MATCHES jcgray)
|
||||
string(REGEX REPLACE "jcgray" "jcgryext" DEPFILE ${file})
|
||||
set(OBJECT_DEPENDS ${OBJECT_DEPENDS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE})
|
||||
endif()
|
||||
if(${file} MATCHES jdcolor)
|
||||
string(REGEX REPLACE "jdcolor" "jdcolext" DEPFILE ${file})
|
||||
set(OBJECT_DEPENDS ${OBJECT_DEPENDS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE})
|
||||
endif()
|
||||
if(${file} MATCHES jdmerge)
|
||||
string(REGEX REPLACE "jdmerge" "jdmrgext" DEPFILE ${file})
|
||||
set(OBJECT_DEPENDS ${OBJECT_DEPENDS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE})
|
||||
endif()
|
||||
set(OBJECT_DEPENDS ${OBJECT_DEPENDS} ${INC_FILES})
|
||||
if(MSVC_IDE OR XCODE)
|
||||
# The CMake Visual Studio generators do not work properly with the ASM_NASM
|
||||
# language, so we have to go rogue here and use a custom command like we
|
||||
# did in prior versions of libjpeg-turbo. (This is why we can't have nice
|
||||
# things.)
|
||||
string(REGEX REPLACE "${CPU_TYPE}/" "" filename ${file})
|
||||
set(SIMD_OBJ ${OBJDIR}/${filename}${CMAKE_C_OUTPUT_EXTENSION})
|
||||
add_custom_command(OUTPUT ${SIMD_OBJ} DEPENDS ${file} ${OBJECT_DEPENDS}
|
||||
COMMAND ${CMAKE_ASM_NASM_COMPILER} -f${CMAKE_ASM_NASM_OBJECT_FORMAT}
|
||||
${CMAKE_ASM_NASM_FLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/${file}
|
||||
-o${SIMD_OBJ})
|
||||
set(SIMD_OBJS ${SIMD_OBJS} ${SIMD_OBJ})
|
||||
else()
|
||||
set_source_files_properties(${file} PROPERTIES OBJECT_DEPENDS
|
||||
"${OBJECT_DEPENDS}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(MSVC_IDE OR XCODE)
|
||||
set(SIMD_OBJS ${SIMD_OBJS} PARENT_SCOPE)
|
||||
add_library(jsimd OBJECT ${CPU_TYPE}/jsimd.c)
|
||||
add_custom_target(jsimd-objs DEPENDS ${SIMD_OBJS})
|
||||
add_dependencies(jsimd jsimd-objs)
|
||||
set_target_properties(jsimd PROPERTIES FOLDER "3rdparty")
|
||||
set_target_properties(jsimd-objs PROPERTIES FOLDER "3rdparty")
|
||||
else()
|
||||
add_library(jsimd OBJECT ${SIMD_SOURCES} ${CPU_TYPE}/jsimd.c)
|
||||
endif()
|
||||
if(NOT WIN32 AND (CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED))
|
||||
set_target_properties(jsimd PROPERTIES POSITION_INDEPENDENT_CODE 1)
|
||||
endif()
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Arm (Intrinsics or GAS)
|
||||
###############################################################################
|
||||
|
||||
elseif(CPU_TYPE STREQUAL "arm64" OR CPU_TYPE STREQUAL "arm")
|
||||
|
||||
# If Neon instructions are not explicitly enabled at compile time (e.g. using
|
||||
# -mfpu=neon) with an AArch32 Linux or Android build, then the AArch32 SIMD
|
||||
# dispatcher will parse /proc/cpuinfo to determine whether the Neon SIMD
|
||||
# extensions can be enabled at run time. In order to support all AArch32 CPUs
|
||||
# using the same code base, i.e. to support run-time FPU and Neon
|
||||
# auto-detection, it is necessary to compile the scalar C source code using
|
||||
# -mfloat-abi=soft (which is usually the default) but compile the intrinsics
|
||||
# implementation of the Neon SIMD extensions using -mfloat-abi=softfp. The
|
||||
# following test determines whether -mfloat-abi=softfp should be explicitly
|
||||
# added to the compile flags for the intrinsics implementation of the Neon SIMD
|
||||
# extensions.
|
||||
|
||||
if(BITS EQUAL 32)
|
||||
check_c_source_compiles("
|
||||
#if defined(__ARM_NEON__) || (!defined(__linux__) && !defined(ANDROID) && !defined(__ANDROID__))
|
||||
#error \"Neon run-time auto-detection will not be used\"
|
||||
#endif
|
||||
#if __ARM_PCS_VFP == 1
|
||||
#error \"float ABI = hard\"
|
||||
#endif
|
||||
#if __SOFTFP__ != 1
|
||||
#error \"float ABI = softfp\"
|
||||
#endif
|
||||
int main(void) { return 0; }" NEED_SOFTFP_FOR_INTRINSICS)
|
||||
if(NEED_SOFTFP_FOR_INTRINSICS)
|
||||
set(SOFTFP_FLAG -mfloat-abi=softfp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BITS EQUAL 32)
|
||||
set(CMAKE_REQUIRED_FLAGS "-mfpu=neon ${SOFTFP_FLAG}")
|
||||
check_c_source_compiles("
|
||||
#include <arm_neon.h>
|
||||
int main(int argc, char **argv) {
|
||||
uint16x8_t input = vdupq_n_u16((uint16_t)argc);
|
||||
uint8x8_t output = vmovn_u16(input);
|
||||
return (int)output[0];
|
||||
}" HAVE_NEON)
|
||||
if(NOT HAVE_NEON)
|
||||
simd_fail("SIMD extensions not available for this architecture")
|
||||
return()
|
||||
endif()
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
#include <arm_neon.h>
|
||||
int main(int argc, char **argv) {
|
||||
int16_t input[] = {
|
||||
(int16_t)argc, (int16_t)argc, (int16_t)argc, (int16_t)argc,
|
||||
(int16_t)argc, (int16_t)argc, (int16_t)argc, (int16_t)argc,
|
||||
(int16_t)argc, (int16_t)argc, (int16_t)argc, (int16_t)argc
|
||||
};
|
||||
int16x4x3_t output = vld1_s16_x3(input);
|
||||
vst3_s16(input, output);
|
||||
return (int)input[0];
|
||||
}" HAVE_VLD1_S16_X3)
|
||||
check_c_source_compiles("
|
||||
#include <arm_neon.h>
|
||||
int main(int argc, char **argv) {
|
||||
uint16_t input[] = {
|
||||
(uint16_t)argc, (uint16_t)argc, (uint16_t)argc, (uint16_t)argc,
|
||||
(uint16_t)argc, (uint16_t)argc, (uint16_t)argc, (uint16_t)argc
|
||||
};
|
||||
uint16x4x2_t output = vld1_u16_x2(input);
|
||||
vst2_u16(input, output);
|
||||
return (int)input[0];
|
||||
}" HAVE_VLD1_U16_X2)
|
||||
check_c_source_compiles("
|
||||
#include <arm_neon.h>
|
||||
int main(int argc, char **argv) {
|
||||
uint8_t input[] = {
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc,
|
||||
(uint8_t)argc, (uint8_t)argc, (uint8_t)argc, (uint8_t)argc
|
||||
};
|
||||
uint8x16x4_t output = vld1q_u8_x4(input);
|
||||
vst4q_u8(input, output);
|
||||
return (int)input[0];
|
||||
}" HAVE_VLD1Q_U8_X4)
|
||||
if(BITS EQUAL 32)
|
||||
unset(CMAKE_REQUIRED_FLAGS)
|
||||
endif()
|
||||
configure_file(arm/neon-compat.h.in arm/neon-compat.h @ONLY)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/arm)
|
||||
|
||||
# GCC 11 and earlier and some older versions of Clang do not have a full or
|
||||
# optimal set of Neon intrinsics, so for performance reasons, when using those
|
||||
# compilers, we default to using the older GAS implementation of the Neon SIMD
|
||||
# extensions for certain algorithms. The presence or absence of the three
|
||||
# intrinsics we tested above is a reasonable proxy for this, except with GCC 10
|
||||
# and 11.
|
||||
if((HAVE_VLD1_S16_X3 AND HAVE_VLD1_U16_X2 AND HAVE_VLD1Q_U8_X4 AND
|
||||
(NOT CMAKE_COMPILER_IS_GNUCC OR
|
||||
CMAKE_C_COMPILER_VERSION VERSION_EQUAL 12.0.0 OR
|
||||
CMAKE_C_COMPILER_VERSION VERSION_GREATER 12.0.0)))
|
||||
set(DEFAULT_NEON_INTRINSICS 1)
|
||||
else()
|
||||
set(DEFAULT_NEON_INTRINSICS 0)
|
||||
endif()
|
||||
option(NEON_INTRINSICS
|
||||
"Because GCC (as of this writing) and some older versions of Clang do not have a full or optimal set of Neon intrinsics, for performance reasons, the default when building libjpeg-turbo with those compilers is to continue using the older GAS implementation of the Neon SIMD extensions for certain algorithms. Setting this option forces the full Neon intrinsics implementation to be used with all compilers. Unsetting this option forces the hybrid GAS/intrinsics implementation to be used with all compilers."
|
||||
${DEFAULT_NEON_INTRINSICS})
|
||||
if(NOT NEON_INTRINSICS)
|
||||
enable_language(ASM)
|
||||
|
||||
set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ASM_FLAGS}")
|
||||
|
||||
# Test whether gas-preprocessor.pl would be needed to build the GAS
|
||||
# implementation of the Neon SIMD extensions. If so, then automatically
|
||||
# enable the full Neon intrinsics implementation.
|
||||
if(CPU_TYPE STREQUAL "arm")
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/gastest.S "
|
||||
.text
|
||||
.fpu neon
|
||||
.arch armv7a
|
||||
.object_arch armv4
|
||||
.arm
|
||||
pld [r0]
|
||||
vmovn.u16 d0, q0")
|
||||
else()
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/gastest.S "
|
||||
.text
|
||||
MYVAR .req x0
|
||||
movi v0.16b, #100
|
||||
mov MYVAR, #100
|
||||
.unreq MYVAR")
|
||||
endif()
|
||||
separate_arguments(CMAKE_ASM_FLAGS_SEP UNIX_COMMAND "${CMAKE_ASM_FLAGS}")
|
||||
execute_process(COMMAND ${CMAKE_ASM_COMPILER} ${CMAKE_ASM_FLAGS_SEP}
|
||||
-x assembler-with-cpp -c ${CMAKE_CURRENT_BINARY_DIR}/gastest.S
|
||||
RESULT_VARIABLE RESULT OUTPUT_VARIABLE OUTPUT ERROR_VARIABLE ERROR)
|
||||
if(NOT RESULT EQUAL 0)
|
||||
message(STATUS "libjpeg-turbo(SIMD): GAS appears to be broken. Using the full Neon SIMD intrinsics implementation.")
|
||||
set(NEON_INTRINSICS 1 CACHE INTERNAL "" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
boolean_number(NEON_INTRINSICS PARENT_SCOPE)
|
||||
if(NEON_INTRINSICS)
|
||||
add_definitions(-DNEON_INTRINSICS)
|
||||
message(STATUS "Use full Neon SIMD intrinsics implementation (NEON_INTRINSICS = ${NEON_INTRINSICS})")
|
||||
else()
|
||||
message(STATUS "Use partial Neon SIMD intrinsics implementation (NEON_INTRINSICS = ${NEON_INTRINSICS})")
|
||||
endif()
|
||||
|
||||
set(SIMD_SOURCES arm/jcgray-neon.c arm/jcphuff-neon.c arm/jcsample-neon.c
|
||||
arm/jdmerge-neon.c arm/jdsample-neon.c arm/jfdctfst-neon.c
|
||||
arm/jidctred-neon.c arm/jquanti-neon.c)
|
||||
if(NEON_INTRINSICS)
|
||||
set(SIMD_SOURCES ${SIMD_SOURCES} arm/jccolor-neon.c arm/jidctint-neon.c)
|
||||
endif()
|
||||
if(NEON_INTRINSICS OR BITS EQUAL 64)
|
||||
set(SIMD_SOURCES ${SIMD_SOURCES} arm/jidctfst-neon.c)
|
||||
endif()
|
||||
if(NEON_INTRINSICS OR BITS EQUAL 32)
|
||||
set(SIMD_SOURCES ${SIMD_SOURCES} arm/aarch${BITS}/jchuff-neon.c
|
||||
arm/jdcolor-neon.c arm/jfdctint-neon.c)
|
||||
endif()
|
||||
if(BITS EQUAL 32)
|
||||
set_source_files_properties(${SIMD_SOURCES} COMPILE_FLAGS "-mfpu=neon ${SOFTFP_FLAG}")
|
||||
endif()
|
||||
if(NOT NEON_INTRINSICS)
|
||||
string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
|
||||
set(EFFECTIVE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${CMAKE_ASM_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
|
||||
message(STATUS "CMAKE_ASM_FLAGS = ${EFFECTIVE_ASM_FLAGS}")
|
||||
|
||||
set(SIMD_SOURCES ${SIMD_SOURCES} arm/aarch${BITS}/jsimd_neon.S)
|
||||
endif()
|
||||
|
||||
add_library(jsimd OBJECT ${SIMD_SOURCES} arm/aarch${BITS}/jsimd.c)
|
||||
|
||||
if(CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED)
|
||||
set_target_properties(jsimd PROPERTIES POSITION_INDEPENDENT_CODE 1)
|
||||
endif()
|
||||
|
||||
|
||||
###############################################################################
|
||||
# MIPS (GAS)
|
||||
###############################################################################
|
||||
|
||||
elseif(CPU_TYPE STREQUAL "mips" OR CPU_TYPE STREQUAL "mipsel")
|
||||
|
||||
enable_language(ASM)
|
||||
|
||||
string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
|
||||
set(EFFECTIVE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${CMAKE_ASM_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
|
||||
message(STATUS "CMAKE_ASM_FLAGS = ${EFFECTIVE_ASM_FLAGS}")
|
||||
|
||||
set(CMAKE_REQUIRED_FLAGS -mdspr2)
|
||||
|
||||
check_c_source_compiles("
|
||||
#if !(defined(__mips__) && __mips_isa_rev >= 2)
|
||||
#error MIPS DSPr2 is currently only available on MIPS32r2 platforms.
|
||||
#endif
|
||||
int main(void) {
|
||||
int c = 0, a = 0, b = 0;
|
||||
__asm__ __volatile__ (
|
||||
\"precr.qb.ph %[c], %[a], %[b]\"
|
||||
: [c] \"=r\" (c)
|
||||
: [a] \"r\" (a), [b] \"r\" (b)
|
||||
);
|
||||
return c;
|
||||
}" HAVE_DSPR2)
|
||||
|
||||
unset(CMAKE_REQUIRED_FLAGS)
|
||||
|
||||
if(NOT HAVE_DSPR2)
|
||||
simd_fail("SIMD extensions not available for this CPU")
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_library(jsimd OBJECT mips/jsimd_dspr2.S mips/jsimd.c)
|
||||
|
||||
if(CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED)
|
||||
set_target_properties(jsimd PROPERTIES POSITION_INDEPENDENT_CODE 1)
|
||||
endif()
|
||||
|
||||
###############################################################################
|
||||
# MIPS64 (Intrinsics)
|
||||
###############################################################################
|
||||
|
||||
elseif(CPU_TYPE STREQUAL "loongson" OR CPU_TYPE MATCHES "^mips64")
|
||||
|
||||
set(CMAKE_REQUIRED_FLAGS -Wa,-mloongson-mmi,-mloongson-ext)
|
||||
|
||||
check_c_source_compiles("
|
||||
int main(void) {
|
||||
int c = 0, a = 0, b = 0;
|
||||
asm (
|
||||
\"paddb %0, %1, %2\"
|
||||
: \"=f\" (c)
|
||||
: \"f\" (a), \"f\" (b)
|
||||
);
|
||||
return c;
|
||||
}" HAVE_MMI)
|
||||
|
||||
unset(CMAKE_REQUIRED_FLAGS)
|
||||
|
||||
if(NOT HAVE_MMI)
|
||||
simd_fail("SIMD extensions not available for this CPU")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(SIMD_SOURCES mips64/jccolor-mmi.c mips64/jcgray-mmi.c mips64/jcsample-mmi.c
|
||||
mips64/jdcolor-mmi.c mips64/jdmerge-mmi.c mips64/jdsample-mmi.c
|
||||
mips64/jfdctfst-mmi.c mips64/jfdctint-mmi.c mips64/jidctfst-mmi.c
|
||||
mips64/jidctint-mmi.c mips64/jquanti-mmi.c)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
foreach(file ${SIMD_SOURCES})
|
||||
set_property(SOURCE ${file} APPEND_STRING PROPERTY COMPILE_FLAGS
|
||||
" -fno-strict-aliasing")
|
||||
endforeach()
|
||||
endif()
|
||||
foreach(file ${SIMD_SOURCES})
|
||||
set_property(SOURCE ${file} APPEND_STRING PROPERTY COMPILE_FLAGS
|
||||
" -Wa,-mloongson-mmi,-mloongson-ext")
|
||||
endforeach()
|
||||
|
||||
add_library(jsimd OBJECT ${SIMD_SOURCES} mips64/jsimd.c)
|
||||
|
||||
if(CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED)
|
||||
set_target_properties(jsimd PROPERTIES POSITION_INDEPENDENT_CODE 1)
|
||||
endif()
|
||||
|
||||
###############################################################################
|
||||
# PowerPC (Intrinsics)
|
||||
###############################################################################
|
||||
|
||||
elseif(CPU_TYPE STREQUAL "powerpc")
|
||||
|
||||
set(CMAKE_REQUIRED_FLAGS -maltivec)
|
||||
|
||||
check_c_source_compiles("
|
||||
#include <altivec.h>
|
||||
int main(void) {
|
||||
__vector int vi = { 0, 0, 0, 0 };
|
||||
int i[4];
|
||||
vec_st(vi, 0, i);
|
||||
return i[0];
|
||||
}" HAVE_ALTIVEC)
|
||||
|
||||
unset(CMAKE_REQUIRED_FLAGS)
|
||||
|
||||
if(NOT HAVE_ALTIVEC)
|
||||
simd_fail("SIMD extensions not available for this CPU (PowerPC SPE)")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(SIMD_SOURCES powerpc/jccolor-altivec.c powerpc/jcgray-altivec.c
|
||||
powerpc/jcsample-altivec.c powerpc/jdcolor-altivec.c
|
||||
powerpc/jdmerge-altivec.c powerpc/jdsample-altivec.c
|
||||
powerpc/jfdctfst-altivec.c powerpc/jfdctint-altivec.c
|
||||
powerpc/jidctfst-altivec.c powerpc/jidctint-altivec.c
|
||||
powerpc/jquanti-altivec.c)
|
||||
|
||||
set_source_files_properties(${SIMD_SOURCES} PROPERTIES
|
||||
COMPILE_FLAGS -maltivec)
|
||||
|
||||
add_library(jsimd OBJECT ${SIMD_SOURCES} powerpc/jsimd.c)
|
||||
|
||||
if(CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED)
|
||||
set_target_properties(jsimd PROPERTIES POSITION_INDEPENDENT_CODE 1)
|
||||
endif()
|
||||
|
||||
|
||||
###############################################################################
|
||||
# None
|
||||
###############################################################################
|
||||
|
||||
else()
|
||||
|
||||
simd_fail("SIMD extensions not available for this CPU (${CMAKE_SYSTEM_PROCESSOR})")
|
||||
|
||||
endif() # CPU_TYPE
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* jccolext-neon.c - colorspace conversion (32-bit Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2020, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/* This file is included by jccolor-neon.c */
|
||||
|
||||
|
||||
/* RGB -> YCbCr conversion is defined by the following equations:
|
||||
* Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
|
||||
* Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + 128
|
||||
* Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + 128
|
||||
*
|
||||
* Avoid floating point arithmetic by using shifted integer constants:
|
||||
* 0.29899597 = 19595 * 2^-16
|
||||
* 0.58700561 = 38470 * 2^-16
|
||||
* 0.11399841 = 7471 * 2^-16
|
||||
* 0.16874695 = 11059 * 2^-16
|
||||
* 0.33125305 = 21709 * 2^-16
|
||||
* 0.50000000 = 32768 * 2^-16
|
||||
* 0.41868592 = 27439 * 2^-16
|
||||
* 0.08131409 = 5329 * 2^-16
|
||||
* These constants are defined in jccolor-neon.c
|
||||
*
|
||||
* We add the fixed-point equivalent of 0.5 to Cb and Cr, which effectively
|
||||
* rounds up or down the result via integer truncation.
|
||||
*/
|
||||
|
||||
void jsimd_rgb_ycc_convert_neon(JDIMENSION image_width, JSAMPARRAY input_buf,
|
||||
JSAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
int num_rows)
|
||||
{
|
||||
/* Pointer to RGB(X/A) input data */
|
||||
JSAMPROW inptr;
|
||||
/* Pointers to Y, Cb, and Cr output data */
|
||||
JSAMPROW outptr0, outptr1, outptr2;
|
||||
/* Allocate temporary buffer for final (image_width % 8) pixels in row. */
|
||||
ALIGN(16) uint8_t tmp_buf[8 * RGB_PIXELSIZE];
|
||||
|
||||
/* Set up conversion constants. */
|
||||
#ifdef HAVE_VLD1_U16_X2
|
||||
const uint16x4x2_t consts = vld1_u16_x2(jsimd_rgb_ycc_neon_consts);
|
||||
#else
|
||||
/* GCC does not currently support the intrinsic vld1_<type>_x2(). */
|
||||
const uint16x4_t consts1 = vld1_u16(jsimd_rgb_ycc_neon_consts);
|
||||
const uint16x4_t consts2 = vld1_u16(jsimd_rgb_ycc_neon_consts + 4);
|
||||
const uint16x4x2_t consts = { { consts1, consts2 } };
|
||||
#endif
|
||||
const uint32x4_t scaled_128_5 = vdupq_n_u32((128 << 16) + 32767);
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr = *input_buf++;
|
||||
outptr0 = output_buf[0][output_row];
|
||||
outptr1 = output_buf[1][output_row];
|
||||
outptr2 = output_buf[2][output_row];
|
||||
output_row++;
|
||||
|
||||
int cols_remaining = image_width;
|
||||
for (; cols_remaining > 0; cols_remaining -= 8) {
|
||||
|
||||
/* To prevent buffer overread by the vector load instructions, the last
|
||||
* (image_width % 8) columns of data are first memcopied to a temporary
|
||||
* buffer large enough to accommodate the vector load.
|
||||
*/
|
||||
if (cols_remaining < 8) {
|
||||
memcpy(tmp_buf, inptr, cols_remaining * RGB_PIXELSIZE);
|
||||
inptr = tmp_buf;
|
||||
}
|
||||
|
||||
#if RGB_PIXELSIZE == 4
|
||||
uint8x8x4_t input_pixels = vld4_u8(inptr);
|
||||
#else
|
||||
uint8x8x3_t input_pixels = vld3_u8(inptr);
|
||||
#endif
|
||||
uint16x8_t r = vmovl_u8(input_pixels.val[RGB_RED]);
|
||||
uint16x8_t g = vmovl_u8(input_pixels.val[RGB_GREEN]);
|
||||
uint16x8_t b = vmovl_u8(input_pixels.val[RGB_BLUE]);
|
||||
|
||||
/* Compute Y = 0.29900 * R + 0.58700 * G + 0.11400 * B */
|
||||
uint32x4_t y_low = vmull_lane_u16(vget_low_u16(r), consts.val[0], 0);
|
||||
y_low = vmlal_lane_u16(y_low, vget_low_u16(g), consts.val[0], 1);
|
||||
y_low = vmlal_lane_u16(y_low, vget_low_u16(b), consts.val[0], 2);
|
||||
uint32x4_t y_high = vmull_lane_u16(vget_high_u16(r), consts.val[0], 0);
|
||||
y_high = vmlal_lane_u16(y_high, vget_high_u16(g), consts.val[0], 1);
|
||||
y_high = vmlal_lane_u16(y_high, vget_high_u16(b), consts.val[0], 2);
|
||||
|
||||
/* Compute Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + 128 */
|
||||
uint32x4_t cb_low = scaled_128_5;
|
||||
cb_low = vmlsl_lane_u16(cb_low, vget_low_u16(r), consts.val[0], 3);
|
||||
cb_low = vmlsl_lane_u16(cb_low, vget_low_u16(g), consts.val[1], 0);
|
||||
cb_low = vmlal_lane_u16(cb_low, vget_low_u16(b), consts.val[1], 1);
|
||||
uint32x4_t cb_high = scaled_128_5;
|
||||
cb_high = vmlsl_lane_u16(cb_high, vget_high_u16(r), consts.val[0], 3);
|
||||
cb_high = vmlsl_lane_u16(cb_high, vget_high_u16(g), consts.val[1], 0);
|
||||
cb_high = vmlal_lane_u16(cb_high, vget_high_u16(b), consts.val[1], 1);
|
||||
|
||||
/* Compute Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + 128 */
|
||||
uint32x4_t cr_low = scaled_128_5;
|
||||
cr_low = vmlal_lane_u16(cr_low, vget_low_u16(r), consts.val[1], 1);
|
||||
cr_low = vmlsl_lane_u16(cr_low, vget_low_u16(g), consts.val[1], 2);
|
||||
cr_low = vmlsl_lane_u16(cr_low, vget_low_u16(b), consts.val[1], 3);
|
||||
uint32x4_t cr_high = scaled_128_5;
|
||||
cr_high = vmlal_lane_u16(cr_high, vget_high_u16(r), consts.val[1], 1);
|
||||
cr_high = vmlsl_lane_u16(cr_high, vget_high_u16(g), consts.val[1], 2);
|
||||
cr_high = vmlsl_lane_u16(cr_high, vget_high_u16(b), consts.val[1], 3);
|
||||
|
||||
/* Descale Y values (rounding right shift) and narrow to 16-bit. */
|
||||
uint16x8_t y_u16 = vcombine_u16(vrshrn_n_u32(y_low, 16),
|
||||
vrshrn_n_u32(y_high, 16));
|
||||
/* Descale Cb values (right shift) and narrow to 16-bit. */
|
||||
uint16x8_t cb_u16 = vcombine_u16(vshrn_n_u32(cb_low, 16),
|
||||
vshrn_n_u32(cb_high, 16));
|
||||
/* Descale Cr values (right shift) and narrow to 16-bit. */
|
||||
uint16x8_t cr_u16 = vcombine_u16(vshrn_n_u32(cr_low, 16),
|
||||
vshrn_n_u32(cr_high, 16));
|
||||
/* Narrow Y, Cb, and Cr values to 8-bit and store to memory. Buffer
|
||||
* overwrite is permitted up to the next multiple of ALIGN_SIZE bytes.
|
||||
*/
|
||||
vst1_u8(outptr0, vmovn_u16(y_u16));
|
||||
vst1_u8(outptr1, vmovn_u16(cb_u16));
|
||||
vst1_u8(outptr2, vmovn_u16(cr_u16));
|
||||
|
||||
/* Increment pointers. */
|
||||
inptr += (8 * RGB_PIXELSIZE);
|
||||
outptr0 += 8;
|
||||
outptr1 += 8;
|
||||
outptr2 += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,334 @@
|
||||
/*
|
||||
* jchuff-neon.c - Huffman entropy encoding (32-bit Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* NOTE: All referenced figures are from
|
||||
* Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../../jinclude.h"
|
||||
#include "../../../jpeglib.h"
|
||||
#include "../../../jsimd.h"
|
||||
#include "../../../jdct.h"
|
||||
#include "../../../jsimddct.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../jchuff.h"
|
||||
#include "neon-compat.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
|
||||
JOCTET *jsimd_huff_encode_one_block_neon(void *state, JOCTET *buffer,
|
||||
JCOEFPTR block, int last_dc_val,
|
||||
c_derived_tbl *dctbl,
|
||||
c_derived_tbl *actbl)
|
||||
{
|
||||
uint8_t block_nbits[DCTSIZE2];
|
||||
uint16_t block_diff[DCTSIZE2];
|
||||
|
||||
/* Load rows of coefficients from DCT block in zig-zag order. */
|
||||
|
||||
/* Compute DC coefficient difference value. (F.1.1.5.1) */
|
||||
int16x8_t row0 = vdupq_n_s16(block[0] - last_dc_val);
|
||||
row0 = vld1q_lane_s16(block + 1, row0, 1);
|
||||
row0 = vld1q_lane_s16(block + 8, row0, 2);
|
||||
row0 = vld1q_lane_s16(block + 16, row0, 3);
|
||||
row0 = vld1q_lane_s16(block + 9, row0, 4);
|
||||
row0 = vld1q_lane_s16(block + 2, row0, 5);
|
||||
row0 = vld1q_lane_s16(block + 3, row0, 6);
|
||||
row0 = vld1q_lane_s16(block + 10, row0, 7);
|
||||
|
||||
int16x8_t row1 = vld1q_dup_s16(block + 17);
|
||||
row1 = vld1q_lane_s16(block + 24, row1, 1);
|
||||
row1 = vld1q_lane_s16(block + 32, row1, 2);
|
||||
row1 = vld1q_lane_s16(block + 25, row1, 3);
|
||||
row1 = vld1q_lane_s16(block + 18, row1, 4);
|
||||
row1 = vld1q_lane_s16(block + 11, row1, 5);
|
||||
row1 = vld1q_lane_s16(block + 4, row1, 6);
|
||||
row1 = vld1q_lane_s16(block + 5, row1, 7);
|
||||
|
||||
int16x8_t row2 = vld1q_dup_s16(block + 12);
|
||||
row2 = vld1q_lane_s16(block + 19, row2, 1);
|
||||
row2 = vld1q_lane_s16(block + 26, row2, 2);
|
||||
row2 = vld1q_lane_s16(block + 33, row2, 3);
|
||||
row2 = vld1q_lane_s16(block + 40, row2, 4);
|
||||
row2 = vld1q_lane_s16(block + 48, row2, 5);
|
||||
row2 = vld1q_lane_s16(block + 41, row2, 6);
|
||||
row2 = vld1q_lane_s16(block + 34, row2, 7);
|
||||
|
||||
int16x8_t row3 = vld1q_dup_s16(block + 27);
|
||||
row3 = vld1q_lane_s16(block + 20, row3, 1);
|
||||
row3 = vld1q_lane_s16(block + 13, row3, 2);
|
||||
row3 = vld1q_lane_s16(block + 6, row3, 3);
|
||||
row3 = vld1q_lane_s16(block + 7, row3, 4);
|
||||
row3 = vld1q_lane_s16(block + 14, row3, 5);
|
||||
row3 = vld1q_lane_s16(block + 21, row3, 6);
|
||||
row3 = vld1q_lane_s16(block + 28, row3, 7);
|
||||
|
||||
int16x8_t abs_row0 = vabsq_s16(row0);
|
||||
int16x8_t abs_row1 = vabsq_s16(row1);
|
||||
int16x8_t abs_row2 = vabsq_s16(row2);
|
||||
int16x8_t abs_row3 = vabsq_s16(row3);
|
||||
|
||||
int16x8_t row0_lz = vclzq_s16(abs_row0);
|
||||
int16x8_t row1_lz = vclzq_s16(abs_row1);
|
||||
int16x8_t row2_lz = vclzq_s16(abs_row2);
|
||||
int16x8_t row3_lz = vclzq_s16(abs_row3);
|
||||
|
||||
/* Compute number of bits required to represent each coefficient. */
|
||||
uint8x8_t row0_nbits = vsub_u8(vdup_n_u8(16),
|
||||
vmovn_u16(vreinterpretq_u16_s16(row0_lz)));
|
||||
uint8x8_t row1_nbits = vsub_u8(vdup_n_u8(16),
|
||||
vmovn_u16(vreinterpretq_u16_s16(row1_lz)));
|
||||
uint8x8_t row2_nbits = vsub_u8(vdup_n_u8(16),
|
||||
vmovn_u16(vreinterpretq_u16_s16(row2_lz)));
|
||||
uint8x8_t row3_nbits = vsub_u8(vdup_n_u8(16),
|
||||
vmovn_u16(vreinterpretq_u16_s16(row3_lz)));
|
||||
|
||||
vst1_u8(block_nbits + 0 * DCTSIZE, row0_nbits);
|
||||
vst1_u8(block_nbits + 1 * DCTSIZE, row1_nbits);
|
||||
vst1_u8(block_nbits + 2 * DCTSIZE, row2_nbits);
|
||||
vst1_u8(block_nbits + 3 * DCTSIZE, row3_nbits);
|
||||
|
||||
uint16x8_t row0_mask =
|
||||
vshlq_u16(vreinterpretq_u16_s16(vshrq_n_s16(row0, 15)),
|
||||
vnegq_s16(row0_lz));
|
||||
uint16x8_t row1_mask =
|
||||
vshlq_u16(vreinterpretq_u16_s16(vshrq_n_s16(row1, 15)),
|
||||
vnegq_s16(row1_lz));
|
||||
uint16x8_t row2_mask =
|
||||
vshlq_u16(vreinterpretq_u16_s16(vshrq_n_s16(row2, 15)),
|
||||
vnegq_s16(row2_lz));
|
||||
uint16x8_t row3_mask =
|
||||
vshlq_u16(vreinterpretq_u16_s16(vshrq_n_s16(row3, 15)),
|
||||
vnegq_s16(row3_lz));
|
||||
|
||||
uint16x8_t row0_diff = veorq_u16(vreinterpretq_u16_s16(abs_row0), row0_mask);
|
||||
uint16x8_t row1_diff = veorq_u16(vreinterpretq_u16_s16(abs_row1), row1_mask);
|
||||
uint16x8_t row2_diff = veorq_u16(vreinterpretq_u16_s16(abs_row2), row2_mask);
|
||||
uint16x8_t row3_diff = veorq_u16(vreinterpretq_u16_s16(abs_row3), row3_mask);
|
||||
|
||||
/* Store diff values for rows 0, 1, 2, and 3. */
|
||||
vst1q_u16(block_diff + 0 * DCTSIZE, row0_diff);
|
||||
vst1q_u16(block_diff + 1 * DCTSIZE, row1_diff);
|
||||
vst1q_u16(block_diff + 2 * DCTSIZE, row2_diff);
|
||||
vst1q_u16(block_diff + 3 * DCTSIZE, row3_diff);
|
||||
|
||||
/* Load last four rows of coefficients from DCT block in zig-zag order. */
|
||||
int16x8_t row4 = vld1q_dup_s16(block + 35);
|
||||
row4 = vld1q_lane_s16(block + 42, row4, 1);
|
||||
row4 = vld1q_lane_s16(block + 49, row4, 2);
|
||||
row4 = vld1q_lane_s16(block + 56, row4, 3);
|
||||
row4 = vld1q_lane_s16(block + 57, row4, 4);
|
||||
row4 = vld1q_lane_s16(block + 50, row4, 5);
|
||||
row4 = vld1q_lane_s16(block + 43, row4, 6);
|
||||
row4 = vld1q_lane_s16(block + 36, row4, 7);
|
||||
|
||||
int16x8_t row5 = vld1q_dup_s16(block + 29);
|
||||
row5 = vld1q_lane_s16(block + 22, row5, 1);
|
||||
row5 = vld1q_lane_s16(block + 15, row5, 2);
|
||||
row5 = vld1q_lane_s16(block + 23, row5, 3);
|
||||
row5 = vld1q_lane_s16(block + 30, row5, 4);
|
||||
row5 = vld1q_lane_s16(block + 37, row5, 5);
|
||||
row5 = vld1q_lane_s16(block + 44, row5, 6);
|
||||
row5 = vld1q_lane_s16(block + 51, row5, 7);
|
||||
|
||||
int16x8_t row6 = vld1q_dup_s16(block + 58);
|
||||
row6 = vld1q_lane_s16(block + 59, row6, 1);
|
||||
row6 = vld1q_lane_s16(block + 52, row6, 2);
|
||||
row6 = vld1q_lane_s16(block + 45, row6, 3);
|
||||
row6 = vld1q_lane_s16(block + 38, row6, 4);
|
||||
row6 = vld1q_lane_s16(block + 31, row6, 5);
|
||||
row6 = vld1q_lane_s16(block + 39, row6, 6);
|
||||
row6 = vld1q_lane_s16(block + 46, row6, 7);
|
||||
|
||||
int16x8_t row7 = vld1q_dup_s16(block + 53);
|
||||
row7 = vld1q_lane_s16(block + 60, row7, 1);
|
||||
row7 = vld1q_lane_s16(block + 61, row7, 2);
|
||||
row7 = vld1q_lane_s16(block + 54, row7, 3);
|
||||
row7 = vld1q_lane_s16(block + 47, row7, 4);
|
||||
row7 = vld1q_lane_s16(block + 55, row7, 5);
|
||||
row7 = vld1q_lane_s16(block + 62, row7, 6);
|
||||
row7 = vld1q_lane_s16(block + 63, row7, 7);
|
||||
|
||||
int16x8_t abs_row4 = vabsq_s16(row4);
|
||||
int16x8_t abs_row5 = vabsq_s16(row5);
|
||||
int16x8_t abs_row6 = vabsq_s16(row6);
|
||||
int16x8_t abs_row7 = vabsq_s16(row7);
|
||||
|
||||
int16x8_t row4_lz = vclzq_s16(abs_row4);
|
||||
int16x8_t row5_lz = vclzq_s16(abs_row5);
|
||||
int16x8_t row6_lz = vclzq_s16(abs_row6);
|
||||
int16x8_t row7_lz = vclzq_s16(abs_row7);
|
||||
|
||||
/* Compute number of bits required to represent each coefficient. */
|
||||
uint8x8_t row4_nbits = vsub_u8(vdup_n_u8(16),
|
||||
vmovn_u16(vreinterpretq_u16_s16(row4_lz)));
|
||||
uint8x8_t row5_nbits = vsub_u8(vdup_n_u8(16),
|
||||
vmovn_u16(vreinterpretq_u16_s16(row5_lz)));
|
||||
uint8x8_t row6_nbits = vsub_u8(vdup_n_u8(16),
|
||||
vmovn_u16(vreinterpretq_u16_s16(row6_lz)));
|
||||
uint8x8_t row7_nbits = vsub_u8(vdup_n_u8(16),
|
||||
vmovn_u16(vreinterpretq_u16_s16(row7_lz)));
|
||||
|
||||
vst1_u8(block_nbits + 4 * DCTSIZE, row4_nbits);
|
||||
vst1_u8(block_nbits + 5 * DCTSIZE, row5_nbits);
|
||||
vst1_u8(block_nbits + 6 * DCTSIZE, row6_nbits);
|
||||
vst1_u8(block_nbits + 7 * DCTSIZE, row7_nbits);
|
||||
|
||||
uint16x8_t row4_mask =
|
||||
vshlq_u16(vreinterpretq_u16_s16(vshrq_n_s16(row4, 15)),
|
||||
vnegq_s16(row4_lz));
|
||||
uint16x8_t row5_mask =
|
||||
vshlq_u16(vreinterpretq_u16_s16(vshrq_n_s16(row5, 15)),
|
||||
vnegq_s16(row5_lz));
|
||||
uint16x8_t row6_mask =
|
||||
vshlq_u16(vreinterpretq_u16_s16(vshrq_n_s16(row6, 15)),
|
||||
vnegq_s16(row6_lz));
|
||||
uint16x8_t row7_mask =
|
||||
vshlq_u16(vreinterpretq_u16_s16(vshrq_n_s16(row7, 15)),
|
||||
vnegq_s16(row7_lz));
|
||||
|
||||
uint16x8_t row4_diff = veorq_u16(vreinterpretq_u16_s16(abs_row4), row4_mask);
|
||||
uint16x8_t row5_diff = veorq_u16(vreinterpretq_u16_s16(abs_row5), row5_mask);
|
||||
uint16x8_t row6_diff = veorq_u16(vreinterpretq_u16_s16(abs_row6), row6_mask);
|
||||
uint16x8_t row7_diff = veorq_u16(vreinterpretq_u16_s16(abs_row7), row7_mask);
|
||||
|
||||
/* Store diff values for rows 4, 5, 6, and 7. */
|
||||
vst1q_u16(block_diff + 4 * DCTSIZE, row4_diff);
|
||||
vst1q_u16(block_diff + 5 * DCTSIZE, row5_diff);
|
||||
vst1q_u16(block_diff + 6 * DCTSIZE, row6_diff);
|
||||
vst1q_u16(block_diff + 7 * DCTSIZE, row7_diff);
|
||||
|
||||
/* Construct bitmap to accelerate encoding of AC coefficients. A set bit
|
||||
* means that the corresponding coefficient != 0.
|
||||
*/
|
||||
uint8x8_t row0_nbits_gt0 = vcgt_u8(row0_nbits, vdup_n_u8(0));
|
||||
uint8x8_t row1_nbits_gt0 = vcgt_u8(row1_nbits, vdup_n_u8(0));
|
||||
uint8x8_t row2_nbits_gt0 = vcgt_u8(row2_nbits, vdup_n_u8(0));
|
||||
uint8x8_t row3_nbits_gt0 = vcgt_u8(row3_nbits, vdup_n_u8(0));
|
||||
uint8x8_t row4_nbits_gt0 = vcgt_u8(row4_nbits, vdup_n_u8(0));
|
||||
uint8x8_t row5_nbits_gt0 = vcgt_u8(row5_nbits, vdup_n_u8(0));
|
||||
uint8x8_t row6_nbits_gt0 = vcgt_u8(row6_nbits, vdup_n_u8(0));
|
||||
uint8x8_t row7_nbits_gt0 = vcgt_u8(row7_nbits, vdup_n_u8(0));
|
||||
|
||||
/* { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 } */
|
||||
const uint8x8_t bitmap_mask =
|
||||
vreinterpret_u8_u64(vmov_n_u64(0x0102040810204080));
|
||||
|
||||
row0_nbits_gt0 = vand_u8(row0_nbits_gt0, bitmap_mask);
|
||||
row1_nbits_gt0 = vand_u8(row1_nbits_gt0, bitmap_mask);
|
||||
row2_nbits_gt0 = vand_u8(row2_nbits_gt0, bitmap_mask);
|
||||
row3_nbits_gt0 = vand_u8(row3_nbits_gt0, bitmap_mask);
|
||||
row4_nbits_gt0 = vand_u8(row4_nbits_gt0, bitmap_mask);
|
||||
row5_nbits_gt0 = vand_u8(row5_nbits_gt0, bitmap_mask);
|
||||
row6_nbits_gt0 = vand_u8(row6_nbits_gt0, bitmap_mask);
|
||||
row7_nbits_gt0 = vand_u8(row7_nbits_gt0, bitmap_mask);
|
||||
|
||||
uint8x8_t bitmap_rows_10 = vpadd_u8(row1_nbits_gt0, row0_nbits_gt0);
|
||||
uint8x8_t bitmap_rows_32 = vpadd_u8(row3_nbits_gt0, row2_nbits_gt0);
|
||||
uint8x8_t bitmap_rows_54 = vpadd_u8(row5_nbits_gt0, row4_nbits_gt0);
|
||||
uint8x8_t bitmap_rows_76 = vpadd_u8(row7_nbits_gt0, row6_nbits_gt0);
|
||||
uint8x8_t bitmap_rows_3210 = vpadd_u8(bitmap_rows_32, bitmap_rows_10);
|
||||
uint8x8_t bitmap_rows_7654 = vpadd_u8(bitmap_rows_76, bitmap_rows_54);
|
||||
uint8x8_t bitmap = vpadd_u8(bitmap_rows_7654, bitmap_rows_3210);
|
||||
|
||||
/* Shift left to remove DC bit. */
|
||||
bitmap = vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(bitmap), 1));
|
||||
/* Move bitmap to 32-bit scalar registers. */
|
||||
uint32_t bitmap_1_32 = vget_lane_u32(vreinterpret_u32_u8(bitmap), 1);
|
||||
uint32_t bitmap_33_63 = vget_lane_u32(vreinterpret_u32_u8(bitmap), 0);
|
||||
|
||||
/* Set up state and bit buffer for output bitstream. */
|
||||
working_state *state_ptr = (working_state *)state;
|
||||
int free_bits = state_ptr->cur.free_bits;
|
||||
size_t put_buffer = state_ptr->cur.put_buffer;
|
||||
|
||||
/* Encode DC coefficient. */
|
||||
|
||||
unsigned int nbits = block_nbits[0];
|
||||
/* Emit Huffman-coded symbol and additional diff bits. */
|
||||
unsigned int diff = block_diff[0];
|
||||
PUT_CODE(dctbl->ehufco[nbits], dctbl->ehufsi[nbits], diff)
|
||||
|
||||
/* Encode AC coefficients. */
|
||||
|
||||
unsigned int r = 0; /* r = run length of zeros */
|
||||
unsigned int i = 1; /* i = number of coefficients encoded */
|
||||
/* Code and size information for a run length of 16 zero coefficients */
|
||||
const unsigned int code_0xf0 = actbl->ehufco[0xf0];
|
||||
const unsigned int size_0xf0 = actbl->ehufsi[0xf0];
|
||||
|
||||
while (bitmap_1_32 != 0) {
|
||||
r = BUILTIN_CLZ(bitmap_1_32);
|
||||
i += r;
|
||||
bitmap_1_32 <<= r;
|
||||
nbits = block_nbits[i];
|
||||
diff = block_diff[i];
|
||||
while (r > 15) {
|
||||
/* If run length > 15, emit special run-length-16 codes. */
|
||||
PUT_BITS(code_0xf0, size_0xf0)
|
||||
r -= 16;
|
||||
}
|
||||
/* Emit Huffman symbol for run length / number of bits. (F.1.2.2.1) */
|
||||
unsigned int rs = (r << 4) + nbits;
|
||||
PUT_CODE(actbl->ehufco[rs], actbl->ehufsi[rs], diff)
|
||||
i++;
|
||||
bitmap_1_32 <<= 1;
|
||||
}
|
||||
|
||||
r = 33 - i;
|
||||
i = 33;
|
||||
|
||||
while (bitmap_33_63 != 0) {
|
||||
unsigned int leading_zeros = BUILTIN_CLZ(bitmap_33_63);
|
||||
r += leading_zeros;
|
||||
i += leading_zeros;
|
||||
bitmap_33_63 <<= leading_zeros;
|
||||
nbits = block_nbits[i];
|
||||
diff = block_diff[i];
|
||||
while (r > 15) {
|
||||
/* If run length > 15, emit special run-length-16 codes. */
|
||||
PUT_BITS(code_0xf0, size_0xf0)
|
||||
r -= 16;
|
||||
}
|
||||
/* Emit Huffman symbol for run length / number of bits. (F.1.2.2.1) */
|
||||
unsigned int rs = (r << 4) + nbits;
|
||||
PUT_CODE(actbl->ehufco[rs], actbl->ehufsi[rs], diff)
|
||||
r = 0;
|
||||
i++;
|
||||
bitmap_33_63 <<= 1;
|
||||
}
|
||||
|
||||
/* If the last coefficient(s) were zero, emit an end-of-block (EOB) code.
|
||||
* The value of RS for the EOB code is 0.
|
||||
*/
|
||||
if (i != 64) {
|
||||
PUT_BITS(actbl->ehufco[0], actbl->ehufsi[0])
|
||||
}
|
||||
|
||||
state_ptr->cur.put_buffer = put_buffer;
|
||||
state_ptr->cur.free_bits = free_bits;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
+980
@@ -0,0 +1,980 @@
|
||||
/*
|
||||
* jsimd_arm.c
|
||||
*
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2011, Nokia Corporation and/or its subsidiary(-ies).
|
||||
* Copyright (C) 2009-2011, 2013-2014, 2016, 2018, 2022, D. R. Commander.
|
||||
* Copyright (C) 2015-2016, 2018, Matthieu Darbois.
|
||||
* Copyright (C) 2019, Google LLC.
|
||||
* Copyright (C) 2020, Arm Limited.
|
||||
*
|
||||
* Based on the x86 SIMD extension for IJG JPEG library,
|
||||
* Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
* For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
*
|
||||
* This file contains the interface between the "normal" portions
|
||||
* of the library and the SIMD implementations when running on a
|
||||
* 32-bit Arm architecture.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../../jinclude.h"
|
||||
#include "../../../jpeglib.h"
|
||||
#include "../../../jsimd.h"
|
||||
#include "../../../jdct.h"
|
||||
#include "../../../jsimddct.h"
|
||||
#include "../../jsimd.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static unsigned int simd_support = ~0;
|
||||
static unsigned int simd_huffman = 1;
|
||||
|
||||
#if !defined(__ARM_NEON__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
|
||||
|
||||
#define SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT (1024 * 1024)
|
||||
|
||||
LOCAL(int)
|
||||
check_feature(char *buffer, char *feature)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (*feature == 0)
|
||||
return 0;
|
||||
if (strncmp(buffer, "Features", 8) != 0)
|
||||
return 0;
|
||||
buffer += 8;
|
||||
while (isspace(*buffer))
|
||||
buffer++;
|
||||
|
||||
/* Check if 'feature' is present in the buffer as a separate word */
|
||||
while ((p = strstr(buffer, feature))) {
|
||||
if (p > buffer && !isspace(*(p - 1))) {
|
||||
buffer++;
|
||||
continue;
|
||||
}
|
||||
p += strlen(feature);
|
||||
if (*p != 0 && !isspace(*p)) {
|
||||
buffer++;
|
||||
continue;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOCAL(int)
|
||||
parse_proc_cpuinfo(int bufsize)
|
||||
{
|
||||
char *buffer = (char *)malloc(bufsize);
|
||||
FILE *fd;
|
||||
|
||||
simd_support = 0;
|
||||
|
||||
if (!buffer)
|
||||
return 0;
|
||||
|
||||
fd = fopen("/proc/cpuinfo", "r");
|
||||
if (fd) {
|
||||
while (fgets(buffer, bufsize, fd)) {
|
||||
if (!strchr(buffer, '\n') && !feof(fd)) {
|
||||
/* "impossible" happened - insufficient size of the buffer! */
|
||||
fclose(fd);
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
if (check_feature(buffer, "neon"))
|
||||
simd_support |= JSIMD_NEON;
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
free(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check what SIMD accelerations are supported.
|
||||
*
|
||||
* FIXME: This code is racy under a multi-threaded environment.
|
||||
*/
|
||||
LOCAL(void)
|
||||
init_simd(void)
|
||||
{
|
||||
#ifndef NO_GETENV
|
||||
char env[2] = { 0 };
|
||||
#endif
|
||||
#if !defined(__ARM_NEON__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
|
||||
int bufsize = 1024; /* an initial guess for the line buffer size limit */
|
||||
#endif
|
||||
|
||||
if (simd_support != ~0U)
|
||||
return;
|
||||
|
||||
simd_support = 0;
|
||||
|
||||
#if defined(__ARM_NEON__)
|
||||
simd_support |= JSIMD_NEON;
|
||||
#elif defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
|
||||
/* We still have a chance to use Neon regardless of globally used
|
||||
* -mcpu/-mfpu options passed to gcc by performing runtime detection via
|
||||
* /proc/cpuinfo parsing on linux/android */
|
||||
while (!parse_proc_cpuinfo(bufsize)) {
|
||||
bufsize *= 2;
|
||||
if (bufsize > SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NO_GETENV
|
||||
/* Force different settings through environment variables */
|
||||
if (!GETENV_S(env, 2, "JSIMD_FORCENEON") && !strcmp(env, "1"))
|
||||
simd_support = JSIMD_NEON;
|
||||
if (!GETENV_S(env, 2, "JSIMD_FORCENONE") && !strcmp(env, "1"))
|
||||
simd_support = 0;
|
||||
if (!GETENV_S(env, 2, "JSIMD_NOHUFFENC") && !strcmp(env, "1"))
|
||||
simd_huffman = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_rgb_ycc(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (BITS_IN_JSAMPLE != 8)
|
||||
return 0;
|
||||
if (sizeof(JDIMENSION) != 4)
|
||||
return 0;
|
||||
if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_rgb_gray(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (BITS_IN_JSAMPLE != 8)
|
||||
return 0;
|
||||
if (sizeof(JDIMENSION) != 4)
|
||||
return 0;
|
||||
if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_ycc_rgb(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (BITS_IN_JSAMPLE != 8)
|
||||
return 0;
|
||||
if (sizeof(JDIMENSION) != 4)
|
||||
return 0;
|
||||
if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_ycc_rgb565(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (BITS_IN_JSAMPLE != 8)
|
||||
return 0;
|
||||
if (sizeof(JDIMENSION) != 4)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_rgb_ycc_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
int num_rows)
|
||||
{
|
||||
void (*neonfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
|
||||
|
||||
switch (cinfo->in_color_space) {
|
||||
case JCS_EXT_RGB:
|
||||
neonfct = jsimd_extrgb_ycc_convert_neon;
|
||||
break;
|
||||
case JCS_EXT_RGBX:
|
||||
case JCS_EXT_RGBA:
|
||||
neonfct = jsimd_extrgbx_ycc_convert_neon;
|
||||
break;
|
||||
case JCS_EXT_BGR:
|
||||
neonfct = jsimd_extbgr_ycc_convert_neon;
|
||||
break;
|
||||
case JCS_EXT_BGRX:
|
||||
case JCS_EXT_BGRA:
|
||||
neonfct = jsimd_extbgrx_ycc_convert_neon;
|
||||
break;
|
||||
case JCS_EXT_XBGR:
|
||||
case JCS_EXT_ABGR:
|
||||
neonfct = jsimd_extxbgr_ycc_convert_neon;
|
||||
break;
|
||||
case JCS_EXT_XRGB:
|
||||
case JCS_EXT_ARGB:
|
||||
neonfct = jsimd_extxrgb_ycc_convert_neon;
|
||||
break;
|
||||
default:
|
||||
neonfct = jsimd_extrgb_ycc_convert_neon;
|
||||
break;
|
||||
}
|
||||
|
||||
neonfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
int num_rows)
|
||||
{
|
||||
void (*neonfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
|
||||
|
||||
switch (cinfo->in_color_space) {
|
||||
case JCS_EXT_RGB:
|
||||
neonfct = jsimd_extrgb_gray_convert_neon;
|
||||
break;
|
||||
case JCS_EXT_RGBX:
|
||||
case JCS_EXT_RGBA:
|
||||
neonfct = jsimd_extrgbx_gray_convert_neon;
|
||||
break;
|
||||
case JCS_EXT_BGR:
|
||||
neonfct = jsimd_extbgr_gray_convert_neon;
|
||||
break;
|
||||
case JCS_EXT_BGRX:
|
||||
case JCS_EXT_BGRA:
|
||||
neonfct = jsimd_extbgrx_gray_convert_neon;
|
||||
break;
|
||||
case JCS_EXT_XBGR:
|
||||
case JCS_EXT_ABGR:
|
||||
neonfct = jsimd_extxbgr_gray_convert_neon;
|
||||
break;
|
||||
case JCS_EXT_XRGB:
|
||||
case JCS_EXT_ARGB:
|
||||
neonfct = jsimd_extxrgb_gray_convert_neon;
|
||||
break;
|
||||
default:
|
||||
neonfct = jsimd_extrgb_gray_convert_neon;
|
||||
break;
|
||||
}
|
||||
|
||||
neonfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf,
|
||||
int num_rows)
|
||||
{
|
||||
void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
|
||||
|
||||
switch (cinfo->out_color_space) {
|
||||
case JCS_EXT_RGB:
|
||||
neonfct = jsimd_ycc_extrgb_convert_neon;
|
||||
break;
|
||||
case JCS_EXT_RGBX:
|
||||
case JCS_EXT_RGBA:
|
||||
neonfct = jsimd_ycc_extrgbx_convert_neon;
|
||||
break;
|
||||
case JCS_EXT_BGR:
|
||||
neonfct = jsimd_ycc_extbgr_convert_neon;
|
||||
break;
|
||||
case JCS_EXT_BGRX:
|
||||
case JCS_EXT_BGRA:
|
||||
neonfct = jsimd_ycc_extbgrx_convert_neon;
|
||||
break;
|
||||
case JCS_EXT_XBGR:
|
||||
case JCS_EXT_ABGR:
|
||||
neonfct = jsimd_ycc_extxbgr_convert_neon;
|
||||
break;
|
||||
case JCS_EXT_XRGB:
|
||||
case JCS_EXT_ARGB:
|
||||
neonfct = jsimd_ycc_extxrgb_convert_neon;
|
||||
break;
|
||||
default:
|
||||
neonfct = jsimd_ycc_extrgb_convert_neon;
|
||||
break;
|
||||
}
|
||||
|
||||
neonfct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf,
|
||||
int num_rows)
|
||||
{
|
||||
jsimd_ycc_rgb565_convert_neon(cinfo->output_width, input_buf, input_row,
|
||||
output_buf, num_rows);
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h2v2_downsample(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (BITS_IN_JSAMPLE != 8)
|
||||
return 0;
|
||||
if (DCTSIZE != 8)
|
||||
return 0;
|
||||
if (sizeof(JDIMENSION) != 4)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h2v1_downsample(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (BITS_IN_JSAMPLE != 8)
|
||||
return 0;
|
||||
if (DCTSIZE != 8)
|
||||
return 0;
|
||||
if (sizeof(JDIMENSION) != 4)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY output_data)
|
||||
{
|
||||
jsimd_h2v2_downsample_neon(cinfo->image_width, cinfo->max_v_samp_factor,
|
||||
compptr->v_samp_factor, compptr->width_in_blocks,
|
||||
input_data, output_data);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY output_data)
|
||||
{
|
||||
jsimd_h2v1_downsample_neon(cinfo->image_width, cinfo->max_v_samp_factor,
|
||||
compptr->v_samp_factor, compptr->width_in_blocks,
|
||||
input_data, output_data);
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h2v2_upsample(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (BITS_IN_JSAMPLE != 8)
|
||||
return 0;
|
||||
if (sizeof(JDIMENSION) != 4)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h2v1_upsample(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (BITS_IN_JSAMPLE != 8)
|
||||
return 0;
|
||||
if (sizeof(JDIMENSION) != 4)
|
||||
return 0;
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
jsimd_h2v2_upsample_neon(cinfo->max_v_samp_factor, cinfo->output_width,
|
||||
input_data, output_data_ptr);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
jsimd_h2v1_upsample_neon(cinfo->max_v_samp_factor, cinfo->output_width,
|
||||
input_data, output_data_ptr);
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h2v2_fancy_upsample(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (BITS_IN_JSAMPLE != 8)
|
||||
return 0;
|
||||
if (sizeof(JDIMENSION) != 4)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h2v1_fancy_upsample(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (BITS_IN_JSAMPLE != 8)
|
||||
return 0;
|
||||
if (sizeof(JDIMENSION) != 4)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h1v2_fancy_upsample(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (BITS_IN_JSAMPLE != 8)
|
||||
return 0;
|
||||
if (sizeof(JDIMENSION) != 4)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
jsimd_h2v2_fancy_upsample_neon(cinfo->max_v_samp_factor,
|
||||
compptr->downsampled_width, input_data,
|
||||
output_data_ptr);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
jsimd_h2v1_fancy_upsample_neon(cinfo->max_v_samp_factor,
|
||||
compptr->downsampled_width, input_data,
|
||||
output_data_ptr);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
jsimd_h1v2_fancy_upsample_neon(cinfo->max_v_samp_factor,
|
||||
compptr->downsampled_width, input_data,
|
||||
output_data_ptr);
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h2v2_merged_upsample(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (BITS_IN_JSAMPLE != 8)
|
||||
return 0;
|
||||
if (sizeof(JDIMENSION) != 4)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h2v1_merged_upsample(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (BITS_IN_JSAMPLE != 8)
|
||||
return 0;
|
||||
if (sizeof(JDIMENSION) != 4)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
|
||||
{
|
||||
void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
|
||||
|
||||
switch (cinfo->out_color_space) {
|
||||
case JCS_EXT_RGB:
|
||||
neonfct = jsimd_h2v2_extrgb_merged_upsample_neon;
|
||||
break;
|
||||
case JCS_EXT_RGBX:
|
||||
case JCS_EXT_RGBA:
|
||||
neonfct = jsimd_h2v2_extrgbx_merged_upsample_neon;
|
||||
break;
|
||||
case JCS_EXT_BGR:
|
||||
neonfct = jsimd_h2v2_extbgr_merged_upsample_neon;
|
||||
break;
|
||||
case JCS_EXT_BGRX:
|
||||
case JCS_EXT_BGRA:
|
||||
neonfct = jsimd_h2v2_extbgrx_merged_upsample_neon;
|
||||
break;
|
||||
case JCS_EXT_XBGR:
|
||||
case JCS_EXT_ABGR:
|
||||
neonfct = jsimd_h2v2_extxbgr_merged_upsample_neon;
|
||||
break;
|
||||
case JCS_EXT_XRGB:
|
||||
case JCS_EXT_ARGB:
|
||||
neonfct = jsimd_h2v2_extxrgb_merged_upsample_neon;
|
||||
break;
|
||||
default:
|
||||
neonfct = jsimd_h2v2_extrgb_merged_upsample_neon;
|
||||
break;
|
||||
}
|
||||
|
||||
neonfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
|
||||
{
|
||||
void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
|
||||
|
||||
switch (cinfo->out_color_space) {
|
||||
case JCS_EXT_RGB:
|
||||
neonfct = jsimd_h2v1_extrgb_merged_upsample_neon;
|
||||
break;
|
||||
case JCS_EXT_RGBX:
|
||||
case JCS_EXT_RGBA:
|
||||
neonfct = jsimd_h2v1_extrgbx_merged_upsample_neon;
|
||||
break;
|
||||
case JCS_EXT_BGR:
|
||||
neonfct = jsimd_h2v1_extbgr_merged_upsample_neon;
|
||||
break;
|
||||
case JCS_EXT_BGRX:
|
||||
case JCS_EXT_BGRA:
|
||||
neonfct = jsimd_h2v1_extbgrx_merged_upsample_neon;
|
||||
break;
|
||||
case JCS_EXT_XBGR:
|
||||
case JCS_EXT_ABGR:
|
||||
neonfct = jsimd_h2v1_extxbgr_merged_upsample_neon;
|
||||
break;
|
||||
case JCS_EXT_XRGB:
|
||||
case JCS_EXT_ARGB:
|
||||
neonfct = jsimd_h2v1_extxrgb_merged_upsample_neon;
|
||||
break;
|
||||
default:
|
||||
neonfct = jsimd_h2v1_extrgb_merged_upsample_neon;
|
||||
break;
|
||||
}
|
||||
|
||||
neonfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_convsamp(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (DCTSIZE != 8)
|
||||
return 0;
|
||||
if (BITS_IN_JSAMPLE != 8)
|
||||
return 0;
|
||||
if (sizeof(JDIMENSION) != 4)
|
||||
return 0;
|
||||
if (sizeof(DCTELEM) != 2)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_convsamp_float(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_convsamp(JSAMPARRAY sample_data, JDIMENSION start_col,
|
||||
DCTELEM *workspace)
|
||||
{
|
||||
jsimd_convsamp_neon(sample_data, start_col, workspace);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
|
||||
FAST_FLOAT *workspace)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_fdct_islow(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (DCTSIZE != 8)
|
||||
return 0;
|
||||
if (sizeof(DCTELEM) != 2)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_fdct_ifast(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (DCTSIZE != 8)
|
||||
return 0;
|
||||
if (sizeof(DCTELEM) != 2)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_fdct_float(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_fdct_islow(DCTELEM *data)
|
||||
{
|
||||
jsimd_fdct_islow_neon(data);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_fdct_ifast(DCTELEM *data)
|
||||
{
|
||||
jsimd_fdct_ifast_neon(data);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_fdct_float(FAST_FLOAT *data)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_quantize(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (DCTSIZE != 8)
|
||||
return 0;
|
||||
if (sizeof(JCOEF) != 2)
|
||||
return 0;
|
||||
if (sizeof(DCTELEM) != 2)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_quantize_float(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
|
||||
{
|
||||
jsimd_quantize_neon(coef_block, divisors, workspace);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
|
||||
FAST_FLOAT *workspace)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_idct_2x2(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (DCTSIZE != 8)
|
||||
return 0;
|
||||
if (sizeof(JCOEF) != 2)
|
||||
return 0;
|
||||
if (BITS_IN_JSAMPLE != 8)
|
||||
return 0;
|
||||
if (sizeof(JDIMENSION) != 4)
|
||||
return 0;
|
||||
if (sizeof(ISLOW_MULT_TYPE) != 2)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_idct_4x4(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (DCTSIZE != 8)
|
||||
return 0;
|
||||
if (sizeof(JCOEF) != 2)
|
||||
return 0;
|
||||
if (BITS_IN_JSAMPLE != 8)
|
||||
return 0;
|
||||
if (sizeof(JDIMENSION) != 4)
|
||||
return 0;
|
||||
if (sizeof(ISLOW_MULT_TYPE) != 2)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
jsimd_idct_2x2_neon(compptr->dct_table, coef_block, output_buf, output_col);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
jsimd_idct_4x4_neon(compptr->dct_table, coef_block, output_buf, output_col);
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_idct_islow(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (DCTSIZE != 8)
|
||||
return 0;
|
||||
if (sizeof(JCOEF) != 2)
|
||||
return 0;
|
||||
if (BITS_IN_JSAMPLE != 8)
|
||||
return 0;
|
||||
if (sizeof(JDIMENSION) != 4)
|
||||
return 0;
|
||||
if (sizeof(ISLOW_MULT_TYPE) != 2)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_idct_ifast(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
/* The code is optimised for these values only */
|
||||
if (DCTSIZE != 8)
|
||||
return 0;
|
||||
if (sizeof(JCOEF) != 2)
|
||||
return 0;
|
||||
if (BITS_IN_JSAMPLE != 8)
|
||||
return 0;
|
||||
if (sizeof(JDIMENSION) != 4)
|
||||
return 0;
|
||||
if (sizeof(IFAST_MULT_TYPE) != 2)
|
||||
return 0;
|
||||
if (IFAST_SCALE_BITS != 2)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_idct_float(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
jsimd_idct_islow_neon(compptr->dct_table, coef_block, output_buf,
|
||||
output_col);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
jsimd_idct_ifast_neon(compptr->dct_table, coef_block, output_buf,
|
||||
output_col);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_huff_encode_one_block(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
if (DCTSIZE != 8)
|
||||
return 0;
|
||||
if (sizeof(JCOEF) != 2)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON && simd_huffman)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(JOCTET *)
|
||||
jsimd_huff_encode_one_block(void *state, JOCTET *buffer, JCOEFPTR block,
|
||||
int last_dc_val, c_derived_tbl *dctbl,
|
||||
c_derived_tbl *actbl)
|
||||
{
|
||||
return jsimd_huff_encode_one_block_neon(state, buffer, block, last_dc_val,
|
||||
dctbl, actbl);
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_encode_mcu_AC_first_prepare(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
if (DCTSIZE != 8)
|
||||
return 0;
|
||||
if (sizeof(JCOEF) != 2)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_encode_mcu_AC_first_prepare(const JCOEF *block,
|
||||
const int *jpeg_natural_order_start, int Sl,
|
||||
int Al, JCOEF *values, size_t *zerobits)
|
||||
{
|
||||
jsimd_encode_mcu_AC_first_prepare_neon(block, jpeg_natural_order_start,
|
||||
Sl, Al, values, zerobits);
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_encode_mcu_AC_refine_prepare(void)
|
||||
{
|
||||
init_simd();
|
||||
|
||||
if (DCTSIZE != 8)
|
||||
return 0;
|
||||
if (sizeof(JCOEF) != 2)
|
||||
return 0;
|
||||
|
||||
if (simd_support & JSIMD_NEON)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_encode_mcu_AC_refine_prepare(const JCOEF *block,
|
||||
const int *jpeg_natural_order_start, int Sl,
|
||||
int Al, JCOEF *absvalues, size_t *bits)
|
||||
{
|
||||
return jsimd_encode_mcu_AC_refine_prepare_neon(block,
|
||||
jpeg_natural_order_start, Sl,
|
||||
Al, absvalues, bits);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* jccolext-neon.c - colorspace conversion (64-bit Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/* This file is included by jccolor-neon.c */
|
||||
|
||||
|
||||
/* RGB -> YCbCr conversion is defined by the following equations:
|
||||
* Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
|
||||
* Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + 128
|
||||
* Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + 128
|
||||
*
|
||||
* Avoid floating point arithmetic by using shifted integer constants:
|
||||
* 0.29899597 = 19595 * 2^-16
|
||||
* 0.58700561 = 38470 * 2^-16
|
||||
* 0.11399841 = 7471 * 2^-16
|
||||
* 0.16874695 = 11059 * 2^-16
|
||||
* 0.33125305 = 21709 * 2^-16
|
||||
* 0.50000000 = 32768 * 2^-16
|
||||
* 0.41868592 = 27439 * 2^-16
|
||||
* 0.08131409 = 5329 * 2^-16
|
||||
* These constants are defined in jccolor-neon.c
|
||||
*
|
||||
* We add the fixed-point equivalent of 0.5 to Cb and Cr, which effectively
|
||||
* rounds up or down the result via integer truncation.
|
||||
*/
|
||||
|
||||
void jsimd_rgb_ycc_convert_neon(JDIMENSION image_width, JSAMPARRAY input_buf,
|
||||
JSAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
int num_rows)
|
||||
{
|
||||
/* Pointer to RGB(X/A) input data */
|
||||
JSAMPROW inptr;
|
||||
/* Pointers to Y, Cb, and Cr output data */
|
||||
JSAMPROW outptr0, outptr1, outptr2;
|
||||
/* Allocate temporary buffer for final (image_width % 16) pixels in row. */
|
||||
ALIGN(16) uint8_t tmp_buf[16 * RGB_PIXELSIZE];
|
||||
|
||||
/* Set up conversion constants. */
|
||||
const uint16x8_t consts = vld1q_u16(jsimd_rgb_ycc_neon_consts);
|
||||
const uint32x4_t scaled_128_5 = vdupq_n_u32((128 << 16) + 32767);
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr = *input_buf++;
|
||||
outptr0 = output_buf[0][output_row];
|
||||
outptr1 = output_buf[1][output_row];
|
||||
outptr2 = output_buf[2][output_row];
|
||||
output_row++;
|
||||
|
||||
int cols_remaining = image_width;
|
||||
for (; cols_remaining >= 16; cols_remaining -= 16) {
|
||||
|
||||
#if RGB_PIXELSIZE == 4
|
||||
uint8x16x4_t input_pixels = vld4q_u8(inptr);
|
||||
#else
|
||||
uint8x16x3_t input_pixels = vld3q_u8(inptr);
|
||||
#endif
|
||||
uint16x8_t r_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_RED]));
|
||||
uint16x8_t g_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_GREEN]));
|
||||
uint16x8_t b_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_BLUE]));
|
||||
uint16x8_t r_h = vmovl_u8(vget_high_u8(input_pixels.val[RGB_RED]));
|
||||
uint16x8_t g_h = vmovl_u8(vget_high_u8(input_pixels.val[RGB_GREEN]));
|
||||
uint16x8_t b_h = vmovl_u8(vget_high_u8(input_pixels.val[RGB_BLUE]));
|
||||
|
||||
/* Compute Y = 0.29900 * R + 0.58700 * G + 0.11400 * B */
|
||||
uint32x4_t y_ll = vmull_laneq_u16(vget_low_u16(r_l), consts, 0);
|
||||
y_ll = vmlal_laneq_u16(y_ll, vget_low_u16(g_l), consts, 1);
|
||||
y_ll = vmlal_laneq_u16(y_ll, vget_low_u16(b_l), consts, 2);
|
||||
uint32x4_t y_lh = vmull_laneq_u16(vget_high_u16(r_l), consts, 0);
|
||||
y_lh = vmlal_laneq_u16(y_lh, vget_high_u16(g_l), consts, 1);
|
||||
y_lh = vmlal_laneq_u16(y_lh, vget_high_u16(b_l), consts, 2);
|
||||
uint32x4_t y_hl = vmull_laneq_u16(vget_low_u16(r_h), consts, 0);
|
||||
y_hl = vmlal_laneq_u16(y_hl, vget_low_u16(g_h), consts, 1);
|
||||
y_hl = vmlal_laneq_u16(y_hl, vget_low_u16(b_h), consts, 2);
|
||||
uint32x4_t y_hh = vmull_laneq_u16(vget_high_u16(r_h), consts, 0);
|
||||
y_hh = vmlal_laneq_u16(y_hh, vget_high_u16(g_h), consts, 1);
|
||||
y_hh = vmlal_laneq_u16(y_hh, vget_high_u16(b_h), consts, 2);
|
||||
|
||||
/* Compute Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + 128 */
|
||||
uint32x4_t cb_ll = scaled_128_5;
|
||||
cb_ll = vmlsl_laneq_u16(cb_ll, vget_low_u16(r_l), consts, 3);
|
||||
cb_ll = vmlsl_laneq_u16(cb_ll, vget_low_u16(g_l), consts, 4);
|
||||
cb_ll = vmlal_laneq_u16(cb_ll, vget_low_u16(b_l), consts, 5);
|
||||
uint32x4_t cb_lh = scaled_128_5;
|
||||
cb_lh = vmlsl_laneq_u16(cb_lh, vget_high_u16(r_l), consts, 3);
|
||||
cb_lh = vmlsl_laneq_u16(cb_lh, vget_high_u16(g_l), consts, 4);
|
||||
cb_lh = vmlal_laneq_u16(cb_lh, vget_high_u16(b_l), consts, 5);
|
||||
uint32x4_t cb_hl = scaled_128_5;
|
||||
cb_hl = vmlsl_laneq_u16(cb_hl, vget_low_u16(r_h), consts, 3);
|
||||
cb_hl = vmlsl_laneq_u16(cb_hl, vget_low_u16(g_h), consts, 4);
|
||||
cb_hl = vmlal_laneq_u16(cb_hl, vget_low_u16(b_h), consts, 5);
|
||||
uint32x4_t cb_hh = scaled_128_5;
|
||||
cb_hh = vmlsl_laneq_u16(cb_hh, vget_high_u16(r_h), consts, 3);
|
||||
cb_hh = vmlsl_laneq_u16(cb_hh, vget_high_u16(g_h), consts, 4);
|
||||
cb_hh = vmlal_laneq_u16(cb_hh, vget_high_u16(b_h), consts, 5);
|
||||
|
||||
/* Compute Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + 128 */
|
||||
uint32x4_t cr_ll = scaled_128_5;
|
||||
cr_ll = vmlal_laneq_u16(cr_ll, vget_low_u16(r_l), consts, 5);
|
||||
cr_ll = vmlsl_laneq_u16(cr_ll, vget_low_u16(g_l), consts, 6);
|
||||
cr_ll = vmlsl_laneq_u16(cr_ll, vget_low_u16(b_l), consts, 7);
|
||||
uint32x4_t cr_lh = scaled_128_5;
|
||||
cr_lh = vmlal_laneq_u16(cr_lh, vget_high_u16(r_l), consts, 5);
|
||||
cr_lh = vmlsl_laneq_u16(cr_lh, vget_high_u16(g_l), consts, 6);
|
||||
cr_lh = vmlsl_laneq_u16(cr_lh, vget_high_u16(b_l), consts, 7);
|
||||
uint32x4_t cr_hl = scaled_128_5;
|
||||
cr_hl = vmlal_laneq_u16(cr_hl, vget_low_u16(r_h), consts, 5);
|
||||
cr_hl = vmlsl_laneq_u16(cr_hl, vget_low_u16(g_h), consts, 6);
|
||||
cr_hl = vmlsl_laneq_u16(cr_hl, vget_low_u16(b_h), consts, 7);
|
||||
uint32x4_t cr_hh = scaled_128_5;
|
||||
cr_hh = vmlal_laneq_u16(cr_hh, vget_high_u16(r_h), consts, 5);
|
||||
cr_hh = vmlsl_laneq_u16(cr_hh, vget_high_u16(g_h), consts, 6);
|
||||
cr_hh = vmlsl_laneq_u16(cr_hh, vget_high_u16(b_h), consts, 7);
|
||||
|
||||
/* Descale Y values (rounding right shift) and narrow to 16-bit. */
|
||||
uint16x8_t y_l = vcombine_u16(vrshrn_n_u32(y_ll, 16),
|
||||
vrshrn_n_u32(y_lh, 16));
|
||||
uint16x8_t y_h = vcombine_u16(vrshrn_n_u32(y_hl, 16),
|
||||
vrshrn_n_u32(y_hh, 16));
|
||||
/* Descale Cb values (right shift) and narrow to 16-bit. */
|
||||
uint16x8_t cb_l = vcombine_u16(vshrn_n_u32(cb_ll, 16),
|
||||
vshrn_n_u32(cb_lh, 16));
|
||||
uint16x8_t cb_h = vcombine_u16(vshrn_n_u32(cb_hl, 16),
|
||||
vshrn_n_u32(cb_hh, 16));
|
||||
/* Descale Cr values (right shift) and narrow to 16-bit. */
|
||||
uint16x8_t cr_l = vcombine_u16(vshrn_n_u32(cr_ll, 16),
|
||||
vshrn_n_u32(cr_lh, 16));
|
||||
uint16x8_t cr_h = vcombine_u16(vshrn_n_u32(cr_hl, 16),
|
||||
vshrn_n_u32(cr_hh, 16));
|
||||
/* Narrow Y, Cb, and Cr values to 8-bit and store to memory. Buffer
|
||||
* overwrite is permitted up to the next multiple of ALIGN_SIZE bytes.
|
||||
*/
|
||||
vst1q_u8(outptr0, vcombine_u8(vmovn_u16(y_l), vmovn_u16(y_h)));
|
||||
vst1q_u8(outptr1, vcombine_u8(vmovn_u16(cb_l), vmovn_u16(cb_h)));
|
||||
vst1q_u8(outptr2, vcombine_u8(vmovn_u16(cr_l), vmovn_u16(cr_h)));
|
||||
|
||||
/* Increment pointers. */
|
||||
inptr += (16 * RGB_PIXELSIZE);
|
||||
outptr0 += 16;
|
||||
outptr1 += 16;
|
||||
outptr2 += 16;
|
||||
}
|
||||
|
||||
if (cols_remaining > 8) {
|
||||
/* To prevent buffer overread by the vector load instructions, the last
|
||||
* (image_width % 16) columns of data are first memcopied to a temporary
|
||||
* buffer large enough to accommodate the vector load.
|
||||
*/
|
||||
memcpy(tmp_buf, inptr, cols_remaining * RGB_PIXELSIZE);
|
||||
inptr = tmp_buf;
|
||||
|
||||
#if RGB_PIXELSIZE == 4
|
||||
uint8x16x4_t input_pixels = vld4q_u8(inptr);
|
||||
#else
|
||||
uint8x16x3_t input_pixels = vld3q_u8(inptr);
|
||||
#endif
|
||||
uint16x8_t r_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_RED]));
|
||||
uint16x8_t g_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_GREEN]));
|
||||
uint16x8_t b_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_BLUE]));
|
||||
uint16x8_t r_h = vmovl_u8(vget_high_u8(input_pixels.val[RGB_RED]));
|
||||
uint16x8_t g_h = vmovl_u8(vget_high_u8(input_pixels.val[RGB_GREEN]));
|
||||
uint16x8_t b_h = vmovl_u8(vget_high_u8(input_pixels.val[RGB_BLUE]));
|
||||
|
||||
/* Compute Y = 0.29900 * R + 0.58700 * G + 0.11400 * B */
|
||||
uint32x4_t y_ll = vmull_laneq_u16(vget_low_u16(r_l), consts, 0);
|
||||
y_ll = vmlal_laneq_u16(y_ll, vget_low_u16(g_l), consts, 1);
|
||||
y_ll = vmlal_laneq_u16(y_ll, vget_low_u16(b_l), consts, 2);
|
||||
uint32x4_t y_lh = vmull_laneq_u16(vget_high_u16(r_l), consts, 0);
|
||||
y_lh = vmlal_laneq_u16(y_lh, vget_high_u16(g_l), consts, 1);
|
||||
y_lh = vmlal_laneq_u16(y_lh, vget_high_u16(b_l), consts, 2);
|
||||
uint32x4_t y_hl = vmull_laneq_u16(vget_low_u16(r_h), consts, 0);
|
||||
y_hl = vmlal_laneq_u16(y_hl, vget_low_u16(g_h), consts, 1);
|
||||
y_hl = vmlal_laneq_u16(y_hl, vget_low_u16(b_h), consts, 2);
|
||||
uint32x4_t y_hh = vmull_laneq_u16(vget_high_u16(r_h), consts, 0);
|
||||
y_hh = vmlal_laneq_u16(y_hh, vget_high_u16(g_h), consts, 1);
|
||||
y_hh = vmlal_laneq_u16(y_hh, vget_high_u16(b_h), consts, 2);
|
||||
|
||||
/* Compute Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + 128 */
|
||||
uint32x4_t cb_ll = scaled_128_5;
|
||||
cb_ll = vmlsl_laneq_u16(cb_ll, vget_low_u16(r_l), consts, 3);
|
||||
cb_ll = vmlsl_laneq_u16(cb_ll, vget_low_u16(g_l), consts, 4);
|
||||
cb_ll = vmlal_laneq_u16(cb_ll, vget_low_u16(b_l), consts, 5);
|
||||
uint32x4_t cb_lh = scaled_128_5;
|
||||
cb_lh = vmlsl_laneq_u16(cb_lh, vget_high_u16(r_l), consts, 3);
|
||||
cb_lh = vmlsl_laneq_u16(cb_lh, vget_high_u16(g_l), consts, 4);
|
||||
cb_lh = vmlal_laneq_u16(cb_lh, vget_high_u16(b_l), consts, 5);
|
||||
uint32x4_t cb_hl = scaled_128_5;
|
||||
cb_hl = vmlsl_laneq_u16(cb_hl, vget_low_u16(r_h), consts, 3);
|
||||
cb_hl = vmlsl_laneq_u16(cb_hl, vget_low_u16(g_h), consts, 4);
|
||||
cb_hl = vmlal_laneq_u16(cb_hl, vget_low_u16(b_h), consts, 5);
|
||||
uint32x4_t cb_hh = scaled_128_5;
|
||||
cb_hh = vmlsl_laneq_u16(cb_hh, vget_high_u16(r_h), consts, 3);
|
||||
cb_hh = vmlsl_laneq_u16(cb_hh, vget_high_u16(g_h), consts, 4);
|
||||
cb_hh = vmlal_laneq_u16(cb_hh, vget_high_u16(b_h), consts, 5);
|
||||
|
||||
/* Compute Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + 128 */
|
||||
uint32x4_t cr_ll = scaled_128_5;
|
||||
cr_ll = vmlal_laneq_u16(cr_ll, vget_low_u16(r_l), consts, 5);
|
||||
cr_ll = vmlsl_laneq_u16(cr_ll, vget_low_u16(g_l), consts, 6);
|
||||
cr_ll = vmlsl_laneq_u16(cr_ll, vget_low_u16(b_l), consts, 7);
|
||||
uint32x4_t cr_lh = scaled_128_5;
|
||||
cr_lh = vmlal_laneq_u16(cr_lh, vget_high_u16(r_l), consts, 5);
|
||||
cr_lh = vmlsl_laneq_u16(cr_lh, vget_high_u16(g_l), consts, 6);
|
||||
cr_lh = vmlsl_laneq_u16(cr_lh, vget_high_u16(b_l), consts, 7);
|
||||
uint32x4_t cr_hl = scaled_128_5;
|
||||
cr_hl = vmlal_laneq_u16(cr_hl, vget_low_u16(r_h), consts, 5);
|
||||
cr_hl = vmlsl_laneq_u16(cr_hl, vget_low_u16(g_h), consts, 6);
|
||||
cr_hl = vmlsl_laneq_u16(cr_hl, vget_low_u16(b_h), consts, 7);
|
||||
uint32x4_t cr_hh = scaled_128_5;
|
||||
cr_hh = vmlal_laneq_u16(cr_hh, vget_high_u16(r_h), consts, 5);
|
||||
cr_hh = vmlsl_laneq_u16(cr_hh, vget_high_u16(g_h), consts, 6);
|
||||
cr_hh = vmlsl_laneq_u16(cr_hh, vget_high_u16(b_h), consts, 7);
|
||||
|
||||
/* Descale Y values (rounding right shift) and narrow to 16-bit. */
|
||||
uint16x8_t y_l = vcombine_u16(vrshrn_n_u32(y_ll, 16),
|
||||
vrshrn_n_u32(y_lh, 16));
|
||||
uint16x8_t y_h = vcombine_u16(vrshrn_n_u32(y_hl, 16),
|
||||
vrshrn_n_u32(y_hh, 16));
|
||||
/* Descale Cb values (right shift) and narrow to 16-bit. */
|
||||
uint16x8_t cb_l = vcombine_u16(vshrn_n_u32(cb_ll, 16),
|
||||
vshrn_n_u32(cb_lh, 16));
|
||||
uint16x8_t cb_h = vcombine_u16(vshrn_n_u32(cb_hl, 16),
|
||||
vshrn_n_u32(cb_hh, 16));
|
||||
/* Descale Cr values (right shift) and narrow to 16-bit. */
|
||||
uint16x8_t cr_l = vcombine_u16(vshrn_n_u32(cr_ll, 16),
|
||||
vshrn_n_u32(cr_lh, 16));
|
||||
uint16x8_t cr_h = vcombine_u16(vshrn_n_u32(cr_hl, 16),
|
||||
vshrn_n_u32(cr_hh, 16));
|
||||
/* Narrow Y, Cb, and Cr values to 8-bit and store to memory. Buffer
|
||||
* overwrite is permitted up to the next multiple of ALIGN_SIZE bytes.
|
||||
*/
|
||||
vst1q_u8(outptr0, vcombine_u8(vmovn_u16(y_l), vmovn_u16(y_h)));
|
||||
vst1q_u8(outptr1, vcombine_u8(vmovn_u16(cb_l), vmovn_u16(cb_h)));
|
||||
vst1q_u8(outptr2, vcombine_u8(vmovn_u16(cr_l), vmovn_u16(cr_h)));
|
||||
|
||||
} else if (cols_remaining > 0) {
|
||||
/* To prevent buffer overread by the vector load instructions, the last
|
||||
* (image_width % 8) columns of data are first memcopied to a temporary
|
||||
* buffer large enough to accommodate the vector load.
|
||||
*/
|
||||
memcpy(tmp_buf, inptr, cols_remaining * RGB_PIXELSIZE);
|
||||
inptr = tmp_buf;
|
||||
|
||||
#if RGB_PIXELSIZE == 4
|
||||
uint8x8x4_t input_pixels = vld4_u8(inptr);
|
||||
#else
|
||||
uint8x8x3_t input_pixels = vld3_u8(inptr);
|
||||
#endif
|
||||
uint16x8_t r = vmovl_u8(input_pixels.val[RGB_RED]);
|
||||
uint16x8_t g = vmovl_u8(input_pixels.val[RGB_GREEN]);
|
||||
uint16x8_t b = vmovl_u8(input_pixels.val[RGB_BLUE]);
|
||||
|
||||
/* Compute Y = 0.29900 * R + 0.58700 * G + 0.11400 * B */
|
||||
uint32x4_t y_l = vmull_laneq_u16(vget_low_u16(r), consts, 0);
|
||||
y_l = vmlal_laneq_u16(y_l, vget_low_u16(g), consts, 1);
|
||||
y_l = vmlal_laneq_u16(y_l, vget_low_u16(b), consts, 2);
|
||||
uint32x4_t y_h = vmull_laneq_u16(vget_high_u16(r), consts, 0);
|
||||
y_h = vmlal_laneq_u16(y_h, vget_high_u16(g), consts, 1);
|
||||
y_h = vmlal_laneq_u16(y_h, vget_high_u16(b), consts, 2);
|
||||
|
||||
/* Compute Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + 128 */
|
||||
uint32x4_t cb_l = scaled_128_5;
|
||||
cb_l = vmlsl_laneq_u16(cb_l, vget_low_u16(r), consts, 3);
|
||||
cb_l = vmlsl_laneq_u16(cb_l, vget_low_u16(g), consts, 4);
|
||||
cb_l = vmlal_laneq_u16(cb_l, vget_low_u16(b), consts, 5);
|
||||
uint32x4_t cb_h = scaled_128_5;
|
||||
cb_h = vmlsl_laneq_u16(cb_h, vget_high_u16(r), consts, 3);
|
||||
cb_h = vmlsl_laneq_u16(cb_h, vget_high_u16(g), consts, 4);
|
||||
cb_h = vmlal_laneq_u16(cb_h, vget_high_u16(b), consts, 5);
|
||||
|
||||
/* Compute Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + 128 */
|
||||
uint32x4_t cr_l = scaled_128_5;
|
||||
cr_l = vmlal_laneq_u16(cr_l, vget_low_u16(r), consts, 5);
|
||||
cr_l = vmlsl_laneq_u16(cr_l, vget_low_u16(g), consts, 6);
|
||||
cr_l = vmlsl_laneq_u16(cr_l, vget_low_u16(b), consts, 7);
|
||||
uint32x4_t cr_h = scaled_128_5;
|
||||
cr_h = vmlal_laneq_u16(cr_h, vget_high_u16(r), consts, 5);
|
||||
cr_h = vmlsl_laneq_u16(cr_h, vget_high_u16(g), consts, 6);
|
||||
cr_h = vmlsl_laneq_u16(cr_h, vget_high_u16(b), consts, 7);
|
||||
|
||||
/* Descale Y values (rounding right shift) and narrow to 16-bit. */
|
||||
uint16x8_t y_u16 = vcombine_u16(vrshrn_n_u32(y_l, 16),
|
||||
vrshrn_n_u32(y_h, 16));
|
||||
/* Descale Cb values (right shift) and narrow to 16-bit. */
|
||||
uint16x8_t cb_u16 = vcombine_u16(vshrn_n_u32(cb_l, 16),
|
||||
vshrn_n_u32(cb_h, 16));
|
||||
/* Descale Cr values (right shift) and narrow to 16-bit. */
|
||||
uint16x8_t cr_u16 = vcombine_u16(vshrn_n_u32(cr_l, 16),
|
||||
vshrn_n_u32(cr_h, 16));
|
||||
/* Narrow Y, Cb, and Cr values to 8-bit and store to memory. Buffer
|
||||
* overwrite is permitted up to the next multiple of ALIGN_SIZE bytes.
|
||||
*/
|
||||
vst1_u8(outptr0, vmovn_u16(y_u16));
|
||||
vst1_u8(outptr1, vmovn_u16(cb_u16));
|
||||
vst1_u8(outptr2, vmovn_u16(cr_u16));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
* jchuff-neon.c - Huffman entropy encoding (64-bit Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020-2021, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2020, 2022, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* NOTE: All referenced figures are from
|
||||
* Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../../jinclude.h"
|
||||
#include "../../../jpeglib.h"
|
||||
#include "../../../jsimd.h"
|
||||
#include "../../../jdct.h"
|
||||
#include "../../../jsimddct.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../align.h"
|
||||
#include "../jchuff.h"
|
||||
#include "neon-compat.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
|
||||
ALIGN(16) static const uint8_t jsimd_huff_encode_one_block_consts[] = {
|
||||
0, 1, 2, 3, 16, 17, 32, 33,
|
||||
18, 19, 4, 5, 6, 7, 20, 21,
|
||||
34, 35, 48, 49, 255, 255, 50, 51,
|
||||
36, 37, 22, 23, 8, 9, 10, 11,
|
||||
255, 255, 6, 7, 20, 21, 34, 35,
|
||||
48, 49, 255, 255, 50, 51, 36, 37,
|
||||
54, 55, 40, 41, 26, 27, 12, 13,
|
||||
14, 15, 28, 29, 42, 43, 56, 57,
|
||||
6, 7, 20, 21, 34, 35, 48, 49,
|
||||
50, 51, 36, 37, 22, 23, 8, 9,
|
||||
26, 27, 12, 13, 255, 255, 14, 15,
|
||||
28, 29, 42, 43, 56, 57, 255, 255,
|
||||
52, 53, 54, 55, 40, 41, 26, 27,
|
||||
12, 13, 255, 255, 14, 15, 28, 29,
|
||||
26, 27, 40, 41, 42, 43, 28, 29,
|
||||
14, 15, 30, 31, 44, 45, 46, 47
|
||||
};
|
||||
|
||||
/* The AArch64 implementation of the FLUSH() macro triggers a UBSan misaligned
|
||||
* address warning because the macro sometimes writes a 64-bit value to a
|
||||
* non-64-bit-aligned address. That behavior is technically undefined per
|
||||
* the C specification, but it is supported by the AArch64 architecture and
|
||||
* compilers.
|
||||
*/
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(undefined_behavior_sanitizer)
|
||||
__attribute__((no_sanitize("alignment")))
|
||||
#endif
|
||||
#endif
|
||||
JOCTET *jsimd_huff_encode_one_block_neon(void *state, JOCTET *buffer,
|
||||
JCOEFPTR block, int last_dc_val,
|
||||
c_derived_tbl *dctbl,
|
||||
c_derived_tbl *actbl)
|
||||
{
|
||||
uint16_t block_diff[DCTSIZE2];
|
||||
|
||||
/* Load lookup table indices for rows of zig-zag ordering. */
|
||||
#ifdef HAVE_VLD1Q_U8_X4
|
||||
const uint8x16x4_t idx_rows_0123 =
|
||||
vld1q_u8_x4(jsimd_huff_encode_one_block_consts + 0 * DCTSIZE);
|
||||
const uint8x16x4_t idx_rows_4567 =
|
||||
vld1q_u8_x4(jsimd_huff_encode_one_block_consts + 8 * DCTSIZE);
|
||||
#else
|
||||
/* GCC does not currently support intrinsics vl1dq_<type>_x4(). */
|
||||
const uint8x16x4_t idx_rows_0123 = { {
|
||||
vld1q_u8(jsimd_huff_encode_one_block_consts + 0 * DCTSIZE),
|
||||
vld1q_u8(jsimd_huff_encode_one_block_consts + 2 * DCTSIZE),
|
||||
vld1q_u8(jsimd_huff_encode_one_block_consts + 4 * DCTSIZE),
|
||||
vld1q_u8(jsimd_huff_encode_one_block_consts + 6 * DCTSIZE)
|
||||
} };
|
||||
const uint8x16x4_t idx_rows_4567 = { {
|
||||
vld1q_u8(jsimd_huff_encode_one_block_consts + 8 * DCTSIZE),
|
||||
vld1q_u8(jsimd_huff_encode_one_block_consts + 10 * DCTSIZE),
|
||||
vld1q_u8(jsimd_huff_encode_one_block_consts + 12 * DCTSIZE),
|
||||
vld1q_u8(jsimd_huff_encode_one_block_consts + 14 * DCTSIZE)
|
||||
} };
|
||||
#endif
|
||||
|
||||
/* Load 8x8 block of DCT coefficients. */
|
||||
#ifdef HAVE_VLD1Q_U8_X4
|
||||
const int8x16x4_t tbl_rows_0123 =
|
||||
vld1q_s8_x4((int8_t *)(block + 0 * DCTSIZE));
|
||||
const int8x16x4_t tbl_rows_4567 =
|
||||
vld1q_s8_x4((int8_t *)(block + 4 * DCTSIZE));
|
||||
#else
|
||||
const int8x16x4_t tbl_rows_0123 = { {
|
||||
vld1q_s8((int8_t *)(block + 0 * DCTSIZE)),
|
||||
vld1q_s8((int8_t *)(block + 1 * DCTSIZE)),
|
||||
vld1q_s8((int8_t *)(block + 2 * DCTSIZE)),
|
||||
vld1q_s8((int8_t *)(block + 3 * DCTSIZE))
|
||||
} };
|
||||
const int8x16x4_t tbl_rows_4567 = { {
|
||||
vld1q_s8((int8_t *)(block + 4 * DCTSIZE)),
|
||||
vld1q_s8((int8_t *)(block + 5 * DCTSIZE)),
|
||||
vld1q_s8((int8_t *)(block + 6 * DCTSIZE)),
|
||||
vld1q_s8((int8_t *)(block + 7 * DCTSIZE))
|
||||
} };
|
||||
#endif
|
||||
|
||||
/* Initialise extra lookup tables. */
|
||||
const int8x16x4_t tbl_rows_2345 = { {
|
||||
tbl_rows_0123.val[2], tbl_rows_0123.val[3],
|
||||
tbl_rows_4567.val[0], tbl_rows_4567.val[1]
|
||||
} };
|
||||
const int8x16x3_t tbl_rows_567 =
|
||||
{ { tbl_rows_4567.val[1], tbl_rows_4567.val[2], tbl_rows_4567.val[3] } };
|
||||
|
||||
/* Shuffle coefficients into zig-zag order. */
|
||||
int16x8_t row0 =
|
||||
vreinterpretq_s16_s8(vqtbl4q_s8(tbl_rows_0123, idx_rows_0123.val[0]));
|
||||
int16x8_t row1 =
|
||||
vreinterpretq_s16_s8(vqtbl4q_s8(tbl_rows_0123, idx_rows_0123.val[1]));
|
||||
int16x8_t row2 =
|
||||
vreinterpretq_s16_s8(vqtbl4q_s8(tbl_rows_2345, idx_rows_0123.val[2]));
|
||||
int16x8_t row3 =
|
||||
vreinterpretq_s16_s8(vqtbl4q_s8(tbl_rows_0123, idx_rows_0123.val[3]));
|
||||
int16x8_t row4 =
|
||||
vreinterpretq_s16_s8(vqtbl4q_s8(tbl_rows_4567, idx_rows_4567.val[0]));
|
||||
int16x8_t row5 =
|
||||
vreinterpretq_s16_s8(vqtbl4q_s8(tbl_rows_2345, idx_rows_4567.val[1]));
|
||||
int16x8_t row6 =
|
||||
vreinterpretq_s16_s8(vqtbl4q_s8(tbl_rows_4567, idx_rows_4567.val[2]));
|
||||
int16x8_t row7 =
|
||||
vreinterpretq_s16_s8(vqtbl3q_s8(tbl_rows_567, idx_rows_4567.val[3]));
|
||||
|
||||
/* Compute DC coefficient difference value (F.1.1.5.1). */
|
||||
row0 = vsetq_lane_s16(block[0] - last_dc_val, row0, 0);
|
||||
/* Initialize AC coefficient lanes not reachable by lookup tables. */
|
||||
row1 =
|
||||
vsetq_lane_s16(vgetq_lane_s16(vreinterpretq_s16_s8(tbl_rows_4567.val[0]),
|
||||
0), row1, 2);
|
||||
row2 =
|
||||
vsetq_lane_s16(vgetq_lane_s16(vreinterpretq_s16_s8(tbl_rows_0123.val[1]),
|
||||
4), row2, 0);
|
||||
row2 =
|
||||
vsetq_lane_s16(vgetq_lane_s16(vreinterpretq_s16_s8(tbl_rows_4567.val[2]),
|
||||
0), row2, 5);
|
||||
row5 =
|
||||
vsetq_lane_s16(vgetq_lane_s16(vreinterpretq_s16_s8(tbl_rows_0123.val[1]),
|
||||
7), row5, 2);
|
||||
row5 =
|
||||
vsetq_lane_s16(vgetq_lane_s16(vreinterpretq_s16_s8(tbl_rows_4567.val[2]),
|
||||
3), row5, 7);
|
||||
row6 =
|
||||
vsetq_lane_s16(vgetq_lane_s16(vreinterpretq_s16_s8(tbl_rows_0123.val[3]),
|
||||
7), row6, 5);
|
||||
|
||||
/* DCT block is now in zig-zag order; start Huffman encoding process. */
|
||||
|
||||
/* Construct bitmap to accelerate encoding of AC coefficients. A set bit
|
||||
* means that the corresponding coefficient != 0.
|
||||
*/
|
||||
uint16x8_t row0_ne_0 = vtstq_s16(row0, row0);
|
||||
uint16x8_t row1_ne_0 = vtstq_s16(row1, row1);
|
||||
uint16x8_t row2_ne_0 = vtstq_s16(row2, row2);
|
||||
uint16x8_t row3_ne_0 = vtstq_s16(row3, row3);
|
||||
uint16x8_t row4_ne_0 = vtstq_s16(row4, row4);
|
||||
uint16x8_t row5_ne_0 = vtstq_s16(row5, row5);
|
||||
uint16x8_t row6_ne_0 = vtstq_s16(row6, row6);
|
||||
uint16x8_t row7_ne_0 = vtstq_s16(row7, row7);
|
||||
|
||||
uint8x16_t row10_ne_0 = vuzp1q_u8(vreinterpretq_u8_u16(row1_ne_0),
|
||||
vreinterpretq_u8_u16(row0_ne_0));
|
||||
uint8x16_t row32_ne_0 = vuzp1q_u8(vreinterpretq_u8_u16(row3_ne_0),
|
||||
vreinterpretq_u8_u16(row2_ne_0));
|
||||
uint8x16_t row54_ne_0 = vuzp1q_u8(vreinterpretq_u8_u16(row5_ne_0),
|
||||
vreinterpretq_u8_u16(row4_ne_0));
|
||||
uint8x16_t row76_ne_0 = vuzp1q_u8(vreinterpretq_u8_u16(row7_ne_0),
|
||||
vreinterpretq_u8_u16(row6_ne_0));
|
||||
|
||||
/* { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 } */
|
||||
const uint8x16_t bitmap_mask =
|
||||
vreinterpretq_u8_u64(vdupq_n_u64(0x0102040810204080));
|
||||
|
||||
uint8x16_t bitmap_rows_10 = vandq_u8(row10_ne_0, bitmap_mask);
|
||||
uint8x16_t bitmap_rows_32 = vandq_u8(row32_ne_0, bitmap_mask);
|
||||
uint8x16_t bitmap_rows_54 = vandq_u8(row54_ne_0, bitmap_mask);
|
||||
uint8x16_t bitmap_rows_76 = vandq_u8(row76_ne_0, bitmap_mask);
|
||||
|
||||
uint8x16_t bitmap_rows_3210 = vpaddq_u8(bitmap_rows_32, bitmap_rows_10);
|
||||
uint8x16_t bitmap_rows_7654 = vpaddq_u8(bitmap_rows_76, bitmap_rows_54);
|
||||
uint8x16_t bitmap_rows_76543210 = vpaddq_u8(bitmap_rows_7654,
|
||||
bitmap_rows_3210);
|
||||
uint8x8_t bitmap_all = vpadd_u8(vget_low_u8(bitmap_rows_76543210),
|
||||
vget_high_u8(bitmap_rows_76543210));
|
||||
|
||||
/* Shift left to remove DC bit. */
|
||||
bitmap_all =
|
||||
vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(bitmap_all), 1));
|
||||
/* Count bits set (number of non-zero coefficients) in bitmap. */
|
||||
unsigned int non_zero_coefficients = vaddv_u8(vcnt_u8(bitmap_all));
|
||||
/* Move bitmap to 64-bit scalar register. */
|
||||
uint64_t bitmap = vget_lane_u64(vreinterpret_u64_u8(bitmap_all), 0);
|
||||
|
||||
/* Set up state and bit buffer for output bitstream. */
|
||||
working_state *state_ptr = (working_state *)state;
|
||||
int free_bits = state_ptr->cur.free_bits;
|
||||
size_t put_buffer = state_ptr->cur.put_buffer;
|
||||
|
||||
/* Encode DC coefficient. */
|
||||
|
||||
/* For negative coeffs: diff = abs(coeff) -1 = ~abs(coeff) */
|
||||
int16x8_t abs_row0 = vabsq_s16(row0);
|
||||
int16x8_t row0_lz = vclzq_s16(abs_row0);
|
||||
uint16x8_t row0_mask = vshlq_u16(vcltzq_s16(row0), vnegq_s16(row0_lz));
|
||||
uint16x8_t row0_diff = veorq_u16(vreinterpretq_u16_s16(abs_row0), row0_mask);
|
||||
/* Find nbits required to specify sign and amplitude of coefficient. */
|
||||
unsigned int lz = vgetq_lane_u16(vreinterpretq_u16_s16(row0_lz), 0);
|
||||
unsigned int nbits = 16 - lz;
|
||||
/* Emit Huffman-coded symbol and additional diff bits. */
|
||||
unsigned int diff = vgetq_lane_u16(row0_diff, 0);
|
||||
PUT_CODE(dctbl->ehufco[nbits], dctbl->ehufsi[nbits], diff)
|
||||
|
||||
/* Encode AC coefficients. */
|
||||
|
||||
unsigned int r = 0; /* r = run length of zeros */
|
||||
unsigned int i = 1; /* i = number of coefficients encoded */
|
||||
/* Code and size information for a run length of 16 zero coefficients */
|
||||
const unsigned int code_0xf0 = actbl->ehufco[0xf0];
|
||||
const unsigned int size_0xf0 = actbl->ehufsi[0xf0];
|
||||
|
||||
/* The most efficient method of computing nbits and diff depends on the
|
||||
* number of non-zero coefficients. If the bitmap is not too sparse (> 8
|
||||
* non-zero AC coefficients), it is beneficial to do all of the work using
|
||||
* Neon; else we do some of the work using Neon and the rest on demand using
|
||||
* scalar code.
|
||||
*/
|
||||
if (non_zero_coefficients > 8) {
|
||||
uint8_t block_nbits[DCTSIZE2];
|
||||
|
||||
int16x8_t abs_row1 = vabsq_s16(row1);
|
||||
int16x8_t abs_row2 = vabsq_s16(row2);
|
||||
int16x8_t abs_row3 = vabsq_s16(row3);
|
||||
int16x8_t abs_row4 = vabsq_s16(row4);
|
||||
int16x8_t abs_row5 = vabsq_s16(row5);
|
||||
int16x8_t abs_row6 = vabsq_s16(row6);
|
||||
int16x8_t abs_row7 = vabsq_s16(row7);
|
||||
int16x8_t row1_lz = vclzq_s16(abs_row1);
|
||||
int16x8_t row2_lz = vclzq_s16(abs_row2);
|
||||
int16x8_t row3_lz = vclzq_s16(abs_row3);
|
||||
int16x8_t row4_lz = vclzq_s16(abs_row4);
|
||||
int16x8_t row5_lz = vclzq_s16(abs_row5);
|
||||
int16x8_t row6_lz = vclzq_s16(abs_row6);
|
||||
int16x8_t row7_lz = vclzq_s16(abs_row7);
|
||||
/* Narrow leading zero count to 8 bits. */
|
||||
uint8x16_t row01_lz = vuzp1q_u8(vreinterpretq_u8_s16(row0_lz),
|
||||
vreinterpretq_u8_s16(row1_lz));
|
||||
uint8x16_t row23_lz = vuzp1q_u8(vreinterpretq_u8_s16(row2_lz),
|
||||
vreinterpretq_u8_s16(row3_lz));
|
||||
uint8x16_t row45_lz = vuzp1q_u8(vreinterpretq_u8_s16(row4_lz),
|
||||
vreinterpretq_u8_s16(row5_lz));
|
||||
uint8x16_t row67_lz = vuzp1q_u8(vreinterpretq_u8_s16(row6_lz),
|
||||
vreinterpretq_u8_s16(row7_lz));
|
||||
/* Compute nbits needed to specify magnitude of each coefficient. */
|
||||
uint8x16_t row01_nbits = vsubq_u8(vdupq_n_u8(16), row01_lz);
|
||||
uint8x16_t row23_nbits = vsubq_u8(vdupq_n_u8(16), row23_lz);
|
||||
uint8x16_t row45_nbits = vsubq_u8(vdupq_n_u8(16), row45_lz);
|
||||
uint8x16_t row67_nbits = vsubq_u8(vdupq_n_u8(16), row67_lz);
|
||||
/* Store nbits. */
|
||||
vst1q_u8(block_nbits + 0 * DCTSIZE, row01_nbits);
|
||||
vst1q_u8(block_nbits + 2 * DCTSIZE, row23_nbits);
|
||||
vst1q_u8(block_nbits + 4 * DCTSIZE, row45_nbits);
|
||||
vst1q_u8(block_nbits + 6 * DCTSIZE, row67_nbits);
|
||||
/* Mask bits not required to specify sign and amplitude of diff. */
|
||||
uint16x8_t row1_mask = vshlq_u16(vcltzq_s16(row1), vnegq_s16(row1_lz));
|
||||
uint16x8_t row2_mask = vshlq_u16(vcltzq_s16(row2), vnegq_s16(row2_lz));
|
||||
uint16x8_t row3_mask = vshlq_u16(vcltzq_s16(row3), vnegq_s16(row3_lz));
|
||||
uint16x8_t row4_mask = vshlq_u16(vcltzq_s16(row4), vnegq_s16(row4_lz));
|
||||
uint16x8_t row5_mask = vshlq_u16(vcltzq_s16(row5), vnegq_s16(row5_lz));
|
||||
uint16x8_t row6_mask = vshlq_u16(vcltzq_s16(row6), vnegq_s16(row6_lz));
|
||||
uint16x8_t row7_mask = vshlq_u16(vcltzq_s16(row7), vnegq_s16(row7_lz));
|
||||
/* diff = abs(coeff) ^ sign(coeff) [no-op for positive coefficients] */
|
||||
uint16x8_t row1_diff = veorq_u16(vreinterpretq_u16_s16(abs_row1),
|
||||
row1_mask);
|
||||
uint16x8_t row2_diff = veorq_u16(vreinterpretq_u16_s16(abs_row2),
|
||||
row2_mask);
|
||||
uint16x8_t row3_diff = veorq_u16(vreinterpretq_u16_s16(abs_row3),
|
||||
row3_mask);
|
||||
uint16x8_t row4_diff = veorq_u16(vreinterpretq_u16_s16(abs_row4),
|
||||
row4_mask);
|
||||
uint16x8_t row5_diff = veorq_u16(vreinterpretq_u16_s16(abs_row5),
|
||||
row5_mask);
|
||||
uint16x8_t row6_diff = veorq_u16(vreinterpretq_u16_s16(abs_row6),
|
||||
row6_mask);
|
||||
uint16x8_t row7_diff = veorq_u16(vreinterpretq_u16_s16(abs_row7),
|
||||
row7_mask);
|
||||
/* Store diff bits. */
|
||||
vst1q_u16(block_diff + 0 * DCTSIZE, row0_diff);
|
||||
vst1q_u16(block_diff + 1 * DCTSIZE, row1_diff);
|
||||
vst1q_u16(block_diff + 2 * DCTSIZE, row2_diff);
|
||||
vst1q_u16(block_diff + 3 * DCTSIZE, row3_diff);
|
||||
vst1q_u16(block_diff + 4 * DCTSIZE, row4_diff);
|
||||
vst1q_u16(block_diff + 5 * DCTSIZE, row5_diff);
|
||||
vst1q_u16(block_diff + 6 * DCTSIZE, row6_diff);
|
||||
vst1q_u16(block_diff + 7 * DCTSIZE, row7_diff);
|
||||
|
||||
while (bitmap != 0) {
|
||||
r = BUILTIN_CLZLL(bitmap);
|
||||
i += r;
|
||||
bitmap <<= r;
|
||||
nbits = block_nbits[i];
|
||||
diff = block_diff[i];
|
||||
while (r > 15) {
|
||||
/* If run length > 15, emit special run-length-16 codes. */
|
||||
PUT_BITS(code_0xf0, size_0xf0)
|
||||
r -= 16;
|
||||
}
|
||||
/* Emit Huffman symbol for run length / number of bits. (F.1.2.2.1) */
|
||||
unsigned int rs = (r << 4) + nbits;
|
||||
PUT_CODE(actbl->ehufco[rs], actbl->ehufsi[rs], diff)
|
||||
i++;
|
||||
bitmap <<= 1;
|
||||
}
|
||||
} else if (bitmap != 0) {
|
||||
uint16_t block_abs[DCTSIZE2];
|
||||
/* Compute and store absolute value of coefficients. */
|
||||
int16x8_t abs_row1 = vabsq_s16(row1);
|
||||
int16x8_t abs_row2 = vabsq_s16(row2);
|
||||
int16x8_t abs_row3 = vabsq_s16(row3);
|
||||
int16x8_t abs_row4 = vabsq_s16(row4);
|
||||
int16x8_t abs_row5 = vabsq_s16(row5);
|
||||
int16x8_t abs_row6 = vabsq_s16(row6);
|
||||
int16x8_t abs_row7 = vabsq_s16(row7);
|
||||
vst1q_u16(block_abs + 0 * DCTSIZE, vreinterpretq_u16_s16(abs_row0));
|
||||
vst1q_u16(block_abs + 1 * DCTSIZE, vreinterpretq_u16_s16(abs_row1));
|
||||
vst1q_u16(block_abs + 2 * DCTSIZE, vreinterpretq_u16_s16(abs_row2));
|
||||
vst1q_u16(block_abs + 3 * DCTSIZE, vreinterpretq_u16_s16(abs_row3));
|
||||
vst1q_u16(block_abs + 4 * DCTSIZE, vreinterpretq_u16_s16(abs_row4));
|
||||
vst1q_u16(block_abs + 5 * DCTSIZE, vreinterpretq_u16_s16(abs_row5));
|
||||
vst1q_u16(block_abs + 6 * DCTSIZE, vreinterpretq_u16_s16(abs_row6));
|
||||
vst1q_u16(block_abs + 7 * DCTSIZE, vreinterpretq_u16_s16(abs_row7));
|
||||
/* Compute diff bits (without nbits mask) and store. */
|
||||
uint16x8_t row1_diff = veorq_u16(vreinterpretq_u16_s16(abs_row1),
|
||||
vcltzq_s16(row1));
|
||||
uint16x8_t row2_diff = veorq_u16(vreinterpretq_u16_s16(abs_row2),
|
||||
vcltzq_s16(row2));
|
||||
uint16x8_t row3_diff = veorq_u16(vreinterpretq_u16_s16(abs_row3),
|
||||
vcltzq_s16(row3));
|
||||
uint16x8_t row4_diff = veorq_u16(vreinterpretq_u16_s16(abs_row4),
|
||||
vcltzq_s16(row4));
|
||||
uint16x8_t row5_diff = veorq_u16(vreinterpretq_u16_s16(abs_row5),
|
||||
vcltzq_s16(row5));
|
||||
uint16x8_t row6_diff = veorq_u16(vreinterpretq_u16_s16(abs_row6),
|
||||
vcltzq_s16(row6));
|
||||
uint16x8_t row7_diff = veorq_u16(vreinterpretq_u16_s16(abs_row7),
|
||||
vcltzq_s16(row7));
|
||||
vst1q_u16(block_diff + 0 * DCTSIZE, row0_diff);
|
||||
vst1q_u16(block_diff + 1 * DCTSIZE, row1_diff);
|
||||
vst1q_u16(block_diff + 2 * DCTSIZE, row2_diff);
|
||||
vst1q_u16(block_diff + 3 * DCTSIZE, row3_diff);
|
||||
vst1q_u16(block_diff + 4 * DCTSIZE, row4_diff);
|
||||
vst1q_u16(block_diff + 5 * DCTSIZE, row5_diff);
|
||||
vst1q_u16(block_diff + 6 * DCTSIZE, row6_diff);
|
||||
vst1q_u16(block_diff + 7 * DCTSIZE, row7_diff);
|
||||
|
||||
/* Same as above but must mask diff bits and compute nbits on demand. */
|
||||
while (bitmap != 0) {
|
||||
r = BUILTIN_CLZLL(bitmap);
|
||||
i += r;
|
||||
bitmap <<= r;
|
||||
lz = BUILTIN_CLZ(block_abs[i]);
|
||||
nbits = 32 - lz;
|
||||
diff = ((unsigned int)block_diff[i] << lz) >> lz;
|
||||
while (r > 15) {
|
||||
/* If run length > 15, emit special run-length-16 codes. */
|
||||
PUT_BITS(code_0xf0, size_0xf0)
|
||||
r -= 16;
|
||||
}
|
||||
/* Emit Huffman symbol for run length / number of bits. (F.1.2.2.1) */
|
||||
unsigned int rs = (r << 4) + nbits;
|
||||
PUT_CODE(actbl->ehufco[rs], actbl->ehufsi[rs], diff)
|
||||
i++;
|
||||
bitmap <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the last coefficient(s) were zero, emit an end-of-block (EOB) code.
|
||||
* The value of RS for the EOB code is 0.
|
||||
*/
|
||||
if (i != 64) {
|
||||
PUT_BITS(actbl->ehufco[0], actbl->ehufsi[0])
|
||||
}
|
||||
|
||||
state_ptr->cur.put_buffer = put_buffer;
|
||||
state_ptr->cur.free_bits = free_bits;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
+1058
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/* How to obtain memory alignment for structures and variables */
|
||||
#if defined(_MSC_VER)
|
||||
#define ALIGN(alignment) __declspec(align(alignment))
|
||||
#elif defined(__clang__) || defined(__GNUC__)
|
||||
#define ALIGN(alignment) __attribute__((aligned(alignment)))
|
||||
#else
|
||||
#error "Unknown compiler"
|
||||
#endif
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* jccolor-neon.c - colorspace conversion (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2020, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
#include "neon-compat.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
|
||||
/* RGB -> YCbCr conversion constants */
|
||||
|
||||
#define F_0_298 19595
|
||||
#define F_0_587 38470
|
||||
#define F_0_113 7471
|
||||
#define F_0_168 11059
|
||||
#define F_0_331 21709
|
||||
#define F_0_500 32768
|
||||
#define F_0_418 27439
|
||||
#define F_0_081 5329
|
||||
|
||||
ALIGN(16) static const uint16_t jsimd_rgb_ycc_neon_consts[] = {
|
||||
F_0_298, F_0_587, F_0_113, F_0_168,
|
||||
F_0_331, F_0_500, F_0_418, F_0_081
|
||||
};
|
||||
|
||||
|
||||
/* Include inline routines for colorspace extensions. */
|
||||
|
||||
#if defined(__aarch64__) || defined(_M_ARM64)
|
||||
#include "aarch64/jccolext-neon.c"
|
||||
#else
|
||||
#include "aarch32/jccolext-neon.c"
|
||||
#endif
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
|
||||
#define RGB_RED EXT_RGB_RED
|
||||
#define RGB_GREEN EXT_RGB_GREEN
|
||||
#define RGB_BLUE EXT_RGB_BLUE
|
||||
#define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
|
||||
#define jsimd_rgb_ycc_convert_neon jsimd_extrgb_ycc_convert_neon
|
||||
#if defined(__aarch64__) || defined(_M_ARM64)
|
||||
#include "aarch64/jccolext-neon.c"
|
||||
#else
|
||||
#include "aarch32/jccolext-neon.c"
|
||||
#endif
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_rgb_ycc_convert_neon
|
||||
|
||||
#define RGB_RED EXT_RGBX_RED
|
||||
#define RGB_GREEN EXT_RGBX_GREEN
|
||||
#define RGB_BLUE EXT_RGBX_BLUE
|
||||
#define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
|
||||
#define jsimd_rgb_ycc_convert_neon jsimd_extrgbx_ycc_convert_neon
|
||||
#if defined(__aarch64__) || defined(_M_ARM64)
|
||||
#include "aarch64/jccolext-neon.c"
|
||||
#else
|
||||
#include "aarch32/jccolext-neon.c"
|
||||
#endif
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_rgb_ycc_convert_neon
|
||||
|
||||
#define RGB_RED EXT_BGR_RED
|
||||
#define RGB_GREEN EXT_BGR_GREEN
|
||||
#define RGB_BLUE EXT_BGR_BLUE
|
||||
#define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
|
||||
#define jsimd_rgb_ycc_convert_neon jsimd_extbgr_ycc_convert_neon
|
||||
#if defined(__aarch64__) || defined(_M_ARM64)
|
||||
#include "aarch64/jccolext-neon.c"
|
||||
#else
|
||||
#include "aarch32/jccolext-neon.c"
|
||||
#endif
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_rgb_ycc_convert_neon
|
||||
|
||||
#define RGB_RED EXT_BGRX_RED
|
||||
#define RGB_GREEN EXT_BGRX_GREEN
|
||||
#define RGB_BLUE EXT_BGRX_BLUE
|
||||
#define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
|
||||
#define jsimd_rgb_ycc_convert_neon jsimd_extbgrx_ycc_convert_neon
|
||||
#if defined(__aarch64__) || defined(_M_ARM64)
|
||||
#include "aarch64/jccolext-neon.c"
|
||||
#else
|
||||
#include "aarch32/jccolext-neon.c"
|
||||
#endif
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_rgb_ycc_convert_neon
|
||||
|
||||
#define RGB_RED EXT_XBGR_RED
|
||||
#define RGB_GREEN EXT_XBGR_GREEN
|
||||
#define RGB_BLUE EXT_XBGR_BLUE
|
||||
#define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
|
||||
#define jsimd_rgb_ycc_convert_neon jsimd_extxbgr_ycc_convert_neon
|
||||
#if defined(__aarch64__) || defined(_M_ARM64)
|
||||
#include "aarch64/jccolext-neon.c"
|
||||
#else
|
||||
#include "aarch32/jccolext-neon.c"
|
||||
#endif
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_rgb_ycc_convert_neon
|
||||
|
||||
#define RGB_RED EXT_XRGB_RED
|
||||
#define RGB_GREEN EXT_XRGB_GREEN
|
||||
#define RGB_BLUE EXT_XRGB_BLUE
|
||||
#define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
|
||||
#define jsimd_rgb_ycc_convert_neon jsimd_extxrgb_ycc_convert_neon
|
||||
#if defined(__aarch64__) || defined(_M_ARM64)
|
||||
#include "aarch64/jccolext-neon.c"
|
||||
#else
|
||||
#include "aarch32/jccolext-neon.c"
|
||||
#endif
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_rgb_ycc_convert_neon
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* jcgray-neon.c - grayscale colorspace conversion (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
|
||||
/* RGB -> Grayscale conversion constants */
|
||||
|
||||
#define F_0_298 19595
|
||||
#define F_0_587 38470
|
||||
#define F_0_113 7471
|
||||
|
||||
|
||||
/* Include inline routines for colorspace extensions. */
|
||||
|
||||
#include "jcgryext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
|
||||
#define RGB_RED EXT_RGB_RED
|
||||
#define RGB_GREEN EXT_RGB_GREEN
|
||||
#define RGB_BLUE EXT_RGB_BLUE
|
||||
#define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
|
||||
#define jsimd_rgb_gray_convert_neon jsimd_extrgb_gray_convert_neon
|
||||
#include "jcgryext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_rgb_gray_convert_neon
|
||||
|
||||
#define RGB_RED EXT_RGBX_RED
|
||||
#define RGB_GREEN EXT_RGBX_GREEN
|
||||
#define RGB_BLUE EXT_RGBX_BLUE
|
||||
#define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
|
||||
#define jsimd_rgb_gray_convert_neon jsimd_extrgbx_gray_convert_neon
|
||||
#include "jcgryext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_rgb_gray_convert_neon
|
||||
|
||||
#define RGB_RED EXT_BGR_RED
|
||||
#define RGB_GREEN EXT_BGR_GREEN
|
||||
#define RGB_BLUE EXT_BGR_BLUE
|
||||
#define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
|
||||
#define jsimd_rgb_gray_convert_neon jsimd_extbgr_gray_convert_neon
|
||||
#include "jcgryext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_rgb_gray_convert_neon
|
||||
|
||||
#define RGB_RED EXT_BGRX_RED
|
||||
#define RGB_GREEN EXT_BGRX_GREEN
|
||||
#define RGB_BLUE EXT_BGRX_BLUE
|
||||
#define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
|
||||
#define jsimd_rgb_gray_convert_neon jsimd_extbgrx_gray_convert_neon
|
||||
#include "jcgryext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_rgb_gray_convert_neon
|
||||
|
||||
#define RGB_RED EXT_XBGR_RED
|
||||
#define RGB_GREEN EXT_XBGR_GREEN
|
||||
#define RGB_BLUE EXT_XBGR_BLUE
|
||||
#define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
|
||||
#define jsimd_rgb_gray_convert_neon jsimd_extxbgr_gray_convert_neon
|
||||
#include "jcgryext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_rgb_gray_convert_neon
|
||||
|
||||
#define RGB_RED EXT_XRGB_RED
|
||||
#define RGB_GREEN EXT_XRGB_GREEN
|
||||
#define RGB_BLUE EXT_XRGB_BLUE
|
||||
#define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
|
||||
#define jsimd_rgb_gray_convert_neon jsimd_extxrgb_gray_convert_neon
|
||||
#include "jcgryext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_rgb_gray_convert_neon
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* jcgryext-neon.c - grayscale colorspace conversion (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/* This file is included by jcgray-neon.c */
|
||||
|
||||
|
||||
/* RGB -> Grayscale conversion is defined by the following equation:
|
||||
* Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
|
||||
*
|
||||
* Avoid floating point arithmetic by using shifted integer constants:
|
||||
* 0.29899597 = 19595 * 2^-16
|
||||
* 0.58700561 = 38470 * 2^-16
|
||||
* 0.11399841 = 7471 * 2^-16
|
||||
* These constants are defined in jcgray-neon.c
|
||||
*
|
||||
* This is the same computation as the RGB -> Y portion of RGB -> YCbCr.
|
||||
*/
|
||||
|
||||
void jsimd_rgb_gray_convert_neon(JDIMENSION image_width, JSAMPARRAY input_buf,
|
||||
JSAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
int num_rows)
|
||||
{
|
||||
JSAMPROW inptr;
|
||||
JSAMPROW outptr;
|
||||
/* Allocate temporary buffer for final (image_width % 16) pixels in row. */
|
||||
ALIGN(16) uint8_t tmp_buf[16 * RGB_PIXELSIZE];
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr = *input_buf++;
|
||||
outptr = output_buf[0][output_row];
|
||||
output_row++;
|
||||
|
||||
int cols_remaining = image_width;
|
||||
for (; cols_remaining > 0; cols_remaining -= 16) {
|
||||
|
||||
/* To prevent buffer overread by the vector load instructions, the last
|
||||
* (image_width % 16) columns of data are first memcopied to a temporary
|
||||
* buffer large enough to accommodate the vector load.
|
||||
*/
|
||||
if (cols_remaining < 16) {
|
||||
memcpy(tmp_buf, inptr, cols_remaining * RGB_PIXELSIZE);
|
||||
inptr = tmp_buf;
|
||||
}
|
||||
|
||||
#if RGB_PIXELSIZE == 4
|
||||
uint8x16x4_t input_pixels = vld4q_u8(inptr);
|
||||
#else
|
||||
uint8x16x3_t input_pixels = vld3q_u8(inptr);
|
||||
#endif
|
||||
uint16x8_t r_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_RED]));
|
||||
uint16x8_t r_h = vmovl_u8(vget_high_u8(input_pixels.val[RGB_RED]));
|
||||
uint16x8_t g_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_GREEN]));
|
||||
uint16x8_t g_h = vmovl_u8(vget_high_u8(input_pixels.val[RGB_GREEN]));
|
||||
uint16x8_t b_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_BLUE]));
|
||||
uint16x8_t b_h = vmovl_u8(vget_high_u8(input_pixels.val[RGB_BLUE]));
|
||||
|
||||
/* Compute Y = 0.29900 * R + 0.58700 * G + 0.11400 * B */
|
||||
uint32x4_t y_ll = vmull_n_u16(vget_low_u16(r_l), F_0_298);
|
||||
uint32x4_t y_lh = vmull_n_u16(vget_high_u16(r_l), F_0_298);
|
||||
uint32x4_t y_hl = vmull_n_u16(vget_low_u16(r_h), F_0_298);
|
||||
uint32x4_t y_hh = vmull_n_u16(vget_high_u16(r_h), F_0_298);
|
||||
y_ll = vmlal_n_u16(y_ll, vget_low_u16(g_l), F_0_587);
|
||||
y_lh = vmlal_n_u16(y_lh, vget_high_u16(g_l), F_0_587);
|
||||
y_hl = vmlal_n_u16(y_hl, vget_low_u16(g_h), F_0_587);
|
||||
y_hh = vmlal_n_u16(y_hh, vget_high_u16(g_h), F_0_587);
|
||||
y_ll = vmlal_n_u16(y_ll, vget_low_u16(b_l), F_0_113);
|
||||
y_lh = vmlal_n_u16(y_lh, vget_high_u16(b_l), F_0_113);
|
||||
y_hl = vmlal_n_u16(y_hl, vget_low_u16(b_h), F_0_113);
|
||||
y_hh = vmlal_n_u16(y_hh, vget_high_u16(b_h), F_0_113);
|
||||
|
||||
/* Descale Y values (rounding right shift) and narrow to 16-bit. */
|
||||
uint16x8_t y_l = vcombine_u16(vrshrn_n_u32(y_ll, 16),
|
||||
vrshrn_n_u32(y_lh, 16));
|
||||
uint16x8_t y_h = vcombine_u16(vrshrn_n_u32(y_hl, 16),
|
||||
vrshrn_n_u32(y_hh, 16));
|
||||
|
||||
/* Narrow Y values to 8-bit and store to memory. Buffer overwrite is
|
||||
* permitted up to the next multiple of ALIGN_SIZE bytes.
|
||||
*/
|
||||
vst1q_u8(outptr, vcombine_u8(vmovn_u16(y_l), vmovn_u16(y_h)));
|
||||
|
||||
/* Increment pointers. */
|
||||
inptr += (16 * RGB_PIXELSIZE);
|
||||
outptr += 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* jchuff.h
|
||||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009, 2018, 2021, D. R. Commander.
|
||||
* Copyright (C) 2018, Matthias Räncker.
|
||||
* Copyright (C) 2020-2021, Arm Limited.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*/
|
||||
|
||||
/* Expanded entropy encoder object for Huffman encoding.
|
||||
*
|
||||
* The savable_state subrecord contains fields that change within an MCU,
|
||||
* but must not be updated permanently until we complete the MCU.
|
||||
*/
|
||||
|
||||
#if defined(__aarch64__) || defined(_M_ARM64)
|
||||
#define BIT_BUF_SIZE 64
|
||||
#else
|
||||
#define BIT_BUF_SIZE 32
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
size_t put_buffer; /* current bit accumulation buffer */
|
||||
int free_bits; /* # of bits available in it */
|
||||
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
|
||||
} savable_state;
|
||||
|
||||
typedef struct {
|
||||
JOCTET *next_output_byte; /* => next byte to write in buffer */
|
||||
size_t free_in_buffer; /* # of byte spaces remaining in buffer */
|
||||
savable_state cur; /* Current bit buffer & DC state */
|
||||
j_compress_ptr cinfo; /* dump_buffer needs access to this */
|
||||
int simd;
|
||||
} working_state;
|
||||
|
||||
/* Outputting bits to the file */
|
||||
|
||||
/* Output byte b and, speculatively, an additional 0 byte. 0xFF must be encoded
|
||||
* as 0xFF 0x00, so the output buffer pointer is advanced by 2 if the byte is
|
||||
* 0xFF. Otherwise, the output buffer pointer is advanced by 1, and the
|
||||
* speculative 0 byte will be overwritten by the next byte.
|
||||
*/
|
||||
#define EMIT_BYTE(b) { \
|
||||
buffer[0] = (JOCTET)(b); \
|
||||
buffer[1] = 0; \
|
||||
buffer -= -2 + ((JOCTET)(b) < 0xFF); \
|
||||
}
|
||||
|
||||
/* Output the entire bit buffer. If there are no 0xFF bytes in it, then write
|
||||
* directly to the output buffer. Otherwise, use the EMIT_BYTE() macro to
|
||||
* encode 0xFF as 0xFF 0x00.
|
||||
*/
|
||||
#if defined(__aarch64__) || defined(_M_ARM64)
|
||||
|
||||
#define FLUSH() { \
|
||||
if (put_buffer & 0x8080808080808080 & ~(put_buffer + 0x0101010101010101)) { \
|
||||
EMIT_BYTE(put_buffer >> 56) \
|
||||
EMIT_BYTE(put_buffer >> 48) \
|
||||
EMIT_BYTE(put_buffer >> 40) \
|
||||
EMIT_BYTE(put_buffer >> 32) \
|
||||
EMIT_BYTE(put_buffer >> 24) \
|
||||
EMIT_BYTE(put_buffer >> 16) \
|
||||
EMIT_BYTE(put_buffer >> 8) \
|
||||
EMIT_BYTE(put_buffer ) \
|
||||
} else { \
|
||||
*((uint64_t *)buffer) = BUILTIN_BSWAP64(put_buffer); \
|
||||
buffer += 8; \
|
||||
} \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define SPLAT() { \
|
||||
buffer[0] = (JOCTET)(put_buffer >> 24); \
|
||||
buffer[1] = (JOCTET)(put_buffer >> 16); \
|
||||
buffer[2] = (JOCTET)(put_buffer >> 8); \
|
||||
buffer[3] = (JOCTET)(put_buffer ); \
|
||||
buffer += 4; \
|
||||
}
|
||||
#else
|
||||
#define SPLAT() { \
|
||||
put_buffer = __builtin_bswap32(put_buffer); \
|
||||
__asm__("str %1, [%0], #4" : "+r" (buffer) : "r" (put_buffer)); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define FLUSH() { \
|
||||
if (put_buffer & 0x80808080 & ~(put_buffer + 0x01010101)) { \
|
||||
EMIT_BYTE(put_buffer >> 24) \
|
||||
EMIT_BYTE(put_buffer >> 16) \
|
||||
EMIT_BYTE(put_buffer >> 8) \
|
||||
EMIT_BYTE(put_buffer ) \
|
||||
} else { \
|
||||
SPLAT(); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Fill the bit buffer to capacity with the leading bits from code, then output
|
||||
* the bit buffer and put the remaining bits from code into the bit buffer.
|
||||
*/
|
||||
#define PUT_AND_FLUSH(code, size) { \
|
||||
put_buffer = (put_buffer << (size + free_bits)) | (code >> -free_bits); \
|
||||
FLUSH() \
|
||||
free_bits += BIT_BUF_SIZE; \
|
||||
put_buffer = code; \
|
||||
}
|
||||
|
||||
/* Insert code into the bit buffer and output the bit buffer if needed.
|
||||
* NOTE: We can't flush with free_bits == 0, since the left shift in
|
||||
* PUT_AND_FLUSH() would have undefined behavior.
|
||||
*/
|
||||
#define PUT_BITS(code, size) { \
|
||||
free_bits -= size; \
|
||||
if (free_bits < 0) \
|
||||
PUT_AND_FLUSH(code, size) \
|
||||
else \
|
||||
put_buffer = (put_buffer << size) | code; \
|
||||
}
|
||||
|
||||
#define PUT_CODE(code, size, diff) { \
|
||||
diff |= code << nbits; \
|
||||
nbits += size; \
|
||||
PUT_BITS(diff, nbits) \
|
||||
}
|
||||
+622
@@ -0,0 +1,622 @@
|
||||
/*
|
||||
* jcphuff-neon.c - prepare data for progressive Huffman encoding (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020-2021, Arm Limited. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jconfigint.h"
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "neon-compat.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
|
||||
/* Data preparation for encode_mcu_AC_first().
|
||||
*
|
||||
* The equivalent scalar C function (encode_mcu_AC_first_prepare()) can be
|
||||
* found in jcphuff.c.
|
||||
*/
|
||||
|
||||
void jsimd_encode_mcu_AC_first_prepare_neon
|
||||
(const JCOEF *block, const int *jpeg_natural_order_start, int Sl, int Al,
|
||||
JCOEF *values, size_t *zerobits)
|
||||
{
|
||||
JCOEF *values_ptr = values;
|
||||
JCOEF *diff_values_ptr = values + DCTSIZE2;
|
||||
|
||||
/* Rows of coefficients to zero (since they haven't been processed) */
|
||||
int i, rows_to_zero = 8;
|
||||
|
||||
for (i = 0; i < Sl / 16; i++) {
|
||||
int16x8_t coefs1 = vld1q_dup_s16(block + jpeg_natural_order_start[0]);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[1], coefs1, 1);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[2], coefs1, 2);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[3], coefs1, 3);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[4], coefs1, 4);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[5], coefs1, 5);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[6], coefs1, 6);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[7], coefs1, 7);
|
||||
int16x8_t coefs2 = vld1q_dup_s16(block + jpeg_natural_order_start[8]);
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[9], coefs2, 1);
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[10], coefs2, 2);
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[11], coefs2, 3);
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[12], coefs2, 4);
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[13], coefs2, 5);
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[14], coefs2, 6);
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[15], coefs2, 7);
|
||||
|
||||
/* Isolate sign of coefficients. */
|
||||
int16x8_t sign_coefs1 = vshrq_n_s16(coefs1, 15);
|
||||
int16x8_t sign_coefs2 = vshrq_n_s16(coefs2, 15);
|
||||
/* Compute absolute value of coefficients and apply point transform Al. */
|
||||
int16x8_t abs_coefs1 = vabsq_s16(coefs1);
|
||||
int16x8_t abs_coefs2 = vabsq_s16(coefs2);
|
||||
coefs1 = vshlq_s16(abs_coefs1, vdupq_n_s16(-Al));
|
||||
coefs2 = vshlq_s16(abs_coefs2, vdupq_n_s16(-Al));
|
||||
|
||||
/* Compute diff values. */
|
||||
int16x8_t diff1 = veorq_s16(coefs1, sign_coefs1);
|
||||
int16x8_t diff2 = veorq_s16(coefs2, sign_coefs2);
|
||||
|
||||
/* Store transformed coefficients and diff values. */
|
||||
vst1q_s16(values_ptr, coefs1);
|
||||
vst1q_s16(values_ptr + DCTSIZE, coefs2);
|
||||
vst1q_s16(diff_values_ptr, diff1);
|
||||
vst1q_s16(diff_values_ptr + DCTSIZE, diff2);
|
||||
values_ptr += 16;
|
||||
diff_values_ptr += 16;
|
||||
jpeg_natural_order_start += 16;
|
||||
rows_to_zero -= 2;
|
||||
}
|
||||
|
||||
/* Same operation but for remaining partial vector */
|
||||
int remaining_coefs = Sl % 16;
|
||||
if (remaining_coefs > 8) {
|
||||
int16x8_t coefs1 = vld1q_dup_s16(block + jpeg_natural_order_start[0]);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[1], coefs1, 1);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[2], coefs1, 2);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[3], coefs1, 3);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[4], coefs1, 4);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[5], coefs1, 5);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[6], coefs1, 6);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[7], coefs1, 7);
|
||||
int16x8_t coefs2 = vdupq_n_s16(0);
|
||||
switch (remaining_coefs) {
|
||||
case 15:
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[14], coefs2, 6);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 14:
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[13], coefs2, 5);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 13:
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[12], coefs2, 4);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 12:
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[11], coefs2, 3);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 11:
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[10], coefs2, 2);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 10:
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[9], coefs2, 1);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 9:
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[8], coefs2, 0);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Isolate sign of coefficients. */
|
||||
int16x8_t sign_coefs1 = vshrq_n_s16(coefs1, 15);
|
||||
int16x8_t sign_coefs2 = vshrq_n_s16(coefs2, 15);
|
||||
/* Compute absolute value of coefficients and apply point transform Al. */
|
||||
int16x8_t abs_coefs1 = vabsq_s16(coefs1);
|
||||
int16x8_t abs_coefs2 = vabsq_s16(coefs2);
|
||||
coefs1 = vshlq_s16(abs_coefs1, vdupq_n_s16(-Al));
|
||||
coefs2 = vshlq_s16(abs_coefs2, vdupq_n_s16(-Al));
|
||||
|
||||
/* Compute diff values. */
|
||||
int16x8_t diff1 = veorq_s16(coefs1, sign_coefs1);
|
||||
int16x8_t diff2 = veorq_s16(coefs2, sign_coefs2);
|
||||
|
||||
/* Store transformed coefficients and diff values. */
|
||||
vst1q_s16(values_ptr, coefs1);
|
||||
vst1q_s16(values_ptr + DCTSIZE, coefs2);
|
||||
vst1q_s16(diff_values_ptr, diff1);
|
||||
vst1q_s16(diff_values_ptr + DCTSIZE, diff2);
|
||||
values_ptr += 16;
|
||||
diff_values_ptr += 16;
|
||||
rows_to_zero -= 2;
|
||||
|
||||
} else if (remaining_coefs > 0) {
|
||||
int16x8_t coefs = vdupq_n_s16(0);
|
||||
|
||||
switch (remaining_coefs) {
|
||||
case 8:
|
||||
coefs = vld1q_lane_s16(block + jpeg_natural_order_start[7], coefs, 7);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 7:
|
||||
coefs = vld1q_lane_s16(block + jpeg_natural_order_start[6], coefs, 6);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 6:
|
||||
coefs = vld1q_lane_s16(block + jpeg_natural_order_start[5], coefs, 5);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 5:
|
||||
coefs = vld1q_lane_s16(block + jpeg_natural_order_start[4], coefs, 4);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 4:
|
||||
coefs = vld1q_lane_s16(block + jpeg_natural_order_start[3], coefs, 3);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 3:
|
||||
coefs = vld1q_lane_s16(block + jpeg_natural_order_start[2], coefs, 2);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 2:
|
||||
coefs = vld1q_lane_s16(block + jpeg_natural_order_start[1], coefs, 1);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 1:
|
||||
coefs = vld1q_lane_s16(block + jpeg_natural_order_start[0], coefs, 0);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Isolate sign of coefficients. */
|
||||
int16x8_t sign_coefs = vshrq_n_s16(coefs, 15);
|
||||
/* Compute absolute value of coefficients and apply point transform Al. */
|
||||
int16x8_t abs_coefs = vabsq_s16(coefs);
|
||||
coefs = vshlq_s16(abs_coefs, vdupq_n_s16(-Al));
|
||||
|
||||
/* Compute diff values. */
|
||||
int16x8_t diff = veorq_s16(coefs, sign_coefs);
|
||||
|
||||
/* Store transformed coefficients and diff values. */
|
||||
vst1q_s16(values_ptr, coefs);
|
||||
vst1q_s16(diff_values_ptr, diff);
|
||||
values_ptr += 8;
|
||||
diff_values_ptr += 8;
|
||||
rows_to_zero--;
|
||||
}
|
||||
|
||||
/* Zero remaining memory in the values and diff_values blocks. */
|
||||
for (i = 0; i < rows_to_zero; i++) {
|
||||
vst1q_s16(values_ptr, vdupq_n_s16(0));
|
||||
vst1q_s16(diff_values_ptr, vdupq_n_s16(0));
|
||||
values_ptr += 8;
|
||||
diff_values_ptr += 8;
|
||||
}
|
||||
|
||||
/* Construct zerobits bitmap. A set bit means that the corresponding
|
||||
* coefficient != 0.
|
||||
*/
|
||||
int16x8_t row0 = vld1q_s16(values + 0 * DCTSIZE);
|
||||
int16x8_t row1 = vld1q_s16(values + 1 * DCTSIZE);
|
||||
int16x8_t row2 = vld1q_s16(values + 2 * DCTSIZE);
|
||||
int16x8_t row3 = vld1q_s16(values + 3 * DCTSIZE);
|
||||
int16x8_t row4 = vld1q_s16(values + 4 * DCTSIZE);
|
||||
int16x8_t row5 = vld1q_s16(values + 5 * DCTSIZE);
|
||||
int16x8_t row6 = vld1q_s16(values + 6 * DCTSIZE);
|
||||
int16x8_t row7 = vld1q_s16(values + 7 * DCTSIZE);
|
||||
|
||||
uint8x8_t row0_eq0 = vmovn_u16(vceqq_s16(row0, vdupq_n_s16(0)));
|
||||
uint8x8_t row1_eq0 = vmovn_u16(vceqq_s16(row1, vdupq_n_s16(0)));
|
||||
uint8x8_t row2_eq0 = vmovn_u16(vceqq_s16(row2, vdupq_n_s16(0)));
|
||||
uint8x8_t row3_eq0 = vmovn_u16(vceqq_s16(row3, vdupq_n_s16(0)));
|
||||
uint8x8_t row4_eq0 = vmovn_u16(vceqq_s16(row4, vdupq_n_s16(0)));
|
||||
uint8x8_t row5_eq0 = vmovn_u16(vceqq_s16(row5, vdupq_n_s16(0)));
|
||||
uint8x8_t row6_eq0 = vmovn_u16(vceqq_s16(row6, vdupq_n_s16(0)));
|
||||
uint8x8_t row7_eq0 = vmovn_u16(vceqq_s16(row7, vdupq_n_s16(0)));
|
||||
|
||||
/* { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 } */
|
||||
const uint8x8_t bitmap_mask =
|
||||
vreinterpret_u8_u64(vmov_n_u64(0x8040201008040201));
|
||||
|
||||
row0_eq0 = vand_u8(row0_eq0, bitmap_mask);
|
||||
row1_eq0 = vand_u8(row1_eq0, bitmap_mask);
|
||||
row2_eq0 = vand_u8(row2_eq0, bitmap_mask);
|
||||
row3_eq0 = vand_u8(row3_eq0, bitmap_mask);
|
||||
row4_eq0 = vand_u8(row4_eq0, bitmap_mask);
|
||||
row5_eq0 = vand_u8(row5_eq0, bitmap_mask);
|
||||
row6_eq0 = vand_u8(row6_eq0, bitmap_mask);
|
||||
row7_eq0 = vand_u8(row7_eq0, bitmap_mask);
|
||||
|
||||
uint8x8_t bitmap_rows_01 = vpadd_u8(row0_eq0, row1_eq0);
|
||||
uint8x8_t bitmap_rows_23 = vpadd_u8(row2_eq0, row3_eq0);
|
||||
uint8x8_t bitmap_rows_45 = vpadd_u8(row4_eq0, row5_eq0);
|
||||
uint8x8_t bitmap_rows_67 = vpadd_u8(row6_eq0, row7_eq0);
|
||||
uint8x8_t bitmap_rows_0123 = vpadd_u8(bitmap_rows_01, bitmap_rows_23);
|
||||
uint8x8_t bitmap_rows_4567 = vpadd_u8(bitmap_rows_45, bitmap_rows_67);
|
||||
uint8x8_t bitmap_all = vpadd_u8(bitmap_rows_0123, bitmap_rows_4567);
|
||||
|
||||
#if defined(__aarch64__) || defined(_M_ARM64)
|
||||
/* Move bitmap to a 64-bit scalar register. */
|
||||
uint64_t bitmap = vget_lane_u64(vreinterpret_u64_u8(bitmap_all), 0);
|
||||
/* Store zerobits bitmap. */
|
||||
*zerobits = ~bitmap;
|
||||
#else
|
||||
/* Move bitmap to two 32-bit scalar registers. */
|
||||
uint32_t bitmap0 = vget_lane_u32(vreinterpret_u32_u8(bitmap_all), 0);
|
||||
uint32_t bitmap1 = vget_lane_u32(vreinterpret_u32_u8(bitmap_all), 1);
|
||||
/* Store zerobits bitmap. */
|
||||
zerobits[0] = ~bitmap0;
|
||||
zerobits[1] = ~bitmap1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Data preparation for encode_mcu_AC_refine().
|
||||
*
|
||||
* The equivalent scalar C function (encode_mcu_AC_refine_prepare()) can be
|
||||
* found in jcphuff.c.
|
||||
*/
|
||||
|
||||
int jsimd_encode_mcu_AC_refine_prepare_neon
|
||||
(const JCOEF *block, const int *jpeg_natural_order_start, int Sl, int Al,
|
||||
JCOEF *absvalues, size_t *bits)
|
||||
{
|
||||
/* Temporary storage buffers for data used to compute the signbits bitmap and
|
||||
* the end-of-block (EOB) position
|
||||
*/
|
||||
uint8_t coef_sign_bits[64];
|
||||
uint8_t coef_eq1_bits[64];
|
||||
|
||||
JCOEF *absvalues_ptr = absvalues;
|
||||
uint8_t *coef_sign_bits_ptr = coef_sign_bits;
|
||||
uint8_t *eq1_bits_ptr = coef_eq1_bits;
|
||||
|
||||
/* Rows of coefficients to zero (since they haven't been processed) */
|
||||
int i, rows_to_zero = 8;
|
||||
|
||||
for (i = 0; i < Sl / 16; i++) {
|
||||
int16x8_t coefs1 = vld1q_dup_s16(block + jpeg_natural_order_start[0]);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[1], coefs1, 1);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[2], coefs1, 2);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[3], coefs1, 3);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[4], coefs1, 4);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[5], coefs1, 5);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[6], coefs1, 6);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[7], coefs1, 7);
|
||||
int16x8_t coefs2 = vld1q_dup_s16(block + jpeg_natural_order_start[8]);
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[9], coefs2, 1);
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[10], coefs2, 2);
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[11], coefs2, 3);
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[12], coefs2, 4);
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[13], coefs2, 5);
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[14], coefs2, 6);
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[15], coefs2, 7);
|
||||
|
||||
/* Compute and store data for signbits bitmap. */
|
||||
uint8x8_t sign_coefs1 =
|
||||
vmovn_u16(vreinterpretq_u16_s16(vshrq_n_s16(coefs1, 15)));
|
||||
uint8x8_t sign_coefs2 =
|
||||
vmovn_u16(vreinterpretq_u16_s16(vshrq_n_s16(coefs2, 15)));
|
||||
vst1_u8(coef_sign_bits_ptr, sign_coefs1);
|
||||
vst1_u8(coef_sign_bits_ptr + DCTSIZE, sign_coefs2);
|
||||
|
||||
/* Compute absolute value of coefficients and apply point transform Al. */
|
||||
int16x8_t abs_coefs1 = vabsq_s16(coefs1);
|
||||
int16x8_t abs_coefs2 = vabsq_s16(coefs2);
|
||||
coefs1 = vshlq_s16(abs_coefs1, vdupq_n_s16(-Al));
|
||||
coefs2 = vshlq_s16(abs_coefs2, vdupq_n_s16(-Al));
|
||||
vst1q_s16(absvalues_ptr, coefs1);
|
||||
vst1q_s16(absvalues_ptr + DCTSIZE, coefs2);
|
||||
|
||||
/* Test whether transformed coefficient values == 1 (used to find EOB
|
||||
* position.)
|
||||
*/
|
||||
uint8x8_t coefs_eq11 = vmovn_u16(vceqq_s16(coefs1, vdupq_n_s16(1)));
|
||||
uint8x8_t coefs_eq12 = vmovn_u16(vceqq_s16(coefs2, vdupq_n_s16(1)));
|
||||
vst1_u8(eq1_bits_ptr, coefs_eq11);
|
||||
vst1_u8(eq1_bits_ptr + DCTSIZE, coefs_eq12);
|
||||
|
||||
absvalues_ptr += 16;
|
||||
coef_sign_bits_ptr += 16;
|
||||
eq1_bits_ptr += 16;
|
||||
jpeg_natural_order_start += 16;
|
||||
rows_to_zero -= 2;
|
||||
}
|
||||
|
||||
/* Same operation but for remaining partial vector */
|
||||
int remaining_coefs = Sl % 16;
|
||||
if (remaining_coefs > 8) {
|
||||
int16x8_t coefs1 = vld1q_dup_s16(block + jpeg_natural_order_start[0]);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[1], coefs1, 1);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[2], coefs1, 2);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[3], coefs1, 3);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[4], coefs1, 4);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[5], coefs1, 5);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[6], coefs1, 6);
|
||||
coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[7], coefs1, 7);
|
||||
int16x8_t coefs2 = vdupq_n_s16(0);
|
||||
switch (remaining_coefs) {
|
||||
case 15:
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[14], coefs2, 6);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 14:
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[13], coefs2, 5);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 13:
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[12], coefs2, 4);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 12:
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[11], coefs2, 3);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 11:
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[10], coefs2, 2);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 10:
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[9], coefs2, 1);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 9:
|
||||
coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[8], coefs2, 0);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Compute and store data for signbits bitmap. */
|
||||
uint8x8_t sign_coefs1 =
|
||||
vmovn_u16(vreinterpretq_u16_s16(vshrq_n_s16(coefs1, 15)));
|
||||
uint8x8_t sign_coefs2 =
|
||||
vmovn_u16(vreinterpretq_u16_s16(vshrq_n_s16(coefs2, 15)));
|
||||
vst1_u8(coef_sign_bits_ptr, sign_coefs1);
|
||||
vst1_u8(coef_sign_bits_ptr + DCTSIZE, sign_coefs2);
|
||||
|
||||
/* Compute absolute value of coefficients and apply point transform Al. */
|
||||
int16x8_t abs_coefs1 = vabsq_s16(coefs1);
|
||||
int16x8_t abs_coefs2 = vabsq_s16(coefs2);
|
||||
coefs1 = vshlq_s16(abs_coefs1, vdupq_n_s16(-Al));
|
||||
coefs2 = vshlq_s16(abs_coefs2, vdupq_n_s16(-Al));
|
||||
vst1q_s16(absvalues_ptr, coefs1);
|
||||
vst1q_s16(absvalues_ptr + DCTSIZE, coefs2);
|
||||
|
||||
/* Test whether transformed coefficient values == 1 (used to find EOB
|
||||
* position.)
|
||||
*/
|
||||
uint8x8_t coefs_eq11 = vmovn_u16(vceqq_s16(coefs1, vdupq_n_s16(1)));
|
||||
uint8x8_t coefs_eq12 = vmovn_u16(vceqq_s16(coefs2, vdupq_n_s16(1)));
|
||||
vst1_u8(eq1_bits_ptr, coefs_eq11);
|
||||
vst1_u8(eq1_bits_ptr + DCTSIZE, coefs_eq12);
|
||||
|
||||
absvalues_ptr += 16;
|
||||
coef_sign_bits_ptr += 16;
|
||||
eq1_bits_ptr += 16;
|
||||
jpeg_natural_order_start += 16;
|
||||
rows_to_zero -= 2;
|
||||
|
||||
} else if (remaining_coefs > 0) {
|
||||
int16x8_t coefs = vdupq_n_s16(0);
|
||||
|
||||
switch (remaining_coefs) {
|
||||
case 8:
|
||||
coefs = vld1q_lane_s16(block + jpeg_natural_order_start[7], coefs, 7);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 7:
|
||||
coefs = vld1q_lane_s16(block + jpeg_natural_order_start[6], coefs, 6);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 6:
|
||||
coefs = vld1q_lane_s16(block + jpeg_natural_order_start[5], coefs, 5);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 5:
|
||||
coefs = vld1q_lane_s16(block + jpeg_natural_order_start[4], coefs, 4);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 4:
|
||||
coefs = vld1q_lane_s16(block + jpeg_natural_order_start[3], coefs, 3);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 3:
|
||||
coefs = vld1q_lane_s16(block + jpeg_natural_order_start[2], coefs, 2);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 2:
|
||||
coefs = vld1q_lane_s16(block + jpeg_natural_order_start[1], coefs, 1);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 1:
|
||||
coefs = vld1q_lane_s16(block + jpeg_natural_order_start[0], coefs, 0);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Compute and store data for signbits bitmap. */
|
||||
uint8x8_t sign_coefs =
|
||||
vmovn_u16(vreinterpretq_u16_s16(vshrq_n_s16(coefs, 15)));
|
||||
vst1_u8(coef_sign_bits_ptr, sign_coefs);
|
||||
|
||||
/* Compute absolute value of coefficients and apply point transform Al. */
|
||||
int16x8_t abs_coefs = vabsq_s16(coefs);
|
||||
coefs = vshlq_s16(abs_coefs, vdupq_n_s16(-Al));
|
||||
vst1q_s16(absvalues_ptr, coefs);
|
||||
|
||||
/* Test whether transformed coefficient values == 1 (used to find EOB
|
||||
* position.)
|
||||
*/
|
||||
uint8x8_t coefs_eq1 = vmovn_u16(vceqq_s16(coefs, vdupq_n_s16(1)));
|
||||
vst1_u8(eq1_bits_ptr, coefs_eq1);
|
||||
|
||||
absvalues_ptr += 8;
|
||||
coef_sign_bits_ptr += 8;
|
||||
eq1_bits_ptr += 8;
|
||||
rows_to_zero--;
|
||||
}
|
||||
|
||||
/* Zero remaining memory in blocks. */
|
||||
for (i = 0; i < rows_to_zero; i++) {
|
||||
vst1q_s16(absvalues_ptr, vdupq_n_s16(0));
|
||||
vst1_u8(coef_sign_bits_ptr, vdup_n_u8(0));
|
||||
vst1_u8(eq1_bits_ptr, vdup_n_u8(0));
|
||||
absvalues_ptr += 8;
|
||||
coef_sign_bits_ptr += 8;
|
||||
eq1_bits_ptr += 8;
|
||||
}
|
||||
|
||||
/* Construct zerobits bitmap. */
|
||||
int16x8_t abs_row0 = vld1q_s16(absvalues + 0 * DCTSIZE);
|
||||
int16x8_t abs_row1 = vld1q_s16(absvalues + 1 * DCTSIZE);
|
||||
int16x8_t abs_row2 = vld1q_s16(absvalues + 2 * DCTSIZE);
|
||||
int16x8_t abs_row3 = vld1q_s16(absvalues + 3 * DCTSIZE);
|
||||
int16x8_t abs_row4 = vld1q_s16(absvalues + 4 * DCTSIZE);
|
||||
int16x8_t abs_row5 = vld1q_s16(absvalues + 5 * DCTSIZE);
|
||||
int16x8_t abs_row6 = vld1q_s16(absvalues + 6 * DCTSIZE);
|
||||
int16x8_t abs_row7 = vld1q_s16(absvalues + 7 * DCTSIZE);
|
||||
|
||||
uint8x8_t abs_row0_eq0 = vmovn_u16(vceqq_s16(abs_row0, vdupq_n_s16(0)));
|
||||
uint8x8_t abs_row1_eq0 = vmovn_u16(vceqq_s16(abs_row1, vdupq_n_s16(0)));
|
||||
uint8x8_t abs_row2_eq0 = vmovn_u16(vceqq_s16(abs_row2, vdupq_n_s16(0)));
|
||||
uint8x8_t abs_row3_eq0 = vmovn_u16(vceqq_s16(abs_row3, vdupq_n_s16(0)));
|
||||
uint8x8_t abs_row4_eq0 = vmovn_u16(vceqq_s16(abs_row4, vdupq_n_s16(0)));
|
||||
uint8x8_t abs_row5_eq0 = vmovn_u16(vceqq_s16(abs_row5, vdupq_n_s16(0)));
|
||||
uint8x8_t abs_row6_eq0 = vmovn_u16(vceqq_s16(abs_row6, vdupq_n_s16(0)));
|
||||
uint8x8_t abs_row7_eq0 = vmovn_u16(vceqq_s16(abs_row7, vdupq_n_s16(0)));
|
||||
|
||||
/* { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 } */
|
||||
const uint8x8_t bitmap_mask =
|
||||
vreinterpret_u8_u64(vmov_n_u64(0x8040201008040201));
|
||||
|
||||
abs_row0_eq0 = vand_u8(abs_row0_eq0, bitmap_mask);
|
||||
abs_row1_eq0 = vand_u8(abs_row1_eq0, bitmap_mask);
|
||||
abs_row2_eq0 = vand_u8(abs_row2_eq0, bitmap_mask);
|
||||
abs_row3_eq0 = vand_u8(abs_row3_eq0, bitmap_mask);
|
||||
abs_row4_eq0 = vand_u8(abs_row4_eq0, bitmap_mask);
|
||||
abs_row5_eq0 = vand_u8(abs_row5_eq0, bitmap_mask);
|
||||
abs_row6_eq0 = vand_u8(abs_row6_eq0, bitmap_mask);
|
||||
abs_row7_eq0 = vand_u8(abs_row7_eq0, bitmap_mask);
|
||||
|
||||
uint8x8_t bitmap_rows_01 = vpadd_u8(abs_row0_eq0, abs_row1_eq0);
|
||||
uint8x8_t bitmap_rows_23 = vpadd_u8(abs_row2_eq0, abs_row3_eq0);
|
||||
uint8x8_t bitmap_rows_45 = vpadd_u8(abs_row4_eq0, abs_row5_eq0);
|
||||
uint8x8_t bitmap_rows_67 = vpadd_u8(abs_row6_eq0, abs_row7_eq0);
|
||||
uint8x8_t bitmap_rows_0123 = vpadd_u8(bitmap_rows_01, bitmap_rows_23);
|
||||
uint8x8_t bitmap_rows_4567 = vpadd_u8(bitmap_rows_45, bitmap_rows_67);
|
||||
uint8x8_t bitmap_all = vpadd_u8(bitmap_rows_0123, bitmap_rows_4567);
|
||||
|
||||
#if defined(__aarch64__) || defined(_M_ARM64)
|
||||
/* Move bitmap to a 64-bit scalar register. */
|
||||
uint64_t bitmap = vget_lane_u64(vreinterpret_u64_u8(bitmap_all), 0);
|
||||
/* Store zerobits bitmap. */
|
||||
bits[0] = ~bitmap;
|
||||
#else
|
||||
/* Move bitmap to two 32-bit scalar registers. */
|
||||
uint32_t bitmap0 = vget_lane_u32(vreinterpret_u32_u8(bitmap_all), 0);
|
||||
uint32_t bitmap1 = vget_lane_u32(vreinterpret_u32_u8(bitmap_all), 1);
|
||||
/* Store zerobits bitmap. */
|
||||
bits[0] = ~bitmap0;
|
||||
bits[1] = ~bitmap1;
|
||||
#endif
|
||||
|
||||
/* Construct signbits bitmap. */
|
||||
uint8x8_t signbits_row0 = vld1_u8(coef_sign_bits + 0 * DCTSIZE);
|
||||
uint8x8_t signbits_row1 = vld1_u8(coef_sign_bits + 1 * DCTSIZE);
|
||||
uint8x8_t signbits_row2 = vld1_u8(coef_sign_bits + 2 * DCTSIZE);
|
||||
uint8x8_t signbits_row3 = vld1_u8(coef_sign_bits + 3 * DCTSIZE);
|
||||
uint8x8_t signbits_row4 = vld1_u8(coef_sign_bits + 4 * DCTSIZE);
|
||||
uint8x8_t signbits_row5 = vld1_u8(coef_sign_bits + 5 * DCTSIZE);
|
||||
uint8x8_t signbits_row6 = vld1_u8(coef_sign_bits + 6 * DCTSIZE);
|
||||
uint8x8_t signbits_row7 = vld1_u8(coef_sign_bits + 7 * DCTSIZE);
|
||||
|
||||
signbits_row0 = vand_u8(signbits_row0, bitmap_mask);
|
||||
signbits_row1 = vand_u8(signbits_row1, bitmap_mask);
|
||||
signbits_row2 = vand_u8(signbits_row2, bitmap_mask);
|
||||
signbits_row3 = vand_u8(signbits_row3, bitmap_mask);
|
||||
signbits_row4 = vand_u8(signbits_row4, bitmap_mask);
|
||||
signbits_row5 = vand_u8(signbits_row5, bitmap_mask);
|
||||
signbits_row6 = vand_u8(signbits_row6, bitmap_mask);
|
||||
signbits_row7 = vand_u8(signbits_row7, bitmap_mask);
|
||||
|
||||
bitmap_rows_01 = vpadd_u8(signbits_row0, signbits_row1);
|
||||
bitmap_rows_23 = vpadd_u8(signbits_row2, signbits_row3);
|
||||
bitmap_rows_45 = vpadd_u8(signbits_row4, signbits_row5);
|
||||
bitmap_rows_67 = vpadd_u8(signbits_row6, signbits_row7);
|
||||
bitmap_rows_0123 = vpadd_u8(bitmap_rows_01, bitmap_rows_23);
|
||||
bitmap_rows_4567 = vpadd_u8(bitmap_rows_45, bitmap_rows_67);
|
||||
bitmap_all = vpadd_u8(bitmap_rows_0123, bitmap_rows_4567);
|
||||
|
||||
#if defined(__aarch64__) || defined(_M_ARM64)
|
||||
/* Move bitmap to a 64-bit scalar register. */
|
||||
bitmap = vget_lane_u64(vreinterpret_u64_u8(bitmap_all), 0);
|
||||
/* Store signbits bitmap. */
|
||||
bits[1] = ~bitmap;
|
||||
#else
|
||||
/* Move bitmap to two 32-bit scalar registers. */
|
||||
bitmap0 = vget_lane_u32(vreinterpret_u32_u8(bitmap_all), 0);
|
||||
bitmap1 = vget_lane_u32(vreinterpret_u32_u8(bitmap_all), 1);
|
||||
/* Store signbits bitmap. */
|
||||
bits[2] = ~bitmap0;
|
||||
bits[3] = ~bitmap1;
|
||||
#endif
|
||||
|
||||
/* Construct bitmap to find EOB position (the index of the last coefficient
|
||||
* equal to 1.)
|
||||
*/
|
||||
uint8x8_t row0_eq1 = vld1_u8(coef_eq1_bits + 0 * DCTSIZE);
|
||||
uint8x8_t row1_eq1 = vld1_u8(coef_eq1_bits + 1 * DCTSIZE);
|
||||
uint8x8_t row2_eq1 = vld1_u8(coef_eq1_bits + 2 * DCTSIZE);
|
||||
uint8x8_t row3_eq1 = vld1_u8(coef_eq1_bits + 3 * DCTSIZE);
|
||||
uint8x8_t row4_eq1 = vld1_u8(coef_eq1_bits + 4 * DCTSIZE);
|
||||
uint8x8_t row5_eq1 = vld1_u8(coef_eq1_bits + 5 * DCTSIZE);
|
||||
uint8x8_t row6_eq1 = vld1_u8(coef_eq1_bits + 6 * DCTSIZE);
|
||||
uint8x8_t row7_eq1 = vld1_u8(coef_eq1_bits + 7 * DCTSIZE);
|
||||
|
||||
row0_eq1 = vand_u8(row0_eq1, bitmap_mask);
|
||||
row1_eq1 = vand_u8(row1_eq1, bitmap_mask);
|
||||
row2_eq1 = vand_u8(row2_eq1, bitmap_mask);
|
||||
row3_eq1 = vand_u8(row3_eq1, bitmap_mask);
|
||||
row4_eq1 = vand_u8(row4_eq1, bitmap_mask);
|
||||
row5_eq1 = vand_u8(row5_eq1, bitmap_mask);
|
||||
row6_eq1 = vand_u8(row6_eq1, bitmap_mask);
|
||||
row7_eq1 = vand_u8(row7_eq1, bitmap_mask);
|
||||
|
||||
bitmap_rows_01 = vpadd_u8(row0_eq1, row1_eq1);
|
||||
bitmap_rows_23 = vpadd_u8(row2_eq1, row3_eq1);
|
||||
bitmap_rows_45 = vpadd_u8(row4_eq1, row5_eq1);
|
||||
bitmap_rows_67 = vpadd_u8(row6_eq1, row7_eq1);
|
||||
bitmap_rows_0123 = vpadd_u8(bitmap_rows_01, bitmap_rows_23);
|
||||
bitmap_rows_4567 = vpadd_u8(bitmap_rows_45, bitmap_rows_67);
|
||||
bitmap_all = vpadd_u8(bitmap_rows_0123, bitmap_rows_4567);
|
||||
|
||||
#if defined(__aarch64__) || defined(_M_ARM64)
|
||||
/* Move bitmap to a 64-bit scalar register. */
|
||||
bitmap = vget_lane_u64(vreinterpret_u64_u8(bitmap_all), 0);
|
||||
|
||||
/* Return EOB position. */
|
||||
if (bitmap == 0) {
|
||||
/* EOB position is defined to be 0 if all coefficients != 1. */
|
||||
return 0;
|
||||
} else {
|
||||
return 63 - BUILTIN_CLZLL(bitmap);
|
||||
}
|
||||
#else
|
||||
/* Move bitmap to two 32-bit scalar registers. */
|
||||
bitmap0 = vget_lane_u32(vreinterpret_u32_u8(bitmap_all), 0);
|
||||
bitmap1 = vget_lane_u32(vreinterpret_u32_u8(bitmap_all), 1);
|
||||
|
||||
/* Return EOB position. */
|
||||
if (bitmap0 == 0 && bitmap1 == 0) {
|
||||
return 0;
|
||||
} else if (bitmap1 != 0) {
|
||||
return 63 - BUILTIN_CLZ(bitmap1);
|
||||
} else {
|
||||
return 31 - BUILTIN_CLZ(bitmap0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* jcsample-neon.c - downsampling (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
|
||||
ALIGN(16) static const uint8_t jsimd_h2_downsample_consts[] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* Pad 0 */
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* Pad 1 */
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0E,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* Pad 2 */
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0D, 0x0D,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* Pad 3 */
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0C, 0x0C, 0x0C,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* Pad 4 */
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* Pad 5 */
|
||||
0x08, 0x09, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* Pad 6 */
|
||||
0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* Pad 7 */
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* Pad 8 */
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, /* Pad 9 */
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x05, /* Pad 10 */
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x04, 0x04, 0x04, /* Pad 11 */
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x00, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, /* Pad 12 */
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* Pad 13 */
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* Pad 14 */
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Pad 15 */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
|
||||
/* Downsample pixel values of a single component.
|
||||
* This version handles the common case of 2:1 horizontal and 1:1 vertical,
|
||||
* without smoothing.
|
||||
*/
|
||||
|
||||
void jsimd_h2v1_downsample_neon(JDIMENSION image_width, int max_v_samp_factor,
|
||||
JDIMENSION v_samp_factor,
|
||||
JDIMENSION width_in_blocks,
|
||||
JSAMPARRAY input_data, JSAMPARRAY output_data)
|
||||
{
|
||||
JSAMPROW inptr, outptr;
|
||||
/* Load expansion mask to pad remaining elements of last DCT block. */
|
||||
const int mask_offset = 16 * ((width_in_blocks * 2 * DCTSIZE) - image_width);
|
||||
const uint8x16_t expand_mask =
|
||||
vld1q_u8(&jsimd_h2_downsample_consts[mask_offset]);
|
||||
/* Load bias pattern (alternating every pixel.) */
|
||||
/* { 0, 1, 0, 1, 0, 1, 0, 1 } */
|
||||
const uint16x8_t bias = vreinterpretq_u16_u32(vdupq_n_u32(0x00010000));
|
||||
unsigned i, outrow;
|
||||
|
||||
for (outrow = 0; outrow < v_samp_factor; outrow++) {
|
||||
outptr = output_data[outrow];
|
||||
inptr = input_data[outrow];
|
||||
|
||||
/* Downsample all but the last DCT block of pixels. */
|
||||
for (i = 0; i < width_in_blocks - 1; i++) {
|
||||
uint8x16_t pixels = vld1q_u8(inptr + i * 2 * DCTSIZE);
|
||||
/* Add adjacent pixel values, widen to 16-bit, and add bias. */
|
||||
uint16x8_t samples_u16 = vpadalq_u8(bias, pixels);
|
||||
/* Divide total by 2 and narrow to 8-bit. */
|
||||
uint8x8_t samples_u8 = vshrn_n_u16(samples_u16, 1);
|
||||
/* Store samples to memory. */
|
||||
vst1_u8(outptr + i * DCTSIZE, samples_u8);
|
||||
}
|
||||
|
||||
/* Load pixels in last DCT block into a table. */
|
||||
uint8x16_t pixels = vld1q_u8(inptr + (width_in_blocks - 1) * 2 * DCTSIZE);
|
||||
#if defined(__aarch64__) || defined(_M_ARM64)
|
||||
/* Pad the empty elements with the value of the last pixel. */
|
||||
pixels = vqtbl1q_u8(pixels, expand_mask);
|
||||
#else
|
||||
uint8x8x2_t table = { { vget_low_u8(pixels), vget_high_u8(pixels) } };
|
||||
pixels = vcombine_u8(vtbl2_u8(table, vget_low_u8(expand_mask)),
|
||||
vtbl2_u8(table, vget_high_u8(expand_mask)));
|
||||
#endif
|
||||
/* Add adjacent pixel values, widen to 16-bit, and add bias. */
|
||||
uint16x8_t samples_u16 = vpadalq_u8(bias, pixels);
|
||||
/* Divide total by 2, narrow to 8-bit, and store. */
|
||||
uint8x8_t samples_u8 = vshrn_n_u16(samples_u16, 1);
|
||||
vst1_u8(outptr + (width_in_blocks - 1) * DCTSIZE, samples_u8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Downsample pixel values of a single component.
|
||||
* This version handles the standard case of 2:1 horizontal and 2:1 vertical,
|
||||
* without smoothing.
|
||||
*/
|
||||
|
||||
void jsimd_h2v2_downsample_neon(JDIMENSION image_width, int max_v_samp_factor,
|
||||
JDIMENSION v_samp_factor,
|
||||
JDIMENSION width_in_blocks,
|
||||
JSAMPARRAY input_data, JSAMPARRAY output_data)
|
||||
{
|
||||
JSAMPROW inptr0, inptr1, outptr;
|
||||
/* Load expansion mask to pad remaining elements of last DCT block. */
|
||||
const int mask_offset = 16 * ((width_in_blocks * 2 * DCTSIZE) - image_width);
|
||||
const uint8x16_t expand_mask =
|
||||
vld1q_u8(&jsimd_h2_downsample_consts[mask_offset]);
|
||||
/* Load bias pattern (alternating every pixel.) */
|
||||
/* { 1, 2, 1, 2, 1, 2, 1, 2 } */
|
||||
const uint16x8_t bias = vreinterpretq_u16_u32(vdupq_n_u32(0x00020001));
|
||||
unsigned i, outrow;
|
||||
|
||||
for (outrow = 0; outrow < v_samp_factor; outrow++) {
|
||||
outptr = output_data[outrow];
|
||||
inptr0 = input_data[outrow];
|
||||
inptr1 = input_data[outrow + 1];
|
||||
|
||||
/* Downsample all but the last DCT block of pixels. */
|
||||
for (i = 0; i < width_in_blocks - 1; i++) {
|
||||
uint8x16_t pixels_r0 = vld1q_u8(inptr0 + i * 2 * DCTSIZE);
|
||||
uint8x16_t pixels_r1 = vld1q_u8(inptr1 + i * 2 * DCTSIZE);
|
||||
/* Add adjacent pixel values in row 0, widen to 16-bit, and add bias. */
|
||||
uint16x8_t samples_u16 = vpadalq_u8(bias, pixels_r0);
|
||||
/* Add adjacent pixel values in row 1, widen to 16-bit, and accumulate.
|
||||
*/
|
||||
samples_u16 = vpadalq_u8(samples_u16, pixels_r1);
|
||||
/* Divide total by 4 and narrow to 8-bit. */
|
||||
uint8x8_t samples_u8 = vshrn_n_u16(samples_u16, 2);
|
||||
/* Store samples to memory and increment pointers. */
|
||||
vst1_u8(outptr + i * DCTSIZE, samples_u8);
|
||||
}
|
||||
|
||||
/* Load pixels in last DCT block into a table. */
|
||||
uint8x16_t pixels_r0 =
|
||||
vld1q_u8(inptr0 + (width_in_blocks - 1) * 2 * DCTSIZE);
|
||||
uint8x16_t pixels_r1 =
|
||||
vld1q_u8(inptr1 + (width_in_blocks - 1) * 2 * DCTSIZE);
|
||||
#if defined(__aarch64__) || defined(_M_ARM64)
|
||||
/* Pad the empty elements with the value of the last pixel. */
|
||||
pixels_r0 = vqtbl1q_u8(pixels_r0, expand_mask);
|
||||
pixels_r1 = vqtbl1q_u8(pixels_r1, expand_mask);
|
||||
#else
|
||||
uint8x8x2_t table_r0 =
|
||||
{ { vget_low_u8(pixels_r0), vget_high_u8(pixels_r0) } };
|
||||
uint8x8x2_t table_r1 =
|
||||
{ { vget_low_u8(pixels_r1), vget_high_u8(pixels_r1) } };
|
||||
pixels_r0 = vcombine_u8(vtbl2_u8(table_r0, vget_low_u8(expand_mask)),
|
||||
vtbl2_u8(table_r0, vget_high_u8(expand_mask)));
|
||||
pixels_r1 = vcombine_u8(vtbl2_u8(table_r1, vget_low_u8(expand_mask)),
|
||||
vtbl2_u8(table_r1, vget_high_u8(expand_mask)));
|
||||
#endif
|
||||
/* Add adjacent pixel values in row 0, widen to 16-bit, and add bias. */
|
||||
uint16x8_t samples_u16 = vpadalq_u8(bias, pixels_r0);
|
||||
/* Add adjacent pixel values in row 1, widen to 16-bit, and accumulate. */
|
||||
samples_u16 = vpadalq_u8(samples_u16, pixels_r1);
|
||||
/* Divide total by 4, narrow to 8-bit, and store. */
|
||||
uint8x8_t samples_u8 = vshrn_n_u16(samples_u16, 2);
|
||||
vst1_u8(outptr + (width_in_blocks - 1) * DCTSIZE, samples_u8);
|
||||
}
|
||||
}
|
||||
+374
@@ -0,0 +1,374 @@
|
||||
/*
|
||||
* jdcolext-neon.c - colorspace conversion (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2020, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/* This file is included by jdcolor-neon.c. */
|
||||
|
||||
|
||||
/* YCbCr -> RGB conversion is defined by the following equations:
|
||||
* R = Y + 1.40200 * (Cr - 128)
|
||||
* G = Y - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128)
|
||||
* B = Y + 1.77200 * (Cb - 128)
|
||||
*
|
||||
* Scaled integer constants are used to avoid floating-point arithmetic:
|
||||
* 0.3441467 = 11277 * 2^-15
|
||||
* 0.7141418 = 23401 * 2^-15
|
||||
* 1.4020386 = 22971 * 2^-14
|
||||
* 1.7720337 = 29033 * 2^-14
|
||||
* These constants are defined in jdcolor-neon.c.
|
||||
*
|
||||
* To ensure correct results, rounding is used when descaling.
|
||||
*/
|
||||
|
||||
/* Notes on safe memory access for YCbCr -> RGB conversion routines:
|
||||
*
|
||||
* Input memory buffers can be safely overread up to the next multiple of
|
||||
* ALIGN_SIZE bytes, since they are always allocated by alloc_sarray() in
|
||||
* jmemmgr.c.
|
||||
*
|
||||
* The output buffer cannot safely be written beyond output_width, since
|
||||
* output_buf points to a possibly unpadded row in the decompressed image
|
||||
* buffer allocated by the calling program.
|
||||
*/
|
||||
|
||||
void jsimd_ycc_rgb_convert_neon(JDIMENSION output_width, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf,
|
||||
int num_rows)
|
||||
{
|
||||
JSAMPROW outptr;
|
||||
/* Pointers to Y, Cb, and Cr data */
|
||||
JSAMPROW inptr0, inptr1, inptr2;
|
||||
|
||||
const int16x4_t consts = vld1_s16(jsimd_ycc_rgb_convert_neon_consts);
|
||||
const int16x8_t neg_128 = vdupq_n_s16(-128);
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr0 = input_buf[0][input_row];
|
||||
inptr1 = input_buf[1][input_row];
|
||||
inptr2 = input_buf[2][input_row];
|
||||
input_row++;
|
||||
outptr = *output_buf++;
|
||||
int cols_remaining = output_width;
|
||||
for (; cols_remaining >= 16; cols_remaining -= 16) {
|
||||
uint8x16_t y = vld1q_u8(inptr0);
|
||||
uint8x16_t cb = vld1q_u8(inptr1);
|
||||
uint8x16_t cr = vld1q_u8(inptr2);
|
||||
/* Subtract 128 from Cb and Cr. */
|
||||
int16x8_t cr_128_l =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128),
|
||||
vget_low_u8(cr)));
|
||||
int16x8_t cr_128_h =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128),
|
||||
vget_high_u8(cr)));
|
||||
int16x8_t cb_128_l =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128),
|
||||
vget_low_u8(cb)));
|
||||
int16x8_t cb_128_h =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128),
|
||||
vget_high_u8(cb)));
|
||||
/* Compute G-Y: - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128) */
|
||||
int32x4_t g_sub_y_ll = vmull_lane_s16(vget_low_s16(cb_128_l), consts, 0);
|
||||
int32x4_t g_sub_y_lh = vmull_lane_s16(vget_high_s16(cb_128_l),
|
||||
consts, 0);
|
||||
int32x4_t g_sub_y_hl = vmull_lane_s16(vget_low_s16(cb_128_h), consts, 0);
|
||||
int32x4_t g_sub_y_hh = vmull_lane_s16(vget_high_s16(cb_128_h),
|
||||
consts, 0);
|
||||
g_sub_y_ll = vmlsl_lane_s16(g_sub_y_ll, vget_low_s16(cr_128_l),
|
||||
consts, 1);
|
||||
g_sub_y_lh = vmlsl_lane_s16(g_sub_y_lh, vget_high_s16(cr_128_l),
|
||||
consts, 1);
|
||||
g_sub_y_hl = vmlsl_lane_s16(g_sub_y_hl, vget_low_s16(cr_128_h),
|
||||
consts, 1);
|
||||
g_sub_y_hh = vmlsl_lane_s16(g_sub_y_hh, vget_high_s16(cr_128_h),
|
||||
consts, 1);
|
||||
/* Descale G components: shift right 15, round, and narrow to 16-bit. */
|
||||
int16x8_t g_sub_y_l = vcombine_s16(vrshrn_n_s32(g_sub_y_ll, 15),
|
||||
vrshrn_n_s32(g_sub_y_lh, 15));
|
||||
int16x8_t g_sub_y_h = vcombine_s16(vrshrn_n_s32(g_sub_y_hl, 15),
|
||||
vrshrn_n_s32(g_sub_y_hh, 15));
|
||||
/* Compute R-Y: 1.40200 * (Cr - 128) */
|
||||
int16x8_t r_sub_y_l = vqrdmulhq_lane_s16(vshlq_n_s16(cr_128_l, 1),
|
||||
consts, 2);
|
||||
int16x8_t r_sub_y_h = vqrdmulhq_lane_s16(vshlq_n_s16(cr_128_h, 1),
|
||||
consts, 2);
|
||||
/* Compute B-Y: 1.77200 * (Cb - 128) */
|
||||
int16x8_t b_sub_y_l = vqrdmulhq_lane_s16(vshlq_n_s16(cb_128_l, 1),
|
||||
consts, 3);
|
||||
int16x8_t b_sub_y_h = vqrdmulhq_lane_s16(vshlq_n_s16(cb_128_h, 1),
|
||||
consts, 3);
|
||||
/* Add Y. */
|
||||
int16x8_t r_l =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y_l),
|
||||
vget_low_u8(y)));
|
||||
int16x8_t r_h =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y_h),
|
||||
vget_high_u8(y)));
|
||||
int16x8_t b_l =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y_l),
|
||||
vget_low_u8(y)));
|
||||
int16x8_t b_h =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y_h),
|
||||
vget_high_u8(y)));
|
||||
int16x8_t g_l =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y_l),
|
||||
vget_low_u8(y)));
|
||||
int16x8_t g_h =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y_h),
|
||||
vget_high_u8(y)));
|
||||
|
||||
#if RGB_PIXELSIZE == 4
|
||||
uint8x16x4_t rgba;
|
||||
/* Convert each component to unsigned and narrow, clamping to [0-255]. */
|
||||
rgba.val[RGB_RED] = vcombine_u8(vqmovun_s16(r_l), vqmovun_s16(r_h));
|
||||
rgba.val[RGB_GREEN] = vcombine_u8(vqmovun_s16(g_l), vqmovun_s16(g_h));
|
||||
rgba.val[RGB_BLUE] = vcombine_u8(vqmovun_s16(b_l), vqmovun_s16(b_h));
|
||||
/* Set alpha channel to opaque (0xFF). */
|
||||
rgba.val[RGB_ALPHA] = vdupq_n_u8(0xFF);
|
||||
/* Store RGBA pixel data to memory. */
|
||||
vst4q_u8(outptr, rgba);
|
||||
#elif RGB_PIXELSIZE == 3
|
||||
uint8x16x3_t rgb;
|
||||
/* Convert each component to unsigned and narrow, clamping to [0-255]. */
|
||||
rgb.val[RGB_RED] = vcombine_u8(vqmovun_s16(r_l), vqmovun_s16(r_h));
|
||||
rgb.val[RGB_GREEN] = vcombine_u8(vqmovun_s16(g_l), vqmovun_s16(g_h));
|
||||
rgb.val[RGB_BLUE] = vcombine_u8(vqmovun_s16(b_l), vqmovun_s16(b_h));
|
||||
/* Store RGB pixel data to memory. */
|
||||
vst3q_u8(outptr, rgb);
|
||||
#else
|
||||
/* Pack R, G, and B values in ratio 5:6:5. */
|
||||
uint16x8_t rgb565_l = vqshluq_n_s16(r_l, 8);
|
||||
rgb565_l = vsriq_n_u16(rgb565_l, vqshluq_n_s16(g_l, 8), 5);
|
||||
rgb565_l = vsriq_n_u16(rgb565_l, vqshluq_n_s16(b_l, 8), 11);
|
||||
uint16x8_t rgb565_h = vqshluq_n_s16(r_h, 8);
|
||||
rgb565_h = vsriq_n_u16(rgb565_h, vqshluq_n_s16(g_h, 8), 5);
|
||||
rgb565_h = vsriq_n_u16(rgb565_h, vqshluq_n_s16(b_h, 8), 11);
|
||||
/* Store RGB pixel data to memory. */
|
||||
vst1q_u16((uint16_t *)outptr, rgb565_l);
|
||||
vst1q_u16(((uint16_t *)outptr) + 8, rgb565_h);
|
||||
#endif
|
||||
|
||||
/* Increment pointers. */
|
||||
inptr0 += 16;
|
||||
inptr1 += 16;
|
||||
inptr2 += 16;
|
||||
outptr += (RGB_PIXELSIZE * 16);
|
||||
}
|
||||
|
||||
if (cols_remaining >= 8) {
|
||||
uint8x8_t y = vld1_u8(inptr0);
|
||||
uint8x8_t cb = vld1_u8(inptr1);
|
||||
uint8x8_t cr = vld1_u8(inptr2);
|
||||
/* Subtract 128 from Cb and Cr. */
|
||||
int16x8_t cr_128 =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cr));
|
||||
int16x8_t cb_128 =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cb));
|
||||
/* Compute G-Y: - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128) */
|
||||
int32x4_t g_sub_y_l = vmull_lane_s16(vget_low_s16(cb_128), consts, 0);
|
||||
int32x4_t g_sub_y_h = vmull_lane_s16(vget_high_s16(cb_128), consts, 0);
|
||||
g_sub_y_l = vmlsl_lane_s16(g_sub_y_l, vget_low_s16(cr_128), consts, 1);
|
||||
g_sub_y_h = vmlsl_lane_s16(g_sub_y_h, vget_high_s16(cr_128), consts, 1);
|
||||
/* Descale G components: shift right 15, round, and narrow to 16-bit. */
|
||||
int16x8_t g_sub_y = vcombine_s16(vrshrn_n_s32(g_sub_y_l, 15),
|
||||
vrshrn_n_s32(g_sub_y_h, 15));
|
||||
/* Compute R-Y: 1.40200 * (Cr - 128) */
|
||||
int16x8_t r_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cr_128, 1),
|
||||
consts, 2);
|
||||
/* Compute B-Y: 1.77200 * (Cb - 128) */
|
||||
int16x8_t b_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cb_128, 1),
|
||||
consts, 3);
|
||||
/* Add Y. */
|
||||
int16x8_t r =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y), y));
|
||||
int16x8_t b =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y), y));
|
||||
int16x8_t g =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y), y));
|
||||
|
||||
#if RGB_PIXELSIZE == 4
|
||||
uint8x8x4_t rgba;
|
||||
/* Convert each component to unsigned and narrow, clamping to [0-255]. */
|
||||
rgba.val[RGB_RED] = vqmovun_s16(r);
|
||||
rgba.val[RGB_GREEN] = vqmovun_s16(g);
|
||||
rgba.val[RGB_BLUE] = vqmovun_s16(b);
|
||||
/* Set alpha channel to opaque (0xFF). */
|
||||
rgba.val[RGB_ALPHA] = vdup_n_u8(0xFF);
|
||||
/* Store RGBA pixel data to memory. */
|
||||
vst4_u8(outptr, rgba);
|
||||
#elif RGB_PIXELSIZE == 3
|
||||
uint8x8x3_t rgb;
|
||||
/* Convert each component to unsigned and narrow, clamping to [0-255]. */
|
||||
rgb.val[RGB_RED] = vqmovun_s16(r);
|
||||
rgb.val[RGB_GREEN] = vqmovun_s16(g);
|
||||
rgb.val[RGB_BLUE] = vqmovun_s16(b);
|
||||
/* Store RGB pixel data to memory. */
|
||||
vst3_u8(outptr, rgb);
|
||||
#else
|
||||
/* Pack R, G, and B values in ratio 5:6:5. */
|
||||
uint16x8_t rgb565 = vqshluq_n_s16(r, 8);
|
||||
rgb565 = vsriq_n_u16(rgb565, vqshluq_n_s16(g, 8), 5);
|
||||
rgb565 = vsriq_n_u16(rgb565, vqshluq_n_s16(b, 8), 11);
|
||||
/* Store RGB pixel data to memory. */
|
||||
vst1q_u16((uint16_t *)outptr, rgb565);
|
||||
#endif
|
||||
|
||||
/* Increment pointers. */
|
||||
inptr0 += 8;
|
||||
inptr1 += 8;
|
||||
inptr2 += 8;
|
||||
outptr += (RGB_PIXELSIZE * 8);
|
||||
cols_remaining -= 8;
|
||||
}
|
||||
|
||||
/* Handle the tail elements. */
|
||||
if (cols_remaining > 0) {
|
||||
uint8x8_t y = vld1_u8(inptr0);
|
||||
uint8x8_t cb = vld1_u8(inptr1);
|
||||
uint8x8_t cr = vld1_u8(inptr2);
|
||||
/* Subtract 128 from Cb and Cr. */
|
||||
int16x8_t cr_128 =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cr));
|
||||
int16x8_t cb_128 =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cb));
|
||||
/* Compute G-Y: - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128) */
|
||||
int32x4_t g_sub_y_l = vmull_lane_s16(vget_low_s16(cb_128), consts, 0);
|
||||
int32x4_t g_sub_y_h = vmull_lane_s16(vget_high_s16(cb_128), consts, 0);
|
||||
g_sub_y_l = vmlsl_lane_s16(g_sub_y_l, vget_low_s16(cr_128), consts, 1);
|
||||
g_sub_y_h = vmlsl_lane_s16(g_sub_y_h, vget_high_s16(cr_128), consts, 1);
|
||||
/* Descale G components: shift right 15, round, and narrow to 16-bit. */
|
||||
int16x8_t g_sub_y = vcombine_s16(vrshrn_n_s32(g_sub_y_l, 15),
|
||||
vrshrn_n_s32(g_sub_y_h, 15));
|
||||
/* Compute R-Y: 1.40200 * (Cr - 128) */
|
||||
int16x8_t r_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cr_128, 1),
|
||||
consts, 2);
|
||||
/* Compute B-Y: 1.77200 * (Cb - 128) */
|
||||
int16x8_t b_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cb_128, 1),
|
||||
consts, 3);
|
||||
/* Add Y. */
|
||||
int16x8_t r =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y), y));
|
||||
int16x8_t b =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y), y));
|
||||
int16x8_t g =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y), y));
|
||||
|
||||
#if RGB_PIXELSIZE == 4
|
||||
uint8x8x4_t rgba;
|
||||
/* Convert each component to unsigned and narrow, clamping to [0-255]. */
|
||||
rgba.val[RGB_RED] = vqmovun_s16(r);
|
||||
rgba.val[RGB_GREEN] = vqmovun_s16(g);
|
||||
rgba.val[RGB_BLUE] = vqmovun_s16(b);
|
||||
/* Set alpha channel to opaque (0xFF). */
|
||||
rgba.val[RGB_ALPHA] = vdup_n_u8(0xFF);
|
||||
/* Store RGBA pixel data to memory. */
|
||||
switch (cols_remaining) {
|
||||
case 7:
|
||||
vst4_lane_u8(outptr + 6 * RGB_PIXELSIZE, rgba, 6);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 6:
|
||||
vst4_lane_u8(outptr + 5 * RGB_PIXELSIZE, rgba, 5);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 5:
|
||||
vst4_lane_u8(outptr + 4 * RGB_PIXELSIZE, rgba, 4);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 4:
|
||||
vst4_lane_u8(outptr + 3 * RGB_PIXELSIZE, rgba, 3);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 3:
|
||||
vst4_lane_u8(outptr + 2 * RGB_PIXELSIZE, rgba, 2);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 2:
|
||||
vst4_lane_u8(outptr + RGB_PIXELSIZE, rgba, 1);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 1:
|
||||
vst4_lane_u8(outptr, rgba, 0);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#elif RGB_PIXELSIZE == 3
|
||||
uint8x8x3_t rgb;
|
||||
/* Convert each component to unsigned and narrow, clamping to [0-255]. */
|
||||
rgb.val[RGB_RED] = vqmovun_s16(r);
|
||||
rgb.val[RGB_GREEN] = vqmovun_s16(g);
|
||||
rgb.val[RGB_BLUE] = vqmovun_s16(b);
|
||||
/* Store RGB pixel data to memory. */
|
||||
switch (cols_remaining) {
|
||||
case 7:
|
||||
vst3_lane_u8(outptr + 6 * RGB_PIXELSIZE, rgb, 6);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 6:
|
||||
vst3_lane_u8(outptr + 5 * RGB_PIXELSIZE, rgb, 5);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 5:
|
||||
vst3_lane_u8(outptr + 4 * RGB_PIXELSIZE, rgb, 4);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 4:
|
||||
vst3_lane_u8(outptr + 3 * RGB_PIXELSIZE, rgb, 3);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 3:
|
||||
vst3_lane_u8(outptr + 2 * RGB_PIXELSIZE, rgb, 2);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 2:
|
||||
vst3_lane_u8(outptr + RGB_PIXELSIZE, rgb, 1);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 1:
|
||||
vst3_lane_u8(outptr, rgb, 0);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#else
|
||||
/* Pack R, G, and B values in ratio 5:6:5. */
|
||||
uint16x8_t rgb565 = vqshluq_n_s16(r, 8);
|
||||
rgb565 = vsriq_n_u16(rgb565, vqshluq_n_s16(g, 8), 5);
|
||||
rgb565 = vsriq_n_u16(rgb565, vqshluq_n_s16(b, 8), 11);
|
||||
/* Store RGB565 pixel data to memory. */
|
||||
switch (cols_remaining) {
|
||||
case 7:
|
||||
vst1q_lane_u16((uint16_t *)(outptr + 6 * RGB_PIXELSIZE), rgb565, 6);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 6:
|
||||
vst1q_lane_u16((uint16_t *)(outptr + 5 * RGB_PIXELSIZE), rgb565, 5);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 5:
|
||||
vst1q_lane_u16((uint16_t *)(outptr + 4 * RGB_PIXELSIZE), rgb565, 4);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 4:
|
||||
vst1q_lane_u16((uint16_t *)(outptr + 3 * RGB_PIXELSIZE), rgb565, 3);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 3:
|
||||
vst1q_lane_u16((uint16_t *)(outptr + 2 * RGB_PIXELSIZE), rgb565, 2);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 2:
|
||||
vst1q_lane_u16((uint16_t *)(outptr + RGB_PIXELSIZE), rgb565, 1);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 1:
|
||||
vst1q_lane_u16((uint16_t *)outptr, rgb565, 0);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* jdcolor-neon.c - colorspace conversion (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jconfigint.h"
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
|
||||
/* YCbCr -> RGB conversion constants */
|
||||
|
||||
#define F_0_344 11277 /* 0.3441467 = 11277 * 2^-15 */
|
||||
#define F_0_714 23401 /* 0.7141418 = 23401 * 2^-15 */
|
||||
#define F_1_402 22971 /* 1.4020386 = 22971 * 2^-14 */
|
||||
#define F_1_772 29033 /* 1.7720337 = 29033 * 2^-14 */
|
||||
|
||||
ALIGN(16) static const int16_t jsimd_ycc_rgb_convert_neon_consts[] = {
|
||||
-F_0_344, F_0_714, F_1_402, F_1_772
|
||||
};
|
||||
|
||||
|
||||
/* Include inline routines for colorspace extensions. */
|
||||
|
||||
#include "jdcolext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
|
||||
#define RGB_RED EXT_RGB_RED
|
||||
#define RGB_GREEN EXT_RGB_GREEN
|
||||
#define RGB_BLUE EXT_RGB_BLUE
|
||||
#define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
|
||||
#define jsimd_ycc_rgb_convert_neon jsimd_ycc_extrgb_convert_neon
|
||||
#include "jdcolext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_ycc_rgb_convert_neon
|
||||
|
||||
#define RGB_RED EXT_RGBX_RED
|
||||
#define RGB_GREEN EXT_RGBX_GREEN
|
||||
#define RGB_BLUE EXT_RGBX_BLUE
|
||||
#define RGB_ALPHA 3
|
||||
#define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
|
||||
#define jsimd_ycc_rgb_convert_neon jsimd_ycc_extrgbx_convert_neon
|
||||
#include "jdcolext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_ALPHA
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_ycc_rgb_convert_neon
|
||||
|
||||
#define RGB_RED EXT_BGR_RED
|
||||
#define RGB_GREEN EXT_BGR_GREEN
|
||||
#define RGB_BLUE EXT_BGR_BLUE
|
||||
#define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
|
||||
#define jsimd_ycc_rgb_convert_neon jsimd_ycc_extbgr_convert_neon
|
||||
#include "jdcolext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_ycc_rgb_convert_neon
|
||||
|
||||
#define RGB_RED EXT_BGRX_RED
|
||||
#define RGB_GREEN EXT_BGRX_GREEN
|
||||
#define RGB_BLUE EXT_BGRX_BLUE
|
||||
#define RGB_ALPHA 3
|
||||
#define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
|
||||
#define jsimd_ycc_rgb_convert_neon jsimd_ycc_extbgrx_convert_neon
|
||||
#include "jdcolext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_ALPHA
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_ycc_rgb_convert_neon
|
||||
|
||||
#define RGB_RED EXT_XBGR_RED
|
||||
#define RGB_GREEN EXT_XBGR_GREEN
|
||||
#define RGB_BLUE EXT_XBGR_BLUE
|
||||
#define RGB_ALPHA 0
|
||||
#define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
|
||||
#define jsimd_ycc_rgb_convert_neon jsimd_ycc_extxbgr_convert_neon
|
||||
#include "jdcolext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_ALPHA
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_ycc_rgb_convert_neon
|
||||
|
||||
#define RGB_RED EXT_XRGB_RED
|
||||
#define RGB_GREEN EXT_XRGB_GREEN
|
||||
#define RGB_BLUE EXT_XRGB_BLUE
|
||||
#define RGB_ALPHA 0
|
||||
#define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
|
||||
#define jsimd_ycc_rgb_convert_neon jsimd_ycc_extxrgb_convert_neon
|
||||
#include "jdcolext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_ALPHA
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_ycc_rgb_convert_neon
|
||||
|
||||
/* YCbCr -> RGB565 Conversion */
|
||||
|
||||
#define RGB_PIXELSIZE 2
|
||||
#define jsimd_ycc_rgb_convert_neon jsimd_ycc_rgb565_convert_neon
|
||||
#include "jdcolext-neon.c"
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_ycc_rgb_convert_neon
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* jdmerge-neon.c - merged upsampling/color conversion (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jconfigint.h"
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
|
||||
/* YCbCr -> RGB conversion constants */
|
||||
|
||||
#define F_0_344 11277 /* 0.3441467 = 11277 * 2^-15 */
|
||||
#define F_0_714 23401 /* 0.7141418 = 23401 * 2^-15 */
|
||||
#define F_1_402 22971 /* 1.4020386 = 22971 * 2^-14 */
|
||||
#define F_1_772 29033 /* 1.7720337 = 29033 * 2^-14 */
|
||||
|
||||
ALIGN(16) static const int16_t jsimd_ycc_rgb_convert_neon_consts[] = {
|
||||
-F_0_344, F_0_714, F_1_402, F_1_772
|
||||
};
|
||||
|
||||
|
||||
/* Include inline routines for colorspace extensions. */
|
||||
|
||||
#include "jdmrgext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
|
||||
#define RGB_RED EXT_RGB_RED
|
||||
#define RGB_GREEN EXT_RGB_GREEN
|
||||
#define RGB_BLUE EXT_RGB_BLUE
|
||||
#define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
|
||||
#define jsimd_h2v1_merged_upsample_neon jsimd_h2v1_extrgb_merged_upsample_neon
|
||||
#define jsimd_h2v2_merged_upsample_neon jsimd_h2v2_extrgb_merged_upsample_neon
|
||||
#include "jdmrgext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_h2v1_merged_upsample_neon
|
||||
#undef jsimd_h2v2_merged_upsample_neon
|
||||
|
||||
#define RGB_RED EXT_RGBX_RED
|
||||
#define RGB_GREEN EXT_RGBX_GREEN
|
||||
#define RGB_BLUE EXT_RGBX_BLUE
|
||||
#define RGB_ALPHA 3
|
||||
#define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
|
||||
#define jsimd_h2v1_merged_upsample_neon jsimd_h2v1_extrgbx_merged_upsample_neon
|
||||
#define jsimd_h2v2_merged_upsample_neon jsimd_h2v2_extrgbx_merged_upsample_neon
|
||||
#include "jdmrgext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_ALPHA
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_h2v1_merged_upsample_neon
|
||||
#undef jsimd_h2v2_merged_upsample_neon
|
||||
|
||||
#define RGB_RED EXT_BGR_RED
|
||||
#define RGB_GREEN EXT_BGR_GREEN
|
||||
#define RGB_BLUE EXT_BGR_BLUE
|
||||
#define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
|
||||
#define jsimd_h2v1_merged_upsample_neon jsimd_h2v1_extbgr_merged_upsample_neon
|
||||
#define jsimd_h2v2_merged_upsample_neon jsimd_h2v2_extbgr_merged_upsample_neon
|
||||
#include "jdmrgext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_h2v1_merged_upsample_neon
|
||||
#undef jsimd_h2v2_merged_upsample_neon
|
||||
|
||||
#define RGB_RED EXT_BGRX_RED
|
||||
#define RGB_GREEN EXT_BGRX_GREEN
|
||||
#define RGB_BLUE EXT_BGRX_BLUE
|
||||
#define RGB_ALPHA 3
|
||||
#define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
|
||||
#define jsimd_h2v1_merged_upsample_neon jsimd_h2v1_extbgrx_merged_upsample_neon
|
||||
#define jsimd_h2v2_merged_upsample_neon jsimd_h2v2_extbgrx_merged_upsample_neon
|
||||
#include "jdmrgext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_ALPHA
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_h2v1_merged_upsample_neon
|
||||
#undef jsimd_h2v2_merged_upsample_neon
|
||||
|
||||
#define RGB_RED EXT_XBGR_RED
|
||||
#define RGB_GREEN EXT_XBGR_GREEN
|
||||
#define RGB_BLUE EXT_XBGR_BLUE
|
||||
#define RGB_ALPHA 0
|
||||
#define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
|
||||
#define jsimd_h2v1_merged_upsample_neon jsimd_h2v1_extxbgr_merged_upsample_neon
|
||||
#define jsimd_h2v2_merged_upsample_neon jsimd_h2v2_extxbgr_merged_upsample_neon
|
||||
#include "jdmrgext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_ALPHA
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_h2v1_merged_upsample_neon
|
||||
#undef jsimd_h2v2_merged_upsample_neon
|
||||
|
||||
#define RGB_RED EXT_XRGB_RED
|
||||
#define RGB_GREEN EXT_XRGB_GREEN
|
||||
#define RGB_BLUE EXT_XRGB_BLUE
|
||||
#define RGB_ALPHA 0
|
||||
#define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
|
||||
#define jsimd_h2v1_merged_upsample_neon jsimd_h2v1_extxrgb_merged_upsample_neon
|
||||
#define jsimd_h2v2_merged_upsample_neon jsimd_h2v2_extxrgb_merged_upsample_neon
|
||||
#include "jdmrgext-neon.c"
|
||||
#undef RGB_RED
|
||||
#undef RGB_GREEN
|
||||
#undef RGB_BLUE
|
||||
#undef RGB_ALPHA
|
||||
#undef RGB_PIXELSIZE
|
||||
#undef jsimd_h2v1_merged_upsample_neon
|
||||
+723
@@ -0,0 +1,723 @@
|
||||
/*
|
||||
* jdmrgext-neon.c - merged upsampling/color conversion (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2020, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/* This file is included by jdmerge-neon.c. */
|
||||
|
||||
|
||||
/* These routines combine simple (non-fancy, i.e. non-smooth) h2v1 or h2v2
|
||||
* chroma upsampling and YCbCr -> RGB color conversion into a single function.
|
||||
*
|
||||
* As with the standalone functions, YCbCr -> RGB conversion is defined by the
|
||||
* following equations:
|
||||
* R = Y + 1.40200 * (Cr - 128)
|
||||
* G = Y - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128)
|
||||
* B = Y + 1.77200 * (Cb - 128)
|
||||
*
|
||||
* Scaled integer constants are used to avoid floating-point arithmetic:
|
||||
* 0.3441467 = 11277 * 2^-15
|
||||
* 0.7141418 = 23401 * 2^-15
|
||||
* 1.4020386 = 22971 * 2^-14
|
||||
* 1.7720337 = 29033 * 2^-14
|
||||
* These constants are defined in jdmerge-neon.c.
|
||||
*
|
||||
* To ensure correct results, rounding is used when descaling.
|
||||
*/
|
||||
|
||||
/* Notes on safe memory access for merged upsampling/YCbCr -> RGB conversion
|
||||
* routines:
|
||||
*
|
||||
* Input memory buffers can be safely overread up to the next multiple of
|
||||
* ALIGN_SIZE bytes, since they are always allocated by alloc_sarray() in
|
||||
* jmemmgr.c.
|
||||
*
|
||||
* The output buffer cannot safely be written beyond output_width, since
|
||||
* output_buf points to a possibly unpadded row in the decompressed image
|
||||
* buffer allocated by the calling program.
|
||||
*/
|
||||
|
||||
/* Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
|
||||
*/
|
||||
|
||||
void jsimd_h2v1_merged_upsample_neon(JDIMENSION output_width,
|
||||
JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr,
|
||||
JSAMPARRAY output_buf)
|
||||
{
|
||||
JSAMPROW outptr;
|
||||
/* Pointers to Y, Cb, and Cr data */
|
||||
JSAMPROW inptr0, inptr1, inptr2;
|
||||
|
||||
const int16x4_t consts = vld1_s16(jsimd_ycc_rgb_convert_neon_consts);
|
||||
const int16x8_t neg_128 = vdupq_n_s16(-128);
|
||||
|
||||
inptr0 = input_buf[0][in_row_group_ctr];
|
||||
inptr1 = input_buf[1][in_row_group_ctr];
|
||||
inptr2 = input_buf[2][in_row_group_ctr];
|
||||
outptr = output_buf[0];
|
||||
|
||||
int cols_remaining = output_width;
|
||||
for (; cols_remaining >= 16; cols_remaining -= 16) {
|
||||
/* De-interleave Y component values into two separate vectors, one
|
||||
* containing the component values with even-numbered indices and one
|
||||
* containing the component values with odd-numbered indices.
|
||||
*/
|
||||
uint8x8x2_t y = vld2_u8(inptr0);
|
||||
uint8x8_t cb = vld1_u8(inptr1);
|
||||
uint8x8_t cr = vld1_u8(inptr2);
|
||||
/* Subtract 128 from Cb and Cr. */
|
||||
int16x8_t cr_128 =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cr));
|
||||
int16x8_t cb_128 =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cb));
|
||||
/* Compute G-Y: - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128) */
|
||||
int32x4_t g_sub_y_l = vmull_lane_s16(vget_low_s16(cb_128), consts, 0);
|
||||
int32x4_t g_sub_y_h = vmull_lane_s16(vget_high_s16(cb_128), consts, 0);
|
||||
g_sub_y_l = vmlsl_lane_s16(g_sub_y_l, vget_low_s16(cr_128), consts, 1);
|
||||
g_sub_y_h = vmlsl_lane_s16(g_sub_y_h, vget_high_s16(cr_128), consts, 1);
|
||||
/* Descale G components: shift right 15, round, and narrow to 16-bit. */
|
||||
int16x8_t g_sub_y = vcombine_s16(vrshrn_n_s32(g_sub_y_l, 15),
|
||||
vrshrn_n_s32(g_sub_y_h, 15));
|
||||
/* Compute R-Y: 1.40200 * (Cr - 128) */
|
||||
int16x8_t r_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cr_128, 1), consts, 2);
|
||||
/* Compute B-Y: 1.77200 * (Cb - 128) */
|
||||
int16x8_t b_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cb_128, 1), consts, 3);
|
||||
/* Add the chroma-derived values (G-Y, R-Y, and B-Y) to both the "even" and
|
||||
* "odd" Y component values. This effectively upsamples the chroma
|
||||
* components horizontally.
|
||||
*/
|
||||
int16x8_t g_even =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
|
||||
y.val[0]));
|
||||
int16x8_t r_even =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
|
||||
y.val[0]));
|
||||
int16x8_t b_even =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
|
||||
y.val[0]));
|
||||
int16x8_t g_odd =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
|
||||
y.val[1]));
|
||||
int16x8_t r_odd =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
|
||||
y.val[1]));
|
||||
int16x8_t b_odd =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
|
||||
y.val[1]));
|
||||
/* Convert each component to unsigned and narrow, clamping to [0-255].
|
||||
* Re-interleave the "even" and "odd" component values.
|
||||
*/
|
||||
uint8x8x2_t r = vzip_u8(vqmovun_s16(r_even), vqmovun_s16(r_odd));
|
||||
uint8x8x2_t g = vzip_u8(vqmovun_s16(g_even), vqmovun_s16(g_odd));
|
||||
uint8x8x2_t b = vzip_u8(vqmovun_s16(b_even), vqmovun_s16(b_odd));
|
||||
|
||||
#ifdef RGB_ALPHA
|
||||
uint8x16x4_t rgba;
|
||||
rgba.val[RGB_RED] = vcombine_u8(r.val[0], r.val[1]);
|
||||
rgba.val[RGB_GREEN] = vcombine_u8(g.val[0], g.val[1]);
|
||||
rgba.val[RGB_BLUE] = vcombine_u8(b.val[0], b.val[1]);
|
||||
/* Set alpha channel to opaque (0xFF). */
|
||||
rgba.val[RGB_ALPHA] = vdupq_n_u8(0xFF);
|
||||
/* Store RGBA pixel data to memory. */
|
||||
vst4q_u8(outptr, rgba);
|
||||
#else
|
||||
uint8x16x3_t rgb;
|
||||
rgb.val[RGB_RED] = vcombine_u8(r.val[0], r.val[1]);
|
||||
rgb.val[RGB_GREEN] = vcombine_u8(g.val[0], g.val[1]);
|
||||
rgb.val[RGB_BLUE] = vcombine_u8(b.val[0], b.val[1]);
|
||||
/* Store RGB pixel data to memory. */
|
||||
vst3q_u8(outptr, rgb);
|
||||
#endif
|
||||
|
||||
/* Increment pointers. */
|
||||
inptr0 += 16;
|
||||
inptr1 += 8;
|
||||
inptr2 += 8;
|
||||
outptr += (RGB_PIXELSIZE * 16);
|
||||
}
|
||||
|
||||
if (cols_remaining > 0) {
|
||||
/* De-interleave Y component values into two separate vectors, one
|
||||
* containing the component values with even-numbered indices and one
|
||||
* containing the component values with odd-numbered indices.
|
||||
*/
|
||||
uint8x8x2_t y = vld2_u8(inptr0);
|
||||
uint8x8_t cb = vld1_u8(inptr1);
|
||||
uint8x8_t cr = vld1_u8(inptr2);
|
||||
/* Subtract 128 from Cb and Cr. */
|
||||
int16x8_t cr_128 =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cr));
|
||||
int16x8_t cb_128 =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cb));
|
||||
/* Compute G-Y: - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128) */
|
||||
int32x4_t g_sub_y_l = vmull_lane_s16(vget_low_s16(cb_128), consts, 0);
|
||||
int32x4_t g_sub_y_h = vmull_lane_s16(vget_high_s16(cb_128), consts, 0);
|
||||
g_sub_y_l = vmlsl_lane_s16(g_sub_y_l, vget_low_s16(cr_128), consts, 1);
|
||||
g_sub_y_h = vmlsl_lane_s16(g_sub_y_h, vget_high_s16(cr_128), consts, 1);
|
||||
/* Descale G components: shift right 15, round, and narrow to 16-bit. */
|
||||
int16x8_t g_sub_y = vcombine_s16(vrshrn_n_s32(g_sub_y_l, 15),
|
||||
vrshrn_n_s32(g_sub_y_h, 15));
|
||||
/* Compute R-Y: 1.40200 * (Cr - 128) */
|
||||
int16x8_t r_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cr_128, 1), consts, 2);
|
||||
/* Compute B-Y: 1.77200 * (Cb - 128) */
|
||||
int16x8_t b_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cb_128, 1), consts, 3);
|
||||
/* Add the chroma-derived values (G-Y, R-Y, and B-Y) to both the "even" and
|
||||
* "odd" Y component values. This effectively upsamples the chroma
|
||||
* components horizontally.
|
||||
*/
|
||||
int16x8_t g_even =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
|
||||
y.val[0]));
|
||||
int16x8_t r_even =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
|
||||
y.val[0]));
|
||||
int16x8_t b_even =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
|
||||
y.val[0]));
|
||||
int16x8_t g_odd =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
|
||||
y.val[1]));
|
||||
int16x8_t r_odd =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
|
||||
y.val[1]));
|
||||
int16x8_t b_odd =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
|
||||
y.val[1]));
|
||||
/* Convert each component to unsigned and narrow, clamping to [0-255].
|
||||
* Re-interleave the "even" and "odd" component values.
|
||||
*/
|
||||
uint8x8x2_t r = vzip_u8(vqmovun_s16(r_even), vqmovun_s16(r_odd));
|
||||
uint8x8x2_t g = vzip_u8(vqmovun_s16(g_even), vqmovun_s16(g_odd));
|
||||
uint8x8x2_t b = vzip_u8(vqmovun_s16(b_even), vqmovun_s16(b_odd));
|
||||
|
||||
#ifdef RGB_ALPHA
|
||||
uint8x8x4_t rgba_h;
|
||||
rgba_h.val[RGB_RED] = r.val[1];
|
||||
rgba_h.val[RGB_GREEN] = g.val[1];
|
||||
rgba_h.val[RGB_BLUE] = b.val[1];
|
||||
/* Set alpha channel to opaque (0xFF). */
|
||||
rgba_h.val[RGB_ALPHA] = vdup_n_u8(0xFF);
|
||||
uint8x8x4_t rgba_l;
|
||||
rgba_l.val[RGB_RED] = r.val[0];
|
||||
rgba_l.val[RGB_GREEN] = g.val[0];
|
||||
rgba_l.val[RGB_BLUE] = b.val[0];
|
||||
/* Set alpha channel to opaque (0xFF). */
|
||||
rgba_l.val[RGB_ALPHA] = vdup_n_u8(0xFF);
|
||||
/* Store RGBA pixel data to memory. */
|
||||
switch (cols_remaining) {
|
||||
case 15:
|
||||
vst4_lane_u8(outptr + 14 * RGB_PIXELSIZE, rgba_h, 6);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 14:
|
||||
vst4_lane_u8(outptr + 13 * RGB_PIXELSIZE, rgba_h, 5);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 13:
|
||||
vst4_lane_u8(outptr + 12 * RGB_PIXELSIZE, rgba_h, 4);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 12:
|
||||
vst4_lane_u8(outptr + 11 * RGB_PIXELSIZE, rgba_h, 3);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 11:
|
||||
vst4_lane_u8(outptr + 10 * RGB_PIXELSIZE, rgba_h, 2);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 10:
|
||||
vst4_lane_u8(outptr + 9 * RGB_PIXELSIZE, rgba_h, 1);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 9:
|
||||
vst4_lane_u8(outptr + 8 * RGB_PIXELSIZE, rgba_h, 0);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 8:
|
||||
vst4_u8(outptr, rgba_l);
|
||||
break;
|
||||
case 7:
|
||||
vst4_lane_u8(outptr + 6 * RGB_PIXELSIZE, rgba_l, 6);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 6:
|
||||
vst4_lane_u8(outptr + 5 * RGB_PIXELSIZE, rgba_l, 5);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 5:
|
||||
vst4_lane_u8(outptr + 4 * RGB_PIXELSIZE, rgba_l, 4);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 4:
|
||||
vst4_lane_u8(outptr + 3 * RGB_PIXELSIZE, rgba_l, 3);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 3:
|
||||
vst4_lane_u8(outptr + 2 * RGB_PIXELSIZE, rgba_l, 2);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 2:
|
||||
vst4_lane_u8(outptr + RGB_PIXELSIZE, rgba_l, 1);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 1:
|
||||
vst4_lane_u8(outptr, rgba_l, 0);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#else
|
||||
uint8x8x3_t rgb_h;
|
||||
rgb_h.val[RGB_RED] = r.val[1];
|
||||
rgb_h.val[RGB_GREEN] = g.val[1];
|
||||
rgb_h.val[RGB_BLUE] = b.val[1];
|
||||
uint8x8x3_t rgb_l;
|
||||
rgb_l.val[RGB_RED] = r.val[0];
|
||||
rgb_l.val[RGB_GREEN] = g.val[0];
|
||||
rgb_l.val[RGB_BLUE] = b.val[0];
|
||||
/* Store RGB pixel data to memory. */
|
||||
switch (cols_remaining) {
|
||||
case 15:
|
||||
vst3_lane_u8(outptr + 14 * RGB_PIXELSIZE, rgb_h, 6);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 14:
|
||||
vst3_lane_u8(outptr + 13 * RGB_PIXELSIZE, rgb_h, 5);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 13:
|
||||
vst3_lane_u8(outptr + 12 * RGB_PIXELSIZE, rgb_h, 4);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 12:
|
||||
vst3_lane_u8(outptr + 11 * RGB_PIXELSIZE, rgb_h, 3);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 11:
|
||||
vst3_lane_u8(outptr + 10 * RGB_PIXELSIZE, rgb_h, 2);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 10:
|
||||
vst3_lane_u8(outptr + 9 * RGB_PIXELSIZE, rgb_h, 1);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 9:
|
||||
vst3_lane_u8(outptr + 8 * RGB_PIXELSIZE, rgb_h, 0);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 8:
|
||||
vst3_u8(outptr, rgb_l);
|
||||
break;
|
||||
case 7:
|
||||
vst3_lane_u8(outptr + 6 * RGB_PIXELSIZE, rgb_l, 6);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 6:
|
||||
vst3_lane_u8(outptr + 5 * RGB_PIXELSIZE, rgb_l, 5);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 5:
|
||||
vst3_lane_u8(outptr + 4 * RGB_PIXELSIZE, rgb_l, 4);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 4:
|
||||
vst3_lane_u8(outptr + 3 * RGB_PIXELSIZE, rgb_l, 3);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 3:
|
||||
vst3_lane_u8(outptr + 2 * RGB_PIXELSIZE, rgb_l, 2);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 2:
|
||||
vst3_lane_u8(outptr + RGB_PIXELSIZE, rgb_l, 1);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 1:
|
||||
vst3_lane_u8(outptr, rgb_l, 0);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
|
||||
*
|
||||
* See comments above for details regarding color conversion and safe memory
|
||||
* access.
|
||||
*/
|
||||
|
||||
void jsimd_h2v2_merged_upsample_neon(JDIMENSION output_width,
|
||||
JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr,
|
||||
JSAMPARRAY output_buf)
|
||||
{
|
||||
JSAMPROW outptr0, outptr1;
|
||||
/* Pointers to Y (both rows), Cb, and Cr data */
|
||||
JSAMPROW inptr0_0, inptr0_1, inptr1, inptr2;
|
||||
|
||||
const int16x4_t consts = vld1_s16(jsimd_ycc_rgb_convert_neon_consts);
|
||||
const int16x8_t neg_128 = vdupq_n_s16(-128);
|
||||
|
||||
inptr0_0 = input_buf[0][in_row_group_ctr * 2];
|
||||
inptr0_1 = input_buf[0][in_row_group_ctr * 2 + 1];
|
||||
inptr1 = input_buf[1][in_row_group_ctr];
|
||||
inptr2 = input_buf[2][in_row_group_ctr];
|
||||
outptr0 = output_buf[0];
|
||||
outptr1 = output_buf[1];
|
||||
|
||||
int cols_remaining = output_width;
|
||||
for (; cols_remaining >= 16; cols_remaining -= 16) {
|
||||
/* For each row, de-interleave Y component values into two separate
|
||||
* vectors, one containing the component values with even-numbered indices
|
||||
* and one containing the component values with odd-numbered indices.
|
||||
*/
|
||||
uint8x8x2_t y0 = vld2_u8(inptr0_0);
|
||||
uint8x8x2_t y1 = vld2_u8(inptr0_1);
|
||||
uint8x8_t cb = vld1_u8(inptr1);
|
||||
uint8x8_t cr = vld1_u8(inptr2);
|
||||
/* Subtract 128 from Cb and Cr. */
|
||||
int16x8_t cr_128 =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cr));
|
||||
int16x8_t cb_128 =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cb));
|
||||
/* Compute G-Y: - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128) */
|
||||
int32x4_t g_sub_y_l = vmull_lane_s16(vget_low_s16(cb_128), consts, 0);
|
||||
int32x4_t g_sub_y_h = vmull_lane_s16(vget_high_s16(cb_128), consts, 0);
|
||||
g_sub_y_l = vmlsl_lane_s16(g_sub_y_l, vget_low_s16(cr_128), consts, 1);
|
||||
g_sub_y_h = vmlsl_lane_s16(g_sub_y_h, vget_high_s16(cr_128), consts, 1);
|
||||
/* Descale G components: shift right 15, round, and narrow to 16-bit. */
|
||||
int16x8_t g_sub_y = vcombine_s16(vrshrn_n_s32(g_sub_y_l, 15),
|
||||
vrshrn_n_s32(g_sub_y_h, 15));
|
||||
/* Compute R-Y: 1.40200 * (Cr - 128) */
|
||||
int16x8_t r_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cr_128, 1), consts, 2);
|
||||
/* Compute B-Y: 1.77200 * (Cb - 128) */
|
||||
int16x8_t b_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cb_128, 1), consts, 3);
|
||||
/* For each row, add the chroma-derived values (G-Y, R-Y, and B-Y) to both
|
||||
* the "even" and "odd" Y component values. This effectively upsamples the
|
||||
* chroma components both horizontally and vertically.
|
||||
*/
|
||||
int16x8_t g0_even =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
|
||||
y0.val[0]));
|
||||
int16x8_t r0_even =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
|
||||
y0.val[0]));
|
||||
int16x8_t b0_even =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
|
||||
y0.val[0]));
|
||||
int16x8_t g0_odd =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
|
||||
y0.val[1]));
|
||||
int16x8_t r0_odd =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
|
||||
y0.val[1]));
|
||||
int16x8_t b0_odd =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
|
||||
y0.val[1]));
|
||||
int16x8_t g1_even =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
|
||||
y1.val[0]));
|
||||
int16x8_t r1_even =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
|
||||
y1.val[0]));
|
||||
int16x8_t b1_even =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
|
||||
y1.val[0]));
|
||||
int16x8_t g1_odd =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
|
||||
y1.val[1]));
|
||||
int16x8_t r1_odd =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
|
||||
y1.val[1]));
|
||||
int16x8_t b1_odd =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
|
||||
y1.val[1]));
|
||||
/* Convert each component to unsigned and narrow, clamping to [0-255].
|
||||
* Re-interleave the "even" and "odd" component values.
|
||||
*/
|
||||
uint8x8x2_t r0 = vzip_u8(vqmovun_s16(r0_even), vqmovun_s16(r0_odd));
|
||||
uint8x8x2_t r1 = vzip_u8(vqmovun_s16(r1_even), vqmovun_s16(r1_odd));
|
||||
uint8x8x2_t g0 = vzip_u8(vqmovun_s16(g0_even), vqmovun_s16(g0_odd));
|
||||
uint8x8x2_t g1 = vzip_u8(vqmovun_s16(g1_even), vqmovun_s16(g1_odd));
|
||||
uint8x8x2_t b0 = vzip_u8(vqmovun_s16(b0_even), vqmovun_s16(b0_odd));
|
||||
uint8x8x2_t b1 = vzip_u8(vqmovun_s16(b1_even), vqmovun_s16(b1_odd));
|
||||
|
||||
#ifdef RGB_ALPHA
|
||||
uint8x16x4_t rgba0, rgba1;
|
||||
rgba0.val[RGB_RED] = vcombine_u8(r0.val[0], r0.val[1]);
|
||||
rgba1.val[RGB_RED] = vcombine_u8(r1.val[0], r1.val[1]);
|
||||
rgba0.val[RGB_GREEN] = vcombine_u8(g0.val[0], g0.val[1]);
|
||||
rgba1.val[RGB_GREEN] = vcombine_u8(g1.val[0], g1.val[1]);
|
||||
rgba0.val[RGB_BLUE] = vcombine_u8(b0.val[0], b0.val[1]);
|
||||
rgba1.val[RGB_BLUE] = vcombine_u8(b1.val[0], b1.val[1]);
|
||||
/* Set alpha channel to opaque (0xFF). */
|
||||
rgba0.val[RGB_ALPHA] = vdupq_n_u8(0xFF);
|
||||
rgba1.val[RGB_ALPHA] = vdupq_n_u8(0xFF);
|
||||
/* Store RGBA pixel data to memory. */
|
||||
vst4q_u8(outptr0, rgba0);
|
||||
vst4q_u8(outptr1, rgba1);
|
||||
#else
|
||||
uint8x16x3_t rgb0, rgb1;
|
||||
rgb0.val[RGB_RED] = vcombine_u8(r0.val[0], r0.val[1]);
|
||||
rgb1.val[RGB_RED] = vcombine_u8(r1.val[0], r1.val[1]);
|
||||
rgb0.val[RGB_GREEN] = vcombine_u8(g0.val[0], g0.val[1]);
|
||||
rgb1.val[RGB_GREEN] = vcombine_u8(g1.val[0], g1.val[1]);
|
||||
rgb0.val[RGB_BLUE] = vcombine_u8(b0.val[0], b0.val[1]);
|
||||
rgb1.val[RGB_BLUE] = vcombine_u8(b1.val[0], b1.val[1]);
|
||||
/* Store RGB pixel data to memory. */
|
||||
vst3q_u8(outptr0, rgb0);
|
||||
vst3q_u8(outptr1, rgb1);
|
||||
#endif
|
||||
|
||||
/* Increment pointers. */
|
||||
inptr0_0 += 16;
|
||||
inptr0_1 += 16;
|
||||
inptr1 += 8;
|
||||
inptr2 += 8;
|
||||
outptr0 += (RGB_PIXELSIZE * 16);
|
||||
outptr1 += (RGB_PIXELSIZE * 16);
|
||||
}
|
||||
|
||||
if (cols_remaining > 0) {
|
||||
/* For each row, de-interleave Y component values into two separate
|
||||
* vectors, one containing the component values with even-numbered indices
|
||||
* and one containing the component values with odd-numbered indices.
|
||||
*/
|
||||
uint8x8x2_t y0 = vld2_u8(inptr0_0);
|
||||
uint8x8x2_t y1 = vld2_u8(inptr0_1);
|
||||
uint8x8_t cb = vld1_u8(inptr1);
|
||||
uint8x8_t cr = vld1_u8(inptr2);
|
||||
/* Subtract 128 from Cb and Cr. */
|
||||
int16x8_t cr_128 =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cr));
|
||||
int16x8_t cb_128 =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cb));
|
||||
/* Compute G-Y: - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128) */
|
||||
int32x4_t g_sub_y_l = vmull_lane_s16(vget_low_s16(cb_128), consts, 0);
|
||||
int32x4_t g_sub_y_h = vmull_lane_s16(vget_high_s16(cb_128), consts, 0);
|
||||
g_sub_y_l = vmlsl_lane_s16(g_sub_y_l, vget_low_s16(cr_128), consts, 1);
|
||||
g_sub_y_h = vmlsl_lane_s16(g_sub_y_h, vget_high_s16(cr_128), consts, 1);
|
||||
/* Descale G components: shift right 15, round, and narrow to 16-bit. */
|
||||
int16x8_t g_sub_y = vcombine_s16(vrshrn_n_s32(g_sub_y_l, 15),
|
||||
vrshrn_n_s32(g_sub_y_h, 15));
|
||||
/* Compute R-Y: 1.40200 * (Cr - 128) */
|
||||
int16x8_t r_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cr_128, 1), consts, 2);
|
||||
/* Compute B-Y: 1.77200 * (Cb - 128) */
|
||||
int16x8_t b_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cb_128, 1), consts, 3);
|
||||
/* For each row, add the chroma-derived values (G-Y, R-Y, and B-Y) to both
|
||||
* the "even" and "odd" Y component values. This effectively upsamples the
|
||||
* chroma components both horizontally and vertically.
|
||||
*/
|
||||
int16x8_t g0_even =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
|
||||
y0.val[0]));
|
||||
int16x8_t r0_even =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
|
||||
y0.val[0]));
|
||||
int16x8_t b0_even =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
|
||||
y0.val[0]));
|
||||
int16x8_t g0_odd =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
|
||||
y0.val[1]));
|
||||
int16x8_t r0_odd =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
|
||||
y0.val[1]));
|
||||
int16x8_t b0_odd =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
|
||||
y0.val[1]));
|
||||
int16x8_t g1_even =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
|
||||
y1.val[0]));
|
||||
int16x8_t r1_even =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
|
||||
y1.val[0]));
|
||||
int16x8_t b1_even =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
|
||||
y1.val[0]));
|
||||
int16x8_t g1_odd =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
|
||||
y1.val[1]));
|
||||
int16x8_t r1_odd =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
|
||||
y1.val[1]));
|
||||
int16x8_t b1_odd =
|
||||
vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
|
||||
y1.val[1]));
|
||||
/* Convert each component to unsigned and narrow, clamping to [0-255].
|
||||
* Re-interleave the "even" and "odd" component values.
|
||||
*/
|
||||
uint8x8x2_t r0 = vzip_u8(vqmovun_s16(r0_even), vqmovun_s16(r0_odd));
|
||||
uint8x8x2_t r1 = vzip_u8(vqmovun_s16(r1_even), vqmovun_s16(r1_odd));
|
||||
uint8x8x2_t g0 = vzip_u8(vqmovun_s16(g0_even), vqmovun_s16(g0_odd));
|
||||
uint8x8x2_t g1 = vzip_u8(vqmovun_s16(g1_even), vqmovun_s16(g1_odd));
|
||||
uint8x8x2_t b0 = vzip_u8(vqmovun_s16(b0_even), vqmovun_s16(b0_odd));
|
||||
uint8x8x2_t b1 = vzip_u8(vqmovun_s16(b1_even), vqmovun_s16(b1_odd));
|
||||
|
||||
#ifdef RGB_ALPHA
|
||||
uint8x8x4_t rgba0_h, rgba1_h;
|
||||
rgba0_h.val[RGB_RED] = r0.val[1];
|
||||
rgba1_h.val[RGB_RED] = r1.val[1];
|
||||
rgba0_h.val[RGB_GREEN] = g0.val[1];
|
||||
rgba1_h.val[RGB_GREEN] = g1.val[1];
|
||||
rgba0_h.val[RGB_BLUE] = b0.val[1];
|
||||
rgba1_h.val[RGB_BLUE] = b1.val[1];
|
||||
/* Set alpha channel to opaque (0xFF). */
|
||||
rgba0_h.val[RGB_ALPHA] = vdup_n_u8(0xFF);
|
||||
rgba1_h.val[RGB_ALPHA] = vdup_n_u8(0xFF);
|
||||
|
||||
uint8x8x4_t rgba0_l, rgba1_l;
|
||||
rgba0_l.val[RGB_RED] = r0.val[0];
|
||||
rgba1_l.val[RGB_RED] = r1.val[0];
|
||||
rgba0_l.val[RGB_GREEN] = g0.val[0];
|
||||
rgba1_l.val[RGB_GREEN] = g1.val[0];
|
||||
rgba0_l.val[RGB_BLUE] = b0.val[0];
|
||||
rgba1_l.val[RGB_BLUE] = b1.val[0];
|
||||
/* Set alpha channel to opaque (0xFF). */
|
||||
rgba0_l.val[RGB_ALPHA] = vdup_n_u8(0xFF);
|
||||
rgba1_l.val[RGB_ALPHA] = vdup_n_u8(0xFF);
|
||||
/* Store RGBA pixel data to memory. */
|
||||
switch (cols_remaining) {
|
||||
case 15:
|
||||
vst4_lane_u8(outptr0 + 14 * RGB_PIXELSIZE, rgba0_h, 6);
|
||||
vst4_lane_u8(outptr1 + 14 * RGB_PIXELSIZE, rgba1_h, 6);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 14:
|
||||
vst4_lane_u8(outptr0 + 13 * RGB_PIXELSIZE, rgba0_h, 5);
|
||||
vst4_lane_u8(outptr1 + 13 * RGB_PIXELSIZE, rgba1_h, 5);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 13:
|
||||
vst4_lane_u8(outptr0 + 12 * RGB_PIXELSIZE, rgba0_h, 4);
|
||||
vst4_lane_u8(outptr1 + 12 * RGB_PIXELSIZE, rgba1_h, 4);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 12:
|
||||
vst4_lane_u8(outptr0 + 11 * RGB_PIXELSIZE, rgba0_h, 3);
|
||||
vst4_lane_u8(outptr1 + 11 * RGB_PIXELSIZE, rgba1_h, 3);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 11:
|
||||
vst4_lane_u8(outptr0 + 10 * RGB_PIXELSIZE, rgba0_h, 2);
|
||||
vst4_lane_u8(outptr1 + 10 * RGB_PIXELSIZE, rgba1_h, 2);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 10:
|
||||
vst4_lane_u8(outptr0 + 9 * RGB_PIXELSIZE, rgba0_h, 1);
|
||||
vst4_lane_u8(outptr1 + 9 * RGB_PIXELSIZE, rgba1_h, 1);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 9:
|
||||
vst4_lane_u8(outptr0 + 8 * RGB_PIXELSIZE, rgba0_h, 0);
|
||||
vst4_lane_u8(outptr1 + 8 * RGB_PIXELSIZE, rgba1_h, 0);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 8:
|
||||
vst4_u8(outptr0, rgba0_l);
|
||||
vst4_u8(outptr1, rgba1_l);
|
||||
break;
|
||||
case 7:
|
||||
vst4_lane_u8(outptr0 + 6 * RGB_PIXELSIZE, rgba0_l, 6);
|
||||
vst4_lane_u8(outptr1 + 6 * RGB_PIXELSIZE, rgba1_l, 6);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 6:
|
||||
vst4_lane_u8(outptr0 + 5 * RGB_PIXELSIZE, rgba0_l, 5);
|
||||
vst4_lane_u8(outptr1 + 5 * RGB_PIXELSIZE, rgba1_l, 5);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 5:
|
||||
vst4_lane_u8(outptr0 + 4 * RGB_PIXELSIZE, rgba0_l, 4);
|
||||
vst4_lane_u8(outptr1 + 4 * RGB_PIXELSIZE, rgba1_l, 4);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 4:
|
||||
vst4_lane_u8(outptr0 + 3 * RGB_PIXELSIZE, rgba0_l, 3);
|
||||
vst4_lane_u8(outptr1 + 3 * RGB_PIXELSIZE, rgba1_l, 3);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 3:
|
||||
vst4_lane_u8(outptr0 + 2 * RGB_PIXELSIZE, rgba0_l, 2);
|
||||
vst4_lane_u8(outptr1 + 2 * RGB_PIXELSIZE, rgba1_l, 2);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 2:
|
||||
vst4_lane_u8(outptr0 + 1 * RGB_PIXELSIZE, rgba0_l, 1);
|
||||
vst4_lane_u8(outptr1 + 1 * RGB_PIXELSIZE, rgba1_l, 1);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 1:
|
||||
vst4_lane_u8(outptr0, rgba0_l, 0);
|
||||
vst4_lane_u8(outptr1, rgba1_l, 0);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#else
|
||||
uint8x8x3_t rgb0_h, rgb1_h;
|
||||
rgb0_h.val[RGB_RED] = r0.val[1];
|
||||
rgb1_h.val[RGB_RED] = r1.val[1];
|
||||
rgb0_h.val[RGB_GREEN] = g0.val[1];
|
||||
rgb1_h.val[RGB_GREEN] = g1.val[1];
|
||||
rgb0_h.val[RGB_BLUE] = b0.val[1];
|
||||
rgb1_h.val[RGB_BLUE] = b1.val[1];
|
||||
|
||||
uint8x8x3_t rgb0_l, rgb1_l;
|
||||
rgb0_l.val[RGB_RED] = r0.val[0];
|
||||
rgb1_l.val[RGB_RED] = r1.val[0];
|
||||
rgb0_l.val[RGB_GREEN] = g0.val[0];
|
||||
rgb1_l.val[RGB_GREEN] = g1.val[0];
|
||||
rgb0_l.val[RGB_BLUE] = b0.val[0];
|
||||
rgb1_l.val[RGB_BLUE] = b1.val[0];
|
||||
/* Store RGB pixel data to memory. */
|
||||
switch (cols_remaining) {
|
||||
case 15:
|
||||
vst3_lane_u8(outptr0 + 14 * RGB_PIXELSIZE, rgb0_h, 6);
|
||||
vst3_lane_u8(outptr1 + 14 * RGB_PIXELSIZE, rgb1_h, 6);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 14:
|
||||
vst3_lane_u8(outptr0 + 13 * RGB_PIXELSIZE, rgb0_h, 5);
|
||||
vst3_lane_u8(outptr1 + 13 * RGB_PIXELSIZE, rgb1_h, 5);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 13:
|
||||
vst3_lane_u8(outptr0 + 12 * RGB_PIXELSIZE, rgb0_h, 4);
|
||||
vst3_lane_u8(outptr1 + 12 * RGB_PIXELSIZE, rgb1_h, 4);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 12:
|
||||
vst3_lane_u8(outptr0 + 11 * RGB_PIXELSIZE, rgb0_h, 3);
|
||||
vst3_lane_u8(outptr1 + 11 * RGB_PIXELSIZE, rgb1_h, 3);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 11:
|
||||
vst3_lane_u8(outptr0 + 10 * RGB_PIXELSIZE, rgb0_h, 2);
|
||||
vst3_lane_u8(outptr1 + 10 * RGB_PIXELSIZE, rgb1_h, 2);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 10:
|
||||
vst3_lane_u8(outptr0 + 9 * RGB_PIXELSIZE, rgb0_h, 1);
|
||||
vst3_lane_u8(outptr1 + 9 * RGB_PIXELSIZE, rgb1_h, 1);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 9:
|
||||
vst3_lane_u8(outptr0 + 8 * RGB_PIXELSIZE, rgb0_h, 0);
|
||||
vst3_lane_u8(outptr1 + 8 * RGB_PIXELSIZE, rgb1_h, 0);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 8:
|
||||
vst3_u8(outptr0, rgb0_l);
|
||||
vst3_u8(outptr1, rgb1_l);
|
||||
break;
|
||||
case 7:
|
||||
vst3_lane_u8(outptr0 + 6 * RGB_PIXELSIZE, rgb0_l, 6);
|
||||
vst3_lane_u8(outptr1 + 6 * RGB_PIXELSIZE, rgb1_l, 6);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 6:
|
||||
vst3_lane_u8(outptr0 + 5 * RGB_PIXELSIZE, rgb0_l, 5);
|
||||
vst3_lane_u8(outptr1 + 5 * RGB_PIXELSIZE, rgb1_l, 5);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 5:
|
||||
vst3_lane_u8(outptr0 + 4 * RGB_PIXELSIZE, rgb0_l, 4);
|
||||
vst3_lane_u8(outptr1 + 4 * RGB_PIXELSIZE, rgb1_l, 4);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 4:
|
||||
vst3_lane_u8(outptr0 + 3 * RGB_PIXELSIZE, rgb0_l, 3);
|
||||
vst3_lane_u8(outptr1 + 3 * RGB_PIXELSIZE, rgb1_l, 3);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 3:
|
||||
vst3_lane_u8(outptr0 + 2 * RGB_PIXELSIZE, rgb0_l, 2);
|
||||
vst3_lane_u8(outptr1 + 2 * RGB_PIXELSIZE, rgb1_l, 2);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 2:
|
||||
vst3_lane_u8(outptr0 + 1 * RGB_PIXELSIZE, rgb0_l, 1);
|
||||
vst3_lane_u8(outptr1 + 1 * RGB_PIXELSIZE, rgb1_l, 1);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case 1:
|
||||
vst3_lane_u8(outptr0, rgb0_l, 0);
|
||||
vst3_lane_u8(outptr1, rgb1_l, 0);
|
||||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
+569
@@ -0,0 +1,569 @@
|
||||
/*
|
||||
* jdsample-neon.c - upsampling (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2020, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
|
||||
/* The diagram below shows a row of samples produced by h2v1 downsampling.
|
||||
*
|
||||
* s0 s1 s2
|
||||
* +---------+---------+---------+
|
||||
* | | | |
|
||||
* | p0 p1 | p2 p3 | p4 p5 |
|
||||
* | | | |
|
||||
* +---------+---------+---------+
|
||||
*
|
||||
* Samples s0-s2 were created by averaging the original pixel component values
|
||||
* centered at positions p0-p5 above. To approximate those original pixel
|
||||
* component values, we proportionally blend the adjacent samples in each row.
|
||||
*
|
||||
* An upsampled pixel component value is computed by blending the sample
|
||||
* containing the pixel center with the nearest neighboring sample, in the
|
||||
* ratio 3:1. For example:
|
||||
* p1(upsampled) = 3/4 * s0 + 1/4 * s1
|
||||
* p2(upsampled) = 3/4 * s1 + 1/4 * s0
|
||||
* When computing the first and last pixel component values in the row, there
|
||||
* is no adjacent sample to blend, so:
|
||||
* p0(upsampled) = s0
|
||||
* p5(upsampled) = s2
|
||||
*/
|
||||
|
||||
void jsimd_h2v1_fancy_upsample_neon(int max_v_samp_factor,
|
||||
JDIMENSION downsampled_width,
|
||||
JSAMPARRAY input_data,
|
||||
JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
JSAMPROW inptr, outptr;
|
||||
int inrow;
|
||||
unsigned colctr;
|
||||
/* Set up constants. */
|
||||
const uint16x8_t one_u16 = vdupq_n_u16(1);
|
||||
const uint8x8_t three_u8 = vdup_n_u8(3);
|
||||
|
||||
for (inrow = 0; inrow < max_v_samp_factor; inrow++) {
|
||||
inptr = input_data[inrow];
|
||||
outptr = output_data[inrow];
|
||||
/* First pixel component value in this row of the original image */
|
||||
*outptr = (JSAMPLE)GETJSAMPLE(*inptr);
|
||||
|
||||
/* 3/4 * containing sample + 1/4 * nearest neighboring sample
|
||||
* For p1: containing sample = s0, nearest neighboring sample = s1
|
||||
* For p2: containing sample = s1, nearest neighboring sample = s0
|
||||
*/
|
||||
uint8x16_t s0 = vld1q_u8(inptr);
|
||||
uint8x16_t s1 = vld1q_u8(inptr + 1);
|
||||
/* Multiplication makes vectors twice as wide. '_l' and '_h' suffixes
|
||||
* denote low half and high half respectively.
|
||||
*/
|
||||
uint16x8_t s1_add_3s0_l =
|
||||
vmlal_u8(vmovl_u8(vget_low_u8(s1)), vget_low_u8(s0), three_u8);
|
||||
uint16x8_t s1_add_3s0_h =
|
||||
vmlal_u8(vmovl_u8(vget_high_u8(s1)), vget_high_u8(s0), three_u8);
|
||||
uint16x8_t s0_add_3s1_l =
|
||||
vmlal_u8(vmovl_u8(vget_low_u8(s0)), vget_low_u8(s1), three_u8);
|
||||
uint16x8_t s0_add_3s1_h =
|
||||
vmlal_u8(vmovl_u8(vget_high_u8(s0)), vget_high_u8(s1), three_u8);
|
||||
/* Add ordered dithering bias to odd pixel values. */
|
||||
s0_add_3s1_l = vaddq_u16(s0_add_3s1_l, one_u16);
|
||||
s0_add_3s1_h = vaddq_u16(s0_add_3s1_h, one_u16);
|
||||
|
||||
/* The offset is initially 1, because the first pixel component has already
|
||||
* been stored. However, in subsequent iterations of the SIMD loop, this
|
||||
* offset is (2 * colctr - 1) to stay within the bounds of the sample
|
||||
* buffers without having to resort to a slow scalar tail case for the last
|
||||
* (downsampled_width % 16) samples. See "Creation of 2-D sample arrays"
|
||||
* in jmemmgr.c for more details.
|
||||
*/
|
||||
unsigned outptr_offset = 1;
|
||||
uint8x16x2_t output_pixels;
|
||||
|
||||
/* We use software pipelining to maximise performance. The code indented
|
||||
* an extra two spaces begins the next iteration of the loop.
|
||||
*/
|
||||
for (colctr = 16; colctr < downsampled_width; colctr += 16) {
|
||||
|
||||
s0 = vld1q_u8(inptr + colctr - 1);
|
||||
s1 = vld1q_u8(inptr + colctr);
|
||||
|
||||
/* Right-shift by 2 (divide by 4), narrow to 8-bit, and combine. */
|
||||
output_pixels.val[0] = vcombine_u8(vrshrn_n_u16(s1_add_3s0_l, 2),
|
||||
vrshrn_n_u16(s1_add_3s0_h, 2));
|
||||
output_pixels.val[1] = vcombine_u8(vshrn_n_u16(s0_add_3s1_l, 2),
|
||||
vshrn_n_u16(s0_add_3s1_h, 2));
|
||||
|
||||
/* Multiplication makes vectors twice as wide. '_l' and '_h' suffixes
|
||||
* denote low half and high half respectively.
|
||||
*/
|
||||
s1_add_3s0_l =
|
||||
vmlal_u8(vmovl_u8(vget_low_u8(s1)), vget_low_u8(s0), three_u8);
|
||||
s1_add_3s0_h =
|
||||
vmlal_u8(vmovl_u8(vget_high_u8(s1)), vget_high_u8(s0), three_u8);
|
||||
s0_add_3s1_l =
|
||||
vmlal_u8(vmovl_u8(vget_low_u8(s0)), vget_low_u8(s1), three_u8);
|
||||
s0_add_3s1_h =
|
||||
vmlal_u8(vmovl_u8(vget_high_u8(s0)), vget_high_u8(s1), three_u8);
|
||||
/* Add ordered dithering bias to odd pixel values. */
|
||||
s0_add_3s1_l = vaddq_u16(s0_add_3s1_l, one_u16);
|
||||
s0_add_3s1_h = vaddq_u16(s0_add_3s1_h, one_u16);
|
||||
|
||||
/* Store pixel component values to memory. */
|
||||
vst2q_u8(outptr + outptr_offset, output_pixels);
|
||||
outptr_offset = 2 * colctr - 1;
|
||||
}
|
||||
|
||||
/* Complete the last iteration of the loop. */
|
||||
|
||||
/* Right-shift by 2 (divide by 4), narrow to 8-bit, and combine. */
|
||||
output_pixels.val[0] = vcombine_u8(vrshrn_n_u16(s1_add_3s0_l, 2),
|
||||
vrshrn_n_u16(s1_add_3s0_h, 2));
|
||||
output_pixels.val[1] = vcombine_u8(vshrn_n_u16(s0_add_3s1_l, 2),
|
||||
vshrn_n_u16(s0_add_3s1_h, 2));
|
||||
/* Store pixel component values to memory. */
|
||||
vst2q_u8(outptr + outptr_offset, output_pixels);
|
||||
|
||||
/* Last pixel component value in this row of the original image */
|
||||
outptr[2 * downsampled_width - 1] =
|
||||
GETJSAMPLE(inptr[downsampled_width - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* The diagram below shows an array of samples produced by h2v2 downsampling.
|
||||
*
|
||||
* s0 s1 s2
|
||||
* +---------+---------+---------+
|
||||
* | p0 p1 | p2 p3 | p4 p5 |
|
||||
* sA | | | |
|
||||
* | p6 p7 | p8 p9 | p10 p11|
|
||||
* +---------+---------+---------+
|
||||
* | p12 p13| p14 p15| p16 p17|
|
||||
* sB | | | |
|
||||
* | p18 p19| p20 p21| p22 p23|
|
||||
* +---------+---------+---------+
|
||||
* | p24 p25| p26 p27| p28 p29|
|
||||
* sC | | | |
|
||||
* | p30 p31| p32 p33| p34 p35|
|
||||
* +---------+---------+---------+
|
||||
*
|
||||
* Samples s0A-s2C were created by averaging the original pixel component
|
||||
* values centered at positions p0-p35 above. To approximate one of those
|
||||
* original pixel component values, we proportionally blend the sample
|
||||
* containing the pixel center with the nearest neighboring samples in each
|
||||
* row, column, and diagonal.
|
||||
*
|
||||
* An upsampled pixel component value is computed by first blending the sample
|
||||
* containing the pixel center with the nearest neighboring samples in the
|
||||
* same column, in the ratio 3:1, and then blending each column sum with the
|
||||
* nearest neighboring column sum, in the ratio 3:1. For example:
|
||||
* p14(upsampled) = 3/4 * (3/4 * s1B + 1/4 * s1A) +
|
||||
* 1/4 * (3/4 * s0B + 1/4 * s0A)
|
||||
* = 9/16 * s1B + 3/16 * s1A + 3/16 * s0B + 1/16 * s0A
|
||||
* When computing the first and last pixel component values in the row, there
|
||||
* is no horizontally adjacent sample to blend, so:
|
||||
* p12(upsampled) = 3/4 * s0B + 1/4 * s0A
|
||||
* p23(upsampled) = 3/4 * s2B + 1/4 * s2C
|
||||
* When computing the first and last pixel component values in the column,
|
||||
* there is no vertically adjacent sample to blend, so:
|
||||
* p2(upsampled) = 3/4 * s1A + 1/4 * s0A
|
||||
* p33(upsampled) = 3/4 * s1C + 1/4 * s2C
|
||||
* When computing the corner pixel component values, there is no adjacent
|
||||
* sample to blend, so:
|
||||
* p0(upsampled) = s0A
|
||||
* p35(upsampled) = s2C
|
||||
*/
|
||||
|
||||
void jsimd_h2v2_fancy_upsample_neon(int max_v_samp_factor,
|
||||
JDIMENSION downsampled_width,
|
||||
JSAMPARRAY input_data,
|
||||
JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
JSAMPROW inptr0, inptr1, inptr2, outptr0, outptr1;
|
||||
int inrow, outrow;
|
||||
unsigned colctr;
|
||||
/* Set up constants. */
|
||||
const uint16x8_t seven_u16 = vdupq_n_u16(7);
|
||||
const uint8x8_t three_u8 = vdup_n_u8(3);
|
||||
const uint16x8_t three_u16 = vdupq_n_u16(3);
|
||||
|
||||
inrow = outrow = 0;
|
||||
while (outrow < max_v_samp_factor) {
|
||||
inptr0 = input_data[inrow - 1];
|
||||
inptr1 = input_data[inrow];
|
||||
inptr2 = input_data[inrow + 1];
|
||||
/* Suffixes 0 and 1 denote the upper and lower rows of output pixels,
|
||||
* respectively.
|
||||
*/
|
||||
outptr0 = output_data[outrow++];
|
||||
outptr1 = output_data[outrow++];
|
||||
|
||||
/* First pixel component value in this row of the original image */
|
||||
int s0colsum0 = GETJSAMPLE(*inptr1) * 3 + GETJSAMPLE(*inptr0);
|
||||
*outptr0 = (JSAMPLE)((s0colsum0 * 4 + 8) >> 4);
|
||||
int s0colsum1 = GETJSAMPLE(*inptr1) * 3 + GETJSAMPLE(*inptr2);
|
||||
*outptr1 = (JSAMPLE)((s0colsum1 * 4 + 8) >> 4);
|
||||
|
||||
/* Step 1: Blend samples vertically in columns s0 and s1.
|
||||
* Leave the divide by 4 until the end, when it can be done for both
|
||||
* dimensions at once, right-shifting by 4.
|
||||
*/
|
||||
|
||||
/* Load and compute s0colsum0 and s0colsum1. */
|
||||
uint8x16_t s0A = vld1q_u8(inptr0);
|
||||
uint8x16_t s0B = vld1q_u8(inptr1);
|
||||
uint8x16_t s0C = vld1q_u8(inptr2);
|
||||
/* Multiplication makes vectors twice as wide. '_l' and '_h' suffixes
|
||||
* denote low half and high half respectively.
|
||||
*/
|
||||
uint16x8_t s0colsum0_l = vmlal_u8(vmovl_u8(vget_low_u8(s0A)),
|
||||
vget_low_u8(s0B), three_u8);
|
||||
uint16x8_t s0colsum0_h = vmlal_u8(vmovl_u8(vget_high_u8(s0A)),
|
||||
vget_high_u8(s0B), three_u8);
|
||||
uint16x8_t s0colsum1_l = vmlal_u8(vmovl_u8(vget_low_u8(s0C)),
|
||||
vget_low_u8(s0B), three_u8);
|
||||
uint16x8_t s0colsum1_h = vmlal_u8(vmovl_u8(vget_high_u8(s0C)),
|
||||
vget_high_u8(s0B), three_u8);
|
||||
/* Load and compute s1colsum0 and s1colsum1. */
|
||||
uint8x16_t s1A = vld1q_u8(inptr0 + 1);
|
||||
uint8x16_t s1B = vld1q_u8(inptr1 + 1);
|
||||
uint8x16_t s1C = vld1q_u8(inptr2 + 1);
|
||||
uint16x8_t s1colsum0_l = vmlal_u8(vmovl_u8(vget_low_u8(s1A)),
|
||||
vget_low_u8(s1B), three_u8);
|
||||
uint16x8_t s1colsum0_h = vmlal_u8(vmovl_u8(vget_high_u8(s1A)),
|
||||
vget_high_u8(s1B), three_u8);
|
||||
uint16x8_t s1colsum1_l = vmlal_u8(vmovl_u8(vget_low_u8(s1C)),
|
||||
vget_low_u8(s1B), three_u8);
|
||||
uint16x8_t s1colsum1_h = vmlal_u8(vmovl_u8(vget_high_u8(s1C)),
|
||||
vget_high_u8(s1B), three_u8);
|
||||
|
||||
/* Step 2: Blend the already-blended columns. */
|
||||
|
||||
uint16x8_t output0_p1_l = vmlaq_u16(s1colsum0_l, s0colsum0_l, three_u16);
|
||||
uint16x8_t output0_p1_h = vmlaq_u16(s1colsum0_h, s0colsum0_h, three_u16);
|
||||
uint16x8_t output0_p2_l = vmlaq_u16(s0colsum0_l, s1colsum0_l, three_u16);
|
||||
uint16x8_t output0_p2_h = vmlaq_u16(s0colsum0_h, s1colsum0_h, three_u16);
|
||||
uint16x8_t output1_p1_l = vmlaq_u16(s1colsum1_l, s0colsum1_l, three_u16);
|
||||
uint16x8_t output1_p1_h = vmlaq_u16(s1colsum1_h, s0colsum1_h, three_u16);
|
||||
uint16x8_t output1_p2_l = vmlaq_u16(s0colsum1_l, s1colsum1_l, three_u16);
|
||||
uint16x8_t output1_p2_h = vmlaq_u16(s0colsum1_h, s1colsum1_h, three_u16);
|
||||
/* Add ordered dithering bias to odd pixel values. */
|
||||
output0_p1_l = vaddq_u16(output0_p1_l, seven_u16);
|
||||
output0_p1_h = vaddq_u16(output0_p1_h, seven_u16);
|
||||
output1_p1_l = vaddq_u16(output1_p1_l, seven_u16);
|
||||
output1_p1_h = vaddq_u16(output1_p1_h, seven_u16);
|
||||
/* Right-shift by 4 (divide by 16), narrow to 8-bit, and combine. */
|
||||
uint8x16x2_t output_pixels0 = { {
|
||||
vcombine_u8(vshrn_n_u16(output0_p1_l, 4), vshrn_n_u16(output0_p1_h, 4)),
|
||||
vcombine_u8(vrshrn_n_u16(output0_p2_l, 4), vrshrn_n_u16(output0_p2_h, 4))
|
||||
} };
|
||||
uint8x16x2_t output_pixels1 = { {
|
||||
vcombine_u8(vshrn_n_u16(output1_p1_l, 4), vshrn_n_u16(output1_p1_h, 4)),
|
||||
vcombine_u8(vrshrn_n_u16(output1_p2_l, 4), vrshrn_n_u16(output1_p2_h, 4))
|
||||
} };
|
||||
|
||||
/* Store pixel component values to memory.
|
||||
* The minimum size of the output buffer for each row is 64 bytes => no
|
||||
* need to worry about buffer overflow here. See "Creation of 2-D sample
|
||||
* arrays" in jmemmgr.c for more details.
|
||||
*/
|
||||
vst2q_u8(outptr0 + 1, output_pixels0);
|
||||
vst2q_u8(outptr1 + 1, output_pixels1);
|
||||
|
||||
/* The first pixel of the image shifted our loads and stores by one byte.
|
||||
* We have to re-align on a 32-byte boundary at some point before the end
|
||||
* of the row (we do it now on the 32/33 pixel boundary) to stay within the
|
||||
* bounds of the sample buffers without having to resort to a slow scalar
|
||||
* tail case for the last (downsampled_width % 16) samples. See "Creation
|
||||
* of 2-D sample arrays" in jmemmgr.c for more details.
|
||||
*/
|
||||
for (colctr = 16; colctr < downsampled_width; colctr += 16) {
|
||||
/* Step 1: Blend samples vertically in columns s0 and s1. */
|
||||
|
||||
/* Load and compute s0colsum0 and s0colsum1. */
|
||||
s0A = vld1q_u8(inptr0 + colctr - 1);
|
||||
s0B = vld1q_u8(inptr1 + colctr - 1);
|
||||
s0C = vld1q_u8(inptr2 + colctr - 1);
|
||||
s0colsum0_l = vmlal_u8(vmovl_u8(vget_low_u8(s0A)), vget_low_u8(s0B),
|
||||
three_u8);
|
||||
s0colsum0_h = vmlal_u8(vmovl_u8(vget_high_u8(s0A)), vget_high_u8(s0B),
|
||||
three_u8);
|
||||
s0colsum1_l = vmlal_u8(vmovl_u8(vget_low_u8(s0C)), vget_low_u8(s0B),
|
||||
three_u8);
|
||||
s0colsum1_h = vmlal_u8(vmovl_u8(vget_high_u8(s0C)), vget_high_u8(s0B),
|
||||
three_u8);
|
||||
/* Load and compute s1colsum0 and s1colsum1. */
|
||||
s1A = vld1q_u8(inptr0 + colctr);
|
||||
s1B = vld1q_u8(inptr1 + colctr);
|
||||
s1C = vld1q_u8(inptr2 + colctr);
|
||||
s1colsum0_l = vmlal_u8(vmovl_u8(vget_low_u8(s1A)), vget_low_u8(s1B),
|
||||
three_u8);
|
||||
s1colsum0_h = vmlal_u8(vmovl_u8(vget_high_u8(s1A)), vget_high_u8(s1B),
|
||||
three_u8);
|
||||
s1colsum1_l = vmlal_u8(vmovl_u8(vget_low_u8(s1C)), vget_low_u8(s1B),
|
||||
three_u8);
|
||||
s1colsum1_h = vmlal_u8(vmovl_u8(vget_high_u8(s1C)), vget_high_u8(s1B),
|
||||
three_u8);
|
||||
|
||||
/* Step 2: Blend the already-blended columns. */
|
||||
|
||||
output0_p1_l = vmlaq_u16(s1colsum0_l, s0colsum0_l, three_u16);
|
||||
output0_p1_h = vmlaq_u16(s1colsum0_h, s0colsum0_h, three_u16);
|
||||
output0_p2_l = vmlaq_u16(s0colsum0_l, s1colsum0_l, three_u16);
|
||||
output0_p2_h = vmlaq_u16(s0colsum0_h, s1colsum0_h, three_u16);
|
||||
output1_p1_l = vmlaq_u16(s1colsum1_l, s0colsum1_l, three_u16);
|
||||
output1_p1_h = vmlaq_u16(s1colsum1_h, s0colsum1_h, three_u16);
|
||||
output1_p2_l = vmlaq_u16(s0colsum1_l, s1colsum1_l, three_u16);
|
||||
output1_p2_h = vmlaq_u16(s0colsum1_h, s1colsum1_h, three_u16);
|
||||
/* Add ordered dithering bias to odd pixel values. */
|
||||
output0_p1_l = vaddq_u16(output0_p1_l, seven_u16);
|
||||
output0_p1_h = vaddq_u16(output0_p1_h, seven_u16);
|
||||
output1_p1_l = vaddq_u16(output1_p1_l, seven_u16);
|
||||
output1_p1_h = vaddq_u16(output1_p1_h, seven_u16);
|
||||
/* Right-shift by 4 (divide by 16), narrow to 8-bit, and combine. */
|
||||
output_pixels0.val[0] = vcombine_u8(vshrn_n_u16(output0_p1_l, 4),
|
||||
vshrn_n_u16(output0_p1_h, 4));
|
||||
output_pixels0.val[1] = vcombine_u8(vrshrn_n_u16(output0_p2_l, 4),
|
||||
vrshrn_n_u16(output0_p2_h, 4));
|
||||
output_pixels1.val[0] = vcombine_u8(vshrn_n_u16(output1_p1_l, 4),
|
||||
vshrn_n_u16(output1_p1_h, 4));
|
||||
output_pixels1.val[1] = vcombine_u8(vrshrn_n_u16(output1_p2_l, 4),
|
||||
vrshrn_n_u16(output1_p2_h, 4));
|
||||
/* Store pixel component values to memory. */
|
||||
vst2q_u8(outptr0 + 2 * colctr - 1, output_pixels0);
|
||||
vst2q_u8(outptr1 + 2 * colctr - 1, output_pixels1);
|
||||
}
|
||||
|
||||
/* Last pixel component value in this row of the original image */
|
||||
int s1colsum0 = GETJSAMPLE(inptr1[downsampled_width - 1]) * 3 +
|
||||
GETJSAMPLE(inptr0[downsampled_width - 1]);
|
||||
outptr0[2 * downsampled_width - 1] = (JSAMPLE)((s1colsum0 * 4 + 7) >> 4);
|
||||
int s1colsum1 = GETJSAMPLE(inptr1[downsampled_width - 1]) * 3 +
|
||||
GETJSAMPLE(inptr2[downsampled_width - 1]);
|
||||
outptr1[2 * downsampled_width - 1] = (JSAMPLE)((s1colsum1 * 4 + 7) >> 4);
|
||||
inrow++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* The diagram below shows a column of samples produced by h1v2 downsampling
|
||||
* (or by losslessly rotating or transposing an h2v1-downsampled image.)
|
||||
*
|
||||
* +---------+
|
||||
* | p0 |
|
||||
* sA | |
|
||||
* | p1 |
|
||||
* +---------+
|
||||
* | p2 |
|
||||
* sB | |
|
||||
* | p3 |
|
||||
* +---------+
|
||||
* | p4 |
|
||||
* sC | |
|
||||
* | p5 |
|
||||
* +---------+
|
||||
*
|
||||
* Samples sA-sC were created by averaging the original pixel component values
|
||||
* centered at positions p0-p5 above. To approximate those original pixel
|
||||
* component values, we proportionally blend the adjacent samples in each
|
||||
* column.
|
||||
*
|
||||
* An upsampled pixel component value is computed by blending the sample
|
||||
* containing the pixel center with the nearest neighboring sample, in the
|
||||
* ratio 3:1. For example:
|
||||
* p1(upsampled) = 3/4 * sA + 1/4 * sB
|
||||
* p2(upsampled) = 3/4 * sB + 1/4 * sA
|
||||
* When computing the first and last pixel component values in the column,
|
||||
* there is no adjacent sample to blend, so:
|
||||
* p0(upsampled) = sA
|
||||
* p5(upsampled) = sC
|
||||
*/
|
||||
|
||||
void jsimd_h1v2_fancy_upsample_neon(int max_v_samp_factor,
|
||||
JDIMENSION downsampled_width,
|
||||
JSAMPARRAY input_data,
|
||||
JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
JSAMPROW inptr0, inptr1, inptr2, outptr0, outptr1;
|
||||
int inrow, outrow;
|
||||
unsigned colctr;
|
||||
/* Set up constants. */
|
||||
const uint16x8_t one_u16 = vdupq_n_u16(1);
|
||||
const uint8x8_t three_u8 = vdup_n_u8(3);
|
||||
|
||||
inrow = outrow = 0;
|
||||
while (outrow < max_v_samp_factor) {
|
||||
inptr0 = input_data[inrow - 1];
|
||||
inptr1 = input_data[inrow];
|
||||
inptr2 = input_data[inrow + 1];
|
||||
/* Suffixes 0 and 1 denote the upper and lower rows of output pixels,
|
||||
* respectively.
|
||||
*/
|
||||
outptr0 = output_data[outrow++];
|
||||
outptr1 = output_data[outrow++];
|
||||
inrow++;
|
||||
|
||||
/* The size of the input and output buffers is always a multiple of 32
|
||||
* bytes => no need to worry about buffer overflow when reading/writing
|
||||
* memory. See "Creation of 2-D sample arrays" in jmemmgr.c for more
|
||||
* details.
|
||||
*/
|
||||
for (colctr = 0; colctr < downsampled_width; colctr += 16) {
|
||||
/* Load samples. */
|
||||
uint8x16_t sA = vld1q_u8(inptr0 + colctr);
|
||||
uint8x16_t sB = vld1q_u8(inptr1 + colctr);
|
||||
uint8x16_t sC = vld1q_u8(inptr2 + colctr);
|
||||
/* Blend samples vertically. */
|
||||
uint16x8_t colsum0_l = vmlal_u8(vmovl_u8(vget_low_u8(sA)),
|
||||
vget_low_u8(sB), three_u8);
|
||||
uint16x8_t colsum0_h = vmlal_u8(vmovl_u8(vget_high_u8(sA)),
|
||||
vget_high_u8(sB), three_u8);
|
||||
uint16x8_t colsum1_l = vmlal_u8(vmovl_u8(vget_low_u8(sC)),
|
||||
vget_low_u8(sB), three_u8);
|
||||
uint16x8_t colsum1_h = vmlal_u8(vmovl_u8(vget_high_u8(sC)),
|
||||
vget_high_u8(sB), three_u8);
|
||||
/* Add ordered dithering bias to pixel values in even output rows. */
|
||||
colsum0_l = vaddq_u16(colsum0_l, one_u16);
|
||||
colsum0_h = vaddq_u16(colsum0_h, one_u16);
|
||||
/* Right-shift by 2 (divide by 4), narrow to 8-bit, and combine. */
|
||||
uint8x16_t output_pixels0 = vcombine_u8(vshrn_n_u16(colsum0_l, 2),
|
||||
vshrn_n_u16(colsum0_h, 2));
|
||||
uint8x16_t output_pixels1 = vcombine_u8(vrshrn_n_u16(colsum1_l, 2),
|
||||
vrshrn_n_u16(colsum1_h, 2));
|
||||
/* Store pixel component values to memory. */
|
||||
vst1q_u8(outptr0 + colctr, output_pixels0);
|
||||
vst1q_u8(outptr1 + colctr, output_pixels1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* The diagram below shows a row of samples produced by h2v1 downsampling.
|
||||
*
|
||||
* s0 s1
|
||||
* +---------+---------+
|
||||
* | | |
|
||||
* | p0 p1 | p2 p3 |
|
||||
* | | |
|
||||
* +---------+---------+
|
||||
*
|
||||
* Samples s0 and s1 were created by averaging the original pixel component
|
||||
* values centered at positions p0-p3 above. To approximate those original
|
||||
* pixel component values, we duplicate the samples horizontally:
|
||||
* p0(upsampled) = p1(upsampled) = s0
|
||||
* p2(upsampled) = p3(upsampled) = s1
|
||||
*/
|
||||
|
||||
void jsimd_h2v1_upsample_neon(int max_v_samp_factor, JDIMENSION output_width,
|
||||
JSAMPARRAY input_data,
|
||||
JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
JSAMPROW inptr, outptr;
|
||||
int inrow;
|
||||
unsigned colctr;
|
||||
|
||||
for (inrow = 0; inrow < max_v_samp_factor; inrow++) {
|
||||
inptr = input_data[inrow];
|
||||
outptr = output_data[inrow];
|
||||
for (colctr = 0; 2 * colctr < output_width; colctr += 16) {
|
||||
uint8x16_t samples = vld1q_u8(inptr + colctr);
|
||||
/* Duplicate the samples. The store operation below interleaves them so
|
||||
* that adjacent pixel component values take on the same sample value,
|
||||
* per above.
|
||||
*/
|
||||
uint8x16x2_t output_pixels = { { samples, samples } };
|
||||
/* Store pixel component values to memory.
|
||||
* Due to the way sample buffers are allocated, we don't need to worry
|
||||
* about tail cases when output_width is not a multiple of 32. See
|
||||
* "Creation of 2-D sample arrays" in jmemmgr.c for details.
|
||||
*/
|
||||
vst2q_u8(outptr + 2 * colctr, output_pixels);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* The diagram below shows an array of samples produced by h2v2 downsampling.
|
||||
*
|
||||
* s0 s1
|
||||
* +---------+---------+
|
||||
* | p0 p1 | p2 p3 |
|
||||
* sA | | |
|
||||
* | p4 p5 | p6 p7 |
|
||||
* +---------+---------+
|
||||
* | p8 p9 | p10 p11|
|
||||
* sB | | |
|
||||
* | p12 p13| p14 p15|
|
||||
* +---------+---------+
|
||||
*
|
||||
* Samples s0A-s1B were created by averaging the original pixel component
|
||||
* values centered at positions p0-p15 above. To approximate those original
|
||||
* pixel component values, we duplicate the samples both horizontally and
|
||||
* vertically:
|
||||
* p0(upsampled) = p1(upsampled) = p4(upsampled) = p5(upsampled) = s0A
|
||||
* p2(upsampled) = p3(upsampled) = p6(upsampled) = p7(upsampled) = s1A
|
||||
* p8(upsampled) = p9(upsampled) = p12(upsampled) = p13(upsampled) = s0B
|
||||
* p10(upsampled) = p11(upsampled) = p14(upsampled) = p15(upsampled) = s1B
|
||||
*/
|
||||
|
||||
void jsimd_h2v2_upsample_neon(int max_v_samp_factor, JDIMENSION output_width,
|
||||
JSAMPARRAY input_data,
|
||||
JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
JSAMPROW inptr, outptr0, outptr1;
|
||||
int inrow, outrow;
|
||||
unsigned colctr;
|
||||
|
||||
for (inrow = 0, outrow = 0; outrow < max_v_samp_factor; inrow++) {
|
||||
inptr = input_data[inrow];
|
||||
outptr0 = output_data[outrow++];
|
||||
outptr1 = output_data[outrow++];
|
||||
|
||||
for (colctr = 0; 2 * colctr < output_width; colctr += 16) {
|
||||
uint8x16_t samples = vld1q_u8(inptr + colctr);
|
||||
/* Duplicate the samples. The store operation below interleaves them so
|
||||
* that adjacent pixel component values take on the same sample value,
|
||||
* per above.
|
||||
*/
|
||||
uint8x16x2_t output_pixels = { { samples, samples } };
|
||||
/* Store pixel component values for both output rows to memory.
|
||||
* Due to the way sample buffers are allocated, we don't need to worry
|
||||
* about tail cases when output_width is not a multiple of 32. See
|
||||
* "Creation of 2-D sample arrays" in jmemmgr.c for details.
|
||||
*/
|
||||
vst2q_u8(outptr0 + 2 * colctr, output_pixels);
|
||||
vst2q_u8(outptr1 + 2 * colctr, output_pixels);
|
||||
}
|
||||
}
|
||||
}
|
||||
+214
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* jfdctfst-neon.c - fast integer FDCT (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
|
||||
/* jsimd_fdct_ifast_neon() performs a fast, not so accurate forward DCT
|
||||
* (Discrete Cosine Transform) on one block of samples. It uses the same
|
||||
* calculations and produces exactly the same output as IJG's original
|
||||
* jpeg_fdct_ifast() function, which can be found in jfdctfst.c.
|
||||
*
|
||||
* Scaled integer constants are used to avoid floating-point arithmetic:
|
||||
* 0.382683433 = 12544 * 2^-15
|
||||
* 0.541196100 = 17795 * 2^-15
|
||||
* 0.707106781 = 23168 * 2^-15
|
||||
* 0.306562965 = 9984 * 2^-15
|
||||
*
|
||||
* See jfdctfst.c for further details of the DCT algorithm. Where possible,
|
||||
* the variable names and comments here in jsimd_fdct_ifast_neon() match up
|
||||
* with those in jpeg_fdct_ifast().
|
||||
*/
|
||||
|
||||
#define F_0_382 12544
|
||||
#define F_0_541 17792
|
||||
#define F_0_707 23168
|
||||
#define F_0_306 9984
|
||||
|
||||
|
||||
ALIGN(16) static const int16_t jsimd_fdct_ifast_neon_consts[] = {
|
||||
F_0_382, F_0_541, F_0_707, F_0_306
|
||||
};
|
||||
|
||||
void jsimd_fdct_ifast_neon(DCTELEM *data)
|
||||
{
|
||||
/* Load an 8x8 block of samples into Neon registers. De-interleaving loads
|
||||
* are used, followed by vuzp to transpose the block such that we have a
|
||||
* column of samples per vector - allowing all rows to be processed at once.
|
||||
*/
|
||||
int16x8x4_t data1 = vld4q_s16(data);
|
||||
int16x8x4_t data2 = vld4q_s16(data + 4 * DCTSIZE);
|
||||
|
||||
int16x8x2_t cols_04 = vuzpq_s16(data1.val[0], data2.val[0]);
|
||||
int16x8x2_t cols_15 = vuzpq_s16(data1.val[1], data2.val[1]);
|
||||
int16x8x2_t cols_26 = vuzpq_s16(data1.val[2], data2.val[2]);
|
||||
int16x8x2_t cols_37 = vuzpq_s16(data1.val[3], data2.val[3]);
|
||||
|
||||
int16x8_t col0 = cols_04.val[0];
|
||||
int16x8_t col1 = cols_15.val[0];
|
||||
int16x8_t col2 = cols_26.val[0];
|
||||
int16x8_t col3 = cols_37.val[0];
|
||||
int16x8_t col4 = cols_04.val[1];
|
||||
int16x8_t col5 = cols_15.val[1];
|
||||
int16x8_t col6 = cols_26.val[1];
|
||||
int16x8_t col7 = cols_37.val[1];
|
||||
|
||||
/* Pass 1: process rows. */
|
||||
|
||||
/* Load DCT conversion constants. */
|
||||
const int16x4_t consts = vld1_s16(jsimd_fdct_ifast_neon_consts);
|
||||
|
||||
int16x8_t tmp0 = vaddq_s16(col0, col7);
|
||||
int16x8_t tmp7 = vsubq_s16(col0, col7);
|
||||
int16x8_t tmp1 = vaddq_s16(col1, col6);
|
||||
int16x8_t tmp6 = vsubq_s16(col1, col6);
|
||||
int16x8_t tmp2 = vaddq_s16(col2, col5);
|
||||
int16x8_t tmp5 = vsubq_s16(col2, col5);
|
||||
int16x8_t tmp3 = vaddq_s16(col3, col4);
|
||||
int16x8_t tmp4 = vsubq_s16(col3, col4);
|
||||
|
||||
/* Even part */
|
||||
int16x8_t tmp10 = vaddq_s16(tmp0, tmp3); /* phase 2 */
|
||||
int16x8_t tmp13 = vsubq_s16(tmp0, tmp3);
|
||||
int16x8_t tmp11 = vaddq_s16(tmp1, tmp2);
|
||||
int16x8_t tmp12 = vsubq_s16(tmp1, tmp2);
|
||||
|
||||
col0 = vaddq_s16(tmp10, tmp11); /* phase 3 */
|
||||
col4 = vsubq_s16(tmp10, tmp11);
|
||||
|
||||
int16x8_t z1 = vqdmulhq_lane_s16(vaddq_s16(tmp12, tmp13), consts, 2);
|
||||
col2 = vaddq_s16(tmp13, z1); /* phase 5 */
|
||||
col6 = vsubq_s16(tmp13, z1);
|
||||
|
||||
/* Odd part */
|
||||
tmp10 = vaddq_s16(tmp4, tmp5); /* phase 2 */
|
||||
tmp11 = vaddq_s16(tmp5, tmp6);
|
||||
tmp12 = vaddq_s16(tmp6, tmp7);
|
||||
|
||||
int16x8_t z5 = vqdmulhq_lane_s16(vsubq_s16(tmp10, tmp12), consts, 0);
|
||||
int16x8_t z2 = vqdmulhq_lane_s16(tmp10, consts, 1);
|
||||
z2 = vaddq_s16(z2, z5);
|
||||
int16x8_t z4 = vqdmulhq_lane_s16(tmp12, consts, 3);
|
||||
z5 = vaddq_s16(tmp12, z5);
|
||||
z4 = vaddq_s16(z4, z5);
|
||||
int16x8_t z3 = vqdmulhq_lane_s16(tmp11, consts, 2);
|
||||
|
||||
int16x8_t z11 = vaddq_s16(tmp7, z3); /* phase 5 */
|
||||
int16x8_t z13 = vsubq_s16(tmp7, z3);
|
||||
|
||||
col5 = vaddq_s16(z13, z2); /* phase 6 */
|
||||
col3 = vsubq_s16(z13, z2);
|
||||
col1 = vaddq_s16(z11, z4);
|
||||
col7 = vsubq_s16(z11, z4);
|
||||
|
||||
/* Transpose to work on columns in pass 2. */
|
||||
int16x8x2_t cols_01 = vtrnq_s16(col0, col1);
|
||||
int16x8x2_t cols_23 = vtrnq_s16(col2, col3);
|
||||
int16x8x2_t cols_45 = vtrnq_s16(col4, col5);
|
||||
int16x8x2_t cols_67 = vtrnq_s16(col6, col7);
|
||||
|
||||
int32x4x2_t cols_0145_l = vtrnq_s32(vreinterpretq_s32_s16(cols_01.val[0]),
|
||||
vreinterpretq_s32_s16(cols_45.val[0]));
|
||||
int32x4x2_t cols_0145_h = vtrnq_s32(vreinterpretq_s32_s16(cols_01.val[1]),
|
||||
vreinterpretq_s32_s16(cols_45.val[1]));
|
||||
int32x4x2_t cols_2367_l = vtrnq_s32(vreinterpretq_s32_s16(cols_23.val[0]),
|
||||
vreinterpretq_s32_s16(cols_67.val[0]));
|
||||
int32x4x2_t cols_2367_h = vtrnq_s32(vreinterpretq_s32_s16(cols_23.val[1]),
|
||||
vreinterpretq_s32_s16(cols_67.val[1]));
|
||||
|
||||
int32x4x2_t rows_04 = vzipq_s32(cols_0145_l.val[0], cols_2367_l.val[0]);
|
||||
int32x4x2_t rows_15 = vzipq_s32(cols_0145_h.val[0], cols_2367_h.val[0]);
|
||||
int32x4x2_t rows_26 = vzipq_s32(cols_0145_l.val[1], cols_2367_l.val[1]);
|
||||
int32x4x2_t rows_37 = vzipq_s32(cols_0145_h.val[1], cols_2367_h.val[1]);
|
||||
|
||||
int16x8_t row0 = vreinterpretq_s16_s32(rows_04.val[0]);
|
||||
int16x8_t row1 = vreinterpretq_s16_s32(rows_15.val[0]);
|
||||
int16x8_t row2 = vreinterpretq_s16_s32(rows_26.val[0]);
|
||||
int16x8_t row3 = vreinterpretq_s16_s32(rows_37.val[0]);
|
||||
int16x8_t row4 = vreinterpretq_s16_s32(rows_04.val[1]);
|
||||
int16x8_t row5 = vreinterpretq_s16_s32(rows_15.val[1]);
|
||||
int16x8_t row6 = vreinterpretq_s16_s32(rows_26.val[1]);
|
||||
int16x8_t row7 = vreinterpretq_s16_s32(rows_37.val[1]);
|
||||
|
||||
/* Pass 2: process columns. */
|
||||
|
||||
tmp0 = vaddq_s16(row0, row7);
|
||||
tmp7 = vsubq_s16(row0, row7);
|
||||
tmp1 = vaddq_s16(row1, row6);
|
||||
tmp6 = vsubq_s16(row1, row6);
|
||||
tmp2 = vaddq_s16(row2, row5);
|
||||
tmp5 = vsubq_s16(row2, row5);
|
||||
tmp3 = vaddq_s16(row3, row4);
|
||||
tmp4 = vsubq_s16(row3, row4);
|
||||
|
||||
/* Even part */
|
||||
tmp10 = vaddq_s16(tmp0, tmp3); /* phase 2 */
|
||||
tmp13 = vsubq_s16(tmp0, tmp3);
|
||||
tmp11 = vaddq_s16(tmp1, tmp2);
|
||||
tmp12 = vsubq_s16(tmp1, tmp2);
|
||||
|
||||
row0 = vaddq_s16(tmp10, tmp11); /* phase 3 */
|
||||
row4 = vsubq_s16(tmp10, tmp11);
|
||||
|
||||
z1 = vqdmulhq_lane_s16(vaddq_s16(tmp12, tmp13), consts, 2);
|
||||
row2 = vaddq_s16(tmp13, z1); /* phase 5 */
|
||||
row6 = vsubq_s16(tmp13, z1);
|
||||
|
||||
/* Odd part */
|
||||
tmp10 = vaddq_s16(tmp4, tmp5); /* phase 2 */
|
||||
tmp11 = vaddq_s16(tmp5, tmp6);
|
||||
tmp12 = vaddq_s16(tmp6, tmp7);
|
||||
|
||||
z5 = vqdmulhq_lane_s16(vsubq_s16(tmp10, tmp12), consts, 0);
|
||||
z2 = vqdmulhq_lane_s16(tmp10, consts, 1);
|
||||
z2 = vaddq_s16(z2, z5);
|
||||
z4 = vqdmulhq_lane_s16(tmp12, consts, 3);
|
||||
z5 = vaddq_s16(tmp12, z5);
|
||||
z4 = vaddq_s16(z4, z5);
|
||||
z3 = vqdmulhq_lane_s16(tmp11, consts, 2);
|
||||
|
||||
z11 = vaddq_s16(tmp7, z3); /* phase 5 */
|
||||
z13 = vsubq_s16(tmp7, z3);
|
||||
|
||||
row5 = vaddq_s16(z13, z2); /* phase 6 */
|
||||
row3 = vsubq_s16(z13, z2);
|
||||
row1 = vaddq_s16(z11, z4);
|
||||
row7 = vsubq_s16(z11, z4);
|
||||
|
||||
vst1q_s16(data + 0 * DCTSIZE, row0);
|
||||
vst1q_s16(data + 1 * DCTSIZE, row1);
|
||||
vst1q_s16(data + 2 * DCTSIZE, row2);
|
||||
vst1q_s16(data + 3 * DCTSIZE, row3);
|
||||
vst1q_s16(data + 4 * DCTSIZE, row4);
|
||||
vst1q_s16(data + 5 * DCTSIZE, row5);
|
||||
vst1q_s16(data + 6 * DCTSIZE, row6);
|
||||
vst1q_s16(data + 7 * DCTSIZE, row7);
|
||||
}
|
||||
+376
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
* jfdctint-neon.c - accurate integer FDCT (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2020, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
#include "neon-compat.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
|
||||
/* jsimd_fdct_islow_neon() performs a slower but more accurate forward DCT
|
||||
* (Discrete Cosine Transform) on one block of samples. It uses the same
|
||||
* calculations and produces exactly the same output as IJG's original
|
||||
* jpeg_fdct_islow() function, which can be found in jfdctint.c.
|
||||
*
|
||||
* Scaled integer constants are used to avoid floating-point arithmetic:
|
||||
* 0.298631336 = 2446 * 2^-13
|
||||
* 0.390180644 = 3196 * 2^-13
|
||||
* 0.541196100 = 4433 * 2^-13
|
||||
* 0.765366865 = 6270 * 2^-13
|
||||
* 0.899976223 = 7373 * 2^-13
|
||||
* 1.175875602 = 9633 * 2^-13
|
||||
* 1.501321110 = 12299 * 2^-13
|
||||
* 1.847759065 = 15137 * 2^-13
|
||||
* 1.961570560 = 16069 * 2^-13
|
||||
* 2.053119869 = 16819 * 2^-13
|
||||
* 2.562915447 = 20995 * 2^-13
|
||||
* 3.072711026 = 25172 * 2^-13
|
||||
*
|
||||
* See jfdctint.c for further details of the DCT algorithm. Where possible,
|
||||
* the variable names and comments here in jsimd_fdct_islow_neon() match up
|
||||
* with those in jpeg_fdct_islow().
|
||||
*/
|
||||
|
||||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 2
|
||||
|
||||
#define DESCALE_P1 (CONST_BITS - PASS1_BITS)
|
||||
#define DESCALE_P2 (CONST_BITS + PASS1_BITS)
|
||||
|
||||
#define F_0_298 2446
|
||||
#define F_0_390 3196
|
||||
#define F_0_541 4433
|
||||
#define F_0_765 6270
|
||||
#define F_0_899 7373
|
||||
#define F_1_175 9633
|
||||
#define F_1_501 12299
|
||||
#define F_1_847 15137
|
||||
#define F_1_961 16069
|
||||
#define F_2_053 16819
|
||||
#define F_2_562 20995
|
||||
#define F_3_072 25172
|
||||
|
||||
|
||||
ALIGN(16) static const int16_t jsimd_fdct_islow_neon_consts[] = {
|
||||
F_0_298, -F_0_390, F_0_541, F_0_765,
|
||||
-F_0_899, F_1_175, F_1_501, -F_1_847,
|
||||
-F_1_961, F_2_053, -F_2_562, F_3_072
|
||||
};
|
||||
|
||||
void jsimd_fdct_islow_neon(DCTELEM *data)
|
||||
{
|
||||
/* Load DCT constants. */
|
||||
#ifdef HAVE_VLD1_S16_X3
|
||||
const int16x4x3_t consts = vld1_s16_x3(jsimd_fdct_islow_neon_consts);
|
||||
#else
|
||||
/* GCC does not currently support the intrinsic vld1_<type>_x3(). */
|
||||
const int16x4_t consts1 = vld1_s16(jsimd_fdct_islow_neon_consts);
|
||||
const int16x4_t consts2 = vld1_s16(jsimd_fdct_islow_neon_consts + 4);
|
||||
const int16x4_t consts3 = vld1_s16(jsimd_fdct_islow_neon_consts + 8);
|
||||
const int16x4x3_t consts = { { consts1, consts2, consts3 } };
|
||||
#endif
|
||||
|
||||
/* Load an 8x8 block of samples into Neon registers. De-interleaving loads
|
||||
* are used, followed by vuzp to transpose the block such that we have a
|
||||
* column of samples per vector - allowing all rows to be processed at once.
|
||||
*/
|
||||
int16x8x4_t s_rows_0123 = vld4q_s16(data);
|
||||
int16x8x4_t s_rows_4567 = vld4q_s16(data + 4 * DCTSIZE);
|
||||
|
||||
int16x8x2_t cols_04 = vuzpq_s16(s_rows_0123.val[0], s_rows_4567.val[0]);
|
||||
int16x8x2_t cols_15 = vuzpq_s16(s_rows_0123.val[1], s_rows_4567.val[1]);
|
||||
int16x8x2_t cols_26 = vuzpq_s16(s_rows_0123.val[2], s_rows_4567.val[2]);
|
||||
int16x8x2_t cols_37 = vuzpq_s16(s_rows_0123.val[3], s_rows_4567.val[3]);
|
||||
|
||||
int16x8_t col0 = cols_04.val[0];
|
||||
int16x8_t col1 = cols_15.val[0];
|
||||
int16x8_t col2 = cols_26.val[0];
|
||||
int16x8_t col3 = cols_37.val[0];
|
||||
int16x8_t col4 = cols_04.val[1];
|
||||
int16x8_t col5 = cols_15.val[1];
|
||||
int16x8_t col6 = cols_26.val[1];
|
||||
int16x8_t col7 = cols_37.val[1];
|
||||
|
||||
/* Pass 1: process rows. */
|
||||
|
||||
int16x8_t tmp0 = vaddq_s16(col0, col7);
|
||||
int16x8_t tmp7 = vsubq_s16(col0, col7);
|
||||
int16x8_t tmp1 = vaddq_s16(col1, col6);
|
||||
int16x8_t tmp6 = vsubq_s16(col1, col6);
|
||||
int16x8_t tmp2 = vaddq_s16(col2, col5);
|
||||
int16x8_t tmp5 = vsubq_s16(col2, col5);
|
||||
int16x8_t tmp3 = vaddq_s16(col3, col4);
|
||||
int16x8_t tmp4 = vsubq_s16(col3, col4);
|
||||
|
||||
/* Even part */
|
||||
int16x8_t tmp10 = vaddq_s16(tmp0, tmp3);
|
||||
int16x8_t tmp13 = vsubq_s16(tmp0, tmp3);
|
||||
int16x8_t tmp11 = vaddq_s16(tmp1, tmp2);
|
||||
int16x8_t tmp12 = vsubq_s16(tmp1, tmp2);
|
||||
|
||||
col0 = vshlq_n_s16(vaddq_s16(tmp10, tmp11), PASS1_BITS);
|
||||
col4 = vshlq_n_s16(vsubq_s16(tmp10, tmp11), PASS1_BITS);
|
||||
|
||||
int16x8_t tmp12_add_tmp13 = vaddq_s16(tmp12, tmp13);
|
||||
int32x4_t z1_l =
|
||||
vmull_lane_s16(vget_low_s16(tmp12_add_tmp13), consts.val[0], 2);
|
||||
int32x4_t z1_h =
|
||||
vmull_lane_s16(vget_high_s16(tmp12_add_tmp13), consts.val[0], 2);
|
||||
|
||||
int32x4_t col2_scaled_l =
|
||||
vmlal_lane_s16(z1_l, vget_low_s16(tmp13), consts.val[0], 3);
|
||||
int32x4_t col2_scaled_h =
|
||||
vmlal_lane_s16(z1_h, vget_high_s16(tmp13), consts.val[0], 3);
|
||||
col2 = vcombine_s16(vrshrn_n_s32(col2_scaled_l, DESCALE_P1),
|
||||
vrshrn_n_s32(col2_scaled_h, DESCALE_P1));
|
||||
|
||||
int32x4_t col6_scaled_l =
|
||||
vmlal_lane_s16(z1_l, vget_low_s16(tmp12), consts.val[1], 3);
|
||||
int32x4_t col6_scaled_h =
|
||||
vmlal_lane_s16(z1_h, vget_high_s16(tmp12), consts.val[1], 3);
|
||||
col6 = vcombine_s16(vrshrn_n_s32(col6_scaled_l, DESCALE_P1),
|
||||
vrshrn_n_s32(col6_scaled_h, DESCALE_P1));
|
||||
|
||||
/* Odd part */
|
||||
int16x8_t z1 = vaddq_s16(tmp4, tmp7);
|
||||
int16x8_t z2 = vaddq_s16(tmp5, tmp6);
|
||||
int16x8_t z3 = vaddq_s16(tmp4, tmp6);
|
||||
int16x8_t z4 = vaddq_s16(tmp5, tmp7);
|
||||
/* sqrt(2) * c3 */
|
||||
int32x4_t z5_l = vmull_lane_s16(vget_low_s16(z3), consts.val[1], 1);
|
||||
int32x4_t z5_h = vmull_lane_s16(vget_high_s16(z3), consts.val[1], 1);
|
||||
z5_l = vmlal_lane_s16(z5_l, vget_low_s16(z4), consts.val[1], 1);
|
||||
z5_h = vmlal_lane_s16(z5_h, vget_high_s16(z4), consts.val[1], 1);
|
||||
|
||||
/* sqrt(2) * (-c1+c3+c5-c7) */
|
||||
int32x4_t tmp4_l = vmull_lane_s16(vget_low_s16(tmp4), consts.val[0], 0);
|
||||
int32x4_t tmp4_h = vmull_lane_s16(vget_high_s16(tmp4), consts.val[0], 0);
|
||||
/* sqrt(2) * ( c1+c3-c5+c7) */
|
||||
int32x4_t tmp5_l = vmull_lane_s16(vget_low_s16(tmp5), consts.val[2], 1);
|
||||
int32x4_t tmp5_h = vmull_lane_s16(vget_high_s16(tmp5), consts.val[2], 1);
|
||||
/* sqrt(2) * ( c1+c3+c5-c7) */
|
||||
int32x4_t tmp6_l = vmull_lane_s16(vget_low_s16(tmp6), consts.val[2], 3);
|
||||
int32x4_t tmp6_h = vmull_lane_s16(vget_high_s16(tmp6), consts.val[2], 3);
|
||||
/* sqrt(2) * ( c1+c3-c5-c7) */
|
||||
int32x4_t tmp7_l = vmull_lane_s16(vget_low_s16(tmp7), consts.val[1], 2);
|
||||
int32x4_t tmp7_h = vmull_lane_s16(vget_high_s16(tmp7), consts.val[1], 2);
|
||||
|
||||
/* sqrt(2) * (c7-c3) */
|
||||
z1_l = vmull_lane_s16(vget_low_s16(z1), consts.val[1], 0);
|
||||
z1_h = vmull_lane_s16(vget_high_s16(z1), consts.val[1], 0);
|
||||
/* sqrt(2) * (-c1-c3) */
|
||||
int32x4_t z2_l = vmull_lane_s16(vget_low_s16(z2), consts.val[2], 2);
|
||||
int32x4_t z2_h = vmull_lane_s16(vget_high_s16(z2), consts.val[2], 2);
|
||||
/* sqrt(2) * (-c3-c5) */
|
||||
int32x4_t z3_l = vmull_lane_s16(vget_low_s16(z3), consts.val[2], 0);
|
||||
int32x4_t z3_h = vmull_lane_s16(vget_high_s16(z3), consts.val[2], 0);
|
||||
/* sqrt(2) * (c5-c3) */
|
||||
int32x4_t z4_l = vmull_lane_s16(vget_low_s16(z4), consts.val[0], 1);
|
||||
int32x4_t z4_h = vmull_lane_s16(vget_high_s16(z4), consts.val[0], 1);
|
||||
|
||||
z3_l = vaddq_s32(z3_l, z5_l);
|
||||
z3_h = vaddq_s32(z3_h, z5_h);
|
||||
z4_l = vaddq_s32(z4_l, z5_l);
|
||||
z4_h = vaddq_s32(z4_h, z5_h);
|
||||
|
||||
tmp4_l = vaddq_s32(tmp4_l, z1_l);
|
||||
tmp4_h = vaddq_s32(tmp4_h, z1_h);
|
||||
tmp4_l = vaddq_s32(tmp4_l, z3_l);
|
||||
tmp4_h = vaddq_s32(tmp4_h, z3_h);
|
||||
col7 = vcombine_s16(vrshrn_n_s32(tmp4_l, DESCALE_P1),
|
||||
vrshrn_n_s32(tmp4_h, DESCALE_P1));
|
||||
|
||||
tmp5_l = vaddq_s32(tmp5_l, z2_l);
|
||||
tmp5_h = vaddq_s32(tmp5_h, z2_h);
|
||||
tmp5_l = vaddq_s32(tmp5_l, z4_l);
|
||||
tmp5_h = vaddq_s32(tmp5_h, z4_h);
|
||||
col5 = vcombine_s16(vrshrn_n_s32(tmp5_l, DESCALE_P1),
|
||||
vrshrn_n_s32(tmp5_h, DESCALE_P1));
|
||||
|
||||
tmp6_l = vaddq_s32(tmp6_l, z2_l);
|
||||
tmp6_h = vaddq_s32(tmp6_h, z2_h);
|
||||
tmp6_l = vaddq_s32(tmp6_l, z3_l);
|
||||
tmp6_h = vaddq_s32(tmp6_h, z3_h);
|
||||
col3 = vcombine_s16(vrshrn_n_s32(tmp6_l, DESCALE_P1),
|
||||
vrshrn_n_s32(tmp6_h, DESCALE_P1));
|
||||
|
||||
tmp7_l = vaddq_s32(tmp7_l, z1_l);
|
||||
tmp7_h = vaddq_s32(tmp7_h, z1_h);
|
||||
tmp7_l = vaddq_s32(tmp7_l, z4_l);
|
||||
tmp7_h = vaddq_s32(tmp7_h, z4_h);
|
||||
col1 = vcombine_s16(vrshrn_n_s32(tmp7_l, DESCALE_P1),
|
||||
vrshrn_n_s32(tmp7_h, DESCALE_P1));
|
||||
|
||||
/* Transpose to work on columns in pass 2. */
|
||||
int16x8x2_t cols_01 = vtrnq_s16(col0, col1);
|
||||
int16x8x2_t cols_23 = vtrnq_s16(col2, col3);
|
||||
int16x8x2_t cols_45 = vtrnq_s16(col4, col5);
|
||||
int16x8x2_t cols_67 = vtrnq_s16(col6, col7);
|
||||
|
||||
int32x4x2_t cols_0145_l = vtrnq_s32(vreinterpretq_s32_s16(cols_01.val[0]),
|
||||
vreinterpretq_s32_s16(cols_45.val[0]));
|
||||
int32x4x2_t cols_0145_h = vtrnq_s32(vreinterpretq_s32_s16(cols_01.val[1]),
|
||||
vreinterpretq_s32_s16(cols_45.val[1]));
|
||||
int32x4x2_t cols_2367_l = vtrnq_s32(vreinterpretq_s32_s16(cols_23.val[0]),
|
||||
vreinterpretq_s32_s16(cols_67.val[0]));
|
||||
int32x4x2_t cols_2367_h = vtrnq_s32(vreinterpretq_s32_s16(cols_23.val[1]),
|
||||
vreinterpretq_s32_s16(cols_67.val[1]));
|
||||
|
||||
int32x4x2_t rows_04 = vzipq_s32(cols_0145_l.val[0], cols_2367_l.val[0]);
|
||||
int32x4x2_t rows_15 = vzipq_s32(cols_0145_h.val[0], cols_2367_h.val[0]);
|
||||
int32x4x2_t rows_26 = vzipq_s32(cols_0145_l.val[1], cols_2367_l.val[1]);
|
||||
int32x4x2_t rows_37 = vzipq_s32(cols_0145_h.val[1], cols_2367_h.val[1]);
|
||||
|
||||
int16x8_t row0 = vreinterpretq_s16_s32(rows_04.val[0]);
|
||||
int16x8_t row1 = vreinterpretq_s16_s32(rows_15.val[0]);
|
||||
int16x8_t row2 = vreinterpretq_s16_s32(rows_26.val[0]);
|
||||
int16x8_t row3 = vreinterpretq_s16_s32(rows_37.val[0]);
|
||||
int16x8_t row4 = vreinterpretq_s16_s32(rows_04.val[1]);
|
||||
int16x8_t row5 = vreinterpretq_s16_s32(rows_15.val[1]);
|
||||
int16x8_t row6 = vreinterpretq_s16_s32(rows_26.val[1]);
|
||||
int16x8_t row7 = vreinterpretq_s16_s32(rows_37.val[1]);
|
||||
|
||||
/* Pass 2: process columns. */
|
||||
|
||||
tmp0 = vaddq_s16(row0, row7);
|
||||
tmp7 = vsubq_s16(row0, row7);
|
||||
tmp1 = vaddq_s16(row1, row6);
|
||||
tmp6 = vsubq_s16(row1, row6);
|
||||
tmp2 = vaddq_s16(row2, row5);
|
||||
tmp5 = vsubq_s16(row2, row5);
|
||||
tmp3 = vaddq_s16(row3, row4);
|
||||
tmp4 = vsubq_s16(row3, row4);
|
||||
|
||||
/* Even part */
|
||||
tmp10 = vaddq_s16(tmp0, tmp3);
|
||||
tmp13 = vsubq_s16(tmp0, tmp3);
|
||||
tmp11 = vaddq_s16(tmp1, tmp2);
|
||||
tmp12 = vsubq_s16(tmp1, tmp2);
|
||||
|
||||
row0 = vrshrq_n_s16(vaddq_s16(tmp10, tmp11), PASS1_BITS);
|
||||
row4 = vrshrq_n_s16(vsubq_s16(tmp10, tmp11), PASS1_BITS);
|
||||
|
||||
tmp12_add_tmp13 = vaddq_s16(tmp12, tmp13);
|
||||
z1_l = vmull_lane_s16(vget_low_s16(tmp12_add_tmp13), consts.val[0], 2);
|
||||
z1_h = vmull_lane_s16(vget_high_s16(tmp12_add_tmp13), consts.val[0], 2);
|
||||
|
||||
int32x4_t row2_scaled_l =
|
||||
vmlal_lane_s16(z1_l, vget_low_s16(tmp13), consts.val[0], 3);
|
||||
int32x4_t row2_scaled_h =
|
||||
vmlal_lane_s16(z1_h, vget_high_s16(tmp13), consts.val[0], 3);
|
||||
row2 = vcombine_s16(vrshrn_n_s32(row2_scaled_l, DESCALE_P2),
|
||||
vrshrn_n_s32(row2_scaled_h, DESCALE_P2));
|
||||
|
||||
int32x4_t row6_scaled_l =
|
||||
vmlal_lane_s16(z1_l, vget_low_s16(tmp12), consts.val[1], 3);
|
||||
int32x4_t row6_scaled_h =
|
||||
vmlal_lane_s16(z1_h, vget_high_s16(tmp12), consts.val[1], 3);
|
||||
row6 = vcombine_s16(vrshrn_n_s32(row6_scaled_l, DESCALE_P2),
|
||||
vrshrn_n_s32(row6_scaled_h, DESCALE_P2));
|
||||
|
||||
/* Odd part */
|
||||
z1 = vaddq_s16(tmp4, tmp7);
|
||||
z2 = vaddq_s16(tmp5, tmp6);
|
||||
z3 = vaddq_s16(tmp4, tmp6);
|
||||
z4 = vaddq_s16(tmp5, tmp7);
|
||||
/* sqrt(2) * c3 */
|
||||
z5_l = vmull_lane_s16(vget_low_s16(z3), consts.val[1], 1);
|
||||
z5_h = vmull_lane_s16(vget_high_s16(z3), consts.val[1], 1);
|
||||
z5_l = vmlal_lane_s16(z5_l, vget_low_s16(z4), consts.val[1], 1);
|
||||
z5_h = vmlal_lane_s16(z5_h, vget_high_s16(z4), consts.val[1], 1);
|
||||
|
||||
/* sqrt(2) * (-c1+c3+c5-c7) */
|
||||
tmp4_l = vmull_lane_s16(vget_low_s16(tmp4), consts.val[0], 0);
|
||||
tmp4_h = vmull_lane_s16(vget_high_s16(tmp4), consts.val[0], 0);
|
||||
/* sqrt(2) * ( c1+c3-c5+c7) */
|
||||
tmp5_l = vmull_lane_s16(vget_low_s16(tmp5), consts.val[2], 1);
|
||||
tmp5_h = vmull_lane_s16(vget_high_s16(tmp5), consts.val[2], 1);
|
||||
/* sqrt(2) * ( c1+c3+c5-c7) */
|
||||
tmp6_l = vmull_lane_s16(vget_low_s16(tmp6), consts.val[2], 3);
|
||||
tmp6_h = vmull_lane_s16(vget_high_s16(tmp6), consts.val[2], 3);
|
||||
/* sqrt(2) * ( c1+c3-c5-c7) */
|
||||
tmp7_l = vmull_lane_s16(vget_low_s16(tmp7), consts.val[1], 2);
|
||||
tmp7_h = vmull_lane_s16(vget_high_s16(tmp7), consts.val[1], 2);
|
||||
|
||||
/* sqrt(2) * (c7-c3) */
|
||||
z1_l = vmull_lane_s16(vget_low_s16(z1), consts.val[1], 0);
|
||||
z1_h = vmull_lane_s16(vget_high_s16(z1), consts.val[1], 0);
|
||||
/* sqrt(2) * (-c1-c3) */
|
||||
z2_l = vmull_lane_s16(vget_low_s16(z2), consts.val[2], 2);
|
||||
z2_h = vmull_lane_s16(vget_high_s16(z2), consts.val[2], 2);
|
||||
/* sqrt(2) * (-c3-c5) */
|
||||
z3_l = vmull_lane_s16(vget_low_s16(z3), consts.val[2], 0);
|
||||
z3_h = vmull_lane_s16(vget_high_s16(z3), consts.val[2], 0);
|
||||
/* sqrt(2) * (c5-c3) */
|
||||
z4_l = vmull_lane_s16(vget_low_s16(z4), consts.val[0], 1);
|
||||
z4_h = vmull_lane_s16(vget_high_s16(z4), consts.val[0], 1);
|
||||
|
||||
z3_l = vaddq_s32(z3_l, z5_l);
|
||||
z3_h = vaddq_s32(z3_h, z5_h);
|
||||
z4_l = vaddq_s32(z4_l, z5_l);
|
||||
z4_h = vaddq_s32(z4_h, z5_h);
|
||||
|
||||
tmp4_l = vaddq_s32(tmp4_l, z1_l);
|
||||
tmp4_h = vaddq_s32(tmp4_h, z1_h);
|
||||
tmp4_l = vaddq_s32(tmp4_l, z3_l);
|
||||
tmp4_h = vaddq_s32(tmp4_h, z3_h);
|
||||
row7 = vcombine_s16(vrshrn_n_s32(tmp4_l, DESCALE_P2),
|
||||
vrshrn_n_s32(tmp4_h, DESCALE_P2));
|
||||
|
||||
tmp5_l = vaddq_s32(tmp5_l, z2_l);
|
||||
tmp5_h = vaddq_s32(tmp5_h, z2_h);
|
||||
tmp5_l = vaddq_s32(tmp5_l, z4_l);
|
||||
tmp5_h = vaddq_s32(tmp5_h, z4_h);
|
||||
row5 = vcombine_s16(vrshrn_n_s32(tmp5_l, DESCALE_P2),
|
||||
vrshrn_n_s32(tmp5_h, DESCALE_P2));
|
||||
|
||||
tmp6_l = vaddq_s32(tmp6_l, z2_l);
|
||||
tmp6_h = vaddq_s32(tmp6_h, z2_h);
|
||||
tmp6_l = vaddq_s32(tmp6_l, z3_l);
|
||||
tmp6_h = vaddq_s32(tmp6_h, z3_h);
|
||||
row3 = vcombine_s16(vrshrn_n_s32(tmp6_l, DESCALE_P2),
|
||||
vrshrn_n_s32(tmp6_h, DESCALE_P2));
|
||||
|
||||
tmp7_l = vaddq_s32(tmp7_l, z1_l);
|
||||
tmp7_h = vaddq_s32(tmp7_h, z1_h);
|
||||
tmp7_l = vaddq_s32(tmp7_l, z4_l);
|
||||
tmp7_h = vaddq_s32(tmp7_h, z4_h);
|
||||
row1 = vcombine_s16(vrshrn_n_s32(tmp7_l, DESCALE_P2),
|
||||
vrshrn_n_s32(tmp7_h, DESCALE_P2));
|
||||
|
||||
vst1q_s16(data + 0 * DCTSIZE, row0);
|
||||
vst1q_s16(data + 1 * DCTSIZE, row1);
|
||||
vst1q_s16(data + 2 * DCTSIZE, row2);
|
||||
vst1q_s16(data + 3 * DCTSIZE, row3);
|
||||
vst1q_s16(data + 4 * DCTSIZE, row4);
|
||||
vst1q_s16(data + 5 * DCTSIZE, row5);
|
||||
vst1q_s16(data + 6 * DCTSIZE, row6);
|
||||
vst1q_s16(data + 7 * DCTSIZE, row7);
|
||||
}
|
||||
+472
@@ -0,0 +1,472 @@
|
||||
/*
|
||||
* jidctfst-neon.c - fast integer IDCT (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
|
||||
/* jsimd_idct_ifast_neon() performs dequantization and a fast, not so accurate
|
||||
* inverse DCT (Discrete Cosine Transform) on one block of coefficients. It
|
||||
* uses the same calculations and produces exactly the same output as IJG's
|
||||
* original jpeg_idct_ifast() function, which can be found in jidctfst.c.
|
||||
*
|
||||
* Scaled integer constants are used to avoid floating-point arithmetic:
|
||||
* 0.082392200 = 2688 * 2^-15
|
||||
* 0.414213562 = 13568 * 2^-15
|
||||
* 0.847759065 = 27776 * 2^-15
|
||||
* 0.613125930 = 20096 * 2^-15
|
||||
*
|
||||
* See jidctfst.c for further details of the IDCT algorithm. Where possible,
|
||||
* the variable names and comments here in jsimd_idct_ifast_neon() match up
|
||||
* with those in jpeg_idct_ifast().
|
||||
*/
|
||||
|
||||
#define PASS1_BITS 2
|
||||
|
||||
#define F_0_082 2688
|
||||
#define F_0_414 13568
|
||||
#define F_0_847 27776
|
||||
#define F_0_613 20096
|
||||
|
||||
|
||||
ALIGN(16) static const int16_t jsimd_idct_ifast_neon_consts[] = {
|
||||
F_0_082, F_0_414, F_0_847, F_0_613
|
||||
};
|
||||
|
||||
void jsimd_idct_ifast_neon(void *dct_table, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
IFAST_MULT_TYPE *quantptr = dct_table;
|
||||
|
||||
/* Load DCT coefficients. */
|
||||
int16x8_t row0 = vld1q_s16(coef_block + 0 * DCTSIZE);
|
||||
int16x8_t row1 = vld1q_s16(coef_block + 1 * DCTSIZE);
|
||||
int16x8_t row2 = vld1q_s16(coef_block + 2 * DCTSIZE);
|
||||
int16x8_t row3 = vld1q_s16(coef_block + 3 * DCTSIZE);
|
||||
int16x8_t row4 = vld1q_s16(coef_block + 4 * DCTSIZE);
|
||||
int16x8_t row5 = vld1q_s16(coef_block + 5 * DCTSIZE);
|
||||
int16x8_t row6 = vld1q_s16(coef_block + 6 * DCTSIZE);
|
||||
int16x8_t row7 = vld1q_s16(coef_block + 7 * DCTSIZE);
|
||||
|
||||
/* Load quantization table values for DC coefficients. */
|
||||
int16x8_t quant_row0 = vld1q_s16(quantptr + 0 * DCTSIZE);
|
||||
/* Dequantize DC coefficients. */
|
||||
row0 = vmulq_s16(row0, quant_row0);
|
||||
|
||||
/* Construct bitmap to test if all AC coefficients are 0. */
|
||||
int16x8_t bitmap = vorrq_s16(row1, row2);
|
||||
bitmap = vorrq_s16(bitmap, row3);
|
||||
bitmap = vorrq_s16(bitmap, row4);
|
||||
bitmap = vorrq_s16(bitmap, row5);
|
||||
bitmap = vorrq_s16(bitmap, row6);
|
||||
bitmap = vorrq_s16(bitmap, row7);
|
||||
|
||||
int64_t left_ac_bitmap = vgetq_lane_s64(vreinterpretq_s64_s16(bitmap), 0);
|
||||
int64_t right_ac_bitmap = vgetq_lane_s64(vreinterpretq_s64_s16(bitmap), 1);
|
||||
|
||||
/* Load IDCT conversion constants. */
|
||||
const int16x4_t consts = vld1_s16(jsimd_idct_ifast_neon_consts);
|
||||
|
||||
if (left_ac_bitmap == 0 && right_ac_bitmap == 0) {
|
||||
/* All AC coefficients are zero.
|
||||
* Compute DC values and duplicate into vectors.
|
||||
*/
|
||||
int16x8_t dcval = row0;
|
||||
row1 = dcval;
|
||||
row2 = dcval;
|
||||
row3 = dcval;
|
||||
row4 = dcval;
|
||||
row5 = dcval;
|
||||
row6 = dcval;
|
||||
row7 = dcval;
|
||||
} else if (left_ac_bitmap == 0) {
|
||||
/* AC coefficients are zero for columns 0, 1, 2, and 3.
|
||||
* Use DC values for these columns.
|
||||
*/
|
||||
int16x4_t dcval = vget_low_s16(row0);
|
||||
|
||||
/* Commence regular fast IDCT computation for columns 4, 5, 6, and 7. */
|
||||
|
||||
/* Load quantization table. */
|
||||
int16x4_t quant_row1 = vld1_s16(quantptr + 1 * DCTSIZE + 4);
|
||||
int16x4_t quant_row2 = vld1_s16(quantptr + 2 * DCTSIZE + 4);
|
||||
int16x4_t quant_row3 = vld1_s16(quantptr + 3 * DCTSIZE + 4);
|
||||
int16x4_t quant_row4 = vld1_s16(quantptr + 4 * DCTSIZE + 4);
|
||||
int16x4_t quant_row5 = vld1_s16(quantptr + 5 * DCTSIZE + 4);
|
||||
int16x4_t quant_row6 = vld1_s16(quantptr + 6 * DCTSIZE + 4);
|
||||
int16x4_t quant_row7 = vld1_s16(quantptr + 7 * DCTSIZE + 4);
|
||||
|
||||
/* Even part: dequantize DCT coefficients. */
|
||||
int16x4_t tmp0 = vget_high_s16(row0);
|
||||
int16x4_t tmp1 = vmul_s16(vget_high_s16(row2), quant_row2);
|
||||
int16x4_t tmp2 = vmul_s16(vget_high_s16(row4), quant_row4);
|
||||
int16x4_t tmp3 = vmul_s16(vget_high_s16(row6), quant_row6);
|
||||
|
||||
int16x4_t tmp10 = vadd_s16(tmp0, tmp2); /* phase 3 */
|
||||
int16x4_t tmp11 = vsub_s16(tmp0, tmp2);
|
||||
|
||||
int16x4_t tmp13 = vadd_s16(tmp1, tmp3); /* phases 5-3 */
|
||||
int16x4_t tmp1_sub_tmp3 = vsub_s16(tmp1, tmp3);
|
||||
int16x4_t tmp12 = vqdmulh_lane_s16(tmp1_sub_tmp3, consts, 1);
|
||||
tmp12 = vadd_s16(tmp12, tmp1_sub_tmp3);
|
||||
tmp12 = vsub_s16(tmp12, tmp13);
|
||||
|
||||
tmp0 = vadd_s16(tmp10, tmp13); /* phase 2 */
|
||||
tmp3 = vsub_s16(tmp10, tmp13);
|
||||
tmp1 = vadd_s16(tmp11, tmp12);
|
||||
tmp2 = vsub_s16(tmp11, tmp12);
|
||||
|
||||
/* Odd part: dequantize DCT coefficients. */
|
||||
int16x4_t tmp4 = vmul_s16(vget_high_s16(row1), quant_row1);
|
||||
int16x4_t tmp5 = vmul_s16(vget_high_s16(row3), quant_row3);
|
||||
int16x4_t tmp6 = vmul_s16(vget_high_s16(row5), quant_row5);
|
||||
int16x4_t tmp7 = vmul_s16(vget_high_s16(row7), quant_row7);
|
||||
|
||||
int16x4_t z13 = vadd_s16(tmp6, tmp5); /* phase 6 */
|
||||
int16x4_t neg_z10 = vsub_s16(tmp5, tmp6);
|
||||
int16x4_t z11 = vadd_s16(tmp4, tmp7);
|
||||
int16x4_t z12 = vsub_s16(tmp4, tmp7);
|
||||
|
||||
tmp7 = vadd_s16(z11, z13); /* phase 5 */
|
||||
int16x4_t z11_sub_z13 = vsub_s16(z11, z13);
|
||||
tmp11 = vqdmulh_lane_s16(z11_sub_z13, consts, 1);
|
||||
tmp11 = vadd_s16(tmp11, z11_sub_z13);
|
||||
|
||||
int16x4_t z10_add_z12 = vsub_s16(z12, neg_z10);
|
||||
int16x4_t z5 = vqdmulh_lane_s16(z10_add_z12, consts, 2);
|
||||
z5 = vadd_s16(z5, z10_add_z12);
|
||||
tmp10 = vqdmulh_lane_s16(z12, consts, 0);
|
||||
tmp10 = vadd_s16(tmp10, z12);
|
||||
tmp10 = vsub_s16(tmp10, z5);
|
||||
tmp12 = vqdmulh_lane_s16(neg_z10, consts, 3);
|
||||
tmp12 = vadd_s16(tmp12, vadd_s16(neg_z10, neg_z10));
|
||||
tmp12 = vadd_s16(tmp12, z5);
|
||||
|
||||
tmp6 = vsub_s16(tmp12, tmp7); /* phase 2 */
|
||||
tmp5 = vsub_s16(tmp11, tmp6);
|
||||
tmp4 = vadd_s16(tmp10, tmp5);
|
||||
|
||||
row0 = vcombine_s16(dcval, vadd_s16(tmp0, tmp7));
|
||||
row7 = vcombine_s16(dcval, vsub_s16(tmp0, tmp7));
|
||||
row1 = vcombine_s16(dcval, vadd_s16(tmp1, tmp6));
|
||||
row6 = vcombine_s16(dcval, vsub_s16(tmp1, tmp6));
|
||||
row2 = vcombine_s16(dcval, vadd_s16(tmp2, tmp5));
|
||||
row5 = vcombine_s16(dcval, vsub_s16(tmp2, tmp5));
|
||||
row4 = vcombine_s16(dcval, vadd_s16(tmp3, tmp4));
|
||||
row3 = vcombine_s16(dcval, vsub_s16(tmp3, tmp4));
|
||||
} else if (right_ac_bitmap == 0) {
|
||||
/* AC coefficients are zero for columns 4, 5, 6, and 7.
|
||||
* Use DC values for these columns.
|
||||
*/
|
||||
int16x4_t dcval = vget_high_s16(row0);
|
||||
|
||||
/* Commence regular fast IDCT computation for columns 0, 1, 2, and 3. */
|
||||
|
||||
/* Load quantization table. */
|
||||
int16x4_t quant_row1 = vld1_s16(quantptr + 1 * DCTSIZE);
|
||||
int16x4_t quant_row2 = vld1_s16(quantptr + 2 * DCTSIZE);
|
||||
int16x4_t quant_row3 = vld1_s16(quantptr + 3 * DCTSIZE);
|
||||
int16x4_t quant_row4 = vld1_s16(quantptr + 4 * DCTSIZE);
|
||||
int16x4_t quant_row5 = vld1_s16(quantptr + 5 * DCTSIZE);
|
||||
int16x4_t quant_row6 = vld1_s16(quantptr + 6 * DCTSIZE);
|
||||
int16x4_t quant_row7 = vld1_s16(quantptr + 7 * DCTSIZE);
|
||||
|
||||
/* Even part: dequantize DCT coefficients. */
|
||||
int16x4_t tmp0 = vget_low_s16(row0);
|
||||
int16x4_t tmp1 = vmul_s16(vget_low_s16(row2), quant_row2);
|
||||
int16x4_t tmp2 = vmul_s16(vget_low_s16(row4), quant_row4);
|
||||
int16x4_t tmp3 = vmul_s16(vget_low_s16(row6), quant_row6);
|
||||
|
||||
int16x4_t tmp10 = vadd_s16(tmp0, tmp2); /* phase 3 */
|
||||
int16x4_t tmp11 = vsub_s16(tmp0, tmp2);
|
||||
|
||||
int16x4_t tmp13 = vadd_s16(tmp1, tmp3); /* phases 5-3 */
|
||||
int16x4_t tmp1_sub_tmp3 = vsub_s16(tmp1, tmp3);
|
||||
int16x4_t tmp12 = vqdmulh_lane_s16(tmp1_sub_tmp3, consts, 1);
|
||||
tmp12 = vadd_s16(tmp12, tmp1_sub_tmp3);
|
||||
tmp12 = vsub_s16(tmp12, tmp13);
|
||||
|
||||
tmp0 = vadd_s16(tmp10, tmp13); /* phase 2 */
|
||||
tmp3 = vsub_s16(tmp10, tmp13);
|
||||
tmp1 = vadd_s16(tmp11, tmp12);
|
||||
tmp2 = vsub_s16(tmp11, tmp12);
|
||||
|
||||
/* Odd part: dequantize DCT coefficients. */
|
||||
int16x4_t tmp4 = vmul_s16(vget_low_s16(row1), quant_row1);
|
||||
int16x4_t tmp5 = vmul_s16(vget_low_s16(row3), quant_row3);
|
||||
int16x4_t tmp6 = vmul_s16(vget_low_s16(row5), quant_row5);
|
||||
int16x4_t tmp7 = vmul_s16(vget_low_s16(row7), quant_row7);
|
||||
|
||||
int16x4_t z13 = vadd_s16(tmp6, tmp5); /* phase 6 */
|
||||
int16x4_t neg_z10 = vsub_s16(tmp5, tmp6);
|
||||
int16x4_t z11 = vadd_s16(tmp4, tmp7);
|
||||
int16x4_t z12 = vsub_s16(tmp4, tmp7);
|
||||
|
||||
tmp7 = vadd_s16(z11, z13); /* phase 5 */
|
||||
int16x4_t z11_sub_z13 = vsub_s16(z11, z13);
|
||||
tmp11 = vqdmulh_lane_s16(z11_sub_z13, consts, 1);
|
||||
tmp11 = vadd_s16(tmp11, z11_sub_z13);
|
||||
|
||||
int16x4_t z10_add_z12 = vsub_s16(z12, neg_z10);
|
||||
int16x4_t z5 = vqdmulh_lane_s16(z10_add_z12, consts, 2);
|
||||
z5 = vadd_s16(z5, z10_add_z12);
|
||||
tmp10 = vqdmulh_lane_s16(z12, consts, 0);
|
||||
tmp10 = vadd_s16(tmp10, z12);
|
||||
tmp10 = vsub_s16(tmp10, z5);
|
||||
tmp12 = vqdmulh_lane_s16(neg_z10, consts, 3);
|
||||
tmp12 = vadd_s16(tmp12, vadd_s16(neg_z10, neg_z10));
|
||||
tmp12 = vadd_s16(tmp12, z5);
|
||||
|
||||
tmp6 = vsub_s16(tmp12, tmp7); /* phase 2 */
|
||||
tmp5 = vsub_s16(tmp11, tmp6);
|
||||
tmp4 = vadd_s16(tmp10, tmp5);
|
||||
|
||||
row0 = vcombine_s16(vadd_s16(tmp0, tmp7), dcval);
|
||||
row7 = vcombine_s16(vsub_s16(tmp0, tmp7), dcval);
|
||||
row1 = vcombine_s16(vadd_s16(tmp1, tmp6), dcval);
|
||||
row6 = vcombine_s16(vsub_s16(tmp1, tmp6), dcval);
|
||||
row2 = vcombine_s16(vadd_s16(tmp2, tmp5), dcval);
|
||||
row5 = vcombine_s16(vsub_s16(tmp2, tmp5), dcval);
|
||||
row4 = vcombine_s16(vadd_s16(tmp3, tmp4), dcval);
|
||||
row3 = vcombine_s16(vsub_s16(tmp3, tmp4), dcval);
|
||||
} else {
|
||||
/* Some AC coefficients are non-zero; full IDCT calculation required. */
|
||||
|
||||
/* Load quantization table. */
|
||||
int16x8_t quant_row1 = vld1q_s16(quantptr + 1 * DCTSIZE);
|
||||
int16x8_t quant_row2 = vld1q_s16(quantptr + 2 * DCTSIZE);
|
||||
int16x8_t quant_row3 = vld1q_s16(quantptr + 3 * DCTSIZE);
|
||||
int16x8_t quant_row4 = vld1q_s16(quantptr + 4 * DCTSIZE);
|
||||
int16x8_t quant_row5 = vld1q_s16(quantptr + 5 * DCTSIZE);
|
||||
int16x8_t quant_row6 = vld1q_s16(quantptr + 6 * DCTSIZE);
|
||||
int16x8_t quant_row7 = vld1q_s16(quantptr + 7 * DCTSIZE);
|
||||
|
||||
/* Even part: dequantize DCT coefficients. */
|
||||
int16x8_t tmp0 = row0;
|
||||
int16x8_t tmp1 = vmulq_s16(row2, quant_row2);
|
||||
int16x8_t tmp2 = vmulq_s16(row4, quant_row4);
|
||||
int16x8_t tmp3 = vmulq_s16(row6, quant_row6);
|
||||
|
||||
int16x8_t tmp10 = vaddq_s16(tmp0, tmp2); /* phase 3 */
|
||||
int16x8_t tmp11 = vsubq_s16(tmp0, tmp2);
|
||||
|
||||
int16x8_t tmp13 = vaddq_s16(tmp1, tmp3); /* phases 5-3 */
|
||||
int16x8_t tmp1_sub_tmp3 = vsubq_s16(tmp1, tmp3);
|
||||
int16x8_t tmp12 = vqdmulhq_lane_s16(tmp1_sub_tmp3, consts, 1);
|
||||
tmp12 = vaddq_s16(tmp12, tmp1_sub_tmp3);
|
||||
tmp12 = vsubq_s16(tmp12, tmp13);
|
||||
|
||||
tmp0 = vaddq_s16(tmp10, tmp13); /* phase 2 */
|
||||
tmp3 = vsubq_s16(tmp10, tmp13);
|
||||
tmp1 = vaddq_s16(tmp11, tmp12);
|
||||
tmp2 = vsubq_s16(tmp11, tmp12);
|
||||
|
||||
/* Odd part: dequantize DCT coefficients. */
|
||||
int16x8_t tmp4 = vmulq_s16(row1, quant_row1);
|
||||
int16x8_t tmp5 = vmulq_s16(row3, quant_row3);
|
||||
int16x8_t tmp6 = vmulq_s16(row5, quant_row5);
|
||||
int16x8_t tmp7 = vmulq_s16(row7, quant_row7);
|
||||
|
||||
int16x8_t z13 = vaddq_s16(tmp6, tmp5); /* phase 6 */
|
||||
int16x8_t neg_z10 = vsubq_s16(tmp5, tmp6);
|
||||
int16x8_t z11 = vaddq_s16(tmp4, tmp7);
|
||||
int16x8_t z12 = vsubq_s16(tmp4, tmp7);
|
||||
|
||||
tmp7 = vaddq_s16(z11, z13); /* phase 5 */
|
||||
int16x8_t z11_sub_z13 = vsubq_s16(z11, z13);
|
||||
tmp11 = vqdmulhq_lane_s16(z11_sub_z13, consts, 1);
|
||||
tmp11 = vaddq_s16(tmp11, z11_sub_z13);
|
||||
|
||||
int16x8_t z10_add_z12 = vsubq_s16(z12, neg_z10);
|
||||
int16x8_t z5 = vqdmulhq_lane_s16(z10_add_z12, consts, 2);
|
||||
z5 = vaddq_s16(z5, z10_add_z12);
|
||||
tmp10 = vqdmulhq_lane_s16(z12, consts, 0);
|
||||
tmp10 = vaddq_s16(tmp10, z12);
|
||||
tmp10 = vsubq_s16(tmp10, z5);
|
||||
tmp12 = vqdmulhq_lane_s16(neg_z10, consts, 3);
|
||||
tmp12 = vaddq_s16(tmp12, vaddq_s16(neg_z10, neg_z10));
|
||||
tmp12 = vaddq_s16(tmp12, z5);
|
||||
|
||||
tmp6 = vsubq_s16(tmp12, tmp7); /* phase 2 */
|
||||
tmp5 = vsubq_s16(tmp11, tmp6);
|
||||
tmp4 = vaddq_s16(tmp10, tmp5);
|
||||
|
||||
row0 = vaddq_s16(tmp0, tmp7);
|
||||
row7 = vsubq_s16(tmp0, tmp7);
|
||||
row1 = vaddq_s16(tmp1, tmp6);
|
||||
row6 = vsubq_s16(tmp1, tmp6);
|
||||
row2 = vaddq_s16(tmp2, tmp5);
|
||||
row5 = vsubq_s16(tmp2, tmp5);
|
||||
row4 = vaddq_s16(tmp3, tmp4);
|
||||
row3 = vsubq_s16(tmp3, tmp4);
|
||||
}
|
||||
|
||||
/* Transpose rows to work on columns in pass 2. */
|
||||
int16x8x2_t rows_01 = vtrnq_s16(row0, row1);
|
||||
int16x8x2_t rows_23 = vtrnq_s16(row2, row3);
|
||||
int16x8x2_t rows_45 = vtrnq_s16(row4, row5);
|
||||
int16x8x2_t rows_67 = vtrnq_s16(row6, row7);
|
||||
|
||||
int32x4x2_t rows_0145_l = vtrnq_s32(vreinterpretq_s32_s16(rows_01.val[0]),
|
||||
vreinterpretq_s32_s16(rows_45.val[0]));
|
||||
int32x4x2_t rows_0145_h = vtrnq_s32(vreinterpretq_s32_s16(rows_01.val[1]),
|
||||
vreinterpretq_s32_s16(rows_45.val[1]));
|
||||
int32x4x2_t rows_2367_l = vtrnq_s32(vreinterpretq_s32_s16(rows_23.val[0]),
|
||||
vreinterpretq_s32_s16(rows_67.val[0]));
|
||||
int32x4x2_t rows_2367_h = vtrnq_s32(vreinterpretq_s32_s16(rows_23.val[1]),
|
||||
vreinterpretq_s32_s16(rows_67.val[1]));
|
||||
|
||||
int32x4x2_t cols_04 = vzipq_s32(rows_0145_l.val[0], rows_2367_l.val[0]);
|
||||
int32x4x2_t cols_15 = vzipq_s32(rows_0145_h.val[0], rows_2367_h.val[0]);
|
||||
int32x4x2_t cols_26 = vzipq_s32(rows_0145_l.val[1], rows_2367_l.val[1]);
|
||||
int32x4x2_t cols_37 = vzipq_s32(rows_0145_h.val[1], rows_2367_h.val[1]);
|
||||
|
||||
int16x8_t col0 = vreinterpretq_s16_s32(cols_04.val[0]);
|
||||
int16x8_t col1 = vreinterpretq_s16_s32(cols_15.val[0]);
|
||||
int16x8_t col2 = vreinterpretq_s16_s32(cols_26.val[0]);
|
||||
int16x8_t col3 = vreinterpretq_s16_s32(cols_37.val[0]);
|
||||
int16x8_t col4 = vreinterpretq_s16_s32(cols_04.val[1]);
|
||||
int16x8_t col5 = vreinterpretq_s16_s32(cols_15.val[1]);
|
||||
int16x8_t col6 = vreinterpretq_s16_s32(cols_26.val[1]);
|
||||
int16x8_t col7 = vreinterpretq_s16_s32(cols_37.val[1]);
|
||||
|
||||
/* 1-D IDCT, pass 2 */
|
||||
|
||||
/* Even part */
|
||||
int16x8_t tmp10 = vaddq_s16(col0, col4);
|
||||
int16x8_t tmp11 = vsubq_s16(col0, col4);
|
||||
|
||||
int16x8_t tmp13 = vaddq_s16(col2, col6);
|
||||
int16x8_t col2_sub_col6 = vsubq_s16(col2, col6);
|
||||
int16x8_t tmp12 = vqdmulhq_lane_s16(col2_sub_col6, consts, 1);
|
||||
tmp12 = vaddq_s16(tmp12, col2_sub_col6);
|
||||
tmp12 = vsubq_s16(tmp12, tmp13);
|
||||
|
||||
int16x8_t tmp0 = vaddq_s16(tmp10, tmp13);
|
||||
int16x8_t tmp3 = vsubq_s16(tmp10, tmp13);
|
||||
int16x8_t tmp1 = vaddq_s16(tmp11, tmp12);
|
||||
int16x8_t tmp2 = vsubq_s16(tmp11, tmp12);
|
||||
|
||||
/* Odd part */
|
||||
int16x8_t z13 = vaddq_s16(col5, col3);
|
||||
int16x8_t neg_z10 = vsubq_s16(col3, col5);
|
||||
int16x8_t z11 = vaddq_s16(col1, col7);
|
||||
int16x8_t z12 = vsubq_s16(col1, col7);
|
||||
|
||||
int16x8_t tmp7 = vaddq_s16(z11, z13); /* phase 5 */
|
||||
int16x8_t z11_sub_z13 = vsubq_s16(z11, z13);
|
||||
tmp11 = vqdmulhq_lane_s16(z11_sub_z13, consts, 1);
|
||||
tmp11 = vaddq_s16(tmp11, z11_sub_z13);
|
||||
|
||||
int16x8_t z10_add_z12 = vsubq_s16(z12, neg_z10);
|
||||
int16x8_t z5 = vqdmulhq_lane_s16(z10_add_z12, consts, 2);
|
||||
z5 = vaddq_s16(z5, z10_add_z12);
|
||||
tmp10 = vqdmulhq_lane_s16(z12, consts, 0);
|
||||
tmp10 = vaddq_s16(tmp10, z12);
|
||||
tmp10 = vsubq_s16(tmp10, z5);
|
||||
tmp12 = vqdmulhq_lane_s16(neg_z10, consts, 3);
|
||||
tmp12 = vaddq_s16(tmp12, vaddq_s16(neg_z10, neg_z10));
|
||||
tmp12 = vaddq_s16(tmp12, z5);
|
||||
|
||||
int16x8_t tmp6 = vsubq_s16(tmp12, tmp7); /* phase 2 */
|
||||
int16x8_t tmp5 = vsubq_s16(tmp11, tmp6);
|
||||
int16x8_t tmp4 = vaddq_s16(tmp10, tmp5);
|
||||
|
||||
col0 = vaddq_s16(tmp0, tmp7);
|
||||
col7 = vsubq_s16(tmp0, tmp7);
|
||||
col1 = vaddq_s16(tmp1, tmp6);
|
||||
col6 = vsubq_s16(tmp1, tmp6);
|
||||
col2 = vaddq_s16(tmp2, tmp5);
|
||||
col5 = vsubq_s16(tmp2, tmp5);
|
||||
col4 = vaddq_s16(tmp3, tmp4);
|
||||
col3 = vsubq_s16(tmp3, tmp4);
|
||||
|
||||
/* Scale down by a factor of 8, narrowing to 8-bit. */
|
||||
int8x16_t cols_01_s8 = vcombine_s8(vqshrn_n_s16(col0, PASS1_BITS + 3),
|
||||
vqshrn_n_s16(col1, PASS1_BITS + 3));
|
||||
int8x16_t cols_45_s8 = vcombine_s8(vqshrn_n_s16(col4, PASS1_BITS + 3),
|
||||
vqshrn_n_s16(col5, PASS1_BITS + 3));
|
||||
int8x16_t cols_23_s8 = vcombine_s8(vqshrn_n_s16(col2, PASS1_BITS + 3),
|
||||
vqshrn_n_s16(col3, PASS1_BITS + 3));
|
||||
int8x16_t cols_67_s8 = vcombine_s8(vqshrn_n_s16(col6, PASS1_BITS + 3),
|
||||
vqshrn_n_s16(col7, PASS1_BITS + 3));
|
||||
/* Clamp to range [0-255]. */
|
||||
uint8x16_t cols_01 =
|
||||
vreinterpretq_u8_s8
|
||||
(vaddq_s8(cols_01_s8, vreinterpretq_s8_u8(vdupq_n_u8(CENTERJSAMPLE))));
|
||||
uint8x16_t cols_45 =
|
||||
vreinterpretq_u8_s8
|
||||
(vaddq_s8(cols_45_s8, vreinterpretq_s8_u8(vdupq_n_u8(CENTERJSAMPLE))));
|
||||
uint8x16_t cols_23 =
|
||||
vreinterpretq_u8_s8
|
||||
(vaddq_s8(cols_23_s8, vreinterpretq_s8_u8(vdupq_n_u8(CENTERJSAMPLE))));
|
||||
uint8x16_t cols_67 =
|
||||
vreinterpretq_u8_s8
|
||||
(vaddq_s8(cols_67_s8, vreinterpretq_s8_u8(vdupq_n_u8(CENTERJSAMPLE))));
|
||||
|
||||
/* Transpose block to prepare for store. */
|
||||
uint32x4x2_t cols_0415 = vzipq_u32(vreinterpretq_u32_u8(cols_01),
|
||||
vreinterpretq_u32_u8(cols_45));
|
||||
uint32x4x2_t cols_2637 = vzipq_u32(vreinterpretq_u32_u8(cols_23),
|
||||
vreinterpretq_u32_u8(cols_67));
|
||||
|
||||
uint8x16x2_t cols_0145 = vtrnq_u8(vreinterpretq_u8_u32(cols_0415.val[0]),
|
||||
vreinterpretq_u8_u32(cols_0415.val[1]));
|
||||
uint8x16x2_t cols_2367 = vtrnq_u8(vreinterpretq_u8_u32(cols_2637.val[0]),
|
||||
vreinterpretq_u8_u32(cols_2637.val[1]));
|
||||
uint16x8x2_t rows_0426 = vtrnq_u16(vreinterpretq_u16_u8(cols_0145.val[0]),
|
||||
vreinterpretq_u16_u8(cols_2367.val[0]));
|
||||
uint16x8x2_t rows_1537 = vtrnq_u16(vreinterpretq_u16_u8(cols_0145.val[1]),
|
||||
vreinterpretq_u16_u8(cols_2367.val[1]));
|
||||
|
||||
uint8x16_t rows_04 = vreinterpretq_u8_u16(rows_0426.val[0]);
|
||||
uint8x16_t rows_15 = vreinterpretq_u8_u16(rows_1537.val[0]);
|
||||
uint8x16_t rows_26 = vreinterpretq_u8_u16(rows_0426.val[1]);
|
||||
uint8x16_t rows_37 = vreinterpretq_u8_u16(rows_1537.val[1]);
|
||||
|
||||
JSAMPROW outptr0 = output_buf[0] + output_col;
|
||||
JSAMPROW outptr1 = output_buf[1] + output_col;
|
||||
JSAMPROW outptr2 = output_buf[2] + output_col;
|
||||
JSAMPROW outptr3 = output_buf[3] + output_col;
|
||||
JSAMPROW outptr4 = output_buf[4] + output_col;
|
||||
JSAMPROW outptr5 = output_buf[5] + output_col;
|
||||
JSAMPROW outptr6 = output_buf[6] + output_col;
|
||||
JSAMPROW outptr7 = output_buf[7] + output_col;
|
||||
|
||||
/* Store DCT block to memory. */
|
||||
vst1q_lane_u64((uint64_t *)outptr0, vreinterpretq_u64_u8(rows_04), 0);
|
||||
vst1q_lane_u64((uint64_t *)outptr1, vreinterpretq_u64_u8(rows_15), 0);
|
||||
vst1q_lane_u64((uint64_t *)outptr2, vreinterpretq_u64_u8(rows_26), 0);
|
||||
vst1q_lane_u64((uint64_t *)outptr3, vreinterpretq_u64_u8(rows_37), 0);
|
||||
vst1q_lane_u64((uint64_t *)outptr4, vreinterpretq_u64_u8(rows_04), 1);
|
||||
vst1q_lane_u64((uint64_t *)outptr5, vreinterpretq_u64_u8(rows_15), 1);
|
||||
vst1q_lane_u64((uint64_t *)outptr6, vreinterpretq_u64_u8(rows_26), 1);
|
||||
vst1q_lane_u64((uint64_t *)outptr7, vreinterpretq_u64_u8(rows_37), 1);
|
||||
}
|
||||
+802
@@ -0,0 +1,802 @@
|
||||
/*
|
||||
* jidctint-neon.c - accurate integer IDCT (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2020, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jconfigint.h"
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
#include "neon-compat.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
|
||||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 2
|
||||
|
||||
#define DESCALE_P1 (CONST_BITS - PASS1_BITS)
|
||||
#define DESCALE_P2 (CONST_BITS + PASS1_BITS + 3)
|
||||
|
||||
/* The computation of the inverse DCT requires the use of constants known at
|
||||
* compile time. Scaled integer constants are used to avoid floating-point
|
||||
* arithmetic:
|
||||
* 0.298631336 = 2446 * 2^-13
|
||||
* 0.390180644 = 3196 * 2^-13
|
||||
* 0.541196100 = 4433 * 2^-13
|
||||
* 0.765366865 = 6270 * 2^-13
|
||||
* 0.899976223 = 7373 * 2^-13
|
||||
* 1.175875602 = 9633 * 2^-13
|
||||
* 1.501321110 = 12299 * 2^-13
|
||||
* 1.847759065 = 15137 * 2^-13
|
||||
* 1.961570560 = 16069 * 2^-13
|
||||
* 2.053119869 = 16819 * 2^-13
|
||||
* 2.562915447 = 20995 * 2^-13
|
||||
* 3.072711026 = 25172 * 2^-13
|
||||
*/
|
||||
|
||||
#define F_0_298 2446
|
||||
#define F_0_390 3196
|
||||
#define F_0_541 4433
|
||||
#define F_0_765 6270
|
||||
#define F_0_899 7373
|
||||
#define F_1_175 9633
|
||||
#define F_1_501 12299
|
||||
#define F_1_847 15137
|
||||
#define F_1_961 16069
|
||||
#define F_2_053 16819
|
||||
#define F_2_562 20995
|
||||
#define F_3_072 25172
|
||||
|
||||
#define F_1_175_MINUS_1_961 (F_1_175 - F_1_961)
|
||||
#define F_1_175_MINUS_0_390 (F_1_175 - F_0_390)
|
||||
#define F_0_541_MINUS_1_847 (F_0_541 - F_1_847)
|
||||
#define F_3_072_MINUS_2_562 (F_3_072 - F_2_562)
|
||||
#define F_0_298_MINUS_0_899 (F_0_298 - F_0_899)
|
||||
#define F_1_501_MINUS_0_899 (F_1_501 - F_0_899)
|
||||
#define F_2_053_MINUS_2_562 (F_2_053 - F_2_562)
|
||||
#define F_0_541_PLUS_0_765 (F_0_541 + F_0_765)
|
||||
|
||||
|
||||
ALIGN(16) static const int16_t jsimd_idct_islow_neon_consts[] = {
|
||||
F_0_899, F_0_541,
|
||||
F_2_562, F_0_298_MINUS_0_899,
|
||||
F_1_501_MINUS_0_899, F_2_053_MINUS_2_562,
|
||||
F_0_541_PLUS_0_765, F_1_175,
|
||||
F_1_175_MINUS_0_390, F_0_541_MINUS_1_847,
|
||||
F_3_072_MINUS_2_562, F_1_175_MINUS_1_961,
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
|
||||
/* Forward declaration of regular and sparse IDCT helper functions */
|
||||
|
||||
static INLINE void jsimd_idct_islow_pass1_regular(int16x4_t row0,
|
||||
int16x4_t row1,
|
||||
int16x4_t row2,
|
||||
int16x4_t row3,
|
||||
int16x4_t row4,
|
||||
int16x4_t row5,
|
||||
int16x4_t row6,
|
||||
int16x4_t row7,
|
||||
int16x4_t quant_row0,
|
||||
int16x4_t quant_row1,
|
||||
int16x4_t quant_row2,
|
||||
int16x4_t quant_row3,
|
||||
int16x4_t quant_row4,
|
||||
int16x4_t quant_row5,
|
||||
int16x4_t quant_row6,
|
||||
int16x4_t quant_row7,
|
||||
int16_t *workspace_1,
|
||||
int16_t *workspace_2);
|
||||
|
||||
static INLINE void jsimd_idct_islow_pass1_sparse(int16x4_t row0,
|
||||
int16x4_t row1,
|
||||
int16x4_t row2,
|
||||
int16x4_t row3,
|
||||
int16x4_t quant_row0,
|
||||
int16x4_t quant_row1,
|
||||
int16x4_t quant_row2,
|
||||
int16x4_t quant_row3,
|
||||
int16_t *workspace_1,
|
||||
int16_t *workspace_2);
|
||||
|
||||
static INLINE void jsimd_idct_islow_pass2_regular(int16_t *workspace,
|
||||
JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col,
|
||||
unsigned buf_offset);
|
||||
|
||||
static INLINE void jsimd_idct_islow_pass2_sparse(int16_t *workspace,
|
||||
JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col,
|
||||
unsigned buf_offset);
|
||||
|
||||
|
||||
/* Perform dequantization and inverse DCT on one block of coefficients. For
|
||||
* reference, the C implementation (jpeg_idct_slow()) can be found in
|
||||
* jidctint.c.
|
||||
*
|
||||
* Optimization techniques used for fast data access:
|
||||
*
|
||||
* In each pass, the inverse DCT is computed for the left and right 4x8 halves
|
||||
* of the DCT block. This avoids spilling due to register pressure, and the
|
||||
* increased granularity allows for an optimized calculation depending on the
|
||||
* values of the DCT coefficients. Between passes, intermediate data is stored
|
||||
* in 4x8 workspace buffers.
|
||||
*
|
||||
* Transposing the 8x8 DCT block after each pass can be achieved by transposing
|
||||
* each of the four 4x4 quadrants and swapping quadrants 1 and 2 (refer to the
|
||||
* diagram below.) Swapping quadrants is cheap, since the second pass can just
|
||||
* swap the workspace buffer pointers.
|
||||
*
|
||||
* +-------+-------+ +-------+-------+
|
||||
* | | | | | |
|
||||
* | 0 | 1 | | 0 | 2 |
|
||||
* | | | transpose | | |
|
||||
* +-------+-------+ ------> +-------+-------+
|
||||
* | | | | | |
|
||||
* | 2 | 3 | | 1 | 3 |
|
||||
* | | | | | |
|
||||
* +-------+-------+ +-------+-------+
|
||||
*
|
||||
* Optimization techniques used to accelerate the inverse DCT calculation:
|
||||
*
|
||||
* In a DCT coefficient block, the coefficients are increasingly likely to be 0
|
||||
* as you move diagonally from top left to bottom right. If whole rows of
|
||||
* coefficients are 0, then the inverse DCT calculation can be simplified. On
|
||||
* the first pass of the inverse DCT, we test for three special cases before
|
||||
* defaulting to a full "regular" inverse DCT:
|
||||
*
|
||||
* 1) Coefficients in rows 4-7 are all zero. In this case, we perform a
|
||||
* "sparse" simplified inverse DCT on rows 0-3.
|
||||
* 2) AC coefficients (rows 1-7) are all zero. In this case, the inverse DCT
|
||||
* result is equal to the dequantized DC coefficients.
|
||||
* 3) AC and DC coefficients are all zero. In this case, the inverse DCT
|
||||
* result is all zero. For the left 4x8 half, this is handled identically
|
||||
* to Case 2 above. For the right 4x8 half, we do no work and signal that
|
||||
* the "sparse" algorithm is required for the second pass.
|
||||
*
|
||||
* In the second pass, only a single special case is tested: whether the AC and
|
||||
* DC coefficients were all zero in the right 4x8 block during the first pass
|
||||
* (refer to Case 3 above.) If this is the case, then a "sparse" variant of
|
||||
* the second pass is performed for both the left and right halves of the DCT
|
||||
* block. (The transposition after the first pass means that the right 4x8
|
||||
* block during the first pass becomes rows 4-7 during the second pass.)
|
||||
*/
|
||||
|
||||
void jsimd_idct_islow_neon(void *dct_table, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
ISLOW_MULT_TYPE *quantptr = dct_table;
|
||||
|
||||
int16_t workspace_l[8 * DCTSIZE / 2];
|
||||
int16_t workspace_r[8 * DCTSIZE / 2];
|
||||
|
||||
/* Compute IDCT first pass on left 4x8 coefficient block. */
|
||||
|
||||
/* Load DCT coefficients in left 4x8 block. */
|
||||
int16x4_t row0 = vld1_s16(coef_block + 0 * DCTSIZE);
|
||||
int16x4_t row1 = vld1_s16(coef_block + 1 * DCTSIZE);
|
||||
int16x4_t row2 = vld1_s16(coef_block + 2 * DCTSIZE);
|
||||
int16x4_t row3 = vld1_s16(coef_block + 3 * DCTSIZE);
|
||||
int16x4_t row4 = vld1_s16(coef_block + 4 * DCTSIZE);
|
||||
int16x4_t row5 = vld1_s16(coef_block + 5 * DCTSIZE);
|
||||
int16x4_t row6 = vld1_s16(coef_block + 6 * DCTSIZE);
|
||||
int16x4_t row7 = vld1_s16(coef_block + 7 * DCTSIZE);
|
||||
|
||||
/* Load quantization table for left 4x8 block. */
|
||||
int16x4_t quant_row0 = vld1_s16(quantptr + 0 * DCTSIZE);
|
||||
int16x4_t quant_row1 = vld1_s16(quantptr + 1 * DCTSIZE);
|
||||
int16x4_t quant_row2 = vld1_s16(quantptr + 2 * DCTSIZE);
|
||||
int16x4_t quant_row3 = vld1_s16(quantptr + 3 * DCTSIZE);
|
||||
int16x4_t quant_row4 = vld1_s16(quantptr + 4 * DCTSIZE);
|
||||
int16x4_t quant_row5 = vld1_s16(quantptr + 5 * DCTSIZE);
|
||||
int16x4_t quant_row6 = vld1_s16(quantptr + 6 * DCTSIZE);
|
||||
int16x4_t quant_row7 = vld1_s16(quantptr + 7 * DCTSIZE);
|
||||
|
||||
/* Construct bitmap to test if DCT coefficients in left 4x8 block are 0. */
|
||||
int16x4_t bitmap = vorr_s16(row7, row6);
|
||||
bitmap = vorr_s16(bitmap, row5);
|
||||
bitmap = vorr_s16(bitmap, row4);
|
||||
int64_t bitmap_rows_4567 = vget_lane_s64(vreinterpret_s64_s16(bitmap), 0);
|
||||
|
||||
if (bitmap_rows_4567 == 0) {
|
||||
bitmap = vorr_s16(bitmap, row3);
|
||||
bitmap = vorr_s16(bitmap, row2);
|
||||
bitmap = vorr_s16(bitmap, row1);
|
||||
int64_t left_ac_bitmap = vget_lane_s64(vreinterpret_s64_s16(bitmap), 0);
|
||||
|
||||
if (left_ac_bitmap == 0) {
|
||||
int16x4_t dcval = vshl_n_s16(vmul_s16(row0, quant_row0), PASS1_BITS);
|
||||
int16x4x4_t quadrant = { { dcval, dcval, dcval, dcval } };
|
||||
/* Store 4x4 blocks to workspace, transposing in the process. */
|
||||
vst4_s16(workspace_l, quadrant);
|
||||
vst4_s16(workspace_r, quadrant);
|
||||
} else {
|
||||
jsimd_idct_islow_pass1_sparse(row0, row1, row2, row3, quant_row0,
|
||||
quant_row1, quant_row2, quant_row3,
|
||||
workspace_l, workspace_r);
|
||||
}
|
||||
} else {
|
||||
jsimd_idct_islow_pass1_regular(row0, row1, row2, row3, row4, row5,
|
||||
row6, row7, quant_row0, quant_row1,
|
||||
quant_row2, quant_row3, quant_row4,
|
||||
quant_row5, quant_row6, quant_row7,
|
||||
workspace_l, workspace_r);
|
||||
}
|
||||
|
||||
/* Compute IDCT first pass on right 4x8 coefficient block. */
|
||||
|
||||
/* Load DCT coefficients in right 4x8 block. */
|
||||
row0 = vld1_s16(coef_block + 0 * DCTSIZE + 4);
|
||||
row1 = vld1_s16(coef_block + 1 * DCTSIZE + 4);
|
||||
row2 = vld1_s16(coef_block + 2 * DCTSIZE + 4);
|
||||
row3 = vld1_s16(coef_block + 3 * DCTSIZE + 4);
|
||||
row4 = vld1_s16(coef_block + 4 * DCTSIZE + 4);
|
||||
row5 = vld1_s16(coef_block + 5 * DCTSIZE + 4);
|
||||
row6 = vld1_s16(coef_block + 6 * DCTSIZE + 4);
|
||||
row7 = vld1_s16(coef_block + 7 * DCTSIZE + 4);
|
||||
|
||||
/* Load quantization table for right 4x8 block. */
|
||||
quant_row0 = vld1_s16(quantptr + 0 * DCTSIZE + 4);
|
||||
quant_row1 = vld1_s16(quantptr + 1 * DCTSIZE + 4);
|
||||
quant_row2 = vld1_s16(quantptr + 2 * DCTSIZE + 4);
|
||||
quant_row3 = vld1_s16(quantptr + 3 * DCTSIZE + 4);
|
||||
quant_row4 = vld1_s16(quantptr + 4 * DCTSIZE + 4);
|
||||
quant_row5 = vld1_s16(quantptr + 5 * DCTSIZE + 4);
|
||||
quant_row6 = vld1_s16(quantptr + 6 * DCTSIZE + 4);
|
||||
quant_row7 = vld1_s16(quantptr + 7 * DCTSIZE + 4);
|
||||
|
||||
/* Construct bitmap to test if DCT coefficients in right 4x8 block are 0. */
|
||||
bitmap = vorr_s16(row7, row6);
|
||||
bitmap = vorr_s16(bitmap, row5);
|
||||
bitmap = vorr_s16(bitmap, row4);
|
||||
bitmap_rows_4567 = vget_lane_s64(vreinterpret_s64_s16(bitmap), 0);
|
||||
bitmap = vorr_s16(bitmap, row3);
|
||||
bitmap = vorr_s16(bitmap, row2);
|
||||
bitmap = vorr_s16(bitmap, row1);
|
||||
int64_t right_ac_bitmap = vget_lane_s64(vreinterpret_s64_s16(bitmap), 0);
|
||||
|
||||
/* If this remains non-zero, a "regular" second pass will be performed. */
|
||||
int64_t right_ac_dc_bitmap = 1;
|
||||
|
||||
if (right_ac_bitmap == 0) {
|
||||
bitmap = vorr_s16(bitmap, row0);
|
||||
right_ac_dc_bitmap = vget_lane_s64(vreinterpret_s64_s16(bitmap), 0);
|
||||
|
||||
if (right_ac_dc_bitmap != 0) {
|
||||
int16x4_t dcval = vshl_n_s16(vmul_s16(row0, quant_row0), PASS1_BITS);
|
||||
int16x4x4_t quadrant = { { dcval, dcval, dcval, dcval } };
|
||||
/* Store 4x4 blocks to workspace, transposing in the process. */
|
||||
vst4_s16(workspace_l + 4 * DCTSIZE / 2, quadrant);
|
||||
vst4_s16(workspace_r + 4 * DCTSIZE / 2, quadrant);
|
||||
}
|
||||
} else {
|
||||
if (bitmap_rows_4567 == 0) {
|
||||
jsimd_idct_islow_pass1_sparse(row0, row1, row2, row3, quant_row0,
|
||||
quant_row1, quant_row2, quant_row3,
|
||||
workspace_l + 4 * DCTSIZE / 2,
|
||||
workspace_r + 4 * DCTSIZE / 2);
|
||||
} else {
|
||||
jsimd_idct_islow_pass1_regular(row0, row1, row2, row3, row4, row5,
|
||||
row6, row7, quant_row0, quant_row1,
|
||||
quant_row2, quant_row3, quant_row4,
|
||||
quant_row5, quant_row6, quant_row7,
|
||||
workspace_l + 4 * DCTSIZE / 2,
|
||||
workspace_r + 4 * DCTSIZE / 2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Second pass: compute IDCT on rows in workspace. */
|
||||
|
||||
/* If all coefficients in right 4x8 block are 0, use "sparse" second pass. */
|
||||
if (right_ac_dc_bitmap == 0) {
|
||||
jsimd_idct_islow_pass2_sparse(workspace_l, output_buf, output_col, 0);
|
||||
jsimd_idct_islow_pass2_sparse(workspace_r, output_buf, output_col, 4);
|
||||
} else {
|
||||
jsimd_idct_islow_pass2_regular(workspace_l, output_buf, output_col, 0);
|
||||
jsimd_idct_islow_pass2_regular(workspace_r, output_buf, output_col, 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Perform dequantization and the first pass of the accurate inverse DCT on a
|
||||
* 4x8 block of coefficients. (To process the full 8x8 DCT block, this
|
||||
* function-- or some other optimized variant-- needs to be called for both the
|
||||
* left and right 4x8 blocks.)
|
||||
*
|
||||
* This "regular" version assumes that no optimization can be made to the IDCT
|
||||
* calculation, since no useful set of AC coefficients is all 0.
|
||||
*
|
||||
* The original C implementation of the accurate IDCT (jpeg_idct_slow()) can be
|
||||
* found in jidctint.c. Algorithmic changes made here are documented inline.
|
||||
*/
|
||||
|
||||
static INLINE void jsimd_idct_islow_pass1_regular(int16x4_t row0,
|
||||
int16x4_t row1,
|
||||
int16x4_t row2,
|
||||
int16x4_t row3,
|
||||
int16x4_t row4,
|
||||
int16x4_t row5,
|
||||
int16x4_t row6,
|
||||
int16x4_t row7,
|
||||
int16x4_t quant_row0,
|
||||
int16x4_t quant_row1,
|
||||
int16x4_t quant_row2,
|
||||
int16x4_t quant_row3,
|
||||
int16x4_t quant_row4,
|
||||
int16x4_t quant_row5,
|
||||
int16x4_t quant_row6,
|
||||
int16x4_t quant_row7,
|
||||
int16_t *workspace_1,
|
||||
int16_t *workspace_2)
|
||||
{
|
||||
/* Load constants for IDCT computation. */
|
||||
#ifdef HAVE_VLD1_S16_X3
|
||||
const int16x4x3_t consts = vld1_s16_x3(jsimd_idct_islow_neon_consts);
|
||||
#else
|
||||
const int16x4_t consts1 = vld1_s16(jsimd_idct_islow_neon_consts);
|
||||
const int16x4_t consts2 = vld1_s16(jsimd_idct_islow_neon_consts + 4);
|
||||
const int16x4_t consts3 = vld1_s16(jsimd_idct_islow_neon_consts + 8);
|
||||
const int16x4x3_t consts = { { consts1, consts2, consts3 } };
|
||||
#endif
|
||||
|
||||
/* Even part */
|
||||
int16x4_t z2_s16 = vmul_s16(row2, quant_row2);
|
||||
int16x4_t z3_s16 = vmul_s16(row6, quant_row6);
|
||||
|
||||
int32x4_t tmp2 = vmull_lane_s16(z2_s16, consts.val[0], 1);
|
||||
int32x4_t tmp3 = vmull_lane_s16(z2_s16, consts.val[1], 2);
|
||||
tmp2 = vmlal_lane_s16(tmp2, z3_s16, consts.val[2], 1);
|
||||
tmp3 = vmlal_lane_s16(tmp3, z3_s16, consts.val[0], 1);
|
||||
|
||||
z2_s16 = vmul_s16(row0, quant_row0);
|
||||
z3_s16 = vmul_s16(row4, quant_row4);
|
||||
|
||||
int32x4_t tmp0 = vshll_n_s16(vadd_s16(z2_s16, z3_s16), CONST_BITS);
|
||||
int32x4_t tmp1 = vshll_n_s16(vsub_s16(z2_s16, z3_s16), CONST_BITS);
|
||||
|
||||
int32x4_t tmp10 = vaddq_s32(tmp0, tmp3);
|
||||
int32x4_t tmp13 = vsubq_s32(tmp0, tmp3);
|
||||
int32x4_t tmp11 = vaddq_s32(tmp1, tmp2);
|
||||
int32x4_t tmp12 = vsubq_s32(tmp1, tmp2);
|
||||
|
||||
/* Odd part */
|
||||
int16x4_t tmp0_s16 = vmul_s16(row7, quant_row7);
|
||||
int16x4_t tmp1_s16 = vmul_s16(row5, quant_row5);
|
||||
int16x4_t tmp2_s16 = vmul_s16(row3, quant_row3);
|
||||
int16x4_t tmp3_s16 = vmul_s16(row1, quant_row1);
|
||||
|
||||
z3_s16 = vadd_s16(tmp0_s16, tmp2_s16);
|
||||
int16x4_t z4_s16 = vadd_s16(tmp1_s16, tmp3_s16);
|
||||
|
||||
/* Implementation as per jpeg_idct_islow() in jidctint.c:
|
||||
* z5 = (z3 + z4) * 1.175875602;
|
||||
* z3 = z3 * -1.961570560; z4 = z4 * -0.390180644;
|
||||
* z3 += z5; z4 += z5;
|
||||
*
|
||||
* This implementation:
|
||||
* z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602;
|
||||
* z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644);
|
||||
*/
|
||||
|
||||
int32x4_t z3 = vmull_lane_s16(z3_s16, consts.val[2], 3);
|
||||
int32x4_t z4 = vmull_lane_s16(z3_s16, consts.val[1], 3);
|
||||
z3 = vmlal_lane_s16(z3, z4_s16, consts.val[1], 3);
|
||||
z4 = vmlal_lane_s16(z4, z4_s16, consts.val[2], 0);
|
||||
|
||||
/* Implementation as per jpeg_idct_islow() in jidctint.c:
|
||||
* z1 = tmp0 + tmp3; z2 = tmp1 + tmp2;
|
||||
* tmp0 = tmp0 * 0.298631336; tmp1 = tmp1 * 2.053119869;
|
||||
* tmp2 = tmp2 * 3.072711026; tmp3 = tmp3 * 1.501321110;
|
||||
* z1 = z1 * -0.899976223; z2 = z2 * -2.562915447;
|
||||
* tmp0 += z1 + z3; tmp1 += z2 + z4;
|
||||
* tmp2 += z2 + z3; tmp3 += z1 + z4;
|
||||
*
|
||||
* This implementation:
|
||||
* tmp0 = tmp0 * (0.298631336 - 0.899976223) + tmp3 * -0.899976223;
|
||||
* tmp1 = tmp1 * (2.053119869 - 2.562915447) + tmp2 * -2.562915447;
|
||||
* tmp2 = tmp1 * -2.562915447 + tmp2 * (3.072711026 - 2.562915447);
|
||||
* tmp3 = tmp0 * -0.899976223 + tmp3 * (1.501321110 - 0.899976223);
|
||||
* tmp0 += z3; tmp1 += z4;
|
||||
* tmp2 += z3; tmp3 += z4;
|
||||
*/
|
||||
|
||||
tmp0 = vmull_lane_s16(tmp0_s16, consts.val[0], 3);
|
||||
tmp1 = vmull_lane_s16(tmp1_s16, consts.val[1], 1);
|
||||
tmp2 = vmull_lane_s16(tmp2_s16, consts.val[2], 2);
|
||||
tmp3 = vmull_lane_s16(tmp3_s16, consts.val[1], 0);
|
||||
|
||||
tmp0 = vmlsl_lane_s16(tmp0, tmp3_s16, consts.val[0], 0);
|
||||
tmp1 = vmlsl_lane_s16(tmp1, tmp2_s16, consts.val[0], 2);
|
||||
tmp2 = vmlsl_lane_s16(tmp2, tmp1_s16, consts.val[0], 2);
|
||||
tmp3 = vmlsl_lane_s16(tmp3, tmp0_s16, consts.val[0], 0);
|
||||
|
||||
tmp0 = vaddq_s32(tmp0, z3);
|
||||
tmp1 = vaddq_s32(tmp1, z4);
|
||||
tmp2 = vaddq_s32(tmp2, z3);
|
||||
tmp3 = vaddq_s32(tmp3, z4);
|
||||
|
||||
/* Final output stage: descale and narrow to 16-bit. */
|
||||
int16x4x4_t rows_0123 = { {
|
||||
vrshrn_n_s32(vaddq_s32(tmp10, tmp3), DESCALE_P1),
|
||||
vrshrn_n_s32(vaddq_s32(tmp11, tmp2), DESCALE_P1),
|
||||
vrshrn_n_s32(vaddq_s32(tmp12, tmp1), DESCALE_P1),
|
||||
vrshrn_n_s32(vaddq_s32(tmp13, tmp0), DESCALE_P1)
|
||||
} };
|
||||
int16x4x4_t rows_4567 = { {
|
||||
vrshrn_n_s32(vsubq_s32(tmp13, tmp0), DESCALE_P1),
|
||||
vrshrn_n_s32(vsubq_s32(tmp12, tmp1), DESCALE_P1),
|
||||
vrshrn_n_s32(vsubq_s32(tmp11, tmp2), DESCALE_P1),
|
||||
vrshrn_n_s32(vsubq_s32(tmp10, tmp3), DESCALE_P1)
|
||||
} };
|
||||
|
||||
/* Store 4x4 blocks to the intermediate workspace, ready for the second pass.
|
||||
* (VST4 transposes the blocks. We need to operate on rows in the next
|
||||
* pass.)
|
||||
*/
|
||||
vst4_s16(workspace_1, rows_0123);
|
||||
vst4_s16(workspace_2, rows_4567);
|
||||
}
|
||||
|
||||
|
||||
/* Perform dequantization and the first pass of the accurate inverse DCT on a
|
||||
* 4x8 block of coefficients.
|
||||
*
|
||||
* This "sparse" version assumes that the AC coefficients in rows 4-7 are all
|
||||
* 0. This simplifies the IDCT calculation, accelerating overall performance.
|
||||
*/
|
||||
|
||||
static INLINE void jsimd_idct_islow_pass1_sparse(int16x4_t row0,
|
||||
int16x4_t row1,
|
||||
int16x4_t row2,
|
||||
int16x4_t row3,
|
||||
int16x4_t quant_row0,
|
||||
int16x4_t quant_row1,
|
||||
int16x4_t quant_row2,
|
||||
int16x4_t quant_row3,
|
||||
int16_t *workspace_1,
|
||||
int16_t *workspace_2)
|
||||
{
|
||||
/* Load constants for IDCT computation. */
|
||||
#ifdef HAVE_VLD1_S16_X3
|
||||
const int16x4x3_t consts = vld1_s16_x3(jsimd_idct_islow_neon_consts);
|
||||
#else
|
||||
const int16x4_t consts1 = vld1_s16(jsimd_idct_islow_neon_consts);
|
||||
const int16x4_t consts2 = vld1_s16(jsimd_idct_islow_neon_consts + 4);
|
||||
const int16x4_t consts3 = vld1_s16(jsimd_idct_islow_neon_consts + 8);
|
||||
const int16x4x3_t consts = { { consts1, consts2, consts3 } };
|
||||
#endif
|
||||
|
||||
/* Even part (z3 is all 0) */
|
||||
int16x4_t z2_s16 = vmul_s16(row2, quant_row2);
|
||||
|
||||
int32x4_t tmp2 = vmull_lane_s16(z2_s16, consts.val[0], 1);
|
||||
int32x4_t tmp3 = vmull_lane_s16(z2_s16, consts.val[1], 2);
|
||||
|
||||
z2_s16 = vmul_s16(row0, quant_row0);
|
||||
int32x4_t tmp0 = vshll_n_s16(z2_s16, CONST_BITS);
|
||||
int32x4_t tmp1 = vshll_n_s16(z2_s16, CONST_BITS);
|
||||
|
||||
int32x4_t tmp10 = vaddq_s32(tmp0, tmp3);
|
||||
int32x4_t tmp13 = vsubq_s32(tmp0, tmp3);
|
||||
int32x4_t tmp11 = vaddq_s32(tmp1, tmp2);
|
||||
int32x4_t tmp12 = vsubq_s32(tmp1, tmp2);
|
||||
|
||||
/* Odd part (tmp0 and tmp1 are both all 0) */
|
||||
int16x4_t tmp2_s16 = vmul_s16(row3, quant_row3);
|
||||
int16x4_t tmp3_s16 = vmul_s16(row1, quant_row1);
|
||||
|
||||
int16x4_t z3_s16 = tmp2_s16;
|
||||
int16x4_t z4_s16 = tmp3_s16;
|
||||
|
||||
int32x4_t z3 = vmull_lane_s16(z3_s16, consts.val[2], 3);
|
||||
int32x4_t z4 = vmull_lane_s16(z3_s16, consts.val[1], 3);
|
||||
z3 = vmlal_lane_s16(z3, z4_s16, consts.val[1], 3);
|
||||
z4 = vmlal_lane_s16(z4, z4_s16, consts.val[2], 0);
|
||||
|
||||
tmp0 = vmlsl_lane_s16(z3, tmp3_s16, consts.val[0], 0);
|
||||
tmp1 = vmlsl_lane_s16(z4, tmp2_s16, consts.val[0], 2);
|
||||
tmp2 = vmlal_lane_s16(z3, tmp2_s16, consts.val[2], 2);
|
||||
tmp3 = vmlal_lane_s16(z4, tmp3_s16, consts.val[1], 0);
|
||||
|
||||
/* Final output stage: descale and narrow to 16-bit. */
|
||||
int16x4x4_t rows_0123 = { {
|
||||
vrshrn_n_s32(vaddq_s32(tmp10, tmp3), DESCALE_P1),
|
||||
vrshrn_n_s32(vaddq_s32(tmp11, tmp2), DESCALE_P1),
|
||||
vrshrn_n_s32(vaddq_s32(tmp12, tmp1), DESCALE_P1),
|
||||
vrshrn_n_s32(vaddq_s32(tmp13, tmp0), DESCALE_P1)
|
||||
} };
|
||||
int16x4x4_t rows_4567 = { {
|
||||
vrshrn_n_s32(vsubq_s32(tmp13, tmp0), DESCALE_P1),
|
||||
vrshrn_n_s32(vsubq_s32(tmp12, tmp1), DESCALE_P1),
|
||||
vrshrn_n_s32(vsubq_s32(tmp11, tmp2), DESCALE_P1),
|
||||
vrshrn_n_s32(vsubq_s32(tmp10, tmp3), DESCALE_P1)
|
||||
} };
|
||||
|
||||
/* Store 4x4 blocks to the intermediate workspace, ready for the second pass.
|
||||
* (VST4 transposes the blocks. We need to operate on rows in the next
|
||||
* pass.)
|
||||
*/
|
||||
vst4_s16(workspace_1, rows_0123);
|
||||
vst4_s16(workspace_2, rows_4567);
|
||||
}
|
||||
|
||||
|
||||
/* Perform the second pass of the accurate inverse DCT on a 4x8 block of
|
||||
* coefficients. (To process the full 8x8 DCT block, this function-- or some
|
||||
* other optimized variant-- needs to be called for both the right and left 4x8
|
||||
* blocks.)
|
||||
*
|
||||
* This "regular" version assumes that no optimization can be made to the IDCT
|
||||
* calculation, since no useful set of coefficient values are all 0 after the
|
||||
* first pass.
|
||||
*
|
||||
* Again, the original C implementation of the accurate IDCT (jpeg_idct_slow())
|
||||
* can be found in jidctint.c. Algorithmic changes made here are documented
|
||||
* inline.
|
||||
*/
|
||||
|
||||
static INLINE void jsimd_idct_islow_pass2_regular(int16_t *workspace,
|
||||
JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col,
|
||||
unsigned buf_offset)
|
||||
{
|
||||
/* Load constants for IDCT computation. */
|
||||
#ifdef HAVE_VLD1_S16_X3
|
||||
const int16x4x3_t consts = vld1_s16_x3(jsimd_idct_islow_neon_consts);
|
||||
#else
|
||||
const int16x4_t consts1 = vld1_s16(jsimd_idct_islow_neon_consts);
|
||||
const int16x4_t consts2 = vld1_s16(jsimd_idct_islow_neon_consts + 4);
|
||||
const int16x4_t consts3 = vld1_s16(jsimd_idct_islow_neon_consts + 8);
|
||||
const int16x4x3_t consts = { { consts1, consts2, consts3 } };
|
||||
#endif
|
||||
|
||||
/* Even part */
|
||||
int16x4_t z2_s16 = vld1_s16(workspace + 2 * DCTSIZE / 2);
|
||||
int16x4_t z3_s16 = vld1_s16(workspace + 6 * DCTSIZE / 2);
|
||||
|
||||
int32x4_t tmp2 = vmull_lane_s16(z2_s16, consts.val[0], 1);
|
||||
int32x4_t tmp3 = vmull_lane_s16(z2_s16, consts.val[1], 2);
|
||||
tmp2 = vmlal_lane_s16(tmp2, z3_s16, consts.val[2], 1);
|
||||
tmp3 = vmlal_lane_s16(tmp3, z3_s16, consts.val[0], 1);
|
||||
|
||||
z2_s16 = vld1_s16(workspace + 0 * DCTSIZE / 2);
|
||||
z3_s16 = vld1_s16(workspace + 4 * DCTSIZE / 2);
|
||||
|
||||
int32x4_t tmp0 = vshll_n_s16(vadd_s16(z2_s16, z3_s16), CONST_BITS);
|
||||
int32x4_t tmp1 = vshll_n_s16(vsub_s16(z2_s16, z3_s16), CONST_BITS);
|
||||
|
||||
int32x4_t tmp10 = vaddq_s32(tmp0, tmp3);
|
||||
int32x4_t tmp13 = vsubq_s32(tmp0, tmp3);
|
||||
int32x4_t tmp11 = vaddq_s32(tmp1, tmp2);
|
||||
int32x4_t tmp12 = vsubq_s32(tmp1, tmp2);
|
||||
|
||||
/* Odd part */
|
||||
int16x4_t tmp0_s16 = vld1_s16(workspace + 7 * DCTSIZE / 2);
|
||||
int16x4_t tmp1_s16 = vld1_s16(workspace + 5 * DCTSIZE / 2);
|
||||
int16x4_t tmp2_s16 = vld1_s16(workspace + 3 * DCTSIZE / 2);
|
||||
int16x4_t tmp3_s16 = vld1_s16(workspace + 1 * DCTSIZE / 2);
|
||||
|
||||
z3_s16 = vadd_s16(tmp0_s16, tmp2_s16);
|
||||
int16x4_t z4_s16 = vadd_s16(tmp1_s16, tmp3_s16);
|
||||
|
||||
/* Implementation as per jpeg_idct_islow() in jidctint.c:
|
||||
* z5 = (z3 + z4) * 1.175875602;
|
||||
* z3 = z3 * -1.961570560; z4 = z4 * -0.390180644;
|
||||
* z3 += z5; z4 += z5;
|
||||
*
|
||||
* This implementation:
|
||||
* z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602;
|
||||
* z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644);
|
||||
*/
|
||||
|
||||
int32x4_t z3 = vmull_lane_s16(z3_s16, consts.val[2], 3);
|
||||
int32x4_t z4 = vmull_lane_s16(z3_s16, consts.val[1], 3);
|
||||
z3 = vmlal_lane_s16(z3, z4_s16, consts.val[1], 3);
|
||||
z4 = vmlal_lane_s16(z4, z4_s16, consts.val[2], 0);
|
||||
|
||||
/* Implementation as per jpeg_idct_islow() in jidctint.c:
|
||||
* z1 = tmp0 + tmp3; z2 = tmp1 + tmp2;
|
||||
* tmp0 = tmp0 * 0.298631336; tmp1 = tmp1 * 2.053119869;
|
||||
* tmp2 = tmp2 * 3.072711026; tmp3 = tmp3 * 1.501321110;
|
||||
* z1 = z1 * -0.899976223; z2 = z2 * -2.562915447;
|
||||
* tmp0 += z1 + z3; tmp1 += z2 + z4;
|
||||
* tmp2 += z2 + z3; tmp3 += z1 + z4;
|
||||
*
|
||||
* This implementation:
|
||||
* tmp0 = tmp0 * (0.298631336 - 0.899976223) + tmp3 * -0.899976223;
|
||||
* tmp1 = tmp1 * (2.053119869 - 2.562915447) + tmp2 * -2.562915447;
|
||||
* tmp2 = tmp1 * -2.562915447 + tmp2 * (3.072711026 - 2.562915447);
|
||||
* tmp3 = tmp0 * -0.899976223 + tmp3 * (1.501321110 - 0.899976223);
|
||||
* tmp0 += z3; tmp1 += z4;
|
||||
* tmp2 += z3; tmp3 += z4;
|
||||
*/
|
||||
|
||||
tmp0 = vmull_lane_s16(tmp0_s16, consts.val[0], 3);
|
||||
tmp1 = vmull_lane_s16(tmp1_s16, consts.val[1], 1);
|
||||
tmp2 = vmull_lane_s16(tmp2_s16, consts.val[2], 2);
|
||||
tmp3 = vmull_lane_s16(tmp3_s16, consts.val[1], 0);
|
||||
|
||||
tmp0 = vmlsl_lane_s16(tmp0, tmp3_s16, consts.val[0], 0);
|
||||
tmp1 = vmlsl_lane_s16(tmp1, tmp2_s16, consts.val[0], 2);
|
||||
tmp2 = vmlsl_lane_s16(tmp2, tmp1_s16, consts.val[0], 2);
|
||||
tmp3 = vmlsl_lane_s16(tmp3, tmp0_s16, consts.val[0], 0);
|
||||
|
||||
tmp0 = vaddq_s32(tmp0, z3);
|
||||
tmp1 = vaddq_s32(tmp1, z4);
|
||||
tmp2 = vaddq_s32(tmp2, z3);
|
||||
tmp3 = vaddq_s32(tmp3, z4);
|
||||
|
||||
/* Final output stage: descale and narrow to 16-bit. */
|
||||
int16x8_t cols_02_s16 = vcombine_s16(vaddhn_s32(tmp10, tmp3),
|
||||
vaddhn_s32(tmp12, tmp1));
|
||||
int16x8_t cols_13_s16 = vcombine_s16(vaddhn_s32(tmp11, tmp2),
|
||||
vaddhn_s32(tmp13, tmp0));
|
||||
int16x8_t cols_46_s16 = vcombine_s16(vsubhn_s32(tmp13, tmp0),
|
||||
vsubhn_s32(tmp11, tmp2));
|
||||
int16x8_t cols_57_s16 = vcombine_s16(vsubhn_s32(tmp12, tmp1),
|
||||
vsubhn_s32(tmp10, tmp3));
|
||||
/* Descale and narrow to 8-bit. */
|
||||
int8x8_t cols_02_s8 = vqrshrn_n_s16(cols_02_s16, DESCALE_P2 - 16);
|
||||
int8x8_t cols_13_s8 = vqrshrn_n_s16(cols_13_s16, DESCALE_P2 - 16);
|
||||
int8x8_t cols_46_s8 = vqrshrn_n_s16(cols_46_s16, DESCALE_P2 - 16);
|
||||
int8x8_t cols_57_s8 = vqrshrn_n_s16(cols_57_s16, DESCALE_P2 - 16);
|
||||
/* Clamp to range [0-255]. */
|
||||
uint8x8_t cols_02_u8 = vadd_u8(vreinterpret_u8_s8(cols_02_s8),
|
||||
vdup_n_u8(CENTERJSAMPLE));
|
||||
uint8x8_t cols_13_u8 = vadd_u8(vreinterpret_u8_s8(cols_13_s8),
|
||||
vdup_n_u8(CENTERJSAMPLE));
|
||||
uint8x8_t cols_46_u8 = vadd_u8(vreinterpret_u8_s8(cols_46_s8),
|
||||
vdup_n_u8(CENTERJSAMPLE));
|
||||
uint8x8_t cols_57_u8 = vadd_u8(vreinterpret_u8_s8(cols_57_s8),
|
||||
vdup_n_u8(CENTERJSAMPLE));
|
||||
|
||||
/* Transpose 4x8 block and store to memory. (Zipping adjacent columns
|
||||
* together allows us to store 16-bit elements.)
|
||||
*/
|
||||
uint8x8x2_t cols_01_23 = vzip_u8(cols_02_u8, cols_13_u8);
|
||||
uint8x8x2_t cols_45_67 = vzip_u8(cols_46_u8, cols_57_u8);
|
||||
uint16x4x4_t cols_01_23_45_67 = { {
|
||||
vreinterpret_u16_u8(cols_01_23.val[0]),
|
||||
vreinterpret_u16_u8(cols_01_23.val[1]),
|
||||
vreinterpret_u16_u8(cols_45_67.val[0]),
|
||||
vreinterpret_u16_u8(cols_45_67.val[1])
|
||||
} };
|
||||
|
||||
JSAMPROW outptr0 = output_buf[buf_offset + 0] + output_col;
|
||||
JSAMPROW outptr1 = output_buf[buf_offset + 1] + output_col;
|
||||
JSAMPROW outptr2 = output_buf[buf_offset + 2] + output_col;
|
||||
JSAMPROW outptr3 = output_buf[buf_offset + 3] + output_col;
|
||||
/* VST4 of 16-bit elements completes the transpose. */
|
||||
vst4_lane_u16((uint16_t *)outptr0, cols_01_23_45_67, 0);
|
||||
vst4_lane_u16((uint16_t *)outptr1, cols_01_23_45_67, 1);
|
||||
vst4_lane_u16((uint16_t *)outptr2, cols_01_23_45_67, 2);
|
||||
vst4_lane_u16((uint16_t *)outptr3, cols_01_23_45_67, 3);
|
||||
}
|
||||
|
||||
|
||||
/* Performs the second pass of the accurate inverse DCT on a 4x8 block
|
||||
* of coefficients.
|
||||
*
|
||||
* This "sparse" version assumes that the coefficient values (after the first
|
||||
* pass) in rows 4-7 are all 0. This simplifies the IDCT calculation,
|
||||
* accelerating overall performance.
|
||||
*/
|
||||
|
||||
static INLINE void jsimd_idct_islow_pass2_sparse(int16_t *workspace,
|
||||
JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col,
|
||||
unsigned buf_offset)
|
||||
{
|
||||
/* Load constants for IDCT computation. */
|
||||
#ifdef HAVE_VLD1_S16_X3
|
||||
const int16x4x3_t consts = vld1_s16_x3(jsimd_idct_islow_neon_consts);
|
||||
#else
|
||||
const int16x4_t consts1 = vld1_s16(jsimd_idct_islow_neon_consts);
|
||||
const int16x4_t consts2 = vld1_s16(jsimd_idct_islow_neon_consts + 4);
|
||||
const int16x4_t consts3 = vld1_s16(jsimd_idct_islow_neon_consts + 8);
|
||||
const int16x4x3_t consts = { { consts1, consts2, consts3 } };
|
||||
#endif
|
||||
|
||||
/* Even part (z3 is all 0) */
|
||||
int16x4_t z2_s16 = vld1_s16(workspace + 2 * DCTSIZE / 2);
|
||||
|
||||
int32x4_t tmp2 = vmull_lane_s16(z2_s16, consts.val[0], 1);
|
||||
int32x4_t tmp3 = vmull_lane_s16(z2_s16, consts.val[1], 2);
|
||||
|
||||
z2_s16 = vld1_s16(workspace + 0 * DCTSIZE / 2);
|
||||
int32x4_t tmp0 = vshll_n_s16(z2_s16, CONST_BITS);
|
||||
int32x4_t tmp1 = vshll_n_s16(z2_s16, CONST_BITS);
|
||||
|
||||
int32x4_t tmp10 = vaddq_s32(tmp0, tmp3);
|
||||
int32x4_t tmp13 = vsubq_s32(tmp0, tmp3);
|
||||
int32x4_t tmp11 = vaddq_s32(tmp1, tmp2);
|
||||
int32x4_t tmp12 = vsubq_s32(tmp1, tmp2);
|
||||
|
||||
/* Odd part (tmp0 and tmp1 are both all 0) */
|
||||
int16x4_t tmp2_s16 = vld1_s16(workspace + 3 * DCTSIZE / 2);
|
||||
int16x4_t tmp3_s16 = vld1_s16(workspace + 1 * DCTSIZE / 2);
|
||||
|
||||
int16x4_t z3_s16 = tmp2_s16;
|
||||
int16x4_t z4_s16 = tmp3_s16;
|
||||
|
||||
int32x4_t z3 = vmull_lane_s16(z3_s16, consts.val[2], 3);
|
||||
z3 = vmlal_lane_s16(z3, z4_s16, consts.val[1], 3);
|
||||
int32x4_t z4 = vmull_lane_s16(z3_s16, consts.val[1], 3);
|
||||
z4 = vmlal_lane_s16(z4, z4_s16, consts.val[2], 0);
|
||||
|
||||
tmp0 = vmlsl_lane_s16(z3, tmp3_s16, consts.val[0], 0);
|
||||
tmp1 = vmlsl_lane_s16(z4, tmp2_s16, consts.val[0], 2);
|
||||
tmp2 = vmlal_lane_s16(z3, tmp2_s16, consts.val[2], 2);
|
||||
tmp3 = vmlal_lane_s16(z4, tmp3_s16, consts.val[1], 0);
|
||||
|
||||
/* Final output stage: descale and narrow to 16-bit. */
|
||||
int16x8_t cols_02_s16 = vcombine_s16(vaddhn_s32(tmp10, tmp3),
|
||||
vaddhn_s32(tmp12, tmp1));
|
||||
int16x8_t cols_13_s16 = vcombine_s16(vaddhn_s32(tmp11, tmp2),
|
||||
vaddhn_s32(tmp13, tmp0));
|
||||
int16x8_t cols_46_s16 = vcombine_s16(vsubhn_s32(tmp13, tmp0),
|
||||
vsubhn_s32(tmp11, tmp2));
|
||||
int16x8_t cols_57_s16 = vcombine_s16(vsubhn_s32(tmp12, tmp1),
|
||||
vsubhn_s32(tmp10, tmp3));
|
||||
/* Descale and narrow to 8-bit. */
|
||||
int8x8_t cols_02_s8 = vqrshrn_n_s16(cols_02_s16, DESCALE_P2 - 16);
|
||||
int8x8_t cols_13_s8 = vqrshrn_n_s16(cols_13_s16, DESCALE_P2 - 16);
|
||||
int8x8_t cols_46_s8 = vqrshrn_n_s16(cols_46_s16, DESCALE_P2 - 16);
|
||||
int8x8_t cols_57_s8 = vqrshrn_n_s16(cols_57_s16, DESCALE_P2 - 16);
|
||||
/* Clamp to range [0-255]. */
|
||||
uint8x8_t cols_02_u8 = vadd_u8(vreinterpret_u8_s8(cols_02_s8),
|
||||
vdup_n_u8(CENTERJSAMPLE));
|
||||
uint8x8_t cols_13_u8 = vadd_u8(vreinterpret_u8_s8(cols_13_s8),
|
||||
vdup_n_u8(CENTERJSAMPLE));
|
||||
uint8x8_t cols_46_u8 = vadd_u8(vreinterpret_u8_s8(cols_46_s8),
|
||||
vdup_n_u8(CENTERJSAMPLE));
|
||||
uint8x8_t cols_57_u8 = vadd_u8(vreinterpret_u8_s8(cols_57_s8),
|
||||
vdup_n_u8(CENTERJSAMPLE));
|
||||
|
||||
/* Transpose 4x8 block and store to memory. (Zipping adjacent columns
|
||||
* together allows us to store 16-bit elements.)
|
||||
*/
|
||||
uint8x8x2_t cols_01_23 = vzip_u8(cols_02_u8, cols_13_u8);
|
||||
uint8x8x2_t cols_45_67 = vzip_u8(cols_46_u8, cols_57_u8);
|
||||
uint16x4x4_t cols_01_23_45_67 = { {
|
||||
vreinterpret_u16_u8(cols_01_23.val[0]),
|
||||
vreinterpret_u16_u8(cols_01_23.val[1]),
|
||||
vreinterpret_u16_u8(cols_45_67.val[0]),
|
||||
vreinterpret_u16_u8(cols_45_67.val[1])
|
||||
} };
|
||||
|
||||
JSAMPROW outptr0 = output_buf[buf_offset + 0] + output_col;
|
||||
JSAMPROW outptr1 = output_buf[buf_offset + 1] + output_col;
|
||||
JSAMPROW outptr2 = output_buf[buf_offset + 2] + output_col;
|
||||
JSAMPROW outptr3 = output_buf[buf_offset + 3] + output_col;
|
||||
/* VST4 of 16-bit elements completes the transpose. */
|
||||
vst4_lane_u16((uint16_t *)outptr0, cols_01_23_45_67, 0);
|
||||
vst4_lane_u16((uint16_t *)outptr1, cols_01_23_45_67, 1);
|
||||
vst4_lane_u16((uint16_t *)outptr2, cols_01_23_45_67, 2);
|
||||
vst4_lane_u16((uint16_t *)outptr3, cols_01_23_45_67, 3);
|
||||
}
|
||||
+486
@@ -0,0 +1,486 @@
|
||||
/*
|
||||
* jidctred-neon.c - reduced-size IDCT (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020, Arm Limited. All Rights Reserved.
|
||||
* Copyright (C) 2020, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
#include "align.h"
|
||||
#include "neon-compat.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
|
||||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 2
|
||||
|
||||
#define F_0_211 1730
|
||||
#define F_0_509 4176
|
||||
#define F_0_601 4926
|
||||
#define F_0_720 5906
|
||||
#define F_0_765 6270
|
||||
#define F_0_850 6967
|
||||
#define F_0_899 7373
|
||||
#define F_1_061 8697
|
||||
#define F_1_272 10426
|
||||
#define F_1_451 11893
|
||||
#define F_1_847 15137
|
||||
#define F_2_172 17799
|
||||
#define F_2_562 20995
|
||||
#define F_3_624 29692
|
||||
|
||||
|
||||
/* jsimd_idct_2x2_neon() is an inverse DCT function that produces reduced-size
|
||||
* 2x2 output from an 8x8 DCT block. It uses the same calculations and
|
||||
* produces exactly the same output as IJG's original jpeg_idct_2x2() function
|
||||
* from jpeg-6b, which can be found in jidctred.c.
|
||||
*
|
||||
* Scaled integer constants are used to avoid floating-point arithmetic:
|
||||
* 0.720959822 = 5906 * 2^-13
|
||||
* 0.850430095 = 6967 * 2^-13
|
||||
* 1.272758580 = 10426 * 2^-13
|
||||
* 3.624509785 = 29692 * 2^-13
|
||||
*
|
||||
* See jidctred.c for further details of the 2x2 IDCT algorithm. Where
|
||||
* possible, the variable names and comments here in jsimd_idct_2x2_neon()
|
||||
* match up with those in jpeg_idct_2x2().
|
||||
*/
|
||||
|
||||
ALIGN(16) static const int16_t jsimd_idct_2x2_neon_consts[] = {
|
||||
-F_0_720, F_0_850, -F_1_272, F_3_624
|
||||
};
|
||||
|
||||
void jsimd_idct_2x2_neon(void *dct_table, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
ISLOW_MULT_TYPE *quantptr = dct_table;
|
||||
|
||||
/* Load DCT coefficients. */
|
||||
int16x8_t row0 = vld1q_s16(coef_block + 0 * DCTSIZE);
|
||||
int16x8_t row1 = vld1q_s16(coef_block + 1 * DCTSIZE);
|
||||
int16x8_t row3 = vld1q_s16(coef_block + 3 * DCTSIZE);
|
||||
int16x8_t row5 = vld1q_s16(coef_block + 5 * DCTSIZE);
|
||||
int16x8_t row7 = vld1q_s16(coef_block + 7 * DCTSIZE);
|
||||
|
||||
/* Load quantization table values. */
|
||||
int16x8_t quant_row0 = vld1q_s16(quantptr + 0 * DCTSIZE);
|
||||
int16x8_t quant_row1 = vld1q_s16(quantptr + 1 * DCTSIZE);
|
||||
int16x8_t quant_row3 = vld1q_s16(quantptr + 3 * DCTSIZE);
|
||||
int16x8_t quant_row5 = vld1q_s16(quantptr + 5 * DCTSIZE);
|
||||
int16x8_t quant_row7 = vld1q_s16(quantptr + 7 * DCTSIZE);
|
||||
|
||||
/* Dequantize DCT coefficients. */
|
||||
row0 = vmulq_s16(row0, quant_row0);
|
||||
row1 = vmulq_s16(row1, quant_row1);
|
||||
row3 = vmulq_s16(row3, quant_row3);
|
||||
row5 = vmulq_s16(row5, quant_row5);
|
||||
row7 = vmulq_s16(row7, quant_row7);
|
||||
|
||||
/* Load IDCT conversion constants. */
|
||||
const int16x4_t consts = vld1_s16(jsimd_idct_2x2_neon_consts);
|
||||
|
||||
/* Pass 1: process columns from input, put results in vectors row0 and
|
||||
* row1.
|
||||
*/
|
||||
|
||||
/* Even part */
|
||||
int32x4_t tmp10_l = vshll_n_s16(vget_low_s16(row0), CONST_BITS + 2);
|
||||
int32x4_t tmp10_h = vshll_n_s16(vget_high_s16(row0), CONST_BITS + 2);
|
||||
|
||||
/* Odd part */
|
||||
int32x4_t tmp0_l = vmull_lane_s16(vget_low_s16(row1), consts, 3);
|
||||
tmp0_l = vmlal_lane_s16(tmp0_l, vget_low_s16(row3), consts, 2);
|
||||
tmp0_l = vmlal_lane_s16(tmp0_l, vget_low_s16(row5), consts, 1);
|
||||
tmp0_l = vmlal_lane_s16(tmp0_l, vget_low_s16(row7), consts, 0);
|
||||
int32x4_t tmp0_h = vmull_lane_s16(vget_high_s16(row1), consts, 3);
|
||||
tmp0_h = vmlal_lane_s16(tmp0_h, vget_high_s16(row3), consts, 2);
|
||||
tmp0_h = vmlal_lane_s16(tmp0_h, vget_high_s16(row5), consts, 1);
|
||||
tmp0_h = vmlal_lane_s16(tmp0_h, vget_high_s16(row7), consts, 0);
|
||||
|
||||
/* Final output stage: descale and narrow to 16-bit. */
|
||||
row0 = vcombine_s16(vrshrn_n_s32(vaddq_s32(tmp10_l, tmp0_l), CONST_BITS),
|
||||
vrshrn_n_s32(vaddq_s32(tmp10_h, tmp0_h), CONST_BITS));
|
||||
row1 = vcombine_s16(vrshrn_n_s32(vsubq_s32(tmp10_l, tmp0_l), CONST_BITS),
|
||||
vrshrn_n_s32(vsubq_s32(tmp10_h, tmp0_h), CONST_BITS));
|
||||
|
||||
/* Transpose two rows, ready for second pass. */
|
||||
int16x8x2_t cols_0246_1357 = vtrnq_s16(row0, row1);
|
||||
int16x8_t cols_0246 = cols_0246_1357.val[0];
|
||||
int16x8_t cols_1357 = cols_0246_1357.val[1];
|
||||
/* Duplicate columns such that each is accessible in its own vector. */
|
||||
int32x4x2_t cols_1155_3377 = vtrnq_s32(vreinterpretq_s32_s16(cols_1357),
|
||||
vreinterpretq_s32_s16(cols_1357));
|
||||
int16x8_t cols_1155 = vreinterpretq_s16_s32(cols_1155_3377.val[0]);
|
||||
int16x8_t cols_3377 = vreinterpretq_s16_s32(cols_1155_3377.val[1]);
|
||||
|
||||
/* Pass 2: process two rows, store to output array. */
|
||||
|
||||
/* Even part: we're only interested in col0; the top half of tmp10 is "don't
|
||||
* care."
|
||||
*/
|
||||
int32x4_t tmp10 = vshll_n_s16(vget_low_s16(cols_0246), CONST_BITS + 2);
|
||||
|
||||
/* Odd part: we're only interested in the bottom half of tmp0. */
|
||||
int32x4_t tmp0 = vmull_lane_s16(vget_low_s16(cols_1155), consts, 3);
|
||||
tmp0 = vmlal_lane_s16(tmp0, vget_low_s16(cols_3377), consts, 2);
|
||||
tmp0 = vmlal_lane_s16(tmp0, vget_high_s16(cols_1155), consts, 1);
|
||||
tmp0 = vmlal_lane_s16(tmp0, vget_high_s16(cols_3377), consts, 0);
|
||||
|
||||
/* Final output stage: descale and clamp to range [0-255]. */
|
||||
int16x8_t output_s16 = vcombine_s16(vaddhn_s32(tmp10, tmp0),
|
||||
vsubhn_s32(tmp10, tmp0));
|
||||
output_s16 = vrsraq_n_s16(vdupq_n_s16(CENTERJSAMPLE), output_s16,
|
||||
CONST_BITS + PASS1_BITS + 3 + 2 - 16);
|
||||
/* Narrow to 8-bit and convert to unsigned. */
|
||||
uint8x8_t output_u8 = vqmovun_s16(output_s16);
|
||||
|
||||
/* Store 2x2 block to memory. */
|
||||
vst1_lane_u8(output_buf[0] + output_col, output_u8, 0);
|
||||
vst1_lane_u8(output_buf[1] + output_col, output_u8, 1);
|
||||
vst1_lane_u8(output_buf[0] + output_col + 1, output_u8, 4);
|
||||
vst1_lane_u8(output_buf[1] + output_col + 1, output_u8, 5);
|
||||
}
|
||||
|
||||
|
||||
/* jsimd_idct_4x4_neon() is an inverse DCT function that produces reduced-size
|
||||
* 4x4 output from an 8x8 DCT block. It uses the same calculations and
|
||||
* produces exactly the same output as IJG's original jpeg_idct_4x4() function
|
||||
* from jpeg-6b, which can be found in jidctred.c.
|
||||
*
|
||||
* Scaled integer constants are used to avoid floating-point arithmetic:
|
||||
* 0.211164243 = 1730 * 2^-13
|
||||
* 0.509795579 = 4176 * 2^-13
|
||||
* 0.601344887 = 4926 * 2^-13
|
||||
* 0.765366865 = 6270 * 2^-13
|
||||
* 0.899976223 = 7373 * 2^-13
|
||||
* 1.061594337 = 8697 * 2^-13
|
||||
* 1.451774981 = 11893 * 2^-13
|
||||
* 1.847759065 = 15137 * 2^-13
|
||||
* 2.172734803 = 17799 * 2^-13
|
||||
* 2.562915447 = 20995 * 2^-13
|
||||
*
|
||||
* See jidctred.c for further details of the 4x4 IDCT algorithm. Where
|
||||
* possible, the variable names and comments here in jsimd_idct_4x4_neon()
|
||||
* match up with those in jpeg_idct_4x4().
|
||||
*/
|
||||
|
||||
ALIGN(16) static const int16_t jsimd_idct_4x4_neon_consts[] = {
|
||||
F_1_847, -F_0_765, -F_0_211, F_1_451,
|
||||
-F_2_172, F_1_061, -F_0_509, -F_0_601,
|
||||
F_0_899, F_2_562, 0, 0
|
||||
};
|
||||
|
||||
void jsimd_idct_4x4_neon(void *dct_table, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
ISLOW_MULT_TYPE *quantptr = dct_table;
|
||||
|
||||
/* Load DCT coefficients. */
|
||||
int16x8_t row0 = vld1q_s16(coef_block + 0 * DCTSIZE);
|
||||
int16x8_t row1 = vld1q_s16(coef_block + 1 * DCTSIZE);
|
||||
int16x8_t row2 = vld1q_s16(coef_block + 2 * DCTSIZE);
|
||||
int16x8_t row3 = vld1q_s16(coef_block + 3 * DCTSIZE);
|
||||
int16x8_t row5 = vld1q_s16(coef_block + 5 * DCTSIZE);
|
||||
int16x8_t row6 = vld1q_s16(coef_block + 6 * DCTSIZE);
|
||||
int16x8_t row7 = vld1q_s16(coef_block + 7 * DCTSIZE);
|
||||
|
||||
/* Load quantization table values for DC coefficients. */
|
||||
int16x8_t quant_row0 = vld1q_s16(quantptr + 0 * DCTSIZE);
|
||||
/* Dequantize DC coefficients. */
|
||||
row0 = vmulq_s16(row0, quant_row0);
|
||||
|
||||
/* Construct bitmap to test if all AC coefficients are 0. */
|
||||
int16x8_t bitmap = vorrq_s16(row1, row2);
|
||||
bitmap = vorrq_s16(bitmap, row3);
|
||||
bitmap = vorrq_s16(bitmap, row5);
|
||||
bitmap = vorrq_s16(bitmap, row6);
|
||||
bitmap = vorrq_s16(bitmap, row7);
|
||||
|
||||
int64_t left_ac_bitmap = vgetq_lane_s64(vreinterpretq_s64_s16(bitmap), 0);
|
||||
int64_t right_ac_bitmap = vgetq_lane_s64(vreinterpretq_s64_s16(bitmap), 1);
|
||||
|
||||
/* Load constants for IDCT computation. */
|
||||
#ifdef HAVE_VLD1_S16_X3
|
||||
const int16x4x3_t consts = vld1_s16_x3(jsimd_idct_4x4_neon_consts);
|
||||
#else
|
||||
/* GCC does not currently support the intrinsic vld1_<type>_x3(). */
|
||||
const int16x4_t consts1 = vld1_s16(jsimd_idct_4x4_neon_consts);
|
||||
const int16x4_t consts2 = vld1_s16(jsimd_idct_4x4_neon_consts + 4);
|
||||
const int16x4_t consts3 = vld1_s16(jsimd_idct_4x4_neon_consts + 8);
|
||||
const int16x4x3_t consts = { { consts1, consts2, consts3 } };
|
||||
#endif
|
||||
|
||||
if (left_ac_bitmap == 0 && right_ac_bitmap == 0) {
|
||||
/* All AC coefficients are zero.
|
||||
* Compute DC values and duplicate into row vectors 0, 1, 2, and 3.
|
||||
*/
|
||||
int16x8_t dcval = vshlq_n_s16(row0, PASS1_BITS);
|
||||
row0 = dcval;
|
||||
row1 = dcval;
|
||||
row2 = dcval;
|
||||
row3 = dcval;
|
||||
} else if (left_ac_bitmap == 0) {
|
||||
/* AC coefficients are zero for columns 0, 1, 2, and 3.
|
||||
* Compute DC values for these columns.
|
||||
*/
|
||||
int16x4_t dcval = vshl_n_s16(vget_low_s16(row0), PASS1_BITS);
|
||||
|
||||
/* Commence regular IDCT computation for columns 4, 5, 6, and 7. */
|
||||
|
||||
/* Load quantization table. */
|
||||
int16x4_t quant_row1 = vld1_s16(quantptr + 1 * DCTSIZE + 4);
|
||||
int16x4_t quant_row2 = vld1_s16(quantptr + 2 * DCTSIZE + 4);
|
||||
int16x4_t quant_row3 = vld1_s16(quantptr + 3 * DCTSIZE + 4);
|
||||
int16x4_t quant_row5 = vld1_s16(quantptr + 5 * DCTSIZE + 4);
|
||||
int16x4_t quant_row6 = vld1_s16(quantptr + 6 * DCTSIZE + 4);
|
||||
int16x4_t quant_row7 = vld1_s16(quantptr + 7 * DCTSIZE + 4);
|
||||
|
||||
/* Even part */
|
||||
int32x4_t tmp0 = vshll_n_s16(vget_high_s16(row0), CONST_BITS + 1);
|
||||
|
||||
int16x4_t z2 = vmul_s16(vget_high_s16(row2), quant_row2);
|
||||
int16x4_t z3 = vmul_s16(vget_high_s16(row6), quant_row6);
|
||||
|
||||
int32x4_t tmp2 = vmull_lane_s16(z2, consts.val[0], 0);
|
||||
tmp2 = vmlal_lane_s16(tmp2, z3, consts.val[0], 1);
|
||||
|
||||
int32x4_t tmp10 = vaddq_s32(tmp0, tmp2);
|
||||
int32x4_t tmp12 = vsubq_s32(tmp0, tmp2);
|
||||
|
||||
/* Odd part */
|
||||
int16x4_t z1 = vmul_s16(vget_high_s16(row7), quant_row7);
|
||||
z2 = vmul_s16(vget_high_s16(row5), quant_row5);
|
||||
z3 = vmul_s16(vget_high_s16(row3), quant_row3);
|
||||
int16x4_t z4 = vmul_s16(vget_high_s16(row1), quant_row1);
|
||||
|
||||
tmp0 = vmull_lane_s16(z1, consts.val[0], 2);
|
||||
tmp0 = vmlal_lane_s16(tmp0, z2, consts.val[0], 3);
|
||||
tmp0 = vmlal_lane_s16(tmp0, z3, consts.val[1], 0);
|
||||
tmp0 = vmlal_lane_s16(tmp0, z4, consts.val[1], 1);
|
||||
|
||||
tmp2 = vmull_lane_s16(z1, consts.val[1], 2);
|
||||
tmp2 = vmlal_lane_s16(tmp2, z2, consts.val[1], 3);
|
||||
tmp2 = vmlal_lane_s16(tmp2, z3, consts.val[2], 0);
|
||||
tmp2 = vmlal_lane_s16(tmp2, z4, consts.val[2], 1);
|
||||
|
||||
/* Final output stage: descale and narrow to 16-bit. */
|
||||
row0 = vcombine_s16(dcval, vrshrn_n_s32(vaddq_s32(tmp10, tmp2),
|
||||
CONST_BITS - PASS1_BITS + 1));
|
||||
row3 = vcombine_s16(dcval, vrshrn_n_s32(vsubq_s32(tmp10, tmp2),
|
||||
CONST_BITS - PASS1_BITS + 1));
|
||||
row1 = vcombine_s16(dcval, vrshrn_n_s32(vaddq_s32(tmp12, tmp0),
|
||||
CONST_BITS - PASS1_BITS + 1));
|
||||
row2 = vcombine_s16(dcval, vrshrn_n_s32(vsubq_s32(tmp12, tmp0),
|
||||
CONST_BITS - PASS1_BITS + 1));
|
||||
} else if (right_ac_bitmap == 0) {
|
||||
/* AC coefficients are zero for columns 4, 5, 6, and 7.
|
||||
* Compute DC values for these columns.
|
||||
*/
|
||||
int16x4_t dcval = vshl_n_s16(vget_high_s16(row0), PASS1_BITS);
|
||||
|
||||
/* Commence regular IDCT computation for columns 0, 1, 2, and 3. */
|
||||
|
||||
/* Load quantization table. */
|
||||
int16x4_t quant_row1 = vld1_s16(quantptr + 1 * DCTSIZE);
|
||||
int16x4_t quant_row2 = vld1_s16(quantptr + 2 * DCTSIZE);
|
||||
int16x4_t quant_row3 = vld1_s16(quantptr + 3 * DCTSIZE);
|
||||
int16x4_t quant_row5 = vld1_s16(quantptr + 5 * DCTSIZE);
|
||||
int16x4_t quant_row6 = vld1_s16(quantptr + 6 * DCTSIZE);
|
||||
int16x4_t quant_row7 = vld1_s16(quantptr + 7 * DCTSIZE);
|
||||
|
||||
/* Even part */
|
||||
int32x4_t tmp0 = vshll_n_s16(vget_low_s16(row0), CONST_BITS + 1);
|
||||
|
||||
int16x4_t z2 = vmul_s16(vget_low_s16(row2), quant_row2);
|
||||
int16x4_t z3 = vmul_s16(vget_low_s16(row6), quant_row6);
|
||||
|
||||
int32x4_t tmp2 = vmull_lane_s16(z2, consts.val[0], 0);
|
||||
tmp2 = vmlal_lane_s16(tmp2, z3, consts.val[0], 1);
|
||||
|
||||
int32x4_t tmp10 = vaddq_s32(tmp0, tmp2);
|
||||
int32x4_t tmp12 = vsubq_s32(tmp0, tmp2);
|
||||
|
||||
/* Odd part */
|
||||
int16x4_t z1 = vmul_s16(vget_low_s16(row7), quant_row7);
|
||||
z2 = vmul_s16(vget_low_s16(row5), quant_row5);
|
||||
z3 = vmul_s16(vget_low_s16(row3), quant_row3);
|
||||
int16x4_t z4 = vmul_s16(vget_low_s16(row1), quant_row1);
|
||||
|
||||
tmp0 = vmull_lane_s16(z1, consts.val[0], 2);
|
||||
tmp0 = vmlal_lane_s16(tmp0, z2, consts.val[0], 3);
|
||||
tmp0 = vmlal_lane_s16(tmp0, z3, consts.val[1], 0);
|
||||
tmp0 = vmlal_lane_s16(tmp0, z4, consts.val[1], 1);
|
||||
|
||||
tmp2 = vmull_lane_s16(z1, consts.val[1], 2);
|
||||
tmp2 = vmlal_lane_s16(tmp2, z2, consts.val[1], 3);
|
||||
tmp2 = vmlal_lane_s16(tmp2, z3, consts.val[2], 0);
|
||||
tmp2 = vmlal_lane_s16(tmp2, z4, consts.val[2], 1);
|
||||
|
||||
/* Final output stage: descale and narrow to 16-bit. */
|
||||
row0 = vcombine_s16(vrshrn_n_s32(vaddq_s32(tmp10, tmp2),
|
||||
CONST_BITS - PASS1_BITS + 1), dcval);
|
||||
row3 = vcombine_s16(vrshrn_n_s32(vsubq_s32(tmp10, tmp2),
|
||||
CONST_BITS - PASS1_BITS + 1), dcval);
|
||||
row1 = vcombine_s16(vrshrn_n_s32(vaddq_s32(tmp12, tmp0),
|
||||
CONST_BITS - PASS1_BITS + 1), dcval);
|
||||
row2 = vcombine_s16(vrshrn_n_s32(vsubq_s32(tmp12, tmp0),
|
||||
CONST_BITS - PASS1_BITS + 1), dcval);
|
||||
} else {
|
||||
/* All AC coefficients are non-zero; full IDCT calculation required. */
|
||||
int16x8_t quant_row1 = vld1q_s16(quantptr + 1 * DCTSIZE);
|
||||
int16x8_t quant_row2 = vld1q_s16(quantptr + 2 * DCTSIZE);
|
||||
int16x8_t quant_row3 = vld1q_s16(quantptr + 3 * DCTSIZE);
|
||||
int16x8_t quant_row5 = vld1q_s16(quantptr + 5 * DCTSIZE);
|
||||
int16x8_t quant_row6 = vld1q_s16(quantptr + 6 * DCTSIZE);
|
||||
int16x8_t quant_row7 = vld1q_s16(quantptr + 7 * DCTSIZE);
|
||||
|
||||
/* Even part */
|
||||
int32x4_t tmp0_l = vshll_n_s16(vget_low_s16(row0), CONST_BITS + 1);
|
||||
int32x4_t tmp0_h = vshll_n_s16(vget_high_s16(row0), CONST_BITS + 1);
|
||||
|
||||
int16x8_t z2 = vmulq_s16(row2, quant_row2);
|
||||
int16x8_t z3 = vmulq_s16(row6, quant_row6);
|
||||
|
||||
int32x4_t tmp2_l = vmull_lane_s16(vget_low_s16(z2), consts.val[0], 0);
|
||||
int32x4_t tmp2_h = vmull_lane_s16(vget_high_s16(z2), consts.val[0], 0);
|
||||
tmp2_l = vmlal_lane_s16(tmp2_l, vget_low_s16(z3), consts.val[0], 1);
|
||||
tmp2_h = vmlal_lane_s16(tmp2_h, vget_high_s16(z3), consts.val[0], 1);
|
||||
|
||||
int32x4_t tmp10_l = vaddq_s32(tmp0_l, tmp2_l);
|
||||
int32x4_t tmp10_h = vaddq_s32(tmp0_h, tmp2_h);
|
||||
int32x4_t tmp12_l = vsubq_s32(tmp0_l, tmp2_l);
|
||||
int32x4_t tmp12_h = vsubq_s32(tmp0_h, tmp2_h);
|
||||
|
||||
/* Odd part */
|
||||
int16x8_t z1 = vmulq_s16(row7, quant_row7);
|
||||
z2 = vmulq_s16(row5, quant_row5);
|
||||
z3 = vmulq_s16(row3, quant_row3);
|
||||
int16x8_t z4 = vmulq_s16(row1, quant_row1);
|
||||
|
||||
tmp0_l = vmull_lane_s16(vget_low_s16(z1), consts.val[0], 2);
|
||||
tmp0_l = vmlal_lane_s16(tmp0_l, vget_low_s16(z2), consts.val[0], 3);
|
||||
tmp0_l = vmlal_lane_s16(tmp0_l, vget_low_s16(z3), consts.val[1], 0);
|
||||
tmp0_l = vmlal_lane_s16(tmp0_l, vget_low_s16(z4), consts.val[1], 1);
|
||||
tmp0_h = vmull_lane_s16(vget_high_s16(z1), consts.val[0], 2);
|
||||
tmp0_h = vmlal_lane_s16(tmp0_h, vget_high_s16(z2), consts.val[0], 3);
|
||||
tmp0_h = vmlal_lane_s16(tmp0_h, vget_high_s16(z3), consts.val[1], 0);
|
||||
tmp0_h = vmlal_lane_s16(tmp0_h, vget_high_s16(z4), consts.val[1], 1);
|
||||
|
||||
tmp2_l = vmull_lane_s16(vget_low_s16(z1), consts.val[1], 2);
|
||||
tmp2_l = vmlal_lane_s16(tmp2_l, vget_low_s16(z2), consts.val[1], 3);
|
||||
tmp2_l = vmlal_lane_s16(tmp2_l, vget_low_s16(z3), consts.val[2], 0);
|
||||
tmp2_l = vmlal_lane_s16(tmp2_l, vget_low_s16(z4), consts.val[2], 1);
|
||||
tmp2_h = vmull_lane_s16(vget_high_s16(z1), consts.val[1], 2);
|
||||
tmp2_h = vmlal_lane_s16(tmp2_h, vget_high_s16(z2), consts.val[1], 3);
|
||||
tmp2_h = vmlal_lane_s16(tmp2_h, vget_high_s16(z3), consts.val[2], 0);
|
||||
tmp2_h = vmlal_lane_s16(tmp2_h, vget_high_s16(z4), consts.val[2], 1);
|
||||
|
||||
/* Final output stage: descale and narrow to 16-bit. */
|
||||
row0 = vcombine_s16(vrshrn_n_s32(vaddq_s32(tmp10_l, tmp2_l),
|
||||
CONST_BITS - PASS1_BITS + 1),
|
||||
vrshrn_n_s32(vaddq_s32(tmp10_h, tmp2_h),
|
||||
CONST_BITS - PASS1_BITS + 1));
|
||||
row3 = vcombine_s16(vrshrn_n_s32(vsubq_s32(tmp10_l, tmp2_l),
|
||||
CONST_BITS - PASS1_BITS + 1),
|
||||
vrshrn_n_s32(vsubq_s32(tmp10_h, tmp2_h),
|
||||
CONST_BITS - PASS1_BITS + 1));
|
||||
row1 = vcombine_s16(vrshrn_n_s32(vaddq_s32(tmp12_l, tmp0_l),
|
||||
CONST_BITS - PASS1_BITS + 1),
|
||||
vrshrn_n_s32(vaddq_s32(tmp12_h, tmp0_h),
|
||||
CONST_BITS - PASS1_BITS + 1));
|
||||
row2 = vcombine_s16(vrshrn_n_s32(vsubq_s32(tmp12_l, tmp0_l),
|
||||
CONST_BITS - PASS1_BITS + 1),
|
||||
vrshrn_n_s32(vsubq_s32(tmp12_h, tmp0_h),
|
||||
CONST_BITS - PASS1_BITS + 1));
|
||||
}
|
||||
|
||||
/* Transpose 8x4 block to perform IDCT on rows in second pass. */
|
||||
int16x8x2_t row_01 = vtrnq_s16(row0, row1);
|
||||
int16x8x2_t row_23 = vtrnq_s16(row2, row3);
|
||||
|
||||
int32x4x2_t cols_0426 = vtrnq_s32(vreinterpretq_s32_s16(row_01.val[0]),
|
||||
vreinterpretq_s32_s16(row_23.val[0]));
|
||||
int32x4x2_t cols_1537 = vtrnq_s32(vreinterpretq_s32_s16(row_01.val[1]),
|
||||
vreinterpretq_s32_s16(row_23.val[1]));
|
||||
|
||||
int16x4_t col0 = vreinterpret_s16_s32(vget_low_s32(cols_0426.val[0]));
|
||||
int16x4_t col1 = vreinterpret_s16_s32(vget_low_s32(cols_1537.val[0]));
|
||||
int16x4_t col2 = vreinterpret_s16_s32(vget_low_s32(cols_0426.val[1]));
|
||||
int16x4_t col3 = vreinterpret_s16_s32(vget_low_s32(cols_1537.val[1]));
|
||||
int16x4_t col5 = vreinterpret_s16_s32(vget_high_s32(cols_1537.val[0]));
|
||||
int16x4_t col6 = vreinterpret_s16_s32(vget_high_s32(cols_0426.val[1]));
|
||||
int16x4_t col7 = vreinterpret_s16_s32(vget_high_s32(cols_1537.val[1]));
|
||||
|
||||
/* Commence second pass of IDCT. */
|
||||
|
||||
/* Even part */
|
||||
int32x4_t tmp0 = vshll_n_s16(col0, CONST_BITS + 1);
|
||||
int32x4_t tmp2 = vmull_lane_s16(col2, consts.val[0], 0);
|
||||
tmp2 = vmlal_lane_s16(tmp2, col6, consts.val[0], 1);
|
||||
|
||||
int32x4_t tmp10 = vaddq_s32(tmp0, tmp2);
|
||||
int32x4_t tmp12 = vsubq_s32(tmp0, tmp2);
|
||||
|
||||
/* Odd part */
|
||||
tmp0 = vmull_lane_s16(col7, consts.val[0], 2);
|
||||
tmp0 = vmlal_lane_s16(tmp0, col5, consts.val[0], 3);
|
||||
tmp0 = vmlal_lane_s16(tmp0, col3, consts.val[1], 0);
|
||||
tmp0 = vmlal_lane_s16(tmp0, col1, consts.val[1], 1);
|
||||
|
||||
tmp2 = vmull_lane_s16(col7, consts.val[1], 2);
|
||||
tmp2 = vmlal_lane_s16(tmp2, col5, consts.val[1], 3);
|
||||
tmp2 = vmlal_lane_s16(tmp2, col3, consts.val[2], 0);
|
||||
tmp2 = vmlal_lane_s16(tmp2, col1, consts.val[2], 1);
|
||||
|
||||
/* Final output stage: descale and clamp to range [0-255]. */
|
||||
int16x8_t output_cols_02 = vcombine_s16(vaddhn_s32(tmp10, tmp2),
|
||||
vsubhn_s32(tmp12, tmp0));
|
||||
int16x8_t output_cols_13 = vcombine_s16(vaddhn_s32(tmp12, tmp0),
|
||||
vsubhn_s32(tmp10, tmp2));
|
||||
output_cols_02 = vrsraq_n_s16(vdupq_n_s16(CENTERJSAMPLE), output_cols_02,
|
||||
CONST_BITS + PASS1_BITS + 3 + 1 - 16);
|
||||
output_cols_13 = vrsraq_n_s16(vdupq_n_s16(CENTERJSAMPLE), output_cols_13,
|
||||
CONST_BITS + PASS1_BITS + 3 + 1 - 16);
|
||||
/* Narrow to 8-bit and convert to unsigned while zipping 8-bit elements.
|
||||
* An interleaving store completes the transpose.
|
||||
*/
|
||||
uint8x8x2_t output_0123 = vzip_u8(vqmovun_s16(output_cols_02),
|
||||
vqmovun_s16(output_cols_13));
|
||||
uint16x4x2_t output_01_23 = { {
|
||||
vreinterpret_u16_u8(output_0123.val[0]),
|
||||
vreinterpret_u16_u8(output_0123.val[1])
|
||||
} };
|
||||
|
||||
/* Store 4x4 block to memory. */
|
||||
JSAMPROW outptr0 = output_buf[0] + output_col;
|
||||
JSAMPROW outptr1 = output_buf[1] + output_col;
|
||||
JSAMPROW outptr2 = output_buf[2] + output_col;
|
||||
JSAMPROW outptr3 = output_buf[3] + output_col;
|
||||
vst2_lane_u16((uint16_t *)outptr0, output_01_23, 0);
|
||||
vst2_lane_u16((uint16_t *)outptr1, output_01_23, 1);
|
||||
vst2_lane_u16((uint16_t *)outptr2, output_01_23, 2);
|
||||
vst2_lane_u16((uint16_t *)outptr3, output_01_23, 3);
|
||||
}
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* jquanti-neon.c - sample data conversion and quantization (Arm Neon)
|
||||
*
|
||||
* Copyright (C) 2020-2021, Arm Limited. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "../../jinclude.h"
|
||||
#include "../../jpeglib.h"
|
||||
#include "../../jsimd.h"
|
||||
#include "../../jdct.h"
|
||||
#include "../../jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
|
||||
/* After downsampling, the resulting sample values are in the range [0, 255],
|
||||
* but the Discrete Cosine Transform (DCT) operates on values centered around
|
||||
* 0.
|
||||
*
|
||||
* To prepare sample values for the DCT, load samples into a DCT workspace,
|
||||
* subtracting CENTERJSAMPLE (128). The samples, now in the range [-128, 127],
|
||||
* are also widened from 8- to 16-bit.
|
||||
*
|
||||
* The equivalent scalar C function convsamp() can be found in jcdctmgr.c.
|
||||
*/
|
||||
|
||||
void jsimd_convsamp_neon(JSAMPARRAY sample_data, JDIMENSION start_col,
|
||||
DCTELEM *workspace)
|
||||
{
|
||||
uint8x8_t samp_row0 = vld1_u8(sample_data[0] + start_col);
|
||||
uint8x8_t samp_row1 = vld1_u8(sample_data[1] + start_col);
|
||||
uint8x8_t samp_row2 = vld1_u8(sample_data[2] + start_col);
|
||||
uint8x8_t samp_row3 = vld1_u8(sample_data[3] + start_col);
|
||||
uint8x8_t samp_row4 = vld1_u8(sample_data[4] + start_col);
|
||||
uint8x8_t samp_row5 = vld1_u8(sample_data[5] + start_col);
|
||||
uint8x8_t samp_row6 = vld1_u8(sample_data[6] + start_col);
|
||||
uint8x8_t samp_row7 = vld1_u8(sample_data[7] + start_col);
|
||||
|
||||
int16x8_t row0 =
|
||||
vreinterpretq_s16_u16(vsubl_u8(samp_row0, vdup_n_u8(CENTERJSAMPLE)));
|
||||
int16x8_t row1 =
|
||||
vreinterpretq_s16_u16(vsubl_u8(samp_row1, vdup_n_u8(CENTERJSAMPLE)));
|
||||
int16x8_t row2 =
|
||||
vreinterpretq_s16_u16(vsubl_u8(samp_row2, vdup_n_u8(CENTERJSAMPLE)));
|
||||
int16x8_t row3 =
|
||||
vreinterpretq_s16_u16(vsubl_u8(samp_row3, vdup_n_u8(CENTERJSAMPLE)));
|
||||
int16x8_t row4 =
|
||||
vreinterpretq_s16_u16(vsubl_u8(samp_row4, vdup_n_u8(CENTERJSAMPLE)));
|
||||
int16x8_t row5 =
|
||||
vreinterpretq_s16_u16(vsubl_u8(samp_row5, vdup_n_u8(CENTERJSAMPLE)));
|
||||
int16x8_t row6 =
|
||||
vreinterpretq_s16_u16(vsubl_u8(samp_row6, vdup_n_u8(CENTERJSAMPLE)));
|
||||
int16x8_t row7 =
|
||||
vreinterpretq_s16_u16(vsubl_u8(samp_row7, vdup_n_u8(CENTERJSAMPLE)));
|
||||
|
||||
vst1q_s16(workspace + 0 * DCTSIZE, row0);
|
||||
vst1q_s16(workspace + 1 * DCTSIZE, row1);
|
||||
vst1q_s16(workspace + 2 * DCTSIZE, row2);
|
||||
vst1q_s16(workspace + 3 * DCTSIZE, row3);
|
||||
vst1q_s16(workspace + 4 * DCTSIZE, row4);
|
||||
vst1q_s16(workspace + 5 * DCTSIZE, row5);
|
||||
vst1q_s16(workspace + 6 * DCTSIZE, row6);
|
||||
vst1q_s16(workspace + 7 * DCTSIZE, row7);
|
||||
}
|
||||
|
||||
|
||||
/* After the DCT, the resulting array of coefficient values needs to be divided
|
||||
* by an array of quantization values.
|
||||
*
|
||||
* To avoid a slow division operation, the DCT coefficients are multiplied by
|
||||
* the (scaled) reciprocals of the quantization values and then right-shifted.
|
||||
*
|
||||
* The equivalent scalar C function quantize() can be found in jcdctmgr.c.
|
||||
*/
|
||||
|
||||
void jsimd_quantize_neon(JCOEFPTR coef_block, DCTELEM *divisors,
|
||||
DCTELEM *workspace)
|
||||
{
|
||||
JCOEFPTR out_ptr = coef_block;
|
||||
UDCTELEM *recip_ptr = (UDCTELEM *)divisors;
|
||||
UDCTELEM *corr_ptr = (UDCTELEM *)divisors + DCTSIZE2;
|
||||
DCTELEM *shift_ptr = divisors + 3 * DCTSIZE2;
|
||||
int i;
|
||||
|
||||
#if defined(__clang__) && (defined(__aarch64__) || defined(_M_ARM64))
|
||||
#pragma unroll
|
||||
#endif
|
||||
for (i = 0; i < DCTSIZE; i += DCTSIZE / 2) {
|
||||
/* Load DCT coefficients. */
|
||||
int16x8_t row0 = vld1q_s16(workspace + (i + 0) * DCTSIZE);
|
||||
int16x8_t row1 = vld1q_s16(workspace + (i + 1) * DCTSIZE);
|
||||
int16x8_t row2 = vld1q_s16(workspace + (i + 2) * DCTSIZE);
|
||||
int16x8_t row3 = vld1q_s16(workspace + (i + 3) * DCTSIZE);
|
||||
/* Load reciprocals of quantization values. */
|
||||
uint16x8_t recip0 = vld1q_u16(recip_ptr + (i + 0) * DCTSIZE);
|
||||
uint16x8_t recip1 = vld1q_u16(recip_ptr + (i + 1) * DCTSIZE);
|
||||
uint16x8_t recip2 = vld1q_u16(recip_ptr + (i + 2) * DCTSIZE);
|
||||
uint16x8_t recip3 = vld1q_u16(recip_ptr + (i + 3) * DCTSIZE);
|
||||
uint16x8_t corr0 = vld1q_u16(corr_ptr + (i + 0) * DCTSIZE);
|
||||
uint16x8_t corr1 = vld1q_u16(corr_ptr + (i + 1) * DCTSIZE);
|
||||
uint16x8_t corr2 = vld1q_u16(corr_ptr + (i + 2) * DCTSIZE);
|
||||
uint16x8_t corr3 = vld1q_u16(corr_ptr + (i + 3) * DCTSIZE);
|
||||
int16x8_t shift0 = vld1q_s16(shift_ptr + (i + 0) * DCTSIZE);
|
||||
int16x8_t shift1 = vld1q_s16(shift_ptr + (i + 1) * DCTSIZE);
|
||||
int16x8_t shift2 = vld1q_s16(shift_ptr + (i + 2) * DCTSIZE);
|
||||
int16x8_t shift3 = vld1q_s16(shift_ptr + (i + 3) * DCTSIZE);
|
||||
|
||||
/* Extract sign from coefficients. */
|
||||
int16x8_t sign_row0 = vshrq_n_s16(row0, 15);
|
||||
int16x8_t sign_row1 = vshrq_n_s16(row1, 15);
|
||||
int16x8_t sign_row2 = vshrq_n_s16(row2, 15);
|
||||
int16x8_t sign_row3 = vshrq_n_s16(row3, 15);
|
||||
/* Get absolute value of DCT coefficients. */
|
||||
uint16x8_t abs_row0 = vreinterpretq_u16_s16(vabsq_s16(row0));
|
||||
uint16x8_t abs_row1 = vreinterpretq_u16_s16(vabsq_s16(row1));
|
||||
uint16x8_t abs_row2 = vreinterpretq_u16_s16(vabsq_s16(row2));
|
||||
uint16x8_t abs_row3 = vreinterpretq_u16_s16(vabsq_s16(row3));
|
||||
/* Add correction. */
|
||||
abs_row0 = vaddq_u16(abs_row0, corr0);
|
||||
abs_row1 = vaddq_u16(abs_row1, corr1);
|
||||
abs_row2 = vaddq_u16(abs_row2, corr2);
|
||||
abs_row3 = vaddq_u16(abs_row3, corr3);
|
||||
|
||||
/* Multiply DCT coefficients by quantization reciprocals. */
|
||||
int32x4_t row0_l = vreinterpretq_s32_u32(vmull_u16(vget_low_u16(abs_row0),
|
||||
vget_low_u16(recip0)));
|
||||
int32x4_t row0_h = vreinterpretq_s32_u32(vmull_u16(vget_high_u16(abs_row0),
|
||||
vget_high_u16(recip0)));
|
||||
int32x4_t row1_l = vreinterpretq_s32_u32(vmull_u16(vget_low_u16(abs_row1),
|
||||
vget_low_u16(recip1)));
|
||||
int32x4_t row1_h = vreinterpretq_s32_u32(vmull_u16(vget_high_u16(abs_row1),
|
||||
vget_high_u16(recip1)));
|
||||
int32x4_t row2_l = vreinterpretq_s32_u32(vmull_u16(vget_low_u16(abs_row2),
|
||||
vget_low_u16(recip2)));
|
||||
int32x4_t row2_h = vreinterpretq_s32_u32(vmull_u16(vget_high_u16(abs_row2),
|
||||
vget_high_u16(recip2)));
|
||||
int32x4_t row3_l = vreinterpretq_s32_u32(vmull_u16(vget_low_u16(abs_row3),
|
||||
vget_low_u16(recip3)));
|
||||
int32x4_t row3_h = vreinterpretq_s32_u32(vmull_u16(vget_high_u16(abs_row3),
|
||||
vget_high_u16(recip3)));
|
||||
/* Narrow back to 16-bit. */
|
||||
row0 = vcombine_s16(vshrn_n_s32(row0_l, 16), vshrn_n_s32(row0_h, 16));
|
||||
row1 = vcombine_s16(vshrn_n_s32(row1_l, 16), vshrn_n_s32(row1_h, 16));
|
||||
row2 = vcombine_s16(vshrn_n_s32(row2_l, 16), vshrn_n_s32(row2_h, 16));
|
||||
row3 = vcombine_s16(vshrn_n_s32(row3_l, 16), vshrn_n_s32(row3_h, 16));
|
||||
|
||||
/* Since VSHR only supports an immediate as its second argument, negate the
|
||||
* shift value and shift left.
|
||||
*/
|
||||
row0 = vreinterpretq_s16_u16(vshlq_u16(vreinterpretq_u16_s16(row0),
|
||||
vnegq_s16(shift0)));
|
||||
row1 = vreinterpretq_s16_u16(vshlq_u16(vreinterpretq_u16_s16(row1),
|
||||
vnegq_s16(shift1)));
|
||||
row2 = vreinterpretq_s16_u16(vshlq_u16(vreinterpretq_u16_s16(row2),
|
||||
vnegq_s16(shift2)));
|
||||
row3 = vreinterpretq_s16_u16(vshlq_u16(vreinterpretq_u16_s16(row3),
|
||||
vnegq_s16(shift3)));
|
||||
|
||||
/* Restore sign to original product. */
|
||||
row0 = veorq_s16(row0, sign_row0);
|
||||
row0 = vsubq_s16(row0, sign_row0);
|
||||
row1 = veorq_s16(row1, sign_row1);
|
||||
row1 = vsubq_s16(row1, sign_row1);
|
||||
row2 = veorq_s16(row2, sign_row2);
|
||||
row2 = vsubq_s16(row2, sign_row2);
|
||||
row3 = veorq_s16(row3, sign_row3);
|
||||
row3 = vsubq_s16(row3, sign_row3);
|
||||
|
||||
/* Store quantized coefficients to memory. */
|
||||
vst1q_s16(out_ptr + (i + 0) * DCTSIZE, row0);
|
||||
vst1q_s16(out_ptr + (i + 1) * DCTSIZE, row1);
|
||||
vst1q_s16(out_ptr + (i + 2) * DCTSIZE, row2);
|
||||
vst1q_s16(out_ptr + (i + 3) * DCTSIZE, row3);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2020, D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C) 2020-2021, Arm Limited. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#cmakedefine HAVE_VLD1_S16_X3
|
||||
#cmakedefine HAVE_VLD1_U16_X2
|
||||
#cmakedefine HAVE_VLD1Q_U8_X4
|
||||
|
||||
/* Define compiler-independent count-leading-zeros and byte-swap macros */
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define BUILTIN_CLZ(x) _CountLeadingZeros(x)
|
||||
#define BUILTIN_CLZLL(x) _CountLeadingZeros64(x)
|
||||
#define BUILTIN_BSWAP64(x) _byteswap_uint64(x)
|
||||
#elif defined(__clang__) || defined(__GNUC__)
|
||||
#define BUILTIN_CLZ(x) __builtin_clz(x)
|
||||
#define BUILTIN_CLZLL(x) __builtin_clzll(x)
|
||||
#define BUILTIN_BSWAP64(x) __builtin_bswap64(x)
|
||||
#else
|
||||
#error "Unknown compiler"
|
||||
#endif
|
||||
@@ -0,0 +1,578 @@
|
||||
;
|
||||
; jccolext.asm - colorspace conversion (AVX2)
|
||||
;
|
||||
; Copyright (C) 2015, Intel Corporation.
|
||||
; Copyright (C) 2016, D. R. Commander.
|
||||
;
|
||||
; Based on the x86 SIMD extension for IJG JPEG library
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
|
||||
%include "jcolsamp.inc"
|
||||
|
||||
; --------------------------------------------------------------------------
|
||||
;
|
||||
; Convert some rows of samples to the output colorspace.
|
||||
;
|
||||
; GLOBAL(void)
|
||||
; jsimd_rgb_ycc_convert_avx2(JDIMENSION img_width, JSAMPARRAY input_buf,
|
||||
; JSAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
; int num_rows);
|
||||
;
|
||||
|
||||
%define img_width(b) (b) + 8 ; JDIMENSION img_width
|
||||
%define input_buf(b) (b) + 12 ; JSAMPARRAY input_buf
|
||||
%define output_buf(b) (b) + 16 ; JSAMPIMAGE output_buf
|
||||
%define output_row(b) (b) + 20 ; JDIMENSION output_row
|
||||
%define num_rows(b) (b) + 24 ; int num_rows
|
||||
|
||||
%define original_ebp ebp + 0
|
||||
%define wk(i) ebp - (WK_NUM - (i)) * SIZEOF_YMMWORD
|
||||
; ymmword wk[WK_NUM]
|
||||
%define WK_NUM 8
|
||||
%define gotptr wk(0) - SIZEOF_POINTER ; void * gotptr
|
||||
|
||||
align 32
|
||||
GLOBAL_FUNCTION(jsimd_rgb_ycc_convert_avx2)
|
||||
|
||||
EXTN(jsimd_rgb_ycc_convert_avx2):
|
||||
push ebp
|
||||
mov eax, esp ; eax = original ebp
|
||||
sub esp, byte 4
|
||||
and esp, byte (-SIZEOF_YMMWORD) ; align to 256 bits
|
||||
mov [esp], eax
|
||||
mov ebp, esp ; ebp = aligned ebp
|
||||
lea esp, [wk(0)]
|
||||
pushpic eax ; make a room for GOT address
|
||||
push ebx
|
||||
; push ecx ; need not be preserved
|
||||
; push edx ; need not be preserved
|
||||
push esi
|
||||
push edi
|
||||
|
||||
get_GOT ebx ; get GOT address
|
||||
movpic POINTER [gotptr], ebx ; save GOT address
|
||||
|
||||
mov ecx, JDIMENSION [img_width(eax)]
|
||||
test ecx, ecx
|
||||
jz near .return
|
||||
|
||||
push ecx
|
||||
|
||||
mov esi, JSAMPIMAGE [output_buf(eax)]
|
||||
mov ecx, JDIMENSION [output_row(eax)]
|
||||
mov edi, JSAMPARRAY [esi+0*SIZEOF_JSAMPARRAY]
|
||||
mov ebx, JSAMPARRAY [esi+1*SIZEOF_JSAMPARRAY]
|
||||
mov edx, JSAMPARRAY [esi+2*SIZEOF_JSAMPARRAY]
|
||||
lea edi, [edi+ecx*SIZEOF_JSAMPROW]
|
||||
lea ebx, [ebx+ecx*SIZEOF_JSAMPROW]
|
||||
lea edx, [edx+ecx*SIZEOF_JSAMPROW]
|
||||
|
||||
pop ecx
|
||||
|
||||
mov esi, JSAMPARRAY [input_buf(eax)]
|
||||
mov eax, INT [num_rows(eax)]
|
||||
test eax, eax
|
||||
jle near .return
|
||||
alignx 16, 7
|
||||
.rowloop:
|
||||
pushpic eax
|
||||
push edx
|
||||
push ebx
|
||||
push edi
|
||||
push esi
|
||||
push ecx ; col
|
||||
|
||||
mov esi, JSAMPROW [esi] ; inptr
|
||||
mov edi, JSAMPROW [edi] ; outptr0
|
||||
mov ebx, JSAMPROW [ebx] ; outptr1
|
||||
mov edx, JSAMPROW [edx] ; outptr2
|
||||
movpic eax, POINTER [gotptr] ; load GOT address (eax)
|
||||
|
||||
cmp ecx, byte SIZEOF_YMMWORD
|
||||
jae near .columnloop
|
||||
alignx 16, 7
|
||||
|
||||
%if RGB_PIXELSIZE == 3 ; ---------------
|
||||
|
||||
.column_ld1:
|
||||
push eax
|
||||
push edx
|
||||
lea ecx, [ecx+ecx*2] ; imul ecx,RGB_PIXELSIZE
|
||||
test cl, SIZEOF_BYTE
|
||||
jz short .column_ld2
|
||||
sub ecx, byte SIZEOF_BYTE
|
||||
movzx eax, byte [esi+ecx]
|
||||
.column_ld2:
|
||||
test cl, SIZEOF_WORD
|
||||
jz short .column_ld4
|
||||
sub ecx, byte SIZEOF_WORD
|
||||
movzx edx, word [esi+ecx]
|
||||
shl eax, WORD_BIT
|
||||
or eax, edx
|
||||
.column_ld4:
|
||||
vmovd xmmA, eax
|
||||
pop edx
|
||||
pop eax
|
||||
test cl, SIZEOF_DWORD
|
||||
jz short .column_ld8
|
||||
sub ecx, byte SIZEOF_DWORD
|
||||
vmovd xmmF, XMM_DWORD [esi+ecx]
|
||||
vpslldq xmmA, xmmA, SIZEOF_DWORD
|
||||
vpor xmmA, xmmA, xmmF
|
||||
.column_ld8:
|
||||
test cl, SIZEOF_MMWORD
|
||||
jz short .column_ld16
|
||||
sub ecx, byte SIZEOF_MMWORD
|
||||
vmovq xmmB, XMM_MMWORD [esi+ecx]
|
||||
vpslldq xmmA, xmmA, SIZEOF_MMWORD
|
||||
vpor xmmA, xmmA, xmmB
|
||||
.column_ld16:
|
||||
test cl, SIZEOF_XMMWORD
|
||||
jz short .column_ld32
|
||||
sub ecx, byte SIZEOF_XMMWORD
|
||||
vmovdqu xmmB, XMM_MMWORD [esi+ecx]
|
||||
vperm2i128 ymmA, ymmA, ymmA, 1
|
||||
vpor ymmA, ymmB
|
||||
.column_ld32:
|
||||
test cl, SIZEOF_YMMWORD
|
||||
jz short .column_ld64
|
||||
sub ecx, byte SIZEOF_YMMWORD
|
||||
vmovdqa ymmF, ymmA
|
||||
vmovdqu ymmA, YMMWORD [esi+0*SIZEOF_YMMWORD]
|
||||
.column_ld64:
|
||||
test cl, 2*SIZEOF_YMMWORD
|
||||
mov ecx, SIZEOF_YMMWORD
|
||||
jz short .rgb_ycc_cnv
|
||||
vmovdqa ymmB, ymmA
|
||||
vmovdqu ymmA, YMMWORD [esi+0*SIZEOF_YMMWORD]
|
||||
vmovdqu ymmF, YMMWORD [esi+1*SIZEOF_YMMWORD]
|
||||
jmp short .rgb_ycc_cnv
|
||||
alignx 16, 7
|
||||
|
||||
.columnloop:
|
||||
vmovdqu ymmA, YMMWORD [esi+0*SIZEOF_YMMWORD]
|
||||
vmovdqu ymmF, YMMWORD [esi+1*SIZEOF_YMMWORD]
|
||||
vmovdqu ymmB, YMMWORD [esi+2*SIZEOF_YMMWORD]
|
||||
|
||||
.rgb_ycc_cnv:
|
||||
; ymmA=(00 10 20 01 11 21 02 12 22 03 13 23 04 14 24 05
|
||||
; 15 25 06 16 26 07 17 27 08 18 28 09 19 29 0A 1A)
|
||||
; ymmF=(2A 0B 1B 2B 0C 1C 2C 0D 1D 2D 0E 1E 2E 0F 1F 2F
|
||||
; 0G 1G 2G 0H 1H 2H 0I 1I 2I 0J 1J 2J 0K 1K 2K 0L)
|
||||
; ymmB=(1L 2L 0M 1M 2M 0N 1N 2N 0O 1O 2O 0P 1P 2P 0Q 1Q
|
||||
; 2Q 0R 1R 2R 0S 1S 2S 0T 1T 2T 0U 1U 2U 0V 1V 2V)
|
||||
|
||||
vmovdqu ymmC, ymmA
|
||||
vinserti128 ymmA, ymmF, xmmA, 0 ; ymmA=(00 10 20 01 11 21 02 12 22 03 13 23 04 14 24 05
|
||||
; 0G 1G 2G 0H 1H 2H 0I 1I 2I 0J 1J 2J 0K 1K 2K 0L)
|
||||
vinserti128 ymmC, ymmC, xmmB, 0 ; ymmC=(1L 2L 0M 1M 2M 0N 1N 2N 0O 1O 2O 0P 1P 2P 0Q 1Q
|
||||
; 15 25 06 16 26 07 17 27 08 18 28 09 19 29 0A 1A)
|
||||
vinserti128 ymmB, ymmB, xmmF, 0 ; ymmB=(2A 0B 1B 2B 0C 1C 2C 0D 1D 2D 0E 1E 2E 0F 1F 2F
|
||||
; 2Q 0R 1R 2R 0S 1S 2S 0T 1T 2T 0U 1U 2U 0V 1V 2V)
|
||||
vperm2i128 ymmF, ymmC, ymmC, 1 ; ymmF=(15 25 06 16 26 07 17 27 08 18 28 09 19 29 0A 1A
|
||||
; 1L 2L 0M 1M 2M 0N 1N 2N 0O 1O 2O 0P 1P 2P 0Q 1Q)
|
||||
|
||||
vmovdqa ymmG, ymmA
|
||||
vpslldq ymmA, ymmA, 8 ; ymmA=(-- -- -- -- -- -- -- -- 00 10 20 01 11 21 02 12
|
||||
; 22 03 13 23 04 14 24 05 0G 1G 2G 0H 1H 2H 0I 1I)
|
||||
vpsrldq ymmG, ymmG, 8 ; ymmG=(22 03 13 23 04 14 24 05 0G 1G 2G 0H 1H 2H 0I 1I
|
||||
; 2I 0J 1J 2J 0K 1K 2K 0L -- -- -- -- -- -- -- --)
|
||||
|
||||
vpunpckhbw ymmA, ymmA, ymmF ; ymmA=(00 08 10 18 20 28 01 09 11 19 21 29 02 0A 12 1A
|
||||
; 0G 0O 1G 1O 2G 2O 0H 0P 1H 1P 2H 2P 0I 0Q 1I 1Q)
|
||||
vpslldq ymmF, ymmF, 8 ; ymmF=(-- -- -- -- -- -- -- -- 15 25 06 16 26 07 17 27
|
||||
; 08 18 28 09 19 29 0A 1A 1L 2L 0M 1M 2M 0N 1N 2N)
|
||||
|
||||
vpunpcklbw ymmG, ymmG, ymmB ; ymmG=(22 2A 03 0B 13 1B 23 2B 04 0C 14 1C 24 2C 05 0D
|
||||
; 2I 2Q 0J 0R 1J 1R 2J 2R 0K 0S 1K 1S 2K 2S 0L 0T)
|
||||
vpunpckhbw ymmF, ymmF, ymmB ; ymmF=(15 1D 25 2D 06 0E 16 1E 26 2E 07 0F 17 1F 27 2F
|
||||
; 1L 1T 2L 2T 0M 0U 1M 1U 2M 2U 0N 0V 1N 1V 2N 2V)
|
||||
|
||||
vmovdqa ymmD, ymmA
|
||||
vpslldq ymmA, ymmA, 8 ; ymmA=(-- -- -- -- -- -- -- -- 00 08 10 18 20 28 01 09
|
||||
; 11 19 21 29 02 0A 12 1A 0G 0O 1G 1O 2G 2O 0H 0P)
|
||||
vpsrldq ymmD, ymmD, 8 ; ymmD=(11 19 21 29 02 0A 12 1A 0G 0O 1G 1O 2G 2O 0H 0P
|
||||
; 1H 1P 2H 2P 0I 0Q 1I 1Q -- -- -- -- -- -- -- --)
|
||||
|
||||
vpunpckhbw ymmA, ymmA, ymmG ; ymmA=(00 04 08 0C 10 14 18 1C 20 24 28 2C 01 05 09 0D
|
||||
; 0G 0K 0O 0S 1G 1K 1O 1S 2G 2K 2O 2S 0H 0L 0P 0T)
|
||||
vpslldq ymmG, ymmG, 8 ; ymmG=(-- -- -- -- -- -- -- -- 22 2A 03 0B 13 1B 23 2B
|
||||
; 04 0C 14 1C 24 2C 05 0D 2I 2Q 0J 0R 1J 1R 2J 2R)
|
||||
|
||||
vpunpcklbw ymmD, ymmD, ymmF ; ymmD=(11 15 19 1D 21 25 29 2D 02 06 0A 0E 12 16 1A 1E
|
||||
; 1H 1L 1P 1T 2H 2L 2P 2T 0I 0M 0Q 0U 1I 1M 1Q 1U)
|
||||
vpunpckhbw ymmG, ymmG, ymmF ; ymmG=(22 26 2A 2E 03 07 0B 0F 13 17 1B 1F 23 27 2B 2F
|
||||
; 2I 2M 2Q 2U 0J 0N 0R 0V 1J 1N 1R 1V 2J 2N 2R 2V)
|
||||
|
||||
vmovdqa ymmE, ymmA
|
||||
vpslldq ymmA, ymmA, 8 ; ymmA=(-- -- -- -- -- -- -- -- 00 04 08 0C 10 14 18 1C
|
||||
; 20 24 28 2C 01 05 09 0D 0G 0K 0O 0S 1G 1K 1O 1S)
|
||||
vpsrldq ymmE, ymmE, 8 ; ymmE=(20 24 28 2C 01 05 09 0D 0G 0K 0O 0S 1G 1K 1O 1S
|
||||
; 2G 2K 2O 2S 0H 0L 0P 0T -- -- -- -- -- -- -- --)
|
||||
|
||||
vpunpckhbw ymmA, ymmA, ymmD ; ymmA=(00 02 04 06 08 0A 0C 0E 10 12 14 16 18 1A 1C 1E
|
||||
; 0G 0I 0K 0M 0O 0Q 0S 0U 1G 1I 1K 1M 1O 1Q 1S 1U)
|
||||
vpslldq ymmD, ymmD, 8 ; ymmD=(-- -- -- -- -- -- -- -- 11 15 19 1D 21 25 29 2D
|
||||
; 02 06 0A 0E 12 16 1A 1E 1H 1L 1P 1T 2H 2L 2P 2T)
|
||||
|
||||
vpunpcklbw ymmE, ymmE, ymmG ; ymmE=(20 22 24 26 28 2A 2C 2E 01 03 05 07 09 0B 0D 0F
|
||||
; 2G 2I 2K 2M 2O 2Q 2S 2U 0H 0J 0L 0N 0P 0R 0T 0V)
|
||||
vpunpckhbw ymmD, ymmD, ymmG ; ymmD=(11 13 15 17 19 1B 1D 1F 21 23 25 27 29 2B 2D 2F
|
||||
; 1H 1J 1L 1N 1P 1R 1T 1V 2H 2J 2L 2N 2P 2R 2T 2V)
|
||||
|
||||
vpxor ymmH, ymmH, ymmH
|
||||
|
||||
vmovdqa ymmC, ymmA
|
||||
vpunpcklbw ymmA, ymmA, ymmH ; ymmA=(00 02 04 06 08 0A 0C 0E 0G 0I 0K 0M 0O 0Q 0S 0U)
|
||||
vpunpckhbw ymmC, ymmC, ymmH ; ymmC=(10 12 14 16 18 1A 1C 1E 1G 1I 1K 1M 1O 1Q 1S 1U)
|
||||
|
||||
vmovdqa ymmB, ymmE
|
||||
vpunpcklbw ymmE, ymmE, ymmH ; ymmE=(20 22 24 26 28 2A 2C 2E 2G 2I 2K 2M 2O 2Q 2S 2U)
|
||||
vpunpckhbw ymmB, ymmB, ymmH ; ymmB=(01 03 05 07 09 0B 0D 0F 0H 0J 0L 0N 0P 0R 0T 0V)
|
||||
|
||||
vmovdqa ymmF, ymmD
|
||||
vpunpcklbw ymmD, ymmD, ymmH ; ymmD=(11 13 15 17 19 1B 1D 1F 1H 1J 1L 1N 1P 1R 1T 1V)
|
||||
vpunpckhbw ymmF, ymmF, ymmH ; ymmF=(21 23 25 27 29 2B 2D 2F 2H 2J 2L 2N 2P 2R 2T 2V)
|
||||
|
||||
%else ; RGB_PIXELSIZE == 4 ; -----------
|
||||
|
||||
.column_ld1:
|
||||
test cl, SIZEOF_XMMWORD/16
|
||||
jz short .column_ld2
|
||||
sub ecx, byte SIZEOF_XMMWORD/16
|
||||
vmovd xmmA, XMM_DWORD [esi+ecx*RGB_PIXELSIZE]
|
||||
.column_ld2:
|
||||
test cl, SIZEOF_XMMWORD/8
|
||||
jz short .column_ld4
|
||||
sub ecx, byte SIZEOF_XMMWORD/8
|
||||
vmovq xmmF, XMM_MMWORD [esi+ecx*RGB_PIXELSIZE]
|
||||
vpslldq xmmA, xmmA, SIZEOF_MMWORD
|
||||
vpor xmmA, xmmA, xmmF
|
||||
.column_ld4:
|
||||
test cl, SIZEOF_XMMWORD/4
|
||||
jz short .column_ld8
|
||||
sub ecx, byte SIZEOF_XMMWORD/4
|
||||
vmovdqa xmmF, xmmA
|
||||
vperm2i128 ymmF, ymmF, ymmF, 1
|
||||
vmovdqu xmmA, XMMWORD [esi+ecx*RGB_PIXELSIZE]
|
||||
vpor ymmA, ymmA, ymmF
|
||||
.column_ld8:
|
||||
test cl, SIZEOF_XMMWORD/2
|
||||
jz short .column_ld16
|
||||
sub ecx, byte SIZEOF_XMMWORD/2
|
||||
vmovdqa ymmF, ymmA
|
||||
vmovdqu ymmA, YMMWORD [esi+ecx*RGB_PIXELSIZE]
|
||||
.column_ld16:
|
||||
test cl, SIZEOF_XMMWORD
|
||||
mov ecx, SIZEOF_YMMWORD
|
||||
jz short .rgb_ycc_cnv
|
||||
vmovdqa ymmE, ymmA
|
||||
vmovdqa ymmH, ymmF
|
||||
vmovdqu ymmA, YMMWORD [esi+0*SIZEOF_YMMWORD]
|
||||
vmovdqu ymmF, YMMWORD [esi+1*SIZEOF_YMMWORD]
|
||||
jmp short .rgb_ycc_cnv
|
||||
alignx 16, 7
|
||||
|
||||
.columnloop:
|
||||
vmovdqu ymmA, YMMWORD [esi+0*SIZEOF_YMMWORD]
|
||||
vmovdqu ymmF, YMMWORD [esi+1*SIZEOF_YMMWORD]
|
||||
vmovdqu ymmE, YMMWORD [esi+2*SIZEOF_YMMWORD]
|
||||
vmovdqu ymmH, YMMWORD [esi+3*SIZEOF_YMMWORD]
|
||||
|
||||
.rgb_ycc_cnv:
|
||||
; ymmA=(00 10 20 30 01 11 21 31 02 12 22 32 03 13 23 33
|
||||
; 04 14 24 34 05 15 25 35 06 16 26 36 07 17 27 37)
|
||||
; ymmF=(08 18 28 38 09 19 29 39 0A 1A 2A 3A 0B 1B 2B 3B
|
||||
; 0C 1C 2C 3C 0D 1D 2D 3D 0E 1E 2E 3E 0F 1F 2F 3F)
|
||||
; ymmE=(0G 1G 2G 3G 0H 1H 2H 3H 0I 1I 2I 3I 0J 1J 2J 3J
|
||||
; 0K 1K 2K 3K 0L 1L 2L 3L 0M 1M 2M 3M 0N 1N 2N 3N)
|
||||
; ymmH=(0O 1O 2O 3O 0P 1P 2P 3P 0Q 1Q 2Q 3Q 0R 1R 2R 3R
|
||||
; 0S 1S 2S 3S 0T 1T 2T 3T 0U 1U 2U 3U 0V 1V 2V 3V)
|
||||
|
||||
vmovdqa ymmB, ymmA
|
||||
vinserti128 ymmA, ymmA, xmmE, 1 ; ymmA=(00 10 20 30 01 11 21 31 02 12 22 32 03 13 23 33
|
||||
; 0G 1G 2G 3G 0H 1H 2H 3H 0I 1I 2I 3I 0J 1J 2J 3J)
|
||||
vperm2i128 ymmE, ymmB, ymmE, 0x31 ; ymmE=(04 14 24 34 05 15 25 35 06 16 26 36 07 17 27 37
|
||||
; 0K 1K 2K 3K 0L 1L 2L 3L 0M 1M 2M 3M 0N 1N 2N 3N)
|
||||
|
||||
vmovdqa ymmB, ymmF
|
||||
vinserti128 ymmF, ymmF, xmmH, 1 ; ymmF=(08 18 28 38 09 19 29 39 0A 1A 2A 3A 0B 1B 2B 3B
|
||||
; 0O 1O 2O 3O 0P 1P 2P 3P 0Q 1Q 2Q 3Q 0R 1R 2R 3R)
|
||||
vperm2i128 ymmH, ymmB, ymmH, 0x31 ; ymmH=(0C 1C 2C 3C 0D 1D 2D 3D 0E 1E 2E 3E 0F 1F 2F 3F
|
||||
; 0S 1S 2S 3S 0T 1T 2T 3T 0U 1U 2U 3U 0V 1V 2V 3V)
|
||||
|
||||
vmovdqa ymmD, ymmA
|
||||
vpunpcklbw ymmA, ymmA, ymmE ; ymmA=(00 04 10 14 20 24 30 34 01 05 11 15 21 25 31 35
|
||||
; 0G 0K 1G 1K 2G 2K 3G 3K 0H 0L 1H 1L 2H 2L 3H 3L)
|
||||
vpunpckhbw ymmD, ymmD, ymmE ; ymmD=(02 06 12 16 22 26 32 36 03 07 13 17 23 27 33 37
|
||||
; 0I 0M 1I 1M 2I 2M 3I 3M 0J 0N 1J 1N 2J 2N 3J 3N)
|
||||
|
||||
vmovdqa ymmC, ymmF
|
||||
vpunpcklbw ymmF, ymmF, ymmH ; ymmF=(08 0C 18 1C 28 2C 38 3C 09 0D 19 1D 29 2D 39 3D
|
||||
; 0O 0S 1O 1S 2O 2S 3O 3S 0P 0T 1P 1T 2P 2T 3P 3T)
|
||||
vpunpckhbw ymmC, ymmC, ymmH ; ymmC=(0A 0E 1A 1E 2A 2E 3A 3E 0B 0F 1B 1F 2B 2F 3B 3F
|
||||
; 0Q 0U 1Q 1U 2Q 2U 3Q 3U 0R 0V 1R 1V 2R 2V 3R 3V)
|
||||
|
||||
vmovdqa ymmB, ymmA
|
||||
vpunpcklwd ymmA, ymmA, ymmF ; ymmA=(00 04 08 0C 10 14 18 1C 20 24 28 2C 30 34 38 3C
|
||||
; 0G 0K 0O 0S 1G 1K 1O 1S 2G 2K 2O 2S 3G 3K 3O 3S)
|
||||
vpunpckhwd ymmB, ymmB, ymmF ; ymmB=(01 05 09 0D 11 15 19 1D 21 25 29 2D 31 35 39 3D
|
||||
; 0H 0L 0P 0T 1H 1L 1P 1T 2H 2L 2P 2T 3H 3L 3P 3T)
|
||||
|
||||
vmovdqa ymmG, ymmD
|
||||
vpunpcklwd ymmD, ymmD, ymmC ; ymmD=(02 06 0A 0E 12 16 1A 1E 22 26 2A 2E 32 36 3A 3E
|
||||
; 0I 0M 0Q 0U 1I 1M 1Q 1U 2I 2M 2Q 2U 3I 3M 3Q 3U)
|
||||
vpunpckhwd ymmG, ymmG, ymmC ; ymmG=(03 07 0B 0F 13 17 1B 1F 23 27 2B 2F 33 37 3B 3F
|
||||
; 0J 0N 0R 0V 1J 1N 1R 1V 2J 2N 2R 2V 3J 3N 3R 3V)
|
||||
|
||||
vmovdqa ymmE, ymmA
|
||||
vpunpcklbw ymmA, ymmA, ymmD ; ymmA=(00 02 04 06 08 0A 0C 0E 10 12 14 16 18 1A 1C 1E
|
||||
; 0G 0I 0K 0M 0O 0Q 0S 0U 1G 1I 1K 1M 1O 1Q 1S 1U)
|
||||
vpunpckhbw ymmE, ymmE, ymmD ; ymmE=(20 22 24 26 28 2A 2C 2E 30 32 34 36 38 3A 3C 3E
|
||||
; 2G 2I 2K 2M 2O 2Q 2S 2U 3G 3I 3K 3M 3O 3Q 3S 3U)
|
||||
|
||||
vmovdqa ymmH, ymmB
|
||||
vpunpcklbw ymmB, ymmB, ymmG ; ymmB=(01 03 05 07 09 0B 0D 0F 11 13 15 17 19 1B 1D 1F
|
||||
; 0H 0J 0L 0N 0P 0R 0T 0V 1H 1J 1L 1N 1P 1R 1T 1V)
|
||||
vpunpckhbw ymmH, ymmH, ymmG ; ymmH=(21 23 25 27 29 2B 2D 2F 31 33 35 37 39 3B 3D 3F
|
||||
; 2H 2J 2L 2N 2P 2R 2T 2V 3H 3J 3L 3N 3P 3R 3T 3V)
|
||||
|
||||
vpxor ymmF, ymmF, ymmF
|
||||
|
||||
vmovdqa ymmC, ymmA
|
||||
vpunpcklbw ymmA, ymmA, ymmF ; ymmA=(00 02 04 06 08 0A 0C 0E 0G 0I 0K 0M 0O 0Q 0S 0U)
|
||||
vpunpckhbw ymmC, ymmC, ymmF ; ymmC=(10 12 14 16 18 1A 1C 1E 1G 1I 1K 1M 1O 1Q 1S 1U)
|
||||
|
||||
vmovdqa ymmD, ymmB
|
||||
vpunpcklbw ymmB, ymmB, ymmF ; ymmB=(01 03 05 07 09 0B 0D 0F 0H 0J 0L 0N 0P 0R 0T 0V)
|
||||
vpunpckhbw ymmD, ymmD, ymmF ; ymmD=(11 13 15 17 19 1B 1D 1F 1H 1J 1L 1N 1P 1R 1T 1V)
|
||||
|
||||
vmovdqa ymmG, ymmE
|
||||
vpunpcklbw ymmE, ymmE, ymmF ; ymmE=(20 22 24 26 28 2A 2C 2E 2G 2I 2K 2M 2O 2Q 2S 2U)
|
||||
vpunpckhbw ymmG, ymmG, ymmF ; ymmG=(30 32 34 36 38 3A 3C 3E 3G 3I 3K 3M 3O 3Q 3S 3U)
|
||||
|
||||
vpunpcklbw ymmF, ymmF, ymmH
|
||||
vpunpckhbw ymmH, ymmH, ymmH
|
||||
vpsrlw ymmF, ymmF, BYTE_BIT ; ymmF=(21 23 25 27 29 2B 2D 2F 2H 2J 2L 2N 2P 2R 2T 2V)
|
||||
vpsrlw ymmH, ymmH, BYTE_BIT ; ymmH=(31 33 35 37 39 3B 3D 3F 3H 3J 3L 3N 3P 3R 3T 3V)
|
||||
|
||||
%endif ; RGB_PIXELSIZE ; ---------------
|
||||
|
||||
; ymm0=R(02468ACEGIKMOQSU)=RE, ymm2=G(02468ACEGIKMOQSU)=GE, ymm4=B(02468ACEGIKMOQSU)=BE
|
||||
; ymm1=R(13579BDFHJLNPRTV)=RO, ymm3=G(13579BDFHJLNPRTV)=GO, ymm5=B(13579BDFHJLNPRTV)=BO
|
||||
|
||||
; (Original)
|
||||
; Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
|
||||
; Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
|
||||
; Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
|
||||
;
|
||||
; (This implementation)
|
||||
; Y = 0.29900 * R + 0.33700 * G + 0.11400 * B + 0.25000 * G
|
||||
; Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
|
||||
; Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
|
||||
|
||||
vmovdqa YMMWORD [wk(0)], ymm0 ; wk(0)=RE
|
||||
vmovdqa YMMWORD [wk(1)], ymm1 ; wk(1)=RO
|
||||
vmovdqa YMMWORD [wk(2)], ymm4 ; wk(2)=BE
|
||||
vmovdqa YMMWORD [wk(3)], ymm5 ; wk(3)=BO
|
||||
|
||||
vmovdqa ymm6, ymm1
|
||||
vpunpcklwd ymm1, ymm1, ymm3
|
||||
vpunpckhwd ymm6, ymm6, ymm3
|
||||
vmovdqa ymm7, ymm1
|
||||
vmovdqa ymm4, ymm6
|
||||
vpmaddwd ymm1, ymm1, [GOTOFF(eax,PW_F0299_F0337)] ; ymm1=ROL*FIX(0.299)+GOL*FIX(0.337)
|
||||
vpmaddwd ymm6, ymm6, [GOTOFF(eax,PW_F0299_F0337)] ; ymm6=ROH*FIX(0.299)+GOH*FIX(0.337)
|
||||
vpmaddwd ymm7, ymm7, [GOTOFF(eax,PW_MF016_MF033)] ; ymm7=ROL*-FIX(0.168)+GOL*-FIX(0.331)
|
||||
vpmaddwd ymm4, ymm4, [GOTOFF(eax,PW_MF016_MF033)] ; ymm4=ROH*-FIX(0.168)+GOH*-FIX(0.331)
|
||||
|
||||
vmovdqa YMMWORD [wk(4)], ymm1 ; wk(4)=ROL*FIX(0.299)+GOL*FIX(0.337)
|
||||
vmovdqa YMMWORD [wk(5)], ymm6 ; wk(5)=ROH*FIX(0.299)+GOH*FIX(0.337)
|
||||
|
||||
vpxor ymm1, ymm1, ymm1
|
||||
vpxor ymm6, ymm6, ymm6
|
||||
vpunpcklwd ymm1, ymm1, ymm5 ; ymm1=BOL
|
||||
vpunpckhwd ymm6, ymm6, ymm5 ; ymm6=BOH
|
||||
vpsrld ymm1, ymm1, 1 ; ymm1=BOL*FIX(0.500)
|
||||
vpsrld ymm6, ymm6, 1 ; ymm6=BOH*FIX(0.500)
|
||||
|
||||
vmovdqa ymm5, [GOTOFF(eax,PD_ONEHALFM1_CJ)] ; ymm5=[PD_ONEHALFM1_CJ]
|
||||
|
||||
vpaddd ymm7, ymm7, ymm1
|
||||
vpaddd ymm4, ymm4, ymm6
|
||||
vpaddd ymm7, ymm7, ymm5
|
||||
vpaddd ymm4, ymm4, ymm5
|
||||
vpsrld ymm7, ymm7, SCALEBITS ; ymm7=CbOL
|
||||
vpsrld ymm4, ymm4, SCALEBITS ; ymm4=CbOH
|
||||
vpackssdw ymm7, ymm7, ymm4 ; ymm7=CbO
|
||||
|
||||
vmovdqa ymm1, YMMWORD [wk(2)] ; ymm1=BE
|
||||
|
||||
vmovdqa ymm6, ymm0
|
||||
vpunpcklwd ymm0, ymm0, ymm2
|
||||
vpunpckhwd ymm6, ymm6, ymm2
|
||||
vmovdqa ymm5, ymm0
|
||||
vmovdqa ymm4, ymm6
|
||||
vpmaddwd ymm0, ymm0, [GOTOFF(eax,PW_F0299_F0337)] ; ymm0=REL*FIX(0.299)+GEL*FIX(0.337)
|
||||
vpmaddwd ymm6, ymm6, [GOTOFF(eax,PW_F0299_F0337)] ; ymm6=REH*FIX(0.299)+GEH*FIX(0.337)
|
||||
vpmaddwd ymm5, ymm5, [GOTOFF(eax,PW_MF016_MF033)] ; ymm5=REL*-FIX(0.168)+GEL*-FIX(0.331)
|
||||
vpmaddwd ymm4, ymm4, [GOTOFF(eax,PW_MF016_MF033)] ; ymm4=REH*-FIX(0.168)+GEH*-FIX(0.331)
|
||||
|
||||
vmovdqa YMMWORD [wk(6)], ymm0 ; wk(6)=REL*FIX(0.299)+GEL*FIX(0.337)
|
||||
vmovdqa YMMWORD [wk(7)], ymm6 ; wk(7)=REH*FIX(0.299)+GEH*FIX(0.337)
|
||||
|
||||
vpxor ymm0, ymm0, ymm0
|
||||
vpxor ymm6, ymm6, ymm6
|
||||
vpunpcklwd ymm0, ymm0, ymm1 ; ymm0=BEL
|
||||
vpunpckhwd ymm6, ymm6, ymm1 ; ymm6=BEH
|
||||
vpsrld ymm0, ymm0, 1 ; ymm0=BEL*FIX(0.500)
|
||||
vpsrld ymm6, ymm6, 1 ; ymm6=BEH*FIX(0.500)
|
||||
|
||||
vmovdqa ymm1, [GOTOFF(eax,PD_ONEHALFM1_CJ)] ; ymm1=[PD_ONEHALFM1_CJ]
|
||||
|
||||
vpaddd ymm5, ymm5, ymm0
|
||||
vpaddd ymm4, ymm4, ymm6
|
||||
vpaddd ymm5, ymm5, ymm1
|
||||
vpaddd ymm4, ymm4, ymm1
|
||||
vpsrld ymm5, ymm5, SCALEBITS ; ymm5=CbEL
|
||||
vpsrld ymm4, ymm4, SCALEBITS ; ymm4=CbEH
|
||||
vpackssdw ymm5, ymm5, ymm4 ; ymm5=CbE
|
||||
|
||||
vpsllw ymm7, ymm7, BYTE_BIT
|
||||
vpor ymm5, ymm5, ymm7 ; ymm5=Cb
|
||||
vmovdqu YMMWORD [ebx], ymm5 ; Save Cb
|
||||
|
||||
vmovdqa ymm0, YMMWORD [wk(3)] ; ymm0=BO
|
||||
vmovdqa ymm6, YMMWORD [wk(2)] ; ymm6=BE
|
||||
vmovdqa ymm1, YMMWORD [wk(1)] ; ymm1=RO
|
||||
|
||||
vmovdqa ymm4, ymm0
|
||||
vpunpcklwd ymm0, ymm0, ymm3
|
||||
vpunpckhwd ymm4, ymm4, ymm3
|
||||
vmovdqa ymm7, ymm0
|
||||
vmovdqa ymm5, ymm4
|
||||
vpmaddwd ymm0, ymm0, [GOTOFF(eax,PW_F0114_F0250)] ; ymm0=BOL*FIX(0.114)+GOL*FIX(0.250)
|
||||
vpmaddwd ymm4, ymm4, [GOTOFF(eax,PW_F0114_F0250)] ; ymm4=BOH*FIX(0.114)+GOH*FIX(0.250)
|
||||
vpmaddwd ymm7, ymm7, [GOTOFF(eax,PW_MF008_MF041)] ; ymm7=BOL*-FIX(0.081)+GOL*-FIX(0.418)
|
||||
vpmaddwd ymm5, ymm5, [GOTOFF(eax,PW_MF008_MF041)] ; ymm5=BOH*-FIX(0.081)+GOH*-FIX(0.418)
|
||||
|
||||
vmovdqa ymm3, [GOTOFF(eax,PD_ONEHALF)] ; ymm3=[PD_ONEHALF]
|
||||
|
||||
vpaddd ymm0, ymm0, YMMWORD [wk(4)]
|
||||
vpaddd ymm4, ymm4, YMMWORD [wk(5)]
|
||||
vpaddd ymm0, ymm0, ymm3
|
||||
vpaddd ymm4, ymm4, ymm3
|
||||
vpsrld ymm0, ymm0, SCALEBITS ; ymm0=YOL
|
||||
vpsrld ymm4, ymm4, SCALEBITS ; ymm4=YOH
|
||||
vpackssdw ymm0, ymm0, ymm4 ; ymm0=YO
|
||||
|
||||
vpxor ymm3, ymm3, ymm3
|
||||
vpxor ymm4, ymm4, ymm4
|
||||
vpunpcklwd ymm3, ymm3, ymm1 ; ymm3=ROL
|
||||
vpunpckhwd ymm4, ymm4, ymm1 ; ymm4=ROH
|
||||
vpsrld ymm3, ymm3, 1 ; ymm3=ROL*FIX(0.500)
|
||||
vpsrld ymm4, ymm4, 1 ; ymm4=ROH*FIX(0.500)
|
||||
|
||||
vmovdqa ymm1, [GOTOFF(eax,PD_ONEHALFM1_CJ)] ; ymm1=[PD_ONEHALFM1_CJ]
|
||||
|
||||
vpaddd ymm7, ymm7, ymm3
|
||||
vpaddd ymm5, ymm5, ymm4
|
||||
vpaddd ymm7, ymm7, ymm1
|
||||
vpaddd ymm5, ymm5, ymm1
|
||||
vpsrld ymm7, ymm7, SCALEBITS ; ymm7=CrOL
|
||||
vpsrld ymm5, ymm5, SCALEBITS ; ymm5=CrOH
|
||||
vpackssdw ymm7, ymm7, ymm5 ; ymm7=CrO
|
||||
|
||||
vmovdqa ymm3, YMMWORD [wk(0)] ; ymm3=RE
|
||||
|
||||
vmovdqa ymm4, ymm6
|
||||
vpunpcklwd ymm6, ymm6, ymm2
|
||||
vpunpckhwd ymm4, ymm4, ymm2
|
||||
vmovdqa ymm1, ymm6
|
||||
vmovdqa ymm5, ymm4
|
||||
vpmaddwd ymm6, ymm6, [GOTOFF(eax,PW_F0114_F0250)] ; ymm6=BEL*FIX(0.114)+GEL*FIX(0.250)
|
||||
vpmaddwd ymm4, ymm4, [GOTOFF(eax,PW_F0114_F0250)] ; ymm4=BEH*FIX(0.114)+GEH*FIX(0.250)
|
||||
vpmaddwd ymm1, ymm1, [GOTOFF(eax,PW_MF008_MF041)] ; ymm1=BEL*-FIX(0.081)+GEL*-FIX(0.418)
|
||||
vpmaddwd ymm5, ymm5, [GOTOFF(eax,PW_MF008_MF041)] ; ymm5=BEH*-FIX(0.081)+GEH*-FIX(0.418)
|
||||
|
||||
vmovdqa ymm2, [GOTOFF(eax,PD_ONEHALF)] ; ymm2=[PD_ONEHALF]
|
||||
|
||||
vpaddd ymm6, ymm6, YMMWORD [wk(6)]
|
||||
vpaddd ymm4, ymm4, YMMWORD [wk(7)]
|
||||
vpaddd ymm6, ymm6, ymm2
|
||||
vpaddd ymm4, ymm4, ymm2
|
||||
vpsrld ymm6, ymm6, SCALEBITS ; ymm6=YEL
|
||||
vpsrld ymm4, ymm4, SCALEBITS ; ymm4=YEH
|
||||
vpackssdw ymm6, ymm6, ymm4 ; ymm6=YE
|
||||
|
||||
vpsllw ymm0, ymm0, BYTE_BIT
|
||||
vpor ymm6, ymm6, ymm0 ; ymm6=Y
|
||||
vmovdqu YMMWORD [edi], ymm6 ; Save Y
|
||||
|
||||
vpxor ymm2, ymm2, ymm2
|
||||
vpxor ymm4, ymm4, ymm4
|
||||
vpunpcklwd ymm2, ymm2, ymm3 ; ymm2=REL
|
||||
vpunpckhwd ymm4, ymm4, ymm3 ; ymm4=REH
|
||||
vpsrld ymm2, ymm2, 1 ; ymm2=REL*FIX(0.500)
|
||||
vpsrld ymm4, ymm4, 1 ; ymm4=REH*FIX(0.500)
|
||||
|
||||
vmovdqa ymm0, [GOTOFF(eax,PD_ONEHALFM1_CJ)] ; ymm0=[PD_ONEHALFM1_CJ]
|
||||
|
||||
vpaddd ymm1, ymm1, ymm2
|
||||
vpaddd ymm5, ymm5, ymm4
|
||||
vpaddd ymm1, ymm1, ymm0
|
||||
vpaddd ymm5, ymm5, ymm0
|
||||
vpsrld ymm1, ymm1, SCALEBITS ; ymm1=CrEL
|
||||
vpsrld ymm5, ymm5, SCALEBITS ; ymm5=CrEH
|
||||
vpackssdw ymm1, ymm1, ymm5 ; ymm1=CrE
|
||||
|
||||
vpsllw ymm7, ymm7, BYTE_BIT
|
||||
vpor ymm1, ymm1, ymm7 ; ymm1=Cr
|
||||
vmovdqu YMMWORD [edx], ymm1 ; Save Cr
|
||||
|
||||
sub ecx, byte SIZEOF_YMMWORD
|
||||
add esi, RGB_PIXELSIZE*SIZEOF_YMMWORD ; inptr
|
||||
add edi, byte SIZEOF_YMMWORD ; outptr0
|
||||
add ebx, byte SIZEOF_YMMWORD ; outptr1
|
||||
add edx, byte SIZEOF_YMMWORD ; outptr2
|
||||
cmp ecx, byte SIZEOF_YMMWORD
|
||||
jae near .columnloop
|
||||
test ecx, ecx
|
||||
jnz near .column_ld1
|
||||
|
||||
pop ecx ; col
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebx
|
||||
pop edx
|
||||
poppic eax
|
||||
|
||||
add esi, byte SIZEOF_JSAMPROW ; input_buf
|
||||
add edi, byte SIZEOF_JSAMPROW
|
||||
add ebx, byte SIZEOF_JSAMPROW
|
||||
add edx, byte SIZEOF_JSAMPROW
|
||||
dec eax ; num_rows
|
||||
jg near .rowloop
|
||||
|
||||
.return:
|
||||
vzeroupper
|
||||
pop edi
|
||||
pop esi
|
||||
; pop edx ; need not be preserved
|
||||
; pop ecx ; need not be preserved
|
||||
pop ebx
|
||||
mov esp, ebp ; esp <- aligned ebp
|
||||
pop esp ; esp <- original ebp
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
; For some reason, the OS X linker does not honor the request to align the
|
||||
; segment unless we do this.
|
||||
align 32
|
||||
@@ -0,0 +1,476 @@
|
||||
;
|
||||
; jccolext.asm - colorspace conversion (MMX)
|
||||
;
|
||||
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
; Copyright (C) 2016, D. R. Commander.
|
||||
;
|
||||
; Based on the x86 SIMD extension for IJG JPEG library
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
|
||||
%include "jcolsamp.inc"
|
||||
|
||||
; --------------------------------------------------------------------------
|
||||
;
|
||||
; Convert some rows of samples to the output colorspace.
|
||||
;
|
||||
; GLOBAL(void)
|
||||
; jsimd_rgb_ycc_convert_mmx(JDIMENSION img_width, JSAMPARRAY input_buf,
|
||||
; JSAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
; int num_rows);
|
||||
;
|
||||
|
||||
%define img_width(b) (b) + 8 ; JDIMENSION img_width
|
||||
%define input_buf(b) (b) + 12 ; JSAMPARRAY input_buf
|
||||
%define output_buf(b) (b) + 16 ; JSAMPIMAGE output_buf
|
||||
%define output_row(b) (b) + 20 ; JDIMENSION output_row
|
||||
%define num_rows(b) (b) + 24 ; int num_rows
|
||||
|
||||
%define original_ebp ebp + 0
|
||||
%define wk(i) ebp - (WK_NUM - (i)) * SIZEOF_MMWORD
|
||||
; mmword wk[WK_NUM]
|
||||
%define WK_NUM 8
|
||||
%define gotptr wk(0) - SIZEOF_POINTER ; void * gotptr
|
||||
|
||||
align 32
|
||||
GLOBAL_FUNCTION(jsimd_rgb_ycc_convert_mmx)
|
||||
|
||||
EXTN(jsimd_rgb_ycc_convert_mmx):
|
||||
push ebp
|
||||
mov eax, esp ; eax = original ebp
|
||||
sub esp, byte 4
|
||||
and esp, byte (-SIZEOF_MMWORD) ; align to 64 bits
|
||||
mov [esp], eax
|
||||
mov ebp, esp ; ebp = aligned ebp
|
||||
lea esp, [wk(0)]
|
||||
pushpic eax ; make a room for GOT address
|
||||
push ebx
|
||||
; push ecx ; need not be preserved
|
||||
; push edx ; need not be preserved
|
||||
push esi
|
||||
push edi
|
||||
|
||||
get_GOT ebx ; get GOT address
|
||||
movpic POINTER [gotptr], ebx ; save GOT address
|
||||
|
||||
mov ecx, JDIMENSION [img_width(eax)] ; num_cols
|
||||
test ecx, ecx
|
||||
jz near .return
|
||||
|
||||
push ecx
|
||||
|
||||
mov esi, JSAMPIMAGE [output_buf(eax)]
|
||||
mov ecx, JDIMENSION [output_row(eax)]
|
||||
mov edi, JSAMPARRAY [esi+0*SIZEOF_JSAMPARRAY]
|
||||
mov ebx, JSAMPARRAY [esi+1*SIZEOF_JSAMPARRAY]
|
||||
mov edx, JSAMPARRAY [esi+2*SIZEOF_JSAMPARRAY]
|
||||
lea edi, [edi+ecx*SIZEOF_JSAMPROW]
|
||||
lea ebx, [ebx+ecx*SIZEOF_JSAMPROW]
|
||||
lea edx, [edx+ecx*SIZEOF_JSAMPROW]
|
||||
|
||||
pop ecx
|
||||
|
||||
mov esi, JSAMPARRAY [input_buf(eax)]
|
||||
mov eax, INT [num_rows(eax)]
|
||||
test eax, eax
|
||||
jle near .return
|
||||
alignx 16, 7
|
||||
.rowloop:
|
||||
pushpic eax
|
||||
push edx
|
||||
push ebx
|
||||
push edi
|
||||
push esi
|
||||
push ecx ; col
|
||||
|
||||
mov esi, JSAMPROW [esi] ; inptr
|
||||
mov edi, JSAMPROW [edi] ; outptr0
|
||||
mov ebx, JSAMPROW [ebx] ; outptr1
|
||||
mov edx, JSAMPROW [edx] ; outptr2
|
||||
movpic eax, POINTER [gotptr] ; load GOT address (eax)
|
||||
|
||||
cmp ecx, byte SIZEOF_MMWORD
|
||||
jae short .columnloop
|
||||
alignx 16, 7
|
||||
|
||||
%if RGB_PIXELSIZE == 3 ; ---------------
|
||||
|
||||
.column_ld1:
|
||||
push eax
|
||||
push edx
|
||||
lea ecx, [ecx+ecx*2] ; imul ecx,RGB_PIXELSIZE
|
||||
test cl, SIZEOF_BYTE
|
||||
jz short .column_ld2
|
||||
sub ecx, byte SIZEOF_BYTE
|
||||
xor eax, eax
|
||||
mov al, byte [esi+ecx]
|
||||
.column_ld2:
|
||||
test cl, SIZEOF_WORD
|
||||
jz short .column_ld4
|
||||
sub ecx, byte SIZEOF_WORD
|
||||
xor edx, edx
|
||||
mov dx, word [esi+ecx]
|
||||
shl eax, WORD_BIT
|
||||
or eax, edx
|
||||
.column_ld4:
|
||||
movd mmA, eax
|
||||
pop edx
|
||||
pop eax
|
||||
test cl, SIZEOF_DWORD
|
||||
jz short .column_ld8
|
||||
sub ecx, byte SIZEOF_DWORD
|
||||
movd mmG, dword [esi+ecx]
|
||||
psllq mmA, DWORD_BIT
|
||||
por mmA, mmG
|
||||
.column_ld8:
|
||||
test cl, SIZEOF_MMWORD
|
||||
jz short .column_ld16
|
||||
movq mmG, mmA
|
||||
movq mmA, MMWORD [esi+0*SIZEOF_MMWORD]
|
||||
mov ecx, SIZEOF_MMWORD
|
||||
jmp short .rgb_ycc_cnv
|
||||
.column_ld16:
|
||||
test cl, 2*SIZEOF_MMWORD
|
||||
mov ecx, SIZEOF_MMWORD
|
||||
jz short .rgb_ycc_cnv
|
||||
movq mmF, mmA
|
||||
movq mmA, MMWORD [esi+0*SIZEOF_MMWORD]
|
||||
movq mmG, MMWORD [esi+1*SIZEOF_MMWORD]
|
||||
jmp short .rgb_ycc_cnv
|
||||
alignx 16, 7
|
||||
|
||||
.columnloop:
|
||||
movq mmA, MMWORD [esi+0*SIZEOF_MMWORD]
|
||||
movq mmG, MMWORD [esi+1*SIZEOF_MMWORD]
|
||||
movq mmF, MMWORD [esi+2*SIZEOF_MMWORD]
|
||||
|
||||
.rgb_ycc_cnv:
|
||||
; mmA=(00 10 20 01 11 21 02 12)
|
||||
; mmG=(22 03 13 23 04 14 24 05)
|
||||
; mmF=(15 25 06 16 26 07 17 27)
|
||||
|
||||
movq mmD, mmA
|
||||
psllq mmA, 4*BYTE_BIT ; mmA=(-- -- -- -- 00 10 20 01)
|
||||
psrlq mmD, 4*BYTE_BIT ; mmD=(11 21 02 12 -- -- -- --)
|
||||
|
||||
punpckhbw mmA, mmG ; mmA=(00 04 10 14 20 24 01 05)
|
||||
psllq mmG, 4*BYTE_BIT ; mmG=(-- -- -- -- 22 03 13 23)
|
||||
|
||||
punpcklbw mmD, mmF ; mmD=(11 15 21 25 02 06 12 16)
|
||||
punpckhbw mmG, mmF ; mmG=(22 26 03 07 13 17 23 27)
|
||||
|
||||
movq mmE, mmA
|
||||
psllq mmA, 4*BYTE_BIT ; mmA=(-- -- -- -- 00 04 10 14)
|
||||
psrlq mmE, 4*BYTE_BIT ; mmE=(20 24 01 05 -- -- -- --)
|
||||
|
||||
punpckhbw mmA, mmD ; mmA=(00 02 04 06 10 12 14 16)
|
||||
psllq mmD, 4*BYTE_BIT ; mmD=(-- -- -- -- 11 15 21 25)
|
||||
|
||||
punpcklbw mmE, mmG ; mmE=(20 22 24 26 01 03 05 07)
|
||||
punpckhbw mmD, mmG ; mmD=(11 13 15 17 21 23 25 27)
|
||||
|
||||
pxor mmH, mmH
|
||||
|
||||
movq mmC, mmA
|
||||
punpcklbw mmA, mmH ; mmA=(00 02 04 06)
|
||||
punpckhbw mmC, mmH ; mmC=(10 12 14 16)
|
||||
|
||||
movq mmB, mmE
|
||||
punpcklbw mmE, mmH ; mmE=(20 22 24 26)
|
||||
punpckhbw mmB, mmH ; mmB=(01 03 05 07)
|
||||
|
||||
movq mmF, mmD
|
||||
punpcklbw mmD, mmH ; mmD=(11 13 15 17)
|
||||
punpckhbw mmF, mmH ; mmF=(21 23 25 27)
|
||||
|
||||
%else ; RGB_PIXELSIZE == 4 ; -----------
|
||||
|
||||
.column_ld1:
|
||||
test cl, SIZEOF_MMWORD/8
|
||||
jz short .column_ld2
|
||||
sub ecx, byte SIZEOF_MMWORD/8
|
||||
movd mmA, dword [esi+ecx*RGB_PIXELSIZE]
|
||||
.column_ld2:
|
||||
test cl, SIZEOF_MMWORD/4
|
||||
jz short .column_ld4
|
||||
sub ecx, byte SIZEOF_MMWORD/4
|
||||
movq mmF, mmA
|
||||
movq mmA, MMWORD [esi+ecx*RGB_PIXELSIZE]
|
||||
.column_ld4:
|
||||
test cl, SIZEOF_MMWORD/2
|
||||
mov ecx, SIZEOF_MMWORD
|
||||
jz short .rgb_ycc_cnv
|
||||
movq mmD, mmA
|
||||
movq mmC, mmF
|
||||
movq mmA, MMWORD [esi+0*SIZEOF_MMWORD]
|
||||
movq mmF, MMWORD [esi+1*SIZEOF_MMWORD]
|
||||
jmp short .rgb_ycc_cnv
|
||||
alignx 16, 7
|
||||
|
||||
.columnloop:
|
||||
movq mmA, MMWORD [esi+0*SIZEOF_MMWORD]
|
||||
movq mmF, MMWORD [esi+1*SIZEOF_MMWORD]
|
||||
movq mmD, MMWORD [esi+2*SIZEOF_MMWORD]
|
||||
movq mmC, MMWORD [esi+3*SIZEOF_MMWORD]
|
||||
|
||||
.rgb_ycc_cnv:
|
||||
; mmA=(00 10 20 30 01 11 21 31)
|
||||
; mmF=(02 12 22 32 03 13 23 33)
|
||||
; mmD=(04 14 24 34 05 15 25 35)
|
||||
; mmC=(06 16 26 36 07 17 27 37)
|
||||
|
||||
movq mmB, mmA
|
||||
punpcklbw mmA, mmF ; mmA=(00 02 10 12 20 22 30 32)
|
||||
punpckhbw mmB, mmF ; mmB=(01 03 11 13 21 23 31 33)
|
||||
|
||||
movq mmG, mmD
|
||||
punpcklbw mmD, mmC ; mmD=(04 06 14 16 24 26 34 36)
|
||||
punpckhbw mmG, mmC ; mmG=(05 07 15 17 25 27 35 37)
|
||||
|
||||
movq mmE, mmA
|
||||
punpcklwd mmA, mmD ; mmA=(00 02 04 06 10 12 14 16)
|
||||
punpckhwd mmE, mmD ; mmE=(20 22 24 26 30 32 34 36)
|
||||
|
||||
movq mmH, mmB
|
||||
punpcklwd mmB, mmG ; mmB=(01 03 05 07 11 13 15 17)
|
||||
punpckhwd mmH, mmG ; mmH=(21 23 25 27 31 33 35 37)
|
||||
|
||||
pxor mmF, mmF
|
||||
|
||||
movq mmC, mmA
|
||||
punpcklbw mmA, mmF ; mmA=(00 02 04 06)
|
||||
punpckhbw mmC, mmF ; mmC=(10 12 14 16)
|
||||
|
||||
movq mmD, mmB
|
||||
punpcklbw mmB, mmF ; mmB=(01 03 05 07)
|
||||
punpckhbw mmD, mmF ; mmD=(11 13 15 17)
|
||||
|
||||
movq mmG, mmE
|
||||
punpcklbw mmE, mmF ; mmE=(20 22 24 26)
|
||||
punpckhbw mmG, mmF ; mmG=(30 32 34 36)
|
||||
|
||||
punpcklbw mmF, mmH
|
||||
punpckhbw mmH, mmH
|
||||
psrlw mmF, BYTE_BIT ; mmF=(21 23 25 27)
|
||||
psrlw mmH, BYTE_BIT ; mmH=(31 33 35 37)
|
||||
|
||||
%endif ; RGB_PIXELSIZE ; ---------------
|
||||
|
||||
; mm0=(R0 R2 R4 R6)=RE, mm2=(G0 G2 G4 G6)=GE, mm4=(B0 B2 B4 B6)=BE
|
||||
; mm1=(R1 R3 R5 R7)=RO, mm3=(G1 G3 G5 G7)=GO, mm5=(B1 B3 B5 B7)=BO
|
||||
|
||||
; (Original)
|
||||
; Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
|
||||
; Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
|
||||
; Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
|
||||
;
|
||||
; (This implementation)
|
||||
; Y = 0.29900 * R + 0.33700 * G + 0.11400 * B + 0.25000 * G
|
||||
; Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
|
||||
; Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
|
||||
|
||||
movq MMWORD [wk(0)], mm0 ; wk(0)=RE
|
||||
movq MMWORD [wk(1)], mm1 ; wk(1)=RO
|
||||
movq MMWORD [wk(2)], mm4 ; wk(2)=BE
|
||||
movq MMWORD [wk(3)], mm5 ; wk(3)=BO
|
||||
|
||||
movq mm6, mm1
|
||||
punpcklwd mm1, mm3
|
||||
punpckhwd mm6, mm3
|
||||
movq mm7, mm1
|
||||
movq mm4, mm6
|
||||
pmaddwd mm1, [GOTOFF(eax,PW_F0299_F0337)] ; mm1=ROL*FIX(0.299)+GOL*FIX(0.337)
|
||||
pmaddwd mm6, [GOTOFF(eax,PW_F0299_F0337)] ; mm6=ROH*FIX(0.299)+GOH*FIX(0.337)
|
||||
pmaddwd mm7, [GOTOFF(eax,PW_MF016_MF033)] ; mm7=ROL*-FIX(0.168)+GOL*-FIX(0.331)
|
||||
pmaddwd mm4, [GOTOFF(eax,PW_MF016_MF033)] ; mm4=ROH*-FIX(0.168)+GOH*-FIX(0.331)
|
||||
|
||||
movq MMWORD [wk(4)], mm1 ; wk(4)=ROL*FIX(0.299)+GOL*FIX(0.337)
|
||||
movq MMWORD [wk(5)], mm6 ; wk(5)=ROH*FIX(0.299)+GOH*FIX(0.337)
|
||||
|
||||
pxor mm1, mm1
|
||||
pxor mm6, mm6
|
||||
punpcklwd mm1, mm5 ; mm1=BOL
|
||||
punpckhwd mm6, mm5 ; mm6=BOH
|
||||
psrld mm1, 1 ; mm1=BOL*FIX(0.500)
|
||||
psrld mm6, 1 ; mm6=BOH*FIX(0.500)
|
||||
|
||||
movq mm5, [GOTOFF(eax,PD_ONEHALFM1_CJ)] ; mm5=[PD_ONEHALFM1_CJ]
|
||||
|
||||
paddd mm7, mm1
|
||||
paddd mm4, mm6
|
||||
paddd mm7, mm5
|
||||
paddd mm4, mm5
|
||||
psrld mm7, SCALEBITS ; mm7=CbOL
|
||||
psrld mm4, SCALEBITS ; mm4=CbOH
|
||||
packssdw mm7, mm4 ; mm7=CbO
|
||||
|
||||
movq mm1, MMWORD [wk(2)] ; mm1=BE
|
||||
|
||||
movq mm6, mm0
|
||||
punpcklwd mm0, mm2
|
||||
punpckhwd mm6, mm2
|
||||
movq mm5, mm0
|
||||
movq mm4, mm6
|
||||
pmaddwd mm0, [GOTOFF(eax,PW_F0299_F0337)] ; mm0=REL*FIX(0.299)+GEL*FIX(0.337)
|
||||
pmaddwd mm6, [GOTOFF(eax,PW_F0299_F0337)] ; mm6=REH*FIX(0.299)+GEH*FIX(0.337)
|
||||
pmaddwd mm5, [GOTOFF(eax,PW_MF016_MF033)] ; mm5=REL*-FIX(0.168)+GEL*-FIX(0.331)
|
||||
pmaddwd mm4, [GOTOFF(eax,PW_MF016_MF033)] ; mm4=REH*-FIX(0.168)+GEH*-FIX(0.331)
|
||||
|
||||
movq MMWORD [wk(6)], mm0 ; wk(6)=REL*FIX(0.299)+GEL*FIX(0.337)
|
||||
movq MMWORD [wk(7)], mm6 ; wk(7)=REH*FIX(0.299)+GEH*FIX(0.337)
|
||||
|
||||
pxor mm0, mm0
|
||||
pxor mm6, mm6
|
||||
punpcklwd mm0, mm1 ; mm0=BEL
|
||||
punpckhwd mm6, mm1 ; mm6=BEH
|
||||
psrld mm0, 1 ; mm0=BEL*FIX(0.500)
|
||||
psrld mm6, 1 ; mm6=BEH*FIX(0.500)
|
||||
|
||||
movq mm1, [GOTOFF(eax,PD_ONEHALFM1_CJ)] ; mm1=[PD_ONEHALFM1_CJ]
|
||||
|
||||
paddd mm5, mm0
|
||||
paddd mm4, mm6
|
||||
paddd mm5, mm1
|
||||
paddd mm4, mm1
|
||||
psrld mm5, SCALEBITS ; mm5=CbEL
|
||||
psrld mm4, SCALEBITS ; mm4=CbEH
|
||||
packssdw mm5, mm4 ; mm5=CbE
|
||||
|
||||
psllw mm7, BYTE_BIT
|
||||
por mm5, mm7 ; mm5=Cb
|
||||
movq MMWORD [ebx], mm5 ; Save Cb
|
||||
|
||||
movq mm0, MMWORD [wk(3)] ; mm0=BO
|
||||
movq mm6, MMWORD [wk(2)] ; mm6=BE
|
||||
movq mm1, MMWORD [wk(1)] ; mm1=RO
|
||||
|
||||
movq mm4, mm0
|
||||
punpcklwd mm0, mm3
|
||||
punpckhwd mm4, mm3
|
||||
movq mm7, mm0
|
||||
movq mm5, mm4
|
||||
pmaddwd mm0, [GOTOFF(eax,PW_F0114_F0250)] ; mm0=BOL*FIX(0.114)+GOL*FIX(0.250)
|
||||
pmaddwd mm4, [GOTOFF(eax,PW_F0114_F0250)] ; mm4=BOH*FIX(0.114)+GOH*FIX(0.250)
|
||||
pmaddwd mm7, [GOTOFF(eax,PW_MF008_MF041)] ; mm7=BOL*-FIX(0.081)+GOL*-FIX(0.418)
|
||||
pmaddwd mm5, [GOTOFF(eax,PW_MF008_MF041)] ; mm5=BOH*-FIX(0.081)+GOH*-FIX(0.418)
|
||||
|
||||
movq mm3, [GOTOFF(eax,PD_ONEHALF)] ; mm3=[PD_ONEHALF]
|
||||
|
||||
paddd mm0, MMWORD [wk(4)]
|
||||
paddd mm4, MMWORD [wk(5)]
|
||||
paddd mm0, mm3
|
||||
paddd mm4, mm3
|
||||
psrld mm0, SCALEBITS ; mm0=YOL
|
||||
psrld mm4, SCALEBITS ; mm4=YOH
|
||||
packssdw mm0, mm4 ; mm0=YO
|
||||
|
||||
pxor mm3, mm3
|
||||
pxor mm4, mm4
|
||||
punpcklwd mm3, mm1 ; mm3=ROL
|
||||
punpckhwd mm4, mm1 ; mm4=ROH
|
||||
psrld mm3, 1 ; mm3=ROL*FIX(0.500)
|
||||
psrld mm4, 1 ; mm4=ROH*FIX(0.500)
|
||||
|
||||
movq mm1, [GOTOFF(eax,PD_ONEHALFM1_CJ)] ; mm1=[PD_ONEHALFM1_CJ]
|
||||
|
||||
paddd mm7, mm3
|
||||
paddd mm5, mm4
|
||||
paddd mm7, mm1
|
||||
paddd mm5, mm1
|
||||
psrld mm7, SCALEBITS ; mm7=CrOL
|
||||
psrld mm5, SCALEBITS ; mm5=CrOH
|
||||
packssdw mm7, mm5 ; mm7=CrO
|
||||
|
||||
movq mm3, MMWORD [wk(0)] ; mm3=RE
|
||||
|
||||
movq mm4, mm6
|
||||
punpcklwd mm6, mm2
|
||||
punpckhwd mm4, mm2
|
||||
movq mm1, mm6
|
||||
movq mm5, mm4
|
||||
pmaddwd mm6, [GOTOFF(eax,PW_F0114_F0250)] ; mm6=BEL*FIX(0.114)+GEL*FIX(0.250)
|
||||
pmaddwd mm4, [GOTOFF(eax,PW_F0114_F0250)] ; mm4=BEH*FIX(0.114)+GEH*FIX(0.250)
|
||||
pmaddwd mm1, [GOTOFF(eax,PW_MF008_MF041)] ; mm1=BEL*-FIX(0.081)+GEL*-FIX(0.418)
|
||||
pmaddwd mm5, [GOTOFF(eax,PW_MF008_MF041)] ; mm5=BEH*-FIX(0.081)+GEH*-FIX(0.418)
|
||||
|
||||
movq mm2, [GOTOFF(eax,PD_ONEHALF)] ; mm2=[PD_ONEHALF]
|
||||
|
||||
paddd mm6, MMWORD [wk(6)]
|
||||
paddd mm4, MMWORD [wk(7)]
|
||||
paddd mm6, mm2
|
||||
paddd mm4, mm2
|
||||
psrld mm6, SCALEBITS ; mm6=YEL
|
||||
psrld mm4, SCALEBITS ; mm4=YEH
|
||||
packssdw mm6, mm4 ; mm6=YE
|
||||
|
||||
psllw mm0, BYTE_BIT
|
||||
por mm6, mm0 ; mm6=Y
|
||||
movq MMWORD [edi], mm6 ; Save Y
|
||||
|
||||
pxor mm2, mm2
|
||||
pxor mm4, mm4
|
||||
punpcklwd mm2, mm3 ; mm2=REL
|
||||
punpckhwd mm4, mm3 ; mm4=REH
|
||||
psrld mm2, 1 ; mm2=REL*FIX(0.500)
|
||||
psrld mm4, 1 ; mm4=REH*FIX(0.500)
|
||||
|
||||
movq mm0, [GOTOFF(eax,PD_ONEHALFM1_CJ)] ; mm0=[PD_ONEHALFM1_CJ]
|
||||
|
||||
paddd mm1, mm2
|
||||
paddd mm5, mm4
|
||||
paddd mm1, mm0
|
||||
paddd mm5, mm0
|
||||
psrld mm1, SCALEBITS ; mm1=CrEL
|
||||
psrld mm5, SCALEBITS ; mm5=CrEH
|
||||
packssdw mm1, mm5 ; mm1=CrE
|
||||
|
||||
psllw mm7, BYTE_BIT
|
||||
por mm1, mm7 ; mm1=Cr
|
||||
movq MMWORD [edx], mm1 ; Save Cr
|
||||
|
||||
sub ecx, byte SIZEOF_MMWORD
|
||||
add esi, byte RGB_PIXELSIZE*SIZEOF_MMWORD ; inptr
|
||||
add edi, byte SIZEOF_MMWORD ; outptr0
|
||||
add ebx, byte SIZEOF_MMWORD ; outptr1
|
||||
add edx, byte SIZEOF_MMWORD ; outptr2
|
||||
cmp ecx, byte SIZEOF_MMWORD
|
||||
jae near .columnloop
|
||||
test ecx, ecx
|
||||
jnz near .column_ld1
|
||||
|
||||
pop ecx ; col
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebx
|
||||
pop edx
|
||||
poppic eax
|
||||
|
||||
add esi, byte SIZEOF_JSAMPROW ; input_buf
|
||||
add edi, byte SIZEOF_JSAMPROW
|
||||
add ebx, byte SIZEOF_JSAMPROW
|
||||
add edx, byte SIZEOF_JSAMPROW
|
||||
dec eax ; num_rows
|
||||
jg near .rowloop
|
||||
|
||||
emms ; empty MMX state
|
||||
|
||||
.return:
|
||||
pop edi
|
||||
pop esi
|
||||
; pop edx ; need not be preserved
|
||||
; pop ecx ; need not be preserved
|
||||
pop ebx
|
||||
mov esp, ebp ; esp <- aligned ebp
|
||||
pop esp ; esp <- original ebp
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
; For some reason, the OS X linker does not honor the request to align the
|
||||
; segment unless we do this.
|
||||
align 32
|
||||
@@ -0,0 +1,503 @@
|
||||
;
|
||||
; jccolext.asm - colorspace conversion (SSE2)
|
||||
;
|
||||
; Copyright (C) 2016, D. R. Commander.
|
||||
;
|
||||
; Based on the x86 SIMD extension for IJG JPEG library
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
|
||||
%include "jcolsamp.inc"
|
||||
|
||||
; --------------------------------------------------------------------------
|
||||
;
|
||||
; Convert some rows of samples to the output colorspace.
|
||||
;
|
||||
; GLOBAL(void)
|
||||
; jsimd_rgb_ycc_convert_sse2(JDIMENSION img_width, JSAMPARRAY input_buf,
|
||||
; JSAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
; int num_rows);
|
||||
;
|
||||
|
||||
%define img_width(b) (b) + 8 ; JDIMENSION img_width
|
||||
%define input_buf(b) (b) + 12 ; JSAMPARRAY input_buf
|
||||
%define output_buf(b) (b) + 16 ; JSAMPIMAGE output_buf
|
||||
%define output_row(b) (b) + 20 ; JDIMENSION output_row
|
||||
%define num_rows(b) (b) + 24 ; int num_rows
|
||||
|
||||
%define original_ebp ebp + 0
|
||||
%define wk(i) ebp - (WK_NUM - (i)) * SIZEOF_XMMWORD
|
||||
; xmmword wk[WK_NUM]
|
||||
%define WK_NUM 8
|
||||
%define gotptr wk(0) - SIZEOF_POINTER ; void * gotptr
|
||||
|
||||
align 32
|
||||
GLOBAL_FUNCTION(jsimd_rgb_ycc_convert_sse2)
|
||||
|
||||
EXTN(jsimd_rgb_ycc_convert_sse2):
|
||||
push ebp
|
||||
mov eax, esp ; eax = original ebp
|
||||
sub esp, byte 4
|
||||
and esp, byte (-SIZEOF_XMMWORD) ; align to 128 bits
|
||||
mov [esp], eax
|
||||
mov ebp, esp ; ebp = aligned ebp
|
||||
lea esp, [wk(0)]
|
||||
pushpic eax ; make a room for GOT address
|
||||
push ebx
|
||||
; push ecx ; need not be preserved
|
||||
; push edx ; need not be preserved
|
||||
push esi
|
||||
push edi
|
||||
|
||||
get_GOT ebx ; get GOT address
|
||||
movpic POINTER [gotptr], ebx ; save GOT address
|
||||
|
||||
mov ecx, JDIMENSION [img_width(eax)]
|
||||
test ecx, ecx
|
||||
jz near .return
|
||||
|
||||
push ecx
|
||||
|
||||
mov esi, JSAMPIMAGE [output_buf(eax)]
|
||||
mov ecx, JDIMENSION [output_row(eax)]
|
||||
mov edi, JSAMPARRAY [esi+0*SIZEOF_JSAMPARRAY]
|
||||
mov ebx, JSAMPARRAY [esi+1*SIZEOF_JSAMPARRAY]
|
||||
mov edx, JSAMPARRAY [esi+2*SIZEOF_JSAMPARRAY]
|
||||
lea edi, [edi+ecx*SIZEOF_JSAMPROW]
|
||||
lea ebx, [ebx+ecx*SIZEOF_JSAMPROW]
|
||||
lea edx, [edx+ecx*SIZEOF_JSAMPROW]
|
||||
|
||||
pop ecx
|
||||
|
||||
mov esi, JSAMPARRAY [input_buf(eax)]
|
||||
mov eax, INT [num_rows(eax)]
|
||||
test eax, eax
|
||||
jle near .return
|
||||
alignx 16, 7
|
||||
.rowloop:
|
||||
pushpic eax
|
||||
push edx
|
||||
push ebx
|
||||
push edi
|
||||
push esi
|
||||
push ecx ; col
|
||||
|
||||
mov esi, JSAMPROW [esi] ; inptr
|
||||
mov edi, JSAMPROW [edi] ; outptr0
|
||||
mov ebx, JSAMPROW [ebx] ; outptr1
|
||||
mov edx, JSAMPROW [edx] ; outptr2
|
||||
movpic eax, POINTER [gotptr] ; load GOT address (eax)
|
||||
|
||||
cmp ecx, byte SIZEOF_XMMWORD
|
||||
jae near .columnloop
|
||||
alignx 16, 7
|
||||
|
||||
%if RGB_PIXELSIZE == 3 ; ---------------
|
||||
|
||||
.column_ld1:
|
||||
push eax
|
||||
push edx
|
||||
lea ecx, [ecx+ecx*2] ; imul ecx,RGB_PIXELSIZE
|
||||
test cl, SIZEOF_BYTE
|
||||
jz short .column_ld2
|
||||
sub ecx, byte SIZEOF_BYTE
|
||||
movzx eax, byte [esi+ecx]
|
||||
.column_ld2:
|
||||
test cl, SIZEOF_WORD
|
||||
jz short .column_ld4
|
||||
sub ecx, byte SIZEOF_WORD
|
||||
movzx edx, word [esi+ecx]
|
||||
shl eax, WORD_BIT
|
||||
or eax, edx
|
||||
.column_ld4:
|
||||
movd xmmA, eax
|
||||
pop edx
|
||||
pop eax
|
||||
test cl, SIZEOF_DWORD
|
||||
jz short .column_ld8
|
||||
sub ecx, byte SIZEOF_DWORD
|
||||
movd xmmF, XMM_DWORD [esi+ecx]
|
||||
pslldq xmmA, SIZEOF_DWORD
|
||||
por xmmA, xmmF
|
||||
.column_ld8:
|
||||
test cl, SIZEOF_MMWORD
|
||||
jz short .column_ld16
|
||||
sub ecx, byte SIZEOF_MMWORD
|
||||
movq xmmB, XMM_MMWORD [esi+ecx]
|
||||
pslldq xmmA, SIZEOF_MMWORD
|
||||
por xmmA, xmmB
|
||||
.column_ld16:
|
||||
test cl, SIZEOF_XMMWORD
|
||||
jz short .column_ld32
|
||||
movdqa xmmF, xmmA
|
||||
movdqu xmmA, XMMWORD [esi+0*SIZEOF_XMMWORD]
|
||||
mov ecx, SIZEOF_XMMWORD
|
||||
jmp short .rgb_ycc_cnv
|
||||
.column_ld32:
|
||||
test cl, 2*SIZEOF_XMMWORD
|
||||
mov ecx, SIZEOF_XMMWORD
|
||||
jz short .rgb_ycc_cnv
|
||||
movdqa xmmB, xmmA
|
||||
movdqu xmmA, XMMWORD [esi+0*SIZEOF_XMMWORD]
|
||||
movdqu xmmF, XMMWORD [esi+1*SIZEOF_XMMWORD]
|
||||
jmp short .rgb_ycc_cnv
|
||||
alignx 16, 7
|
||||
|
||||
.columnloop:
|
||||
movdqu xmmA, XMMWORD [esi+0*SIZEOF_XMMWORD]
|
||||
movdqu xmmF, XMMWORD [esi+1*SIZEOF_XMMWORD]
|
||||
movdqu xmmB, XMMWORD [esi+2*SIZEOF_XMMWORD]
|
||||
|
||||
.rgb_ycc_cnv:
|
||||
; xmmA=(00 10 20 01 11 21 02 12 22 03 13 23 04 14 24 05)
|
||||
; xmmF=(15 25 06 16 26 07 17 27 08 18 28 09 19 29 0A 1A)
|
||||
; xmmB=(2A 0B 1B 2B 0C 1C 2C 0D 1D 2D 0E 1E 2E 0F 1F 2F)
|
||||
|
||||
movdqa xmmG, xmmA
|
||||
pslldq xmmA, 8 ; xmmA=(-- -- -- -- -- -- -- -- 00 10 20 01 11 21 02 12)
|
||||
psrldq xmmG, 8 ; xmmG=(22 03 13 23 04 14 24 05 -- -- -- -- -- -- -- --)
|
||||
|
||||
punpckhbw xmmA, xmmF ; xmmA=(00 08 10 18 20 28 01 09 11 19 21 29 02 0A 12 1A)
|
||||
pslldq xmmF, 8 ; xmmF=(-- -- -- -- -- -- -- -- 15 25 06 16 26 07 17 27)
|
||||
|
||||
punpcklbw xmmG, xmmB ; xmmG=(22 2A 03 0B 13 1B 23 2B 04 0C 14 1C 24 2C 05 0D)
|
||||
punpckhbw xmmF, xmmB ; xmmF=(15 1D 25 2D 06 0E 16 1E 26 2E 07 0F 17 1F 27 2F)
|
||||
|
||||
movdqa xmmD, xmmA
|
||||
pslldq xmmA, 8 ; xmmA=(-- -- -- -- -- -- -- -- 00 08 10 18 20 28 01 09)
|
||||
psrldq xmmD, 8 ; xmmD=(11 19 21 29 02 0A 12 1A -- -- -- -- -- -- -- --)
|
||||
|
||||
punpckhbw xmmA, xmmG ; xmmA=(00 04 08 0C 10 14 18 1C 20 24 28 2C 01 05 09 0D)
|
||||
pslldq xmmG, 8 ; xmmG=(-- -- -- -- -- -- -- -- 22 2A 03 0B 13 1B 23 2B)
|
||||
|
||||
punpcklbw xmmD, xmmF ; xmmD=(11 15 19 1D 21 25 29 2D 02 06 0A 0E 12 16 1A 1E)
|
||||
punpckhbw xmmG, xmmF ; xmmG=(22 26 2A 2E 03 07 0B 0F 13 17 1B 1F 23 27 2B 2F)
|
||||
|
||||
movdqa xmmE, xmmA
|
||||
pslldq xmmA, 8 ; xmmA=(-- -- -- -- -- -- -- -- 00 04 08 0C 10 14 18 1C)
|
||||
psrldq xmmE, 8 ; xmmE=(20 24 28 2C 01 05 09 0D -- -- -- -- -- -- -- --)
|
||||
|
||||
punpckhbw xmmA, xmmD ; xmmA=(00 02 04 06 08 0A 0C 0E 10 12 14 16 18 1A 1C 1E)
|
||||
pslldq xmmD, 8 ; xmmD=(-- -- -- -- -- -- -- -- 11 15 19 1D 21 25 29 2D)
|
||||
|
||||
punpcklbw xmmE, xmmG ; xmmE=(20 22 24 26 28 2A 2C 2E 01 03 05 07 09 0B 0D 0F)
|
||||
punpckhbw xmmD, xmmG ; xmmD=(11 13 15 17 19 1B 1D 1F 21 23 25 27 29 2B 2D 2F)
|
||||
|
||||
pxor xmmH, xmmH
|
||||
|
||||
movdqa xmmC, xmmA
|
||||
punpcklbw xmmA, xmmH ; xmmA=(00 02 04 06 08 0A 0C 0E)
|
||||
punpckhbw xmmC, xmmH ; xmmC=(10 12 14 16 18 1A 1C 1E)
|
||||
|
||||
movdqa xmmB, xmmE
|
||||
punpcklbw xmmE, xmmH ; xmmE=(20 22 24 26 28 2A 2C 2E)
|
||||
punpckhbw xmmB, xmmH ; xmmB=(01 03 05 07 09 0B 0D 0F)
|
||||
|
||||
movdqa xmmF, xmmD
|
||||
punpcklbw xmmD, xmmH ; xmmD=(11 13 15 17 19 1B 1D 1F)
|
||||
punpckhbw xmmF, xmmH ; xmmF=(21 23 25 27 29 2B 2D 2F)
|
||||
|
||||
%else ; RGB_PIXELSIZE == 4 ; -----------
|
||||
|
||||
.column_ld1:
|
||||
test cl, SIZEOF_XMMWORD/16
|
||||
jz short .column_ld2
|
||||
sub ecx, byte SIZEOF_XMMWORD/16
|
||||
movd xmmA, XMM_DWORD [esi+ecx*RGB_PIXELSIZE]
|
||||
.column_ld2:
|
||||
test cl, SIZEOF_XMMWORD/8
|
||||
jz short .column_ld4
|
||||
sub ecx, byte SIZEOF_XMMWORD/8
|
||||
movq xmmE, XMM_MMWORD [esi+ecx*RGB_PIXELSIZE]
|
||||
pslldq xmmA, SIZEOF_MMWORD
|
||||
por xmmA, xmmE
|
||||
.column_ld4:
|
||||
test cl, SIZEOF_XMMWORD/4
|
||||
jz short .column_ld8
|
||||
sub ecx, byte SIZEOF_XMMWORD/4
|
||||
movdqa xmmE, xmmA
|
||||
movdqu xmmA, XMMWORD [esi+ecx*RGB_PIXELSIZE]
|
||||
.column_ld8:
|
||||
test cl, SIZEOF_XMMWORD/2
|
||||
mov ecx, SIZEOF_XMMWORD
|
||||
jz short .rgb_ycc_cnv
|
||||
movdqa xmmF, xmmA
|
||||
movdqa xmmH, xmmE
|
||||
movdqu xmmA, XMMWORD [esi+0*SIZEOF_XMMWORD]
|
||||
movdqu xmmE, XMMWORD [esi+1*SIZEOF_XMMWORD]
|
||||
jmp short .rgb_ycc_cnv
|
||||
alignx 16, 7
|
||||
|
||||
.columnloop:
|
||||
movdqu xmmA, XMMWORD [esi+0*SIZEOF_XMMWORD]
|
||||
movdqu xmmE, XMMWORD [esi+1*SIZEOF_XMMWORD]
|
||||
movdqu xmmF, XMMWORD [esi+2*SIZEOF_XMMWORD]
|
||||
movdqu xmmH, XMMWORD [esi+3*SIZEOF_XMMWORD]
|
||||
|
||||
.rgb_ycc_cnv:
|
||||
; xmmA=(00 10 20 30 01 11 21 31 02 12 22 32 03 13 23 33)
|
||||
; xmmE=(04 14 24 34 05 15 25 35 06 16 26 36 07 17 27 37)
|
||||
; xmmF=(08 18 28 38 09 19 29 39 0A 1A 2A 3A 0B 1B 2B 3B)
|
||||
; xmmH=(0C 1C 2C 3C 0D 1D 2D 3D 0E 1E 2E 3E 0F 1F 2F 3F)
|
||||
|
||||
movdqa xmmD, xmmA
|
||||
punpcklbw xmmA, xmmE ; xmmA=(00 04 10 14 20 24 30 34 01 05 11 15 21 25 31 35)
|
||||
punpckhbw xmmD, xmmE ; xmmD=(02 06 12 16 22 26 32 36 03 07 13 17 23 27 33 37)
|
||||
|
||||
movdqa xmmC, xmmF
|
||||
punpcklbw xmmF, xmmH ; xmmF=(08 0C 18 1C 28 2C 38 3C 09 0D 19 1D 29 2D 39 3D)
|
||||
punpckhbw xmmC, xmmH ; xmmC=(0A 0E 1A 1E 2A 2E 3A 3E 0B 0F 1B 1F 2B 2F 3B 3F)
|
||||
|
||||
movdqa xmmB, xmmA
|
||||
punpcklwd xmmA, xmmF ; xmmA=(00 04 08 0C 10 14 18 1C 20 24 28 2C 30 34 38 3C)
|
||||
punpckhwd xmmB, xmmF ; xmmB=(01 05 09 0D 11 15 19 1D 21 25 29 2D 31 35 39 3D)
|
||||
|
||||
movdqa xmmG, xmmD
|
||||
punpcklwd xmmD, xmmC ; xmmD=(02 06 0A 0E 12 16 1A 1E 22 26 2A 2E 32 36 3A 3E)
|
||||
punpckhwd xmmG, xmmC ; xmmG=(03 07 0B 0F 13 17 1B 1F 23 27 2B 2F 33 37 3B 3F)
|
||||
|
||||
movdqa xmmE, xmmA
|
||||
punpcklbw xmmA, xmmD ; xmmA=(00 02 04 06 08 0A 0C 0E 10 12 14 16 18 1A 1C 1E)
|
||||
punpckhbw xmmE, xmmD ; xmmE=(20 22 24 26 28 2A 2C 2E 30 32 34 36 38 3A 3C 3E)
|
||||
|
||||
movdqa xmmH, xmmB
|
||||
punpcklbw xmmB, xmmG ; xmmB=(01 03 05 07 09 0B 0D 0F 11 13 15 17 19 1B 1D 1F)
|
||||
punpckhbw xmmH, xmmG ; xmmH=(21 23 25 27 29 2B 2D 2F 31 33 35 37 39 3B 3D 3F)
|
||||
|
||||
pxor xmmF, xmmF
|
||||
|
||||
movdqa xmmC, xmmA
|
||||
punpcklbw xmmA, xmmF ; xmmA=(00 02 04 06 08 0A 0C 0E)
|
||||
punpckhbw xmmC, xmmF ; xmmC=(10 12 14 16 18 1A 1C 1E)
|
||||
|
||||
movdqa xmmD, xmmB
|
||||
punpcklbw xmmB, xmmF ; xmmB=(01 03 05 07 09 0B 0D 0F)
|
||||
punpckhbw xmmD, xmmF ; xmmD=(11 13 15 17 19 1B 1D 1F)
|
||||
|
||||
movdqa xmmG, xmmE
|
||||
punpcklbw xmmE, xmmF ; xmmE=(20 22 24 26 28 2A 2C 2E)
|
||||
punpckhbw xmmG, xmmF ; xmmG=(30 32 34 36 38 3A 3C 3E)
|
||||
|
||||
punpcklbw xmmF, xmmH
|
||||
punpckhbw xmmH, xmmH
|
||||
psrlw xmmF, BYTE_BIT ; xmmF=(21 23 25 27 29 2B 2D 2F)
|
||||
psrlw xmmH, BYTE_BIT ; xmmH=(31 33 35 37 39 3B 3D 3F)
|
||||
|
||||
%endif ; RGB_PIXELSIZE ; ---------------
|
||||
|
||||
; xmm0=R(02468ACE)=RE, xmm2=G(02468ACE)=GE, xmm4=B(02468ACE)=BE
|
||||
; xmm1=R(13579BDF)=RO, xmm3=G(13579BDF)=GO, xmm5=B(13579BDF)=BO
|
||||
|
||||
; (Original)
|
||||
; Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
|
||||
; Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
|
||||
; Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
|
||||
;
|
||||
; (This implementation)
|
||||
; Y = 0.29900 * R + 0.33700 * G + 0.11400 * B + 0.25000 * G
|
||||
; Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
|
||||
; Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
|
||||
|
||||
movdqa XMMWORD [wk(0)], xmm0 ; wk(0)=RE
|
||||
movdqa XMMWORD [wk(1)], xmm1 ; wk(1)=RO
|
||||
movdqa XMMWORD [wk(2)], xmm4 ; wk(2)=BE
|
||||
movdqa XMMWORD [wk(3)], xmm5 ; wk(3)=BO
|
||||
|
||||
movdqa xmm6, xmm1
|
||||
punpcklwd xmm1, xmm3
|
||||
punpckhwd xmm6, xmm3
|
||||
movdqa xmm7, xmm1
|
||||
movdqa xmm4, xmm6
|
||||
pmaddwd xmm1, [GOTOFF(eax,PW_F0299_F0337)] ; xmm1=ROL*FIX(0.299)+GOL*FIX(0.337)
|
||||
pmaddwd xmm6, [GOTOFF(eax,PW_F0299_F0337)] ; xmm6=ROH*FIX(0.299)+GOH*FIX(0.337)
|
||||
pmaddwd xmm7, [GOTOFF(eax,PW_MF016_MF033)] ; xmm7=ROL*-FIX(0.168)+GOL*-FIX(0.331)
|
||||
pmaddwd xmm4, [GOTOFF(eax,PW_MF016_MF033)] ; xmm4=ROH*-FIX(0.168)+GOH*-FIX(0.331)
|
||||
|
||||
movdqa XMMWORD [wk(4)], xmm1 ; wk(4)=ROL*FIX(0.299)+GOL*FIX(0.337)
|
||||
movdqa XMMWORD [wk(5)], xmm6 ; wk(5)=ROH*FIX(0.299)+GOH*FIX(0.337)
|
||||
|
||||
pxor xmm1, xmm1
|
||||
pxor xmm6, xmm6
|
||||
punpcklwd xmm1, xmm5 ; xmm1=BOL
|
||||
punpckhwd xmm6, xmm5 ; xmm6=BOH
|
||||
psrld xmm1, 1 ; xmm1=BOL*FIX(0.500)
|
||||
psrld xmm6, 1 ; xmm6=BOH*FIX(0.500)
|
||||
|
||||
movdqa xmm5, [GOTOFF(eax,PD_ONEHALFM1_CJ)] ; xmm5=[PD_ONEHALFM1_CJ]
|
||||
|
||||
paddd xmm7, xmm1
|
||||
paddd xmm4, xmm6
|
||||
paddd xmm7, xmm5
|
||||
paddd xmm4, xmm5
|
||||
psrld xmm7, SCALEBITS ; xmm7=CbOL
|
||||
psrld xmm4, SCALEBITS ; xmm4=CbOH
|
||||
packssdw xmm7, xmm4 ; xmm7=CbO
|
||||
|
||||
movdqa xmm1, XMMWORD [wk(2)] ; xmm1=BE
|
||||
|
||||
movdqa xmm6, xmm0
|
||||
punpcklwd xmm0, xmm2
|
||||
punpckhwd xmm6, xmm2
|
||||
movdqa xmm5, xmm0
|
||||
movdqa xmm4, xmm6
|
||||
pmaddwd xmm0, [GOTOFF(eax,PW_F0299_F0337)] ; xmm0=REL*FIX(0.299)+GEL*FIX(0.337)
|
||||
pmaddwd xmm6, [GOTOFF(eax,PW_F0299_F0337)] ; xmm6=REH*FIX(0.299)+GEH*FIX(0.337)
|
||||
pmaddwd xmm5, [GOTOFF(eax,PW_MF016_MF033)] ; xmm5=REL*-FIX(0.168)+GEL*-FIX(0.331)
|
||||
pmaddwd xmm4, [GOTOFF(eax,PW_MF016_MF033)] ; xmm4=REH*-FIX(0.168)+GEH*-FIX(0.331)
|
||||
|
||||
movdqa XMMWORD [wk(6)], xmm0 ; wk(6)=REL*FIX(0.299)+GEL*FIX(0.337)
|
||||
movdqa XMMWORD [wk(7)], xmm6 ; wk(7)=REH*FIX(0.299)+GEH*FIX(0.337)
|
||||
|
||||
pxor xmm0, xmm0
|
||||
pxor xmm6, xmm6
|
||||
punpcklwd xmm0, xmm1 ; xmm0=BEL
|
||||
punpckhwd xmm6, xmm1 ; xmm6=BEH
|
||||
psrld xmm0, 1 ; xmm0=BEL*FIX(0.500)
|
||||
psrld xmm6, 1 ; xmm6=BEH*FIX(0.500)
|
||||
|
||||
movdqa xmm1, [GOTOFF(eax,PD_ONEHALFM1_CJ)] ; xmm1=[PD_ONEHALFM1_CJ]
|
||||
|
||||
paddd xmm5, xmm0
|
||||
paddd xmm4, xmm6
|
||||
paddd xmm5, xmm1
|
||||
paddd xmm4, xmm1
|
||||
psrld xmm5, SCALEBITS ; xmm5=CbEL
|
||||
psrld xmm4, SCALEBITS ; xmm4=CbEH
|
||||
packssdw xmm5, xmm4 ; xmm5=CbE
|
||||
|
||||
psllw xmm7, BYTE_BIT
|
||||
por xmm5, xmm7 ; xmm5=Cb
|
||||
movdqa XMMWORD [ebx], xmm5 ; Save Cb
|
||||
|
||||
movdqa xmm0, XMMWORD [wk(3)] ; xmm0=BO
|
||||
movdqa xmm6, XMMWORD [wk(2)] ; xmm6=BE
|
||||
movdqa xmm1, XMMWORD [wk(1)] ; xmm1=RO
|
||||
|
||||
movdqa xmm4, xmm0
|
||||
punpcklwd xmm0, xmm3
|
||||
punpckhwd xmm4, xmm3
|
||||
movdqa xmm7, xmm0
|
||||
movdqa xmm5, xmm4
|
||||
pmaddwd xmm0, [GOTOFF(eax,PW_F0114_F0250)] ; xmm0=BOL*FIX(0.114)+GOL*FIX(0.250)
|
||||
pmaddwd xmm4, [GOTOFF(eax,PW_F0114_F0250)] ; xmm4=BOH*FIX(0.114)+GOH*FIX(0.250)
|
||||
pmaddwd xmm7, [GOTOFF(eax,PW_MF008_MF041)] ; xmm7=BOL*-FIX(0.081)+GOL*-FIX(0.418)
|
||||
pmaddwd xmm5, [GOTOFF(eax,PW_MF008_MF041)] ; xmm5=BOH*-FIX(0.081)+GOH*-FIX(0.418)
|
||||
|
||||
movdqa xmm3, [GOTOFF(eax,PD_ONEHALF)] ; xmm3=[PD_ONEHALF]
|
||||
|
||||
paddd xmm0, XMMWORD [wk(4)]
|
||||
paddd xmm4, XMMWORD [wk(5)]
|
||||
paddd xmm0, xmm3
|
||||
paddd xmm4, xmm3
|
||||
psrld xmm0, SCALEBITS ; xmm0=YOL
|
||||
psrld xmm4, SCALEBITS ; xmm4=YOH
|
||||
packssdw xmm0, xmm4 ; xmm0=YO
|
||||
|
||||
pxor xmm3, xmm3
|
||||
pxor xmm4, xmm4
|
||||
punpcklwd xmm3, xmm1 ; xmm3=ROL
|
||||
punpckhwd xmm4, xmm1 ; xmm4=ROH
|
||||
psrld xmm3, 1 ; xmm3=ROL*FIX(0.500)
|
||||
psrld xmm4, 1 ; xmm4=ROH*FIX(0.500)
|
||||
|
||||
movdqa xmm1, [GOTOFF(eax,PD_ONEHALFM1_CJ)] ; xmm1=[PD_ONEHALFM1_CJ]
|
||||
|
||||
paddd xmm7, xmm3
|
||||
paddd xmm5, xmm4
|
||||
paddd xmm7, xmm1
|
||||
paddd xmm5, xmm1
|
||||
psrld xmm7, SCALEBITS ; xmm7=CrOL
|
||||
psrld xmm5, SCALEBITS ; xmm5=CrOH
|
||||
packssdw xmm7, xmm5 ; xmm7=CrO
|
||||
|
||||
movdqa xmm3, XMMWORD [wk(0)] ; xmm3=RE
|
||||
|
||||
movdqa xmm4, xmm6
|
||||
punpcklwd xmm6, xmm2
|
||||
punpckhwd xmm4, xmm2
|
||||
movdqa xmm1, xmm6
|
||||
movdqa xmm5, xmm4
|
||||
pmaddwd xmm6, [GOTOFF(eax,PW_F0114_F0250)] ; xmm6=BEL*FIX(0.114)+GEL*FIX(0.250)
|
||||
pmaddwd xmm4, [GOTOFF(eax,PW_F0114_F0250)] ; xmm4=BEH*FIX(0.114)+GEH*FIX(0.250)
|
||||
pmaddwd xmm1, [GOTOFF(eax,PW_MF008_MF041)] ; xmm1=BEL*-FIX(0.081)+GEL*-FIX(0.418)
|
||||
pmaddwd xmm5, [GOTOFF(eax,PW_MF008_MF041)] ; xmm5=BEH*-FIX(0.081)+GEH*-FIX(0.418)
|
||||
|
||||
movdqa xmm2, [GOTOFF(eax,PD_ONEHALF)] ; xmm2=[PD_ONEHALF]
|
||||
|
||||
paddd xmm6, XMMWORD [wk(6)]
|
||||
paddd xmm4, XMMWORD [wk(7)]
|
||||
paddd xmm6, xmm2
|
||||
paddd xmm4, xmm2
|
||||
psrld xmm6, SCALEBITS ; xmm6=YEL
|
||||
psrld xmm4, SCALEBITS ; xmm4=YEH
|
||||
packssdw xmm6, xmm4 ; xmm6=YE
|
||||
|
||||
psllw xmm0, BYTE_BIT
|
||||
por xmm6, xmm0 ; xmm6=Y
|
||||
movdqa XMMWORD [edi], xmm6 ; Save Y
|
||||
|
||||
pxor xmm2, xmm2
|
||||
pxor xmm4, xmm4
|
||||
punpcklwd xmm2, xmm3 ; xmm2=REL
|
||||
punpckhwd xmm4, xmm3 ; xmm4=REH
|
||||
psrld xmm2, 1 ; xmm2=REL*FIX(0.500)
|
||||
psrld xmm4, 1 ; xmm4=REH*FIX(0.500)
|
||||
|
||||
movdqa xmm0, [GOTOFF(eax,PD_ONEHALFM1_CJ)] ; xmm0=[PD_ONEHALFM1_CJ]
|
||||
|
||||
paddd xmm1, xmm2
|
||||
paddd xmm5, xmm4
|
||||
paddd xmm1, xmm0
|
||||
paddd xmm5, xmm0
|
||||
psrld xmm1, SCALEBITS ; xmm1=CrEL
|
||||
psrld xmm5, SCALEBITS ; xmm5=CrEH
|
||||
packssdw xmm1, xmm5 ; xmm1=CrE
|
||||
|
||||
psllw xmm7, BYTE_BIT
|
||||
por xmm1, xmm7 ; xmm1=Cr
|
||||
movdqa XMMWORD [edx], xmm1 ; Save Cr
|
||||
|
||||
sub ecx, byte SIZEOF_XMMWORD
|
||||
add esi, byte RGB_PIXELSIZE*SIZEOF_XMMWORD ; inptr
|
||||
add edi, byte SIZEOF_XMMWORD ; outptr0
|
||||
add ebx, byte SIZEOF_XMMWORD ; outptr1
|
||||
add edx, byte SIZEOF_XMMWORD ; outptr2
|
||||
cmp ecx, byte SIZEOF_XMMWORD
|
||||
jae near .columnloop
|
||||
test ecx, ecx
|
||||
jnz near .column_ld1
|
||||
|
||||
pop ecx ; col
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebx
|
||||
pop edx
|
||||
poppic eax
|
||||
|
||||
add esi, byte SIZEOF_JSAMPROW ; input_buf
|
||||
add edi, byte SIZEOF_JSAMPROW
|
||||
add ebx, byte SIZEOF_JSAMPROW
|
||||
add edx, byte SIZEOF_JSAMPROW
|
||||
dec eax ; num_rows
|
||||
jg near .rowloop
|
||||
|
||||
.return:
|
||||
pop edi
|
||||
pop esi
|
||||
; pop edx ; need not be preserved
|
||||
; pop ecx ; need not be preserved
|
||||
pop ebx
|
||||
mov esp, ebp ; esp <- aligned ebp
|
||||
pop esp ; esp <- original ebp
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
; For some reason, the OS X linker does not honor the request to align the
|
||||
; segment unless we do this.
|
||||
align 32
|
||||
@@ -0,0 +1,121 @@
|
||||
;
|
||||
; jccolor.asm - colorspace conversion (AVX2)
|
||||
;
|
||||
; Copyright (C) 2009, 2016, D. R. Commander.
|
||||
; Copyright (C) 2015, Intel Corporation.
|
||||
;
|
||||
; Based on the x86 SIMD extension for IJG JPEG library
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
; --------------------------------------------------------------------------
|
||||
|
||||
%define SCALEBITS 16
|
||||
|
||||
F_0_081 equ 5329 ; FIX(0.08131)
|
||||
F_0_114 equ 7471 ; FIX(0.11400)
|
||||
F_0_168 equ 11059 ; FIX(0.16874)
|
||||
F_0_250 equ 16384 ; FIX(0.25000)
|
||||
F_0_299 equ 19595 ; FIX(0.29900)
|
||||
F_0_331 equ 21709 ; FIX(0.33126)
|
||||
F_0_418 equ 27439 ; FIX(0.41869)
|
||||
F_0_587 equ 38470 ; FIX(0.58700)
|
||||
F_0_337 equ (F_0_587 - F_0_250) ; FIX(0.58700) - FIX(0.25000)
|
||||
|
||||
; --------------------------------------------------------------------------
|
||||
SECTION SEG_CONST
|
||||
|
||||
alignz 32
|
||||
GLOBAL_DATA(jconst_rgb_ycc_convert_avx2)
|
||||
|
||||
EXTN(jconst_rgb_ycc_convert_avx2):
|
||||
|
||||
PW_F0299_F0337 times 8 dw F_0_299, F_0_337
|
||||
PW_F0114_F0250 times 8 dw F_0_114, F_0_250
|
||||
PW_MF016_MF033 times 8 dw -F_0_168, -F_0_331
|
||||
PW_MF008_MF041 times 8 dw -F_0_081, -F_0_418
|
||||
PD_ONEHALFM1_CJ times 8 dd (1 << (SCALEBITS - 1)) - 1 + \
|
||||
(CENTERJSAMPLE << SCALEBITS)
|
||||
PD_ONEHALF times 8 dd (1 << (SCALEBITS - 1))
|
||||
|
||||
alignz 32
|
||||
|
||||
; --------------------------------------------------------------------------
|
||||
SECTION SEG_TEXT
|
||||
BITS 32
|
||||
|
||||
%include "jccolext-avx2.asm"
|
||||
|
||||
%undef RGB_RED
|
||||
%undef RGB_GREEN
|
||||
%undef RGB_BLUE
|
||||
%undef RGB_PIXELSIZE
|
||||
%define RGB_RED EXT_RGB_RED
|
||||
%define RGB_GREEN EXT_RGB_GREEN
|
||||
%define RGB_BLUE EXT_RGB_BLUE
|
||||
%define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
|
||||
%define jsimd_rgb_ycc_convert_avx2 jsimd_extrgb_ycc_convert_avx2
|
||||
%include "jccolext-avx2.asm"
|
||||
|
||||
%undef RGB_RED
|
||||
%undef RGB_GREEN
|
||||
%undef RGB_BLUE
|
||||
%undef RGB_PIXELSIZE
|
||||
%define RGB_RED EXT_RGBX_RED
|
||||
%define RGB_GREEN EXT_RGBX_GREEN
|
||||
%define RGB_BLUE EXT_RGBX_BLUE
|
||||
%define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
|
||||
%define jsimd_rgb_ycc_convert_avx2 jsimd_extrgbx_ycc_convert_avx2
|
||||
%include "jccolext-avx2.asm"
|
||||
|
||||
%undef RGB_RED
|
||||
%undef RGB_GREEN
|
||||
%undef RGB_BLUE
|
||||
%undef RGB_PIXELSIZE
|
||||
%define RGB_RED EXT_BGR_RED
|
||||
%define RGB_GREEN EXT_BGR_GREEN
|
||||
%define RGB_BLUE EXT_BGR_BLUE
|
||||
%define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
|
||||
%define jsimd_rgb_ycc_convert_avx2 jsimd_extbgr_ycc_convert_avx2
|
||||
%include "jccolext-avx2.asm"
|
||||
|
||||
%undef RGB_RED
|
||||
%undef RGB_GREEN
|
||||
%undef RGB_BLUE
|
||||
%undef RGB_PIXELSIZE
|
||||
%define RGB_RED EXT_BGRX_RED
|
||||
%define RGB_GREEN EXT_BGRX_GREEN
|
||||
%define RGB_BLUE EXT_BGRX_BLUE
|
||||
%define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
|
||||
%define jsimd_rgb_ycc_convert_avx2 jsimd_extbgrx_ycc_convert_avx2
|
||||
%include "jccolext-avx2.asm"
|
||||
|
||||
%undef RGB_RED
|
||||
%undef RGB_GREEN
|
||||
%undef RGB_BLUE
|
||||
%undef RGB_PIXELSIZE
|
||||
%define RGB_RED EXT_XBGR_RED
|
||||
%define RGB_GREEN EXT_XBGR_GREEN
|
||||
%define RGB_BLUE EXT_XBGR_BLUE
|
||||
%define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
|
||||
%define jsimd_rgb_ycc_convert_avx2 jsimd_extxbgr_ycc_convert_avx2
|
||||
%include "jccolext-avx2.asm"
|
||||
|
||||
%undef RGB_RED
|
||||
%undef RGB_GREEN
|
||||
%undef RGB_BLUE
|
||||
%undef RGB_PIXELSIZE
|
||||
%define RGB_RED EXT_XRGB_RED
|
||||
%define RGB_GREEN EXT_XRGB_GREEN
|
||||
%define RGB_BLUE EXT_XRGB_BLUE
|
||||
%define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
|
||||
%define jsimd_rgb_ycc_convert_avx2 jsimd_extxrgb_ycc_convert_avx2
|
||||
%include "jccolext-avx2.asm"
|
||||
@@ -0,0 +1,121 @@
|
||||
;
|
||||
; jccolor.asm - colorspace conversion (MMX)
|
||||
;
|
||||
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
; Copyright (C) 2009, 2016, D. R. Commander.
|
||||
;
|
||||
; Based on the x86 SIMD extension for IJG JPEG library
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
; --------------------------------------------------------------------------
|
||||
|
||||
%define SCALEBITS 16
|
||||
|
||||
F_0_081 equ 5329 ; FIX(0.08131)
|
||||
F_0_114 equ 7471 ; FIX(0.11400)
|
||||
F_0_168 equ 11059 ; FIX(0.16874)
|
||||
F_0_250 equ 16384 ; FIX(0.25000)
|
||||
F_0_299 equ 19595 ; FIX(0.29900)
|
||||
F_0_331 equ 21709 ; FIX(0.33126)
|
||||
F_0_418 equ 27439 ; FIX(0.41869)
|
||||
F_0_587 equ 38470 ; FIX(0.58700)
|
||||
F_0_337 equ (F_0_587 - F_0_250) ; FIX(0.58700) - FIX(0.25000)
|
||||
|
||||
; --------------------------------------------------------------------------
|
||||
SECTION SEG_CONST
|
||||
|
||||
alignz 32
|
||||
GLOBAL_DATA(jconst_rgb_ycc_convert_mmx)
|
||||
|
||||
EXTN(jconst_rgb_ycc_convert_mmx):
|
||||
|
||||
PW_F0299_F0337 times 2 dw F_0_299, F_0_337
|
||||
PW_F0114_F0250 times 2 dw F_0_114, F_0_250
|
||||
PW_MF016_MF033 times 2 dw -F_0_168, -F_0_331
|
||||
PW_MF008_MF041 times 2 dw -F_0_081, -F_0_418
|
||||
PD_ONEHALFM1_CJ times 2 dd (1 << (SCALEBITS - 1)) - 1 + \
|
||||
(CENTERJSAMPLE << SCALEBITS)
|
||||
PD_ONEHALF times 2 dd (1 << (SCALEBITS - 1))
|
||||
|
||||
alignz 32
|
||||
|
||||
; --------------------------------------------------------------------------
|
||||
SECTION SEG_TEXT
|
||||
BITS 32
|
||||
|
||||
%include "jccolext-mmx.asm"
|
||||
|
||||
%undef RGB_RED
|
||||
%undef RGB_GREEN
|
||||
%undef RGB_BLUE
|
||||
%undef RGB_PIXELSIZE
|
||||
%define RGB_RED EXT_RGB_RED
|
||||
%define RGB_GREEN EXT_RGB_GREEN
|
||||
%define RGB_BLUE EXT_RGB_BLUE
|
||||
%define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
|
||||
%define jsimd_rgb_ycc_convert_mmx jsimd_extrgb_ycc_convert_mmx
|
||||
%include "jccolext-mmx.asm"
|
||||
|
||||
%undef RGB_RED
|
||||
%undef RGB_GREEN
|
||||
%undef RGB_BLUE
|
||||
%undef RGB_PIXELSIZE
|
||||
%define RGB_RED EXT_RGBX_RED
|
||||
%define RGB_GREEN EXT_RGBX_GREEN
|
||||
%define RGB_BLUE EXT_RGBX_BLUE
|
||||
%define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
|
||||
%define jsimd_rgb_ycc_convert_mmx jsimd_extrgbx_ycc_convert_mmx
|
||||
%include "jccolext-mmx.asm"
|
||||
|
||||
%undef RGB_RED
|
||||
%undef RGB_GREEN
|
||||
%undef RGB_BLUE
|
||||
%undef RGB_PIXELSIZE
|
||||
%define RGB_RED EXT_BGR_RED
|
||||
%define RGB_GREEN EXT_BGR_GREEN
|
||||
%define RGB_BLUE EXT_BGR_BLUE
|
||||
%define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
|
||||
%define jsimd_rgb_ycc_convert_mmx jsimd_extbgr_ycc_convert_mmx
|
||||
%include "jccolext-mmx.asm"
|
||||
|
||||
%undef RGB_RED
|
||||
%undef RGB_GREEN
|
||||
%undef RGB_BLUE
|
||||
%undef RGB_PIXELSIZE
|
||||
%define RGB_RED EXT_BGRX_RED
|
||||
%define RGB_GREEN EXT_BGRX_GREEN
|
||||
%define RGB_BLUE EXT_BGRX_BLUE
|
||||
%define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
|
||||
%define jsimd_rgb_ycc_convert_mmx jsimd_extbgrx_ycc_convert_mmx
|
||||
%include "jccolext-mmx.asm"
|
||||
|
||||
%undef RGB_RED
|
||||
%undef RGB_GREEN
|
||||
%undef RGB_BLUE
|
||||
%undef RGB_PIXELSIZE
|
||||
%define RGB_RED EXT_XBGR_RED
|
||||
%define RGB_GREEN EXT_XBGR_GREEN
|
||||
%define RGB_BLUE EXT_XBGR_BLUE
|
||||
%define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
|
||||
%define jsimd_rgb_ycc_convert_mmx jsimd_extxbgr_ycc_convert_mmx
|
||||
%include "jccolext-mmx.asm"
|
||||
|
||||
%undef RGB_RED
|
||||
%undef RGB_GREEN
|
||||
%undef RGB_BLUE
|
||||
%undef RGB_PIXELSIZE
|
||||
%define RGB_RED EXT_XRGB_RED
|
||||
%define RGB_GREEN EXT_XRGB_GREEN
|
||||
%define RGB_BLUE EXT_XRGB_BLUE
|
||||
%define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
|
||||
%define jsimd_rgb_ycc_convert_mmx jsimd_extxrgb_ycc_convert_mmx
|
||||
%include "jccolext-mmx.asm"
|
||||
@@ -0,0 +1,120 @@
|
||||
;
|
||||
; jccolor.asm - colorspace conversion (SSE2)
|
||||
;
|
||||
; Copyright (C) 2009, 2016, D. R. Commander.
|
||||
;
|
||||
; Based on the x86 SIMD extension for IJG JPEG library
|
||||
; Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
; For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
;
|
||||
; This file should be assembled with NASM (Netwide Assembler),
|
||||
; can *not* be assembled with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler).
|
||||
; NASM is available from http://nasm.sourceforge.net/ or
|
||||
; http://sourceforge.net/project/showfiles.php?group_id=6208
|
||||
|
||||
%include "jsimdext.inc"
|
||||
|
||||
; --------------------------------------------------------------------------
|
||||
|
||||
%define SCALEBITS 16
|
||||
|
||||
F_0_081 equ 5329 ; FIX(0.08131)
|
||||
F_0_114 equ 7471 ; FIX(0.11400)
|
||||
F_0_168 equ 11059 ; FIX(0.16874)
|
||||
F_0_250 equ 16384 ; FIX(0.25000)
|
||||
F_0_299 equ 19595 ; FIX(0.29900)
|
||||
F_0_331 equ 21709 ; FIX(0.33126)
|
||||
F_0_418 equ 27439 ; FIX(0.41869)
|
||||
F_0_587 equ 38470 ; FIX(0.58700)
|
||||
F_0_337 equ (F_0_587 - F_0_250) ; FIX(0.58700) - FIX(0.25000)
|
||||
|
||||
; --------------------------------------------------------------------------
|
||||
SECTION SEG_CONST
|
||||
|
||||
alignz 32
|
||||
GLOBAL_DATA(jconst_rgb_ycc_convert_sse2)
|
||||
|
||||
EXTN(jconst_rgb_ycc_convert_sse2):
|
||||
|
||||
PW_F0299_F0337 times 4 dw F_0_299, F_0_337
|
||||
PW_F0114_F0250 times 4 dw F_0_114, F_0_250
|
||||
PW_MF016_MF033 times 4 dw -F_0_168, -F_0_331
|
||||
PW_MF008_MF041 times 4 dw -F_0_081, -F_0_418
|
||||
PD_ONEHALFM1_CJ times 4 dd (1 << (SCALEBITS - 1)) - 1 + \
|
||||
(CENTERJSAMPLE << SCALEBITS)
|
||||
PD_ONEHALF times 4 dd (1 << (SCALEBITS - 1))
|
||||
|
||||
alignz 32
|
||||
|
||||
; --------------------------------------------------------------------------
|
||||
SECTION SEG_TEXT
|
||||
BITS 32
|
||||
|
||||
%include "jccolext-sse2.asm"
|
||||
|
||||
%undef RGB_RED
|
||||
%undef RGB_GREEN
|
||||
%undef RGB_BLUE
|
||||
%undef RGB_PIXELSIZE
|
||||
%define RGB_RED EXT_RGB_RED
|
||||
%define RGB_GREEN EXT_RGB_GREEN
|
||||
%define RGB_BLUE EXT_RGB_BLUE
|
||||
%define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
|
||||
%define jsimd_rgb_ycc_convert_sse2 jsimd_extrgb_ycc_convert_sse2
|
||||
%include "jccolext-sse2.asm"
|
||||
|
||||
%undef RGB_RED
|
||||
%undef RGB_GREEN
|
||||
%undef RGB_BLUE
|
||||
%undef RGB_PIXELSIZE
|
||||
%define RGB_RED EXT_RGBX_RED
|
||||
%define RGB_GREEN EXT_RGBX_GREEN
|
||||
%define RGB_BLUE EXT_RGBX_BLUE
|
||||
%define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
|
||||
%define jsimd_rgb_ycc_convert_sse2 jsimd_extrgbx_ycc_convert_sse2
|
||||
%include "jccolext-sse2.asm"
|
||||
|
||||
%undef RGB_RED
|
||||
%undef RGB_GREEN
|
||||
%undef RGB_BLUE
|
||||
%undef RGB_PIXELSIZE
|
||||
%define RGB_RED EXT_BGR_RED
|
||||
%define RGB_GREEN EXT_BGR_GREEN
|
||||
%define RGB_BLUE EXT_BGR_BLUE
|
||||
%define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
|
||||
%define jsimd_rgb_ycc_convert_sse2 jsimd_extbgr_ycc_convert_sse2
|
||||
%include "jccolext-sse2.asm"
|
||||
|
||||
%undef RGB_RED
|
||||
%undef RGB_GREEN
|
||||
%undef RGB_BLUE
|
||||
%undef RGB_PIXELSIZE
|
||||
%define RGB_RED EXT_BGRX_RED
|
||||
%define RGB_GREEN EXT_BGRX_GREEN
|
||||
%define RGB_BLUE EXT_BGRX_BLUE
|
||||
%define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
|
||||
%define jsimd_rgb_ycc_convert_sse2 jsimd_extbgrx_ycc_convert_sse2
|
||||
%include "jccolext-sse2.asm"
|
||||
|
||||
%undef RGB_RED
|
||||
%undef RGB_GREEN
|
||||
%undef RGB_BLUE
|
||||
%undef RGB_PIXELSIZE
|
||||
%define RGB_RED EXT_XBGR_RED
|
||||
%define RGB_GREEN EXT_XBGR_GREEN
|
||||
%define RGB_BLUE EXT_XBGR_BLUE
|
||||
%define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
|
||||
%define jsimd_rgb_ycc_convert_sse2 jsimd_extxbgr_ycc_convert_sse2
|
||||
%include "jccolext-sse2.asm"
|
||||
|
||||
%undef RGB_RED
|
||||
%undef RGB_GREEN
|
||||
%undef RGB_BLUE
|
||||
%undef RGB_PIXELSIZE
|
||||
%define RGB_RED EXT_XRGB_RED
|
||||
%define RGB_GREEN EXT_XRGB_GREEN
|
||||
%define RGB_BLUE EXT_XRGB_BLUE
|
||||
%define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
|
||||
%define jsimd_rgb_ycc_convert_sse2 jsimd_extxrgb_ycc_convert_sse2
|
||||
%include "jccolext-sse2.asm"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user