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

  Switch to unified view

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