Bibliothèque de traitements d'images en virgule flottante.
http://la.buvette.org/photos/cumul/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
4.1 KiB
199 lines
4.1 KiB
/* |
|
* 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; |
|
} |
|
/* ---------------------------------------------------------------- */
|
|
|