~siretart/libav/merge.raring.libav-0.8.6

« back to all changes in this revision

Viewing changes to libavcodec/cinepak.c

  • Committer: Package Import Robot
  • Author(s): Reinhard Tartler
  • Date: 2012-01-12 22:30:00 UTC
  • mfrom: (1.4.1)
  • mto: (1.3.11 sid) (26.1.1 quantal-security)
  • mto: This revision was merged to the branch mainline in revision 15.
  • Revision ID: package-import@ubuntu.com-20120112223000-s1reiy1e28hnix42
Tags: upstream-0.8~beta2
ImportĀ upstreamĀ versionĀ 0.8~beta2

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
/**
23
23
 * @file
24
24
 * Cinepak video decoder
25
 
 * by Ewald Snel <ewald@rambo.its.tudelft.nl>
26
 
 * For more information on the Cinepak algorithm, visit:
 
25
 * @author Ewald Snel <ewald@rambo.its.tudelft.nl>
 
26
 *
 
27
 * @see For more information on the Cinepak algorithm, visit:
27
28
 *   http://www.csse.monash.edu.au/~timf/
28
 
 * For more information on the quirky data inside Sega FILM/CPK files, visit:
 
29
 * @see For more information on the quirky data inside Sega FILM/CPK files, visit:
29
30
 *   http://wiki.multimedia.cx/index.php?title=Sega_FILM
30
31
 */
31
32
 
