~ubuntu-branches/ubuntu/gutsy/blender/gutsy-security

« back to all changes in this revision

Viewing changes to extern/ffmpeg/libavformat/aviobuf.c

  • Committer: Bazaar Package Importer
  • Author(s): Lukas Fittl
  • Date: 2006-09-20 01:57:27 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20060920015727-gmoqlxwstx9wwqs3
Tags: 2.42a-1ubuntu1
* Merge from Debian unstable (Closes: Malone #55903). Remaining changes:
  - debian/genpot: Add python scripts from Lee June <blender@eyou.com> to
    generate a reasonable PO template from the sources. Since gettext is used
    in a highly nonstandard way, xgettext does not work for this job.
  - debian/rules: Call the scripts, generate po/blender.pot, and clean it up
    in the clean target.
  - Add a proper header to the generated PO template.
* debian/control: Build depend on libavformat-dev >= 3:0.cvs20060823-3.1,
  otherwise this package will FTBFS

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Buffered I/O for ffmpeg system
 
3
 * Copyright (c) 2000,2001 Fabrice Bellard
 
4
 *
 
5
 * This library is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU Lesser General Public
 
7
 * License as published by the Free Software Foundation; either
 
8
 * version 2 of the License, or (at your option) any later version.
 
9
 *
 
10
 * This library is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * Lesser General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU Lesser General Public
 
16
 * License along with this library; if not, write to the Free Software
 
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
18
 */
 
19
#include "avformat.h"
 
20
#include "avio.h"
 
21
#include <stdarg.h>
 
22
 
 
23
#define IO_BUFFER_SIZE 32768
 
24
 
 
25
int init_put_byte(ByteIOContext *s,
 
26
                  unsigned char *buffer,
 
27
                  int buffer_size,
 
28
                  int write_flag,
 
29
                  void *opaque,
 
30
                  int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
 
31
                  int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
 
32
                  offset_t (*seek)(void *opaque, offset_t offset, int whence))
 
33
{
 
34
    s->buffer = buffer;
 
35
    s->buffer_size = buffer_size;
 
36
    s->buf_ptr = buffer;
 
37
    s->write_flag = write_flag;
 
38
    if (!s->write_flag)
 
39
        s->buf_end = buffer;
 
40
    else
 
41
        s->buf_end = buffer + buffer_size;
 
42
    s->opaque = opaque;
 
43
    s->write_packet = write_packet;
 
44
    s->read_packet = read_packet;
 
45
    s->seek = seek;
 
46
    s->pos = 0;
 
47
    s->must_flush = 0;
 
48
    s->eof_reached = 0;
 
49
    s->error = 0;
 
50
    s->is_streamed = 0;
 
51
    s->max_packet_size = 0;
 
52
    s->update_checksum= NULL;
 
53
    return 0;
 
54
}
 
55
 
 
56
static void flush_buffer(ByteIOContext *s)
 
57
{
 
58
    if (s->buf_ptr > s->buffer) {
 
59
        if (s->write_packet && !s->error){
 
60
            int ret= s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer);
 
61
            if(ret < 0){
 
62
                s->error = ret;
 
63
            }
 
64
        }
 
65
        if(s->update_checksum){
 
66
            s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr);
 
67
            s->checksum_ptr= s->buffer;
 
68
        }
 
69
        s->pos += s->buf_ptr - s->buffer;
 
70
    }
 
71
    s->buf_ptr = s->buffer;
 
72
}
 
73
 
 
74
void put_byte(ByteIOContext *s, int b)
 
75
{
 
76
    *(s->buf_ptr)++ = b;
 
77
    if (s->buf_ptr >= s->buf_end)
 
78
        flush_buffer(s);
 
79
}
 
80
 
 
81
void put_buffer(ByteIOContext *s, const unsigned char *buf, int size)
 
82
{
 
83
    int len;
 
84
 
 
85
    while (size > 0) {
 
86
        len = (s->buf_end - s->buf_ptr);
 
87
        if (len > size)
 
88
            len = size;
 
89
        memcpy(s->buf_ptr, buf, len);
 
90
        s->buf_ptr += len;
 
91
 
 
92
        if (s->buf_ptr >= s->buf_end)
 
93
            flush_buffer(s);
 
94
 
 
95
        buf += len;
 
96
        size -= len;
 
97
    }
 
98
}
 
