Exemplo n.º 1
0
// IDL_LONG64 IDL_SysRtnNumEnabled(int is_function, int enabled)
static IDL_VPTR IDL_CDECL IDL_IDL_SysRtnNumEnabled(int argc, IDL_VPTR *argv, char *argk) {
  IDL_LONG64 result;
  IDL_ENSURE_SIMPLE(argv[0]);
  IDL_ENSURE_SCALAR(argv[0])
  MG_ENSURE_TYPE(argv[0], IDL_TYP_LONG, "int is_function")
  IDL_ENSURE_SIMPLE(argv[1]);
  IDL_ENSURE_SCALAR(argv[1])
  MG_ENSURE_TYPE(argv[1], IDL_TYP_LONG, "int enabled")
  result = (IDL_LONG64) IDL_SysRtnNumEnabled(argv[0]->value.l,   // int is_function
                                             argv[1]->value.l);   // int enabled
  return IDL_GettmpLong64(result);
}
Exemplo n.º 2
0
/*
  nbytes = MG_NET_SENDTO(socket, variable, host, port)

  Sends the raw byte data from the IDL variable on the socket. Returns the
  number of bytes sent or -1 for error. Note: no byteswapping is performed.
*/
static IDL_VPTR IDL_CDECL mg_net_sendto(int argc, IDL_VPTR argv[], char *argk) {
  IDL_LONG i, iNum, iRet;
  struct sockaddr_in sin;
  IDL_VPTR vpTmp;
  char *pbuffer;
  short	port;
  int host, addr_len;

  i = IDL_LongScalar(argv[0]);
  if ((i < 0) || (i >= MAX_SOCKETS)) return (IDL_GettmpLong(-1));
  if (net_list[i].iState != NET_IO) return (IDL_GettmpLong(-1));
  IDL_ENSURE_SIMPLE(argv[1]);
  vpTmp = argv[1];
  port = (short) IDL_LongScalar(argv[3]);
  host = IDL_ULongScalar(argv[2]);

  if (vpTmp->type == IDL_TYP_STRING) {
    vpTmp  = IDL_CvtByte(1, &vpTmp);
  }

  IDL_VarGetData(vpTmp, &iNum, &pbuffer, 1);
  iNum = iNum * IDL_TypeSizeFunc(vpTmp->type);

  sin.sin_addr.s_addr = host;
  sin.sin_family = AF_INET;
  sin.sin_port = htons(port);
  addr_len = sizeof(struct sockaddr_in);

  iRet = sendto(net_list[i].socket, pbuffer, iNum, 0, (struct sockaddr *) &sin, addr_len);

  if (vpTmp != argv[1]) IDL_Deltmp(vpTmp);

  return(IDL_GettmpLong(iRet));
}
Exemplo n.º 3
0
/*
  nbytes = MG_NET_SEND(socket, variable [, host] [, port])

  Sends the raw byte data from the IDL variable on the socket. Returns the
  number of bytes sent or -1 for error. Note: no byteswapping is performed.

	When sending data from a UDP socket, you must specify the remote host and
	port arguments where host is the value returned from the MG_NET_NAME2HOST
	function.
*/
static IDL_VPTR IDL_CDECL mg_net_send(int argc, IDL_VPTR argv[], char *argk) {
  IDL_LONG i, iNum, iRet;
  IDL_VPTR vpTmp;
  char *pbuffer;

  i = IDL_LongScalar(argv[0]);
  if ((i < 0) || (i >= MAX_SOCKETS)) return(IDL_GettmpLong(-1));
  if ((net_list[i].iState != NET_IO) || (net_list[i].iType != NET_UDP_PEER))
    return(IDL_GettmpLong(-1));
  IDL_ENSURE_SIMPLE(argv[1]);
  vpTmp = argv[1];

  if (vpTmp->type == IDL_TYP_STRING) {
    vpTmp  = IDL_CvtByte(1, &vpTmp);
  }

  IDL_VarGetData(vpTmp, &iNum, &pbuffer, 1);
  iNum = iNum * IDL_TypeSizeFunc(vpTmp->type);

  iRet = send(net_list[i].socket, pbuffer, iNum, 0);

  if (vpTmp != argv[1]) IDL_Deltmp(vpTmp);

  return(IDL_GettmpLong(iRet));
}
Exemplo n.º 4
0
// Convert the input IDL_VPTR of IDL_STRINGs to a vector<string> all uppercase
int IDLStruct::IDL_STRING2StringVecUpper(
        IDL_VPTR svptr, vector<string>& tagnames)
{
    int status=0;
    IDL_MEMINT num=0;
    IDL_STRING* ptr;


    // Checking here, but better to check outside of this in case of memory
    // issues
    IDL_ENSURE_SIMPLE(svptr);

    if (svptr->type != IDL_TYP_STRING)
    {
        IDL_Message(IDL_M_NAMED_GENERIC, IDL_MSG_INFO, 
                "IDL_STRING2StringVecUpper: Input must be of type IDL_STRING");
        return(status);
    }

    IDL_VarGetData(svptr, &num, (char **) &ptr, IDL_TRUE);

    tagnames.resize(num);
    for (IDL_MEMINT i=0; i<num; i++)
    {
        string name=ptr[i].s;
        // Make upper case
        std::transform(name.begin(), name.end(), 
                name.begin(), (int(*)(int)) toupper);
        tagnames[i] = name;
    }
    status=1;
    return(status);
}
Exemplo n.º 5
0
// Match an input IDL_VPTR of tag indicators, either strings or numerical
// to the tags of our structure and return the match ids.
int IDLStruct::MatchIDL_VPTR2Tags(IDL_VPTR tagvptr, vector<IDL_MEMINT>& tagnums)
{
    int status=0;

    // Checking here, but better to check outside of this in case of memory
    // issues
    IDL_ENSURE_SIMPLE(tagvptr);

    if (tagvptr->type == IDL_TYP_STRING)
    {
        vector<string> tagnamevec;
        // Try to convert to upper case strings
        if (IDL_STRING2StringVecUpper(tagvptr, tagnamevec) != 1)
        {
            return(status);
        }

        return( MatchTagNames(tagnamevec, tagnums) );
    } else {

        vector<IDL_MEMINT> tmptagnums;
        if (IDL_VAR2IDL_MEMINTVec(tagvptr, tmptagnums) != 1)
        {
            return(status);
        }

        return( MatchTagNums(tmptagnums, tagnums) );

    }

}
Exemplo n.º 6
0
// char *IDL_TypeNameFunc(int type)
static IDL_VPTR IDL_CDECL IDL_IDL_TypeNameFunc(int argc, IDL_VPTR *argv, char *argk) {
  char *result;
  IDL_ENSURE_SIMPLE(argv[0]);
  IDL_ENSURE_SCALAR(argv[0])
  MG_ENSURE_TYPE(argv[0], IDL_TYP_LONG, "int type")
  result = (char *) IDL_TypeNameFunc(argv[0]->value.l);   // int type
  return IDL_StrToSTRING(result);
}
Exemplo n.º 7
0
// int IDL_TypeSizeFunc(int type)
static IDL_VPTR IDL_CDECL IDL_IDL_TypeSizeFunc(int argc, IDL_VPTR *argv, char *argk) {
  IDL_LONG result;
  IDL_ENSURE_SIMPLE(argv[0]);
  IDL_ENSURE_SCALAR(argv[0])
  MG_ENSURE_TYPE(argv[0], IDL_TYP_LONG, "int type")
  result = (IDL_LONG) IDL_TypeSizeFunc(argv[0]->value.l);   // int type
  return IDL_GettmpLong(result);
}
Exemplo n.º 8
0
// Convert the input numerical variable to a vector<IDL_MEMINT>
int IDLStruct::IDL_VAR2IDL_MEMINTVec(
        IDL_VPTR vptr, vector<IDL_MEMINT>& memintvec)
{
    int status=0;

    // Checking here, but better to check outside of this in case of memory
    // issues
    IDL_ENSURE_SIMPLE(vptr);

    int converted = 0;
    if (vptr->type != IDL_TYP_MEMINT)
        converted = 1;

    // Will return same variable if it is already type IDL_MEMINT
    // We have to explicitly release this mem; but at least IDL
    // will warn us if we forget
    IDL_VPTR vptr_use = IDL_CvtMEMINT(1, &vptr);


    // The true will ensure simple, which we have already done 
    IDL_MEMINT num;
    IDL_MEMINT* ptr;
    IDL_VarGetData(vptr_use, &num, (char **) &ptr, IDL_TRUE);

    memintvec.clear();

    if (num > 0)
    {
        memintvec.resize(num);
        for (IDL_MEMINT i=0; i<num; i++)
        {
            memintvec[i] = ptr[i];
        }

    }

    if (converted)
        IDL_Deltmp(vptr_use);

    status=1;
    return(status);

}
Exemplo n.º 9
0
/*
  err = MG_NET_SENDVAR(socket, variable [, host] [, port])

  Sends a complete IDL variable to a socket for reading by MG_NET_RECVVAR. The
  variable must be one of the basic types, but strings and arrays are sent
  with array dimensions and lengths intact.

	When sending data from a UDP socket, you must specify the remote host and
	port arguments where host is the value returned from the MG_NET_NAME2HOST
	function.

  Note: This is the easiest way to send a complete variable from one IDL to
  another. The receiver will byteswap the data if necessary. One should be
  careful not to mix calls to MG_NET_SEND/RECV and MG_NET_SENDVAR/RECVVAR as
  the latter send formatted information. You can use the two calls on the same
  socket as long as they are paired.
*/
static IDL_VPTR IDL_CDECL mg_net_sendvar(int argc, IDL_VPTR argv[], char *argk) {
  IDL_LONG i;
  i_var	var;
  int host, addr_len;
  short	port;
  IDL_LONG iRet;
  IDL_VPTR vpTmp;
  char *pbuffer;
  struct sockaddr_in sin;

  i = IDL_LongScalar(argv[0]);
  if ((i < 0) || (i >= MAX_SOCKETS)) return (IDL_GettmpLong(-1));
  if (net_list[i].iState != NET_IO) return (IDL_GettmpLong(-1));
  IDL_ENSURE_SIMPLE(argv[1]);
  vpTmp = argv[1];

  if (net_list[i].iType == NET_UDP) {
    if (argc == 4) {
      host = IDL_ULongScalar(argv[2]);
      port = (short) IDL_LongScalar(argv[3]);
    } else {
      IDL_MessageFromBlock(msg_block,
			   MG_NET_ERROR,
			   IDL_MSG_RET,
			   "This UDP socket requires the destination HOST and PORT arguments.");
    }
  }

  var.token = TOKEN;
  var.type = vpTmp->type;
  if ((var.type == IDL_TYP_STRUCT) ||
      (var.type == IDL_TYP_PTR) ||
      (var.type == IDL_TYP_OBJREF) ||
      (var.type == IDL_TYP_UNDEF)) {
    IDL_MessageFromBlock(msg_block,
			 MG_NET_BADTYPE,
			 IDL_MSG_LONGJMP,
			 IDL_TypeNameFunc(var.type));
  }

  if (vpTmp->type == IDL_TYP_STRING) {
    if (vpTmp->flags & IDL_V_ARR) return (IDL_GettmpLong(-1));
    pbuffer = IDL_STRING_STR(&(vpTmp->value.str));
    var.ndims = 0;
    var.len = vpTmp->value.str.slen + 1;
    var.nelts = var.len;
  } else if (vpTmp->flags & IDL_V_ARR) {
    pbuffer = vpTmp->value.arr->data;
    var.ndims = vpTmp->value.arr->n_dim;
    var.len = vpTmp->value.arr->arr_len;
    var.nelts = vpTmp->value.arr->n_elts;
    memcpy(var.dims, vpTmp->value.arr->dim, IDL_MAX_ARRAY_DIM * sizeof(IDL_LONG));
  } else {
    pbuffer = &(vpTmp->value.c);
    var.ndims = 0;
    var.len = IDL_TypeSizeFunc(var.type);
    var.nelts = 1;
  }

  /* send native, recvvar swaps if needed */
  if (net_list[i].iType == NET_UDP) {
    sin.sin_addr.s_addr = host;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(port);
    addr_len = sizeof(struct sockaddr_in);

    iRet = sendto(net_list[i].socket, (char *) &var, sizeof(i_var), 0,
		  (struct sockaddr *) &sin, addr_len);
    if (iRet == -1) return(IDL_GettmpLong(iRet));

    iRet = sendto(net_list[i].socket, pbuffer, var.len, 0,
		  (struct sockaddr *) &sin, addr_len);
  } else {
    iRet = send(net_list[i].socket,(char *) &var, sizeof(i_var), 0);
    if (iRet == -1) return (IDL_GettmpLong(iRet));
    
    iRet = send(net_list[i].socket, pbuffer, var.len, 0);
  }

  return(IDL_GettmpLong(1));
}
Exemplo n.º 10
0
IDL_VPTR p3d_idlGetMaxVolumeBlob(int argc, IDL_VPTR argv[], char* argk) {

    typedef struct {
        IDL_KW_RESULT_FIRST_FIELD; // Must be first entry in structure
        IDL_LONG conn;
        int cn_there;
    } KW_RESULT;

    // Alphabetical order is crucial:
    static IDL_KW_PAR kw_pars[] = {
        IDL_KW_FAST_SCAN,
        { "CONN", IDL_TYP_LONG, 1, 0, (int*) IDL_KW_OFFSETOF(cn_there), (char*) IDL_KW_OFFSETOF(conn)},
        { NULL}
    };

    KW_RESULT kw;

    IDL_VPTR idl_out_rev, idl_in_rev;
    unsigned char *in_rev8, *out_rev8;
    int keywords_ct = 0;

    int conn2D = CONN4;
    int conn3D = CONN6;

    int err_code;

    // Process keywords:
    IDL_KWProcessByOffset(argc, argv, argk, kw_pars, NULL, 1, &kw);


    // Get input data in IDL format:
    idl_in_rev = argv[0];

    IDL_ENSURE_SIMPLE(idl_in_rev);
    IDL_ENSURE_ARRAY(idl_in_rev);


    // Get the CONN input argument:
    if (kw.cn_there) {
        if (idl_in_rev->value.arr->n_dim == 2) {
            // Check values:
            if ((kw.conn != 4) && (kw.conn != 8))
                _p3d_idlPrintNamedError("CONN must be a value of the set {4,8}.");

            // Get values:
            if (kw.conn == 4)
                conn2D = CONN4;
            else if (kw.conn == 8)
                conn2D = CONN8;
        } else if (idl_in_rev->value.arr->n_dim == 3) {
            // Check values:
            if ((kw.conn != 6) && (kw.conn != 18) && (kw.conn != 26))
                _p3d_idlPrintNamedError("CONN must be a value of the set {6,18,26}.");

            // Get values:
            if (kw.conn == 6)
                conn3D = CONN6;
            else if (kw.conn == 18)
                conn3D = CONN18;
            else if (kw.conn == 26)
                conn3D = CONN26;
        }
        // else: error on input arguments with further handling.

        keywords_ct++;
    }


    // Call Pore3D depending on input arguments:
	if (idl_in_rev->value.arr->n_dim == 3) {
        // Extract first input (volume to filter) in C format:
        if (idl_in_rev->type == IDL_TYP_BYTE) {
            in_rev8 = (unsigned char *) idl_in_rev->value.arr->data;

            // Allocate memory for output:
            if (!(idl_in_rev->flags & IDL_V_TEMP))
                out_rev8 = (unsigned char *) IDL_MakeTempArray(
                    IDL_TYP_BYTE,
                    idl_in_rev->value.arr->n_dim,
                    idl_in_rev->value.arr->dim,
                    IDL_ARR_INI_NOP,
                    &idl_out_rev
                    );


            // Call Pore3D:
            err_code = p3dGetMaxVolumeBlob3D(
                    in_rev8,
                    out_rev8,
                    (unsigned int) idl_in_rev->value.arr->dim[0],
                    (unsigned int) idl_in_rev->value.arr->dim[1],
                    (unsigned int) idl_in_rev->value.arr->dim[2],
                    conn3D,
                    _p3d_idlPrintInfo
                    );

            // On exception print error:
            if (err_code == P3D_ERROR)
                _p3d_idlPrintNamedError("Error on code execution.");
        }
        else {
            _p3d_idlPrintNamedError("Input argument IMAGE must be of type BYTE.");
        }
    } else {
        _p3d_idlPrintNamedError("Input argument IMAGE must be a 2D or 3D matrix.");
    }


    // Free resources:
    IDL_KW_FREE;

    // Return output in IDL Format
    return (idl_out_rev);
}
IDL_VPTR p3d_idlSquaredEuclideanDT(int argc, IDL_VPTR argv[], char* argk) {

    IDL_VPTR idl_out_rev, idl_in_rev;
    unsigned char *in_rev;
    unsigned int *out_rev;

    int err_code;


    // Get input data in IDL format:
    idl_in_rev = argv[0];

    IDL_ENSURE_SIMPLE(idl_in_rev);
    IDL_ENSURE_ARRAY(idl_in_rev); // Get input data in IDL format:

    // Allocate memory for output:
    if (!(idl_in_rev->flags & IDL_V_TEMP))
        out_rev = (unsigned int *) IDL_MakeTempArray(
            IDL_TYP_ULONG,
            idl_in_rev->value.arr->n_dim,
            idl_in_rev->value.arr->dim,
            IDL_ARR_INI_NOP,
            &idl_out_rev
            );

    if (idl_in_rev->value.arr->n_dim == 3) {
        // Extract input in C format
        if (idl_in_rev->type == IDL_TYP_BYTE)
            in_rev = (unsigned char *) idl_in_rev->value.arr->data;
        else
            _p3d_idlPrintNamedError("Input argument IMAGE must be of type BYTE.");

        // Call Pore3D:
        err_code = p3dSquaredEuclideanDT(
                in_rev,
                out_rev,
                (unsigned int) idl_in_rev->value.arr->dim[0],
                (unsigned int) idl_in_rev->value.arr->dim[1],
                (unsigned int) idl_in_rev->value.arr->dim[2],
                _p3d_idlPrintInfo
                );

        if (err_code == P3D_ERROR) {
            // Print error:
            _p3d_idlPrintNamedError("Error on internal code execution.");
        }

        //
        // Following code is not necessary 'cause number of input arguments
        // is checked at compile-time and not at run time (see further IDL_Load).
        //
        //else
        //{
        //	// Print error:
        //	_p3d_idlPrintNamedError("Incorrect number of arguments.");
        //}
    } else {
        _p3d_idlPrintNamedError("Input argument IMAGE must be a 3D matrix.");
    }

    // Return output in IDL Format:
    return idl_out_rev;
}
Exemplo n.º 12
0
IDL_VPTR p3d_idlGaussianFilter(int argc, IDL_VPTR argv[], char* argk) {

	typedef struct {
		IDL_KW_RESULT_FIRST_FIELD; // Must be first entry in structure
		double sigma;
		int si_there;
		IDL_LONG nsize;
		int ns_there;
	} KW_RESULT;

	// Alphabetical order is crucial:
	static IDL_KW_PAR kw_pars[] = {
		IDL_KW_FAST_SCAN,
		{ "SIGMA", IDL_TYP_DOUBLE, 1, 0, (int*) IDL_KW_OFFSETOF(si_there), (char*) IDL_KW_OFFSETOF(sigma)},
		{ "WIDTH", IDL_TYP_LONG, 1, 0, (int*) IDL_KW_OFFSETOF(ns_there), (char*) IDL_KW_OFFSETOF(nsize)},
		{ NULL}
	};

	KW_RESULT kw;

	IDL_VPTR idl_out_rev, idl_in_rev;
	unsigned char *in_rev8, *out_rev8;
	unsigned short *in_rev16, *out_rev16;
	int keywords_ct = 0;

	int    width = 3;   // default
	double sigma = 1.0; // default

	int err_code;

	// Process keywords:
	IDL_KWProcessByOffset(argc, argv, argk, kw_pars, NULL, 1, &kw);


	// Get input data in IDL format:
	idl_in_rev = argv[0];

	IDL_ENSURE_SIMPLE(idl_in_rev);
	IDL_ENSURE_ARRAY(idl_in_rev);


	// Get the WIDTH input argument:
	if (kw.ns_there) {
		// Check values:
		if ((kw.nsize < 3) || (kw.nsize > 51))
			_p3d_idlPrintNamedError("WIDTH must be an odd value within the range [3,51].");

		if ((kw.nsize % 2) == 0)
			_p3d_idlPrintNamedError("WIDTH must be an odd value within the range [3,51].");

		// Get values:
		width = (int) kw.nsize;

		keywords_ct++;
	}

	// Get the SIGMA input argument:
	if (kw.si_there) {
		// Check values:
		if (kw.sigma < 0)
			_p3d_idlPrintNamedError("SIGMA must be greater than zero.");

		// Get values:
		sigma = (double) kw.sigma;

		keywords_ct++;
	}


	// Call Pore3D depending on input arguments:
	if (idl_in_rev->value.arr->n_dim == 3) {
		// Extract first input (volume to filter) in C format:
		if (idl_in_rev->type == IDL_TYP_BYTE) {
			in_rev8 = (unsigned char *) idl_in_rev->value.arr->data;

			// Allocate memory for output:
			if (!(idl_in_rev->flags & IDL_V_TEMP))
				out_rev8 = (unsigned char *) IDL_MakeTempArray(
				IDL_TYP_BYTE,
				idl_in_rev->value.arr->n_dim,
				idl_in_rev->value.arr->dim,
				IDL_ARR_INI_NOP,
				&idl_out_rev
				);



			// Call Pore3D:
			err_code = p3dGaussianFilter3D_8(
				in_rev8,
				out_rev8,
				(int) idl_in_rev->value.arr->dim[0],
				(int) idl_in_rev->value.arr->dim[1],
				(int) idl_in_rev->value.arr->dim[2],
				width,
				sigma,
				_p3d_idlPrintInfo,
				NULL
				);

			// On exception print error:
			if ((err_code == P3D_IO_ERROR) || (err_code == P3D_ERROR))
				_p3d_idlPrintNamedError("Error on code execution.");

		} else if (idl_in_rev->type == IDL_TYP_UINT) {
			in_rev16 = (unsigned short *) idl_in_rev->value.arr->data;

			// Allocate memory for output:
			if (!(idl_in_rev->flags & IDL_V_TEMP))
				out_rev16 = (unsigned short *) IDL_MakeTempArray(
				IDL_TYP_UINT,
				idl_in_rev->value.arr->n_dim,
				idl_in_rev->value.arr->dim,
				IDL_ARR_INI_NOP,
				&idl_out_rev
				);


			// Call Pore3D:
			err_code = p3dGaussianFilter3D_16(
				in_rev16,
				out_rev16,
				(int) idl_in_rev->value.arr->dim[0],
				(int) idl_in_rev->value.arr->dim[1],
				(int) idl_in_rev->value.arr->dim[2],
				width,
				sigma,
				_p3d_idlPrintInfo,
				NULL
				);

			// On exception print error:
			if ((err_code == P3D_IO_ERROR) || (err_code == P3D_ERROR))
				_p3d_idlPrintNamedError("Error on code execution.");

		} else {
			_p3d_idlPrintNamedError("Input argument IMAGE must be of type BYTE or UINT.");
		}
	} else {
		_p3d_idlPrintNamedError("Input argument IMAGE must be a 2D or 3D matrix.");
	}


	// Free resources:
	IDL_KW_FREE;

	// Return output in IDL Format
	return (idl_out_rev);
}
Exemplo n.º 13
0
void p3d_idlWriteRaw(int argc, IDL_VPTR argv[], char* argk) {

	typedef struct {
		IDL_KW_RESULT_FIRST_FIELD; // Must be first entry in structure
		IDL_LONG endian;
		IDL_LONG sign;
	} KW_RESULT;

	// Alphabetical order is crucial:
	static IDL_KW_PAR kw_pars[] = {
		IDL_KW_FAST_SCAN,
		{ "BIG_ENDIAN", IDL_TYP_LONG, 1, IDL_KW_ZERO, 0, (char*) IDL_KW_OFFSETOF(endian)},
		{ "UNSIGNED", IDL_TYP_LONG, 1, IDL_KW_ZERO, 0, (char*) IDL_KW_OFFSETOF(sign)},
		{ NULL}
	};

	KW_RESULT kw;
	IDL_VPTR idl_in_rev;

	char* filename;
	int err_code;

	int little_endian;
	int is_signed;

	unsigned char* in_rev8;
	unsigned short* in_rev16;
	unsigned int* in_rev32;
	float* in_rev32f;


	// Process keywords:
	IDL_KWProcessByOffset(argc, argv, argk, kw_pars, (IDL_VPTR *) 0, 1, &kw);

	little_endian = (kw.endian == 0) ? P3D_TRUE : P3D_FALSE;
	is_signed = (kw.sign == 0) ? P3D_TRUE : P3D_FALSE;

	// Get input data in IDL format:
	idl_in_rev = argv[0];

	IDL_ENSURE_SIMPLE(idl_in_rev);
	IDL_ENSURE_ARRAY(idl_in_rev);


	if (argv[1]->type == IDL_TYP_STRING)
		filename = IDL_VarGetString(argv[1]);
	else
		_p3d_idlPrintNamedError("Input argument FILENAME must be a string.");


	// Check if user wants to write a 8-bit or 16-bit format image:
	if (idl_in_rev->type == IDL_TYP_BYTE) {
		// Extract input in C format
		in_rev8 = (unsigned char *) idl_in_rev->value.arr->data;


		// Check if user wants to write a 2D image or a 3D volume:
		if (idl_in_rev->value.arr->n_dim == 2) {
			// Call Pore3D:
			err_code = p3dWriteRaw8(
				in_rev8,
				filename,
				(int) (idl_in_rev->value.arr->dim[0]),
				(int) (idl_in_rev->value.arr->dim[1]),
				1,
				_p3d_idlPrintInfo,
				NULL
				);

			// On exception print error:
			if ((err_code == P3D_IO_ERROR) || (err_code == P3D_ERROR))
				_p3d_idlPrintNamedError("Error on code execution.");
		} else if (idl_in_rev->value.arr->n_dim == 3) {


			// Call Pore3D:
			err_code = p3dWriteRaw8(
				in_rev8,
				filename,
				(int) idl_in_rev->value.arr->dim[0],
				(int) idl_in_rev->value.arr->dim[1],
				(int) idl_in_rev->value.arr->dim[2],
				_p3d_idlPrintInfo,
				NULL
				);

			// On exception print error:
			if ((err_code == P3D_IO_ERROR) || (err_code == P3D_ERROR))
				_p3d_idlPrintNamedError("Error on code execution.");
		} else {
			_p3d_idlPrintNamedError("Input argument IMAGE must be a 2D or 3D matrix.");
		}
	} else if (idl_in_rev->type == IDL_TYP_UINT) {
		// Extract input in C format
		in_rev16 = (unsigned short *) idl_in_rev->value.arr->data;

		// Check if user wants to write a 2D image or a 3D volume:
		if (idl_in_rev->value.arr->n_dim == 2) {


			// Call Pore3D:
			err_code = p3dWriteRaw16(
				in_rev16,
				filename,
				(int) idl_in_rev->value.arr->dim[0],
				(int) idl_in_rev->value.arr->dim[1],
				1,
				little_endian,
				is_signed,
				_p3d_idlPrintInfo,
				NULL
				);

			// On exception print error:
			if ((err_code == P3D_IO_ERROR) || (err_code == P3D_ERROR))
				_p3d_idlPrintNamedError("Error on code execution.");
		} else if (idl_in_rev->value.arr->n_dim == 3) {


			// Call Pore3D:
			err_code = p3dWriteRaw16(
				in_rev16,
				filename,
				(int) idl_in_rev->value.arr->dim[0],
				(int) idl_in_rev->value.arr->dim[1],
				(int) idl_in_rev->value.arr->dim[2],
				little_endian,
				is_signed,
				_p3d_idlPrintInfo,
				NULL
				);

			// On exception print error:
			if ((err_code == P3D_IO_ERROR) || (err_code == P3D_ERROR))
				_p3d_idlPrintNamedError("Error on code execution.");

		} else {
			_p3d_idlPrintNamedError("Input argument IMAGE must be a 2D or 3D matrix."); 
		}
	} else if (idl_in_rev->type == IDL_TYP_ULONG) {
		// Extract input in C format
		in_rev32 = (unsigned int *) idl_in_rev->value.arr->data;

		// Check if user wants to write a 2D image or a 3D volume:
		if (idl_in_rev->value.arr->n_dim == 2) {


			// Call Pore3D:
			err_code = p3dWriteRaw32(
				in_rev32,
				filename,
				(int) idl_in_rev->value.arr->dim[0],
				(int) idl_in_rev->value.arr->dim[1],
				1,
				little_endian,
				is_signed,
				_p3d_idlPrintInfo,
				NULL
				);

			// On exception print error:
			if ((err_code == P3D_IO_ERROR) || (err_code == P3D_ERROR))
				_p3d_idlPrintNamedError("Error on code execution.");
		} else if (idl_in_rev->value.arr->n_dim == 3) {


			// Call Pore3D:
			err_code = p3dWriteRaw32(
				in_rev32,
				filename,
				(int) idl_in_rev->value.arr->dim[0],
				(int) idl_in_rev->value.arr->dim[1],
				(int) idl_in_rev->value.arr->dim[2],
				little_endian,
				is_signed,
				_p3d_idlPrintInfo,
				NULL
				);

			// On exception print error:
			if ((err_code == P3D_IO_ERROR) || (err_code == P3D_ERROR))
				_p3d_idlPrintNamedError("Error on code execution.");
		}
		else {
			_p3d_idlPrintNamedError("Input argument IMAGE must be a 2D or 3D matrix.");
		}	
	} else if (idl_in_rev->type == IDL_TYP_FLOAT) {
		// Extract input in C format
		in_rev32f = (float *) idl_in_rev->value.arr->data;

		// Check if user wants to write a 2D image or a 3D volume:
		if (idl_in_rev->value.arr->n_dim == 2) {


			// Call Pore3D:
			err_code = p3dWriteRaw32f(
				in_rev32f,
				filename,
				(int) idl_in_rev->value.arr->dim[0],
				(int) idl_in_rev->value.arr->dim[1],
				1,
				_p3d_idlPrintInfo,
				NULL
				);

			// On exception print error:
			if ((err_code == P3D_IO_ERROR) || (err_code == P3D_ERROR))
				_p3d_idlPrintNamedError("Error on code execution.");
		} else if (idl_in_rev->value.arr->n_dim == 3) {


			// Call Pore3D:
			err_code = p3dWriteRaw32f(
				in_rev32f,
				filename,
				(int) idl_in_rev->value.arr->dim[0],
				(int) idl_in_rev->value.arr->dim[1],
				(int) idl_in_rev->value.arr->dim[2],
				_p3d_idlPrintInfo,
				NULL
				);

			// On exception print error:
			if ((err_code == P3D_IO_ERROR) || (err_code == P3D_ERROR))
				_p3d_idlPrintNamedError("Error on code execution.");
		}
		else {
			_p3d_idlPrintNamedError("Input argument IMAGE must be a 2D or 3D matrix.");
		}

	} else {
		_p3d_idlPrintNamedError("Input argument IMAGE must be a BYTE, UINT, ULONG or FLOAT matrix.");
	}


	// Free keywords resources:
	IDL_KW_FREE;
}