/******************************************************************************
 * Copyright 1986, 2014 NVIDIA Corporation. All rights reserved.
 ******************************************************************************
 * Created:	08.01.2014
 * Purpose:	standard header file for all mental ray shaders
 *
 * Note: This file is generated automatically from the mental ray sources, do
 * not edit. Some definitions exist for internal reasons and are subject to
 * change between mental ray versions. See the mental ray user's manual for
 * a definitive description of the shader interface. Avoid using features not
 * documented in the manual because they may change in future versions.
 *****************************************************************************/

#include <stdio.h>
#include <math.h>

#ifndef SHADER_H
#define SHADER_H

#define RAY2			/* for shaders that share sources with 1.9 */

#ifdef __cplusplus
extern "C" {
#endif


/*------------ mi_raylib.h ------------*/



/** define C linkage for function prototypes */
#ifndef miC_LINKAGE
#if defined(__cplusplus)
#define miC_LINKAGE extern "C"
#else
#define miC_LINKAGE
#endif
#endif


#define miFALSE 0
#define miTRUE 1

typedef int                         	miBoolean;
typedef unsigned char			miCBoolean;	/* if space is tight */
typedef int				miInteger;	/* for shader params */
typedef signed char			miSint1;
typedef unsigned char			miUint1;
typedef signed short			miSint2;
typedef unsigned short			miUint2;
typedef signed int			miSint4;
typedef unsigned int			miUint4;
typedef unsigned int			miUint;
typedef unsigned char			miUchar;
typedef unsigned short			miUshort;


#if defined(_WIN32) && defined(_WIN64)
typedef unsigned __int64		miUlong;
typedef signed   __int64		miSlong;
#else
typedef unsigned long			miUlong;
typedef signed   long			miSlong;
#endif

typedef signed char			miSchar;
typedef float				miScalar;
typedef double				miGeoScalar;

typedef unsigned short			miIndex;
typedef unsigned int			miGeoIndex;
typedef miBoolean			(*miFunction_ptr)(void);
typedef miUint 				miTag;
typedef miSint4				miThreadID;
typedef miSint4				miHostID;
typedef miScalar			miMatrix[16];

/* forward decls */
struct miState;
struct miOptions;
struct miImg_image;
struct miInfo;
struct mi_lock;
struct miSpectrum;
struct miInstance;
struct miCamera;
struct miObject;
struct miMaterial;
struct miAssembly;

struct miVector2d { miScalar u, v; };
struct miVector { miScalar x, y, z; };
struct miGeoVector2d { miGeoScalar u, v; };
struct miGeoVector { miGeoScalar x, y, z; };
struct miQuaternion { miScalar x, y, z, w; };
struct miColor { miScalar r, g, b, a; };
struct miRange {miScalar min, max; };
struct miGeoRange {miGeoScalar min, max; };
union miPointer {void *p; miUint4 padding[2];};	/* 8-byte aligned ptr*/
union miLock { struct mi_lock* milockptr; int padding[2]; };

typedef struct miState		miState;
typedef struct miOptions	miOptions;
typedef struct miImg_image	miImg_image;
typedef struct miInfo		miInfo;
typedef struct miInstance       miInstance;
typedef struct miCamera         miCamera;
typedef struct miObject         miObject;
typedef struct miMaterial       miMaterial;
typedef struct miAssembly	miAssembly;

typedef struct miVector2d 	miVector2d;
typedef struct miVector		miVector;
typedef struct miGeoVector2d	miGeoVector2d;
typedef struct miGeoVector	miGeoVector;
typedef struct miQuaternion	miQuaternion;
typedef struct miColor		miColor;
typedef struct miSpectrum	miSpectrum;
typedef struct miRange		miRange;
typedef struct miGeoRange	miGeoRange;
typedef union miPointer		miPointer;
typedef union miLock		miLock;

typedef int (*miInh_func)(void **, void *, 
        int, void *, int, miInstance *, 
        miInstance *, miMatrix, miMaterial *);



/* int type wide enough for a pointer. */
typedef size_t				miIntptr;

#define miSCALAR_EPSILON		(1.0e-5f)
#define miGEO_SCALAR_EPSILON		(1e-9)
#define miHUGE_SCALAR			(1e36f)	/* don't require <limits.h> */
#define miHUGE_INT			(2147483647)
#define miNULL_INDEX			(0xffff) /* null value for miIndex */
#define miMAX_INDEX			(0xfffe) /* largest valid miIndex */
#define miNULL_GEOINDEX			(0xffffffff) /* null miGeoIndex */
#define miMAX_GEOINDEX			(0xfffffffe) /* largest miGeoIndex */
#define miNULLTAG                       ((miTag) 0)
#define miNOLIGHTS                      ((miTag) ~0)
#define miGHOSTTAG			((miTag) ~0)
#define miPARAMTAG			((miTag) ~1) /* parameter set directly */

typedef enum miModule {
	miM_NULL = 0,		/* not a legal module, wildcard value */
	miM_MSG,		/* message passing */
	miM_PAR,		/* message routing and event loops */
	miM_MEM,		/* memory manager */
	miM_DB,			/* database module */
	miM_PHEN,		/* phenomenon database */
	miM_RCRM,		/* rendering core: rasterizer */
	miM_SCENE,		/* common scene operations */
	miM_RC,			/* rendering core */
	miM_GAPMI,		/* geometry approximation (GAP) */
	miM_IMG,		/* image file read/write */
	miM_ECHO,		/* scene echo to .mi file */
	miM_MI,			/* mi file translator */
	miM_RCLM,		/* light mapping module */
	miM_RCH   = miM_RCLM + 2, /* Hair rendering */
	miM_GEOSI = miM_RCH+2,  /* surface / surface intersection */
	miM_LINK  = miM_GEOSI+2,/* dynamical linking, function symbol table */
	miM_P2SD,		/* polygonal import */
	miM_DISP,		/* realtime image displayer */
	miM_LPROF,              /* light profile support (ray 3.1) */
	miM_JOB,		/* job manager (ray 3.0) */
	miM_MAIN,		/* all front-ends with main() */
	miM_GEOMI,		/* geometry service library (GEO) */
	miM_EXR,		/* ILM OpenEXR image file library */
	miM_TRANS,		/* TRANS transaction handling */
	miM_INVENTOR,		/* SGI Inventor translator */
	miM_LIB,		/* library module, error messages */
	miM_API,		/* high-level app programming interface */
	miM_PHCR = miM_API + 2,	/* shader editor GUI */
	miM_RCB,		/* RC boxing */
	miM_RCC,		/* RC contours */
	miM_RCI,		/* RC intersection */
	miM_RCGI,		/* RC global illumination and caustics */
	miM_SIMP = miM_RCGI+2,	/* Mesh simplification */
	miM_SURF,		/* subdivision surfaces */
	miM_CAPI,		/* class api module */
	miM_GAPAD,		/* GAP adjacency detection and edge merging */
	miM_GAPCU,		/* GAP curves */
	miM_GAPDI,		/* GAP displacement mapping */
	miM_GAPIS,		/* GAP isoline segments */
	miM_GAPPO,		/* GAP polygons */
	miM_GAPFA,		/* GAP faces */
	miM_GAPTE,		/* GAP tessellation */
	miM_GEOCO,		/* GEO conditioning */
	miM_GEOEV,		/* GEO evaluation */
	miM_GEOMO,		/* GEO modelling */
	miM_GEOST,		/* GEO strips */
	miM_GEOTE,		/* GEO tessellation */
	miM_JPG,		/* JPEG compression/decompression */
	miM_RCFG,		/* Final gathering */
	miM_BSP2,		/* BSP2 */
	miM_DBN,		/* DBN module for neuray db elements */
	miM_BRDF = miM_DBN + 2, /* BRDF routines */
	miM_MATH,		/* MATH module */
	miM_BVH,		/* bounding volume module */
	miM_N2SD,		/* nurbs import */ 
	miM_PARTICLEMAP,	/* particle maps */
	miM_SCHED,		/* interface to neuray scheduler */
	miM_SERIAL,		/* interface to neuray serializer */
	miM_EXTERN,		/* external library routine, like png, expat */ 
	miM_CONT,		/* additional C++ containers */
	miM_SAMP,		/* sampling routines */
        miM_MSL,		/* metasl library */
	miM_DISK = miM_MSL + 2,	/* disk routines */
	miM_MRMSL,		/* mental ray metasl proxy */
	miM_SHADERDB = miM_MRMSL + 2,	/* metasl shader database */
	miM_MSLC,		/* metasl compiler proxy */
	miM_COMP = miM_MSLC + 3,/* metasl compiler kernel */
	miM_HALF = miM_COMP + 4,/* 16-bit float type */
	miM_RCMAP,		/* RC map */
	miM_LLVM,		/* LLVM MetaSL shaders backend */
	miM_IRAY,		/* IRAY renderer */
	miM_CUDA,		/* CUDA */
	miM_ENVLIGHT,		/* environment lighting / IBL */
        miM_RCGPU,              /* gpu render accelleration */
        miNMODULES		/* # of modules (not a module itself) */
} miModule;
#ifndef M_PI
#define M_PI		3.14159265358979323846
#endif
#ifndef M_PI_2
#define M_PI_2		1.57079632679489661923
#endif
#ifndef M_SQRT1_2
#define M_SQRT1_2	0.70710678118654752440
#endif
#define RAY2			/* defined for mental ray 2.0 and up */
#define RAY3			/* defined for mental ray 3.0 and up */
#define RAY31                   /* defined for mental ray 3.1 and up */
#define RAY32                   /* defined for mental ray 3.2 and up */
#define RAY33                   /* defined for mental ray 3.3 and up */
#define RAY34                   /* defined for mental ray 3.4 and up */
#define RAY35                   /* defined for mental ray 3.5 and up */
#define RAY36                   /* defined for mental ray 3.6 and up */
#define RAY37                   /* defined for mental ray 3.7 and up */
#define RAY38                   /* defined for mental ray 3.8 and up */
#define RAY39                   /* defined for mental ray 3.9 and up */
#define RAY310		        /* defined for mental ray 3.10 and up */
#define RAY311		        /* defined for mental ray 3.11 and up */
#define RAY312		        /* defined for mental ray 3.12 and up */

#ifndef DLLIMPORT
#ifdef _WIN32
#define DLLIMPORT __declspec(dllimport)
#else
#define DLLIMPORT
#endif
#endif

#ifndef DLLEXPORT
#ifdef _WIN32
#define DLLEXPORT __declspec(dllexport)
#elif __GNUC__ >= 4
#define DLLEXPORT __attribute__ ((visibility("default")))
#else
#define DLLEXPORT
#endif
#endif

/*------------ mi_lib.h ------------*/

/*
 * vector operations. MI_SQRT works for ANSI C compilers. If it causes trouble,
 * #define MI_SQRT sqrt before including this file. IBM and HP mess up as usual.
 */

#ifndef MI_SQRT
#define MI_SQRT sqrt
#endif

#define mi_vector_neg(r)	((r)->x = -(r)->x,\
				 (r)->y = -(r)->y,\
				 (r)->z = -(r)->z)

#define mi_vector_add(r,a,b)	((r)->x = (a)->x + (b)->x,\
				 (r)->y = (a)->y + (b)->y,\
				 (r)->z = (a)->z + (b)->z)

#define mi_vector_sub(r,a,b)	((r)->x = (a)->x - (b)->x,\
				 (r)->y = (a)->y - (b)->y,\
				 (r)->z = (a)->z - (b)->z)

#define mi_vector_mul(r,f)	((r)->x *= (f),\
				 (r)->y *= (f),\
				 (r)->z *= (f))

#define mi_vector_div(r,d)	do {if ((d) != 0.0f)\
					{miScalar _i=1.0f/(d);\
						 (r)->x *= _i;\
						 (r)->y *= _i;\
						 (r)->z *= _i; }} while (0)

#define mi_vector_div_d(r,d)	do {if ((d) != 0.0)\
					{double _i = 1.0/(d);\
						 (r)->x *= _i;\
						 (r)->y *= _i;\
						 (r)->z *= _i; }} while (0)

#define mi_vector_prod(r,a,b)	((r)->x = (a)->y * (b)->z - (a)->z * (b)->y,\
				 (r)->y = (a)->z * (b)->x - (a)->x * (b)->z,\
				 (r)->z = (a)->x * (b)->y - (a)->y * (b)->x)

#define mi_vector_dot(a,b)	((a)->x * (b)->x +\
				 (a)->y * (b)->y +\
				 (a)->z * (b)->z)

#define mi_vector_dot_d(a,b)	((double)(a)->x * (double)(b)->x +\
				 (double)(a)->y * (double)(b)->y +\
				 (double)(a)->z * (double)(b)->z)

#define mi_vector_norm(r)	(miScalar)MI_SQRT((r)->x * (r)->x +\
					(r)->y * (r)->y +\
					(r)->z * (r)->z)

#define mi_vector_norm_d(r)	sqrt((double)(r)->x * (double)(r)->x +\
				     (double)(r)->y * (double)(r)->y +\
				     (double)(r)->z * (double)(r)->z)

#define mi_vector_normalize(r)	do { miScalar _n = mi_vector_norm(r);\
				     mi_vector_div(r, _n); } while (0)

#define mi_vector_normalize_d(r) do { double _n= mi_vector_norm_d(r);\
				     mi_vector_div_d(r, _n); } while (0)

#define mi_vector_min(r,a,b)	((a)->x < (b)->x ? ((r)->x = (a)->x) \
						 : ((r)->x = (b)->x),\
				 (a)->y < (b)->y ? ((r)->y = (a)->y) \
						 : ((r)->y = (b)->y),\
				 (a)->z < (b)->z ? ((r)->z = (a)->z) \
						 : ((r)->z = (b)->z))

#define mi_vector_max(r,a,b)	((a)->x > (b)->x ? ((r)->x = (a)->x) \
						 : ((r)->x = (b)->x),\
				 (a)->y > (b)->y ? ((r)->y = (a)->y) \
						 : ((r)->y = (b)->y),\
				 (a)->z > (b)->z ? ((r)->z = (a)->z) \
						 : ((r)->z = (b)->z))

#define mi_vector_det(a,b,c)	((a)->x * ((b)->y * (c)->z - (c)->y * (b)->z)+\
				 (b)->x * ((c)->y * (a)->z - (a)->y * (c)->z)+\
				 (c)->x * ((a)->y * (b)->z - (b)->y * (a)->z))

#define mi_vector_dist(a,b)	MI_SQRT(((a)->x - (b)->x) * ((a)->x - (b)->x)+\
					((a)->y - (b)->y) * ((a)->y - (b)->y)+\
					((a)->z - (b)->z) * ((a)->z - (b)->z))

/*
 * matrix operations (libmatrix.c)
 */

#define	  mi_matrix_copy(t,s)		(void)memcpy((t),(s),sizeof(miMatrix))
#define	  mi_matrix_null(m)		(void)memset((m), 0, sizeof(miMatrix))

void		mi_matrix_ident		(miMatrix);
void		mi_matrix_prod		(miMatrix,
					 miMatrix const,
					 miMatrix const);
miBoolean	mi_matrix_isident	(miMatrix const);
miBoolean	mi_matrix_isnull	(miMatrix const);
float		mi_matrix_rot_det	(miMatrix const);
miBoolean	mi_matrix_invert	(miMatrix, miMatrix const);
void		mi_point_transform	(miVector * const,
					 miVector const * const,
					 miMatrix const);
void		mi_vector_transform	(miVector * const,
					 miVector const * const,
					 miMatrix const);
void		mi_vector_transform_T	(miVector * const,
					 miVector const * const,
					 miMatrix const);
void		mi_matrix_rotate	(miMatrix, const miScalar,
					 const miScalar, const miScalar);
void		mi_matrix_rotate_axis	(miMatrix, miVector const * const,
					 miScalar const);
miBoolean	mi_matrix_solve		(miScalar *, miMatrix const,
					 miScalar const *, int);

miScalar	mi_spline		(miScalar, int, const miScalar *);
miScalar	mi_random		(void);
miScalar	mi_erandom		(unsigned short seed[3]);
void		mi_srandom		(long newseed);
miScalar	mi_noise_1d		(miScalar);
miScalar	mi_unoise_1d		(miScalar);
miScalar	mi_noise_2d		(miScalar, miScalar);
miScalar	mi_unoise_2d		(miScalar, miScalar);
miScalar	mi_noise_3d		(miVector *);
miScalar	mi_unoise_3d		(const miVector *);
miScalar	mi_noise_1d_grad	(miScalar, miScalar *);
miScalar	mi_unoise_1d_grad	(miScalar, miScalar *);
miScalar	mi_noise_2d_grad	(miScalar, miScalar,
					 miScalar *, miScalar *);
miScalar	mi_unoise_2d_grad	(miScalar, miScalar,
					 miScalar *, miScalar *);
miScalar	mi_noise_3d_grad	(const miVector *, miVector *);
miScalar	mi_unoise_3d_grad	(const miVector *, miVector *);


/*
 * error handler: severity levels for mi_set_verbosity (miERR_*), and
 * sub-levels to turn on individual message types per module (miMSG_*).
 */

void		mi_fatal		(const char *, ...);
void		mi_error		(const char *, ...);
void		mi_warning		(const char *, ...);
void		mi_info			(const char *, ...);
void		mi_progress		(const char *, ...);
void		mi_debug		(const char *, ...);
void		mi_vdebug		(const char *, ...);
void		mi_nfatal		(int, const char *, ...);
void		mi_nerror		(int, const char *, ...);
void		mi_nwarning		(int, const char *, ...);
const char	*mi_strerror		(void);

char *mi_string_substitute(	/* apply dos/unix etc path substns */
	char		*new_name,		/* place to copy mangled path*/
	const char	*name,			/* path to be mangled */
	long		max_new_name_len);	/* size of new_name[] */

struct miState;

miScalar mi_luminance(struct miState *state, miColor *c);

miScalar mi_blackbody_spectral_radiance( /* in W/(sr m^2 nm) */
    miScalar temperature, /* in Kelvin */
    miScalar wavelength); /* in nano-meter */

miScalar mi_blackbody_radiance( /* W/m^2/sr */
    miColor* c, miScalar temperature, miBoolean normalized);

void mi_ciexyz_weights(miColor* weight, miScalar wavelen);


/* returned by miQ_PRI_DATA: */
typedef struct miPri_data {
	miUint		info_size;	/* size of info */
	miUint		*info;		/* info: data layout */
	miUint		data_size;	/* size of triangle data */
	miUint		*data;		/* primitive (triangle) data */
} miPri_data;