147
148
        for (x=strip->x1; x < strip->x2; x+=4) {
148
149
            if ((chunk_id & 0x01) && !(mask >>= 1)) {
149
150
                if ((data + 4) > eod)
150
 
                    return -1;
 
151
                    return AVERROR_INVALIDDATA;
151
152
 
152
153
                flag  = AV_RB32 (data);
153
154
                data += 4;
157
158
            if (!(chunk_id & 0x01) || (flag & mask)) {
158
159
                if (!(chunk_id & 0x02) && !(mask >>= 1)) {
159
160
                    if ((data + 4) > eod)
160
 
                        return -1;
 
161
                        return AVERROR_INVALIDDATA;
161
162
 
162
163
                    flag  = AV_RB32 (data);
163
164
                    data += 4;
166
167
 
167
168
                if ((chunk_id & 0x02) || (~flag & mask)) {
168
169
                    if (data >= eod)
169
 
                        return -1;
 
170
                        return AVERROR_INVALIDDATA;
170
171
 
171
172
                    codebook = &strip->v1_codebook[*data++];
172
173
                    s->frame.data[0][iy[0] + 0] = codebook->y0;
207
208
 
208
209
                } else if (flag & mask) {
209
210
                    if ((data + 4) > eod)
210
 
                        return -1;
 
211
                        return AVERROR_INVALIDDATA;
211
212
 
212
213
                    codebook = &strip->v4_codebook[*data++];
213
214
                    s->frame.data[0][iy[0] + 0] = codebook->y0;
269
270
    int      chunk_id, chunk_size;
270
271
 
271
272
    /* coordinate sanity checks */
272
 
    if (strip->x1 >= s->width  || strip->x2 > s->width  ||
273
 
        strip->y1 >= s->height || strip->y2 > s->height ||
 
273
    if (strip->x2 > s->width   ||
 
274
        strip->y2 > s->height  ||
274
275
        strip->x1 >= strip->x2 || strip->y1 >= strip->y2)
275
 
        return -1;
 
276
        return AVERROR_INVALIDDATA;
276
277
 
277
278
    while ((data + 4) <= eod) {
278
279
        chunk_id   = data[0];
279
280
        chunk_size = AV_RB24 (&data[1]) - 4;
280
281
        if(chunk_size < 0)
281
 
            return -1;
 
282
            return AVERROR_INVALIDDATA;
282
283
 
283
284
        data      += 4;
284
285
        chunk_size = ((data + chunk_size) > eod) ? (eod - data) : chunk_size;
311
312
        data += chunk_size;
312
313
    }
313
314
 
314
 
    return -1;
 
315
    return AVERROR_INVALIDDATA;
315
316
}
316
317
 
317
318
static int cinepak_decode (CinepakContext *s)
322
323
    int           encoded_buf_size;
323
324
 
324
325
    if (s->size < 10)
325
 
        return -1;
 
326
        return AVERROR_INVALIDDATA;
326
327
 
327
328
    frame_flags = s->data[0];
328
329
    num_strips  = AV_RB16 (&s->data[8]);
329
 
    encoded_buf_size = ((s->data[1] << 16) | AV_RB16 (&s->data[2]));
 
330
    encoded_buf_size = AV_RB24(&s->data[1]);
330
331
 
331
332
    /* if this is the first frame, check for deviant Sega FILM data */
332
333
    if (s->sega_film_skip_bytes == -1) {
333
 
        if (encoded_buf_size != s->size) {
 
334
        if (!encoded_buf_size) {
 
335
            av_log_ask_for_sample(s->avctx, "encoded_buf_size is 0");
 
336
            return AVERROR_INVALIDDATA;
 
337
        }
 
338
        if (encoded_buf_size != s->size && (s->size % encoded_buf_size) != 0) {
334
339
            /* If the encoded frame size differs from the frame size as indicated
335
340
             * by the container file, this data likely comes from a Sega FILM/CPK file.
336
341
             * If the frame header is followed by the bytes FE 00 00 06 00 00 then
337
342
             * this is probably one of the two known files that have 6 extra bytes
338
 
             * after the frame header. Else, assume 2 extra bytes. */
339
 
            if ((s->data[10] == 0xFE) &&
 
343
             * after the frame header. Else, assume 2 extra bytes. The container
 
344
             * size also cannot be a multiple of the encoded size. */
 
345
            if (s->size >= 16 &&
 
346
                (s->data[10] == 0xFE) &&
340
347
                (s->data[11] == 0x00) &&
341
348
                (s->data[12] == 0x00) &&
342
349
                (s->data[13] == 0x06) &&
351
358
 
352
359
    s->data += 10 + s->sega_film_skip_bytes;
353
360
 
354
 
    if (num_strips > MAX_STRIPS)
355
 
        num_strips = MAX_STRIPS;
 
361
    num_strips = FFMIN(num_strips, MAX_STRIPS);
356
362
 
357
363
    for (i=0; i < num_strips; i++) {
358
364
        if ((s->data + 12) > eod)
359
 
            return -1;
 
365
            return AVERROR_INVALIDDATA;
360
366
 
361
367
        s->strips[i].id = s->data[0];
362
368
        s->strips[i].y1 = y0;
365
371
        s->strips[i].x2 = s->avctx->width;
366
372
 
367
373
        strip_size = AV_RB24 (&s->data[1]) - 12;
 
374
        if (strip_size < 0)
 
375
            return AVERROR_INVALIDDATA;
368
376
        s->data   += 12;
369
377
        strip_size = ((s->data + strip_size) > eod) ? (eod - s->data) : strip_size;
370
378
 
414
422
                                AVPacket *avpkt)
415
423
{
416
424
    const uint8_t *buf = avpkt->data;
417
 
    int buf_size = avpkt->size;
 
425
    int ret = 0, buf_size = avpkt->size;
418
426
    CinepakContext *s = avctx->priv_data;
419
427
 
420
428
    s->data = buf;
423
431
    s->frame.reference = 1;
424
432
    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
425
433
                            FF_BUFFER_HINTS_REUSABLE;
426
 
    if (avctx->reget_buffer(avctx, &s->frame)) {
 
434
    if ((ret = avctx->reget_buffer(avctx, &s->frame))) {
427
435
        av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
428
 
        return -1;
 
436
        return ret;
429
437
    }
430
438
 
431
439
    if (s->palette_video) {
459
467
}
460
468
 
461
469
AVCodec ff_cinepak_decoder = {
462
 
    "cinepak",
463
 
    AVMEDIA_TYPE_VIDEO,
464
 
    CODEC_ID_CINEPAK,
465
 
    sizeof(CinepakContext),
466
 
    cinepak_decode_init,
467
 
    NULL,
468
 
    cinepak_decode_end,
469
 
    cinepak_decode_frame,
470
 
    CODEC_CAP_DR1,
 
470
    .name           = "cinepak",
 
471
    .type           = AVMEDIA_TYPE_VIDEO,
 
472
    .id             = CODEC_ID_CINEPAK,
 
473
    .priv_data_size = sizeof(CinepakContext),
 
474
    .init           = cinepak_decode_init,
 
475
    .close          = cinepak_decode_end,
 
476
    .decode         = cinepak_decode_frame,
 
477
    .capabilities   = CODEC_CAP_DR1,
471
478
    .long_name = NULL_IF_CONFIG_SMALL("Cinepak"),
472
479
};