1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use crate::jpeg::writer::JpegWriter;
/// Struct representing the header of a JPEG File Interchange Format (JFIF) file.
///
/// This struct contains information about the JFIF version.
#[derive(Debug, Clone)]
pub struct JfifHeader {
/// JFIF version information.
pub version: u16,
}
impl JfifHeader {
/// Creates a new `JfifHeader` by parsing a byte slice.
///
/// # Arguments
///
/// * `data` - A reference to a byte slice containing the JFIF header data.
///
/// # Returns
///
/// A `Result` containing the initialized `JfifHeader` if successful, or an error message
/// if the byte slice is invalid.
///
/// # Examples
///
/// ```
/// use stegano::jpeg::header::JfifHeader;
///
/// // Assuming data is a valid byte slice containing JFIF header data
/// let data: Vec<u8> = vec![
/// 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
/// 0x00, 0x01, 0x00, 0x00,
/// ];
///
/// let jfif_header_result = JfifHeader::new(&data);
///
/// match jfif_header_result {
/// Ok(jfif_header) => {
/// assert_eq!(jfif_header.version, 1);
///
/// println!("JfifHeader created successfully: {:?}", jfif_header);
/// }
/// Err(err) => {
/// eprintln!("Error creating JfifHeader: {}", err);
/// }
/// }
/// ```
pub fn new(data: &[u8]) -> Result<Self, &'static str> {
// Check if the byte slice has the expected length
if data.len() != 18 {
eprintln!("Warning: Invalid byte slice length for JFIF header. Continuing...");
return Err("Invalid byte slice length for JFIF header");
}
// Validate the JFIF marker and other fields
let expected_marker: [u8; 2] = [0x4A, 0x46]; // ASCII codes for "JF"
if data[0..2] != expected_marker {
eprintln!("Warning: Invalid JFIF marker. Continuing...");
return Err("Invalid JFIF marker");
}
// Extract the version field from the byte slice
let version = u16::from_be_bytes(data[2..4].try_into().unwrap());
// If all checks pass, create and return the JfifHeader
Ok(JfifHeader { version })
}
/// Writes the JFIF header to the provided JPEG writer.
///
/// # Arguments
///
/// * `writer` - A mutable reference to a `JpegWriter` trait object.
///
/// # Examples
///
/// ```
/// use stegano::jpeg::header::JfifHeader;
/// use std::io::BufWriter;
/// use std::fs::File;
///
/// let output_file = File::create("temp.jpeg").unwrap();
///
/// let mut writer = BufWriter::new(output_file);
/// let jfif_header = JfifHeader { version: 1 };
/// jfif_header.write(&mut writer);
/// ```
pub fn write(&self, writer: &mut dyn JpegWriter) {
let jfif: [u8; 18] = [
0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
0x00, 0x01, 0x00, 0x00,
];
writer.write_array(&jfif);
}
}