summaryrefslogtreecommitdiff
path: root/Libraries/LibGfx/JPGLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Libraries/LibGfx/JPGLoader.cpp')
-rw-r--r--Libraries/LibGfx/JPGLoader.cpp151
1 files changed, 151 insertions, 0 deletions
diff --git a/Libraries/LibGfx/JPGLoader.cpp b/Libraries/LibGfx/JPGLoader.cpp
index fe4c0c16b0..6338f66d52 100644
--- a/Libraries/LibGfx/JPGLoader.cpp
+++ b/Libraries/LibGfx/JPGLoader.cpp
@@ -40,6 +40,60 @@
if (JPG_DBG) \
dbg() << x
+#define JPG_INVALID 0X0000
+
+#define JPG_APPN0 0XFFE0
+#define JPG_APPN1 0XFFE1
+#define JPG_APPN2 0XFFE2
+#define JPG_APPN3 0XFFE3
+#define JPG_APPN4 0XFFE4
+#define JPG_APPN5 0XFFE5
+#define JPG_APPN6 0XFFE6
+#define JPG_APPN7 0XFFE7
+#define JPG_APPN8 0XFFE8
+#define JPG_APPN9 0XFFE9
+#define JPG_APPNA 0XFFEA
+#define JPG_APPNB 0XFFEB
+#define JPG_APPNC 0XFFEC
+#define JPG_APPND 0XFFED
+#define JPG_APPNE 0xFFEE
+#define JPG_APPNF 0xFFEF
+
+#define JPG_RESERVED1 0xFFF1
+#define JPG_RESERVED2 0xFFF2
+#define JPG_RESERVED3 0xFFF3
+#define JPG_RESERVED4 0xFFF4
+#define JPG_RESERVED5 0xFFF5
+#define JPG_RESERVED6 0xFFF6
+#define JPG_RESERVED7 0xFFF7
+#define JPG_RESERVED8 0xFFF8
+#define JPG_RESERVED9 0xFFF9
+#define JPG_RESERVEDA 0xFFFA
+#define JPG_RESERVEDB 0xFFFB
+#define JPG_RESERVEDC 0xFFFC
+#define JPG_RESERVEDD 0xFFFD
+
+#define JPG_RST0 0xFFD0
+#define JPG_RST1 0xFFD1
+#define JPG_RST2 0xFFD2
+#define JPG_RST3 0xFFD3
+#define JPG_RST4 0xFFD4
+#define JPG_RST5 0xFFD5
+#define JPG_RST6 0xFFD6
+#define JPG_RST7 0xFFD7
+
+#define JPG_DHP 0xFFDE
+#define JPG_EXP 0xFFDF
+
+#define JPG_DHT 0XFFC4
+#define JPG_DQT 0XFFDB
+#define JPG_EOI 0xFFD9
+#define JPG_RST 0XFFDD
+#define JPG_SOF0 0XFFC0
+#define JPG_SOI 0XFFD8
+#define JPG_SOS 0XFFDA
+#define JPG_COM 0xFFFE
+
namespace Gfx {
constexpr static u8 zigzag_map[64] {
@@ -55,6 +109,103 @@ constexpr static u8 zigzag_map[64] {
using Marker = u16;
+/**
+ * MCU means group of data units that are coded together. A data unit is an 8x8
+ * block of component data. In interleaved scans, number of non-interleaved data
+ * units of a component C is Ch * Cv, where Ch and Cv represent the horizontal &
+ * vertical subsampling factors of the component, respectively. A MacroBlock is
+ * an 8x8 block of RGB values before encoding, and 8x8 block of YCbCr values when
+ * we're done decoding the huffman stream.
+ */
+struct Macroblock {
+ union {
+ i32 y[64] = { 0 };
+ i32 r[64];
+ };
+
+ union {
+ i32 cb[64] = { 0 };
+ i32 g[64];
+ };
+
+ union {
+ i32 cr[64] = { 0 };
+ i32 b[64];
+ };
+};
+
+struct MacroblockMeta {
+ u32 total;
+ u32 padded_total;
+ u32 hcount;
+ u32 vcount;
+ u32 hpadded_count;
+ u32 vpadded_count;
+};
+
+struct ComponentSpec {
+ i8 id { -1 };
+ u8 hsample_factor { 1 }; // Horizontal sampling factor.
+ u8 vsample_factor { 1 }; // Vertical sampling factor.
+ u8 ac_destination_id;
+ u8 dc_destination_id;
+ u8 qtable_id; // Quantization table id.
+};
+
+struct StartOfFrame {
+ enum class FrameType {
+ Baseline = 0
+ // Progressive = 1
+ };
+
+ FrameType type { FrameType::Baseline };
+ u8 precision;
+ u16 height;
+ u16 width;
+};
+
+struct HuffmanTableSpec {
+ u8 type;
+ u8 destination_id;
+ u8 code_counts[16] = { 0 };
+ Vector<u8> symbols;
+ Vector<u16> codes;
+};
+
+struct HuffmanStreamState {
+ Vector<u8> stream;
+ u8 bit_offset { 0 };
+ size_t byte_offset { 0 };
+};
+
+struct JPGLoadingContext {
+ enum State {
+ NotDecoded = 0,
+ Error,
+ FrameDecoded,
+ BitmapDecoded
+ };
+
+ State state { State::NotDecoded };
+ const u8* data { nullptr };
+ size_t data_size { 0 };
+ u32 luma_table[64];
+ u32 chroma_table[64];
+ StartOfFrame frame;
+ u8 hsample_factor;
+ u8 vsample_factor;
+ bool has_zero_based_ids;
+ u8 component_count;
+ ComponentSpec components[3];
+ RefPtr<Gfx::Bitmap> bitmap;
+ u16 dc_reset_interval;
+ Vector<HuffmanTableSpec> dc_tables;
+ Vector<HuffmanTableSpec> ac_tables;
+ HuffmanStreamState huffman_stream;
+ i32 previous_dc_values[3] = { 0 };
+ MacroblockMeta mblock_meta;
+};
+
void generate_huffman_codes(HuffmanTableSpec& table)
{
unsigned code = 0;