jbig2_halftone.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. /* Copyright (C) 2001-2023 Artifex Software, Inc.
  2. All Rights Reserved.
  3. This software is provided AS-IS with no warranty, either express or
  4. implied.
  5. This software is distributed under license and may not be copied,
  6. modified or distributed except as expressly authorized under the terms
  7. of the license contained in the file LICENSE in this distribution.
  8. Refer to licensing information at http://www.artifex.com or contact
  9. Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
  10. CA 94129, USA, for further information.
  11. */
  12. /*
  13. jbig2dec
  14. */
  15. /* JBIG2 Pattern Dictionary and Halftone Region decoding */
  16. #ifdef HAVE_CONFIG_H
  17. #include "config.h"
  18. #endif
  19. #include "os_types.h"
  20. #include <string.h> /* memset() */
  21. #include "jbig2.h"
  22. #include "jbig2_priv.h"
  23. #include "jbig2_arith.h"
  24. #include "jbig2_generic.h"
  25. #include "jbig2_image.h"
  26. #include "jbig2_halftone.h"
  27. #include "jbig2_mmr.h"
  28. #include "jbig2_page.h"
  29. #include "jbig2_segment.h"
  30. /**
  31. * jbig2_hd_new: create a new dictionary from a collective bitmap
  32. */
  33. static Jbig2PatternDict *
  34. jbig2_hd_new(Jbig2Ctx *ctx, const Jbig2PatternDictParams *params, Jbig2Image *image)
  35. {
  36. Jbig2PatternDict *new;
  37. const uint32_t N = params->GRAYMAX + 1;
  38. const uint32_t HPW = params->HDPW;
  39. const uint32_t HPH = params->HDPH;
  40. int code;
  41. uint32_t i, j;
  42. if (N == 0) {
  43. /* We've wrapped. */
  44. jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "params->GRAYMAX out of range");
  45. return NULL;
  46. }
  47. /* allocate a new struct */
  48. new = jbig2_new(ctx, Jbig2PatternDict, 1);
  49. if (new != NULL) {
  50. new->patterns = jbig2_new(ctx, Jbig2Image *, N);
  51. if (new->patterns == NULL) {
  52. jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to allocate pattern in collective bitmap dictionary");
  53. jbig2_free(ctx->allocator, new);
  54. return NULL;
  55. }
  56. new->n_patterns = N;
  57. new->HPW = HPW;
  58. new->HPH = HPH;
  59. /* 6.7.5(4) - copy out the individual pattern images */
  60. for (i = 0; i < N; i++) {
  61. new->patterns[i] = jbig2_image_new(ctx, HPW, HPH);
  62. if (new->patterns[i] == NULL) {
  63. jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to allocate pattern element image");
  64. /* new->patterns[i] above did not succeed, so releasing patterns 0..i-1 is enough */
  65. for (j = 0; j < i; j++)
  66. jbig2_image_release(ctx, new->patterns[j]);
  67. jbig2_free(ctx->allocator, new->patterns);
  68. jbig2_free(ctx->allocator, new);
  69. return NULL;
  70. }
  71. /* compose with the REPLACE operator; the source
  72. will be clipped to the destination, selecting the
  73. proper sub image */
  74. code = jbig2_image_compose(ctx, new->patterns[i], image, -i * (int32_t) HPW, 0, JBIG2_COMPOSE_REPLACE);
  75. if (code < 0) {
  76. jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to compose image into collective bitmap dictionary");
  77. /* new->patterns[i] above succeeded, so release all patterns 0..i */
  78. for (j = 0; j <= i; j++)
  79. jbig2_image_release(ctx, new->patterns[j]);
  80. jbig2_free(ctx->allocator, new->patterns);
  81. jbig2_free(ctx->allocator, new);
  82. return NULL;
  83. }
  84. }
  85. } else {
  86. jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to allocate collective bitmap dictionary");
  87. }
  88. return new;
  89. }
  90. /**
  91. * jbig2_hd_release: release a pattern dictionary
  92. */
  93. void
  94. jbig2_hd_release(Jbig2Ctx *ctx, Jbig2PatternDict *dict)
  95. {
  96. int i;
  97. if (dict == NULL)
  98. return;
  99. if (dict->patterns != NULL)
  100. for (i = 0; i < dict->n_patterns; i++)
  101. jbig2_image_release(ctx, dict->patterns[i]);
  102. jbig2_free(ctx->allocator, dict->patterns);
  103. jbig2_free(ctx->allocator, dict);
  104. }
  105. /**
  106. * jbig2_decode_pattern_dict: decode pattern dictionary data
  107. *
  108. * @ctx: jbig2 decoder context
  109. * @segment: jbig2 segment (header) structure
  110. * @params: parameters from the pattern dictionary header
  111. * @data: pointer to text region data to be decoded
  112. * @size: length of text region data
  113. * @GB_stats: arithmetic coding context to use
  114. *
  115. * Implements the pattern dictionary decoding procedure
  116. * described in section 6.7 of the JBIG2 spec.
  117. *
  118. * returns: a pointer to the resulting dictionary on success
  119. * returns: 0 on failure
  120. **/
  121. static Jbig2PatternDict *
  122. jbig2_decode_pattern_dict(Jbig2Ctx *ctx, Jbig2Segment *segment,
  123. const Jbig2PatternDictParams *params, const byte *data, const size_t size, Jbig2ArithCx *GB_stats)
  124. {
  125. Jbig2PatternDict *hd = NULL;
  126. Jbig2Image *image = NULL;
  127. Jbig2GenericRegionParams rparams;
  128. int code = 0;
  129. /* allocate the collective image */
  130. image = jbig2_image_new(ctx, params->HDPW * (params->GRAYMAX + 1), params->HDPH);
  131. if (image == NULL) {
  132. jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to allocate collective bitmap for halftone dictionary");
  133. return NULL;
  134. }
  135. /* fill out the generic region decoder parameters */
  136. rparams.MMR = params->HDMMR;
  137. rparams.GBTEMPLATE = params->HDTEMPLATE;
  138. rparams.TPGDON = 0; /* not used if HDMMR = 1 */
  139. rparams.USESKIP = 0;
  140. rparams.gbat[0] = -(int8_t) params->HDPW;
  141. rparams.gbat[1] = 0;
  142. rparams.gbat[2] = -3;
  143. rparams.gbat[3] = -1;
  144. rparams.gbat[4] = 2;
  145. rparams.gbat[5] = -2;
  146. rparams.gbat[6] = -2;
  147. rparams.gbat[7] = -2;
  148. if (params->HDMMR) {
  149. code = jbig2_decode_generic_mmr(ctx, segment, &rparams, data, size, image);
  150. } else {
  151. Jbig2WordStream *ws = jbig2_word_stream_buf_new(ctx, data, size);
  152. if (ws != NULL) {
  153. Jbig2ArithState *as = jbig2_arith_new(ctx, ws);
  154. if (as != NULL) {
  155. code = jbig2_decode_generic_region(ctx, segment, &rparams, as, image, GB_stats);
  156. } else {
  157. code = jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to allocate arithmetic coding state when handling halftone dictionary");
  158. }
  159. jbig2_free(ctx->allocator, as);
  160. jbig2_word_stream_buf_free(ctx, ws);
  161. } else {
  162. code = jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to allocate word stream when handling halftone dictionary");
  163. }
  164. }
  165. if (code == 0)
  166. hd = jbig2_hd_new(ctx, params, image);
  167. else
  168. jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode immediate generic region");
  169. jbig2_image_release(ctx, image);
  170. return hd;
  171. }
  172. /* 7.4.4 */
  173. int
  174. jbig2_pattern_dictionary(Jbig2Ctx *ctx, Jbig2Segment *segment, const byte *segment_data)
  175. {
  176. Jbig2PatternDictParams params;
  177. Jbig2ArithCx *GB_stats = NULL;
  178. byte flags;
  179. int offset = 0;
  180. /* 7.4.4.1 - Data header */
  181. if (segment->data_length < 7) {
  182. return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "segment too short");
  183. }
  184. flags = segment_data[0];
  185. params.HDMMR = flags & 1;
  186. params.HDTEMPLATE = (flags & 6) >> 1;
  187. params.HDPW = segment_data[1];
  188. params.HDPH = segment_data[2];
  189. params.GRAYMAX = jbig2_get_uint32(segment_data + 3);
  190. offset += 7;
  191. jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
  192. "pattern dictionary, flags=%02x, %d grays (%dx%d cell)", flags, params.GRAYMAX + 1, params.HDPW, params.HDPH);
  193. if (params.HDMMR && params.HDTEMPLATE) {
  194. jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "HDTEMPLATE is %d when HDMMR is %d, contrary to spec", params.HDTEMPLATE, params.HDMMR);
  195. }
  196. if (flags & 0xf8) {
  197. jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "reserved flag bits non-zero");
  198. }
  199. /* 7.4.4.2 */
  200. if (!params.HDMMR) {
  201. /* allocate and zero arithmetic coding stats */
  202. int stats_size = jbig2_generic_stats_size(ctx, params.HDTEMPLATE);
  203. GB_stats = jbig2_new(ctx, Jbig2ArithCx, stats_size);
  204. if (GB_stats == NULL)
  205. return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to allocate arithmetic coding state when handling pattern dictionary");
  206. memset(GB_stats, 0, stats_size);
  207. }
  208. segment->result = jbig2_decode_pattern_dict(ctx, segment, &params, segment_data + offset, segment->data_length - offset, GB_stats);
  209. /* todo: retain GB_stats? */
  210. if (!params.HDMMR) {
  211. jbig2_free(ctx->allocator, GB_stats);
  212. }
  213. return (segment->result != NULL) ? 0 : -1;
  214. }
  215. /**
  216. * jbig2_decode_gray_scale_image: decode gray-scale image
  217. *
  218. * @ctx: jbig2 decoder context
  219. * @segment: jbig2 segment (header) structure
  220. * @data: pointer to text region data to be decoded
  221. * @size: length of text region data
  222. * @GSMMR: if MMR is used
  223. * @GSW: width of gray-scale image
  224. * @GSH: height of gray-scale image
  225. * @GSBPP: number of bitplanes/Jbig2Images to use
  226. * @GSKIP: mask indicating which values should be skipped
  227. * @GSTEMPLATE: template used to code the gray-scale bitplanes
  228. * @GB_stats: arithmetic coding context to use
  229. *
  230. * Implements the decoding a gray-scale image described in
  231. * annex C.5. This is part of the halftone region decoding.
  232. *
  233. * returns: array of gray-scale values with GSW x GSH width/height
  234. * 0 on failure
  235. **/
  236. static uint16_t **
  237. jbig2_decode_gray_scale_image(Jbig2Ctx *ctx, Jbig2Segment *segment,
  238. const byte *data, const size_t size,
  239. bool GSMMR, uint32_t GSW, uint32_t GSH,
  240. uint32_t GSBPP, bool GSUSESKIP, Jbig2Image *GSKIP, int GSTEMPLATE, Jbig2ArithCx *GB_stats)
  241. {
  242. uint16_t **GSVALS = NULL;
  243. size_t consumed_bytes = 0;
  244. uint32_t i, j, stride, x, y;
  245. int code;
  246. Jbig2Image **GSPLANES;
  247. Jbig2GenericRegionParams rparams;
  248. Jbig2WordStream *ws = NULL;
  249. Jbig2ArithState *as = NULL;
  250. /* allocate GSPLANES */
  251. GSPLANES = jbig2_new(ctx, Jbig2Image *, GSBPP);
  252. if (GSPLANES == NULL) {
  253. jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to allocate %d bytes for GSPLANES", GSBPP);
  254. return NULL;
  255. }
  256. for (i = 0; i < GSBPP; ++i) {
  257. GSPLANES[i] = jbig2_image_new(ctx, GSW, GSH);
  258. if (GSPLANES[i] == NULL) {
  259. jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to allocate %dx%d image for GSPLANES", GSW, GSH);
  260. /* free already allocated */
  261. for (j = i; j > 0;)
  262. jbig2_image_release(ctx, GSPLANES[--j]);
  263. jbig2_free(ctx->allocator, GSPLANES);
  264. return NULL;
  265. }
  266. }
  267. /* C.5 step 1. Decode GSPLANES[GSBPP-1] */
  268. /* fill generic region decoder parameters */
  269. rparams.MMR = GSMMR;
  270. rparams.GBTEMPLATE = GSTEMPLATE;
  271. rparams.TPGDON = 0;
  272. rparams.USESKIP = GSUSESKIP;
  273. rparams.SKIP = GSKIP;
  274. rparams.gbat[0] = (GSTEMPLATE <= 1 ? 3 : 2);
  275. rparams.gbat[1] = -1;
  276. rparams.gbat[2] = -3;
  277. rparams.gbat[3] = -1;
  278. rparams.gbat[4] = 2;
  279. rparams.gbat[5] = -2;
  280. rparams.gbat[6] = -2;
  281. rparams.gbat[7] = -2;
  282. if (GSMMR) {
  283. code = jbig2_decode_halftone_mmr(ctx, &rparams, data, size, GSPLANES[GSBPP - 1], &consumed_bytes);
  284. } else {
  285. ws = jbig2_word_stream_buf_new(ctx, data, size);
  286. if (ws == NULL) {
  287. jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to allocate word stream when decoding gray scale image");
  288. goto cleanup;
  289. }
  290. as = jbig2_arith_new(ctx, ws);
  291. if (as == NULL) {
  292. jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to allocate arithmetic coding state when decoding gray scale image");
  293. goto cleanup;
  294. }
  295. code = jbig2_decode_generic_region(ctx, segment, &rparams, as, GSPLANES[GSBPP - 1], GB_stats);
  296. }
  297. if (code < 0) {
  298. jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "error decoding GSPLANES for halftone image");
  299. goto cleanup;
  300. }
  301. /* C.5 step 2. Set j = GSBPP-2 */
  302. j = GSBPP - 1;
  303. /* C.5 step 3. decode loop */
  304. while (j > 0) {
  305. j--;
  306. /* C.5 step 3. (a) */
  307. if (GSMMR) {
  308. code = jbig2_decode_halftone_mmr(ctx, &rparams, data + consumed_bytes, size - consumed_bytes, GSPLANES[j], &consumed_bytes);
  309. } else {
  310. code = jbig2_decode_generic_region(ctx, segment, &rparams, as, GSPLANES[j], GB_stats);
  311. }
  312. if (code < 0) {
  313. jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode GSPLANES for halftone image");
  314. goto cleanup;
  315. }
  316. /* C.5 step 3. (b):
  317. * for each [x,y]
  318. * GSPLANES[j][x][y] = GSPLANES[j+1][x][y] XOR GSPLANES[j][x][y] */
  319. stride = GSPLANES[j]->stride;
  320. for (i = 0; i < stride * GSH; ++i)
  321. GSPLANES[j]->data[i] ^= GSPLANES[j + 1]->data[i];
  322. /* C.5 step 3. (c) */
  323. }
  324. /* allocate GSVALS */
  325. GSVALS = jbig2_new(ctx, uint16_t *, GSW);
  326. if (GSVALS == NULL) {
  327. jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to allocate GSVALS: %d bytes", GSW);
  328. goto cleanup;
  329. }
  330. for (i = 0; i < GSW; ++i) {
  331. GSVALS[i] = jbig2_new(ctx, uint16_t, GSH);
  332. if (GSVALS[i] == NULL) {
  333. jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to allocate GSVALS: %d bytes", GSH * GSW);
  334. /* free already allocated */
  335. for (j = i; j > 0;)
  336. jbig2_free(ctx->allocator, GSVALS[--j]);
  337. jbig2_free(ctx->allocator, GSVALS);
  338. GSVALS = NULL;
  339. goto cleanup;
  340. }
  341. }
  342. /* C.5 step 4. */
  343. for (x = 0; x < GSW; ++x) {
  344. for (y = 0; y < GSH; ++y) {
  345. GSVALS[x][y] = 0;
  346. for (j = 0; j < GSBPP; ++j)
  347. GSVALS[x][y] += jbig2_image_get_pixel(GSPLANES[j], x, y) << j;
  348. }
  349. }
  350. cleanup:
  351. /* free memory */
  352. if (!GSMMR) {
  353. jbig2_free(ctx->allocator, as);
  354. jbig2_word_stream_buf_free(ctx, ws);
  355. }
  356. for (i = 0; i < GSBPP; ++i)
  357. jbig2_image_release(ctx, GSPLANES[i]);
  358. jbig2_free(ctx->allocator, GSPLANES);
  359. return GSVALS;
  360. }
  361. /**
  362. * jbig2_decode_ht_region_get_hpats: get pattern dictionary
  363. *
  364. * @ctx: jbig2 decoder context
  365. * @segment: jbig2 halftone region segment
  366. *
  367. * Returns the first referred pattern dictionary of segment
  368. *
  369. * returns: pattern dictionary
  370. * 0 if search failed
  371. **/
  372. static Jbig2PatternDict *
  373. jbig2_decode_ht_region_get_hpats(Jbig2Ctx *ctx, Jbig2Segment *segment)
  374. {
  375. int index = 0;
  376. Jbig2PatternDict *pattern_dict = NULL;
  377. Jbig2Segment *rsegment = NULL;
  378. /* loop through all referred segments */
  379. while (!pattern_dict && segment->referred_to_segment_count > index) {
  380. rsegment = jbig2_find_segment(ctx, segment->referred_to_segments[index]);
  381. if (rsegment) {
  382. /* segment type is pattern dictionary and result is not empty */
  383. if ((rsegment->flags & 0x3f) == 16 && rsegment->result) {
  384. pattern_dict = (Jbig2PatternDict *) rsegment->result;
  385. return pattern_dict;
  386. }
  387. }
  388. index++;
  389. }
  390. return pattern_dict;
  391. }
  392. /**
  393. * jbig2_decode_halftone_region: decode a halftone region
  394. *
  395. * @ctx: jbig2 decoder context
  396. * @segment: jbig2 halftone region segment
  397. * @params: parameters
  398. * @data: pointer to halftone region data to be decoded
  399. * @size: length of halftone region data
  400. * @GB_stats: arithmetic coding context to use
  401. *
  402. * Implements the halftone region decoding procedure
  403. * described in section 6.6.5 of the JBIG2 spec.
  404. *
  405. * returns: 0 on success
  406. * <0 on failure
  407. **/
  408. static int
  409. jbig2_decode_halftone_region(Jbig2Ctx *ctx, Jbig2Segment *segment,
  410. Jbig2HalftoneRegionParams *params, const byte *data, const size_t size, Jbig2Image *image, Jbig2ArithCx *GB_stats)
  411. {
  412. uint32_t HBPP;
  413. uint32_t HNUMPATS;
  414. uint16_t **GI = NULL;
  415. Jbig2Image *HSKIP = NULL;
  416. Jbig2PatternDict *HPATS;
  417. uint32_t i;
  418. uint32_t mg, ng;
  419. uint16_t gray_val;
  420. int code = 0;
  421. /* We need the patterns used in this region, get them from the referred pattern dictionary */
  422. HPATS = jbig2_decode_ht_region_get_hpats(ctx, segment);
  423. if (!HPATS) {
  424. code = jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "no pattern dictionary found, skipping halftone image");
  425. goto cleanup;
  426. }
  427. /* 6.6.5 point 1. Fill bitmap with HDEFPIXEL */
  428. memset(image->data, params->HDEFPIXEL, image->stride * image->height);
  429. /* 6.6.5 point 2. compute HSKIP according to 6.6.5.1 */
  430. if (params->HENABLESKIP == 1) {
  431. HSKIP = jbig2_image_new(ctx, params->HGW, params->HGH);
  432. if (HSKIP == NULL)
  433. return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to allocate skip image");
  434. for (mg = 0; mg < params->HGH; ++mg) {
  435. for (ng = 0; ng < params->HGW; ++ng) {
  436. int64_t x = ((int64_t) params->HGX + mg * params->HRY + ng * params->HRX) >> 8;
  437. int64_t y = ((int64_t) params->HGY + mg * params->HRX - ng * params->HRY) >> 8;
  438. if (x + HPATS->HPW <= 0 || x >= image->width || y + HPATS->HPH <= 0 || y >= image->height) {
  439. jbig2_image_set_pixel(HSKIP, ng, mg, 1);
  440. } else {
  441. jbig2_image_set_pixel(HSKIP, ng, mg, 0);
  442. }
  443. }
  444. }
  445. }
  446. /* 6.6.5 point 3. set HBPP to ceil(log2(HNUMPATS)): */
  447. HNUMPATS = HPATS->n_patterns;
  448. HBPP = 0;
  449. while (HNUMPATS > (1U << ++HBPP));
  450. if (HBPP > 16) {
  451. code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "HBPP is larger than supported (%u)", HBPP);
  452. goto cleanup;
  453. }
  454. /* 6.6.5 point 4. decode gray-scale image as mentioned in annex C */
  455. GI = jbig2_decode_gray_scale_image(ctx, segment, data, size,
  456. params->HMMR, params->HGW, params->HGH, HBPP, params->HENABLESKIP, HSKIP, params->HTEMPLATE, GB_stats);
  457. if (!GI) {
  458. code = jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "unable to acquire gray-scale image, skipping halftone image");
  459. goto cleanup;
  460. }
  461. /* 6.6.5 point 5. place patterns with procedure mentioned in 6.6.5.2 */
  462. for (mg = 0; mg < params->HGH; ++mg) {
  463. for (ng = 0; ng < params->HGW; ++ng) {
  464. int64_t x = ((int64_t) params->HGX + mg * params->HRY + ng * params->HRX) >> 8;
  465. int64_t y = ((int64_t) params->HGY + mg * params->HRX - ng * params->HRY) >> 8;
  466. /* prevent pattern index >= HNUMPATS */
  467. gray_val = GI[ng][mg];
  468. if (gray_val >= HNUMPATS) {
  469. jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "gray-scale index %d out of range, using largest index", gray_val);
  470. /* use highest available pattern */
  471. gray_val = HNUMPATS - 1;
  472. }
  473. code = jbig2_image_compose(ctx, image, HPATS->patterns[gray_val], x, y, params->HCOMBOP);
  474. if (code < 0) {
  475. code = jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to compose pattern with gray-scale image");
  476. goto cleanup;
  477. }
  478. }
  479. }
  480. cleanup:
  481. if (GI) {
  482. for (i = 0; i < params->HGW; ++i) {
  483. jbig2_free(ctx->allocator, GI[i]);
  484. }
  485. }
  486. jbig2_free(ctx->allocator, GI);
  487. jbig2_image_release(ctx, HSKIP);
  488. return code;
  489. }
  490. /**
  491. * jbig2_halftone_region: read a halftone region segment header
  492. **/
  493. int
  494. jbig2_halftone_region(Jbig2Ctx *ctx, Jbig2Segment *segment, const byte *segment_data)
  495. {
  496. int offset = 0;
  497. Jbig2RegionSegmentInfo region_info;
  498. Jbig2HalftoneRegionParams params;
  499. Jbig2Image *image = NULL;
  500. Jbig2ArithCx *GB_stats = NULL;
  501. int code = 0;
  502. /* 7.4.5.1 */
  503. if (segment->data_length < 17)
  504. goto too_short;
  505. jbig2_get_region_segment_info(&region_info, segment_data);
  506. offset += 17;
  507. if (segment->data_length < 18)
  508. goto too_short;
  509. /* 7.4.5.1.1 Figure 42 */
  510. params.flags = segment_data[offset];
  511. params.HMMR = params.flags & 1;
  512. params.HTEMPLATE = (params.flags & 6) >> 1;
  513. params.HENABLESKIP = (params.flags & 8) >> 3;
  514. params.HCOMBOP = (Jbig2ComposeOp)((params.flags & 0x70) >> 4);
  515. params.HDEFPIXEL = (params.flags & 0x80) >> 7;
  516. offset += 1;
  517. jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
  518. "halftone region: %u x %u @ (%u, %u), flags = %02x", region_info.width, region_info.height, region_info.x, region_info.y, params.flags);
  519. if (params.HMMR && params.HTEMPLATE) {
  520. jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "HTEMPLATE is %d when HMMR is %d, contrary to spec", params.HTEMPLATE, params.HMMR);
  521. }
  522. if (params.HMMR && params.HENABLESKIP) {
  523. jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "HENABLESKIP is %d when HMMR is %d, contrary to spec", params.HENABLESKIP, params.HMMR);
  524. }
  525. /* 7.4.5.1.2 Figure 43 */
  526. if (segment->data_length - offset < 16)
  527. goto too_short;
  528. params.HGW = jbig2_get_uint32(segment_data + offset);
  529. params.HGH = jbig2_get_uint32(segment_data + offset + 4);
  530. params.HGX = jbig2_get_int32(segment_data + offset + 8);
  531. params.HGY = jbig2_get_int32(segment_data + offset + 12);
  532. offset += 16;
  533. /* 7.4.5.1.3 Figure 44 */
  534. if (segment->data_length - offset < 4)
  535. goto too_short;
  536. params.HRX = jbig2_get_uint16(segment_data + offset);
  537. params.HRY = jbig2_get_uint16(segment_data + offset + 2);
  538. offset += 4;
  539. jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
  540. "grid %d x %d @ (%d.%d,%d.%d) vector (%d.%d,%d.%d)",
  541. params.HGW, params.HGH,
  542. params.HGX >> 8, params.HGX & 0xff,
  543. params.HGY >> 8, params.HGY & 0xff,
  544. params.HRX >> 8, params.HRX & 0xff,
  545. params.HRY >> 8, params.HRY & 0xff);
  546. /* 7.4.5.2 */
  547. if (!params.HMMR) {
  548. /* allocate and zero arithmetic coding stats */
  549. int stats_size = jbig2_generic_stats_size(ctx, params.HTEMPLATE);
  550. GB_stats = jbig2_new(ctx, Jbig2ArithCx, stats_size);
  551. if (GB_stats == NULL) {
  552. return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to allocate arithmetic decoder states in halftone region");
  553. }
  554. memset(GB_stats, 0, stats_size);
  555. }
  556. image = jbig2_image_new(ctx, region_info.width, region_info.height);
  557. if (image == NULL) {
  558. jbig2_free(ctx->allocator, GB_stats);
  559. return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to allocate halftone image");
  560. }
  561. code = jbig2_decode_halftone_region(ctx, segment, &params, segment_data + offset, segment->data_length - offset, image, GB_stats);
  562. if (code < 0) {
  563. jbig2_image_release(ctx, image);
  564. jbig2_free(ctx->allocator, GB_stats);
  565. return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode halftone region");
  566. }
  567. /* todo: retain GB_stats? */
  568. if (!params.HMMR) {
  569. jbig2_free(ctx->allocator, GB_stats);
  570. }
  571. code = jbig2_page_add_result(ctx, &ctx->pages[ctx->current_page], image, region_info.x, region_info.y, region_info.op);
  572. if (code < 0) {
  573. jbig2_image_release(ctx, image);
  574. return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "unable to add halftone region to page");
  575. }
  576. jbig2_image_release(ctx, image);
  577. return code;
  578. too_short:
  579. return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "segment too short");
  580. }