• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/qdrw.c

Go to the documentation of this file.
00001 /*
00002  * QuickDraw (qdrw) codec
00003  * Copyright (c) 2004 Konstantin Shishkov
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00027 #include "libavutil/intreadwrite.h"
00028 #include "avcodec.h"
00029 
00030 typedef struct QdrawContext{
00031     AVCodecContext *avctx;
00032     AVFrame pic;
00033 } QdrawContext;
00034 
00035 static int decode_frame(AVCodecContext *avctx,
00036                         void *data, int *data_size,
00037                         AVPacket *avpkt)
00038 {
00039     const uint8_t *buf = avpkt->data;
00040     int buf_size = avpkt->size;
00041     QdrawContext * const a = avctx->priv_data;
00042     AVFrame * const p= (AVFrame*)&a->pic;
00043     uint8_t* outdata;
00044     int colors;
00045     int i;
00046     uint32_t *pal;
00047     int r, g, b;
00048 
00049     if(p->data[0])
00050         avctx->release_buffer(avctx, p);
00051 
00052     p->reference= 0;
00053     if(avctx->get_buffer(avctx, p) < 0){
00054         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00055         return -1;
00056     }
00057     p->pict_type= FF_I_TYPE;
00058     p->key_frame= 1;
00059 
00060     outdata = a->pic.data[0];
00061 
00062     buf += 0x68; /* jump to palette */
00063     colors = AV_RB32(buf);
00064     buf += 4;
00065 
00066     if(colors < 0 || colors > 256) {
00067         av_log(avctx, AV_LOG_ERROR, "Error color count - %i(0x%X)\n", colors, colors);
00068         return -1;
00069     }
00070 
00071     pal = (uint32_t*)p->data[1];
00072     for (i = 0; i <= colors; i++) {
00073         unsigned int idx;
00074         idx = AV_RB16(buf); /* color index */
00075         buf += 2;
00076 
00077         if (idx > 255) {
00078             av_log(avctx, AV_LOG_ERROR, "Palette index out of range: %u\n", idx);
00079             buf += 6;
00080             continue;
00081         }
00082         r = *buf++;
00083         buf++;
00084         g = *buf++;
00085         buf++;
00086         b = *buf++;
00087         buf++;
00088         pal[idx] = (r << 16) | (g << 8) | b;
00089     }
00090     p->palette_has_changed = 1;
00091 
00092     buf += 18; /* skip unneeded data */
00093     for (i = 0; i < avctx->height; i++) {
00094         int size, left, code, pix;
00095         const uint8_t *next;
00096         uint8_t *out;
00097         int tsize = 0;
00098 
00099         /* decode line */
00100         out = outdata;
00101         size = AV_RB16(buf); /* size of packed line */
00102         buf += 2;
00103         left = size;
00104         next = buf + size;
00105         while (left > 0) {
00106             code = *buf++;
00107             if (code & 0x80 ) { /* run */
00108                 pix = *buf++;
00109                 if ((out + (257 - code)) > (outdata +  a->pic.linesize[0]))
00110                     break;
00111                 memset(out, pix, 257 - code);
00112                 out += 257 - code;
00113                 tsize += 257 - code;
00114                 left -= 2;
00115             } else { /* copy */
00116                 if ((out + code) > (outdata +  a->pic.linesize[0]))
00117                     break;
00118                 memcpy(out, buf, code + 1);
00119                 out += code + 1;
00120                 buf += code + 1;
00121                 left -= 2 + code;
00122                 tsize += code + 1;
00123             }
00124         }
00125         buf = next;
00126         outdata += a->pic.linesize[0];
00127     }
00128 
00129     *data_size = sizeof(AVFrame);
00130     *(AVFrame*)data = a->pic;
00131 
00132     return buf_size;
00133 }
00134 
00135 static av_cold int decode_init(AVCodecContext *avctx){
00136 //    QdrawContext * const a = avctx->priv_data;
00137 
00138     avctx->pix_fmt= PIX_FMT_PAL8;
00139 
00140     return 0;
00141 }
00142 
00143 static av_cold int decode_end(AVCodecContext *avctx){
00144     QdrawContext * const a = avctx->priv_data;
00145     AVFrame *pic = &a->pic;
00146 
00147     if (pic->data[0])
00148         avctx->release_buffer(avctx, pic);
00149 
00150     return 0;
00151 }
00152 
00153 AVCodec qdraw_decoder = {
00154     "qdraw",
00155     AVMEDIA_TYPE_VIDEO,
00156     CODEC_ID_QDRAW,
00157     sizeof(QdrawContext),
00158     decode_init,
00159     NULL,
00160     decode_end,
00161     decode_frame,
00162     CODEC_CAP_DR1,
00163     .long_name = NULL_IF_CONFIG_SMALL("Apple QuickDraw"),
00164 };

Generated on Fri Sep 16 2011 17:17:42 for FFmpeg by  doxygen 1.7.1