#!/usr/bin/perl
# Require Perl5
#
# jpg2pdf -- JPEG images to PDF
#
# by SANFACE Software <sanface@sanface.com> 24 October 2001
#
# jpg2pdf 2.x is shareware: its cost is $65. Try it for 30 days.
# If you decide to continue using it, register NOW via a SECURE SERVER at
# http://www.regsoft.net/purchase.php3?productid=10644
# or contact SANFACE Software sanface@sanface.com
#
# This is version 2.3
#
use strict;
use Getopt::Long;
use File::DosGlob 'glob';
use File::Find;

my $producer="jpg2pdf";
sub myread($) {
	my $ret;
	read(MYFILE, $ret, shift()) || die ("$producer: could not read");
	return $ret;
}
my $jpeg_have_seen_app14;
sub jpeg_info($) {
	my ($id, $fp);
	my $file = shift();
	open(MYFILE, "<$file")
		|| die ("$producer: could not open '$file'\n");
	binmode(MYFILE);
	$jpeg_have_seen_app14 = 0;
	while (1) {
		do {
			die ("$producer: '$file' seems to be no jpeg-file\n")
				if unpack("C", myread(1)) != 0xff;
			$id = unpack("C", myread(1));
			$fp = tell MYFILE;
		} while ($id == 0xd8);
		die ("$producer: no info available for '$file'\n")
			if ($id == 0xd9 || $id == 0xda);
		my $size = unpack("n", myread(2));
		if ($id == 0xc0 || $id == 0xc1 || $id == 0xc2 ||
		    $id == 0xc9 || $id == 0xca) {
			my ($prec, $height, $width, $compon) =
				unpack ("CnnC", myread(6));
			close MYFILE;
			return $prec, $height, $width, $compon;
		} elsif ($id == 0xee) {
			$jpeg_have_seen_app14 = 1;
		}
		seek MYFILE, $fp + $size, 0;
	}
}

my $i;
my $fpos=0;
my $version="2.3";
my $pageNO;
# Default paper is Letter size
my $pageHeight=792; my $pageWidth=612;
my @location;
my @pageObj;
my $buf="";
my $input="";
my $obj=0;
my $Tpages=0; my $resources=0; my $root=0;
my @annots;
my $configure="jpg2pdf.cfg"; my $help=0; my $verbose=0; my $output="jpegs.pdf";
my $paper=""; my $recursive=""; my $match=""; my $elem="";
my $transition=""; my $motion=""; my $direction=0; my $dimension="";
my $bgdesign=""; my $fgdesign="";
my $jpg2pdfHome="http://www.sanface.com/$producer.html";
my $companyname="SANFACE Software";
my $SANFACEmail="mailto:sanface\@sanface.com";
my $SECURESERVER="http://www.regsoft.net/purchase.php3?productid=10644";
my ($imgwidth,$imgheight,$imagen); my @image;
my $info=0; my $title="";
my $npage=1; my $times = 0; my $timef = 0;

$configure = $ENV{'JPG2PDFCFG'} if (! -e "$configure");

&GetOptions("configure=s"  => \$configure,
            "help"         => \$help,
            "output=s"     => \$output,
            "recursive=s"  => \$recursive,
            "match=s"      => \$match,
            "verbose"      => \$verbose) || printusage() ;
my @elem=("author","creator","keywords","subject","title","bgdesign","fgdesign",
          "paper","transition","pagemode","pagelayout","imagex","imagey","scale",
          "typeencoding");
my %option=(author             => '',
            creator            => '',
            keywords           => '',
            subject            => '',
            title              => '',
            paper              => 'letter',
            transition         => '',
            pagemode           => '',
            pagelayout         => '',
            bgdesign           => '',
            fgdesign           => '',
            typeencoding       => 'default',
            imagex             => '0',
            imagey             => '0',
            scale              => '1');

$help and printusage();
my $tmpelem; my $var;
open (CNF, "$configure") || die "$producer: couldn't open configuration file $configure\n";
while (<CNF>) {
  s/\t/ /g;        #replace tabs by space
  next if /^ *\#/; #ignore comment lines
  next if /^ *$/;  #ignore empty lines
  foreach $elem (@elem) {
    if (/ *$elem *: *(.*)/i) {
      $tmpelem=$1;
#      if ($tmpelem=~/#!ENV#(.*)#!\/ENV#/) {
#        $var=$ENV{$1};
#        $tmpelem=~s/#!ENV#(.*)#!\/ENV#/$var/;
#        }
      $option{$elem}=$tmpelem;
      }
    }
  }
