CD - Canvas Draw

Client Images

There are 2 kinds of client images: RGB and Indexed RGB (or MAP). The RGB image is composed by 3 buffers: red, green and blue (more colors, more memory). The MAP image is composed by 1 buffer of indices for a table and one table of encoded RGB values (less colors, less memory).

The image buffer is described by its width and height in pixels. The starting point of the buffer is the origin of the image, which is located at its bottom left corner. To retrieve a pixel in the image, use the formula pixel(x,y)=buffer[y*width + x].

The Put functions may do zoom in or out; zero order interpolation is used to scale the image. It is not possible to specify a part of the image to be drawn.


void cdGetImageRGB(unsigned char *r, unsigned char *g, unsigned char *b, int x, int y, int w, int h); [in C]
cd.GetImageRGB(imagergb: imagergb_tag; x, y: number) [in Lua]

Returns the red, green and blue components of each pixel in a server image. The RGB components are provided in three matrices stored as byte arrays. The (i,j) component of these matrices is at the address (j*w+i). As occurs with all primitives from the Canvas Draw library, the pixel (0,0) is at the bottom left corner, and the pixel (w-1,h-1) is that the upper right corner of the image rectangle.

void cdPutImageRectRGB(int iw, int ih, unsigned char *r, unsigned char *g, unsigned char *b, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax); [in C]
void wdPutImageRectRGB(int iw, int ih, unsigned char *r, unsigned char *g, unsigned char *b, double x, double y, double w, double h, int xmin, int xmax, int ymin, int ymax); (WC) [in C]
cd.PutImageRectRGB(imagergb: imagergb_tag; x, y, w, h, xmin, xmax, ymin, ymax: number) [in Lua]
cd.wPutImageRectRGB(imagergb: imagergb_tag; x, y, w, h, xmin, xmax, ymin, ymax: number) (WC) [in Lua]

Puts, in a specified area of the canvas, an image with its red, green and blue components defined in the three matrices stored in byte arrays. The (i,j) component of these matrices is at the address (j*iw+i). The pixel (0,0) is at the bottom left corner, and the pixel (iw-1,ih-1) is that the upper right corner of the image rectangle.

Parameters w and h refer to the target rectangle of the canvas, so that it is possible to reduce or expand the image drawn. If w and h are 0, the size of the image is assumed (iw and ih).

It also allows specifying a rectangle inside the image to be drawn, if xmin, xmax, ymin and ymax are 0 then the whole image is assumed.

If the driver has bpp <=8 or only 256 colors or less, then the image is converted to 256 optimal colors using the function cdRGB2Map and is drawn using cdPutImageRectMap.

void cdPutImageRectRGBA(int iw, int ih, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax); [in C]
void wdPutImageRectRGBA(int iw, int ih, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a, double x, double y, double w, double h, int xmin, int xmax, int ymin, int ymax); (WC) [in C]
cd.PutImageRectRGBA(imagergba: imagergba_tag; x, y, w, h, xmin, xmax, ymin, ymax: number) [in Lua]
cd.wPutImageRectRGBA(imagergba: imagergba_tag; x, y, w, h, xmin, xmax, ymin, ymax: number) (WC) [in Lua]

The same as function  cdPutImageRectRGB, except for the fact that it is possible to specify an alpha channel. The resulting color is the image color weighted by the alpha value, using the formula result=(source * alpha + destiny * (255 - alpha))/255. This means that, if alpha is 0, the resulting color is the target color (completely transparent), and, if alpha is 255, the resulting color is the original image color (completely opaque).

If this function is not defined for a given driver or if alpha is NULL, then the function cdPutImageRGB is used, as long as it is defined.

void cdPutImageRectMap(int iw, int ih, unsigned char *index, long int *colors, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax); [in C]
void wdPutImageRectMap(int iw, int ih, unsigned char *index, long int *colors, double x, double y, double w, double h, int xmin, int xmax, int ymin, int ymax); (WC) [in C]
cd.PutImageRectMap(imagemap: imagemap_tag; palette: palette_tag; x, y, w, h, xmin, xmax, ymin, ymax: number) [in Lua]
cd.wPutImageRectMap(imagemap: imagemap_tag; palette: palette_tag; x, y, w, h, xmin, xmax, ymin, ymax: number) (WC) [in Lua]

The same as function  cdPutImageRectRGB, except for the fact that the colors are provided by means of an index matrix (map). The color corresponding to a given index is given in  colors[index]. The map is also a matrix stored as a byte vector. If the color vector is null, then a vector with 256 gray tones is assumed.

void cdRGB2Map(int width, int height, unsigned char *red, unsigned char *green, unsigned char *blue, unsigned char *map, int pal_size, long *color); [in C]
cd.RGB2Map(imagergb: imagergb_tag, imagemap: imagemap_tag, palette: palette_tag) [in Lua]

Converts an RGB image into an image with 256 indexed colors. The resulting image must have the same size (width x length) as the RGB image. It is necessary to allocate memory for the arrays map and colors. This is the same algorithm used in the IM library - in fact, the same code.


Extras

The following functions are used only for encapsulating the several types of client images from the library in a single structure, simplifying their treatment. 

For such, a public structure was created, called cdBitmap, which will store the image. From this structure, the following fields are officially defined:

cdBitmap:
  int w      /* image width */
  int h      /* image heigth */
  int type   /* image type: CD_RGBA, CD_RGB or CD_MAP */

cdBitmap* cdCreateBitmap(int w, int h, int type); [in C]
cd.CreateBitmap(w, h, type: number) -> (image: bitmap_tag) [in Lua]

