PICCANTE  0.4
The hottest HDR imaging library!
discrete_cosine_transform.hpp
Go to the documentation of this file.
1 /*
2 
3 PICCANTE
4 The hottest HDR imaging library!
5 http://vcg.isti.cnr.it/piccante
6 
7 Copyright (C) 2014
8 Visual Computing Laboratory - ISTI CNR
9 http://vcg.isti.cnr.it
10 First author: Francesco Banterle
11 
12 This Source Code Form is subject to the terms of the Mozilla Public
13 License, v. 2.0. If a copy of the MPL was not distributed with this
14 file, You can obtain one at http://mozilla.org/MPL/2.0/.
15 
16 */
17 
18 #ifndef PIC_ALGORITHMS_DISCRETE_COSINE_TRANSFORM_HPP
19 #define PIC_ALGORITHMS_DISCRETE_COSINE_TRANSFORM_HPP
20 
21 #include "../image.hpp"
22 #include "../util/tile_list.hpp"
23 
24 namespace pic {
25 
30 class DCT
31 {
32 public:
33 
37  DCT()
38  {
39  }
40 
48  static Image *transform(Image *imgIn, Image *imgOut, int size = 8)
49  {
50  if(imgIn == NULL) {
51  return imgOut;
52  }
53 
54  if(imgOut == NULL) {
55  imgOut = imgIn->allocateSimilarOne();
56  }
57 
58  if(size < 1) {
59  size = 8;
60  }
61 
62  float size2 = float(size * 2);
63  float squareRoot2 = sqrtf(2.0f);
64  float squareRoot = sqrtf(2.0f / float(size));
65  float squareRootPow2 = squareRoot * squareRoot;
66 
67  int channels = imgIn->channels;
68 
69  TileList tiles(size, imgOut->width, imgOut->height);
70 
71  for(unsigned int t = 0; t < tiles.tiles.size(); t++) {
72  BBox box = tiles.getBBox(t);
73 
74  for(int v = box.y0; v < box.y1; v++) {
75  int vr = v % size;
76 
77  for(int u = box.x0; u < box.x1; u++) {
78  int ur = u % size;
79 
80  float *dataOut = (*imgOut)(u, v);
81 
82  for(int p = 0; p < channels; p++) {
83  dataOut[p] = 0.0f;
84  }
85 
86  for(int y = 0; y < size; y++) {
87  int yi = y + box.y0;
88  int val = vr * (2 * y + 1);
89  float cosU = cosf(C_PI * float(val) / size2);
90 
91  for(int x = 0; x < size; x++) {
92  int xi = x + box.x0;
93  val = ur * (2 * x + 1);
94  float tot = cosU * cosf(C_PI * float(val) / size2);
95 
96  float *dataIn = (*imgIn)(xi, yi);
97 
98  for(int p = 0; p < channels; p++) {
99  dataOut[p] += tot * dataIn[p];
100  }
101  }
102  }
103 
104  if(ur == 0) {
105  for(int p = 0; p < channels; p++) {
106  dataOut[p] /= squareRoot2;
107  }
108  }
109 
110  if(vr == 0) {
111  for(int p = 0; p < channels; p++) {
112  dataOut[p] /= squareRoot2;
113  }
114  }
115 
116  for(int p = 0; p < channels; p++) {
117  dataOut[p] *= squareRootPow2;
118  }
119  }
120  }
121  }
122 
123  return imgOut;
124  }
125 
133  static Image *inverse(Image *imgIn, Image *imgOut, int size = 8)
134  {
135  if(imgIn == NULL) {
136  return imgOut;
137  }
138 
139  if(imgOut == NULL) {
140  imgOut = imgIn->allocateSimilarOne();
141  }
142 
143  if(size < 1) {
144  size = 8;
145  }
146 
147  float size2 = float(size * 2);
148  float squareRoot2 = sqrtf(2.0f);
149  float squareRoot = sqrtf(2.0f / float(size));
150  float squareRootPow2 = squareRoot * squareRoot;
151 
152  int channels = imgIn->channels;
153 
154  TileList tiles(size, imgOut->width, imgOut->height);
155 
156  for(unsigned int t = 0; t < tiles.tiles.size(); t++) {
157  BBox box = tiles.getBBox(t);
158 
159  for(int y = box.y0; y < box.y1; y++) {
160  int yr = y % size;
161 
162  for(int x = box.x0; x < box.x1; x++) {
163  int xr = x % size;
164 
165  float *dataOut = (*imgOut)(x, y);
166 
167  for(int p = 0; p < channels; p++) {
168  dataOut[p] = 0.0f;
169  }
170 
171  for(int v = 0; v < size; v++) {
172  int vi = box.y0 + v;
173  int val = v * (2 * yr + 1);
174  float cosU = cosf(C_PI * float(val) / size2);
175 
176  if(v == 0) {
177  cosU /= squareRoot2;
178  }
179 
180  for(int u = 0; u < size; u++) {
181  int ui = box.x0 + u;
182  val = u * (2 * xr + 1);
183  float tot = cosU * cosf(C_PI * float(val) / size2);
184 
185  if(u == 0) {
186  tot /= squareRoot2;
187  }
188 
189  float *dataIn = (*imgIn)(ui, vi);
190 
191  for(int p = 0; p < channels; p++) {
192  dataOut[p] += tot * dataIn[p];
193  }
194  }
195  }
196 
197  for(int p = 0; p < channels; p++) {
198  dataOut[p] *= squareRootPow2;
199  }
200  }
201  }
202  }
203 
204  return imgOut;
205  }
206 };
207 
208 } // end namespace pic
209 
210 #endif /* PIC_ALGORITHMS_DISCRETE_COSINE_TRANSFORM_HPP */
211 
The BBox class manages the creation of bounding boxes for images.
Definition: bbox.hpp:29
int channels
Definition: image.hpp:80
int x0
Definition: bbox.hpp:32
BBox getBBox(int index)
genBBox
const float C_PI
Definition: math.hpp:50
The DCT class provides a reference implementation for Discret Cosine Transform.
Definition: discrete_cosine_transform.hpp:30
static Image * inverse(Image *imgIn, Image *imgOut, int size=8)
inverse computes the inverse DCT transformation.
Definition: discrete_cosine_transform.hpp:133
int y0
Definition: bbox.hpp:32
The TileList class.
Definition: tile_list.hpp:33
static Image * transform(Image *imgIn, Image *imgOut, int size=8)
transform computes the forward DCT transformation.
Definition: discrete_cosine_transform.hpp:48
DCT()
DCT.
Definition: discrete_cosine_transform.hpp:37
int x1
Definition: bbox.hpp:32
The Image class stores an image as buffer of float.
Definition: image.hpp:60
int y1
Definition: bbox.hpp:32
Image * allocateSimilarOne()
allocateSimilarOne creates an Image with similar size of the calling instance.
Definition: bilateral_separation.hpp:25
int width
Definition: image.hpp:80
int height
Definition: image.hpp:80
std::vector< Tile > tiles
tiles a list of tiles
Definition: tile_list.hpp:50