forked from tTh/FloatImg
364 lines
8.1 KiB
C
364 lines
8.1 KiB
C
/*
|
|
* 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;
|
|
}
|
|
|
|
/* XXX preparer la gestion des metadata */
|
|
if ('a' == filehead.magic[4] && verbosity > 1) {
|
|
fprintf(stderr,"*** %s have metadata\n", fname);
|
|
}
|
|
|
|
datas[0] = filehead.w;
|
|
datas[1] = filehead.h;
|
|
datas[2] = filehead.t;
|
|
|
|
return 0;
|
|
}
|
|
/* ---------------------------------------------------------------- */
|
|
/*
|
|
* new avril 2022 : trying to save metadatas...
|
|
*/
|
|
int fimg_dumpmd_to_file(FloatImg *fimg, char *fname, \
|
|
FimgMetaData *pmd, int notused)
|
|
{
|
|
FILE *fp;
|
|
int foo, nbre;
|
|
FimgFileHead filehead;
|
|
FimgMetaData fakemd;
|
|
|
|
#if DEBUG_LEVEL
|
|
fprintf(stderr, ">>> %s ( %p '%s' %p %d )\n", __func__, fimg,
|
|
fname, pmd, notused);
|
|
#endif
|
|
|
|
if (notused) {
|
|
fprintf(stderr, "%s: notused must be 0, was %d\n", \
|
|
__func__, notused);
|
|
}
|
|
|
|
if (FIMG_TYPE_RGB != fimg->type) {
|
|
fprintf(stderr, "%s : bad type %d\n", __func__, fimg->type);
|
|
return -8;
|
|
}
|
|
|
|
/* OK, we have to make a fake metadata chunk, if the caller
|
|
* don't have one. Ugly, and nice */
|
|
if (NULL == pmd) {
|
|
// fprintf(stderr, ">>> %s making faked metadata\n", __func__);
|
|
foo = fimg_default_metadata(&fakemd, 3);
|
|
// fprintf(stderr, "fakemd is at %p\n", &fakemd);
|
|
pmd = &fakemd;
|
|
}
|
|
else {
|
|
/* OK, get some funky metadatas */
|
|
fprintf(stderr, "%s: acqu fval=%f count=%d\n", __func__,
|
|
pmd->fval, pmd->count);
|
|
}
|
|
|
|
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;
|
|
|
|
/* XXX metadata */
|
|
if (NULL != pmd) {
|
|
// fprintf(stderr, "ok, %s give an 'a' flag\n", __func__);
|
|
filehead.magic[4] = 'a';
|
|
}
|
|
|
|
foo = fwrite(&filehead, sizeof(FimgFileHead), 1, fp);
|
|
if (1 != foo) {
|
|
perror(fname);
|
|
fclose(fp);
|
|
/* may be here, we can remove the broken file ? */
|
|
return -2;
|
|
}
|
|
|
|
/* we have metadata, put them on tape */
|
|
if (NULL != pmd) {
|
|
// fprintf(stderr, ">>> %s write metadata %p\n", __func__, pmd);
|
|
foo = fwrite(pmd, sizeof(FimgMetaData), 1, fp);
|
|
if (1 != foo) {
|
|
perror(fname);
|
|
fclose(fp);
|
|
/* may be here, we can remove the broken file ? */
|
|
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;
|
|
}
|
|
/* ---------------------------------------------------------------- */
|
|
/*
|
|
* /!\ this 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 (notused) {
|
|
fprintf(stderr, "%s: notused must be 0, was %d\n", \
|
|
__func__, notused);
|
|
}
|
|
|
|
if (FIMG_TYPE_RGB != fimg->type) {
|
|
fprintf(stderr, "%s : bad type %d\n", __func__, fimg->type);
|
|
return -8;
|
|
}
|
|
|
|
// fprintf(stderr, "'%s' try to open '%s'\n", __func__, fname);
|
|
fp = fopen(fname, "w");
|
|
// fprintf(stderr, " fp at %p\n", fp);
|
|
|
|
if (NULL == fp) {
|
|
perror(fname);
|
|
return -1;
|
|
}
|
|
else {
|
|
// fprintf(stderr, "file '%s' opened\n", fname);
|
|
}
|
|
|
|
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;
|
|
}
|
|
// fprintf(stderr, "'%s' write header --> %d\n", __func__, foo);
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
/* XXX preparer la gestion des metadata */
|
|
if ('a' == filehead.magic[4]) {
|
|
if (verbosity > 1) fprintf(stderr,"%s say %s have metadata\n",
|
|
__func__, fname);
|
|
foo = fseek(fp, (long)sizeof(FimgMetaData), SEEK_CUR);
|
|
if (foo) {
|
|
fprintf(stderr, "%s: seek error\n", __func__);
|
|
perror(fname);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
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 from caller is not blank ? Or just
|
|
* display a warning ?
|
|
*/
|
|
|
|
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;
|
|
}
|
|
|
|
/* bugfix Sat 14 May 2022 07:02:53 PM CEST */
|
|
/*
|
|
* Oh boy, we have to skeep the metadata chunck
|
|
*/
|
|
if ('a' == filehead.magic[4]) {
|
|
if (verbosity > 1)
|
|
{ fprintf(stderr, "in %s, %s has metadata\n", __func__, fname); }
|
|
/* old school processing...
|
|
foo = fseek(fp, (long)sizeof(FimgMetaData), SEEK_CUR);
|
|
*/
|
|
foo = fread(&head->mdatas, sizeof(FimgMetaData), 1, fp);
|
|
if (1 != foo) {
|
|
fprintf(stderr, "%s: shit hit the fan %d\n", __func__, foo);
|
|
abort();
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|