static void
cdisplay_gamma_convert_buffer (GimpColorDisplay *display,
                               GeglBuffer       *buffer,
                               GeglRectangle    *area)
{
  CdisplayGamma      *gamma = CDISPLAY_GAMMA (display);
  GeglBufferIterator *iter;
  gdouble             one_over_gamma;

  one_over_gamma = 1.0 / gamma->gamma;

  iter = gegl_buffer_iterator_new (buffer, area, 0,
                                   babl_format ("R'G'B'A float"),
                                   GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    {
      gfloat *data  = iter->data[0];
      gint    count = iter->length;

      while (count--)
        {
          *data = pow (*data, one_over_gamma); data++;
          *data = pow (*data, one_over_gamma); data++;
          *data = pow (*data, one_over_gamma); data++;

          data++;
        }
    }
}
static void
cdisplay_gamma_convert_surface (GimpColorDisplay *display,
                                cairo_surface_t  *surface)
{
  CdisplayGamma  *gamma  = CDISPLAY_GAMMA (display);
  gint            width  = cairo_image_surface_get_width (surface);
  gint            height = cairo_image_surface_get_height (surface);
  gint            stride = cairo_image_surface_get_stride (surface);
  guchar         *buf    = cairo_image_surface_get_data (surface);
  cairo_format_t  fmt    = cairo_image_surface_get_format (surface);
  gint            i, j, skip;
  gint            r, g, b, a;

  if (fmt != CAIRO_FORMAT_ARGB32)
    return;

  /* You will not be using the entire buffer most of the time.
   * Hence, the simplistic code for this is as follows:
   *
   * for (j = 0; j < height; j++)
   *   {
   *     for (i = 0; i < width * bpp; i++)
   *       buf[i] = lookup[buf[i]];
   *     buf += bpl;
   *   }
   */

  j = height;
  skip = stride - 4 * width;

  while (j--)
    {
      i = width;
      while (i--)
        {
          GIMP_CAIRO_ARGB32_GET_PIXEL (buf, r, g, b, a);
          r = gamma->lookup[r];
          g = gamma->lookup[g];
          b = gamma->lookup[b];
          GIMP_CAIRO_ARGB32_SET_PIXEL (buf, r, g, b, a);
          buf += 4;
        }
      buf += skip;
    }
}
static void
cdisplay_gamma_set_property (GObject      *object,
                             guint         property_id,
                             const GValue *value,
                             GParamSpec   *pspec)
{
  CdisplayGamma *gamma = CDISPLAY_GAMMA (object);

  switch (property_id)
    {
    case PROP_GAMMA:
      cdisplay_gamma_set_gamma (gamma, g_value_get_double (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}
static GtkWidget *
cdisplay_gamma_configure (GimpColorDisplay *display)
{
  CdisplayGamma *gamma = CDISPLAY_GAMMA (display);
  GtkWidget     *hbox;
  GtkWidget     *label;
  GtkWidget     *spinbutton;

  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);

  label = gtk_label_new_with_mnemonic (_("_Gamma:"));
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
  gtk_widget_show (label);

  spinbutton = gimp_prop_spin_button_new (G_OBJECT (gamma), "gamma",
                                          0.1, 1.0, 3);
  gtk_box_pack_start (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
  gtk_widget_show (spinbutton);

  gtk_label_set_mnemonic_widget (GTK_LABEL (label), spinbutton);

  return hbox;
}
static void
cdisplay_gamma_convert (GimpColorDisplay *display,
                        guchar           *buf,
                        gint              width,
                        gint              height,
                        gint              bpp,
                        gint              bpl)
{
  CdisplayGamma *gamma = CDISPLAY_GAMMA (display);
  gint           i, j  = height;

  /* You will not be using the entire buffer most of the time.
   * Hence, the simplistic code for this is as follows:
   *
   * for (j = 0; j < height; j++)
   *   {
   *     for (i = 0; i < width * bpp; i++)
   *       buf[i] = lookup[buf[i]];
   *     buf += bpl;
   *   }
   */

  width *= bpp;
  bpl -= width;

  while (j--)
    {
      i = width;
      while (i--)
        {
          *buf = gamma->lookup[*buf];
          buf++;
        }
      buf += bpl;
    }
}