added still image support
Originally committed as revision 1439 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
		
							parent
							
								
									f746a04616
								
							
						
					
					
						commit
						87a0a6816f
					
				@ -12,9 +12,13 @@ OBJS= utils.o cutils.o allformats.o
 | 
			
		||||
 | 
			
		||||
# mux and demuxes
 | 
			
		||||
OBJS+=mpeg.o mpegts.o ffm.o crc.o img.o raw.o rm.o asf.o \
 | 
			
		||||
      avienc.o avidec.o wav.o swf.o au.o gif.o mov.o jpeg.o dv.o framehook.o
 | 
			
		||||
      avienc.o avidec.o wav.o swf.o au.o gif.o mov.o jpeg.o dv.o \
 | 
			
		||||
      yuv4mpeg.o
 | 
			
		||||
# image formats
 | 
			
		||||
OBJS+= pnm.o yuv.o
 | 
			
		||||
# file I/O
 | 
			
		||||
OBJS+= avio.o aviobuf.o file.o 
 | 
			
		||||
OBJS+= framehook.o 
 | 
			
		||||
 | 
			
		||||
ifeq ($(BUILD_STRPTIME),yes)
 | 
			
		||||
OBJS+= strptime.o
 | 
			
		||||
 | 
			
		||||
@ -45,6 +45,8 @@ void av_register_all(void)
 | 
			
		||||
    mov_init();
 | 
			
		||||
    jpeg_init();
 | 
			
		||||
    dv_init();
 | 
			
		||||
 | 
			
		||||
    av_register_output_format(&yuv4mpegpipe_oformat);
 | 
			
		||||
    
 | 
			
		||||
#ifdef CONFIG_VORBIS
 | 
			
		||||
    ogg_init();
 | 
			
		||||
@ -60,6 +62,14 @@ void av_register_all(void)
 | 
			
		||||
    audio_init();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* image formats */
 | 
			
		||||
    av_register_image_format(&pnm_image_format);
 | 
			
		||||
    av_register_image_format(&pbm_image_format);
 | 
			
		||||
    av_register_image_format(&pgm_image_format);
 | 
			
		||||
    av_register_image_format(&ppm_image_format);
 | 
			
		||||
    av_register_image_format(&pgmyuv_image_format);
 | 
			
		||||
    av_register_image_format(&yuv_image_format);
 | 
			
		||||
 | 
			
		||||
    /* file protocols */
 | 
			
		||||
    register_protocol(&file_protocol);
 | 
			
		||||
    register_protocol(&pipe_protocol);
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										285
									
								
								libavformat/pnm.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										285
									
								
								libavformat/pnm.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,285 @@
 | 
			
		||||
