]> git.imager.perl.org - imager.git/blobdiff - Imager.xs
- use scanline oriented operations to flip images instead of pixel
[imager.git] / Imager.xs
index 46f7b3e37f72ed98544d292e48eaee4f0e431a58..f6733ed68dbbd8541def9bf5d7dfca64de901ec8 100644 (file)
--- a/Imager.xs
+++ b/Imager.xs
@@ -719,14 +719,12 @@ static void copy_colors_back(HV *hv, i_quantize *quant) {
 
   sv = hv_fetch(hv, "colors", 6, 0);
   if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
-    SV *ref;
-    av = newAV();
-    ref = newRV_inc((SV*) av);
-    sv = hv_store(hv, "colors", 6, ref, 0);
-  }
-  else {
-    av = (AV *)SvRV(*sv);
+    /* nothing to do */
+    return;
   }
+
+  av = (AV *)SvRV(*sv);
+  av_clear(av);
   av_extend(av, quant->mc_count+1);
   for (i = 0; i < quant->mc_count; ++i) {
     i_color *in = quant->mc_colors+i;
@@ -734,9 +732,7 @@ static void copy_colors_back(HV *hv, i_quantize *quant) {
     work = sv_newmortal();
     sv_setref_pv(work, "Imager::Color", (void *)c);
     SvREFCNT_inc(work);
-    if (!av_store(av, i, work)) {
-      SvREFCNT_dec(work);
-    }
+    av_push(av, work);
   }
 }
 
@@ -1287,9 +1283,13 @@ i_sametype_chans(im, x, y, channels)
                int channels
 
 void
-i_init_log(name,level)
-             char*    name
+i_init_log(name_sv,level)
+             SV*    name_sv
               int     level
+       PREINIT:
+         const char *name = SvOK(name_sv) ? SvPV_nolen(name_sv) : NULL;
+       CODE:
+         i_init_log(name, level);
 
 void
 i_log_entry(string,level)
@@ -1343,6 +1343,25 @@ i_img_getdata(im)
                     sv_2mortal(newSVpv((char *)im->idata, im->bytes)) 
                     : &PL_sv_undef);
 
+void
+i_img_is_monochrome(im)
+       Imager::ImgRaw im
+      PREINIT:
+       int zero_is_white;
+       int result;
+      PPCODE:
+       result = i_img_is_monochrome(im, &zero_is_white);
+       if (result) {
+         if (GIMME_V == G_ARRAY) {
+           EXTEND(SP, 2);
+           PUSHs(&PL_sv_yes);
+           PUSHs(sv_2mortal(newSViv(zero_is_white)));
+         }
+         else {
+           EXTEND(SP, 1);
+           PUSHs(&PL_sv_yes);
+         }
+       }
 
 void
 i_line(im,x1,y1,x2,y2,val,endp)
@@ -1617,6 +1636,34 @@ i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
               int     src_maxx
               int     src_maxy
 
+undef_int
+i_compose(out, src, out_left, out_top, src_left, src_top, width, height, combine = ic_normal, opacity = 0.0)
+    Imager::ImgRaw out
+    Imager::ImgRaw src
+       int out_left
+       int out_top
+       int src_left
+       int src_top
+       int width
+       int height
+       int combine
+       double opacity
+
+undef_int
+i_compose_mask(out, src, mask, out_left, out_top, src_left, src_top, mask_left, mask_top, width, height, combine = ic_normal, opacity = 0.0)
+    Imager::ImgRaw out
+    Imager::ImgRaw src
+    Imager::ImgRaw mask
+       int out_left
+       int out_top
+       int src_left
+       int src_top
+       int mask_left
+       int mask_top
+       int width
+       int height
+       int combine
+       double opacity
 
 undef_int
 i_flipxy(im, direction)
@@ -1709,45 +1756,40 @@ i_unsharp_mask(im,stdev,scale)
             float     stdev
              double    scale
 
-void
-i_conv(im,pcoef)
-    Imager::ImgRaw     im
-            PREINIT:
-            float*    coeff;
-            int     len;
-            AV* av;
-            SV* sv1;
-            int i;
-            PPCODE:
-            if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
-            if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
-            av=(AV*)SvRV(ST(1));
-            len=av_len(av)+1;
-            coeff=mymalloc( len*sizeof(float) );
-            for(i=0;i<len;i++) {
-              sv1=(*(av_fetch(av,i,0)));
-              coeff[i]=(float)SvNV(sv1);
-            }
-            i_conv(im,coeff,len);
-            myfree(coeff);
+int
+i_conv(im,coef)
+       Imager::ImgRaw     im
+       AV *coef
+     PREINIT:
+       double*    c_coef;
+       int     len;
+       SV* sv1;
+       int i;
+    CODE:
+       len = av_len(coef) + 1;
+       c_coef=mymalloc( len * sizeof(double) );
+       for(i = 0; i  < len; i++) {
+         sv1 = (*(av_fetch(coef, i, 0)));
+         c_coef[i] = (double)SvNV(sv1);
+       }
+       RETVAL = i_conv(im, c_coef, len);
+       myfree(c_coef);
+    OUTPUT:
+       RETVAL
 
