/* vcitoppm.c - convert VistaCom video codec video image to ppm
 **
 ** by Tero Kivinen, Sami Tikka
 ** Internet: kivinen@hut.fi, sti@cs.hut.fi
 **
 ** Based on yuvtoppm
 **
 **
 ** Permission to use, copy, modify, and distribute this software and its
 ** documentation for any purpose and without fee is hereby granted, provided
 ** that the above copyright notice appear in all copies and that both that
 ** copyright notice and this permission notice appear in supporting
 ** documentation.  This software is provided "as is" without express or
 ** implied warranty.
 */

#include "ppm.h"

#define limit(x) (((x) > 255) ? 255 : (((x) < 0) ? 0 : (unsigned char)(x)))

void main(argc, argv)
		 int argc;
		 char **argv;
{
	FILE *ifp;
	pixel **picture;
	int rows = 288, cols = 352, row, col;
	char *usage = "[vcifile]";
	unsigned char *buffer;

	ppm_init(&argc, argv);

	if (argc > 2)
		pm_usage(usage);

	if (argc == 2) {
		ifp = pm_openr(argv[1]);
	}
	else {
		ifp = stdin;
	}

	ppm_writeppminit(stdout, cols, rows, (pixval) 255, 0);
	picture = ppm_allocarray(cols, rows);
	buffer = malloc(cols);

	for (row = 0; row < rows; row++) {
		fread(buffer, cols, 1, ifp);
		for (col = 0; col < cols; col++) {
			int y;

			y = buffer[col] - 16;
			if (y < 0)
				y = 0;
			if (y > 235)
				y = 235;
			PPM_ASSIGN(picture[row][col], y, y, y);
		}
	}

	for (row = 0; row < rows; row += 2) {
		fread(buffer, cols, 1, ifp);
		for (col = 0; col < cols; col += 2) {
			long y, u, v;
			long r, g, b;

			y = PPM_GETB(picture[row][col]);
			u = buffer[col] - 128;
			v = buffer[col + 1] - 128;

			r = (65536 * y + 91881 * v) >> 16;
			g = (65536 * y - 22554 * u - 46802 * v) >> 16;
			b = (65536 * y + 116130 * u) >> 16;

			PPM_ASSIGN(picture[row][col], limit(r), limit(g), limit(b));

			y = PPM_GETB(picture[row + 1][col]);

			r = (65536 * y + 91881 * v) >> 16;
			g = (65536 * y - 22554 * u - 46802 * v) >> 16;
			b = (65536 * y + 116130 * u) >> 16;

			PPM_ASSIGN(picture[row + 1][col], limit(r), limit(g), limit(b));

			y = PPM_GETB(picture[row][col + 1]);

			r = (65536 * y + 91881 * v) >> 16;
			g = (65536 * y - 22554 * u - 46802 * v) >> 16;
			b = (65536 * y + 116130 * u) >> 16;

			PPM_ASSIGN(picture[row][col + 1], limit(r), limit(g), limit(b));

			y = PPM_GETB(picture[row + 1][col + 1]);

			r = (65536 * y + 91881 * v) >> 16;
			g = (65536 * y - 22554 * u - 46802 * v) >> 16;
			b = (65536 * y + 116130 * u) >> 16;

			PPM_ASSIGN(picture[row + 1][col + 1], limit(r), limit(g), limit(b));
		}
	}

	for (row = 0; row < rows; row++)
		ppm_writeppmrow(stdout, picture[row], cols, (pixval) 255, 0);
	pm_close(ifp);
	pm_close(stdout);
	ppm_freearray(picture, rows);
	exit(0);
}
