LCOV - code coverage report
Current view: top level - src/libavcodec - bintext.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 107 0.0 %
Date: 2017-03-25 17:02:41 Functions: 0 5 0.0 %

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

Generated by: LCOV version 1.13