/* * 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 . * * Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / rasdaman GmbH. * * For more information please see * or contact Peter Baumann via . / /** * 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(); break; case r_Type::DOUBLE: applyColorScheme(); break; case r_Type::USHORT: applyColorScheme(); break; case r_Type::SHORT: applyColorScheme(); 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 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 data[i]) min=data[i]; if (max < data[i]) max=data[i]; } for (i=0, t=img; iisStructType()) { // 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; }