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