diff options
Diffstat (limited to 'conversion/convertor.cc')
-rw-r--r-- | conversion/convertor.cc | 405 |
1 files changed, 405 insertions, 0 deletions
diff --git a/conversion/convertor.cc b/conversion/convertor.cc new file mode 100644 index 0000000..9c6f353 --- /dev/null +++ b/conversion/convertor.cc @@ -0,0 +1,405 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>. +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see <http://www.rasdaman.org> +* or contact Peter Baumann via <baumann@rasdaman.com>. +/ +/** + * SOURCE: convertor.cc + * + * MODULE: conversion + * + * CLASSES: r_Convertor, r_Convert_Memory + * + * PURPOPSE: + * Provides interface to convert data to other formats. + * + * COMMENTS: + * - FIXME: r_Convertor::get_internal_type(): every structType is recognised as RGB! + * +*/ + +#include "conversion/convertor.hh" +#include "conversion/memfs.hh" +#include "raslib/error.hh" +#include "raslib/parseparams.hh" +#include "raslib/rminit.hh" +#include "raslib/primitivetype.hh" + + +/* + * r_Convertor class + */ + +void r_Convertor::initShare( const char *src, const r_Minterval &interv ) +{ + desc.src = src; + desc.srcInterv = interv; + desc.srcType = NULL; + desc.destType = NULL; + desc.dest = NULL; + params = NULL; + destroySrc = false; +} + + +r_Convertor::r_Convertor( void ) +{ + desc.srcType = NULL; + desc.destType = NULL; + desc.dest = NULL; + desc.src = NULL; + desc.baseType = ctype_void; + params = NULL; +} + + +r_Convertor::r_Convertor( const char *src, const r_Minterval &interv, const r_Type *tp, bool fullTypes ) throw(r_Error) +{ + initShare(src, interv); + + desc.srcType = tp; + + if (tp == NULL) + { + RMInit::logOut << "Error: in conversion: type is null." << endl; + throw r_Error(); + } + + // Initialise desc.baseType from desc.srcType + desc.baseType=get_internal_type(tp, fullTypes); + + if (!fullTypes) { + switch (tp->type_id()) { + case r_Type::FLOAT: + this->applyColorScheme<float>(); + break; + case r_Type::DOUBLE: + applyColorScheme<double>(); + break; + case r_Type::USHORT: + applyColorScheme<unsigned short>(); + break; + case r_Type::SHORT: + applyColorScheme<short>(); + break; + } + } +} + + +r_Convertor::r_Convertor(const char *src, const r_Minterval &interv, int type) throw(r_Error) +{ + initShare(src, interv); + + desc.baseType = type; +} + + +r_Convertor::~r_Convertor(void) +{ + // Don't delete the resulting object pointer (desc->dest) ! + // This is the job of the external application. + if (params!=NULL) + { + delete params; + params=NULL; + } + if (destroySrc) + { + delete desc.src; + destroySrc=false; + } +} + + +void r_Convertor::set_storage_handler( const r_Storage_Man &newStore ) +{ + mystore = newStore; +} + + +const r_Storage_Man& +r_Convertor::get_storage_handler( ) const +{ + return mystore; +} + + + +r_Type *r_Convertor::get_external_type( int ctype ) throw(r_Error) +{ + r_Type* retval=NULL; + switch (ctype) + { + case ctype_bool: + retval=r_Type::get_any_type("boolean"); + break; + case ctype_char: + case ctype_uint8: + retval=r_Type::get_any_type("char"); + break; + case ctype_int8: + retval=r_Type::get_any_type("octet"); + break; + case ctype_int16: + retval=r_Type::get_any_type("short"); + break; + case ctype_uint16: + retval=r_Type::get_any_type("ushort"); + break; + case ctype_int32: + retval=r_Type::get_any_type("long"); + break; + case ctype_uint32: + retval=r_Type::get_any_type("ulong"); + break; + case ctype_int64: + retval=r_Type::get_any_type("double"); // currently unsupported + break; + case ctype_uint64: + retval=r_Type::get_any_type("double"); // currently unsupported + break; + case ctype_float32: + retval=r_Type::get_any_type("float"); + break; + case ctype_float64: + retval=r_Type::get_any_type("double"); + break; + case ctype_rgb: + retval=r_Type::get_any_type("struct {char, char, char}"); + break; + default: + RMInit::logOut << "Error: in conversion: unsupported type " << ctype << endl; + r_Error err(r_Error::r_Error_General); + throw(err); + } + return retval; +} + + +template <class baseType> +void r_Convertor::applyColorScheme() { + baseType *data = (baseType*)desc.src; + baseType min=data[0], max=data[0]; + int i, size = desc.srcInterv.cell_count(); + unsigned char *t, *img = new unsigned char[size*3]; + for (i=1; i<size; ++i) { + if (min > data[i]) + min=data[i]; + if (max < data[i]) + max=data[i]; + } + for (i=0, t=img; i<size; ++i) { + float n = (data[i]-min)/(max-min); + if (n<0.5) { + *t=(unsigned char)((0.5-n)*500); t++; + *t=(unsigned char)(n*500); t++; + *t=0; t++; + } else + { + *t=0;t++; + *t=(unsigned char)((1-n)*500); t++; + *t=(unsigned char)((n-0.5)*500); t++; + } + } + destroySrc = true; + desc.src = (char*)img; +} + +r_Convertor::convert_type_e +r_Convertor::get_internal_type(const r_Type* tp, bool fullTypes) throw(r_Error) { + r_Convertor::convert_type_e retval=ctype_void; + + if (tp == NULL) + return retval; + + //check if tp is structure type + if (tp->isStructType()) + { + // make life easy and always interpret as RGB + retval = ctype_rgb; + } + else + { + //is primitive type + if (fullTypes == false) + { + // restricted types for ``classic'' image formats + switch (tp->type_id()) + { + case r_Type::BOOL: + retval = ctype_bool; break; + case r_Type::CHAR: + case r_Type::OCTET: + retval = ctype_char; break; + // added (U)LONG -- PB 2005-apr-27 + case r_Type::LONG: + retval = ctype_int32; break; + case r_Type::ULONG: + retval = ctype_uint32; break; + // set to defined value (FIXME: still not good) -- PB 2005-apr-27 + default: + RMInit::logOut << "Error: in conversion: unknown type " << tp->type_id() << ", setting to void." << endl; + retval = ctype_rgb; + //retval = ctype_char; + + break; + } + } + else + { + // full types for more generic convertors + switch (tp->type_id()) + { + case r_Type::BOOL: + //FIXME that was in hdf.cc retval = ctype_uint8; break; + retval = ctype_bool; break; + case r_Type::CHAR: + retval = ctype_uint8; break; + case r_Type::OCTET: + retval = ctype_int8; break; + case r_Type::SHORT: + retval = ctype_int16; break; + case r_Type::USHORT: + retval = ctype_uint16; break; + case r_Type::LONG: + retval = ctype_int32; break; + case r_Type::ULONG: + retval = ctype_uint32; break; + case r_Type::FLOAT: + retval = ctype_float32; break; + case r_Type::DOUBLE: + retval = ctype_float64; break; + default: + break; + } + }//endif fullTypes + if (retval == ctype_void) + { + RMInit::logOut << "Warning: in conversion: this type overrides base type: " << tp->type_id() << "; using char." << endl; + retval = ctype_char; + } + }//endif structuretype + + return retval; +} + +std::ostream& operator<<(std::ostream& os, r_Convertor::convert_type_e& cte) +{ + switch(cte) + { + case r_Convertor::ctype_bool: + os << "bool"; + break; + case r_Convertor::ctype_char: + os << "char"; + break; + case r_Convertor::ctype_uint8: + os << "uint8"; + break; + case r_Convertor::ctype_int8: + os << "int8"; + break; + case r_Convertor::ctype_int16: + os << "int16"; + break; + case r_Convertor::ctype_uint16: + os << "uint16"; + break; + case r_Convertor::ctype_int32: + os << "int32"; + break; + case r_Convertor::ctype_uint32: + os << "uint32"; + break; + case r_Convertor::ctype_int64: + os << "int64"; // currently unsupported + break; + case r_Convertor::ctype_uint64: + os << "uint64"; // currently unsupported + break; + case r_Convertor::ctype_float32: + os << "float32"; + break; + case r_Convertor::ctype_float64: + os << "float64"; + break; + case r_Convertor::ctype_rgb: + os << "rgb"; + break; + default: + os << "r_Convertor::convert_type_e unknown type: " << cte << endl; + break; + } + + return os; +} + +/* + * r_Convert_Memory class + */ + +void r_Convert_Memory::initMemory( void ) throw(r_Error) +{ + int status = -1; + + memFS=NULL; + handle=NULL; + + memFS = new memFSContext; + if ( memFS != NULL) + { + handle = (void*)memFS; + if (memfs_initfs(handle) >= 0) + status = 0; + } + if (status < 0) + { + RMInit::logOut << "Error: cannot allocate memory for conversion." << endl; + r_Error err(MEMMORYALLOCATIONERROR); + throw(err); + } +} + + +r_Convert_Memory::r_Convert_Memory( const char *src, const r_Minterval &interv, const r_Type *tp, int fullTypes ) throw(r_Error) +: r_Convertor(src, interv, tp, fullTypes) +{ + initMemory(); +} + + +r_Convert_Memory::r_Convert_Memory( const char *src, const r_Minterval &interv, int type ) throw(r_Error) +: r_Convertor(src, interv, type) +{ + initMemory(); +} + + +r_Convert_Memory::~r_Convert_Memory( void ) +{ + memfs_killfs(handle); + if(memFS!=NULL) + { + delete memFS; + memFS=NULL; + } + handle=NULL; +} |