NetSurf
bitmap.c
Go to the documentation of this file.
1/*
2 * Copyright 2004 James Bursa <bursa@users.sourceforge.net>
3 * Copyright 2005 Richard Wilson <info@tinct.net>
4 * Copyright 2008 Adrian Lees <adrianl@users.sourceforge.net>
5 *
6 * This file is part of NetSurf, http://www.netsurf-browser.org/
7 *
8 * NetSurf is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * NetSurf is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21/**
22 * \file
23 * RISC OS implementation of bitmap operations.
24 *
25 * This implements the interface given by image/bitmap.h using RISC OS
26 * sprites.
27 */
28
29#include <assert.h>
30#include <stdbool.h>
31#include <string.h>
32#include <swis.h>
33#include <rufl.h>
34#include <unixlib/local.h>
35#include <oslib/colourtrans.h>
36#include <oslib/osfile.h>
37#include <oslib/osfind.h>
38#include <oslib/osgbpb.h>
39#include <oslib/osspriteop.h>
40#include <oslib/wimp.h>
41
42#include "utils/nsoption.h"
43#include "utils/filename.h"
44#include "utils/log.h"
45#include "utils/messages.h"
46#include "netsurf/plotters.h"
47#include "netsurf/content.h"
48
49#include "riscos/gui.h"
50#include "riscos/image.h"
51#include "riscos/palettes.h"
53#include "riscos/tinct.h"
54#include "riscos/bitmap.h"
55
56/** Colour in the overlay sprite that allows the bitmap to show through */
57#define OVERLAY_INDEX 0xfe
58
59/** Size of buffer used when constructing mask data to be saved */
60#define SAVE_CHUNK_SIZE 4096
61
62/**
63 * Whether we can use 32bpp sprites
64 */
66
67/**
68 * Sprite output context saving
69 */
71 osspriteop_save_area *save_area;
75};
76
77/**
78 * Initialise a bitmaps sprite area.
79 *
80 * \param bitmap the bitmap to initialise
81 * \return true if bitmap initialised else false.
82 */
83
84static bool bitmap_initialise(struct bitmap *bitmap)
85{
86 unsigned int area_size;
87 osspriteop_area *sprite_area;
88 osspriteop_header *sprite;
89
90 assert(!bitmap->sprite_area);
91
92 area_size = 16 + 44 + bitmap->width * bitmap->height * 4;
93 if (bitmap->clear)
94 bitmap->sprite_area = calloc(1, area_size);
95 else
96 bitmap->sprite_area = malloc(area_size);
97
98 if (!bitmap->sprite_area)
99 return false;
100
101 /* area control block */
102 sprite_area = bitmap->sprite_area;
103 sprite_area->size = area_size;
104 sprite_area->sprite_count = 1;
105 sprite_area->first = 16;
106 sprite_area->used = area_size;
107
108 /* sprite control block */
109 sprite = (osspriteop_header *) (sprite_area + 1);
110 sprite->size = area_size - 16;
111 memset(sprite->name, 0x00, 12);
112 strncpy(sprite->name, "bitmap", 12);
113 sprite->width = bitmap->width - 1;
114 sprite->height = bitmap->height - 1;
115 sprite->left_bit = 0;
116 sprite->right_bit = 31;
117 sprite->image = sprite->mask = 44;
118 sprite->mode = tinct_SPRITE_MODE;
119
120 return true;
121}
122
123
124/* exported interface documented in riscos/bitmap.h */
126{
127 struct bitmap *bitmap;
128
129 if (width == 0 || height == 0)
130 return NULL;
131
132 bitmap = calloc(1, sizeof(struct bitmap));
133 if (!bitmap)
134 return NULL;
135 bitmap->width = width;
138 bitmap->clear = (flags & BITMAP_CLEAR) == BITMAP_CLEAR;
139
140 return bitmap;
141}
142
143
144/* exported interface documented in riscos/bitmap.h */
145unsigned char *riscos_bitmap_get_buffer(void *vbitmap)
146{
147 struct bitmap *bitmap = (struct bitmap *) vbitmap;
148 assert(bitmap);
149
150 /* dynamically create the buffer */
151 if (bitmap->sprite_area == NULL) {
153 return NULL;
154 }
155
156 /* image data area should exist */
157 if (bitmap->sprite_area)
158 return ((unsigned char *) (bitmap->sprite_area)) + 16 + 44;
159
160 return NULL;
161}
162
163
164/**
165 * Sets whether a bitmap should be plotted opaque
166 *
167 * \param vbitmap a bitmap, as returned by bitmap_create()
168 * \param opaque whether the bitmap should be plotted opaque
169 */
170static void bitmap_set_opaque(void *vbitmap, bool opaque)
171{
172 struct bitmap *bitmap = (struct bitmap *) vbitmap;
173 assert(bitmap);
174
176}
177
178
179/**
180 * Find the width of a pixel row in bytes.
181 *
182 * \param vbitmap A bitmap, as returned by riscos_bitmap_create()
183 * \return width of a pixel row in the bitmap
184 */
185static size_t bitmap_get_rowstride(void *vbitmap)
186{
187 struct bitmap *bitmap = (struct bitmap *) vbitmap;
188 return bitmap->width * 4;
189}
190
191
192/* exported interface documented in riscos/bitmap.h */
193bool riscos_bitmap_get_opaque(void *vbitmap)
194{
195 struct bitmap *bitmap = (struct bitmap *) vbitmap;
196 assert(bitmap);
197 return bitmap->opaque;
198}
199
200
201/* exported interface documented in riscos/bitmap.h */
202void riscos_bitmap_destroy(void *vbitmap)
203{
204 struct bitmap *bitmap = (struct bitmap *) vbitmap;
205
206 assert(bitmap);
207
208 /* destroy bitmap */
209 if (bitmap->sprite_area) {
210 free(bitmap->sprite_area);
211 }
212
213 free(bitmap);
214}
215
216
217/* exported interface documented in riscos/bitmap.h */
218bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags)
219{
220 struct bitmap *bitmap = (struct bitmap *) vbitmap;
221 os_error *error;
222
223 if (bitmap == NULL) {
224 ro_warn_user("SaveError", messages_get("SprIsNull"));
225 return false;
226 }
227
228 if (!bitmap->sprite_area) {
230 }
231 if (!bitmap->sprite_area)
232 return false;
233
235 error = xosspriteop_save_sprite_file(osspriteop_USER_AREA,
237 if (error) {
238 NSLOG(netsurf, INFO,
239 "xosspriteop_save_sprite_file: 0x%x: %s",
240 error->errnum,
241 error->errmess);
242 ro_warn_user("SaveError", error->errmess);
243 return false;
244 }
245 return true;
246 } else {
247 /* to make the saved sprite useful we must convert from 'Tinct'
248 * format to either a bi-level mask or a Select-style full
249 * alpha channel */
250 osspriteop_area *area = bitmap->sprite_area;
251 osspriteop_header *hdr = (void *) ((char *) area + area->first);
252 unsigned width = hdr->width + 1, height = hdr->height + 1;
253 unsigned image_size = height * width * 4;
254 unsigned char *chunk_buf;
255 unsigned *p, *elp, *eip;
256 unsigned mask_size;
257 size_t chunk_pix;
258 struct {
259 osspriteop_area area;
260 osspriteop_header hdr;
261 } file_hdr;
262 os_fw fw;
263
264 /* we only support 32bpp sprites */
265 if ((((unsigned)hdr->mode >> 27)&15) != 6) {
266 assert(!"Unsupported sprite format in bitmap_save");
267 return false;
268 }
269
270 chunk_buf = malloc(SAVE_CHUNK_SIZE);
271 if (!chunk_buf) {
272 ro_warn_user("NoMemory", NULL);
273 return false;
274 }
275
276 file_hdr.area = *area;
277 file_hdr.hdr = *hdr;
278
279 if (flags & BITMAP_SAVE_FULL_ALPHA) {
280 mask_size = ((width + 3) & ~3) * height;
281 chunk_pix = SAVE_CHUNK_SIZE;
282 file_hdr.hdr.mode = (os_mode)((unsigned)file_hdr.hdr.mode
283 | (1U<<31));
284 } else {
285 mask_size = (((width + 31) & ~31)/8) * height;
286 chunk_pix = SAVE_CHUNK_SIZE<<3;
287 file_hdr.hdr.mode = (os_mode)((unsigned)file_hdr.hdr.mode
288 & ~(1U<<31));
289 }
290
291 file_hdr.area.sprite_count = 1;
292 file_hdr.area.first = sizeof(file_hdr.area);
293 file_hdr.area.used = sizeof(file_hdr) + image_size + mask_size;
294
295 file_hdr.hdr.image = sizeof(file_hdr.hdr);
296 file_hdr.hdr.mask = file_hdr.hdr.image + image_size;
297 file_hdr.hdr.size = file_hdr.hdr.mask + mask_size;
298
299 error = xosfind_openoutw(0, path, NULL, &fw);
300 if (error) {
301 NSLOG(netsurf, INFO, "xosfind_openoutw: 0x%x: %s",
302 error->errnum, error->errmess);
303 free(chunk_buf);
304 ro_warn_user("SaveError", error->errmess);
305 return false;
306 }
307
308 p = (void *) ((char *) hdr + hdr->image);
309
310 /* write out the area header, sprite header and image data */
311 error = xosgbpb_writew(fw, (byte*)&file_hdr + 4,
312 sizeof(file_hdr)-4, NULL);
313 if (!error)
314 error = xosgbpb_writew(fw, (byte*)p, image_size, NULL);
315 if (error) {
316 NSLOG(netsurf, INFO, "xosgbpb_writew: 0x%x: %s",
317 error->errnum, error->errmess);
318 free(chunk_buf);
319 xosfind_closew(fw);
320 ro_warn_user("SaveError", error->errmess);
321 return false;
322 }
323
324 /* then write out the mask data in chunks */
325 eip = p + (width * height); /* end of image */
326 elp = p + width; /* end of line */
327
328 while (p < eip) {
329 unsigned char *dp = chunk_buf;
330 unsigned *ep = p + chunk_pix;
331 if (ep > elp) ep = elp;
332
333 if (flags & BITMAP_SAVE_FULL_ALPHA) {
334 while (p < ep) {
335 *dp++ = ((unsigned char*)p)[3];
336 p++;
337 }
338 }
339 else {
340 unsigned char mb = 0;
341 int msh = 0;
342 while (p < ep) {
343 if (((unsigned char*)p)[3]) mb |= (1 << msh);
344 if (++msh >= 8) {
345 *dp++ = mb;
346 msh = 0;
347 mb = 0;
348 }
349 p++;
350 }
351 if (msh > 0) *dp++ = mb;
352 }
353
354 if (p >= elp) { /* end of line yet? */
355 /* align to word boundary */
356 while ((int)dp & 3) *dp++ = 0;
357 /* advance end of line pointer */
358 elp += width;
359 }
360 error = xosgbpb_writew(fw, (byte*)chunk_buf, dp-chunk_buf, NULL);
361 if (error) {
362 NSLOG(netsurf, INFO,
363 "xosgbpb_writew: 0x%x: %s",
364 error->errnum,
365 error->errmess);
366 free(chunk_buf);
367 xosfind_closew(fw);
368 ro_warn_user("SaveError", error->errmess);
369 return false;
370 }
371 }
372
373 error = xosfind_closew(fw);
374 if (error) {
375 NSLOG(netsurf, INFO, "xosfind_closew: 0x%x: %s",
376 error->errnum, error->errmess);
377 ro_warn_user("SaveError", error->errmess);
378 }
379
380 error = xosfile_set_type(path, osfile_TYPE_SPRITE);
381 if (error) {
382 NSLOG(netsurf, INFO, "xosfile_set_type: 0x%x: %s",
383 error->errnum, error->errmess);
384 ro_warn_user("SaveError", error->errmess);
385 }
386
387 free(chunk_buf);
388 return true;
389 }
390}
391
392
393/**
394 * The bitmap image has changed, so flush any persistent cache.
395 *
396 * \param vbitmap a bitmap, as returned by bitmap_create()
397 */
398static void bitmap_modified(void *vbitmap)
399{
400 (void)(vbitmap);
401}
402
403
404/**
405 * Get the width of a bitmap.
406 *
407 * \param vbitmap A bitmap, as returned by bitmap_create()
408 * \return The bitmaps width in pixels.
409 */
410static int bitmap_get_width(void *vbitmap)
411{
412 struct bitmap *bitmap = (struct bitmap *) vbitmap;
413 return bitmap->width;
414}
415
416
417/**
418 * Get the height of a bitmap.
419 *
420 * \param vbitmap A bitmap, as returned by bitmap_create()
421 * \return The bitmaps height in pixels.
422 */
423static int bitmap_get_height(void *vbitmap)
424{
425 struct bitmap *bitmap = (struct bitmap *) vbitmap;
426 return bitmap->height;
427}
428
429
430/* exported interface documented in riscos/bitmap.h */
432 const osspriteop_header *s)
433{
434 const os_colour *palette;
435 const byte *sp, *mp;
436 bool masked = false;
437 bool alpha = false;
438 os_error *error;
439 int dp_offset;
440 int sp_offset;
441 unsigned *dp;
442 int x, y;
443 int w, h;
444
445 assert(sprite_bpp(s) == 8);
446
447 if ((unsigned)s->mode & 0x80000000U)
448 alpha = true;
449
450 error = xosspriteop_read_sprite_info(osspriteop_PTR,
451 (osspriteop_area *)0x100,
452 (osspriteop_id)s,
453 &w, &h, NULL, NULL);
454 if (error) {
455 NSLOG(netsurf, INFO, "xosspriteop_read_sprite_info: 0x%x:%s",
456 error->errnum, error->errmess);
457 return;
458 }
459 sp_offset = ((s->width + 1) * 4) - w;
460
461 if (w > bitmap->width)
462 w = bitmap->width;
463 if (h > bitmap->height)
464 h = bitmap->height;
465
466 dp_offset = bitmap_get_rowstride(bitmap) / 4;
467
468 dp = (void*)riscos_bitmap_get_buffer(bitmap);
469 if (!dp)
470 return;
471 sp = (byte*)s + s->image;
472 mp = (byte*)s + s->mask;
473
474 sp += s->left_bit / 8;
475 mp += s->left_bit / 8;
476
477 if (s->image > (int)sizeof(*s))
478 palette = (os_colour*)(s + 1);
479 else
480 palette = default_palette8;
481
482 if (s->mask != s->image) {
483 masked = true;
485 }
486
487 /* (partially-)transparent pixels in the overlayed sprite retain
488 * their transparency in the output bitmap; opaque sprite pixels
489 * are also propagated to the bitmap, except those which are the
490 * OVERLAY_INDEX colour which allow the original bitmap contents to
491 * show through */
492 for (y = 0; y < h; y++) {
493 unsigned *sdp = dp;
494 for(x = 0; x < w; x++) {
495 os_colour d = ((unsigned)palette[(*sp) << 1]) >> 8;
496 if (*sp++ == OVERLAY_INDEX)
497 d = *dp;
498 if (masked) {
499 if (alpha)
500 d |= ((*mp << 24) ^ 0xff000000U);
501 else if (*mp)
502 d |= 0xff000000U;
503 }
504 *dp++ = d;
505 mp++;
506 }
507 dp = sdp + dp_offset;
508 sp += sp_offset;
509 mp += sp_offset;
510 }
511}
512
513
514/**
515 * Creates an 8bpp canvas.
516 *
517 * \param bitmap the bitmap to clone the size of
518 * \return a sprite area containing an 8bpp sprite
519 */
520static osspriteop_area *thumbnail_create_8bpp(struct bitmap *bitmap)
521{
522 unsigned image_size = ((bitmap->width + 3) & ~3) * bitmap->height;
524 osspriteop_header *sprite_header = NULL;
525 osspriteop_area *sprite_area = NULL;
526 unsigned area_size;
527
528 /* clone the sprite */
529 area_size = sizeof(osspriteop_area) +
530 sizeof(osspriteop_header) +
531 image_size +
532 2048;
533
534 if (!opaque) area_size += image_size;
535
536 sprite_area = (osspriteop_area *)malloc(area_size);
537 if (!sprite_area) {
538 NSLOG(netsurf, INFO, "no memory for malloc()");
539 return NULL;
540 }
541 sprite_area->size = area_size;
542 sprite_area->sprite_count = 1;
543 sprite_area->first = 16;
544 sprite_area->used = area_size;
545 sprite_header = (osspriteop_header *)(sprite_area + 1);
546 sprite_header->size = area_size - sizeof(osspriteop_area);
547 memset(sprite_header->name, 0x00, 12);
548 strcpy(sprite_header->name, "bitmap");
549 sprite_header->left_bit = 0;
550 sprite_header->height = bitmap->height - 1;
551 sprite_header->mode = os_MODE8BPP90X90;
552 sprite_header->right_bit = ((bitmap->width << 3) - 1) & 31;
553 sprite_header->width = ((bitmap->width + 3) >> 2) - 1;
554 sprite_header->image = sizeof(osspriteop_header) + 2048;
555 sprite_header->mask = sizeof(osspriteop_header) + 2048;
556 if (!opaque) sprite_header->mask += image_size;
557
558 /* create the palette. we don't read the necessary size like
559 * we really should as we know it's going to have 256 entries
560 * of 8 bytes = 2048. */
561 xcolourtrans_read_palette((osspriteop_area *)os_MODE8BPP90X90,
562 (osspriteop_id)0,
563 (os_palette *)(sprite_header + 1), 2048,
564 (colourtrans_palette_flags)(1 << 1), 0);
565 return sprite_area;
566}
567
568
569/**
570 * Switches output to the specified sprite and returns the previous context.
571 */
572static struct thumbnail_save_area*
573thumbnail_switch_output(osspriteop_area *sprite_area,
574 osspriteop_header *sprite_header)
575{
577 int size;
578
579 /* create a save area */
580 save_area = calloc(sizeof(struct thumbnail_save_area), 1);
581 if (save_area == NULL) return NULL;
582
583 /* allocate OS_SpriteOp save area */
584 if (xosspriteop_read_save_area_size(osspriteop_PTR, sprite_area,
585 (osspriteop_id)sprite_header, &size)) {
586 free(save_area);
587 return NULL;
588 }
589
590 /* create the save area */
591 save_area->save_area = malloc((unsigned)size);
592 if (save_area->save_area == NULL) {
593 free(save_area);
594 return NULL;
595 }
596 save_area->save_area->a[0] = 0;
597
598 /* switch output to sprite */
599 if (xosspriteop_switch_output_to_sprite(osspriteop_PTR, sprite_area,
600 (osspriteop_id)sprite_header, save_area->save_area,
601 0, &save_area->context1, &save_area->context2,
602 &save_area->context3)) {
603 free(save_area->save_area);
604 free(save_area);
605 return NULL;
606 }
607 return save_area;
608}
609
610
611/**
612 * Restores output to the specified context, and destroys it.
613 */
615{
616 /* we don't care if we err, as there's nothing we can do about it */
617 xosspriteop_switch_output_to_sprite(osspriteop_PTR,
618 (osspriteop_area *)save_area->context1,
619 (osspriteop_id)save_area->context2,
620 (osspriteop_save_area *)save_area->context3,
621 0, 0, 0, 0);
622 free(save_area->save_area);
623 free(save_area);
624}
625
626
627/**
628 * Convert a bitmap to 8bpp.
629 *
630 * \param bitmap the bitmap to convert
631 * \return a sprite area containing an 8bpp sprite
632 */
633osspriteop_area *riscos_bitmap_convert_8bpp(struct bitmap *bitmap)
634{
636 osspriteop_area *sprite_area = NULL;
637 osspriteop_header *sprite_header = NULL;
638
639 sprite_area = thumbnail_create_8bpp(bitmap);
640 if (!sprite_area)
641 return NULL;
642 sprite_header = (osspriteop_header *)(sprite_area + 1);
643
644
645 /* switch output and redraw */
646 save_area = thumbnail_switch_output(sprite_area, sprite_header);
647 if (save_area == NULL) {
649 free(sprite_area);
650 return false;
651 }
652 _swix(Tinct_Plot, _IN(2) | _IN(3) | _IN(4) | _IN(7),
653 (osspriteop_header *)(bitmap->sprite_area + 1),
654 0, 0,
657
658 if (sprite_header->image != sprite_header->mask) {
659 /* build the sprite mask from the alpha channel */
660 void *buf = riscos_bitmap_get_buffer(bitmap);
661 unsigned *dp = (unsigned *) buf;
662 if (!dp)
663 return sprite_area;
664 int w = bitmap_get_width(bitmap);
665 int h = bitmap_get_height(bitmap);
666 int dp_offset = bitmap_get_rowstride(bitmap) / 4 - w;
667 int mp_offset = ((sprite_header->width + 1) * 4) - w;
668 byte *mp = (byte*)sprite_header + sprite_header->mask;
669 bool alpha = ((unsigned)sprite_header->mode & 0x80000000U) != 0;
670
671 while (h-- > 0) {
672 int x = 0;
673 for(x = 0; x < w; x++) {
674 unsigned d = *dp++;
675 if (alpha)
676 *mp++ = (d >> 24) ^ 0xff;
677 else
678 *mp++ = (d < 0xff000000U) ? 0 : 0xff;
679 }
680 dp += dp_offset;
681 mp += mp_offset;
682 }
683 }
684
685 return sprite_area;
686}
687
688
689
690
691/**
692 * Check to see whether 32bpp sprites are available.
693 *
694 * Rather than using Wimp_ReadSysInfo we test if 32bpp sprites are available
695 * in case the user has a 3rd party patch to enable them.
696 */
697static void thumbnail_test(void)
698{
699 unsigned int area_size;
700 osspriteop_area *sprite_area;
701
702 /* try to create a 1x1 32bpp sprite */
703 area_size = sizeof(osspriteop_area) +
704 sizeof(osspriteop_header) + sizeof(int);
705 if ((sprite_area = (osspriteop_area *)malloc(area_size)) == NULL) {
706 NSLOG(netsurf, INFO,
707 "Insufficient memory to perform sprite test.");
708 return;
709 }
710 sprite_area->size = area_size + 1;
711 sprite_area->sprite_count = 0;
712 sprite_area->first = 16;
713 sprite_area->used = 16;
714 if (xosspriteop_create_sprite(osspriteop_NAME, sprite_area,
715 "test", false, 1, 1, (os_mode)tinct_SPRITE_MODE))
717 else
719 free(sprite_area);
720}
721
722
723/* exported interface documented in riscos/bitmap.h */
725 struct hlcache_handle *content)
726{
728 osspriteop_area *sprite_area = NULL;
729 osspriteop_header *sprite_header = NULL;
730 struct redraw_context ctx = {
731 .interactive = false,
732 .background_images = true,
733 .plot = &ro_plotters
734 };
735
736 assert(content);
737 assert(bitmap);
738
739 NSLOG(netsurf, INFO, "content %p in bitmap %p", content, bitmap);
740
741 /* check if we have access to 32bpp sprites natively */
742 if (thumbnail_32bpp_available == -1) {
744 }
745
746 /* if we don't support 32bpp sprites then we redirect to an 8bpp
747 * image and then convert back.
748 */
749 if (thumbnail_32bpp_available != 1) {
750 sprite_area = thumbnail_create_8bpp(bitmap);
751 if (!sprite_area)
752 return false;
753 sprite_header = (osspriteop_header *)(sprite_area + 1);
754 } else {
755 const uint8_t *pixbufp = riscos_bitmap_get_buffer(bitmap);
756 if (!pixbufp || !bitmap->sprite_area)
757 return false;
758 sprite_area = bitmap->sprite_area;
759 sprite_header = (osspriteop_header *)(sprite_area + 1);
760 }
761
762 /* set up the plotters */
765
766 /* switch output and redraw */
767 save_area = thumbnail_switch_output(sprite_area, sprite_header);
768 if (!save_area) {
770 free(sprite_area);
771 return false;
772 }
773 rufl_invalidate_cache();
774 colourtrans_set_gcol(os_COLOUR_WHITE, colourtrans_SET_BG_GCOL,
775 os_ACTION_OVERWRITE, 0);
776
777 /* render the content */
779
781 rufl_invalidate_cache();
782
783 /* if we changed to 8bpp then go back to 32bpp */
784 if (thumbnail_32bpp_available != 1) {
785 const uint8_t *pixbufp = riscos_bitmap_get_buffer(bitmap);
786 _kernel_oserror *error;
787
788 if (!pixbufp || !bitmap->sprite_area) {
789 free(sprite_area);
790 return false;
791 }
792 error = _swix(Tinct_ConvertSprite, _INR(2,3),
793 sprite_header,
794 (osspriteop_header *)(bitmap->sprite_area + 1));
795 free(sprite_area);
796 if (error)
797 return false;
798 }
799
801
802 return NSERROR_OK;
803}
804
807 .destroy = riscos_bitmap_destroy,
808 .set_opaque = bitmap_set_opaque,
809 .get_opaque = riscos_bitmap_get_opaque,
810 .get_buffer = riscos_bitmap_get_buffer,
811 .get_rowstride = bitmap_get_rowstride,
812 .get_width = bitmap_get_width,
813 .get_height = bitmap_get_height,
814 .modified = bitmap_modified,
815 .render = riscos_bitmap_render,
816};
817
static osspriteop_save_area * save_area
The current save area.
Definition: buffer.c:64
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_OK
No error.
Definition: errors.h:30
int bitmap_get_width(void *bitmap)
get width of a bitmap.
Definition: bitmap.c:319
int bitmap_get_height(void *bitmap)
get height of a bitmap.
Definition: bitmap.c:336
static void thumbnail_test(void)
Check to see whether 32bpp sprites are available.
Definition: bitmap.c:697
osspriteop_area * riscos_bitmap_convert_8bpp(struct bitmap *bitmap)
Convert a bitmap to 8bpp.
Definition: bitmap.c:633
static void bitmap_set_opaque(void *vbitmap, bool opaque)
Sets whether a bitmap should be plotted opaque.
Definition: bitmap.c:170
void riscos_bitmap_destroy(void *vbitmap)
Free a bitmap.
Definition: bitmap.c:202
void riscos_bitmap_overlay_sprite(struct bitmap *bitmap, const osspriteop_header *s)
Definition: bitmap.c:431
unsigned char * riscos_bitmap_get_buffer(void *vbitmap)
Return a pointer to the pixel data in a bitmap.
Definition: bitmap.c:145
static struct gui_bitmap_table bitmap_table
Definition: bitmap.c:805
static void bitmap_modified(void *vbitmap)
The bitmap image has changed, so flush any persistent cache.
Definition: bitmap.c:398
static int thumbnail_32bpp_available
Whether we can use 32bpp sprites.
Definition: bitmap.c:65
struct gui_bitmap_table * riscos_bitmap_table
bitmap operations table
Definition: bitmap.c:818
#define OVERLAY_INDEX
Colour in the overlay sprite that allows the bitmap to show through.
Definition: bitmap.c:57
bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags)
Save a bitmap in the platform's native format.
Definition: bitmap.c:218
bool riscos_bitmap_get_opaque(void *vbitmap)
Gets whether a bitmap should be plotted opaque.
Definition: bitmap.c:193
void * riscos_bitmap_create(int width, int height, enum gui_bitmap_flags flags)
Create a bitmap.
Definition: bitmap.c:125
static size_t bitmap_get_rowstride(void *vbitmap)
Find the width of a pixel row in bytes.
Definition: bitmap.c:185
static osspriteop_area * thumbnail_create_8bpp(struct bitmap *bitmap)
Creates an 8bpp canvas.
Definition: bitmap.c:520
nserror riscos_bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content)
Render content into bitmap.
Definition: bitmap.c:724
static struct thumbnail_save_area * thumbnail_switch_output(osspriteop_area *sprite_area, osspriteop_header *sprite_header)
Switches output to the specified sprite and returns the previous context.
Definition: bitmap.c:573
static bool bitmap_initialise(struct bitmap *bitmap)
Initialise a bitmaps sprite area.
Definition: bitmap.c:84
#define SAVE_CHUNK_SIZE
Size of buffer used when constructing mask data to be saved.
Definition: bitmap.c:60
static void thumbnail_restore_output(struct thumbnail_save_area *save_area)
Restores output to the specified context, and destroys it.
Definition: bitmap.c:614
#define BITMAP_SAVE_FULL_ALPHA
save with full alpha channel (if not opaque)
Definition: bitmap.h:33
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
Public content interface.
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
Target independent plotting interface.
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
const char * messages_get(const char *key)
Fast lookup of a message by key from the standard Messages hash.
Definition: messages.c:241
Localised message support (interface).
#define colourtrans_SET_BG_GCOL
After OSLib 6.90, there was a rename of colourtrans defines in order to avoid namespace clashes: svn ...
Definition: oslib_pre7.h:36
const os_colour default_palette8[]
Definition: palettes.c:63
Palette definitions for sprites.
int width
Definition: gui.c:160
nserror ro_warn_user(const char *warning, const char *detail)
Display a warning for a serious problem (eg memory exhaustion).
Definition: gui.c:2077
int height
Definition: gui.c:161
int ro_plot_origin_x
Definition: plotters.c:40
int ro_plot_origin_y
Definition: plotters.c:41
const struct plotter_table ro_plotters
RISC OS plotter operation table.
Definition: plotters.c:727
byte sprite_bpp(const osspriteop_header *s)
Returns the bit depth of a sprite.
Definition: sprite.c:249
Content for image/x-riscos-sprite (RISC OS interface).
Interface to utility string handling.
RISC OS wimp toolkit bitmap.
Definition: bitmap.c:68
bool clear
Whether the bitmap should be initialised to zeros.
Definition: bitmap.h:43
struct osspriteop_area * sprite_area
Uncompressed data, or NULL.
Definition: bitmap.h:45
int width
width of bitmap
Definition: bitmap.c:69
int height
height of bitmap
Definition: bitmap.c:70
bool opaque
Whether the bitmap is opaque.
Definition: bitmap.c:74
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
Redraw context.
Definition: plotters.h:51
bool interactive
Redraw to show interactive features.
Definition: plotters.h:59
Sprite output context saving.
Definition: bitmap.c:70
osspriteop_save_area * save_area
Definition: bitmap.c:71
Tinct SWI numbers and flags for version 0.11.
#define tinct_ERROR_DIFFUSE
Definition: tinct.h:136
#define tinct_SPRITE_MODE
Definition: tinct.h:156
#define Tinct_ConvertSprite
Converts a paletted sprite into its 32bpp equivalent.
Definition: tinct.h:90
#define Tinct_Plot
Plots a sprite at the specified coordinates with a constant 0xff value for the alpha channel,...
Definition: tinct.h:64
Option reading and saving interface.
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
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