#include "regmach.h"
#include "imextdef.h"
#include "imextpltypes.h"
+#include "imperlio.h"
#include <float.h>
#if i_int_hlines_testing()
#include "imperl.h"
+#define ARRAY_COUNT(array) (sizeof(array)/sizeof(*array))
+
+/*
+
+Context object management
+
+*/
+
+typedef im_context_t Imager__Context;
+
+#define im_context_DESTROY(ctx) im_context_refdec((ctx), "DESTROY")
+
+#ifdef PERL_IMPLICIT_CONTEXT
+
+#define MY_CXT_KEY "Imager::_context" XS_VERSION
+
+typedef struct {
+ im_context_t ctx;
+} my_cxt_t;
+
+START_MY_CXT
+
+static void
+start_context(pTHX) {
+ dMY_CXT;
+ MY_CXT.ctx = im_context_new();
+ sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", MY_CXT.ctx);
+}
+
+static im_context_t
+perl_get_context(void) {
+ dTHX;
+ dMY_CXT;
+
+ return MY_CXT.ctx;
+}
+
+#else
+
+static im_context_t perl_context;
+
+static void
+start_context(pTHX) {
+ perl_context = im_context_new();
+
+ /* just so it gets destroyed */
+ sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", perl_context);
+}
+
+static im_context_t
+perl_get_context(void) {
+ return perl_context;
+}
+
+#endif
+
/* used to represent channel lists parameters */
typedef struct i_channel_list_tag {
int *channels;
const i_fsample_t *samples;
} i_fsample_list;
+typedef struct {
+ size_t count;
+ const i_polygon_t *polygons;
+} i_polygon_list;
+
/*
Allocate memory that will be discarded when mortals are discarded.
static void *
malloc_temp(pTHX_ size_t size) {
- SV *sv = sv_2mortal(newSV(size));
+ void *result;
+ Newx(result, size, char);
+ SAVEFREEPV(result);
- return SvPVX(sv);
+ return result;
+}
+
+static void *
+calloc_temp(pTHX_ size_t size) {
+ void *result;
+ Newxz(result, size, char);
+ SAVEFREEPV(result);
+
+ return result;
+}
+
+/* for use with the T_AVARRAY typemap */
+#define doublePtr(size) ((double *)calloc_temp(aTHX_ sizeof(double) * (size)))
+#define SvDouble(sv, pname) (SvNV(sv))
+
+#define intPtr(size) ((int *)calloc_temp(aTHX_ sizeof(int) * (size)))
+#define SvInt(sv, pname) (SvIV(sv))
+
+#define i_img_dimPtr(size) ((i_img_dim *)calloc_temp(aTHX_ sizeof(i_img_dim) * (size)))
+#define SvI_img_dim(sv, pname) (SvIV(sv))
+
+#define i_colorPtr(size) ((i_color *)calloc_temp(aTHX_ sizeof(i_color) * (size)))
+
+#define SvI_color(sv, pname) S_sv_to_i_color(aTHX_ sv, pname)
+
+static i_color
+S_sv_to_i_color(pTHX_ SV *sv, const char *pname) {
+ if (!sv_derived_from(sv, "Imager::Color")) {
+ croak("%s: not a color object", pname);
+ }
+ return *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
}
/* These functions are all shared - then comes platform dependant code */
UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
-void my_SvREFCNT_dec(void *p) {
- dTHX;
- SvREFCNT_dec((SV*)p);
+static void
+free_buffer(void *p) {
+ myfree(p);
}
SV *data;
dSP;
- if (!SvOK(cbd->readcb))
+ if (!SvOK(cbd->readcb)) {
+ mm_log((1, "read callback called but no readcb supplied\n"));
+ i_push_error(0, "read callback called but no readcb supplied");
return -1;
+ }
ENTER;
SAVETMPS;
off_t result;
dSP;
- if (!SvOK(cbd->seekcb))
+ if (!SvOK(cbd->seekcb)) {
+ mm_log((1, "seek callback called but no seekcb supplied\n"));
+ i_push_error(0, "seek callback called but no seekcb supplied");
return -1;
+ }
ENTER;
SAVETMPS;
dSP;
bool success;
- if (!SvOK(cbd->writecb))
+ if (!SvOK(cbd->writecb)) {
+ mm_log((1, "write callback called but no writecb supplied\n"));
+ i_push_error(0, "write callback called but no writecb supplied");
return -1;
+ }
ENTER;
SAVETMPS;
if (SvOK(cbd->closecb)) {
dSP;
I32 count;
- SV *sv;
ENTER;
SAVETMPS;
SPAGAIN;
- sv = POPs;
- success = SvTRUE(sv);
+ if (count) {
+ SV *sv = POPs;
+ success = SvTRUE(sv);
+ }
+ else
+ success = 0;
PUTBACK;
FREETMPS;
myfree(cbd);
}
+static bool
+im_SvREFSCALAR(SV *sv) {
+ svtype type = SvTYPE(sv);
+
+ switch (type) {
+ case SVt_PV:
+ case SVt_PVIV:
+ case SVt_PVNV:
+ case SVt_PVMG:
+ case SVt_IV:
+ case SVt_NV:
+ case SVt_PVLV:
+#if PERL_VERSION > 10
+ case SVt_REGEXP:
+#endif
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+static const char *
+describe_sv(SV *sv) {
+ if (SvOK(sv)) {
+ if (SvROK(sv)) {
+ svtype type = SvTYPE(SvRV(sv));
+ switch (type) {
+ case SVt_PVCV: return "CV";
+ case SVt_PVGV: return "GV";
+ case SVt_PVLV: return "LV";
+ default: return "some reference";
+ }
+ }
+ else {
+ return "non-reference scalar";
+ }
+ }
+ else {
+ return "undef";
+ }
+}
+
static i_io_glue_t *
do_io_new_buffer(pTHX_ SV *data_sv) {
const char *data;
+ char *data_copy;
STRLEN length;
+ SV *sv;
- data = SvPVbyte(data_sv, length);
- SvREFCNT_inc(data_sv);
- return io_new_buffer(data, length, my_SvREFCNT_dec, data_sv);
+ SvGETMAGIC(data_sv);
+ if (SvROK(data_sv)) {
+ if (im_SvREFSCALAR(SvRV(data_sv))) {
+ sv = SvRV(data_sv);
+ }
+ else {
+ i_push_errorf(0, "data is not a scalar or a reference to scalar");
+ return NULL;
+ }
+ }
+ else {
+ sv = data_sv;
+ }
+
+ /* previously this would keep the SV around, but this is unsafe in
+ many ways, so always copy the bytes */
+ data = SvPVbyte(sv, length);
+ data_copy = mymalloc(length);
+ memcpy(data_copy, data, length);
+ return io_new_buffer(data_copy, length, free_buffer, data_copy);
}
static i_io_glue_t *
cbd->seekcb = newSVsv(seekcb);
cbd->closecb = newSVsv(closecb);
+ mm_log((1, "do_io_new_cb(writecb %p (%s), readcb %p (%s), seekcb %p (%s), closecb %p (%s))\n", writecb, describe_sv(writecb), readcb, describe_sv(readcb), seekcb, describe_sv(seekcb), closecb, describe_sv(closecb)));
+
return io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
io_destroyer);
}
struct value_name {
- char *name;
+ const char *name;
int value;
};
-static int lookup_name(struct value_name *names, int count, char *name, int def_value)
+static int
+lookup_name(const struct value_name *names, int count, char *name, int def_value, int push_errors, const char *id, int *failed)
{
int i;
+
+ if (push_errors)
+ *failed = 0;
+
for (i = 0; i < count; ++i)
if (strEQ(names[i].name, name))
return names[i].value;
+ if (push_errors) {
+ i_push_errorf(0, "unknown value '%s' for %s", name, id);
+ *failed = 1;
+ }
+
return def_value;
}
+
static struct value_name transp_names[] =
{
{ "none", tr_none },
};
/* look through the hash for quantization options */
-static void
-ip_handle_quant_opts(pTHX_ i_quantize *quant, HV *hv)
+static int
+ip_handle_quant_opts_low(pTHX_ i_quantize *quant, HV *hv, int push_errors)
{
- /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
SV **sv;
int i;
STRLEN len;
char *str;
+ int failed = 0;
quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
if (sv && *sv && (str = SvPV(*sv, len))) {
quant->transp =
lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
- str, tr_none);
+ str, tr_none, push_errors, "transp", &failed);
+ if (failed)
+ return 0;
if (quant->transp != tr_none) {
quant->tr_threshold = 127;
sv = hv_fetch(hv, "tr_threshold", 12, 0);
if (quant->transp == tr_errdiff) {
sv = hv_fetch(hv, "tr_errdiff", 10, 0);
if (sv && *sv && (str = SvPV(*sv, len)))
- quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
+ quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd, push_errors, "tr_errdiff", &failed);
+ if (failed)
+ return 0;
}
if (quant->transp == tr_ordered) {
quant->tr_orddith = od_tiny;
sv = hv_fetch(hv, "tr_orddith", 10, 0);
- if (sv && *sv && (str = SvPV(*sv, len)))
- quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
+ if (sv && *sv && (str = SvPV(*sv, len))) {
+ quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random, push_errors, "tr_orddith", &failed);
+ if (failed)
+ return 0;
+ }
if (quant->tr_orddith == od_custom) {
sv = hv_fetch(hv, "tr_map", 6, 0);
sv = hv_fetch(hv, "make_colors", 11, 0);
if (sv && *sv && (str = SvPV(*sv, len))) {
quant->make_colors =
- lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_median_cut);
+ lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_median_cut, push_errors, "make_colors", &failed);
+ if (failed)
+ return 0;
}
sv = hv_fetch(hv, "colors", 6, 0);
if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
quant->mc_colors[i] = *col;
}
+ else if (push_errors) {
+ i_push_errorf(0, "colors[%d] isn't an Imager::Color object", i);
+ return 0;
+ }
}
}
sv = hv_fetch(hv, "max_colors", 10, 0);
quant->translate = pt_closest;
sv = hv_fetch(hv, "translate", 9, 0);
if (sv && *sv && (str = SvPV(*sv, len))) {
- quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
+ quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest, push_errors, "translate", &failed);
+ if (failed)
+ return 0;
}
sv = hv_fetch(hv, "errdiff", 7, 0);
if (sv && *sv && (str = SvPV(*sv, len))) {
- quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
+ quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd, push_errors, "errdiff", &failed);
+ if (failed)
+ return 0;
}
if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
/* get the error diffusion map */
for (i = 0; i < len; ++i) {
SV **sv2 = av_fetch(av, i, 0);
if (sv2 && *sv2) {
- quant->ed_map[i] = SvIV(*sv2);
+ IV iv = SvIV(*sv2);
+ if (push_errors && iv < 0) {
+ i_push_errorf(0, "errdiff_map values must be non-negative, errdiff[%d] is negative", i);
+ return 0;
+ }
+ quant->ed_map[i] = iv;
sum += quant->ed_map[i];
}
}
myfree(quant->ed_map);
quant->ed_map = 0;
quant->errdiff = ed_floyd;
+ if (push_errors) {
+ i_push_error(0, "error diffusion map must contain some non-zero values");
+ return 0;
+ }
}
}
}
sv = hv_fetch(hv, "perturb", 7, 0);
if (sv && *sv)
quant->perturb = SvIV(*sv);
+
+ return 1;
}
static void
myfree(quant->ed_map);
}
+static int
+ip_handle_quant_opts2(pTHX_ i_quantize *quant, HV *hv) {
+ int result = ip_handle_quant_opts_low(aTHX_ quant, hv, 1);
+ if (!result) {
+ ip_cleanup_quant_opts(aTHX_ quant);
+ }
+ return result;
+}
+
+static void
+ip_handle_quant_opts(pTHX_ i_quantize *quant, HV *hv) {
+ (void)ip_handle_quant_opts_low(aTHX_ quant, hv, 0);
+}
+
/* copies the color map from the hv into the colors member of the HV */
static void
ip_copy_colors_back(pTHX_ HV *hv, i_quantize *quant) {
}
}
+static struct value_name
+poly_fill_mode_names[] =
+{
+ { "evenodd", i_pfm_evenodd },
+ { "nonzero", i_pfm_nonzero }
+};
+
+static i_poly_fill_mode_t
+S_get_poly_fill_mode(pTHX_ SV *sv) {
+ if (looks_like_number(sv)) {
+ IV work = SvIV(sv);
+ if (work < (IV)i_pfm_evenodd || work > (IV)i_pfm_nonzero)
+ work = (IV)i_pfm_evenodd;
+ return (i_poly_fill_mode_t)work;
+ }
+ else {
+ return (i_poly_fill_mode_t)lookup_name
+ (poly_fill_mode_names, ARRAY_COUNT(poly_fill_mode_names),
+ SvPV_nolen(sv), i_pfm_evenodd, 0, NULL, NULL);
+ }
+}
+
+static void
+S_get_polygon_list(pTHX_ i_polygon_list *polys, SV *sv) {
+ AV *av;
+ int i;
+ i_polygon_t *s;
+
+ SvGETMAGIC(sv);
+ if (!SvOK(sv) || !SvROK(sv) || SvTYPE(SvRV(sv)) != SVt_PVAV)
+ croak("polys must be an arrayref");
+
+ av = (AV*)SvRV(sv);
+ polys->count = av_len(av) + 1;
+ if (polys->count < 1)
+ croak("polypolygon: no polygons provided");
+ s = malloc_temp(aTHX_ sizeof(i_polygon_t) * polys->count);
+ for (i = 0; i < polys->count; ++i) {
+ SV **poly_sv = av_fetch(av, i, 0);
+ AV *poly_av;
+ SV **x_sv, **y_sv;
+ AV *x_av, *y_av;
+ double *x_data, *y_data;
+ ssize_t j;
+ ssize_t point_count;
+
+ if (!poly_sv)
+ croak("poly_polygon: nothing found for polygon %d", i);
+ /* needs to be another av */
+ SvGETMAGIC(*poly_sv);
+ if (!SvOK(*poly_sv) || !SvROK(*poly_sv) || SvTYPE(SvRV(*poly_sv)) != SVt_PVAV)
+ croak("poly_polygon: polygon %d isn't an arrayref", i);
+ poly_av = (AV*)SvRV(*poly_sv);
+ /* with two elements */
+ if (av_len(poly_av) != 1)
+ croak("poly_polygon: polygon %d should contain two arrays", i);
+ x_sv = av_fetch(poly_av, 0, 0);
+ y_sv = av_fetch(poly_av, 1, 0);
+ if (!x_sv)
+ croak("poly_polygon: polygon %d has no x elements", i);
+ if (!y_sv)
+ croak("poly_polygon: polygon %d has no y elements", i);
+ SvGETMAGIC(*x_sv);
+ SvGETMAGIC(*y_sv);
+ if (!SvOK(*x_sv) || !SvROK(*x_sv) || SvTYPE(SvRV(*x_sv)) != SVt_PVAV)
+ croak("poly_polygon: polygon %d x elements isn't an array", i);
+ if (!SvOK(*y_sv) || !SvROK(*y_sv) || SvTYPE(SvRV(*y_sv)) != SVt_PVAV)
+ croak("poly_polygon: polygon %d y elements isn't an array", i);
+ x_av = (AV*)SvRV(*x_sv);
+ y_av = (AV*)SvRV(*y_sv);
+ if (av_len(x_av) != av_len(y_av))
+ croak("poly_polygon: polygon %d x and y arrays different lengths", i+1);
+ point_count = av_len(x_av)+1;
+ x_data = malloc_temp(aTHX_ sizeof(double) * point_count * 2);
+ y_data = x_data + point_count;
+
+ for (j = 0; j < point_count; ++j) {
+ SV **x_item_sv = av_fetch(x_av, j, 0);
+ SV **y_item_sv = av_fetch(y_av, j, 0);
+ x_data[j] = x_item_sv ? SvNV(*x_item_sv) : 0;
+ y_data[j] = y_item_sv ? SvNV(*y_item_sv) : 0;
+ }
+ s[i].x = x_data;
+ s[i].y = y_data;
+ s[i].count = point_count;
+ }
+ polys->polygons = s;
+}
+
/* loads the segments of a fountain fill into an array */
static i_fountain_seg *
load_fount_segs(pTHX_ AV *asegs, int *count) {
}
}
-
/* I don't think ICLF_* names belong at the C interface
this makes the XS code think we have them, to let us avoid
putting function bodies in the XS code
IMAGER_PL_API_LEVEL,
ip_handle_quant_opts,
ip_cleanup_quant_opts,
- ip_copy_colors_back
+ ip_copy_colors_back,
+ ip_handle_quant_opts2
};
#define PERL_PL_SET_GLOBAL_CALLBACKS \
sv_setiv(get_sv(PERL_PL_FUNCTION_TABLE_NAME, 1), PTR2IV(&im_perl_funcs));
+#define IIM_new i_img_8_new
+#define IIM_DESTROY i_img_destroy
+typedef int SysRet;
+
#ifdef IMEXIF_ENABLE
#define i_exif_enabled() 1
#else
unsigned char b
unsigned char a
PPCODE:
- ICL_set_internal(cl, r, g, b, a);
+ cl->rgba.r = r;
+ cl->rgba.g = g;
+ cl->rgba.b = b;
+ cl->rgba.a = a;
EXTEND(SP, 1);
PUSHs(ST(0));
Imager::Color cl
PPCODE:
EXTEND(SP, 4);
- PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
- PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
- PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
- PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
+ PUSHs(sv_2mortal(newSViv(cl->rgba.r)));
+ PUSHs(sv_2mortal(newSViv(cl->rgba.g)));
+ PUSHs(sv_2mortal(newSViv(cl->rgba.b)));
+ PUSHs(sv_2mortal(newSViv(cl->rgba.a)));
Imager::Color
i_hsv_to_rgb(c)
Imager::Color::Float
ICLF_new_internal(r, g, b, a)
- double r
- double g
- double b
- double a
+ im_double r
+ im_double g
+ im_double b
+ im_double a
void
ICLF_DESTROY(cl)
void
ICLF_set_internal(cl,r,g,b,a)
Imager::Color::Float cl
- double r
- double g
- double b
- double a
+ im_double r
+ im_double g
+ im_double b
+ im_double a
PPCODE:
cl->rgba.r = r;
cl->rgba.g = g;
MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
Imager::ImgRaw
-IIM_new(x,y,ch)
- i_img_dim x
- i_img_dim y
+IIM_new(xsize,ysize,ch)
+ i_img_dim xsize
+ i_img_dim ysize
int ch
void
io_new_buffer(data_sv)
SV *data_sv
CODE:
+ i_clear_error();
RETVAL = do_io_new_buffer(aTHX_ data_sv);
+ if (!RETVAL)
+ XSRETURN(0);
OUTPUT:
RETVAL
SV *readcb;
SV *seekcb;
SV *closecb;
- int maxwrite;
CODE:
RETVAL = do_io_new_cb(aTHX_ writecb, readcb, seekcb, closecb);
OUTPUT:
PUSHs(sv_2mortal(newSVuv(bytes)));
}
+bool
+i_int_check_image_file_limits(width, height, channels, sample_size)
+ i_img_dim width
+ i_img_dim height
+ int channels
+ size_t sample_size
+ PROTOTYPE: DISABLE
+
MODULE = Imager PACKAGE = Imager::IO PREFIX = io_
Imager::IO
io_new_buffer(class, data_sv)
SV *data_sv
CODE:
+ i_clear_error();
RETVAL = do_io_new_buffer(aTHX_ data_sv);
+ if (!RETVAL)
+ XSRETURN(0);
OUTPUT:
RETVAL
OUTPUT:
RETVAL
+Imager::IO
+io__new_perlio(class, io)
+ PerlIO *io
+ CODE:
+ RETVAL = im_io_new_perlio(aTHX_ io);
+ OUTPUT:
+ RETVAL
+
SV *
io_slurp(class, ig)
Imager::IO ig
void *data;
STRLEN size;
CODE:
-#ifdef SvUTF8
- if (SvUTF8(data_sv)) {
- data_sv = sv_2mortal(newSVsv(data_sv));
- /* yes, we want this to croak() if the SV can't be downgraded */
- sv_utf8_downgrade(data_sv, FALSE);
- }
-#endif
- data = SvPV(data_sv, size);
+ data = SvPVbyte(data_sv, size);
RETVAL = i_io_raw_write(ig, data, size);
OUTPUT:
RETVAL
if (size <= 0)
croak("size negative in call to i_io_raw_read()");
/* prevent an undefined value warning if they supplied an
- undef buffer.
+ undef buffer.
Orginally conditional on !SvOK(), but this will prevent the
- downgrade from croaking */
- sv_setpvn(buffer_sv, "", 0);
+ downgrade from croaking */
+ sv_setpvn(buffer_sv, "", 0);
#ifdef SvUTF8
- if (SvUTF8(buffer_sv))
+ if (SvUTF8(buffer_sv))
sv_utf8_downgrade(buffer_sv, FALSE);
#endif
buffer = SvGROW(buffer_sv, size+1);
i_io_getc(ig)
Imager::IO ig
+void
+i_io_nextc(ig)
+ Imager::IO ig
+
int
i_io_putc(ig, c)
Imager::IO ig
if (size <= 0)
croak("size negative in call to i_io_read()");
/* prevent an undefined value warning if they supplied an
- undef buffer.
+ undef buffer.
Orginally conditional on !SvOK(), but this will prevent the
- downgrade from croaking */
- sv_setpvn(buffer_sv, "", 0);
+ downgrade from croaking */
+ sv_setpvn(buffer_sv, "", 0);
#ifdef SvUTF8
- if (SvUTF8(buffer_sv))
+ if (SvUTF8(buffer_sv))
sv_utf8_downgrade(buffer_sv, FALSE);
#endif
buffer = SvGROW(buffer_sv, size+1);
void *data;
STRLEN size;
CODE:
-#ifdef SvUTF8
- if (SvUTF8(data_sv)) {
- data_sv = sv_2mortal(newSVsv(data_sv));
- /* yes, we want this to croak() if the SV can't be downgraded */
- sv_utf8_downgrade(data_sv, FALSE);
- }
-#endif
- data = SvPV(data_sv, size);
+ data = SvPVbyte(data_sv, size);
RETVAL = i_io_write(ig, data, size);
OUTPUT:
RETVAL
PUSHs(sv_2mortal(newSVpv(item,0)));
}
-Imager::ImgRaw
-i_img_new()
-
-Imager::ImgRaw
-i_img_empty(im,x,y)
- Imager::ImgRaw im
- i_img_dim x
- i_img_dim y
-
-Imager::ImgRaw
-i_img_empty_ch(im,x,y,ch)
- Imager::ImgRaw im
- i_img_dim x
- i_img_dim y
- int ch
-
Imager::ImgRaw
i_sametype(im, x, y)
Imager::ImgRaw im
int
i_log_enabled()
-void
-i_img_exorcise(im)
- Imager::ImgRaw im
-
-void
-i_img_destroy(im)
- Imager::ImgRaw im
-
void
i_img_info(im)
Imager::ImgRaw im
i_img_get_height(im)
Imager::ImgRaw im
+int
+i_img_color_model(im)
+ Imager::ImgRaw im
+
+int
+i_img_color_channels(im)
+ Imager::ImgRaw im
+
+int
+i_img_alpha_channel(im)
+ Imager::ImgRaw im
+ CODE:
+ if (!i_img_alpha_channel(im, &RETVAL))
+ XSRETURN(0);
+ OUTPUT:
+ RETVAL
void
i_img_is_monochrome(im)
Imager::ImgRaw im
i_img_dim x
i_img_dim y
- double rad
- double d1
- double d2
+ im_double rad
+ im_double d1
+ im_double d2
Imager::Color val
void
i_arc_aa(im,x,y,rad,d1,d2,val)
Imager::ImgRaw im
- double x
- double y
- double rad
- double d1
- double d2
+ im_double x
+ im_double y
+ im_double rad
+ im_double d1
+ im_double d2
Imager::Color val
void
Imager::ImgRaw im
i_img_dim x
i_img_dim y
- double rad
- double d1
- double d2
+ im_double rad
+ im_double d1
+ im_double d2
Imager::FillHandle fill
void
i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
Imager::ImgRaw im
- double x
- double y
- double rad
- double d1
- double d2
+ im_double x
+ im_double y
+ im_double rad
+ im_double d1
+ im_double d2
Imager::FillHandle fill
void
i_circle_aa(im,x,y,rad,val)
Imager::ImgRaw im
- double x
- double y
- double rad
+ im_double x
+ im_double y
+ im_double rad
Imager::Color val
+void
+i_circle_aa_fill(im,x,y,rad,fill)
+ Imager::ImgRaw im
+ im_double x
+ im_double y
+ im_double rad
+ Imager::FillHandle fill
+
int
i_circle_out(im,x,y,rad,val)
Imager::ImgRaw im
i_img_dim x
i_img_dim y
i_img_dim rad
- double d1
- double d2
+ im_double d1
+ im_double d2
Imager::Color val
int
i_img_dim x
i_img_dim y
i_img_dim rad
- double d1
- double d2
+ im_double d1
+ im_double d2
Imager::Color val
void
-i_bezier_multi(im,xc,yc,val)
+i_bezier_multi(im,x,y,val)
Imager::ImgRaw im
- Imager::Color val
- PREINIT:
- double *x,*y;
- int len;
- AV *av1;
- AV *av2;
- SV *sv1;
- SV *sv2;
- int i;
- PPCODE:
- ICL_info(val);
- if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
- if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
- if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
- if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
- av1=(AV*)SvRV(ST(1));
- av2=(AV*)SvRV(ST(2));
- if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
- len=av_len(av1)+1;
- x=mymalloc( len*sizeof(double) );
- y=mymalloc( len*sizeof(double) );
- for(i=0;i<len;i++) {
- sv1=(*(av_fetch(av1,i,0)));
- sv2=(*(av_fetch(av2,i,0)));
- x[i]=(double)SvNV(sv1);
- y[i]=(double)SvNV(sv2);
- }
- i_bezier_multi(im,len,x,y,val);
- myfree(x);
- myfree(y);
-
+ double *x
+ double *y
+ Imager::Color val
+ PREINIT:
+ STRLEN size_x;
+ STRLEN size_y;
+ PPCODE:
+ if (size_x != size_y)
+ croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
+ i_bezier_multi(im,size_x,x,y,val);
int
-i_poly_aa(im,xc,yc,val)
+i_poly_aa_m(im,x,y,mode,val)
Imager::ImgRaw im
- Imager::Color val
- PREINIT:
- double *x,*y;
- int len;
- AV *av1;
- AV *av2;
- SV *sv1;
- SV *sv2;
- int i;
- CODE:
- ICL_info(val);
- if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
- if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
- if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
- if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
- av1=(AV*)SvRV(ST(1));
- av2=(AV*)SvRV(ST(2));
- if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
- len=av_len(av1)+1;
- x=mymalloc( len*sizeof(double) );
- y=mymalloc( len*sizeof(double) );
- for(i=0;i<len;i++) {
- sv1=(*(av_fetch(av1,i,0)));
- sv2=(*(av_fetch(av2,i,0)));
- x[i]=(double)SvNV(sv1);
- y[i]=(double)SvNV(sv2);
- }
- RETVAL = i_poly_aa(im,len,x,y,val);
- myfree(x);
- myfree(y);
- OUTPUT:
- RETVAL
+ double *x
+ double *y
+ i_poly_fill_mode_t mode
+ Imager::Color val
+ PREINIT:
+ STRLEN size_x;
+ STRLEN size_y;
+ CODE:
+ if (size_x != size_y)
+ croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
+ RETVAL = i_poly_aa_m(im, size_x, x, y, mode, val);
+ OUTPUT:
+ RETVAL
int
-i_poly_aa_cfill(im,xc,yc,fill)
+i_poly_aa_cfill_m(im, x, y, mode, fill)
Imager::ImgRaw im
- Imager::FillHandle fill
- PREINIT:
- double *x,*y;
- int len;
- AV *av1;
- AV *av2;
- SV *sv1;
- SV *sv2;
- int i;
- CODE:
- if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
- if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
- if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
- if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
- av1=(AV*)SvRV(ST(1));
- av2=(AV*)SvRV(ST(2));
- if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
- len=av_len(av1)+1;
- x=mymalloc( len*sizeof(double) );
- y=mymalloc( len*sizeof(double) );
- for(i=0;i<len;i++) {
- sv1=(*(av_fetch(av1,i,0)));
- sv2=(*(av_fetch(av2,i,0)));
- x[i]=(double)SvNV(sv1);
- y[i]=(double)SvNV(sv2);
- }
- RETVAL = i_poly_aa_cfill(im,len,x,y,fill);
- myfree(x);
- myfree(y);
- OUTPUT:
- RETVAL
+ double *x
+ double *y
+ i_poly_fill_mode_t mode
+ Imager::FillHandle fill
+ PREINIT:
+ STRLEN size_x;
+ STRLEN size_y;
+ CODE:
+ if (size_x != size_y)
+ croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
+ RETVAL = i_poly_aa_cfill_m(im, size_x, x, y, mode, fill);
+ OUTPUT:
+ RETVAL
+int
+i_poly_poly_aa(im, polys, mode, color)
+ Imager::ImgRaw im
+ i_polygon_list polys
+ i_poly_fill_mode_t mode
+ Imager::Color color
+ CODE:
+ RETVAL = i_poly_poly_aa(im, polys.count, polys.polygons, mode, color);
+ OUTPUT:
+ RETVAL
+int
+i_poly_poly_aa_cfill(im, polys, mode, fill)
+ Imager::ImgRaw im
+ i_polygon_list polys
+ i_poly_fill_mode_t mode
+ Imager::FillHandle fill
+ CODE:
+ RETVAL = i_poly_poly_aa_cfill(im, polys.count, polys.polygons, mode, fill);
+ OUTPUT:
+ RETVAL
undef_int
i_flood_fill(im,seedx,seedy,dcol)
i_img_dim width
i_img_dim height
int combine
- double opacity
+ im_double opacity
undef_int
i_compose_mask(out, src, mask, out_left, out_top, src_left, src_top, mask_left, mask_top, width, height, combine = ic_normal, opacity = 0.0)
i_img_dim width
i_img_dim height
int combine
- double opacity
+ im_double opacity
Imager::ImgRaw
i_combine(src_av, channels_av = NULL)
Imager::ImgRaw
i_rotate_exact(im, amount, ...)
Imager::ImgRaw im
- double amount
+ im_double amount
PREINIT:
i_color *backp = NULL;
i_fcolor *fbackp = NULL;
RETVAL
Imager::ImgRaw
-i_matrix_transform(im, xsize, ysize, matrix, ...)
+i_matrix_transform(im, xsize, ysize, matrix_av, ...)
Imager::ImgRaw im
- i_img_dim xsize
- i_img_dim ysize
- PREINIT:
- double matrix[9];
- AV *av;
- IV len;
- SV *sv1;
- int i;
- i_color *backp = NULL;
- i_fcolor *fbackp = NULL;
- CODE:
- if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
- croak("i_matrix_transform: parameter 4 must be an array ref\n");
- av=(AV*)SvRV(ST(3));
- len=av_len(av)+1;
- if (len > 9)
- len = 9;
- for (i = 0; i < len; ++i) {
- sv1=(*(av_fetch(av,i,0)));
- matrix[i] = SvNV(sv1);
- }
- for (; i < 9; ++i)
- matrix[i] = 0;
- /* extract the bg colors if any */
- /* yes, this is kind of strange */
- for (i = 4; i < items; ++i) {
- sv1 = ST(i);
- if (sv_derived_from(sv1, "Imager::Color")) {
- IV tmp = SvIV((SV*)SvRV(sv1));
- backp = INT2PTR(i_color *, tmp);
- }
- else if (sv_derived_from(sv1, "Imager::Color::Float")) {
- IV tmp = SvIV((SV*)SvRV(sv1));
- fbackp = INT2PTR(i_fcolor *, tmp);
- }
- }
- RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
- OUTPUT:
- RETVAL
+ i_img_dim xsize
+ i_img_dim ysize
+ AV *matrix_av
+ PREINIT:
+ double matrix[9];
+ STRLEN len;
+ SV *sv1;
+ int i;
+ i_color *backp = NULL;
+ i_fcolor *fbackp = NULL;
+ CODE:
+ len=av_len(matrix_av)+1;
+ if (len > 9)
+ len = 9;
+ for (i = 0; i < len; ++i) {
+ sv1=(*(av_fetch(matrix_av,i,0)));
+ matrix[i] = SvNV(sv1);
+ }
+ for (; i < 9; ++i)
+ matrix[i] = 0;
+ /* extract the bg colors if any */
+ /* yes, this is kind of strange */
+ for (i = 4; i < items; ++i) {
+ sv1 = ST(i);
+ if (sv_derived_from(sv1, "Imager::Color")) {
+ IV tmp = SvIV((SV*)SvRV(sv1));
+ backp = INT2PTR(i_color *, tmp);
+ }
+ else if (sv_derived_from(sv1, "Imager::Color::Float")) {
+ IV tmp = SvIV((SV*)SvRV(sv1));
+ fbackp = INT2PTR(i_fcolor *, tmp);
+ }
+ }
+ RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
+ OUTPUT:
+ RETVAL
undef_int
i_gaussian(im,stdev)
Imager::ImgRaw im
- double stdev
+ im_double stdev
void
i_unsharp_mask(im,stdev,scale)
Imager::ImgRaw im
- double stdev
- double scale
+ im_double stdev
+ im_double scale
int
i_conv(im,coef)
if (len > inchan)
inchan = len;
}
+ else {
+ i_push_errorf(0, "invalid matrix: element %d is not an array ref", j);
+ XSRETURN(0);
+ }
}
coeff = mymalloc(sizeof(double) * outchan * inchan);
for (j = 0; j < outchan; ++j) {
RETVAL
-void
-i_map(im, pmaps)
+undef_int
+i_map(im, pmaps_av)
Imager::ImgRaw im
- PREINIT:
- unsigned int mask = 0;
- AV *avmain;
- AV *avsub;
- SV **temp;
- int len;
- int i, j;
- unsigned char (*maps)[256];
- CODE:
- if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
- croak("i_map: parameter 2 must be an arrayref\n");
- avmain = (AV*)SvRV(ST(1));
- len = av_len(avmain)+1;
- if (im->channels < len) len = im->channels;
-
- maps = mymalloc( len * sizeof(unsigned char [256]) );
-
- for (j=0; j<len ; j++) {
- temp = av_fetch(avmain, j, 0);
- if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
- avsub = (AV*)SvRV(*temp);
- if(av_len(avsub) != 255) continue;
- mask |= 1<<j;
- for (i=0; i<256 ; i++) {
- int val;
- temp = av_fetch(avsub, i, 0);
- val = temp ? SvIV(*temp) : 0;
- if (val<0) val = 0;
- if (val>255) val = 255;
- maps[j][i] = val;
- }
- }
- }
- i_map(im, maps, mask);
- myfree(maps);
-
-
+ AV *pmaps_av
+ PREINIT:
+ unsigned int mask = 0;
+ AV *avsub;
+ SV **temp;
+ int len;
+ int i, j;
+ unsigned char (*maps)[256];
+ CODE:
+ len = av_len(pmaps_av)+1;
+ if (im->channels < len)
+ len = im->channels;
+ maps = mymalloc( len * sizeof(unsigned char [256]) );
+ for (j=0; j<len ; j++) {
+ temp = av_fetch(pmaps_av, j, 0);
+ if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
+ avsub = (AV*)SvRV(*temp);
+ if(av_len(avsub) != 255)
+ continue;
+ mask |= 1<<j;
+ for (i=0; i<256 ; i++) {
+ int val;
+ temp = av_fetch(avsub, i, 0);
+ val = temp ? SvIV(*temp) : 0;
+ if (val<0) val = 0;
+ if (val>255) val = 255;
+ maps[j][i] = val;
+ }
+ }
+ }
+ i_map(im, maps, mask);
+ myfree(maps);
+ RETVAL = 1;
+ OUTPUT:
+ RETVAL
float
i_img_diff(im1,im2)
i_img_samef(im1, im2, epsilon = i_img_epsilonf(), what=NULL)
Imager::ImgRaw im1
Imager::ImgRaw im2
- double epsilon
+ im_double epsilon
const char *what
double
undef_int
-i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
+i_tt_text(handle,im,xb,yb,cl,points,str_sv,smooth,utf8,align=1)
Imager::Font::TT handle
Imager::ImgRaw im
i_img_dim xb
i_img_dim yb
Imager::Color cl
- double points
+ im_double points
SV * str_sv
int smooth
int utf8
char *str;
STRLEN len;
CODE:
+ str = SvPV(str_sv, len);
#ifdef SvUTF8
if (SvUTF8(str_sv))
utf8 = 1;
#endif
- str = SvPV(str_sv, len);
RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
len, smooth, utf8, align);
OUTPUT:
undef_int
-i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
+i_tt_cp(handle,im,xb,yb,channel,points,str_sv,smooth,utf8,align=1)
Imager::Font::TT handle
Imager::ImgRaw im
i_img_dim xb
i_img_dim yb
int channel
- double points
+ im_double points
SV * str_sv
int smooth
int utf8
char *str;
STRLEN len;
CODE:
+ str = SvPV(str_sv, len);
#ifdef SvUTF8
if (SvUTF8(str_sv))
utf8 = 1;
#endif
- str = SvPV(str_sv, len);
RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
smooth, utf8, align);
OUTPUT:
void
-i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
+i_tt_bbox(handle,point,str_sv,utf8)
Imager::Font::TT handle
- double point
+ im_double point
SV* str_sv
int utf8
PREINIT:
STRLEN len;
int i;
PPCODE:
+ str = SvPV(str_sv, len);
#ifdef SvUTF8
if (SvUTF8(ST(2)))
utf8 = 1;
#endif
- str = SvPV(str_sv, len);
if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
EXTEND(SP, rc);
for (i = 0; i < rc; ++i) {
size_t count;
size_t i;
PPCODE:
+ i_clear_error();
+ text = SvPV(text_sv, len);
#ifdef SvUTF8
if (SvUTF8(text_sv))
utf8 = 1;
#endif
- text = SvPV(text_sv, len);
work = mymalloc(len);
count = i_tt_has_chars(handle, text, len, utf8, work);
if (GIMME_V == G_ARRAY) {
- EXTEND(SP, count);
- for (i = 0; i < count; ++i) {
- PUSHs(boolSV(work[i]));
- }
+ if (count) {
+ EXTEND(SP, count);
+ for (i = 0; i < count; ++i) {
+ PUSHs(boolSV(work[i]));
+ }
+ }
}
else {
EXTEND(SP, 1);
size_t outsize;
char name[255];
PPCODE:
+ i_clear_error();
+ text = SvPV(text_sv, work_len);
#ifdef SvUTF8
if (SvUTF8(text_sv))
utf8 = 1;
#endif
- text = SvPV(text_sv, work_len);
len = work_len;
while (len) {
unsigned long ch;
ch = i_utf8_advance(&text, &len);
if (ch == ~0UL) {
i_push_error(0, "invalid UTF8 character");
- break;
+ XSRETURN_EMPTY;
}
}
else {
}
EXTEND(SP, 1);
if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
- PUSHs(sv_2mortal(newSVpv(name, 0)));
+ PUSHs(sv_2mortal(newSVpv(name, 0)));
}
else {
- PUSHs(&PL_sv_undef);
- }
+ PUSHs(&PL_sv_undef);
+ }
}
#endif
Imager::ImgRaw
i_scaleaxis(im,Value,Axis)
Imager::ImgRaw im
- double Value
+ im_double Value
int Axis
Imager::ImgRaw
i_scale_nn(im,scx,scy)
Imager::ImgRaw im
- double scx
- double scy
+ im_double scx
+ im_double scy
Imager::ImgRaw
i_scale_mixing(im, width, height)
int col_cnt;
PPCODE:
col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
+ if (col_cnt <= 0) {
+ XSRETURN_EMPTY;
+ }
EXTEND(SP, col_cnt);
for (i = 0; i < col_cnt; i++) {
PUSHs(sv_2mortal(newSViv( col_usage[i])));
}
myfree(col_usage);
- XSRETURN(col_cnt);
void
-i_transform(im,opx,opy,parm)
+i_transform(im, opx, opy, parm)
Imager::ImgRaw im
+ int *opx
+ int *opy
+ double *parm
PREINIT:
- double* parm;
- int *opx;
- int *opy;
- int opxl;
- int opyl;
- int parmlen;
- AV* av;
- SV* sv1;
- int i;
+ STRLEN size_opx, size_opy, size_parm;
i_img *result;
PPCODE:
- if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
- if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
- if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
- if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
- if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
- if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
- av=(AV*)SvRV(ST(1));
- opxl=av_len(av)+1;
- opx=mymalloc( opxl*sizeof(int) );
- for(i=0;i<opxl;i++) {
- sv1=(*(av_fetch(av,i,0)));
- opx[i]=(int)SvIV(sv1);
- }
- av=(AV*)SvRV(ST(2));
- opyl=av_len(av)+1;
- opy=mymalloc( opyl*sizeof(int) );
- for(i=0;i<opyl;i++) {
- sv1=(*(av_fetch(av,i,0)));
- opy[i]=(int)SvIV(sv1);
- }
- av=(AV*)SvRV(ST(3));
- parmlen=av_len(av)+1;
- parm=mymalloc( parmlen*sizeof(double) );
- for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
- sv1=(*(av_fetch(av,i,0)));
- parm[i]=(double)SvNV(sv1);
- }
- result=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
- myfree(parm);
- myfree(opy);
- myfree(opx);
+ result=i_transform(im,opx,size_opx,opy,size_opy,parm,size_parm);
if (result) {
SV *result_sv = sv_newmortal();
EXTEND(SP, 1);
void
i_contrast(im,intensity)
Imager::ImgRaw im
- float intensity
+ im_float intensity
void
i_hardinvert(im)
void
i_noise(im,amount,type)
Imager::ImgRaw im
- float amount
+ im_float amount
unsigned char type
void
int channel
i_img_dim tx
i_img_dim ty
- double Lx
- double Ly
- double Lz
- float cd
- float cs
- float n
+ im_double Lx
+ im_double Ly
+ im_double Lz
+ im_float cd
+ im_float cs
+ im_float n
Imager::Color Ia
Imager::Color Il
Imager::Color Is
void
i_autolevels(im,lsat,usat,skew)
Imager::ImgRaw im
- float lsat
- float usat
- float skew
+ im_float lsat
+ im_float usat
+ im_float skew
+
+void
+i_autolevels_mono(im,lsat,usat)
+ Imager::ImgRaw im
+ im_float lsat
+ im_float usat
void
i_radnoise(im,xo,yo,rscale,ascale)
Imager::ImgRaw im
- float xo
- float yo
- float rscale
- float ascale
+ im_float xo
+ im_float yo
+ im_float rscale
+ im_float ascale
void
i_turbnoise(im, xo, yo, scale)
Imager::ImgRaw im
- float xo
- float yo
- float scale
+ im_float xo
+ im_float yo
+ im_float scale
void
-i_gradgen(im, ...)
+i_gradgen(im, xo, yo, ac, dmeasure)
Imager::ImgRaw im
+ i_img_dim *xo
+ i_img_dim *yo
+ i_color *ac
+ int dmeasure
PREINIT:
- int num;
- i_img_dim *xo;
- i_img_dim *yo;
- i_color *ival;
- int dmeasure;
- int i;
- SV *sv;
- AV *axx;
- AV *ayy;
- AV *ac;
+ STRLEN size_xo;
+ STRLEN size_yo;
+ STRLEN size_ac;
CODE:
- if (items != 5)
- croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
- if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
- croak("i_gradgen: Second argument must be an array ref");
- if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
- croak("i_gradgen: Third argument must be an array ref");
- if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
- croak("i_gradgen: Fourth argument must be an array ref");
- axx = (AV *)SvRV(ST(1));
- ayy = (AV *)SvRV(ST(2));
- ac = (AV *)SvRV(ST(3));
- dmeasure = (int)SvIV(ST(4));
-
- num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
- num = num <= av_len(ac) ? num : av_len(ac);
- num++;
- if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
- xo = mymalloc( sizeof(i_img_dim) * num );
- yo = mymalloc( sizeof(i_img_dim) * num );
- ival = mymalloc( sizeof(i_color) * num );
- for(i = 0; i<num; i++) {
- xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
- yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
- sv = *av_fetch(ac, i, 0);
- if ( !sv_derived_from(sv, "Imager::Color") ) {
- free(axx); free(ayy); free(ac);
- croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
- }
- ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
- }
- i_gradgen(im, num, xo, yo, ival, dmeasure);
- myfree(xo);
- myfree(yo);
- myfree(ival);
+ if (size_xo != size_yo || size_xo != size_ac)
+ croak("i_gradgen: x, y and color arrays must be the same size");
+ if (size_xo < 2)
+ croak("Usage: i_gradgen array refs must have more than 1 entry each");
+ i_gradgen(im, size_xo, xo, yo, ac, dmeasure);
Imager::ImgRaw
i_diff_image(im, im2, mindist=0)
Imager::ImgRaw im
Imager::ImgRaw im2
- double mindist
+ im_double mindist
undef_int
i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
Imager::ImgRaw im
- double xa
- double ya
- double xb
- double yb
+ im_double xa
+ im_double ya
+ im_double xb
+ im_double yb
int type
int repeat
int combine
int super_sample
- double ssample_param
+ im_double ssample_param
PREINIT:
AV *asegs;
int count;
Imager::FillHandle
i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
- double xa
- double ya
- double xb
- double yb
+ im_double xa
+ im_double ya
+ im_double xb
+ im_double yb
int type
int repeat
int combine
int super_sample
- double ssample_param
+ im_double ssample_param
PREINIT:
AV *asegs;
int count;
Imager::FillHandle
i_new_fill_opacity(other_fill, alpha_mult)
Imager::FillHandle other_fill
- double alpha_mult
+ im_double alpha_mult
void
i_errors()
if (!av_store(av, 1, sv)) {
SvREFCNT_dec(sv);
}
- PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
+ XPUSHs(sv_2mortal(newRV_noinc((SV*)av)));
++i;
}
num = num <= av_len(ac) ? num : av_len(ac);
num++;
if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
- xo = mymalloc( sizeof(i_img_dim) * num );
- yo = mymalloc( sizeof(i_img_dim) * num );
- ival = mymalloc( sizeof(i_color) * num );
+ xo = malloc_temp(aTHX_ sizeof(i_img_dim) * num );
+ yo = malloc_temp(aTHX_ sizeof(i_img_dim) * num );
+ ival = malloc_temp(aTHX_ sizeof(i_color) * num );
for(i = 0; i<num; i++) {
xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
DSO_call(handle,func_index,hv)
void* handle
int func_index
- PREINIT:
- HV* hv;
+ HV *hv
PPCODE:
- if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
- hv=(HV*)SvRV(ST(2));
- if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
DSO_call( (DSO_handle *)handle,func_index,hv);
-SV *
+Imager::Color
i_get_pixel(im, x, y)
Imager::ImgRaw im
i_img_dim x
i_img_dim y;
- PREINIT:
- i_color *color;
CODE:
- color = (i_color *)mymalloc(sizeof(i_color));
- if (i_gpix(im, x, y, color) == 0) {
- RETVAL = NEWSV(0, 0);
- sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
- }
- else {
- myfree(color);
- RETVAL = &PL_sv_undef;
+ RETVAL = (i_color *)mymalloc(sizeof(i_color));
+ memset(RETVAL, 0, sizeof(*RETVAL));
+ if (i_gpix(im, x, y, RETVAL) != 0) {
+ myfree(RETVAL);
+ XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
int maxpal
Imager::ImgRaw
-i_img_to_pal(src, quant)
+i_img_to_pal(src, quant_hv)
Imager::ImgRaw src
+ HV *quant_hv
PREINIT:
HV *hv;
i_quantize quant;
CODE:
- if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
- croak("i_img_to_pal: second argument must be a hash ref");
- hv = (HV *)SvRV(ST(1));
memset(&quant, 0, sizeof(quant));
quant.version = 1;
quant.mc_size = 256;
- ip_handle_quant_opts(aTHX_ &quant, hv);
+ i_clear_error();
+ if (!ip_handle_quant_opts2(aTHX_ &quant, quant_hv)) {
+ XSRETURN_EMPTY;
+ }
RETVAL = i_img_to_pal(src, &quant);
if (RETVAL) {
- ip_copy_colors_back(aTHX_ hv, &quant);
+ ip_copy_colors_back(aTHX_ quant_hv, &quant);
}
ip_cleanup_quant_opts(aTHX_ &quant);
OUTPUT:
memset(&quant, 0, sizeof(quant));
quant.version = 1;
quant.mc_size = 256;
- ip_handle_quant_opts(aTHX_ &quant, quant_hv);
+ if (!ip_handle_quant_opts2(aTHX_ &quant, quant_hv)) {
+ XSRETURN_EMPTY;
+ }
i_quant_makemap(&quant, imgs, count);
EXTEND(SP, quant.mc_count);
for (i = 0; i < quant.mc_count; ++i) {
PUSHs(sv_c);
}
ip_cleanup_quant_opts(aTHX_ &quant);
+ myfree(imgs);
void
OUTPUT:
RETVAL
-SV *
+SysRet
i_addcolors(im, ...)
Imager::ImgRaw im
PREINIT:
- int index;
i_color *colors;
int i;
CODE:
croak("i_addcolor: pixels must be Imager::Color objects");
}
}
- index = i_addcolors(im, colors, items-1);
+ RETVAL = i_addcolors(im, colors, items-1);
myfree(colors);
- if (index == 0) {
- RETVAL = newSVpv("0 but true", 0);
- }
- else if (index == -1) {
- RETVAL = &PL_sv_undef;
- }
- else {
- RETVAL = newSViv(index);
- }
OUTPUT:
RETVAL
RETVAL
void
-i_getcolors(im, index, ...)
+i_getcolors(im, index, count=1)
Imager::ImgRaw im
int index
+ int count
PREINIT:
i_color *colors;
- int count = 1;
int i;
PPCODE:
- if (items > 3)
- croak("i_getcolors: too many arguments");
- if (items == 3)
- count = SvIV(ST(2));
if (count < 1)
croak("i_getcolors: count must be positive");
- colors = mymalloc(sizeof(i_color) * count);
+ colors = malloc_temp(aTHX_ sizeof(i_color) * count);
if (i_getcolors(im, index, colors, count)) {
+ EXTEND(SP, count);
for (i = 0; i < count; ++i) {
SV *sv = make_i_color_sv(aTHX_ colors+i);
PUSHs(sv);
}
}
- myfree(colors);
-
undef_neg_int
i_colorcount(im)
i_maxcolors(im)
Imager::ImgRaw im
-SV *
+i_palidx
i_findcolor(im, color)
Imager::ImgRaw im
Imager::Color color
- PREINIT:
- i_palidx index;
CODE:
- if (i_findcolor(im, color, &index)) {
- RETVAL = newSViv(index);
- }
- else {
- RETVAL = &PL_sv_undef;
+ if (!i_findcolor(im, color, &RETVAL)) {
+ XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
i_img_dim count, i;
PPCODE:
if (l < r) {
- data = mymalloc(sizeof(i_sample_t) * (r-l) * channels.count); /* XXX: memleak? */
+ data = mymalloc(sizeof(i_sample_t) * (r-l) * channels.count);
count = i_gsamp(im, l, r, y, data, channels.channels, channels.count);
if (GIMME_V == G_ARRAY) {
EXTEND(SP, count);
}
else {
if (GIMME_V != G_ARRAY) {
- EXTEND(SP, 1);
- PUSHs(&PL_sv_undef);
+ XSRETURN_UNDEF;
}
}
}
else {
if (GIMME_V != G_ARRAY) {
- EXTEND(SP, 1);
- PUSHs(&PL_sv_undef);
+ XSRETURN_UNDEF;
}
}
OUTPUT:
RETVAL
-SV *
+Imager::Color::Float
i_gpixf(im, x, y)
Imager::ImgRaw im
i_img_dim x
i_img_dim y;
- PREINIT:
- i_fcolor *color;
CODE:
- color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
- if (i_gpixf(im, x, y, color) == 0) {
- RETVAL = NEWSV(0,0);
- sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
- }
- else {
- myfree(color);
- RETVAL = &PL_sv_undef;
+ RETVAL = (i_fcolor *)mymalloc(sizeof(i_fcolor));
+ memset(RETVAL, 0, sizeof(*RETVAL));
+ if (i_gpixf(im, x, y, RETVAL) != 0) {
+ myfree(RETVAL);
+ XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
}
Imager::ImgRaw
-i_img_16_new(x, y, ch)
- i_img_dim x
- i_img_dim y
- int ch
+i_img_8_new(xsize, ysize, channels)
+ i_img_dim xsize
+ i_img_dim ysize
+ int channels
+
+Imager::ImgRaw
+i_img_16_new(xsize, ysize, channels)
+ i_img_dim xsize
+ i_img_dim ysize
+ int channels
Imager::ImgRaw
i_img_to_rgb16(im)
Imager::ImgRaw im
Imager::ImgRaw
-i_img_double_new(x, y, ch)
- i_img_dim x
- i_img_dim y
- int ch
+i_img_double_new(xsize, ysize, channels)
+ i_img_dim xsize
+ i_img_dim ysize
+ int channels
Imager::ImgRaw
i_img_to_drgb(im)
Imager::ImgRaw im
undef_int
-i_tags_addn(im, name, code, idata)
+i_tags_addn(im, name_sv, code, idata)
Imager::ImgRaw im
+ SV *name_sv
int code
int idata
PREINIT:
char *name;
STRLEN len;
CODE:
- if (SvOK(ST(1)))
- name = SvPV(ST(1), len);
+ SvGETMAGIC(name_sv);
+ if (SvOK(name_sv))
+ name = SvPV_nomg(name_sv, len);
else
name = NULL;
RETVAL = i_tags_addn(&im->tags, name, code, idata);
RETVAL
undef_int
-i_tags_add(im, name, code, data, idata)
+i_tags_add(im, name_sv, code, data_sv, idata)
Imager::ImgRaw im
+ SV *name_sv
int code
+ SV *data_sv
int idata
PREINIT:
char *name;
char *data;
STRLEN len;
CODE:
- if (SvOK(ST(1)))
- name = SvPV(ST(1), len);
+ SvGETMAGIC(name_sv);
+ if (SvOK(name_sv))
+ name = SvPV_nomg(name_sv, len);
else
name = NULL;
- if (SvOK(ST(3)))
- data = SvPV(ST(3), len);
+ SvGETMAGIC(data_sv);
+ if (SvOK(data_sv))
+ data = SvPV(data_sv, len);
else {
data = NULL;
len = 0;
OUTPUT:
RETVAL
-SV *
+SysRet
i_tags_find(im, name, start)
Imager::ImgRaw im
char *name
int entry;
CODE:
if (i_tags_find(&im->tags, name, start, &entry)) {
- if (entry == 0)
- RETVAL = newSVpv("0 but true", 0);
- else
- RETVAL = newSViv(entry);
+ RETVAL = entry;
} else {
- RETVAL = &PL_sv_undef;
+ XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
-SV *
+SysRet
i_tags_findn(im, code, start)
Imager::ImgRaw im
int code
int entry;
CODE:
if (i_tags_findn(&im->tags, code, start, &entry)) {
- if (entry == 0)
- RETVAL = newSVpv("0 but true", 0);
- else
- RETVAL = newSViv(entry);
+ RETVAL = entry;
}
else {
- RETVAL = &PL_sv_undef;
+ XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
int combine
Imager::FillHandle
-i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
+i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch_sv, dx, dy)
Imager::Color fg
Imager::Color bg
int combine
int hatch
+ SV *cust_hatch_sv
i_img_dim dx
i_img_dim dy
PREINIT:
unsigned char *cust_hatch;
STRLEN len;
CODE:
- if (SvOK(ST(4))) {
- cust_hatch = (unsigned char *)SvPV(ST(4), len);
+ SvGETMAGIC(cust_hatch_sv);
+ if (SvOK(cust_hatch_sv)) {
+ cust_hatch = (unsigned char *)SvPV_nomg(cust_hatch_sv, len);
}
else
cust_hatch = NULL;
RETVAL
Imager::FillHandle
-i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
+i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch_sv, dx, dy)
Imager::Color::Float fg
Imager::Color::Float bg
int combine
int hatch
+ SV *cust_hatch_sv
i_img_dim dx
i_img_dim dy
PREINIT:
unsigned char *cust_hatch;
STRLEN len;
CODE:
- if (SvOK(ST(4))) {
- cust_hatch = (unsigned char *)SvPV(ST(4), len);
+ SvGETMAGIC(cust_hatch_sv);
+ if (SvOK(cust_hatch_sv)) {
+ cust_hatch = (unsigned char *)SvPV(cust_hatch_sv, len);
}
else
cust_hatch = NULL;
RETVAL
Imager::FillHandle
-i_new_fill_image(src, matrix, xoff, yoff, combine)
+i_new_fill_image(src, matrix_sv, xoff, yoff, combine)
Imager::ImgRaw src
+ SV *matrix_sv
i_img_dim xoff
i_img_dim yoff
int combine
SV *sv1;
int i;
CODE:
- if (!SvOK(ST(1))) {
+ SvGETMAGIC(matrix_sv);
+ if (!SvOK(matrix_sv)) {
matrixp = NULL;
}
else {
- if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
- croak("i_new_fill_image: parameter must be an arrayref");
- av=(AV*)SvRV(ST(1));
+ if (!SvROK(matrix_sv) || SvTYPE(SvRV(matrix_sv)) != SVt_PVAV)
+ croak("i_new_fill_image: matrix parameter must be an arrayref or undef");
+ av=(AV*)SvRV(matrix_sv);
len=av_len(av)+1;
if (len > 9)
len = 9;
#endif
+MODULE = Imager PACKAGE = Imager::Context PREFIX=im_context_
+
+void
+im_context_DESTROY(ctx)
+ Imager::Context ctx
+
+#ifdef PERL_IMPLICIT_CONTEXT
+
+void
+im_context_CLONE(...)
+ CODE:
+ MY_CXT_CLONE;
+ (void)items;
+ /* the following sv_setref_pv() will free this inc */
+ im_context_refinc(MY_CXT.ctx, "CLONE");
+ MY_CXT.ctx = im_context_clone(MY_CXT.ctx, "CLONE");
+ if (MY_CXT.ctx == NULL) {
+ croak("Failed to clone Imager context");
+ }
+ sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", MY_CXT.ctx);
+
+#endif
+
BOOT:
PERL_SET_GLOBAL_CALLBACKS;
PERL_PL_SET_GLOBAL_CALLBACKS;
+#ifdef PERL_IMPLICIT_CONTEXT
+ {
+ MY_CXT_INIT;
+ (void)MY_CXT;
+ }
+#endif
+ start_context(aTHX);
+ im_get_context = perl_get_context;
+#ifdef HAVE_LIBTT
+ i_tt_start();
+#endif