typedef enum miQ_type {
	miQ_NONE			= 0,
	miQ_VERSION			= 1,
	miQ_DATE			= 2,
	miQ_INST_FUNCTION		= 3,
	miQ_INST_GLOBAL_TO_LOCAL	= 4,
	miQ_INST_LOCAL_TO_GLOBAL	= 5,
	miQ_INST_IDENTITY		= 6,
	miQ_INST_ITEM			= 7,
	miQ_INST_PLACEHOLDER_ITEM	= 153,
	miQ_INST_PARENT			= 8,
	miQ_INST_HIDE			= 9,
	miQ_INST_VISIBLE		= 90,
	miQ_INST_SHADOW			= 91,
	miQ_INST_TRACE			= 92,
	miQ_INST_CAUSTIC		= 93,
	miQ_INST_GLOBILLUM		= 111,
	miQ_INST_FINALGATHER		= 151,
	miQ_INST_DECL			= 10,
	miQ_INST_PARAM_SIZE		= 11,
	miQ_INST_PARAM			= 12,
	miQ_INST_MATERIAL		= 83,
	miQ_INST_LABEL			= 101,
	miQ_INST_DATA			= 102,
        miQ_INST_AREA			= 125,
	miQ_GROUP_MERGE_GROUP		= 13,
	miQ_GROUP_NKIDS			= 14,
	miQ_GROUP_KID			= 15,
	miQ_GROUP_LABEL			= 103,
	miQ_GROUP_DATA			= 104,
	miQ_OBJ_TYPE			= 16,
	miQ_OBJ_VISIBLE			= 17,
	miQ_OBJ_TRACE			= 18,
	miQ_OBJ_SHADOW			= 19,
	miQ_OBJ_VIEW_DEPENDENT		= 20,
	miQ_OBJ_CAUSTIC			= 21,
	miQ_OBJ_GLOBILLUM		= 112,
	miQ_OBJ_FINALGATHER		= 150,
	miQ_OBJ_LABEL			= 22,
	miQ_OBJ_DATA			= 100,
	miQ_LIGHT_TYPE			= 23,
	miQ_LIGHT_AREA			= 24,
	miQ_LIGHT_EXPONENT		= 25,
	miQ_LIGHT_CAUSTIC_PHOTONS	= 26,
	miQ_LIGHT_CAUSTIC_PHOTONS_EMIT	= 135,
	miQ_LIGHT_CAUSTIC_PHOTONS_EMITTED = 144,
	miQ_LIGHT_GLOBAL_PHOTONS	= 27,
	miQ_LIGHT_GLOBAL_PHOTONS_EMIT	= 136,
	miQ_LIGHT_GLOBAL_PHOTONS_EMITTED = 145,
	miQ_LIGHT_ENERGY		= 28,
	miQ_LIGHT_SHADER		= 29,
	miQ_LIGHT_EMITTER		= 30,
	miQ_LIGHT_ORIGIN		= 31,
	miQ_LIGHT_DIRECTION		= 32,
	miQ_LIGHT_AREA_R_EDGE_U		= 33,
	miQ_LIGHT_AREA_R_EDGE_V		= 34,
	miQ_LIGHT_AREA_D_NORMAL		= 35,
	miQ_LIGHT_AREA_D_RADIUS		= 36,
	miQ_LIGHT_AREA_S_RADIUS		= 37,
	miQ_LIGHT_AREA_C_RADIUS		= 96,
	miQ_LIGHT_AREA_C_AXIS		= 97,
	miQ_LIGHT_AREA_SAMPLES_U	= 38,
	miQ_LIGHT_AREA_SAMPLES_V	= 39,
	miQ_LIGHT_SPREAD		= 40,
	miQ_LIGHT_USE_SHADOWMAP		= 41,
	miQ_LIGHT_LABEL			= 98,
	miQ_LIGHT_DATA			= 99,
	miQ_LIGHT_TANGENT_SPACE		= 155,
	miQ_LIGHT_NORMAL                = 156,
	miQ_LIGHT_SAMPLE_COORD		= 147,
	miQ_MTL_OPAQUE			= 42,
	miQ_MTL_SHADER			= 43,
	miQ_MTL_DISPLACE		= 44,
	miQ_MTL_SHADOW			= 45,
	miQ_MTL_VOLUME			= 46,
	miQ_MTL_ENVIRONMENT		= 47,
	miQ_MTL_CONTOUR			= 48,
	miQ_MTL_PHOTON			= 49,
	miQ_MTL_PHOTONVOL		= 50,
	miQ_MTL_LIGHTMAP		= 146,
 	miQ_FUNC_USERPTR		= 51,
	miQ_FUNC_LOCK			= 52,
	miQ_FUNC_TYPE			= 53,
	miQ_FUNC_DECL			= 54,
	miQ_FUNC_NEXT			= 55,
	miQ_FUNC_INDIRECT		= 56,
	miQ_FUNC_PARAM_SIZE		= 57,
	miQ_FUNC_RESULT_SIZE		= 58,
	miQ_FUNC_PARAM			= 59,
	miQ_FUNC_PARAM_VALUE		= 165,
	miQ_FUNC_TLS_GET		= 124,
	miQ_FUNC_TLS_SET		= 126,
	miQ_FUNC_TLS_GETALL		= 127,
	miQ_FUNC_CALLTYPE		= 140,
	miQ_FUNC_TAG			= 141,
	miQ_FUNC_IS_ROOT		= 160,
	miQ_DECL_LOCK			= 60,
	miQ_DECL_TYPE			= 61,
	miQ_DECL_RESULT_SIZE		= 62,
	miQ_DECL_NAME			= 63,
	miQ_DECL_PARAM			= 64,
	miQ_DECL_VERSION		= 89,
	miQ_IMAGE_WIDTH			= 65,
	miQ_IMAGE_HEIGHT		= 66,
	miQ_IMAGE_BITS			= 67,
	miQ_IMAGE_COMP			= 68,
	miQ_IMAGE_FILTER		= 69,
	miQ_IMAGE_DESATURATE		= 85,
	miQ_IMAGE_DITHER		= 86,
	miQ_IMAGE_NOPREMULT		= 87,
	miQ_IMAGE_GAMMA			= 88,
	miQ_IMAGE_COLORCLIP		= 115,
	miQ_NUM_GLOBAL_LIGHTS		= 70,
	miQ_GLOBAL_LIGHTS		= 71,
	miQ_TRANS_INTERNAL_TO_WORLD	= 72,
	miQ_TRANS_INTERNAL_TO_CAMERA	= 73,
	miQ_TRANS_INTERNAL_TO_OBJECT	= 74,
	miQ_TRANS_WORLD_TO_INTERNAL	= 75,
	miQ_TRANS_CAMERA_TO_INTERNAL	= 76,
	miQ_TRANS_OBJECT_TO_INTERNAL	= 77,
	miQ_TRANS_WORLD_TO_CAMERA	= 78,
	miQ_TRANS_WORLD_TO_OBJECT	= 79,
	miQ_TRANS_CAMERA_TO_WORLD	= 80,
	miQ_TRANS_OBJECT_TO_WORLD	= 81,
	miQ_NUM_TEXTURES		= 82,
	miQ_NUM_BUMPS			= 137,
	miQ_NUM_MOTIONS			= 183,
	miQ_GEO_LABEL			= 84,
	miQ_GEO_DATA			= 114,
	miQ_GEO_HAS_DERIVS		= 138,
	miQ_GEO_HAS_DERIVS2		= 139,
	miQ_PRI_BBOX_MIN		= 94,
	miQ_PRI_BBOX_MAX		= 95,
	miQ_PRI_ASSEMBLY_INST_TAG	= 162,
	miQ_DATA_PARAM			= 105,
	miQ_DATA_DECL			= 106,
	miQ_DATA_NEXT			= 107,
	miQ_DATA_LABEL			= 108,
	miQ_DATA_PARAM_SIZE		= 109,
	miQ_DATA_NEEDSWAP		= 110,
	miQ_TILE_PIXELS			= 116,
	miQ_TILE_SAMPLES		= 117,
	miQ_FINALGATHER_STATE		= 142,
	miQ_SCENE_BBOX_ALL		= 118,
	miQ_SCENE_BBOX_SHADOW		= 119,
	miQ_SCENE_BBOX_GLOBILLUM_G	= 120,
	miQ_SCENE_BBOX_GLOBILLUM_R	= 121,
	miQ_SCENE_BBOX_CAUSTIC_G	= 122,
	miQ_SCENE_BBOX_CAUSTIC_R	= 123,
        miQ_LIGHTPROFILE_PHI_MIN        = 128,
        miQ_LIGHTPROFILE_PHI_MAX        = 129,
        miQ_LIGHTPROFILE_COSTHETA_MIN   = 130,
        miQ_LIGHTPROFILE_COSTHETA_MAX   = 131,
        miQ_LIGHTPROFILE_INTENSITY_MAX  = 132,
        miQ_LIGHTPROFILE_PHI_RES        = 133,
        miQ_LIGHTPROFILE_THETA_RES      = 134,
	miQ_PIXEL_SAMPLE		= 143,
	miQ_SCENE_ROOT_GROUP		= 148,
	miQ_TEXTURE_DIM			= 152,
	miQ_PRI_DATA			= 154,
	miQ_PRI_INDEX			= 159,
	miQ_SAMPLE_MOVING		= 158,
	miQ_RAY_INTERFACE               = 157,
	miQ_STAGE		        = 161,
	miQ_BUMP_BASIS		        = 163,
        miQ_HAIR_NUM_TEXTURES           = 182,
	miQ_HAIR_NUM_USERS              = 166,
        miQ_HAIR_USERS                  = 167,
        miQ_HAIR_RADIUS                 = 113,
	miQ_PRI_NUM_VERTICES		= 181,
	miQ_PRI_VERTICES_POINTS		= 168,
	miQ_PRI_VERTICES_NORMALS	= 169,
	miQ_PRI_VERTICES_MOTION		= 170,
	miQ_PRI_VERTICES_TEX		= 171,
	miQ_PRI_VERTICES_USER		= 172,
	miQ_PRI_VERTICES_BUMPS_U	= 173,
	miQ_PRI_VERTICES_BUMPS_V	= 174,
	miQ_PRI_VERTICES_DERIVS_U	= 175,
	miQ_PRI_VERTICES_DERIVS_V	= 176,
	miQ_PRI_VERTICES_DERIVS_UU	= 177,
	miQ_PRI_VERTICES_DERIVS_VV	= 178,
	miQ_PRI_VERTICES_DERIVS_UV	= 179,
	miQ_PRI_VERTICES_DERIVS_VU	= miQ_PRI_VERTICES_DERIVS_UV,
	miQ_PRI_PARTICLE_INDEX		= 180,
	miQ_PRI_PARTICLE_TYPE		= 184,
	miQ_PRI_PARTICLE_UV		= 185,
	miQ_PRI_SDS_UV			= 186,
	miQ_PRI_UV_DIFFERENTIALS	= 187,
	miQ_PRI_NUM_DATA		= 188,
	miQ_NUM_USERS			= 189,
	miQ_USER_DIM			= 190,
	miQ_PRI_VERTEX_INFO		= 191,
	miQ_PRI_VERTEX_INFO_INDEX	= 192,
	miQ_PRI_NUM_VERTEX_INFOS	= 193,
	miQ_PRI_TYPE			= 194,
	miNQ				= 195
} miQ_type;

/* returned values for the miQ_STAGE mode */
typedef enum {
	miSTAGE_UNKNOWN			= 0,		/* no rendering/unknown stage */
	miSTAGE_TILE 			= 1 << 0,	/* rendering tile */
	miSTAGE_FINALGATHER_PRECOMP	= 1 << 1,	/* precomputing final gathering */
	miSTAGE_AO_PRECOMP		= 1 << 2,	/* precomputing ambient occlusion */
	miSTAGE_CAUSTIC_EMIT		= 1 << 3,	/* caustic photon emission */
	miSTAGE_GLOBILLUM_EMIT		= 1 << 4,	/* globillum photon emission */
	miSTAGE_PHOTON_EMIT		= miSTAGE_CAUSTIC_EMIT | miSTAGE_GLOBILLUM_EMIT,
	miSTAGE_IMPORTON_EMIT		= 1 << 5,	/* importon emission */
	miSTAGE_LIGHTMAP		= 1 << 6,	/* computing light map */
	miSTAGE_IP_COMP			= 1 << 7	/* irr particles computation */
} miStage; 

struct miState;
miBoolean	mi_query(miQ_type, miState *, miUint, void *, ...);
#define miSS_LIFETIME_EYERAY	1	/* for mi_shaderstate_set: delete */
#define miSS_LIFETIME_RECT	2	/* if eye ray is done, or sometime */
					/* later when pixel rect is finished */
miBoolean mi_shaderstate_set(
	struct miState	*state,		/* table is anchored in state->ts */
	const char	*key,		/* key to look up */
	void		*value,		/* value to store */
	int		valsize,	/* # of bytes in value */
	int		lifetime);	/* 0=subrays, 1=eye ray, 2=many rays */

void *mi_shaderstate_get(
	struct miState	*state,		/* table is anchored in state->ts */
	const char	*key,		/* key to look up */
	int		*valsize);	/* # of bytes in key (strlen/sizeof) */

void mi_shaderstate_enumerate(
	struct miState	*state,		/* table is anchored in state->ts */
	miBoolean	(*cb)(void *arg, char *key, void *val, int vsz, int l),
	void		*arg);		/* opaque data pointer for cb */
typedef enum miKdtree_type {
	miKDTREE_UNKNOWN		= 0,
	miKDTREE_3D,
	miKDTREE_NTYPES 		= miKDTREE_3D
} miKdtree_type;


struct miKdtree;

typedef miBoolean ((miKdtree_insert_callback)
	(void 		*callback_data, /* user callback data */
	 void		*data,		/* element data */
	 miScalar	point[],	/* element location */
	 const void 	*shared_data)); /* data shared for inserting elements*/

typedef miBoolean ((miKdtree_lookup_callback)
	(void 		*callback_data, /* user callback data */
	 const void	*data,		/* element data */
	 const miScalar	point[]));	/* element location */

miTag mi_kdtree_create(
	miKdtree_type	type,		/* access type and dimension */
	miUint		datasize);	/* data size of the element */

struct miKdtree *mi_kdtree_edit(
	miTag		tag,			/* kdtree tag */
	const void	*shared_data,		/* data shared by elements */
	miUint		shared_data_size);	/* size of the data */

miBoolean mi_kdtree_add(
	struct miKdtree	*tree,		/* thread handle to the tree */
	const void	*data,		/* element data to store */
	const miScalar	point[]);	/* element location to store */

miBoolean mi_kdtree_unpin(
	struct miKdtree	*tree);		/* thread handle to the tree */

struct miKdtree *mi_kdtree_access(
	miTag			 tag,
	miKdtree_insert_callback *callback, /* modify/reject new elements*/
	void			 *callback_data); /* user callback data */

miUint mi_kdtree_lookup(
	struct miKdtree	*tree,	     /* thread handle to the tree */
	const miScalar	point[],     /* lookup position */
	miUint		max_n,	     /* max. number of elem. to look for */
	miScalar	max_dist,    /* max. distance to look for */
	miScalar	*max_dist_used,	   /* out: dist. to farthest elem.*/
	miKdtree_lookup_callback *callback,/* callback function*/
	void		*callback_data);   /* user callback data */

miBoolean mi_kdtree_iterate(
	struct miKdtree	*tree,		   /* thread handle to the tree */
	miKdtree_lookup_callback *callback,/* callback function*/
	void		*callback_data);   /* user callback data */

miBoolean mi_kdtree_delete(
	miTag		tag);	/* Unpinned tree tag */

/*------------ mi_mem.h ------------*/

struct miMemblk;
typedef struct miMemblk miMemblk;

/*
 * Uncomment this to use size_t allocators, but loose binary compatibility
 * with older mental ray versions.
 */
/* 
#define MI_USE_SIZET_ALLOCATORS
*/


#ifndef MI_USE_SIZET_ALLOCATORS
#define mi_mem_allocate(s)	mi_mem_int_allocate	(__FILE__,__LINE__,s)
#define mi_mem_reallocate(m,s)	mi_mem_int_reallocate	(__FILE__,__LINE__,m,s)
#else
#define mi_mem_allocate(s)	mi_mem_int_allocate_sizet  (__FILE__,__LINE__,s)
#define mi_mem_reallocate(m,s)	mi_mem_int_reallocate_sizet(__FILE__,__LINE__,m,s)
#endif

#define mi_mem_blkcreate(s)	mi_mem_int_blkcreate	(__FILE__,__LINE__,s)
#define mi_mem_strdup(s)	mi_mem_int_strdup	(__FILE__,__LINE__,s)
#define mi_mem_release(m)	mi_mem_int_release	(__FILE__,__LINE__,m)
#define mi_mem_test_allocate(s)	mi_mem_int_test_allocate(__FILE__,__LINE__,s)
#define mi_mem_test_reallocate(m,s)	mi_mem_int_test_reallocate\
							(__FILE__,__LINE__,m,s)
void		*mi_mem_int_allocate	   	(const char *, int, miUint);
void		*mi_mem_int_allocate_sizet 	(const char *, int, size_t);
void		*mi_mem_int_test_allocate  	(const char *, int, miUint);
void		*mi_mem_int_reallocate	   	(const char *, int, void *, miUint);
void 		*mi_mem_int_reallocate_sizet	(const char *, int, void *, size_t);
void		*mi_mem_int_test_reallocate	(const char *, int, void *, miUint);
void		 mi_mem_int_release	   	(const char *, int, void *);
void		 mi_mem_check		(void);
miUlong		 mi_mem_getsize		(void);
void		 mi_mem_summary		(void);
void		 mi_mem_dump		(const miModule);

char		*mi_mem_int_strdup	(const char *, int, const char *);

/*
 * block allocator. note that the current internal block size is 8Kb, and
 * we assume that at least two items fit on a page. hence the largest block
 * you should use the block allocator for is around 4000 bytes. even in this
 * range the efficiency of using a block allocator is noticeably lower than
 * for smaller blocks. it is recommended to use the block allocator only up
 * to a block size of about 1Kb.
 */

extern const int mi_mem_blkmaxsize; /* maximal block size */
miMemblk	*mi_mem_int_blkcreate	(const char *, int, int);
void		 mi_mem_blkdelete	(miMemblk *);
void		*mi_mem_blkallocate	(miMemblk *);
void		*mi_mem_blkfallocate	(miMemblk *);
void		 mi_mem_blkrelease	(miMemblk *, void *);
void		 mi_mem_blkfrelease	(miMemblk *, void *);
void		 mi_mem_blkclear	(miMemblk *);
void		 mi_mem_blkenumerate	(miMemblk *, void (*)(void *));

