Repository: imageio/imageio

Issue:
PPM-FI not creating ASCII output
When ssing the PPM-FI format string, no ASCII output is created.

```python
imageio.imwrite(path, image_data, "PPM-FI")
```

Produces for example

```
P6
200 100
65535
<binary data>
```

This is the expected behavior when using PPMRAW-FI. The expected ASCII output would be something like 

```
P3
200 100
65535
1 2 3 4 5 6 ...
```

Discussion:
ttobsen: I'v just added the PNM/PPM support and tested it localy with the following script:

```python
from imageio import imwrite, imread
import numpy as np
from binaryornot.check import is_binary

def is_ascii(file):
    is_bin = is_binary(file)
    return not is_bin

if __name__ == '__main__':

    tests = [
        {"data": np.full((200, 300, 3), 200, np.uint8),  "format": "PPM-FI",    "use_ascii": True},
        {"data": np.full((200, 300),    200, np.uint8),  "format": "PPM-FI",    "use_ascii": True},
        {"data": np.full((200, 300, 3), 200, np.uint8),  "format": "PPM-FI",    "use_ascii": False},
        {"data": np.full((200, 300),    200, np.uint8),  "format": "PPM-FI",    "use_ascii": False},
        {"data": np.full((200, 300, 3), 200, np.uint8),  "format": "PPMRAW-FI", "use_ascii": True},
        {"data": np.full((200, 300),    200, np.uint8),  "format": "PPMRAW-FI", "use_ascii": True},
        {"data": np.full((200, 300, 3), 200, np.uint8),  "format": "PPMRAW-FI", "use_ascii": False},
        {"data": np.full((200, 300),    200, np.uint8),  "format": "PPMRAW-FI", "use_ascii": False},
        {"data": np.full((200, 300, 3), 200, np.uint16), "format": "PPM-FI",    "use_ascii": True},
        {"data": np.full((200, 300),    200, np.uint16), "format": "PPM-FI",    "use_ascii": True},
        {"data": np.full((200, 300, 3), 200, np.uint16), "format": "PPM-FI",    "use_ascii": False},
        {"data": np.full((200, 300),    200, np.uint16), "format": "PPM-FI",    "use_ascii": False},
        {"data": np.full((200, 300, 3), 200, np.uint16), "format": "PPMRAW-FI", "use_ascii": True},
        {"data": np.full((200, 300),    200, np.uint16), "format": "PPMRAW-FI", "use_ascii": True},
        {"data": np.full((200, 300, 3), 200, np.uint16), "format": "PPMRAW-FI", "use_ascii": False},
        {"data": np.full((200, 300),    200, np.uint16), "format": "PPMRAW-FI", "use_ascii": False},
    ]

    for key, test in enumerate(tests):
        image_data = test["data"]
        filename = str(key) + ".ppm"
        fmt = test["format"]
        use_ascii = test["use_ascii"]

        imwrite(filename, image_data, fmt, use_ascii=use_ascii)
        assert is_ascii(filename) == use_ascii, "ASCII Flag missmatch!"
        read_data = imread(filename, fmt)

        np.testing.assert_array_equal(read_data, image_data, "Missmatch!")

        print("Test " + str(key) + " done.")
```

I'm not sure how to implement these tests properly. It seems that the special classes testing is done in `test_freeimage.py`. Are there any other places where tests have to be implemented?

