annotate ffmpeg/libavcodec/msrle.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * Microsoft RLE video decoder
yading@10 3 * Copyright (C) 2003 the ffmpeg project
yading@10 4 *
yading@10 5 * This file is part of FFmpeg.
yading@10 6 *
yading@10 7 * FFmpeg is free software; you can redistribute it and/or
yading@10 8 * modify it under the terms of the GNU Lesser General Public
yading@10 9 * License as published by the Free Software Foundation; either
yading@10 10 * version 2.1 of the License, or (at your option) any later version.
yading@10 11 *
yading@10 12 * FFmpeg is distributed in the hope that it will be useful,
yading@10 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 15 * Lesser General Public License for more details.
yading@10 16 *
yading@10 17 * You should have received a copy of the GNU Lesser General Public
yading@10 18 * License along with FFmpeg; if not, write to the Free Software
yading@10 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 20 */
yading@10 21
yading@10 22 /**
yading@10 23 * @file
yading@10 24 * MS RLE video decoder by Mike Melanson (melanson@pcisys.net)
yading@10 25 * For more information about the MS RLE format, visit:
yading@10 26 * http://www.pcisys.net/~melanson/codecs/
yading@10 27 *
yading@10 28 * The MS RLE decoder outputs PAL8 colorspace data.
yading@10 29 */
yading@10 30
yading@10 31 #include <stdio.h>
yading@10 32 #include <stdlib.h>
yading@10 33 #include <string.h>
yading@10 34
yading@10 35 #include "avcodec.h"
yading@10 36 #include "internal.h"
yading@10 37 #include "msrledec.h"
yading@10 38
yading@10 39 typedef struct MsrleContext {
yading@10 40 AVCodecContext *avctx;
yading@10 41 AVFrame frame;
yading@10 42
yading@10 43 GetByteContext gb;
yading@10 44 const unsigned char *buf;
yading@10 45 int size;
yading@10 46
yading@10 47 uint32_t pal[256];
yading@10 48 } MsrleContext;
yading@10 49
yading@10 50 static av_cold int msrle_decode_init(AVCodecContext *avctx)
yading@10 51 {
yading@10 52 MsrleContext *s = avctx->priv_data;
yading@10 53 int i;
yading@10 54
yading@10 55 s->avctx = avctx;
yading@10 56
yading@10 57 switch (avctx->bits_per_coded_sample) {
yading@10 58 case 1:
yading@10 59 avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
yading@10 60 break;
yading@10 61 case 4:
yading@10 62 case 8:
yading@10 63 avctx->pix_fmt = AV_PIX_FMT_PAL8;
yading@10 64 break;
yading@10 65 case 24:
yading@10 66 avctx->pix_fmt = AV_PIX_FMT_BGR24;
yading@10 67 break;
yading@10 68 default:
yading@10 69 av_log(avctx, AV_LOG_ERROR, "unsupported bits per sample\n");
yading@10 70 return AVERROR_INVALIDDATA;
yading@10 71 }
yading@10 72
yading@10 73 avcodec_get_frame_defaults(&s->frame);
yading@10 74
yading@10 75 if (avctx->extradata_size >= 4)
yading@10 76 for (i = 0; i < FFMIN(avctx->extradata_size, AVPALETTE_SIZE)/4; i++)
yading@10 77 s->pal[i] = 0xFFU<<24 | AV_RL32(avctx->extradata+4*i);
yading@10 78
yading@10 79 return 0;
yading@10 80 }
yading@10 81
yading@10 82 static int msrle_decode_frame(AVCodecContext *avctx,
yading@10 83 void *data, int *got_frame,
yading@10 84 AVPacket *avpkt)
yading@10 85 {
yading@10 86 const uint8_t *buf = avpkt->data;
yading@10 87 int buf_size = avpkt->size;
yading@10 88 MsrleContext *s = avctx->priv_data;
yading@10 89 int istride = FFALIGN(avctx->width*avctx->bits_per_coded_sample, 32) / 8;
yading@10 90 int ret;
yading@10 91
yading@10 92 s->buf = buf;
yading@10 93 s->size = buf_size;
yading@10 94
yading@10 95 if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0)
yading@10 96 return ret;
yading@10 97
yading@10 98 if (avctx->bits_per_coded_sample > 1 && avctx->bits_per_coded_sample <= 8) {
yading@10 99 const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
yading@10 100
yading@10 101 if (pal) {
yading@10 102 s->frame.palette_has_changed = 1;
yading@10 103 memcpy(s->pal, pal, AVPALETTE_SIZE);
yading@10 104 }
yading@10 105 /* make the palette available */
yading@10 106 memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE);
yading@10 107 }
yading@10 108
yading@10 109 /* FIXME how to correctly detect RLE ??? */
yading@10 110 if (avctx->height * istride == avpkt->size) { /* assume uncompressed */
yading@10 111 int linesize = (avctx->width * avctx->bits_per_coded_sample + 7) / 8;
yading@10 112 uint8_t *ptr = s->frame.data[0];
yading@10 113 uint8_t *buf = avpkt->data + (avctx->height-1)*istride;
yading@10 114 int i, j;
yading@10 115
yading@10 116 for (i = 0; i < avctx->height; i++) {
yading@10 117 if (avctx->bits_per_coded_sample == 4) {
yading@10 118 for (j = 0; j < avctx->width - 1; j += 2) {
yading@10 119 ptr[j+0] = buf[j>>1] >> 4;
yading@10 120 ptr[j+1] = buf[j>>1] & 0xF;
yading@10 121 }
yading@10 122 if (avctx->width & 1)
yading@10 123 ptr[j+0] = buf[j>>1] >> 4;
yading@10 124 } else {
yading@10 125 memcpy(ptr, buf, linesize);
yading@10 126 }
yading@10 127 buf -= istride;
yading@10 128 ptr += s->frame.linesize[0];
yading@10 129 }
yading@10 130 } else {
yading@10 131 bytestream2_init(&s->gb, buf, buf_size);
yading@10 132 ff_msrle_decode(avctx, (AVPicture*)&s->frame, avctx->bits_per_coded_sample, &s->gb);
yading@10 133 }
yading@10 134
yading@10 135 if ((ret = av_frame_ref(data, &s->frame)) < 0)
yading@10 136 return ret;
yading@10 137
yading@10 138 *got_frame = 1;
yading@10 139
yading@10 140 /* report that the buffer was completely consumed */
yading@10 141 return buf_size;
yading@10 142 }
yading@10 143
yading@10 144 static av_cold int msrle_decode_end(AVCodecContext *avctx)
yading@10 145 {
yading@10 146 MsrleContext *s = avctx->priv_data;
yading@10 147
yading@10 148 /* release the last frame */
yading@10 149 av_frame_unref(&s->frame);
yading@10 150
yading@10 151 return 0;
yading@10 152 }
yading@10 153
yading@10 154 AVCodec ff_msrle_decoder = {
yading@10 155 .name = "msrle",
yading@10 156 .type = AVMEDIA_TYPE_VIDEO,
yading@10 157 .id = AV_CODEC_ID_MSRLE,
yading@10 158 .priv_data_size = sizeof(MsrleContext),
yading@10 159 .init = msrle_decode_init,
yading@10 160 .close = msrle_decode_end,
yading@10 161 .decode = msrle_decode_frame,
yading@10 162 .capabilities = CODEC_CAP_DR1,
yading@10 163 .long_name = NULL_IF_CONFIG_SMALL("Microsoft RLE"),
yading@10 164 };