/*------------ mi_db.h ------------*/

const void  *mi_db_access(miTag);	/* access tag content */
int    mi_db_type       (miTag);	/* get tag type */
miUint    mi_db_size    (miTag);	/* check if tag is a job */
miBoolean mi_db_isjob   (miTag);	/* access tag type and content */
void  *mi_db_access_type(
			int *,		/* returned type, really miScene_type*/
			miTag);		/* tag to be accessed */
void   mi_db_unpin	(miTag);	/* tag to be unpinned */
void  *mi_db_create    (
			miTag *,	/* returned new tag */
			int,		/* miSCENE_* type to store */
			int);		/* size of item in bytes */
void  *mi_db_realloc(
			miTag,		/* tag to be resized */
			miUint);	/* new size of the db item */
void   mi_db_delete	(miTag);	/* tag to be deleted */
miTag  mi_db_copy	(miTag);	/* source tag to duplicate */
void   mi_db_dump	(miModule);/* dump whose entries, 0=all */

/*------------ mi_img.h ------------*/

/*
 * supported internal scanline types. These types are used when a file is
 * opened and created; they specify the internal data structure but not the
 * type of the file to be created. The use as array indexes is the reason
 * why every enumerator is assigned explicitly, to show that the numbers
 * are important.
 * miIMG_TYPE_ANY is a wildcard that disables conversion. The USER types
 * are assigned real types in "frame buffer" statements. Defining them here
 * allows storing them in the out_type and out_interp bitmaps in miFunction.
 */

struct miColor_profile;

enum miImg_type {
	miIMG_TYPE_RGBA		= 0,	/* 4*8	bits, color with alpha */
	miIMG_TYPE_RGBA_16	= 1,	/* 4*16 bits, color with alpha */
	miIMG_TYPE_RGB		= 2,	/* 3*8	bits, color */
	miIMG_TYPE_RGB_16	= 3,	/* 3*16 bits, color */
	miIMG_TYPE_A		= 4,	/* 1*8	bits, alpha */
	miIMG_TYPE_A_16		= 5,	/* 1*16 bits, alpha */
	miIMG_TYPE_S		= 6,	/* 1*8	bits, intensity */
	miIMG_TYPE_S_16		= 7,	/* 1*16 bits, intensity */
	miIMG_TYPE_VTA		= 8,	/* 2*16 bits, bumpmap from alpha */
	miIMG_TYPE_VTS		= 9,	/* 2*16 bits, bumpmap from intensity */
	miIMG_TYPE_Z		= 10,	/* 1*32 bits, Z coordinates (float) */
	miIMG_TYPE_N		= 11,	/* 3*32 bits, normal vectors (float) */
	miIMG_TYPE_M		= 14,	/* 3*32 bits, motion vectors (float) */
	miIMG_TYPE_TAG		= 12,	/* 1*32 bits, material tags (u int) */
	miIMG_TYPE_BIT		= 15,	/* 1*1	bit,  must-render flag map */
	miIMG_TYPE_RGBA_FP	= 13,	/* 4*32 bits, color with alpha, float*/
	miIMG_TYPE_RGB_FP	= 16,	/* 3*32 bits, color, float*/
	miIMG_TYPE_COVERAGE	= 17,	/* 1*32 bits, coverage, float */
	miIMG_TYPE_RGBE		= 18,	/* 4*8  bits, HDR with common expon. */
	miIMG_TYPE_A_FP		= 19,	/* 1*32 bits, alpha */
	miIMG_TYPE_S_FP		= 20,	/* 1*32 bits, intensity */
	miIMG_TYPE_RGBA_H	= 21,	/* 4*16 bits half float */
	miIMG_TYPE_RGB_H	= 22,	/* 3*16 bits half float */
	miIMG_TYPE_A_H		= 23,	/* 1*16 bits half float */
	miIMG_TYPE_S_H		= 24,	/* 1*16 bits half float */
	miIMG_NTYPES		= 25,
					/* remainder is out-of-band types */
	miIMG_TYPE_CONT		= 29,	/* API/PHEN: contours */
	miIMG_TYPE_ANY		= 30,	/* img_open: don't convert */
	miIMG_TYPE_USER_FIRST	= 31	/* API/PHEN: user-defined types >= 0 */
};

#define miIMG_USER_MASK		0x7f000000	/* bits 25-30 */
/* number of user FBs packed to the mask */
#define miIMG_USER_N_FB		(miIMG_TYPE_USER_FIRST - miIMG_NTYPES)

typedef enum miImg_type miImg_type;

/* The documented error return */
#define miIMG_TYPE_ERROR miIMG_NTYPES



/*
 * supported file formats. These are used for one purpose only: when creating
 * an image file, they specify the output format. When adding or inserting
 * an entry, add external declarations and entries to all arrays defined as
 * "something[miIMG_NFORMATS]" at the beginning of imgdispatch.c. Make sure
 * the order is correct!
 * Generally, common formats should precede uncommon, and formats difficult
 * to recognize by their headers should come last (qnt, zpic). QNT_PAL must
 * be QNT_NTSC-1, and there may be only two QNT formats (see mi_img_open).
 */

enum miImg_format {
	miIMG_FORMAT_RLA	= 0,	/* Wavefront RLA */
	miIMG_FORMAT_RLB	= 1,	/* Wavefront RLB */
	miIMG_FORMAT_PIC	= 2,	/* Softimage pic, compressed */
	miIMG_FORMAT_ALIAS	= 3,	/* Alias */
	miIMG_FORMAT_RGB	= 4,	/* SGI RGB, compressed */
	miIMG_FORMAT_CT		= 5,	/* mi Color Texture */
	miIMG_FORMAT_CT_16	= 6,	/* mi Color Texture, 16 bits */
	miIMG_FORMAT_ST		= 7,	/* mi Scalar Texture */
	miIMG_FORMAT_ST_16	= 8,	/* mi Scalar Texture, 16 bits */
	miIMG_FORMAT_VT		= 9,	/* mi vector texture, from alpha */
	miIMG_FORMAT_WT		= 10,	/* mi vector texture, from intensity */
	miIMG_FORMAT_ZT		= 11,	/* mi Z channel, from intersect depth*/
	miIMG_FORMAT_NT		= 12,	/* mi normal vectors */
	miIMG_FORMAT_MT		= 28,	/* mi motion vectors */
	miIMG_FORMAT_TT		= 13,	/* mi tag channel, from material tags*/
	miIMG_FORMAT_BIT	= 29,	/* mi one-bit render-enable flags */
	miIMG_FORMAT_TIFF	= 14,	/* compressed	any TIFF */
	miIMG_FORMAT_TIFF_U	= 15,	/* uncompressed any TIFF */
	miIMG_FORMAT_TIFF_3	= 16,	/* compressed	any 3-component TIFF */
	miIMG_FORMAT_TIFF_U3	= 17,	/* uncompressed any 3-component TIFF */
	miIMG_FORMAT_TIFF_16	= 30,	/* compressed any 16bit TIFF */
	miIMG_FORMAT_TIFF_16_U	= 31,	/* uncompress any 16bit TIFF */
	miIMG_FORMAT_TIFF_16_3	= 32,	/* compressed 3-component 16bit TIFF */
	miIMG_FORMAT_TIFF_16_U3	= 33,	/* uncompress 3-component 16bit TIFF */
	miIMG_FORMAT_CATIA	= 18,	/* Dassault Systemes Catia format */
	miIMG_FORMAT_PPM	= 19,	/* Jef Poskanzer's portable pixmaps */
	miIMG_FORMAT_CT_FP	= 20,	/* mi Color Texture, floating-point */
	miIMG_FORMAT_MAP	= 21,	/* mmap-ed raw texture file */
	miIMG_FORMAT_TARGA	= 22,	/* compressed RGBA Targa */
	miIMG_FORMAT_BMP	= 23,	/* Microsoft BMP 32-bit uncompressed */
	miIMG_FORMAT_QNT_PAL	= 24,	/* Quantel/Abekas, 576x720 */
	miIMG_FORMAT_QNT_NTSC	= 25,	/* Quantel/Abekas, 486x720 */
	miIMG_FORMAT_ZPIC	= 26,	/* Softimage Zpic, uncompr Z coords */
	miIMG_FORMAT_NULL	= 27,	/* dummy file, write nothing at all */
	miIMG_FORMAT_JPEG	= 34,	/* baseline sequential JPEG */
	miIMG_FORMAT_LWI	= 35,	/* Solidworks texture, read only */
	miIMG_FORMAT_PS		= 36,	/* PostScript - write only */
	miIMG_FORMAT_EPS	= 37,	/* encapsulated PostScript */
	miIMG_FORMAT_CT_H	= 38,	/* mi Color Texture, HDR RGBE */
	miIMG_FORMAT_HDR	= 39,	/* Radiance HDR (aka PIC) */
	miIMG_FORMAT_ST_FP	= 40,	/* mi Color Texture, 32 bits */
	miIMG_FORMAT_IFF	= 41,	/* Alias|wavefront IFF compressed */
	miIMG_FORMAT_CUSTOM_0	= 42,	/* user-defined */
	miIMG_FORMAT_CUSTOM_1	= 43,	/* user-defined */
	miIMG_FORMAT_CUSTOM_2	= 44,	/* user-defined */
	miIMG_FORMAT_CUSTOM_3	= 45,	/* user-defined */
	miIMG_FORMAT_CUSTOM_4	= 46,	/* user-defined */
	miIMG_FORMAT_CUSTOM_5	= 47,	/* user-defined */
	miIMG_FORMAT_CUSTOM_6	= 48,	/* user-defined */
	miIMG_FORMAT_CUSTOM_7	= 49,	/* user-defined */
	miIMG_FORMAT_CUSTOM_8	= 50,	/* user-defined */
	miIMG_FORMAT_CUSTOM_9	= 51,	/* user-defined */
	miIMG_FORMAT_CUSTOM_10	= 52,	/* user-defined */
	miIMG_FORMAT_CUSTOM_11	= 53,	/* user-defined */
	miIMG_FORMAT_CUSTOM_12	= 54,	/* user-defined */
	miIMG_FORMAT_CUSTOM_13	= 55,	/* user-defined */
	miIMG_FORMAT_CUSTOM_14	= 56,	/* user-defined */
	miIMG_FORMAT_CUSTOM_15	= 57,	/* user-defined */
	miIMG_FORMAT_CUSTOM_LAST= 57,	/* last user-defined */
	miIMG_FORMAT_PNG	= 58,	/* png */
	miIMG_FORMAT_SHMAP	= 59,   /* internal shadowmap format */
	miIMG_FORMAT_EXR	= 60,   /* ILM OpenEXR */
	miIMG_FORMAT_DDS	= 61,   /* Microsoft DDS */
	miIMG_FORMAT_MAP_V1     = 62,   /* .map format of mental ray 3.10 and prior */
	miIMG_NFORMATS		= 63,

	miIMG_FORMAT_FROM_EXT   = 255   /* deduce format from file extension */
};

typedef enum miImg_format miImg_format;
/* The documented error return */
#define miIMG_FORMAT_ERROR miIMG_NFORMATS


/*
 * error codes. If you add one, also add a message to errmsg[] in libimg.c.
 */

typedef enum miImg_error {
	miIMG_ERR_NONE		= 0,	/* no error */
	miIMG_ERR_READ		= 1,	/* can't read, end of file */
	miIMG_ERR_WRITE		= 2,	/* can't write, probably disk full */
	miIMG_ERR_DECODE	= 3,	/* file format error */
	miIMG_ERR_ENCODE	= 4,	/* internal error */
	miIMG_ERR_TYPE		= 5,	/* unrecognized file type */
	miIMG_ERR_SUBTYPE	= 6,	/* file version not supported */
	miIMG_ERR_CREATE	= 7,	/* failed to create file */
	miIMG_ERR_OPEN		= 8,	/* failed to open file */
	miIMG_ERR_CLOSE		= 9,	/* failed to close file */
	miIMG_ERR_ARGS		= 10,	/* incorrect call argument */
	miIMG_ERR_NOTOPEN	= 11,	/* file not open */
	miIMG_ERR_NOTCLOSED	= 12,	/* file still open, can't re-open */
	miIMG_ERR_SIZE		= 13,	/* wrong file size */
	miIMG_NERRS
} miImg_error;


/*
 * file descriptor. The file name is stored to be able to print meaningful
 * error messages. It is an array, not a strdup'ed pointer, because it is
 * not clear who would de-allocate the name otherwise. If the file name is
 * longer than the array, it is truncated. The real file name is stored
 * too, but it can't be relied upon to exist. Gamma is not used and may go
 * away in future versions.
 * Other modules may only use the public fields. The others are reserved
 * by raylib (and in fact not documented in the external manual). The fp
 * field is actually a FILE*, but it's void* here because otherwise every
 * file including img.h would have to include stdio.h as well. It's always
 * cast to FILE* in img*.c.
 */

typedef struct miImg_line {
	unsigned long long	c[4];		/* indexed by miIMG_* */
} miImg_line;					/* component scanlines follow here */

typedef struct miImg_file {
	int		null;		/* bomb out if someone forgets & */
					/* --------------- public --------- */
	int		width, height;	/* width and height in pixels */
	int		bits;		/* requested bits per component, 8/16*/
	int		comp;		/* requested components/pixel, 1..4 */
	miBoolean	filter;		/* caller wants filtered lookups */
	miBoolean	topdown;	/* read file top-down */
	int		filesize0;	/* deprecated (4GB limit): if reading, 
                                         * size of file in bytes */
	float		gamma;		/* gamma correction value (read only)*/
	float		aspect;		/* aspect/xres*yres (for .pic output)*/
	float		parms[8];	/* additional undefined parameters, */
					/* [0] is .jpg quality: 0..100
					 *     or .exr compression type:
					 *     0=default, 1=none, 2=piz,
					 *     3=zip, 4=rle, 5=pxr24, 6=b44 */
					/* [1] is .pic field: 1=even, 2=odd */
					/* [2] scaling factor for filters */
					/*  -  For multi-buffer formats (EXR)
					 *     store buffertag. */
					/* [3] whether IFF has extra Z. */
					/* [4] DOD tag for IFF */
					/* [5] typemap for EXR */
					/* [6] DPI for IFF, TIF, JPG */
					/* [7] buffer index */
	miImg_type	type;		/* requested miIMG_TYPE_* */
	miImg_format	format;		/* if reading, file format */
	miImg_error	error;		/* one of miIMG_ERR_*, or 0 */
	int		os_error;	/* copy of Unix's errno, or 0 */
					/* --------------- private --------- */
	int		magic;		/* magic number while file is open */
	int		lineno;		/* current line# to be read/written */
	miBoolean	writing;	/* if nz, file is open for writing */
	miCBoolean	swap_map;	/* swap if memory-mapping */
	miUint1		ftype;		/* actual file data type, should     */
					/* be cast to miImg_type. this is    */
					/* set internally in mi_img_create   */
					/* from miImg_file.type              */
	miCBoolean	writable;	/* writable texture (eg. light map) */
	miUint1		pyr_level;	/* open map file, level to rd, 0=std */
	miPointer	fp;		/* open file descriptor, 0 if closed */
	miPointer	real_name;	/* complete path (for unlink/local) */
	miPointer	convline;	/* converted line if type != format */
	miPointer	data;		/* more format-dependent file info*/
					/* or map address for .map files */
	char		name[64];	/* file name (for error messages) */
	miTag		colorprofile;	/* color space of image data */
	miCBoolean	win_error;	/* os_error is GetLastError code */
	miCBoolean	is_texture;	/* image is a texture */
	miPointer	layer_name;	/* EXR: which layer to open */
	miUint1		flags;		/* additional flags */
	miCBoolean	stereo;		/* EXR */
        unsigned long long filesize;    /* if reading, size of file in bytes */
	int		spare[8];	/* makes sizeof(miImg_file) 256 bytes */
} miImg_file;


/*
 * generic scanline and image struct. They are based on index values that
 * define the beginning of component scanlines relative to the beginning of
 * the struct (including header and all). Both miImg_line and miImg_image
 * are actually allocated larger than their size; the component scanlines
 * directly follow the typedef'ed header. One mi_mem_release suffices for
 * the whole thing including data.
 * <comp> in the access macro stands for one of the miIMG_* constants below.
 * Do not use miIMG_LINEACCESS before using miIMG_ACCESS to load local texs!
 */

#define miIMG_R		0		/* red */
#define miIMG_G		1		/* green */
#define miIMG_B		2		/* blue */
#define miIMG_A		3		/* alpha */
#define miIMG_E		3		/* HDR exponent */
#define miIMG_S		miIMG_A		/* scalar */
#define miIMG_U		0		/* u vector */
#define miIMG_V		1		/* v vector */
#define miIMG_Z		0		/* Z coordinate */
#define miIMG_COVERAGE	0		/* coverage fraction scalar */
#define miIMG_T		0		/* material tag */
#define miIMG_NX	0		/* normal vector X component */
#define miIMG_NY	1		/* normal vector Y component */
#define miIMG_NZ	2		/* normal vector Z component */

#define miIMG_ACCESS(_i, _y,_c)\
        ((_i)->cacheable \
         ? ((miUchar *) mi_img_cache_get((_i), (_i)->c[4*(_y)+(_c)]))\
	 : ((miUchar *)(_i) + (_i)->c[4*(_y)+(_c)]))

/* do not use it with "cacheable" images */
#define miIMG_LINEACCESS(_l,_c)	((miUchar *)(_l)+(_l)->c[(_c)])

#define miIMG_DIRSIZE	20		/* image filters have max 20 levels */

struct miImg_image {
    miScalar	filter;		/* filtered lookups if > 0 */
    int		dirsize;	/* valid # of filter levels */
    unsigned long long 	dir[miIMG_DIRSIZE]; /* offs from this to other imgs */
    int		width, height;	/* width and height in pixels */
    int		bits;		/* requested bits per comp, 8/16/32 */
    int		comp;		/* requested components/pixel, 1..4 */
    miUint1	flags;		/* additional flags */
    miUint1	writable;	/* writable texture incl. image format */
    miCBoolean	cacheable;	/* cache in parts */
    miCBoolean	remap;		/* image is remapped */
    int		type;		/* requested miIMG_TYPE_* */
    miTag	real_name;	/* (local) file name to open */
    miTag	colorprofile;	/* color profile for image data */
    /* tile remapping data */
    int	tile_pixels;		/* number of pixels in a full res tile */
    int	n_tiles;		/* redundant to image height */
    int	tile_width;		/* tile width */
    int	tile_height;		/* tile height */
    int	n_horz_tiles;		/* number of tiles in a row */
    int n_vert_tiles;		/* number of tiles in a column */
    int	horz_offset;		/* non-positive full-size tile border*/
    int	vert_offset;		/* non-positive full-size tile border*/
    int	spare[4];		/* future use */

