"#include ''ary.h''
ARY* makary(int fr, int lr, int fc, int lc, int matrix_type);
void destAry(ARY * ary);"
void* consAry1
#define consAry
"CARY *makCary(int rows, int cols);"
"BARY *makBary(int rows, int cols);"
"SARY *makSary(int rows, int cols);"
"IARY *makIary(int rows, int cols);"
"FARY *makFary(int rows, int cols);"
"DARY *makDary(int rows, int cols);"
"PARY *makPary(int rows, int cols);"
USARY *makUSary(int rows, int cols);
RGBARY *makRGBary(int rows, int cols);
XRGBARY *makXRGBary (int rows, int cols);
YUVARY *makYUVary (int rows, int cols);
FRGBARY *makFRGBary (int rows, int cols);
RGIARY *makRGIary (int rows, int cols) ;
#define rowsAry(a)
#define colsAry(a)
#define startAddrAry(a)
"void InitialiseBary( BARY *array, int value );"
"void InitialiseFary( FARY *array, float value );"
"void InitialisePary( PARY *array, void * ptr );"
void InitialiseUSary( USARY *array, unsigned short int ptr );
FILE* ReadP5header(char * filename, int * cols, int * rows);
BARY* P5pgm2Bary(char * filename);
BARY* P4pbm2Bary(char * filename);
FARY* P5pgm2Fary(char * filename);
RGBARY* P6ppm2RGBary(char * filename);
RGBARY* MoveP6ppm2RGBary(RGBARY * RGBary, char * filename);
YUVARY* P6ppm2YUVary(char * filename);
void* Bary2P5pgm(BARY * image, char * filename);
void* Bary2P4pbm(BARY * image, char * filename);
void* RGBary2P6ppm(RGBARY * image,char * filename);
void* YUVary2P6ppm(YUVARY * image,char * filename);
void* Bary2P5pgmCm(BARY * image,char * filename,char * comment) ;
void* Bary2P4pbmCm(BARY * image, char * filename,char * comment);
void* RGBary2P6ppmCm(RGBARY * image,char * filename,char * comment);
void CutFary2P5pgm(FARY * image,char * filename);
void ScaleFary2P5pgm(FARY * image,char * filename) ;
FARY* P5pgmRoi2Fary(char * filename, int * roi, int fullImage, int extend);
FARY* P5pgmRoi2Fary1 (FILE * file, int cols, int rows, int * roi,
int fullImage, int extend, void * mem);
void WriteAry(ARY *ary,char * filename);
ARY * ReadAry(char *filename);
"ARY * CopyAry(ARY * ary);"
"void NormFary(FARY *mask,float value);"
"void ScaleMaxFary(FARY *ary,int requested_max) ;"
"BARY * Fary2Bary(FARY *fary);"
"BARY * ScaleFary2Bary(FARY *fary);"
""
t_frgb Yuv2Frgb(t_yuv p) ;
t_rgb Yuv2Rgb(t_yuv p);
t_rgI Yuv2Rgi(t_yuv yuv);
t_rgI Frgb2Rgi(t_frgb frgb);
t_rgI Rgb2Rgi(t_rgb rgb);
t_rgI Yuv2Rgi(t_yuv yuv);
t_rgb Frgb2Rgb(t_frgb frgb);
t_frgb Rgb2Frgb(t_rgb frgb);
t_rg Frgb2Rg(t_frgb frgb);
RGBARY* YUVary2RGBary(YUVARY * ary) ;
FRGBARY* YUVary2FRGBary(YUVARY * ary);
RGIARY* YUVary2RGIary(YUVARY * ary) ;
BARY * Fary2Bary(FARY *fary);
BARY * ScaleFary2Bary(FARY *fary);
RGBARY * XRGBary2RGBary(XRGBARY * image) ;
RGBARY * XBGRary2RGBary(XRGBARY *xrgb) ;
SARY * Bary2Sary(BARY *bary);
BARY * Sary2Bary(SARY *sary);
typedef struct {
int lb1; /* first row index */
int ub1; /* index of last row */
int lb2; /* index of first column */
int ub2; /* index of the last column */
int ary_type; /* the type of the ARY */
ELEMENT_TYPE **el; /* pointer to a pointer to array element*/
} ARY_NAME;
This version of the ary library supports the following ELEMENT_TYPES:
ELEMENT_TYPE ARY_NAME Constructor
char CARY makCary(rows,cols)
unsigned char BARY makBary(rows,cols)
short int SARY makSary(rows,cols)
int IARY makIary(rows,cols)
float FARY makFary(rows,cols)
double DARY makDary(rows,cols)
void * PARY makPary(rows,cols)
t_rgb RGBARY makRGBary(rows, cols)
t_frgb FRGBARY makFRGBary (rows, cols)
t_xrgb XRGBARY makXRGBary (rows, cols)
t_yuv YUVARY makYUVary (rows, cols)
t_rgI RGIARY makRGIary (rows, cols)
any_ary_type makary (int fr,int lr,int fc,int lc,int type)
any_ary_type makmemary (int fr,int lr,int fc,int lc,int type,void *addr);
any consAry (rows,cols,type)
any consAry1 (int fr,int lr,int fc,int lc,int elSize,void * mem);
The t_rgb, t_frgb, t_xrgb, t_yuv, t_rgI (see ary.h) declare structures
that can hold:
t_rgb red, green, blue components, each represented as a byte
t_frgb red, green, blue components, each represented as a float
t_xrgb x, red, green, blue compenents as in SUN rasterfile
t_yuv yuv components of a digitized PAL video signal
t_rgI red and gren chromaticity + intensity representation of
colour
Before using a variable of ARY type, the dynamic ARY structure must be created
using a constructor. Preferably the constructor is called when the
variable is declared, eg.
BARY * array_of_bytes = makBary(250,16);
This creats a 2D array of unsigned chars (bytes). Individual elements of the array can be accessed using the [] notation:
elem = array_of_bytes->el[7][7];
The lower and upper bounds are stored in the lb1,lb2, ub1,ub2 fields so scanning all array elements would typically look like:
/*--------------------- cut here -----------------------*/
int main(void)
{
BARY * image = makBary(30,30)
int i,j;
/*--------- initialise all elements to 0 -------------*/
for(i=image->lb1; i<=image->ub1; i++)
for(j=image->lb2; j<=image->ub2; j++)
image->el[i][j] = 0; /* could use InitialiseBary*/
/* do you processing here */
/*-------- free the memory used by ary ----------------*/
destAry((ARY*)image);
return 0;
}
/*--------------------- cut here -----------------------*/
BARY * bary = makary(1,10,2,10,BYTEMATRIX);
This command allocates a 2D array with lower bounds 1 resp. 2 and both upper bounds 10. The last parameter defines the type of ARY required. The following constants are defined
Type Constant
CARY UBYTEMATRIX
SARY SHORTINTMATRIX
IARY INTEGERMATRIX
FARY FLOATMATRIX
DARY DOUBLEMATRIX
BARY BYTEMATRIX
PARY POINTERMATRIX
RGBARY RGBMATRIX
XRGBARY XRGBMATRIX
FRGBARY FRGBMATRIX
RGIARY RGIMATRIX
USARY USHORTINTMATRIX
any_other USER_DEFINED
The memory used by an ARY variable should be deallocated when a variable
goes out of scope by a call to destAry, eg.
destAry((ARY*)bary)
The function destAry is declared to expect a parameter of type ARY. No variables of this type exist; the ARY type is used to indicate and ARY variable of any element type (int, float, etc.). ARYs must not be deallocated by a call to free(), this frees only a small part of the memory allocated for the ARY. Manipulation of ARY's of user-defined types is covered in a separate section (see User-defined types).
ARY's can be stored in and read from a file format used in the pbmplus package of Jeff Poskanzer. The package provides a large number of image manipulation routines. Moreover, files in this format are accepted by xv, a sophisticated image viewer written by John Bradley (bradley@cis.upenn.edu). XV is an interactive tool that allows image resizing, cutting, conversion to a number of formats, etc.
The interface is provided by a number of functions with pgm/ppm/pbm in the function name. The functionality of each of the function is coded in the function name. P4pbm and P5pgm refer to the raw bitmap (pbm) and raw greylevel (pgm) image formats respectively. So P5pgm2Bary reads a pgm file into a BARY structure it allocates and returns. Bary2P5pgm writes an ARY to a P5 pgm file.
The family of output functions (write image from ARY) with the Cm suffix inserts a comment into the pbm/pgm/ppm file (in the required format). The Move prefix indicates that the image is read into an already existing ary, which must have the same size as the image read.
Scaling is necessary when a floating point matrix is output into a 256 level pgm image. CutFary2P5pgm replaces all values smaller then 0 by 0 and all values >255 by 255. ScaleFary2P5pgm finds a maximum of all elements which is then output as 255; other values are scaled linearly. A simple bitmap inversion serves as an example:
/*--------------------- cut here -----------------------*/
int main()
{
BARY * image = P4pbm2Bary("-"); /* read P4 from stdin */
int i,j;
for(i=image->lb1; i<=image->ub1; i++)
for(j=image->lb2; j<=image->ub2; j++)
image->el[i][j] = 255 - image->el[i][j]; /* invert */
Bary2P4pbm(image,"-"); /* write as P4 to stdout */
destAry((ARY*)image);
return 0;
}
The P5pgmRoi2Fary(char * filename, int * roi, int fullImage, int extend)
function reads a rectangular area (a region of interest - ROI)
from the matrix (image) stored in the 'filename' file. If the 'fullImage'
is set to a non-zero value, the roi parameter will be ignored and the whole
matrix (image) will be read in. Ohterwise (ie. if fullImage==0) the roi
must point to and array of four integers specifying the region (rectangle)
of interest in the following way: roi[0]=x_min (where x denotes
the first coordinate of ary); roi[1]=x_max,roi[2]=y_min,roi[3]=y_max. The
rectange defined through roi is clipped (intersected) with the matrix
(image) read from file if a part of it is not inside the matrix; therefore
the ARY returned by P5pgmRoi2Fary need not be of the same size of roi. For
typical use the 'extend' parameter should be set to 0 and ignored.
The P5pgmRoi2Fary function was written to support convolutions on regions of
interest. If convolution is to be performed on the whole ROI, the data read
must be 'extended' by half of the convolutin mask size. If the ROI is
close to the border of the original image 'mirroring' is applied.
CopyAry creates a copy of an ary of any type. NormFary(FARY *fary,float value) normalises FARY so that the summ of its absolute values is 'value'. ScaleMaxFary(FARY *ary,int requested_max) scales a FARY so that it's maximum (positive, not absolute!) is equal to the requested_max value. Fary2Bary convets FARY to BARY by setting all values above 255 to 255, all values bellow 0 to 0 and flooring (not rounding) the remaning values. ScaleFary2Bary scales FARY to BARY so that the maximum element becomes 255 and the others are linearly rescaled.
typefef struct{....} myType;
DEFINE_ARY(myTypeARY, myType);
myTypeARY *ary = consAry(100,100,myType);
myType x = .... ; /* initialise your structure */
ary->el[1][1] = x;
User-defined ARY's can be constructed using consAry (instead of mak?ary)
with lower bounds set to 0. consAry1 allows to specify lower bounds.
User-defined ARY's can be copied, written to file, read from a file and
destroyed. Individual elements are accessed in the standard way.
At UoS the library was ANSI-fied, made portable by changing the internal representation of ARY. Other additions: the structures for aggregate types, possibility to declare ARY of a user-defined type (without modifing the library), the generic I/O (essentially external rep. of ary), interface to the pgm package;a couple of miscelanous functions and macros, conversion functions between colour representations. The pbm/pgm/ppm formats were defined in the pbmplus packages written by Jef Poskanzer (jef@well.sf.ca.us).