source: trunk/tools/yuvconvert.c @ 3421

Revision 909, 5.3 KB checked in by reyalp, 4 years ago (diff)

add yuvconvert tool, converts live view dumps to RGB or individual channels. See source for usage.

  • Property svn:eol-style set to native
Line 
1/*
2A small tools to convert/debug CHDK live view dumps.
3
4REVISIONS:
51. Initial release. Author: reyalP (04-Jul-2010)
6
7code borrowed from motion_detector.c, rawconvert.c and ewavrs ptpcam
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
17void 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
35static uint8_t clip(int v) {
36        if (v<0) return 0;
37        if (v>255) return 255;
38        return v;
39}
40
41void 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
48int 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 < 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,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,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 = 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
Note: See TracBrowser for help on using the repository browser.