Drawing Pixmap
---------------

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

Data Structure
~~~~~~~~~~~~~~

[source,c]
-------------------------------------------------------------------------------
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
<<Sub_Pixmap,subpixmaps>> for pixel types that are not byte aligned).

The link:pixels.html[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 link:gamma.html[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 <<Sub_Pixmap, 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.

[source,c]
-------------------------------------------------------------------------------
#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)
-------------------------------------------------------------------------------

[source,c]
------------------------------------------------------------------------------
#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
~~~~~~~~~~~~~~~~~~~~~~~

[source,c]
-------------------------------------------------------------------------------
#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()'.

[source,c]
-------------------------------------------------------------------------------
#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.

[source,c]
-------------------------------------------------------------------------------
#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.

[[pixmap_free]]
[source,c]
-------------------------------------------------------------------------------
#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.

[[Sub_Pixmap]]
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.

[source,c]
-------------------------------------------------------------------------------
#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
~~~~~~~~~~~

[source,c]
-------------------------------------------------------------------------------
#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 link:filters.html#Dithering[dithering filters] instead.

Misc
~~~~

[source,c]
-------------------------------------------------------------------------------
#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.