close(CNF);
$paper and $option{'paper'}=$paper;

print <<FEE;

This is an UNREGISTERED version of $producer.
Registration fee is \$65.
Register NOW via a SECURE SERVER at
$SECURESERVER
or contact $companyname $SANFACEmail


FEE

if (uc($option{'paper'}) eq "A3")           {$pageWidth=842;  $pageHeight=1190;}
elsif (uc($option{'paper'}) eq "A4")        {$pageWidth=595;  $pageHeight=842; }
elsif (uc($option{'paper'}) eq "A5")        {$pageWidth=421;  $pageHeight=595; }
elsif (uc($option{'paper'}) eq "TABLOID")   {$pageWidth=792;  $pageHeight=1224;}
elsif (uc($option{'paper'}) eq "LEDGER")    {$pageWidth=1224; $pageHeight=792; }
elsif (uc($option{'paper'}) eq "LEGAL")     {$pageWidth=612;  $pageHeight=1008;}
elsif (uc($option{'paper'}) eq "STATEMENT") {$pageWidth=396;  $pageHeight=612; }
elsif (uc($option{'paper'}) eq "EXECUTIVE") {$pageWidth=540;  $pageHeight=720; }
elsif (uc($option{'paper'}) eq "IMAGE") {}
else {
   if (($option{'paper'}) && (uc($option{'paper'}) ne "LETTER")) 
     {&Warning("the set paper $option{'paper'} isn't supported\n$producer will use the default paper (letter)")}
   }
my $typeencoding=$option{'typeencoding'};
if (($typeencoding ne "MacRomanEncoding") && ($typeencoding ne "MacExpertEncoding") && ($typeencoding ne "WinAnsiEncoding") && ($typeencoding ne "default"))
  {&Warning("the set encoding $typeencoding isn't MacRomanEncoding or MacExpertEncoding or WinAnsiEncoding or default\n$producer will use the default encoding (ISOLatin1Encoding)")}
if ($option{'transition'} eq "replace") {$transition=""}
elsif ($option{'transition'} eq "dissolve") {$transition="Dissolve"}
elsif ($option{'transition'}=~/box!(.*)!/)
  {
  $transition="Box";
  if ($1 eq "I" || $1 eq "O") {$motion=$1}
  else     {
    &Warning("the set motion $1 with $transition transition isn't supported\n$producer will use the $transition I (Input) motion");
    $motion="I";
    }
  }
elsif ($option{'transition'}=~/glitter!(.*)!/)
  {
  $transition="Glitter";
  if ($1 == 0 || $1 == 270 || $1 == 315) {$direction=$1}
  else {&Warning("the set direction $1 with $transition transition isn't supported\n$producer will use the $transition 0 direction")}
  }
elsif ($option{'transition'}=~/wipe!(.*)!/)
  {
  $transition="Wipe";
  if ($1 == 0 || $1 == 90 || $1 == 180 || $1 == 270) {$direction=$1}
  else {&Warning("the set direction $1 with $transition transition isn't supported\n$producer will use the $transition 0 direction")}
  }
elsif ($option{'transition'}=~/blinds!(.*)!/)
  {
  $transition="Blinds";
  if ($1 eq "H" || $1 eq "V") {$dimension=$1}
  else     {
    &Warning("the set dimension $1 with $transition transition isn't supported\n$producer will use the $transition H dimension");
    $dimension="H";
    }
  }
elsif ($option{'transition'}=~/split!(.*)!(.*)!/)
  {
  $transition="Split";
  if ($1 eq "H" || $1 eq "V") {$dimension=$1}
  else     {
    &Warning("the set dimension $1 with $transition transition isn't supported\n$producer will use the $transition H dimension");
    $dimension="H";
    }
  if ($2 eq "I" || $2 eq "O") {$motion=$2}
  else     {
    &Warning("the set motion $1 with $transition transition isn't supported\n$producer will use the $transition I (Input) motion");
    $motion="I";
    }
  }
