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
 | 
					# mux and demuxes
 | 
				
			||||||
OBJS+=mpeg.o mpegts.o ffm.o crc.o img.o raw.o rm.o asf.o \
 | 
					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
 | 
					# file I/O
 | 
				
			||||||
OBJS+= avio.o aviobuf.o file.o 
 | 
					OBJS+= avio.o aviobuf.o file.o 
 | 
				
			||||||
 | 
					OBJS+= framehook.o 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq ($(BUILD_STRPTIME),yes)
 | 
					ifeq ($(BUILD_STRPTIME),yes)
 | 
				
			||||||
OBJS+= strptime.o
 | 
					OBJS+= strptime.o
 | 
				
			||||||
 | 
				
			|||||||
@ -45,6 +45,8 @@ void av_register_all(void)
 | 
				
			|||||||
    mov_init();
 | 
					    mov_init();
 | 
				
			||||||
    jpeg_init();
 | 
					    jpeg_init();
 | 
				
			||||||
    dv_init();
 | 
					    dv_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    av_register_output_format(&yuv4mpegpipe_oformat);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
#ifdef CONFIG_VORBIS
 | 
					#ifdef CONFIG_VORBIS
 | 
				
			||||||
    ogg_init();
 | 
					    ogg_init();
 | 
				
			||||||
@ -60,6 +62,14 @@ void av_register_all(void)
 | 
				
			|||||||
    audio_init();
 | 
					    audio_init();
 | 
				
			||||||
#endif
 | 
					#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 */
 | 
					    /* file protocols */
 | 
				
			||||||
    register_protocol(&file_protocol);
 | 
					    register_protocol(&file_protocol);
 | 
				
			||||||
    register_protocol(&pipe_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;
 | 
					AVInputFormat *first_iformat;
 | 
				
			||||||
AVOutputFormat *first_oformat;
 | 
					AVOutputFormat *first_oformat;
 | 
				
			||||||
 | 
					AVImageFormat *first_image_format;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void av_register_input_format(AVInputFormat *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;
 | 
					    AVOutputFormat *fmt, *fmt_found;
 | 
				
			||||||
    int score_max, score;
 | 
					    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 */
 | 
					    /* find the proper file type */
 | 
				
			||||||
    fmt_found = NULL;
 | 
					    fmt_found = NULL;
 | 
				
			||||||
    score_max = 0;
 | 
					    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);
 | 
					        fmt = av_probe_input_format(pd, 0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* if no file needed do not try to open one */
 | 
					 | 
				
			||||||
    if (!fmt || !(fmt->flags & AVFMT_NOFILE)) {
 | 
					    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) {
 | 
					        if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0) {
 | 
				
			||||||
            err = AVERROR_IO;
 | 
					            err = AVERROR_IO;
 | 
				
			||||||
            goto fail;
 | 
					            goto fail;
 | 
				
			||||||
@ -365,6 +371,14 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    ic->iformat = fmt;
 | 
					    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 */
 | 
					    /* allocate private data */
 | 
				
			||||||
    ic->priv_data = av_mallocz(fmt->priv_data_size);
 | 
					    ic->priv_data = av_mallocz(fmt->priv_data_size);
 | 
				
			||||||
    if (!ic->priv_data) {
 | 
					    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 */
 | 
					    /* default pts settings is MPEG like */
 | 
				
			||||||
    av_set_pts_info(ic, 33, 1, 90000);
 | 
					    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);
 | 
					    err = ic->iformat->read_header(ic, ap);
 | 
				
			||||||
    if (err < 0)
 | 
					    if (err < 0)
 | 
				
			||||||
        goto fail1;
 | 
					        goto fail1;
 | 
				
			||||||
@ -707,6 +713,21 @@ AVStream *av_new_stream(AVFormatContext *s, int id)
 | 
				
			|||||||
/************************************************************/
 | 
					/************************************************************/
 | 
				
			||||||
/* output media file */
 | 
					/* 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
 | 
					 * allocate the stream private data and write the stream header to an
 | 
				
			||||||
 * output media file
 | 
					 * output media file
 | 
				
			||||||
@ -719,9 +740,6 @@ int av_write_header(AVFormatContext *s)
 | 
				
			|||||||
    int ret, i;
 | 
					    int ret, i;
 | 
				
			||||||
    AVStream *st;
 | 
					    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 */
 | 
					    /* default pts settings is MPEG like */
 | 
				
			||||||
    av_set_pts_info(s, 33, 1, 90000);
 | 
					    av_set_pts_info(s, 33, 1, 90000);
 | 
				
			||||||
    ret = s->oformat->write_header(s);
 | 
					    ret = s->oformat->write_header(s);
 | 
				
			||||||
@ -1291,3 +1309,88 @@ void av_frac_add(AVFrac *f, INT64 incr)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    f->num = num;
 | 
					    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