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

Contents of /gtk-jpegtran.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (show annotations)
Sat Feb 1 00:39:46 2003 UTC (16 years, 1 month 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 #!/usr/bin/perl -w #d
2
3 # GUI front-end to jpegtran to rotate and flip jpegs without loss
4 #
5 # 2000-06-14 Dobrica Pavlinusic <dpavlin@rot13.org>
6
7 use Gtk;
8 use strict;
9
10 init Gtk;
11 set_locale Gtk;
12
13 my $DEBUG = 1;
14 sub pdebug { print STDERR @_,"\n" if ($DEBUG); }
15
16 my $false = 0;
17 my $true = 1;
18
19 # $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 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 pdebug "found $#pic_filenames files in $xv_pic_dir";
46
47 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 }
83
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 #--------------------------------------------------------------------
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 ($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 #--------------------------------------------------------------------
124 # make rotated pictures
125
126 #sub make_rotated {
127 # my ($w,$h,$xv_pix)
128
129 #/* width height ncolors chars_per_pixel */
130 #my @xpm_0= ( "$w $h 256 2" );
131 my @xpm_180= ( "$w $h 256 2" );
132 my @xpm_90= ( "$h $w 256 2" );
133 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 #push @xpm_0,@xpm_colmap;
138 push @xpm_180,@xpm_colmap;
139 push @xpm_90,@xpm_colmap;
140 push @xpm_270,@xpm_colmap;
141 push @xpm_h,@xpm_colmap;
142 push @xpm_v,@xpm_colmap;
143
144 my @pix_0;
145 my @pix_180;
146 my @pix_90;
147 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++) {
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 $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]);
159 $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 {
163 warn "undef pixel $x,$y!\n";
164 }
165 }
166 }
167
168
169 # fill in pixels now
170
171 my $tmp;
172
173 # portrait
174 my $lw=$w*2;
175 #$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); }
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
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 #--------------------------------------------------------------------
186 # GTK GUI
187
188 my $window;
189 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 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 $window->set_title( "GTK jpegtran" );
199 $window->realize();
200
201 # now for the pixmap from gdk
202 $style = $window->get_style()->bg( 'normal' );
203
204 #( $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
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 $button_180->signal_connect( "clicked", \&jpegtran, "-rotate 180" );
228
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 $button_90->signal_connect( "clicked", \&jpegtran, "-rotate 90" );
238
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 $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
270
271 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
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();
367
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;
386 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 }

  ViewVC Help
Powered by ViewVC 1.1.26