Skip to content

Commit

Permalink
Add JpegTestStreamWriter
Browse files Browse the repository at this point in the history
Move functions to helper struct JpegTestStreamWriter
  • Loading branch information
vbaderks committed Oct 7, 2023
1 parent a24c9e8 commit 5328d35
Showing 1 changed file with 89 additions and 68 deletions.
157 changes: 89 additions & 68 deletions src/jpeg_stream_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,18 +117,19 @@ mod tests {
#[test]
fn read_header_from_buffer_preceded_with_fill_bytes() {
let extra_start_byte = 0xFFu8;
let mut buffer = Vec::new();

write_byte(&mut buffer, extra_start_byte);
write_start_of_image(&mut buffer);
let mut writer = JpegTestStreamWriter::new();

write_byte(&mut buffer, extra_start_byte);
write_start_of_frame_segment(&mut buffer, 1, 1, 2, 1);
writer.write_byte(extra_start_byte);
writer.write_start_of_image();

write_byte(&mut buffer, extra_start_byte);
write_start_of_scan_segment(&mut buffer, 0, 1, 1, 0);
writer.write_byte(extra_start_byte);
writer.write_start_of_frame_segment(1, 1, 2, 1);

let mut reader = JpegStreamReader::new(buffer.as_slice());
writer.write_byte(extra_start_byte);
writer.write_start_of_scan_segment(0, 1, 1, 0);

let mut reader = JpegStreamReader::new(writer.data());
assert!(reader.read_header().is_ok());
}

Expand All @@ -150,85 +151,105 @@ mod tests {
}
}

