diff --git a/Userland/Libraries/LibGfx/ImageFormats/CCITTDecoder.cpp b/Userland/Libraries/LibGfx/ImageFormats/CCITTDecoder.cpp index f47cd24e80..d8c4179352 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/CCITTDecoder.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/CCITTDecoder.cpp @@ -272,6 +272,36 @@ Color invert(Color current_color) return current_color == ccitt_white ? ccitt_black : ccitt_white; } +ErrorOr read_run_length(BigEndianInputBitStream& input_bit_stream, Color current_color, u32 image_width, u32 column) +{ + u8 size {}; + u16 potential_code {}; + u32 run_length {}; + while (size < 14) { + potential_code <<= 1; + potential_code |= TRY(input_bit_stream.read_bit()); + size++; + + if (auto const maybe_markup = get_markup_code(current_color, potential_code, size); maybe_markup.has_value()) { + run_length += maybe_markup->run_length; + // OK, let's reset the loop to read a terminal code now + size = 0; + potential_code = 0; + } else if (auto const maybe_terminal = get_terminal_code(current_color, potential_code, size); maybe_terminal.has_value()) { + run_length += maybe_terminal->run_length; + break; + } + } + + if (size == 14) + return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid CCITT code"); + + if (column + run_length > image_width) + return Error::from_string_literal("TIFFImageDecoderPlugin: CCITT codes encode for more than a line"); + + return run_length; +} + ErrorOr decode_single_ccitt3_1d_line(BigEndianInputBitStream& input_bit_stream, BigEndianOutputBitStream& decoded_bits, u32 image_width) { // We always flip the color when entering the loop, so let's initialize the @@ -291,29 +321,7 @@ ErrorOr decode_single_ccitt3_1d_line(BigEndianInputBitStream& input_bit_st current_color = invert(current_color); - u8 size {}; - u16 potential_code {}; - while (size < 14) { - potential_code <<= 1; - potential_code |= TRY(input_bit_stream.read_bit()); - size++; - - if (auto const maybe_markup = get_markup_code(current_color, potential_code, size); maybe_markup.has_value()) { - run_length += maybe_markup->run_length; - // OK, let's reset the loop to read a terminal code now - size = 0; - potential_code = 0; - } else if (auto const maybe_terminal = get_terminal_code(current_color, potential_code, size); maybe_terminal.has_value()) { - run_length += maybe_terminal->run_length; - break; - } - } - - if (size == 14) - return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid CCITT code"); - - if (column + run_length > image_width) - return Error::from_string_literal("TIFFImageDecoderPlugin: CCITT codes encode for more that a line"); + run_length += TRY(read_run_length(input_bit_stream, current_color, image_width, column)); } TRY(decoded_bits.align_to_byte_boundary());