"Fossies" - the Fresh Open Source Software Archive

Member "rawtherapee-5.7/rtengine/slicer.cc" (10 Sep 2019, 5570 Bytes) of package /linux/misc/rawtherapee-5.7.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "slicer.cc" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 5.6_vs_5.7.

    1 /*
    2  *  This file is part of RawTherapee.
    3  *
    4  *  Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
    5  *
    6  *  RawTherapee is free software: you can redistribute it and/or modify
    7  *  it under the terms of the GNU General Public License as published by
    8  *  the Free Software Foundation, either version 3 of the License, or
    9  *  (at your option) any later version.
   10  *
   11  *  RawTherapee is distributed in the hope that it will be useful,
   12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  *  GNU General Public License for more details.
   15  *
   16  *  You should have received a copy of the GNU General Public License
   17  *  along with RawTherapee.  If not, see <https://www.gnu.org/licenses/>.
   18  */
   19 
   20 #include <cmath>
   21 #include <gtkmm.h>
   22 #include "rt_math.h"
   23 
   24 #include "slicer.h"
   25 
   26 #ifdef _OPENMP
   27 #include <omp.h>
   28 #endif
   29 
   30 using namespace std;
   31 
   32 // If no parameter set, everything = 0 -> process all the image
   33 Block::Block()
   34 {
   35     posX = 0;
   36     posY = 0;
   37     width = 0;
   38     height = 0;
   39 }
   40 
   41 Block::Block(unsigned int x, unsigned int y, unsigned int w, unsigned int h)
   42 {
   43     posX = x;
   44     posY = y;
   45     width = w;
   46     height = h;
   47 }
   48 
   49 /*
   50  * Slice a sub-region to process in blocks who's size is given by the number of processor
   51  * and the number of pixel per block (and hence the memory footprint)
   52  */
   53 Slicer::Slicer(unsigned int imageWidth, unsigned int imageHeight, Block *subRegion, unsigned int pixels )
   54 {
   55     // If the sub-region has a portrait shape, X and Y coordinates are swapped for better result
   56     // It will be swapped back when sending back the block coordinates
   57     region.width = !(subRegion->width) ? imageWidth : subRegion->width;
   58     region.height = !(subRegion->height) ? imageHeight : subRegion->height; // Assuming that the sub-region is under posY
   59 
   60     if (region.width < region.height) {
   61         region.width = !(subRegion->height) ? imageHeight : subRegion->height;
   62         region.height = !(subRegion->width) ? imageWidth : subRegion->width;    // Assuming that the sub-region is under posY
   63         portrait = true;
   64         imWidth = imageHeight;
   65         imHeight = imageWidth;
   66         region.posX = subRegion->posY;
   67         region.posY = subRegion->posX;
   68     } else {
   69         portrait = false;
   70         imWidth = imageWidth;
   71         imHeight = imageHeight;
   72         region.posX = subRegion->posX;
   73         region.posY = subRegion->posY;
   74     }
   75 
   76     double subRegionRatio = (double)(region.width) / (double)(region.height);
   77 
   78     //total number of core/processor
   79 #ifdef _OPENMP
   80     unsigned int procNumber = omp_get_num_procs();
   81 #else
   82     unsigned int procNumber = 1;
   83 #endif
   84 
   85     //calculate the number of block
   86     blockNumber = (double(region.width * region.height) / (double)pixels);
   87     blockNumber = int((rtengine::max(blockNumber, 1U) + (double)procNumber / 2.) / procNumber) * procNumber;
   88     vBlockNumber = (unsigned int)(sqrt((double)blockNumber / subRegionRatio) + 0.5);
   89     vBlockNumber = CLAMP(vBlockNumber, 1, blockNumber);
   90     hBlockNumber = (double)blockNumber / (double)vBlockNumber;
   91     blockWidth = 1.0 / hBlockNumber;
   92 
   93     double maxPixelNumberX = (double)region.height / (double)vBlockNumber;
   94     double maxPixelNumberY = (double)region.width / (double)((unsigned int)hBlockNumber);
   95 
   96     if (maxPixelNumberX - (double)((unsigned int)maxPixelNumberX) != 0.) {
   97         maxPixelNumberX += 1.;
   98     }
   99 
  100     if (maxPixelNumberY - (double)((unsigned int)maxPixelNumberY) != 0.) {
  101         maxPixelNumberY += 1.;
  102     }
  103 
  104     maxPixelNumber = (unsigned int)maxPixelNumberX * (unsigned int)maxPixelNumberY;
  105 
  106 }
  107 
  108 // return the absolute position and size of the requested block
  109 void Slicer::get_block(unsigned int numBlock, Block *block)
  110 {
  111     double roundingTradeOff = (hBlockNumber - (double)((int)hBlockNumber)) == 0.5 ? 2.1 : 2.0;
  112     unsigned int alreadyCompletedLineNbr = (unsigned int)((double)(numBlock) * blockWidth + (blockWidth / roundingTradeOff));
  113 
  114     unsigned int prevLineEnd = (unsigned int)((double)alreadyCompletedLineNbr * hBlockNumber + 0.5);
  115     unsigned int myLineEnd = (unsigned int)((double)(alreadyCompletedLineNbr + 1) * hBlockNumber + 0.5);
  116 
  117     unsigned int nbrCellsOnMyLine = myLineEnd - prevLineEnd;
  118     unsigned int cellOnMyLine = numBlock - prevLineEnd;
  119 
  120     unsigned int blockStart = (unsigned int)(((double)region.width / (double)nbrCellsOnMyLine) * (double)(cellOnMyLine));
  121     unsigned int blockEnd = (unsigned int)(((double)region.width / (double)nbrCellsOnMyLine) * (double)(cellOnMyLine + 1));
  122     block->width = blockEnd - blockStart;
  123     block->posX = region.posX + blockStart;
  124 
  125     if (cellOnMyLine == (nbrCellsOnMyLine - 1)) {
  126         // We make sure that the last block of the row take the rest of the remaining X space
  127         block->width = region.posX + region.width - block->posX;
  128     }
  129 
  130     blockStart = (unsigned int)(((double)region.height / (double)vBlockNumber) * (double)(alreadyCompletedLineNbr));
  131     blockEnd = (unsigned int)(((double)region.height / (double)vBlockNumber) * (double)(alreadyCompletedLineNbr + 1));
  132     block->height = blockEnd - blockStart;
  133     block->posY = region.posY + blockStart;
  134 
  135     if (alreadyCompletedLineNbr == (vBlockNumber - 1)) {
  136         block->height = region.posY + region.height - block->posY;
  137     }
  138 
  139     if (portrait) {
  140         // we swap back the X/Y coordinates
  141         unsigned int temp;
  142 
  143         temp = block->posX;
  144         block->posX = block->posY;
  145         block->posY = temp;
  146 
  147         temp = block->width;
  148         block->width = block->height;
  149         block->height = temp;
  150 
  151     }
  152 }