## Copyright (C) 2002 Andy Adler ## ## This program 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 2, or (at your option) ## any later version. USE THIS SOFTWARE AT YOUR OWN RISK. ## -*- texinfo -*- ## @deftypefn {Function File} address@hidden =} imread(@var{filename}) ## Read images from various file formats. ## ## The size and numeric class of the output depends on the ## format of the image. A colour image is returned as an ## MxNx3 matrix. Grey-level and black-and-white images are ## of size MxN. ## The colour depth of the image determines the numeric ## class of the output: 'uint8' or 'uint16' for grey ## and colour, and 'logical' for black and white. ## ## Note: For image formats other than jpeg and png, the ## ImageMagick "convert" and "identify" utilities ## are needed. ImageMagick can be found at www.imagemagick.org ## @end deftypefn ## Author: Andy Adler ## ## Modified: Stefan van der Walt ## Date: 24 January 2005 ## ## Modified: Thomas Weber ## Date: 20 December 2006 ## Change parsing of imagemagick's output to get the 'color' depth for grayscale ## images ## ## Modified Kristian Rumberg ## Date 2 April 2008 ## Imread now works with BMP's created with "convert inputimage out.bmp" ## (tested with stable release Octave 3.0 in GNU/Linux and Windows XP), ## modified the calling parameters to identify and convert ## ## Modified Thomas Scofield 3 ) varargout{1} = varargout{1}(:,:,1:3); endif break endif ## The next line could be altered from "identify ..." to "gm identify ..." ## If we continue to carry this out with a system call, my guess is that ## more people will have ImageMagick than have GraphicsMagick. But if ## we want this to work for people who have neither, then the system call ## needs to be scrapped and replaced with a call to a dynamically-linked ## routine that again employs the C++ API to GraphicsMagick. ## Note also the system call to ImageMagick's "convert" farther down. [sys, ident] = system(sprintf('identify -verbose \"%s\" | grep -e "bit" -e Type', fn)); if (sys != 0) error("imread: error running ImageMagick's 'identify' on %s", fn); endif depth = re_grab("([[:digit:]]{1,2})-bit", ident); imtype = re_grab("Type: ([[:alpha:]]*)", ident); depth = str2num(depth); if isempty(depth) || (pow2(nextpow2(depth)) != depth) error("imread: invalid image depth %s", depth); endif if !( strcmp(imtype, "Bilevel") || strcmp(imtype, "Grayscale") || strcmp(imtype, "TrueColor") || strcmp(imtype, "TrueColorMatte") || strcmp(imtype, "Palette") ) error("imread: unknown image type '%s'", imtype); endif switch (imtype) case {"Bilevel"} fmt = "pgm"; case {"Grayscale"} fmt = "pgm"; case {"TrueColor", "TrueColorMatte", "Palette"} fmt = "ppm"; endswitch ## Why are pipes so slow? ## cmd = sprintf("convert -flatten -strip %s %s:-", fn, fmt); tmpf = [tmpnam(), ".", fmt]; ##cmd = sprintf("convert -flatten -strip +compress '%s' '%s' 2>/dev/null", ## fn, tmpf); cmd = sprintf("convert -strip \"%s\" \"%s\"", fn, tmpf); sys = system(cmd); if (sys != 0) error("imread: error running ImageMagick's 'convert'"); unlink(tmpf); endif try fid = fopen(tmpf, "rb"); catch unlink(tmpf); error("imread: could not open temporary file %s", tmpf) end_try_catch fgetl(fid); # P5 or P6 (pgm or ppm) [width, height] = sscanf(fgetl(fid), "%d %d", "C"); fgetl(fid); # ignore max components if (depth == 16) ## PGM format has MSB first, i.e. big endian [data, count] = fread(fid, "uint16", 0, "ieee-be"); else [data, count] = fread(fid, "uint8"); endif fclose(fid); unlink(tmpf); if (any(strcmp(imtype, {"TrueColor", "TrueColorMatte", "Palette"}))) channels = 3; else channels = 1; endif if (count != width*height*channels) error("imread: image data chunk has invalid size %i != %i*%i*%i == %i", count, width, height, channels, width*height*channels); endif varargout = {}; switch (imtype) case {"Bilevel"} varargout{1} = logical(reshape(data, width, height)'); case {"Grayscale"} varargout{1} = uint8(reshape(data, width, height)'); case {"TrueColor", "TrueColorMatte", "Palette"} varargout{1} = cat(3, reshape(data(1:3:end), width, height)', reshape(data(2:3:end), width, height)', reshape(data(3:3:end), width, height)'); eval(sprintf("varargout{1} = uint%d(varargout{1});", depth)); endswitch endfunction function value = re_grab(re, str) T = regexp(str,re,'tokens'); if (isempty(T)) value = ""; else value = T{1}{1}; endif endfunction