diff options
author | Lutz Mueller <lutz@topfrose.de> | 2009-09-17 09:38:02 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2009-09-17 09:39:10 +0200 |
commit | a4e438d19381c65ec071221a80a1f329c0928d77 (patch) | |
tree | 4d4546598ceff6d52025a753ce4e7b730713538a | |
parent | c7aa0aae4e42d64d9a5a5f86329f2afb72dc6234 (diff) |
pnm: Add ASCII decoding support
...and make the ASCII output of the encoder a bit more pretty.
Fixes bug #595409.
-rw-r--r-- | gst/pnm/gstpnmdec.c | 123 | ||||
-rw-r--r-- | gst/pnm/gstpnmenc.c | 2 |
2 files changed, 85 insertions, 40 deletions
diff --git a/gst/pnm/gstpnmdec.c b/gst/pnm/gstpnmdec.c index bd28eaea7..0d7cc3c1f 100644 --- a/gst/pnm/gstpnmdec.c +++ b/gst/pnm/gstpnmdec.c @@ -92,14 +92,88 @@ gst_pnmdec_push (GstPnmdec * s, GstPad * src, GstBuffer * buf) } static GstFlowReturn +gst_pnmdec_chain_raw (GstPnmdec * s, GstPad * src, GstBuffer * buf) +{ + GstFlowReturn r = GST_FLOW_OK; + + /* If we got the whole image, just push the buffer. */ + if (GST_BUFFER_SIZE (buf) == s->size) { + memset (&s->mngr, 0, sizeof (GstPnmInfoMngr)); + s->size = 0; + gst_buffer_set_caps (buf, GST_PAD_CAPS (src)); + return gst_pnmdec_push (s, src, buf); + } + + /* We didn't get the whole image. */ + if (!s->buf) { + s->buf = buf; + } else { + buf = gst_buffer_span (s->buf, 0, buf, + GST_BUFFER_SIZE (s->buf) + GST_BUFFER_SIZE (buf)); + gst_buffer_unref (s->buf); + s->buf = buf; + } + if (!s->buf) + return GST_FLOW_ERROR; + + /* Do we now have the full image? If yes, push. */ + if (GST_BUFFER_SIZE (s->buf) == s->size) { + gst_buffer_set_caps (s->buf, GST_PAD_CAPS (src)); + r = gst_pnmdec_push (s, src, s->buf); + s->buf = NULL; + memset (&s->mngr, 0, sizeof (GstPnmInfoMngr)); + s->size = 0; + } + + return r; +} + +static GstFlowReturn +gst_pnmdec_chain_ascii (GstPnmdec * s, GstPad * src, GstBuffer * buf) +{ + GScanner *scanner; + GstBuffer *out = gst_buffer_new_and_alloc (s->size); + guint i = 0; + + scanner = g_scanner_new (NULL); + g_scanner_input_text (scanner, (gchar *) GST_BUFFER_DATA (buf), + GST_BUFFER_SIZE (buf)); + while (!g_scanner_eof (scanner)) { + switch (g_scanner_get_next_token (scanner)) { + case G_TOKEN_INT: + if (i == s->size) { + GST_DEBUG_OBJECT (s, "PNM file contains too much data."); + gst_buffer_unref (buf); + gst_buffer_unref (out); + return GST_FLOW_ERROR; + } + GST_BUFFER_DATA (out)[i++] = scanner->value.v_int; + break; + default: + /* Should we care? */ ; + } + } + g_scanner_destroy (scanner); + gst_buffer_unref (buf); + + if (i < s->size) { + GST_DEBUG_OBJECT (s, "FIXME: Decoding of ASCII encoded files split " + "over several buffers is not implemented!"); + gst_buffer_unref (out); + return GST_FLOW_ERROR; + } + + return gst_pnmdec_chain_raw (s, src, out); +} + +static GstFlowReturn gst_pnmdec_chain (GstPad * pad, GstBuffer * data) { GstPnmdec *s = GST_PNMDEC (gst_pad_get_parent (pad)); GstPad *src = gst_element_get_static_pad (GST_ELEMENT (s), "src"); - GstBuffer *buf; GstCaps *caps = NULL; GstFlowReturn r = GST_FLOW_OK; - guint8 offset = 0; + guint offset = 0; if (!(s->mngr.info.fields & GST_PNM_INFO_FIELDS_ALL)) { switch (gst_pnm_info_mngr_scan (&s->mngr, GST_BUFFER_DATA (data), @@ -114,12 +188,6 @@ 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: @@ -157,40 +225,17 @@ gst_pnmdec_chain (GstPad * pad, GstBuffer * data) goto out; } - /* If we got the whole image, just push the buffer. */ - if (GST_BUFFER_SIZE (data) - offset == s->size) { - buf = gst_buffer_create_sub (data, offset, s->size); - gst_buffer_unref (data); - memset (&s->mngr, 0, sizeof (GstPnmInfoMngr)); - s->size = 0; - gst_buffer_set_caps (buf, GST_PAD_CAPS (src)); - r = gst_pnmdec_push (s, src, buf); - goto out; - } - - /* We didn't get the whole image. */ - if (!s->buf) { - s->buf = gst_buffer_create_sub (data, offset, + if (offset) { + GstBuffer *buf = gst_buffer_create_sub (data, offset, GST_BUFFER_SIZE (data) - offset); - } else { - buf = gst_buffer_span (s->buf, 0, data, - GST_BUFFER_SIZE (s->buf) + GST_BUFFER_SIZE (data) - offset); - gst_buffer_unref (s->buf); - s->buf = buf; - } - if (!s->buf) { - r = GST_FLOW_ERROR; - goto out; + gst_buffer_unref (data); + data = buf; } - /* Do we now have the full image? If yes, push. */ - if (GST_BUFFER_SIZE (s->buf) == s->size) { - gst_buffer_set_caps (s->buf, GST_PAD_CAPS (src)); - r = gst_pnmdec_push (s, src, s->buf); - s->buf = NULL; - memset (&s->mngr, 0, sizeof (GstPnmInfoMngr)); - s->size = 0; - } + if (s->mngr.info.encoding == GST_PNM_ENCODING_ASCII) + r = gst_pnmdec_chain_ascii (s, src, data); + else + r = gst_pnmdec_chain_raw (s, src, data); out: gst_object_unref (src); diff --git a/gst/pnm/gstpnmenc.c b/gst/pnm/gstpnmenc.c index ae2395f3b..f9d558c19 100644 --- a/gst/pnm/gstpnmenc.c +++ b/gst/pnm/gstpnmenc.c @@ -157,7 +157,7 @@ gst_pnmenc_chain (GstPad * pad, GstBuffer * buf) GST_BUFFER_DATA (buf)[i]); o += 3; GST_BUFFER_DATA (obuf)[o++] = ' '; - if (!(i % 20)) + if (!((i + 1) % 20)) GST_BUFFER_DATA (obuf)[o++] = '\n'; } gst_buffer_unref (buf); |