[gimp] Add support for both gamma-corrected and linear for all bit depths



commit caf73f5f350e25d1a8b2259748df5cb6cd1d1478
Author: Michael Natterer <mitch gimp org>
Date:   Sun Jun 23 16:51:24 2013 +0200

    Add support for both gamma-corrected and linear for all bit depths
    
    - Add new enum GimpComponentType which contains u8, u16, u32 etc.
    - Change GimpPrecision to be u8-linear, u8-gamma, u16-linear etc.
    - Add all the needed formats to gimp-babl.c
    - Bump the XCF version to 5 and make sure version 4 with the old
      GimpPrecision enum values is loaded correctly
    
    This change blows up the precision enums in "New Image" and
    Image->Precision so we can test all this stuff. It is undecided what
    format will be user-visible options in 2.10.

 app/actions/debug-commands.c           |    2 +-
 app/actions/image-actions.c            |  162 +++++++---
 app/core/core-enums.c                  |   65 +++-
 app/core/core-enums.h                  |   29 ++-
 app/core/gimpbuffer.c                  |    4 +-
 app/core/gimpdrawable.c                |   12 +
 app/core/gimpdrawable.h                |    1 +
 app/core/gimpimage-contiguous-region.c |    2 +-
 app/core/gimpimage-convert-precision.c |   41 ++-
 app/core/gimpimage-new.c               |    2 +-
 app/core/gimpimage-preview.c           |    2 +-
 app/core/gimpimage.c                   |   16 +-
 app/core/gimpimage.h                   |    1 +
 app/core/gimptemplate.c                |    4 +-
 app/file/file-open.c                   |   12 +-
 app/gegl/gimp-babl-compat.c            |    2 +-
 app/gegl/gimp-babl.c                   |  583 ++++++++++++++++++++++++++-----
 app/gegl/gimp-babl.h                   |   32 +-
 app/gegl/gimp-gegl-loops.c             |   10 +-
 app/pdb/convert-cmds.c                 |    4 +-
 app/pdb/image-cmds.c                   |   10 +-
 app/tests/gimp-app-test-utils.c        |    2 +-
 app/tools/gimpbrightnesscontrasttool.c |    2 +-
 app/tools/gimpcurvestool.c             |    2 +-
 app/tools/gimplevelstool.c             |    2 +-
 app/widgets/gimpcolorframe.c           |   27 +-
 app/xcf/xcf-load.c                     |   31 ++-
 app/xcf/xcf-save.c                     |    4 +-
 app/xcf/xcf.c                          |    3 +-
 libgimp/gimpenums.c.tail               |    2 +
 libgimp/gimpenums.h                    |   29 ++-
 libgimp/gimpimage_pdb.c                |    2 +-
 menus/image-menu.xml.in                |   15 +-
 plug-ins/common/file-gegl.c            |   94 ++++--
 plug-ins/common/file-png.c             |   14 +-
 plug-ins/common/file-ps.c              |    2 +-
 plug-ins/common/file-tiff-load.c       |    8 +-
 plug-ins/common/file-tiff-save.c       |    2 +-
 plug-ins/file-exr/file-exr.c           |    6 +-
 plug-ins/file-fits/fits.c              |   10 +-
 plug-ins/file-jpeg/jpeg-load.c         |    7 +-
 tools/pdbgen/enums.pl                  |   39 ++-
 tools/pdbgen/pdb/convert.pdb           |    2 +-
 tools/pdbgen/pdb/image.pdb             |    6 +-
 44 files changed, 995 insertions(+), 312 deletions(-)
---
diff --git a/app/actions/debug-commands.c b/app/actions/debug-commands.c
index bb0377e..1581784 100644
--- a/app/actions/debug-commands.c
+++ b/app/actions/debug-commands.c
@@ -303,7 +303,7 @@ debug_show_image_graph (GimpImage *source_image)
                                  gegl_buffer_get_width (buffer),
                                  gegl_buffer_get_height (buffer),
                                  GIMP_RGB,
