Mercurial > hg > octave-image
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; +}