DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦736f1183e⟧ Ada Source

    Length: 60416 (0xec00)
    Types: Ada Source
    Notes: 03_class, FILE, R1k_Segment, e3_tag, package body Xlbip_Image_Internal, seg_004f21

Derivation

└─⟦8527c1e9b⟧ Bits:30000544 8mm tape, Rational 1000, Arrival backup of disks in PAM's R1000
    └─ ⟦cfc2e13cd⟧ »Space Info Vol 2« 
        └─⟦this⟧ 

E3 Source Code



with Unchecked_Conversion;

with Xlbt_Arithmetic;  
use Xlbt_Arithmetic;  
with Xlbt_Basic3;  
use Xlbt_Basic3;  
with Xlbt_Exceptions;  
use Xlbt_Exceptions;  
with Xlbt_Image3;  
use Xlbt_Image3;  
with Xlbt_String;  
use Xlbt_String;

with Xlbp_Image;  
use Xlbp_Image;  
with Xlbp_Proc_Var;  
use Xlbp_Proc_Var;

with Xlbit_Library4;  
use Xlbit_Library4;

with Xlbmp_Error_Log;  
use Xlbmp_Error_Log;

package body Xlbip_Image_Internal is
------------------------------------------------------------------------------
-- X Library Internal Image Operations
--
-- Xlbip_Image_Internal - Operations for images.
------------------------------------------------------------------------------
-- Copyright 1989 - 1991 by Rational, Santa Clara, California.
-- Copyright 1985 - 1989 by the Massachusetts Institute of Technology
--
--                  All Rights Reserved.
--
-- Permission to use, copy, modify, and distribute this software and its
-- documentation for any purpose and without fee is hereby granted,
-- provided that the above copyright notice(s) appear in all copies and that
-- both that copyright notice(s) and this permission notice appear in
-- supporting documentation, and that the names of MIT or Rational not be
-- used in advertising or publicity pertaining to distribution of the software
-- without specific, written prior permission.
--
-- MIT and Rational disclaim all warranties with regard to this software,
-- including all implied warranties of merchantability and fitness, in no
-- event shall MIT or Rational be liable for any special, indirect or
-- consequential damages or any damages whatsoever resulting from loss of use,
-- data or profits, whether in an action of contract, negligence or other
-- tortious action, arising out of or in connection with the use or performance
-- of this software.
------------------------------------------------------------------------------

