Let's update the title again!

Default Editor Stuff!!!

this is a test blog post!
Next.js may not be updating the stuff properly! Let's check this!


pub fn encode_message(img: &mut DynamicImage, message: &str) -> Result<(), String> {
// Convert the input DynamicImage to RGBA format for pixel manipulation
let mut rgba_img = img.to_rgba8();
// Print the rgba image into a .txt file.
let file = File::create("rgba_img.txt").unwrap();
let mut file = BufWriter::new(file);
// Write only the rgba values of the image into a .txt file as a single array with 32 colums in each row.
let mut count = 0;
for y in 0..rgba_img.height() {
for x in 0..rgba_img.width() {
let pixel = rgba_img.get_pixel(x, y);
let r = pixel[0];
let g = pixel[1];
let b = pixel[2];
let a = pixel[3];
write!(file, "{}, {}, {}, {}, ", r, g, b, a).unwrap();
count += 1;
if count == 8 {
write!(file, "\n").unwrap();
count = 0;
}
}
}
if count != 0 {
write!(file, "\n").unwrap();
}
// Convert message string to bytes for encoding
let bytes = message.as_bytes();
// Store message length for capacity check and encoding
let len = bytes.len();
// Calculate if image has enough pixels to store message:
// Each pixel has 3 channels (RGB) that can store 1 bit each
// Message length needs 32 bits + (message length * 8 bits) for the actual message
if len * 8 > (rgba_img.width() * rgba_img.height() * 3) as usize {
return Err("Image is too small to store the message".to_string());
}
// Convert message length (32-bit unsigned int) to big-endian byte array
let len_bytes = (len as u32).to_be_bytes();
// Track current bit position in the image while encoding
let mut bit_index = 0;
// First encode the 32-bit message length
for byte in len_bytes.iter() {
// Process each bit in the current byte
for bit in 0..8 {
// Calculate x-coordinate: (bit_index / 3) gives pixel index, mod by width for x position
let x = (bit_index / 3) % rgba_img.width();
// Calculate y-coordinate: (bit_index / 3) gives pixel index, divide by width for y position
let y = (bit_index / 3) / rgba_img.width();
// Determine which color channel (R=0, G=1, B=2) to modify
let color_channel = bit_index % 3;
// Get mutable reference to current pixel
let pixel = rgba_img.get_pixel_mut(x, y);
// Extract current bit from byte: shift right by (7-bit) and mask with 1
let bit_value = (byte >> (7 - bit)) & 1;
// Modify appropriate color channel:
// Clear LSB with AND 0xFE, then set it to our bit value
match color_channel {
0 => pixel[0] = (pixel[0] & 0xFE) | bit_value, // Modify red channel
1 => pixel[1] = (pixel[1] & 0xFE) | bit_value, // Modify green channel
2 => pixel[2] = (pixel[2] & 0xFE) | bit_value, // Modify blue channel
_ => unreachable!(), // This case is impossible due to modulo 3
}
// Move to next bit position
bit_index += 1;
}
}
// Now encode the actual message bytes
for byte in bytes {
// Process each bit in the current message byte
for bit in 0..8 {
// Calculate x-coordinate for current bit
let x = (bit_index / 3) % rgba_img.width();
// Calculate y-coordinate for current bit
let y = (bit_index / 3) / rgba_img.width();
// Determine which color channel to modify
let color_channel = bit_index % 3;
// Get mutable reference to current pixel
let pixel = rgba_img.get_pixel_mut(x, y);
// Extract current bit from message byte
let bit_value = (byte >> (7 - bit)) & 1;
// Modify appropriate color channel with the bit value
match color_channel {
0 => pixel[0] = (pixel[0] & 0xFE) | bit_value, // Modify red channel
1 => pixel[1] = (pixel[1] & 0xFE) | bit_value, // Modify green channel
2 => pixel[2] = (pixel[2] & 0xFE) | bit_value, // Modify blue channel
_ => unreachable!(), // This case is impossible due to modulo 3
}
// Move to next bit position
bit_index += 1;
}
}
// Update the original image with our modified RGBA image
*img = DynamicImage::ImageRgba8(rgba_img);
// Return success
Ok(())
}