Blame gdk/win32/gdkimage-win32.c

Packit Service fb6fa5
/* GDK - The GIMP Drawing Kit
Packit Service fb6fa5
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
Packit Service fb6fa5
 * Copyright (C) 1998-2002 Tor Lillqvist
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is free software; you can redistribute it and/or
Packit Service fb6fa5
 * modify it under the terms of the GNU Lesser General Public
Packit Service fb6fa5
 * License as published by the Free Software Foundation; either
Packit Service fb6fa5
 * version 2 of the License, or (at your option) any later version.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is distributed in the hope that it will be useful,
Packit Service fb6fa5
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service fb6fa5
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service fb6fa5
 * Lesser General Public License for more details.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * You should have received a copy of the GNU Lesser General Public
Packit Service fb6fa5
 * License along with this library; if not, write to the
Packit Service fb6fa5
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit Service fb6fa5
 * Boston, MA 02111-1307, USA.
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
Packit Service fb6fa5
 * file for a list of people on the GTK+ Team.  See the ChangeLog
Packit Service fb6fa5
 * files for a list of changes.  These files are distributed with
Packit Service fb6fa5
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
#include "config.h"
Packit Service fb6fa5
#include "gdkimage.h"
Packit Service fb6fa5
#include "gdkpixmap.h"
Packit Service fb6fa5
#include "gdkscreen.h" /* gdk_screen_get_default() */
Packit Service fb6fa5
#include "gdkprivate-win32.h"
Packit Service fb6fa5
Packit Service fb6fa5
static GList *image_list = NULL;
Packit Service fb6fa5
static gpointer parent_class = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
static void gdk_win32_image_destroy (GdkImage      *image);
Packit Service fb6fa5
static void gdk_image_init          (GdkImage      *image);
Packit Service fb6fa5
static void gdk_image_class_init    (GdkImageClass *klass);
Packit Service fb6fa5
static void gdk_image_finalize      (GObject       *object);
Packit Service fb6fa5
Packit Service fb6fa5
GType
Packit Service fb6fa5
gdk_image_get_type (void)
Packit Service fb6fa5
{
Packit Service fb6fa5
  static GType object_type = 0;
Packit Service fb6fa5
Packit Service fb6fa5
  if (!object_type)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      const GTypeInfo object_info =
Packit Service fb6fa5
      {
Packit Service fb6fa5
        sizeof (GdkImageClass),
Packit Service fb6fa5
        (GBaseInitFunc) NULL,
Packit Service fb6fa5
        (GBaseFinalizeFunc) NULL,
Packit Service fb6fa5
        (GClassInitFunc) gdk_image_class_init,
Packit Service fb6fa5
        NULL,           /* class_finalize */
Packit Service fb6fa5
        NULL,           /* class_data */
Packit Service fb6fa5
        sizeof (GdkImage),
Packit Service fb6fa5
        0,              /* n_preallocs */
Packit Service fb6fa5
        (GInstanceInitFunc) gdk_image_init,
Packit Service fb6fa5
      };
Packit Service fb6fa5
      
Packit Service fb6fa5
      object_type = g_type_register_static (G_TYPE_OBJECT,
Packit Service fb6fa5
                                            "GdkImage",
Packit Service fb6fa5
                                            &object_info, 0);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  return object_type;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_image_init (GdkImage *image)
Packit Service fb6fa5
{
Packit Service fb6fa5
  image->windowing_data = NULL;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_image_class_init (GdkImageClass *klass)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit Service fb6fa5
Packit Service fb6fa5
  parent_class = g_type_class_peek_parent (klass);
Packit Service fb6fa5
Packit Service fb6fa5
  object_class->finalize = gdk_image_finalize;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_image_finalize (GObject *object)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkImage *image = GDK_IMAGE (object);
Packit Service fb6fa5
Packit Service fb6fa5
  gdk_win32_image_destroy (image);
Packit Service fb6fa5
  
Packit Service fb6fa5
  G_OBJECT_CLASS (parent_class)->finalize (object);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
_gdk_image_exit (void)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkImage *image;
Packit Service fb6fa5
Packit Service fb6fa5
  while (image_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      image = image_list->data;
Packit Service fb6fa5
      gdk_win32_image_destroy (image);
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * Create a GdkImage _without_ an associated GdkPixmap. The caller is
Packit Service fb6fa5
 * responsible for creating a GdkPixmap object and making the association.
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
static GdkImage *
Packit Service fb6fa5
_gdk_win32_new_image (GdkVisual *visual,
Packit Service fb6fa5
		      gint       width,
Packit Service fb6fa5
		      gint       height,
Packit Service fb6fa5
		      gint       depth,
Packit Service fb6fa5
		      guchar    *bits)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkImage *image;
Packit Service fb6fa5
Packit Service fb6fa5
  image = g_object_new (gdk_image_get_type (), NULL);
Packit Service fb6fa5
  image->windowing_data = NULL;
Packit Service fb6fa5
  image->type = GDK_IMAGE_SHARED;
Packit Service fb6fa5
  image->visual = visual;
Packit Service fb6fa5
  image->byte_order = GDK_LSB_FIRST;
Packit Service fb6fa5
  image->width = width;
Packit Service fb6fa5
  image->height = height;
Packit Service fb6fa5
  image->depth = depth;
Packit Service fb6fa5
  image->bits_per_pixel = _gdk_windowing_get_bits_for_depth (gdk_display_get_default (), depth);
Packit Service fb6fa5
  switch (depth)
Packit Service fb6fa5
    {
Packit Service fb6fa5
    case 1:
Packit Service fb6fa5
    case 4:
Packit Service fb6fa5
    case 5:
Packit Service fb6fa5
    case 6:
Packit Service fb6fa5
    case 7:
Packit Service fb6fa5
    case 8:
Packit Service fb6fa5
      image->bpp = 1;
Packit Service fb6fa5
      break;
Packit Service fb6fa5
    case 15:
Packit Service fb6fa5
    case 16:
Packit Service fb6fa5
      image->bpp = 2;
Packit Service fb6fa5
      break;
Packit Service fb6fa5
    case 24:
Packit Service fb6fa5
      image->bpp = image->bits_per_pixel / 8;
Packit Service fb6fa5
      break;
Packit Service fb6fa5
    case 32:
Packit Service fb6fa5
      image->bpp = 4;
Packit Service fb6fa5
      break;
Packit Service fb6fa5
    default:
Packit Service fb6fa5
      g_warning ("_gdk_win32_new_image: depth=%d", image->depth);
Packit Service fb6fa5
      g_assert_not_reached ();
Packit Service fb6fa5
    }
Packit Service fb6fa5
  if (depth == 1)
Packit Service fb6fa5
    image->bpl = ((width - 1)/32 + 1)*4;
Packit Service fb6fa5
  else if (depth == 4)
Packit Service fb6fa5
    image->bpl = ((width - 1)/8 + 1)*4;
Packit Service fb6fa5
  else
Packit Service fb6fa5
    image->bpl = ((width*image->bpp - 1)/4 + 1)*4;
Packit Service fb6fa5
  image->mem = bits;
Packit Service fb6fa5
Packit Service fb6fa5
  return image;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GdkImage *
Packit Service fb6fa5
gdk_image_new_bitmap (GdkVisual *visual,
Packit Service fb6fa5
		      gpointer   data,
Packit Service fb6fa5
		      gint       w,
Packit Service fb6fa5
		      gint       h)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkPixmap *pixmap;
Packit Service fb6fa5
  GdkImage *image;
Packit Service fb6fa5
  guchar *bits;
Packit Service fb6fa5
  gint data_bpl = (w-1)/8 + 1;
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
Packit Service fb6fa5
  pixmap = gdk_pixmap_new (NULL, w, h, 1);
Packit Service fb6fa5
Packit Service fb6fa5
  if (pixmap == NULL)
Packit Service fb6fa5
    return NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  GDK_NOTE (IMAGE, g_print ("gdk_image_new_bitmap: %dx%d=%p\n",
Packit Service fb6fa5
			    w, h, GDK_PIXMAP_HBITMAP (pixmap)));
Packit Service fb6fa5
Packit Service fb6fa5
  bits = GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl)->bits;
Packit Service fb6fa5
  image = _gdk_win32_new_image (visual, w, h, 1, bits);
Packit Service fb6fa5
  image->windowing_data = pixmap;
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (data_bpl != image->bpl)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      for (i = 0; i < h; i++)
Packit Service fb6fa5
	memmove ((guchar *) image->mem + i*image->bpl, ((guchar *) data) + i*data_bpl, data_bpl);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    memmove (image->mem, data, data_bpl*h);
Packit Service fb6fa5
Packit Service fb6fa5
  return image;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
_gdk_windowing_image_init (void)
Packit Service fb6fa5
{
Packit Service fb6fa5
  /* Nothing needed AFAIK */
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GdkImage*
Packit Service fb6fa5
_gdk_image_new_for_depth (GdkScreen    *screen,
Packit Service fb6fa5
			  GdkImageType  type,
Packit Service fb6fa5
			  GdkVisual    *visual,
Packit Service fb6fa5
			  gint          width,
Packit Service fb6fa5
			  gint          height,
Packit Service fb6fa5
			  gint          depth)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkPixmap *pixmap;
Packit Service fb6fa5
  GdkImage *image;
Packit Service fb6fa5
  guchar *bits;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (!visual || GDK_IS_VISUAL (visual), NULL);
Packit Service fb6fa5
  g_return_val_if_fail (visual || depth != -1, NULL);
Packit Service fb6fa5
  g_return_val_if_fail (screen == gdk_screen_get_default (), NULL);
Packit Service fb6fa5
 
Packit Service fb6fa5
  if (visual)
Packit Service fb6fa5
    depth = visual->depth;
Packit Service fb6fa5
Packit Service fb6fa5
  pixmap = gdk_pixmap_new (NULL, width, height, depth);
Packit Service fb6fa5
Packit Service fb6fa5
  if (pixmap == NULL)
Packit Service fb6fa5
    return NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  GDK_NOTE (IMAGE, g_print ("_gdk_image_new_for_depth: %dx%dx%d=%p\n",
Packit Service fb6fa5
			    width, height, depth, GDK_PIXMAP_HBITMAP (pixmap)));
Packit Service fb6fa5
  
Packit Service fb6fa5
  bits = GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl)->bits;
Packit Service fb6fa5
  image = _gdk_win32_new_image (visual, width, height, depth, bits);
Packit Service fb6fa5
  image->windowing_data = pixmap;
Packit Service fb6fa5
  
Packit Service fb6fa5
  return image;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GdkImage*
Packit Service fb6fa5
_gdk_win32_copy_to_image (GdkDrawable    *drawable,
Packit Service fb6fa5
			  GdkImage       *image,
Packit Service fb6fa5
			  gint            src_x,
Packit Service fb6fa5
			  gint            src_y,
Packit Service fb6fa5
			  gint            dest_x,
Packit Service fb6fa5
			  gint            dest_y,
Packit Service fb6fa5
			  gint            width,
Packit Service fb6fa5
			  gint            height)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkGC *gc;
Packit Service fb6fa5
  GdkScreen *screen = gdk_drawable_get_screen (drawable);
Packit Service fb6fa5
  
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_DRAWABLE_IMPL_WIN32 (drawable), NULL);
Packit Service fb6fa5
  g_return_val_if_fail (image != NULL || (dest_x == 0 && dest_y == 0), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  GDK_NOTE (IMAGE, g_print ("_gdk_win32_copy_to_image: %p\n",
Packit Service fb6fa5
			    GDK_DRAWABLE_HANDLE (drawable)));
Packit Service fb6fa5
Packit Service fb6fa5
  if (!image)
Packit Service fb6fa5
    image = _gdk_image_new_for_depth (screen, GDK_IMAGE_FASTEST, NULL, width, height,
Packit Service fb6fa5
				      gdk_drawable_get_depth (drawable));
Packit Service fb6fa5
Packit Service fb6fa5
  gc = gdk_gc_new ((GdkDrawable *) image->windowing_data);
Packit Service fb6fa5
  _gdk_win32_blit
Packit Service fb6fa5
    (FALSE,
Packit Service fb6fa5
     GDK_DRAWABLE_IMPL_WIN32 (GDK_PIXMAP_OBJECT (image->windowing_data)->impl),
Packit Service fb6fa5
     gc, drawable, src_x, src_y, dest_x, dest_y, width, height);
Packit Service fb6fa5
  g_object_unref (gc);
Packit Service fb6fa5
Packit Service fb6fa5
  return image;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
guint32
Packit Service fb6fa5
gdk_image_get_pixel (GdkImage *image,
Packit Service fb6fa5
		     gint      x,
Packit Service fb6fa5
		     gint      y)
Packit Service fb6fa5
{
Packit Service fb6fa5
  guchar *pixelp;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (image != NULL, 0);
Packit Service fb6fa5
  g_return_val_if_fail (x >= 0 && x < image->width, 0);
Packit Service fb6fa5
  g_return_val_if_fail (y >= 0 && y < image->height, 0);
Packit Service fb6fa5
Packit Service fb6fa5
  if (!(x >= 0 && x < image->width && y >= 0 && y < image->height))
Packit Service fb6fa5
      return 0;
Packit Service fb6fa5
Packit Service fb6fa5
  if (image->depth == 1)
Packit Service fb6fa5
    return (((guchar *) image->mem)[y * image->bpl + (x >> 3)] & (1 << (7 - (x & 0x7)))) != 0;
Packit Service fb6fa5
Packit Service fb6fa5
  if (image->depth == 4)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      pixelp = (guchar *) image->mem + y * image->bpl + (x >> 1);
Packit Service fb6fa5
      if (x&1)
Packit Service fb6fa5
	return (*pixelp) & 0x0F;
Packit Service fb6fa5
Packit Service fb6fa5
      return (*pixelp) >> 4;
Packit Service fb6fa5
    }
Packit Service fb6fa5
    
Packit Service fb6fa5
  pixelp = (guchar *) image->mem + y * image->bpl + x * image->bpp;
Packit Service fb6fa5
      
Packit Service fb6fa5
  switch (image->bpp)
Packit Service fb6fa5
    {
Packit Service fb6fa5
    case 1:
Packit Service fb6fa5
      return *pixelp;
Packit Service fb6fa5
      
Packit Service fb6fa5
      /* Windows is always LSB, no need to check image->byte_order. */
Packit Service fb6fa5
    case 2:
Packit Service fb6fa5
      return pixelp[0] | (pixelp[1] << 8);
Packit Service fb6fa5
      
Packit Service fb6fa5
    case 3:
Packit Service fb6fa5
      return pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16);
Packit Service fb6fa5
Packit Service fb6fa5
    case 4:
Packit Service fb6fa5
      return pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  g_assert_not_reached ();
Packit Service fb6fa5
  return 0;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
gdk_image_put_pixel (GdkImage *image,
Packit Service fb6fa5
		     gint       x,
Packit Service fb6fa5
		     gint       y,
Packit Service fb6fa5
		     guint32    pixel)
Packit Service fb6fa5
{
Packit Service fb6fa5
  guchar *pixelp;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (image != NULL);
Packit Service fb6fa5
  g_return_if_fail (x >= 0 && x < image->width);
Packit Service fb6fa5
  g_return_if_fail (y >= 0 && y < image->height);
Packit Service fb6fa5
Packit Service fb6fa5
  if  (!(x >= 0 && x < image->width && y >= 0 && y < image->height))
Packit Service fb6fa5
    return;
Packit Service fb6fa5
Packit Service fb6fa5
  GdiFlush ();
Packit Service fb6fa5
  if (image->depth == 1)
Packit Service fb6fa5
    if (pixel & 1)
Packit Service fb6fa5
      ((guchar *) image->mem)[y * image->bpl + (x >> 3)] |= (1 << (7 - (x & 0x7)));
Packit Service fb6fa5
    else
Packit Service fb6fa5
      ((guchar *) image->mem)[y * image->bpl + (x >> 3)] &= ~(1 << (7 - (x & 0x7)));
Packit Service fb6fa5
  else if (image->depth == 4)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      pixelp = (guchar *) image->mem + y * image->bpl + (x >> 1);
Packit Service fb6fa5
Packit Service fb6fa5
      if (x&1)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  *pixelp &= 0xF0;
Packit Service fb6fa5
	  *pixelp |= (pixel & 0x0F);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  *pixelp &= 0x0F;
Packit Service fb6fa5
	  *pixelp |= (pixel << 4);
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      pixelp = (guchar *) image->mem + y * image->bpl + x * image->bpp;
Packit Service fb6fa5
      
Packit Service fb6fa5
      /* Windows is always LSB, no need to check image->byte_order. */
Packit Service fb6fa5
      switch (image->bpp)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	case 4:
Packit Service fb6fa5
	  pixelp[3] = 0;
Packit Service fb6fa5
	case 3:
Packit Service fb6fa5
	  pixelp[2] = ((pixel >> 16) & 0xFF);
Packit Service fb6fa5
	case 2:
Packit Service fb6fa5
	  pixelp[1] = ((pixel >> 8) & 0xFF);
Packit Service fb6fa5
	case 1:
Packit Service fb6fa5
	  pixelp[0] = (pixel & 0xFF);
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_win32_image_destroy (GdkImage *image)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkPixmap *pixmap;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (GDK_IS_IMAGE (image));
Packit Service fb6fa5
Packit Service fb6fa5
  pixmap = image->windowing_data;
Packit Service fb6fa5
Packit Service fb6fa5
  if (pixmap == NULL)		/* This means that _gdk_image_exit()
Packit Service fb6fa5
				 * destroyed the image already, and
Packit Service fb6fa5
				 * now we're called a second time from
Packit Service fb6fa5
				 * _finalize()
Packit Service fb6fa5
				 */
Packit Service fb6fa5
    return;
Packit Service fb6fa5
  
Packit Service fb6fa5
  GDK_NOTE (IMAGE, g_print ("gdk_win32_image_destroy: %p\n",
Packit Service fb6fa5
			    GDK_PIXMAP_HBITMAP (pixmap)));
Packit Service fb6fa5
Packit Service fb6fa5
  g_object_unref (pixmap);
Packit Service fb6fa5
  image->windowing_data = NULL;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
gint
Packit Service fb6fa5
_gdk_windowing_get_bits_for_depth (GdkDisplay *display,
Packit Service fb6fa5
                                   gint        depth)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (display == gdk_display_get_default (), 0);
Packit Service fb6fa5
Packit Service fb6fa5
  switch (depth)
Packit Service fb6fa5
    {
Packit Service fb6fa5
    case 1:
Packit Service fb6fa5
      return 1;
Packit Service fb6fa5
Packit Service fb6fa5
    case 2:
Packit Service fb6fa5
    case 3:
Packit Service fb6fa5
    case 4:
Packit Service fb6fa5
      return 4;
Packit Service fb6fa5
Packit Service fb6fa5
    case 5:
Packit Service fb6fa5
    case 6:
Packit Service fb6fa5
    case 7:
Packit Service fb6fa5
    case 8:
Packit Service fb6fa5
      return 8;
Packit Service fb6fa5
Packit Service fb6fa5
    case 15:
Packit Service fb6fa5
    case 16:
Packit Service fb6fa5
      return 16;
Packit Service fb6fa5
Packit Service fb6fa5
    case 24:
Packit Service fb6fa5
    case 32:
Packit Service fb6fa5
      return 32;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  g_assert_not_reached ();
Packit Service fb6fa5
  return 0;
Packit Service fb6fa5
}