DeBayer.C

00001 /*!@file Raster/Debayer.C is the general debayer class */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Zhicheng Li <zhicheng@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Raster/DeBayer.C $
00035 // $Id: DeBayer.C 10794 2009-02-08 06:21:09Z itti $
00036 //
00037 
00038 #include <stdio.h>
00039 #include <stdint.h>
00040 
00041 #include "Util/log.H"
00042 #include "Raster/DeBayer.H"
00043 #include "Raster/DeBayerREG.H"
00044 
00045 #ifdef INVT_USE_SSEDB
00046 #include <emmintrin.h>
00047 #include "Raster/DeBayerSSE2.H"
00048 #ifdef INVT_USE_SSE3
00049 #include <pmmintrin.h>
00050 #include "Raster/DeBayerSSE3.H"
00051 #endif
00052 #endif
00053 
00054 #include "Image/Image.H"
00055 #include "Image/Pixels.H"
00056 #include "Util/Types.H"
00057 
00058 template <class T>
00059 Image<PixRGB<T> > deBayer(const Image<T>& src, BayerFormat format)
00060 {
00061   Image<PixRGB<T> >  res(src.getDims(), NO_INIT);
00062   int bitDepth = 8*sizeof(T);
00063 
00064   if(bitDepth == 8)
00065     {
00066       // use accelerated deBayer code?
00067       // now SSE2 and SSE3 only support 8 bit depth image
00068       // so althogh they use the template T type they only work for byte type
00069 #ifdef INVT_USE_SSEDB
00070 
00071 #ifdef INVT_USE_SSE3
00072       res = debayerSSE3(src,format);
00073 #else
00074       res = debayerSSE2(src,format);
00075 #endif
00076 
00077 #else
00078       res = debayerREG(src,format);
00079 #endif
00080     }
00081   else
00082     res = debayerREG(src, format);
00083   return res;
00084 }
00085 
00086 template Image<PixRGB<byte> >  deBayer(const Image<byte>& src, BayerFormat format);
00087 template Image<PixRGB<uint16> >  deBayer(const Image<uint16>& src, BayerFormat format);
00088 
00089 // #######################################################################//
00090 int
00091 replicateBorder_8u (uint8_t * src, int sstride, int width, int height)
00092 {
00093 
00094     memcpy (src - sstride, src, width);
00095     memcpy (src + height * sstride, src + (height-1)*sstride, width);
00096 
00097     int i;
00098     for (i = -1; i < height+1; i++) {
00099         src[i*sstride-1] = src[i*sstride];
00100         src[i*sstride + width] = src[i*sstride + width - 1];
00101     }
00102     return 0;
00103 }
00104 
00105 // #######################################################################//
00106 int
00107 copy_8u_generic (const uint8_t *src, int sstride,
00108         uint8_t *dst, int dstride,
00109         int src_x, int src_y,
00110         int dst_x, int dst_y,
00111         int width, int height,
00112         int bits_per_pixel)
00113 {
00114     if (bits_per_pixel % 8) return -1;
00115     int bytes_per_pixel = bits_per_pixel / 8;
00116 
00117     int i;
00118     for (i=0; i<height; i++) {
00119         uint8_t *dst_row = dst + (dst_y + i) * dstride;
00120         const uint8_t *src_row = src + (src_y + i) * sstride;
00121 
00122         memcpy (dst_row + dst_x * bytes_per_pixel,
00123                 src_row + src_x * bytes_per_pixel,
00124                 width * bytes_per_pixel);
00125     }
00126     return 0;
00127 }
00128 
00129 
00130 // ################### get the 4 plane of R GR GB B plane #################//
00131 // #######################################################################//
00132 // #######################################################################//
00133 int
00134 splitBayerPlanes_8u (uint8_t *dst[4], int dstride,
00135                      const uint8_t * src, int sstride,
00136                      int width, int height)
00137 {
00138 #ifndef INVT_USE_SSEDB
00139   LINFO("you need to have sse2 support");
00140   return -1;
00141 #else
00142   __m128i mask;
00143   int i, j;
00144 
00145   for (i = 0; i < 4; i++) {
00146     if (!IS_ALIGNED16(dstride)) {
00147       LFATAL("splitBayerPlanes_8u: dst[%d] is not "
00148              "16-byte aligned\n",i);
00149       return -1;
00150     }
00151   }
00152   if (!IS_ALIGNED16(sstride)) {
00153     LFATAL("splitBayerPlanes_8u: src is not 16-byte "
00154              "aligned\n");
00155     return -1;
00156   }
00157 
00158   /* If the source stride is not a multiple of 32 pixels, we need to
00159    * fix up the last column at the end. */
00160   if (!IS_ALIGNED32 (sstride))
00161     width -= 8;
00162 
00163   mask = _mm_set1_epi16 (0xff);
00164   for (i = 0; i < height; i++) {
00165     uint8_t * drow1 = dst[0] + i * dstride;
00166     uint8_t * drow2 = dst[1] + i * dstride;
00167     uint8_t * drow3 = dst[2] + i * dstride;
00168     uint8_t * drow4 = dst[3] + i * dstride;
00169     const uint8_t * srow = src + 2*i*sstride;
00170     for (j = 0; j < width; j += 16) {
00171       __m128i s1, s2, t1, t2, out;
00172       s1 = _mm_load_si128 ((__m128i *)(srow + 2*j));
00173       s2 = _mm_load_si128 ((__m128i *)(srow + 2*j + 16));
00174 
00175       t1 = _mm_and_si128 (s1, mask);
00176       t2 = _mm_and_si128 (s2, mask);
00177 
00178       out = _mm_packus_epi16 (t1, t2);
00179       _mm_store_si128 ((__m128i *)(drow1 + j), out);
00180 
00181       t1 = _mm_srli_epi16 (s1, 8);
00182       t2 = _mm_srli_epi16 (s2, 8);
00183 
00184       out = _mm_packus_epi16 (t1, t2);
00185       _mm_store_si128 ((__m128i *)(drow2 + j), out);
00186 
00187       s1 = _mm_load_si128 ((__m128i *)(srow + sstride + 2*j));
00188       s2 = _mm_load_si128 ((__m128i *)(srow + sstride + 2*j + 16));
00189 
00190       t1 = _mm_and_si128 (s1, mask);
00191       t2 = _mm_and_si128 (s2, mask);
00192 
00193       out = _mm_packus_epi16 (t1, t2);
00194       _mm_store_si128 ((__m128i *)(drow3 + j), out);
00195 
00196       t1 = _mm_srli_epi16 (s1, 8);
00197       t2 = _mm_srli_epi16 (s2, 8);
00198 
00199       out = _mm_packus_epi16 (t1, t2);
00200       _mm_store_si128 ((__m128i *)(drow4 + j), out);
00201     }
00202   }
00203   if (IS_ALIGNED32 (sstride))
00204     return 0;
00205 
00206   /* Fix up the last column if necessary */
00207   const uint8_t * scol1 = src + 2*width;
00208   const uint8_t * scol2 = src + 2*width + sstride;
00209   uint8_t * dcol1 = dst[0] + width;
00210   uint8_t * dcol2 = dst[1] + width;
00211   uint8_t * dcol3 = dst[2] + width;
00212   uint8_t * dcol4 = dst[3] + width;
00213   __m128i t2 = _mm_set1_epi16 (0);
00214   for (i = 0; i < height; i++) {
00215     __m128i s1, t1, out;
00216     s1 = _mm_load_si128 ((__m128i *)(scol1 + 2*i*sstride));
00217     t1 = _mm_and_si128 (s1, mask);
00218 
00219     out = _mm_packus_epi16 (t1, t2);
00220     _mm_store_si128 ((__m128i *)(dcol1 + i*dstride), out);
00221 
00222     t1 = _mm_srli_epi16 (s1, 8);
00223 
00224     out = _mm_packus_epi16 (t1, t2);
00225     _mm_store_si128 ((__m128i *)(dcol2 + i*dstride), out);
00226 
00227     s1 = _mm_load_si128 ((__m128i *)(scol2 + 2*i*sstride));
00228     t1 = _mm_and_si128 (s1, mask);
00229 
00230     out = _mm_packus_epi16 (t1, t2);
00231     _mm_store_si128 ((__m128i *)(dcol3 + i*dstride), out);
00232 
00233     t1 = _mm_srli_epi16 (s1, 8);
00234 
00235     out = _mm_packus_epi16 (t1, t2);
00236     _mm_store_si128 ((__m128i *)(dcol4 + i*dstride), out);
00237   }
00238   return 0;
00239 #endif
00240 }
00241 
00242 // ######################################################################
00243 /* So things look consistent in everyone's emacs... */
00244 /* Local Variables: */
00245 /* indent-tabs-mode: nil */
00246 /* End: */
Generated on Sun May 8 08:41:16 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3