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

/appl/grid/readjpg.b

https://bitbucket.org/floren/inferno/
Brainfuck | 1146 lines | 1055 code | 91 blank | 0 comment | 668 complexity | 244384a0207bbc88e4fcedb96e407465 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, MPL-2.0-no-copyleft-exception
  1. implement Readjpg;
  2. include "sys.m";
  3. sys: Sys;
  4. include "draw.m";
  5. draw: Draw;
  6. Display, Image: import draw;
  7. include "grid/readjpg.m";
  8. display: ref Display;
  9. slowread: int;
  10. zeroints := array[64] of { * => 0 };
  11. init(disp: ref Draw->Display)
  12. {
  13. sys = load Sys Sys->PATH;
  14. draw = load Draw Draw->PATH;
  15. display = disp;
  16. init_tabs();
  17. }
  18. fjpg2img(fd: ref sys->FD, cachepath: string, chanin, chanout: chan of string): ref Image
  19. {
  20. if (fd == nil) return nil;
  21. sync := chan of int;
  22. imgchan := chan of ref Image;
  23. is := newImageSource(0,0);
  24. spawn slowreads(is,fd,cachepath, sync, chanout);
  25. srpid := <- sync;
  26. if (srpid == -1) return nil;
  27. spawn getjpegimg(is, chanout, imgchan, sync);
  28. gjipid := <- sync;
  29. for (;;) alt {
  30. ctl := <- chanin =>
  31. if (ctl == "kill") {
  32. if (srpid != -1) kill(srpid);
  33. kill(gjipid);
  34. return nil;
  35. }
  36. img := <- imgchan =>
  37. if (srpid != -1) kill(srpid);
  38. return img;
  39. err := <- sync =>
  40. if (err == 0) srpid = -1;
  41. else {
  42. kill(gjipid);
  43. return nil;
  44. }
  45. }
  46. }
  47. jpg2img(filename, cachepath: string, chanin, chanout: chan of string): ref Image
  48. {
  49. fd := sys->open(filename, sys->OREAD);
  50. return fjpg2img(fd, cachepath, chanin, chanout);
  51. }
  52. kill(pid: int)
  53. {
  54. pctl := sys->open("/prog/" + string pid + "/ctl", Sys->OWRITE);
  55. if (pctl != nil)
  56. sys->write(pctl, array of byte "kill", len "kill");
  57. }
  58. filelength(fd : ref sys->FD): int
  59. {
  60. (n, dir) := sys->fstat(fd);
  61. if (n == -1) return -1;
  62. filelen := int dir.length;
  63. return filelen;
  64. }
  65. slowreads(is: ref ImageSource, fd : ref sys->FD, cachepath: string, sync: chan of int, chanout: chan of string)
  66. {
  67. filelen := filelength(fd);
  68. if (filelen < 1) {
  69. sync <-= -1;
  70. return;
  71. }
  72. is.data = array[filelen] of byte;
  73. slowread = 0;
  74. sync <-= sys->pctl(0, nil);
  75. cachefd : ref sys->FD = nil;
  76. if (cachepath != "") cachefd = sys->create(cachepath, sys->OWRITE, 8r666);
  77. if (chanout != nil) {
  78. chanout <-= "l2 Loading...";
  79. chanout <-= "pc 0";
  80. }
  81. i : int;
  82. for (;;) {
  83. i = sys->read(fd,is.data[slowread:], 8192);
  84. if (i < 1) break;
  85. if (cachefd != nil)
  86. sys->write(cachefd, is.data[slowread:],i);
  87. slowread += i;
  88. if (chanout != nil)
  89. chanout <-= "pc "+string ((slowread*100)/filelen);
  90. sys->sleep(0);
  91. }
  92. if (i == -1 || slowread == 0) {
  93. sync <-= -1;
  94. return;
  95. }
  96. newdata := array[slowread] of byte;
  97. newdata = is.data[:slowread];
  98. is.data = newdata;
  99. if (cachepath != "" && slowread < filelen)
  100. sys->remove(cachepath);
  101. sync <-= 0;
  102. }
  103. wait4data(n: int)
  104. {
  105. for(;;) {
  106. if (slowread > n) break;
  107. sys->sleep(100);
  108. }
  109. }
  110. newImageSource(w, h: int) : ref ImageSource
  111. {
  112. is := ref ImageSource(
  113. w,h, # width, height
  114. 0,0, # origw, origh
  115. 0, # i
  116. nil, # jhdr
  117. nil # data
  118. );
  119. return is;
  120. }
  121. getjpeghdr(is: ref ImageSource)
  122. {
  123. h := ref Jpegstate(
  124. 0, 0, # sr, cnt
  125. 0, # Nf
  126. nil, # comp
  127. byte 0, # mode,
  128. 0, 0, # X, Y
  129. nil, # qt
  130. nil, nil, # dcht, acht
  131. 0, # Ns
  132. nil, # scomp
  133. 0, 0, # Ss, Se
  134. 0, 0, # Ah, Al
  135. 0, 0, # ri, nseg
  136. nil, # nblock
  137. nil, nil, # dccoeff, accoeff
  138. 0, 0, 0, 0 # nacross, ndown, Hmax, Vmax
  139. );
  140. is.jstate = h;
  141. if(jpegmarker(is) != SOI)
  142. sys->print("Error: Jpeg expected SOI marker\n");
  143. (m, n) := jpegtabmisc(is);
  144. if(!(m == SOF || m == SOF2))
  145. sys->print("Error: Jpeg expected Frame marker");
  146. nil = getc(is); # sample precision
  147. h.Y = getbew(is);
  148. h.X = getbew(is);
  149. h.Nf = getc(is);
  150. h.comp = array[h.Nf] of Framecomp;
  151. h.nblock = array[h.Nf] of int;
  152. for(i:=0; i<h.Nf; i++) {
  153. h.comp[i].C = getc(is);
  154. (H, V) := nibbles(getc(is));
  155. h.comp[i].H = H;
  156. h.comp[i].V = V;
  157. h.comp[i].Tq = getc(is);
  158. h.nblock[i] =H*V;
  159. }
  160. h.mode = byte m;
  161. is.origw = h.X;
  162. is.origh = h.Y;
  163. setdims(is);
  164. if(n != 6+3*h.Nf)
  165. sys->print("Error: Jpeg bad SOF length");
  166. }
  167. setdims(is: ref ImageSource)
  168. {
  169. sw := is.origw;
  170. sh := is.origh;
  171. dw := is.width;
  172. dh := is.height;
  173. if(dw == 0 && dh == 0) {
  174. dw = sw;
  175. dh = sh;
  176. }
  177. else if(dw == 0 || dh == 0) {
  178. if(dw == 0) {
  179. dw = int ((real sw) * (real dh/real sh));
  180. if(dw == 0)
  181. dw = 1;
  182. }
  183. else {
  184. dh = int ((real sh) * (real dw/real sw));
  185. if(dh == 0)
  186. dh = 1;
  187. }
  188. }
  189. is.width = dw;
  190. is.height = dh;
  191. }
  192. jpegmarker(is: ref ImageSource) : int
  193. {
  194. if(getc(is) != 16rFF)
  195. sys->print("Error: Jpeg expected marker");
  196. return getc(is);
  197. }
  198. getbew(is: ref ImageSource) : int
  199. {
  200. c0 := getc(is);
  201. c1 := getc(is);
  202. return (c0<<8) + c1;
  203. }
  204. getn(is: ref ImageSource, n: int) : (array of byte, int)
  205. {
  206. if (is.i + n > slowread - 1) wait4data(is.i + n);
  207. a := is.data;
  208. i := is.i;
  209. if(i + n <= len a)
  210. is.i += n;
  211. # else
  212. # sys->print("Error: premature eof");
  213. return (a, i);
  214. }
  215. # Consume tables and miscellaneous marker segments,
  216. # returning the marker id and length of the first non-such-segment
  217. # (after having consumed the marker).
  218. # May raise "premature eof" or other exception.
  219. jpegtabmisc(is: ref ImageSource) : (int, int)
  220. {
  221. h := is.jstate;
  222. m, n : int;
  223. Loop:
  224. for(;;) {
  225. h.nseg++;
  226. m = jpegmarker(is);
  227. n = 0;
  228. if(m != EOI)
  229. n = getbew(is) - 2;
  230. case m {
  231. SOF or SOF2 or SOS or EOI =>
  232. break Loop;
  233. APPn+0 =>
  234. if(h.nseg==1 && n >= 6) {
  235. (buf, i) := getn(is, 6);
  236. n -= 6;
  237. if(string buf[i:i+4]=="JFIF") {
  238. vers0 := int buf[i+5];
  239. vers1 := int buf[i+6];
  240. if(vers0>1 || vers1>2)
  241. sys->print("Error: Jpeg unimplemented version");
  242. }
  243. }
  244. APPn+1 to APPn+15 =>
  245. ;
  246. DQT =>
  247. jpegquanttables(is, n);
  248. n = 0;
  249. DHT =>
  250. jpeghuffmantables(is, n);
  251. n = 0;
  252. DRI =>
  253. h.ri =getbew(is);
  254. n -= 2;
  255. COM =>
  256. ;
  257. * =>
  258. sys->print("Error: Jpeg unexpected marker");
  259. }
  260. if(n > 0)
  261. getn(is, n);
  262. }
  263. return (m, n);
  264. }
  265. # Consume huffman tables, raising exception on error.
  266. jpeghuffmantables(is: ref ImageSource, n: int)
  267. {
  268. h := is.jstate;
  269. if(h.dcht == nil) {
  270. h.dcht = array[4] of ref Huffman;
  271. h.acht = array[4] of ref Huffman;
  272. }
  273. for(l:= 0; l < n; )
  274. l += jpeghuffmantable(is);
  275. if(l != n)
  276. sys->print("Error: Jpeg huffman table bad length");
  277. }
  278. jpeghuffmantable(is: ref ImageSource) : int
  279. {
  280. t := ref Huffman;
  281. h := is.jstate;
  282. (Tc, th) := nibbles(getc(is));
  283. if(Tc > 1)
  284. sys->print("Error: Jpeg unknown Huffman table class");
  285. if(th>3 || (h.mode==byte SOF && th>1))
  286. sys->print("Error: Jpeg unknown Huffman table index");
  287. if(Tc == 0)
  288. h.dcht[th] = t;
  289. else
  290. h.acht[th] = t;
  291. # flow chart C-2
  292. (b, bi) := getn(is, 16);
  293. numcodes := array[16] of int;
  294. nsize := 0;
  295. for(i:=0; i<16; i++)
  296. nsize += (numcodes[i] = int b[bi+i]);
  297. t.size = array[nsize+1] of int;
  298. k := 0;
  299. for(i=1; i<=16; i++) {
  300. n :=numcodes[i-1];
  301. for(j:=0; j<n; j++)
  302. t.size[k++] = i;
  303. }
  304. t.size[k] = 0;
  305. # initialize HUFFVAL
  306. t.val = array[nsize] of int;
  307. (b, bi) = getn(is, nsize);
  308. for(i=0; i<nsize; i++)
  309. t.val[i] = int b[bi++];
  310. # flow chart C-3
  311. t.code = array[nsize+1] of int;
  312. k = 0;
  313. code := 0;
  314. si := t.size[0];
  315. for(;;) {
  316. do
  317. t.code[k++] = code++;
  318. while(t.size[k] == si);
  319. if(t.size[k] == 0)
  320. break;
  321. do {
  322. code <<= 1;
  323. si++;
  324. } while(t.size[k] != si);
  325. }
  326. # flow chart F-25
  327. t.mincode = array[17] of int;
  328. t.maxcode = array[17] of int;
  329. t.valptr = array[17] of int;
  330. i = 0;
  331. j := 0;
  332. F25:
  333. for(;;) {
  334. for(;;) {
  335. i++;
  336. if(i > 16)
  337. break F25;
  338. if(numcodes[i-1] != 0)
  339. break;
  340. t.maxcode[i] = -1;
  341. }
  342. t.valptr[i] = j;
  343. t.mincode[i] = t.code[j];
  344. j += int numcodes[i-1]-1;
  345. t.maxcode[i] = t.code[j];
  346. j++;
  347. }
  348. # create byte-indexed fast path tables
  349. t.value = array[256] of int;
  350. t.shift = array[256] of int;
  351. maxcode := t.maxcode;
  352. # stupid startup algorithm: just run machine for each byte value
  353. Bytes:
  354. for(v:=0; v<256; v++){
  355. cnt := 7;
  356. m := 1<<7;
  357. code = 0;
  358. sr := v;
  359. i = 1;
  360. for(;;i++){
  361. if(sr & m)
  362. code |= 1;
  363. if(code <= maxcode[i])
  364. break;
  365. code <<= 1;
  366. m >>= 1;
  367. if(m == 0){
  368. t.shift[v] = 0;
  369. t.value[v] = -1;
  370. continue Bytes;
  371. }
  372. cnt--;
  373. }
  374. t.shift[v] = 8-cnt;
  375. t.value[v] = t.val[t.valptr[i]+(code-t.mincode[i])];
  376. }
  377. return nsize+17;
  378. }
  379. jpegquanttables(is: ref ImageSource, n: int)
  380. {
  381. h := is.jstate;
  382. if(h.qt == nil)
  383. h.qt = array[4] of array of int;
  384. for(l:=0; l<n; )
  385. l += jpegquanttable(is);
  386. if(l != n)
  387. sys->print("Error: Jpeg quant table bad length");
  388. }
  389. jpegquanttable(is: ref ImageSource): int
  390. {
  391. (pq, tq) := nibbles(getc(is));
  392. if(pq > 1)
  393. sys->print("Error: Jpeg unknown quantization table class");
  394. if(tq > 3)
  395. sys->print("Error: Jpeg bad quantization table index");
  396. q := array[64] of int;
  397. is.jstate.qt[tq] = q;
  398. for(i:=0; i<64; i++) {
  399. if(pq == 0)
  400. q[i] =getc(is);
  401. else
  402. q[i] = getbew(is);
  403. }
  404. return 1+(64*(1+pq));;
  405. }
  406. # Have just read Frame header.
  407. # Now expect:
  408. # ((tabl/misc segment(s))* (scan header) (entropy coded segment)+)+ EOI
  409. getjpegimg(is:ref ImageSource,chanout:chan of string,imgchan: chan of ref Image,sync: chan of int)
  410. {
  411. sync <-= sys->pctl(0, nil);
  412. getjpeghdr(is);
  413. h := is.jstate;
  414. chans: array of array of byte = nil;
  415. for(;;) {
  416. (m, n) := jpegtabmisc(is);
  417. if(m == EOI)
  418. break;
  419. if(m != SOS)
  420. sys->print("Error: Jpeg expected start of scan");
  421. h.Ns = getc(is);
  422. scomp := array[h.Ns] of Scancomp;
  423. for(i := 0; i < h.Ns; i++) {
  424. scomp[i].C = getc(is);
  425. (scomp[i].tdc, scomp[i].tac) = nibbles(getc(is));
  426. }
  427. h.scomp = scomp;
  428. h.Ss = getc(is);
  429. h.Se = getc(is);
  430. (h.Ah, h.Al) = nibbles(getc(is));
  431. if(n != 4+h.Ns*2)
  432. sys->print("Error: Jpeg SOS header wrong length");
  433. if(h.mode == byte SOF) {
  434. if(chans != nil)
  435. sys->print("Error: Jpeg baseline has > 1 scan");
  436. chans = jpegbaselinescan(is, chanout);
  437. }
  438. }
  439. if(chans == nil)
  440. sys->print("Error: jpeg has no image");
  441. width := is.width;
  442. height := is.height;
  443. if(width != h.X || height != h.Y) {
  444. for(k := 0; k < len chans; k++)
  445. chans[k] = resample(chans[k], h.X, h.Y, width, height);
  446. }
  447. r := remapYCbCr(chans, chanout);
  448. im := newimage24(width, height);
  449. im.writepixels(im.r, r);
  450. imgchan <-= im;
  451. }
  452. newimage24(w, h: int) : ref Image
  453. {
  454. im := display.newimage(((0,0),(w,h)), Draw->RGB24, 0, Draw->White);
  455. if(im == nil)
  456. sys->print("Error: out of memory");
  457. return im;
  458. }
  459. remapYCbCr(chans: array of array of byte, chanout: chan of string): array of byte
  460. {
  461. Y := chans[0];
  462. Cb := chans[1];
  463. Cr := chans[2];
  464. rgb := array [3*len Y] of byte;
  465. bix := 0;
  466. lY := len Y;
  467. n := lY / 20;
  468. count := 0;
  469. for (i := 0; i < lY; i++) {
  470. if ((count == 0 || count >= n ) && chanout != nil) {
  471. chanout <-= "l2 Processing...";
  472. chanout <-= "pc "+string ((100*i)/ lY);
  473. count = 0;
  474. }
  475. count++;
  476. y := int Y[i];
  477. cb := int Cb[i];
  478. cr := int Cr[i];
  479. r := y + Cr2r[cr];
  480. g := y - Cr2g[cr] - Cb2g[cb];
  481. b := y + Cb2b[cb];
  482. rgb[bix++] = clampb[b+CLAMPBOFF];
  483. rgb[bix++] = clampb[g+CLAMPBOFF];
  484. rgb[bix++] = clampb[r+CLAMPBOFF];
  485. }
  486. if (chanout != nil) chanout <-= "pc 100";
  487. return rgb;
  488. }
  489. zig := array[64] of {
  490. 0, 1, 8, 16, 9, 2, 3, 10, 17, # 0-7
  491. 24, 32, 25, 18, 11, 4, 5, # 8-15
  492. 12, 19, 26, 33, 40, 48, 41, 34, # 16-23
  493. 27, 20, 13, 6, 7, 14, 21, 28, # 24-31
  494. 35, 42, 49, 56, 57, 50, 43, 36, # 32-39
  495. 29, 22, 15, 23, 30, 37, 44, 51, # 40-47
  496. 58, 59, 52, 45, 38, 31, 39, 46, # 48-55
  497. 53, 60, 61, 54, 47, 55, 62, 63 # 56-63
  498. };
  499. jpegbaselinescan(is: ref ImageSource,chanout: chan of string) : array of array of byte
  500. {
  501. h := is.jstate;
  502. Ns := h.Ns;
  503. if(Ns != h.Nf)
  504. sys->print("Error: Jpeg baseline needs Ns==Nf");
  505. if(!(Ns==3 || Ns==1))
  506. sys->print("Error: Jpeg baseline needs Ns==1 or 3");
  507. chans := array[h.Nf] of array of byte;
  508. for(k:=0; k<h.Nf; k++)
  509. chans[k] = array[h.X*h.Y] of byte;
  510. # build per-component arrays
  511. Td := array[Ns] of int;
  512. Ta := array[Ns] of int;
  513. data := array[Ns] of array of array of int;
  514. H := array[Ns] of int;
  515. V := array[Ns] of int;
  516. DC := array[Ns] of int;
  517. # compute maximum H and V
  518. Hmax := 0;
  519. Vmax := 0;
  520. for(comp:=0; comp<Ns; comp++) {
  521. if(h.comp[comp].H > Hmax)
  522. Hmax = h.comp[comp].H;
  523. if(h.comp[comp].V > Vmax)
  524. Vmax = h.comp[comp].V;
  525. }
  526. # initialize data structures
  527. allHV1 := 1;
  528. for(comp=0; comp<Ns; comp++) {
  529. # JPEG requires scan components to be in same order as in frame,
  530. # so if both have 3 we know scan is Y Cb Cr and there's no need to
  531. # reorder
  532. Td[comp] = h.scomp[comp].tdc;
  533. Ta[comp] = h.scomp[comp].tac;
  534. H[comp] = h.comp[comp].H;
  535. V[comp] = h.comp[comp].V;
  536. nblock := H[comp]*V[comp];
  537. if(nblock != 1)
  538. allHV1 = 0;
  539. # data[comp]: needs (3+nblock)*4 + nblock*(3+8*8)*4 bytes
  540. data[comp] = array[nblock] of array of int;
  541. DC[comp] = 0;
  542. for(m:=0; m<nblock; m++)
  543. data[comp][m] = array[8*8] of int;
  544. }
  545. ri := h.ri;
  546. h.cnt = 0;
  547. h.sr = 0;
  548. nacross := ((h.X+(8*Hmax-1))/(8*Hmax));
  549. nmcu := ((h.Y+(8*Vmax-1))/(8*Vmax))*nacross;
  550. n1 := 0;
  551. n2 := nmcu / 20;
  552. for(mcu:=0; mcu<nmcu; ) {
  553. if ((n1 == 0 || n1 >= n2) && chanout != nil && slowread == len is.data) {
  554. chanout <-= "l2 Scanning... ";
  555. chanout <-= "pc "+string ((100*mcu)/nmcu);
  556. n1 = 0;
  557. }
  558. n1 ++;
  559. for(comp=0; comp<Ns; comp++) {
  560. dcht := h.dcht[Td[comp]];
  561. acht := h.acht[Ta[comp]];
  562. qt := h.qt[h.comp[comp].Tq];
  563. for(block:=0; block<H[comp]*V[comp]; block++) {
  564. # F-22
  565. t := jdecode(is, dcht);
  566. diff := jreceive(is, t);
  567. DC[comp] += diff;
  568. # F-23
  569. zz := data[comp][block];
  570. zz[0:] = zeroints;
  571. zz[0] = qt[0]*DC[comp];
  572. k = 1;
  573. for(;;) {
  574. rs := jdecode(is, acht);
  575. (rrrr, ssss) := nibbles(rs);
  576. if(ssss == 0){
  577. if(rrrr != 15)
  578. break;
  579. k += 16;
  580. }else{
  581. k += rrrr;
  582. z := jreceive(is, ssss);
  583. zz[zig[k]] = z*qt[k];
  584. if(k == 63)
  585. break;
  586. k++;
  587. }
  588. }
  589. idct(zz);
  590. }
  591. }
  592. # rotate colors to RGB and assign to bytes
  593. colormap(h, chans, data[0], data[1], data[2], mcu, nacross, Hmax, Vmax, H, V);
  594. # process restart marker, if present
  595. mcu++;
  596. if(ri>0 && mcu<nmcu && mcu%ri==0){
  597. jrestart(is, mcu);
  598. for(comp=0; comp<Ns; comp++)
  599. DC[comp] = 0;
  600. }
  601. }
  602. if (chanout != nil) chanout <-= "pc 100";
  603. return chans;
  604. }
  605. jrestart(is: ref ImageSource, mcu: int)
  606. {
  607. h := is.jstate;
  608. ri := h.ri;
  609. restart := mcu/ri-1;
  610. rst, nskip: int;
  611. nskip = 0;
  612. do {
  613. do{
  614. rst = jnextborm(is);
  615. nskip++;
  616. }while(rst>=0 && rst!=16rFF);
  617. if(rst == 16rFF){
  618. rst = jnextborm(is);
  619. nskip++;
  620. }
  621. } while(rst>=0 && (rst&~7)!= RST);
  622. if(nskip != 2 || rst < 0 || ((rst&7) != (restart&7)))
  623. sys->print("Error: Jpeg restart problem");
  624. h.cnt = 0;
  625. h.sr = 0;
  626. }
  627. jc1: con 2871; # 1.402 * 2048
  628. jc2: con 705; # 0.34414 * 2048
  629. jc3: con 1463; # 0.71414 * 2048
  630. jc4: con 3629; # 1.772 * 2048
  631. CLAMPBOFF: con 300;
  632. NCLAMPB: con CLAMPBOFF+256+CLAMPBOFF;
  633. CLAMPNOFF: con 64;
  634. NCLAMPN: con CLAMPNOFF+256+CLAMPNOFF;
  635. clampb: array of byte; # clamps byte values
  636. init_tabs()
  637. {
  638. j: int;
  639. clampb = array[NCLAMPB] of byte;
  640. for(j=0; j<CLAMPBOFF; j++)
  641. clampb[j] = byte 0;
  642. for(j=0; j<256; j++)
  643. clampb[CLAMPBOFF+j] = byte j;
  644. for(j=0; j<CLAMPBOFF; j++)
  645. clampb[CLAMPBOFF+256+j] = byte 16rFF;
  646. }
  647. # Fills in pixels (x,y) for x = minx=8*Hmax*(mcu%nacross), minx+1, ..., minx+8*Hmax-1 (or h.X-1, if less)
  648. # and for y = miny=8*Vmax*(mcu/nacross), miny+1, ..., miny+8*Vmax-1 (or h.Y-1, if less)
  649. colormap(h: ref Jpegstate, chans: array of array of byte, data0, data1, data2: array of array of int, mcu, nacross, Hmax, Vmax: int, H, V: array of int)
  650. {
  651. rpic := chans[0];
  652. gpic := chans[1];
  653. bpic := chans[2];
  654. minx := 8*Hmax*(mcu%nacross);
  655. dx := 8*Hmax;
  656. if(minx+dx > h.X)
  657. dx = h.X-minx;
  658. miny := 8*Vmax*(mcu/nacross);
  659. dy := 8*Vmax;
  660. if(miny+dy > h.Y)
  661. dy = h.Y-miny;
  662. pici := miny*h.X+minx;
  663. H0 := H[0];
  664. H1 := H[1];
  665. H2 := H[2];
  666. for(y:=0; y<dy; y++) {
  667. t := y*V[0];
  668. b0 := H0*(t/(8*Vmax));
  669. y0 := 8*((t/Vmax)&7);
  670. t = y*V[1];
  671. b1 := H1*(t/(8*Vmax));
  672. y1 := 8*((t/Vmax)&7);
  673. t = y*V[2];
  674. b2 := H2*(t/(8*Vmax));
  675. y2 := 8*((t/Vmax)&7);
  676. x0 := 0;
  677. x1 := 0;
  678. x2 := 0;
  679. for(x:=0; x<dx; x++) {
  680. rpic[pici+x] = clampb[data0[b0][y0+x0++*H0/Hmax] + 128 + CLAMPBOFF];
  681. gpic[pici+x] = clampb[data1[b1][y1+x1++*H1/Hmax] + 128 + CLAMPBOFF];
  682. bpic[pici+x] = clampb[data2[b2][y2+x2++*H2/Hmax] + 128 + CLAMPBOFF];
  683. if(x0*H0/Hmax >= 8){
  684. x0 = 0;
  685. b0++;
  686. }
  687. if(x1*H1/Hmax >= 8){
  688. x1 = 0;
  689. b1++;
  690. }
  691. if(x2*H2/Hmax >= 8){
  692. x2 = 0;
  693. b2++;
  694. }
  695. }
  696. pici += h.X;
  697. }
  698. }
  699. # decode next 8-bit value from entropy-coded input. chart F-26
  700. jdecode(is: ref ImageSource, t: ref Huffman): int
  701. {
  702. h := is.jstate;
  703. maxcode := t.maxcode;
  704. if(h.cnt < 8)
  705. jnextbyte(is);
  706. # fast lookup
  707. code := (h.sr>>(h.cnt-8))&16rFF;
  708. v := t.value[code];
  709. if(v >= 0){
  710. h.cnt -= t.shift[code];
  711. return v;
  712. }
  713. h.cnt -= 8;
  714. if(h.cnt == 0)
  715. jnextbyte(is);
  716. h.cnt--;
  717. cnt := h.cnt;
  718. m := 1<<cnt;
  719. sr := h.sr;
  720. code <<= 1;
  721. i := 9;
  722. for(;;i++){
  723. if(sr & m)
  724. code |= 1;
  725. if(code <= maxcode[i])
  726. break;
  727. code <<= 1;
  728. m >>= 1;
  729. if(m == 0){
  730. sr = jnextbyte(is);
  731. m = 16r80;
  732. cnt = 8;
  733. }
  734. cnt--;
  735. }
  736. h.cnt = cnt;
  737. return t.val[t.valptr[i]+(code-t.mincode[i])];
  738. }
  739. # load next byte of input
  740. jnextbyte(is: ref ImageSource): int
  741. {
  742. b :=getc(is);
  743. if(b == 16rFF) {
  744. b2 :=getc(is);
  745. if(b2 != 0) {
  746. if(b2 == int DNL)
  747. sys->print("Error: Jpeg DNL marker unimplemented");
  748. # decoder is reading into marker; satisfy it and restore state
  749. ungetc2(is, byte b);
  750. }
  751. }
  752. h := is.jstate;
  753. h.cnt += 8;
  754. h.sr = (h.sr<<8)| b;
  755. return b;
  756. }
  757. ungetc2(is: ref ImageSource, nil: byte)
  758. {
  759. if(is.i < 2) {
  760. if(is.i != 1)
  761. sys->print("Error: EXInternal: ungetc2 past beginning of buffer");
  762. is.i = 0;
  763. }
  764. else
  765. is.i -= 2;
  766. }
  767. getc(is: ref ImageSource) : int
  768. {
  769. if(is.i >= len is.data) {
  770. sys->print("Error: premature eof");
  771. }
  772. if (is.i >= slowread)
  773. wait4data(is.i);
  774. return int is.data[is.i++];
  775. }
  776. # like jnextbyte, but look for marker too
  777. jnextborm(is: ref ImageSource): int
  778. {
  779. b :=getc(is);
  780. if(b == 16rFF)
  781. return b;
  782. h := is.jstate;
  783. h.cnt += 8;
  784. h.sr = (h.sr<<8)| b;
  785. return b;
  786. }
  787. # return next s bits of input, MSB first, and level shift it
  788. jreceive(is: ref ImageSource, s: int): int
  789. {
  790. h := is.jstate;
  791. while(h.cnt < s)
  792. jnextbyte(is);
  793. h.cnt -= s;
  794. v := h.sr >> h.cnt;
  795. m := (1<<s);
  796. v &= m-1;
  797. # level shift
  798. if(v < (m>>1))
  799. v += ~(m-1)+1;
  800. return v;
  801. }
  802. nibbles(c: int) : (int, int)
  803. {
  804. return (c>>4, c&15);
  805. }
  806. # Scaled integer implementation.
  807. # inverse two dimensional DCT, Chen-Wang algorithm
  808. # (IEEE ASSP-32, pp. 803-816, Aug. 1984)
  809. # 32-bit integer arithmetic (8 bit coefficients)
  810. # 11 mults, 29 adds per DCT
  811. #
  812. # coefficients extended to 12 bit for IEEE1180-1990
  813. # compliance
  814. W1: con 2841; # 2048*sqrt(2)*cos(1*pi/16)
  815. W2: con 2676; # 2048*sqrt(2)*cos(2*pi/16)
  816. W3: con 2408; # 2048*sqrt(2)*cos(3*pi/16)
  817. W5: con 1609; # 2048*sqrt(2)*cos(5*pi/16)
  818. W6: con 1108; # 2048*sqrt(2)*cos(6*pi/16)
  819. W7: con 565; # 2048*sqrt(2)*cos(7*pi/16)
  820. W1pW7: con 3406; # W1+W7
  821. W1mW7: con 2276; # W1-W7
  822. W3pW5: con 4017; # W3+W5
  823. W3mW5: con 799; # W3-W5
  824. W2pW6: con 3784; # W2+W6
  825. W2mW6: con 1567; # W2-W6
  826. R2: con 181; # 256/sqrt(2)
  827. idct(b: array of int)
  828. {
  829. # transform horizontally
  830. for(y:=0; y<8; y++){
  831. eighty := y<<3;
  832. # if all non-DC components are zero, just propagate the DC term
  833. if(b[eighty+1]==0)
  834. if(b[eighty+2]==0 && b[eighty+3]==0)
  835. if(b[eighty+4]==0 && b[eighty+5]==0)
  836. if(b[eighty+6]==0 && b[eighty+7]==0){
  837. v := b[eighty]<<3;
  838. b[eighty+0] = v;
  839. b[eighty+1] = v;
  840. b[eighty+2] = v;
  841. b[eighty+3] = v;
  842. b[eighty+4] = v;
  843. b[eighty+5] = v;
  844. b[eighty+6] = v;
  845. b[eighty+7] = v;
  846. continue;
  847. }
  848. # prescale
  849. x0 := (b[eighty+0]<<11)+128;
  850. x1 := b[eighty+4]<<11;
  851. x2 := b[eighty+6];
  852. x3 := b[eighty+2];
  853. x4 := b[eighty+1];
  854. x5 := b[eighty+7];
  855. x6 := b[eighty+5];
  856. x7 := b[eighty+3];
  857. # first stage
  858. x8 := W7*(x4+x5);
  859. x4 = x8 + W1mW7*x4;
  860. x5 = x8 - W1pW7*x5;
  861. x8 = W3*(x6+x7);
  862. x6 = x8 - W3mW5*x6;
  863. x7 = x8 - W3pW5*x7;
  864. # second stage
  865. x8 = x0 + x1;
  866. x0 -= x1;
  867. x1 = W6*(x3+x2);
  868. x2 = x1 - W2pW6*x2;
  869. x3 = x1 + W2mW6*x3;
  870. x1 = x4 + x6;
  871. x4 -= x6;
  872. x6 = x5 + x7;
  873. x5 -= x7;
  874. # third stage
  875. x7 = x8 + x3;
  876. x8 -= x3;
  877. x3 = x0 + x2;
  878. x0 -= x2;
  879. x2 = (R2*(x4+x5)+128)>>8;
  880. x4 = (R2*(x4-x5)+128)>>8;
  881. # fourth stage
  882. b[eighty+0] = (x7+x1)>>8;
  883. b[eighty+1] = (x3+x2)>>8;
  884. b[eighty+2] = (x0+x4)>>8;
  885. b[eighty+3] = (x8+x6)>>8;
  886. b[eighty+4] = (x8-x6)>>8;
  887. b[eighty+5] = (x0-x4)>>8;
  888. b[eighty+6] = (x3-x2)>>8;
  889. b[eighty+7] = (x7-x1)>>8;
  890. }
  891. # transform vertically
  892. for(x:=0; x<8; x++){
  893. # if all non-DC components are zero, just propagate the DC term
  894. if(b[x+8*1]==0)
  895. if(b[x+8*2]==0 && b[x+8*3]==0)
  896. if(b[x+8*4]==0 && b[x+8*5]==0)
  897. if(b[x+8*6]==0 && b[x+8*7]==0){
  898. v := (b[x+8*0]+32)>>6;
  899. b[x+8*0] = v;
  900. b[x+8*1] = v;
  901. b[x+8*2] = v;
  902. b[x+8*3] = v;
  903. b[x+8*4] = v;
  904. b[x+8*5] = v;
  905. b[x+8*6] = v;
  906. b[x+8*7] = v;
  907. continue;
  908. }
  909. # prescale
  910. x0 := (b[x+8*0]<<8)+8192;
  911. x1 := b[x+8*4]<<8;
  912. x2 := b[x+8*6];
  913. x3 := b[x+8*2];
  914. x4 := b[x+8*1];
  915. x5 := b[x+8*7];
  916. x6 := b[x+8*5];
  917. x7 := b[x+8*3];
  918. # first stage
  919. x8 := W7*(x4+x5) + 4;
  920. x4 = (x8+W1mW7*x4)>>3;
  921. x5 = (x8-W1pW7*x5)>>3;
  922. x8 = W3*(x6+x7) + 4;
  923. x6 = (x8-W3mW5*x6)>>3;
  924. x7 = (x8-W3pW5*x7)>>3;
  925. # second stage
  926. x8 = x0 + x1;
  927. x0 -= x1;
  928. x1 = W6*(x3+x2) + 4;
  929. x2 = (x1-W2pW6*x2)>>3;
  930. x3 = (x1+W2mW6*x3)>>3;
  931. x1 = x4 + x6;
  932. x4 -= x6;
  933. x6 = x5 + x7;
  934. x5 -= x7;
  935. # third stage
  936. x7 = x8 + x3;
  937. x8 -= x3;
  938. x3 = x0 + x2;
  939. x0 -= x2;
  940. x2 = (R2*(x4+x5)+128)>>8;
  941. x4 = (R2*(x4-x5)+128)>>8;
  942. # fourth stage
  943. b[x+8*0] = (x7+x1)>>14;
  944. b[x+8*1] = (x3+x2)>>14;
  945. b[x+8*2] = (x0+x4)>>14;
  946. b[x+8*3] = (x8+x6)>>14;
  947. b[x+8*4] = (x8-x6)>>14;
  948. b[x+8*5] = (x0-x4)>>14;
  949. b[x+8*6] = (x3-x2)>>14;
  950. b[x+8*7] = (x7-x1)>>14;
  951. }
  952. }
  953. resample(src: array of byte, sw, sh: int, dw, dh: int) : array of byte
  954. {
  955. if(src == nil || sw == 0 || sh == 0 || dw == 0 || dh == 0)
  956. return src;
  957. xfac := real sw / real dw;
  958. yfac := real sh / real dh;
  959. totpix := dw*dh;
  960. dst := array[totpix] of byte;
  961. dindex := 0;
  962. # precompute index in src row corresponding to each index in dst row
  963. sindices := array[dw] of int;
  964. dx := 0.0;
  965. for(x := 0; x < dw; x++) {
  966. sx := int dx;
  967. dx += xfac;
  968. if(sx >= sw)
  969. sx = sw-1;
  970. sindices[x] = sx;
  971. }
  972. dy := 0.0;
  973. for(y := 0; y < dh; y++) {
  974. sy := int dy;
  975. dy += yfac;
  976. if(sy >= sh)
  977. sy = sh-1;
  978. soffset := sy * sw;
  979. for(x = 0; x < dw; x++)
  980. dst[dindex++] = src[soffset + sindices[x]];
  981. }
  982. return dst;
  983. }
  984. Cr2r := array [256] of {
  985. -179, -178, -177, -175, -174, -172, -171, -170, -168, -167, -165, -164, -163, -161, -160, -158,
  986. -157, -156, -154, -153, -151, -150, -149, -147, -146, -144, -143, -142, -140, -139, -137, -136,
  987. -135, -133, -132, -130, -129, -128, -126, -125, -123, -122, -121, -119, -118, -116, -115, -114,
  988. -112, -111, -109, -108, -107, -105, -104, -102, -101, -100, -98, -97, -95, -94, -93, -91,
  989. -90, -88, -87, -86, -84, -83, -81, -80, -79, -77, -76, -74, -73, -72, -70, -69,
  990. -67, -66, -64, -63, -62, -60, -59, -57, -56, -55, -53, -52, -50, -49, -48, -46,
  991. -45, -43, -42, -41, -39, -38, -36, -35, -34, -32, -31, -29, -28, -27, -25, -24,
  992. -22, -21, -20, -18, -17, -15, -14, -13, -11, -10, -8, -7, -6, -4, -3, -1,
  993. 0, 1, 3, 4, 6, 7, 8, 10, 11, 13, 14, 15, 17, 18, 20, 21,
  994. 22, 24, 25, 27, 28, 29, 31, 32, 34, 35, 36, 38, 39, 41, 42, 43,
  995. 45, 46, 48, 49, 50, 52, 53, 55, 56, 57, 59, 60, 62, 63, 64, 66,
  996. 67, 69, 70, 72, 73, 74, 76, 77, 79, 80, 81, 83, 84, 86, 87, 88,
  997. 90, 91, 93, 94, 95, 97, 98, 100, 101, 102, 104, 105, 107, 108, 109, 111,
  998. 112, 114, 115, 116, 118, 119, 121, 122, 123, 125, 126, 128, 129, 130, 132, 133,
  999. 135, 136, 137, 139, 140, 142, 143, 144, 146, 147, 149, 150, 151, 153, 154, 156,
  1000. 157, 158, 160, 161, 163, 164, 165, 167, 168, 170, 171, 172, 174, 175, 177, 178,
  1001. };
  1002. Cr2g := array [256] of {
  1003. -91, -91, -90, -89, -89, -88, -87, -86, -86, -85, -84, -84, -83, -82, -81, -81,
  1004. -80, -79, -79, -78, -77, -76, -76, -75, -74, -74, -73, -72, -71, -71, -70, -69,
  1005. -69, -68, -67, -66, -66, -65, -64, -64, -63, -62, -61, -61, -60, -59, -59, -58,
  1006. -57, -56, -56, -55, -54, -54, -53, -52, -51, -51, -50, -49, -49, -48, -47, -46,
  1007. -46, -45, -44, -44, -43, -42, -41, -41, -40, -39, -39, -38, -37, -36, -36, -35,
  1008. -34, -34, -33, -32, -31, -31, -30, -29, -29, -28, -27, -26, -26, -25, -24, -24,
  1009. -23, -22, -21, -21, -20, -19, -19, -18, -17, -16, -16, -15, -14, -14, -13, -12,
  1010. -11, -11, -10, -9, -9, -8, -7, -6, -6, -5, -4, -4, -3, -2, -1, -1,
  1011. 0, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
  1012. 11, 12, 13, 14, 14, 15, 16, 16, 17, 18, 19, 19, 20, 21, 21, 22,
  1013. 23, 24, 24, 25, 26, 26, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34,
  1014. 34, 35, 36, 36, 37, 38, 39, 39, 40, 41, 41, 42, 43, 44, 44, 45,
  1015. 46, 46, 47, 48, 49, 49, 50, 51, 51, 52, 53, 54, 54, 55, 56, 56,
  1016. 57, 58, 59, 59, 60, 61, 61, 62, 63, 64, 64, 65, 66, 66, 67, 68,
  1017. 69, 69, 70, 71, 71, 72, 73, 74, 74, 75, 76, 76, 77, 78, 79, 79,
  1018. 80, 81, 81, 82, 83, 84, 84, 85, 86, 86, 87, 88, 89, 89, 90, 91,
  1019. };
  1020. Cb2g := array [256] of {
  1021. -44, -44, -43, -43, -43, -42, -42, -42, -41, -41, -41, -40, -40, -40, -39, -39,
  1022. -39, -38, -38, -38, -37, -37, -36, -36, -36, -35, -35, -35, -34, -34, -34, -33,
  1023. -33, -33, -32, -32, -32, -31, -31, -31, -30, -30, -30, -29, -29, -29, -28, -28,
  1024. -28, -27, -27, -26, -26, -26, -25, -25, -25, -24, -24, -24, -23, -23, -23, -22,
  1025. -22, -22, -21, -21, -21, -20, -20, -20, -19, -19, -19, -18, -18, -18, -17, -17,
  1026. -17, -16, -16, -15, -15, -15, -14, -14, -14, -13, -13, -13, -12, -12, -12, -11,
  1027. -11, -11, -10, -10, -10, -9, -9, -9, -8, -8, -8, -7, -7, -7, -6, -6,
  1028. -6, -5, -5, -4, -4, -4, -3, -3, -3, -2, -2, -2, -1, -1, -1, 0,
  1029. 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5,
  1030. 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11,
  1031. 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16,
  1032. 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22,
  1033. 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27,
  1034. 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33,
  1035. 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 38, 38, 38,
  1036. 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 43, 43, 43, 44,
  1037. };
  1038. Cb2b := array [256] of {
  1039. -227, -225, -223, -222, -220, -218, -216, -214, -213, -211, -209, -207, -206, -204, -202, -200,
  1040. -198, -197, -195, -193, -191, -190, -188, -186, -184, -183, -181, -179, -177, -175, -174, -172,
  1041. -170, -168, -167, -165, -163, -161, -159, -158, -156, -154, -152, -151, -149, -147, -145, -144,
  1042. -142, -140, -138, -136, -135, -133, -131, -129, -128, -126, -124, -122, -120, -119, -117, -115,
  1043. -113, -112, -110, -108, -106, -105, -103, -101, -99, -97, -96, -94, -92, -90, -89, -87,
  1044. -85, -83, -82, -80, -78, -76, -74, -73, -71, -69, -67, -66, -64, -62, -60, -58,
  1045. -57, -55, -53, -51, -50, -48, -46, -44, -43, -41, -39, -37, -35, -34, -32, -30,
  1046. -28, -27, -25, -23, -21, -19, -18, -16, -14, -12, -11, -9, -7, -5, -4, -2,
  1047. 0, 2, 4, 5, 7, 9, 11, 12, 14, 16, 18, 19, 21, 23, 25, 27,
  1048. 28, 30, 32, 34, 35, 37, 39, 41, 43, 44, 46, 48, 50, 51, 53, 55,
  1049. 57, 58, 60, 62, 64, 66, 67, 69, 71, 73, 74, 76, 78, 80, 82, 83,
  1050. 85, 87, 89, 90, 92, 94, 96, 97, 99, 101, 103, 105, 106, 108, 110, 112,
  1051. 113, 115, 117, 119, 120, 122, 124, 126, 128, 129, 131, 133, 135, 136, 138, 140,
  1052. 142, 144, 145, 147, 149, 151, 152, 154, 156, 158, 159, 161, 163, 165, 167, 168,
  1053. 170, 172, 174, 175, 177, 179, 181, 183, 184, 186, 188, 190, 191, 193, 195, 197,
  1054. 198, 200, 202, 204, 206, 207, 209, 211, 213, 214, 216, 218, 220, 222, 223, 225,
  1055. };