Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  lighting-image.c   Sprache: C

 

/*************************************/
/* GIMP image manipulation routines. */
/*************************************/

#include "config.h"

#include <gtk/gtk.h>

#include <libgimp/gimp.h>

#include "lighting-main.h"
#include "lighting-image.h"
#include "lighting-preview.h"
#include "lighting-ui.h"


GimpDrawable *input_drawable;
GimpDrawable *output_drawable;
GeglBuffer   *source_buffer;
GeglBuffer   *dest_buffer;

GimpDrawable *bump_drawable;
GeglBuffer   *bump_buffer;
const Babl   *bump_format;

GimpDrawable *env_drawable;
GeglBuffer   *env_buffer;

guchar          *preview_rgb_data = NULL;
gint             preview_rgb_stride;
cairo_surface_t *preview_surface = NULL;

glong   maxcounter;
gint    width, height;
gint    env_width, env_height;
gdouble background[4];

gint border_x1, border_y1, border_x2, border_y2;

guchar sinemap[256], spheremap[256], logmap[256];

/******************/
/* Implementation */
/******************/

guchar
peek_map (GeglBuffer *buffer,
          const Babl *format,
          gint        x,
          gint        y)
{
  guchar data[4];
  guchar ret_val;

  gegl_buffer_sample (buffer, x, y, NULL, data, format,
                      GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);

  if (babl_format_get_bytes_per_pixel (format))
    {
      ret_val = data[0];
    }
  else
    {
      ret_val = (guchar)((float)((data[0] + data[1] + data[2])/3.0));
    }

  return ret_val;
}

void
peek (gint     x,
      gint     y,
      gdouble *color)
{
  gegl_buffer_sample (source_buffer, x, y, NULL,
                      color, babl_format ("R'G'B'A double"),
                      GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);

  if (! babl_format_has_alpha (gegl_buffer_get_format (source_buffer)))
    color[3] = 1.0;
}

void
peek_env_map (gint     x,
              gint     y,
              gdouble *color)
{
  if (x < 0)
    x = 0;
  else if (x >= env_width)
    x = env_width - 1;
  if (y < 0)
    y = 0;
  else if (y >= env_height)
    y = env_height - 1;

  gegl_buffer_sample (env_buffer, x, y, NULL,
                      color, babl_format ("R'G'B'A double"),
                      GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);

  color[3] = 1.0;
}

void
poke (gint     x,
      gint     y,
      gdouble *color)
{
  if (x < 0)
    x = 0;
  else if (x >= width)
    x = width - 1;
  if (y < 0)
    y = 0;
  else if (y >= height)
    y = height - 1;

  gegl_buffer_set (dest_buffer, GEGL_RECTANGLE (x, y, 1, 1), 0,
                   babl_format ("R'G'B'A double"), color,
                   GEGL_AUTO_ROWSTRIDE);
}

gint
check_bounds (gint x,
              gint y)
{
  if (x < border_x1 ||
      y < border_y1 ||
      x >= border_x2 ||
      y >= border_y2)
    return FALSE;
  else
    return TRUE;
}

GimpVector3
int_to_pos (gint x,
     gint y)
{
  GimpVector3 pos;

  if (width >= height)
    {
      pos.x = (gdouble) x / (gdouble) width;
      pos.y = (gdouble) y / (gdouble) width;

      pos.y += 0.5 * (1.0 - (gdouble) height / (gdouble) width);
    }
  else
    {
      pos.x = (gdouble) x / (gdouble) height;
      pos.y = (gdouble) y / (gdouble) height;

      pos.x += 0.5 * (1.0 - (gdouble) width / (gdouble) height);
    }

  pos.z = 0.0;
  return pos;
}

GimpVector3
int_to_posf (gdouble x,
      gdouble y)
{
  GimpVector3 pos;

  if (width >= height)
    {
      pos.x = x / (gdouble) width;
      pos.y = y / (gdouble) width;

      pos.y += 0.5 * (1.0 - (gdouble) height / (gdouble) width);
    }
  else
    {
      pos.x = x / (gdouble) height;
      pos.y = y / (gdouble) height;

      pos.x += 0.5 * (1.0 - (gdouble) width / (gdouble) height);
    }

  pos.z = 0.0;
  return pos;
}

void
pos_to_int (gdouble  x,
     gdouble  y,
     gint    *scr_x,
     gint    *scr_y)
{
  if (width >= height)
    {
      y -= 0.5 * (1.0 - (gdouble) height / (gdouble) width);
      *scr_x = RINT ((x * (gdouble) width));
      *scr_y = RINT ((y * (gdouble) width));
    }
  else
    {
      x -= 0.5 * (1.0 - (gdouble) width / (gdouble) height);

      *scr_x = RINT ((x * (gdouble) height));
      *scr_y = RINT ((y  *(gdouble) height));
    }
}

void
pos_to_float (gdouble  x,
       gdouble  y,
       gdouble *xf,
       gdouble *yf)
{
  if (width >= height)
    {
      y -= 0.5 * (1.0 - (gdouble) height / (gdouble) width);

      *xf = x * (gdouble) (width-1);
      *yf = y * (gdouble) (width-1);
    }
  else
    {
      x -= 0.5 * (1.0 - (gdouble) width / (gdouble) height);

      *xf = x * (gdouble) (height-1);
      *yf = y * (gdouble) (height-1);
    }
}

