# HG changeset patch
# User John Donoghue <john.donoghue@ieee.org>
# Date 1389830539 18000
#      Wed Jan 15 19:02:19 2014 -0500
# Node ID 6d3ef72287f8a6d1b8d026c63e7e4f67cc590840
# Parent  906e95708ec1932a5af35837fa2607aa684c8ff4
imread: download image if cant find locally (Bug #41234)

* /scripts/image/private/__imread__.m: if cant find image, attempt to download using urlwrite.

diff -r 906e95708ec1 -r 6d3ef72287f8 scripts/image/private/__imread__.m
--- a/scripts/image/private/__imread__.m	Wed Jan 15 15:28:50 2014 -0500
+++ b/scripts/image/private/__imread__.m	Wed Jan 15 19:02:19 2014 -0500
@@ -44,109 +44,123 @@
   ## keep track of the varargin offset we're looking at each moment
   offset    = 1;
 
-  filename  = tilde_expand (filename);
-  fn        = file_in_path (IMAGE_PATH, filename);
-  if (isempty (fn) && nargin >= offset + 1 && ischar (varargin{offset}))
-    ## if we can't find the file, check if the next input is the file extension
-    filename  = [filename "." varargin{offset}];
+  # keep track of if need to delete a tmp file
+  delete_file = false;
+  
+  unwind_protect
+
+    filename  = tilde_expand (filename);
     fn        = file_in_path (IMAGE_PATH, filename);
-    offset++;
-  endif
-  if (isempty (fn))
-    error ("imread: cannot find %s", filename);
-  endif
+    if (isempty (fn) && nargin >= offset + 1 && ischar (varargin{offset}))
+      ## if we can't find the file, check if the next input is the file extension
+      filename  = [filename "." varargin{offset}];
+      fn        = file_in_path (IMAGE_PATH, filename);
+      offset++;
+    endif
+    if (isempty (fn))
+      [fn, status, msg] = urlwrite (filename, tmpnam ());
+      if (! status)
+        error ("imread: cannot find or load %s", filename);
+      endif
+      delete_file = true;
+    endif
 
-  ## It is possible for an file with multiple pages to have very different
-  ## images on each page. Specifically, they may have different sizes. Because
-  ## of this, we need to first find out the index of the images to read so
-  ## we can set up defaults for things such as PixelRegion later on.
-  options = struct ("index", 1);  # default image index
+    ## It is possible for an file with multiple pages to have very different
+    ## images on each page. Specifically, they may have different sizes. Because
+    ## of this, we need to first find out the index of the images to read so
+    ## we can set up defaults for things such as PixelRegion later on.
+    options = struct ("index", 1);  # default image index
 
-  ## Index is the only option that can be defined without the parameter/value
-  ## pair style. When defining it here, the string "all" is invalid though.
-  ## Also, for matlab compatibility, if index is defined both as an option here
-  ## and parameter/value pair, silently ignore the first.
-  if (nargin >= offset + 1 && ! ischar (varargin{offset}))
-    if (! is_valid_index_option (options.index))
-      error ("imread: IDX must be a numeric vector");
+    ## Index is the only option that can be defined without the parameter/value
+    ## pair style. When defining it here, the string "all" is invalid though.
+    ## Also, for matlab compatibility, if index is defined both as an option here
+    ## and parameter/value pair, silently ignore the first.
+    if (nargin >= offset + 1 && ! ischar (varargin{offset}))
+      if (! is_valid_index_option (options.index))
+        error ("imread: IDX must be a numeric vector");
+      endif
+      options.index = varargin{offset};
+      offset++;
     endif
-    options.index = varargin{offset};
-    offset++;
-  endif
 
-  if (rem (numel (varargin) - offset + 1, 2) != 0)
-    error ("imread: no pair for all arguments (odd number left over)");
-  endif
+    if (rem (numel (varargin) - offset + 1, 2) != 0)
+      error ("imread: no pair for all arguments (odd number left over)");
+    endif
 
-  ## Check key/value options.
-  indexes = cellfun ("isclass", varargin, "char");
-  indexes(indexes) &= ismember (tolower (varargin(indexes)), {"frames", "index"});
-  indexes = find (indexes);
-  if (indexes)
-    options.index = varargin{indexes+1};
-    if (! (is_valid_index_option (options.index)) &&
-        ! (ischar (options.index) && strcmpi (options.index, "all")))
-      error ("imread: value for %s must be a vector or the string `all'");
+    ## Check key/value options.
+    indexes = cellfun ("isclass", varargin, "char");
+    indexes(indexes) &= ismember (tolower (varargin(indexes)), {"frames", "index"});
+    indexes = find (indexes);
+    if (indexes)
+      options.index = varargin{indexes+1};
+      if (! (is_valid_index_option (options.index)) &&
+          ! (ischar (options.index) && strcmpi (options.index, "all")))
+        error ("imread: value for %s must be a vector or the string `all'");
+      endif
     endif
-  endif
 
-  ## Use information from the first image to be read to set defaults.
-  if (ischar (options.index) && strcmpi (options.index, "all"))
-    info = __magick_ping__ (fn, 1);
-  else
-    info = __magick_ping__ (fn, options.index(1));
-  endif
+    ## Use information from the first image to be read to set defaults.
+    if (ischar (options.index) && strcmpi (options.index, "all"))
+      info = __magick_ping__ (fn, 1);
+    else
+      info = __magick_ping__ (fn, options.index(1));
+    endif
 
-  ## Set default for options.
-  options.region = {1:1:info.rows 1:1:info.columns};
+    ## Set default for options.
+    options.region = {1:1:info.rows 1:1:info.columns};
 
-  for idx = offset:2:(numel (varargin) - offset + 1)
-    switch (tolower (varargin{idx}))
+    for idx = offset:2:(numel (varargin) - offset + 1)
+      switch (tolower (varargin{idx}))
 
-      case {"frames", "index"}
-        ## Do nothing. This options were already processed before the loop.
+        case {"frames", "index"}
+          ## Do nothing. This options were already processed before the loop.
 
-      case "pixelregion",
-        options.region = varargin{idx+1};
-        if (! iscell (options.region) || numel (options.region) != 2)
-          error ("imread: value for %s must be a 2 element cell array",
-                 varargin{idx});
-        endif
-        for reg_idx = 1:2
-          if (numel (options.region{reg_idx}) == 3)
-            ## do nothing
-          elseif (numel (options.region{reg_idx}) == 2)
-            options.region{reg_idx}(3) = options.region{reg_idx}(2);
-            options.region{reg_idx}(2) = 1;
-          else
-            error ("imread: range for %s must be a 2 or 3 element vector",
+        case "pixelregion",
+          options.region = varargin{idx+1};
+          if (! iscell (options.region) || numel (options.region) != 2)
+            error ("imread: value for %s must be a 2 element cell array",
                    varargin{idx});
           endif
-          options.region{reg_idx} = floor (options.region{reg_idx}(1)): ...
-                                    floor (options.region{reg_idx}(2)): ...
-                                    floor (options.region{reg_idx}(3));
-        endfor
-        if (options.region{1}(end) > info.rows)
-          error ("imread: end ROWS for PixelRegions option is larger than image height");
-        elseif (options.region{2}(end) > info.columns)
-          error ("imread: end COLS for PixelRegions option is larger than image width");
-        endif
+          for reg_idx = 1:2
+            if (numel (options.region{reg_idx}) == 3)
+              ## do nothing
+            elseif (numel (options.region{reg_idx}) == 2)
+              options.region{reg_idx}(3) = options.region{reg_idx}(2);
+              options.region{reg_idx}(2) = 1;
+            else
+              error ("imread: range for %s must be a 2 or 3 element vector",
+                     varargin{idx});
+            endif
+            options.region{reg_idx} = floor (options.region{reg_idx}(1)): ...
+                                      floor (options.region{reg_idx}(2)): ...
+                                      floor (options.region{reg_idx}(3));
+          endfor
+          if (options.region{1}(end) > info.rows)
+            error ("imread: end ROWS for PixelRegions option is larger than image height");
+          elseif (options.region{2}(end) > info.columns)
+            error ("imread: end COLS for PixelRegions option is larger than image width");
+          endif
 
-      case "info",
-        ## We ignore this option. This parameter exists in Matlab to
-        ## speed up the reading of multipage TIFF by passing a structure
-        ## that contains information about the start on the file of each
-        ## page.  We can't control it through GraphicsMagic but at least
-        ## we allow to load multiple pages with one command.
+        case "info",
+          ## We ignore this option. This parameter exists in Matlab to
+          ## speed up the reading of multipage TIFF by passing a structure
+          ## that contains information about the start on the file of each
+          ## page.  We can't control it through GraphicsMagic but at least
+          ## we allow to load multiple pages with one command.
 
-      otherwise
-        error ("imread: invalid PARAMETER `%s'", varargin{idx});
+        otherwise
+          error ("imread: invalid PARAMETER `%s'", varargin{idx});
 
-    endswitch
-  endfor
+      endswitch
+    endfor
 
-  [varargout{1:nargout}] = __magick_read__ (fn, options);
+    [varargout{1:nargout}] = __magick_read__ (fn, options);
 
+  unwind_protect_cleanup
+    if (delete_file)
+      unlink (fn);
+    endif
+  end_unwind_protect
 endfunction
 
 ## Tests if the value passed to the Index or Frames is valid. This option
