PageRenderTime 26ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/bin/ppmfade

http://shell-simulator.googlecode.com/
Perl | 316 lines | 253 code | 17 blank | 46 comment | 53 complexity | a2aa854f07df6d0b8b6122cdc67b1642 MD5 | raw file
Possible License(s): GPL-3.0, CPL-1.0
  1. #!/usr/bin/perl -w
  2. #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  3. #
  4. # This program creates a fade (a sequence of frames) between two images.
  5. #
  6. # By Bryan Henderson, Olympia WA; March 2000
  7. #
  8. # Contributed to the public domain by its author.
  9. #
  10. # Inspired by the program Pbmfade by Wesley C. Barris of AHPCRC,
  11. # Minnesota Supercomputer Center, Inc. January 7, 1994. Pbmfade does
  12. # much the same thing, but handles non-Netpbm formats too, and is
  13. # implemented in a more primitive language.
  14. #
  15. #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  16. use strict;
  17. use File::Temp "tempdir";
  18. my $SPREAD = 1;
  19. my $SHIFT = 2;
  20. my $RELIEF = 3;
  21. my $OIL = 4;
  22. my $EDGE = 5;
  23. my $BENTLEY = 6;
  24. my $BLOCK = 7;
  25. my $MIX = 8;
  26. #
  27. # Set some defaults.
  28. #
  29. my $nframes = 30; # total number of files created (1 sec)
  30. my $first_file = "undefined";
  31. my $last_file = "undefined";
  32. my $base_name = "fade"; # default base name of output files
  33. my $image = "ppm"; # default output storage format
  34. my $mode = $SPREAD; # default fading mode
  35. #
  36. # Check those command line args.
  37. #
  38. if (@ARGV == 0) {
  39. usage();
  40. }
  41. my $n; # argument number
  42. for ($n = 0; $n < @ARGV; $n++) {
  43. if ("$ARGV[$n]" eq "-f") {
  44. $n++;
  45. $first_file = $ARGV[$n];
  46. if (-e $first_file) {
  47. } else {
  48. print "I can't find $first_file\n";
  49. exit 20;
  50. }
  51. } elsif ($ARGV[$n] eq "-l") {
  52. $n++;
  53. $last_file = $ARGV[$n];
  54. if (-e $last_file) {
  55. } else {
  56. print "I can't find $last_file\n";
  57. exit 20;
  58. }
  59. } elsif ($ARGV[$n] eq "-base") {
  60. $n++;
  61. $base_name = $ARGV[$n];
  62. } elsif ($ARGV[$n] eq "-spread") {
  63. $mode = $SPREAD;
  64. } elsif ($ARGV[$n] eq "-shift") {
  65. $mode = $SHIFT;
  66. } elsif ($ARGV[$n] eq "-relief") {
  67. $mode = $RELIEF;
  68. } elsif ($ARGV[$n] eq "-oil") {
  69. $mode = $OIL;
  70. } elsif ("$ARGV[$n]" eq "-edge") {
  71. $mode = $EDGE;
  72. } elsif ("$ARGV[$n]" eq "-bentley") {
  73. $mode = $BENTLEY;
  74. } elsif ("$ARGV[$n]" eq "-block") {
  75. $mode = $BLOCK;
  76. } elsif ("$ARGV[$n]" eq "-mix") {
  77. $mode = $MIX;
  78. } elsif ($ARGV[$n] eq "-help" || $ARGV[$n] eq "-h") {
  79. usage();
  80. } else {
  81. print "Unknown argument: $ARGV[$n]\n";
  82. exit 100;
  83. }
  84. }
  85. #
  86. # Define a couple linear ramps.
  87. #
  88. # We don't use element 0 of these arrays.
  89. my @spline10 = (0, 0, 0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 0.77, 0.88, 1.0);
  90. my @spline20 = (0, 0, 0.05, 0.11, 0.16, 0.21, 0.26, 0.32, 0.37, 0.42, 0.47,
  91. 0.53, 0.58, 0.63, 0.69, 0.74, 0.79, 0.84, 0.89, 0.95, 1.0);
  92. #
  93. # Just what are we supposed to do?
  94. #
  95. my ($height, $width); # width and height of our frames
  96. if ($first_file ne "undefined") {
  97. if ((`pnmfile $first_file` =~ m{\b(\d+)\sby\s(\d+)} )) {
  98. $width = $1; $height = $2;
  99. } else {
  100. print("Unrecognized results from pnmfile on $first_file.\n");
  101. exit(50);
  102. }
  103. } elsif ($last_file ne "undefined") {
  104. if ((`pnmfile $last_file` =~ m{\b(\d+)\sby\s(\d+)} )) {
  105. $width = $1; $height = $2;
  106. } else {
  107. print("Unrecognized results from pnmfile on $first_file.\n");
  108. exit(50);
  109. }
  110. } else {
  111. print("ppmfade: You must specify -f or -l (or both)\n");
  112. exit(90);
  113. }
  114. print("Frames are " . $width . "W x " . $height . "H\n");
  115. #
  116. # We create a tmp-directory right here
  117. #
  118. my $tmpdir = tempdir("ppmfade.XXXXXX", CLEANUP => 1);
  119. if ($first_file eq "undefined") {
  120. print "Fading from black to ";
  121. system("ppmmake \\#000 $width $height >$tmpdir/junk1$$.ppm");
  122. } else {
  123. print "Fading from $first_file to ";
  124. system("cp", $first_file, "$tmpdir/junk1$$.ppm");
  125. }
  126. if ($last_file eq "undefined") {
  127. print "black.\n";
  128. system("ppmmake \\#000 $width $height >$tmpdir/junk2$$.ppm");
  129. } else {
  130. print "$last_file\n";
  131. system("cp", $last_file, "$tmpdir/junk2$$.ppm");
  132. }
  133. #
  134. # Perform the fade.
  135. #
  136. # Here's what our temporary files are:
  137. # $tmpdir/junk1$$.ppm: The original (fade-from) image
  138. # $tmpdir/junk2$$.ppm: The target (fade-from) image
  139. # $tmpdir/junk3$$.ppm: The frame of the fade for the current iteration of the
  140. # the for loop.
  141. # $tmpdir/junk1a$$.ppm: If the fade involves a ppmmix sequence from one intermediate
  142. # image to another, this is the first frame of that
  143. # sequence.
  144. # $tmpdir/junk2a$$.ppm: This is the last frame of the above-mentioned ppmmix sequence
  145. my $i; # Frame number
  146. for ($i = 1; $i <= $nframes; $i++) {
  147. print("Creating $i of $nframes...\n");
  148. if ($mode eq $SPREAD) {
  149. if ($i <= 10) {
  150. my $n = $spline20[$i] * 100;
  151. system("ppmspread $n $tmpdir/junk1$$.ppm >$tmpdir/junk3$$.ppm");
  152. } elsif ($i <= 20) {
  153. my $n;
  154. $n = $spline20[$i] * 100;
  155. system("ppmspread $n $tmpdir/junk1$$.ppm >$tmpdir/junk1a$$.ppm");
  156. $n = (1-$spline20[$i-10]) * 100;
  157. system("ppmspread $n $tmpdir/junk2$$.ppm >$tmpdir/junk2a$$.ppm");
  158. $n = $spline10[$i-10];
  159. system("ppmmix $n $tmpdir/junk1a$$.ppm $tmpdir/junk2a$$.ppm >$tmpdir/junk3$$.ppm");
  160. } else {
  161. my $n = (1-$spline20[$i-10])*100;
  162. ystem("ppmspread $n $tmpdir/junk2$$.ppm >$tmpdir/junk3$$.ppm");
  163. }
  164. } elsif ($mode eq $SHIFT) {
  165. if ($i <= 10) {
  166. my $n = $spline20[$i] * 100;
  167. system("ppmshift $n $tmpdir/junk1$$.ppm >$tmpdir/junk3$$.ppm");
  168. } elsif ($i <= 20) {
  169. my $n;
  170. $n = $spline20[$i] * 100;
  171. system("ppmshift $n $tmpdir/junk1$$.ppm >$tmpdir/junk1a$$.ppm");
  172. $n = (1-$spline20[$i-10])*100;
  173. system("ppmshift $n $tmpdir/junk2$$.ppm >$tmpdir/junk2a$$.ppm");
  174. $n = $spline10[$i-10];
  175. system("ppmmix $n $tmpdir/junk1a$$.ppm $tmpdir/junk2a$$.ppm >$tmpdir/junk3$$.ppm");
  176. } else {
  177. my $n = (1-$spline20[$i-10]) * 100;
  178. system("ppmshift $n $tmpdir/junk2$$.ppm >$tmpdir/junk3$$.ppm");
  179. }
  180. } elsif ($mode eq $RELIEF) {
  181. if ($i == 1) {
  182. system("ppmrelief $tmpdir/junk1$$.ppm >$tmpdir/junk1r$$.ppm");
  183. }
  184. if ($i <= 10) {
  185. my $n = $spline10[$i];
  186. system("ppmmix $n $tmpdir/junk1$$.ppm $tmpdir/junk1r$$.ppm >$tmpdir/junk3$$.ppm");
  187. } elsif ($i <= 20) {
  188. my $n = $spline10[$i-10];
  189. system("ppmmix $n $tmpdir/junk1r$$.ppm $tmpdir/junk2r$$.ppm >$tmpdir/junk3$$.ppm");
  190. } else {
  191. my $n = $spline10[$i-20];
  192. system("ppmmix $n $tmpdir/junk2r$$.ppm $tmpdir/junk2$$.ppm >$tmpdir/junk3$$.ppm");
  193. }
  194. if ($i == 10) {
  195. system("ppmrelief $tmpdir/junk2$$.ppm >$tmpdir/junk2r$$.ppm");
  196. }
  197. } elsif ($mode eq $OIL) {
  198. if ($i == 1) {
  199. system("ppmtopgm $tmpdir/junk1$$.ppm | pgmoil >$tmpdir/junko$$.ppm");
  200. system("rgb3toppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm " .
  201. ">$tmpdir/junk1o$$.ppm");
  202. }
  203. if ($i <= 10) {
  204. my $n = $spline10[$i];
  205. system("ppmmix $n $tmpdir/junk1$$.ppm $tmpdir/junk1o$$.ppm >$tmpdir/junk3$$.ppm");
  206. } elsif ($i <= 20) {
  207. my $n = $spline10[$i-10];
  208. system("ppmmix $n $tmpdir/junk1o$$.ppm $tmpdir/junk2o$$.ppm >$tmpdir/junk3$$.ppm");
  209. } else {
  210. my $n = $spline10[$i-20];
  211. system("ppmmix $n $tmpdir/junk2o$$.ppm $tmpdir/junk2$$.ppm >$tmpdir/junk3$$.ppm");
  212. }
  213. if ($i == 10) {
  214. system("ppmtopgm $tmpdir/junk2$$.ppm | pgmoil >$tmpdir/junko$$.ppm");
  215. system("rgb3toppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm " .
  216. ">$tmpdir/junk2o$$.ppm");
  217. }
  218. } elsif ($mode eq $EDGE) {
  219. if ($i == 1) {
  220. system("ppmtopgm $tmpdir/junk1$$.ppm | pgmedge >$tmpdir/junko$$.ppm");
  221. system("rgb3toppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm " .
  222. ">$tmpdir/junk1o$$.ppm");
  223. }
  224. if ($i <= 10) {
  225. my $n = $spline10[$i];
  226. system("ppmmix $n $tmpdir/junk1$$.ppm $tmpdir/junk1o$$.ppm >$tmpdir/junk3$$.ppm");
  227. } elsif ($i <= 20) {
  228. my $n = $spline10[$i-10];
  229. system("ppmmix $n $tmpdir/junk1o$$.ppm $tmpdir/junk2o$$.ppm >$tmpdir/junk3$$.ppm");
  230. } else {
  231. my $n = $spline10[$i-20];
  232. system("ppmmix $n $tmpdir/junk2o$$.ppm $tmpdir/junk2$$.ppm >$tmpdir/junk3$$.ppm");
  233. }
  234. if ($i == 10) {
  235. system("ppmtopgm $tmpdir/junk2$$.ppm | pgmedge >$tmpdir/junko$$.ppm");
  236. system("rgb3toppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm " .
  237. ">$tmpdir/junk2o$$.ppm");
  238. }
  239. } elsif ($mode eq $BENTLEY) {
  240. if ($i == 1) {
  241. system("ppmtopgm $tmpdir/junk1$$.ppm | pgmbentley >$tmpdir/junko$$.ppm");
  242. system("rgb3toppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm " .
  243. ">$tmpdir/junk1o$$.ppm");
  244. }
  245. if ($i <= 10) {
  246. my $n = $spline10[$i];
  247. system("ppmmix $n $tmpdir/junk1$$.ppm $tmpdir/junk1o$$.ppm >$tmpdir/junk3$$.ppm");
  248. } elsif ($i <= 20) {
  249. my $n = $spline10[$i-10];
  250. system("ppmmix $n $tmpdir/junk1o$$.ppm $tmpdir/junk2o$$.ppm >$tmpdir/junk3$$.ppm");
  251. } else {
  252. my $n = $spline10[$i-20];
  253. system("ppmmix $n $tmpdir/junk2o$$.ppm $tmpdir/junk2$$.ppm >$tmpdir/junk3$$.ppm");
  254. }
  255. if ($i == 10) {
  256. system("ppmtopgm $tmpdir/junk2$$.ppm | pgmbentley >$tmpdir/junko$$.ppm");
  257. system("rgb3toppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm " .
  258. ">$tmpdir/junk2o$$.ppm");
  259. }
  260. } elsif ($mode eq $BLOCK) {
  261. if ($i <= 10) {
  262. my $n = 1 - 1.9*$spline20[$i];
  263. system("pamscale $n $tmpdir/junk1$$.ppm | " .
  264. "pamscale -width $width -height $height >$tmpdir/junk3$$.ppm");
  265. } elsif ($i <= 20) {
  266. my $n = $spline10[$i-10];
  267. system("ppmmix $n $tmpdir/junk1a$$.ppm $tmpdir/junk2a$$.ppm >$tmpdir/junk3$$.ppm");
  268. } else {
  269. my $n = 1 - 1.9*$spline20[31-$i];
  270. system("pamscale $n $tmpdir/junk2$$.ppm | " .
  271. "pamscale -width $width -height $height >$tmpdir/junk3$$.ppm");
  272. }
  273. if ($i == 10) {
  274. system("cp", "$tmpdir/junk3$$.ppm", "$tmpdir/junk1a$$.ppm");
  275. system("pamscale $n $tmpdir/junk2$$.ppm | " .
  276. "pamscale -width $width -height $height >$tmpdir/junk2a$$.ppm");
  277. }
  278. } elsif ($mode eq $MIX) {
  279. my $fade_factor = sqrt(1/($nframes-$i+1));
  280. system("ppmmix $fade_factor $tmpdir/junk1$$.ppm $tmpdir/junk2$$.ppm >$tmpdir/junk3$$.ppm");
  281. } else {
  282. print("Internal error: impossible mode value '$mode'\n");
  283. }
  284. my $outfile = sprintf("%s.%04d.ppm", $base_name, $i);
  285. system("cp", "$tmpdir/junk3$$.ppm", $outfile);
  286. }
  287. #
  288. # Clean up shop.
  289. #
  290. system("rm $tmpdir/junk*$$.ppm");
  291. exit(0);
  292. sub usage() {
  293. print "Usage: ppmfade [-f first_file] [-l last_file]\n";
  294. print " [-spread|-relief|-oil|-edge|-bentley|-block]\n";
  295. print " [-base basename]\n";
  296. print "Notes: Default base: fade\n";
  297. print " The resulting image files will be named fade.NNNN.ppm.\n";
  298. exit(100);
  299. }