1 /*
2 * This file is part of XForms.
3 *
4 * XForms is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as
6 * published by the Free Software Foundation; either version 2.1, or
7 * (at your option) any later version.
8 *
9 * XForms is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with XForms; see the file COPYING. If not, write to
16 * the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
17 * MA 02111-1307, USA.
18 */
19
20
21 /*
22 * image support test program
23 *
24 * This file is part of xforms package
25 * T.C. Zhao (Nov., 1999)
26 */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include <math.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <unistd.h>
38
39 #include "include/forms.h"
40 #include "image/flimage.h"
41 #include "fd/is_gui.h"
42
43 typedef struct
44 {
45 FL_IMAGE * image;
46 FD_is_mainform * fd_mainform;
47 FD_viewform * fd_viewform;
48 FD_processform * fd_processform;
49 FD_saveAs_form * fd_saveAs_form;
50 const char * outformat;
51 int double_buffer;
52 int rgb[ 4 ]; /* current fill color */
53 } App;
54
55 static App app;
56 static int testicon = 1;
57
58
59 /***************************************
60 ***************************************/
61
62 int
visual_cue(FL_IMAGE * im,const char * s)63 visual_cue( FL_IMAGE * im,
64 const char * s )
65 {
66 fl_set_object_label( app.fd_mainform->status, s );
67
68 if ( im->completed < 0 )
69 fl_set_slider_value( app.fd_mainform->progressbar, 0 );
70 else
71 fl_set_slider_value( app.fd_mainform->progressbar,
72 ( double ) im->completed / im->total );
73 return 0;
74 }
75
76
77 /***************************************
78 * only show image file in file selector
79 ***************************************/
80
81 static int
image_file_filter(const char * name,int type)82 image_file_filter( const char * name,
83 int type )
84 {
85 return type == FT_FILE && flimage_is_supported( name );
86 }
87
88
89 /***************************************
90 * application initialization. Enable all formats and setup visual_cue
91 * and error reporting functions.
92 ***************************************/
93
94 static void
app_init(void)95 app_init( void )
96 {
97 FLIMAGE_SETUP setup;
98
99 memset( &setup, 0, sizeof setup );
100
101 flimage_enable_bmp( );
102 flimage_enable_gif( );
103 flimage_enable_ps( );
104 flimage_enable_fits( );
105 flimage_enable_xpm( );
106 flimage_enable_xbm( );
107 flimage_enable_jpeg( );
108 flimage_enable_tiff( );
109
110 /* Setup visual cue and status reporting */
111
112 setup.visual_cue = visual_cue;
113 setup.header_info = 1;
114 setup.app_data = &app;
115 flimage_setup( &setup );
116
117 fl_set_dirlist_filter( image_file_filter );
118 }
119
120
121 /***************************************
122 ***************************************/
123
124 void
doublebuffer_callback(FL_OBJECT * ob,long data FL_UNUSED_ARG)125 doublebuffer_callback( FL_OBJECT * ob,
126 long data FL_UNUSED_ARG )
127 {
128 app.double_buffer = fl_get_button( ob );
129 if ( app.image )
130 app.image->double_buffer = app.double_buffer;
131 }
132
133
134 /***************************************
135 ***************************************/
136
137 void
windowlevel_callback(FL_OBJECT * ob FL_UNUSED_ARG,long data FL_UNUSED_ARG)138 windowlevel_callback( FL_OBJECT * ob FL_UNUSED_ARG,
139 long data FL_UNUSED_ARG )
140 {
141 if ( ! app.image )
142 return;
143
144 flimage_windowlevel( app.image,
145 fl_get_slider_value( app.fd_viewform->level ),
146 fl_get_slider_value( app.fd_viewform->window ) );
147 app.image->display( app.image, app.image->win );
148 }
149
150
151 /*** callbacks and freeobj handles for form is_mainform ***/
152
153 /***************************************
154 ***************************************/
155
156 void
vscroll_callback(FL_OBJECT * ob,long data FL_UNUSED_ARG)157 vscroll_callback( FL_OBJECT * ob,
158 long data FL_UNUSED_ARG )
159 {
160 if ( app.image )
161 {
162 app.image->wy = ( 0.5 - fl_get_scrollbar_value( ob ) ) * app.image->h;
163 app.image->display( app.image, app.image->win );
164 }
165 }
166
167
168 /***************************************
169 ***************************************/
170
171 void
hscroll_callback(FL_OBJECT * ob,long data FL_UNUSED_ARG)172 hscroll_callback( FL_OBJECT * ob,
173 long data FL_UNUSED_ARG )
174 {
175 if ( app.image )
176 {
177 app.image->wx = ( 0.5 - fl_get_scrollbar_value( ob ) ) * app.image->w;
178 app.image->display( app.image, app.image->win );
179 }
180 }
181
182
183 /***************************************
184 ***************************************/
185
186 void
outformat_callback(FL_OBJECT * ob,long data FL_UNUSED_ARG)187 outformat_callback( FL_OBJECT * ob,
188 long data FL_UNUSED_ARG )
189 {
190 app.outformat = fl_get_choice_text( ob );
191 }
192
193
194 /*** Image Processing callbacks ***/
195
196 /***************************************
197 ***************************************/
198
199 void
colorchange_callback(FL_OBJECT * ob,long data)200 colorchange_callback( FL_OBJECT * ob,
201 long data )
202 {
203 app.rgb[ data ] = fl_get_slider_value( ob ) + 0.1;
204 fl_mapcolor( FL_FREE_COL1, app.rgb[ 0 ], app.rgb[ 1 ], app.rgb[ 2 ] );
205 fl_redraw_object( app.fd_processform->colorobj );
206 }
207
208
209 /***************************************
210 ***************************************/
211
212 void
autocrop_callback(FL_OBJECT * ob FL_UNUSED_ARG,long data FL_UNUSED_ARG)213 autocrop_callback( FL_OBJECT * ob FL_UNUSED_ARG,
214 long data FL_UNUSED_ARG )
215 {
216 if ( ! app.image )
217 return;
218
219 flimage_autocrop( app.image, FLIMAGE_AUTOCOLOR );
220 app.image->display( app.image, app.image->win );
221 }
222
223
224 /***************************************
225 ***************************************/
226
227 void
convolve_callback(FL_OBJECT * ob FL_UNUSED_ARG,long data)228 convolve_callback( FL_OBJECT * ob FL_UNUSED_ARG,
229 long data)
230 {
231 #if 1
232 if ( app.image )
233 {
234 flimage_convolve( app.image, ( int ** ) data, 0, 0 );
235 app.image->display( app.image, app.image->win );
236 }
237 #else
238 /* pixtran test */
239
240 int red[ 256 ],
241 green[ 256 ],
242 blue[ 256 ],
243 i;
244
245 for ( i = 0; i < 256; i++ )
246 {
247 red[ i ] = i * ( log10( 1.0 + 5 * i / 255.0 ) / log10( 1.0 + 5 ) );
248 green[ i ] = i * ( log10( 1.0 + 5 * i / 255.0 ) / log10( 1.0 + 5 ) );
249 blue[ i ] = i * ( log10( 1.0 + 5 * i / 255.0 ) / log10( 1.0 + 5 ) );
250 }
251
252 flimage_transform_pixel( app.image, red, green, blue );
253 app.image->display( app.image, app.image->win );
254 #endif
255 }
256
257
258 /***************************************
259 ***************************************/
260
261 void
scaling_callback(FL_OBJECT * ob FL_UNUSED_ARG,long data FL_UNUSED_ARG)262 scaling_callback( FL_OBJECT * ob FL_UNUSED_ARG,
263 long data FL_UNUSED_ARG )
264 {
265 FD_processform *processform = app.fd_processform;
266 int neww,
267 newh,
268 options;
269 float sw,
270 sh;
271
272 if ( ! app.image )
273 return;
274
275 sw = fl_get_counter_value( processform->width );
276 sh = fl_get_counter_value( processform->height );
277
278 if ( fl_get_button( processform->pixel ) )
279 {
280 neww = sw + 0.1;
281 newh = sh + 0.1;
282 }
283 else
284 {
285 neww = sw * app.image->w + 0.1;
286 newh = sh * app.image->h + 0.1;
287 }
288
289 if ( ! strcmp( fl_get_choice_text( processform->subpixel ), "subpixel" ) )
290 options = FLIMAGE_SUBPIXEL;
291 else
292 options = FLIMAGE_NOSUBPIXEL;
293
294 if ( ! strcmp( fl_get_choice_text( processform->aspect ), "aspect" ) )
295 options |= FLIMAGE_ASPECT;
296
297 if ( ! strcmp( fl_get_choice_text( processform->align ), "center" ) )
298 options |= FLIMAGE_CENTER;
299 else
300 options |= FLIMAGE_NOCENTER;
301
302 app.image->fill_color = FL_PACK(app.rgb[ 0 ], app.rgb[ 1 ], app.rgb[ 2 ] );
303 if ( flimage_scale( app.image, neww, newh, options) < 0 )
304 fprintf( stderr, "scaling failed\n" );
305
306 app.image->display( app.image, app.image->win );
307 }
308
309
310 /***************************************
311 ***************************************/
312
313 void
switchtopixel_callback(FL_OBJECT * ob,long data FL_UNUSED_ARG)314 switchtopixel_callback( FL_OBJECT * ob,
315 long data FL_UNUSED_ARG )
316 {
317 FD_processform *processform = app.fd_processform;
318 float w,
319 h;
320 FL_IMAGE *im = app.image;
321
322 if ( ! app.image )
323 return;
324
325 /* this function may be called in two ways: real callback when switch to
326 pixel button is pressed or when called directly by the application
327 when a new image is loaded */
328
329 if ( fl_get_button( processform->pixel ) )
330 {
331 w = ob == 0 ? 1.0 : fl_get_counter_value( processform->width );
332 h = ob == 0 ? 1.0 : fl_get_counter_value( processform->height );
333 }
334 else
335 {
336 w = ob == 0 ? im->w : fl_get_counter_value( processform->width );
337 h = ob == 0 ? im->h : fl_get_counter_value( processform->height );
338 }
339
340 fl_freeze_form( processform->processform );
341
342 if ( fl_get_button( processform->pixel ) )
343 {
344 fl_set_counter_bounds( processform->width, 0.1 * im->w, 10.0 * im->w );
345 fl_set_counter_bounds( processform->height, 0.1 * im->h, 10.0 * im->h );
346 fl_set_counter_value( processform->width, w * im->w );
347 fl_set_counter_value( processform->height, h * im->h );
348 fl_set_counter_precision( processform->width, 0 );
349 fl_set_counter_precision( processform->height, 0 );
350 fl_set_counter_step( processform->width, 1, 10 );
351 fl_set_counter_step( processform->height, 1, 10 );
352 }
353 else
354 {
355 fl_set_counter_bounds( processform->width, 0.1, 10.0 );
356 fl_set_counter_bounds( processform->height, 0.1, 10.0 );
357 fl_set_counter_value( processform->width, w / im->w );
358 fl_set_counter_value( processform->height, h / im->h );
359 fl_set_counter_precision( processform->width, 1 );
360 fl_set_counter_precision( processform->height, 1 );
361 fl_set_counter_step( processform->width, 0.1, 1 );
362 fl_set_counter_step( processform->height, 0.1, 1 );
363 }
364
365 fl_unfreeze_form( processform->processform );
366 }
367
368
369 /***************************************
370 * when a new image is loaded, update the GUI
371 ***************************************/
372
373 void
update_process_form(void)374 update_process_form( void )
375 {
376 switchtopixel_callback( 0, 0 );
377 }
378
379
380 /******************** END OF PROCESS CALLBACKS ****************************/
381
382 /***************************************
383 ***************************************/
384
385 void
reset_scrollbar(FL_IMAGE * im)386 reset_scrollbar( FL_IMAGE * im )
387 {
388 FD_is_mainform *fdui = im->u_vdata;
389
390 fl_set_scrollbar_value( fdui->hscroll, 0.5 );
391 fl_set_scrollbar_value( fdui->vscroll, 0.5 );
392 }
393
394
395 /***************************************
396 ***************************************/
397
398 static void
test_icon(void)399 test_icon( void )
400 {
401 Pixmap pixmap;
402 FL_IMAGE *im;
403
404 if( ! testicon || app.image == 0 )
405 return;
406
407 im = flimage_dup( app.image );
408 if( app.image->w > 64 || app.image->h > 64 )
409 flimage_scale( im, 64, 64, FLIMAGE_ASPECT );
410
411 pixmap = flimage_to_pixmap( im, FL_ObjWin( app.fd_viewform->pixmap ) );
412 fl_free_pixmap_pixmap( app.fd_viewform->pixmap );
413 fl_set_pixmap_pixmap( app.fd_viewform->pixmap, pixmap, 0 );
414
415 flimage_free( im );
416 }
417
418
419 /***************************************
420 ***************************************/
421
422 static int
load_and_show(const char * file,void * data)423 load_and_show( const char * file,
424 void * data )
425 {
426 FD_is_mainform *fdui = data;
427 FL_IMAGE *image;
428 FD_viewform *fd_viewform = app.fd_viewform;
429 struct stat buff;
430
431 if ( ! file || ! *file )
432 {
433 fprintf( stderr, "Missing file name\n" );
434 return 0;
435 }
436
437 if ( ! stat( file, &buff ) && S_ISDIR( buff.st_mode ) )
438 {
439 fl_set_directory( file );
440 return 0;
441 }
442
443 if ( ! ( image = flimage_load( file ) ) )
444 return 0;
445
446 image->u_vdata = data;
447 reset_scrollbar( image );
448 image->display( image, FL_ObjWin( fdui->canvas ) );
449 if ( app.image )
450 flimage_free( app.image );
451 app.image = image;
452 app.image->double_buffer = app.double_buffer;
453 app.outformat = image->fmt_name;
454
455
456 /* update image info */
457
458 fl_freeze_form( fd_viewform->viewform );
459
460 fl_set_choice_text( app.fd_saveAs_form->outformat, app.outformat );
461 fl_clear_browser( fd_viewform->headerinfo );
462
463 if ( app.image->info )
464 fl_addto_browser( fd_viewform->headerinfo, app.image->info );
465
466 if ( app.image->type == FL_IMAGE_GRAY16 )
467 {
468 fl_activate_object( fd_viewform->level );
469 fl_activate_object( fd_viewform->window );
470 fl_set_slider_bounds( fd_viewform->level, 0, image->gray_maxval );
471 fl_set_slider_bounds( fd_viewform->window, 0, image->gray_maxval );
472 }
473 else
474 {
475 fl_deactivate_object( fd_viewform->level );
476 fl_deactivate_object( fd_viewform->window );
477 }
478
479 test_icon( );
480 fl_unfreeze_form( fd_viewform->viewform );
481
482 update_process_form( );
483
484 return 0;
485 }
486
487
488 static int save_file( const char *,
489 void * );
490
491
492 /***************************************
493 ***************************************/
494
495 void
filemenu_callback(FL_OBJECT * ob,long data FL_UNUSED_ARG)496 filemenu_callback( FL_OBJECT * ob,
497 long data FL_UNUSED_ARG )
498 {
499 int n = fl_get_menu( ob );
500
501 switch ( n )
502 {
503 case 2: /* Open */
504 fl_use_fselector( 0 );
505 fl_set_fselector_placement( FL_PLACE_MOUSE );
506 fl_set_fselector_callback( load_and_show, ob->form->fdui );
507 fl_show_fselector( "Load an Image", 0, "*", 0 );
508 break;
509
510 case 3: /* Save */
511 if( app.image )
512 {
513 const char *f;
514
515 fl_use_fselector( 1 );
516 if ( ( f = fl_show_fselector( "OutputName", 0, "*",
517 app.image->infile ) ) )
518 save_file( f, 0 );
519 }
520 break;
521
522 case 4: /* Save As */
523 if( app.image )
524 fl_show_form( app.fd_saveAs_form->saveAs_form,
525 FL_PLACE_CENTERFREE, FL_TRANSIENT,
526 "OutputForm");
527 break;
528
529 case 5:
530 fl_finish( );
531 exit( 0 );
532 }
533 }
534
535
536 /***************************************
537 ***************************************/
538
539 void
progressbar(FL_OBJECT * ob FL_UNUSED_ARG,long data FL_UNUSED_ARG)540 progressbar( FL_OBJECT * ob FL_UNUSED_ARG,
541 long data FL_UNUSED_ARG )
542 {
543 }
544
545
546 /***************************************
547 ***************************************/
548
549 static int
expose_handle(FL_OBJECT * ob FL_UNUSED_ARG,Window win,int w FL_UNUSED_ARG,int h FL_UNUSED_ARG,XEvent * xev FL_UNUSED_ARG,void * data FL_UNUSED_ARG)550 expose_handle( FL_OBJECT * ob FL_UNUSED_ARG,
551 Window win,
552 int w FL_UNUSED_ARG,
553 int h FL_UNUSED_ARG,
554 XEvent * xev FL_UNUSED_ARG,
555 void * data FL_UNUSED_ARG)
556 {
557 if ( app.image )
558 app.image->display( app.image, win );
559 return 0;
560 }
561
562
563 /**********************************************************************
564 * The Save As dialog
565 *********************************************************************/
566
567 /***************************************
568 * SaveAs file selector callback
569 ***************************************/
570
save_file(const char * file,void * data FL_UNUSED_ARG)571 static int save_file( const char * file,
572 void * data FL_UNUSED_ARG )
573 {
574 if ( ! file || ! *file )
575 return -1;
576 return flimage_dump( app.image, file, app.outformat );
577 }
578
579
580 /***************************************
581 ***************************************/
582
hide_it(FL_OBJECT * ob FL_UNUSED_ARG,long data FL_UNUSED_ARG)583 static void hide_it( FL_OBJECT * ob FL_UNUSED_ARG,
584 long data FL_UNUSED_ARG )
585 {
586 char file[ 256 ];
587 const char *d,
588 *f;
589
590 /* get the selected file */
591
592 fl_use_fselector( 2 );
593 if ( ( d = fl_get_directory( ) ) && ( f = fl_get_filename( ) ) )
594 {
595 sprintf( file,"%s/%s", d, f );
596 save_file( f, 0 );
597 }
598
599 fl_hide_form( app.fd_saveAs_form->saveAs_form );
600 }
601
602
603 /***************************************
604 ***************************************/
605
606 static void
init_save_as_form(void)607 init_save_as_form( void )
608 {
609 static FD_saveAs_form *fd_saveAs_form;
610 const FLIMAGE_FORMAT_INFO *fmtinfo;
611 int i,
612 n;
613 FD_FSELECTOR *fd_fselect;
614
615 fd_saveAs_form = create_form_saveAs_form( );
616 app.fd_saveAs_form = fd_saveAs_form;
617
618 fl_use_fselector( 2 );
619 fd_fselect = fl_get_fselector_fdstruct( );
620 /* fl_set_fselector_callback( save_file, 0 ); */
621 fl_set_object_callback( fd_fselect->ready, hide_it, 0 );
622 fl_show_object( fd_fselect->ready );
623 fl_set_form_atclose( app.fd_saveAs_form->saveAs_form,
624 fl_goodies_atclose, fd_fselect->ready );
625
626 /* Put fselector into the formbrowser as a way of reparenting */
627
628 fl_addto_formbrowser( app.fd_saveAs_form->formcontainer,
629 fd_fselect->fselect );
630
631 /* Fill the output format choice */
632
633 for ( n = flimage_get_number_of_formats( ), i = 1; i <= n; i++ )
634 {
635 fmtinfo = flimage_get_format_info( i );
636
637 if ( fmtinfo->read_write & FLIMAGE_WRITABLE )
638 fl_addto_choice( app.fd_saveAs_form->outformat,
639 fmtinfo->short_name );
640 }
641
642 app.outformat = fl_get_choice_text( app.fd_saveAs_form->outformat );
643 }
644
645
646 /***************************************
647 ***************************************/
648
649 int
main(int argc,char * argv[])650 main( int argc,
651 char * argv[ ] )
652 {
653 FD_is_mainform *fd_is_mainform;
654 FD_viewform *fd_viewform;
655 FD_processform *fd_processform;
656 FD_annotationform *fd_annotationform;
657
658 fl_set_border_width( -2 );
659 fl_initialize( &argc, argv, 0, 0, 0 );
660 fd_is_mainform = create_form_is_mainform( );
661 fd_viewform = create_form_viewform( );
662 fd_processform = create_form_processform( );
663 fd_annotationform = create_form_annotationform( );
664
665 /* initialize app GUI */
666
667 app.fd_mainform = fd_is_mainform;
668 app.fd_viewform = fd_viewform;
669 app.fd_processform = fd_processform;
670
671 /* image related initializations */
672
673 app_init( );
674
675 /* fill-in form initialization code */
676
677 fl_set_browser_fontstyle( fd_viewform->headerinfo, FL_FIXED_STYLE );
678
679 fl_addto_tabfolder( fd_is_mainform->tabfolder, " View ",
680 fd_viewform->viewform);
681 fl_addto_tabfolder( fd_is_mainform->tabfolder, "Processing",
682 fd_processform->processform );
683 fl_addto_tabfolder( fd_is_mainform->tabfolder, "Annotation",
684 fd_annotationform->annotationform);
685
686 fl_add_canvas_handler( fd_is_mainform->canvas,
687 Expose, expose_handle, 0 );
688
689 app.rgb[ 0 ] = fl_get_slider_value( fd_processform->red ) + 0.1;
690 app.rgb[ 1 ] = fl_get_slider_value( fd_processform->green ) + 0.1;
691 colorchange_callback( fd_processform->blue, 2 );
692
693 init_save_as_form( );
694
695 /* show the main form */
696
697 fl_show_form( fd_is_mainform->is_mainform, FL_PLACE_CENTERFREE,
698 FL_FULLBORDER, "is_mainform" );
699
700 while ( fl_do_forms( ) )
701 /* empty */ ;
702
703 return 0;
704 }
705
706 #include "fd/is_gui.c"
707
708
709 /*
710 * Local variables:
711 * tab-width: 4
712 * indent-tabs-mode: nil
713 * End:
714 */
715