Пример #1
0
static gboolean
gst_jpeg_parse_read_header (GstJpegParse * parse, GstBuffer * buffer)
{
  GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (buffer);
  guint8 marker = 0;
  gboolean foundSOF = FALSE;

  if (!gst_byte_reader_peek_uint8 (&reader, &marker))
    goto error;

  while (marker == 0xff) {
    if (!gst_byte_reader_skip (&reader, 1))
      goto error;

    if (!gst_byte_reader_get_uint8 (&reader, &marker))
      goto error;

    GST_DEBUG_OBJECT (parse, "marker = %x", marker);

    switch (marker) {
      case SOS:                /* start of scan (begins compressed data) */
        return foundSOF;

      case SOI:
        break;

      case DRI:
        if (!gst_byte_reader_skip (&reader, 4)) /* fixed size */
          goto error;
        break;

      case COM:
        if (!gst_jpeg_parse_com (parse, &reader))
          goto error;
        break;

      case APP1:
        if (!gst_jpeg_parse_app1 (parse, &reader))
          goto error;
        break;

      case DHT:
      case DQT:
        /* Ignore these codes */
        if (!gst_jpeg_parse_skip_marker (parse, &reader, marker))
          goto error;
        break;

      case SOF2:
        parse->priv->interlaced = TRUE;
        /* fall through */
      case SOF0:
        foundSOF = TRUE;
        /* parse Start Of Frame */
        if (!gst_jpeg_parse_sof (parse, &reader))
          goto error;

        return TRUE;

      default:
        if (marker == JPG || (marker >= JPG0 && marker <= JPG13)) {
          /* we'd like to remove them from the buffer */
          if (!gst_jpeg_parse_remove_marker (parse, &reader, marker, buffer))
            goto error;
        } else if (marker >= APP0 && marker <= APP15) {
          if (!gst_jpeg_parse_skip_marker (parse, &reader, marker))
            goto error;
        } else {
          GST_WARNING_OBJECT (parse, "unhandled marker %x, leaving", marker);
          /* Not SOF or SOI.  Must not be a JPEG file (or file pointer
           * is placed wrong).  In either case, it's an error. */
          return FALSE;
        }
    }

    if (!gst_byte_reader_peek_uint8 (&reader, &marker))
      goto error;
  }

  return foundSOF;

error:
  GST_WARNING_OBJECT (parse,
      "Error parsing image header (need more than %u bytes available)",
      gst_byte_reader_get_remaining (&reader));
  return FALSE;
}
Пример #2
0
static gboolean
gst_jif_mux_parse_image (GstJifMux * self, GstBuffer * buf)
{
    GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (buf);
    GstJifMuxMarker *m;
    guint8 marker = 0;
    guint16 size = 0;
    const guint8 *data = NULL;

    GST_LOG_OBJECT (self, "Received buffer of size: %u", GST_BUFFER_SIZE (buf));

    if (!gst_byte_reader_peek_uint8 (&reader, &marker))
        goto error;

    while (marker == 0xff) {
        if (!gst_byte_reader_skip (&reader, 1))
            goto error;

        if (!gst_byte_reader_get_uint8 (&reader, &marker))
            goto error;

        switch (marker) {
        case RST0:
        case RST1:
        case RST2:
        case RST3:
        case RST4:
        case RST5:
        case RST6:
        case RST7:
        case SOI:
            GST_DEBUG_OBJECT (self, "marker = %x", marker);
            m = gst_jif_mux_new_marker (marker, 0, NULL, FALSE);
            self->priv->markers = g_list_prepend (self->priv->markers, m);
            break;
        case EOI:
            GST_DEBUG_OBJECT (self, "marker = %x", marker);
            m = gst_jif_mux_new_marker (marker, 0, NULL, FALSE);
            self->priv->markers = g_list_prepend (self->priv->markers, m);
            goto done;
            break;
        default:
            if (!gst_byte_reader_get_uint16_be (&reader, &size))
                goto error;
            if (!gst_byte_reader_get_data (&reader, size - 2, &data))
                goto error;

            m = gst_jif_mux_new_marker (marker, size - 2, data, FALSE);
            self->priv->markers = g_list_prepend (self->priv->markers, m);

            GST_DEBUG_OBJECT (self, "marker = %2x, size = %u", marker, size);
            break;
        }

        if (marker == SOS) {
            gint eoi_pos = -1;
            gint i;

            /* search the last 5 bytes for the EOI marker */
            g_assert (GST_BUFFER_SIZE (buf) >= 5);
            for (i = 5; i >= 2; i--) {
                if (GST_BUFFER_DATA (buf)[GST_BUFFER_SIZE (buf) - i] == 0xFF &&
                        GST_BUFFER_DATA (buf)[GST_BUFFER_SIZE (buf) - i + 1] == EOI) {
                    eoi_pos = GST_BUFFER_SIZE (buf) - i;
                    break;
                }
            }

            if (eoi_pos == -1) {
                GST_WARNING_OBJECT (self, "Couldn't find an EOI marker");
                eoi_pos = GST_BUFFER_SIZE (buf);
            }

            /* remaining size except EOI is scan data */
            self->priv->scan_size = eoi_pos - gst_byte_reader_get_pos (&reader);
            if (!gst_byte_reader_get_data (&reader, self->priv->scan_size,
                                           &self->priv->scan_data))
                goto error;

            GST_DEBUG_OBJECT (self, "scan data, size = %u", self->priv->scan_size);
        }

        if (!gst_byte_reader_peek_uint8 (&reader, &marker))
            goto error;
    }
    GST_INFO_OBJECT (self, "done parsing at 0x%x / 0x%x",
                     gst_byte_reader_get_pos (&reader), GST_BUFFER_SIZE (buf));

done:
    self->priv->markers = g_list_reverse (self->priv->markers);
    return TRUE;

error:
    GST_WARNING_OBJECT (self,
                        "Error parsing image header (need more that %u bytes available)",
                        gst_byte_reader_get_remaining (&reader));
    return FALSE;
}