Exemplo n.º 1
0
static int load_embedded_image(lua_State *L) {
    am_check_nargs(L, 1);
    const char *filename = luaL_checkstring(L, 1);
    am_embedded_file_record *rec = am_get_embedded_file(filename);
    if (rec == NULL) {
        return luaL_error(L, "embedded file not found: %s", filename);
    }
    int width, height;
    int components = 4;
    stbi_set_flip_vertically_on_load(1);
    stbi_uc *img_data =
        stbi_load_from_memory((stbi_uc const *)rec->data, rec->len, &width, &height, &components, 4);
    if (img_data == NULL) {
        return luaL_error(L, "error loading image %s: %s", filename, stbi_failure_reason());
    }
    am_image_buffer *img = am_new_userdata(L, am_image_buffer);
    img->width = width;
    img->height = height;
    img->format = AM_PIXEL_FORMAT_RGBA8;
    int sz = width * height * pixel_format_size(img->format);
    am_buffer *imgbuf = am_new_userdata(L, am_buffer);
    imgbuf->size = sz;
    imgbuf->data = img_data;
    img->buffer = imgbuf;
    img->buffer_ref = img->ref(L, -1);
    lua_pop(L, 1); // pop imgbuf
    return 1;
}
Exemplo n.º 2
0
static int load_image(lua_State *L) {
    am_check_nargs(L, 1);
    char *errmsg;
    int len;
    const char *filename = luaL_checkstring(L, 1);
    void *data = am_read_resource(filename, &len, &errmsg);
    if (data == NULL) {
        lua_pushstring(L, errmsg);
        free(errmsg);
        return lua_error(L);
    }
    int width, height;
    int components = 4;
    stbi_set_flip_vertically_on_load(1);
    stbi_uc *img_data =
        stbi_load_from_memory((stbi_uc const *)data, len, &width, &height, &components, 4);
    free(data);
    if (img_data == NULL) {
        return luaL_error(L, "error loading image %s: %s", filename, stbi_failure_reason());
    }
    am_image_buffer *img = am_new_userdata(L, am_image_buffer);
    img->width = width;
    img->height = height;
    img->format = AM_PIXEL_FORMAT_RGBA8;
    int sz = width * height * pixel_format_size(img->format);
    am_buffer *imgbuf = am_new_userdata(L, am_buffer);
    imgbuf->size = sz;
    imgbuf->data = img_data;
    img->buffer = imgbuf;
    img->buffer_ref = img->ref(L, -1);
    lua_pop(L, 1); // pop imgbuf
    return 1;
}
Exemplo n.º 3
0
static int paste(lua_State *L) {
    am_check_nargs(L, 4);
    am_image_buffer *dst = am_get_userdata(L, am_image_buffer, 1);
    am_image_buffer *src = am_get_userdata(L, am_image_buffer, 2);
    int start_x = lua_tointeger(L, 3) - 1;
    int start_y = lua_tointeger(L, 4) - 1;
    if (start_x < 0) luaL_argerror(L, 3, "must be a positive integer");
    if (start_y < 0) luaL_argerror(L, 4, "must be a positive integer");
    if (src->format != dst->format) luaL_error(L, "images must have the same format");
    int src_w = src->width;
    int src_h = src->height;
    int dst_w = dst->width;
    int dst_h = dst->height;
    if (start_x >= dst_w) return 0;
    if (start_y >= dst_h) return 0;
    int pitch = am_min(dst_w - start_x, src_w);
    int end_y = am_min(dst_h - start_y, src_h);
    uint8_t *src_data = src->buffer->data;
    uint8_t *dst_data = dst->buffer->data;
    int psz = pixel_format_size(src->format);
    int row_size = pitch * psz;
    int j = start_y;
    for (int i = 0; i < end_y; i++) {
        memmove(dst_data + j * dst_w * psz + start_x * psz, src_data + i * src_w * psz, row_size);
        j++;
    }
    dst->buffer->mark_dirty(start_y * dst_w * psz + start_x * psz, (start_y + end_y - 1) * psz + (start_x + pitch) * psz);
    return 0;
}
Exemplo n.º 4
0
static VALUE
image_create_cairo_surface(VALUE obj)
{
    cairo_surface_t* cairo_surface;
    cairo_format_t cairo_format;
    unsigned char* data;
    VALUE surface;
    struct image_data* image = get_image_data(obj);

    data = xmalloc(sizeof(unsigned char)*RSTRING_LEN(image->buffer));
    MEMCPY(data, RSTRING_PTR(image->buffer), unsigned char, RSTRING_LEN(image->buffer));

    cairo_format = pixel_format_to_cairo_format(image->pixel_format);
    cairo_surface = cairo_image_surface_create_for_data(
	    data, cairo_format, (int)image->width, (int)image->height,
	    (int)image->stride*pixel_format_size(image->pixel_format));
    cairo_surface_set_user_data(cairo_surface, &cairo_data_key, data, image_surface_did_destroyed);
    surface = CRSURFACE2RVAL_WITH_DESTROY(cairo_surface);
    return surface;
}
Exemplo n.º 5
0
static int create_image_buffer(lua_State *L) {
    int nargs = am_check_nargs(L, 1);
    am_image_buffer *img = am_new_userdata(L, am_image_buffer);
    int arg = 1;
    if (am_get_type(L, arg) == MT_am_buffer) {
        img->buffer = am_get_userdata(L, am_buffer, arg);
        img->buffer_ref = img->ref(L, arg);
        arg++;
    }
    if (nargs < arg) {
        return luaL_error(L, "not enough arguments");
    }
    img->width = luaL_checkinteger(L, arg++);
    if (img->width <= 0) {
        return luaL_error(L, "width must be positive");
    }
    if (nargs >= arg) {
        img->height = luaL_checkinteger(L, arg++);
    } else {
        img->height = img->width;
    }
    if (img->height <= 0) {
        return luaL_error(L, "height must be positive");
    }
    img->format = AM_PIXEL_FORMAT_RGBA8;
    int required_size = img->width * img->height * pixel_format_size(img->format);
    if (img->buffer == NULL) {
        // create new buffer
        img->buffer = am_new_userdata(L, am_buffer, required_size);
        img->buffer_ref = img->ref(L, -1);
        lua_pop(L, 1); // pop buffer;
    } else {
        // check supplied buffer has correct size.
        if (required_size != img->buffer->size) {
            return luaL_error(L, "buffer has wrong size (%d, expecting %d)", img->buffer->size, required_size);
        }
    }
    return 1;
}
Exemplo n.º 6
0
static int decode_png(lua_State *L) {
    am_check_nargs(L, 1);
    am_buffer *buf = am_get_userdata(L, am_buffer, 1);
    int width, height;
    int components = 4;
    stbi_set_flip_vertically_on_load(1);
    stbi_uc *img_data =
        stbi_load_from_memory((stbi_uc const *)buf->data, buf->size, &width, &height, &components, 4);
    if (img_data == NULL) {
        return luaL_error(L, "error decoding image %s: %s", buf->origin, stbi_failure_reason());
    }
    am_image_buffer *img = am_new_userdata(L, am_image_buffer);
    img->width = width;
    img->height = height;
    img->format = AM_PIXEL_FORMAT_RGBA8;
    int sz = width * height * pixel_format_size(img->format);
    am_buffer *imgbuf = am_new_userdata(L, am_buffer);
    imgbuf->size = sz;
    imgbuf->data = img_data;
    img->buffer = imgbuf;
    img->buffer_ref = img->ref(L, -1);
    lua_pop(L, 1); // pop imgbuf
    return 1;
}
Exemplo n.º 7
0
static void
process_arguments_of_image_initialize(int const argc, VALUE* const argv,
	VALUE* buffer_ptr,
	rb_image_file_image_pixel_format_t* pixel_format_ptr,
	long* width_ptr,
	long* height_ptr,
	long* stride_ptr
	)
{
    VALUE params;
    VALUE buffer = Qnil;
    VALUE pixel_format = Qnil;
    VALUE width = Qnil;
    VALUE height = Qnil;
    VALUE stride = Qnil;

    rb_image_file_image_pixel_format_t pf;
    long wd, ht, st;
    long min_len;

    ID id_pixel_format, id_data, id_width, id_height, id_row_stride;
    CONST_ID(id_data,  "data");
    CONST_ID(id_pixel_format,  "pixel_format");
    CONST_ID(id_width,  "width");
    CONST_ID(id_height, "height");
    CONST_ID(id_row_stride,  "row_stride");

    rb_scan_args(argc, argv, "01", &params);
    if (TYPE(params) == T_HASH) {
	buffer = rb_hash_lookup(params, ID2SYM(id_data));
	pixel_format = rb_hash_lookup(params, ID2SYM(id_pixel_format));
	width = rb_hash_lookup(params, ID2SYM(id_width));
	height = rb_hash_lookup(params, ID2SYM(id_height));
	stride = rb_hash_lookup(params, ID2SYM(id_row_stride));
    }

    if (!NIL_P(buffer)) {
	Check_Type(buffer, T_STRING);
	buffer = rb_str_dup(buffer);
    }

    if (NIL_P(pixel_format))
	rb_raise(rb_eArgError, "missing image pixel format");
    if (TYPE(pixel_format) == T_STRING)
	pixel_format = rb_str_intern(pixel_format);
    pf = check_pixel_format(pixel_format);

    if (NIL_P(width))
	rb_raise(rb_eArgError, "missing image width");
    wd = NUM2LONG(width);
    if (wd <= 0)
	rb_raise(rb_eArgError, "zero or negative image width");

    if (NIL_P(height))
	rb_raise(rb_eArgError, "missing image height");
    ht = NUM2LONG(height);
    if (ht <= 0)
	rb_raise(rb_eArgError, "zero or negative image height");

    if (NIL_P(stride)) {
#ifdef HAVE_RB_CAIRO_H
	st = cairo_format_stride_for_width(pixel_format_to_cairo_format(pf), (int)wd) / pixel_format_size(pf);
	stride = INT2NUM(st);
#else
	stride = width;
#endif
    }
    st = NUM2LONG(stride);
    if (st <= 0)
	rb_raise(rb_eArgError, "zero or negative image row-stride");
    else if (st < wd) {
	rb_warning("the given row-stride is less than the given image width.");
	st = wd;
    }

    min_len = minimum_buffer_size(pf, st, ht);
    if (NIL_P(buffer)) {
	buffer = rb_str_new(NULL, min_len);
    }
    else if (RSTRING_LEN(buffer) < min_len) {
	void rb_str_modify_expand(VALUE, long);
	rb_warning("the size of the given data is too short for the given size of image");
	rb_str_modify_expand(buffer, min_len - RSTRING_LEN(buffer));
    }

    *buffer_ptr = buffer;
    *pixel_format_ptr = pf;
    *width_ptr = wd;
    *height_ptr = ht;
    *stride_ptr = st;
}