utils.c
Go to the documentation of this file.
1 /*
2  * This file is part of Libav.
3  *
4  * Libav is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * Libav is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with Libav; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include <errno.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #define SCALEBITS 8
25 #define ONE_HALF (1 << (SCALEBITS - 1))
26 #define FIX(x) ((int) ((x) * (1L << SCALEBITS) + 0.5))
27 
28 #define err_if(expr) do { \
29  if (expr) { \
30  fprintf(stderr, "%s\n", strerror(errno)); \
31  exit(1); \
32  } \
33 } while (0)
34 
35 static void rgb24_to_yuv420p(unsigned char *lum, unsigned char *cb,
36  unsigned char *cr, unsigned char *src,
37  int width, int height)
38 {
39  int wrap, wrap3, x, y;
40  int r, g, b, r1, g1, b1;
41  unsigned char *p;
42 
43  wrap = width;
44  wrap3 = width * 3;
45  p = src;
46  for (y = 0; y < height; y += 2) {
47  for (x = 0; x < width; x += 2) {
48  r = p[0];
49  g = p[1];
50  b = p[2];
51  r1 = r;
52  g1 = g;
53  b1 = b;
54  lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
55  FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
56  r = p[3];
57  g = p[4];
58  b = p[5];
59  r1 += r;
60  g1 += g;
61  b1 += b;
62  lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
63  FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
64  p += wrap3;
65  lum += wrap;
66 
67  r = p[0];
68  g = p[1];
69  b = p[2];
70  r1 += r;
71  g1 += g;
72  b1 += b;
73  lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
74  FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
75  r = p[3];
76  g = p[4];
77  b = p[5];
78  r1 += r;
79  g1 += g;
80  b1 += b;
81  lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
82  FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
83 
84  cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
85  FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
86  cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
87  FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
88 
89  cb++;
90  cr++;
91  p += -wrap3 + 2 * 3;
92  lum += -wrap + 2;
93  }
94  p += wrap3;
95  lum += wrap;
96  }
97 }
98 
99 /* cif format */
100 #define DEFAULT_WIDTH 352
101 #define DEFAULT_HEIGHT 288
102 #define DEFAULT_NB_PICT 50
103 
104 static void pgmyuv_save(const char *filename, int w, int h,
105  unsigned char *rgb_tab)
106 {
107  FILE *f;
108  int i, h2, w2;
109  unsigned char *cb, *cr;
110  unsigned char *lum_tab, *cb_tab, *cr_tab;
111 
112  lum_tab = malloc(w * h);
113  cb_tab = malloc(w * h / 4);
114  cr_tab = malloc(w * h / 4);
115 
116  rgb24_to_yuv420p(lum_tab, cb_tab, cr_tab, rgb_tab, w, h);
117 
118  if (filename) {
119  f = fopen(filename, "wb");
120  fprintf(f, "P5\n%d %d\n%d\n", w, h * 3 / 2, 255);
121  } else {
122  f = stdout;
123  }
124 
125  err_if(fwrite(lum_tab, 1, w * h, f) != w * h);
126  h2 = h / 2;
127  w2 = w / 2;
128  cb = cb_tab;
129  cr = cr_tab;
130 
131  if (filename) {
132  for (i = 0; i < h2; i++) {
133  err_if(fwrite(cb, 1, w2, f) != w2);
134  err_if(fwrite(cr, 1, w2, f) != w2);
135  cb += w2;
136  cr += w2;
137  }
138  fclose(f);
139  } else {
140  for (i = 0; i < h2; i++) {
141  err_if(fwrite(cb, 1, w2, f) != w2);
142  cb += w2;
143  }
144  for (i = 0; i < h2; i++) {
145  err_if(fwrite(cr, 1, w2, f) != w2);
146  cr += w2;
147  }
148  }
149 
150  free(lum_tab);
151  free(cb_tab);
152  free(cr_tab);
153 }
154 
155 static unsigned char *rgb_tab;
156 static int width, height, wrap;
157 
158 static void put_pixel(int x, int y, int r, int g, int b)
159 {
160  unsigned char *p;
161 
162  if (x < 0 || x >= width ||
163  y < 0 || y >= height)
164  return;
165 
166  p = rgb_tab + y * wrap + x * 3;
167  p[0] = r;
168  p[1] = g;
169  p[2] = b;
170 }
#define FIX(x)
Definition: utils.c:26
static void put_pixel(int x, int y, int r, int g, int b)
Definition: utils.c:158
static void rgb24_to_yuv420p(unsigned char *lum, unsigned char *cb, unsigned char *cr, unsigned char *src, int width, int height)
Definition: utils.c:35
static unsigned char * rgb_tab
Definition: utils.c:155
#define b
Definition: input.c:52
#define err_if(expr)
Definition: utils.c:28
#define r
Definition: input.c:51
g
Definition: yuv2rgb.c:540
static void pgmyuv_save(const char *filename, int w, int h, unsigned char *rgb_tab)
Definition: utils.c:104
static int wrap
Definition: utils.c:156
static int width
Definition: utils.c:156
#define ONE_HALF
Definition: utils.c:25
#define SCALEBITS
Definition: utils.c:24
static int height
Definition: utils.c:156