home *** CD-ROM | disk | FTP | other *** search
- /* sierra2_4a.c
- * AUTHOR: Cy Booker, cy@cheepnis.demon.co.uk
- * LICENSE: FreeWare, Copyright (c) 1995 Cy Booker
- *
- * filter: * 2
- * 1 1 (1/4)
- */
-
- #include "internal.h"
-
- #include <assert.h>
- #include <string.h> /* memset() */
- #include <stdlib.h> /* calloc() */
-
-
-
- /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- */
-
- extern void process_image_8bpp_sierra2_4a(
- const process_image *p) {
- byte *dest;
- bits *source;
- int width, height;
- int x, y;
- int source_line_length;
- int dest_line_length;
- int *buffer, *this_row, *next_row;
- int buffer_width;
- int red, grn, blu;
- bits colour;
- int error_red, error_grn, error_blu;
- int temp_red, temp_grn, temp_blu;
- rgbtuple error;
- rgbtuple_fn fn;
-
- assert(p);
- assert(p->pixel_width > 0);
- assert(p->pixel_height > 0);
- assert(p->buffer);
- assert(p->fn);
-
- /*
- * sierra2_4a requires storing error info for one pixel to left
- * so we will just allocate one extra column for each row and not do any edge checks
- * each entry is stored as {red, green, blue}
- */
- buffer_width = (p->pixel_width + 1) * 3;
- buffer = xmalloc(sizeof(*buffer) * (buffer_width * 2));
- memset(buffer, 0, sizeof(*buffer) * (buffer_width * 2));
-
- /*
- * not we pre-load values from the process_gif array
- * because it considerably helps the compiler produce better code
- */
- dest = p->buffer;
- source = (bits *)dest;
- width = p->pixel_width;
- height = p->pixel_height;
- source_line_length = p->source_line_length / 4;
- dest_line_length = p->dest_line_length;
- fn = p->fn;
-
- for (y= height; (y > 0); y--) {
- if ((y & 7) == 0) {
- xhourglass_percentage((y * 100) / height);
- }
- this_row = buffer + (buffer_width * ((y + 2) % 2)) + 1*3;
- next_row = buffer + (buffer_width * ((y + 1) % 2)) + 0*3;
- /* bottom row has no errors */
- memset(next_row, 0, sizeof(*next_row) * (buffer_width - 1*3));
- error_red = error_grn = error_blu = 0; /* error along this row */
- /*
- * note that just because we are actually scanning/outputting right to left
- * doesn't matter as far as sierra2_4a is concerned
- * although it might help if we could ``snake''
- */
- for (x= 0; (x < width); x++) {
- INPUT;
-
- red += *this_row++; /* add in errors from other row */
- grn += *this_row++;
- blu += *this_row++;
-
- red += error_red; /* add in errors from this row */
- grn += error_grn;
- blu += error_blu;
-
- PROCESS;
-
- temp_red = red / 4; /* diffuse pixel `below left' */
- temp_grn = grn / 4;
- temp_blu = blu / 4;
- *next_row += temp_red; next_row++;
- *next_row += temp_grn; next_row++;
- *next_row += temp_blu; next_row++;
-
- next_row[0] += temp_red; /* diffuse pixel `below' */
- next_row[1] += temp_grn;
- next_row[2] += temp_blu;
-
- error_red = red - (temp_red * 2); /* diffuse pixel to `right' */
- error_grn = grn - (temp_grn * 2);
- error_blu = blu - (temp_blu * 2);
- }
- source += source_line_length;
- dest += dest_line_length;
- }
- free(buffer);
- }
-
-
-