153 lines
3.4 KiB
C
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
|