Mercurial > libavutil.hg
annotate base64.c @ 728:1fa3820b1a84 libavutil
ARM asm for AV_RN*()
ARMv6 and later support unaligned loads and stores for single
word/halfword but not double/multiple. GCC is ignorant of this and
will always use bytewise accesses for unaligned data. Casting to an
int32_t pointer is dangerous since a load/store double or multiple
instruction might be used (this happens with some code in FFmpeg).
Implementing the AV_[RW]* macros with inline asm using only supported
instructions gives fast and safe unaligned accesses. ARM RVCT does
the right thing with generic code.
This gives an overall speedup of up to 10%.
author | mru |
---|---|
date | Sat, 18 Apr 2009 00:00:28 +0000 |
parents | 3f3e69baaaf8 |
children | 0795a743bda1 |
rev | line source |
---|---|
244 | 1 /* |
2 * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com) | |
3 * | |
4 * This file is part of FFmpeg. | |
5 * | |
6 * FFmpeg is free software; you can redistribute it and/or | |
7 * modify it under the terms of the GNU Lesser General Public | |
8 * License as published by the Free Software Foundation; either | |
9 * version 2.1 of the License, or (at your option) any later version. | |
10 * | |
11 * FFmpeg is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * Lesser General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU Lesser General Public | |
17 * License along with FFmpeg; if not, write to the Free Software | |
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
19 */ | |
20 | |
21 /** | |
642
70bdd5501662
Use full internal pathname in doxygen @file directives.
diego
parents:
636
diff
changeset
|
22 * @file libavutil/base64.c |
636 | 23 * @brief Base64 encode/decode |
244 | 24 * @author Ryan Martell <rdm4@martellventures.com> (with lots of Michael) |
25 */ | |
26 | |
27 #include "common.h" | |
28 #include "base64.h" | |
29 | |
30 /* ---------------- private code */ | |
428 | 31 static const uint8_t map2[] = |
244 | 32 { |
33 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36, | |
34 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, | |
35 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, | |
36 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, | |
37 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, | |
38 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, | |
39 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b, | |
40 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, | |
41 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, | |
42 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33 | |
43 }; | |
44 | |
659
d3cd35bec3d0
Cosmetics: "* out" -> "*out" for consistency with the other
stefano
parents:
658
diff
changeset
|
45 int av_base64_decode(uint8_t *out, const char *in, int out_size) |
244 | 46 { |
47 int i, v; | |
48 uint8_t *dst = out; | |
49 | |
50 v = 0; | |
51 for (i = 0; in[i] && in[i] != '='; i++) { | |
52 unsigned int index= in[i]-43; | |
581 | 53 if (index>=FF_ARRAY_ELEMS(map2) || map2[index] == 0xff) |
244 | 54 return -1; |
55 v = (v << 6) + map2[index]; | |
56 if (i & 3) { | |
656
eadb97de8dc0
Cosmetics: consistently prefer "size" over "len"/"length" for the
stefano
parents:
655
diff
changeset
|
57 if (dst - out < out_size) { |
244 | 58 *dst++ = v >> (6 - 2 * (i & 3)); |
59 } | |
60 } | |
61 } | |
62 | |
505 | 63 return dst - out; |
244 | 64 } |
65 | |
66 /***************************************************************************** | |
636 | 67 * b64_encode: Stolen from VLC's http.c. |
68 * Simplified by Michael. | |
69 * Fixed edge cases and made it work from data (vs. strings) by Ryan. | |
244 | 70 *****************************************************************************/ |
71 | |
658
cc7c1ea68a52
Cosmetics: rename the "size" parameter of av_base64_encode() to "in_size".
stefano
parents:
657
diff
changeset
|
72 char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size) |
244 | 73 { |
74 static const char b64[] = | |
75 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
76 char *ret, *dst; | |
77 unsigned i_bits = 0; | |
78 int i_shift = 0; | |
658
cc7c1ea68a52
Cosmetics: rename the "size" parameter of av_base64_encode() to "in_size".
stefano
parents:
657
diff
changeset
|
79 int bytes_remaining = in_size; |
244 | 80 |
658
cc7c1ea68a52
Cosmetics: rename the "size" parameter of av_base64_encode() to "in_size".
stefano
parents:
657
diff
changeset
|
81 if (in_size >= UINT_MAX / 4 || |
cc7c1ea68a52
Cosmetics: rename the "size" parameter of av_base64_encode() to "in_size".
stefano
parents:
657
diff
changeset
|
82 out_size < (in_size+2) / 3 * 4 + 1) |
244 | 83 return NULL; |
657
50112fafa1ef
Cosmetics: prefer out/in over buf/src for the parameter names of
stefano
parents:
656
diff
changeset
|
84 ret = dst = out; |
401 | 85 while (bytes_remaining) { |
657
50112fafa1ef
Cosmetics: prefer out/in over buf/src for the parameter names of
stefano
parents:
656
diff
changeset
|
86 i_bits = (i_bits << 8) + *in++; |
401 | 87 bytes_remaining--; |
88 i_shift += 8; | |
244 | 89 |
401 | 90 do { |
91 *dst++ = b64[(i_bits << 6 >> i_shift) & 0x3f]; | |
92 i_shift -= 6; | |
93 } while (i_shift > 6 || (bytes_remaining == 0 && i_shift > 0)); | |
94 } | |
95 while ((dst - ret) & 3) | |
96 *dst++ = '='; | |
244 | 97 *dst = '\0'; |
98 | |
99 return ret; | |
100 } | |
654
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
101 |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
102 #ifdef TEST |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
103 |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
104 #undef printf |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
105 |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
106 #define MAX_DATA_SIZE 1024 |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
107 #define MAX_ENCODED_SIZE 2048 |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
108 |
716
3f3e69baaaf8
Mark non-exported functions in test and example programs as static.
diego
parents:
659
diff
changeset
|
109 static int test_encode_decode(const uint8_t *data, unsigned int data_size, |
3f3e69baaaf8
Mark non-exported functions in test and example programs as static.
diego
parents:
659
diff
changeset
|
110 const char *encoded_ref) |
654
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
111 { |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
112 char encoded[MAX_ENCODED_SIZE]; |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
113 uint8_t data2[MAX_DATA_SIZE]; |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
114 int data2_size, max_data2_size = MAX_DATA_SIZE; |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
115 |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
116 if (!av_base64_encode(encoded, MAX_ENCODED_SIZE, data, data_size)) { |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
117 printf("Failed: cannot encode the input data\n"); |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
118 return 1; |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
119 } |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
120 if (encoded_ref && strcmp(encoded, encoded_ref)) { |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
121 printf("Failed: encoded string differs from reference\n" |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
122 "Encoded:\n%s\nReference:\n%s\n", encoded, encoded_ref); |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
123 return 1; |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
124 } |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
125 |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
126 if ((data2_size = av_base64_decode(data2, encoded, max_data2_size)) < 0) { |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
127 printf("Failed: cannot decode the encoded string\n" |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
128 "Encoded:\n%s\n", encoded); |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
129 return 1; |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
130 } |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
131 if (memcmp(data2, data, data_size)) { |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
132 printf("Failed: encoded/decoded data differs from original data\n"); |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
133 return 1; |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
134 } |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
135 |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
136 printf("Passed!\n"); |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
137 return 0; |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
138 } |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
139 |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
140 int main(void) |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
141 { |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
142 int i, error_count = 0; |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
143 struct test { |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
144 const uint8_t *data; |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
145 const char *encoded_ref; |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
146 } tests[] = { |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
147 { "", ""}, |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
148 { "1", "MQ=="}, |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
149 { "22", "MjI="}, |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
150 { "333", "MzMz"}, |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
151 { "4444", "NDQ0NA=="}, |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
152 { "55555", "NTU1NTU="}, |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
153 { "666666", "NjY2NjY2"}, |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
154 { "abc:def", "YWJjOmRlZg=="}, |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
155 }; |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
156 |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
157 printf("Encoding/decoding tests\n"); |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
158 for (i = 0; i < FF_ARRAY_ELEMS(tests); i++) |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
159 error_count += test_encode_decode(tests[i].data, strlen(tests[i].data), tests[i].encoded_ref); |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
160 |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
161 return error_count; |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
162 } |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
163 |
b751ac480294
Add a new test program for base64, based on that removed in r17024.
stefano
parents:
653
diff
changeset
|
164 #endif |