V10/cmd/qsnap/qprep.c

Compare this file to the similar file:
Show the results in this format:

#include	<stdio.h>
#include	<sys/types.h>
#include	<sys/stat.h>
#include	"defines.h"

#define XTIMES		Times
#define YTIMES		Times
#define Min(a,b)	((a)>(b)?(b):(a))
#define Max(a,b)	((a)<(b)?(b):(a))

int Dither=0, BW=1, Times=6, Reso = 4;
int laplace = 0;

unsigned char nq[9];
char *malloc();
unsigned char *rgb;

Usage(str)
	char *str;
{	fprintf(stderr, "qprep: %s\n", str);
	fprintf(stderr, "usage: qprep -dmL [N ...] file\n");
	fprintf(stderr, "d  dither image +- N [2-255]\n");
	fprintf(stderr, "m  enlargement [1- ], defaults to 3(2k) or 6(4k)\n");
	fprintf(stderr, "L  if bw image, apply 1/2 laplace filter\n");
	exit(1);
}

main(argc, argv)
	char **argv;
{
	int i=1, base=2;	/* base of option arguments */
	char c;

	if (argc > 1 && argv[1][0] == '-')
	{	base++;
		while ((c = argv[1][i++]) != '\0')
			switch (c) {
	/* dither   */	case 'd': if (argc >= base)
				  {	sscanf(argv[base-1], "%d", &Dither);
					base++;
					if (Dither < 0) Dither = -Dither;
					break;
				  } else
				  	Usage("missing argument for `d' flag");

	/* multiply */	case 'm': if (argc >= base)
				  {	sscanf(argv[base-1], "%d", &Times);
					base++;
					break;
				  } else
				  	Usage("missing argument for `m' flag");
	/* laplace */	case 'L': laplace = 2; break;
			default : Usage("unknown option");
			}
	}
	if (base != argc)
		Usage("bad arglist");

	prep(argv[base-1]);
	exit(0);
}

prep(name)
	char *name;
{	int fd, h, w;

	if ((fd = open(name, 0)) == -1)
	{	perror(name);
		exit(1);
	}
	h = w = dimension(fd);
	printf("%s: %dx%d\n", name, w, h);
	if (!(rgb = (unsigned char *) malloc(w*h* sizeof(unsigned char))))
	{	fprintf(stderr, "sorry, not enough memory\n");
		exit(1);
	}
	read(fd, (char *)rgb, w*h);
	close(fd);

	if (laplace)
		filter(rgb, h, w);
	if (Dither)
	{	prerand();
		onedither(rgb, h, w, 1);
	} else
		straight(rgb, h, w, 1);
}

straight(from, h, w, n)
	unsigned char *from;
{
	register i, j, k;
	register unsigned char *p, *q;
	unsigned char obuf[8192];
	int chunk = w*XTIMES;

	for (i = 0, p = from; i < h; i++)
	{	q = obuf;
		for (j = 0; j < w; j++, p += n)
		for (k = 0; k < XTIMES; k++)
			*q++ = *p;
		for (k = 0; k < YTIMES; k++)
			write(1, obuf, chunk);
	}
}

short Nrand[5000];

prerand()
{	register int i, D1=Dither, D2=Dither/2;

	for (i = 0; i < 5000; i++)
		Nrand[i] = (short) (nrand(D1) - D2);
}

onedither(from, h, w, n)
	unsigned char *from;
{
	register int c, m, kk=0;
	register unsigned char *op, *q;
	unsigned char *p, obuf[8192];
	int i, j, k;
	int chunk = w*XTIMES;

	if(w<=0 || XTIMES<=0) abort();
	for (i = 0, p = from; i < h; i++, p = op)
	for (k = 0; k < YTIMES; k++)
	{	q = obuf;
		op = p;
		j = w;
		do{
			m = XTIMES;
			do{
				c = *op + Nrand[kk];
				if (++kk >= 5000) kk = 0;
				if(c<0)
					c=0;
				if(c>255)
					c=255;
				*q++ = c;
			}while(--m);
			op += n;
		}while(--j);
		write(1, obuf, chunk);
	}
}

dimension(fd)
{ 	struct stat bam;
	int N;
	extern float fsqrt();

	if (fstat(fd, &bam)==0)
	{	N = bam.st_size;
		N = (int) fsqrt((double)N+1.0);
		return N;
	}
	return 0;
}

filter(old, h, w)
	register unsigned char *old;
{
	register unsigned char *new;
	register int i, a, x, y;

	if (!(new = (unsigned char *) malloc(w*h* sizeof(unsigned char))))
	{	fprintf(stderr, "sorry, not enough memory for filter\n");
		exit(1);
	}
	for (y = 1; y < h-1; y++)
	for (x = 1; x < w-1; x++)
	{	i = y*w+x;
		a = old[i-1]+old[i+1]+old[i-w]+old[i+w]+
			old[i-w-1]+old[i+w+1]+old[i-w+1]+old[i+w-1];
		a = 5*old[i] - a/2;
		new[i] = (a > 255)?255:(a < 0)?0:a;
	}
	for (y = 1; y < h-1; y++)
	for (x = 1; x < w-1; x++)
	{	i = y*w+x;
		old[i] = new[i];
	}
	free((char *)new);
}