Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /branches/vis15/src/lib/include/diderot/nrrd-inst.hxx
ViewVC logotype

View of /branches/vis15/src/lib/include/diderot/nrrd-inst.hxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4028 - (download) (as text) (annotate)
Wed Jun 22 21:15:36 2016 UTC (3 years, 1 month ago) by jhr
File size: 7679 byte(s)
  Working on merge: dynamic sequence loading.
/*! \file nrrd-inst.hxx
 *
 * \author John Reppy
 */

/*
 * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
 *
 * COPYRIGHT (c) 2016 The University of Chicago
 * All rights reserved.
 */

#ifndef _DIDEROT_NRRD_INST_HXX_
#define _DIDEROT_NRRD_INST_HXX_

namespace diderot {

    namespace __details {

	//! copy the contents of a nrrd into the destination sequence, where the elements
	//! have boolean ground type
	//! \param wrld the world; used to report errors
	//! \param dst the target destination to copy the data
	//! \param nin the source nrrd to copy
	//! \param nDims the number of dimensions in the sequence elements
	//! \param dims the array of sequence element dimensions
	//! \return true if there are any errors
        bool copy_nrrd_data_bool (
	    world_base *wrld,
	    bool *dst,
	    Nrrd *nin,
	    uint32_t nDims,
	    uint32_t *dims)
	{
	    uint32_t nValuesPerElem = wrld->check_nrrd (nin, nDims, dims);
	    size_t elemSz = sizeof(bool) * nValuesPerElem;

	    if (nValuesPerElem == 0) {
		return true;
	    }

	    if (nrrd_type_info[nin->type].isFloat) {
		wrld->error ("expected integer element type for bool sequence, but found %d\n",
		    nin->type);
		return true;
	    }

	  // get the number of elements
	    size_t nElems = nin->axis[0].size;

 	  // initialize the sequence from the nrrd
	    if (nrrd_type_info[nin->type].sizeb != sizeof(bool)) {
	      // this is the slow path; we have to convert values as they are copied from the nrrd
		int (*loadFn)(const void *) = nrrdILoad[nin->type];
		char *src = reinterpret_cast<char *>(nin->data);
		size_t srcElemSz = nrrd_type_info[nin->type].sizeb;
		for (size_t i = 0;  i < nElems * nValuesPerElem;  i++) {
		    *dst++ = loadFn(src) ? true : false;
		    src += srcElemSz;
		}
	    }
	    else {
	      // this is the fast path, where we can just do a bulk memcpy
		memcpy (dst, nin->data, nElems * elemSz);
	    }

	    return false;

	} // copy_nrrd_data_bool

	//! copy the contents of a nrrd into the destination sequence, where the elements
	//! have Diderot int ground type
	//! \param wrld the world; used to report errors
	//! \param dst the target destination to copy the data
	//! \param nin the source nrrd to copy
	//! \param nDims the number of dimensions in the sequence elements
	//! \param dims the array of sequence element dimensions
	//! \return true if there are any errors
	template <typename INT>
	bool copy_nrrd_data_int (
	    world_base *wrld,
	    INT *dst,
	    Nrrd *nin,
	    uint32_t nDims,
	    uint32_t *dims)
	{
	    uint32_t nValuesPerElem = wrld->check_nrrd (nin, nDims, dims);
	    size_t elemSz = sizeof(INT) * nValuesPerElem;

	    if (nValuesPerElem == 0) {
		return true;
	    }

	    if (nrrd_type_info[nin->type].isFloat) {
		wrld->error ("expected integer element type for int sequence, but found %d\n",
		    nin->type);
		return true;
	    }

	  // get the number of elements
	    size_t nElems = nin->axis[0].size;

 	  // initialize the sequence from the nrrd
	    if (nrrd_type_info[nin->type].sizeb != sizeof(INT)) {
	      // this is the slow path; we have to convert values as they are copied from the nrrd
		int (*loadFn)(const void *) = nrrdILoad[nin->type];
		char *src = (char *)nin->data;
		size_t srcElemSz = nrrd_type_info[nin->type].sizeb;
		for (size_t i = 0;  i < nElems * nValuesPerElem;  i++) {
		    *dst++ = loadFn(src);
		    src += srcElemSz;
		}
	    }
	    else {
	      // this is the fast path, where we can just do a bulk memcpy
		memcpy (dst, nin->data, nElems * elemSz);
	    }

	    return false;

	} // copy_nrrd_data_int

	// Teem provides two different arrays of functions for loading floating-point
	// numbers; we define a template function to get C++ template resolution
	// to pick the right code.
	template <typename REAL>
	void slow_copy_real_data (REAL *dst, Nrrd *nin, size_t nItems);

