[mod.sources] v07i067: Image manipulation routines in C++, Part04/05

sources-request@mirror.TMC.COM (11/11/86)

Submitted by: David Sher <seismo!rochester!sher>
Mod.sources: Volume 7, Issue 67
Archive-name: image/Part04

[  The Makefiles had ESCAPE and \r characters in their comment lines;
   I changed them to their printable representation, the two-character
   sequences ^[ and ^M, respectively.  Also, the file ascii2var/uu.test.var
   had some non-ASCII characters in it; I used uuencode; the resultant
   file is really ascii2var/test.var.  Also, I do not have C++ nor any
   images, so I have not tested this package.  --r$  ]

#!/bin/sh
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
# If all goes well, you will see the message "No problems found."
# Wrapped by mirror!rs on Mon Nov 10 13:44:37 EST 1986

# Exit status; set to 1 on "wc" errors or if would overwrite.
STATUS=0
# Contents:  varc++/long_image.c++ varc++/image.c++
#	varc++/image.c.old varc++/double_image.c++ vartools/trunc.c++
#	vartools/scale.c++ vartools/correlate.c++
 
echo x - varc++/long_image.c++
if test -f varc++/long_image.c++ ; then
    echo varc++/long_image.c++ exists, putting output in $$varc++/long_image.c++
    OUT=$$varc++/long_image.c++
    STATUS=1
else
    OUT=varc++/long_image.c++
fi
sed 's/^X//' > $OUT <<'@//E*O*F varc++/long_image.c++//'
X/*
X    This file contains the routines necessary to manipulate an image
X    of 8 bit data that do not need to know about the image file format
X*/

X#include <stream.h>
X#include <stdio.h>

X#include "for.h++"

X#include "long_image.h++"


X/* the constructor when the image is built */
Xlong_image::long_image 
X    ( 
X    const create_image_type cit ,	// marker that the image is being created
X    const card n_rows , 		// the number of rows in the image
X    const card n_cols , 		// the number of collumns in the image
X    const FILE * image_file ,	// file for image
X    const card w_width = 1 ,	// window width
X    const card w_length = 1 	// window length
X    )
X    : ( CREATE , image_file , n_rows , n_cols , w_width , w_length )
X    {
X    /* check that the constructor is called correctly */
X    if ( cit != CREATE )
X	{
X	cerr << "constructor for long_image being called in obscure way\n";
X	abort();
X	}
X    
X    /* allocate space for image */
X    image_buffer = new long [ n_rows*n_cols ];

X    /* allocate space for dope vector */
X    image_rows = new long * [ n_rows ];
X    /* allocate space for window dope vector */
X    window_rows = new long * [ w_length ];

X    /* initialize dope vector */
X    FOR(int i1 = 0 ; i1 < n_rows; i1++)
X	{
X	image_rows[i1] = image_buffer + i1*n_cols;
X	}
X    ENDFOR

X    /* set up the protection  so the image can be written */
X    prot = CAN_WRITE;

X    /* initialize function pointers */
X    next = &uninitialized_next;
X    prev = &uninitialized_prev;
X    get_w_e_pointer = &uninitialized_get_w_e;
X    write_w_e_pointer = &uninitialized_write_w_e;
X    }


X/* functions for function pointers */

X/* this version of next assumes the window has been initialized */
Xint 
Xlong_image::initialized_next ()
X    {
X    // if at the end of a row
X    if ( collumn + window_width == number_cols )
X	{
X	// if at the end of the image
X	if ( row + window_length == number_rows )
X	    {
X	    return 0;
X	    }
X	// otherwise go to the beginning of the next row
X	collumn = 0;
X	row++;
X	// reset the pointers in the window
X	FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	    {
X	    window_rows[i1] = image_rows[row + i1];
X	    }
X	ENDFOR
X	// return successfully
X	return 1;
X	}
X    // otherwise move along row
X    collumn++;
X    // move the pointers in the window
X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	{
X	window_rows[i1]++;
X	}
X    ENDFOR
X    // return successfully
X    return 1;
X    }

X/* this version of prev assumes the window has been initialized */
Xint 
Xlong_image::initialized_prev ()
X    {
X    // if at beginning of a row
X    if ( collumn == 0 )
X	{
X	// if at the beginning of the image
X	if ( row == 0 )
X	    {
X	    return 0;
X	    }
X	// otherwise go to the end of the previous row
X	collumn = number_cols - window_width;
X	row--;
X	// reset the pointers in the window
X	FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	    {
X	    window_rows[i1] = image_rows[row + i1] + collumn;
X	    }
X	ENDFOR
X	// return successfully
X	return 1;
X	}
X    // otherwise move back on the row
X    collumn--;
X    // move the pointers in the window
X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	{
X	window_rows[i1]--;
X	}
X    ENDFOR
X    // return successfully
X    return 1;
X    }

X/* this version of next initializes the window */
Xint 
Xlong_image::uninitialized_next ()
X    {
X    // check that the window fits in the image
X    if ( (window_width > number_cols) || (window_length > number_rows) )
X	{
X	return 0;
X	}

X    // set row and collumn to 0
X    row = 0;
X    collumn = 0;

X    // set the window row pointers
X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	{
X	window_rows[i1] = image_rows[row + i1];
X	}
X    ENDFOR

X    // set the function pointers
X    next = &initialized_next;
X    prev = &initialized_prev;
X    get_w_e_pointer = &initialized_get_w_e;
X    write_w_e_pointer = &initialized_write_w_e;

X    // set the window status
X    window_status = INITIALIZED;
X    return 1;
X    }

X/* this version of prev initializes the window */
Xint 
Xlong_image::uninitialized_prev ()
X    {
X    // check that the window fits in the image
X    if ( (window_width > number_cols) || (window_length > number_rows) )
X	{
X	return 0;
X	}

X    // set row and collumn to bottom right of image
X    row = number_rows - window_length;
X    collumn = number_cols - window_width;
X    // set the window row pointers
X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	{
X	window_rows[i1] = image_rows[row + i1] + collumn;
X	}
X    ENDFOR

X    // set the function pointers
X    next = &initialized_next;
X    prev = &initialized_prev;
X    get_w_e_pointer = &initialized_get_w_e;
X    write_w_e_pointer = &initialized_write_w_e;

X    // set the window status
X    window_status = INITIALIZED;
X    return 1;
X    }

X// this version of next says that applying the next operation is impossible
Xint
Xlong_image::impossible_next ( )
X    {
X    cerr << "Trying to apply the next operation to an image for which it is impossible!\n";
X    return 0;
X    }

X// this version of prev says that applying the next operation is impossible
Xint
Xlong_image::impossible_prev ( )
X    {
X    cerr << "Trying to apply the prev operation to an image for which it is impossible!\n";
X    return 0;
X    }

X/* uninitialized version of get_w_e will just die */
Xlong 
Xlong_image::uninitialized_get_w_e ( const card i , const card j )
X    {
X    cerr << "Trying to get an element of an uninitialized window\n";
X    cerr << "The element was " << i << "," << j << "\n";
X    abort ();
X    return 0;
X    }

X/* initialized version of get_w_e */
Xlong 
Xlong_image::initialized_get_w_e ( const card i , const card j )
X    {
X    // check that i,j is in the window
X    if ( ( i >= window_length ) || ( j >= window_width ) )
X	{
X	cerr << "Tried to access element outside window\n";
X	cerr << "Window size " << window_length << "," << window_width << "\n";
X	cerr << "Accessed " << i << "," << j << "\n";
X	abort ();
X	return 0;
X	}
X    
X    // otherwise return the element
X    return window_rows[i][j];
X    }

X/* uninitialized version of write_w_e will just die */
Xvoid 
Xlong_image::uninitialized_write_w_e ( const card i , const card j , const long value )
X    {
X    cerr << "Trying to write to an element of an uninitialized window\n";
X    cerr << "Trying to write " << value << "\n";
X    cerr << "To " << i << "," << j << "\n";
X    abort ();
X    }

X/* initialized version of write_w_e */
Xvoid 
Xlong_image::initialized_write_w_e ( const card i , const card j , const long value)
X    {
X    // check that i,j is in the window
X    if ( ( i >= window_length ) || ( j >= window_width ) )
X	{
X	cerr << "Tried to access element outside window\n";
X	cerr << "Window size " << window_length << "," << window_width << "\n";
X	cerr << "Accessed " << i << "," << j << "\n";
X	abort ();
X	}
X    
X    // otherwise set the element
X    window_rows[i][j] = value;
X    }

X/*
X    move in row n steps 
X    returns 1 when that motion is legal 0 otherwise
X*/
Xint 
Xlong_image::move_collumn ( const int n ) 
X    {
X    // the version in image does the checking and most of the work
X    int result = image_class::move_collumn ( n );

X    // if the move was successful move the window
X    if ( result == 1 )
X	{
X	FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	    {
X	    window_rows[i1] += n;
X	    }
X	ENDFOR
X	}

X    return result;
X    }

X/*
X    move in collumn n steps
X    returns 1 when that motion is legal 0 otherwise
X*/
Xint 
Xlong_image::move_row ( const int n ) 
X    {
X    // the version in image does the checking and most of the work
X    int result = image_class::move_row ( n );

X    // if the move was successful move the window
X    if ( result == 1 )
X	{
X	FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	    {
X	    window_rows[i1] = image_rows[row + i1] + collumn ;
X	    }
X	ENDFOR
X	}

X    return result;
X    }


X/*
X    move to specified row
X*/
Xvoid 
Xlong_image::move_to_row ( const card n ) 
X    {
X    // the version in image does the checking and most of the work
X    image_class::move_to_row ( n );

X    // move the window to the specified place
X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	{
X	window_rows[i1] = image_rows[row + i1] + collumn ;
X	}
X    ENDFOR
X    }


X/*
X    move to specified collumn
X*/
Xvoid 
Xlong_image::move_to_collumn ( const card n ) 
X    {
X    // the version in image does the checking and most of the work
X    image_class::move_to_collumn ( n );

X    // move the window to the specified place
X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	{
X	window_rows[i1] = image_rows[row + i1] + collumn ;
X	}
X    ENDFOR
X    }

X/*
X    Gets a pointer to a row
X    of the image
X*/
Xconst long * 
Xlong_image::get_row( card row )
X    {
X    // Checks to make sure request is legal
X    if ( row >= number_rows )
X	{
X	cerr << "Tried to accesses row " << row;
X	cerr << " when image only has " << number_rows << " rows!\n";
X	abort();
X	}
X    if ( image_status == UNINITIALIZED )
X	{
X	cerr << "Trying to read row from unitialized image!\n";
X	abort();
X	}
X    if ( (prot != CAN_READ) && (prot != CAN_READ_AND_WRITE) )
X	{
X	cerr << "Trying to access a row of an image protected against reading!\n";
X	abort();
X	}
X    
X    return image_rows[row];
X    }

X/*
X    Change the size of a window
X    causes the window to become uninitialized
X*/
Xvoid 
Xlong_image::resize_window ( card width , card length )
X    {

X    // set the window
X    window_width = width;
X    window_length = length;
X    window_status = UNINITIALIZED;

X    /* allocate space for window dope vector */
X    window_rows = new long * [ window_length ];

X    /* reset function pointers */
X    next = &uninitialized_next;
X    prev = &uninitialized_prev;
X    get_w_e_pointer = &uninitialized_get_w_e;
X    write_w_e_pointer = &uninitialized_write_w_e;
X    }

X/*
X    Causes the window to cover the entire image.
X    Allows one to access any part of the image with window operations
X*/
Xvoid 
Xlong_image::window_entire_image ( )
X    {
X    // set up the window
X    window_width = number_cols;
X    window_length = number_rows;
X    window_status = INITIALIZED;
X    // make the window dope vector an alias for the image dope vector
X    window_rows = image_rows;

X    // set up function pointers so next and previous impossible
X    next = &impossible_next;
X    prev = &impossible_prev;
X    // access functions
X    get_w_e_pointer = &initialized_get_w_e;
X    write_w_e_pointer = &initialized_write_w_e;
X    }
X/*
XCopyright (C) 1986, David Sher in the University of Rochester
XPermission is granted to any individual or institution to use, copy, or
Xredistribute this software so long as it is not sold for profit, provided
Xthis copyright notice is retained.
X*/
@//E*O*F varc++/long_image.c++//
chmod u=rw,g=r,o=r $OUT
 
echo x - varc++/image.c++
if test -f varc++/image.c++ ; then
    echo varc++/image.c++ exists, putting output in $$varc++/image.c++
    OUT=$$varc++/image.c++
    STATUS=1
else
    OUT=varc++/image.c++
fi
sed 's/^X//' > $OUT <<'@//E*O*F varc++/image.c++//'
X/*
X    This file contains the implementation of the generic image stuff
X    except for handling the and read and write function that 
X    requires knowledge of the image file format
X*/
X#include <stream.h>
X#include <stdio.h>
X#include <string.h>
X#include "for.h++"
X#include "image.h++"

X/*
X    initializer for generic images when image is being created rather
X    than read from file
X*/
Ximage_class::image_class
X    ( 
X    const create_image_type cit,	// maker that the image is being created
X    const FILE * image_file , 	// the file for the image
X    const card n_rows , 		// the number of rows in the image
X    const card n_cols , 		// the number of collumns in the image
X    const card w_width , 		// the width of the window
X    const card w_length 		// the length of the window
X    )
X    {
X    /* check that the constructor is called correctly */
X    if ( cit != CREATE )
X	{
X	cerr << "Generic constructor for image being called in obscure way\n";
X	abort();
X	}

X    /* initialize using arguments */
X    file = image_file;
X    number_rows = n_rows;
X    number_cols = n_cols;
X    window_width = w_width;
X    window_length = w_length;

X    /* a priori initializations */
X    /* status */
X    image_status = UNINITIALIZED;
X    window_status = UNINITIALIZED;
X    prot = CAN_NOT_DO_ANYTHING;
X    /* comments */
X    comment_length = 0;
X    comments = NULL;
X    /* header info from file format */
X    header_info = NULL;
X    }

X/*
X    comment manipulation code
X*/
X/* 
X    returns a null terminated string for comments 
X*/
Xconst char * 
Xcomment_string ( image_class& i )
X    {
X    char * output = new char [ i.comment_length + 1 ];	// output for the data
X    char * output_p = output;				// pointer to output
X    const char * com = i.comments;			// comments

X    /* copy the comments into the new string */
X    FOR(int i1 = 0 ; i1 < i.comment_length ; i1++)
X	{
X	*(output_p++) = *(com++);
X	}
X    ENDFOR

X    /* null terminate the new string */
X    *output_p = '\0';

X    /* return the new string */
X    return output;
X    }

X/* sets the comments */
Xvoid 
Ximage_class::set_comments( char * string , const card length )
X    {
X    comment_length = length;
X    comments = string;
X    }

X/* adds a string to the comments */
Xvoid 
Ximage_class::add_comment( char * string , const card length )
X    {
X    /* the new comments to be used */
X    char * new_comments = new char [ comment_length + length ];
X    char * ncp = new_comments;	// pointer into new comments
X    char * ocp = comments;	// pointer into old comments

X    /* copy the old comments into the new string */
X    FOR(int i1 = 0 ; i1 < comment_length ; i1++)
X	{
X	*(ncp++) = *(ocp++);
X	}
X    ENDFOR
X    
X    /* copy the added comments into the new string */
X    FOR(int i1 = 0 ; i1 < length ; i1++)
X	{
X	*(ncp++) = *(string++);
X	}
X    ENDFOR

X    /* make the new string the comments */
X    comment_length += length;
X    comments = new_comments;
X    }

X/*
X    for moving around in images
X*/

X/*
X    move to specified row
X*/
Xvoid 
Ximage_class::move_to_row ( const card n ) 
X    {
X    // test bounds
X    if ( n < 0 ) 
X	{
X	cerr << "Trying to move to a negative row in an image\n";
X	cerr << "The row is " << n << "\n";
X	abort();
X	}
X    if ( n + window_length > number_rows )
X	{
X	cerr << "Trying to move to a nonexistant row in an image\n";
X	cerr << "The row is " << n << "\n";
X	abort();
X	}

X    // check status
X    if ( window_status == UNINITIALIZED )
X	{
X	// check collumn boundaries
X	if ( window_width > number_cols )
X	    {
X	    cerr << "Window to wide for image!\n";
X	    cerr << "Width of image: " << number_cols;
X	    cerr << "Width of window: " << window_width;
X	    cerr << "\n";
X	    abort();
X	    }
X	row = n;
X	collumn = 0;
X	window_status = INITIALIZED;
X	}

X    // otherwise change the row since it is legal
X    row = n;
X    }

X/*
X    move to specified collumn
X*/
Xvoid 
Ximage_class::move_to_collumn ( const card n ) 
X    {
X    // test bounds
X    if ( n < 0 ) 
X	{
X	cerr << "Trying to move to a negative collumn in an image\n";
X	cerr << "The collumn is " << n << "\n";
X	abort();
X	}
X    if ( n + window_width > number_cols )
X	{
X	cerr << "Trying to move to a nonexistant collumn in an image\n";
X	cerr << "The collumn is " << n << "\n";
X	abort();
X	}

X    // check status
X    if ( window_status == UNINITIALIZED )
X	{
X	// check collumn boundaries
X	if ( window_length > number_rows )
X	    {
X	    cerr << "Window to long for image!\n";
X	    cerr << "Height of image: " << number_rows;
X	    cerr << "Height of window: " << window_length;
X	    cerr << "\n";
X	    abort();
X	    }
X	collumn = n;
X	row = 0;
X	window_status = INITIALIZED;
X	}

X    // otherwise change the row since it is legal
X    collumn = n;
X    }

X/*
X    move in row n steps 
X    returns 1 when that motion is legal 0 otherwise
X*/
Xint 
Ximage_class::move_collumn ( const int n ) 
X    {
X    // check the status of the window
X    if ( window_status == UNINITIALIZED )
X	{
X	// it is probably an error so print an error message
X	cerr << "trying to move in unitialized window\n";
X	// but return 0 since  that is the semantics
X	return 0;
X	}
X    
X    // check that the movement doesn't lead to a negative position
X    if ( n + collumn < 0 )
X	{
X	return 0;
X	}
X    
X    // check that the movement doesn't lead to a too large position
X    if ( n + collumn + window_width > number_rows )
X	{
X	return 0;
X	}
X    
X    // else increment the collumn position and return successfully
X    collumn += n;
X    return 1;
X    }

X/*
X    move in collumn n steps
X    returns 1 when that motion is legal 0 otherwise
X*/
Xint 
Ximage_class::move_row ( const int n ) 
X    {
X    // check the status of the window
X    if ( window_status == UNINITIALIZED )
X	{
X	// it is probably an error so print an error message
X	cerr << "trying to move in unitialized window\n";
X	// but return 0 since  that is the semantics
X	return 0;
X	}
X    
X    // check that the movement doesn't lead to a negative position
X    if ( n + row < 0 )
X	{
X	return 0;
X	}
X    
X    // check that the movement doesn't lead to a too large position
X    if ( n + row + window_width > number_cols )
X	{
X	return 0;
X	}
X    
X    // else increment the collumn position and return successfully
X    row += n;
X    return 1;
X    }

X/* change the protection from CAN_WRITE to CAN_READ_AND_WRITE */
Xvoid image_class::read_and_write ( )
X    { 
X    if ( prot == CAN_WRITE ) 
X	{
X	prot = CAN_READ_AND_WRITE;
X	}
X    else
X	{
X	cerr << "Protection violation for read_and_write\n";
X	abort();
X	}
X    }

X/*
XCopyright (C) 1986, David Sher in the University of Rochester
XPermission is granted to any individual or institution to use, copy, or
Xredistribute this software so long as it is not sold for profit, provided
Xthis copyright notice is retained.
X*/
@//E*O*F varc++/image.c++//
chmod u=rw,g=r,o=r $OUT
 
echo x - varc++/image.c.old
if test -f varc++/image.c.old ; then
    echo varc++/image.c.old exists, putting output in $$varc++/image.c.old
    OUT=$$varc++/image.c.old
    STATUS=1
else
    OUT=varc++/image.c.old
fi
sed 's/^X//' > $OUT <<'@//E*O*F varc++/image.c.old//'
X/*
X    This file contains the routines that interface to the maryland
X    vision package
X*/

X#include <stdio.h>
X#include "utils.h"
X#include "image.h"


X/*
X    Creates an image Data Structure
X*/
Ximage_pt
Xcreate_image(number_rows,number_cols)
Xcard number_rows;	/* Number of rows */
Xcard number_cols;	/* Number of cols */
X    {
X    register card i;

X/* Allocate space for the image data structure */
X    image_pt output = (image_pt) MALLOC(sizeof(image));
X    if(output == NULL)
X	{
X	perror("CreateImage:MALLOC failed");
X	abort();
X	}

X/* Should set up defaults properly */
X    mhead(&(output->head), number_cols, number_rows);

X/* Make sure defaults are correct */
X    output->head.cv_lcom = 0;
X    output->head.cv_type = 0;
X    output->head.cv_dims = 2;
X    output->head.cv_hpls = 1;
X    output->head.cv_bnds = 1;
X    output->head.cv_bp = sizeof(image_elt)*8;
X    output->head.cv_ebb = 0;
X    output->head.cv_sbb = sizeof(image_elt)*8;
X    output->head.cv_bb = sizeof(image_elt)*8;
X    output->head.cv_sbp = sizeof(image_elt)*8;
X    output->head.cv_ebp = 0;

X/* Allocate the dope vector for the image array */
X    output->array = (image_elt **) MALLOC
X				(
X				sizeof(image_elt *) 
X				* output->head.cv_rows
X				);
X    
X/* Allocate the storage areas for the image array */
X    for(i = 0; i < output->head.cv_rows; i++)
X	{
X	output->array[i] = (image_elt *) MALLOC 
X				(
X				sizeof(image_elt) 
X				* output->head.cv_cols
X				);
X        if(output->array[i] == NULL)
X	    {
X	    perror("CreateImage:MALLOC failed");
X	    abort();
X	    }

X	}

X/* Describe there being 0 lines of comments */
X    output->comment.number_lines = 0;
X    output->comment.line_lengths = NULL;
X    output->comment.lines = NULL;

X/* return the processed output */
X    return output;
X    }

X/*
X    Reads in an image from a file
X*/
Ximage_pt
Xread_image(f)
Xint f;	/* file descriptor to read image from */
X    {
X    register card i;

X/* Allocate space for the image data structure */
X    image_pt output = (image_pt) MALLOC(sizeof(image));

X/* Create the mv header */
X    ihead(f,&(output->head));

X/* Read in the image comments */
X    read_comments(f,output);

X/* Allocate the dope vector for the image array */
X    output->array = (image_elt **) MALLOC
X				(
X				sizeof(image_elt *) 
X				* output->head.cv_rows
X				);
X    if(output == NULL)
X	{
X	perror("ReadImage:MALLOC failed");
X	abort();
X	}
X    
X/* Allocate the storage areas for the image array */
X    for(i = 0; i < output->head.cv_rows; i++)
X	{
X	output->array[i] = (image_elt *) MALLOC 
X				(
X				sizeof(image_elt) 
X				* output->head.cv_cols
X				);
X        if(output->array[i] == NULL)
X	    {
X	    perror("ReadImage:MALLOC failed");
X	    abort();
X	    }

X    /* Read in a row of the image into the new array */
X	rrow8(f,output->array[i],&(output->head));

X#ifdef DEBUG
X	fprintf(stderr,"read row %d 1st element is %d\n",i,output->array[i][0]);
X#endif DEBUG
X	}

X/* return the processed output */
X    return output;
X    }


X/*
X    Writes an image out to a file
X*/
Xvoid
Xwrite_image(f,input)
Xint f;	/* file to write image to */
Ximage_pt input;	/* image to write */
X    {
X    register card i;

X/* Write out image header */
X    ohead(f,&(input->head));

X/* Write comments to file */
X    write_comments(f,&(input->comment));

X/* Write out image array */
X    for(i = 0; i < input->head.cv_rows; i++)
X	{
X    /* Write out a row of the image from the image array */
X	wrow8(f,input->array[i],&(input->head));
X	}
X    }


X/*
X    routines to manipulate floating images
X*/

X/*
X    Creates an floating image Data Structure
X*/
Xfloat_image_pt
Xfloat_create_image(number_rows,number_cols)
Xcard number_rows;	/* Number of rows */
Xcard number_cols;	/* Number of cols */
X    {
X    register card i;

X/* Allocate space for the image data structure */
X    float_image_pt output = (float_image_pt) MALLOC(sizeof(float_image));
X    if(output == NULL)
X	{
X	perror("CreateImage:MALLOC failed");
X	abort();
X	}

X/* Should set up defaults properly */
X    mhead(&(output->head), number_cols, number_rows);

X/* Make sure defaults are correct */
X    output->head.cv_lcom = 0;
X    output->head.cv_type = 0;
X    output->head.cv_dims = 2;
X    output->head.cv_hpls = 1;
X    output->head.cv_bnds = 1;
X    output->head.cv_bp = sizeof(double)*8;
X    output->head.cv_ebb = 8;
X    output->head.cv_sbb = sizeof(double)*8;
X    output->head.cv_bb = sizeof(double)*8;
X    output->head.cv_sbp = sizeof(double)*8;
X    output->head.cv_ebp = 8;

X/* Allocate the dope vector for the image array */
X    output->array = (double **) MALLOC
X				(
X				sizeof(double *) 
X				* output->head.cv_rows
X				);
X    
X/* Allocate the storage areas for the image array */
X    for(i = 0; i < output->head.cv_rows; i++)
X	{
X	output->array[i] = (double *) MALLOC 
X				(
X				sizeof(double) 
X				* output->head.cv_cols
X				);
X        if(output->array[i] == NULL)
X	    {
X	    perror("CreateImage:MALLOC failed");
X	    abort();
X	    }

X	}

X/* Describe there being 0 lines of comments */
X    output->comment.number_lines = 0;
X    output->comment.line_lengths = NULL;
X    output->comment.lines = NULL;

X/* return the processed output */
X    return output;
X    }

X/*
X    Reads in an floating image from a file
X*/
Xfloat_image_pt
Xfloat_read_image(f)
Xint f;	/* file descriptor to read image from */
X    {
X    register card i;

X/* Allocate space for the image data structure */
X    float_image_pt output = (float_image_pt) MALLOC(sizeof(float_image));

X/* Create the mv header */
X    ihead(f,&(output->head));

X/* Read in the image comments */
X    read_comments(f,output);

X/* Allocate the dope vector for the image array */
X    output->array = (double **) MALLOC
X				(
X				sizeof(double *) 
X				* output->head.cv_rows
X				);
X    if(output == NULL)
X	{
X	perror("ReadImage:MALLOC failed");
X	abort();
X	}
X    
X/* Allocate the storage areas for the image array */
X    for(i = 0; i < output->head.cv_rows; i++)
X	{
X	output->array[i] = (double *) MALLOC 
X				(
X				sizeof(double) 
X				* output->head.cv_cols
X				);
X        if(output->array[i] == NULL)
X	    {
X	    perror("ReadImage:MALLOC failed");
X	    abort();
X	    }

X#ifndef MVWORKS
X    /* This code should work but doesn't  so ... */
X    /* Read in a row of the image into the new array */
X	rrowd(f,output->array[i],&(output->head));
X#else
X/* This only works for reading floating point images */
X        read(f,(char *) output->array[i],output->head.cv_cols * sizeof(double));
X#endif MVWORKS
X	}

X/* return the processed output */
X    return output;
X    }


X/*
X    Writes an floating image out to a file
X*/
Xvoid
Xfloat_write_image(f,input)
Xint f;	/* file to write image to */
Xfloat_image_pt input;	/* image to write */
X    {
X    register card i;

X/* Write out image header */
X    ohead(f,&(input->head));

X/* Write comments to file */
X    write_comments(f,&(input->comment));

X/* Write out image array */
X    for(i = 0; i < input->head.cv_rows; i++)
X	{
X#ifndef MVWORKS
X    /* This code should work but doesn't  so ... */
X    /* Write out a row of the image from the image array */
X	wrowd(f,input->array[i],&(input->head));
X#else
X/* This only works for writing floating point images */
X        write(f,(char *) input->array[i],input->head.cv_cols * sizeof(double));
X#endif MVWORKS
X	}
X    }


X/*
X    Reads comments from image
X*/
Xvoid
Xread_comments(f,input)
Xint f;	/* file descriptor */
Ximage_pt input;	/* image */
X    {
X    char *buffer;
X    int read_result;
X    int read_total = 0;

X    if (input->head.cv_lcom == 0) 
X	{
X	input->comment.number_lines = 0;
X	input->comment.line_lengths = NULL;
X	input->comment.lines = NULL;
X	return;
X	}

X    buffer = (char *) MALLOC(input->head.cv_lcom * sizeof(char));

X/* If there is a problem reading the comments */
X    while(input->head.cv_lcom != ( read_total += (read_result = read(f,buffer+read_total,input->head.cv_lcom - read_total))))
X	{
X	if ( read_result == -1 ) 
X	    {
X	    perror("Could not read comments");
X	    abort();
X	    }
X	else if( read_result == 0 ) 
X	    {
X	    fprintf(stderr,"Could only read %d bytes of comments when there is supposed to be %d bytes!\n",read_total,input->head.cv_lcom);
X	    abort();
X	    }
X	}

X/* Allocates things for comments and reads them */
X    input->comment.number_lines = find_number_of_lines(buffer,(card) input->head.cv_lcom);
X    input->comment.line_lengths = (card *) MALLOC((input->comment.number_lines*sizeof(card)));
X    input->comment.lines = (char **) MALLOC(input->comment.number_lines*sizeof(char *));
X    allocate_lines(buffer,(card) input->head.cv_lcom,input->comment.line_lengths,input->comment.lines);
X    }

X/*
X    finds number of lines in comment
X*/
Xcard
Xfind_number_of_lines(buffer,size)
Xchar buffer[];
Xcard size;
X    {
X    register card i;
X    register char *pc = buffer;
X    card num_lines = 1;
X    for(i = 0 ; i < size; i++) 
X	{
X	if(*pc == '\n') num_lines++;
X	pc++;
X	}
X    return num_lines;
X    }

X/*
X    allocates space and inserts the lines of the image into the right
X    places in lines
X*/
Xvoid
Xallocate_lines(buffer,size,line_lengths,lines)
Xchar buffer[];
Xcard size;
Xcard line_lengths[];
Xchar *lines[];
X    {
X    register card i,j;
X    register char *pc = buffer;
X    register char *begin_line = buffer;
X    card current_line = 0;
X    card current_size = 0;
X    for(i = 0 ; i < size; i++) 
X	{
X    /* If at end of line */
X	if(*pc == '\n')
X	    {
X	/* fill in size of line */
X	    line_lengths[current_line] = current_size;
X	/* allocate space for line */
X	    lines[current_line] = MALLOC((current_size + 1)*sizeof(char));
X	/* read line into lines array */
X	    for(j = 0 ; j < current_size ; j++) 
X		{
X		lines[current_line][j] = *begin_line;
X		begin_line++;
X		}
X	/* set end marker in lines array */
X	    lines[current_line][j] = 0;
X	/* set current size to 0 */
X	    current_size = 0;
X	/* set begin_line to the beginning of the next line */
X	    begin_line++;
X	/* set current_line to the next line */
X	    current_line++;
X	    }
X	else 
X	    {
X	/* current size is increased */
X	    current_size++;
X	    }
X	pc++;
X	}

X/* Do last line in image */

X/* fill in size of line */
X    line_lengths[current_line] = current_size;
X/* allocate space for line */
X    lines[current_line] = MALLOC((current_size + 1)*sizeof(char));
X/* read line into lines array */
X    for(j = 0 ; j < current_size ; j++) 
X        {
X        lines[current_line][j] = *begin_line;
X	begin_line++;
X	}
X/* set end marker in lines array */
X    lines[current_line][j] = 0;
X    }



X/*
X    Writes comments to image
X*/
Xvoid
Xwrite_comments(file,comment)
Xint file;
Ximage_comment *comment;
X    {
X    register card i;
X    int write_return;
X    for(i = 0;i < comment->number_lines; i++)
X	{
X	write_return = write(file,comment->lines[i],(int) comment->line_lengths[i]);
X	if(write_return != comment->line_lengths[i])
X	    {
X	    if(write_return == -1)
X		{
X		perror("Could not write comments to file");
X		}
X	    else
X		{
X		fprintf(stderr,"Something went wrong only could write %d bytes of comment line to file\n",write_return);
X		}
X	    abort();
X	    }
X	if(i == comment->number_lines - 1) break;
X        write_return = write(file,"\n",1);
X        if(write_return != 1)
X            {
X            if(write_return == -1)
X	        {
X	        perror("Could not write comments to file");
X	        }
X            else
X	        {
X	        fprintf(stderr,"Something went wrong could not write \\n to file\n",write_return);
X	        }
X            abort();
X            }
X	}
X    }


X/*
X    Adds a line to comments;
X*/
Xvoid
Xadd_comment(line,im)
Xchar *line;
Ximage_pt im;
X    {
X    card length = (card) strlen(line);
X    char *strcpy();

X/* 
X    add in the length of the line and the carriage return 
X    to the comment length
X*/
X    im->head.cv_lcom += (im->head.cv_lcom == 0) ? length : length + 1;

X/* increment the number of lines */
X    im->comment.number_lines++;

X/* allocates space for new line length */
X    im->comment.line_lengths = (card *) realloc
X					(
X					(char *) (im->comment.line_lengths),
X					(unsigned) (im->comment.number_lines*sizeof(card))
X					);
X/* store new line length */
X    im->comment.line_lengths[im->comment.number_lines-1] = length;
X    
X/* allocates space for ptr to new line */
X    im->comment.lines = (char **) realloc
X					(
X					(char *) (im->comment.lines),
X					(unsigned) (im->comment.number_lines*sizeof(char *))
X					);

X/* allocates space and copies in new line */
X    im->comment.lines[im->comment.number_lines-1] = strcpy
X		(
X		(char *) MALLOC((length+1)*sizeof(char)),
X		line
X		);
X    }

X    
X/*
X    Appends the comments from one image to the comments of another
X    im1 has im2's comments appended to it
X*/
Xvoid
Xappend_comments(im1,im2)
Ximage_pt im1,im2;
X    {
X    register card i;

X/* iterate through the lines of im2 adding them 1 at a time */
X    for(i = 0 ; i < im2->comment.number_lines ; i++) 
X	{
X	add_comment(im2->comment.lines[i],im1);
X	}
X    }

X/*
X    Prints comments to file
X*/
Xvoid
Xprint_comments(fptr,im)
XFILE *fptr;
Ximage_pt im;
X    {
X    card numlines = im->comment.number_lines;
X    register card i;
X    for(i = 0; i < numlines; i++)
X	{
X	fprintf(fptr,"%s\n",im->comment.lines[i]);
X	}
X    }
@//E*O*F varc++/image.c.old//
chmod u=rw,g=r,o=r $OUT
 
echo x - varc++/double_image.c++
if test -f varc++/double_image.c++ ; then
    echo varc++/double_image.c++ exists, putting output in $$varc++/double_image.c++
    OUT=$$varc++/double_image.c++
    STATUS=1
else
    OUT=varc++/double_image.c++
fi
sed 's/^X//' > $OUT <<'@//E*O*F varc++/double_image.c++//'
X/*
X    This file contains the routines necessary to manipulate an image
X    of 8 bit data that do not need to know about the image file format
X*/

X#include <stream.h>
X#include <stdio.h>

X#include "for.h++"

X#include "double_image.h++"


X/* the constructor when the image is built */
Xdouble_image::double_image 
X    ( 
X    const create_image_type cit ,	// marker that the image is being created
X    const card n_rows , 		// the number of rows in the image
X    const card n_cols , 		// the number of collumns in the image
X    const FILE * image_file ,	// file for image
X    const card w_width = 1 ,	// window width
X    const card w_length = 1 	// window length
X    )
X    : ( CREATE , image_file , n_rows , n_cols , w_width , w_length )
X    {
X    /* check that the constructor is called correctly */
X    if ( cit != CREATE )
X	{
X	cerr << "constructor for double_image being called in obscure way\n";
X	abort();
X	}
X    
X    /* allocate space for image */
X    image_buffer = new double [ n_rows*n_cols ];

X    /* allocate space for dope vector */
X    image_rows = new double * [ n_rows ];
X    /* allocate space for window dope vector */
X    window_rows = new double * [ w_length ];

X    /* initialize dope vector */
X    FOR(int i1 = 0 ; i1 < n_rows; i1++)
X	{
X	image_rows[i1] = image_buffer + i1*n_cols;
X	}
X    ENDFOR

X    /* set up the protection  so the image can be written */
X    prot = CAN_WRITE;

X    /* initialize function pointers */
X    next = &uninitialized_next;
X    prev = &uninitialized_prev;
X    get_w_e_pointer = &uninitialized_get_w_e;
X    write_w_e_pointer = &uninitialized_write_w_e;
X    }


X/* functions for function pointers */

X/* this version of next assumes the window has been initialized */
Xint 
Xdouble_image::initialized_next ()
X    {
X    // if at the end of a row
X    if ( collumn + window_width == number_cols )
X	{
X	// if at the end of the image
X	if ( row + window_length == number_rows )
X	    {
X	    return 0;
X	    }
X	// otherwise go to the beginning of the next row
X	collumn = 0;
X	row++;
X	// reset the pointers in the window
X	FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	    {
X	    window_rows[i1] = image_rows[row + i1];
X	    }
X	ENDFOR
X	// return successfully
X	return 1;
X	}
X    // otherwise move adouble row
X    collumn++;
X    // move the pointers in the window
X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	{
X	window_rows[i1]++;
X	}
X    ENDFOR
X    // return successfully
X    return 1;
X    }

X/* this version of prev assumes the window has been initialized */
Xint 
Xdouble_image::initialized_prev ()
X    {
X    // if at beginning of a row
X    if ( collumn == 0 )
X	{
X	// if at the beginning of the image
X	if ( row == 0 )
X	    {
X	    return 0;
X	    }
X	// otherwise go to the end of the previous row
X	collumn = number_cols - window_width;
X	row--;
X	// reset the pointers in the window
X	FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	    {
X	    window_rows[i1] = image_rows[row + i1] + collumn;
X	    }
X	ENDFOR
X	// return successfully
X	return 1;
X	}
X    // otherwise move back on the row
X    collumn--;
X    // move the pointers in the window
X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	{
X	window_rows[i1]--;
X	}
X    ENDFOR
X    // return successfully
X    return 1;
X    }

X/* this version of next initializes the window */
Xint 
Xdouble_image::uninitialized_next ()
X    {
X    // check that the window fits in the image
X    if ( (window_width > number_cols) || (window_length > number_rows) )
X	{
X	return 0;
X	}

X    // set row and collumn to 0
X    row = 0;
X    collumn = 0;

X    // set the window row pointers
X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	{
X	window_rows[i1] = image_rows[row + i1];
X	}
X    ENDFOR

X    // set the function pointers
X    next = &initialized_next;
X    prev = &initialized_prev;
X    get_w_e_pointer = &initialized_get_w_e;
X    write_w_e_pointer = &initialized_write_w_e;

X    // set the window status
X    window_status = INITIALIZED;
X    return 1;
X    }

X/* this version of prev initializes the window */
Xint 
Xdouble_image::uninitialized_prev ()
X    {
X    // check that the window fits in the image
X    if ( (window_width > number_cols) || (window_length > number_rows) )
X	{
X	return 0;
X	}

X    // set row and collumn to bottom right of image
X    row = number_rows - window_length;
X    collumn = number_cols - window_width;
X    // set the window row pointers
X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	{
X	window_rows[i1] = image_rows[row + i1] + collumn;
X	}
X    ENDFOR

X    // set the function pointers
X    next = &initialized_next;
X    prev = &initialized_prev;
X    get_w_e_pointer = &initialized_get_w_e;
X    write_w_e_pointer = &initialized_write_w_e;

X    // set the window status
X    window_status = INITIALIZED;
X    return 1;
X    }

X// this version of next says that applying the next operation is impossible
Xint
Xdouble_image::impossible_next ( )
X    {
X    cerr << "Trying to apply the next operation to an image for which it is impossible!\n";
X    return 0;
X    }

X// this version of prev says that applying the next operation is impossible
Xint
Xdouble_image::impossible_prev ( )
X    {
X    cerr << "Trying to apply the prev operation to an image for which it is impossible!\n";
X    return 0;
X    }

X/* uninitialized version of get_w_e will just die */
Xdouble 
Xdouble_image::uninitialized_get_w_e ( const card i , const card j )
X    {
X    cerr << "Trying to get an element of an uninitialized window\n";
X    cerr << "The element was " << i << "," << j << "\n";
X    abort ();
X    return 0;
X    }


X/* initialized version of get_w_e */
Xdouble 
Xdouble_image::initialized_get_w_e ( const card i , const card j )
X    {
X    // check that i,j is in the window
X    if ( ( i >= window_length ) || ( j >= window_width ) )
X	{
X	cerr << "Tried to access element outside window\n";
X	cerr << "Window size " << window_length << "," << window_width << "\n";
X	cerr << "Accessed " << i << "," << j << "\n";
X	abort ();
X	return 0;
X	}
X    
X    // otherwise return the element
X    return window_rows[i][j];
X    }

X/* uninitialized version of write_w_e will just die */
Xvoid 
Xdouble_image::uninitialized_write_w_e ( const card i , const card j , const double value )
X    {
X    cerr << "Trying to write to an element of an uninitialized window\n";
X    cerr << "Trying to write " << value << "\n";
X    cerr << "To " << i << "," << j << "\n";
X    abort ();
X    }

X/* initialized version of write_w_e */
Xvoid 
Xdouble_image::initialized_write_w_e ( const card i , const card j , const double value)
X    {
X    // check that i,j is in the window
X    if ( ( i >= window_length ) || ( j >= window_width ) )
X	{
X	cerr << "Tried to access element outside window\n";
X	cerr << "Window size " << window_length << "," << window_width << "\n";
X	cerr << "Accessed " << i << "," << j << "\n";
X	abort ();
X	}
X    
X    // otherwise set the element
X    window_rows[i][j] = value;
X    }

X/*
X    move in row n steps 
X    returns 1 when that motion is legal 0 otherwise
X*/
Xint 
Xdouble_image::move_collumn ( const int n ) 
X    {
X    // the version in image does the checking and most of the work
X    int result = image_class::move_collumn ( n );

X    // if the move was successful move the window
X    if ( result == 1 )
X	{
X	FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	    {
X	    window_rows[i1] += n;
X	    }
X	ENDFOR
X	}

X    return result;
X    }

X/*
X    move in collumn n steps
X    returns 1 when that motion is legal 0 otherwise
X*/
Xint 
Xdouble_image::move_row ( const int n ) 
X    {
X    // the version in image does the checking and most of the work
X    int result = image_class::move_row ( n );

X    // if the move was successful move the window
X    if ( result == 1 )
X	{
X	FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	    {
X	    window_rows[i1] = image_rows[row + i1] + collumn ;
X	    }
X	ENDFOR
X	}

X    return result;
X    }


X/*
X    move to specified row
X*/
Xvoid 
Xdouble_image::move_to_row ( const card n ) 
X    {
X    // the version in image does the checking and most of the work
X    image_class::move_to_row ( n );

X    // move the window to the specified place
X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	{
X	window_rows[i1] = image_rows[row + i1] + collumn ;
X	}
X    ENDFOR
X    }


X/*
X    move to specified collumn
X*/
Xvoid 
Xdouble_image::move_to_collumn ( const card n ) 
X    {
X    // the version in image does the checking and most of the work
X    image_class::move_to_collumn ( n );

X    // move the window to the specified place
X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
X	{
X	window_rows[i1] = image_rows[row + i1] + collumn ;
X	}
X    ENDFOR
X    }



X/*
X    Gets a pointer to a row
X    of the image
X*/
Xconst double * 
Xdouble_image::get_row( card row )
X    {
X    // Checks to make sure request is legal
X    if ( row >= number_rows )
X	{
X	cerr << "Tried to accesses row " << row;
X	cerr << " when image only has " << number_rows << " rows!\n";
X	abort();
X	}
X    if ( image_status == UNINITIALIZED )
X	{
X	cerr << "Trying to read row from unitialized image!\n";
X	abort();
X	}
X    if ( (prot != CAN_READ) && (prot != CAN_READ_AND_WRITE) )
X	{
X	cerr << "Trying to access a row of an image protected against reading!\n";
X	abort();
X	}
X    
X    return image_rows[row];
X    }

X/*
X    Change the size of a window
X    causes the window to become uninitialized
X*/
Xvoid 
Xdouble_image::resize_window ( card width , card length )
X    {

X    // set the window
X    window_width = width;
X    window_length = length;
X    window_status = UNINITIALIZED;

X    /* allocate space for window dope vector */
X    window_rows = new double * [ window_length ];

X    /* reset function pointers */
X    next = &uninitialized_next;
X    prev = &uninitialized_prev;
X    get_w_e_pointer = &uninitialized_get_w_e;
X    write_w_e_pointer = &uninitialized_write_w_e;
X    }

X/*
X    Causes the window to cover the entire image.
X    Allows one to access any part of the image with window operations
X*/
Xvoid 
Xdouble_image::window_entire_image ( )
X    {
X    // set up the window
X    window_width = number_cols;
X    window_length = number_rows;
X    window_status = INITIALIZED;
X    // make the window dope vector an alias for the image dope vector
X    window_rows = image_rows;

X    // set up function pointers so next and previous impossible
X    next = &impossible_next;
X    prev = &impossible_prev;
X    // access functions
X    get_w_e_pointer = &initialized_get_w_e;
X    write_w_e_pointer = &initialized_write_w_e;
X    }
X/*
XCopyright (C) 1986, David Sher in the University of Rochester
XPermission is granted to any individual or institution to use, copy, or
Xredistribute this software so long as it is not sold for profit, provided
Xthis copyright notice is retained.
X*/
@//E*O*F varc++/double_image.c++//
chmod u=rw,g=r,o=r $OUT
 
echo x - vartools/trunc.c++
if test -f vartools/trunc.c++ ; then
    echo vartools/trunc.c++ exists, putting output in $$vartools/trunc.c++
    OUT=$$vartools/trunc.c++
    STATUS=1
else
    OUT=vartools/trunc.c++
fi
sed 's/^X//' > $OUT <<'@//E*O*F vartools/trunc.c++//'
X/*
X    This is the routine that takes in a double image and truncates
X    it to a long image
X*/
X#include <stdio.h>
X#include <string.h>
X#include <long_image.h++>
X#include <double_image.h++>
X#include "vartools.h++"

X/*
X    Truncates an input image needs a file to be output to
X    but does not write to file
X*/
Xlong_image&
Xtrunc2( double_image& input , FILE *outfile )
X    {
X    long_image *output_p = new long_image(CREATE,input.n_rows(),input.n_cols(),outfile);
X    long_image& output = *output_p;
X    while(++input,++output)
X	{
X	output() = input();
X	}
X    return output;
X    }


X/*
X    Takes two files and reads from one to write to the other
X*/
Xvoid
Xtrunc( FILE *infile , FILE *outfile, char *comment)
X    {
X    double_image input(READ,infile);
X    long_image& output = trunc2(input,outfile);
X    output.set_comments(comment,strlen(comment));
X    output.add_comment("The file being truncated is:\n",strlen("The file being truncated is:\n"));
X    output.add_comment((char *) input.the_comments(),input.c_length());
X    output.write();
X    }
X/*
XCopyright (C) 1986, David Sher in the University of Rochester
XPermission is granted to any individual or institution to use, copy, or
Xredistribute this software so long as it is not sold for profit, provided
Xthis copyright notice is retained.
X*/
@//E*O*F vartools/trunc.c++//
chmod u=rw,g=r,o=r $OUT
 
echo x - vartools/scale.c++
if test -f vartools/scale.c++ ; then
    echo vartools/scale.c++ exists, putting output in $$vartools/scale.c++
    OUT=$$vartools/scale.c++
    STATUS=1
else
    OUT=vartools/scale.c++
fi
sed 's/^X//' > $OUT <<'@//E*O*F vartools/scale.c++//'

X/*
X    This file contains the declarations necessary to scale 
X    the pixels in images.
X*/

X#include <stream.h>
X#include <stdio.h>
X#include <string.h>
X#include <double_image.h++>
X#include "vartools.h++"

X/*
X    This takes an image as input and create another
X*/
Xdouble_image&
Xscale2(double scale, double increment, double_image& input, FILE *output_file)
X    {
X    // create the output image 
X    double_image *output_pointer = 
X	new double_image(CREATE,input.n_rows(),input.n_cols(),output_file);
X    double_image& output = *output_pointer;

X    // scale  and increment the image
X    while(input++,output++)
X	{
X	output() = input() * scale + increment;
X	}
X    
X    return output;
X    }

X/*
X    This takes two files and takes one and puts a scaled version into the other
X*/
Xvoid
Xscale(double scale, double increment, FILE *input, FILE *output, char * comment)
X    {
X    // read in the input image
X    double_image input_image(READ,input);
X    // scale and  increment it
X    double_image& output_image = scale2(scale,increment,input_image,output);
X    // set up the comments
X    output_image.set_comments(comment,strlen(comment));
X    // add the comments 
X    char *string = 
X	form("Scaling image: scale %lf increment %lf\n",scale,increment);
X    output_image.add_comment(string,strlen(string));
X    output_image.add_comment((char *) input_image.the_comments(),input_image.c_length());

X    // output the image to file
X    output_image.write();
X    }
X/*
XCopyright (C) 1986, David Sher in the University of Rochester
XPermission is granted to any individual or institution to use, copy, or
Xredistribute this software so long as it is not sold for profit, provided
Xthis copyright notice is retained.
X*/
@//E*O*F vartools/scale.c++//
chmod u=rw,g=r,o=r $OUT
 
echo x - vartools/correlate.c++
if test -f vartools/correlate.c++ ; then
    echo vartools/correlate.c++ exists, putting output in $$vartools/correlate.c++
    OUT=$$vartools/correlate.c++
    STATUS=1
else
    OUT=vartools/correlate.c++
fi
sed 's/^X//' > $OUT <<'@//E*O*F vartools/correlate.c++//'
X/*
X    This is the source file for correlation routines
X*/

X#include <stream.h>
X#include <stdio.h>
X#include <string.h>
X#include <for.h++>
X#include <double_image.h++>
X#include "vartools.h++"

X// this routine correlates the image at a point
Xdouble
Xdo_correlate(double_image& template, double_image& input)
X    {
X    // total sums up the correlation
X    double total = 0.;

X    // iterate through the template
X    FOR(int i1 = 0 ; i1 < template.n_rows() ; i1++)
X	{
X	FOR(int i2 = 0 ; i2 < template.n_cols() ; i2++)
X	    {
X	    total += template.get_w_e(i1,i2)*input.get_w_e(i1,i2);
X	    }
X	ENDFOR
X	}
X    ENDFOR

X    return total;
X    }

X// this one takes 2 images and returns an image containing the correlation
Xdouble_image&
Xcorrelate2(double_image& template, double_image& input, FILE *output_file)
X    {
X    // check that the template is smaller than the input
X    if 
X	( 
X	(template.n_rows() > input.n_rows()) 
X	|| 
X	(template.n_cols() > input.n_cols()) 
X	)
X	{
X	cerr << form
X	    (
X	    "Template[%d,%d] is larger than image[%d,%d]!\n",
X	    template.n_rows(),
X	    template.n_cols(),
X	    input.n_rows(),
X	    input.n_cols(),
X	    );
X	abort();
X	}
X    // the output will only have points of the input that
X    // can be completely calculated (template does not fall off edge)
X    double_image *output_pointer = new double_image
X	(
X	CREATE,
X	input.n_rows() - template.n_rows() + 1,
X	input.n_cols() - template.n_cols() + 1,
X	output_file
X	);
X    double_image& output = *output_pointer;
X    
X    // make sure the window size is the same as the template size
X    // for the input
X    input.resize_window(template.n_cols(),template.n_rows());

X    // make the entire template random accessable
X    template.window_entire_image();

X    // iterate through image correlating
X    while(++input,++output)
X	{
X	output() = do_correlate(template,input);
X	}
X    
X    // return the output image
X    return output;
X    }

X// this one takes 3 file pointers
Xvoid
Xcorrelate(FILE *template_file, FILE *input_file, FILE *output_file, char *comment)
X    {
X    // read in the template and input file
X    double_image template(READ,template_file);
X    double_image input(READ,input_file);

X    // do the correlation
X    double_image& output = correlate2(template,input,output_file);

X    // construct the comments
X    output.set_comments(comment,strlen(comment));
X    output.add_comment("Engaged in correlation, template is:\n",strlen("Engaged in correlation, template is:\n"));
X    output.add_comment((char *) template.the_comments(), template.c_length());
X    output.add_comment("\nImage is:\n",strlen("\nImage is:\n"));
X    output.add_comment((char *) input.the_comments(), input.c_length());

X    // write the image to file
X    output.write();
X    }
X/*
XCopyright (C) 1986, David Sher in the University of Rochester
XPermission is granted to any individual or institution to use, copy, or
Xredistribute this software so long as it is not sold for profit, provided
Xthis copyright notice is retained.
X*/
@//E*O*F vartools/correlate.c++//
chmod u=rw,g=r,o=r $OUT
 
echo Inspecting for damage in transit...
temp=/tmp/sharin$$; dtemp=/tmp/sharout$$
trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
cat > $temp <<\!!!
     426    1682   10472 long_image.c++
     286    1115    6652 image.c++
     567    1631   12970 image.c.old
     429    1682   10537 double_image.c++
      46     162    1291 trunc.c++
      59     198    1700 scale.c++
     109     344    2977 correlate.c++
    1922    6814   46599 total
!!!
wc  varc++/long_image.c++ varc++/image.c++ varc++/image.c.old varc++/double_image.c++ vartools/trunc.c++ vartools/scale.c++ vartools/correlate.c++ | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
if test -s $dtemp ; then
    echo "Ouch [diff of wc output]:"
    cat $dtemp
    STATUS=1
elif test $STATUS = 0 ; then
    echo "No problems found."
else
    echo "WARNING -- PROBLEMS WERE FOUND..."
fi
exit $STATUS