Source file : gid.ads
---------------------------------
-- GID - Generic Image Decoder --
---------------------------------
--
-- Purpose:
--
-- The Generic Image Decoder is a package for decoding a broad
-- variety of image formats, from any data stream, to any kind
-- of medium, be it an in-memory bitmap, a GUI object,
-- some other stream, arrays of floating-point initial data
-- for scientific calculations, a browser element, a device,...
-- Animations are supported.
--
-- The code is unconditionally portable, independent of the
-- choice of operating system, processor, endianess and compiler.
--
-- Image types currently supported:
--
-- BMP, GIF, JPEG, PNG, PNM, QOI, TGA
--
-- Credits:
--
-- - André van Splunter: GIF's LZW decoder in Ada
-- - Martin J. Fiedler: most of the JPEG decoder (from NanoJPEG)
--
-- More credits in gid_work.xls, sheet "credits".
--
-- Copyright (c) Gautier de Montmollin 2010 .. 2022
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-- THE SOFTWARE.
--
-- NB: this is the MIT License, as found 2-May-2010 on the site
-- http://www.opensource.org/licenses/mit-license.php
with Ada.Calendar, Ada.Streams, Ada.Strings.Bounded, Ada.Finalization;
with Interfaces;
with System;
package GID is
type Image_descriptor is private;
---------------------------------------------------
-- 1) Load the image header from the data stream --
---------------------------------------------------
procedure Load_image_header (
image : out Image_descriptor;
from : in out Ada.Streams.Root_Stream_Type'Class;
try_tga : Boolean := False
);
-- try_tga: if no known signature is found, assume it might be
-- the TGA format (which hasn't a signature) and try to load an
-- image of this format
unknown_image_format,
known_but_unsupported_image_format,
unsupported_image_subformat,
error_in_image_data,
invalid_primary_color_range : exception;
----------------------------------------------------------------------
-- 2) If needed, use dimensions to prepare the retrieval of the --
-- image, for instance: reserving an in-memory bitmap, sizing a --
-- GUI object, defining a browser element, setting up a device --
----------------------------------------------------------------------
function Pixel_width (image : Image_descriptor) return Positive;
function Pixel_height (image : Image_descriptor) return Positive;
-- "Unchanged" orientation has origin at top left
type Orientation is (
Unchanged,
Rotation_90, Rotation_180, Rotation_270
);
function Display_orientation (image : Image_descriptor) return Orientation;
--------------------------------------------------------------------
-- 3) Load and decode the image itself. If the image is animated, --
-- call Load_image_contents until next_frame is 0.0 --
--------------------------------------------------------------------
type Display_mode is (fast, nice);
-- For bitmap pictures, the result is exactly the same, but
-- interlaced images' larger pixels are drawn in full during decoding.
generic
type Primary_color_range is mod <>;
-- Coding of primary colors (red, green or blue)
-- and of opacity (also known as alpha channel), on the target "device".
-- Currently, only 8-bit and 16-bit are admitted.
-- 8-bit coding is usual: TrueColor, PC graphics, etc.;
-- 16-bit coding is seen in some high-end apps/devices/formats.
--
with procedure Set_X_Y (x, y : Natural);
-- After Set_X_Y, next pixel is meant to be displayed at position (x,y)
with procedure Put_Pixel (
red, green, blue : Primary_color_range;
alpha : Primary_color_range
);
-- When Put_Pixel is called twice without a Set_X_Y inbetween,
-- the pixel must be displayed on the next X position after the last one.
-- [ Rationale: if the image lands into an array with contiguous pixels
-- on the X axis, this approach allows full address calculation to be
-- made only at the beginning of each row, which is much faster ]
--
with procedure Feedback (percents : Natural);
--
mode : Display_mode;
--
procedure Load_image_contents (
image : in out Image_descriptor;
next_frame : out Ada.Calendar.Day_Duration
-- ^ animation: real time lapse foreseen between the first image
-- and the image right after this one; 0.0 if no next frame
);
-------------------------------------------------------------------
-- Some informations about the image, not necessary for decoding --
-------------------------------------------------------------------
type Image_format_type is
( -- Bitmap formats
BMP, FITS, GIF, JPEG, PNG, PNM, QOI, TGA, TIFF
);
function Format (image : Image_descriptor) return Image_format_type;
function Detailed_format (image : Image_descriptor) return String;
-- example: "GIF89a, interlaced"
function Subformat (image : Image_descriptor) return Integer;
-- example the 'color type' in PNG
function Bits_per_pixel (image : Image_descriptor) return Positive;
function Is_RLE_encoded (image : Image_descriptor) return Boolean;
function Is_Interlaced (image : Image_descriptor) return Boolean;
function Greyscale (image : Image_descriptor) return Boolean;
function Has_palette (image : Image_descriptor) return Boolean;
function Expect_transparency (image : Image_descriptor) return Boolean;
----------------------------------------------------------------
-- Information about this package - e.g. for an "about" box --
----------------------------------------------------------------
version : constant String := "010";
reference : constant String := "14-Apr-2022";
web : constant String := "http://gen-img-dec.sf.net/";
-- Hopefully the latest version is at that URL..........^
-- There is a mirror too @ https://github.com/zertovitch/gid
private
subtype U8 is Interfaces.Unsigned_8;
subtype U16 is Interfaces.Unsigned_16;
subtype U32 is Interfaces.Unsigned_32;
package Bounded_255 is
new Ada.Strings.Bounded.Generic_Bounded_Length (255);
type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class;
type RGB_Color_8_Bit is record
red, green, blue : U8;
end record;
type Color_table is array (Integer range <>) of RGB_Color_8_Bit;
type p_Color_table is access Color_table;
min_bits : constant := Integer'Max (32, System.Word_Size);
-- 13.3(8): A word is the largest amount of storage that can be
-- conveniently and efficiently manipulated by the hardware,
-- given the implementation's run-time model.
type Integer_M32 is range -2**(min_bits - 1) .. 2**(min_bits - 1) - 1;
-- We define an Integer type which is at least 32 bits, but n bits
-- on a native n > 32 bits architecture (no performance hit on 64+
-- bits architectures).
subtype Natural_M32 is Integer_M32 range 0 .. Integer_M32'Last;
subtype Positive_M32 is Integer_M32 range 1 .. Integer_M32'Last;
type Byte_array is array (Integer range <>) of U8;
type Input_buffer is record
data : Byte_array (1 .. 1024);
stream : Stream_Access := null;
InBufIdx : Positive := 1; -- Points to next char in buffer to be read
MaxInBufIdx : Natural := 0; -- Count of valid chars in input buffer
InputEoF : Boolean; -- End of file indicator
end record;
-- Initial values ensure call to Fill_Buffer on first Get_Byte
-- JPEG may store data _before_ any image header (SOF), then we have
-- to make the image descriptor store that information, alas...
package JPEG_defs is
type Component is
(Y, -- brightness
Cb, -- hue
Cr, -- saturation
I, -- ??
Q -- ??
);
type QT is array (0 .. 63) of Natural;
type QT_list is array (0 .. 7) of QT;
type Compo_set is array (Component) of Boolean;
type Info_per_component_A is record -- B is defined inside the decoder
qt_assoc : Natural;
samples_hor : Natural;
samples_ver : Natural;
up_factor_x : Natural; -- how much we must repeat horizontally
up_factor_y : Natural; -- how much we must repeat vertically
shift_x : Natural; -- shift for repeating pixels horizontally
shift_y : Natural; -- shift for repeating pixels vertically
end record;
type Component_info_A is array (Component) of Info_per_component_A;
type Supported_color_space is (
YCbCr, -- 3-dim color space
Y_Grey, -- 1-dim greyscale
CMYK -- 4-dim Cyan, Magenta, Yellow, blacK
);
type AC_DC is (AC, DC);
type VLC_code is record
bits, code : U8;
end record;
type VLC_table is array (0 .. 65_535) of VLC_code;
type p_VLC_table is access VLC_table;
type VLC_defs_type is array (AC_DC, 0 .. 7) of p_VLC_table;
end JPEG_defs;
type JPEG_stuff_type is record
components : JPEG_defs.Compo_set := (others => False);
color_space : JPEG_defs.Supported_color_space;
info : JPEG_defs.Component_info_A;
max_samples_hor : Natural;
max_samples_ver : Natural;
qt_list : JPEG_defs.QT_list;
vlc_defs : JPEG_defs.VLC_defs_type := (others => (others => null));
restart_interval : Natural; -- predictor restarts every... (0: never)
end record;
type Endianess_type is (little, big); -- for TIFF images
subtype Positive_32 is Interfaces.Integer_32 range 1 .. Interfaces.Integer_32'Last;
type Image_descriptor is new Ada.Finalization.Controlled with record
format : Image_format_type;
detailed_format : Bounded_255.Bounded_String; -- for humans only!
subformat_id : Integer := 0;
width, height : Positive_32;
display_orientation : Orientation;
top_first : Boolean; -- data orientation in TGA
bits_per_pixel : Positive;
RLE_encoded : Boolean := False;
transparency : Boolean := False;
greyscale : Boolean := False;
interlaced : Boolean := False; -- GIF or PNG
endianess : Endianess_type; -- TIFF
JPEG_stuff : JPEG_stuff_type;
stream : Stream_Access;
buffer : Input_buffer;
palette : p_Color_table := null;
first_byte : U8;
next_frame : Ada.Calendar.Day_Duration;
end record;
overriding procedure Adjust (Object : in out Image_descriptor);
overriding procedure Finalize (Object : in out Image_descriptor);
to_be_done : exception;
-- this exception should not happen, even with malformed files
-- its role is to pop up when a feature is set as implemented
-- but one aspect (e.g. palette) was forgotten.
--
-- Primitive tracing using Ada.Text_IO, for debugging,
-- or explaining internals.
--
type Trace_type is (
none, -- No trace at all, no use of console from the library
some_t, -- Image / frame technical informations
full -- Byte / pixel / compressed block details
);
trace : constant Trace_type := none; -- <== Choice here
no_trace : constant Boolean := trace = none;
full_trace : constant Boolean := trace = full;
some_trace : constant Boolean := trace >= some_t;
use Interfaces;
end GID;
Ada PDF Writer: Ada package for writing PDF files (.pdf).
Ada programming.
Some news about Ada PDF Writer and other Ada projects
on Gautier's blog.