Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /branches/vis12/src/compiler/fields/image-info.sml
ViewVC logotype

View of /branches/vis12/src/compiler/fields/image-info.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1784 - (download) (annotate)
Sun Apr 1 19:05:23 2012 UTC (7 years, 6 months ago) by jhr
File size: 6061 byte(s)
  Working on better axis support for dnorm
(* image-info.sml
 *
 * COPYRIGHT (c) 2010 The Diderot Project (http://diderot-language.cs.uchicago.edu)
 * All rights reserved.
 *
 * Information about a NRRD file.
 *
 * TODO:
 *	handle images where the symmetries are exploited.
 *)

structure ImageInfo : sig

  (* Image voxels are tensors of some raw representation type *)
    type voxel_ty = (int list * RawTypes.ty)

  (* a subset of the Nrrd file axis kinds (see http://teem.sourceforge.net/nrrd/format.html#kinds) *)
    datatype axis_kind
      = SPACE
      | SCALAR
      | VEC of int	(* 2, 3, or 4-vector *)
      | MAT of int	(* 2x2 or 3x3 matrix *)

    datatype info = ImgInfo of {
	id : OS.FileSys.file_id,	(* ID of image file *)
	dim : int,			(* dimension of space *)
	ty : voxel_ty,			(* types of image samples *)
	origin : FloatLit.float list,	(* center of first sample *)
	kinds : axis_kind list,		(* the kinds of each axis;
					 * we follow the Nrrd convention of
					 * listing the axes in fast to slow
					 * order.
					 *)
	sizes : int list		(* number of samples along each axis *)
      }

  (* are the underlying files the same? *)
    val same : info * info -> bool

  (* hash value (based on image file ID) *)
    val hash : info -> word

  (* get image info from a Nrrd file *)
    val getInfo : string -> info

    val toString : info -> string
    val dim : info -> int		(* dimension of space *)
    val sizes : info -> int list	(* size of each dimension *)
    val voxelShape : info -> int list	(* shape of voxels; empty list for scalars *)
    val voxelSzB : info -> int		(* size in bytes of a voxel *)
    val stride : info -> int		(* for non-scalar images, this returns the *)
					(* number of samples between voxels *)
    val sampleTy : info -> RawTypes.ty	(* representation type of samples *)

  end = struct

  (* Image samples are tensors of some raw representation type *)
    type voxel_ty = (int list * RawTypes.ty)

  (* a subset of the Nrrd file axis kinds (see http://teem.sourceforge.net/nrrd/format.html#kinds) *)
    datatype axis_kind
      = SPACE
      | SCALAR
      | VEC of int	(* 2, 3, or 4-vector *)
      | MAT of int	(* 2x2 or 3x3 matrix *)

    datatype info = ImgInfo of {
	id : OS.FileSys.file_id,	(* ID of image file *)
	dim : int,			(* dimension of space *)
	ty : voxel_ty,			(* types of image samples *)
	origin : FloatLit.float list,	(* center of first sample *)
	kinds : axis_kind list,		(* the kinds of each axis;
					 * we follow the Nrrd convention of
					 * listing the axes in fast to slow
					 * order.
					 *)
	sizes : int list		(* number of samples along each axis *)
      }

    fun same (ImgInfo{id=a, ...}, ImgInfo{id=b, ...}) = (a = b)

    fun hash (ImgInfo{id, ...}) = OS.FileSys.hash id

    fun doHeader (fileName, header) = let
	  fun fields s = String.tokens Char.isSpace s
	  fun set (r, v) = (r := SOME v)
	  fun get (tag, r) = (case !r of NONE => raise Fail("missing "^tag) | SOME v => v)
	  val ty = ref NONE
	  val totalDim = ref NONE
	  val dim = ref NONE
	  val kinds = ref NONE
	  val sizes = ref NONE
	  fun doValue ("type", v) = set(ty, RawTypes.fromString v)
	    | doValue ("dimension", v) = set (totalDim, valOf(Int.fromString v))
	    | doValue ("space dimension", v) = set (dim, valOf(Int.fromString v))
	    | doValue ("sizes", v) = let
		fun atoi s = (case Int.fromString s
		       of SOME i => i
			| NONE => raise Fail(concat[
			      "bogus dnorm output: \"", "sizes: ", String.toString v, "\n"
			    ])
		      (* end case *))
		in
		  set (sizes, List.map atoi (fields v))
		end
	    | doValue ("space directions", v) = ()
	    | doValue ("kinds", v) = let
		fun s2kind "space" = SPACE
		  | s2kind "scalar" = SCALAR
		  | s2kind "2-vector" = VEC 2
		  | s2kind "3-vector" = VEC 3
		  | s2kind "4-vector" = VEC 4
		  | s2kind "2D-matrix" = MAT 2
		  | s2kind "3D-matrix" = MAT 3
		  | s2kind k = raise Fail(concat["axis kind \"", k, "\" not supported"])
		in
		  set (kinds, List.map s2kind (fields v))
		end
	    | doValue ("endian", v) = ()
	    | doValue ("encoding", v) = ()
	    | doValue ("space origin", v) = ()
	    | doValue _ = ()
	  in
	    Log.msg (concat[fileName, " file header:\n"]);
	    List.app (fn (tag, value) => Log.msg(concat["  ", tag, ": ", value, "\n"])) header;
	    List.app doValue header;
	    let
	    val dim = get ("space dimension", dim)
	    val rngDim = get ("dimension", totalDim) - dim
	  (* split the sizes into those that control the shape of the voxels, which come first
	   * in the list, and those that span the image's dimensions.
	   *)
	    val (rngShape, sizes) = let
		  fun split (0, l, prefix) = (List.rev prefix, l)
		    | split (i, d::l, prefix) = split(i-1, l, d::prefix)
		    | split _ = raise Fail "bogus dnorm output: too few sizes"
		  in
		    split (rngDim, get ("sizes", sizes), [])
		  end
	    in
	      ImgInfo{
		  id = OS.FileSys.fileId fileName,
		  dim = dim,
		  ty = (rngShape, get ("type", ty)),
		  origin = [],	(* FIXME *)
		  kinds = get ("kinds", kinds),
		  sizes = sizes
		}
	    end
	  end

    fun getInfo fileName = if OS.FileSys.access(fileName, [OS.FileSys.A_READ])
	  then let
	    val {version, header} = RunDNorm.run fileName
	    in
	      doHeader (fileName, header)
	    end
	  else raise Fail(concat["Nrrd file \"", fileName, "\" does not exist"])

    fun toString (ImgInfo{dim, ty=(dd, rTy), ...}) = let
	  val shape = (case dd
		 of [] => ""
		  | [d] => concat["{", Int.toString d, "}"]
		  | dd => concat["{", String.concatWith "," (List.map Int.toString dd), "}"]
		(* end case *))
	  in
	    concat[
		"IMAGE", Int.toString dim, "D<", RawTypes.toString rTy, shape, ">"
	      ]
	  end

    fun dim (ImgInfo{dim, ...}) = dim

    fun sizes (ImgInfo{sizes, ...}) = sizes

    fun voxelShape (ImgInfo{ty=(dd, _), ...}) = dd

    fun voxelSzB (ImgInfo{ty=(dd, rTy), ...}) = let
	  val nSamples = List.foldl (op * ) 1 dd
	  in
	    nSamples * RawTypes.sizeb rTy
	  end

    fun stride (ImgInfo{ty=(dd, rTy), ...}) = List.foldl (op * ) 1 dd

    fun sampleTy (ImgInfo{ty=(_, rTy), ...}) = rTy

  end

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0