This source file includes following definitions.
- usage
- clip
- yuv_to_rgb
- main
1
2
3
4
5
6
7
8
9 #include <stdio.h>
10 #include <stdint.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <sys/stat.h>
14 #include <assert.h>
15
16
17 void usage()
18 {
19 fprintf(stderr,"Usage: -w=<width> -h=<height> [-split] [-rgb] [-skipy] <infile> <outbasename>\n");
20 fprintf(stderr,"infile: dump of live viewport data, assumed UYVYYY with 8 bit elements.\n"
21 "outbasename: base name to use for various output files\n"
22 "-w=,-h=\n"
23 " real width and height of input. Width is by counting Y values.\n"
24 "-rgb:\n"
25 " Output packed 24 bit RGB outbasename-<output width>.RGB\n"
26 "-skipy:\n"
27 " skip 50%% of Y values in each row when making RGB\n"
28 " to give correct aspect ratio on older cameras\n"
29 "-split:\n"
30 " produces outbasename.Y outbasename.U and outbasename.V as 8 bit greyscale\n"
31 " .Y will be full resolution, .U and .V will be 1/4 width of Y\n");
32 exit(1);
33 }
34
35 static uint8_t clip(int v) {
36 if (v<0) return 0;
37 if (v>255) return 255;
38 return v;
39 }
40
41 void yuv_to_rgb(uint8_t **dest, uint8_t y, int8_t u, int8_t v)
42 {
43 *((*dest)++) = clip(((y<<12) + v*5743 + 2048)>>12);
44 *((*dest)++) = clip(((y<<12) - u*1411 - v*2925 + 2048)>>12);
45 *((*dest)++) = clip(((y<<12) + u*7258 + 2048)>>12);
46 }
47
48 int main(int argc, char**argv)
49 {
50 int8_t *in_data;
51 uint8_t *out_data;
52 uint8_t *prgb_data;
53 int8_t *y_data,*py_data;
54 int8_t *u_data,*pu_data;
55 int8_t *v_data,*pv_data;
56 FILE *fp;
57 char *iname=NULL;
58 char *oname=NULL;
59
60 unsigned height=0;
61 unsigned width=0;
62 unsigned npixels;
63 unsigned isize;
64 unsigned osize;
65
66 unsigned split_yuv=0;
67 unsigned skipy=0;
68 unsigned rgb=0;
69
70 struct stat st;
71
72 size_t rcount;
73
74 unsigned i;
75
76 for(i = 1; i < (unsigned)argc; i++) {
77 if ( strncmp(argv[i],"-h=",3) == 0 ) {
78 height=atoi(argv[i]+3);
79 }
80 else if ( strncmp(argv[i],"-w=",3) == 0 ) {
81 width=atoi(argv[i]+3);
82 }
83 else if( strcmp(argv[i],"-split") == 0 ) {
84 split_yuv=1;
85 }
86 else if( strcmp(argv[i],"-skipy") == 0 ) {
87 skipy=1;
88 }
89 else if( strcmp(argv[i],"-rgb") == 0 ) {
90 rgb=1;
91 }
92 else {
93 if(!iname) {
94 iname=argv[i];
95 }
96 else if (!oname) {
97 oname=argv[i];
98 }
99 else {
100 fprintf(stderr,"%s: unknown option %s\n",argv[0],argv[i]);
101 usage();
102 }
103 }
104 }
105 if(!iname) {
106 fprintf(stderr,"%s: missing input file\n",argv[0]);
107 usage();
108 }
109 if(!oname) {
110 fprintf(stderr,"%s: missing output file\n",argv[0]);
111 usage();
112 }
113 if(!height || !width) {
114 fprintf(stderr,"%s: invalid dimensions\n",argv[0]);
115 usage();
116 }
117
118 if(stat(iname,&st) != 0) {
119 fprintf(stderr,"%s: bad input file %s\n",argv[0],iname);
120 exit(1);
121 }
122
123 if((width*12)%8 != 0) {
124 fprintf(stderr,"WARNING: width %u not an integral number of bytes at 12 bpp\n",width);
125 }
126
127
128 npixels=height*width;
129 isize = (npixels*12)/8;
130 if(isize > st.st_size) {
131 fprintf(stderr,"%s: ERROR: dimensions too large for input file (%u*%u*12)/8=%u > %lu\n",
132 argv[0],width,height,isize,(unsigned long)st.st_size);
133 exit(1);
134 } else if ( isize < st.st_size) {
135 fprintf(stderr,"%s: WARNING: dimensions smaller than input file (%u*%u*12)/8=%u < %lu\n",
136 argv[0],width,height,isize,(unsigned long)st.st_size);
137 }
138
139 if(!rgb && !split_yuv) {
140 fprintf(stderr,"nothing to do!\n");
141 usage();
142 return 0;
143 }
144
145 in_data=malloc(isize);
146 assert(in_data);
147
148 fp=fopen(iname,"rb");
149 assert(fp);
150
151 rcount=fread(in_data,1,isize,fp);
152 assert(rcount==isize);
153
154 fclose(fp);
155
156 fprintf(stderr,"input: %s %ux%u UYVYYY %u bytes\n",iname, width, height, isize);
157
158 if(split_yuv) {
159 fprintf(stderr,"output: %s.Y %ux%u %s.U,V %ux%u\n", oname, width, height,oname,width/4,height);
160 char splitname[256];
161 py_data = y_data=malloc(npixels);
162 assert(y_data);
163 pu_data = u_data=malloc(npixels/4);
164 assert(u_data);
165 pv_data = v_data=malloc(npixels/4);
166 assert(v_data);
167 for (i=0;i<isize; i+=6) {
168 *py_data++ = in_data[i+1];
169 *py_data++ = in_data[i+3];
170 *py_data++ = in_data[i+4];
171 *py_data++ = in_data[i+5];
172 *pu_data++ = in_data[i];
173 *pv_data++ = in_data[i+2];
174
175 }
176 sprintf(splitname,"%s.Y",oname);
177 fp=fopen(splitname,"wb");
178 assert(fp);
179 fwrite(y_data, 1, npixels, fp);
180 fclose(fp);
181 free(y_data);
182
183 sprintf(splitname,"%s.U",oname);
184 fp=fopen(splitname,"wb");
185 assert(fp);
186 fwrite(u_data, 1, npixels/4, fp);
187 fclose(fp);
188 free(u_data);
189
190 sprintf(splitname,"%s.V",oname);
191 fp=fopen(splitname,"wb");
192 assert(fp);
193 fwrite(v_data, 1, npixels/4, fp);
194 fclose(fp);
195 free(v_data);
196 }
197 if (rgb) {
198 unsigned owidth;
199 uint8_t *p_yuv;
200 char rgbname[256];
201
202 if(skipy) {
203 owidth = width/2;
204 } else {
205 owidth = width;
206 }
207 osize = (owidth*height)*3;
208 out_data=malloc(osize);
209 assert(out_data);
210
211 prgb_data = out_data;
212 p_yuv = (uint8_t*)in_data;
213
214 sprintf(rgbname,"%s-%d.RGB",oname,owidth);
215
216 fprintf(stderr,"output: %s %ux%u RGB8 %u bytes\n", rgbname, owidth, height, osize);
217
218 for (i=0;i<npixels; i+=4, p_yuv+=6) {
219 yuv_to_rgb(&prgb_data,p_yuv[1],p_yuv[0],p_yuv[2]);
220 yuv_to_rgb(&prgb_data,p_yuv[3],p_yuv[0],p_yuv[2]);
221 if(skipy)
222 continue;
223 yuv_to_rgb(&prgb_data,p_yuv[4],p_yuv[0],p_yuv[2]);
224 yuv_to_rgb(&prgb_data,p_yuv[5],p_yuv[0],p_yuv[2]);
225 }
226
227 fp=fopen(rgbname,"wb");
228 assert(fp);
229 fwrite(out_data, 1, osize, fp);
230 fclose(fp);
231
232 free(in_data);
233 free(out_data);
234 fprintf(stderr,"done\n");
235 }
236 return 0;
237 }
238