Libav
|
00001 /* 00002 * V.Flash PTX (.ptx) image decoder 00003 * Copyright (c) 2007 Ivo van Poorten 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 00022 #include "libavutil/intreadwrite.h" 00023 #include "avcodec.h" 00024 00025 typedef struct PTXContext { 00026 AVFrame picture; 00027 } PTXContext; 00028 00029 static av_cold int ptx_init(AVCodecContext *avctx) { 00030 PTXContext *s = avctx->priv_data; 00031 00032 avcodec_get_frame_defaults(&s->picture); 00033 avctx->coded_frame= &s->picture; 00034 00035 return 0; 00036 } 00037 00038 static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, 00039 AVPacket *avpkt) { 00040 const uint8_t *buf = avpkt->data; 00041 PTXContext * const s = avctx->priv_data; 00042 AVFrame *picture = data; 00043 AVFrame * const p = &s->picture; 00044 unsigned int offset, w, h, y, stride, bytes_per_pixel; 00045 uint8_t *ptr; 00046 00047 offset = AV_RL16(buf); 00048 w = AV_RL16(buf+8); 00049 h = AV_RL16(buf+10); 00050 bytes_per_pixel = AV_RL16(buf+12) >> 3; 00051 00052 if (bytes_per_pixel != 2) { 00053 av_log(avctx, AV_LOG_ERROR, "image format is not rgb15, please report on ffmpeg-users mailing list\n"); 00054 return -1; 00055 } 00056 00057 avctx->pix_fmt = PIX_FMT_RGB555; 00058 00059 if (offset != 0x2c) 00060 av_log(avctx, AV_LOG_WARNING, "offset != 0x2c, untested due to lack of sample files\n"); 00061 00062 buf += offset; 00063 00064 if (p->data[0]) 00065 avctx->release_buffer(avctx, p); 00066 00067 if (avcodec_check_dimensions(avctx, w, h)) 00068 return -1; 00069 if (w != avctx->width || h != avctx->height) 00070 avcodec_set_dimensions(avctx, w, h); 00071 if (avctx->get_buffer(avctx, p) < 0) { 00072 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); 00073 return -1; 00074 } 00075 00076 p->pict_type = FF_I_TYPE; 00077 00078 ptr = p->data[0]; 00079 stride = p->linesize[0]; 00080 00081 for (y=0; y<h; y++) { 00082 #if HAVE_BIGENDIAN 00083 unsigned int x; 00084 for (x=0; x<w*bytes_per_pixel; x+=bytes_per_pixel) 00085 AV_WN16(ptr+x, AV_RL16(buf+x)); 00086 #else 00087 memcpy(ptr, buf, w*bytes_per_pixel); 00088 #endif 00089 ptr += stride; 00090 buf += w*bytes_per_pixel; 00091 } 00092 00093 *picture = s->picture; 00094 *data_size = sizeof(AVPicture); 00095 00096 return offset + w*h*bytes_per_pixel; 00097 } 00098 00099 static av_cold int ptx_end(AVCodecContext *avctx) { 00100 PTXContext *s = avctx->priv_data; 00101 00102 if(s->picture.data[0]) 00103 avctx->release_buffer(avctx, &s->picture); 00104 00105 return 0; 00106 } 00107 00108 AVCodec ptx_decoder = { 00109 "ptx", 00110 AVMEDIA_TYPE_VIDEO, 00111 CODEC_ID_PTX, 00112 sizeof(PTXContext), 00113 ptx_init, 00114 NULL, 00115 ptx_end, 00116 ptx_decode_frame, 00117 CODEC_CAP_DR1, 00118 NULL, 00119 .long_name = NULL_IF_CONFIG_SMALL("V.Flash PTX image"), 00120 };