diff options
Diffstat (limited to 'riscos/bitmap.c')
-rw-r--r-- | riscos/bitmap.c | 876 |
1 files changed, 0 insertions, 876 deletions
diff --git a/riscos/bitmap.c b/riscos/bitmap.c deleted file mode 100644 index cc4be590c..000000000 --- a/riscos/bitmap.c +++ /dev/null @@ -1,876 +0,0 @@ -/* - * Copyright 2004 James Bursa <bursa@users.sourceforge.net> - * Copyright 2005 Richard Wilson <info@tinct.net> - * Copyright 2008 Adrian Lees <adrianl@users.sourceforge.net> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** - * \file - * RISC OS implementation of bitmap operations. - * - * This implements the interface given by image/bitmap.h using RISC OS - * sprites. - */ - -#include <assert.h> -#include <stdbool.h> -#include <string.h> -#include <swis.h> -#include <rufl.h> -#include <unixlib/local.h> -#include <oslib/colourtrans.h> -#include <oslib/osfile.h> -#include <oslib/osfind.h> -#include <oslib/osgbpb.h> -#include <oslib/osspriteop.h> -#include <oslib/wimp.h> - -#include "utils/nsoption.h" -#include "utils/filename.h" -#include "utils/log.h" -#include "utils/messages.h" -#include "desktop/plotters.h" -#include "content/content.h" -#include "image/bitmap.h" - -#include "riscos/gui.h" -#include "riscos/image.h" -#include "riscos/palettes.h" -#include "riscos/content-handlers/sprite.h" -#include "riscos/tinct.h" -#include "riscos/bitmap.h" - -/** Colour in the overlay sprite that allows the bitmap to show through */ -#define OVERLAY_INDEX 0xfe - -/** Size of buffer used when constructing mask data to be saved */ -#define SAVE_CHUNK_SIZE 4096 - -/** - * Whether we can use 32bpp sprites - */ -static int thumbnail_32bpp_available = -1; - -/** - * Sprite output context saving - */ -struct thumbnail_save_area { - osspriteop_save_area *save_area; - int context1; - int context2; - int context3; -}; - -/** - * Initialise a bitmaps sprite area. - * - * \param bitmap the bitmap to initialise - * \return true if bitmap initialised else false. - */ - -static bool bitmap_initialise(struct bitmap *bitmap) -{ - unsigned int area_size; - osspriteop_area *sprite_area; - osspriteop_header *sprite; - - assert(!bitmap->sprite_area); - - area_size = 16 + 44 + bitmap->width * bitmap->height * 4; - if (bitmap->state & BITMAP_CLEAR_MEMORY) - bitmap->sprite_area = calloc(1, area_size); - else - bitmap->sprite_area = malloc(area_size); - - if (!bitmap->sprite_area) - return false; - - /* area control block */ - sprite_area = bitmap->sprite_area; - sprite_area->size = area_size; - sprite_area->sprite_count = 1; - sprite_area->first = 16; - sprite_area->used = area_size; - - /* sprite control block */ - sprite = (osspriteop_header *) (sprite_area + 1); - sprite->size = area_size - 16; - memset(sprite->name, 0x00, 12); - strncpy(sprite->name, "bitmap", 12); - sprite->width = bitmap->width - 1; - sprite->height = bitmap->height - 1; - sprite->left_bit = 0; - sprite->right_bit = 31; - sprite->image = sprite->mask = 44; - sprite->mode = tinct_SPRITE_MODE; - - return true; -} - - -/* exported interface documented in riscos/bitmap.h */ -void *riscos_bitmap_create(int width, int height, unsigned int state) -{ - struct bitmap *bitmap; - - if (width == 0 || height == 0) - return NULL; - - bitmap = calloc(1, sizeof(struct bitmap)); - if (!bitmap) - return NULL; - bitmap->width = width; - bitmap->height = height; - bitmap->state = state; - - return bitmap; -} - - -/* exported interface documented in riscos/bitmap.h */ -unsigned char *riscos_bitmap_get_buffer(void *vbitmap) -{ - struct bitmap *bitmap = (struct bitmap *) vbitmap; - assert(bitmap); - - /* dynamically create the buffer */ - if (bitmap->sprite_area == NULL) { - if (!bitmap_initialise(bitmap)) - return NULL; - } - - /* image data area should exist */ - if (bitmap->sprite_area) - return ((unsigned char *) (bitmap->sprite_area)) + 16 + 44; - - return NULL; -} - - -/** - * Sets whether a bitmap should be plotted opaque - * - * \param vbitmap a bitmap, as returned by bitmap_create() - * \param opaque whether the bitmap should be plotted opaque - */ -static void bitmap_set_opaque(void *vbitmap, bool opaque) -{ - struct bitmap *bitmap = (struct bitmap *) vbitmap; - assert(bitmap); - - if (opaque) - bitmap->state |= BITMAP_OPAQUE; - else - bitmap->state &= ~BITMAP_OPAQUE; -} - - -/** - * Find the width of a pixel row in bytes. - * - * \param vbitmap A bitmap, as returned by riscos_bitmap_create() - * \return width of a pixel row in the bitmap - */ -static size_t bitmap_get_rowstride(void *vbitmap) -{ - struct bitmap *bitmap = (struct bitmap *) vbitmap; - return bitmap->width * 4; -} - - -/** - * Tests whether a bitmap has an opaque alpha channel - * - * \param vbitmap a bitmap, as returned by bitmap_create() - * \return whether the bitmap is opaque - */ -static bool bitmap_test_opaque(void *vbitmap) -{ - struct bitmap *bitmap = (struct bitmap *) vbitmap; - unsigned char *sprite; - unsigned int width, height, size; - osspriteop_header *sprite_header; - unsigned *p, *ep; - - assert(bitmap); - - sprite = riscos_bitmap_get_buffer(bitmap); - if (!sprite) - return false; - - width = bitmap_get_rowstride(bitmap); - - sprite_header = (osspriteop_header *) (bitmap->sprite_area + 1); - - height = (sprite_header->height + 1); - - size = width * height; - - p = (void *) sprite; - - ep = (void *) (sprite + (size & ~31)); - while (p < ep) { - /* \todo prefetch(p, 128)? */ - if (((p[0] & p[1] & p[2] & p[3] & p[4] & p[5] & p[6] & p[7]) - & 0xff000000U) != 0xff000000U) - return false; - p += 8; - } - - ep = (void *) (sprite + size); - while (p < ep) { - if ((*p & 0xff000000U) != 0xff000000U) return false; - p++; - } - - return true; -} - - -/* exported interface documented in riscos/bitmap.h */ -bool riscos_bitmap_get_opaque(void *vbitmap) -{ - struct bitmap *bitmap = (struct bitmap *) vbitmap; - assert(bitmap); - return (bitmap->state & BITMAP_OPAQUE); -} - - -/* exported interface documented in riscos/bitmap.h */ -void riscos_bitmap_destroy(void *vbitmap) -{ - struct bitmap *bitmap = (struct bitmap *) vbitmap; - - assert(bitmap); - - /* destroy bitmap */ - if (bitmap->sprite_area) { - free(bitmap->sprite_area); - } - - free(bitmap); -} - - -/* exported interface documented in riscos/bitmap.h */ -bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags) -{ - struct bitmap *bitmap = (struct bitmap *) vbitmap; - os_error *error; - - if (bitmap == NULL) { - ro_warn_user("SaveError", messages_get("SprIsNull")); - return false; - } - - if (!bitmap->sprite_area) { - riscos_bitmap_get_buffer(bitmap); - } - if (!bitmap->sprite_area) - return false; - - if (riscos_bitmap_get_opaque(bitmap)) { - error = xosspriteop_save_sprite_file(osspriteop_USER_AREA, - (bitmap->sprite_area), path); - if (error) { - LOG("xosspriteop_save_sprite_file: 0x%x: %s", error->errnum, error->errmess); - ro_warn_user("SaveError", error->errmess); - return false; - } - return true; - } else { - /* to make the saved sprite useful we must convert from 'Tinct' - * format to either a bi-level mask or a Select-style full - * alpha channel */ - osspriteop_area *area = bitmap->sprite_area; - osspriteop_header *hdr = (void *) ((char *) area + area->first); - unsigned width = hdr->width + 1, height = hdr->height + 1; - unsigned image_size = height * width * 4; - unsigned char *chunk_buf; - unsigned *p, *elp, *eip; - unsigned mask_size; - size_t chunk_pix; - struct { - osspriteop_area area; - osspriteop_header hdr; - } file_hdr; - os_fw fw; - - /* we only support 32bpp sprites */ - if ((((unsigned)hdr->mode >> 27)&15) != 6) { - assert(!"Unsupported sprite format in bitmap_save"); - return false; - } - - chunk_buf = malloc(SAVE_CHUNK_SIZE); - if (!chunk_buf) { - ro_warn_user("NoMemory", NULL); - return false; - } - - file_hdr.area = *area; - file_hdr.hdr = *hdr; - - if (flags & BITMAP_SAVE_FULL_ALPHA) { - mask_size = ((width + 3) & ~3) * height; - chunk_pix = SAVE_CHUNK_SIZE; - file_hdr.hdr.mode = (os_mode)((unsigned)file_hdr.hdr.mode - | (1U<<31)); - } else { - mask_size = (((width + 31) & ~31)/8) * height; - chunk_pix = SAVE_CHUNK_SIZE<<3; - file_hdr.hdr.mode = (os_mode)((unsigned)file_hdr.hdr.mode - & ~(1U<<31)); - } - - file_hdr.area.sprite_count = 1; - file_hdr.area.first = sizeof(file_hdr.area); - file_hdr.area.used = sizeof(file_hdr) + image_size + mask_size; - - file_hdr.hdr.image = sizeof(file_hdr.hdr); - file_hdr.hdr.mask = file_hdr.hdr.image + image_size; - file_hdr.hdr.size = file_hdr.hdr.mask + mask_size; - - error = xosfind_openoutw(0, path, NULL, &fw); - if (error) { - LOG("xosfind_openoutw: 0x%x: %s", error->errnum, error->errmess); - free(chunk_buf); - ro_warn_user("SaveError", error->errmess); - return false; - } - - p = (void *) ((char *) hdr + hdr->image); - - /* write out the area header, sprite header and image data */ - error = xosgbpb_writew(fw, (byte*)&file_hdr + 4, - sizeof(file_hdr)-4, NULL); - if (!error) - error = xosgbpb_writew(fw, (byte*)p, image_size, NULL); - if (error) { - LOG("xosgbpb_writew: 0x%x: %s", error->errnum, error->errmess); - free(chunk_buf); - xosfind_closew(fw); - ro_warn_user("SaveError", error->errmess); - return false; - } - - /* then write out the mask data in chunks */ - eip = p + (width * height); /* end of image */ - elp = p + width; /* end of line */ - - while (p < eip) { - unsigned char *dp = chunk_buf; - unsigned *ep = p + chunk_pix; - if (ep > elp) ep = elp; - - if (flags & BITMAP_SAVE_FULL_ALPHA) { - while (p < ep) { - *dp++ = ((unsigned char*)p)[3]; - p++; - } - } - else { - unsigned char mb = 0; - int msh = 0; - while (p < ep) { - if (((unsigned char*)p)[3]) mb |= (1 << msh); - if (++msh >= 8) { - *dp++ = mb; - msh = 0; - mb = 0; - } - p++; - } - if (msh > 0) *dp++ = mb; - } - - if (p >= elp) { /* end of line yet? */ - /* align to word boundary */ - while ((int)dp & 3) *dp++ = 0; - /* advance end of line pointer */ - elp += width; - } - error = xosgbpb_writew(fw, (byte*)chunk_buf, dp-chunk_buf, NULL); - if (error) { - LOG("xosgbpb_writew: 0x%x: %s", error->errnum, error->errmess); - free(chunk_buf); - xosfind_closew(fw); - ro_warn_user("SaveError", error->errmess); - return false; - } - } - - error = xosfind_closew(fw); - if (error) { - LOG("xosfind_closew: 0x%x: %s", error->errnum, error->errmess); - ro_warn_user("SaveError", error->errmess); - } - - error = xosfile_set_type(path, osfile_TYPE_SPRITE); - if (error) { - LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess); - ro_warn_user("SaveError", error->errmess); - } - - free(chunk_buf); - return true; - } -} - - -/** - * The bitmap image has changed, so flush any persistent cache. - * - * \param vbitmap a bitmap, as returned by bitmap_create() - */ -static void bitmap_modified(void *vbitmap) -{ - struct bitmap *bitmap = (struct bitmap *) vbitmap; - bitmap->state |= BITMAP_MODIFIED; -} - - -/** - * Get the width of a bitmap. - * - * \param vbitmap A bitmap, as returned by bitmap_create() - * \return The bitmaps width in pixels. - */ -static int bitmap_get_width(void *vbitmap) -{ - struct bitmap *bitmap = (struct bitmap *) vbitmap; - return bitmap->width; -} - - -/** - * Get the height of a bitmap. - * - * \param vbitmap A bitmap, as returned by bitmap_create() - * \return The bitmaps height in pixels. - */ -static int bitmap_get_height(void *vbitmap) -{ - struct bitmap *bitmap = (struct bitmap *) vbitmap; - return bitmap->height; -} - - -/** - * Find the bytes per pixel of a bitmap - * - * \param vbitmap a bitmap, as returned by bitmap_create() - * \return bytes per pixel - */ -static size_t bitmap_get_bpp(void *vbitmap) -{ - struct bitmap *bitmap = (struct bitmap *)vbitmap; - assert(bitmap); - return 4; -} - - -/* exported interface documented in riscos/bitmap.h */ -void riscos_bitmap_overlay_sprite(struct bitmap *bitmap, - const osspriteop_header *s) -{ - const os_colour *palette; - const byte *sp, *mp; - bool masked = false; - bool alpha = false; - os_error *error; - int dp_offset; - int sp_offset; - unsigned *dp; - int x, y; - int w, h; - - assert(sprite_bpp(s) == 8); - - if ((unsigned)s->mode & 0x80000000U) - alpha = true; - - error = xosspriteop_read_sprite_info(osspriteop_PTR, - (osspriteop_area *)0x100, - (osspriteop_id)s, - &w, &h, NULL, NULL); - if (error) { - LOG("xosspriteop_read_sprite_info: 0x%x:%s", error->errnum, error->errmess); - return; - } - sp_offset = ((s->width + 1) * 4) - w; - - if (w > bitmap->width) - w = bitmap->width; - if (h > bitmap->height) - h = bitmap->height; - - dp_offset = bitmap_get_rowstride(bitmap) / 4; - - dp = (void*)riscos_bitmap_get_buffer(bitmap); - if (!dp) - return; - sp = (byte*)s + s->image; - mp = (byte*)s + s->mask; - - sp += s->left_bit / 8; - mp += s->left_bit / 8; - - if (s->image > (int)sizeof(*s)) - palette = (os_colour*)(s + 1); - else - palette = default_palette8; - - if (s->mask != s->image) { - masked = true; - bitmap_set_opaque(bitmap, false); - } - - /* (partially-)transparent pixels in the overlayed sprite retain - * their transparency in the output bitmap; opaque sprite pixels - * are also propagated to the bitmap, except those which are the - * OVERLAY_INDEX colour which allow the original bitmap contents to - * show through */ - for (y = 0; y < h; y++) { - unsigned *sdp = dp; - for(x = 0; x < w; x++) { - os_colour d = ((unsigned)palette[(*sp) << 1]) >> 8; - if (*sp++ == OVERLAY_INDEX) - d = *dp; - if (masked) { - if (alpha) - d |= ((*mp << 24) ^ 0xff000000U); - else if (*mp) - d |= 0xff000000U; - } - *dp++ = d; - mp++; - } - dp = sdp + dp_offset; - sp += sp_offset; - mp += sp_offset; - } -} - - -/** - * Creates an 8bpp canvas. - * - * \param bitmap the bitmap to clone the size of - * \return a sprite area containing an 8bpp sprite - */ -static osspriteop_area *thumbnail_create_8bpp(struct bitmap *bitmap) -{ - unsigned image_size = ((bitmap->width + 3) & ~3) * bitmap->height; - bool opaque = riscos_bitmap_get_opaque(bitmap); - osspriteop_header *sprite_header = NULL; - osspriteop_area *sprite_area = NULL; - unsigned area_size; - - /* clone the sprite */ - area_size = sizeof(osspriteop_area) + - sizeof(osspriteop_header) + - image_size + - 2048; - - if (!opaque) area_size += image_size; - - sprite_area = (osspriteop_area *)malloc(area_size); - if (!sprite_area) { - LOG("no memory for malloc()"); - return NULL; - } - sprite_area->size = area_size; - sprite_area->sprite_count = 1; - sprite_area->first = 16; - sprite_area->used = area_size; - sprite_header = (osspriteop_header *)(sprite_area + 1); - sprite_header->size = area_size - sizeof(osspriteop_area); - memset(sprite_header->name, 0x00, 12); - strcpy(sprite_header->name, "bitmap"); - sprite_header->left_bit = 0; - sprite_header->height = bitmap->height - 1; - sprite_header->mode = os_MODE8BPP90X90; - sprite_header->right_bit = ((bitmap->width << 3) - 1) & 31; - sprite_header->width = ((bitmap->width + 3) >> 2) - 1; - sprite_header->image = sizeof(osspriteop_header) + 2048; - sprite_header->mask = sizeof(osspriteop_header) + 2048; - if (!opaque) sprite_header->mask += image_size; - - /* create the palette. we don't read the necessary size like - * we really should as we know it's going to have 256 entries - * of 8 bytes = 2048. */ - xcolourtrans_read_palette((osspriteop_area *)os_MODE8BPP90X90, - (osspriteop_id)0, - (os_palette *)(sprite_header + 1), 2048, - (colourtrans_palette_flags)(1 << 1), 0); - return sprite_area; -} - - -/** - * Switches output to the specified sprite and returns the previous context. - */ -static struct thumbnail_save_area* -thumbnail_switch_output(osspriteop_area *sprite_area, - osspriteop_header *sprite_header) -{ - struct thumbnail_save_area *save_area; - int size; - - /* create a save area */ - save_area = calloc(sizeof(struct thumbnail_save_area), 1); - if (save_area == NULL) return NULL; - - /* allocate OS_SpriteOp save area */ - if (xosspriteop_read_save_area_size(osspriteop_PTR, sprite_area, - (osspriteop_id)sprite_header, &size)) { - free(save_area); - return NULL; - } - - /* create the save area */ - save_area->save_area = malloc((unsigned)size); - if (save_area->save_area == NULL) { - free(save_area); - return NULL; - } - save_area->save_area->a[0] = 0; - - /* switch output to sprite */ - if (xosspriteop_switch_output_to_sprite(osspriteop_PTR, sprite_area, - (osspriteop_id)sprite_header, save_area->save_area, - 0, &save_area->context1, &save_area->context2, - &save_area->context3)) { - free(save_area->save_area); - free(save_area); - return NULL; - } - return save_area; -} - - -/** - * Restores output to the specified context, and destroys it. - */ -static void thumbnail_restore_output(struct thumbnail_save_area *save_area) -{ - /* we don't care if we err, as there's nothing we can do about it */ - xosspriteop_switch_output_to_sprite(osspriteop_PTR, - (osspriteop_area *)save_area->context1, - (osspriteop_id)save_area->context2, - (osspriteop_save_area *)save_area->context3, - 0, 0, 0, 0); - free(save_area->save_area); - free(save_area); -} - - -/** - * Convert a bitmap to 8bpp. - * - * \param bitmap the bitmap to convert - * \return a sprite area containing an 8bpp sprite - */ -osspriteop_area *riscos_bitmap_convert_8bpp(struct bitmap *bitmap) -{ - struct thumbnail_save_area *save_area; - osspriteop_area *sprite_area = NULL; - osspriteop_header *sprite_header = NULL; - - sprite_area = thumbnail_create_8bpp(bitmap); - if (!sprite_area) - return NULL; - sprite_header = (osspriteop_header *)(sprite_area + 1); - - - /* switch output and redraw */ - save_area = thumbnail_switch_output(sprite_area, sprite_header); - if (save_area == NULL) { - if (thumbnail_32bpp_available != 1) - free(sprite_area); - return false; - } - _swix(Tinct_Plot, _IN(2) | _IN(3) | _IN(4) | _IN(7), - (osspriteop_header *)(bitmap->sprite_area + 1), - 0, 0, - tinct_ERROR_DIFFUSE); - thumbnail_restore_output(save_area); - - if (sprite_header->image != sprite_header->mask) { - /* build the sprite mask from the alpha channel */ - void *buf = riscos_bitmap_get_buffer(bitmap); - unsigned *dp = (unsigned *) buf; - if (!dp) - return sprite_area; - int w = bitmap_get_width(bitmap); - int h = bitmap_get_height(bitmap); - int dp_offset = bitmap_get_rowstride(bitmap) / 4 - w; - int mp_offset = ((sprite_header->width + 1) * 4) - w; - byte *mp = (byte*)sprite_header + sprite_header->mask; - bool alpha = ((unsigned)sprite_header->mode & 0x80000000U) != 0; - - while (h-- > 0) { - int x = 0; - for(x = 0; x < w; x++) { - unsigned d = *dp++; - if (alpha) - *mp++ = (d >> 24) ^ 0xff; - else - *mp++ = (d < 0xff000000U) ? 0 : 0xff; - } - dp += dp_offset; - mp += mp_offset; - } - } - - return sprite_area; -} - - - - -/** - * Check to see whether 32bpp sprites are available. - * - * Rather than using Wimp_ReadSysInfo we test if 32bpp sprites are available - * in case the user has a 3rd party patch to enable them. - */ -static void thumbnail_test(void) -{ - unsigned int area_size; - osspriteop_area *sprite_area; - - /* try to create a 1x1 32bpp sprite */ - area_size = sizeof(osspriteop_area) + - sizeof(osspriteop_header) + sizeof(int); - if ((sprite_area = (osspriteop_area *)malloc(area_size)) == NULL) { - LOG("Insufficient memory to perform sprite test."); - return; - } - sprite_area->size = area_size + 1; - sprite_area->sprite_count = 0; - sprite_area->first = 16; - sprite_area->used = 16; - if (xosspriteop_create_sprite(osspriteop_NAME, sprite_area, - "test", false, 1, 1, (os_mode)tinct_SPRITE_MODE)) - thumbnail_32bpp_available = 0; - else - thumbnail_32bpp_available = 1; - free(sprite_area); -} - - -/* exported interface documented in riscos/bitmap.h */ -nserror riscos_bitmap_render(struct bitmap *bitmap, - struct hlcache_handle *content) -{ - struct thumbnail_save_area *save_area; - osspriteop_area *sprite_area = NULL; - osspriteop_header *sprite_header = NULL; - struct redraw_context ctx = { - .interactive = false, - .background_images = true, - .plot = &ro_plotters - }; - - assert(content); - assert(bitmap); - - LOG("content %p in bitmap %p", content, bitmap); - - /* check if we have access to 32bpp sprites natively */ - if (thumbnail_32bpp_available == -1) { - thumbnail_test(); - } - - /* if we don't support 32bpp sprites then we redirect to an 8bpp - * image and then convert back. - */ - if (thumbnail_32bpp_available != 1) { - sprite_area = thumbnail_create_8bpp(bitmap); - if (!sprite_area) - return false; - sprite_header = (osspriteop_header *)(sprite_area + 1); - } else { - const uint8_t *pixbufp = riscos_bitmap_get_buffer(bitmap); - if (!pixbufp || !bitmap->sprite_area) - return false; - sprite_area = bitmap->sprite_area; - sprite_header = (osspriteop_header *)(sprite_area + 1); - } - - /* set up the plotters */ - ro_plot_origin_x = 0; - ro_plot_origin_y = bitmap->height * 2; - - /* switch output and redraw */ - save_area = thumbnail_switch_output(sprite_area, sprite_header); - if (!save_area) { - if (thumbnail_32bpp_available != 1) - free(sprite_area); - return false; - } - rufl_invalidate_cache(); - colourtrans_set_gcol(os_COLOUR_WHITE, colourtrans_SET_BG_GCOL, - os_ACTION_OVERWRITE, 0); - - /* render the content */ - content_scaled_redraw(content, bitmap->width, bitmap->height, &ctx); - - thumbnail_restore_output(save_area); - rufl_invalidate_cache(); - - /* if we changed to 8bpp then go back to 32bpp */ - if (thumbnail_32bpp_available != 1) { - const uint8_t *pixbufp = riscos_bitmap_get_buffer(bitmap); - _kernel_oserror *error; - - if (!pixbufp || !bitmap->sprite_area) { - free(sprite_area); - return false; - } - error = _swix(Tinct_ConvertSprite, _INR(2,3), - sprite_header, - (osspriteop_header *)(bitmap->sprite_area + 1)); - free(sprite_area); - if (error) - return false; - } - - bitmap_modified(bitmap); - - return NSERROR_OK; -} - -static struct gui_bitmap_table bitmap_table = { - .create = riscos_bitmap_create, - .destroy = riscos_bitmap_destroy, - .set_opaque = bitmap_set_opaque, - .get_opaque = riscos_bitmap_get_opaque, - .test_opaque = bitmap_test_opaque, - .get_buffer = riscos_bitmap_get_buffer, - .get_rowstride = bitmap_get_rowstride, - .get_width = bitmap_get_width, - .get_height = bitmap_get_height, - .get_bpp = bitmap_get_bpp, - .save = riscos_bitmap_save, - .modified = bitmap_modified, - .render = riscos_bitmap_render, -}; - -struct gui_bitmap_table *riscos_bitmap_table = &bitmap_table; |