1
2 #include "filter.h"
3 #include "ptutils.h"
4 #include <locale.h>
5
6 #if _MSC_VER > 1000
7 #pragma warning(disable: 4100) // disable unreferenced formal parameter warning
8 #endif
9
10 void ReadMLine( char *script, char *m );
11 int loadProject( fullPath *fspec );
12 int writeProject( AlignInfo *g, fullPath *pFile);
13 int jpathTofullPath( const char* jpath, fullPath *fp );
14 void BackUp();
15 void Restore();
16 void SetAlignInfoDefaults( AlignInfo *a);
17
18
19 #define HELPERS "./Helpers/"
20
21 #ifdef __Mac__
22 #undef HELPERS
23 #define HELPERS ":Helpers:"
24 #endif
25
26 #ifdef WIN32
27 #undef HELPERS
28 #define HELPERS "Helpers\\"
29 #endif
30
31
32 AlignInfo *gl = NULL;
33 fullPath project;
34 void *theBackUp=NULL;
35 char mLine[256];
36
37
38 Image im;
39 int JavaUI = FALSE;
40 static JNIEnv *ptenv;
41 // since gPicker is already defined in ColorPicker.h I change picker to gPicker : Kekus Digital
42 //static jobject picker; //commented by Kekus Digital
43 static jobject gPicker;//added by Kekus Digital
44
45 #define SET_JAVA JavaUI = TRUE; ptenv = env; gPicker = obj;
46
JPrintError(char * text)47 void JPrintError( char* text ){
48 jclass cls = (*ptenv)->GetObjectClass(ptenv, gPicker);
49 jmethodID mid = (*ptenv)->GetMethodID(ptenv, cls, "PrintError", "(Ljava/lang/String;)V");
50 if (mid == 0) return;
51 (*ptenv)->CallVoidMethod(ptenv, gPicker, mid, (*ptenv)->NewStringUTF(ptenv, text));
52 }
53
54 #if 0
55 int JinfoDlg( int command, char* argument ){
56 jclass cls = (*ptenv)->GetObjectClass(ptenv, gPicker);
57 jmethodID mid = (*ptenv)->GetMethodID(ptenv, cls, "infoDlg", "(ILjava/lang/String;)I");
58 if (mid == 0) return -1;
59 (*ptenv)->CallIntMethod(ptenv, gPicker, mid, command, (*ptenv)->NewStringUTF(ptenv, argument));
60 }
61
62 int JProgress( int command, char* argument ){
63 jclass cls = (*ptenv)->GetObjectClass(ptenv, gPicker);
64 jmethodID mid = (*ptenv)->GetMethodID(ptenv, cls, "Progress", "(ILjava/lang/String;)I");
65 if (mid == 0) return -1;
66 (*ptenv)->CallIntMethod(ptenv, gPicker, mid, command, (*ptenv)->NewStringUTF(ptenv, argument));
67 }
68 #endif
Java_ptutils_CSaveProject(JNIEnv * env,jobject obj,jstring path)69 JNIEXPORT void JNICALL Java_ptutils_CSaveProject
70 (JNIEnv *env, jobject obj, jstring path){
71
72 const char *jpath = (*env)->GetStringUTFChars(env, path, 0);
73
74 SET_JAVA
75
76
77 if( strlen(jpath) > 0 ){
78 if( jpathTofullPath( jpath, &project ) != 0 ){
79 PrintError("Could not create Path from %s", jpath);
80 return;
81 }
82 }
83 (*env)->ReleaseStringUTFChars(env, path, jpath);
84 writeProject( gl, &project);
85 }
86
87
88
Java_ptutils_CSetControlPointCount(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED,jint nc)89 JNIEXPORT void JNICALL Java_ptutils_CSetControlPointCount
90 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED, jint nc){
91 if( gl && nc != gl->numPts ){
92 free(gl->cpt);
93 gl->numPts = nc;
94 gl->cpt = (controlPoint*) malloc( gl->numPts * sizeof( controlPoint ) );
95 }
96 }
97
Java_ptutils_CSetCP(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED,jint i,jint n0,jint n1,jdouble x0,jdouble x1,jdouble y0,jdouble y1,jint type)98 JNIEXPORT void JNICALL Java_ptutils_CSetCP
99 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED, jint i, jint n0, jint n1, jdouble x0, jdouble x1, jdouble y0, jdouble y1, jint type){
100 if( gl && i < gl->numPts ){
101 controlPoint *c = &(gl->cpt[i]);
102 c->num[0] = n0;
103 c->num[1] = n1;
104 c->x[0] = x0;
105 c->x[1] = x1;
106 c->y[0] = y0;
107 c->y[1] = y1;
108 c->type = type;
109 }
110 }
111
Java_ptutils_CSetTriangleCount(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED,jint nt)112 JNIEXPORT void JNICALL Java_ptutils_CSetTriangleCount
113 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED, jint nt){
114 if( gl && nt != gl->nt ){
115 free( gl->t );
116 gl->nt = nt;
117 gl->t = (triangle*)malloc( gl->nt * sizeof(triangle) );
118 }
119 }
120
Java_ptutils_CSetTR(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED,jint i,jint v0,jint v1,jint v2,jint nIm)121 JNIEXPORT void JNICALL Java_ptutils_CSetTR
122 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED, jint i, jint v0, jint v1, jint v2, jint nIm){
123 if( gl && i< gl->nt ){
124 triangle *t = &(gl->t[i]);
125 t->vert[0] = v0;
126 t->vert[1] = v1;
127 t->vert[2] = v2;
128 t->nIm = nIm;
129 }
130 }
131
132
133
134
135
Java_ptutils_CLoadProject(JNIEnv * env,jobject obj,jstring path)136 JNIEXPORT void JNICALL Java_ptutils_CLoadProject
137 (JNIEnv *env, jobject obj, jstring path){
138
139 const char *jpath = (*env)->GetStringUTFChars(env, path, 0);
140
141 SET_JAVA
142
143 if( jpathTofullPath( jpath, &project ) != 0 ){
144 PrintError("Could not create fullpath from %s", jpath);
145 return;
146 }
147 (*env)->ReleaseStringUTFChars(env, path, jpath);
148
149 if( loadProject( &project ) != 0 ){
150 PrintError("Could not load Project");
151 return;
152 }
153 }
154
Java_ptutils_CGetImageCount(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED)155 JNIEXPORT jint JNICALL Java_ptutils_CGetImageCount
156 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED){
157 if( gl )
158 return (jint)gl->numIm;
159 else
160 return (jint)0;
161 }
162
Java_ptutils_CGetImageName(JNIEnv * env,jobject obj,jint nIm)163 JNIEXPORT jstring JNICALL Java_ptutils_CGetImageName
164 (JNIEnv *env, jobject obj, jint nIm){
165 SET_JAVA
166 if( gl )
167 return (*env)->NewStringUTF(env, gl->im[(int)nIm].name);
168 else
169 return (*env)->NewStringUTF(env, "");
170 }
171
Java_ptutils_CGetControlPointCount(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED)172 JNIEXPORT jint JNICALL Java_ptutils_CGetControlPointCount
173 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED){
174 if( gl )
175 return (jint)gl->numPts;
176 else
177 return (jint)0;
178 }
179
Java_ptutils_CGetCP_1n(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED,jint ncpt,jint nim)180 JNIEXPORT jint JNICALL Java_ptutils_CGetCP_1n
181 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED, jint ncpt, jint nim){
182 if(gl)
183 return (jint)gl->cpt[(int)ncpt].num[(int)nim];
184 else
185 return (jint) 0;
186 }
187
Java_ptutils_CGetCP_1x(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED,jint ncpt,jint nim)188 JNIEXPORT jdouble JNICALL Java_ptutils_CGetCP_1x
189 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED, jint ncpt, jint nim){
190 if( gl )
191 return (jdouble)gl->cpt[(int)ncpt].x[(int)nim];
192 else
193 return (jdouble) 0.0;
194 }
195
Java_ptutils_CGetCP_1y(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED,jint ncpt,jint nim)196 JNIEXPORT jdouble JNICALL Java_ptutils_CGetCP_1y
197 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED, jint ncpt, jint nim){
198 if(gl)
199 return (jdouble)gl->cpt[(int)ncpt].y[(int)nim];
200 else
201 return (jdouble) 0.0;
202 }
203
Java_ptutils_CGetCP_1t(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED,jint ncpt)204 JNIEXPORT jint JNICALL Java_ptutils_CGetCP_1t
205 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED, jint ncpt){
206 if( gl )
207 return (jint)gl->cpt[(int)ncpt].type;
208 else
209 return (jint ) 0;
210 }
211
Java_ptutils_CGetTriangleCount(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED)212 JNIEXPORT jint JNICALL Java_ptutils_CGetTriangleCount
213 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED){
214 if( gl )
215 return (jint)gl->nt;
216 else
217 return (jint ) 0;
218 }
219
Java_ptutils_CGetTR_1v(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED,jint ntr,jint nv)220 JNIEXPORT jint JNICALL Java_ptutils_CGetTR_1v
221 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED, jint ntr, jint nv){
222 if( gl )
223 return (jint)gl->t[(int)ntr].vert[(int)nv];
224 else
225 return (jint ) 0;
226 }
227
Java_ptutils_CGetTR_1i(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED,jint ntr)228 JNIEXPORT jint JNICALL Java_ptutils_CGetTR_1i
229 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED, jint ntr){
230 return (jint)gl->t[(int)ntr].nIm;
231 }
232
Java_ptutils_CSetImageName(JNIEnv * env,jobject obj PT_UNUSED,jint n,jstring jname)233 JNIEXPORT void JNICALL Java_ptutils_CSetImageName
234 (JNIEnv *env, jobject obj PT_UNUSED, jint n, jstring jname){
235 const char *name = (*env)->GetStringUTFChars(env, jname, 0);
236 if( n < gl->numIm ){
237 strcpy( gl->im[n].name, name );
238 }
239 (*env)->ReleaseStringUTFChars(env, jname, name);
240 }
241
Java_ptutils_CGetIndex(JNIEnv * env,jobject obj PT_UNUSED,jstring jname)242 JNIEXPORT jint JNICALL Java_ptutils_CGetIndex
243 (JNIEnv *env, jobject obj PT_UNUSED, jstring jname){
244
245 const char *name =(*env)->GetStringUTFChars(env, jname, 0);
246 jint i;
247
248 for( i=0; i<gl->numIm; i++){
249 if( strcmp( name, gl->im[i].name ) == 0 ){
250 (*env)->ReleaseStringUTFChars(env, jname, name);
251 return i;
252 }
253 }
254 (*env)->ReleaseStringUTFChars(env, jname, name);
255 return -1;
256 }
257
258
259
260
261
262
263
264
265
266
Java_ptutils_CLoadImage(JNIEnv * env,jobject obj,jint n)267 JNIEXPORT void JNICALL Java_ptutils_CLoadImage
268 (JNIEnv *env, jobject obj, jint n){
269 fullPath fp;
270
271 SET_JAVA
272
273 memcpy( &fp, &project, sizeof( fullPath ));
274 InsertFileName( &fp, gl->im[n].name );
275
276 SetImageDefaults(&im);
277
278 if( panoImageRead( &im, &fp ) != 0 ){
279 PrintError("Could not read image");
280 return;
281 }
282 TwoToOneByte( &im );
283
284 if( gl->im[n].cP.cutFrame ){
285 CropImage( &im, &gl->im[n].selection );
286 }
287
288 gl->im[n].width = im.width;
289 gl->im[n].height = im.height;
290
291 // If this is a new project, set params now
292
293 if(gl->im[n].hfov < 0.0)
294 {
295 int i;
296 double dYaw = 360.0 / (double)gl->numIm;
297 int numParam = 0;
298
299 // Calculate Field of view
300
301 if( gl->im[n].width < gl->im[n].height ) // portrait
302 {
303 if( gl->im[n].format == _rectilinear )
304 {
305 gl->im[n].hfov = 2.0 * atan( 12.0 / (-gl->im[n].hfov) );
306 }
307 else if ( gl->im[n].format == _fisheye_ff )
308 {
309 gl->im[n].hfov = 24.0 / (-gl->im[n].hfov);
310 }
311 else
312 gl->im[n].hfov = 4.0 * asin( 5.7 / (-gl->im[n].hfov) );
313 }
314 else // landscape
315 {
316 if( gl->im[n].format == _rectilinear )
317 {
318 gl->im[n].hfov = 2.0 * atan( 18.0 / (-gl->im[n].hfov) );
319 }
320 else if( gl->im[n].format == _fisheye_ff )
321 {
322 gl->im[n].hfov = 36.0 / (-gl->im[n].hfov);
323 }
324 else
325 gl->im[n].hfov = 4.0 * asin( 5.7 / (-gl->im[n].hfov) );
326 }
327 gl->im[n].hfov = /*RAD_TO_DEG*/(( gl->im[n].hfov) * 360.0 / ( 2.0 * PI ) );
328
329 if( gl->im[n].hfov < dYaw )
330 PrintError( "Warning: No overlap of images");
331
332 for(i=0; i<gl->numIm; i++)
333 {
334 gl->im[i].format = gl->im[n].format;
335 gl->im[i].hfov = gl->im[n].hfov;
336 gl->im[i].yaw = (double)i * dYaw;
337 gl->im[i].roll = 0.0;
338 gl->im[i].pitch = 0.0;
339
340 if( gl->im[i].format != _fisheye_circ )
341 {
342 // gl->opt[i].d = 1; numParam++;
343 // gl->opt[i].e = 1; numParam++;
344 }
345
346 if(i != 0) // pin first image
347 {
348 gl->opt[i].hfov = 2; // linked to image 1
349 gl->opt[i].yaw = 1; numParam++;
350 gl->opt[i].pitch = 1; numParam++;
351 gl->opt[i].roll = 1; numParam++;
352 }
353 else
354 {
355 gl->opt[i].hfov = 1; numParam++;
356 }
357 }
358
359 gl->numParam = numParam;
360
361 // Set pano dimensionw
362 gl->pano.width = (int32_t)(gl->im[n].width * gl->pano.hfov / gl->im[n].hfov);
363 gl->pano.width /= 10; gl->pano.width *= 10;
364
365
366
367 if( gl->pano.format == _equirectangular )
368 {
369 gl->pano.height = gl->pano.width / 2;
370 }
371 else // Cylinder
372 {
373 if( gl->im[n].format == _rectilinear )
374 gl->pano.height = (int32_t)(gl->im[n].height * cos( DEG_TO_RAD(dYaw) / 2.0 ));
375 else
376 {
377 double vfov = gl->im[n].hfov * (double)gl->im[n].height / (double)gl->im[n].width;
378
379
380 if( vfov < 180.0 )
381 gl->pano.height = (int32_t)(gl->im[n].height * tan( DEG_TO_RAD(vfov) / 2.0 ) * cos( DEG_TO_RAD(dYaw) / 2.0 ) / ( DEG_TO_RAD(vfov) / 2.0));
382 else
383 gl->pano.height = (int32_t)(gl->im[n].height * tan( DEG_TO_RAD(160.0) / 2.0 ) / ( DEG_TO_RAD(160.0) / 2.0));
384
385 gl->pano.height /= 10; gl->pano.height *= 10;
386 }
387
388
389 if( strcmp( gl->pano.name, "QTVR") == 0 )
390 {
391 gl->pano.width = gl->pano.width - (gl->pano.width % 96);
392 gl->pano.height= gl->pano.height - (gl->pano.height % 4);
393 }
394 }
395
396
397 }
398
399
400
401 }
402
403
404
Java_ptutils_CGetImageRow(JNIEnv * env,jobject obj PT_UNUSED,jintArray jdata,jint nrow)405 JNIEXPORT void JNICALL Java_ptutils_CGetImageRow
406 (JNIEnv *env, jobject obj PT_UNUSED, jintArray jdata, jint nrow){
407 if(im.data != NULL){
408 #ifdef PT_BIGENDIAN
409 (*env)->SetIntArrayRegion( env, jdata, 0, im.width ,
410 (jint*)((*im.data) + im.bytesPerLine * nrow) ) ;
411 #else
412 {
413 jint *row = (jint*)((*im.data) + im.bytesPerLine * nrow), pix;
414 unsigned char *p,*q;
415 int x;
416 q = (unsigned char*) &pix;
417 for(x=0; x<im.width; x++){
418 p = (unsigned char*) &(row[x]);
419 q[0] = p[3];
420 q[1] = p[2];
421 q[2] = p[1];
422 q[3] = p[0];
423 row[x] = pix;
424 }
425 }
426 (*env)->SetIntArrayRegion( env, jdata, 0, im.width ,
427 (jint*)((*im.data) + im.bytesPerLine * nrow) ) ;
428
429 #endif
430 if(nrow == im.height - 1){
431 myfree((void**)im.data);
432 SetImageDefaults(&im);
433 }
434 }
435 }
436
Java_ptutils_CGetImageWidth(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED,jint n)437 JNIEXPORT jint JNICALL Java_ptutils_CGetImageWidth
438 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED, jint n){
439 if( n == -1 )
440 return (jint)gl->pano.width;
441 if( im.data != NULL )
442 return (jint)gl->im[n].width;
443 else
444 return (jint)0;
445 }
446
Java_ptutils_CGetImageHeight(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED,jint n)447 JNIEXPORT jint JNICALL Java_ptutils_CGetImageHeight
448 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED, jint n){
449 if( n == -1 )
450 return (jint)gl->pano.height;
451 if( im.data != NULL )
452 return (jint)gl->im[n].height;
453 else
454 return (jint)0;
455 }
456
457
Java_ptutils_CGetImageFormat(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED,jint n)458 JNIEXPORT jint JNICALL Java_ptutils_CGetImageFormat
459 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED, jint n){
460 if( n == -1 )
461 return (jint)gl->pano.format;
462 else if( n < gl->numIm )
463 return (jint)gl->im[n].format;
464 else
465 return -1;
466 }
467
Java_ptutils_CGetHfov(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED,jint n)468 JNIEXPORT jdouble JNICALL Java_ptutils_CGetHfov
469 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED, jint n){
470 if( n == -1 )
471 return (jdouble)gl->pano.hfov;
472 else if( n < gl->numIm && n >= 0 )
473 return (jdouble)gl->im[n].hfov;
474 else
475 return -1.0;
476 }
477
478
Java_ptutils_CGetYaw(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED,jint n)479 JNIEXPORT jdouble JNICALL Java_ptutils_CGetYaw
480 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED, jint n){
481 return (jdouble)gl->im[n].yaw;
482 }
483
Java_ptutils_CGetPitch(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED,jint n)484 JNIEXPORT jdouble JNICALL Java_ptutils_CGetPitch
485 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED, jint n){
486 return (jdouble)gl->im[n].pitch;
487 }
488
Java_ptutils_CGetRoll(JNIEnv * env PT_UNUSED,jobject obj PT_UNUSED,jint n)489 JNIEXPORT jdouble JNICALL Java_ptutils_CGetRoll
490 (JNIEnv *env PT_UNUSED, jobject obj PT_UNUSED, jint n){
491 return (jdouble)gl->im[n].roll;
492 }
493
494
Java_ptutils_CCreateProject(JNIEnv * env,jobject obj,jstring path,jint panoMap,jstring panofile,jint imageFormat,jint numIm,jdouble fLength)495 JNIEXPORT void JNICALL Java_ptutils_CCreateProject
496 (JNIEnv *env, jobject obj, jstring path, jint panoMap, jstring panofile, jint imageFormat, jint numIm, jdouble fLength){
497 Image kim;
498 int i;
499 AlignInfo al;
500
501 const char *jpath = (*env)->GetStringUTFChars(env, path, 0),
502 *jpath2 = (*env)->GetStringUTFChars(env, panofile, 0);
503
504 SET_JAVA
505
506 if( jpathTofullPath( jpath, &project ) != 0 ){
507 PrintError("Could not create Path from %s", jpath);
508 return;
509 }
510 (*env)->ReleaseStringUTFChars(env, path, jpath);
511
512 SetImageDefaults( &kim );
513
514 SetAlignInfoDefaults( &al );
515
516 SetImageDefaults( &al.pano );
517 al.pano.format = _panorama ;
518 strcpy( al.pano.name, "PSD_mask" );
519 al.im = &kim;
520
521
522 al.numIm = numIm;
523 kim.hfov = fLength;
524 kim.format = imageFormat;
525 al.pano.format = panoMap;
526 strcpy(al.pano.name, jpath2 );
527 (*env)->ReleaseStringUTFChars(env, panofile, jpath2);
528
529 // Check for obvious nonsense
530 if( al.numIm <= 0 || kim.hfov <= 0.0)
531 return ;
532
533 al.pano.hfov = 360.0;
534
535 if( kim.format == _fisheye_ff && kim.hfov < 8.5 )
536 kim.format = _fisheye_circ;
537
538 al.im = (Image*) malloc( al.numIm * sizeof(Image ) );
539 al.opt = (optVars*) malloc( al.numIm * sizeof(optVars) );
540 al.cim = (CoordInfo*) malloc( al.numIm * sizeof(CoordInfo) );
541
542 if(al.im == NULL || al.opt == NULL || al.cim == NULL){
543 PrintError("Not enough memory");
544 }
545 SetStitchDefaults(&(al.st));
546 strcpy( al.st.srcName, "buf" );
547
548 if( strcmp( al.pano.name, "PSD_mask" ) == 0 ){
549 strcpy( al.st.destName, "buf" );
550 }else{
551 al.st.destName[0] = 0;
552 }
553
554 for(i=0; i<al.numIm; i++){
555 SetOptDefaults ( &(al.opt[i]));
556 SetImageDefaults( &al.im[i] );
557 al.im[i].format = kim.format;
558 if( al.im[i].format != _fisheye_circ ){
559 //al.im[i].cP.horizontal = 1;
560 //al.im[i].cP.vertical = 1;
561 }
562 al.cim[i].x[0] = (double) i;
563 al.cim[i].x[1] = al.cim[i].x[2] = 0.0;
564 al.cim[i].set[0] = al.cim[i].set[1] = al.cim[i].set[2] = TRUE;
565 al.im[i].hfov = -kim.hfov; // Calculate later!
566 }
567
568 writeProject( &al, &project );
569 DisposeAlignInfo( &al );
570 }
571
572
Java_ptutils_CTriangulate(JNIEnv * env,jobject obj,jint n)573 JNIEXPORT void JNICALL Java_ptutils_CTriangulate
574 (JNIEnv *env, jobject obj, jint n){
575 SET_JAVA
576
577 TriangulatePoints( gl, n );
578 }
579
Java_ptutils_CReduce(JNIEnv * env,jobject obj,jint n)580 JNIEXPORT void JNICALL Java_ptutils_CReduce
581 (JNIEnv *env, jobject obj, jint n){
582 SET_JAVA
583
584 ReduceTriangles( gl, n );
585 }
586
Java_ptutils_CCallOptimizer(JNIEnv * env,jobject obj)587 JNIEXPORT void JNICALL Java_ptutils_CCallOptimizer
588 (JNIEnv *env, jobject obj){
589 OptInfo opt;
590 char *script = NULL;
591 SET_JAVA
592
593 #ifdef __Mac__
594 setLibToResFile();
595 #endif
596
597 BackUp();
598 script = LoadScript( &project );
599
600 if( script == NULL ) {
601 PrintError("Error reading script");
602 #ifdef __Mac__
603 unsetLibToResFile();
604 #endif
605 return ;
606 }
607
608 gl->fcn = fcnPano;
609
610 SetGlobalPtr( gl );
611
612 opt.numVars = gl->numParam;
613 opt.numData = gl->numPts;
614 opt.SetVarsToX = SetLMParams;
615 opt.SetXToVars = SetAlignParams;
616 opt.fcn = gl->fcn;
617 *opt.message = 0;
618
619
620 RunLMOptimizer( &opt );
621 gl->data = opt.message;
622
623 // Print Results
624
625 // First Optimizer data
626
627 WriteResults( script, &project, gl, distSquared ,0 );
628 if( script ) free( script );
629 #ifdef __Mac__
630 unsetLibToResFile();
631 #endif
632 Restore();
633 }
634
635
Java_ptutils_CShowScript(JNIEnv * env,jobject obj)636 JNIEXPORT void JNICALL Java_ptutils_CShowScript
637 (JNIEnv *env, jobject obj){
638 SET_JAVA
639 showScript( &project );
640 }
641
Java_ptutils_CLaunchAndSendScript(JNIEnv * env,jobject obj,jstring japp,jstring joutput)642 JNIEXPORT void JNICALL Java_ptutils_CLaunchAndSendScript
643 (JNIEnv *env, jobject obj, jstring japp, jstring joutput){
644 char *script = malloc( 512 * 2 + 100);
645 char fname[512];
646 char appPath[32];
647 fullPath fspec;
648 const char *output = (*env)->GetStringUTFChars(env, joutput, 0);
649 const char *app = (*env)->GetStringUTFChars(env, japp, 0);
650
651 SET_JAVA
652
653 if( script == NULL ) return;
654
655 if( output == NULL || strlen(output) == 0 ){
656 script[0] = 0;
657 }else{
658 jpathTofullPath( output, &fspec );
659
660 FullPathtoString( &fspec, fname );
661 sprintf(script,"-o \"%s\" ", fname);
662 }
663 (*env)->ReleaseStringUTFChars(env, joutput, output);
664
665 memcpy( &fspec, &project, sizeof( fullPath ));
666
667 FullPathtoString( &fspec, fname );
668 strcat(script, "\"");
669 strcat(script,fname);
670 strcat(script, "\" ");
671
672 sprintf(appPath, "%s%s", HELPERS, app);
673 LaunchAndSendScript( appPath, script);
674 (*env)->ReleaseStringUTFChars(env, japp, app);
675 if( script ) free( script );
676 }
677
678
679
writeProject(AlignInfo * g,fullPath * pFile)680 int writeProject( AlignInfo *g, fullPath *pFile)
681 {
682 fullPath tmp;
683 file_spec fnum;
684 int i;
685 char line[512];
686 long count;
687 Image *im;
688 controlPoint *c;
689 triangle *t;
690 optVars *o;
691 CoordInfo *ci;
692 int pf;
693 char ch[256], cv[64];
694
695
696 if( g == NULL ) return 0;
697
698 setlocale(LC_ALL, "C");
699
700
701 memcpy(&tmp, pFile, sizeof( fullPath ));
702
703 p2cstr( tmp.name );
704 strcat((char*)tmp.name, "_temp_");
705 c2pstr((char*)tmp.name);
706
707 mycreate( &tmp, 'ttxt', 'TEXT' );
708 if( myopen( &tmp, write_text, fnum ) )
709 return -1;
710
711 if( g->pano.format == _equirectangular )
712 pf = 2;
713 else
714 pf = g->pano.format;
715
716 // Add command for stitcher, depending on g->st
717 // If '-' option has been set (destName != 0), do nothing
718 // else add stitch commands
719
720 if(g->st.destName[0] != 0)
721 sprintf(ch, "-%s", g->st.destName);
722 else
723 *ch=0;
724
725 if(g->pano.cP.radial)
726 sprintf(cv, "a%lg b%lg c%lg", g->pano.cP.radial_params[0][3],
727 g->pano.cP.radial_params[0][2],
728 g->pano.cP.radial_params[0][1] );
729 else
730 *cv=0;
731
732
733
734 sprintf(line, "p f%d w%ld h%ld v%lg u%d %s n\"%s\" %s\n\n", pf, (long int) g->pano.width, (long int) g->pano.height, g->pano.hfov, g->st.feather, cv, g->pano.name, ch );
735 count = strlen( line ); mywrite( fnum, count, line );
736
737 for(i=0; i<g->numIm; i++)
738 {
739 im = &g->im[i];
740
741 if( g->opt[i].hfov > 1 )
742 sprintf(ch, "v=%d", g->opt[i].hfov - 2);
743 else
744 sprintf(ch, "v%lg", g->im[i].hfov);
745
746 sprintf(line, "i f%ld w%ld h%ld y%lg p%lg r%lg %s %s n\"%s\" ", (long int) im->format, (long int) im->width, (long int) im->height,
747 im->yaw, im->pitch, im->roll,
748 (im->cP.correction_mode & correction_mode_morph ? "o" : "" ),
749 ch, im->name );
750 if(g->im[i].cP.radial)
751 {
752 if(g->opt[i].a > 1 )
753 sprintf(ch, " a=%d", g->opt[i].a - 2);
754 else
755 sprintf(ch, " a%lg", g->im[i].cP.radial_params[0][3]);
756 strcat(line, ch);
757
758 if(g->opt[i].b > 1 )
759 sprintf(ch, " b=%d", g->opt[i].b - 2);
760 else
761 sprintf(ch, " b%lg", g->im[i].cP.radial_params[0][2]);
762 strcat(line, ch);
763
764 if(g->opt[i].c > 1 )
765 sprintf(ch, " c=%d", g->opt[i].c - 2);
766 else
767 sprintf(ch, " c%lg", g->im[i].cP.radial_params[0][1]);
768 strcat(line, ch);
769 }
770 if(g->im[i].cP.horizontal)
771 {
772 sprintf(ch, " d%lg", g->im[i].cP.horizontal_params[0]);
773 strcat(line, ch);
774 }
775 if(g->im[i].cP.vertical)
776 {
777 sprintf(ch, " e%lg", g->im[i].cP.vertical_params[0]);
778 strcat(line, ch);
779 }
780
781 if( g->im[i].cP.correction_mode & correction_mode_morph )
782 {
783 strcat( line, "o " );
784 }
785
786 if( g->im[i].selection.bottom != 0 || g->im[i].selection.right != 0 ){
787 sprintf( ch, " S%ld,%ld,%ld,%ld ",(long int) g->im[i].selection.left, (long int) g->im[i].selection.right,
788 (long int) g->im[i].selection.top, (long int) g->im[i].selection.bottom );
789 strcat(line, ch);
790 }
791
792 if(g->cim[i].set[0])
793 {
794 sprintf(ch, " X%lg", g->cim[i].x[0]);
795 strcat(line, ch);
796 }
797 if(g->cim[i].set[1])
798 {
799 sprintf(ch, " Y%lg", g->cim[i].x[1]);
800 strcat(line, ch);
801 }
802 if(g->cim[i].set[2])
803 {
804 sprintf(ch, " Z%lg", g->cim[i].x[2]);
805 strcat(line, ch);
806 }
807
808 strcat(line, "\n");
809 count = strlen( line ); mywrite( fnum, count, line );
810 }
811
812 // Print v-lines
813 for(i=0; i<g->numIm; i++)
814 {
815 char ch[8];
816
817 strcpy(line, "v ");
818
819 o = &g->opt[i];
820 ci = &g->cim[i];
821
822 if( o->yaw == 1 )
823 {
824 sprintf(ch, "y%d ", i ); strcat(line, ch);
825 }
826 if( o->pitch == 1 )
827 {
828 sprintf(ch, "p%d ", i ); strcat(line, ch);
829 }
830 if( o->roll == 1 )
831 {
832 sprintf(ch, "r%d ", i ); strcat(line, ch);
833 }
834 if( o->hfov == 1 )
835 {
836 sprintf(ch, "v%d ", i ); strcat(line, ch);
837 }
838 if( o->a == 1 )
839 {
840 sprintf(ch, "a%d ", i ); strcat(line, ch);
841 }
842 if( o->b == 1 )
843 {
844 sprintf(ch, "b%d ", i ); strcat(line, ch);
845 }
846 if( o->c == 1 )
847 {
848 sprintf(ch, "c%d ", i ); strcat(line, ch);
849 }
850 if( o->d == 1 )
851 {
852 sprintf(ch, "d%d ", i ); strcat(line, ch);
853 }
854 if( o->e == 1 )
855 {
856 sprintf(ch, "e%d ", i ); strcat(line, ch);
857 }
858
859 if( !ci->set[0] )
860 {
861 sprintf(ch, "X%d ", i ); strcat(line, ch);
862 }
863 if( !ci->set[1] )
864 {
865 sprintf(ch, "Y%d ", i ); strcat(line, ch);
866 }
867 if( !ci->set[2] )
868 {
869 sprintf(ch, "Z%d ", i ); strcat(line, ch);
870 }
871
872 strcat(line,"\n");
873 count = strlen( line ); mywrite( fnum, count, line );
874 }
875
876 for(i=0; i<g->numPts; i++)
877 {
878 c = &g->cpt[i];
879 sprintf(line, "c n%d N%d x%lg y%lg X%lg Y%lg \n", c->num[0], c->num[1], c->x[0], c->y[0], c->x[1], c->y[1]);
880 count = strlen( line ); mywrite( fnum, count, line );
881 }
882 for(i=0; i<g->nt; i++)
883 {
884 t = &g->t[i];
885 sprintf(line, "t %d %d %d i%d\n", t->vert[0], t->vert[1], t->vert[2], t->nIm );
886 count = strlen( line ); mywrite( fnum, count, line );
887 }
888
889 strcat(mLine, "\n");
890 count = strlen( mLine ); mywrite( fnum, count, mLine );
891
892
893
894 myclose( fnum );
895 mydelete( pFile );
896 myrename( &tmp, pFile );
897 return 0;
898 }
899
900
loadProject(fullPath * fspec)901 int loadProject( fullPath *fspec ){
902 char *script=NULL;
903
904 script = LoadScript( fspec );
905
906 if( script == NULL ){
907 PrintError("Could not read project file");
908 return -1;
909 }
910
911 if( gl != NULL ){
912 DisposeAlignInfo( gl );
913 free( gl );
914 }
915
916 gl = (AlignInfo*)malloc( sizeof( AlignInfo ) );
917 if( gl == NULL ) return -1;
918
919 SetAlignInfoDefaults( gl );
920
921 if( ParseScript( script, gl ) != 0 ){
922 PrintError("Could not parse project file");
923 return -1;
924 }
925
926 ReadMLine( script, mLine );
927
928 if( script ) free( script );
929 return 0;
930 }
931
ReadMLine(char * script,char * m)932 void ReadMLine( char *script, char *m )
933 {
934 char *c = script;
935 int i=0;
936
937 while(*c == '\n' && *c != 0) c++;
938
939 while( *c != 0 )
940 {
941 c++;
942 if( *c == 'm')
943 {
944 while(*c!= '\n' && *c!=0 && i<250)
945 m[i++] = *c++;
946 m[i] = 0;
947 return;
948 }
949 while(*c!=0 && *c!='\n')c++;
950 }
951 }
952
953
jpathTofullPath(const char * jpath,fullPath * fp)954 int jpathTofullPath( const char* jpath, fullPath *fp ){
955 int length = strlen(jpath);
956 char *cpath = malloc( length + 1), *c;
957 int i, result = 0;
958 strcpy( cpath, jpath );
959 for(i=0; i<length; i++){
960 if(cpath[i] == '/')
961 cpath[i] = PATH_SEP ;
962 }
963 #ifdef __Mac__
964 c = cpath + 1;
965 if( /*StringtoFullPath*/GetFullPath( fp, c) != 0 )//Kekus Digital
966 #else
967 c = cpath;
968 if( StringtoFullPath( fp, c) != 0 )
969 #endif
970 {
971 result = -1;
972 }
973 free( cpath );
974 return result;
975 }
976
BackUp()977 void BackUp()
978 {
979 int i;
980
981 if( theBackUp != NULL )
982 free( theBackUp );
983
984 theBackUp = malloc( gl->numIm * sizeof( Image ));
985 if( theBackUp == NULL )
986 return;
987
988 for(i=0; i<gl->numIm; i++)
989 {
990 memcpy( &((Image*)theBackUp)[i], &gl->im[i], sizeof( Image ));
991 }
992 return;
993 }
994
Restore()995 void Restore(){
996 int i;
997
998 if( theBackUp == NULL )
999 return;
1000
1001
1002 for(i=0; i<gl->numIm; i++){
1003 memcpy( &gl->im[i], &((Image*)theBackUp)[i], sizeof( Image ));
1004 }
1005 return;
1006 }
1007
1008
SetAlignInfoDefaults(AlignInfo * al)1009 void SetAlignInfoDefaults( AlignInfo *al){
1010 al->numIm = 0;
1011 al->numPts = 0;
1012 al->nt = 0;
1013 al->numParam= 0;
1014 al->im = NULL;
1015 al->opt = NULL;
1016 al->cpt = NULL;
1017 al->t = NULL;
1018 al->cim = NULL;
1019 }
1020
1021 static TrformStr *pc_Tr;
1022 static Image *pc_reg;
1023 static fDesc *pc_fDesc;
1024 static aPrefs *pc_adj;
1025 static struct size_Prefs *pc_sp;
1026
pc_SetXtoVars(double * x)1027 int pc_SetXtoVars( double *x ){
1028 pc_adj->im.cP.horizontal_params[2] =pc_adj->im.cP.horizontal_params[1] =
1029 pc_adj->im.cP.horizontal_params[0] =x[2];//-params[0];
1030 pc_adj->im.cP.vertical_params[2] =pc_adj->im.cP.vertical_params[1] =
1031 pc_adj->im.cP.vertical_params[0] =x[3];//-params[1];
1032 pc_adj->im.hfov=x[0]/100.0;
1033 pc_adj->im.roll=x[1];
1034
1035 #if 0
1036 double *p = (double*) pc_fDesc->param;
1037
1038 p[0] = x[3];// shift_x
1039 p[1] = x[2];// shift_y
1040 p[2] = x[1] / 100.0; // scale
1041 p[5] = x[0] * PI / 180.0; // phi
1042 p[3] = cos(p[5]); // cos_phi
1043 p[4] = sin(p[5]); // sin_phi
1044 #endif
1045 //PrintError("shift_x = %lg, shift_y = %lg, scale = %lg, Phi = %lg",
1046 // p[0] ,p[1],p[2],p[5] *180.0/PI );
1047 return 0;
1048 }
1049
pc_SetVarsToX(double * x)1050 int pc_SetVarsToX( double *x ){
1051 x[2] = pc_adj->im.cP.horizontal_params[0];//-params[0];
1052 x[3] = pc_adj->im.cP.vertical_params[0];//-params[1];
1053 x[0] = pc_adj->im.hfov * 100.0;
1054 x[1] = pc_adj->im.roll;
1055 #if 0
1056 double *p = (double*) pc_fDesc->param;
1057
1058 x[3] = p[0];// shift_x
1059 x[2] = p[1];// shift_y
1060 x[1] = p[2] * 100.0; // scale
1061 x[0] = p[5] * 180.0 / PI; // phi
1062 #endif
1063 return 0;
1064 }
1065
1066
fcnAlign(int m PT_UNUSED,int n PT_UNUSED,double x[],double fvec[],int * iflag)1067 int fcnAlign(int m PT_UNUSED, int n PT_UNUSED, double x[], double fvec[],int *iflag)
1068 {
1069 // int i;
1070 double r = 0.0;
1071 static int numIt,a=0;
1072
1073 if( *iflag == -100 ){ // reset
1074 numIt = 0;
1075 // infoDlg ( _initProgress, "Optimizing Variables" );
1076 return 0;
1077 }
1078 if( *iflag == -99 ){ //
1079 //infoDlg ( _disposeProgress, "" );
1080 return 0;
1081 }
1082
1083
1084 if( *iflag == 0 ){
1085 char message[256];
1086
1087 sprintf( message, "Average Difference between Pixels \nafter %d iteration(s): %g ", numIt,sqrt(fvec[0]/(3*16*16)));
1088 numIt ++;a=0;
1089 //if( !infoDlg ( _setProgress,message ) ) *iflag = -1;
1090 return 0;
1091 }
1092
1093
1094 // Set Parameters
1095 pc_SetXtoVars(x);
1096
1097 filter_main( pc_Tr, pc_sp );
1098 //transForm( pc_Tr, pc_fDesc, 0);
1099
1100 {
1101 Image *a = pc_Tr->dest, *b = pc_reg;
1102 unsigned char *adata, *bdata;
1103 int x,y,cy;
1104 int c1,c2,c3;
1105
1106 for(y=0; y<a->height; y++){
1107 cy = y * a->bytesPerLine;
1108 for(x=0, adata = *a->data+cy, bdata = *b->data+cy;
1109 x<a->width; x++, adata+=4, bdata+=4){
1110 if( *adata != 0 && *bdata != 0 ){
1111 c1 = ((int)(adata[1])) - ((int)(bdata[1]));
1112 c2 = ((int)(adata[2])) - ((int)(bdata[2]));
1113 c3 = ((int)(adata[3])) - ((int)(bdata[3]));
1114 r += c1*c1 + c2*c2 + c3*c3;
1115 }else{
1116 r += 3.0 * 255.0 * 255.0;
1117 }
1118 }
1119 }
1120 }
1121 fvec[0]= r;
1122 fvec[1]= r;
1123 fvec[2]= r;
1124 fvec[3]= r;
1125
1126 return 0;
1127 }
1128
1129
Java_ptutils_CAlignPoint(JNIEnv * env,jobject obj,jdoubleArray jX,jintArray jreg,jintArray jseek)1130 JNIEXPORT void JNICALL Java_ptutils_CAlignPoint
1131 (JNIEnv *env, jobject obj, jdoubleArray jX, jintArray jreg, jintArray jseek){
1132 OptInfo opt;
1133 int w_reg, h_reg, w_seek, h_seek;
1134 Image src, dst, reg;
1135 jdouble *X;
1136 jint *pix_reg, *pix_seek;
1137 fDesc pc_fD;
1138 double params[6];
1139 struct size_Prefs spref;
1140
1141 pc_sp = &spref;
1142
1143 SET_JAVA
1144 JavaUI = FALSE;
1145
1146 #ifdef __Mac__
1147 setLibToResFile(); // MacOS: Get resources from shared lib
1148 #endif
1149
1150 X = (*env)->GetDoubleArrayElements(env, jX, 0);
1151 pix_reg = (*env)->GetIntArrayElements(env, jreg, 0);
1152 pix_seek = (*env)->GetIntArrayElements(env, jseek, 0);
1153
1154 w_reg = h_reg = (int)(sqrt((double) (*env)->GetArrayLength(env, jreg))+0.5);
1155 w_seek = h_seek = (int)(sqrt((double) (*env)->GetArrayLength(env, jseek))+0.5);
1156
1157 pc_Tr = (TrformStr *) malloc(sizeof(TrformStr));
1158 memset(pc_Tr, 0, sizeof(TrformStr));
1159 pc_reg = ®
1160 pc_adj = (aPrefs*) malloc(sizeof(aPrefs));
1161 SetAdjustDefaults(pc_adj);
1162
1163 SetImageDefaults(&src);
1164 src.width = w_seek;
1165 src.height = h_seek;
1166 src.bitsPerPixel = 32;
1167 src.bytesPerLine = 4 * src.width;
1168 src.dataSize = src.bytesPerLine * src.height;
1169 src.data = (unsigned char**)(&pix_seek);
1170
1171 SetImageDefaults(&dst);
1172 dst.width = w_reg;
1173 dst.height = h_reg;
1174 dst.bitsPerPixel = 32;
1175 dst.bytesPerLine = 4 * dst.width;
1176 dst.dataSize = dst.bytesPerLine * dst.height;
1177 dst.data = (unsigned char**)mymalloc(dst.dataSize);
1178
1179 SetImageDefaults(®);
1180 reg.width = w_reg;
1181 reg.height = h_reg;
1182 reg.bitsPerPixel = 32;
1183 reg.bytesPerLine = 4 * reg.width;
1184 reg.dataSize = reg.bytesPerLine * reg.height;
1185 reg.data = (unsigned char**)(&pix_reg);
1186
1187
1188 pc_fDesc = &pc_fD;
1189 params[0] = 0.0; // shift_x
1190 params[1] = 0.0; // shift_y
1191 params[2] = 1.0; // scale
1192 params[5] = 0.0; // phi
1193 params[3] = cos(params[5]); // cos_phi
1194 params[4] = sin(params[5]); // sin_phi
1195
1196 SetDesc(pc_fD, shift_scale_rotate, params);
1197
1198
1199 pc_adj->mode = _insert;
1200
1201 memcpy( &pc_adj->im, &src, sizeof(Image) );
1202 pc_adj->im.format = _rectilinear;
1203 pc_adj->im.hfov = ((double)w_seek)/100.0;
1204 pc_adj->im.cP.horizontal = 1;
1205 pc_adj->im.cP.vertical = 1;
1206
1207 memcpy( &pc_adj->pano, &dst, sizeof(Image));
1208 pc_adj->pano.format = _rectilinear;
1209 pc_adj->pano.hfov = ((double)w_reg)/100.0;
1210
1211 if( readPrefs( (char*) pc_sp, _sizep ) != 0 )
1212 SetSizeDefaults ( pc_sp );
1213
1214
1215 pc_Tr->src = &src;
1216 pc_Tr->dest = &dst;
1217
1218 pc_Tr->tool = _adjust;
1219 pc_Tr->mode = _usedata + _destSupplied;
1220 pc_Tr->interpolator = _spline36;
1221 pc_Tr->gamma = 1.0;
1222 pc_Tr->fastStep = FAST_TRANSFORM_STEP_NONE;
1223 pc_Tr->data = (void*) pc_adj;
1224
1225 opt.numVars = 4;
1226 opt.numData = 4;
1227 opt.SetVarsToX = pc_SetVarsToX;
1228 opt.SetXToVars = pc_SetXtoVars;
1229 opt.fcn = fcnAlign;
1230 *opt.message = 0;
1231 //RunLMOptimizer( &opt );
1232
1233 //PrintError("Start");
1234
1235 RunBROptimizer ( &opt, 1e-3);
1236
1237 X[0] = pc_adj->im.cP.horizontal_params[0];//-params[0];
1238 X[1] = pc_adj->im.cP.vertical_params[0];//-params[1];
1239
1240 if(pc_Tr) free(pc_Tr);
1241 if(pc_adj) free(pc_adj);
1242 myfree((void**)dst.data);
1243
1244 (*env)->ReleaseIntArrayElements(env, jseek, pix_seek, 0);
1245 (*env)->ReleaseIntArrayElements(env, jreg, pix_reg, 0);
1246 (*env)->ReleaseDoubleArrayElements(env, jX, X, 0);
1247
1248 #ifdef __Mac__
1249 unsetLibToResFile( );
1250 #endif
1251
1252
1253 }
1254
1255
1256
1257
1258
1259
1260