|
|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: B T
Length: 38810 (0x979a)
Types: TextFile
Names: »B«
└─⟦85b835f43⟧ Bits:30000549 8mm tape, Rational 1000, Xlib rev 6.00
└─⟦0c20f784e⟧ »DATA«
└─⟦1abbe589f⟧
└─⟦059497ac5⟧
└─⟦this⟧
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.
------------------------------------------------------------------------------
--\f
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);
--\f
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;
--\f
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;
--\f
------------------------------------------------------------------------------
-- 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;
--\f
------------------------------------------------------------------------------
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;
--\f
------------------------------------------------------------------------------
-- 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.
--
------------------------------------------------------------------------------
--\f
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;
--\f
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;
--\f
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;
--\f
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;
--\f
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;
--\f
------------------------------------------------------------------------------
-- 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;
--\f
------------------------------------------------------------------------------
-- 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;
--\f
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;
--\f
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;
--\f
------------------------------------------------------------------------------
-- 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;
--\f
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;
--\f
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;
--\f
------------------------------------------------------------------------------
-- 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;
--\f
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);
--\f
-- 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;
--\f
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;
--\f
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;
--\f
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;
--\f
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;
--\f
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;