Diff of /remap.c [000000] .. [2a97a8]  Maximize  Restore

  Switch to unified view

a b/remap.c
1
/* Panorama_Tools -   Generate, Edit and Convert Panoramic Images
2
   Copyright (C) 1998,1999 - Helmut Dersch  der@fh-furtwangen.de
3
   
4
   This program is free software; you can redistribute it and/or modify
5
   it under the terms of the GNU General Public License as published by
6
   the Free Software Foundation; either version 2, or (at your option)
7
   any later version.
8
9
   This program is distributed in the hope that it will be useful,
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
   GNU General Public License for more details.
13
14
   You should have received a copy of the GNU General Public License
15
   along with this program; if not, write to the Free Software
16
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
17
18
/*------------------------------------------------------------*/
19
20
#include "filter.h"
21
22
23
  
24
25
void remap(TrformStr *TrPtr, rPrefs *r_prefs)
26
{
27
  fDesc fD;                               // remapping function
28
  double  vars[3];                        // variables required for calculation
29
                                          // vars[0] = distance d
30
                                          // vars[1] 
31
                                          // vars[2] 
32
  double  a,b;                            // horizontal/vertical field of view in 'rad'
33
  int     destwidth, destheight;
34
35
  
36
  fD.param    = (void*) vars;
37
  fD.func     = (trfn)NULL;
38
  
39
  
40
  // Check for inconsistent values (should be extended!)
41
  
42
  if( r_prefs->hfov <= 0.0  )
43
  {
44
      TrPtr->success = 0;
45
      PrintError("Parameter Error");
46
      return;
47
  }
48
49
  
50
  // Set destination image parameters and parameters for remapping
51
  
52
  a = DEG_TO_RAD( r_prefs->hfov );
53
  
54
  switch(r_prefs->from)
55
  {
56
      case _rectilinear:  
57
          if( a >= PI )
58
          {
59
              TrPtr->success = 0;
60
              PrintError("Wrong FOV: Must be smaller than 180 degrees");
61
              return;
62
          }
63
          vars[0] = TrPtr->src->width / ( 2.0 * tan( a/2.0 ) );
64
          switch(r_prefs->to)
65
          {
66
              case _rectilinear:  TrPtr->success = 0;
67
                          PrintError("Same Mapping!");
68
                          return;
69
                          break;
70
              case _panorama   :  
71
                          destheight = TrPtr->src->height;
72
                          destwidth = a * vars[0] + 0.5;
73
                          fD.func = rect_pano;
74
                          break;
75
              case _equirectangular:
76
                          destheight  = 2.0 * vars[0] * atan( TrPtr->src->height/(2*vars[0]) ) + 0.5;                         
77
                          destwidth = a * vars[0] + 0.5;
78
                          fD.func = rect_erect;
79
                          break;
80
              case _spherical_cp:TrPtr->success = 0;
81
                          PrintError("Use Fisheye Horizontal and Perspective");
82
                          return;
83
                          break;
84
              case _spherical_tp:
85
                          destheight  = 2.0 * vars[0] * atan( TrPtr->src->height/(2*vars[0]) ) + 0.5;
86
                          destwidth   =  a * vars[0] + 0.5;
87
                          fD.func = rect_sphere_tp;
88
                          break;
89
              case _mirror:TrPtr->success = 0;
90
                          PrintError("Sorry, not yet available");
91
                          return;
92
                          break;
93
              default: break;
94
          }
95
          break;
96
      case _panorama:
97
          vars[0] = TrPtr->src->width / a;
98
          switch(r_prefs->to)
99
          {
100
              case _rectilinear: 
101
                          if( a >= PI )
102
                          {
103
                              TrPtr->success = 0;
104
                              PrintError("Wrong FOV: Must be smaller than 180 degrees");
105
                              return;
106
                          }
107
                          destheight = TrPtr->src->height;
108
                          destwidth = 2.0 * tan( a/2.0 ) * vars[0] + 0.5;
109
                          fD.func = pano_rect;
110
                          break;
111
              case _panorama   :  TrPtr->success = 0;
112
                          PrintError("Same Mapping!");
113
                          return;
114
                          break;
115
              case _equirectangular:
116
                          destheight =  2 * vars[0] * atan( TrPtr->src->height/ (2*vars[0]) );
117
                          destwidth = TrPtr->src->width;
118
                          fD.func = pano_erect;
119
                          break;
120
              case _spherical_cp:
121
                          TrPtr->success = 0;
122
                          PrintError("Sorry, not yet available");
123
                          return;
124
                          break;
125
              case _spherical_tp:                         
126
                          destheight =  TrPtr->src->width ;//2 * vars[0] * atan( TrPtr->src->height/ (2*vars[0]) );
127
                          destwidth = TrPtr->src->width;
128
                          fD.func = pano_sphere_tp;
129
                          break;
130
              case _mirror:TrPtr->success = 0;
131
                          PrintError("Sorry, not yet available");
132
                          return;
133
                          break;
134
              default: break;
135
          }
136
          break;
137
      case _equirectangular:
138
          vars[0] = TrPtr->src->width / a;
139
          b       = TrPtr->src->height/ vars[0];
140
          switch(r_prefs->to)
141
          {
142
              case _rectilinear:
143
                          if( a >= PI || b >= PI )
144
                          {
145
                              TrPtr->success = 0;
146
                              PrintError("Wrong FOV: Must be smaller than 180 degrees");
147
                              return;
148
                          }
149
                          destheight = 2 * vars[0] * tan( TrPtr->src->height/(2*vars[0]) );
150
                          destwidth  = 2 * vars[0] * tan( TrPtr->src->width/(2*vars[0]) );
151
                          fD.func = erect_rect;
152
                          break;
153
              case _panorama   :
154
                          if( b >= PI )
155
                          {
156
                              TrPtr->success = 0;
157
                              PrintError("Wrong VFOV: Must be smaller than 180 degrees");
158
                              return;
159
                          }
160
                          destheight = 2 * vars[0] * tan( TrPtr->src->height/(2*vars[0]) );
161
                          destwidth = TrPtr->src->width;
162
                          fD.func = erect_pano;
163
                          break;
164
              case _equirectangular:TrPtr->success = 0;
165
                          PrintError("Same Mapping!");
166
                          return;
167
                          break;
168
              case _spherical_cp: 
169
                          destwidth   = 2 * TrPtr->src->height;
170
                          destheight  = 2 * TrPtr->src->height;
171
                          vars[1] = TrPtr->src->height/2; // vars[1] is midpoint
172
                          fD.func = erect_sphere_cp;
173
                          break;
174
              case _spherical_tp:
175
                          destwidth   = TrPtr->src->width;
176
                          destheight  = TrPtr->src->width;
177
                          fD.func = erect_sphere_tp;
178
                          break;
179
              case _mirror:TrPtr->success = 0;
180
                          PrintError("Sorry, not yet available");
181
                          return;
182
                          break;
183
              default: break;
184
          }
185
          break;
186
      case _spherical_cp:
187
          if( r_prefs->hfov > MAX_FISHEYE_FOV ){
188
              TrPtr->success = 0;
189
              PrintError("Fisheye lens processing limited to fov <= %lg", MAX_FISHEYE_FOV);
190
              return;
191
          }
192
          vars[0] = TrPtr->src->width / a;
193
          switch(r_prefs->to)
194
          {
195
              case _rectilinear:TrPtr->success = 0;
196
                          PrintError("Sorry, not yet available");
197
                          return; 
198
                          break;
199
              case _panorama   :
200
                          if(r_prefs->vfov >= 180.0 )
201
                          {
202
                              TrPtr->success = 0;
203
                              PrintError("Wrong VFOV: Must be smaller than 180 degrees");
204
                              return;
205
                          }
206
                          destheight = PI * vars[0] * tan(r_prefs->vfov * PI / 360.0);
207
                          destwidth  = PI * vars[0] * PI;
208
                          fD.func = sphere_cp_pano;
209
                          break;
210
              case _equirectangular:
211
                          destheight  =  (TrPtr->src->width > TrPtr->src->height ? 
212
                                                      TrPtr->src->width/2: TrPtr->src->height/2) * PI / 2.0;
213
                          destwidth       = vars[0] *  PI * PI;
214
                          vars[1]                 = destheight / 2;
215
216
                          fD.func = sphere_cp_erect;
217
                          break;
218
              case _spherical_cp:TrPtr->success = 0;
219
                          PrintError("Same Mapping!");
220
                          return;
221
                          break;
222
              case _spherical_tp:TrPtr->success = 0;
223
                          PrintError("Use tool perspective.");
224
                          return;
225
                          break;
226
              case _mirror:
227
                          vars[1] = TrPtr->src->width / (2 * sin(a/4.0)) ; // Radius of mirror
228
                          destwidth  = TrPtr->src->width ;
229
                          destheight = TrPtr->src->height ;
230
                          fD.func = sphere_cp_mirror;
231
                          break;
232
              default: break;
233
          }
234
          break;
235
      case _spherical_tp:
236
          if( r_prefs->hfov > MAX_FISHEYE_FOV ){
237
              TrPtr->success = 0;
238
              PrintError("Fisheye lens processing limited to fov <= %lg", MAX_FISHEYE_FOV);
239
              return;
240
          }
241
          vars[0] = TrPtr->src->width / a;
242
          b = TrPtr->src->height / vars[0]; 
243
          switch(r_prefs->to)
244
          {
245
              case _rectilinear:
246
                          if( a >= PI || b >= PI )
247
                          {
248
                              TrPtr->success = 0;
249
                              PrintError("Wrong FOV: Must be smaller than 180 degrees");
250
                              return;
251
                          }
252
                          destheight      = 2.0 * vars[0] * tan( TrPtr->src->height / (2.0*vars[0]) ) + 0.5;
253
                          destwidth       = 2.0 * tan( a/2.0 ) * vars[0] + 0.5;
254
                          fD.func = sphere_tp_rect;
255
                          break;
256
              case _panorama   :
257
                          if(  b >= PI )
258
                          {
259
                              TrPtr->success = 0;
260
                              PrintError("Wrong VFOV: Must be smaller than 180 degrees");
261
                              return;
262
                          }
263
                          destheight  = 2.0 * vars[0] * tan( TrPtr->src->height / (2.0*vars[0]) ) + 0.5;
264
                          destwidth   = TrPtr->src->width;
265
                          fD.func = sphere_tp_pano;
266
                          break;
267
              case _equirectangular:
268
                          destheight  = TrPtr->src->height ;
269
                          destwidth   = TrPtr->src->width;
270
                          vars[1]                         = destheight / 2;
271
                          fD.func = sphere_tp_erect;
272
                          break;
273
              case _spherical_cp:TrPtr->success = 0;
274
                          PrintError("Use tool perspective.");
275
                          return;
276
                          break;
277
              case _spherical_tp:TrPtr->success = 0;
278
                          PrintError( "Same Mapping!");
279
                          return;
280
                          break;
281
              case _mirror:TrPtr->success = 0;
282
                          PrintError( "Sorry, not yet available");
283
                          return;
284
                          break;
285
              default: break;
286
          }
287
          break;
288
      case _mirror:
289
          vars[1] = TrPtr->src->width / (2 * sin(a/4.0)) ; // Radius of mirror
290
          vars[0] = TrPtr->src->width / a;
291
          switch(r_prefs->to)
292
          {
293
              case _rectilinear:TrPtr->success = 0;
294
                          PrintError("Sorry, not yet available");
295
                          return;
296
                          break;
297
              case _panorama   :                          
298
                          if(r_prefs->vfov >= 180.0 )
299
                          {
300
                              TrPtr->success = 0;
301
                              PrintError("Wrong VFOV: Must be smaller than 180 degrees");
302
                              return;
303
                          }
304
                          destheight = PI * vars[0] * tan(r_prefs->vfov * PI / 360.0);
305
                          destwidth  = PI * vars[0] *  PI;
306
                          fD.func = mirror_pano;
307
                          break;
308
              case _equirectangular:
309
                          destwidth  = vars[0] *  PI * PI; 
310
                          destheight = PI * vars[0] * a / 4.0 ;
311
                          vars[2] = destheight / 2.0;
312
                          fD.func = mirror_erect;
313
                          break;
314
              case _spherical_cp:
315
                          destwidth  = TrPtr->src->width ;
316
                          destheight = TrPtr->src->height ;
317
                          fD.func = mirror_sphere_cp;
318
                          break;
319
              case _spherical_tp:TrPtr->success = 0;
320
                          PrintError( "Sorry, not yet available");
321
                          return;
322
                          break;
323
              case _mirror:TrPtr->success = 0;
324
                          PrintError( "Same Mapping!");
325
                          return;
326
                          break;
327
              default: break;
328
          }
329
          break;
330
      default: break;
331
  }
332
333
334
  
335
  if( SetDestImage(TrPtr, destwidth, destheight) != 0 ) 
336
  {
337
      TrPtr->success = 0;
338
      PrintError( "Not enough Memory.");
339
      return; 
340
  }
341
  
342
  // Do transformation
343
344
  if( fD.func != NULL)
345
  {
346
      transForm( TrPtr, &fD, 0 );
347
  }
348
  else
349
      TrPtr->success = 0;
350
351
  if( TrPtr->success == 0 && ! (TrPtr->mode & _destSupplied)) // Moved here
352
                  myfree( (void**)TrPtr->dest->data );
353
354
}
355
356
void SetRemapDefaults( rPrefs *rP )
357
{
358
  rP->magic   = 30;               // Magic number for file validity check
359
  rP->from    = _rectilinear;
360
  rP->to      = _panorama;
361
  rP->hfov    = 60.0;
362
  rP->vfov    = 60.0;
363
364
}
365
366

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks