#ifdef HAVELIB_IUPCD
/* XXX-CHECKLATER include all headers for all supported drivers */
#include <cdcgm.h> /* CD_CGM */
#include <cddebug.h> /* CD_DEBUG */
#include <cddgn.h> /* CD_DGN */
#include <cddxf.h> /* CD_DXF */
#include <cdemf.h> /* CD_EMF */
#include <cdmf.h> /* CD_METAFILE */
#include <cdps.h> /* CD_PS */
#include <cdsvg.h> /* CD_SVG */
#include <cdwmf.h> /* CD_WMF */
#include <cdirgb.h> /* CD_IMAGERGB CD_DBUFFERRGB */
/* #include <cdclipbd.h> / * CD_CLIPBOARD */
/* #include <cdpicture.h> / * CD_PICTURE */
/* #include <cdprint.h> / * CD_PRINTER */
/* #include <cddbuf.h> / * CD_DBUFFER */
/* #include <cdimage.h> / * CD_IMAGE */
/* #include <cdpdf.h> / * CD_PDF */
/* #include <cdnative.h> / * CD_NATIVEWINDOW */
/* #include <cdiup.h> / * CD_IUP */
/* #include <cdgl.h> / * CD_GL */
#endif
/* convert 'SV' to 'Ihandle*' + do undef->NULL conversion */
#define mySV2IHN(a) (SvIOK(a) ? INT2PTR(Ihandle *, SvIVX(a)) : NULL)
cdCanvas* ref2cnv(SV* ref) {
HV* h;
SV** s;
if ((h = (HV*)(SvRV(ref))) == NULL) return NULL;
if ((s = hv_fetchs(h, "!int!cnvhandle", 0)) != NULL) return INT2PTR(cdCanvas*,SvIVX(*s));
return NULL;
}
int AV2transmatrix(SV *A, double *buffer) {
AV *array;
int lastindex, i;
if ((!SvROK(A)) || (SvTYPE(SvRV(A)) != SVt_PVAV)) return 0;
array = (AV *)SvRV(A);
lastindex = av_len(array);
if (lastindex<5) return 0;
for(i=0; i<6; i++) buffer[i] = (double)SvNV(*av_fetch(array,i,0));
return 1;
}
SV* transmatrix2AV(double *buffer) {
int i;
AV* array;
array = (AV *)sv_2mortal((SV *)newAV()); /* new array */
av_extend(array,6); /* not needed but faster */
for(i=0; i<6; i++) av_push(array,newSVnv(buffer[i]));
return newRV((SV*)array);
}
int AV2int(SV *A, int **data, int *n) {
int * buffer;
int lastindex, i;
AV *array;
if( (!SvROK(A)) || (SvTYPE(SvRV(A)) != SVt_PVAV) ) return 0;
array = (AV *)SvRV(A);
lastindex = av_len(array);
buffer = malloc(sizeof(int)*(lastindex+1));
if (!buffer) return 0;
for(i=0; i<=lastindex; i++) buffer[i] = (int)SvIV(*av_fetch(array,i,0));
*data = buffer;
*n = lastindex+1;
return 1;
}
int AV2long(SV *A, long **data, int *n) {
long * buffer;
int lastindex, i;
AV *array;
if( (!SvROK(A)) || (SvTYPE(SvRV(A)) != SVt_PVAV) ) return 0;
array = (AV *)SvRV(A);
lastindex = av_len(array);
buffer = malloc(sizeof(long)*(lastindex+1));
if (!buffer) return 0;
for(i=0; i<=lastindex; i++) buffer[i] = (long)SvIV(*av_fetch(array,i,0));
*data = buffer;
*n = lastindex+1;
return 1;
}
SV* long2AV(long *data, int n) {
int i;
AV *array;
array = (AV *)sv_2mortal((SV *)newAV());
av_extend(array,n); /* not needed but faster */
for(i=0; i<n; i++) av_push(array,newSViv(data[i]));
return newRV((SV*)array);
}
int AV2bitmap(SV *A1, unsigned char **r, unsigned char **g, unsigned char **b, unsigned char **a, int *w, int *h) {
unsigned char *buffer_r, *buffer_g, *buffer_b, *buffer_a;
int lastindex1, lastindex2, i, j, error;
AV *array1, *array2;
SV *A2;
int n, width, height;
/* warn("XXX-DEBUG: r=%p g=%p b=%p a=%p\n",r,g,b,a); */
if (!r || !g || !b) return 0;
n = a ? 4 : 3;
/* warn("XXX-DEBUG: AV2bitmap n=%d\n",n); */
if( (!SvROK(A1)) || (SvTYPE(SvRV(A1)) != SVt_PVAV) ) return 0;
array1 = (AV *)SvRV(A1);
lastindex1 = av_len(array1);
A2 = (SV*)(*av_fetch(array1,0,0));
if( (!SvROK(A2)) || (SvTYPE(SvRV(A2)) != SVt_PVAV) ) return 0;
array2 = (AV *)SvRV(A2);
lastindex2 = av_len(array2);
/* warn("XXX-DEBUG: li1=%d li2=%d", lastindex1, lastindex2); */
if ((lastindex2+1)%n != 0) return 0;
error=0;
width = (lastindex2+1)/n;
height = (lastindex1+1);
buffer_r = malloc( sizeof(unsigned char) * width * height * n );
buffer_g = buffer_r + width * height;
buffer_b = buffer_g + width * height;
buffer_a = (n==4) ? buffer_b + width * height : NULL;
if (!buffer_r) error=1;
/* warn("XXX-DEBUG: before for\n"); */
for(i=0; (i<height && !error); i++) {
A2 = (SV*)(*av_fetch(array1,i,0));
array2 = (AV *)SvRV(A2);
if (lastindex2 != av_len(array2)) {
error=1;
}
else {
for(j=0; j<width; j++) {
buffer_r[i*width+j] = (unsigned char)SvUV(*av_fetch(array2,j*n,0));
buffer_g[i*width+j] = (unsigned char)SvUV(*av_fetch(array2,j*n+1,0));
buffer_b[i*width+j] = (unsigned char)SvUV(*av_fetch(array2,j*n+2,0));
if(n==4) buffer_a[i*width+j] = (unsigned char)SvUV(*av_fetch(array2,j*n+3,0));
}
}
}
/* warn("XXX-DEBUG: after for\n"); */
if (error) {
if (buffer_r) free(buffer_r);
if (buffer_g) free(buffer_g);
if (buffer_b) free(buffer_b);
if (buffer_a) free(buffer_a);
return 0;
}
if(r) *r = buffer_r;
if(g) *g = buffer_g;
if(b) *b = buffer_b;
if(a) *a = buffer_a;
*h = height;
*w = width;
return 1;
}
SV* Bitmap2AV(unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a, unsigned char *m, int w, int h) {
int i,j;
AV *array1, *array2;
int n = 0;
if (r) n++;
if (g) n++;
if (b) n++;
if (a) n++;
if (m) n++;
/* warn("XXX-DEBUG: Bitmap2AV n=%d r=%p g=%p b=%p a=%p m=%p w=%d h=%d\n", n,r,g,b,a,m,w,h); */
array1 = (AV *)sv_2mortal((SV *)newAV());
av_extend(array1,h); /* not needed but faster */
for(i=0; i<h; i++) {
array2 = (AV *)sv_2mortal((SV *)newAV()); /* new array */
av_extend(array2,w*n);
for(j=0; j<w; j++) {
if (r) av_push(array2,newSViv(r[i*w+j]));
if (g) av_push(array2,newSViv(g[i*w+j]));
if (b) av_push(array2,newSViv(b[i*w+j]));
if (a) av_push(array2,newSViv(a[i*w+j]));
if (m) av_push(array2,newSViv(m[i*w+j]));
}
av_push(array1,newRV((SV*)array2));
}
return newRV((SV*)array1);
}
SV* long2D2AV(long *data, int w, int h) {
int i,j;
AV *array1, *array2;
array1 = (AV *)sv_2mortal((SV *)newAV());
av_extend(array1,h); /* not needed but faster */
for(i=0; i<h; i++) {
array2 = (AV *)sv_2mortal((SV *)newAV()); /* new array */
av_extend(array2,w); /* not needed but faster */
for(j=0; j<w; j++) av_push(array2,newSViv(data[i*w+j]));
av_push(array1,newRV((SV*)array2));
}
return newRV((SV*)array1);
}
SV* uchar2D2AV(unsigned char *data, int w, int h) {
int i,j;
AV *array1, *array2;
array1 = (AV *)sv_2mortal((SV *)newAV());
av_extend(array1,h); /* not needed but faster */
for(i=0; i<h; i++) {
array2 = (AV *)sv_2mortal((SV *)newAV()); /* new array */
av_extend(array2,w); /* not needed but faster */
for(j=0; j<w; j++) av_push(array2,newSVuv(data[i*w+j]));
av_push(array1,newRV((SV*)array2));
}
return newRV((SV*)array1);
}
int AV2long2D(SV *A1, long **data, int *w, int *h) {
long * buffer;
int lastindex1, lastindex2, i, j, error;
AV *array1, *array2;
SV *A2;
if( (!SvROK(A1)) || (SvTYPE(SvRV(A1)) != SVt_PVAV) ) return 0;
array1 = (AV *)SvRV(A1);
lastindex1 = av_len(array1);
A2 = (SV*)(*av_fetch(array1,0,0));
if( (!SvROK(A2)) || (SvTYPE(SvRV(A2)) != SVt_PVAV) ) return 0;
array2 = (AV *)SvRV(A2);
lastindex2 = av_len(array2);
buffer = malloc( sizeof(long) * (lastindex2+1) * (lastindex1+1) );
if (!buffer) return 0;
for(error=0, i=0; (i<=lastindex1 && !error); i++) {
A2 = (SV*)(*av_fetch(array1,i,0));
array2 = (AV *)SvRV(A2);
if (lastindex2 != av_len(array2)) {
error=1;
}
else {
for(j=0; j<=lastindex2; j++) {
buffer[i*(lastindex2+1)+j] = (long)SvIV(*av_fetch(array2,j,0));
}
}
}
if (error) {
free(buffer);
return 0;
}
*data = buffer;
*h = lastindex1+1;
*w = lastindex2+1;
return 1;
}
int AV2uchar2D(SV *A1, unsigned char **data, int *w, int *h) {
unsigned char * buffer;
int lastindex1, lastindex2, i, j, error;
AV *array1, *array2;
SV *A2;
if( (!SvROK(A1)) || (SvTYPE(SvRV(A1)) != SVt_PVAV) ) return 0;
array1 = (AV *)SvRV(A1);
lastindex1 = av_len(array1);
A2 = (SV*)(*av_fetch(array1,0,0));
if( (!SvROK(A2)) || (SvTYPE(SvRV(A2)) != SVt_PVAV) ) return 0;
array2 = (AV *)SvRV(A2);
lastindex2 = av_len(array2);
buffer = malloc( sizeof(unsigned char) * (lastindex2+1) * (lastindex1+1) );
if (!buffer) return 0;
for(error=0, i=0; (i<=lastindex1 && !error); i++) {
A2 = (SV*)(*av_fetch(array1,i,0));
array2 = (AV *)SvRV(A2);
if (lastindex2 != av_len(array2)) {
error=1;
}
else {
for(j=0; j<=lastindex2; j++) {
buffer[i*(lastindex2+1)+j] = (unsigned char)SvUV(*av_fetch(array2,j,0));
}
}
}
if (error) {
free(buffer);
return 0;
}
*data = buffer;
*h = lastindex1+1;
*w = lastindex2+1;
return 1;
}
typedef struct __IUPinternal_cdPalette {
int n;
long *palette;
} *IUP__Canvas__Palette;
typedef struct __IUPinternal_cdPattern {
int w;
int h;
long *pattern;
} *IUP__Canvas__Pattern;
typedef struct __IUPinternal_cdStipple {
int w;
int h;
unsigned char *fgbg;
} *IUP__Canvas__Stipple;
typedef cdImage *IUP__Canvas__InternalServerImage;
typedef cdState *IUP__Canvas__InternalState;
typedef cdContext *IUP__Canvas__InternalContext;
typedef cdBitmap *IUP__Canvas__Bitmap;
cdBitmap* BitmapFromFile(char * file_name) {
imImage *image;
cdBitmap* bitmap;
int error;
image = imFileImageLoadBitmap(file_name, 0, &error);
/* warn("XXX-DEBUG: BitmapFromFile error=%d\n",error); */
if (error) return NULL;
if (!image) return NULL;
if (!imImageIsBitmap(image)) return NULL;
if (image->color_space == IM_RGB) {
if (image->has_alpha) {
/* warn("XXX-DEBUG: RGBA 0=%p 1=%p 2=%p 3=%p\n", image->data[0], image->data[1], image->data[2], image->data[3]); */
bitmap = cdInitBitmap(image->width, image->height, CD_RGBA, image->data[0], image->data[1], image->data[2], image->data[3]);
}
else {
/* warn("XXX-DEBUG: RGB\n"); */
bitmap = cdInitBitmap(image->width, image->height, CD_RGB, image->data[0], image->data[1], image->data[2]);
}
}
else {
/* warn("XXX-DEBUG: MAP\n"); */
bitmap = cdInitBitmap(image->width, image->height, CD_MAP, image->data[0], image->palette);
}
return(bitmap);
}