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