-undef_int
-i_convert(im, src, coeff)
-    Imager::ImgRaw     im
+Imager::ImgRaw
+i_convert(src, avmain)
     Imager::ImgRaw     src
+    AV *avmain
        PREINIT:
          float *coeff;
          int outchan;
          int inchan;
-         AV *avmain;
           SV **temp;
           AV *avsub;
          int len;
          int i, j;
         CODE:
-         if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
-           croak("i_convert: parameter 3 must be an arrayref\n");
-          avmain = (AV*)SvRV(ST(2));
          outchan = av_len(avmain)+1;
           /* find the biggest */
           inchan = 0;
@@ -1774,7 +1816,7 @@ i_convert(im, src, coeff)
            while (i < inchan)
              coeff[i++ + j*inchan] = 0;
          }
-         RETVAL = i_convert(im, src, coeff, outchan, inchan);
+         RETVAL = i_convert(src, coeff, outchan, inchan);
           myfree(coeff);
        OUTPUT:
          RETVAL
@@ -1826,7 +1868,10 @@ i_img_diff(im1,im2)
     Imager::ImgRaw     im1
     Imager::ImgRaw     im2
 
-
+double
+i_img_diffd(im1,im2)
+    Imager::ImgRaw     im1
+    Imager::ImgRaw     im2
 
 undef_int        
 i_init_fonts(t1log=0)
@@ -2372,6 +2417,12 @@ i_writetiff_multi_wiol_faxable(ig, fine, ...)
       OUTPUT:
         RETVAL
 
+const char *
+i_tiff_libversion()
+
+bool
+i_tiff_has_compression(name)
+       const char *name
 
 #endif /* HAVE_LIBTIFF */
 
@@ -2462,6 +2513,8 @@ i_writegif_gen(fd, ...)
        hv = (HV *)SvRV(ST(1));
        memset(&quant, 0, sizeof(quant));
        quant.mc_size = 256;
+       quant.transp = tr_threshold;
+       quant.tr_threshold = 127;
        handle_quant_opts(&quant, hv);
        img_count = items - 2;
        RETVAL = 1;
@@ -2517,6 +2570,8 @@ i_writegif_callback(cb, maxbuffer,...)
        hv = (HV *)SvRV(ST(2));
        memset(&quant, 0, sizeof(quant));
        quant.mc_size = 256;
+       quant.transp = tr_threshold;
+       quant.tr_threshold = 127;
        handle_quant_opts(&quant, hv);
        img_count = items - 3;
        RETVAL = 1;
@@ -2567,6 +2622,8 @@ i_writegif_wiol(ig, opts,...)
        hv = (HV *)SvRV(ST(1));
        memset(&quant, 0, sizeof(quant));
        quant.mc_size = 256;
+       quant.transp = tr_threshold;
+       quant.tr_threshold = 127;
        handle_quant_opts(&quant, hv);
        img_count = items - 2;
        RETVAL = 1;
@@ -2941,27 +2998,6 @@ i_readtga_wiol(ig, length)
                int     length
 
 
-undef_int
-i_writergb_wiol(im,ig, wierdpack, compress, idstring)
-    Imager::ImgRaw     im
-        Imager::IO     ig
-               int     wierdpack
-               int     compress
-              char*    idstring
-            PREINIT:
-                int idlen;
-              CODE:
-                idlen  = SvCUR(ST(4));
-                RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
-                OUTPUT:
-                RETVAL
-
-
-Imager::ImgRaw
-i_readrgb_wiol(ig, length)
-        Imager::IO     ig
-               int     length
-
 
 
 Imager::ImgRaw
@@ -2991,6 +3027,23 @@ i_count_colors(im,maxc)
     Imager::ImgRaw     im
                int     maxc
 
+void
+i_get_anonymous_color_histo(im, maxc = 0x40000000)
+   Imager::ImgRaw  im
+   int maxc
+    PREINIT:
+        int i;
+        unsigned int * col_usage = NULL;
+        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])));
+        }
+        myfree(col_usage);
+        XSRETURN(col_cnt);
+
 
 Imager::ImgRaw
 i_transform(im,opx,opy,parm)
@@ -3329,6 +3382,11 @@ i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_pa
       OUTPUT:
         RETVAL
 
+Imager::FillHandle
+i_new_fill_opacity(other_fill, alpha_mult)
+    Imager::FillHandle other_fill
+    double alpha_mult
+
 void
 i_errors()
       PREINIT:
@@ -3443,17 +3501,18 @@ DSO_funclist(dso_handle_v)
             PREINIT:
               int i;
               DSO_handle *dso_handle;
+              func_ptr *functions;
             PPCODE:
               dso_handle=(DSO_handle*)dso_handle_v;
