Index: app/core/gimpprojection.c
===================================================================
--- app/core/gimpprojection.c	(revision 22694)
+++ app/core/gimpprojection.c	(arbetskopia)
@@ -33,6 +33,7 @@
 #include "gimpprojection.h"
 #include "gimpprojection-construct.h"
 
+#include "libgimpmath/gimpmath.h"
 
 enum
 {
@@ -59,7 +60,7 @@
                                                          gint            x,
                                                          gint            y);
 
-static void       gimp_projection_alloc_tiles           (GimpProjection *proj);
+static void       gimp_projection_alloc_levels          (GimpProjection *proj);
 static void       gimp_projection_add_update_area       (GimpProjection *proj,
                                                          gint            x,
                                                          gint            y,
@@ -83,6 +84,12 @@
                                                          gint            h);
 static void       gimp_projection_validate_tile         (TileManager    *tm,
                                                          Tile           *tile);
+static void       write_quarter                         (Tile           *dest_tile,
+                                                         Tile           *source_tile,
+                                                         gint            i,
+                                                         gint            j);
+static void       gimp_projection_validate_pyramid_tile (TileManager    *tm,
+                                                         Tile           *tile);
 
 static void       gimp_projection_image_update          (GimpImage      *image,
                                                          gint            x,
@@ -139,8 +146,10 @@
 
   proj->type                     = -1;
   proj->bytes                    = 0;
-  proj->tiles                    = NULL;
 
+  proj->pyramid                  = g_new0 (TileManager*, PYRAMID_MAX_LEVELS);
+  proj->top_level                = PYRAMID_BASE_LEVEL;
+
   proj->update_areas             = NULL;
 
   proj->idle_render.idle_id      = 0;
@@ -167,6 +176,7 @@
 gimp_projection_finalize (GObject *object)
 {
   GimpProjection *proj = GIMP_PROJECTION (object);
+  gint            level;
 
   if (proj->idle_render.idle_id)
     {
@@ -180,11 +190,14 @@
   gimp_area_list_free (proj->idle_render.update_areas);
   proj->idle_render.update_areas = NULL;
 
-  if (proj->tiles)
-    {
-      tile_manager_unref (proj->tiles);
-      proj->tiles = NULL;
-    }
+  for (level = 0; level <= proj->top_level; level++)
+    if (proj->pyramid[level])
+      {
+        tile_manager_unref (proj->pyramid[level]);
+        proj->pyramid[level] = NULL;
+      }
+  g_free (proj->pyramid);
+  proj->top_level = 0;
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -195,9 +208,11 @@
 {
   GimpProjection *projection = GIMP_PROJECTION (object);
   gint64          memsize = 0;
+  gint            level;
 
-  if (projection->tiles)
-    memsize += tile_manager_get_memsize (projection->tiles, FALSE);
+  for (level = 0; level <= projection->top_level; level++)
+    if (projection->pyramid[level])
+      memsize += tile_manager_get_memsize (projection->pyramid[level], FALSE);
 
   return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
                                                                   gui_size);
@@ -266,18 +281,63 @@
 TileManager *
 gimp_projection_get_tiles (GimpProjection *proj)
 {
+  return gimp_projection_get_tiles_at_level (proj, PYRAMID_BASE_LEVEL);
+}
+
+TileManager *
+gimp_projection_get_tiles_at_level (GimpProjection *proj,
+                                    gint            level)
+{
+  TileManager *base_level;
+
   g_return_val_if_fail (GIMP_IS_PROJECTION (proj), NULL);
 
-  if (proj->tiles == NULL                                      ||
-      tile_manager_width  (proj->tiles) != proj->image->width ||
-      tile_manager_height (proj->tiles) != proj->image->height)
-    {
-      gimp_projection_alloc_tiles (proj);
-    }
+  base_level = proj->pyramid[PYRAMID_BASE_LEVEL];
 
-  return proj->tiles;
+  if (base_level          == NULL                             ||
+      proj->image->width  != tile_manager_width  (base_level) ||
+      proj->image->height != tile_manager_height (base_level))
+    gimp_projection_alloc_levels (proj);
+
+  g_return_val_if_fail (level >= PYRAMID_BASE_LEVEL &&
+                        level <= proj->top_level,
+                        NULL);
+
+  return proj->pyramid[level];
 }
 
+gint
+gimp_projection_source_width_height (GimpProjection *proj,
+                                     gdouble         scalex,
+                                     gint           *width,
+                                     gint           *height)
+{
+  TileManager *src_tiles;
+  gint         level;
+
+  /* We must make sure the pyramid is up to date. */
+  gimp_projection_alloc_levels (proj);
+
+  level = gimp_projection_scale_to_level (proj, scalex);
+  src_tiles = gimp_projection_get_tiles_at_level (proj, level);
+
+  *width  = tile_manager_width  (src_tiles);
+  *height = tile_manager_height (src_tiles);
+
+  return level;
+}
+
+gint
+gimp_projection_scale_to_level (GimpProjection *proj,
+                                gdouble         scalex)
+{
+  g_return_val_if_fail (GIMP_IS_PROJECTION (proj), PYRAMID_BASE_LEVEL);
+
+  return CLAMP ((gint) -(log (scalex) / log(2)),
+                PYRAMID_BASE_LEVEL,
+                proj->top_level);
+}
+
 GimpImage *
 gimp_projection_get_image (const GimpProjection *proj)
 {
@@ -350,7 +410,7 @@
 /*  private functions  */
 
 static void
-gimp_projection_alloc_tiles (GimpProjection *proj)
+gimp_projection_alloc_levels (GimpProjection *proj)
 {
   GimpImageType proj_type  = 0;
   gint          proj_bytes = 0;
@@ -378,29 +438,71 @@
       g_assert_not_reached ();
     }
 
-  if (proj->tiles)
+  if (proj->pyramid[PYRAMID_BASE_LEVEL])
     {
-      if (proj_type           != proj->type                       ||
-          proj_bytes          != proj->bytes                      ||
-          proj->image->width  != tile_manager_width (proj->tiles) ||
-          proj->image->height != tile_manager_height (proj->tiles))
+      gint current_width  = tile_manager_width  (proj->pyramid[PYRAMID_BASE_LEVEL]);
+      gint current_height = tile_manager_height (proj->pyramid[PYRAMID_BASE_LEVEL]);
+
+      if (proj_type           != proj->type    ||
+          proj_bytes          != proj->bytes   ||
+          proj->image->width  != current_width ||
+          proj->image->height != current_height)
         {
-          tile_manager_unref (proj->tiles);
-          proj->tiles = NULL;
+          gint level;
+
+          for (level = 0; level <= proj->top_level; level++)
+            {
+              tile_manager_unref (proj->pyramid[level]);
+              proj->pyramid[level] = NULL;
+            }
+
+          proj->top_level = 0;
         }
     }
 
-  if (! proj->tiles)
+  if (! proj->pyramid[PYRAMID_BASE_LEVEL])
     {
+      gint level;
+
       proj->type  = proj_type;
       proj->bytes = proj_bytes;
 
-      proj->tiles = tile_manager_new (proj->image->width,
-                                      proj->image->height,
-                                      proj->bytes);
-      tile_manager_set_user_data (proj->tiles, proj);
-      tile_manager_set_validate_proc (proj->tiles,
-                                      gimp_projection_validate_tile);
+      for (level = 0; level < PYRAMID_MAX_LEVELS; level++)
+        {
+          gint level_width  = proj->image->width  / (1 << level);
+          gint level_height = proj->image->height / (1 << level);
+
+          /* There is no use having levels that have the same number of
+           * tiles as the parent level.
+           */
+          if (level        != PYRAMID_BASE_LEVEL &&
+              level_width  <= TILE_WIDTH  / 2    &&
+              level_height <= TILE_HEIGHT / 2)
+            break;
+
+          proj->top_level      = level;
+          proj->pyramid[level] = tile_manager_new (level_width,
+                                                   level_height,
+                                                   proj->bytes);
+
+          tile_manager_set_user_data (proj->pyramid[level], proj);
+
+          if (level == PYRAMID_BASE_LEVEL)
+            {
+              /* Validate tiles by building from the layers of the image. */
+              tile_manager_set_validate_proc (proj->pyramid[level],
+                                              gimp_projection_validate_tile);
+            }
+          else
+            {
+              /* Use the level below to validate tiles. */
+              tile_manager_set_validate_proc (proj->pyramid[level],
+                                              gimp_projection_validate_pyramid_tile);
+
+              tile_manager_set_level_below (proj->pyramid[level],
+                                            proj->pyramid[level - 1]);
+            }
+        }
     }
 }
 
@@ -631,19 +733,16 @@
                             gint            w,
                             gint            h)
 {
-  Tile        *tile;
   TileManager *tm;
-  gint         i, j;
+  gint         level;
 
-  tm = gimp_projection_get_tiles (proj);
+  for (level = 0; level <= proj->top_level; level++)
+    {
+      gint c = (1 << level);
 
-  for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
-    for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
-      {
-        tile = tile_manager_get_tile (tm, j, i, FALSE, FALSE);
-
-        tile_invalidate_tile (&tile, tm, j, i);
-      }
+      tm = gimp_projection_get_tiles_at_level (proj, level);
+      tile_manager_invalidate_area (tm, x / c, y / c, w / c, h / c);
+    }
 }
 
 static void
@@ -662,7 +761,85 @@
   gimp_projection_construct (proj, x, y, w, h);
 }
 
+static void
+write_quarter (Tile *dest_tile,
+               Tile *source_tile,
+               gint  i,
+               gint  j)
+{
+  guchar *source_data    = NULL;
+  guchar *dest_data      = NULL;
 
+  gint    source_ewidth  = tile_ewidth  (source_tile);
+  gint    source_eheight = tile_eheight (source_tile);
+  gint    dest_ewidth    = tile_ewidth  (dest_tile);
+  gint    bpp            = tile_bpp     (dest_tile);
+
+  gint    y;
+
+  tile_lock (source_tile);
+  source_data = tile_data_pointer (source_tile, 0, 0);
+
+  dest_data = tile_data_pointer (dest_tile, 0, 0);
+
+  /* Adjust dest pointer to the right quadrant. */
+  dest_data += i * bpp * (TILE_WIDTH / 2) + j * bpp * dest_ewidth * (TILE_HEIGHT / 2);
+
+  for (y = 0; y < source_eheight / 2; y++)
+    {
+      gint    x;
+      guchar *dst = dest_data + y * dest_ewidth * bpp;
+      guchar *src = source_data + y * 2 * source_ewidth * bpp;
+
+      for (x = 0; x < source_ewidth / 2; x++)
+        {
+          int i;
+          for (i = 0; i < bpp; i++)
+            dst[i] = (src[i] +
+                      src[i + bpp] +
+                      src[i + source_ewidth * bpp] +
+                      src[i + source_ewidth * bpp + bpp]) / 4;
+
+
+          dst += bpp;
+          src += bpp * 2;
+        }
+    }
+
+  tile_release (source_tile, FALSE);
+}
+
+static void
+gimp_projection_validate_pyramid_tile (TileManager *tm,
+                                       Tile        *tile)
+{
+  gint         tile_col;
+  gint         tile_row;
+  gint         i;
+  gint         j;
+  TileManager *level_below  = tile_manager_get_level_below (tm);
+  Tile        *source[2][2] = { { NULL, NULL },
+                                { NULL, NULL } };
+
+  tile_manager_get_tile_col_row (tm, tile, &tile_col, &tile_row);
+
+  for (i = 0; i < 2; i++)
+    for (j = 0; j < 2; j++)
+        source[i][j] = tile_manager_get_at(level_below,
+                                           tile_col * 2 + i,
+                                           tile_row * 2 + j,
+                                           TRUE,
+                                           FALSE);
+  for (i = 0; i < 2; i++)
+    for (j = 0; j < 2; j++)
+      if (source[i][j])
+        {
+          write_quarter (tile, source[i][j], i, j);
+
+          tile_release (source[i][j], FALSE);
+        }
+}
+
 /*  image callbacks  */
 
 static void
@@ -680,7 +857,7 @@
 gimp_projection_image_size_changed (GimpImage      *image,
                                     GimpProjection *proj)
 {
-  gimp_projection_alloc_tiles (proj);
+  gimp_projection_alloc_levels (proj);
   gimp_projection_add_update_area (proj, 0, 0, image->width, image->height);
 }
 
@@ -688,7 +865,7 @@
 gimp_projection_image_mode_changed (GimpImage      *image,
                                     GimpProjection *proj)
 {
-  gimp_projection_alloc_tiles (proj);
+  gimp_projection_alloc_levels (proj);
   gimp_projection_add_update_area (proj, 0, 0, image->width, image->height);
 }
 
Index: app/core/gimpprojection.h
===================================================================
--- app/core/gimpprojection.h	(revision 22694)
+++ app/core/gimpprojection.h	(arbetskopia)
@@ -45,7 +45,10 @@
 #define GIMP_IS_PROJECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PROJECTION))
 #define GIMP_PROJECTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PROJECTION, GimpProjectionClass))
 
+#define PYRAMID_MAX_LEVELS              10
+#define PYRAMID_BASE_LEVEL              0
 
+
 typedef struct _GimpProjectionClass GimpProjectionClass;
 
 struct _GimpProjection
@@ -56,8 +59,11 @@
 
   GimpImageType             type;
   gint                      bytes;
-  TileManager              *tiles;
 
+  /* An image pyramid. Level n + 1 has half the width and height of level n. */
+  TileManager             **pyramid;
+  gint                      top_level;
+
   GSList                   *update_areas;
   GimpProjectionIdleRender  idle_render;
 
@@ -81,7 +87,24 @@
 
 GimpProjection * gimp_projection_new            (GimpImage            *image);
 
+/* Returns the tiles for the base level. */
 TileManager    * gimp_projection_get_tiles      (GimpProjection       *proj);
+
+TileManager    * gimp_projection_get_tiles_at_level
+                                                (GimpProjection       *proj,
+                                                 gint                  level);
+
+/* Convenience function. */
+gint             gimp_projection_source_width_height
+                                                (GimpProjection       *proj,
+                                                 gdouble               scalex,
+                                                 gint                 *width,
+                                                 gint                 *height);
+
+/* Returns which level of the pyramid that should be used for scale 'scale'. */
+gint             gimp_projection_scale_to_level (GimpProjection       *proj,
+                                                 gdouble               scalex);
+
 GimpImage      * gimp_projection_get_image      (const GimpProjection *proj);
 GimpImageType    gimp_projection_get_image_type (const GimpProjection *proj);
 gint             gimp_projection_get_bytes      (const GimpProjection *proj);
@@ -91,5 +114,4 @@
 void             gimp_projection_flush_now      (GimpProjection       *proj);
 void             gimp_projection_finish_draw    (GimpProjection       *proj);
 
-
 #endif /*  __GIMP_PROJECTION_H__  */
Index: app/display/gimpdisplayshell-draw.c
===================================================================
--- app/display/gimpdisplayshell-draw.c	(revision 22694)
+++ app/display/gimpdisplayshell-draw.c	(arbetskopia)
@@ -30,6 +30,7 @@
 #include "core/gimpguide.h"
 #include "core/gimpimage.h"
 #include "core/gimplist.h"
+#include "core/gimpprojection.h"
 #include "core/gimpsamplepoint.h"
 
 #include "vectors/gimpstroke.h"
@@ -504,16 +505,26 @@
                               gint              w,
                               gint              h)
 {
-  gint sx, sy;
-  gint sw, sh;
+  GimpProjection *proj = shell->display->image->projection;
+  gint            width_of_source;
+  gint            height_of_source;
+  gint            sx, sy;
+  gint            sw, sh;
+  gint            level;
 
-  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
+  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell) && GIMP_IS_PROJECTION (proj));
 