    unsigned long long	c[4];		/*	indexed by miIMG_*; 4*height */
    /*	component indices follow, */
    /*	then component scanlines */
};


typedef struct miImg_tonemap {
	miScalar	ref;		/* referene, adjust units */
	miScalar	tolerance;	/* desired accuracy, about 1% */
	miScalar	low_out;	/* min luminance output device */
	miScalar	hi_out;		/* max luminance output device */
	miScalar	low_in;		/* min input lumin. to consider*/
	miScalar	hi_in;		/* max input lumin. to consider*/
	miColor		lum_weights;	/* luminance weights */
	int		n_bins;		/* number of bins in histogram */
	int		x_res;		/* average over x_res*y_res pixels*/
	int		y_res;
	int		x_lo;		/* restrict to sub-image */
	int		y_lo;		/* lower left corner and */
	int		x_hi;		/* upper right corner */
	int		y_hi;
	miBoolean	linear;	  	/* use simple linear tonemap */
	miBoolean	desaturate;	/* desaturate color components */
	miTag		map;		/* provide your own mapping for */
					/* intensities */
} miImg_tonemap;
miBoolean    	mi_img_create(
				miImg_file *,		/* file descriptor */
				const char *,		/* new file name */
				miImg_type,		/* data type, RGB etc*/
				miImg_format,		/* format, RLA etc */
				int,			/* image width */
				int);			/* image height */
miBoolean    	mi_img_open(
				miImg_file *,		/* file descriptor */
				const char *,		/* file name */
				miImg_type);		/* desired data type */
miBoolean    	mi_img_close(
				miImg_file *);		/* file descriptor */

miBoolean    	mi_img_image_read(
				miImg_file *,		/* file descriptor */
				miImg_image*);		/* frame buffer */

miBoolean    	mi_img_image_write(
				miImg_file *,		/* file descriptor */
				const miImg_image*);	/* frame buffer */
miBoolean	mi_img_tonemap(
				miImg_image*,		/* target image*/
				const miImg_image*,	/* source image*/
				miImg_tonemap*);	/* parameters */

miImg_image 	*mi_img_image_dbcreate(
				miImg_file *,		/* file descriptor */
				miTag *);		/* returned tag in DB*/
miBoolean      	mi_img_placeholder_dbcreate(
				miImg_file *,		/* file struct */
				miTag *,		/* returned tag in DB*/
				miBoolean);		/* local texture? */
miBoolean mi_img_image_shared(
			        miTag,			/* first image tag */
				miTag);			/* second image tag */
void		mi_img_image_release(
				miImg_image *img);	/* file struct */

miUchar     	*mi_img_access(
				miImg_image	*,	/* image to access */
				int,			/* requested scanline*/
				int);			/* req component 0..3*/
miImg_image	*mi_img_image_alloc(
				miImg_file *);		/* file descriptor */
miImg_type	mi_img_type_identify(
				const char *);		/* type, "rgb" etc */
miImg_format	mi_img_format_identify(
				const char *);		/* format, "rla" etc */
miImg_type	mi_img_best_type(
				miImg_format);		/* format to test */
const char	*mi_img_type_name(
				miImg_type);		/* data type to name */
void		mi_img_type_query(
				miImg_type,		/* type to query */
				int *,			/* ret. # of comp */
				int *,			/* ret. # of bits/c */
				miCBoolean *);		/* ret. comp mask.
							 * set to NULL if not
							 * wanted */
const char	*mi_img_format_name(
				miImg_format);		/* format to name */
typedef enum {						/* colorclip modes */
	miIMG_COLORCLIP_RGB,				/* rgb priority */
	miIMG_COLORCLIP_ALPHA,				/* alpha priority */
	miIMG_COLORCLIP_RAW				/* ignore premult */
} miImg_colorclip;
void		mi_img_clip_color(
				const miImg_image *,	/* image to clip for */
				miColor *);		/* color to clip */

void		mi_img_put_color(
				miImg_image *,		/* image to store in */
				const miColor *,	/* color to store */
				int,			/* X coordinate */
				int);			/* Y coordinate */

void		mi_img_put_scalar(
				miImg_image *,		/* image to store in */
				float,			/* scalar to store */
				int,			/* X coordinate */
				int);			/* Y coordinate */
void		mi_img_put_vector(
				miImg_image *,		/* image to store in */
				const miVector *,	/* vector to store */
				int,			/* X coordinate */
				int);			/* Y coordinate */
void		mi_img_put_depth(
				miImg_image *,		/* image to store in */
				float,			/* depth, 0=eye, >=0 */
				int,			/* X coordinate */
				int);			/* Y coordinate */
void		mi_img_put_coverage(
				miImg_image *,		/* image to store in */
				float,			/* 0.0f <= c <= 1.0f */
				int,			/* X coordinate */
				int);			/* Y coordinate */
void		mi_img_put_normal(
				miImg_image *,		/* image to store in */
				const miVector *,	/* normal to store */
				int,			/* X coordinate */
				int);			/* Y coordinate */
void		mi_img_put_label(
				miImg_image *,		/* image to store in */
				miUint,			/* label value */
				int,			/* X coordinate */
				int);			/* Y coordinate */
void		mi_img_get_color(
				const miImg_image *,	/* image to store in */
				miColor *,		/* color to read */
				int,			/* X coordinate */
				int);			/* Y coordinate */
void		mi_img_get_scalar(
				const miImg_image *,	/* image to store in */
				float *,		/* scalar to read */
				int,			/* X coordinate */
				int);			/* Y coordinate */
void		mi_img_get_vector(
				const miImg_image *,	/* image to store in */
				miVector *,		/* vector to read */
				int,			/* X coordinate */
				int);			/* Y coordinate */
void		mi_img_get_depth(
				const miImg_image *,	/* image to store in */
				float *,		/* depth, 0=eye, >=0 */
				int,			/* X coordinate */
				int);			/* Y coordinate */
void		mi_img_get_coverage(
				const miImg_image *,	/* image to store in */
				float *,		/* 0.0f <= c <= 1.0f */
				int,			/* X coordinate */
				int);			/* Y coordinate */
void		mi_img_get_normal(
				const miImg_image *,	/* image to store in */
				miVector *,		/* normal to read */
				int,			/* X coordinate */
				int);			/* Y coordinate */
void		mi_img_get_label(
				const miImg_image *,	/* image to store in */
				miUint *,		/* returned label */
				int,			/* X coordinate */
				int);			/* Y coordinate */
miImg_image	*mi_img_pyramid_get_level(
				miImg_image *,		/* image */
				int);			/* level of pyramid */

int		mi_img_get_width(
				const miImg_image *);	/* image */
int		mi_img_get_height(
				const miImg_image *);	/* image */
void *mi_img_cache_get(
		const miImg_image	*image,		/* cached image */
		unsigned long long	offset);	/* to image->c */

/*-------------------------< dealing with color profiles >----------------*/

miUint1 mi_colorprofile_renderspace_id(void);
miUint1 mi_colorprofile_internalspace_id(void);
miUint1 mi_colorprofile_sourcespace_id(void);
miUint1 mi_colorprofile_ciexyz_color_id(void);

miBoolean mi_colorprofile_ciexyz_to_internal(
		miColor			*c);		/* color to convert */

miBoolean mi_colorprofile_internal_to_ciexyz(
		miColor			*c);		/* color to convert */

miBoolean mi_colorprofile_internal_to_render(
		miColor			*c);		/* color to convert */

miBoolean mi_colorprofile_render_to_internal(
		miColor			*c);		/* color to convert */

miBoolean mi_colorprofile_ciexyz_to_render(
		miColor			*c);		/* color to convert */

miBoolean mi_colorprofile_render_to_ciexyz(
		miColor			*c);		/* color to convert */


/*------------ mi_rclm.h ------------*/

miImg_image	*mi_lightmap_edit(			/* open for writing */
				void **handle,		/* for _edit_end */
				miTag tag);		/* texture tag */
void		mi_lightmap_edit_end(			/* write texture */
				void *handle);		/* from _edit */

/*------------ mi_msg.h ------------*/


/* create and initialize lock*/
miBoolean mi_init_lock(miLock *);

void mi_delete_lock(miLock *); /* destroy and free lock */
void mi_lock(miLock);          /* acquire lock, blocking */
void mi_unlock(miLock);        /* release lock */
miBoolean mi_trylock(miLock);  /* aqcuire lock if available, non-blocking */


/*------------ mi_par.h ------------*/

void mi_abort(void);

int mi_par_aborted(void);

/*------------ mi_rc.h ------------*/

struct miState;
miC_LINKAGE void *mi_renderpass_access(	/* for renderpass merge function */
	struct miState	*state,		/* state->pri is sample set array */
	int		pass,		/* access which pass, -1=output */
	int		fb);		/* frame buffer number */

miC_LINKAGE miBoolean mi_renderpass_resolution(
	int		*xl,		/* returned subpixel coordinates of */
	int		*yl,		/* lower left corner of rectangle */
	int		*xs,		/* returned number of subpixels in */
	int		*ys,		/* the rectangle (containing x/y) */
	int		*xres,		/* returned number of subpixels in */
	int		*yres,		/* the entire frame buffer */
	struct miState	*state,		/* state->cache is sample set array */
	int		x,		/* X subpixel coordinate to look up */
	int		y);		/* Y subpixel coordinate to look up */

miC_LINKAGE miBoolean mi_renderpass_sample_get(
	void		*result,	/* copy data here */
	int		resultsize,	/* number of bytes in *result */
	struct miState	*state,		/* state->cache is sample set array */
	int		fb,		/* frame buffer number */
	int		x,		/* X subpixel coordinate */
	int		y);		/* Y subpixel coordinate */

miC_LINKAGE miBoolean mi_renderpass_sample_put(
	void		*result,	/* data to copy */
	int		resultsize,	/* number of bytes in *result */
	struct miState	*state,		/* state->cache is sample set array */
	int		fb,		/* frame buffer number */
	int		x,		/* X subpixel coordinate */
	int		y);		/* Y subpixel coordinate */

miC_LINKAGE miBoolean mi_renderpass_samplerect_black(
	miBoolean	*result,	/* set this to miTRUE if black */
	struct miState	*state,		/* state->cache is sample set array */
	int		x,		/* X subpixel coordinate */
	int		y);		/* Y subpixel coordinate */

miC_LINKAGE miBoolean mi_renderpass_samplerect_flush(
	struct miState	*state,		/* state->cache is sample set array */
	int		pass,		/* 0=write (put), 1=read (get) */
	int		x,		/* X subpixel coordinate in rect */
	int		y);		/* Y subpixel coordinate in rect */
/*
 * Set the falloff start/stop. If the intersecton point is closer than
 * start, result of the intersection is taken. If it lies between start
 * ebd stop, the result is linearly interpoletad from surface shader and
 * environment shader. If intersection point is behind stop, the environment
 * shader result is taken. Obviously, intersections behind stop may be ignored
 * for optimization.
 */
miC_LINKAGE miBoolean mi_ray_falloff(
	const struct miState	*state,		/* state */
	double			*start,		/* falloff start distance */
	double			*stop);		/* complete falloff */

/*
 * Set the distance to the normal plane under which the intersections
 * would be ignored. The main purpose is to allow rendering of objects
 * with different approximation levels.
 */
miC_LINKAGE miBoolean mi_ray_offset(
	const struct miState	*state,		/* state */
        double			*offset);	/* offset from the surface */

/*
 * Set state primitive
 */

struct miRc_intersection;

miC_LINKAGE void mi_state_set_pri(
	struct miState		*state,		/* state */
	const struct miRc_intersection	*pri,	/* intersected primitive */
	miUint			pri_idx);	/* primitive index */


/*------------ mi_scene.h ------------*/

/*
 * Every DB element managed by SCENE has a unique type and is known by SCENE.
 * mi_db_create should not be used by modules other than SCENE because that
 * makes it hard to properly swap bytes between sane parts of the
 * network and Windows NT.
 * When adding types, change the arrays in scncall1.c!
 */

typedef enum miScene_types {
	miSCENE_NONE = 0,	/* unknown. Danger, Will Robinson. */
	miSCENE_FUNCTION_DECL,	/*  1: miFunction_decl */
	miSCENE_FUNCTION,	/*  2: miFunction */
	miSCENE_MATERIAL,	/*  3: miMaterial */
	miSCENE_LIGHT,		/*  4: miLight */
	miSCENE_CAMERA,		/*  5: miCamera */
	miSCENE_BASIS_LIST,	/*  6: miBasis_list */
	miSCENE_OBJECT,		/*  7: miObject */
	miSCENE_BOX,		/*  8: miGeoBox */
	miSCENE_LINEBOX,	/*  9: miLinebox */
	miSCENE_INSTANCE,	/* 10: miInstance */
	miSCENE_GROUP,		/* 11: miGroup */
	miSCENE_OPTIONS,	/* 12: miOptions */
	miSCENE_IMAGE,		/* 13: image data type */
	miSCENE_POLYGON,	/* 14: miPolygon [] */
	miSCENE_INDEX,		/* 15: miIndex [], used as indices */
	miSCENE_GEOINDEX,	/* 16: miGeoIndex [], used as indices */
	miSCENE_VERTEX,		/* 17: miIndex [], used as vertices */
	miSCENE_GEOVERTEX,	/* 18: miGeoIndex [], used as vertices */
	miSCENE_VECTOR,		/* 19: miVector [] */
	miSCENE_GEOVECTOR,	/* 20: miGeoVector [] */
	miSCENE_FACE,		/* 21: miFace [] */
	miSCENE_SURFACE,	/* 22: miSurface [] */
	miSCENE_CURVE,		/* 23: miCurve [] */
	miSCENE_CURVPNT,	/* 24: miCurve_point [] */
	miSCENE_SCALAR,		/* 25: miScalar [] */
	miSCENE_GEOSCALAR,	/* 26: miGeoScalar [] */
	                        /* 27: unused */
	miSCENE_TAG = 28,	/* 28: miTag [] */
	miSCENE_STRING,		/* 29: char [] */
	miSCENE_SPACECURVE,	/* 30: miSpacecurve [] */
	miSCENE_BOOK,		/* 31: miBook */
	miSCENE_PAGE,		/* 32: miPage */
	miSCENE_SUBDIVSURF,	/* 33: miSurf_subsurf */
	miSCENE_USERDATA,	/* 34: miUserdata */
			        /* 35: unused */
	                        /* 36: unused */
	                    	/* 37: unused */
	              		/* 38: unused */
	                        /* 39: unused */
	miSCENE_NBOX = 40,	/* 40: new miBox, replaces miGeoBox/miSCENE_BOX*/
	miSCENE_LOCAL,		/* 41: byte[], host-local unswappable data */
	miSCENE_SPLITOBJECT,    /* 42: miSplit_object */
	miSCENE_INDEXRANGE, 	/* 43: miIndex_range */
        miSCENE_LIGHTPROFILE,   /* 44: light profiles*/
	                        /* 45: unused */
	miSCENE_LIGHTPROFILE_STD = 46,	/* 46: light profile descr. */
        miSCENE_APPROX_LIST,    /* 47:miApprox array*/
	                        /* 48: unused */
	miSCENE_FBINFO = 49,	/* 49: frame buffer information */
	miSCENE_COLORPROFILE,	/* 50: support color profiles */
	miSCENE_SPECTRUM,	/* 51: support light spectra */
	             		/* 52: unused */
	miSCENE_FLIST = 53,	/* 53: face list */
	miSCENE_ASSEMBLY,	/* 54: assembly */
	miSCENE_MAP_DECL,	/* 55: miMap_decl */
	miSCENE_METASL,		/* 56: metasl code */
	miSCENE_PHEN_EXTDINFO,	/* 57: extended phen data */
                                /* 58--62: unused */
        miSCENE_NEURAY = 63,	/* 63: generic neuray type */
	miSCENE_NTYPES = 64	/* user defs start with this index */

} miScene_types;


/*------------ mi_scene_db.h ------------*/

enum miApprox_method {
	miAPPROX_PARAMETRIC,
	miAPPROX_REGULAR,
	miAPPROX_SPATIAL,
	miAPPROX_CURVATURE,
	miAPPROX_LDA,
	miAPPROX_ADJACENCY,		/* only for curves		     */
	miAPPROX_DEFTRIM,		/* only for miFace def_trim_approx   */
	miAPPROX_REGULAR_PERCENT,	/* new in 3.2, regular param n% m%   */
	miAPPROX_INDIRECT,		/* in which case		     */
					/* cnst[miCNST_VISIBLE] 	     */
					/* cnst[miCNST_SHADOW] ...	     */
					/* are offsets into approx list      */
	miAPPROX_NMETHODS
};

enum miApprox_style {
	miAPPROX_STYLE_NONE = 0,	/* must be 0 for miOptions default */
	miAPPROX_STYLE_GRID,		/* (0 means don't override) */
	miAPPROX_STYLE_TREE,
	miAPPROX_STYLE_DELAUNAY,
	miAPPROX_STYLE_FINE,		/* sub-object/subpixel tessellation */
        miAPPROX_STYLE_FINE_NO_SMOOTHING,/* fine poly displacement without
                                            Hermite interpolation */
        miAPPROX_STYLE_FINE_CONT_DISP,  /* fine poly displacement which is
                                           continuous at unshared vertices */
        miAPPROX_STYLE_FINE_NO_SMOOTHING_CONT_DISP,
                                        /* combination of the above two */
	miAPPROX_NSTYLES
};

#define miCNST_UPARAM	  0		/* regular/parametric only */
#define miCNST_VPARAM	  1
#define miCNST_LENGTH	  0		/* curvature/spatial only  */
#define miCNST_DISTANCE   1
#define miCNST_ANGLE	  2

enum miCnst_type {
	miCNST_VISIBLE	= 0,		/* for accessing (int)cnst[0] */
	miCNST_TRACE,
	miCNST_SHADOW,
	miCNST_CAUSTIC,
	miCNST_GLOBILLUM,
	miCNST_NTYPES			/* must not be > 7 ! */
};

