Index: src/simutrans/descriptor/ground_desc.cc
===================================================================
--- src/simutrans/descriptor/ground_desc.cc	(revision 12130)
+++ src/simutrans/descriptor/ground_desc.cc	(working copy)
@@ -239,6 +239,7 @@
 		image_t *image_dest = image_t::create_single_pixel();
 		return image_dest;
 	}
+#if COLOUR_DEPTH != 0
 	// assumes ref is texture image with no clear runs, full rows.
 	image_t *image_dest = image_t::copy_image(*ref);
 	PIXVAL *const sp2 = image_dest->get_data();
@@ -299,6 +300,7 @@
 	}
 	// image_dest not registered
 	return image_dest;
+#endif
 #undef copypixel
 }
 
@@ -449,11 +451,12 @@
 	if(image_offset!=IMG_EMPTY) {
 		gfx->free_all_images_above(image_offset);
 	}
-#if COLOUR_DEPTH != 0
+#if COLOUR_DEPTH == 0
+	return;
+#else
 	while (!ground_image_list.empty()) {
 		delete ground_image_list.remove_first();
 	}
-#endif
 
 	// not the wrong tile size?
 	assert(boden_texture->get_image_ptr(0)->get_pic()->w == ground_desc_t::outside->get_image_ptr(0)->get_pic()->w);
@@ -921,6 +924,7 @@
 #endif
 	//dbg->message("ground_desc_t::calc_water_level()", "Last image nr %u", final_tile->get_pic()->imageid);
 	DBG_DEBUG("ground_desc_t::init_ground_textures()", "Init ground textures successful");
+#endif
 }
 
 
Index: src/simutrans/descriptor/image.cc
===================================================================
--- src/simutrans/descriptor/image.cc	(revision 12130)
+++ src/simutrans/descriptor/image.cc	(working copy)
@@ -12,6 +12,7 @@
 #include <string.h>
 #include <stdlib.h>
 
