gst/avi/gstavidemux.*: Invert DIB images. Fixes #132341.
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>
Sat, 29 Jan 2005 15:47:18 +0000 (15:47 +0000)
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>
Sat, 29 Jan 2005 15:47:18 +0000 (15:47 +0000)
Original commit message from CVS:
* gst/avi/gstavidemux.c: (gst_avi_demux_add_stream), (swap_line),
(gst_avi_demux_invert), (gst_avi_demux_process_next_entry),
(gst_avi_demux_stream_data):
* gst/avi/gstavidemux.h:
Invert DIB images. Fixes #132341.

ChangeLog
gst/avi/gstavidemux.c
gst/avi/gstavidemux.h

index 1607474ae26566d400b95ae4cb9ff7a596b8f92d..8ca829dd94fb5e7782b72770bdcb4a5a394961b1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2005-01-29  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
+
+       * gst/avi/gstavidemux.c: (gst_avi_demux_add_stream), (swap_line),
+       (gst_avi_demux_invert), (gst_avi_demux_process_next_entry),
+       (gst_avi_demux_stream_data):
+       * gst/avi/gstavidemux.h:
+         Invert DIB images. Fixes #132341.
+
 2005-01-29  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
 
        * gst/ffmpegcolorspace/gstffmpegcolorspace.c:
index c3f7a6187edbb7fea7055e4f5d6ed107fae75eb6..2fdd16bdffe2c44d1c2802ab62b6c93c920dda93 100644 (file)
@@ -884,7 +884,7 @@ gst_avi_demux_add_stream (GstAviDemux * avi)
   GstPadTemplate *templ = NULL;
   GstPad *pad;
   avi_stream_context *stream;
-  gint blockalign = 0, bitrate = 0;
+  gint blockalign = 0, bitrate = 0, width = 0, height = 0;
   guint64 *locations = NULL;
   GstTagList *list = gst_tag_list_new ();
   gboolean have_tag = FALSE;
@@ -1003,6 +1003,8 @@ gst_avi_demux_add_stream (GstAviDemux * avi)
         have_tag = TRUE;
         g_free (codec_name);
       }
+      width = strf.vids->width;
+      height = strf.vids->height;
       g_free (strf.vids);
       avi->num_v_streams++;
       break;
@@ -1076,6 +1078,8 @@ gst_avi_demux_add_stream (GstAviDemux * avi)
   stream->skip = 0;
   stream->blockalign = blockalign;
   stream->bitrate = bitrate;
+  stream->width = width;
+  stream->height = height;
   stream->indexes = locations;
   gst_pad_set_element_private (pad, stream);
   avi->num_streams++;
@@ -1984,6 +1988,37 @@ gst_avi_demux_handle_seek (GstAviDemux * avi)
   return TRUE;
 }
 
+/*
+ * Invert DIB buffers... Takes existing buffer and
+ * returns either the buffer or a new one (with old
+ * one dereferenced).
+ */
+
+static inline void
+swap_line (guint8 * d1, guint8 * d2, guint8 * tmp, gint bytes)
+{
+  memcpy (tmp, d1, bytes);
+  memcpy (d1, d2, bytes);
+  memcpy (d2, tmp, bytes);
+}
+
+static GstBuffer *
+gst_avi_demux_invert (avi_stream_context * stream, GstBuffer * buf)
+{
+  buf = gst_buffer_copy_on_write (buf);
+  gint y, h = stream->height, w = stream->width;
+  guint8 *tmp = g_malloc (w);
+
+  for (y = 0; y < h / 2; y++) {
+    swap_line (GST_BUFFER_DATA (buf) + w * y,
+        GST_BUFFER_DATA (buf) + w * (h - 1 - y), tmp, w);
+  }
+
+  g_free (tmp);
+
+  return buf;
+}
+
 static gboolean
 gst_avi_demux_process_next_entry (GstAviDemux * avi)
 {
@@ -2036,6 +2071,9 @@ gst_avi_demux_process_next_entry (GstAviDemux * avi)
           GST_ERROR ("Failed to read %d bytes of data", entry->size);
           return FALSE;
         }
+        if (stream->strh->fcc_handler == GST_MAKE_FOURCC ('D', 'I', 'B', ' ')) {
+          buf = gst_avi_demux_invert (stream, buf);
+        }
         if (entry->flags & GST_RIFF_IF_KEYFRAME) {
           GST_BUFFER_FLAG_SET (buf, GST_BUFFER_KEY_UNIT);
         }
@@ -2126,6 +2164,10 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
       } else {
         GstClockTime dur_ts;
 
+        if (stream->strh->fcc_handler == GST_MAKE_FOURCC ('D', 'I', 'B', ' ')) {
+          buf = gst_avi_demux_invert (stream, buf);
+        }
+
         GST_BUFFER_TIMESTAMP (buf) = next_ts;
         gst_pad_query (stream->pad, GST_QUERY_POSITION, &format, &dur_ts);
         GST_BUFFER_DURATION (buf) = dur_ts - next_ts;
index b506802edce1b04619e58533b631440cbcf55c67..c5db25816a5b971beaeffe93d34e06c987045503 100644 (file)
@@ -64,6 +64,7 @@ typedef struct {
   GstCaps      *caps;
   gst_riff_strh        *strh;
   gint           blockalign, bitrate;
+  gint           width, height;
 
   /* current position (byte, frame, time) */
   guint         current_frame;