root/tools/yuvconvert.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. usage
  2. clip
  3. yuv_to_rgb
  4. main

   1 /*
   2 A small tools to convert/debug CHDK live view dumps.
   3 
   4 REVISIONS:
   5 1. Initial release. Author: reyalP (04-Jul-2010)
   6 
   7 code 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 
  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 < 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 

/* [<][>][^][v][top][bottom][index][help] */