Esempio n. 1
0
	void SensorEvent::Dispatch (SensorEvent* event) {
		
		if (SensorEvent::callback) {
			
			if (!init) {
				
				id_id = val_id ("id");
				id_type = val_id ("type");
				id_x = val_id ("x");
				id_y = val_id ("y");
				id_z = val_id ("z");
				init = true;
				
			}
			
			value object = (SensorEvent::eventObject ? SensorEvent::eventObject->get () : alloc_empty_object ());
			
			alloc_field (object, id_id, alloc_int (event->id));
			alloc_field (object, id_type, alloc_int (event->type));
			alloc_field (object, id_x, alloc_float (event->x));
			alloc_field (object, id_y, alloc_float (event->y));
			alloc_field (object, id_z, alloc_float (event->z));
			
			val_call0 (SensorEvent::callback->get ());
			
		}
		
	}
Esempio n. 2
0
value AudioBuffer::Value () {

    if (!init) {

        id_bitsPerSample = val_id ("bitsPerSample");
        id_channels = val_id ("channels");
        id_data = val_id ("data");
        id_sampleRate = val_id ("sampleRate");
        init = true;

    }

    if (val_is_null (mValue)) {

        mValue = alloc_empty_object ();

    }

    alloc_field (mValue, id_bitsPerSample, alloc_int (bitsPerSample));
    alloc_field (mValue, id_channels, alloc_int (channels));
    alloc_field (mValue, id_data, data ? data->Value () : alloc_null ());
    alloc_field (mValue, id_sampleRate, alloc_int (sampleRate));
    return mValue;

}
Esempio n. 3
0
    value snow_assets_audio_read_bytes_wav( value _info, value _start, value _len ) {

        QuickVec<unsigned char> buffer;

        value _handle = property_value(_info, id_handle);

        snow::assets::audio::WAV_file_source* wav_source = snow::from_hx<snow::assets::audio::WAV_file_source>(_handle);

        if( !val_is_null(_handle) && wav_source ) {

            bool complete = snow::assets::audio::read_bytes_wav( wav_source, buffer, val_int(_start), val_int(_len) );

            value data = snow::bytes_to_hx( &buffer[0], buffer.size() );

            value _object = alloc_empty_object();

                alloc_field( _object, id_bytes, data );
                alloc_field( _object, id_complete, alloc_bool(complete) );

            return _object;

        } else {

            return alloc_null();

        }

    } DEFINE_PRIM(snow_assets_audio_read_bytes_wav, 3);
Esempio n. 4
0
    value snow_assets_audio_read_bytes_pcm( value _info, value _start, value _len ) {

        QuickVec<unsigned char> buffer;

        value _handle = property_value(_info, id_handle);

        snow::assets::audio::PCM_file_source* pcm_source = snow::from_hx<snow::assets::audio::PCM_file_source>(_handle);

        if( !val_is_null(_handle) && pcm_source ) {

            bool complete = snow::assets::audio::read_bytes_pcm( pcm_source, buffer, val_int(_start), val_int(_len) );

            ByteArray data(buffer);

            value _object = alloc_empty_object();

                alloc_field( _object, id_bytes, data.mValue );
                alloc_field( _object, id_complete, alloc_bool(complete) );

            return _object;

        } else {

            return alloc_null();

        }

    } DEFINE_PRIM(snow_assets_audio_read_bytes_pcm, 3);
Esempio n. 5
0
static value socket_recv_from( value o, value dataBuf, value pos, value len, value addr ) {
	int p,l,ret;
	int retry = 0;
	struct sockaddr_in saddr;
	SockLen slen = sizeof(saddr);
	val_check_kind(o,k_socket);
	val_check(dataBuf,buffer);
	buffer buf = val_to_buffer(dataBuf);
   char *data = buffer_data(buf);
   int dlen = buffer_size(buf);
	val_check(pos,int);
	val_check(len,int);
	val_check(addr,object);
	p = val_int(pos);
	l = val_int(len);

	if( p < 0 || l < 0 || p > dlen || p + l > dlen )
		neko_error();
   SOCKET sock = val_sock(o);
   gc_enter_blocking();
	POSIX_LABEL(recv_from_again);
	if( retry++ > NRETRYS ) {
      ret = recv(sock,data+p,l,MSG_NOSIGNAL);
	} else
		ret = recvfrom(sock, data + p , l, MSG_NOSIGNAL, (struct sockaddr*)&saddr, &slen);
	if( ret == SOCKET_ERROR ) {
		HANDLE_EINTR(recv_from_again);
		return block_error();
	}
   gc_exit_blocking();
	alloc_field(addr,f_host,alloc_int32(*(int*)&saddr.sin_addr));
	alloc_field(addr,f_port,alloc_int(ntohs(saddr.sin_port)));
	return alloc_int(ret);
}
Esempio n. 6
0
	void TouchEvent::Dispatch (TouchEvent* event) {
		
		if (TouchEvent::callback) {
			
			if (!init) {
				
				id_id = val_id ("id");
				id_type = val_id ("type");
				id_x = val_id ("x");
				id_y = val_id ("y");
				init = true;
				
			}
			
			value object = (TouchEvent::eventObject ? TouchEvent::eventObject->get () : alloc_empty_object ());
			
			alloc_field (object, id_id, alloc_int (event->id));
			alloc_field (object, id_type, alloc_int (event->type));
			alloc_field (object, id_x, alloc_float (event->x));
			alloc_field (object, id_y, alloc_float (event->y));
			
			val_call1 (TouchEvent::callback->get (), object);
			
		}
		
	}
Esempio n. 7
0
        value sdl2_window_event_to_hx( WindowEvent &new_event, SDL_Event &event ) {

            value _object = alloc_empty_object();

                alloc_field( _object, id_type, alloc_int(event.window.event) );
                alloc_field( _object, id_window_id, alloc_int(event.window.windowID) );
                alloc_field( _object, id_timestamp, alloc_float(event.window.timestamp/1000.0) );

                switch (event.window.event) {

                    case SDL_WINDOWEVENT_MOVED:
                    case SDL_WINDOWEVENT_RESIZED:
                    case SDL_WINDOWEVENT_SIZE_CHANGED: {

                        alloc_field( _object, id_x, alloc_int(event.window.data1) );
                        alloc_field( _object, id_y, alloc_int(event.window.data2) );

                        break;

                    }

                } //switch event.type

            return _object;

        } //sdl2_window_event_to_hx
Esempio n. 8
0
	void GamepadEvent::Dispatch (GamepadEvent* event) {
		
		if (GamepadEvent::callback) {
			
			if (!init) {
				
				id_axis = val_id ("axis");
				id_button = val_id ("button");
				id_id = val_id ("id");
				id_type = val_id ("type");
				id_value = val_id ("value");
				init = true;
				
			}
			
			value object = (GamepadEvent::eventObject ? GamepadEvent::eventObject->get () : alloc_empty_object ());
			
			alloc_field (object, id_axis, alloc_int (event->axis));
			alloc_field (object, id_button, alloc_int (event->button));
			alloc_field (object, id_id, alloc_int (event->id));
			alloc_field (object, id_type, alloc_int (event->type));
			alloc_field (object, id_value, alloc_float (event->axisValue));
			
			val_call0 (GamepadEvent::callback->get ());
			
		}
		
	}
Esempio n. 9
0
	void* DisplayMode::Value () {

		// if (_mode) {

		// 	_mode->height = height;
		// 	_mode->pixelFormat = pixelFormat;
		// 	_mode->refreshRate = refreshRate;
		// 	_mode->width = width;
		// 	return _mode;

		// } else {

			if (!init) {

				id_height = val_id ("height");
				id_pixelFormat = val_id ("pixelFormat");
				id_refreshRate = val_id ("refreshRate");
				id_width = val_id ("width");
				init = true;

			}

			value displayMode = alloc_empty_object ();
			alloc_field (displayMode, id_height, alloc_int (height));
			alloc_field (displayMode, id_pixelFormat, alloc_int (pixelFormat));
			alloc_field (displayMode, id_refreshRate, alloc_int (refreshRate));
			alloc_field (displayMode, id_width, alloc_int (width));
			return displayMode;

		// }

	}
