/*
 * 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.
 */
/*
 * fade.c - creates several images fading from the source to the target.
 *
 * Author:      Raul Rivero
 *              Mathematics Dept.
 *              University of Oviedo
 * Date:        Mon Oct 5 1992
 * Copyright (c) 1992, Raul Rivero
 *
 */
/*
 * History:
 *		I had problems with implicits conversions of some
 *		compilers, so i 'casted' all what i could :-).
 */

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

extern char *MY_NAME;
extern int LUGverbose;

void fade();

main(argc, argv)
int argc;
char **argv;
{
  int i;
  bitmap_hdr source, target;

  MY_NAME = argv[0];

  /*
   * Get options ( some day I'll build a procedure ).
   */
  if ( argc > 1 ) {             /* else core on SGI */
    while ( argv[1][0] == '-' ) {
      for ( i = 1; argv[1][i]; i++ ) {
        switch ( argv[1][i] ) {
                case 'v':
                        LUGverbose++;
                        break;
                case '!':
                        print_copyright();
                        break;
                default :
                        usage();
                        break;
        }
      }
      argv++;
      argc--;
    }
  }

  /* 
   * We need two imagenes, one name and a number.
   */
  if ( argc < 5 ) {
    usage();
  }

  /*
   * A real number ?.
   */
  if ( !isnumber(argv[4]) )
    usage();

  /*
   * Read the source and the target image.
   */
  read_lug_file( argv[1], &source );
  read_lug_file( argv[2], &target );

  /*
   * Ok. Lets go!.
   */
  fade( &source, &target, argv[3], atoi(argv[4]) );

  return 0;
}

void
fade( source, target, out_base_name, no_frames )
bitmap_hdr *source, *target;
char *out_base_name;
int no_frames;
{
  int totalsize = source->xsize * source->ysize;
  float *rinc, *rptr;
  float *ginc, *gptr;
  float *binc, *bptr;
  byte *srptr, *sgptr, *sbptr;
  byte *trptr, *tgptr, *tbptr;
  bitmap_hdr image;
  char out_name[132];
  int i, j;

  /*
   * We need image with the same sizes...
   */
  if ( source->xsize != target->xsize || source->ysize != target->ysize )
    error( 12 );

  /*
   * ... and true color.
   */
  if ( source->depth != 24 || target->depth != 24 )
    error( 7 );

  /*
   * Get memory.
   */
  rptr = rinc = (float *) Malloc( totalsize * sizeof(float) );
  gptr = ginc = (float *) Malloc( totalsize * sizeof(float) );
  bptr = binc = (float *) Malloc( totalsize * sizeof(float) );

  /*
   * Set the pointers.
   */
  srptr = source->r, sgptr = source->g, sbptr = source->b;
  trptr = target->r, tgptr = target->g, tbptr = target->b;

  /*
   * Calculate the diffs. buffers.
   */
  fprintf( stderr, "Precalculating differences"), fflush( stderr );
  j = no_frames - 1;
  for ( i = 0; i < totalsize; i++ ) {
    *rptr++ = (((float)*trptr++ - (float)*srptr++)) / (float)j;
    *gptr++ = (((float)*tgptr++ - (float)*sgptr++)) / (float)j;
    *bptr++ = (((float)*tbptr++ - (float)*sbptr++)) / (float)j;
  }

  /*
   * Write the new first image.
   */
  sprintf( out_name, "%s.%d", out_base_name, 1 );
  fprintf( stderr, "\nWritting: %s", out_name ), fflush( stderr );
  write_lug_file( out_name, source );

  /* 
   * The new images will be modifications from the original. So
   * we need it.
   */
  copy_bitmap( source, &image );

  /*
   * The algorithm: we know the differences per frame ( r/g/binc ),
   *                so each new frame is calculated using the source
   *                image and this buffer. 
   * You get it ?.
   */
  for ( i = 1; i < no_frames-1 ; i++ ) {
    fprintf( stderr, "\nCalculating" ), fflush( stderr );
    /* reset the pointers */
    rptr = rinc, gptr = ginc, bptr = binc;
    srptr = source->r, sgptr = source->g, sbptr = source->b;
    trptr = image.r, tgptr = image.g, tbptr = image.b;
    /* calculate the NEW image */
    for ( j = 0; j < totalsize; j++ ) {
      *trptr++ = (int) ( *rptr++ * (float)i + (float)*srptr++);
      *tgptr++ = (int) ( *gptr++ * (float)i + (float)*sgptr++);
      *tbptr++ = (int) ( *bptr++ * (float)i + (float)*sbptr++);
    }
    /* get the file name and write the image */
    sprintf( out_name, "%s.%d", out_base_name, i+1 ); 
    fprintf( stderr, ". Writting: %s", out_name ), fflush( stderr );
    write_lug_file( out_name, &image );
  }

  /*
   * Write the last image.
   */
  sprintf( out_name, "%s.%d", out_base_name, no_frames ); 
  fprintf( stderr, "\nWritting: %s", out_name ), fflush( stderr );
  write_lug_file( out_name, target );

  /*
   * Free all buffers and images.
   */
  Free( rinc ); Free( ginc ); Free( binc );
  freebitmap( &image );

  fprintf( stderr, "\nDone\n");
}

usage()
{
  char *msg = "\n\
%s: Usage: %s [-v!] <source_file> <target_file> <out_base_name> <no_frames>\n\n\
Flags:\n\
\t-v: verbose\n\
\t-!: hey!, what about this program ?!\n\n\
The Alias 'pix' format is the format used.\n";

  fprintf( stderr, msg, MY_NAME, MY_NAME );
  exit( 1 );
}

print_copyright()
{
  char *msg = "\
fade ( %s ) - creates several images fading from the source to the target\n\n\
This program - (c) 1992, Raul Rivero\n\
LUG  library - (c) 1992, Raul Rivero && Math Dept. ( U. of Oviedo )\n\n\
This software is free and you can get a full copy of original LUG library\n\
via E-mail to rivero@pinon.ccu.uniovi.es or via anonymous ftp to \n\
ftp.uniovi.es ( /uniovi/mathdept/src ).\n\n\
The LUG library includes support for several file formats, viewers on\n\
different architectures and digital image processing.\n\n\
Supported input formats:\n\n\
\t* Pix ( Alias )  *** default ***\n\
\t* TIFF ( needs Sam Leffler's TIFF library )\n\
\t* RLE ( needs Utah Raster Toolkit library )\n\
\t* RLA ( Wavefront )\n\
\t* SGI ( internal Silicon Graphics file format )\n\
\t* Targa ( Truevision )\n\
\t* GIF ( Compuserve )\n\
\t* PCX ( ZSoft )\n\
\t* PBM/PGM/PPM\n\
\t* Postscript\n\
\t* JPEG ( needs Thomas G. Lane's JPEG library )\n";

  fprintf( stderr, msg, LUGVERSIONs );
  exit( 1 );
}
