filter-sgi.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. // Copyright (C) 2004-2021 Artifex Software, Inc.
  2. //
  3. // This file is part of MuPDF.
  4. //
  5. // MuPDF is free software: you can redistribute it and/or modify it under the
  6. // terms of the GNU Affero General Public License as published by the Free
  7. // Software Foundation, either version 3 of the License, or (at your option)
  8. // any later version.
  9. //
  10. // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
  11. // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  12. // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  13. // details.
  14. //
  15. // You should have received a copy of the GNU Affero General Public License
  16. // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
  17. //
  18. // Alternative licensing terms are available from the licensor.
  19. // For commercial licensing, see <https://www.artifex.com/> or contact
  20. // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
  21. // CA 94129, USA, for further information.
  22. #include "mupdf/fitz.h"
  23. #include <math.h>
  24. #include <string.h>
  25. /* Table stolen from LibTiff */
  26. #define UV_SQSIZ 0.003500f
  27. #define UV_NDIVS 16289
  28. #define UV_VSTART 0.016940f
  29. #define UV_NVS 163
  30. #define U_NEU 0.210526316f
  31. #define V_NEU 0.473684211f
  32. #define UVSCALE 410
  33. static struct {
  34. float ustart;
  35. short nus, ncum;
  36. } uv_row[UV_NVS] = {
  37. { 0.247663f, 4, 0 },
  38. { 0.243779f, 6, 4 },
  39. { 0.241684f, 7, 10 },
  40. { 0.237874f, 9, 17 },
  41. { 0.235906f, 10, 26 },
  42. { 0.232153f, 12, 36 },
  43. { 0.228352f, 14, 48 },
  44. { 0.226259f, 15, 62 },
  45. { 0.222371f, 17, 77 },
  46. { 0.220410f, 18, 94 },
  47. { 0.214710f, 21, 112 },
  48. { 0.212714f, 22, 133 },
  49. { 0.210721f, 23, 155 },
  50. { 0.204976f, 26, 178 },
  51. { 0.202986f, 27, 204 },
  52. { 0.199245f, 29, 231 },
  53. { 0.195525f, 31, 260 },
  54. { 0.193560f, 32, 291 },
  55. { 0.189878f, 34, 323 },
  56. { 0.186216f, 36, 357 },
  57. { 0.186216f, 36, 393 },
  58. { 0.182592f, 38, 429 },
  59. { 0.179003f, 40, 467 },
  60. { 0.175466f, 42, 507 },
  61. { 0.172001f, 44, 549 },
  62. { 0.172001f, 44, 593 },
  63. { 0.168612f, 46, 637 },
  64. { 0.168612f, 46, 683 },
  65. { 0.163575f, 49, 729 },
  66. { 0.158642f, 52, 778 },
  67. { 0.158642f, 52, 830 },
  68. { 0.158642f, 52, 882 },
  69. { 0.153815f, 55, 934 },
  70. { 0.153815f, 55, 989 },
  71. { 0.149097f, 58, 1044 },
  72. { 0.149097f, 58, 1102 },
  73. { 0.142746f, 62, 1160 },
  74. { 0.142746f, 62, 1222 },
  75. { 0.142746f, 62, 1284 },
  76. { 0.138270f, 65, 1346 },
  77. { 0.138270f, 65, 1411 },
  78. { 0.138270f, 65, 1476 },
  79. { 0.132166f, 69, 1541 },
  80. { 0.132166f, 69, 1610 },
  81. { 0.126204f, 73, 1679 },
  82. { 0.126204f, 73, 1752 },
  83. { 0.126204f, 73, 1825 },
  84. { 0.120381f, 77, 1898 },
  85. { 0.120381f, 77, 1975 },
  86. { 0.120381f, 77, 2052 },
  87. { 0.120381f, 77, 2129 },
  88. { 0.112962f, 82, 2206 },
  89. { 0.112962f, 82, 2288 },
  90. { 0.112962f, 82, 2370 },
  91. { 0.107450f, 86, 2452 },
  92. { 0.107450f, 86, 2538 },
  93. { 0.107450f, 86, 2624 },
  94. { 0.107450f, 86, 2710 },
  95. { 0.100343f, 91, 2796 },
  96. { 0.100343f, 91, 2887 },
  97. { 0.100343f, 91, 2978 },
  98. { 0.095126f, 95, 3069 },
  99. { 0.095126f, 95, 3164 },
  100. { 0.095126f, 95, 3259 },
  101. { 0.095126f, 95, 3354 },
  102. { 0.088276f, 100, 3449 },
  103. { 0.088276f, 100, 3549 },
  104. { 0.088276f, 100, 3649 },
  105. { 0.088276f, 100, 3749 },
  106. { 0.081523f, 105, 3849 },
  107. { 0.081523f, 105, 3954 },
  108. { 0.081523f, 105, 4059 },
  109. { 0.081523f, 105, 4164 },
  110. { 0.074861f, 110, 4269 },
  111. { 0.074861f, 110, 4379 },
  112. { 0.074861f, 110, 4489 },
  113. { 0.074861f, 110, 4599 },
  114. { 0.068290f, 115, 4709 },
  115. { 0.068290f, 115, 4824 },
  116. { 0.068290f, 115, 4939 },
  117. { 0.068290f, 115, 5054 },
  118. { 0.063573f, 119, 5169 },
  119. { 0.063573f, 119, 5288 },
  120. { 0.063573f, 119, 5407 },
  121. { 0.063573f, 119, 5526 },
  122. { 0.057219f, 124, 5645 },
  123. { 0.057219f, 124, 5769 },
  124. { 0.057219f, 124, 5893 },
  125. { 0.057219f, 124, 6017 },
  126. { 0.050985f, 129, 6141 },
  127. { 0.050985f, 129, 6270 },
  128. { 0.050985f, 129, 6399 },
  129. { 0.050985f, 129, 6528 },
  130. { 0.050985f, 129, 6657 },
  131. { 0.044859f, 134, 6786 },
  132. { 0.044859f, 134, 6920 },
  133. { 0.044859f, 134, 7054 },
  134. { 0.044859f, 134, 7188 },
  135. { 0.040571f, 138, 7322 },
  136. { 0.040571f, 138, 7460 },
  137. { 0.040571f, 138, 7598 },
  138. { 0.040571f, 138, 7736 },
  139. { 0.036339f, 142, 7874 },
  140. { 0.036339f, 142, 8016 },
  141. { 0.036339f, 142, 8158 },
  142. { 0.036339f, 142, 8300 },
  143. { 0.032139f, 146, 8442 },
  144. { 0.032139f, 146, 8588 },
  145. { 0.032139f, 146, 8734 },
  146. { 0.032139f, 146, 8880 },
  147. { 0.027947f, 150, 9026 },
  148. { 0.027947f, 150, 9176 },
  149. { 0.027947f, 150, 9326 },
  150. { 0.023739f, 154, 9476 },
  151. { 0.023739f, 154, 9630 },
  152. { 0.023739f, 154, 9784 },
  153. { 0.023739f, 154, 9938 },
  154. { 0.019504f, 158, 10092 },
  155. { 0.019504f, 158, 10250 },
  156. { 0.019504f, 158, 10408 },
  157. { 0.016976f, 161, 10566 },
  158. { 0.016976f, 161, 10727 },
  159. { 0.016976f, 161, 10888 },
  160. { 0.016976f, 161, 11049 },
  161. { 0.012639f, 165, 11210 },
  162. { 0.012639f, 165, 11375 },
  163. { 0.012639f, 165, 11540 },
  164. { 0.009991f, 168, 11705 },
  165. { 0.009991f, 168, 11873 },
  166. { 0.009991f, 168, 12041 },
  167. { 0.009016f, 170, 12209 },
  168. { 0.009016f, 170, 12379 },
  169. { 0.009016f, 170, 12549 },
  170. { 0.006217f, 173, 12719 },
  171. { 0.006217f, 173, 12892 },
  172. { 0.005097f, 175, 13065 },
  173. { 0.005097f, 175, 13240 },
  174. { 0.005097f, 175, 13415 },
  175. { 0.003909f, 177, 13590 },
  176. { 0.003909f, 177, 13767 },
  177. { 0.002340f, 177, 13944 },
  178. { 0.002389f, 170, 14121 },
  179. { 0.001068f, 164, 14291 },
  180. { 0.001653f, 157, 14455 },
  181. { 0.000717f, 150, 14612 },
  182. { 0.001614f, 143, 14762 },
  183. { 0.000270f, 136, 14905 },
  184. { 0.000484f, 129, 15041 },
  185. { 0.001103f, 123, 15170 },
  186. { 0.001242f, 115, 15293 },
  187. { 0.001188f, 109, 15408 },
  188. { 0.001011f, 103, 15517 },
  189. { 0.000709f, 97, 15620 },
  190. { 0.000301f, 89, 15717 },
  191. { 0.002416f, 82, 15806 },
  192. { 0.003251f, 76, 15888 },
  193. { 0.003246f, 69, 15964 },
  194. { 0.004141f, 62, 16033 },
  195. { 0.005963f, 55, 16095 },
  196. { 0.008839f, 47, 16150 },
  197. { 0.010490f, 40, 16197 },
  198. { 0.016994f, 31, 16237 },
  199. { 0.023659f, 21, 16268 },
  200. };
  201. /* SGI Log 16bit (greyscale) */
  202. typedef struct
  203. {
  204. fz_stream *chain;
  205. int run, n, c, w;
  206. uint16_t *temp;
  207. } fz_sgilog16;
  208. static inline int
  209. sgilog16val(fz_context *ctx, uint16_t v)
  210. {
  211. int Le;
  212. float Y;
  213. Le = v & 0x7fff;
  214. if (!Le)
  215. Y = 0;
  216. else
  217. {
  218. Y = expf(FZ_LN2/256 * (Le + .5f) - FZ_LN2*64);
  219. if (v & 0x8000)
  220. Y = -Y;
  221. }
  222. return ((Y <= 0) ? 0 : (Y >= 1) ? 255 : (int)(256*sqrtf(Y)));
  223. }
  224. static int
  225. next_sgilog16(fz_context *ctx, fz_stream *stm, size_t max)
  226. {
  227. fz_sgilog16 *state = stm->state;
  228. uint16_t *p;
  229. uint16_t *ep;
  230. uint8_t *q;
  231. int shift;
  232. (void)max;
  233. if (state->run < 0)
  234. return EOF;
  235. memset(state->temp, 0, state->w * sizeof(uint16_t));
  236. for (shift = 8; shift >= 0; shift -= 8)
  237. {
  238. p = state->temp;
  239. ep = p + state->w;
  240. while (p < ep)
  241. {
  242. if (state->n == 0)
  243. {
  244. state->run = fz_read_byte(ctx, state->chain);
  245. if (state->run < 0)
  246. {
  247. state->run = -1;
  248. fz_throw(ctx, FZ_ERROR_FORMAT, "premature end of data in run length decode");
  249. }
  250. if (state->run < 128)
  251. state->n = state->run;
  252. else
  253. {
  254. state->n = state->run - 126;
  255. state->c = fz_read_byte(ctx, state->chain);
  256. if (state->c < 0)
  257. {
  258. state->run = -1;
  259. fz_throw(ctx, FZ_ERROR_FORMAT, "premature end of data in run length decode");
  260. }
  261. }
  262. }
  263. if (state->run < 128)
  264. {
  265. while (p < ep && state->n)
  266. {
  267. int c = fz_read_byte(ctx, state->chain);
  268. if (c < 0)
  269. {
  270. state->run = -1;
  271. fz_throw(ctx, FZ_ERROR_FORMAT, "premature end of data in run length decode");
  272. }
  273. *p++ |= c<<shift;
  274. state->n--;
  275. }
  276. }
  277. else
  278. {
  279. while (p < ep && state->n)
  280. {
  281. *p++ |= state->c<<shift;
  282. state->n--;
  283. }
  284. }
  285. }
  286. }
  287. p = state->temp;
  288. q = (uint8_t *)p;
  289. ep = p + state->w;
  290. while (p < ep)
  291. {
  292. *q++ = sgilog16val(ctx, *p++);
  293. }
  294. stm->rp = (uint8_t *)(state->temp);
  295. stm->wp = q;
  296. stm->pos += q - stm->rp;
  297. if (q == stm->rp)
  298. return EOF;
  299. return *stm->rp++;
  300. }
  301. static void
  302. close_sgilog16(fz_context *ctx, void *state_)
  303. {
  304. fz_sgilog16 *state = (fz_sgilog16 *)state_;
  305. fz_stream *chain = state->chain;
  306. fz_free(ctx, state->temp);
  307. fz_free(ctx, state);
  308. fz_drop_stream(ctx, chain);
  309. }
  310. fz_stream *
  311. fz_open_sgilog16(fz_context *ctx, fz_stream *chain, int w)
  312. {
  313. fz_sgilog16 *state = fz_malloc_struct(ctx, fz_sgilog16);
  314. fz_try(ctx)
  315. {
  316. state->run = 0;
  317. state->n = 0;
  318. state->c = 0;
  319. state->w = w;
  320. state->temp = Memento_label(fz_malloc(ctx, w * sizeof(uint16_t)), "sgilog16_temp");
  321. state->chain = fz_keep_stream(ctx, chain);
  322. }
  323. fz_catch(ctx)
  324. {
  325. fz_free(ctx, state->temp);
  326. fz_free(ctx, state);
  327. fz_rethrow(ctx);
  328. }
  329. return fz_new_stream(ctx, state, next_sgilog16, close_sgilog16);
  330. }
  331. /* SGI Log 24bit (LUV) */
  332. typedef struct
  333. {
  334. fz_stream *chain;
  335. int err, w;
  336. uint8_t *temp;
  337. } fz_sgilog24;
  338. static int
  339. uv_decode(float *up, float *vp, int c) /* decode (u',v') index */
  340. {
  341. int upper, lower;
  342. register int ui, vi;
  343. if (c < 0 || c >= UV_NDIVS)
  344. return (-1);
  345. lower = 0; /* binary search */
  346. upper = UV_NVS;
  347. while (upper - lower > 1) {
  348. vi = (lower + upper) >> 1;
  349. ui = c - uv_row[vi].ncum;
  350. if (ui > 0)
  351. lower = vi;
  352. else if (ui < 0)
  353. upper = vi;
  354. else {
  355. lower = vi;
  356. break;
  357. }
  358. }
  359. vi = lower;
  360. ui = c - uv_row[vi].ncum;
  361. *up = uv_row[vi].ustart + (ui+.5f)*UV_SQSIZ;
  362. *vp = UV_VSTART + (vi+.5f)*UV_SQSIZ;
  363. return (0);
  364. }
  365. static inline int
  366. sgilog24val(fz_context *ctx, fz_stream *chain, uint8_t *rgb)
  367. {
  368. int b0, b1, b2;
  369. int luv, p;
  370. float u, v, s, x, y, X, Y, Z;
  371. float r, g, b;
  372. b0 = fz_read_byte(ctx, chain);
  373. if (b0 < 0)
  374. return b0;
  375. b1 = fz_read_byte(ctx, chain);
  376. if (b1 < 0)
  377. return b1;
  378. b2 = fz_read_byte(ctx, chain);
  379. if (b2 < 0)
  380. return b2;
  381. luv = (b0<<16) | (b1<<8) | b2;
  382. /* decode luminance */
  383. p = (luv>>14) & 0x3ff;
  384. Y = (p == 0 ? 0 : expf(FZ_LN2/64*(p+.5f) - FZ_LN2*12));
  385. if (Y <= 0)
  386. {
  387. X = Y = Z = 0;
  388. }
  389. else
  390. {
  391. /* decode color */
  392. if (uv_decode(&u, &v, luv & 0x3fff) < 0) {
  393. u = U_NEU; v = V_NEU;
  394. }
  395. s = 6*u - 16*v + 12;
  396. x = 9*u;
  397. y = 4*v;
  398. /* convert to XYZ */
  399. X = x/y * Y;
  400. Z = (s-x-y)/y * Y;
  401. }
  402. /* assume CCIR-709 primaries */
  403. r = 2.690f*X + -1.276f*Y + -0.414f*Z;
  404. g = -1.022f*X + 1.978f*Y + 0.044f*Z;
  405. b = 0.061f*X + -0.224f*Y + 1.163f*Z;
  406. /* assume 2.0 gamma for speed */
  407. /* could use integer sqrt approx., but this is probably faster */
  408. rgb[0] = (uint8_t)((r<=0) ? 0 : (r >= 1) ? 255 : (int)(256*sqrtf(r)));
  409. rgb[1] = (uint8_t)((g<=0) ? 0 : (g >= 1) ? 255 : (int)(256*sqrtf(g)));
  410. rgb[2] = (uint8_t)((b<=0) ? 0 : (b >= 1) ? 255 : (int)(256*sqrtf(b)));
  411. return 0;
  412. }
  413. static int
  414. next_sgilog24(fz_context *ctx, fz_stream *stm, size_t max)
  415. {
  416. fz_sgilog24 *state = stm->state;
  417. uint8_t *p;
  418. uint8_t *ep;
  419. (void)max;
  420. if (state->err)
  421. return EOF;
  422. memset(state->temp, 0, state->w * 3);
  423. p = state->temp;
  424. ep = p + state->w * 3;
  425. while (p < ep)
  426. {
  427. int c = sgilog24val(ctx, state->chain, p);
  428. if (c < 0)
  429. {
  430. state->err = 1;
  431. fz_throw(ctx, FZ_ERROR_FORMAT, "premature end of data in run length decode");
  432. }
  433. p += 3;
  434. }
  435. stm->rp = state->temp;
  436. stm->wp = p;
  437. stm->pos += p - stm->rp;
  438. if (p == stm->rp)
  439. return EOF;
  440. return *stm->rp++;
  441. }
  442. static void
  443. close_sgilog24(fz_context *ctx, void *state_)
  444. {
  445. fz_sgilog24 *state = (fz_sgilog24 *)state_;
  446. fz_stream *chain = state->chain;
  447. fz_free(ctx, state->temp);
  448. fz_free(ctx, state);
  449. fz_drop_stream(ctx, chain);
  450. }
  451. fz_stream *
  452. fz_open_sgilog24(fz_context *ctx, fz_stream *chain, int w)
  453. {
  454. fz_sgilog24 *state = fz_malloc_struct(ctx, fz_sgilog24);
  455. fz_try(ctx)
  456. {
  457. state->err = 0;
  458. state->w = w;
  459. state->temp = Memento_label(fz_malloc(ctx, w * 3), "sgilog24_temp");
  460. state->chain = fz_keep_stream(ctx, chain);
  461. }
  462. fz_catch(ctx)
  463. {
  464. fz_free(ctx, state->temp);
  465. fz_free(ctx, state);
  466. fz_rethrow(ctx);
  467. }
  468. return fz_new_stream(ctx, state, next_sgilog24, close_sgilog24);
  469. }
  470. /* SGI Log 32bit */
  471. typedef struct
  472. {
  473. fz_stream *chain;
  474. int run, n, c, w;
  475. uint32_t *temp;
  476. } fz_sgilog32;
  477. static inline void
  478. sgilog32val(fz_context *ctx, uint32_t p, uint8_t *rgb)
  479. {
  480. float r, g, b;
  481. float u, v, s, x, y;
  482. float X, Y, Z;
  483. if (p>>31)
  484. {
  485. X = Y = Z = 0;
  486. }
  487. else
  488. {
  489. int Le = (p>>16) & 0x7fff;
  490. Y = !Le ? 0 : expf(FZ_LN2/256*(Le+.5f) - FZ_LN2*64);
  491. /* decode color */
  492. u = (1.f/UVSCALE) * ((p>>8 & 0xff) + .5f);
  493. v = (1.f/UVSCALE) * ((p & 0xff) + .5f);
  494. s = 6*u - 16*v + 12;
  495. x = 9 * u;
  496. y = 4 * v;
  497. /* convert to XYZ */
  498. X = x/y * Y;
  499. Z = (s-x-y)/y * Y;
  500. }
  501. /* assume CCIR-709 primaries */
  502. r = 2.690f*X + -1.276f*Y + -0.414f*Z;
  503. g = -1.022f*X + 1.978f*Y + 0.044f*Z;
  504. b = 0.061f*X + -0.224f*Y + 1.163f*Z;
  505. /* assume 2.0 gamma for speed */
  506. /* could use integer sqrt approx., but this is probably faster */
  507. rgb[0] = (uint8_t)((r<=0) ? 0 : (r >= 1) ? 255 : (int)(256*sqrtf(r)));
  508. rgb[1] = (uint8_t)((g<=0) ? 0 : (g >= 1) ? 255 : (int)(256*sqrtf(g)));
  509. rgb[2] = (uint8_t)((b<=0) ? 0 : (b >= 1) ? 255 : (int)(256*sqrtf(b)));
  510. }
  511. static int
  512. next_sgilog32(fz_context *ctx, fz_stream *stm, size_t max)
  513. {
  514. fz_sgilog32 *state = stm->state;
  515. uint32_t *p;
  516. uint32_t *ep;
  517. uint8_t *q;
  518. int shift;
  519. (void)max;
  520. if (state->run < 0)
  521. return EOF;
  522. memset(state->temp, 0, state->w * sizeof(uint32_t));
  523. for (shift = 24; shift >= 0; shift -= 8)
  524. {
  525. p = state->temp;
  526. ep = p + state->w;
  527. while (p < ep)
  528. {
  529. if (state->n == 0)
  530. {
  531. state->run = fz_read_byte(ctx, state->chain);
  532. if (state->run < 0)
  533. {
  534. state->run = -1;
  535. fz_throw(ctx, FZ_ERROR_FORMAT, "premature end of data in run length decode");
  536. }
  537. if (state->run < 128)
  538. state->n = state->run;
  539. else
  540. {
  541. state->n = state->run - 126;
  542. state->c = fz_read_byte(ctx, state->chain);
  543. if (state->c < 0)
  544. {
  545. state->run = -1;
  546. fz_throw(ctx, FZ_ERROR_FORMAT, "premature end of data in run length decode");
  547. }
  548. }
  549. }
  550. if (state->run < 128)
  551. {
  552. while (p < ep && state->n)
  553. {
  554. int c = fz_read_byte(ctx, state->chain);
  555. if (c < 0)
  556. {
  557. state->run = -1;
  558. fz_throw(ctx, FZ_ERROR_FORMAT, "premature end of data in run length decode");
  559. }
  560. *p++ |= c<<shift;
  561. state->n--;
  562. }
  563. }
  564. else
  565. {
  566. while (p < ep && state->n)
  567. {
  568. *p++ |= state->c<<shift;
  569. state->n--;
  570. }
  571. }
  572. }
  573. }
  574. p = state->temp;
  575. q = (uint8_t *)p;
  576. ep = p + state->w;
  577. while (p < ep)
  578. {
  579. sgilog32val(ctx, *p++, q);
  580. q += 3;
  581. }
  582. stm->rp = (uint8_t *)(state->temp);
  583. stm->wp = q;
  584. stm->pos += q - stm->rp;
  585. if (q == stm->rp)
  586. return EOF;
  587. return *stm->rp++;
  588. }
  589. static void
  590. close_sgilog32(fz_context *ctx, void *state_)
  591. {
  592. fz_sgilog32 *state = (fz_sgilog32 *)state_;
  593. fz_drop_stream(ctx, state->chain);
  594. fz_free(ctx, state->temp);
  595. fz_free(ctx, state);
  596. }
  597. fz_stream *
  598. fz_open_sgilog32(fz_context *ctx, fz_stream *chain, int w)
  599. {
  600. fz_sgilog32 *state = fz_malloc_struct(ctx, fz_sgilog32);
  601. fz_try(ctx)
  602. {
  603. state->run = 0;
  604. state->n = 0;
  605. state->c = 0;
  606. state->w = w;
  607. state->temp = Memento_label(fz_malloc(ctx, w * sizeof(uint32_t)), "sgilog32_temp");
  608. state->chain = fz_keep_stream(ctx, chain);
  609. }
  610. fz_catch(ctx)
  611. {
  612. fz_free(ctx, state->temp);
  613. fz_free(ctx, state);
  614. fz_rethrow(ctx);
  615. }
  616. return fz_new_stream(ctx, state, next_sgilog32, close_sgilog32);
  617. }