Statistics
| Branch: | Revision:

ffmpeg / libavformat / yuv.c @ 7be806f3

History | View | Annotate | Download (3.73 KB)

1 87a0a681 Fabrice Bellard
/*
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 0bd586c5 Mike Melanson
        return AVERROR_IO;
64 87a0a681 Fabrice Bellard
    }
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 0bd586c5 Mike Melanson
        return AVERROR_IO;
76 87a0a681 Fabrice Bellard
77
    get_buffer(f, info->pict.data[0], size);
78
    
79
    p[1] = 'U';
80
    if (url_fopen(pb, fname, URL_RDONLY) < 0)
81 0bd586c5 Mike Melanson
        return AVERROR_IO;
82 87a0a681 Fabrice Bellard
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 0bd586c5 Mike Melanson
        return AVERROR_IO;
89 87a0a681 Fabrice Bellard
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 0c1a9eda Zdenek Kabelac
    uint8_t *ptr;
101 87a0a681 Fabrice Bellard
    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 0bd586c5 Mike Melanson
        return AVERROR_IO;
111 87a0a681 Fabrice Bellard
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 0bd586c5 Mike Melanson
                return AVERROR_IO;
126 87a0a681 Fabrice Bellard
        } 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
};