Mercurial > octave-nkf
view src/DLD-FUNCTIONS/__magick_read__.cc @ 7925:9316b59903c9
Add original imread() files (from octave-forge) to core octave.
* * *
Modify imread() for partial reliance on GraphicsMagick libs; clean up code.
author | Thomas L. Scofield <scofield AT calvin DOT edu> |
---|---|
date | Sat, 12 Jul 2008 10:11:30 -0400 |
parents | |
children | d74f996e005d |
line wrap: on
line source
/* Copyright (C) 2002 Andy Adler 2008 Thomas L. Scofield This file is part of Octave. Octave is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Octave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Octave; see the file COPYING. If not, see <http://www.gnu.org/licenses/>. */ #include <octave/oct.h> #include <GraphicsMagick/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) / MaxRGB * ((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, "\ -*- texinfo -*-\n\ @deftypefn {Function File} {@var{m} =} __imagemagick_read__(@var{fname}, @var{index})\n\ @deftypefnx{Function File} {[@var{m}, @var{colormap}] =} __imagemagick_read__(@var{fname}, @var{index})\n\ @deftypefnx{Function File} {[@var{m}, @var{colormap}, @var{alpha}] =} __imagemagick_read__(@var{fname}, @var{index})\n\ Read images with ImageMagick++. In general you should not be using this function.\n\ Instead you should use @code{imread}.\n\ @seealso{imread}\n\ @end deftypefn\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; }