add new comparison method rgb_difference that resembles arithmetical difference per...
[imager.git] / palimg.c
index 72b43fa..0c37b58 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"
 
@@ -84,9 +86,10 @@ static i_img IIM_base_8bit_pal =
 };
 
 /*
-=item i_img_pal_new(C<x>, C<y>, C<channels>, C<maxpal>)
-
+=item im_img_pal_new(ctx, C<x>, C<y>, C<channels>, C<maxpal>)
+X<im_img_pal_new API>X<i_img_pal_new API>
 =category Image creation/destruction
+=synopsis i_img *img = im_img_pal_new(aIMCTX, width, height, channels, max_palette_size)
 =synopsis i_img *img = i_img_pal_new(width, height, channels, max_palette_size)
 
 Creates a new paletted image of the supplied dimensions.
@@ -95,10 +98,12 @@ C<maxpal> is the maximum palette size and should normally be 256.
 
 Returns a new image or NULL on failure.
 
+Also callable as C<i_img_pal_new(width, height, channels, max_palette_size)>.
+
 =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;
@@ -113,7 +118,7 @@ i_img_pal_new(i_img_dim x, i_img_dim y, int channels, int maxpal) {
     return NULL;
   }
   if (channels < 1 || channels > MAXCHANNELS) {
-    i_push_errorf(0, "Channels must be positive and <= %d", MAXCHANNELS);
+    im_push_errorf(aIMCTX, 0, "Channels must be positive and <= %d", MAXCHANNELS);
     return NULL;
   }
   bytes = sizeof(i_palidx) * x * y;
@@ -185,8 +190,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;
@@ -198,10 +205,12 @@ int i_img_to_rgb_inplace(i_img *im) {
   i_img_rgb_convert(&temp, im);
 
   /* nasty hack */
-  (im->i_f_destroy)(im);
-  myfree(im->idata);
+  i_img_exorcise(im);
   *im = temp;
 
+  /* i_img_empty_ch() calls i_img_init() which takes a ref */
+  im_context_refdec(aIMCTX, "img_destroy");
+
   return 1;
 }
 
@@ -215,6 +224,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 +254,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);
 
@@ -306,7 +318,8 @@ i_ppix_p(i_img *im, i_img_dim x, i_img_dim y, const i_color *val) {
     return 0;
   }
   else {
-    mm_log((1, "i_ppix: color(%d,%d,%d) not found, converting to rgb\n",
+    dIMCTXim(im);
+    im_log((aIMCTX, 1, "i_ppix: color(%d,%d,%d) not found, converting to rgb\n",
            val->channel[0], val->channel[1], val->channel[2]));
     if (i_img_to_rgb_inplace(im)) {
       return i_ppix(im, x, y, val);
@@ -423,7 +436,8 @@ static i_img_dim i_gsamp_p(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_s
     if (chans) {
       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]);
         }
       }
 
@@ -439,7 +453,8 @@ static i_img_dim i_gsamp_p(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_s
     }
     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;
       }
@@ -645,7 +660,8 @@ i_psamp_p(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 -1;
         }
       }
@@ -662,7 +678,8 @@ i_psamp_p(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;
       }
@@ -682,6 +699,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;
   }
@@ -716,7 +734,8 @@ i_psampf_p(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 -1;
         }
       }
@@ -733,7 +752,8 @@ i_psampf_p(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;
       }
@@ -753,6 +773,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;
   }