1 #ifndef ProcessByBrick_h
2 #define ProcessByBrick_h
10 #include <QtConcurrentMap>
100 int requirements = 0);
104 int requirements = 0);
137 virtual void StartProcess(
void funct(std::vector<Buffer *> &in,
138 std::vector<Buffer *> &out));
164 const Functor & functor,
bool threaded =
true) {
168 bool haveInput = PrepProcessCubeInPlace(&cube, &brick);
169 bool writeOutput = (!haveInput) || (cube->
isReadWrite());
171 ProcessCubeInPlaceFunctor<Functor> wrapperFunctor(
172 cube, brick, haveInput, writeOutput, functor);
174 RunProcess(wrapperFunctor, brick->
Bricks(), threaded);
200 template <
typename Functor>
void ProcessCube(
const Functor & functor,
201 bool threaded =
true) {
202 Brick *inputCubeData = NULL;
203 Brick *outputCubeData = NULL;
205 int numBricks = PrepProcessCube(&inputCubeData, &outputCubeData);
207 ProcessCubeFunctor<Functor> wrapperFunctor(
InputCubes[0], inputCubeData,
210 RunProcess(wrapperFunctor, numBricks, threaded);
212 delete inputCubeData;
213 delete outputCubeData;
240 bool threaded =
true) {
241 std::vector<Brick *> inputCubeData;
242 std::vector<Brick *> outputCubeData;
244 std::vector<Buffer *> inputCubeDataParents;
245 std::vector<Buffer *> outputCubeDataParents;
247 int numBricks = PrepProcessCubes(
248 inputCubeDataParents, outputCubeDataParents,
249 inputCubeData, outputCubeData);
251 ProcessCubesFunctor<Functor> wrapperFunctor(
InputCubes, inputCubeData,
254 RunProcess(wrapperFunctor, numBricks, threaded);
256 for(
unsigned int i = 0; i < inputCubeData.size(); i++) {
257 delete inputCubeData[i];
260 for(
unsigned int i = 0; i < outputCubeData.size(); i++) {
261 delete outputCubeData[i];
279 template <
typename Functor>
280 void RunProcess(
const Functor &wrapperFunctor,
281 int numSteps,
bool threaded) {
282 ProcessIterator begin(0);
283 ProcessIterator end(numSteps);
288 int threadCount = QThreadPool::globalInstance()->maxThreadCount();
289 if (threaded && threadCount > 1) {
290 QFuture<void> result = QtConcurrent::mapped(begin, end,
292 BlockingReportProgress(result);
295 while (begin != end) {
296 wrapperFunctor(*begin);
318 template <
typename T>
319 class ProcessCubeInPlaceFunctor :
320 public std::unary_function<const int &, void *> {
337 ProcessCubeInPlaceFunctor(Cube *cube,
338 const Brick *templateBrick,
339 bool readInput,
bool writeOutput,
340 const T &processingFunctor) :
342 m_templateBrick(templateBrick),
343 m_readInput(readInput),
344 m_writeOutput(writeOutput),
345 m_processingFunctor(processingFunctor) {
354 ProcessCubeInPlaceFunctor(
const ProcessCubeInPlaceFunctor &other) :
355 m_cube(other.m_cube),
356 m_templateBrick(other.m_templateBrick),
357 m_readInput(other.m_readInput),
358 m_writeOutput(other.m_writeOutput),
359 m_processingFunctor(other.m_processingFunctor) {
366 virtual ~ProcessCubeInPlaceFunctor() {
368 m_templateBrick = NULL;
378 void *operator()(
const int &brickPosition)
const {
379 Brick cubeData(*m_templateBrick);
380 cubeData.setpos(brickPosition);
383 m_cube->read(cubeData);
385 m_processingFunctor(cubeData);
388 m_cube->write(cubeData);
401 ProcessCubeInPlaceFunctor &operator=(
402 const ProcessCubeInPlaceFunctor &rhs) {
404 m_templateBrick = rhs.m_templateBrick;
406 m_readInput = rhs.m_readInput;
407 m_writeOutput = rhs.m_writeOutput;
409 m_processingFunctor = rhs.m_processingFunctor;
418 const Brick *m_templateBrick;
425 const T &m_processingFunctor;
442 template <
typename T>
443 class ProcessCubeFunctor :
444 public std::unary_function<const int &, void *> {
461 ProcessCubeFunctor(Cube *inputCube,
462 const Brick *inputTemplateBrick,
464 const Brick *outputTemplateBrick,
465 const T &processingFunctor) :
466 m_inputCube(inputCube),
467 m_inputTemplateBrick(inputTemplateBrick),
468 m_outputCube(outputCube),
469 m_outputTemplateBrick(outputTemplateBrick),
470 m_processingFunctor(processingFunctor) {
479 ProcessCubeFunctor(
const ProcessCubeFunctor &other) :
480 m_inputCube(other.m_inputCube),
481 m_inputTemplateBrick(other.m_inputTemplateBrick),
482 m_outputCube(other.m_outputCube),
483 m_outputTemplateBrick(other.m_outputTemplateBrick),
484 m_processingFunctor(other.m_processingFunctor) {
491 virtual ~ProcessCubeFunctor() {
492 m_inputTemplateBrick = NULL;
493 m_outputTemplateBrick = NULL;
503 void *operator()(
const int &brickPosition)
const {
504 Brick inputCubeData(*m_inputTemplateBrick);
505 Brick outputCubeData(*m_outputTemplateBrick);
507 inputCubeData.setpos(brickPosition);
508 outputCubeData.setpos(brickPosition);
510 m_inputCube->read(inputCubeData);
512 m_processingFunctor(inputCubeData, outputCubeData);
514 m_outputCube->write(outputCubeData);
527 ProcessCubeFunctor &operator=(
const ProcessCubeFunctor &rhs) {
528 m_inputCube = rhs.m_inputCube;
529 m_inputTemplateBrick = rhs.m_inputTemplateBrick;
531 m_outputCube = rhs.m_outputCube;
532 m_outputTemplateBrick = rhs.m_outputTemplateBrick;
534 m_processingFunctor = rhs.m_processingFunctor;
543 const Brick *m_inputTemplateBrick;
548 const Brick *m_outputTemplateBrick;
551 const T &m_processingFunctor;
569 template <
typename T>
570 class ProcessCubesFunctor :
571 public std::unary_function<const int &, void *> {
592 ProcessCubesFunctor(std::vector<Cube *> &inputCubes,
593 std::vector<Brick *> &inputTemplateBricks,
594 std::vector<Cube *> &outputCubes,
595 std::vector<Brick *> &outputTemplateBricks,
597 const T &processingFunctor) :
598 m_inputCubes(inputCubes),
599 m_inputTemplateBricks(inputTemplateBricks),
600 m_outputCubes(outputCubes),
601 m_outputTemplateBricks(outputTemplateBricks),
603 m_processingFunctor(processingFunctor) {
612 ProcessCubesFunctor(
const ProcessCubesFunctor &other) :
613 m_inputCubes(other.m_inputCubes),
614 m_inputTemplateBricks(other.m_inputTemplateBricks),
615 m_outputCubes(other.m_outputCubes),
616 m_outputTemplateBricks(other.m_outputTemplateBricks),
617 m_wraps(other.m_wraps),
618 m_processingFunctor(other.m_processingFunctor) {
625 virtual ~ProcessCubesFunctor() {
635 void *operator()(
const int &brickPosition)
const {
638 for (
int i = 0; i < (int)m_inputTemplateBricks.size(); i++) {
639 Brick *inputBrick =
new Brick(*m_inputTemplateBricks[i]);
640 functorBricks.first.push_back(inputBrick);
643 inputBrick->setpos(brickPosition % inputBrick->Bricks());
646 inputBrick->setpos(brickPosition);
650 functorBricks.first.size() &&
651 inputBrick->Band() != functorBricks.first[0]->Band() &&
652 m_inputCubes[i]->bandCount() != 1) {
653 inputBrick->SetBaseBand(functorBricks.first[0]->Band());
656 m_inputCubes[i]->read(*inputBrick);
659 for (
int i = 0; i < (int)m_outputTemplateBricks.size(); i++) {
660 Brick *outputBrick =
new Brick(*m_outputTemplateBricks[i]);
661 functorBricks.second.push_back(outputBrick);
662 outputBrick->setpos(brickPosition);
666 m_processingFunctor(functorBricks.first, functorBricks.second);
669 for (
int i = 0; i < (int)functorBricks.second.size(); i++) {
670 m_outputCubes[i]->write(*functorBricks.second[i]);
671 delete functorBricks.second[i];
674 for (
int i = 0; i < (int)functorBricks.first.size(); i++) {
675 delete functorBricks.first[i];
689 ProcessCubesFunctor &operator=(
const ProcessCubesFunctor &rhs) {
690 m_inputCubes = rhs.m_inputCubes;
691 m_inputTemplateBricks = rhs.m_inputTemplateBricks;
693 m_outputCubes = rhs.m_outputCubes;
694 m_outputTemplateBricks = rhs.m_outputTemplateBricks;
696 m_wraps = rhs.m_wraps;
698 m_processingFunctor = rhs.m_processingFunctor;
705 std::vector<Cube *> m_inputCubes;
710 std::vector<Brick *> &m_inputTemplateBricks;
713 std::vector<Cube *> m_outputCubes;
718 std::vector<Brick *> &m_outputTemplateBricks;
724 const T &m_processingFunctor;
728 void BlockingReportProgress(QFuture<void> &future);
729 std::vector<int> CalculateMaxDimensions(std::vector<Cube *> cubes)
const;
730 bool PrepProcessCubeInPlace(Cube **cube, Brick **bricks);
731 int PrepProcessCube(Brick **ibrick, Brick **obrick);
732 int PrepProcessCubes(std::vector<Buffer *> & ibufs,
733 std::vector<Buffer *> & obufs,
734 std::vector<Brick *> & imgrs,
735 std::vector<Brick *> & omgrs);
747 class ProcessIterator :
public std::iterator<
748 std::forward_iterator_tag, int> {
750 ProcessIterator(
int position);
751 ProcessIterator(
const ProcessIterator &other);
752 virtual ~ProcessIterator();
754 ProcessIterator &operator++();
762 bool operator==(
const ProcessIterator &rhs) {
763 return (m_currentPosition == rhs.m_currentPosition);
772 bool operator!=(
const ProcessIterator &rhs) {
773 return !(*
this == rhs);
782 void swap(ProcessIterator &other) {
783 std::swap(m_currentPosition, other.m_currentPosition);
793 ProcessIterator &operator=(
const ProcessIterator &rhs) {
794 ProcessIterator copy(rhs);
805 return m_currentPosition;
810 int m_currentPosition;
818 bool p_inputBrickSizeSet;
820 bool p_outputBrickSizeSet;
823 int p_outputRequirements;
826 std::vector<int> p_inputBrickSamples;
828 std::vector<int> p_inputBrickLines;
830 std::vector<int> p_inputBrickBands;
832 std::vector<int> p_outputBrickSamples;
834 std::vector<int> p_outputBrickLines;
836 std::vector<int> p_outputBrickBands;