Ejemplo n.º 1
0
static void
prepare (GeglOperation *operation)
{
  const Babl *src_format = gegl_operation_get_source_format (operation, "input");
  const char *format     = "RGB float";

  if (src_format)
    {
      const Babl *model = babl_format_get_model (src_format);

      if (model == babl_model ("RGB"))
        format = "RGB float";
      else if (model == babl_model ("RGBA"))
        format = "RGBA float";
      else if (model == babl_model ("R'G'B'"))
        format = "R'G'B' float";
      else if (model == babl_model ("R'G'B'A"))
        format = "R'G'B'A float";
      else if (babl_format_has_alpha (src_format))
        format = "RGBA float";
    }

  gegl_operation_set_format (operation, "input",  babl_format (format));
  gegl_operation_set_format (operation, "output", babl_format (format));
}
Ejemplo n.º 2
0
static void
prepare (GeglOperation *operation)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  const Babl *src_format   = gegl_operation_get_source_format (operation, "input");
  const Babl *input_format = babl_format ("RGB double");
  gint        n_components = 3;
  const Babl *output_format;

  if (src_format)
    {
      const Babl *model = babl_format_get_model (src_format);

      if (model == babl_model ("RGB") || model == babl_model ("R'G'B'") ||
          model == babl_model ("RGBA") || model == babl_model ("R'G'B'A"))
        {
          input_format = babl_format ("RGB double");
          n_components = 3;
        }
      else if (model == babl_model ("Y") || model == babl_model ("Y'") ||
               model == babl_model ("YA") || model == babl_model ("Y'A"))
        {
          input_format = babl_format ("Y double");
          n_components = 1;
        }
    }

  if (o->squared)
    n_components *= 2;

  output_format = babl_format_n (babl_type ("double"), n_components);

  gegl_operation_set_format (operation, "input", input_format);
  gegl_operation_set_format (operation, "output", output_format);
}
Ejemplo n.º 3
0
static void
gegl_gblur_1d_prepare (GeglOperation *operation)
{
  const Babl *src_format = gegl_operation_get_source_format (operation, "input");
  const char *format     = "RaGaBaA float";

  /*
   * FIXME: when the abyss policy is _NONE, the behavior at the edge
   *        depends on input format (with or without an alpha component)
   */
  if (src_format)
    {
      const Babl *model = babl_format_get_model (src_format);

      if (model == babl_model ("RGB") || model == babl_model ("R'G'B'"))
        format = "RGB float";
      else if (model == babl_model ("Y") || model == babl_model ("Y'"))
        format = "Y float";
      else if (model == babl_model ("YA") || model == babl_model ("Y'A") ||
               model == babl_model ("YaA") || model == babl_model ("Y'aA"))
        format = "YaA float";
    }

  gegl_operation_set_format (operation, "output", babl_format (format));
}
Ejemplo n.º 4
0
gboolean
gimp_babl_format_get_linear (const Babl *format)
{
  const Babl *model;

  g_return_val_if_fail (format != NULL, FALSE);

  model = babl_format_get_model (format);

  if (model == babl_model ("Y")   ||
      model == babl_model ("YA")  ||
      model == babl_model ("RGB") ||
      model == babl_model ("RGBA"))
    {
      return TRUE;
    }
  else if (model == babl_model ("Y'")     ||
           model == babl_model ("Y'A")    ||
           model == babl_model ("R'G'B'") ||
           model == babl_model ("R'G'B'A"))
    {
      return FALSE;
    }
  else if (babl_format_is_palette (format))
    {
      return FALSE;
    }

  g_return_val_if_reached (FALSE);
}
Ejemplo n.º 5
0
GimpImageBaseType
gimp_babl_format_get_base_type (const Babl *format)
{
  const Babl *model;

  g_return_val_if_fail (format != NULL, -1);

  model = babl_format_get_model (format);

  if (model == babl_model ("Y")  ||
      model == babl_model ("Y'") ||
      model == babl_model ("YA") ||
      model == babl_model ("Y'A"))
    {
      return GIMP_GRAY;
    }
  else if (model == babl_model ("RGB")    ||
           model == babl_model ("R'G'B'") ||
           model == babl_model ("RGBA")   ||
           model == babl_model ("R'G'B'A"))
    {
      return GIMP_RGB;
    }
  else if (babl_format_is_palette (format))
    {
      return GIMP_INDEXED;
    }

  g_return_val_if_reached (-1);
}
Ejemplo n.º 6
0
Archivo: opacity.c Proyecto: GNOME/gegl
static void
prepare (GeglOperation *self)
{
  const Babl *fmt = gegl_operation_get_source_format (self, "input");
  GeglProperties *o = GEGL_PROPERTIES (self);

  if (fmt)
    {
      const Babl *model = babl_format_get_model (fmt);

      if (model == babl_model ("R'aG'aB'aA") ||
          model == babl_model ("Y'aA"))
        {
          o->user_data = NULL;
          fmt = babl_format ("R'aG'aB'aA float");
        }
      else if (model == babl_model ("RaGaBaA") ||
               model == babl_model ("YaA"))
        {
          o->user_data = NULL;
          fmt = babl_format ("RaGaBaA float");
        }
      else if (model == babl_model ("R'G'B'A") ||
               model == babl_model ("R'G'B'")  ||
               model == babl_model ("Y'")      ||
               model == babl_model ("Y'A"))
        {
          o->user_data = (void*)0xabc;
          fmt = babl_format ("R'G'B'A float");
        }
      else
        {
          o->user_data = (void*)0xabc;
          fmt = babl_format ("RGBA float");
        }
    }
  else
    {
      o->user_data = (void*)0xabc;
      fmt = babl_format ("RGBA float");
    }

  gegl_operation_set_format (self, "input", fmt);
  gegl_operation_set_format (self, "output", fmt);
  gegl_operation_set_format (self, "aux", babl_format ("Y float"));

  return;
}
Ejemplo n.º 7
0
static void prepare (GeglOperation *operation)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  const Babl *format;
  const Babl *input_format;
  const Babl *input_model;
  const Babl *lch_model;

  input_format = gegl_operation_get_source_format (operation, "input");
  if (input_format == NULL)
    return;

  input_model = babl_format_get_model (input_format);

  if (babl_format_has_alpha (input_format))
    {
      lch_model = babl_model ("CIE LCH(ab) alpha");
      if (input_model == lch_model)
        {
          format = babl_format ("CIE LCH(ab) alpha float");
          o->user_data = process_lch_alpha;
        }
      else
        {
          format = babl_format ("CIE Lab alpha float");
          o->user_data = process_lab_alpha;
        }
    }
  else
    {
      lch_model = babl_model ("CIE LCH(ab)");
      if (input_model == lch_model)
        {
          format = babl_format ("CIE LCH(ab) float");
          o->user_data = process_lch;
        }
      else
        {
          format = babl_format ("CIE Lab float");
          o->user_data = process_lab;
        }
    }

  gegl_operation_set_format (operation, "input", format);
  gegl_operation_set_format (operation, "output", format);
}
Ejemplo n.º 8
0
GimpImageType
gimp_babl_format_get_image_type (const Babl *format)
{
  const gchar *name;

  g_return_val_if_fail (format != NULL, -1);

  name = babl_get_name (babl_format_get_model (format));

  if (! strcmp (name, "Y")  ||
      ! strcmp (name, "Y'") ||
      ! strcmp (name, "Y~"))
    {
      return GIMP_GRAY_IMAGE;
    }
  else if (! strcmp (name, "YA")   ||
           ! strcmp (name, "Y'A") ||
           ! strcmp (name, "Y~A"))
    {
      return GIMP_GRAYA_IMAGE;
    }
  else if (! strcmp (name, "RGB")    ||
           ! strcmp (name, "R'G'B'") ||
           ! strcmp (name, "R~G~B~"))
    {
      return GIMP_RGB_IMAGE;
    }
  else if (! strcmp (name, "RGBA")    ||
           ! strcmp (name, "R'G'B'A") ||
           ! strcmp (name, "R~G~B~A"))
    {
      return GIMP_RGBA_IMAGE;
    }
  else if (babl_format_is_palette (format))
    {
      if (babl_format_has_alpha (format))
        return GIMP_INDEXEDA_IMAGE;
      else
        return GIMP_INDEXED_IMAGE;
    }

  g_return_val_if_reached (-1);
}
Ejemplo n.º 9
0
GimpImageType
gimp_babl_format_get_image_type (const Babl *format)
{
  const Babl *model;

  g_return_val_if_fail (format != NULL, -1);

  model = babl_format_get_model (format);

  if (model == babl_model ("Y") ||
      model == babl_model ("Y'"))
    {
      return GIMP_GRAY_IMAGE;
    }
  else if (model == babl_model ("YA") ||
           model == babl_model ("Y'A"))
    {
      return GIMP_GRAYA_IMAGE;
    }
  else if (model == babl_model ("RGB") ||
           model == babl_model ("R'G'B'"))
    {
      return GIMP_RGB_IMAGE;
    }
  else if (model == babl_model ("RGBA") ||
           model == babl_model ("R'G'B'A"))
    {
      return GIMP_RGBA_IMAGE;
    }
  else if (babl_format_is_palette (format))
    {
      if (babl_format_has_alpha (format))
        return GIMP_INDEXEDA_IMAGE;
      else
        return GIMP_INDEXED_IMAGE;
    }

  g_return_val_if_reached (-1);
}
Ejemplo n.º 10
0
static void
prepare (GeglOperation *self)
{
  const Babl *fmt = gegl_operation_get_source_format (self, "input");
  GeglChantO *o = GEGL_CHANT_PROPERTIES (self);

  if (fmt)
    {
      const Babl *model = babl_format_get_model (fmt);

      if (model == babl_model ("RaGaBaA") ||
          model == babl_model ("R'aG'aB'aA") ||
          model == babl_model ("YaA") ||
          model == babl_model ("Y'aA"))
        {
          o->chant_data = NULL;

          gegl_operation_set_format (self, "input",
                                     babl_format ("RaGaBaA float"));
          gegl_operation_set_format (self, "output",
                                     babl_format ("RaGaBaA float"));
          gegl_operation_set_format (self, "aux",
                                     babl_format ("Y float"));

          return;
        }
    }

  /* ugly way of communicating that we want the RGBA version */
  /* because of that, we can't use the common opencl api for point ops */
  o->chant_data = (void*)0xabc;

  gegl_operation_set_format (self, "input", babl_format ("RGBA float"));
  gegl_operation_set_format (self, "output", babl_format ("RGBA float"));
  gegl_operation_set_format (self, "aux", babl_format ("Y float"));

  return;
}
static void
gimp_operation_mask_components_prepare (GeglOperation *operation)
{
  const Babl *format = gegl_operation_get_source_format (operation, "input");

  if (format)
    {
      const Babl *model = babl_format_get_model (format);

      if (model == babl_model ("R'G'B'A"))
        format = babl_format ("R'G'B'A float");
      else
        format = babl_format ("RGBA float");
    }
  else
    {
      format = babl_format ("RGBA float");
    }

  gegl_operation_set_format (operation, "input",  format);
  gegl_operation_set_format (operation, "aux",    format);
  gegl_operation_set_format (operation, "output", format);
}
Ejemplo n.º 12
0
/**
 * gimp_color_profile_get_format:
 * @format:      a #Babl format
 * @lcms_format: return location for an lcms format
 *
 * This function takes a #Babl format and returns the lcms format to
 * be used with that @format. It also returns a #Babl format to be
 * used instead of the passed @format, which usually is the same as
 * @format, unless lcms doesn't support @format.
 *
 * Note that this function currently only supports RGB, RGBA, R'G'B',
 * R'G'B'A, Y, YA, Y', Y'A and the cairo-RGB24 and cairo-ARGB32 formats.
 *
 * Return value: the #Babl format to be used instead of @format, or %NULL
 *               is the passed @format is not supported at all.
 *
 * Since: 2.10
 **/
