/[perl]/gtk-jpegtran.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /gtk-jpegtran.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.1.1 by dpavlin, Mon Jun 18 06:44:14 2001 UTC revision 1.2 by dpavlin, Sat Feb 1 00:39:46 2003 UTC
# Line 1  Line 1 
1  #!/usr/bin/perl -w  #!/usr/bin/perl -w #d
2    
3  # by Dobrica Pavlinusic <dpavlin@rot13.org> 2001-06-14  # GUI front-end to jpegtran to rotate and flip jpegs without loss
4  #  #
5  # rotate jpeg using jpegtran with GTK interface  # 2000-06-14 Dobrica Pavlinusic <dpavlin@rot13.org>
6    
7  use Gtk;  use Gtk;
8  use strict;  use strict;
# Line 10  use strict; Line 10  use strict;
10  init Gtk;  init Gtk;
11  set_locale Gtk;  set_locale Gtk;
12    
13    my $DEBUG = 1;
14    sub pdebug { print STDERR @_,"\n" if ($DEBUG); }
15    
16  my $false = 0;  my $false = 0;
17  my $true = 1;  my $true = 1;
18    
19  my $xv_pic=".xvpics/0610_011.jpg";  # $X[0](dir|filename|w|h|pix)
20    my @X;
21    
22    my $xv_pic_dir=".xvpics";
23    #$xv_pic_dir="/mnt/f/tmp2/PICS/.xvpics" if ($DEBUG);
24    
25    if (! $ARGV[0] && !-d ".xvpics") {
26            print "Usage: $0 [path to directory with pictures (in which is .xvpics dir)]\n";
27            exit 1;
28    }
29    
30    $xv_pic_dir = $ARGV[0]."/.xvpics" if ($ARGV[0]);
31    
32    if (! -d $xv_pic_dir) {
33            print "$xv_pic_dir is not directory!";
34    }
35    
36    #--------------------------------------------------------------------
37    # scan directory
38    
39    pdebug "reading dir $xv_pic_dir";
40    
41  $xv_pic = $ARGV[0] if ($ARGV[0]);  opendir(DIR, $xv_pic_dir) || die "can't opendir $xv_pic_dir: $!";
42    my @pic_filenames = grep { !/^\./ && -f "$xv_pic_dir/$_" } readdir(DIR);
43    closedir(DIR);
44    
45  my ($w,$h,$cols) = (0,0,0);  pdebug "found $#pic_filenames files in $xv_pic_dir";
 my @xv_pix;  
