NetSurf
bitmap.c
Go to the documentation of this file.
1/*
2 * Copyright 2010 Ole Loots <ole@monochrom.net>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <sys/types.h>
20#include <string.h>
21#include <assert.h>
22#include <stdlib.h>
23
24#include "netsurf/inttypes.h"
25#include "utils/nsoption.h"
26#include "utils/log.h"
27#include "netsurf/bitmap.h"
28#include "netsurf/mouse.h"
29
30#include "atari/bitmap.h"
31#include "atari/plot/plot.h"
32
33
34/*
35 * param bpp bits per pixel,
36 * param w width of the buffer (in pixel)
37 * param h height of the buffer (in pixel)
38 * param flags MFDB_FLAG_NOALLOC | MFDB_FLAG_ZEROMEM | MFDB_FLAG_STAND
39 * returns size of the fd_addr buffer required or allocated
40*/
41int init_mfdb(int bpp, int w, int h, uint32_t flags, MFDB * out )
42{
43 int dststride;
44 dststride = MFDB_STRIDE( w );
45 int size = MFDB_SIZE( bpp, dststride, h );
46 if( bpp > 0 ) {
47 if( (flags & MFDB_FLAG_NOALLOC) == 0 ) {
48 out->fd_addr = malloc( size );
49 if( out->fd_addr == NULL ){
50 return( 0 );
51 }
52 if( (flags & MFDB_FLAG_ZEROMEM) ){
53 memset( out->fd_addr, 0, size );
54 }
55 }
56 out->fd_stand = (flags & MFDB_FLAG_STAND) ? 1 : 0;
57 out->fd_nplanes = (short)bpp;
58 out->fd_r1 = out->fd_r2 = out->fd_r3 = 0;
59 } else {
60 memset( out, 0, sizeof(MFDB) );
61 }
62 out->fd_w = dststride;
63 out->fd_h = h;
64 out->fd_wdwidth = dststride >> 4;
65 return( size );
66}
67
68
69/**
70 * Create a bitmap.
71 *
72 * \param w width of image in pixels
73 * \param h height of image in pixels
74 * \param bpp number of BYTES per pixel
75 * \param rowstride linewidth in bytes
76 * \param state a flag word indicating the initial state
77 * \param pixdata NULL or an memory address to use as the bitmap pixdata
78 * \return an opaque struct bitmap, or NULL on memory exhaustion
79 */
80static void *atari_bitmap_create_ex( int w, int h, short bpp, int rowstride, enum gui_bitmap_flags flags, void * pixdata )
81{
82 struct bitmap * bitmap;
83
84 NSLOG(netsurf, INFO,
85 "width %d (rowstride: %d, bpp: %d), height %d, flags %u", w,
86 rowstride, bpp, h, (unsigned)flags);
87
88 if( rowstride == 0) {
89 rowstride = bpp * w;
90 }
91
92 assert( rowstride >= (w * bpp) );
93 bitmap = calloc(1 , sizeof(struct bitmap) );
94 if (bitmap) {
95 if( pixdata == NULL) {
96 bitmap->pixdata = calloc(1, (rowstride * h)+128);
97 }
98 else {
100 }
101
102 if (bitmap->pixdata != NULL) {
103 bitmap->width = w;
104 bitmap->height = h;
105 bitmap->opaque = (flags & BITMAP_OPAQUE) ? true : false;
106 bitmap->bpp = bpp;
107 bitmap->resized = NULL;
109 } else {
110 free(bitmap);
111 bitmap=NULL;
112 NSLOG(netsurf, INFO, "Out of memory!");
113 }
114 }
115 NSLOG(netsurf, INFO, "bitmap %p", bitmap);
116 return bitmap;
117}
118
119
120/* exported interface documented in atari/bitmap.h */
121void *atari_bitmap_create(int w, int h, enum gui_bitmap_flags flags)
122{
123 return atari_bitmap_create_ex( w, h, NS_BMP_DEFAULT_BPP, w * NS_BMP_DEFAULT_BPP, flags, NULL );
124}
125
126/**
127 * The bitmap image has changed, so flush any persistant cache.
128 *
129 * \param bitmap a bitmap, as returned by bitmap_create()
130 */
131static void bitmap_modified(void *bitmap)
132{
133 struct bitmap *bm = bitmap;
134 if( bm->resized != NULL ) {
136 bm->resized = NULL;
137 }
138 if( bm->converted ){
139 if( bm->pixdata != bm->native.fd_addr ){
140 free( bm->native.fd_addr );
141 }
142 bm->native.fd_addr = NULL;
143 bm->converted = false;
144 }
145}
146
147
148/* exported interface documented in atari/bitmap.h */
149void *atari_bitmap_realloc( int w, int h, short bpp, int rowstride, unsigned int state, void * bmp )
150{
151 struct bitmap * bitmap = bmp;
152 int newsize = rowstride * h;
153
154 if( bitmap == NULL ) {
155 return( NULL );
156 }
157
158 assert( bitmap->pixdata != NULL );
159 int oldsize = bitmap->rowstride * bitmap->height;
160 bool doalloc = (state & BITMAP_GROW) ? (newsize > oldsize) : (newsize != oldsize);
161 if( newsize > oldsize )
162 assert( doalloc == true );
163 if( doalloc ) {
164 // TODO: set red band to a specific value and check the red band
165 // on bitmap_destroy()
166 bitmap->pixdata = realloc( bitmap->pixdata, newsize + 128 );
167 if( bitmap->pixdata == NULL )
168 return( NULL );
169 }
170
171 if( state & BITMAP_CLEAR ){
172 memset( bitmap->pixdata, 0x00, newsize + 128 );
173 }
174
175 bitmap->width = w;
176 bitmap->height = h;
177 bitmap->bpp = bpp;
178 bitmap->resized = NULL;
181 return( bitmap );
182}
183
184
185/**
186 * Return a pointer to the pixel data in a bitmap.
187 *
188 * \param bitmap a bitmap, as returned by bitmap_create()
189 * \return pointer to the pixel buffer
190 *
191 * The pixel data is packed as BITMAP_FORMAT, possibly with padding at the end
192 * of rows. The width of a row in bytes is given by bitmap_get_rowstride().
193 */
194static unsigned char *bitmap_get_buffer(void *bitmap)
195{
196 struct bitmap *bm = bitmap;
197
198 if (bitmap == NULL) {
199 NSLOG(netsurf, INFO, "NULL bitmap!");
200 return NULL;
201 }
202
203 return bm->pixdata;
204}
205
206
207/* exported interface documented in atari/bitmap.h */
209{
210 struct bitmap * bm = bitmap;
211 if( bm == NULL )
212 return 0;
213 return( bm->rowstride * bm->height );
214}
215
216
217/* exported interface documented in atari/bitmap.h */
219{
220 struct bitmap *bm = bitmap;
221
222 if (bitmap == NULL) {
223 NSLOG(netsurf, INFO, "NULL bitmap!");
224 return 0;
225 }
226 return bm->rowstride;
227}
228
229
230/* exported interface documented in atari/bitmap.h */
232{
233 struct bitmap *bm = bitmap;
234
235 if (bitmap == NULL) {
236 NSLOG(netsurf, INFO, "NULL bitmap!");
237 return;
238 }
239
240 if( bm->resized != NULL ) {
242 }
243 if( bm->converted && ( bm->native.fd_addr != bm->pixdata ) ) {
244 free( bm->native.fd_addr );
245 }
246 free(bm->pixdata);
247 free(bm);
248}
249
250
251/**
252 * Sets whether a bitmap should be plotted opaque
253 *
254 * \param bitmap a bitmap, as returned by bitmap_create()
255 * \param opaque whether the bitmap should be plotted opaque
256 */
257static void bitmap_set_opaque(void *bitmap, bool opaque)
258{
259 struct bitmap *bm = bitmap;
260
261 if (bitmap == NULL) {
262 NSLOG(netsurf, INFO, "NULL bitmap!");
263 return;
264 }
265
266 NSLOG(netsurf, INFO, "setting bitmap %p to %s", bm,
267 opaque ? "opaque" : "transparent");
268 bm->opaque = opaque;
269}
270
271
272/* exported interface documented in atari/bitmap.h */
274{
275 struct bitmap *bm = bitmap;
276
277 if (bitmap == NULL) {
278 NSLOG(netsurf, INFO, "NULL bitmap!");
279 return false;
280 }
281
282 return bm->opaque;
283}
284
285
286/* exported interface documented in atari/bitmap.h */
288{
289 struct bitmap *bm = bitmap;
290
291 if (bitmap == NULL) {
292 NSLOG(netsurf, INFO, "NULL bitmap!");
293 return 0;
294 }
295
296 return(bm->width);
297}
298
299
300/* exported interface documented in atari/bitmap.h */
302{
303 struct bitmap *bm = bitmap;
304
305 if (bitmap == NULL) {
306 NSLOG(netsurf, INFO, "NULL bitmap!");
307 return 0;
308 }
309 return(bm->height);
310}
311
312/* exported interface documented in atari/bitmap.h */
313bool atari_bitmap_resize(struct bitmap *img, HermesHandle hermes_h,
314 HermesFormat *fmt, int nw, int nh)
315{
316 enum gui_bitmap_flags flags = 0;
317 short bpp = img->bpp;
318 int stride = atari_bitmap_get_rowstride( img );
319 int err;
320
321 if( img->resized != NULL ) {
322 if( img->resized->width != nw || img->resized->height != nh ) {
324 img->resized = NULL;
325 } else {
326 /* the bitmap is already resized */
327 return(true);
328 }
329 }
330
331 /* allocate the mem for resized bitmap */
332 if (img->opaque == true) {
333 flags |= BITMAP_OPAQUE;
334 }
335 img->resized = atari_bitmap_create_ex( nw, nh, bpp, nw*bpp, flags, NULL );
336 if( img->resized == NULL ) {
337 printf("W: %d, H: %d, bpp: %d\n", nw, nh, bpp);
338 assert(img->resized);
339 return(false);
340 }
341
342 /* allocate an converter, only for resizing */
343 err = Hermes_ConverterRequest( hermes_h,
344 fmt,
345 fmt
346 );
347 if( err == 0 ) {
348 return(false);
349 }
350
351 err = Hermes_ConverterCopy( hermes_h,
352 img->pixdata,
353 0, /* x src coord of top left in pixel coords */
354 0, /* y src coord of top left in pixel coords */
357 stride, /* stride as bytes */
358 img->resized->pixdata,
359 0, /* x dst coord of top left in pixel coords */
360 0, /* y dst coord of top left in pixel coords */
361 nw, nh,
362 atari_bitmap_get_rowstride(img->resized) /* stride as bytes */
363 );
364 if( err == 0 ) {
366 img->resized = NULL;
367 return(false);
368 }
369
370 return(true);
371}
372
374{
376}
377
380 .destroy = atari_bitmap_destroy,
381 .set_opaque = bitmap_set_opaque,
382 .get_opaque = atari_bitmap_get_opaque,
383 .get_buffer = bitmap_get_buffer,
384 .get_rowstride = atari_bitmap_get_rowstride,
385 .get_width = atari_bitmap_get_width,
386 .get_height = atari_bitmap_get_height,
387 .modified = bitmap_modified,
388 .render = bitmap_render,
389};
390
392
393/*
394 * Local Variables:
395 * c-basic-offset:8
396 * End:
397 */
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_NOT_IMPLEMENTED
Functionality is not implemented.
Definition: errors.h:61
bool atari_bitmap_resize(struct bitmap *img, HermesHandle hermes_h, HermesFormat *fmt, int nw, int nh)
Definition: bitmap.c:313
static void * atari_bitmap_create_ex(int w, int h, short bpp, int rowstride, enum gui_bitmap_flags flags, void *pixdata)
Create a bitmap.
Definition: bitmap.c:80
static struct gui_bitmap_table bitmap_table
Definition: bitmap.c:378
static void bitmap_modified(void *bitmap)
The bitmap image has changed, so flush any persistant cache.
Definition: bitmap.c:131
size_t atari_bitmap_buffer_size(void *bitmap)
Definition: bitmap.c:208
static nserror bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content)
Definition: bitmap.c:373
size_t atari_bitmap_get_rowstride(void *bitmap)
Find the width of a pixel row in bytes.
Definition: bitmap.c:218
bool atari_bitmap_get_opaque(void *bitmap)
Gets whether a bitmap should be plotted opaque.
Definition: bitmap.c:273
static unsigned char * bitmap_get_buffer(void *bitmap)
Return a pointer to the pixel data in a bitmap.
Definition: bitmap.c:194
void atari_bitmap_destroy(void *bitmap)
Free a bitmap.
Definition: bitmap.c:231
static void bitmap_set_opaque(void *bitmap, bool opaque)
Sets whether a bitmap should be plotted opaque.
Definition: bitmap.c:257
void * atari_bitmap_create(int w, int h, enum gui_bitmap_flags flags)
Create a bitmap.
Definition: bitmap.c:121
struct gui_bitmap_table * atari_bitmap_table
Definition: bitmap.c:391
int init_mfdb(int bpp, int w, int h, uint32_t flags, MFDB *out)
setup an MFDB struct and allocate memory for it when it is needed.
Definition: bitmap.c:41
int atari_bitmap_get_height(void *bitmap)
Get bitmap height.
Definition: bitmap.c:301
int atari_bitmap_get_width(void *bitmap)
Get bitmap width.
Definition: bitmap.c:287
void * atari_bitmap_realloc(int w, int h, short bpp, int rowstride, unsigned int state, void *bmp)
Definition: bitmap.c:149
Atari bitmap handling implementation.
#define MFDB_SIZE(bpp, stride, h)
Calculate size of an mfdb,.
Definition: bitmap.h:55
#define MFDB_FLAG_ZEROMEM
Definition: bitmap.h:34
#define MFDB_FLAG_STAND
Definition: bitmap.h:33
#define MFDB_FLAG_NOALLOC
Definition: bitmap.h:35
#define NS_BMP_DEFAULT_BPP
Definition: bitmap.h:30
#define BITMAP_GROW
Definition: bitmap.h:38
#define MFDB_STRIDE(w)
Calculates MFDB compatible rowstride (in number of bits)
Definition: bitmap.h:45
Generic bitmap handling interface.
gui_bitmap_flags
Bitmap creation flags.
Definition: bitmap.h:36
@ BITMAP_CLEAR
memory should be wiped to 0
Definition: bitmap.h:39
@ BITMAP_OPAQUE
image is opaque
Definition: bitmap.h:38
Core mouse and pointer states.
Netsurf additional integer type formatting macros.
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
Interface to utility string handling.
RISC OS wimp toolkit bitmap.
Definition: bitmap.c:68
int native
Definition: bitmap.c:75
int width
width of bitmap
Definition: bitmap.c:69
struct bitmap * resized
Definition: bitmap.h:66
int height
height of bitmap
Definition: bitmap.c:70
bool opaque
Whether the bitmap is opaque.
Definition: bitmap.c:74
UBYTE * pixdata
Definition: bitmap.c:71
short bpp
Definition: bitmap.h:64
size_t rowstride
Definition: bitmap.h:65
bool converted
Definition: bitmap.h:68
Content which corresponds to a single URL.
Bitmap operations.
Definition: bitmap.h:125
void *(* create)(int width, int height, enum gui_bitmap_flags flags)
Create a new bitmap.
Definition: bitmap.h:136
High-level cache handle.
Definition: hlcache.c:66
Option reading and saving interface.
static nserror bitmap(const struct redraw_context *ctx, struct bitmap *bitmap, int x, int y, int width, int height, colour bg, bitmap_flags_t flags)
Plot a bitmap.
Definition: plot.c:857