Navigation C API Pages Python bindings Applications

Drawing Pixmap

The gp_pixmap structure describes an in memory pixmap. The structure contains all metadata needed for drawing, loaders and filters.

Data Structure

typedef struct gp_pixmap {
        uint8_t *pixels;         /* pointer to image pixels */
        uint8_t  bpp;            /* pixel length in bits */
        uint32_t bytes_per_row;
        uint32_t w;              /* width in pixels */
        uint32_t h;              /* height in pixels */
        /*
         * Row bit offset. The offset is ignored for byte aligned pixels.
         * Basically it's used for non aligned pixels with combination
         * with subpixmapes.
         */
        uint8_t offset;

        enum gp_pixel_type pixel_type; /* pixel format */

        /*
         * Pointer to optional Gamma correction tables.
         */
        struct gp_gamma *gamma;

        uint8_t axes_swap:1;         /* swap axes */
        uint8_t x_swap:1;            /* mirror x */
        uint8_t y_swap:1;            /* mirror y */
        uint8_t bit_endian:1;        /* GP_BIT_ENDIAN */
        uint8_t free_pixels:1;       /* if set gp_pixmap_free() calls free on pixmap->pixels */
} gp_pixmap;

The pixels field points to the image data.

The pixels are stored as a one-dimensional array consisting of byte-aligned lines (i.e. each image line starts at whole byte and ends at whole byte).

The pixels array starts exactly at upper left corner of the image and is stored in horizontal lines (each line contains w pixels and there is h lines). Each line is bytes_per_row bytes long (which equals to w * bpp / 8 rouned up to the whole bytes). The first pixel may actually start at offset bit in the first byte in each line (but only for some subpixmaps for pixel types that are not byte aligned).

The pixel_type enumeration defines in which format and how are pixel data stored in the pixels buffer, i.e. organization and function of the pixel channels.

The optional pointer to gamma tables describes per-channel gamma correction. Unfortunatelly very few parts of the library use it at the moment (this will be fixed in subsequent releases).

The bitfield at the the end of the structure describes image orientation (see below) and a flag that tell if pixels data should be freed, which is usefull for example for subpixmaps.

Rotation

The orientation flags affects the gfx and text drawing functions and blits. If some of the flags is changed the origin and direction of the drawing is changed accordingly. Note that the image pixels are not affected by this at all only the coordinates passed to drawing functions are transformed.

If you don’t need this functionality just don’t touch the flags the as overhead of these transformations is not measurable.

If you really need drawing primitives that do not use the orientation flags, you could use variants with _raw suffix (although this is not recommended).

There are various helper macros for transforming coordinates and sizes in core/GP_Transform.h. And pixmap helper functions to "rotate" the flags clock wise and counter clock wise as well as functions to get the pixmap size when taking into the account the width and height.

#include <core/gp_transform.h>
/* or */
#include <gfxprim.h>

/* Transforms point user coordinates to bitmap coordinates */
GP_TRANSFORM_POINT(pixmap, x, y)

/* Transforms rectangular area coordinates and size */
GP_TRANSFORM_RECT(pixmap, x, y, w, h)

/* Inverse transformation, bitmap coordinates to user coordinates */
GP_RETRANSFORM_POINT(pixmap, x, y)
#include <core/gp_pixmap.h>
/* or */
#include <gfxprim.h>

/*
 * Rotate pixmap flags clock wise.
 */
void gp_pixmap_rotate_cw(gp_pixmap *pixmap);

/*
 * Rotate pixmap flags counter clock wise.
 */
void gp_pixmap_rotate_ccw(gp_pixmap *pixmap);

/*
 * Retruns 1 if rotation flags are equal.
 */
int gp_pixmap_rtation_equal(const gp_pixmap *c1, const gp_pixmap *c2);

/*
 * Sets pixmap rotation flags.
 */
void gp_pixmap_set_rotation(gp_pixmap *dst, int axes_swap,
                            int x_swap, int y_swap);

/*
 * Copies rotation flags.
 */
void gp_pixmap_copy_rotation(const gp_pixmap *src, gp_pixmap *dst);

/*
 * Returns pixmap width and height taking the rotation flags into the account.
 */
gp_size gp_pixmap_w(const gp_pixmap *pixmap);
gp_size gp_pixmap_h(const gp_pixmap *pixmap);

Basic pixmap functions

#include <core/gp_pixmap.h>
/* or */
#include <gfxprim.h>

enum gp_pixmap_init_flags {
        GP_PIXMAP_FREE_PIXELS = 0x01, /* If set the pixmap->pixels is freed on gp_pixmap_free() */
};

gp_pixmap *gp_pixmap_init(gp_pixmap *pixmap, gp_size w, gp_size h,
                          gp_pixel_type type, void *pixels,
                          enum gp_pixmap_init_flags flags);

