Beispiel #1
0
static gboolean
test_opacity_common (const Babl *in_format,
                     const Babl *out_format)
{
  /* Validate that gegl:opacity produces out_format when given in_format */
  gboolean result = TRUE;

  GeglNode *ptn, *src, *opacity, *sink;
  GeglBuffer *src_buffer;
  GeglBuffer *sink_buffer = NULL;

  src_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, 10, 10), in_format);

  ptn  = gegl_node_new ();

  src  = gegl_node_new_child (ptn,
                              "operation", "gegl:buffer-source",
                              "buffer", src_buffer,
                              NULL);

  opacity = gegl_node_new_child (ptn,
                                 "operation", "gegl:opacity",
                                 "value", 0.5,
                                 NULL);

  sink = gegl_node_new_child (ptn,
                              "operation", "gegl:buffer-sink",
                              "buffer", &sink_buffer,
                              "format", NULL,
                              NULL);

  gegl_node_link_many (src, opacity, sink, NULL);

  gegl_node_blit_buffer (sink, NULL, NULL, 0, GEGL_ABYSS_NONE);

  if (out_format != gegl_buffer_get_format (sink_buffer))
    {
      printf ("Got %s expected %s\n", babl_get_name (gegl_buffer_get_format (sink_buffer)),
                                      babl_get_name (out_format));
      result = FALSE;
    }

  if (!gegl_rectangle_equal (gegl_buffer_get_extent (src_buffer),
                             gegl_buffer_get_extent (sink_buffer)))
    result = FALSE;

  g_object_unref (ptn);
  g_object_unref (src_buffer);
  g_object_unref (sink_buffer);

  return result;
}
static gboolean
gimp_operation_histogram_sink_process (GeglOperation        *operation,
                                       GeglOperationContext *context,
                                       const gchar          *output_prop,
                                       const GeglRectangle  *result,
                                       gint                  level)
{
  GeglBuffer *input;
  GeglBuffer *aux;

  if (strcmp (output_prop, "output"))
    {
      g_warning ("requested processing of %s pad on a sink", output_prop);
      return FALSE;
    }

  input = gegl_operation_context_get_source (context, "input");
  aux   = gegl_operation_context_get_source (context, "aux");

  if (! input)
    {
      g_warning ("received NULL input");

      return FALSE;
    }

  if (aux)
    {
      /* do hist with mask */

      g_printerr ("aux format: %s\n",
                  babl_get_name (gegl_buffer_get_format (aux)));

      g_object_unref (aux);
    }
  else
    {
      /* without */
    }

  g_printerr ("input format: %s\n",
              babl_get_name (gegl_buffer_get_format (input)));

  g_object_unref (input);

  return TRUE;
}
const gchar *
gegl_format_get_name (GValue *value)
{
  Babl *format;

  if (!(G_TYPE_POINTER == G_VALUE_TYPE(value)))
    return NULL;
  format = g_value_get_pointer (value);

  if (!format)
    return NULL;

  return babl_get_name (format);
}
Beispiel #4
0
const gchar *
gimp_babl_get_description (const Babl *babl)
{
  const gchar *description;

  g_return_val_if_fail (babl != NULL, NULL);

  if (G_UNLIKELY (! babl_description_hash))
    {
      gint i;

      babl_description_hash = g_hash_table_new (g_str_hash,
                                                g_str_equal);

      for (i = 0; i < G_N_ELEMENTS (babl_descriptions); i++)
        g_hash_table_insert (babl_description_hash,
                             (gpointer) babl_descriptions[i].name,
                             gettext (babl_descriptions[i].description));
    }

  if (babl_format_is_palette (babl))
    {
      if (babl_format_has_alpha (babl))
        return _("Indexed-alpha");
      else
        return _("Indexed");
    }

  description = g_hash_table_lookup (babl_description_hash,
                                     babl_get_name (babl));

  if (description)
    return description;

  return g_strconcat ("ERROR: unknown Babl format ",
                      babl_get_name (babl), NULL);
}
Beispiel #5
0
static char *
babl_fish_serialize (Babl *fish, char *dest, int n)
{
  char *d = dest;
  if (fish->class_type != BABL_FISH_PATH)
    return NULL;

  snprintf (d, n, "%s\n%s\n",
  babl_get_name (fish->fish.source),
  babl_get_name (fish->fish.destination));
  n -= strlen (d);d += strlen (d);

  snprintf (d, n, "\tpixels=%li", fish->fish.pixels);
  n -= strlen (d);d += strlen (d);

  snprintf (d, n, " processings=%i", fish->fish.processings);
  n -= strlen (d);d += strlen (d);

  snprintf (d, n, " cost=%d", (int)fish->fish_path.cost);
  n -= strlen (d);d += strlen (d);

  snprintf (d, n, " error=%f", fish->fish.error);
  n -= strlen (d);d += strlen (d);

  snprintf (d, n, "\n");
  n -= strlen (d);d += strlen (d);

  for (int i = 0; i < fish->fish_path.conversion_list->count; i++)
  {
    snprintf (d, n, "\t%s\n",
      babl_get_name(fish->fish_path.conversion_list->items[i]  ));
    n -= strlen (d);d += strlen (d);
  }

  return dest;
}
Beispiel #6
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);
}
Beispiel #7
0
static gboolean
test_scale (const gdouble scale, const gint x, const gint y, const Babl *format)
{
  GeglNode *checkerboard;
  GeglBuffer *tmp_buffer;
  gboolean result = FALSE;

  const gint bpp = babl_format_get_bytes_per_pixel (format);
  const gint scaled_width  = 32;
  const gint scaled_height = 32;
  gint pad = 32;

  guchar *output_buffer_scaled = gegl_malloc (scaled_width * scaled_height * bpp);
  guchar *output_node_scaled   = gegl_malloc (scaled_width * scaled_height * bpp);

  if (2 / scale > pad)
    pad = 2 / scale + 2;

  tmp_buffer = gegl_buffer_new (GEGL_RECTANGLE ((x / scale) - pad,
                                                (y / scale) - pad,
                                                (scaled_width / scale) + (2 * pad),
                                                (scaled_height / scale) + (2 * pad)),
                                babl_format ("RGBA float"));

  checkerboard = gegl_node_new_child(NULL,
                                     "operation", "gegl:checkerboard",
                                     "x", 16,
                                     "y", 16,
                                     NULL);

  gegl_node_blit_buffer (checkerboard,
                         tmp_buffer,
                         NULL,
                         0,
                         GEGL_ABYSS_NONE);

  gegl_buffer_get (tmp_buffer,
                   GEGL_RECTANGLE (x, y, scaled_width, scaled_height),
                   scale,
                   format,
                   output_buffer_scaled,
                   GEGL_AUTO_ROWSTRIDE,
                   GEGL_ABYSS_NONE);

  g_object_unref (checkerboard);
  g_object_unref (tmp_buffer);

  /* Re-create the node so we don't hit its cache */
  checkerboard = gegl_node_new_child(NULL,
                                     "operation", "gegl:checkerboard",
                                     "x", 16,
                                     "y", 16,
                                     NULL);

  gegl_node_blit (checkerboard,
                  scale,
                  GEGL_RECTANGLE (x, y, scaled_width, scaled_height),
                  format,
                  output_node_scaled,
                  GEGL_AUTO_ROWSTRIDE,
                  0);

  g_object_unref (checkerboard);

  if (0 == memcmp (output_buffer_scaled, output_node_scaled, scaled_width * scaled_height * bpp))
    {
      printf (".");
      fflush(stdout);
      result = TRUE;
    }
  else
    {
      printf ("\n scale=%.4f at %d, %d in \"%s\" ... FAIL\n", scale, x, y, babl_get_name (format));
      result = FALSE;
    }

  gegl_free (output_buffer_scaled);
  gegl_free (output_node_scaled);

  return result;
}
Beispiel #8
0
static void
lcms_layers_transform_rgb (gint                     *layers,
                           gint                      num_layers,
                           cmsHPROFILE               src_profile,
                           cmsHPROFILE               dest_profile,
                           GimpColorRenderingIntent  intent,
                           gboolean                  bpc)
{
  gint i;

  for (i = 0; i < num_layers; i++)
    {
      gint32           layer_id = layers[i];
      const Babl      *layer_format;
      gboolean         has_alpha;
      const Babl      *type;
      const Babl      *iter_format = NULL;
      cmsUInt32Number  lcms_format = 0;
      cmsHTRANSFORM    transform   = NULL;
      gint            *children;
      gint             num_children;

      children = gimp_item_get_children (layer_id, &num_children);

      if (children)
        {
          lcms_layers_transform_rgb (children, num_children,
                                     src_profile, dest_profile,
                                     intent, bpc);

          g_free (children);

          continue;
        }

      layer_format = gimp_drawable_get_format (layer_id);
      has_alpha    = babl_format_has_alpha (layer_format);
      type         = babl_format_get_type (layer_format, 0);

      if (type == babl_type ("u8"))
        {
          if (has_alpha)
            {
              lcms_format = TYPE_RGBA_8;
              iter_format = babl_format ("R'G'B'A u8");
            }
          else
            {
              lcms_format = TYPE_RGB_8;
              iter_format = babl_format ("R'G'B' u8");
            }
        }
      else if (type == babl_type ("u16"))
        {
          if (has_alpha)
            {
              lcms_format = TYPE_RGBA_16;
              iter_format = babl_format ("R'G'B'A u16");
            }
          else
            {
              lcms_format = TYPE_RGB_16;
              iter_format = babl_format ("R'G'B' u16");
            }
        }
      else if (type == babl_type ("half")) /* 16-bit floating point (half) */
        {
#ifdef TYPE_RGB_HALF_FLT
          /* half float types are only in lcms 2.4 and newer */
          if (has_alpha)
            {
              lcms_format = TYPE_RGBA_HALF_FLT;
              iter_format = babl_format ("R'G'B'A half");
            }
          else
            {
              lcms_format = TYPE_RGB_HALF_FLT;
              iter_format = babl_format ("R'G'B' float");
            }
#endif /* TYPE_RGB_HALF_FLT */
        }
      else if (type == babl_type ("float"))
        {
          if (has_alpha)
            {
              lcms_format = TYPE_RGBA_FLT;
              iter_format = babl_format ("R'G'B'A float");
            }
          else
            {
              lcms_format = TYPE_RGB_FLT;
              iter_format = babl_format ("R'G'B' float");
            }
        }
      else if (type == babl_type ("double"))
        {
          if (has_alpha)
            {
#ifdef TYPE_RGBA_DBL
              /* RGBA double not implemented in lcms */
              lcms_format = TYPE_RGBA_DBL;
              iter_format = babl_format ("R'G'B'A double");
#endif /* TYPE_RGBA_DBL */
            }
          else
            {
              lcms_format = TYPE_RGB_DBL;
              iter_format = babl_format ("R'G'B' double");
            }
        }

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

          if (has_alpha)
            {
              lcms_format = TYPE_RGBA_FLT;
              iter_format = babl_format ("R'G'B'A float");
            }
          else
            {
              lcms_format = TYPE_RGB_FLT;
              iter_format = babl_format ("R'G'B' float");
            }
        }

      transform = cmsCreateTransform (src_profile,  lcms_format,
                                      dest_profile, lcms_format,
                                      intent,
                                      cmsFLAGS_NOOPTIMIZE |
                                      (bpc ? cmsFLAGS_BLACKPOINTCOMPENSATION : 0));

      if (transform)
        {
          GeglBuffer         *src_buffer;
          GeglBuffer         *dest_buffer;
          GeglBufferIterator *iter;
          gint                layer_width;
          gint                layer_height;
          gint                layer_bpp;
          gboolean            layer_alpha;
          gdouble             progress_start = (gdouble) i / num_layers;
          gdouble             progress_end   = (gdouble) (i + 1) / num_layers;
          gdouble             range          = progress_end - progress_start;
          gint                count          = 0;
          gint                done           = 0;

          src_buffer   = gimp_drawable_get_buffer (layer_id);
          dest_buffer  = gimp_drawable_get_shadow_buffer (layer_id);
          layer_width  = gegl_buffer_get_width (src_buffer);
          layer_height = gegl_buffer_get_height (src_buffer);
          layer_bpp    = babl_format_get_bytes_per_pixel (iter_format);
          layer_alpha  = babl_format_has_alpha (iter_format);

          iter = gegl_buffer_iterator_new (src_buffer, NULL, 0,
                                           iter_format,
                                           GEGL_ACCESS_READ, GEGL_ABYSS_NONE);

          gegl_buffer_iterator_add (iter, dest_buffer, NULL, 0,
                                    iter_format,
                                    GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);

          while (gegl_buffer_iterator_next (iter))
            {
              /*  lcms doesn't touch the alpha channel, simply
               *  copy everything to dest before the transform
               */
              if (layer_alpha)
                memcpy (iter->data[1], iter->data[0],
                        iter->length * layer_bpp);

              cmsDoTransform (transform,
                              iter->data[0], iter->data[1], iter->length);
            }

          g_object_unref (src_buffer);
          g_object_unref (dest_buffer);

          gimp_drawable_merge_shadow (layer_id, TRUE);
          gimp_drawable_update (layer_id, 0, 0, layer_width, layer_height);

          if (count++ % 32 == 0)
            {
              gimp_progress_update (progress_start +
                                    (gdouble) done /
                                    (layer_width * layer_height) * range);
            }

          cmsDeleteTransform (transform);
        }
    }
}
Beispiel #9
0
static inline gboolean
_gegl_buffer_cl_cache_flush2 (GeglTileHandlerCache *cache,
                              const GeglRectangle  *roi)
{
  size_t size;
  GList *elem;
  GeglRectangle tmp;
  cl_int cl_err = 0;

  gpointer data;
  gboolean need_cl = FALSE;

  for (elem=cache_entries; elem; elem=elem->next)
    {
      CacheEntry *entry = elem->data;

      if (entry->valid && entry->tile_storage->cache == cache
          && (!roi || gegl_rectangle_intersect (&tmp, roi, &entry->roi)))
        {
          entry->valid = FALSE;
          entry->used ++;

          gegl_cl_color_babl (entry->buffer->soft_format, &size);

          data = g_malloc(entry->roi.width * entry->roi.height * size);

          cl_err = gegl_clEnqueueReadBuffer(gegl_cl_get_command_queue(),
                                            entry->tex, CL_TRUE, 0, entry->roi.width * entry->roi.height * size, data,
                                            0, NULL, NULL);
          /* tile-ize */
          gegl_buffer_set (entry->buffer, &entry->roi, 0, entry->buffer->soft_format, data, GEGL_AUTO_ROWSTRIDE);

          entry->used --;
          need_cl = TRUE;

          g_free(data);

          CL_CHECK;
        }
    }

  if (need_cl)
    {
      cl_err = gegl_clFinish (gegl_cl_get_command_queue ());
      CL_CHECK;

      g_mutex_lock (&cache_mutex);

      while (cache_entry_find_invalid (&data))
        {
          CacheEntry *entry = data;

#if 1
          GEGL_NOTE (GEGL_DEBUG_OPENCL, "Removing from cl-cache: %p %s {%d %d %d %d}", entry->buffer, babl_get_name(entry->buffer->soft_format),
                                                                                       entry->roi.x, entry->roi.y, entry->roi.width, entry->roi.height);
#endif

          gegl_clReleaseMemObject(entry->tex);

          memset (entry, 0x0, sizeof (CacheEntry));

          g_slice_free (CacheEntry, data);
          cache_entries = g_list_remove (cache_entries, data);
        }

      g_mutex_unlock (&cache_mutex);
    }

  return TRUE;

error:

  g_mutex_lock (&cache_mutex);

  while (cache_entry_find_invalid (&data))
    {
      g_slice_free (CacheEntry, data);
      cache_entries = g_list_remove (cache_entries, data);
    }

  g_mutex_unlock (&cache_mutex);

  /* XXX : result is corrupted */
  return FALSE;
}
Beispiel #10
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;
}
Beispiel #11
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);
}
Beispiel #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' 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;
}
void
combine_paint_mask_to_canvas_mask (const GimpTempBuf *paint_mask,
                                   gint               mask_x_offset,
                                   gint               mask_y_offset,
                                   GeglBuffer        *canvas_buffer,
                                   gint               x_offset,
                                   gint               y_offset,
                                   gfloat             opacity,
                                   gboolean           stipple)
{
  GeglRectangle roi;
  GeglBufferIterator *iter;

  const gint mask_stride       = gimp_temp_buf_get_width (paint_mask);
  const gint mask_start_offset = mask_y_offset * mask_stride + mask_x_offset;
  const Babl *mask_format      = gimp_temp_buf_get_format (paint_mask);

  roi.x = x_offset;
  roi.y = y_offset;
  roi.width  = gimp_temp_buf_get_width (paint_mask) - mask_x_offset;
  roi.height = gimp_temp_buf_get_height (paint_mask) - mask_y_offset;

  iter = gegl_buffer_iterator_new (canvas_buffer, &roi, 0,
                                   babl_format ("Y float"),
                                   GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE);

  if (stipple)
    {
      if (mask_format == babl_format ("Y u8"))
        {
          const guint8 *mask_data = (const guint8 *) gimp_temp_buf_get_data (paint_mask);
          mask_data += mask_start_offset;

          while (gegl_buffer_iterator_next (iter))
            {
              gfloat *out_pixel = (gfloat *)iter->data[0];
              int iy, ix;

              for (iy = 0; iy < iter->roi[0].height; iy++)
                {
                  int mask_offset = (iy + iter->roi[0].y - roi.y) * mask_stride + iter->roi[0].x - roi.x;
                  const guint8 *mask_pixel = &mask_data[mask_offset];

                  for (ix = 0; ix < iter->roi[0].width; ix++)
                    {
                      out_pixel[0] += (1.0 - out_pixel[0]) * (*mask_pixel / 255.0f) * opacity;

                      mask_pixel += 1;
                      out_pixel  += 1;
                    }
                }
            }
        }
      else if (mask_format == babl_format ("Y float"))
        {
          const gfloat *mask_data = (const gfloat *) gimp_temp_buf_get_data (paint_mask);
          mask_data += mask_start_offset;

          while (gegl_buffer_iterator_next (iter))
            {
              gfloat *out_pixel = (gfloat *)iter->data[0];
              int iy, ix;

              for (iy = 0; iy < iter->roi[0].height; iy++)
                {
                  int mask_offset = (iy + iter->roi[0].y - roi.y) * mask_stride + iter->roi[0].x - roi.x;
                  const gfloat *mask_pixel = &mask_data[mask_offset];

                  for (ix = 0; ix < iter->roi[0].width; ix++)
                    {
                      out_pixel[0] += (1.0 - out_pixel[0]) * (*mask_pixel) * opacity;

                      mask_pixel += 1;
                      out_pixel  += 1;
                    }
                }
            }
        }
      else
        {
          g_warning("Mask format not supported: %s", babl_get_name (mask_format));
        }
    }
  else
    {
      if (mask_format == babl_format ("Y u8"))
        {
          const guint8 *mask_data = (const guint8 *) gimp_temp_buf_get_data (paint_mask);
          mask_data += mask_start_offset;

          while (gegl_buffer_iterator_next (iter))
            {
              gfloat *out_pixel = (gfloat *)iter->data[0];
              int iy, ix;

              for (iy = 0; iy < iter->roi[0].height; iy++)
                {
                  int mask_offset = (iy + iter->roi[0].y - roi.y) * mask_stride + iter->roi[0].x - roi.x;
                  const guint8 *mask_pixel = &mask_data[mask_offset];

                  for (ix = 0; ix < iter->roi[0].width; ix++)
                    {
                      if (opacity > out_pixel[0])
                        out_pixel[0] += (opacity - out_pixel[0]) * (*mask_pixel / 255.0f) * opacity;

                      mask_pixel += 1;
                      out_pixel  += 1;
                    }
                }
            }
        }
      else if (mask_format == babl_format ("Y float"))
        {
          const gfloat *mask_data = (const gfloat *) gimp_temp_buf_get_data (paint_mask);
          mask_data += mask_start_offset;

          while (gegl_buffer_iterator_next (iter))
            {
              gfloat *out_pixel = (gfloat *)iter->data[0];
              int iy, ix;

              for (iy = 0; iy < iter->roi[0].height; iy++)
                {
                  int mask_offset = (iy + iter->roi[0].y - roi.y) * mask_stride + iter->roi[0].x - roi.x;
                  const gfloat *mask_pixel = &mask_data[mask_offset];

                  for (ix = 0; ix < iter->roi[0].width; ix++)
                    {
                      if (opacity > out_pixel[0])
                        out_pixel[0] += (opacity - out_pixel[0]) * (*mask_pixel) * opacity;

                      mask_pixel += 1;
                      out_pixel  += 1;
                    }
                }
            }
        }
      else
        {
          g_warning("Mask format not supported: %s", babl_get_name (mask_format));
        }
    }
}
Beispiel #14
0
static gboolean
test_buffer_open (void)
{
  gboolean         result = TRUE;
  gchar           *tmpdir = NULL;
  gchar           *buf_a_path = NULL;
  GeglBuffer      *buf_a = NULL;
  const Babl      *format = babl_format ("R'G'B'A u8");
  GeglRectangle    roi = {0, 0, 128, 128};

  tmpdir = g_dir_make_tmp ("test-backend-file-XXXXXX", NULL);
  g_return_val_if_fail (tmpdir, FALSE);

  buf_a_path = g_build_filename (tmpdir, "buf_a.gegl", NULL);

  buf_a = g_object_new (GEGL_TYPE_BUFFER,
                        "format", format,
                        "path", buf_a_path,
                        "x", roi.x,
                        "y", roi.y,
                        "width", roi.width,
                        "height", roi.height,
                        NULL);

  gegl_buffer_flush (buf_a);
  g_object_unref (buf_a);

  buf_a = gegl_buffer_open (buf_a_path);

  if (!GEGL_IS_BUFFER (buf_a))
    {
      printf ("Failed to load file:%s\n",
              buf_a_path);
      result = FALSE;
    }

  if (!gegl_rectangle_equal (gegl_buffer_get_extent (buf_a), &roi))
    {
      printf ("Extent does not match:\n");
      gegl_rectangle_dump (gegl_buffer_get_extent (buf_a));
      gegl_rectangle_dump (&roi);
      result = FALSE;
    }

  if (gegl_buffer_get_format (buf_a) != format)
    {
      printf ("Formats do not match:\n%s\n%s\n",
        babl_get_name (gegl_buffer_get_format (buf_a)),
        babl_get_name (format));
      result = FALSE;
    }

  g_object_unref (buf_a);

  g_unlink (buf_a_path);
  g_remove (tmpdir);

  g_free (tmpdir);
  g_free (buf_a_path);

  return result;
}
Beispiel #15
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);

  if (o->buffer)
    {
      GeglBuffer *output = GEGL_BUFFER (o->buffer);
      const Babl *in_format = gegl_buffer_get_format (input);
      const Babl *out_format = gegl_buffer_get_format (output);

      if (gegl_operation_use_opencl (operation)
          && gegl_cl_color_supported (in_format, out_format) == GEGL_CL_COLOR_CONVERT)
        {
          size_t size;
          gboolean err;
          cl_int cl_err = 0;

          GeglBufferClIterator *i = gegl_buffer_cl_iterator_new (output,
                                                                 result,
                                                                 out_format,
                                                                 GEGL_CL_BUFFER_WRITE);

          gint read = gegl_buffer_cl_iterator_add (i,
                                                   input,
                                                   result,
                                                   out_format,
                                                   GEGL_CL_BUFFER_READ,
                                                   GEGL_ABYSS_NONE);

          gegl_cl_color_babl (out_format, &size);

          GEGL_NOTE (GEGL_DEBUG_OPENCL,
                     "write-buffer: "
                     "%p %p %s %s {%d %d %d %d}",
                     input,
                     output,
                     babl_get_name (in_format),
                     babl_get_name (out_format),
                     result->x,
                     result->y,
                     result->width,
                     result->height);

          while (gegl_buffer_cl_iterator_next (i, &err))
            {
              if (err) break;

              cl_err = gegl_clEnqueueCopyBuffer (gegl_cl_get_command_queue (),
                                                 i->tex[read],
                                                 i->tex[0],
                                                 0,
                                                 0,
                                                 i->size[0] * size,
                                                 0,
                                                 NULL,
                                                 NULL);

              if (cl_err != CL_SUCCESS)
                {
                  GEGL_NOTE (GEGL_DEBUG_OPENCL, "Error: %s", gegl_cl_errstring (cl_err));
                  break;
                }
            }

          if (cl_err || err)
            gegl_buffer_copy (input, result, output, result);
        }
      else
        gegl_buffer_copy (input, result, output, result);

      gegl_buffer_flush (output);
    }

  return TRUE;
}