     nil
   end
 
-  def calc_tiles(project, image_id, image_size = {size_x, size_y}) do
-
-    template = create_template(image_size, @tile_size)
-
-    # todo: build all commands, then flatten, then execute them
+  def calc_tiles(project, image_id, image_size = {width, height}) do
+    template = create_template(Enum.max([width, height]), @tile_size)
     commands = Enum.map(template, fn {{rescale, entries}, z} ->
       rescale = floor(rescale)
-      {cmd, args} = make_rescale_command(project, rescale, rescale)
-      System.cmd(cmd, args)
+      {mkdir_cmd, mkdir_args, rescale_cmd, rescale_args} = make_rescale_commands(project, image_id, rescale)
+      System.cmd(mkdir_cmd, mkdir_args)
+      System.cmd(rescale_cmd, rescale_args)
       Enum.map(entries,
         fn entry ->
-           {cmd_a, args_a, cmd_b, args_b} = make_crop_commands(
-             project, @tile_size, "#{image_id}.#{rescale}.jpg", image_id, z, entry)
-           System.cmd(cmd_a, args_a)
-           System.cmd(cmd_b, args_b)
+           {mkdir_cmd, mkdir_args, crop_cmd, crop_args} = make_crop_commands(
+             project, @tile_size, image_id, rescale, z, entry)
+           System.cmd(mkdir_cmd, mkdir_args)
+           System.cmd(crop_cmd, crop_args)
            nil
         end)
     end)
     nil
   end
 
-  defp create_template(image_size = {size_x, size_y}, tile_size) do
-    Stream.unfold({:continue, image_size}, fn {run, current_size = {current_size_x, current_size_y}} ->
-      if run != :continue do
-        nil
-      else
+  defp create_template(image_size, tile_size) do
+    Stream.unfold({:continue, image_size}, fn {run, current_size} ->
+      if run != :continue, do: nil, else:
         {
           {
             current_size,
             List.flatten(calc_template(current_size, tile_size))
           },
           {
-            if current_size_x < tile_size do :halt else :continue end,
-            {current_size_x / 2, current_size_y / 2}
+            if current_size < tile_size do :halt else :continue end,
+            current_size / 2
           }
         }
-      end
     end) |> Enum.to_list() |> Enum.reverse() |> Enum.with_index()
   end
 

  @tile_size 256
  @required_imagemagick_version [6, 9]
  @required_delegates ["jp2", "png", "jpeg"]

  def required_version_matches(version, [required_major, required_minor]) do
    [major, minor, _] = String.split(version, ".")

    )
  end

  defp make_rescale_commands(project, image_id, rescale) do
    {
      "mkdir",
      [
        "-p", "#{@imageroot}#{project}/#{image_id}"
      ],
      "convert",
      [
        "#{@imageroot}#{project}/#{image_id}.jpg", # todo make param for suffix
        "-resize",
        "#{rescale}x#{rescale}",
        "#{@imageroot}#{project}/#{image_id}/#{image_id}.#{rescale}.#{@intermediate_format_suffix}"
      ]
    }
  end
