/* ppmtovci.c - convert a portable pixmap into VistaCom videocodec file.
**
** by Sami Tikka
** Internet: sti@cs.hut.fi
**
** based on ppmtoyuv
**
** 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"

void main(argc, argv)
		 int argc;
		 char **argv;
{
	FILE *ifp;
	pixel *pixelrow;
	register pixel *pP;
	int rows, cols, format, row;
	register int col;
	pixval maxval;
	unsigned long y1, y2 = 0, u = 0, v = 0, u0 = 0, u1, u2, v0 = 0, v1, v2;
	unsigned char *ybuf;
	unsigned char **uvbuf;

	ppm_init(&argc, argv);

	if (argc > 2)
		pm_usage("[ppmfile]");

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

	ppm_readppminit(ifp, &cols, &rows, &maxval, &format);
	pixelrow = ppm_allocrow(cols);
	ybuf = (unsigned char *) pm_allocrow(cols, sizeof(char));
	uvbuf = (unsigned char **) pm_allocarray(cols, rows / 2, sizeof(char));

	for (row = 0; row < rows; ++row) {
		unsigned char *yptr;

		ppm_readppmrow(ifp, pixelrow, cols, maxval, format);

		for (col = 0, pP = pixelrow, yptr = ybuf; col < cols; col += 2, ++pP) {
			pixval r, g, b;
			long y, u, v;

			r = PPM_GETR(*pP);
			g = PPM_GETG(*pP);
			b = PPM_GETB(*pP);

			y = 16829 * r + 33039 * g + 6416 * b;
			u = -9712 * r - 19073 * g + 28784 * b;
			v = 28784 * r - 24104 * g - 4680 * b;

			*yptr++ = (unsigned char) ((y >> 16) + 16);
			if (!(row & 0x0001)) {
				uvbuf[row / 2][col] = (unsigned char) ((u >> 16) + 128);
				uvbuf[row / 2][col + 1] = (unsigned char) ((v >> 16) + 128);
			}

			pP++;
			r = PPM_GETR(*pP);
			g = PPM_GETG(*pP);
			b = PPM_GETB(*pP);

			y = 16829 * r + 33039 * g + 6416 * b;
			*yptr++ = (unsigned char) ((y >> 16) + 16);
		}
		fwrite(ybuf, cols, 1, stdout);
	}

	/*
	 * Dump UV information at the end.
	 */
	for (row = 0; row < rows; row += 2)
		fwrite(uvbuf[row / 2], cols, 1, stdout);

	pm_close(ifp);
	ppm_freerow(pixelrow);
	pm_freerow(ybuf);
	pm_freearray((char **) uvbuf, rows / 2);
	exit(0);
}
