2022-04-07 18:46:57 +02:00

153 lines
3.4 KiB
C

#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