Initial commit
[distort.git] / distort.cc
1 /*
2    Distort v1.0, written by Francois FLEURET
3    Contact francois.fleuret@inria.fr for info & bugs reports
4    THIS SOURCE IS VERY DIRTY, I KNOW IT :p
5 */
6
7 #include <iostream.h>
8 #include <fstream.h>
9
10 #include "pictures.h"
11
12 float abs(float x) { if(x>0) return x; else return -x; }
13
14 int main(int argc, char **argv)
15 {
16   Picture org;
17   int block_size, result_w, result_h, w, h;
18
19   int c;
20   float xa, ya, alpha_x, alpha_y, s;
21   int x, y, xx, yy;
22
23   if(argc != 5)
24     {
25       cerr<<"\nusage : "<<argv[0]<<" <block size> <gride file> <source pic> <result pic>\n\n";
26       cerr<<" <block size> is an integer\n";
27       cerr<<" <gride file> is the name of a gride file\n";
28       cerr<<" <source pic> is a pictures name, wich have to be in pgm or ppm format\n";
29       cerr<<" <result pic> is the result picture name, wich will be in pgm\n\n";
30       exit(1);
31     }
32
33   block_size = atoi(argv[1]);
34
35   cerr<<"Blocks : "<<block_size<<"x"<<block_size<<" gride file : "<<argv[2]
36     <<" source picture "<<argv[3]<<" result picture : "<<argv[4]<<"\n";
37
38   cerr<<"Loading "<<argv[3]<<" ... "; cout.flush();
39   org.LoadPpm(argv[3]);
40   cerr<<"done\n"; cout.flush();
41
42   cerr<<"Loading gride ... "; cout.flush();
43
44   ifstream gride_file(argv[2]);
45
46   if(!gride_file.fail()) gride_file>>w>>h;
47
48   float x_v[w*h], y_v[w*h];
49
50   if(!gride_file.fail())
51     {
52       for(y=0; y<h; y++)
53         for(x=0; x<w; x++) gride_file>>x_v[x + y*w]>>y_v[x + y*w];
54     };
55
56   cerr<<"done\n"; cout.flush();
57
58   cerr<<"Gride "<<w<<"x"<<h<<" with blocks size "<<block_size<<"\n";
59
60   result_w = (w-1)*block_size;
61   result_h = (h-1)*block_size;
62
63   Picture result(result_w, result_h);
64
65   float g, g_nw, g_ne, g_se, g_sw;
66   int xa_e, ya_e;
67
68   cerr<<"Correcting picture ... "; cout.flush();
69
70   for(x = 0; x<w-1; x++)
71     for(y=0; y<h-1; y++)
72       {
73         for(xx = 0; xx<block_size; xx++)
74           for(yy = 0; yy<block_size; yy++)
75             {
76               alpha_x = 1-float(xx)/block_size;
77               alpha_y = 1-float(yy)/block_size;
78
79               xa =
80                 alpha_x * alpha_y * x_v[x + y*w] +
81                   (1-alpha_x) * alpha_y * x_v[x+1 + y*w] + 
82                     alpha_x * (1 - alpha_y) * x_v[x + (y+1)*w] +
83                       (1-alpha_x) * (1- alpha_y) * x_v[x+1 + (y+1)*w];
84               
85               ya =
86                 alpha_x * alpha_y * y_v[x + y*w] +
87                   (1-alpha_x) * alpha_y * y_v[x+1 + y*w] + 
88                     alpha_x * (1 - alpha_y) * y_v[x + (y+1)*w] +
89                       (1-alpha_x) * (1- alpha_y) * y_v[x+1 + (y+1)*w];
90
91               xa_e = int(xa); alpha_x = 1-(xa-float(xa_e));
92               ya_e = int(ya); alpha_y = 1-(ya-float(ya_e));
93
94               g_nw = org.GetComponent(xa_e, ya_e, PIC_RED);
95               g_ne = org.GetComponent(xa_e+1, ya_e, PIC_RED);
96               g_se = org.GetComponent(xa_e+1, ya_e+1, PIC_RED);
97               g_sw = org.GetComponent(xa_e, ya_e+1, PIC_RED);
98
99               g = g_nw*alpha_x*alpha_y + g_ne*(1-alpha_x)*alpha_y +
100                 g_se*(1-alpha_x)*(1-alpha_y) + g_sw*alpha_x*(1-alpha_y);
101
102               for(c=0; c<PIC_DEPTH; c++)
103                 result.SetComponent(x*block_size + xx, y*block_size+yy, c, g);
104             }
105       }
106   cerr<<"done\n"; cout.flush();
107
108   cerr<<"Saving in "<<argv[4]<<" ... "; cout.flush();
109   result.SavePpm(argv[4]);
110   cerr<<"done\n"; cout.flush();
111 }