/* Method: Info#page=<aString> or <aGeometry> Purpose: store the Postscript page geometry */ VALUE Info_page_eq(VALUE self, VALUE page_arg) { Info *info; volatile VALUE geom_str; char *geometry; Data_Get_Struct(self, Info, info); if (NIL_P(page_arg)) { magick_free(info->page); info->page = NULL; return self; } geom_str = rm_to_s(page_arg); geometry=GetPageGeometry(StringValuePtr(geom_str)); if (*geometry == '\0') { magick_free(info->page); info->page = NULL; return self; } magick_clone_string(&info->page, geometry); (void) SetImageOption(info, "page", StringValuePtr(geom_str)); return self; }
/* Method: ImageList#to_blob Purpose: returns the imagelist as a blob (a String) Notes: runs an info parm block if present - the user can specify the image format and depth */ VALUE ImageList_to_blob(VALUE self) { Image *images; Info *info; volatile VALUE info_obj; volatile VALUE blob_str; void *blob = NULL; size_t length = 0; ExceptionInfo exception; info_obj = rm_info_new(); Data_Get_Struct(info_obj, Info, info); // Convert the images array to an images sequence. images = images_from_imagelist(self); GetExceptionInfo(&exception); (void) SetImageInfo(info, MagickTrue, &exception); rm_check_exception(&exception, images, RetainOnError); if (*info->magick != '\0') { Image *img; for (img = images; img; img = GetNextImageInList(img)) { strncpy(img->magick, info->magick, sizeof(info->magick)-1); } } // Unconditionally request multi-images support. The worst that // can happen is that there's only one image or the format // doesn't support multi-image files. info->adjoin = MagickTrue; blob = ImagesToBlob(info, images, &length, &exception); if (exception.severity != UndefinedException) { magick_free((void*)blob); } rm_split(images); CHECK_EXCEPTION() (void) DestroyExceptionInfo(&exception); if (length == 0 || !blob) { return Qnil; } blob_str = rb_str_new(blob, (long)length); magick_free((void*)blob); return blob_str; }
VALUE Info_extract_eq(VALUE self, VALUE extract_arg) { Info *info; char *extr; volatile VALUE extract; Data_Get_Struct(self, Info, info); if (NIL_P(extract_arg)) { magick_free(info->extract); info->extract = NULL; return self; } extract = rm_to_s(extract_arg); extr = StringValuePtr(extract); if (!IsGeometry(extr)) { rb_raise(rb_eArgError, "invalid extract geometry: %s", extr); } magick_clone_string(&info->extract, extr); return self; }
/* Method: Info#density=<aString> Purpose: Set the text rendering density, e.g. "72x72" Raise: ArgumentError */ VALUE Info_density_eq(VALUE self, VALUE density_arg) { Info *info; volatile VALUE density; char *dens; Data_Get_Struct(self, Info, info); if (NIL_P(density_arg)) { magick_free(info->density); info->density = NULL; return self; } density = rm_to_s(density_arg); dens = StringValuePtr(density); if (!IsGeometry(dens)) { rb_raise(rb_eArgError, "invalid density geometry: %s", dens); } magick_clone_string(&info->density, dens); return self; }
VALUE Info_authenticate_eq(VALUE self, VALUE passwd) { Info *info; char *passwd_p = NULL; long passwd_l = 0; Data_Get_Struct(self, Info, info); if (!NIL_P(passwd)) { passwd_p = rm_str2cstr(passwd, &passwd_l); } if (info->authenticate) { magick_free(info->authenticate); info->authenticate = NULL; } if (passwd_l > 0) { magick_clone_string(&info->authenticate, passwd_p); } return self; }
/* Method: Image::Info#texture=texture_image Purpose: Set name of texture to tile onto the image background */ VALUE Info_texture_eq(VALUE self, VALUE texture) { Info *info; Image *image; char name[MaxTextExtent]; Data_Get_Struct(self, Info, info); // Delete any existing texture file if (info->texture) { rm_delete_temp_image(info->texture); magick_free(info->texture); info->texture = NULL; } // If argument is nil we're done if (texture == Qnil) { return self; } // Create a temp copy of the texture and store its name in the texture field image = rm_check_destroyed(texture); rm_write_temp_image(image, name); magick_clone_string(&info->texture, name); return self; }
/* Method: Info#size=<aString> Info#size=<aGeometry> Purpose: Set the size (a Geometry string, i.e. WxH{+-}x{+-}y) Raises: ArgumentError */ VALUE Info_size_eq(VALUE self, VALUE size_arg) { Info *info; volatile VALUE size; char *sz; Data_Get_Struct(self, Info, info); if (NIL_P(size_arg)) { magick_free(info->size); info->size = NULL; return self; } size = rm_to_s(size_arg); sz = StringValuePtr(size); if (!IsGeometry(sz)) { rb_raise(rb_eArgError, "invalid size geometry: %s", sz); } magick_clone_string(&info->size, sz); return self; }
VALUE Info_sampling_factor_eq(VALUE self, VALUE sampling_factor) { Info *info; char *sampling_factor_p = NULL; long sampling_factor_len = 0; Data_Get_Struct(self, Info, info); if (!NIL_P(sampling_factor)) { sampling_factor_p = rm_str2cstr(sampling_factor, &sampling_factor_len); } if (info->sampling_factor) { magick_free(info->sampling_factor); info->sampling_factor = NULL; } if (sampling_factor_len > 0) { magick_clone_string(&info->sampling_factor, sampling_factor_p); } return self; }
/* Method: Draw#draw(i) Purpose: Execute the stored drawing primitives on the current image image */ VALUE Draw_draw(VALUE self, VALUE image_arg) { Draw *draw; Image *image; image_arg = rm_cur_image(image_arg); image = rm_check_frozen(image_arg); Data_Get_Struct(self, Draw, draw); if (draw->primitives == 0) { rb_raise(rb_eArgError, "nothing to draw"); } // Point the DrawInfo structure at the current set of primitives. magick_clone_string(&(draw->info->primitive), StringValuePtr(draw->primitives)); (void) DrawImage(image, draw->info); rm_check_image_exception(image, RetainOnError); magick_free(draw->info->primitive); draw->info->primitive = NULL; return self; }
/** * Convert an image to a blob and the blob to a String. * * No Ruby usage (internal function) * * Notes: * - Returns Qnil if there is no image * * @param image the Image to convert * @return Ruby string representation of image * @see str_to_image */ static VALUE image_to_str(Image *image) { VALUE dimg = Qnil; unsigned char *blob; size_t length; Info *info; ExceptionInfo *exception; if (image) { info = CloneImageInfo(NULL); exception = AcquireExceptionInfo(); blob = ImageToBlob(info, image, &length, exception); DestroyImageInfo(info); CHECK_EXCEPTION(); DestroyExceptionInfo(exception); dimg = rb_str_new((char *)blob, (long)length); magick_free((void*)blob); } RB_GC_GUARD(dimg); return dimg; }
/* Static: destroy_Info Purpose: if there is a texture image, delete it before destroying the ImageInfo structure */ static void destroy_Info(void *infoptr) { Info *info = (Info *)infoptr; if (info->texture) { rm_delete_temp_image(info->texture); magick_free(info->texture); info->texture = NULL; } (void) DestroyImageInfo(info); }
VALUE Info_font_eq(VALUE self, VALUE font_arg) { Info *info; char *font; Data_Get_Struct(self, Info, info); if (NIL_P(font_arg) || StringValuePtr(font_arg) == NULL) { magick_free(info->font); info->font = NULL; } else { font = StringValuePtr(font_arg); magick_clone_string(&info->font, font); } return self; }
/* Method: Info#server_name=<aString> Purpose: Set the server name */ VALUE Info_server_name_eq(VALUE self, VALUE server_arg) { Info *info; char *server; Data_Get_Struct(self, Info, info); if (NIL_P(server_arg) || StringValuePtr(server_arg) == NULL) { magick_free(info->server_name); info->server_name = NULL; } else { server = StringValuePtr(server_arg); magick_clone_string(&info->server_name, server); } return self; }
/* Method: Info#view= Purpose: Set FlashPix viewing parameters */ VALUE Info_view_eq(VALUE self, VALUE view_arg) { Info *info; char *view; Data_Get_Struct(self, Info, info); if (NIL_P(view_arg) || StringValuePtr(view_arg) == NULL) { magick_free(info->view); info->view = NULL; } else { view = StringValuePtr(view_arg); magick_clone_string(&info->view, view); } return self; }
/* Static: image_to_str Purpose: Convert an image to a blob and the blob to a String Notes: Returns Qnil if there is no image */ static VALUE image_to_str(Image *image) { volatile VALUE dimg = Qnil; unsigned char *blob; size_t length; Info *info; ExceptionInfo exception; if (image) { info = CloneImageInfo(NULL); GetExceptionInfo(&exception); blob = ImageToBlob(info, image, &length, &exception); DestroyImageInfo(info); CHECK_EXCEPTION(); DestroyExceptionInfo(&exception); dimg = rb_str_new((char *)blob, (long)length); magick_free((void*)blob); } return dimg; }
/* Method: Draw#annotate(img, w, h, x, y, text) <{optional parms}> Purpose: annotates an image with text Returns: self Notes: Additional Draw attribute methods may be called in the optional block, which is executed in the context of an Draw object. */ VALUE Draw_annotate( VALUE self, VALUE image_arg, VALUE width_arg, VALUE height_arg, VALUE x_arg, VALUE y_arg, VALUE text) { Draw *draw; Image *image; unsigned long width, height; long x, y; AffineMatrix keep; char geometry_str[50]; // Save the affine matrix in case it is modified by // Draw#rotation= Data_Get_Struct(self, Draw, draw); keep = draw->info->affine; image_arg = rm_cur_image(image_arg); image = rm_check_frozen(image_arg); // If we have an optional parm block, run it in self's context, // allowing the app a chance to modify the object's attributes if (rb_block_given_p()) { (void)rb_obj_instance_eval(0, NULL, self); } // Translate & store in Draw structure #if defined(HAVE_INTERPRETIMAGEPROPERTIES) draw->info->text = InterpretImageProperties(NULL, image, StringValuePtr(text)); #else draw->info->text = InterpretImageAttributes(NULL, image, StringValuePtr(text)); #endif if (!draw->info->text) { rb_raise(rb_eArgError, "no text"); } // Create geometry string, copy to Draw structure, overriding // any previously existing value. width = NUM2ULONG(width_arg); height = NUM2ULONG(height_arg); x = NUM2LONG(x_arg); y = NUM2LONG(y_arg); if (width == 0 && height == 0) { sprintf(geometry_str, "%+ld%+ld", x, y); } // WxH is non-zero else { sprintf(geometry_str, "%lux%lu%+ld%+ld", width, height, x, y); } magick_clone_string(&draw->info->geometry, geometry_str); (void) AnnotateImage(image, draw->info); magick_free(draw->info->text); draw->info->text = NULL; draw->info->affine = keep; rm_check_image_exception(image, RetainOnError); return self; }