+freelist_tpl<image_t> image_t::ifl;
 
 /**
  * Definition of special colors
@@ -55,15 +56,24 @@
 
 image_t* image_t::copy_image(const image_t& other)
 {
+#if COLOUR_DEPTH == 0
+	image_t* img = new image_t();
+	img->x = other.x;
+	img->y = other.y;
+	img->w = other.w;
+	img->h = other.h;
+	img->imageid = IMG_EMPTY;
+#else
 	image_t* img = new image_t(other.len);
-	img->len = other.len;
 	img->x   = other.x;
 	img->y   = other.y;
 	img->w   = other.w;
 	img->h   = other.h;
 	img->imageid  = IMG_EMPTY;
+	img->len = other.len;
 	img->zoomable = other.zoomable;
 	memcpy(img->data, other.data, other.len * sizeof(PIXVAL));
+#endif
 	return img;
 }
 
@@ -71,20 +81,25 @@
 image_t* image_t::create_single_pixel()
 {
 	image_t* desc = new image_t(4);
-	desc->len = 4;
 	desc->x = 0;
 	desc->y = 0;
 	desc->w = 1;
 	desc->h = 1;
+#if COLOUR_DEPTH != 0
+	desc->len = 4;
 	desc->zoomable = 0;
 	desc->data[0] = 0;
 	desc->data[1] = 0;
 	desc->data[2] = 0;
 	desc->data[3] = 0;
+#endif
 	return desc;
 }
 
 
+#if COLOUR_DEPTH != 0
+
+
 /* rotate_image_data - produces a (rotated) image
  * only rotates by 90 degrees or multiples thereof, and assumes a square image
  * Otherwise it will only succeed for angle=0;
@@ -189,3 +204,5 @@
 	}
 	return target_image;
 }
+
+#endif
Index: src/simutrans/descriptor/image.h
===================================================================
--- src/simutrans/descriptor/image.h	(revision 12130)
+++ src/simutrans/descriptor/image.h	(working copy)
@@ -6,6 +6,7 @@
 #ifndef DESCRIPTOR_IMAGE_H
 #define DESCRIPTOR_IMAGE_H
 
+#include "../tpl/freelist_tpl.h"
 
 #include "../display/simgraph.h"
 #include "../display/simimg.h"
@@ -17,8 +18,65 @@
 
 #define SPECIAL_TRANSPARENT (0x00E7FFFF)
 
+#if COLOUR_DEPTH == 0
 
+/**
+ * Data of one image
+ *
+ * Child nodes:
+ *  (none)
+ */
+class image_t : public obj_desc_t
+{
+private:
+	static freelist_tpl<image_t> ifl;
 
+public:
+	static const uint32 rgbtab[SPECIAL];
+
+	image_id imageid = 0; ///< Graphics renderer image id
+	scr_coord_val x = 0;  ///< x offset of data[] image
+	scr_coord_val y = 0;  ///< y offset of data[] image
+	scr_coord_val w = 0;  ///< width of data[] image
+	scr_coord_val h = 0;  ///< height of data[] image
+
+ 	void* operator new(size_t) { return ifl.gimme_node(); }
+	void operator delete(void* p) { return ifl.putback_node(p); }
+
+	image_t(size_t len_ = 0)
+	{
+		(void)len_;
+	}
+
+	static image_t* copy_image(const image_t& other);
+
+	const image_t* get_pic() const { return this; }
+
+	uint16 const* get_data() const { return NULL; }
+	uint16* get_data() { return NULL; }
+
+	image_id get_id() const { return imageid; }
+
+	/* rotate_image_data - produces a (rotated) image
+	 * only rotates by 90 degrees or multiples thereof, and assumes a square image
+	 * Otherwise it will only succeed for angle=0;
+	 */
+	image_t* copy_rotate(const sint16 angle) const;
+
+	image_t* copy_flipvertical() const;
+	image_t* copy_fliphorizontal() const;
+
+	static image_t* create_single_pixel();
+
+	void register_image() { this->imageid = gfx->register_image(this); }
+
+private:
+	friend class image_reader_t;
+};
+
+#else
+
+
 /**
  * Data of one image
  *
@@ -27,18 +85,24 @@
  */
 class image_t : public obj_desc_t
 {
+private:
+	static freelist_tpl<image_t> ifl;
+
 public:
 	static const uint32 rgbtab[SPECIAL];
 
-	size_t len = 0;       ///< length of data[] in PIXVAL units
+	image_id imageid = 0; ///< Graphics renderer image id
 	scr_coord_val x = 0;  ///< x offset of data[] image
 	scr_coord_val y = 0;  ///< y offset of data[] image
 	scr_coord_val w = 0;  ///< width of data[] image
 	scr_coord_val h = 0;  ///< height of data[] image
-	image_id imageid = 0; ///< Graphics renderer image id
 	uint8 zoomable = 0;   ///< some images may not be zoomed i.e. icons
+	size_t len = 0;       ///< length of data[] in PIXVAL units
 	PIXVAL *data = NULL;  ///< RLE encoded image data
 
+	void* operator new(size_t) { return ifl.gimme_node(); }
+	void operator delete(void* p) { return ifl.putback_node(p); }
+
 	image_t(size_t len_=0)
 	{
 		if (len_) {
@@ -85,3 +149,5 @@
 };
 
 #endif
+
+#endif
Index: src/simutrans/descriptor/reader/image_reader.cc
===================================================================
--- src/simutrans/descriptor/reader/image_reader.cc	(revision 12130)
+++ src/simutrans/descriptor/reader/image_reader.cc	(working copy)
@@ -18,13 +18,6 @@
 #include "../../tpl/inthashtable_tpl.h"
 
 
-// if without graphics backend, do not copy any pixel
-#if COLOUR_DEPTH != 0
-#define skip_reading_pixels_if_no_graphics
-#else
-#define skip_reading_pixels_if_no_graphics goto adjust_image
-#endif
-
 obj_desc_t *image_reader_t::read_node(FILE *fp, obj_node_info_t &node)
 {
 	node_body_t p(fp, node.size, get_type_name());
@@ -36,26 +29,20 @@
 	uint8 version = decode_uint8(p);
 	p.seek(0);
 
-#if COLOUR_DEPTH != 0
-	image_t *desc = new image_t();
-#else
-	// reserve space for one single pixel and initialize data
-	image_t *desc = image_t::create_single_pixel();
-#endif
+	image_t* desc = new image_t();
 
+	desc->imageid = IMG_EMPTY;
 	if(version==0) {
 		desc->x = decode_uint8(p);
 		desc->w = decode_uint8(p);
 		desc->y = decode_uint8(p);
 		desc->h = decode_uint8(p);
+#if COLOUR_DEPTH == 0
+		goto adjust_image;
+#else
 		desc->alloc(decode_uint32(p)); // len
-		desc->imageid = IMG_EMPTY;
 		p += 2; // dummys
 		desc->zoomable = decode_uint8(p) != 0;
-
-		skip_reading_pixels_if_no_graphics;
-		//PAKSET_INFO("image_t::read_node()","x,y=%d,%d  w,h=%d,%d, len=%i",desc->x,desc->y,desc->w,desc->h, desc->len);
-
 		uint16* dest = desc->data;
 		p.seek(12);
 
@@ -69,6 +56,7 @@
 				*dest++ = data;
 			}
 		}
+#endif
 	}
 	else if(version<=2) {
 		desc->x = decode_sint16(p);
@@ -75,13 +63,14 @@
 		desc->y = decode_sint16(p);
 		desc->w = decode_uint8(p);
 		desc->h = decode_uint8(p);
+#if COLOUR_DEPTH == 0
+		goto adjust_image;
+#else
 		p++; // skip version information
 		desc->alloc(decode_uint16(p)); // len
 		desc->zoomable = decode_uint8(p) != 0;
-		desc->imageid = IMG_EMPTY;
-
-		skip_reading_pixels_if_no_graphics;
 		p.read_uint16_block(desc->data, desc->len);
+#endif
 	}
 	else if(version==3) {
 		desc->x = decode_sint16(p);
@@ -89,12 +78,13 @@
 		desc->w = decode_sint16(p);
 		p++; // skip version information
 		desc->h = decode_sint16(p);
+#if COLOUR_DEPTH == 0
+		goto adjust_image;
+#else
 		desc->alloc((node.size-10)/2); // len
 		desc->zoomable = decode_uint8(p) != 0;
-		desc->imageid = IMG_EMPTY;
-
-		skip_reading_pixels_if_no_graphics;
 		p.read_uint16_block(desc->data, desc->len);
+#endif
 	}
 	else {
 		dbg->fatal( "image_reader_t::read_node()", "Cannot handle too new node version %i", version );
@@ -104,17 +94,11 @@
 adjust_image:
 	// drop the pixels but keep x/y/w/h: descriptors derive data from them
 	// (building_desc_t::calc_height_clearance), and that must not depend on the backend
-	if(  desc->len > 0  ) {
-		// alloc() releases the buffer read above, setting len alone would keep it
-		desc->alloc(4);
-		memset(desc->data, 0, desc->len*sizeof(PIXVAL));
-	}
 #else
 	if (!image_has_valid_data(desc)) {
 		delete desc;
 		return NULL;
 	}
-#endif
 
 	// check for left corner
 	if(COLOUR_DEPTH != 0  &&  version<2  &&  desc->h>0) {
@@ -202,6 +186,7 @@
 			desc = same;
 		}
 	}
+#endif
 
 	return desc;
 }
@@ -211,6 +196,7 @@
 
 bool image_reader_t::image_has_valid_data(image_t *image_in) const
 {
+#if COLOUR_DEPTH != 0
 	PIXVAL *src = image_in->data;
 	PIXVAL *end = image_in->data + image_in->len;
 
@@ -234,4 +220,7 @@
 	}
 
 	return src == end;
+#else
+	return true;
+#endif
 }
