Mercurial > hg > octave-image
changeset 194:b5ddaaa60dd9
Fix for non 8bit Quantum sizes in imagemagick
author | adb014 |
---|---|
date | Sun, 10 Sep 2006 05:41:18 +0000 |
parents | 9747fb34a1dd |
children | 5ecfd5a60e67 |
files | PKG_ADD src/Makefile src/__imagemagick__.cc src/__magick_read__.cc |
diffstat | 4 files changed, 323 insertions(+), 313 deletions(-) [+] |
line wrap: on
line diff
deleted file mode 100644 --- a/PKG_ADD +++ /dev/null @@ -1,1 +0,0 @@ -autoload ("__magick_read__", which ("__imagemagick__"));
--- a/src/Makefile +++ b/src/Makefile @@ -9,7 +9,7 @@ endif ifdef HAVE_MAGICKXX - IMAGEMAGICK=__imagemagick__.oct + IMAGEMAGICK=__magick_read__.oct endif all: cordflt2.oct bwlabel.oct bwfill.oct rotate_scale.oct \ @@ -28,7 +28,7 @@ pngwrite.oct: pngwrite.cc $(MKOCTFILE) $< -lpng -__imagemagick__.oct: __imagemagick__.cc +__magick_read__.oct: __magick_read__.cc $(MKOCTFILE) $< -lMagick++ -lMagick clean: ; -$(RM) *.o octave-core core *.oct *~
deleted file mode 100644 --- a/src/__imagemagick__.cc +++ /dev/null @@ -1,310 +0,0 @@ -#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 (); - 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; -}
new file mode 100644 --- /dev/null +++ b/src/__magick_read__.cc @@ -0,0 +1,321 @@ +#include <octave/oct.h> +#include <Magick++.h> +#include <iostream> +using namespace std; +using namespace Magick; + +unsigned int scaleQuantumToDepth (const Quantum &_quantum, unsigned int depth) +{ + return (static_cast<unsigned int> (static_cast<double>(_quantum) / + QuantumRange * ((1 << depth) - 1))); +} + +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, + unsigned int depth) +{ + 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) = scaleQuantumToDepth (pix[i++].red, depth); + } + } + } + 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) = scaleQuantumToDepth (pix[i].red, depth); + idx(2) = 1; + im(idx) = scaleQuantumToDepth (pix[i].opacity, depth); + 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) = scaleQuantumToDepth (pix[i].red, depth); + idx(2) = 1; + im(idx) = scaleQuantumToDepth (pix[i].green, depth); + idx(2) = 2; + im(idx) = scaleQuantumToDepth (pix[i].blue, depth); + 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) = scaleQuantumToDepth (pix[i].red, depth); + idx(2) = 1; + im(idx) = scaleQuantumToDepth (pix[i].green, depth); + idx(2) = 2; + im(idx) = scaleQuantumToDepth (pix[i].blue, depth); + idx(2) = 3; + im(idx) = scaleQuantumToDepth (pix[i].opacity, depth); + 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>, + unsigned int depth); +template octave_value_list read_images<uint8NDArray>(vector<Image>, + Array<int>, + unsigned int depth); +template octave_value_list read_images<uint16NDArray>(vector<Image>, + Array<int>, + unsigned int depth); + +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 (); + 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 { + unsigned int depth = imvec[0].modulusDepth(); + i = 0; + while(depth >>= 1) i++; + depth = 1 << i; + + switch(depth) { + case 1: + output = read_images<boolNDArray>(imvec, frameidx, depth); + break; + case 2: + case 4: + case 8: + output = read_images<uint8NDArray>(imvec, frameidx, depth); + break; + case 16: + output = read_images<uint16NDArray>(imvec, frameidx, depth); + 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; +}