Index: uspace/srv/hid/fb/ppm.c
===================================================================
--- uspace/srv/hid/fb/ppm.c	(revision 3b3e776c798388c535fed921aeb73f37a0268abd)
+++ uspace/srv/hid/fb/ppm.c	(revision 3b3e776c798388c535fed921aeb73f37a0268abd)
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+
+#include "ppm.h"
+
+static void skip_whitespace(unsigned char **data)
+{
+retry:
+	while (**data == ' ' || **data == '\t' || **data == '\n' ||
+	    **data == '\r')
+		(*data)++;
+	if (**data == '#') {
+		while (1) {
+			if (**data == '\n' || **data == '\r')
+				break;
+			(*data)++;
+		}
+		goto retry;
+	}
+}
+
+static void read_num(unsigned char **data, unsigned int *num)
+{
+	*num = 0;
+	while (**data >= '0' && **data <= '9') {
+		*num *= 10;
+		*num += **data - '0';
+		(*data)++;
+	}
+}
+
+int ppm_get_data(unsigned char *data, size_t dtsz, unsigned int *width,
+    unsigned int *height)
+{
+	/* Read magic */
+	if (data[0] != 'P' || data[1] != '6')
+		return EINVAL;
+
+	data+=2;
+	skip_whitespace(&data);
+	read_num(&data, width);
+	skip_whitespace(&data);
+	read_num(&data,height);
+
+	return 0;
+}
+
+/** Draw PPM pixmap
+ *
+ * @param data Pointer to PPM data
+ * @param datasz Maximum data size
+ * @param sx Coordinate of upper left corner
+ * @param sy Coordinate of upper left corner
+ * @param maxwidth Maximum allowed width for picture
+ * @param maxheight Maximum allowed height for picture
+ * @param putpixel Putpixel function used to print bitmap
+ */
+int ppm_draw(unsigned char *data, size_t datasz, unsigned int sx,
+    unsigned int sy, unsigned int maxwidth, unsigned int maxheight,
+    putpixel_cb_t putpixel, void *vport)
+{
+	unsigned int width, height;
+	unsigned int maxcolor;
+	unsigned int i;
+	unsigned int color;
+	unsigned int coef;
+	
+	/* Read magic */
+	if ((data[0] != 'P') || (data[1] != '6'))
+		return EINVAL;
+	
+	data += 2;
+	skip_whitespace(&data);
+	read_num(&data, &width);
+	skip_whitespace(&data);
+	read_num(&data, &height);
+	skip_whitespace(&data);
+	read_num(&data, &maxcolor);
+	data++;
+	
+	if ((maxcolor == 0) || (maxcolor > 255) || (width * height > datasz))
+		return EINVAL;
+	
+	coef = 255 / maxcolor;
+	if (coef * maxcolor > 255)
+		coef -= 1;
+	
+	for (i = 0; i < width * height; i++) {
+		/* Crop picture if we don't fit into region */
+		if (i % width > maxwidth || i / width > maxheight) {
+			data += 3;
+			continue;
+		}
+		color = ((data[0] * coef) << 16) + ((data[1] * coef) << 8) +
+		    data[2] * coef;
+		
+		(*putpixel)(vport, sx + (i % width), sy + (i / width), color);
+		data += 3;
+	}
+	
+	return 0;
+}
