#include "ruby_vips.h" /* :nodoc: */ static VALUE writer_initialize(int argc, VALUE *argv, VALUE obj) { VALUE image, opts; rb_scan_args(argc, argv, "11", &image, &opts); GetImg(image, data, im); GetImg(obj, data_new, im_new); img_add_dep(data_new, image); if (im_copy(im, im_new)) vips_lib_error(); return obj; } /* * call-seq: * writer.image -> image * * Returns the image associated with *self*. */ static VALUE writer_image(VALUE obj) { GetImg(obj, data, im); if(data->deps) return data->deps[0]; return Qnil; } static VALUE writer_meta_set(VALUE obj, const char* name, VALUE str) { GetImg(obj, data, im); size_t len = RSTRING_LEN(str); void *buf = malloc(len); memcpy(buf, RSTRING_PTR(str), len); if (im_meta_set_blob(im, name, (im_callback_fn)xfree, buf, len)) { xfree(buf); vips_lib_error(); } return str; } static VALUE writer_meta_remove(VALUE obj, const char* name) { GetImg(obj, data, im); #if ATLEAST_VIPS( 7, 22 ) if (im_meta_remove(im, name)) return Qfalse; #else rb_raise(eVIPSError, "This method is not implemented in your version of VIPS"); #endif return Qtrue; } /* * call-seq: * writer.exif = exif_data * * Sets the exif header of the writer to exif_data. This will be * written only if the file format supports embedded exif data. * */ static VALUE writer_exif_set(VALUE obj, VALUE str) { return writer_meta_set(obj, IM_META_EXIF_NAME, str); } /* * call-seq: * writer.remove_exif -> true or false * * Removes exif data associated with *self*. */ static VALUE writer_remove_exif(VALUE obj) { return writer_meta_remove(obj, IM_META_EXIF_NAME); } /* * call-seq: * writer.icc = icc_data * * Sets the icc header of the writer to icc_data. This will be written * only if the file format supports embedded icc data. * */ static VALUE writer_icc_set(VALUE obj, VALUE str) { return writer_meta_set(obj, IM_META_ICC_NAME, str); } /* * call-seq: * writer.remove_icc -> true or false * * Removes icc data associated with *self*. */ static VALUE writer_remove_icc(VALUE obj) { return writer_meta_remove(obj, IM_META_ICC_NAME); } /* :nodoc: */ static VALUE writer_write_internal(VALUE obj, VALUE path) { VipsImage *out; GetImg(obj, data, im); if (!(out = im_open(StringValuePtr(path), "w")) || im_copy(im, out)) vips_lib_error(); im_close(out); return obj; } /* :nodoc: */ static VALUE jpeg_buf_internal(VALUE obj, VALUE quality) { char *buf = NULL; int length; GetImg(obj, data, im); #if ATLEAST_VIPS( 7, 28 ) { size_t len; if (vips_jpegsave_buffer(im, &buf, &len, "Q", NUM2INT(quality), NULL)) vips_lib_error(); /* Argh. */ length = len; } #else if (im_vips2bufjpeg(im, NULL, NUM2INT(quality), &buf, &length)) vips_lib_error(); #endif return rb_tainted_str_new(buf, length); } /* :nodoc: */ static VALUE jpeg_write_internal(VALUE obj, VALUE path) { GetImg(obj, data, im); if (im_vips2jpeg(im, RSTRING_PTR(path))) vips_lib_error(); return obj; } /* :nodoc: */ static VALUE tiff_write_internal(VALUE obj, VALUE path) { GetImg(obj, data, im); if (im_vips2tiff(im, RSTRING_PTR(path))) vips_lib_error(); return obj; } /* :nodoc: */ static VALUE ppm_write_internal(VALUE obj, VALUE path) { GetImg(obj, data, im); if (im_vips2ppm(im, RSTRING_PTR(path))) vips_lib_error(); return obj; } /* :nodoc: */ static VALUE png_buf_internal(VALUE obj, VALUE compression, VALUE interlace) { char *buf; size_t length; GetImg(obj, data, im); #if ATLEAST_VIPS( 7, 28 ) if (vips_pngsave_buffer(im, &buf, &length, "compression", NUM2INT(compression), "interlace", NUM2INT(interlace), NULL)) vips_lib_error(); #elif ATLEAST_VIPS( 7, 23 ) if (im_vips2bufpng(im, NULL, NUM2INT(compression), NUM2INT(interlace), &buf, &length)) vips_lib_error(); #else rb_raise(eVIPSError, "This method is not implemented in your version of VIPS"); #endif return rb_tainted_str_new(buf, length); } /* :nodoc: */ static VALUE png_write_internal(VALUE obj, VALUE path) { GetImg(obj, data, im); if (im_vips2png(im, RSTRING_PTR(path))) vips_lib_error(); return obj; } /* :nodoc: */ static VALUE csv_write_internal(VALUE obj, VALUE path) { GetImg(obj, data, im); if (im_vips2csv(im, RSTRING_PTR(path))) vips_lib_error(); return obj; } /* :nodoc: */ static VALUE vips_write_internal(VALUE obj, VALUE path) { VipsImage *im_new; GetImg(obj, data, im); if (!(im_new = (VipsImage *)im_openout(RSTRING_PTR(path)))) vips_lib_error(); if (im_copy(im, im_new)) vips_lib_error(); im_close(im_new); return obj; } /* * Base class for image format readers. */ void init_Writer(void) { VALUE writer = rb_define_class_under(mVIPS, "Writer", rb_cObject); rb_include_module(writer, mVIPSHeader); rb_define_alloc_func(writer, img_init_partial_anyclass); rb_define_method(writer, "initialize", writer_initialize, -1); rb_define_method(writer, "image", writer_image, 0); rb_define_method(writer, "exif=", writer_exif_set, 1); rb_define_method(writer, "remove_exif", writer_remove_exif, 0); rb_define_method(writer, "icc=", writer_icc_set, 1); rb_define_method(writer, "remove_icc", writer_remove_icc, 0); rb_define_private_method(writer, "write_internal", writer_write_internal, 1); /* * Write JPEG images. */ VALUE jpeg_writer = rb_define_class_under(mVIPS, "JPEGWriter", writer); rb_define_private_method(jpeg_writer, "buf_internal", jpeg_buf_internal, 1); rb_define_private_method(jpeg_writer, "write_internal", jpeg_write_internal, 1); /* * Write TIFF images. */ VALUE tiff_writer = rb_define_class_under(mVIPS, "TIFFWriter", writer); rb_define_private_method(tiff_writer, "write_internal", tiff_write_internal, 1); /* * Write PPM images. */ VALUE ppm_writer = rb_define_class_under(mVIPS, "PPMWriter", writer); rb_define_private_method(ppm_writer, "write_internal", ppm_write_internal, 1); /* * Write PNG images. */ VALUE png_writer = rb_define_class_under(mVIPS, "PNGWriter", writer); rb_define_private_method(png_writer, "write_internal", png_write_internal, 1); rb_define_private_method(png_writer, "buf_internal", png_buf_internal, 2); /* * Write CSV images. */ VALUE csv_writer = rb_define_class_under(mVIPS, "CSVWriter", writer); rb_define_private_method(csv_writer, "write_internal", csv_write_internal, 1); /* * Write native VIPS images. */ VALUE vips_writer = rb_define_class_under(mVIPS, "VIPSWriter", writer); rb_define_private_method(vips_writer, "write_internal", vips_write_internal, 1); #if 0 VALUE mVIPS = rb_define_module("VIPS"); #endif }