/**********************************************/
/* Compute the image color at pos (u,v) using */
/* Quartics bilinear interpolation stuff.     */
/**********************************************/

void
get_image_color (gdouble  u,
                 gdouble  v,
                 gint    *inside,
                 gdouble *color)
{
  gint     x1;
  gint     y1;
  gint     x2;
  gint     y2;
  gdouble  p[4];
  gdouble  pixels[16];

  x1 = RINT (u);
  y1 = RINT (v);

  if (check_bounds (x1, y1) == FALSE)
    {
      *inside = FALSE;
      for (gint i = 0; i < 4; i++)
        color[i] = background[i];

      return;
    }

  x2 = (x1 + 1);
  y2 = (y1 + 1);

  if (check_bounds (x2, y2) == FALSE)
    {
      *inside = TRUE;
      peek (x1, y1, color);

      return;
    }

  *inside = TRUE;
  peek (x1, y1, p);
  for (gint i = 0; i < 4; i++)
    pixels[i] = p[i];
  peek (x2, y1, p);
  for (gint i = 0; i < 4; i++)
    pixels[i + 4] = p[i];
  peek (x1, y2, p);
  for (gint i = 0; i < 4; i++)
    pixels[i + 8] = p[i];
  peek (x2, y2, p);
  for (gint i = 0; i < 4; i++)
    pixels[i + 12] = p[i];

  gimp_bilinear_rgb (u, v, pixels, TRUE, color);
}

gdouble
get_map_value (GeglBuffer *buffer,
               const Babl *format,
               gdouble     u,
               gdouble     v,
               gint       *inside)
{
  gint    x1, y1, x2, y2;
  gdouble p[4];

  x1 = RINT (u);
  y1 = RINT (v);

  x2 = (x1 + 1);
  y2 = (y1 + 1);

  if (check_bounds (x2, y2) == FALSE)
    {
      *inside = TRUE;
      return (gdouble) peek_map (buffer, format, x1, y1);
    }

  *inside = TRUE;
  p[0] = (gdouble) peek_map (buffer, format, x1, y1);
  p[1] = (gdouble) peek_map (buffer, format, x2, y1);
  p[2] = (gdouble) peek_map (buffer, format, x1, y2);
  p[3] = (gdouble) peek_map (buffer, format, x2, y2);

  return gimp_bilinear (u, v, p);
}

static void
compute_maps (void)
{
  gint    x;
  gdouble val, c, d;

  /* Compute Sine, Log and Spherical transfer function maps */
  /* ====================================================== */

  c = 1.0  / 255.0;
  d = 1.15 * 255.0;

  for (x = 0; x < 256; x++)
    {
      sinemap[x] = (guchar) (255.0 * (0.5 * (sin ((G_PI * c * (gdouble) x) -
        0.5 * G_PI) +
          1.0)));
      spheremap[x] = (guchar) (255.0 * (sqrt (sin (G_PI * (gdouble) x /
         512.0))));
      val = (d * exp (-1.0 / (8.0 * c * ((gdouble) x + 5.0))));

      if (val > 255.0)
        val = 255.0;
      logmap[x] = (guchar) val;
    }
}

/****************************************/
/* Allocate memory for temporary images */
/****************************************/

gint
image_setup (GimpDrawable *drawable,
      gint          interactive)
{
  gint    w, h;
  gboolean ret;

  compute_maps ();

  /* Get some useful info on the input drawable */
  /* ========================================== */

  input_drawable  = drawable;
  output_drawable = drawable;

  ret = gimp_drawable_mask_intersect (drawable,
                                      &border_x1, &border_y1, &w, &h);

  border_x2 = border_x1 + w;
  border_y2 = border_y1 + h;

  if (! ret)
    return FALSE;

  width  = gimp_drawable_get_width  (input_drawable);
  height = gimp_drawable_get_height (input_drawable);

  source_buffer = gimp_drawable_get_buffer (input_drawable);

  maxcounter = (glong) width * (glong) height;

  if (interactive)
    {
      preview_rgb_stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24,
                                                          PREVIEW_WIDTH);
      preview_rgb_data = g_new0 (guchar, preview_rgb_stride * PREVIEW_HEIGHT);
      preview_surface = cairo_image_surface_create_for_data (preview_rgb_data,
                                                             CAIRO_FORMAT_RGB24,
                                                             PREVIEW_WIDTH,
                                                             PREVIEW_HEIGHT,
                                                             preview_rgb_stride);
    }

  return TRUE;
}

void
bumpmap_setup (GimpDrawable *bumpmap)
{
  if (bumpmap)
    {
      gboolean has_alpha = gimp_drawable_has_alpha (bumpmap);

      if (! bump_buffer)
        {
          bump_buffer = gimp_drawable_get_buffer (bumpmap);
        }

      if (gimp_drawable_is_rgb (bumpmap))
        bump_format = has_alpha ? babl_format ("R'aG'aB'aA u8") :
                                  babl_format ("R'G'B' u8");
      else
        bump_format = has_alpha ? babl_format ("Y'aA u8") : /* FIXME */
                                  babl_format ("Y' u8");
    }
}

void
envmap_setup (GimpDrawable *envmap)
{
  if (envmap && ! env_buffer)
    {
      env_width  = gimp_drawable_get_width  (envmap);
      env_height = gimp_drawable_get_height (envmap);

      env_buffer = gimp_drawable_get_buffer (envmap);
    }
}

Messung
CHZG
849710093

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104845
#Domains=499264