const Babl *
gimp_color_profile_get_format (const Babl *format,
                               guint32    *lcms_format)
{
  const Babl *output_format = NULL;
  const Babl *type;
  const Babl *model;
  gboolean    has_alpha;
  gboolean    gray;
  gboolean    linear;

  g_return_val_if_fail (format != NULL, NULL);
  g_return_val_if_fail (lcms_format != NULL, NULL);

  has_alpha = babl_format_has_alpha (format);
  type      = babl_format_get_type (format, 0);
  model     = babl_format_get_model (format);

  if (format == babl_format ("cairo-RGB24"))
    {
      *lcms_format = TYPE_RGB_8;

      return babl_format ("R'G'B' u8");
    }
  else if (format == babl_format ("cairo-ARGB32"))
    {
      *lcms_format = TYPE_RGBA_8;

      return babl_format ("R'G'B'A u8");
    }
  else if (model == babl_model ("RGB") ||
           model == babl_model ("RGBA"))
    {
      gray   = FALSE;
      linear = TRUE;
    }
  else if (model == babl_model ("R'G'B'") ||
           model == babl_model ("R'G'B'A"))
    {
      gray   = FALSE;
      linear = FALSE;
    }
  else if (model == babl_model ("Y") ||
           model == babl_model ("YA"))
    {
      gray   = TRUE;
      linear = TRUE;
    }
  else if (model == babl_model ("Y'") ||
           model == babl_model ("Y'A"))
    {
      gray   = TRUE;
      linear = FALSE;
    }
  else if (babl_format_is_palette (format))
    {
      if (has_alpha)
        {
          *lcms_format = TYPE_RGBA_8;

          return babl_format ("R'G'B'A u8");
        }
      else
        {
          *lcms_format = TYPE_RGB_8;

          return babl_format ("R'G'B' u8");
        }
    }
  else
    {
      g_printerr ("format: %s\n"
                  "has_alpha = %s\n"
                  "type = %s\n"
                  "model = %s\n",
                  babl_get_name (format),
                  has_alpha ? "TRUE" : "FALSE",
                  babl_get_name (type),
                  babl_get_name (model));
      g_return_val_if_reached (NULL);
    }

  *lcms_format = 0;

  if (type == babl_type ("u8"))
    {
      if (has_alpha)
        {
          if (gray)
            *lcms_format = TYPE_GRAYA_8;
          else
            *lcms_format = TYPE_RGBA_8;
        }
      else
        {
          if (gray)
            *lcms_format = TYPE_GRAY_8;
          else
            *lcms_format = TYPE_RGB_8;
        }

      output_format = format;
    }
  else if (type == babl_type ("u16"))
    {
      if (has_alpha)
        {
          if (gray)
            *lcms_format = TYPE_GRAYA_16;
          else
            *lcms_format = TYPE_RGBA_16;
        }
      else
        {
          if (gray)
            *lcms_format = TYPE_GRAY_16;
          else
            *lcms_format = TYPE_RGB_16;
        }

      output_format = format;
    }
  else if (type == babl_type ("half")) /* 16-bit floating point (half) */
    {
      if (has_alpha)
        {
          if (gray)
            *lcms_format = TYPE_GRAYA_HALF_FLT;
          else
            *lcms_format = TYPE_RGBA_HALF_FLT;
        }
      else
        {
          if (gray)
            *lcms_format = TYPE_GRAY_HALF_FLT;
          else
            *lcms_format = TYPE_RGB_HALF_FLT;
        }

      output_format = format;
    }
  else if (type == babl_type ("float"))
    {
      if (has_alpha)
        {
          if (gray)
            *lcms_format = TYPE_GRAYA_FLT;
          else
            *lcms_format = TYPE_RGBA_FLT;
        }
      else
        {
          if (gray)
            *lcms_format = TYPE_GRAY_FLT;
          else
            *lcms_format = TYPE_RGB_FLT;
        }

      output_format = format;
    }
  else if (type == babl_type ("double"))
    {
      if (has_alpha)
        {
          if (gray)
            *lcms_format = TYPE_GRAYA_DBL;
          else
            *lcms_format = TYPE_RGBA_DBL;
        }
      else
        {
          if (gray)
            *lcms_format = TYPE_GRAY_DBL;
          else
            *lcms_format = TYPE_RGB_DBL;
        }

      output_format = format;
    }

  if (*lcms_format == 0)
    {
      g_printerr ("%s: layer format %s not supported, "
                  "falling back to float\n",
                  G_STRFUNC, babl_get_name (format));

      if (has_alpha)
        {
          if (gray)
            {
              *lcms_format = TYPE_GRAYA_FLT;

              if (linear)
                output_format = babl_format ("YA float");
              else
                output_format = babl_format ("Y'A float");
            }
          else
            {
              *lcms_format = TYPE_RGBA_FLT;

              if (linear)
                output_format = babl_format ("RGBA float");
              else
                output_format = babl_format ("R'G'B'A float");
            }
        }
      else
        {
          if (gray)
            {
             *lcms_format = TYPE_GRAY_FLT;

              if (linear)
                output_format = babl_format ("Y float");
              else
                output_format = babl_format ("Y' float");
            }
          else
            {
              *lcms_format = TYPE_RGB_FLT;

              if (linear)
                output_format = babl_format ("RGB float");
              else
                output_format = babl_format ("R'G'B' float");
            }
        }
    }

  return output_format;
}
Ejemplo n.º 13
0
static int
export_tiff (GeglOperation *operation,
             GeglBuffer *input,
             const GeglRectangle *result)
{
  GeglProperties *o = GEGL_PROPERTIES(operation);
  Priv *p = (Priv*) o->user_data;
  gshort color_space, compression = COMPRESSION_NONE;
  gushort bits_per_sample, samples_per_pixel;
  gboolean has_alpha, alpha_is_premultiplied = FALSE;
  gushort sample_format, predictor = 0;
  gushort extra_types[1];
  glong rows_per_stripe = 1;
  gint bytes_per_row;
  const Babl *type, *model;
  gchar format_string[32];
  const Babl *format;

  g_return_val_if_fail(p->tiff != NULL, -1);

  TIFFSetField(p->tiff, TIFFTAG_SUBFILETYPE, 0);
  TIFFSetField(p->tiff, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);

  TIFFSetField(p->tiff, TIFFTAG_IMAGEWIDTH, result->width);
  TIFFSetField(p->tiff, TIFFTAG_IMAGELENGTH, result->height);

  format = gegl_buffer_get_format(input);

  model = babl_format_get_model(format);
  type = babl_format_get_type(format, 0);

  if (model == babl_model("Y") || model == babl_model("Y'"))
    {
      has_alpha = FALSE;
      color_space = PHOTOMETRIC_MINISBLACK;
      model = babl_model("Y'");
      samples_per_pixel = 1;
    }
  else if (model == babl_model("YA") || model == babl_model("Y'A"))
    {
      has_alpha = TRUE;
      alpha_is_premultiplied = FALSE;
      color_space = PHOTOMETRIC_MINISBLACK;
      model = babl_model("Y'A");
      samples_per_pixel = 2;
    }
  else if (model == babl_model("YaA") || model == babl_model("Y'aA"))
    {
      has_alpha = TRUE;
      alpha_is_premultiplied = TRUE;
      color_space = PHOTOMETRIC_MINISBLACK;
      model = babl_model("Y'aA");
      samples_per_pixel = 2;
    }
  else if (model == babl_model("RGB") || model == babl_model("R'G'B'"))
    {
      has_alpha = FALSE;
      color_space = PHOTOMETRIC_RGB;
      model = babl_model("R'G'B'");
      samples_per_pixel = 3;
      predictor = 2;
    }
  else if (model == babl_model("RGBA") || model == babl_model("R'G'B'A"))
    {
      has_alpha = TRUE;
      alpha_is_premultiplied = FALSE;
      color_space = PHOTOMETRIC_RGB;
      model = babl_model("R'G'B'A");
      samples_per_pixel = 4;
      predictor = 2;
    }
  else if (model == babl_model("RaGaBaA") || model == babl_model("R'aG'aB'aA"))
    {
      has_alpha = TRUE;
      alpha_is_premultiplied = TRUE;
      color_space = PHOTOMETRIC_RGB;
      model = babl_model("R'aG'aB'aA");
      samples_per_pixel = 4;
      predictor = 2;
    }
  else
    {
      g_warning("color space not supported: %s", babl_get_name(model));

      has_alpha = TRUE;
      alpha_is_premultiplied = TRUE;
      color_space = PHOTOMETRIC_RGB;
      model = babl_model("R'aG'aB'aA");
      samples_per_pixel = 4;
      predictor = 2;
    }

  TIFFSetField(p->tiff, TIFFTAG_PHOTOMETRIC, color_space);
  TIFFSetField(p->tiff, TIFFTAG_SAMPLESPERPIXEL, samples_per_pixel);
  TIFFSetField(p->tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);

  if (has_alpha)
    {
      if (alpha_is_premultiplied)
        extra_types[0] = EXTRASAMPLE_ASSOCALPHA;
      else
        extra_types[0] = EXTRASAMPLE_UNASSALPHA;

      TIFFSetField(p->tiff, TIFFTAG_EXTRASAMPLES, 1, extra_types);
    }

  if (predictor != 0)
    {
      if (compression == COMPRESSION_LZW)
        TIFFSetField(p->tiff, TIFFTAG_PREDICTOR, predictor);
      else if (compression == COMPRESSION_ADOBE_DEFLATE)
        TIFFSetField(p->tiff, TIFFTAG_PREDICTOR, predictor);
    }

  if (type == babl_type("u8"))
    {
      sample_format = SAMPLEFORMAT_UINT;
      bits_per_sample = 8;
    }
  else if (type == babl_type("half"))
    {
      sample_format = SAMPLEFORMAT_IEEEFP;
      bits_per_sample = 16;
    }
  else if (type == babl_type("u16"))
    {
      sample_format = SAMPLEFORMAT_UINT;
      bits_per_sample = 16;
    }
  else if (type == babl_type("float"))
    {
      sample_format = SAMPLEFORMAT_IEEEFP;
      bits_per_sample = 32;
    }
  else if (type == babl_type("u32"))
    {
      sample_format = SAMPLEFORMAT_UINT;
      bits_per_sample = 32;
    }
  else  if (type == babl_type("double"))
    {
      sample_format = SAMPLEFORMAT_IEEEFP;
      bits_per_sample = 64;
    }
  else
    {
      g_warning("sample format not supported: %s", babl_get_name(type));

      sample_format = SAMPLEFORMAT_UINT;
      type = babl_type("u8");
      bits_per_sample = 8;
    }

  TIFFSetField(p->tiff, TIFFTAG_BITSPERSAMPLE, bits_per_sample);
  TIFFSetField(p->tiff, TIFFTAG_SAMPLEFORMAT, sample_format);

  TIFFSetField(p->tiff, TIFFTAG_COMPRESSION, compression);

  if ((compression == COMPRESSION_CCITTFAX3 ||
       compression == COMPRESSION_CCITTFAX4) &&
       (bits_per_sample != 1 || samples_per_pixel != 1))
    {
      g_critical("only monochrome pictures can be compressed "
                 "with \"CCITT Group 4\" or \"CCITT Group 3\"");
      return -1;
    }

  g_snprintf(format_string, 32, "%s %s",
             babl_get_name(model), babl_get_name(type));

  format = babl_format(format_string);

  /* "Choose RowsPerStrip such that each strip is about 8K bytes." */
  bytes_per_row = babl_format_get_bytes_per_pixel(format) * result->width;
  while (bytes_per_row * rows_per_stripe <= 8192)
    rows_per_stripe++;

  rows_per_stripe = MIN(rows_per_stripe, result->height);

  TIFFSetField(p->tiff, TIFFTAG_ROWSPERSTRIP, rows_per_stripe);

  return save_contiguous(operation, input, result, format);
}
Ejemplo n.º 14
0
/**
 * gimp_color_profile_get_format:
 * @format:      a #Babl format
 * @lcms_format: return location for an lcms format
 *
 * This function takes a #Babl format and returns the lcms format to
 * be used with that @format. It also returns a #Babl format to be
 * used instead of the passed @format, which usually is the same as
 * @format, unless lcms doesn't support @format.
 *
 * Note that this function currently only supports RGB, RGBA, R'G'B' and
 * R'G'B'A formats.
 *
 * Return value: the #Babl format to be used instead of @format, or %NULL
 *               is the passed @format is not supported at all.
 *
 * Since: 2.10
 **/