99
 
 
100
void put_flush_packet(ByteIOContext *s)
 
101
{
 
102
    flush_buffer(s);
 
103
    s->must_flush = 0;
 
104
}
 
105
 
 
106
offset_t url_fseek(ByteIOContext *s, offset_t offset, int whence)
 
107
{
 
108
    offset_t offset1;
 
109
 
 
110
    if (whence != SEEK_CUR && whence != SEEK_SET)
 
111
        return -EINVAL;
 
112
 
 
113
#ifdef CONFIG_MUXERS
 
114
    if (s->write_flag) {
 
115
        if (whence == SEEK_CUR) {
 
116
            offset1 = s->pos + (s->buf_ptr - s->buffer);
 
117
            if (offset == 0)
 
118
                return offset1;
 
119
            offset += offset1;
 
120
        }
 
121
        offset1 = offset - s->pos;
 
122
        if (!s->must_flush &&
 
123
            offset1 >= 0 && offset1 < (s->buf_end - s->buffer)) {
 
124
            /* can do the seek inside the buffer */
 
125
            s->buf_ptr = s->buffer + offset1;
 
126
        } else {
 
127
            if (!s->seek)
 
128
                return -EPIPE;
 
129
            flush_buffer(s);
 
130
            s->must_flush = 1;
 
131
            s->buf_ptr = s->buffer;
 
132
            s->seek(s->opaque, offset, SEEK_SET);
 
133
            s->pos = offset;
 
134
        }
 
135
    } else
 
136
#endif //CONFIG_MUXERS
 
137
    {
 
138
        if (whence == SEEK_CUR) {
 
139
            offset1 = s->pos - (s->buf_end - s->buffer) + (s->buf_ptr - s->buffer);
 
140
            if (offset == 0)
 
141
                return offset1;
 
142
            offset += offset1;
 
143
        }
 
144
        offset1 = offset - (s->pos - (s->buf_end - s->buffer));
 
145
        if (offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) {
 
146
            /* can do the seek inside the buffer */
 
147
            s->buf_ptr = s->buffer + offset1;
 
148
        } else {
 
149
            if (!s->seek)
 
150
                return -EPIPE;
 
151
            s->buf_ptr = s->buffer;
 
152
            s->buf_end = s->buffer;
 
153
            if (s->seek(s->opaque, offset, SEEK_SET) == (offset_t)-EPIPE)
 
154
                return -EPIPE;
 
155
            s->pos = offset;
 
156
        }
 
157
        s->eof_reached = 0;
 
158
    }
 
159
    return offset;
 
160
}
 
161
 
 
162
void url_fskip(ByteIOContext *s, offset_t offset)
 
163
{
 
164
    url_fseek(s, offset, SEEK_CUR);
 
165
}
 
166
 
 
167
offset_t url_ftell(ByteIOContext *s)
 
168
{
 
169
    return url_fseek(s, 0, SEEK_CUR);
 
170
}
 
171
 
 
172
offset_t url_fsize(ByteIOContext *s)
 
173
{
 
174
    offset_t size;
 
175
 
 
176
    if (!s->seek)
 
177
        return -EPIPE;
 
178
    size = s->seek(s->opaque, -1, SEEK_END) + 1;
 
179
    s->seek(s->opaque, s->pos, SEEK_SET);
 
180
    return size;
 
181
}
 
182
 
 
183
int url_feof(ByteIOContext *s)
 
184
{
 
185
    return s->eof_reached;
 
186
}
 
187
 
 
188
int url_ferror(ByteIOContext *s)
 
189
{
 
190
    return s->error;
 
191
}
 
192
 
 
193
#if defined(CONFIG_MUXERS) || defined(CONFIG_PROTOCOLS)
 
194
void put_le32(ByteIOContext *s, unsigned int val)
 
195
{
 
196
    put_byte(s, val);
 
197
    put_byte(s, val >> 8);
 
198
    put_byte(s, val >> 16);
 
199
    put_byte(s, val >> 24);
 
200
}
 
201
 
 
202
void put_be32(ByteIOContext *s, unsigned int val)
 
203
{
 
204
    put_byte(s, val >> 24);
 
205
    put_byte(s, val >> 16);
 
206
    put_byte(s, val >> 8);
 
207
    put_byte(s, val);
 
208
}
 
