In an earlier post we looked at converting an image to 16 bit 5:6:5 format for direct copying to framebuffer. The obvious drawback of that approach is the requirement on the image size to exactly match the display/framebuffer size (or the width at least).
Modifying the PPM reading code to read into an image object in memory (I chose to use the struct fb_image from linux/fb.h as teh image object) and combining that with the familiar framebuffer drawing code (put_pixel_RGB565 from part 6)
Make sure you have a 24 bit PPM image file to start with - convert one from for example PNG using pngtopnm (any bit depth source file should do) - and make sure the image fits the screen (no bounds checking in the code). Then compile and run:
... int read_ppm(char *fpath, struct fb_image *image) { ... image->data = malloc(width * height * bytes_per_pixel); ... // store pixel in memory unsigned int pix_offset = (y * width + x ) * bytes_per_pixel; *((unsigned short *)(image->data + pix_offset)) = rgb565; ... void draw(struct fb_image *image) { int y; int x; unsigned char rgb[3]; for (y = 0; y < image->height; y++) { for (x = 0; x < image->width; x++) { // get pixel from image unsigned int img_pix_offset = (y * image->width + x) * 2; unsigned short c = *(unsigned short *)(image->data + img_pix_offset); // plot pixel to screen unsigned int fb_pix_offset = x * 2 + y * finfo.line_length; *((unsigned short*)(fbp + fb_pix_offset)) = c; } } } ... int main(int argc, char* argv[]) { // read the image file int ret = read_ppm(argv[1], &image); if (ret != 0) { printf("Reading image failed.\n"); return ret; } ...
gcc -O2 -o ppmtofbimg ppmtofbimg.c ./ppmtofbimg test24.ppm
Full source and a test image (test24.ppm) in GitHub.