2 * Generates a synthetic YUV video sequence suitable for codec testing.
4 * rotozoom.c -> s.bechet@av7.net
11 #define ONE_HALF (1 << (SCALEBITS - 1))
12 #define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5))
13 typedef unsigned char UINT8;
15 static void rgb24_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
16 UINT8 *src, int width, int height)
18 int wrap, wrap3, x, y;
19 int r, g, b, r1, g1, b1;
25 for(y=0;y<height;y+=2) {
26 for(x=0;x<width;x+=2) {
33 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
34 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
41 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
42 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
52 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
53 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
60 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
61 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
63 cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
64 FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
65 cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
66 FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
79 #define DEFAULT_WIDTH 352
80 #define DEFAULT_HEIGHT 288
81 #define DEFAULT_NB_PICT 360
83 void pgmyuv_save(const char *filename, int w, int h,
84 unsigned char *rgb_tab)
88 unsigned char *cb, *cr;
89 unsigned char *lum_tab, *cb_tab, *cr_tab;
91 lum_tab = malloc(w * h);
92 cb_tab = malloc((w * h) / 4);
93 cr_tab = malloc((w * h) / 4);
95 rgb24_to_yuv420p(lum_tab, cb_tab, cr_tab, rgb_tab, w, h);
97 f = fopen(filename,"w");
98 fprintf(f, "P5\n%d %d\n%d\n", w, (h * 3) / 2, 255);
99 fwrite(lum_tab, 1, w * h, f);
105 fwrite(cb, 1, w2, f);
106 fwrite(cr, 1, w2, f);
117 unsigned char *rgb_tab;
118 int width, height, wrap;
120 void put_pixel(int x, int y, int r, int g, int b)
124 if (x < 0 || x >= width ||
125 y < 0 || y >= height)
128 p = rgb_tab + y * wrap + x * 3;
134 unsigned char tab_r[256*256];
135 unsigned char tab_g[256*256];
136 unsigned char tab_b[256*256];
142 void gen_image(int num, int w, int h)
144 const int c = h_cos [teta];
145 const int s = h_sin [teta];
147 const int xi = -(w/2) * c;
148 const int yi = (w/2) * s;
150 const int xj = -(h/2) * s;
151 const int yj = -(h/2) * c;
169 for ( i=0 ; i<w ; i++ ) {
172 dep = ((x>>8)&255) + (y&(255<<8));
173 put_pixel(i, j, tab_r[dep], tab_g[dep], tab_b[dep]);
176 teta = (teta+1) % 360;
188 fichier = fopen("rotozoom-ffmpeg.pnm","r");
189 fread(line, 1, 15, fichier);
190 for (i=0;i<128;i++) {
191 fread(line,1,3*128,fichier);
192 for (j=0;j<128;j++) {
193 tab_r[256*i+j] = line[3*j ];
194 tab_g[256*i+j] = line[3*j + 1];
195 tab_b[256*i+j] = line[3*j + 2];
197 memcpy(tab_r + 257*128 + i*256, tab_r + i*256, 128);
198 memcpy(tab_g + 257*128 + i*256, tab_g + i*256, 128);
199 memcpy(tab_b + 257*128 + i*256, tab_b + i*256, 128);
203 fichier = fopen("rotozoom-tux.pnm","r");
204 fread(line, 1, 15, fichier);
205 for (i=0;i<128;i++) {
206 fread(line,1,3*128,fichier);
207 for (j=0;j<128;j++) {
208 tab_r[128 + 256*i+j] = line[3*j ];
209 tab_g[128 + 256*i+j] = line[3*j + 1];
210 tab_b[128 + 256*i+j] = line[3*j + 2];
212 memcpy(tab_r + 256*128 + i*256, tab_r + 128 + i*256, 128);
213 memcpy(tab_g + 256*128 + i*256, tab_g + 128 + i*256, 128);
214 memcpy(tab_b + 256*128 + i*256, tab_b + 128 + i*256, 128);
221 for (i=0;i<360;i++) {
222 radian = 2*i*M_PI/360;
223 h = 2 + cos (radian);
224 h_cos[i] = 256 * ( h * cos (radian) );
225 h_sin[i] = 256 * ( h * sin (radian) );
229 int main(int argc, char **argv)
235 printf("usage: %s directory/\n"
236 "generate a test video stream\n", argv[0]);
243 rgb_tab = malloc(w * h * 3);
250 for(i=0;i<DEFAULT_NB_PICT;i++) {
251 snprintf(buf, sizeof(buf), "%s%03d.pgm", argv[1], i);
253 pgmyuv_save(buf, w, h, rgb_tab);