static void
chroma_pre_process (const Babl   *format,
                    const gfloat *in,
                    const gfloat *layer,
                    gfloat       *out,
                    glong         samples)
{
  gfloat tmp[4 * samples], *layer_lab = tmp;
  gint   i;

  babl_process (babl_fish (format, "CIE Lab alpha float"), in, out, samples);
  babl_process (babl_fish (format, "CIE Lab alpha float"), layer, layer_lab, samples);

  for (i = 0; i < samples; ++i)
    {
      gfloat A1 = out[4 * i + 1];
      gfloat B1 = out[4 * i + 2];
      gfloat c1 = hypot (A1, B1);

      if (c1 != 0)
        {
          gfloat A2 = layer_lab[4 * i + 1];
          gfloat B2 = layer_lab[4 * i + 2];
          gfloat c2 = hypot (A2, B2);
          gfloat A  = c2 * A1 / c1;
          gfloat B  = c2 * B1 / c1;

          out[4 * i + 1] = A;
          out[4 * i + 2] = B;
        }
    }

  babl_process (babl_fish ("CIE Lab alpha float", format), out, out, samples);
}
Пример #2
0
static BablPalette *
make_pal (const Babl *pal_space, 
          const Babl *format, 
          const void *data, 
          int         count)
{
  BablPalette *pal = NULL;
  int bpp = babl_format_get_bytes_per_pixel (format);

  babl_assert (count > 0);

  pal = babl_malloc (sizeof (BablPalette));
  pal->count = count;
  pal->format = format;
  pal->data = babl_malloc (bpp * count);
  pal->data_double = babl_malloc (4 * sizeof(double) * count);
  pal->data_u8 = babl_malloc (4 * sizeof(char) * count);
  pal->radii = babl_malloc (sizeof (BablPaletteRadius) *
                            (pal->count - 1)           *
                            pal->count);

  memcpy (pal->data, data, bpp * count);

  babl_process (babl_fish (format, babl_format_with_space ("RGBA double", pal_space)),
                data, pal->data_double, count);
  babl_process (babl_fish (format, babl_format_with_space ("R'G'B'A u8", pal_space)),
                data, pal->data_u8, count);

  babl_palette_init_radii (pal);

  babl_palette_reset_hash (pal);

  return pal;
}
Пример #3
0
static void
init_path_instrumentation (FishPathInstrumentation *fpi,
                           Babl                    *fmt_source,
                           Babl                    *fmt_destination)
{
  long   ticks_start = 0;
  long   ticks_end   = 0;

  if (!fpi->fmt_rgba_double)
    {
      fpi->fmt_rgba_double = babl_format_new (
        babl_model ("RGBA"),
        babl_type ("double"),
        babl_component ("R"),
        babl_component ("G"),
        babl_component ("B"),
        babl_component ("A"),
        NULL);
    }

  if (!fpi->test)
    fpi->test = test_create (); // <- test_create utiliza var static dentro de la función

  fpi->fish_rgba_to_source      = babl_fish_reference (fpi->fmt_rgba_double,
                                                  fmt_source);
  fpi->fish_reference           = babl_fish_reference (fmt_source,
                                                  fmt_destination);
  fpi->fish_destination_to_rgba = babl_fish_reference (fmt_destination,
                                                  fpi->fmt_rgba_double);

  fpi->source                      = babl_calloc (NUM_TEST_PIXELS,
                                             fmt_source->format.bytes_per_pixel);
  fpi->destination                 = babl_calloc (NUM_TEST_PIXELS,
                                             fmt_destination->format.bytes_per_pixel);
  fpi->ref_destination             = babl_calloc (NUM_TEST_PIXELS,
                                             fmt_destination->format.bytes_per_pixel);
  fpi->destination_rgba_double     = babl_calloc (NUM_TEST_PIXELS,
                                             fpi->fmt_rgba_double->format.bytes_per_pixel);
  fpi->ref_destination_rgba_double = babl_calloc (NUM_TEST_PIXELS,
                                             fpi->fmt_rgba_double->format.bytes_per_pixel);

  /* create sourcebuffer from testbuffer in the correct format */
  babl_process (fpi->fish_rgba_to_source,
                fpi->test, fpi->source, NUM_TEST_PIXELS);

  /* calculate the reference buffer of how it should be */
  ticks_start = babl_ticks ();
  babl_process (fpi->fish_reference,
                fpi->source, fpi->ref_destination, NUM_TEST_PIXELS);
  ticks_end = babl_ticks ();
  fpi->reference_cost = babl_process_cost (ticks_start, ticks_end);

  /* transform the reference destination buffer to RGBA */
  babl_process (fpi->fish_destination_to_rgba,
                fpi->ref_destination, fpi->ref_destination_rgba_double, NUM_TEST_PIXELS);
}
Пример #4
0
static int
test (void)
{
  int   components;
  int   OK = 1;

  for (components = 1; components < 2048; components ++)
  {
    const Babl *fish;
    const Babl *src_fmt;
    const Babl *dst_fmt;
    int   i;

    src_fmt = babl_format_n (babl_type ("float"), components);
    dst_fmt = babl_format_n (babl_type ("u8"), components);

    fish = babl_fish (src_fmt, dst_fmt);

    babl_process (fish, source_buf, destination_buf, PIXELS);

    for (i = 0; i < PIXELS * components; i++)
      {
        if (abs (destination_buf[i] - reference_buf[i]) > TOLERANCE)
          {
            babl_log ("%i-components, pixel %i component %i is %i should be %i",
                      components, i / components, i % components, destination_buf[i], reference_buf[i]);
            OK = 0;
          }
      }
  }
  if (!OK)
    return -1;
  return 0;
}
Пример #5
0
static void
transfer_registration_color (GeglBuffer  *src,
                             GeglBuffer **dst,
                             gint         count)
{
  GimpRGB color, test;
  GeglBufferIterator *gi;
  const Babl *src_format, *dst_format;
  gint i, src_bpp, dst_bpp;
  gdouble white;

  gimp_context_get_foreground (&color);
  white = 1.0;

  src_format = gegl_buffer_get_format (src);
  src_bpp = babl_format_get_bytes_per_pixel (src_format);

  dst_format = gegl_buffer_get_format (dst[0]);
  dst_bpp = babl_format_get_bytes_per_pixel (dst_format);

  gi = gegl_buffer_iterator_new (src, NULL, 0, NULL,
                                 GEGL_BUFFER_READ, GEGL_ABYSS_NONE);

  for (i = 0; i < count; i++)
    {
      gegl_buffer_iterator_add (gi, dst[i], NULL, 0, NULL,
                                GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE);
    }

  while (gegl_buffer_iterator_next (gi))
    {
      guint j, k;
      gpointer src_data, dst_data[MAX_EXTRACT_IMAGES];

      src_data = gi->data[0];
      for (j = 0; j < count; j++)
        dst_data[j] = gi->data[j+1];

      for (k = 0; k < gi->length; k++)
        {
          gulong pos;
          pos = k * src_bpp;
          gimp_rgba_set_pixel (&test, src_format, ((guchar *)src_data) + pos);

          if (gimp_rgb_distance (&test, &color) < 1e-6)
            {
              for (j = 0; j < count; j++)
                {
                  gpointer data;
                  data = dst_data[j];
                  babl_process (babl_fish (babl_format ("Y double"), dst_format),
                                &white, (guchar *)data + (k * dst_bpp), 1);
                }
            }
        }
    }
}
Пример #6
0
void
gimp_operation_layer_mode_blend_luminance (const gfloat *in,
                                           const gfloat *layer,
                                           gfloat       *comp,
                                           gint          samples)
{
  static const Babl *fish;
  gfloat            *scratch;
  gfloat            *in_Y;
  gfloat            *layer_Y;

  if (! fish)
    fish = babl_fish ("RGBA float", "Y float");

  scratch = gegl_scratch_new (gfloat, 2 * samples);

  in_Y    = scratch;
  layer_Y = scratch + samples;

  babl_process (fish, in,    in_Y,    samples);
  babl_process (fish, layer, layer_Y, samples);

  while (samples--)
    {
      if (layer[ALPHA] != 0.0f && in[ALPHA] != 0.0f)
        {
          gfloat ratio = safe_div (layer_Y[0], in_Y[0]);
          gint   c;

          for (c = 0; c < 3; c ++)
            comp[c] = in[c] * ratio;
        }

      comp[ALPHA] = layer[ALPHA];

      comp    += 4;
      in      += 4;
      layer   += 4;
      in_Y    ++;
      layer_Y ++;
    }

  gegl_scratch_free (scratch);
}
Пример #7
0
static BablPalette *make_pal (const Babl *format, const void *data, int count)
{
  BablPalette *pal = NULL;
  int bpp = babl_format_get_bytes_per_pixel (format);

  pal = babl_malloc (sizeof (BablPalette));
  pal->count = count;
  pal->format = format;
  pal->data = babl_malloc (bpp * count);
  pal->data_double = babl_malloc (4 * sizeof(double) * count);
  pal->data_u8 = babl_malloc (4 * sizeof(char) * count);
  memcpy (pal->data, data, bpp * count);

  babl_process (babl_fish (format, babl_format ("RGBA double")),
                data, pal->data_double, count);
  babl_process (babl_fish (format, babl_format ("RGBA u8")),
                data, pal->data_u8, count);

  babl_palette_reset_hash (pal);

  return pal;
}
static void
color_pre_process (const Babl   *format,
                   const gfloat *in,
                   const gfloat *layer,
                   gfloat       *out,
                   glong         samples)
{
    gfloat tmp[4 * samples], *layer_lab = tmp;
    gint   i;

    babl_process (babl_fish (format, "CIE L alpha float"), in, &out[2 * samples], samples);
    babl_process (babl_fish (format, "CIE Lab alpha float"), layer, layer_lab, samples);

    for (i = 0; i < samples; ++i)
    {
        out[4 * i + 0] = out[2 * samples + 2 * i + 0];
        out[4 * i + 1] = layer_lab[4 * i + 1];
        out[4 * i + 2] = layer_lab[4 * i + 2];
        out[4 * i + 3] = out[2 * samples + 2 * i + 1];
    }

    babl_process (babl_fish ("CIE Lab alpha float", format), out, out, samples);
}
Пример #9
0
static int
test (void)
{
  const Babl *fish;
  int   i;
  int   OK = 1;


  fish = babl_fish (
    babl_format_new (
      babl_model ("Y"),
      babl_type ("float"),
      babl_component ("Y"),
      NULL
    ),
    babl_format_new (
      babl_model ("RGB"),
      babl_type ("float"),
      babl_component ("R"),
      babl_component ("G"),
      babl_component ("B"),
      NULL
    )
         );

  babl_process (fish,
                grayscale_buf, rgb_buf,
                PIXELS);

  for (i = 0; i < PIXELS * 3; i++)
    {
      if (rgb_buf[i] != rgb_buf_ref[i])
        {
          babl_log ("index %i is problematic : %f instead of %f",
                    i, rgb_buf[i], rgb_buf_ref[i]);
          OK = 0;
        }
    }
  if (!OK)
    return -1;
  return 0;
}
Пример #10
0
static BablPalette *
default_palette (void)
{
  static BablPalette pal;
  static int inited = 0;

  babl_mutex_lock (babl_format_mutex);

  if (inited)
    {
      babl_mutex_unlock (babl_format_mutex);

      return &pal;
    }

  init_ceil_sqrt_u8 ();

  memset (&pal, 0, sizeof (pal));
  pal.count = 16;
  pal.format = babl_format ("R'G'B'A u8"); /* dynamically generated, so
                                              the default palette can
                                              not be fully static.
                                            */
  pal.data = defpal_data;
  pal.data_double = defpal_double;
  pal.data_u8 = defpal_data;
  pal.radii = defpal_radii;

  babl_process (babl_fish (pal.format, babl_format ("RGBA double")),
                pal.data, pal.data_double, pal.count);

  babl_palette_init_radii (&pal);

  babl_palette_reset_hash (&pal);

  inited = 1;

  babl_mutex_unlock (babl_format_mutex);

  return &pal;
}
Пример #11
0
static int
test (void)
{
  const Babl *fish;
  int   i;
  int   OK = 1;

  fish = babl_fish (
    babl_format_new (
      babl_model ("RGB"),
      babl_type ("u8"),
      babl_component ("R"),
      babl_component ("G"),
      babl_component ("B"),
      NULL
    ),
    babl_format_new (
      babl_model ("RGB"),
      babl_type ("u8"),
      babl_component ("B"),
      babl_component ("G"),
      babl_component ("R"),
      NULL
    )
         );

  babl_process (fish, source_buf, destination_buf, PIXELS);

  for (i = 0; i < PIXELS * 3; i++)
    {
      if (abs (destination_buf[i] - reference_buf[i]) > TOLERANCE)
        {
          babl_log ("%2i (%2i%%3=%i, %2i/3=%i) is %i should be %i",
                    i, i, i % 3, i, i / 3, destination_buf[i], reference_buf[i]);
          OK = 0;
        }
    }
  if (!OK)
    return -1;
  return 0;
}
Пример #12
0
static int
test (void)
{
  int i;
  int OK = 1;

  babl_process (babl_fish (babl_format_with_space ("R'G'B' u8", babl_space("Apple")), "R'G'B' u8"),
                source_buf, destination_buf,
                PIXELS);

  for (i = 0; i < PIXELS * 3; i++)
    {
      if (abs (destination_buf[i] - reference_buf[i]) > TOLERANCE)
        {
          babl_log ("%2i (%2i%%3=%i, %2i/3=%i) is %i should be %i",
                    i, i, i % 3, i, i / 3, destination_buf[i], reference_buf[i]);
          OK = 0;
        }
    }
  if (!OK)
    return -1;
  return 0;
}
Пример #13
0
static BablPalette *default_palette (void)
{
  static BablPalette pal;
  static int inited = 0;
  if (inited)
    return &pal;
  memset (&pal, 0, sizeof (pal));
  inited = 1;
  pal.count = 16;
  pal.format = babl_format ("RGBA u8"); /* dynamically generated, so
                                           the default palette can
                                           not be fully static.
                                         */
  pal.data = defpal_data;
  pal.data_double = defpal_double;
  pal.data_u8 = defpal_data;

  babl_process (babl_fish (pal.format, babl_format ("RGBA double")),
                pal.data, pal.data_double, pal.count);

  babl_palette_reset_hash (&pal);
  return &pal;
}
Пример #14
0
/*
  Returns 2048 samples of the gradient.
  Each sample is (R'G'B'A float) or (Y'A float), depending on the drawable
 */
