~akirad/cinecutie/trunk

« back to all changes in this revision

Viewing changes to quicktime/ffmpeg/libavutil/base64.c

  • Committer: Paolo Rampino
  • Date: 2010-03-06 18:08:30 UTC
  • Revision ID: git-v1:9d525e02347cedf5c7cbe9ecbf5d50b83c26f5e4
Updated ffmpeg, now open also flv with aac codecs

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Base64.c
3
2
 * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com)
4
3
 *
5
4
 * This file is part of FFmpeg.
20
19
 */
21
20
 
22
21
/**
23
 
* @file base64.c
24
 
 * @brief Base64 Encode/Decode
 
22
 * @file libavutil/base64.c
 
23
 * @brief Base64 encode/decode
25
24
 * @author Ryan Martell <rdm4@martellventures.com> (with lots of Michael)
26
25
 */
27
26
 
43
42
    0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33
44
43
};
45
44
 
46
 
int av_base64_decode(uint8_t * out, const char *in, int out_length)
 
45
int av_base64_decode(uint8_t *out, const char *in, int out_size)
47
46
{
48
47
    int i, v;
49
48
    uint8_t *dst = out;
51
50
    v = 0;
52
51
    for (i = 0; in[i] && in[i] != '='; i++) {
53
52
        unsigned int index= in[i]-43;
54
 
        if (index>=(sizeof(map2)/sizeof(map2[0])) || map2[index] == 0xff)
 
53
        if (index>=FF_ARRAY_ELEMS(map2) || map2[index] == 0xff)
55
54
            return -1;
56
55
        v = (v << 6) + map2[index];
57
56
        if (i & 3) {
58
 
            if (dst - out < out_length) {
 
57
            if (dst - out < out_size) {
59
58
                *dst++ = v >> (6 - 2 * (i & 3));
60
59
            }
61
60
        }
65
64
}
66
65
 
67
66
/*****************************************************************************
68
 
* b64_encode: stolen from VLC's http.c
69
 
* simplified by michael
70
 
* fixed edge cases and made it work from data (vs. strings) by ryan.
 
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.
71
70
*****************************************************************************/
72
71
 
73
 
char *av_base64_encode(char * buf, int buf_len, const uint8_t * src, int len)
 
72
char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size)
74
73
{
75
74
    static const char b64[] =
76
75
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
77
76
    char *ret, *dst;
78
77
    unsigned i_bits = 0;
79
78
    int i_shift = 0;
80
 
    int bytes_remaining = len;
 
79
    int bytes_remaining = in_size;
81
80
 
82
 
    if (len >= UINT_MAX / 4 ||
83
 
        buf_len < len * 4 / 3 + 12)
 
81
    if (in_size >= UINT_MAX / 4 ||
 
82
        out_size < (in_size+2) / 3 * 4 + 1)
84
83
        return NULL;
85
 
    ret = dst = buf;
 
84
    ret = dst = out;
86
85
    while (bytes_remaining) {
87
 
        i_bits = (i_bits << 8) + *src++;
 
86
        i_bits = (i_bits << 8) + *in++;
88
87
        bytes_remaining--;
89
88
        i_shift += 8;
90
89
 
100
99
    return ret;
101
100
}
102
101
 
103
 
// #define TEST_BASE64
104
 
 
105
 
#ifdef TEST_BASE64
106
 
#include "avutil.h"
107
 
 
108
 
int b64test()
109
 
{
110
 
    int numerr = 0;
111
 
    int len;
112
 
    int numtest = 1;
113
 
    uint8_t decode[1000];
 
102
#ifdef TEST
 
103
 
 
104
#undef printf
 
105
 
 
106
#define MAX_DATA_SIZE    1024
 
107
#define MAX_ENCODED_SIZE 2048
 
108
 
 
109
int test_encode_decode(const uint8_t *data, unsigned int data_size, const char *encoded_ref)
 
110
{
 
111
    char  encoded[MAX_ENCODED_SIZE];
 
112
    uint8_t data2[MAX_DATA_SIZE];
 
113
    int data2_size, max_data2_size = MAX_DATA_SIZE;
 
114
 
 
115
    if (!av_base64_encode(encoded, MAX_ENCODED_SIZE, data, data_size)) {
 
116
        printf("Failed: cannot encode the input data\n");
 
117
        return 1;
 
118
    }
 
119
    if (encoded_ref && strcmp(encoded, encoded_ref)) {
 
120
        printf("Failed: encoded string differs from reference\n"
 
121
               "Encoded:\n%s\nReference:\n%s\n", encoded, encoded_ref);
 
122
        return 1;
 
123
    }
 
124
 
 
125
    if ((data2_size = av_base64_decode(data2, encoded, max_data2_size)) < 0) {
 
126
        printf("Failed: cannot decode the encoded string\n"
 
127
               "Encoded:\n%s\n", encoded);
 
128
        return 1;
 
129
    }
 
130
    if (memcmp(data2, data, data_size)) {
 
131
        printf("Failed: encoded/decoded data differs from original data\n");
 
132
        return 1;
 
133
    }
 
134
 
 
135
    printf("Passed!\n");
 
136
    return 0;
 
137
}
 
138
 
 
139
int main(void)
 
140
{
 
141
    int i, error_count = 0;
114
142
    struct test {
115
 
        void *data;
116
 
        int len;
117
 
        const char *result;
118
 
    } *t, tests[] = {
119
 
        {
120
 
        "", 0, ""}, {
121
 
        "1", 1, "MQ=="}, {
122
 
        "22", 2, "MjI="}, {
123
 
        "333", 3, "MzMz"}, {
124
 
        "4444", 4, "NDQ0NA=="}, {
125
 
        "55555", 5, "NTU1NTU="}, {
126
 
        "abc:def", 7, "YWJjOmRlZg=="}, {
127
 
        NULL}
 
143
        const uint8_t *data;
 
144
        const char *encoded_ref;
 
145
    } tests[] = {
 
146
        { "",        ""},
 
147
        { "1",       "MQ=="},
 
148
        { "22",      "MjI="},
 
149
        { "333",     "MzMz"},
 
150
        { "4444",    "NDQ0NA=="},
 
151
        { "55555",   "NTU1NTU="},
 
152
        { "666666",  "NjY2NjY2"},
 
153
        { "abc:def", "YWJjOmRlZg=="},
128
154
    };
129
 
    for (t = tests; t->data; t++) {
130
 
        char *str;
131
 
 
132
 
        av_log(NULL, AV_LOG_ERROR, "Encoding %s...\n", (char *) t->data);
133
 
        str = av_base64_encode(t->data, t->len);
134
 
        if (str) {
135
 
            av_log(NULL, AV_LOG_ERROR, "Encoded to %s...\n", str);
136
 
            if (strcmp(str, t->result) != 0) {
137
 
                av_log(NULL, AV_LOG_ERROR, "failed test %d: %s != %s\n",
138
 
                       numtest, str, t->result);
139
 
                numerr++;
140
 
            }
141
 
            av_free(str);
142
 
        }
143
 
 
144
 
        av_log(NULL, AV_LOG_ERROR, "Done encoding, about to decode...\n");
145
 
        len = av_base64_decode(decode, t->result, sizeof(decode));
146
 
        if (len != t->len) {
147
 
            av_log(NULL, AV_LOG_ERROR, "failed test %d: len %d != %d\n",
148
 
                   numtest, len, t->len);
149
 
            numerr++;
150
 
        } else if (memcmp(decode, t->data, t->len) != 0) {
151
 
            av_log(NULL, AV_LOG_ERROR, "failed test %d: data\n", numtest);
152
 
            numerr++;
153
 
        } else {
154
 
            av_log(NULL, AV_LOG_ERROR, "Decoded to %s\n",
155
 
                   (char *) t->data);
156
 
        }
157
 
        numtest++;
158
 
    }
159
 
 
160
 
#undef srand
161
 
#undef rand
162
 
 
163
 
    {
164
 
        int test_count;
165
 
        srand(123141);          // time(NULL));
166
 
        for (test_count = 0; test_count < 100; test_count++) {
167
 
            int size = rand() % 1024;
168
 
            int ii;
169
 
            uint8_t *data;
170
 
            char *encoded_result;
171
 
 
172
 
            av_log(NULL, AV_LOG_ERROR, "Test %d: Size %d bytes...",
173
 
                   test_count, size);
174
 
            data = (uint8_t *) av_malloc(size);
175
 
            for (ii = 0; ii < size; ii++) {
176
 
                data[ii] = rand() % 255;
177
 
            }
178
 
 
179
 
            encoded_result = av_base64_encode(data, size);
180
 
            if (encoded_result) {
181
 
                int decode_buffer_size = size + 10;     // try without 10 as well
182
 
                uint8_t *decode_buffer = av_malloc(decode_buffer_size);
183
 
                if (decode_buffer) {
184
 
                    int decoded_size =
185
 
                        av_base64_decode(decode_buffer, encoded_result,
186
 
                                   decode_buffer_size);
187
 
 
188
 
                    if (decoded_size != size) {
189
 
                        av_log(NULL, AV_LOG_ERROR,
190
 
                               "Decoded/Encoded size mismatch (%d != %d)\n",
191
 
                               decoded_size, size);
192
 
                    } else {
193
 
                        if (memcmp(decode_buffer, data, decoded_size) == 0) {
194
 
                            av_log(NULL, AV_LOG_ERROR, "Passed!\n");
195
 
                        } else {
196
 
                            av_log(NULL, AV_LOG_ERROR,
197
 
                                   "Failed (Data differs)!\n");
198
 
                        }
199
 
                    }
200
 
                    av_free(decode_buffer);
201
 
                }
202
 
 
203
 
                av_free(encoded_result);
204
 
            }
205
 
        }
206
 
    }
207
 
 
208
 
    // these are invalid strings, that it currently decodes (which it probably shouldn't?)
209
 
    {
210
 
        uint8_t str[32];
211
 
        if (av_base64_decode(str, "M=M=", sizeof(str)) != -1) {
212
 
            av_log(NULL, AV_LOG_ERROR,
213
 
                   "failed test %d: successful decode of `M=M='\n",
214
 
                   numtest++);
215
 
            numerr++;
216
 
        }
217
 
        if (av_base64_decode(str, "MQ===", sizeof(str)) != -1) {
218
 
            av_log(NULL, AV_LOG_ERROR,
219
 
                   "failed test %d: successful decode of `MQ==='\n",
220
 
                   numtest++);
221
 
            numerr++;
222
 
        }
223
 
    }
224
 
 
225
 
    return numerr;
 
155
 
 
156
    printf("Encoding/decoding tests\n");
 
157
    for (i = 0; i < FF_ARRAY_ELEMS(tests); i++)
 
158
        error_count += test_encode_decode(tests[i].data, strlen(tests[i].data), tests[i].encoded_ref);
 
159
 
 
160
    return error_count;
226
161
}
 
162
 
227
163
#endif
228