#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
+#define NEED_newRV_noinc
+#define NEED_sv_2pv_nolen
#include "ppport.h"
#ifdef __cplusplus
}
static ssize_t write_flush(struct cbdata *cbd) {
ssize_t result;
- result = call_writer(cbd, cbd->buffer, cbd->used);
- cbd->used = 0;
- return 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) {
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 */
- *(char *)0 = 0;
if (io_seeker(p, cbd->where - cbd->used, SEEK_CUR) < 0) {
return -1;
}
}
cbd->writing = 1;
if (cbd->used && cbd->used + size > cbd->maxlength) {
- if (write_flush(cbd) <= 0) {
- return 0;
+ int write_res = write_flush(cbd);
+ if (write_res <= 0) {
+ return write_res;
}
cbd->used = 0;
}
return call_writer(cbd, data, size);
}
-static ssize_t io_reader(void *p, void *data, size_t size) {
+static ssize_t
+io_reader(void *p, void *data, size_t size) {
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;
size -= cbd->used - cbd->where;
out += cbd->used - cbd->where;
if (size < sizeof(cbd->buffer)) {
- int did_read;
+ int did_read = 0;
int copy_size;
while (size
&& (did_read = call_reader(cbd, cbd->buffer, size,
total += copy_size;
size -= copy_size;
}
+ if (did_read < 0)
+ return -1;
}
else {
/* just read the rest - too big for our buffer*/
total += did_read;
out += did_read;
}
+ if (did_read < 0)
+ return -1;
}
return total;
return segs;
}
+/* validates the indexes supplied to i_ppal
+
+i_ppal() doesn't do that for speed, but I'm not comfortable doing that
+for calls from perl.
+
+*/
+static void
+validate_i_ppal(i_img *im, i_palidx const *indexes, int count) {
+ int color_count = i_colorcount(im);
+ int i;
+
+ if (color_count == -1)
+ croak("i_plin() called on direct color image");
+
+ for (i = 0; i < count; ++i) {
+ if (indexes[i] >= color_count) {
+ croak("i_plin() called with out of range color index %d (max %d)",
+ indexes[i], color_count-1);
+ }
+ }
+}
+
+
/* 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
#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
OUTPUT:
RETVAL
-SV *
+void
i_io_read(ig, buffer_sv, size)
Imager::IO ig
SV *buffer_sv
PREINIT:
void *buffer;
int result;
- CODE:
- if (size < 0)
+ PPCODE:
+ if (size <= 0)
croak("size negative in call to i_io_read()");
/* prevent an undefined value warning if they supplied an
undef buffer.
#endif
buffer = SvGROW(buffer_sv, size+1);
result = i_io_read(ig, buffer, size);
- if (result < 0) {
- RETVAL = &PL_sv_undef;
+ if (result >= 0) {
+ SvCUR_set(buffer_sv, result);
+ *SvEND(buffer_sv) = '\0';
+ SvPOK_only(buffer_sv);
+ EXTEND(SP, 1);
+ PUSHs(sv_2mortal(newSViv(result)));
}
- else {
+ ST(1) = buffer_sv;
+ SvSETMAGIC(ST(1));
+
+void
+i_io_read2(ig, size)
+ Imager::IO ig
+ int size
+ PREINIT:
+ SV *buffer_sv;
+ void *buffer;
+ int 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);
+ if (result >= 0) {
SvCUR_set(buffer_sv, result);
*SvEND(buffer_sv) = '\0';
SvPOK_only(buffer_sv);
- RETVAL = newSViv(result); /* XS will mortal this */
+ EXTEND(SP, 1);
+ PUSHs(sv_2mortal(buffer_sv));
}
- OUTPUT:
- RETVAL
- buffer_sv
+ else {
+ /* discard it */
+ SvREFCNT_dec(buffer_sv);
+ }
int
i_io_seek(ig, position, whence)
long position
int whence
-void
+int
i_io_close(ig)
Imager::IO ig
int seedy
Imager::FillHandle fill
+undef_int
+i_flood_fill_border(im,seedx,seedy,dcol, border)
+ Imager::ImgRaw im
+ int seedx
+ int 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
+ Imager::FillHandle fill
+ Imager::Color border
+
void
i_copyto(im,src,x1,y1,x2,y2,tx,ty)
float scx
float scy
+Imager::ImgRaw
+i_scale_mixing(im, width, height)
+ Imager::ImgRaw im
+ int width
+ int height
+
Imager::ImgRaw
i_haar(im)
Imager::ImgRaw im
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);
}
OUTPUT:
RETVAL
+int
+i_ppal_p(im, l, y, data)
+ Imager::ImgRaw im
+ int l
+ int y
+ SV *data
+ PREINIT:
+ i_palidx const *work;
+ STRLEN len;
+ CODE:
+ work = (i_palidx const *)SvPV(data, len);
+ len /= sizeof(i_palidx);
+ if (len > 0) {
+ validate_i_ppal(im, work, len);
+ RETVAL = i_ppal(im, l, l+len, y, work);
+ }
+ else {
+ RETVAL = 0;
+ }
+ OUTPUT:
+ RETVAL
+
SV *
i_addcolors(im, ...)
Imager::ImgRaw im
#ifdef HAVE_WIN32
void
-i_wf_bbox(face, size, text)
+i_wf_bbox(face, size, text_sv, utf8=0)
char *face
int size
- char *text
+ SV *text_sv
+ int utf8
PREINIT:
int cords[BOUNDING_BOX_COUNT];
int rc, i;
+ char const *text;
+ STRLEN text_len;
PPCODE:
- if (rc = i_wf_bbox(face, size, text, strlen(text), cords)) {
+ text = SvPV(text_sv, text_len);
+#ifdef SvUTF8
+ if (SvUTF8(text_sv))
+ utf8 = 1;
+#endif
+ if (rc = i_wf_bbox(face, size, text, text_len, cords, utf8)) {
EXTEND(SP, rc);
for (i = 0; i < rc; ++i)
PUSHs(sv_2mortal(newSViv(cords[i])));
}
undef_int
-i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
+i_wf_text(face, im, tx, ty, cl, size, text_sv, align, aa, utf8 = 0)
char *face
Imager::ImgRaw im
int tx
int ty
Imager::Color cl
int size
- char *text
+ SV *text_sv
int align
int aa
+ int utf8
+ PREINIT:
+ char const *text;
+ STRLEN text_len;
CODE:
- RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
- align, aa);
+ text = SvPV(text_sv, text_len);
+#ifdef SvUTF8
+ if (SvUTF8(text_sv))
+ utf8 = 1;
+#endif
+ RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, text_len,
+ align, aa, utf8);
OUTPUT:
RETVAL
undef_int
-i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
+i_wf_cp(face, im, tx, ty, channel, size, text_sv, align, aa, utf8 = 0)
char *face
Imager::ImgRaw im
int tx
int ty
int channel
int size
- char *text
+ SV *text_sv
int align
int aa
+ int utf8
+ PREINIT:
+ char const *text;
+ STRLEN text_len;
CODE:
- RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
- align, aa);
+ text = SvPV(text_sv, text_len);
+#ifdef SvUTF8
+ if (SvUTF8(text_sv))
+ utf8 = 1;
+#endif
+ RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, text_len,
+ align, aa, utf8);
OUTPUT:
RETVAL
RETVAL
undef_int
-i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
+i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text_sv, align, aa, vlayout, utf8)
Imager::Font::FT2 font
Imager::ImgRaw im
int tx
int channel
double cheight
double cwidth
- char *text
+ SV *text_sv
int align
int aa
int vlayout
int utf8
+ PREINIT:
+ char const *text;
+ STRLEN len;
CODE:
#ifdef SvUTF8
if (SvUTF8(ST(7)))
utf8 = 1;
#endif
+ text = SvPV(text_sv, len);
RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
- strlen(text), align, aa, vlayout, 1);
+ len, align, aa, vlayout, 1);
OUTPUT:
RETVAL