FloatImg/lib/fimg-pnm.c

200 lines
4.1 KiB
C

/*
* fimg-pnm.c
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "string.h"
#include "../floatimg.h"
extern int verbosity; /* must be declared around main() */
/* ---------------------------------------------------------------- */
/* nouveau juin 2019, pendant la Ravebish */
int fimg_load_from_pnm(char *fname, FloatImg *head, int notused)
{
FILE *fp;
int width, height, maxval;
int foo, line, column;
unsigned char *buffline, *idxrd, dummychar;
float *Rptr, *Gptr, *Bptr;
if (NULL==head) {
fprintf(stderr, "%s : head ptr is %p\n", __func__, head);
return -8;
}
if (NULL==(fp=fopen(fname, "r"))) {
perror(fname);
exit(1);
}
foo = fscanf(fp, "P6 %d %d %d", &width, &height, &maxval);
if (3 != foo) {
fprintf(stderr, "%s : fscanf -> %d\n", __func__, foo);
return -1;
}
if (verbosity) {
fprintf(stderr, "%s is %dx%d , max=%d\n",fname, width, height, maxval);
}
if (NULL==(buffline=calloc(3, width))) {
fprintf(stderr, "%s on %s : memory error\n", __func__, fname);
return -2;
}
foo = fimg_create(head, width, height, 3);
if (foo) {
fprintf(stderr, "%s : create floatimg -> %d\n", __func__, foo);
exit(1);
}
#if DEBUG_LEVEL
fread(&dummychar, 1, 1, fp);
fprintf(stderr, "%s : dummychar %xx\n", __func__, dummychar);
#else
fseek(fp, 1L, SEEK_CUR); /* black magic */
#endif
Rptr = head->R; Gptr = head->G; Bptr = head->B;
for (line=0; line<height; line++) {
foo = fread(buffline, 3, width, fp);
// fprintf(stderr, "line %d read %d\n", line, width);
idxrd = buffline;
for (column=0; column<width; column++)
{
*Rptr++ = (float)*idxrd++;
*Gptr++ = (float)*idxrd++;
*Bptr++ = (float)*idxrd++;
}
}
fclose(fp);
return 0;
}
/* ---------------------------------------------------------------- */
static void dump_gray_values(FILE *fp, FloatImg *picz, float fk)
{
int cnt, sz, value;
int idx;
cnt = 0;
sz = picz->width * picz->height;
for (idx=0; idx<sz; idx++) {
if (fk > 0) value = (int)(picz->R[idx] / fk);
else value = 0;
cnt += fprintf(fp, "%d", value);
if (cnt > 70) {
fputs("\n", fp); cnt = 0;
}
else {
fputs(" ", fp); cnt++;
}
}
fputs("\n", fp);
}
/* ---------------------------------------------------------------- */
static void dump_rgb_values(FILE *fp, FloatImg *picz, float fk)
{
int cnt, sz, idx;
int Rv, Gv, Bv;
cnt = 0;
sz = picz->width * picz->height;
for (idx=0; idx<sz; idx++) {
if (fk > 0) {
Rv = (int)(picz->R[idx] / fk);
Gv = (int)(picz->G[idx] / fk);
Bv = (int)(picz->B[idx] / fk);
}
else {
Rv = Gv = Bv = 0;
}
cnt += fprintf(fp, "%d %d %d", Rv, Gv, Bv);
if (cnt > 60) {
fputs("\n", fp); cnt = 0;
}
else {
fputs(" ", fp); cnt++;
}
}
fputs("\n", fp);
}
/* ---------------------------------------------------------------- */
/*
* bit 0 of flags : use fvalue/count
*/
int fimg_save_as_pnm(FloatImg *head, char *fname, int flags)
{
FILE *fp;
float maximum, fk;
char *code;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %-25s ( %p '%s' 0x%04x )\n", __func__, head,
fname, flags);
#endif
if ( head->type != FIMG_TYPE_RGB && head->type != FIMG_TYPE_GRAY) {
#if DEBUG_LEVEL
fprintf(stderr, "%s : type %d is bad.\n", __func__, head->type);
#endif
return -1;
}
if (NULL==(fp=fopen(fname, "w"))) {
perror(fname);
return -2;
}
switch(head->type) {
case FIMG_TYPE_GRAY: code = "P2"; break;
case FIMG_TYPE_RGB: code = "P3"; break;
}
fprintf(fp, "%s\n%d %d\n", code, head->width, head->height);
if ( flags & 1 ) {
fk = (head->fval * head->count) / 65535.0;
if (verbosity > 1) {
fprintf(stderr, "%s using fval/count %f %d -> %f\n",
__func__,
head->fval, head->count, fk);
}
fprintf(fp, "# fval/count %f %d\n", head->fval, head->count);
}
else {
maximum = fimg_get_maxvalue(head);
fk = maximum / 65535.0;
fprintf(fp, "# maxval %15f\n# divisor %15f\n", maximum, fk);
}
fprintf(fp, "65535\n");
fflush(fp);
switch(head->type) {
case FIMG_TYPE_GRAY:
dump_gray_values(fp, head, fk);
break;
case FIMG_TYPE_RGB:
dump_rgb_values(fp, head, fk);
break;
}
fputs("\n", fp);
fclose(fp);
return 0;
}
/* ---------------------------------------------------------------- */