/*
 * 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.
 */
/*
 * sharpen.c - do a new sharpen image.
 *
 * Author:      Raul Rivero
 *              Mathematics Dept.
 *              University of Oviedo
 * Date:        Thu Jan 16 1992
 * Copyright (c) 1992, Raul Rivero
 *
 */
/*
 * NOTE:
 *       the same process could be done using the convolve routines
 *       defining a 'sharpening' matrix. But, I wanna give you an
 *       example of using the HSL/RGB routines. Ok ?.
 */

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

extern int LUGverbose;

sharpen_bitmap(inbitmap, outbitmap)
bitmap_hdr *inbitmap;
bitmap_hdr *outbitmap;
{
  int i, j, k;
  int totalsize = inbitmap->xsize * inbitmap->ysize;
  byte *rout, *gout, *bout;
  byte *r, *g, *b;
  double *hbuf[3], *sbuf[3], *lbuf[3];
  byte *end;
  double new;
  int d_linesize = inbitmap->xsize * sizeof(double);

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

  /* RGB image ? */
  if ( inbitmap->depth != 24 )
    error(7);

  /* Fill our header and allocate memory */
  outbitmap->magic  = LUGUSED;
  outbitmap->xsize  = inbitmap->xsize;
  outbitmap->ysize  = inbitmap->ysize;
  outbitmap->depth  = inbitmap->depth;          /* 24 */
  outbitmap->colors = inbitmap->colors;
  rout = outbitmap->r = (byte *) Malloc( totalsize );
  gout = outbitmap->g = (byte *) Malloc( totalsize );
  bout = outbitmap->b = (byte *) Malloc( totalsize );

  /* Set pointers to in image */
  r = inbitmap->r;
  g = inbitmap->g;
  b = inbitmap->b;

  /* Allocate memory to hsl buffers */
  for ( i = 0; i < 3; i++ ) {
    hbuf[i] = (double *) Malloc( d_linesize );
    sbuf[i] = (double *) Malloc( d_linesize );
    lbuf[i] = (double *) Malloc( d_linesize );
  }

  end = r + totalsize;

  /* Convert first two lines to hsl */
  for ( i = 0; i < 2; i++ ) {
    rgb_to_hsl_buffer( r, g, b, hbuf[i], sbuf[i], lbuf[i], outbitmap->xsize );
    r += outbitmap->xsize;
    g += outbitmap->xsize;
    b += outbitmap->xsize;
  }

  VPRINTF( stderr, "Sharpening image\n");

  while ( r < end ) {
    for ( i = 2 ; i ; i-- ) {
      bcopy( hbuf[i-1], hbuf[i], d_linesize );
      bcopy( sbuf[i-1], sbuf[i], d_linesize );
      bcopy( lbuf[i-1], lbuf[i], d_linesize );
    }
    rgb_to_hsl_buffer( r, g, b, hbuf[0], sbuf[0], lbuf[0], outbitmap->xsize );
    r += outbitmap->xsize;
    g += outbitmap->xsize;
    b += outbitmap->xsize;
    rout++, bout++, gout++;
    for ( i = 1, j = 0, k = 2; i < outbitmap->xsize-1; i++, j++, k++ ) {
      new = 4.   * lbuf[1][i] -
             .5  * lbuf[1][j] - .5  * lbuf[1][k] -
             .5  * lbuf[0][i] - .5  * lbuf[2][i] -
             .25 * lbuf[0][j] - .25 * lbuf[0][k] -
             .25 * lbuf[2][j] - .25 * lbuf[2][k];
      HSL_to_RGB( hbuf[1][i], sbuf[1][i], new, rout, gout, bout );
      rout++, bout++, gout++;
    }
    rout++, gout++, bout++;
  }

  /* Free memory */
  for ( i = 0; i < 3; i++ ) {
    free( hbuf[i] );
    free( sbuf[i] );
    free( lbuf[i] );
  }

  /* No errors */
  return 0;
}
