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);
}