#ifdef ENABLE_IMAGE_TEST #include "stdint.h" #include "math.h" #include "stdio.h" #include "lt24.h" #include "system.h" #include "sys/alt_irq.h" #define W (320) #define H (240) typedef struct { unsigned char red,green,blue; } PPMPixel; typedef struct { int x, y; PPMPixel *data; } PPMImage; #define RGB_COMPONENT_COLOR 255 // Source: https://stackoverflow.com/questions/2693631/read-ppm-file-and-store-it-in-an-array-coded-with-c static PPMImage *readPPM(const char *filename) { char buff[16]; PPMImage *img; FILE *fp; int c, rgb_comp_color; //open PPM file for reading fp = fopen(filename, "rb"); if (!fp) { fprintf(stderr, "Unable to open file '%s'\n", filename); return NULL; } //read image format if (!fgets(buff, sizeof(buff), fp)) { perror(filename); return NULL; } //check the image format if (buff[0] != 'P' || buff[1] != '6') { fprintf(stderr, "Invalid image format (must be 'P6')\n"); return NULL; } //alloc memory form image img = HPS_0_BRIDGES_BASE;//(PPMImage *)malloc(sizeof(PPMImage)); if (!img) { fprintf(stderr, "Unable to allocate memory\n"); return NULL; } //check for comments c = getc(fp); while (c == '#') { while (getc(fp) != '\n') ; c = getc(fp); } ungetc(c, fp); //read image size information if (fscanf(fp, "%d %d", &img->x, &img->y) != 2) { fprintf(stderr, "Invalid image size (error loading '%s')\n", filename); return NULL; } //read rgb component if (fscanf(fp, "%d", &rgb_comp_color) != 1) { fprintf(stderr, "Invalid rgb component (error loading '%s')\n", filename); return NULL; } //check rgb component depth if (rgb_comp_color!= RGB_COMPONENT_COLOR) { fprintf(stderr, "'%s' does not have 8-bits components\n", filename); return NULL; } while (fgetc(fp) != '\n') ; //memory allocation for pixel data img->data = HPS_0_BRIDGES_BASE + sizeof(PPMImage); if (!img) { fprintf(stderr, "Unable to allocate memory\n"); return NULL; } //read pixel data from file if (fread(img->data, 3 * img->x, img->y, fp) != img->y) { fprintf(stderr, "Error loading image '%s'\n", filename); return NULL; } fclose(fp); return img; } void ppmToLCD(uint16_t* lcdbuf, PPMImage* ppm) { pixel_t p; for(int y = 0; y < ppm->y; y++) { for(int x = 0; x < ppm->x; x++) { const PPMPixel* ppmPixel = &ppm->data[y*W + x]; p.r = ppmPixel->red >> 3; p.g = ppmPixel->green >> 2; p.b = ppmPixel->blue >> 3; IOWR_16DIRECT(lcdbuf,y*W + x, encPixel(&p)); } } } int main() { struct LT24 *lcd = LCDCONTROLLER_0_BASE; uint16_t *buffer = HPS_0_BRIDGES_BASE; LT24_initialize(lcd); LT24_setWidth(lcd, W); LT24_setHeight(lcd, H); LT24_writeBase(lcd, (uint32_t)buffer); // Read PPM from file PPMImage* img = readPPM("/mnt/host/application/testimage.ppm"); if (img == NULL){ return 1; } // Ensure equal to LCD display if(img->x != W || img->y != H) { fprintf(stderr, "Invalid image size (must be 320x240 but was %d x %d)\n", img->x, img->y); return 1; } // Write (and translate) to LCD buffer ppmToLCD(buffer, img); LT24_refresh(lcd); while (1){} return 0; } #endif