/[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

Annotation of /gtk-jpegtran.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide annotations)
Sat Feb 1 00:39:46 2003 UTC (21 years, 2 months ago) by dpavlin
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +296 -62 lines
File MIME type: text/plain
changes so old, that I don't really remember...

1 dpavlin 1.2 #!/usr/bin/perl -w #d
2 dpavlin 1.1
3 dpavlin 1.2 # GUI front-end to jpegtran to rotate and flip jpegs without loss
4 dpavlin 1.1 #
5 dpavlin 1.2 # 2000-06-14 Dobrica Pavlinusic <dpavlin@rot13.org>
6 dpavlin 1.1
7     use Gtk;
8     use strict;
9    
10     init Gtk;
11     set_locale Gtk;
12    
13 dpavlin 1.2 my $DEBUG = 1;
14     sub pdebug { print STDERR @_,"\n" if ($DEBUG); }
15    
16 dpavlin 1.1 my $false = 0;
17     my $true = 1;
18    
19 dpavlin 1.2 # $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 dpavlin 1.1
41 dpavlin 1.2 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 dpavlin 1.1
45 dpavlin 1.2 pdebug "found $#pic_filenames files in $xv_pic_dir";
46 dpavlin 1.1
47 dpavlin 1.2 my $dir=$xv_pic_dir;
48     $dir=~s/\.xvpics//;
49    
50     foreach my $filename (@pic_filenames) {
51     pdebug "gronk $filename";
52     my ($w,$h,$pix) = xvpic_read("$xv_pic_dir/$filename");
53     my (%tmp) = ( dir=>$dir, filename=>$filename, w=>$w, h=>$h, pix=>$pix );
54     push @X,\%tmp;
55     }
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 dpavlin 1.1 }
83 dpavlin 1.2
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 dpavlin 1.1 }
93    
94 dpavlin 1.2 #--------------------------------------------------------------------
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 dpavlin 1.1
113 dpavlin 1.2 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 dpavlin 1.1
123 dpavlin 1.2 #--------------------------------------------------------------------
124     # make rotated pictures
125    
126     #sub make_rotated {
127     # my ($w,$h,$xv_pix)
128 dpavlin 1.1
129     #/* width height ncolors chars_per_pixel */
130 dpavlin 1.2 #my @xpm_0= ( "$w $h 256 2" );
131 dpavlin 1.1 my @xpm_180= ( "$w $h 256 2" );
132     my @xpm_90= ( "$h $w 256 2" );
133     my @xpm_270= ( "$h $w 256 2" );
134 dpavlin 1.2 my @xpm_h= ( "$w $h 256 2" );
135     my @xpm_v= ( "$w $h 256 2" );
136 dpavlin 1.1
137 dpavlin 1.2 #push @xpm_0,@xpm_colmap;
138 dpavlin 1.1 push @xpm_180,@xpm_colmap;
139     push @xpm_90,@xpm_colmap;
140     push @xpm_270,@xpm_colmap;
141 dpavlin 1.2 push @xpm_h,@xpm_colmap;
142     push @xpm_v,@xpm_colmap;
143 dpavlin 1.1
144     my @pix_0;
145     my @pix_180;
146     my @pix_90;
147     my @pix_270;
148 dpavlin 1.2 my @pix_h;
149     my @pix_v;
150    
151     my @xv_pix=unpack("C*",$xv_pix);
152 dpavlin 1.1
153     for(my $y=0; $y<$h; $y++) {
154     for (my $x=0; $x<$w; $x++) {
155     if (defined($xv_pix[$y*$w+$x])) {
156     $pix_0[$y*$w+$x] = sprintf("%02x",$xv_pix[$y*$w+$x]);
157 dpavlin 1.2 $pix_180[($h-$y-1)*$w+($w-$x-1)] = sprintf("%02x",$xv_pix[$y*$w+$x]);
158 dpavlin 1.1 $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]);
160 dpavlin 1.2 $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 dpavlin 1.1 } else {
163 dpavlin 1.2 warn "undef pixel $x,$y!\n";
164 dpavlin 1.1 }
165     }
166     }
167    
168    
169     # fill in pixels now
170    
171     my $tmp;
172    
173     # portrait
174     my $lw=$w*2;
175 dpavlin 1.2 #$tmp=join('',@pix_0); while ($tmp=~s/^(.{$lw})//) { push(@xpm_0,$1); }
176 dpavlin 1.1 $tmp=join('',@pix_180); while ($tmp=~s/^(.{$lw})//) { push(@xpm_180,$1); }
177 dpavlin 1.2 $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 dpavlin 1.1
180     # landscape
181     $lw=$h*2;
182     $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); }
184    
185 dpavlin 1.2 #--------------------------------------------------------------------
186     # GTK GUI
187    
188 dpavlin 1.1 my $window;
189 dpavlin 1.2 my ($pixmapwid_0, $pixmapwid_180, $pixmapwid_90, $pixmapwid_270, $pixmapwid_v, $pixmapwid_h);
190     my ($button_0, $button_180, $button_90, $button_270, $button_v, $button_h);
191     my ($pixmap_0, $pixmap_180, $pixmap_90, $pixmap_270, $pixmap_v, $pixmap_h);
192 dpavlin 1.1 my $mask;
193     my $style;
194    
195     $window = new Gtk::Window( "toplevel" );
196     $window->signal_connect( "delete_event", sub { Gtk->exit( 0 ); } );
197     $window->border_width( 10 );
198 dpavlin 1.2 $window->set_title( "GTK jpegtran" );
199     $window->realize();
200 dpavlin 1.1
201     # now for the pixmap from gdk
202     $style = $window->get_style()->bg( 'normal' );
203    
204 dpavlin 1.2 #( $pixmap_0, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_0 );
205     #
206     ## a pixmap widget to contain the pixmap
207     #$pixmapwid_0 = new Gtk::Pixmap( $pixmap_0, $mask );
208     #$pixmapwid_0->show();
209     #
210     ## a button to contain the pixmap widget
211     #$button_0 = new Gtk::Button();
212     #$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 dpavlin 1.1
218     # rotate 180
219     ( $pixmap_180, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_180 );
220    
221     $pixmapwid_180 = new Gtk::Pixmap( $pixmap_180, $mask );
222     $pixmapwid_180->show();
223    
224     $button_180 = new Gtk::Button();
225     $button_180->add( $pixmapwid_180 );
226     $button_180->show();
227 dpavlin 1.2 $button_180->signal_connect( "clicked", \&jpegtran, "-rotate 180" );
228 dpavlin 1.1
229     # rotate 90
230     ( $pixmap_90, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_90 );
231     $pixmapwid_90 = new Gtk::Pixmap( $pixmap_90, $mask );
232     $pixmapwid_90->show();
233    
234     $button_90 = new Gtk::Button();
235     $button_90->add( $pixmapwid_90 );
236     $button_90->show();
237 dpavlin 1.2 $button_90->signal_connect( "clicked", \&jpegtran, "-rotate 90" );
238 dpavlin 1.1
239     # rotate 270
240     ( $pixmap_270, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window, $style, @xpm_270 );
241     $pixmapwid_270 = new Gtk::Pixmap( $pixmap_270, $mask );
242     $pixmapwid_270->show();
243    
244     $button_270 = new Gtk::Button();
245     $button_270->add( $pixmapwid_270 );
246     $button_270->show();
247 dpavlin 1.2 $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 dpavlin 1.1
269     # pack, show, draw
270    
271 dpavlin 1.2 my $hbox_top = new Gtk::HBox( $false, 0 );
272     my $hbox_mid = new Gtk::HBox( $true, 0 );
273     my $hbox_bot = new Gtk::HBox( $true, 0 );
274    
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 dpavlin 1.1
322 dpavlin 1.2
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 dpavlin 1.1 $hbox->show();
367 dpavlin 1.2
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 dpavlin 1.1
385     main Gtk;
386     exit( 0 );
387    
388 dpavlin 1.2 #--------------------------------------------------------------------
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     }

  ViewVC Help
Powered by ViewVC 1.1.26