--\x0c
    subtype U_Char_4_Array is U_Char_Array (0 .. 3);

    function To_U_Char is new Unchecked_Conversion (X_Pixel,  
                                                    U_Char_4_Array);

    function From_U_Char is new Unchecked_Conversion (U_Char_4_Array,  
                                                      X_Pixel);  
    subtype U_Char_0_31 is U_Char range 0 .. 31;

    Private_Lo_Mask : constant U_Char_Array (0 .. 16#09# - 1) :=  
       (16#00#, 16#01#, 16#03#, 16#07#, 16#0F#, 16#1F#, 16#3F#, 16#7F#, 16#FF#);  
    Private_Hi_Mask : constant U_Char_Array (0 .. 16#09# - 1) :=  
       (16#FF#, 16#FE#, 16#FC#, 16#F8#, 16#F0#, 16#E0#, 16#C0#, 16#80#, 16#00#);

    Low_Bits_Table : constant X_Pixel_Array (0 .. 32) :=  
       (16#00000000#, 16#00000001#, 16#00000003#, 16#00000007#,  
        16#0000000F#, 16#0000001F#, 16#0000003F#, 16#0000007F#,  
        16#000000FF#, 16#000001FF#, 16#000003FF#, 16#000007FF#,  
        16#00000FFF#, 16#00001FFF#, 16#00003FFF#, 16#00007FFF#,  
        16#0000FFFF#, 16#0001FFFF#, 16#0003FFFF#, 16#0007FFFF#,  
        16#000FFFFF#, 16#001FFFFF#, 16#003FFFFF#, 16#007FFFFF#,  
        16#00FFFFFF#, 16#01FFFFFF#, 16#03FFFFFF#, 16#07FFFFFF#,  
        16#0FFFFFFF#, 16#1FFFFFFF#, 16#3FFFFFFF#, 16#7FFFFFFF#,  
        -1);

--\x0c
    procedure Private_X_Report_Bad_Image (Errtype : X_String;  
                                          Error   : String;  
                                          Routine : X_String) is  
    begin

        X_Report_Error ("XlibError", "BadImage",  
                        "Xlib; Bad image %1 {%2} found in routine %3.",  
                        Errtype,  
                        To_X_String (Error),  
                        Routine);  
        raise X_Library_Confusion;

    end Private_X_Report_Bad_Image;

--\x0c
    procedure Private_Reverse_Bytes (Bp : in out U_Char_Array) is  
    begin

        for I in Bp'Range loop  
            Bp (I) := Private_Reverse_Byte (S_Natural (Bp (I)));  
        end loop;

    end Private_Reverse_Bytes;

--\x0c
    ------------------------------------------------------------------------------
-- This module provides rudimentary manipulation routines for image data
-- structures.  The functions provided are:
--
--  X_Create_Image          Creates a default X_Image data structure
--  private_X_Destroy_Image Deletes an X_Image data structure
--  private_X_Get_Pixel     Reads a pixel from an image data structure
--  private_X_Get_Pixel_8   Reads a pixel from an 8-bit Z image data structure
--  private_X_Get_Pixel_1   Reads a pixel from a 1-bit image data structure
--  private_X_Put_Pixel     Writes a pixel into an image data structure
--  private_X_Put_Pixel_8   Writes a pixel into an 8-bit Z image data structure
--  private_X_Put_Pixel_1   Writes a pixel into a 1-bit image data structure
--  private_X_Sub_Image     Clones a new (sub)image from an existing one
--  private_X_Set_Image     Writes an image data pattern into another image
--  private_X_Add_Pixel     Adds a constant value to every pixel in an image
--
-- The logic contained in these routines makes several assumptions about
-- the image data structures, and at least for current implementations
-- these assumptions are believed to be true.  They are:
--
--  For all formats, bits_per_pixel is less than or equal to 32.
--  For X_Y formats, bitmap_unit is 8, 16, 24, or 32 bits.
--  For Z format, bits_per_pixel is 4, 8, 12, 16, 20, 24, 28 or 32 bits.
------------------------------------------------------------------------------

    procedure Private_Normalize_Image_Bits  
                 (Bpt        : in out U_Char_Array;  
                  Nb         :        S_Natural;      -- # bytes to normalize
                  Byte_Order :        X_Byte_Bit_Order;  
                  Unit_Size  :        U_Char; -- size of bitmap_unit or Z_pixel
                  Bit_Order  :        X_Byte_Bit_Order) is  
    begin

        if Byte_Order = Msb_First and Byte_Order /= Bit_Order then  
            case Unit_Size is

                when 4 =>  
                    for Bpi in Bpt'First .. Bpt'First + Nb - 1 loop
                        -- swap nibble
                        Bpt (Bpi) := Bpt (Bpi) / 16 + Bpt (Bpi) rem 16 * 16;  
                    end loop;

                when 16 =>  
                    Private_Swap_Short (Bpt (Bpt'First .. Bpt'First + Nb - 1));

                when 24 =>  
                    Private_Swap_Three (Bpt (Bpt'First .. Bpt'First + Nb - 1));

                when 32 =>  
                    Private_Swap_Long (Bpt (Bpt'First .. Bpt'First + Nb - 1));

                when others =>  
                    raise X_Library_Confusion;  
            end case;  
        end if;  
        if Bit_Order = Msb_First then  
            Private_Reverse_Bytes (Bpt (Bpt'First .. Bpt'First + Nb - 1));  
        end if;

    end Private_Normalize_Image_Bits;

--\x0c
    ------------------------------------------------------------------------------

    function Round_Up (N_Bytes : U_Short;  
                       Pad     : U_Short) return S_Natural is  
    begin  
        return ((S_Natural (N_Bytes) + S_Natural (Pad) - 1) / S_Natural (Pad)) *  
                  S_Natural (Pad);  
    end Round_Up;

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

    function Round_Up (N_Bytes : U_Short;  
                       Pad     : U_Char) return S_Natural is  
    begin  
        return ((S_Natural (N_Bytes) + S_Natural (Pad) - 1) / S_Natural (Pad)) *  
                  S_Natural (Pad);  
    end Round_Up;

--\x0c
    ------------------------------------------------------------------------------
-- Macros
--
-- The ROUND_UP macro rounds up a quantity to the specified boundary.
--
-- The X_Y_NORMALIZE macro determines whether X_Y format data requires
-- normalization and calls a routine to do so if needed. The logic in
-- this module is designed for LSB_First byte and bit order, so
-- normalization is done as required to present the data in this order.
--
-- The Z_NORMALIZE macro performs byte and nibble order normalization if
-- required for Z format data.
--
-- The X_Y_INDEX macro computes the index to the starting byte (char) boundary
-- for a bitmap_unit containing a pixel with coordinates x and y for image
-- data in X_Y format.
--
-- The Z_INDEX macro computes the index to the starting byte (char) boundary
-- for a pixel with coordinates x and y for image data in Z_Pixmap format.
--
------------------------------------------------------------------------------

--\x0c
    procedure X_Y_Normalize (Bp      : in out U_Char_Array;  
                             N_Bytes :        S_Natural;  
                             Image   :        X_Image) is  
    begin

        if ((Image.Byte_Order = Msb_First) or else  
            (Image.Bitmap_Bit_Order = Msb_First)) then  
            Private_Normalize_Image_Bits  
               (Bp, N_Bytes, Image.Byte_Order,  
                Image.Bitmap_Unit, Image.Bitmap_Bit_Order);  
        end if;

    end X_Y_Normalize;

--\x0c
    procedure Z_Normalize (Bp      : in out U_Char_Array;  
                           N_Bytes :        S_Natural;  
                           Image   :        X_Image) is  
    begin

        if (Image.Byte_Order = Msb_First) then  
            Private_Normalize_Image_Bits (Bp, N_Bytes, Msb_First,  
                                          Image.Bits_Per_Pixel, Lsb_First);  
        end if;

    end Z_Normalize;

--\x0c
    function X_Y_Index (X     : S_Short;  
                        Y     : S_Short;  
                        Image : X_Image) return S_Natural is  
    begin

        return Image.Data'First +  
                  S_Natural (Y) * S_Natural (Image.Bytes_Per_Line) +  
                  ((S_Natural (X) + S_Natural (Image.X_Offset)) /  
                   S_Natural (Image.Bitmap_Unit)) *  
                  S_Natural (Image.Bitmap_Unit / 8);

    end X_Y_Index;

--\x0c
    function Z_Index (X     : S_Short;  
                      Y     : S_Short;  
                      Image : X_Image) return S_Natural is  
    begin

        return Image.Data'First +  
                  S_Natural (Y) * S_Natural (Image.Bytes_Per_Line) +  
                  S_Natural (X) * S_Natural (Image.Bits_Per_Pixel) / 8;

    end Z_Index;

--\x0c
    procedure Private_Put_Bits  
                 (Src        : U_Char_Array;-- source bit string
                  Dst_Offset : U_Char_0_31; -- bit offset into destination
                  Num_Bits   : S_Natural;   -- number of bits to copy to dest.
                  Dst        : in out       -- destination bit string
                            U_Char_Array)  
                  is  
        Chlo         : U_Char;  
        Chhi         : U_Char;  
        Hibits       : S_Natural;  
        Srci         : S_Natural := Src'First;  
        Dsti         : S_Natural := Dst'First;  
        L_Dst_Offset : S_Natural := S_Natural (Dst_Offset);  
        L_Num_Bits   : S_Natural := S_Natural (Num_Bits);  
    begin

        Dsti         := Dsti + L_Dst_Offset / 8;  
        L_Dst_Offset := L_Dst_Offset rem 8;  
        Hibits       := 8 - L_Dst_Offset;  
        Chlo         := Dst (Dsti) and Private_Lo_Mask (L_Dst_Offset);  
        loop  
            Chhi := Shift (Src (Srci), Integer (L_Dst_Offset)) and  
                       Private_Hi_Mask (L_Dst_Offset);  
            if L_Num_Bits <= Hibits then  
                Chhi := Chhi and Private_Lo_Mask (L_Dst_Offset + L_Num_Bits);  
                Dst (Dsti) := (Dst (Dsti) and  
                               Private_Hi_Mask (L_Dst_Offset + L_Num_Bits))  
                               or Chlo or Chhi;  
                exit;  
            end if;  
            Dst (Dsti) := Chhi or Chlo;  
            Dsti       := Dsti + 1;  
            L_Num_Bits := L_Num_Bits - Hibits;  
            Chlo       := Shift (Src (Srci) and Private_Hi_Mask (Hibits),  
                                 -Integer (Hibits));  
            Srci       := Srci + 1;  
            if L_Num_Bits <= L_Dst_Offset then  
                Chlo       := Chlo and Private_Lo_Mask (L_Num_Bits);  
                Dst (Dsti) :=  
                   (Dst (Dsti) and Private_Hi_Mask (L_Num_Bits)) or Chlo;  
                exit;  
            end if;  
            L_Num_Bits := L_Num_Bits - L_Dst_Offset;  
        end loop;

    end Private_Put_Bits;

--\x0c
    ------------------------------------------------------------------------------
-- Add_Pixel
--
-- Adds a constant value to every pixel in a pixmap.
------------------------------------------------------------------------------

    procedure Private_X_Add_Pixel (Image : X_Image;  
                                   Value : X_Pixel) is  
        Pixel   : X_Pixel;  
        Pixes   : U_Char_4_Array;  
        Src     : S_Natural;  
        N_Bytes : S_Natural;  
    begin

        if Value = 0 then  
            return;  
        end if;

        if Image.Depth = 1 then
            -- The only value that we can add here to an X_Y_Bitmap
            -- is one.  Since 1 + value := ~value for one bit wide
            -- data, we do this quickly by taking the ones complement
            -- of the entire bitmap data (offset and pad included!).
            -- Note that we don't need to be concerned with bit or
            -- byte order at all.
            --
            for I in Image.Data'Range loop
                -- Believe it or not; this is logical negation in Ada.
                Image.Data (I) := U_Char ((-Integer (Image.Data (I))) - 1);  
            end loop;

        elsif Image.Format = X_Y_Pixmap then
            -- this is slow, may do better later
            for Y in S_Short range 0 .. S_Short (Image.Height) - 1 loop  
                for X in S_Short range 0 .. S_Short (Image.Width) - 1 loop  
                    Pixel := X_Get_Pixel (Image, X, Y);  
                    Pixel := Pixel + Value;  
                    X_Put_Pixel (Image, X, Y, Pixel);  
                end loop;  
            end loop;

        elsif Image.Format = Z_Pixmap then
            -- If the bits_per_pixel makes the alignment occur on even
            -- byte boundaries, perform the addition by stepping thru
            -- the data one pixel at a time.  Otherwise, do it the slow
            -- way by calling get and put pixel.
            --
            if Image.Bits_Per_Pixel rem 8 = 0 then  
                N_Bytes := Round_Up  
                              (U_Short (Image.Bits_Per_Pixel), U_Short (8)) / 8;  
                for Y in S_Short range 0 .. S_Short (Image.Height) - 1 loop  
                    Src := Z_Index (0, Y, Image);  
                    for X in S_Short range 0 .. S_Short (Image.Width) - 1 loop  
                        Pixes                    := (others => 0);  
                        Pixes (0 .. N_Bytes - 1) :=  
                           Image.Data (Src .. Src + N_Bytes - 1);  
                        Z_Normalize (Pixes, N_Bytes, Image);  
                        Pixel := From_U_Char (Pixes);  
                        Pixel := Pixel + Value;  
                        Pixes := To_U_Char (Pixel);  
                        Z_Normalize (Pixes, N_Bytes, Image);  
                        Image.Data (Src .. Src + N_Bytes - 1) :=  
                           Pixes (0 .. N_Bytes - 1);  
                        Src := Src + N_Bytes;  
                    end loop;  
                end loop;

            else  
                for Y in S_Short range 0 .. S_Short (Image.Height) - 1 loop  
                    for X in S_Short range 0 .. S_Short (Image.Width) - 1 loop  
                        Pixel := X_Get_Pixel (Image, X, Y);  
                        Pixel := Pixel + Value;  
                        X_Put_Pixel (Image, X, Y, Pixel);  
                    end loop;  
                end loop;  
            end if;

        else    -- should never get here
            Private_X_Report_Bad_Image  
               ("format", X_Image_Format'Image (Image.Format),  
                "private_X_Add_Pixel");  
        end if;

    end Private_X_Add_Pixel;

--\x0c
    ------------------------------------------------------------------------------
-- Get_Pixel
--
-- Returns the specified pixel.  The X and Y coordinates are relative to
-- the origin (upper left [0,0]) of the image.  The pixel value is returned
-- in normalized format, i.e. the LSB of the long is the LSB of the pixel.
-- The algorithm used is:
--
--  copy the source bitmap_unit or Z_pixel into temp
--  normalize temp if needed
--  extract the pixel bits into return value
------------------------------------------------------------------------------

    function Private_X_Get_Pixel (Image : X_Image;  
                                  X     : S_Short;  
                                  Y     : S_Short) return X_Pixel is  
        Pixel   : X_Pixel;  
        Pixes   : U_Char_4_Array;  
        Src     : S_Natural;  
        Plane   : S_Natural;  
        N_Bytes : S_Natural;  
        Bits    : S_Natural;  
    begin

        if Image.Depth = 1 then  
            Src                      := X_Y_Index (X, Y, Image);  
            Pixes                    := (others => 0);  
            N_Bytes                  := S_Natural (Image.Bitmap_Unit) / 8;  
            Pixes (0 .. N_Bytes - 1) := Image.Data (Src .. Src + N_Bytes - 1);  
            X_Y_Normalize (Pixes, N_Bytes, Image);  
            Bits  := S_Natural (X + Image.X_Offset) rem  
                        S_Natural (Image.Bitmap_Unit);  
            Pixel :=  
               X_Pixel  
                  (Shift (S_Long (Pixes (Bits / 8)), -Integer (Bits mod 8)) and  
                   1);

        elsif Image.Format = X_Y_Pixmap then  
            Pixel   := 0;  
            Plane   := 0;  
            N_Bytes := S_Natural (Image.Bitmap_Unit) / 8;  
            for I in 0 .. Image.Depth - 1 loop  
                Src                      := X_Y_Index (X, Y, Image) + Plane;  
                Pixes                    := (others => 0);  
                Pixes (0 .. N_Bytes - 1) :=  
                   Image.Data (Src .. Src + N_Bytes - 1);  
                X_Y_Normalize (Pixes, N_Bytes, Image);  
                Bits  := S_Natural (X + Image.X_Offset) rem  
                            S_Natural (Image.Bitmap_Unit);  
                Pixel :=  
                   Shift (Pixel, 1) or  
                      (Shift (X_Pixel (Pixes (Bits / 8)),  
                              -Integer (Bits rem 8)) and 1);  
                Plane := Plane + S_Natural  
                                    (Image.Bytes_Per_Line * Image.Height);  
            end loop;

        elsif Image.Format = Z_Pixmap then  
            Src                      := Z_Index (X, Y, Image);  
            Pixes                    := (others => 0);  
            N_Bytes                  :=  
               Round_Up (U_Short (Image.Bits_Per_Pixel), U_Short (8)) / 8;  
            Pixes (0 .. N_Bytes - 1) := Image.Data (Src .. Src + N_Bytes - 1);  
            Z_Normalize (Pixes, N_Bytes, Image);  
            Pixel := 0;  
            for I in reverse Pixes'Range loop  
                Pixel := Shift (Pixel, 8) or X_Pixel (Pixes (I));  
            end loop;  
            if Image.Bits_Per_Pixel = 4 then  
                if X rem 2 /= 0 then  
                    Pixel := Shift (Pixel, -4);  
                else  
                    Pixel := Pixel and 16#0F#;  
                end if;  
            end if;

        else  -- should never get here
            Private_X_Report_Bad_Image  
               ("format", X_Image_Format'Image (Image.Format),  
                "private_X_Get_Pixel");  
        end if;  
        if Image.Bits_Per_Pixel = Image.Depth then  
            return Pixel;  
        else  
            return Pixel and Low_Bits_Table (S_Natural (Image.Depth));  
        end if;

    end Private_X_Get_Pixel;

--\x0c
    function Private_X_Get_Pixel_8 (Image : X_Image;  
                                    X     : S_Short;  
                                    Y     : S_Short) return X_Pixel is  
        Pixel : X_Pixel;  
    begin

        if Image.Format = Z_Pixmap and then  
           Image.Bits_Per_Pixel = 8 then  
            Pixel :=  
               X_Pixel  
                  (Image.Data  
                      (Image.Data'First +  
                       S_Natural (Y * S_Short (Image.Bytes_Per_Line) + X)));  
            if Image.Depth /= 8 then  
                Pixel := Pixel and Low_Bits_Table (S_Natural (Image.Depth));  
            end if;  
            return Pixel;  
        else  
            Private_X_Init_Image_Func_Ptrs (Image);  
            return X_Get_Pixel (Image, X, Y);  
        end if;

    end Private_X_Get_Pixel_8;

--\x0c
    function Private_X_Get_Pixel_1 (Image : X_Image;  
                                    X     : S_Short;  
                                    Y     : S_Short) return X_Pixel is  
        Bit  : U_Char;  
        Xoff : S_Natural;  
        Yoff : S_Natural;  
    begin

        if Image.Depth = 1 and then  
           Image.Byte_Order = Image.Bitmap_Bit_Order then  
            Xoff := S_Natural (X + Image.X_Offset);  
            Yoff := S_Natural (Y * S_Short (Image.Bytes_Per_Line)) +  
                       (Xoff / 2 ** 3);  
            Xoff := Xoff rem 8;  
            if Image.Bitmap_Bit_Order = Msb_First then  
                Bit := 2 ** Natural (7 - Xoff);  
            else  
                Bit := 2 ** Natural (Xoff);  
            end if;  
            if (Image.Data (Image.Data'First + Yoff) and Bit) /= 0 then  
                return 1;  
            else  
               return 0;  
            end if;  
        else  
            Private_X_Init_Image_Func_Ptrs (Image);  
            return X_Get_Pixel (Image, X, Y);  
        end if;

    end Private_X_Get_Pixel_1;

--\x0c
    ------------------------------------------------------------------------------
-- Put_Pixel
--
-- Overwrites the specified pixel.  The X and Y coordinates are relative to
-- the origin (upper left [0,0]) of the image.  The input pixel value must be
-- in normalized format, i.e. the LSB of the long is the LSB of the pixel.
-- The algorithm used is:
--
--  copy the destination bitmap_unit or Z_pixel to temp
--  normalize temp if needed
--  copy the pixel bits into the temp
--  renormalize temp if needed
--  copy the temp back into the destination image data
------------------------------------------------------------------------------

    procedure Private_X_Put_Pixel (Image : X_Image;  
                                   X     : S_Short;  
                                   Y     : S_Short;  
                                   Pixel : X_Pixel) is  
        Px      : X_Pixel;  
        Lpixel  : X_Pixel := Pixel;  
        Npixel  : X_Pixel;  
        Pixes   : U_Char_4_Array;  
        Raw     : U_Char_4_Array;  
        Src     : S_Natural;  
        Plane   : S_Natural;  
        N_Bytes : S_Natural;  
        I       : U_Char;  
    begin

        if Image.Depth = 4 then  
            Lpixel := Lpixel and 16#F#;  
        end if;  
        Npixel := Lpixel;  
        for I in Pixes'Range loop  
            Pixes (I) := U_Char (Lpixel and 16#FF#);  
            Lpixel    := Lpixel / X_Pixel (2 ** 8);  
        end loop;

        if Image.Depth = 1 then  
            Src                      := X_Y_Index (X, Y, Image);  
            Pixes                    := (others => 0);  
            N_Bytes                  := S_Natural (Image.Bitmap_Unit) / 8;  
            Pixes (0 .. N_Bytes - 1) := Image.Data (Src .. Src + N_Bytes - 1);  
            X_Y_Normalize (Pixes, N_Bytes, Image);  
            I   := U_Char (X + Image.X_Offset) rem Image.Bitmap_Unit;  
            Raw := To_U_Char (Lpixel);  
            Private_Put_Bits (Raw, I, 1, Pixes);  
            X_Y_Normalize (Pixes, N_Bytes, Image);  
            Image.Data (Src .. Src + N_Bytes - 1) := Pixes (0 .. N_Bytes - 1);

        elsif Image.Format = X_Y_Pixmap then  
            Plane   := S_Natural (Image.Bytes_Per_Line * Image.Height) *  
                          S_Natural (Image.Depth -  
                                     1); -- do least signif plane 1st
            N_Bytes := S_Natural (Image.Bitmap_Unit) / 8;  
            for J in 0 .. Image.Depth - 1 loop  
                Src                      := X_Y_Index (X, Y, Image) + Plane;  
                Pixes                    := (others => 0);  
                Pixes (0 .. N_Bytes - 1) :=  
                   Image.Data (Src .. Src + N_Bytes - 1);  
                X_Y_Normalize (Pixes, N_Bytes, Image);                 I   := U_Char (X + Image.X_Offset) rem Image.Bitmap_Unit;  
                Raw := To_U_Char (Px);  
                Private_Put_Bits (Raw, I, 1, Pixes);  
                X_Y_Normalize (Pixes, N_Bytes, Image);  
                Image.Data (Src .. Src + N_Bytes - 1) :=  
                   Pixes (0 .. N_Bytes - 1);  
                Npixel := Npixel / 2;  
                Px := Npixel;  
                for I in Pixes'Range loop  
                    Pixes (I) := U_Char (Npixel and 16#FF#);  
                    Npixel    := Npixel / X_Pixel (2 ** 8);  
                end loop;  
                Plane := Plane - S_Natural  
                                    (Image.Bytes_Per_Line * Image.Height);  
            end loop;

        elsif Image.Format = Z_Pixmap then  
            Src                      := Z_Index (X, Y, Image);  
            Pixes                    := (others => 0);  
            N_Bytes                  :=  
               Round_Up (U_Short (Image.Bits_Per_Pixel), U_Short (8)) / 8;  
            Pixes (0 .. N_Bytes - 1) := Image.Data (Src .. Src + N_Bytes - 1);  
            Z_Normalize (Pixes, N_Bytes, Image);  
            Raw := To_U_Char (Lpixel);  
            Private_Put_Bits  
               (Raw, U_Char ((X * S_Short (Image.Bits_Per_Pixel)) rem 8),  
                S_Long (Image.Bits_Per_Pixel), Pixes);  
            Z_Normalize (Pixes, N_Bytes, Image);  
            Image.Data (Src .. Src + N_Bytes - 1) := Pixes (0 .. N_Bytes - 1);

        else   -- should never get here
            Private_X_Report_Bad_Image  
               ("format", X_Image_Format'Image (Image.Format),  
                "private_X_Put_Pixel");  
        end if;

    end Private_X_Put_Pixel;

--\x0c
    procedure Private_X_Put_Pixel_8 (Image : X_Image;  
                                     X     : S_Short;  
                                     Y     : S_Short;  
                                     Pixel : X_Pixel) is  
    begin

        if Image.Format = Z_Pixmap and then  
           Image.Bits_Per_Pixel = 8 then  
            Image.Data (Image.Data'First +  
                        S_Natural (Y * S_Short (Image.Bytes_Per_Line) + X)) :=  
               U_Char (Pixel);  
        else  
            Private_X_Init_Image_Func_Ptrs (Image);  
            X_Put_Pixel (Image, X, Y, Pixel);  
        end if;

    end Private_X_Put_Pixel_8;

--\x0c
    procedure Private_X_Put_Pixel_1 (Image : X_Image;  
                                     X     : S_Short;  
                                     Y     : S_Short;  
                                     Pixel : X_Pixel) is  
        Bit  : U_Char;  
        Xoff : S_Natural;  
        Yoff : S_Natural;  
    begin

        if Image.Depth = 1 and then  
           Image.Byte_Order = Image.Bitmap_Bit_Order then  
            Xoff := S_Natural (X + Image.X_Offset);  
            Yoff := S_Natural (Y * S_Short (Image.Bytes_Per_Line)) +  
                       (Xoff / 2 ** 3);  
            Xoff := Xoff rem 8;             if Image.Bitmap_Bit_Order = Msb_First then  
                Bit := 2 ** Natural (7 - Xoff);  
            else  
                Bit := 2 ** Natural (Xoff);  
            end if;  
            Yoff := Yoff + Image.Data'First;  
            if Pixel rem 1 /= 0 then  
                Image.Data (Yoff) := Image.Data (Yoff) or Bit;  
            else  
                Image.Data (Yoff) := Image.Data (Yoff) and not Bit;  
            end if;  
        else  
            Private_X_Init_Image_Func_Ptrs (Image);  
            X_Put_Pixel (Image, X, Y, Pixel);  
        end if;

    end Private_X_Put_Pixel_1;

--\x0c
    ------------------------------------------------------------------------------
-- Sub_Image
--
-- Creates a new image that is a subsection of an existing one.
-- Allocates the memory necessary for the neww image data structure.
-- Pointer to new image is returned.  The algorithm used is repetitive
-- calls to get and put pixel.
------------------------------------------------------------------------------

    function Private_X_Sub_Image  
                (Image  : X_Image;  
                 X      : S_Short;   -- starting x coordinate in Image
                 Y      : S_Short;   -- starting y coordinate in Image
                 Width  : U_Short;   -- width in pixels of new subimage
                 Height : U_Short    -- height in pixels of new subimage
                 ) return X_Image is

        Subimage : X_Image;  
        Dsize    : S_Natural;  
        Pixel    : X_Pixel;

    begin

        Subimage                  := new X_Image_Rec;  
        Subimage.Width            := Width;  
        Subimage.Height           := Height;  
        Subimage.X_Offset         := 0;  
        Subimage.Format           := Image.Format;  
        Subimage.Byte_Order       := Image.Byte_Order;  
        Subimage.Bitmap_Unit      := Image.Bitmap_Unit;  
        Subimage.Bitmap_Bit_Order := Image.Bitmap_Bit_Order;  
        Subimage.Bitmap_Pad       := Image.Bitmap_Pad;  
        Subimage.Bits_Per_Pixel   := Image.Bits_Per_Pixel;  
        Subimage.Depth            := Image.Depth;
        --
        -- compute per line accelerator.
        --
        if (Subimage.Format = Z_Pixmap) then  
            Subimage.Bytes_Per_Line :=  
               U_Short (Round_Up (U_Short (Subimage.Bits_Per_Pixel) * Width,  
                                  Subimage.Bitmap_Pad / 8));  
        else  
            Subimage.Bytes_Per_Line :=  
               U_Short (Round_Up (Width,  
                                  Subimage.Bitmap_Pad / 8));  
        end if;  
        Subimage.Obdata := null;  
        Private_X_Init_Image_Func_Ptrs (Subimage);  
        Dsize := S_Natural (Subimage.Bytes_Per_Line) * S_Natural (Height);  
        if Subimage.Format = X_Y_Pixmap then  
            Dsize := Dsize * S_Natural (Subimage.Depth);  
        end if;  
        Subimage.Data := new U_Char_Array (1 .. Dsize);

        --
        -- Test for cases where the new subimage is larger than the region
        -- that we are copying from the existing data.  In those cases,
        -- copy the area of the existing image, and allow the "uncovered"
        -- area of new subimage to remain with zero filled pixels.
        --
        declare  
            L_Height : S_Short := S_Short (Height);  
            L_Width  : S_Short := S_Short (Width);  
        begin  
            if L_Height > S_Short (Image.Height) - Y then  
                L_Height := S_Short (Image.Height) - Y;  
            end if;  
            if L_Width > S_Short (Image.Width) - X then  
                L_Width := S_Short (Image.Width) - X;  
            end if;

            for Row in Y .. Y + L_Height - 1 loop  
                for Col in X .. X + L_Width - 1 loop  
                    Pixel := X_Get_Pixel (Image, Col, Row);  
                    X_Put_Pixel (Subimage, (Col - X), (Row - Y), Pixel);  
                end loop;  
            end loop;  
        end;  
        return Subimage;

    exception

        when others =>  
            Free_X_Image (Subimage);  
            raise;

    end Private_X_Sub_Image;

--\x0c
    function Default_X_Add_Pixel_Type is  
       new Proc_Var_X_Add_Pixel.Value (Private_X_Add_Pixel);

    function Default_X_Create_Image_Type is  
       new Proc_Var_X_Create_Image.Value (X_Create_Image);

    function Default_X_Destroy_Image_Type is  
       new Proc_Var_X_Destroy_Image.Value (Free_X_Image);

    function Default_X_Get_Pixel_Type is  
       new Proc_Var_X_Get_Pixel.Value (Private_X_Get_Pixel);

    function Default_X_Get_Pixel_8_Type is  
       new Proc_Var_X_Get_Pixel.Value (Private_X_Get_Pixel_8);

    function Default_X_Get_Pixel_1_Type is  
       new Proc_Var_X_Get_Pixel.Value (Private_X_Get_Pixel_1);

    function Default_X_Put_Pixel_Type is  
       new Proc_Var_X_Put_Pixel.Value (Private_X_Put_Pixel);

    function Default_X_Put_Pixel_8_Type is  
       new Proc_Var_X_Put_Pixel.Value (Private_X_Put_Pixel_8);

    function Default_X_Put_Pixel_1_Type is  
       new Proc_Var_X_Put_Pixel.Value (Private_X_Put_Pixel_1);

    function Default_X_Sub_Image_Type is  
       new Proc_Var_X_Sub_Image.Value (Private_X_Sub_Image);

--\x0c
    -- This routine initializes the image object function pointers.  The
-- intent is to provide native (i.e. fast) routines for native format images
-- only using the generic (i.e. slow) routines when fast ones don't exist.
-- However, with the current rather botched external interface, clients may
-- have to mung image attributes after the image gets created, so the fast
-- routines always have to check to make sure the optimization is still
-- valid, and reinitialize the functions if not.

    procedure Private_X_Init_Image_Func_Ptrs (Image : X_Image) is  
    begin

        Image.F.Create_Image  := Proc_Var_X_Create_Image.From_Pv  
                                    (Default_X_Create_Image_Type);  
        Image.F.Destroy_Image := Proc_Var_X_Destroy_Image.From_Pv  
                                    (Default_X_Destroy_Image_Type);

        if Image.Format = Z_Pixmap and then Image.Bits_Per_Pixel = 8 then  
            Image.F.Get_Pixel := Proc_Var_X_Get_Pixel.From_Pv  
                                    (Default_X_Get_Pixel_8_Type);  
            Image.F.Put_Pixel := Proc_Var_X_Put_Pixel.From_Pv  
                                    (Default_X_Put_Pixel_8_Type);  
        elsif Image.Depth = 1 and then  
              Image.Byte_Order = Image.Bitmap_Bit_Order then  
            Image.F.Get_Pixel := Proc_Var_X_Get_Pixel.From_Pv  
                                    (Default_X_Get_Pixel_1_Type);  
            Image.F.Put_Pixel := Proc_Var_X_Put_Pixel.From_Pv  
                                    (Default_X_Put_Pixel_1_Type);  
        else  
            Image.F.Get_Pixel := Proc_Var_X_Get_Pixel.From_Pv  
                                    (Default_X_Get_Pixel_Type);  
            Image.F.Put_Pixel := Proc_Var_X_Put_Pixel.From_Pv  
                                    (Default_X_Put_Pixel_Type);  
        end if;

        Image.F.Sub_Image := Proc_Var_X_Sub_Image.From_Pv  
                                (Default_X_Sub_Image_Type);  
        Image.F.Add_Pixel := Proc_Var_X_Add_Pixel.From_Pv  
                                (Default_X_Add_Pixel_Type);
--        Image.F.Set_Image :=
--            proc_var_X_Set_Image_Type.from_pv(
--            Default_X_Set_Image_Type);

    end Private_X_Init_Image_Func_Ptrs;

--\x0c
    procedure Private_Swap_Bits (B : in out U_Char_Array) is
------------------------------------------------------------------------------
-- For each byte in the buffer; swap the bits within each byte so that they
-- run in the opposite direction.  Bit 0 becomes bit 7; bit 7 becomes bit 0;
-- bit 1 becomes bit 6; etc.
------------------------------------------------------------------------------
    begin

        for I in B'Range loop  
            B (I) := Private_Reverse_Byte (S_Natural (B (I)));  
        end loop;

    end Private_Swap_Bits;

--\x0c
    procedure Private_Swap_Short (P : in out U_Char_Array) is
------------------------------------------------------------------------------
-- For each half-word in the buffer, swap the byte pairs.
------------------------------------------------------------------------------
        I : S_Natural := P'First;  
        C : U_Char;  
    begin

        for J in reverse P'First .. P'First + P'Length / 2 - 1 loop  
            C         := P (I);  
            P (I)     := P (I + 1);  
            P (I + 1) := C;  
            I         := I + 2;  
        end loop;

    end Private_Swap_Short;

--\x0c
    procedure Private_Swap_Long (P : in out U_Char_Array) is
------------------------------------------------------------------------------
-- For each full-word in the buffer; reverse the order of the 4 bytes.
-- We expect the buffer'Length to be a multiple of 4; if it isn't then the
-- last 1, 2, or 3 bytes ('Length rem 4) are not touched.
------------------------------------------------------------------------------
        I : S_Natural := P'First;  
        C : U_Char;  
    begin

        for J in P'First .. P'First + P'Length / 4 - 1 loop  
            C         := P (I);  
            P (I)     := P (I + 3);  
            P (I + 3) := C;  
            C         := P (I + 2);  
            P (I + 2) := P (I + 1);  
            P (I + 1) := C;  
            I         := I + 4;  
        end loop;

    end Private_Swap_Long;

--\x0c
    procedure Private_Swap_Three (P : in out U_Char_Array) is
------------------------------------------------------------------------------
-- We have groups of 24-bits (presumably we have a group of 3-byte colormap
-- values) and we need to swap them from big to little (or little to big)
-- endian.
------------------------------------------------------------------------------
        I : S_Natural := P'First;  
        C : U_Char;  
    begin

        for J in P'First .. P'First + P'Length / 3 - 1 loop  
            C         := P (I);  
            P (I)     := P (I + 2);  
            P (I + 2) := C;  
            I         := I + 3;  
        end loop;

    end Private_Swap_Three;

--\x0c
begin

    X_Lib_Default_X_Add_Pixel :=  
       Proc_Var_X_Add_Pixel.From_Pv (Default_X_Add_Pixel_Type);

    X_Lib_Default_X_Create_Image :=  
       Proc_Var_X_Create_Image.From_Pv (Default_X_Create_Image_Type);

    X_Lib_Default_X_Destroy_Image :=  
       Proc_Var_X_Destroy_Image.From_Pv (Default_X_Destroy_Image_Type);

    X_Lib_Default_X_Get_Pixel :=  
       Proc_Var_X_Get_Pixel.From_Pv (Default_X_Get_Pixel_Type);

    X_Lib_Default_X_Get_Pixel_8 :=  
       Proc_Var_X_Get_Pixel.From_Pv (Default_X_Get_Pixel_8_Type);

    X_Lib_Default_X_Get_Pixel_1 :=  
       Proc_Var_X_Get_Pixel.From_Pv (Default_X_Get_Pixel_1_Type);

    X_Lib_Default_X_Put_Pixel :=  
       Proc_Var_X_Put_Pixel.From_Pv (Default_X_Put_Pixel_Type);

    X_Lib_Default_X_Put_Pixel_8 :=  
       Proc_Var_X_Put_Pixel.From_Pv (Default_X_Put_Pixel_8_Type);

    X_Lib_Default_X_Put_Pixel_1 :=  
       Proc_Var_X_Put_Pixel.From_Pv (Default_X_Put_Pixel_1_Type);

    X_Lib_Default_X_Sub_Image :=  
       Proc_Var_X_Sub_Image.From_Pv (Default_X_Sub_Image_Type);

end Xlbip_Image_Internal;  

E3 Meta Data

    nblk1=3a
    nid=0
    hdr6=74
        [0x00] rec0=25 rec1=00 rec2=01 rec3=08e
        [0x01] rec0=12 rec1=00 rec2=02 rec3=00a
        [0x02] rec0=12 rec1=00 rec2=03 rec3=06e
        [0x03] rec0=1b rec1=00 rec2=04 rec3=044
        [0x04] rec0=13 rec1=00 rec2=05 rec3=03a
        [0x05] rec0=11 rec1=00 rec2=06 rec3=078
        [0x06] rec0=1d rec1=00 rec2=07 rec3=024
        [0x07] rec0=1c rec1=00 rec2=08 rec3=016
        [0x08] rec0=17 rec1=00 rec2=09 rec3=004
        [0x09] rec0=1d rec1=00 rec2=0a rec3=01c
        [0x0a] rec0=1a rec1=00 rec2=0b rec3=040
        [0x0b] rec0=01 rec1=00 rec2=3a rec3=00e
        [0x0c] rec0=15 rec1=00 rec2=0c rec3=008
        [0x0d] rec0=01 rec1=00 rec2=39 rec3=044
        [0x0e] rec0=19 rec1=00 rec2=0d rec3=04c
        [0x0f] rec0=01 rec1=00 rec2=38 rec3=012
        [0x10] rec0=19 rec1=00 rec2=0e rec3=050
        [0x11] rec0=00 rec1=00 rec2=37 rec3=010
        [0x12] rec0=13 rec1=00 rec2=0f rec3=052
        [0x13] rec0=12 rec1=00 rec2=10 rec3=072
        [0x14] rec0=01 rec1=00 rec2=36 rec3=018
        [0x15] rec0=1a rec1=00 rec2=11 rec3=086
        [0x16] rec0=17 rec1=00 rec2=12 rec3=062
        [0x17] rec0=03 rec1=00 rec2=35 rec3=012
        [0x18] rec0=14 rec1=00 rec2=13 rec3=018
        [0x19] rec0=01 rec1=00 rec2=34 rec3=016
        [0x1a] rec0=16 rec1=00 rec2=14 rec3=006
        [0x1b] rec0=01 rec1=00 rec2=33 rec3=050
        [0x1c] rec0=1c rec1=00 rec2=15 rec3=03e
        [0x1d] rec0=1c rec1=00 rec2=16 rec3=004
        [0x1e] rec0=00 rec1=00 rec2=32 rec3=002
        [0x1f] rec0=1a rec1=00 rec2=17 rec3=060
        [0x20] rec0=1b rec1=00 rec2=18 rec3=032
        [0x21] rec0=01 rec1=00 rec2=31 rec3=036
        [0x22] rec0=12 rec1=00 rec2=19 rec3=002
        [0x23] rec0=00 rec1=00 rec2=2f rec3=010
        [0x24] rec0=14 rec1=00 rec2=30 rec3=038
        [0x25] rec0=01 rec1=00 rec2=1a rec3=066
        [0x26] rec0=19 rec1=00 rec2=1b rec3=036
        [0x27] rec0=1a rec1=00 rec2=1c rec3=042
        [0x28] rec0=01 rec1=00 rec2=2e rec3=002
        [0x29] rec0=1a rec1=00 rec2=1d rec3=00c
        [0x2a] rec0=17 rec1=00 rec2=1e rec3=04e
        [0x2b] rec0=01 rec1=00 rec2=2d rec3=06a
        [0x2c] rec0=18 rec1=00 rec2=1f rec3=030
        [0x2d] rec0=00 rec1=00 rec2=2c rec3=01a
        [0x2e] rec0=15 rec1=00 rec2=20 rec3=02e
        [0x2f] rec0=22 rec1=00 rec2=21 rec3=040
        [0x30] rec0=16 rec1=00 rec2=22 rec3=044
        [0x31] rec0=00 rec1=00 rec2=2b rec3=004
        [0x32] rec0=11 rec1=00 rec2=23 rec3=034
        [0x33] rec0=15 rec1=00 rec2=24 rec3=072
        [0x34] rec0=1e rec1=00 rec2=25 rec3=03e
        [0x35] rec0=00 rec1=00 rec2=2a rec3=028
        [0x36] rec0=1a rec1=00 rec2=26 rec3=00e
        [0x37] rec0=00 rec1=00 rec2=29 rec3=038
        [0x38] rec0=21 rec1=00 rec2=27 rec3=026
        [0x39] rec0=0f rec1=00 rec2=28 rec3=000
    tail 0x2170066be819780b23eb4 0x42a00088462063203