NetSurf
bitmap.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008, 2009, 2012, 2016 Chris Young <chris@unsatisfactorysoftware.co.uk>
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 "amiga/os3support.h"
20 
21 #include <stdlib.h>
22 #include <string.h>
23 #include <proto/exec.h>
24 #ifdef __amigaos4__
25 #include <graphics/blitattr.h>
26 #include <graphics/composite.h>
27 #endif
28 #include <graphics/gfxbase.h>
29 #include <proto/datatypes.h>
30 #include <datatypes/pictureclass.h>
31 #include <proto/dos.h>
32 #include <proto/intuition.h>
33 #include <proto/utility.h>
34 
35 #include <proto/guigfx.h>
36 #include <guigfx/guigfx.h>
37 #include <render/render.h>
38 #ifndef __amigaos4__
39 #include <inline/guigfx.h>
40 #endif
41 
42 #ifdef __amigaos4__
43 #include <exec/extmem.h>
44 #include <sys/param.h>
45 #endif
46 #include "assert.h"
47 
48 #include "utils/log.h"
49 #include "utils/nsoption.h"
50 #include "utils/nsurl.h"
51 #include "utils/messages.h"
52 #include "netsurf/bitmap.h"
53 #include "netsurf/content.h"
54 
55 #include "amiga/gui.h"
56 #include "amiga/bitmap.h"
57 #include "amiga/plotters.h"
58 #include "amiga/memory.h"
59 #include "amiga/misc.h"
60 #include "amiga/rtg.h"
61 #include "amiga/schedule.h"
62 
63 // disable use of "triangle mode" for scaling
64 #ifdef AMI_NS_TRIANGLE_SCALING
65 #undef AMI_NS_TRIANGLE_SCALING
66 #endif
67 
68 struct bitmap {
69  int width;
70  int height;
71  UBYTE *pixdata;
72  struct ExtMemIFace *iextmem;
74  bool opaque;
75  int native;
76  struct BitMap *nativebm;
79  PLANEPTR native_mask;
80  Object *dto;
81  APTR drawhandle;
82  struct nsurl *url; /* temporary storage space */
83  char *title; /* temporary storage space */
84  ULONG *icondata; /* for appicons */
85 };
86 
87 enum {
91 };
92 
93 struct vertex {
94  float x, y;
95  float s, t, w;
96 };
97 
98 #define VTX(I,X,Y,S,T) vtx[I].x = X; vtx[I].y = Y; vtx[I].s = S; vtx[I].t = T; vtx[I].w = 1.0f;
99 #define VTX_RECT(SX,SY,SW,SH,DX,DY,DW,DH) \
100  VTX(0, DX, DY, SX, SY); \
101  VTX(1, DX + DW, DY, SX + SW, SY); \
102  VTX(2, DX, DY + DH, SX, SY + SH); \
103  VTX(3, DX + DW, DY, SX + SW, SY); \
104  VTX(4, DX, DY + DH, SX, SY + SH); \
105  VTX(5, DX + DW, DY + DH, SX + SW, SY + SH);
106 
107 static APTR pool_bitmap = NULL;
108 static bool guigfx_warned = false;
109 
110 /* exported function documented in amiga/bitmap.h */
112 {
113  struct bitmap *bitmap;
114 
115  if(pool_bitmap == NULL) pool_bitmap = ami_memory_itempool_create(sizeof(struct bitmap));
116 
117  bitmap = ami_memory_itempool_alloc(pool_bitmap, sizeof(struct bitmap));
118  if(bitmap == NULL) return NULL;
119 
120  bitmap->size = width * height * 4;
121 
122 #ifdef __amigaos4__
123  if(nsoption_bool(use_extmem) == true) {
124  uint64 size64 = bitmap->size;
125  bitmap->iextmem = AllocSysObjectTags(ASOT_EXTMEM,
126  ASOEXTMEM_Size, &size64,
127  ASOEXTMEM_AllocationPolicy, EXTMEMPOLICY_IMMEDIATE,
128  TAG_END);
129 
130  bitmap->pixdata = NULL;
131  UBYTE *pixdata = amiga_bitmap_get_buffer(bitmap);
132  memset(pixdata, 0xff, bitmap->size);
133  } else
134 #endif
135  {
136  bitmap->pixdata = ami_memory_clear_alloc(bitmap->size, 0xff);
137  }
138 
139  bitmap->width = width;
140  bitmap->height = height;
141 
142  bitmap->opaque = (flags & BITMAP_OPAQUE) == BITMAP_OPAQUE;
143 
144  bitmap->nativebm = NULL;
145  bitmap->nativebmwidth = 0;
146  bitmap->nativebmheight = 0;
147  bitmap->native_mask = NULL;
148  bitmap->drawhandle = NULL;
149  bitmap->url = NULL;
150  bitmap->title = NULL;
151  bitmap->icondata = NULL;
152  bitmap->native = AMI_NSBM_NONE;
153 
154  return bitmap;
155 }
156 
157 static void amiga_bitmap_unmap_buffer(void *p)
158 {
159 #ifdef __amigaos4__
160  struct bitmap *bm = p;
161 
162  if((nsoption_bool(use_extmem) == true) && (bm->pixdata != NULL)) {
163  NSLOG(netsurf, INFO,
164  "Unmapping ExtMem object %p for bitmap %p",
165  bm->iextmem,
166  bm);
167  bm->iextmem->Unmap(bm->pixdata, bm->size);
168  bm->pixdata = NULL;
169  }
170 #endif
171 }
172 
173 /* exported function documented in amiga/bitmap.h */
174 unsigned char *amiga_bitmap_get_buffer(void *bitmap)
175 {
176  struct bitmap *bm = bitmap;
177 
178 #ifdef __amigaos4__
179  if(nsoption_bool(use_extmem) == true) {
180  if(bm->pixdata == NULL) {
181  NSLOG(netsurf, INFO,
182  "Mapping ExtMem object %p for bitmap %p",
183  bm->iextmem,
184  bm);
185  bm->pixdata = bm->iextmem->Map(NULL, bm->size, 0LL, 0);
186  }
187 
188  /* unmap the buffer after one second */
190  }
191 #endif
192 
193  return bm->pixdata;
194 }
195 
196 /* exported function documented in amiga/bitmap.h */
198 {
199  struct bitmap *bm = bitmap;
200 
201  if(bm)
202  {
203  return ((bm->width)*4);
204  }
205  else
206  {
207  return 0;
208  }
209 }
210 
211 
212 /* exported function documented in amiga/bitmap.h */
214 {
215  struct bitmap *bm = bitmap;
216 
217  if(bm)
218  {
219  if((bm->nativebm)) { // && (bm->native == AMI_NSBM_TRUECOLOUR)) {
221  }
222 
223  if(bm->native_mask) FreeRaster(bm->native_mask, bm->width, bm->height);
224 
225 #ifdef __amigaos4__
226  if(nsoption_bool(use_extmem) == true) {
229  FreeSysObject(ASOT_EXTMEM, bm->iextmem);
230  bm->iextmem = NULL;
231  } else
232 #endif
233  {
234  if(bm->drawhandle) ReleaseDrawHandle(bm->drawhandle);
236  }
237 
238  if(bm->url) nsurl_unref(bm->url);
239  if(bm->title) free(bm->title);
240 
241  bm->pixdata = NULL;
242  bm->nativebm = NULL;
243  bm->native_mask = NULL;
244  bm->drawhandle = NULL;
245  bm->url = NULL;
246  bm->title = NULL;
247 
248  ami_memory_itempool_free(pool_bitmap, bm, sizeof(struct bitmap));
249  bm = NULL;
250  }
251 }
252 
253 
254 /* exported function documented in amiga/bitmap.h */
255 bool amiga_bitmap_save(void *bitmap, const char *path, unsigned flags)
256 {
257  int err = 0;
258  Object *dto = NULL;
259 
260  if((dto = ami_datatype_object_from_bitmap(bitmap)))
261  {
262  if (flags & AMI_BITMAP_SCALE_ICON) {
263  IDoMethod(dto, PDTM_SCALE, 16, 16, 0);
264 
265  if((DoDTMethod(dto, 0, 0, DTM_PROCLAYOUT, 0, 1)) == 0) {
266  return false;
267  }
268  }
269 
270  err = SaveDTObjectA(dto, NULL, NULL, path, DTWM_IFF, FALSE, NULL);
271  DisposeDTObject(dto);
272  }
273 
274  if(err == 0) return false;
275  else return true;
276 }
277 
278 
279 /* exported function documented in amiga/bitmap.h */
281 {
282  struct bitmap *bm = bitmap;
283 
284 #ifdef __amigaos4__
285  /* unmap the buffer after 0.5s - we might need it imminently */
287 #endif
288 
289  if(bm->nativebm) ami_rtg_freebitmap(bm->nativebm);
290  if(bm->drawhandle) ReleaseDrawHandle(bm->drawhandle);
291  if(bm->native_mask) FreeRaster(bm->native_mask, bm->width, bm->height);
292  bm->nativebm = NULL;
293  bm->drawhandle = NULL;
294  bm->native_mask = NULL;
295  bm->native = AMI_NSBM_NONE;
296 }
297 
298 
299 /* exported function documented in amiga/bitmap.h */
301 {
302  struct bitmap *bm = bitmap;
303  assert(bitmap);
304  bm->opaque = opaque;
305 }
306 
307 
308 /* exported function documented in amiga/bitmap.h */
310 {
311  struct bitmap *bm = bitmap;
312  uint32 p = bm->width * bm->height;
313  uint32 a = 0;
314  uint32 *bmi = (uint32 *)amiga_bitmap_get_buffer(bm);
315 
316  assert(bitmap);
317 
318  for(a=0;a<p;a+=4)
319  {
320  if ((*bmi & 0x000000ffU) != 0x000000ffU) return false;
321  bmi++;
322  }
323  return true;
324 }
325 
326 
327 /* exported function documented in amiga/bitmap.h */
329 {
330  struct bitmap *bm = bitmap;
331  assert(bitmap);
332  return bm->opaque;
333 }
334 
335 /**
336  * get width of a bitmap.
337  */
339 {
340  struct bitmap *bm = bitmap;
341 
342  if(bm)
343  {
344  return(bm->width);
345  }
346  else
347  {
348  return 0;
349  }
350 }
351 
352 /**
353  * get height of a bitmap.
354  */
356 {
357  struct bitmap *bm = bitmap;
358 
359  if(bm)
360  {
361  return(bm->height);
362  }
363  else
364  {
365  return 0;
366  }
367 }
368 
369 static void ami_bitmap_argb_to_rgba(struct bitmap *bm)
370 {
371  if(bm == NULL) return;
372 
373  ULONG *data = (ULONG *)amiga_bitmap_get_buffer(bm);
374  for(int i = 0; i < (bm->width * bm->height); i++) {
375  data[i] = (data[i] << 8) | (data[i] >> 24);
376  }
377 }
378 
379 static void ami_bitmap_rgba_to_argb(struct bitmap *bm)
380 {
381  if(bm == NULL) return;
382 
383  ULONG *data = (ULONG *)amiga_bitmap_get_buffer(bm);
384  for(int i = 0; i < (bm->width * bm->height); i++) {
385  data[i] = (data[ i] >> 8) | (data[i] << 24);
386  }
387 }
388 
389 #ifdef BITMAP_DUMP
390 void bitmap_dump(struct bitmap *bitmap)
391 {
392  int x,y;
393  ULONG *bm = (ULONG *)amiga_bitmap_get_buffer(bitmap);
394 
395  printf("Width=%ld, Height=%ld, Opaque=%s\nnativebm=%lx, width=%ld, height=%ld\n",
396  bitmap->width, bitmap->height, bitmap->opaque ? "true" : "false",
397  bitmap->nativebm, bitmap->nativebmwidth, bitmap->nativebmheight);
398 
399  for(y = 0; y < bitmap->height; y++) {
400  for(x = 0; x < bitmap->width; x++) {
401  printf("%lx ", bm[(y*bitmap->width) + x]);
402  }
403  printf("\n");
404  }
405 }
406 #endif
407 
408 Object *ami_datatype_object_from_bitmap(struct bitmap *bitmap)
409 {
410  Object *dto;
411  struct BitMapHeader *bmhd;
412 
413  if((dto = NewDTObject(NULL,
414  DTA_SourceType,DTST_RAM,
415  DTA_GroupID,GID_PICTURE,
416  //DTA_BaseName,"ilbm",
417  PDTA_DestMode,PMODE_V43,
418  TAG_DONE)))
419  {
420  if(GetDTAttrs(dto,PDTA_BitMapHeader,&bmhd,TAG_DONE))
421  {
422  bmhd->bmh_Width = (UWORD)bitmap_get_width(bitmap);
423  bmhd->bmh_Height = (UWORD)bitmap_get_height(bitmap);
424  bmhd->bmh_Depth = (UBYTE)32;
425  if(!amiga_bitmap_get_opaque(bitmap)) bmhd->bmh_Masking = mskHasAlpha;
426  }
427 
428  SetDTAttrs(dto,NULL,NULL,
429  DTA_ObjName, bitmap->url ? nsurl_access(bitmap->url) : "",
430  DTA_ObjAnnotation,bitmap->title,
431  DTA_ObjAuthor,messages_get("NetSurf"),
432  DTA_NominalHoriz,bitmap_get_width(bitmap),
433  DTA_NominalVert,bitmap_get_height(bitmap),
434  PDTA_SourceMode,PMODE_V43,
435  TAG_DONE);
436 
437  IDoMethod(dto, PDTM_WRITEPIXELARRAY, amiga_bitmap_get_buffer(bitmap),
438  PBPAFMT_RGBA, amiga_bitmap_get_rowstride(bitmap), 0, 0,
439  bitmap_get_width(bitmap), bitmap_get_height(bitmap));
440  }
441 
442  return dto;
443 }
444 
445 /* Quick way to get an object on disk into a struct bitmap */
446 struct bitmap *ami_bitmap_from_datatype(char *filename)
447 {
448  Object *dto;
449  struct bitmap *bm = NULL;
450 
451  if((dto = NewDTObject(filename,
452  DTA_GroupID, GID_PICTURE,
453  PDTA_DestMode, PMODE_V43,
454  PDTA_PromoteMask, TRUE,
455  TAG_DONE))) {
456  struct BitMapHeader *bmh;
457 
458  if(GetDTAttrs(dto, PDTA_BitMapHeader, &bmh, TAG_DONE))
459  {
460  bm = amiga_bitmap_create(bmh->bmh_Width, bmh->bmh_Height, 0);
461 
462  IDoMethod(dto, PDTM_READPIXELARRAY, amiga_bitmap_get_buffer(bm),
463  PBPAFMT_RGBA, amiga_bitmap_get_rowstride(bm), 0, 0,
464  bmh->bmh_Width, bmh->bmh_Height);
465 
467  }
468  DisposeDTObject(dto);
469  }
470 
471  return bm;
472 }
473 
474 static inline struct BitMap *ami_bitmap_get_generic(struct bitmap *bitmap,
475  int width, int height, struct BitMap *restrict friendbm, int type)
476 {
477  struct BitMap *restrict tbm = NULL;
478  struct Screen *scrn = ami_gui_get_screen();
479 
480  if(bitmap->nativebm)
481  {
482  if((bitmap->nativebmwidth == width) && (bitmap->nativebmheight == height)) {
483  tbm = bitmap->nativebm;
484  return tbm;
485  } else if((bitmap->nativebmwidth == bitmap->width) &&
486  (bitmap->nativebmheight == bitmap->height)) { // >= width/height ?
487  tbm = bitmap->nativebm;
488  } else {
489  if(bitmap->nativebm) amiga_bitmap_modified(bitmap);
490  }
491  }
492 
493  if(tbm == NULL) {
494  if(type == AMI_NSBM_TRUECOLOUR) {
495  tbm = ami_rtg_allocbitmap(bitmap->width, bitmap->height, 32, 0,
496  friendbm, AMI_BITMAP_FORMAT);
497  if(tbm == NULL) return NULL;
498 
500  tbm, bitmap->width, bitmap->height,
501  bitmap->width * 4, AMI_BITMAP_FORMAT);
502  } else {
503  tbm = ami_rtg_allocbitmap(width, height,
504  8, 0, friendbm, AMI_BITMAP_FORMAT);
505  if(tbm == NULL) return NULL;
506 
507  if(GuiGFXBase != NULL) {
508  struct RastPort rp;
509  InitRastPort(&rp);
510  rp.BitMap = tbm;
511  ULONG dithermode = DITHERMODE_NONE;
512 
513  if(nsoption_int(dither_quality) == 1) {
514  dithermode = DITHERMODE_EDD;
515  } else if(nsoption_int(dither_quality) == 2) {
516  dithermode = DITHERMODE_FS;
517  }
518 
519  ami_bitmap_rgba_to_argb(bitmap);
520  bitmap->drawhandle = ObtainDrawHandle(
521  NULL,
522  &rp,
523  scrn->ViewPort.ColorMap,
524  GGFX_DitherMode, dithermode,
525  TAG_DONE);
526  if(bitmap->drawhandle) {
527  APTR ddh = CreateDirectDrawHandle(bitmap->drawhandle,
528  bitmap->width, bitmap->height,
529  width, height, NULL);
530 
531  DirectDrawTrueColor(ddh, (ULONG *)amiga_bitmap_get_buffer(bitmap), 0, 0, TAG_DONE);
532  DeleteDirectDrawHandle(ddh);
533  ReleaseDrawHandle(bitmap->drawhandle);
534  bitmap->drawhandle = NULL;
535  }
536  ami_bitmap_argb_to_rgba(bitmap);
537  } else {
538  if(guigfx_warned == false) {
539  amiga_warn_user("BMConvErr", NULL);
540  guigfx_warned = true;
541  }
542  }
543  }
544 
545  if(((type == AMI_NSBM_TRUECOLOUR) && (nsoption_int(cache_bitmaps) == 2)) ||
546  ((type == AMI_NSBM_PALETTEMAPPED) && (((bitmap->width == width) &&
547  (bitmap->height == height) && (nsoption_int(cache_bitmaps) == 2)) ||
548  (nsoption_int(cache_bitmaps) >= 1)))) {
549  bitmap->nativebm = tbm;
550  if(type == AMI_NSBM_TRUECOLOUR) {
551  bitmap->nativebmwidth = bitmap->width;
552  bitmap->nativebmheight = bitmap->height;
553  } else {
554  bitmap->nativebmwidth = width;
555  bitmap->nativebmheight = height;
556  }
557  bitmap->native = type;
558  }
559 
560  if(type == AMI_NSBM_PALETTEMAPPED)
561  return tbm;
562  }
563 
564  if((bitmap->width != width) || (bitmap->height != height)) {
565  struct BitMap *restrict scaledbm;
566  struct BitScaleArgs bsa;
567  int depth = 32;
568  if(type == AMI_NSBM_PALETTEMAPPED) depth = 8;
569 
570  scaledbm = ami_rtg_allocbitmap(width, height, depth, 0,
571  friendbm, AMI_BITMAP_FORMAT);
572 #ifdef __amigaos4__
573  if(__builtin_expect(((GfxBase->LibNode.lib_Version >= 53) &&
574  (type == AMI_NSBM_TRUECOLOUR)), 1)) {
575  /* AutoDoc says v52, but this function isn't in OS4.0, so checking for v53 (OS4.1)
576  * Additionally, when we use friend BitMaps in non 32-bit modes it freezes the OS */
577 
578  uint32 flags = 0;
579  uint32 err = COMPERR_Success;
580 #ifdef AMI_NS_TRIANGLE_SCALING
581  struct vertex vtx[6];
582  VTX_RECT(0, 0, bitmap->width, bitmap->height, 0, 0, width, height);
583 
584  flags = COMPFLAG_HardwareOnly;
585  if(nsoption_bool(scale_quality) == true) flags |= COMPFLAG_SrcFilter;
586 
587  err = CompositeTags(COMPOSITE_Src, tbm, scaledbm,
588  COMPTAG_VertexArray, vtx,
589  COMPTAG_VertexFormat, COMPVF_STW0_Present,
590  COMPTAG_NumTriangles, 2,
591  COMPTAG_Flags, flags,
592  COMPTAG_FriendBitMap, scrn->RastPort.BitMap,
593  TAG_DONE);
594 
595  if (err != COMPERR_Success) {
596  NSLOG(netsurf, INFO,
597  "Composite error %ld - falling back",
598  err);
599  /* If it failed, do it again the way
600  * which works in software
601  */
602 #else
603  {
604 #endif
605  flags = 0;
606  if(nsoption_bool(scale_quality) == true) flags |= COMPFLAG_SrcFilter;
607 
608  err = CompositeTags(COMPOSITE_Src, tbm, scaledbm,
609  COMPTAG_ScaleX, COMP_FLOAT_TO_FIX((float)width/bitmap->width),
610  COMPTAG_ScaleY, COMP_FLOAT_TO_FIX((float)height/bitmap->height),
611  COMPTAG_Flags, flags,
612  COMPTAG_FriendBitMap, scrn->RastPort.BitMap,
613  TAG_DONE);
614  /* If it still fails... it's non-fatal */
615  NSLOG(netsurf, INFO,
616  "Fallback returned error %ld", err);
617  }
618  } else /* Do it the old-fashioned way. This is pretty slow, even on OS4.1 */
619 #endif
620  {
621  bsa.bsa_SrcX = 0;
622  bsa.bsa_SrcY = 0;
623  bsa.bsa_SrcWidth = bitmap->width;
624  bsa.bsa_SrcHeight = bitmap->height;
625  bsa.bsa_DestX = 0;
626  bsa.bsa_DestY = 0;
627  bsa.bsa_XSrcFactor = bitmap->width;
628  bsa.bsa_XDestFactor = width;
629  bsa.bsa_YSrcFactor = bitmap->height;
630  bsa.bsa_YDestFactor = height;
631  bsa.bsa_SrcBitMap = tbm;
632  bsa.bsa_DestBitMap = scaledbm;
633  bsa.bsa_Flags = 0;
634 
635  BitMapScale(&bsa);
636  }
637 
638  if(bitmap->nativebm != tbm) ami_rtg_freebitmap(bitmap->nativebm);
639  ami_rtg_freebitmap(tbm);
640  tbm = scaledbm;
641  bitmap->nativebm = NULL;
642  bitmap->native = AMI_NSBM_NONE;
643 
644  if(nsoption_int(cache_bitmaps) >= 1)
645  {
646  bitmap->nativebm = tbm;
647  bitmap->nativebmwidth = width;
648  bitmap->nativebmheight = height;
649  bitmap->native = type;
650  }
651  }
652 
653  return tbm;
654 }
655 
656 
657 static inline struct BitMap *ami_bitmap_get_truecolour(struct bitmap *bitmap,
658  int width, int height, struct BitMap *friendbm)
659 {
660  if((bitmap->native != AMI_NSBM_NONE) && (bitmap->native != AMI_NSBM_TRUECOLOUR)) {
661  amiga_bitmap_modified(bitmap);
662  }
663 
664  return ami_bitmap_get_generic(bitmap, width, height, friendbm, AMI_NSBM_TRUECOLOUR);
665 }
666 
667 PLANEPTR ami_bitmap_get_mask(struct bitmap *bitmap, int width,
668  int height, struct BitMap *n_bm)
669 {
670  uint32 *bmi = (uint32 *) amiga_bitmap_get_buffer(bitmap);
671  UBYTE maskbit = 0;
672  ULONG bm_width;
673  int y, x, bpr;
674 
675  if((height != bitmap->height) || (width != bitmap->width)) return NULL;
676  if(amiga_bitmap_get_opaque(bitmap) == true) return NULL;
677  if(bitmap->native_mask) return bitmap->native_mask;
678 
679  bm_width = GetBitMapAttr(n_bm, BMA_WIDTH);
680  bpr = RASSIZE(bm_width, 1);
681  bitmap->native_mask = AllocRaster(bm_width, height);
682  SetMem(bitmap->native_mask, 0, bpr * height);
683 
684  for(y=0; y<height; y++) {
685  for(x=0; x<width; x++) {
686  if ((*bmi & 0x000000ffU) <= (ULONG)nsoption_int(mask_alpha)) maskbit = 0;
687  else maskbit = 1;
688  bmi++;
689  bitmap->native_mask[(y*bpr) + (x/8)] |=
690  maskbit << (7 - (x % 8));
691  }
692  }
693 
694  return bitmap->native_mask;
695 }
696 
697 static inline struct BitMap *ami_bitmap_get_palettemapped(struct bitmap *bitmap,
698  int width, int height, struct BitMap *friendbm)
699 {
700  if((bitmap->native != AMI_NSBM_NONE) && (bitmap->native != AMI_NSBM_PALETTEMAPPED)) {
701  amiga_bitmap_modified(bitmap);
702  }
703 
704  return ami_bitmap_get_generic(bitmap, width, height, friendbm, AMI_NSBM_PALETTEMAPPED);
705 }
706 
707 struct BitMap *ami_bitmap_get_native(struct bitmap *bitmap,
708  int width, int height, bool palette_mapped, struct BitMap *friendbm)
709 {
710  if(bitmap == NULL) return NULL;
711 
712  if(__builtin_expect(palette_mapped == true, 0)) {
713  return ami_bitmap_get_palettemapped(bitmap, width, height, friendbm);
714  } else {
715  return ami_bitmap_get_truecolour(bitmap, width, height, friendbm);
716  }
717 }
718 
719 void ami_bitmap_fini(void)
720 {
722  pool_bitmap = NULL;
723 }
724 
725 static nserror bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content)
726 {
727 #ifdef __amigaos4__
728  NSLOG(netsurf, INFO, "Entering bitmap_render");
729 
730  int plot_width;
731  int plot_height;
732  struct gui_globals *bm_globals;
733 
734  plot_width = MIN(content_get_width(content), bitmap->width);
735  plot_height = ((plot_width * bitmap->height) + (bitmap->width / 2)) /
736  bitmap->width;
737 
738  bm_globals = ami_plot_ra_alloc(bitmap->width, bitmap->height, true, false);
739  ami_clearclipreg(bm_globals);
740 
741  struct redraw_context ctx = {
742  .interactive = false,
743  .background_images = true,
744  .plot = &amiplot,
745  .priv = bm_globals
746  };
747 
748  content_scaled_redraw(content, plot_width, plot_height, &ctx);
749 
750  BltBitMapTags( BLITA_SrcX, 0,
751  BLITA_SrcY, 0,
752  BLITA_Width, bitmap->width,
753  BLITA_Height, bitmap->height,
754  BLITA_Source, ami_plot_ra_get_bitmap(bm_globals),
755  BLITA_SrcType, BLITT_BITMAP,
756  BLITA_Dest, amiga_bitmap_get_buffer(bitmap),
757  BLITA_DestType, BLITT_ARGB32,
758  BLITA_DestBytesPerRow, 4 * bitmap->width,
759  BLITA_DestX, 0,
760  BLITA_DestY, 0,
761  TAG_DONE);
762 
763  ami_bitmap_argb_to_rgba(bitmap);
764 
765  /**\todo In theory we should be able to move the bitmap to our native area
766  to try to avoid re-conversion (at the expense of memory) */
767 
768  ami_plot_ra_free(bm_globals);
769  amiga_bitmap_set_opaque(bitmap, true);
770 #else
771 #warning FIXME for OS3 (in current state none of bitmap_render can work!)
772 #endif
773 
774  return NSERROR_OK;
775 }
776 
777 void ami_bitmap_set_url(struct bitmap *bm, struct nsurl *url)
778 {
779  if(bm->url != NULL) return;
780  bm->url = nsurl_ref(url);
781 }
782 
783 void ami_bitmap_set_title(struct bitmap *bm, const char *title)
784 {
785  if(bm->title != NULL) return;
786  bm->title = strdup(title);
787 }
788 
789 void ami_bitmap_set_icondata(struct bitmap *bm, ULONG *icondata)
790 {
791  bm->icondata = icondata;
792 }
793 
794 void ami_bitmap_free_icondata(struct bitmap *bm)
795 {
796  if(bm->icondata) free(bm->icondata);
797  bm->icondata = NULL;
798 }
799 
800 bool ami_bitmap_is_nativebm(struct bitmap *bm, struct BitMap *nbm)
801 {
802  if(bm->nativebm == nbm) return true;
803  else return false;
804 }
805 
806 
809  .destroy = amiga_bitmap_destroy,
810  .set_opaque = amiga_bitmap_set_opaque,
811  .get_opaque = amiga_bitmap_get_opaque,
812  .test_opaque = amiga_bitmap_test_opaque,
813  .get_buffer = amiga_bitmap_get_buffer,
814  .get_rowstride = amiga_bitmap_get_rowstride,
815  .get_width = bitmap_get_width,
816  .get_height = bitmap_get_height,
817  .modified = amiga_bitmap_modified,
818  .render = bitmap_render,
819 };
820 
struct BitMap * nativebm
Definition: bitmap.c:76
bool amiga_bitmap_save(void *bitmap, const char *path, unsigned flags)
Save a bitmap in the platform&#39;s native format.
Definition: bitmap.c:255
struct gui_globals * ami_plot_ra_alloc(ULONG width, ULONG height, bool force32bit, bool alloc_pen_list)
Alloc a plotter render area.
Definition: plotters.c:113
void * amiga_bitmap_create(int width, int height, enum gui_bitmap_flags flags)
Create a bitmap.
Definition: bitmap.c:111
int bitmap_get_height(void *bitmap)
get height of a bitmap.
Definition: bitmap.c:355
Definition: bitmap.c:93
void ami_clearclipreg(struct gui_globals *gg)
Definition: plotters.c:289
struct BitMap * ami_bitmap_get_native(struct bitmap *bitmap, int width, int height, bool palette_mapped, struct BitMap *friendbm)
Definition: bitmap.c:707
#define AllocSysObjectTags(A, B, C, D)
Definition: os3support.h:157
static bool guigfx_warned
Definition: bitmap.c:108
Interface to utility string handling.
#define SetMem
Definition: os3support.h:175
APTR drawhandle
Definition: bitmap.c:81
Localised message support (interface).
static APTR pool_bitmap
Definition: bitmap.c:107
Public content interface.
Abstract RTG functions for newer/older/non-P96 systems.
void amiga_bitmap_set_opaque(void *bitmap, bool opaque)
Sets whether a bitmap should be plotted opaque.
Definition: bitmap.c:300
PLANEPTR ami_bitmap_get_mask(struct bitmap *bitmap, int width, int height, struct BitMap *n_bm)
Definition: bitmap.c:667
void * ami_memory_clear_alloc(size_t size, UBYTE value)
Definition: memory.c:42
static struct gui_bitmap_table bitmap_table
Definition: bitmap.c:807
#define SaveDTObjectA(O, W, R, F, M, I, A)
Definition: os3support.h:146
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
Object * dto
Definition: bitmap.c:80
#define MIN(a, b)
Definition: os3support.h:51
static struct Screen * scrn
Definition: gui.c:326
struct gui_bitmap_table * amiga_bitmap_table
Definition: bitmap.c:821
void ami_bitmap_free_icondata(struct bitmap *bm)
Free an icondata pointer.
Definition: bitmap.c:794
static void amiga_bitmap_unmap_buffer(void *p)
Definition: bitmap.c:157
static nserror bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content)
Definition: bitmap.c:725
#define ami_memory_itempool_create(s)
Definition: memory.h:54
PLANEPTR native_mask
Definition: bitmap.c:79
const char * type
Definition: filetype.cpp:44
#define nsoption_int(OPTION)
Get the value of an integer option.
Definition: nsoption.h:279
bool interactive
Redraw to show interactive features.
Definition: plotters.h:59
Option reading and saving interface.
int nativebmheight
Definition: bitmap.c:78
#define VTX_RECT(SX, SY, SW, SH, DX, DY, DW, DH)
Definition: bitmap.c:99
struct Screen * ami_gui_get_screen(void)
Get a pointer to the screen NetSurf is running on.
Definition: gui.c:403
struct nsurl * url
Definition: bitmap.c:82
char * title
Definition: bitmap.c:83
nserror
Enumeration of error codes.
Definition: errors.h:29
void amiga_bitmap_destroy(void *bitmap)
Free a bitmap.
Definition: bitmap.c:213
int height
height of bitmap
Definition: bitmap.c:70
void ami_plot_ra_free(struct gui_globals *gg)
Free a plotter render area.
Definition: plotters.c:236
image is opaque
Definition: bitmap.h:60
High-level cache handle.
Definition: hlcache.c:65
bool amiga_bitmap_test_opaque(void *bitmap)
Tests whether a bitmap has an opaque alpha channel.
Definition: bitmap.c:309
uint32_t uint32
Definition: os3support.h:184
static struct BitMap * ami_bitmap_get_truecolour(struct bitmap *bitmap, int width, int height, struct BitMap *friendbm)
Definition: bitmap.c:657
Content which corresponds to a single URL.
struct BitMap * ami_plot_ra_get_bitmap(struct gui_globals *gg)
Get a drawing BitMap associated with a render area.
Definition: plotters.c:273
No error.
Definition: errors.h:30
static struct BitMap * ami_bitmap_get_palettemapped(struct bitmap *bitmap, int width, int height, struct BitMap *friendbm)
Definition: bitmap.c:697
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:115
uint32 size
Definition: bitmap.c:73
Object * ami_datatype_object_from_bitmap(struct bitmap *bitmap)
Definition: bitmap.c:408
static void ami_bitmap_argb_to_rgba(struct bitmap *bm)
Definition: bitmap.c:369
struct BitMap * ami_rtg_allocbitmap(ULONG width, ULONG height, ULONG depth, ULONG flags, struct BitMap *friend, RGBFTYPE format)
Definition: rtg.c:25
RISC OS wimp toolkit bitmap.
Definition: bitmap.c:68
void amiga_bitmap_modified(void *bitmap)
The bitmap image has changed, so flush any persistant cache.
Definition: bitmap.c:280
#define AMI_BITMAP_SCALE_ICON
Definition: bitmap.h:31
void ami_rtg_writepixelarray(UBYTE *pixdata, struct BitMap *bm, ULONG width, ULONG height, ULONG bpr, ULONG format)
Definition: rtg.c:44
size_t amiga_bitmap_get_rowstride(void *bitmap)
Find the width of a pixel row in bytes.
Definition: bitmap.c:197
gui_bitmap_flags
Bitmap creation flags.
Definition: bitmap.h:58
bool amiga_bitmap_get_opaque(void *bitmap)
Gets whether a bitmap should be plotted opaque.
Definition: bitmap.c:328
Bitmap operations.
Definition: bitmap.h:71
int nativebmwidth
Definition: bitmap.c:77
const struct plotter_table amiplot
Definition: plotters.c:1158
uint64_t uint64
Definition: os3support.h:186
Redraw context.
Definition: plotters.h:51
bool opaque
Whether the bitmap is opaque.
Definition: bitmap.c:74
nserror amiga_warn_user(const char *warning, const char *detail)
Warn the user of an event.
Definition: misc.c:79
const char * messages_get(const char *key)
Fast lookup of a message by key from the standard Messages hash.
Definition: messages.c:241
void ami_bitmap_set_icondata(struct bitmap *bm, ULONG *icondata)
Set an icondata pointer.
Definition: bitmap.c:789
static void ami_bitmap_rgba_to_argb(struct bitmap *bm)
Definition: bitmap.c:379
struct bitmap * ami_bitmap_from_datatype(char *filename)
Definition: bitmap.c:446
UBYTE * pixdata
Definition: bitmap.c:71
ULONG * icondata
Definition: bitmap.c:84
unsigned char * amiga_bitmap_get_buffer(void *bitmap)
Return a pointer to the pixel data in a bitmap.
Definition: bitmap.c:174
bool ami_bitmap_is_nativebm(struct bitmap *bm, struct BitMap *nbm)
Test if a BitMap is owned by a bitmap.
Definition: bitmap.c:800
nsurl * nsurl_ref(nsurl *url)
Increment the reference count to a NetSurf URL object.
static nserror path(const struct redraw_context *ctx, const plot_style_t *pstyle, const float *p, unsigned int n, const float transform[6])
Plots a path.
Definition: plot.c:821
struct ExtMemIFace * iextmem
Definition: bitmap.c:72
nserror ami_schedule(int t, void(*callback)(void *p), void *p)
Schedule a callback.
Definition: schedule.c:331
int width
width of bitmap
Definition: bitmap.c:69
int content_get_width(struct hlcache_handle *h)
Retrieve width of content.
Definition: content.c:1158
Generic bitmap handling interface.
float w
Definition: bitmap.c:95
const char * nsurl_access(const nsurl *url)
Access a NetSurf URL object as a string.
#define ami_memory_itempool_alloc(p, s)
Definition: memory.h:56
int bitmap_get_width(void *bitmap)
get width of a bitmap.
Definition: bitmap.c:338
#define ami_memory_itempool_delete(p)
Definition: memory.h:55
#define AMI_BITMAP_FORMAT
Definition: bitmap.h:30
static struct BitMap * ami_bitmap_get_generic(struct bitmap *bitmap, int width, int height, struct BitMap *restrict friendbm, int type)
Definition: bitmap.c:474
float y
Definition: bitmap.c:94
#define PDTA_PromoteMask
Definition: os3support.h:75
#define ami_memory_clear_free(p)
Definition: memory.h:39
bool content_scaled_redraw(struct hlcache_handle *h, int width, int height, const struct redraw_context *ctx)
Redraw a content with scale set for horizontal fit.
Definition: content.c:583
#define IDoMethod
Definition: os3support.h:169
static bool palette_mapped
Definition: plotters.c:98
void ami_bitmap_set_url(struct bitmap *bm, struct nsurl *url)
Set bitmap URL.
Definition: bitmap.c:777
void ami_bitmap_fini(void)
Cleanup bitmap allocations.
Definition: bitmap.c:719
Minimal compatibility header for AmigaOS 3.
NetSurf URL handling (interface).
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
void ami_rtg_freebitmap(struct BitMap *bm)
Definition: rtg.c:35
#define ami_memory_itempool_free(p, i, s)
Definition: memory.h:57
#define nsoption_bool(OPTION)
Get the value of a boolean option.
Definition: nsoption.h:270
void FreeSysObject(ULONG type, APTR obj)
Definition: os3support.c:350
void nsurl_unref(nsurl *url)
Drop a reference to a NetSurf URL object.
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
void ami_bitmap_set_title(struct bitmap *bm, const char *title)
Set bitmap title.
Definition: bitmap.c:783