static gdouble *
get_samples_gradient (gint32 drawable_id)
{
  gchar   *gradient_name;
  gint     n_d_samples;
  gdouble *d_samples = NULL;

  gradient_name = gimp_context_get_gradient ();

  /* FIXME: "reverse" hardcoded to FALSE. */
  gimp_gradient_get_uniform_samples (gradient_name, NSAMPLES, FALSE,
                                     &n_d_samples, &d_samples);
  g_free (gradient_name);

  if (!gimp_drawable_is_rgb (drawable_id))
    {
      const Babl *format_src = babl_format ("R'G'B'A double");
      const Babl *format_dst = babl_format ("Y'A double");
      const Babl *fish = babl_fish (format_src, format_dst);
      babl_process (fish, d_samples, d_samples, NSAMPLES);
    }

  return d_samples;
}
Пример #15
0
static void
gimp_view_render_temp_buf_to_surface (GimpViewRenderer *renderer,
                                      GtkWidget        *widget,
                                      GimpTempBuf      *temp_buf,
                                      gint              temp_buf_x,
                                      gint              temp_buf_y,
                                      gint              channel,
                                      GimpViewBG        inside_bg,
                                      GimpViewBG        outside_bg,
                                      cairo_surface_t  *surface,
                                      gint              surface_width,
                                      gint              surface_height)
{
  cairo_t    *cr;
  gint        x, y;
  gint        width, height;
  const Babl *temp_buf_format;
  gint        temp_buf_width;
  gint        temp_buf_height;

  g_return_if_fail (temp_buf != NULL);
  g_return_if_fail (surface != NULL);

  temp_buf_format = gimp_temp_buf_get_format (temp_buf);
  temp_buf_width  = gimp_temp_buf_get_width  (temp_buf);
  temp_buf_height = gimp_temp_buf_get_height (temp_buf);

  /*  Here are the different cases this functions handles correctly:
   *  1)  Offset temp_buf which does not necessarily cover full image area
   *  2)  Color conversion of temp_buf if it is gray and image is color
   *  3)  Background check buffer for transparent temp_bufs
   *  4)  Using the optional "channel" argument, one channel can be extracted
   *      from a multi-channel temp_buf and composited as a grayscale
   *  Prereqs:
   *  1)  Grayscale temp_bufs have bytes == {1, 2}
   *  2)  Color temp_bufs have bytes == {3, 4}
   *  3)  If image is gray, then temp_buf should have bytes == {1, 2}
   */

  cr = cairo_create (surface);

  if (outside_bg == GIMP_VIEW_BG_CHECKS ||
      inside_bg  == GIMP_VIEW_BG_CHECKS)
    {
      if (! renderer->pattern)
        renderer->pattern =
          gimp_cairo_checkerboard_create (cr, GIMP_CHECK_SIZE_SM,
                                          gimp_render_light_check_color (),
                                          gimp_render_dark_check_color ());
    }

  switch (outside_bg)
    {
    case GIMP_VIEW_BG_CHECKS:
      cairo_set_source (cr, renderer->pattern);
      break;

    case GIMP_VIEW_BG_WHITE:
      cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
      break;
    }

  cairo_paint (cr);

  if (! gimp_rectangle_intersect (0, 0,
                                  surface_width, surface_height,
                                  temp_buf_x, temp_buf_y,
                                  temp_buf_width, temp_buf_height,
                                  &x, &y,
                                  &width, &height))
    {
      cairo_destroy (cr);
      return;
    }

  if (inside_bg != outside_bg &&
      babl_format_has_alpha (temp_buf_format) && channel == -1)
    {
      cairo_rectangle (cr, x, y, width, height);

      switch (inside_bg)
        {
        case GIMP_VIEW_BG_CHECKS:
          cairo_set_source (cr, renderer->pattern);
          break;

        case GIMP_VIEW_BG_WHITE:
          cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
          break;
        }

      cairo_fill (cr);
    }

  if (babl_format_has_alpha (temp_buf_format) && channel == -1)
    {
      GeglBuffer      *src_buffer;
      GeglBuffer      *dest_buffer;
      cairo_surface_t *alpha_surface;

      alpha_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
                                                  width, height);

      src_buffer  = gimp_temp_buf_create_buffer (temp_buf);
      dest_buffer = gimp_cairo_surface_create_buffer (alpha_surface);

      if (! renderer->profile_transform)
        gimp_view_renderer_transform_create (renderer, widget,
                                             src_buffer, dest_buffer);

      if (renderer->profile_transform)
        {
          gimp_gegl_convert_color_transform (src_buffer,
                                             GEGL_RECTANGLE (x - temp_buf_x,
                                                             y - temp_buf_y,
                                                             width, height),
                                             renderer->profile_src_format,
                                             dest_buffer,
                                             GEGL_RECTANGLE (0, 0, 0, 0),
                                             renderer->profile_dest_format,
                                             renderer->profile_transform);
        }
      else
        {
          gegl_buffer_copy (src_buffer,
                            GEGL_RECTANGLE (x - temp_buf_x,
                                            y - temp_buf_y,
                                            width, height),
                            GEGL_ABYSS_NONE,
                            dest_buffer,
                            GEGL_RECTANGLE (0, 0, 0, 0));
        }

      g_object_unref (src_buffer);
      g_object_unref (dest_buffer);

      cairo_surface_mark_dirty (alpha_surface);

      cairo_translate (cr, x, y);
      cairo_rectangle (cr, 0, 0, width, height);
      cairo_set_source_surface (cr, alpha_surface, 0, 0);
      cairo_fill (cr);

      cairo_surface_destroy (alpha_surface);
    }
  else if (channel == -1)
    {
      GeglBuffer *src_buffer;
      GeglBuffer *dest_buffer;

      cairo_surface_flush (surface);

      src_buffer  = gimp_temp_buf_create_buffer (temp_buf);
      dest_buffer = gimp_cairo_surface_create_buffer (surface);

      if (! renderer->profile_transform)
        gimp_view_renderer_transform_create (renderer, widget,
                                             src_buffer, dest_buffer);

      if (renderer->profile_transform)
        {
          gimp_gegl_convert_color_transform (src_buffer,
                                             GEGL_RECTANGLE (x - temp_buf_x,
                                                             y - temp_buf_y,
                                                             width, height),
                                             renderer->profile_src_format,
                                             dest_buffer,
                                             GEGL_RECTANGLE (x, y, 0, 0),
                                             renderer->profile_dest_format,
                                             renderer->profile_transform);
        }
      else
        {
          gegl_buffer_copy (src_buffer,
                            GEGL_RECTANGLE (x - temp_buf_x,
                                            y - temp_buf_y,
                                            width, height),
                            GEGL_ABYSS_NONE,
                            dest_buffer,
                            GEGL_RECTANGLE (x, y, 0, 0));
        }

      g_object_unref (src_buffer);
      g_object_unref (dest_buffer);

      cairo_surface_mark_dirty (surface);
    }
  else
    {
      const Babl   *fish;
      const guchar *src;
      guchar       *dest;
      gint          dest_stride;
      gint          bytes;
      gint          rowstride;
      gint          i;

      cairo_surface_flush (surface);

      bytes     = babl_format_get_bytes_per_pixel (temp_buf_format);
      rowstride = temp_buf_width * bytes;

      src = gimp_temp_buf_get_data (temp_buf) + ((y - temp_buf_y) * rowstride +
                                                 (x - temp_buf_x) * bytes);

      dest        = cairo_image_surface_get_data (surface);
      dest_stride = cairo_image_surface_get_stride (surface);

      dest += y * dest_stride + x * 4;

      fish = babl_fish (temp_buf_format,
                        babl_format ("cairo-RGB24"));

      for (i = y; i < (y + height); i++)
        {
          const guchar *s = src;
          guchar       *d = dest;
          gint          j;

          for (j = x; j < (x + width); j++, d += 4, s += bytes)
            {
              if (bytes > 2)
                {
                  guchar pixel[4] = { s[channel], s[channel], s[channel], 255 };

                  babl_process (fish, pixel, d, 1);
                }
              else
                {
                  guchar pixel[2] = { s[channel], 255 };

                  babl_process (fish, pixel, d, 1);
                }
            }

          src += rowstride;
          dest += dest_stride;
        }

      cairo_surface_mark_dirty (surface);
    }

  cairo_destroy (cr);
}
Пример #16
0
static void
get_path_instrumentation (FishPathInstrumentation *fpi,
                          BablList                *path,
                          double                  *path_cost,
                          double                  *ref_cost,
                          double                  *path_error)
{
  long   ticks_start = 0;
  long   ticks_end   = 0;

  Babl *babl_source = fpi->source;
  Babl *babl_destination = fpi->destination;

  int source_bpp = 0;
  int dest_bpp = 0;

  switch (babl_source->instance.class_type)
    {
      case BABL_FORMAT:
        source_bpp = babl_source->format.bytes_per_pixel;
        break;
      case BABL_TYPE:
        source_bpp = babl_source->type.bits / 8;
        break;
      default:
        babl_log ("=eeek{%i}\n", babl_source->instance.class_type - BABL_MAGIC);
    }

  switch (babl_destination->instance.class_type)
    {
      case BABL_FORMAT:
        dest_bpp = babl_destination->format.bytes_per_pixel;
        break;
      case BABL_TYPE:
        dest_bpp = babl_destination->type.bits / 8;
        break;
      default:
        babl_log ("-eeek{%i}\n", babl_destination->instance.class_type - BABL_MAGIC);
     }

  if (!fpi->init_instrumentation_done)
    {
      /* this initialization can be done only once since the
       * source and destination formats do not change during
       * the search */
      init_path_instrumentation (fpi, babl_source, babl_destination);
      fpi->init_instrumentation_done = 1;
    }

  /* calculate this path's view of what the result should be */
  ticks_start = babl_ticks ();
  process_conversion_path (path, fpi->source, source_bpp, fpi->destination, dest_bpp, NUM_TEST_PIXELS);
  ticks_end = babl_ticks ();
  *path_cost = babl_process_cost (ticks_start, ticks_end);

  /* transform the reference and the actual destination buffers to RGBA
   * for comparison with each other
   */
  babl_process (fpi->fish_destination_to_rgba,
                fpi->destination, fpi->destination_rgba_double, NUM_TEST_PIXELS);

  *path_error = babl_rel_avg_error (fpi->destination_rgba_double,
                                    fpi->ref_destination_rgba_double,
                                    NUM_TEST_PIXELS * 4);

#if 0
  fpi->fish_rgba_to_source->fish.processings--;
  fpi->fish_reference->fish.processings--;
  fpi->fish_destination_to_rgba->fish.processings -= 2;

  fpi->fish_rgba_to_source->fish.pixels      -= NUM_TEST_PIXELS;
  fpi->fish_reference->fish.pixels           -= NUM_TEST_PIXELS;
  fpi->fish_destination_to_rgba->fish.pixels -= 2 * NUM_TEST_PIXELS;
#endif

  *ref_cost = fpi->reference_cost;
}
Пример #17
0
/**
 * gimp_color_transform_process_buffer:
 * @transform:
 * @src_format:
 * @src_rect:
 * @dest_format:
 * @dest_rect:
 *
 * This function transforms buffer into another buffer.
 *
 * Since: 2.10
 **/
