diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/postscript/g3p9bit |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/postscript/g3p9bit')
-rwxr-xr-x | sys/src/cmd/postscript/g3p9bit/btab | 109 | ||||
-rwxr-xr-x | sys/src/cmd/postscript/g3p9bit/g3p9bit.c | 455 | ||||
-rwxr-xr-x | sys/src/cmd/postscript/g3p9bit/mkfile | 14 | ||||
-rwxr-xr-x | sys/src/cmd/postscript/g3p9bit/wtab | 109 |
4 files changed, 687 insertions, 0 deletions
diff --git a/sys/src/cmd/postscript/g3p9bit/btab b/sys/src/cmd/postscript/g3p9bit/btab new file mode 100755 index 000000000..45ca2c80a --- /dev/null +++ b/sys/src/cmd/postscript/g3p9bit/btab @@ -0,0 +1,109 @@ +{"0000110111", 0}, +{"010", 1}, +{"11", 2}, +{"10", 3}, +{"011", 4}, +{"0011", 5}, +{"0010", 6}, +{"00011", 7}, +{"000101", 8}, +{"000100", 9}, +{"0000100", 10}, +{"0000101", 11}, +{"0000111", 12}, +{"00000100", 13}, +{"00000111", 14}, +{"000011000", 15}, +{"0000010111", 16}, +{"0000011000", 17}, +{"0000001000", 18}, +{"00001100111", 19}, +{"00001101000", 20}, +{"00001101100", 21}, +{"00000110111", 22}, +{"00000101000", 23}, +{"00000010111", 24}, +{"00000011000", 25}, +{"000011001010", 26}, +{"000011001011", 27}, +{"000011001100", 28}, +{"000011001101", 29}, +{"000001101000", 30}, +{"000001101001", 31}, +{"000001101010", 32}, +{"000001101011", 33}, +{"000011010010", 34}, +{"000011010011", 35}, +{"000011010100", 36}, +{"000011010101", 37}, +{"000011010110", 38}, +{"000011010111", 39}, +{"000001101100", 40}, +{"000001101101", 41}, +{"000011011010", 42}, +{"000011011011", 43}, +{"000001010100", 44}, +{"000001010101", 45}, +{"000001010110", 46}, +{"000001010111", 47}, +{"000001100100", 48}, +{"000001100101", 49}, +{"000001010010", 50}, +{"000001010011", 51}, +{"000000100100", 52}, +{"000000110111", 53}, +{"000000111000", 54}, +{"000000100111", 55}, +{"000000101000", 56}, +{"000001011000", 57}, +{"000001011001", 58}, +{"000000101011", 59}, +{"000000101100", 60}, +{"000001011010", 61}, +{"000001100110", 62}, +{"000001100111", 63}, + +{"0000001111", 64}, +{"000011001000", 128}, +{"000011001001", 192}, +{"000001011011", 256}, +{"000000110011", 320}, +{"000000110100", 384}, +{"000000110101", 448}, +{"0000001101100", 512}, +{"0000001101101", 576}, +{"0000001001010", 640}, +{"0000001001011", 704}, +{"0000001001100", 768}, +{"0000001001101", 832}, +{"0000001110010", 896}, +{"0000001110011", 960}, +{"0000001110100", 1024}, +{"0000001110101", 1088}, +{"0000001110110", 1152}, +{"0000001110111", 1216}, +{"0000001010010", 1280}, +{"0000001010011", 1344}, +{"0000001010100", 1408}, +{"0000001010101", 1472}, +{"0000001011010", 1536}, +{"0000001011011", 1600}, +{"0000001100100", 1664}, +{"0000001100101", 1728}, + +{"00000001000", 1792}, +{"00000001100", 1856}, +{"00000001101", 1920}, +{"000000010010", 1984}, +{"000000010011", 2048}, +{"000000010100", 2112}, +{"000000010101", 2176}, +{"000000010110", 2240}, +{"000000010111", 2304}, +{"000000011100", 2368}, +{"000000011101", 2432}, +{"000000011110", 2496}, +{"000000011111", 2560}, + +{"000000000001", -1}, +{"000000000000", -2}, diff --git a/sys/src/cmd/postscript/g3p9bit/g3p9bit.c b/sys/src/cmd/postscript/g3p9bit/g3p9bit.c new file mode 100755 index 000000000..2650d8b08 --- /dev/null +++ b/sys/src/cmd/postscript/g3p9bit/g3p9bit.c @@ -0,0 +1,455 @@ +#include <u.h> +#include <libc.h> + +enum +{ + ERR, + EOL, + MAKE, + TERM, +}; + +enum +{ + White, + Black, +}; + +typedef struct Tab +{ + ushort run; + ushort bits; + int code; +} Tab; + +Tab wtab[8192]; +Tab btab[8192]; +uchar bitrev[256]; +uchar bitnonrev[256]; + +int readrow(uchar *rev, int*); +void initwbtab(void); +void sync(uchar*); +int readfile(int, char*, char*); + +int nbytes; +uchar *bytes; +uchar *pixels; +uchar *buf; +int y; +uint bitoffset; +uint word24; + +enum +{ + Bytes = 1024*1024, + Lines = 1410, /* 1100 for A4, 1410 for B4 */ + Dots = 1728, +}; + +void +error(char *fmt, ...) +{ + char buf[256]; + va_list arg; + + if(fmt){ + va_start(arg, fmt); + vseprint(buf, buf+sizeof buf, fmt, arg); + va_end(arg); + fprint(2, "g3: %s\n", buf); + } + exits(fmt); +} + +void +usage(void) +{ + fprint(2, "usage: g3p9bit [-gy] file\n"); + exits("usage"); +} + +void +main(int argc, char **argv) +{ + int y, fd, n, m; + char *t; + char *file, err[ERRMAX], tbuf[5*12+1]; + int gray=0; + int yscale=1; + + ARGBEGIN{ + case 'g': + /* do simulated 2bit gray to compress x */ + gray++; + break; + case 'y': + /* double each scan line to double the y resolution */ + yscale=2; + break; + default: + usage(); + }ARGEND + + if(argc > 1) + usage(); + + initwbtab(); + buf = malloc(1024*1024); + t = malloc((Dots/8)*Lines); + if(buf==nil || t==nil) + error("malloc failed: %r\n"); + pixels = (uchar*)t; + + file = "<stdin>"; + fd = 0; + if(argc > 0){ + file = argv[0]; + fd = open(file, OREAD); + if(fd < 0) + error("can't open %s", file); + } + y = readfile(fd, file, err); + if(y < 0) + error(err); + sprint(tbuf, "%11d %11d %11d %11d %11d ", gray, 0, 0, Dots/(gray+1), y*yscale); + write(1, tbuf, 5*12); + n = (Dots/8)*y*yscale; + /* write in pieces; brazil pipes work badly with huge counts */ + while(n > 0){ + if(yscale > 1) /* write one scan line */ + m = Dots/8; + else{ /* write lots */ + m = n; + if(m > 8192) + m = 8192; + } + for(y=0; y<yscale; y++){ + if(write(1, t, m) != m) + error("write error"); + n -= m; + } + t += m; + } + if(err[0]) + error(err); + error(nil); +} + +enum{ + Hvres, + Hbaud, + Hwidth, + Hlength, + Hcomp, + HenabECM, + HenabBFT, + Hmsperscan, +}; + +int defhdr[8] = { + 0, /* 98 lpi */ + 0, /* 2400 baud */ + 0, /* 1728 pixels in 215mm */ + 0, /* A4, 297mm */ + 0, /* 1-D modified huffman */ + 0, /* disable ECM */ + 0, /* disable BFT */ + 3, /* 10 ms per scan */ +}; + +int +crackhdr(uchar *ap, int *hdr) +{ + char *p, *q; + int i; + + p = (char*)ap; + q = p; + for(i=0; i<8; i++){ + if(*p<'0' || '9'<*p) + return -1; + hdr[i] = strtol(p, &q, 0); + p = q+1; + } + return p-(char*)ap; +} + +int +readfile(int f, char *file, char *err) +{ + int i, r, lines; + uchar *rev; + int hdr[8]; + + err[0] = 0; + memset(pixels, 0, (Dots/8) * Lines); + nbytes = readn(f, buf, 1024*1024); + if(nbytes==1024*1024 || nbytes<=100){ + bad: + sprint(err, "g3: file improper size or format: %s", file); + return -1; + } + bytes = buf; + if(bytes[0]=='I' && bytes[1]=='I' && bytes[2]=='*'){ /* dumb PC format */ + bytes += 0xf3; + nbytes -= 0xf3; + rev = bitrev; + memmove(hdr, defhdr, sizeof defhdr); + }else if(bytes[0] == 0 && strcmp((char*)bytes+1, "PC Research, Inc") == 0){ /* digifax format */ + memmove(hdr, defhdr, sizeof defhdr); + if(bytes[45] == 0x40 && bytes[29] == 1) /* high resolution */ + hdr[Hvres] = 1; + else + hdr[Hvres] = 0; + /* hdr[26] | (hdr[27]<<8) is page number */ + + bytes += 64; + nbytes -= 64; + rev = bitnonrev; + }else{ + while(nbytes > 2){ + if(bytes[0]=='\n'){ + if(strncmp((char*)bytes+1, "FDCS=", 5) == 0){ + i = crackhdr(bytes+6, hdr); + if(i < 0){ + sprint(err, "g3: bad FDCS in header: %s", file); + return -1; + } + if(hdr[Hwidth] != 0){ + sprint(err, "g3: unsupported width: %s", file); + return -1; + } + if(hdr[Hcomp] != 0){ + sprint(err, "g3: unsupported compression: %s", file); + return -1; + } + bytes += i+1; + nbytes -= i+1; + continue; + } + if(bytes[1] == '\n'){ + bytes += 2; + nbytes -= 2; + break; + } + } + bytes++; + nbytes--; + } + if(nbytes < 2) + goto bad; + rev = bitnonrev; + } + bitoffset = 24; + word24 = 0; + sync(rev); + lines = Lines; + if(hdr[Hvres] == 1) + lines *= 2; + for(y=0; y<lines; y++){ + r = readrow(rev, hdr); + if(r < 0) + break; + if(r == 0) + sync(rev); + } + if(hdr[Hvres] == 1) + y /= 2; +// if(y < 100) +// goto bad; + return y; +} + +int +readrow(uchar *rev, int *hdr) +{ + int bo, state; + Tab *tab, *t; + int x, oldx, x2, oldx2, dx, xx; + uint w24; + uchar *p, *q; + + state = White; + oldx = 0; + bo = bitoffset; + w24 = word24; + x = y; + if(hdr[Hvres] == 1) /* high resolution */ + x /= 2; + p = pixels + x*Dots/8; + x = 0; + +loop: + if(x > Dots) + return 0; + if(state == White) + tab = wtab; + else + tab = btab; + if(bo > (24-13)) { + do { + if(nbytes <= 0) + return -1; + w24 = (w24<<8) | rev[*bytes]; + bo -= 8; + bytes++; + nbytes--; + } while(bo >= 8); + } + + t = tab + ((w24 >> (24-13-bo)) & 8191); + x += t->run; + bo += t->bits; + if(t->code == TERM){ + if(state == White) + oldx = x; + else{ + oldx2 = oldx; + x2 = x; + xx = oldx2&7; + q = p+oldx2/8; + if(x2/8 == oldx2/8) /* all in one byte, but if((x2&7)==0), do harder case */ + *q |= (0xFF>>xx) & (0xFF<<(8-(x2&7))); + else{ + dx = x2 - oldx2; + /* leading edge */ + if(xx){ + *q++ |= 0xFF>>xx; + dx -= 8-xx; + } + /* middle */ + while(dx >= 8){ + *q++ = 0xFF; + dx -= 8; + } + /* trailing edge */ + if(dx) + *q |= 0xFF<<(8-dx); + } + } + state ^= White^Black; + goto loop; + } + if(t->code == ERR){ + bitoffset = bo; + word24 = w24; + return 0; + } + if(t->code == EOL){ + bitoffset = bo; + word24 = w24; + return 1; + } + goto loop; +} + + +void +sync(uchar *rev) +{ + Tab *t; + int c; + + c = 0; +loop: + if(bitoffset > (24-13)) { + do { + if(nbytes <= 0) + return; + word24 = (word24<<8) | rev[*bytes]; + bitoffset -= 8; + bytes++; + nbytes--; + } while(bitoffset >= 8); + } + t = wtab + ((word24 >> (24-13-bitoffset)) & 8191); + if(t->code != EOL) { + bitoffset++; + c++; + goto loop; + } + bitoffset += t->bits; +} + +typedef struct File +{ + char *val; + int code; +}File; + +File ibtab[] = { +#include "btab" +{nil, 0} +}; + +File iwtab[] = { +#include "wtab" +{nil, 0} +}; + +int +binary(char *s) +{ + int n; + + n = 0; + while(*s) + n = n*2 + *s++-'0'; + return n; +} + +void +tabinit(File *file, Tab *tab) +{ + int i, j, v, r, l; + char *b; + + for(v=0; v<8192; v++) { + tab[v].run = 0; + tab[v].bits = 1; + tab[v].code = ERR; + } + for(i=0; b=file[i].val; i++){ + l = strlen(b); + v = binary(b); + r = file[i].code; + if(l > 13) + fprint(2, "g3: oops1 l = %d %s\n", l, b); + + v = v<<(13-l); + for(j=0; j<(1<<((13-l))); j++) { + if(tab[v].code != ERR) + fprint(2, "g3: oops2 %d %s\n", r, b); + tab[v].run = r; + tab[v].bits = l; + tab[v].code = TERM; + if(r < 0) { + tab[v].run = 0; + tab[v].code = EOL; + if(r < -1) { + tab[v].bits = 1; + tab[v].code = MAKE; + } + } + if(r >= 64) { + tab[v].code = MAKE; + } + v++; + } + } + + for(i=0; i<256; i++) + for(j=0; j<8; j++) + if(i & (1<<j)) + bitrev[i] |= 0x80 >> j; + for(i=0; i<256; i++) + bitnonrev[i] = i; +} + +void +initwbtab(void) +{ + tabinit(iwtab, wtab); + tabinit(ibtab, btab); +} diff --git a/sys/src/cmd/postscript/g3p9bit/mkfile b/sys/src/cmd/postscript/g3p9bit/mkfile new file mode 100755 index 000000000..2475a75bc --- /dev/null +++ b/sys/src/cmd/postscript/g3p9bit/mkfile @@ -0,0 +1,14 @@ +</$objtype/mkfile + +<../config + +TARG=g3p9bit + +OFILES=g3p9bit.$O + +HFILES=wtab btab + +BIN=$POSTBIN + +</sys/src/cmd/mkone + diff --git a/sys/src/cmd/postscript/g3p9bit/wtab b/sys/src/cmd/postscript/g3p9bit/wtab new file mode 100755 index 000000000..580b68a48 --- /dev/null +++ b/sys/src/cmd/postscript/g3p9bit/wtab @@ -0,0 +1,109 @@ +{"00110101", 0}, +{"000111", 1}, +{"0111", 2}, +{"1000", 3}, +{"1011", 4}, +{"1100", 5}, +{"1110", 6}, +{"1111", 7}, +{"10011", 8}, +{"10100", 9}, +{"00111", 10}, +{"01000", 11}, +{"001000", 12}, +{"000011", 13}, +{"110100", 14}, +{"110101", 15}, +{"101010", 16}, +{"101011", 17}, +{"0100111", 18}, +{"0001100", 19}, +{"0001000", 20}, +{"0010111", 21}, +{"0000011", 22}, +{"0000100", 23}, +{"0101000", 24}, +{"0101011", 25}, +{"0010011", 26}, +{"0100100", 27}, +{"0011000", 28}, +{"00000010", 29}, +{"00000011", 30}, +{"00011010", 31}, +{"00011011", 32}, +{"00010010", 33}, +{"00010011", 34}, +{"00010100", 35}, +{"00010101", 36}, +{"00010110", 37}, +{"00010111", 38}, +{"00101000", 39}, +{"00101001", 40}, +{"00101010", 41}, +{"00101011", 42}, +{"00101100", 43}, +{"00101101", 44}, +{"00000100", 45}, +{"00000101", 46}, +{"00001010", 47}, +{"00001011", 48}, +{"01010010", 49}, +{"01010011", 50}, +{"01010100", 51}, +{"01010101", 52}, +{"00100100", 53}, +{"00100101", 54}, +{"01011000", 55}, +{"01011001", 56}, +{"01011010", 57}, +{"01011011", 58}, +{"01001010", 59}, +{"01001011", 60}, +{"00110010", 61}, +{"00110011", 62}, +{"00110100", 63}, + +{"11011", 64}, +{"10010", 128}, +{"010111", 192}, +{"0110111", 256}, +{"00110110", 320}, +{"00110111", 384}, +{"01100100", 448}, +{"01100101", 512}, +{"01101000", 576}, +{"01100111", 640}, +{"011001100", 704}, +{"011001101", 768}, +{"011010010", 832}, +{"011010011", 896}, +{"011010100", 960}, +{"011010101", 1024}, +{"011010110", 1088}, +{"011010111", 1152}, +{"011011000", 1216}, +{"011011001", 1280}, +{"011011010", 1344}, +{"011011011", 1408}, +{"010011000", 1472}, +{"010011001", 1536}, +{"010011010", 1600}, +{"011000", 1664}, +{"010011011", 1728}, + +{"00000001000", 1792}, +{"00000001100", 1856}, +{"00000001101", 1920}, +{"000000010010", 1984}, +{"000000010011", 2048}, +{"000000010100", 2112}, +{"000000010101", 2176}, +{"000000010110", 2240}, +{"000000010111", 2304}, +{"000000011100", 2368}, +{"000000011101", 2432}, +{"000000011110", 2496}, +{"000000011111", 2560}, + +{"000000000001", -1}, +{"000000000000", -2}, |