enum miApprox_flag {
	miAPPROX_FLAG_ANY	= 0,			/* f. all rays (31)  */
	miAPPROX_FLAG_VISIBLE	= 1 << miCNST_VISIBLE,	/* f. 1-gen rays     */
	miAPPROX_FLAG_TRACE	= 1 << miCNST_TRACE,	/* f. trace rays     */
	miAPPROX_FLAG_SHADOW	= 1 << miCNST_SHADOW,	/* f. shadow rays    */
	miAPPROX_FLAG_CAUSTIC	= 1 << miCNST_CAUSTIC,	/* f. caustic rays   */
	miAPPROX_FLAG_GLOBILLUM = 1 << miCNST_GLOBILLUM /* f. globillum rays */
};

typedef struct miApprox {
	miScalar	     cnst[6];	/* indexed with miUPARAM...miANGLE   */
	miUint1 	     sharp;	/* 0=smooth normals, 255=faceted     */
	miUint1 	     flag;	/* vis, trace, shad: miApprox_flag   */
	miCBoolean	     any;	/* stop if any criterion is met      */
	miCBoolean	     view_dep;	/* view dependent ?		     */
	enum miApprox_method method;
	enum miApprox_style  style;
	miUshort	     subdiv[2]; /* recursive subdivision depth	     */
	miGeoIndex	     max;	/* maximum number of triangles	     */
					/* in case of style contour:
					   resolution of sampling grid	     */
	miScalar	     grading;	/* min angle bound for graded meshing*/
        miUint4              spare[2];  /* reserved for future use           */
} miApprox;

#define miAPPROX_MAX_SUBDIV 7
#define miAPPROX_NONE(A) memset(&(A), 0, sizeof(miApprox))
/*: ! this does not specify a valid approximation (tree + parametric) */
#define miAPPROX_DEFAULT(A) do {		 \
	(A).style	  = miAPPROX_STYLE_TREE; \
	(A).method	  = miAPPROX_PARAMETRIC; \
	(A).sharp	  = 0;			 \
	(A).flag	  = miAPPROX_FLAG_ANY;	 \
	(A).any 	  = miFALSE;		 \
	(A).view_dep	  = miFALSE;		 \
	(A).cnst[0]	  = 0.0;		 \
	(A).cnst[1]	  = 0.0;		 \
	(A).cnst[2]	  = 0.0;		 \
	(A).cnst[3]	  = 0.0;		 \
	(A).cnst[4]	  = 0.0;		 \
	(A).cnst[5]	  = 0.0;		 \
	(A).subdiv[miMIN] = 0;			 \
	(A).subdiv[miMAX] = 5;			 \
	(A).max 	  = miHUGE_INT; 	 \
	(A).grading	  = 0.0; } while (0)
#define miAPPROX_FINE_DEFAULT(A) do {		 \
	(A).style	  = miAPPROX_STYLE_FINE; \
	(A).method	  = miAPPROX_LDA;	 \
	(A).sharp	  = 0;			 \
	(A).flag	  = (1<<miCNST_NTYPES)-1;\
	(A).any 	  = miFALSE;		 \
	(A).view_dep	  = miTRUE;		 \
	(A).cnst[0]	  = 0.25;		 \
	(A).cnst[1]	  = 0.0;		 \
	(A).cnst[2]	  = 0.0;		 \
	(A).cnst[3]	  = 0.0;		 \
	(A).cnst[4]	  = 0.0;		 \
	(A).cnst[5]	  = 0.0;		 \
	(A).subdiv[miMIN] = 0;			 \
	(A).subdiv[miMAX] = miAPPROX_MAX_SUBDIV; \
	(A).max 	  = miHUGE_INT; 	 \
	(A).grading	  = 0.0; } while (0)
#define miRC_IMAGE_RGBA 	0		/* standard RGBA color fb */
#define miRC_IMAGE_Z		1		/* standard depth fb */
#define miRC_IMAGE_N		2		/* standard normal-vector fb */
#define miRC_IMAGE_M		3		/* standard motion-vector fb */
#define miRC_IMAGE_TAG		4		/* standard object label fb */
#define miRC_IMAGE_COVERAGE	5		/* coverage framebuffer */
						/* 8-9 virtual frame buffers */
#define miRC_IMAGE_USER		12		/* first user-defined fb */
#define miRC_CLIP_MIN		0.001		/* min near clipping plane */

/* bit definitions for miOptions.diagnostic_mode */
#define miSCENE_DIAG_SAMPLES	1		/* turn on sample view mode */
#define miSCENE_DIAG_PHOTON	6		/* photon 2 bits  */
#define miSCENE_DIAG_PHOTON_D	2		/* photon density  */
#define miSCENE_DIAG_PHOTON_I	4		/* photon irradiance  */
#define miSCENE_DIAG_GRID	24		/* grid 2 bits */
#define miSCENE_DIAG_GRID_O	8		/* object_space_grid*/
#define miSCENE_DIAG_GRID_W	16		/* world_space_grid*/
#define miSCENE_DIAG_GRID_C	24		/* camera_space_grid*/
#define miSCENE_DIAG_BSP_D	32		/* bsp tree depth */
#define miSCENE_DIAG_BSP_L	64		/* bsp tree leaf size */
#define miSCENE_DIAG_BSP	96		/* bsp 2 bits */
#define miSCENE_DIAG_FG 	128		/* final gather */

/* bit definitions for miOptions.motion */
#define miSCENE_MOTION_ON	1		/* motion blur on */
#define miSCENE_MOTION_C_INT	2		/* camera instance interp. */

/* bit definitions for shadowmaps */
#define miSHADOWMAP_MERGE	0x01
#define miSHADOWMAP_TRACE	0x02
#define miSHADOWMAP_CROP	0x04
#define miSHADOWMAP_ONLY	0x08
#define miSHADOWMAP_CAMERA	0x10
#define miSHADOWMAP_DETAIL	0x20
#define miSHADOWMAP_TILE	0x40

/* flag definition for lightmaps */
#define miLIGHTMAP_OFF		0
#define miLIGHTMAP_ON		1
#define miLIGHTMAP_ONLY		2
#define miLIGHTMAP_ANYHOST	4


/*
 * First-hit render types.
 */

#define miRENDER_FH_OFF         0
#define miRENDER_FH_SCANLINE    1
#define miRENDER_FH_RAST        'r'

/*
 * Acceleration types.
 */

#define miRENDER_ACCEL_OFF      0
#define miRENDER_ACCEL_BSP      'b'
#define miRENDER_ACCEL_LARGEBSP 'l'
#define miRENDER_ACCEL_BSP2     'n'
#define miRENDER_ACCEL_BVH      'B'

/*
 * miOptions, the rendering options.
 */

struct miOptions {
	miBoolean	trace;			/* 2nd generation ray trace? */
	int		scanline;		/* one of miRENDER_FH_* */
	miUint		motion; 		/* motion blur? : miFALSE */
	miBoolean	shadow_sort;		/* Obsolete! Do not use */
	miBoolean	preview_mode;		/* for future use */
	int		reflection_depth;	/* refl. trace depth : 1 */
	int		refraction_depth;	/* refr. trace depth : 1 */
	int		trace_depth;		/* refl. + refr. depth : 1 */
	int		min_samples;		/* min. sampling level : -2 */
	int		max_samples;		/* max. sampling level : 0 */
	miColor 	contrast;		/* sampling contrast: .1 */
	miColor 	time_contrast;		/* temporal sampling contrast*/
	miTag		contour_contrast;	/* NULLTAG */
	miTag		contour_store;		/* NULLTAG */
	miBoolean	caustic;		/* enable caustics: miFALSE */
	miBoolean	globillum;		/* enable global il.: miFALSE*/
	int		caustic_accuracy;	/* no. caus. photons in est. */
	float		caustic_radius; 	/* maxdist for caus. photons */
	int		globillum_accuracy;	/* no. glob. photons in est. */
	float		globillum_radius;	/* maxdist for glob. photons */
	float		caustic_filter_const;	/* filter const. for caus. */
	float		filter_size_x;		/* filter size in x : 1.0 */
	float		filter_size_y;		/* filter size in y : 1.0 */
	float		jitter; 		/* sample jittering : 0.0 */
	float		shutter;		/* shutter close time: 0 */
	short		spare8[5];		/* unused */
	miSint1 	def_min_samples;	/* min/max samples for objs */
	miSint1 	def_max_samples;	/* without min/max, -128 127 */
	int		space_max_size; 	/* space subdiv. leaf size: 4*/
	int		space_max_depth;	/* space subdiv. depth : 25*/
	float		shutter_delay;		/* shutter open time: 0 */
	int		no_images;		/* # images : 1 */
	miApprox	approx; 		/* approximation overrides if*/
	miApprox	approx_displace;	/* style != APPROX_STYLE_NONE*/
	miUint		spare1[19];		/* keep ray33 offsets */
	miUint		spare9;		        /* unused */
	miTag		finalgather_file;	/* finalgather map file: 0 */
	miCBoolean	space_shadow_separate;	/* space subdiv shadow struct*/
	miUchar 	finalgather_filter;	/* finalgather ray filter */
	char		rast_collect_rate;	/* rasterizer only: */
						/* samples per pixel dim. */
	char		rast_motion_resample;	/* rasterizer only: # of */
						/* time samples for movng geo*/
	char		use_shadow_maps;	/* 0=off, 1=on, 'o'=opengl*/
						/* bit7: only shmap,no render*/
	miCBoolean	rendering_shadow_maps;	/* Shadow map mode? 0 */
	char		recompute_shadow_maps;	/* 'n'o,'y'es (could be Bool)*/
	char		shadow; 		/* shadow casting? : 1 */
						/* 0 off, 1 on, 'l' sort, */
						/* 's' segments */
	char		caustic_filter; 	/* filter-type */
						/* 'b' box, 'c' cone */
	miCBoolean	finalgather_rebuild;	/* rebuild FG ?: on*/
	char		filter; 		/* sample filter type : 'b' */
						/* 'b' box, 't' triangle, */
						/* 'g' gauss */
	char		acceleration;		/* one of miRENDER_ACCEL_*   */
	char		face;			/* primitive facing: 'a' */
						/* 'f' front, 'b' back, */
						/* 'a' all */
	char		spare10;		/* unused */
						/* 0 off, 'e' even, 'o' odd */
	char		smethod;		/* sampling algorithm: 'q' */
	char		render_space;		/* coordinate space 'o' */
						/* 'o' object space, */
						/* 'c' deprecated, camera space */
	miCBoolean	spare11;		/* unused */
	miCBoolean      spare12;		/* unused */
	miCBoolean	visible_lights; 	/* any visible area lights? */
	miCBoolean	shadow_map_motion;	/* motion blurred shadowmaps?*/
	int		task_size;		/* image task size : 0 */
	miBoolean	strips; 		/* GAP returns triangles in
						 * strips */
	miTag		photonmap_file; 	/* photon map file name */
	miBoolean	photonmap_rebuild;	/* photon map rebuild ? */
	int		photon_reflection_depth;/* photon refl. depth */
	int		photon_refraction_depth;/* photon refr. depth */
	int		photon_trace_depth;	/* total photon trace depth */
	int		space_max_mem;		/* maximum bsp memory (mb):0 */
	miColor		caustic_scale;		/* caustic multiplier */
	miColor		globillum_scale;	/* globillum multiplier */
	miColor		finalgather_scale;	/* finalgather multiplier */
	miColor		finalgather_sec_scale;	/* secondary fg multiplier */
        miUint		spare4;
	miColor		photonvol_scale;	/* photon volume multiplier */
	miUint		spare2[6];		/* unused */
	miUint		spare13;	        /* unused */
	miTag		input_cprof;		/* input color space, default */
	miTag		white_cprof;		/* white adapt. col. space */
	miTag		render_cprof;		/* color profile render space*/
	miTag		fb_dir;			/* frame buffer directory */
	miCBoolean	no_lens;		/* disable lens shaders */
	miCBoolean	no_volume;		/* disable volume shaders */
	miCBoolean	no_geometry;		/* disable geometry shaders */
	miCBoolean	no_displace;		/* disable displace shaders */
	miUint1 	no_output;		/* disable output shaders */
	miCBoolean	no_merge;		/* disable surface merging */
	miUint1 	caustic_flag;		/* def. caustic flag for objs*/
	miUint1 	diagnostic_mode;	/* miSCENE_DIAG_* flags */
	int		photonvol_accuracy;	/* no. vol. photons in est. */
	float		photonvol_radius;	/* maxdist for vol. photons */
	miUint1 	globillum_flag; 	/* def. globil. flag for objs*/
	miCBoolean	samplelock;		/* steady samples?: on */
	miCBoolean	autovolume;		/* internal volumes? */
	miCBoolean	finalgather_view;	/* radii in raster pixels ? */
	miCBoolean	no_hair;		/* disable hair rendering */
	miUint1 	n_motion_vectors;	/* global number of motions */
	miCBoolean	no_pass;		/* disable multipass render */
	miCBoolean	photon_autovolume;	/* autovolume for photons */
	miCBoolean	no_predisplace; 	/* disable displ presampling */
	miUint1 	fg_reflection_depth;	/* finalgather refl. depth */
	miUint1 	fg_refraction_depth;	/* finalgather refr. depth */
	miUint1 	fg_trace_depth; 	/* total fg trace depth */
	float		fg_falloff_start;	/* finalgather falloff start */
	float		fg_falloff_stop;	/* finalgather falloff stop */
	miTag		userdata;		/* optional user data blocks */
	miBoolean	irradiance_particles;	/* irradiance particles on/off */
        miUint4         spare5[23];             /* not used, but keep offsets */
	int		finalgather;		/* 0:off,1:on,'f':fastlookup*/
	int		finalgather_rays;	/* no. rays in final gather */
	float		finalgather_maxradius;	/* maxdist for finalgather */
	float		finalgather_minradius;	/* mindist for finalgather */
	float		diag_photon_density;	/* density for diag */
	float		diag_grid_size; 	/* gridsize for diag */
	miBoolean	desaturate;		/* for IMG: fade to white? */
	miBoolean	dither; 		/* for IMG: LSB dithering? */
	miBoolean	nopremult;		/* for IMG: A < RGB ok? */
	int		colorclip;		/* for IMG: miIMG_COLORCLIP* */
	float		gamma;			/* for IMG: gamma, default 1 */
	miTag		inh_funcdecl;		/* inheritance function */
	miColor 	luminance_weight;	/* weights to calc intensity */
        int		spare0[2];              /* not used */
	miCBoolean	inh_is_traversal;	/* inh_funcdecl is a traver- */
						/* sal, not inheritance, shd */
	miUint1		spare6;			/* not used */
	miUint1 	spare7;			/* not used */
	miUint1 	shadowmap_flags;	/* flag for shadowmaps */
	float		maxdisplace;		/* override if !=0: default 0*/
	miScalar	shadowmap_bias;		/* move shmap Z back by bias */
	miUint1		spare14;		/* unused */
	miCBoolean	photonmap_only;		/* render photon map only */
	miUint1		lightmap;		/* 0=off,1=on,2=only */
	                                        /* 4=use any host (unsafe) */
	miUint1		fg_diffuse_depth;	/* #secondary fg bounces */
	miTag		state_func;		/* allow user to init state */
	float		fg_presamp_density;	/* samples density for precomp.
						 * finalgather points */
	float		rast_shading_samples;	/* shading samples per pixel */
						/* default: 1.0f */
	miUint1		fb_virtual;		/* fb mem management */
						/* 0=none 1=mapped 2=cached */
						/* default: 1 */
	miCBoolean	unified_sampling;	/* is unified sampling on?*/
	miCBoolean	spare3[2];		/* not used */
	miTag		string_options;		/* arbitrary name-value options */

	int		spare[9];		/* not used */
};
typedef enum miCamera_eye {
	miCAMERA_EYE_LEFT	= 0,
	miCAMERA_EYE_CENTER	= 1,
	miCAMERA_EYE_RIGHT	= 2
} miCamera_eye;



typedef enum miCamera_stereo {
	miCAMERA_STEREO_OFF	= 0,
	miCAMERA_STEREO_TOEIN	= 1,
	miCAMERA_STEREO_OFFAXIS	= 2,
	miCAMERA_STEREO_OFFSET	= 3
} miCamera_stereo;


struct miCamera {
	miBoolean	orthographic;		/* orthographic rendering? */
	float		focal;			/* focal length */
	float		aperture;		/* aperture */
	float		aspect; 		/* aspect ratio of the image */
	miRange 	clip;			/* min/max clipping */
	int		x_resolution;		/* x resolution */
	int		y_resolution;		/* y resolution */
	struct {int xl, yl, xh, yh;}
			window; 		/* corners of subwindow */
	miTag		volume; 		/* opt. volume shader */
	miTag		environment;		/* opt. environment shader */
	miTag		lens;			/* opt. lens shader */
	miTag		output; 		/* opt. output shaders/files */
	int		frame;			/* current frame number */
	float		frame_time;		/* ... as time in seconds */
	int		spare2;		        /* unused */
	float		x_offset;		/* x image offset in pixels */
	float		y_offset;		/* y image offset in pixels */
	miTag		userdata;		/* optional user data blocks */
	miTag		pass;			/* opt. pass function chain */
	miUint		spare3[2];		/* unused */
	miBoolean	pass_mask;		/* passes prevent eye rays */
	miTag		buffertag;		/* frame buffer object */
	miCamera_stereo	stereo;			/* stereo rendering method */
	float		eye_separation;		/* left-right eye distance */
	miTag		filter;			/* MI::RC::Pixel_filter*/
	float		parallax_distance;	/* stereo fusion distance */
	int		spare[6];		/* not used */
};

struct miFramebuffer;
enum miLight_type {
	miLIGHT_ORIGIN,
	miLIGHT_DIRECTION,
	miLIGHT_SPOT
};

enum miLight_area {
	/* describe geometry of light source */
	miLIGHT_NONE = 0,
	miLIGHT_RECTANGLE,
	miLIGHT_DISC,
	miLIGHT_SPHERE,
	miLIGHT_CYLINDER,
	miLIGHT_OBJECT,
	miLIGHT_USER
};
enum miFunction_type {
	miFUNCTION_C,				/* regular C/C++ shader */
	miFUNCTION_PHEN,			/* phenomenon interface */
	miFUNCTION_C_REQ,			/* C/C++ shader with reqmnts */
	miFUNCTION_OUTFILE,			/* write an image to a file */
	miFUNCTION_DATA,			/* user data decl, no miFunc */
	miFUNCTION_PASS_SAVE,			/* write pass file */
	miFUNCTION_PASS_PREP,			/* pass file preprocessor */
	miFUNCTION_PASS_MERGE,			/* pass file merge function */
	miFUNCTION_PASS_DELETE 			/* pass file delete */
};