+              functions = DSO_funclist(dso_handle);
               i=0;
-              while( dso_handle->function_list[i].name != NULL) {
+              while( functions[i].name != NULL) {
                 EXTEND(SP,1);
-                PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
+                PUSHs(sv_2mortal(newSVpv(functions[i].name,0)));
                 EXTEND(SP,1);
-                PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
+                PUSHs(sv_2mortal(newSVpv(functions[i++].pcode,0)));
               }
 
-
 void
 DSO_call(handle,func_index,hv)
               void*  handle
@@ -3466,8 +3525,6 @@ DSO_call(handle,func_index,hv)
               if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
               DSO_call( (DSO_handle *)handle,func_index,hv);
 
-
-
 SV *
 i_get_pixel(im, x, y)
        Imager::ImgRaw im
@@ -3774,6 +3831,108 @@ i_gsamp(im, l, r, y, ...)
           }
         }
 
+undef_neg_int
+i_gsamp_bits(im, l, r, y, bits, target, offset, ...)
+        Imager::ImgRaw im
+        int l
+        int r
+        int y
+       int bits
+       AV *target
+       int offset
+      PREINIT:
+        int *chans;
+        int chan_count;
+        unsigned *data;
+        int count, i;
+      CODE:
+       i_clear_error();
+        if (items < 8)
+          croak("No channel numbers supplied to g_samp()");
+        if (l < r) {
+          chan_count = items - 7;
+          chans = mymalloc(sizeof(int) * chan_count);
+          for (i = 0; i < chan_count; ++i)
+            chans[i] = SvIV(ST(i+7));
+          data = mymalloc(sizeof(unsigned) * (r-l) * chan_count);
+          count = i_gsamp_bits(im, l, r, y, data, chans, chan_count, bits);
+         myfree(chans);
+         for (i = 0; i < count; ++i) {
+           av_store(target, i+offset, newSVuv(data[i]));
+         }
+         myfree(data);
+         RETVAL = count;
+        }
+        else {
+         RETVAL = 0;
+        }
+      OUTPUT:
+       RETVAL
+
+undef_neg_int
+i_psamp_bits(im, l, y, bits, channels_sv, data_av, data_offset = 0, pixel_count = -1)
+        Imager::ImgRaw im
+        int l
+        int y
+       int bits
+       SV *channels_sv
+       AV *data_av
+        int data_offset
+        int pixel_count
+      PREINIT:
+       int chan_count;
+       int *channels;
+       int data_count;
+       int data_used;
+       unsigned *data;
+       int i;
+      CODE:
+       i_clear_error();
+       if (SvOK(channels_sv)) {
+         AV *channels_av;
+         if (!SvROK(channels_sv) || SvTYPE(SvRV(channels_sv)) != SVt_PVAV) {
+           croak("channels is not an array ref");
+         }
+         channels_av = (AV *)SvRV(channels_sv);
+         chan_count = av_len(channels_av) + 1;
+         if (chan_count < 1) {
+           croak("i_psamp_bits: no channels provided");
+         }
+         channels = mymalloc(sizeof(int) * chan_count);
+         for (i = 0; i < chan_count; ++i)
+           channels[i] = SvIV(*av_fetch(channels_av, i, 0));
+        }
+       else {
+         chan_count = im->channels;
+         channels = NULL;
+       }
+
+       data_count = av_len(data_av) + 1;
+       if (data_offset < 0) {
+         croak("data_offset must by non-negative");
+       }
+       if (data_offset > data_count) {
+         croak("data_offset greater than number of samples supplied");
+        }
+       if (pixel_count == -1 || 
+           data_offset + pixel_count * chan_count > data_count) {
+         pixel_count = (data_count - data_offset) / chan_count;
+       }
+
+       data_used = pixel_count * chan_count;
+       data = mymalloc(sizeof(unsigned) * data_count);
+       for (i = 0; i < data_used; ++i)
+         data[i] = SvUV(*av_fetch(data_av, data_offset + i, 0));
+
+       RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels, 
+                             chan_count, bits);
+
+       if (data)
+         myfree(data);
+       if (channels)
+         myfree(channels);
+      OUTPUT:
+       RETVAL
 
 Imager::ImgRaw
 i_img_masked_new(targ, mask, x, y, w, h)
@@ -3995,8 +4154,10 @@ i_glinf(im, l, r, y)
       PREINIT:
         i_fcolor *vals;
         int count, i;
-        i_fcolor zero = { 0 };
+        i_fcolor zero;
       PPCODE:
+       for (i = 0; i < MAXCHANNELS; ++i)
+         zero.channel[i] = 0;
         if (l < r) {
           vals = mymalloc((r-l) * sizeof(i_fcolor));
           for (i = 0; i < r-l; ++i)
@@ -4277,6 +4438,10 @@ undef_int
 i_wf_addfont(font)
         char *font
 
+undef_int
+i_wf_delfont(font)
+        char *font
+
 #endif
 
 #ifdef HAVE_FT2