# HG changeset patch
# User address@hidden
# Date 1222281944 -7200
# Node ID 5c269b623ff8a4e39dca7f004cddd283b94c5629
# Parent 31d7885d98690ca9823082227870063bfb43514c
Add the 'imfinfo' function for reading image file information.
diff --git a/doc/interpreter/image.txi b/doc/interpreter/image.txi
--- a/doc/interpreter/image.txi
+++ b/doc/interpreter/image.txi
@@ -63,6 +63,13 @@
@DOCSTRING(saveimage)
@DOCSTRING(IMAGE_PATH)
+
+It is possible to get information about an image file on disk, without actually
+reading in into Octave. This is done using the @code{imfinfo} function which
+provides read access to many of the parameters stored in the header of the image
+file.
+
address@hidden(imfinfo)
@node Displaying Images
@section Displaying Images
diff --git a/scripts/image/Makefile.in b/scripts/image/Makefile.in
--- a/scripts/image/Makefile.in
+++ b/scripts/image/Makefile.in
@@ -35,9 +35,10 @@
SOURCES = __img__.m __img_via_file__.m autumn.m bone.m brighten.m colormap.m \
contrast.m cool.m copper.m flag.m gmap40.m gray.m gray2ind.m hot.m hsv.m \
- hsv2rgb.m image.m image_viewer.m imagesc.m imread.m imshow.m imwrite.m \
- ind2gray.m ind2rgb.m jet.m ntsc2rgb.m ocean.m pink.m prism.m rainbow.m \
- rgb2hsv.m rgb2ind.m rgb2ntsc.m saveimage.m spring.m summer.m white.m winter.m
+ hsv2rgb.m image.m image_viewer.m imagesc.m imfinfo.m imread.m imshow.m \
+ imwrite.m ind2gray.m ind2rgb.m jet.m ntsc2rgb.m ocean.m pink.m prism.m \
+ rainbow.m rgb2hsv.m rgb2ind.m rgb2ntsc.m saveimage.m spring.m summer.m \
+ white.m winter.m
IMAGES = default.img
diff --git a/scripts/image/imfinfo.m b/scripts/image/imfinfo.m
new file mode 100644
--- /dev/null
+++ b/scripts/image/imfinfo.m
@@ -0,0 +1,127 @@
+## Copyright (C) 2008 Soren Hauberg
+##
+## 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
+## .
+
+## -*- texinfo -*-
+## @deftypefn {Function File} address@hidden =} imfinfo (@var{filename})
+## @deftypefnx{Function File} address@hidden =} imfinfo (@var{url})
+## Read image information from a file.
+##
+## @code{imfinfo} returns a structure containing information about the image
+## stored in the file @var{filename}. The output structure contains the following
+## fields.
+##
+## @table @samp
+## @item Filename
+## The full name of the image file.
+## @item FileSize
+## Number of bytes of the image on disk
+## @item FileModDate
+## Date of last modification to the file.
+## @item Height
+## Image height in pixels.
+## @item Width
+## Image Width in pixels.
+## @item BitDepth
+## Number of bits per channel per pixel.
+## @item Format
+## Image format (e.g. @code{"jpeg"}).
+## @item LongFormat
+## Long form image format description.
+## @item XResolution
+## X resolution of the image.
+## @item YResolution
+## Y resolution of the image.
+## @item TotalColors
+## Number of unique colors in the image.
+## @item TileName
+## Tile name.
+## @item AnimationDelay
+## Time in 1/100ths of a second (0 to 65535) which must expire before displaying
+## the next image in an animated sequence.
+## @item AnimationIterations
+## Number of iterations to loop an animation (e.g. Netscape loop extension) for.
+## @item ByteOrder
+## Endian option for formats that support it. Is either @code{"little-endian"},
+## @code{"big-endian"}, or @code{"undefined"}.
+## @item Gamma
+## Gamma level of the image. The same color image displayed on two different
+## workstations may look different due to differences in the display monitor.
+## @item Matte
+## @code{true} if the image has transparency.
+## @item ModulusDepth
+## Image modulus depth (minimum number of bits required to support red/green/blue
+## components without loss of accuracy).
+## @item Quality
+## JPEG/MIFF/PNG compression level.
+## @item QuantizeColors
+## Preferred number of colors in the image.
+## @item ResolutionUnits
+## Units of image resolution. Is either @code{"pixels per inch"},
+## @code{"pixels per centimeter"}, or @code{"undefined"}.
+## @item ColorType
+## Image type. Is either @code{"grayscale"}, @code{"indexed"}, @code{"truecolor"},
+## or @code{"undefined"}.
+## @item View
+## FlashPix viewing parameters.
+## @end table
+##
+## @seealso{imread, imwrite}
+## @end deftypefn
+
+function info = imfinfo (filename)
+
+ if (nargin < 1)
+ print_usage ();
+ endif
+
+ if (!ischar (filename))
+ error ("imfinfo: filename must be a string")
+ endif
+
+ filename = tilde_expand (filename);
+
+ fn = file_in_path (IMAGE_PATH, filename);
+ if (isempty (fn))
+ ## Couldn't find file. See if it's an URL.
+ [contents, isurl] = urlread (filename);
+ if (isurl)
+ ## The file contents has been downloaded. Now we write it to a temproray file.
+ ## XXX: Isn't there an easier way of doing this?
+ ## XXX: Does this approach have endian-issues?
+ [fid, tmpname, msg] = mkstemp ("octave_imfinfo_XXXXXX", true);
+ if (fid < 0)
+ error ("imfinfo: couldn't create temporary file for storing %s", filename);
+ endif
+ fwrite (fid, contents);
+ fclose (fid);
+ fn = tmpname;
+ else
+ error ("imfinfo: cannot find %s", filename);
+ endif
+ endif
+
+ [statinfo, err, msg] = stat (fn);
+ if (err != 0)
+ error ("imfinfo: error reading '%s': %s", fn, msg);
+ endif
+
+ FileModDate = datestr (statinfo.mtime); # XXX: is this the right way to get the date?
+
+ info = __magick_finfo__ (filename);
+ info.FileModDate = FileModDate;
+endfunction
diff --git a/src/DLD-FUNCTIONS/__magick_read__.cc b/src/DLD-FUNCTIONS/__magick_read__.cc
--- a/src/DLD-FUNCTIONS/__magick_read__.cc
+++ b/src/DLD-FUNCTIONS/__magick_read__.cc
@@ -799,6 +799,147 @@
return retval;
}
+template inline
+octave_value magick_to_octave_value (const T magick)
+{
+ return octave_value (magick);
+}
+
+inline
+octave_value magick_to_octave_value (const Magick::EndianType magick)
+{
+ switch (magick)
+ {
+ case Magick::LSBEndian:
+ return octave_value ("little-endian");
+ case Magick::MSBEndian:
+ return octave_value ("big-endian");
+ default:
+ return octave_value ("undefined");
+ }
+}
+
+inline
+octave_value magick_to_octave_value (const Magick::ResolutionType magick)
+{
+ switch (magick)
+ {
+ case Magick::PixelsPerInchResolution:
+ return octave_value ("pixels per inch");
+ case Magick::PixelsPerCentimeterResolution:
+ return octave_value ("pixels per centimeter");
+ default:
+ return octave_value ("undefined");
+ }
+}
+
+inline
+octave_value magick_to_octave_value (const Magick::ImageType magick)
+{
+ switch (magick)
+ {
+ case Magick::BilevelType:
+ case Magick::GrayscaleType:
+ case Magick::GrayscaleMatteType:
+ return octave_value ("grayscale");
+ case Magick::PaletteType:
+ case Magick::PaletteMatteType:
+ return octave_value ("indexed");
+ case Magick::TrueColorType:
+ case Magick::TrueColorMatteType:
+ case Magick::ColorSeparationType:
+ return octave_value ("truecolor");
+ default:
+ return octave_value ("undefined");
+ }
+}
+
+DEFUN_DLD (__magick_finfo__, args, ,
+ "-*- texinfo -*-\n\
address@hidden {Loadable File} {} __magick_finfo__(@var{fname})\n\
+Reads image information with GraphicsMagick++. In general you should not be using\n\
+this function. Instead you should use @code{imfinfo}.\n\
address@hidden, imread}\n\
address@hidden deftypefn")
+{
+ octave_value_list output;
+
+#ifdef HAVE_MAGICK
+
+ if (args.length () < 1 || ! args (0).is_string ())
+ {
+ print_usage ();
+ return output;
+ }
+ const std::string filename = args (0).string_value ();
+
+ try
+ {
+ // Read the file
+ Magick::Image im;
+ im.read (filename);
+
+ // Read properties
+ Octave_map st;
+ st.assign ("Filename", filename);
+
+ // We put this in a try-block because GraphicsMagick will throw exceptions
+ // if a parameter isn't present in the current image.
+ #define GET_PARAM(NAME, OUTNAME) \
+ try {\
+ st.assign (OUTNAME, magick_to_octave_value (im.NAME ()));\
+ } catch (Magick::Warning& w) {}
+
+ // Annoying CamelCase naming is for Matlab compatibility
+ GET_PARAM (fileSize, "FileSize")
+ GET_PARAM (rows, "Height")
+ GET_PARAM (columns, "Width")
+ GET_PARAM (depth, "BitDepth")
+ GET_PARAM (magick, "Format")
+ GET_PARAM (format, "LongFormat")
+ GET_PARAM (xResolution, "XResolution")
+ GET_PARAM (yResolution, "YResolution")
+ GET_PARAM (totalColors, "TotalColors")
+ GET_PARAM (tileName, "TileName")
+ GET_PARAM (animationDelay, "AnimationDelay")
+ GET_PARAM (animationIterations, "AnimationIterations")
+ GET_PARAM (endian, "ByteOrder")
+ GET_PARAM (gamma, "Gamma")
+ GET_PARAM (matte, "Matte")
+ GET_PARAM (modulusDepth, "ModulusDepth")
+ GET_PARAM (quality, "Quality")
+ GET_PARAM (quantizeColors, "QuantizeColors")
+ GET_PARAM (resolutionUnits, "ResolutionUnits")
+ GET_PARAM (type, "ColorType")
+ GET_PARAM (view, "View")
+
+ #undef GET_PARAM
+
+ output (0) = st;
+ }
+ catch (Magick::Warning& w)
+ {
+ warning ("Magick++ warning: %s", w.what ());
+ }
+ catch (Magick::ErrorCoder& e)
+ {
+ warning ("Magick++ coder error: %s", e.what ());
+ }
+ catch (Magick::Exception& e)
+ {
+ error ("Magick++ exception: %s", e.what ());
+ return output;
+ }
+
+#else
+
+ error ("imfinfo: not available in this version of Octave");
+
+#endif
+
+ return output;
+}
+
/*
;;; Local Variables: ***
;;; mode: C++ ***