209
 
 
210
void put_strz(ByteIOContext *s, const char *str)
 
211
{
 
212
    if (str)
 
213
        put_buffer(s, (const unsigned char *) str, strlen(str) + 1);
 
214
    else
 
215
        put_byte(s, 0);
 
216
}
 
217
 
 
218
void put_le64(ByteIOContext *s, uint64_t val)
 
219
{
 
220
    put_le32(s, (uint32_t)(val & 0xffffffff));
 
221
    put_le32(s, (uint32_t)(val >> 32));
 
222
}
 
223
 
 
224
void put_be64(ByteIOContext *s, uint64_t val)
 
225
{
 
226
    put_be32(s, (uint32_t)(val >> 32));
 
227
    put_be32(s, (uint32_t)(val & 0xffffffff));
 
228
}
 
229
 
 
230
void put_le16(ByteIOContext *s, unsigned int val)
 
231
{
 
232
    put_byte(s, val);
 
233
    put_byte(s, val >> 8);
 
234
}
 
235
 
 
236
void put_be16(ByteIOContext *s, unsigned int val)
 
237
{
 
238
    put_byte(s, val >> 8);
 
239
    put_byte(s, val);
 
240
}
 
241
 
 
242
void put_le24(ByteIOContext *s, unsigned int val)
 
243
{
 
244
    put_le16(s, val & 0xffff);
 
245
    put_byte(s, val >> 16);
 
246
}
 
247
 
 
248
void put_be24(ByteIOContext *s, unsigned int val)
 
249
{
 
250
    put_be16(s, val >> 8);
 
251
    put_byte(s, val);
 
252
}
 
253
 
 
254
void put_tag(ByteIOContext *s, const char *tag)
 
255
{
 
256
    while (*tag) {
 
257
        put_byte(s, *tag++);
 
258
    }
 
259
}
 
260
#endif //CONFIG_MUXERS || CONFIG_PROTOCOLS
 
261
 
 
262
/* Input stream */
 
263
 
 
264
static void fill_buffer(ByteIOContext *s)
 
265
{
 
266
    int len;
 
267
 
 
268
    /* no need to do anything if EOF already reached */
 
269
    if (s->eof_reached)
 
270
        return;
 
271
 
 
272
    if(s->update_checksum){
 
273
        if(s->buf_end > s->checksum_ptr)
 
274
            s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_end - s->checksum_ptr);
 
275
        s->checksum_ptr= s->buffer;
 
276
    }
 
277
 
 
278
    len = s->read_packet(s->opaque, s->buffer, s->buffer_size);
 
279
    if (len <= 0) {
 
280
        /* do not modify buffer if EOF reached so that a seek back can
 
281
           be done without rereading data */
 
282
        s->eof_reached = 1;
 
283
    if(len<0)
 
284
        s->error= len;
 
285
    } else {
 
286
        s->pos += len;
 
287
        s->buf_ptr = s->buffer;
 
288
        s->buf_end = s->buffer + len;
 
289
    }
 
290
}
 
291
 
 
292
unsigned long get_checksum(ByteIOContext *s){
 
293
    s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr);
 
294
    s->update_checksum= NULL;
 
295
    return s->checksum;
 
296
}
 
297
 
 
298
void init_checksum(ByteIOContext *s, unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), unsigned long checksum){
 
299
    s->update_checksum= update_checksum;
 
300
    if(s->update_checksum){
 
301
        s->checksum= s->update_checksum(checksum, NULL, 0);
 
302
        s->checksum_ptr= s->buf_ptr;
 
303
    }
 
304
}
 
305
 
 
306
/* NOTE: return 0 if EOF, so you cannot use it if EOF handling is
 
307
   necessary */
 
308
/* XXX: put an inline version */
 
309
int get_byte(ByteIOContext *s)
 
310
{
 
311
    if (s->buf_ptr < s->buf_end) {
 
312
        return *s->buf_ptr++;
 
313
    } else {
 
314
        fill_buffer(s);
 
315
        if (s->buf_ptr < s->buf_end)
 
316
            return *s->buf_ptr++;
 
317
        else
 
318
            return 0;
 
319
    }
 
320
}
 
321
 
 
322
/* NOTE: return URL_EOF (-1) if EOF */
 
323
int url_fgetc(ByteIOContext *s)
 
