Esempio n. 1
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);
}
Esempio n. 2
0
static GimpTempBuf *
gimp_buffer_get_new_preview (GimpViewable *viewable,
                             GimpContext  *context,
                             gint          width,
                             gint          height)
{
  GimpBuffer  *buffer = GIMP_BUFFER (viewable);
  const Babl  *format = gimp_buffer_get_format (buffer);
  GimpTempBuf *preview;

  if (babl_format_is_palette (format))
    format = gimp_babl_format (GIMP_RGB, GIMP_PRECISION_U8_GAMMA,
                               babl_format_has_alpha (format));
  else
    format = gimp_babl_format (gimp_babl_format_get_base_type (format),
                               gimp_babl_precision (GIMP_COMPONENT_TYPE_U8,
                                                    gimp_babl_format_get_linear (format)),
                               babl_format_has_alpha (format));

  preview = gimp_temp_buf_new (width, height, format);

  gegl_buffer_get (buffer->buffer, GEGL_RECTANGLE (0, 0, width, height),
                   MIN ((gdouble) width  / (gdouble) gimp_buffer_get_width (buffer),
                        (gdouble) height / (gdouble) gimp_buffer_get_height (buffer)),
                   format,
                   gimp_temp_buf_get_data (preview),
                   GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

  return preview;
}
Esempio n. 3
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);
}
Esempio n. 4
0
const Babl *
gimp_babl_compat_u8_format (const Babl *format)
{
  g_return_val_if_fail (format != NULL, NULL);

  /*  indexed images only exist in u8, return the same format  */
  if (babl_format_is_palette (format))
    return format;

  return gimp_babl_format (gimp_babl_format_get_base_type (format),
                           GIMP_PRECISION_U8,
                           babl_format_has_alpha (format));
}
Esempio n. 5
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);
}
static const Babl *
choose_format (GeglBuffer          *buffer,
               GimpSelectCriterion  select_criterion,
               gint                *n_components,
               gboolean            *has_alpha)
{
  const Babl *format = gegl_buffer_get_format (buffer);

  *has_alpha = babl_format_has_alpha (format);

  switch (select_criterion)
    {
    case GIMP_SELECT_CRITERION_COMPOSITE:
      if (babl_format_is_palette (format))
        format = babl_format ("R'G'B'A float");
      else
        format = gimp_babl_format (gimp_babl_format_get_base_type (format),
                                   GIMP_PRECISION_FLOAT_GAMMA,
                                   *has_alpha);
      break;

    case GIMP_SELECT_CRITERION_R:
    case GIMP_SELECT_CRITERION_G:
    case GIMP_SELECT_CRITERION_B:
    case GIMP_SELECT_CRITERION_A:
      format = babl_format ("R'G'B'A float");
      break;

    case GIMP_SELECT_CRITERION_H:
    case GIMP_SELECT_CRITERION_S:
    case GIMP_SELECT_CRITERION_V:
      format = babl_format ("HSVA float");
      break;

    default:
      g_return_val_if_reached (NULL);
      break;
    }

  *n_components = babl_format_get_n_components (format);

  return format;
}
Esempio n. 7
0
int
main (int    argc,
      char **argv)
{
    int OK = 1;
    babl_init ();
    OK = ! babl_format_is_palette (babl_format_n (babl_type ("double"), 3));
    if(1) {
        unsigned char in[][1]   = {{        0},{          1},{          2},{15}};
        unsigned char out[][4]  = {{0,0,0,255},{127,0,0,255},{0,127,0,255},{255,255,255,255}};
        const Babl *palA;// = babl_new_palette (NULL, 0);
        //Babl *palB = babl_new_palette (NULL, 0);
        //
        babl_new_palette (NULL, &palA, NULL);
        assert (palA);

        CHECK_CONV("pal to rgba", unsigned char,
                   palA, babl_format("RGBA u8"),
                   in, out);
    }
Esempio n. 8
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);
}
Esempio n. 9
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);
}
Esempio n. 10
0
gboolean
gimp_pickable_pick_color (GimpPickable *pickable,
                          gint          x,
                          gint          y,
                          gboolean      sample_average,
                          gdouble       average_radius,
                          GimpRGB      *color,
                          gint         *color_index)
{
  const Babl *format;
  gdouble     pixel[4];

  g_return_val_if_fail (GIMP_IS_PICKABLE (pickable), FALSE);

  format = babl_format ("RGBA double");

  if (! gimp_pickable_get_pixel_at (pickable, x, y, format, pixel))
    return FALSE;

  if (sample_average)
    {
      gint    count        = 0;
      gdouble color_avg[4] = { 0.0, 0.0, 0.0, 0.0 };
      gint    radius       = (gint) average_radius;
      gint    i, j;

      for (i = x - radius; i <= x + radius; i++)
        for (j = y - radius; j <= y + radius; j++)
          if (gimp_pickable_get_pixel_at (pickable, i, j, format, pixel))
            {
              count++;

              color_avg[RED]   += pixel[RED];
              color_avg[GREEN] += pixel[GREEN];
              color_avg[BLUE]  += pixel[BLUE];
              color_avg[ALPHA] += pixel[ALPHA];
            }

      pixel[RED]   = color_avg[RED]   / count;
      pixel[GREEN] = color_avg[GREEN] / count;
      pixel[BLUE]  = color_avg[BLUE]  / count;
      pixel[ALPHA] = color_avg[ALPHA] / count;
    }

  gimp_rgba_set_pixel (color, format, pixel);

  if (color_index)
    {
      format = gimp_pickable_get_format (pickable);

      if (babl_format_is_palette (format) && ! sample_average)
        {
          guchar indexed_pixel[4];

          gimp_pickable_get_pixel_at (pickable, x, y, format, indexed_pixel);

          *color_index = indexed_pixel[0];
        }
      else
        {
          *color_index = -1;
        }
    }

  return TRUE;
}
Esempio n. 11
0
static void
gimp_color_tool_real_picked (GimpColorTool      *color_tool,
                             GimpColorPickState  pick_state,
                             gdouble             x,
                             gdouble             y,
                             const Babl         *sample_format,
                             const GimpRGB      *color,
                             gint                color_index)
{
  GimpTool          *tool = GIMP_TOOL (color_tool);
  GimpContext       *context;

  /*  use this tool's own options here (NOT color_tool->options)  */
  context = GIMP_CONTEXT (gimp_tool_get_options (tool));

  if (color_tool->pick_mode == GIMP_COLOR_PICK_MODE_FOREGROUND ||
      color_tool->pick_mode == GIMP_COLOR_PICK_MODE_BACKGROUND)
    {
      GtkWidget *widget;

      if (babl_format_is_palette (sample_format))
        {
          widget = gimp_dialog_factory_find_widget (gimp_dialog_factory_get_singleton (),
                                                    "gimp-indexed-palette");
          if (widget)
            {
              GimpColormapEditor *editor;

              editor = GIMP_COLORMAP_EDITOR (gtk_bin_get_child (GTK_BIN (widget)));

              gimp_colormap_editor_set_index (editor, color_index, NULL);
            }
        }

      if (TRUE)
        {
          widget = gimp_dialog_factory_find_widget (gimp_dialog_factory_get_singleton (),
                                                    "gimp-palette-editor");
          if (widget)
            {
              GimpPaletteEditor *editor;
              gint               index;

              editor = GIMP_PALETTE_EDITOR (gtk_bin_get_child (GTK_BIN (widget)));

              index = gimp_palette_editor_get_index (editor, color);
              if (index != -1)
                gimp_palette_editor_set_index (editor, index, NULL);
            }
        }
    }

  switch (color_tool->pick_mode)
    {
    case GIMP_COLOR_PICK_MODE_NONE:
      break;

    case GIMP_COLOR_PICK_MODE_FOREGROUND:
      gimp_context_set_foreground (context, color);
      break;

    case GIMP_COLOR_PICK_MODE_BACKGROUND:
      gimp_context_set_background (context, color);
      break;

    case GIMP_COLOR_PICK_MODE_PALETTE:
      {
        GimpDisplayShell *shell  = gimp_display_get_shell (tool->display);
        GdkScreen        *screen = gtk_widget_get_screen (GTK_WIDGET (shell));
        GtkWidget        *dockable;

        dockable =
          gimp_window_strategy_show_dockable_dialog (GIMP_WINDOW_STRATEGY (gimp_get_window_strategy (tool->display->gimp)),
                                                     tool->display->gimp,
                                                     gimp_dialog_factory_get_singleton (),
                                                     screen,
                                                     "gimp-palette-editor");

        if (dockable)
          {
            GtkWidget *palette_editor;
            GimpData  *data;

            /* don't blink like mad when updating */
            if (pick_state == GIMP_COLOR_PICK_STATE_UPDATE)
              gimp_dockable_blink_cancel (GIMP_DOCKABLE (dockable));

            palette_editor = gtk_bin_get_child (GTK_BIN (dockable));

            data = gimp_data_editor_get_data (GIMP_DATA_EDITOR (palette_editor));

            if (! data)
              {
                data = GIMP_DATA (gimp_context_get_palette (context));

                gimp_data_editor_set_data (GIMP_DATA_EDITOR (palette_editor),
                                           data);
              }

            gimp_palette_editor_pick_color (GIMP_PALETTE_EDITOR (palette_editor),
                                            color, pick_state);
          }
      }
      break;
    }
}
Esempio n. 12
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]);
                  }
              }
          }
      }
