1 /* Panorama_Tools - Generate, Edit and Convert Panoramic Images
2 Copyright (C) 1998,1999 - Helmut Dersch der@fh-furtwangen.de
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)
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.
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. */
18 /*------------------------------------------------------------*/
24 #include "utils_math.h"
26 #define DEG_TO_RAD(x) ((x) * 2.0 * M_PI / 360.0 )
28 // Lookup Tables for Trig-functions and interpolator
37 void matrix_matrix_mult ( double m1[3][3],double m2[3][3],double result[3][3]);
38 void PV_transForm( TrformStr *TrPtr, double dist_r, double dist_e, int mt[3][3]);
39 int PV_sqrt( int x1, int x2 );
43 * Extract image from pano in TrPtr->src using parameters in prefs (ignore
44 * image parameters in TrPtr)
46 void PV_ExtractStill( TrformStr *TrPtr )
48 /* field of view in rad */
56 a = DEG_TO_RAD( TrPtr->dest->hfov ); // field of view in rad
57 b = DEG_TO_RAD( TrPtr->src->hfov );
59 /* Set up the transformation matrix `mt' using Euler angles (somehow..) */
60 SetMatrix (DEG_TO_RAD (TrPtr->dest->pitch), /* alpha */
61 DEG_TO_RAD (TrPtr->dest->yaw), /* beta */
67 p[0] = (double)TrPtr->dest->width/ (2.0 * tan( a / 2.0 ) );
68 p[1] = (double) TrPtr->src->width / b;
72 mi[i][k] = 256 * mt[i][k];
77 PV_transForm( TrPtr, p[0], p[1], mi);
81 typedef enum interpolator_e
87 static int copy_pixel (Image *dest, Image *src,
88 int x_dest, int y_dest,
89 double x_src_fp, double y_src_fp,
90 interpolator_t interp)
93 uint32_t *src_data = (uint32_t *) (*src->data);
94 uint32_t *dest_data = (uint32_t *) (*dest->data);
98 if (interp == NNEIGHBOUR)
100 int x_src = (int) (x_src_fp + 0.5) % src->width;
101 int y_src = (int) (y_src_fp + 0.5) % src->height;
103 if ((x_src < 0) || (x_src >= src->width)
104 || (y_src < 0) || (y_src >= src->height))
105 pixel_value = 0x000000FF;
107 pixel_value = src_data[(y_src * src->width) + x_src];
110 dest_data[(y_dest * dest->width) + x_dest] = pixel_value;
113 } /* int copy_pixel */
115 // Main transformation function. Destination image is calculated using transformation
116 // Function "func". Either all colors (color = 0) or one of rgb (color =1,2,3) are
117 // determined. If successful, TrPtr->success = 1. Memory for destination image
118 // must have been allocated and locked!
120 void PV_transForm( TrformStr *TrPtr, double dist_r, double dist_e, int mt[3][3])
122 int x_dest, y_dest; // Loop through destination image
123 unsigned char *dest,*src;// Source and destination image data
125 // Variables used to convert screen coordinates to cartesian coordinates
128 int dest_width_left = TrPtr->dest->width / 2 ;
129 int dest_height_top = TrPtr->dest->height / 2 ;
130 int src_width_left = TrPtr->src->width / 2 ;
131 int src_height_top = TrPtr->src->height / 2 ;
134 int x_min, x_max, y_min, y_max;
138 dr1 = mt[2][0] * dist_r;
139 dr2 = mt[2][1] * dist_r;
140 dr3 = mt[2][2] * dist_r;
142 dest = *TrPtr->dest->data;
143 src = *TrPtr->src->data; // is locked
145 x_min = -dest_width_left; x_max = TrPtr->dest->width - dest_width_left;
146 y_min = -dest_height_top; y_max = TrPtr->dest->height - dest_height_top;
148 for(y_dest = y_min; y_dest < y_max; y_dest++)
150 for(x_dest = x_min; x_dest < x_max; x_dest++)
155 v[0] = mt[0][0] * x_dest + mt[1][0] * y_dest + dr1;
156 v[1] = mt[0][1] * x_dest + mt[1][1] * y_dest + dr2;
157 v[2] = mt[0][2] * x_dest + mt[1][2] * y_dest + dr3;
159 v[0] = v[0] >> 8; v[2] = v[2] >> 8;
162 x_src_fp = dist_e * atan2 (v[0], v[2]);
163 y_src_fp = dist_e * atan2 (v[1], sqrt (v[2] * v[2] + v[0] * v[0]));
165 copy_pixel (TrPtr->dest, TrPtr->src,
166 dest_width_left + x_dest, dest_height_top + y_dest,
167 src_width_left + x_src_fp, src_height_top + y_src_fp,
176 void matrix_inv_mult( double m[3][3], double vector[3] )
179 register double v0 = vector[0];
180 register double v1 = vector[1];
181 register double v2 = vector[2];
185 vector[i] = m[0][i] * v0 + m[1][i] * v1 + m[2][i] * v2;
190 // Set matrix elements based on Euler angles a, b, c
192 void SetMatrix( double a, double b, double c , double m[3][3], int cl )
194 double mx[3][3], my[3][3], mz[3][3], dummy[3][3];
197 // Calculate Matrices;
199 mx[0][0] = 1.0 ; mx[0][1] = 0.0 ; mx[0][2] = 0.0;
200 mx[1][0] = 0.0 ; mx[1][1] = cos(a) ; mx[1][2] = sin(a);
201 mx[2][0] = 0.0 ; mx[2][1] =-mx[1][2] ; mx[2][2] = mx[1][1];
203 my[0][0] = cos(b); my[0][1] = 0.0 ; my[0][2] =-sin(b);
204 my[1][0] = 0.0 ; my[1][1] = 1.0 ; my[1][2] = 0.0;
205 my[2][0] = -my[0][2]; my[2][1] = 0.0 ; my[2][2] = my[0][0];
207 mz[0][0] = cos(c) ; mz[0][1] = sin(c) ; mz[0][2] = 0.0;
208 mz[1][0] =-mz[0][1] ; mz[1][1] = mz[0][0] ; mz[1][2] = 0.0;
209 mz[2][0] = 0.0 ; mz[2][1] = 0.0 ; mz[2][2] = 1.0;
211 /* Calculate `m = mz * mx * my' */
214 matrix_matrix_mult( mz, mx, dummy);
216 matrix_matrix_mult( mx, mz, dummy);
217 matrix_matrix_mult( dummy, my, m);
218 } /* void SetMatrix */
220 void matrix_matrix_mult( double m1[3][3],double m2[3][3],double result[3][3])
226 result[i][k] = m1[i][0] * m2[0][k] + m1[i][1] * m2[1][k] + m1[i][2] * m2[2][k];
227 } /* void matrix_matrix_mult */
243 // Find last jpeg inside image; create and copy to file jpeg
244 int extractJPEG( fullPath *image, fullPath *jpeg )
252 if( myopen( image, read_bin, fnum ) )
256 count = 1; i=0; // Get file length
260 myread( fnum, count, &ch );
267 im = (UCHAR*)malloc( count );
270 PrintError("Not enough memory");
274 if( myopen( image, read_bin, fnum ) )
277 myread(fnum,count,im);
285 for(i=0; i<count; i++)
287 if( im[i] == ID_0 && im[i+1] == ID_1 && im[i+2] == ID_2 && im[i+3] == ID_3
288 && im[i+4] == ID_4 && im[i+5] == ID_5 && im[i+6] == ID_6 && im[i+7] == ID_7
289 && im[i+8] == ID_8 && im[i+9] == ID_9 && im[i+10] == ID_10)
293 if( idx == -1 ) // No jpeg found
299 count = count + ID_LENGTH - idx;
301 mycreate( jpeg, 'GKON','JPEG');
302 if( myopen( jpeg, write_bin, fnum ) )
304 mywrite( fnum, count, im+idx );
312 * vim: set tabstop=4 softtabstop=4 shiftwidth=4 :