324
{
 
325
    if (s->buf_ptr < s->buf_end) {
 
326
        return *s->buf_ptr++;
 
327
    } else {
 
328
        fill_buffer(s);
 
329
        if (s->buf_ptr < s->buf_end)
 
330
            return *s->buf_ptr++;
 
331
        else
 
332
            return URL_EOF;
 
333
    }
 
334
}
 
335
 
 
336
int get_buffer(ByteIOContext *s, unsigned char *buf, int size)
 
337
{
 
338
    int len, size1;
 
339
 
 
340
    size1 = size;
 
341
    while (size > 0) {
 
342
        len = s->buf_end - s->buf_ptr;
 
343
        if (len > size)
 
344
            len = size;
 
345
        if (len == 0) {
 
346
            if(size > s->buffer_size && !s->update_checksum){
 
347
                len = s->read_packet(s->opaque, buf, size);
 
348
                if (len <= 0) {
 
349
                    /* do not modify buffer if EOF reached so that a seek back can
 
350
                    be done without rereading data */
 
351
                    s->eof_reached = 1;
 
352
                    if(len<0)
 
353
                        s->error= len;
 
354
                    break;
 
355
                } else {
 
356
                    s->pos += len;
 
357
                    size -= len;
 
358
                    buf += len;
 
359
                    s->buf_ptr = s->buffer;
 
360
                    s->buf_end = s->buffer/* + len*/;
 
361
                }
 
362
            }else{
 
363
                fill_buffer(s);
 
364
                len = s->buf_end - s->buf_ptr;
 
365
                if (len == 0)
 
366
                    break;
 
367
            }
 
368
        } else {
 
369
            memcpy(buf, s->buf_ptr, len);
 
370
            buf += len;
 
371
            s->buf_ptr += len;
 
372
            size -= len;
 
373
        }
 
374
    }
 
375
    return size1 - size;
 
376
}
 
377
 
 
378
int get_partial_buffer(ByteIOContext *s, unsigned char *buf, int size)
 
379
{
 
380
    int len;
 
381
 
 
382
    if(size<0)
 
383
        return -1;
 
384
 
 
385
    len = s->buf_end - s->buf_ptr;
 
386
    if (len == 0) {
 
387
        fill_buffer(s);
 
388
        len = s->buf_end - s->buf_ptr;
 
389
    }
 
390
    if (len > size)
 
391
        len = size;
 
392
    memcpy(buf, s->buf_ptr, len);
 
393
    s->buf_ptr += len;
 
394
    return len;
 
395
}
 
396
 
 
397
unsigned int get_le16(ByteIOContext *s)
 
398
{
 
399
    unsigned int val;
 
400
    val = get_byte(s);
 
401
    val |= get_byte(s) << 8;
 
402
    return val;
 
403
}
 
404
 
 
405
unsigned int get_le24(ByteIOContext *s)
 
406
{
 
407
    unsigned int val;
 
408
    val = get_le16(s);
 
409
    val |= get_byte(s) << 16;
 
410
    return val;
 
411
}
 
412
 
 
413
unsigned int get_le32(ByteIOContext *s)
 
414
{
 
415
    unsigned int val;
 
416
    val = get_le16(s);
 
417
    val |= get_le16(s) << 16;
 
418
    return val;
 
419
}
 
420
 
 
421
uint64_t get_le64(ByteIOContext *s)
 
422
{
 
423
    uint64_t val;
 
424
    val = (uint64_t)get_le32(s);
 
425
    val |= (uint64_t)get_le32(s) << 32;
 
426
    return val;
 
427
}
 
428
 
 
429
unsigned int get_be16(ByteIOContext *s)
 
430
{
 
431
    unsigned int val;
 
432
    val = get_byte(s) << 8;
 
433
    val |= get_byte(s);
 
434
    return val;
 
435
}
 
436
 
 
437
unsigned int get_be24(ByteIOContext *s)
 
438
{
 
439
    unsigned int val;
 
440
    val = get_be16(s) << 8;
 
441
    val |= get_byte(s);
 
442
    return val;
 
443
}
 
444
unsigned int get_be32(ByteIOContext *s)
 
445
{
 
446
    unsigned int val;
 
447
    val = get_be16(s) << 16;
 
448
    val |= get_be16(s);
 
449
    return val;
 
450
}
 
451
 
 
452
char *get_strz(ByteIOContext *s, char *buf, int maxlen)
 
