qdrw.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:4k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.  * QuickDraw (qdrw) codec
  3.  * Copyright (c) 2004 Konstantin Shishkov
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Lesser General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2 of the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Lesser General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Lesser General Public
  16.  * License along with this library; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  *
  19.  */
  20.  
  21. /**
  22.  * @file qdrw.c
  23.  * Apple QuickDraw codec.
  24.  */
  25.  
  26. #include "avcodec.h"
  27. #include "mpegvideo.h"
  28. typedef struct QdrawContext{
  29.     AVCodecContext *avctx;
  30.     AVFrame pic;
  31.     uint8_t palette[256*3];
  32. } QdrawContext;
  33. static int decode_frame(AVCodecContext *avctx, 
  34.                         void *data, int *data_size,
  35.                         uint8_t *buf, int buf_size)
  36. {
  37.     QdrawContext * const a = avctx->priv_data;
  38.     AVFrame * const p= (AVFrame*)&a->pic;
  39.     uint8_t* outdata;
  40.     int colors;
  41.     int i;
  42.     
  43.     if(p->data[0])
  44.         avctx->release_buffer(avctx, p);
  45.     p->reference= 0;
  46.     if(avctx->get_buffer(avctx, p) < 0){
  47.         av_log(avctx, AV_LOG_ERROR, "get_buffer() failedn");
  48.         return -1;
  49.     }
  50.     p->pict_type= I_TYPE;
  51.     p->key_frame= 1;
  52.     outdata = a->pic.data[0];
  53.     
  54.     buf += 0x68; /* jump to palette */
  55.     colors = BE_32(buf);
  56.     buf += 4;
  57.     
  58.     if(colors < 0 || colors > 256) {
  59.         av_log(avctx, AV_LOG_ERROR, "Error color count - %i(0x%X)n", colors, colors);
  60.         return -1;
  61.     }
  62.     
  63.     for (i = 0; i <= colors; i++) {
  64.         unsigned int idx;
  65.         idx = BE_16(buf); /* color index */
  66.         buf += 2;
  67.         
  68.         if (idx > 255) {
  69.             av_log(avctx, AV_LOG_ERROR, "Palette index out of range: %un", idx);
  70.             buf += 6;
  71.             continue;
  72.         }
  73.         a->palette[idx * 3 + 0] = *buf++;
  74.         buf++;
  75.         a->palette[idx * 3 + 1] = *buf++;
  76.         buf++;
  77.         a->palette[idx * 3 + 2] = *buf++;
  78.         buf++;
  79.     }
  80.     buf += 18; /* skip unneeded data */
  81.     for (i = 0; i < avctx->height; i++) {
  82.         int size, left, code, pix;
  83.         uint8_t *next;
  84.         uint8_t *out;
  85.         int tsize = 0;
  86.         
  87.         /* decode line */
  88.         out = outdata;
  89.         size = BE_16(buf); /* size of packed line */
  90.         buf += 2;
  91.         left = size;
  92.         next = buf + size;
  93.         while (left > 0) {
  94.             code = *buf++;
  95.             if (code & 0x80 ) { /* run */
  96.                 int i;
  97.                 pix = *buf++;
  98.                 if ((out + (257 - code) * 3) > (outdata +  a->pic.linesize[0]))
  99.                     break;
  100.                 for (i = 0; i < 257 - code; i++) {
  101.                     *out++ = a->palette[pix * 3 + 0];
  102.                     *out++ = a->palette[pix * 3 + 1];
  103.                     *out++ = a->palette[pix * 3 + 2];
  104.                 }
  105.                 tsize += 257 - code;
  106.                 left -= 2;
  107.             } else { /* copy */
  108.                 int i, pix;
  109.                 if ((out + code * 3) > (outdata +  a->pic.linesize[0]))
  110.                     break;
  111.                 for (i = 0; i <= code; i++) {
  112.                     pix = *buf++;
  113.                     *out++ = a->palette[pix * 3 + 0];
  114.                     *out++ = a->palette[pix * 3 + 1];
  115.                     *out++ = a->palette[pix * 3 + 2];
  116.                 }
  117.                 left -= 2 + code;
  118.                 tsize += code + 1;
  119.             }
  120.         }
  121.         buf = next;
  122.         outdata += a->pic.linesize[0];
  123.     }
  124.     *data_size = sizeof(AVFrame);
  125.     *(AVFrame*)data = a->pic;
  126.     
  127.     return buf_size;
  128. }
  129. static int decode_init(AVCodecContext *avctx){
  130. //    QdrawContext * const a = avctx->priv_data;
  131.     if (avcodec_check_dimensions(avctx, avctx->height, avctx->width) < 0) {
  132.         return 1;
  133.     }
  134.     avctx->pix_fmt= PIX_FMT_RGB24;
  135.     return 0;
  136. }
  137. AVCodec qdraw_decoder = {
  138.     "qdraw",
  139.     CODEC_TYPE_VIDEO,
  140.     CODEC_ID_QDRAW,
  141.     sizeof(QdrawContext),
  142.     decode_init,
  143.     NULL,
  144.     NULL,
  145.     decode_frame,
  146.     CODEC_CAP_DR1,
  147. };