else { 
  if ($option{'transition'}) {
    &Warning("the set transition $option{'transition'} isn't supported\n$producer will use the default transition (replace)");
    $option{'transition'}="";
    }
  }
  if (($option{'pagemode'} ne "FullScreen") && ($option{'pagemode'} ne "UseThumbs") && ($option{'pagemode'} ne "")){
    &Warning("the set page mode $option{'pagemode'} isn't supported\n$producer will use the default page mode (UseNone)");
    $option{'pagemode'}="";
    }

  if (($option{'pagelayout'} ne "OneColumn") && ($option{'pagelayout'} ne "TwoColumnRight") && ($option{'pagelayout'} ne "TwoColumnLeft") && ($option{'pagelayout'} ne "")) {
    &Warning("the set page layout $option{'pagelayout'} isn't supported\n$producer will use the default page layout (SinglePage)");
    $option{'pagelayout'}="";
    }

if ($option{'bgdesign'})
  {
  open (BGDESIGN, "$option{'bgdesign'}") ||
     die "$producer: couldn't open background design file $option{'bgdesign'}\n";
  while (<BGDESIGN>) {
    s/\015$//;
    $bgdesign.=$_;
    }
  close(BGDESIGN);
  }
if ($option{'fgdesign'})
  {
  open (FGDESIGN, "$option{'fgdesign'}") ||
     die "$producer: couldn't open foreground design file $option{'fgdesign'}\n";
  while (<FGDESIGN>) {
    s/\015$//;
    $fgdesign.=$_;
    }
  close(FGDESIGN);
  }

sub wanted {
  if ($File::Find::name=~/$match/) {
    push @ARGV,$File::Find::name;
    }
  }

if ($match && !$recursive) {
   print "You can use -match option only with -recursive option\n";
   exit;
   }

if ($recursive) {
  $match=~s/\./\\./g;
  $match=~s/\*/.*/g;
  $match=~s/\?/./g;
  $match=~s/$/\$/;
  find (\&wanted,"$recursive");
  }


