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 "internal.h" 27 28static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, 29 AVPacket *avpkt) { 30 const uint8_t *buf = avpkt->data; 31 const uint8_t *buf_end = avpkt->data + avpkt->size; 32 AVFrame * const p = data; 33 unsigned int offset, w, h, y, stride, bytes_per_pixel; 34 int ret; 35 uint8_t *ptr; 36 37 if (buf_end - buf < 14) 38 return AVERROR_INVALIDDATA; 39 offset = AV_RL16(buf); 40 w = AV_RL16(buf+8); 41 h = AV_RL16(buf+10); 42 bytes_per_pixel = AV_RL16(buf+12) >> 3; 43 44 if (bytes_per_pixel != 2) { 45 avpriv_request_sample(avctx, "Image format not RGB15"); 46 return AVERROR_PATCHWELCOME; 47 } 48 49 avctx->pix_fmt = AV_PIX_FMT_BGR555LE; 50 51 if (buf_end - buf < offset) 52 return AVERROR_INVALIDDATA; 53 if (offset != 0x2c) 54 avpriv_request_sample(avctx, "offset != 0x2c"); 55 56 buf += offset; 57 58 if ((ret = ff_set_dimensions(avctx, w, h)) < 0) 59 return ret; 60 61 if ((ret = ff_get_buffer(avctx, p, 0)) < 0) 62 return ret; 63 64 p->pict_type = AV_PICTURE_TYPE_I; 65 66 ptr = p->data[0]; 67 stride = p->linesize[0]; 68 69 for (y = 0; y < h && buf_end - buf >= w * bytes_per_pixel; y++) { 70 memcpy(ptr, buf, w*bytes_per_pixel); 71 ptr += stride; 72 buf += w*bytes_per_pixel; 73 } 74 75 *got_frame = 1; 76 77 if (y < h) { 78 av_log(avctx, AV_LOG_WARNING, "incomplete packet\n"); 79 return avpkt->size; 80 } 81 82 return offset + w*h*bytes_per_pixel; 83} 84 85AVCodec ff_ptx_decoder = { 86 .name = "ptx", 87 .long_name = NULL_IF_CONFIG_SMALL("V.Flash PTX image"), 88 .type = AVMEDIA_TYPE_VIDEO, 89 .id = AV_CODEC_ID_PTX, 90 .decode = ptx_decode_frame, 91 .capabilities = CODEC_CAP_DR1, 92}; 93