Index: uspace/lib/c/include/ipc/fb.h
===================================================================
--- uspace/lib/c/include/ipc/fb.h	(revision 67b05ff8a6156c062aa30c1388fc37fc148a7ea2)
+++ uspace/lib/c/include/ipc/fb.h	(revision c6f087267a5341520c2f7f049eae7b1a387ecb14)
@@ -55,14 +55,14 @@
 	FB_DRAW_TEXT_DATA,
 	FB_FLUSH,
-	FB_DRAW_PPM,
+	FB_DRAW_IMGMAP,
 	FB_PREPARE_SHM,
 	FB_DROP_SHM,
-	FB_SHM2PIXMAP,
-	FB_VP_DRAW_PIXMAP,
-	FB_VP2PIXMAP,
-	FB_DROP_PIXMAP,
+	FB_SHM2IMGMAP,
+	FB_VP_DRAW_IMGMAP,
+	FB_VP2IMGMAP,
+	FB_DROP_IMGMAP,
 	FB_ANIM_CREATE,
 	FB_ANIM_DROP,
-	FB_ANIM_ADDPIXMAP,
+	FB_ANIM_ADDIMGMAP,
 	FB_ANIM_CHGVP,
 	FB_ANIM_START,
Index: uspace/lib/imgmap/imgmap.c
===================================================================
--- uspace/lib/imgmap/imgmap.c	(revision 67b05ff8a6156c062aa30c1388fc37fc148a7ea2)
+++ uspace/lib/imgmap/imgmap.c	(revision c6f087267a5341520c2f7f049eae7b1a387ecb14)
@@ -69,8 +69,8 @@
 	IMG_CMAP = 1,
 	IMG_BGRA = 2,
-	IMG_BW = 3,
+	IMG_GRAY = 3,
 	IMG_CMAP_RLE = 9,
 	IMG_BGRA_RLE = 10,
-	IMG_BW_RLE = 11
+	IMG_GRAY_RLE = 11
 } img_type_t;
 
@@ -104,4 +104,5 @@
  *
  * @param[in]  data Memory representation of TGA.
+ * @param[in]  size Size of the representation (in bytes).
  * @param[out] tga  Decoded TGA.
  *
@@ -110,6 +111,10 @@
  *
  */
-static bool decode_tga_header(void *data, tga_t *tga)
+static bool decode_tga_header(void *data, size_t size, tga_t *tga)
 {
+	/* Header sanity check */
+	if (size < sizeof(tga_header_t))
+		return false;
+	
 	tga_header_t *head = (tga_header_t *) data;
 	
@@ -117,4 +122,7 @@
 	tga->id_data = data + sizeof(tga_header_t);
 	tga->id_length = head->id_length;
+	
+	if (size < sizeof(tga_header_t) + tga->id_length)
+		return false;
 	
 	/* Color map type */
@@ -130,4 +138,8 @@
 	tga->cmap_data = tga->id_data + tga->id_length;
 	tga->cmap_length = ALIGN_UP(tga->cmap_entries * tga->cmap_bpp, 8) >> 3;
+	
+	if (size < sizeof(tga_header_t) + tga->id_length +
+	    tga->cmap_length)
+		return false;
 	
 	/* Image specification */
@@ -142,4 +154,8 @@
 	tga->img_length = ALIGN_UP(tga->width * tga->height * tga->img_bpp, 8) >> 3;
 	
+	if (size < sizeof(tga_header_t) + tga->id_length +
+	    tga->cmap_length + tga->img_length)
+		return false;
+	
 	return true;
 }
@@ -152,5 +168,6 @@
  * alpha channel.
  *
- * @param data[in] Memory representation of TGA.
+ * @param[in] data Memory representation of TGA.
+ * @param[in] size Size of the representation (in bytes).
  *
  * @return Newly allocated image map.
@@ -158,8 +175,8 @@
  *
  */
