static guchar * wmf_get_pixbuf (const gchar *filename, gint *width, gint *height) { GMappedFile *file; guchar *pixels = NULL; /* the bits we need to decode the WMF via libwmf2's GD layer */ wmf_error_t err; gulong flags; wmf_gd_t *ddata = NULL; wmfAPI *API = NULL; wmfAPI_Options api_options; guint file_width; guint file_height; wmfD_Rect bbox; gint *gd_pixels = NULL; file = g_mapped_file_new (filename, FALSE, NULL); if (! file) return NULL; flags = WMF_OPT_IGNORE_NONFATAL | WMF_OPT_FUNCTION; api_options.function = wmf_gd_function; err = wmf_api_create (&API, flags, &api_options); if (err != wmf_E_None) goto _wmf_error; ddata = WMF_GD_GetData (API); ddata->type = wmf_gd_image; err = wmf_mem_open (API, (guchar *) g_mapped_file_get_contents (file), g_mapped_file_get_length (file)); if (err != wmf_E_None) goto _wmf_error; err = wmf_scan (API, 0, &bbox); if (err != wmf_E_None) goto _wmf_error; err = wmf_display_size (API, &file_width, &file_height, WMF_DEFAULT_RESOLUTION, WMF_DEFAULT_RESOLUTION); if (err != wmf_E_None || file_width <= 0 || file_height <= 0) goto _wmf_error; if (!*width || !*height) goto _wmf_error; /* either both arguments negative or none */ if ((*width * *height) < 0) goto _wmf_error; ddata->bbox = bbox; if (*width > 0) { ddata->width = *width; ddata->height = *height; } else { gdouble w = file_width; gdouble h = file_height; gdouble aspect = ((gdouble) *width) / (gdouble) *height; if (aspect > (w / h)) { ddata->height = abs (*height); ddata->width = (gdouble) abs (*width) * (w / h) + 0.5; } else { ddata->width = abs (*width); ddata->height = (gdouble) abs (*height) / (w / h) + 0.5; } } err = wmf_play (API, 0, &bbox); if (err != wmf_E_None) goto _wmf_error; if (ddata->gd_image != NULL) gd_pixels = wmf_gd_image_pixels (ddata->gd_image); if (gd_pixels == NULL) goto _wmf_error; pixels = pixbuf_gd_convert (gd_pixels, ddata->width, ddata->height); if (pixels == NULL) goto _wmf_error; *width = ddata->width; *height = ddata->height; _wmf_error: if (API) { wmf_mem_close (API); wmf_api_destroy (API); } g_mapped_file_unref (file); return pixels; }
static guchar * wmf_load_file (const gchar *filename, guint *width, guint *height, GError **error) { GMappedFile *file; guchar *pixels = NULL; /* the bits we need to decode the WMF via libwmf2's GD layer */ wmf_error_t err; gulong flags; wmf_gd_t *ddata = NULL; wmfAPI *API = NULL; wmfAPI_Options api_options; wmfD_Rect bbox; gint *gd_pixels = NULL; *width = *height = -1; file = g_mapped_file_new (filename, FALSE, error); if (! file) return NULL; flags = WMF_OPT_IGNORE_NONFATAL | WMF_OPT_FUNCTION; api_options.function = wmf_gd_function; err = wmf_api_create (&API, flags, &api_options); if (err != wmf_E_None) goto _wmf_error; ddata = WMF_GD_GetData (API); ddata->type = wmf_gd_image; err = wmf_mem_open (API, (guchar *) g_mapped_file_get_contents (file), g_mapped_file_get_length (file)); if (err != wmf_E_None) goto _wmf_error; err = wmf_scan (API, 0, &bbox); if (err != wmf_E_None) goto _wmf_error; err = wmf_display_size (API, width, height, load_vals.resolution, load_vals.resolution); if (err != wmf_E_None || *width <= 0 || *height <= 0) goto _wmf_error; if (load_vals.width > 0 && load_vals.height > 0) { *width = load_vals.width; *height = load_vals.height; } ddata->bbox = bbox; ddata->width = *width; ddata->height = *height; err = wmf_play (API, 0, &bbox); if (err != wmf_E_None) goto _wmf_error; if (ddata->gd_image != NULL) gd_pixels = wmf_gd_image_pixels (ddata->gd_image); if (gd_pixels == NULL) goto _wmf_error; pixels = pixbuf_gd_convert (gd_pixels, *width, *height); if (pixels == NULL) goto _wmf_error; _wmf_error: if (API) { wmf_mem_close (API); wmf_api_destroy (API); } g_mapped_file_unref (file); /* FIXME: improve error message */ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Could not open '%s' for reading"), gimp_filename_to_utf8 (filename)); return pixels; }
UT_Error IE_ImpGraphic_WMF::convertGraphic(UT_ByteBuf* pBBwmf, UT_ByteBuf** ppBBpng) { UT_ByteBuf * pBBpng = 0; wmf_error_t err; wmf_gd_t * ddata = 0; wmfAPI * API = 0; wmfAPI_Options api_options; wmfD_Rect bbox; unsigned long flags; #if 0 // the code that uses these two variables is in an if 0 block below unsigned int max_width = 500; unsigned int max_height = 500; #endif unsigned int width, height; bbuf_read_info read_info; bbuf_write_info write_info; if (!pBBwmf) { UT_DEBUGMSG(("IE_ImpGraphic_WMF::convertGraphic Bad Arg (1)\n")); return UT_ERROR; } if (!ppBBpng) { UT_DEBUGMSG(("IE_ImpGraphic_WMF::convertGraphic Bad Arg (2)\n")); return UT_ERROR; } *ppBBpng = 0; flags = WMF_OPT_IGNORE_NONFATAL | WMF_OPT_FUNCTION; api_options.function = wmf_gd_function; err = wmf_api_create(&API,flags,&api_options); if (err != wmf_E_None) { UT_DEBUGMSG(("IE_ImpGraphic_WMF::convertGraphic No API\n")); return UT_ERROR; } ddata = WMF_GD_GetData(API); if ((ddata->flags & WMF_GD_SUPPORTS_PNG) == 0) { // Impossible, but... UT_DEBUGMSG(("IE_ImpGraphic_WMF::convertGraphic No PNG\n")); wmf_api_destroy(API); return UT_ERROR; } read_info.pByteBuf = pBBwmf; read_info.len = pBBwmf->getLength(); read_info.pos = 0; err = wmf_bbuf_input (API,AbiWord_WMF_read,AbiWord_WMF_seek,AbiWord_WMF_tell,(void *) &read_info); if (err != wmf_E_None) { UT_DEBUGMSG(("IE_ImpGraphic_WMF::convertGraphic Bad input set\n")); wmf_api_destroy(API); return UT_ERROR; } err = wmf_scan (API,0,&bbox); if (err != wmf_E_None) { UT_DEBUGMSG(("IE_ImpGraphic_WMF::convertGraphic Scan failed\n")); wmf_api_destroy(API); return UT_ERROR; } /* TODO: be smarter about getting the resolution from screen */ double resolution_x, resolution_y; resolution_x = resolution_y = 72.0; err = wmf_display_size (API, &width, &height, resolution_x, resolution_y); if (err != wmf_E_None) { UT_DEBUGMSG(("IE_ImpGraphic_WMF::convertGraphic Get size failed\n")); wmf_api_destroy(API); return UT_ERROR; } ddata->width = (unsigned int) width; ddata->height = (unsigned int) height; if ((ddata->width == 0) || (ddata->height == 0)) { UT_DEBUGMSG(("IE_ImpGraphic_WMF::convertGraphic Size error (1)\n")); wmf_api_destroy(API); return UT_ERROR; } #if 0 // not sure if this branch is needed any more after the recent changes // done by FJF and myself inside of libWMF for better size detection - DAL if ((ddata->width >= max_width) || (ddata->height >= max_height)) { float ratio_wmf = height / width; float ratio_bounds = (float) max_height / (float) max_width; if (ratio_wmf > ratio_bounds) { ddata->height = max_height; ddata->width = (unsigned int) ((float) ddata->height / ratio_wmf); } else { ddata->width = max_width; ddata->height = (unsigned int) ((float) ddata->width * ratio_wmf); } } #endif if ((ddata->width == 0) || (ddata->height == 0)) { UT_DEBUGMSG(("IE_ImpGraphic_WMF::convertGraphic Size error (1)\n")); wmf_api_destroy(API); return UT_ERROR; } ddata->bbox = bbox; ddata->type = wmf_gd_png; pBBpng = new UT_ByteBuf; if (pBBpng == 0) { UT_DEBUGMSG(("IE_ImpGraphic_WMF::convertGraphic Ins. Mem.\n")); wmf_api_destroy(API); return UT_IE_NOMEMORY; } write_info.pByteBuf = pBBpng; ddata->flags |= WMF_GD_OUTPUT_MEMORY | WMF_GD_OWN_BUFFER; ddata->sink.context = (void *) &write_info; ddata->sink.function = AbiWord_WMF_function; err = wmf_play(API,0,&bbox); if (err != wmf_E_None) { UT_DEBUGMSG(("IE_ImpGraphic_WMF::convertGraphic Play failed\n")); } err = wmf_api_destroy(API); if (err == wmf_E_None) { *ppBBpng = pBBpng; return UT_OK; } UT_DEBUGMSG(("IE_ImpGraphic_WMF::convertGraphic Err. on destroy\n")); DELETEP(pBBpng); return UT_ERROR; }
UT_Error IE_ImpGraphic_WMF::convertGraphicToSVG(UT_ByteBuf* pBBwmf, UT_ByteBuf** ppBB) { int status = 0; unsigned int disp_width = 0; unsigned int disp_height = 0; float wmf_width; float wmf_height; float ratio_wmf; float ratio_bounds; unsigned long flags; unsigned int max_width = 768; unsigned int max_height = 512; unsigned long max_flags = 0; static const char* Default_Description = "wmf2svg"; wmf_error_t err; wmf_svg_t* ddata = 0; wmfAPI* API = 0; wmfD_Rect bbox; wmfAPI_Options api_options; bbuf_read_info read_info; char *stream = NULL; unsigned long stream_len = 0; *ppBB = 0; flags = 0; flags = WMF_OPT_IGNORE_NONFATAL | WMF_OPT_FUNCTION; api_options.function = wmf_svg_function; err = wmf_api_create (&API,flags,&api_options); status = explicit_wmf_error ("wmf_api_create",err); if (status) { if (API) wmf_api_destroy (API); return (UT_ERROR); } read_info.pByteBuf = pBBwmf; read_info.len = pBBwmf->getLength(); read_info.pos = 0; err = wmf_bbuf_input (API,AbiWord_WMF_read,AbiWord_WMF_seek,AbiWord_WMF_tell,(void *) &read_info); if (err != wmf_E_None) { UT_DEBUGMSG(("IE_ImpGraphic_WMF::convertGraphic Bad input set\n")); goto ErrorHandler; } err = wmf_scan (API,0,&(bbox)); status = explicit_wmf_error ("wmf_scan",err); if (status) { goto ErrorHandler; } /* Okay, got this far, everything seems cool. */ ddata = WMF_SVG_GetData (API); ddata->out = wmf_stream_create(API, NULL); ddata->Description = (char *)Default_Description; ddata->bbox = bbox; wmf_display_size (API,&disp_width,&disp_height,72,72); wmf_width = (float) disp_width; wmf_height = (float) disp_height; if ((wmf_width <= 0) || (wmf_height <= 0)) { fputs ("Bad image size - but this error shouldn't occur...\n",stderr); status = 1; wmf_api_destroy (API); return UT_ERROR; } if ((wmf_width > (float) max_width ) || (wmf_height > (float) max_height)) { if (max_flags == 0) max_flags = WMF2SVG_MAXPECT; } if (max_flags == WMF2SVG_MAXPECT) /* scale the image */ { ratio_wmf = wmf_height / wmf_width; ratio_bounds = (float) max_height / (float) max_width; if (ratio_wmf > ratio_bounds) { ddata->height = max_height; ddata->width = (unsigned int) ((float) ddata->height / ratio_wmf); } else { ddata->width = max_width; ddata->height = (unsigned int) ((float) ddata->width * ratio_wmf); } } else if (max_flags == WMF2SVG_MAXSIZE) /* bizarre option, really */ { ddata->width = max_width; ddata->height = max_height; } else { ddata->width = (unsigned int) ceil ((double) wmf_width ); ddata->height = (unsigned int) ceil ((double) wmf_height); } ddata->flags |= WMF_SVG_INLINE_IMAGES; ddata->flags |= WMF_GD_OUTPUT_MEMORY | WMF_GD_OWN_BUFFER; if (status == 0) { err = wmf_play (API,0,&(bbox)); status = explicit_wmf_error ("wmf_play",err); } wmf_stream_destroy(API, ddata->out, &stream, &stream_len); if (status == 0) { UT_ByteBuf* pBB = new UT_ByteBuf; pBB->append((const UT_Byte*)stream, (UT_uint32)stream_len); *ppBB = pBB; DELETEP(pBBwmf); wmf_free(API, stream); wmf_api_destroy (API); return UT_OK; } ErrorHandler: DELETEP(pBBwmf); if(API) { if(stream) { wmf_free(API, stream); } wmf_api_destroy (API); } return UT_ERROR; }
static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception) { char filename[MaxTextExtent]; int unique_file; FILE *file; Image *image; ImageInfo *read_info; MagickBooleanType status; unsigned long flags; wmfAPI *wmf_info; wmfAPI_Options options; wmfD_Rect bounding_box; wmf_eps_t *eps_info; wmf_error_t wmf_status; /* Read WMF image. */ image=AcquireImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } wmf_info=(wmfAPI *) NULL; flags=0; flags|=WMF_OPT_IGNORE_NONFATAL; flags|=WMF_OPT_FUNCTION; options.function=wmf_eps_function; wmf_status=wmf_api_create(&wmf_info,flags,&options); if (wmf_status != wmf_E_None) { if (wmf_info != (wmfAPI *) NULL) wmf_api_destroy(wmf_info); ThrowReaderException(DelegateError,"UnableToInitializeWMFLibrary"); } wmf_status=wmf_bbuf_input(wmf_info,WMFReadBlob,WMFSeekBlob,WMFTellBlob, (void *) image); if (wmf_status != wmf_E_None) { wmf_api_destroy(wmf_info); ThrowFileException(exception,FileOpenError,"UnableToOpenFile", image->filename); image=DestroyImageList(image); return((Image *) NULL); } wmf_status=wmf_scan(wmf_info,0,&bounding_box); if (wmf_status != wmf_E_None) { wmf_api_destroy(wmf_info); ThrowReaderException(DelegateError,"FailedToScanFile"); } eps_info=WMF_EPS_GetData(wmf_info); file=(FILE *) NULL; unique_file=AcquireUniqueFileResource(filename); if (unique_file != -1) file=fdopen(unique_file,"wb"); if ((unique_file == -1) || (file == (FILE *) NULL)) { wmf_api_destroy(wmf_info); ThrowReaderException(FileOpenError,"UnableToCreateTemporaryFile"); } eps_info->out=wmf_stream_create(wmf_info,file); eps_info->bbox=bounding_box; wmf_status=wmf_play(wmf_info,0,&bounding_box); if (wmf_status != wmf_E_None) { wmf_api_destroy(wmf_info); ThrowReaderException(DelegateError,"FailedToRenderFile"); } (void) fclose(file); wmf_api_destroy(wmf_info); (void) CloseBlob(image); image=DestroyImage(image); /* Read EPS image. */ read_info=CloneImageInfo(image_info); (void) FormatMagickString(read_info->filename,MaxTextExtent,"eps:%.1024s", filename); image=ReadImage(read_info,exception); read_info=DestroyImageInfo(read_info); if (image != (Image *) NULL) { (void) CopyMagickString(image->filename,image_info->filename, MaxTextExtent); (void) CopyMagickString(image->magick_filename,image_info->filename, MaxTextExtent); (void) CopyMagickString(image->magick,"WMF",MaxTextExtent); } (void) RelinquishUniqueFileResource(filename); return(GetFirstImageInList(image)); }
static gboolean gdk_pixbuf__wmf_image_stop_load (gpointer data, GError **error) { /* will be used to represent the WMF in-memory * during the decoding process */ WmfContext *context = (WmfContext *)data; gboolean result = FALSE; guchar *pixels = NULL; GdkPixbuf *pixbuf = NULL; /* the bits we need to decode the WMF via libwmf2's GD layer */ wmf_error_t err; unsigned long flags; wmf_gd_t *ddata = NULL; wmfAPI *API = NULL; wmfAPI_Options api_options; wmfD_Rect bbox; int *gd_pixels = NULL; /* the natural width and height of the WMF or the user-specified with+height */ gint width, height; double resolution_x, resolution_y; if (error != NULL) *error = NULL; /* TODO: be smarter about getting the resolution from screen */ resolution_x = resolution_y = 72.0; width = height = -1; flags = WMF_OPT_IGNORE_NONFATAL | WMF_OPT_FUNCTION; api_options.function = wmf_gd_function; err = wmf_api_create (&API, flags, &api_options); if (err != wmf_E_None) { g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, "Couldn't create WMF reader"); goto _wmf_error; } ddata = WMF_GD_GetData (API); ddata->type = wmf_gd_image; err = wmf_mem_open (API, context->data->data, context->data->len); if (err != wmf_E_None) { g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_FAILED, "Couldn't create reader API"); goto _wmf_error; } err = wmf_scan (API, 0, &bbox); if (err != wmf_E_None) { g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, "Error scanning WMF file"); goto _wmf_error; } /* find out how large the app wants the pixbuf to be */ if (context->size_func != NULL) (*context->size_func) (&width, &height, context->user_data); /* if these are <= 0, assume user wants the natural size of the wmf */ if (width <= 0 || height <= 0) { err = wmf_display_size (API, &width, &height, resolution_x, resolution_y); if (err != wmf_E_None || width <= 0 || height <= 0) { g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, "Couldn't determine image size"); goto _wmf_error; } } ddata->bbox = bbox; ddata->width = width; ddata->height = height; err = wmf_play (API, 0, &bbox); if (err != wmf_E_None) { g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, "Couldn't decode WMF file into pixbuf"); goto _wmf_error; } wmf_mem_close (API); if (ddata->gd_image != NULL) gd_pixels = wmf_gd_image_pixels (ddata->gd_image); if (gd_pixels == NULL) { g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, "Couldn't decode WMF file - no output (huh?)"); goto _wmf_error; } pixels = pixbuf_gd_convert (gd_pixels, width, height); if (pixels == NULL) { g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, "Couldn't create RGBA buffer"); goto _wmf_error; } wmf_api_destroy (API); API = NULL; pixbuf = gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB, TRUE, 8, width, height, width * 4, pixbuf_destroy_function, NULL); if (pixbuf == NULL) { g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, "Couldn't decode WMF file"); goto _wmf_error; } if (context->prepared_func != NULL) (* context->prepared_func) (pixbuf, NULL, context->user_data); if (context->updated_func != NULL) (* context->updated_func) (pixbuf, 0, 0, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), context->user_data); result = TRUE; _wmf_error: if (API != NULL) wmf_api_destroy (API); g_byte_array_free (context->data, TRUE); g_free (context); return result; }
int wmf2svg_draw (PlotData* pdata) { int status = 0; float wmf_width; float wmf_height; float ratio_wmf; float ratio_bounds; unsigned long flags; unsigned long max_flags; static char* Default_Description = "wmf2svg"; ImageContext IC; wmf_error_t err; wmf_svg_t* ddata = 0; wmfAPI* API = 0; wmfAPI_Options api_options; flags = 0; flags |= WMF_OPT_FUNCTION; api_options.function = wmf_svg_function; flags |= WMF_OPT_ARGS; api_options.argc = pdata->argc; api_options.argv = pdata->argv; #ifndef DEBUG flags |= WMF_OPT_IGNORE_NONFATAL; #endif err = wmf_api_create (&API,flags,&api_options); status = explicit_wmf_error ("wmf_api_create",err); if (status) { if (API) wmf_api_destroy (API); return (status); } err = wmf_file_open (API,pdata->wmf_filename); status = explicit_wmf_error ("wmf_file_open",err); if (status) { wmf_api_destroy (API); return (status); } err = wmf_scan (API,0,&(pdata->options.bbox)); status = explicit_wmf_error ("wmf_scan",err); if (status) { wmf_api_destroy (API); return (status); } /* Okay, got this far, everything seems cool. */ ddata = WMF_SVG_GetData (API); if (pdata->out) { ddata->out = wmf_stream_create (API,pdata->out); } else { ddata->out = wmf_ztream_create (API,pdata->outz); } if (pdata->options.Description) ddata->Description = pdata->options.Description; else ddata->Description = Default_Description; ddata->bbox = pdata->options.bbox; wmf_size (API,&wmf_width,&wmf_height); if ((wmf_width <= 0) || (wmf_height <= 0)) { fputs ("Bad image size - but this error shouldn't occur...\n",stderr); status = 1; wmf_api_destroy (API); return (status); } max_flags = pdata->max_flags; if ((wmf_width > (float) pdata->max_width ) || (wmf_height > (float) pdata->max_height)) { if (max_flags == 0) max_flags = WMF2SVG_MAXPECT; } if (max_flags == WMF2SVG_MAXPECT) /* scale the image */ { ratio_wmf = wmf_height / wmf_width; ratio_bounds = (float) pdata->max_height / (float) pdata->max_width; if (ratio_wmf > ratio_bounds) { ddata->height = pdata->max_height; ddata->width = (unsigned int) ((float) ddata->height / ratio_wmf); } else { ddata->width = pdata->max_width; ddata->height = (unsigned int) ((float) ddata->width * ratio_wmf); } } else if (max_flags == WMF2SVG_MAXSIZE) /* bizarre option, really */ { ddata->width = pdata->max_width; ddata->height = pdata->max_height; } else { ddata->width = (unsigned int) ceil ((double) wmf_width ); ddata->height = (unsigned int) ceil ((double) wmf_height); } if (pdata->inline_images) { ddata->flags |= WMF_SVG_INLINE_IMAGES; } else { IC.number = 0; IC.prefix = (char*) malloc (strlen (pdata->wmf_filename) + 1); if (IC.prefix) { strcpy (IC.prefix,pdata->wmf_filename); if (wmf_strstr (pdata->wmf_filename,".wmf")) { IC.prefix[strlen (pdata->wmf_filename)-4] = 0; } ddata->image.context = (void*) (&IC); ddata->image.name = image_name; } } if (status == 0) { err = wmf_play (API,0,&(pdata->options.bbox)); status = explicit_wmf_error ("wmf_play",err); } wmf_api_destroy (API); return (status); }