CCITTDecoder.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. /*
  2. * Copyright (c) 2023, Lucas Chollet <lucas.chollet@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/Array.h>
  7. #include <AK/BitStream.h>
  8. #include <AK/MemoryStream.h>
  9. #include <LibGfx/Color.h>
  10. #include <LibGfx/ImageFormats/CCITTDecoder.h>
  11. namespace Gfx::CCITT {
  12. namespace {
  13. struct Code {
  14. u16 run_length {};
  15. u8 code_length {};
  16. u16 code {};
  17. };
  18. // Table 2/T.4 – Terminating codes
  19. constexpr Array white_terminating_codes = {
  20. Code { 0, 8, 0b00110101 },
  21. Code { 1, 6, 0b000111 },
  22. Code { 2, 4, 0b0111 },
  23. Code { 3, 4, 0b1000 },
  24. Code { 4, 4, 0b1011 },
  25. Code { 5, 4, 0b1100 },
  26. Code { 6, 4, 0b1110 },
  27. Code { 7, 4, 0b1111 },
  28. Code { 8, 5, 0b10011 },
  29. Code { 9, 5, 0b10100 },
  30. Code { 10, 5, 0b00111 },
  31. Code { 11, 5, 0b01000 },
  32. Code { 12, 6, 0b001000 },
  33. Code { 13, 6, 0b000011 },
  34. Code { 14, 6, 0b110100 },
  35. Code { 15, 6, 0b110101 },
  36. Code { 16, 6, 0b101010 },
  37. Code { 17, 6, 0b101011 },
  38. Code { 18, 7, 0b0100111 },
  39. Code { 19, 7, 0b0001100 },
  40. Code { 20, 7, 0b0001000 },
  41. Code { 21, 7, 0b0010111 },
  42. Code { 22, 7, 0b0000011 },
  43. Code { 23, 7, 0b0000100 },
  44. Code { 24, 7, 0b0101000 },
  45. Code { 25, 7, 0b0101011 },
  46. Code { 26, 7, 0b0010011 },
  47. Code { 27, 7, 0b0100100 },
  48. Code { 28, 7, 0b0011000 },
  49. Code { 29, 8, 0b00000010 },
  50. Code { 30, 8, 0b00000011 },
  51. Code { 31, 8, 0b00011010 },
  52. Code { 32, 8, 0b00011011 },
  53. Code { 33, 8, 0b00010010 },
  54. Code { 34, 8, 0b00010011 },
  55. Code { 35, 8, 0b00010100 },
  56. Code { 36, 8, 0b00010101 },
  57. Code { 37, 8, 0b00010110 },
  58. Code { 38, 8, 0b00010111 },
  59. Code { 39, 8, 0b00101000 },
  60. Code { 40, 8, 0b00101001 },
  61. Code { 41, 8, 0b00101010 },
  62. Code { 42, 8, 0b00101011 },
  63. Code { 43, 8, 0b00101100 },
  64. Code { 44, 8, 0b00101101 },
  65. Code { 45, 8, 0b00000100 },
  66. Code { 46, 8, 0b00000101 },
  67. Code { 47, 8, 0b00001010 },
  68. Code { 48, 8, 0b00001011 },
  69. Code { 49, 8, 0b01010010 },
  70. Code { 50, 8, 0b01010011 },
  71. Code { 51, 8, 0b01010100 },
  72. Code { 52, 8, 0b01010101 },
  73. Code { 53, 8, 0b00100100 },
  74. Code { 54, 8, 0b00100101 },
  75. Code { 55, 8, 0b01011000 },
  76. Code { 56, 8, 0b01011001 },
  77. Code { 57, 8, 0b01011010 },
  78. Code { 58, 8, 0b01011011 },
  79. Code { 59, 8, 0b01001010 },
  80. Code { 60, 8, 0b01001011 },
  81. Code { 61, 8, 0b00110010 },
  82. Code { 62, 8, 0b00110011 },
  83. Code { 63, 8, 0b00110100 },
  84. };
  85. // Table 2/T.4 – Terminating codes
  86. constexpr Array black_terminating_codes = {
  87. Code { 0, 10, 0b0000110111 },
  88. Code { 1, 3, 0b010 },
  89. Code { 2, 2, 0b11 },
  90. Code { 3, 2, 0b10 },
  91. Code { 4, 3, 0b011 },
  92. Code { 5, 4, 0b0011 },
  93. Code { 6, 4, 0b0010 },
  94. Code { 7, 5, 0b00011 },
  95. Code { 8, 6, 0b000101 },
  96. Code { 9, 6, 0b000100 },
  97. Code { 10, 7, 0b0000100 },
  98. Code { 11, 7, 0b0000101 },
  99. Code { 12, 7, 0b0000111 },
  100. Code { 13, 8, 0b00000100 },
  101. Code { 14, 8, 0b00000111 },
  102. Code { 15, 9, 0b000011000 },
  103. Code { 16, 10, 0b0000010111 },
  104. Code { 17, 10, 0b0000011000 },
  105. Code { 18, 10, 0b0000001000 },
  106. Code { 19, 11, 0b00001100111 },
  107. Code { 20, 11, 0b00001101000 },
  108. Code { 21, 11, 0b00001101100 },
  109. Code { 22, 11, 0b00000110111 },
  110. Code { 23, 11, 0b00000101000 },
  111. Code { 24, 11, 0b00000010111 },
  112. Code { 25, 11, 0b00000011000 },
  113. Code { 26, 12, 0b000011001010 },
  114. Code { 27, 12, 0b000011001011 },
  115. Code { 28, 12, 0b000011001100 },
  116. Code { 29, 12, 0b000011001101 },
  117. Code { 30, 12, 0b000001101000 },
  118. Code { 31, 12, 0b000001101001 },
  119. Code { 32, 12, 0b000001101010 },
  120. Code { 33, 12, 0b000001101011 },
  121. Code { 34, 12, 0b000011010010 },
  122. Code { 35, 12, 0b000011010011 },
  123. Code { 36, 12, 0b000011010100 },
  124. Code { 37, 12, 0b000011010101 },
  125. Code { 38, 12, 0b000011010110 },
  126. Code { 39, 12, 0b000011010111 },
  127. Code { 40, 12, 0b000001101100 },
  128. Code { 41, 12, 0b000001101101 },
  129. Code { 42, 12, 0b000011011010 },
  130. Code { 43, 12, 0b000011011011 },
  131. Code { 44, 12, 0b000001010100 },
  132. Code { 45, 12, 0b000001010101 },
  133. Code { 46, 12, 0b000001010110 },
  134. Code { 47, 12, 0b000001010111 },
  135. Code { 48, 12, 0b000001100100 },
  136. Code { 49, 12, 0b000001100101 },
  137. Code { 50, 12, 0b000001010010 },
  138. Code { 51, 12, 0b000001010011 },
  139. Code { 52, 12, 0b000000100100 },
  140. Code { 53, 12, 0b000000110111 },
  141. Code { 54, 12, 0b000000111000 },
  142. Code { 55, 12, 0b000000100111 },
  143. Code { 56, 12, 0b000000101000 },
  144. Code { 57, 12, 0b000001011000 },
  145. Code { 58, 12, 0b000001011001 },
  146. Code { 59, 12, 0b000000101011 },
  147. Code { 60, 12, 0b000000101100 },
  148. Code { 61, 12, 0b000001011010 },
  149. Code { 62, 12, 0b000001100110 },
  150. Code { 63, 12, 0b000001100111 },
  151. };
  152. // Table 3a/T.4 – Make-up codes
  153. constexpr Array white_make_up_codes = {
  154. Code { 64, 5, 0b11011 },
  155. Code { 128, 5, 0b10010 },
  156. Code { 192, 6, 0b010111 },
  157. Code { 256, 7, 0b0110111 },
  158. Code { 320, 8, 0b00110110 },
  159. Code { 384, 8, 0b00110111 },
  160. Code { 448, 8, 0b01100100 },
  161. Code { 512, 8, 0b01100101 },
  162. Code { 576, 8, 0b01101000 },
  163. Code { 640, 8, 0b01100111 },
  164. Code { 704, 9, 0b011001100 },
  165. Code { 768, 9, 0b011001101 },
  166. Code { 832, 9, 0b011010010 },
  167. Code { 896, 9, 0b011010011 },
  168. Code { 960, 9, 0b011010100 },
  169. Code { 1024, 9, 0b011010101 },
  170. Code { 1088, 9, 0b011010110 },
  171. Code { 1152, 9, 0b011010111 },
  172. Code { 1216, 9, 0b011011000 },
  173. Code { 1280, 9, 0b011011001 },
  174. Code { 1344, 9, 0b011011010 },
  175. Code { 1408, 9, 0b011011011 },
  176. Code { 1472, 9, 0b010011000 },
  177. Code { 1536, 9, 0b010011001 },
  178. Code { 1600, 9, 0b010011010 },
  179. Code { 1664, 6, 0b011000 },
  180. Code { 1728, 9, 0b010011011 },
  181. Code { 0xE0L, 12, 0b000000000001 },
  182. };
  183. // Table 3a/T.4 – Make-up codes
  184. constexpr Array black_make_up_codes = {
  185. Code { 64, 10, 0b0000001111 },
  186. Code { 128, 12, 0b000011001000 },
  187. Code { 192, 12, 0b000011001001 },
  188. Code { 256, 12, 0b000001011011 },
  189. Code { 320, 12, 0b000000110011 },
  190. Code { 384, 12, 0b000000110100 },
  191. Code { 448, 12, 0b000000110101 },
  192. Code { 512, 13, 0b0000001101100 },
  193. Code { 576, 13, 0b0000001101101 },
  194. Code { 640, 13, 0b0000001001010 },
  195. Code { 704, 13, 0b0000001001011 },
  196. Code { 768, 13, 0b0000001001100 },
  197. Code { 832, 13, 0b0000001001101 },
  198. Code { 896, 13, 0b0000001110010 },
  199. Code { 960, 13, 0b0000001110011 },
  200. Code { 1024, 13, 0b0000001110100 },
  201. Code { 1088, 13, 0b0000001110101 },
  202. Code { 1152, 13, 0b0000001110110 },
  203. Code { 1216, 13, 0b0000001110111 },
  204. Code { 1280, 13, 0b0000001010010 },
  205. Code { 1344, 13, 0b0000001010011 },
  206. Code { 1408, 13, 0b0000001010100 },
  207. Code { 1472, 13, 0b0000001010101 },
  208. Code { 1536, 13, 0b0000001011010 },
  209. Code { 1600, 13, 0b0000001011011 },
  210. Code { 1664, 13, 0b0000001100100 },
  211. Code { 1728, 13, 0b0000001100101 },
  212. Code { 0xE0L, 11, 0b00000000000 },
  213. };
  214. // Table 3b/T.4 – Make-up codes
  215. constexpr Array common_make_up_codes = {
  216. Code { 1792, 11, 0b00000001000 },
  217. Code { 1856, 11, 0b00000001100 },
  218. Code { 1920, 11, 0b00000001101 },
  219. Code { 1984, 12, 0b000000010010 },
  220. Code { 2048, 12, 0b000000010011 },
  221. Code { 2112, 12, 0b000000010100 },
  222. Code { 2176, 12, 0b000000010101 },
  223. Code { 2240, 12, 0b000000010110 },
  224. Code { 2304, 12, 0b000000010111 },
  225. Code { 2368, 12, 0b000000011100 },
  226. Code { 2432, 12, 0b000000011101 },
  227. Code { 2496, 12, 0b000000011110 },
  228. Code { 2560, 12, 0b000000011111 },
  229. };
  230. template<typename T, size_t Size>
  231. Optional<T> get_code_from_table(Array<T, Size> const& array, u16 code_word, u8 code_size)
  232. {
  233. for (auto const& code : array) {
  234. if (code.code_length == code_size && code.code == code_word)
  235. return code;
  236. }
  237. return OptionalNone {};
  238. }
  239. Optional<Code> get_markup_code(Color color, u16 code_word, u8 code_size)
  240. {
  241. if (auto maybe_value = get_code_from_table(common_make_up_codes, code_word, code_size); maybe_value.has_value())
  242. return maybe_value.value();
  243. if (color == Color::NamedColor::White)
  244. return get_code_from_table(white_make_up_codes, code_word, code_size);
  245. return get_code_from_table(black_make_up_codes, code_word, code_size);
  246. }
  247. Optional<Code> get_terminal_code(Color color, u16 code_word, u8 code_size)
  248. {
  249. if (color == Color::NamedColor::White)
  250. return get_code_from_table(white_terminating_codes, code_word, code_size);
  251. return get_code_from_table(black_terminating_codes, code_word, code_size);
  252. }
  253. constexpr auto const ccitt_white = Color::NamedColor::White;
  254. constexpr auto const ccitt_black = Color::NamedColor::Black;
  255. Color invert(Color current_color)
  256. {
  257. return current_color == ccitt_white ? ccitt_black : ccitt_white;
  258. }
  259. struct Change {
  260. Color color;
  261. u32 column;
  262. };
  263. using ReferenceLine = Vector<Change>;
  264. ErrorOr<u32> read_run_length(BigEndianInputBitStream& input_bit_stream, Optional<ReferenceLine&> reference_line, Color current_color, u32 image_width, u32 column)
  265. {
  266. u8 size {};
  267. u16 potential_code {};
  268. u32 run_length {};
  269. while (size < 14) {
  270. potential_code <<= 1;
  271. potential_code |= TRY(input_bit_stream.read_bit());
  272. size++;
  273. if (auto const maybe_markup = get_markup_code(current_color, potential_code, size); maybe_markup.has_value()) {
  274. run_length += maybe_markup->run_length;
  275. // OK, let's reset the loop to read a terminal code now
  276. size = 0;
  277. potential_code = 0;
  278. } else if (auto const maybe_terminal = get_terminal_code(current_color, potential_code, size); maybe_terminal.has_value()) {
  279. run_length += maybe_terminal->run_length;
  280. if (reference_line.has_value())
  281. TRY(reference_line->try_append({ invert(current_color), column + run_length }));
  282. break;
  283. }
  284. }
  285. if (size == 14)
  286. return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid CCITT code");
  287. if (column + run_length > image_width)
  288. return Error::from_string_literal("TIFFImageDecoderPlugin: CCITT codes encode for more than a line");
  289. return run_length;
  290. }
  291. ErrorOr<ReferenceLine> decode_single_ccitt3_1d_line(BigEndianInputBitStream& input_bit_stream, BigEndianOutputBitStream& decoded_bits, u32 image_width)
  292. {
  293. // This is only useful for the 2D decoder.
  294. ReferenceLine reference_line;
  295. // We always flip the color when entering the loop, so let's initialize the
  296. // color with black to make the first marker actually be white.
  297. Color current_color { ccitt_black };
  298. u32 run_length = 0;
  299. u32 column = 0;
  300. while (column < image_width) {
  301. if (run_length > 0) {
  302. run_length--;
  303. TRY(decoded_bits.write_bits(current_color == ccitt_white ? 0u : 1u, 1));
  304. ++column;
  305. continue;
  306. }
  307. current_color = invert(current_color);
  308. run_length += TRY(read_run_length(input_bit_stream, reference_line, current_color, image_width, column));
  309. }
  310. TRY(decoded_bits.align_to_byte_boundary());
  311. return reference_line;
  312. }
  313. static ErrorOr<void> read_eol(BigEndianInputBitStream& bit_stream, Group3Options::UseFillBits use_fill_bits)
  314. {
  315. constexpr u16 EOL = 0b0000'0000'0001;
  316. if (use_fill_bits == Group3Options::UseFillBits::Yes) {
  317. // TIFF specification, description of the T4Options tag:
  318. // "Fill bits have been added as necessary before EOL codes such that
  319. // EOL always ends on a byte boundary, thus ensuring an EOL-sequence of 1 byte
  320. // preceded by a zero nibble: xxxx-0000 0000-0001."
  321. auto const to_skip = (12 + bit_stream.bits_until_next_byte_boundary()) % 8;
  322. TRY(bit_stream.read_bits(to_skip));
  323. }
  324. auto const read = TRY(bit_stream.read_bits<u16>(12));
  325. if (read != EOL)
  326. return Error::from_string_literal("CCITTDecoder: Invalid EndOfLine code");
  327. return {};
  328. }
  329. enum class Mode : u8 {
  330. Pass,
  331. Horizontal,
  332. Vertical_0,
  333. Vertical_R1,
  334. Vertical_R2,
  335. Vertical_R3,
  336. Vertical_L1,
  337. Vertical_L2,
  338. Vertical_L3,
  339. };
  340. struct ModeCode {
  341. u8 code_length {};
  342. Mode mode {};
  343. u8 code {};
  344. };
  345. // Table 4/T.4 – Two-dimensional code table
  346. constexpr Array node_codes = to_array<ModeCode>({
  347. { 4, Mode::Pass, 0b0001 },
  348. { 3, Mode::Horizontal, 0b001 },
  349. { 1, Mode::Vertical_0, 0b1 },
  350. { 3, Mode::Vertical_R1, 0b011 },
  351. { 6, Mode::Vertical_R2, 0b000011 },
  352. { 7, Mode::Vertical_R3, 0b0000011 },
  353. { 3, Mode::Vertical_L1, 0b010 },
  354. { 6, Mode::Vertical_L2, 0b000010 },
  355. { 7, Mode::Vertical_L3, 0b0000010 },
  356. });
  357. ErrorOr<ModeCode> read_mode(BigEndianInputBitStream& input_bit_stream)
  358. {
  359. u8 size {};
  360. u16 potential_code {};
  361. while (size < 7) {
  362. potential_code <<= 1;
  363. potential_code |= TRY(input_bit_stream.read_bit());
  364. ++size;
  365. if (auto const maybe_mode = get_code_from_table(node_codes, potential_code, size); maybe_mode.has_value())
  366. return *maybe_mode;
  367. }
  368. return Error::from_string_literal("CCITTDecoder: Unable to find the correct mode");
  369. }
  370. enum class Search : u8 {
  371. B1,
  372. B2,
  373. };
  374. ErrorOr<ReferenceLine> decode_single_ccitt_2d_line(BigEndianInputBitStream& input_bit_stream, BigEndianOutputBitStream& decoded_bits, ReferenceLine&& reference_line, u32 image_width)
  375. {
  376. ReferenceLine current_line {};
  377. Color current_color { ccitt_white };
  378. u32 column {};
  379. u32 remainder_from_pass_mode {};
  380. auto const next_change_on_reference_line = [&]() -> ErrorOr<Change> {
  381. // 4.2.1.3.1 Definition of changing picture elements
  382. Optional<Change> next_change {}; // This is referred to as b1 in the spec.
  383. u32 offset {};
  384. while (!next_change.has_value()) {
  385. if (reference_line.is_empty() || reference_line.size() <= offset)
  386. return Error::from_string_literal("CCITTDecoder: Corrupted stream");
  387. auto const change = reference_line[0 + offset];
  388. // 4.2.1.3.4 Processing the first and last picture elements in a line
  389. // "The first starting picture element a0 on each coding line is imaginarily set at a position just
  390. // before the first picture element, and is regarded as a white picture element."
  391. // To emulate this behavior we check for column == 0 here.
  392. if (change.column <= column && column != 0) {
  393. reference_line.take_first();
  394. continue;
  395. }
  396. if (change.color != current_color || change.column == image_width)
  397. next_change = change;
  398. else
  399. offset++;
  400. }
  401. return *next_change;
  402. };
  403. auto const encode_for = [&](Change change, i8 offset = 0) -> ErrorOr<void> {
  404. auto const to_encode = remainder_from_pass_mode + change.column - column + offset;
  405. for (u32 i {}; i < to_encode; ++i)
  406. TRY(decoded_bits.write_bits(current_color == ccitt_white ? 0u : 1u, 1));
  407. column = change.column + offset;
  408. current_color = invert(current_color);
  409. remainder_from_pass_mode = 0;
  410. TRY(current_line.try_empend(current_color, column));
  411. return {};
  412. };
  413. while (column < image_width) {
  414. auto const mode = TRY(read_mode(input_bit_stream));
  415. // Behavior are described here 4.2.1.3.2 Coding modes.
  416. switch (mode.mode) {
  417. case Mode::Pass: {
  418. auto const column_before = column;
  419. // We search for b1.
  420. auto change = TRY(next_change_on_reference_line());
  421. current_color = change.color;
  422. column = change.column;
  423. // We search for b2, which is the same as searching for b1 after updating the state.
  424. change = TRY(next_change_on_reference_line());
  425. current_color = change.color;
  426. column = change.column;
  427. remainder_from_pass_mode += column - column_before;
  428. break;
  429. }
  430. case Mode::Horizontal: {
  431. // a0a1
  432. auto run_length = TRY(read_run_length(input_bit_stream, OptionalNone {}, current_color, image_width, column));
  433. TRY(encode_for({ invert(current_color), column + run_length }));
  434. // a1a2
  435. run_length = TRY(read_run_length(input_bit_stream, OptionalNone {}, current_color, image_width, column));
  436. TRY(encode_for({ invert(current_color), column + run_length }));
  437. break;
  438. }
  439. case Mode::Vertical_0:
  440. TRY(encode_for(TRY(next_change_on_reference_line())));
  441. break;
  442. case Mode::Vertical_R1:
  443. TRY(encode_for(TRY(next_change_on_reference_line()), 1));
  444. break;
  445. case Mode::Vertical_R2:
  446. TRY(encode_for(TRY(next_change_on_reference_line()), 2));
  447. break;
  448. case Mode::Vertical_R3:
  449. TRY(encode_for(TRY(next_change_on_reference_line()), 3));
  450. break;
  451. case Mode::Vertical_L1:
  452. TRY(encode_for(TRY(next_change_on_reference_line()), -1));
  453. break;
  454. case Mode::Vertical_L2:
  455. TRY(encode_for(TRY(next_change_on_reference_line()), -2));
  456. break;
  457. case Mode::Vertical_L3:
  458. TRY(encode_for(TRY(next_change_on_reference_line()), -3));
  459. break;
  460. default:
  461. return Error::from_string_literal("CCITTDecoder: Unsupported mode for 2D decoding");
  462. }
  463. }
  464. TRY(decoded_bits.align_to_byte_boundary());
  465. return current_line;
  466. }
  467. ErrorOr<void> decode_single_ccitt3_2d_block(BigEndianInputBitStream& input_bit_stream, BigEndianOutputBitStream& decoded_bits, u32 image_width, u32 image_height, Group3Options::UseFillBits use_fill_bits)
  468. {
  469. ReferenceLine reference_line;
  470. for (u32 i = 0; i < image_height; ++i) {
  471. TRY(read_eol(input_bit_stream, use_fill_bits));
  472. bool const next_is_1D = TRY(input_bit_stream.read_bit()) == 1;
  473. if (next_is_1D)
  474. reference_line = TRY(decode_single_ccitt3_1d_line(input_bit_stream, decoded_bits, image_width));
  475. else
  476. reference_line = TRY(decode_single_ccitt_2d_line(input_bit_stream, decoded_bits, move(reference_line), image_width));
  477. }
  478. return {};
  479. }
  480. }
  481. ErrorOr<ByteBuffer> decode_ccitt_rle(ReadonlyBytes bytes, u32 image_width, u32 image_height)
  482. {
  483. auto strip_stream = make<FixedMemoryStream>(bytes);
  484. auto bit_stream = make<BigEndianInputBitStream>(MaybeOwned<Stream>(*strip_stream));
  485. // Note: We put image_height extra-space to handle at most one alignment to byte boundary per line.
  486. ByteBuffer decoded_bytes = TRY(ByteBuffer::create_zeroed(ceil_div(image_width * image_height, 8) + image_height));
  487. auto output_stream = make<FixedMemoryStream>(decoded_bytes.bytes());
  488. auto decoded_bits = make<BigEndianOutputBitStream>(MaybeOwned<Stream>(*output_stream));
  489. while (!bit_stream->is_eof()) {
  490. TRY(decode_single_ccitt3_1d_line(*bit_stream, *decoded_bits, image_width));
  491. bit_stream->align_to_byte_boundary();
  492. }
  493. return decoded_bytes;
  494. }
  495. ErrorOr<ByteBuffer> decode_ccitt_group3(ReadonlyBytes bytes, u32 image_width, u32 image_height, Group3Options const& options)
  496. {
  497. auto strip_stream = make<FixedMemoryStream>(bytes);
  498. auto bit_stream = make<BigEndianInputBitStream>(MaybeOwned<Stream>(*strip_stream));
  499. // Note: We put image_height extra-space to handle at most one alignment to byte boundary per line.
  500. ByteBuffer decoded_bytes = TRY(ByteBuffer::create_zeroed(ceil_div(image_width * image_height, 8) + image_height));
  501. auto output_stream = make<FixedMemoryStream>(decoded_bytes.bytes());
  502. auto decoded_bits = make<BigEndianOutputBitStream>(MaybeOwned<Stream>(*output_stream));
  503. if (options.dimensions == Group3Options::Mode::OneDimension) {
  504. // 4.1.2 End-of-line (EOL)
  505. // This code word follows each line of data. It is a unique code word that can never be found within a
  506. // valid line of data; therefore, resynchronization after an error burst is possible.
  507. // In addition, this signal will occur prior to the first data line of a page.
  508. // ---
  509. // NOTE: For whatever reason, the last EOL doesn't seem to be included
  510. for (u32 i = 0; i < image_height; ++i) {
  511. TRY(read_eol(*bit_stream, options.use_fill_bits));
  512. TRY(decode_single_ccitt3_1d_line(*bit_stream, *decoded_bits, image_width));
  513. }
  514. return decoded_bytes;
  515. }
  516. TRY(decode_single_ccitt3_2d_block(*bit_stream, *decoded_bits, image_width, image_height, options.use_fill_bits));
  517. return decoded_bytes;
  518. }
  519. ErrorOr<ByteBuffer> decode_ccitt_group4(ReadonlyBytes bytes, u32 image_width, u32 image_height)
  520. {
  521. auto strip_stream = make<FixedMemoryStream>(bytes);
  522. auto bit_stream = make<BigEndianInputBitStream>(MaybeOwned<Stream>(*strip_stream));
  523. // Note: We put image_height extra-space to handle at most one alignment to byte boundary per line.
  524. ByteBuffer decoded_bytes = TRY(ByteBuffer::create_zeroed(ceil_div(image_width * image_height, 8) + image_height));
  525. auto output_stream = make<FixedMemoryStream>(decoded_bytes.bytes());
  526. auto decoded_bits = make<BigEndianOutputBitStream>(MaybeOwned<Stream>(*output_stream));
  527. // T.6 2.2.1 Principle of the coding scheme
  528. // The reference line for the first coding line in a page is an imaginary white line.
  529. ReferenceLine reference_line;
  530. TRY(reference_line.try_empend(ccitt_black, image_width));
  531. for (u32 i = 0; i < image_height; ++i)
  532. reference_line = TRY(decode_single_ccitt_2d_line(*bit_stream, *decoded_bits, move(reference_line), image_width));
  533. return decoded_bytes;
  534. }
  535. }