summaryrefslogtreecommitdiffstats
path: root/hacks/vidwhacker
diff options
context:
space:
mode:
Diffstat (limited to 'hacks/vidwhacker')
-rwxr-xr-xhacks/vidwhacker497
1 files changed, 0 insertions, 497 deletions
diff --git a/hacks/vidwhacker b/hacks/vidwhacker
deleted file mode 100755
index 402e2c7..0000000
--- a/hacks/vidwhacker
+++ /dev/null
@@ -1,497 +0,0 @@
-#!/usr/bin/perl -w
-# vidwhacker, for xscreensaver. Copyright (c) 1998-2020 Jamie Zawinski.
-#
-# Permission to use, copy, modify, distribute, and sell this software and its
-# documentation for any purpose is hereby granted without fee, provided that
-# the above copyright notice appear in all copies and that both that
-# copyright notice and this permission notice appear in supporting
-# documentation. No representations are made about the suitability of this
-# software for any purpose. It is provided "as is" without express or
-# implied warranty.
-#
-# This program grabs a frame of video, then uses various pbm filters to
-# munge the image in random nefarious ways, then uses xloadimage, xli, or xv
-# to put it on the root window. This works out really nicely if you just
-# feed some random TV station into it...
-#
-# Created: 14-Apr-01.
-
-require 5;
-use diagnostics;
-use strict;
-
-my $progname = $0; $progname =~ s@.*/@@g;
-my ($version) = ('$Revision: 1.34 $' =~ m/\s(\d[.\d]+)\s/s);
-
-my $verbose = 0;
-my $use_stdin = 0;
-my $use_stdout = 0;
-my $video_p = 0;
-my $file_p = 1;
-my $delay = 5;
-my $imagedir;
-
-my $screen_width = -1;
-
-my $displayer = "xscreensaver-getimage -root -file";
-
-sub which($);
-
-# apparently some versions of netpbm call it "pamoil" instead of "pgmoil"...
-#
-my $pgmoil = (which("pamoil") ? "pamoil" : "pgmoil");
-
-
-# List of interesting PPM filter pipelines.
-# In this list, the following magic words may be used:
-#
-# COLORS a randomly-selected pair of RGB foreground/background colors.
-# FILE1 the (already-existing) input PPM file (ok to overwrite it).
-# FILE2-FILE4 names of other tmp files you can use.
-#
-# These commands should read from FILE1, and write to stdout.
-# All tmp files will be deleted afterward.
-#
-my @filters = (
- "ppmtopgm FILE1 | pgmedge | pgmtoppm COLORS | ppmnorm",
- "ppmtopgm FILE1 | pgmenhance | pgmtoppm COLORS",
- "ppmtopgm FILE1 | $pgmoil | pgmtoppm COLORS",
- "ppmtopgm FILE1 | pgmbentley | pgmtoppm COLORS",
-
- "ppmrelief FILE1 | ppmtopgm | pgmedge | ppmrelief | ppmtopgm |" .
- " pgmedge | pnminvert | pgmtoppm COLORS",
-
- "ppmspread 71 FILE1 > FILE2 ; " .
- " pnmarith -add FILE1 FILE2 ; ",
-
- "pnmflip -lr < FILE1 > FILE2 ; " .
- " pnmarith -multiply FILE1 FILE2 > FILE3 ; " .
- " pnmflip -tb FILE3 | ppmnorm > FILE2 ; " .
- " pnmarith -multiply FILE1 FILE2",
-
- "pnmflip -lr FILE1 > FILE2 ; " .
- " pnmarith -difference FILE1 FILE2",
-
- "pnmflip -tb FILE1 > FILE2 ; " .
- " pnmarith -difference FILE1 FILE2",
-
- "pnmflip -lr FILE1 | pnmflip -tb > FILE2 ; " .
- " pnmarith -difference FILE1 FILE2",
-
- "ppmtopgm < FILE1 | pgmedge > FILE2 ; " .
- " pnmarith -difference FILE1 FILE2 > FILE3 ; " .
- " cp FILE3 FILE1 ; " .
- " ppmtopgm < FILE1 | pgmedge > FILE2 ; " .
- " pnmarith -difference FILE1 FILE2 > FILE3 ; " .
- " ppmnorm < FILE1",
-
- "pnmflip -lr < FILE1 > FILE2 ; " .
- " pnmarith -multiply FILE1 FILE2 | ppmrelief | ppmnorm | pnminvert",
-
- "pnmflip -lr FILE1 > FILE2 ; " .
- " pnmarith -subtract FILE1 FILE2 | ppmrelief | ppmtopgm | pgmedge",
-
- "pgmcrater -number 20000 -width WIDTH -height HEIGHT FILE1 | " .
- " pgmtoppm COLORS > FILE2 ; " .
- " pnmarith -difference FILE1 FILE2 > FILE3 ; " .
- " pnmflip -tb FILE3 | ppmnorm > FILE2 ; " .
- " pnmarith -multiply FILE1 FILE2",
-
- "ppmshift 30 FILE1 | ppmtopgm | $pgmoil | pgmedge | " .
- " pgmtoppm COLORS > FILE2 ; " .
- " pnmarith -difference FILE1 FILE2",
-
- "ppmpat -madras WIDTH HEIGHT | pnmdepth 255 > FILE2 ; " .
- " pnmarith -difference FILE1 FILE2",
-
- "ppmpat -tartan WIDTH HEIGHT | pnmdepth 255 > FILE2 ; " .
- " pnmarith -difference FILE1 FILE2",
-
- "ppmpat -camo WIDTH HEIGHT | pnmdepth 255 | ppmshift 50 > FILE2 ; " .
- " pnmarith -multiply FILE1 FILE2",
-
- "pgmnoise WIDTH HEIGHT | pgmedge | pgmtoppm COLORS > FILE2 ; " .
- " pnmarith -difference FILE1 FILE2 | pnmdepth 255 | pnmsmooth",
-);
-
-
-# Any files on this list will be deleted at exit.
-#
-my @all_tmpfiles = ();
-
-sub exit_cleanup() {
- print STDERR "$progname: delete tmp files\n" if ($verbose);
- unlink @all_tmpfiles;
-}
-
-sub signal_cleanup() {
- my ($sig) = @_;
- print STDERR "$progname: caught SIG$sig\n" if ($verbose);
- exit 1;
-}
-
-sub init_signals() {
-
- $SIG{HUP} = \&signal_cleanup;
- $SIG{INT} = \&signal_cleanup;
- $SIG{QUIT} = \&signal_cleanup;
- $SIG{ABRT} = \&signal_cleanup;
- $SIG{KILL} = \&signal_cleanup;
- $SIG{TERM} = \&signal_cleanup;
-
- # Need this so that if giftopnm dies, we don't die.
- $SIG{PIPE} = 'IGNORE';
-}
-
-END { exit_cleanup(); }
-
-
-# returns the full path of the named program, or undef.
-#
-sub which($) {
- my ($prog) = @_;
- foreach (split (/:/, $ENV{PATH})) {
- if (-x "$_/$prog") {
- return $prog;
- }
- }
- return undef;
-}
-
-
-# Choose random foreground and background colors
-#
-sub randcolors() {
- return sprintf ("#%02x%02x%02x-#%02x%02x%02x",
- int(rand()*60),
- int(rand()*60),
- int(rand()*60),
- 120+int(rand()*135),
- 120+int(rand()*135),
- 120+int(rand()*135));
-}
-
-
-
-sub filter_subst($$$@) {
- my ($filter, $width, $height, @tmpfiles) = @_;
- my $colors = randcolors();
- $filter =~ s/\bWIDTH\b/$width/g;
- $filter =~ s/\bHEIGHT\b/$height/g;
- $filter =~ s/\bCOLORS\b/'$colors'/g;
- my $i = 1;
- foreach my $t (@tmpfiles) {
- $filter =~ s/\bFILE$i\b/$t/g;
- $i++;
- }
- if ($filter =~ m/([A-Z]+)/) {
- error ("internal error: what is \"$1\"?");
- }
- $filter =~ s/ +/ /g;
- return $filter;
-}
-
-# Frobnicate the image in some random way.
-#
-sub frob_ppm($) {
- my ($ppm_data) = @_;
- $_ = $ppm_data;
-
- error ("0-length data") if (!defined($ppm_data) || $ppm_data eq "");
- error ("not a PPM file") unless (m/^P\d\n/s);
- my ($width, $height) = m/^P\d\n(\d+) (\d+)\n/s;
- error ("got a bogus PPM") unless ($width && $height);
-
- my $tmpdir = $ENV{TMPDIR};
- $tmpdir = "/tmp" unless $tmpdir;
- my $fn = sprintf ("%s/vidwhacker-0-%08x", $tmpdir, rand(0xFFFFFFFF));
- my $fn1 = sprintf ("%s/vidwhacker-1-%08x", $tmpdir, rand(0xFFFFFFFF));
- my $fn2 = sprintf ("%s/vidwhacker-2-%08x", $tmpdir, rand(0xFFFFFFFF));
- my $fn3 = sprintf ("%s/vidwhacker-3-%08x", $tmpdir, rand(0xFFFFFFFF));
- my @files = ( "$fn", "$fn1", "$fn2", "$fn3" );
- push @all_tmpfiles, @files;
-
- my $n = int(rand($#filters+1));
- my $filter = $filters[$n];
-
- if ($verbose == 1) {
- printf STDERR "$progname: running filter $n\n";
- } elsif ($verbose > 1) {
- my $f = $filter;
- $f =~ s/ +/ /g;
- $f =~ s/^ */\t/;
- $f =~ s/ *\|/\n\t|/g;
- $f =~ s/ *\; */ ;\n\t/g;
- print STDERR "$progname: filter $n:\n\n$f\n\n" if $verbose;
- }
-
- $filter = filter_subst ($filter, $width, $height, @files);
-
- unlink @files;
-
- local *OUT;
- open (OUT, ">$files[0]") || error ("writing $files[0]: $!");
- print OUT $ppm_data;
- close OUT;
-
- $filter = "( $filter )";
- $filter .= "2>/dev/null" unless ($verbose > 1);
-
- local *IN;
- open (IN, "$filter |") || error ("opening pipe: $!");
- $ppm_data = "";
- while (<IN>) { $ppm_data .= $_; }
- close IN;
-
- unlink @files;
- return $ppm_data;
-}
-
-
-sub read_config() {
- my $conf = "$ENV{HOME}/.xscreensaver";
-
- my $had_dir = defined($imagedir);
-
- local *IN;
- open (IN, "<$conf") || error ("reading $conf: $!");
- while (<IN>) {
- if (!$imagedir && m/^imageDirectory:\s+(.*)\s*$/i) { $imagedir = $1; }
- elsif (m/^grabVideoFrames:\s+true\s*$/i) { $video_p = 1; }
- elsif (m/^grabVideoFrames:\s+false\s*$/i) { $video_p = 0; }
- elsif (m/^chooseRandomImages:\s+true\s*$/i) { $file_p = 1; }
- elsif (m/^chooseRandomImages:\s+false\s*$/i) { $file_p = 0; }
- }
- close IN;
-
- $file_p = 1 if $had_dir;
-
- $imagedir = undef unless ($imagedir && $imagedir ne '');
-
- if (!$file_p && !$video_p) {
-# error ("neither grabVideoFrames nor chooseRandomImages are set\n\t") .
-# "in $conf; $progname requires one or both."
- $file_p = 1;
- }
-
- if ($file_p) {
- error ("no imageDirectory set in $conf") unless $imagedir;
- error ("imageDirectory $imagedir doesn't exist") unless (-d $imagedir);
- }
-
- if ($verbose > 1) {
- printf STDERR "$progname: grab video: $video_p\n";
- printf STDERR "$progname: grab images: $file_p\n";
- printf STDERR "$progname: directory: $imagedir\n";
- }
-
-}
-
-
-sub get_ppm() {
- if ($use_stdin) {
- print STDERR "$progname: reading from stdin\n" if ($verbose > 1);
- my $ppm = "";
- while (<STDIN>) { $ppm .= $_; }
- return $ppm;
-
- } else {
-
- my $do_file_p;
-
- if ($file_p && $video_p) {
- $do_file_p = (int(rand(2)) == 0);
- print STDERR "$progname: doing " . ($do_file_p ? "files" : "video") ."\n"
- if ($verbose);
- }
- elsif ($file_p) { $do_file_p = 1; }
- elsif ($video_p) { $do_file_p = 0; }
- else {
- error ("internal error: not grabbing files or video?");
- }
-
- my $v = ($verbose <= 1 ? "" : "-" . ("v" x ($verbose-1)));
- my $cmd;
- if ($do_file_p) {
- $cmd = "xscreensaver-getimage-file $v --name \"$imagedir\"";
- } else {
- $cmd = "xscreensaver-getimage-video $v";
- }
-
- my $ppm;
-
- print STDERR "$progname: running: $cmd\n" if ($verbose > 1);
- my $fn = `$cmd`;
- $fn =~ s/\n$//s;
- error ("didn't get a file?") if ($fn eq "");
- $fn = "$imagedir/$fn" unless ($fn =~ m@^/@s);
-
- print STDERR "$progname: selected file $fn\n" if ($verbose > 1);
-
- if ($fn =~ m/\.gif/i) { $cmd = "giftopnm < \"$fn\""; }
- elsif ($fn =~ m/\.jpe?g/i) { $cmd = "exiftran -o /dev/stdout -a \"$fn\" | djpeg"; }
- elsif ($fn =~ m/\.png/i) { $cmd = "pngtopnm < \"$fn\""; }
- elsif ($fn =~ m/\.xpm/i) { $cmd = "xpmtoppm < \"$fn\""; }
- elsif ($fn =~ m/\.bmp/i) { $cmd = "bmptoppm < \"$fn\""; }
- elsif ($fn =~ m/\.tiff?/i) { $cmd = "tifftopnm < \"$fn\""; }
- elsif ($fn =~ m/\.p[bgp]m/i) { $cmd = "cat \"$fn\""; }
- else {
- print STDERR "$progname: $fn: unrecognized file extension\n";
- # go around the loop and get another
- return undef;
- }
-
- print STDERR "$progname: converting with: $cmd\n" if ($verbose > 1);
- $cmd .= " 2>/dev/null" unless ($verbose > 1);
- $ppm = `$cmd`;
-
- unlink $fn if (!$do_file_p);
-
-
- return $ppm;
- }
-}
-
-sub dispose_ppm($) {
- my ($ppm) = @_;
-
- error ("0-length data") if (!defined($ppm) || $ppm eq "");
- error ("not a PPM file") unless ($ppm =~ m/^P\d\n/s);
-
- if ($use_stdout) {
- print STDERR "$progname: writing to stdout\n" if ($verbose > 1);
- print $ppm;
-
- } else {
- my $tmpdir = $ENV{TMPDIR};
- $tmpdir = "/tmp" unless $tmpdir;
- my $fn = sprintf ("%s/vidwhacker-%08x.ppm", $tmpdir, rand(0xFFFFFFFF));
- local *OUT;
- unlink $fn;
- push @all_tmpfiles, $fn;
- open (OUT, ">$fn") || error ("writing $fn: $!");
- print OUT $ppm;
- close OUT;
-
- my @cmd = split (/ +/, $displayer);
- push @cmd, $fn;
- print STDERR "$progname: executing \"" . join(" ", @cmd) . "\"\n"
- if ($verbose);
- system (@cmd);
-
- my $exit_value = $? >> 8;
- my $signal_num = $? & 127;
- my $dumped_core = $? & 128;
-
- unlink $fn;
-
- error ("$cmd[0]: core dumped!") if ($dumped_core);
- error ("$cmd[0]: signal $signal_num!") if ($signal_num);
- error ("$cmd[0]: exited with $exit_value!") if ($exit_value);
- }
-}
-
-
-my $stdin_ppm = undef;
-
-sub vidwhack() {
- my $ppm;
- if ($use_stdin) {
- if (!defined($stdin_ppm)) {
- $stdin_ppm = get_ppm();
- }
- $ppm = $stdin_ppm;
- } else {
- my $max_err_count = 20;
- my $err_count = 0;
- while (!defined($ppm)) {
- $ppm = get_ppm();
- if (!defined ($ppm)) {
- $err_count++
- } else {
- $ppm = frob_ppm ($ppm);
- undef $ppm if (defined ($ppm) && $ppm eq "");
- $err_count++ if (!defined ($ppm));
- };
- error ("too many errors, too few images!")
- if ($err_count > $max_err_count);
- }
- }
-
- dispose_ppm ($ppm);
- $ppm = undef;
-}
-
-
-sub error($) {
- my ($err) = @_;
- print STDERR "$progname: $err\n";
- exit 1;
-}
-
-sub usage() {
- print STDERR "VidWhacker, Copyright (c) 2001 Jamie Zawinski <jwz\@jwz.org>\n";
- print STDERR " https://www.jwz.org/xscreensaver/";
- print STDERR "\n";
- print STDERR "usage: $0 [-display dpy] [-verbose]\n";
- print STDERR "\t\t[-root | -window | -window-id 0xXXXXX ]\n";
- print STDERR "\t\t[-stdin] [-stdout] [-delay secs]\n";
- print STDERR "\t\t[-directory image_directory]\n";
- exit 1;
-}
-
-sub main() {
- while ($_ = $ARGV[0]) {
- shift @ARGV;
- if (m/^--?verbose$/) { $verbose++; }
- elsif (m/^-v+$/) { $verbose += length($_)-1; }
- elsif (m/^(-display|-disp|-dis|-dpy|-d)$/) { $ENV{DISPLAY} = shift @ARGV; }
- elsif (m/^--?stdin$/) { $use_stdin = 1; }
- elsif (m/^--?stdout$/) { $use_stdout = 1; }
- elsif (m/^--?delay$/) { $delay = shift @ARGV; }
- elsif (m/^--?dir(ectory)?$/) { $imagedir = shift @ARGV; }
- elsif (m/^--?root$/) { }
- elsif (m/^--?window-id$/) {
- my $id = shift @ARGV;
- error ("unparsable window id: $id")
- unless ($id =~ m/^\d+$|^0x[\da-f]+$/i);
- $displayer =~ s/--?root\b/$id/ ||
- error ("unable to munge displayer: $displayer");
- }
- elsif (m/^--?window$/) {
- print STDERR "$progname: sorry, \"-window\" is unimplemented.\n";
- print STDERR "$progname: use \"-stdout\" and pipe to a displayer.\n";
- exit 1;
- }
- elsif (m/^-./) { usage; }
- else { usage; }
- }
-
- init_signals();
-
- read_config;
-
- # sanity checking - is pbm installed?
- # (this is a non-exhaustive but representative list)
- foreach ("ppmtopgm", "pgmenhance", "pnminvert", "pnmarith", "pnmdepth") {
- which ($_) || error "$_ not found on \$PATH.";
- }
-
- if (!$use_stdout) {
- $_ = `xdpyinfo 2>&-`;
- ($screen_width) =~ m/ dimensions: +(\d+)x(\d+) pixels/;
- $screen_width = 800 unless $screen_width > 0;
- }
-
- if ($use_stdout) {
- vidwhack();
- } else {
- while (1) {
- vidwhack();
- sleep $delay;
- }
- }
-}
-
-main();
-exit 0;