video: add method to get offset and scale for a format
authorWim Taymans <wim.taymans@collabora.co.uk>
Fri, 13 Jul 2012 15:13:10 +0000 (17:13 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Fri, 13 Jul 2012 15:13:10 +0000 (17:13 +0200)
Add a method to get the offset and scale values to transform the color values of
a format to their normalized [0.0 .. 1.0] range. This is usually required as
the first step of a colorspace conversion.

gst-libs/gst/video/video-color.c
gst-libs/gst/video/video-color.h

index 3cab75e..4bd36f6 100644 (file)
@@ -152,6 +152,70 @@ gst_video_colorimetry_matches (GstVideoColorimetry * cinfo, const gchar * color)
   return FALSE;
 }
 
+/**
+ * gst_video_color_range_offsets:
+ * @range: a #GstVideoColorRange
+ * @info: a #GstVideoFormatInfo
+ * @offsets: (out): output offsets
+ * @scale: (out): output scale
+ *
+ * Compute the offset and scale values for each component of @info. For each
+ * component, (c[i] - offset[i]) / scale[i] will scale the component c[i] to the
+ * range [0.0 .. 1.0].
+ *
+ * The reverse operation (c[i] * scale[i]) + offset[i] can be used to convert
+ * the component values in range [0.0 .. 1.0] back to their representation in
+ * @info and @range.
+ */
+void
+gst_video_color_range_offsets (GstVideoColorRange range,
+    const GstVideoFormatInfo * info, gint offset[GST_VIDEO_MAX_COMPONENTS],
+    gint scale[GST_VIDEO_MAX_COMPONENTS])
+{
+  gboolean yuv;
+
+  yuv = GST_VIDEO_FORMAT_INFO_IS_YUV (info);
+
+  switch (range) {
+    default:
+    case GST_VIDEO_COLOR_RANGE_0_255:
+      offset[0] = 0;
+      if (yuv) {
+        offset[1] = 1 << (info->depth[1] - 1);
+        offset[2] = 1 << (info->depth[2] - 1);
+      } else {
+        offset[1] = 0;
+        offset[2] = 0;
+      }
+      scale[0] = (1 << info->depth[0]) - 1;
+      scale[1] = (1 << info->depth[1]) - 1;
+      scale[2] = (1 << info->depth[2]) - 1;
+      break;
+    case GST_VIDEO_COLOR_RANGE_16_235:
+      offset[0] = 1 << (info->depth[0] - 4);
+      scale[0] = 219 << (info->depth[0] - 8);
+      if (yuv) {
+        offset[1] = 1 << (info->depth[1] - 1);
+        offset[2] = 1 << (info->depth[2] - 1);
+        scale[1] = 224 << (info->depth[1] - 8);
+        scale[2] = 224 << (info->depth[2] - 8);
+      } else {
+        offset[1] = 1 << (info->depth[1] - 4);
+        offset[2] = 1 << (info->depth[2] - 4);
+        scale[1] = 219 << (info->depth[1] - 8);
+        scale[2] = 219 << (info->depth[2] - 8);
+      }
+      break;
+  }
+  /* alpha channel is always full range */
+  offset[3] = 0;
+  scale[3] = (1 << info->depth[3]) - 1;
+
+  GST_DEBUG ("scale: %d %d %d %d", scale[0], scale[1], scale[2], scale[3]);
+  GST_DEBUG ("offset: %d %d %d %d", offset[0], offset[1], offset[2], offset[3]);
+}
+
+
 #if 0
 typedef struct
 {
index b574935..dcbb66f 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <gst/gst.h>
 
+#include <gst/video/video-format.h>
+
 G_BEGIN_DECLS
 
 /**
@@ -147,6 +149,13 @@ gboolean     gst_video_colorimetry_matches     (GstVideoColorimetry *cinfo, cons
 gboolean     gst_video_colorimetry_from_string (GstVideoColorimetry *cinfo, const gchar *color);
 gchar *      gst_video_colorimetry_to_string   (GstVideoColorimetry *cinfo);
 
+/* compute offset and scale */
+void         gst_video_color_range_offsets     (GstVideoColorRange range,
+                                                const GstVideoFormatInfo *info,
+                                                gint offset[GST_VIDEO_MAX_COMPONENTS],
+                                                gint scale[GST_VIDEO_MAX_COMPONENTS]);
+
+
 G_END_DECLS
 
 #endif /* __GST_VIDEO_COLOR_H__ */