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-2011 Cyril Hrubis <metan@ucw.cz> *
24 *****************************************************************************/
31 GP_Context
*GP_ContextCopy(const GP_Context
*src
, int flag
)
39 new = malloc(sizeof(GP_Context
));
40 pixels
= malloc(src
->bytes_per_row
* src
->h
);
42 if (pixels
== NULL
|| new == NULL
) {
51 memcpy(pixels
, src
->pixels
, src
->bytes_per_row
* src
->h
);
54 new->bytes_per_row
= src
->bytes_per_row
;
60 new->pixel_type
= src
->pixel_type
;
61 new->bit_endian
= src
->bit_endian
;
63 /* rotation and mirroring */
64 new->axes_swap
= src
->axes_swap
;
65 new->y_swap
= src
->y_swap
;
66 new->x_swap
= src
->x_swap
;
73 static uint32_t get_bpr(uint32_t bpp
, uint32_t w
)
75 return (bpp
* w
) / 8 + !!((bpp
* w
) % 8);
78 GP_Context
*GP_ContextAlloc(GP_Size w
, GP_Size h
, GP_PixelType type
)
80 GP_CHECK_VALID_PIXELTYPE(type
);
81 GP_Context
*context
= malloc(sizeof(GP_Context
));
82 uint32_t bpp
= GP_PixelSize(type
);
83 uint32_t bpr
= get_bpr(bpp
, w
);
86 pixels
= malloc(bpr
* h
);
88 if (pixels
== NULL
|| context
== NULL
) {
94 context
->pixels
= pixels
;
96 context
->bytes_per_row
= bpr
;
102 context
->pixel_type
= type
;
103 #warning Hmm, bit endianity... Why isn't this settled by different pixel types?
104 context->bit_endian = 0;
106 /* rotation and mirroring */
107 context->axes_swap = 0;
111 context->free_pixels = 1;
116 int GP_ContextResize(GP_Context *context, GP_Size w, GP_Size h)
118 uint32_t bpr = get_bpr(context->bpp, w);
121 pixels = realloc(context->pixels, bpr * h);
128 context->bytes_per_row = bpr;
129 context->pixels = pixels;
134 void GP_ContextInit(GP_Context *context, GP_Size w, GP_Size h,
135 GP_PixelType type, void *pixels)
137 uint32_t bpp = GP_PixelSize(type);
138 uint32_t bpr = get_bpr(bpp, w);
140 context->pixels = pixels;
142 context->bytes_per_row = bpr;
148 context->pixel_type = type;
149 context->bit_endian = 0;
151 /* rotation and mirroring */
152 context->axes_swap = 0;
156 context->free_pixels = 0;
159 GP_Context *GP_ContextConvert(const GP_Context *src,
160 GP_PixelType dst_pixel_type)
162 int w = GP_ContextW(src);
163 int h = GP_ContextH(src);
164 GP_Context *ret = GP_ContextAlloc(w, h, dst_pixel_type);
168 GP_Blit(src, 0, 0, w, h, ret, 0, 0);
172 void GP_ContextFree(GP_Context *context)
177 if (context->free_pixels)
178 free(context->pixels);
183 GP_Context *GP_ContextSubContext(GP_Context *context, GP_Context *subcontext,
184 GP_Coord x, GP_Coord y, GP_Size w, GP_Size h)
186 GP_CHECK(context, "NULL context");
188 GP_TRANSFORM_RECT(context, x, y, w, h);
190 GP_CHECK(context->w >= x + w, "Subcontext w out of original context.");
191 GP_CHECK(context->h >= y + h, "Subcontext h out of original context.");
193 GP_Context *ret = subcontext;
196 ret = malloc(sizeof(GP_Context));
202 ret->bpp = context->bpp;
203 ret->bytes_per_row = context->bytes_per_row;
204 ret->offset = (context->offset +
205 GP_PixelAddrOffset(x, context->pixel_type)) % 8;
210 ret->pixel_type = context->pixel_type;
211 ret->bit_endian = context->bit_endian;
213 /* rotation and mirroring */
214 ret->axes_swap = context->axes_swap;
215 ret->y_swap = context->y_swap;
216 ret->x_swap = context->x_swap;
218 ret->pixels = GP_PIXEL_ADDR(context, x, y);
220 ret->free_pixels = 0;
226 * The context rotations consists of two cyclic permutation groups that are
229 * The flags change as follows:
233 * x_swap y_swap axes_swap
239 * And mirrored group:
241 * x_swap y_swap axes_swap
248 void GP_ContextFlagsRotateCW(GP_Context *context)
250 context->axes_swap = !context->axes_swap;
252 if (!context->x_swap && !context->y_swap) {
257 if (context->x_swap && !context->y_swap) {
262 if (context->x_swap && context->y_swap) {
270 void GP_ContextFlagsRotateCCW(GP_Context *context)
272 context->axes_swap = !context->axes_swap;
274 if (!context->x_swap && !context->y_swap) {
279 if (context->x_swap && !context->y_swap) {
284 if (context->x_swap && context->y_swap) {