Skip to content

Instantly share code, notes, and snippets.

@13m0n4de
Last active May 13, 2024 20:11
Show Gist options
  • Save 13m0n4de/238b13f361e0326a0e8868e00119fb2a to your computer and use it in GitHub Desktop.
Save 13m0n4de/238b13f361e0326a0e8868e00119fb2a to your computer and use it in GitHub Desktop.
Bad Apple!! on LemonCore (https://github.com/13m0n4de/lemon-core)
#![no_std]
#![no_main]
extern crate alloc;
extern crate user_lib;
use alloc::vec;
use embedded_graphics::{
draw_target::DrawTarget,
geometry::{OriginDimensions, Point},
image::{Image, ImageRaw},
pixelcolor::BinaryColor,
prelude::Size,
Drawable, Pixel,
};
use user_lib::{
fs::{close, open, read, OpenFlags},
gui::{framebuffer, framebuffer_flush, VIRTGPU_LEN, VIRTGPU_XRES, VIRTGPU_YRES},
};
const IMAGE_WIDTH: usize = 480;
const IMAGE_HEIGHT: usize = 360;
const IMAGE_BUFFER_SIZE: usize = IMAGE_WIDTH * IMAGE_HEIGHT / 8;
const FRAMES_COUNT: usize = 6569;
pub struct Display {
pub size: Size,
pub fb: &'static mut [u8],
}
impl Display {
fn new(size: Size) -> Self {
let fb_ptr = framebuffer() as *mut u8;
let fb = unsafe { core::slice::from_raw_parts_mut(fb_ptr, VIRTGPU_LEN) };
Self { size, fb }
}
fn draw_pixel(&mut self, x: i32, y: i32, color: BinaryColor) {
let idx = (y * VIRTGPU_XRES as i32 + x) as usize * 4;
if idx + 2 < self.fb.len() {
let c = if color.is_on() { 0xff } else { 0x00 };
self.fb[idx] = c;
self.fb[idx + 1] = c;
self.fb[idx + 2] = c;
}
}
}
impl DrawTarget for Display {
type Color = BinaryColor;
type Error = core::convert::Infallible;
fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
where
I: IntoIterator<Item = Pixel<Self::Color>>,
{
for Pixel(Point { x, y }, color) in pixels {
self.draw_pixel(x, y, color);
}
framebuffer_flush();
Ok(())
}
}
impl OriginDimensions for Display {
fn size(&self) -> Size {
self.size
}
}
#[no_mangle]
extern "Rust" fn main() -> i32 {
let mut display = Display::new(Size::new(VIRTGPU_XRES, VIRTGPU_YRES));
display.clear(BinaryColor::On).unwrap();
let fd = open("/data/bad_apple.bin", OpenFlags::RDONLY);
assert!(fd >= 0);
let fd = fd as usize;
let mut image_buffer = vec![0u8; IMAGE_BUFFER_SIZE];
for _ in 0..FRAMES_COUNT {
if read(fd, &mut image_buffer) == 0 {
break;
}
let raw_image = ImageRaw::<BinaryColor>::new(&image_buffer, IMAGE_WIDTH as u32);
let image = Image::new(
&raw_image,
Point {
x: (VIRTGPU_XRES as i32 - IMAGE_WIDTH as i32) / 2,
y: (VIRTGPU_YRES as i32 - IMAGE_HEIGHT as i32) / 2,
},
);
image.draw(&mut display).unwrap();
}
close(fd);
display.clear(BinaryColor::On).unwrap();
0
}
import cv2
import numpy as np
cap = cv2.VideoCapture("bad_apple.mp4")
width = 480
height = 360
binary_flat = []
while True:
ret, frame = cap.read()
if not ret:
break
frame = cv2.resize(frame, (width, height), interpolation=cv2.INTER_AREA)
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray_frame, 128, 1, cv2.THRESH_BINARY)
binary_flat.append(binary.flatten())
packed_bytes = np.packbits(binary_flat)
packed_bytes.tofile("bad_apple.bin")
cap.release()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment