DEFINE_FUNC_1(webp_get_features, data_buffer_value) { if (!val_is_buffer(data_buffer_value)) { val_throw(alloc_string("webp_get_features: Expected to be a buffer")); return alloc_null(); } buffer data_buffer = val_to_buffer(data_buffer_value); int data_len = buffer_size(data_buffer); char *data_ptr = buffer_data(data_buffer); WebPBitstreamFeatures features = {0}; VP8StatusCode code = WebPGetFeatures((const unsigned char *)data_ptr, data_len, &features); if (code != VP8_STATUS_OK) { val_throw(alloc_string("webp_get_features: Error: (code != VP8_STATUS_OK)")); return alloc_null(); } value array = alloc_array(7); val_array_set_i(array, 0, alloc_int(features.width)); val_array_set_i(array, 1, alloc_int(features.height)); val_array_set_i(array, 2, alloc_int(features.has_alpha)); //val_array_set_i(array, 3, alloc_int(features.bitstream_version)); val_array_set_i(array, 3, alloc_int(0)); val_array_set_i(array, 4, alloc_int(features.no_incremental_decoding)); val_array_set_i(array, 5, alloc_int(features.rotate)); val_array_set_i(array, 6, alloc_int(features.uv_sampling)); return array; }
DEFINE_FUNC_1(webp_decode_argb, data_buffer_value) { if (!val_is_buffer(data_buffer_value)) { val_throw(alloc_string("webp_decode_argb: Expected to be a buffer")); return alloc_null(); } buffer data_buffer = val_to_buffer(data_buffer_value); int data_len = buffer_size(data_buffer); char *data_ptr = buffer_data(data_buffer); int webp_width = -1, webp_height = -1; char *webp_data_ptr = (char *)WebPDecodeARGB((const unsigned char *)data_ptr, data_len, &webp_width, &webp_height); int webp_data_len = webp_width * webp_height * 4; if (webp_data_ptr == NULL) { val_throw(alloc_string("webp_decode_argb: Invalid webp data")); return alloc_null(); } buffer webp_buffer = alloc_buffer_len(0); buffer_append_sub(webp_buffer, webp_data_ptr, webp_data_len); buffer_set_size(webp_buffer, webp_data_len); value array = alloc_array(3); val_array_set_i(array, 0, alloc_int(webp_width)); val_array_set_i(array, 1, alloc_int(webp_height)); val_array_set_i(array, 2, buffer_val(webp_buffer)); if (webp_data_ptr != NULL) free(webp_data_ptr); return array; }
//Be very careful with this, it does not support offsets into buffers yet value vertexAttribPointer( value *args, int count ) { enum {index,size,type,normalized,stride,pointer}; if (count != 6) { throw "vertexAttribPointer invalid parameter length"; } char *ptr = NULL; if (val_is_buffer (args[pointer])) { std::cout << "vertexAttribPointer does not accept data for pointer arg" << std::endl; //ptr = buffer_data( val_to_buffer ( args[pointer] ) ); } else if (val_is_int (args[pointer])) { ptr = ((char *)NULL + val_int(args[pointer])); } glVertexAttribPointer( (GLuint)val_int( args[index] ), (GLint)val_int( args[size] ), (GLenum)val_int( args[type] ), (GLboolean)val_bool( args[normalized] ), (GLsizei)val_int( args[stride] ), (const GLvoid *)ptr ); return alloc_null( ); }
value hx_zmq_setbytessockopt(value socket_handle_, value option_, value bytes_optval_) { val_check_kind(socket_handle_, k_zmq_socket_handle); if (!val_is_int(option_)) { printf("option_ is not int"); val_throw(alloc_int(EINVAL)); return alloc_null(); } size_t size = 0; uint8_t *data = 0; // If data from neko if (val_is_string(bytes_optval_)) { size = val_strlen(bytes_optval_); data = (uint8_t *)val_string(bytes_optval_); } // else from C++ else if (val_is_buffer(bytes_optval_)) { buffer buf = val_to_buffer(bytes_optval_); size = buffer_size(buf); data = (uint8_t *)buffer_data(buf); } else { printf("bytes_optval_ not string or buffer"); val_throw(alloc_int(EINVAL)); return alloc_null(); } int rc = 0; int err = 0; int option = val_int(option_); rc = zmq_setsockopt (val_data(socket_handle_), option, data, size); err = zmq_errno(); if (rc != 0) { printf("err:%d",err); val_throw(alloc_int(err)); return alloc_null(); } return alloc_int(rc); }
//FIXME indices and bytearrays do not particularly mix //Does val_to_buffer throw an error on null? value drawElements( value mode, value count, value type, value indices ) { char *ptr = NULL; if (val_is_buffer(indices)) { ptr = buffer_data( val_to_buffer ( indices ) ); } else if (val_is_int(indices)) { ptr = ((char *)NULL+val_int(indices)); } glDrawElements( (GLenum)val_int( mode ), (GLsizei)val_int( count ), (GLenum)val_int( type ), (const GLvoid *)ptr ); return alloc_null( ); }
DEFINE_FUNC_5(webp_encode_argb, data_buffer_value, width_value, height_value, lossless_value, quality_factor_value) { int width = 0; int height = 0; float quality_factor = 100; int lossless = 1; int stride = 0; uint8_t* abgr = NULL; uint8_t* rgba = NULL; uint8_t* output = NULL; int output_size = 0; int pixels_size; int bytes_size; buffer data_buffer; if (val_is_int(width_value)) width = val_int(width_value); if (val_is_int(height_value)) height = val_int(height_value); if (val_is_bool(lossless_value)) lossless = val_bool(lossless_value); if (val_is_float(quality_factor_value)) quality_factor = val_float(quality_factor_value); stride = width * 4; pixels_size = width * height; bytes_size = pixels_size * 4; if (!val_is_buffer(data_buffer_value)) { val_throw(alloc_string("webp_encode_argb: Expected to be a buffer")); return alloc_null(); } data_buffer = val_to_buffer(data_buffer_value); if (bytes_size != buffer_size(data_buffer)) { val_throw(alloc_string("webp_encode_argb: Invalid buffer size")); return alloc_null(); } //if () abgr = (uint8_t *)buffer_data(data_buffer); rgba = (uint8_t *)malloc(bytes_size); uint8_t* _abgr = abgr; uint8_t* _rgba = rgba; int _pixels_size = pixels_size; while (_pixels_size-- > 0) { //_rgba[0] = _abgr[3]; _rgba[0] = _abgr[1]; _rgba[1] = _abgr[2]; _rgba[2] = _abgr[3]; _rgba[3] = _abgr[0]; _abgr += 4; _rgba += 4; } if (lossless) { output_size = WebPEncodeLosslessRGBA( rgba, //abgr, width, height, stride, &output ); } else { output_size = WebPEncodeRGBA( rgba, //abgr, width, height, stride, quality_factor, &output ); } printf("output_size: (%d, %d, %d) : %d\n", width, height, stride, output_size); buffer output_buffer = alloc_buffer_len(0); buffer_append_sub(output_buffer, (char *)output, output_size); buffer_set_size(output_buffer, output_size); if (output != NULL) free(output); if (rgba != NULL) free(rgba); return buffer_val(output_buffer); }
/** * Receive data from socket * Based on code in https://github.com/zeromq/jzmq/blob/master/src/Socket.cpp */ value hx_zmq_send(value socket_handle_, value msg_data, value flags) { val_check_kind(socket_handle_, k_zmq_socket_handle); if (!val_is_null(flags) && !val_is_int(flags)) { val_throw(alloc_int(EINVAL)); return alloc_null(); } size_t size = 0; uint8_t *data = 0; zmq_msg_t message; // Extract byte data from either Neko string or C++ buffer // see: http://waxe.googlecode.com/svn-history/r32/trunk/src/waxe/HaxeAPI.cpp "Val2ByteData" if (val_is_string(msg_data)) { // Neko size = val_strlen(msg_data); data = (uint8_t *)val_string(msg_data); } else if (val_is_buffer(msg_data)) { // CPP buffer buf = val_to_buffer(msg_data); size = buffer_size(buf); data = (uint8_t *)buffer_data(buf); } else { val_throw(alloc_int(EINVAL)); return alloc_null(); } // Set up send message buffer by referencing the provided bytes data //zero copy version: int rc = zmq_msg_init_data (&message, data, size,NULL,NULL); int rc = zmq_msg_init_size(&message, size); memcpy (zmq_msg_data(&message), data, size); int err = zmq_errno(); if (rc != 0) { val_throw(alloc_int(err)); return alloc_null(); } gc_enter_blocking(); // Send #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0) rc = zmq_sendmsg (val_data(socket_handle_), &message, val_int(flags)); #else rc = zmq_send (val_data(socket_handle_), &message, val_int(flags)); #endif err = zmq_errno(); gc_exit_blocking(); // If NOBLOCK, but cant send message now, close message first before quitting if (rc == -1 && err == EAGAIN) { rc = zmq_msg_close (&message); err = zmq_errno(); if (rc != 0) { val_throw(alloc_int(err)); return alloc_null(); } return alloc_null(); } if (rc == -1) { val_throw(alloc_int(err)); rc = zmq_msg_close (&message); err = zmq_errno(); if (rc != 0) { val_throw(alloc_int(err)); return alloc_null(); } return alloc_null(); } rc = zmq_msg_close (&message); err = zmq_errno(); if (rc != 0) { val_throw(alloc_int(err)); return alloc_null(); } return alloc_null(); }