Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * XBM image format
  3.  *
  4.  * Copyright (c) 2012 Paul B Mahol
  5.  *
  6.  * This file is part of FFmpeg.
  7.  *
  8.  * FFmpeg is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Lesser General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2.1 of the License, or (at your option) any later version.
  12.  *
  13.  * FFmpeg is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Lesser General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Lesser General Public
  19.  * License along with FFmpeg; if not, write to the Free Software
  20.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21.  */
  22.  
  23. #include "avcodec.h"
  24. #include "internal.h"
  25. #include "mathops.h"
  26. #include "libavutil/avstring.h"
  27.  
  28. static av_cold int xbm_decode_init(AVCodecContext *avctx)
  29. {
  30.     avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
  31.  
  32.     return 0;
  33. }
  34.  
  35. static int convert(uint8_t x)
  36. {
  37.     if (x >= 'a')
  38.         x -= 87;
  39.     else if (x >= 'A')
  40.         x -= 55;
  41.     else
  42.         x -= '0';
  43.     return x;
  44. }
  45.  
  46. static int xbm_decode_frame(AVCodecContext *avctx, void *data,
  47.                             int *got_frame, AVPacket *avpkt)
  48. {
  49.     AVFrame *p = data;
  50.     const uint8_t *end, *ptr = avpkt->data;
  51.     uint8_t *dst;
  52.     int ret, linesize, i, j;
  53.  
  54.     end = avpkt->data + avpkt->size;
  55.     while (!avctx->width || !avctx->height) {
  56.         char name[256];
  57.         int number, len;
  58.  
  59.         ptr += strcspn(ptr, "#");
  60.         if (sscanf(ptr, "#define %255s %u", name, &number) != 2) {
  61.             av_log(avctx, AV_LOG_ERROR, "Unexpected preprocessor directive\n");
  62.             return AVERROR_INVALIDDATA;
  63.         }
  64.  
  65.         len = strlen(name);
  66.         if ((len > 6) && !avctx->height && !memcmp(name + len - 7, "_height", 7)) {
  67.                 avctx->height = number;
  68.         } else if ((len > 5) && !avctx->width && !memcmp(name + len - 6, "_width", 6)) {
  69.                 avctx->width = number;
  70.         } else {
  71.             av_log(avctx, AV_LOG_ERROR, "Unknown define '%s'\n", name);
  72.             return AVERROR_INVALIDDATA;
  73.         }
  74.         ptr += strcspn(ptr, "\n\r") + 1;
  75.     }
  76.  
  77.     if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
  78.         return ret;
  79.  
  80.     // goto start of image data
  81.     ptr += strcspn(ptr, "{") + 1;
  82.  
  83.     linesize = (avctx->width + 7) / 8;
  84.     for (i = 0; i < avctx->height; i++) {
  85.         dst = p->data[0] + i * p->linesize[0];
  86.         for (j = 0; j < linesize; j++) {
  87.             uint8_t val;
  88.  
  89.             ptr += strcspn(ptr, "x") + 1;
  90.             if (ptr < end && av_isxdigit(*ptr)) {
  91.                 val = convert(*ptr);
  92.                 ptr++;
  93.                 if (av_isxdigit(*ptr))
  94.                     val = (val << 4) + convert(*ptr);
  95.                 *dst++ = ff_reverse[val];
  96.             } else {
  97.                 av_log(avctx, AV_LOG_ERROR, "Unexpected data at '%.8s'\n", ptr);
  98.                 return AVERROR_INVALIDDATA;
  99.             }
  100.         }
  101.     }
  102.  
  103.     p->key_frame = 1;
  104.     p->pict_type = AV_PICTURE_TYPE_I;
  105.  
  106.     *got_frame       = 1;
  107.  
  108.     return avpkt->size;
  109. }
  110.  
  111. AVCodec ff_xbm_decoder = {
  112.     .name         = "xbm",
  113.     .long_name    = NULL_IF_CONFIG_SMALL("XBM (X BitMap) image"),
  114.     .type         = AVMEDIA_TYPE_VIDEO,
  115.     .id           = AV_CODEC_ID_XBM,
  116.     .init         = xbm_decode_init,
  117.     .decode       = xbm_decode_frame,
  118.     .capabilities = CODEC_CAP_DR1,
  119. };
  120.