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 <cams/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 
00039 /** Interleave to YUV422 planar buffers.
00040  * Creates an image buffer which has both images side by side.
00041  * @param yuv422_first first buffer
00042  * @param yuv
00043  * */
00044 void
00045 interleave_yuv422planar(unsigned char *yuv422_first, unsigned char *yuv422_second,
00046                         unsigned char *out,
00047                         unsigned int width, unsigned int height)
00048 {
00049   unsigned char *y1, *y2, *yo, *u1, *u2, *uo, *v1, *v2, *vo;
00050   unsigned int half_width = width / 2;
00051   y1 = yuv422_first;
00052   u1 = y1 + width * height;
00053   v1 = u1 + (width * height / 2);
00054   y2 = yuv422_second;
00055   u2 = y2 + width * height;
00056   v2 = u2 + (width * height / 2);
00057   yo = out;
00058   uo = yo + width * height * 2;
00059   vo = uo + width * height;
00060
00061   for ( unsigned int i = 0; i < height; ++i) {
00062
00063     memcpy(yo, y1, width);
00064     yo += width;
00065     y1 += width;
00066
00067     memcpy(yo, y2, width);
00068     yo += width;
00069     y2 += width;
00070
00071     memcpy(uo, u1, half_width);
00072     uo += half_width;
00073     u1 += half_width;
00074
00075     memcpy(uo, u2, half_width);
00076     uo += half_width;
00077     u2 += half_width;
00078
00079     memcpy(vo, v1, half_width);
00080     vo += half_width;
00081     v1 += half_width;
00082
00083     memcpy(vo, v2, half_width);
00084     vo += half_width;
00085     v2 += half_width;
00086   }
00087
00088   /*
00089   unsigned int half_width = width / 2;
00090   for ( unsigned int i = 0; i < height; ++i) {
00091     memcpy(out, yuv422_first, half_width);
00092     out += half_width;
00093     yuv422_first += half_width;
00094     memcpy(out, yuv422_first, half_width);
00095     out += half_width;
00096     yuv422_second += half_width;
00097   }
00098   for ( unsigned int i = 0; i < height; ++i) {
00099     memcpy(out, yuv422_first, half_width);
00100     out += half_width;
00101     yuv422_first += half_width;
00102     memcpy(out, yuv422_first, half_width);
00103     out += half_width;
00104     yuv422_second += half_width;
00105   }
00106   */
00107 }
00108
00109 int
00110 main(int argc, char **argv)
00111 {
00112
00113   if ( argc < 2 ) {
00114     printf("Usage: %s <dir>\n", argv[0]);
00115     exit(-1);
00116   }
00117
00118   string dirname = argv[1];
00119
00120   // Get all files
00121   DIR *dir;
00122   struct dirent *dirp;
00123
00124   list<string> files;
00125
00126   if ( NULL == (dir = opendir(dirname.c_str())) ) {
00127     printf("Failed to open directory %s\n", dirname.c_str());
00128     exit(-2);
00129   }
00130
00131   while ( NULL != (dirp = readdir(dir)) ) {
00132     if ( NULL != strstr(dirp->d_name, ".raw") ) {
00133       files.push_back(dirp->d_name);
00134     }
00135   }
00136
00137   closedir(dir);
00138
00139   files.sort();
00140
00141   /*
00142   // create directories
00143   char *tmp;
00144   asprintf(&tmp, "%s/%s", dirname.c_str(), "orig_jpeg");
00145   mkdir(tmp, 0644);
00146   free(tmp);
00147 
00148   // create directories
00149   asprintf(&tmp, "%s/%s", dirname.c_str(), "disp_jpeg");
00150   mkdir(tmp, 0644);
00151   free(tmp);
00152   */
00153
00154   JpegWriter *jpeg = new JpegWriter("tmp.jpg");
00155
00156   // printf("%lu images to convert\n", files.size());
00157
00158   unsigned int in = 0;
00159   try {
00160     for (list<string>::iterator f = files.begin(); f != files.end(); ++f) {
00161       FvRawReader *fvraw = new FvRawReader((dirname + "/" + (*f)).c_str());
00162       printf("%4u Converting %s (%s)  ", ++in, (dirname + "/" + (*f)).c_str(), colorspace_to_string(fvraw->colorspace()));
00163       unsigned char *raw16 = malloc_buffer(fvraw->colorspace(), fvraw->pixel_width(), fvraw->pixel_height() * 2);
00164       unsigned char *rgb = (unsigned char *)malloc(colorspace_buffer_size(RGB, fvraw->pixel_width(), fvraw->pixel_height()) * 2);
00165       unsigned char *deinterlaced = (unsigned char *)malloc(fvraw->pixel_width() * fvraw->pixel_height() * 2);
00166       unsigned char *yuv = (unsigned char *)malloc_buffer(YUV422_PLANAR, fvraw->pixel_width(), fvraw->pixel_height() * 2);
00167       unsigned char *yuv_interleaved = (unsigned char *)malloc_buffer(YUV422_PLANAR, fvraw->pixel_width(), fvraw->pixel_height() * 2);
00168       fvraw->set_buffer(raw16);
00169       fvraw->read();
00170
00171       printf("(%ux%u)   ", fvraw->pixel_width(), fvraw->pixel_height());
00172
00173       Bumblebee2Camera::deinterlace_stereo(raw16, deinterlaced,
00174                                            fvraw->pixel_width(), fvraw->pixel_height());
00175       Bumblebee2Camera::decode_bayer(deinterlaced, rgb,
00176                                      fvraw->pixel_width(), fvraw->pixel_height(),
00177                                      BAYER_PATTERN_BGGR);
00178       /*
00179       convert(RGB, YUV422_PLANAR,
00180               rgb + colorspace_buffer_size(RGB, fvraw->pixel_width(), fvraw->pixel_height()),
00181               yuv + colorspace_buffer_size(YUV422_PLANAR, fvraw->pixel_width(), fvraw->pixel_height()),
00182               fvraw->pixel_width(), fvraw->pixel_height());
00183       */
00184       convert(RGB, YUV422_PLANAR,
00185               rgb,
00186               yuv,
00187               fvraw->pixel_width(), fvraw->pixel_height());
00188
00189       convert(RGB, YUV422_PLANAR,
00190               rgb + colorspace_buffer_size(RGB, fvraw->pixel_width(), fvraw->pixel_height()),
00191               yuv + colorspace_buffer_size(YUV422_PLANAR, fvraw->pixel_width(), fvraw->pixel_height()),
00192               fvraw->pixel_width(), fvraw->pixel_height());
00193
00194       interleave_yuv422planar(yuv + colorspace_buffer_size(YUV422_PLANAR, fvraw->pixel_width(), fvraw->pixel_height()),
00195                               yuv, yuv_interleaved, fvraw->pixel_width(), fvraw->pixel_height());
00196
00197       *f += ".jpg";
00198       printf("to %s\n", (dirname + "/orig_jpeg/" + (*f)).c_str());
00199
00200       jpeg->set_filename((dirname + "/orig_jpeg/" + (*f)).c_str());
00201       jpeg->set_buffer(YUV422_PLANAR, yuv_interleaved);
00202       // jpeg->set_buffer(YUV422_PLANAR, yuv);
00203       jpeg->set_dimensions(fvraw->pixel_width() * 2, fvraw->pixel_height());
00204       jpeg->write();
00205
00206       delete fvraw;
00207       free(raw16);
00208       free(rgb);
00209       free(deinterlaced);
00210       free(yuv);
00211       free(yuv_interleaved);
00212     }
00213   } catch (Exception &e) {
00214     e.print_trace();
00215     throw;
00216   }
00217 }