#pragma once #include #include "config.h" struct ProcessedImage { uint8_t* framebuffer; // Palette indices, one byte per pixel uint16_t width; uint16_t height; bool valid; }; class ImagePipeline { public: // Process single landscape photo ProcessedImage process(uint8_t* jpegData, size_t jpegSize); // Process portrait pair (two photos side by side) ProcessedImage processPortraitPair(uint8_t* jpeg1Data, size_t jpeg1Size, uint8_t* jpeg2Data, size_t jpeg2Size); void freeImage(ProcessedImage& img); private: // Decode JPEG into RGB888 buffer in PSRAM uint8_t* decodeJpeg(uint8_t* data, size_t size, uint16_t* outWidth, uint16_t* outHeight); // Resize RGB buffer to target dimensions (bilinear) uint8_t* resize(uint8_t* rgb, uint16_t srcW, uint16_t srcH, uint16_t dstW, uint16_t dstH); // Center-crop to target aspect ratio void centerCrop(uint8_t* rgb, uint16_t srcW, uint16_t srcH, uint16_t targetW, uint16_t targetH, uint16_t* cropX, uint16_t* cropY, uint16_t* cropW, uint16_t* cropH); // Floyd-Steinberg dither RGB888 to 6-color palette indices uint8_t* dither(uint8_t* rgb, uint16_t width, uint16_t height); // Find nearest palette color uint8_t findNearest(int r, int g, int b); };