------------------------------------------------------------------------------
--                  GtkAda - Ada95 binding for Gtk+/Gnome                   --
--                                                                          --
--                     Copyright (C) 2000-2018, AdaCore                     --
--                                                                          --
-- This library is free software;  you can redistribute it and/or modify it --
-- under terms of the  GNU General Public License  as published by the Free --
-- Software  Foundation;  either version 3,  or (at your  option) any later --
-- version. This library is distributed in the hope that it will be useful, --
-- but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN- --
-- TABILITY or FITNESS FOR A PARTICULAR PURPOSE.                            --
--                                                                          --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception,   --
-- version 3.1, as published by the Free Software Foundation.               --
--                                                                          --
-- You should have received a copy of the GNU General Public License and    --
-- a copy of the GCC Runtime Library Exception along with this program;     --
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
-- <http://www.gnu.org/licenses/>.                                          --
--                                                                          --
------------------------------------------------------------------------------

with Gdk.Display; use Gdk.Display;
with Glib.Object; use Glib.Object;
with Ada.Unchecked_Deallocation;

package body Gdk.Pixbuf is

   type Proxy_Data is record
      Pixels : Guchar_Array_Access;
      --  Access to the Ada allocated memory used by Gdk_New_From_Data.
      --  Strictly, this is not necessary, as this access could be
      --  built from the Pixels parameter of the destroy callback.
      --  However, it's not possible to easily and portably convert an
      --  Address to an access to unconstrained array.
   end record;
   pragma Convention (C, Proxy_Data);
   --  Closure data attached to a pixbuf created from user data.

   type Proxy_Data_Access is access Proxy_Data;
   pragma Convention (C, Proxy_Data_Access);

   procedure Free is new Ada.Unchecked_Deallocation
     (Object => Proxy_Data, Name => Proxy_Data_Access);

   procedure Destroy_Pixels
     (Pixels : System.Address;
      Data   : Proxy_Data_Access);
   pragma Convention (C, Destroy_Pixels);
   --  Low level, C compatible, callback called when the reference
   --  count of a pixbuf (that was created from user data) reaches 0.

   ---------------
   -- Add_Alpha --
   ---------------

   function Add_Alpha
     (Pixbuf           : Gdk_Pixbuf;
      Substitute_Color : Boolean := False;
      Red              : Guchar := 0;
      Green            : Guchar := 0;
      Blue             : Guchar := 0) return Gdk_Pixbuf
   is
      function Internal
        (Pixbuf           : System.Address;
         Substitute_Color : Gboolean;
         Red              : Guchar;
         Green            : Guchar;
         Blue             : Guchar) return System.Address;
      pragma Import (C, Internal, "gdk_pixbuf_add_alpha");

   begin
      return Convert
        (Internal
           (Get_Object (Pixbuf),
            Boolean'Pos (Substitute_Color),
            Red,
            Green,
            Blue));
   end Add_Alpha;

   ---------------
   -- Composite --
   ---------------

   procedure Composite
     (Src           : Gdk_Pixbuf;
      Dest          : Gdk_Pixbuf;
      Dest_X        : Gint;
      Dest_Y        : Gint;
      Dest_Width    : Gint;
      Dest_Height   : Gint;
      Offset_X      : Gdouble := 0.0;
      Offset_Y      : Gdouble := 0.0;
      Scale_X       : Gdouble := 1.0;
      Scale_Y       : Gdouble := 1.0;
      Inter_Type    : Gdk_Interp_Type := Interp_Bilinear;
      Overall_Alpha : Alpha_Range := 128)
   is
      procedure Internal
        (Src           : System.Address;
         Dest          : System.Address;
         Dest_X        : Gint;
         Dest_Y        : Gint;
         Dest_Width    : Gint;
         Dest_Height   : Gint;
         Offset_X      : Gdouble := 0.0;
         Offset_Y      : Gdouble := 0.0;
         Scale_X       : Gdouble := 1.0;
         Scale_Y       : Gdouble := 1.0;
         Inter_Type    : Gdk_Interp_Type := Interp_Bilinear;
         Overall_Alpha : Alpha_Range := 128);
      pragma Import (C, Internal, "gdk_pixbuf_composite");

   begin
      Internal
        (Get_Object (Src),
         Get_Object (Dest),
         Dest_X,
         Dest_Y,
         Dest_Width,
         Dest_Height,
         Offset_X,
         Offset_Y,
         Scale_X,
         Scale_Y,
         Inter_Type,
         Overall_Alpha);
   end Composite;

   ---------------------
   -- Composite_Color --
   ---------------------

   procedure Composite_Color
     (Src           : Gdk_Pixbuf;
      Dest          : Gdk_Pixbuf;
      Dest_X        : Gint;
      Dest_Y        : Gint;
      Dest_Width    : Gint;
      Dest_Height   : Gint;
      Offset_X      : Gdouble := 0.0;
      Offset_Y      : Gdouble := 0.0;
      Scale_X       : Gdouble := 1.0;
      Scale_Y       : Gdouble := 1.0;
      Inter_Type    : Gdk_Interp_Type := Interp_Bilinear;
      Overall_Alpha : Alpha_Range := 128;
      Check_X       : Gint := 0;
      Check_Y       : Gint := 0;
      Check_Size    : Gint := 0;
      Color1        : Guint32 := 0;
      Color2        : Guint32 := 0)
   is
      procedure Internal
        (Src           : System.Address;
         Dest          : System.Address;
         Dest_X        : Gint;
         Dest_Y        : Gint;
         Dest_Width    : Gint;
         Dest_Height   : Gint;
         Offset_X      : Gdouble;
         Offset_Y      : Gdouble;
         Scale_X       : Gdouble;
         Scale_Y       : Gdouble;
         Inter_Type    : Gdk_Interp_Type;
         Overall_Alpha : Alpha_Range;
         Check_X       : Gint;
         Check_Y       : Gint;
         Check_Size    : Gint;
         Color1        : Guint32;
         Color2        : Guint32);
      pragma Import (C, Internal, "gdk_pixbuf_composite_color");

   begin
      Internal
        (Get_Object (Src),
         Get_Object (Dest),
         Dest_X,
         Dest_Y,
         Dest_Width,
         Dest_Height,
         Offset_X,
         Offset_Y,
         Scale_X,
         Scale_Y,
         Inter_Type,
         Overall_Alpha,
         Check_X,
         Check_Y,
         Check_Size,
         Color1,
         Color2);
   end Composite_Color;

   ----------------------------
   -- Composite_Color_Simple --
   ----------------------------

   function Composite_Color_Simple
     (Src           : Gdk_Pixbuf;
      Dest_Width    : Gint;
      Dest_Height   : Gint;
      Inter_Type    : Gdk_Interp_Type := Interp_Bilinear;
      Overall_Alpha : Alpha_Range := 128;
      Color1        : Guint32 := 0;
      Color2        : Guint32 := 0) return Gdk_Pixbuf
   is
      function Internal
        (Src           : System.Address;
         Dest_Width    : Gint;
         Dest_Height   : Gint;
         Inter_Type    : Gdk_Interp_Type := Interp_Bilinear;
         Overall_Alpha : Alpha_Range := 128;
         Color1        : Guint32 := 0;
         Color2        : Guint32 := 0) return System.Address;
      pragma Import (C, Internal, "gdk_pixbuf_composite_color_simple");

   begin
      return Convert
        (Internal
           (Get_Object (Src),
            Dest_Width,
            Dest_Height,
            Inter_Type,
            Overall_Alpha,
            Color1,
            Color2));
   end Composite_Color_Simple;

   -------------
   -- Convert --
   -------------

   function Convert (P : System.Address) return Gdk_Pixbuf is
      use type System.Address;

      Stub : Gdk_Pixbuf_Record;

   begin
      if P = System.Null_Address then
         return null;

      else
         return Gdk_Pixbuf (Get_User_Data (P, Stub));
      end if;
   end Convert;

   ----------
   -- Copy --
   ----------

   function Copy (Pixbuf : Gdk_Pixbuf) return Gdk_Pixbuf is
      function Internal (Pixbuf : System.Address) return System.Address;
      pragma Import (C, Internal, "gdk_pixbuf_copy");

   begin
      return Convert (Internal (Get_Object (Pixbuf)));
   end Copy;

   ---------------
   -- Copy_Area --
   ---------------

   procedure Copy_Area
     (Src_Pixbuf  : Gdk_Pixbuf;
      Src_X       : Gint;
      Src_Y       : Gint;
      Width       : Gint;
      Height      : Gint;
      Dest_Pixbuf : Gdk_Pixbuf;
      Dest_X      : Gint;
      Dest_Y      : Gint)
   is
      procedure Internal
        (Src_Pixbuf  : System.Address;
         Src_X       : Gint;
         Src_Y       : Gint;
         Width       : Gint;
         Height      : Gint;
         Dest_Pixbuf : System.Address;
         Dest_X      : Gint;
         Dest_Y      : Gint);
      pragma Import (C, Internal, "gdk_pixbuf_copy_area");

   begin
      Internal
        (Get_Object (Src_Pixbuf),
         Src_X,
         Src_Y,
         Width,
         Height,
         Get_Object (Dest_Pixbuf),
         Dest_X,
         Dest_Y);
   end Copy_Area;

   --------------------
   -- Destroy_Pixels --
   --------------------

   procedure Destroy_Pixels
     (Pixels : System.Address;
      Data   : Proxy_Data_Access)
   is
      pragma Unreferenced (Pixels);
      Tmp : Proxy_Data_Access := Data;
   begin
      Free (Data.Pixels);
      Free (Tmp);
   end Destroy_Pixels;

   ----------
   -- Fill --
   ----------

   procedure Fill (Pixbuf : Gdk_Pixbuf; Pixel : Guint32) is
      procedure Internal (Pixbuf : System.Address; Pixel : Guint32);
      pragma Import (C, Internal, "gdk_pixbuf_fill");
   begin
      Internal (Get_Object (Pixbuf), Pixel);
   end Fill;

   -------------
   -- Gdk_New --
   -------------

   function Gdk_New
     (Colorspace      : Gdk_Colorspace := Colorspace_RGB;
      Has_Alpha       : Boolean := False;
      Bits_Per_Sample : Gint := 8;
      Width           : Gint;
      Height          : Gint) return Gdk_Pixbuf
   is
      function Internal
        (Colorspace      : Gdk_Colorspace;
         Has_Alpha       : Gboolean;
         Bits_Per_Sample : Gint;
         Width           : Gint;
         Height          : Gint) return System.Address;
      pragma Import (C, Internal, "gdk_pixbuf_new");

   begin
      return Convert
        (Internal
           (Colorspace,
            Boolean'Pos (Has_Alpha),
            Bits_Per_Sample,
            Width,
            Height));
   end Gdk_New;

   -----------------------
   -- Gdk_New_From_Data --
   -----------------------

   function Gdk_New_From_Data
     (Data              : Guchar_Array_Access;
      Colorspace        : Gdk_Colorspace := Colorspace_RGB;
      Has_Alpha         : Boolean := False;
      Bits_Per_Sample   : Gint := 8;
      Width             : Gint;
      Height            : Gint;
      Rowstride         : Gint;
      Auto_Destroy_Data : Boolean := True) return Gdk_Pixbuf
   is
      function Internal
        (Data            : System.Address;
         Colorspace      : Gdk_Colorspace;
         Has_Alpha       : Gboolean;
         Bits_Per_Sample : Gint;
         Width           : Gint;
         Height          : Gint;
         Row_Stride      : Gint;
         Destroy_Fn      : System.Address;
         Destroy_Fn_Data : Proxy_Data_Access) return System.Address;
      pragma Import (C, Internal, "gdk_pixbuf_new_from_data");

   begin
      if Auto_Destroy_Data then
         return Convert
           (Internal
              (Data.all'Address,
               Colorspace,
               Boolean'Pos (Has_Alpha),
               Bits_Per_Sample,
               Width,
               Height,
               Rowstride,
               Destroy_Pixels'Address,
               new Proxy_Data'(Pixels => Data)));

      else
         return Convert
           (Internal
              (Data.all'Address,
               Colorspace,
               Boolean'Pos (Has_Alpha),
               Bits_Per_Sample,
               Width,
               Height,
               Rowstride,
               System.Null_Address,
               null));
      end if;
   end Gdk_New_From_Data;

   -----------------------
   -- Gdk_New_From_File --
   -----------------------

   procedure Gdk_New_From_File
     (Pixbuf   : out Gdk_Pixbuf;
      Filename : String;
      Error    : out GError)
   is
      function Internal
        (Filename : String;
         Error    : access GError) return System.Address;
      pragma Import (C, Internal, "ada_gdk_pixbuf_new_from_file");

      Err : aliased GError;

   begin
      Pixbuf := Convert (Internal (Filename & ASCII.NUL, Err'Access));
      Error := Err;
   end Gdk_New_From_File;

   -----------------------
   -- Gdk_New_From_File --
   -----------------------

   procedure Gdk_New_From_File
     (Animation : out Gdk_Pixbuf_Animation;
      Filename  : String;
      Error     : out GError)
   is
      function Internal
        (Filename : String;
         Error    : access GError) return Gdk_Pixbuf_Animation;
      pragma Import (C, Internal, "ada_gdk_pixbuf_animation_new_from_file");

      Err : aliased GError;

   begin
      Animation := Internal (Filename & ASCII.NUL, Err'Access);
      Error := Err;
   end Gdk_New_From_File;

   ---------------------------
   -- Gdk_New_From_Xpm_Data --
   ---------------------------

   function Gdk_New_From_Xpm_Data
     (Data : Gtkada.Types.Chars_Ptr_Array) return Gdk_Pixbuf
   is
      function Internal
        (Data : Gtkada.Types.Chars_Ptr_Array) return System.Address;
      pragma Import (C, Internal, "gdk_pixbuf_new_from_xpm_data");

   begin
      return Convert (Internal (Data));
   end Gdk_New_From_Xpm_Data;

   -----------------------
   -- Gdk_New_Subpixbuf --
   -----------------------

   function Gdk_New_Subpixbuf
     (Src_Pixbuf : Gdk_Pixbuf;
      Src_X      : Gint;
      Src_Y      : Gint;
      Width      : Gint;
      Height     : Gint) return Gdk_Pixbuf
   is
      function Internal
        (Src_Pixbuf : System.Address;
         Src_X      : Gint;
         Src_Y      : Gint;
         Width      : Gint;
         Height     : Gint) return System.Address;
      pragma Import (C, Internal, "gdk_pixbuf_new_subpixbuf");

   begin
      return Convert
        (Internal (Get_Object (Src_Pixbuf), Src_X, Src_Y, Width, Height));
   end Gdk_New_Subpixbuf;

   -------------------------
   -- Get_Bits_Per_Sample --
   -------------------------

   function Get_Bits_Per_Sample (Pixbuf : Gdk_Pixbuf) return Gint is
      function Internal (Pixbuf : System.Address) return Gint;
      pragma Import (C, Internal, "gdk_pixbuf_get_bits_per_sample");

   begin
      return Internal (Get_Object (Pixbuf));
   end Get_Bits_Per_Sample;

   --------------------
   -- Get_Colorspace --
   --------------------

   function Get_Colorspace (Pixbuf : Gdk_Pixbuf) return Gdk_Colorspace is
      function Internal (Pixbuf : System.Address) return Gdk_Colorspace;
      pragma Import (C, Internal, "gdk_pixbuf_get_colorspace");

   begin
      return Internal (Get_Object (Pixbuf));
   end Get_Colorspace;

   ---------------------
   -- Get_From_Window --
   ---------------------

   function Get_From_Window
     (Window : Gdk_Window;
      Src_X  : Gint;
      Src_Y  : Gint;
      Width  : Gint;
      Height : Gint) return Gdk_Pixbuf
   is
      function Internal
        (Window : Gdk_Window;
         Src_X  : Gint;
         Src_Y  : Gint;
         Width  : Gint;
         Height : Gint) return System.Address;
      pragma Import (C, Internal, "gdk_pixbuf_get_from_window");

   begin
      return Convert (Internal (Window, Src_X, Src_Y, Width, Height));
   end Get_From_Window;

   ----------------------
   -- Get_From_Surface --
   ----------------------

   function Get_From_Surface
     (Surface : Cairo.Cairo_Surface;
      Src_X   : Gint;
      Src_Y   : Gint;
      Width   : Gint;
      Height  : Gint) return Gdk_Pixbuf
   is
      function Internal
        (Surface : Cairo.Cairo_Surface;
         Src_X  : Gint;
         Src_Y  : Gint;
         Width  : Gint;
         Height : Gint) return System.Address;
      pragma Import (C, Internal, "gdk_pixbuf_get_from_surface");

   begin
      return Convert (Internal (Surface, Src_X, Src_Y, Width, Height));
   end Get_From_Surface;

   -------------------
   -- Get_Has_Alpha --
   -------------------

   function Get_Has_Alpha (Pixbuf : Gdk_Pixbuf) return Boolean is
      function Internal (Pixbuf : System.Address) return Gboolean;
      pragma Import (C, Internal, "gdk_pixbuf_get_has_alpha");

   begin
      return Internal (Get_Object (Pixbuf)) /= 0;
   end Get_Has_Alpha;

   ----------------
   -- Get_Height --
   ----------------

   function Get_Height (Pixbuf : Gdk_Pixbuf) return Gint is
      function Internal (Pixbuf : System.Address) return Gint;
      pragma Import (C, Internal, "gdk_pixbuf_get_height");

   begin
      return Internal (Get_Object (Pixbuf));
   end Get_Height;

   ----------------
   -- Get_Height --
   ----------------

   function Get_Height (Animation : Gdk_Pixbuf_Animation) return Gint is
      function Internal (Animation : Gdk_Pixbuf_Animation) return Gint;
      pragma Import (C, Internal, "gdk_pixbuf_animation_get_height");

   begin
      return Internal (Animation);
   end Get_Height;

   ---------------
   -- Get_Image --
   ---------------

   function Get_Image (Cursor : Gdk.Gdk_Cursor) return Gdk_Pixbuf is
      function Internal (Cursor : Gdk.Gdk_Cursor) return System.Address;
      pragma Import (C, Internal, "gdk_cursor_get_image");

   begin
      return Convert (Internal (Cursor));
   end Get_Image;

   --------------------
   -- Get_N_Channels --
   --------------------

   function Get_N_Channels (Pixbuf : Gdk_Pixbuf) return Gint is
      function Internal (Pixbuf : System.Address) return Gint;
      pragma Import (C, Internal, "gdk_pixbuf_get_n_channels");

   begin
      return Internal (Get_Object (Pixbuf));
   end Get_N_Channels;

   ----------------
   -- Get_Pixbuf --
   ----------------

   function Get_Pixbuf (Iter : Gdk_Pixbuf_Animation_Iter) return Gdk_Pixbuf is
      function Internal
        (Iter : Gdk_Pixbuf_Animation_Iter) return System.Address;
      pragma Import (C, Internal, "gdk_pixbuf_animation_iter_get_pixbuf");

   begin
      return Convert (Internal (Iter));
   end Get_Pixbuf;

   ----------------
   -- Get_Pixels --
   ----------------

   function Get_Pixels
     (Pixbuf : Gdk_Pixbuf) return Rgb_Buffer_Access
   is
      function Internal
        (Pixbuf : System.Address) return Rgb_Buffer_Access;
      pragma Import (C, Internal, "gdk_pixbuf_get_pixels");

   begin
      return Internal (Get_Object (Pixbuf));
   end Get_Pixels;

   -------------------
   -- Get_Rowstride --
   -------------------

   function Get_Rowstride (Pixbuf : Gdk_Pixbuf) return Gint is
      function Internal (Pixbuf : System.Address) return Gint;
      pragma Import (C, Internal, "gdk_pixbuf_get_rowstride");

   begin
      return Internal (Get_Object (Pixbuf));
   end Get_Rowstride;

   ----------------------
   -- Get_Static_Image --
   ----------------------

   function Get_Static_Image
     (Animation : Gdk_Pixbuf_Animation) return Gdk_Pixbuf
   is
      function Internal
        (Animation : Gdk_Pixbuf_Animation) return System.Address;
      pragma Import (C, Internal, "gdk_pixbuf_animation_get_static_image");

   begin
      return Convert (Internal (Animation));
   end Get_Static_Image;

   ---------------
   -- Get_Width --
   ---------------

   function Get_Width (Pixbuf : Gdk_Pixbuf) return Gint is
      function Internal (Pixbuf : System.Address) return Gint;
      pragma Import (C, Internal, "gdk_pixbuf_get_width");

   begin
      return Internal (Get_Object (Pixbuf));
   end Get_Width;

   ---------------
   -- Get_Width --
   ---------------

   function Get_Width (Animation : Gdk_Pixbuf_Animation) return Gint is
      function Internal (Animation : Gdk_Pixbuf_Animation) return Gint;
      pragma Import (C, Internal, "gdk_pixbuf_animation_get_width");

   begin
      return Internal (Animation);
   end Get_Width;

   ---------
   -- Ref --
   ---------

   procedure Ref (Animation : Gdk_Pixbuf_Animation) is
      procedure Internal (Pixbuf : Gdk_Pixbuf_Animation);
      pragma Import (C, Internal, "gdk_pixbuf_animation_ref");

   begin
      Internal (Animation);
   end Ref;

   procedure Ref (Iter : Gdk_Pixbuf_Animation_Iter) is
      procedure Internal (Iter : Gdk_Pixbuf_Animation_Iter);
      pragma Import (C, Internal, "g_object_ref");

   begin
      Internal (Iter);
   end Ref;

   ---------------------------
   -- Saturate_And_Pixelate --
   ---------------------------

   procedure Saturate_And_Pixelate
     (Src        : Gdk_Pixbuf;
      Dest       : Gdk_Pixbuf;
      Saturation : Gfloat;
      Pixelate   : Boolean := True)
   is
      procedure Internal
        (Src        : System.Address;
         Dest       : System.Address;
         Saturation : Gfloat;
         Pixelate   : Gboolean);
      pragma Import (C, Internal, "gdk_pixbuf_saturate_and_pixelate");

   begin
      Internal
        (Get_Object (Src),
         Get_Object (Dest),
         Saturation,
         Boolean'Pos (Pixelate));
   end Saturate_And_Pixelate;

   ----------
   -- Save --
   ----------

   procedure Save
     (Pixbuf   : Gdk_Pixbuf;
      Filename : String;
      Format   : File_Format;
      Error    : out GError;
      Quality  : Image_Quality := Image_Quality'Last;
      Depth    : Integer := 32)
   is
      procedure Internal
        (Pixbuf   : System.Address;
         Filename : String;
         Format   : String;
         Error    : out GError;
         Term     : System.Address := System.Null_Address);

      procedure Internal
        (Pixbuf   : System.Address;
         Filename : String;
         Format   : String;
         Error    : out GError;
         Key      : String;
         Value    : String);
      pragma Import (C, Internal, "ada_gdk_pixbuf_save");

   begin
      Error := null;

      case Format is
         when JPEG =>
            Internal
              (Get_Object (Pixbuf),
               Filename & ASCII.NUL,
               "jpeg" & ASCII.NUL,
               Error,
               "quality" & ASCII.NUL,
               Image_Quality'Image (Quality) & ASCII.NUL);

         when PNG =>
            Internal
              (Get_Object (Pixbuf),
               Filename & ASCII.NUL,
               "png" & ASCII.NUL,
               Error);

         when ICO =>
            Internal
              (Get_Object (Pixbuf),
               Filename & ASCII.NUL,
               "ico" & ASCII.NUL,
               Error,
               "depth" & ASCII.NUL,
               Integer'Image (Depth));

         when BMP =>
            Internal
              (Get_Object (Pixbuf),
               Filename & ASCII.NUL,
               "bmp" & ASCII.NUL,
               Error);
      end case;
   end Save;

   -----------
   -- Scale --
   -----------

   procedure Scale
     (Src          : Gdk_Pixbuf;
      Dest         : Gdk_Pixbuf;
      Dest_X       : Gint;
      Dest_Y       : Gint;
      Dest_Width   : Gint;
      Dest_Height  : Gint;
      Offset_X     : Gdouble := 0.0;
      Offset_Y     : Gdouble := 0.0;
      Scale_X      : Gdouble := 1.0;
      Scale_Y      : Gdouble := 1.0;
      Inter_Type   : Gdk_Interp_Type := Interp_Bilinear)
   is
      procedure Internal
        (Src          : System.Address;
         Dest         : System.Address;
         Dest_X       : Gint;
         Dest_Y       : Gint;
         Dest_Width   : Gint;
         Dest_Height  : Gint;
         Offset_X     : Gdouble := 0.0;
         Offset_Y     : Gdouble := 0.0;
         Scale_X      : Gdouble := 1.0;
         Scale_Y      : Gdouble := 1.0;
         Inter_Type   : Gdk_Interp_Type);
      pragma Import (C, Internal, "gdk_pixbuf_scale");

   begin
      Internal
        (Get_Object (Src),
         Get_Object (Dest),
         Dest_X,
         Dest_Y,
         Dest_Width,
         Dest_Height,
         Offset_X,
         Offset_Y,
         Scale_X,
         Scale_Y,
         Inter_Type);
   end Scale;

   ------------------
   -- Scale_Simple --
   ------------------

   function Scale_Simple
     (Src           : Gdk_Pixbuf;
      Dest_Width    : Gint;
      Dest_Height   : Gint;
      Inter_Type    : Gdk_Interp_Type := Interp_Bilinear) return Gdk_Pixbuf
   is
      function Internal
        (Src           : System.Address;
         Dest_Width    : Gint;
         Dest_Height   : Gint;
         Inter_Type    : Gdk_Interp_Type) return System.Address;
      pragma Import (C, Internal, "gdk_pixbuf_scale_simple");

   begin
      return Convert
        (Internal (Get_Object (Src), Dest_Width, Dest_Height, Inter_Type));
   end Scale_Simple;

   -----------
   -- Unref --
   -----------

   procedure Unref (Animation : Gdk_Pixbuf_Animation) is
      procedure Internal (Pixbuf : Gdk_Pixbuf_Animation);
      pragma Import (C, Internal, "gdk_pixbuf_animation_unref");

   begin
      Internal (Animation);
   end Unref;

   procedure Unref (Iter : Gdk_Pixbuf_Animation_Iter) is
      procedure Internal (Iter : Gdk_Pixbuf_Animation_Iter);
      pragma Import (C, Internal, "g_object_unref");

   begin
      Internal (Iter);
   end Unref;

   ---------------------
   -- Is_Static_Image --
   ---------------------

   function Is_Static_Image
     (Animation : Gdk_Pixbuf_Animation) return Boolean
   is
      function Internal (Animation : Gdk_Pixbuf_Animation) return Gboolean;
      pragma Import (C, Internal, "gdk_pixbuf_animation_is_static_image");

   begin
      return Internal (Animation) /= 0;
   end Is_Static_Image;

   --------------------------------
   -- On_Currently_Loading_Frame --
   --------------------------------

   function On_Currently_Loading_Frame
     (Iter : Gdk_Pixbuf_Animation_Iter) return Boolean
   is
      function Internal
        (Animation : Gdk_Pixbuf_Animation_Iter) return Gboolean;
      pragma Import
        (C, Internal, "gdk_pixbuf_animation_iter_on_currently_loading_frame");

   begin
      return Internal (Iter) /= 0;
   end On_Currently_Loading_Frame;

   -------------
   -- Advance --
   -------------

   function Advance
     (Iter          : Gdk_Pixbuf_Animation_Iter;
      Current_Timer : GTime_Val_Access := null) return Boolean
   is
      function Internal
        (Iter          : Gdk_Pixbuf_Animation_Iter;
         Current_Timer : GTime_Val_Access) return Gboolean;
      pragma Import (C, Internal, "gdk_pixbuf_animation_iter_advance");

   begin
      return Internal (Iter, Current_Timer) /= 0;
   end Advance;

   -------------------------
   -- Gdk_New_From_Pixbuf --
   -------------------------

   procedure Gdk_New_From_Pixbuf
     (Cursor  : out Gdk.Gdk_Cursor;
      Display : Gdk.Display.Gdk_Display := Gdk.Display.Get_Default;
      Pixbuf  : Gdk_Pixbuf;
      X       : Glib.Gint;
      Y       : Glib.Gint)
   is
      function Internal
        (D : System.Address; P : System.Address; X, Y : Gint)
         return Gdk_Cursor;
      pragma Import (C, Internal, "gdk_cursor_new_from_pixbuf");

   begin
      Cursor := Internal (Get_Object (Display), Get_Object (Pixbuf), X, Y);
   end Gdk_New_From_Pixbuf;

end Gdk.Pixbuf;
