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