<commit_before>use decoders::basics::*;

pub mod huffman;
mod decompressors;
use decoders::ljpeg::huffman::*;
use decoders::ljpeg::decompressors::*;

enum Marker {
  Stuff        = 0x00,
  SOF3         = 0xc3, // lossless
  DHT          = 0xc4, // huffman tables
  SOI          = 0xd8, // start of image
  EOI          = 0xd9, // end of image
  SOS          = 0xda, // start of scan
  DQT          = 0xdb, // quantization tables
  Fill         = 0xff,
}

fn m(marker: Marker) -> u8 {
  marker as u8
}

#[derive(Debug, Copy, Clone)]
struct JpegComponentInfo {
  // These values are fixed over the whole image, read from the SOF marker.
  id: usize,    // identifier for this component (0..255)
  index: usize, // its index in SOF or cPtr->compInfo[]

  // Huffman table selector (0..3). The value may vary between scans.
  // It is read from the SOS marker.
  dc_tbl_num: usize,
  super_h: usize, // Horizontal Supersampling
  super_v: usize, // Vertical Supersampling
}

#[derive(Debug, Clone)]
struct SOFInfo {
  width: usize,
  height: usize,
  cps: usize,
  precision: usize,
  components: Vec<JpegComponentInfo>,
}

impl SOFInfo {
  fn empty() -> SOFInfo {
    SOFInfo {
      width: 0,
      height: 0,
      cps: 0,
      precision: 0,
      components: Vec::new(),
    }
  }

  fn parse_sof(&mut self, input: &mut ByteStream) -> Result<(), String> {
    let header_length = input.get_u16() as usize;
    self.precision = input.get_u8() as usize;
    self.height = input.get_u16() as usize;
    self.width = input.get_u16() as usize;
    self.cps = input.get_u8() as usize;

    if self.precision > 16 {
      return Err("ljpeg: More than 16 bits per channel is not supported.".to_string())
    }
    if self.cps > 4 || self.cps < 1 {
      return Err("ljpeg: Only from 1 to 4 components are supported.".to_string())
    }
    if header_length != 8 + self.cps*3 {
      return Err("ljpeg: Header size mismatch.".to_string())
    }

    for i in 0..self.cps {
      let id = input.get_u8() as usize;
      let subs = input.get_u8() as usize;
      if input.get_u8() != 0 {
        return Err("ljpeg: Quantized components not supported.".to_string())
      }
      self.components.push(JpegComponentInfo {
        id: id,
        index: i,
        dc_tbl_num: 0,
        super_h: subs & 0xf,
        super_v: subs >> 4,
      });
    }
    Ok(())
  }

  fn parse_sos(&mut self, input: &mut ByteStream) -> Result<(usize, usize), String> {
    if self.width == 0 {
      return Err("ljpeg: Trying to parse SOS before SOF".to_string())
    }
    input.get_u16(); //skip header length
    let soscps = input.get_u8() as usize;
    if self.cps != soscps {<commit_msg>ljpeg: swap super_h/super_v the correct way<commit_after>use decoders::basics::*;

pub mod huffman;
mod decompressors;
use decoders::ljpeg::huffman::*;
use decoders::ljpeg::decompressors::*;

enum Marker {
  Stuff        = 0x00,
  SOF3         = 0xc3, // lossless
  DHT          = 0xc4, // huffman tables
  SOI          = 0xd8, // start of image
  EOI          = 0xd9, // end of image
  SOS          = 0xda, // start of scan
  DQT          = 0xdb, // quantization tables
  Fill         = 0xff,
}

fn m(marker: Marker) -> u8 {
  marker as u8
}

#[derive(Debug, Copy, Clone)]
struct JpegComponentInfo {
  // These values are fixed over the whole image, read from the SOF marker.
  id: usize,    // identifier for this component (0..255)
  index: usize, // its index in SOF or cPtr->compInfo[]

  // Huffman table selector (0..3). The value may vary between scans.
  // It is read from the SOS marker.
  dc_tbl_num: usize,
  super_h: usize, // Horizontal Supersampling
  super_v: usize, // Vertical Supersampling
}

#[derive(Debug, Clone)]
struct SOFInfo {
  width: usize,
  height: usize,
  cps: usize,
  precision: usize,
  components: Vec<JpegComponentInfo>,
}

impl SOFInfo {
  fn empty() -> SOFInfo {
    SOFInfo {
      width: 0,
      height: 0,
      cps: 0,
      precision: 0,
      components: Vec::new(),
    }
  }

  fn parse_sof(&mut self, input: &mut ByteStream) -> Result<(), String> {
    let header_length = input.get_u16() as usize;
    self.precision = input.get_u8() as usize;
    self.height = input.get_u16() as usize;
    self.width = input.get_u16() as usize;
    self.cps = input.get_u8() as usize;

    if self.precision > 16 {
      return Err("ljpeg: More than 16 bits per channel is not supported.".to_string())
    }
    if self.cps > 4 || self.cps < 1 {
      return Err("ljpeg: Only from 1 to 4 components are supported.".to_string())
    }
    if header_length != 8 + self.cps*3 {
      return Err("ljpeg: Header size mismatch.".to_string())
    }

    for i in 0..self.cps {
      let id = input.get_u8() as usize;
      let subs = input.get_u8() as usize;
      if input.get_u8() != 0 {
        return Err("ljpeg: Quantized components not supported.".to_string())
      }
      self.components.push(JpegComponentInfo {
        id: id,
        index: i,
        dc_tbl_num: 0,
        super_v: subs & 0xf,
        super_h: subs >> 4,
      });
    }
    Ok(())
  }

  fn parse_sos(&mut self, input: &mut ByteStream) -> Result<(usize, usize), String> {
    if self.width == 0 {
      return Err("ljpeg: Trying to parse SOS before SOF".to_string())
    }
    input.get_u16(); //skip header length
    let soscps = input.get_u8() as usize;
    if self.cps != soscps {
{'fraction_non_alphanumeric': 0.12905632226781052, 'fraction_numerical': 0.02126072361059306, 'mean_word_length': 2.409408773045137, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5868782', 'n_tokens_mistral': 1962, 'n_tokens_neox': 1907, 'n_words': 557}