changeset 168:d756a7b6d533

Add ImageMagick++ support to imread
author tpikonen
date Mon, 31 Oct 2005 21:18:34 +0000
parents 8072e38f637b
children 7127c701b09b
files __imagemagick__.cc
diffstat 1 files changed, 310 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/__imagemagick__.cc
@@ -0,0 +1,310 @@
+#include <octave/oct.h>
+#include <Magick++.h>
+#include <iostream>
+using namespace std;
+using namespace Magick;
+
+octave_value_list read_indexed_images(vector<Image> imvec, Array<int> frameidx, bool wantalpha)
+{
+    octave_value_list output;
+    int rows = imvec[0].baseRows();
+    int columns = imvec[0].baseColumns();
+    int nframes = frameidx.length();
+    ImageType type = imvec[0].type();
+    
+    unsigned int mapsize = imvec[0].colorMapSize();
+    int i = mapsize;
+    unsigned int depth = 0;
+    while(i >>= 1) depth++;
+    i = 0;
+    depth--;
+    while(depth >>= 1) i++;
+    depth = 1 << i;
+
+    int x, y, frame;
+    const IndexPacket *pix;
+    switch(depth) {
+	case 1:
+	case 2:
+	case 4:
+	case 8:
+	{
+	    uint8NDArray im = uint8NDArray(dim_vector(rows, columns, nframes));
+	    for(frame=0; frame < nframes; frame++) {
+		imvec[frameidx(frame)].getConstPixels(0,0, columns, rows);
+		pix = imvec[frameidx(frame)].getConstIndexes();
+		i = 0;      
+		for(y=0; y < rows; y++) {
+		    for(x=0; x < columns; x++) {        
+			im(y, x, frame) = static_cast<octave_uint8>(pix[i++]);
+		    }
+		}
+	    }
+	    im.chop_trailing_singletons();
+	    output(0) = octave_value(im);
+	}
+	    break;
+	case 16:
+	{
+	    uint16NDArray im = uint16NDArray(dim_vector(rows, columns, nframes));
+	    for(frame=0; frame < nframes; frame++) {
+		imvec[frameidx(frame)].getConstPixels(0,0, columns, rows);
+		pix = imvec[frameidx(frame)].getConstIndexes();		
+		i = 0;      
+		for(y=0; y < rows; y++) {
+		    for(x=0; x < columns; x++) {
+			im(y, x, frame) = static_cast<octave_uint16>(pix[i++]);
+		    }
+		}
+	    }
+	    im.chop_trailing_singletons();
+	    output(0) = octave_value(im);
+	}
+	    break;
+	default:
+	    error("Index depths bigger than 16-bit not supported");
+	    return octave_value_list();
+    }
+
+    ColorRGB c;
+    Matrix map = Matrix(mapsize, 3);
+    Matrix alpha;
+    switch(type) {
+	case PaletteMatteType:
+/*	    warning("palettematte");
+	    map = Matrix(mapsize, 3);
+	    alpha = Matrix(mapsize, 1);
+	    for(i = 0; i < mapsize; i++) {
+		warning("%d", i);
+		c = imvec[0].colorMap(i);
+		map(i, 0) = c.red();
+		map(i, 1) = c.green();
+		map(i, 2) = c.blue();
+		alpha(i, 1) = c.alpha();				
+	    }
+	    break;	    */
+    	case PaletteType:
+	    alpha = Matrix(0,0);
+	    for(i = 0; i < mapsize; i++) {
+		c = imvec[0].colorMap(i);
+		map(i, 0) = c.red();
+		map(i, 1) = c.green();
+		map(i, 2) = c.blue();		
+	    }
+	    break;	    
+	default:
+	    error("Unsupported indexed image type");
+	    return octave_value_list();
+    }
+
+    output(1) = octave_value(map);
+    if(wantalpha) {
+	output(2) = octave_value(alpha);
+    }     
+    return output;
+}
+
+template <class T>
+octave_value_list read_images(vector<Image> imvec, Array<int> frameidx)
+{
+  int i;
+  T im;  
+  int rows = imvec[0].baseRows();
+  int columns = imvec[0].baseColumns();
+  int nframes = frameidx.length();
+  ImageType type = imvec[0].type();
+  
+  int x, y, frame;
+  const PixelPacket *pix;
+  dim_vector idim = dim_vector();
+  idim.resize(4);
+  idim(0) = rows;
+  idim(1) = columns;
+  idim(2) = 1;
+  idim(3) = nframes;
+  Array<int> idx(dim_vector(4));
+  switch(type) {
+      case BilevelType:
+    //    break;
+      case GrayscaleType:
+	  im = T(dim_vector(rows, columns, nframes));
+	  for(frame=0; frame < nframes; frame++) {
+	      pix = imvec[frameidx(frame)].getConstPixels(0,0, columns, rows);
+	      i = 0;      
+	      for(y=0; y < rows; y++) {
+		  for(x=0; x < columns; x++) {        
+		      im(y, x, frame) = pix[i++].red;
+		  }
+	      }
+	  }
+	  break;
+      case GrayscaleMatteType:
+	  idim(2) = 2;
+	  im = T(idim);
+	  for(frame=0; frame < nframes; frame++) {
+	      idx(3) = frame;
+	      i = 0;
+	      pix = imvec[frameidx(frame)].getConstPixels(0,0, columns, rows);
+	      for(y=0; y < rows; y++) {
+		  idx(0) = y;
+		  for(x=0; x < columns; x++) {
+		      idx(1) = x;
+		      idx(2) = 0;
+		      im(idx) = pix[i].red;
+		      idx(2) = 1;
+		      im(idx) = pix[i].opacity;
+		      i++;
+		  }
+	      }
+	  }    
+	  break;
+      case PaletteType:
+      case TrueColorType:
+	  idim(2) = 3;
+	  im = T(idim);      
+	  for(frame=0; frame < nframes; frame++) {
+	      idx(3) = frame;
+	      i = 0;
+	      pix = imvec[frameidx(frame)].getConstPixels(0,0, columns, rows);
+	      for(y=0; y < rows; y++) {
+		  idx(0) = y;
+		  for(x=0; x < columns; x++) {
+		      idx(1) = x;
+		      idx(2) = 0;
+		      im(idx) = pix[i].red;
+		      idx(2) = 1;
+		      im(idx) = pix[i].green;
+		      idx(2) = 2;
+		      im(idx) = pix[i].blue;
+		      i++;
+		  }
+	      }
+	  }      
+	  break;
+      case PaletteMatteType:
+      case TrueColorMatteType:
+      case ColorSeparationType:
+	  idim(2) = 4;
+	  im = T(idim);      	  
+	  for(frame=0; frame < nframes; frame++) {
+	      idx(3) = frame;
+	      i = 0;
+	      pix = imvec[frameidx(frame)].getConstPixels(0,0, columns, rows);
+	      for(y=0; y < rows; y++) {
+		  idx(0) = y;
+		  for(x=0; x < columns; x++) {
+		      idx(1) = x;
+		      idx(2) = 0;
+		      im(idx) = pix[i].red;
+		      idx(2) = 1;
+		      im(idx) = pix[i].green;
+		      idx(2) = 2;
+		      im(idx) = pix[i].blue;
+		      idx(2) = 3;
+		      im(idx) = pix[i].opacity;
+		      i++;
+		  }
+	      }
+	  }      
+	  break;
+      default:
+	  error("Undefined Imagemagick image type");
+	  return octave_value_list();
+  }
+
+  im.chop_trailing_singletons();
+  return octave_value_list(octave_value(im));
+}
+
+// instantiate templates
+template octave_value_list read_images<boolNDArray>(vector<Image>, Array<int>);
+template octave_value_list read_images<uint8NDArray>(vector<Image>, Array<int>);
+template octave_value_list read_images<uint16NDArray>(vector<Image>, Array<int>);
+
+DEFUN_DLD(__magick_read__, args, nargout,
+"function m = __imagemagick_read__(fname[, index])\n\
+function [m, colormap] = __imagemagick_read__(fname[, index])\n\
+function [m, colormap, alpha] = __imagemagick_read__(fname[, index])\n\
+\n\
+Read images with ImageMagick++. User interface in imread.m.\n\
+\n\
+")
+{
+    octave_value_list output;
+    int i;    
+    if(args.length() > 2 || args.length() < 1 || !args(0).is_string() \
+       || nargout > 3) {
+      print_usage ("magick_read");
+      return octave_value_list();
+    }
+    Array<int> frameidx;
+    if(args.length() == 2 && args(1).is_real_type()) {
+	frameidx = args(1).int_vector_value();
+    } else {
+	frameidx = Array<int>(1);
+	frameidx(0) = 1;
+    }
+
+    vector<Image> imvec;
+    try {
+	// Read a file into vector of image objects
+	readImages(&imvec, args(0).string_value());
+    }
+    catch( Warning &warning_ ) {
+        warning("Magick++ warning: %s", warning_.what());
+    }
+    catch( ErrorCoder &error_) {
+	warning("Magick++ coder error: %s", error_.what());
+    }
+    catch( Exception &error_ ) {
+	error("Magick++ exception: %s", error_.what());
+	imvec.clear();
+	return octave_value_list();	
+    }
+
+    int nframes = imvec.size();
+    for(i = 0; i < frameidx.length(); i++) {
+	frameidx(i) = frameidx(i) - 1;
+	if(frameidx(i) >= nframes || frameidx(i) < 0) {
+	    error("Invalid index vector");
+	    imvec.clear();
+	    return output;
+	}
+    }
+    
+    ClassType klass = imvec[0].classType();
+    if(klass == PseudoClass && nargout > 1) {
+	output = read_indexed_images(imvec, frameidx, (nargout == 3));
+    } else {
+	int depth = imvec[0].modulusDepth();
+	i = 0;
+	while(depth >>= 1) i++;
+	depth = 1 << i;
+	
+	switch(depth) {
+	    case 1:
+		output = read_images<boolNDArray>(imvec, frameidx);
+	    break;
+	    case 2:
+	    case 4:
+	    case 8:
+		output = read_images<uint8NDArray>(imvec, frameidx);		
+	    break;
+	    case 16:
+		output = read_images<uint16NDArray>(imvec, frameidx);		
+	    break;
+	    case 32:
+	    case 64:
+	    default:
+		error("Image depths bigger than 16-bit not supported");
+	}
+	if(nargout > 1) {
+	    output(1) = Matrix(0,0);
+	    if(nargout > 2)
+		output(2) = Matrix(0,0);
+	}
+    }
+    imvec.clear();
+
+    return output;
+}