/* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2005-05-25 * Description : lens distortion algorithm. * * Copyright (C) 2005-2007 by Gilles Caulier * Copyright (C) 2001-2003 by David Hodson * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ // C++ includes. #include #include // Local includes. #include "dimg.h" #include "ddebug.h" #include "pixelaccess.h" #include "lensdistortion.h" namespace DigikamLensDistortionImagesPlugin { LensDistortion::LensDistortion(Digikam::DImg *orgImage, TQObject *parent, double main, double edge, double rescale, double brighten, int center_x, int center_y) : Digikam::DImgThreadedFilter(orgImage, parent, "LensDistortion") { m_main = main; m_edge = edge; m_rescale = rescale; m_brighten = brighten; m_centre_x = center_x; m_centre_y = center_y; initFilter(); } void LensDistortion::filterImage(void) { int Width = m_orgImage.width(); int Height = m_orgImage.height(); int bytesDepth = m_orgImage.bytesDepth(); uchar *data = m_destImage.bits(); // initial copy m_destImage.bitBltImage(&m_orgImage, 0, 0); // initialize coefficients double normallise_radius_sq = 4.0 / (Width * Width + Height * Height); double center_x = Width * (100.0 + m_centre_x) / 200.0; double center_y = Height * (100.0 + m_centre_y) / 200.0; double mult_sq = m_main / 200.0; double mult_qd = m_edge / 200.0; double rescale = pow(2.0, - m_rescale / 100.0); double brighten = - m_brighten / 10.0; PixelAccess *pa = new PixelAccess(&m_orgImage); /* * start at image (i, j), increment by (step, step) * output goes to dst, which is w x h x d in size * NB: d <= image.bpp */ // We are working on the full image. int dstWidth = Width; int dstHeight = Height; uchar* dst = (uchar*)data; int step = 1, progress; int iLimit, jLimit; double srcX, srcY, mag; iLimit = dstWidth * step; jLimit = dstHeight * step; for (int dstJ = 0 ; !m_cancel && (dstJ < jLimit) ; dstJ += step) { for (int dstI = 0 ; !m_cancel && (dstI < iLimit) ; dstI += step) { // Get source Coordinates. double radius_sq; double off_x; double off_y; double radius_mult; off_x = dstI - center_x; off_y = dstJ - center_y; radius_sq = (off_x * off_x) + (off_y * off_y); radius_sq *= normallise_radius_sq; radius_mult = radius_sq * mult_sq + radius_sq * radius_sq * mult_qd; mag = radius_mult; radius_mult = rescale * (1.0 + radius_mult); srcX = center_x + radius_mult * off_x; srcY = center_y + radius_mult * off_y; brighten = 1.0 + mag * brighten; pa->pixelAccessGetCubic(srcX, srcY, brighten, dst); dst += bytesDepth; } // Update progress bar in dialog. progress = (int) (((double)dstJ * 100.0) / jLimit); if (m_parent && progress%5 == 0) postProgress(progress); } delete pa; } } // NameSpace DigikamLensDistortionImagesPlugin