+  level = gimp_projection_source_width_height (proj,
+                                               shell->scale_x,
+                                               &width_of_source,
+                                               &height_of_source);
+
   /*  the image's size in display coordinates  */
   sx = shell->disp_xoffset - shell->offset_x;
   sy = shell->disp_yoffset - shell->offset_y;
-  sw = SCALEX (shell, shell->display->image->width);
-  sh = SCALEY (shell, shell->display->image->height);
+  /* SCALE[XY] with pyramid level taken into account. */
+  sw = PROJ_ROUND (width_of_source  * shell->scale_x * (1 << level));
+  sh = PROJ_ROUND (height_of_source * shell->scale_y * (1 << level));
 
   /*  check if the passed in area intersects with
    *  both the display and the image
Index: app/display/gimpdisplayshell-render.c
===================================================================
--- app/display/gimpdisplayshell-render.c	(revision 22694)
+++ app/display/gimpdisplayshell-render.c	(arbetskopia)
@@ -831,20 +831,23 @@
                              gint              h,
                              GimpProjection   *projection)
 {
-  info->shell      = shell;
-  info->w          = w;
-  info->h          = h;
-  info->scalex     = shell->scale_x;
-  info->scaley     = shell->scale_y;
-  info->dest_bpp   = 3;
-  info->dest_bpl   = info->dest_bpp * GIMP_RENDER_BUF_WIDTH;
-  info->dest_width = info->dest_bpp * info->w;
+  gint level      = gimp_projection_scale_to_level (projection, shell->scale_x);
+  info->shell     = shell;
+  info->dest_bpp  = 3;
+  info->dest_bpl  = info->dest_bpp * GIMP_RENDER_BUF_WIDTH;
+  info->scalex     = shell->scale_x * (1 << level);
+  info->scaley     = shell->scale_y * (1 << level);
 
   render_image_init_info (info, shell, x, y,
-                          gimp_projection_get_tiles (projection));
+                          gimp_projection_get_tiles_at_level (projection,
+                                                              level));
+  info->w = w;
+  info->h = h;
+  info->dest_width = info->dest_bpp * info->w;
+  info->scale      = render_image_accelerate_scaling (info->w,
+                                                      info->x,
+                                                      info->scalex);
 
-  info->scale      = render_image_accelerate_scaling (w, info->x, info->scalex);
-
   if (GIMP_IMAGE_TYPE_HAS_ALPHA (gimp_projection_get_image_type (projection)))
     {
       gdouble opacity = gimp_projection_get_opacity (projection);
Index: app/base/tile-manager.c
===================================================================
--- app/base/tile-manager.c	(revision 22694)
+++ app/base/tile-manager.c	(arbetskopia)
@@ -57,13 +57,14 @@
 
   tm = g_slice_new0 (TileManager);
 
-  tm->ref_count  = 1;
-  tm->width      = width;
-  tm->height     = height;
-  tm->bpp        = bpp;
-  tm->ntile_rows = (height + TILE_HEIGHT - 1) / TILE_HEIGHT;
-  tm->ntile_cols = (width  + TILE_WIDTH  - 1) / TILE_WIDTH;
-  tm->cached_num = -1;
+  tm->ref_count   = 1;
+  tm->width       = width;
+  tm->height      = height;
+  tm->bpp         = bpp;
+  tm->ntile_rows  = (height + TILE_HEIGHT - 1) / TILE_HEIGHT;
+  tm->ntile_cols  = (width  + TILE_WIDTH  - 1) / TILE_WIDTH;
+  tm->cached_num  = -1;
+  tm->level_below = NULL;
 
   return tm;
 }
@@ -251,6 +252,22 @@
   return *tile_ptr;
 }
 
+Tile *
+tile_manager_get_at (TileManager *tm,
+                     gint         tile_col,
+                     gint         tile_row,
+                     gint         wantread,
+                     gint         wantwrite)
+{
+  g_return_val_if_fail (tm != NULL, NULL);
+
+  if (tile_col < 0 || tile_col >= tm->ntile_cols ||
+      tile_row < 0 || tile_row >= tm->ntile_rows)
+    return NULL;
+
+  return tile_manager_get(tm, tile_row * tm->ntile_cols + tile_col, wantread, wantwrite);
+}
+
 void
 tile_manager_validate (TileManager *tm,
                        Tile        *tile)
@@ -323,6 +340,7 @@
   Tile *tile = *tile_ptr;
 
   g_return_if_fail (tile_ptr != NULL);
+  g_return_if_fail (tile != NULL);
   g_return_if_fail (tm != NULL);
 
   if (! tile->valid)
@@ -492,6 +510,26 @@
 }
 
 void
+tile_manager_invalidate_area (TileManager *tm,
+                              gint         x,
+                              gint         y,
+                              gint         w,
+                              gint         h)
+{
+  gint  i;
+  gint  j;
+
+  for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
+    for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
+      {
+        Tile *tile = tile_manager_get_tile (tm, j, i, FALSE, FALSE);
+
+        if (tile != NULL)
+          tile_invalidate_tile (&tile, tm, j, i);
+      }
+}
+
+void
 tile_manager_set_user_data (TileManager *tm,
                             gpointer     user_data)
 {
@@ -532,7 +570,40 @@
   return tm->bpp;
 }
 
+gint
+tile_manager_tiles_per_col (const TileManager *tm)
+{
+  g_return_val_if_fail (tm != NULL, 0);
+
+  return tm->ntile_cols;
+}
+
+gint
+tile_manager_tiles_per_row (const TileManager *tm)
+{
+  g_return_val_if_fail (tm != NULL, 0);
+
+  return tm->ntile_rows;
+}
+
+TileManager *
+tile_manager_get_level_below (const TileManager *tm)
+{
+  g_return_val_if_fail (tm != NULL, NULL);
+
+  return tm->level_below;
+}
+
 void
+tile_manager_set_level_below (TileManager *tm,
+                              TileManager *level_below)
+{
+  g_return_if_fail (tm != NULL);
+
+  tm->level_below = level_below;
+}
+
+void
 tile_manager_get_offsets (const TileManager *tm,
                           gint              *x,
                           gint              *y)
@@ -623,6 +694,23 @@
 }
 
 void
+tile_manager_get_tile_col_row (TileManager *tm,
+                               Tile        *tile,
+                               gint        *tile_col,
+                               gint        *tile_row)
+{
+  gint tile_x;
+  gint tile_y;
+
+  g_return_if_fail (tm && tile && tile_col && tile_row);
+
+  tile_manager_get_tile_coordinates (tm, tile, &tile_x, &tile_y);
+
+  *tile_col = tile_x / TILE_WIDTH;
+  *tile_row = tile_y / TILE_HEIGHT;
+}
+
+void
 tile_manager_map_over_tile (TileManager *tm,
                             Tile        *tile,
                             Tile        *srctile)
Index: app/base/tile-manager.h
===================================================================
--- app/base/tile-manager.h	(revision 22694)
+++ app/base/tile-manager.h	(arbetskopia)
@@ -61,6 +61,12 @@
                                               gint         wantread,
                                               gint         wantwrite);
 
+Tile        * tile_manager_get_at            (TileManager *tm,
+                                              gint         tile_col,
+                                              gint         tile_row,
+                                              gint         wantread,
+                                              gint         wantwrite);
+
 void          tile_manager_map_tile          (TileManager *tm,
                                               gint         xpixel,
                                               gint         ypixel,
@@ -89,6 +95,12 @@
 void          tile_manager_invalidate_tiles  (TileManager       *tm,
                                               Tile              *toplevel_tile);
 
+void          tile_manager_invalidate_area   (TileManager       *tm,
+                                              gint               x,
+                                              gint               y,
+                                              gint               w,
+                                              gint               h);
+
 void          tile_manager_set_user_data     (TileManager       *tm,
                                               gpointer           user_data);
 gpointer      tile_manager_get_user_data     (const TileManager *tm);
@@ -96,6 +108,11 @@
 gint          tile_manager_width             (const TileManager *tm);
 gint          tile_manager_height            (const TileManager *tm);
 gint          tile_manager_bpp               (const TileManager *tm);
+gint          tile_manager_tiles_per_col     (const TileManager *tm);
+gint          tile_manager_tiles_per_row     (const TileManager *tm);
+TileManager  *tile_manager_get_level_below   (const TileManager *tm);
+void          tile_manager_set_level_below   (TileManager       *tm,
+                                              TileManager       *level_below);
 
 void          tile_manager_get_offsets       (const TileManager *tm,
                                               gint              *x,
@@ -111,6 +128,10 @@
                                                  Tile        *tile,
                                                  gint        *x,
                                                  gint        *y);
+void          tile_manager_get_tile_col_row     (TileManager *tm,
+                                                 Tile        *tile,
+                                                 gint        *tile_col,
+                                                 gint        *tile_row);
 
 void          tile_manager_map_over_tile        (TileManager *tm,
                                                  Tile        *tile,
Index: app/base/tile-manager-private.h
===================================================================
--- app/base/tile-manager-private.h	(revision 22694)
+++ app/base/tile-manager-private.h	(arbetskopia)
@@ -40,6 +40,10 @@
   gint               cached_num;    /*  number of cached tile                */
   Tile              *cached_tile;   /*  the actual cached tile               */
 
+  TileManager       *level_below;   /*  The TileManager containing the level
+                                     *  below in an image pyramid.
+                                     */
+
   gpointer           user_data;     /*  hook for hanging data off of         */
 };
 
