WIP, more context changes
authorTony Cook <tony@develop-help.com>
Thu, 24 May 2012 07:23:21 +0000 (17:23 +1000)
committerTony Cook <tony@develop-help.com>
Sat, 24 Nov 2012 03:59:14 +0000 (14:59 +1100)
18 files changed:
dynaload.c
error.c
ext.h
image.c
imager.h
imageri.h
imdatatypes.h
imerror.h
imexttypes.h
img16.c
img8.c
imgdouble.c
immacros.h
lib/Imager/APIRef.pod
log.c
log.h
palimg.c
plug.h

index 8838038..8a12de2 100644 (file)
@@ -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 c234147..a5f97b8 100644 (file)
--- 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<code>, char const *C<fmt>, va_list C<ap>)
 
diff --git a/ext.h b/ext.h
index dd1cfbd..190ff76 100644 (file)
--- 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 a8045f2..6a4fc8d 100644 (file)
--- 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;
index b2849a0..8246e4f 100644 (file)
--- 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 <unistd.h>
 #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
index 0e9815e..34817ed 100644 (file)
--- 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;
 
index 1115883..b56b43f 100644 (file)
@@ -285,6 +285,14 @@ i_f_psamp - implements psamp() for this image.
 
 i_f_psampf - implements psamp() for this image.
 
+=item *
+
+C<im_data> - image specific data internal to Imager.
+
+=item *
+
+C<context> - 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
index da56df1..b51600e 100644 (file)
--- 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
index 9fd1a0c..e6a354a 100644 (file)
  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 970a173..cfd4da6 100644 (file)
--- 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 d905fa2..0377549 100644 (file)
--- 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<ch> 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;
   }
index fe1ad62..80a60a4 100644 (file)
@@ -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);
index 269c3fc..ad079c3 100644 (file)
@@ -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
index 9827ff7..cb784c2 100644 (file)
@@ -265,6 +265,14 @@ i_f_psamp - implements psamp() for this image.
 
 i_f_psampf - implements psamp() for this image.
 
+=item *
+
+C<im_data> - image specific data internal to Imager.
+
+=item *
+
+C<context> - the Imager API context this image belongs to.
+
 =back
 
 
diff --git a/log.c b/log.c
index 1306e18..5f8b92a 100644 (file)
--- a/log.c
+++ b/log.c
@@ -1,3 +1,4 @@
+#include "imageri.h"
 #include "imconfig.h"
 #include "log.h"
 #include <stdlib.h>
 #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 16b5831..0be9b13 100644 (file)
--- a/log.h
+++ b/log.h
    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
 
 
index 72b43fa..79a05b4 100644 (file)
--- 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 e3583fc..017cf23 100644 (file)
--- 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))