As a starting point, I would use the Bitmap testing in `test_bmp()` as reference.
coveralls: 
[![Coverage Status](https://coveralls.io/builds/23441459/badge)](https://coveralls.io/builds/23441459)

Coverage decreased (-0.06%) to 90.96% when pulling **71a66d289e491dd21d809b51d1aca89100c4a790 on ttobsen:master** into **88b2a43cea81139e1a76460c68fa9aadebadfc1e on imageio:master**.

almarklein: >  Are there any other places where tests have to be implemented?

No, adding one test function to `test_freeimage.py` should be fine
ttobsen: > > Are there any other places where tests have to be implemented?
> 
> No, adding one test function to `test_freeimage.py` should be fine

Ok, I think I'm done. Can you have a look on it?
almarklein: This is great. No comments. Thanks for the contribution!

Patch:
diff --git a/.gitignore b/.gitignore
index ec7c106..35d4389 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,3 +33,6 @@ __pychache__
 
 # IDE
 .idea
+.project
+.pydevproject
+.settings
diff --git a/imageio/plugins/freeimage.py b/imageio/plugins/freeimage.py
index 7f93cb6..ca7db87 100644
--- a/imageio/plugins/freeimage.py
+++ b/imageio/plugins/freeimage.py
@@ -26,7 +26,7 @@ class FreeimageFormat(Format):
     The freeimage plugin requires a `freeimage` binary. If this binary
     not available on the system, it can be downloaded manually from
     <https://github.com/imageio/imageio-binaries> by either
-    
+
     - the command line script ``imageio_download_bin freeimage``
     - the Python method ``imageio.plugins.freeimage.download()``
 
@@ -35,7 +35,7 @@ class FreeimageFormat(Format):
     flags : int
         A freeimage-specific option. In most cases we provide explicit
         parameters for influencing image reading.
-    
+
     Parameters for saving
     ----------------------
     flags : int
@@ -145,13 +145,13 @@ class FreeimageFormat(Format):
 
 class FreeimageBmpFormat(FreeimageFormat):
     """ A BMP format based on the Freeimage library.
-    
+
     This format supports grayscale, RGB and RGBA images.
 
     The freeimage plugin requires a `freeimage` binary. If this binary
     not available on the system, it can be downloaded manually from
     <https://github.com/imageio/imageio-binaries> by either
-    
+
     - the command line script ``imageio_download_bin freeimage``
     - the Python method ``imageio.plugins.freeimage.download()``
 
@@ -161,7 +161,7 @@ class FreeimageBmpFormat(FreeimageFormat):
         Whether to compress the bitmap using RLE when saving. Default False.
         It seems this does not always work, but who cares, you should use
         PNG anyway.
-    
+
     """
 
     class Writer(FreeimageFormat.Writer):
@@ -182,13 +182,13 @@ class FreeimageBmpFormat(FreeimageFormat):
 
 class FreeimagePngFormat(FreeimageFormat):
     """ A PNG format based on the Freeimage library.
-    
+
     This format supports grayscale, RGB and RGBA images.
 
     The freeimage plugin requires a `freeimage` binary. If this binary
     not available on the system, it can be downloaded manually from
     <https://github.com/imageio/imageio-binaries> by either
-    
+
     - the command line script ``imageio_download_bin freeimage``
     - the Python method ``imageio.plugins.freeimage.download()``
 
@@ -196,7 +196,7 @@ class FreeimagePngFormat(FreeimageFormat):
     ----------------------
     ignoregamma : bool
         Avoid gamma correction. Default True.
-    
+
     Parameters for saving
     ---------------------
     compression : {0, 1, 6, 9}
@@ -263,13 +263,13 @@ class FreeimagePngFormat(FreeimageFormat):
 
 class FreeimageJpegFormat(FreeimageFormat):
     """ A JPEG format based on the Freeimage library.
-    
+
     This format supports grayscale and RGB images.
 
     The freeimage plugin requires a `freeimage` binary. If this binary
     not available on the system, it can be downloaded manually from
     <https://github.com/imageio/imageio-binaries> by either
-    
+
     - the command line script ``imageio_download_bin freeimage``
     - the Python method ``imageio.plugins.freeimage.download()``
 
@@ -280,9 +280,9 @@ class FreeimageJpegFormat(FreeimageFormat):
         Default True. If 2 is given, do the rotation in Python instead
         of freeimage.
     quickread : bool
-        Read the image more quickly, at the expense of quality. 
+        Read the image more quickly, at the expense of quality.
         Default False.
-    
+
     Parameters for saving
     ---------------------
     quality : scalar
@@ -296,7 +296,7 @@ class FreeimageJpegFormat(FreeimageFormat):
         few percent of file size). Default False.
     baseline : bool
         Save basic JPEG, without metadata or any markers. Default False.
-    
+
     """
 
     class Reader(FreeimageFormat.Reader):
@@ -316,7 +316,7 @@ class FreeimageJpegFormat(FreeimageFormat):
             return im, meta
 
         def _rotate(self, im, meta):
-            """ Use Orientation information from EXIF meta data to 
+            """ Use Orientation information from EXIF meta data to
             orient the image correctly. Freeimage is also supposed to
             support that, and I am pretty sure it once did, but now it
             does not, so let's just do it in Python.
@@ -370,12 +370,43 @@ class FreeimageJpegFormat(FreeimageFormat):
             return FreeimageFormat.Writer._append_data(self, im, meta)
 
 
+class FreeimagePnmFormat(FreeimageFormat):
+    """ A PNM format based on the Freeimage library.
+
+    This format supports single bit (PBM), grayscale (PGM) and RGB (PPM)
+    images, even with ASCII or binary coding.
+
+    The freeimage plugin requires a `freeimage` binary. If this binary
+    not available on the system, it can be downloaded manually from
+    <https://github.com/imageio/imageio-binaries> by either
+
+    - the command line script ``imageio_download_bin freeimage``
+    - the Python method ``imageio.plugins.freeimage.download()``
+
+    Parameters for saving
+    ---------------------
+    use_ascii : bool
+        Save with ASCII coding. Default True.
+    """
+
+    class Writer(FreeimageFormat.Writer):
+        def _open(self, flags=0, use_ascii=True):
+            # Build flags from kwargs
+            flags = int(flags)
+            if use_ascii:
+                flags |= IO_FLAGS.PNM_SAVE_ASCII
+            # Act as usual, but with modified flags
+            return FreeimageFormat.Writer._open(self, flags)
+
+
 ## Create the formats
 
 SPECIAL_CLASSES = {
     "jpeg": FreeimageJpegFormat,
     "png": FreeimagePngFormat,
     "bmp": FreeimageBmpFormat,
+    "ppm": FreeimagePnmFormat,
+    "ppmraw": FreeimagePnmFormat,
     "gif": None,  # defined in freeimagemulti
     "ico": None,  # defined in freeimagemulti
     "mng": None,  # defined in freeimagemulti


Test patch:
diff --git a/tests/test_freeimage.py b/tests/test_freeimage.py
index 537fe76..b8be9d4 100644
--- a/tests/test_freeimage.py
+++ b/tests/test_freeimage.py
@@ -23,7 +23,7 @@ def setup_module():
     # This tests requires our version of the FI lib
     try:
         imageio.plugins.freeimage.download()
-    except imageio.core.InternetNotAllowedError:
+    except core.InternetNotAllowedError:
         # We cannot download; skip all freeimage tests
         need_internet()
 
@@ -486,6 +486,23 @@ def test_mng():
     # ims = imageio.imread(get_remote_file('images/mngexample.mng'))
 
 
+def test_pnm():
+
+    for useAscii in (True, False):
+        for crop in (0, 1, 2):
+            for colors in (0, 1, 3):
+                fname = fnamebase
+                fname += "%i.%i.%i.ppm" % (useAscii, crop, colors)
+                rim = get_ref_im(colors, crop, isfloat=False)
+                imageio.imsave(fname, rim, use_ascii=useAscii)
+                im = imageio.imread(fname)
+                assert_close(rim, im, 0.1)  # lossless
+
+                # Parameter fail
+                raises(TypeError, imageio.imread, fname, notavalidkwarg=True)
+                raises(TypeError, imageio.imsave, fname, im, notavalidk=True)
+
+
 def test_other():
 
     # Cannot save float