annotate ffmpeg/libavcodec/bintext.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 * Binary text decoder
yading@10 3 * eXtended BINary text (XBIN) decoder
yading@10 4 * iCEDraw File decoder
yading@10 5 * Copyright (c) 2010 Peter Ross (pross@xvid.org)
yading@10 6 *
yading@10 7 * This file is part of FFmpeg.
yading@10 8 *
yading@10 9 * FFmpeg is free software; you can redistribute it and/or
yading@10 10 * modify it under the terms of the GNU Lesser General Public
yading@10 11 * License as published by the Free Software Foundation; either
yading@10 12 * version 2.1 of the License, or (at your option) any later version.
yading@10 13 *
yading@10 14 * FFmpeg is distributed in the hope that it will be useful,
yading@10 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 17 * Lesser General Public License for more details.
yading@10 18 *
yading@10 19 * You should have received a copy of the GNU Lesser General Public
yading@10 20 * License along with FFmpeg; if not, write to the Free Software
yading@10 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 22 */
yading@10 23
yading@10 24 /**
yading@10 25 * @file
yading@10 26 * Binary text decoder
yading@10 27 * eXtended BINary text (XBIN) decoder
yading@10 28 * iCEDraw File decoder
yading@10 29 */
yading@10 30
yading@10 31 #include "libavutil/intreadwrite.h"
yading@10 32 #include "libavutil/xga_font_data.h"
yading@10 33 #include "avcodec.h"
yading@10 34 #include "cga_data.h"
yading@10 35 #include "bintext.h"
yading@10 36 #include "internal.h"
yading@10 37
yading@10 38 typedef struct XbinContext {
yading@10 39 AVFrame *frame;
yading@10 40 int palette[16];
yading@10 41 int flags;
yading@10 42 int font_height;
yading@10 43 const uint8_t *font;
yading@10 44 int x, y;
yading@10 45 } XbinContext;
yading@10 46
yading@10 47 static av_cold int decode_init(AVCodecContext *avctx)
yading@10 48 {
yading@10 49 XbinContext *s = avctx->priv_data;
yading@10 50 uint8_t *p;
yading@10 51 int i;
yading@10 52
yading@10 53 avctx->pix_fmt = AV_PIX_FMT_PAL8;
yading@10 54 p = avctx->extradata;
yading@10 55 if (p) {
yading@10 56 s->font_height = p[0];
yading@10 57 s->flags = p[1];
yading@10 58 p += 2;
yading@10 59 if(avctx->extradata_size < 2 + (!!(s->flags & BINTEXT_PALETTE))*3*16
yading@10 60 + (!!(s->flags & BINTEXT_FONT))*s->font_height*256) {
yading@10 61 av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
yading@10 62 return AVERROR_INVALIDDATA;
yading@10 63 }
yading@10 64 } else {
yading@10 65 s->font_height = 8;
yading@10 66 s->flags = 0;
yading@10 67 }
yading@10 68
yading@10 69 if ((s->flags & BINTEXT_PALETTE)) {
yading@10 70 for (i = 0; i < 16; i++) {
yading@10 71 s->palette[i] = 0xFF000000 | (AV_RB24(p) << 2) | ((AV_RB24(p) >> 4) & 0x30303);
yading@10 72 p += 3;
yading@10 73 }
yading@10 74 } else {
yading@10 75 for (i = 0; i < 16; i++)
yading@10 76 s->palette[i] = 0xFF000000 | ff_cga_palette[i];
yading@10 77 }
yading@10 78
yading@10 79 if ((s->flags & BINTEXT_FONT)) {
yading@10 80 s->font = p;
yading@10 81 } else {
yading@10 82 switch(s->font_height) {
yading@10 83 default:
yading@10 84 av_log(avctx, AV_LOG_WARNING, "font height %i not supported\n", s->font_height);
yading@10 85 s->font_height = 8;
yading@10 86 case 8:
yading@10 87 s->font = avpriv_cga_font;
yading@10 88 break;
yading@10 89 case 16:
yading@10 90 s->font = avpriv_vga16_font;
yading@10 91 break;
yading@10 92 }
yading@10 93 }
yading@10 94
yading@10 95 s->frame = av_frame_alloc();
yading@10 96 if (!s->frame)
yading@10 97 return AVERROR(ENOMEM);
yading@10 98
yading@10 99 return 0;
yading@10 100 }
yading@10 101
yading@10 102 #define DEFAULT_BG_COLOR 0
yading@10 103 av_unused static void hscroll(AVCodecContext *avctx)
yading@10 104 {
yading@10 105 XbinContext *s = avctx->priv_data;
yading@10 106 if (s->y < avctx->height - s->font_height) {
yading@10 107 s->y += s->font_height;
yading@10 108 } else {
yading@10 109 memmove(s->frame->data[0], s->frame->data[0] + s->font_height*s->frame->linesize[0],
yading@10 110 (avctx->height - s->font_height)*s->frame->linesize[0]);
yading@10 111 memset(s->frame->data[0] + (avctx->height - s->font_height)*s->frame->linesize[0],
yading@10 112 DEFAULT_BG_COLOR, s->font_height * s->frame->linesize[0]);
yading@10 113 }
yading@10 114 }
yading@10 115
yading@10 116 #define FONT_WIDTH 8
yading@10 117
yading@10 118 /**
yading@10 119 * Draw character to screen
yading@10 120 */
yading@10 121 static void draw_char(AVCodecContext *avctx, int c, int a)
yading@10 122 {
yading@10 123 XbinContext *s = avctx->priv_data;
yading@10 124 if (s->y > avctx->height - s->font_height)
yading@10 125 return;
yading@10 126 ff_draw_pc_font(s->frame->data[0] + s->y * s->frame->linesize[0] + s->x,
yading@10 127 s->frame->linesize[0], s->font, s->font_height, c,
yading@10 128 a & 0x0F, a >> 4);
yading@10 129 s->x += FONT_WIDTH;
yading@10 130 if (s->x > avctx->width - FONT_WIDTH) {
yading@10 131 s->x = 0;
yading@10 132 s->y += s->font_height;
yading@10 133 }
yading@10 134 }
yading@10 135
yading@10 136 static int decode_frame(AVCodecContext *avctx,
yading@10 137 void *data, int *got_frame,
yading@10 138 AVPacket *avpkt)
yading@10 139 {
yading@10 140 XbinContext *s = avctx->priv_data;
yading@10 141 const uint8_t *buf = avpkt->data;
yading@10 142 int buf_size = avpkt->size;
yading@10 143 const uint8_t *buf_end = buf+buf_size;
yading@10 144 int ret;
yading@10 145
yading@10 146 s->x = s->y = 0;
yading@10 147 if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
yading@10 148 return ret;
yading@10 149 s->frame->pict_type = AV_PICTURE_TYPE_I;
yading@10 150 s->frame->palette_has_changed = 1;
yading@10 151 memcpy(s->frame->data[1], s->palette, 16 * 4);
yading@10 152
yading@10 153 if (avctx->codec_id == AV_CODEC_ID_XBIN) {
yading@10 154 while (buf + 2 < buf_end) {
yading@10 155 int i,c,a;
yading@10 156 int type = *buf >> 6;
yading@10 157 int count = (*buf & 0x3F) + 1;
yading@10 158 buf++;
yading@10 159 switch (type) {
yading@10 160 case 0: //no compression
yading@10 161 for (i = 0; i < count && buf + 1 < buf_end; i++) {
yading@10 162 draw_char(avctx, buf[0], buf[1]);
yading@10 163 buf += 2;
yading@10 164 }
yading@10 165 break;
yading@10 166 case 1: //character compression
yading@10 167 c = *buf++;
yading@10 168 for (i = 0; i < count && buf < buf_end; i++)
yading@10 169 draw_char(avctx, c, *buf++);
yading@10 170 break;
yading@10 171 case 2: //attribute compression
yading@10 172 a = *buf++;
yading@10 173 for (i = 0; i < count && buf < buf_end; i++)
yading@10 174 draw_char(avctx, *buf++, a);
yading@10 175 break;
yading@10 176 case 3: //character/attribute compression
yading@10 177 c = *buf++;
yading@10 178 a = *buf++;
yading@10 179 for (i = 0; i < count && buf < buf_end; i++)
yading@10 180 draw_char(avctx, c, a);
yading@10 181 break;
yading@10 182 }
yading@10 183 }
yading@10 184 } else if (avctx->codec_id == AV_CODEC_ID_IDF) {
yading@10 185 while (buf + 2 < buf_end) {
yading@10 186 if (AV_RL16(buf) == 1) {
yading@10 187 int i;
yading@10 188 if (buf + 6 > buf_end)
yading@10 189 break;
yading@10 190 for (i = 0; i < buf[2]; i++)
yading@10 191 draw_char(avctx, buf[4], buf[5]);
yading@10 192 buf += 6;
yading@10 193 } else {
yading@10 194 draw_char(avctx, buf[0], buf[1]);
yading@10 195 buf += 2;
yading@10 196 }
yading@10 197 }
yading@10 198 } else {
yading@10 199 while (buf + 1 < buf_end) {
yading@10 200 draw_char(avctx, buf[0], buf[1]);
yading@10 201 buf += 2;
yading@10 202 }
yading@10 203 }
yading@10 204
yading@10 205 if ((ret = av_frame_ref(data, s->frame)) < 0)
yading@10 206 return ret;
yading@10 207 *got_frame = 1;
yading@10 208 return buf_size;
yading@10 209 }
yading@10 210
yading@10 211 static av_cold int decode_end(AVCodecContext *avctx)
yading@10 212 {
yading@10 213 XbinContext *s = avctx->priv_data;
yading@10 214
yading@10 215 av_frame_free(&s->frame);
yading@10 216
yading@10 217 return 0;
yading@10 218 }
yading@10 219
yading@10 220 #if CONFIG_BINTEXT_DECODER
yading@10 221 AVCodec ff_bintext_decoder = {
yading@10 222 .name = "bintext",
yading@10 223 .type = AVMEDIA_TYPE_VIDEO,
yading@10 224 .id = AV_CODEC_ID_BINTEXT,
yading@10 225 .priv_data_size = sizeof(XbinContext),
yading@10 226 .init = decode_init,
yading@10 227 .close = decode_end,
yading@10 228 .decode = decode_frame,
yading@10 229 .capabilities = CODEC_CAP_DR1,
yading@10 230 .long_name = NULL_IF_CONFIG_SMALL("Binary text"),
yading@10 231 };
yading@10 232 #endif
yading@10 233 #if CONFIG_XBIN_DECODER
yading@10 234 AVCodec ff_xbin_decoder = {
yading@10 235 .name = "xbin",
yading@10 236 .type = AVMEDIA_TYPE_VIDEO,
yading@10 237 .id = AV_CODEC_ID_XBIN,
yading@10 238 .priv_data_size = sizeof(XbinContext),
yading@10 239 .init = decode_init,
yading@10 240 .close = decode_end,
yading@10 241 .decode = decode_frame,
yading@10 242 .capabilities = CODEC_CAP_DR1,
yading@10 243 .long_name = NULL_IF_CONFIG_SMALL("eXtended BINary text"),
yading@10 244 };
yading@10 245 #endif
yading@10 246 #if CONFIG_IDF_DECODER
yading@10 247 AVCodec ff_idf_decoder = {
yading@10 248 .name = "idf",
yading@10 249 .type = AVMEDIA_TYPE_VIDEO,
yading@10 250 .id = AV_CODEC_ID_IDF,
yading@10 251 .priv_data_size = sizeof(XbinContext),
yading@10 252 .init = decode_init,
yading@10 253 .close = decode_end,
yading@10 254 .decode = decode_frame,
yading@10 255 .capabilities = CODEC_CAP_DR1,
yading@10 256 .long_name = NULL_IF_CONFIG_SMALL("iCEDraw text"),
yading@10 257 };
yading@10 258 #endif