FotoSHOCK
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
TransformImage.hpp
1 /*
2  * Copyright 2011, 2012 Lukas Jirkovsky
3  *
4  * This file is part of FotoSHOCKcore.
5  *
6  * FotoSHOCKcore is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, version 3 of the License.
9  *
10  * FotoSHOCKcore is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with FotoSHOCKcore. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef TRANSFORMIMAGE_H
20 #define TRANSFORMIMAGE_H
21 
22 #include "MipMap.hpp"
23 #include "ImageBuffer.hpp"
24 #include "UpdateInfo.hpp"
25 
26 #include <vector>
27 #include <boost/thread.hpp>
28 
29 namespace FotoSHOCKcore{
30 
31 template <ValueType::Enum InPixelType, ValueType::Enum OutPixelType, typename Functor>
32 void transformImage_impl(ImageBuffer<InPixelType>& src, ImageBuffer<OutPixelType>& dest, Functor func,
33  const unsigned int srcNumOfTilesHoriz, const unsigned int destNumOfTilesHoriz,
34  const unsigned int srcNumOfTilesVert, const unsigned int destNumOfTilesVert,
35  const unsigned int srcTileExtent, ROIinfo &ROI, const long stamp);
36 
38 
53 template <ValueType::Enum InPixelType, ValueType::Enum OutPixelType, typename Functor>
54 void transformImage(MipMap* src, MipMap* dest, Functor func, std::vector<UpdateInfo>& ROIlist, const long stamp) {
55  for (typename std::vector<UpdateInfo>::iterator ROI = ROIlist.begin(); ROI != ROIlist.end(); ++ROI) {
56  const int level = ROI->ROI->mipmapLevel;
57 
58  const unsigned int srcNumOfTilesHoriz = (*src)[level]->getNumOfTilesHoriz();
59  const unsigned int srcNumOfTilesVert = (*src)[level]->getNumOfTilesVert();
60 
61  const unsigned int destNumOfTilesHoriz = (*dest)[level]->getNumOfTilesHoriz();
62  const unsigned int destNumOfTilesVert = (*dest)[level]->getNumOfTilesVert();
63  const unsigned int destTileExtent = (*dest)[level]->getTileExtent();
64 
65  transformImage_impl(*static_cast<ImageBuffer<InPixelType>*>((*src)[level]), *static_cast<ImageBuffer<OutPixelType>*>((*dest)[level]),
66  func, srcNumOfTilesHoriz, destNumOfTilesHoriz, srcNumOfTilesVert,
67  destNumOfTilesVert, destTileExtent, *(ROI->ROI), stamp);
68  }
69 }
70 
71 template <ValueType::Enum PixelType, typename Functor>
72 void transformImage(MipMap* src, MipMap* dest, Functor func, std::vector<UpdateInfo>& ROIlist, const long stamp) {
73  transformImage<PixelType, PixelType>(src, dest, func, ROIlist, stamp);
74 }
75 
81 template <ValueType::Enum InPixelType, ValueType::Enum OutPixelType, typename Functor>
82 void transformImage(ImageBuffer<InPixelType>& src, ImageBuffer<OutPixelType>& dest, Functor func, std::vector<ROIinfo>& ROIlist, const long stamp) {
83  if ((src.getWidth() != dest.getWidth()) || (src.getHeight() != dest.getHeight())) {
84  // TODO: throw an exception
85  return;
86  }
87 
88  const unsigned int srcNumOfTilesHoriz = src.getNumOfTilesHoriz();
89  const unsigned int srcNumOfTilesVert = src.getNumOfTilesVert();
90 
91  const unsigned int destNumOfTilesHoriz = dest.getNumOfTilesHoriz();
92  const unsigned int destNumOfTilesVert = dest.getNumOfTilesVert();
93  const unsigned int destTileExtent = dest.getTileExtent();
94 
95  for (typename std::vector<ROIinfo>::iterator ROI = ROIlist.begin(); ROI != ROIlist.end(); ++ROI) {
96  transformImage_impl(src, dest, func, srcNumOfTilesHoriz, destNumOfTilesHoriz, srcNumOfTilesVert,
97  destNumOfTilesVert, destTileExtent, *ROI, stamp);
98  }
99 }
100 
101 template <ValueType::Enum InPixelType, ValueType::Enum OutPixelType, typename Functor>
102 void transformImage_impl(ImageBuffer<InPixelType>& src, ImageBuffer<OutPixelType>& dest, Functor func,
103  const unsigned int srcNumOfTilesHoriz, const unsigned int destNumOfTilesHoriz,
104  const unsigned int srcNumOfTilesVert, const unsigned int destNumOfTilesVert,
105  const unsigned int destTileExtent, ROIinfo &ROI, const long stamp)
106 {
107  const unsigned int startTileVert = ROI.y / destTileExtent;
108  unsigned int endTileVert = std::ceil((ROI.y + ROI.sizeY) / (double)destTileExtent);
109  const unsigned int startTileHoriz = ROI.x / destTileExtent;
110  unsigned int endTileHoriz = std::ceil((ROI.x + ROI.sizeX) / (double)destTileExtent);
111 
112  if ((srcNumOfTilesHoriz == destNumOfTilesHoriz) && (srcNumOfTilesVert == destNumOfTilesVert) &&
113  (destTileExtent == src.getTileExtent()))
114  {
115  const unsigned int destTilePixels = destTileExtent * destTileExtent;
116 
117  for (unsigned int tileVert = startTileVert; tileVert < endTileVert; tileVert++) {
118  for (unsigned int tileHoriz = startTileHoriz; tileHoriz < endTileHoriz; tileHoriz++) {
119  Tile<OutPixelType>* destTile = dest.getTile(tileHoriz, tileVert);
120  if (destTile->getStamp() != stamp) {
121  boost::this_thread::interruption_point();
122  typename Tile<InPixelType>::Iterator srcIt = src.getTile(tileHoriz, tileVert)->upperLeft();
123  typename Tile<OutPixelType>::Iterator destIt = destTile->upperLeft();
124 
125  unsigned int pixel = destTilePixels;
126  do {
127  --pixel;
128  func(*srcIt, *destIt);
129 
130  ++srcIt;
131  ++destIt;
132  } while (pixel != 0);
133  destTile->setStamp(stamp);
134  }
135  }
136  }
137  } else {
138  // transformation when the number and the size of tiles are different
139  unsigned int yoffset = 0;
140  for (unsigned int tileVert = startTileVert; tileVert < endTileVert; tileVert++, yoffset += destTileExtent) {
141  unsigned int xoffset = 0;
142  for (unsigned int tileHoriz = startTileHoriz; tileHoriz < endTileHoriz; tileHoriz++, xoffset += destTileExtent) {
143  Tile<OutPixelType>* destTile = dest.getTile(tileHoriz, tileVert);
144  if (destTile->getStamp() != stamp) {
145  typename ImageBuffer<InPixelType>::Iterator srcIt = src.upperLeft();
146  typename Tile<OutPixelType>::Iterator destIt = destTile->upperLeft();
147 
148  for (unsigned int y = 0; y < destTileExtent; ++y) {
149  srcIt.moveTo(xoffset, yoffset + y);
150  for (unsigned int x = 0; x < destTileExtent; ++x) {
151  func(*srcIt, *destIt);
152 
153  ++srcIt;
154  ++destIt;
155  }
156  }
157 
158  destTile->setStamp(stamp);
159  }
160  }
161  }
162  }
163 }
164 
165 }
166 
167 #endif