gp_pixmap *gp_pixmap_from_data(gp_size w, gp_size h,
                               gp_pixel_type type, void *pixels,
                               enum gp_pixmap_init_flags flags);

Initialize given pixmap accordingly to parameters, the rest of pixmap parameters are set to the default values (i.e. rotation flags are all set to zero). Number of bits per pixel and bytes per row are computed from the given pixel type and size.

The pixels pointer can be NULL and can be changed later (the call will not try to allocate the pixel memory automatically).

The function returns a pointer to the initialized pixmap (i.e. the same pointer you passed as second argument).

The gp_pixmap_from_data() is a shorthand for allocating the pixmap structure and calling the gp_pixmap_init().

#include <core/gp_pixmap.h>
/* or */
#include <gfxprim.h>

gp_pixmap *gp_pixmap_alloc(gp_size w, gp_size h, gp_pixel_type type);

The gp_pixmap_alloc() allocates and initializes a pixmap.

The orientation flags are all set to zero, the free_pixels flag is set and the rest of the metadata are calculated accordingly to width, height and pixel_type.The pixels pointer will point to a newly allocated bitmap with appropriate size; the initial contents of the bitmap are undefined.

#include <core/gp_pixmap.h>
/* or */
#include <gfxprim.h>

enum gp_pixmap_copy_flags {
        /*
         * Copy bitmap pixels too. If not set pixels are uninitialized.
         */
        GP_COPY_WITH_PIXELS   = 0x01,
        /*
         * Copy image rotation flags. If not set flags are set to (0, 0, 0).
         */
        GP_COPY_WITH_ROTATION = 0x02,
};

gp_pixmap *gp_pixmap_copy(const gp_pixmap *src, int flags);

The gp_pixmap_copy() allocates and initializes a copy of the pixmap passed as arguments.

The call returns pointer to newly allocated pixmap or in case of malloc() failure NULL.

If GP_COPY_WITH_PIXELS is set, the bitmap contents (src→pixels) are also copied; otherwise the copy will have the same dimensions but undefined contents.

If GP_COPY_WITH_ROTATION is set rotation flags are copied; otherwise rotation flags are set to zero.

The free_pixels flag for the resulting pixmap is set.

#include <core/gp_pixmap.h>
/* or */
#include <gfxprim.h>

void gp_pixmap_free(gp_pixmap *pixmap);

Frees the pixmap memory.

If free_pixels flag is set, the pixels buffer is freed too.

If gamma pointer is not NULL the gp_gamma_release() is called.

Subpixmap

A subpixmap is a pixmap that refers to a rectangular area within another pixmap. Subpixmaps can be used as any other pixmaps (including subpixmap creation).

Warning If you create overlaping subpixmaps the result is undefined.

Calling gp_pixmap_free() on a allocated subpixmap is safe; the bitmap is not freed as it belongs to another pixmap; it will be freed when the parent pixmap is freed (i.e. the free_pixels flag is not set when creating subpixmap).

Caution The subpixmap doesn’t hold a reference to the original pixmap, so once the parent pixmap is freed the subpixmap pixels pointer is not valid anymore.
#include <core/gp_pixmap.h>
/* or */
#include <gfxprim.h>

gp_pixmap *gp_sub_pixmap(const gp_pixmap *pixmap, gp_pixmap *subpixmap,
                          gp_coord x, gp_coord y, gp_size w, gp_size h);

gp_pixmap *gp_sub_pixmap_alloc(const gp_pixmap *pixmap,
                             gp_coord x, gp_coord y, gp_size w, gp_size h);

Creates subpixmap of a pixmap. The rectangular area must fit into the parent pixmap.

The gp_sub_pixmap() function initializes the passed pointer as a subpixmap of a pixmap and returns pointer to the initialized subpixmap (i.e. the same pointer you passed as the subpixmap parameter).

The gp_sub_pixmap_alloc() function allocates gp_pixmap structure and initializes it as a subpixmap. This function may return NULL in case of malloc() failure and the newly created pixmap should be later freed with gp_pixmap_free().

Conversions

#include <core/gp_pixmap.h>
/* or */
#include <gfxprim.h>

gp_pixmap *gp_pixmap_convert_alloc(const gp_pixmap *src,
                                   gp_pixel_type dst_pixel_type);

gp_pixmap *gp_pixmap_convert(const gp_pixmap *src, gp_pixmap *dst);

Converts a pixmap to different pixel type.

This is naive implementation that only multiplies/divides the pixel values.

To get a better result use dithering filters instead.

Misc

#include <core/gp_pixmap.h>
/* or */
#include <gfxprim.h>

void gp_pixmap_print_info(const gp_pixmap *self);

This function prints the content of a gp_pixmap structure, in a readable format, into the stdout.