Creates an image with width w, and height h and of type type. The type can be CD_RGBA, CD_RGB or CD_MAP. However, CD_MAP only means that the image will have 256 colors if type is greater than 0. It is assumed that the image will be MAP with the same number of colors in the palette as type. Internally, the color palette is always allocated with 256 entries, which may or may not be totally fulfilled. In this case, the value of type can be changed as wished. It also encapsulates cdCreateImage.

cdBitmap* cdInitBitmap(int w, int h, int type, ...); [in C]
[There is no equivalent in Lua]

Similar to cdCreateBitmap, but it accepts the data area already allocated by the user. The parameters vary according to the image type.

CD_RGBA - (unsigned char* red, unsigned char* green, unsigned char* blue, unsigned char* alpha)
CD_RGB - (unsigned char* red, unsigned char* green, unsigned char* blue)
CD_MAP - (unsigned char* index, lont int* colors)

void cdKillBitmap(cdBitmap* image); [in C]
cd.KillBitmap(image: bitmap_tag) [in Lua]

Liberates the memory allocated for the image. It is not necessary to have an active canvas to call this function. It also encapsulates cdKillImage.

unsigned char* cdBitmapGetData(cdBitmap* image, int dataptr); [in C]
cd.BitmapGetData(image: bitmap_tag; dataptr: number) -> (data: channel_tag) [in Lua]

Returns a pointer to the image's data area according to dataptr. The following values are defined for dataptr:

CD_IRED - red component of an RGB image. channel_tag in Lua.
CD_IGREEN - green component of an RGB image. channel_tag in Lua.
CD_IBLUE - blue component of an RGB image. channel_tag in Lua.
CD_IALPHA - alpha component of an RGBA image. channel_tag in Lua.
CD_INDEX - indices of a MAP image. channel_tag in Lua.
CD_COLORS - color table of a MAP image. In this case, a type conversion must be made to (long int*).  palette_tag in Lua.

void cdBitmapSetRect(cdBitmap* image, int xmin, int xmax, int ymin, int ymax); [in C]
cd.BitmapSetRect(image: bitmap_tag; xmin, xmax, ymin, ymax: number) [in Lua]

Allows specifying a region of interest inside the image to be used by the function cdPutBitmap. If no region was defined, the whole image is used, that is, (0, w-1, 0, h-1).

void cdPutBitmap(cdBitmap* image, int x, int y, int w, int h); [in C]
void wdPutBitmap(cdBitmap* image, double x, double y, double w, double h); (WC) [in C]
cd.PutBitmap(image: bitmap_tag; x, y, w, h: number) [in Lua]
cd.wPutBitmap(image: bitmap_tag; x, y, w, h: number) (WC) [in Lua]

Draws the  image in the position (x,y), changing the scale. It encapsulates cdPutImageRectRGB, cdPutImageRectRGBA and cdPutImageRectMap. The region of the image drawn depends on the rectangle defined by cdBitmapSetRect. If no rectangle was defined, then the whole image is used.

The parameters w and h allow scaling the image, increasing or decreasing its dimensions when drawn. If  w and/or h are 0, then no scale change is assumed.

void cdGetBitmap(cdBitmap* image, int x, int y); [in C]
cd.GetBitmap(image: bitmap_tag; x, y: number) [in Lua]

Encapsulates cdGetImageRGB. Nothing happens if the image is MAP.

void cdBitmapRGB2Map(cdBitmap* image_rgb, cdBitmap* image_map); [in C]
cd.BitmapRGB2Map(image_rgb: bitmap_tag, image_map: bitmap_tag) [in Lua]

Encapsulates cdRGB2Map. The images must be of types RGB(A) and MAP, respectively.


Extras in Lua

cd.CreateImageRGB(width, height: number) -> (imagergb: imagergb_tag)

Creates an RGB image in Lua.

cd.KillImageRGB(imagergb: imagergb_tag)

Destroys the created RGB image and liberates allocated memory.

cd.CreateImageRGBA(width, height: number) -> (imagergba: imagergba_tag)

Creates an RGBA image in Lua.

cd.KillImageRGBA(imagergba: imagergba_tag)

Destroys the created RGBA image and liberates allocated memory.

cd.CreateImageMap(width, height: number) -> (imagemap: imagemap_tag)

Creates a Map image in Lua.

cd.KillImageMap(imagemap: imagemap_tag)

Destroys the created Map image and liberates allocated memory.

Data Access

Data access in Lua is done directly using the operator "[y*width + x]" in image channels. Each channel works as a value table which should be consulted or modified in the following way:

imagergb = cd.CreateImageRGB(100, 200)
...
imagergb.r[y*100 + x] = 255
imagergb.g[y*100 + x] = 128
imagergb.b[y*100 + x] = 0
...
green = imagergb.g[y*100 + x] -- it will return 128

Notice also that it is always important to define the index in the channels, because, for instance, the type of imagergb.r (without index), channel_tag, is internal to the implementation of CDLua and it is useless for the end user. The order of the tables is important, so that imagergb[n].r has no meaning to CDLua and the expression will cause a fatal error. Finally, the user could expect the value of imagergb[n] to be of type color_tag. Unfortunately, this is not the case, and such expression will cause the same fatal error.

MAP images have only one channels, so the channel is not specified: imagemap[y*100+x]. The pallete is kept separeted from the image map.

Known channel names are:

r - red channel of RGB or RGBA images.
g - gree channel of RGB or RGBA images.
b - blue channel of RGB or RGBA images.
a - alpha channel of RGBA images.
m - indices channel of MAP images (valid only for cdBitmap objects).
p - colors table of MAP images (valid only for cdBitmap objects). It is a palette_tag object.