/*
 * This software is copyrighted as noted below.  It may be freely copied,
 * modified, and redistributed, provided that the copyright notice is
 * preserved on all copies.
 *
 * There is no warranty or other guarantee of fitness for this software,
 * it is provided solely "as is".  Bug reports or fixes may be sent
 * to the author, who may or may not act on them as he desires.
 *
 * You may not include this software in a program or other software product
 * without supplying the source, or without informing the end-user that the
 * source is available for no extra charge.
 *
 * If you modify this software, you should include a notice giving the
 * name of the person performing the modification, the date of modification,
 * and the reason for such modification.
 */
/*
 * tohalftone.c - Convert a bw ( or color ) image to a halftone.
 *
 * Author:      Raul Rivero
 *              Mathematics Dept.
 *              University of Oviedo
 * Date:        Sat Jan 11 1992
 * Copyright (c) 1992, Raul Rivero
 *
 */

/*
 * We'll create a halftone image ( two colors ) but with a
 * pallette of 256 ( more compatible with other procedures ).
 */

#include <lug.h>
#include <lugfnts.h>

#define HT_SIZE                 16
#define ht_dither(x, y, c)      ((c)> ht_matrix[x%HT_SIZE][y%HT_SIZE] ? 1 : 0)

extern int LUGverbose;

int ht_matrix[HT_SIZE][HT_SIZE] = {
  0, 192,  48, 240,  12, 204,  60, 252,   3, 195,  51, 243,  15, 207,  63, 255,
128,  64, 176, 112, 140,  76, 188, 124, 131,  67, 179, 115, 143,  79, 191, 127,
 32, 224,  16, 208,  44, 236,  28, 220,  35, 227,  19, 211,  47, 239,  31, 223,
160,  96, 144,  80, 172, 108, 156,  92, 163,  99, 147,  83, 175, 111, 159,  95,
  8, 200,  56, 248,   4, 196,  52, 244,  11, 203,  59, 251,   7, 199,  55, 247,
136,  72, 184, 120, 132,  68, 180, 116, 139,  75, 187, 123, 135,  71, 183, 119,
 40, 232,  24, 216,  36, 228,  20, 212,  43, 235,  27, 219,  39, 231,  23, 215,
168, 104, 152,  88, 164, 100, 148,  84, 171, 107, 155,  91, 167, 103, 151,  87,
  2, 194,  50, 242,  14, 206,  62, 254,   1, 193,  49, 241,  13, 205,  61, 253,
130,  66, 178, 114, 142,  78, 190, 126, 129,  65, 177, 113, 141,  77, 189, 125,
 34, 226,  18, 210,  46, 238,  30, 222,  33, 225,  17, 209,  45, 237,  29, 221,
162,  98, 146,  82, 174, 110, 158,  94, 161,  97, 145,  81, 173, 109, 157,  93,
10,  202,  58, 250,   6, 198,  54, 246,   9, 201,  57, 249,   5, 197,  53, 245,
138,  74, 186, 122, 134,  70, 182, 118, 137,  73, 185, 121, 133,  69, 181, 117,
42,  234,  26, 218,  38, 230,  22, 214,  41, 233,  25, 217,  37, 229,  21, 213,
170, 106, 154,  90, 166, 102, 150,  86, 169, 105, 153,  89, 165, 101, 149,  85
};

tohalftone(inbitmap1, outbitmap)
bitmap_hdr *inbitmap1;
bitmap_hdr *outbitmap;
{
  register int i, j;
  int new_bw = 0;
  bitmap_hdr auxbitmap;
  bitmap_hdr *inbitmap;
  byte *optr, *iptr;

  if ( inbitmap1->magic != LUGUSED )
    error( 19 );

  if ( inbitmap1->depth > 8 ) {
    /*
     * We have a RGB image and we need a simple
     * eight bits image.
     */
    tobw(inbitmap1, &auxbitmap);
    inbitmap = &auxbitmap;
    new_bw++;
  }else inbitmap = inbitmap1;

  VPRINTF(stderr, "Halftonig image\n");
  /*
   * Fill new header ...
   */
  outbitmap->magic = LUGUSED;
  outbitmap->xsize = inbitmap->xsize;
  outbitmap->ysize = inbitmap->ysize;
  outbitmap->depth = 2;
  outbitmap->colors = ( 1 << outbitmap->depth );
  outbitmap->cmap = (byte *) create_halftone_pallete();
  /* One component => r */
  optr = outbitmap->r = (byte *) Malloc(inbitmap->xsize * inbitmap->ysize);
  iptr = inbitmap->r;

  /* Create halftone image */
  for ( i = 0; i < inbitmap->ysize; i++ ) {
    for ( j = 0; j < inbitmap->xsize; j++, iptr++) {
      *optr++ = ht_dither(j, i, *iptr);
    }
  }

  /* Free memory what allocate */
  if ( new_bw ) {
    free( auxbitmap.r );
    free( auxbitmap.cmap );
  }
}

/*
 * This function is defined because you can wanna call it from
 * out of here ( and define will not work ).
 */
bw_to_halftone( x, y, position )
int x, y;
byte position;
{
  return ht_dither(x, y, position);
}

byte *create_halftone_pallete()
{
  byte *buffer = (byte *) Malloc( 3 * 2 );

  /*
   * Color 0 = Black
   * Color 1 = White
   * Others  = undefined ( really blacks, eq. zeros )
   */
  buffer[3] = 255;      /* R */
  buffer[4] = 255;      /* G */
  buffer[5] = 255;      /* B */

  return buffer;
}
