From 07b93dbf2b66fa23c5378ab0fa42f9a7f0083380 Mon Sep 17 00:00:00 2001 From: "Kevin M. Rosenberg" Date: Wed, 7 Jun 2000 00:59:38 +0000 Subject: [PATCH] r70: added imagefiles --- include/Makefile.am | 5 +- include/array2d.h | 54 ++++ include/ct.h | 34 ++- include/imagefile.h | 583 ++++++++++++++++++++++++++++++++++++++++++++ include/ir.h | 21 +- include/kmath.h | 10 +- include/kstddef.h | 26 +- 7 files changed, 702 insertions(+), 31 deletions(-) create mode 100644 include/array2d.h create mode 100644 include/imagefile.h diff --git a/include/Makefile.am b/include/Makefile.am index d821d3a..4d0ac6b 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1 +1,4 @@ -noinst_HEADERS=ascii.h cio.h ct.h ezplot.h ir.h keyboard.h kmath.h kstddef.h pol.h sdf.h sgp.h +noinst_HEADERS=ascii.h cio.h ct.h ezplot.h ir.h keyboard.h kmath.h kstddef.h pol.h sdf.h sgp.h array2d.h imagefile.h + + + diff --git a/include/array2d.h b/include/array2d.h new file mode 100644 index 0000000..8d7cf4e --- /dev/null +++ b/include/array2d.h @@ -0,0 +1,54 @@ +#ifndef ARRAY2D_H +#define ARRAY2D_H + +#include + +template +class Array2d { + private: + unsigned int nx; + unsigned int ny; + + public: + + T** array_data; + + Array2d (unsigned int x, unsigned int y) + { + nx = x; + ny = y; + array_data = new T*[nx]; + + for (int i = 0; i < nx; i++) + array_data[i] = new T[ny]; + } + + + ~Array2d () + { + for (int i = 0; i < nx; i++) + delete array_data[i]; + delete array_data; + } + + T** getArray (void) const + { return array_data; } + + T* getColumn (unsigned int x) const + { return array_data[x]; } + + T getPoint (unsigned int x, unsigned int y) const + { return (array_data[x][y]); } + + unsigned int sizeofPixel (void) const + { return sizeof(T); } + + unsigned int sizeofColumn (void) const + { return (sizeof(T) * ny); } + + unsigned int sizeofArray (void) const + { return (sizeof(T) * nx * ny); } +}; + + +#endif diff --git a/include/ct.h b/include/ct.h index 4d4ba75..c3fe3a0 100644 --- a/include/ct.h +++ b/include/ct.h @@ -2,8 +2,11 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: ct.h,v 1.6 2000/05/24 22:48:17 kevin Exp $ +** $Id: ct.h,v 1.7 2000/06/07 00:59:38 kevin Exp $ ** $Log: ct.h,v $ +** Revision 1.7 2000/06/07 00:59:38 kevin +** added imagefiles +** ** Revision 1.6 2000/05/24 22:48:17 kevin ** First functional version of SDF library for X-window ** @@ -41,13 +44,13 @@ #define CT_H #ifdef _WIN32 -typedef long off_t; -#define HAVE_STRING_H 1 -#include -#define snprintf _snprintf -#define vsnprintf _vsnprintf -#define strcasecmp stricmp -#define strncasecmp strnicmp + typedef long off_t; + #define HAVE_STRING_H 1 + #include + #define snprintf _snprintf + #define vsnprintf _vsnprintf + #define strcasecmp stricmp + #define strncasecmp strnicmp #endif #ifdef HAVE_CONFIG_H @@ -127,9 +130,20 @@ typedef long off_t; #include "ir.h" #include "keyboard.h" #include "cio.h" + #ifdef HAVE_SGP -#include "ezplot.h" -#include "sgp.h" + #include "ezplot.h" + #include "sgp.h" +#endif + +#ifdef __cplusplus + #include + #include + + using namespace std; + + #include "array2d.h" + #include "idf.h" #endif #endif diff --git a/include/imagefile.h b/include/imagefile.h new file mode 100644 index 0000000..0c2f8b5 --- /dev/null +++ b/include/imagefile.h @@ -0,0 +1,583 @@ +#ifndef IDF_H +#define IDF_H + +#include +#include "kstddef.h" +#include + +using namespace std; + +class Array2dFileLabel +{ +private: + void init (void); + +public: + kfloat64 calc_time; + kuint16 label_type; + kuint16 year; + kuint16 month; + kuint16 day; + kuint16 hour; + kuint16 minute; + kuint16 second; + string label_str; + + static const int L_EMPTY = 0; + static const int L_HISTORY = 1; + static const int L_USER = 2; + + Array2dFileLabel(); + + Array2dFileLabel(const char* const str, double ctime = 0.); + + Array2dFileLabel(const int type, const char* const str, double ctime = 0.); + + ~Array2dFileLabel(); + + const string& getLabelString (void) const + { return label_str; } + + kfloat64 getCalcTime (void) const + { return calc_time; } + + kfloat64 getLabelType (void) const + { return label_type; } + + void getDateString (string& str) const; +}; + + +template +class Array2dFile +{ +private: + void init (void); + kuint16 signature; + kuint16 num_labels; + kuint16 headersize; + string filename; + int file_id; + iostream *io; + bool bHeaderWritten; + bool bDataWritten; + + bool headerWrite (void); + + bool headerRead (void); + + bool arrayDataRead (void); + + bool labelSeek (unsigned int label_num); + +public: + kuint16 pixel_size; + kuint16 pixel_type; + kuint32 nx; + kuint32 ny; + + kuint16 axis_increment_known; + kfloat64 xinc, yinc; + kuint16 axis_extent_known; + kfloat64 xmin, xmax, ymin, ymax; + kfloat64 pv_offset, pv_scale; + + Array2d *array; + + static const int INT8 = 1; + static const int UINT8 = 2; + static const int INT16 = 3; + static const int UINT16 = 4; + static const int INT32 = 5; + static const int UINT32 = 6; + static const int FLOAT32 = 7; + static const int FLOAT64 = 8; + + Array2dFile (unsigned int nx, unsigned int ny); + Array2dFile (const char* const filename); + Array2dFile (const char* const filename, unsigned int nx, unsigned int ny); + ~Array2dFile (); + + virtual unsigned int getNumLabels (void) const + { return num_labels; } + + bool labelRead (Array2dFileLabel& label, unsigned int label_num); + + bool labelAdd (const char* const label_str, double calc_time=0.); + + bool labelAdd (int type, const char* const label_str, double calc_time=0.); + + void fileClose (void); + + void set_axis_increment (double xinc, double yinc); + + void set_axis_extent (double xmin, double xmax, double ymin, double ymax); + + void get_pixel_extent (T& pvmin, T& pvmax); + + void set_pixel_offset_extent (double offset, double scale); + + T** getArray (void) const + { return (array == NULL ? NULL : array->getArray()); } + + bool arrayDataWrite (void); + + bool fileRead (void); + + bool fileCreate (void); + + const string& GetFilename (void) const + { return filename; } +}; + + +template +void +Array2dFile::set_axis_increment (double xinc, double yinc) +{ + axis_increment_known = true; + this.xinc = xinc; + this.yinc = yinc; +} + +template +void +Array2dFile::set_axis_extent (double xmin, double xmax, double ymin, double ymax) +{ + axis_extent_known = true; + this.xmin = xmin; + this.ymax = xmax; + this.xmin = xmin; + this.ymax = ymax; +} + +template +void +Array2dFile::get_pixel_extent (T& pvmin, T& pvmax) +{ + if (array != NULL) { + T** da = array.GetArray(); + pvmax = pvmin = da[0][0]; + for (int ix = 0; ix < nx; ix++) + for (int iy = 0; iy < ny; iy++) + if (pvmax < da[ix][iy]) + pvmax = da[ix][iy]; + else if (pvmin > da[ix][iy]) + pvmin = da[ix][iy]; + } +} + +template +void +Array2dFile::set_pixel_offset_extent (double offset, double scale) +{ + pv_offset = offset; + pv_scale = scale; +} + +template +void +Array2dFile::init (void) +{ + pixel_size = sizeof(T); + signature = ('I' * 256 + 'F'); + file_id = -1; + nx = 0; + ny = 0; + headersize = 0; + num_labels = 0; + axis_increment_known = false; + axis_extent_known = false; + xinc = ymin = 0; + xmin = xmax = ymin = ymax = 0; + pv_offset = 0; + pv_scale = 1; + array = NULL; + io = NULL; + +#if 0 + const type_info& t_id = typeid(T); + cout << t_id.name() << endl; + const type_info& comp_id = typeid(T); + + if (t_id == comp_id) + pixel_type = FLOAT64; + else if (t_id == typeid(kfloat32)) + pixel_type = FLOAT32; + else if (t_id == typeid(kint32)) + pixel_type = INT32; + else if (t_id == typeid(kuint32)) + pixel_type = UINT32; + else if (t_id == typeid(kint16)) + pixel_type = INT16; + else if (t_id == typeid(kuint16)) + pixel_type = UINT16; + else if (t_id == typeid(kint8)) + pixel_type = INT8; + else if (t_id == typeid(kuint8)) + pixel_type = UINT8; + else +#endif + pixel_type = 0; + + bHeaderWritten = false; + bDataWritten = false; +} + +template +Array2dFile::Array2dFile (unsigned int x, unsigned int y) +{ + init(); + nx = x; + ny = y; + array = new Array2d (nx, ny); +} + +template +Array2dFile::Array2dFile (const char * const str, unsigned int x, unsigned int y) + : filename(str) +{ + init(); + nx = x; + ny = y; + array = new Array2d (nx, ny); +} + +template +Array2dFile::Array2dFile (const char * const str) + : filename(str) +{ + init(); +} + +template +bool +Array2dFile::fileCreate (void) +{ + // io = new iostream(filename, ios::out | ios::in | ios::trunc | io::binary); + if ((file_id = open (filename.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) { + sys_error (ERR_WARNING, "Error opening file %s for writing [fileCreate]", filename.c_str()); + return (false); + } + headerWrite(); + return (true); +} + +template +bool +Array2dFile::fileRead (void) +{ + // io = new iostream(filename, ios::out | ios::in | io::binary); + if ((file_id = open (filename.c_str(), O_RDONLY | O_BINARY)) < 0) { + sys_error (ERR_WARNING, "Unable to open file %s [fileRead]", filename.c_str()); + return (false); + } + + headerRead(); + if (array != NULL) + delete array; + + array = new Array2d (nx, ny); + + arrayDataRead(); + + return (true); +} + +template +bool +Array2dFile::headerRead (void) +{ + if (file_id < 0) { + sys_error (ERR_WARNING, "Tried to read header with file closed [headerRead]"); + return (false); + } + + lseek (file_id, 0, SEEK_SET); + kuint16 file_signature; + kuint16 file_pixel_size; + kuint16 file_pixel_type; + + read_nint16 (&headersize, file_id); + read_nint16 (&file_signature, file_id); + read_nint16 (&num_labels, file_id); + read_nint16 (&file_pixel_type, file_id); + read_nint16 (&file_pixel_size, file_id); + read_nint32 (&nx, file_id); + read_nint32 (&ny, file_id); + read_nint16 (&axis_increment_known, file_id); + read_nfloat64 (&xinc, file_id); + read_nfloat64 (&yinc, file_id); + read_nint16 (&axis_extent_known, file_id); + read_nfloat64 (&xmin, file_id); + read_nfloat64 (&xmax, file_id); + read_nfloat64 (&ymin, file_id); + read_nfloat64 (&ymax, file_id); + read_nfloat64 (&pv_offset, file_id); + read_nfloat64 (&pv_scale, file_id); + + int read_headersize = lseek (file_id, 0, SEEK_CUR); + if (read_headersize != headersize) { + sys_error (ERR_WARNING, "Read headersize %d != file headersize %d", read_headersize, headersize); + return (false); + } + if (file_signature != signature) { + sys_error (ERR_WARNING, "File signature %d != true signature %d", file_signature, signature); + return (false); + } + if (file_pixel_type != pixel_type) { + sys_error (ERR_WARNING, "File pixel type %d != class pixel type %d", file_pixel_type, pixel_type); + return (false); + } + if (file_pixel_size != pixel_size) { + sys_error (ERR_WARNING, "File pixel size %d != class pixel size %d", file_pixel_size, pixel_size); + return (false); + } + + return (true); +} + +template +bool +Array2dFile::headerWrite (void) +{ + if (file_id < 0) { + sys_error (ERR_WARNING, "Tried to write header with file closed"); + return (false); + } + + lseek (file_id, 0, SEEK_SET); + write_nint16 (&headersize, file_id); + write_nint16 (&signature, file_id); + write_nint16 (&num_labels, file_id); + write_nint16 (&pixel_type, file_id); + write_nint16 (&pixel_size, file_id); + write_nint32 (&nx, file_id); + write_nint32 (&ny, file_id); + write_nint16 (&axis_increment_known, file_id); + write_nfloat64 (&xinc, file_id); + write_nfloat64 (&yinc, file_id); + write_nint16 (&axis_extent_known, file_id); + write_nfloat64 (&xmin, file_id); + write_nfloat64 (&xmax, file_id); + write_nfloat64 (&ymin, file_id); + write_nfloat64 (&ymax, file_id); + write_nfloat64 (&pv_offset, file_id); + write_nfloat64 (&pv_scale, file_id); + + headersize = lseek (file_id, 0, SEEK_CUR); + lseek (file_id, 0, SEEK_SET); + write_nint16 (&headersize, file_id); + + return (true); +} + +template +bool +Array2dFile::arrayDataWrite (void) +{ + if (file_id < 0) { + sys_error (ERR_WARNING, "Tried to arrayDataWrite with file_id < 0"); + return (false); + } + + lseek (file_id, headersize, SEEK_SET); + for (int ix = 0; ix < nx; ix++) + { + write (file_id, array->array_data[ix], ny * pixel_size); + } + + return (true); +} + +template +void +Array2dFile::fileClose (void) +{ + headerWrite (); + if (file_id >= 0 && array != NULL) { + arrayDataWrite (); + close (file_id); + file_id = -1; + } +} + +template +Array2dFile::~Array2dFile (void) +{ + fileClose (); +} + + +template +bool +Array2dFile::arrayDataRead (void) +{ + if (file_id < 0) { + sys_error (ERR_WARNING, "Tried to arrayDataRead with file_id < 0"); + return (false); + } + + lseek (file_id, headersize, SEEK_SET); + for (int ix = 0; ix < nx; ix++) + { + read (file_id, array->array_data[ix], ny * pixel_size); + } + + return (true); +} + +template +bool +Array2dFile::labelSeek (unsigned int label_num) +{ + if (label_num > num_labels) { + sys_error (ERR_WARNING, "label_num %d > num_labels %d [labelSeek]"); + return (false); + } + + if (array == NULL) { // Could not have written data if array not allocated + sys_error (ERR_WARNING, "array == NULL [labelSeek]"); + return (false); + } + + off_t pos = headersize + array->sizeofArray(); + if (lseek (file_id, pos, SEEK_SET) != pos) { + sys_error (ERR_WARNING, "Can't seek to end of data array"); + return (false); + } + + for (int i = 0; i < label_num; i++) + { + pos += 22; // Skip to string length + if (lseek (file_id, pos, SEEK_SET) != pos) { + sys_error (ERR_WARNING, "Can't seek to string length"); + return (false); + } + kuint16 strlength; + read_nint16 (&strlength, file_id); + pos += 2 + strlength; // Skip label string length + data + if (lseek (file_id, pos, SEEK_SET) != pos) { + sys_error (ERR_WARNING, "Can't seek past label string"); + return (false); + } + } + + return (true); +} + +template +bool +Array2dFile::labelRead (Array2dFileLabel& label, unsigned int label_num) +{ + if (label_num >= num_labels) { + sys_error (ERR_WARNING, "Trying to read past number of labels [labelRead]"); + return (false); + } + + if (! labelSeek (label_num)) { + sys_error (ERR_WARNING, "Error calling labelSeek"); + return (false); + } + + read_nint16 (&label.label_type, file_id); + read_nint16 (&label.year, file_id); + read_nint16 (&label.month, file_id); + read_nint16 (&label.day, file_id); + read_nint16 (&label.hour, file_id); + read_nint16 (&label.minute, file_id); + read_nint16 (&label.second, file_id); + read_nfloat64 (&label.calc_time, file_id); + + kuint16 strlength; + read_nint16 (&strlength, file_id); + char *str = new char [strlength+1]; + read (file_id, str, strlength); + label.label_str = str; + + return (true); +} + + +template +bool +Array2dFile::labelAdd (const char* const lstr, double calc_time=0.) +{ + labelAdd (Array2dFileLabel::L_HISTORY, lstr, calc_time); +} + +template +bool +Array2dFile::labelAdd (int type, const char* const lstr, double calc_time=0.) +{ + Array2dFileLabel label (type, lstr, calc_time); + + labelSeek (num_labels); + + write_nint16 (&label.label_type, file_id); + write_nint16 (&label.year, file_id); + write_nint16 (&label.month, file_id); + write_nint16 (&label.day, file_id); + write_nint16 (&label.hour, file_id); + write_nint16 (&label.minute, file_id); + write_nint16 (&label.second, file_id); + write_nfloat64 (&label.calc_time, file_id); + kuint16 strlength = label.label_str.length(); + write_nint16 (&strlength, file_id); + write (file_id, static_cast(label.label_str.c_str()), strlength); + + num_labels++; + + headerWrite(); + fsync(file_id); +} + + +#endif + + +class F32Image +{ +public: + Array2dFile idf; + + F32Image (const char* const fname, unsigned int nx, unsigned int ny) : idf (fname, nx, ny) + { + idf.pixel_type = Array2dFile::FLOAT32; + } + + F32Image (unsigned int nx, unsigned int ny) : idf (nx, ny) + { + idf.pixel_type = Array2dFile::FLOAT32; + } + + F32Image (const char* const fname) : idf (fname) + { + idf.pixel_type = Array2dFile::FLOAT32; + } +}; + +class F64Image +{ +public: + Array2dFile idf; + + F64Image (const char* const fname, unsigned int nx, unsigned int ny) : idf (fname, nx, ny) + { + idf.pixel_type = Array2dFile::FLOAT64; + } + + F64Image (unsigned int nx, unsigned int ny) : idf (nx, ny) + { + idf.pixel_type = Array2dFile::FLOAT64; + } + + F64Image (const char* const fname) : idf (fname) + { + idf.pixel_type = Array2dFile::FLOAT64; + } +}; + +typedef F64Image ImageFile; + + diff --git a/include/ir.h b/include/ir.h index 3cc918a..0a04c79 100644 --- a/include/ir.h +++ b/include/ir.h @@ -2,8 +2,11 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: ir.h,v 1.18 2000/06/05 01:32:45 kevin Exp $ +** $Id: ir.h,v 1.19 2000/06/07 00:59:38 kevin Exp $ ** $Log: ir.h,v $ +** Revision 1.19 2000/06/07 00:59:38 kevin +** added imagefiles +** ** Revision 1.18 2000/06/05 01:32:45 kevin ** Added C++ compatibility ** @@ -82,10 +85,6 @@ #ifndef IR_H #define IR_H -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - #ifdef MPI_CT #define MPI_MAX_PROCESS 128 struct mpi_ct_st @@ -268,12 +267,12 @@ static const char D_FREQ_STR[]= "freq"; static const char D_SPATIAL_STR[]= "spatial"; typedef enum { - D_FREQ, + D_FREQ = 1, D_SPATIAL } DomainType; typedef enum { - FUNC_EVEN, /* function types, f[-n] = f[n] */ + FUNC_EVEN = 1, /* function types, f[-n] = f[n] */ FUNC_ODD, /* f[-n] = -f[n] */ FUNC_BOTH /* function has both odd & even components */ } FunctionSymmetry; @@ -281,7 +280,7 @@ typedef enum { /* interpolation methods */ #undef HAVE_BSPLINE_INTERP typedef enum { /* Interpolation methods */ - I_NEAREST, /* Nearest neighbor */ + I_NEAREST = 1, /* Nearest neighbor */ #if HAVE_BSPLINE_INTERP I_BSPLINE, I_1BSPLINE, /* 1st order B-Spline */ @@ -369,7 +368,11 @@ const static int RAYSUM_TRACE_ROW_ATTEN=18; /************************************************************************* * FUNCTION DECLARATIONS ************************************************************************/ - + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + void usage (const char *program); /* From reconstr.c */ diff --git a/include/kmath.h b/include/kmath.h index 3b4a36a..5bac1be 100644 --- a/include/kmath.h +++ b/include/kmath.h @@ -2,8 +2,11 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: kmath.h,v 1.9 2000/05/08 20:00:48 kevin Exp $ +** $Id: kmath.h,v 1.10 2000/06/07 00:59:38 kevin Exp $ ** $Log: kmath.h,v $ +** Revision 1.10 2000/06/07 00:59:38 kevin +** added imagefiles +** ** Revision 1.9 2000/05/08 20:00:48 kevin ** ANSI C changes ** @@ -78,11 +81,12 @@ extern "C" { /* codes for C data types */ #define DT_CHAR 1 -#define DT_INT 2 +#define DT_INT 2 #define DT_LONG 3 #define DT_FLOAT 4 #define DT_DOUBLE 5 -#define DT_STRING 6 +#define DT_UINT32 6 +#define DT_STRING 7 typedef char *CMTX_1D; typedef CMTX_1D *CMTX_2D; diff --git a/include/kstddef.h b/include/kstddef.h index f02ea8d..a6543dc 100644 --- a/include/kstddef.h +++ b/include/kstddef.h @@ -2,8 +2,11 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: kstddef.h,v 1.12 2000/06/05 01:32:45 kevin Exp $ +** $Id: kstddef.h,v 1.13 2000/06/07 00:59:38 kevin Exp $ ** $Log: kstddef.h,v $ +** Revision 1.13 2000/06/07 00:59:38 kevin +** added imagefiles +** ** Revision 1.12 2000/06/05 01:32:45 kevin ** Added C++ compatibility ** @@ -86,12 +89,9 @@ typedef int bool; /* Boolean variable type */ #define STR_MAX_LEN 255 #define STR_SIZE STR_MAX_LEN+1 +#if !defined(__cplusplus) typedef unsigned char string[STR_SIZE]; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - +#endif #include #include @@ -211,6 +211,9 @@ typedef struct timedate_st TIMEDATE; #define SIZEOF_DOUBLE 8 #endif +typedef signed char kint8; +typedef unsigned char kuint8; + #if SIZEOF_INT == 4 typedef int kint32; typedef unsigned int kuint32; @@ -234,6 +237,11 @@ typedef struct timedate_st TIMEDATE; typedef double kfloat64; #endif +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /* allocnum.c */ float *alloc_float(int n); double *alloc_double(int n); @@ -298,8 +306,10 @@ char *td_day_name(int n); /* netorder.c */ void *strreverse (void *dest, const void *src, size_t n); -int read_n32bint (kuint32 *n, int fd); -int write_n32bint (kuint32 const *n, int fd); +int read_nint16 (kuint16 *n, int fd); +int write_nint16 (kuint16 const *n, int fd); +int read_nint32 (kuint32 *n, int fd); +int write_nint32 (kuint32 const *n, int fd); int read_nfloat32 (float *f, int fd); int write_nfloat32 (float const *f, int fd); int read_nfloat64 (double *d, int fd); -- 2.34.1