/*
 | 
			
		||||
 * PNM image format
 | 
			
		||||
 * Copyright (c) 2002, 2003 Fabrice Bellard.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
#include "avformat.h"
 | 
			
		||||
 | 
			
		||||
static inline int pnm_space(int c)  
 | 
			
		||||
{
 | 
			
		||||
    return (c == ' ' || c == '\n' || c == '\r' || c == '\t');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pnm_get(ByteIOContext *f, char *str, int buf_size) 
 | 
			
		||||
{
 | 
			
		||||
    char *s;
 | 
			
		||||
    int c;
 | 
			
		||||
    
 | 
			
		||||
    /* skip spaces and comments */
 | 
			
		||||
    for(;;) {
 | 
			
		||||
        c = url_fgetc(f);
 | 
			
		||||
        if (c == '#')  {
 | 
			
		||||
            do  {
 | 
			
		||||
                c = url_fgetc(f);
 | 
			
		||||
            } while (c != '\n' && c != URL_EOF);
 | 
			
		||||
        } else if (!pnm_space(c)) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    s = str;
 | 
			
		||||
    while (c != URL_EOF && !pnm_space(c)) {
 | 
			
		||||
        if ((s - str)  < buf_size - 1)
 | 
			
		||||
            *s++ = c;
 | 
			
		||||
        c = url_fgetc(f);
 | 
			
		||||
    }
 | 
			
		||||
    *s = '\0';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int pnm_read1(ByteIOContext *f, 
 | 
			
		||||
                     int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque,
 | 
			
		||||
                     int allow_yuv)
 | 
			
		||||
{
 | 
			
		||||
    int i, n, linesize, h;
 | 
			
		||||
    char buf1[32];
 | 
			
		||||
    unsigned char *ptr;
 | 
			
		||||
    AVImageInfo info1, *info = &info1;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    pnm_get(f, buf1, sizeof(buf1));
 | 
			
		||||
    if (!strcmp(buf1, "P4")) {
 | 
			
		||||
        info->pix_fmt = PIX_FMT_MONOWHITE;
 | 
			
		||||
    } else if (!strcmp(buf1, "P5")) {
 | 
			
		||||
        if (allow_yuv) 
 | 
			
		||||
            info->pix_fmt = PIX_FMT_YUV420P;
 | 
			
		||||
        else
 | 
			
		||||
            info->pix_fmt = PIX_FMT_GRAY8;
 | 
			
		||||
    } else if (!strcmp(buf1, "P6")) {
 | 
			
		||||
        info->pix_fmt = PIX_FMT_RGB24;
 | 
			
		||||
    } else {
 | 
			
		||||
        return AVERROR_INVALIDDATA;
 | 
			
		||||
    }
 | 
			
		||||
    pnm_get(f, buf1, sizeof(buf1));
 | 
			
		||||
    info->width = atoi(buf1);
 | 
			
		||||
    if (info->width <= 0)
 | 
			
		||||
        return AVERROR_INVALIDDATA;
 | 
			
		||||
    pnm_get(f, buf1, sizeof(buf1));
 | 
			
		||||
    info->height = atoi(buf1);
 | 
			
		||||
    if (info->height <= 0)
 | 
			
		||||
        return AVERROR_INVALIDDATA;
 | 
			
		||||
    if (info->pix_fmt != PIX_FMT_MONOWHITE) {
 | 
			
		||||
        pnm_get(f, buf1, sizeof(buf1));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* more check if YUV420 */
 | 
			
		||||
    if (info->pix_fmt == PIX_FMT_YUV420P) {
 | 
			
		||||
        if ((info->width & 1) != 0)
 | 
			
		||||
            return AVERROR_INVALIDDATA;
 | 
			
		||||
        h = (info->height * 2);
 | 
			
		||||
        if ((h % 3) != 0)
 | 
			
		||||
            return AVERROR_INVALIDDATA;
 | 
			
		||||
        h /= 3;
 | 
			
		||||
        info->height = h;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    ret = alloc_cb(opaque, info);
 | 
			
		||||
    if (ret)
 | 
			
		||||
        return ret;
 | 
			
		||||
    
 | 
			
		||||
    switch(info->pix_fmt) {
 | 
			
		||||
    default:
 | 
			
		||||
        return AVERROR_INVALIDDATA;
 | 
			
		||||
    case PIX_FMT_RGB24:
 | 
			
		||||
        n = info->width * 3;
 | 
			
		||||
        goto do_read;
 | 
			
		||||
    case PIX_FMT_GRAY8:
 | 
			
		||||
        n = info->width;
 | 
			
		||||
        goto do_read;
 | 
			
		||||
    case PIX_FMT_MONOWHITE:
 | 
			
		||||
        n = (info->width + 7) >> 3;
 | 
			
		||||
    do_read:
 | 
			
		||||
        ptr = info->pict.data[0];
 | 
			
		||||
        linesize = info->pict.linesize[0];
 | 
			
		||||
        for(i = 0; i < info->height; i++) {
 | 
			
		||||
            get_buffer(f, ptr, n);
 | 
			
		||||
            ptr += linesize;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case PIX_FMT_YUV420P:
 | 
			
		||||
        {
 | 
			
		||||
            unsigned char *ptr1, *ptr2;
 | 
			
		||||
 | 
			
		||||
            n = info->width;
 | 
			
		||||
            ptr = info->pict.data[0];
 | 
			
		||||
            linesize = info->pict.linesize[0];
 | 
			
		||||
            for(i = 0; i < info->height; i++) {
 | 
			
		||||
                get_buffer(f, ptr, n);
 | 
			
		||||
                ptr += linesize;
 | 
			
		||||
            }
 | 
			
		||||
            ptr1 = info->pict.data[1];
 | 
			
		||||
            ptr2 = info->pict.data[2];
 | 
			
		||||
            n >>= 1;
 | 
			
		||||
            h = info->height >> 1;
 | 
			
		||||
            for(i = 0; i < h; i++) {
 | 
			
		||||
                get_buffer(f, ptr1, n);
 | 
			
		||||
                get_buffer(f, ptr2, n);
 | 
			
		||||
                ptr1 += info->pict.linesize[1];
 | 
			
		||||
                ptr2 += info->pict.linesize[2];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int pnm_read(ByteIOContext *f, 
 | 
			
		||||
                    int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    return pnm_read1(f, alloc_cb, opaque, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int pgmyuv_read(ByteIOContext *f, 
 | 
			
		||||
                       int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    return pnm_read1(f, alloc_cb, opaque, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int pnm_write(ByteIOContext *pb, AVImageInfo *info)
 | 
			
		||||
{
 | 
			
		||||
    int i, h, h1, c, n, linesize;
 | 
			
		||||
    char buf[100];
 | 
			
		||||
    UINT8 *ptr, *ptr1, *ptr2;
 | 
			
		||||
 | 
			
		||||
    h = info->height;
 | 
			
		||||
    h1 = h;
 | 
			
		||||
    switch(info->pix_fmt) {
 | 
			
		||||
    case PIX_FMT_MONOWHITE:
 | 
			
		||||
        c = '4';
 | 
			
		||||
        n = (info->width + 7) >> 3;
 | 
			
		||||
        break;
 | 
			
		||||
    case PIX_FMT_GRAY8:
 | 
			
		||||
        c = '5';
 | 
			
		||||
        n = info->width;
 | 
			
		||||
        break;
 | 
			
		||||
    case PIX_FMT_RGB24:
 | 
			
		||||
        c = '6';
 | 
			
		||||
        n = info->width * 3;
 | 
			
		||||
        break;
 | 
			
		||||
    case PIX_FMT_YUV420P:
 | 
			
		||||
        c = '5';
 | 
			
		||||
        n = info->width;
 | 
			
		||||
        h1 = (h * 3) / 2;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        return AVERROR_INVALIDDATA;
 | 
			
		||||
    }
 | 
			
		||||
    snprintf(buf, sizeof(buf), 
 | 
			
		||||
             "P%c\n%d %d\n",
 | 
			
		||||
             c, info->width, h1);
 | 
			
		||||
    put_buffer(pb, buf, strlen(buf));
 | 
			
		||||
    if (info->pix_fmt != PIX_FMT_MONOWHITE) {
 | 
			
		||||
        snprintf(buf, sizeof(buf), 
 | 
			
		||||
                 "%d\n", 255);
 | 
			
		||||
        put_buffer(pb, buf, strlen(buf));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    ptr = info->pict.data[0];
 | 
			
		||||
    linesize = info->pict.linesize[0];
 | 
			
		||||
    for(i=0;i<h;i++) {
 | 
			
		||||
        put_buffer(pb, ptr, n);
 | 
			
		||||
        ptr += linesize;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (info->pix_fmt == PIX_FMT_YUV420P) {
 | 
			
		||||
        h >>= 1;
 | 
			
		||||
        n >>= 1;
 | 
			
		||||
        ptr1 = info->pict.data[1];
 | 
			
		||||
        ptr2 = info->pict.data[2];
 | 
			
		||||
        for(i=0;i<h;i++) {
 | 
			
		||||
            put_buffer(pb, ptr1, n);
 | 
			
		||||
            put_buffer(pb, ptr2, n);
 | 
			
		||||
            ptr1 += info->pict.linesize[1];
 | 
			
		||||
            ptr2 += info->pict.linesize[2];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    put_flush_packet(pb);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
    
 | 
			
		||||
static int pnm_probe(AVProbeData *pd)
 | 
			
		||||
{
 | 
			
		||||
    const char *p = pd->buf;
 | 
			
		||||
    if (pd->buf_size >= 8 &&
 | 
			
		||||
        p[0] == 'P' &&
 | 
			
		||||
        p[1] >= '4' && p[1] <= '6' &&
 | 
			
		||||
        p[2] == '\n')
 | 
			
		||||
        return AVPROBE_SCORE_MAX;
 | 
			
		||||
    else
 | 
			
		||||
        return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int pgmyuv_probe(AVProbeData *pd)
 | 
			
		||||
{
 | 
			
		||||
    if (match_ext(pd->filename, "pgmyuv"))
 | 
			
		||||
        return AVPROBE_SCORE_MAX;
 | 
			
		||||
    else
 | 
			
		||||
        return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AVImageFormat pnm_image_format = {
 | 
			
		||||
    "pnm",
 | 
			
		||||
    NULL,
 | 
			
		||||
    pnm_probe,
 | 
			
		||||
    pnm_read,
 | 
			
		||||
    0,
 | 
			
		||||
    NULL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
AVImageFormat pbm_image_format = {
 | 
			
		||||
    "pbm",
 | 
			
		||||
    "pbm",
 | 
			
		||||
    NULL,
 | 
			
		||||
    NULL,
 | 
			
		||||
    (1 << PIX_FMT_MONOWHITE),
 | 
			
		||||
    pnm_write,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
AVImageFormat pgm_image_format = {
 | 
			
		||||
    "pgm",
 | 
			
		||||
    "pgm",
 | 
			
		||||
    NULL,
 | 
			
		||||
    NULL,
 | 
			
		||||
    (1 << PIX_FMT_GRAY8),
 | 
			
		||||
    pnm_write,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
AVImageFormat ppm_image_format = {
 | 
			
		||||
    "ppm",
 | 
			
		||||
    "ppm",
 | 
			
		||||
    NULL,
 | 
			
		||||
    NULL,
 | 
			
		||||
    (1 << PIX_FMT_RGB24),
 | 
			
		||||
    pnm_write,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
AVImageFormat pgmyuv_image_format = {
 | 
			
		||||
    "pgmyuv",
 | 
			
		||||
    NULL,
 | 
			
		||||
    pgmyuv_probe,
 | 
			
		||||
    pgmyuv_read,
 | 
			
		||||
    (1 << PIX_FMT_YUV420P),
 | 
			
		||||
    pnm_write,
 | 
			
		||||
};
 | 
			
		||||
@ -35,6 +35,7 @@
 | 
			
		||||
 | 
			
		||||
AVInputFormat *first_iformat;
 | 
			
		||||
AVOutputFormat *first_oformat;
 | 
			
		||||
AVImageFormat *first_image_format;
 | 
			
		||||
 | 
			
		||||
void av_register_input_format(AVInputFormat *format)
 | 
			
		||||
{
 | 
			
		||||
@ -84,6 +85,11 @@ AVOutputFormat *guess_format(const char *short_name, const char *filename,
 | 
			
		||||
    AVOutputFormat *fmt, *fmt_found;
 | 
			
		||||
    int score_max, score;
 | 
			
		||||
 | 
			
		||||
    /* specific test for image sequences */
 | 
			
		||||
    if (!short_name && filename && filename_number_test(filename) >= 0) {
 | 
			
		||||
        return guess_format("image", NULL, NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* find the proper file type */
 | 
			
		||||
    fmt_found = NULL;
 | 
			
		||||
    score_max = 0;
 | 
			
		||||
@ -326,8 +332,8 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
 | 
			
		||||
        fmt = av_probe_input_format(pd, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* if no file needed do not try to open one */
 | 
			
		||||
    if (!fmt || !(fmt->flags & AVFMT_NOFILE)) {
 | 
			
		||||
        /* if no file needed do not try to open one */
 | 
			
		||||
        if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0) {
 | 
			
		||||
            err = AVERROR_IO;
 | 
			
		||||
            goto fail;
 | 
			
		||||
@ -365,6 +371,14 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
 | 
			
		||||
 | 
			
		||||
    ic->iformat = fmt;
 | 
			
		||||
 | 
			
		||||
    /* check filename in case of an image number is expected */
 | 
			
		||||
    if (ic->iformat->flags & AVFMT_NEEDNUMBER) {
 | 
			
		||||
        if (filename_number_test(ic->filename) < 0) { 
 | 
			
		||||
            err = AVERROR_NUMEXPECTED;
 | 
			
		||||
            goto fail1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /* allocate private data */
 | 
			
		||||
    ic->priv_data = av_mallocz(fmt->priv_data_size);
 | 
			
		||||
    if (!ic->priv_data) {
 | 
			
		||||
@ -375,14 +389,6 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
 | 
			
		||||
    /* default pts settings is MPEG like */
 | 
			
		||||
    av_set_pts_info(ic, 33, 1, 90000);
 | 
			
		||||
 | 
			
		||||
    /* check filename in case of an image number is expected */
 | 
			
		||||
    if (ic->iformat->flags & AVFMT_NEEDNUMBER) {
 | 
			
		||||
        if (filename_number_test(ic->filename) < 0) { 
 | 
			
		||||
            err = AVERROR_NUMEXPECTED;
 | 
			
		||||
            goto fail1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    err = ic->iformat->read_header(ic, ap);
 | 
			
		||||
    if (err < 0)
 | 
			
		||||
        goto fail1;
 | 
			
		||||
@ -707,6 +713,21 @@ AVStream *av_new_stream(AVFormatContext *s, int id)
 | 
			
		||||
/************************************************************/
 | 
			
		||||
/* output media file */
 | 
			
		||||
 | 
			
		||||
int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    s->priv_data = av_mallocz(s->oformat->priv_data_size);
 | 
			
		||||
    if (!s->priv_data)
 | 
			
		||||
        return AVERROR_NOMEM;
 | 
			
		||||
    if (s->oformat->set_parameters) {
 | 
			
		||||
        ret = s->oformat->set_parameters(s, ap);
 | 
			
		||||
        if (ret < 0)
 | 
			
		||||
            return ret;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * allocate the stream private data and write the stream header to an
 | 
			
		||||
 * output media file
 | 
			
		||||
@ -719,9 +740,6 @@ int av_write_header(AVFormatContext *s)
 | 
			
		||||
    int ret, i;
 | 
			
		||||
    AVStream *st;
 | 
			
		||||
 | 
			
		||||
    s->priv_data = av_mallocz(s->oformat->priv_data_size);
 | 
			
		||||
    if (!s->priv_data)
 | 
			
		||||
        return AVERROR_NOMEM;
 | 
			
		||||
    /* default pts settings is MPEG like */
 | 
			
		||||
    av_set_pts_info(s, 33, 1, 90000);
 | 
			
		||||
    ret = s->oformat->write_header(s);
 | 
			
		||||
@ -1291,3 +1309,88 @@ void av_frac_add(AVFrac *f, INT64 incr)
 | 
			
		||||
    }
 | 
			
		||||
    f->num = num;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * register a new image format
 | 
			
		||||
 * @param img_fmt Image format descriptor
 | 
			
		||||
 */
 | 
			
		||||
void av_register_image_format(AVImageFormat *img_fmt)
 | 
			
		||||
{
 | 
			
		||||
    AVImageFormat **p;
 | 
			
		||||
 | 
			
		||||
    p = &first_image_format;
 | 
			
		||||
    while (*p != NULL) p = &(*p)->next;
 | 
			
		||||
    *p = img_fmt;
 | 
			
		||||
    img_fmt->next = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* guess image format */
 | 
			
		||||
AVImageFormat *av_probe_image_format(AVProbeData *pd)
 | 
			
		||||
{
 | 
			
		||||
    AVImageFormat *fmt1, *fmt;
 | 
			
		||||
    int score, score_max;
 | 
			
		||||
 | 
			
		||||
    fmt = NULL;
 | 
			
		||||
    score_max = 0;
 | 
			
		||||
    for(fmt1 = first_image_format; fmt1 != NULL; fmt1 = fmt1->next) {
 | 
			
		||||
        if (fmt1->img_probe) {
 | 
			
		||||
            score = fmt1->img_probe(pd);
 | 
			
		||||
            if (score > score_max) {
 | 
			
		||||
                score_max = score;
 | 
			
		||||
                fmt = fmt1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return fmt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AVImageFormat *guess_image_format(const char *filename)
 | 
			
		||||
{
 | 
			
		||||
    AVImageFormat *fmt1;
 | 
			
		||||
 | 
			
		||||
    for(fmt1 = first_image_format; fmt1 != NULL; fmt1 = fmt1->next) {
 | 
			
		||||
        if (fmt1->extensions && match_ext(filename, fmt1->extensions))
 | 
			
		||||
            return fmt1;
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Read an image from a stream. 
 | 
			
		||||
 * @param gb byte stream containing the image
 | 
			
		||||
 * @param fmt image format, NULL if probing is required
 | 
			
		||||
 */
 | 
			
		||||
int av_read_image(ByteIOContext *pb, const char *filename,
 | 
			
		||||
                  AVImageFormat *fmt,
 | 
			
		||||
                  int (*alloc_cb)(void *, AVImageInfo *info), void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    char buf[PROBE_BUF_SIZE];
 | 
			
		||||
    AVProbeData probe_data, *pd = &probe_data;
 | 
			
		||||
    offset_t pos;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    if (!fmt) {
 | 
			
		||||
        pd->filename = (char *)filename;
 | 
			
		||||
        pd->buf = buf;
 | 
			
		||||
        pos = url_ftell(pb);
 | 
			
		||||
        pd->buf_size = get_buffer(pb, buf, PROBE_BUF_SIZE);
 | 
			
		||||
        url_fseek(pb, pos, SEEK_SET);
 | 
			
		||||
        fmt = av_probe_image_format(pd);
 | 
			
		||||
    }
 | 
			
		||||
    if (!fmt)
 | 
			
		||||
        return AVERROR_NOFMT;
 | 
			
		||||
    ret = fmt->img_read(pb, alloc_cb, opaque);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Write an image to a stream.
 | 
			
		||||
 * @param pb byte stream for the image output
 | 
			
		||||
 * @param fmt image format
 | 
			
		||||
 * @param img image data and informations
 | 
			
		||||
 */
 | 
			
		||||
int av_write_image(ByteIOContext *pb, AVImageFormat *fmt, AVImageInfo *img)
 | 
			
		||||
{
 | 
			
		||||
    return fmt->img_write(pb, img);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										158
									
								
								libavformat/yuv.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								libavformat/yuv.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,158 @@
 | 
			
		||||
/*
 | 
			
		||||
 * .Y.U.V image format
 | 
			
		||||
 * Copyright (c) 2003 Fabrice Bellard.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
#include "avformat.h"
 | 
			
		||||
 | 
			
		||||
static int sizes[][2] = {
 | 
			
		||||
    { 640, 480 },
 | 
			
		||||
    { 720, 480 },
 | 
			
		||||
    { 720, 576 },
 | 
			
		||||
    { 352, 288 },
 | 
			
		||||
    { 352, 240 },
 | 
			
		||||
    { 160, 128 },
 | 
			
		||||
    { 512, 384 },
 | 
			
		||||
    { 640, 352 },
 | 
			
		||||
    { 640, 240 },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int infer_size(int *width_ptr, int *height_ptr, int size)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    for(i=0;i<sizeof(sizes)/sizeof(sizes[0]);i++) {
 | 
			
		||||
        if ((sizes[i][0] * sizes[i][1]) == size) {
 | 
			
		||||
            *width_ptr = sizes[i][0];
 | 
			
		||||
            *height_ptr = sizes[i][1];
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int yuv_read(ByteIOContext *f,
 | 
			
		||||
                    int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    ByteIOContext pb1, *pb = &pb1;
 | 
			
		||||
    int img_size, ret;
 | 
			
		||||
    char fname[1024], *p;
 | 
			
		||||
    int size;
 | 
			
		||||
    URLContext *h;
 | 
			
		||||
    AVImageInfo info1, *info = &info1;
 | 
			
		||||
    
 | 
			
		||||
    /* XXX: hack hack */
 | 
			
		||||
    h = url_fileno(f);
 | 
			
		||||
    img_size = url_seek(h, 0, SEEK_END);
 | 
			
		||||
    url_get_filename(h, fname, sizeof(fname));
 | 
			
		||||
 | 
			
		||||
    if (infer_size(&info->width, &info->height, img_size) < 0) {
 | 
			
		||||
        return -EIO;
 | 
			
		||||
    }
 | 
			
		||||
    info->pix_fmt = PIX_FMT_YUV420P;
 | 
			
		||||
    
 | 
			
		||||
    ret = alloc_cb(opaque, info);
 | 
			
		||||
    if (ret)
 | 
			
		||||
        return ret;
 | 
			
		||||
    
 | 
			
		||||
    size = info->width * info->height;
 | 
			
		||||
    
 | 
			
		||||
    p = strrchr(fname, '.');
 | 
			
		||||
    if (!p || p[1] != 'Y')
 | 
			
		||||
        return -EIO;
 | 
			
		||||
 | 
			
		||||
    get_buffer(f, info->pict.data[0], size);
 | 
			
		||||
    
 | 
			
		||||
    p[1] = 'U';
 | 
			
		||||
    if (url_fopen(pb, fname, URL_RDONLY) < 0)
 | 
			
		||||
        return -EIO;
 | 
			
		||||
 | 
			
		||||
    get_buffer(pb, info->pict.data[1], size / 4);
 | 
			
		||||
    url_fclose(pb);
 | 
			
		||||
    
 | 
			
		||||
    p[1] = 'V';
 | 
			
		||||
    if (url_fopen(pb, fname, URL_RDONLY) < 0)
 | 
			
		||||
        return -EIO;
 | 
			
		||||
 | 
			
		||||
    get_buffer(pb, info->pict.data[2], size / 4);
 | 
			
		||||
    url_fclose(pb);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int yuv_write(ByteIOContext *pb2, AVImageInfo *info)
 | 
			
		||||
{
 | 
			
		||||
    ByteIOContext pb1, *pb;
 | 
			
		||||
    char fname[1024], *p;
 | 
			
		||||
    int i, j, width, height;
 | 
			
		||||
    UINT8 *ptr;
 | 
			
		||||
    URLContext *h;
 | 
			
		||||
    static const char *ext = "YUV";
 | 
			
		||||
    
 | 
			
		||||
    /* XXX: hack hack */
 | 
			
		||||
    h = url_fileno(pb2);
 | 
			
		||||
    url_get_filename(h, fname, sizeof(fname));
 | 
			
		||||
 | 
			
		||||
    p = strrchr(fname, '.');
 | 
			
		||||
    if (!p || p[1] != 'Y')
 | 
			
		||||
        return -EIO;
 | 
			
		||||
 | 
			
		||||
    width = info->width;
 | 
			
		||||
    height = info->height;
 | 
			
		||||
 | 
			
		||||
    for(i=0;i<3;i++) {
 | 
			
		||||
        if (i == 1) {
 | 
			
		||||
            width >>= 1;
 | 
			
		||||
            height >>= 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (i >= 1) {
 | 
			
		||||
            pb = &pb1;
 | 
			
		||||
            p[1] = ext[i];
 | 
			
		||||
            if (url_fopen(pb, fname, URL_WRONLY) < 0)
 | 
			
		||||
                return -EIO;
 | 
			
		||||
        } else {
 | 
			
		||||
            pb = pb2;
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        ptr = info->pict.data[i];
 | 
			
		||||
        for(j=0;j<height;j++) {
 | 
			
		||||
            put_buffer(pb, ptr, width);
 | 
			
		||||
            ptr += info->pict.linesize[i];
 | 
			
		||||
        }
 | 
			
		||||
        put_flush_packet(pb);
 | 
			
		||||
        if (i >= 1) {
 | 
			
		||||
            url_fclose(pb);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
    
 | 
			
		||||
static int yuv_probe(AVProbeData *pd)
 | 
			
		||||
{
 | 
			
		||||
    if (match_ext(pd->filename, "Y"))
 | 
			
		||||
        return AVPROBE_SCORE_MAX;
 | 
			
		||||
    else
 | 
			
		||||
        return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AVImageFormat yuv_image_format = {
 | 
			
		||||
    "yuv",
 | 
			
		||||
    "Y",
 | 
			
		||||
    yuv_probe,
 | 
			
		||||
    yuv_read,
 | 
			
		||||
    (1 << PIX_FMT_YUV420P),
 | 
			
		||||
    yuv_write,
 | 
			
		||||
};
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user