home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 February / Chip_2002-02_cd2.bin / sw / 7177 / jpg2pdf.exe / jpg2pdf.pl < prev    next >
Perl Script  |  2001-11-06  |  26KB  |  793 lines

  1. #!/usr/bin/perl
  2. # Require Perl5
  3. #
  4. # jpg2pdf -- JPEG images to PDF
  5. #
  6. # by SANFACE Software <sanface@sanface.com> 24 October 2001
  7. #
  8. # jpg2pdf 2.x is shareware: its cost is $65. Try it for 30 days.
  9. # If you decide to continue using it, register NOW via a SECURE SERVER at
  10. # http://www.regsoft.net/purchase.php3?productid=10644
  11. # or contact SANFACE Software sanface@sanface.com
  12. #
  13. # This is version 2.3
  14. #
  15. use strict;
  16. use Getopt::Long;
  17. use File::DosGlob 'glob';
  18. use File::Find;
  19.  
  20. my $producer="jpg2pdf";
  21. sub myread($) {
  22.     my $ret;
  23.     read(MYFILE, $ret, shift()) || die ("$producer: could not read");
  24.     return $ret;
  25. }
  26. my $jpeg_have_seen_app14;
  27. sub jpeg_info($) {
  28.     my ($id, $fp);
  29.     my $file = shift();
  30.     open(MYFILE, "<$file")
  31.         || die ("$producer: could not open '$file'\n");
  32.     binmode(MYFILE);
  33.     $jpeg_have_seen_app14 = 0;
  34.     while (1) {
  35.         do {
  36.             die ("$producer: '$file' seems to be no jpeg-file\n")
  37.                 if unpack("C", myread(1)) != 0xff;
  38.             $id = unpack("C", myread(1));
  39.             $fp = tell MYFILE;
  40.         } while ($id == 0xd8);
  41.         die ("$producer: no info available for '$file'\n")
  42.             if ($id == 0xd9 || $id == 0xda);
  43.         my $size = unpack("n", myread(2));
  44.         if ($id == 0xc0 || $id == 0xc1 || $id == 0xc2 ||
  45.             $id == 0xc9 || $id == 0xca) {
  46.             my ($prec, $height, $width, $compon) =
  47.                 unpack ("CnnC", myread(6));
  48.             close MYFILE;
  49.             return $prec, $height, $width, $compon;
  50.         } elsif ($id == 0xee) {
  51.             $jpeg_have_seen_app14 = 1;
  52.         }
  53.         seek MYFILE, $fp + $size, 0;
  54.     }
  55. }
  56.  
  57. my $i;
  58. my $fpos=0;
  59. my $version="2.3";
  60. my $pageNO;
  61. # Default paper is Letter size
  62. my $pageHeight=792; my $pageWidth=612;
  63. my @location;
  64. my @pageObj;
  65. my $buf="";
  66. my $input="";
  67. my $obj=0;
  68. my $Tpages=0; my $resources=0; my $root=0;
  69. my @annots;
  70. my $configure="jpg2pdf.cfg"; my $help=0; my $verbose=0; my $output="jpegs.pdf";
  71. my $paper=""; my $recursive=""; my $match=""; my $elem="";
  72. my $transition=""; my $motion=""; my $direction=0; my $dimension="";
  73. my $bgdesign=""; my $fgdesign="";
  74. my $jpg2pdfHome="http://www.sanface.com/$producer.html";
  75. my $companyname="SANFACE Software";
  76. my $SANFACEmail="mailto:sanface\@sanface.com";
  77. my $SECURESERVER="http://www.regsoft.net/purchase.php3?productid=10644";
  78. my ($imgwidth,$imgheight,$imagen); my @image;
  79. my $info=0; my $title="";
  80. my $npage=1; my $times = 0; my $timef = 0;
  81.  
  82. $configure = $ENV{'JPG2PDFCFG'} if (! -e "$configure");
  83.  
  84. &GetOptions("configure=s"  => \$configure,
  85.             "help"         => \$help,
  86.             "output=s"     => \$output,
  87.             "recursive=s"  => \$recursive,
  88.             "match=s"      => \$match,
  89.             "verbose"      => \$verbose) || printusage() ;
  90. my @elem=("author","creator","keywords","subject","title","bgdesign","fgdesign",
  91.           "paper","transition","pagemode","pagelayout","imagex","imagey","scale",
  92.           "typeencoding");
  93. my %option=(author             => '',
  94.             creator            => '',
  95.             keywords           => '',
  96.             subject            => '',
  97.             title              => '',
  98.             paper              => 'letter',
  99.             transition         => '',
  100.             pagemode           => '',
  101.             pagelayout         => '',
  102.             bgdesign           => '',
  103.             fgdesign           => '',
  104.             typeencoding       => 'default',
  105.             imagex             => '0',
  106.             imagey             => '0',
  107.             scale              => '1');
  108.  
  109. $help and printusage();
  110. my $tmpelem; my $var;
  111. open (CNF, "$configure") || die "$producer: couldn't open configuration file $configure\n";
  112. while (<CNF>) {
  113.   s/\t/ /g;        #replace tabs by space
  114.   next if /^ *\#/; #ignore comment lines
  115.   next if /^ *$/;  #ignore empty lines
  116.   foreach $elem (@elem) {
  117.     if (/ *$elem *: *(.*)/i) {
  118.       $tmpelem=$1;
  119. #      if ($tmpelem=~/#!ENV#(.*)#!\/ENV#/) {
  120. #        $var=$ENV{$1};
  121. #        $tmpelem=~s/#!ENV#(.*)#!\/ENV#/$var/;
  122. #        }
  123.       $option{$elem}=$tmpelem;
  124.       }
  125.     }
  126.   }
  127. close(CNF);
  128. $paper and $option{'paper'}=$paper;
  129.  
  130. print <<FEE;
  131.  
  132. This is an UNREGISTERED version of $producer.
  133. Registration fee is \$65.
  134. Register NOW via a SECURE SERVER at
  135. $SECURESERVER
  136. or contact $companyname $SANFACEmail
  137.  
  138.  
  139. FEE
  140.  
  141. if (uc($option{'paper'}) eq "A3")           {$pageWidth=842;  $pageHeight=1190;}
  142. elsif (uc($option{'paper'}) eq "A4")        {$pageWidth=595;  $pageHeight=842; }
  143. elsif (uc($option{'paper'}) eq "A5")        {$pageWidth=421;  $pageHeight=595; }
  144. elsif (uc($option{'paper'}) eq "TABLOID")   {$pageWidth=792;  $pageHeight=1224;}
  145. elsif (uc($option{'paper'}) eq "LEDGER")    {$pageWidth=1224; $pageHeight=792; }
  146. elsif (uc($option{'paper'}) eq "LEGAL")     {$pageWidth=612;  $pageHeight=1008;}
  147. elsif (uc($option{'paper'}) eq "STATEMENT") {$pageWidth=396;  $pageHeight=612; }
  148. elsif (uc($option{'paper'}) eq "EXECUTIVE") {$pageWidth=540;  $pageHeight=720; }
  149. elsif (uc($option{'paper'}) eq "IMAGE") {}
  150. else {
  151.    if (($option{'paper'}) && (uc($option{'paper'}) ne "LETTER")) 
  152.      {&Warning("the set paper $option{'paper'} isn't supported\n$producer will use the default paper (letter)")}
  153.    }
  154. my $typeencoding=$option{'typeencoding'};
  155. if (($typeencoding ne "MacRomanEncoding") && ($typeencoding ne "MacExpertEncoding") && ($typeencoding ne "WinAnsiEncoding") && ($typeencoding ne "default"))
  156.   {&Warning("the set encoding $typeencoding isn't MacRomanEncoding or MacExpertEncoding or WinAnsiEncoding or default\n$producer will use the default encoding (ISOLatin1Encoding)")}
  157. if ($option{'transition'} eq "replace") {$transition=""}
  158. elsif ($option{'transition'} eq "dissolve") {$transition="Dissolve"}
  159. elsif ($option{'transition'}=~/box!(.*)!/)
  160.   {
  161.   $transition="Box";
  162.   if ($1 eq "I" || $1 eq "O") {$motion=$1}
  163.   else     {
  164.     &Warning("the set motion $1 with $transition transition isn't supported\n$producer will use the $transition I (Input) motion");
  165.     $motion="I";
  166.     }
  167.   }
  168. elsif ($option{'transition'}=~/glitter!(.*)!/)
  169.   {
  170.   $transition="Glitter";
  171.   if ($1 == 0 || $1 == 270 || $1 == 315) {$direction=$1}
  172.   else {&Warning("the set direction $1 with $transition transition isn't supported\n$producer will use the $transition 0 direction")}
  173.   }
  174. elsif ($option{'transition'}=~/wipe!(.*)!/)
  175.   {
  176.   $transition="Wipe";
  177.   if ($1 == 0 || $1 == 90 || $1 == 180 || $1 == 270) {$direction=$1}
  178.   else {&Warning("the set direction $1 with $transition transition isn't supported\n$producer will use the $transition 0 direction")}
  179.   }
  180. elsif ($option{'transition'}=~/blinds!(.*)!/)
  181.   {
  182.   $transition="Blinds";
  183.   if ($1 eq "H" || $1 eq "V") {$dimension=$1}
  184.   else     {
  185.     &Warning("the set dimension $1 with $transition transition isn't supported\n$producer will use the $transition H dimension");
  186.     $dimension="H";
  187.     }
  188.   }
  189. elsif ($option{'transition'}=~/split!(.*)!(.*)!/)
  190.   {
  191.   $transition="Split";
  192.   if ($1 eq "H" || $1 eq "V") {$dimension=$1}
  193.   else     {
  194.     &Warning("the set dimension $1 with $transition transition isn't supported\n$producer will use the $transition H dimension");
  195.     $dimension="H";
  196.     }
  197.   if ($2 eq "I" || $2 eq "O") {$motion=$2}
  198.   else     {
  199.     &Warning("the set motion $1 with $transition transition isn't supported\n$producer will use the $transition I (Input) motion");
  200.     $motion="I";
  201.     }
  202.   }
  203. else { 
  204.   if ($option{'transition'}) {
  205.     &Warning("the set transition $option{'transition'} isn't supported\n$producer will use the default transition (replace)");
  206.     $option{'transition'}="";
  207.     }
  208.   }
  209.   if (($option{'pagemode'} ne "FullScreen") && ($option{'pagemode'} ne "UseThumbs") && ($option{'pagemode'} ne "")){
  210.     &Warning("the set page mode $option{'pagemode'} isn't supported\n$producer will use the default page mode (UseNone)");
  211.     $option{'pagemode'}="";
  212.     }
  213.  
  214.   if (($option{'pagelayout'} ne "OneColumn") && ($option{'pagelayout'} ne "TwoColumnRight") && ($option{'pagelayout'} ne "TwoColumnLeft") && ($option{'pagelayout'} ne "")) {
  215.     &Warning("the set page layout $option{'pagelayout'} isn't supported\n$producer will use the default page layout (SinglePage)");
  216.     $option{'pagelayout'}="";
  217.     }
  218.  
  219. if ($option{'bgdesign'})
  220.   {
  221.   open (BGDESIGN, "$option{'bgdesign'}") ||
  222.      die "$producer: couldn't open background design file $option{'bgdesign'}\n";
  223.   while (<BGDESIGN>) {
  224.     s/\015$//;
  225.     $bgdesign.=$_;
  226.     }
  227.   close(BGDESIGN);
  228.   }
  229. if ($option{'fgdesign'})
  230.   {
  231.   open (FGDESIGN, "$option{'fgdesign'}") ||
  232.      die "$producer: couldn't open foreground design file $option{'fgdesign'}\n";
  233.   while (<FGDESIGN>) {
  234.     s/\015$//;
  235.     $fgdesign.=$_;
  236.     }
  237.   close(FGDESIGN);
  238.   }
  239.  
  240. sub wanted {
  241.   if ($File::Find::name=~/$match/) {
  242.     push @ARGV,$File::Find::name;
  243.     }
  244.   }
  245.  
  246. if ($match && !$recursive) {
  247.    print "You can use -match option only with -recursive option\n";
  248.    exit;
  249.    }
  250.  
  251. if ($recursive) {
  252.   $match=~s/\./\\./g;
  253.   $match=~s/\*/.*/g;
  254.   $match=~s/\?/./g;
  255.   $match=~s/$/\$/;
  256.   find (\&wanted,"$recursive");
  257.   }
  258.  
  259.  
  260. if (@ARGV) {
  261.   my @files;
  262.  
  263.   $obj=0;
  264.   $pageNO=0;
  265.   $fpos=0;
  266.   @pageObj='';
  267.   $verbose and $times = time;
  268.   open (OUT, ">$output") || die "$producer: couldn't open output file $output\n";
  269.   binmode (OUT);
  270.   &WriteHeader();
  271.   $i=0;
  272.   my $p;
  273.   if ($^O =~ /^MSWin32$/i && !$recursive) {
  274.     foreach $p (@ARGV) {
  275.       if($p=~/\*|\?/) {push @files,glob($p)}
  276.       else {push @files,$p}
  277.       }
  278.     }
  279.   else {@files = @ARGV}
  280.   foreach $input (@files) {
  281.     $verbose and print "Processing $input file\n";
  282.     &WriteImages($input);
  283.     }
  284.   $imagen=($#image+1)/3;
  285.   &WritePages();
  286.   &WriteRest();
  287.   close(OUT);
  288.   if ($verbose) {$timef = time; printf ("PDF generation time = %4.2f sec\n", $timef - $times );}
  289.   } else {printusage()}
  290.  
  291. sub WriteHeader {
  292.   my $sec=0; my $min=0; my $hour=0; my $mday=0; my $mon=0; my $year=0;
  293.   my $wday=0; my $yday=0; my $isdst=0; my $date="";
  294.   ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
  295.   ++$mon;                              # $mon is 0..11
  296.   $year += 1900;
  297.   my $gm = (gmtime(time))[2];
  298.   my $local = (localtime(time))[2];
  299.   my $diff = $local - $gm;
  300.   if ($diff <= -12) { $diff += 24 }
  301.   elsif ($diff > 12) { $diff -= 24 }
  302.   my $zone = $diff;
  303.   if ($zone =~ /-/) {$zone = sprintf "%.2d00", $zone}
  304.   else  {$zone = sprintf "+%.2d00", $zone}
  305.   # Start PDF
  306.   &pos("%PDF-1.2\n");
  307.   # It is recommended that the second line of a PDF file be a comment that
  308.   # contains at least four characters with codes 128 or greater
  309.   &pos("%Γπ╧╙\n");
  310.   $date=sprintf "D:$year%.2ld%.2ld%.2ld%.2ld%.2ld$zone",$mon,$mday,$hour,$min,$sec;
  311.   $location[++$obj]=$fpos;
  312.   $info=$obj;
  313.   &pos("$obj 0 obj\n");
  314.   &pos("<<\n");
  315.   $option{'author'} and &pos("/Author ($option{'author'})\n");
  316.   &pos("/CreationDate ($date)\n");
  317.   $option{'creator'} and &pos("/Creator ($option{'creator'})\n");
  318.   &pos("/Producer (\\(UNREGISTERED\\) $producer v$version \\251 $companyname 2001)\n");
  319.   &pos("/Title ($title)\n");
  320.   $option{'subject'} and &pos("/Subject ($option{'subject'})\n");
  321.   $option{'keywords'} and &pos("/Keywords ($option{'keywords'})\n");
  322.   &pos(">>\n");
  323.   &pos("endobj\n");
  324.   $location[++$obj]=$fpos;
  325.   &pos("$obj 0 obj\n");
  326.   &pos("<<\n");
  327.   &pos("/Type /Annot\n");
  328.   &pos("/Subtype /Text\n");
  329.   &pos("/Open true\n");
  330.   &pos("/Contents (Made by unregistered $producer $version)\n");
  331.   if (uc($option{'paper'}) ne "IMAGE") {&pos("/Rect [ 0 0 $pageWidth $pageHeight ]\n")}
  332.   else {&pos("/Rect [ 0 0 100 100 ]\n")}
  333.   &pos(">>\n");
  334.   &pos("endobj\n");
  335.   $annots[1].="$obj 0 R ";
  336.   $root=++$obj;
  337.   $Tpages=++$obj;
  338.   }
  339.  
  340. sub WriteImages {
  341.   my $file=shift(@_);
  342.  
  343.   my ($bits, $components);
  344.   my @colorspace;
  345.   $colorspace[1] = "Gray";
  346.   $colorspace[3] = "RGB";
  347.   $colorspace[4] = "CMYK";
  348.  
  349.   ($bits, $imgheight, $imgwidth, $components) = jpeg_info("$file");
  350.  
  351.   if (! $colorspace[$components]) {
  352.     die ("$producer: could not determine color space for '$file'\n");
  353.   }
  354.   if (($components eq 1) || ($components eq 4)) {
  355.     die ("$producer: gray jpegs and cmyk jpegs are supported only by jpg2pdf PRO\n\nhttp://www.sanface.com/jpg2pdfPRO.html\n");
  356.   }
  357.  
  358.   $location[++$obj]=$fpos;
  359.   $image[$i*3]=$obj;
  360.   $image[$i*3+1]=$imgwidth*$option{'scale'};
  361.   $image[$i*3+2]=$imgheight*$option{'scale'};
  362.   &pos("$obj 0 obj\n");
  363.   &pos("<<\n/Type /XObject\n/Subtype /Image\n/Name /Im$i\n/Width $imgwidth\n/Height $imgheight\n");
  364.   &pos("/BitsPerComponent $bits\n/ColorSpace /DeviceRGB\n");
  365.   $buf=sprintf "/Length %d 0 R ",$obj+1; &pos($buf);
  366.   &pos("\n/Filter /DCTDecode\n");
  367.   &pos(">>\n");
  368.   &pos("stream\n");
  369.   my $streamStart=$fpos;
  370.   open (IN, "$file") || die "$producer: couldn't open input file $file\n";
  371.   binmode IN;
  372.   while (<IN>) {&pos("$_")}
  373.   close(IN);
  374.   my $streamEnd=$fpos;
  375.   &pos("\nendstream\n");
  376.   &pos("endobj\n");
  377.   $location[++$obj]=$fpos;
  378.   &pos("$obj 0 obj\n");
  379.   $buf=sprintf "%d\n",$streamEnd-$streamStart; &pos($buf);
  380.   &pos("endobj\n");
  381.   $i++;
  382.   }
  383.  
  384. sub WritePages {
  385.   $i=0;
  386.   my $encoding=$obj+15;
  387.   $resources=$obj+16;
  388.   $location[++$obj]=$fpos;
  389.   &pos("$obj 0 obj\n");
  390.   &pos("<<\n");
  391.   &pos("/Type /Font\n");
  392.   &pos("/Subtype /Type1\n");
  393.   &pos("/Name /F1\n");
  394.   &pos("/Encoding $encoding 0 R\n");
  395.   &pos("/BaseFont /Courier\n");
  396.   &pos(">>\n");
  397.   &pos("endobj\n");
  398.   $location[++$obj]=$fpos;
  399.   &pos("$obj 0 obj\n");
  400.   &pos("<<\n");
  401.   &pos("/Type /Font\n");
  402.   &pos("/Subtype /Type1\n");
  403.   &pos("/Name /F2\n");
  404.   &pos("/Encoding $encoding 0 R\n");
  405.   &pos("/BaseFont /Courier-Oblique\n");
  406.   &pos(">>\n");
  407.   &pos("endobj\n");
  408.   $location[++$obj]=$fpos;
  409.   &pos("$obj 0 obj\n");
  410.   &pos("<<\n");
  411.   &pos("/Type /Font\n");
  412.   &pos("/Subtype /Type1\n");
  413.   &pos("/Name /F3\n");
  414.   &pos("/Encoding $encoding 0 R\n");
  415.   &pos("/BaseFont /Courier-Bold\n");
  416.   &pos(">>\n");
  417.   &pos("endobj\n");
  418.   $location[++$obj]=$fpos;
  419.   &pos("$obj 0 obj\n");
  420.   &pos("<<\n");
  421.   &pos("/Type /Font\n");
  422.   &pos("/Subtype /Type1\n");
  423.   &pos("/Name /F4\n");
  424.   &pos("/Encoding $encoding 0 R\n");
  425.   &pos("/BaseFont /Courier-BoldOblique\n");
  426.   &pos(">>\n");
  427.   &pos("endobj\n");
  428.   $location[++$obj]=$fpos;
  429.   &pos("$obj 0 obj\n");
  430.   &pos("<<\n");
  431.   &pos("/Type /Font\n");
  432.   &pos("/Subtype /Type1\n");
  433.   &pos("/Name /F5\n");
  434.   &pos("/Encoding $encoding 0 R\n");
  435.   &pos("/BaseFont /Helvetica\n");
  436.   &pos(">>\n");
  437.   &pos("endobj\n");
  438.   $location[++$obj]=$fpos;
  439.   &pos("$obj 0 obj\n");
  440.   &pos("<<\n");
  441.   &pos("/Type /Font\n");
  442.   &pos("/Subtype /Type1\n");
  443.   &pos("/Name /F6\n");
  444.   &pos("/Encoding $encoding 0 R\n");
  445.   &pos("/BaseFont /Helvetica-Oblique\n");
  446.   &pos(">>\n");
  447.   &pos("endobj\n");
  448.   $location[++$obj]=$fpos;
  449.   &pos("$obj 0 obj\n");
  450.   &pos("<<\n");
  451.   &pos("/Type /Font\n");
  452.   &pos("/Subtype /Type1\n");
  453.   &pos("/Name /F7\n");
  454.   &pos("/Encoding $encoding 0 R\n");
  455.   &pos("/BaseFont /Helvetica-Bold\n");
  456.   &pos(">>\n");
  457.   &pos("endobj\n");
  458.   $location[++$obj]=$fpos;
  459.   &pos("$obj 0 obj\n");
  460.   &pos("<<\n");
  461.   &pos("/Type /Font\n");
  462.   &pos("/Subtype /Type1\n");
  463.   &pos("/Name /F8\n");
  464.   &pos("/Encoding $encoding 0 R\n");
  465.   &pos("/BaseFont /Helvetica-BoldOblique\n");
  466.   &pos(">>\n");
  467.   &pos("endobj\n");
  468.   $location[++$obj]=$fpos;
  469.   &pos("$obj 0 obj\n");
  470.   &pos("<<\n");
  471.   &pos("/Type /Font\n");
  472.   &pos("/Subtype /Type1\n");
  473.   &pos("/Name /F9\n");
  474.   &pos("/Encoding $encoding 0 R\n");
  475.   &pos("/BaseFont /Times-Roman\n");
  476.   &pos(">>\n");
  477.   &pos("endobj\n");
  478.   $location[++$obj]=$fpos;
  479.   &pos("$obj 0 obj\n");
  480.   &pos("<<\n");
  481.   &pos("/Type /Font\n");
  482.   &pos("/Subtype /Type1\n");
  483.   &pos("/Name /F10\n");
  484.   &pos("/Encoding $encoding 0 R\n");
  485.   &pos("/BaseFont /Times-Italic\n");
  486.   &pos(">>\n");
  487.   &pos("endobj\n");
  488.   $location[++$obj]=$fpos;
  489.   &pos("$obj 0 obj\n");
  490.   &pos("<<\n");
  491.   &pos("/Type /Font\n");
  492.   &pos("/Subtype /Type1\n");
  493.   &pos("/Name /F11\n");
  494.   &pos("/Encoding $encoding 0 R\n");
  495.   &pos("/BaseFont /Times-Bold\n");
  496.   &pos(">>\n");
  497.   &pos("endobj\n");
  498.   $location[++$obj]=$fpos;
  499.   &pos("$obj 0 obj\n");
  500.   &pos("<<\n");
  501.   &pos("/Type /Font\n");
  502.   &pos("/Subtype /Type1\n");
  503.   &pos("/Name /F12\n");
  504.   &pos("/Encoding $encoding 0 R\n");
  505.   &pos("/BaseFont /Times-BoldItalic\n");
  506.   &pos(">>\n");
  507.   &pos("endobj\n");
  508.   $location[++$obj]=$fpos;
  509.   &pos("$obj 0 obj\n");
  510.   &pos("<<\n");
  511.   &pos("/Type /Font\n");
  512.   &pos("/Subtype /Type1\n");
  513.   &pos("/Name /F13\n");
  514.   &pos("/BaseFont /Symbol\n");
  515.   &pos(">>\n");
  516.   &pos("endobj\n");
  517.   $location[++$obj]=$fpos;
  518.   &pos("$obj 0 obj\n");
  519.   &pos("<<\n");
  520.   &pos("/Type /Font\n");
  521.   &pos("/Subtype /Type1\n");
  522.   &pos("/Name /F14\n");
  523.   &pos("/BaseFont /ZapfDingbats\n");
  524.   &pos(">>\n");
  525.   &pos("endobj\n");
  526. # ISOLatin1Encoding
  527.   $location[++$obj]=$fpos;
  528.   &pos("$obj 0 obj\n");
  529.   &pos("<<\n");
  530.   &pos("/Type /Encoding\n");
  531.   if ($typeencoding eq "WinAnsiEncoding") {&pos("/BaseEncoding /WinAnsiEncoding\n")}
  532.   elsif ($typeencoding eq "MacRomanEncoding") {&pos("/BaseEncoding /MacRomanEncoding\n")}
  533.   elsif ($typeencoding eq "MacExpertEncoding") {&pos("/BaseEncoding /MacExpertEncoding\n")}
  534.   else {
  535.     &pos("/Differences [ 0 /.notdef /.notdef /.notdef /.notdef\n");
  536.     &pos("/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n");
  537.     &pos("/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n");
  538.     &pos("/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n");
  539.     &pos("/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n");
  540.     &pos("/.notdef /.notdef /.notdef /.notdef /space /exclam\n");
  541.     &pos("/quotedbl /numbersign /dollar /percent /ampersand\n");
  542.     &pos("/quoteright /parenleft /parenright /asterisk /plus /comma\n");
  543.     &pos("/hyphen /period /slash /zero /one /two /three /four /five\n");
  544.     &pos("/six /seven /eight /nine /colon /semicolon /less /equal\n");
  545.     &pos("/greater /question /at /A /B /C /D /E /F /G /H /I /J /K /L\n");
  546.     &pos("/M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft\n");
  547.     &pos("/backslash /bracketright /asciicircum /underscore\n");
  548.     &pos("/quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p\n");
  549.     &pos("/q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright\n");
  550.     &pos("/asciitilde /.notdef /.notdef /.notdef /.notdef /.notdef\n");
  551.     &pos("/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n");
  552.     &pos("/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n");
  553.     &pos("/dotlessi /grave /acute /circumflex /tilde /macron /breve\n");
  554.     &pos("/dotaccent /dieresis /.notdef /ring /cedilla /.notdef\n");
  555.     &pos("/hungarumlaut /ogonek /caron /space /exclamdown /cent\n");
  556.     &pos("/sterling /currency /yen /brokenbar /section /dieresis\n");
  557.     &pos("/copyright /ordfeminine /guillemotleft /logicalnot /hyphen\n");
  558.     &pos("/registered /macron /degree /plusminus /twosuperior\n");
  559.     &pos("/threesuperior /acute /mu /paragraph /periodcentered\n");
  560.     &pos("/cedilla /onesuperior /ordmasculine /guillemotright\n");
  561.     &pos("/onequarter /onehalf /threequarters /questiondown /Agrave\n");
  562.     &pos("/Aacute /Acircumflex /Atilde /Adieresis /Aring /AE\n");
  563.     &pos("/Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave\n");
  564.     &pos("/Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve\n");
  565.     &pos("/Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash\n");
  566.     &pos("/Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn\n");
  567.     &pos("/germandbls /agrave /aacute /acircumflex /atilde /adieresis\n");
  568.     &pos("/aring /ae /ccedilla /egrave /eacute /ecircumflex\n");
  569.     &pos("/edieresis /igrave /iacute /icircumflex /idieresis /eth\n");
  570.     &pos("/ntilde /ograve /oacute /ocircumflex /otilde /odieresis\n");
  571.     &pos("/divide /oslash /ugrave /uacute /ucircumflex /udieresis\n");
  572.     &pos("/yacute /thorn /ydieresis ]\n");
  573.     }
  574.   &pos(">>\n");
  575.   &pos("endobj\n");
  576.   $location[++$obj]=$fpos;
  577.   &pos("$obj 0 obj\n");
  578.   &pos("<<\n");
  579.   $buf=sprintf "  /Font << /F1 %d 0 R /F2 %d 0 R /F3 %d 0 R /F4 %d 0 R /F5 %d 0 R /F6 %d 0 R /F7 %d 0 R /F8 %d 0 R /F9 %d 0 R /F10 %d 0 R /F11 %d 0 R /F12 %d 0 R /F13 %d 0 R /F14 %d 0 R >>\n",
  580.        $obj-15, $obj-14, $obj-13, $obj-12, $obj-11, $obj-10, $obj-9, $obj-8, $obj-7, $obj-6, $obj-5, $obj-4, $obj-3, $obj-2;
  581.   &pos($buf);
  582.   &pos("  /ProcSet [ /PDF /Text /ImageC ]\n");
  583.   &pos("  /XObject << ");
  584.   for (1..$imagen) {
  585.     &pos("/Im$i $image[$i*3] 0 R ");
  586.     $i++;
  587.     }
  588.   &pos(">>\n");
  589.   &pos(">>\n");
  590.   &pos("endobj\n");
  591.   $i=0;
  592.   for (1..$imagen) {
  593.     &StartPage();
  594.     my $strmPos=$fpos;
  595.     if ($bgdesign) {&pos("$bgdesign")}
  596.     &pos("q $image[$i*3+1] 0 0 $image[$i*3+2] $option{'imagex'} $option{'imagey'} cm /Im$i Do Q\n");
  597.     if ($fgdesign) {&pos("$fgdesign")}
  598.     &EndPage($strmPos);
  599.     $i++;
  600.     }
  601.   }
  602.  
  603. # End PDF
  604. sub WriteRest {
  605.   $location[$root]=$fpos;
  606.   &pos("$root 0 obj\n");
  607.   &pos("<<\n");
  608.   &pos("/Type /Catalog\n");
  609.   &pos("/Pages $Tpages 0 R\n");
  610.   if ($option{'pagemode'}) {&pos("/PageMode /$option{'pagemode'}\n")};
  611.   if ($option{'pagelayout'}) {&pos("/PageLayout /$option{'pagelayout'}\n")};
  612.   &pos(">>\n");
  613.   &pos("endobj\n");
  614.   $location[$Tpages]=$fpos;
  615.   &pos("$Tpages 0 obj\n");
  616.   &pos("<<\n");
  617.   &pos("/Type /Pages\n");
  618.   &pos("/Count $pageNO\n");
  619.   &pos("/MediaBox [ 0 0 $pageWidth $pageHeight ]\n");
  620.   &pos("/Kids [ ");
  621.   $i=1;
  622.   for ($i=1; $i<=$pageNO;$i++) {&pos("$pageObj[$i] 0 R ");}
  623.   &pos("]\n");
  624.   &pos(">>\n");
  625.   &pos("endobj\n");
  626.   my $xfer = $fpos;
  627.   &pos("xref\n");
  628.   $buf=sprintf "0 %d\n",$obj+1; &pos($buf);
  629.   &pos("0000000000 65535 f \n");
  630.   my $num="";
  631.   for ($i=1;$i<=$obj;$i++) {
  632.     $buf=sprintf "%.10ld 00000 n \n",$location[$i];
  633.     &pos($buf);
  634.     }
  635.   &pos("trailer\n");
  636.   &pos("<<\n");
  637.   $buf=sprintf "/Size %d\n",$obj+1; &pos($buf);
  638.   &pos("/Root $root 0 R\n");
  639.   &pos("/Info $info 0 R\n");
  640.   &pos(">>\n");
  641.   &pos("startxref\n");
  642.   &pos("$xfer\n");
  643.   &pos("%%EOF\n");
  644.   }
  645.  
  646. sub StartPage {
  647.   $location[++$obj]=$fpos;
  648.   $pageObj[++$pageNO]=$obj;
  649.   &pos("$obj 0 obj\n");
  650.   &pos("<<\n");
  651.   &pos("/Type /Page\n");
  652.   &pos("/Parent $Tpages 0 R\n");
  653.   if (uc($option{'paper'}) eq "IMAGE") {&pos("/MediaBox [ 0 0 $image[$i*3+1] $image[$i*3+2] ]\n")}
  654.   &pos("/Resources $resources 0 R\n");
  655.   $buf=sprintf "/Contents %d 0 R\n",++$obj; &pos($buf);
  656.   if ($transition eq "Dissolve") {&pos("/Trans << /Type /Trans /S /$transition >>\n")}
  657.   if ($transition eq "Box") {&pos("/Trans << /Type /Trans /S /$transition /M /$motion >>\n")}
  658.   if ($transition eq "Glitter") {&pos("/Trans << /Type /Trans /S /$transition /Di $direction >>\n")}
  659.   if ($transition eq "Wipe") {&pos("/Trans << /Type /Trans /S /$transition /Di $direction >>\n")}
  660.   if ($transition eq "Blinds") {&pos("/Trans << /Type /Trans /S /$transition /Dm /$dimension >>\n")}
  661.   if ($transition eq "Split") {&pos("/Trans << /Type /Trans /S /$transition /Dm /$dimension /M /$motion >>\n")}
  662.   $annots[$pageNO] and &pos("/Annots [ $annots[$pageNO]]\n");
  663.   &pos(">>\n");
  664.   &pos("endobj\n");
  665.   $location[$obj]=$fpos;
  666.   &pos("$obj 0 obj\n");
  667.   &pos("<<\n");
  668.   $buf=sprintf "/Length %d 0 R\n",$obj+1; &pos($buf);
  669.   &pos(">>\n");
  670.   &pos("stream\n");
  671.   }
  672.  
  673. sub EndPage {
  674.   my $streamStart=shift(@_);
  675.   my $streamEnd=0;
  676.   $streamEnd=$fpos;
  677.   &pos("endstream\n");
  678.   &pos("endobj\n");
  679.   $location[++$obj]=$fpos;
  680.   &pos("$obj 0 obj\n");
  681.   $buf=sprintf "%d\n",$streamEnd-$streamStart; &pos($buf);
  682.   &pos("endobj\n");
  683.   }
  684.  
  685. sub pos {
  686.   my $string = shift(@_);
  687.  
  688.   $fpos+=length $string;
  689.   print OUT "$string";
  690.   }
  691.  
  692. sub Warning {
  693.   my $string = shift(@_);
  694.   print <<WARNING;
  695. Warning: $string
  696.  
  697. WARNING
  698.   }
  699.  
  700. sub printusage {
  701.     print <<USAGEDESC;
  702.  
  703. usage:
  704.         $producer [-options ...] list
  705.  
  706. where options include:
  707.     -help                        print out this message
  708.     -output    file              default jpegs.pdf
  709.     -configure file              default $producer.cfg
  710.     -recursive directory         scan recursively the directory
  711.     -match     files             match different files ex. *.jpg, a?.*
  712.                                  (require -recursive option)
  713.     -verbose                     verbose
  714.  
  715. list:
  716.     with list you can use metacharacters and relative and absolute path name
  717.  
  718. example:
  719.     $producer *.jpg
  720.     $producer -m "a*.jpg" -r my_directory
  721.  
  722.  
  723. If you want to know more about this tool, you might want
  724. to read the docs. They came together with $producer!
  725.  
  726. Home: $jpg2pdfHome
  727.  
  728. USAGEDESC
  729.     exit(1);
  730. }
  731.  
  732. exit 0;
  733.  
  734. __END__
  735.  
  736. =head1 NAME
  737.  
  738. JPG2PDF - Version 2.3 24th October 2001
  739.  
  740. =head1 SYNOPSIS
  741.  
  742. Syntax : jpg2pdf [-options] files
  743.  
  744. =head1 DESCRIPTION
  745.  
  746. JPG2PDF is a very flexible and powerful PERL5 program.
  747. It can convert a collection of jpeg images into a unique PDF.
  748. You can use jpg2pdf like a module inside your applications (cgis, ...).
  749.  
  750. =head1 Features
  751.  
  752. JPG2PDF  is  a  native  converter,  you  don't  need to  pass  through
  753. PostScript format. Some feature of JPG2PDF includes :
  754.  
  755.  o you  can create (batch)  a unique  PDF file  from your JPEG archive
  756.    (using * and ? metachars: e.g. a*.jpg or recursively) 
  757.  o you  can add  to your  PDF  collection  of jpeg  images  transition
  758.    effects
  759.  o you can set PDF full-screen  mode e.g. to show to your  friend your
  760.    digital photos made by your digital camera
  761.  
  762. =head1 Options
  763.  
  764.     -help                        print out this message
  765.     -output    file              default jpegs.pdf
  766.     -configure file              default jpg2pdf.cfg
  767.     -recursive directory         scan recursively the directory
  768.     -match     files             match different files ex. *.pdf, a?.*
  769.                                  (require -recursive option)
  770.     -verbose                     verbose
  771.  
  772. list:
  773.     with list you can use metacharacters and relative and absolute path name
  774.  
  775. -configure  filename:  with this option you can configure an alternate
  776. configuration file (the default  configuration  file  is  jpg2pdf.cfg,
  777. located  in jpg2pdf directory).  This option is very useful if you use
  778. jpg2pdf in a automatic task (e.g.  cron).  e.g.
  779.  
  780.   jpg2pdf -c myalbum.cfg *.jpg
  781.  
  782. -match files -recursive directory: with  these option  you can convert 
  783. all the files in the directory and in every its subdirectories
  784. e.g
  785.   jpg2pdf -m "a*.jpg" -r .
  786. to create the jpegs.pdf with every jpeg  beginning with a and with jpg
  787. extension inside the . directory and in every its subdirectories 
  788.  
  789. CreationDate (The date the document was created) in Info dictionary is
  790. automatically set.
  791.  
  792. =cut
  793.