typedef struct miFunction {
	miPointer	sparep1[7];
	enum miFunction_type type;		/* C/C++, phenomenon, or file*/
	miUint		out_typemap;		/* if output, IMG_TYPE bitmap*/
	miUint		out_interpmap;		/* if output, interpolate bm */
	miTag		function_decl;		/* declaration if C or PHEN */
	miTag		next_function;		/* next function call in list*/
	miTag		parameter_indirect;	/* get params from this func */
	miTag		interfacephen;		/* parent phen, if any */
	miBoolean	spare0; 		/* not used */
	int		parameter_size; 	/* size of parameter block */
	int		result_size;		/* size of result struct */
	int		ghost_offs;		/* offset to tag ghost, or 0 */
	miTag		pass_read;		/* pass: infile, infile list */
	miTag		pass_write;		/* pass: outfile or 0 */
	miSint1 	pass_maxsamples;	/* pass: max samples or ~0 */
	miCBoolean	has_connections;	/* at least one parameter has a
						   connection.
						   if (func->has_connections)
						   replaces if (func->ghost_offs)
						   as a check for connections,
						   because ghost_offs != 0 for
						   anything but defaults. */
	miCBoolean	spare2[2];		/* not used */
	miCBoolean	no_expl_params; 	/* candidate for indirect par*/
	miCBoolean	spare3[6];		/* not used */
	miUchar 	label;			/* sequential # for bitmasks */
	char		parameters[8];		/* parameter block, then */
						/* miTag ghost for phenomena */
} miFunction;
typedef struct miUserdata {
	miTag		data_decl;		/* parameter declaration */
	miTag		next_data;		/* next data block in list */
	miUint		label;			/* data label */
	int		parameter_size; 	/* size of parameter block */
	short		one;			/* ==1, for byte order check */
	short		spare1; 		/* not used */
	int		spare2; 		/* not used */
	char		parameters[8];		/* parameter block */
} miUserdata;

/*------------ mi_state.h ------------*/

typedef void miMsl_state;

#define MAX_TEX 	64	/* max. number of texture spaces */
#define NO_DERIVS	5	/* number of surface derivatives */


/*
 * Enumeration of all types of rays to be traced
 * DO NOT renumber the flags, or precompiled shaders may stop working!
 * volume shaders can find out from state->type whether this ray came
 * from an object or from a light source. Note that in 3.0, mi_trace_probe
 * used miRAY_NONE and hence ignored non-trace objects. Changed in 3.1.2.
 */

typedef enum miRay_type {
	miRAY_EYE,			/* eye ray */
	miRAY_TRANSPARENT,		/* transparency ray */
	miRAY_REFLECT,			/* reflection ray */
	miRAY_REFRACT,			/* refraction ray */
	miRAY_LIGHT,			/* light ray */
	miRAY_SHADOW,			/* shadow ray */
	miRAY_ENVIRONMENT,		/* ray only into environment/volume */
	miRAY_NONE,			/* other ray */
	miPHOTON_ABSORB,		/* photon is absorbed (RIP) */
	miPHOTON_LIGHT, 		/* photon emitted from a light source*/
	miPHOTON_REFLECT_SPECULAR,	/* specular reflection of a photon */
	miPHOTON_REFLECT_GLOSSY,	/* glossy reflection of a photon */
	miPHOTON_REFLECT_DIFFUSE,	/* diffuse reflection of a photon */
	miPHOTON_TRANSMIT_SPECULAR,	/* specular transmission of a photon */
	miPHOTON_TRANSMIT_GLOSSY,	/* glossy transmission of a photon */
	miPHOTON_TRANSMIT_DIFFUSE,	/* diffuse transmission of a photon */
	miRAY_DISPLACE, 		/* displacement during tessellation */
	miRAY_OUTPUT,			/* output shader */
	miPHOTON_SCATTER_VOLUME,	/* volume scattering of a photon */
	miPHOTON_TRANSPARENT,		/* transparency photon */
	miRAY_FINALGATHER,		/* final gather ray */
	miRAY_LM_VERTEX,		/* light map vertex rendering */
	miRAY_LM_MESH,			/* light map mesh rendering */
	miPHOTON_EMIT_GLOBILLUM,	/* globillum photons (emitters only) */
	miPHOTON_EMIT_CAUSTIC,		/* caustic photons (emitters only) */
	miRAY_PROBE,			/* mi_trace_probe, ignores vis/trace */
	miRAY_HULL,			/* hull ray */
	miPHOTON_HULL,			/* photon hull ray */
	miRAY_NO_TYPES
} miRay_type;


/*
 *
 * Defines interaction of object with different kinds of ray.
 *
 */

typedef enum miTrace_flag {
	miTRACE_FLAG_VISIBLE	    = 1u << 0,	/* 'visible'			*/
	miTRACE_FLAG_SHADOW_CAST    = 1u << 1,	/* cast shadow rays		*/
	miTRACE_FLAG_SHADOW_RECV    = 1u << 2,	/* receive shadow rays		*/
	miTRACE_FLAG_REFLECT_CAST   = 1u << 3,	/* cast reflection rays		*/
	miTRACE_FLAG_REFLECT_RECV   = 1u << 4,	/* receive reflection rays	*/
	miTRACE_FLAG_REFRACT_CAST   = 1u << 5,	/* cast refraction rays		*/
	miTRACE_FLAG_REFRACT_RECV   = 1u << 6,	/* receive refraction rays	*/
	miTRACE_FLAG_TRANSP_CAST    = 1u << 7,	/* cast transparency rays	*/
	miTRACE_FLAG_TRANSP_RECV    = 1u << 8,	/* receive transparency rays	*/
	miTRACE_FLAG_CAUSTIC	    = 1u << 9,	/* interact with caustic photon	*/
	miTRACE_FLAG_GLOBILLUM	    = 1u << 10,	/* interact with glob. photon	*/
	miTRACE_FLAG_FINALGATHER    = 1u << 11	/* interact with final gather	*/
} miTrace_flag;


/*
 * Determine if a ray given by miRay_type is an eye or first generation
 * transparency ray (primary), or a reflection or refraction (secondary) ray.
 */

#define miRAY_PRIMARY(r)	((r) == miRAY_EYE)
#define miRAY_SECONDARY(r)	(((r) >	miRAY_EYE &&\
				  (r) <	miPHOTON_ABSORB)  ||\
				 (r) == miRAY_FINALGATHER ||\
				 (r) == miRAY_HULL)

/*
 * Determine if ray is a photon
 */

#define miRAY_PHOTON(r) 	(((r) >= miPHOTON_ABSORB &&\
				 (r) <= miPHOTON_TRANSMIT_DIFFUSE) ||\
				 ((r) >= miPHOTON_SCATTER_VOLUME &&\
				  (r) <= miPHOTON_TRANSPARENT) ||\
				 ((r) >= miPHOTON_EMIT_GLOBILLUM &&\
				  (r) <= miPHOTON_EMIT_CAUSTIC) ||\
				  (r) == miPHOTON_HULL)
/*
 * Virtual frame buffers numbers.  Used exclusively by pass filters.
 * to access sample information that is not written to files.
 */

#define miVFB_FIRST		8
#define miVFB_SAMPLE_TIME	8	/* time when sample was shot */
#define miVFB_SAMPLE_LIMITS	9	/* per object sample limits */
#define miVFB_TOTAL		9

/*
 * Types of shaders
 */

typedef enum miShader_type {
	miSHADER_LENS,		/* lens shader */
	miSHADER_MATERIAL,	/* material shader */
	miSHADER_LIGHT, 	/* light shader */
	miSHADER_SHADOW,	/* shadow shader */
	miSHADER_ENVIRONMENT,	/* environment shader */
	miSHADER_VOLUME,	/* volume shader */
	miSHADER_TEXTURE,	/* texture shader */
	miSHADER_PHOTON,	/* forward shader */
	miSHADER_GEOMETRY,	/* geometry shader */
	miSHADER_DISPLACE,	/* displacement shader */
	miSHADER_PHOTON_EMITTER,/* photon emitter */
	miSHADER_OUTPUT,	/* output shader */
	miSHADER_OTHER, 	/* shader not known by RC */
	miSHADER_LIGHTMAP,	/* lightmap shader */
	miSHADER_PHOTONVOL,	/* photon volume shader */
	miSHADER_STATE,    	/* allow user to set-up state */
        miSHADER_CONTOUR,       /* contour shader */
	miSHADER_NO_TYPES
} miShader_type;

/* assure no padding for 8-byte alignment on macosx. */
#if defined(__GNUC__) && (defined(__APPLE_CPP__)     ||  \
                          defined(__APPLE_CC__)      ||  \
                          defined(__MACOS_CLASSIC__))
#define MC_PACK __attribute__((packed))
#else
#define MC_PACK
#endif

struct miRc_intersection;

/*
 * State structure
 */

#define MI_STATE_VERSION 2

struct miState {
					/* global */
	int		version;		/* version of state struct,
						 * and shader interface
						 * currently 2 */
	miTag		camera_inst;		/* camera instance */
	const struct miCamera 	*camera;	/* camera */
	const struct miOptions 	*options;	/* options */
	miLock		global_lock;		/* global lock for shaders */
	miUint		qmc_instance;		/* instance of low discrepancy
						 * vector associated to current
						 * ray tree */
#ifdef BIT64
	miUint		pad;
#endif
	struct miTs	*ts;			/* thread local storage (ts) */
						/* (internal) */
	float		raster_x;		/* x in raster space */
	float		raster_y;		/* y in raster space */
					/* ray */
	struct miState	*parent;		/* state of parent ray
						 * first eye ray/lens shader:
						 *   NULL
						 * subsequent eye rays/lens
						 * shaders: previous one
						 * reflection, refraction,
						 * dissolve rays: parent ray
						 * light rays: parent ray
						 * shadow rays: light ray */
	miRay_type	type;			/* type of the ray */
	miUchar 	qmc_component;		/* next component of current
						 * instance of low discrepancy
						 * vector to be used */
	miUint1 	scanline;		/* intersect ray by scanline?*/
	miCBoolean	inv_normal;		/* normals are inverted because
						 * ray hit the back side */
	char		face;			/* f)ront, b)ack, a)ll, from
						 * state->options for subrays*/
	miMsl_state	*msl_state;		/* MetaSL companion state */
	void		*spare; 		/* unused */
	int		reflection_level;	/* reflection depth of the ray
						 * SHOULD BE SHORT
						 */
	int		refraction_level;	/* refraction depth of the ray
						 * SHOULD BE SHORT
						 */
	miVector	org;			/* ray origin
						 * for light, shadow rays the
						 * light position */
	miVector	dir;			/* ray direction
						 * for light, shadow ray
						 * it points
						 * towards the intersection */
	double		dist MC_PACK;		/* length of the ray */
	float		time;			/* time of the ray */
	miScalar	ior;			/* ior of outgoing ray */
	miScalar	ior_in; 		/* ior of incoming ray */
	miTag		material;		/* material of the primitive.
						 * Set to miNULL_TAG if no hit.
						 */
	miTag		volume; 		/* volume shader to be applied
						 */
	miTag		environment;		/* environment shader to be
						 * applied if no hit */
					/* intersection point */
	miTag		refraction_volume;	/* volume shader to apply
						 * to refraction ray */
	miUint		label;			/* label of hit object */
	miTag		instance;		/* hit object instance */
	miTag		light_instance; 	/* light instance */

	struct miRc_intersection * pri;		/* intersection or 0 if none */

	float		importance;		/* current ray importance factor */
	float		bary[4];		/* barycentric coordinates
						 * of hit primitive
						 * triangles: 0 - 2 */
	miVector	point;			/* point of intersection */
	miVector	normal; 		/* interpolated normal
						 * pointing to the side of the
						 * ray */
	miVector	normal_geom;		/* geometric normal of pri.
						 * pointing to the side of the
						 * ray */
	miScalar	dot_nd; 		/* dot of normal, dir
						 * for light rays,
						 * it's the dot_nd of the
						 * parent (intersection) normal
						 * and the light ray dir */
	double		shadow_tol MC_PACK;	/* the minimum distance to a
						 * plane perpendicular to the
						 * shading normal for which the
						 * triangle is completely on
						 * the negative side.  */
	miVector	*tex_list;		/* list of texture coordinates
						 */
	miVector	*bump_x_list;		/* list of bump map basis x
						 * (perturbation) vectors */
	miVector	*bump_y_list;		/* list of bump map basis y
						 * (perturbation) vectors */
	miVector	motion; 		/* motion vector or (0,0,0) */
	miVector	*derivs;		/* list of surface derivative
						 * vectors containing dx/du,
						 * dx/dv, d^2x/du^2, d^2x/dv^2,
						 * d^2x/dudv or (0,0,0) */
					/* light shader, shadow shader */
						/* instance is the
						 * light instance, see above */
					/* texture shader */
	miVector	tex;			/* texture coordinates for
						 * lookup */
					/* shader */
	const struct miFunction *shader;	/* current shader */
					/* other */
	struct miState	*child; 		/* child state */
	short		thread; 		/* current thread number */
	miUshort	count;			/* area light sample counter */
					/* user */
	void		*user;			/* user data */
	int		user_size;		/* size of user data */
};


/*------------ mi_shader.h ------------*/

/*
 * state structure passed to old-style output shaders. It is used for
 * output shaders whose declaration does not specify a version number.
 * Do not use this. Output shaders with nonzero version numbers get
 * a miState, not a miOutstate, and work with versioning and init/exit.
 */

#define MI_OUTSTATE_VERSION 2

typedef struct miOutstate {			/* state for output shaders */
        int		version;		/* version of miOutstate */
        miTag		camera_inst;		/* camera instance */
        const struct miCamera  *camera;		/* camera */
        const struct miOptions *options;	/* options */
        int		xres, yres;		/* image resolution */
        miImg_image	*frame_rgba;		/* RGBA color frame buffer */
        miImg_image	*frame_z;		/* depth channel frame buffer*/
        miImg_image	*frame_n;		/* normal vector frame buffer*/
        miImg_image	*frame_label;		/* label channel frame buffer*/
        miMatrix	camera_to_world;	/* world transformation */
        miMatrix	world_to_camera;	/* inverse world transform */
        miImg_image	*frame_m;		/* motion vector frame buffer*/
} miOutstate;


/* state setup shader */
typedef miBoolean (*miShader_state)(
                miState		*state,
                void		*args);

typedef void (*miContour_Store_Function)(
                void		*info_void,
                int		*info_size,
                miState		*state,
                miColor		*color);

typedef miBoolean (*miContour_Contrast_Function)(
                void		*info1,
                void		*info2,
                int		level,
                miState		*state,
                void		*paras);

struct miContour_endpoint;			/* typedef'd later */

typedef miBoolean (*miContour_Shader)(
                struct miContour_endpoint *epoint,
                void		*info_near,
                void		*info_far,
                miState		*state,
                void		*paras);


/* Typedefs for lightmapping shaders */
typedef struct miRclm_triangle {
                miInteger	a;
                miInteger	b;
                miInteger	c;
                miGeoIndex	pri_idx;
} miRclm_triangle;

typedef struct miRclm_mesh_render {
                struct miRc_intersection *pri;
                int			no_triangles;
                miRclm_triangle const	*triangles;
                void const		*vertex_data;
} miRclm_mesh_render;


/*
 * functions
 */

/** Checks if the miTag t is a non-shader/non-interface tag. */
#define mi_is_nonshader_tag(t) ((t)==miNULLTAG || (t)==miPARAMTAG)

/** Checks if the current shader of miState s has ghosts. */
#define mi_has_ghosts(s) (0!=(s)->shader->ghost_offs)

/** Checks if the current shader of miState s has connections */
#define mi_has_connections(s) (miTRUE==(s)->shader->has_connections)

/** Gets the ghost tag for parameter p of the current shader of miState s.
 * This assumes that mi_has_ghosts(s) is true.
 */
#define mi_get_ghost(s, p) (*((miTag*)((char*)(p)+(s)->shader->ghost_offs)))

/** Checks if the parameter p of the current shader of miState s is connected
 * to a shader.
 */
#define mi_is_connected(s, p) \
       (mi_has_connections(s) \
    && (!mi_is_nonshader_tag(mi_get_ghost((s),(p)))))

/** Checks if the parameter p of the current shader of miState s is connected
 * to a shader or set directly. This means that p is default if
 * mi_is_set(s,p)==miFALSE.
 */
#define mi_is_set(s, p) \
    (mi_has_ghosts(s) && miNULLTAG!=mi_get_ghost((s),(p)))

#define mi_eval(s, p) \
    (!mi_is_connected((s),(p)) ? (void*)(p) : \
    mi_phen_eval((s),(void*)(p)))

/* Like mi_eval except that mi_is_set is assumed to be true */
#define mi_eval_set(s, p) \
    (miPARAMTAG==mi_get_ghost((s),(p)) ? (void*)(p) : \
    mi_phen_eval((s),(void*)(p)))

#define mi_eval_boolean(p)	((miBoolean *)mi_eval(state, (p)))
#define mi_eval_integer(p)	((miInteger *)mi_eval(state, (p)))
#define mi_eval_scalar(p)	((miScalar  *)mi_eval(state, (p)))
#define mi_eval_vector(p)	((miVector  *)mi_eval(state, (p)))
#define mi_eval_transform(p)	((miScalar  *)mi_eval(state, (p)))
#define mi_eval_color(p)	((miColor   *)mi_eval(state, (p)))
#define mi_eval_tag(p)		((miTag     *)mi_eval(state, (p)))
#define mi_eval_spectrum(p)     \
    mi_spectrum_ensure((miSpectrum*)mi_eval(state, (p)))

#define mi_call( s, p ) \
    (!mi_is_connected((s), (p)) ? (void*)(p) : \
    mi_phen_call(s,(void*)(p)))

#define mi_call_boolean(p)	((miBoolean *)mi_call(state, (p)))
#define mi_call_integer(p)	((miInteger *)mi_call(state, (p)))
#define mi_call_scalar(p)	((miScalar  *)mi_call(state, (p)))
#define mi_call_vector(p)	((miVector  *)mi_call(state, (p)))
#define mi_call_transform(p)	((miScalar  *)mi_call(state, (p)))
#define mi_call_color(p)	((miColor   *)mi_call(state, (p)))
#define mi_call_tag(p)		((miTag     *)mi_call(state, (p)))


miBoolean mi_call_shader(
                miColor 	*result,	/* result */
                miShader_type	type,		/* shader type */
                miState 	*state, 	/* state */
                miTag		shader);	/* shader function instance */
