/*
 * 2007+ Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>

#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>

#include <gtk/gtk.h>

struct pixel
{
	guchar		r, g, b, a;
};

static void file_convert_image(GtkImage *img, char *output)
{
	GdkPixbuf *pixbuf = gtk_image_get_pixbuf(img);
	int width, height, rowstride, n_channels;
	guchar *pixels;
	struct pixel *p;
	unsigned char *data;
	int pos, idx, off, fd, size, err;
	int x, y, mt = 0, cur;

	n_channels = gdk_pixbuf_get_n_channels(pixbuf);

	g_assert(gdk_pixbuf_get_colorspace(pixbuf) == GDK_COLORSPACE_RGB);
	g_assert(gdk_pixbuf_get_bits_per_sample(pixbuf) == 8);

	width = gdk_pixbuf_get_width (pixbuf);
	height = gdk_pixbuf_get_height (pixbuf);

	rowstride = gdk_pixbuf_get_rowstride(pixbuf);
	pixels = gdk_pixbuf_get_pixels(pixbuf);

	printf("width: %d, height: %d, out: %s.\n", width, height, output);

	size = width * height / 8;
	data = malloc(size);
	if (!data)
		return;
	
	for (y=0; y<height; ++y) {
		for (x=0; x<width; ++x) {
			p = (struct pixel *)(pixels + y * rowstride + x * n_channels);

			mt += p->r + p->g + p->b;
		}
	}
	
	mt /= height*width*2;

	for (y=0; y<height; ++y) {
		for (x=0; x<width; ++x) {
			p = (struct pixel *)(pixels + y * rowstride + x * n_channels);
			
			cur = p->r + p->g + p->b;

			pos = y*width + x;

			idx = pos / 8;
			off = pos % 8;

			if (cur < 2*mt)
				data[idx] |= (1 << off);
			else
				data[idx] &= ~(1 << off);
		}
	}

	fd = open(output, O_RDWR | O_CREAT | O_TRUNC, 0644);
	if (fd == -1)
		return;

	while (size) {
		err = write(fd, data, size);
		if (err <= 0)
			break;

		data += err;
		size -= err;
	}

	close(fd);

	return;
}

static void usage(char *p)
{
	g_print("Usage: %s -i input -o output\n", p);
}

int main(int argc, char *argv[])
{
	/* GtkWidget is the storage type for widgets */
	GtkWidget *img;
	int ch;
	char *input, *output;

	input = output = NULL;

	while ((ch = getopt(argc, argv, "o:i:h")) != -1) {
		switch (ch) {
			case 'o':
				output = optarg;
				break;
			case 'i':
				input = optarg;
				break;
			default:
				usage(argv[0]);
				return -1;
		}
	}

	if (!input || !output) {
		g_print("Wrong parameters, you must specify all of them.\n");
		usage(argv[0]);
		return -1;
	}

	gtk_init(&argc, &argv);

	img = gtk_image_new_from_file(input);
	file_convert_image(GTK_IMAGE(img), output);

	return 0;
}