const Babl *
gimp_color_profile_get_format (const Babl *format,
                               guint32    *lcms_format)
{
  const Babl *output_format = NULL;
  const Babl *type;
  const Babl *model;
  gboolean    has_alpha;
  gboolean    linear;

  g_return_val_if_fail (format != NULL, NULL);
  g_return_val_if_fail (lcms_format != NULL, NULL);

  has_alpha = babl_format_has_alpha (format);
  type      = babl_format_get_type (format, 0);
  model     = babl_format_get_model (format);

  if (model == babl_model ("RGB") ||
      model == babl_model ("RGBA"))
    {
      linear = TRUE;
    }
  else if (model == babl_model ("R'G'B'") ||
           model == babl_model ("R'G'B'A"))
    {
      linear = FALSE;
    }
  else
    {
      g_return_val_if_reached (NULL);
    }

  *lcms_format = 0;

  if (type == babl_type ("u8"))
    {
      if (has_alpha)
        *lcms_format = TYPE_RGBA_8;
      else
        *lcms_format = TYPE_RGB_8;

      output_format = format;
    }
  else if (type == babl_type ("u16"))
    {
      if (has_alpha)
        *lcms_format = TYPE_RGBA_16;
      else
        *lcms_format = TYPE_RGB_16;

      output_format = format;
    }
  else if (type == babl_type ("half")) /* 16-bit floating point (half) */
    {
      if (has_alpha)
        *lcms_format = TYPE_RGBA_HALF_FLT;
      else
        *lcms_format = TYPE_RGB_HALF_FLT;

      output_format = format;
    }
  else if (type == babl_type ("float"))
    {
      if (has_alpha)
        *lcms_format = TYPE_RGBA_FLT;
      else
        *lcms_format = TYPE_RGB_FLT;

      output_format = format;
    }
  else if (type == babl_type ("double"))
    {
      if (has_alpha)
        {
#ifdef TYPE_RGBA_DBL
          /* RGBA double not implemented in lcms */
          *lcms_format = TYPE_RGBA_DBL;
          output_format = format;
#endif /* TYPE_RGBA_DBL */
        }
      else
        {
          *lcms_format = TYPE_RGB_DBL;
          output_format = format;
        }
    }

  if (*lcms_format == 0)
    {
      g_printerr ("%s: layer format %s not supported, "
                  "falling back to float\n",
                  G_STRFUNC, babl_get_name (format));

      if (has_alpha)
        {
          *lcms_format = TYPE_RGBA_FLT;

          if (linear)
            output_format = babl_format ("RGBA float");
          else
            output_format = babl_format ("R'G'B'A float");
        }
      else
        {
          *lcms_format = TYPE_RGB_FLT;

          if (linear)
            output_format = babl_format ("RGB float");
          else
            output_format = babl_format ("R'G'B' float");
        }
    }

  return output_format;
}