#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <gimp-print/gimp-print.h>
#include "gimp-print-internal.h"
#include <gimp-print/gimp-print-intl-internal.h>
#include <math.h>
#include <limits.h>
#if defined(HAVE_VARARGS_H) && !defined(HAVE_STDARG_H)
#include <varargs.h>
#else
#include <stdarg.h>
#endif
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define FMIN(a, b) ((a) < (b) ? (a) : (b))
typedef struct stp_internal_option
{
char *name;
size_t length;
char *data;
struct stp_internal_option *next;
struct stp_internal_option *prev;
} stp_internal_option_t;
typedef struct
{
const char *output_to,
*driver,
*ppd_file,
*resolution,
*media_size,
*media_type,
*media_source,
*ink_type,
*dither_algorithm;
int output_type;
float brightness;
float scaling;
int orientation,
left,
top;
float gamma;
float contrast,
cyan,
magenta,
yellow;
float saturation;
float density;
int image_type;
int unit;
float app_gamma;
int page_width;
int page_height;
int input_color_model;
int output_color_model;
int page_number;
stp_job_mode_t job_mode;
void *lut;
void *driver_data;
unsigned char *cmap;
void (*outfunc)(void *data, const char *buffer, size_t bytes);
void *outdata;
void (*errfunc)(void *data, const char *buffer, size_t bytes);
void *errdata;
stp_internal_option_t *options;
int verified;
} stp_internal_vars_t;
typedef struct stp_internal_printer
{
const char *long_name,
*driver;
int model;
const stp_printfuncs_t *printfuncs;
stp_internal_vars_t printvars;
} stp_internal_printer_t;
typedef struct
{
const char *name;
const char *text;
unsigned width;
unsigned height;
unsigned top;
unsigned left;
unsigned bottom;
unsigned right;
stp_papersize_unit_t paper_unit;
} stp_internal_papersize_t;
static const stp_internal_vars_t default_vars =
{
"",
N_ ("ps2"),
"",
"",
"",
"",
"",
"",
"",
OUTPUT_COLOR,
1.0,
100.0,
-1,
-1,
-1,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
IMAGE_CONTINUOUS,
0,
1.0,
0,
0,
COLOR_MODEL_RGB,
COLOR_MODEL_RGB,
0,
STP_JOB_MODE_PAGE
};
static const stp_internal_vars_t min_vars =
{
"",
N_ ("ps2"),
"",
"",
"",
"",
"",
"",
"",
0,
0,
5.0,
-1,
-1,
-1,
0.1,
0,
0,
0,
0,
0,
.1,
0,
0,
1.0,
0,
0,
0,
0,
0,
STP_JOB_MODE_PAGE
};
static const stp_internal_vars_t max_vars =
{
"",
N_ ("ps2"),
"",
"",
"",
"",
"",
"",
"",
OUTPUT_RAW_CMYK,
2.0,
100.0,
-1,
-1,
-1,
4.0,
4.0,
4.0,
4.0,
4.0,
9.0,
2.0,
NIMAGE_TYPES - 1,
1,
1.0,
0,
0,
NCOLOR_MODELS - 1,
NCOLOR_MODELS - 1,
INT_MAX,
STP_JOB_MODE_JOB
};
stp_vars_t
stp_allocate_vars(void)
{
void *retval = stp_zalloc(sizeof(stp_internal_vars_t));
stp_copy_vars(retval, (stp_vars_t)&default_vars);
return (retval);
}
#define SAFE_FREE(x) \
do \
{ \
if ((x)) \
stp_free((char *)(x)); \
((x)) = NULL; \
} while (0)
static char *
c_strdup(const char *s)
{
char *ret;
if (!s)
{
ret = stp_malloc(1);
ret[0] = 0;
return ret;
}
else
{
ret = stp_malloc(strlen(s) + 1);
strcpy(ret, s);
return ret;
}
}
static char *
c_strndup(const char *s, int n)
{
char *ret;
if (!s || n < 0)
{
ret = stp_malloc(1);
ret[0] = 0;
return ret;
}
else
{
ret = stp_malloc(n + 1);
strncpy(ret, s, n);
ret[n] = 0;
return ret;
}
}
void
stp_free_vars(stp_vars_t vv)
{
stp_internal_vars_t *v = (stp_internal_vars_t *) vv;
SAFE_FREE(v->output_to);
SAFE_FREE(v->driver);
SAFE_FREE(v->ppd_file);
SAFE_FREE(v->resolution);
SAFE_FREE(v->media_size);
SAFE_FREE(v->media_type);
SAFE_FREE(v->media_source);
SAFE_FREE(v->ink_type);
SAFE_FREE(v->dither_algorithm);
}
#define DEF_STRING_FUNCS(s) \
void \
stp_set_##s(stp_vars_t vv, const char *val) \
{ \
stp_internal_vars_t *v = (stp_internal_vars_t *) vv; \
if (v->s == val) \
return; \
SAFE_FREE(v->s); \
v->s = c_strdup(val); \
v->verified = 0; \
} \
\
void \
stp_set_##s##_n(stp_vars_t vv, const char *val, int n) \
{ \
stp_internal_vars_t *v = (stp_internal_vars_t *) vv; \
if (v->s == val) \
return; \
SAFE_FREE(v->s); \
v->s = c_strndup(val, n); \
v->verified = 0; \
} \
\
const char * \
stp_get_##s(const stp_vars_t vv) \
{ \
stp_internal_vars_t *v = (stp_internal_vars_t *) vv; \
return v->s; \
}
#define DEF_FUNCS(s, t) \
void \
stp_set_##s(stp_vars_t vv, t val) \
{ \
stp_internal_vars_t *v = (stp_internal_vars_t *) vv; \
v->verified = 0; \
v->s = val; \
} \
\
t \
stp_get_##s(const stp_vars_t vv) \
{ \
stp_internal_vars_t *v = (stp_internal_vars_t *) vv; \
return v->s; \
}
DEF_STRING_FUNCS(output_to)
DEF_STRING_FUNCS(driver)
DEF_STRING_FUNCS(ppd_file)
DEF_STRING_FUNCS(resolution)
DEF_STRING_FUNCS(media_size)
DEF_STRING_FUNCS(media_type)
DEF_STRING_FUNCS(media_source)
DEF_STRING_FUNCS(ink_type)
DEF_STRING_FUNCS(dither_algorithm)
DEF_FUNCS(output_type, int)
DEF_FUNCS(orientation, int)
DEF_FUNCS(left, int)
DEF_FUNCS(top, int)
DEF_FUNCS(image_type, int)
DEF_FUNCS(unit, int)
DEF_FUNCS(page_width, int)
DEF_FUNCS(page_height, int)
DEF_FUNCS(input_color_model, int)
DEF_FUNCS(output_color_model, int)
DEF_FUNCS(brightness, float)
DEF_FUNCS(scaling, float)
DEF_FUNCS(gamma, float)
DEF_FUNCS(contrast, float)
DEF_FUNCS(cyan, float)
DEF_FUNCS(magenta, float)
DEF_FUNCS(yellow, float)
DEF_FUNCS(saturation, float)
DEF_FUNCS(density, float)
DEF_FUNCS(app_gamma, float)
DEF_FUNCS(page_number, int)
DEF_FUNCS(job_mode, stp_job_mode_t)
DEF_FUNCS(lut, void *)
DEF_FUNCS(outdata, void *)
DEF_FUNCS(errdata, void *)
DEF_FUNCS(driver_data, void *)
DEF_FUNCS(cmap, unsigned char *)
DEF_FUNCS(outfunc, stp_outfunc_t)
DEF_FUNCS(errfunc, stp_outfunc_t)
void
stp_set_verified(stp_vars_t vv, int val)
{
stp_internal_vars_t *v = (stp_internal_vars_t *) vv;
v->verified = val;
}
int
stp_get_verified(const stp_vars_t vv)
{
stp_internal_vars_t *v = (stp_internal_vars_t *) vv;
return v->verified;
}
void
stp_copy_options(stp_vars_t vd, const stp_vars_t vs)
{
const stp_internal_vars_t *src = (const stp_internal_vars_t *)vs;
stp_internal_vars_t *dest = (stp_internal_vars_t *)vd;
stp_internal_option_t *opt = (stp_internal_option_t *) src->options;
stp_internal_option_t *popt = NULL;
if (opt)
{
stp_internal_option_t *nopt = stp_malloc(sizeof(stp_internal_option_t));
stp_set_verified(vd, 0);
dest->options = nopt;
memcpy(nopt, opt, sizeof(stp_internal_option_t));
nopt->name = stp_malloc(strlen(opt->name) + 1);
strcpy(nopt->name, opt->name);
nopt->data = stp_malloc(opt->length);
memcpy(nopt->data, opt->data, opt->length);
opt = opt->next;
popt = nopt;
while (opt)
{
nopt = stp_malloc(sizeof(stp_internal_option_t));
memcpy(nopt, opt, sizeof(stp_internal_option_t));
nopt->prev = popt;
popt->next = nopt;
nopt->name = stp_malloc(strlen(opt->name) + 1);
strcpy(nopt->name, opt->name);
nopt->data = stp_malloc(opt->length);
memcpy(nopt->data, opt->data, opt->length);
opt = opt->next;
popt = nopt;
}
}
}
void
stp_copy_vars(stp_vars_t vd, const stp_vars_t vs)
{
if (vs == vd)
return;
stp_set_output_to(vd, stp_get_output_to(vs));
stp_set_driver(vd, stp_get_driver(vs));
stp_set_driver_data(vd, stp_get_driver_data(vs));
stp_set_ppd_file(vd, stp_get_ppd_file(vs));
stp_set_resolution(vd, stp_get_resolution(vs));
stp_set_media_size(vd, stp_get_media_size(vs));
stp_set_media_type(vd, stp_get_media_type(vs));
stp_set_media_source(vd, stp_get_media_source(vs));
stp_set_ink_type(vd, stp_get_ink_type(vs));
stp_set_dither_algorithm(vd, stp_get_dither_algorithm(vs));
stp_set_output_type(vd, stp_get_output_type(vs));
stp_set_orientation(vd, stp_get_orientation(vs));
stp_set_left(vd, stp_get_left(vs));
stp_set_top(vd, stp_get_top(vs));
stp_set_image_type(vd, stp_get_image_type(vs));
stp_set_unit(vd, stp_get_unit(vs));
stp_set_page_width(vd, stp_get_page_width(vs));
stp_set_page_height(vd, stp_get_page_height(vs));
stp_set_brightness(vd, stp_get_brightness(vs));
stp_set_scaling(vd, stp_get_scaling(vs));
stp_set_gamma(vd, stp_get_gamma(vs));
stp_set_contrast(vd, stp_get_contrast(vs));
stp_set_cyan(vd, stp_get_cyan(vs));
stp_set_magenta(vd, stp_get_magenta(vs));
stp_set_yellow(vd, stp_get_yellow(vs));
stp_set_saturation(vd, stp_get_saturation(vs));
stp_set_density(vd, stp_get_density(vs));
stp_set_app_gamma(vd, stp_get_app_gamma(vs));
stp_set_input_color_model(vd, stp_get_input_color_model(vd));
stp_set_output_color_model(vd, stp_get_output_color_model(vd));
stp_set_lut(vd, stp_get_lut(vs));
stp_set_outdata(vd, stp_get_outdata(vs));
stp_set_errdata(vd, stp_get_errdata(vs));
stp_set_cmap(vd, stp_get_cmap(vs));
stp_set_outfunc(vd, stp_get_outfunc(vs));
stp_set_errfunc(vd, stp_get_errfunc(vs));
stp_copy_options(vd, vs);
stp_set_verified(vd, stp_get_verified(vs));
}
stp_vars_t
stp_allocate_copy(const stp_vars_t vs)
{
stp_vars_t vd = stp_allocate_vars();
stp_copy_vars(vd, vs);
return (vd);
}
#define ICLAMP(value) \
do \
{ \
if (stp_get_##value(user) < stp_get_##value(min)) \
stp_set_##value(user, stp_get_##value(min)); \
else if (stp_get_##value(user) > stp_get_##value(max)) \
stp_set_##value(user, stp_get_##value(max)); \
} while (0)
void
stp_merge_printvars(stp_vars_t user, const stp_vars_t print)
{
const stp_vars_t max = stp_maximum_settings();
const stp_vars_t min = stp_minimum_settings();
stp_set_cyan(user, stp_get_cyan(user) * stp_get_cyan(print));
ICLAMP(cyan);
stp_set_magenta(user, stp_get_magenta(user) * stp_get_magenta(print));
ICLAMP(magenta);
stp_set_yellow(user, stp_get_yellow(user) * stp_get_yellow(print));
ICLAMP(yellow);
stp_set_contrast(user, stp_get_contrast(user) * stp_get_contrast(print));
ICLAMP(contrast);
stp_set_brightness(user, stp_get_brightness(user)*stp_get_brightness(print));
ICLAMP(brightness);
stp_set_gamma(user, stp_get_gamma(user) / stp_get_gamma(print));
ICLAMP(gamma);
stp_set_saturation(user, stp_get_saturation(user)*stp_get_saturation(print));
ICLAMP(saturation);
stp_set_density(user, stp_get_density(user) * stp_get_density(print));
ICLAMP(density);
if (stp_get_output_type(print) == OUTPUT_GRAY &&
stp_get_output_type(user) == OUTPUT_COLOR)
stp_set_output_type(user, OUTPUT_GRAY);
}
static stp_internal_papersize_t paper_sizes[] =
{
{ "Letter", N_ ("Letter"),
612, 792, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "Legal", N_ ("Legal"),
612, 1008, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "Tabloid", N_ ("Tabloid"),
792, 1224, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "Executive", N_ ("Executive"),
522, 756, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "Postcard", N_ ("Postcard"),
283, 416, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w216h360", N_ ("3x5"),
216, 360, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w288h432", N_ ("4x6"),
288, 432, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w324h495", N_ ("Epson 4x6 Photo Paper"),
324, 495, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w360h504", N_ ("5x7"),
360, 504, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w360h576", N_ ("5x8"),
360, 576, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w432h576", N_ ("6x8"),
432, 576, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "8x10", N_ ("8x10"),
576, 720, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "Statement", N_ ("Manual"),
396, 612, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "TabloidExtra", N_ ("12x18"),
864, 1296, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "SuperB", N_ ("Super B 13x19"),
936, 1368, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w576h864", N_ ("8x12"),
576, 864, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w792h1008", N_ ("11x14"),
792, 1008, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w1152h1440", N_ ("16x20"),
1152, 1440, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w1152h1728", N_ ("16x24"),
1152, 1728, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w1440h1728", N_ ("20x24"),
1440, 1728, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w1440h2160", N_ ("20x30"),
1440, 2160, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w1584h2160", N_ ("22x30"),
1584, 2160, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w1728h2160", N_ ("24x30"),
1728, 2160, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w1728h2592", N_ ("24x36"),
1728, 2592, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w2160h2880", N_ ("30x40"),
2160, 2880, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w4768h6749", N_ ("4A"),
4768, 6749, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w3370h4768", N_ ("2A"),
3370, 4768, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "A0", N_ ("A0"),
2384, 3370, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "A1", N_ ("A1"),
1684, 2384, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "A2", N_ ("A2"),
1191, 1684, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "A3", N_ ("A3"),
842, 1191, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "A4", N_ ("A4"),
595, 842, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "A5", N_ ("A5"),
420, 595, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "A6", N_ ("A6"),
297, 420, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "A7", N_ ("A7"),
210, 297, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "A8", N_ ("A8"),
148, 210, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "A9", N_ ("A9"),
105, 148, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "A10", N_ ("A10"),
73, 105, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w2437h3458", N_ ("RA0"),
2437, 3458, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w1729h2437", N_ ("RA1"),
1729, 2437, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w1218h1729", N_ ("RA2"),
1218, 1729, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w864h1218", N_ ("RA3"),
864, 1218, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w609h864", N_ ("RA4"),
609, 864, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w2551h3628", N_ ("SRA0"),
2551, 3628, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w1814h2551", N_ ("SRA1"),
1814, 2551, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w1275h1814", N_ ("SRA2"),
1275, 1814, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w907h1275", N_ ("SRA3"),
907, 1275, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w637h907", N_ ("SRA4"),
637, 907, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w5669h8016", N_ ("4B ISO"),
5669, 8016, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w4008h5669", N_ ("2B ISO"),
4008, 5669, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "ISOB0", N_ ("B0 ISO"),
2834, 4008, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "ISOB1", N_ ("B1 ISO"),
2004, 2834, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "ISOB2", N_ ("B2 ISO"),
1417, 2004, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "ISOB3", N_ ("B3 ISO"),
1000, 1417, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "ISOB4", N_ ("B4 ISO"),
708, 1000, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "ISOB5", N_ ("B5 ISO"),
498, 708, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "ISOB6", N_ ("B6 ISO"),
354, 498, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "ISOB7", N_ ("B7 ISO"),
249, 354, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "ISOB8", N_ ("B8 ISO"),
175, 249, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "ISOB9", N_ ("B9 ISO"),
124, 175, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "ISOB10", N_ ("B10 ISO"),
87, 124, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "B0", N_ ("B0 JIS"),
2919, 4127, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "B1", N_ ("B1 JIS"),
2063, 2919, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "B2", N_ ("B2 JIS"),
1459, 2063, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "B3", N_ ("B3 JIS"),
1029, 1459, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "B4", N_ ("B4 JIS"),
727, 1029, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "B5", N_ ("B5 JIS"),
518, 727, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "B6", N_ ("B6 JIS"),
362, 518, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "B7", N_ ("B7 JIS"),
257, 362, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "B8", N_ ("B8 JIS"),
180, 257, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "B9", N_ ("B9 JIS"),
127, 180, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "B10", N_ ("B10 JIS"),
90, 127, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "C0", N_ ("C0"),
2599, 3676, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "C1", N_ ("C1"),
1836, 2599, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "C2", N_ ("C2"),
1298, 1836, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "C3", N_ ("C3"),
918, 1298, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "C4", N_ ("C4"),
649, 918, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "C5", N_ ("C5"),
459, 649, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w354h918", N_ ("B6-C4"),
354, 918, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "C6", N_ ("C6"),
323, 459, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "DL", N_ ("DL"),
311, 623, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w229h459", N_ ("C7-6"),
229, 459, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "C7", N_ ("C7"),
229, 323, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "C8", N_ ("C8"),
161, 229, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "C9", N_ ("C9"),
113, 161, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "C10", N_ ("C10"),
79, 113, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "ARCHA", N_ ("ArchA"),
648, 864, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "ARCHA_trans", N_ ("ArchA Transverse"),
864, 648, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "ARCHB", N_ ("ArchB"),
864, 1296, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "ARCHB_trans", N_ ("ArchB Transverse"),
1296, 864, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "ARCHC", N_ ("ArchC"),
1296, 1728, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "ARCHC_trans", N_ ("ArchC Transverse"),
1728, 1296, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "ARCHD", N_ ("ArchD"),
1728, 2592, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "ARCHD_trans", N_ ("ArchD Transverse"),
2592, 1728, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "ARCHE", N_ ("ArchE"),
2592, 3456, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "ARCHE_trans", N_ ("ArchE Transverse"),
3456, 2592, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w612h936", N_ ("American foolscap"),
612, 936, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w648h936", N_ ("European foolscap"),
648, 936, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w535h697", N_ ("Crown Quarto"),
535, 697, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w569h731", N_ ("Large Crown Quarto"),
569, 731, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w620h782", N_ ("Demy Quarto"),
620, 782, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w671h884", N_ ("Royal Quarto"),
671, 884, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w348h527", N_ ("Crown Octavo"),
348, 527, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w365h561", N_ ("Large Crown Octavo"),
365, 561, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w391h612", N_ ("Demy Octavo"),
391, 612, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w442h663", N_ ("Royal Octavo"),
442, 663, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w314h504", N_ ("Small paperback"),
314, 504, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w314h513", N_ ("Penguin small paperback"),
314, 513, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w365h561", N_ ("Penguin large paperback"),
365, 561, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w283h420", N_ ("Hagaki Card"),
283, 420, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w420h567", N_ ("Oufuku Card"),
420, 567, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w340h666", N_ ("Japanese long envelope #3"),
340, 666, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w255h581", N_ ("Japanese long envelope #4"),
255, 581, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w680h941", N_ ("Japanese Kaku envelope #4"),
680, 941, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "COM10", N_ ("Commercial 10"),
297, 684, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w315h414", N_ ("A2 Invitation"),
315, 414, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "Monarch", N_ ("Monarch Envelope"),
279, 540, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "Custom", N_ ("Custom"),
0, 0, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w252", N_ ("89 mm Roll Paper"),
252, 0, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w288", N_ ("4 Inch Roll Paper"),
288, 0, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w360", N_ ("5 Inch Roll Paper"),
360, 0, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w595", N_ ("210 mm Roll Paper"),
595, 0, 0, 0, 0, 0, PAPERSIZE_METRIC },
{ "w936", N_ ("13 Inch Roll Paper"),
936, 0, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w1584", N_ ("22 Inch Roll Paper"),
1584, 0, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w1728", N_ ("24 Inch Roll Paper"),
1728, 0, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w2592", N_ ("36 Inch Roll Paper"),
2592, 0, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "w3168", N_ ("44 Inch Roll Paper"),
3168, 0, 0, 0, 0, 0, PAPERSIZE_ENGLISH },
{ "", "", 0, 0, 0, 0, 0, PAPERSIZE_METRIC }
};
int
stp_known_papersizes(void)
{
return sizeof(paper_sizes) / sizeof(stp_internal_papersize_t) - 1;
}
const char *
stp_papersize_get_name(const stp_papersize_t pt)
{
const stp_internal_papersize_t *p = (const stp_internal_papersize_t *) pt;
return p->name;
}
const char *
stp_papersize_get_text(const stp_papersize_t pt)
{
const stp_internal_papersize_t *p = (const stp_internal_papersize_t *) pt;
return _(p->text);
}
unsigned
stp_papersize_get_width(const stp_papersize_t pt)
{
const stp_internal_papersize_t *p = (const stp_internal_papersize_t *) pt;
return p->width;
}
unsigned
stp_papersize_get_height(const stp_papersize_t pt)
{
const stp_internal_papersize_t *p = (const stp_internal_papersize_t *) pt;
return p->height;
}
unsigned
stp_papersize_get_top(const stp_papersize_t pt)
{
const stp_internal_papersize_t *p = (const stp_internal_papersize_t *) pt;
return p->top;
}
unsigned
stp_papersize_get_left(const stp_papersize_t pt)
{
const stp_internal_papersize_t *p = (const stp_internal_papersize_t *) pt;
return p->left;
}
unsigned
stp_papersize_get_bottom(const stp_papersize_t pt)
{
const stp_internal_papersize_t *p = (const stp_internal_papersize_t *) pt;
return p->bottom;
}
unsigned
stp_papersize_get_right(const stp_papersize_t pt)
{
const stp_internal_papersize_t *p = (const stp_internal_papersize_t *) pt;
return p->right;
}
stp_papersize_unit_t
stp_papersize_get_unit(const stp_papersize_t pt)
{
const stp_internal_papersize_t *p = (const stp_internal_papersize_t *) pt;
return p->paper_unit;
}
#if 1
const stp_papersize_t
stp_get_papersize_by_name(const char *name)
{
static int last_used_papersize = 0;
int base = last_used_papersize;
int sizes = stp_known_papersizes();
int i;
if (!name)
return NULL;
for (i = 0; i < sizes; i++)
{
int size_to_try = (i + base) % sizes;
const stp_internal_papersize_t *val = &(paper_sizes[size_to_try]);
if (!strcmp(val->name, name))
{
last_used_papersize = size_to_try;
return (const stp_papersize_t) val;
}
}
return NULL;
}
#else
const stp_papersize_t
stp_get_papersize_by_name(const char *name)
{
const stp_internal_papersize_t *val = &(paper_sizes[0]);
if (!name)
return NULL;
while (strlen(val->name) > 0)
{
if (!strcmp(val->name, name))
return (stp_papersize_t) val;
val++;
}
return NULL;
}
#endif
const stp_papersize_t
stp_get_papersize_by_index(int index)
{
if (index < 0 || index >= stp_known_papersizes())
return NULL;
else
return (stp_papersize_t) &(paper_sizes[index]);
}
static int
paper_size_mismatch(int l, int w, const stp_internal_papersize_t *val)
{
int hdiff = abs(l - (int) val->height);
int vdiff = abs(w - (int) val->width);
return hdiff + vdiff;
}
const stp_papersize_t
stp_get_papersize_by_size(int l, int w)
{
int score = INT_MAX;
const stp_internal_papersize_t *ref = NULL;
const stp_internal_papersize_t *val = &(paper_sizes[0]);
int sizes = stp_known_papersizes();
int i;
for (i = 0; i < sizes; i++)
{
if (val->width == w && val->height == l)
return (stp_papersize_t) val;
else
{
int myscore = paper_size_mismatch(l, w, val);
if (myscore < score && myscore < 20)
{
ref = val;
score = myscore;
}
}
val++;
}
return (stp_papersize_t) ref;
}
void
stp_default_media_size(const stp_printer_t printer,
const stp_vars_t v,
int *width,
int *height)
{
if (stp_get_page_width(v) > 0 && stp_get_page_height(v) > 0)
{
*width = stp_get_page_width(v);
*height = stp_get_page_height(v);
}
else
{
const stp_papersize_t papersize =
stp_get_papersize_by_name(stp_get_media_size(v));
if (!papersize)
{
*width = 1;
*height = 1;
}
else
{
*width = stp_papersize_get_width(papersize);
*height = stp_papersize_get_height(papersize);
}
if (*width == 0)
*width = 612;
if (*height == 0)
*height = 792;
}
}
#include "print-printers.c"
int
stp_known_printers(void)
{
return printer_count;
}
const stp_printer_t
stp_get_printer_by_index(int idx)
{
if (idx < 0 || idx >= printer_count)
return NULL;
return (stp_printer_t) &(printers[idx]);
}
const stp_printer_t
stp_get_printer_by_long_name(const char *long_name)
{
const stp_internal_printer_t *val = &(printers[0]);
int i;
if (!long_name)
return NULL;
for (i = 0; i < stp_known_printers(); i++)
{
if (!strcmp(val->long_name, long_name))
return (stp_printer_t) val;
val++;
}
return NULL;
}
const stp_printer_t
stp_get_printer_by_driver(const char *driver)
{
const stp_internal_printer_t *val = &(printers[0]);
int i;
if (!driver)
return NULL;
for (i = 0; i < stp_known_printers(); i++)
{
if (!strcmp(val->driver, driver))
return (stp_printer_t) val;
val++;
}
return NULL;
}
int
stp_get_printer_index_by_driver(const char *driver)
{
int idx = 0;
const stp_internal_printer_t *val = &(printers[0]);
if (!driver)
return -1;
for (idx = 0; idx < stp_known_printers(); idx++)
{
if (!strcmp(val->driver, driver))
return idx;
val++;
}
return -1;
}
const char *
stp_printer_get_long_name(const stp_printer_t p)
{
const stp_internal_printer_t *val = (const stp_internal_printer_t *) p;
return val->long_name;
}
const char *
stp_printer_get_driver(const stp_printer_t p)
{
const stp_internal_printer_t *val = (const stp_internal_printer_t *) p;
return val->driver;
}
int
stp_printer_get_model(const stp_printer_t p)
{
const stp_internal_printer_t *val = (const stp_internal_printer_t *) p;
return val->model;
}
const stp_printfuncs_t *
stp_printer_get_printfuncs(const stp_printer_t p)
{
const stp_internal_printer_t *val = (const stp_internal_printer_t *) p;
return val->printfuncs;
}
const stp_vars_t
stp_printer_get_printvars(const stp_printer_t p)
{
const stp_internal_printer_t *val = (const stp_internal_printer_t *) p;
return (stp_vars_t) &(val->printvars);
}
const char *
stp_default_dither_algorithm(void)
{
return stp_dither_algorithm_name(0);
}
int
stp_start_job(const stp_printer_t printer,
stp_image_t *image, const stp_vars_t v)
{
if (!stp_get_verified(v))
return 0;
if (stp_get_job_mode(v) == STP_JOB_MODE_JOB)
return 1;
else
return 0;
}
int
stp_end_job(const stp_printer_t printer,
stp_image_t *image, const stp_vars_t v)
{
if (!stp_get_verified(v))
return 0;
if (stp_get_job_mode(v) == STP_JOB_MODE_JOB)
return 1;
else
return 0;
}
void
stp_compute_page_parameters(int page_right,
int page_left,
int page_top,
int page_bottom,
double scaling,
int image_width,
int image_height,
stp_image_t *image,
int *orientation,
int *page_width,
int *page_height,
int *out_width,
int *out_height,
int *left,
int *top)
{
*page_width = page_right - page_left;
*page_height = page_top - page_bottom;
if (*orientation == ORIENT_AUTO)
{
if ((*page_width >= *page_height && image_width >= image_height)
|| (*page_height >= *page_width && image_height >= image_width))
*orientation = ORIENT_PORTRAIT;
else
*orientation = ORIENT_LANDSCAPE;
}
if (*orientation == ORIENT_LANDSCAPE)
image->rotate_ccw(image);
else if (*orientation == ORIENT_UPSIDEDOWN)
image->rotate_180(image);
else if (*orientation == ORIENT_SEASCAPE)
image->rotate_cw(image);
image_width = image->width(image);
image_height = image->height(image);
if (scaling == 0.0)
{
*out_width = *page_width;
*out_height = *page_height;
}
else if (scaling < 0.0)
{
*out_width = image_width * -72.0 / scaling;
*out_height = image_height * -72.0 / scaling;
}
else
{
int twidth0 = *page_width * scaling / 100.0;
int theight0 = twidth0 * image_height / image_width;
int theight1 = *page_height * scaling / 100.0;
int twidth1 = theight1 * image_width / image_height;
*out_width = FMIN(twidth0, twidth1);
*out_height = FMIN(theight0, theight1);
}
if (*out_width == 0)
*out_width = 1;
if (*out_height == 0)
*out_height = 1;
if (*orientation == ORIENT_LANDSCAPE || *orientation == ORIENT_SEASCAPE)
{
int x;
x = *left;
*left = *top;
*top = x;
}
if ((*orientation == ORIENT_UPSIDEDOWN || *orientation == ORIENT_SEASCAPE)
&& *left >= 0)
{
*left = *page_width - *left - *out_width;
if (*left < 0)
*left = 0;
}
if ((*orientation == ORIENT_UPSIDEDOWN || *orientation == ORIENT_LANDSCAPE)
&& *top >= 0)
{
*top = *page_height - *top - *out_height;
if (*top < 0)
*top = 0;
}
if (*left < 0)
*left = (*page_width - *out_width) / 2;
if (*top < 0)
*top = (*page_height - *out_height) / 2;
}
void
stp_set_printer_defaults(stp_vars_t v, const stp_printer_t p,
const char *ppd_file)
{
const stp_printfuncs_t *printfuncs = stp_printer_get_printfuncs(p);
stp_set_resolution(v, ((printfuncs->default_parameters)
(p, ppd_file, "Resolution")));
stp_set_ink_type(v, ((printfuncs->default_parameters)
(p, ppd_file, "InkType")));
stp_set_media_type(v, ((printfuncs->default_parameters)
(p, ppd_file, "MediaType")));
stp_set_media_source(v, ((printfuncs->default_parameters)
(p, ppd_file, "InputSlot")));
stp_set_media_size(v, ((printfuncs->default_parameters)
(p, ppd_file, "PageSize")));
stp_set_dither_algorithm(v, stp_default_dither_algorithm());
stp_set_driver(v, stp_printer_get_driver(p));
}
static int
verify_param(const char *checkval, stp_param_t *vptr,
int count, const char *what, const stp_vars_t v)
{
int answer = 0;
int i;
if (count > 0)
{
for (i = 0; i < count; i++)
if (!strcmp(checkval, vptr[i].name))
{
answer = 1;
break;
}
if (!answer)
stp_eprintf(v, _("%s is not a valid parameter of type %s\n"),
checkval, what);
for (i = 0; i < count; i++)
{
stp_free((void *)vptr[i].name);
stp_free((void *)vptr[i].text);
}
}
else
stp_eprintf(v, _("%s is not a valid parameter of type %s\n"),
checkval, what);
if (vptr)
free(vptr);
return answer;
}
#define CHECK_FLOAT_RANGE(v, component) \
do \
{ \
const stp_vars_t max = stp_maximum_settings(); \
const stp_vars_t min = stp_minimum_settings(); \
if (stp_get_##component((v)) < stp_get_##component(min) || \
stp_get_##component((v)) > stp_get_##component(max)) \
{ \
answer = 0; \
stp_eprintf(v, _("%s out of range (value %f, min %f, max %f)\n"), \
#component, stp_get_##component(v), \
stp_get_##component(min), stp_get_##component(max)); \
} \
} while (0)
#define CHECK_INT_RANGE(v, component) \
do \
{ \
const stp_vars_t max = stp_maximum_settings(); \
const stp_vars_t min = stp_minimum_settings(); \
if (stp_get_##component((v)) < stp_get_##component(min) || \
stp_get_##component((v)) > stp_get_##component(max)) \
{ \
answer = 0; \
stp_eprintf(v, _("%s out of range (value %d, min %d, max %d)\n"), \
#component, stp_get_##component(v), \
stp_get_##component(min), stp_get_##component(max)); \
} \
} while (0)
int
stp_verify_printer_params(const stp_printer_t p, const stp_vars_t v)
{
stp_param_t *vptr;
int count;
int i;
int answer = 1;
const stp_printfuncs_t *printfuncs = stp_printer_get_printfuncs(p);
const stp_vars_t printvars = stp_printer_get_printvars(p);
const char *ppd_file = stp_get_ppd_file(v);
if (stp_get_output_type(printvars) == OUTPUT_GRAY &&
(stp_get_output_type(v) == OUTPUT_COLOR ||
stp_get_output_type(v) == OUTPUT_RAW_CMYK))
{
answer = 0;
stp_eprintf(v, _("Printer does not support color output\n"));
}
if (strlen(stp_get_media_size(v)) > 0)
{
const char *checkval = stp_get_media_size(v);
vptr = (*printfuncs->parameters)(p, ppd_file, "PageSize", &count);
answer &= verify_param(checkval, vptr, count, "page size", v);
}
else
{
int height, width;
int min_height, min_width;
(*printfuncs->limit)(p, v, &width, &height, &min_width, &min_height);
if (stp_get_page_height(v) <= min_height ||
stp_get_page_height(v) > height ||
stp_get_page_width(v) <= min_width || stp_get_page_width(v) > width)
{
answer = 0;
stp_eprintf(v, _("Image size is not valid\n"));
}
}
if (stp_get_top(v) < 0)
{
answer = 0;
stp_eprintf(v, _("Top margin must not be less than zero\n"));
}
if (stp_get_left(v) < 0)
{
answer = 0;
stp_eprintf(v, _("Left margin must not be less than zero\n"));
}
CHECK_FLOAT_RANGE(v, gamma);
CHECK_FLOAT_RANGE(v, contrast);
CHECK_FLOAT_RANGE(v, cyan);
CHECK_FLOAT_RANGE(v, magenta);
CHECK_FLOAT_RANGE(v, yellow);
CHECK_FLOAT_RANGE(v, brightness);
CHECK_FLOAT_RANGE(v, density);
CHECK_FLOAT_RANGE(v, saturation);
if (stp_get_scaling(v) > 0)
{
CHECK_FLOAT_RANGE(v, scaling);
}
CHECK_INT_RANGE(v, image_type);
CHECK_INT_RANGE(v, unit);
CHECK_INT_RANGE(v, output_type);
CHECK_INT_RANGE(v, input_color_model);
CHECK_INT_RANGE(v, output_color_model);
if (strlen(stp_get_media_type(v)) > 0)
{
const char *checkval = stp_get_media_type(v);
vptr = (*printfuncs->parameters)(p, ppd_file, "MediaType", &count);
answer &= verify_param(checkval, vptr, count, "media type", v);
}
if (strlen(stp_get_media_source(v)) > 0)
{
const char *checkval = stp_get_media_source(v);
vptr = (*printfuncs->parameters)(p, ppd_file, "InputSlot", &count);
answer &= verify_param(checkval, vptr, count, "media source", v);
}
if (strlen(stp_get_resolution(v)) > 0)
{
const char *checkval = stp_get_resolution(v);
vptr = (*printfuncs->parameters)(p, ppd_file, "Resolution", &count);
answer &= verify_param(checkval, vptr, count, "resolution", v);
}
if (strlen(stp_get_ink_type(v)) > 0)
{
const char *checkval = stp_get_ink_type(v);
vptr = (*printfuncs->parameters)(p, ppd_file, "InkType", &count);
answer &= verify_param(checkval, vptr, count, "ink type", v);
}
for (i = 0; i < stp_dither_algorithm_count(); i++)
if (!strcmp(stp_get_dither_algorithm(v), stp_dither_algorithm_name(i)))
{
stp_set_verified(v, answer);
return answer;
}
stp_eprintf(v, _("%s is not a valid dither algorithm\n"),
stp_get_dither_algorithm(v));
stp_set_verified(v, 0);
return 0;
}
const stp_vars_t
stp_default_settings()
{
return (stp_vars_t) &default_vars;
}
const stp_vars_t
stp_maximum_settings()
{
return (stp_vars_t) &max_vars;
}
const stp_vars_t
stp_minimum_settings()
{
return (stp_vars_t) &min_vars;
}
#define STP_VASPRINTF(result, bytes, format) \
{ \
int current_allocation = 64; \
result = stp_malloc(current_allocation); \
while (1) \
{ \
va_list args; \
va_start(args, format); \
bytes = vsnprintf(result, current_allocation, format, args); \
va_end(args); \
if (bytes >= 0 && bytes < current_allocation) \
break; \
else \
{ \
free (result); \
if (bytes < 0) \
current_allocation *= 2; \
else \
current_allocation = bytes + 1; \
result = stp_malloc(current_allocation); \
} \
} \
}
void
stp_zprintf(const stp_vars_t v, const char *format, ...)
{
char *result;
int bytes;
STP_VASPRINTF(result, bytes, format);
(stp_get_outfunc(v))((void *)(stp_get_outdata(v)), result, bytes);
free(result);
}
void
stp_zfwrite(const char *buf, size_t bytes, size_t nitems, const stp_vars_t v)
{
(stp_get_outfunc(v))((void *)(stp_get_outdata(v)), buf, bytes * nitems);
}
void
stp_putc(int ch, const stp_vars_t v)
{
char a = (char) ch;
(stp_get_outfunc(v))((void *)(stp_get_outdata(v)), &a, 1);
}
void
stp_puts(const char *s, const stp_vars_t v)
{
(stp_get_outfunc(v))((void *)(stp_get_outdata(v)), s, strlen(s));
}
void
stp_eprintf(const stp_vars_t v, const char *format, ...)
{
int bytes;
if (stp_get_errfunc(v))
{
char *result;
STP_VASPRINTF(result, bytes, format);
(stp_get_errfunc(v))((void *)(stp_get_errdata(v)), result, bytes);
free(result);
}
}
void
stp_erputc(int ch)
{
putc(ch, stderr);
}
void
stp_erprintf(const char *format, ...)
{
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
}
unsigned long stp_debug_level = 0;
static void
stp_init_debug(void)
{
static int debug_initialized = 0;
if (!debug_initialized)
{
const char *dval = getenv("STP_DEBUG");
debug_initialized = 1;
if (dval)
{
stp_debug_level = strtoul(dval, 0, 0);
stp_erprintf("Gimp-Print %s %s\n", VERSION, RELEASE_DATE);
}
}
}
void
stp_dprintf(unsigned long level, const stp_vars_t v, const char *format, ...)
{
int bytes;
stp_init_debug();
if ((level & stp_debug_level) && stp_get_errfunc(v))
{
char *result;
STP_VASPRINTF(result, bytes, format);
(stp_get_errfunc(v))((void *)(stp_get_errdata(v)), result, bytes);
free(result);
}
}
void
stp_deprintf(unsigned long level, const char *format, ...)
{
va_list args;
va_start(args, format);
stp_init_debug();
if (level & stp_debug_level)
vfprintf(stderr, format, args);
va_end(args);
}
void *
stp_malloc (size_t size)
{
register void *memptr = NULL;
if ((memptr = malloc (size)) == NULL)
{
fputs("Virtual memory exhausted.\n", stderr);
exit (EXIT_FAILURE);
}
return (memptr);
}
void *
stp_zalloc (size_t size)
{
register void *memptr = stp_malloc(size);
(void) memset(memptr, 0, size);
return (memptr);
}
void *
stp_realloc (void *ptr, size_t size)
{
register void *memptr = NULL;
if (size > 0 && ((memptr = realloc (ptr, size)) == NULL))
{
fputs("Virtual memory exhausted.\n", stderr);
exit (EXIT_FAILURE);
}
return (memptr);
}
void
stp_free(void *ptr)
{
free(ptr);
}
int
stp_init(void)
{
static int stp_is_initialised = 0;
if (!stp_is_initialised)
{
#ifdef ENABLE_NLS
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, PACKAGE_LOCALE_DIR);
#endif
stp_init_debug();
}
stp_is_initialised = 1;
return (0);
}
#ifdef QUANTIFY
unsigned quantify_counts[NUM_QUANTIFY_BUCKETS] = {0};
struct timeval quantify_buckets[NUM_QUANTIFY_BUCKETS] = {{0,0}};
int quantify_high_index = 0;
int quantify_first_time = 1;
struct timeval quantify_cur_time;
struct timeval quantify_prev_time;
void print_timers(const stp_vars_t v)
{
int i;
stp_eprintf(v, "%s", "Quantify timers:\n");
for (i = 0; i <= quantify_high_index; i++)
{
if (quantify_counts[i] > 0)
{
stp_eprintf(v,
"Bucket %d:\t%ld.%ld s\thit %u times\n", i,
quantify_buckets[i].tv_sec, quantify_buckets[i].tv_usec,
quantify_counts[i]);
quantify_buckets[i].tv_sec = 0;
quantify_buckets[i].tv_usec = 0;
quantify_counts[i] = 0;
}
}
}
#endif