Eine aufbereitete Darstellung der Quelle

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

Benutzer

Quelle  gimptilehandlervalidate.c   Sprache: C

 

/* GIMP - The GNU Image Manipulation Program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */


#include "config.h"

#include <cairo.h>
#include <gio/gio.h>
#include <gegl.h>

#include "libgimpbase/gimpbase.h"

#include "gimp-gegl-types.h"

#include "core/gimpchunkiterator.h"

#include "gimp-gegl-loops.h"
#include "gimp-gegl-utils.h"
#include "gimptilehandlervalidate.h"


enum
{
  INVALIDATED,
  LAST_SIGNAL
};

enum
{
  PROP_0,
  PROP_FORMAT,
  PROP_TILE_WIDTH,
  PROP_TILE_HEIGHT,
  PROP_WHOLE_TILE
};


static void     gimp_tile_handler_validate_finalize             (GObject         *object);
static void     gimp_tile_handler_validate_set_property         (GObject         *object,
                                                                 guint            property_id,
                                                                 const GValue    *value,
                                                                 GParamSpec      *pspec);
static void     gimp_tile_handler_validate_get_property         (GObject         *object,
                                                                 guint            property_id,
                                                                 GValue          *value,
                                                                 GParamSpec      *pspec);

static void     gimp_tile_handler_validate_real_begin_validate  (GimpTileHandlerValidate *validate);
static void     gimp_tile_handler_validate_real_end_validate    (GimpTileHandlerValidate *validate);
static void     gimp_tile_handler_validate_real_validate        (GimpTileHandlerValidate *validate,
                                                                 const GeglRectangle     *rect,
                                                                 const Babl              *format,
                                                                 gpointer                 dest_buf,
                                                                 gint                     dest_stride);
static void     gimp_tile_handler_validate_real_validate_buffer (GimpTileHandlerValidate *validate,
                                                                 const GeglRectangle     *rect,
                                                                 GeglBuffer              *buffer);

static gpointer gimp_tile_handler_validate_command              (GeglTileSource  *source,
                                                                 GeglTileCommand  command,
                                                                 gint             x,
                                                                 gint             y,
                                                                 gint             z,
                                                                 gpointer         data);


G_DEFINE_TYPE (GimpTileHandlerValidate, gimp_tile_handler_validate,
               GEGL_TYPE_TILE_HANDLER)

#define parent_class gimp_tile_handler_validate_parent_class

static guint gimp_tile_handler_validate_signals[LAST_SIGNAL];


static void
gimp_tile_handler_validate_class_init (GimpTileHandlerValidateClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  gimp_tile_handler_validate_signals[INVALIDATED] =
    g_signal_new ("invalidated",
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_FIRST,
                  G_STRUCT_OFFSET (GimpTileHandlerValidateClass, invalidated),
                  NULL, NULL,
                  g_cclosure_marshal_VOID__BOXED,
                  G_TYPE_NONE, 1,
                  GEGL_TYPE_RECTANGLE);

  object_class->finalize     = gimp_tile_handler_validate_finalize;
  object_class->set_property = gimp_tile_handler_validate_set_property;
  object_class->get_property = gimp_tile_handler_validate_get_property;

  klass->begin_validate      = gimp_tile_handler_validate_real_begin_validate;
  klass->end_validate        = gimp_tile_handler_validate_real_end_validate;
  klass->validate            = gimp_tile_handler_validate_real_validate;
  klass->validate_buffer     = gimp_tile_handler_validate_real_validate_buffer;

  g_object_class_install_property (object_class, PROP_FORMAT,
                                   g_param_spec_pointer ("format", NULL, NULL,
                                                         GIMP_PARAM_READWRITE));

  g_object_class_install_property (object_class, PROP_TILE_WIDTH,
                                   g_param_spec_int ("tile-width", NULL, NULL,
                                                     1, G_MAXINT, 1,
                                                     GIMP_PARAM_READWRITE |
                                                     G_PARAM_CONSTRUCT));

  g_object_class_install_property (object_class, PROP_TILE_HEIGHT,
                                   g_param_spec_int ("tile-height", NULL, NULL,
                                                     1, G_MAXINT, 1,
                                                     GIMP_PARAM_READWRITE |
                                                     G_PARAM_CONSTRUCT));

  g_object_class_install_property (object_class, PROP_WHOLE_TILE,
                                   g_param_spec_boolean ("whole-tile", NULL, NULL,
                                                         FALSE,
                                                         GIMP_PARAM_READWRITE |
                                                         G_PARAM_CONSTRUCT));
}