453
{
 
454
    int i = 0;
 
455
    char c;
 
456
 
 
457
    while ((c = get_byte(s))) {
 
458
        if (i < maxlen-1)
 
459
            buf[i++] = c;
 
460
    }
 
461
 
 
462
    buf[i] = 0; /* Ensure null terminated, but may be truncated */
 
463
 
 
464
    return buf;
 
465
}
 
466
 
 
467
uint64_t get_be64(ByteIOContext *s)
 
468
{
 
469
    uint64_t val;
 
470
    val = (uint64_t)get_be32(s) << 32;
 
471
    val |= (uint64_t)get_be32(s);
 
472
    return val;
 
473
}
 
474
 
 
475
/* link with avio functions */
 
476
 
 
477
#ifdef CONFIG_MUXERS
 
478
static int url_write_packet(void *opaque, uint8_t *buf, int buf_size)
 
479
{
 
480
    URLContext *h = opaque;
 
481
    return url_write(h, buf, buf_size);
 
482
}
 
483
#else
 
484
#define         url_write_packet NULL
 
485
#endif //CONFIG_MUXERS
 
486
 
 
487
static int url_read_packet(void *opaque, uint8_t *buf, int buf_size)
 
488
{
 
489
    URLContext *h = opaque;
 
490
    return url_read(h, buf, buf_size);
 
491
}
 
492
 
 
493
static offset_t url_seek_packet(void *opaque, offset_t offset, int whence)
 
494
{
 
495
    URLContext *h = opaque;
 
496
    return url_seek(h, offset, whence);
 
497
    //return 0;
 
498
}
 
499
 
 
500
int url_fdopen(ByteIOContext *s, URLContext *h)
 
501
{
 
502
    uint8_t *buffer;
 
503
    int buffer_size, max_packet_size;
 
504
 
 
505
 
 
506
    max_packet_size = url_get_max_packet_size(h);
 
507
    if (max_packet_size) {
 
508
        buffer_size = max_packet_size; /* no need to bufferize more than one packet */
 
509
    } else {
 
510
        buffer_size = IO_BUFFER_SIZE;
 
511
    }
 
512
    buffer = av_malloc(buffer_size);
 
513
    if (!buffer)
 
514
        return -ENOMEM;
 
515
 
 
516
    if (init_put_byte(s, buffer, buffer_size,
 
517
                      (h->flags & URL_WRONLY || h->flags & URL_RDWR), h,
 
518
                      url_read_packet, url_write_packet, url_seek_packet) < 0) {
 
519
        av_free(buffer);
 
520
        return AVERROR_IO;
 
521
    }
 
522
    s->is_streamed = h->is_streamed;
 
523
    s->max_packet_size = max_packet_size;
 
524
    return 0;
 
525
}
 
526
 
 
527
/* XXX: must be called before any I/O */
 
528
int url_setbufsize(ByteIOContext *s, int buf_size)
 
529
{
 
530
    uint8_t *buffer;
 
531
    buffer = av_malloc(buf_size);
 
532
    if (!buffer)
 
533
        return -ENOMEM;
 
534
 
 
535
    av_free(s->buffer);
 
536
    s->buffer = buffer;
 
537
    s->buffer_size = buf_size;
 
538
    s->buf_ptr = buffer;
 
539
    if (!s->write_flag)
 
540
        s->buf_end = buffer;
 
541
    else
 
542
        s->buf_end = buffer + buf_size;
 
543
    return 0;
 
544
}
 
545
 
 
546
/* NOTE: when opened as read/write, the buffers are only used for
 
547
   reading */
 
548
int url_fopen(ByteIOContext *s, const char *filename, int flags)
 
549
{
 
550
    URLContext *h;
 
551
    int err;
 
552
 
 
553
    err = url_open(&h, filename, flags);
 
554
    if (err < 0)
 
555
        return err;
 
556
    err = url_fdopen(s, h);
 
557
    if (err < 0) {
 
558
        url_close(h);
 
559
        return err;
 
560
    }
 
561
    return 0;
 
562
}
 
563
 
 
564
int url_fclose(ByteIOContext *s)
 
565
{
 
566
    URLContext *h = s->opaque;
 
567
 
 
568
    av_free(s->buffer);
 
569
    memset(s, 0, sizeof(ByteIOContext));
 
570
    return url_close(h);
 
571
}
 