fn read_header_with_application_data_for(data_number: u8) {
let mut buffer = Vec::new();
struct JpegTestStreamWriter {
buffer: Vec<u8>,
}

write_start_of_image(&mut buffer);
write_byte(&mut buffer, 0xFF);
write_byte(&mut buffer, 0xE0 + data_number);
write_byte(&mut buffer, 0);
write_byte(&mut buffer, 0x02);
write_start_of_frame_segment(&mut buffer, 1, 1, 2,1);
write_start_of_scan_segment(&mut buffer, 0, 1, 1, 0);
impl JpegTestStreamWriter {
fn new() -> JpegTestStreamWriter {
JpegTestStreamWriter {
buffer: Vec::new()
}
}

let mut reader = JpegStreamReader::new(buffer.as_slice());
assert!(reader.read_header().is_ok());
}
fn write_byte(&mut self, value: u8) {
self.buffer.write_all(&[value]).unwrap();
}

fn write_byte(buffer: &mut Vec<u8>, value: u8) {
buffer.write_all(&[value]).unwrap();
}
fn write_marker(&mut self, marker_code: JpegMarkerCode)
{
self.write_byte(0xFF);
self.write_byte(marker_code as u8);
}

fn write_u16(buffer: &mut Vec<u8>, value: u16) {
buffer.write_all(&value.to_be_bytes()).unwrap();
}
fn write_start_of_image(&mut self) {
self.buffer.write_all(&[0xFF, 0xD8]).unwrap();
}

fn write_marker(buffer: &mut Vec<u8>, marker_code: JpegMarkerCode)
{
write_byte(buffer, 0xFF);
write_byte(buffer, marker_code as u8);
}
fn write_start_of_frame_segment(&mut self, width: u16, height: u16, bits_per_sample: u8,
component_count: u16) {
// Create a Frame Header as defined in T.87, C.2.2 and T.81, B.2.2
let mut segment = Vec::new();

fn write_start_of_image(buffer: &mut Vec<u8>) {
buffer.write_all(&[0xFF, 0xD8]).unwrap();
}
write_byte(&mut segment, bits_per_sample); // P = Sample precision
write_u16(&mut segment, height); // Y = Number of lines
write_u16(&mut segment, width); // X = Number of samples per line

// Components
write_byte(&mut segment, component_count as u8); // Nf = Number of image components in frame

for component_id in 0..component_count as u8 {
// Component Specification parameters
write_byte(&mut segment, component_id); // Ci = Component identifier
write_byte(&mut segment, 0x11); // Hi + Vi = Horizontal sampling factor + Vertical sampling factor
write_byte(&mut segment, 0); // Tqi = Quantization table destination selector (reserved for JPEG-LS, should be set to 0)
}

fn write_start_of_frame_segment(buffer: &mut Vec<u8>, width: u16, height: u16, bits_per_sample: u8,
component_count: u16) {
// Create a Frame Header as defined in T.87, C.2.2 and T.81, B.2.2
let mut segment = Vec::new();
self.write_segment(JpegMarkerCode::StartOfFrameJpegls, &segment);
}

fn write_start_of_scan_segment(&mut self, component_id: u8, component_count: u8, near_lossless: u8,
interleave_mode: u8) {
// Create a Scan Header as defined in T.87, C.2.3 and T.81, B.2.3
let mut segment = Vec::new();

write_byte(&mut segment, bits_per_sample); // P = Sample precision
write_u16(&mut segment, height); // Y = Number of lines
write_u16(&mut segment, width); // X = Number of samples per line
write_byte(&mut segment, component_count);
for i in 0..component_count {
write_byte(&mut segment, component_id + i);
write_byte(&mut segment, 0); // Mapping table selector (0 = no table)
}

// Components
write_byte(&mut segment, component_count as u8); // Nf = Number of image components in frame
write_byte(&mut segment, near_lossless); // NEAR parameter
write_byte(&mut segment, interleave_mode); // ILV parameter
write_byte(&mut segment, 0); // transformation

for component_id in 0..component_count as u8 {
// Component Specification parameters
write_byte(&mut segment, component_id); // Ci = Component identifier
write_byte(&mut segment, 0x11); // Hi + Vi = Horizontal sampling factor + Vertical sampling factor
write_byte(&mut segment, 0); // Tqi = Quantization table destination selector (reserved for JPEG-LS, should be set to 0)
self.write_segment(JpegMarkerCode::StartOfScan, &segment);
}

write_segment(buffer, JpegMarkerCode::StartOfFrameJpegls, &segment);
}
fn write_segment(&mut self, marker_code: JpegMarkerCode, segment_data: &Vec<u8>)
{
self.buffer.write_all(&[0xFF, 0xD8]).unwrap();

fn write_start_of_scan_segment(buffer: &mut Vec<u8>, component_id: u8, component_count: u8, near_lossless: u8,
interleave_mode: u8) {
// Create a Scan Header as defined in T.87, C.2.3 and T.81, B.2.3
let mut segment = Vec::new();
self.write_marker(marker_code);
write_u16(&mut self.buffer, (segment_data.len() + 2) as u16);
self.buffer.write_all(segment_data).unwrap();
}

write_byte(&mut segment, component_count);
for i in 0..component_count {
write_byte(&mut segment, component_id + i);
write_byte(&mut segment, 0); // Mapping table selector (0 = no table)
fn data(&self) -> &[u8] {
self.buffer.as_slice()
}
}

fn read_header_with_application_data_for(data_number: u8) {
let mut writer = JpegTestStreamWriter::new();

write_byte(&mut segment, near_lossless); // NEAR parameter
write_byte(&mut segment, interleave_mode); // ILV parameter
write_byte(&mut segment, 0); // transformation
writer.write_start_of_image();
writer.write_byte(0xFF);
writer.write_byte(0xE0 + data_number);
writer.write_byte(0);
writer.write_byte(0x02);
writer.write_start_of_frame_segment(1, 1, 2, 1);
writer.write_start_of_scan_segment(0, 1, 1, 0);

write_segment(buffer, JpegMarkerCode::StartOfScan, &segment);
let mut reader = JpegStreamReader::new(writer.data());
assert!(reader.read_header().is_ok());
}

fn write_segment(buffer: &mut Vec<u8>, marker_code: JpegMarkerCode, segment_data: &Vec<u8>)
{
buffer.write_all(&[0xFF, 0xD8]).unwrap();
fn write_byte(buffer: &mut Vec<u8>, value: u8) {
buffer.write_all(&[value]).unwrap();
}

write_marker(buffer, marker_code);
write_u16(buffer, (segment_data.len() + 2) as u16);
buffer.write_all(segment_data).unwrap();
fn write_u16(buffer: &mut Vec<u8>, value: u16) {
buffer.write_all(&value.to_be_bytes()).unwrap();
}
}

0 comments on commit 5328d35

Please sign in to comment.