home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / utilities / utilsm / randjpeg / source / c / sierra2_4a < prev    next >
Encoding:
Text File  |  1995-12-27  |  3.5 KB  |  113 lines

  1. /* sierra2_4a.c
  2.  * AUTHOR:      Cy Booker, cy@cheepnis.demon.co.uk
  3.  * LICENSE:     FreeWare, Copyright (c) 1995 Cy Booker
  4.  *
  5.  * filter:              *  2
  6.  *                   1  1               (1/4)
  7.  */
  8.  
  9. #include "internal.h"
  10.  
  11. #include <assert.h>
  12. #include <string.h>             /* memset() */
  13. #include <stdlib.h>             /* calloc() */
  14.  
  15.  
  16.  
  17. /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  18.  */
  19.  
  20. extern void process_image_8bpp_sierra2_4a(
  21.                 const process_image     *p) {
  22.   byte                  *dest;
  23.   bits                  *source;
  24.   int                   width, height;
  25.   int                   x, y;
  26.   int                   source_line_length;
  27.   int                   dest_line_length;
  28.   int                   *buffer, *this_row, *next_row;
  29.   int                   buffer_width;
  30.   int                   red, grn, blu;
  31.   bits                  colour;
  32.   int                   error_red, error_grn, error_blu;
  33.   int                   temp_red, temp_grn, temp_blu;
  34.   rgbtuple              error;
  35.   rgbtuple_fn           fn;
  36.  
  37.   assert(p);
  38.   assert(p->pixel_width > 0);
  39.   assert(p->pixel_height > 0);
  40.   assert(p->buffer);
  41.   assert(p->fn);
  42.  
  43.   /*
  44.    * sierra2_4a requires storing error info for one pixel to left
  45.    * so we will just allocate one extra column for each row and not do any edge checks
  46.    * each entry is stored as {red, green, blue}
  47.    */
  48.   buffer_width = (p->pixel_width + 1) * 3;
  49.   buffer = xmalloc(sizeof(*buffer) * (buffer_width * 2));
  50.   memset(buffer, 0, sizeof(*buffer) * (buffer_width * 2));
  51.  
  52.   /*
  53.    * not we pre-load values from the process_gif array
  54.    * because it considerably helps the compiler produce better code
  55.    */
  56.   dest = p->buffer;
  57.   source = (bits *)dest;
  58.   width = p->pixel_width;
  59.   height = p->pixel_height;
  60.   source_line_length = p->source_line_length / 4;
  61.   dest_line_length = p->dest_line_length;
  62.   fn = p->fn;
  63.  
  64.   for (y= height; (y > 0); y--) {
  65.     if ((y & 7) == 0) {
  66.       xhourglass_percentage((y * 100) / height);
  67.     }
  68.     this_row = buffer + (buffer_width * ((y + 2) % 2)) + 1*3;
  69.     next_row = buffer + (buffer_width * ((y + 1) % 2)) + 0*3;
  70.     /* bottom row has no errors */
  71.     memset(next_row, 0, sizeof(*next_row) * (buffer_width - 1*3));
  72.     error_red = error_grn = error_blu = 0;                      /* error along this row */
  73.     /*
  74.      * note that just because we are actually scanning/outputting right to left
  75.      * doesn't matter as far as sierra2_4a is concerned
  76.      * although it might help if we could ``snake''
  77.      */
  78.     for (x= 0; (x < width); x++) {
  79.       INPUT;
  80.  
  81.       red += *this_row++;                               /* add in errors from other row */
  82.       grn += *this_row++;
  83.       blu += *this_row++;
  84.  
  85.       red += error_red;                                 /* add in errors from this row */
  86.       grn += error_grn;
  87.       blu += error_blu;
  88.  
  89.       PROCESS;
  90.  
  91.       temp_red = red / 4;                               /* diffuse pixel `below left' */
  92.       temp_grn = grn / 4;
  93.       temp_blu = blu / 4;
  94.       *next_row += temp_red; next_row++;
  95.       *next_row += temp_grn; next_row++;
  96.       *next_row += temp_blu; next_row++;
  97.  
  98.       next_row[0] += temp_red;                          /* diffuse pixel `below' */
  99.       next_row[1] += temp_grn;
  100.       next_row[2] += temp_blu;
  101.  
  102.       error_red = red - (temp_red * 2);                 /* diffuse pixel to `right' */
  103.       error_grn = grn - (temp_grn * 2);
  104.       error_blu = blu - (temp_blu * 2);
  105.     }
  106.     source += source_line_length;
  107.     dest += dest_line_length;
  108.   }
  109.   free(buffer);
  110. }
  111.  
  112.  
  113.