| # | 
| # The Python Imaging Library. | 
| # $Id$ | 
| # | 
| # PPM support for PIL | 
| # | 
| # History: | 
| #       96-03-24 fl     Created | 
| #       98-03-06 fl     Write RGBA images (as RGB, that is) | 
| # | 
| # Copyright (c) Secret Labs AB 1997-98. | 
| # Copyright (c) Fredrik Lundh 1996. | 
| # | 
| # See the README file for information on usage and redistribution. | 
| # | 
|   | 
|   | 
| __version__ = "0.2" | 
|   | 
| import string | 
|   | 
| import Image, ImageFile | 
|   | 
| # | 
| # -------------------------------------------------------------------- | 
|   | 
| MODES = { | 
|     # standard | 
|     "P4": "1", | 
|     "P5": "L", | 
|     "P6": "RGB", | 
|     # extensions | 
|     "P0CMYK": "CMYK", | 
|     # PIL extensions (for test purposes only) | 
|     "PyP": "P", | 
|     "PyRGBA": "RGBA", | 
|     "PyCMYK": "CMYK" | 
| } | 
|   | 
| def _accept(prefix): | 
|     return prefix[0] == "P" and prefix[1] in "0456y" | 
|   | 
| ## | 
| # Image plugin for PBM, PGM, and PPM images. | 
|   | 
| class PpmImageFile(ImageFile.ImageFile): | 
|   | 
|     format = "PPM" | 
|     format_description = "Pbmplus image" | 
|   | 
|     def _token(self, s = ""): | 
|         while 1: # read until next whitespace | 
|             c = self.fp.read(1) | 
|             if not c or c in string.whitespace: | 
|                 break | 
|             s = s + c | 
|         return s | 
|   | 
|     def _open(self): | 
|   | 
|         # check magic | 
|         s = self.fp.read(1) | 
|         if s != "P": | 
|             raise SyntaxError, "not a PPM file" | 
|         mode = MODES[self._token(s)] | 
|   | 
|         if mode == "1": | 
|             self.mode = "1" | 
|             rawmode = "1;I" | 
|         else: | 
|             self.mode = rawmode = mode | 
|   | 
|         for ix in range(3): | 
|             while 1: | 
|                 while 1: | 
|                     s = self.fp.read(1) | 
|                     if s not in string.whitespace: | 
|                         break | 
|                 if s != "#": | 
|                     break | 
|                 s = self.fp.readline() | 
|             s = int(self._token(s)) | 
|             if ix == 0: | 
|                 xsize = s | 
|             elif ix == 1: | 
|                 ysize = s | 
|                 if mode == "1": | 
|                     break | 
|   | 
|         self.size = xsize, ysize | 
|         self.tile = [("raw", | 
|                      (0, 0, xsize, ysize), | 
|                      self.fp.tell(), | 
|                      (rawmode, 0, 1))] | 
|   | 
|         # ALTERNATIVE: load via builtin debug function | 
|         # self.im = Image.core.open_ppm(self.filename) | 
|         # self.mode = self.im.mode | 
|         # self.size = self.im.size | 
|   | 
| # | 
| # -------------------------------------------------------------------- | 
|   | 
| def _save(im, fp, filename): | 
|     if im.mode == "1": | 
|         rawmode, head = "1;I", "P4" | 
|     elif im.mode == "L": | 
|         rawmode, head = "L", "P5" | 
|     elif im.mode == "RGB": | 
|         rawmode, head = "RGB", "P6" | 
|     elif im.mode == "RGBA": | 
|         rawmode, head = "RGB", "P6" | 
|     else: | 
|         raise IOError, "cannot write mode %s as PPM" % im.mode | 
|     fp.write(head + "\n%d %d\n" % im.size) | 
|     if head != "P4": | 
|         fp.write("255\n") | 
|     ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, 1))]) | 
|   | 
|     # ALTERNATIVE: save via builtin debug function | 
|     # im._dump(filename) | 
|   | 
| # | 
| # -------------------------------------------------------------------- | 
|   | 
| Image.register_open("PPM", PpmImageFile, _accept) | 
| Image.register_save("PPM", _save) | 
|   | 
| Image.register_extension("PPM", ".pbm") | 
| Image.register_extension("PPM", ".pgm") | 
| Image.register_extension("PPM", ".ppm") |