avutil/hwcontext_cuda: add support for nvenc rgb formats
[ffmpeg.git] / libavutil / cast5.c
index 2309223..445eb55 100644 (file)
 #include "intreadwrite.h"
 #include "attributes.h"
 
-#define IA(x) ((x)>>24)
-#define IB(x) (((x)>>16) & 0xff)
-#define IC(x) (((x)>>8) & 0xff)
+#define IA(x) ((x) >> 24)
+#define IB(x) (((x) >> 16) & 0xff)
+#define IC(x) (((x) >> 8) & 0xff)
 #define ID(x) ((x) & 0xff)
 
-#define LR(x,c) (((x)<<(c))|((x)>>(32-(c))))
+#define LR(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
 
-#define F3(l,r,i)                                       \
-    do {                                                \
-        I=LR(cs->Km[i]-r,cs->Kr[i]);                    \
-        f=((S1[IA(I)]+S2[IB(I)])^S3[IC(I)])-S4[ID(I)];  \
-        l=f^l;                                          \
+#define F3(l, r, i)                                                                                  \
+    do {                                                                                             \
+        I = LR(cs->Km[i] - r, cs->Kr[i]);                                                            \
+        f = ((S1[IA(I)] + S2[IB(I)]) ^ S3[IC(I)]) - S4[ID(I)];                                       \
+        l = f ^ l;                                                                                   \
     } while (0)
 
-#define F2(l,r,i)                                       \
-    do {                                                \
-        I=LR(cs->Km[i]^r,cs->Kr[i]);                    \
-        f=((S1[IA(I)]-S2[IB(I)])+S3[IC(I)])^S4[ID(I)];  \
-        l=f^l;                                          \
+#define F2(l, r, i)                                                                                  \
+    do {                                                                                             \
+        I = LR(cs->Km[i] ^ r, cs->Kr[i]);                                                            \
+        f = ((S1[IA(I)] - S2[IB(I)]) + S3[IC(I)]) ^ S4[ID(I)];                                       \
+        l = f ^ l;                                                                                   \
     } while (0)
 
-#define F1(l,r,i)                                       \
-    do {                                                \
-        I=LR(cs->Km[i]+r,cs->Kr[i]);                    \
-        f=((S1[IA(I)]^S2[IB(I)])-S3[IC(I)])+S4[ID(I)];  \
-        l=f^l;                                          \
+#define F1(l, r, i)                                                                                  \
+    do {                                                                                             \
+        I = LR(cs->Km[i] + r, cs->Kr[i]);                                                            \
+        f = ((S1[IA(I)] ^ S2[IB(I)]) - S3[IC(I)]) + S4[ID(I)];                                       \
+        l = f ^ l;                                                                                   \
     } while (0)
 
-#define COMPUTE_Z                                                                      \
-    do {                                                                               \
-        z[0]=x[0]^S5[IB(x[3])]^S6[ID(x[3])]^S7[IA(x[3])]^S8[IC(x[3])]^S7[IA(x[2])];    \
-        z[1]=x[2]^S5[IA(z[0])]^S6[IC(z[0])]^S7[IB(z[0])]^S8[ID(z[0])]^S8[IC(x[2])];    \
-        z[2]=x[3]^S5[ID(z[1])]^S6[IC(z[1])]^S7[IB(z[1])]^S8[IA(z[1])]^S5[IB(x[2])];    \
-        z[3]=x[1]^S5[IC(z[2])]^S6[IB(z[2])]^S7[ID(z[2])]^S8[IA(z[2])]^S6[ID(x[2])];    \
+#define COMPUTE_Z                                                                                    \
+    do {                                                                                             \
+        z[0] = x[0] ^ S5[IB(x[3])] ^ S6[ID(x[3])] ^ S7[IA(x[3])] ^ S8[IC(x[3])] ^ S7[IA(x[2])];      \
+        z[1] = x[2] ^ S5[IA(z[0])] ^ S6[IC(z[0])] ^ S7[IB(z[0])] ^ S8[ID(z[0])] ^ S8[IC(x[2])];      \
+        z[2] = x[3] ^ S5[ID(z[1])] ^ S6[IC(z[1])] ^ S7[IB(z[1])] ^ S8[IA(z[1])] ^ S5[IB(x[2])];      \
+        z[3] = x[1] ^ S5[IC(z[2])] ^ S6[IB(z[2])] ^ S7[ID(z[2])] ^ S8[IA(z[2])] ^ S6[ID(x[2])];      \
     } while (0)
 
-#define COMPUTE_X                                                                      \
-    do {                                                                               \
-        x[0]=z[2]^S5[IB(z[1])]^S6[ID(z[1])]^S7[IA(z[1])]^S8[IC(z[1])]^S7[IA(z[0])];    \
-        x[1]=z[0]^S5[IA(x[0])]^S6[IC(x[0])]^S7[IB(x[0])]^S8[ID(x[0])]^S8[IC(z[0])];    \
-        x[2]=z[1]^S5[ID(x[1])]^S6[IC(x[1])]^S7[IB(x[1])]^S8[IA(x[1])]^S5[IB(z[0])];    \
-        x[3]=z[3]^S5[IC(x[2])]^S6[IB(x[2])]^S7[ID(x[2])]^S8[IA(x[2])]^S6[ID(z[0])];    \
+#define COMPUTE_X                                                                                    \
+    do {                                                                                             \
+        x[0] = z[2] ^ S5[IB(z[1])] ^ S6[ID(z[1])] ^ S7[IA(z[1])] ^ S8[IC(z[1])] ^ S7[IA(z[0])];      \
+        x[1] = z[0] ^ S5[IA(x[0])] ^ S6[IC(x[0])] ^ S7[IB(x[0])] ^ S8[ID(x[0])] ^ S8[IC(z[0])];      \
+        x[2] = z[1] ^ S5[ID(x[1])] ^ S6[IC(x[1])] ^ S7[IB(x[1])] ^ S8[IA(x[1])] ^ S5[IB(z[0])];      \
+        x[3] = z[3] ^ S5[IC(x[2])] ^ S6[IB(x[2])] ^ S7[ID(x[2])] ^ S8[IA(x[2])] ^ S6[ID(z[0])];      \
     } while (0)
 
 
@@ -74,9 +74,9 @@ typedef struct AVCAST5 {
     int rounds;
 } AVCAST5;
 
-const int av_cast5_size= sizeof(AVCAST5);
+const int av_cast5_size = sizeof(AVCAST5);
 
-static const uint32_t S1[256]={
+static const uint32_t S1[256] = {
     0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
     0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
     0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
@@ -108,9 +108,10 @@ static const uint32_t S1[256]={
     0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
     0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
     0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
-    0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf};
+    0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
+};
 
-static const uint32_t S2[256]={
+static const uint32_t S2[256] = {
     0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
     0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
     0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
@@ -142,9 +143,10 @@ static const uint32_t S2[256]={
     0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
     0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
     0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
-    0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1};
+    0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1
+};
 
-static const uint32_t S3[256]={
+static const uint32_t S3[256] = {
     0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
     0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
     0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
@@ -176,9 +178,10 @@ static const uint32_t S3[256]={
     0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
     0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
     0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
-    0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783};
+    0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783
+};
 
-static const uint32_t S4[256]={
+static const uint32_t S4[256] = {
     0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
     0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
     0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
@@ -210,9 +213,10 @@ static const uint32_t S4[256]={
     0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
     0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
     0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
-    0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2};
+    0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
+};
 
-static const uint32_t S5[256]={
+static const uint32_t S5[256] = {
     0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
     0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
     0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
@@ -244,9 +248,10 @@ static const uint32_t S5[256]={
     0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
     0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
     0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
-    0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4};
+    0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4
+};
 
-static const uint32_t S6[256]={
+static const uint32_t S6[256] = {
     0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
     0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
     0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
@@ -272,15 +277,16 @@ static const uint32_t S6[256]={
     0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
     0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
     0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
-   0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
+    0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
     0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
     0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
     0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
     0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
     0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
-    0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f};
+    0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f
+};
 
-static const uint32_t S7[256]={
+static const uint32_t S7[256] = {
     0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
     0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
     0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
@@ -312,9 +318,10 @@ static const uint32_t S7[256]={
     0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
     0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
     0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
-    0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3};
+    0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3
+};
 
-static const uint32_t S8[256]={
+static const uint32_t S8[256] = {
     0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
     0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
     0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
@@ -346,95 +353,99 @@ static const uint32_t S8[256]={
     0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
     0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
     0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
-    0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e};
+    0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e
+};
 
-static void generate_round_keys(int rnds,uint32_t* K, uint32_t* x, uint32_t* z)
+static void generate_round_keys(int rnds, uint32_t* K, uint32_t* x, uint32_t* z)
 {
     COMPUTE_Z;
 
-    K[1]=S5[IA(z[2])]^S6[IB(z[2])]^S7[ID(z[1])]^S8[IC(z[1])]^S5[IC(z[0])];
-    K[2]=S5[IC(z[2])]^S6[ID(z[2])]^S7[IB(z[1])]^S8[IA(z[1])]^S6[IC(z[1])];
-    K[3]=S5[IA(z[3])]^S6[IB(z[3])]^S7[ID(z[0])]^S8[IC(z[0])]^S7[IB(z[2])];
-    K[4]=S5[IC(z[3])]^S6[ID(z[3])]^S7[IB(z[0])]^S8[IA(z[0])]^S8[IA(z[3])];
+    K[1] = S5[IA(z[2])] ^ S6[IB(z[2])] ^ S7[ID(z[1])] ^ S8[IC(z[1])] ^ S5[IC(z[0])];
+    K[2] = S5[IC(z[2])] ^ S6[ID(z[2])] ^ S7[IB(z[1])] ^ S8[IA(z[1])] ^ S6[IC(z[1])];
+    K[3] = S5[IA(z[3])] ^ S6[IB(z[3])] ^ S7[ID(z[0])] ^ S8[IC(z[0])] ^ S7[IB(z[2])];
+    K[4] = S5[IC(z[3])] ^ S6[ID(z[3])] ^ S7[IB(z[0])] ^ S8[IA(z[0])] ^ S8[IA(z[3])];
 
     COMPUTE_X;
 
-    K[5]=S5[ID(x[0])]^S6[IC(x[0])]^S7[IA(x[3])]^S8[IB(x[3])]^S5[IA(x[2])];
-    K[6]=S5[IB(x[0])]^S6[IA(x[0])]^S7[IC(x[3])]^S8[ID(x[3])]^S6[IB(x[3])];
-    K[7]=S5[ID(x[1])]^S6[IC(x[1])]^S7[IA(x[2])]^S8[IB(x[2])]^S7[ID(x[0])];
-    K[8]=S5[IB(x[1])]^S6[IA(x[1])]^S7[IC(x[2])]^S8[ID(x[2])]^S8[ID(x[1])];
+    K[5] = S5[ID(x[0])] ^ S6[IC(x[0])] ^ S7[IA(x[3])] ^ S8[IB(x[3])] ^ S5[IA(x[2])];
+    K[6] = S5[IB(x[0])] ^ S6[IA(x[0])] ^ S7[IC(x[3])] ^ S8[ID(x[3])] ^ S6[IB(x[3])];
+    K[7] = S5[ID(x[1])] ^ S6[IC(x[1])] ^ S7[IA(x[2])] ^ S8[IB(x[2])] ^ S7[ID(x[0])];
+    K[8] = S5[IB(x[1])] ^ S6[IA(x[1])] ^ S7[IC(x[2])] ^ S8[ID(x[2])] ^ S8[ID(x[1])];
 
     COMPUTE_Z;
 
-    K[9]=S5[ID(z[0])]^S6[IC(z[0])]^S7[IA(z[3])]^S8[IB(z[3])]^S5[IB(z[2])];
-    K[10]=S5[IB(z[0])]^S6[IA(z[0])]^S7[IC(z[3])]^S8[ID(z[3])]^S6[IA(z[3])];
-    K[11]=S5[ID(z[1])]^S6[IC(z[1])]^S7[IA(z[2])]^S8[IB(z[2])]^S7[IC(z[0])];
-    K[12]=S5[IB(z[1])]^S6[IA(z[1])]^S7[IC(z[2])]^S8[ID(z[2])]^S8[IC(z[1])];
+    K[9] = S5[ID(z[0])] ^ S6[IC(z[0])] ^ S7[IA(z[3])] ^ S8[IB(z[3])] ^ S5[IB(z[2])];
+    K[10] = S5[IB(z[0])] ^ S6[IA(z[0])] ^ S7[IC(z[3])] ^ S8[ID(z[3])] ^ S6[IA(z[3])];
+    K[11] = S5[ID(z[1])] ^ S6[IC(z[1])] ^ S7[IA(z[2])] ^ S8[IB(z[2])] ^ S7[IC(z[0])];
+    K[12] = S5[IB(z[1])] ^ S6[IA(z[1])] ^ S7[IC(z[2])] ^ S8[ID(z[2])] ^ S8[IC(z[1])];
 
     COMPUTE_X;
 
-    if (rnds==16) {
-        K[13]=S5[IA(x[2])]^S6[IB(x[2])]^S7[ID(x[1])]^S8[IC(x[1])]^S5[ID(x[0])];
-        K[14]=S5[IC(x[2])]^S6[ID(x[2])]^S7[IB(x[1])]^S8[IA(x[1])]^S6[ID(x[1])];
-        K[15]=S5[IA(x[3])]^S6[IB(x[3])]^S7[ID(x[0])]^S8[IC(x[0])]^S7[IA(x[2])];
-        K[16]=S5[IC(x[3])]^S6[ID(x[3])]^S7[IB(x[0])]^S8[IA(x[0])]^S8[IB(x[3])];
+    if (rnds == 16) {
+        K[13] = S5[IA(x[2])] ^ S6[IB(x[2])] ^ S7[ID(x[1])] ^ S8[IC(x[1])] ^ S5[ID(x[0])];
+        K[14] = S5[IC(x[2])] ^ S6[ID(x[2])] ^ S7[IB(x[1])] ^ S8[IA(x[1])] ^ S6[ID(x[1])];
+        K[15] = S5[IA(x[3])] ^ S6[IB(x[3])] ^ S7[ID(x[0])] ^ S8[IC(x[0])] ^ S7[IA(x[2])];
+        K[16] = S5[IC(x[3])] ^ S6[ID(x[3])] ^ S7[IB(x[0])] ^ S8[IA(x[0])] ^ S8[IB(x[3])];
     }
 }
 
-static void encipher(AVCAST5* cs,uint8_t* dst,const uint8_t* src)
+static void encipher(AVCAST5* cs, uint8_t* dst, const uint8_t* src)
 {
-    uint32_t r,l,f,I;
-    l=AV_RB32(src);
-    r=AV_RB32(src+4);
-    F1(l,r,1);
-    F2(r,l,2);
-    F3(l,r,3);
-    F1(r,l,4);
-    F2(l,r,5);
-    F3(r,l,6);
-    F1(l,r,7);
-    F2(r,l,8);
-    F3(l,r,9);
-    F1(r,l,10);
-    F2(l,r,11);
-    F3(r,l,12);
-    if (cs->rounds==16) {
-        F1(l,r,13);
-        F2(r,l,14);
-        F3(l,r,15);
-        F1(r,l,16);
+    uint32_t r, l, f, I;
+    l = AV_RB32(src);
+    r = AV_RB32(src + 4);
+    F1(l, r, 1);
+    F2(r, l, 2);
+    F3(l, r, 3);
+    F1(r, l, 4);
+    F2(l, r, 5);
+    F3(r, l, 6);
+    F1(l, r, 7);
+    F2(r, l, 8);
+    F3(l, r, 9);
+    F1(r, l, 10);
+    F2(l, r, 11);
+    F3(r, l, 12);
+    if (cs->rounds == 16) {
+        F1(l, r, 13);
+        F2(r, l, 14);
+        F3(l, r, 15);
+        F1(r, l, 16);
     }
-    AV_WB32(dst,r);
-    AV_WB32(dst+4,l);
+    AV_WB32(dst, r);
+    AV_WB32(dst + 4, l);
 }
 
-static void decipher(AVCAST5* cs,uint8_t* dst,const uint8_t* src)
+static void decipher(AVCAST5* cs, uint8_t* dst, const uint8_t* src, uint8_t *iv)
 {
-    uint32_t f,I,r,l;
-    l=AV_RB32(src);
-    r=AV_RB32(src+4);
-    if (cs->rounds==16) {
-        F1(l,r,16);
-        F3(r,l,15);
-        F2(l,r,14);
-        F1(r,l,13);
+    uint32_t f, I, r, l;
+    l = AV_RB32(src);
+    r = AV_RB32(src + 4);
+    if (cs->rounds == 16) {
+        F1(l, r, 16);
+        F3(r, l, 15);
+        F2(l, r, 14);
+        F1(r, l, 13);
     }
-    F3(l,r,12);
-    F2(r,l,11);
-    F1(l,r,10);
-    F3(r,l,9);
-    F2(l,r,8);
-    F1(r,l,7);
-    F3(l,r,6);
-    F2(r,l,5);
-    F1(l,r,4);
-    F3(r,l,3);
-    F2(l,r,2);
-    F1(r,l,1);
-
-    AV_WB32(dst,r);
-    AV_WB32(dst+4,l);
-
+    F3(l, r, 12);
+    F2(r, l, 11);
+    F1(l, r, 10);
+    F3(r, l, 9);
+    F2(l, r, 8);
+    F1(r, l, 7);
+    F3(l, r, 6);
+    F2(r, l, 5);
+    F1(l, r, 4);
+    F3(r, l, 3);
+    F2(l, r, 2);
+    F1(r, l, 1);
+    if (iv) {
+        r ^= AV_RB32(iv);
+        l ^= AV_RB32(iv + 4);
+        memcpy(iv, src, 8);
+    }
+    AV_WB32(dst, r);
+    AV_WB32(dst + 4, l);
 }
 
 struct AVCAST5 *av_cast5_alloc(void)
@@ -446,96 +457,51 @@ av_cold int av_cast5_init(AVCAST5* cs, const uint8_t *key, int key_bits)
 {
     uint8_t newKey[16];
     int i;
-    uint32_t p[4],q[4];
-    if (key_bits%8||key_bits<40||key_bits>128)
-        return -1;
-    memset(newKey,0,sizeof(newKey));
-    memcpy(newKey,key,key_bits>>3);
-
-    cs->rounds = key_bits<=80 ? 12:16;
-    for (i=0;i<4;i++)
-        q[i]=AV_RB32(newKey+(4*i));
-    generate_round_keys(cs->rounds,cs->Km,q,p);
-    generate_round_keys(cs->rounds,cs->Kr,q,p);
-    for (i=0;i<cs->rounds;i++)
-        cs->Kr[i]=cs->Kr[i]&0x1f;
+    uint32_t p[4], q[4];
+    if (key_bits % 8 || key_bits < 40 || key_bits > 128)
+        return AVERROR(EINVAL);
+    memset(newKey, 0, sizeof(newKey));
+    memcpy(newKey, key, key_bits >> 3);
+
+    cs->rounds = key_bits <= 80 ? 12 : 16;
+    for (i = 0; i < 4; i++)
+        q[i] = AV_RB32(newKey + (4 * i));
+    generate_round_keys(cs->rounds, cs->Km, q, p);
+    generate_round_keys(cs->rounds, cs->Kr, q, p);
+    for (i = 0; i <= cs->rounds; i++)
+        cs->Kr[i] = cs->Kr[i] & 0x1f;
     return 0;
 }
 
-void av_cast5_crypt(AVCAST5* cs, uint8_t* dst, const uint8_t* src, int count, int decrypt)
+void av_cast5_crypt2(AVCAST5* cs, uint8_t* dst, const uint8_t* src, int count, uint8_t *iv, int decrypt)
 {
+    int i;
     while (count--) {
-        if (decrypt){
-            decipher(cs,dst,src);
+        if (decrypt) {
+            decipher(cs, dst, src, iv);
         } else {
-            encipher(cs,dst,src);
+            if (iv) {
+                for (i = 0; i < 8; i++)
+                    dst[i] = src[i] ^ iv[i];
+                encipher(cs, dst, dst);
+                memcpy(iv, dst, 8);
+            } else {
+                encipher(cs, dst, src);
+            }
         }
-        src=src+8;
-        dst=dst+8;
+        src = src + 8;
+        dst = dst + 8;
     }
 }
-
-#ifdef TEST
-#include<stdio.h>
-#include<stdlib.h>
-#include"log.h"
-
-int main(int argc, char** argv)
+void av_cast5_crypt(AVCAST5* cs, uint8_t* dst, const uint8_t* src, int count, int decrypt)
 {
-
-    static const uint8_t Key[3][16]={{0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9a},
-        {0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,0x23,0x45},
-        {0x01,0x23,0x45,0x67,0x12}};
-    static const uint8_t rpt[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
-    static const uint8_t rct[3][8]={{0x23,0x8b,0x4f,0xe5,0x84,0x7e,0x44,0xb2},
-        {0xeb,0x6a,0x71,0x1a,0x2c,0x02,0x27,0x1b},
-        {0x7a,0xc8,0x16,0xd1,0x6e,0x9b,0x30,0x2e}};
-    static const uint8_t rct2[2][16]={{0xee,0xa9,0xd0,0xa2,0x49,0xfd,0x3b,0xa6,0xb3,0x43,0x6f,0xb8,0x9d,0x6d,0xca,0x92},
-        {0xb2,0xc9,0x5e,0xb0,0x0c,0x31,0xad,0x71,0x80,0xac,0x05,0xb8,0xe8,0x3d,0x69,0x6e}};
-    static uint8_t rpt2[2][16];
-    int i,j,err=0;
-    static int key_bits[3]={128,80,40};
-    uint8_t temp[8];
-    AVCAST5 *cs;
-    cs=av_cast5_alloc();
-    if (!cs)
-        return 1;
-    for (j=0;j<3;j++){
-
-        av_cast5_init(cs,Key[j],key_bits[j]);
-        av_cast5_crypt(cs,temp,rpt,1,0);
-        for (i=0;i<8;i++){
-            if (rct[j][i]!=temp[i]){
-                av_log(NULL,AV_LOG_ERROR,"%d %02x %02x\n",i,rct[j][i],temp[i]);
-                err=1;
-            }
-        }
-
-        av_cast5_crypt(cs,temp,rct[j],1,1);
-        for (i=0;i<8;i++){
-            if (rpt[i]!=temp[i]){
-                av_log(NULL,AV_LOG_ERROR,"%d %02x %02x\n",i,rpt[i],temp[i]);
-                err=1;
-            }
-        }
-    }
-    memcpy(rpt2[0],Key[0],16);
-    memcpy(rpt2[1],Key[0],16);
-    for (i=0;i<1000000;i++){
-        av_cast5_init(cs,rpt2[1],128);
-        av_cast5_crypt(cs,rpt2[0],rpt2[0],2,0);
-        av_cast5_init(cs,rpt2[0],128);
-        av_cast5_crypt(cs,rpt2[1],rpt2[1],2,0);
-    }
-    for (j=0;j<2;j++){
-        for (i=0;i<16;i++){
-            if (rct2[j][i]!=rpt2[j][i]){
-                av_log(NULL,AV_LOG_ERROR,"%d %02x %02x\n",i,rct2[j][i],rpt2[j][i]);
-                err=1;
-            }
+    while (count--) {
+        if (decrypt){
+            decipher(cs, dst, src, NULL);
+        } else {
+            encipher(cs, dst, src);
         }
+        src = src + 8;
+        dst = dst + 8;
     }
-    av_free(cs);
-    return err;
 }
-#endif