Esempio n. 13
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;
}
Esempio n. 14
0
void
gimp_gegl_convolve (GeglBuffer          *src_buffer,
                    const GeglRectangle *src_rect,
                    GeglBuffer          *dest_buffer,
                    const GeglRectangle *dest_rect,
                    const gfloat        *kernel,
                    gint                 kernel_size,
                    gdouble              divisor,
                    GimpConvolutionType  mode,
                    gboolean             alpha_weighting)
{
  GeglBufferIterator *iter;
  GeglRectangle      *src_roi;
  GeglRectangle      *dest_roi;
  const Babl         *src_format;
  const Babl         *dest_format;
  gint                src_components;
  gint                dest_components;

  src_format = gegl_buffer_get_format (src_buffer);

  if (babl_format_is_palette (src_format))
    src_format = gimp_babl_format (GIMP_RGB,
                                   GIMP_PRECISION_FLOAT_LINEAR,
                                   babl_format_has_alpha (src_format));
  else
    src_format = gimp_babl_format (gimp_babl_format_get_base_type (src_format),
                                   GIMP_PRECISION_FLOAT_LINEAR,
                                   babl_format_has_alpha (src_format));

  dest_format = gegl_buffer_get_format (dest_buffer);

  if (babl_format_is_palette (dest_format))
    dest_format = gimp_babl_format (GIMP_RGB,
                                    GIMP_PRECISION_FLOAT_LINEAR,
                                    babl_format_has_alpha (dest_format));
  else
    dest_format = gimp_babl_format (gimp_babl_format_get_base_type (dest_format),
                                    GIMP_PRECISION_FLOAT_LINEAR,
                                    babl_format_has_alpha (dest_format));

  src_components  = babl_format_get_n_components (src_format);
  dest_components = babl_format_get_n_components (dest_format);

  iter = gegl_buffer_iterator_new (src_buffer, src_rect, 0, src_format,
                                   GEGL_BUFFER_READ, GEGL_ABYSS_NONE);
  src_roi = &iter->roi[0];

  gegl_buffer_iterator_add (iter, dest_buffer, dest_rect, 0, dest_format,
                            GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);
  dest_roi = &iter->roi[1];

  while (gegl_buffer_iterator_next (iter))
    {
      /*  Convolve the src image using the convolution kernel, writing
       *  to dest Convolve is not tile-enabled--use accordingly
       */
      const gfloat *src         = iter->data[0];
      gfloat       *dest        = iter->data[1];
      const gint    components  = src_components;
      const gint    a_component = components - 1;
      const gint    rowstride   = src_components * src_roi->width;
      const gint    margin      = kernel_size / 2;
      const gint    x1          = src_roi->x;
      const gint    y1          = src_roi->y;
      const gint    x2          = src_roi->x + src_roi->width  - 1;
      const gint    y2          = src_roi->y + src_roi->height - 1;
      gint          x, y;
      gfloat        offset;

      /*  If the mode is NEGATIVE_CONVOL, the offset should be 128  */
      if (mode == GIMP_NEGATIVE_CONVOL)
        {
          offset = 0.5;
          mode = GIMP_NORMAL_CONVOL;
        }
      else
        {
          offset = 0.0;
        }

      for (y = 0; y < dest_roi->height; y++)
        {
          gfloat *d = dest;

          if (alpha_weighting)
            {
              for (x = 0; x < dest_roi->width; x++)
                {
                  const gfloat *m                = kernel;
                  gdouble       total[4]         = { 0.0, 0.0, 0.0, 0.0 };
                  gdouble       weighted_divisor = 0.0;
                  gint          i, j, b;

                  for (j = y - margin; j <= y + margin; j++)
                    {
                      for (i = x - margin; i <= x + margin; i++, m++)
                        {
                          gint          xx = CLAMP (i, x1, x2);
                          gint          yy = CLAMP (j, y1, y2);
                          const gfloat *s  = src + yy * rowstride + xx * components;
                          const gfloat  a  = s[a_component];

                          if (a)
                            {
                              gdouble mult_alpha = *m * a;

                              weighted_divisor += mult_alpha;

                              for (b = 0; b < a_component; b++)
                                total[b] += mult_alpha * s[b];

                              total[a_component] += mult_alpha;
                            }
                        }
                    }

                  if (weighted_divisor == 0.0)
                    weighted_divisor = divisor;

                  for (b = 0; b < a_component; b++)
                    total[b] /= weighted_divisor;

                  total[a_component] /= divisor;

                  for (b = 0; b < components; b++)
                    {
                      total[b] += offset;

                      if (mode != GIMP_NORMAL_CONVOL && total[b] < 0.0)
                        total[b] = - total[b];

                      *d++ = CLAMP (total[b], 0.0, 1.0);
                    }
                }
            }
          else
            {
              for (x = 0; x < dest_roi->width; x++)
                {
                  const gfloat *m        = kernel;
                  gdouble       total[4] = { 0.0, 0.0, 0.0, 0.0 };
                  gint          i, j, b;

                  for (j = y - margin; j <= y + margin; j++)
                    {
                      for (i = x - margin; i <= x + margin; i++, m++)
                        {
                          gint          xx = CLAMP (i, x1, x2);
                          gint          yy = CLAMP (j, y1, y2);
                          const gfloat *s  = src + yy * rowstride + xx * components;

                          for (b = 0; b < components; b++)
                            total[b] += *m * s[b];
                        }
                    }

                  for (b = 0; b < components; b++)
                    {
                      total[b] = total[b] / divisor + offset;

                      if (mode != GIMP_NORMAL_CONVOL && total[b] < 0.0)
                        total[b] = - total[b];

                      total[b] = CLAMP (total[b], 0.0, 1.0);
                    }
                }
            }

          dest += dest_roi->width * dest_components;
        }
    }
}
Esempio n. 15
0
void
gimp_histogram_calculate (GimpHistogram       *histogram,
                          GeglBuffer          *buffer,
                          const GeglRectangle *buffer_rect,
                          GeglBuffer          *mask,
                          const GeglRectangle *mask_rect)
{
  GeglBufferIterator *iter;
  const Babl         *format;
  gint                n_components;

  g_return_if_fail (histogram != NULL);
  g_return_if_fail (GEGL_IS_BUFFER (buffer));
  g_return_if_fail (buffer_rect != NULL);

  format = gegl_buffer_get_format (buffer);

  if (babl_format_is_palette (format))
    format = gimp_babl_format (GIMP_RGB, GIMP_PRECISION_U8,
                               babl_format_has_alpha (format));
  else
    format = gimp_babl_format (gimp_babl_format_get_base_type (format),
                               GIMP_PRECISION_U8,
                               babl_format_has_alpha (format));

  n_components = babl_format_get_n_components (format);

  gimp_histogram_alloc_values (histogram, n_components);

  iter = gegl_buffer_iterator_new (buffer, buffer_rect, 0, format,
                                   GEGL_BUFFER_READ, GEGL_ABYSS_NONE);

  if (mask)
    gegl_buffer_iterator_add (iter, mask, mask_rect, 0,
                              babl_format ("Y float"),
                              GEGL_BUFFER_READ, GEGL_ABYSS_NONE);

#define VALUE(c,i) (histogram->values[(c) * 256 + (i)])

  while (gegl_buffer_iterator_next (iter))
    {
      const guchar *data = iter->data[0];
      gint          max;

      if (mask)
        {
          const gfloat *mask_data = iter->data[1];

          switch (n_components)
            {
            case 1:
              while (iter->length)
                {
                  const gdouble masked = *mask_data;

                  VALUE (0, data[0]) += masked;

                  data += n_components;
                  mask_data += 1;
                }
              break;

            case 2:
              while (iter->length--)
                {
                  const gdouble masked = *mask_data;
                  const gdouble weight = data[1] / 255.0;

                  VALUE (0, data[0]) += weight * masked;
                  VALUE (1, data[1]) += masked;

                  data += n_components;
                  mask_data += 1;
                }
              break;

            case 3: /* calculate separate value values */
              while (iter->length--)
                {
                  const gdouble masked = *mask_data;

                  VALUE (1, data[0]) += masked;
                  VALUE (2, data[1]) += masked;
                  VALUE (3, data[2]) += masked;

                  max = MAX (data[0], data[1]);
                  max = MAX (data[2], max);

                  VALUE (0, max) += masked;

                  data += n_components;
                  mask_data += 1;
                }
              break;

            case 4: /* calculate separate value values */
              while (iter->length--)
                {
                  const gdouble masked = *mask_data;
                  const gdouble weight = data[3] / 255.0;

                  VALUE (1, data[0]) += weight * masked;
                  VALUE (2, data[1]) += weight * masked;
                  VALUE (3, data[2]) += weight * masked;
                  VALUE (4, data[3]) += masked;

                  max = MAX (data[0], data[1]);
                  max = MAX (data[2], max);

                  VALUE (0, max) += weight * masked;

                  data += n_components;
                  mask_data += 1;
                }
              break;
            }
        }
      else /* no mask */
        {
          switch (n_components)
            {
            case 1:
              while (iter->length--)
                {
                  VALUE (0, data[0]) += 1.0;

                  data += n_components;
                }
              break;

            case 2:
              while (iter->length--)
                {
                  const gdouble weight = data[1] / 255;

                  VALUE (0, data[0]) += weight;
                  VALUE (1, data[1]) += 1.0;

                  data += n_components;
                }
              break;

            case 3: /* calculate separate value values */
              while (iter->length--)
                {
                  VALUE (1, data[0]) += 1.0;
                  VALUE (2, data[1]) += 1.0;
                  VALUE (3, data[2]) += 1.0;

                  max = MAX (data[0], data[1]);
                  max = MAX (data[2], max);

                  VALUE (0, max) += 1.0;

                  data += n_components;
                }
              break;

            case 4: /* calculate separate value values */
              while (iter->length--)
                {
                  const gdouble weight = data[3] / 255;

                  VALUE (1, data[0]) += weight;
                  VALUE (2, data[1]) += weight;
                  VALUE (3, data[2]) += weight;
                  VALUE (4, data[3]) += 1.0;

                  max = MAX (data[0], data[1]);
                  max = MAX (data[2], max);

                  VALUE (0, max) += weight;

                  data += n_components;
                }
              break;
            }
        }
    }

#undef VALUE
}