if (@ARGV) {
  my @files;

  $obj=0;
  $pageNO=0;
  $fpos=0;
  @pageObj='';
  $verbose and $times = time;
  open (OUT, ">$output") || die "$producer: couldn't open output file $output\n";
  binmode (OUT);
  &WriteHeader();
  $i=0;
  my $p;
  if ($^O =~ /^MSWin32$/i && !$recursive) {
    foreach $p (@ARGV) {
      if($p=~/\*|\?/) {push @files,glob($p)}
      else {push @files,$p}
      }
    }
  else {@files = @ARGV}
  foreach $input (@files) {
    $verbose and print "Processing $input file\n";
    &WriteImages($input);
    }
  $imagen=($#image+1)/3;
  &WritePages();
  &WriteRest();
  close(OUT);
  if ($verbose) {$timef = time; printf ("PDF generation time = %4.2f sec\n", $timef - $times );}
  } else {printusage()}

sub WriteHeader {
  my $sec=0; my $min=0; my $hour=0; my $mday=0; my $mon=0; my $year=0;
  my $wday=0; my $yday=0; my $isdst=0; my $date="";
  ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
  ++$mon;                              # $mon is 0..11
  $year += 1900;
  my $gm = (gmtime(time))[2];
  my $local = (localtime(time))[2];
  my $diff = $local - $gm;
  if ($diff <= -12) { $diff += 24 }
  elsif ($diff > 12) { $diff -= 24 }
  my $zone = $diff;
  if ($zone =~ /-/) {$zone = sprintf "%.2d00", $zone}
  else  {$zone = sprintf "+%.2d00", $zone}
  # Start PDF
  &pos("%PDF-1.2\n");
  # It is recommended that the second line of a PDF file be a comment that
  # contains at least four characters with codes 128 or greater
  &pos("%忏嫌\n");
  $date=sprintf "D:$year%.2ld%.2ld%.2ld%.2ld%.2ld$zone",$mon,$mday,$hour,$min,$sec;
  $location[++$obj]=$fpos;
  $info=$obj;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  $option{'author'} and &pos("/Author ($option{'author'})\n");
  &pos("/CreationDate ($date)\n");
  $option{'creator'} and &pos("/Creator ($option{'creator'})\n");
  &pos("/Producer (\\(UNREGISTERED\\) $producer v$version \\251 $companyname 2001)\n");
  &pos("/Title ($title)\n");
  $option{'subject'} and &pos("/Subject ($option{'subject'})\n");
  $option{'keywords'} and &pos("/Keywords ($option{'keywords'})\n");
  &pos(">>\n");
  &pos("endobj\n");
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Annot\n");
  &pos("/Subtype /Text\n");
  &pos("/Open true\n");
  &pos("/Contents (Made by unregistered $producer $version)\n");
  if (uc($option{'paper'}) ne "IMAGE") {&pos("/Rect [ 0 0 $pageWidth $pageHeight ]\n")}
  else {&pos("/Rect [ 0 0 100 100 ]\n")}
  &pos(">>\n");
  &pos("endobj\n");
  $annots[1].="$obj 0 R ";
  $root=++$obj;
  $Tpages=++$obj;
  }

sub WriteImages {
  my $file=shift(@_);

  my ($bits, $components);
  my @colorspace;
  $colorspace[1] = "Gray";
  $colorspace[3] = "RGB";
  $colorspace[4] = "CMYK";

  ($bits, $imgheight, $imgwidth, $components) = jpeg_info("$file");

  if (! $colorspace[$components]) {
    die ("$producer: could not determine color space for '$file'\n");
  }
  if (($components eq 1) || ($components eq 4)) {
    die ("$producer: gray jpegs and cmyk jpegs are supported only by jpg2pdf PRO\n\nhttp://www.sanface.com/jpg2pdfPRO.html\n");
  }

  $location[++$obj]=$fpos;
  $image[$i*3]=$obj;
  $image[$i*3+1]=$imgwidth*$option{'scale'};
  $image[$i*3+2]=$imgheight*$option{'scale'};
  &pos("$obj 0 obj\n");
  &pos("<<\n/Type /XObject\n/Subtype /Image\n/Name /Im$i\n/Width $imgwidth\n/Height $imgheight\n");
  &pos("/BitsPerComponent $bits\n/ColorSpace /DeviceRGB\n");
  $buf=sprintf "/Length %d 0 R ",$obj+1; &pos($buf);
  &pos("\n/Filter /DCTDecode\n");
  &pos(">>\n");
  &pos("stream\n");
  my $streamStart=$fpos;
  open (IN, "$file") || die "$producer: couldn't open input file $file\n";
  binmode IN;
  while (<IN>) {&pos("$_")}
  close(IN);
  my $streamEnd=$fpos;
  &pos("\nendstream\n");
  &pos("endobj\n");
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  $buf=sprintf "%d\n",$streamEnd-$streamStart; &pos($buf);
  &pos("endobj\n");
  $i++;
  }

sub WritePages {
  $i=0;
  my $encoding=$obj+15;
  $resources=$obj+16;
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Font\n");
  &pos("/Subtype /Type1\n");
  &pos("/Name /F1\n");
  &pos("/Encoding $encoding 0 R\n");
  &pos("/BaseFont /Courier\n");
  &pos(">>\n");
  &pos("endobj\n");
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Font\n");
  &pos("/Subtype /Type1\n");
  &pos("/Name /F2\n");
  &pos("/Encoding $encoding 0 R\n");
  &pos("/BaseFont /Courier-Oblique\n");
  &pos(">>\n");
  &pos("endobj\n");
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Font\n");
  &pos("/Subtype /Type1\n");
  &pos("/Name /F3\n");
  &pos("/Encoding $encoding 0 R\n");
  &pos("/BaseFont /Courier-Bold\n");
  &pos(">>\n");
  &pos("endobj\n");
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Font\n");
  &pos("/Subtype /Type1\n");
  &pos("/Name /F4\n");
  &pos("/Encoding $encoding 0 R\n");
  &pos("/BaseFont /Courier-BoldOblique\n");
  &pos(">>\n");
  &pos("endobj\n");
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Font\n");
  &pos("/Subtype /Type1\n");
  &pos("/Name /F5\n");
  &pos("/Encoding $encoding 0 R\n");
  &pos("/BaseFont /Helvetica\n");
  &pos(">>\n");
  &pos("endobj\n");
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Font\n");
  &pos("/Subtype /Type1\n");
  &pos("/Name /F6\n");
  &pos("/Encoding $encoding 0 R\n");
  &pos("/BaseFont /Helvetica-Oblique\n");
  &pos(">>\n");
  &pos("endobj\n");
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Font\n");
  &pos("/Subtype /Type1\n");
  &pos("/Name /F7\n");
  &pos("/Encoding $encoding 0 R\n");
  &pos("/BaseFont /Helvetica-Bold\n");
  &pos(">>\n");
  &pos("endobj\n");
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Font\n");
  &pos("/Subtype /Type1\n");
  &pos("/Name /F8\n");
  &pos("/Encoding $encoding 0 R\n");
  &pos("/BaseFont /Helvetica-BoldOblique\n");
  &pos(">>\n");
  &pos("endobj\n");
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Font\n");
  &pos("/Subtype /Type1\n");
  &pos("/Name /F9\n");
  &pos("/Encoding $encoding 0 R\n");
  &pos("/BaseFont /Times-Roman\n");
  &pos(">>\n");
  &pos("endobj\n");
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Font\n");
  &pos("/Subtype /Type1\n");
  &pos("/Name /F10\n");
  &pos("/Encoding $encoding 0 R\n");
  &pos("/BaseFont /Times-Italic\n");
  &pos(">>\n");
  &pos("endobj\n");
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Font\n");
  &pos("/Subtype /Type1\n");
  &pos("/Name /F11\n");
  &pos("/Encoding $encoding 0 R\n");
  &pos("/BaseFont /Times-Bold\n");
  &pos(">>\n");
  &pos("endobj\n");
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Font\n");
  &pos("/Subtype /Type1\n");
  &pos("/Name /F12\n");
  &pos("/Encoding $encoding 0 R\n");
  &pos("/BaseFont /Times-BoldItalic\n");
  &pos(">>\n");
  &pos("endobj\n");
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Font\n");
  &pos("/Subtype /Type1\n");
  &pos("/Name /F13\n");
  &pos("/BaseFont /Symbol\n");
  &pos(">>\n");
  &pos("endobj\n");
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Font\n");
  &pos("/Subtype /Type1\n");
  &pos("/Name /F14\n");
  &pos("/BaseFont /ZapfDingbats\n");
  &pos(">>\n");
  &pos("endobj\n");
# ISOLatin1Encoding
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Encoding\n");
  if ($typeencoding eq "WinAnsiEncoding") {&pos("/BaseEncoding /WinAnsiEncoding\n")}
  elsif ($typeencoding eq "MacRomanEncoding") {&pos("/BaseEncoding /MacRomanEncoding\n")}
  elsif ($typeencoding eq "MacExpertEncoding") {&pos("/BaseEncoding /MacExpertEncoding\n")}
  else {
    &pos("/Differences [ 0 /.notdef /.notdef /.notdef /.notdef\n");
    &pos("/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n");
    &pos("/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n");
    &pos("/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n");
    &pos("/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n");
    &pos("/.notdef /.notdef /.notdef /.notdef /space /exclam\n");
    &pos("/quotedbl /numbersign /dollar /percent /ampersand\n");
    &pos("/quoteright /parenleft /parenright /asterisk /plus /comma\n");
    &pos("/hyphen /period /slash /zero /one /two /three /four /five\n");
    &pos("/six /seven /eight /nine /colon /semicolon /less /equal\n");
    &pos("/greater /question /at /A /B /C /D /E /F /G /H /I /J /K /L\n");
    &pos("/M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft\n");
    &pos("/backslash /bracketright /asciicircum /underscore\n");
    &pos("/quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p\n");
    &pos("/q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright\n");
    &pos("/asciitilde /.notdef /.notdef /.notdef /.notdef /.notdef\n");
    &pos("/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n");
    &pos("/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n");
    &pos("/dotlessi /grave /acute /circumflex /tilde /macron /breve\n");
    &pos("/dotaccent /dieresis /.notdef /ring /cedilla /.notdef\n");
    &pos("/hungarumlaut /ogonek /caron /space /exclamdown /cent\n");
    &pos("/sterling /currency /yen /brokenbar /section /dieresis\n");
    &pos("/copyright /ordfeminine /guillemotleft /logicalnot /hyphen\n");
    &pos("/registered /macron /degree /plusminus /twosuperior\n");
    &pos("/threesuperior /acute /mu /paragraph /periodcentered\n");
    &pos("/cedilla /onesuperior /ordmasculine /guillemotright\n");
    &pos("/onequarter /onehalf /threequarters /questiondown /Agrave\n");
    &pos("/Aacute /Acircumflex /Atilde /Adieresis /Aring /AE\n");
    &pos("/Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave\n");
    &pos("/Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve\n");
    &pos("/Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash\n");
    &pos("/Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn\n");
    &pos("/germandbls /agrave /aacute /acircumflex /atilde /adieresis\n");
    &pos("/aring /ae /ccedilla /egrave /eacute /ecircumflex\n");
    &pos("/edieresis /igrave /iacute /icircumflex /idieresis /eth\n");
    &pos("/ntilde /ograve /oacute /ocircumflex /otilde /odieresis\n");
    &pos("/divide /oslash /ugrave /uacute /ucircumflex /udieresis\n");
    &pos("/yacute /thorn /ydieresis ]\n");
    }
  &pos(">>\n");
  &pos("endobj\n");
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  $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",
       $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;
  &pos($buf);
  &pos("  /ProcSet [ /PDF /Text /ImageC ]\n");
  &pos("  /XObject << ");
  for (1..$imagen) {
    &pos("/Im$i $image[$i*3] 0 R ");
    $i++;
    }
  &pos(">>\n");
  &pos(">>\n");
  &pos("endobj\n");
  $i=0;
  for (1..$imagen) {
    &StartPage();
    my $strmPos=$fpos;
    if ($bgdesign) {&pos("$bgdesign")}
    &pos("q $image[$i*3+1] 0 0 $image[$i*3+2] $option{'imagex'} $option{'imagey'} cm /Im$i Do Q\n");
    if ($fgdesign) {&pos("$fgdesign")}
    &EndPage($strmPos);
    $i++;
    }
  }

# End PDF
sub WriteRest {
  $location[$root]=$fpos;
  &pos("$root 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Catalog\n");
  &pos("/Pages $Tpages 0 R\n");
  if ($option{'pagemode'}) {&pos("/PageMode /$option{'pagemode'}\n")};
  if ($option{'pagelayout'}) {&pos("/PageLayout /$option{'pagelayout'}\n")};
  &pos(">>\n");
  &pos("endobj\n");
  $location[$Tpages]=$fpos;
  &pos("$Tpages 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Pages\n");
  &pos("/Count $pageNO\n");
  &pos("/MediaBox [ 0 0 $pageWidth $pageHeight ]\n");
  &pos("/Kids [ ");
  $i=1;
  for ($i=1; $i<=$pageNO;$i++) {&pos("$pageObj[$i] 0 R ");}
  &pos("]\n");
  &pos(">>\n");
  &pos("endobj\n");
  my $xfer = $fpos;
  &pos("xref\n");
  $buf=sprintf "0 %d\n",$obj+1; &pos($buf);
  &pos("0000000000 65535 f \n");
  my $num="";
  for ($i=1;$i<=$obj;$i++) {
    $buf=sprintf "%.10ld 00000 n \n",$location[$i];
    &pos($buf);
    }
  &pos("trailer\n");
  &pos("<<\n");
  $buf=sprintf "/Size %d\n",$obj+1; &pos($buf);
  &pos("/Root $root 0 R\n");
  &pos("/Info $info 0 R\n");
  &pos(">>\n");
  &pos("startxref\n");
  &pos("$xfer\n");
  &pos("%%EOF\n");
  }

sub StartPage {
  $location[++$obj]=$fpos;
  $pageObj[++$pageNO]=$obj;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  &pos("/Type /Page\n");
  &pos("/Parent $Tpages 0 R\n");
  if (uc($option{'paper'}) eq "IMAGE") {&pos("/MediaBox [ 0 0 $image[$i*3+1] $image[$i*3+2] ]\n")}
  &pos("/Resources $resources 0 R\n");
  $buf=sprintf "/Contents %d 0 R\n",++$obj; &pos($buf);
  if ($transition eq "Dissolve") {&pos("/Trans << /Type /Trans /S /$transition >>\n")}
  if ($transition eq "Box") {&pos("/Trans << /Type /Trans /S /$transition /M /$motion >>\n")}
  if ($transition eq "Glitter") {&pos("/Trans << /Type /Trans /S /$transition /Di $direction >>\n")}
  if ($transition eq "Wipe") {&pos("/Trans << /Type /Trans /S /$transition /Di $direction >>\n")}
  if ($transition eq "Blinds") {&pos("/Trans << /Type /Trans /S /$transition /Dm /$dimension >>\n")}
  if ($transition eq "Split") {&pos("/Trans << /Type /Trans /S /$transition /Dm /$dimension /M /$motion >>\n")}
  $annots[$pageNO] and &pos("/Annots [ $annots[$pageNO]]\n");
  &pos(">>\n");
  &pos("endobj\n");
  $location[$obj]=$fpos;
  &pos("$obj 0 obj\n");
  &pos("<<\n");
  $buf=sprintf "/Length %d 0 R\n",$obj+1; &pos($buf);
  &pos(">>\n");
  &pos("stream\n");
  }

sub EndPage {
  my $streamStart=shift(@_);
  my $streamEnd=0;
  $streamEnd=$fpos;
  &pos("endstream\n");
  &pos("endobj\n");
  $location[++$obj]=$fpos;
  &pos("$obj 0 obj\n");
  $buf=sprintf "%d\n",$streamEnd-$streamStart; &pos($buf);
  &pos("endobj\n");
  }

sub pos {
  my $string = shift(@_);

  $fpos+=length $string;
  print OUT "$string";
  }

sub Warning {
  my $string = shift(@_);
  print <<WARNING;
Warning: $string

WARNING
  }

sub printusage {
    print <<USAGEDESC;

usage:
        $producer [-options ...] list

where options include:
    -help                        print out this message
    -output    file              default jpegs.pdf
    -configure file              default $producer.cfg
    -recursive directory         scan recursively the directory
    -match     files             match different files ex. *.jpg, a?.*
                                 (require -recursive option)
    -verbose                     verbose

list:
    with list you can use metacharacters and relative and absolute path name

example:
    $producer *.jpg
    $producer -m "a*.jpg" -r my_directory


If you want to know more about this tool, you might want
to read the docs. They came together with $producer!

Home: $jpg2pdfHome

USAGEDESC
    exit(1);
}

exit 0;

__END__

=head1 NAME

JPG2PDF - Version 2.3 24th October 2001

=head1 SYNOPSIS

Syntax : jpg2pdf [-options] files

=head1 DESCRIPTION

JPG2PDF is a very flexible and powerful PERL5 program.
It can convert a collection of jpeg images into a unique PDF.
You can use jpg2pdf like a module inside your applications (cgis, ...).

=head1 Features

JPG2PDF  is  a  native  converter,  you  don't  need to  pass  through
PostScript format. Some feature of JPG2PDF includes :

 o you  can create (batch)  a unique  PDF file  from your JPEG archive
   (using * and ? metachars: e.g. a*.jpg or recursively) 
 o you  can add  to your  PDF  collection  of jpeg  images  transition
   effects
 o you can set PDF full-screen  mode e.g. to show to your  friend your
   digital photos made by your digital camera

=head1 Options

    -help                        print out this message
    -output    file              default jpegs.pdf
    -configure file              default jpg2pdf.cfg
    -recursive directory         scan recursively the directory
    -match     files             match different files ex. *.pdf, a?.*
                                 (require -recursive option)
    -verbose                     verbose

list:
    with list you can use metacharacters and relative and absolute path name

-configure  filename:  with this option you can configure an alternate
configuration file (the default  configuration  file  is  jpg2pdf.cfg,
located  in jpg2pdf directory).  This option is very useful if you use
jpg2pdf in a automatic task (e.g.  cron).  e.g.
 
  jpg2pdf -c myalbum.cfg *.jpg

-match files -recursive directory: with  these option  you can convert 
all the files in the directory and in every its subdirectories
e.g
  jpg2pdf -m "a*.jpg" -r .
to create the jpegs.pdf with every jpeg  beginning with a and with jpg
extension inside the . directory and in every its subdirectories 

CreationDate (The date the document was created) in Info dictionary is
automatically set.

=cut