void
gimp_color_transform_process_buffer (GimpColorTransform  *transform,
                                     GeglBuffer          *src_buffer,
                                     const GeglRectangle *src_rect,
                                     GeglBuffer          *dest_buffer,
                                     const GeglRectangle *dest_rect)
{
  GimpColorTransformPrivate *priv;
  GeglBufferIterator        *iter;
  gint                       total_pixels;
  gint                       done_pixels = 0;

  g_return_if_fail (GIMP_IS_COLOR_TRANSFORM (transform));
  g_return_if_fail (GEGL_IS_BUFFER (src_buffer));
  g_return_if_fail (GEGL_IS_BUFFER (dest_buffer));

  priv = transform->priv;

  if (src_rect)
    {
      total_pixels = src_rect->width * src_rect->height;
    }
  else
    {
      total_pixels = (gegl_buffer_get_width  (src_buffer) *
                      gegl_buffer_get_height (src_buffer));
    }

  if (src_buffer != dest_buffer)
    {
      const Babl *fish = NULL;

      if (babl_format_has_alpha (priv->dest_format))
        fish = babl_fish (priv->src_format,
                          priv->dest_format);

      iter = gegl_buffer_iterator_new (src_buffer, src_rect, 0,
                                       priv->src_format,
                                       GEGL_ACCESS_READ,
                                       GEGL_ABYSS_NONE);

      gegl_buffer_iterator_add (iter, dest_buffer, dest_rect, 0,
                                priv->dest_format,
                                GEGL_ACCESS_WRITE,
                                GEGL_ABYSS_NONE);

      while (gegl_buffer_iterator_next (iter))
        {
          /* make sure the alpha channel is copied too, lcms doesn't copy it */
          if (fish)
            babl_process (fish, iter->data[0], iter->data[1], iter->length);

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

          done_pixels += iter->roi[0].width * iter->roi[0].height;

          g_signal_emit (transform, gimp_color_transform_signals[PROGRESS], 0,
                         (gdouble) done_pixels /
                         (gdouble) total_pixels);
        }
    }
  else
    {
      iter = gegl_buffer_iterator_new (src_buffer, src_rect, 0,
                                       priv->src_format,
                                       GEGL_ACCESS_READWRITE,
                                       GEGL_ABYSS_NONE);

      while (gegl_buffer_iterator_next (iter))
        {
          cmsDoTransform (priv->transform,
                          iter->data[0], iter->data[0], iter->length);

          done_pixels += iter->roi[0].width * iter->roi[0].height;

          g_signal_emit (transform, gimp_color_transform_signals[PROGRESS], 0,
                         (gdouble) done_pixels /
                         (gdouble) total_pixels);
        }
    }

  g_signal_emit (transform, gimp_color_transform_signals[PROGRESS], 0,
                 1.0);
}
Пример #18
0
/**
 * gimp_color_transform_process_pixels:
 * @transform:
 * @src_format:
 * @src_pixels:
 * @dest_format:
 * @dest_pixels:
 * @length:
 *
 * This function transforms a contiguous line of pixels.
 *
 * Since: 2.10
 **/