Esempio n. 10
0
/**
	gc_stats : void -> { heap => int, free => int }
	<doc>Return the size of the GC heap and the among of free space, in bytes</doc>
**/
static value gc_stats() {
	int heap, free;
	value o;
	neko_gc_stats(&heap,&free);
	o = alloc_object(NULL);
	alloc_field(o,val_id("heap"),alloc_int(heap));
	alloc_field(o,val_id("free"),alloc_int(free));
	return o;
}
Esempio n. 11
0
	void Bytes::Resize (int size) {
		
		if (size != _length) {
			
			if (!_value) {
				
				_value = alloc_empty_object ();
				
			}
			
			if (val_is_null (val_field (_value, id_b))) {
				
				value dataValue;
				
				if (useBuffer) {
					
					buffer b = alloc_buffer_len (size);
					dataValue = buffer_val (b);
					_data = (unsigned char*)buffer_data (b);
					
				} else {
					
					dataValue = alloc_raw_string (size);
					_data = (unsigned char*)val_string (dataValue);
					
				}
				
				alloc_field (_value, id_b, dataValue);
				
			} else {
				
				if (useBuffer) {
					
					buffer b = val_to_buffer (val_field (_value, id_b));
					buffer_set_size (b, size);
					_data = (unsigned char*)buffer_data (b);
					
				} else {
					
					value s = alloc_raw_string (size);
					memcpy ((char *)val_string (s), val_string (val_field (_value, id_b)), size);
					alloc_field (_value, id_b, s);
					_data = (unsigned char*)val_string (s);
					
				}
				
			}
			
			alloc_field (_value, id_length, alloc_int (size));
			
		}
		
		_length = size;
		
	}
Esempio n. 12
0
        value display_mode_to_hx( display_mode mode ) {

            value _object = alloc_empty_object();

                alloc_field( _object, id_width, alloc_int(mode.width) );
                alloc_field( _object, id_height, alloc_int(mode.height) );
                alloc_field( _object, id_refresh_rate, alloc_int(mode.refresh_rate) );
                alloc_field( _object, id_format, alloc_int(mode.format) );

            return _object;

        } //display_mode_to_hx
Esempio n. 13
0
        value display_bounds_to_hx( bounds_rect bounds ) {

            value _object = alloc_empty_object();

                alloc_field( _object, id_x, alloc_int(bounds.x) );
                alloc_field( _object, id_y, alloc_int(bounds.y) );
                alloc_field( _object, id_width, alloc_int(bounds.width) );
                alloc_field( _object, id_height, alloc_int(bounds.height) );

            return _object;

        } //display_bounds_to_hx
Esempio n. 14
0
value hx_zmq_getint64sockopt(value socket_handle_,value option_) {

	val_check_kind(socket_handle_, k_zmq_socket_handle);

	if (!val_is_int(option_)) {
		val_throw(alloc_int(EINVAL));
		return alloc_null();
	}

	int rc = 0;
	int err = 0;
	uint64_t optval = 0;
	size_t optvallen = sizeof(optval);
	rc = zmq_getsockopt(val_data(socket_handle_),val_int(option_),&optval, &optvallen);
	err = zmq_errno();
	if (rc != 0) {
		val_throw(alloc_int(err));
		return alloc_int(0);
	}	
	value ret = alloc_empty_object();
	alloc_field(ret, val_id("hi"),alloc_int(optval >> 32));
	alloc_field(ret, val_id("lo"),alloc_int(optval & 0xFFFFFFFF));
	
	return ret;
}
Esempio n. 15
0
	void RenderEvent::Dispatch (RenderEvent* event) {

		if (RenderEvent::callback) {

			if (RenderEvent::eventObject->IsCFFIValue ()) {

				if (!init) {

					id_type = val_id ("type");

				}

				value object = (value)RenderEvent::eventObject->Get ();

				alloc_field (object, id_type, alloc_int (event->type));

			} else {

				RenderEvent* eventObject = (RenderEvent*)RenderEvent::eventObject->Get ();

				eventObject->type = event->type;

			}

			RenderEvent::callback->Call ();

		}

	}
