summaryrefslogtreecommitdiff
path: root/sys/src/cmd/postscript/g3p9bit
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/postscript/g3p9bit
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/postscript/g3p9bit')
-rwxr-xr-xsys/src/cmd/postscript/g3p9bit/btab109
-rwxr-xr-xsys/src/cmd/postscript/g3p9bit/g3p9bit.c455
-rwxr-xr-xsys/src/cmd/postscript/g3p9bit/mkfile14
-rwxr-xr-xsys/src/cmd/postscript/g3p9bit/wtab109
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},