g3p9bit.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. #include <u.h>
  2. #include <libc.h>
  3. enum
  4. {
  5. ERR,
  6. EOL,
  7. MAKE,
  8. TERM,
  9. };
  10. enum
  11. {
  12. White,
  13. Black,
  14. };
  15. typedef struct Tab
  16. {
  17. ushort run;
  18. ushort bits;
  19. int code;
  20. } Tab;
  21. Tab wtab[8192];
  22. Tab btab[8192];
  23. uchar bitrev[256];
  24. uchar bitnonrev[256];
  25. int readrow(uchar *rev, int*);
  26. void initwbtab(void);
  27. void sync(uchar*);
  28. int readfile(int, char*, char*);
  29. int nbytes;
  30. uchar *bytes;
  31. uchar *pixels;
  32. uchar *buf;
  33. int y;
  34. uint bitoffset;
  35. uint word24;
  36. enum
  37. {
  38. Bytes = 1024*1024,
  39. Lines = 1410, /* 1100 for A4, 1410 for B4 */
  40. Dots = 1728,
  41. };
  42. void
  43. error(char *fmt, ...)
  44. {
  45. char buf[256];
  46. va_list arg;
  47. if(fmt){
  48. va_start(arg, fmt);
  49. vseprint(buf, buf+sizeof buf, fmt, arg);
  50. va_end(arg);
  51. fprint(2, "g3: %s\n", buf);
  52. }
  53. exits(fmt);
  54. }
  55. void
  56. usage(void)
  57. {
  58. fprint(2, "usage: g3p9bit [-gy] file\n");
  59. exits("usage");
  60. }
  61. void
  62. main(int argc, char **argv)
  63. {
  64. int y, fd, n, m;
  65. char *t;
  66. char *file, err[ERRMAX], tbuf[5*12+1];
  67. int gray=0;
  68. int yscale=1;
  69. ARGBEGIN{
  70. case 'g':
  71. /* do simulated 2bit gray to compress x */
  72. gray++;
  73. break;
  74. case 'y':
  75. /* double each scan line to double the y resolution */
  76. yscale=2;
  77. break;
  78. default:
  79. usage();
  80. }ARGEND
  81. if(argc > 1)
  82. usage();
  83. initwbtab();
  84. buf = malloc(1024*1024);
  85. t = malloc((Dots/8)*Lines);
  86. if(buf==nil || t==nil)
  87. error("malloc failed: %r\n");
  88. pixels = (uchar*)t;
  89. file = "<stdin>";
  90. fd = 0;
  91. if(argc > 0){
  92. file = argv[0];
  93. fd = open(file, OREAD);
  94. if(fd < 0)
  95. error("can't open %s", file);
  96. }
  97. y = readfile(fd, file, err);
  98. if(y < 0)
  99. error(err);
  100. sprint(tbuf, "%11d %11d %11d %11d %11d ", gray, 0, 0, Dots/(gray+1), y*yscale);
  101. write(1, tbuf, 5*12);
  102. n = (Dots/8)*y*yscale;
  103. /* write in pieces; brazil pipes work badly with huge counts */
  104. while(n > 0){
  105. if(yscale > 1) /* write one scan line */
  106. m = Dots/8;
  107. else{ /* write lots */
  108. m = n;
  109. if(m > 8192)
  110. m = 8192;
  111. }
  112. for(y=0; y<yscale; y++){
  113. if(write(1, t, m) != m)
  114. error("write error");
  115. n -= m;
  116. }
  117. t += m;
  118. }
  119. if(err[0])
  120. error(err);
  121. error(nil);
  122. }
  123. enum{
  124. Hvres,
  125. Hbaud,
  126. Hwidth,
  127. Hlength,
  128. Hcomp,
  129. HenabECM,
  130. HenabBFT,
  131. Hmsperscan,
  132. };
  133. int defhdr[8] = {
  134. 0, /* 98 lpi */
  135. 0, /* 2400 baud */
  136. 0, /* 1728 pixels in 215mm */
  137. 0, /* A4, 297mm */
  138. 0, /* 1-D modified huffman */
  139. 0, /* disable ECM */
  140. 0, /* disable BFT */
  141. 3, /* 10 ms per scan */
  142. };
  143. int
  144. crackhdr(uchar *ap, int *hdr)
  145. {
  146. char *p, *q;
  147. int i;
  148. p = (char*)ap;
  149. q = p;
  150. for(i=0; i<8; i++){
  151. if(*p<'0' || '9'<*p)
  152. return -1;
  153. hdr[i] = strtol(p, &q, 0);
  154. p = q+1;
  155. }
  156. return p-(char*)ap;
  157. }
  158. int
  159. readfile(int f, char *file, char *err)
  160. {
  161. int i, r, lines;
  162. uchar *rev;
  163. int hdr[8];
  164. err[0] = 0;
  165. memset(pixels, 0, (Dots/8) * Lines);
  166. nbytes = readn(f, buf, 1024*1024);
  167. if(nbytes==1024*1024 || nbytes<=100){
  168. bad:
  169. sprint(err, "g3: file improper size or format: %s", file);
  170. return -1;
  171. }
  172. bytes = buf;
  173. if(bytes[0]=='I' && bytes[1]=='I' && bytes[2]=='*'){ /* dumb PC format */
  174. bytes += 0xf3;
  175. nbytes -= 0xf3;
  176. rev = bitrev;
  177. memmove(hdr, defhdr, sizeof defhdr);
  178. }else if(bytes[0] == 0 && strcmp((char*)bytes+1, "PC Research, Inc") == 0){ /* digifax format */
  179. memmove(hdr, defhdr, sizeof defhdr);
  180. if(bytes[45] == 0x40 && bytes[29] == 1) /* high resolution */
  181. hdr[Hvres] = 1;
  182. else
  183. hdr[Hvres] = 0;
  184. /* hdr[26] | (hdr[27]<<8) is page number */
  185. bytes += 64;
  186. nbytes -= 64;
  187. rev = bitnonrev;
  188. }else{
  189. while(nbytes > 2){
  190. if(bytes[0]=='\n'){
  191. if(strncmp((char*)bytes+1, "FDCS=", 5) == 0){
  192. i = crackhdr(bytes+6, hdr);
  193. if(i < 0){
  194. sprint(err, "g3: bad FDCS in header: %s", file);
  195. return -1;
  196. }
  197. if(hdr[Hwidth] != 0){
  198. sprint(err, "g3: unsupported width: %s", file);
  199. return -1;
  200. }
  201. if(hdr[Hcomp] != 0){
  202. sprint(err, "g3: unsupported compression: %s", file);
  203. return -1;
  204. }
  205. bytes += i+1;
  206. nbytes -= i+1;
  207. continue;
  208. }
  209. if(bytes[1] == '\n'){
  210. bytes += 2;
  211. nbytes -= 2;
  212. break;
  213. }
  214. }
  215. bytes++;
  216. nbytes--;
  217. }
  218. if(nbytes < 2)
  219. goto bad;
  220. rev = bitnonrev;
  221. }
  222. bitoffset = 24;
  223. word24 = 0;
  224. sync(rev);
  225. lines = Lines;
  226. if(hdr[Hvres] == 1)
  227. lines *= 2;
  228. for(y=0; y<lines; y++){
  229. r = readrow(rev, hdr);
  230. if(r < 0)
  231. break;
  232. if(r == 0)
  233. sync(rev);
  234. }
  235. if(hdr[Hvres] == 1)
  236. y /= 2;
  237. // if(y < 100)
  238. // goto bad;
  239. return y;
  240. }
  241. int
  242. readrow(uchar *rev, int *hdr)
  243. {
  244. int bo, state;
  245. Tab *tab, *t;
  246. int x, oldx, x2, oldx2, dx, xx;
  247. uint w24;
  248. uchar *p, *q;
  249. state = White;
  250. oldx = 0;
  251. bo = bitoffset;
  252. w24 = word24;
  253. x = y;
  254. if(hdr[Hvres] == 1) /* high resolution */
  255. x /= 2;
  256. p = pixels + x*Dots/8;
  257. x = 0;
  258. loop:
  259. if(x > Dots)
  260. return 0;
  261. if(state == White)
  262. tab = wtab;
  263. else
  264. tab = btab;
  265. if(bo > (24-13)) {
  266. do {
  267. if(nbytes <= 0)
  268. return -1;
  269. w24 = (w24<<8) | rev[*bytes];
  270. bo -= 8;
  271. bytes++;
  272. nbytes--;
  273. } while(bo >= 8);
  274. }
  275. t = tab + ((w24 >> (24-13-bo)) & 8191);
  276. x += t->run;
  277. bo += t->bits;
  278. if(t->code == TERM){
  279. if(state == White)
  280. oldx = x;
  281. else{
  282. oldx2 = oldx;
  283. x2 = x;
  284. xx = oldx2&7;
  285. q = p+oldx2/8;
  286. if(x2/8 == oldx2/8) /* all in one byte, but if((x2&7)==0), do harder case */
  287. *q |= (0xFF>>xx) & (0xFF<<(8-(x2&7)));
  288. else{
  289. dx = x2 - oldx2;
  290. /* leading edge */
  291. if(xx){
  292. *q++ |= 0xFF>>xx;
  293. dx -= 8-xx;
  294. }
  295. /* middle */
  296. while(dx >= 8){
  297. *q++ = 0xFF;
  298. dx -= 8;
  299. }
  300. /* trailing edge */
  301. if(dx)
  302. *q |= 0xFF<<(8-dx);
  303. }
  304. }
  305. state ^= White^Black;
  306. goto loop;
  307. }
  308. if(t->code == ERR){
  309. bitoffset = bo;
  310. word24 = w24;
  311. return 0;
  312. }
  313. if(t->code == EOL){
  314. bitoffset = bo;
  315. word24 = w24;
  316. return 1;
  317. }
  318. goto loop;
  319. return 0;
  320. }
  321. void
  322. sync(uchar *rev)
  323. {
  324. Tab *t;
  325. int c;
  326. c = 0;
  327. loop:
  328. if(bitoffset > (24-13)) {
  329. do {
  330. if(nbytes <= 0)
  331. return;
  332. word24 = (word24<<8) | rev[*bytes];
  333. bitoffset -= 8;
  334. bytes++;
  335. nbytes--;
  336. } while(bitoffset >= 8);
  337. }
  338. t = wtab + ((word24 >> (24-13-bitoffset)) & 8191);
  339. if(t->code != EOL) {
  340. bitoffset++;
  341. c++;
  342. goto loop;
  343. }
  344. bitoffset += t->bits;
  345. }
  346. typedef struct File
  347. {
  348. char *val;
  349. int code;
  350. }File;
  351. File ibtab[] = {
  352. #include "btab"
  353. {nil, 0}
  354. };
  355. File iwtab[] = {
  356. #include "wtab"
  357. {nil, 0}
  358. };
  359. int
  360. binary(char *s)
  361. {
  362. int n;
  363. n = 0;
  364. while(*s)
  365. n = n*2 + *s++-'0';
  366. return n;
  367. }
  368. void
  369. tabinit(File *file, Tab *tab)
  370. {
  371. int i, j, v, r, l;
  372. char *b;
  373. for(v=0; v<8192; v++) {
  374. tab[v].run = 0;
  375. tab[v].bits = 1;
  376. tab[v].code = ERR;
  377. }
  378. for(i=0; b=file[i].val; i++){
  379. l = strlen(b);
  380. v = binary(b);
  381. r = file[i].code;
  382. if(l > 13)
  383. fprint(2, "g3: oops1 l = %d %s\n", l, b);
  384. v = v<<(13-l);
  385. for(j=0; j<(1<<((13-l))); j++) {
  386. if(tab[v].code != ERR)
  387. fprint(2, "g3: oops2 %d %s\n", r, b);
  388. tab[v].run = r;
  389. tab[v].bits = l;
  390. tab[v].code = TERM;
  391. if(r < 0) {
  392. tab[v].run = 0;
  393. tab[v].code = EOL;
  394. if(r < -1) {
  395. tab[v].bits = 1;
  396. tab[v].code = MAKE;
  397. }
  398. }
  399. if(r >= 64) {
  400. tab[v].code = MAKE;
  401. }
  402. v++;
  403. }
  404. }
  405. for(i=0; i<256; i++)
  406. for(j=0; j<8; j++)
  407. if(i & (1<<j))
  408. bitrev[i] |= 0x80 >> j;
  409. for(i=0; i<256; i++)
  410. bitnonrev[i] = i;
  411. }
  412. void
  413. initwbtab(void)
  414. {
  415. tabinit(iwtab, wtab);
  416. tabinit(ibtab, btab);
  417. }