#include <stdio.h>
#include <stdlib.h>
#include <xil/xil.h>

XilImage 
load_file(XilSystemState state, char *filename)
{
    XilImage image;
    unsigned int width, height, nbands, bits;
    XilDataType datatype;
    XilMemoryStorage storage;
    Xil_boolean status;
    FILE *in_file;
    char datafile[256];
    int size;
   
    /* Open the header file */
    if ((in_file = fopen(filename, "r")) == NULL) {
        fprintf(stderr, "Could not open %s\n", filename);
        exit(1);
    }
   
    /* Get header information */
    fscanf(in_file, "%d%d%d%d", &width, &height, &bits, &nbands);
    fscanf(in_file, "%s", datafile);
    fclose(in_file);
   
    if ((bits == 8) && (nbands == 1)) {
        datatype = XIL_BYTE;
    }
    else {
        fprintf(stderr, "This program requires a single band, 8 bit image\n");
        exit(1);
    }
   
    /* Open the data file */
    if ((in_file = fopen(datafile, "r")) == NULL) {
        fprintf(stderr, "Could not open %s\n", datafile);
        exit(1);
    }
   
    /* Create the image to read the data into */
    image = xil_create(state, width, height, nbands, datatype);
    if (image == NULL) {
        /* XIL's default error handler will print an error msg to stderr */
        exit(1);
    }

    /* Get the pointer to the image data */
    if (xil_export(image) == XIL_FAILURE) {
        /* XIL's default error handler will print an error msg to stderr */
	exit(1);
    }
    status = xil_get_memory_storage(image, &storage);
    if (status == FALSE) {
        /* XIL's default error handler will print an error msg to stderr */
	exit(1);
    }

    /* Load the image data */
    if((storage.byte.pixel_stride == nbands) &&
            (storage.byte.scanline_stride == nbands * width)) {
        size = nbands * width * height;
        if (fread((char *) storage.byte.data, sizeof(Xil_unsigned8), 
                  size, in_file) != size) {
            fprintf(stderr, "Error reading data in %s\n", datafile);
            exit(1);
        }
    } else {
        int h, w, n;
        Xil_unsigned8* scanline = storage.byte.data;
        for(h=0; h<height; h++) {
            Xil_unsigned8* row = scanline;
            for(w=0; w<width; w++) {
                Xil_unsigned8* pixel = row;
                for(n=0; n<nbands; n++) {
                    *pixel++ = fgetc(in_file);
                }
                row += storage.byte.pixel_stride;
            }
            scanline += storage.byte.scanline_stride;
        }
    }      
    fclose(in_file);
   
    /* Make the image available for XIL processing */
    xil_import(image, 1);
    return(image);
}