Esempio n. 16
0
File: main.c Progetto: robinp/neko
int neko_execute_self( neko_vm *vm, value mload ) {
	value args[] = { alloc_string("std@module_read"), alloc_int(2) };
	value args2[] = { alloc_string("std@module_exec"), alloc_int(1) };
	value args3[] = { alloc_function(read_bytecode,3,"boot_read_bytecode"), mload };
	value exc = NULL;
	value module_read, module_exec, module_val;
	module_read = val_callEx(mload,val_field(mload,val_id("loadprim")),args,2,&exc);
	if( exc != NULL ) {
		report(vm,exc,1);
		return 1;
	}
	module_exec = val_callEx(mload,val_field(mload,val_id("loadprim")),args2,2,&exc);
	if( exc != NULL ) {
		report(vm,exc,1);
		return 1;
	}
	module_val = val_callEx(val_null,module_read,args3,2,&exc);
	fclose(self);
	if( exc != NULL ) {
		report(vm,exc,1);
		return 1;
	}
	alloc_field(val_field(mload,val_id("cache")),val_id("_self"),module_val);
	val_callEx(val_null,module_exec,&module_val,1,&exc);
	if( exc != NULL ) {
		report(vm,exc,1);
		return 1;
	}
	return 0;
}
Esempio n. 17
0
/**
	$objset : o:any -> f:int -> v:any -> any
	<doc>Set the field [f] of [o] to [v] and return [v] if [o] is an object or [null] if not</doc>
**/
static value builtin_objset( value o, value f, value v ) {
	if( !val_is_object(o) )
		return val_null; // keep dot-access semantics
	val_check(f,int);
	alloc_field(o,val_int(f),v);
	return v;
}
Esempio n. 18
0
krb5_error_code
decode_krb5_tgs_req(const krb5_data *code, krb5_kdc_req **repptr)
{
    setup_no_length(krb5_kdc_req *);
    alloc_field(rep);
    clear_field(rep,padata);
    clear_field(rep,client);
    clear_field(rep,server);
    clear_field(rep,ktype);
    clear_field(rep,addresses);
    clear_field(rep,authorization_data.ciphertext.data);
    clear_field(rep,unenc_authdata);
    clear_field(rep,second_ticket);
    clear_field(rep, kdc_state);

    check_apptag(12);
    retval = asn1_decode_kdc_req(&buf,rep);
    if (retval) clean_return(retval);
#ifdef KRB5_MSGTYPE_STRICT
    if (rep->msg_type != KRB5_TGS_REQ) clean_return(KRB5_BADMSGTYPE);
#endif

    cleanup_manual();
error_out:
    krb5_free_kdc_req(NULL, rep);
    return retval;
}
Esempio n. 19
0
value wx_dir_dialog_show(value ioData)
{
   wxWindow *parent = 0;
   wxString message;
   wxString directory;
   int      style;
   wxPoint  position;
   wxSize   size;

   ValueToWX(val_field(ioData,val_id("parent")),parent);
   ValueToWX(val_field(ioData,val_id("message")),message);
   ValueToWX(val_field(ioData,val_id("directory")),directory);
   ValueToWX(val_field(ioData,val_id("style")),style);
   ValueToWX(val_field(ioData,val_id("size")),size);

   wxDirDialog *dlg = new wxDirDialog(parent,message,directory,style,position,size);
   bool result = dlg->ShowModal()==wxID_OK;

   if (result)
   {
     alloc_field(ioData,val_id("directory"), WXToValue(dlg->GetPath()));
   }

   dlg->Destroy();
   return alloc_bool(result);
}
Esempio n. 20
0
/**
	result_next : 'result -> object?
	<doc>Returns the next row in the result or [null] if no more result.</doc>
**/
static value result_next( value v ) {
	int i;
	result *r;
	val_check_kind(v,k_result);
	r = val_result(v);
	if( r->done )
		return val_null;
	switch( sqlite3_step(r->r) ) {
	case SQLITE_ROW:
		r->first = 0;
		v = alloc_object(NULL);
		for(i=0;i<r->ncols;i++) {
			value f;
			switch( sqlite3_column_type(r->r,i) ) {
			case SQLITE_NULL:
				f = val_null;
				break;
			case SQLITE_INTEGER:
				if( r->bools[i] )
					f = alloc_bool(sqlite3_column_int(r->r,i));
				else
					f = alloc_int(sqlite3_column_int(r->r,i));
				break;
			case SQLITE_FLOAT:
				f = alloc_float(sqlite3_column_double(r->r,i));
				break;
			case SQLITE_TEXT:
				f = alloc_string((char*)sqlite3_column_text(r->r,i));
				break;
			case SQLITE_BLOB:
				{
					int size = sqlite3_column_bytes(r->r,i);
					f = alloc_empty_string(size);
					memcpy(val_string(f),sqlite3_column_blob(r->r,i),size);
					break;
				}
			default:
				{
					buffer b = alloc_buffer("Unknown Sqlite type #");
					val_buffer(b,alloc_int(sqlite3_column_type(r->r,i)));
					val_throw(buffer_to_string(b));
				}
			}
			alloc_field(v,r->names[i],f);
		}
		return v;
	case SQLITE_DONE:
		finalize_result(r,1);
		return val_null;
	case SQLITE_BUSY:
		val_throw(alloc_string("Database is busy"));
	case SQLITE_ERROR:
		sqlite_error(r->db->db);
	default:
		neko_error();
	}
	return val_null;
}
Esempio n. 21
0
// Display specific code
static value display_get_screen_size()
{
#ifndef HX_LINUX
    dimensions dim;
	value w;
	value h;
	value o = alloc_empty_object();
	systools_display_get_screen_size(&dim);
	w=alloc_int(dim.width);
	h=alloc_int(dim.height);
	alloc_field( o, val_id("w"), w );
	alloc_field( o, val_id("h"), h );
	return o;
#else
	val_throw(alloc_string("function not available for this platform"));
	return val_null;
#endif
}
Esempio n. 22
0
/**
	regexp_matched_pos : 'regexp -> n:int -> { pos => int, len => int }
	<doc>Return the [n]th matched block position by the regexp. If [n] is 0 then
	return the whole matched substring position</doc>
**/
static value regexp_matched_pos( value o, value n ) {
	pcredata *d;
	int m;
	val_check_kind(o,k_regexp);	
	d = PCRE(o);
	val_check(n,int);
	m = val_int(n);
	if( m < 0 || m >= d->nmatchs || val_is_null(d->str) )
		return alloc_null();
	{
		int start = d->matchs[m*2];
		int len = d->matchs[m*2+1] - start;
		value o = alloc_empty_object();
		alloc_field(o,id_pos,alloc_int(start));
		alloc_field(o,id_len,alloc_int(len));
		return o;
	}
}
Esempio n. 23
0
	value AudioBuffer::Value (value audioBuffer) {

		if (!init) {

			id_bitsPerSample = val_id ("bitsPerSample");
			id_channels = val_id ("channels");
			id_data = val_id ("data");
			id_sampleRate = val_id ("sampleRate");
			init = true;

		}

		alloc_field (audioBuffer, id_bitsPerSample, alloc_int (bitsPerSample));
		alloc_field (audioBuffer, id_channels, alloc_int (channels));
		alloc_field (audioBuffer, id_data, data ? data->Value (val_field (audioBuffer, id_data)) : alloc_null ());
		alloc_field (audioBuffer, id_sampleRate, alloc_int (sampleRate));
		return audioBuffer;

	}