572
 
 
573
URLContext *url_fileno(ByteIOContext *s)
 
574
{
 
575
    return s->opaque;
 
576
}
 
577
 
 
578
#ifdef CONFIG_MUXERS
 
579
/* XXX: currently size is limited */
 
580
int url_fprintf(ByteIOContext *s, const char *fmt, ...)
 
581
{
 
582
    va_list ap;
 
583
    char buf[4096];
 
584
    int ret;
 
585
 
 
586
    va_start(ap, fmt);
 
587
    ret = vsnprintf(buf, sizeof(buf), fmt, ap);
 
588
    va_end(ap);
 
589
    put_buffer(s, buf, strlen(buf));
 
590
    return ret;
 
591
}
 
592
#endif //CONFIG_MUXERS
 
593
 
 
594
/* note: unlike fgets, the EOL character is not returned and a whole
 
595
   line is parsed. return NULL if first char read was EOF */
 
596
char *url_fgets(ByteIOContext *s, char *buf, int buf_size)
 
597
{
 
598
    int c;
 
599
    char *q;
 
600
 
 
601
    c = url_fgetc(s);
 
602
    if (c == EOF)
 
603
        return NULL;
 
604
    q = buf;
 
605
    for(;;) {
 
606
        if (c == EOF || c == '\n')
 
607
            break;
 
608
        if ((q - buf) < buf_size - 1)
 
609
            *q++ = c;
 
610
        c = url_fgetc(s);
 
611
    }
 
612
    if (buf_size > 0)
 
613
        *q = '\0';
 
614
    return buf;
 
615
}
 
616
 
 
617
/*
 
618
 * Return the maximum packet size associated to packetized buffered file
 
619
 * handle. If the file is not packetized (stream like http or file on
 
620
 * disk), then 0 is returned.
 
621
 *
 
622
 * @param h buffered file handle
 
623
 * @return maximum packet size in bytes
 
624
 */
 
625
int url_fget_max_packet_size(ByteIOContext *s)
 
626
{
 
627
    return s->max_packet_size;
 
628
}
 
629
 
 
630
#ifdef CONFIG_MUXERS
 
631
/* buffer handling */
 
632
int url_open_buf(ByteIOContext *s, uint8_t *buf, int buf_size, int flags)
 
633
{
 
634
    return init_put_byte(s, buf, buf_size,
 
635
                         (flags & URL_WRONLY || flags & URL_RDWR),
 
636
                         NULL, NULL, NULL, NULL);
 
637
}
 
638
 
 
639
/* return the written or read size */
 
640
int url_close_buf(ByteIOContext *s)
 
641
{
 
642
    put_flush_packet(s);
 
643
    return s->buf_ptr - s->buffer;
 
644
}
 
645
 
 
646
/* output in a dynamic buffer */
 
647
 
 
648
typedef struct DynBuffer {
 
649
    int pos, size, allocated_size;
 
650
    uint8_t *buffer;
 
651
    int io_buffer_size;
 
652
    uint8_t io_buffer[1];
 
653
} DynBuffer;
 
654
 
 
655
static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size)
 
656
{
 
657
    DynBuffer *d = opaque;
 
658
    int new_size, new_allocated_size;
 
659
 
 
660
    /* reallocate buffer if needed */
 
661
    new_size = d->pos + buf_size;
 
662
    new_allocated_size = d->allocated_size;
 
663
    if(new_size < d->pos || new_size > INT_MAX/2)
 
664
        return -1;
 
665
    while (new_size > new_allocated_size) {
 
666
        if (!new_allocated_size)
 
667
            new_allocated_size = new_size;
 
668
        else
 
669
            new_allocated_size += new_allocated_size / 2 + 1;
 
670
    }
 
671
 
 
672
    if (new_allocated_size > d->allocated_size) {
 
673
        d->buffer = av_realloc(d->buffer, new_allocated_size);
 
674
        if(d->buffer == NULL)
 
675
             return -1234;
 
676
        d->allocated_size = new_allocated_size;
 
677
    }
 
678
    memcpy(d->buffer + d->pos, buf, buf_size);
 
679
    d->pos = new_size;
 
680
    if (d->pos > d->size)
 
681
        d->size = d->pos;
 
682
    return buf_size;
 
683
}
 
