mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
pnm: Add ASCII decoding support
...and make the ASCII output of the encoder a bit more pretty. Fixes bug #595409.
This commit is contained in:
parent
c7aa0aae4e
commit
a4e438d193
2 changed files with 85 additions and 40 deletions
|
@ -91,15 +91,89 @@ 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
|
static GstFlowReturn
|
||||||
gst_pnmdec_chain (GstPad * pad, GstBuffer * data)
|
gst_pnmdec_chain (GstPad * pad, GstBuffer * data)
|
||||||
{
|
{
|
||||||
GstPnmdec *s = GST_PNMDEC (gst_pad_get_parent (pad));
|
GstPnmdec *s = GST_PNMDEC (gst_pad_get_parent (pad));
|
||||||
GstPad *src = gst_element_get_static_pad (GST_ELEMENT (s), "src");
|
GstPad *src = gst_element_get_static_pad (GST_ELEMENT (s), "src");
|
||||||
GstBuffer *buf;
|
|
||||||
GstCaps *caps = NULL;
|
GstCaps *caps = NULL;
|
||||||
GstFlowReturn r = GST_FLOW_OK;
|
GstFlowReturn r = GST_FLOW_OK;
|
||||||
guint8 offset = 0;
|
guint offset = 0;
|
||||||
|
|
||||||
if (!(s->mngr.info.fields & GST_PNM_INFO_FIELDS_ALL)) {
|
if (!(s->mngr.info.fields & GST_PNM_INFO_FIELDS_ALL)) {
|
||||||
switch (gst_pnm_info_mngr_scan (&s->mngr, GST_BUFFER_DATA (data),
|
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;
|
goto out;
|
||||||
case GST_PNM_INFO_MNGR_RESULT_FINISHED:
|
case GST_PNM_INFO_MNGR_RESULT_FINISHED:
|
||||||
offset = s->mngr.data_offset;
|
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));
|
caps = gst_caps_copy (gst_pad_get_pad_template_caps (src));
|
||||||
switch (s->mngr.info.type) {
|
switch (s->mngr.info.type) {
|
||||||
case GST_PNM_TYPE_BITMAP:
|
case GST_PNM_TYPE_BITMAP:
|
||||||
|
@ -157,40 +225,17 @@ gst_pnmdec_chain (GstPad * pad, GstBuffer * data)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we got the whole image, just push the buffer. */
|
if (offset) {
|
||||||
if (GST_BUFFER_SIZE (data) - offset == s->size) {
|
GstBuffer *buf = gst_buffer_create_sub (data, offset,
|
||||||
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,
|
|
||||||
GST_BUFFER_SIZE (data) - offset);
|
GST_BUFFER_SIZE (data) - offset);
|
||||||
} else {
|
gst_buffer_unref (data);
|
||||||
buf = gst_buffer_span (s->buf, 0, data,
|
data = buf;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do we now have the full image? If yes, push. */
|
if (s->mngr.info.encoding == GST_PNM_ENCODING_ASCII)
|
||||||
if (GST_BUFFER_SIZE (s->buf) == s->size) {
|
r = gst_pnmdec_chain_ascii (s, src, data);
|
||||||
gst_buffer_set_caps (s->buf, GST_PAD_CAPS (src));
|
else
|
||||||
r = gst_pnmdec_push (s, src, s->buf);
|
r = gst_pnmdec_chain_raw (s, src, data);
|
||||||
s->buf = NULL;
|
|
||||||
memset (&s->mngr, 0, sizeof (GstPnmInfoMngr));
|
|
||||||
s->size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
gst_object_unref (src);
|
gst_object_unref (src);
|
||||||
|
|
|
@ -157,7 +157,7 @@ gst_pnmenc_chain (GstPad * pad, GstBuffer * buf)
|
||||||
GST_BUFFER_DATA (buf)[i]);
|
GST_BUFFER_DATA (buf)[i]);
|
||||||
o += 3;
|
o += 3;
|
||||||
GST_BUFFER_DATA (obuf)[o++] = ' ';
|
GST_BUFFER_DATA (obuf)[o++] = ' ';
|
||||||
if (!(i % 20))
|
if (!((i + 1) % 20))
|
||||||
GST_BUFFER_DATA (obuf)[o++] = '\n';
|
GST_BUFFER_DATA (obuf)[o++] = '\n';
|
||||||
}
|
}
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
Loading…
Reference in a new issue