ext/jpeg/jpeg_image.c in jpeg-0.6.0 vs ext/jpeg/jpeg_image.c in jpeg-0.7.0
- old
+ new
@@ -5,29 +5,29 @@
extern VALUE rb_mJpeg;
VALUE rb_cJpegImage;
static VALUE jpeg_image_s_open(int argc, VALUE *argv, VALUE sef);
+static VALUE jpeg_image_s_open_buffer(int argc, VALUE *argv, VALUE sef);
static VALUE jpeg_image_alloc(VALUE klass);
static void jpeg_image_mark(struct rb_jpeg_image *p);
static void jpeg_image_free(struct rb_jpeg_image *p);
-static VALUE jpeg_image_width(VALUE self);
-static VALUE jpeg_image_height(VALUE self);
static VALUE jpeg_image_size(VALUE self);
-static VALUE jpeg_image_color_info(VALUE self);
static VALUE jpeg_image_raw_data(VALUE self);
extern VALUE rb_eJpegError;
void Init_jpeg_image(void) {
rb_cJpegImage = rb_define_class_under(rb_mJpeg, "Image", rb_cObject);
rb_define_alloc_func(rb_cJpegImage, jpeg_image_alloc);
rb_define_singleton_method(rb_cJpegImage, "open", jpeg_image_s_open, -1);
- rb_define_method(rb_cJpegImage, "width", jpeg_image_width, 0);
- rb_define_method(rb_cJpegImage, "height", jpeg_image_height, 0);
+ rb_define_singleton_method(rb_cJpegImage, "open_buffer", jpeg_image_s_open_buffer, -1);
+ rb_attr(rb_cJpegImage, rb_intern("width"), 1, 0, 0);
+ rb_attr(rb_cJpegImage, rb_intern("height"), 1, 0, 0);
+ rb_attr(rb_cJpegImage, rb_intern("color_info"), 1, 0, 0);
+
rb_define_method(rb_cJpegImage, "size", jpeg_image_size, 0);
- rb_define_method(rb_cJpegImage, "color_info", jpeg_image_color_info, 0);
rb_define_method(rb_cJpegImage, "raw_data", jpeg_image_raw_data, 0);
}
void jpeg_image_exit(j_common_ptr jpeg) {
char buffer[JMSG_LENGTH_MAX];
@@ -41,22 +41,20 @@
jpeg->fp = NULL;
jpeg->read = (void *)ALLOC(struct jpeg_decompress_struct);
jpeg->error = (void *)ALLOC(struct jpeg_error_mgr);
jpeg->read->err = jpeg_std_error(jpeg->error);
jpeg->error->error_exit = jpeg_image_exit;
- jpeg_create_decompress(jpeg->read);
return Data_Wrap_Struct(klass, jpeg_image_mark, jpeg_image_free, jpeg);
}
static void jpeg_image_mark(struct rb_jpeg_image *p) {
}
static void jpeg_image_free(struct rb_jpeg_image *p) {
if (p->read) {
- jpeg_destroy_decompress(p->read);
xfree(p->read);
}
if (p->error) {
xfree(p->error);
}
@@ -64,62 +62,97 @@
fclose(p->fp);
}
xfree(p);
}
-static VALUE jpeg_image_s_open(int argc, VALUE *argv, VALUE self) {
- VALUE path;
+static void jpeg_image_s_set_read_source(struct rb_jpeg_image *p_jpeg) {
+
+ if (p_jpeg->filename) {
+
+ if ((p_jpeg->fp = fopen(p_jpeg->filename, "rb")) == NULL) {
+ rb_raise(rb_eJpegError, "Open file failed: %s", p_jpeg->filename);
+ }
+
+ } else {
+
+#ifdef jpeg_mem_src
+ jpeg_mem_src(p_jpeg->read, (unsigned char *) p_jpeg->buffer, p_jpeg->buffer_len);
+#else
+ if ((p_jpeg->fp = fmemopen(p_jpeg->buffer, p_jpeg->buffer_len, "rb")) == NULL) {
+ rb_raise(rb_eJpegError, "Could not read jpeg from buffer");
+ }
+#endif
+
+ }
+
+ if (p_jpeg->fp) {
+ jpeg_stdio_src(p_jpeg->read, p_jpeg->fp);
+ }
+}
+
+static VALUE jpeg_image_s_get_image_values(char *filename, char *buffer, int64_t buffer_len, VALUE self) {
VALUE jpeg;
struct rb_jpeg_image *p_jpeg;
- char *filename;
- rb_scan_args(argc, argv, "1", &path);
- Check_Type(path, T_STRING);
- jpeg = rb_funcall(rb_cJpegImage, rb_intern("new"), 0);
+ jpeg = rb_obj_alloc(rb_cJpegImage);
+ rb_obj_call_init(jpeg, 0, NULL);
+
Data_Get_Struct(jpeg, struct rb_jpeg_image, p_jpeg);
- filename = StringValuePtr(path);
- if ((p_jpeg->fp = fopen(filename, "rb")) == NULL) {
- rb_raise(rb_eJpegError, "Open file failed: %s", filename);
- }
- jpeg_stdio_src(p_jpeg->read, p_jpeg->fp);
+ p_jpeg->filename = filename;
+ p_jpeg->buffer = buffer;
+ p_jpeg->buffer_len = buffer_len;
+ jpeg_create_decompress(p_jpeg->read);
+
+ jpeg_image_s_set_read_source(p_jpeg);
+
jpeg_read_header(p_jpeg->read, TRUE);
+
+ rb_iv_set(jpeg, "@width", LONG2NUM(p_jpeg->read->image_width));
+ rb_iv_set(jpeg, "@height", LONG2NUM(p_jpeg->read->image_height));
+ rb_iv_set(jpeg, "@color_info", ID2SYM(rb_intern( p_jpeg->read->out_color_space == JCS_GRAYSCALE ? "gray" : "rgb" )));
+
+ jpeg_destroy_decompress(p_jpeg->read);
+
+ if (p_jpeg->fp) {
+ fclose(p_jpeg->fp);
+ p_jpeg->fp = NULL;
+ }
+
return jpeg;
}
-static VALUE jpeg_image_width(VALUE self) {
- struct rb_jpeg_image *p_jpeg;
- Data_Get_Struct(self, struct rb_jpeg_image, p_jpeg);
- return rb_int_new(p_jpeg->read->image_width);
+static VALUE jpeg_image_s_open(int argc, VALUE *argv, VALUE self) {
+ VALUE path;
+
+ rb_scan_args(argc, argv, "1", &path);
+ Check_Type(path, T_STRING);
+
+ return jpeg_image_s_get_image_values(StringValuePtr(path), NULL, 0, self);
}
-static VALUE jpeg_image_height(VALUE self) {
- struct rb_jpeg_image *p_jpeg;
- Data_Get_Struct(self, struct rb_jpeg_image, p_jpeg);
- return rb_int_new(p_jpeg->read->image_height);
+static VALUE jpeg_image_s_open_buffer(int argc, VALUE *argv, VALUE self) {
+ VALUE str;
+
+ rb_scan_args(argc, argv, "1", &str);
+ Check_Type(str, T_STRING);
+
+ return jpeg_image_s_get_image_values(NULL, StringValuePtr(str), RSTRING_LEN(str), self);
}
static VALUE jpeg_image_size(VALUE self) {
- struct rb_jpeg_image *p_jpeg;
VALUE array;
- Data_Get_Struct(self, struct rb_jpeg_image, p_jpeg);
array = rb_ary_new();
- rb_ary_push(array, rb_int_new(p_jpeg->read->image_width));
- rb_ary_push(array, rb_int_new(p_jpeg->read->image_height));
+ rb_ary_push(array, rb_iv_get(self, "@width"));
+ rb_ary_push(array, rb_iv_get(self, "@height"));
+
return array;
}
-static VALUE jpeg_image_color_info(VALUE self) {
- struct rb_jpeg_image *p_jpeg;
-
- Data_Get_Struct(self, struct rb_jpeg_image, p_jpeg);
- return ID2SYM(rb_intern( p_jpeg->read->out_color_space == JCS_GRAYSCALE ? "gray" : "rgb" ));
-}
-
static VALUE jpeg_image_raw_data(VALUE self) {
struct rb_jpeg_image *p_jpeg;
VALUE matrix;
VALUE line;
VALUE point;
@@ -133,10 +166,16 @@
return matrix;
}
Data_Get_Struct(self, struct rb_jpeg_image, p_jpeg);
+ jpeg_create_decompress(p_jpeg->read);
+
+ jpeg_image_s_set_read_source(p_jpeg);
+
+ jpeg_read_header(p_jpeg->read, TRUE);
+
jpeg_start_decompress(p_jpeg->read);
line_size = p_jpeg->read->output_width * p_jpeg->read->out_color_components;
if ((buffer = (*p_jpeg->read->mem->alloc_sarray)((j_common_ptr) p_jpeg->read, JPOOL_IMAGE, line_size, 1)) == NULL) {
rb_raise(rb_eJpegError, "Could not allocate memory (%ld bytes) to decode the image", line_size);
@@ -162,9 +201,16 @@
}
rb_ary_push(matrix, line);
}
jpeg_finish_decompress(p_jpeg->read);
+
+ jpeg_destroy_decompress(p_jpeg->read);
+
+ if (p_jpeg->fp) {
+ fclose(p_jpeg->fp);
+ p_jpeg->fp = NULL;
+ }
rb_iv_set(self, "@raw_data", matrix);
return matrix;
}