#include "XSUB.h"
#define NEED_newRV_noinc
#define NEED_sv_2pv_nolen
+#define NEED_sv_2pvbyte
#include "ppport.h"
#ifdef __cplusplus
}
#include "regmach.h"
#include "imextdef.h"
#include "imextpltypes.h"
+#include <float.h>
#if i_int_hlines_testing()
#include "imageri.h"
#include "imperl.h"
+/*
+
+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
+
+im_context_t fallback_context;
+
+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);
+
+ /* Ideally we'd free this reference, but the error message memory
+ was never released on exit, so the associated memory here is reasonable
+ to keep.
+ With logging enabled we always need at least one context, since
+ objects may be released fairly late and attempt to get the log file.
+ */
+ im_context_refinc(MY_CXT.ctx, "start_context");
+ fallback_context = MY_CXT.ctx;
+}
+
+static im_context_t
+perl_get_context(void) {
+ dTHX;
+ dMY_CXT;
+
+ return MY_CXT.ctx ? MY_CXT.ctx : fallback_context;
+}
+
+#else
+
+static im_context_t perl_context;
+
+static void
+start_context(pTHX) {
+ perl_context = im_context_new();
+ im_context_refinc(perl_context, "start_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;
+ int count;
+} i_channel_list;
+
+typedef struct {
+ size_t count;
+ const i_sample_t *samples;
+} i_sample_list;
+
+typedef struct {
+ size_t count;
+ const i_fsample_t *samples;
+} i_fsample_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));
+
+ return SvPVX(sv);
+}
+
/* These functions are all shared - then comes platform dependant code */
static int getstr(void *hv_t,char *key,char **store) {
dTHX;
SV** svpp;
HV* hv=(HV*)hv_t;
- mm_log((1,"getstr(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
+ mm_log((1,"getstr(hv_t %p, key %s, store %p)\n",hv_t,key,store));
if ( !hv_exists(hv,key,strlen(key)) ) return 0;
SV** svpp;
HV* hv=(HV*)hv_t;
- mm_log((1,"getint(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
+ mm_log((1,"getint(hv_t %p, key %s, store %p)\n",hv_t,key,store));
if ( !hv_exists(hv,key,strlen(key)) ) return 0;
SV** svpp;
HV* hv=(HV*)hv_t;
- mm_log((1,"getdouble(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
+ mm_log((1,"getdouble(hv_t %p, key %s, store %p)\n",hv_t,key,store));
if ( !hv_exists(hv,key,strlen(key)) ) return 0;
svpp=hv_fetch(hv, key, strlen(key), 0);
- *store=(float)SvNV(*svpp);
+ *store=(double)SvNV(*svpp);
return 1;
}
SV** svpp;
HV* hv=(HV*)hv_t;
- mm_log((1,"getvoid(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
+ mm_log((1,"getvoid(hv_t %p, key %s, store %p)\n",hv_t,key,store));
if ( !hv_exists(hv,key,strlen(key)) ) return 0;
SV** svpp;
HV* hv=(HV*)hv_t;
- mm_log((1,"getobj(hv_t 0x%X, key %s,type %s, store 0x%X)\n",hv_t,key,type,store));
+ mm_log((1,"getobj(hv_t %p, key %s,type %s, store %p)\n",hv_t,key,type,store));
if ( !hv_exists(hv,key,strlen(key)) ) return 0;
static void
i_log_entry(char *string, int level) {
- mm_log((level, string));
-}
-
-
-typedef struct i_reader_data_tag
-{
- /* presumably a CODE ref or name of a sub */
- SV *sv;
-} i_reader_data;
-
-/* used by functions that want callbacks */
-static int read_callback(char *userdata, char *buffer, int need, int want) {
- dTHX;
- i_reader_data *rd = (i_reader_data *)userdata;
- int count;
- int result;
- SV *data;
- dSP; dTARG = sv_newmortal();
- /* thanks to Simon Cozens for help with the dTARG above */
-
- ENTER;
- SAVETMPS;
- EXTEND(SP, 2);
- PUSHMARK(SP);
- PUSHi(want);
- PUSHi(need);
- PUTBACK;
-
- count = perl_call_sv(rd->sv, G_SCALAR);
-
- SPAGAIN;
-
- if (count != 1)
- croak("Result of perl_call_sv(..., G_SCALAR) != 1");
-
- data = POPs;
-
- if (SvOK(data)) {
- STRLEN len;
- char *ptr = SvPV(data, len);
- if (len > want)
- croak("Too much data returned in reader callback");
-
- memcpy(buffer, ptr, len);
- result = len;
- }
- else {
- result = -1;
- }
-
- PUTBACK;
- FREETMPS;
- LEAVE;
-
- return result;
+ mm_log((level, "%s", string));
}
-typedef struct
-{
- SV *sv; /* a coderef or sub name */
-} i_writer_data;
-
-/* used by functions that want callbacks */
-static int write_callback(char *userdata, char const *data, int size) {
- dTHX;
- i_writer_data *wd = (i_writer_data *)userdata;
- int count;
- int success;
+static SV *
+make_i_color_sv(pTHX_ const i_color *c) {
SV *sv;
- dSP;
-
- ENTER;
- SAVETMPS;
- EXTEND(SP, 1);
- PUSHMARK(SP);
- XPUSHs(sv_2mortal(newSVpv((char *)data, size)));
- PUTBACK;
+ i_color *col = mymalloc(sizeof(i_color));
+ *col = *c;
+ sv = sv_newmortal();
+ sv_setref_pv(sv, "Imager::Color", (void *)col);
- count = perl_call_sv(wd->sv, G_SCALAR);
-
- SPAGAIN;
-
- if (count != 1)
- croak("Result of perl_call_sv(..., G_SCALAR) != 1");
-
- sv = POPs;
- success = SvTRUE(sv);
-
-
- PUTBACK;
- FREETMPS;
- LEAVE;
-
- return success;
+ return sv;
}
#define CBDATA_BUFSIZE 8192
SV *readcb;
SV *seekcb;
SV *closecb;
-
- /* we need to remember whether the buffer contains write data or
- read data
- */
- int reading;
- int writing;
-
- /* how far we've read into the buffer (not used for writing) */
- int where;
-
- /* the amount of space used/data available in the buffer */
- int used;
-
- /* the maximum amount to fill the buffer before flushing
- If any write is larger than this then the buffer is flushed and
- the full write is performed. The write is _not_ split into
- maxwrite sized calls
- */
- int maxlength;
-
- char buffer[CBDATA_BUFSIZE];
};
-/*
-
-call_writer(cbd, buf, size)
-
-Low-level function to call the perl writer callback.
-
-*/
-
-static ssize_t call_writer(struct cbdata *cbd, void const *buf, size_t size) {
- dTHX;
- int count;
- int success;
- SV *sv;
- dSP;
-
- if (!SvOK(cbd->writecb))
- return -1;
-
- ENTER;
- SAVETMPS;
- EXTEND(SP, 1);
- PUSHMARK(SP);
- PUSHs(sv_2mortal(newSVpv((char *)buf, size)));
- PUTBACK;
-
- count = perl_call_sv(cbd->writecb, G_SCALAR);
-
- SPAGAIN;
- if (count != 1)
- croak("Result of perl_call_sv(..., G_SCALAR) != 1");
-
- sv = POPs;
- success = SvTRUE(sv);
-
-
- PUTBACK;
- FREETMPS;
- LEAVE;
-
- return success ? size : -1;
-}
-
-static ssize_t call_reader(struct cbdata *cbd, void *buf, size_t size,
- size_t maxread) {
+static ssize_t
+call_reader(struct cbdata *cbd, void *buf, size_t size,
+ size_t maxread) {
dTHX;
int count;
int result;
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;
if (SvOK(data)) {
STRLEN len;
- char *ptr = SvPV(data, len);
+ char *ptr = SvPVbyte(data, len);
if (len > maxread)
- croak("Too much data returned in reader callback");
+ croak("Too much data returned in reader callback (wanted %d, got %d, expected %d)",
+ (int)size, (int)len, (int)maxread);
memcpy(buf, ptr, len);
result = len;
return result;
}
-static ssize_t write_flush(struct cbdata *cbd) {
- dTHX;
- ssize_t result;
-
- if (cbd->used) {
- result = call_writer(cbd, cbd->buffer, cbd->used);
- cbd->used = 0;
- return result;
- }
- else {
- return 1; /* success of some sort */
- }
-}
-
-static off_t io_seeker(void *p, off_t offset, int whence) {
+static off_t
+io_seeker(void *p, off_t offset, int whence) {
dTHX;
struct cbdata *cbd = p;
int count;
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;
-
- if (cbd->writing) {
- if (cbd->used && write_flush(cbd) <= 0)
- return -1;
- cbd->writing = 0;
- }
- if (whence == SEEK_CUR && cbd->reading && cbd->where != cbd->used) {
- offset -= cbd->where - cbd->used;
}
- cbd->reading = 0;
- cbd->where = cbd->used = 0;
-
+
ENTER;
SAVETMPS;
EXTEND(SP, 2);
return result;
}
-static ssize_t io_writer(void *p, void const *data, size_t size) {
+static ssize_t
+io_writer(void *p, void const *data, size_t size) {
dTHX;
struct cbdata *cbd = p;
+ I32 count;
+ SV *sv;
+ dSP;
+ bool success;
- /* printf("io_writer(%p, %p, %u)\n", p, data, size); */
- if (!cbd->writing) {
- if (cbd->reading && cbd->where < cbd->used) {
- /* we read past the place where the caller expected us to be
- so adjust our position a bit */
- if (io_seeker(p, cbd->where - cbd->used, SEEK_CUR) < 0) {
- return -1;
- }
- cbd->reading = 0;
- }
- cbd->where = cbd->used = 0;
- }
- cbd->writing = 1;
- if (cbd->used && cbd->used + size > cbd->maxlength) {
- int write_res = write_flush(cbd);
- if (write_res <= 0) {
- return write_res;
- }
- cbd->used = 0;
- }
- if (cbd->used+size <= cbd->maxlength) {
- memcpy(cbd->buffer + cbd->used, data, size);
- cbd->used += size;
- return size;
+ 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;
}
- /* it doesn't fit - just pass it up */
- return call_writer(cbd, data, size);
+
+ ENTER;
+ SAVETMPS;
+ EXTEND(SP, 1);
+ PUSHMARK(SP);
+ PUSHs(sv_2mortal(newSVpv((char *)data, size)));
+ PUTBACK;
+
+ count = perl_call_sv(cbd->writecb, G_SCALAR);
+
+ SPAGAIN;
+ if (count != 1)
+ croak("Result of perl_call_sv(..., G_SCALAR) != 1");
+
+ sv = POPs;
+ success = SvTRUE(sv);
+
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ return success ? size : -1;
}
static ssize_t
io_reader(void *p, void *data, size_t size) {
- dTHX;
struct cbdata *cbd = p;
- ssize_t total;
- char *out = data; /* so we can do pointer arithmetic */
-
- /* printf("io_reader(%p, %p, %d)\n", p, data, size); */
- if (cbd->writing) {
- if (write_flush(cbd) <= 0)
- return 0;
- cbd->writing = 0;
- }
- cbd->reading = 1;
- if (size <= cbd->used - cbd->where) {
- /* simplest case */
- memcpy(data, cbd->buffer+cbd->where, size);
- cbd->where += size;
- return size;
- }
- total = 0;
- memcpy(out, cbd->buffer + cbd->where, cbd->used - cbd->where);
- total += cbd->used - cbd->where;
- size -= cbd->used - cbd->where;
- out += cbd->used - cbd->where;
- if (size < sizeof(cbd->buffer)) {
- int did_read = 0;
- int copy_size;
- while (size
- && (did_read = call_reader(cbd, cbd->buffer, size,
- sizeof(cbd->buffer))) > 0) {
- cbd->where = 0;
- cbd->used = did_read;
-
- copy_size = i_min(size, cbd->used);
- memcpy(out, cbd->buffer, copy_size);
- cbd->where += copy_size;
- out += copy_size;
- total += copy_size;
- size -= copy_size;
- }
- if (did_read < 0)
- return -1;
- }
- else {
- /* just read the rest - too big for our buffer*/
- int did_read;
- while ((did_read = call_reader(cbd, out, size, size)) > 0) {
- size -= did_read;
- total += did_read;
- out += did_read;
- }
- if (did_read < 0)
- return -1;
- }
-
- return total;
+ return call_reader(cbd, data, size, size);
}
static int io_closer(void *p) {
dTHX;
struct cbdata *cbd = p;
-
- if (cbd->writing && cbd->used > 0) {
- if (write_flush(cbd) < 0)
- return -1;
- cbd->writing = 0;
- }
+ int success = 1;
if (SvOK(cbd->closecb)) {
dSP;
+ I32 count;
+ SV *sv;
ENTER;
SAVETMPS;
PUSHMARK(SP);
PUTBACK;
- perl_call_sv(cbd->closecb, G_VOID);
+ count = perl_call_sv(cbd->closecb, G_SCALAR);
SPAGAIN;
+
+ sv = POPs;
+ success = SvTRUE(sv);
+
PUTBACK;
FREETMPS;
LEAVE;
}
- return 0;
+ return success ? 0 : -1;
}
static void io_destroyer(void *p) {
myfree(cbd);
}
+static i_io_glue_t *
+do_io_new_buffer(pTHX_ SV *data_sv) {
+ const char *data;
+ STRLEN length;
+
+ data = SvPVbyte(data_sv, length);
+ SvREFCNT_inc(data_sv);
+ return io_new_buffer(data, length, my_SvREFCNT_dec, data_sv);
+}
+
+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_cb(pTHX_ SV *writecb, SV *readcb, SV *seekcb, SV *closecb) {
+ struct cbdata *cbd;
+
+ cbd = mymalloc(sizeof(struct cbdata));
+ cbd->writecb = newSVsv(writecb);
+ cbd->readcb = newSVsv(readcb);
+ 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;
int value;
{ "mediancut", mc_median_cut, },
{ "mono", mc_mono, },
{ "monochrome", mc_mono, },
+ { "gray", mc_gray, },
+ { "gray4", mc_gray4, },
+ { "gray16", mc_gray16, },
};
static struct value_name translate_names[] =
}
}
}
- quant->make_colors = mc_addi;
+ quant->make_colors = mc_median_cut;
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_addi);
+ lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_median_cut);
}
sv = hv_fetch(hv, "colors", 6, 0);
if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
}
}
-
/* 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
#define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
#define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
-
-/* the m_init_log() function was called init_log(), renamed to reduce
- potential naming conflicts */
-#define init_log m_init_log
+#ifdef IMAGER_LOG
+#define i_log_enabled() 1
+#else
+#define i_log_enabled() 0
+#endif
#if i_int_hlines_testing()
typedef i_int_hlines *Imager__Internal__Hlines;
static i_int_hlines *
-i_int_hlines_new(int start_y, int count_y, int start_x, int count_x) {
+i_int_hlines_new(i_img_dim start_y, i_img_dim count_y, i_img_dim start_x, i_img_dim count_x) {
i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
i_int_init_hlines(result, start_y, count_y, start_x, count_x);
static SV *
i_int_hlines_dump(i_int_hlines *hlines) {
dTHX;
- SV *dump = newSVpvf("start_y: %d limit_y: %d start_x: %d limit_x: %d\n",
- hlines->start_y, hlines->limit_y, hlines->start_x, hlines->limit_x);
- int y;
+ SV *dump = newSVpvf("start_y: %" i_DF " limit_y: %" i_DF " start_x: %" i_DF " limit_x: %" i_DF"\n",
+ i_DFc(hlines->start_y), i_DFc(hlines->limit_y), i_DFc(hlines->start_x), i_DFc(hlines->limit_x));
+ i_img_dim y;
for (y = hlines->start_y; y < hlines->limit_y; ++y) {
i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
if (entry->count)
qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
- sv_catpvf(dump, " %d (%d):", y, entry->count);
+ sv_catpvf(dump, " %" i_DF " (%" i_DF "):", i_DFc(y), i_DFc(entry->count));
for (i = 0; i < entry->count; ++i) {
- sv_catpvf(dump, " [%d, %d)", entry->segs[i].minx,
- entry->segs[i].x_limit);
+ sv_catpvf(dump, " [%" i_DF ", %" i_DF ")", i_DFc(entry->segs[i].minx),
+ i_DFc(entry->segs[i].x_limit));
}
sv_catpv(dump, "\n");
}
#endif
+static off_t
+i_sv_off_t(pTHX_ SV *sv) {
+#if LSEEKSIZE > IVSIZE
+ return (off_t)SvNV(sv);
+#else
+ return (off_t)SvIV(sv);
+#endif
+}
+
+static SV *
+i_new_sv_off_t(pTHX_ off_t off) {
+#if LSEEKSIZE > IVSIZE
+ return newSVnv(off);
+#else
+ return newSViv(off);
+#endif
+}
+
static im_pl_ext_funcs im_perl_funcs =
{
IMAGER_PL_API_VERSION,
#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
+
#ifdef IMEXIF_ENABLE
#define i_exif_enabled() 1
#else
#define i_img_get_width(im) ((im)->xsize)
#define i_img_get_height(im) ((im)->ysize)
+#define i_img_epsilonf() (DBL_EPSILON * 4)
+
+/* avoid some xsubpp strangeness */
+#define NEWLINE '\n'
+
MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
Imager::Color
Imager::ImgRaw
IIM_new(x,y,ch)
- int x
- int y
+ i_img_dim x
+ i_img_dim y
int ch
void
Imager::IO
-io_new_buffer(data)
- char *data
- PREINIT:
- size_t length;
+io_new_buffer(data_sv)
+ SV *data_sv
CODE:
- SvPV(ST(0), length);
- SvREFCNT_inc(ST(0));
- RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
+ RETVAL = do_io_new_buffer(aTHX_ data_sv);
OUTPUT:
RETVAL
SV *seekcb;
SV *closecb;
int maxwrite;
- PREINIT:
- struct cbdata *cbd;
CODE:
- cbd = mymalloc(sizeof(struct cbdata));
- SvREFCNT_inc(writecb);
- cbd->writecb = writecb;
- SvREFCNT_inc(readcb);
- cbd->readcb = readcb;
- SvREFCNT_inc(seekcb);
- cbd->seekcb = seekcb;
- SvREFCNT_inc(closecb);
- cbd->closecb = closecb;
- cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
- if (maxwrite > CBDATA_BUFSIZE)
- maxwrite = CBDATA_BUFSIZE;
- cbd->maxlength = maxwrite;
- RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
- io_destroyer);
+ RETVAL = do_io_new_cb(aTHX_ writecb, readcb, seekcb, closecb);
OUTPUT:
RETVAL
-void
+SV *
io_slurp(ig)
Imager::IO ig
PREINIT:
unsigned char* data;
size_t tlength;
- PPCODE:
+ CODE:
data = NULL;
tlength = io_slurp(ig, &data);
- EXTEND(SP,1);
- PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
+ RETVAL = newSVpv((char *)data,tlength);
myfree(data);
+ OUTPUT:
+ RETVAL
undef_int
i_set_image_file_limits(width, height, bytes)
- int width
- int height
- int bytes
+ i_img_dim width
+ i_img_dim height
+ size_t bytes
void
i_get_image_file_limits()
PREINIT:
- int width, height, bytes;
+ i_img_dim width, height;
+ size_t bytes;
PPCODE:
if (i_get_image_file_limits(&width, &height, &bytes)) {
EXTEND(SP, 3);
PUSHs(sv_2mortal(newSViv(width)));
PUSHs(sv_2mortal(newSViv(height)));
- PUSHs(sv_2mortal(newSViv(bytes)));
+ 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_fd(class, fd)
+ int fd
+ CODE:
+ RETVAL = io_new_fd(fd);
+ OUTPUT:
+ RETVAL
+
+Imager::IO
+io_new_buffer(class, data_sv)
+ SV *data_sv
+ CODE:
+ RETVAL = do_io_new_buffer(aTHX_ data_sv);
+ OUTPUT:
+ RETVAL
+
+Imager::IO
+io_new_cb(class, writecb, readcb, seekcb, closecb)
+ SV *writecb;
+ SV *readcb;
+ SV *seekcb;
+ SV *closecb;
+ CODE:
+ RETVAL = do_io_new_cb(aTHX_ writecb, readcb, seekcb, closecb);
+ OUTPUT:
+ RETVAL
+
+Imager::IO
+io_new_bufchain(class)
+ CODE:
+ RETVAL = io_new_bufchain();
+ OUTPUT:
+ RETVAL
+
+SV *
+io_slurp(class, ig)
+ Imager::IO ig
+ PREINIT:
+ unsigned char* data;
+ size_t tlength;
+ CODE:
+ data = NULL;
+ tlength = io_slurp(ig, &data);
+ RETVAL = newSVpv((char *)data,tlength);
+ myfree(data);
+ OUTPUT:
+ RETVAL
+
MODULE = Imager PACKAGE = Imager::IO PREFIX = i_io_
-int
-i_io_write(ig, data_sv)
+IV
+i_io_raw_write(ig, data_sv)
Imager::IO ig
SV *data_sv
PREINIT:
}
#endif
data = SvPV(data_sv, size);
- RETVAL = i_io_write(ig, data, size);
+ RETVAL = i_io_raw_write(ig, data, size);
OUTPUT:
RETVAL
void
-i_io_read(ig, buffer_sv, size)
+i_io_raw_read(ig, buffer_sv, size)
Imager::IO ig
SV *buffer_sv
- int size
+ IV size
PREINIT:
void *buffer;
- int result;
+ ssize_t result;
PPCODE:
if (size <= 0)
- croak("size negative in call to i_io_read()");
+ croak("size negative in call to i_io_raw_read()");
/* prevent an undefined value warning if they supplied an
undef buffer.
Orginally conditional on !SvOK(), but this will prevent the
sv_utf8_downgrade(buffer_sv, FALSE);
#endif
buffer = SvGROW(buffer_sv, size+1);
- result = i_io_read(ig, buffer, size);
+ result = i_io_raw_read(ig, buffer, size);
if (result >= 0) {
SvCUR_set(buffer_sv, result);
*SvEND(buffer_sv) = '\0';
SvSETMAGIC(ST(1));
void
-i_io_read2(ig, size)
+i_io_raw_read2(ig, size)
Imager::IO ig
- int size
+ IV size
PREINIT:
SV *buffer_sv;
void *buffer;
- int result;
+ ssize_t result;
PPCODE:
if (size <= 0)
croak("size negative in call to i_io_read2()");
buffer_sv = newSV(size);
buffer = SvGROW(buffer_sv, size+1);
- result = i_io_read(ig, buffer, size);
+ result = i_io_raw_read(ig, buffer, size);
if (result >= 0) {
SvCUR_set(buffer_sv, result);
*SvEND(buffer_sv) = '\0';
SvREFCNT_dec(buffer_sv);
}
-int
-i_io_seek(ig, position, whence)
+off_t
+i_io_raw_seek(ig, position, whence)
Imager::IO ig
- long position
+ off_t position
int whence
int
-i_io_close(ig)
+i_io_raw_close(ig)
Imager::IO ig
void
int
i_io_CLONE_SKIP(...)
CODE:
+ (void)items; /* avoid unused warning for XS variable */
RETVAL = 1;
OUTPUT:
RETVAL
-MODULE = Imager PACKAGE = Imager
+int
+i_io_getc(ig)
+ Imager::IO ig
-PROTOTYPES: ENABLE
+int
+i_io_putc(ig, c)
+ Imager::IO ig
+ int c
+
+int
+i_io_close(ig)
+ Imager::IO ig
+
+int
+i_io_flush(ig)
+ Imager::IO ig
+
+int
+i_io_peekc(ig)
+ Imager::IO ig
+
+int
+i_io_seek(ig, off, whence)
+ Imager::IO ig
+ off_t off
+ int whence
void
-i_list_formats()
- PREINIT:
- char* item;
- int i;
- PPCODE:
- i=0;
- while( (item=i_format_list[i++]) != NULL ) {
- EXTEND(SP, 1);
- PUSHs(sv_2mortal(newSVpv(item,0)));
- }
+i_io_peekn(ig, size)
+ Imager::IO ig
+ STRLEN size
+ PREINIT:
+ SV *buffer_sv;
+ void *buffer;
+ ssize_t result;
+ PPCODE:
+ buffer_sv = newSV(size+1);
+ buffer = SvGROW(buffer_sv, size+1);
+ result = i_io_peekn(ig, buffer, size);
+ if (result >= 0) {
+ SvCUR_set(buffer_sv, result);
+ *SvEND(buffer_sv) = '\0';
+ SvPOK_only(buffer_sv);
+ EXTEND(SP, 1);
+ PUSHs(sv_2mortal(buffer_sv));
+ }
+ else {
+ /* discard it */
+ SvREFCNT_dec(buffer_sv);
+ }
-undef_int
-i_has_format(frmt)
- char* frmt
+void
+i_io_read(ig, buffer_sv, size)
+ Imager::IO ig
+ SV *buffer_sv
+ IV size
+ PREINIT:
+ void *buffer;
+ ssize_t result;
+ PPCODE:
+ if (size <= 0)
+ croak("size negative in call to i_io_read()");
+ /* prevent an undefined value warning if they supplied an
+ undef buffer.
+ Orginally conditional on !SvOK(), but this will prevent the
+ downgrade from croaking */
+ sv_setpvn(buffer_sv, "", 0);
+#ifdef SvUTF8
+ if (SvUTF8(buffer_sv))
+ sv_utf8_downgrade(buffer_sv, FALSE);
+#endif
+ buffer = SvGROW(buffer_sv, size+1);
+ result = i_io_read(ig, buffer, size);
+ if (result >= 0) {
+ SvCUR_set(buffer_sv, result);
+ *SvEND(buffer_sv) = '\0';
+ SvPOK_only(buffer_sv);
+ EXTEND(SP, 1);
+ PUSHs(sv_2mortal(newSViv(result)));
+ }
+ ST(1) = buffer_sv;
+ SvSETMAGIC(ST(1));
-Imager::ImgRaw
-i_img_new()
+void
+i_io_read2(ig, size)
+ Imager::IO ig
+ STRLEN size
+ PREINIT:
+ SV *buffer_sv;
+ void *buffer;
+ ssize_t result;
+ PPCODE:
+ if (size == 0)
+ croak("size zero in call to read2()");
+ buffer_sv = newSV(size);
+ buffer = SvGROW(buffer_sv, size+1);
+ result = i_io_read(ig, buffer, size);
+ if (result > 0) {
+ SvCUR_set(buffer_sv, result);
+ *SvEND(buffer_sv) = '\0';
+ SvPOK_only(buffer_sv);
+ EXTEND(SP, 1);
+ PUSHs(sv_2mortal(buffer_sv));
+ }
+ else {
+ /* discard it */
+ SvREFCNT_dec(buffer_sv);
+ }
-Imager::ImgRaw
-i_img_empty(im,x,y)
- Imager::ImgRaw im
- int x
- int y
+void
+i_io_gets(ig, size = 8192, eol = NEWLINE)
+ Imager::IO ig
+ STRLEN size
+ int eol
+ PREINIT:
+ SV *buffer_sv;
+ void *buffer;
+ ssize_t result;
+ PPCODE:
+ if (size < 2)
+ croak("size too small in call to gets()");
+ buffer_sv = sv_2mortal(newSV(size+1));
+ buffer = SvPVX(buffer_sv);
+ result = i_io_gets(ig, buffer, size+1, eol);
+ if (result > 0) {
+ SvCUR_set(buffer_sv, result);
+ *SvEND(buffer_sv) = '\0';
+ SvPOK_only(buffer_sv);
+ EXTEND(SP, 1);
+ PUSHs(buffer_sv);
+ }
-Imager::ImgRaw
-i_img_empty_ch(im,x,y,ch)
- Imager::ImgRaw im
- int x
- int y
- int ch
+IV
+i_io_write(ig, data_sv)
+ Imager::IO ig
+ SV *data_sv
+ PREINIT:
+ 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);
+ RETVAL = i_io_write(ig, data, size);
+ OUTPUT:
+ RETVAL
+
+void
+i_io_dump(ig, flags = I_IO_DUMP_DEFAULT)
+ Imager::IO ig
+ int flags
+
+bool
+i_io_set_buffered(ig, flag = 1)
+ Imager::IO ig
+ int flag
+
+bool
+i_io_is_buffered(ig)
+ Imager::IO ig
+
+bool
+i_io_eof(ig)
+ Imager::IO ig
+
+bool
+i_io_error(ig)
+ Imager::IO ig
+
+MODULE = Imager PACKAGE = Imager
+
+PROTOTYPES: ENABLE
+
+void
+i_list_formats()
+ PREINIT:
+ char* item;
+ int i;
+ PPCODE:
+ i=0;
+ while( (item=i_format_list[i++]) != NULL ) {
+ EXTEND(SP, 1);
+ PUSHs(sv_2mortal(newSVpv(item,0)));
+ }
Imager::ImgRaw
i_sametype(im, x, y)
Imager::ImgRaw im
- int x
- int y
+ i_img_dim x
+ i_img_dim y
Imager::ImgRaw
i_sametype_chans(im, x, y, channels)
Imager::ImgRaw im
- int x
- int y
+ i_img_dim x
+ i_img_dim y
int channels
-void
+int
i_init_log(name_sv,level)
SV* name_sv
int level
PREINIT:
const char *name = SvOK(name_sv) ? SvPV_nolen(name_sv) : NULL;
CODE:
- i_init_log(name, level);
+ RETVAL = i_init_log(name, level);
+ OUTPUT:
+ RETVAL
void
i_log_entry(string,level)
char* string
int level
-
-void
-i_img_exorcise(im)
- Imager::ImgRaw im
-
-void
-i_img_destroy(im)
- Imager::ImgRaw im
+int
+i_log_enabled()
void
i_img_info(im)
Imager::ImgRaw im
PREINIT:
- int info[4];
+ i_img_dim info[4];
PPCODE:
i_img_info(im,info);
EXTEND(SP, 4);
void
i_line(im,x1,y1,x2,y2,val,endp)
Imager::ImgRaw im
- int x1
- int y1
- int x2
- int y2
+ i_img_dim x1
+ i_img_dim y1
+ i_img_dim x2
+ i_img_dim y2
Imager::Color val
int endp
void
i_line_aa(im,x1,y1,x2,y2,val,endp)
Imager::ImgRaw im
- int x1
- int y1
- int x2
- int y2
+ i_img_dim x1
+ i_img_dim y1
+ i_img_dim x2
+ i_img_dim y2
Imager::Color val
int endp
void
i_box(im,x1,y1,x2,y2,val)
Imager::ImgRaw im
- int x1
- int y1
- int x2
- int y2
+ i_img_dim x1
+ i_img_dim y1
+ i_img_dim x2
+ i_img_dim y2
Imager::Color val
void
i_box_filled(im,x1,y1,x2,y2,val)
Imager::ImgRaw im
- int x1
- int y1
- int x2
- int y2
+ i_img_dim x1
+ i_img_dim y1
+ i_img_dim x2
+ i_img_dim y2
Imager::Color val
+int
+i_box_filledf(im,x1,y1,x2,y2,val)
+ Imager::ImgRaw im
+ i_img_dim x1
+ i_img_dim y1
+ i_img_dim x2
+ i_img_dim y2
+ Imager::Color::Float val
+
void
i_box_cfill(im,x1,y1,x2,y2,fill)
Imager::ImgRaw im
- int x1
- int y1
- int x2
- int y2
+ i_img_dim x1
+ i_img_dim y1
+ i_img_dim x2
+ i_img_dim y2
Imager::FillHandle fill
void
i_arc(im,x,y,rad,d1,d2,val)
Imager::ImgRaw im
- int x
- int y
- float rad
- float d1
- float d2
+ i_img_dim x
+ i_img_dim y
+ double rad
+ double d1
+ double d2
Imager::Color val
void
void
i_arc_cfill(im,x,y,rad,d1,d2,fill)
Imager::ImgRaw im
- int x
- int y
- float rad
- float d1
- float d2
+ i_img_dim x
+ i_img_dim y
+ double rad
+ double d1
+ double d2
Imager::FillHandle fill
void
void
i_circle_aa(im,x,y,rad,val)
Imager::ImgRaw im
- float x
- float y
- float rad
+ double x
+ double y
+ double rad
Imager::Color val
int
i_img_dim x
i_img_dim y
i_img_dim rad
- float d1
- float d2
+ double d1
+ double d2
Imager::Color val
int
i_img_dim x
i_img_dim y
i_img_dim rad
- float d1
- float d2
+ double d1
+ double d2
Imager::Color val
undef_int
i_flood_fill(im,seedx,seedy,dcol)
Imager::ImgRaw im
- int seedx
- int seedy
+ i_img_dim seedx
+ i_img_dim seedy
Imager::Color dcol
undef_int
i_flood_cfill(im,seedx,seedy,fill)
Imager::ImgRaw im
- int seedx
- int seedy
+ i_img_dim seedx
+ i_img_dim seedy
Imager::FillHandle fill
undef_int
i_flood_fill_border(im,seedx,seedy,dcol, border)
Imager::ImgRaw im
- int seedx
- int seedy
+ i_img_dim seedx
+ i_img_dim seedy
Imager::Color dcol
Imager::Color border
undef_int
i_flood_cfill_border(im,seedx,seedy,fill, border)
Imager::ImgRaw im
- int seedx
- int seedy
+ i_img_dim seedx
+ i_img_dim seedy
Imager::FillHandle fill
Imager::Color border
i_copyto(im,src,x1,y1,x2,y2,tx,ty)
Imager::ImgRaw im
Imager::ImgRaw src
- int x1
- int y1
- int x2
- int y2
- int tx
- int ty
+ i_img_dim x1
+ i_img_dim y1
+ i_img_dim x2
+ i_img_dim y2
+ i_img_dim tx
+ i_img_dim ty
void
i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
Imager::ImgRaw im
Imager::ImgRaw src
- int x1
- int y1
- int x2
- int y2
- int tx
- int ty
+ i_img_dim x1
+ i_img_dim y1
+ i_img_dim x2
+ i_img_dim y2
+ i_img_dim tx
+ i_img_dim ty
Imager::Color trans
Imager::ImgRaw
i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
Imager::ImgRaw im
Imager::ImgRaw src
- int tx
- int ty
- int src_minx
- int src_miny
- int src_maxx
- int src_maxy
+ i_img_dim tx
+ i_img_dim ty
+ i_img_dim src_minx
+ i_img_dim src_miny
+ i_img_dim src_maxx
+ i_img_dim src_maxy
undef_int
i_compose(out, src, out_left, out_top, src_left, src_top, width, height, combine = ic_normal, opacity = 0.0)
Imager::ImgRaw out
Imager::ImgRaw src
- int out_left
- int out_top
- int src_left
- int src_top
- int width
- int height
+ i_img_dim out_left
+ i_img_dim out_top
+ i_img_dim src_left
+ i_img_dim src_top
+ i_img_dim width
+ i_img_dim height
int combine
double opacity
Imager::ImgRaw out
Imager::ImgRaw src
Imager::ImgRaw mask
- int out_left
- int out_top
- int src_left
- int src_top
- int mask_left
- int mask_top
- int width
- int height
+ i_img_dim out_left
+ i_img_dim out_top
+ i_img_dim src_left
+ i_img_dim src_top
+ i_img_dim mask_left
+ i_img_dim mask_top
+ i_img_dim width
+ i_img_dim height
int combine
double opacity
+Imager::ImgRaw
+i_combine(src_av, channels_av = NULL)
+ AV *src_av
+ AV *channels_av
+ PREINIT:
+ i_img **imgs = NULL;
+ STRLEN in_count;
+ int *channels = NULL;
+ int i;
+ SV **psv;
+ IV tmp;
+ CODE:
+ in_count = av_len(src_av) + 1;
+ if (in_count > 0) {
+ imgs = mymalloc(sizeof(i_img*) * in_count);
+ channels = mymalloc(sizeof(int) * in_count);
+ for (i = 0; i < in_count; ++i) {
+ psv = av_fetch(src_av, i, 0);
+ if (!psv || !*psv || !sv_derived_from(*psv, "Imager::ImgRaw")) {
+ myfree(imgs);
+ myfree(channels);
+ croak("imgs must contain only images");
+ }
+ tmp = SvIV((SV*)SvRV(*psv));
+ imgs[i] = INT2PTR(i_img*, tmp);
+ if (channels_av &&
+ (psv = av_fetch(channels_av, i, 0)) != NULL &&
+ *psv) {
+ channels[i] = SvIV(*psv);
+ }
+ else {
+ channels[i] = 0;
+ }
+ }
+ }
+ RETVAL = i_combine(imgs, channels, in_count);
+ myfree(imgs);
+ myfree(channels);
+ OUTPUT:
+ RETVAL
+
undef_int
i_flipxy(im, direction)
Imager::ImgRaw im
Imager::ImgRaw
i_matrix_transform(im, xsize, ysize, matrix, ...)
Imager::ImgRaw im
- int xsize
- int ysize
+ i_img_dim xsize
+ i_img_dim ysize
PREINIT:
double matrix[9];
AV *av;
void
i_unsharp_mask(im,stdev,scale)
Imager::ImgRaw im
- float stdev
+ double stdev
double scale
int
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) {
Imager::ImgRaw im1
Imager::ImgRaw im2
-undef_int
-i_init_fonts(t1log=0)
- int t1log
+int
+i_img_samef(im1, im2, epsilon = i_img_epsilonf(), what=NULL)
+ Imager::ImgRaw im1
+ Imager::ImgRaw im2
+ double epsilon
+ const char *what
+
+double
+i_img_epsilonf()
bool
_is_color_object(sv)
OUTPUT:
RETVAL
-#ifdef HAVE_LIBT1
-
-void
-i_t1_set_aa(st)
- int st
-
-int
-i_t1_new(pfb,afm)
- char* pfb
- char* afm
-
-int
-i_t1_destroy(font_id)
- int font_id
-
-
-undef_int
-i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
- Imager::ImgRaw im
- int xb
- int yb
- int channel
- int fontnum
- float points
- SV* str_sv
- int align
- int utf8
- char* flags
- PREINIT:
- char *str;
- STRLEN len;
- CODE:
-#ifdef SvUTF8
- if (SvUTF8(str_sv))
- utf8 = 1;
-#endif
- str = SvPV(str_sv, len);
- RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
- utf8,flags);
- OUTPUT:
- RETVAL
-
-
-void
-i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
- int fontnum
- float point
- SV* str_sv
- int utf8
- char* flags
- PREINIT:
- char *str;
- STRLEN len;
- int cords[BOUNDING_BOX_COUNT];
- int i;
- int rc;
- PPCODE:
-#ifdef SvUTF8
- if (SvUTF8(str_sv))
- utf8 = 1;
-#endif
- str = SvPV(str_sv, len);
- rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
- if (rc > 0) {
- EXTEND(SP, rc);
- for (i = 0; i < rc; ++i)
- PUSHs(sv_2mortal(newSViv(cords[i])));
- }
-
-
-
-undef_int
-i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
- Imager::ImgRaw im
- int xb
- int yb
- Imager::Color cl
- int fontnum
- float points
- SV* str_sv
- int align
- int utf8
- char* flags
- PREINIT:
- char *str;
- STRLEN len;
- CODE:
-#ifdef SvUTF8
- if (SvUTF8(str_sv))
- utf8 = 1;
-#endif
- str = SvPV(str_sv, len);
- RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
- utf8,flags);
- OUTPUT:
- RETVAL
-
-void
-i_t1_has_chars(handle, text_sv, utf8 = 0)
- int handle
- SV *text_sv
- int utf8
- PREINIT:
- char const *text;
- STRLEN len;
- char *work;
- int count;
- int i;
- PPCODE:
-#ifdef SvUTF8
- if (SvUTF8(text_sv))
- utf8 = 1;
-#endif
- text = SvPV(text_sv, len);
- work = mymalloc(len);
- count = i_t1_has_chars(handle, text, len, utf8, work);
- if (GIMME_V == G_ARRAY) {
- EXTEND(SP, count);
- for (i = 0; i < count; ++i) {
- PUSHs(sv_2mortal(newSViv(work[i])));
- }
- }
- else {
- EXTEND(SP, 1);
- PUSHs(sv_2mortal(newSVpv(work, count)));
- }
- myfree(work);
-
-void
-i_t1_face_name(handle)
- int handle
- PREINIT:
- char name[255];
- int len;
- PPCODE:
- len = i_t1_face_name(handle, name, sizeof(name));
- if (len) {
- EXTEND(SP, 1);
- PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
- }
-
-void
-i_t1_glyph_name(handle, text_sv, utf8 = 0)
- int handle
- SV *text_sv
- int utf8
- PREINIT:
- char const *text;
- STRLEN work_len;
- size_t len;
- char name[255];
- PPCODE:
-#ifdef SvUTF8
- if (SvUTF8(text_sv))
- utf8 = 1;
-#endif
- text = SvPV(text_sv, work_len);
- len = work_len;
- while (len) {
- unsigned long ch;
- if (utf8) {
- ch = i_utf8_advance(&text, &len);
- if (ch == ~0UL) {
- i_push_error(0, "invalid UTF8 character");
- break;
- }
- }
- else {
- ch = *text++;
- --len;
- }
- EXTEND(SP, 1);
- if (i_t1_glyph_name(handle, ch, name, sizeof(name))) {
- PUSHs(sv_2mortal(newSVpv(name, 0)));
- }
- else {
- PUSHs(&PL_sv_undef);
- }
- }
-
-#endif
-
#ifdef HAVE_LIBTT
int
TT_CLONE_SKIP(...)
CODE:
+ (void)items; /* avoid unused warning */
RETVAL = 1;
OUTPUT:
RETVAL
i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
Imager::Font::TT handle
Imager::ImgRaw im
- int xb
- int yb
+ i_img_dim xb
+ i_img_dim yb
Imager::Color cl
- float points
+ double points
SV * str_sv
int smooth
int utf8
i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
Imager::Font::TT handle
Imager::ImgRaw im
- int xb
- int yb
+ i_img_dim xb
+ i_img_dim yb
int channel
- float points
+ double points
SV * str_sv
int smooth
int utf8
void
i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
Imager::Font::TT handle
- float point
+ double point
SV* str_sv
int utf8
PREINIT:
- int cords[BOUNDING_BOX_COUNT],rc;
+ i_img_dim cords[BOUNDING_BOX_COUNT];
+ int rc;
char * str;
STRLEN len;
int i;
char const *text;
STRLEN len;
char *work;
- int count;
- int i;
+ size_t count;
+ size_t i;
PPCODE:
#ifdef SvUTF8
if (SvUTF8(text_sv))
if (GIMME_V == G_ARRAY) {
EXTEND(SP, count);
for (i = 0; i < count; ++i) {
- PUSHs(sv_2mortal(newSViv(work[i])));
+ PUSHs(boolSV(work[i]));
}
}
else {
Imager::Font::TT handle
PREINIT:
char name[255];
- int len;
+ size_t len;
PPCODE:
len = i_tt_face_name(handle, name, sizeof(name));
if (len) {
EXTEND(SP, 1);
- PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
+ PUSHs(sv_2mortal(newSVpv(name, len-1)));
}
void
char const *text;
STRLEN work_len;
size_t len;
- int outsize;
+ size_t outsize;
char name[255];
PPCODE:
#ifdef SvUTF8
Imager::ImgRaw
i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
Imager::IO ig
- int x
- int y
+ i_img_dim x
+ i_img_dim y
int datachannels
int storechannels
int intrl
Imager::ImgRaw
i_scaleaxis(im,Value,Axis)
Imager::ImgRaw im
- float Value
+ double Value
int Axis
Imager::ImgRaw
i_scale_nn(im,scx,scy)
Imager::ImgRaw im
- float scx
- float scy
+ double scx
+ double scy
Imager::ImgRaw
i_scale_mixing(im, width, height)
Imager::ImgRaw im
- int width
- int height
+ i_img_dim width
+ i_img_dim height
Imager::ImgRaw
i_haar(im)
XSRETURN(col_cnt);
-Imager::ImgRaw
+void
i_transform(im,opx,opy,parm)
Imager::ImgRaw im
PREINIT:
double* parm;
- int* opx;
- int* opy;
+ int *opx;
+ int *opy;
int opxl;
int opyl;
int parmlen;
AV* av;
SV* sv1;
int i;
- CODE:
+ 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");
sv1=(*(av_fetch(av,i,0)));
parm[i]=(double)SvNV(sv1);
}
- RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
+ result=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
myfree(parm);
myfree(opy);
myfree(opx);
- ST(0) = sv_newmortal();
- if (RETVAL == 0) ST(0)=&PL_sv_undef;
- else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
+ if (result) {
+ SV *result_sv = sv_newmortal();
+ EXTEND(SP, 1);
+ sv_setref_pv(result_sv, "Imager::ImgRaw", (void*)result);
+ PUSHs(result_sv);
+ }
-Imager::ImgRaw
+void
i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
SV *sv_width
SV *sv_height
AV *av_in_imgs
int channels
PREINIT:
- int width;
- int height;
+ i_img_dim width;
+ i_img_dim height;
struct rm_op *ops;
STRLEN ops_len;
int ops_count;
SV *sv1;
IV tmp;
int i;
- CODE:
+ i_img *result;
+ PPCODE:
in_imgs_count = av_len(av_in_imgs)+1;
for (i = 0; i < in_imgs_count; ++i) {
c_regs = mymalloc(c_regs_count * sizeof(i_color));
/* I don't bother initializing the colou?r registers */
- RETVAL=i_transform2(width, height, channels, ops, ops_count,
+ result=i_transform2(width, height, channels, ops, ops_count,
n_regs, n_regs_count,
c_regs, c_regs_count, in_imgs, in_imgs_count);
if (in_imgs)
myfree(in_imgs);
myfree(n_regs);
myfree(c_regs);
- ST(0) = sv_newmortal();
- if (RETVAL == 0) ST(0)=&PL_sv_undef;
- else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
+ if (result) {
+ SV *result_sv = sv_newmortal();
+ EXTEND(SP, 1);
+ sv_setref_pv(result_sv, "Imager::ImgRaw", (void*)result);
+ PUSHs(result_sv);
+ }
void
Imager::ImgRaw im
Imager::ImgRaw bump
int channel
- int light_x
- int light_y
- int strength
+ i_img_dim light_x
+ i_img_dim light_y
+ i_img_dim strength
void
Imager::ImgRaw im
Imager::ImgRaw bump
int channel
- int tx
- int ty
- float Lx
- float Ly
- float Lz
+ i_img_dim tx
+ i_img_dim ty
+ double Lx
+ double Ly
+ double Lz
float cd
float cs
float n
void
i_mosaic(im,size)
Imager::ImgRaw im
- int size
+ i_img_dim size
void
i_watermark(im,wmark,tx,ty,pixdiff)
Imager::ImgRaw im
Imager::ImgRaw wmark
- int tx
- int ty
+ i_img_dim tx
+ i_img_dim ty
int pixdiff
Imager::ImgRaw im
PREINIT:
int num;
- int *xo;
- int *yo;
+ i_img_dim *xo;
+ i_img_dim *yo;
i_color *ival;
int dmeasure;
int i;
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(int) * num );
- yo = mymalloc( sizeof(int) * num );
+ 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] = (int)SvIV(* av_fetch(axx, i, 0));
- yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
+ 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);
Imager::ImgRaw im
PREINIT:
int num;
- int *xo;
- int *yo;
+ i_img_dim *xo;
+ i_img_dim *yo;
i_color *ival;
int dmeasure;
int 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(int) * num );
- yo = mymalloc( sizeof(int) * num );
+ 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] = (int)SvIV(* av_fetch(axx, i, 0));
- yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
+ 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);
SV *
i_get_pixel(im, x, y)
Imager::ImgRaw im
- int x
- int y;
+ i_img_dim x
+ i_img_dim y;
PREINIT:
i_color *color;
CODE:
int
i_ppix(im, x, y, cl)
Imager::ImgRaw im
- int x
- int y
+ i_img_dim x
+ i_img_dim y
Imager::Color cl
Imager::ImgRaw
i_img_pal_new(x, y, channels, maxpal)
- int x
- int y
+ i_img_dim x
+ i_img_dim y
int channels
int maxpal
i_img_to_rgb(src)
Imager::ImgRaw src
+void
+i_img_make_palette(HV *quant_hv, ...)
+ PREINIT:
+ size_t count = items - 1;
+ i_quantize quant;
+ i_img **imgs = NULL;
+ ssize_t i;
+ PPCODE:
+ if (count <= 0)
+ croak("Please supply at least one image (%d)", (int)count);
+ imgs = mymalloc(sizeof(i_img *) * count);
+ for (i = 0; i < count; ++i) {
+ SV *img_sv = ST(i + 1);
+ if (SvROK(img_sv) && sv_derived_from(img_sv, "Imager::ImgRaw")) {
+ imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(img_sv)));
+ }
+ else {
+ myfree(imgs);
+ croak("Image %d is not an image object", (int)i+1);
+ }
+ }
+ memset(&quant, 0, sizeof(quant));
+ quant.version = 1;
+ quant.mc_size = 256;
+ ip_handle_quant_opts(aTHX_ &quant, quant_hv);
+ i_quant_makemap(&quant, imgs, count);
+ EXTEND(SP, quant.mc_count);
+ for (i = 0; i < quant.mc_count; ++i) {
+ SV *sv_c = make_i_color_sv(aTHX_ quant.mc_colors + i);
+ PUSHs(sv_c);
+ }
+ ip_cleanup_quant_opts(aTHX_ &quant);
+
+
void
i_gpal(im, l, r, y)
Imager::ImgRaw im
- int l
- int r
- int y
+ i_img_dim l
+ i_img_dim r
+ i_img_dim y
PREINIT:
i_palidx *work;
int count, i;
int
i_ppal(im, l, y, ...)
Imager::ImgRaw im
- int l
- int y
+ i_img_dim l
+ i_img_dim y
PREINIT:
i_palidx *work;
- int i;
+ i_img_dim i;
CODE:
if (items > 3) {
- work = mymalloc(sizeof(i_palidx) * (items-3));
+ work = malloc_temp(aTHX_ sizeof(i_palidx) * (items-3));
for (i=0; i < items-3; ++i) {
work[i] = SvIV(ST(i+3));
}
validate_i_ppal(im, work, items - 3);
RETVAL = i_ppal(im, l, l+items-3, y, work);
- myfree(work);
}
else {
RETVAL = 0;
int
i_ppal_p(im, l, y, data)
Imager::ImgRaw im
- int l
- int y
+ i_img_dim l
+ i_img_dim y
SV *data
PREINIT:
i_palidx const *work;
colors = mymalloc(sizeof(i_color) * count);
if (i_getcolors(im, index, colors, count)) {
for (i = 0; i < count; ++i) {
- i_color *pv;
- SV *sv = sv_newmortal();
- pv = mymalloc(sizeof(i_color));
- *pv = colors[i];
- sv_setref_pv(sv, "Imager::Color", (void *)pv);
+ SV *sv = make_i_color_sv(aTHX_ colors+i);
PUSHs(sv);
}
}
Imager::ImgRaw im
void
-i_gsamp(im, l, r, y, ...)
+i_gsamp(im, l, r, y, channels)
Imager::ImgRaw im
- int l
- int r
- int y
+ i_img_dim l
+ i_img_dim r
+ i_img_dim y
+ i_channel_list channels
PREINIT:
- int *chans;
- int chan_count;
i_sample_t *data;
- int count, i;
+ i_img_dim count, i;
PPCODE:
- if (items < 5)
- croak("No channel numbers supplied to g_samp()");
if (l < r) {
- chan_count = items - 4;
- chans = mymalloc(sizeof(int) * chan_count);
- for (i = 0; i < chan_count; ++i)
- chans[i] = SvIV(ST(i+4));
- data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
- count = i_gsamp(im, l, r, y, data, chans, chan_count);
- myfree(chans);
+ data = mymalloc(sizeof(i_sample_t) * (r-l) * channels.count); /* XXX: memleak? */
+ count = i_gsamp(im, l, r, y, data, channels.channels, channels.count);
if (GIMME_V == G_ARRAY) {
EXTEND(SP, count);
for (i = 0; i < count; ++i)
}
undef_neg_int
-i_gsamp_bits(im, l, r, y, bits, target, offset, ...)
+i_gsamp_bits(im, l, r, y, bits, target, offset, channels)
Imager::ImgRaw im
- int l
- int r
- int y
+ i_img_dim l
+ i_img_dim r
+ i_img_dim y
int bits
AV *target
- int offset
+ STRLEN offset
+ i_channel_list channels
PREINIT:
- int *chans;
- int chan_count;
unsigned *data;
- int count, i;
+ i_img_dim count, i;
CODE:
i_clear_error();
if (items < 8)
croak("No channel numbers supplied to g_samp()");
if (l < r) {
- chan_count = items - 7;
- chans = mymalloc(sizeof(int) * chan_count);
- for (i = 0; i < chan_count; ++i)
- chans[i] = SvIV(ST(i+7));
- data = mymalloc(sizeof(unsigned) * (r-l) * chan_count);
- count = i_gsamp_bits(im, l, r, y, data, chans, chan_count, bits);
- myfree(chans);
+ data = mymalloc(sizeof(unsigned) * (r-l) * channels.count);
+ count = i_gsamp_bits(im, l, r, y, data, channels.channels, channels.count, bits);
for (i = 0; i < count; ++i) {
av_store(target, i+offset, newSVuv(data[i]));
}
RETVAL
undef_neg_int
-i_psamp_bits(im, l, y, bits, channels_sv, data_av, data_offset = 0, pixel_count = -1)
+i_psamp_bits(im, l, y, bits, channels, data_av, data_offset = 0, pixel_count = -1)
Imager::ImgRaw im
- int l
- int y
+ i_img_dim l
+ i_img_dim y
int bits
- SV *channels_sv
+ i_channel_list channels
AV *data_av
- int data_offset
- int pixel_count
+ i_img_dim data_offset
+ i_img_dim pixel_count
PREINIT:
- int chan_count;
- int *channels;
- int data_count;
- int data_used;
+ STRLEN data_count;
+ size_t data_used;
unsigned *data;
- int i;
+ ptrdiff_t i;
CODE:
i_clear_error();
- if (SvOK(channels_sv)) {
- AV *channels_av;
- if (!SvROK(channels_sv) || SvTYPE(SvRV(channels_sv)) != SVt_PVAV) {
- croak("channels is not an array ref");
- }
- channels_av = (AV *)SvRV(channels_sv);
- chan_count = av_len(channels_av) + 1;
- if (chan_count < 1) {
- croak("i_psamp_bits: no channels provided");
- }
- channels = mymalloc(sizeof(int) * chan_count);
- for (i = 0; i < chan_count; ++i)
- channels[i] = SvIV(*av_fetch(channels_av, i, 0));
- }
- else {
- chan_count = im->channels;
- channels = NULL;
- }
data_count = av_len(data_av) + 1;
if (data_offset < 0) {
- croak("data_offset must by non-negative");
+ croak("data_offset must be non-negative");
}
if (data_offset > data_count) {
croak("data_offset greater than number of samples supplied");
}
if (pixel_count == -1 ||
- data_offset + pixel_count * chan_count > data_count) {
- pixel_count = (data_count - data_offset) / chan_count;
+ data_offset + pixel_count * channels.count > data_count) {
+ pixel_count = (data_count - data_offset) / channels.count;
}
- data_used = pixel_count * chan_count;
+ data_used = pixel_count * channels.count;
data = mymalloc(sizeof(unsigned) * data_count);
for (i = 0; i < data_used; ++i)
data[i] = SvUV(*av_fetch(data_av, data_offset + i, 0));
- RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels,
- chan_count, bits);
+ RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels.channels,
+ channels.count, bits);
if (data)
myfree(data);
- if (channels)
- myfree(channels);
OUTPUT:
RETVAL
+undef_neg_int
+i_psamp(im, x, y, channels, data, offset = 0, width = -1)
+ Imager::ImgRaw im
+ i_img_dim x
+ i_img_dim y
+ i_channel_list channels
+ i_sample_list data
+ i_img_dim offset
+ i_img_dim width
+ PREINIT:
+ i_img_dim r;
+ CODE:
+ i_clear_error();
+ if (offset < 0) {
+ i_push_error(0, "offset must be non-negative");
+ XSRETURN_UNDEF;
+ }
+ if (offset > 0) {
+ if (offset > data.count) {
+ i_push_error(0, "offset greater than number of samples supplied");
+ XSRETURN_UNDEF;
+ }
+ data.samples += offset;
+ data.count -= offset;
+ }
+ if (width == -1 ||
+ width * channels.count > data.count) {
+ width = data.count / channels.count;
+ }
+ r = x + width;
+ RETVAL = i_psamp(im, x, r, y, data.samples, channels.channels, channels.count);
+ OUTPUT:
+ RETVAL
+
+undef_neg_int
+i_psampf(im, x, y, channels, data, offset = 0, width = -1)
+ Imager::ImgRaw im
+ i_img_dim x
+ i_img_dim y
+ i_channel_list channels
+ i_fsample_list data
+ i_img_dim offset
+ i_img_dim width
+ PREINIT:
+ i_img_dim r;
+ CODE:
+ i_clear_error();
+ if (offset < 0) {
+ i_push_error(0, "offset must be non-negative");
+ XSRETURN_UNDEF;
+ }
+ if (offset > 0) {
+ if (offset > data.count) {
+ i_push_error(0, "offset greater than number of samples supplied");
+ XSRETURN_UNDEF;
+ }
+ data.samples += offset;
+ data.count -= offset;
+ }
+ if (width == -1 ||
+ width * channels.count > data.count) {
+ width = data.count / channels.count;
+ }
+ r = x + width;
+ RETVAL = i_psampf(im, x, r, y, data.samples, channels.channels, channels.count);
+ OUTPUT:
+ RETVAL
+
Imager::ImgRaw
i_img_masked_new(targ, mask, x, y, w, h)
Imager::ImgRaw targ
- int x
- int y
- int w
- int h
+ i_img_dim x
+ i_img_dim y
+ i_img_dim w
+ i_img_dim h
PREINIT:
i_img *mask;
CODE:
int
i_plin(im, l, y, ...)
Imager::ImgRaw im
- int l
- int y
+ i_img_dim l
+ i_img_dim y
PREINIT:
i_color *work;
- int i;
+ STRLEN i;
STRLEN len;
- int count;
+ size_t count;
CODE:
if (items > 3) {
if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
int
i_ppixf(im, x, y, cl)
Imager::ImgRaw im
- int x
- int y
+ i_img_dim x
+ i_img_dim y
Imager::Color::Float cl
void
-i_gsampf(im, l, r, y, ...)
+i_gsampf(im, l, r, y, channels)
Imager::ImgRaw im
- int l
- int r
- int y
+ i_img_dim l
+ i_img_dim r
+ i_img_dim y
+ i_channel_list channels
PREINIT:
- int *chans;
- int chan_count;
i_fsample_t *data;
- int count, i;
+ i_img_dim count, i;
PPCODE:
- if (items < 5)
- croak("No channel numbers supplied to g_sampf()");
if (l < r) {
- chan_count = items - 4;
- chans = mymalloc(sizeof(int) * chan_count);
- for (i = 0; i < chan_count; ++i)
- chans[i] = SvIV(ST(i+4));
- data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
- count = i_gsampf(im, l, r, y, data, chans, chan_count);
- myfree(chans);
+ data = mymalloc(sizeof(i_fsample_t) * (r-l) * channels.count);
+ count = i_gsampf(im, l, r, y, data, channels.channels, channels.count);
if (GIMME_V == G_ARRAY) {
EXTEND(SP, count);
for (i = 0; i < count; ++i)
int
i_plinf(im, l, y, ...)
Imager::ImgRaw im
- int l
- int y
+ i_img_dim l
+ i_img_dim y
PREINIT:
i_fcolor *work;
- int i;
+ i_img_dim i;
STRLEN len;
- int count;
+ size_t count;
CODE:
if (items > 3) {
if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
SV *
i_gpixf(im, x, y)
Imager::ImgRaw im
- int x
- int y;
+ i_img_dim x
+ i_img_dim y;
PREINIT:
i_fcolor *color;
CODE:
void
i_glin(im, l, r, y)
Imager::ImgRaw im
- int l
- int r
- int y
+ i_img_dim l
+ i_img_dim r
+ i_img_dim y
PREINIT:
i_color *vals;
- int count, i;
+ i_img_dim count, i;
PPCODE:
if (l < r) {
vals = mymalloc((r-l) * sizeof(i_color));
if (GIMME_V == G_ARRAY) {
EXTEND(SP, count);
for (i = 0; i < count; ++i) {
- SV *sv;
- i_color *col = mymalloc(sizeof(i_color));
- *col = vals[i];
- sv = sv_newmortal();
- sv_setref_pv(sv, "Imager::Color", (void *)col);
+ SV *sv = make_i_color_sv(aTHX_ vals+i);
PUSHs(sv);
}
}
void
i_glinf(im, l, r, y)
Imager::ImgRaw im
- int l
- int r
- int y
+ i_img_dim l
+ i_img_dim r
+ i_img_dim y
PREINIT:
i_fcolor *vals;
- int count, i;
+ i_img_dim count, i;
i_fcolor zero;
PPCODE:
for (i = 0; i < MAXCHANNELS; ++i)
myfree(vals);
}
+Imager::ImgRaw
+i_img_8_new(x, y, ch)
+ i_img_dim x
+ i_img_dim y
+ int ch
+
Imager::ImgRaw
i_img_16_new(x, y, ch)
- int x
- int y
+ i_img_dim x
+ i_img_dim y
int ch
Imager::ImgRaw
Imager::ImgRaw
i_img_double_new(x, y, ch)
- int x
- int y
+ i_img_dim x
+ i_img_dim y
int ch
+Imager::ImgRaw
+i_img_to_drgb(im)
+ Imager::ImgRaw im
+
undef_int
i_tags_addn(im, name, code, idata)
Imager::ImgRaw im
int
IFILL_CLONE_SKIP(...)
CODE:
+ (void)items; /* avoid unused warning for XS variable */
RETVAL = 1;
OUTPUT:
RETVAL
Imager::Color bg
int combine
int hatch
- int dx
- int dy
+ i_img_dim dx
+ i_img_dim dy
PREINIT:
unsigned char *cust_hatch;
STRLEN len;
Imager::Color::Float bg
int combine
int hatch
- int dx
- int dy
+ i_img_dim dx
+ i_img_dim dy
PREINIT:
unsigned char *cust_hatch;
STRLEN len;
Imager::FillHandle
i_new_fill_image(src, matrix, xoff, yoff, combine)
Imager::ImgRaw src
- int xoff
- int yoff
+ i_img_dim xoff
+ i_img_dim yoff
int combine
PREINIT:
double matrix[9];
Imager::Internal::Hlines
i_int_hlines_new(start_y, count_y, start_x, count_x)
- int start_y
+ i_img_dim start_y
int count_y
- int start_x
+ i_img_dim start_x
int count_x
Imager::Internal::Hlines
void
i_int_hlines_add(hlines, y, minx, width)
Imager::Internal::Hlines hlines
- int y
- int minx
- int width
+ i_img_dim y
+ i_img_dim minx
+ i_img_dim width
void
i_int_hlines_DESTROY(hlines)
int
i_int_hlines_CLONE_SKIP(cls)
- SV *cls
+
+#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");
+ 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;
\ No newline at end of file
+ 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