home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 April / enter-2004-04.iso / files / EVE_1424_100181.exe / PdfImagePlugin.py < prev    next >
Encoding:
Text File  |  2004-04-20  |  4.4 KB  |  182 lines

  1. #
  2. # The Python Imaging Library.
  3. # $Id: //modules/pil/PIL/PdfImagePlugin.py#3 $
  4. #
  5. # PDF (Acrobat) file handling
  6. #
  7. # History:
  8. #       96-07-16 fl     Created
  9. #       97-01-18 fl     Fixed header
  10. #
  11. # Copyright (c) Secret Labs AB 1997.
  12. # Copyright (c) Fredrik Lundh 1996-97.
  13. #
  14. # See the README file for information on usage and redistribution.
  15. #
  16.  
  17.  
  18. __version__ = "0.2"
  19.  
  20. import Image, ImageFile
  21. import StringIO
  22.  
  23.  
  24. #
  25. # --------------------------------------------------------------------
  26.  
  27. # object ids:
  28. #  1. catalogue
  29. #  2. pages
  30. #  3. image
  31. #  4. page
  32. #  5. page contents
  33.  
  34. def _obj(fp, obj, **dict):
  35.     fp.write("%d 0 obj\n" % obj)
  36.     if dict:
  37.         fp.write("<<\n")
  38.         for k, v in dict.items():
  39.             if v is not None:
  40.                 fp.write("/%s %s\n" % (k, v))
  41.         fp.write(">>\n")
  42.  
  43. def _endobj(fp):
  44.     fp.write("endobj\n")
  45.  
  46. def _save(im, fp, filename):
  47.  
  48.     #
  49.     # make sure image data is available
  50.     im.load()
  51.  
  52.     xref = [0]*(5+1) # placeholders
  53.  
  54.     fp.write("%PDF-1.2\n")
  55.     fp.write("% created by PIL PDF driver " + __version__ + "\n")
  56.  
  57.     #
  58.     # Get image characteristics
  59.  
  60.     width, height = im.size
  61.  
  62.     # FIXME: Should replace ASCIIHexDecode with RunLengthDecode (packbits)
  63.     # or LZWDecode (tiff/lzw compression).  Note that PDF 1.2 also supports
  64.     # Flatedecode (zip compression).
  65.  
  66.     params = None
  67.  
  68.     if im.mode == "1":
  69.         filter = "/ASCIIHexDecode"
  70.         config = "/DeviceGray", "/ImageB", 1
  71.     elif im.mode == "L":
  72.         filter = "/DctDecode"
  73.         # params = "<< /Predictor 15 /Columns %d >>" % (width-2)
  74.         config = "/DeviceGray", "/ImageB", 8
  75.     elif im.mode == "P":
  76.         filter = "/ASCIIHexDecode"
  77.         config = "/Indexed", "/ImageI", 8
  78.     elif im.mode == "RGB":
  79.         filter = "/DCTDecode"
  80.         config = "/DeviceRGB", "/ImageC", 8
  81.     elif im.mode == "CMYK":
  82.         filter = "/DCTDecode"   
  83.         config = "/DeviceRGB", "/ImageC", 8
  84.     else:
  85.         raise ValueError, "illegal mode"
  86.  
  87.     colorspace, proc, bits = config
  88.  
  89.     #
  90.     # catalogue
  91.  
  92.     xref[1] = fp.tell()
  93.     _obj(fp, 1, Type = "/Catalog",
  94.                 Pages = "2 0 R")
  95.     _endobj(fp)
  96.  
  97.     #
  98.     # pages
  99.  
  100.     xref[2] = fp.tell()
  101.     _obj(fp, 2, Type = "/Pages",
  102.                 Count = 1,
  103.                 Kids = "[4 0 R]")
  104.     _endobj(fp)
  105.  
  106.     #
  107.     # image
  108.  
  109.     op = StringIO.StringIO()
  110.  
  111.     if filter == "/ASCIIHexDecode":
  112.         ImageFile._save(im, op, [("hex", (0,0)+im.size, 0, None)])
  113.     elif filter == "/DCTDecode":
  114.         ImageFile._save(im, op, [("jpeg", (0,0)+im.size, 0, im.mode)])
  115.     elif filter == "/FlateDecode":
  116.         ImageFile._save(im, op, [("zip", (0,0)+im.size, 0, im.mode)])
  117.     elif filter == "/RunLengthDecode":
  118.         ImageFile._save(im, op, [("packbits", (0,0)+im.size, 0, im.mode)])
  119.     else:
  120.         raise ValueError, "unsupported PDF filter"
  121.  
  122.     xref[3] = fp.tell()
  123.     _obj(fp, 3, Type = "/XObject",
  124.                 Subtype = "/Image",
  125.                 Width = width,
  126.                 Height = height,
  127.                 Length = len(op.getvalue()),
  128.                 Filter = filter,
  129.                 BitsPerComponent = bits,
  130.                 DecodeParams = params,
  131.                 ColorSpace = colorspace)
  132.  
  133.     fp.write("stream\n")
  134.     fp.write(op.getvalue())
  135.     fp.write("\nendstream\n")
  136.  
  137.     _endobj(fp)
  138.  
  139.     #
  140.     # page
  141.  
  142.     xref[4] = fp.tell()
  143.     fp.write("4 0 obj\n<<\n/Type /Page\n/Parent 2 0 R\n"\
  144.              "/Resources <<\n/ProcSet [ /PDF %s ]\n"\
  145.              "/XObject << /image 3 0 R >>\n>>\n"\
  146.              "/MediaBox [ 0 0 %d %d ]\n/Contents 5 0 R\n>>\n" %\
  147.              (proc, width, height))
  148.  
  149.     #
  150.     # page contents
  151.  
  152.     op = StringIO.StringIO()
  153.  
  154.     op.write("q %d 0 0 %d 0 0 cm /image Do Q\n" % (width, height))
  155.  
  156.     xref[5] = fp.tell()
  157.     _obj(fp, 5, Length = len(op.getvalue()))
  158.  
  159.     fp.write("stream\n")
  160.     fp.write(op.getvalue())
  161.  
  162.     _endobj(fp)
  163.  
  164.     #
  165.     # trailer
  166.     startxref = fp.tell()
  167.     fp.write("xref\n0 %d\n0000000000 65535 f \n" % len(xref))
  168.     for x in xref[1:]:
  169.         fp.write("%010d 00000 n \n" % x)
  170.     fp.write("trailer\n<<\n/Size %d\n/Root 1 0 R\n>>\n" % len(xref))
  171.     fp.write("startxref\n%d\n%%%%EOF\n" % startxref)
  172.     fp.flush()
  173.  
  174. #
  175. # --------------------------------------------------------------------
  176.  
  177. Image.register_save("PDF", _save)
  178.  
  179. Image.register_extension("PDF", ".pdf")
  180.  
  181. Image.register_mime("PDF", "application/pdf")
  182.