[gtkada] Addition of Gdk_New_From_Data into Gdk.Pixbuf

Anne et Damien Carbonne aetdcarbonne at free.fr
Mon Jul 13 13:03:38 CEST 2009


Hi,

As Gdk_New_From_Data is currently missing from Gdk.Pixbuf, I created a 
binding for it (in a child package of Gtk.Pixbuf).
Would you consider adding this directly into to Gtk.Pixbuf?
Is the attached code sufficient or would you prefer a diff?

Regards,

Damien Carbonne


------------------------------------------------------------------------------------
-- Specification

-- with System;

   type Guchar_Array_Ptr is access all Guchar_Array;

   type Gdk_Destroy_Notify is access procedure
     (Pixels : in out Guchar_Array_Ptr;
      Data : System.Address);

   function Gdk_New_From_Data
     (Data            : Guchar_Array_Ptr;
      Colorspace      : Gdk_Colorspace := Colorspace_RGB;
      Has_Alpha       : Boolean := False;
      Bits_Per_Sample : Gint := 8;
      Width           : Gint;
      Height          : Gint;
      Rowstride       : Gint;
      Destroy_Fn      : Gdk_Destroy_Notify := null;
      Destroy_Fn_Data : System.Address := System.Null_Address)
      return Gdk_Pixbuf;
   --  Creates a new GdkPixbuf out of in-memory image data.
   --  Currently only RGB images with 8 bits per sample are supported.
   --
   --  Width and Height must be > 0
   --  Rowstride is the distance in bytes between row starts.
   --  A typical value is 4 * Width when ther is an Alpha channel.
   --  Destroy_Fn is an access to a procedure used to free data when the
   --  pixbuf's reference count drops to zero, or null if teh data 
should not
   --  be freed.
   --  Destroy_Fn_Data is the closure data to pass to the destroy 
notification
   --  procedure.
   --  This function returns the newly-created GdkPixbuf structure with a
   --  reference count of 1


------------------------------------------------------------------------------------
-- Body

-- with Ada.Unchecked_Conversion;
-- with Ada.Unchecked_Deallocation;

   type Proxy_Data is record
      Pixels : Guchar_Array_Ptr;
      Destroy_Fn : Gdk_Destroy_Notify;
      Destroy_Fn_Data : System.Address;
   end record;
   --  This is used as a proxy object to do minimum conversions from C types
   --  to Ada types.
   --  By copying Pixels (access) in this record, we avoid warnings at
   --  instantiation of System.Address_To_Access_Conversions
   --  with unconstrained arrays.

   type Proxy_Data_Ptr is access Proxy_Data;

   procedure Proxy_Destroy
     (Pixels : System.Address;
      Data : System.Address); -- expected to be of type Proxy_Data_Ptr

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

   function Gdk_New_From_Data
     (Data            : Guchar_Array_Ptr;
      Colorspace      : Gdk_Colorspace := Colorspace_RGB;
      Has_Alpha       : Boolean := False;
      Bits_Per_Sample : Gint := 8;
      Width           : Gint;
      Height          : Gint;
      Rowstride       : Gint;
      Destroy_Fn      : Gdk_Destroy_Notify := null;
      Destroy_Fn_Data : System.Address := System.Null_Address)
      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 : System.Address)
         return Gdk_Pixbuf;
      pragma Import (C, Internal, "gdk_pixbuf_new_from_data");
      use type System.Address;
   begin
      if Destroy_Fn /= null then
         -- Create a proxy data only if the user has provided
         -- a destroy function.
         -- If only destroy_fn_data has been provided, this is an error
         declare
            C_Data : constant Proxy_Data_Ptr := new Proxy_Data;
         begin
            C_Data.Destroy_Fn := Destroy_Fn;
            C_Data.Destroy_Fn_Data := Destroy_Fn_Data;
            C_Data.Pixels := Data;

            return Internal
              (Data.all'Address,
               Colorspace, Boolean'Pos (Has_Alpha), Bits_Per_Sample,
               Width, Height, Rowstride,
               Proxy_Destroy'Address, C_Data.all'Address);
         end;
      else
         pragma Assert (Destroy_Fn_Data = System.Null_Address);
         return Internal
           (Data.all'Address,
            Colorspace, Boolean'Pos (Has_Alpha), Bits_Per_Sample,
            Width, Height, Rowstride,
            System.Null_Address, System.Null_Address);
      end if;
   end Gdk_New_From_Data;

   -------------------
   -- Proxy_Destroy --
   -------------------

   procedure Proxy_Destroy
     (Pixels : System.Address;
      Data : System.Address)
   is
      use type System.Address;
      function To_Ada is new
        Ada.Unchecked_Conversion (System.Address, Proxy_Data_Ptr);
      procedure Free is new
        Ada.Unchecked_Deallocation (Proxy_Data, Proxy_Data_Ptr);
      Ada_Data : Proxy_Data_Ptr := To_Ada (Data);
   begin
      pragma Assert (Ada_Data /= null);
      pragma Assert (Pixels = Ada_Data.Pixels.all'Address);
      Ada_Data.Destroy_Fn.all (Ada_Data.Pixels, Ada_Data.Destroy_Fn_Data);
      Free (Ada_Data);
   end Proxy_Destroy;

------------------------------------------------------------------------------------




More information about the gtkada mailing list