/
gid.txt
209 lines (172 loc) · 9.18 KB
/
gid.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
GID - the Generic Image Decoder
===============================
The Generic Image Decoder (GID) is an Ada 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.
Some features:
- Standalone (no dependency on other libraires, bindings,...)
- Unconditionally portable code: OS-, CPU-, compiler- independent code.
- Multi-platform, but native code
- Task safe
- Endian-neutral
- Free, open-source
- pure Ada 2005 (compiled by Ada 2005, and compilers for later versions)
Some existing or possible applications:
- image processing (interactive or not)
- image analysis, text recognition
- a drawing program
- a web browser
- use of images as data for simulations
- thumbnail generation for a file manager
Through the genericity and the use of the Inline pragma at multiple
nesting levels (see it like macros inside macros), the package is
able to deliver a decent decoding performance, keep a reasonably
compact and readable source code, and avoid tediously copied
pieces of code with almost the same contents corresponding to
different subformats.
Licensing, warranty, copyright, supported formats, authors, credits, history
============================================================================
There is NO WARRANTY in the GID software.
GID is licensed under the MIT License.
You find the full license and copyright notice in gid.ads.
Further details (especially, credits and history) can be found in gid_work.xls.
Files
=====
gid.ads GID package specification
gid.adb GID package body
gid-*.ad* private packages for decoding specific
formats, reading headers,...
To summarize, the gid*.ad* files are the whole GID source files.
For example, you can have a copy of those in a gid/ subdirectory
in your project.
gid.gpr AdaCore GNAT/GCC project file - to be opened with
GNAT Studio or used with the command: gnatmake -P gid
gid_objectada.prj ObjectAda (10.4+) project file
gid_work.xls This workbook contains GID's history, a list of open
bugs, technical informations about formats, etc.
test/mini.adb Small-size command-line demo, recommended for beginning.
Decodes images of any supported type and writes PPM
(Portable PixMap) files. File names are given as
arguments (also works from a GUI file explorer
with drag & drop). Typically, you put plenty of
images into the test folder and launch "mini *" to
convert them all.
test/to_bmp.adb Middle-size command-line demo which converts all image
files given as argument into BMP image files with
the .dib extension. Contrary to mini.adb, it
handles transparency (GIF, PNG, QOI, TGA), orientation
(JPEG) and animation (GIF) as well, but of course
it is more difficult to understand than mini.adb.
test/all_rgb.adb This program transforms an image into a similar image
in which each pixel has a different colour and
all 8-bit-per-channel colours are displayed.
test/recurve.adb Image processing demo: Recurve is a digitalization
tool which recovers curves from a chart and outputs
corresponding data.
test/steg.adb Steganography tool: Steg hides a data into an image.
How to use GID in your programs
===============================
Hopefully the package specification (in the file gid.ads) is self
explanatory enough. There are three steps needed:
1) Load the image header from a data stream
2) If needed, use dimensions to prepare the retrieval of the image
3) Load and decode the image itself. If the image is animated,
call Load_image_contents until next_frame is 0.0
The subprograms corresponding to these steps are
1) Load_image_header
2) Pixel_width and Pixel_height
3) Load_image_contents
Load_image_contents is generic. You provide the following:
* Primary_color_range: the type of primary colors.
Usually it is a byte (E.g. Unsigned_8)
* procedure Set_X_Y: setting a "cursor" (an array index, for instance)
* procedure Put_Pixel: set a color (and transparency) on
the "cursor" place; the cursor is meant to move one pixel
to te right, then
* procedure Feedback: display progress (if you want or need it;
otherwise, you can always provide an empty procedure)
* mode: Display_mode: here you tell if you want the decoding rather
nicer or faster, when the decoder is processing "progressive"
(JPEG) or "interlaced" (GIF, PNG) pictures. Note: the end
result is exactly the same. The visual difference appears only
during the decoding.
This generic construction allows you a total freedom on where and
how to use GID in your programs. In addition, your Set_X_Y and
Put_Pixel procedures are inserted at compile-time, (no call instruction),
right in the heart of the decoding procedures, for each image format,
which should deliver a decent performance as soon as you set the right
compiler options (optimization, inlined or macro-expanded generics,
suppression of all checks, loop unrolling).
*Important note*: the performance of GID is mostly dependant of the code
you provide in Put_Pixel. If it is much more that inserting a byte into
a buffer and advancing an index or a pointer, you will get an *important
performance penalty*. Remember that Put_Pixel is called... for each pixel!
How to build GID
================
- From GPS (GNAT Programming Studio - see below for installation), press F4.
The main test's (to_bmp) executable is built in the /test folder.
- From ObjectAda's IDE, press F7. to_bmp.exe is in the folder
created by ObjectAda upon first project opening.
- From the command line, with GNAT (see below for GNAT installation):
- default build mode: gprbuild -p -P gid
- other build mode (e.g. Fast for producing fast executables):
gprbuild -p -P gid -XGID_Build_Mode=Fast
We assume here you have GID unpacked "out of the box", with directories.
Installing the free GNAT Ada compiler
=====================================
- Linux: apt install gnat (or an equivalent command like yum)
- Other systems: download GNAT @
https://www.adacore.com/community or
https://www.adacore.com/download
Memory requirements and usage
=============================
GID uses only memory for decoding purposes (e.g. decompression
structures, color tables) and doesn't store the image itself.
As a result, memory will be reserved for *at most* only one copy of
the output bitmap, and this under the format you want or need to have.
The exception to that is progressive JPEG, where the whole
bitmap in a special colour space has to be stored and updated
over multiple scans.
As an example, the `to_bmp` demo stores the image as a packed
RBG byte array with a 4-byte padding which is the appropriate
format for dumping a BMP file in the end. But there are many
other possible storage formats, and GID lets you the total
freedom about it. It can be even the case that the bitmap
storage is more appropriate through an operating system or
a specific library; in such a case you would not store the
bitmap within the Ada progam at all and Put_Pixel would be used
to transmit the pixels further. In some more exotic cases,
you don't want to store the bitmap at all, but use it as
some sort of data in floating-point values, or do a statistic
of the image.
All memory used by GID is taken on the stack, with the exception
of palettes, JPEG's DHT tables and JPEG progressive temporary image.
Those are dynamically allocated on the heap and deallocated upon
the scope's end of a variable of the Image_descriptor type.
It means there is no possible memory leak.
The use of heap allocation is justified there because of the
relatively large size of those objects. They could very well
be also part of the descriptor record, with a maximal size for
palette (2**16, for the TGA format).
Where to find the latest version
================================
Please check the "web" constant in gid.ads.
Note on the construction of GID.
================================
All image formats decoded by GID have similarities in their structure.
- Most streams begin with a signature, followed by a header
containing dimensions and the color depth. Then the image contents
follow. This is obvious to have such a data organisation,
since the header details are needed to calibrate the recipient
of the image.
- Streams are structured in blocks of data which are given different
names depending on the format:
- PNG : chunks
- GIF : blocks
- JPEG: segments
- TGA : areas
- TIFF: tags
etc.