1 /*****************************************************************************
2 * This file is part of gfxprim library. *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
9 * Gfxprim is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Lesser General Public License for more details. *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
19 * Copyright (C) 2009-2011 Jiri "BlueBear" Dluhos *
20 * <jiri.bluebear.dluhos@gmail.com> *
22 * Copyright (C) 2009-2013 Cyril Hrubis <metan@ucw.cz> *
24 *****************************************************************************/
26 #ifndef CORE_GP_CONTEXT_H
27 #define CORE_GP_CONTEXT_H
32 #include "GP_Common.h"
38 /* This structure holds all information needed for drawing into an image. */
39 typedef struct GP_Context
{
40 uint8_t *pixels
; /* pointer to image pixels */
41 uint8_t bpp
; /* pixel size in bits */
42 uint32_t bytes_per_row
;
43 uint32_t w
; /* width in pixels */
44 uint32_t h
; /* height in pixels */
46 * Row bit offset. The offset is ignored for byte aligned pixels.
47 * Basically it's used for non aligned pixels with combination
53 * Pixel format. See GP_Pixel.gen.h and GP_Pixel.gen.c.
55 enum GP_PixelType pixel_type
;
58 * Pointer to optional Gamma table.
60 * If NULL, the channel values are considered linear.
62 * See GP_GammaCorrection.h.
64 struct GP_Gamma
*gamma
;
67 * Image orientation. Most common is landscape (0, 0, 0),
68 * portrait with normal topleft corner is (1, 0, 0).
70 uint8_t axes_swap
:1; /* swap axes so that x is y and y is x */
71 uint8_t x_swap
:1; /* swap direction on x */
72 uint8_t y_swap
:1; /* swap direction on y */
73 uint8_t bit_endian
:1; /* GP_BIT_ENDIAN */
74 uint8_t free_pixels
:1; /* If set pixels are freed on GP_ContextFree */
77 /* Determines the address of a pixel within the context's image.
78 * Rows and columns are specified in the image's orientation
79 * (i.e. they might not be XY if the image is rotated).
81 #define GP_PIXEL_ADDR(context, x, y) ((context)->pixels \
82 + (y) * (context)->bytes_per_row \
83 + ((x) * (context)->bpp) / 8)
85 #define GP_CALC_ROW_SIZE(pixel_type, width) \
86 ((GP_PixelSize(pixel_type) * width) / 8 + \
87 !!((GP_PixelSize(pixel_type) * width) % 8))
89 /* Performs a series of sanity checks on context, aborting if any fails. */
90 #define GP_CHECK_CONTEXT(context) do { \
91 GP_CHECK(context, "NULL passed as context"); \
92 GP_CHECK(context->pixels, "invalid context: NULL image pointer"); \
93 GP_CHECK(context->bpp <= 32, "invalid context: unsupported bits-per-pixel count"); \
94 GP_CHECK(context->w > 0 && context->h > 0, "invalid context: invalid image size"); \
98 * Is true, when pixel is clipped out of context.
100 #define GP_PIXEL_IS_CLIPPED(context, x, y) \
101 ((x) < 0 || x >= (typeof(x)) context->w \
102 || (y) < 0 || y >= (typeof(y)) context->h) \
107 * The context consists of two parts, the GP_Context structure and pixels array.
109 * The rotation flags are set to (0, 0, 0).
111 GP_Context
*GP_ContextAlloc(GP_Size w
, GP_Size h
, GP_PixelType type
);
116 * If context->free_pixels, also free pixel data.
118 void GP_ContextFree(GP_Context
*context
);
121 * Initalize context, pixels pointer is not dereferenced so it's safe to pass
122 * NULL there and allocate it later with size context->bpr * context->h.
124 * The returned pointer is the pointer you passed as first argument.
126 GP_Context
*GP_ContextInit(GP_Context
*context
, GP_Size w
, GP_Size h
,
127 GP_PixelType type
, void *pixels
);
130 * Resizes context->pixels array and changes metadata to match the new size.
132 * Returns non-zero on failure (malloc() has failed).
134 * This call only resizes the pixel array. The pixel values, after resizing,
135 * are __UNINITALIZED__ use resampling filters to resize image data.
137 int GP_ContextResize(GP_Context
*context
, GP_Size w
, GP_Size h
);
139 enum GP_ContextCopyFlags
{
141 * Copy bitmap pixels too. If not set pixels are uninitalized.
143 GP_COPY_WITH_PIXELS
= 0x01,
145 * Copy image rotation flags. If not set flags are set to (0, 0, 0).
147 GP_COPY_WITH_ROTATION
= 0x02,
151 * Allocates a contex with exactly same values as source context.
153 GP_Context
*GP_ContextCopy(const GP_Context
*src
, int flags
);
156 * Initalize subcontext. The returned pointer points to passed subcontext.
158 GP_Context
*GP_SubContext(const GP_Context
*context
, GP_Context
*subcontext
,
159 GP_Coord x
, GP_Coord y
, GP_Size w
, GP_Size h
);
162 * Allocate and initalize subcontext.
164 * The free_pixels flag is set to 0 upon subcontext initalization so the
165 * GP_ContextFree() would not call free() upon the subcontext->pixels pointer.
167 GP_Context
*GP_SubContextAlloc(const GP_Context
*context
,
168 GP_Coord x
, GP_Coord y
, GP_Size w
, GP_Size h
);
171 * Converts context to a different pixel type.
172 * Returns a newly allocated context.
174 * This is naive implementation that doesn't do any ditherings or error
177 GP_Context
*GP_ContextConvertAlloc(const GP_Context
*src
,
178 GP_PixelType dst_pixel_type
);
181 * Converts context to a different pixel type.
183 * This is naive implementation that doesn't do any ditherings or error
186 GP_Context
*GP_ContextConvert(const GP_Context
*src
, GP_Context
*dst
);
189 * Prints context information into stdout.
191 void GP_ContextPrintInfo(const GP_Context
*self
);
194 * Rotates context flags clock wise.
196 void GP_ContextRotateCW(GP_Context
*context
);
199 * Rotates context flags counter clock wise.
201 void GP_ContextRotateCCW(GP_Context
*context
);
204 * Retruns 1 if rotation flags are equal.
206 static inline int GP_ContextRotationEqual(const GP_Context
*c1
,
207 const GP_Context
*c2
)
209 return c1
->axes_swap
== c2
->axes_swap
&&
210 c1
->x_swap
== c2
->x_swap
&&
211 c1
->y_swap
== c2
->y_swap
;
215 * Sets rotation flags.
217 static inline void GP_ContextSetRotation(GP_Context
*dst
, int axes_swap
,
218 int x_swap
, int y_swap
)
220 dst
->axes_swap
= axes_swap
;
221 dst
->x_swap
= x_swap
;
222 dst
->y_swap
= y_swap
;
226 * Copies rotation flags.
228 static inline void GP_ContextCopyRotation(const GP_Context
*src
,
231 dst
->axes_swap
= src
->axes_swap
;
232 dst
->x_swap
= src
->x_swap
;
233 dst
->y_swap
= src
->y_swap
;
237 * Returns context width and height taking the rotation flags into a account.
239 static inline GP_Size
GP_ContextW(const GP_Context
*context
)
241 if (context
->axes_swap
)
247 static inline GP_Size
GP_ContextH(const GP_Context
*context
)
249 if (context
->axes_swap
)
256 * Compare two contexts. Returns true only if all of types, sizes and
257 * bitmap data match. Takes transformations into account.
259 * For now ignores gamma tables.
261 * Currently rather slow (getpixel).
262 * TODO: speed up for same rotation and same bit-offset data (per-row memcpy).
265 int GP_ContextEqual(const GP_Context
*ctx1
, const GP_Context
*ctx2
);
267 #endif /* CORE_GP_CONTEXT_H */