unwarp.cpp

00001
00002 /***************************************************************************
00003  *  unwarp.cpp - Implementation of unwarp filter
00004  *
00005  *  Created: Mon Jul 25 11:22:11 2005
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. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023
00024 #include <filters/unwarp.h>
00025
00026 #include <models/mirror/mirrormodel.h>
00027 #include <fvutils/color/yuv.h>
00028 #include <cstddef>
00029
00030 
00031 /** @class FilterUnwarp <filters/unwarp.h>
00032  * Create unwarped image with given mirror model.
00033  * @author Tim Niemueller
00034  */
00035 
00036 /** Constructor.
00037  * @param mm mirror model
00038  */
00039 FilterUnwarp::FilterUnwarp(MirrorModel *mm)
00040   : Filter("FilterUnwarp")
00041 {
00042   this->mm = mm;
00043 }
00044
00045
00046 void
00047 FilterUnwarp::apply()
00048 {
00049   // destination y-plane
00050   register unsigned char *dyp  = dst + (dst_roi->start.y * dst_roi->line_step) + (dst_roi->start.x * dst_roi->pixel_step);
00051
00052   // destination u-plane
00053   register unsigned char *dup  = YUV422_PLANAR_U_PLANE(dst, dst_roi->image_width, dst_roi->image_height)
00054                                    + ((dst_roi->start.y * dst_roi->line_step) / 2 + (dst_roi->start.x * dst_roi->pixel_step) / 2) ;
00055   // v-plane
00056   register unsigned char *dvp  = YUV422_PLANAR_V_PLANE(dst, dst_roi->image_width, dst_roi->image_height)
00057                                    + ((dst_roi->start.y * dst_roi->line_step) / 2 + (dst_roi->start.x * dst_roi->pixel_step) / 2);
00058
00059   // line starts
00060   unsigned char *ldyp  = dyp;  // destination y-plane
00061   unsigned char *ldup  = dup;   // u-plane
00062   unsigned char *ldvp  = dvp;   // v-plane
00063
00064   unsigned int warp1_x = 0, warp1_y = 0,
00065                warp2_x = 0, warp2_y = 0;
00066
00067   unsigned char py1=0, py2=0, pu1=0, pu2=0, pv1=0, pv2=0;
00068
00069   for (unsigned int h = 0; h < dst_roi->height; ++h) {
00070     for (unsigned int w = 0; w < dst_roi->width; w += 2) {
00071       mm->unwarp2warp( dst_roi->start.x + w, dst_roi->start.y + h,
00072                        &warp1_x, &warp1_y );
00073       mm->unwarp2warp( dst_roi->start.x + w + 1, dst_roi->start.y + h + 1,
00074                        &warp2_x, &warp2_y );
00075
00076       if ( (warp1_x < src_roi[0]->image_width) &&
00077            (warp1_y < src_roi[0]->image_height) ) {
00078         // Src pixel is in original image
00079
00080         YUV422_PLANAR_YUV(src[0], src_roi[0]->image_width, src_roi[0]->image_height,
00081                           warp1_x, warp1_y,
00082                           py1, pu1, pv1);
00083
00084         *dyp++ = py1;
00085         *dup   = pu1;
00086         *dvp   = pv1;
00087
00088
00089         if ( (warp2_x < src_roi[0]->image_width) &&
00090              (warp2_y < src_roi[0]->image_height) ) {
00091
00092           YUV422_PLANAR_YUV(src[0], src_roi[0]->image_width, src_roi[0]->image_height,
00093                           warp2_x, warp2_y,
00094                           py2, pu2, pv2);
00095
00096           *dyp++ = py2;
00097           *dup   = (*dup + pu2) / 2;
00098           *dvp   = (*dvp + pv2) / 2;
00099         } else {
00100           *dyp++ = 0;
00101         }
00102         dup++;
00103         dvp++;
00104       } else {
00105
00106         *dyp++ = 0;
00107         *dup   = 0;
00108         *dvp   = 0;
00109
00110         if ( (warp2_x < src_roi[0]->image_width) &&
00111              (warp2_y < src_roi[0]->image_height) ) {
00112
00113           YUV422_PLANAR_YUV(src[0], src_roi[0]->image_width, src_roi[0]->image_height,
00114                           warp2_x, warp2_y,
00115                           py2, pu2, pv2);
00116
00117           *dyp++ = py2;
00118           *dup   = pu2;
00119           *dvp   = pv2;
00120         } else {
00121           *dyp++ = 0;
00122         }
00123
00124         dup++;
00125         dvp++;
00126       }
00127     }
00128
00129     ldyp += dst_roi->line_step;
00130     ldup += dst_roi->line_step;
00131     ldup += dst_roi->line_step;
00132     dyp = ldyp;
00133     dup = ldup;
00134     dvp = ldvp;
00135   }
00136 }
00137