You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
362 lines
7.5 KiB
362 lines
7.5 KiB
15 years ago
|
/* libwmf (convert/wmf2gd.c): library for wmf conversion
|
||
|
Copyright (C) 2000 - various; see CREDITS, ChangeLog, and sources
|
||
|
|
||
|
The libwmf Library is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU Library General Public License as
|
||
|
published by the Free Software Foundation; either version 2 of the
|
||
|
License, or (at your option) any later version.
|
||
|
|
||
|
The libwmf Library is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
Library General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU Library General Public
|
||
|
License along with the libwmf Library; see the file COPYING. If not,
|
||
|
write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
Boston, MA 02110-1301, USA. */
|
||
|
|
||
|
|
||
|
#include <cstdio>
|
||
|
#include <cstdlib>
|
||
|
#include <cstring>
|
||
|
#include <cctype>
|
||
|
#include <cmath>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#include "ksquirrel-libs/fmt_types.h"
|
||
|
#include "ksquirrel-libs/fmt_defs.h"
|
||
|
|
||
|
#include <libwmf/fund.h>
|
||
|
#include <libwmf/types.h>
|
||
|
#include <libwmf/api.h>
|
||
|
#include <libwmf/ipa.h>
|
||
|
#include <libwmf/font.h>
|
||
|
#include <libwmf/color.h>
|
||
|
#include <libwmf/macro.h>
|
||
|
|
||
|
#include <libwmf/gd.h>
|
||
|
|
||
|
typedef struct
|
||
|
{ int argc;
|
||
|
char** argv;
|
||
|
|
||
|
char* wmf_filename;
|
||
|
char* gd_filename;
|
||
|
|
||
|
wmf_gd_t options;
|
||
|
|
||
|
unsigned int max_width;
|
||
|
unsigned int max_height;
|
||
|
|
||
|
unsigned long max_flags;
|
||
|
|
||
|
} PlotData;
|
||
|
|
||
|
#define WMF2GD_MAXPECT (1 << 0)
|
||
|
#define WMF2GD_MAXSIZE (1 << 1)
|
||
|
|
||
|
int wmf2gd_draw (PlotData*, unsigned char **buf, int *w, int *h);
|
||
|
|
||
|
void wmf2gd_init (PlotData*,int,char**);
|
||
|
int wmf2gd_args (PlotData*);
|
||
|
int wmf2gd_file (PlotData*, unsigned char **buf, int *w, int *h);
|
||
|
|
||
|
int call(int argc,char** argv, unsigned char **buf, int *w, int *h);
|
||
|
|
||
|
int explicit_wmf_error(wmf_error_t);
|
||
|
|
||
|
int wmf2gd_draw (PlotData* pdata, unsigned char **buf, int *www, int *hhh)
|
||
|
{
|
||
|
int status = 0;
|
||
|
|
||
|
float wmf_width;
|
||
|
float wmf_height;
|
||
|
|
||
|
float ratio_wmf;
|
||
|
float ratio_bounds;
|
||
|
|
||
|
unsigned int disp_width = 0;
|
||
|
unsigned int disp_height = 0;
|
||
|
|
||
|
unsigned long flags;
|
||
|
unsigned long max_flags;
|
||
|
|
||
|
wmf_error_t err;
|
||
|
|
||
|
wmf_gd_t* ddata = 0;
|
||
|
|
||
|
wmfAPI* API = 0;
|
||
|
|
||
|
wmfAPI_Options api_options;
|
||
|
|
||
|
flags = 0;
|
||
|
|
||
|
flags |= WMF_OPT_FUNCTION;
|
||
|
api_options.function = wmf_gd_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 (err);
|
||
|
|
||
|
if (status)
|
||
|
{ if (API) wmf_api_destroy (API);
|
||
|
return (status);
|
||
|
}
|
||
|
|
||
|
ddata = WMF_GD_GetData (API);
|
||
|
|
||
|
err = wmf_file_open(API, pdata->wmf_filename);
|
||
|
status = explicit_wmf_error (err);
|
||
|
|
||
|
if (status)
|
||
|
{
|
||
|
wmf_api_destroy (API);
|
||
|
return (status);
|
||
|
}
|
||
|
|
||
|
err = wmf_scan (API, 0, &(pdata->options.bbox));
|
||
|
status = explicit_wmf_error (err);
|
||
|
|
||
|
if (status)
|
||
|
{
|
||
|
wmf_api_destroy (API);
|
||
|
return (status);
|
||
|
}
|
||
|
|
||
|
/* Okay, got this far, everything seems cool.
|
||
|
*/
|
||
|
ddata->type = pdata->options.type;
|
||
|
|
||
|
ddata->flags |= WMF_GD_OUTPUT_MEMORY;
|
||
|
ddata->file = pdata->options.file;
|
||
|
|
||
|
ddata->bbox = pdata->options.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))
|
||
|
{
|
||
|
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 = WMF2GD_MAXPECT;
|
||
|
|
||
|
if (max_flags == WMF2GD_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 == WMF2GD_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 (status == 0)
|
||
|
{
|
||
|
err = wmf_play(API, 0, &(pdata->options.bbox));
|
||
|
status = explicit_wmf_error (err);
|
||
|
}
|
||
|
|
||
|
wmf_api_destroy(API);
|
||
|
|
||
|
int *p = wmf_gd_image_pixels(ddata->gd_image);
|
||
|
unsigned int w, h;
|
||
|
|
||
|
unsigned int pixel;
|
||
|
unsigned char r, g, b, a;
|
||
|
|
||
|
*buf = new u8 [ddata->height * ddata->width * sizeof(RGBA)];
|
||
|
|
||
|
if(!*buf)
|
||
|
return 1;
|
||
|
|
||
|
unsigned char *pss = *buf;
|
||
|
|
||
|
for (h = 0; h < ddata->height; h++)
|
||
|
for (w = 0; w < ddata->width; w++)
|
||
|
{
|
||
|
pixel = (unsigned int) (*p++);
|
||
|
|
||
|
b = (unsigned char) (pixel & 0xff);
|
||
|
pixel >>= 8;
|
||
|
g = (unsigned char) (pixel & 0xff);
|
||
|
pixel >>= 8;
|
||
|
r = (unsigned char) (pixel & 0xff);
|
||
|
pixel >>= 7;
|
||
|
a = (unsigned char) (pixel & 0xfe);
|
||
|
a ^= 0xff;
|
||
|
|
||
|
*pss++ = r;
|
||
|
*pss++ = g;
|
||
|
*pss++ = b;
|
||
|
*pss++ = a;
|
||
|
}
|
||
|
|
||
|
*www = ddata->width;
|
||
|
*hhh = ddata->height;
|
||
|
|
||
|
free(ddata->gd_image);
|
||
|
|
||
|
if(ddata->memory)
|
||
|
free(ddata->memory);
|
||
|
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
void wmf2gd_init(PlotData *pdata, int argc, char **argv)
|
||
|
{
|
||
|
pdata->argc = argc;
|
||
|
pdata->argv = argv;
|
||
|
|
||
|
pdata->wmf_filename = 0;
|
||
|
pdata->gd_filename = 0;
|
||
|
|
||
|
pdata->options.type = wmf_gd_png;
|
||
|
|
||
|
pdata->options.file = 0;
|
||
|
|
||
|
pdata->options.width = 0;
|
||
|
pdata->options.height = 0;
|
||
|
|
||
|
pdata->options.flags = 0;
|
||
|
|
||
|
pdata->max_width = 768;
|
||
|
pdata->max_height = 512;
|
||
|
|
||
|
pdata->max_flags = 0;
|
||
|
}
|
||
|
|
||
|
int wmf2gd_args (PlotData* pdata)
|
||
|
{
|
||
|
int status = 0;
|
||
|
int arg = 0;
|
||
|
|
||
|
int argc = pdata->argc;
|
||
|
char** argv = pdata->argv;
|
||
|
|
||
|
while ((++arg) < argc)
|
||
|
{
|
||
|
if (strcmp (argv[arg],"-o") == 0)
|
||
|
{ if ((++arg) < argc)
|
||
|
{ pdata->gd_filename = argv[arg];
|
||
|
continue;
|
||
|
}
|
||
|
fprintf (stderr,"usage: `wmf2gd -o <file.gd> <file.wmf>'.\n");
|
||
|
fprintf (stderr,"Try `%s --help' for more information.\n",argv[0]);
|
||
|
status = arg;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (argv[arg][0] != '-')
|
||
|
{ pdata->wmf_filename = argv[arg];
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
fprintf (stderr,"option `%s' not recognized.\n",argv[arg]);
|
||
|
fprintf (stderr,"Try `%s --help' for more information.\n",argv[0]);
|
||
|
status = arg;
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (status == 0)
|
||
|
{ if(pdata->wmf_filename == 0)
|
||
|
{
|
||
|
fprintf (stderr,"No input file specified!\n");
|
||
|
fprintf (stderr,"Try `%s --help' for more information.\n",argv[0]);
|
||
|
status = argc;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pdata->options.type = wmf_gd_image;
|
||
|
|
||
|
return (status);
|
||
|
}
|
||
|
|
||
|
int wmf2gd_file(PlotData* pdata, unsigned char **buf, int *w, int *h)
|
||
|
{
|
||
|
int status = 0;
|
||
|
|
||
|
pdata->options.file = stdout;
|
||
|
|
||
|
status = wmf2gd_draw(pdata, buf, w, h);
|
||
|
|
||
|
if(pdata->options.file != stdout)
|
||
|
fclose(pdata->options.file);
|
||
|
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
int call(int argc, char **argv, unsigned char **buf, int *w, int *h)
|
||
|
{
|
||
|
int status = 0;
|
||
|
|
||
|
PlotData PData;
|
||
|
|
||
|
wmf2gd_init(&PData, argc, argv);
|
||
|
|
||
|
status = wmf2gd_args(&PData);
|
||
|
|
||
|
if(status)
|
||
|
return status;
|
||
|
|
||
|
status = wmf2gd_file(&PData, buf, w, h);
|
||
|
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
int explicit_wmf_error (wmf_error_t err)
|
||
|
{
|
||
|
int status = 0;
|
||
|
|
||
|
switch (err)
|
||
|
{
|
||
|
case wmf_E_None:
|
||
|
status = 0;
|
||
|
break;
|
||
|
|
||
|
case wmf_E_InsMem:
|
||
|
case wmf_E_BadFile:
|
||
|
case wmf_E_BadFormat:
|
||
|
case wmf_E_EOF:
|
||
|
case wmf_E_DeviceError:
|
||
|
case wmf_E_Glitch:
|
||
|
case wmf_E_Assert:
|
||
|
status = 1;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
status = 1;
|
||
|
}
|
||
|
|
||
|
return status;
|
||
|
}
|