/*
* 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;
}