-                                 GIMP_PRECISION_U8,
+                                 GIMP_PRECISION_U8_GAMMA,
                                  FALSE);
   gimp_image_set_uri (new_image, new_name);
   layer = gimp_layer_new_from_buffer (buffer,
diff --git a/app/actions/image-actions.c b/app/actions/image-actions.c
index 23688fa..21b908a 100644
--- a/app/actions/image-actions.c
+++ b/app/actions/image-actions.c
@@ -164,30 +164,65 @@ static const GimpRadioActionEntry image_convert_base_type_actions[] =
 
 static const GimpRadioActionEntry image_convert_precision_actions[] =
 {
-  { "image-convert-u8", NULL,
-    NC_("image-convert-action", "8 bit integer"), NULL,
-    NC_("image-convert-action", "Convert the image to 8 bit integer"),
-    GIMP_PRECISION_U8, GIMP_HELP_IMAGE_CONVERT_U8 },
-
-  { "image-convert-u16", NULL,
-    NC_("image-convert-action", "16 bit integer"), NULL,
-    NC_("image-convert-action", "Convert the image to 16 bit integer"),
-    GIMP_PRECISION_U16, GIMP_HELP_IMAGE_CONVERT_U16 },
-
-  { "image-convert-u32", NULL,
-    NC_("image-convert-action", "32 bit integer"), NULL,
-    NC_("image-convert-action", "Convert the image to 32 bit integer"),
-    GIMP_PRECISION_U32, GIMP_HELP_IMAGE_CONVERT_U32 },
-
-  { "image-convert-half", NULL,
-    NC_("image-convert-action", "16 bit floating point"), NULL,
-    NC_("image-convert-action", "Convert the image to 16 bit floating point"),
-    GIMP_PRECISION_HALF, GIMP_HELP_IMAGE_CONVERT_HALF },
-
-  { "image-convert-float", NULL,
-    NC_("image-convert-action", "32 bit floating point"), NULL,
-    NC_("image-convert-action", "Convert the image to 32 bit floating point"),
-    GIMP_PRECISION_FLOAT, GIMP_HELP_IMAGE_CONVERT_FLOAT }
+  { "image-convert-u8-linear", NULL,
+    NC_("image-convert-action", "8 bit integer (linear)"), NULL,
+    NC_("image-convert-action",
+        "Convert the image to 8 bit linear integer"),
+    GIMP_PRECISION_U8_LINEAR, GIMP_HELP_IMAGE_CONVERT_U8 },
+
+  { "image-convert-u8-gamma", NULL,
+    NC_("image-convert-action", "8 bit integer (gamma)"), NULL,
+    NC_("image-convert-action",
+        "Convert the image to 8 bit gamma-corrected integer"),
+    GIMP_PRECISION_U8_GAMMA, GIMP_HELP_IMAGE_CONVERT_U8 },
+
+  { "image-convert-u16-linear", NULL,
+    NC_("image-convert-action", "16 bit integer (linear)"), NULL,
+    NC_("image-convert-action",
+        "Convert the image to 16 bit linear integer"),
+    GIMP_PRECISION_U16_LINEAR, GIMP_HELP_IMAGE_CONVERT_U16 },
+
+  { "image-convert-u16-gamma", NULL,
+    NC_("image-convert-action", "16 bit integer (gamma)"), NULL,
+    NC_("image-convert-action",
+        "Convert the image to 16 bit gamma-corrected integer"),
+    GIMP_PRECISION_U16_GAMMA, GIMP_HELP_IMAGE_CONVERT_U16 },
+
+  { "image-convert-u32-linear", NULL,
+    NC_("image-convert-action", "32 bit integer (linear)"), NULL,
+    NC_("image-convert-action",
+        "Convert the image to 32 bit linear integer"),
+    GIMP_PRECISION_U32_LINEAR, GIMP_HELP_IMAGE_CONVERT_U32 },
+
+  { "image-convert-u32-gamma", NULL,
+    NC_("image-convert-action", "32 bit integer (gamma)"), NULL,
+    NC_("image-convert-action",
+        "Convert the image to 32 bit gamma-corrected integer"),
+    GIMP_PRECISION_U32_GAMMA, GIMP_HELP_IMAGE_CONVERT_U32 },
+
+  { "image-convert-half-linear", NULL,
+    NC_("image-convert-action", "16 bit floating point (linear)"), NULL,
+    NC_("image-convert-action",
+        "Convert the image to 16 bit linear floating point"),
+    GIMP_PRECISION_HALF_LINEAR, GIMP_HELP_IMAGE_CONVERT_HALF },
+
+  { "image-convert-half-gamma", NULL,
+    NC_("image-convert-action", "16 bit floating point (gamma)"), NULL,
+    NC_("image-convert-action",
+        "Convert the image to 16 bit gamma-corrected floating point"),
+    GIMP_PRECISION_HALF_GAMMA, GIMP_HELP_IMAGE_CONVERT_HALF },
+
+  { "image-convert-float-linear", NULL,
+    NC_("image-convert-action", "32 bit floating point (linear)"), NULL,
+    NC_("image-convert-action",
+        "Convert the image to 32 bit linear floating point"),
+    GIMP_PRECISION_FLOAT_LINEAR, GIMP_HELP_IMAGE_CONVERT_FLOAT },
+
+  { "image-convert-float-gamma", NULL,
+    NC_("image-convert-action", "32 bit floating point (gamma)"), NULL,
+    NC_("image-convert-action",
+        "Convert the image to 32 bit gamma-corrected floating point"),
+    GIMP_PRECISION_FLOAT_GAMMA, GIMP_HELP_IMAGE_CONVERT_FLOAT }
 };
 
 static const GimpEnumActionEntry image_flip_actions[] =
@@ -270,13 +305,13 @@ void
 image_actions_update (GimpActionGroup *group,
                       gpointer         data)
 {
-  GimpImage *image      = action_data_get_image (data);
-  gboolean   is_indexed = FALSE;
-  gboolean   is_u8      = FALSE;
-  gboolean   aux        = FALSE;
-  gboolean   lp         = FALSE;
-  gboolean   sel        = FALSE;
-  gboolean   groups     = FALSE;
+  GimpImage *image       = action_data_get_image (data);
+  gboolean   is_indexed  = FALSE;
+  gboolean   is_u8_gamma = FALSE;
+  gboolean   aux         = FALSE;
+  gboolean   lp          = FALSE;
+  gboolean   sel         = FALSE;
+  gboolean   groups      = FALSE;
 
   if (image)
     {
@@ -294,20 +329,46 @@ image_actions_update (GimpActionGroup *group,
 
       switch (gimp_image_get_precision (image))
         {
-        case GIMP_PRECISION_U8:    action = "image-convert-u8";    break;
-        case GIMP_PRECISION_U16:   action = "image-convert-u16";   break;
-        case GIMP_PRECISION_U32:   action = "image-convert-u32";   break;
-        case GIMP_PRECISION_HALF:  action = "image-convert-half";  break;
-        case GIMP_PRECISION_FLOAT: action = "image-convert-float"; break;
+        case GIMP_PRECISION_U8_LINEAR:
+          action = "image-convert-u8-linear";
+          break;
+        case GIMP_PRECISION_U8_GAMMA:
+          action = "image-convert-u8-gamma";
+          break;
+        case GIMP_PRECISION_U16_LINEAR:
+          action = "image-convert-u16-linear";
+          break;
+        case GIMP_PRECISION_U16_GAMMA:
+          action = "image-convert-u16-gamma";
+          break;
+        case GIMP_PRECISION_U32_LINEAR:
+          action = "image-convert-u32-linear";
+          break;
+        case GIMP_PRECISION_U32_GAMMA:
+          action = "image-convert-u32-gamma";
+          break;
+        case GIMP_PRECISION_HALF_LINEAR:
+          action = "image-convert-half-linear";
+          break;
+        case GIMP_PRECISION_HALF_GAMMA:
+          action = "image-convert-half-gamma";
+          break;
+        case GIMP_PRECISION_FLOAT_LINEAR:
+          action = "image-convert-float-linear";
+          break;
+        case GIMP_PRECISION_FLOAT_GAMMA:
+          action = "image-convert-float-gamma";
+          break;
         }
 
       gimp_action_group_set_action_active (group, action, TRUE);
 
-      is_indexed = (gimp_image_get_base_type (image) == GIMP_INDEXED);
-      is_u8      = (gimp_image_get_precision (image) == GIMP_PRECISION_U8);
-      aux        = (gimp_image_get_active_channel (image) != NULL);
-      lp         = ! gimp_image_is_empty (image);
-      sel        = ! gimp_channel_is_empty (gimp_image_get_mask (image));
+      is_indexed  = (gimp_image_get_base_type (image) == GIMP_INDEXED);
+      is_u8_gamma = (gimp_image_get_precision (image) ==
+                     GIMP_PRECISION_U8_GAMMA);
+      aux         = (gimp_image_get_active_channel (image) != NULL);
+      lp          = ! gimp_image_is_empty (image);
+      sel         = ! gimp_channel_is_empty (gimp_image_get_mask (image));
 
       layers = gimp_image_get_layers (image);
 
@@ -319,13 +380,18 @@ image_actions_update (GimpActionGroup *group,
 
   SET_SENSITIVE ("image-convert-rgb",       image);
   SET_SENSITIVE ("image-convert-grayscale", image);
-  SET_SENSITIVE ("image-convert-indexed",   image && !groups && is_u8);
-
-  SET_SENSITIVE ("image-convert-u8",    image);
-  SET_SENSITIVE ("image-convert-u16",   image && !is_indexed);
-  SET_SENSITIVE ("image-convert-u32",   image && !is_indexed);
-  SET_SENSITIVE ("image-convert-half",  image && !is_indexed);
-  SET_SENSITIVE ("image-convert-float", image && !is_indexed);
+  SET_SENSITIVE ("image-convert-indexed",   image && !groups && is_u8_gamma);
+
+  SET_SENSITIVE ("image-convert-u8-gamma",     image);
+  SET_SENSITIVE ("image-convert-u8-linear",    image && !is_indexed);
+  SET_SENSITIVE ("image-convert-u16-gamma",    image && !is_indexed);
+  SET_SENSITIVE ("image-convert-u16-linear",   image && !is_indexed);
+  SET_SENSITIVE ("image-convert-u32-gamma",    image && !is_indexed);
+  SET_SENSITIVE ("image-convert-u32-linear",   image && !is_indexed);
+  SET_SENSITIVE ("image-convert-half-gamma",   image && !is_indexed);
+  SET_SENSITIVE ("image-convert-half-linear",  image && !is_indexed);
+  SET_SENSITIVE ("image-convert-float-gamma",  image && !is_indexed);
+  SET_SENSITIVE ("image-convert-float-linear", image && !is_indexed);
 
   SET_SENSITIVE ("image-flip-horizontal", image);
   SET_SENSITIVE ("image-flip-vertical",   image);
diff --git a/app/core/core-enums.c b/app/core/core-enums.c
index 1065058..491ec16 100644
--- a/app/core/core-enums.c
+++ b/app/core/core-enums.c
@@ -44,6 +44,41 @@ gimp_component_mask_get_type (void)
 }
 
 GType
+gimp_component_type_get_type (void)
+{
+  static const GEnumValue values[] =
+  {
+    { GIMP_COMPONENT_TYPE_U8, "GIMP_COMPONENT_TYPE_U8", "u8" },
+    { GIMP_COMPONENT_TYPE_U16, "GIMP_COMPONENT_TYPE_U16", "u16" },
+    { GIMP_COMPONENT_TYPE_U32, "GIMP_COMPONENT_TYPE_U32", "u32" },
+    { GIMP_COMPONENT_TYPE_HALF, "GIMP_COMPONENT_TYPE_HALF", "half" },
+    { GIMP_COMPONENT_TYPE_FLOAT, "GIMP_COMPONENT_TYPE_FLOAT", "float" },
+    { 0, NULL, NULL }
+  };
+
+  static const GimpEnumDesc descs[] =
+  {
+    { GIMP_COMPONENT_TYPE_U8, NC_("component-type", "8-bit integer"), NULL },
+    { GIMP_COMPONENT_TYPE_U16, NC_("component-type", "16-bit integer"), NULL },
+    { GIMP_COMPONENT_TYPE_U32, NC_("component-type", "32-bit integer"), NULL },
+    { GIMP_COMPONENT_TYPE_HALF, NC_("component-type", "16-bit floating point"), NULL },
+    { GIMP_COMPONENT_TYPE_FLOAT, NC_("component-type", "32-bit floating point"), NULL },
+    { 0, NULL, NULL }
+  };
+
+  static GType type = 0;
+
+  if (G_UNLIKELY (! type))
+    {
+      type = g_enum_register_static ("GimpComponentType", values);
+      gimp_type_set_translation_context (type, "component-type");
+      gimp_enum_set_value_descriptions (type, descs);
+    }
+
+  return type;
+}
+
+GType
 gimp_container_policy_get_type (void)
 {
   static const GEnumValue values[] =
@@ -753,21 +788,31 @@ gimp_precision_get_type (void)
 {
   static const GEnumValue values[] =
   {
-    { GIMP_PRECISION_U8, "GIMP_PRECISION_U8", "u8" },
-    { GIMP_PRECISION_U16, "GIMP_PRECISION_U16", "u16" },
-    { GIMP_PRECISION_U32, "GIMP_PRECISION_U32", "u32" },
-    { GIMP_PRECISION_HALF, "GIMP_PRECISION_HALF", "half" },
-    { GIMP_PRECISION_FLOAT, "GIMP_PRECISION_FLOAT", "float" },
+    { GIMP_PRECISION_U8_LINEAR, "GIMP_PRECISION_U8_LINEAR", "u8-linear" },
+    { GIMP_PRECISION_U8_GAMMA, "GIMP_PRECISION_U8_GAMMA", "u8-gamma" },
+    { GIMP_PRECISION_U16_LINEAR, "GIMP_PRECISION_U16_LINEAR", "u16-linear" },
+    { GIMP_PRECISION_U16_GAMMA, "GIMP_PRECISION_U16_GAMMA", "u16-gamma" },
+    { GIMP_PRECISION_U32_LINEAR, "GIMP_PRECISION_U32_LINEAR", "u32-linear" },
+    { GIMP_PRECISION_U32_GAMMA, "GIMP_PRECISION_U32_GAMMA", "u32-gamma" },
+    { GIMP_PRECISION_HALF_LINEAR, "GIMP_PRECISION_HALF_LINEAR", "half-linear" },
+    { GIMP_PRECISION_HALF_GAMMA, "GIMP_PRECISION_HALF_GAMMA", "half-gamma" },
+    { GIMP_PRECISION_FLOAT_LINEAR, "GIMP_PRECISION_FLOAT_LINEAR", "float-linear" },
+    { GIMP_PRECISION_FLOAT_GAMMA, "GIMP_PRECISION_FLOAT_GAMMA", "float-gamma" },
     { 0, NULL, NULL }
   };
 
   static const GimpEnumDesc descs[] =
   {
-    { GIMP_PRECISION_U8, NC_("precision", "8-bit integer"), NULL },
-    { GIMP_PRECISION_U16, NC_("precision", "16-bit integer"), NULL },
-    { GIMP_PRECISION_U32, NC_("precision", "32-bit integer"), NULL },
-    { GIMP_PRECISION_HALF, NC_("precision", "16-bit floating point"), NULL },
-    { GIMP_PRECISION_FLOAT, NC_("precision", "32-bit floating point"), NULL },
+    { GIMP_PRECISION_U8_LINEAR, NC_("precision", "8-bit linear integer"), NULL },
+    { GIMP_PRECISION_U8_GAMMA, NC_("precision", "8-bit gamma integer"), NULL },
+    { GIMP_PRECISION_U16_LINEAR, NC_("precision", "16-bit linear integer"), NULL },
+    { GIMP_PRECISION_U16_GAMMA, NC_("precision", "16-bit gamma integer"), NULL },
+    { GIMP_PRECISION_U32_LINEAR, NC_("precision", "32-bit linear integer"), NULL },
+    { GIMP_PRECISION_U32_GAMMA, NC_("precision", "32-bit gamma integer"), NULL },
+    { GIMP_PRECISION_HALF_LINEAR, NC_("precision", "16-bit linear floating point"), NULL },
+    { GIMP_PRECISION_HALF_GAMMA, NC_("precision", "16-bit gamma floating point"), NULL },
+    { GIMP_PRECISION_FLOAT_LINEAR, NC_("precision", "32-bit linear floating point"), NULL },
+    { GIMP_PRECISION_FLOAT_GAMMA, NC_("precision", "32-bit gamma floating point"), NULL },
     { 0, NULL, NULL }
   };
 
diff --git a/app/core/core-enums.h b/app/core/core-enums.h
index d49ff76..4ee7713 100644
--- a/app/core/core-enums.h
+++ b/app/core/core-enums.h
@@ -54,6 +54,20 @@ typedef enum /*< pdb-skip >*/
 } GimpComponentMask;
 
 
+#define GIMP_TYPE_COMPONENT_TYPE (gimp_component_type_get_type ())
+
+GType gimp_component_type_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+  GIMP_COMPONENT_TYPE_U8    = 100, /*< desc="8-bit integer"         >*/
+  GIMP_COMPONENT_TYPE_U16   = 200, /*< desc="16-bit integer"        >*/
+  GIMP_COMPONENT_TYPE_U32   = 300, /*< desc="32-bit integer"        >*/
+  GIMP_COMPONENT_TYPE_HALF  = 400, /*< desc="16-bit floating point" >*/
+  GIMP_COMPONENT_TYPE_FLOAT = 500  /*< desc="32-bit floating point" >*/
+} GimpComponentType;
+
+
 #define GIMP_TYPE_CONTAINER_POLICY (gimp_container_policy_get_type ())
 
 GType gimp_container_policy_get_type (void) G_GNUC_CONST;
@@ -348,11 +362,16 @@ GType gimp_precision_get_type (void) G_GNUC_CONST;
 
 typedef enum
 {
-  GIMP_PRECISION_U8,    /*< desc="8-bit integer"         >*/
-  GIMP_PRECISION_U16,   /*< desc="16-bit integer"        >*/
-  GIMP_PRECISION_U32,   /*< desc="32-bit integer"        >*/
-  GIMP_PRECISION_HALF,  /*< desc="16-bit floating point" >*/
-  GIMP_PRECISION_FLOAT  /*< desc="32-bit floating point" >*/
+  GIMP_PRECISION_U8_LINEAR    = 100, /*< desc="8-bit linear integer"         >*/
+  GIMP_PRECISION_U8_GAMMA     = 150, /*< desc="8-bit gamma integer"          >*/
+  GIMP_PRECISION_U16_LINEAR   = 200, /*< desc="16-bit linear integer"        >*/
+  GIMP_PRECISION_U16_GAMMA    = 250, /*< desc="16-bit gamma integer"         >*/
+  GIMP_PRECISION_U32_LINEAR   = 300, /*< desc="32-bit linear integer"        >*/
+  GIMP_PRECISION_U32_GAMMA    = 350, /*< desc="32-bit gamma integer"         >*/
+  GIMP_PRECISION_HALF_LINEAR  = 400, /*< desc="16-bit linear floating point" >*/
+  GIMP_PRECISION_HALF_GAMMA   = 450, /*< desc="16-bit gamma floating point"  >*/
+  GIMP_PRECISION_FLOAT_LINEAR = 500, /*< desc="32-bit linear floating point" >*/
+  GIMP_PRECISION_FLOAT_GAMMA  = 550  /*< desc="32-bit gamma floating point"  >*/
 } GimpPrecision;
 
 
diff --git a/app/core/gimpbuffer.c b/app/core/gimpbuffer.c
index 304071b..129422b 100644
--- a/app/core/gimpbuffer.c
+++ b/app/core/gimpbuffer.c
@@ -202,11 +202,11 @@ gimp_buffer_get_new_preview (GimpViewable *viewable,
   GimpTempBuf *preview;
 
   if (babl_format_is_palette (format))
-    format = gimp_babl_format (GIMP_RGB, GIMP_PRECISION_U8,
+    format = gimp_babl_format (GIMP_RGB, GIMP_PRECISION_U8_GAMMA,
                                babl_format_has_alpha (format));
   else
     format = gimp_babl_format (gimp_babl_format_get_base_type (format),
-                               GIMP_PRECISION_U8,
+                               GIMP_PRECISION_U8_GAMMA,
                                babl_format_has_alpha (format));
 
   preview = gimp_temp_buf_new (width, height, format);
diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c
index 73215a8..677e521 100644
--- a/app/core/gimpdrawable.c
+++ b/app/core/gimpdrawable.c
@@ -1626,6 +1626,18 @@ gimp_drawable_get_base_type (const GimpDrawable *drawable)
   return gimp_babl_format_get_base_type (format);
 }
 
+GimpComponentType
+gimp_drawable_get_component_type (const GimpDrawable *drawable)
+{
+  const Babl *format;
+
+  g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), -1);
+
+  format = gegl_buffer_get_format (drawable->private->buffer);
+
+  return gimp_babl_format_get_component_type (format);
+}
+
 GimpPrecision
 gimp_drawable_get_precision (const GimpDrawable *drawable)
 {
diff --git a/app/core/gimpdrawable.h b/app/core/gimpdrawable.h
index d5d826f..84210f3 100644
--- a/app/core/gimpdrawable.h
+++ b/app/core/gimpdrawable.h
@@ -208,6 +208,7 @@ const Babl    * gimp_drawable_get_format_without_alpha
 gboolean        gimp_drawable_get_linear         (const GimpDrawable *drawable);
 gboolean        gimp_drawable_has_alpha          (const GimpDrawable *drawable);
 GimpImageBaseType gimp_drawable_get_base_type    (const GimpDrawable *drawable);
+GimpComponentType gimp_drawable_get_component_type(const GimpDrawable *drawable);
 GimpPrecision   gimp_drawable_get_precision      (const GimpDrawable *drawable);
 gboolean        gimp_drawable_is_rgb             (const GimpDrawable *drawable);
 gboolean        gimp_drawable_is_gray            (const GimpDrawable *drawable);
diff --git a/app/core/gimpimage-contiguous-region.c b/app/core/gimpimage-contiguous-region.c
index 0fb5e19..2309975 100644
--- a/app/core/gimpimage-contiguous-region.c
+++ b/app/core/gimpimage-contiguous-region.c
@@ -259,7 +259,7 @@ choose_format (GeglBuffer          *buffer,
         format = babl_format ("RGBA float");
       else
         format = gimp_babl_format (gimp_babl_format_get_base_type (format),
-                                   GIMP_PRECISION_FLOAT,
+                                   GIMP_PRECISION_FLOAT_LINEAR,
                                    *has_alpha);
       break;
 
diff --git a/app/core/gimpimage-convert-precision.c b/app/core/gimpimage-convert-precision.c
index 9e70a2d..c7defc9 100644
--- a/app/core/gimpimage-convert-precision.c
+++ b/app/core/gimpimage-convert-precision.c
@@ -53,7 +53,7 @@ gimp_image_convert_precision (GimpImage     *image,
 
   g_return_if_fail (GIMP_IS_IMAGE (image));
   g_return_if_fail (precision != gimp_image_get_precision (image));
-  g_return_if_fail (precision == GIMP_PRECISION_U8 ||
+  g_return_if_fail (precision == GIMP_PRECISION_U8_GAMMA ||
                     gimp_image_get_base_type (image) != GIMP_INDEXED);
   g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
 
@@ -64,24 +64,35 @@ gimp_image_convert_precision (GimpImage     *image,
 
   switch (precision)
     {
-    case GIMP_PRECISION_U8:
-      undo_desc = C_("undo-type", "Convert Image to 8 bit integer");
+    case GIMP_PRECISION_U8_LINEAR:
+      undo_desc = C_("undo-type", "Convert Image to 8 bit linear integer");
       break;
-
-    case GIMP_PRECISION_U16:
-      undo_desc = C_("undo-type", "Convert Image to 16 bit integer");
+    case GIMP_PRECISION_U8_GAMMA:
+      undo_desc = C_("undo-type", "Convert Image to 8 bit gamma integer");
       break;
-
-    case GIMP_PRECISION_U32:
-      undo_desc = C_("undo-type", "Convert Image to 32 bit integer");
+    case GIMP_PRECISION_U16_LINEAR:
+      undo_desc = C_("undo-type", "Convert Image to 16 bit linear integer");
       break;
-
-    case GIMP_PRECISION_HALF:
-      undo_desc = C_("undo-type", "Convert Image to 16 bit floating point");
+    case GIMP_PRECISION_U16_GAMMA:
+      undo_desc = C_("undo-type", "Convert Image to 16 bit gamma integer");
       break;
-
-    case GIMP_PRECISION_FLOAT:
-      undo_desc = C_("undo-type", "Convert Image to 32 bit floating point");
+    case GIMP_PRECISION_U32_LINEAR:
+      undo_desc = C_("undo-type", "Convert Image to 32 bit linear integer");
+      break;
+    case GIMP_PRECISION_U32_GAMMA:
+      undo_desc = C_("undo-type", "Convert Image to 32 bit gamma integer");
+      break;
+    case GIMP_PRECISION_HALF_LINEAR:
+      undo_desc = C_("undo-type", "Convert Image to 16 bit linear floating point");
+      break;
+    case GIMP_PRECISION_HALF_GAMMA:
+      undo_desc = C_("undo-type", "Convert Image to 16 bit gamma floating point");
+      break;
+    case GIMP_PRECISION_FLOAT_LINEAR:
+      undo_desc = C_("undo-type", "Convert Image to 32 bit linear floating point");
+      break;
+    case GIMP_PRECISION_FLOAT_GAMMA:
+      undo_desc = C_("undo-type", "Convert Image to 32 bit gamma floating point");
       break;
     }
 
diff --git a/app/core/gimpimage-new.c b/app/core/gimpimage-new.c
index 2e3d5e4..ca88952 100644
--- a/app/core/gimpimage-new.c
+++ b/app/core/gimpimage-new.c
@@ -343,7 +343,7 @@ gimp_image_new_from_pixbuf (Gimp        *gimp,
                                  gdk_pixbuf_get_width  (pixbuf),
                                  gdk_pixbuf_get_height (pixbuf),
                                  base_type,
-                                 GIMP_PRECISION_U8,
+                                 GIMP_PRECISION_U8_GAMMA,
                                  FALSE);
 
   gimp_image_undo_disable (new_image);
diff --git a/app/core/gimpimage-preview.c b/app/core/gimpimage-preview.c
index 1fb73c4..8c98213 100644
--- a/app/core/gimpimage-preview.c
+++ b/app/core/gimpimage-preview.c
@@ -112,7 +112,7 @@ gimp_image_get_new_preview (GimpViewable *viewable,
 
   format = gimp_projectable_get_format (GIMP_PROJECTABLE (image));
   format = gimp_babl_format (gimp_babl_format_get_base_type (format),
-                             GIMP_PRECISION_U8,
+                             GIMP_PRECISION_U8_GAMMA,
                              babl_format_has_alpha (format));
 
   buf = gimp_temp_buf_new (width, height, format);
diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c
index f5b0409..74975ab 100644
--- a/app/core/gimpimage.c
+++ b/app/core/gimpimage.c
@@ -591,7 +591,7 @@ gimp_image_class_init (GimpImageClass *klass)
   g_object_class_install_property (object_class, PROP_PRECISION,
                                    g_param_spec_enum ("precision", NULL, NULL,
                                                       GIMP_TYPE_PRECISION,
-                                                      GIMP_PRECISION_U8,
+                                                      GIMP_PRECISION_U8_GAMMA,
                                                       GIMP_PARAM_READWRITE |
                                                       G_PARAM_CONSTRUCT));
 
@@ -632,7 +632,7 @@ gimp_image_init (GimpImage *image)
   private->yresolution         = 1.0;
   private->resolution_unit     = GIMP_UNIT_INCH;
   private->base_type           = GIMP_RGB;
-  private->precision           = GIMP_PRECISION_U8;
+  private->precision           = GIMP_PRECISION_U8_GAMMA;
 
   private->colormap            = NULL;
   private->n_colors            = 0;
@@ -1456,7 +1456,7 @@ gimp_image_new (Gimp              *gimp,
 {
   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
   g_return_val_if_fail (base_type != GIMP_INDEXED ||
-                        precision == GIMP_PRECISION_U8, NULL);
+                        precision == GIMP_PRECISION_U8_GAMMA, NULL);
 
   return g_object_new (GIMP_TYPE_IMAGE,
                        "gimp",      gimp,
@@ -1475,6 +1475,14 @@ gimp_image_get_base_type (const GimpImage *image)
   return GIMP_IMAGE_GET_PRIVATE (image)->base_type;
 }
 
+GimpComponentType
+gimp_image_get_component_type (const GimpImage *image)
+{
+  g_return_val_if_fail (GIMP_IS_IMAGE (image), -1);
+
+  return gimp_babl_component_type (GIMP_IMAGE_GET_PRIVATE (image)->precision);
+}
+
 GimpPrecision
 gimp_image_get_precision (const GimpImage *image)
 {
@@ -1498,7 +1506,7 @@ gimp_image_get_format (const GimpImage   *image,
       return gimp_babl_format (base_type, precision, with_alpha);
 
     case GIMP_INDEXED:
-      if (precision == GIMP_PRECISION_U8)
+      if (precision == GIMP_PRECISION_U8_GAMMA)
         {
           if (with_alpha)
             return gimp_image_colormap_get_rgba_format (image);
diff --git a/app/core/gimpimage.h b/app/core/gimpimage.h
index cac48cf..3cd6a1e 100644
--- a/app/core/gimpimage.h
+++ b/app/core/gimpimage.h
@@ -111,6 +111,7 @@ GimpImage     * gimp_image_new                   (Gimp               *gimp,
                                                   GimpPrecision       precision);
 
 GimpImageBaseType  gimp_image_get_base_type      (const GimpImage    *image);
+GimpComponentType  gimp_image_get_component_type (const GimpImage    *image);
 GimpPrecision      gimp_image_get_precision      (const GimpImage    *image);
 
 const Babl    * gimp_image_get_format            (const GimpImage    *image,
diff --git a/app/core/gimptemplate.c b/app/core/gimptemplate.c
index adb6d09..a11427f 100644
--- a/app/core/gimptemplate.c
+++ b/app/core/gimptemplate.c
@@ -162,7 +162,7 @@ gimp_template_class_init (GimpTemplateClass *klass)
   GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_PRECISION,
                                  "precision",
                                  NULL,
-                                 GIMP_TYPE_PRECISION, GIMP_PRECISION_U8,
+                                 GIMP_TYPE_PRECISION, GIMP_PRECISION_U8_GAMMA,
                                  GIMP_PARAM_STATIC_STRINGS);
 
   GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_FILL_TYPE,
@@ -461,7 +461,7 @@ gimp_template_get_base_type (GimpTemplate *template)
 GimpPrecision
 gimp_template_get_precision (GimpTemplate *template)
 {
-  g_return_val_if_fail (GIMP_IS_TEMPLATE (template), GIMP_PRECISION_U8);
+  g_return_val_if_fail (GIMP_IS_TEMPLATE (template), GIMP_PRECISION_U8_GAMMA);
 
   return GET_PRIVATE (template)->precision;
 }
diff --git a/app/file/file-open.c b/app/file/file-open.c
index 781baeb..fde3774 100644
--- a/app/file/file-open.c
+++ b/app/file/file-open.c
@@ -334,22 +334,26 @@ file_open_thumbnail (Gimp           *gimp,
                   switch (value)
                     {
                     case GIMP_RGB_IMAGE:
-                      *format = gimp_babl_format (GIMP_RGB, GIMP_PRECISION_U8,
+                      *format = gimp_babl_format (GIMP_RGB,
+                                                  GIMP_PRECISION_U8_GAMMA,
                                                   FALSE);
                       break;
 
                     case GIMP_RGBA_IMAGE:
-                      *format = gimp_babl_format (GIMP_RGB, GIMP_PRECISION_U8,
+                      *format = gimp_babl_format (GIMP_RGB,
+                                                  GIMP_PRECISION_U8_GAMMA,
                                                   TRUE);
                       break;
 
                     case GIMP_GRAY_IMAGE:
-                      *format = gimp_babl_format (GIMP_GRAY, GIMP_PRECISION_U8,
+                      *format = gimp_babl_format (GIMP_GRAY,
+                                                  GIMP_PRECISION_U8_GAMMA,
                                                   FALSE);
                       break;
 
                     case GIMP_GRAYA_IMAGE:
-                      *format = gimp_babl_format (GIMP_GRAY, GIMP_PRECISION_U8,
+                      *format = gimp_babl_format (GIMP_GRAY,
+                                                  GIMP_PRECISION_U8_GAMMA,
                                                   TRUE);
                       break;
 
diff --git a/app/gegl/gimp-babl-compat.c b/app/gegl/gimp-babl-compat.c
index c820d1f..4c58ce1 100644
--- a/app/gegl/gimp-babl-compat.c
+++ b/app/gegl/gimp-babl-compat.c
@@ -78,6 +78,6 @@ gimp_babl_compat_u8_format (const Babl *format)
     return format;
 
   return gimp_babl_format (gimp_babl_format_get_base_type (format),
-                           GIMP_PRECISION_U8,
+                           GIMP_PRECISION_U8_GAMMA,
                            babl_format_has_alpha (format));
 }
diff --git a/app/gegl/gimp-babl.c b/app/gegl/gimp-babl.c
index 197da4f..8284571 100644
--- a/app/gegl/gimp-babl.c
+++ b/app/gegl/gimp-babl.c
@@ -32,44 +32,74 @@
 void
 gimp_babl_init (void)
 {
+  babl_format_new ("name", "R u8",
+                   babl_model ("RGBA"),
+                   babl_type ("u8"),
+                   babl_component ("R"),
+                   NULL);
   babl_format_new ("name", "R' u8",
                    babl_model ("R'G'B'A"),
                    babl_type ("u8"),
                    babl_component ("R'"),
                    NULL);
+  babl_format_new ("name", "G u8",
+                   babl_model ("RGBA"),
+                   babl_type ("u8"),
+                   babl_component ("G"),
+                   NULL);
   babl_format_new ("name", "G' u8",
                    babl_model ("R'G'B'A"),
                    babl_type ("u8"),
                    babl_component ("G'"),
                    NULL);
+  babl_format_new ("name", "B u8",
+                   babl_model ("RGBA"),
+                   babl_type ("u8"),
+                   babl_component ("B"),
+                   NULL);
   babl_format_new ("name", "B' u8",
                    babl_model ("R'G'B'A"),
                    babl_type ("u8"),
                    babl_component ("B'"),
                    NULL);
   babl_format_new ("name", "A u8",
-                   babl_model ("R'G'B'A"),
+                   babl_model ("RGBA"),
                    babl_type ("u8"),
                    babl_component ("A"),
                    NULL);
 
+  babl_format_new ("name", "R u16",
+                   babl_model ("RGBA"),
+                   babl_type ("u16"),
+                   babl_component ("R"),
+                   NULL);
   babl_format_new ("name", "R' u16",
                    babl_model ("R'G'B'A"),
                    babl_type ("u16"),
                    babl_component ("R'"),
                    NULL);
+  babl_format_new ("name", "G u16",
+                   babl_model ("RGBA"),
+                   babl_type ("u16"),
+                   babl_component ("G"),
+                   NULL);
   babl_format_new ("name", "G' u16",
                    babl_model ("R'G'B'A"),
                    babl_type ("u16"),
                    babl_component ("G'"),
                    NULL);
+  babl_format_new ("name", "B u16",
+                   babl_model ("RGBA"),
+                   babl_type ("u16"),
+                   babl_component ("B"),
+                   NULL);
   babl_format_new ("name", "B' u16",
                    babl_model ("R'G'B'A"),
                    babl_type ("u16"),
                    babl_component ("B'"),
                    NULL);
   babl_format_new ("name", "A u16",
-                   babl_model ("R'G'B'A"),
+                   babl_model ("RGBA"),
                    babl_type ("u16"),
                    babl_component ("A"),
                    NULL);
@@ -79,16 +109,31 @@ gimp_babl_init (void)
                    babl_type ("u32"),
                    babl_component ("R"),
                    NULL);
+  babl_format_new ("name", "R' u32",
+                   babl_model ("R'G'B'A"),
+                   babl_type ("u32"),
+                   babl_component ("R'"),
+                   NULL);
   babl_format_new ("name", "G u32",
                    babl_model ("RGBA"),
                    babl_type ("u32"),
                    babl_component ("G"),
                    NULL);
+  babl_format_new ("name", "G' u32",
+                   babl_model ("R'G'B'A"),
+                   babl_type ("u32"),
+                   babl_component ("G'"),
+                   NULL);
   babl_format_new ("name", "B u32",
                    babl_model ("RGBA"),
                    babl_type ("u32"),
                    babl_component ("B"),
                    NULL);
+  babl_format_new ("name", "B' u32",
+                   babl_model ("R'G'B'A"),
+                   babl_type ("u32"),
+                   babl_component ("B'"),
+                   NULL);
   babl_format_new ("name", "A u32",
                    babl_model ("RGBA"),
                    babl_type ("u32"),
@@ -100,16 +145,31 @@ gimp_babl_init (void)
                    babl_type ("half"),
                    babl_component ("R"),
                    NULL);
+  babl_format_new ("name", "R' half",
+                   babl_model ("R'G'B'A"),
+                   babl_type ("half"),
+                   babl_component ("R'"),
+                   NULL);
   babl_format_new ("name", "G half",
                    babl_model ("RGBA"),
                    babl_type ("half"),
                    babl_component ("G"),
                    NULL);
+  babl_format_new ("name", "G' half",
+                   babl_model ("R'G'B'A"),
+                   babl_type ("half"),
+                   babl_component ("G'"),
+                   NULL);
   babl_format_new ("name", "B half",
                    babl_model ("RGBA"),
                    babl_type ("half"),
                    babl_component ("B"),
                    NULL);
+  babl_format_new ("name", "B' half",
+                   babl_model ("R'G'B'A"),
+                   babl_type ("half"),
+                   babl_component ("B'"),
+                   NULL);
   babl_format_new ("name", "A half",
                    babl_model ("RGBA"),
                    babl_type ("half"),
@@ -121,16 +181,31 @@ gimp_babl_init (void)
                    babl_type ("float"),
                    babl_component ("R"),
                    NULL);
+  babl_format_new ("name", "R' float",
+                   babl_model ("R'G'B'A"),
+                   babl_type ("float"),
+                   babl_component ("R'"),
+                   NULL);
   babl_format_new ("name", "G float",
                    babl_model ("RGBA"),
                    babl_type ("float"),
                    babl_component ("G"),
                    NULL);
+  babl_format_new ("name", "G' float",
+                   babl_model ("R'G'B'A"),
+                   babl_type ("float"),
+                   babl_component ("G'"),
+                   NULL);
   babl_format_new ("name", "B float",
                    babl_model ("RGBA"),
                    babl_type ("float"),
                    babl_component ("B"),
                    NULL);
+  babl_format_new ("name", "B' float",
+                   babl_model ("R'G'B'A"),
+                   babl_type ("float"),
+                   babl_component ("B'"),
+                   NULL);
   babl_format_new ("name", "A float",
                    babl_model ("RGBA"),
                    babl_type ("float"),
@@ -151,56 +226,89 @@ static const struct
 }
 babl_descriptions[] =
 {
-  { "R'G'B' u8",  N_("RGB") },
-  { "R'G'B' u16", N_("RGB") },
-  { "RGB u32",    N_("RGB") },
-  { "RGB half",   N_("RGB") },
-  { "RGB float",  N_("RGB") },
-
-  { "R'G'B'A u8", N_("RGB-alpha") },
-  { "R'G'B'A u16",N_("RGB-alpha") },
-  { "RGBA u32",   N_("RGB-alpha") },
-  { "RGBA half",  N_("RGB-alpha") },
-  { "RGBA float", N_("RGB-alpha") },
-
-  { "Y' u8",      N_("Grayscale") },
-  { "Y u8",       N_("Grayscale") },
-  { "Y' u16",     N_("Grayscale") },
-  { "Y u16",      N_("Grayscale") },
-  { "Y u32",      N_("Grayscale") },
-  { "Y half",     N_("Grayscale") },
-  { "Y float",    N_("Grayscale") },
-
-  { "Y'A u8",     N_("Grayscale-alpha") },
-  { "Y'A u16",    N_("Grayscale-alpha") },
-  { "YA u32",     N_("Grayscale-alpha") },
-  { "YA half",    N_("Grayscale-alpha") },
-  { "YA float",   N_("Grayscale-alpha") },
-
-  { "R' u8",      N_("Red component") },
-  { "R' u16",     N_("Red component") },
-  { "R u32",      N_("Red component") },
-  { "R half",     N_("Red component") },
-  { "R float",    N_("Red component") },
-
-  { "G' u8",      N_("Green component") },
-  { "G' u16",     N_("Green component") },
-  { "G u32",      N_("Green component") },
-  { "G half",     N_("Green component") },
-  { "G float",    N_("Green component") },
-
-  { "B' u8",      N_("Blue component") },
-  { "B' u16",     N_("Blue component") },
-  { "B u32",      N_("Blue component") },
-  { "B half",     N_("Blue component") },
-  { "B float",    N_("Blue component") },
-
-  { "A u8",       N_("Alpha component") },
-  { "A u16",      N_("Alpha component") },
-  { "A u32",      N_("Alpha component") },
-  { "A half",     N_("Alpha component") },
-  { "A float",    N_("Alpha component") },
-  { "A double",   N_("Alpha component") }
+  { "RGB u8",        N_("RGB") },
+  { "R'G'B' u8",     N_("RGB") },
+  { "RGB u16",       N_("RGB") },
+  { "R'G'B' u16",    N_("RGB") },
+  { "RGB u32",       N_("RGB") },
+  { "R'G'B' u32",    N_("RGB") },
+  { "RGB half",      N_("RGB") },
+  { "R'G'B' half",   N_("RGB") },
+  { "RGB float",     N_("RGB") },
+  { "R'G'B' float",  N_("RGB") },
+
+  { "RGBA u8",       N_("RGB-alpha") },
+  { "R'G'B'A u8",    N_("RGB-alpha") },
+  { "RGBA u16",      N_("RGB-alpha") },
+  { "R'G'B'A u16",   N_("RGB-alpha") },
+  { "RGBA u32",      N_("RGB-alpha") },
+  { "R'G'B'A u32",   N_("RGB-alpha") },
+  { "RGBA half",     N_("RGB-alpha") },
+  { "R'G'B'A half",  N_("RGB-alpha") },
+  { "RGBA float",    N_("RGB-alpha") },
+  { "R'G'B'A float", N_("RGB-alpha") },
+
+  { "Y u8",          N_("Grayscale") },
+  { "Y' u8",         N_("Grayscale") },
+  { "Y u16",         N_("Grayscale") },
+  { "Y' u16",        N_("Grayscale") },
+  { "Y u32",         N_("Grayscale") },
+  { "Y' u32",        N_("Grayscale") },
+  { "Y half",        N_("Grayscale") },
+  { "Y' half",       N_("Grayscale") },
+  { "Y float",       N_("Grayscale") },
+  { "Y' float",      N_("Grayscale") },
+
+  { "YA u8",         N_("Grayscale-alpha") },
+  { "Y'A u8",        N_("Grayscale-alpha") },
+  { "YA u16",        N_("Grayscale-alpha") },
+  { "Y'A u16",       N_("Grayscale-alpha") },
+  { "YA u32",        N_("Grayscale-alpha") },
+  { "Y'A u32",       N_("Grayscale-alpha") },
+  { "YA half",       N_("Grayscale-alpha") },
+  { "Y'A half",      N_("Grayscale-alpha") },
+  { "YA float",      N_("Grayscale-alpha") },
+  { "Y'A float",     N_("Grayscale-alpha") },
+
+  { "R u8",          N_("Red component") },
+  { "R' u8",         N_("Red component") },
+  { "R u16",         N_("Red component") },
+  { "R' u16",        N_("Red component") },
+  { "R u32",         N_("Red component") },
+  { "R' u32",        N_("Red component") },
+  { "R half",        N_("Red component") },
+  { "R' half",       N_("Red component") },
+  { "R float",       N_("Red component") },
+  { "R' float",      N_("Red component") },
+
+  { "G u8",          N_("Green component") },
+  { "G' u8",         N_("Green component") },
+  { "G u16",         N_("Green component") },
+  { "G' u16",        N_("Green component") },
+  { "G u32",         N_("Green component") },
+  { "G' u32",        N_("Green component") },
+  { "G half",        N_("Green component") },
+  { "G' half",       N_("Green component") },
+  { "G float",       N_("Green component") },
+  { "G' float",      N_("Green component") },
+
+  { "B u8",          N_("Blue component") },
+  { "B' u8",         N_("Blue component") },
+  { "B u16",         N_("Blue component") },
+  { "B' u16",        N_("Blue component") },
+  { "B u32",         N_("Blue component") },
+  { "B' u32",        N_("Blue component") },
+  { "B half",        N_("Blue component") },
+  { "B' half",       N_("Blue component") },
+  { "B float",       N_("Blue component") },
+  { "B' float",      N_("Blue component") },
+
+  { "A u8",          N_("Alpha component") },
+  { "A u16",         N_("Alpha component") },
+  { "A u32",         N_("Alpha component") },
+  { "A half",        N_("Alpha component") },
+  { "A float",       N_("Alpha component") },
+  { "A double",      N_("Alpha component") }
 };
 
 static GHashTable *babl_description_hash = NULL;
@@ -274,8 +382,8 @@ gimp_babl_format_get_base_type (const Babl *format)
   g_return_val_if_reached (-1);
 }
 
-GimpPrecision
-gimp_babl_format_get_precision (const Babl *format)
+GimpComponentType
+gimp_babl_format_get_component_type (const Babl *format)
 {
   const Babl *type;
 
@@ -284,15 +392,54 @@ gimp_babl_format_get_precision (const Babl *format)
   type = babl_format_get_type (format, 0);
 
   if (type == babl_type ("u8"))
-    return GIMP_PRECISION_U8;
+    return GIMP_COMPONENT_TYPE_U8;
   else if (type == babl_type ("u16"))
-    return GIMP_PRECISION_U16;
+    return GIMP_COMPONENT_TYPE_U16;
   else if (type == babl_type ("u32"))
-    return GIMP_PRECISION_U32;
+    return GIMP_COMPONENT_TYPE_U32;
   else if (type == babl_type ("half"))
-    return GIMP_PRECISION_HALF;
+    return GIMP_COMPONENT_TYPE_HALF;
   else if (type == babl_type ("float"))
-    return GIMP_PRECISION_FLOAT;
+    return GIMP_COMPONENT_TYPE_FLOAT;
+
+  g_return_val_if_reached (-1);
+}
+
+GimpPrecision
+gimp_babl_format_get_precision (const Babl *format)
+{
+  const Babl *type;
+
+  g_return_val_if_fail (format != NULL, -1);
+
+  type = babl_format_get_type (format, 0);
+
+  if (gimp_babl_format_get_linear (format))
+    {
+      if (type == babl_type ("u8"))
+        return GIMP_PRECISION_U8_LINEAR;
+      else if (type == babl_type ("u16"))
+        return GIMP_PRECISION_U16_LINEAR;
+      else if (type == babl_type ("u32"))
+        return GIMP_PRECISION_U32_LINEAR;
+      else if (type == babl_type ("half"))
+        return GIMP_PRECISION_HALF_LINEAR;
+      else if (type == babl_type ("float"))
+        return GIMP_PRECISION_FLOAT_LINEAR;
+    }
+  else
+    {
+      if (type == babl_type ("u8"))
+        return GIMP_PRECISION_U8_GAMMA;
+      else if (type == babl_type ("u16"))
+        return GIMP_PRECISION_U16_GAMMA;
+      else if (type == babl_type ("u32"))
+        return GIMP_PRECISION_U32_GAMMA;
+      else if (type == babl_type ("half"))
+        return GIMP_PRECISION_HALF_GAMMA;
+      else if (type == babl_type ("float"))
+        return GIMP_PRECISION_FLOAT_GAMMA;
+    }
 
   g_return_val_if_reached (-1);
 }
@@ -328,6 +475,78 @@ gimp_babl_format_get_linear (const Babl *format)
   g_return_val_if_reached (FALSE);
 }
 
+GimpComponentType
+gimp_babl_component_type (GimpPrecision precision)
+{
+  switch (precision)
+    {
+    case GIMP_PRECISION_U8_LINEAR:
+    case GIMP_PRECISION_U8_GAMMA:
+      return GIMP_COMPONENT_TYPE_U8;
+
+    case GIMP_PRECISION_U16_LINEAR:
+    case GIMP_PRECISION_U16_GAMMA:
+      return GIMP_COMPONENT_TYPE_U16;
+
+    case GIMP_PRECISION_U32_LINEAR:
+    case GIMP_PRECISION_U32_GAMMA:
+      return GIMP_COMPONENT_TYPE_U32;
+
+    case GIMP_PRECISION_HALF_LINEAR:
+    case GIMP_PRECISION_HALF_GAMMA:
+      return GIMP_COMPONENT_TYPE_HALF;
+
+    case GIMP_PRECISION_FLOAT_LINEAR:
+    case GIMP_PRECISION_FLOAT_GAMMA:
+      return GIMP_COMPONENT_TYPE_FLOAT;
+    }
+
+  g_return_val_if_reached (-1);
+}
+
+GimpPrecision
+gimp_babl_precision (GimpComponentType component,
+                     gboolean          linear)
+{
+  switch (component)
+    {
+    case GIMP_COMPONENT_TYPE_U8:
+      if (linear)
+        return GIMP_PRECISION_U8_LINEAR;
+      else
+        return GIMP_PRECISION_U8_GAMMA;
+
+    case GIMP_COMPONENT_TYPE_U16:
+      if (linear)
+        return GIMP_PRECISION_U16_LINEAR;
+      else
+        return GIMP_PRECISION_U16_GAMMA;
+
+    case GIMP_COMPONENT_TYPE_U32:
+      if (linear)
+         return GIMP_PRECISION_U32_LINEAR;
+      else
+        return GIMP_PRECISION_U32_GAMMA;
+
+    case GIMP_COMPONENT_TYPE_HALF:
+      if (linear)
+        return GIMP_PRECISION_HALF_LINEAR;
+      else
+        return GIMP_PRECISION_HALF_GAMMA;
+
+    case GIMP_COMPONENT_TYPE_FLOAT:
+      if (linear)
+        return GIMP_PRECISION_FLOAT_LINEAR;
+      else
+        return GIMP_PRECISION_FLOAT_GAMMA;
+
+    default:
+      break;
+    }
+
+  g_return_val_if_reached (-1);
+}
+
 const Babl *
 gimp_babl_format (GimpImageBaseType  base_type,
                   GimpPrecision      precision,
@@ -338,36 +557,66 @@ gimp_babl_format (GimpImageBaseType  base_type,
     case GIMP_RGB:
       switch (precision)
         {
-        case GIMP_PRECISION_U8:
+        case GIMP_PRECISION_U8_LINEAR:
+          if (with_alpha)
+            return babl_format ("RGBA u8");
+          else
+            return babl_format ("RGB u8");
+
+        case GIMP_PRECISION_U8_GAMMA:
           if (with_alpha)
             return babl_format ("R'G'B'A u8");
           else
             return babl_format ("R'G'B' u8");
 
-        case GIMP_PRECISION_U16:
+        case GIMP_PRECISION_U16_LINEAR:
+          if (with_alpha)
+            return babl_format ("RGBA u16");
+          else
+            return babl_format ("RGB u16");
+
+        case GIMP_PRECISION_U16_GAMMA:
           if (with_alpha)
             return babl_format ("R'G'B'A u16");
           else
             return babl_format ("R'G'B' u16");
 
-        case GIMP_PRECISION_U32:
+        case GIMP_PRECISION_U32_LINEAR:
           if (with_alpha)
             return babl_format ("RGBA u32");
           else
             return babl_format ("RGB u32");
 
-        case GIMP_PRECISION_HALF:
+        case GIMP_PRECISION_U32_GAMMA:
+          if (with_alpha)
+            return babl_format ("R'G'B'A u32");
+          else
+            return babl_format ("R'G'B' u32");
+
+        case GIMP_PRECISION_HALF_LINEAR:
           if (with_alpha)
             return babl_format ("RGBA half");
           else
             return babl_format ("RGB half");
 
-        case GIMP_PRECISION_FLOAT:
+        case GIMP_PRECISION_HALF_GAMMA:
+          if (with_alpha)
+            return babl_format ("R'G'B'A half");
+          else
+            return babl_format ("R'G'B' half");
+
+        case GIMP_PRECISION_FLOAT_LINEAR:
           if (with_alpha)
             return babl_format ("RGBA float");
           else
             return babl_format ("RGB float");
 
+        case GIMP_PRECISION_FLOAT_GAMMA:
+          if (with_alpha)
+            return babl_format ("R'G'B'A float");
+          else
+            return babl_format ("R'G'B' float");
+
         default:
           break;
         }
@@ -376,36 +625,66 @@ gimp_babl_format (GimpImageBaseType  base_type,
     case GIMP_GRAY:
       switch (precision)
         {
-        case GIMP_PRECISION_U8:
+        case GIMP_PRECISION_U8_LINEAR:
+          if (with_alpha)
+            return babl_format ("YA u8");
+          else
+            return babl_format ("Y u8");
+
+        case GIMP_PRECISION_U8_GAMMA:
           if (with_alpha)
             return babl_format ("Y'A u8");
           else
             return babl_format ("Y' u8");
 
-        case GIMP_PRECISION_U16:
+        case GIMP_PRECISION_U16_LINEAR:
+          if (with_alpha)
+            return babl_format ("YA u16");
+          else
+            return babl_format ("Y u16");
+
+        case GIMP_PRECISION_U16_GAMMA:
           if (with_alpha)
             return babl_format ("Y'A u16");
           else
             return babl_format ("Y' u16");
 
-        case GIMP_PRECISION_U32:
+        case GIMP_PRECISION_U32_LINEAR:
           if (with_alpha)
             return babl_format ("YA u32");
           else
             return babl_format ("Y u32");
 
-        case GIMP_PRECISION_HALF:
+        case GIMP_PRECISION_U32_GAMMA:
+          if (with_alpha)
+            return babl_format ("Y'A u32");
+          else
+            return babl_format ("Y' u32");
+
+        case GIMP_PRECISION_HALF_LINEAR:
           if (with_alpha)
             return babl_format ("YA half");
           else
             return babl_format ("Y half");
 
-        case GIMP_PRECISION_FLOAT:
+        case GIMP_PRECISION_HALF_GAMMA:
+          if (with_alpha)
+            return babl_format ("Y'A half");
+          else
+            return babl_format ("Y' half");
+
+        case GIMP_PRECISION_FLOAT_LINEAR:
           if (with_alpha)
             return babl_format ("YA float");
           else
             return babl_format ("Y float");
 
+        case GIMP_PRECISION_FLOAT_GAMMA:
+          if (with_alpha)
+            return babl_format ("Y'A float");
+          else
+            return babl_format ("Y' float");
+
         default:
           break;
         }
@@ -422,13 +701,13 @@ gimp_babl_format (GimpImageBaseType  base_type,
 const Babl *
 gimp_babl_mask_format (GimpPrecision precision)
 {
-  switch (precision)
+  switch (gimp_babl_component_type (precision))
     {
-    case GIMP_PRECISION_U8:    return babl_format ("Y u8");
-    case GIMP_PRECISION_U16:   return babl_format ("Y u16");
-    case GIMP_PRECISION_U32:   return babl_format ("Y u32");
-    case GIMP_PRECISION_HALF:  return babl_format ("Y half");
-    case GIMP_PRECISION_FLOAT: return babl_format ("Y float");
+    case GIMP_COMPONENT_TYPE_U8:    return babl_format ("Y u8");
+    case GIMP_COMPONENT_TYPE_U16:   return babl_format ("Y u16");
+    case GIMP_COMPONENT_TYPE_U32:   return babl_format ("Y u32");
+    case GIMP_COMPONENT_TYPE_HALF:  return babl_format ("Y half");
+    case GIMP_COMPONENT_TYPE_FLOAT: return babl_format ("Y float");
     }
 
   g_return_val_if_reached (NULL);
@@ -444,7 +723,19 @@ gimp_babl_component_format (GimpImageBaseType base_type,
     case GIMP_RGB:
       switch (precision)
         {
-        case GIMP_PRECISION_U8:
+        case GIMP_PRECISION_U8_LINEAR:
+          switch (index)
+            {
+            case 0: return babl_format ("R u8");
+            case 1: return babl_format ("G u8");
+            case 2: return babl_format ("B u8");
+            case 3: return babl_format ("A u8");
+            default:
+              break;
+            }
+          break;
+
+        case GIMP_PRECISION_U8_GAMMA:
           switch (index)
             {
             case 0: return babl_format ("R' u8");
@@ -456,7 +747,19 @@ gimp_babl_component_format (GimpImageBaseType base_type,
             }
           break;
 
-        case GIMP_PRECISION_U16:
+        case GIMP_PRECISION_U16_LINEAR:
+          switch (index)
+            {
+            case 0: return babl_format ("R u16");
+            case 1: return babl_format ("G u16");
+            case 2: return babl_format ("B u16");
+            case 3: return babl_format ("A u16");
+            default:
+              break;
+            }
+          break;
+
+        case GIMP_PRECISION_U16_GAMMA:
           switch (index)
             {
             case 0: return babl_format ("R' u16");
@@ -468,7 +771,7 @@ gimp_babl_component_format (GimpImageBaseType base_type,
             }
           break;
 
-        case GIMP_PRECISION_U32:
+        case GIMP_PRECISION_U32_LINEAR:
           switch (index)
             {
             case 0: return babl_format ("R u32");
@@ -480,7 +783,19 @@ gimp_babl_component_format (GimpImageBaseType base_type,
             }
           break;
 
-        case GIMP_PRECISION_HALF:
+        case GIMP_PRECISION_U32_GAMMA:
+          switch (index)
+            {
+            case 0: return babl_format ("R' u32");
+            case 1: return babl_format ("G' u32");
+            case 2: return babl_format ("B' u32");
+            case 3: return babl_format ("A u32");
+            default:
+              break;
+            }
+          break;
+
+        case GIMP_PRECISION_HALF_LINEAR:
           switch (index)
             {
             case 0: return babl_format ("R half");
@@ -492,7 +807,19 @@ gimp_babl_component_format (GimpImageBaseType base_type,
             }
           break;
 
-        case GIMP_PRECISION_FLOAT:
+        case GIMP_PRECISION_HALF_GAMMA:
+          switch (index)
+            {
+            case 0: return babl_format ("R' half");
+            case 1: return babl_format ("G' half");
+            case 2: return babl_format ("B' half");
+            case 3: return babl_format ("A half");
+            default:
+              break;
+            }
+          break;
+
+        case GIMP_PRECISION_FLOAT_LINEAR:
           switch (index)
             {
             case 0: return babl_format ("R float");
@@ -504,6 +831,18 @@ gimp_babl_component_format (GimpImageBaseType base_type,
             }
           break;
 
+        case GIMP_PRECISION_FLOAT_GAMMA:
+          switch (index)
+            {
+            case 0: return babl_format ("R' float");
+            case 1: return babl_format ("G' float");
+            case 2: return babl_format ("B' float");
+            case 3: return babl_format ("A float");
+            default:
+              break;
+            }
+          break;
+
         default:
           break;
         }
@@ -512,7 +851,17 @@ gimp_babl_component_format (GimpImageBaseType base_type,
     case GIMP_GRAY:
       switch (precision)
         {
-        case GIMP_PRECISION_U8:
+        case GIMP_PRECISION_U8_LINEAR:
+          switch (index)
+            {
+            case 0: return babl_format ("Y u8");
+            case 1: return babl_format ("A u8");
+            default:
+              break;
+            }
+          break;
+
+        case GIMP_PRECISION_U8_GAMMA:
           switch (index)
             {
             case 0: return babl_format ("Y' u8");
@@ -522,7 +871,17 @@ gimp_babl_component_format (GimpImageBaseType base_type,
             }
           break;
 
-        case GIMP_PRECISION_U16:
+        case GIMP_PRECISION_U16_LINEAR:
+          switch (index)
+            {
+            case 0: return babl_format ("Y u16");
+            case 1: return babl_format ("A u16");
+            default:
+              break;
+            }
+          break;
+
+        case GIMP_PRECISION_U16_GAMMA:
           switch (index)
             {
             case 0: return babl_format ("Y' u16");
@@ -532,7 +891,7 @@ gimp_babl_component_format (GimpImageBaseType base_type,
             }
           break;
 
-        case GIMP_PRECISION_U32:
+        case GIMP_PRECISION_U32_LINEAR:
           switch (index)
             {
             case 0: return babl_format ("Y u32");
@@ -542,7 +901,17 @@ gimp_babl_component_format (GimpImageBaseType base_type,
             }
           break;
 
-        case GIMP_PRECISION_HALF:
+        case GIMP_PRECISION_U32_GAMMA:
+          switch (index)
+            {
+            case 0: return babl_format ("Y' u32");
+            case 1: return babl_format ("A u32");
+            default:
+              break;
+            }
+          break;
+
+        case GIMP_PRECISION_HALF_LINEAR:
           switch (index)
             {
             case 0: return babl_format ("Y half");
@@ -552,7 +921,17 @@ gimp_babl_component_format (GimpImageBaseType base_type,
             }
           break;
 
-        case GIMP_PRECISION_FLOAT:
+        case GIMP_PRECISION_HALF_GAMMA:
+          switch (index)
+            {
+            case 0: return babl_format ("Y' half");
+            case 1: return babl_format ("A half");
+            default:
+              break;
+            }
+          break;
+
+        case GIMP_PRECISION_FLOAT_LINEAR:
           switch (index)
             {
             case 0: return babl_format ("Y float");
@@ -562,6 +941,16 @@ gimp_babl_component_format (GimpImageBaseType base_type,
             }
           break;
 
+        case GIMP_PRECISION_FLOAT_GAMMA:
+          switch (index)
+            {
+            case 0: return babl_format ("Y' float");
+            case 1: return babl_format ("A float");
+            default:
+              break;
+            }
+          break;
+
         default:
           break;
         }
@@ -604,9 +993,9 @@ gimp_babl_print_pixel (const Babl *format,
 
   strings = g_new0 (gchar *, n_components + 1);
 
-  switch (gimp_babl_format_get_precision (format))
+  switch (gimp_babl_format_get_component_type (format))
     {
-    case GIMP_PRECISION_U8:
+    case GIMP_COMPONENT_TYPE_U8:
       {
         guchar *color = pixel;
         gint    i;
@@ -616,7 +1005,7 @@ gimp_babl_print_pixel (const Babl *format,
       }
       break;
 
-    case GIMP_PRECISION_U16:
+    case GIMP_COMPONENT_TYPE_U16:
       {
         guint16 *color = pixel;
         gint     i;
@@ -626,7 +1015,7 @@ gimp_babl_print_pixel (const Babl *format,
       }
       break;
 
-    case GIMP_PRECISION_U32:
+    case GIMP_COMPONENT_TYPE_U32:
       {
         guint32 *color = pixel;
         gint     i;
@@ -636,11 +1025,17 @@ gimp_babl_print_pixel (const Babl *format,
       }
       break;
 
-    case GIMP_PRECISION_HALF:
+    case GIMP_COMPONENT_TYPE_HALF:
       {
-        const Babl *f = gimp_babl_format (gimp_babl_format_get_base_type (format),
-                                          GIMP_PRECISION_FLOAT,
-                                          babl_format_has_alpha (format));
+        GimpPrecision p;
+        const Babl   *f;
+
+        p = gimp_babl_precision (GIMP_COMPONENT_TYPE_FLOAT,
+                                 gimp_babl_format_get_linear (format));
+
+        f = gimp_babl_format (gimp_babl_format_get_base_type (format),
+                              p,
+                              babl_format_has_alpha (format));
 
         babl_process (babl_fish (format, f), pixel, tmp_pixel, 1);
 
@@ -648,7 +1043,7 @@ gimp_babl_print_pixel (const Babl *format,
       }
       /* fall through */
 
-    case GIMP_PRECISION_FLOAT:
+    case GIMP_COMPONENT_TYPE_FLOAT:
       {
         gfloat *color = pixel;
         gint    i;
diff --git a/app/gegl/gimp-babl.h b/app/gegl/gimp-babl.h
index 82027f3..6244848 100644
--- a/app/gegl/gimp-babl.h
+++ b/app/gegl/gimp-babl.h
@@ -22,25 +22,29 @@
 #define __GIMP_BABL_H__
 
 
-void                gimp_babl_init                  (void);
+void                gimp_babl_init                      (void);
 
-const gchar       * gimp_babl_get_description       (const Babl        *babl);
+const gchar       * gimp_babl_get_description           (const Babl *format);
 
-GimpImageBaseType   gimp_babl_format_get_base_type  (const Babl        *format);
-GimpPrecision       gimp_babl_format_get_precision  (const Babl        *format);
-gboolean            gimp_babl_format_get_linear     (const Babl        *format);
+GimpImageBaseType   gimp_babl_format_get_base_type      (const Babl *format);
+GimpComponentType   gimp_babl_format_get_component_type (const Babl *format);
+GimpPrecision       gimp_babl_format_get_precision      (const Babl *format);
+gboolean            gimp_babl_format_get_linear         (const Babl *format);
 
+GimpComponentType   gimp_babl_component_type   (GimpPrecision      precision);
+GimpPrecision       gimp_babl_precision        (GimpComponentType  component,
+                                                gboolean           linear);
 
-const Babl        * gimp_babl_format                (GimpImageBaseType  base_type,
-                                                     GimpPrecision      precision,
-                                                     gboolean           with_alpha);
-const Babl        * gimp_babl_mask_format           (GimpPrecision      precision);
-const Babl        * gimp_babl_component_format      (GimpImageBaseType  base_type,
-                                                     GimpPrecision      precision,
-                                                     gint               index);
+const Babl        * gimp_babl_format           (GimpImageBaseType  base_type,
+                                                GimpPrecision      precision,
+                                                gboolean           with_alpha);
+const Babl        * gimp_babl_mask_format      (GimpPrecision      precision);
+const Babl        * gimp_babl_component_format (GimpImageBaseType  base_type,
+                                                GimpPrecision      precision,
+                                                gint               index);
 
-gchar            ** gimp_babl_print_pixel           (const Babl        *format,
-                                                     gpointer           pixel);
+gchar            ** gimp_babl_print_pixel      (const Babl        *format,
+                                                gpointer           pixel);
 
 
 #endif /* __GIMP_BABL_H__ */
diff --git a/app/gegl/gimp-gegl-loops.c b/app/gegl/gimp-gegl-loops.c
index dd65d6f..2225aa4 100644
--- a/app/gegl/gimp-gegl-loops.c
+++ b/app/gegl/gimp-gegl-loops.c
@@ -52,21 +52,23 @@ gimp_gegl_convolve (GeglBuffer          *src_buffer,
   src_format = gegl_buffer_get_format (src_buffer);
 
   if (babl_format_is_palette (src_format))
-    src_format = gimp_babl_format (GIMP_RGB, GIMP_PRECISION_FLOAT,
+    src_format = gimp_babl_format (GIMP_RGB,
+                                   GIMP_PRECISION_FLOAT_LINEAR,
                                    babl_format_has_alpha (src_format));
   else
     src_format = gimp_babl_format (gimp_babl_format_get_base_type (src_format),
-                                   GIMP_PRECISION_FLOAT,
+                                   GIMP_PRECISION_FLOAT_LINEAR,
                                    babl_format_has_alpha (src_format));
 
   dest_format = gegl_buffer_get_format (dest_buffer);
 
   if (babl_format_is_palette (dest_format))
-    dest_format = gimp_babl_format (GIMP_RGB, GIMP_PRECISION_FLOAT,
+    dest_format = gimp_babl_format (GIMP_RGB,
+                                    GIMP_PRECISION_FLOAT_LINEAR,
                                     babl_format_has_alpha (dest_format));
   else
     dest_format = gimp_babl_format (gimp_babl_format_get_base_type (dest_format),
-                                    GIMP_PRECISION_FLOAT,
+                                    GIMP_PRECISION_FLOAT_LINEAR,
                                     babl_format_has_alpha (dest_format));
 
   src_components  = babl_format_get_n_components (src_format);
diff --git a/app/pdb/convert-cmds.c b/app/pdb/convert-cmds.c
index 24b4f91..9efa81c 100644
--- a/app/pdb/convert-cmds.c
+++ b/app/pdb/convert-cmds.c
@@ -138,7 +138,7 @@ image_convert_indexed_invoker (GimpProcedure         *procedure,
       GimpPalette *pal = NULL;
 
       if (gimp_pdb_image_is_not_base_type (image, GIMP_INDEXED, error) &&
-          gimp_pdb_image_is_precision (image, GIMP_PRECISION_U8, error) &&
+          gimp_pdb_image_is_precision (image, GIMP_PRECISION_U8_GAMMA, error) &&
           gimp_item_stack_is_flat (GIMP_ITEM_STACK (gimp_image_get_layers (image))))
         {
           switch (palette_type)
@@ -437,7 +437,7 @@ register_convert_procs (GimpPDB *pdb)
                                                   "precision",
                                                   "The new precision",
                                                   GIMP_TYPE_PRECISION,
-                                                  GIMP_PRECISION_U8,
+                                                  GIMP_PRECISION_U8_LINEAR,
                                                   GIMP_PARAM_READWRITE));
   gimp_pdb_register_procedure (pdb, procedure);
   g_object_unref (procedure);
diff --git a/app/pdb/image-cmds.c b/app/pdb/image-cmds.c
index 72cf1b0..a07daab 100644
--- a/app/pdb/image-cmds.c
+++ b/app/pdb/image-cmds.c
@@ -160,7 +160,7 @@ image_new_invoker (GimpProcedure         *procedure,
   if (success)
     {
       image = gimp_create_image (gimp, width, height, type,
-                                 GIMP_PRECISION_U8, FALSE);
+                                 GIMP_PRECISION_U8_GAMMA, FALSE);
 
       if (! image)
         success = FALSE;
@@ -201,7 +201,7 @@ image_new_with_precision_invoker (GimpProcedure         *procedure,
       if (gimp->plug_in_manager->current_plug_in)
         gimp_plug_in_enable_precision (gimp->plug_in_manager->current_plug_in);
 
-      if (type != GIMP_INDEXED || precision == GIMP_PRECISION_U8)
+      if (type != GIMP_INDEXED || precision == GIMP_PRECISION_U8_GAMMA)
         {
           image = gimp_create_image (gimp, width, height, type,
                                      precision, FALSE);
@@ -2986,7 +2986,7 @@ register_image_procs (GimpPDB *pdb)
   gimp_procedure_set_static_strings (procedure,
                                      "gimp-image-new-with-precision",
                                      "Creates a new image with the specified width, height, type and 
precision.",
-                                     "Creates a new image, undisplayed with the specified extents, type and 
precision. Indexed images can only be created at GIMP_PRECISION_U8 precision. See 'gimp-image-new' for 
further details.",
+                                     "Creates a new image, undisplayed with the specified extents, type and 
precision. Indexed images can only be created at GIMP_PRECISION_U8_GAMMA precision. See 'gimp-image-new' for 
further details.",
                                      "Michael Natterer <mitch gimp org>",
                                      "Michael Natterer",
                                      "2012",
@@ -3015,7 +3015,7 @@ register_image_procs (GimpPDB *pdb)
                                                   "precision",
                                                   "The precision",
                                                   GIMP_TYPE_PRECISION,
-                                                  GIMP_PRECISION_U8,
+                                                  GIMP_PRECISION_U8_LINEAR,
                                                   GIMP_PARAM_READWRITE));
   gimp_procedure_add_return_value (procedure,
                                    gimp_param_spec_image_id ("image",
@@ -3133,7 +3133,7 @@ register_image_procs (GimpPDB *pdb)
                                                       "precision",
                                                       "The image's precision",
                                                       GIMP_TYPE_PRECISION,
-                                                      GIMP_PRECISION_U8,
+                                                      GIMP_PRECISION_U8_LINEAR,
                                                       GIMP_PARAM_READWRITE));
   gimp_pdb_register_procedure (pdb, procedure);
   g_object_unref (procedure);
diff --git a/app/tests/gimp-app-test-utils.c b/app/tests/gimp-app-test-utils.c
index e289567..962d4ec 100644
--- a/app/tests/gimp-app-test-utils.c
+++ b/app/tests/gimp-app-test-utils.c
@@ -119,7 +119,7 @@ gimp_test_utils_create_image (Gimp *gimp,
   GimpLayer *layer;
 
   image = gimp_image_new (gimp, width, height,
-                          GIMP_RGB, GIMP_PRECISION_U8);
+                          GIMP_RGB, GIMP_PRECISION_U8_GAMMA);
 
   layer = gimp_layer_new (image,
                           width,
diff --git a/app/tools/gimpbrightnesscontrasttool.c b/app/tools/gimpbrightnesscontrasttool.c
index 08b61cd..279b3d7 100644
--- a/app/tools/gimpbrightnesscontrasttool.c
+++ b/app/tools/gimpbrightnesscontrasttool.c
@@ -142,7 +142,7 @@ gimp_brightness_contrast_tool_initialize (GimpTool     *tool,
       return FALSE;
     }
 
-  if (gimp_drawable_get_precision (drawable) == GIMP_PRECISION_U8)
+  if (gimp_drawable_get_component_type (drawable) == GIMP_COMPONENT_TYPE_U8)
     {
       gimp_prop_widget_set_factor (bc_tool->brightness_scale, 127.0, 0);
       gimp_prop_widget_set_factor (bc_tool->contrast_scale,   127.0, 0);
diff --git a/app/tools/gimpcurvestool.c b/app/tools/gimpcurvestool.c
index 73db111..15817d2 100644
--- a/app/tools/gimpcurvestool.c
+++ b/app/tools/gimpcurvestool.c
@@ -218,7 +218,7 @@ gimp_curves_tool_initialize (GimpTool     *tool,
                                       histogram);
   g_object_unref (histogram);
 
-  if (gimp_drawable_get_precision (drawable) == GIMP_PRECISION_U8)
+  if (gimp_drawable_get_component_type (drawable) == GIMP_COMPONENT_TYPE_U8)
     {
       gimp_curve_view_set_range_x (GIMP_CURVE_VIEW (c_tool->graph), 0, 255);
       gimp_curve_view_set_range_y (GIMP_CURVE_VIEW (c_tool->graph), 0, 255);
diff --git a/app/tools/gimplevelstool.c b/app/tools/gimplevelstool.c
index 4786f57..4d1ed7f 100644
--- a/app/tools/gimplevelstool.c
+++ b/app/tools/gimplevelstool.c
@@ -208,7 +208,7 @@ gimp_levels_tool_initialize (GimpTool     *tool,
   gimp_histogram_view_set_histogram (GIMP_HISTOGRAM_VIEW (l_tool->histogram_view),
                                      l_tool->histogram);
 
-  if (gimp_drawable_get_precision (drawable) == GIMP_PRECISION_U8)
+  if (gimp_drawable_get_component_type (drawable) == GIMP_COMPONENT_TYPE_U8)
     {
       scale_factor = 255.0;
       digits       = 0;
diff --git a/app/widgets/gimpcolorframe.c b/app/widgets/gimpcolorframe.c
index ea40b40..adf522f 100644
--- a/app/widgets/gimpcolorframe.c
+++ b/app/widgets/gimpcolorframe.c
@@ -514,24 +514,35 @@ gimp_color_frame_update (GimpColorFrame *frame)
 
             switch (gimp_babl_format_get_precision (frame->sample_format))
               {
-              case GIMP_PRECISION_U8:
+              case GIMP_PRECISION_U8_GAMMA:
                 if (babl_format_is_palette (frame->sample_format))
                   {
                     print_format = gimp_babl_format (GIMP_RGB,
-                                                     GIMP_PRECISION_U8,
+                                                     GIMP_PRECISION_U8_GAMMA,
                                                      has_alpha);
                     break;
                   }
-
-              case GIMP_PRECISION_U16:
-              case GIMP_PRECISION_U32:
+                /* else fall thru */
+
+              case GIMP_PRECISION_U8_LINEAR:
+              case GIMP_PRECISION_U16_LINEAR:
+              case GIMP_PRECISION_U16_GAMMA:
+              case GIMP_PRECISION_U32_LINEAR:
+              case GIMP_PRECISION_U32_GAMMA:
+              case GIMP_PRECISION_FLOAT_LINEAR:
+              case GIMP_PRECISION_FLOAT_GAMMA:
                 print_format = frame->sample_format;
                 break;
 
-              case GIMP_PRECISION_HALF:
-              case GIMP_PRECISION_FLOAT:
+              case GIMP_PRECISION_HALF_GAMMA:
+                print_format = gimp_babl_format (base_type,
+                                                 GIMP_PRECISION_FLOAT_GAMMA,
+                                                 has_alpha);
+                break;
+
+              case GIMP_PRECISION_HALF_LINEAR:
                 print_format = gimp_babl_format (base_type,
-                                                 GIMP_PRECISION_FLOAT,
+                                                 GIMP_PRECISION_FLOAT_LINEAR,
                                                  has_alpha);
                 break;
               }
diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c
index 3b8d923..bd2a448 100644
--- a/app/xcf/xcf-load.c
+++ b/app/xcf/xcf-load.c
@@ -139,14 +139,14 @@ xcf_load_image (Gimp     *gimp,
                 XcfInfo  *info,
                 GError  **error)
 {
-  GimpImage          *image;
+  GimpImage          *image = NULL;
   const GimpParasite *parasite;
   guint32             saved_pos;
   guint32             offset;
   gint                width;
   gint                height;
   gint                image_type;
-  gint                precision = GIMP_PRECISION_U8;
+  GimpPrecision       precision = GIMP_PRECISION_U8_GAMMA;
   gint                num_successful_elements = 0;
 
   /* read in the image width, height and type */
@@ -155,7 +155,29 @@ xcf_load_image (Gimp     *gimp,
   info->cp += xcf_read_int32 (info->fp, (guint32 *) &image_type, 1);
 
   if (info->file_version >= 4)
-    info->cp += xcf_read_int32 (info->fp, (guint32 *) &precision, 1);
+    {
+      gint p;
+
+      info->cp += xcf_read_int32 (info->fp, (guint32 *) &p, 1);
+
+      if (info->file_version == 4)
+        {
+          switch (p)
+            {
+            case 0: precision = GIMP_PRECISION_U8_GAMMA;     break;
+            case 1: precision = GIMP_PRECISION_U16_GAMMA;    break;
+            case 2: precision = GIMP_PRECISION_U32_LINEAR;   break;
+            case 3: precision = GIMP_PRECISION_HALF_LINEAR;  break;
+            case 4: precision = GIMP_PRECISION_FLOAT_LINEAR; break;
+            default:
+              goto hard_error;
+            }
+        }
+      else
+        {
+          precision = p;
+        }
+    }
 
   image = gimp_create_image (gimp, width, height, image_type, precision,
                              FALSE);
@@ -358,7 +380,8 @@ xcf_load_image (Gimp     *gimp,
                       _("This XCF file is corrupt!  I could not even "
                         "salvage any partial image data from it."));
 
-  g_object_unref (image);
+  if (image)
+    g_object_unref (image);
 
   return NULL;
 }
diff --git a/app/xcf/xcf-save.c b/app/xcf/xcf-save.c
index 266f2b8..d577971 100644
--- a/app/xcf/xcf-save.c
+++ b/app/xcf/xcf-save.c
@@ -215,8 +215,8 @@ xcf_save_choose_format (XcfInfo   *info,
         save_version = MAX (3, save_version);
     }
 
-  if (gimp_image_get_precision (image) != GIMP_PRECISION_U8)
-    save_version = MAX (4, save_version);
+  if (gimp_image_get_precision (image) != GIMP_PRECISION_U8_GAMMA)
+    save_version = MAX (5, save_version);
 
   info->file_version = save_version;
 }
diff --git a/app/xcf/xcf.c b/app/xcf/xcf.c
index 99dcbe8..7b8f464 100644
--- a/app/xcf/xcf.c
+++ b/app/xcf/xcf.c
@@ -70,7 +70,8 @@ static GimpXcfLoaderFunc * const xcf_loaders[] =
   xcf_load_image,   /* version 1 */
   xcf_load_image,   /* version 2 */
   xcf_load_image,   /* version 3 */
-  xcf_load_image    /* version 4 */
+  xcf_load_image,   /* version 4 */
+  xcf_load_image    /* version 5 */
 };
 
 
diff --git a/libgimp/gimpenums.c.tail b/libgimp/gimpenums.c.tail
index d472342..8094ec0 100644
--- a/libgimp/gimpenums.c.tail
+++ b/libgimp/gimpenums.c.tail
@@ -11,6 +11,7 @@ static const GimpGetTypeFunc get_type_funcs[] =
   gimp_channel_ops_get_type,
   gimp_channel_type_get_type,
   gimp_clone_type_get_type,
+  gimp_component_type_get_type,
   gimp_convert_dither_type_get_type,
   gimp_convert_palette_type_get_type,
   gimp_convolution_type_get_type,
@@ -69,6 +70,7 @@ static const gchar * const type_names[] =
   "GimpChannelOps",
   "GimpChannelType",
   "GimpCloneType",
+  "GimpComponentType",
   "GimpConvertDitherType",
   "GimpConvertPaletteType",
   "GimpConvolutionType",
diff --git a/libgimp/gimpenums.h b/libgimp/gimpenums.h
index 5c992cb..77c0c63 100644
--- a/libgimp/gimpenums.h
+++ b/libgimp/gimpenums.h
@@ -47,6 +47,20 @@ typedef enum
 } GimpBrushGeneratedShape;
 
 
+#define GIMP_TYPE_COMPONENT_TYPE (gimp_component_type_get_type ())
+
+GType gimp_component_type_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+  GIMP_COMPONENT_TYPE_U8 = 100,
+  GIMP_COMPONENT_TYPE_U16 = 200,
+  GIMP_COMPONENT_TYPE_U32 = 300,
+  GIMP_COMPONENT_TYPE_HALF = 400,
+  GIMP_COMPONENT_TYPE_FLOAT = 500
+} GimpComponentType;
+
+
 #define GIMP_TYPE_CONVERT_DITHER_TYPE (gimp_convert_dither_type_get_type ())
 
 GType gimp_convert_dither_type_get_type (void) G_GNUC_CONST;
@@ -264,11 +278,16 @@ GType gimp_precision_get_type (void) G_GNUC_CONST;
 
 typedef enum
 {
-  GIMP_PRECISION_U8,
-  GIMP_PRECISION_U16,
-  GIMP_PRECISION_U32,
-  GIMP_PRECISION_HALF,
-  GIMP_PRECISION_FLOAT
+  GIMP_PRECISION_U8_LINEAR = 100,
+  GIMP_PRECISION_U8_GAMMA = 150,
+  GIMP_PRECISION_U16_LINEAR = 200,
+  GIMP_PRECISION_U16_GAMMA = 250,
+  GIMP_PRECISION_U32_LINEAR = 300,
+  GIMP_PRECISION_U32_GAMMA = 350,
+  GIMP_PRECISION_HALF_LINEAR = 400,
+  GIMP_PRECISION_HALF_GAMMA = 450,
+  GIMP_PRECISION_FLOAT_LINEAR = 500,
+  GIMP_PRECISION_FLOAT_GAMMA = 550
 } GimpPrecision;
 
 
diff --git a/libgimp/gimpimage_pdb.c b/libgimp/gimpimage_pdb.c
index 3cc5fd4..64bd821 100644
--- a/libgimp/gimpimage_pdb.c
+++ b/libgimp/gimpimage_pdb.c
@@ -161,7 +161,7 @@ gimp_image_new (gint              width,
  *
  * Creates a new image, undisplayed with the specified extents, type
  * and precision. Indexed images can only be created at
- * GIMP_PRECISION_U8 precision. See gimp_image_new() for further
+ * GIMP_PRECISION_U8_GAMMA precision. See gimp_image_new() for further
  * details.
  *
  * Returns: The ID of the newly created image.
diff --git a/menus/image-menu.xml.in b/menus/image-menu.xml.in
index 582a3d5..a47452d 100644
--- a/menus/image-menu.xml.in
+++ b/menus/image-menu.xml.in
@@ -328,11 +328,16 @@
         <separator />
       </menu>
       <menu action="image-precision-menu" name="Precision">
-        <menuitem action="image-convert-u8" />
-        <menuitem action="image-convert-u16" />
-        <menuitem action="image-convert-u32" />
-        <menuitem action="image-convert-half" />
-        <menuitem action="image-convert-float" />
+        <menuitem action="image-convert-u8-linear" />
+        <menuitem action="image-convert-u8-gamma" />
+        <menuitem action="image-convert-u16-linear" />
+        <menuitem action="image-convert-u16-gamma" />
+        <menuitem action="image-convert-u32-linear" />
+        <menuitem action="image-convert-u32-gamma" />
+        <menuitem action="image-convert-half-linear" />
+        <menuitem action="image-convert-half-gamma" />
+        <menuitem action="image-convert-float-linear" />
+        <menuitem action="image-convert-float-gamma" />
         <separator />
       </menu>
       <menu action="image-transform-menu" name="Transform">
diff --git a/plug-ins/common/file-gegl.c b/plug-ins/common/file-gegl.c
index 21bff28..c4af101 100644
--- a/plug-ins/common/file-gegl.c
+++ b/plug-ins/common/file-gegl.c
@@ -289,8 +289,6 @@ load_image (const gchar  *filename,
   GeglBuffer        *src_buf  = NULL;
   GeglBuffer        *dest_buf = NULL;
   const Babl        *format;
-  const Babl        *model;
-  const Babl        *type;
 
   gimp_progress_init_printf (_("Opening '%s'"),
                              gimp_filename_to_utf8 (filename));
@@ -327,21 +325,7 @@ load_image (const gchar  *filename,
   height = gegl_buffer_get_height (src_buf);
   format = gegl_buffer_get_format (src_buf);
 
-  model = babl_format_get_model (format);
-
-  if (model == babl_model ("Y")  ||
-      model == babl_model ("Y'") ||
-      model == babl_model ("YA") ||
-      model == babl_model ("Y'A"))
-    {
-      base_type = GIMP_GRAY;
-
-      if (babl_format_has_alpha (format))
-        image_type = GIMP_GRAYA_IMAGE;
-      else
-        image_type = GIMP_GRAY_IMAGE;
-    }
-  else if (babl_format_is_palette (format))
+  if (babl_format_is_palette (format))
     {
       base_type = GIMP_INDEXED;
 
@@ -349,29 +333,73 @@ load_image (const gchar  *filename,
         image_type = GIMP_INDEXEDA_IMAGE;
       else
         image_type = GIMP_INDEXED_IMAGE;
+
+      precision = GIMP_PRECISION_U8_GAMMA;
     }
   else
     {
-      base_type = GIMP_RGB;
+      const Babl *model  = babl_format_get_model (format);
+      const Babl *type   = babl_format_get_type (format, 0);
+      gboolean    linear = TRUE;
+
+      if (model == babl_model ("Y")  ||
+          model == babl_model ("Y'") ||
+          model == babl_model ("YA") ||
+          model == babl_model ("Y'A"))
+        {
+          base_type = GIMP_GRAY;
 
-      if (babl_format_has_alpha (format))
-        image_type = GIMP_RGBA_IMAGE;
+          if (babl_format_has_alpha (format))
+            image_type = GIMP_GRAYA_IMAGE;
+          else
+            image_type = GIMP_GRAY_IMAGE;
+
+          if (model == babl_model ("Y'") ||
+              model == babl_model ("Y'A"))
+            linear = FALSE;
+        }
       else
-        image_type = GIMP_RGB_IMAGE;
-    }
+        {
+          base_type = GIMP_RGB;
 
-  type = babl_format_get_type (format, 0);
+          if (babl_format_has_alpha (format))
+            image_type = GIMP_RGBA_IMAGE;
+          else
+            image_type = GIMP_RGB_IMAGE;
+
+          if (model == babl_model ("R'G'B'") ||
+              model == babl_model ("R'G'B'A"))
+            linear = FALSE;
+        }
+
+      if (linear)
+        {
+          if (type == babl_type ("u8"))
+            precision = GIMP_PRECISION_U8_LINEAR;
+          else if (type == babl_type ("u16"))
+            precision = GIMP_PRECISION_U16_LINEAR;
+          else if (type == babl_type ("u32"))
+            precision = GIMP_PRECISION_U32_LINEAR;
+          else if (type == babl_type ("half"))
+            precision = GIMP_PRECISION_HALF_LINEAR;
+          else
+            precision = GIMP_PRECISION_FLOAT_LINEAR;
+        }
+      else
+        {
+          if (type == babl_type ("u8"))
+            precision = GIMP_PRECISION_U8_GAMMA;
+          else if (type == babl_type ("u16"))
+            precision = GIMP_PRECISION_U16_GAMMA;
+          else if (type == babl_type ("u32"))
+            precision = GIMP_PRECISION_U32_GAMMA;
+          else if (type == babl_type ("half"))
+            precision = GIMP_PRECISION_HALF_GAMMA;
+          else
+            precision = GIMP_PRECISION_FLOAT_GAMMA;
+        }
+    }
 
-  if (type == babl_type ("u8"))
-    precision = GIMP_PRECISION_U8;
-  else if (type == babl_type ("u16"))
-    precision = GIMP_PRECISION_U16;
-  else if (type == babl_type ("u32"))
-    precision = GIMP_PRECISION_U32;
-  else if (type == babl_type ("half"))
-    precision = GIMP_PRECISION_HALF;
-  else
-    precision = GIMP_PRECISION_FLOAT;
 
   image_ID = gimp_image_new_with_precision (width, height,
                                             base_type, precision);
diff --git a/plug-ins/common/file-png.c b/plug-ins/common/file-png.c
index 6be0160..1d64254 100644
--- a/plug-ins/common/file-png.c
+++ b/plug-ins/common/file-png.c
@@ -774,9 +774,9 @@ load_image (const gchar  *filename,
    */
 
   if (png_get_bit_depth (pp, info) == 16)
-    image_precision = GIMP_PRECISION_U16;
+    image_precision = GIMP_PRECISION_U16_GAMMA;
   else
-    image_precision = GIMP_PRECISION_U8;
+    image_precision = GIMP_PRECISION_U8_GAMMA;
 
   if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
     png_set_swap (pp);
@@ -839,7 +839,7 @@ load_image (const gchar  *filename,
     case PNG_COLOR_TYPE_RGB:           /* RGB */
       image_type = GIMP_RGB;
       layer_type = GIMP_RGB_IMAGE;
-      if (image_precision == GIMP_PRECISION_U8)
+      if (image_precision == GIMP_PRECISION_U8_GAMMA)
         file_format = babl_format ("R'G'B' u8");
       else
         file_format = babl_format ("R'G'B' u16");
@@ -848,7 +848,7 @@ load_image (const gchar  *filename,
     case PNG_COLOR_TYPE_RGB_ALPHA:     /* RGBA */
       image_type = GIMP_RGB;
       layer_type = GIMP_RGBA_IMAGE;
-      if (image_precision == GIMP_PRECISION_U8)
+      if (image_precision == GIMP_PRECISION_U8_GAMMA)
         file_format = babl_format ("R'G'B'A u8");
       else
         file_format = babl_format ("R'G'B'A u16");
@@ -857,7 +857,7 @@ load_image (const gchar  *filename,
     case PNG_COLOR_TYPE_GRAY:          /* Grayscale */
       image_type = GIMP_GRAY;
       layer_type = GIMP_GRAY_IMAGE;
-      if (image_precision == GIMP_PRECISION_U8)
+      if (image_precision == GIMP_PRECISION_U8_GAMMA)
         file_format = babl_format ("Y' u8");
       else
         file_format = babl_format ("Y' u16");
@@ -866,7 +866,7 @@ load_image (const gchar  *filename,
     case PNG_COLOR_TYPE_GRAY_ALPHA:    /* Grayscale + alpha */
       image_type = GIMP_GRAY;
       layer_type = GIMP_GRAYA_IMAGE;
-      if (image_precision == GIMP_PRECISION_U8)
+      if (image_precision == GIMP_PRECISION_U8_GAMMA)
         file_format = babl_format ("Y'A u8");
       else
         file_format = babl_format ("Y'A u16");
@@ -1330,7 +1330,7 @@ save_image (const gchar  *filename,
 
   png_textp  text = NULL;
 
-  if (gimp_image_get_precision (image_ID) == GIMP_PRECISION_U8)
+  if (gimp_image_get_precision (image_ID) == GIMP_PRECISION_U8_GAMMA)
     bit_depth = 8;
   else
     bit_depth = 16;
diff --git a/plug-ins/common/file-ps.c b/plug-ins/common/file-ps.c
index 6bb1168..80bc098 100644
--- a/plug-ins/common/file-ps.c
+++ b/plug-ins/common/file-ps.c
@@ -1802,7 +1802,7 @@ create_new_image (const gchar        *filename,
     }
 
   image_ID = gimp_image_new_with_precision (width, height, type,
-                                            GIMP_PRECISION_U8);
+                                            GIMP_PRECISION_U8_GAMMA);
   gimp_image_undo_disable (image_ID);
 
   tmp = g_strdup_printf ("%s-%d", filename, pagenum);
diff --git a/plug-ins/common/file-tiff-load.c b/plug-ins/common/file-tiff-load.c
index de3d1e2..1ba1882 100644
--- a/plug-ins/common/file-tiff-load.c
+++ b/plug-ins/common/file-tiff-load.c
@@ -804,8 +804,12 @@ load_image (const gchar        *filename,
 
       if ((target == GIMP_PAGE_SELECTOR_TARGET_IMAGES) || (! image))
         {
-          if ((image = gimp_image_new_with_precision (cols, rows, image_type,
-                                                      bps <= 8 ? GIMP_PRECISION_U8 : GIMP_PRECISION_U16)) == 
-1)
+          image = gimp_image_new_with_precision (cols, rows, image_type,
+                                                 bps <= 8 ?
+                                                 GIMP_PRECISION_U8_GAMMA :
+                                                 GIMP_PRECISION_U16_GAMMA);
+
+          if (image < 1)
             {
               g_message ("Could not create a new image: %s",
                          gimp_get_pdb_error ());
diff --git a/plug-ins/common/file-tiff-save.c b/plug-ins/common/file-tiff-save.c
index 281bb7c..19ca62d 100644
--- a/plug-ins/common/file-tiff-save.c
+++ b/plug-ins/common/file-tiff-save.c
@@ -720,7 +720,7 @@ save_image (const gchar  *filename,
   gimp_progress_init_printf (_("Saving '%s'"),
                              gimp_filename_to_utf8 (filename));
 
-  if (gimp_image_get_precision (image) == GIMP_PRECISION_U8)
+  if (gimp_image_get_precision (image) == GIMP_PRECISION_U8_GAMMA)
     bitspersample = 8;
   else
     bitspersample = 16;
diff --git a/plug-ins/file-exr/file-exr.c b/plug-ins/file-exr/file-exr.c
index 2f420a6..8f3df6d 100644
--- a/plug-ins/file-exr/file-exr.c
+++ b/plug-ins/file-exr/file-exr.c
@@ -195,13 +195,13 @@ load_image (const gchar  *filename,
   switch (exr_loader_get_precision (loader))
     {
     case PREC_UINT:
-      image_precision = GIMP_PRECISION_U32;
+      image_precision = GIMP_PRECISION_U32_LINEAR;
       break;
     case PREC_HALF:
-      image_precision = GIMP_PRECISION_HALF;
+      image_precision = GIMP_PRECISION_HALF_LINEAR;
       break;
     case PREC_FLOAT:
-      image_precision = GIMP_PRECISION_FLOAT;
+      image_precision = GIMP_PRECISION_FLOAT_LINEAR;
       break;
     default:
       g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
diff --git a/plug-ins/file-fits/fits.c b/plug-ins/file-fits/fits.c
index 579e8c2..a262f62 100644
--- a/plug-ins/file-fits/fits.c
+++ b/plug-ins/file-fits/fits.c
@@ -570,31 +570,31 @@ load_fits (const gchar *filename,
   switch (hdulist->bitpix)
     {
     case 8:
-      iprecision = GIMP_PRECISION_U8;
+      iprecision = GIMP_PRECISION_U8_GAMMA;
       type = babl_type ("u8");
       datamax = 255.0;
       replacetransform = 1.0;
       break;
     case 16:
-      iprecision = GIMP_PRECISION_U16;
+      iprecision = GIMP_PRECISION_U16_GAMMA; /* FIXME precision */
       type = babl_type ("u16");
       datamax = 65535.0;
       replacetransform = 257;
       break;
     case 32:
-      iprecision = GIMP_PRECISION_U32;
+      iprecision = GIMP_PRECISION_U32_LINEAR;
       type = babl_type ("u32");
       datamax = 4294967295.0;
       replacetransform = 16843009;
       break;
     case -32:
-      iprecision = GIMP_PRECISION_FLOAT;
+      iprecision = GIMP_PRECISION_FLOAT_LINEAR;
       type = babl_type ("float");
       datamax = 1.0;
       replacetransform = 1.0 / 255.0;
       break;
     case -64:
-      iprecision = GIMP_PRECISION_FLOAT;
+      iprecision = GIMP_PRECISION_FLOAT_LINEAR;
       type = babl_type ("double");
       datamax = 1.0;
       replacetransform = 1.0 / 255.0;
diff --git a/plug-ins/file-jpeg/jpeg-load.c b/plug-ins/file-jpeg/jpeg-load.c
index 0ed9269..41cd2e4 100644
--- a/plug-ins/file-jpeg/jpeg-load.c
+++ b/plug-ins/file-jpeg/jpeg-load.c
@@ -235,9 +235,10 @@ load_image (const gchar  *filename,
     }
   else
     {
-      image_ID = gimp_image_new_with_precision
-        (cinfo.output_width, cinfo.output_height,
-         image_type, GIMP_PRECISION_U8);
+      image_ID = gimp_image_new_with_precision (cinfo.output_width,
+                                                cinfo.output_height,
+                                                image_type,
+                                                GIMP_PRECISION_U8_GAMMA);
 
       gimp_image_undo_disable (image_ID);
       gimp_image_set_filename (image_ID, filename);
diff --git a/tools/pdbgen/enums.pl b/tools/pdbgen/enums.pl
index b8d5329..6132b72 100644
--- a/tools/pdbgen/enums.pl
+++ b/tools/pdbgen/enums.pl
@@ -415,6 +415,18 @@ package Gimp::CodeGen::enums;
          symbols => [ qw(GIMP_VECTORS_STROKE_TYPE_BEZIER) ],
          mapping => { GIMP_VECTORS_STROKE_TYPE_BEZIER => '0' }
        },
+    GimpComponentType =>
+       { contig => 0,
+         header => 'core/core-enums.h',
+         symbols => [ qw(GIMP_COMPONENT_TYPE_U8 GIMP_COMPONENT_TYPE_U16
+                         GIMP_COMPONENT_TYPE_U32 GIMP_COMPONENT_TYPE_HALF
+                         GIMP_COMPONENT_TYPE_FLOAT) ],
+         mapping => { GIMP_COMPONENT_TYPE_U8 => '100',
+                      GIMP_COMPONENT_TYPE_U16 => '200',
+                      GIMP_COMPONENT_TYPE_U32 => '300',
+                      GIMP_COMPONENT_TYPE_HALF => '400',
+                      GIMP_COMPONENT_TYPE_FLOAT => '500' }
+       },
     GimpConvertDitherType =>
        { contig => 1,
          header => 'core/core-enums.h',
@@ -542,16 +554,25 @@ package Gimp::CodeGen::enums;
                       GIMP_ORIENTATION_UNKNOWN => '2' }
        },
     GimpPrecision =>
-       { contig => 1,
+       { contig => 0,
          header => 'core/core-enums.h',
-         symbols => [ qw(GIMP_PRECISION_U8 GIMP_PRECISION_U16
-                         GIMP_PRECISION_U32 GIMP_PRECISION_HALF
-                         GIMP_PRECISION_FLOAT) ],
-         mapping => { GIMP_PRECISION_U8 => '0',
-                      GIMP_PRECISION_U16 => '1',
-                      GIMP_PRECISION_U32 => '2',
-                      GIMP_PRECISION_HALF => '3',
-                      GIMP_PRECISION_FLOAT => '4' }
+         symbols => [ qw(GIMP_PRECISION_U8_LINEAR GIMP_PRECISION_U8_GAMMA
+                         GIMP_PRECISION_U16_LINEAR GIMP_PRECISION_U16_GAMMA
+                         GIMP_PRECISION_U32_LINEAR GIMP_PRECISION_U32_GAMMA
+                         GIMP_PRECISION_HALF_LINEAR
+                         GIMP_PRECISION_HALF_GAMMA
+                         GIMP_PRECISION_FLOAT_LINEAR
+                         GIMP_PRECISION_FLOAT_GAMMA) ],
+         mapping => { GIMP_PRECISION_U8_LINEAR => '100',
+                      GIMP_PRECISION_U8_GAMMA => '150',
+                      GIMP_PRECISION_U16_LINEAR => '200',
+                      GIMP_PRECISION_U16_GAMMA => '250',
+                      GIMP_PRECISION_U32_LINEAR => '300',
+                      GIMP_PRECISION_U32_GAMMA => '350',
+                      GIMP_PRECISION_HALF_LINEAR => '400',
+                      GIMP_PRECISION_HALF_GAMMA => '450',
+                      GIMP_PRECISION_FLOAT_LINEAR => '500',
+                      GIMP_PRECISION_FLOAT_GAMMA => '550' }
        },
     GimpRotationType =>
        { contig => 1,
diff --git a/tools/pdbgen/pdb/convert.pdb b/tools/pdbgen/pdb/convert.pdb
index 2e84f6f..a37a756 100644
--- a/tools/pdbgen/pdb/convert.pdb
+++ b/tools/pdbgen/pdb/convert.pdb
@@ -131,7 +131,7 @@ HELP
   GimpPalette *pal = NULL;
 
   if (gimp_pdb_image_is_not_base_type (image, GIMP_INDEXED, error) &&
-      gimp_pdb_image_is_precision (image, GIMP_PRECISION_U8, error) &&
+      gimp_pdb_image_is_precision (image, GIMP_PRECISION_U8_GAMMA, error) &&
       gimp_item_stack_is_flat (GIMP_ITEM_STACK (gimp_image_get_layers (image))))
     {
       switch (palette_type)
diff --git a/tools/pdbgen/pdb/image.pdb b/tools/pdbgen/pdb/image.pdb
index 767be93..cb866d7 100644
--- a/tools/pdbgen/pdb/image.pdb
+++ b/tools/pdbgen/pdb/image.pdb
@@ -114,7 +114,7 @@ HELP
         code => <<'CODE'
 {
   image = gimp_create_image (gimp, width, height, type,
-                             GIMP_PRECISION_U8, FALSE);
+                             GIMP_PRECISION_U8_GAMMA, FALSE);
 
   if (! image)
     success = FALSE;
@@ -128,7 +128,7 @@ sub image_new_with_precision {
 
     $help = <<'HELP';
 Creates a new image, undisplayed with the specified extents, type
-and precision. Indexed images can only be created at GIMP_PRECISION_U8
+and precision. Indexed images can only be created at GIMP_PRECISION_U8_GAMMA
 precision. See gimp_image_new() for further details.
 HELP
 
@@ -156,7 +156,7 @@ HELP
   if (gimp->plug_in_manager->current_plug_in)
     gimp_plug_in_enable_precision (gimp->plug_in_manager->current_plug_in);
 
-  if (type != GIMP_INDEXED || precision == GIMP_PRECISION_U8)
+  if (type != GIMP_INDEXED || precision == GIMP_PRECISION_U8_GAMMA)
     {
       image = gimp_create_image (gimp, width, height, type,
                                  precision, FALSE);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]