]> git.imager.perl.org - imager.git/blobdiff - Imager.xs
add some more extensions, add add_type_extensions() class method
[imager.git] / Imager.xs
index 5fe6b4dceab387b5075172a740f7a39c1620fdcd..a69fec9eb3c6a1bfc72aeec4cf1b577c13d011a6 100644 (file)
--- a/Imager.xs
+++ b/Imager.xs
@@ -52,22 +52,11 @@ typedef struct {
 
 START_MY_CXT
 
-im_context_t fallback_context;
-
 static void
 start_context(pTHX) {
   dMY_CXT;
   MY_CXT.ctx = im_context_new();
   sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", MY_CXT.ctx);
-
-  /* Ideally we'd free this reference, but the error message memory
-     was never released on exit, so the associated memory here is reasonable
-     to keep.
-     With logging enabled we always need at least one context, since
-     objects may be released fairly late and attempt to get the log file.
-  */
-  im_context_refinc(MY_CXT.ctx, "start_context");
-  fallback_context = MY_CXT.ctx;
 }
 
 static im_context_t
@@ -75,7 +64,7 @@ perl_get_context(void) {
   dTHX;
   dMY_CXT;
   
-  return MY_CXT.ctx ? MY_CXT.ctx : fallback_context;
+  return MY_CXT.ctx;
 }
 
 #else
@@ -85,7 +74,9 @@ static im_context_t perl_context;
 static void
 start_context(pTHX) {
   perl_context = im_context_new();
-  im_context_refinc(perl_context, "start_context");
+
+  /* just so it gets destroyed */
+  sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", perl_context);
 }
 
 static im_context_t
@@ -124,15 +115,18 @@ Allocate memory that will be discarded when mortals are discarded.
 
 static void *
 malloc_temp(pTHX_ size_t size) {
-  SV *sv = sv_2mortal(newSV(size));
+  void *result;
+  Newx(result, size, char);
+  SAVEFREEPV(result);
 
-  return SvPVX(sv);
+  return result;
 }
 
 static void *
 calloc_temp(pTHX_ size_t size) {
-  void *result = malloc_temp(aTHX_ size);
-  memset(result, 0, size);
+  void *result;
+  Newxz(result, size, char);
+  SAVEFREEPV(result);
 
   return result;
 }
@@ -1720,6 +1714,22 @@ IV
 i_img_get_height(im)
     Imager::ImgRaw     im
 
+int
+i_img_color_model(im)
+    Imager::ImgRaw     im
+
+int
+i_img_color_channels(im)
+    Imager::ImgRaw     im
+
+int
+i_img_alpha_channel(im)
+    Imager::ImgRaw     im
+  CODE:
+    if (!i_img_alpha_channel(im, &RETVAL))
+      XSRETURN(0);
+  OUTPUT:
+    RETVAL
 
 void
 i_img_is_monochrome(im)
@@ -2658,12 +2668,17 @@ i_get_anonymous_color_histo(im, maxc = 0x40000000)
         int col_cnt;
     PPCODE:
        col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
-        EXTEND(SP, col_cnt);
-        for (i = 0; i < col_cnt; i++)  {
-            PUSHs(sv_2mortal(newSViv( col_usage[i])));
+        if (col_cnt > 0) {
+            EXTEND(SP, col_cnt);
+            for (i = 0; i < col_cnt; i++)  {
+                PUSHs(sv_2mortal(newSViv( col_usage[i])));
+            }
+            myfree(col_usage);
+            XSRETURN(col_cnt);
+        }
+        else {
+            XSRETURN_EMPTY;
         }
-        myfree(col_usage);
-        XSRETURN(col_cnt);
 
 
 void
@@ -2979,7 +2994,7 @@ i_errors()
          if (!av_store(av, 1, sv)) {
            SvREFCNT_dec(sv);
          }
-         PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
+         XPUSHs(sv_2mortal(newRV_noinc((SV*)av)));
          ++i;
        }
 
@@ -3023,9 +3038,9 @@ i_nearest_color(im, ...)
        num = num <= av_len(ac) ? num : av_len(ac);
        num++; 
        if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
-       xo = mymalloc( sizeof(i_img_dim) * num );
-       yo = mymalloc( sizeof(i_img_dim) * num );
-       ival = mymalloc( sizeof(i_color) * num );
+       xo = malloc_temp(aTHX_ sizeof(i_img_dim) * num );
+       yo = malloc_temp(aTHX_ sizeof(i_img_dim) * num );
+       ival = malloc_temp(aTHX_ sizeof(i_color) * num );
        for(i = 0; i<num; i++) {
          xo[i]   = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
          yo[i]   = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
@@ -3100,6 +3115,7 @@ i_get_pixel(im, x, y)
        i_img_dim y;
       CODE:
        RETVAL = (i_color *)mymalloc(sizeof(i_color));
+       memset(RETVAL, 0, sizeof(*RETVAL));
        if (i_gpix(im, x, y, RETVAL) != 0) {
           myfree(RETVAL);
          XSRETURN_UNDEF;
@@ -3180,6 +3196,7 @@ i_img_make_palette(HV *quant_hv, ...)
          PUSHs(sv_c);
        }
        ip_cleanup_quant_opts(aTHX_ &quant);
+        myfree(imgs);
        
 
 void
@@ -3281,6 +3298,7 @@ i_addcolors(im, ...)
           }
         }
         RETVAL = i_addcolors(im, colors, items-1);
+        myfree(colors);
       OUTPUT:
         RETVAL
 
@@ -3693,6 +3711,7 @@ i_gpixf(im, x, y)
        i_img_dim y;
       CODE:
        RETVAL = (i_fcolor *)mymalloc(sizeof(i_fcolor));
+       memset(RETVAL, 0, sizeof(*RETVAL));
        if (i_gpixf(im, x, y, RETVAL) != 0) {
           myfree(RETVAL);
           XSRETURN_UNDEF;