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 */
41 int 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  */
80 static 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 {
99  bitmap->pixdata = pixdata;
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;
108  bitmap->rowstride = rowstride;
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 */
121 void *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  */
131 static 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 */
149 void *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;
179  bitmap->rowstride = rowstride;
180  bitmap_modified( bitmap );
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  */
194 static 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  */
257 static 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 /**
273  * Tests whether a bitmap has an opaque alpha channel
274  *
275  * \param bitmap a bitmap, as returned by bitmap_create()
276  * \return whether the bitmap is opaque
277  */
278 static bool bitmap_test_opaque(void *bitmap)
279 {
280  int tst;
281  struct bitmap *bm = bitmap;
282 
283  if (bitmap == NULL) {
284  NSLOG(netsurf, INFO, "NULL bitmap!");
285  return false;
286  }
287 
288  if( nsoption_int(atari_transparency) == 0 ){
289  return( true );
290  }
291 
292  tst = bm->width * bm->height;
293 
294  while (tst-- > 0) {
295  if (bm->pixdata[(tst << 2) + 3] != 0xff) {
296  NSLOG(netsurf, INFO,
297  "bitmap %p has transparency", bm);
298  return false;
299  }
300  }
301  NSLOG(netsurf, INFO, "bitmap %p is opaque", bm);
302  return true;
303 }
304 
305 
306 /* exported interface documented in atari/bitmap.h */
308 {
309  struct bitmap *bm = bitmap;
310 
311  if (bitmap == NULL) {
312  NSLOG(netsurf, INFO, "NULL bitmap!");
313  return false;
314  }
315 
316  return bm->opaque;
317 }
318 
319 
320 /* exported interface documented in atari/bitmap.h */
322 {
323  struct bitmap *bm = bitmap;
324 
325  if (bitmap == NULL) {
326  NSLOG(netsurf, INFO, "NULL bitmap!");
327  return 0;
328  }
329 
330  return(bm->width);
331 }
332 
333 
334 /* exported interface documented in atari/bitmap.h */
336 {
337  struct bitmap *bm = bitmap;
338 
339  if (bitmap == NULL) {
340  NSLOG(netsurf, INFO, "NULL bitmap!");
341  return 0;
342  }
343  return(bm->height);
344 }
345 
346 /* exported interface documented in atari/bitmap.h */
347 bool atari_bitmap_resize(struct bitmap *img, HermesHandle hermes_h,
348  HermesFormat *fmt, int nw, int nh)
349 {
350  enum gui_bitmap_flags flags = 0;
351  short bpp = img->bpp;
352  int stride = atari_bitmap_get_rowstride( img );
353  int err;
354 
355  if( img->resized != NULL ) {
356  if( img->resized->width != nw || img->resized->height != nh ) {
358  img->resized = NULL;
359  } else {
360  /* the bitmap is already resized */
361  return(true);
362  }
363  }
364 
365  /* allocate the mem for resized bitmap */
366  if (img->opaque == true) {
367  flags |= BITMAP_OPAQUE;
368  }
369  img->resized = atari_bitmap_create_ex( nw, nh, bpp, nw*bpp, flags, NULL );
370  if( img->resized == NULL ) {
371  printf("W: %d, H: %d, bpp: %d\n", nw, nh, bpp);
372  assert(img->resized);
373  return(false);
374  }
375 
376  /* allocate an converter, only for resizing */
377  err = Hermes_ConverterRequest( hermes_h,
378  fmt,
379  fmt
380  );
381  if( err == 0 ) {
382  return(false);
383  }
384 
385  err = Hermes_ConverterCopy( hermes_h,
386  img->pixdata,
387  0, /* x src coord of top left in pixel coords */
388  0, /* y src coord of top left in pixel coords */
389  atari_bitmap_get_width( img ),
391  stride, /* stride as bytes */
392  img->resized->pixdata,
393  0, /* x dst coord of top left in pixel coords */
394  0, /* y dst coord of top left in pixel coords */
395  nw, nh,
396  atari_bitmap_get_rowstride(img->resized) /* stride as bytes */
397  );
398  if( err == 0 ) {
400  img->resized = NULL;
401  return(false);
402  }
403 
404  return(true);
405 }
406 
408 {
410 }
411 
414  .destroy = atari_bitmap_destroy,
415  .set_opaque = bitmap_set_opaque,
416  .get_opaque = atari_bitmap_get_opaque,
417  .test_opaque = bitmap_test_opaque,
418  .get_buffer = bitmap_get_buffer,
419  .get_rowstride = atari_bitmap_get_rowstride,
420  .get_width = atari_bitmap_get_width,
421  .get_height = atari_bitmap_get_height,
422  .modified = bitmap_modified,
423  .render = bitmap_render,
424 };
425 
427 
428 /*
429  * Local Variables:
430  * c-basic-offset:8
431  * End:
432  */
size_t atari_bitmap_buffer_size(void *bitmap)
Definition: bitmap.c:208
bool converted
Definition: bitmap.h:68
struct bitmap * resized
Definition: bitmap.h:66
Interface to utility string handling.
static struct gui_bitmap_table bitmap_table
Definition: bitmap.c:412
Functionality is not implemented.
Definition: errors.h:61
size_t rowstride
Definition: bitmap.h:65
void atari_bitmap_destroy(void *bitmap)
Free a bitmap.
Definition: bitmap.c:231
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
Core mouse and pointer states.
#define MFDB_FLAG_NOALLOC
Definition: bitmap.h:35
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
#define MFDB_FLAG_ZEROMEM
Definition: bitmap.h:34
#define nsoption_int(OPTION)
Get the value of an integer option.
Definition: nsoption.h:279
Option reading and saving interface.
static bool bitmap_test_opaque(void *bitmap)
Tests whether a bitmap has an opaque alpha channel.
Definition: bitmap.c:278
nserror
Enumeration of error codes.
Definition: errors.h:29
int height
height of bitmap
Definition: bitmap.c:70
image is opaque
Definition: bitmap.h:60
High-level cache handle.
Definition: hlcache.c:65
int atari_bitmap_get_width(void *bitmap)
Get bitmap width.
Definition: bitmap.c:321
Content which corresponds to a single URL.
bool atari_bitmap_get_opaque(void *bitmap)
Gets whether a bitmap should be plotted opaque.
Definition: bitmap.c:307
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 void bitmap_modified(void *bitmap)
The bitmap image has changed, so flush any persistant cache.
Definition: bitmap.c:131
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:115
#define NS_BMP_DEFAULT_BPP
Definition: bitmap.h:30
#define MFDB_STRIDE(w)
Calculates MFDB compatible rowstride (in number of bits)
Definition: bitmap.h:45
RISC OS wimp toolkit bitmap.
Definition: bitmap.c:68
int atari_bitmap_get_height(void *bitmap)
Get bitmap height.
Definition: bitmap.c:335
#define BITMAP_GROW
Definition: bitmap.h:38
static nserror bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content)
Definition: bitmap.c:407
size_t atari_bitmap_get_rowstride(void *bitmap)
Find the width of a pixel row in bytes.
Definition: bitmap.c:218
gui_bitmap_flags
Bitmap creation flags.
Definition: bitmap.h:58
Bitmap operations.
Definition: bitmap.h:71
memory should be wiped to 0
Definition: bitmap.h:61
struct gui_bitmap_table * atari_bitmap_table
Definition: bitmap.c:426
#define MFDB_FLAG_STAND
Definition: bitmap.h:33
bool opaque
Whether the bitmap is opaque.
Definition: bitmap.c:74
Netsurf additional integer type formatting macros.
UBYTE * pixdata
Definition: bitmap.c:71
int width
width of bitmap
Definition: bitmap.c:69
#define MFDB_SIZE(bpp, stride, h)
Calculate size of an mfdb,.
Definition: bitmap.h:55
Generic bitmap handling interface.
static unsigned char * bitmap_get_buffer(void *bitmap)
Return a pointer to the pixel data in a bitmap.
Definition: bitmap.c:194
short bpp
Definition: bitmap.h:64
bool atari_bitmap_resize(struct bitmap *img, HermesHandle hermes_h, HermesFormat *fmt, int nw, int nh)
Definition: bitmap.c:347
void * atari_bitmap_create(int w, int h, enum gui_bitmap_flags flags)
Create a bitmap.
Definition: bitmap.c:121
void * atari_bitmap_realloc(int w, int h, short bpp, int rowstride, unsigned int state, void *bmp)
Definition: bitmap.c:149
void *(* create)(int width, int height, enum gui_bitmap_flags flags)
Create a new bitmap.
Definition: bitmap.h:82
int native
Definition: bitmap.c:75
Atari bitmap handling implementation.
static void bitmap_set_opaque(void *bitmap, bool opaque)
Sets whether a bitmap should be plotted opaque.
Definition: bitmap.c:257