PageRenderTime 47ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/appl/lib/readjpg.b

https://bitbucket.org/floren/inferno/
Brainfuck | 973 lines | 885 code | 88 blank | 0 comment | 67 complexity | 1a454a5e87f1da8d21170a805059b2ed MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, MPL-2.0-no-copyleft-exception
  1. implement RImagefile;
  2. include "sys.m";
  3. sys: Sys;
  4. include "draw.m";
  5. include "bufio.m";
  6. bufio: Bufio;
  7. Iobuf: import bufio;
  8. include "imagefile.m";
  9. # Constants, all preceded by byte 16rFF
  10. SOF: con byte 16rC0; # Start of Frame
  11. SOF2: con byte 16rC2; # Start of Frame; progressive Huffman
  12. JPG: con byte 16rC8; # Reserved for JPEG extensions
  13. DHT: con byte 16rC4; # Define Huffman Tables
  14. DAC: con byte 16rCC; # Arithmetic coding conditioning
  15. RST: con byte 16rD0; # Restart interval termination
  16. RST7: con byte 16rD7; # Restart interval termination (highest value)
  17. SOI: con byte 16rD8; # Start of Image
  18. EOI: con byte 16rD9; # End of Image
  19. SOS: con byte 16rDA; # Start of Scan
  20. DQT: con byte 16rDB; # Define quantization tables
  21. DNL: con byte 16rDC; # Define number of lines
  22. DRI: con byte 16rDD; # Define restart interval
  23. DHP: con byte 16rDE; # Define hierarchical progression
  24. EXP: con byte 16rDF; # Expand reference components
  25. APPn: con byte 16rE0; # Reserved for application segments
  26. JPGn: con byte 16rF0; # Reserved for JPEG extensions
  27. COM: con byte 16rFE; # Comment
  28. Header: adt
  29. {
  30. fd: ref Iobuf;
  31. ch: chan of (ref Rawimage, string);
  32. # variables in i/o routines
  33. sr: int; # shift register, right aligned
  34. cnt: int; # # bits in right part of sr
  35. buf: array of byte;
  36. bufi: int;
  37. nbuf: int;
  38. Nf: int;
  39. comp: array of Framecomp;
  40. mode: byte;
  41. X,Y: int;
  42. qt: array of array of int; # quantization tables
  43. dcht: array of ref Huffman;
  44. acht: array of ref Huffman;
  45. sf: array of byte; # start of frame; do better later
  46. ss: array of byte; # start of scan; do better later
  47. ri: int;
  48. };
  49. NBUF: con 16*1024;
  50. Huffman: adt
  51. {
  52. bits: array of int;
  53. size: array of int;
  54. code: array of int;
  55. val: array of int;
  56. mincode: array of int;
  57. maxcode: array of int;
  58. valptr: array of int;
  59. # fast lookup
  60. value: array of int;
  61. shift: array of int;
  62. };
  63. Framecomp: adt # Frame component specifier from SOF marker
  64. {
  65. C: int;
  66. H: int;
  67. V: int;
  68. Tq: int;
  69. };
  70. zerobytes: array of byte;
  71. zeroints: array of int;
  72. zeroreals: array of real;
  73. clamp: array of byte;
  74. NCLAMP: con 1000;
  75. CLAMPOFF: con 300;
  76. init(iomod: Bufio)
  77. {
  78. if(sys == nil)
  79. sys = load Sys Sys->PATH;
  80. bufio = iomod;
  81. zerobytes = array[8*8] of byte;
  82. zeroints = array[8*8] of int;
  83. zeroreals = array[8*8] of real;
  84. for(k:=0; k<8*8; k++){
  85. zerobytes[k] = byte 0;
  86. zeroints[k] = 0;
  87. zeroreals[k] = 0.0;
  88. }
  89. clamp = array[NCLAMP] of byte;
  90. for(k=0; k<CLAMPOFF; k++)
  91. clamp[k] = byte 0;
  92. for(; k<CLAMPOFF+256; k++)
  93. clamp[k] = byte(k-CLAMPOFF);
  94. for(; k<NCLAMP; k++)
  95. clamp[k] = byte 255;
  96. }
  97. read(fd: ref Iobuf): (ref Rawimage, string)
  98. {
  99. # spawn a subprocess so I/O errors can clean up easily
  100. ch := chan of (ref Rawimage, string);
  101. spawn readslave(fd, ch);
  102. return <-ch;
  103. }
  104. readmulti(fd: ref Iobuf): (array of ref Rawimage, string)
  105. {
  106. (i, err) := read(fd);
  107. if(i != nil){
  108. a := array[1] of { i };
  109. return (a, err);
  110. }
  111. return (nil, err);
  112. }
  113. readslave(fd: ref Iobuf, ch: chan of (ref Rawimage, string))
  114. {
  115. image: ref Rawimage;
  116. (header, err) := soiheader(fd, ch);
  117. if(header == nil){
  118. ch <-= (nil, err);
  119. exit;
  120. }
  121. buf := header.buf;
  122. nseg := 0;
  123. Loop:
  124. while(err == ""){
  125. m: int;
  126. b: array of byte;
  127. nseg++;
  128. (m, b, err) = readsegment(header);
  129. case m{
  130. -1 =>
  131. break Loop;
  132. int APPn+0 =>
  133. if(nseg==1 && string b[0:4]=="JFIF"){ # JFIF header; check version
  134. vers0 := int b[5];
  135. vers1 := int b[6];
  136. if(vers0>1 || vers1>2)
  137. err = sys->sprint("ReadJPG: can't handle JFIF version %d.%2d", vers0, vers1);
  138. }
  139. int APPn+1 to int APPn+15 =>
  140. ;
  141. int DQT =>
  142. err = quanttables(header, b);
  143. int SOF =>
  144. header.Y = int2(b, 1);
  145. header.X = int2(b, 3);
  146. header.Nf = int b[5];
  147. header.comp = array[header.Nf] of Framecomp;
  148. for(i:=0; i<header.Nf; i++){
  149. header.comp[i].C = int b[6+3*i+0];
  150. (H, V) := nibbles(b[6+3*i+1]);
  151. header.comp[i].H = H;
  152. header.comp[i].V = V;
  153. header.comp[i].Tq = int b[6+3*i+2];
  154. }
  155. header.mode = SOF;
  156. header.sf = b;
  157. int SOF2 =>
  158. err = sys->sprint("ReadJPG: can't handle progressive Huffman mode");
  159. break Loop;
  160. int SOS =>
  161. header.ss = b;
  162. (image, err) = decodescan(header);
  163. if(err != "")
  164. break Loop;
  165. # BUG: THIS SHOULD USE THE LOOP TO FINISH UP
  166. x := nextbyte(header, 1);
  167. if(x != 16rFF)
  168. err = sys->sprint("ReadJPG: didn't see marker at end of scan; saw %x", x);
  169. else{
  170. x = nextbyte(header, 1);
  171. if(x != int EOI)
  172. err = sys->sprint("ReadJPG: expected EOI saw %x", x);
  173. }
  174. break Loop;
  175. int DHT =>
  176. err = huffmantables(header, b);
  177. int DRI =>
  178. header.ri = int2(b, 0);
  179. int COM =>
  180. ;
  181. int EOI =>
  182. break Loop;
  183. * =>
  184. err = sys->sprint("ReadJPG: unknown marker %.2x", m);
  185. }
  186. }
  187. ch <-= (image, err);
  188. }
  189. readerror(): string
  190. {
  191. return sys->sprint("ReadJPG: read error: %r");
  192. }
  193. marker(buf: array of byte, n: int): byte
  194. {
  195. if(buf[n] != byte 16rFF)
  196. return byte 0;
  197. return buf[n+1];
  198. }
  199. int2(buf: array of byte, n: int): int
  200. {
  201. return (int buf[n]<<8)+(int buf[n+1]);
  202. }
  203. nibbles(b: byte): (int, int)
  204. {
  205. i := int b;
  206. return (i>>4, i&15);
  207. }
  208. soiheader(fd: ref Iobuf, ch: chan of (ref Rawimage, string)): (ref Header, string)
  209. {
  210. # 1+ for restart preamble (see nextbyte), +1 for sentinel
  211. buf := array[1+NBUF+1] of byte;
  212. if(fd.read(buf, 2) != 2)
  213. return (nil, sys->sprint("ReadJPG: can't read header: %r"));
  214. if(marker(buf, 0) != SOI)
  215. return (nil, sys->sprint("ReadJPG: unrecognized marker in header"));
  216. h := ref Header;
  217. h.buf = buf;
  218. h.bufi = 0;
  219. h.nbuf = 0;
  220. h.fd = fd;
  221. h.ri = 0;
  222. h.ch = ch;
  223. return (h, nil);
  224. }
  225. readsegment(h: ref Header): (int, array of byte, string)
  226. {
  227. if(h.fd.read(h.buf, 2) != 2)
  228. return (-1, nil, readerror());
  229. m := int marker(h.buf, 0);
  230. case m{
  231. int EOI =>
  232. return (m, nil, nil);
  233. 0 =>
  234. err := sys->sprint("ReadJPG: expecting marker; saw %.2x%.2x)",
  235. int h.buf[0], int h.buf[1]);
  236. return (-1, nil, err);
  237. }
  238. if(h.fd.read(h.buf, 2) != 2)
  239. return (-1, nil, readerror());
  240. n := int2(h.buf, 0);
  241. if(n < 2)
  242. return (-1, nil, readerror());
  243. n -= 2;
  244. # if(n > len h.buf){
  245. # h.buf = array[n+1] of byte; # +1 for sentinel
  246. # #h.nbuf = n;
  247. # }
  248. b := array[n] of byte;
  249. if(h.fd.read(b, n) != n)
  250. return (-1, nil, readerror());
  251. return (m, b, nil);
  252. }
  253. huffmantables(h: ref Header, b: array of byte): string
  254. {
  255. if(h.dcht == nil){
  256. h.dcht = array[4] of ref Huffman;
  257. h.acht = array[4] of ref Huffman;
  258. }
  259. err: string;
  260. mt: int;
  261. for(l:=0; l<len b; l+=17+mt){
  262. (mt, err) = huffmantable(h, b[l:]);
  263. if(err != nil)
  264. return err;
  265. }
  266. return nil;
  267. }
  268. huffmantable(h: ref Header, b: array of byte): (int, string)
  269. {
  270. t := ref Huffman;
  271. (Tc, th) := nibbles(b[0]);
  272. if(Tc > 1)
  273. return (0, sys->sprint("ReadJPG: unknown Huffman table class %d", Tc));
  274. if(th>3 || (h.mode==SOF && th>1))
  275. return (0, sys->sprint("ReadJPG: unknown Huffman table index %d", th));
  276. if(Tc == 0)
  277. h.dcht[th] = t;
  278. else
  279. h.acht[th] = t;
  280. # flow chart C-2
  281. nsize := 0;
  282. for(i:=0; i<16; i++)
  283. nsize += int b[1+i];
  284. t.size = array[nsize+1] of int;
  285. k := 0;
  286. for(i=1; i<=16; i++){
  287. n := int b[i];
  288. for(j:=0; j<n; j++)
  289. t.size[k++] = i;
  290. }
  291. t.size[k] = 0;
  292. # initialize HUFFVAL
  293. t.val = array[nsize] of int;
  294. for(i=0; i<nsize; i++){
  295. t.val[i] = int b[17+i];
  296. }
  297. # flow chart C-3
  298. t.code = array[nsize+1] of int;
  299. k = 0;
  300. code := 0;
  301. si := t.size[0];
  302. for(;;){
  303. do
  304. t.code[k++] = code++;
  305. while(t.size[k] == si);
  306. if(t.size[k] == 0)
  307. break;
  308. do{
  309. code <<= 1;
  310. si++;
  311. }while(t.size[k] != si);
  312. }
  313. # flow chart F-25
  314. t.mincode = array[17] of int;
  315. t.maxcode = array[17] of int;
  316. t.valptr = array[17] of int;
  317. i = 0;
  318. j := 0;
  319. F25:
  320. for(;;){
  321. for(;;){
  322. i++;
  323. if(i > 16)
  324. break F25;
  325. if(int b[i] != 0)
  326. break;
  327. t.maxcode[i] = -1;
  328. }
  329. t.valptr[i] = j;
  330. t.mincode[i] = t.code[j];
  331. j += int b[i]-1;
  332. t.maxcode[i] = t.code[j];
  333. j++;
  334. }
  335. # create byte-indexed fast path tables
  336. t.value = array[256] of int;
  337. t.shift = array[256] of int;
  338. maxcode := t.maxcode;
  339. # stupid startup algorithm: just run machine for each byte value
  340. Bytes:
  341. for(v:=0; v<256; v++){
  342. cnt := 7;
  343. m := 1<<7;
  344. code = 0;
  345. sr := v;
  346. i = 1;
  347. for(;;i++){
  348. if(sr & m)
  349. code |= 1;
  350. if(code <= maxcode[i])
  351. break;
  352. code <<= 1;
  353. m >>= 1;
  354. if(m == 0){
  355. t.shift[v] = 0;
  356. t.value[v] = -1;
  357. continue Bytes;
  358. }
  359. cnt--;
  360. }
  361. t.shift[v] = 8-cnt;
  362. t.value[v] = t.val[t.valptr[i]+(code-t.mincode[i])];
  363. }
  364. return (nsize, nil);
  365. }
  366. quanttables(h: ref Header, b: array of byte): string
  367. {
  368. if(h.qt == nil)
  369. h.qt = array[4] of array of int;
  370. err: string;
  371. n: int;
  372. for(l:=0; l<len b; l+=1+n){
  373. (n, err) = quanttable(h, b[l:]);
  374. if(err != nil)
  375. return err;
  376. }
  377. return nil;
  378. }
  379. quanttable(h: ref Header, b: array of byte): (int, string)
  380. {
  381. (pq, tq) := nibbles(b[0]);
  382. if(pq > 1)
  383. return (0, sys->sprint("ReadJPG: unknown quantization table class %d", pq));
  384. if(tq > 3)
  385. return (0, sys->sprint("ReadJPG: unknown quantization table index %d", tq));
  386. q := array[64] of int;
  387. h.qt[tq] = q;
  388. for(i:=0; i<64; i++){
  389. if(pq == 0)
  390. q[i] = int b[1+i];
  391. else
  392. q[i] = int2(b, 1+2*i);
  393. }
  394. return (64*(1+pq), nil);
  395. }
  396. zig := array[64] of {
  397. 0, 1, 8, 16, 9, 2, 3, 10, 17, # 0-7
  398. 24, 32, 25, 18, 11, 4, 5, # 8-15
  399. 12, 19, 26, 33, 40, 48, 41, 34, # 16-23
  400. 27, 20, 13, 6, 7, 14, 21, 28, # 24-31
  401. 35, 42, 49, 56, 57, 50, 43, 36, # 32-39
  402. 29, 22, 15, 23, 30, 37, 44, 51, # 40-47
  403. 58, 59, 52, 45, 38, 31, 39, 46, # 48-55
  404. 53, 60, 61, 54, 47, 55, 62, 63 # 56-63
  405. };
  406. decodescan(h: ref Header): (ref Rawimage, string)
  407. {
  408. ss := h.ss;
  409. Ns := int ss[0];
  410. if((Ns!=3 && Ns!=1) || Ns!=h.Nf)
  411. return (nil, "ReadJPG: can't handle scan not 3 components");
  412. image := ref Rawimage;
  413. image.r = ((0, 0), (h.X, h.Y));
  414. image.cmap = nil;
  415. image.transp = 0;
  416. image.trindex = byte 0;
  417. image.fields = 0;
  418. image.chans = array[h.Nf] of array of byte;
  419. if(Ns == 3)
  420. image.chandesc = CRGB;
  421. else
  422. image.chandesc = CY;
  423. image.nchans = h.Nf;
  424. for(k:=0; k<h.Nf; k++)
  425. image.chans[k] = array[h.X*h.Y] of byte;
  426. # build per-component arrays
  427. Td := array[Ns] of int;
  428. Ta := array[Ns] of int;
  429. data := array[Ns] of array of array of real;
  430. H := array[Ns] of int;
  431. V := array[Ns] of int;
  432. DC := array[Ns] of int;
  433. # compute maximum H and V
  434. Hmax := 0;
  435. Vmax := 0;
  436. for(comp:=0; comp<Ns; comp++){
  437. if(h.comp[comp].H > Hmax)
  438. Hmax = h.comp[comp].H;
  439. if(h.comp[comp].V > Vmax)
  440. Vmax = h.comp[comp].V;
  441. }
  442. # initialize data structures
  443. allHV1 := 1;
  444. for(comp=0; comp<Ns; comp++){
  445. # JPEG requires scan components to be in same order as in frame,
  446. # so if both have 3 we know scan is Y Cb Cr and there's no need to
  447. # reorder
  448. cs := int ss[1+2*comp];
  449. (Td[comp], Ta[comp]) = nibbles(ss[2+2*comp]);
  450. H[comp] = h.comp[comp].H;
  451. V[comp] = h.comp[comp].V;
  452. nblock := H[comp]*V[comp];
  453. if(nblock != 1)
  454. allHV1 = 0;
  455. data[comp] = array[nblock] of array of real;
  456. DC[comp] = 0;
  457. for(m:=0; m<nblock; m++)
  458. data[comp][m] = array[8*8] of real;
  459. }
  460. ri := h.ri;
  461. h.buf[0] = byte 16rFF; # see nextbyte()
  462. h.cnt = 0;
  463. h.sr = 0;
  464. nacross := ((h.X+(8*Hmax-1))/(8*Hmax));
  465. nmcu := ((h.Y+(8*Vmax-1))/(8*Vmax))*nacross;
  466. zz := array[64] of real;
  467. err := "";
  468. for(mcu:=0; mcu<nmcu; ){
  469. for(comp=0; comp<Ns; comp++){
  470. dcht := h.dcht[Td[comp]];
  471. acht := h.acht[Ta[comp]];
  472. qt := h.qt[h.comp[comp].Tq];
  473. for(block:=0; block<H[comp]*V[comp]; block++){
  474. # F-22
  475. t := decode(h, dcht);
  476. diff := receive(h, t);
  477. DC[comp] += diff;
  478. # F-23
  479. zz[0:] = zeroreals;
  480. zz[0] = real (qt[0]*DC[comp]);
  481. k = 1;
  482. for(;;){
  483. rs := decode(h, acht);
  484. (rrrr, ssss) := nibbles(byte rs);
  485. if(ssss == 0){
  486. if(rrrr != 15)
  487. break;
  488. k += 16;
  489. }else{
  490. k += rrrr;
  491. z := receive(h, ssss);
  492. zz[zig[k]] = real (z*qt[k]);
  493. if(k == 63)
  494. break;
  495. k++;
  496. }
  497. }
  498. idct(zz, data[comp][block]);
  499. }
  500. }
  501. # rotate colors to RGB and assign to bytes
  502. if(Ns == 1) # very easy
  503. colormap1(h, image, data[0][0], mcu, nacross);
  504. else if(allHV1) # fairly easy
  505. colormapall1(h, image, data[0][0], data[1][0], data[2][0], mcu, nacross);
  506. else # miserable general case
  507. colormap(h, image, data[0], data[1], data[2], mcu, nacross, Hmax, Vmax, H, V);
  508. # process restart marker, if present
  509. mcu++;
  510. if(ri>0 && mcu<nmcu-1 && mcu%ri==0){
  511. restart := mcu/ri-1;
  512. rst, nskip: int;
  513. nskip = 0;
  514. do{
  515. do{
  516. rst = nextbyte(h, 1);
  517. nskip++;
  518. }while(rst>=0 && rst!=16rFF);
  519. if(rst == 16rFF){
  520. rst = nextbyte(h, 1);
  521. nskip++;
  522. }
  523. }while(rst>=0 && (rst&~7)!=int RST);
  524. if(nskip != 2)
  525. err = sys->sprint("skipped %d bytes at restart %d\n", nskip-2, restart);
  526. if(rst < 0)
  527. return (nil, readerror());
  528. if((rst&7) != (restart&7))
  529. return (nil, sys->sprint("ReadJPG: expected RST%d got %d", restart&7, int rst&7));
  530. h.cnt = 0;
  531. h.sr = 0;
  532. for(comp=0; comp<Ns; comp++)
  533. DC[comp] = 0;
  534. }
  535. }
  536. return (image, err);
  537. }
  538. colormap1(h: ref Header, image: ref Rawimage, data: array of real, mcu, nacross: int)
  539. {
  540. pic := image.chans[0];
  541. minx := 8*(mcu%nacross);
  542. dx := 8;
  543. if(minx+dx > h.X)
  544. dx = h.X-minx;
  545. miny := 8*(mcu/nacross);
  546. dy := 8;
  547. if(miny+dy > h.Y)
  548. dy = h.Y-miny;
  549. pici := miny*h.X+minx;
  550. k := 0;
  551. for(y:=0; y<dy; y++){
  552. for(x:=0; x<dx; x++){
  553. r := clamp[int (data[k+x]+128.)+CLAMPOFF];
  554. pic[pici+x] = r;
  555. }
  556. pici += h.X;
  557. k += 8;
  558. }
  559. }
  560. colormapall1(h: ref Header, image: ref Rawimage, data0, data1, data2: array of real, mcu, nacross: int)
  561. {
  562. rpic := image.chans[0];
  563. gpic := image.chans[1];
  564. bpic := image.chans[2];
  565. minx := 8*(mcu%nacross);
  566. dx := 8;
  567. if(minx+dx > h.X)
  568. dx = h.X-minx;
  569. miny := 8*(mcu/nacross);
  570. dy := 8;
  571. if(miny+dy > h.Y)
  572. dy = h.Y-miny;
  573. pici := miny*h.X+minx;
  574. k := 0;
  575. for(y:=0; y<dy; y++){
  576. for(x:=0; x<dx; x++){
  577. Y := data0[k+x]+128.;
  578. Cb := data1[k+x];
  579. Cr := data2[k+x];
  580. r := int (Y+1.402*Cr);
  581. g := int (Y-0.34414*Cb-0.71414*Cr);
  582. b := int (Y+1.772*Cb);
  583. rpic[pici+x] = clamp[r+CLAMPOFF];
  584. gpic[pici+x] = clamp[g+CLAMPOFF];
  585. bpic[pici+x] = clamp[b+CLAMPOFF];
  586. }
  587. pici += h.X;
  588. k += 8;
  589. }
  590. }
  591. colormap(h: ref Header, image: ref Rawimage, data0, data1, data2: array of array of real, mcu, nacross, Hmax, Vmax: int, H, V: array of int)
  592. {
  593. rpic := image.chans[0];
  594. gpic := image.chans[1];
  595. bpic := image.chans[2];
  596. minx := 8*Hmax*(mcu%nacross);
  597. dx := 8*Hmax;
  598. if(minx+dx > h.X)
  599. dx = h.X-minx;
  600. miny := 8*Vmax*(mcu/nacross);
  601. dy := 8*Vmax;
  602. if(miny+dy > h.Y)
  603. dy = h.Y-miny;
  604. pici := miny*h.X+minx;
  605. H0 := H[0];
  606. H1 := H[1];
  607. H2 := H[2];
  608. for(y:=0; y<dy; y++){
  609. t := y*V[0];
  610. b0 := H0*(t/(8*Vmax));
  611. y0 := 8*((t/Vmax)&7);
  612. t = y*V[1];
  613. b1 := H1*(t/(8*Vmax));
  614. y1 := 8*((t/Vmax)&7);
  615. t = y*V[2];
  616. b2 := H2*(t/(8*Vmax));
  617. y2 := 8*((t/Vmax)&7);
  618. x0 := 0;
  619. x1 := 0;
  620. x2 := 0;
  621. for(x:=0; x<dx; x++){
  622. Y := data0[b0][y0+x0++*H0/Hmax]+128.;
  623. Cb := data1[b1][y1+x1++*H1/Hmax];
  624. Cr := data2[b2][y2+x2++*H2/Hmax];
  625. if(x0*H0/Hmax >= 8){
  626. x0 = 0;
  627. b0++;
  628. }
  629. if(x1*H1/Hmax >= 8){
  630. x1 = 0;
  631. b1++;
  632. }
  633. if(x2*H2/Hmax >= 8){
  634. x2 = 0;
  635. b2++;
  636. }
  637. r := int (Y+1.402*Cr);
  638. g := int (Y-0.34414*Cb-0.71414*Cr);
  639. b := int (Y+1.772*Cb);
  640. rpic[pici+x] = clamp[r+CLAMPOFF];
  641. gpic[pici+x] = clamp[g+CLAMPOFF];
  642. bpic[pici+x] = clamp[b+CLAMPOFF];
  643. }
  644. pici += h.X;
  645. }
  646. }
  647. # decode next 8-bit value from entropy-coded input. chart F-26
  648. decode(h: ref Header, t: ref Huffman): int
  649. {
  650. maxcode := t.maxcode;
  651. if(h.cnt < 8)
  652. nextbyte(h, 0);
  653. # fast lookup
  654. code := (h.sr>>(h.cnt-8))&16rFF;
  655. v := t.value[code];
  656. if(v >= 0){
  657. h.cnt -= t.shift[code];
  658. return v;
  659. }
  660. h.cnt -= 8;
  661. if(h.cnt == 0)
  662. nextbyte(h, 0);
  663. h.cnt--;
  664. cnt := h.cnt;
  665. m := 1<<cnt;
  666. sr := h.sr;
  667. code <<= 1;
  668. i := 9;
  669. for(;;i++){
  670. if(sr & m)
  671. code |= 1;
  672. if(code <= maxcode[i])
  673. break;
  674. code <<= 1;
  675. m >>= 1;
  676. if(m == 0){
  677. sr = nextbyte(h, 0);
  678. m = 16r80;
  679. cnt = 8;
  680. }
  681. cnt--;
  682. }
  683. h.cnt = cnt;
  684. return t.val[t.valptr[i]+(code-t.mincode[i])];
  685. }
  686. #
  687. # load next byte of input
  688. # we should really just call h.fd.getb(), but it's faster just to use Bufio
  689. # to load big chunks and manage our own byte-at-a-time input.
  690. #
  691. nextbyte(h: ref Header, marker: int): int
  692. {
  693. b := int h.buf[h.bufi++];
  694. if(b == 16rFF){
  695. # check for sentinel at end of buffer
  696. if(h.bufi >= h.nbuf){
  697. underflow := (h.bufi > h.nbuf);
  698. h.nbuf = h.fd.read(h.buf, NBUF);
  699. if(h.nbuf <= 0){
  700. h.ch <-= (nil, readerror());
  701. exit;
  702. }
  703. h.buf[h.nbuf] = byte 16rFF;
  704. h.bufi = 0;
  705. if(underflow) # if ran off end of buffer, just restart
  706. return nextbyte(h, marker);
  707. }
  708. if(marker)
  709. return b;
  710. b2 := h.buf[h.bufi++];
  711. if(b2 != byte 0){
  712. if(b2 == DNL){
  713. h.ch <-= (nil, "ReadJPG: DNL marker unimplemented");
  714. exit;
  715. }else if(b2<RST && RST7<b2){
  716. h.ch <-= (nil, sys->sprint("ReadJPG: unrecognized marker %x", int b2));
  717. exit;
  718. }
  719. # decode is reading into restart marker; satisfy it and restore state
  720. if(h.bufi < 2){
  721. # misery: must shift up buffer
  722. h.buf[1:] = h.buf[0:h.nbuf+1];
  723. h.nbuf++;
  724. h.buf[0] = byte 16rFF;
  725. h.bufi -= 1;
  726. }else
  727. h.bufi -= 2;
  728. b = 16rFF;
  729. }
  730. }
  731. h.cnt += 8;
  732. h.sr = (h.sr<<8)|b;
  733. return b;
  734. }
  735. # return next s bits of input, MSB first, and level shift it
  736. receive(h: ref Header, s: int): int
  737. {
  738. while(h.cnt < s)
  739. nextbyte(h, 0);
  740. v := h.sr >> (h.cnt-s);
  741. m := (1<<s);
  742. v &= m-1;
  743. h.cnt -= s;
  744. # level shift
  745. if(v < (m>>1))
  746. v += ~(m-1)+1;
  747. return v;
  748. }
  749. # IDCT based on Arai, Agui, and Nakajima, using flow chart Figure 4.8
  750. # of Pennebaker & Mitchell, JPEG: Still Image Data Compression Standard.
  751. # Remember IDCT is reverse of flow of DCT.
  752. a0: con 1.414;
  753. a1: con 0.707;
  754. a2: con 0.541;
  755. a3: con 0.707;
  756. a4: con 1.307;
  757. a5: con -0.383;
  758. # scaling factors from eqn 4-35 of P&M
  759. s1: con 1.0196;
  760. s2: con 1.0823;
  761. s3: con 1.2026;
  762. s4: con 1.4142;
  763. s5: con 1.8000;
  764. s6: con 2.6131;
  765. s7: con 5.1258;
  766. # overall normalization of 1/16, folded into premultiplication on vertical pass
  767. scale: con 0.0625;
  768. idct(zin: array of real, zout: array of real)
  769. {
  770. x, y: int;
  771. r := array[8*8] of real;
  772. # transform horizontally
  773. for(y=0; y<8; y++){
  774. eighty := y<<3;
  775. # if all non-DC components are zero, just propagate the DC term
  776. if(zin[eighty+1]==0.)
  777. if(zin[eighty+2]==0. && zin[eighty+3]==0.)
  778. if(zin[eighty+4]==0. && zin[eighty+5]==0.)
  779. if(zin[eighty+6]==0. && zin[eighty+7]==0.){
  780. v := zin[eighty]*a0;
  781. r[eighty+0] = v;
  782. r[eighty+1] = v;
  783. r[eighty+2] = v;
  784. r[eighty+3] = v;
  785. r[eighty+4] = v;
  786. r[eighty+5] = v;
  787. r[eighty+6] = v;
  788. r[eighty+7] = v;
  789. continue;
  790. }
  791. # step 5
  792. in1 := s1*zin[eighty+1];
  793. in3 := s3*zin[eighty+3];
  794. in5 := s5*zin[eighty+5];
  795. in7 := s7*zin[eighty+7];
  796. f2 := s2*zin[eighty+2];
  797. f3 := s6*zin[eighty+6];
  798. f5 := (in1+in7);
  799. f7 := (in5+in3);
  800. # step 4
  801. g2 := f2-f3;
  802. g4 := (in5-in3);
  803. g6 := (in1-in7);
  804. g7 := f5+f7;
  805. # step 3.5
  806. t := (g4+g6)*a5;
  807. # step 3
  808. f0 := a0*zin[eighty+0];
  809. f1 := s4*zin[eighty+4];
  810. f3 += f2;
  811. f2 = a1*g2;
  812. # step 2
  813. g0 := f0+f1;
  814. g1 := f0-f1;
  815. g3 := f2+f3;
  816. g4 = t-a2*g4;
  817. g5 := a3*(f5-f7);
  818. g6 = a4*g6+t;
  819. # step 1
  820. f0 = g0+g3;
  821. f1 = g1+f2;
  822. f2 = g1-f2;
  823. f3 = g0-g3;
  824. f5 = g5-g4;
  825. f6 := g5+g6;
  826. f7 = g6+g7;
  827. # step 6
  828. r[eighty+0] = (f0+f7);
  829. r[eighty+1] = (f1+f6);
  830. r[eighty+2] = (f2+f5);
  831. r[eighty+3] = (f3-g4);
  832. r[eighty+4] = (f3+g4);
  833. r[eighty+5] = (f2-f5);
  834. r[eighty+6] = (f1-f6);
  835. r[eighty+7] = (f0-f7);
  836. }
  837. # transform vertically
  838. for(x=0; x<8; x++){
  839. # step 5
  840. in1 := scale*s1*r[x+8];
  841. in3 := scale*s3*r[x+24];
  842. in5 := scale*s5*r[x+40];
  843. in7 := scale*s7*r[x+56];
  844. f2 := scale*s2*r[x+16];
  845. f3 := scale*s6*r[x+48];
  846. f5 := (in1+in7);
  847. f7 := (in5+in3);
  848. # step 4
  849. g2 := f2-f3;
  850. g4 := (in5-in3);
  851. g6 := (in1-in7);
  852. g7 := f5+f7;
  853. # step 3.5
  854. t := (g4+g6)*a5;
  855. # step 3
  856. f0 := scale*a0*r[x];
  857. f1 := scale*s4*r[x+32];
  858. f3 += f2;
  859. f2 = a1*g2;
  860. # step 2
  861. g0 := f0+f1;
  862. g1 := f0-f1;
  863. g3 := f2+f3;
  864. g4 = t-a2*g4;
  865. g5 := a3*(f5-f7);
  866. g6 = a4*g6+t;
  867. # step 1
  868. f0 = g0+g3;
  869. f1 = g1+f2;
  870. f2 = g1-f2;
  871. f3 = g0-g3;
  872. f5 = g5-g4;
  873. f6 := g5+g6;
  874. f7 = g6+g7;
  875. # step 6
  876. zout[x] = (f0+f7);
  877. zout[x+8] = (f1+f6);
  878. zout[x+16] = (f2+f5);
  879. zout[x+24] = (f3-g4);
  880. zout[x+32] = (f3+g4);
  881. zout[x+40] = (f2-f5);
  882. zout[x+48] = (f1-f6);
  883. zout[x+56] = (f0-f7);
  884. }
  885. }