home *** CD-ROM | disk | FTP | other *** search
- /* process.c
- * MACHINE: RISC OS 3.60
- * LANGUAGE: Acorn C v5.06
- * AUTHOR: Cy Booker <cy@cheepnis.demon.co.uk>
- * LICENCE: Freeware, Copyright (c) 1996 Cy Booker
- */
-
- #include "process.h"
-
-
- #include <assert.h>
- #include <ctype.h>
- #include <limits.h>
- #include <locale.h>
- #include <math.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
-
- #include "OS:colourtrans.h"
- #include "OS:hourglass.h"
- #include "OS:jpeg.h"
- #include "OS:macros.h"
- #include "OS:osfile.h"
- #include "OS:osspriteop.h"
-
-
- #include "internal.h"
-
-
- #include "OS:osfile.h"
-
- /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- */
-
- #define XDPI (90)
- #define YDPI (90)
-
-
- /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- */
-
- #define MODE(LOG2BPP, XRES, YRES) ((os_mode)(\
- (((LOG2BPP) + 1) << osspriteop_TYPE_SHIFT)\
- | ((XRES) << osspriteop_YRES_SHIFT)\
- | ((YRES) << osspriteop_XRES_SHIFT)\
- | 1))
-
- #define LSR(X, S) (((unsigned int)(X)) >> (S)) /* portable */
-
- #define WORD_WIDTH(P) LSR((P) + 31, 5) /* P is BIT width */
-
-
- /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- */
-
-
- rgbtuple default_wimp_palette_as_tuples[256];
-
- /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- */
-
-
- static void inline_reduce_sprite_to_8bpp(
- osspriteop_area *area,
- const char *sprite_name);
-
- /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- */
-
- /*
- * actually, the current JPEG renderer ignores the source DPI
- * when rendering, so keep scale factors as constant
- */
-
- extern void process(
- const char *source_file_name,
- const char *dest_file_name) {
- os_error *error;
- int c0, c1, c2, c3;
- osspriteop_area *area;
- os_mode mode;
- jpeg_info_flags flags;
- int width, height, xdpi, ydpi, workspace_size;
- int lb_bpp;
- int line_length;
- size_t area_size;
- char sprite_name[osspriteop_NAME_LIMIT+1];
-
- assert(source_file_name);
- assert(dest_file_name);
-
- {
- const char *name;
- int len;
- int i;
-
- name = strrchr(source_file_name, '.');
- if (!name) {
- name = strrchr(source_file_name, ':');
- }
- if (!name) {
- name = source_file_name;
- } else {
- name++;
- }
- len = strlen(name);
- if (len > osspriteop_NAME_LIMIT) {
- name += len - osspriteop_NAME_LIMIT;
- }
- for (i= 0; (name[i]); i++) {
- sprite_name[i] = tolower(name[i]);
- }
- sprite_name[i] = '\0';
- }
-
- flags = jpegfileinfo_dimensions(
- source_file_name,
- &width, &height,
- &xdpi, &ydpi,
- &workspace_size);
-
- lb_bpp = 5;
-
- line_length = 4 * WORD_WIDTH(width * (1 << lb_bpp));
-
- mode = MODE(lb_bpp, XDPI, YDPI);
-
- area_size = sizeof(osspriteop_area)
- + sizeof (osspriteop_header)
- + 0 /*palette_size*/
- + (line_length * height)
- + 0 /*mask size*/;
-
- area = xmalloc(area_size);
-
- area->size = area_size;
- area->first = sizeof(osspriteop_area);
- osspriteop_clear_sprites(osspriteop_USER_AREA, area);
- osspriteop_create_sprite(
- osspriteop_NAME,
- area,
- sprite_name,
- FALSE, /* no palette */
- width,
- height,
- mode);
- xhourglass_on();
- osspriteop_switch_output_to_sprite(
- osspriteop_NAME,
- area,
- (osspriteop_id)sprite_name,
- NULL, /* use system save area */
- &c0, &c1, &c2, &c3);
- {
- error = xcolourtrans_invalidate_cache();
- if (error) goto recover;
-
- error = xjpeg_plot_file_scaled(source_file_name, 0, 0, NULL, 0);
- if (error) goto recover;
- }
- osspriteop_unswitch_output(c0, c1, c2, c3);
- colourtrans_invalidate_cache();
-
- inline_reduce_sprite_to_8bpp(area, sprite_name);
-
- osspriteop_save_sprite_file(osspriteop_USER_AREA, area, dest_file_name);
- xhourglass_off();
- free (area);
- return;
- recover:
- xosspriteop_unswitch_output(c0, c1, c2, c3);
- xhourglass_off();
- os_generate_error(error);
- }
-
-
- /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- */
-
-
- static void inline_reduce_sprite_to_8bpp(
- osspriteop_area *area,
- const char *sprite_name) {
- osspriteop_header *sprite;
- int width;
- int height;
- int line_length;
- process_image p;
- int size;
- int delta;
- char *base = (char *)area;
- int sprite_offset;
- int eof_sprite;
- int nbytes_above;
- int bpp;
- int ppw;
-
- assert(area);
- assert(sprite_name);
-
- sprite = osspriteop_select_sprite(
- osspriteop_NAME,
- area,
- (osspriteop_id)sprite_name);
- assert(sprite);
-
- width = sprite->width + 1;
- height = sprite->height + 1;
- line_length = ALIGN(width);
- p.pixel_width = width;
- p.pixel_height = height;
- p.source_line_length = width * 4;
- p.dest_line_length = line_length;
- p.buffer = (byte *)(((char *)sprite) + sprite->image);
- p.fn = map_scaled_rgb_to_8bpp_colour_number_changefsi;
-
- {
- int red, grn, blu, tnt, idx;
-
- for (idx= 0; (idx < 256); idx++) {
- /* idx == %BGgRbrTt */
- red = ((idx & 0x10) >> 1) | ((idx & 0x04) >> 0);
- grn = ((idx & 0x40) >> 3) | ((idx & 0x20) >> 3);
- blu = ((idx & 0x80) >> 4) | ((idx & 0x08) >> 1);
- tnt = idx & 0x03;
- red |= tnt; red |= red << 4; red |= red << 8; /* expand 4 bit -> 16 bit */
- grn |= tnt; grn |= grn << 4; grn |= grn << 8;
- blu |= tnt; blu |= blu << 4; blu |= blu << 8;
- default_wimp_palette_as_tuples[idx].red = red;
- default_wimp_palette_as_tuples[idx].grn = grn;
- default_wimp_palette_as_tuples[idx].blu = blu;
- }
- }
- xhourglass_on();
-
- /*process_image_8bpp_floyd_steinberg(&p);*/
- process_image_8bpp_sierra2_4a(&p);
- /*process_image_8bpp_sierra3(&p);*/
- /*process_image_8bpp_nearest(&p);*/
- xhourglass_off();
-
- size = (height * line_length) + sizeof(*sprite);
- delta = size - sprite->size;
-
- sprite_offset = ((char *)sprite) - base;
- eof_sprite = sprite_offset + sprite->size;
- nbytes_above = area->used - eof_sprite;
- if (nbytes_above > 0) {
- memmove(base + eof_sprite, base + sprite_offset + size, nbytes_above);
- }
-
- bpp = 8;
- ppw = 32 / bpp;
- sprite->right_bit = 31 - (bpp * (width % ppw)); /* and must do this! */
- sprite->width = (line_length / 4) - 1;
- sprite->mode = os_MODE8BPP90X90;
- sprite->size += delta;
- area->used += delta;
-
- osspriteop_verify_area(osspriteop_USER_AREA, area);
- }
-
-