oozle 0.1.5

Open source Kraken, Mermaid, Selkie, Leviathan, LZNA, Bitknit decompressor
Documentation
#pragma once

#include "decompress.h"
#include "stdafx.h"

// Mermaid/Selkie decompression also happens in two phases, just like in
// Kraken, but the match copier works differently. Both Mermaid and Selkie use
// the same on-disk format, only the compressor differs.
struct MermaidLzTable
{
  // Flag stream. Format of flags:
  // Read flagbyte from |cmd_stream|
  // If flagbyte >= 24:
  //   flagbyte & 0x80 == 0 : Read from |off16_stream| into |recent_offs|.
  //                   != 0 : Don't read offset.
  //   flagbyte & 7 = Number of literals to copy first from |lit_stream|.
  //   (flagbyte >> 3) & 0xF = Number of bytes to copy from |recent_offs|.
  //
  //  If flagbyte == 0 :
  //    Read uint8_t L from |length_stream|
  //    If L > 251: L += 4 * Read word from |length_stream|
  //    L += 64
  //    Copy L bytes from |lit_stream|.
  //
  //  If flagbyte == 1 :
  //    Read uint8_t L from |length_stream|
  //    If L > 251: L += 4 * Read word from |length_stream|
  //    L += 91
  //    Copy L bytes from match pointed by next offset from |off16_stream|
  //
  //  If flagbyte == 2 :
  //    Read uint8_t L from |length_stream|
  //    If L > 251: L += 4 * Read word from |length_stream|
  //    L += 29
  //    Copy L bytes from match pointed by next offset from |off32_stream|,
  //    relative to start of block.
  //    Then prefetch |off32_stream[3]|
  //
  //  If flagbyte > 2:
  //    L = flagbyte + 5
  //    Copy L bytes from match pointed by next offset from |off32_stream|,
  //    relative to start of block.
  //    Then prefetch |off32_stream[3]|
  const uint8_t *cmd_stream, *cmd_stream_end;

  // Length stream
  const uint8_t *length_stream;

  // Literal stream
  const uint8_t *lit_stream, *lit_stream_end;

  // Near offsets
  const uint16_t *off16_stream, *off16_stream_end;

  // Far offsets for current chunk
  uint32_t *off32_stream, *off32_stream_end;

  // Holds the offsets for the two chunks
  uint32_t *off32_stream_1, *off32_stream_2;
  uint32_t off32_size_1, off32_size_2;

  // Flag offsets for next 64k chunk.
  uint32_t cmd_stream_2_offs, cmd_stream_2_offs_end;
};

int32_t Mermaid_DecodeFarOffsets (const uint8_t *src, const uint8_t *src_end,
                                  uint32_t *output, size_t output_size,
                                  int64_t offset);
void Mermaid_CombineOffs16 (uint16_t *dst, size_t size, const uint8_t *lo,
                            const uint8_t *hi);
bool Mermaid_ReadLzTable (int32_t mode, const uint8_t *src,
                          const uint8_t *src_end, uint8_t *dst,
                          int32_t dst_size, int64_t offset, uint8_t *scratch,
                          uint8_t *scratch_end, MermaidLzTable *lz);
const uint8_t *Mermaid_Mode0 (uint8_t *dst, size_t dst_size,
                               uint8_t *dst_ptr_end, uint8_t *dst_start,
                               const uint8_t *src_end, MermaidLzTable *lz,
                               int32_t *saved_dist, size_t startoff);
const uint8_t *Mermaid_Mode1 (uint8_t *dst, size_t dst_size,
                               uint8_t *dst_ptr_end, uint8_t *dst_start,
                               const uint8_t *src_end, MermaidLzTable *lz,
                               int32_t *saved_dist, size_t startoff);
bool Mermaid_ProcessLzRuns (int32_t mode, const uint8_t *src,
                            const uint8_t *src_end, uint8_t *dst,
                            size_t dst_size, uint64_t offset,
                            uint8_t *dst_end, MermaidLzTable *lz);
int32_t Mermaid_DecodeQuantum (uint8_t *dst, uint8_t *dst_end,
                               uint8_t *dst_start, const uint8_t *src,
                               const uint8_t *src_end, uint8_t *temp,
                               uint8_t *temp_end);