miBoolean mi_call_shader_x(
                miColor 	*result,	/* result */
                miShader_type	type,		/* shader type */
                miState 	*state, 	/* state */
                miTag		shader, 	/* shader function instance */
                void		*arg);		/* pass to shader */
void mi_flush_cache(
                miState *state );		/* the famous state */
miBoolean mi_call_material(			/* for smart volume shaders */
                miColor 	*result,	/* material shader result */
                miState 	*state);	/* state with state->material*/
miBoolean mi_call_photon_material(		/* for photon volume shaders */
                miColor 	*energy,	/* energy (surprise!) */
                miState 	*state);	/* state with state->material*/
miBoolean mi_call_shadow_material(		/* for shadow shaders */
                miColor 	*result,	/* result */
                miState 	*state);	/* state with state->material*/
miBoolean mi_call_environment_material(		/* for environment shaders */
                miColor 	*result,	/* result */
                miState 	*state);	/* state with state->material*/
miBoolean mi_call_volume_material(		/* for volume shaders */
                miColor 	*result,	/* result */
                miState 	*state);	/* state with state->material*/
miBoolean mi_call_photonvol_material(		/* for photon volume shaders */
                miColor 	*result,	/* result */
                miState 	*state);	/* state with state->material*/
miBoolean mi_call_contour_material(		/* for contour shaders */
                struct miContour_endpoint* result,  /* contour result */
                void		*info_near,     /* near info */
                void            *info_far,      /* far info */
                miState         *state);        /* state with state->material*/
void *mi_phen_eval(				/* evaluate a shader param */
                miState		*state, 	/* state */
                void		*parm );	/* parameter */
void *mi_phen_call(				/* re-evaluate a shader param */
                miState		*state, 	/* state */
                void		*parm );	/* parameter */
miBoolean mi_lookup_color_texture(
                miColor* 	color,		/* returned color */
                miState* 	state,
                miTag		tex,		/* texture to look up */
                miVector* 	coord);		/* texture coordinate */
miBoolean mi_lookup_scalar_texture(
                miScalar* 	scalar,		/* returned scalar */
                miState* 	state,
                miTag		tex,		/* texture to look up */
                miVector* 	coord);		/* texture coordinate */
miBoolean mi_lookup_vector_texture(
                miVector*	rvector,	/* returned vector */
                miState* 	state,
                miTag		tex,		/* texture to look up */
                miVector* 	coord);		/* texture coordinate */
miBoolean mi_lookup_color_texture_x(
                miColor* 	color,		/* returned color */
                miState* 	state,
                miTag		tex,		/* texture to look up */
                miVector* 	coord,		/* texture coordinate */
                miScalar	filter);	/* filter for lookup */
miBoolean mi_lookup_scalar_texture_x(
                miScalar* 	scalar,		/* returned scalar */
                miState* 	state,
                miTag		tex,		/* texture to look up */
                miVector* 	coord,		/* texture coordinate */
                miScalar	filter);	/* filter for lookup */
miBoolean mi_lookup_vector_texture_x(
                miVector*	rvector,	/* returned vector */
                miState* 	state,
                miTag		tex,		/* texture to look up */
                miVector* 	coord,		/* texture coordinate */
                miScalar	filter);	/* filter for lookup */


/*
 * texture filtering
 */

typedef struct miTexfilter {
                miScalar	eccmax; 	/* max. eccentricity */
                miScalar	max_minor;	/* max. minor axis length */
                miScalar	circle_radius;	/* scale blurring */
                miBoolean	bilinear;	/* bilin. subpixel interp. */
                miScalar	spare[10];	/* not used */
} miTexfilter;

miBoolean mi_lookup_filter_color_texture(
                miColor *	color,		/* returned color */
                miState *	state,
                miTag		tex,		/* texture to look up */
                miTexfilter *	paras,		/* filter options */
                miMatrix	p2t);		/* pixel->texture transform */

miBoolean mi_lookup_filter_color_texture_x(
                miColor	* 	color,		/* returned color */
                miState	* 	state,
                miTag		tex,		/* texture image to look up */
                miTexfilter *	paras,		/* filter options */
                miMatrix	p2t,		/* pixel->texture transform */
                miScalar	filter);	/* the filter value to use */

miBoolean mi_texture_filter_project(
                miVector	p[3],		/* pixel space points */
                miVector	t[3],		/* texture space points */
                miState *	state,
                miScalar	disc_r, 	/* projection disc radius */
                miUint		space); 	/* texture space index */

miBoolean mi_texture_filter_transform(
                miMatrix	ST,		/* screen->texture transform */
                miVector	p[3],		/* pixel space points */
                miVector	t[3]);		/* texture space points */

/* info functions */
void	  mi_texture_info(
                const miTag	tag,		/* texture to inquire about */
                int * const	xresp,		/* store width here */
                int * const	yresp,		/* store height here */
                void ** const	paraspp);	/* store ptr to tex paras */
void	  mi_light_info(
                const miTag	tag,		/* light to inquire about */
                miVector *const orgp,		/* store origin here */
                miVector *const dirp,		/* store direction here */
                void ** const	paraspp);	/* store ptr to light paras 0*/
int	  mi_global_lights_info(
                miTag		**tag); 	/* array of light leaf insts */
void	**mi_shader_info(
                miState * const state); 	/* state with shader */
int	  mi_instance_info(
                const miTag	inst_tag,	/* instance tag */
                void ** const	paraspp,	/* store ptr to inst paras */
                void ** const	spare1, 	/* not currently used */
                void ** const	spare2, 	/* not currently used */
                void ** const	spare3);	/* not currently used */

miBoolean mi_inclusive_lightlist(
                int		*n_lights,	/* number of lights */
                miTag		**lights,	/* lightlist (array of tags) */
                miState 	*state);	/* state */
miBoolean mi_exclusive_lightlist(
                int		*n_lights,	/* number of lights */
                miTag		**lights,	/* lightlist (array of tags) */
                miState 	*state);	/* state */
miBoolean mi_expand_lightlist(
                int		*n_lights,	/* number of lights */
                miTag		**lights,	/* lightlist (array of tags) */
                miState		*state);	/* state */
miBoolean mi_instance_lightlist(
                int		*n_lights,	/* number of inst. lights */
                miTag		**lights,	/* inst. light list */
                miState		*state);	/* the state */

miBoolean mi_tri_vectors(
                miState 	*state,
                int		which,		/* point, normal, motion, tex*/
                int		ntex,		/* if which==t, which texture*/
                const miVector	**a,		/* returned vectors */
                const miVector	**b,
                const miVector	**c);

miBoolean mi_texture_interpolate(
                miState		*state,		/* current state */
                miUint		space,		/* texture space index */
                miScalar	*result);	/* interpolated coordinate */

miBoolean mi_raster_unit(
                miState 	*state, 	/* shader state with camera */
                miVector	*x,		/* ret. X unit basis vector */
                miVector	*y);		/* ret. Y unit basis vector */

miImg_image * mi_output_image_open(
                miState 	*state, 	/* shader state with camera */
                miUint		idx);		/* output image index */

void mi_output_image_close(
                miState 	*state, 	/* shader state with camera */
                miUint		idx);		/* output image index */

/* autovolume functions */
miInteger mi_volume_num_shaders(
                miState 	*state);	/* state */
miInteger mi_volume_cur_shader(
                miState 	*state);	/* state */
miColor *mi_volume_user_color(
                miState 	*state);	/* state */
miTag const *mi_volume_tags(
                miState 	*state);	/* state */
miTag const *mi_volume_instances(
                miState 	*state);	/* state */

/* ray tracing functions */
miBoolean mi_trace_eye(
                miColor 	*result,	/* result */
                miState 	*state, 	/* state */
                const miVector	*origin,	/* ray origin */
                const miVector	*direction);	/* ray direction */
miBoolean mi_trace_transparent(
                miColor 	*result,	/* result */
                miState 	*state);	/* state */
miBoolean mi_trace_reflection(
                miColor 	*result,	/* result */
                miState 	*state, 	/* state */
                const miVector	*direction);	/* ray direction */
miBoolean mi_trace_refraction(
                miColor 	*result,	/* result */
                miState 	*state, 	/* state */
                const miVector	*direction);	/* ray direction */
miBoolean mi_trace_environment(
                miColor 	*result,	/* result */
                miState 	*state, 	/* state */
                const miVector	*direction);	/* direction */
miBoolean mi_trace_probe(
                miState 	*state, 	/* state */
                const miVector  *direction,	/* direction */
                const miVector 	*origin);	/* origin */
miBoolean mi_trace_probe_x(
                miState 	*state, 	/* state */
                const miVector  *direction,	/* direction */
                const miVector 	*origin,	/* origin */
                miUint		flag );		/* intersection flag */
miBoolean mi_trace_continue(
                miColor 	*result,	/* result */
                miState 	*state);	/* state */
miBoolean mi_sample_light(
                miColor 	*result, 	/* result */
                miVector 	*dir,		/* opt. result direction */
                float 		*dot_nl, 	/* opt. result dot of N, L */
                miState 	*state,		/* state */
                miTag	 	light_inst,	/* light instance */
                int 		*samples);	/* # samples */
miBoolean mi_trace_light(
                miColor 	*result,	/* result */
                miVector	*dir,		/* opt. result direction */
                float		*dot_nl,	/* opt. result dot of N, L */
                miState 	*state, 	/* state */
                miTag		light_inst);	/* light instance */
miBoolean mi_trace_shadow(
                miColor 	*result, 	/* result */
                miState 	*state); 	/* state */
miBoolean mi_trace_shadow_seg(
                miColor 	*result, 	/* result */
                miState 	*state); 	/* state */
miBoolean mi_continue_shadow_seg(
                miColor		*result, 	/* result */
                miState 	*state); 	/* state */

/* set opacity color. mental ray will use the last value set. note
   that if opacity is not set, alpha is assumed to hold the opacity. */
void mi_opacity_set(
                miState 	*state, 	/* shader state */
                const miColor  	*opacity); 	/* opacity to store */

/* get opacity colour. return miBoolean is miTRUE
   if it was previously set, otherwise miFALSE. */
miBoolean mi_opacity_get(
                miState 	*state, 	/* shader state */
                miColor 	*opacity);	/* where to store opacity */

/* compute reflection / transmission directions */
void mi_reflection_dir(
                miVector	*dir,		/* in direction */
                miState 	*state);	/* state */
miBoolean mi_refraction_dir(
                miVector	*dir,		/* in direction */
                miState 	*state, 	/* state */
                miScalar	ior_in, 	/* in index of refraction */
                miScalar	ior_out);	/* out index of refraction */
void mi_reflection_dir_specular(	/* same as mi_reflection_dir */
                miVector	*dir,		/* in direction */
                miState 	*state);	/* state */
void mi_reflection_dir_glossy(
                miVector	*dir,		/* out direction */
                miState 	*state, 	/* state */
                miScalar	shiny); 	/* shiny coefficient */
void mi_reflection_dir_glossy_x(
                miVector	*dir,		/* out direction */
                miState 	*state, 	/* state */
                miScalar	shiny, 		/* shiny coefficient */
                const  double	sample[2]);	/* 2-dim sample to use */
void mi_reflection_dir_anisglossy(
                miVector	*dir,		/* out direction */
                miState 	*state, 	/* state */
                miVector	*u,		/* u direction */
                miVector	*v,		/* v direction */
                miScalar	shiny_u,	/* shiny coefficient in u dir*/
                miScalar	shiny_v);	/* shiny coefficient in v dir*/
void mi_reflection_dir_anisglossy_x(
                miVector	*dir,		/* out direction */
                miState 	*state, 	/* state */
                const miVector	*u,		/* u direction */
                const miVector	*v,		/* v direction */
                miScalar	shiny_u,	/* shiny coefficient in u dir*/
                miScalar	shiny_v,	/* shiny coefficient in v dir*/
                const  double	sample[2]);	/* 2-dim sample to use */
void mi_reflection_dir_diffuse(
                miVector	*dir,		/* out direction */
                miState 	*state);	/* state */
void mi_reflection_dir_diffuse_x(
                miVector	*dir,		/* out direction */
                miState 	*state,		/* state */
                const  double	sample[2]);	/* 2-dim sample to use */
miBoolean mi_transmission_dir_specular( /*same as mi_refraction_dir*/
                miVector	*dir,		/* in direction */
                miState 	*state, 	/* state */
                miScalar	ior_in, 	/* in index of refraction */
                miScalar	ior_out);	/* out index of refraction */
miBoolean mi_transmission_dir_glossy(
                miVector	*dir,		/* out direction */
                miState 	*state, 	/* state */
                miScalar	ior_in, 	/* in index of refraction */
                miScalar	ior_out,	/* out index of refraction */
                miScalar	shiny); 	/* shiny coefficient */
miBoolean mi_transmission_dir_glossy_x(
                miVector	*dir,		/* out direction */
                miState 	*state, 	/* state */
                miScalar	ior_in, 	/* in index of refraction */
                miScalar	ior_out,	/* out index of refraction */
                miScalar	shiny, 		/* shiny coefficient */
                const  double	sample[2]);	/* 2-dim sample to use */
miBoolean mi_transmission_dir_anisglossy(
                miVector	*dir,		/* out direction */
                miState 	*state, 	/* state */
                miScalar	ior_in, 	/* in index of refraction */
                miScalar	ior_out,	/* out index of refraction */
                miVector	*u,		/* u direction */
                miVector	*v,		/* v direction */
                miScalar	shiny_u,	/* shiny coefficient in u dir*/
                miScalar	shiny_v);	/* shiny coefficient in v dir*/
miBoolean mi_transmission_dir_anisglossy_x(
                miVector	*dir,		/* out direction */
                miState 	*state, 	/* state */
                miScalar	ior_in, 	/* in index of refraction */
                miScalar	ior_out,	/* out index of refraction */
                const miVector	*u,		/* u direction */
                const miVector	*v,		/* v direction */
                miScalar	shiny_u,	/* shiny coefficient in u dir*/
                miScalar	shiny_v,	/* shiny coefficient in v dir*/
                const  double	sample[2]);	/* 2-dim sample to use */
void mi_transmission_dir_diffuse(
                miVector	*dir,		/* out direction */
                miState 	*state);	/* state */
void mi_transmission_dir_diffuse_x(
                miVector	*dir,		/* out direction */
                miState 	*state,		/* state */
                const  double	sample[2]);	/* 2-dim sample to use */
void mi_scattering_dir_diffuse(
                miVector	*dir,		/* result: out direction */
                miState 	*state);
void mi_scattering_dir_directional(
                miVector	*dir,		/* result: out direction */
                miState 	*state,
                miScalar	directionality);/* -1: back ... 1: forward */
miScalar mi_scattering_pathlength(
                miState		*state,
                miScalar	k);

/* choose scatter type */
miRay_type mi_choose_scatter_type(
                miState 	*state,
                miScalar	transp, 	/* refl = 1-transp */
                miColor 	*diffuse,
                miColor 	*glossy,
                miColor 	*specular);
miRay_type mi_choose_simple_scatter_type(
                miState 	*state,
                miColor 	*rdiffuse,
                miColor 	*rspecular,
                miColor 	*tdiffuse,
                miColor 	*tspecular);
int mi_choose_lobe(
                miState 	*state,
                miScalar	r);		/* probability of first lobe */

/* evalution of reflection models */
miScalar mi_phong_specular(
                miScalar	spec_exp,	/* specular exponent */
                miState 	*state, 	/* state */
                miVector	*dir);		/* direction */
miScalar mi_blong_specular(
                miScalar	spec_exp,	/* specular exponent */
                miState 	*state, 	/* state */
                miVector	*dir);		/* direction */
miScalar mi_blinn_specular(
                miVector	*di,		/* incident direction */
                miVector	*dr,		/* direction of reflection */
                miVector	*n,		/* surface normal */
                miScalar	roughness,	/* average microfacet slope */
                miScalar	ior);		/* index of refraction */
miBoolean mi_cooktorr_specular(
                miColor 	*result,	/* resulting color */
                miVector	*di,		/* incident direction */
                miVector	*dr,		/* direction of reflection */
                miVector	*n,		/* surface normal */
                miScalar	roughness,	/* average microfacet slope */
                miColor 	*ior);		/* relative ior for 3 wavelgt*/
void mi_fresnel_specular(
                miScalar	*ns,
                miScalar	*ks,
                miScalar	spec_exp,	/* specular exponent */
                miState 	*state, 	/* state */
                miVector	*dir,		/* direction */
                miScalar	ior_in, 	/* in index of refraction */
                miScalar	ior_out);	/* out index of refraction */
miScalar mi_ward_glossy(
                miVector	*di,		/* incident direction */
                miVector	*dr,		/* direction of reflection */
                miVector	*n,		/* normal */
                miScalar	shiny); 	/* glossyness */
miScalar mi_ward_anisglossy(
                miVector	*di,		/* incident direction */
                miVector	*dr,		/* direction of reflection */
                miVector	*n,		/* normal */
                miVector	*u,		/* u direction */
                miVector	*v,		/* v direction */
                miScalar	shiny_u,	/* glossyness in u direction */
                miScalar	shiny_v);	/* glossyness in u direction */
miScalar mi_fresnel(
                miScalar	n1,
                miScalar	n2,
                miScalar	t1,
                miScalar	t2);
miScalar mi_fresnel_reflection(
                miState 	*state,
                miScalar	ior_in,
                miScalar	ior_out);
miScalar mi_schlick_scatter(
                miVector	*di,		/* incident direction */
                miVector	*dr,		/* direction of reflection */
                miScalar	directionality);/* -1:back, 0:isot., 1:forw. */

/* photon tracing */
miBoolean mi_photon_reflection_specular(
                miColor 	*energy,	/* energy carried by photon */
                miState 	*state,
                miVector	*dir);
miBoolean mi_photon_reflection_glossy(
                miColor 	*energy,	/* energy carried by photon */
                miState 	*state,
                miVector	*dir);
miBoolean mi_photon_reflection_diffuse(
                miColor 	*energy,	/* energy carried by photon */
                miState 	*state,
                miVector	*dir);
miBoolean mi_photon_transmission_specular(
                miColor 	*energy,	/* energy carried by photon */
                miState 	*state,
                miVector	*dir);
miBoolean mi_photon_transmission_glossy(
                miColor 	*energy,	/* energy carried by photon */
                miState 	*state,
                miVector	*dir);
miBoolean mi_photon_transmission_diffuse(
                miColor 	*energy,	/* energy carried by photon */
                miState 	*state,
                miVector	*dir);
miBoolean mi_photon_transparent(
                miColor 	*energy,	/* photon flux */
                miState 	*parent);