46    
47  open(XV,$xv_pic) || die "$xv_pic: $!";  my $dir=$xv_pic_dir;
48  my $l=<XV>; chomp $l;  $dir=~s/\.xvpics//;
49  die "$xv_pic not XV thumbnail file ($l)" if ($l!~m/^P7 332$/);  
50  while(<XV>) {  foreach my $filename (@pic_filenames) {
51          chomp;          pdebug "gronk $filename";
52          next if (/^#/);          my ($w,$h,$pix) = xvpic_read("$xv_pic_dir/$filename");
53          if (/^(\d+) (\d+) (\d+)$/) {          my (%tmp) = ( dir=>$dir, filename=>$filename, w=>$w, h=>$h, pix=>$pix );
54                  ($w,$h,$cols) = ($1,$2,$3);          push @X,\%tmp;
55                  last;  }
56    
57    #--------------------------------------------------------------------
58    # read xvpic from disk
59    #       xvpic_read($filename)
60    #       returns:
61    #               ($w,$h,$xv_pix)
62    
63    sub xvpic_read {
64            my ($xv_pic) = @_;
65    
66            my ($w,$h,$cols) = (0,0,0);
67    
68            open(XV,$xv_pic) || die "$xv_pic: $!";
69            my $l=<XV>; chomp $l;
70            if ($l!~m/^P7 332$/) {
71                    warn "$xv_pic not XV thumbnail file ($l)";
72                    return;
73            }
74            while(<XV>) {
75                    chomp;
76                    next if (/^#/);
77                    if (/^(\d+) (\d+) (\d+)$/) {
78                            ($w,$h,$cols) = ($1,$2,$3);
79                            last;
80                    }
81                    warn "expected w,h,cols, got: $_";
82          }          }
83          print STDERR "--$_--\n";  
84            warn "$xv_pic number of colors is not 255 (strange)" if ($cols != 255);
85    
86            my $buf;        # tmp buffer for read;
87    
88            # read pixels
89            read XV,$buf,($w*$h);
90    
91            return ($w,$h,$buf);
92  }  }
93    
94  warn "$xv_pic number of colors is not 255 (strange)" if ($cols != 255);  #--------------------------------------------------------------------
95    # Generate 332 colour-cube colourmap
96    
97    sub generate_xpm_colmap {
98            my @xpm_colmap;
99            for (my $i=0; $i<256; $i++) {
100    
101                    push(@xpm_colmap,sprintf ("%02x c #%02x%02x%02x",$i,
102                            (255*(($i&(7<<5))>>5))/7,
103                            (255*(($i&(7<<2))>>2))/7,
104                            (255*(($i&(3<<0))>>0))/3
105                            ));
106            }
107            return @xpm_colmap;
108    }
109    
110    #--------------------------------------------------------------------
111    # main
112    
113  my $buf;        # tmp buffer for read;  my ($w,$h) = (0,0);
114    my $xv_pix;
115    my @xpm_colmap=generate_xpm_colmap();
116    
117    #($w,$h,@xv_pix) = xvpic_read($xv_pic);
118    my $xv_pic = $X[0]{filename};
119    $w = $X[0]{w};
120    $h = $X[0]{h};
121    $xv_pix = $X[0]{pix};
122    
123  # read pixels  #--------------------------------------------------------------------
124  read XV,$buf,($w*$h);  # make rotated pictures
125  @xv_pix=unpack("C*",$buf);  
126    #sub make_rotated {
127    #       my ($w,$h,$xv_pix)
128    
129  #/* width height ncolors chars_per_pixel */  #/* width height ncolors chars_per_pixel */
130  my @xpm_0= ( "$w $h 256 2" );  #my @xpm_0= ( "$w $h 256 2" );
131  my @xpm_180= ( "$w $h 256 2" );  my @xpm_180= ( "$w $h 256 2" );
132  my @xpm_90= ( "$h $w 256 2" );  my @xpm_90= ( "$h $w 256 2" );
133  my @xpm_270= ( "$h $w 256 2" );  my @xpm_270= ( "$h $w 256 2" );
134    my @xpm_h= ( "$w $h 256 2" );
135    my @xpm_v= ( "$w $h 256 2" );
136    
137  # Generate 332 colour-cube colourmap  #push @xpm_0,@xpm_colmap;
 my @xpm_colmap;  
 for (my $i=0; $i<256; $i++) {  
   
         push(@xpm_colmap,sprintf ("%02x c #%02x%02x%02x",$i,  
                 (255*(($i&(7<<5))>>5))/7,  
                 (255*(($i&(7<<2))>>2))/7,  
                 (255*(($i&(3<<0))>>0))/3  
                 ));  
 }  
   
 push @xpm_0,@xpm_colmap;  
138  push @xpm_180,@xpm_colmap;  push @xpm_180,@xpm_colmap;
139  push @xpm_90,@xpm_colmap;  push @xpm_90,@xpm_colmap;
140  push @xpm_270,@xpm_colmap;  push @xpm_270,@xpm_colmap;
141    push @xpm_h,@xpm_colmap;
142    push @xpm_v,@xpm_colmap;
143    
144  my @pix_0;  my @pix_0;
145  my @pix_180;  my @pix_180;
146  my @pix_90;  my @pix_90;
147  my @pix_270;  my @pix_270;
148    my @pix_h;
149    my @pix_v;
150    
151    my @xv_pix=unpack("C*",$xv_pix);
152    
153  for(my $y=0; $y<$h; $y++) {  for(my $y=0; $y<$h; $y++) {
154          for (my $x=0; $x<$w; $x++) {          for (my $x=0; $x<$w; $x++) {
155                  if (defined($xv_pix[$y*$w+$x])) {                  if (defined($xv_pix[$y*$w+$x])) {
156                          $pix_0[$y*$w+$x] = sprintf("%02x",$xv_pix[$y*$w+$x]);                          $pix_0[$y*$w+$x] = sprintf("%02x",$xv_pix[$y*$w+$x]);
157                          $pix_180[($h-$y-1)*$w+$x] = sprintf("%02x",$xv_pix[$y*$w+$x]);                          $pix_180[($h-$y-1)*$w+($w-$x-1)] = sprintf("%02x",$xv_pix[$y*$w+$x]);
158                          $pix_270[($w-$x-1)*$h+$y] = sprintf("%02x",$xv_pix[$y*$w+$x]);                          $pix_270[($w-$x-1)*$h+$y] = sprintf("%02x",$xv_pix[$y*$w+$x]);
159                          $pix_90[$x*$h+$y] = sprintf("%02x",$xv_pix[$y*$w+$x]);                          $pix_90[$x*$h+$y] = sprintf("%02x",$xv_pix[$y*$w+$x]);
160                            $pix_h[$y*$w+($w-$x-1)] = sprintf("%02x",$xv_pix[$y*$w+$x]);
161                            $pix_v[($h-$y-1)*$w+$x] = sprintf("%02x",$xv_pix[$y*$w+$x]);
162                  } else {                  } else {
163                          print STDERR "undef pixel $x,$y!\n";                          warn "undef pixel $x,$y!\n";
164                  }                  }
165          }          }
166  }  }
# Line 88  my $tmp; Line 172  my $tmp;
172    
173  # portrait  # portrait
174  my $lw=$w*2;  my $lw=$w*2;
175  $tmp=join('',@pix_0); while ($tmp=~s/^(.{$lw})//) { push(@xpm_0,$1); }  #$tmp=join('',@pix_0); while ($tmp=~s/^(.{$lw})//) { push(@xpm_0,$1); }
176  $tmp=join('',@pix_180); while ($tmp=~s/^(.{$lw})//) { push(@xpm_180,$1); }  $tmp=join('',@pix_180); while ($tmp=~s/^(.{$lw})//) { push(@xpm_180,$1); }
177    $tmp=join('',@pix_v); while ($tmp=~s/^(.{$lw})//) { push(@xpm_v,$1); }
178    $tmp=join('',@pix_h); while ($tmp=~s/^(.{$lw})//) { push(@xpm_h,$1); }
179    
180  # landscape  # landscape
181  $lw=$h*2;  $lw=$h*2;
182  $tmp=join('',@pix_90); while ($tmp=~s/^(.{$lw})//) { push(@xpm_90,$1); }  $tmp=join('',@pix_90); while ($tmp=~s/^(.{$lw})//) { push(@xpm_90,$1); }
183  $tmp=join('',@pix_270); while ($tmp=~s/^(.{$lw})//) { push(@xpm_270,$1); }  $tmp=join('',@pix_270); while ($tmp=~s/^(.{$lw})//) { push(@xpm_270,$1); }
184    
185    #--------------------------------------------------------------------
186    # GTK GUI
187    
188  my $window;  my $window;
189  my ($pixmapwid_0, $pixmapwid_180, $pixmapwid_90, $pixmapwid_270);  my ($pixmapwid_0, $pixmapwid_180, $pixmapwid_90, $pixmapwid_270, $pixmapwid_v, $pixmapwid_h);
190  my ($button_0, $button_180, $button_90, $button_270);  my ($button_0, $button_180, $button_90, $button_270, $button_v, $button_h);
191  my ($pixmap_0, $pixmap_180, $pixmap_90, $pixmap_270);  my ($pixmap_0, $pixmap_180, $pixmap_90, $pixmap_270, $pixmap_v, $pixmap_h);
192  my $mask;  my $mask;
193  my $style;  my $style;
194    
195  $window = new Gtk::Window( "toplevel" );  $window = new Gtk::Window( "toplevel" );
196  $window->signal_connect( "delete_event", sub { Gtk->exit( 0 ); } );  $window->signal_connect( "delete_event", sub { Gtk->exit( 0 ); } );
197  $window->border_width( 10 );  $window->border_width( 10 );
198  $window->show();  $window->set_title( "GTK jpegtran" );
199    $window->realize();
 my $hbox = new Gtk::HBox( $true, 0 );  
200    
201  # now for the pixmap from gdk  # now for the pixmap from gdk
202  $style = $window->get_style()->bg( 'normal' );  $style = $window->get_style()->bg( 'normal' );
 ( $pixmap_0, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_0 );  
203    
204  # a pixmap widget to contain the pixmap  #( $pixmap_0, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_0 );
205  $pixmapwid_0 = new Gtk::Pixmap( $pixmap_0, $mask );  #
206  $pixmapwid_0->show();  ## a pixmap widget to contain the pixmap
207    #$pixmapwid_0 = new Gtk::Pixmap( $pixmap_0, $mask );
208  # a button to contain the pixmap widget  #$pixmapwid_0->show();
209  $button_0 = new Gtk::Button();  #
210  $button_0->add( $pixmapwid_0 );  ## a button to contain the pixmap widget
211  $button_0->show();  #$button_0 = new Gtk::Button();
212  $button_0->signal_connect( "clicked", sub { print( "button 0 clicked\n" ); } );  #$button_0->add( $pixmapwid_0 );
213    #$button_0->show();
214    ##$button_0->signal_connect( "clicked", \&jpegtran, "-optimize" );
215    ## make button_0 inactive
216    #$button_0->set_sensitive( $false );
217    
218  # rotate 180  # rotate 180
219  ( $pixmap_180, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_180 );  ( $pixmap_180, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_180 );
# Line 133  $pixmapwid_180->show(); Line 224  $pixmapwid_180->show();
224  $button_180 = new Gtk::Button();  $button_180 = new Gtk::Button();
225  $button_180->add( $pixmapwid_180 );  $button_180->add( $pixmapwid_180 );
226  $button_180->show();  $button_180->show();
227  $button_180->signal_connect( "clicked", sub { print( "button 180 clicked\n" ); } );  $button_180->signal_connect( "clicked", \&jpegtran, "-rotate 180" );
228    
229  # rotate 90  # rotate 90
230  ( $pixmap_90, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_90 );  ( $pixmap_90, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_90 );
# Line 143  $pixmapwid_90->show(); Line 234  $pixmapwid_90->show();
234  $button_90 = new Gtk::Button();  $button_90 = new Gtk::Button();
235  $button_90->add( $pixmapwid_90 );  $button_90->add( $pixmapwid_90 );
236  $button_90->show();  $button_90->show();
237  $button_90->signal_connect( "clicked", sub { print( "button 90 clicked\n" ); } );  $button_90->signal_connect( "clicked", \&jpegtran, "-rotate 90" );
238    
239  # rotate 270  # rotate 270
240  ( $pixmap_270, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_270 );  ( $pixmap_270, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_270 );
# Line 153  $pixmapwid_270->show(); Line 244  $pixmapwid_270->show();
244  $button_270 = new Gtk::Button();  $button_270 = new Gtk::Button();
245  $button_270->add( $pixmapwid_270 );  $button_270->add( $pixmapwid_270 );
246  $button_270->show();  $button_270->show();
247  $button_270->signal_connect( "clicked", sub { print( "button 270 clicked\n" ); } );  $button_270->signal_connect( "clicked", \&jpegtran, "-rotate 270" );
248    
249    # rotate v
250    ( $pixmap_v, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_v );
251    $pixmapwid_v = new Gtk::Pixmap( $pixmap_v, $mask );
252    $pixmapwid_v->show();
253    
254    $button_v = new Gtk::Button();
255    $button_v->add( $pixmapwid_v );
256    $button_v->show();
257    $button_v->signal_connect( "clicked", \&jpegtran, "-flip vertical" );
258    
259    # rotate h
260    ( $pixmap_h, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_h );
261    $pixmapwid_h = new Gtk::Pixmap( $pixmap_h, $mask );
262    $pixmapwid_h->show();
263    
264    $button_h = new Gtk::Button();
265    $button_h->add( $pixmapwid_h );
266    $button_h->show();
267    $button_h->signal_connect( "clicked", \&jpegtran, "-flip horizontal" );
268    
269  # pack, show, draw  # pack, show, draw
270    
271  $hbox->pack_start( $button_0, $false, $false, 0 );  my $hbox_top = new Gtk::HBox( $false, 0 );
272  $hbox->pack_start( $button_90, $false, $false, 0 );  my $hbox_mid = new Gtk::HBox( $true, 0 );
273  $hbox->pack_start( $button_180, $false, $false, 0 );  my $hbox_bot = new Gtk::HBox( $true, 0 );
274  $hbox->pack_start( $button_270, $false, $false, 0 );  
275    
276    #--------------------------------------------------------------------
277    #
278    
279    sub pix2xpm {
280            my ($nr,$w,$h,$xv_pix) = @_;
281    
282            pdebug("pix2xpm w:$w h:$w pix:",length($xv_pix));
283    
284            my @xpm=( "$w $h 256 2" );
285            push @xpm,@xpm_colmap;
286    
287            my @xv_pix=unpack("C*",$xv_pix);
288            my $pix;
289    
290            for(my $i=0; $i<$#xv_pix; $i++) {
291                    $pix .= sprintf("%02x",$xv_pix[$i]);
292            }
293            my $lw=$w*2;
294            while ($pix=~s/^(.{$lw})//) { push(@xpm,$1); }
295    
296            pdebug "pix2xpm retured ",length(join("",@xpm))," bytes, $#xpm lines";
297            return (\@xpm);
298    }
299    
300    sub xpm_button {
301            my ($nr) = @_;
302    
303            pdebug "xpm_button($nr): xpm/pix len: ", length $X[$nr]{xpm},"/",length $X[$nr]{pix};
304    
305            ( $X[$nr]{pixmap}, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @{$X[$nr]{xpm}} );
306    #       ( $pixmap, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm( $window->window, $style, "test.xpm" );
307            $X[$nr]{pixmapwid} = new Gtk::Pixmap( $X[$nr]{pixmap}, $mask );
308            $X[$nr]{pixmapwid}->show();
309    
310            $X[$nr]{button} = new Gtk::Button();
311            $X[$nr]{button}->add( $X[$nr]{pixmapwid} );
312            $X[$nr]{button}->show();
313            $X[$nr]{button}->signal_connect( "clicked", \&select_pic, $nr );
314    
315            return ($X[$nr]{button});
316    }
317    
318    my $arr_l = create_arrow_button( 'left', 'in' );
319    $hbox_top->pack_start( $arr_l, $false, $false, 0 );
320    #$hbox_top->pack_start( $button_0, $false, $false, 0 );
321    
322    
323    for (my $i=0; $i<$#X; $i++) {
324    #for (my $i=0; $i<0; $i++) {
325            $X[$i]{xpm} = pix2xpm($i,$X[$i]{w},$X[$i]{h},$X[$i]{pix});
326            $X[$i]{button}=xpm_button($window, $i );
327            $hbox_top->pack_start( $X[$i]{button}, $false, $false, 0 );
328    }
329    
330    my $arr_r = create_arrow_button( 'right', 'in' );
331    $hbox_top->pack_start( $arr_r, $false, $false, 0 );
332    
333    $hbox_mid->pack_start( $button_90, $false, $false, 0 );
334    $hbox_mid->pack_start( $button_180, $false, $false, 0 );
335    $hbox_mid->pack_start( $button_270, $false, $false, 0 );
336    
337    $hbox_bot->pack_start( $button_v, $false, $false, 0 );
338    $hbox_bot->pack_start( $button_h, $false, $false, 0 );
339    
340    $hbox_top->show();
341    $hbox_mid->show();
342    $hbox_bot->show();
343    
344    sub create_arrow_button
345    {
346            my ( $arrow_type, $shadow_type ) = @_;
347            
348            my $button;
349            my $arrow;
350                        
351            $button = new Gtk::Button();
352            $arrow = new Gtk::Arrow( $arrow_type, $shadow_type );
353                                    
354            $button->add( $arrow );
355            $button->show();
356            $arrow->show();  
357    
358            return ( $button );
359    }
360    
361    
362    my $hbox = new Gtk::HBox( $true, 0 );
363    my $filename_label = new Gtk::Label($xv_pic);
364    $filename_label->show();
365    $hbox->pack_start( $filename_label, $false, $false, 0 );
366  $hbox->show();  $hbox->show();
367  $window->add($hbox);  
368    my $hseparator = new Gtk::HSeparator();
369    $hseparator->show();
370    my $hseparator2 = new Gtk::HSeparator();
371    $hseparator2->show();
372    
373    my $vbox = new Gtk::VBox( $false, 5 );
374    $vbox->pack_start( $hbox_top, $false, $false, 0 );
375    $vbox->pack_start( $hseparator, $false, $false, 0 );
376    $vbox->pack_start( $hbox, $false, $false, 0 );
377    $vbox->pack_start( $hseparator2, $false, $false, 0 );
378    $vbox->pack_start( $hbox_mid, $false, $false, 0 );
379    $vbox->pack_start( $hbox_bot, $false, $false, 0 );
380    $vbox->show();
381    
382    $window->add($vbox);
383    $window->show();
384    
385  main Gtk;  main Gtk;
386  exit( 0 );  exit( 0 );
387    
388    #--------------------------------------------------------------------
389    # call jpegtran command
390    
391    sub jpegtran {
392            my ( $widget, $data ) = @_;
393            print "jpegtran $data\n";
394    }
395    
396    #--------------------------------------------------------------------
397    # select picture
398    
399    sub select_pic {
400            my ( $widget, $data ) = @_;
401            my $xvpic=$X[$data]{filename};
402            print "picture selected: $data ($xvpic)\n";
403            $filename_label->set_text($xvpic);
404    }

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.2

  ViewVC Help
Powered by ViewVC 1.1.26