]> git.imager.perl.org - imager.git/blobdiff - image.c
fill out files missing froom MANIFEST
[imager.git] / image.c
diff --git a/image.c b/image.c
index f1d659d859502fbd3e8371944ad7c68f301039f1..03a06f44f7633889a8cf88c186b292c8d699ad52 100644 (file)
--- a/image.c
+++ b/image.c
@@ -71,7 +71,7 @@ ICL_new_internal(unsigned char r,unsigned char g,unsigned char b,unsigned char a
 
   mm_log((1,"ICL_new_internal(r %d,g %d,b %d,a %d)\n", r, g, b, a));
 
-  if ( (cl=mymalloc(sizeof(i_color))) == NULL) m_fatal(2,"malloc() error\n");
+  if ( (cl=mymalloc(sizeof(i_color))) == NULL) i_fatal(2,"malloc() error\n");
   cl->rgba.r = r;
   cl->rgba.g = g;
   cl->rgba.b = b;
@@ -100,7 +100,7 @@ ICL_set_internal(i_color *cl,unsigned char r,unsigned char g,unsigned char b,uns
   mm_log((1,"ICL_set_internal(cl* %p,r %d,g %d,b %d,a %d)\n",cl,r,g,b,a));
   if (cl == NULL)
     if ( (cl=mymalloc(sizeof(i_color))) == NULL)
-      m_fatal(2,"malloc() error\n");
+      i_fatal(2,"malloc() error\n");
   cl->rgba.r=r;
   cl->rgba.g=g;
   cl->rgba.b=b;
@@ -173,7 +173,7 @@ i_fcolor *i_fcolor_new(double r, double g, double b, double a) {
 
   mm_log((1,"i_fcolor_new(r %g,g %g,b %g,a %g)\n", r, g, b, a));
 
-  if ( (cl=mymalloc(sizeof(i_fcolor))) == NULL) m_fatal(2,"malloc() error\n");
+  if ( (cl=mymalloc(sizeof(i_fcolor))) == NULL) i_fatal(2,"malloc() error\n");
   cl->rgba.r = r;
   cl->rgba.g = g;
   cl->rgba.b = b;
@@ -300,7 +300,7 @@ i_img_new() {
   
   mm_log((1,"i_img_struct()\n"));
   if ( (im=mymalloc(sizeof(i_img))) == NULL)
-    m_fatal(2,"malloc() error\n");
+    i_fatal(2,"malloc() error\n");
   
   *im = IIM_base_8bit_direct;
   im->xsize=0;
@@ -372,7 +372,7 @@ i_img_empty_ch(i_img *im,int x,int y,int ch) {
 
   if (im == NULL)
     if ( (im=mymalloc(sizeof(i_img))) == NULL)
-      m_fatal(2,"malloc() error\n");
+      i_fatal(2,"malloc() error\n");
 
   memcpy(im, &IIM_base_8bit_direct, sizeof(i_img));
   i_tags_new(&im->tags);
@@ -382,7 +382,7 @@ i_img_empty_ch(i_img *im,int x,int y,int ch) {
   im->ch_mask  = MAXINT;
   im->bytes=bytes;
   if ( (im->idata=mymalloc(im->bytes)) == NULL) 
-    m_fatal(2,"malloc() error\n"); 
+    i_fatal(2,"malloc() error\n"); 
   memset(im->idata,0,(size_t)im->bytes);
   
   im->ext_data = NULL;
@@ -697,104 +697,6 @@ i_copy(i_img *src) {
 }
 
 
-/*
-=item i_rubthru(im, src, tx, ty, src_minx, src_miny, src_maxx, src_maxy )
-
-=category Image
-
-Takes the sub image I<src[src_minx, src_maxx)[src_miny, src_maxy)> and
-overlays it at (I<tx>,I<ty>) on the image object.
-
-The alpha channel of each pixel in I<src> is used to control how much
-the existing colour in I<im> is replaced, if it is 255 then the colour
-is completely replaced, if it is 0 then the original colour is left 
-unmodified.
-
-=cut
-*/
-
-int
-i_rubthru(i_img *im, i_img *src, int tx, int ty, int src_minx, int src_miny,
-         int src_maxx, int src_maxy) {
-  int x, y, ttx, tty;
-  int chancount;
-  int chans[3];
-  int alphachan;
-  int ch;
-
-  mm_log((1,"i_rubthru(im %p, src %p, tx %d, ty %d, src_minx %d, "
-         "src_miny %d, src_maxx %d, src_maxy %d)\n",
-         im, src, tx, ty, src_minx, src_miny, src_maxx, src_maxy));
-  i_clear_error();
-
-  if (im->channels == 3 && src->channels == 4) {
-    chancount = 3;
-    chans[0] = 0; chans[1] = 1; chans[2] = 2;
-    alphachan = 3;
-  }
-  else if (im->channels == 3 && src->channels == 2) {
-    chancount = 3;
-    chans[0] = chans[1] = chans[2] = 0;
-    alphachan = 1;
-  }
-  else if (im->channels == 1 && src->channels == 2) {
-    chancount = 1;
-    chans[0] = 0;
-    alphachan = 1;
-  }
-  else {
-    i_push_error(0, "rubthru can only work where (dest, src) channels are (3,4), (3,2) or (1,2)");
-    return 0;
-  }
-
-  if (im->bits <= 8) {
-    /* if you change this code, please make sure the else branch is
-       changed in a similar fashion - TC */
-    int alpha;
-    i_color pv, orig, dest;
-    tty = ty;
-    for(y = src_miny; y < src_maxy; y++) {
-      ttx = tx;
-      for(x = src_minx; x < src_maxx; x++) {
-        i_gpix(src, x,   y,   &pv);
-        i_gpix(im,  ttx, tty, &orig);
-        alpha = pv.channel[alphachan];
-        for (ch = 0; ch < chancount; ++ch) {
-          dest.channel[ch] = (alpha * pv.channel[chans[ch]]
-                              + (255 - alpha) * orig.channel[ch])/255;
-        }
-        i_ppix(im, ttx, tty, &dest);
-       ttx++;
-      }
-      tty++;
-    }
-  }
-  else {
-    double alpha;
-    i_fcolor pv, orig, dest;
-
-    tty = ty;
-    for(y = src_miny; y < src_maxy; y++) {
-      ttx = tx;
-      for(x = src_minx; x < src_maxx; x++) {
-        i_gpixf(src, x,   y,   &pv);
-        i_gpixf(im,  ttx, tty, &orig);
-        alpha = pv.channel[alphachan];
-        for (ch = 0; ch < chancount; ++ch) {
-          dest.channel[ch] = alpha * pv.channel[chans[ch]]
-           + (1 - alpha) * orig.channel[ch];
-        }
-        i_ppixf(im, ttx, tty, &dest);
-        ttx++;
-      }
-      tty++;
-    }
-  }
-
-  return 1;
-}
-
-
 /*
 =item i_flipxy(im, axis)
 
@@ -2118,8 +2020,6 @@ struct magic_entry {
 
 static int
 test_magic(unsigned char *buffer, size_t length, struct magic_entry const *magic) {
-  int c;
-
   if (length < magic->magic_size)
     return 0;
   if (magic->mask) {
@@ -2154,7 +2054,7 @@ Check the beginning of the supplied file for a 'magic number'
 #define FORMAT_ENTRY(magic, type) \
   { (unsigned char *)(magic ""), sizeof(magic)-1, type }
 #define FORMAT_ENTRY2(magic, type, mask) \
-  { (unsigned char *)(magic ""), sizeof(magic)-1, type, mask }
+  { (unsigned char *)(magic ""), sizeof(magic)-1, type, (unsigned char *)(mask) }
 
 const char *
 i_test_format_probe(io_glue *data, int length) {
@@ -2190,7 +2090,7 @@ i_test_format_probe(io_glue *data, int length) {
        http://www.fileformat.info/format/pcx/
     */
     FORMAT_ENTRY("\x0A\x00\x01", "pcx"),
-    FORMAT_ENTRY("\x0A\x03\x01", "pcx"),
+    FORMAT_ENTRY("\x0A\x02\x01", "pcx"),
     FORMAT_ENTRY("\x0A\x03\x01", "pcx"),
     FORMAT_ENTRY("\x0A\x04\x01", "pcx"),
     FORMAT_ENTRY("\x0A\x05\x01", "pcx"),
@@ -2204,10 +2104,23 @@ i_test_format_probe(io_glue *data, int length) {
     /* EPS - Encapsulated Postscript */
     /* only reading 18 chars, so we don't include the F in EPSF */
     FORMAT_ENTRY("%!PS-Adobe-2.0 EPS", "eps"),
+
+    /* Utah RLE */
+    FORMAT_ENTRY("\x52\xCC", "utah"),
+
+    /* GZIP compressed, only matching deflate for now */
+    FORMAT_ENTRY("\x1F\x8B\x08", "gzip"),
+
+    /* bzip2 compressed */
+    FORMAT_ENTRY("BZh", "bzip2"),
   };
   static const struct magic_entry more_formats[] = {
-    FORMAT_ENTRY("\x00\x00\x01\x00", "ico"),
-    FORMAT_ENTRY("\x00\x00\x02\x00", "ico"), /* cursor */
+    /* these were originally both listed as ico, but cur files can
+       include hotspot information */
+    FORMAT_ENTRY("\x00\x00\x01\x00", "ico"), /* Windows icon */
+    FORMAT_ENTRY("\x00\x00\x02\x00", "cur"), /* Windows cursor */
+    FORMAT_ENTRY2("\x00\x00\x00\x00\x00\x00\x00\x07", 
+                 "xwd", "    xxxx"), /* X Windows Dump */
   };
 
   unsigned int i;
@@ -2240,8 +2153,77 @@ i_test_format_probe(io_glue *data, int length) {
   return NULL;
 }
 
+/*
+=item i_img_is_monochrome(img, &zero_is_white)
+
+Tests an image to check it meets our monochrome tests.
+
+The idea is that a file writer can use this to test where it should
+write the image in whatever bi-level format it uses, eg. pbm for pnm.
+
+For performance of encoders we require monochrome images:
+
+=over
+
+=item *
 
+be paletted
 
+=item *
+
+have a palette of two colors, containing only (0,0,0) and
+(255,255,255) in either order.
+
+=back
+
+zero_is_white is set to non-zero iff the first palette entry is white.
+
+=cut
+*/
+
+int
+i_img_is_monochrome(i_img *im, int *zero_is_white) {
+  if (im->type == i_palette_type
+      && i_colorcount(im) == 2) {
+    i_color colors[2];
+    i_getcolors(im, 0, colors, 2);
+    if (im->channels == 3) {
+      if (colors[0].rgb.r == 255 && 
+          colors[0].rgb.g == 255 &&
+          colors[0].rgb.b == 255 &&
+          colors[1].rgb.r == 0 &&
+          colors[1].rgb.g == 0 &&
+          colors[1].rgb.b == 0) {
+        *zero_is_white = 0;
+        return 1;
+      }
+      else if (colors[0].rgb.r == 0 && 
+               colors[0].rgb.g == 0 &&
+               colors[0].rgb.b == 0 &&
+               colors[1].rgb.r == 255 &&
+               colors[1].rgb.g == 255 &&
+               colors[1].rgb.b == 255) {
+        *zero_is_white = 1;
+        return 1;
+      }
+    }
+    else if (im->channels == 1) {
+      if (colors[0].channel[0] == 255 &&
+          colors[1].channel[1] == 0) {
+        *zero_is_white = 0;
+        return 1;
+      }
+      else if (colors[0].channel[0] == 0 &&
+               colors[0].channel[0] == 255) {
+        *zero_is_white = 1;
+        return 1;         
+      }
+    }
+  }
+
+  *zero_is_white = 0;
+  return 0;
+}
 
 /*
 =back