/* * This file is part of NetSurf, http://netsurf.sourceforge.net/ * Licensed under the GNU General Public License, * http://www.opensource.org/licenses/gpl-license * Copyright 2004 James Bursa */ /** \file * Generic bitmap handling (RISC OS implementation). * * This implements the interface given by desktop/bitmap.h using RISC OS * sprites. */ #include #include #include #include "oslib/osspriteop.h" #include "netsurf/content/content.h" #include "netsurf/image/bitmap.h" #include "netsurf/riscos/bitmap.h" #include "netsurf/riscos/image.h" #include "netsurf/utils/log.h" #include "netsurf/utils/utils.h" /** * Create a bitmap. * * \param width width of image in pixels * \param height width of image in pixels * \param clear whether to clear the image ready for use * \return an opaque struct bitmap, or NULL on memory exhaustion */ struct bitmap *bitmap_create(int width, int height, bool clear) { unsigned int area_size; struct bitmap *bitmap; osspriteop_area *sprite_area; osspriteop_header *sprite; if (width == 0 || height == 0) return NULL; area_size = 16 + 44 + width * height * 4; if (clear) bitmap = calloc(sizeof(struct bitmap) + area_size, 1); else bitmap = malloc(sizeof(struct bitmap) + area_size); if (!bitmap) return NULL; bitmap->width = width; bitmap->height = height; bitmap->opaque = 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; if (!clear) memset(sprite->name, 0x00, 12); strncpy(sprite->name, "bitmap", 12); sprite->width = width - 1; sprite->height = height - 1; sprite->left_bit = 0; sprite->right_bit = 31; sprite->image = sprite->mask = 44; sprite->mode = (os_mode) 0x301680b5; return bitmap; } /** * Sets whether a bitmap should be plotted opaque * * \param bitmap a bitmap, as returned by bitmap_create() * \param opaque whether the bitmap should be plotted opaque */ void bitmap_set_opaque(struct bitmap *bitmap, bool opaque) { assert(bitmap); bitmap->opaque = opaque; } /** * Tests whether a bitmap has an opaque alpha channel * * \param bitmap a bitmap, as returned by bitmap_create() * \return whether the bitmap is opaque */ bool bitmap_test_opaque(struct bitmap *bitmap) { assert(bitmap); char *sprite = bitmap_get_buffer(bitmap); unsigned int width = bitmap_get_rowstride(bitmap); osspriteop_header *sprite_header = (osspriteop_header *) (&(bitmap->sprite_area) + 1); unsigned int height = (sprite_header->height + 1); unsigned int size = width * height; unsigned *p = (unsigned*)sprite; unsigned *ep; ep = (unsigned*)(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 = (unsigned*)(sprite + size); while (p < ep) { if ((*p & 0xff000000U) != 0xff000000U) return false; p++; } return true; } /** * Gets whether a bitmap should be plotted opaque * * \param bitmap a bitmap, as returned by bitmap_create() */ bool bitmap_get_opaque(struct bitmap *bitmap) { assert(bitmap); return (bitmap->opaque); } /** * Return a pointer to the pixel data in a bitmap. * * \param bitmap a bitmap, as returned by bitmap_create() * \return pointer to the pixel buffer * * The pixel data is packed as BITMAP_FORMAT, possibly with padding at the end * of rows. The width of a row in bytes is given by bitmap_get_rowstride(). */ char *bitmap_get_buffer(struct bitmap *bitmap) { assert(bitmap); return ((char *) (&(bitmap->sprite_area))) + 16 + 44; } /** * Find the width of a pixel row in bytes. * * \param bitmap a bitmap, as returned by bitmap_create() * \return width of a pixel row in the bitmap */ size_t bitmap_get_rowstride(struct bitmap *bitmap) { osspriteop_header *sprite; assert(bitmap); sprite = (osspriteop_header *) (&(bitmap->sprite_area) + 1); return (sprite->width + 1) * 4; } /** * Free a bitmap. * * \param bitmap a bitmap, as returned by bitmap_create() */ void bitmap_destroy(struct bitmap *bitmap) { assert(bitmap); free(bitmap); } /** * Save a bitmap in the platform's native format. * * \param bitmap a bitmap, as returned by bitmap_create() * \param path pathname for file * \return true on success, false on error and error reported */ bool bitmap_save(struct bitmap *bitmap, const char *path) { os_error *error; 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)); warn_user("SaveError", error->errmess); return false; } return true; }