encode-fax.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  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. /* Fax G3/G4 tables */
  24. typedef struct
  25. {
  26. unsigned short code;
  27. unsigned short nbits;
  28. } cfe_code;
  29. typedef struct {
  30. cfe_code termination[64];
  31. cfe_code makeup[41];
  32. } cf_runs;
  33. /* Define the end-of-line code. */
  34. static const cfe_code cf_run_eol = {1, 12};
  35. /* Define the 2-D run codes. */
  36. static const cfe_code cf2_run_pass = {0x1, 4};
  37. static const cfe_code cf2_run_vertical[7] =
  38. {
  39. {0x3, 7},
  40. {0x3, 6},
  41. {0x3, 3},
  42. {0x1, 1},
  43. {0x2, 3},
  44. {0x2, 6},
  45. {0x2, 7}
  46. };
  47. static const cfe_code cf2_run_horizontal = {1, 3};
  48. /* White run codes. */
  49. static const cf_runs cf_white_runs =
  50. {
  51. /* Termination codes */
  52. {
  53. {0x35, 8}, {0x7, 6}, {0x7, 4}, {0x8, 4},
  54. {0xb, 4}, {0xc, 4}, {0xe, 4}, {0xf, 4},
  55. {0x13, 5}, {0x14, 5}, {0x7, 5}, {0x8, 5},
  56. {0x8, 6}, {0x3, 6}, {0x34, 6}, {0x35, 6},
  57. {0x2a, 6}, {0x2b, 6}, {0x27, 7}, {0xc, 7},
  58. {0x8, 7}, {0x17, 7}, {0x3, 7}, {0x4, 7},
  59. {0x28, 7}, {0x2b, 7}, {0x13, 7}, {0x24, 7},
  60. {0x18, 7}, {0x2, 8}, {0x3, 8}, {0x1a, 8},
  61. {0x1b, 8}, {0x12, 8}, {0x13, 8}, {0x14, 8},
  62. {0x15, 8}, {0x16, 8}, {0x17, 8}, {0x28, 8},
  63. {0x29, 8}, {0x2a, 8}, {0x2b, 8}, {0x2c, 8},
  64. {0x2d, 8}, {0x4, 8}, {0x5, 8}, {0xa, 8},
  65. {0xb, 8}, {0x52, 8}, {0x53, 8}, {0x54, 8},
  66. {0x55, 8}, {0x24, 8}, {0x25, 8}, {0x58, 8},
  67. {0x59, 8}, {0x5a, 8}, {0x5b, 8}, {0x4a, 8},
  68. {0x4b, 8}, {0x32, 8}, {0x33, 8}, {0x34, 8}
  69. },
  70. /* Make-up codes */
  71. {
  72. {0, 0} /* dummy */ , {0x1b, 5}, {0x12, 5}, {0x17, 6},
  73. {0x37, 7}, {0x36, 8}, {0x37, 8}, {0x64, 8},
  74. {0x65, 8}, {0x68, 8}, {0x67, 8}, {0xcc, 9},
  75. {0xcd, 9}, {0xd2, 9}, {0xd3, 9}, {0xd4, 9},
  76. {0xd5, 9}, {0xd6, 9}, {0xd7, 9}, {0xd8, 9},
  77. {0xd9, 9}, {0xda, 9}, {0xdb, 9}, {0x98, 9},
  78. {0x99, 9}, {0x9a, 9}, {0x18, 6}, {0x9b, 9},
  79. {0x8, 11}, {0xc, 11}, {0xd, 11}, {0x12, 12},
  80. {0x13, 12}, {0x14, 12}, {0x15, 12}, {0x16, 12},
  81. {0x17, 12}, {0x1c, 12}, {0x1d, 12}, {0x1e, 12},
  82. {0x1f, 12}
  83. }
  84. };
  85. /* Black run codes. */
  86. static const cf_runs cf_black_runs =
  87. {
  88. /* Termination codes */
  89. {
  90. {0x37, 10}, {0x2, 3}, {0x3, 2}, {0x2, 2},
  91. {0x3, 3}, {0x3, 4}, {0x2, 4}, {0x3, 5},
  92. {0x5, 6}, {0x4, 6}, {0x4, 7}, {0x5, 7},
  93. {0x7, 7}, {0x4, 8}, {0x7, 8}, {0x18, 9},
  94. {0x17, 10}, {0x18, 10}, {0x8, 10}, {0x67, 11},
  95. {0x68, 11}, {0x6c, 11}, {0x37, 11}, {0x28, 11},
  96. {0x17, 11}, {0x18, 11}, {0xca, 12}, {0xcb, 12},
  97. {0xcc, 12}, {0xcd, 12}, {0x68, 12}, {0x69, 12},
  98. {0x6a, 12}, {0x6b, 12}, {0xd2, 12}, {0xd3, 12},
  99. {0xd4, 12}, {0xd5, 12}, {0xd6, 12}, {0xd7, 12},
  100. {0x6c, 12}, {0x6d, 12}, {0xda, 12}, {0xdb, 12},
  101. {0x54, 12}, {0x55, 12}, {0x56, 12}, {0x57, 12},
  102. {0x64, 12}, {0x65, 12}, {0x52, 12}, {0x53, 12},
  103. {0x24, 12}, {0x37, 12}, {0x38, 12}, {0x27, 12},
  104. {0x28, 12}, {0x58, 12}, {0x59, 12}, {0x2b, 12},
  105. {0x2c, 12}, {0x5a, 12}, {0x66, 12}, {0x67, 12}
  106. },
  107. /* Make-up codes. */
  108. {
  109. {0, 0} /* dummy */ , {0xf, 10}, {0xc8, 12}, {0xc9, 12},
  110. {0x5b, 12}, {0x33, 12}, {0x34, 12}, {0x35, 12},
  111. {0x6c, 13}, {0x6d, 13}, {0x4a, 13}, {0x4b, 13},
  112. {0x4c, 13}, {0x4d, 13}, {0x72, 13}, {0x73, 13},
  113. {0x74, 13}, {0x75, 13}, {0x76, 13}, {0x77, 13},
  114. {0x52, 13}, {0x53, 13}, {0x54, 13}, {0x55, 13},
  115. {0x5a, 13}, {0x5b, 13}, {0x64, 13}, {0x65, 13},
  116. {0x8, 11}, {0xc, 11}, {0xd, 11}, {0x12, 12},
  117. {0x13, 12}, {0x14, 12}, {0x15, 12}, {0x16, 12},
  118. {0x17, 12}, {0x1c, 12}, {0x1d, 12}, {0x1e, 12},
  119. {0x1f, 12}
  120. }
  121. };
  122. static inline int
  123. getbit(const unsigned char *buf, int x)
  124. {
  125. /* Invert bit to handle BlackIs1=false */
  126. return ( ( buf[x >> 3] >> ( 7 - (x & 7) ) ) & 1 ) ^ 1;
  127. }
  128. static inline int
  129. find_changing(const unsigned char *line, int x, int w)
  130. {
  131. int a, b;
  132. if (!line || x >= w)
  133. return w;
  134. if (x == -1)
  135. {
  136. a = 0;
  137. x = 0;
  138. }
  139. else
  140. {
  141. a = getbit(line, x);
  142. x++;
  143. }
  144. while (x < w)
  145. {
  146. b = getbit(line, x);
  147. if (a != b)
  148. break;
  149. x++;
  150. }
  151. return x;
  152. }
  153. static inline int
  154. find_changing_color(const unsigned char *line, int x, int w, int color)
  155. {
  156. if (!line || x >= w)
  157. return w;
  158. x = find_changing(line, x, w);
  159. if (x < w && getbit(line, x) != color)
  160. x = find_changing(line, x, w);
  161. return x;
  162. }
  163. static inline int
  164. getrun(const unsigned char *line, int x, int w, int c)
  165. {
  166. int z = x;
  167. while (z < w)
  168. {
  169. int b = getbit(line, z);
  170. if (c != b)
  171. break;
  172. ++z;
  173. }
  174. return z - x;
  175. }
  176. static inline void
  177. putcode(fz_context *ctx, fz_buffer *out, const cfe_code *run)
  178. {
  179. fz_append_bits(ctx, out, run->code, run->nbits);
  180. }
  181. static void
  182. putrun(fz_context *ctx, fz_buffer *out, int run, int c)
  183. {
  184. const cf_runs *codetable = c ? &cf_black_runs : &cf_white_runs;
  185. if (run > 63)
  186. {
  187. int m = run >> 6;
  188. while (m > 40)
  189. {
  190. putcode(ctx, out, &codetable->makeup[40]);
  191. m -= 40;
  192. }
  193. if (m > 0)
  194. putcode(ctx, out, &codetable->makeup[m]);
  195. putcode(ctx, out, &codetable->termination[run & 63]);
  196. }
  197. else
  198. {
  199. putcode(ctx, out, &codetable->termination[run]);
  200. }
  201. }
  202. fz_buffer *
  203. fz_compress_ccitt_fax_g4(fz_context *ctx, const unsigned char *src, int columns, int rows, ptrdiff_t stride)
  204. {
  205. fz_buffer *out = fz_new_buffer(ctx, (stride * rows) >> 3);
  206. const unsigned char *ref = NULL;
  207. fz_try(ctx)
  208. {
  209. while (rows-- > 0)
  210. {
  211. int a0 = -1;
  212. int c = 0;
  213. while (a0 < columns)
  214. {
  215. int a1 = find_changing(src, a0, columns);
  216. int b1 = find_changing_color(ref, a0, columns, c^1);
  217. int b2 = find_changing(ref, b1, columns);
  218. int diff = b1 - a1;
  219. if (a0 < 0)
  220. a0 = 0;
  221. /* pass mode */
  222. if (b2 < a1)
  223. {
  224. putcode(ctx, out, &cf2_run_pass);
  225. a0 = b2;
  226. }
  227. /* vertical mode */
  228. else if (diff >= -3 && diff <= 3)
  229. {
  230. putcode(ctx, out, &cf2_run_vertical[diff + 3]);
  231. a0 = a1;
  232. c = c^1;
  233. }
  234. /* horizontal mode */
  235. else
  236. {
  237. int a2 = find_changing(src, a1, columns);
  238. putcode(ctx, out, &cf2_run_horizontal);
  239. putrun(ctx, out, a1 - a0, c);
  240. putrun(ctx, out, a2 - a1, c^1);
  241. a0 = a2;
  242. }
  243. }
  244. ref = src;
  245. src += stride;
  246. }
  247. putcode(ctx, out, &cf_run_eol);
  248. putcode(ctx, out, &cf_run_eol);
  249. }
  250. fz_catch(ctx)
  251. {
  252. fz_drop_buffer(ctx, out);
  253. fz_rethrow(ctx);
  254. }
  255. return out;
  256. }
  257. fz_buffer *
  258. fz_compress_ccitt_fax_g3(fz_context *ctx, const unsigned char *src, int columns, int rows, ptrdiff_t stride)
  259. {
  260. fz_buffer *out = fz_new_buffer(ctx, (stride * rows) >> 3);
  261. int i;
  262. fz_try(ctx)
  263. {
  264. while (rows-- > 0)
  265. {
  266. int a0 = 0;
  267. int c = 0;
  268. while (a0 < columns)
  269. {
  270. int run = getrun(src, a0, columns, c);
  271. putrun(ctx, out, run, c);
  272. a0 += run;
  273. c = c^1;
  274. }
  275. src += stride;
  276. }
  277. for (i = 0; i < 6; ++i)
  278. putcode(ctx, out, &cf_run_eol);
  279. }
  280. fz_catch(ctx)
  281. {
  282. fz_drop_buffer(ctx, out);
  283. fz_rethrow(ctx);
  284. }
  285. return out;
  286. }