684
 
 
685
static int dyn_packet_buf_write(void *opaque, uint8_t *buf, int buf_size)
 
686
{
 
687
    unsigned char buf1[4];
 
688
    int ret;
 
689
 
 
690
    /* packetized write: output the header */
 
691
    buf1[0] = (buf_size >> 24);
 
692
    buf1[1] = (buf_size >> 16);
 
693
    buf1[2] = (buf_size >> 8);
 
694
    buf1[3] = (buf_size);
 
695
    ret= dyn_buf_write(opaque, buf1, 4);
 
696
    if(ret < 0)
 
697
        return ret;
 
698
 
 
699
    /* then the data */
 
700
    return dyn_buf_write(opaque, buf, buf_size);
 
701
}
 
702
 
 
703
static offset_t dyn_buf_seek(void *opaque, offset_t offset, int whence)
 
704
{
 
705
    DynBuffer *d = opaque;
 
706
 
 
707
    if (whence == SEEK_CUR)
 
708
        offset += d->pos;
 
709
    else if (whence == SEEK_END)
 
710
        offset += d->size;
 
711
    if (offset < 0 || offset > 0x7fffffffLL)
 
712
        return -1;
 
713
    d->pos = offset;
 
714
    return 0;
 
715
}
 
716
 
 
717
static int url_open_dyn_buf_internal(ByteIOContext *s, int max_packet_size)
 
718
{
 
719
    DynBuffer *d;
 
720
    int io_buffer_size, ret;
 
721
 
 
722
    if (max_packet_size)
 
723
        io_buffer_size = max_packet_size;
 
724
    else
 
725
        io_buffer_size = 1024;
 
726
 
 
727
    if(sizeof(DynBuffer) + io_buffer_size < io_buffer_size)
 
728
        return -1;
 
729
    d = av_malloc(sizeof(DynBuffer) + io_buffer_size);
 
730
    if (!d)
 
731
        return -1;
 
732
    d->io_buffer_size = io_buffer_size;
 
733
    d->buffer = NULL;
 
734
    d->pos = 0;
 
735
    d->size = 0;
 
736
    d->allocated_size = 0;
 
737
    ret = init_put_byte(s, d->io_buffer, io_buffer_size,
 
738
                        1, d, NULL,
 
739
                        max_packet_size ? dyn_packet_buf_write : dyn_buf_write,
 
740
                        max_packet_size ? NULL : dyn_buf_seek);
 
741
    if (ret == 0) {
 
742
        s->max_packet_size = max_packet_size;
 
743
    }
 
744
    return ret;
 
745
}
 
746
 
 
747
/*
 
748
 * Open a write only memory stream.
 
749
 *
 
750
 * @param s new IO context
 
751
 * @return zero if no error.
 
752
 */
 
753
int url_open_dyn_buf(ByteIOContext *s)
 
754
{
 
755
    return url_open_dyn_buf_internal(s, 0);
 
756
}
 
757
 
 
758
/*
 
759
 * Open a write only packetized memory stream with a maximum packet
 
760
 * size of 'max_packet_size'.  The stream is stored in a memory buffer
 
761
 * with a big endian 4 byte header giving the packet size in bytes.
 
762
 *
 
763
 * @param s new IO context
 
764
 * @param max_packet_size maximum packet size (must be > 0)
 
765
 * @return zero if no error.
 
766
 */
 
767
int url_open_dyn_packet_buf(ByteIOContext *s, int max_packet_size)
 
768
{
 
769
    if (max_packet_size <= 0)
 
770
        return -1;
 
771
    return url_open_dyn_buf_internal(s, max_packet_size);
 
772
}
 
773
 
 
774
/*
 
775
 * Return the written size and a pointer to the buffer. The buffer
 
776
 *  must be freed with av_free().
 
777
 * @param s IO context
 
778
 * @param pointer to a byte buffer
 
779
 * @return the length of the byte buffer
 
780
 */
 
781
int url_close_dyn_buf(ByteIOContext *s, uint8_t **pbuffer)
 
782
{
 
783
    DynBuffer *d = s->opaque;
 
784
    int size;
 
785
 
 
786
    put_flush_packet(s);
 
787
 
 
788
    *pbuffer = d->buffer;
 
789
    size = d->size;
 
790
    av_free(d);
 
791
    return size;
 
792
}
 
793
#endif //CONFIG_MUXERS