Esempio n. 24
0
	void GamepadEvent::Dispatch (GamepadEvent* event) {

		if (GamepadEvent::callback) {

			if (GamepadEvent::eventObject->IsCFFIValue ()) {

				if (!init) {

					id_axis = val_id ("axis");
					id_button = val_id ("button");
					id_id = val_id ("id");
					id_type = val_id ("type");
					id_value = val_id ("axisValue");
					init = true;

				}

				value object = (value)GamepadEvent::eventObject->Get ();

				alloc_field (object, id_axis, alloc_int (event->axis));
				alloc_field (object, id_button, alloc_int (event->button));
				alloc_field (object, id_id, alloc_int (event->id));
				alloc_field (object, id_type, alloc_int (event->type));
				alloc_field (object, id_value, alloc_float (event->axisValue));

			} else {

				GamepadEvent* eventObject = (GamepadEvent*)GamepadEvent::eventObject->Get ();

				eventObject->axis = event->axis;
				eventObject->button = event->button;
				eventObject->id = event->id;
				eventObject->type = event->type;
				eventObject->axisValue = event->axisValue;

			}

			GamepadEvent::callback->Call ();

		}

	}
Esempio n. 25
0
krb5_error_code
decode_krb5_kdc_req_body(const krb5_data *code, krb5_kdc_req **repptr)
{
    setup_buf_only(krb5_kdc_req *);
    alloc_field(rep);

    retval = asn1_decode_kdc_req_body(&buf,rep);
    if (retval) clean_return(retval);

    cleanup(free);
}
Esempio n. 26
0
krb5_error_code
decode_krb5_pa_pk_as_req_draft9(const krb5_data *code,
                                krb5_pa_pk_as_req_draft9 **repptr)
{
    setup_buf_only(krb5_pa_pk_as_req_draft9 *);
    alloc_field(rep);

    retval = asn1_decode_pa_pk_as_req_draft9(&buf, rep);
    if (retval) clean_return(retval);

    cleanup(free);
}
Esempio n. 27
0
	value ImageBuffer::Value () {
		
		if (!init) {
			
			id_bitsPerPixel = val_id ("bitsPerPixel");
			id_transparent = val_id ("transparent");
			id_buffer = val_id ("buffer");
			id_width = val_id ("width");
			id_height = val_id ("height");
			id_data = val_id ("data");
			id_format = val_id ("format");
			init = true;
			
		}
		
		mValue = alloc_empty_object ();
		alloc_field (mValue, id_width, alloc_int (width));
		alloc_field (mValue, id_height, alloc_int (height));
		alloc_field (mValue, id_bitsPerPixel, alloc_int (bitsPerPixel));
		alloc_field (mValue, id_data, data ? data->Value () : alloc_null ());
		alloc_field (mValue, id_transparent, alloc_bool (transparent));
		alloc_field (mValue, id_format, alloc_int (format));
		return mValue;
		
	}
