1/* 2 * V.Flash PTX (.ptx) image decoder 3 * Copyright (c) 2007 Ivo van Poorten 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22#include "libavutil/common.h" 23#include "libavutil/intreadwrite.h" 24#include "libavutil/imgutils.h" 25#include "avcodec.h" 26#include "codec_internal.h" 27#include "internal.h" 28 29static int ptx_decode_frame(AVCodecContext *avctx, AVFrame *p, 30 int *got_frame, AVPacket *avpkt) 31{ 32 const uint8_t *buf = avpkt->data; 33 const uint8_t *buf_end = avpkt->data + avpkt->size; 34 unsigned int offset, w, h, y, stride, bytes_per_pixel; 35 int ret; 36 uint8_t *ptr; 37 38 if (buf_end - buf < 14) 39 return AVERROR_INVALIDDATA; 40 offset = AV_RL16(buf); 41 w = AV_RL16(buf+8); 42 h = AV_RL16(buf+10); 43 bytes_per_pixel = AV_RL16(buf+12) >> 3; 44 45 if (bytes_per_pixel != 2) { 46 avpriv_request_sample(avctx, "Image format not RGB15"); 47 return AVERROR_PATCHWELCOME; 48 } 49 50 avctx->pix_fmt = AV_PIX_FMT_BGR555LE; 51 52 if (buf_end - buf < offset) 53 return AVERROR_INVALIDDATA; 54 if (offset != 0x2c) 55 avpriv_request_sample(avctx, "offset != 0x2c"); 56 57 buf += offset; 58 59 if (buf_end - buf < w * bytes_per_pixel) 60 return AVERROR_INVALIDDATA; 61 62 if ((ret = ff_set_dimensions(avctx, w, h)) < 0) 63 return ret; 64 65 if ((ret = ff_get_buffer(avctx, p, 0)) < 0) 66 return ret; 67 68 p->pict_type = AV_PICTURE_TYPE_I; 69 70 ptr = p->data[0]; 71 stride = p->linesize[0]; 72 73 for (y = 0; y < h && buf_end - buf >= w * bytes_per_pixel; y++) { 74 memcpy(ptr, buf, w*bytes_per_pixel); 75 ptr += stride; 76 buf += w*bytes_per_pixel; 77 } 78 79 *got_frame = 1; 80 81 if (y < h) { 82 av_log(avctx, AV_LOG_WARNING, "incomplete packet\n"); 83 return avpkt->size; 84 } 85 86 return offset + w*h*bytes_per_pixel; 87} 88 89const FFCodec ff_ptx_decoder = { 90 .p.name = "ptx", 91 .p.long_name = NULL_IF_CONFIG_SMALL("V.Flash PTX image"), 92 .p.type = AVMEDIA_TYPE_VIDEO, 93 .p.id = AV_CODEC_ID_PTX, 94 .p.capabilities = AV_CODEC_CAP_DR1, 95 FF_CODEC_DECODE_CB(ptx_decode_frame), 96}; 97