From 156699af0d2ede8cdf1a8c4bd7b4867a6e3118dd Mon Sep 17 00:00:00 2001 From: Tony Cook Date: Thu, 24 May 2012 17:23:21 +1000 Subject: [PATCH] WIP, more context changes --- dynaload.c | 11 +++-- error.c | 9 ++--- ext.h | 30 +++++++++++++- image.c | 24 +++++++++-- imager.h | 61 ++++++++-------------------- imageri.h | 2 + imdatatypes.h | 11 +++++ imerror.h | 7 +++- imexttypes.h | 4 +- img16.c | 27 +++++++++---- img8.c | 27 ++++++++----- imgdouble.c | 41 ++++++++++++------- immacros.h | 3 ++ lib/Imager/APIRef.pod | 8 ++++ log.c | 93 ++++++++++++++++++++++++++++--------------- log.h | 7 +++- palimg.c | 15 +++++-- plug.h | 9 +++-- 18 files changed, 257 insertions(+), 132 deletions(-) diff --git a/dynaload.c b/dynaload.c index 8838038a..8a12de25 100644 --- a/dynaload.c +++ b/dynaload.c @@ -11,7 +11,7 @@ typedef HMODULE minthandle_t; typedef void *minthandle_t; #endif -#include "plug.h" +#include "ext.h" struct DSO_handle_tag { minthandle_t handle; @@ -24,14 +24,19 @@ struct DSO_handle_tag { /* #include "XSUB.h" so we can compile on threaded perls */ #include "imageri.h" +static im_context_t +do_get_context(void) { + return im_get_context(); +} + static symbol_table_t symbol_table= { i_has_format, ICL_set_internal, ICL_info, - i_img_new, + do_get_context, i_img_empty, - i_img_empty_ch, + im_img_empty_ch, i_img_exorcise, i_img_info, i_img_setmask, diff --git a/error.c b/error.c index c234147c..a5f97b87 100644 --- a/error.c +++ b/error.c @@ -205,11 +205,6 @@ im_clear_error(im_context_t ctx) { ctx->error_sp = IM_ERROR_COUNT-1; } -void -i_clear_error(void) { - im_clear_error(im_get_context()); -} - /* =item i_push_error(int code, char const *msg) =synopsis i_push_error(0, "Yep, it's broken"); @@ -247,11 +242,15 @@ im_push_error(im_context_t ctx, int code, char const *msg) { ctx->error_stack[ctx->error_sp].code = code; } +#if 0 + void i_push_error(int code, char const *msg) { im_push_error(im_get_context(), code, msg); } +#endif + /* =item i_push_errorvf(int C, char const *C, va_list C) diff --git a/ext.h b/ext.h index dd1cfbd8..190ff76b 100644 --- a/ext.h +++ b/ext.h @@ -1,4 +1,4 @@ -#include "imager.h" +#include "imdatatypes.h" #ifndef IMAGER_EXT_H #define IMAGER_EXT_H @@ -20,4 +20,32 @@ typedef struct { int (*getobj)(void *hv_t,char* key,char* type,void **store); } UTIL_table_t; +typedef struct { + undef_int (*i_has_format)(char *frmt); + i_color*(*ICL_set)(i_color *cl,unsigned char r,unsigned char g,unsigned char b,unsigned char a); + void (*ICL_info)(const i_color *cl); + + im_context_t (*im_get_context_f)(void); + i_img*(*i_img_empty_f)(i_img *im,i_img_dim x,i_img_dim y); + i_img*(*im_img_empty_ch_f)(im_context_t, i_img *im,i_img_dim x,i_img_dim y,int ch); + void(*i_img_exorcise_f)(i_img *im); + + void(*i_img_info_f)(i_img *im,i_img_dim *info); + + void(*i_img_setmask)(i_img *im,int ch_mask); + int (*i_img_getmask)(i_img *im); + + /* + int (*i_ppix)(i_img *im,i_img_dim x,i_img_dim y,i_color *val); + int (*i_gpix)(i_img *im,i_img_dim x,i_img_dim y,i_color *val); + */ + void(*i_box)(i_img *im,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,const i_color *val); + void(*i_line)(i_img *im,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,const i_color *val,int endp); + void(*i_arc)(i_img *im,i_img_dim x,i_img_dim y,double rad,double d1,double d2,const i_color *val); + void(*i_copyto)(i_img *im,i_img *src,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)(i_img *im,i_img *src,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,i_img_dim tx,i_img_dim ty,const i_color *trans); + int(*i_rubthru)(i_img *im,i_img *src,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); + +} symbol_table_t; + #endif diff --git a/image.c b/image.c index a8045f24..6a4fc8dd 100644 --- a/image.c +++ b/image.c @@ -1,3 +1,5 @@ +#define IMAGER_NO_CONTEXT + #include "imager.h" #include "imageri.h" @@ -70,7 +72,7 @@ object. */ i_img * -i_img_alloc(void) { +im_img_alloc(pIMCTX) { return mymalloc(sizeof(i_img)); } @@ -87,8 +89,9 @@ support threads, or color profiles. */ void -i_img_init(i_img *img) { +im_img_init(pIMCTX, i_img *img) { img->im_data = NULL; + img->context = aIMCTX; } /* @@ -533,6 +536,7 @@ i_scaleaxis(i_img *im, double Value, int Axis) { i_img *new_img; int has_alpha = i_img_has_alpha(im); int color_chans = i_img_color_channels(im); + dIMCTXim(im); i_clear_error(); mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis)); @@ -733,6 +737,7 @@ i_scale_nn(i_img *im, double scx, double scy) { i_img_dim nxsize,nysize,nx,ny; i_img *new_img; i_color val; + dIMCTXim(im); mm_log((1,"i_scale_nn(im %p,scx %.2f,scy %.2f)\n",im,scx,scy)); @@ -773,7 +778,10 @@ For paletted images the palette is copied from the source. =cut */ -i_img *i_sametype(i_img *src, i_img_dim xsize, i_img_dim ysize) { +i_img * +i_sametype(i_img *src, i_img_dim xsize, i_img_dim ysize) { + dIMCTXim(src); + if (src->type == i_direct_type) { if (src->bits == 8) { return i_img_empty_ch(NULL, xsize, ysize, src->channels); @@ -816,7 +824,10 @@ For paletted images the equivalent direct type is returned. =cut */ -i_img *i_sametype_chans(i_img *src, i_img_dim xsize, i_img_dim ysize, int channels) { +i_img * +i_sametype_chans(i_img *src, i_img_dim xsize, i_img_dim ysize, int channels) { + dIMCTXim(src); + if (src->bits == 8) { return i_img_empty_ch(NULL, xsize, ysize, channels); } @@ -857,6 +868,7 @@ i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int par i_img_dim nxsize,nysize,nx,ny; i_img *new_img; i_color val; + dIMCTXim(im); mm_log((1,"i_transform(im %p, opx %p, opxl %d, opy %p, opyl %d, parm %p, parmlen %d)\n",im,opx,opxl,opy,opyl,parm,parmlen)); @@ -903,6 +915,7 @@ i_img_diff(i_img *im1,i_img *im2) { int ch, chb; float tdiff; i_color val1,val2; + dIMCTXim(im1); mm_log((1,"i_img_diff(im1 %p,im2 %p)\n",im1,im2)); @@ -1018,6 +1031,7 @@ i_haar(i_img *im) { int ch,c; i_img *new_img,*new_img2; i_color val1,val2,dval1,dval2; + dIMCTXim(im); mx=im->xsize; my=im->ysize; @@ -1429,6 +1443,8 @@ int i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry) { i_img_dim i_gsamp_bits_fb(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, unsigned *samps, const int *chans, int chan_count, int bits) { + dIMCTXim(im); + if (bits < 1 || bits > 32) { i_push_error(0, "Invalid bits, must be 1..32"); return -1; diff --git a/imager.h b/imager.h index b2849a00..8246e4f2 100644 --- a/imager.h +++ b/imager.h @@ -2,12 +2,11 @@ #define _IMAGE_H_ #include "imconfig.h" +#include "immacros.h" #include "imio.h" #include "iolayer.h" -#include "log.h" #include "stackmach.h" - #ifndef _MSC_VER #include #endif @@ -48,22 +47,23 @@ extern void i_hsv_to_rgbf(i_fcolor *color); extern void i_rgb_to_hsv(i_color *color); extern void i_hsv_to_rgb(i_color *color); -i_img *i_img_8_new(i_img_dim x,i_img_dim y,int ch); -i_img *i_img_new( void ); +i_img *im_img_8_new(pIMCTX, i_img_dim x,i_img_dim y,int ch); +#define i_img_8_new(x,y,ch) im_img_8_new(aIMCTX, x,y,ch) i_img *i_img_empty(i_img *im,i_img_dim x,i_img_dim y); -i_img *i_img_empty_ch(i_img *im,i_img_dim x,i_img_dim y,int ch); +i_img *im_img_empty_ch(pIMCTX, i_img *im,i_img_dim x,i_img_dim y,int ch); +#define i_img_empty_ch(im, x, y, ch) im_img_empty_ch(aIMCTX, im, x, y, ch) void i_img_exorcise(i_img *im); void i_img_destroy(i_img *im); -i_img *i_img_alloc(void); -void i_img_init(i_img *im); +i_img *im_img_alloc(pIMCTX); +#define i_img_alloc() im_img_alloc(aIMCTX) +void im_img_init(pIMCTX, i_img *im); +#define i_img_init(im) im_img_init(aIMCTX, im) void i_img_info(i_img *im,i_img_dim *info); extern i_img *i_sametype(i_img *im, i_img_dim xsize, i_img_dim ysize); extern i_img *i_sametype_chans(i_img *im, i_img_dim xsize, i_img_dim ysize, int channels); -i_img *i_img_pal_new(i_img_dim x, i_img_dim y, int ch, int maxpal); - /* Image feature settings */ void i_img_setmask (i_img *im,int ch_mask); @@ -247,14 +247,18 @@ extern void i_quant_makemap(i_quantize *quant, i_img **imgs, int count); extern i_palidx *i_quant_translate(i_quantize *quant, i_img *img); extern void i_quant_transparent(i_quantize *quant, i_palidx *indices, i_img *img, i_palidx trans_index); -extern i_img *i_img_pal_new(i_img_dim x, i_img_dim y, int channels, int maxpal); +i_img *im_img_pal_new(pIMCTX, i_img_dim x, i_img_dim y, int ch, int maxpal); +#define i_img_pal_new(x, y, ch, maxpal) im_img_pal_new(aIMCTX, x, y, ch, maxpal) + extern i_img *i_img_to_pal(i_img *src, i_quantize *quant); extern i_img *i_img_to_rgb(i_img *src); extern i_img *i_img_masked_new(i_img *targ, i_img *mask, i_img_dim x, i_img_dim y, i_img_dim w, i_img_dim h); -extern i_img *i_img_16_new(i_img_dim x, i_img_dim y, int ch); +extern i_img *im_img_16_new(pIMCTX, i_img_dim x, i_img_dim y, int ch); +#define i_img_16_new(x, y, ch) im_img_16_new(aIMCTX, x, y, ch) extern i_img *i_img_to_rgb16(i_img *im); -extern i_img *i_img_double_new(i_img_dim x, i_img_dim y, int ch); +extern i_img *im_img_double_new(pIMCTX, i_img_dim x, i_img_dim y, int ch); +#define i_img_double_new(x, y, ch) im_img_double_new(aIMCTX, x, y, ch) extern i_img *i_img_to_drgb(i_img *im); extern int i_img_is_monochrome(i_img *im, int *zero_is_white); @@ -331,36 +335,6 @@ i_new_fill_fount(double xa, double ya, double xb, double yb, void malloc_state( void ); -/* this is sort of obsolete now */ - -typedef struct { - undef_int (*i_has_format)(char *frmt); - i_color*(*ICL_set)(i_color *cl,unsigned char r,unsigned char g,unsigned char b,unsigned char a); - void (*ICL_info)(const i_color *cl); - - i_img*(*i_img_new)( void ); - i_img*(*i_img_empty)(i_img *im,i_img_dim x,i_img_dim y); - i_img*(*i_img_empty_ch)(i_img *im,i_img_dim x,i_img_dim y,int ch); - void(*i_img_exorcise)(i_img *im); - - void(*i_img_info)(i_img *im,i_img_dim *info); - - void(*i_img_setmask)(i_img *im,int ch_mask); - int (*i_img_getmask)(i_img *im); - - /* - int (*i_ppix)(i_img *im,i_img_dim x,i_img_dim y,i_color *val); - int (*i_gpix)(i_img *im,i_img_dim x,i_img_dim y,i_color *val); - */ - void(*i_box)(i_img *im,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,const i_color *val); - void(*i_line)(i_img *im,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,const i_color *val,int endp); - void(*i_arc)(i_img *im,i_img_dim x,i_img_dim y,double rad,double d1,double d2,const i_color *val); - void(*i_copyto)(i_img *im,i_img *src,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)(i_img *im,i_img *src,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,i_img_dim tx,i_img_dim ty,const i_color *trans); - int(*i_rubthru)(i_img *im,i_img *src,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); - -} symbol_table_t; - #include "imerror.h" /* image tag processing */ @@ -428,7 +402,6 @@ void malloc_state(void); #endif /* IMAGER_MALLOC_DEBUG */ #include "imrender.h" -#include "immacros.h" extern void i_adapt_colors(int dest_channels, int src_channels, i_color *colors, @@ -454,8 +427,6 @@ i_gsampf_bg(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *sampl extern im_context_t (*im_get_context)(void); -#define aIMCTX (im_get_context()) - #include "imio.h" #endif diff --git a/imageri.h b/imageri.h index 0e9815e9..34817ed1 100644 --- a/imageri.h +++ b/imageri.h @@ -119,6 +119,8 @@ typedef struct im_context_tag { #ifdef IMAGER_LOG int log_level; FILE *lg_file; + const char *filename; + int line; #endif } im_context_struct; diff --git a/imdatatypes.h b/imdatatypes.h index 1115883c..b56b43f1 100644 --- a/imdatatypes.h +++ b/imdatatypes.h @@ -285,6 +285,14 @@ i_f_psamp - implements psamp() for this image. i_f_psampf - implements psamp() for this image. +=item * + +C - image specific data internal to Imager. + +=item * + +C - the Imager API context this image belongs to. + =back =cut @@ -337,6 +345,9 @@ struct i_img_ { i_f_psampf_t i_f_psampf; void *im_data; + + /* 0.91 */ + im_context_t context; }; /* ext_data for paletted images diff --git a/imerror.h b/imerror.h index da56df1f..b51600ec 100644 --- a/imerror.h +++ b/imerror.h @@ -18,10 +18,13 @@ extern void i_set_argv0(char const *); extern int i_set_errors_fatal(int new_fatal); extern i_errmsg *i_errors(void); -extern void i_push_error(int code, char const *msg); +extern void im_push_error(pIMCTX, int code, char const *msg); +#define i_push_error(code, msg) im_push_error(aIMCTX, code, msg) extern void i_push_errorf(int code, char const *fmt, ...) I_FORMAT_ATTR(2, 3); +extern void im_push_errorf(pIMCTX, int code, char const *fmt, ...) I_FORMAT_ATTR(3, 4); extern void i_push_errorvf(int code, char const *fmt, va_list); -extern void i_clear_error(void); +extern void im_clear_error(pIMCTX); +#define i_clear_error() im_clear_error(aIMCTX); extern int i_failed(int code, char const *msg); #endif diff --git a/imexttypes.h b/imexttypes.h index 9fd1a0c0..e6a354af 100644 --- a/imexttypes.h +++ b/imexttypes.h @@ -25,8 +25,10 @@ Version 5 changed the return types of i_get_file_background() and i_get_file_backgroundf() from void to int. + Version 6 added + */ -#define IMAGER_API_VERSION 5 +#define IMAGER_API_VERSION 6 /* IMAGER_API_LEVEL is the level of the structure. New function pointers diff --git a/img16.c b/img16.c index 970a1731..cfd4da6a 100644 --- a/img16.c +++ b/img16.c @@ -20,6 +20,8 @@ sample image type to work with. =cut */ +#define IMAGER_NO_CONTEXT + #include "imager.h" #include "imageri.h" @@ -160,7 +162,8 @@ Returns the image on success, or NULL on failure. =cut */ -i_img *i_img_16_new(i_img_dim x, i_img_dim y, int ch) { +i_img * +im_img_16_new(pIMCTX, i_img_dim x, i_img_dim y, int ch) { i_img *im; size_t bytes, line_bytes; @@ -168,16 +171,16 @@ i_img *i_img_16_new(i_img_dim x, i_img_dim y, int ch) { i_DFc(x), i_DFc(y), ch)); if (x < 1 || y < 1) { - i_push_error(0, "Image sizes must be positive"); + im_push_error(aIMCTX, 0, "Image sizes must be positive"); return NULL; } if (ch < 1 || ch > MAXCHANNELS) { - i_push_errorf(0, "channels must be between 1 and %d", MAXCHANNELS); + im_push_errorf(aIMCTX, 0, "channels must be between 1 and %d", MAXCHANNELS); return NULL; } bytes = x * y * ch * 2; if (bytes / y / ch / 2 != x) { - i_push_errorf(0, "integer overflow calculating image allocation"); + im_push_errorf(aIMCTX, 0, "integer overflow calculating image allocation"); return NULL; } @@ -186,11 +189,11 @@ i_img *i_img_16_new(i_img_dim x, i_img_dim y, int ch) { working with the image */ line_bytes = sizeof(i_fcolor) * x; if (line_bytes / x != sizeof(i_fcolor)) { - i_push_error(0, "integer overflow calculating scanline allocation"); + im_push_error(aIMCTX, 0, "integer overflow calculating scanline allocation"); return NULL; } - im = i_img_alloc(); + im = im_img_alloc(aIMCTX); *im = IIM_base_16bit_direct; i_tags_new(&im->tags); im->xsize = x; @@ -201,7 +204,7 @@ i_img *i_img_16_new(i_img_dim x, i_img_dim y, int ch) { im->idata = mymalloc(im->bytes); memset(im->idata, 0, im->bytes); - i_img_init(im); + im_img_init(aIMCTX, im); return im; } @@ -223,8 +226,9 @@ i_img_to_rgb16(i_img *im) { i_img *targ; i_fcolor *line; i_img_dim y; + dIMCTXim(im); - targ = i_img_16_new(im->xsize, im->ysize, im->channels); + targ = im_img_16_new(aIMCTX, im->xsize, im->ysize, im->channels); if (!targ) return NULL; line = mymalloc(sizeof(i_fcolor) * im->xsize); @@ -556,6 +560,7 @@ i_gsamp_bits_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, unsigned *sam } else { if (chan_count <= 0 || chan_count > im->channels) { + dIMCTXim(im); i_push_error(0, "Invalid channel count"); return -1; } @@ -571,6 +576,7 @@ i_gsamp_bits_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, unsigned *sam return count; } else { + dIMCTXim(im); i_push_error(0, "Image position outside of image"); return -1; } @@ -584,6 +590,7 @@ i_psamp_bits_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, unsigned cons i_img_dim off; if (bits != 16) { + dIMCTXim(im); i_push_error(0, "Invalid bits for 16-bit image"); return -1; } @@ -615,6 +622,7 @@ i_psamp_bits_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, unsigned cons } else { if (chan_count <= 0 || chan_count > im->channels) { + dIMCTXim(im); i_push_error(0, "Invalid channel count"); return -1; } @@ -632,6 +640,7 @@ i_psamp_bits_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, unsigned cons return count; } else { + dIMCTXim(im); i_push_error(0, "Image position outside of image"); return -1; } @@ -721,6 +730,7 @@ i_psamp_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, return count; } else { + dIMCTXim(im); i_push_error(0, "Image position outside of image"); return -1; } @@ -815,6 +825,7 @@ i_psampf_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, return count; } else { + dIMCTXim(im); i_push_error(0, "Image position outside of image"); return -1; } diff --git a/img8.c b/img8.c index d905fa2c..03775496 100644 --- a/img8.c +++ b/img8.c @@ -1,3 +1,5 @@ +#define IMAGER_NO_CONTEXT + #include "imager.h" #include "imageri.h" @@ -94,18 +96,19 @@ I channels. i_img * -i_img_8_new(i_img_dim x,i_img_dim y,int ch) { +im_img_8_new(pIMCTX, i_img_dim x,i_img_dim y,int ch) { i_img *im; mm_log((1,"IIM_new(x %" i_DF ", y %" i_DF ", ch %d)\n", i_DFc(x), i_DFc(y), ch)); - im=i_img_empty_ch(NULL,x,y,ch); + im = im_img_empty_ch(aIMCTX, NULL,x,y,ch); mm_log((1,"(%p) <- IIM_new\n",im)); return im; } +#if 0 /* =item i_img_new() @@ -138,6 +141,8 @@ i_img_new() { return im; } +#endif + /* =item i_img_empty(im, x, y) @@ -155,10 +160,10 @@ Should this just call i_img_empty_ch()? */ i_img * -i_img_empty(i_img *im,i_img_dim x,i_img_dim y) { +im_img_empty(pIMCTX, i_img *im,i_img_dim x,i_img_dim y) { mm_log((1,"i_img_empty(*im %p, x %" i_DF ", y %" i_DF ")\n", im, i_DFc(x), i_DFc(y))); - return i_img_empty_ch(im, x, y, 3); + return im_img_empty_ch(aIMCTX, im, x, y, 3); } /* @@ -175,29 +180,29 @@ Re-new image reference */ i_img * -i_img_empty_ch(i_img *im,i_img_dim x,i_img_dim y,int ch) { +im_img_empty_ch(pIMCTX, i_img *im,i_img_dim x,i_img_dim y,int ch) { size_t bytes; mm_log((1,"i_img_empty_ch(*im %p, x %" i_DF ", y %" i_DF ", ch %d)\n", im, i_DFc(x), i_DFc(y), ch)); if (x < 1 || y < 1) { - i_push_error(0, "Image sizes must be positive"); + im_push_error(aIMCTX, 0, "Image sizes must be positive"); return NULL; } if (ch < 1 || ch > MAXCHANNELS) { - i_push_errorf(0, "channels must be between 1 and %d", MAXCHANNELS); + im_push_errorf(aIMCTX, 0, "channels must be between 1 and %d", MAXCHANNELS); return NULL; } /* check this multiplication doesn't overflow */ bytes = x*y*ch; if (bytes / y / ch != x) { - i_push_errorf(0, "integer overflow calculating image allocation"); + im_push_errorf(aIMCTX, 0, "integer overflow calculating image allocation"); return NULL; } if (im == NULL) - im = i_img_alloc(); + im = im_img_alloc(aIMCTX); memcpy(im, &IIM_base_8bit_direct, sizeof(i_img)); i_tags_new(&im->tags); @@ -212,7 +217,7 @@ i_img_empty_ch(i_img *im,i_img_dim x,i_img_dim y,int ch) { im->ext_data = NULL; - i_img_init(im); + im_img_init(aIMCTX, im); mm_log((1,"(%p) <- i_img_empty_ch\n",im)); return im; @@ -687,6 +692,7 @@ i_psamp_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, return count; } else { + dIMCTXim(im); i_push_error(0, "Image position outside of image"); return -1; } @@ -776,6 +782,7 @@ i_psampf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, return count; } else { + dIMCTXim(im); i_push_error(0, "Image position outside of image"); return -1; } diff --git a/imgdouble.c b/imgdouble.c index fe1ad624..80a60a41 100644 --- a/imgdouble.c +++ b/imgdouble.c @@ -20,6 +20,7 @@ sample image type to work with. =cut */ +#define IMAGER_NO_CONTEXT #include "imager.h" #include "imageri.h" @@ -99,7 +100,8 @@ Creates a new double per sample image. =cut */ -i_img *i_img_double_new(i_img_dim x, i_img_dim y, int ch) { +i_img * +im_img_double_new(pIMCTX, i_img_dim x, i_img_dim y, int ch) { size_t bytes; i_img *im; @@ -107,20 +109,20 @@ i_img *i_img_double_new(i_img_dim x, i_img_dim y, int ch) { i_DFc(x), i_DFc(y), ch)); if (x < 1 || y < 1) { - i_push_error(0, "Image sizes must be positive"); + im_push_error(aIMCTX, 0, "Image sizes must be positive"); return NULL; } if (ch < 1 || ch > MAXCHANNELS) { - i_push_errorf(0, "channels must be between 1 and %d", MAXCHANNELS); + im_push_errorf(aIMCTX, 0, "channels must be between 1 and %d", MAXCHANNELS); return NULL; } bytes = x * y * ch * sizeof(double); if (bytes / y / ch / sizeof(double) != x) { - i_push_errorf(0, "integer overflow calculating image allocation"); + im_push_errorf(aIMCTX, 0, "integer overflow calculating image allocation"); return NULL; } - im = i_img_alloc(); + im = im_img_alloc(aIMCTX); *im = IIM_base_double_direct; i_tags_new(&im->tags); im->xsize = x; @@ -130,7 +132,7 @@ i_img *i_img_double_new(i_img_dim x, i_img_dim y, int ch) { im->ext_data = NULL; im->idata = mymalloc(im->bytes); memset(im->idata, 0, im->bytes); - i_img_init(im); + im_img_init(aIMCTX, im); return im; } @@ -332,7 +334,8 @@ static i_img_dim i_gsamp_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, /* make sure we have good channel numbers */ for (ch = 0; ch < chan_count; ++ch) { if (chans[ch] < 0 || chans[ch] >= im->channels) { - i_push_errorf(0, "No channel %d in this image", chans[ch]); + dIMCTXim(im); + im_push_errorf(aIMCTX, 0, "No channel %d in this image", chans[ch]); return 0; } } @@ -346,7 +349,8 @@ static i_img_dim i_gsamp_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, } else { if (chan_count <= 0 || chan_count > im->channels) { - i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels", + dIMCTXim(im); + im_push_errorf(aIMCTX, 0, "chan_count %d out of range, must be >0, <= channels", chan_count); return 0; } @@ -383,7 +387,8 @@ static i_img_dim i_gsampf_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y /* make sure we have good channel numbers */ for (ch = 0; ch < chan_count; ++ch) { if (chans[ch] < 0 || chans[ch] >= im->channels) { - i_push_errorf(0, "No channel %d in this image", chans[ch]); + dIMCTXim(im); + im_push_errorf(aIMCTX, 0, "No channel %d in this image", chans[ch]); return 0; } } @@ -397,7 +402,8 @@ static i_img_dim i_gsampf_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y } else { if (chan_count <= 0 || chan_count > im->channels) { - i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels", + dIMCTXim(im); + im_push_errorf(aIMCTX, 0, "chan_count %d out of range, must be >0, <= channels", chan_count); return 0; } @@ -451,6 +457,7 @@ i_psamp_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, int all_in_mask = 1; for (ch = 0; ch < chan_count; ++ch) { if (chans[ch] < 0 || chans[ch] >= im->channels) { + dIMCTXim(im); i_push_errorf(0, "No channel %d in this image", chans[ch]); return -1; } @@ -482,7 +489,8 @@ i_psamp_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, } else { if (chan_count <= 0 || chan_count > im->channels) { - i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels", + dIMCTXim(im); + im_push_errorf(aIMCTX, 0, "chan_count %d out of range, must be >0, <= channels", chan_count); return -1; } @@ -503,6 +511,7 @@ i_psamp_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, return count; } else { + dIMCTXim(im); i_push_error(0, "Image position outside of image"); return -1; } @@ -542,7 +551,8 @@ i_psampf_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, int all_in_mask = 1; for (ch = 0; ch < chan_count; ++ch) { if (chans[ch] < 0 || chans[ch] >= im->channels) { - i_push_errorf(0, "No channel %d in this image", chans[ch]); + dIMCTXim(im); + im_push_errorf(aIMCTX, 0, "No channel %d in this image", chans[ch]); return -1; } if (!((1 << chans[ch]) & im->ch_mask)) @@ -573,7 +583,8 @@ i_psampf_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, } else { if (chan_count <= 0 || chan_count > im->channels) { - i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels", + dIMCTXim(im); + im_push_errorf(aIMCTX, 0, "chan_count %d out of range, must be >0, <= channels", chan_count); return -1; } @@ -594,6 +605,7 @@ i_psampf_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, return count; } else { + dIMCTXim(im); i_push_error(0, "Image position outside of image"); return -1; } @@ -616,8 +628,9 @@ i_img_to_drgb(i_img *im) { i_img *targ; i_fcolor *line; i_img_dim y; + dIMCTXim(im); - targ = i_img_double_new(im->xsize, im->ysize, im->channels); + targ = im_img_double_new(aIMCTX, im->xsize, im->ysize, im->channels); if (!targ) return NULL; line = mymalloc(sizeof(i_fcolor) * im->xsize); diff --git a/immacros.h b/immacros.h index 269c3fc4..ad079c35 100644 --- a/immacros.h +++ b/immacros.h @@ -78,9 +78,12 @@ returns -1 and pushes an error. #ifdef IMAGER_NO_CONTEXT #define dIMCTX im_context_t my_im_ctx = im_get_context() #define dIMCTXa(a) im_context_t my_im_ctx = im_get_context() +#define dIMCTXim(im) im_context_t my_im_ctx = (im)->context #define aIMCTX my_im_ctx #else #define aIMCTX im_get_context() #endif +#define pIMCTX im_context_t my_im_ctx + #endif diff --git a/lib/Imager/APIRef.pod b/lib/Imager/APIRef.pod index 9827ff73..cb784c28 100644 --- a/lib/Imager/APIRef.pod +++ b/lib/Imager/APIRef.pod @@ -265,6 +265,14 @@ i_f_psamp - implements psamp() for this image. i_f_psampf - implements psamp() for this image. +=item * + +C - image specific data internal to Imager. + +=item * + +C - the Imager API context this image belongs to. + =back diff --git a/log.c b/log.c index 1306e189..5f8b92a6 100644 --- a/log.c +++ b/log.c @@ -1,3 +1,4 @@ +#include "imageri.h" #include "imconfig.h" #include "log.h" #include @@ -9,41 +10,44 @@ #define DTBUFF 50 #define DATABUFF DTBUFF+3+10+1+5+1+1 +#if 0 static int log_level = 0; static FILE *lg_file = NULL; -static char *date_format = "%Y/%m/%d %H:%M:%S"; static char date_buffer[DTBUFF]; static char data_buffer[DATABUFF]; +#endif +#define LOG_DATE_FORMAT "%Y/%m/%d %H:%M:%S" /* * Logging is active */ int -i_init_log(const char* name,int level) { +im_init_log(pIMCTX, const char* name,int level) { i_clear_error(); - log_level = level; + aIMCTX->log_level = level; if (level < 0) { - lg_file = NULL; + aIMCTX->lg_file = NULL; } else { if (name == NULL) { - lg_file = stderr; + aIMCTX->lg_file = stderr; } else { - if (NULL == (lg_file = fopen(name, "w+")) ) { + if (NULL == (aIMCTX->lg_file = fopen(name, "w+")) ) { i_push_errorf(errno, "Cannot open file '%s': (%d)", name, errno); return 0; } } } - if (lg_file) { - setvbuf(lg_file, NULL, _IONBF, BUFSIZ); + if (aIMCTX->lg_file) { + setvbuf(aIMCTX->lg_file, NULL, _IONBF, BUFSIZ); mm_log((0,"Imager - log started (level = %d)\n", level)); } - return lg_file != NULL; + return aIMCTX->lg_file != NULL; } +#if 0 void i_fatal(int exitcode,const char *fmt, ... ) { va_list ap; @@ -62,6 +66,7 @@ i_fatal(int exitcode,const char *fmt, ... ) { exit(exitcode); } +#endif /* =item i_loog(level, format, ...) @@ -72,18 +77,47 @@ This is an internal function called by the mm_log() macro. =cut */ +static void +im_vloog(pIMCTX, int level, const char *fmt, va_list ap) { + time_t timi; + struct tm *str_tm; + char date_buffer[DTBUFF]; + + if (!aIMCTX->lg_file || level > aIMCTX->log_level) + return; + + timi = time(NULL); + str_tm = localtime(&timi); + strftime(date_buffer, DTBUFF, LOG_DATE_FORMAT, str_tm); + fprintf(aIMCTX->lg_file, "[%s] %10s:%-5d %3d: ", date_buffer, + aIMCTX->filename, aIMCTX->line, level); + vfprintf(aIMCTX->lg_file, fmt, ap); + fflush(aIMCTX->lg_file); +} + void i_loog(int level,const char *fmt, ... ) { + pIMCTX = im_get_context(); va_list ap; - if (level > log_level) return; - if (lg_file != NULL) { - fputs(data_buffer, lg_file); - fprintf(lg_file, "%3d: ",level); - va_start(ap,fmt); - vfprintf(lg_file, fmt, ap); - fflush(lg_file); - va_end(ap); - } + + if (!aIMCTX->lg_file || level > aIMCTX->log_level) + return; + + va_start(ap,fmt); + im_vloog(aIMCTX, level, fmt, ap); + va_end(ap); +} + +void +im_loog(pIMCTX, int level,const char *fmt, ... ) { + va_list ap; + + if (!aIMCTX->lg_file || level > aIMCTX->log_level) + return; + + va_start(ap,fmt); + im_vloog(aIMCTX, level, fmt, ap); + va_end(ap); } /* @@ -96,22 +130,19 @@ This is an internal function called by the mm_log() macro. */ void -i_lhead(const char *file, int line) { - time_t timi; - struct tm *str_tm; - - if (lg_file != NULL) { - timi = time(NULL); - str_tm = localtime(&timi); - strftime(date_buffer, DTBUFF, date_format, str_tm); -#ifdef IMAGER_SNPRINTF - snprintf(data_buffer, sizeof(data_buffer), "[%s] %10s:%-5d ", date_buffer, file, line); -#else - sprintf(data_buffer, "[%s] %10s:%-5d ", date_buffer, file, line); -#endif +im_lhead(pIMCTX, const char *file, int line) { + if (aIMCTX->lg_file != NULL) { + aIMCTX->filename = file; + aIMCTX->line = line; } } +void i_lhead(const char *file, int line) { + pIMCTX = im_get_context(); + + im_lhead(aIMCTX, file, line); +} + #else /* diff --git a/log.h b/log.h index 16b58310..0be9b13b 100644 --- a/log.h +++ b/log.h @@ -11,10 +11,13 @@ global: creates a global variable FILE* lg_file */ -int i_init_log( const char *name, int onoff ); +int im_init_log(pIMCTX, const char *name, int onoff ); +#define i_init_log(name, onoff) im_init_log(aIMCTX, name, onoff) void i_fatal ( int exitcode,const char *fmt, ... ); +void im_lhead ( pIMCTX, const char *file, int line ); void i_lhead ( const char *file, int line ); void i_loog(int level,const char *msg, ... ) I_FORMAT_ATTR(2,3); +void im_loog(pIMCTX, int level,const char *msg, ... ) I_FORMAT_ATTR(3,4); /* =item mm_log((level, format, ...)) @@ -31,8 +34,10 @@ log file if logging is enabled. #ifdef IMAGER_LOG #define mm_log(x) { i_lhead(__FILE__,__LINE__); i_loog x; } +#define im_log(x) { im_lhead(aIMCTX, __FILE__,__LINE__); im_loog x; } #else #define mm_log(x) +#define im_log(x) #endif diff --git a/palimg.c b/palimg.c index 72b43fad..79a05b47 100644 --- a/palimg.c +++ b/palimg.c @@ -18,6 +18,8 @@ Basic 8-bit/sample paletted image =cut */ +#define IMAGER_NO_CONTEXT + #include "imager.h" #include "imageri.h" @@ -98,7 +100,7 @@ Returns a new image or NULL on failure. =cut */ i_img * -i_img_pal_new(i_img_dim x, i_img_dim y, int channels, int maxpal) { +im_img_pal_new(pIMCTX, i_img_dim x, i_img_dim y, int channels, int maxpal) { i_img *im; i_img_pal_ext *palext; size_t bytes, line_bytes; @@ -185,8 +187,10 @@ The conversion cannot be done for virtual images. =cut */ -int i_img_to_rgb_inplace(i_img *im) { +int +i_img_to_rgb_inplace(i_img *im) { i_img temp; + dIMCTXim(im); if (im->virtual) return 0; @@ -215,6 +219,7 @@ Converts an RGB image to a paletted image i_img *i_img_to_pal(i_img *src, i_quantize *quant) { i_palidx *result; i_img *im; + dIMCTXim(src); i_clear_error(); @@ -244,7 +249,9 @@ i_img *i_img_to_pal(i_img *src, i_quantize *quant) { =cut */ -i_img *i_img_to_rgb(i_img *src) { +i_img * +i_img_to_rgb(i_img *src) { + dIMCTXim(src); i_img *im = i_img_empty_ch(NULL, src->xsize, src->ysize, src->channels); i_img_rgb_convert(im, src); @@ -682,6 +689,7 @@ i_psamp_p(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, return count; } else { + dIMCTXim(im); i_push_error(0, "Image position outside of image"); return -1; } @@ -753,6 +761,7 @@ i_psampf_p(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, return count; } else { + dIMCTXim(im); i_push_error(0, "Image position outside of image"); return -1; } diff --git a/plug.h b/plug.h index e3583fca..017cf233 100644 --- a/plug.h +++ b/plug.h @@ -1,4 +1,5 @@ -#include "imager.h" +#include "imdatatypes.h" +#include "immacros.h" /* structures for passing data between Imager-plugin and the Imager-module */ @@ -14,9 +15,9 @@ #define i_color_set(cl,r,g,b,a) (symbol_table->i_color_set(cl,r,g,b,a)) #define i_color_info(cl) (symbol_table->i_color_info(cl)) -#define i_img_new() (symbol_table->i_img_new()) -#define i_img_empty(im,x,y) ((symbol_table->i_img_empty(im,x,y)) -#define i_img_empty_ch(im,x,y,ch) ((symbol_table->i_img_empty_ch(im,x,y,ch)) +#define im_get_context() (symbol_table->im_get_context_f()) +#define i_img_empty(im,x,y) ((symbol_table->im_img_empty_f(im,x,y)) +#define i_img_empty_ch(im,x,y,ch) ((symbol_table->i_img_empty_ch_f(im_get_context(), im,x,y,ch)) #define i_img_exorcise(im) (symbol_table->i_img_exorcise(im)) #define i_img_info(im,info) (symbol_table->i_img_info(im,info)) -- 2.39.5