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