static void
gimp_tile_handler_validate_init (GimpTileHandlerValidate *validate)
{
  GeglTileSource *source = GEGL_TILE_SOURCE (validate);

  source->command = gimp_tile_handler_validate_command;

  validate->dirty_region = cairo_region_create ();
}

static void
gimp_tile_handler_validate_finalize (GObject *object)
{
  GimpTileHandlerValidate *validate = GIMP_TILE_HANDLER_VALIDATE (object);

  g_clear_object (&validate->graph);
  g_clear_pointer (&validate->dirty_region, cairo_region_destroy);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static void
gimp_tile_handler_validate_set_property (GObject      *object,
                                         guint         property_id,
                                         const GValue *value,
                                         GParamSpec   *pspec)
{
  GimpTileHandlerValidate *validate = GIMP_TILE_HANDLER_VALIDATE (object);

  switch (property_id)
    {
    case PROP_FORMAT:
      validate->format = g_value_get_pointer (value);
      break;
    case PROP_TILE_WIDTH:
      validate->tile_width = g_value_get_int (value);
      break;
    case PROP_TILE_HEIGHT:
      validate->tile_height = g_value_get_int (value);
      break;
    case PROP_WHOLE_TILE:
      validate->whole_tile = g_value_get_boolean (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}

static void
gimp_tile_handler_validate_get_property (GObject    *object,
                                         guint       property_id,
                                         GValue     *value,
                                         GParamSpec *pspec)
{
  GimpTileHandlerValidate *validate = GIMP_TILE_HANDLER_VALIDATE (object);

  switch (property_id)
    {
    case PROP_FORMAT:
      g_value_set_pointer (value, (gpointer) validate->format);
      break;
    case PROP_TILE_WIDTH:
      g_value_set_int (value, validate->tile_width);
      break;
    case PROP_TILE_HEIGHT:
      g_value_set_int (value, validate->tile_height);
      break;
    case PROP_WHOLE_TILE:
      g_value_set_boolean (value, validate->whole_tile);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}

static void
gimp_tile_handler_validate_real_begin_validate (GimpTileHandlerValidate *validate)
{
  validate->suspend_validate++;
}

static void
gimp_tile_handler_validate_real_end_validate (GimpTileHandlerValidate *validate)
{
  validate->suspend_validate--;
}

static void
gimp_tile_handler_validate_real_validate (GimpTileHandlerValidate *validate,
                                          const GeglRectangle     *rect,
                                          const Babl              *format,
                                          gpointer                 dest_buf,
                                          gint                     dest_stride)
{
#if 0
  g_printerr ("validating at %d %d %d %d\n",
              rect.x,
              rect.y,
              rect.width,
              rect.height);
#endif

  gegl_node_blit (validate->graph, 1.0, rect, format,
                  dest_buf, dest_stride,
                  GEGL_BLIT_DEFAULT);
}

static void
gimp_tile_handler_validate_real_validate_buffer (GimpTileHandlerValidate *validate,
                                                 const GeglRectangle     *rect,
                                                 GeglBuffer              *buffer)
{
  GimpTileHandlerValidateClass *klass;

  klass = GIMP_TILE_HANDLER_VALIDATE_GET_CLASS (validate);

  if (klass->validate == gimp_tile_handler_validate_real_validate)
    {
      gegl_node_blit_buffer (validate->graph, buffer, rect, 0,
                             GEGL_ABYSS_NONE);
    }
  else
    {
      const Babl *format = gegl_buffer_get_format (buffer);
      gpointer    data;
      gint        stride;

      data = gegl_buffer_linear_open (buffer, rect, &stride, format);

      klass->validate (validate, rect, format, data, stride);

      gegl_buffer_linear_close (buffer, data);
    }
}

static GeglTile *
gimp_tile_handler_validate_validate_tile (GeglTileSource *source,
                                          gint            x,
                                          gint            y)
{
  GimpTileHandlerValidate *validate = GIMP_TILE_HANDLER_VALIDATE (source);
  GeglTile                *tile;
  cairo_rectangle_int_t    tile_rect;
  cairo_region_overlap_t   overlap;

  if (validate->suspend_validate ||
      cairo_region_is_empty (validate->dirty_region))
    {
      return gegl_tile_handler_source_command (source,
                                               GEGL_TILE_GET, x, y, 0, NULL);
    }

  tile_rect.x      = x * validate->tile_width;
  tile_rect.y      = y * validate->tile_height;
  tile_rect.width  = validate->tile_width;
  tile_rect.height = validate->tile_height;

  overlap = cairo_region_contains_rectangle (validate->dirty_region,
                                             &tile_rect);

  if (overlap == CAIRO_REGION_OVERLAP_OUT)
    {
      return gegl_tile_handler_source_command (source,
                                               GEGL_TILE_GET, x, y, 0, NULL);
    }

  if (overlap == CAIRO_REGION_OVERLAP_IN || validate->whole_tile)
    {
      gint tile_bpp;
      gint tile_stride;

      cairo_region_subtract_rectangle (validate->dirty_region, &tile_rect);

      tile_bpp    = babl_format_get_bytes_per_pixel (validate->format);
      tile_stride = tile_bpp * validate->tile_width;

      tile = gegl_tile_handler_get_source_tile (GEGL_TILE_HANDLER (source),
                                                x, y, 0, FALSE);

      gimp_tile_handler_validate_begin_validate (validate);

      gegl_tile_lock (tile);

      GIMP_TILE_HANDLER_VALIDATE_GET_CLASS (validate)->validate
        (validate,
         GEGL_RECTANGLE (tile_rect.x,
                         tile_rect.y,
                         tile_rect.width,
                         tile_rect.height),
         validate->format,
         gegl_tile_get_data (tile),
         tile_stride);

      gegl_tile_unlock (tile);

      gimp_tile_handler_validate_end_validate (validate);
    }
  else
    {
      cairo_region_t *tile_region;
      gint            tile_bpp;
      gint            tile_stride;
      gint            n_rects;
      gint            i;

      tile_region = cairo_region_copy (validate->dirty_region);
      cairo_region_intersect_rectangle (tile_region, &tile_rect);

      cairo_region_subtract_rectangle (validate->dirty_region, &tile_rect);

      tile_bpp    = babl_format_get_bytes_per_pixel (validate->format);
      tile_stride = tile_bpp * validate->tile_width;

      tile = gegl_tile_handler_source_command (source,
                                               GEGL_TILE_GET, x, y, 0, NULL);

      if (! tile)
        {
          tile = gegl_tile_handler_create_tile (GEGL_TILE_HANDLER (source),
                                                x, y, 0);

          memset (gegl_tile_get_data (tile),
                  0, tile_stride * validate->tile_height);
        }

      gimp_tile_handler_validate_begin_validate (validate);

      gegl_tile_lock (tile);

      n_rects = cairo_region_num_rectangles (tile_region);

#if 0
      g_printerr ("%d chunks\n", n_rects);
#endif

      for (i = 0; i < n_rects; i++)
        {
          cairo_rectangle_int_t blit_rect;
          gint                  tile_x;
          gint                  tile_y;

          cairo_region_get_rectangle (tile_region, i, &blit_rect);

          tile_x = blit_rect.x % validate->tile_width;
          if (tile_x < 0) tile_x += validate->tile_width;

          tile_y = blit_rect.y % validate->tile_height;
          if (tile_y < 0) tile_y += validate->tile_height;

          GIMP_TILE_HANDLER_VALIDATE_GET_CLASS (validate)->validate
            (validate,
             GEGL_RECTANGLE (blit_rect.x,
                             blit_rect.y,
                             blit_rect.width,
                             blit_rect.height),
             validate->format,
             gegl_tile_get_data (tile) +
             tile_y * tile_stride      +
             tile_x * tile_bpp,
             tile_stride);
        }

      gegl_tile_unlock (tile);

      gimp_tile_handler_validate_end_validate (validate);

      cairo_region_destroy (tile_region);
    }

  return tile;
}

static gpointer
gimp_tile_handler_validate_command (GeglTileSource  *source,
                                    GeglTileCommand  command,
                                    gint             x,
                                    gint             y,
                                    gint             z,
                                    gpointer         data)
{
  if (command == GEGL_TILE_GET && z == 0)
    return gimp_tile_handler_validate_validate_tile (source, x, y);

  return gegl_tile_handler_source_command (source, command, x, y, z, data);
}


/*  public functions  */

GeglTileHandler *
gimp_tile_handler_validate_new (GeglNode *graph)
{
  GimpTileHandlerValidate *validate;

  g_return_val_if_fail (GEGL_IS_NODE (graph), NULL);

  validate = g_object_new (GIMP_TYPE_TILE_HANDLER_VALIDATE, NULL);

  validate->graph = g_object_ref (graph);

  return GEGL_TILE_HANDLER (validate);
}

void
gimp_tile_handler_validate_assign (GimpTileHandlerValidate *validate,
                                   GeglBuffer              *buffer)
{
  g_return_if_fail (GIMP_IS_TILE_HANDLER_VALIDATE (validate));
  g_return_if_fail (GEGL_IS_BUFFER (buffer));
  g_return_if_fail (gimp_tile_handler_validate_get_assigned (buffer) == NULL);

  gegl_buffer_add_handler (buffer, validate);

  g_object_get (buffer,
                "format",      &validate->format,
                "tile-width",  &validate->tile_width,
                "tile-height", &validate->tile_height,
                NULL);

  g_object_set_data (G_OBJECT (buffer),
                     "gimp-tile-handler-validate", validate);
}

void
gimp_tile_handler_validate_unassign (GimpTileHandlerValidate *validate,
                                     GeglBuffer              *buffer)
{
  g_return_if_fail (GIMP_IS_TILE_HANDLER_VALIDATE (validate));
  g_return_if_fail (GEGL_IS_BUFFER (buffer));
  g_return_if_fail (gimp_tile_handler_validate_get_assigned (buffer) == validate);

  g_object_set_data (G_OBJECT (buffer),
                     "gimp-tile-handler-validate", NULL);

  gegl_buffer_remove_handler (buffer, validate);
}

GimpTileHandlerValidate *
gimp_tile_handler_validate_get_assigned (GeglBuffer *buffer)
{
  g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL);

  return g_object_get_data (G_OBJECT (buffer),
                            "gimp-tile-handler-validate");
}

void
gimp_tile_handler_validate_invalidate (GimpTileHandlerValidate *validate,
                                       const GeglRectangle     *rect)
{
  g_return_if_fail (GIMP_IS_TILE_HANDLER_VALIDATE (validate));
  g_return_if_fail (rect != NULL);

  cairo_region_union_rectangle (validate->dirty_region,
                                (cairo_rectangle_int_t *) rect);

  gegl_tile_handler_damage_rect (GEGL_TILE_HANDLER (validate), rect);

  g_signal_emit (validate, gimp_tile_handler_validate_signals[INVALIDATED],
                 0, rect, NULL);
}

void
gimp_tile_handler_validate_undo_invalidate (GimpTileHandlerValidate *validate,
                                            const GeglRectangle     *rect)
{
  g_return_if_fail (GIMP_IS_TILE_HANDLER_VALIDATE (validate));
  g_return_if_fail (rect != NULL);

  cairo_region_subtract_rectangle (validate->dirty_region,
                                   (cairo_rectangle_int_t *) rect);
}

void
gimp_tile_handler_validate_begin_validate (GimpTileHandlerValidate *validate)
{
  g_return_if_fail (GIMP_IS_TILE_HANDLER_VALIDATE (validate));

  if (validate->validating++ == 0)
    GIMP_TILE_HANDLER_VALIDATE_GET_CLASS (validate)->begin_validate (validate);
}

void
gimp_tile_handler_validate_end_validate (GimpTileHandlerValidate *validate)
{
  g_return_if_fail (GIMP_IS_TILE_HANDLER_VALIDATE (validate));
  g_return_if_fail (validate->validating > 0);

  if (--validate->validating == 0)
    GIMP_TILE_HANDLER_VALIDATE_GET_CLASS (validate)->end_validate (validate);
}

void
gimp_tile_handler_validate_validate (GimpTileHandlerValidate *validate,
                                     GeglBuffer              *buffer,
                                     const GeglRectangle     *rect,
                                     gboolean                 intersect,
                                     gboolean                 chunked)
{
  GimpTileHandlerValidateClass *klass;
  cairo_region_t               *region = NULL;

  g_return_if_fail (GIMP_IS_TILE_HANDLER_VALIDATE (validate));
  g_return_if_fail (gimp_tile_handler_validate_get_assigned (buffer) ==
                    validate);

  klass = GIMP_TILE_HANDLER_VALIDATE_GET_CLASS (validate);

  if (! rect)
    rect = gegl_buffer_get_extent (buffer);

  if (intersect)
    {
      region = cairo_region_copy (validate->dirty_region);

      cairo_region_intersect_rectangle (region,
                                        (const cairo_rectangle_int_t *) rect);
    }
  else if (chunked)
    {
      region = cairo_region_create_rectangle (
        (const cairo_rectangle_int_t *) rect);
    }

  if (region)
    {
      if (! cairo_region_is_empty (region))
        {
          gimp_tile_handler_validate_begin_validate (validate);

          if (chunked)
            {
              GimpChunkIterator *iter;

              iter   = gimp_chunk_iterator_new (region);
              region = NULL;

              while (gimp_chunk_iterator_next (iter))
                {
                  GeglRectangle blit_rect;

                  while (gimp_chunk_iterator_get_rect (iter, &blit_rect))
                    klass->validate_buffer (validate, &blit_rect, buffer);
                }
            }
          else
            {
              gint n_rects;
              gint i;

              n_rects = cairo_region_num_rectangles (region);

              for (i = 0; i < n_rects; i++)
                {
                  cairo_rectangle_int_t blit_rect;

                  cairo_region_get_rectangle (region, i, &blit_rect);

                  klass->validate_buffer (validate,
                                          (const GeglRectangle *) &blit_rect,
                                          buffer);
                }
              }

          gimp_tile_handler_validate_end_validate (validate);

          cairo_region_subtract_rectangle (
            validate->dirty_region,
            (const cairo_rectangle_int_t *) rect);
        }

      g_clear_pointer (®ion, cairo_region_destroy);
    }
  else
    {
      gimp_tile_handler_validate_begin_validate (validate);

      klass->validate_buffer (validate, rect, buffer);

      gimp_tile_handler_validate_end_validate (validate);

      cairo_region_subtract_rectangle (
            validate->dirty_region,
            (const cairo_rectangle_int_t *) rect);
    }
}

gboolean
gimp_tile_handler_validate_buffer_set_extent (GeglBuffer          *buffer,
                                              const GeglRectangle *extent)
{
  GimpTileHandlerValidate *validate;

  g_return_val_if_fail (GEGL_IS_BUFFER (buffer), FALSE);
  g_return_val_if_fail (extent != NULL, FALSE);

  validate = gimp_tile_handler_validate_get_assigned (buffer);

  g_return_val_if_fail (validate != NULL, FALSE);

  validate->suspend_validate++;

  if (gimp_gegl_buffer_set_extent (buffer, extent))
    {
      validate->suspend_validate--;

      cairo_region_intersect_rectangle (validate->dirty_region,
                                        (const cairo_rectangle_int_t *) extent);

      return TRUE;
    }

  validate->suspend_validate--;

  return FALSE;
}

void
gimp_tile_handler_validate_buffer_copy (GeglBuffer          *src_buffer,
                                        const GeglRectangle *src_rect,
                                        GeglBuffer          *dst_buffer,
                                        const GeglRectangle *dst_rect)
{
  GimpTileHandlerValidate *src_validate;
  GimpTileHandlerValidate *dst_validate;
  GeglRectangle            real_src_rect;
  GeglRectangle            real_dst_rect;

  g_return_if_fail (GEGL_IS_BUFFER (src_buffer));
  g_return_if_fail (GEGL_IS_BUFFER (dst_buffer));
  g_return_if_fail (src_rect != dst_rect);

  src_validate = gimp_tile_handler_validate_get_assigned (src_buffer);
  dst_validate = gimp_tile_handler_validate_get_assigned (dst_buffer);

  g_return_if_fail (dst_validate != NULL);

  if (! src_rect)
    src_rect = gegl_buffer_get_extent (src_buffer);

  if (! dst_rect)
    dst_rect = src_rect;

  real_src_rect = *src_rect;

  gegl_rectangle_intersect (&real_dst_rect,
                            dst_rect, gegl_buffer_get_extent (dst_buffer));

  real_src_rect.x      += real_dst_rect.x - dst_rect->x;
  real_src_rect.y      += real_dst_rect.y - dst_rect->y;
  real_src_rect.width  -= real_dst_rect.x - dst_rect->x;
  real_src_rect.height -= real_dst_rect.y - dst_rect->y;

  real_src_rect.width  = CLAMP (real_src_rect.width,  0, real_dst_rect.width);
  real_src_rect.height = CLAMP (real_src_rect.height, 0, real_dst_rect.height);

  /* temporarily remove the source buffer's validate handler, so that
   * gegl_buffer_copy() can use fast tile copying, using the TILE_COPY command.
   * currently, gegl only uses TILE_COPY when the source buffer has no user-
   * provided tile handlers.
   */

  if (src_validate)
    {
      g_object_ref (src_validate);

      gimp_tile_handler_validate_unassign (src_validate, src_buffer);
    }

  dst_validate->suspend_validate++;

  gimp_gegl_buffer_copy (src_buffer, &real_src_rect, GEGL_ABYSS_NONE,
                         dst_buffer, &real_dst_rect);

  dst_validate->suspend_validate--;

  if (src_validate)
    {
      gimp_tile_handler_validate_assign (src_validate, src_buffer);

      g_object_unref (src_validate);
    }

  cairo_region_subtract_rectangle (dst_validate->dirty_region,
                                   (cairo_rectangle_int_t *) &real_dst_rect);

  if (src_validate)
    {
      if (real_src_rect.x == real_dst_rect.x &&
          real_src_rect.y == real_dst_rect.y &&
          gegl_rectangle_equal (&real_src_rect,
                                gegl_buffer_get_extent (src_buffer)))
        {
          cairo_region_union (dst_validate->dirty_region,
                              src_validate->dirty_region);
        }
      else if (cairo_region_contains_rectangle (
                 src_validate->dirty_region,
                 (cairo_rectangle_int_t *) &real_src_rect) !=
               CAIRO_REGION_OVERLAP_OUT)
        {
          cairo_region_t *region;

          region = cairo_region_copy (src_validate->dirty_region);

          if (! gegl_rectangle_equal (&real_src_rect,
                                      gegl_buffer_get_extent (src_buffer)))
            {
              cairo_region_intersect_rectangle (
                region, (cairo_rectangle_int_t *) &real_src_rect);
            }

          cairo_region_translate (region,
                                  real_dst_rect.x - real_src_rect.x,
                                  real_dst_rect.y - real_src_rect.y);

          if (cairo_region_is_empty (dst_validate->dirty_region))
            {
              cairo_region_destroy (dst_validate->dirty_region);

              dst_validate->dirty_region = region;
            }
          else
            {
              cairo_region_union (dst_validate->dirty_region, region);

              cairo_region_destroy (region);
            }
        }
    }
}

Messung
CHZG
919610095

¤ Dauer der Verarbeitung: 0.12 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=499266