/*
 *		fimg-file.c
 *
 *
 */

#include  <stdio.h>
#include  <stdlib.h>
#include  <stdint.h>
#include  <unistd.h>
#include  <string.h>
#include  <errno.h>
#include  "../floatimg.h"

extern int verbosity;		/* must be declared around main() */

/* ---------------------------------------------------------------- */
int fimg_fileinfos(char *fname, int *datas)
{
FILE    	*fp;
FimgFileHead	filehead;

#if DEBUG_LEVEL
fprintf(stderr, ">>> %-25s ( '%s' %p )\n", __func__, fname, datas);
#endif

fp = fopen(fname, "r");
if (NULL==fp) {
        perror(fname);
        return -1;
        }

if (1 != fread(&filehead, sizeof(FimgFileHead), 1, fp)) {
        fprintf(stderr, "%s: %s bad read\n", __func__, fname);
        fclose(fp);
        return -2;
        }
fclose(fp);

#if DEBUG_LEVEL
fprintf(stderr, "    magic [%s]\n", filehead.magic);
#endif
 
if (memcmp(filehead.magic, "FIMG", 4)) {
	fprintf(stderr, "'%s' is not a fimg file.\n", fname);
	return -3;
	}

datas[0] = filehead.w;
datas[1] = filehead.h;
datas[2] = filehead.t;

return 0;
}
/* ---------------------------------------------------------------- */
/*
 *	/!\		thi func work ONLY on RGB image
 */
int fimg_dump_to_file(FloatImg *fimg, char *fname, int notused)
{
FILE		*fp;
int		foo, nbre;
FimgFileHead	filehead;

#if DEBUG_LEVEL
fprintf(stderr, ">>> %-25s ( %p '%s' %d )\n", __func__, fimg,
						fname, notused);
#endif

if (3 != fimg->type) {
	fprintf(stderr, "%s : bad type %d\n", __func__, fimg->type);
	return -8;
	} 

fp = fopen(fname, "w");
if (NULL==fp) {
	perror(fname);
	return -1;
	}

memset(&filehead, 0, sizeof(filehead));
memcpy(filehead.magic, "FIMG", 4);
filehead.w = fimg->width;	filehead.h = fimg->height;
filehead.t = fimg->type;

foo = fwrite(&filehead, sizeof(FimgFileHead), 1, fp);
if (1 != foo) {
	perror(fname);
	fclose(fp);
	return -2;
	}
nbre = fimg->width * fimg->height;	/* pixels per frame */

foo = fwrite(fimg->R, sizeof(float), nbre, fp);
if (nbre != foo) {
	perror(fname); fclose(fp); return -3;
	}
foo = fwrite(fimg->G, sizeof(float), nbre, fp);
if (nbre != foo) {
	perror(fname); fclose(fp); return -3;
	}
foo = fwrite(fimg->B, sizeof(float), nbre, fp);
if (nbre != foo) {
	perror(fname); fclose(fp); return -3;
	}
	
fclose(fp);

return 0;
}
/* ---------------------------------------------------------------- */
/*
 *	load a dump in a pre-allocated FloatImg
 */
int fimg_load_from_dump(char *fname, FloatImg *where)
{
FILE		*fp;
int		foo, nbre;
FimgFileHead	filehead;

#if DEBUG_LEVEL
fprintf(stderr, ">>> %-25s ( '%s' %p )\n", __func__, fname, where);
#endif

if (NULL==(fp = fopen(fname, "r"))) {
	perror(fname);
	return -15;
	}
foo = fread(&filehead, sizeof(FimgFileHead), 1, fp);  
if (1 != foo) {
	fprintf(stderr, "%s: short read on '%s'\n", __func__, fname);
	fclose(fp);
	return -16;
	}

/* check compatibility */
if (	(filehead.w != where->width) ||
	(filehead.h != where->height) ||
	(filehead.t != where->type) ) {
		fprintf(stderr, "%s: file '%s' incompatible\n",
				__func__, fname);
		fclose(fp);
		return -17;
		}

nbre = filehead.w * filehead.h;		/* number of pixels per frame */
foo = fread(where->R, sizeof(float), nbre, fp);
if (nbre != foo) {
	fprintf(stderr, "%s: err read '%s' : %d\n", __func__, fname, foo);
	fclose(fp);	return -18;
	}
foo = fread(where->G, sizeof(float), nbre, fp);
if (nbre != foo) {
	fprintf(stderr, "%s: err read '%s' : %d\n", __func__, fname, foo);
	fclose(fp);	return -18;
	}
foo = fread(where->B, sizeof(float), nbre, fp);
if (nbre != foo) {
	fprintf(stderr, "%s: err read '%s' : %d\n", __func__, fname, foo);
	fclose(fp);	return -18;
	}

fclose(fp);

return 0;
}
/* ---------------------------------------------------------------- */

int fimg_create_from_dump(char *fname, FloatImg *head)
{
FILE		*fp;
int		foo, size;
long		nbread;
FimgFileHead	filehead;

#if DEBUG_LEVEL
fprintf(stderr, ">>> %-25s ( '%s' %p )\n", __func__, fname, head);
#endif

/*
 *	may be we can crash coredump here if the head
 *	descriptor is not blank ?
 */

fp = fopen(fname, "r");
if (NULL==fp) {
	perror(fname);
	return -15;
	}
	
foo = fread(&filehead, sizeof(FimgFileHead), 1, fp);  
if (1 != foo) {
	fprintf(stderr, "%s: short read on '%s'\n", __func__, fname);
	fclose(fp);
	return -16;
	}
#if DEBUG_LEVEL
fprintf(stderr, "%s : got [ %dx%d %s ] from '%s'\n", __func__,
			filehead.w, filehead.h, fimg_str_type(filehead.t),
						fname);
#endif

foo = fimg_create(head, filehead.w, filehead.h, filehead.t); 
if (foo) {
	fprintf(stderr, "%s : create -> %d\n", __func__, foo);
	return foo;
	}

size = filehead.w * filehead.h;
nbread = 0;
nbread += fread(head->R, sizeof(float), size, fp);
nbread += fread(head->G, sizeof(float), size, fp);
nbread += fread(head->B, sizeof(float), size, fp);

fclose(fp);

return 0;
}