summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscos/bitmap.c635
1 files changed, 315 insertions, 320 deletions
diff --git a/riscos/bitmap.c b/riscos/bitmap.c
index 9e808c7b1..0f54003a9 100644
--- a/riscos/bitmap.c
+++ b/riscos/bitmap.c
@@ -96,12 +96,321 @@ struct bitmap_compressed_header {
char bitmap_unixname[256];
char bitmap_filename[256];
-static bool bitmap_initialise(struct bitmap *bitmap);
-static void bitmap_decompress(struct bitmap *bitmap);
-static void bitmap_compress(struct bitmap *bitmap);
-static void bitmap_load_file(struct bitmap *bitmap);
-static void bitmap_save_file(struct bitmap *bitmap);
-static void bitmap_delete_file(struct bitmap *bitmap);
+
+
+static void bitmap_delete_file(struct bitmap *bitmap)
+{
+ assert(bitmap->filename[0]);
+ filename_release(bitmap->filename);
+ bitmap->filename[0] = 0;
+}
+
+
+static void bitmap_load_file(struct bitmap *bitmap)
+{
+ int len;
+ fileswitch_object_type obj_type;
+ os_error *error;
+ char *r;
+ struct bitmap_compressed_header *bitmap_compressed;
+ osspriteop_header *bitmap_direct;
+ int *data;
+
+ assert(bitmap->filename);
+
+ sprintf(bitmap_unixname, "%s/%s", TEMP_FILENAME_PREFIX,
+ bitmap->filename);
+ r = __riscosify(bitmap_unixname, 0, __RISCOSIFY_NO_SUFFIX,
+ bitmap_filename, 256, 0);
+ if (r == 0) {
+ LOG(("__riscosify failed"));
+ return;
+ }
+ error = xosfile_read_stamped_no_path(bitmap_filename,
+ &obj_type, 0, 0, &len, 0, 0);
+ if ((error) || (obj_type != fileswitch_IS_FILE))
+ return;
+
+ bitmap->compressed = malloc(len);
+ if (!bitmap->compressed)
+ return;
+
+ error = xosfile_load_stamped_no_path(bitmap_filename,
+ (byte *) bitmap->compressed, 0, 0, 0, 0, 0);
+ if (error) {
+ free(bitmap->compressed);
+ bitmap->compressed = NULL;
+ return;
+ }
+
+ data = (void *) bitmap->compressed;
+
+ LOG(("Loaded file from disk"));
+ /* Sanity check the file we've just loaded:
+ * If it's an uncompressed buffer, then it's a raw sprite area,
+ * including the total size word at the start. Therefore, we check
+ * that:
+ * a) The declared total area size == file length
+ * b) The offset to the first free word == file length
+ * c) There is only 1 sprite in the area
+ * d) The name of the sprite in the area is "bitmap"
+ *
+ * If it's a compressed buffer, then we check that:
+ * a) The declared input size + header size == file length
+ * b) The name of the buffer is "bitmap"
+ *
+ * If it's neither of these, we fail.
+ */
+ if (*data == len && *(data + 3) == len && *(data + 1) == 1 &&
+ strncmp(bitmap->compressed + 20, "bitmap", 6) == 0) {
+ bitmap->sprite_area = (void *) bitmap->compressed;
+ bitmap->compressed = NULL;
+ bitmap_direct = (osspriteop_header *)(bitmap->sprite_area + 1);
+ bitmap->width = bitmap_direct->width + 1;
+ bitmap->height = bitmap_direct->height + 1;
+ bitmap_direct_used += 16 + 44 +
+ bitmap->width * bitmap->height * 4;
+ } else if ((int) (*(data + 6) +
+ sizeof(struct bitmap_compressed_header)) == len &&
+ strncmp(bitmap->compressed + 8, "bitmap", 6) == 0) {
+ bitmap_compressed = (void *) bitmap->compressed;
+ bitmap_compressed_used -= bitmap_compressed->input_size +
+ sizeof(struct bitmap_compressed_header);
+ bitmap->width = bitmap_compressed->width;
+ bitmap->height = bitmap_compressed->height;
+ } else {
+ free(bitmap->compressed);
+ bitmap->compressed = NULL;
+ return;
+ }
+ if (bitmap->state & BITMAP_MODIFIED)
+ bitmap_delete_file(bitmap);
+}
+
+
+static void bitmap_save_file(struct bitmap *bitmap)
+{
+ unsigned int area_size;
+ const char *filename;
+ char *r;
+ os_error *error;
+ struct bitmap_compressed_header *header;
+
+ assert(bitmap);
+
+ if (!bitmap->compressed && !bitmap->sprite_area) {
+ LOG(("bitmap has no data"));
+ return;
+ }
+
+ /* unmodified bitmaps will still have their file available */
+ if ((!(bitmap->state & BITMAP_MODIFIED)) && bitmap->filename[0]) {
+ if (bitmap->sprite_area)
+ free(bitmap->sprite_area);
+ bitmap->sprite_area = NULL;
+ if (bitmap->compressed)
+ free(bitmap->compressed);
+ bitmap->compressed = NULL;
+ return;
+ }
+
+ /* dump the data (compressed or otherwise) to disk */
+ filename = filename_request();
+ if (!filename) {
+ LOG(("filename_request failed"));
+ return;
+ }
+
+ strcpy(bitmap->filename, filename);
+ sprintf(bitmap_unixname, "%s/%s", TEMP_FILENAME_PREFIX,
+ bitmap->filename);
+ r = __riscosify(bitmap_unixname, 0, __RISCOSIFY_NO_SUFFIX,
+ bitmap_filename, 256, 0);
+ if (r == 0) {
+ LOG(("__riscosify failed"));
+ return;
+ }
+ if (bitmap->compressed) {
+ header = (void *) bitmap->compressed;
+ area_size = header->input_size +
+ sizeof(struct bitmap_compressed_header);
+ error = xosfile_save_stamped(bitmap_filename, 0xffd,
+ (byte *) bitmap->compressed,
+ (byte *) bitmap->compressed + area_size);
+ } else {
+ area_size = bitmap->width * bitmap->height * 4 +
+ sizeof(osspriteop_header) +
+ sizeof(osspriteop_area);
+ error = xosfile_save_stamped(bitmap_filename, 0xffd,
+ (byte *) bitmap->sprite_area,
+ ((byte *) bitmap->sprite_area) + area_size);
+ }
+
+ if (error) {
+ LOG(("xosfile_save_stamped: 0x%x: %s",
+ error->errnum, error->errmess));
+ bitmap->filename[0] = 0;
+ } else {
+ if (bitmap->sprite_area) {
+ bitmap_direct_used -= area_size;
+ free(bitmap->sprite_area);
+ }
+ bitmap->sprite_area = NULL;
+ if (bitmap->compressed) {
+ bitmap_compressed_used -= area_size;
+ free(bitmap->compressed);
+ }
+ bitmap->compressed = NULL;
+ bitmap->state &= ~BITMAP_MODIFIED;
+ LOG(("Saved file to disk"));
+ }
+}
+
+
+/**
+ * Initialise a bitmaps sprite area.
+ *
+ * \param bitmap the bitmap to initialise
+ * \param clear whether to clear the image ready for use
+ */
+
+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;
+ bitmap->state |= BITMAP_READY;
+ bitmap_direct_used += area_size;
+
+ /* 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;
+
+ bitmap_maintenance = true;
+ bitmap_maintenance_priority |=
+ (bitmap_direct_used > bitmap_direct_size * 0.9);
+ return true;
+}
+
+
+static void bitmap_decompress(struct bitmap *bitmap)
+{
+ unsigned int area_size;
+ _kernel_oserror *error;
+ int output_size;
+ struct bitmap_compressed_header *header;
+
+ assert(bitmap->compressed);
+
+ /* ensure the width/height is correct */
+ header = (void *)bitmap->compressed;
+ if ((header->width != bitmap->width) ||
+ (header->height != bitmap->height)) {
+ LOG(("Warning: Mismatch between bitmap and compressed sizes"));
+ return;
+ }
+
+ /* create the image memory/header to decompress to */
+ if (!bitmap_initialise(bitmap))
+ return;
+
+ /* decompress the data */
+ output_size = bitmap->width * bitmap->height * 4 +
+ sizeof(struct osspriteop_header);
+ error = _swix(Tinct_Decompress, _IN(0) | _IN(2) | _IN(3) | _IN(7),
+ bitmap->compressed,
+ (char *)(bitmap->sprite_area + 1),
+ output_size,
+ 0);
+ if (error) {
+ LOG(("Decompression error"));
+ free(bitmap->sprite_area);
+ bitmap->sprite_area = NULL;
+ } else {
+ LOG(("Decompressed"));
+ area_size = header->input_size +
+ sizeof(struct bitmap_compressed_header);
+ bitmap_compressed_used -= area_size;
+ free(bitmap->compressed);
+ bitmap->compressed = NULL;
+ area_size = 16 + 44 + bitmap->width * bitmap->height * 4;
+ bitmap_direct_used += area_size;
+ }
+}
+
+
+static void bitmap_compress(struct bitmap *bitmap)
+{
+ unsigned int area_size;
+ _kernel_oserror *error;
+ char *output;
+ unsigned int output_size, new_size;
+ unsigned int flags = 0;
+ float calc;
+
+ /* get the maximum output size (33/32 * size) */
+ output_size = ((bitmap->width * bitmap->height * 4 * 33) >> 5) +
+ sizeof(struct bitmap_compressed_header);
+ output = malloc(output_size);
+ if (!output)
+ return;
+
+ /* compress the data */
+ if (bitmap->state & BITMAP_OPAQUE)
+ flags |= tinct_OPAQUE_IMAGE;
+ error = _swix(Tinct_Compress, _IN(0) | _IN(2) | _IN(7) | _OUT(0),
+ (char *)(bitmap->sprite_area + 1),
+ output,
+ flags,
+ &new_size);
+ if (error) {
+ LOG(("Compression error"));
+ free(output);
+ } else {
+ bitmap->compressed = realloc(output, new_size);
+ if (!bitmap->compressed) {
+ free(output);
+ } else {
+ bitmap_compressed_used += new_size;
+ if (bitmap->sprite_area) {
+ area_size = 16 + 44 + bitmap->width *
+ bitmap->height * 4;
+ bitmap_direct_used -= area_size;
+ free(bitmap->sprite_area);
+ }
+ bitmap->sprite_area = NULL;
+ calc = (100 / (float)output_size) * new_size;
+ LOG(("Compression: %i->%i, %.3f%%",
+ output_size, new_size, calc));
+ }
+ }
+}
/**
@@ -297,58 +606,6 @@ void bitmap_overlay_sprite(struct bitmap *bitmap, const osspriteop_header *s)
/**
- * Initialise a bitmaps sprite area.
- *
- * \param bitmap the bitmap to initialise
- * \param clear whether to clear the image ready for use
- */
-
-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;
- bitmap->state |= BITMAP_READY;
- bitmap_direct_used += area_size;
-
- /* 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;
-
- bitmap_maintenance = true;
- bitmap_maintenance_priority |=
- (bitmap_direct_used > bitmap_direct_size * 0.9);
- return true;
-}
-
-
-/**
* Sets whether a bitmap should be plotted opaque
*
* \param bitmap a bitmap, as returned by bitmap_create()
@@ -812,268 +1069,6 @@ void bitmap_maintain(void)
}
-void bitmap_decompress(struct bitmap *bitmap)
-{
- unsigned int area_size;
- _kernel_oserror *error;
- int output_size;
- struct bitmap_compressed_header *header;
-
- assert(bitmap->compressed);
-
- /* ensure the width/height is correct */
- header = (void *)bitmap->compressed;
- if ((header->width != bitmap->width) ||
- (header->height != bitmap->height)) {
- LOG(("Warning: Mismatch between bitmap and compressed sizes"));
- return;
- }
-
- /* create the image memory/header to decompress to */
- if (!bitmap_initialise(bitmap))
- return;
-
- /* decompress the data */
- output_size = bitmap->width * bitmap->height * 4 +
- sizeof(struct osspriteop_header);
- error = _swix(Tinct_Decompress, _IN(0) | _IN(2) | _IN(3) | _IN(7),
- bitmap->compressed,
- (char *)(bitmap->sprite_area + 1),
- output_size,
- 0);
- if (error) {
- LOG(("Decompression error"));
- free(bitmap->sprite_area);
- bitmap->sprite_area = NULL;
- } else {
- LOG(("Decompressed"));
- area_size = header->input_size +
- sizeof(struct bitmap_compressed_header);
- bitmap_compressed_used -= area_size;
- free(bitmap->compressed);
- bitmap->compressed = NULL;
- area_size = 16 + 44 + bitmap->width * bitmap->height * 4;
- bitmap_direct_used += area_size;
- }
-}
-
-
-void bitmap_compress(struct bitmap *bitmap)
-{
- unsigned int area_size;
- _kernel_oserror *error;
- char *output;
- unsigned int output_size, new_size;
- unsigned int flags = 0;
- float calc;
-
- /* get the maximum output size (33/32 * size) */
- output_size = ((bitmap->width * bitmap->height * 4 * 33) >> 5) +
- sizeof(struct bitmap_compressed_header);
- output = malloc(output_size);
- if (!output)
- return;
-
- /* compress the data */
- if (bitmap->state & BITMAP_OPAQUE)
- flags |= tinct_OPAQUE_IMAGE;
- error = _swix(Tinct_Compress, _IN(0) | _IN(2) | _IN(7) | _OUT(0),
- (char *)(bitmap->sprite_area + 1),
- output,
- flags,
- &new_size);
- if (error) {
- LOG(("Compression error"));
- free(output);
- } else {
- bitmap->compressed = realloc(output, new_size);
- if (!bitmap->compressed) {
- free(output);
- } else {
- bitmap_compressed_used += new_size;
- if (bitmap->sprite_area) {
- area_size = 16 + 44 + bitmap->width *
- bitmap->height * 4;
- bitmap_direct_used -= area_size;
- free(bitmap->sprite_area);
- }
- bitmap->sprite_area = NULL;
- calc = (100 / (float)output_size) * new_size;
- LOG(("Compression: %i->%i, %.3f%%",
- output_size, new_size, calc));
- }
- }
-}
-
-void bitmap_load_file(struct bitmap *bitmap)
-{
- int len;
- fileswitch_object_type obj_type;
- os_error *error;
- char *r;
- struct bitmap_compressed_header *bitmap_compressed;
- osspriteop_header *bitmap_direct;
- int *data;
-
- assert(bitmap->filename);
-
- sprintf(bitmap_unixname, "%s/%s", TEMP_FILENAME_PREFIX,
- bitmap->filename);
- r = __riscosify(bitmap_unixname, 0, __RISCOSIFY_NO_SUFFIX,
- bitmap_filename, 256, 0);
- if (r == 0) {
- LOG(("__riscosify failed"));
- return;
- }
- error = xosfile_read_stamped_no_path(bitmap_filename,
- &obj_type, 0, 0, &len, 0, 0);
- if ((error) || (obj_type != fileswitch_IS_FILE))
- return;
-
- bitmap->compressed = malloc(len);
- if (!bitmap->compressed)
- return;
-
- error = xosfile_load_stamped_no_path(bitmap_filename,
- (byte *) bitmap->compressed, 0, 0, 0, 0, 0);
- if (error) {
- free(bitmap->compressed);
- bitmap->compressed = NULL;
- return;
- }
-
- data = (void *) bitmap->compressed;
-
- LOG(("Loaded file from disk"));
- /* Sanity check the file we've just loaded:
- * If it's an uncompressed buffer, then it's a raw sprite area,
- * including the total size word at the start. Therefore, we check
- * that:
- * a) The declared total area size == file length
- * b) The offset to the first free word == file length
- * c) There is only 1 sprite in the area
- * d) The name of the sprite in the area is "bitmap"
- *
- * If it's a compressed buffer, then we check that:
- * a) The declared input size + header size == file length
- * b) The name of the buffer is "bitmap"
- *
- * If it's neither of these, we fail.
- */
- if (*data == len && *(data + 3) == len && *(data + 1) == 1 &&
- strncmp(bitmap->compressed + 20, "bitmap", 6) == 0) {
- bitmap->sprite_area = (void *) bitmap->compressed;
- bitmap->compressed = NULL;
- bitmap_direct = (osspriteop_header *)(bitmap->sprite_area + 1);
- bitmap->width = bitmap_direct->width + 1;
- bitmap->height = bitmap_direct->height + 1;
- bitmap_direct_used += 16 + 44 +
- bitmap->width * bitmap->height * 4;
- } else if ((int) (*(data + 6) +
- sizeof(struct bitmap_compressed_header)) == len &&
- strncmp(bitmap->compressed + 8, "bitmap", 6) == 0) {
- bitmap_compressed = (void *) bitmap->compressed;
- bitmap_compressed_used -= bitmap_compressed->input_size +
- sizeof(struct bitmap_compressed_header);
- bitmap->width = bitmap_compressed->width;
- bitmap->height = bitmap_compressed->height;
- } else {
- free(bitmap->compressed);
- bitmap->compressed = NULL;
- return;
- }
- if (bitmap->state & BITMAP_MODIFIED)
- bitmap_delete_file(bitmap);
-}
-
-
-void bitmap_save_file(struct bitmap *bitmap)
-{
- unsigned int area_size;
- const char *filename;
- char *r;
- os_error *error;
- struct bitmap_compressed_header *header;
-
- assert(bitmap);
-
- if (!bitmap->compressed && !bitmap->sprite_area) {
- LOG(("bitmap has no data"));
- return;
- }
-
- /* unmodified bitmaps will still have their file available */
- if ((!(bitmap->state & BITMAP_MODIFIED)) && bitmap->filename[0]) {
- if (bitmap->sprite_area)
- free(bitmap->sprite_area);
- bitmap->sprite_area = NULL;
- if (bitmap->compressed)
- free(bitmap->compressed);
- bitmap->compressed = NULL;
- return;
- }
-
- /* dump the data (compressed or otherwise) to disk */
- filename = filename_request();
- if (!filename) {
- LOG(("filename_request failed"));
- return;
- }
-
- strcpy(bitmap->filename, filename);
- sprintf(bitmap_unixname, "%s/%s", TEMP_FILENAME_PREFIX,
- bitmap->filename);
- r = __riscosify(bitmap_unixname, 0, __RISCOSIFY_NO_SUFFIX,
- bitmap_filename, 256, 0);
- if (r == 0) {
- LOG(("__riscosify failed"));
- return;
- }
- if (bitmap->compressed) {
- header = (void *) bitmap->compressed;
- area_size = header->input_size +
- sizeof(struct bitmap_compressed_header);
- error = xosfile_save_stamped(bitmap_filename, 0xffd,
- (byte *) bitmap->compressed,
- (byte *) bitmap->compressed + area_size);
- } else {
- area_size = bitmap->width * bitmap->height * 4 +
- sizeof(osspriteop_header) +
- sizeof(osspriteop_area);
- error = xosfile_save_stamped(bitmap_filename, 0xffd,
- (byte *) bitmap->sprite_area,
- ((byte *) bitmap->sprite_area) + area_size);
- }
-
- if (error) {
- LOG(("xosfile_save_stamped: 0x%x: %s",
- error->errnum, error->errmess));
- bitmap->filename[0] = 0;
- } else {
- if (bitmap->sprite_area) {
- bitmap_direct_used -= area_size;
- free(bitmap->sprite_area);
- }
- bitmap->sprite_area = NULL;
- if (bitmap->compressed) {
- bitmap_compressed_used -= area_size;
- free(bitmap->compressed);
- }
- bitmap->compressed = NULL;
- bitmap->state &= ~BITMAP_MODIFIED;
- LOG(("Saved file to disk"));
- }
-}
-
-
-void bitmap_delete_file(struct bitmap *bitmap)
-{
- assert(bitmap->filename[0]);
- filename_release(bitmap->filename);
- bitmap->filename[0] = 0;
-}
-
-
int bitmap_get_width(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *) vbitmap;