ext/rfreeimage/rfi_main.c in rfreeimage-0.1.1 vs ext/rfreeimage/rfi_main.c in rfreeimage-0.1.3

- old
+ new

@@ -216,11 +216,58 @@ if(!result) rb_raise(rb_eIOError, "Fail to save image"); return Qnil; } +VALUE Image_to_blob(VALUE self, VALUE type) +{ + char *filetype; + struct native_image* img; + FIMEMORY *hmem; + BOOL result; + FREE_IMAGE_FORMAT out_fif; + VALUE ret; + BYTE *raw = NULL; + DWORD file_size; + Data_Get_Struct(self, struct native_image, img); + RFI_CHECK_IMG(img); + + Check_Type(type, T_STRING); + filetype = rfi_value_to_str(type); + + out_fif = FreeImage_GetFIFFromFormat(filetype); + free(filetype); + if (out_fif == FIF_UNKNOWN) + rb_raise(Class_RFIError, "Invalid format"); + + hmem = FreeImage_OpenMemory(0, 0); + if (!hmem) + rb_raise(rb_eIOError, "Fail to allocate blob"); + if (out_fif == FIF_JPEG && img->bpp != 8 && img->bpp != 24) { + FIBITMAP *to_save = FreeImage_ConvertTo24Bits(img->handle); + result = FreeImage_SaveToMemory(out_fif, to_save, hmem, JPEG_BASELINE); + FreeImage_Unload(to_save); + } else { + result = FreeImage_SaveToMemory(out_fif, img->handle, hmem, 0); + } + + if(!result) { + FreeImage_CloseMemory(hmem); + rb_raise(rb_eIOError, "Fail to save image to blob"); + } + file_size = FreeImage_TellMemory(hmem); + FreeImage_SeekMemory(hmem, 0, SEEK_SET); + FreeImage_AcquireMemory(hmem, &raw, &file_size); + ret = rb_str_new((char*)raw, (long)file_size); + FreeImage_CloseMemory(hmem); + return ret; +} + + + + VALUE Image_cols(VALUE self) { struct native_image* img; Data_Get_Struct(self, struct native_image, img); return INT2NUM(img->w); @@ -447,10 +494,53 @@ img->handle = NULL; return v; } +VALUE Image_from_bytes(VALUE self, VALUE bytes, VALUE width, + VALUE height, VALUE stride, VALUE bpp) +{ + long f_len; + int _bpp = NUM2INT(bpp); + char *ptr; + unsigned char *p; + int i; + int src_stride = NUM2INT(stride); + FIBITMAP *h; + + ALLOC_NEW_IMAGE(v, img); + + if (_bpp != 8 && _bpp != 32) + rb_raise(rb_eArgError, "bpp must be 8 or 32"); + Check_Type(bytes, T_STRING); + f_len = RSTRING_LEN(bytes); + if (f_len < (long)src_stride * NUM2INT(height)) + rb_raise(rb_eArgError, "buffer too small"); + + h = FreeImage_Allocate(NUM2INT(width), NUM2INT(height), _bpp, 0, 0, 0); + if (!h) + rb_raise(rb_eArgError, "fail to allocate image"); + + img->handle = h; + img->w = FreeImage_GetWidth(h); + img->h = FreeImage_GetHeight(h); + img->bpp = FreeImage_GetBPP(h); + img->stride = FreeImage_GetPitch(h); + img->fif = FIF_BMP; + + /* up-side-down */ + p = FreeImage_GetBits(img->handle); + ptr = RSTRING_PTR(bytes) + img->h * src_stride; + for(i = 0; i < img->h; i++) { + ptr -= src_stride; + memcpy(p, ptr, img->stride); + p += img->stride; + } + + return v; +} + /* draw */ VALUE Image_draw_point(VALUE self, VALUE _x, VALUE _y, VALUE color, VALUE _size) { struct native_image* img; int x = NUM2INT(_x); @@ -534,14 +624,16 @@ rb_define_method(Class_Image, "to_bpp", Image_to_bpp, 1); rb_define_method(Class_Image, "rotate", Image_rotate, 1); rb_define_method(Class_Image, "resize", Image_resize, 2); rb_define_method(Class_Image, "crop", Image_crop, 4); + rb_define_method(Class_Image, "to_blob", Image_to_blob, 1); /* draw */ rb_define_method(Class_Image, "draw_point", Image_draw_point, 4); rb_define_method(Class_Image, "draw_rectangle", Image_draw_rectangle, 4 + 2); rb_define_singleton_method(Class_Image, "ping", Image_ping, 1); rb_define_singleton_method(Class_Image, "from_blob", Image_from_blob, -1); rb_define_singleton_method(Class_Image, "ping_blob", Image_ping_blob, 1); + rb_define_singleton_method(Class_Image, "from_bytes", Image_from_bytes, 5); }