1 /* -*- C++ -*-
2  *
3  *  This file is part of RawTherapee.
4  *
5  *  Copyright (c) 2018 Alberto Griggio <alberto.griggio@gmail.com>
6  *
7  *  RawTherapee is free software: you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation, either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  RawTherapee is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with RawTherapee.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #pragma once
22 
23 //#include "array2D.h"
24 
25 namespace rtengine {
26 
getBilinearValue(const array2D<float> & src,float x,float y)27 inline float getBilinearValue(const array2D<float> &src, float x, float y)
28 {
29     const int W = src.width();
30     const int H = src.height();
31 
32     // Get integer and fractional parts of numbers
33     int xi = x;
34     int yi = y;
35     float xf = x - xi;
36     float yf = y - yi;
37     int xi1 = std::min(xi + 1, W - 1);
38     int yi1 = std::min(yi + 1, H - 1);
39 
40     float bl = src[yi][xi];
41     float br = src[yi][xi1];
42     float tl = src[yi1][xi];
43     float tr = src[yi1][xi1];
44 
45     // interpolate
46     float b = xf * br + (1.f - xf) * bl;
47     float t = xf * tr + (1.f - xf) * tl;
48     float pxf = yf * t + (1.f - yf) * b;
49     return pxf;
50 }
51 
52 
rescaleBilinear(const array2D<float> & src,array2D<float> & dst,bool multithread)53 inline void rescaleBilinear(const array2D<float> &src, array2D<float> &dst, bool multithread)
54 {
55     const int Ws = src.width();
56     const int Hs = src.height();
57     const int Wd = dst.width();
58     const int Hd = dst.height();
59 
60     float col_scale = float (Ws) / float (Wd);
61     float row_scale = float (Hs) / float (Hd);
62 
63 #ifdef _OPENMP
64     #pragma omp parallel for if (multithread)
65 #endif
66 
67     for (int y = 0; y < Hd; ++y) {
68         float ymrs = y * row_scale;
69 
70         for (int x = 0; x < Wd; ++x) {
71             dst[y][x] = getBilinearValue(src, x * col_scale, ymrs);
72         }
73     }
74 }
75 
76 
rescaleNearest(const array2D<float> & src,array2D<float> & dst,bool multithread)77 inline void rescaleNearest(const array2D<float> &src, array2D<float> &dst, bool multithread)
78 {
79     const int width = src.width();
80     const int height = src.height();
81     const int nw = dst.width();
82     const int nh = dst.height();
83 
84 #ifdef _OPENMP
85     #pragma omp parallel for if (multithread)
86 #endif
87 
88     for (int y = 0; y < nh; ++y) {
89         int sy = y * height / nh;
90 
91         for (int x = 0; x < nw; ++x) {
92             int sx = x * width / nw;
93             dst[y][x] = src[sy][sx];
94         }
95     }
96 }
97 
98 
99 } // namespace rtengine
100