Adding the Slicer class
This commit is contained in:
@@ -11,7 +11,7 @@ set (RTENGINESOURCEFILES colortemp.cc curves.cc dcraw.cc iccstore.cc dfmanager.c
|
||||
image8.cc image16.cc imagedata.cc imageio.cc improcfun.cc init.cc dcrop.cc
|
||||
loadinitial.cc procparams.cc rawimagesource.cc shmap.cc simpleprocess.cc refreshmap.cc
|
||||
stdimagesource.cc myfile.cc iccjpeg.c hlmultipliers.cc improccoordinator.cc
|
||||
processingjob.cc rtthumbnail.cc utils.cc labimage.cc
|
||||
processingjob.cc rtthumbnail.cc utils.cc labimage.cc slicer.cc
|
||||
iplab2rgb.cc ipsharpen.cc iptransform.cc ipresize.cc
|
||||
wavelet_dec.cc ipequalizer.cc)
|
||||
|
||||
|
171
rtengine/slicer.cc
Normal file
171
rtengine/slicer.cc
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* This file is part of RawTherapee.
|
||||
*
|
||||
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
|
||||
*
|
||||
* RawTherapee 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* RawTherapee 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <omp.h>
|
||||
#include <slicer.h>
|
||||
|
||||
using namespace rtengine;
|
||||
|
||||
// If no parameter set, everything = 0 -> process all the image
|
||||
Block::Block() {
|
||||
posX = 0;
|
||||
posY = 0;
|
||||
width = 0;
|
||||
height = 0;
|
||||
}
|
||||
|
||||
Block::Block(unsigned int x, unsigned int y, unsigned int w, unsigned int h) {
|
||||
posX = x;
|
||||
posY = y;
|
||||
width = w;
|
||||
height = h;
|
||||
}
|
||||
|
||||
/*
|
||||
* Slice a sub-region to process in blocks who's size is given by the number of processor
|
||||
* and the number of pixel per block (and hence the memory footprint)
|
||||
*/
|
||||
Slicer::Slicer(unsigned int imageWidth, unsigned int imageHeight, Block *subRegion, unsigned int pixels, const char* nomFichier) {
|
||||
maxPixelNumberR = 0;
|
||||
// If the sub-region has a portrait shape, X and Y coordinates are swapped for better result
|
||||
// It will be swapped back when sending back the block coordinates
|
||||
region.width = !(subRegion->width) ? imageWidth : subRegion->width;
|
||||
region.height = !(subRegion->height) ? imageHeight : subRegion->height; // Assuming that the sub-region is under posY
|
||||
if (region.width < region.height) {
|
||||
region.width = !(subRegion->height) ? imageHeight : subRegion->height;
|
||||
region.height = !(subRegion->width) ? imageWidth : subRegion->width; // Assuming that the sub-region is under posY
|
||||
portrait = true;
|
||||
imWidth = imageHeight;
|
||||
imHeight = imageWidth;
|
||||
region.posX = subRegion->posY;
|
||||
region.posY = subRegion->posX;
|
||||
}
|
||||
else {
|
||||
portrait = false;
|
||||
imWidth = imageWidth;
|
||||
imHeight = imageHeight;
|
||||
region.posX = subRegion->posX;
|
||||
region.posY = subRegion->posY;
|
||||
}
|
||||
double subRegionRatio = (double)(region.width) / (double)(region.height);
|
||||
|
||||
//total number of core/processor
|
||||
#ifdef _OPENMP
|
||||
procNumber = omp_get_num_procs();
|
||||
#else
|
||||
procNumber = 1;
|
||||
#endif
|
||||
|
||||
//calculate the number of block
|
||||
blockNumber = (double(region.width*region.height) / (double)pixels);
|
||||
blockNumber = int((MAX(blockNumber, 1) + (double)procNumber/2.)/procNumber)*procNumber;
|
||||
vBlockNumber = (unsigned int)(sqrt((double)blockNumber / subRegionRatio)+0.5);
|
||||
vBlockNumber = CLAMP(vBlockNumber, 1, blockNumber);
|
||||
hBlockNumber = (double)blockNumber / (double)vBlockNumber;
|
||||
blockWidth = 1.0 / hBlockNumber;
|
||||
blockHeight = 1.0 / (double)vBlockNumber;
|
||||
|
||||
double maxPixelNumberX = (double)region.height / (double)vBlockNumber;
|
||||
double maxPixelNumberY = (double)region.width / (double)((unsigned int)hBlockNumber);
|
||||
if (maxPixelNumberX - (double)((unsigned int)maxPixelNumberX) != 0) maxPixelNumberX += 1.;
|
||||
if (maxPixelNumberY - (double)((unsigned int)maxPixelNumberY) != 0) maxPixelNumberY += 1.;
|
||||
maxPixelNumber = (unsigned int)maxPixelNumberX * (unsigned int)maxPixelNumberY;
|
||||
|
||||
printf ("\n*****************\nimageWidth : %d\nimageHeight : %d\nregion.width : %d\nregion.height : %d\npixels : %d\n\n", imageWidth, imageHeight, region.width, region.height, pixels);
|
||||
printf ("subRegionRatio=%.5f\nPortrait = %d\n", (float)subRegionRatio, portrait);
|
||||
printf ("Total block number : %d\nHorizontal block number : %.3f\nVertical block number : %d\nmaxPixelNumber : %d\n", blockNumber, hBlockNumber, vBlockNumber, maxPixelNumber);
|
||||
fichierSortie = fopen(nomFichier, "wt");
|
||||
fprintf(fichierSortie,"<?xml version='1.0' encoding='utf-8' standalone='no'?>\n");
|
||||
fprintf(fichierSortie,"<svg xmlns:svg='http://www.w3.org/2000/svg' xmlns='http://www.w3.org/2000/svg' version='1.0' ");
|
||||
fprintf(fichierSortie,"width='%d' height='%d' id='svg2'><defs id='defs4' />\n", (portrait?imageHeight:imageWidth), (portrait?imageWidth:imageHeight));
|
||||
|
||||
fprintf(fichierSortie,"<rect width='%d' height='%d' x='%d' y='%d'", ((portrait?region.height:region.width)-2), ((portrait?region.width:region.height)-2), ((portrait?region.posY:region.posX)+1), ((portrait?region.posX:region.posY)+1));
|
||||
fprintf(fichierSortie," id='rectSR' style='opacity:0.3;fill:none;");
|
||||
fprintf(fichierSortie,"fill-opacity:1;fill-rule:evenodd;stroke:#FF0000;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;");
|
||||
fprintf(fichierSortie,"stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1' />\n");
|
||||
|
||||
}
|
||||
|
||||
Slicer::~Slicer() {
|
||||
printf("maxPixelNumberR = %d (block #%d)\n", maxPixelNumberR, maxPixBlockNumber);
|
||||
fprintf(fichierSortie,"</svg>\n");
|
||||
fclose(fichierSortie);
|
||||
}
|
||||
|
||||
// return the absolute position and size of the requested block
|
||||
void Slicer::get_block(unsigned int numBlock, Block *block) {
|
||||
volatile double roundingTradeOff = (hBlockNumber - (double)((int)hBlockNumber)) == 0.5 ? 2.1 : 2.0;
|
||||
volatile unsigned int nbrLigneDejaComplete = (unsigned int)((double)(numBlock) * blockWidth + (blockWidth/roundingTradeOff));
|
||||
|
||||
volatile unsigned int prevLigneFin = (unsigned int)((double)nbrLigneDejaComplete * hBlockNumber + 0.5);
|
||||
volatile unsigned int maLigneFin = (unsigned int)((double)(nbrLigneDejaComplete+1) * hBlockNumber + 0.5);
|
||||
|
||||
volatile unsigned int nbCelluleSurMaLigne = maLigneFin - prevLigneFin;
|
||||
volatile unsigned int celluleSurMaLigne = numBlock - prevLigneFin;
|
||||
|
||||
volatile unsigned int blockStart = (unsigned int)(((double)region.width / (double)nbCelluleSurMaLigne)*(double)(celluleSurMaLigne));
|
||||
volatile unsigned int blockEnd = (unsigned int)(((double)region.width / (double)nbCelluleSurMaLigne)*(double)(celluleSurMaLigne+1));
|
||||
block->width = blockEnd - blockStart;
|
||||
block->posX = region.posX + blockStart;
|
||||
if (celluleSurMaLigne == (nbCelluleSurMaLigne-1)) {
|
||||
// We make sure that the last block of the row take the rest of the remaining X space
|
||||
block->width = region.posX + region.width - block->posX;
|
||||
}
|
||||
|
||||
blockStart = (unsigned int)(((double)region.height / (double)vBlockNumber)*(double)(nbrLigneDejaComplete));
|
||||
blockEnd = (unsigned int)(((double)region.height / (double)vBlockNumber)*(double)(nbrLigneDejaComplete+1));
|
||||
block->height = blockEnd - blockStart;
|
||||
block->posY = region.posY + blockStart;
|
||||
if (nbrLigneDejaComplete == (vBlockNumber-1)) {
|
||||
block->height = region.posY + region.height - block->posY;
|
||||
}
|
||||
|
||||
if (portrait) {
|
||||
// we swap back the X/Y coordinates
|
||||
unsigned int temp;
|
||||
|
||||
temp = block->posX;
|
||||
block->posX = block->posY;
|
||||
block->posY = temp;
|
||||
|
||||
temp = block->width;
|
||||
block->width = block->height;
|
||||
block->height = temp;
|
||||
|
||||
}
|
||||
unsigned int currBlockSize = block->width * block->height;
|
||||
if (currBlockSize > maxPixelNumberR) {
|
||||
maxPixelNumberR = currBlockSize;
|
||||
maxPixBlockNumber = numBlock+1;
|
||||
}
|
||||
|
||||
char *couleur[4] = {"70d26e", "3ba6c3", "d0d26e", "3b62c3"};
|
||||
char *coul = couleur[(nbrLigneDejaComplete%2)*2 + celluleSurMaLigne%2];
|
||||
fprintf(fichierSortie,"<rect width='%d' height='%d' x='%d' y='%d'", (block->width-2), (block->height-2), (block->posX+1), (block->posY+1));
|
||||
fprintf(fichierSortie," id='rect%d' style='opacity:0.3;fill:#%s;fill-opacity:1;fill-rule:evenodd;stroke:#%s;stroke-width:2;stroke-linecap:square;", numBlock, coul, coul);
|
||||
fprintf(fichierSortie,"stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1' />\n", numBlock);
|
||||
fprintf(fichierSortie,"<text x='%d' y='%d'", (block->posX + block->width/2), (block->posY + block->height/2));
|
||||
fprintf(fichierSortie," id='text%d' xml:space='preserve' style='font-size:15px;font-style:normal;", numBlock);
|
||||
fprintf(fichierSortie,"font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;text-anchor:start;fill:#000000;");
|
||||
fprintf(fichierSortie,"fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;");
|
||||
fprintf(fichierSortie,"font-family:Arial;-inkscape-font-specification:Arial'>\n");
|
||||
fprintf(fichierSortie,"<tspan x='%d' y='%d'", (block->posX + block->width/2), (block->posY + block->height/2));
|
||||
fprintf(fichierSortie," id='tspan%d'>%d</tspan>\n</text>\n", numBlock, (numBlock+1));
|
||||
}
|
76
rtengine/slicer.h
Normal file
76
rtengine/slicer.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is part of RawTherapee.
|
||||
*
|
||||
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
|
||||
*
|
||||
* RawTherapee 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* RawTherapee 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _SLICER_
|
||||
#define _SLICER_
|
||||
|
||||
//The image is divided in blocks even on single processor machine, mainly to decrease memory consumption
|
||||
//maximum number of pixel per block
|
||||
#define PIXELS_PER_BLOCK 1000000
|
||||
|
||||
// DEBUG!
|
||||
#include <glibmm.h>
|
||||
#include <stdio.h>
|
||||
//#include <glib/gstdio.h>
|
||||
|
||||
|
||||
namespace rtengine {
|
||||
|
||||
class Block {
|
||||
public:
|
||||
unsigned int posX;
|
||||
unsigned int posY;
|
||||
unsigned int width; // If 0, use the full width of the image
|
||||
unsigned int height; // If 0, use the full height of the image
|
||||
Block();
|
||||
Block(unsigned int x, unsigned int y, unsigned int w, unsigned int h);
|
||||
};
|
||||
|
||||
/*
|
||||
* This class handle the best slicing of the image with a given number of pixels per block and the number of
|
||||
* processor, and tries to create block as square as possible. There can be a different number of block on
|
||||
* each line.
|
||||
*/
|
||||
class Slicer {
|
||||
protected:
|
||||
bool portrait; // Orientation of the sub-region
|
||||
unsigned int procNumber; // Number of processor
|
||||
unsigned int imWidth; // Image width
|
||||
unsigned int imHeight; // Image height
|
||||
Block region; // Sub-region to process
|
||||
double hBlockNumber; // Horizontal number of block for the sub-region
|
||||
unsigned int vBlockNumber; // Vertical number of block for the sub-region
|
||||
double blockWidth;
|
||||
double blockHeight;
|
||||
// DEBUG below
|
||||
unsigned int maxPixelNumberR;
|
||||
int maxPixBlockNumber;
|
||||
FILE *fichierSortie;
|
||||
|
||||
public:
|
||||
unsigned int blockNumber; // number of block for the sub-region
|
||||
unsigned int maxPixelNumber; // number of pixel of the biggest block (for memory allocation purpose)
|
||||
Slicer(unsigned int imageWidth, unsigned int imageHeight, Block *subRegion, unsigned int pixels, const char* nomFichier);
|
||||
~Slicer(void);
|
||||
void get_block(unsigned int blockId, Block *block);
|
||||
void drawRectSVG(unsigned int numBlock, Block *block);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user