diff --git a/gst/pnm/gstpnm.c b/gst/pnm/gstpnm.c
index d40ce14..c2dc268 100644
--- a/gst/pnm/gstpnm.c
+++ b/gst/pnm/gstpnm.c
@@ -57,16 +57,13 @@ gst_my_typefind_function (GstTypeFind * tf, gpointer d)
       return;
     case GST_PNM_INFO_MNGR_RESULT_FINISHED:
       switch (mngr.info.type) {
-        case GST_PNM_TYPE_BITMAP_ASCII:
-        case GST_PNM_TYPE_BITMAP_RAW:
+        case GST_PNM_TYPE_BITMAP:
           gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, BITMAP_CAPS);
           return;
-        case GST_PNM_TYPE_GRAYMAP_ASCII:
-        case GST_PNM_TYPE_GRAYMAP_RAW:
+        case GST_PNM_TYPE_GRAYMAP:
           gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, GRAYMAP_CAPS);
           return;
-        case GST_PNM_TYPE_PIXMAP_ASCII:
-        case GST_PNM_TYPE_PIXMAP_RAW:
+        case GST_PNM_TYPE_PIXMAP:
           gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, PIXMAP_CAPS);
           return;
       }
diff --git a/gst/pnm/gstpnmdec.c b/gst/pnm/gstpnmdec.c
index 4b6b15f..bd28eae 100644
--- a/gst/pnm/gstpnmdec.c
+++ b/gst/pnm/gstpnmdec.c
@@ -68,8 +68,7 @@ gst_pnmdec_push (GstPnmdec * s, GstPad * src, GstBuffer * buf)
     GstBuffer *obuf;
     guint i;
 
