Fawkes API  Fawkes Development Version
stereodecoder.cpp
00001 
00002 /***************************************************************************
00003  *  stereodecoder.cpp - Stereo decoder utility
00004  *
00005  *  Created: Wed Jul 11 15:50:10 2007 (Atlanta Airport)
00006  *  Copyright  2005-2007  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022 
00023 #include <fvcams/bumblebee2.h>
00024 #include <fvutils/writers/jpeg.h>
00025 #include <fvutils/readers/fvraw.h>
00026 #include <fvutils/color/conversions.h>
00027 
00028 #include <list>
00029 #include <string>
00030 #include <cstdlib>
00031 
00032 #include <sys/stat.h>
00033 #include <sys/types.h>
00034 #include <dirent.h>
00035 
00036 using namespace std;
00037 using namespace fawkes;
00038 using namespace firevision;
00039 
00040 /** Interleave to YUV422 planar buffers.
00041  * Creates an image buffer which has both images side by side.
00042  * @param yuv422_first first buffer
00043  * @param yuv
00044  * */
00045 void
00046 interleave_yuv422planar(unsigned char *yuv422_first, unsigned char *yuv422_second,
00047                         unsigned char *out,
00048                         unsigned int width, unsigned int height)
00049 {
00050   unsigned char *y1, *y2, *yo, *u1, *u2, *uo, *v1, *v2, *vo;
00051   unsigned int half_width = width / 2;
00052   y1 = yuv422_first;
00053   u1 = y1 + width * height;
00054   v1 = u1 + (width * height / 2);
00055   y2 = yuv422_second;
00056   u2 = y2 + width * height;
00057   v2 = u2 + (width * height / 2);
00058   yo = out;
00059   uo = yo + width * height * 2;
00060   vo = uo + width * height;
00061 
00062   for ( unsigned int i = 0; i < height; ++i) {
00063 
00064     memcpy(yo, y1, width);
00065     yo += width;
00066     y1 += width;
00067 
00068     memcpy(yo, y2, width);
00069     yo += width;
00070     y2 += width;
00071 
00072     memcpy(uo, u1, half_width);
00073     uo += half_width;
00074     u1 += half_width;
00075 
00076     memcpy(uo, u2, half_width);
00077     uo += half_width;
00078     u2 += half_width;
00079 
00080     memcpy(vo, v1, half_width);
00081     vo += half_width;
00082     v1 += half_width;
00083 
00084     memcpy(vo, v2, half_width);
00085     vo += half_width;
00086     v2 += half_width;
00087   }
00088 
00089   /*
00090   unsigned int half_width = width / 2;
00091   for ( unsigned int i = 0; i < height; ++i) {
00092     memcpy(out, yuv422_first, half_width);
00093     out += half_width;
00094     yuv422_first += half_width;
00095     memcpy(out, yuv422_first, half_width);
00096     out += half_width;
00097     yuv422_second += half_width;
00098   }
00099   for ( unsigned int i = 0; i < height; ++i) {
00100     memcpy(out, yuv422_first, half_width);
00101     out += half_width;
00102     yuv422_first += half_width;
00103     memcpy(out, yuv422_first, half_width);
00104     out += half_width;
00105     yuv422_second += half_width;
00106   }
00107   */
00108 }
00109 
00110 int
00111 main(int argc, char **argv)
00112 {
00113 
00114   if ( argc < 2 ) {
00115     printf("Usage: %s <dir>\n", argv[0]);
00116     exit(-1);
00117   }
00118 
00119   string dirname = argv[1];
00120 
00121   // Get all files
00122   DIR *dir;
00123   struct dirent *dirp;
00124 
00125   list<string> files;
00126 
00127   if ( NULL == (dir = opendir(dirname.c_str())) ) {
00128     printf("Failed to open directory %s\n", dirname.c_str());
00129     exit(-2);
00130   }
00131 
00132   while ( NULL != (dirp = readdir(dir)) ) {
00133     if ( NULL != strstr(dirp->d_name, ".raw") ) {
00134       files.push_back(dirp->d_name);
00135     }
00136   }
00137 
00138   closedir(dir);
00139 
00140   files.sort();
00141 
00142   /*
00143   // create directories
00144   char *tmp;
00145   asprintf(&tmp, "%s/%s", dirname.c_str(), "orig_jpeg");
00146   mkdir(tmp, 0644);
00147   free(tmp);
00148 
00149   // create directories
00150   asprintf(&tmp, "%s/%s", dirname.c_str(), "disp_jpeg");
00151   mkdir(tmp, 0644);
00152   free(tmp);
00153   */
00154 
00155   JpegWriter *jpeg = new JpegWriter("tmp.jpg");
00156 
00157   // printf("%lu images to convert\n", files.size());
00158 
00159   unsigned int in = 0;
00160   try {
00161     for (list<string>::iterator f = files.begin(); f != files.end(); ++f) {
00162       FvRawReader *fvraw = new FvRawReader((dirname + "/" + (*f)).c_str());
00163       printf("%4u Converting %s (%s)  ", ++in, (dirname + "/" + (*f)).c_str(), colorspace_to_string(fvraw->colorspace()));
00164       unsigned char *raw16 = malloc_buffer(fvraw->colorspace(), fvraw->pixel_width(), fvraw->pixel_height() * 2);
00165       unsigned char *rgb = (unsigned char *)malloc(colorspace_buffer_size(RGB, fvraw->pixel_width(), fvraw->pixel_height()) * 2);
00166       unsigned char *deinterlaced = (unsigned char *)malloc(fvraw->pixel_width() * fvraw->pixel_height() * 2);
00167       unsigned char *yuv = (unsigned char *)malloc_buffer(YUV422_PLANAR, fvraw->pixel_width(), fvraw->pixel_height() * 2);
00168       unsigned char *yuv_interleaved = (unsigned char *)malloc_buffer(YUV422_PLANAR, fvraw->pixel_width(), fvraw->pixel_height() * 2);
00169       fvraw->set_buffer(raw16);
00170       fvraw->read();
00171 
00172       printf("(%ux%u)   ", fvraw->pixel_width(), fvraw->pixel_height());
00173 
00174       Bumblebee2Camera::deinterlace_stereo(raw16, deinterlaced,
00175                                            fvraw->pixel_width(), fvraw->pixel_height());
00176       Bumblebee2Camera::decode_bayer(deinterlaced, rgb,
00177                                      fvraw->pixel_width(), fvraw->pixel_height(),
00178                                      BAYER_PATTERN_BGGR);
00179       /*
00180       convert(RGB, YUV422_PLANAR,
00181               rgb + colorspace_buffer_size(RGB, fvraw->pixel_width(), fvraw->pixel_height()),
00182               yuv + colorspace_buffer_size(YUV422_PLANAR, fvraw->pixel_width(), fvraw->pixel_height()),
00183               fvraw->pixel_width(), fvraw->pixel_height());
00184       */
00185       convert(RGB, YUV422_PLANAR,
00186               rgb,
00187               yuv,
00188               fvraw->pixel_width(), fvraw->pixel_height());
00189 
00190       convert(RGB, YUV422_PLANAR,
00191               rgb + colorspace_buffer_size(RGB, fvraw->pixel_width(), fvraw->pixel_height()),
00192               yuv + colorspace_buffer_size(YUV422_PLANAR, fvraw->pixel_width(), fvraw->pixel_height()),
00193               fvraw->pixel_width(), fvraw->pixel_height());
00194 
00195       interleave_yuv422planar(yuv + colorspace_buffer_size(YUV422_PLANAR, fvraw->pixel_width(), fvraw->pixel_height()),
00196                               yuv, yuv_interleaved, fvraw->pixel_width(), fvraw->pixel_height());
00197 
00198       *f += ".jpg";
00199       printf("to %s\n", (dirname + "/orig_jpeg/" + (*f)).c_str());
00200 
00201       jpeg->set_filename((dirname + "/orig_jpeg/" + (*f)).c_str());
00202       jpeg->set_buffer(YUV422_PLANAR, yuv_interleaved);
00203       // jpeg->set_buffer(YUV422_PLANAR, yuv);
00204       jpeg->set_dimensions(fvraw->pixel_width() * 2, fvraw->pixel_height());
00205       jpeg->write();
00206 
00207       delete fvraw;
00208       free(raw16);
00209       free(rgb);
00210       free(deinterlaced);
00211       free(yuv);
00212       free(yuv_interleaved);
00213     }
00214   } catch (Exception &e) {
00215     e.print_trace();
00216     throw;
00217   }
00218 }