~ubuntu-branches/debian/wheezy/vlc/wheezy

« back to all changes in this revision

Viewing changes to extras/ffmpeg/libavformat/yuv.c

Tags: upstream-0.7.2.final
ImportĀ upstreamĀ versionĀ 0.7.2.final

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * .Y.U.V image format
 
3
 * Copyright (c) 2003 Fabrice Bellard.
 
4
 *
 
5
 * This library is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU Lesser General Public
 
7
 * License as published by the Free Software Foundation; either
 
8
 * version 2 of the License, or (at your option) any later version.
 
9
 *
 
10
 * This library is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * Lesser General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU Lesser General Public
 
16
 * License along with this library; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 */
 
19
#include "avformat.h"
 
20
 
 
21
static int sizes[][2] = {
 
22
    { 640, 480 },
 
23
    { 720, 480 },
 
24
    { 720, 576 },
 
25
    { 352, 288 },
 
26
    { 352, 240 },
 
27
    { 160, 128 },
 
28
    { 512, 384 },
 
29
    { 640, 352 },
 
30
    { 640, 240 },
 
31
};
 
32
 
 
33
static int infer_size(int *width_ptr, int *height_ptr, int size)
 
34
{
 
35
    int i;
 
36
 
 
37
    for(i=0;i<sizeof(sizes)/sizeof(sizes[0]);i++) {
 
38
        if ((sizes[i][0] * sizes[i][1]) == size) {
 
39
            *width_ptr = sizes[i][0];
 
40
            *height_ptr = sizes[i][1];
 
41
            return 0;
 
42
        }
 
43
    }
 
44
    return -1;
 
45
}
 
46
 
 
47
static int yuv_read(ByteIOContext *f,
 
48
                    int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque)
 
49
{
 
50
    ByteIOContext pb1, *pb = &pb1;
 
51
    int img_size, ret;
 
52
    char fname[1024], *p;
 
53
    int size;
 
54
    URLContext *h;
 
55
    AVImageInfo info1, *info = &info1;
 
56
    
 
57
    /* XXX: hack hack */
 
58
    h = url_fileno(f);
 
59
    img_size = url_seek(h, 0, SEEK_END);
 
60
    url_get_filename(h, fname, sizeof(fname));
 
61
 
 
62
    if (infer_size(&info->width, &info->height, img_size) < 0) {
 
63
        return -EIO;
 
64
    }
 
65
    info->pix_fmt = PIX_FMT_YUV420P;
 
66
    
 
67
    ret = alloc_cb(opaque, info);
 
68
    if (ret)
 
69
        return ret;
 
70
    
 
71
    size = info->width * info->height;
 
72
    
 
73
    p = strrchr(fname, '.');
 
74
    if (!p || p[1] != 'Y')
 
75
        return -EIO;
 
76
 
 
77
    get_buffer(f, info->pict.data[0], size);
 
78
    
 
79
    p[1] = 'U';
 
80
    if (url_fopen(pb, fname, URL_RDONLY) < 0)
 
81
        return -EIO;
 
82
 
 
83
    get_buffer(pb, info->pict.data[1], size / 4);
 
84
    url_fclose(pb);
 
85
    
 
86
    p[1] = 'V';
 
87
    if (url_fopen(pb, fname, URL_RDONLY) < 0)
 
88
        return -EIO;
 
89
 
 
90
    get_buffer(pb, info->pict.data[2], size / 4);
 
91
    url_fclose(pb);
 
92
    return 0;
 
93
}
 
94
 
 
95
static int yuv_write(ByteIOContext *pb2, AVImageInfo *info)
 
96
{
 
97
    ByteIOContext pb1, *pb;
 
98
    char fname[1024], *p;
 
99
    int i, j, width, height;
 
100
    uint8_t *ptr;
 
101
    URLContext *h;
 
102
    static const char *ext = "YUV";
 
103
    
 
104
    /* XXX: hack hack */
 
105
    h = url_fileno(pb2);
 
106
    url_get_filename(h, fname, sizeof(fname));
 
107
 
 
108
    p = strrchr(fname, '.');
 
109
    if (!p || p[1] != 'Y')
 
110
        return -EIO;
 
111
 
 
112
    width = info->width;
 
113
    height = info->height;
 
114
 
 
115
    for(i=0;i<3;i++) {
 
116
        if (i == 1) {
 
117
            width >>= 1;
 
118
            height >>= 1;
 
119
        }
 
120
 
 
121
        if (i >= 1) {
 
122
            pb = &pb1;
 
123
            p[1] = ext[i];
 
124
            if (url_fopen(pb, fname, URL_WRONLY) < 0)
 
125
                return -EIO;
 
126
        } else {
 
127
            pb = pb2;
 
128
        }
 
129
    
 
130
        ptr = info->pict.data[i];
 
131
        for(j=0;j<height;j++) {
 
132
            put_buffer(pb, ptr, width);
 
133
            ptr += info->pict.linesize[i];
 
134
        }
 
135
        put_flush_packet(pb);
 
136
        if (i >= 1) {
 
137
            url_fclose(pb);
 
138
        }
 
139
    }
 
140
    return 0;
 
141
}
 
142
    
 
143
static int yuv_probe(AVProbeData *pd)
 
144
{
 
145
    if (match_ext(pd->filename, "Y"))
 
146
        return AVPROBE_SCORE_MAX;
 
147
    else
 
148
        return 0;
 
149
}
 
150
 
 
151
AVImageFormat yuv_image_format = {
 
152
    "yuv",
 
153
    "Y",
 
154
    yuv_probe,
 
155
    yuv_read,
 
156
    (1 << PIX_FMT_YUV420P),
 
157
    yuv_write,
 
158
};