miBoolean mi_photon_light(
                miColor 	*energy,
                miState 	*state );
miBoolean mi_photon_volume_scattering(
                miColor 	*energy,	/* energy carried by photon */
                miState 	*state,
                miVector	*dir);

/*
 * user frame buffer access
 */

miBoolean mi_fb_put(
                miState 	*state, 	/* current shader state */
                int		fb,		/* frame buffer number, 0..n */
                void		*data); 	/* sample data to store */
miBoolean mi_fb_get(
                miState 	*state, 	/* current shader state */
                int		fb,		/* frame buffer number, 0..n */
                void		*data); 	/* sample data to store */

/*
 * contour output shader interface
 */

typedef struct miContour_endpoint {
                miVector	point;		/* x, y in screen coords, */
                                                /* z in camera coordinates */
                miColor 	color;
                float		width;
                miVector	motion;
                miVector	normal;
                miTag		material;
                int		label;
} miContour_endpoint;


miC_LINKAGE miBoolean mi_get_contour_line(
                miContour_endpoint *p1,
                miContour_endpoint *p2);

miC_LINKAGE void mi_add_contour_lines(
                miContour_endpoint p1[],	/* list of first endpoints */
                miContour_endpoint p2[],	/* list of second endpoints */
                int		n);		/* number of contour lines */


/*
 * parallel safe random number generator
 */

double mi_par_random(
                miState		*state);

/*
 * more functions, defined by LIB. They are here because they need miState.
 * All take the state, a result vector pointer, and an input vector pointer.
 */

void mi_point_to_world(
                const miState *, miVector *, const miVector *);
void mi_point_to_camera(
                const miState *, miVector *, const miVector *);
void mi_point_to_object(
                const miState *, miVector *, const miVector *);
void mi_point_to_raster(
                const miState *, miVector *, const miVector *);
void mi_point_to_light(
                const miState *, miVector *, const miVector *);
void mi_point_from_world(
                const miState *, miVector *, const miVector *);
void mi_point_from_camera(
                const miState *, miVector *, const miVector *);
void mi_point_from_object(
                const miState *, miVector *, const miVector *);
void mi_point_from_light(
                const miState *, miVector *, const miVector *);
void mi_vector_to_world(
                const miState *, miVector *, const miVector *);
void mi_vector_to_camera(
                const miState *, miVector *, const miVector *);
void mi_vector_to_object(
                const miState *, miVector *, const miVector *);
void mi_vector_to_light(
                const miState *, miVector *, const miVector *);
void mi_vector_from_world(
                const miState *, miVector *, const miVector *);
void mi_vector_from_camera(
                const miState *, miVector *, const miVector *);
void mi_vector_from_object(
                const miState *, miVector *, const miVector *);
void mi_vector_from_light(
                const miState *, miVector *, const miVector *);
void mi_normal_to_world(
                const miState *, miVector *, const miVector *);
void mi_normal_to_camera(
                const miState *, miVector *, const miVector *);
void mi_normal_to_object(
                const miState *, miVector *, const miVector *);
void mi_normal_to_light(
                const miState *, miVector *, const miVector *);
void mi_normal_from_world(
                const miState *, miVector *, const miVector *);
void mi_normal_from_camera(
                const miState *, miVector *, const miVector *);
void mi_normal_from_object(
                const miState *, miVector *, const miVector *);
void mi_normal_from_light(
                const miState *, miVector *, const miVector *);

/*
 * geometry shaders
 */

miBoolean mi_geoshader_add_result(
                miTag		*result,	/* shader result */
                const miTag	item);		/* scene item to add */


/*------------ mi_rcgi.h ------------*/

miBoolean mi_store_volume_photon(
  miColor* energy,
  miState* state);

miBoolean mi_store_photon(
  miColor* energy,
  miState* state);

miBoolean mi_compute_irradiance(
  miColor* result,
  miState* state);

miBoolean mi_compute_irradiance_backside(
  miColor* result,
  miState* state);

miBoolean mi_compute_directional_irradiance(
  miColor* result,
  miState* state,
  const miScalar r,
  const miScalar g1,
  const miScalar g2);

miBoolean mi_compute_volume_irradiance(
  miColor* result,
  miState* state);

/* Type for overwriting global finalgather options */
typedef struct miIrrad_options {
  int		size;			/* size of the structure */
  /* finalgather part */
  int		finalgather_rays;	/* no. rays in final gather */
  miScalar	finalgather_maxradius;	/* maxdist for finalgather */
  miScalar	finalgather_minradius;	/* mindist for finalgather */
  miCBoolean	finalgather_view;	/* radii in raster pixels ? */
  miUchar	finalgather_filter;	/* finalgather ray filter */
  miUchar	padding1[2];		/* padding */

  /* globillum part */
  int		globillum_accuracy;	/* no. GI photons in estimation */
  miScalar	globillum_radius; 	/* maxdist for GI photons */


  /* caustics part */
  int		caustic_accuracy;	/* no. caustic photons in estimation */
  miScalar	caustic_radius;		/* maxdist for caustic photons */

  /* extension */
  miUint	finalgather_points;	/* #fg points for interpolation */
  miScalar	importance;		/* importance factor */
  miUint	id;			/* id of fg points to use */
  miUint	finalgather_force;	/* 0==see inst/obj, 1==on, 2==off */
  miUint	finalgather_points_test;/* 0==see global flag, 1==on, 2==off */

  /* this structure may be extended in the future */
} miIrrad_options;

/*
 * Initialize values from the default options. Call this macro, when overwrite
 * defaults were necessary. Negative importance means: use the default one.
 */
#define miIRRAD_DEFAULT(irrad, state) do {                                  \
  (irrad)->size                  = sizeof(miIrrad_options);                 \
  (irrad)->finalgather_rays      = (state)->options->finalgather_rays;      \
  (irrad)->finalgather_maxradius = (state)->options->finalgather_maxradius; \
  (irrad)->finalgather_minradius = (state)->options->finalgather_minradius; \
  (irrad)->finalgather_view      = (state)->options->finalgather_view;      \
  (irrad)->finalgather_filter    = (state)->options->finalgather_filter;    \
  (irrad)->padding1[0]           = 0;                                       \
  (irrad)->padding1[1]           = 0;                                       \
  (irrad)->globillum_accuracy    = (state)->options->globillum_accuracy;    \
  (irrad)->globillum_radius      = (state)->options->globillum_radius;      \
  (irrad)->caustic_accuracy      = (state)->options->caustic_accuracy;      \
  (irrad)->caustic_radius        = (state)->options->caustic_radius;        \
  (irrad)->finalgather_points    = 0;     /* use the default one */         \
  (irrad)->importance            = -1.0f; /* use the default one */         \
  (irrad)->id                    = 0;     /* no id by default    */         \
  (irrad)->finalgather_force     = 0;     /* see inst/obj by default */     \
  (irrad)->finalgather_points_test=0;     /* see global flag by default */  \
} while(0)

/*****************************************************************************
 * This function is a replacement for mi_compute_irradiance and
 * mi_compute_irradiance_backside. If irrad_options is NULL, the result is
 * 1/M_PI of mi_compute_irradiance(_backside), side depending on the face
 * parameter. If it is not NULL, fields in the miIrrad_options overwrite the
 * global values from miOptions structure.
 */
miBoolean mi_compute_avg_radiance(
  miColor			*result,
  miState			*state,
  miUchar			face,	/* 'f' front, 'b' back */
  struct miIrrad_options	*irrad_options);/* options to overwrite */


/* Type for mi_ambient_occlusion */
typedef struct miAmboccl_options {
  int		size;		/* size of the structure             */

  int		rays;		/* number of rays to shoot           */
  miVector	axis;		/* the axis for the cone             */
  miScalar	spread;		/* cosine of the spread angle        */
  miScalar	spread_exp;	/* the exponent of the cosine distr  */
  miScalar	mindist;	/* near clipping distance            */
  miScalar	maxdist;	/* far clipping distance             */
  int		cache_points;	/* number of ao points for lookup    */
  int		flags;		/* intersection flags (miTrace_flag) */
  miScalar	falloff;	/* falloff exponent                  */
} miAmboccl_options;


/*
 * Initialize values from the default options. Call this macro, then overwrite
 * defaults where necessary.
 */
#define miAMBOCCL_DEFAULT(ao, state) do {                                   \
  (ao)->size                  	 = sizeof(miAmboccl_options);               \
  (ao)->rays			 = -1;	  /* use string options */	    \
  (ao)->axis			 = state->normal;			    \
  (ao)->spread			 = -2;	  /* out of range, use default */   \
  (ao)->spread_exp		 = 1;	  /* lambertian */		    \
  (ao)->mindist			 = -1;	  /* use string options */	    \
  (ao)->maxdist			 = -1;	  /* use string options */	    \
  (ao)->cache_points		 = -1;	  /* use string options */	    \
  (ao)->flags			 = -1;	  /* use default */		    \
  (ao)->falloff			 = -1;	  /* use string options */	    \
} while(0)

/*****************************************************************************
 * computes and returns the ambient occlusion factor.
 * A value of 0 means completely unoccluded, while 1 means totally occluded
 */
miScalar    mi_ambient_occlusion (
  miState			*state,
  struct miAmboccl_options	*amboccl_options,
  miVector			*bent_normal);   /* opt. bent normal */


/*------------ mi_rcfg.h ------------*/

typedef enum miFinalgather_store_mode {
  miFG_STORE_COMPUTE		= 1,	/* compute FG point */
  miFG_STORE_SET		= 2	/* set FG to given value */
} miFinalgather_store_mode;

miBoolean mi_finalgather_store(
  miColor	*result,
  miState	*state,
  int 		mode);

/*------------ mi_phen.h ------------*/

/* state shaders */
typedef enum miShader_state_op {
        miSHADERSTATE_STATE_INIT,	/* call shader for local init */
        miSHADERSTATE_STATE_EXIT,	/* call shader for local exit */
        miSHADERSTATE_SAMPLE_INIT,	/* shader call before other shaders */
	miSHADERSTATE_SAMPLE_EXIT	/* shader call after other shaders */ 
} miShader_state_op;

typedef struct miShader_state_arg {
	miShader_state_op	op;	/* what the state shader should do */
	miBoolean		shader_return;	/* result prev. shader call*/
} miShader_state_arg;

/*------------ mi_smethod.h ------------*/

miBoolean mi_sample(
	double 		*sample,
	int 		*instance,
	struct miState 	*state,
	const miUshort 	dimension,
	const miUint 	*n);

/*------------ mi_lprof.h ------------*/

miScalar mi_lightprofile_value(
        const void*     vlprof,         /* opaque pointer to light profile */
        miScalar        phi,            /* horizontal angle */
        miScalar        costheta,       /* cos of vertical angle */
        const miVector* pos,            /* sample position */
        miBoolean       rel);           /* return abs. or relative values */

miScalar mi_lightprofile_sample(
        miState*        state,
        miTag           light_profile,
        miBoolean       rel);

/*------------ mi_spectrum.h ------------*/

/* all spectra contain in the first four float entries a color, the
 * CIE XYZ value of the spectrum. 
 */
#define miSPECTRUM_MAX_SIZE 74  

typedef float miSpectrum_para[miSPECTRUM_MAX_SIZE];

struct miSpectrum;
struct miSpectrum_iterator;
typedef struct miSpectrum_iterator miSpectrum_iterator;
struct miSpectrum_data;

const char* 		mi_spectrum_enabled	(void);

struct miSpectrum*	mi_spectrum_ensure	(struct miSpectrum* s);
struct miSpectrum*	mi_spectrum_blueprint	(void);
struct miSpectrum*	mi_spectrum_create	(const struct 
							miSpectrum_data *sd);
struct miSpectrum*	mi_spectrum_create_inheap (const struct
							miSpectrum_data *sd);
struct miSpectrum*	mi_spectrum_clone	(const struct miSpectrum *s);

void			mi_spectrum_delete	(struct miSpectrum *s);
void			mi_spectrum_delete_fromheap (struct miSpectrum *s);
void			mi_spectrum_clear	(struct miSpectrum *s);
void			mi_spectrum_reset	(struct miSpectrum *s);

unsigned int 		mi_spectrum_size	(const struct miSpectrum *s);
void			mi_spectrum_assign	(struct miSpectrum *s,
						 const struct miSpectrum* in);
void			mi_spectrum_assign_data (struct miSpectrum *s,
						 const struct miSpectrum_data* sd);
void			mi_spectrum_copy	(struct miSpectrum *s,
						 const struct miSpectrum* in);
void			mi_spectrum_mul		(struct miSpectrum *s,
						 const struct miSpectrum* in);
void			mi_spectrum_add		(struct miSpectrum *s,
						 const struct miSpectrum* in);
void			mi_spectrum_scale	(struct miSpectrum *s,
						 miScalar scale);
void			mi_spectrum_scale_add	(struct miSpectrum  *s,
						 const struct miSpectrum* in,
						 miScalar   scale);
void			mi_spectrum_lerp	(struct miSpectrum *s,
						 const struct miSpectrum *in,
						 miScalar lerp);
void			mi_spectrum_color_add	(struct miSpectrum *s,
						 const miColor	   *c);	
miScalar    		mi_spectrum_ciexyz	(miColor	   *c,
						 const struct miSpectrum *s);
void			mi_spectrum_rgb		(miColor	    *c,
						 const struct miSpectrum* s);

struct miSpectrum_iterator* mi_spectrum_iterator_create(
						struct miSpectrum* s,
						miScalar quality);
void			mi_spectrum_iterator_destroy(
					    struct miSpectrum_iterator* it);

struct miSpectrum*	mi_spectrum_iterator_begin(
					struct miSpectrum_iterator* it);
struct miSpectrum*	mi_spectrum_iterator_next(
					struct miSpectrum_iterator* it);
struct miSpectrum*	mi_spectrum_iterator_end(
					struct miSpectrum_iterator* it);

unsigned int		mi_spectrum_iterator_size(void);

miScalar		mi_spectrum_value_get	(const struct miSpectrum* s,
						 miScalar   wavelen);
miScalar		mi_spectrum_value_set	(struct miSpectrum* s,
						 miScalar   wavelen,
						 miScalar   value);
miScalar		mi_spectrum_value_add	(struct miSpectrum* s,
						 miScalar   wavelen,
						 miScalar   value);
void			mi_spectrum_range_get	(const struct miSpectrum* s,
						 miScalar*  wavelen_min,
						 miScalar*  wavelen_max);
miScalar		mi_spectrum_linewidth	(const struct miSpectrum* s,
						 miScalar   wavelen);
miBoolean		mi_spectrum_check	(const struct miSpectrum* s);
void			mi_spectrum_visible_range(miScalar* min_lambda, 
						  miScalar* max_lambda);

void			mi_spectrum_blackbody   (miSpectrum* bbody,
						 miScalar temperature,
						 miScalar intensity);
void			mi_spectrum_cie         (miSpectrum* spec, 
						 miScalar intensity,
						 const char* illuminant);
void			mi_spectrum_cie_sky	(miSpectrum* sky, 
						 miScalar temperature,
						 miScalar intensity);


/*------------ i_mem_allocatable.h ------------*/

#ifdef __cplusplus
} // extern "C"
#endif
#ifndef MI_PRODUCT_RAY
#define MI_PRODUCT_RAY
#endif

#ifdef __cplusplus
#ifndef DEFINED_MI_MEM_ALLOCATABLE
#define DEFINED_MI_MEM_ALLOCATABLE

// Some compilers fall apart when they see a placement delete.
#if defined(__SUNPRO_CC)
#define MI_MEM_NO_PLACEMENT_DELETE
#endif


namespace MI {
namespace MEM {


/// Allocator class implementation based on mi_mem_ functions.
class Allocator_impl_mi_mem
{
public:
    static void *amalloc(size_t sz)
    { return mi_mem_int_allocate_sizet(0, 0, sz); }

    static void *amalloc(const char* file, int line, size_t sz)
    { return mi_mem_int_allocate_sizet(file, line, sz); }

    static void afree(void *p)
    { mi_mem_int_release(0, 0, p); }

    static void afree(const char *file, int line, void *p)
    { mi_mem_int_release(file, line, p); }
};


/// The base class for all allocatable objects.
///
/// This class allows the introduction of system-wide memory handling
/// strategies (at least for the inheriting objects) without overloading global
/// \c new and \c delete.
/// Users should derive objects which are allocated with \c new from this class.

template < class Impl >
class Tallocatable : public Impl
{
public:
    /// Class-specific dynamic-storage handling functions.
    /// Note that all those members come in pairs, where each allocation function requires
    /// a corresponding deallocation function. For sematic issues, look at 3.7.3.1 and 3.7.3.2,
    /// for the mechanisms behind it 5.3.4, 5.3.5 and 12.5. Please note that the matching placement
    /// deallocation functions required for one case only - when the corresponding allocation
    /// function throws an exception 5.3.4(17). Not providing such a matching deallocation
    /// function results in C4291 "no matching operator delete found; memory will not be freed
    /// if initialization throws an exception".

    void* operator new ( size_t	sz )    { return Impl::amalloc(sz); }
    void* operator new[] ( size_t sz )  { return Impl::amalloc(sz); }

    void operator delete ( void* p )    { Impl::afree(p); }
    void operator delete[] ( void* p )  { Impl::afree(p); }


    void* operator new ( size_t	sz, const char* file, int line )
    { return Impl::amalloc(file, line, sz); }

    void* operator new[] ( size_t sz, const char* file, int line )
    { return Impl::amalloc(file, line, sz); }

    void operator delete ( void* p, size_t)    { Impl::afree(p); }
    void operator delete[] ( void* p, size_t)  { Impl::afree(p); }

    /// The placement allocation function.
    void* operator new (size_t sz, void* a)  { return a; }

#ifndef MI_MEM_NO_PLACEMENT_DELETE
    /// The placement deallocation function.
    void operator delete ( void* a, void* ) {}
    void operator delete[] ( void* a, void* ) {}

    void operator delete ( void* p, const char* file, int line)
    { Impl::afree(file, line, p); }

    void operator delete[] (void* p, const char* file, int line)
    { Impl::afree(file, line, p); }
#endif

};


/// The Allocatable base class.
typedef Tallocatable< Allocator_impl_mi_mem >  Allocatable;
}} // MI::MEM
#endif  // DEFINED_MI_MEM_ALLOCATABLE
#endif  // __cplusplus
#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
#include "mi_shader_if.h"
#include "shader_bsdf.h"
#ifdef MI_METASL_HEADERS
#include "shader_metasl.h"
#endif
#endif

#endif