void
gimp_color_transform_process_pixels (GimpColorTransform *transform,
                                     const Babl         *src_format,
                                     gconstpointer       src_pixels,
                                     const Babl         *dest_format,
                                     gpointer            dest_pixels,
                                     gsize               length)
{
  GimpColorTransformPrivate *priv;
  gpointer                  *src;
  gpointer                  *dest;

  g_return_if_fail (GIMP_IS_COLOR_TRANSFORM (transform));
  g_return_if_fail (src_format != NULL);
  g_return_if_fail (src_pixels != NULL);
  g_return_if_fail (dest_format != NULL);
  g_return_if_fail (dest_pixels != NULL);

  priv = transform->priv;

  if (src_format != priv->src_format)
    {
      src = g_malloc (length * babl_format_get_bytes_per_pixel (priv->src_format));

      babl_process (babl_fish (src_format,
                               priv->src_format),
                    src_pixels, src, length);
    }
  else
    {
      src = (gpointer) src_pixels;
    }

  if (dest_format != priv->dest_format)
    {
      dest = g_malloc (length * babl_format_get_bytes_per_pixel (priv->dest_format));
    }
  else
    {
      dest = dest_pixels;
    }

  /* copy the alpha channel */
  if (src != dest && babl_format_has_alpha (dest_format))
    babl_process (babl_fish (src_format,
                             priv->dest_format),
                  src, dest, length);

  cmsDoTransform (priv->transform, src, dest, length);

  if (src_format != priv->src_format)
    {
      g_free (src);
    }

  if (dest_format != priv->dest_format)
    {
      babl_process (babl_fish (priv->dest_format,
                               dest_format),
                    dest, dest_pixels, length);

      g_free (dest);
    }
}
Пример #19
0
static void inline
gegl_sampler_get_pixel (GeglSampler    *sampler,
                        gint            x,
                        gint            y,
                        gpointer        data,
                        GeglAbyssPolicy repeat_mode)
{
  GeglSamplerNearest *nearest_sampler = (GeglSamplerNearest*)(sampler);
  GeglBuffer *buffer = sampler->buffer;
  const GeglRectangle *abyss = &buffer->abyss;
  guchar              *buf   = data;

  if (y <  abyss->y ||
      x <  abyss->x ||
      y >= abyss->y + abyss->height ||
      x >= abyss->x + abyss->width)
    {
      switch (repeat_mode)
      {
        case GEGL_ABYSS_CLAMP:
          x = CLAMP (x, abyss->x, abyss->x+abyss->width-1);
          y = CLAMP (y, abyss->y, abyss->y+abyss->height-1);
          break;

        case GEGL_ABYSS_LOOP:
          x = abyss->x + GEGL_REMAINDER (x - abyss->x, abyss->width);
          y = abyss->y + GEGL_REMAINDER (y - abyss->y, abyss->height);
          break;

        case GEGL_ABYSS_BLACK:
          {
            gfloat color[4] = {0.0, 0.0, 0.0, 1.0};
            babl_process (babl_fish (gegl_babl_rgba_linear_float (), sampler->format),
                          color,
                          buf,
                          1);
            return;
          }

        case GEGL_ABYSS_WHITE:
          {
            gfloat color[4] = {1.0, 1.0, 1.0, 1.0};
            babl_process (babl_fish (gegl_babl_rgba_linear_float (),
                                     sampler->format),
                          color,
                          buf,
                          1);
            return;
          }

        default:
        case GEGL_ABYSS_NONE:
          memset (buf, 0x00, babl_format_get_bytes_per_pixel (sampler->format));
          return;
      }
    }

  gegl_buffer_lock (sampler->buffer);

  {
    gint tile_width  = buffer->tile_width;
    gint tile_height = buffer->tile_height;
    gint tiledy      = y + buffer->shift_y;
    gint tiledx      = x + buffer->shift_x;
    gint indice_x    = gegl_tile_indice (tiledx, tile_width);
    gint indice_y    = gegl_tile_indice (tiledy, tile_height);

    GeglTile *tile = nearest_sampler->hot_tile;

    if (!(tile &&
          tile->x == indice_x &&
          tile->y == indice_y))
      {
        if (gegl_config_threads()>1)
          g_rec_mutex_lock (&buffer->tile_storage->mutex);

        if (tile)
          gegl_tile_unref (tile);

        tile = gegl_tile_source_get_tile ((GeglTileSource *) (buffer),
                                          indice_x, indice_y,
                                          0);
        nearest_sampler->hot_tile = tile;

        if (gegl_config_threads()>1)
          g_rec_mutex_unlock (&buffer->tile_storage->mutex);
      }

    if (tile)
      {
        gint tile_origin_x = indice_x * tile_width;
        gint tile_origin_y = indice_y * tile_height;
        gint       offsetx = tiledx - tile_origin_x;
        gint       offsety = tiledy - tile_origin_y;

        guchar *tp = gegl_tile_get_data (tile) + (offsety * tile_width + offsetx) * nearest_sampler->buffer_bpp;

        babl_process (sampler->fish, tp, buf, 1);
      }
  }

  gegl_buffer_unlock (sampler->buffer);
}
Пример #20
0
static void
gimp_color_frame_update (GimpColorFrame *frame)
{
  const gchar  *names[GIMP_COLOR_FRAME_ROWS]  = { NULL, };
  gchar       **values = NULL;
  gboolean      has_alpha;
  gint          i;

  has_alpha = babl_format_has_alpha (frame->sample_format);

  if (frame->sample_valid)
    {
      gimp_color_area_set_color (GIMP_COLOR_AREA (frame->color_area),
                                 &frame->color);
    }

  switch (frame->frame_mode)
    {
    case GIMP_COLOR_FRAME_MODE_PIXEL:
      {
        GimpImageBaseType base_type;

        base_type = gimp_babl_format_get_base_type (frame->sample_format);

        if (frame->sample_valid)
          {
            const Babl *print_format = NULL;
            guchar      print_pixel[32];

            switch (gimp_babl_format_get_precision (frame->sample_format))
              {
              case GIMP_PRECISION_U8_GAMMA:
                if (babl_format_is_palette (frame->sample_format))
                  {
                    print_format = gimp_babl_format (GIMP_RGB,
                                                     GIMP_PRECISION_U8_GAMMA,
                                                     has_alpha);
                    break;
                  }
                /* 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:
              case GIMP_PRECISION_DOUBLE_LINEAR:
              case GIMP_PRECISION_DOUBLE_GAMMA:
                print_format = frame->sample_format;
                break;

              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_LINEAR,
                                                 has_alpha);
                break;
              }

            if (frame->sample_average)
              {
                /* FIXME: this is broken: can't use the averaged sRGB GimpRGB
                 * value for displaying pixel values when color management
                 * is enabled
                 */
                gimp_rgba_get_pixel (&frame->color, print_format, print_pixel);
              }
            else
              {
                babl_process (babl_fish (frame->sample_format, print_format),
                              frame->pixel, print_pixel, 1);
              }

            values = gimp_babl_print_pixel (print_format, print_pixel);
          }

        if (base_type == GIMP_GRAY)
          {
            names[0] = _("Value:");

            if (has_alpha)
              names[1] = _("Alpha:");
          }
        else
          {
            names[0] = _("Red:");
            names[1] = _("Green:");
            names[2] = _("Blue:");

            if (has_alpha)
              names[3] = _("Alpha:");

            if (babl_format_is_palette (frame->sample_format))
              {
                names[4] = _("Index:");

                if (frame->sample_valid)
                  {
                    gchar **v   = g_new0 (gchar *, 6);
                    gchar **tmp = values;

                    memcpy (v, values, 4 * sizeof (gchar *));
                    values = v;

                    g_free (tmp);

                    if (! frame->sample_average)
                      values[4] = g_strdup_printf ("%d", frame->pixel[0]);
                  }
              }
          }
      }
Пример #21
0
void
gegl_sampler_cubic_get (GeglSampler *self,
                        gdouble      x,
                        gdouble      y,
                        void        *output)
{
  GeglSamplerCubic *cubic = (GeglSamplerCubic*)(self);
  GeglRectangle     context_rect;
  const gint        offsets[16]={-4-64*4, 4, 4, 4,
                                (64-3)*4, 4, 4, 4,
                                (64-3)*4, 4, 4, 4,
                                (64-3)*4, 4, 4, 4};
  gfloat           *sampler_bptr;
  gfloat            factor;

#ifdef HAS_G4FLOAT
  g4float            newval4 = g4float_zero;
  gfloat            *newval = &newval4;
#else
  gfloat             newval[4] = {0.0, 0.0, 0.0, 0.0};
#endif

  gint              u,v;
  gint              dx,dy;
  gint              i;

  context_rect = self->context_rect;
  dx = (gint) x;
  dy = (gint) y;
  sampler_bptr = gegl_sampler_get_ptr (self, dx, dy);

#ifdef HAS_G4FLOAT
  if (G_LIKELY (gegl_cpu_accel_get_support () & (GEGL_CPU_ACCEL_X86_SSE|
                                                 GEGL_CPU_ACCEL_X8&_MMX)))
    {
      for (v=dy+context_rect.y, i=0; v < dy+context_rect.y+context_rect.height ; v++)
        for (u=dx+context_rect.x ; u < dx+context_rect.x+context_rect.width  ; u++, i++)
          {
            sampler_bptr += offsets[i];
            factor = cubicKernel (y - v, cubic->b, cubic->c) *
                     cubicKernel (x - u, cubic->b, cubic->c);
            newval4 += g4float_mul(&sampler_bptr[0], factor);
           }
     }
   else
#endif
     {
       for (v=dy+context_rect.y, i=0; v < dy+context_rect.y+context_rect.height ; v++)
         for (u=dx+context_rect.x ; u < dx+context_rect.x+context_rect.width  ; u++, i++)
           {
             /*sampler_bptr = gegl_sampler_get_from_buffer (self, u, v);*/
             sampler_bptr += offsets[i];
             factor = cubicKernel (y - v, cubic->b, cubic->c) *
                      cubicKernel (x - u, cubic->b, cubic->c);

            newval[0] += factor * sampler_bptr[0];
            newval[1] += factor * sampler_bptr[1];
            newval[2] += factor * sampler_bptr[2];
            newval[3] += factor * sampler_bptr[3];
           }
     }

  babl_process (self->fish, newval, output, 1);
}
Пример #22
0
void
gegl_sampler_lanczos_get (GeglSampler *self,
                          gdouble      x,
                          gdouble      y,
                          GeglMatrix2 *scale,
                          void        *output)
{
  GeglSamplerLanczos      *lanczos      = GEGL_SAMPLER_LANCZOS (self);
  GeglRectangle            context_rect = self->context_rect[0];
  gfloat                  *sampler_bptr;
  gdouble                  x_sum, y_sum;
  gfloat                   newval[4] = {0.0, 0.0, 0.0, 0.0};
  gint                     i, j;
  gint                     spp    = lanczos->lanczos_spp;
  gint                     width  = lanczos->lanczos_width;
  gint                     width2 = context_rect.width;
  gint                     dx,dy;
  gint                     u,v;

  /* FIXME: move the initialization of these arrays into the _prepare function
   * to speed up actual resampling
   */
  gfloat                  *x_kernel, /* 1-D kernels of Lanczos window coeffs */
                          *y_kernel;

  x_kernel = g_newa (gfloat, width2);
  y_kernel = g_newa (gfloat, width2);

  self->interpolate_format = babl_format ("RaGaBaA float");

  dx = (gint) ((x - ((gint) x)) * spp + 0.5);
  dy = (gint) ((y - ((gint) y)) * spp + 0.5);
  /* fill 1D kernels */
  for (x_sum = y_sum = 0.0, i = width; i >= -width; i--)
    {
      gint pos    = i * spp;
      x_sum += x_kernel[width + i] = lanczos->lanczos_lookup[ABS (dx - pos)];
      y_sum += y_kernel[width + i] = lanczos->lanczos_lookup[ABS (dy - pos)];
    }

  /* normalise the weighted arrays */
  for (i = 0; i < width2; i++)
    {
      x_kernel[i] /= x_sum;
      y_kernel[i] /= y_sum;
    }

  dx = (gint) x;
  dy = (gint) y;
  for (v=dy+context_rect.y, j = 0; v < dy+context_rect.y+context_rect.height; j++, v++)
    for (u=dx+context_rect.x, i = 0; u < dx+context_rect.x+context_rect.width; i++, u++)
      {
         sampler_bptr = gegl_sampler_get_from_buffer (self, u, v);
         newval[0] += y_kernel[j] * x_kernel[i] * sampler_bptr[0];
         newval[1] += y_kernel[j] * x_kernel[i] * sampler_bptr[1];
         newval[2] += y_kernel[j] * x_kernel[i] * sampler_bptr[2];
         newval[3] += y_kernel[j] * x_kernel[i] * sampler_bptr[3];
      }

  babl_process (self->fish, newval, output, 1);
}