(Last Mod: 27 November 2010 21:37:52 )
Note on Data Types:
t_image_data => WORD => unsigned 16-bit integer
t_image_size => WORD => unsigned 16-bit integer
WORD IMAGE_version (int what);
void IMAGE_report (IMAGE
*p);
IMAGE* IMAGE_new (IMAGE
*p, t_image_size rows, t_image_size cols, WORD bits);
IMAGE* IMAGE_delete (IMAGE
*p);
t_image_data
IMAGE_get_color (IMAGE *p, t_image_size row, t_image_size col, WORD color);
t_image_data
IMAGE_set_color (IMAGE *p, t_image_size row, t_image_size col, WORD color,
t_image_data value);
t_image_data
IMAGE_set_rgb (IMAGE *p, t_image_size row, t_image_size col,
t_image_data r, t_image_data g, t_image_data b);
WORD IMAGE_get_bits (IMAGE *p);
t_image_size IMAGE_get_rows (IMAGE *p);
t_image_size IMAGE_get_cols (IMAGE *p);
IMAGE* IMAGE_fill (IMAGE *p, t_image_data r, t_image_data g, t_image_data b);
IMAGE*
IMAGE_color2gray (IMAGE *p);
t_image_data IMAGE_min (IMAGE *p);
t_image_data IMAGE_max
(IMAGE *p);
t_image_data IMAGE_min_gray (IMAGE *p);
t_image_data IMAGE_max_gray (IMAGE *p);
IMAGE*
IMAGE_clip (IMAGE *p);
IMAGE*
IMAGE_scale (IMAGE *p, double factor);
IMAGE*
IMAGE_offset (IMAGE *p, int offset);
IMAGE*
IMAGE_set_depth (IMAGE *p, WORD bits);
IMAGE*
IMAGE_draw_pixel (IMAGE *p, t_image_size x, t_image_size y,
t_image_data r, t_image_data g, t_image_data b);
IMAGE*
IMAGE_draw_line (IMAGE *p, t_image_size x1, t_image_size y1, t_image_size x2, t_image_size y2,
t_image_data r, t_image_data g, t_image_data b);
IMAGE*
IMAGE_draw_box (IMAGE *p, t_image_size x1, t_image_size y1, t_image_size x2, t_image_size y2,
t_image_data r, t_image_data g, t_image_data b, WORD fill);
IMAGE*
IMAGE_draw_circle (IMAGE *p, t_image_size x, t_image_size y, t_image_size radius,
t_image_data r, t_image_data g, t_image_data b, WORD how);
IMAGE*
IMAGE_compose (IMAGE *d, IMAGE *s, int x, int y, WORD how,
t_image_data (*func)(t_image_data d, t_image_data s));
The image.h Header File
The image.c Source Code File
The IMAGE
structure is used to contain the data for a three-color 2-D
picture. The size (number of rows and columns) of the image is maintained as
part of the image structure. The data for each pixel may be accessed and
modified individually. This data consists of three values, one each for the red,
green, and blue color components.
Gray scale images are implemented by setting all three color components in a pixel to the same value. The gray scale equivalent of a colored pixel is taken to be the RMS (root-mean-square) value of the three components. This is frequently referred to as the luminosity of the pixel.
The maximum size that an image can be is limited by the size of the integer
used to represent the number of rows and columns. This data type is defined as
t_image_size
and, in V1.0, is a WORD
(unsigned 16-bit integers).
Thus, in theory, images with up to 65,535 rows and an equal number of colums are
supported. Similarly, the intensity information for each color component is
limited by the size of the data type t_image_data
, which, in
V1.0, is also a WORD
.
However, most images are composed of one-byte color intensities (0 through 255), though some formats of interest use 10-bits (0 through 1023). The ideal way of dealing with these variations would be to store the data as floating point values between 0.0 and 1.0; however, not only would this require more space (not a large concern, here) and probably slow down the functions (again, not a large concern, here), but it would add potential uncertainly in the exact values for each pixel. Because of the nature of some of the applications this structure is intended for, such as steganography, this was considered unacceptable. The consequence is that the user is responsible for knowing what the acceptable range of values is for the image they are working with. To help out with this, the nominal bit depth of the image is maintained within the structure and several functions are provided to help the user translate between bit depths. Furthermore, the function that writes the values to the data structure ensures that the values are clipped to the ranged supported by the present bit depth of the image. The user is cautioned that, since these are unsigned integers, code which produces nominally negative component values will likely end up being clipped at the most positive allowed component value.
One important distinction to be aware of is that the bit-depth of an
IMAGE
structure is not the same as the bit-depth of a BMP file. In
an IMAGE
structure, the bit depth is how may bits are in the
unsigned integer used to represent each color component. In a BMP file, the
bid-depth is how many bits are used to represent the color of each pixel
according to the BMP format definitions. These are fundamentally different
concepts; aside from the obvious distinction of being per-color versus
per-pixel, the bit-depth of a BMP file dictates the encoding scheme used. For
instance, in a BMP file, all bit depths of one-byte or less are represented
using a color palette. While this limits the total number of distinct colors
available to the image as a whole, each color used is still 24-bits total (8
bits per component). Except for 24-bit BMP files, which correspond directly to
8-bit IMAGE
structures, there is no simple way to convert
back and forth between the two. Of course, reading any of the legitimate BMP
file formats and converting them to IMAGE
structures is
relatively straight forward. But writing an IMAGE
structure
to a non-24-bit BMP file is much less so. However, since the IMAGE
structure is intended to be a generic representation of an image, the task of
performing this conversion, in either direction, is properly the responsibility
of the BMP (or possibly other) library.
The following sets of symbolic constants are defined in the image.h header file:
IMAGE
Version
ParametersIMAGE_VERSION
IMAGE_MAJOR
IMAGE_MINOR
These are used as arguments to the IMAGE_version()
.
IMAGE
Color ParametersIMAGE_RED
IMAGE_GREEN
IMAGE_BLUE
IMAGE_GRAY
These are to be used as arguments to those functions calling for a "color" parameter. The purpose is to make indicating the intended color easier and the code more readable. The red, green, and blue constants are self-explanatory. Using a color of 'gray' will either set all three color components to the same value or return the 'gray' equivalent of the pixel color which, here, is taken to be the RMS (root-mean-square) value of the three color components.
IMAGE
Composition
ParametersIMAGE_NEW
IMAGE_MIN
IMAGE_MAX
IMAGE_AVG
IMAGE_SUM
IMAGE_SUB
IMAGE_FUN
These are used as arguments to the IMAGE_compose()
function to determine how pixels from two images are to be combined.
WORD IMAGE_report(int what)
Returns the version information for the STRUCT library as a
16-bit unsigned integer according to value passed as the what
parameter:
what = IMAGE_VERSION
: Upper byte is
the major version number and the lower byte is the minor revision number.
what = IMAGE_MAJOR
: The major version
number
what = IMAGE_MINOR
: The minor
revision number.
void IMAGE_report(IMAGE *p)
Generates an on screen report giving the address of the structure and the values of all of the members. This is primarily for debugging purposes.
IMAGE* IMAGE_new(IMAGE *p, t_image_size rows, t_image_size cols, WORD bits)
If p
is NULL (the usual case), allocates memory for a new IMAGE structure with sufficient
memory to store a (rows
)x(cols
) image
and returns a pointer to that structure if successful. If p
is a pointer to an existing IMAGE structure, then that structure is reused. Returns NULL if
unsuccessful. If either rows
or cols
is
zero, then the structure is still allocated but no memory for the data is
allocated.
The bits
parameter is the nominal bit
depth (per image component, not per pixel) of the image that is stored within the structure. It has no effect on the
amount of memory allocated, but is used to ensure that data written to the
structure is within the appropriate range. The maximum value of bits
is sizeof(t_image_color)
.
IMAGE* IMAGE_delete(IMAGE *p)
Deallocates the memory used by the structure, including that allocated for the pixel data. Returns a NULL pointer if successful. If the memory could not be freed, then the original value of the pointer is returned.
int IMAGE_get_color(IMAGE *p, t_image_size row, t_image_size col, WORD
color)
Gets the value of the color component specified for the pixel
in the specificed row and column. If the requested color is gray (IMAGE_GRAY
),
then the RMS value of the three color components is returned. Note: the data
itself is not changed.
t_image_data IMAGE_set_color(IMAGE *p, t_image_size row, t_image_size col, WORD
color, t_image_data value)
Sets the specified color component of the pixel specified by
row
and col
to value
. If the specified
component is gray (IMAGE_GRAY
), then all three component are
set to value
. Returns the new value of the specified component
(which should be value
).
t_image_data IMAGE_set_rgb(IMAGE *p, t_image_size row, t_image_size col, t_image_data r,
t_image_data g, t_image_data b)
Sets the color of the pixel specified by row
and
col
to that indicated by the r
, g
,
and b
parameters. Returns the new grayscale value of the
pixel.
WORD IMAGE_get_bits(IMAGE *p)
Returns the nominal bit depth of the image.
t_image_size IMAGE_get_rows(IMAGE *p)
Returns the number of rows in the image.
t_image_size IMAGE_get_cols(IMAGE *p)
Returns the number of columns in the image.
IMAGE* IMAGE_fill(IMAGE *p, t_image_data r, t_image_data g, t_image_data b)
Fills the entire image with the color indicated by the r
,
g
,
and b
parameters. Returns p
.
IMAGE* IMAGE_color2gray
(IMAGE *p);
Sets each pixel's color to that pixel's gray scale value. Returns p
.
t_image_data IMAGE_min
(IMAGE *p);
Returns the minimum color component in the image.
t_image_data IMAGE_max
(IMAGE *p);
Returns the maximum color component in the image.
t_image_data IMAGE_min_gray (IMAGE *p);
Returns the minimum gray scale value in the image.
t_image_data IMAGE_max_gray (IMAGE *p);
Returns the minimum gray scale value in the image.
IMAGE* IMAGE_clip (IMAGE *p);
Clips all component values in the image to the maximum as
indicated by the images' present bit depth. Returns p
.
IMAGE* IMAGE_scale (IMAGE *p, double factor);
Multiplies all component values within the image by
factor
, clipping as needed to avoid exceeding the image's bit depth. Returns p
.
IMAGE* IMAGE_offset (IMAGE *p, int offset);
Adds factor
to all component values within
the image, clipping as needed to avoid exceeding the image's bit depth. Returns p
.
IMAGE* IMAGE_set_depth (IMAGE *p, WORD bits);
Changes the image's bit depth from its present value to
bits.
The pixel component values are scaled accordinglyt. Returns p
.
IMAGE* IMAGE_draw_pixel (IMAGE *p, t_image_size x, t_image_size y,
t_image_data r, t_image_data g, t_image_data b);
Sets the color of the pixel specified by row
and
col
to that indicated by the r
, g
,
and b
parameters. The same as IMAGE_set_rgb() except for the
return value. This function is primarily provided to give the a consistent set
of drawing functions. Returns p
.
IMAGE* IMAGE_draw_line (IMAGE *p, t_image_size x1, t_image_size y1, t_image_size x2, t_image_size y2,
t_image_data r, t_image_data g, t_image_data b);
Draws a line from (x1
,y1
)
to (x1
,y2
). Returns p
.
Note, unspecified results if the endpoints are not within the image's bounds.
IMAGE* IMAGE_draw_box (IMAGE *p, t_image_size x1, t_image_size y1, t_image_size x2, t_image_size y2,
t_image_data r, t_image_data g, t_image_data b, WORD fill);
Draws a box with corners located at (x1
,y1
)
to (x1
,y2
). If fill
is FALSE
then only the outline is draw, otherwise the box is
solid. Returns p
.
Note, unspecified results if the endpoints are not within the image's bounds.
IMAGE* IMAGE_draw_circle (IMAGE *p, t_image_size x, t_image_size y, t_image_size radius,
t_image_data r, t_image_data g, t_image_data b, WORD how);
Draws a circle centered at at (x
,y
)
with the given radius
. If fill
is
FALSE
then only the outline is draw, otherwise the circle is
solid. Returns p
.
Note, unspecified results if the endpoints are not within the image's bounds.
IMAGE* IMAGE_compose (IMAGE *d, IMAGE *s, int x, int y, WORD how,
t_image_data (*func)(t_image_data d, t_image_data s));
Combines two images by overlaying the second image (s
)
onto the first (or destination) image (d
). The size of the
first image is unchanged. The second image is shifted by (x
,y
)
before being overlaid. Returns d
, the pointer to the
destination image.
The how
parameter dictates how the value of the
pixel in the destination image is to be modified. The options are as follows:
IMAGE_NEW
- Uses the value
from the second image.
IMAGE_MIN
- Uses the
minimum value of the components from the two images.
IMAGE_MAX
- Uses the
maximum value of the components from the two images.
IMAGE_AVG
- Uses the
average value of the components from the two images.
IMAGE_SUM
- Uses the sum of
the components from the two images.
IMAGE_SUB
- Uses the
difference of the components from the two images (destination - source)/
IMAGE_FUN
- Use a custom
function. The pointer to this function must be passed as the final argument.
The images are combined component-by-component, pixel-by-pixel. Thus it is not possible (using this function) to use information from surrounding pixels (or even the other components within the same pixel) in determining the new pixel color. One potential consequence of this is color shifting if a pixel's color components are clipped. This is only possible with the SUM and SUB options (as well as the custom option, of course) and is particularly likely with the SUB option.
If IMAGE_FUN
is passed as the how
parameter, then the function uses a user-supplied custom combining function; a
pointer to this function must be passed as the final argument (which can be set
to NULL for all other how
choices). This function will be passed
the pixel component values, one-by-one and pixel-by-pixel, from the
corresponding pixels from first and second images and must return the value that
destination pixel should be set to.
If the bit depths of the two images are not equal, the second is scaled to match the first and then scaled back afterwards. The possibility of scaling artifacts persisting in the second image exists.