#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); }