-    if (s->mngr.info.type == GST_PNM_TYPE_PIXMAP_RAW ||
-        s->mngr.info.type == GST_PNM_TYPE_PIXMAP_ASCII) {
+    if (s->mngr.info.type == GST_PNM_TYPE_PIXMAP) {
       i_rowstride = 3 * s->mngr.info.width;
       o_rowstride = GST_ROUND_UP_4 (i_rowstride);
     } else {
@@ -115,17 +114,25 @@ gst_pnmdec_chain (GstPad * pad, GstBuffer * data)
         goto out;
       case GST_PNM_INFO_MNGR_RESULT_FINISHED:
         offset = s->mngr.data_offset;
+        if (s->mngr.info.encoding == GST_PNM_ENCODING_ASCII) {
+          GST_DEBUG_OBJECT (s, "FIXME: ASCII encoding not implemented!");
+          gst_buffer_unref (data);
+          r = GST_FLOW_ERROR;
+          goto out;
+        }
         caps = gst_caps_copy (gst_pad_get_pad_template_caps (src));
         switch (s->mngr.info.type) {
-          case GST_PNM_TYPE_BITMAP_RAW:
-          case GST_PNM_TYPE_BITMAP_ASCII:
-          case GST_PNM_TYPE_GRAYMAP_RAW:
-          case GST_PNM_TYPE_GRAYMAP_ASCII:
+          case GST_PNM_TYPE_BITMAP:
+            GST_DEBUG_OBJECT (s, "FIXME: BITMAP format not implemented!");
+            gst_caps_unref (caps);
+            gst_buffer_unref (data);
+            r = GST_FLOW_ERROR;
+            goto out;
+          case GST_PNM_TYPE_GRAYMAP:
             gst_caps_remove_structure (caps, 0);
             s->size = s->mngr.info.width * s->mngr.info.height * 1;
             break;
-          case GST_PNM_TYPE_PIXMAP_RAW:
-          case GST_PNM_TYPE_PIXMAP_ASCII:
+          case GST_PNM_TYPE_PIXMAP:
             gst_caps_remove_structure (caps, 1);
             s->size = s->mngr.info.width * s->mngr.info.height * 3;
             break;
@@ -136,6 +143,7 @@ gst_pnmdec_chain (GstPad * pad, GstBuffer * data)
             GST_TYPE_FRACTION, 0, 1, NULL);
         if (!gst_pad_set_caps (src, caps)) {
           gst_caps_unref (caps);
+          gst_buffer_unref (data);
           r = GST_FLOW_ERROR;
           goto out;
         }
@@ -144,6 +152,7 @@ gst_pnmdec_chain (GstPad * pad, GstBuffer * data)
   }
 
   if (offset == GST_BUFFER_SIZE (data)) {
+    gst_buffer_unref (data);
     r = GST_FLOW_OK;
     goto out;
   }
diff --git a/gst/pnm/gstpnmenc.c b/gst/pnm/gstpnmenc.c
index 3a9a98a..766850f 100644
--- a/gst/pnm/gstpnmenc.c
+++ b/gst/pnm/gstpnmenc.c
@@ -19,13 +19,15 @@
 /**
  * SECTION:element-pnmenc
  *
- * Encodes pnm images.
+ * Encodes pnm images. This plugin supports both raw and ASCII encoding.
+ * To enable ASCII encoding, set the parameter ascii to TRUE. If you omit
+ * the parameter or set it to FALSE, the output will be raw encoded.
  *
  * <refsect">
  * <title>Example launch line</title>
  * |[
- * gst-launch videotestsrc num_buffers=1 ! pnmenc ! ffmpegcolorspace ! "video/x-raw-gray" ! pnmenc ! filesink location=test.pnm
- * ]| The above pipeline writes a test pnm file.
+ * gst-launch videotestsrc num_buffers=1 ! ffmpegcolorspace ! "video/x-raw-gray" ! pnmenc ascii=true ! filesink location=test.pnm
+ * ]| The above pipeline writes a test pnm file (ASCII encoding).
  * </refsect2>
  */
 
@@ -41,6 +43,12 @@
 
 #include <string.h>
 
+enum {
+  GST_PNMENC_PROP_0,
+  GST_PNMENC_PROP_ASCII
+  /* Add here. */
+};
+
 static GstElementDetails pnmenc_details =
 GST_ELEMENT_DETAILS ("PNM converter", "Codec/Encoder/Image",
     "Encodes in PNM format",
@@ -57,6 +65,42 @@ static GstStaticPadTemplate src_pad_template =
 GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
     GST_STATIC_CAPS (MIME_ALL));
 
+static void
+gst_pnmenc_set_property (GObject * object, guint prop_id, const GValue * value,
+    GParamSpec * pspec)
+{
+  GstPnmenc *s = GST_PNMENC (object);
+
+  switch (prop_id) {
+    case GST_PNMENC_PROP_ASCII:
+      if (g_value_get_boolean (value))
+        s->info.encoding = GST_PNM_ENCODING_ASCII;
+      else
+        s->info.encoding = GST_PNM_ENCODING_RAW;
+      s->info.fields |= GST_PNM_INFO_FIELDS_ENCODING;
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_pnmenc_get_property (GObject * object, guint prop_id, GValue * value,
+    GParamSpec * pspec)
+{
+  GstPnmenc *s = GST_PNMENC (object);
+
+  switch (prop_id) {
+    case GST_PNMENC_PROP_ASCII:
+      g_value_set_boolean (value, s->info.encoding == GST_PNM_ENCODING_ASCII);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
 static GstFlowReturn
 gst_pnmenc_chain (GstPad * pad, GstBuffer * buf)
 {
@@ -65,14 +109,10 @@ gst_pnmenc_chain (GstPad * pad, GstBuffer * buf)
   gchar *header;
   GstBuffer *out;
 
-  if (s->info.fields != GST_PNM_INFO_FIELDS_ALL) {
-    r = GST_FLOW_NOT_NEGOTIATED;
-    goto out;
-  }
-
   /* Assumption: One buffer, one image. That is, always first write header. */
   header = g_strdup_printf ("P%i\n%i %i\n%i\n",
-      s->info.type, s->info.width, s->info.height, s->info.max);
+      s->info.type + 3 * (1 - s->info.encoding), s->info.width, s->info.height,
+      s->info.max);
   out = gst_buffer_new ();
   gst_buffer_set_data (out, (guchar *) header, strlen (header));
   gst_buffer_set_caps (out, GST_PAD_CAPS (s->src));
@@ -86,7 +126,7 @@ gst_pnmenc_chain (GstPad * pad, GstBuffer * buf)
     GstBuffer *obuf;
     guint i;
 
-    if (s->info.type == GST_PNM_TYPE_PIXMAP_RAW) {
+    if (s->info.type == GST_PNM_TYPE_PIXMAP) {
       o_rowstride = 3 * s->info.width;
       i_rowstride = GST_ROUND_UP_4 (o_rowstride);
     } else {
@@ -104,6 +144,25 @@ gst_pnmenc_chain (GstPad * pad, GstBuffer * buf)
     /* Pass through the data. */
     buf = gst_buffer_make_metadata_writable (buf);
   }
+
+  /* We might need to convert to ASCII... */
+  if (s->info.encoding == GST_PNM_ENCODING_ASCII) {
+    GstBuffer *obuf;
+    guint i, o;
+
+    obuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (buf) * (4 + 1/20.));
+    for (i = o = 0; i < GST_BUFFER_SIZE (buf); i++) {
+      g_snprintf ((char *) GST_BUFFER_DATA (obuf) + o, 4, "%3i",
+          GST_BUFFER_DATA (buf)[i]);
+      o += 3;
+      GST_BUFFER_DATA (obuf)[o++] = ' ';
+      if (!(i % 20))
+        GST_BUFFER_DATA (obuf)[o++] = '\n';
+    }
+    gst_buffer_unref (buf);
+    buf = obuf;
+  }
+
   gst_buffer_set_caps (buf, GST_PAD_CAPS (s->src));
   r = gst_pad_push (s->src, buf);
 
@@ -127,10 +186,10 @@ gst_pnmenc_setcaps_func_sink (GstPad * pad, GstCaps * caps)
 
   /* Set caps on the source. */
   if (!strcmp (mime, "video/x-raw-rgb")) {
-    s->info.type = GST_PNM_TYPE_PIXMAP_RAW;
+    s->info.type = GST_PNM_TYPE_PIXMAP;
     srccaps = gst_caps_from_string (MIME_PM);
   } else if (!strcmp (mime, "video/x-raw-gray")) {
-    s->info.type = GST_PNM_TYPE_GRAYMAP_RAW;
+    s->info.type = GST_PNM_TYPE_GRAYMAP;
     srccaps = gst_caps_from_string (MIME_GM);
   } else {
     r = FALSE;
@@ -187,7 +246,14 @@ gst_pnmenc_base_init (gpointer g_class)
 static void
 gst_pnmenc_class_init (GstPnmencClass * klass)
 {
-  /* Nothing to see here. Move along. */
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->set_property = gst_pnmenc_set_property;
+  gobject_class->get_property = gst_pnmenc_get_property;
+
+  g_object_class_install_property (gobject_class, GST_PNMENC_PROP_ASCII,
+    g_param_spec_boolean ("ascii", "ASCII Encoding", "The output will be "
+        "ASCII encoded", FALSE, G_PARAM_READWRITE));
 }
 
 GST_BOILERPLATE (GstPnmenc, gst_pnmenc, GstElement, GST_TYPE_ELEMENT)
diff --git a/gst/pnm/gstpnmutils.c b/gst/pnm/gstpnmutils.c
index a0c8f38..7f23373 100644
--- a/gst/pnm/gstpnmutils.c
+++ b/gst/pnm/gstpnmutils.c
@@ -94,27 +94,33 @@ gst_pnm_info_mngr_scan (GstPnmInfoMngr * mngr, const guint8 * buf,
     case GST_PNM_INFO_MNGR_STATE_DATA_TYPE:
       switch (buf[i++]) {
         case '1':
-          mngr->info.type = GST_PNM_TYPE_BITMAP_ASCII;
+          mngr->info.type = GST_PNM_TYPE_BITMAP;
+          mngr->info.encoding = GST_PNM_ENCODING_ASCII;
           break;
         case '2':
-          mngr->info.type = GST_PNM_TYPE_GRAYMAP_ASCII;
+          mngr->info.type = GST_PNM_TYPE_GRAYMAP;
+          mngr->info.encoding = GST_PNM_ENCODING_ASCII;
           break;
         case '3':
-          mngr->info.type = GST_PNM_TYPE_PIXMAP_ASCII;
+          mngr->info.type = GST_PNM_TYPE_PIXMAP;
+          mngr->info.encoding = GST_PNM_ENCODING_ASCII;
           break;
         case '4':
-          mngr->info.type = GST_PNM_TYPE_BITMAP_RAW;
+          mngr->info.type = GST_PNM_TYPE_BITMAP;
+          mngr->info.encoding = GST_PNM_ENCODING_RAW;
           break;
         case '5':
-          mngr->info.type = GST_PNM_TYPE_GRAYMAP_RAW;
+          mngr->info.type = GST_PNM_TYPE_GRAYMAP;
+          mngr->info.encoding = GST_PNM_ENCODING_RAW;
           break;
         case '6':
-          mngr->info.type = GST_PNM_TYPE_PIXMAP_RAW;
+          mngr->info.type = GST_PNM_TYPE_PIXMAP;
+          mngr->info.encoding = GST_PNM_ENCODING_RAW;
           break;
         default:
           return GST_PNM_INFO_MNGR_RESULT_FAILED;
       }
-      mngr->info.fields |= GST_PNM_INFO_FIELDS_TYPE;
+      mngr->info.fields |= GST_PNM_INFO_FIELDS_TYPE | GST_PNM_INFO_FIELDS_ENCODING;
       mngr->state = GST_PNM_INFO_MNGR_STATE_WHITE_SPACE;
       if (i == buf_len)
         return GST_PNM_INFO_MNGR_RESULT_READING;
@@ -177,27 +183,3 @@ gst_pnm_info_mngr_scan (GstPnmInfoMngr * mngr, const guint8 * buf,
   }
   return GST_PNM_INFO_MNGR_RESULT_FAILED;
 }
-
-GType
-gst_pnm_type_get_type (void)
-{
-  static GType etype = 0;
-
-  if (etype == 0) {
-    static const GEnumValue values[] = {
-      {GST_PNM_TYPE_BITMAP_RAW, "GST_PNM_TYPE_BITMAP_RAW", MIME_BM " (ascii)"},
-      {GST_PNM_TYPE_GRAYMAP_ASCII, "GST_PNM_TYPE_BITMAP_ASCII",
-          MIME_BM " (raw)"},
-      {GST_PNM_TYPE_GRAYMAP_RAW, "GST_PNM_TYPE_GRAYMAP_RAW",
-          MIME_GM " (ascii)"},
-      {GST_PNM_TYPE_GRAYMAP_ASCII, "GST_PNM_TYPE_GRAYMAP_ASCII",
-          MIME_GM " (raw)"},
-      {GST_PNM_TYPE_PIXMAP_RAW, "GST_PNM_TYPE_PIXMAP_RAW", MIME_PM " (ascii)"},
-      {GST_PNM_TYPE_PIXMAP_ASCII, "GST_PNM_TYPE_PIXMAP_ASCII",
-          MIME_PM " (raw)"},
-      {0, NULL, NULL}
-    };
-    etype = g_enum_register_static ("GstPnmdecType", values);
-  }
-  return etype;
-}
diff --git a/gst/pnm/gstpnmutils.h b/gst/pnm/gstpnmutils.h
index b0afb5f..75b3caa 100644
--- a/gst/pnm/gstpnmutils.h
+++ b/gst/pnm/gstpnmutils.h
@@ -33,26 +33,30 @@ typedef enum
   GST_PNM_INFO_FIELDS_TYPE = 1 << 0,
   GST_PNM_INFO_FIELDS_WIDTH = 1 << 1,
   GST_PNM_INFO_FIELDS_HEIGHT = 1 << 2,
-  GST_PNM_INFO_FIELDS_MAX = 1 << 3
+  GST_PNM_INFO_FIELDS_MAX = 1 << 3,
+  GST_PNM_INFO_FIELDS_ENCODING = 1 << 4
 } GstPnmInfoFields;
 
-#define GST_PNM_INFO_FIELDS_ALL (GST_PNM_INFO_FIELDS_TYPE | GST_PNM_INFO_FIELDS_WIDTH | GST_PNM_INFO_FIELDS_HEIGHT | GST_PNM_INFO_FIELDS_MAX)
+#define GST_PNM_INFO_FIELDS_ALL (GST_PNM_INFO_FIELDS_TYPE | GST_PNM_INFO_FIELDS_WIDTH | GST_PNM_INFO_FIELDS_HEIGHT | GST_PNM_INFO_FIELDS_MAX | GST_PNM_INFO_FIELDS_ENCODING)
 
 typedef enum
 {
-  GST_PNM_TYPE_BITMAP_ASCII = 1,
-  GST_PNM_TYPE_GRAYMAP_ASCII = 2,
-  GST_PNM_TYPE_PIXMAP_ASCII = 3,
-  GST_PNM_TYPE_BITMAP_RAW = 4,
-  GST_PNM_TYPE_GRAYMAP_RAW = 5,
-  GST_PNM_TYPE_PIXMAP_RAW = 6
+  GST_PNM_TYPE_BITMAP = 1,
+  GST_PNM_TYPE_GRAYMAP = 2,
+  GST_PNM_TYPE_PIXMAP = 3
 } GstPnmType;
-GType gst_pnm_type_get_type (void);
+
+typedef enum
+{
+  GST_PNM_ENCODING_RAW = 0,
+  GST_PNM_ENCODING_ASCII = 1
+} GstPnmEncoding;
 
 typedef struct
 {
   GstPnmInfoFields fields;
   GstPnmType type;
+  GstPnmEncoding encoding;
   guint width, height, max;
 } GstPnmInfo;
 