Esempio n. 28
0
/**
	inflate_buffer : 'istream -> src:string -> srcpos:int -> dst:string -> dstpos:int -> { done => bool, read => int, write => int }
**/
static value inflate_buffer( value s, value src, value srcpos, value dst, value dstpos ) {
	z_stream *z;
	int err;
	value o;
	val_check_kind(s,k_stream_inf);
	val_check(srcpos,int);

	buffer src_buf = val_to_buffer(src);
	if (!src_buf)
	   hx_failure("invalid source buffer");
	buffer dst_buf = val_to_buffer(dst);
	if (!dst_buf)
	   hx_failure("invalid destination buffer");

	int slen = buffer_size(src_buf);
	int dlen = buffer_size(dst_buf);

	val_check(dstpos,int);
	z = val_stream(s);
	if( val_int(srcpos) < 0 || val_int(dstpos) < 0 )
		return alloc_null();
	slen -= val_int(srcpos);
	dlen -= val_int(dstpos);
	if( slen < 0 || dlen < 0 )
		return alloc_null();

	z->next_in = (Bytef*)buffer_data(src_buf) + val_int(srcpos);
	z->next_out = (Bytef*)buffer_data(dst_buf) + val_int(dstpos);
	z->avail_in = slen;
	z->avail_out = dlen;
	if( (err = inflate(z,val_flush(z))) < 0 )
		zlib_error(z,err);
	z->next_in = NULL;
	z->next_out = NULL;
	o = alloc_empty_object();
	alloc_field(o,id_done,alloc_bool(err == Z_STREAM_END));
	alloc_field(o,id_read,alloc_int((int)(slen - z->avail_in)));
	alloc_field(o,id_write,alloc_int((int)(dlen - z->avail_out)));
	return o;
}
Esempio n. 29
0
    value snow_assets_image_load_info( value _id, value _req_bpp ) {

        QuickVec<unsigned char> buffer;

        int w = 0, h = 0, bpp = 0, bpp_source = 0;
        int req_bpp = val_int(_req_bpp);

        bool success = snow::assets::image::load_info( buffer, val_string(_id), &w, &h, &bpp, &bpp_source, req_bpp );

        if(!success) {
            return alloc_null();
        }

        value data = snow::bytes_to_hx( &buffer[0], buffer.size() );

        value _object = alloc_empty_object();

            alloc_field( _object, id_id, _id );
            alloc_field( _object, id_width, alloc_int(w) );
            alloc_field( _object, id_height, alloc_int(h) );
            alloc_field( _object, id_bpp, alloc_int(bpp) );
            alloc_field( _object, id_bpp_source, alloc_int(bpp_source) );
            alloc_field( _object, id_data, data );

        return _object;

    } DEFINE_PRIM(snow_assets_image_load_info, 2);
Esempio n. 30
0
    value snow_assets_image_info_from_bytes( value _id, value _bytes, value _req_bpp ) {

        QuickVec<unsigned char> buffer;

        int w = 0, h = 0, bpp = 0, bpp_source = 0;
        int req_bpp = val_int(_req_bpp);

        bool success = snow::assets::image::info_from_bytes( buffer, ByteArray(_bytes), val_string(_id), &w, &h, &bpp, &bpp_source, req_bpp );

        if(!success) {
            return alloc_null();
        }

        value _object = alloc_empty_object();

            alloc_field( _object, id_id, _id );
            alloc_field( _object, id_width, alloc_int(w) );
            alloc_field( _object, id_height, alloc_int(h) );
            alloc_field( _object, id_bpp, alloc_int(bpp) );
            alloc_field( _object, id_bpp_source, alloc_int(bpp_source) );
            alloc_field( _object, id_data, ByteArray(buffer).mValue );

        return _object;

    } DEFINE_PRIM(snow_assets_image_info_from_bytes, 3);