home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
vis-ftp.cs.umass.edu
/
vis-ftp.cs.umass.edu.tar
/
vis-ftp.cs.umass.edu
/
pub
/
Software
/
ASCENDER
/
umass_foa.tar
/
mdt_NEW
/
ISRhdrs
/
TokenStream.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-11
|
23KB
|
939 lines
/*
* ------------------------------------------------------------------
* TokenStream.cc - TokenStream implementation
* Created by Bruce Draper
* ------------------------------------------------------------------
* Modification History: $Log: TokenStream.cc,v $
// Revision 1.6 1994/11/23 21:02:51 heller
// Add magic number and auto byte swaping code (.isrb files)
//
// Revision 1.5 1994/10/26 16:42:05 heller
// Add code to allow writing BytePlanes as GIF files (greyscale).
//
// Revision 1.4 1994/10/26 14:30:52 heller
// add support to write intensity planes from ColorImage
// tokens when the output format only supports a single
// Plane token (.plane and .im type output streams).
//
// Revision 1.3 1994/10/17 18:07:37 heller
// Added support for writing viff 3-band color images.
//
// Revision 1.2 1994/10/14 19:46:21 heller
// Added support for reading viff 3-band color images.
//
* ------------------------------------------------------------------
* Contents:
* ------------------------------------------------------------------
*
*
* Copyright 1994 University of Massachusetts.
* All rights reserved.
*
* Permission to copy and modify this software and its documen-
* tation only for internal use in your organization is hereby
* granted, provided that this notice is retained thereon and
* on all copies. UMASS makes no representations as to the sui-
* tability and operability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
* UMASS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
* NESS. IN NO EVENT SHALL UMASS BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
* SOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER-
* FORMANCE OF THIS SOFTWARE.
*
* No other rights, including, for example, the right to redis-
* tribute this software and its documentation or the right to
* prepare derivative works, are granted unless specifically
* provided in a separate license agreement.
*
* Copyright 1994, University of Massachusetts. All rights
* reserved.
*
*
*/
static char rcsid[] = "$Id: TokenStream.cc,v 1.6 1994/11/23 21:02:51 heller Exp $";
#include <TokenStream.h>
extern Registry *print_registry;
/* File Organization:
* Part 1: TokenStream code: TokenIStreams and TokenOStreams are top-level
streams for the user. They read/write any type of token.
* Part 2: ISRIstream & ISROstream: code for implementing .isra and .isrb file
formats.
* Part3: code for reading other formats (.viff, .im, ... )
*/
/* Part 1 ****************************************************************/
void TokenStream::TokenStreamInit()
{
name = NULL;
state = Closed;
format = untyped;
}
void TokenStream::TokenStreamFree()
{
TokenStreamInit();
}
int TokenStream::SetFormat(StreamFormat stream_format)
{
cerr << "Error: use TokenIStream or TokenOStream, not TokenStream.\n";
exit(-1);
return(0); // make the compiler happy
}
int TokenStream::openp()
{
if (state == Open) return 1;
else return 0;
}
int TokenStream::MatchFormatToFilename(char *filename)
{
if (NULL == filename) {
cerr << "Filename is NULL.\n";
return(-1);
}
if (NULL != strstr(filename, ".isrb")) {
SetFormat(isrb);
return(0);
}
if (NULL != strstr(filename, ".isra")) {
SetFormat(isra);
return(0);
}
if (NULL != strstr(filename, ".plane")) {
SetFormat(plane);
return(0);
}
#ifdef KHOROS
if (NULL != strstr(filename, ".viff")) {
SetFormat(viff);
return(0);
}
if (NULL != strstr(filename, ".xv")) {
SetFormat(viff);
return(0);
}
#endif
#ifdef KBV
if (NULL != strstr(filename, ".im")) {
SetFormat(im);
return(0);
}
if (NULL != strstr(filename, ".tks")) {
SetFormat(tks);
return(0);
}
#endif
if (NULL != strstr(filename, ".gif")) {
SetFormat(gif);
return(0);
}
#ifdef TIFFLIB
if (NULL != strstr(filename, ".tiff")) {
SetFormat(tiff);
return(0);
}
if (NULL != strstr(filename, ".tif")) {
SetFormat(tiff);
return(0);
}
#endif
cerr << "Unrecognized file extension.\n";
return(-1);
}
void TokenOStream::open(char *filename)
{
if (state == Open) {
cerr << "Warning: Attempt to open already opened TokenOStream.\n";
return;
}
name = filename;
state = Open;
if (format_stream == NULL) MatchFormatToFilename(filename);
if (format_stream == NULL) {
cerr << "Unable to open file.\n";
exit(-1);
}
format_stream->open(filename);
}
void TokenOStream::close()
{
if (state == Closed) {
cerr << "Warning: Attempt to close already closed TokenOStream.\n";
return;
}
state = Closed;
if (format_stream != NULL) format_stream->close();
}
int TokenOStream::SetFormat(StreamFormat stream_format)
{
/* first, check stream state (should be closed with format == NULL) */
if (state == Open) {
cerr << "attempt to reformat stream when file is open! (Close file first.)\n";
return -1;
}
if (format_stream != NULL) delete format_stream;
format = stream_format;
switch (stream_format) {
case isra:
format_stream = new ISROStream(isra);
break;
case isrb:
format_stream = new ISROStream(isrb);
break;
case plane:
format_stream = new PlaneOStream;
break;
#ifdef KHOROS
case viff:
format_stream = new ViffOStream;
break;
#endif
#ifdef KBV
case im:
format_stream = new ImOStream;
break;
case tks:
format_stream = new TksOStream;
break;
#endif
case gif:
format_stream = new GifOStream;
break;
#ifdef TIFFLIB
case tiff:
format_stream = new TiffOStream;
break;
#endif
default:
cerr << "Unknown or unimplemented file type.\n";
format = untyped;
return -1;
}
return 0;
}
TokenOStream::TokenOStream()
{
TokenStreamInit();
format_stream = NULL;
}
TokenOStream::TokenOStream(StreamFormat type)
{
TokenStreamInit();
format_stream = NULL;
SetFormat(type);
}
TokenOStream::TokenOStream(char *filename)
{
TokenStreamInit();
format_stream = NULL;
MatchFormatToFilename(filename);
}
TokenOStream::~TokenOStream()
{
if (format_stream != NULL) delete format_stream;
TokenStreamFree();
}
TokenOStream& operator << (TokenOStream& tos, Token& tok)
{
if (tos.state == Closed) {
if (tos.name == NULL) {
cerr << "attempt to write to unopened & unnamed file.\n";
exit(-1);
}
else tos.open(tos.name);
}
tos.format_stream->write_token(tok);
return tos;
}
TokenOStream& operator << (TokenOStream& tos, Token* tok)
{
tos << *tok;
return tos;
}
int operator ! (TokenOStream& tos)
{
if (tos.format_stream == NULL) return 0;
else return !(*tos.format_stream);
}
void TokenIStream::open(char *filename)
{
if (state == Open) {
cerr << "Warning: Attempt to open already open TokenIStream.\n";
return;
}
name = filename;
state = Open;
if (format_stream == NULL) MatchFormatToFilename(filename);
if (format_stream == NULL) {
cerr << "Unable to open file.\n";
exit(-1);
}
format_stream->open(filename);
}
void TokenIStream::close()
{
if (state == Closed) {
cerr << "Warning: Attempt to close already closed TokenIStream.\n";
return;
}
state = Closed;
if (format_stream != NULL) format_stream->close();
}
int TokenIStream::SetFormat(StreamFormat stream_format)
{
/* first, check stream state (should be closed with format == NULL) */
if (state == Open) {
cerr << "attempt to reformat stream when file is open! (Close file first.)\n";
return -1;
}
if (format_stream != NULL) delete format_stream;
format = stream_format;
switch (stream_format) {
case isra:
format_stream = new ISRIStream(isra); break;
case isrb:
format_stream = new ISRIStream(isrb); break;
case plane:
format_stream = new PlaneIStream; break;
#ifdef KHOROS
case viff:
format_stream = new ViffIStream; break;
#endif
#ifdef KBV
case im:
format_stream = new ImIStream; break;
case tks:
format_stream = new TksIStream;
break;
#endif
case gif:
format_stream = new GifIStream;
break;
#ifdef TIFFLIB
case tiff:
format_stream = new TiffIStream;
break;
#endif
default:
cerr << "Unknown or unimplemented file type.\n";
format = untyped;
return -1;
}
return 0;
}
TokenIStream::TokenIStream()
{
TokenStreamInit();
format_stream = NULL;
}
TokenIStream::TokenIStream(StreamFormat type)
{
TokenStreamInit();
format_stream = NULL;
SetFormat(type);
}
TokenIStream::TokenIStream(char *filename)
{
TokenStreamInit();
format_stream = NULL;
MatchFormatToFilename(filename);
}
TokenIStream::~TokenIStream()
{
if (format_stream != NULL) delete format_stream;
TokenStreamFree();
}
Token *TokenIStream::read_token_ptr()
{
if (state == Closed) {
if (name == NULL) {
cerr << "attempt to write to unopened & unnamed file.\n";
exit(-1);
}
else open(name);
}
return format_stream->read_token_ptr();
}
TokenIStream& operator >> (TokenIStream& tos, Token& tok)
{
if (tos.state == Closed) {
if (tos.name == NULL) {
cerr << "attempt to write to unopened & unnamed file.\n";
exit(-1);
}
else tos.open(tos.name);
}
tos.format_stream->read_token(tok);
return tos;
}
int operator ! (TokenIStream& tis)
{
if (tis.format_stream == NULL) return 0;
else return !(*tis.format_stream);
}
/** Part 2 ***********************************************************/
ISROStream::ISROStream(StreamFormat format)
{
if (format == isrb) isr_stream = new Isrostream(BINARY, ISR);
else if (format == isra) isr_stream = new Isrostream(ASCII, ISR);
else {
cerr << "ISROStream initialized with illegal StreaFormat.\n";
exit(-1);
}
if (isr_stream == NULL) {
cerr << "Unable to allocate Isrostream structure.\n";
exit(-1);
}
}
ISROStream::~ISROStream()
{
delete isr_stream;
}
void ISROStream::open(char *filename)
{
isr_stream->open(filename, ios::out);
}
void ISROStream::close()
{
isr_stream->close();
}
void ISROStream::write_token(Token& tok)
{
/* << sets up the table to guard against infinite loops
when printing. token_array_ptr is a pointer to an array
of token pointers. When a token is "demanded" by trace
(calling for some action) it is added to the token array,
(if it wasn't there already) and the demand ptr is advanced.
When a token is printed, the print ptr is advanced. Printing
continues until the print ptr catches the demand ptr, meaning
that every referenced token has been printed. */
Registry to_print(tok.token_count);
TypeDirectory* type_table_ptr = system_type_table();
Token *current_token;
int index;
Isrostream os = *isr_stream;
/* Set up registry and register the first token */
assert(print_registry == NULL);
print_registry = &to_print;
to_print.Register(&tok);
/* deactivate type table, to see which types are actually being printed */
type_table_ptr->deactivate();
/* recursively trace data tree from first token */
while (0 <= (index = to_print.next())) {
current_token = to_print.translate(index);
type_table_ptr->activate(current_token->type_index());
current_token->trace();
}
/* print file header */
os.write_magic_header();
os << to_print.count() << " tokens ";
os << type_table_ptr->active_entries() << " tokentypes ";
os << type_table_ptr->max_active_entry() << " maximum tokentype index\n\n";
if (!os) {
cerr << "Unable to write to output stream\n";
exit(-1);
}
type_table_ptr->print_active_entries(os);
/* recursively print traced tokens */
to_print.reset();
while (0 <= (index = to_print.next())) {
current_token = to_print.translate(index);
write_token_number_and_type(os, current_token, index);
os << "\n";
current_token->output(os);
os << "\n";
if (!os) {
cerr << "Error writing in token print function\n";
exit(-1);
}
}
/* Destroy static registry (destructor will execute when
to_print leaves the lexical scope). */
print_registry = NULL;
}
ISRIStream::ISRIStream(StreamFormat format)
{
if (format == isrb) isr_stream = new Isristream(BINARY, ISR);
else if (format == isra) isr_stream = new Isristream(ASCII, ISR);
else {
cerr << "ISRIStream initialized with illegal StreamFormat.\n";
exit(-1);
}
if (isr_stream == NULL) {
cerr << "Unable to allocate Isristream structure.\n";
exit(-1);
}
}
ISRIStream::~ISRIStream()
{
delete isr_stream;
}
void ISRIStream::open(char *filename)
{
isr_stream->open(filename, ios::in);
}
void ISRIStream::close()
{
isr_stream->close();
}
/* This dummy function allows the real reading function below 1) to take
a token to fill as an optional argument and 2) to be used by the PlaneIStream
class as well. (PlaneIStream is a subclass that will redefine read_token_ptr). */
Token* ISRIStream::read_token_ptr()
{
return internal_read_token_ptr();
}
Token* ISRIStream::internal_read_token_ptr (Token* preallocated/* = NULL*/)
{
Isristream is = *isr_stream;
int token_count = -1, tokentype_count = -1, max_tokentype_entry = -1, i;
Token* new_token;
if (!is) {
cerr << "File unopened or unable to read from file\n";
exit(-1);
}
/* open file and read how many tokens are in it. */
is.read_magic_header();
is >> token_count >> "tokens";
is >> tokentype_count >> "tokentypes";
is >> max_tokentype_entry >> "maximum tokentype index";
max_tokentype_entry++;
if ((!is) || (0 >= token_count) || (0 >= tokentype_count)
|| (tokentype_count > max_tokentype_entry))
{
cerr << "Unable to read header; probably wrong file type\n";
exit(-1);
}
/* allocate and read stream-specific tokentype table */
is.read_tokentype_table(tokentype_count, max_tokentype_entry);
/* allocate appropriate size registry */
print_registry = new Registry(token_count);
/* iteratively read all tokens in file */
for (i=0; i < token_count; i++) {
new_token = read_token_file_ptr(is, preallocated);
preallocated = NULL;
/* if new_token is NULL, an error has occurred, since NULL
pointers should only appear as feature values, not as tokens
to be read in their own right */
if (new_token == NULL) {
cerr << "file includes definition of NULL token\n";
exit(-1);
}
/* expand to include possible alt_inputs in the future, for
translating token types. */
new_token->input(is);
if (!is) {
cerr << "Error reading token (in user-defined read function)\n";
exit(-1);
}
}
/* deallocate registry and return pointer to first token */
new_token = print_registry->translate(0);
free(print_registry);
print_registry = NULL;
return new_token;
}
void ISRIStream::read_token (Token& tok)
{
internal_read_token_ptr(&tok);
}
/**********/
PlaneOStream::~PlaneOStream()
{
delete isr_stream;
}
void PlaneOStream::write_token(Token& tok)
{
if (strcmp(tok.name(), "ColorImage") == 0)
{
ColorImage *ci = (ColorImage*) &tok;
ci->intensity()->output(*isr_stream);
if (!(*isr_stream)) {
cerr << "Error writing token (in user-defined output function)\n";
exit(-1);
} else return;
} else if (NULL == strstr(tok.name(), "Plane")) {
cerr << "Plane Files can only store Plane tokens, not "
<< tok.name() << " tokens.\n";
cerr << "Nothing will be written to file or stream.\n";
return;
}
tok.output(*isr_stream);
if (!(*isr_stream)) {
cerr << "Error writing token (in user-defined output function)\n";
exit(-1);
}
}
PlaneIStream::~PlaneIStream()
{
delete isr_stream;
}
Token *PlaneIStream::read_token_ptr()
{
return (Token *)read_llvs_plane(*isr_stream);
}
void PlaneIStream::read_token(Token& tok)
{
Token *temp;;
Isristream is = *isr_stream;
if (NULL == strstr(tok.name(), "Plane")) {
cerr << "Plane Files can only store Plane tokens, not "
<< tok.name() << " tokens.\n";
cerr << "Nothing will be read from file or stream.\n";
return;
}
temp = read_llvs_plane(is);
if (!is) cerr << "Error in plane reading function.\n";
else copy_plane_header((Plane *)temp, (Plane *)&tok);
}
#ifdef KHOROS
void ViffOStream::open(char *fname)
{
filename = fname;
}
void ViffOStream::write_token(Token& tok)
{
if (strcmp(tok.name(), "ColorImage") == 0) {
if (!writecolorimage(filename, (ColorImage*)&tok)) {
cerr << "Viff Files can only store ColorImage tokens with active "
<< "RGB or HSV planes.\n";
}
} else if (NULL == strstr(tok.name(), "Plane")) {
cerr << "Viff Files can only store Plane or ColorImage tokens, not "
<< tok.name() << " tokens.\n";
cerr << "Nothing will be written to file or stream.\n";
return;
} else writeplaneimage(filename, (Plane *)&tok);
}
void ViffIStream::open(char *fname)
{
if (0 != access(fname, R_OK)) {
cerr << "Unable to find Viff file " << fname << " for reading. \n";
exit(-1);
}
filename = fname;
}
Token *ViffIStream::read_token_ptr()
{
struct xvimage *image = readimage(filename);
Token *result;
if (image == NULL)
{
cerr << "Cannot read image file: " << filename << "\n";
return NULL;
}
else if (image->num_of_images == 1 && image->num_data_bands == 1 &&
image->location_type == VFF_LOC_IMPLICIT)
{
result = (Token *)viff2llvs(image);
} else if (image->num_of_images == 1 && image->num_data_bands == 3 &&
image->location_type == VFF_LOC_IMPLICIT &&
(image->color_space_model == VFF_CM_ntscRGB ||
image->color_space_model == VFF_CM_cieRGB ||
image->color_space_model == VFF_CM_genericRGB ||
image->color_space_model == VFF_CM_HSV))
{
result = (Token *)viff2ColorImage(image);
} else
{
cerr << "Don't know how to deal with this viff file: " << filename << "\n";
result = NULL;
}
freeimage(image);
return result;
}
void ViffIStream::read_token(Token& tok)
{
Token *temp;
temp = read_token_ptr();
if (temp == NULL)
{
return;
} else if (strstr(tok.name(), "Plane") != NULL &&
strstr(temp->name(), "Plane") != NULL)
{
copy_plane_header((Plane *)temp, (Plane *)&tok);
} else if (strcmp(tok.name(),"ColorImage") == 0 &&
(strcmp(temp->name(),"ColorImage") == 0))
{
copy_ColorImage_header((ColorImage*)temp,(ColorImage*)&tok);
} else
{
cerr << "Viff Files can only store Plane or ColorImage tokens, not "
<< tok.name() << " tokens.\n";
cerr << "Nothing will be read from file or stream.\n";
}
}
#endif
#ifdef KBV
void ImOStream::open(char *fname)
{
filename = fname;
}
void ImOStream::write_token(Token& tok)
{
if (strcmp(tok.name(), "ColorImage") == 0)
{
ColorImage *ci = (ColorImage*) &tok;
writekbvimage(filename, (Plane *)(ci->intensity()));
return;
} else if (NULL == strstr(tok.name(), "Plane")) {
cerr << "Im Files can only store Plane tokens, not "
<< tok.name() << " tokens.\n";
cerr << "Nothing will be written to file or stream.\n";
return;
}
writekbvimage(filename, (Plane *)&tok);
}
void ImIStream::open(char *fname)
{
if (0 != access(fname, R_OK)) {
cerr << "Unable to find Im file " << fname << " for reading. \n";
exit(-1);
}
filename = fname;
}
Token *ImIStream::read_token_ptr()
{
return readkbvplane(filename);
}
void ImIStream::read_token(Token& tok)
{
Token *temp;
if (NULL == strstr(tok.name(), "Plane")) {
cerr << "Im Files can only store Plane tokens, not "
<< tok.name() << " tokens.\n";
cerr << "Nothing will be read from file or stream.\n";
return;
}
temp = read_token_ptr();
copy_plane_header((Plane *)temp, (Plane *)&tok);
}
#endif
void GifIStream::open(char *fname)
{
if (0 != access(fname, R_OK)) {
cerr << "Unable to find Gif file " << fname << " for reading. \n";
exit(-1);
}
filename = fname;
}
Token *GifIStream::read_token_ptr()
{
return (Token *)GIF2ColorImage(filename);
}
void GifIStream::read_token(Token& tok)
{
ColorImage *temp;
if (0 != strcmp(tok.name(), "ColorImage")) {
cerr << "Gif Files can only store ColorImage tokens, not "
<< tok.name() << " tokens.\n";
cerr << "Nothing will be read from file or stream.\n";
return;
}
temp = (ColorImage*) read_token_ptr();
((ColorImage*)&tok)->SetRedGreenBlue(temp->red(),temp->green(),temp->blue());
delete temp;
}
void GifOStream::open(char *fname)
{
filename = fname;
}
void GifOStream::write_token(Token& tok)
{
if (0 == strcmp(tok.name(), "BytePlane")) {
ColorImage *ci = new ColorImage((BytePlane*)&tok,
(BytePlane*)&tok,
(BytePlane*)&tok);
writeGifFile(filename, ci);
delete ci;
}
else if (0 != strcmp(tok.name(), "ColorImage")) {
cerr << "Gif Files can only store ColorImage tokens, not "
<< tok.name() << " tokens.\n";
cerr << "Nothing will be written to file or stream.\n";
} else writeGifFile(filename, (ColorImage *)&tok);
}
#ifdef TIFFLIB
void TiffIStream::open(char *fname)
{
if (0 != access(fname, R_OK)) {
cerr << "Unable to find Tiff file " << fname << " for reading. \n";
exit(-1);
}
filename = fname;
}
Token *TiffIStream::read_token_ptr()
{
return ReadTiffFile(filename);
}
void TiffIStream::read_token(Token& tok)
{
Token *temp;
if (strcmp(tok.name(),"BytePlane") != 0 &&
strcmp(tok.name(),"ColorImage") != 0)
{
cerr << "Tiff Files can only store ColorImage or BytePlane tokens, not "
<< tok.name() << " tokens.\n";
cerr << "Nothing will be read from file or stream.\n";
delete temp;
return;
}
temp = read_token_ptr();
if (strcmp(temp->name(),tok.name()) == 0)
{
if (strcmp(temp->name(),"BytePlane") == 0)
copy_plane_header((Plane*)&tok,(Plane*)temp);
else
{
ColorImage *ci = (ColorImage*) temp;
((ColorImage*)&tok)->SetRedGreenBlue(ci->red(),ci->green(),ci->blue());
delete temp;
}
}
else
{
cerr << "Tiff File is " << temp->name() << " and token is " << tok.name()
<< "\nNot the same, cannot convert\n";
delete temp;
}
}
void TiffOStream::open(char *fname)
{
filename = fname;
}
void TiffOStream::write_token(Token& tok)
{
if (strcmp(tok.name(),"BytePlane") == 0)
{
writeTiffFile(filename, (BytePlane*) &tok);
} else if (strcmp(tok.name(),"ColorImage") == 0)
{
writeTiffFile(filename, (ColorImage*) &tok);
} else
{
cerr << "Tiff Files can only store ColorImage or BytePlane tokens, not "
<< tok.name() << " tokens.\n";
cerr << "Nothing will be written to the file or stream.\n";
}
}
#endif