	template <>
	inline void slow_copy_real_data (double *dst, Nrrd *nin, size_t nItems)
	{
	    double (*loadFn)(const void *) = nrrdDLoad[nin->type];
	    char *src = reinterpret_cast<char *>(nin->data);
	    size_t srcElemSz = nrrd_type_info[nin->type].sizeb;
	    for (size_t i = 0;  i < nItems;  i++) {
		*dst++ = loadFn(src);
		src += srcElemSz;
	    }
	}

	template <>
	inline void slow_copy_real_data (float *dst, Nrrd *nin, size_t nItems)
	{
	    float (*loadFn)(const void *) = nrrdFLoad[nin->type];
	    char *src = reinterpret_cast<char *>(nin->data);
	    size_t srcElemSz = nrrd_type_info[nin->type].sizeb;
	    for (size_t i = 0;  i < nItems;  i++) {
		*dst++ = loadFn(src);
		src += srcElemSz;
	    }
	}

	//! copy the contents of a nrrd into the destination sequence, where the elements
	//! have Diderot real ground type
	//! \param wrld the world; used to report errors
	//! \param dst the target destination to copy the data
	//! \param nin the source nrrd to copy
	//! \param nDims the number of dimensions in the sequence elements
	//! \param dims the array of sequence element dimensions
	//! \return true if there are any errors
	template <typename REAL>
	bool copy_nrrd_data_real (
	    world_base *wrld,
	    REAL *dst,
	    Nrrd *nin,
	    uint32_t nDims,
	    uint32_t *dims)
	{
	    uint32_t nValuesPerElem = wrld->check_nrrd (nin, nDims, dims);

	    if (nValuesPerElem == 0) {
		return true;
	    }

	    if (nrrd_type_info[nin->type].isFloat) {
		wrld->error ("expected integer element type for int sequence, but found %d\n",
		    nin->type);
		return true;
	    }

	  // get the number of elements
	    size_t nElems = nin->axis[0].size;

	  // initialize the sequence from the nrrd
	    if (! nrrd_type_info[nin->type].isFloat
	    || (nrrd_type_info[nin->type].sizeb != sizeof(REAL)))
	    {
	      // this is the slow path; we have to convert values as they are copied from the nrrd
		slow_copy_real_data (dst, nin, static_cast<size_t>(nElems * nValuesPerElem));
	    }
	    else {
	      // this is the fast path, where we can just do a bulk memcpy
		memcpy (dst, nin->data, sizeof(REAL) * nElems * nValuesPerElem);
	    }

	    return false;

	} // copy_nrrd_data_real

	template <typename T>
	dynseq<T> load_dynseq_from_nrrd (const Nrrd *nin, bool &sts)
	{
	    uint32_t nDims = dynseq<T>::traits::ndims;
	    const uint32_t *dims = dynseq<T>::traits::dims;
	    uint32_t nValuesPerElem = wrld->check_nrrd (nin, nDims, dims);
	    size_t elemSz = sizeof(dynseq<T>::traits::base_type) * nValuesPerElem;

	    if (nValuesPerElem == 0) {
		return dynseq<T>();
	    }

//	    if (nrrd_type_info[nin->type].isFloat) {
//		wrld->error ("expected integer element type for int sequence, but found %d\n",
//		    nin->type);
//		return true;
//	    }

	  // get the number of elements
	    size_t nElems = nin->axis[0].size;

	  // allocate the result sequence object
	    dynseq<T> result(nElems);

 	  // initialize the sequence from the nrrd
	    dynseq<T>::traits::base_type *dst =
		reinterpret_cast<dynseq<T>::traits::base_type *>(result.data());

	    if (nrrd_type_info[nin->type].sizeb != sizeof(dynseq<T>::traits::base_type)) {
	      // this is the slow path; we have to convert values as they are copied from the nrrd
		load_fn_ptr loadFn = dynseq<T>::traits::get_load_fn (nin->type);
		char *src = (char *)nin->data;
		size_t srcElemSz = nrrd_type_info[nin->type].sizeb;
		for (size_t i = 0;  i < nElems * nValuesPerElem;  i++) {
		    *dst++ = loadFn(src);
		    src += srcElemSz;
		}
	    }
	    else {
	      // this is the fast path, where we can just do a bulk memcpy
		memcpy (dst, nin->data, nElems * elemSz);
	    }

	    return result;

	}

    } // namespace __details

} // namespace diderot


#endif // !_DIDEROT_NRRD_INST_HXX_

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0