-imgmap_t *imgmap_decode_tga(void *data)
+imgmap_t *imgmap_decode_tga(void *data, size_t size)
 {
 	tga_t tga;
-	if (!decode_tga_header(data, &tga))
+	if (!decode_tga_header(data, size, &tga))
 		return NULL;
 	
@@ -178,4 +195,10 @@
 	switch (tga.img_type) {
 	case IMG_BGRA:
+		if (tga.img_bpp != 24)
+			return NULL;
+		break;
+	case IMG_GRAY:
+		if (tga.img_bpp != 8)
+			return NULL;
 		break;
 	default:
@@ -184,7 +207,4 @@
 	}
 	
-	if (tga.img_bpp != 24)
-		return NULL;
-	
 	if (tga.img_alpha_bpp != 0)
 		return NULL;
@@ -192,24 +212,43 @@
 	sysarg_t twidth = tga.startx + tga.width;
 	sysarg_t theight = tga.starty + tga.height;
-	size_t size = twidth * theight * 3;
-	
-	imgmap_t *imgmap = (imgmap_t *) malloc(sizeof(imgmap_t) + size);
+	size_t bsize = twidth * theight * 3;
+	
+	imgmap_t *imgmap = (imgmap_t *) malloc(sizeof(imgmap_t) + bsize);
 	if (imgmap == NULL)
 		return NULL;
 	
-	imgmap->tag = 'I';
-	imgmap->size = sizeof(imgmap_t) + size;
+	imgmap->size = sizeof(imgmap_t) + bsize;
 	imgmap->width = twidth;
 	imgmap->height = theight;
 	imgmap->visual = VISUAL_BGR_8_8_8;
 	
-	memset(imgmap->data, 0, size);
-	
-	for (sysarg_t y = tga.starty; y < theight; y++) {
-		size_t src_offset = (y - tga.starty) * tga.width * 3;
-		size_t dst_offset = ((theight - y - 1) * twidth + tga.startx) * 3;
-		
-		memcpy(imgmap->data + dst_offset, tga.img_data + src_offset,
-		    tga.width * 3);
+	memset(imgmap->data, 0, bsize);
+	
+	/*
+	 * TGA is encoded in a bottom-up manner.
+	 */
+	
+	switch (tga.img_type) {
+	case IMG_BGRA:
+		for (sysarg_t y = tga.starty; y < theight; y++) {
+			size_t src_offset = (y - tga.starty) * tga.width * 3;
+			size_t dst_offset = ((theight - y - 1) * twidth + tga.startx) * 3;
+			
+			memcpy(imgmap->data + dst_offset, tga.img_data + src_offset,
+			    tga.width * 3);
+		}
+		break;
+	case IMG_GRAY:
+		for (sysarg_t y = tga.starty; y < theight; y++) {
+			for (sysarg_t x = tga.startx; x < twidth; x++) {
+				uint8_t val =
+				    ((uint8_t *) tga.img_data)[(y - tga.starty) * tga.width + (x - tga.startx)];
+				size_t dst_offset = ((theight - y - 1) * twidth + x) * 3;
+				memset(imgmap->data + dst_offset, val, 3);
+			}
+		}
+		break;
+	default:
+		break;
 	}
 	
Index: uspace/lib/imgmap/imgmap.h
===================================================================
--- uspace/lib/imgmap/imgmap.h	(revision 67b05ff8a6156c062aa30c1388fc37fc148a7ea2)
+++ uspace/lib/imgmap/imgmap.h	(revision c6f087267a5341520c2f7f049eae7b1a387ecb14)
@@ -41,5 +41,4 @@
 
 typedef struct {
-	uint8_t tag;
 	size_t size;
 	sysarg_t width;
@@ -49,5 +48,5 @@
 } imgmap_t;
 
-extern imgmap_t *imgmap_decode_tga(void *);
+extern imgmap_t *imgmap_decode_tga(void *, size_t);
 
 #endif
