source tree refactor and build system (to be completed)

This commit is contained in:
John Doe
2021-05-11 22:44:13 +02:00
parent cc79dd5152
commit bbc0309591
121 changed files with 259 additions and 290 deletions

234
src/floatimg.h Normal file
View File

@@ -0,0 +1,234 @@
/*
* floatimg.h
* ugly code from tTh
* http://la.buvette.org/photos/cumul
*/
#define FIMG_VERSION 145
/*
* in memory descriptor
*/
#define MAGIC_FIMG 0x00F11F00
typedef struct {
unsigned long magic;
int width;
int height;
int type;
float fval;
int count;
float *R, *G, *B, *A;
int reserved;
} FloatImg;
/*
* fimg file header
*/
typedef struct {
char magic[8];
int w, h, t;
} FimgFileHead;
#define MAGIC_AREA51 0xA5EA0051
typedef struct {
unsigned long magic;
int w, h;
int x, y;
int flags;
} FimgArea51;
#define FIMG_TYPE_GRAY 1
#define FIMG_TYPE_RGB 3
#define FIMG_TYPE_RGBA 4
#define FIMG_TYPE_RGBZ 99
#define FILE_TYPE_FIMG 1
#define FILE_TYPE_PNM 2
#define FILE_TYPE_PNG 3
#define FILE_TYPE_TGA 4
#define FILE_TYPE_TIFF 5
#define FILE_TYPE_FITS 6
#define FILE_TYPE_BMP 7
#define FILE_TYPE_EXR 8
/* lib/contrast.c */
#define CONTRAST_NONE 0
#define CONTRAST_SQRT 1
#define CONTRAST_POW2 2
#define CONTRAST_COS01 3
#define CONTRAST_COS010 4
/*
* core module
*/
int fimg_create(FloatImg *fimg, int w, int h, int t);
int fimg_destroy(FloatImg *fimg);
int fimg_clone(FloatImg *fimg, FloatImg *newpic, int flags);
int fimg_copy_data(FloatImg *from, FloatImg *to);
int fimg_type_is_valid(int type);
int fimg_print_version(int k);
void fimg_print_sizeof(void);
void fimg_printhead(FloatImg *h);
void fimg_printdims(char *txt, FloatImg *pi);
int fimg_describe(FloatImg *head, char *txt);
char *fimg_str_type(int type);
int fimg_plot_rgb (FloatImg *head, int x, int y,
float r, float g, float b);
int fimg_get_rgb(FloatImg *head, int x, int y, float *rgb);
int fimg_put_rgb(FloatImg *head, int x, int y, float *rgb);
int fimg_clear(FloatImg *fimg);
int fimg_add_rgb(FloatImg *head, int x, int y, float r, float g, float b);
int fimg_rgb_constant(FloatImg *head, float r, float g, float b);
/* --> lib/fimg-compare.c */
int fimg_images_not_compatible(FloatImg *a, FloatImg *b);
int fimg_interpolate(FloatImg *s1, FloatImg *s2, FloatImg *d, float coef);
/* 'operats' module */
int fimg_add_3(FloatImg *a, FloatImg *b, FloatImg *d);
int fimg_add_2(FloatImg *a, FloatImg *b); /* B+=A */
int fimg_sub_3(FloatImg *a, FloatImg *b, FloatImg *d);
int fimg_mul_3(FloatImg *a, FloatImg *b, FloatImg *d);
int fimg_minimum(FloatImg *a, FloatImg *b, FloatImg *d);
int fimg_maximum(FloatImg *a, FloatImg *b, FloatImg *d);
/* funcs/filtrage.c */
typedef struct {
float matrix[9];
float mult;
float offset;
} FimgFilter3x3;
int fimg_killborders(FloatImg *img);
int fimg_lissage_2x2(FloatImg *img);
int fimg_filter_3x3(FloatImg *s, FloatImg *d, FimgFilter3x3 *filtr);
int fimg_contour_2x2(FloatImg *psrc, FloatImg *pdst, int reverse);
/* module sfx0.c */
int fimg_killcolors_a(FloatImg *fimg, float fval);
int fimg_killcolors_b(FloatImg *fimg, float fval);
int fimg_colors_mixer_a(FloatImg *fimg, float fval);
/* module sfx1.c */
int fimg_highlight_color(FloatImg *src, FloatImg *dst,
char color, float fval);
/* module sfx2.c */
int fimg_binarize(FloatImg *pimg, int notused);
int fimg_trinarize(FloatImg *pimg, int notused);
/* funcs/rotate.c module */
/* #coronamaison */
int fimg_rotate_90(FloatImg *src, FloatImg *dst, int notused);
/* universal exporter XXX */
int fimg_export_picture(FloatImg *pic, char *fname, int flags);
/* PNM files module */
int fimg_save_as_pnm(FloatImg *head, char *fname, int flags);
int fimg_load_from_pnm(char *fname, FloatImg *head, int notused);
double fimg_timer_set(int whot);
double fimg_timer_get(int whot);
/* --> lib/contrast.c */
int fimg_id_contraste(char *name);
int fimg_square_root(FloatImg *s, FloatImg *d, double maxval);
int fimg_power_2(FloatImg *s, FloatImg *d, double maxval);
int fimg_cos_01(FloatImg *s, FloatImg *d, double maxval);
int fimg_cos_010(FloatImg *s, FloatImg *d, double maxval);
int fimg_mix_rgb_gray(FloatImg *img, float mix);
/* funcs/saturation.c */
int fimg_shift_to_zero(FloatImg *s, FloatImg *d, float coefs[6]);
int fimg_auto_shift_to_zero(FloatImg *s, FloatImg *d);
/* --> funcs/plasmas.c */
int fimg_prototype_plasma(FloatImg *img, double time, int type);
/* * * * experimental ! */
int fimg_classif_trial(FloatImg *src, FloatImg*dst, float fval, int notused);
int fimg_qsort_rgb_a(FloatImg *psrc, FloatImg *pdst, int notused);
int fimg_qsort_rgb_b(FloatImg *psrc, FloatImg *pdst, int notused);
/* module funcs/??????.c */
int fimg_equalize_compute(FloatImg *src, void *vptr, float vmax);
int fimg_mk_gray_from(FloatImg *src, FloatImg*dst, int k);
int fimg_desaturate(FloatImg *src, FloatImg *dst, int notused);
/* module funcs/geometry.c */
/* warning, this module is a mess */
int fimg_halfsize_0(FloatImg *src, FloatImg *dst, int notused);
int fimg_halfsize_1(FloatImg *src, FloatImg *dst, int notused);
int fimg_extractor(FloatImg *in, FloatImg *out, FimgArea51 *rect);
int fimg_mirror(FloatImg *src, FloatImg *dst, int notused);
int fimg_incrustator_0(FloatImg *psrc, FloatImg *pdst,
int xpos, int ypos, int flags);
int fimg_displacement_0(FloatImg *psrc, FloatImg *pdst, int flags);
/* module funcs/rampes.c */
int fimg_hdeg_a(FloatImg *img, double dcoef);
int fimg_vdeg_a(FloatImg *img, double dcoef);
/* FIMG files module */
int fimg_fileinfos(char *fname, int *datas);
int fimg_dump_to_file(FloatImg *head, char *fname, int notused);
int fimg_load_from_dump(char *fname, FloatImg *where);
int fimg_create_from_dump(char *fname, FloatImg *head);
int fimg_save_R_as_fits(FloatImg *src, char *outname, int flags);
int fimg_save_G_as_fits(FloatImg *src, char *outname, int flags);
int fimg_save_B_as_fits(FloatImg *src, char *outname, int flags);
int fimg_save_plane_as_fits(FloatImg *src, char *oname, char plane, int flags);
int fimg_write_as_tiff(FloatImg *src, char *fname, int flags);
int fimg_save_as_exr(FloatImg *src, char *outname, int flags);
/* mathematics operations */
float fimg_get_maxvalue(FloatImg *head);
int fimg_get_minmax_rgb(FloatImg *head, float mmvals[6]);
int fimg_meanvalues(FloatImg *head, float means[4]);
int fimg_to_gray(FloatImg *head);
int fimg_add_cste(FloatImg *fi, float value);
int fimg_mul_cste(FloatImg *fi, float value);
int fimg_ajust_from_grab(FloatImg *fi, double maxima, int notused);
void fimg_drand48(FloatImg *fi, float kmul);
long fimg_count_negativ(FloatImg *fi);
long fimg_clamp_negativ(FloatImg *fi);
/* various funcs modules */
int fimg_load_from_png(char *filename, FloatImg *fimg);
int fimg_create_from_png(char *filename, FloatImg *fimg);
int fimg_save_as_png(FloatImg *src, char *outname, int flags);
int fimg_save_as_bmp(FloatImg *src, char *outname, int flags);
int fimg_test_pattern(FloatImg *fimg, int type, double dval);
int fimg_draw_something(FloatImg *fimg);
int fimg_multirandom(FloatImg *fimg, long nbpass);
/* file is 'funcs/utils.c' */
void fimg_print_minmax(float minmax[6], char *titre);
int parse_WxH(char *str, int *pw, int *ph);
int parse_double(char *str, double *dptr);
int print_rectangle(char *str, FimgArea51 *rect);
int parse_rectangle(char *str, FimgArea51 *r, int notused);
int format_from_extension(char *fname);
char * extension_from_format(int fmt);

138
src/funcs/Makefile Normal file
View File

@@ -0,0 +1,138 @@
#---------------------------------------------------------------
# Please, use the 'Gloabl.makefile' system !
LIB_DIR = ../../build/lib
OBJ_DIR = ../../build/obj
STATIC_LIB = $(LIB_DIR)/libfloatimg.a
DYN_OBJ = $(OBJ_DIR)/libfloatimg-funcs.o
COPT = -Wall -fpic -g -no-pie -DDEBUG_LEVEL=0
DEPS = ../floatimg.h Makefile
OBJS = fimg-png.o fimg-tiff.o misc-plots.o filtrage.o utils.o \
fimg-libpnm.o rampes.o sfx0.o sfx1.o sfx2.o \
geometry.o rotate.o fimg-openexr.o \
equalize.o fimg-fits.o saturation.o histogram.o \
hsv.o classif.o contour2x2.o qsortrgb.o exporter.o \
displacement.o dithering.o plasmas.o incrustator.o \
recurse.o
all: $(OBJS) $(STATIC_LIB) $(DYN_OBJ)
#---------------------------------------------------------------
t: t.c $(DEPS) ../libfloatimg.a tests.o
gcc $(COPT) $< \
tests.o \
-I/usr/include/netpbm/ \
-I/usr/include/cfitsio/ \
../libfloatimg.a -lnetpbm -lpnglite -lcfitsio \
-ltiff \
-lz -lm -o $@
tests.o: tests.c tests.h $(DEPS)
gcc $(COPT) -I/usr/include/netpbm -c $<
#---------------------------------------------------------------
# upper-level functions
$(STATIC_LIB): $(OBJS)
$(AR) r $@ $?
$(DYN_OBJ): $(OBJS)
mkdir -p $(OBJ_DIR)
ld -Ur -o $@ $?
clean:
rm -rf $(OBJS) $(STATIC_LIB) $(DYN_OBJ)
recurse.o: recurse.c $(DEPS)
gcc $(COPT) -c $<
incrustator.o: incrustator.c $(DEPS)
gcc $(COPT) -c $<
displacement.o: displacement.c $(DEPS)
gcc $(COPT) -c $<
fimg-png.o: fimg-png.c $(DEPS)
gcc $(COPT) -c $<
fimg-bmp.o: fimg-bmp.c $(DEPS)
gcc $(COPT) -c $<
fimg-tiff.o: fimg-tiff.c $(DEPS)
gcc $(COPT) -c $<
fimg-openexr.o: fimg-openexr.c $(DEPS)
gcc $(COPT) -c $<
fimg-fits.o: fimg-fits.c $(DEPS)
gcc $(COPT) -I/usr/include/cfitsio/ -c $<
fimg-libpnm.o: fimg-libpnm.c $(DEPS)
gcc $(COPT) -I/usr/include/netpbm -c $<
misc-plots.o: misc-plots.c $(DEPS)
gcc $(COPT) -c $<
filtrage.o: filtrage.c $(DEPS)
gcc $(COPT) -c $<
geometry.o: geometry.c $(DEPS)
gcc $(COPT) -c $<
rotate.o: rotate.c $(DEPS)
gcc $(COPT) -c $<
saturation.o: saturation.c $(DEPS)
gcc $(COPT) -c $<
histogram.o: histogram.c $(DEPS)
gcc $(COPT) -c $<
equalize.o: equalize.c $(DEPS)
gcc $(COPT) -c $<
dithering.o: dithering.c $(DEPS)
gcc $(COPT) -c $<
plasmas.o: plasmas.c $(DEPS)
gcc $(COPT) -c $<
sfx0.o: sfx0.c $(DEPS)
gcc $(COPT) -c $<
sfx1.o: sfx1.c $(DEPS)
gcc $(COPT) -c $<
sfx2.o: sfx2.c $(DEPS)
gcc $(COPT) -c $<
contour2x2.o: contour2x2.c $(DEPS)
gcc $(COPT) -c $<
rampes.o: rampes.c $(DEPS)
gcc $(COPT) -c $<
classif.o: classif.c $(DEPS)
gcc $(COPT) -c $<
qsortrgb.o: qsortrgb.c $(DEPS)
gcc $(COPT) -c $<
exporter.o: exporter.c $(DEPS)
gcc $(COPT) -c $<
hsv.o: hsv.c $(DEPS)
gcc $(COPT) -c $<
utils.o: utils.c $(DEPS)
gcc $(COPT) -c $<

26
src/funcs/README.md Normal file
View File

@@ -0,0 +1,26 @@
# Fonctions
Plein de fonctions qu'il serait bon de documenter :)
## PNG
__Attention__ : la bibliothèque `pnglite`actuellement utiilsée pour lire les
fichiers PNG n'accepte que **certains** types de fichiers.
Et en particulier, elle brotche sur ceux produits par ImageMagick !
## Contours
Détecter des contours est une activité respectable.
## Exporter
Une méta-fonction qui va sauvegarder (dans la mesure de ses conséquences)
une image en fonction de l'extension du nom de fichier.
## Sfx
Effets spéciaux divers.
## Dithering
Work in progress...

33
src/funcs/alltests.sh Executable file
View File

@@ -0,0 +1,33 @@
#!/bin/bash
#
# trying to run a maximum of ugly code
#
for trial in $(./t -l)
do
printf "============ %-10s ============\n" $trial
make t
error=$?
if [ 0 -ne $error ]
then
echo "make error is " $error
exit 1
fi
./t -v $trial
error=$?
if [ 0 -ne $error ]
then
echo "run error is " $error
exit 1
fi
printf "\t=== return code %d\n" $error
echo
sleep 10
done

103
src/funcs/classif.c Normal file
View File

@@ -0,0 +1,103 @@
/*
* classif.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
/* nouveau 2 octobre 2020, juste avant sonoptic de la pluie craignos */
int fimg_classif_trial(FloatImg *psrc, FloatImg *pdst, float fval, int notused)
{
float minmax[6], delta[3], baryc[3];
float range, dist, rgb[3], dr, dg, db;
int x, y, on, off;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %f %d )\n", __func__,
psrc, pdst, fval, notused);
#endif
if (FIMG_TYPE_RGB != psrc->type) {
fprintf(stderr, "%s: bad src type %d\n", __func__, psrc->type);
return -7;
}
if (fimg_images_not_compatible(psrc, pdst)) {
fprintf(stderr, "%s: bad dst type %d\n", __func__, pdst->type);
return -8;
}
/* calculer les amplitudes RGB de l'image source */
fimg_get_minmax_rgb(psrc, minmax);
delta[0] = minmax[1] - minmax[0];
delta[1] = minmax[3] - minmax[2];
delta[2] = minmax[5] - minmax[4];
/* chercher le plus petit des deltas */
range = delta[0]; if (delta[1]<range) range=delta[1];
if (delta[2]<range) range=delta[2];
/* convertir le diametre en rayon (magic inside) */
range *= fval;
if (verbosity > 1) fprintf(stderr, "deltas : %f %f %f / %f\n",
delta[0], delta[1], delta[2], range);
/* calcul du "barycentre" chromatique */
baryc[0] = (minmax[1] + minmax[0]) / 2;
baryc[1] = (minmax[3] + minmax[2]) / 2;
baryc[2] = (minmax[5] + minmax[4]) / 2;
if (verbosity > 1) fprintf(stderr, "barycs : %f %f %f\n",
baryc[0], baryc[1], baryc[2]);
on = off = 0;
for (y=0; y<psrc->height; y++) {
for (x=0; x<psrc->width; x++) {
fimg_get_rgb(psrc, x, y, rgb);
/* calcul de la distance chromatique */
dr = rgb[0] - baryc[0];
dg = rgb[1] - baryc[1];
db = rgb[2] - baryc[2];
dist = sqrtf( (dr*dr) + (dg*dg) + (db*db) );
#if DEBUG_LEVEL
if (x==y) fprintf(stderr, "%4d %4d %f\n", x, y, dist);
#endif
/* action !!! */
if (dist > range) {
/* make our pixel gray-level */
rgb[0] = rgb[1] = rgb[2] = 0.0;
// (rgb[0] + rgb[1] + rgb[2]) / 3.0;
on++;
}
else {
/* the easy part : do nothing */
off++;
}
fimg_put_rgb(pdst, x, y, rgb);
/* MUST BE MORE CREATIVE HERE !!! */
}
}
if (verbosity > 1) fprintf(stderr, "on %d off %d\n", on, off);
return 0;
}
/* --------------------------------------------------------------------- */

95
src/funcs/contour2x2.c Normal file
View File

@@ -0,0 +1,95 @@
/*
* Detection de contours
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
/* nouveau 4 octobre 2020, juste avant sonoptic de la pluie craignos */
int fimg_contour_2x2(FloatImg *psrc, FloatImg *pdst, int reverse)
{
float avg[4];
int foo, x, y, q;
float v1, v2;
int tbl[] = /* deep magic inside */
{
0, 1, 1, 1,
1, 1, 0, 1,
1, 0, 1, 1,
1, 1, 1, 0
}; /* please explain */
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__, psrc, pdst, reverse);
#endif
if (FIMG_TYPE_RGB != psrc->type) {
fprintf(stderr, "%s: bad src type %d\n", __func__, psrc->type);
return -7;
}
if (fimg_images_not_compatible(psrc, pdst)) {
fprintf(stderr, "%s: bad dst type %d\n", __func__, pdst->type);
return -8;
}
if (reverse) {
v1 = 0.0; v2 = 1.0;
}
else {
v1 = 1.0; v2 = 0.0;
}
foo = fimg_meanvalues(psrc, avg);
if (foo) {
fprintf(stderr, "%s: err %d on fimg_meanvalues\n", __func__, foo);
return foo;
}
if (verbosity > 1) {
fprintf(stderr, "%s: %f %f %f\n", __func__, avg[0], avg[1], avg[2]);
}
#define RP(ix, iy) ( psrc->R[((iy)*psrc->width)+(ix)] < avg[0] )
#define GP(ix, iy) ( psrc->G[((iy)*psrc->width)+(ix)] < avg[1] )
#define BP(ix, iy) ( psrc->B[((iy)*psrc->width)+(ix)] < avg[2] )
for (y=0; y<psrc->height-1; y++) {
for (x=0; x<psrc->width-1; x++) {
q = ( ( RP(x, y) << 3 ) |
( RP(x+1, y) << 2 ) |
( RP(x, y+1) << 1 ) |
( RP(x+1, y+1) ) );
pdst->R[(y*psrc->width)+x] = tbl[q] ? v1 : v2 ;
q = ( ( GP(x, y) << 3 ) |
( GP(x+1, y) << 2 ) |
( GP(x, y+1) << 1 ) |
( GP(x+1, y+1) ) );
pdst->G[(y*psrc->width)+x] = tbl[q] ? v1 : v2 ;
q = ( ( BP(x, y) << 3 ) |
( BP(x+1, y) << 2 ) |
( BP(x, y+1) << 1 ) |
( BP(x+1, y+1) ) );
pdst->B[(y*psrc->width)+x] = tbl[q] ? v1 : v2 ;
}
}
/* kill potential NaN values in last row or last column */
fimg_killborders(pdst);
return 0;
}
/* --------------------------------------------------------------------- */

92
src/funcs/displacement.c Normal file
View File

@@ -0,0 +1,92 @@
/*
* displacement.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
/* nouveau 24 octobre 2020, pendant le masque-flamme coronavidique */
int fimg_displacement_0(FloatImg *psrc, FloatImg *pdst, int flags)
{
int x, y, foo;
float minmax[6];
float rgb[3];
float dltr, dltg, dltb; /* delta des minmax */
float dispx, dispy;
int dstx, dsty;
int in, out;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p 0x%04x )\n", __func__, psrc, pdst, flags);
#endif
if (FIMG_TYPE_RGB != psrc->type) {
fprintf(stderr, "%s: bad src type %d\n", __func__, psrc->type);
return -7;
}
if (fimg_images_not_compatible(psrc, pdst)) {
fprintf(stderr, "%s: bad dst type %d\n", __func__, pdst->type);
return -8;
}
foo = fimg_get_minmax_rgb(psrc, minmax);
if (verbosity) {
fimg_print_minmax(minmax, (char *)__func__);
}
dltr = minmax[1] - minmax[0];
dltg = minmax[3] - minmax[2];
dltb = minmax[5] - minmax[4];
in = out = 0;
/*
* BE WARNED !
* This code doesn't work as expected, so I have to
* rewrite it, maybe when the pandemic is closed...
*/
for (y=0; y<psrc->height; y++) {
for (x=0; x<psrc->width; x++) {
fimg_get_rgb(psrc, x, y, rgb);
dispx = (float)x + (rgb[1]/dltg * 20.0);
dispy = (float)y + (rgb[2]/dltb * 10.0);
dstx = (int)roundf(dispx - 10.0);
dsty = (int)roundf(dispy - 10.0);
if ( (dstx < 0) || (dsty < 0) ||
(dstx >= psrc->width) ||
(dsty >= psrc->height) )
{
/* OUT OF DESTINATION PICTURE */
out++;
}
else {
if (flags & 1) {
/* going monochrome */
rgb[1] = rgb[2] = rgb[0];
}
fimg_put_rgb(pdst, dstx, dsty, rgb);
in++;
}
}
}
if (verbosity) fprintf(stderr, "%s -> in %d out %d\n", __func__, in, out);
return 0;
}
/* --------------------------------------------------------------------- */

31
src/funcs/dithering.c Normal file
View File

@@ -0,0 +1,31 @@
/*
* FloatImg : some dithering experiments
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
int fimg_dither_0(FloatImg *psrc, FloatImg *pdst, int flags)
{
int x, y;
for (y=0; y<psrc->height; y++) {
for (x=0; x<psrc->width; x++)
{
}
}
return -1;
}
/* --------------------------------------------------------------------- */

53
src/funcs/equalize.c Normal file
View File

@@ -0,0 +1,53 @@
/*
* FLOATIMG
* egalisation dynamique approximative
* #coronamaison Thu 09 Apr 2020 03:37:10 PM CEST
*/
#include <stdio.h>
#include <string.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
int fimg_equalize_compute(FloatImg *src, void *vptr, float vmax)
{
float minmax[6];
int foo;
float dr, dg, db;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %f )\n", __func__, src, vptr, vmax);
#endif
memset(minmax, 0, 6*sizeof(float));
foo = fimg_get_minmax_rgb(src, minmax);
if (foo) {
fprintf(stderr, "err %d get minmax in %s\n", foo, __func__);
return foo;
}
dr = minmax[1] - minmax[0];
dg = minmax[3] - minmax[2];
db = minmax[5] - minmax[4];
printf("Rmin %12.4g max %12.4g delta %12.4g\n", minmax[0], minmax[1], dr);
printf("Gmin %12.4g max %12.4g delta %12.4g\n", minmax[2], minmax[3], dg);
printf("Bmin %12.4g max %12.4g delta %12.4g\n", minmax[4], minmax[5], db);
if ( (minmax[0]<0.0) || (minmax[2]<0.0) || (minmax[4]<0.0) ) {
fprintf(stderr, "%s: negative value ?\n", __func__);
return -4;
}
// printf("deltas %12.4g %12.4g %12.4g\n", dr, dg, db);
return 0;
}
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */

73
src/funcs/exporter.c Normal file
View File

@@ -0,0 +1,73 @@
/*
* exporter.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
/*
* multi-magic 'save file' function.
*/
int fimg_export_picture(FloatImg *pic, char *fname, int flags)
{
int filetype;
int foo;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p '%s' 0x%X )\n", __func__,
pic, fname, flags);
#endif
filetype = format_from_extension(fname);
if (verbosity > 1) {
fprintf(stderr, "file %s have type %d\n", fname, filetype);
}
switch(filetype) {
case FILE_TYPE_FIMG:
foo = fimg_dump_to_file(pic, fname, 0);
break;
case FILE_TYPE_PNM:
foo = fimg_save_as_pnm(pic, fname, 0);
break;
case FILE_TYPE_PNG:
foo = fimg_save_as_png(pic, fname, 0);
break;
case FILE_TYPE_TGA:
fprintf(stderr, "%s: FILE_TYPE_TGA not implemented\n",
__func__);
foo = -666;
break;
case FILE_TYPE_TIFF:
foo = fimg_write_as_tiff(pic, fname, 0);
break;
case FILE_TYPE_FITS:
foo = fimg_save_R_as_fits(pic, fname, 0);
break;
case FILE_TYPE_BMP:
fprintf(stderr, "%s: file type BMP not implemented\n", __func__);
foo = -666;
case FILE_TYPE_EXR:
fprintf(stderr, "%s: file type EXR experimental\n", __func__);
foo = fimg_save_as_exr(pic, fname, 0);
default:
foo = -1789;
break;
}
if (foo) {
fprintf(stderr, "%s: exporting '%s' -> %d\n", __func__,
fname, foo);
/* que faire maintenant ? */
}
return foo;
}
/* --------------------------------------------------------------------- */

200
src/funcs/filtrage.c Normal file
View File

@@ -0,0 +1,200 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <float.h>
#include "../floatimg.h"
/* -------------------------------------------------------------------- */
int fimg_filter_3x3(FloatImg *src, FloatImg *dst, FimgFilter3x3 *filtr)
{
int x, y, w, h, of;
float *pr, *pg, *pb; /* alias for src pix filds */
float *M; /* alias of filter matrix */
double dval;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %p )\n", __func__, src, dst, filtr);
#endif
if (src->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s: src type %d invalid\n", __func__, src->type);
return -99;
}
if (dst->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s: dst type %d invalid\n", __func__, dst->type);
return -99;
}
if (fimg_images_not_compatible(src, dst)) {
fprintf(stderr, "%s: src & dst not comatibles\n", __func__);
return -98;
}
/* aliasing some vars for cleaner code */
pr = src->R; pg = src->G; pb = src->B;
w = src->width; h = src->height;
M = filtr->matrix;
for (y=1; y < h-1; y++) {
for (x=1; x < w-1; x++) {
of = x + (y * w);
dval = M[0] * pr[of-(w+1)] +
M[1] * pr[of-w] +
M[2] * pr[of-(w-1)] +
M[3] * pr[of-1] +
M[4] * pr[of] +
M[5] * pr[of+1] +
M[6] * pr[of+(w+1)] +
M[7] * pr[of+w] +
M[8] * pr[of+(w-1)] ;
dst->R[of] = dval + filtr->offset;
dval = M[0] * pg[of-(w+1)] +
M[1] * pg[of-w] +
M[2] * pg[of-(w-1)] +
M[3] * pg[of-1] +
M[4] * pg[of] +
M[5] * pg[of+1] +
M[6] * pg[of+(w+1)] +
M[7] * pg[of+w] +
M[8] * pg[of+(w-1)] ;
dst->G[of] = dval + filtr->offset;
dval = M[0] * pb[of-(w+1)] +
M[1] * pb[of-w] +
M[2] * pb[of-(w-1)] +
M[3] * pb[of-1] +
M[4] * pb[of] +
M[5] * pb[of+1] +
M[6] * pb[of+(w+1)] +
M[7] * pb[of+w] +
M[8] * pb[of+(w-1)] ;
dst->B[of] = dval + filtr->offset;
}
}
return 0;
}
/* -------------------------------------------------------------------- */
/*
* this is the more shifting hack on the block.
*/
static int fimg_lissage_2x2_a(FloatImg *img)
{
int x, y, offset;
float cr, cg, cb;
float *pr, *pg, *pb;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p )\n", __func__, img);
fprintf(stderr," type %d size %dx%d\n", img->type,
img->width, img->height);
#endif
if (img->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n", __func__, img->type);
return -99;
}
pr = img->R; pg = img->G; pb = img->B;
for (y=1; y < img->height-1; y++) {
for (x=1; x < img->width-1; x++) {
offset = x + (y * img->width);
cr = pr[offset] + pr[offset+1] +
pr[offset+img->width] + pr[offset+img->width+1];
cg = pg[offset] + pg[offset+1] +
pg[offset+img->width] + pg[offset+img->width+1];
cb = pb[offset] + pb[offset+1] +
pb[offset+img->width] + pb[offset+img->width+1];
pr[offset] = cr / 4.0;
pg[offset] = cg / 4.0;
pb[offset] = cb / 4.0;
}
}
return 0;
}
/* -------------------------------------------------------------------- */
int fimg_killborders(FloatImg *img)
{
int idx, h, w, o;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p )\n", __func__, img);
fprintf(stderr," type %d size %dx%d\n", img->type,
img->width, img->height);
#endif
if (img->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n", __func__, img->type);
return -99;
}
h = img->height; w = img->width;
for (idx=0; idx<h; idx++) {
#define FAST 1
#if FAST
img->R[idx*w] = 0.0;
img->G[idx*w] = 0.0;
img->B[idx*w] = 0.0;
img->R[(idx*w)+w-1] = 0.0;
img->G[(idx*w)+w-1] = 0.0;
img->B[(idx*w)+w-1] = 0.0;
#else
fimg_plot_rgb(img, 0, idx, 0.0, 0.0, 0.0);
fimg_plot_rgb(img, w-1, idx, 0.0, 0.0, 0.0);
#endif
}
o = w * (h - 1);
for (idx=0; idx<w; idx++) {
#if FAST
img->R[idx] = 0.0;
img->G[idx] = 0.0;
img->B[idx] = 0.0;
img->R[idx+o] = 0.0;
img->G[idx+o] = 0.0;
img->B[idx+o] = 0.0;
#else
fimg_plot_rgb(img, idx, 0, 0.0, 0.0, 0.0);
fimg_plot_rgb(img, idx, h-1, 0.0, 0.0, 0.0);
#endif
}
return 0;
}
/* -------------------------------------------------------------------- */
int fimg_lissage_2x2(FloatImg *img)
{
int foo;
foo = fimg_lissage_2x2_a(img);
if (foo) {
fprintf(stderr, "%s: fail %d\n", __func__, foo);
return foo;
}
fimg_killborders(img);
return foo;
}
/* -------------------------------------------------------------------- */

21
src/funcs/fimg-bmp.c Normal file
View File

@@ -0,0 +1,21 @@
/*
* Lecture/ecriture des images BMP
* -------------------------------
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
int fimg_save_as_bmp(FloatImg *src, char *outname, int flags)
{
return -2;
}
/* --------------------------------------------------------------------- */

114
src/funcs/fimg-fits.c Normal file
View File

@@ -0,0 +1,114 @@
/*
* FLOATIMG
* import/export to/from FITS files
https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/node1.html
*/
#include <stdio.h>
#include <stdlib.h>
#include <fitsio.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
int fimg_save_plane_as_fits(FloatImg *src, char *outname,
char plane, int flags)
{
fitsfile *fptr; /* pointer to the FITS file */
int status, sz;
int bitpix = FLOAT_IMG;
float *pplane;
long naxis = 2;
long naxes[2];
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p '%s' %d )\n", __func__, src, outname, flags);
#endif
status = 0;
switch (plane) {
case 'r': case 'R':
pplane = src->R; break;
case 'g': case 'G':
pplane = src->G; break;
case 'b': case 'B':
pplane = src->B; break;
default:
return -66;
}
remove(outname); /* Delete old file if it already exists */
if (fits_create_file(&fptr, outname, &status)) {
fits_report_error(stderr, status);
return -9;
}
naxes[0] = src->width; naxes[1] = src->height;
if (verbosity) fimg_describe(src, "to be saved as FITS");
if ( fits_create_img(fptr, bitpix, naxis, naxes, &status) ) {
fits_report_error(stderr, status);
return -10;
}
sz = naxes[0]*naxes[1];
if ( fits_write_img(fptr, TFLOAT, 1, sz, pplane, &status) ) {
fits_report_error(stderr, status);
return -10;
}
if ( fits_close_file(fptr, &status) ) {
fits_report_error(stderr, status);
return -9;
}
return 0;
}
/* --------------------------------------------------------------------- */
int fimg_save_R_as_fits(FloatImg *src, char *outname, int flags)
{
int retv;
retv = fimg_save_plane_as_fits(src, outname, 'r', flags);
return retv;
}
/* --------------------------------------------------------------------- */
int fimg_save_G_as_fits(FloatImg *src, char *outname, int flags)
{
int retv;
retv = fimg_save_plane_as_fits(src, outname, 'g', flags);
return retv;
}
/* --------------------------------------------------------------------- */
int fimg_save_B_as_fits(FloatImg *src, char *outname, int flags)
{
int retv;
retv = fimg_save_plane_as_fits(src, outname, 'b', flags);
return retv;
}
/************************************************************
***** MAGIC CODE FROM OUTERSPACE ?
function 'writeimage' from :
https://heasarc.gsfc.nasa.gov/docs/software/fitsio/cexamples/cookbook.c
float **array;
array = calloc(src->height, sizeof(float *));
array[0] = src->R;
#define REVERSE 1
for( idx=0; idx<naxes[1]; idx++ ) {
#if REVERSE
k = naxes[1] - idx - 1;
#else
k = idx;
#endif
array[idx] = src->R + (k*naxes[0]);
fprintf(stderr, " %6d %6d %p\n", idx, k, array[idx]);
}
**************************************************************/

52
src/funcs/fimg-libpnm.c Normal file
View File

@@ -0,0 +1,52 @@
/*
* interface FloatImg <-> libpnm(3)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pam.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
static void print_struct_pam(struct pam *ppam, char *txt)
{
printf(" size %d\n", ppam->size);
printf(" format %d\n", ppam->format);
printf(" plainformat %d\n", ppam->plainformat);
printf(" width & height %d %d\n", ppam->width, ppam->height);
printf(" depth %d\n", ppam->depth);
printf(" maxval %lu\n", ppam->maxval);
}
/* --------------------------------------------------------------------- */
int fimg_pnm_infos(char *fname)
{
struct pam inpam;
FILE *fp;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' )\n", __func__, fname);
#endif
if (NULL==(fp=fopen(fname, "r"))) {
perror(fname);
exit(1);
}
pnm_readpaminit(fp, &inpam, sizeof(inpam));
print_struct_pam(&inpam, fname);
fclose(fp);
return 0;
}
/* --------------------------------------------------------------------- */

30
src/funcs/fimg-openexr.c Normal file
View File

@@ -0,0 +1,30 @@
/*
* Lecture/ecriture des images EXR
* -------------------------------
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
int fimg_save_as_exr(FloatImg *src, char *outname, int flags)
{
// #if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p '%s' 0x%X )\n", __func__, src, outname, flags);
// #endif
if (FIMG_TYPE_RGB != src->type) {
fprintf(stderr, "%s: src bad type %d\n", __func__, src->type);
return -2;
}
return -2;
}
/* --------------------------------------------------------------------- */

220
src/funcs/fimg-png.c Normal file
View File

@@ -0,0 +1,220 @@
/*
* Lecture des images PNG
* ----------------------
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pnglite.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
/*
* warning : this func has been tested only with
* RGB (3x8bits) PNG files
*
* Attention : certains fichiers, tels que ceux
* produits par ImageMagick ne sont pas lisibles
* par cette fonction :(
*/
int fimg_create_from_png(char *filename, FloatImg *fimg)
{
png_t png;
int foo, idx;
unsigned char *datas, *ptr;
int datasize;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %-25s ( '%s' %p )\n", __func__, filename, fimg);
#endif
/* We MUST clear the fimg destination header first */
memset(fimg, 0, sizeof(FloatImg));
memset(&png, 0, sizeof(png_t));
png_init(NULL, NULL); /* this is VITAL ! */
foo = png_open_file_read(&png, filename);
if (PNG_NO_ERROR != foo) {
fprintf(stderr, "%s :\n\topen_file '%s' = %d %s\n", __func__,
filename, foo, png_error_string(foo));
png_close_file(&png);
return foo;
}
#if DEBUG_LEVEL > 1
fprintf(stderr, "%s opened\n", filename);
#endif
if (verbosity) {
printf("----------- %s ---------\n", filename);
png_print_info(&png); puts("");
fflush(stdout);
}
if ( 3 != png.bpp ) {
fprintf(stderr, "bpp format %d of '%s' not supported\n",
png.color_type, filename);
return -21;
}
datasize = png.width * png.height * png.bpp;
datas = malloc(datasize);
if (NULL==datas) {
fprintf(stderr, "%s : fatal memory failure\n", __func__);
exit(1);
}
memset(fimg, 0, sizeof(FloatImg));
foo = fimg_create(fimg, png.width, png.height, 3);
if (foo) {
fprintf(stderr, "can't create fimg\n");
exit(1);
}
/* I GET AN 'Unknown file error' HERE, WHY ???*/
foo = png_get_data(&png, datas);
if (PNG_NO_ERROR != foo) {
fprintf(stderr, "err in '%s:%s' :\n\tpng_get_data -> %d = %s\n\n",
__FILE__, __func__, foo, png_error_string(foo));
png_close_file(&png);
return foo;
}
ptr = datas;
for (idx=0; idx<png.width * png.height; idx++) {
fimg->R[idx] = (float)*ptr++;
fimg->G[idx] = (float)*ptr++;
fimg->B[idx] = (float)*ptr++;
}
free(datas);
png_close_file(&png);
// fprintf(stderr, "png closed...\n");
return foo;
}
/* --------------------------------------------------------------------- */
/*
* warning : this func has been tested only with
* RGB (3x8bits) PNG files
*/
int fimg_load_from_png(char *filename, FloatImg *fimg)
{
png_t png;
int foo, idx, datasize;
unsigned char *datas, *ptr;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %-25s ( '%s' %p )\n", __func__, filename, fimg);
#endif
memset(&png, 0, sizeof(png_t));
png_init(NULL, NULL); /* this is VITAL ! */
foo = png_open_file_read(&png, filename);
if (PNG_NO_ERROR != foo) {
#if DEBUG_LEVEL
fprintf(stderr, "open png -> %d\n", foo);
#endif
return foo;
}
// puts(""); png_print_info(&png); puts("");
if ( 3 != png.bpp ) { /* TO BE PATCHED */
fprintf(stderr, "format of '%s' not supported\n", filename);
return -21;
}
/* check if floatimg and PNG have the same size */
if ((fimg->width != png.width) || (fimg->height != png.height)) {
fprintf(stderr, "%s : fatal error on images sizes\n", __func__);
exit(1);
}
datasize = png.width * png.height * png.bpp;
datas = malloc(datasize);
if (NULL==datas) {
fprintf(stderr, "%s : fatal memory failure\n", __func__);
exit(1);
}
foo = png_get_data(&png, datas);
if (PNG_NO_ERROR != foo) {
fprintf(stderr, "error in '%s' : read png -> %d\n",
__func__, foo);
return foo;
}
ptr = datas;
for (idx=0; idx<png.width * png.height; idx++) {
fimg->R[idx] = (float)*ptr++;
fimg->G[idx] = (float)*ptr++;
fimg->B[idx] = (float)*ptr++;
}
free(datas);
png_close_file(&png);
return 0;
}
/* --------------------------------------------------------------------- */
/* nouveau 13 decembre 2019 */
int fimg_save_as_png(FloatImg *src, char *outname, int flags)
{
png_t png;
int foo, sz, idx;
unsigned char *bytes, *bptr;
double maximum, fk;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %-25s ( %p '%s' 0x%x )\n", __func__, src, outname, flags);
#endif
/* convert ou floating datas to a byte/rgb array */
/* first, alloc a buffer */
sz = src->width * src->height;
bytes = calloc(sz, 3);
if (NULL==bytes) {
fprintf(stderr, "%s : no mem ?\n", __func__);
exit(3);
}
/* compute max value */
maximum = (double)fimg_get_maxvalue(src);
fk = maximum / 255.0;
if (verbosity > 1)
fprintf(stderr, "%s: max val %g fk %g\n", __func__, maximum, fk);
/* massage des pixels */
bptr = bytes;
for (idx=0; idx<sz; idx++) {
*bptr++ = (unsigned char) (src->R[idx] / fk);
*bptr++ = (unsigned char) (src->G[idx] / fk);
*bptr++ = (unsigned char) (src->B[idx] / fk);
}
memset(&png, 0, sizeof(png_t));
png_init(NULL, NULL); /* this is VITAL ! */
foo = png_open_file_write(&png, outname);
if (PNG_NO_ERROR != foo) {
fprintf(stderr, "error in '%s' : open_file_write -> %d\n",
__func__, foo);
return foo;
}
foo = png_set_data(&png, src->width, src->height, 8, PNG_TRUECOLOR, bytes);
if (PNG_NO_ERROR != foo) {
fprintf(stderr, "error in '%s' : set_data -> %d\n",
__func__, foo);
return foo;
}
png_close_file(&png);
free(bytes); /* yolo ? */
return 0;
}
/* --------------------------------------------------------------------- */

89
src/funcs/fimg-tiff.c Normal file
View File

@@ -0,0 +1,89 @@
/*
* FLOATIMG
* import/export to/from TIFF files
*/
#include <stdio.h>
#include <stdlib.h>
#include <tiffio.h>
#include "../floatimg.h"
/* --------------------------------------------------------------------- */
extern int verbosity;
/* --------------------------------------------------------------------- */
int fimg_write_as_tiff(FloatImg *src, char *fname, int flags)
{
TIFF *tiff;
unsigned short *linebuff, *ptr;
int x, y, idx, foo;
char ligne[100];
double maximum, fk;
/* bon, tout cela semble bien tortueux ! */
if (FIMG_TYPE_RGB != src->type) {
fprintf(stderr, "%s: src bad type %d\n", __func__, src->type);
return -2;
}
linebuff = calloc(src->width, 3*sizeof(unsigned short));
if (NULL==linebuff) {
fprintf(stderr, "%s: fatal memory error\n", __func__);
return -7;
}
maximum = (double)fimg_get_maxvalue(src);
fk = maximum / 65535.0;
if (verbosity) {
fprintf(stderr, "%s : maxv %f fk %f\n", __func__, maximum, fk);
}
tiff = TIFFOpen(fname, "w");
if (NULL==tiff) {
return -6;
}
TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, src->width);
TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, src->height);
TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 3); // RGB
TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 16); // 0->65535
TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
sprintf(ligne, "lib FloatImg v %d by tTh", FIMG_VERSION);
TIFFSetField(tiff, TIFFTAG_SOFTWARE, ligne);
foo = src->width * 3;
foo = TIFFDefaultStripSize(tiff, foo);
if (verbosity) fprintf(stderr, "default strip size %d\n", foo);
TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, foo);
for (y=0; y<src->height; y++) {
ptr = linebuff;
idx = y * src->width;
for (x=0; x<src->width; x++) {
*ptr++ = (unsigned short) (src->R[idx] / fk);
*ptr++ = (unsigned short) (src->G[idx] / fk);
*ptr++ = (unsigned short) (src->B[idx] / fk);
idx++;
}
TIFFWriteScanline(tiff, linebuff, y, 0);
idx += src->width;
}
TIFFClose(tiff);
free(linebuff);
return 0;
}
/* --------------------------------------------------------------------- */

180
src/funcs/geometry.c Normal file
View File

@@ -0,0 +1,180 @@
/*
* FLOATIMG
* distorsions géométriques - coredumping ?
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
/*
* really crude function, need more work...
*/
int fimg_halfsize_0(FloatImg *src, FloatImg *dst, int notused)
{
int wd, hd;
int foo, x, y;
float pixel[3];
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__,
src, dst, notused);
#endif
/* no magic check here ? */
if (dst->width || dst->height) {
fprintf(stderr, "*** %s: image at %p not empty\n", __func__, dst);
fimg_describe(dst, "destination halfsize 0");
return -2;
}
wd = src->width / 2; hd = src->height / 2;
foo = fimg_create(dst, wd, hd, FIMG_TYPE_RGB);
if (foo) {
fprintf(stderr, "%s: err create %d\n", __func__, foo);
return -3;
}
for (y=0; y<hd; y++) {
for (x=0; x<wd; x++) {
foo = fimg_get_rgb(src, x*2, y*2, pixel);
if (foo) {
fprintf(stderr, "%s: err get %d\n", __func__, foo);
abort();
}
foo = fimg_plot_rgb(dst, x, y, pixel[0], pixel[1], pixel[2]);
if (foo) {
fprintf(stderr, "%s: err plot %d\n", __func__, foo);
abort();
}
}
}
return 0;
}
/* --------------------------------------------------------------------- */
int fimg_halfsize_1(FloatImg *src, FloatImg *dst, int notused)
{
int wd, hd;
int foo, x, y, x2, y2;
float ac;
if (dst->width || dst->height) {
fprintf(stderr, "*** %s: image at %p not empty\n", __func__, dst);
fimg_describe(dst, "destination halfsize 1");
return -2;
}
wd = src->width / 2; hd = src->height / 2;
if ( (foo = fimg_create(dst, wd, hd, FIMG_TYPE_RGB)) ) {
fprintf(stderr, "%s: err create %d\n", __func__, foo);
return -3;
}
#define WS (src->width)
#define WD (dst->width)
for (y=0; y<hd; y++) {
y2 = y * 2;
for (x=0; x<wd; x++) {
x2 = x * 2;
ac = src->R[(y2*WS)+x2] + src->R[(y2*WS)+x2+1] +
src->R[((1+y2)*WS)+x2] + src->R[((1+y2)*WS)+x2+1];
dst->R[y*WD +x] = ac / 4.0;
ac = src->G[(y2*WS)+x2] + src->G[(y2*WS)+x2+1] +
src->G[((1+y2)*WS)+x2] + src->G[((1+y2)*WS)+x2+1];
dst->G[y*WD +x] = ac / 4.0;
ac = src->B[(y2*WS)+x2] + src->B[(y2*WS)+x2+1] +
src->B[((1+y2)*WS)+x2] + src->B[((1+y2)*WS)+x2+1];
dst->B[y*WD +x] = ac / 4.0;
}
}
#undef WS
#undef WD
return 0;
}
/* --------------------------------------------------------------------- */
int fimg_extractor(FloatImg *in, FloatImg *out, FimgArea51 *rect)
{
int foo;
int xs, ys, xd, yd;
int count;
float rgb[3];
if (verbosity > 1) {
fimg_describe(in, "extractor: source");
fimg_describe(out, "extractor: destination");
// print_rectangle(rect);
}
count = 0;
for (yd=0; yd<rect->h; yd++) {
ys = yd + rect->y;
if ((ys<0) || (ys>=in->height)) continue;
for (xd=0; xd<rect->w; xd++) {
xs = xd + rect->x;
if ((xs<0) || (xs>=in->width)) continue;
fimg_get_rgb(in, xs, ys, rgb);
fimg_put_rgb(out, xd, yd, rgb);
count++;
}
}
// fprintf(stderr, "%s: %d pix moved\n", __func__, count);
return 0;
}
/* --------------------------------------------------------------------- */
/* ho, btw, you can have a locck at 'incrustator.c' :) */
/* --------------------------------------------------------------------- */
int fimg_mirror(FloatImg *src, FloatImg *dst, int notused)
{
float *fptr;
int line, col, offl;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p 0x%04x )\n", __func__,
src, dst, notused);
#endif
if (fimg_images_not_compatible(src, dst)) {
fprintf(stderr, "bad karma in %s\n", __func__);
return -9;
}
if (NULL == (fptr=alloca(src->width*sizeof(float)))) {
fprintf(stderr, "%s: no mem available\n", __func__);
#if MUST_ABORT
abort();
#endif
return -11;
}
for (line=0; line<src->height; line++) {
offl = line * src->width;
for (col=0; col<src->width; col++)
fptr[(src->width-1) - col] = src->R[offl+col];
memcpy(dst->R+offl, fptr, src->width*sizeof(float));
for (col=0; col<src->width; col++)
fptr[(src->width-1) - col] = src->G[offl+col];
memcpy(dst->G+offl, fptr, src->width*sizeof(float));
for (col=0; col<src->width; col++)
fptr[(src->width-1) - col] = src->B[offl+col];
memcpy(dst->B+offl, fptr, src->width*sizeof(float));
}
return 0;
}
/* --------------------------------------------------------------------- */

95
src/funcs/histogram.c Normal file
View File

@@ -0,0 +1,95 @@
/*
* FLOATIMG
* calculer un histogramme et l'afficher
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
int fimg_calcul_histo(FloatImg *src, long *ghist, int sz)
{
float maxval;
int x, y, idx;
float rgb[3], moy;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__, src, ghist, sz);
#endif
if (FIMG_TYPE_RGB != src->type) {
fprintf(stderr, "%s: bad type %d of image\n", __func__, src->type);
return -97;
}
maxval = fimg_get_maxvalue(src);
fprintf(stderr, "maximum is %f\n", maxval);
for (y=0; y<src->height; y++) {
for(x=0; x<src->width; x++) {
fimg_get_rgb(src, x, y, rgb);
moy = (rgb[0]+rgb[1]+rgb[2]) / 3.0;
/* ok, here the had math part ... */
idx = (int)( (moy*sz) / maxval);
/* sanity check */
if (idx<0 || idx>=sz) {
fprintf(stderr, "idx = %d, error\n", idx);
abort();
}
ghist[idx]++;
}
}
return -66;
}
/* --------------------------------------------------------------------- */
int fimg_essai_histo(FloatImg *src, char *outpic, int nbslices)
{
long *histo;
int foo;
FILE *pipe;
fprintf(stderr, ">>> %s ( %p '%s' %d )\n", __func__, src, outpic, nbslices);
if (NULL==(histo=calloc(nbslices, sizeof(long)))) {
fprintf(stderr, "OUT OF MEMORY\n");
abort();
}
foo = fimg_calcul_histo(src, histo, nbslices);
// for (foo=0; foo<NSLICES; foo++) {
// printf("%7d %ld\n", foo, histo[foo]);
// }
pipe = popen("gnuplot", "w");
if (NULL==pipe) {
fprintf(stderr, "%s: error running gnuplot\n", __func__);
return -17;
}
fprintf(pipe, "set term png size 1024,512\n");
fprintf(pipe, "set grid\n");
fprintf(pipe, "set output \"%s\"\n", outpic);
fprintf(pipe, "plot '/dev/stdin' with lines\n");
for (foo=0; foo<nbslices; foo++) {
fprintf(pipe, "%d %ld\n", foo, histo[foo]);
}
pclose(pipe); // and not fclose (see man page)
free(histo);
return 0;
}
/* --------------------------------------------------------------------- */

161
src/funcs/hsv.c Normal file
View File

@@ -0,0 +1,161 @@
/*
* FloatImg library
* HUE - SATURATION - VALUE
+---------------------------------------------+
| ce code ne fonctionne vraiment PAS ! |
+---------------------------------------------+
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
/* helper functions */
static float maxi3f(float a, float b, float c)
{
return ((a > b)? (a > c ? a : c) : (b > c ? b : c));
}
static float mini3f(float a, float b, float c)
{
return ((a < b)? (a < c ? a : c) : (b < c ? b : c));
}
static int pseudoeq(float a, float b)
{
return (fabsf(a-b)<0.00000000000001); // UGLY HACK ???
}
/* --------------------------------------------------------------------- */
/*
* WARNING : ALL THIS CODE IS STRANGE
*
www.tutorialspoint.com/c-program-to-change-rgb-color-model-to-hsv-color-model
*/
int fimg_rgb2hsv(float rgb[3], float hsv[3], float scale)
{
// float h, s, v;
float cmin, cmax, diff;
// scale input value to [0..1]
rgb[0] /= scale; rgb[1] /= scale; rgb[2] /= scale;
hsv[0] = hsv[1] = hsv[2] = -12345.6789;
cmin = mini3f(rgb[0], rgb[1], rgb[2]);
cmax = maxi3f(rgb[0], rgb[1], rgb[2]);
diff = cmax - cmin;
if (pseudoeq(cmax, cmin)) hsv[0] = 0.0;
else if (pseudoeq(cmax, rgb[0]))
hsv[0] = fmod((60 * ((rgb[1] - rgb[2]) / diff) + 360), 360.0);
else if (pseudoeq(cmax, rgb[1]))
hsv[0] = fmod((60 * ((rgb[2] - rgb[0]) / diff) + 120), 360.0);
else if (pseudoeq(cmax, rgb[2]))
hsv[0] = fmod((60 * ((rgb[0] - rgb[1]) / diff) + 240), 360.0);
if (pseudoeq(cmax, 0.0)) hsv[1] = 0.0;
else hsv[1] = (diff / cmax) / 100.0;
hsv[2] = cmax * 100.0; /* WHAT THE FUCK ? */
#if DEBUG_LEVEL
fprintf(stderr, "cmin/cmax %f %f\n", cmin, cmax);
#endif
return 0;
}
/* --------------------------------------------------------------------- */
int fimg_hsv2rgb(float hsv[3], float rgb[3], float scale)
{
float hh, ff, p, q, t;
long i;
if(hsv[1] <= 0.0) { // < is bogus, just shuts up warnings
rgb[0] = rgb[1] = rgb[2] = hsv[2];
return 0;
}
hh = hsv[0];
if(hh >= 360.0) hh = 0.0;
hh /= 60.0;
i = (long)hh;
ff = hh - i;
p = hsv[2] * (1.0 - hsv[1]);
q = hsv[2] * (1.0 - (hsv[1] * ff));
t = hsv[2] * (1.0 - (hsv[1] * (1.0 - ff)));
switch(i) {
case 0:
rgb[0] = hsv[2]; rgb[1] = t; rgb[2] = p;
break;
case 1:
rgb[0] = q; rgb[1] = hsv[2]; rgb[2] = p;
break;
case 2:
rgb[0] = p; rgb[1] = hsv[2]; rgb[2] = t;
break;
case 3:
rgb[0] = p; rgb[1] = q; rgb[2] = hsv[2];
break;
case 4:
rgb[0] = t; rgb[1] = p; rgb[2] = hsv[2];
break;
case 5:
default:
rgb[0] = hsv[2]; rgb[1] = p; rgb[2] = q;
break;
}
return 0;
}
/* --------------------------------------------------------------------- */
/*
* expect garbage !
*/
int fimg_essai_hsv(char *fname)
{
float colors[3], values[3], newcols[3];
int foo, r, g, b;
#define INC 16
for (r=0; r<255; r+=INC) {
for (g=0; g<255; g+=INC) {
for (b=0; b<255; b+=INC) {
printf("%4d %4d %4d ", r, g, b);
colors[0] = (float)r;
colors[1] = (float)g;
colors[2] = (float)b;
foo = fimg_rgb2hsv(colors, values, 255.0);
if (foo) {
fprintf(stderr, "%s: err %d in rgv->hsv\n", __func__, foo);
exit(1);
}
printf(" %8.4f %8.4f %8.4f ",
values[0], values[1], values[2]);
foo = fimg_hsv2rgb(values, newcols, 255.0);
if (foo) {
fprintf(stderr, "%s: err %d in hsv->rgb\n", __func__, foo);
exit(1);
}
printf(" %8.4f %8.4f %8.4f\n",
newcols[0], newcols[1], newcols[2]);
}
}
}
return -1;
}
/* --------------------------------------------------------------------- */

93
src/funcs/incrustator.c Normal file
View File

@@ -0,0 +1,93 @@
/*
* incrustator VERY experimental
* KRKRK
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "../floatimg.h"
// XXX #include "incrustator.h"
extern int verbosity;
/* ---------------------------------------------------------------- */
static int check_boundaries(FloatImg *from, FloatImg *to, FimgArea51 *a51)
{
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %p )\n", __func__, from, to, a51);
fimg_printdims("from", from);
fimg_printdims("to ", to);
#endif
/* just a small molly-guard */
if ( (a51->w < 0) || (a51->h < 0) ) {
fprintf(stderr, "%s: fubar on %p\n", __func__, a51);
abort(); /* FY Bro ! */
}
return -1;
}
/* ---------------------------------------------------------------- */
static int move_pixels(FloatImg *from, FloatImg *to,
FimgArea51 *a51, int flags)
{
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %p 0x%04x )\n", __func__,
from, to, a51, flags);
#endif
return -1;
}
/* ---------------------------------------------------------------- */
int fimg_incrustator_0(FloatImg *psrc, FloatImg *pdst,
int xpos, int ypos, int flags)
{
int y, srcpos, dstpos, szl;
int foo;
FimgArea51 area;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %d %d 0x%04X\n", __func__, psrc, pdst,
xpos, ypos, flags);
#endif
if (verbosity > 1) {
fimg_describe(psrc, "source");
fimg_describe(pdst, "destination");
}
/* check boudaries */
area.x = xpos; area.y = ypos;
area.w = psrc->width; area.h = psrc->height;
foo = check_boundaries(psrc, pdst, &area);
if ( (xpos < 0) || (xpos > pdst->width - psrc->width) ||
(ypos < 0) || (ypos > pdst->height - psrc->height) ) {
fprintf(stderr, "%s: boudary error\n", __func__);
return -2;
}
/* move all the data by looping over lines */
srcpos = 0;
dstpos = (ypos * pdst->width) + xpos;
szl = psrc->width * sizeof(float);
for (y=0; y<psrc->height; y++) {
// fprintf(stderr, " %7d %7d %7d\n", y, srcpos, dstpos);
memcpy(pdst->R + dstpos, psrc->R + srcpos, szl);
memcpy(pdst->G + dstpos, psrc->G + srcpos, szl);
memcpy(pdst->B + dstpos, psrc->B + srcpos, szl);
srcpos += psrc->width;
dstpos += pdst->width;
}
return 0;
}
/* ---------------------------------------------------------------- */

104
src/funcs/misc-plots.c Normal file
View File

@@ -0,0 +1,104 @@
/*
* This is an eternal WIP, sorry...
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "../floatimg.h"
/* --------------------------------------------------------------------- */
int fimg_test_pattern(FloatImg *fimg, int type, double dval)
{
int nio;
int x, y, k;
float fr, fg, fb, val;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %d %g )\n", __func__, fimg, type, dval);
#endif
if (fimg->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s need an rgb pic\n", __func__);
return -6;
}
/* rampe de primaires dans le quart du haut */
val = (float)dval;
for (x=0; x<fimg->width; x++) {
nio = x / (fimg->width / 8);
switch(nio) {
case 0: fr = 0.0, fg = 0.0, fb = 0.0; break;
case 1: fr = val, fg = 0.0, fb = 0.0; break;
case 2: fr = 0.0, fg = val, fb = 0.0; break;
case 3: fr = val, fg = val, fb = 0.0; break;
case 4: fr = 0.0, fg = 0.0, fb = val; break;
case 5: fr = val, fg = 0.0, fb = val; break;
case 6: fr = 0.0, fg = val, fb = val; break;
case 7: fr = val, fg = val, fb = val; break;
default:
abort(); break;
}
for (y=0; y<fimg->height/4; y++)
fimg_plot_rgb(fimg, x, y, fr, fg, fb);
}
k = fimg->height / 4;
for (x=0; x<fimg->width; x++) {
val = ((double)x / (double)fimg->width) * dval;
for (y=0; y<20; y++) {
fimg_plot_rgb(fimg, x, k+y, val, val, val);
fimg_plot_rgb(fimg, x, k+y+20, dval-val, dval-val, dval-val);
}
// fprintf(stderr, " %6d %f\n", x, val);
}
return 0;
}
/* --------------------------------------------------------------------- */
int fimg_draw_something(FloatImg *fimg)
{
int x, y;
float fx, fy;
#define K (3.14159*13.456)
#define M 100.0
for (x=0; x<fimg->width; x++) {
fimg_plot_rgb(fimg, x, 0,
(float)x,
(float)x + 5.678,
(float)x * 1.33333);
}
for (y=1; y<fimg->height; y++) {
fy = (float)y / (float)fimg->height;
for (x=0; x<fimg->width; x++) {
fx = (float)x / (float)fimg->width;
fimg_plot_rgb(fimg, x, y,
M*(cos(fx*K)+1.2),
M*(sin(fy*K)+1.4),
M*(cos(fx*fy)+1.6));
}
}
return 0;
}
/* --------------------------------------------------------------------- */
int fimg_multirandom(FloatImg *fimg, long nbpass)
{
int foo, x, y;
#define RI ( (rand()/7) + (rand()/9) )
#define RD ( (drand48()/7) + (drand48()/7) )
for (foo=0; foo<nbpass; foo++)
{
x = RI % fimg->width;
y = RI % fimg->height;
fimg_add_rgb(fimg, x, y, RD, RD, RD);
}
return 0;
}
/* --------------------------------------------------------------------- */

43
src/funcs/plasmas.c Normal file
View File

@@ -0,0 +1,43 @@
/*
PLASMAS
Inspiration Reep : https://blog.314r.net/2021/01/10/plasma/
*/
#include <stdio.h>
#include <math.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
int fimg_prototype_plasma(FloatImg *img, double time, int type)
{
int x, y;
float rgb[3];
double dx, dy;
fprintf(stderr, ">>> %s ( %p %.3f %d )\n", __func__,
img, time, type);
for (y=0; y<img->height; y++) {
dy = ((double)y/(double)img->height) - 0.5000;
for (x=0; x<img->width; x++) {
dx = ((double)x/(double)img->width) - 0.5000;
rgb[0] = sin(dx*10 + time) + 1.0;
rgb[1] = sin(dx*12 + time) + 1.0;
rgb[2] = sin(dx*14 + time) + 1.0;
fimg_put_rgb(img, x, y, rgb);
}
}
return 0;
}
/* --------------------------------------------------------------------- */

128
src/funcs/qsortrgb.c Normal file
View File

@@ -0,0 +1,128 @@
/*
* qsort_rgb.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
/* nouveau 7 octobre 2020, juste avant sonoptic de la pluie craignos */
static int compare_a(const void *p1, const void *p2)
{
return ( *(float *)p1 < *(float *)p2 );
}
int fimg_qsort_rgb_a(FloatImg *psrc, FloatImg *pdst, int notused)
{
int foo, szimg;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__, psrc, pdst, notused);
#endif
if (FIMG_TYPE_RGB != psrc->type) {
fprintf(stderr, "%s: bad src type %d\n", __func__, psrc->type);
return -7;
}
if (fimg_images_not_compatible(psrc, pdst)) {
fprintf(stderr, "%s: bad dst type %d\n", __func__, pdst->type);
return -8;
}
if (psrc != pdst) { /* optimize or futurbug ? */
foo = fimg_copy_data(psrc, pdst);
if (foo) {
fprintf(stderr, "%s: err %d on copy data\n", __func__, foo);
return foo;
}
}
szimg = pdst->width * pdst->height;
// fprintf(stderr, "%s : %d pixels\n", __func__, szimg);
qsort(pdst->R, szimg, sizeof(float), compare_a);
qsort(pdst->G, szimg, sizeof(float), compare_a);
qsort(pdst->B, szimg, sizeof(float), compare_a);
return 0;
}
/* --------------------------------------------------------------------- */
typedef struct {
float sum;
float r, g, b;
} pix;
static int compare_b(const void *p1, const void *p2)
{
pix *s1, *s2;
s1 = (pix *)p1;
s2 = (pix *)p2;
return ( s1->sum < s2->sum );
}
int fimg_qsort_rgb_b(FloatImg *psrc, FloatImg *pdst, int notused)
{
int x, y, szimg;
pix *ppix, *ptr;
float rgb[3];
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__, psrc, pdst, notused);
#endif
if (FIMG_TYPE_RGB != psrc->type) {
fprintf(stderr, "%s: bad src type %d\n", __func__, psrc->type);
return -7;
}
if (fimg_images_not_compatible(psrc, pdst)) {
fprintf(stderr, "%s: bad dst type %d\n", __func__, pdst->type);
return -8;
}
szimg = pdst->width * pdst->height;
// fprintf(stderr, "%s : %d pixels\n", __func__, szimg);
ppix = calloc(szimg, sizeof(pix));
ptr = ppix; /* mobile pointer */
for (y=0; y<psrc->height; y++) {
for (x=0; x<psrc->width; x++) {
fimg_get_rgb(psrc, x, y, rgb);
ptr->sum = rgb[0] + rgb[1] + rgb[2];
ptr->r = rgb[0];
ptr->g = rgb[1];
ptr->b = rgb[2];
ptr++; /* next pixel */
}
}
qsort(ppix, szimg, sizeof(pix), compare_b);
ptr = ppix; /* mobile pointer */
for (y=0; y<psrc->height; y++) {
for (x=0; x<psrc->width; x++) {
rgb[0] = ptr->r;
rgb[1] = ptr->g;
rgb[2] = ptr->b;
fimg_put_rgb(pdst, x, y, rgb);
ptr++; /* next pixel */
}
}
free(ppix);
return 0;
}
/* --------------------------------------------------------------------- */

63
src/funcs/rampes.c Normal file
View File

@@ -0,0 +1,63 @@
/*
* FLOATIMG
* rampes diverses, trucs etranges
*/
#include <stdio.h>
#include "../floatimg.h"
/* --------------------------------------------------------------------- */
int fimg_hdeg_a(FloatImg *img, double dcoef)
{
int x, y;
float value;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %f )\n", __func__, img, dcoef);
#endif
if (FIMG_TYPE_RGB != img->type) {
fprintf(stderr, "%s bad type\n", __func__);
return -6;
}
for (x=0; x<img->width; x++)
{
value = (float)x / (float)img->width;
value *= dcoef;
for (y=0; y<img->height; y++) {
fimg_plot_rgb(img, x, y, value, value, value);
}
}
return 0;
}
/* --------------------------------------------------------------------- */
/*
* To have the black at the bottom, use a negative dcoef
*/
int fimg_vdeg_a(FloatImg *img, double dcoef)
{
int x, y;
float value;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %f )\n", __func__, img, dcoef);
#endif
if (FIMG_TYPE_RGB != img->type) {
fprintf(stderr, "%s bad type\n", __func__);
return -6;
}
for (y=0; y<img->height; y++)
{
value = (float)y / (float)img->height;
value *= dcoef;
for (x=0; x<img->width; x++) {
fimg_plot_rgb(img, x, y, value, value, value);
}
}
return 0;
}
/* --------------------------------------------------------------------- */

26
src/funcs/recurse.c Normal file
View File

@@ -0,0 +1,26 @@
/*
RECURSION 'QUADTREE' SUR LES IMAGES
-----------------------------------
*/
#include <stdio.h>
#include <math.h>
#include "../floatimg.h"
/* -------------------------------------------------------------------- */
/* may be we need some private variables ? */
/* -------------------------------------------------------------------- */
/* nouveau 29 avril 2021, pendant un autre masque-flamme coronavidique */
int fimg_recursion_proto(FloatImg *src, FloatImg *dst, int notused)
{
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__, src, dst, notused);
#endif
return -1;
}
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */

72
src/funcs/rotate.c Normal file
View File

@@ -0,0 +1,72 @@
/*
* FLOATIMG
* rotation matricielle des images
* #coronamaison Mon 23 Mar 2020 11:45:59 AM CET
*/
#include <stdio.h>
#include <string.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
int fimg_rotate_90(FloatImg *src, FloatImg *dst, int notused)
{
int foo;
int x, y, k;
float rgb[3];
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__,
src, dst, notused);
#endif
if (src->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s: src type %d not valid\n", __func__,
src->type);
return -6;
}
/* check if dst pic is not allocated */
if ( 0 == (dst->type | dst->width | dst->height) ) {
#if DEBUG_LEVEL
fprintf(stderr, "in %s, %p is empty\n", __func__, dst);
#endif
/* OK allocate a new fpic */
foo = fimg_create(dst, src->height, src->width, src->type);
if (foo) {
fprintf(stderr, "%s: err %d create new pic\n", __func__, foo);
return -887;
}
// if (verbosity>1) fimg_describe(dst, "new pic");
}
/* check if dst and src are conpatibles */
if ( (src->type != dst->type) ||
(src->width != dst->height) || (src->height != dst->width) ) {
fprintf(stderr, "%s: src & dst not compatibles\n", __func__);
return -888;
}
/*
* THIS IS A CRUDE IMPLEMENTATION
*/
for (y=0; y<src->height; y++) {
for (x=0; x<src->width; x++) {
fimg_get_rgb(src, x, y, rgb);
// XXX ??? j = (dst->height - x) - 1;
k = (dst->width - y) - 1;
#if DEBUG_LEVEL > 1
fprintf(stderr, "%6d %6d\n", k, j);
#endif
fimg_put_rgb(dst, k, x, rgb);
}
}
/* we don't have any cleanup to make */
return 0;
}
/* --------------------------------------------------------------------- */

109
src/funcs/saturation.c Normal file
View File

@@ -0,0 +1,109 @@
/*
* FloatImg library from tTh - really ugly code inside
*/
#include <stdio.h>
#include "../floatimg.h"
/* -------------------------------------------------------------- */
/* global vars exported from main
*/
extern int verbosity;
/* -------------------------------------------------------------- */
/*
* parameter mix is between 0.0 and 1.0 but other
* values give sometime good vibrations.
*/
int fimg_mix_rgb_gray(FloatImg *img, float mix)
{
int x, y, p;
float gr;
if (FIMG_TYPE_RGB != img->type) {
fprintf(stderr, "%s bad type\n", __func__);
return -6;
}
for (y=0; y<img->height; y++) {
p = y * img->width; /* first pixel of the row */
for (x=0; x<img->width; x++) {
gr = (img->R[p] + img->G[p] + img->R[p]) / 3.0;
img->R[p] = ((gr * mix) + (img->R[p] * (1.0-mix))) / 2.0;
img->G[p] = ((gr * mix) + (img->G[p] * (1.0-mix))) / 2.0;
img->B[p] = ((gr * mix) + (img->B[p] * (1.0-mix))) / 2.0;
p++; /* next pixel in the row */
}
}
return 0;
}
/* -------------------------------------------------------------- */
/*
* The third parameter was a six value array with min and max
* values maybe computed by the 'fimg_get_minmax_rgb' function.
*/
int fimg_shift_to_zero(FloatImg *s, FloatImg *d, float coefs[6])
{
int sz, idx;
if (FIMG_TYPE_RGB != s->type) {
fprintf(stderr, "%s bad type\n", __func__);
return -6;
}
sz = s->width * s->height;
for (idx=0; idx<sz; idx++) {
d->R[idx] = s->R[idx] - coefs[0];
d->G[idx] = s->G[idx] - coefs[2];
d->B[idx] = s->B[idx] - coefs[4];
}
return 0;
}
/* -------------------------------------------------------------- */
/*
* I think that this function is fully buggy, and need
* more explanations.
*/
int fimg_auto_shift_to_zero(FloatImg *src, FloatImg *dst)
{
float coefs[6];
int foo;
float minima = 1e7; /* magic value ? */
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p )\n", __func__, src, dst);
#endif
if (FIMG_TYPE_RGB != src->type) {
fprintf(stderr, "%s: bad image type %d\n", __func__, src->type);
return -6;
}
foo = fimg_get_minmax_rgb(src, coefs);
if (foo) {
fprintf(stderr, "%s: err %d get minmax\n", __func__, foo);
return foo;
}
/* crude hack for now */
if (coefs[0] < minima) minima = coefs[0];
if (coefs[2] < minima) minima = coefs[2];
if (coefs[4] < minima) minima = coefs[4];
coefs[0] = coefs[2] = coefs[4] = minima;
foo = fimg_shift_to_zero(src, dst, coefs);
if (foo) {
fprintf(stderr, "%s WTF?\n", __func__);
return foo;
}
return 0;
}
/* -------------------------------------------------------------- */

89
src/funcs/sfx0.c Normal file
View File

@@ -0,0 +1,89 @@
/*
* FLOATIMG
* effets spéciaux àlc sur les couleurs
*/
#include <stdio.h>
#include <string.h>
#include "../floatimg.h"
/* --------------------------------------------------------------------- */
/*
* OMG ! a Color Graphic Adaptor emulator :)
*/
int fimg_killcolors_a(FloatImg *fimg, float fval)
{
int nbpix, foo;
if (FIMG_TYPE_RGB != fimg->type) {
fprintf(stderr, "%s: bad src type %d on %p\n", __func__,
fimg->type, fimg);
return -8;
}
nbpix = fimg->width * fimg->height;
for (foo=0; foo<nbpix; foo++) {
if (fimg->R[foo] > fimg->G[foo])
fimg->B[foo] = fimg->R[foo];
else
fimg->B[foo] = fimg->G[foo];
}
return 0;
}
/* --------------------------------------------------------------------- */
/*
* parameter fval is not used, why ?
*/
int fimg_killcolors_b(FloatImg *fimg, float fval)
{
int nbpix, foo;
if (FIMG_TYPE_RGB != fimg->type) {
fprintf(stderr, "%s: bad src type %d on %p\n", __func__,
fimg->type, fimg);
return -8;
}
nbpix = fimg->width * fimg->height;
for (foo=0; foo<nbpix; foo++) {
if (fimg->R[foo] > fimg->B[foo])
fimg->G[foo] = fimg->R[foo];
else
fimg->G[foo] = fimg->B[foo];
}
return 0;
}
/* --------------------------------------------------------------------- */
int fimg_colors_mixer_a(FloatImg *fimg, float fval)
{
int nbpix, foo;
float R, G, B;
if (FIMG_TYPE_RGB != fimg->type) {
fprintf(stderr, "%s: bad src type %d on %p\n", __func__,
fimg->type, fimg);
#if MUST_ABORT
abort();
#endif
return -8;
}
nbpix = fimg->width * fimg->height;
for (foo=0; foo<nbpix; foo++) {
R = (fimg->G[foo] + fimg->B[foo]) / fval;
G = (fimg->R[foo] + fimg->B[foo]) / fval;
B = (fimg->R[foo] + fimg->G[foo]) / fval;
fimg->R[foo] = R;
fimg->G[foo] = G;
fimg->B[foo] = B;
}
return 0;
}
/* --------------------------------------------------------------------- */

106
src/funcs/sfx1.c Normal file
View File

@@ -0,0 +1,106 @@
/*
* FLOATIMG - a kluge from tTh
* effets spéciaux bizarres sur les couleurs.
* nouveau pour un truc chelou avec Maëva
*/
#include <stdio.h>
#include <string.h>
#include "../floatimg.h"
/* WARNING
some crapy code cuted & pasted here */
/* --------------------------------------------------------------------- */
static void highlight_red(FloatImg *src, FloatImg *dst, float fval)
{
int sz, idx;
sz = src->width * src->height;
for (idx=0; idx<sz; idx++) {
dst->G[idx] = src->G[idx];
dst->B[idx] = src->B[idx];
if ( (src->G[idx] < src->R[idx]) &&
(src->B[idx] < src->R[idx]) ) {
dst->R[idx] = src->R[idx] * fval;
}
else {
dst->R[idx] = src->R[idx];
}
}
}
/* --------------------------------------------------------------------- */
static void highlight_green(FloatImg *src, FloatImg *dst, float fval)
{
int sz, idx;
sz = src->width * src->height;
for (idx=0; idx<sz; idx++) {
dst->R[idx] = src->R[idx];
dst->B[idx] = src->B[idx];
if ( (src->R[idx] < src->R[idx]) &&
(src->B[idx] < src->R[idx]) ) {
dst->G[idx] = src->G[idx] * fval;
}
else {
dst->G[idx] = src->G[idx];
}
}
}
/* --------------------------------------------------------------------- */
static void highlight_blue(FloatImg *src, FloatImg *dst, float fval)
{
int sz, idx;
sz = src->width * src->height;
for (idx=0; idx<sz; idx++) {
dst->G[idx] = src->G[idx];
dst->R[idx] = src->R[idx];
if ( (src->G[idx] < src->B[idx]) &&
(src->R[idx] < src->B[idx]) ) {
dst->B[idx] = src->B[idx] * fval;
}
else {
dst->B[idx] = src->B[idx];
}
}
}
/* --------------------------------------------------------------------- */
int fimg_highlight_color(FloatImg *src, FloatImg *dst, char color, float fval)
{
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p [%c] %f )\n", __func__,
src, dst, color, fval);
#endif
if (FIMG_TYPE_RGB != src->type) {
fprintf(stderr, "%s: bad src type %d on %p\n", __func__,
src->type, src);
return -8;
}
if (fimg_images_not_compatible(src, dst)) {
fprintf(stderr, "oh fuck in %s\n", __func__);
return -9;
}
switch (color) {
case 'r': case 'R':
highlight_red(src, dst, fval); break;
case 'g': case 'G':
highlight_green(src, dst, fval); break;
case 'b': case 'B':
highlight_blue(src, dst, fval); break;
default:
fprintf(stderr, "%s: '%c' is invalid\n", __func__, color);
return -11;
break; /* nottreached */
}
return 0;
}
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */

94
src/funcs/sfx2.c Normal file
View File

@@ -0,0 +1,94 @@
/*
* FLOATIMG - a kluge from tTh
*/
#include <stdio.h>
#include <string.h>
#include "../floatimg.h"
extern int verbosity;
/*
* a place for moving here Fonderie effects
*/
/* -------------------------------------------------------------- */
int fimg_binarize(FloatImg *pimg, int notused)
{
float mm[6], mR, mG, mB;
int foo, size;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %d )\n", __func__, pimg, notused);
#endif
foo = fimg_get_minmax_rgb(pimg, mm);
mR = (mm[1] - mm[0]) / 2.0;
mG = (mm[3] - mm[2]) / 2.0;
mB = (mm[5] - mm[4]) / 2.0;
if (verbosity > 1)
fprintf(stderr, "%s: %f %f %f\n", __func__, mR, mG, mB);
size = pimg->width * pimg->height;
for (foo=0; foo<size; foo++) {
if (pimg->R[foo] < mR) pimg->R[foo] = mm[0];
else pimg->R[foo] = mm[1];
if (pimg->G[foo] < mG) pimg->G[foo] = mm[2];
else pimg->G[foo] = mm[3];
if (pimg->B[foo] < mB) pimg->B[foo] = mm[4];
else pimg->B[foo] = mm[5];
}
return 0;
}
/* -------------------------------------------------------------- */
int fimg_trinarize(FloatImg *pimg, int notused)
{
float mm[6], mRa, mGa, mBa, mRb, mGb, mBb;
float *fptr;
int foo, size;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %d )\n", __func__, pimg, notused);
#endif
foo = fimg_get_minmax_rgb(pimg, mm);
mRa = (mm[1] - mm[0]) * 0.33333;
mGa = (mm[3] - mm[2]) * 0.33333;
mBa = (mm[5] - mm[4]) * 0.33333;
mRb = (mm[1] - mm[0]) * 0.66666;
mGb = (mm[3] - mm[2]) * 0.66666;
mBb = (mm[5] - mm[4]) * 0.66666;
size = pimg->width * pimg->height;
for (foo=0; foo<size; foo++) {
fptr = pimg->R;
if (fptr[foo] < mRa || fptr[foo] > mRb)
fptr[foo] = mm[0];
else
fptr[foo] = mm[1];
fptr = pimg->G;
if (fptr[foo] < mGa || fptr[foo] > mGb)
fptr[foo] = mm[2];
else
fptr[foo] = mm[3];
fptr = pimg->B;
if (fptr[foo] < mBa || fptr[foo] > mBb)
fptr[foo] = mm[4];
else
fptr[foo] = mm[5];
}
return 0;
}
/* -------------------------------------------------------------- */

231
src/funcs/t.c Normal file
View File

@@ -0,0 +1,231 @@
/*
* tests des fonctions diverses - main file
see also: tests.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pam.h>
#undef DEBUG_LEVEL
#define DEBUG_LEVEL 1
#include "../floatimg.h"
#include "tests.h"
int verbosity;
float global_fvalue;
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
enum nCmd { Equalize=1, Rotate, Sfx0, F3x3, MIRE, Wfits, Wpng, Wtiff,
Histo, Hsv, Classif, Ctr2x2, Qsortrgb,
Displace, ReadPNG, Plasmas, Hilight, OpenEXR,
Geometrie, FileType, Mirror };
typedef struct {
char *name;
int Cmd;
} Command;
Command commands[] = {
{ "equalize", Equalize },
{ "rotate", Rotate },
{ "sfx0", Sfx0 },
{ "f3x3", F3x3 },
{ "mire", MIRE },
{ "wfits", Wfits },
{ "wpng", Wpng },
{ "wtiff", Wtiff },
{ "histo", Histo },
{ "hsv", Hsv },
{ "classif", Classif },
{ "ctr2x2", Ctr2x2 },
{ "qsortrgb", Qsortrgb },
{ "displace", Displace },
{ "readpng", ReadPNG },
{ "plasma", Plasmas },
{ "hilight", Hilight },
{ "openexr", OpenEXR },
{ "geometrie", Geometrie, },
{ "filetype", FileType },
{ "mirror", Mirror },
{ NULL, 0 }
} ;
/* --------------------------------------------------------------------- */
int lookup_cmd(char *cmdtxt)
{
Command *pcmd;
pcmd = commands;
while (pcmd->name) {
if (!strcmp(pcmd->name, cmdtxt)) return pcmd->Cmd;
pcmd++;
}
return -1;
}
/* --------------------------------------------------------------------- */
void list_tests(void)
{
Command *pcmd = commands;
while (pcmd->name) {
printf("%s\n", pcmd->name);
pcmd++;
}
exit(0);
}
/* --------------------------------------------------------------------- */
void help(int k)
{
Command *pcmd;
fprintf(stderr, "usage:\n\t./t [options] command [filename]\n");
fprintf(stderr, "options:\n");
fprintf(stderr, "\t-k 1.414\tset float value\n");
fprintf(stderr, "\t-l\t\tlist tests\n");
fprintf(stderr, "\t-o \t\toutfile\n");
fprintf(stderr, "commands:\n");
pcmd = commands;
while (pcmd->name) {
fprintf(stderr, "\t%-15s %d\n", pcmd->name, pcmd->Cmd);
pcmd++;
}
fprintf(stderr, "\ncompiled on "__DATE__" at "__TIME__"\n");
exit(0);
}
/* --------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo, opt;
char *filename, *command, *outfile;
fprintf(stderr, "++++++++ test des fonctions pid=%d\n", getpid());
fprintf(stderr, "++++++++ compiled "__DATE__" at " __TIME__ "\n");
global_fvalue = 1.0;
outfile = "out.pnm";
command = "none";
filename = "in.fimg";
while ((opt = getopt(argc, argv, "hk:lo:p:v")) != -1) {
// fprintf(stderr, "opt = %c\n", opt);
switch(opt) {
case 'h': help(0); break;
case 'k': global_fvalue = atof(optarg); break;
case 'l': list_tests(); break;
case 'o': outfile = optarg; break;
case 'v': verbosity++; break;
}
}
// fprintf(stderr, "argc %d optind %d\n", argc, optind);
switch (argc-optind) {
case 1: /* only command */
command = argv[optind];
break;
case 2:
command = argv[optind];
filename = argv[optind+1];
break;
default:
fprintf(stderr, "%s: bad command line ?\n", argv[0]);
help(1);
break;
}
if (verbosity) {
fprintf(stderr, "++++++++ %s : running command '%s' on '%s'\n",
argv[0], command, filename);
fprintf(stderr, "global fvalue : %f\n", global_fvalue);
}
opt = lookup_cmd(command);
// fprintf(stderr, "lookup '%s' --> %d\n", command, opt);
switch(opt) {
case Equalize:
foo = essai_equalize(filename); break;
case Sfx0:
foo = essai_sfx0(filename); break;
case F3x3:
foo = essai_filtrage_3x3(filename); break;
case MIRE:
foo = essai_mire(filename, 0);
break;
case Wfits:
foo = essai_ecriture_fits("out.fits");
break;
case Wpng:
foo = essai_ecriture_png("out.png");
break;
case Wtiff:
foo = essai_ecriture_tiff("out.tiff");
break;
case Histo:
foo = essai_histogramme(filename, 98765);
break;
case Hsv:
// not ready for primtime
// foo = fimg_essai_hsv(filename);
foo = 0;
break;
case Classif:
foo = essai_classif(filename, outfile, global_fvalue);
break;
case Ctr2x2:
foo = essai_contour_2x2(filename, outfile);
break;
case Qsortrgb:
foo = essai_qsort_rgb(filename, outfile);
break;
case Displace:
foo = essai_displacement(filename, outfile);
break;
case ReadPNG:
// not ready for primetime
// foo = essai_lecture_png("in.png", outfile, 0);
foo = 0;
break;
case Plasmas:
foo = essai_plasma(filename, outfile, 1, global_fvalue);
fprintf(stderr, "we are all plasmafields\n");
break;
case Rotate:
fprintf(stderr, "rotate not implemented (%d)\n", rand());
foo = 0;
break;
case Hilight:
foo = essai_highlights(filename, outfile, 0, global_fvalue);
break;
case OpenEXR:
foo = essai_openexr(filename, outfile, 0x55);
break;
case Geometrie:
foo = essai_geometrie(filename, 0);
break;
case FileType:
foo = essai_detect_type();
break;
case Mirror:
foo = essai_miroir(filename, outfile, 0);
break;
default:
fprintf(stderr, "'%s' is a bad command\n", command);
exit(1);
}
if (foo) {
fprintf(stderr, "******* Essai --> %d\n", foo);
}
fprintf(stderr, "++++++++++++ end of '%s' pid %d\n", command, getpid());
return 0;
}
/* --------------------------------------------------------------------- */

830
src/funcs/tests.c Normal file
View File

@@ -0,0 +1,830 @@
/*
* tests des fonctions diverses - subroutines
see also: t.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pam.h>
#undef DEBUG_LEVEL
#define DEBUG_LEVEL 1
#include "../floatimg.h"
#include "tests.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
int fimg_recursion_proto(FloatImg *src, FloatImg *dst, int notused);
int essai_recursion(char *inf, char *outf, int flags)
{
int foo;
FloatImg src, dst;
fprintf(stderr, ">>> %s ( '%s' '%s' 0x%04X )\n", __func__,
inf, outf, flags);
foo = fimg_create_from_dump(inf, &src);
if (0 != foo) {
fprintf(stderr, "%s: err %d loading image '%s'\n", __func__,
foo, inf);
return foo;
}
fimg_clone(&src, &dst, 0);
foo = fimg_recursion_proto(&src, &dst, flags);
if (foo) {
fprintf(stderr, "%s: fail %d\n", __func__, foo);
return foo;
}
foo = fimg_export_picture(&dst, outf, 0);
if (foo) {
fprintf(stderr, "%s : err %d saving result\n", __func__, foo);
return foo;
}
return -1;
}
/* --------------------------------------------------------------------- */
int essai_miroir(char *inf, char *outf, int flags)
{
int foo;
FloatImg src, dst;
fprintf(stderr, ">>> %s ( '%s' '%s' 0x%X )\n", __func__,
inf, outf, flags);
foo = fimg_create_from_dump(inf, &src);
if (0 != foo) {
fprintf(stderr, "%s: err %d loading image '%s'\n", __func__,
foo, inf);
return foo;
}
fimg_clone(&src, &dst, 0);
/* run the crappy code */
foo = fimg_mirror(&src, &dst, 0);
if (foo) {
fprintf(stderr, "err %d in fimg_mirrot\n", foo);
return -6;
}
foo = fimg_export_picture(&dst, outf, 0);
if (foo) {
fprintf(stderr, "%s : err %d saving result\n", __func__, foo);
return foo;
}
return 0;
}
/* --------------------------------------------------------------------- */
/* nouveau 21 mars 2021 - rue d'Aragon */
int essai_openexr(char *inf, char *outf, int flags)
{
FloatImg src;
int foo;
fprintf(stderr, ">>> %s ( '%s' '%s' 0x%X )\n", __func__,
inf, outf, flags);
foo = fimg_create_from_dump(inf, &src);
if (0 != foo) {
fprintf(stderr, "%s: err %d loading image '%s'\n", __func__,
foo, inf);
return foo;
}
// fprintf(stderr, "image loaded at %p\n", &src);
fimg_describe(&src, "for save EXR test");
foo = fimg_save_as_exr(&src, outf, flags);
fimg_destroy(&src);
return -2;
}
/* --------------------------------------------------------------------- */
/* nouveau 20 mars 2021 - rue d'Aragon */
int essai_highlights(char *inf, char *outf, int ikoef, float fkoef)
{
FloatImg src, dst;
int foo;
fprintf(stderr, ">>> %s ( '%s' '%s' %d %g )\n", __func__,
inf, outf, ikoef, fkoef);
foo = fimg_create_from_dump(inf, &src);
if (0 != foo) {
fprintf(stderr, "%s: err %d loading image '%s'\n", __func__,
foo, inf);
return foo;
}
fimg_clone(&src, &dst, 0);
foo = fimg_highlight_color(&src, &dst, 'R', fkoef);
if (foo) {
fprintf(stderr, "%s: err %d ?\n", __func__, foo);
return foo;
}
foo = fimg_export_picture(&dst, outf, 0);
if (foo) {
fprintf(stderr, "%s : err %d saving result\n", __func__, foo);
return foo;
}
return 0;
}
/* --------------------------------------------------------------------- */
int essai_plasma(char *infile, char *outfile, int ikoef, float fkoef)
{
FloatImg src, dst;
int foo;
fprintf(stderr, ">>> %s ( '%s' '%s' %d %g )\n", __func__,
infile, outfile, ikoef, fkoef);
/* if infile is loadable, use it for background */
foo = fimg_create_from_dump(infile, &src);
if (0 == foo) {
fprintf(stderr, "%s: image '%s' loaded\n", __func__, infile);
}
else {
/* make a fancy synthetic picture */
foo = fimg_create(&src, 800, 600, FIMG_TYPE_RGB);
}
fimg_printhead(&src);
fimg_clone(&src, &dst, 1);
foo = fimg_prototype_plasma(&dst, fkoef, 0);
if (foo) {
fprintf(stderr, "%s: err %d on plasma proto\n", __func__, foo);
return -88;
}
fimg_mul_3(&src, &dst, &dst);
foo = fimg_export_picture(&dst, outfile, 0);
if (foo) {
fprintf(stderr, "%s : err %d saving result\n", __func__, foo);
return foo;
}
return -1;
}
/* --------------------------------------------------------------------- */
/* nouveau 24 octobre 2020, pendant le masque-flamme coronavidique */
int essai_displacement(char *infile, char *outfile)
{
int foo;
FloatImg src, dst;
fprintf(stderr, "%s : loading %s\n", __func__, infile);
foo = fimg_create_from_dump(infile, &src);
if (foo) {
fprintf(stderr, "%s: error loading '%s'\n", __func__, infile);
return foo;
}
fimg_clone(&src, &dst, 1);
foo = fimg_displacement_0(&src, &dst, 0);
if (foo) {
fprintf(stderr, "%s: err %d in disp map 0\n", __func__, foo);
return foo;
}
foo = fimg_export_picture(&dst, outfile, 0);
if (foo) {
fprintf(stderr, "%s : err %d saving result\n", __func__, foo);
return foo;
}
return 0;
}
/* --------------------------------------------------------------------- */
/*
* nouveau 7 octobre 2020 pendant sonoptic
*
* inspiration: Olivier Baudu
*/
int essai_qsort_rgb(char *infile, char *outfile)
{
FloatImg src, dst;
int foo;
if (NULL != infile) {
fprintf(stderr, "%s : loading %s\n", __func__, infile);
foo = fimg_create_from_dump(infile, &src);
if (foo) {
fprintf(stderr, "%s: error loading '%s'\n", __func__, infile);
return foo;
}
}
else {
fprintf(stderr, "%s : NOT INPUT FILE, FUBAR\n", __func__);
abort();
}
fimg_clone(&src, &dst, 1);
foo = fimg_qsort_rgb_b(&src, &dst, 0);
if (foo) {
fprintf(stderr, "%s: err %d in qsort_rgb\n", __func__, foo);
return foo;
}
foo = fimg_export_picture(&dst, outfile, 0);
if (foo) {
fprintf(stderr, "%s : err %d saving result\n", __func__, foo);
return foo;
}
fimg_destroy(&src); fimg_destroy(&dst);
return 0;
}
/* --------------------------------------------------------------------- */
/*
* nouveau 5 octobre 2020 pendant sonoptic
*/
int essai_contour_2x2(char *infile, char *outfile)
{
FloatImg src, dst;
int foo;
if (NULL != infile) {
fprintf(stderr, "%s : loading %s\n", __func__, infile);
foo = fimg_create_from_dump(infile, &src);
if (foo) {
fprintf(stderr, "%s: error loading '%s'\n", __func__, infile);
return foo;
}
}
else {
fprintf(stderr, "%s : NOT INPUT FILE, FUBAR\n", __func__);
abort();
}
fimg_clone(&src, &dst, 1);
foo = fimg_contour_2x2(&src, &dst, 0);
if (foo) {
fprintf(stderr, "%s: err %d in contour_2x2\n", __func__, foo);
return foo;
}
foo = fimg_export_picture(&dst, outfile, 0);
if (foo) {
fprintf(stderr, "%s : err %d saving result\n", __func__, foo);
return foo;
}
fimg_destroy(&src); fimg_destroy(&dst);
return 0;
}
/* --------------------------------------------------------------------- */
/*
* nouveau 5 octobre 2020 pendant sonoptic
*/
int essai_classif(char *infile, char *outfile, float fvalue)
{
FloatImg src, dst;
int foo;
if (NULL != infile) {
fprintf(stderr, "%s : loading %s\n", __func__, infile);
foo = fimg_create_from_dump(infile, &src);
if (foo) {
fprintf(stderr, "%s: error loading '%s'\n", __func__, infile);
return foo;
}
}
else {
fprintf(stderr, "%s : NOT INPUT FILE, FUBAR\n", __func__);
abort();
}
fimg_clone(&src, &dst, 1);
fprintf(stderr, "%s : fvalue is %f\n", __func__, fvalue);
foo = fimg_classif_trial(&src, &dst, fvalue, 0);
if (foo) {
fprintf(stderr, "%s: err %d in classif_trial\n", __func__, foo);
return foo;
}
foo = fimg_export_picture(&dst, outfile, 0);
if (foo) {
fprintf(stderr, "%s : err %d saving result\n", __func__, foo);
return foo;
}
fimg_destroy(&src); fimg_destroy(&dst);
return 0;
}
/* --------------------------------------------------------------------- */
/* nouveau 19 aout 2020, le matin avant la canicule */
int essai_ecriture_tiff(char *outname)
{
int foo;
FloatImg picz;
fimg_create(&picz, 800, 600, FIMG_TYPE_RGB);
fimg_test_pattern(&picz, 0, 22222);
foo = fimg_write_as_tiff(&picz, outname, 0);
if (foo) {
fprintf(stderr, "%s got a %d\n", __func__, foo);
return foo;
}
return 0;
}
/* --------------------------------------------------------------------- */
/* essai de fichiers FITS (astronomie) */
int essai_ecriture_fits(char *outname)
{
FloatImg src;
int foo;
fprintf(stderr, "%s is creating the picz\n", __func__);
fimg_create(&src, 512, 512, FIMG_TYPE_RGB);
fimg_test_pattern(&src, 0, 255.0);
foo = fimg_save_R_as_fits(&src, outname, 0);
fprintf(stderr, "saving '%s' to fits --> %d\n", outname, foo);
return -1;
}
/* --------------------------------------------------------------------- */
/*
* egalisation dynamique approximative
* #coronamaison Thu 09 Apr 2020 03:37:10 PM CEST
*/
int essai_equalize(char *infile)
{
FloatImg src;
int foo;
if (NULL != infile) {
fprintf(stderr, "%s: loading %s\n", __func__, infile);
foo = fimg_create_from_dump(infile, &src);
if (foo) {
fprintf(stderr, "%s: err load '%s'\n", __func__, infile);
return foo;
}
}
else {
fprintf(stderr, "%s : NOT INPUT FILE, FUBAR\n", __func__);
abort();
}
/*
* XXX need more work on this function !
*/
foo = fimg_equalize_compute(&src, NULL, 666.666);
fprintf(stderr, "equalize compute --> %d\n", foo);
fimg_destroy(&src);
return 0;
}
/* --------------------------------------------------------------------- */
int essai_rotate(char *infile)
{
FloatImg src, dst;
int foo;
if (NULL != infile) {
fprintf(stderr, "%s: loading %s\n", __func__, infile);
foo = fimg_create_from_dump(infile, &src);
if (foo) {
fprintf(stderr, "%s: err load '%s'\n", __func__, infile);
return foo;
}
}
else {
fprintf(stderr, "%s : NOT INPUT FILE, FUBAR\n", __func__);
abort();
}
fimg_save_as_png(&src, "test.png", 0);
foo = fimg_rotate_90(&src, &dst, 0);
fprintf(stderr, "rotate 90 -> %d\n", foo);
foo = fimg_export_picture(&dst, "rotated90.png", 0);
foo = fimg_export_picture(&dst, "rotated90.pnm", 0);
fimg_destroy(&src);
return -1;
}
/* --------------------------------------------------------------------- */
int essai_filtrage_3x3(char *infile)
{
FloatImg src, dst;
int foo; /// , idx;
// char buffer[100];
FimgFilter3x3 filter_a = {
{ 1.0, 1.0, 1.0,
1.0, -3.0, 1.0,
1.0, 1.0, 1.0 },
9.0, 0.0
};
FimgFilter3x3 filter_b = {
{ -2.0, -1.0, 0.0,
-1.0, 3.0, 1.0,
0.0, 1.0, 2.0 },
8.0, 0.0
};
FimgFilter3x3 filter_c = {
{
2.0, 1.0, 0.0,
1.0, 0.0, -1.0,
0.0, -1.0, -2.0,
},
1.0, 8.0
};
if (NULL != infile) {
fprintf(stderr, "%s: loading %s\n", __func__, infile);
foo = fimg_create_from_dump(infile, &src);
if (foo) {
fprintf(stderr, "%s: err load '%s'\n", __func__, infile);
return foo;
}
}
else {
fprintf(stderr, "%s is creating the picz\n", __func__);
fimg_create(&src, 640, 480, FIMG_TYPE_RGB);
fimg_test_pattern(&src, 0, 255.0);
}
// fimg_save_as_png(&src, "test.png", 0);
foo = fimg_count_negativ(&src);
fprintf(stderr, "%s: source have %d negs\n", __func__, foo);
foo = fimg_clone(&src, &dst, 0);
if (foo) {
fprintf(stderr, "%s: err clone %p\n", __func__, &src);
return -44;
}
fimg_filter_3x3(&src, &dst, &filter_a);
foo = fimg_clamp_negativ(&dst);
if (foo) {
fprintf(stderr, "A clamped %d negative pixels\n", foo);
}
foo = fimg_save_as_png(&dst, "f3x3a.png", 0);
// foo = fimg_save_as_pnm(&dst, "f3x3a.pnm", 0);
fimg_filter_3x3(&src, &dst, &filter_b);
foo = fimg_clamp_negativ(&dst);
if (foo) {
fprintf(stderr, "B clamped %d negative pixels\n", foo);
}
foo = fimg_save_as_png(&dst, "f3x3b.png", 0);
// foo = fimg_save_as_pnm(&dst, "f3x3a.pnm", 0);
fimg_filter_3x3(&src, &dst, &filter_c);
foo = fimg_clamp_negativ(&dst);
if (foo) {
fprintf(stderr, "C clamped %d negative pixels\n", foo);
}
foo = fimg_save_as_png(&dst, "f3x3b.png", 0);
// foo = fimg_save_as_pnm(&dst, "f3x3a.pnm", 0);
fimg_destroy(&src); fimg_destroy(&dst);
return 0;
}
/* --------------------------------------------------------------------- */
int essai_filtrage_2x2(char *infile)
{
FloatImg fimg;
int foo, idx;
char buffer[100];
if (NULL != infile) {
fprintf(stderr, "%s: loading %s\n", __func__, infile);
foo = fimg_create_from_dump(infile, &fimg);
if (foo) {
fprintf(stderr, "%s: err load '%s'\n", __func__, infile);
return foo;
}
}
else {
fprintf(stderr, "%s is creating the picz\n", __func__);
fimg_create(&fimg, 512, 512, FIMG_TYPE_RGB);
fimg_draw_something(&fimg);
}
foo = fimg_save_as_pnm(&fimg, "source.pnm", 0);
/*
* running multiple filters so you can
* watch the up-left shift :)
*/
for (idx=0; idx<5; idx++) {
foo = fimg_lissage_2x2(&fimg);
sprintf(buffer, "filter%03d.png", idx);
foo = fimg_save_as_png(&fimg, buffer, 0);
if (verbosity) {
fprintf(stderr, "%s %d\n", buffer, foo);
}
}
fimg_destroy(&fimg);
return 0;
}
/* --------------------------------------------------------------------- */
int essai_geometrie(char *infile, int notused)
{
FloatImg fimg, result;
int foo;
if (NULL != infile) {
fprintf(stderr, "loading %s\n", infile);
foo = fimg_create_from_dump(infile, &fimg);
if (foo) {
fprintf(stderr, "%s: err load '%s'\n", __func__, infile);
return foo;
}
}
else {
fimg_create(&fimg, 512, 512, FIMG_TYPE_RGB);
fimg_draw_something(&fimg);
}
// foo = fimg_save_as_pnm(&fimg, "source.pnm", 0);
memset(&result, 0, sizeof(FloatImg));
foo = fimg_halfsize_0(&fimg, &result, 0);
fprintf(stderr, "retour halfsize 0 -> %d\n", foo);
if (foo) {
return -2;
}
if (verbosity) fimg_describe(&result, "result after halfsize 0");
foo = fimg_save_as_pnm(&result, "halfsize0.pnm", 0);
fimg_destroy(&result);
foo = fimg_halfsize_1(&fimg, &result, 0);
fprintf(stderr, "retour halfsize 1 -> %d\n", foo);
if (foo) {
return -2;
}
if (verbosity) fimg_describe(&result, "result after halfsize 1");
foo = fimg_save_as_pnm(&result, "halfsize1.pnm", 0);
/* hop, un peu de nettoyage */
fimg_destroy(&result); fimg_destroy(&fimg);
return 0;
}
/* --------------------------------------------------------------------- */
int essai_sfx0(char *infile)
{
FloatImg fimg;
int foo;
if (NULL != infile) {
fprintf(stderr, "loading %s\n", infile);
foo = fimg_create_from_dump(infile, &fimg);
if (foo) {
fprintf(stderr, "%s: err load '%s'\n", __func__, infile);
return foo;
}
}
else {
fimg_create(&fimg, 512, 512, FIMG_TYPE_RGB);
fimg_draw_something(&fimg);
}
foo = fimg_save_as_pnm(&fimg, "something.pnm", 0);
if (foo) {
fprintf(stderr, "%s: err save %d\n", __func__, foo);
return -6;
}
foo = fimg_killcolors_a(&fimg, 0.0);
foo = fimg_save_as_pnm(&fimg, "colorskilled-a.pnm", 0);
if (foo) {
fprintf(stderr, "%s: err save %d\n", __func__, foo);
return -6;
}
foo = fimg_killcolors_b(&fimg, 0.0);
foo = fimg_save_as_pnm(&fimg, "colorskilled-b.pnm", 0);
if (foo) {
fprintf(stderr, "%s: err save %d\n", __func__, foo);
return -6;
}
fimg_destroy(&fimg);
return 0;
}
/* --------------------------------------------------------------------- */
int essai_parse_double(void)
{
int foo;
double dval;
char *str;
str = "12.34"; dval = 0.0;
foo = parse_double(str, &dval);
printf("%-10s -> %3d %g\n", str, foo, dval);
str = "12e4"; dval = 0.0;
foo = parse_double(str, &dval);
printf("%-10s -> %3d %g\n", str, foo, dval);
str = "5s"; dval = 0.0;
foo = parse_double(str, &dval);
printf("%-10s -> %3d %g\n", str, foo, dval);
str = "PORN"; dval = 0.0;
foo = parse_double(str, &dval);
printf("%-10s -> %3d %g\n", str, foo, dval);
return 0;
}
/* --------------------------------------------------------------------- */
int essai_detect_type(void)
{
int foo;
char *fname;
foo = format_from_extension(fname="foo.fimg");
printf("%-10s %3d\n", fname, foo);
foo = format_from_extension(fname="foo.pnm");
printf("%-10s %3d\n", fname, foo);
foo = format_from_extension(fname="foo.png");
printf("%-10s %3d\n", fname, foo);
foo = format_from_extension(fname="foo.tiff");
printf("%-10s %3d\n", fname, foo);
foo = format_from_extension(fname="foo.fits");
printf("%-10s %3d\n", fname, foo);
foo = format_from_extension(fname="foo.xyzzy");
printf("%-10s %3d\n", fname, foo);
return 0;
}
/* --------------------------------------------------------------------- */
int essai_mire(char *outname, int notused)
{
FloatImg fimg;
int re, foo;
fimg_create(&fimg, 1280, 960, FIMG_TYPE_RGB);
re = fimg_test_pattern(&fimg, 9, 1.0);
if (re) {
fprintf(stderr, "fimg_test_pattern -> %d\n", re);
}
foo = fimg_export_picture(&fimg, "mire.pnm", 0);
fprintf(stderr, "in %s, export give a %d value\n", __func__, foo);
return 0;
}
/* --------------------------------------------------------------------- */
int essai_rampes(void)
{
FloatImg fimg;
int foo;
fimg_create(&fimg, 640, 480, FIMG_TYPE_RGB);
#define V ((double)3.141592654)
foo = fimg_hdeg_a(&fimg, V);
fprintf(stderr, "make h deg -> %d\n", foo);
foo = fimg_save_as_pnm(&fimg, "hdeg.pnm", 0);
fprintf(stderr, "%s: save as pnm -> %d\n", __func__, foo);
foo = fimg_vdeg_a(&fimg, V);
fprintf(stderr, "make h deg -> %d\n", foo);
foo = fimg_save_as_pnm(&fimg, "vdeg_a.pnm", 0);
fprintf(stderr, "%s: save as pnm -> %d\n", __func__, foo);
foo = fimg_vdeg_a(&fimg, -V);
fprintf(stderr, "make h deg -> %d\n", foo);
foo = fimg_save_as_pnm(&fimg, "vdeg_b.pnm", 0);
fprintf(stderr, "%s: save as pnm -> %d\n", __func__, foo);
#undef V
return 0;
}
/* --------------------------------------------------------------------- */
int essai_lecture_png(char *fname, char *outfile, int notused)
{
FloatImg fimg;
int foo;
fprintf(stderr, ">>> %s ( '%s' %d )\n", __func__, fname, notused);
memset(&fimg, 0, sizeof(FloatImg));
foo = fimg_create_from_png(fname, &fimg);
if (foo) {
fprintf(stderr, "%s: createfrom -> %d\n", __func__, foo);
return foo;
}
fimg_describe(&fimg, "created from png");
foo = fimg_export_picture(&fimg, outfile, 0);
if (foo) {
fprintf(stderr, "%s : err %d saving result to %s\n", __func__,
foo, outfile);
return foo;
}
return 0;
}
/* --------------------------------------------------------------------- */
int essai_ecriture_png(char *fname)
{
FloatImg fimg;
int foo;
fimg_create(&fimg, 800, 600, FIMG_TYPE_RGB);
fimg_draw_something(&fimg);
if (verbosity) {
foo = fimg_save_as_pnm(&fimg, "quux.pnm", 0);
fprintf(stderr, "%s: saved as pnm -> %d\n", __func__, foo);
}
foo = fimg_save_as_png(&fimg, fname, 0);
fprintf(stderr, "save as png -> %d\n", foo);
fimg_destroy(&fimg);
return 0;
}
/* --------------------------------------------------------------------- */
int fimg_essai_hsv(char *fname); /* hsv.c */
int essai_histogramme(char *fname, int k)
{
FloatImg fimg;
int foo;
fprintf(stderr, ">>> %s ( '%s' %d )\n", __func__, fname, k);
foo = fimg_create_from_dump(fname, &fimg);
if (foo) {
fprintf(stderr, "%s: err load '%s'\n", __func__, fname);
return foo;
}
foo = fimg_essai_histo(&fimg, "out.png", k);
if (foo) {
fprintf(stderr, "essai_histo -> error %d\n", foo);
return foo;
}
fimg_destroy(&fimg);
fprintf(stderr, "\\o/ end of %s\n", __func__);
return 0;
}
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */

32
src/funcs/tests.h Normal file
View File

@@ -0,0 +1,32 @@
/*
* tests des fonctions diverses - prototypes
see also: t.c & tests.c
*/
int essai_plasma(char *infile, char *outfile, int ikoef, float fkoef);
int essai_miroir(char *inf, char *outf, int flags);
int essai_displacement(char *infile, char *outfile);
int essai_qsort_rgb(char *infile, char *outfile);
int essai_equalize(char *infile);
int essai_ecriture_fits(char *outname);
int essai_rotate(char *infile);
int essai_filtrage_2x2(char *infile);
int essai_filtrage_3x3(char *infile);
int essai_sfx0(char *infile);
int essai_mire(char *infile, int wtf);
int essai_ecriture_png(char *infile);
int essai_ecriture_tiff(char *infile);
int fimg_essai_hsv(char *infile);
int essai_classif(char *infile, char *outfile, float fvalue);
int essai_contour_2x2(char *filename, char *outfile);
int essai_geometrie(char *infile, int notused);
int essai_detect_type(void);
int fimg_essai_histo(FloatImg *src, char *outpic, int k); /* histogram.c */
int essai_histogramme(char *fname, int k);
int essai_lecture_png(char *fname, char *outfile, int notused);
int essai_highlights(char *inf, char *outf, int ikoef, float fkoef);
int essai_openexr(char *inf, char *outf, int flags);

28
src/funcs/tpnm.c Normal file
View File

@@ -0,0 +1,28 @@
/*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pam.h>
#include "../floatimg.h"
int fimg_pnm_infos(char *);
/* --------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo;
char *infile = "foo.pnm";
pnm_init(&argc, argv);
if (2 == argc) infile = argv[1];
foo = fimg_pnm_infos(infile);
fprintf(stderr, "got %d\n", foo);
return 0;
}
/* --------------------------------------------------------------------- */

140
src/funcs/utils.c Normal file
View File

@@ -0,0 +1,140 @@
/*
* FloatImg from tTh - 2021
*/
#include <stdio.h>
#include <string.h>
#include "../floatimg.h"
extern int verbosity; /* must be declared around main() */
/* --------------------------------------------------------------------- */
void fimg_print_minmax(float minmax[6], char *titre)
{
fprintf(stderr, "\t\tminmax %s\n", titre);
fprintf(stderr, "red\t\t%10f %10f\n", minmax[0], minmax[1]);
fprintf(stderr, "green\t\t%10f %10f\n", minmax[2], minmax[3]);
fprintf(stderr, "blue\t\t%10f %10f\n", minmax[4], minmax[5]);
}
/* --------------------------------------------------------------------- */
int parse_WxH(char *str, int *pw, int *ph)
{
// char *ptr;
int foo, w, h;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' %p %p )\n", __func__,
str, pw, ph);
#endif
foo = sscanf(str, "%dx%d", &w, &h);
if (2 != foo) {
fprintf(stderr, "%s : arg '%s' is invalid\n", __func__, str);
return foo;
}
*pw = w; *ph = h;
return 2;
}
/* --------------------------------------------------------------------- */
int parse_double(char *str, double *dptr)
{
double value;
int foo;
foo = sscanf(str, "%lf", &value);
if (1 == foo) {
*dptr = value;
return 1;
}
return -1;
}
/* --------------------------------------------------------------------- */
int file_type_from_name(char *name)
{
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' )\n", __func__, name);
#endif
if (!strcasecmp(name, "pnm" )) return FILE_TYPE_PNM;
if (!strcasecmp(name, "fimg")) return FILE_TYPE_FIMG;
if (!strcasecmp(name, "tga" )) return FILE_TYPE_TGA;
if (!strcasecmp(name, "png" )) return FILE_TYPE_PNG;
if (!strcasecmp(name, "tiff")) return FILE_TYPE_TIFF;
if (!strcasecmp(name, "tif" )) return FILE_TYPE_TIFF;
if (!strcasecmp(name, "fits")) return FILE_TYPE_FITS;
if (!strcasecmp(name, "exr")) return FILE_TYPE_EXR;
return -1;
}
/* --------------------------------------------------------------------- */
int print_rectangle(char *str, FimgArea51 *rect)
{
printf("rect @ %p '%s':\n\t %dx%d at %d,%d\n", rect, str,
rect->w, rect->h, rect->x, rect->y);
return 0;
}
/* ---------------------------------------------- ~~~~~~~~~~~~~~~~ */
/*
* /!\ return 4 on success
*/
int parse_rectangle(char *str, FimgArea51 *r, int notused)
{
int x, y, w, h, foo;
if (verbosity)
fprintf(stderr, "parsing %s\n", str);
foo = sscanf(str, "%d,%d,%d,%d", &w, &h, &x, &y);
if (4 == foo) {
r->x = x, r->y = y, r->w = w, r->h = h;
return 4;
}
return -1;
}
/* --------------------------------------------------------------------- */
int format_from_extension(char *fname)
{
char *cptr;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' )\n", __func__, fname);
#endif
cptr = rindex(fname, '.');
if (NULL==cptr) {
fprintf(stderr, "No dot in %s\n", fname);
return -1;
}
#if DEBUG_LEVEL
fprintf(stderr, "\t[%s] --> [%s]\n", fname, cptr);
#endif
return file_type_from_name(cptr+1);
}
/* --------------------------------------------------------------------- */
char * extension_from_format(int fmt)
{
switch (fmt) {
case FILE_TYPE_FIMG: return ".fimg"; break;
case FILE_TYPE_PNM: return ".pnm"; break;
case FILE_TYPE_PNG: return ".png"; break;
case FILE_TYPE_TIFF: return ".tiff"; break;
case FILE_TYPE_FITS: return ".fits"; break;
case FILE_TYPE_TGA: return ".tga"; break;
default:
fprintf(stderr, "%s: bad %d fmt type\n", __func__, fmt);
return NULL;
}
return "???";
}
/* --------------------------------------------------------------------- */

43
src/funcs/vroum.sh Executable file
View File

@@ -0,0 +1,43 @@
#!/bin/bash
src=/dev/shm/foo.fimg
out=out.fimg
device=/dev/video2
maxi=59
W="320"
H="240"
grabopt=" -s ${W}x${H} -vv -u -d $device -p 0 -n 30
0 -c none "
mkdir /tmp/V
rm /tmp/V/*
G=$(printf "%dx%d+0+0" $W $H)
for foo in $(seq 0 $maxi)
do
echo ; echo
grabvidseq -$grabopt -o $src
fval=$(echo "$foo / $maxi * 13.56636" | bc -l)
echo ; echo $foo ' => ' $fval
./t -vv -k $fval -o $out plasma $src
# fimgstats $out
dst=$(printf "/tmp/V/%03d.png" $foo)
echo $dst
montage $src $out -tile 1x2 -geometry $G $dst
sleep 55
done
convert -delay 10 /tmp/V/*.png foo.gif
rm /tmp/V/*

72
src/lib/Makefile Normal file
View File

@@ -0,0 +1,72 @@
#
# building the base library
#
LIB_DIR = ../../build/lib
STATIC_LIB = $(LIB_DIR)/libfloatimg.a
OBJ_DIR = ../../build/obj
DYN_OBJ = $(OBJ_DIR)/libfloatimg-lib.o
COPT = -Wall -fpic -g -no-pie -DDEBUG_LEVEL=0
OBJS = fimg-core.o fimg-pnm.o fimg-file.o fimg-math.o \
fimg-timers.o operators.o fimg-2gray.o \
interpolate.o fimg-compare.o contrast.o
DEPS = Makefile ../floatimg.h
# modify it 'as you like'
AR=ar
all: $(OBJS) $(STATIC_LIB) $(DYN_OBJ)
# t: t.c ../libfloatimg.a $(DEPS)
# gcc $(COPT) $< ../libfloatimg.a -lpnglite -lz -lm -o $@
clean:
rm -rf $(OBJS) $(STATIC_LIB) $(DYN_OBJ)
# --------------------------------------------
$(STATIC_LIB): $(OBJS)
mkdir -p $(LIB_DIR)
$(AR) r $@ $?
$(DYN_OBJ): $(OBJS) # verbosity.o
mkdir -p $(OBJ_DIR)
ld -Ur -o $@ $?
fimg-core.o: fimg-core.c $(DEPS)
gcc $(COPT) -c $<
fimg-compare.o: fimg-compare.c $(DEPS)
gcc $(COPT) -c $<
fimg-2gray.o: fimg-2gray.c $(DEPS)
gcc $(COPT) -c $<
operators.o: operators.c $(DEPS)
gcc $(COPT) -c $<
contrast.o: contrast.c $(DEPS)
gcc $(COPT) -c $<
interpolate.o: interpolate.c $(DEPS)
gcc $(COPT) -c $<
fimg-pnm.o: fimg-pnm.c $(DEPS)
gcc $(COPT) -c $<
fimg-file.o: fimg-file.c $(DEPS)
gcc $(COPT) -c $<
fimg-math.o: fimg-math.c $(DEPS)
gcc $(COPT) -c $<
fimg-timers.o: fimg-timers.c $(DEPS)
gcc $(COPT) -c $<
# --------------------------------------------

176
src/lib/contrast.c Normal file
View File

@@ -0,0 +1,176 @@
/*
* contrast.c - part of libfloatimg
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
#include "../floatimg.h"
extern int verbosity;
/* ---------------------------------------------------------------- */
int fimg_id_contraste(char *str)
{
if (!strcmp(str, "none")) return CONTRAST_NONE;
if (!strcmp(str, "sqrt")) return CONTRAST_SQRT;
if (!strcmp(str, "pow2")) return CONTRAST_POW2;
if (!strcmp(str, "cos01")) return CONTRAST_COS01;
if (!strcmp(str, "cos010")) return CONTRAST_COS010;
return -1;
}
/* ---------------------------------------------------------------- */
/*
* if the second parameter is NULL, operate 'in-place'
*/
int fimg_square_root(FloatImg *s, FloatImg *d, double maxval)
{
int nbre, idx;
double dval;
if (s->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, s->type);
return -4;
}
if (NULL==d) { d = s; }
else {
if (d->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : dst type %d invalide\n",
__func__, d->type);
return -4;
}
}
nbre = s->width * s->height;
for (idx=0; idx<nbre; idx++) {
dval = s->R[idx] / maxval;
d->R[idx] = maxval * sqrt(dval);
dval = s->G[idx] / maxval;
d->G[idx] = maxval * sqrt(dval);
dval = s->B[idx] / maxval;
d->B[idx] = maxval * sqrt(dval);
}
return 0;
}
/* ---------------------------------------------------------------- */
int fimg_power_2(FloatImg *s, FloatImg *d, double maxval)
{
int nbre, idx;
double dval;
if (s->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s: src type %d invalide\n",
__func__, s->type);
return -4;
}
if (NULL==d) { d = s; }
else {
if (d->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s: dst type %d invalide\n",
__func__, d->type);
return -4;
}
}
nbre = s->width * s->height;
for (idx=0; idx<nbre; idx++) {
dval = s->R[idx] / maxval;
d->R[idx] = maxval * dval * dval;
dval = s->G[idx] / maxval;
d->G[idx] = maxval * dval * dval;
dval = s->B[idx] / maxval;
d->B[idx] = maxval * dval * dval;
}
return 0;
}
/* ---------------------------------------------------------------- */
/*
#macro Cos_01( X )
(0.5-0.5*cos( 3.141592654 * X))
#end
*/
int fimg_cos_01(FloatImg *s, FloatImg *d, double maxval)
{
int nbre, idx;
double dval;
if (s->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, s->type);
return -4;
}
if (NULL==d) { d = s; }
else {
if (d->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : dst type %d invalide\n",
__func__, d->type);
return -4;
}
}
nbre = s->width * s->height;
for (idx=0; idx<nbre; idx++) {
dval = s->R[idx] / maxval;
d->R[idx] = maxval * (0.5 - 0.5 * cos(3.141592654*dval));
dval = s->G[idx] / maxval;
d->G[idx] = maxval * (0.5 - 0.5 * cos(3.141592654*dval));
dval = s->B[idx] / maxval;
d->B[idx] = maxval * (0.5 - 0.5 * cos(3.141592654*dval));
}
return 0;
}
/* ---------------------------------------------------------------- */
int fimg_cos_010(FloatImg *s, FloatImg *d, double maxval)
{
int nbre, idx;
double dval;
if (s->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, s->type);
return -4;
}
if (NULL==d) { d = s; }
else {
if (d->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : dst type %d invalide\n",
__func__, d->type);
return -4;
}
}
nbre = s->width * s->height;
for (idx=0; idx<nbre; idx++) {
dval = s->R[idx] / maxval;
d->R[idx] = maxval * (0.5 - 0.5 * cos(2*3.141592654*dval));
dval = s->G[idx] / maxval;
d->G[idx] = maxval * (0.5 - 0.5 * cos(2*3.141592654*dval));
dval = s->B[idx] / maxval;
d->B[idx] = maxval * (0.5 - 0.5 * cos(2*3.141592654*dval));
}
return 0;
}
/* ---------------------------------------------------------------- */

80
src/lib/fimg-2gray.c Normal file
View File

@@ -0,0 +1,80 @@
/*
* fimg-2gray.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "string.h"
#include "../floatimg.h"
extern int verbosity; /* must be declared around main() */
/* --------------------------------------------------------------------- */
/*
* floating resultat img MUST be allocated before calling this func.
*/
int fimg_mk_gray_from(FloatImg *src, FloatImg *dst, int k)
{
float kr, kg, kb, kdiv;
int nbb, foo;
kr = kg = kb = 1.0; /* canonic random values */
kdiv = kr + kg + kb;
/* we must check the validity of our parameters */
if (FIMG_TYPE_RGB != src->type) {
fprintf(stderr, "%s : bad src type %d on %p\n", __func__,
src->type, src);
return -8;
}
if (FIMG_TYPE_GRAY != dst->type) {
fprintf(stderr, "%s : bad dst type %d on %p\n", __func__,
dst->type, dst);
/*
* may be we can convert dst picture on the fly ?
*/
return -9;
}
/* entering the main processing loop */
nbb = src->width * src->height;
for (foo=0; foo<nbb; foo++) {
dst->R[foo] = ( (src->R[foo] * kr) +
(src->G[foo] * kg) +
(src->B[foo] * kb) ) /
kdiv;
}
return 0;
}
/* --------------------------------------------------------------------- */
/* this function can work 'in place' */
int fimg_desaturate(FloatImg *src, FloatImg *dst, int notused)
{
int foo, nbb;
/* we must check the validity of our parameters */
if (FIMG_TYPE_RGB != src->type || FIMG_TYPE_RGB != dst->type) {
fprintf(stderr, "%s : bad image type\n", __func__);
return -18;
}
/* entering the main processing loop */
nbb = src->width * src->height;
for (foo=0; foo<nbb; foo++) {
dst->R[foo] = dst->G[foo] = dst->B[foo] =
(src->R[foo] + src->G[foo] + src->B[foo]) / 3.0;
}
return 0;
}
/* --------------------------------------------------------------------- */

42
src/lib/fimg-compare.c Normal file
View File

@@ -0,0 +1,42 @@
/*
* fimg-compare.c
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "string.h"
#include "../floatimg.h"
extern int verbosity; /* must be declared around main() */
/* ---------------------------------------------------------------- */
/*
* return 0 if images are compatibles
*/
int fimg_images_not_compatible(FloatImg *a, FloatImg *b)
{
#if DEBUG_LEVEL > 1
fprintf(stderr, ">>> %s ( %p %p )\n", __func__, a, b);
#endif
if (a->type != b->type) {
if (verbosity) fprintf(stderr, "%p %p != type\n", a, b);
return -10;
}
if (a->width != b->width) {
if (verbosity) fprintf(stderr, "%p %p != width\n", a, b);
return -11;
}
if (a->height != b->height) {
if (verbosity) fprintf(stderr, "%p %p != height\n", a, b);
return -12;
}
return 0;
}
/* ---------------------------------------------------------------- */

367
src/lib/fimg-core.c Normal file
View File

@@ -0,0 +1,367 @@
/*
* fimg-core.c
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "string.h"
#include "../floatimg.h"
extern int verbosity; /* must be declared around main() */
/* ---------------------------------------------------------------- */
int fimg_type_is_valid(int type)
{
switch (type) {
case FIMG_TYPE_GRAY:
case FIMG_TYPE_RGB:
case FIMG_TYPE_RGBA:
case FIMG_TYPE_RGBZ: return 1;
}
return 0;
}
/* --------------------------------------------------------------------- */
char *fimg_str_type(int type)
{
switch (type) {
case FIMG_TYPE_GRAY: return "gray";
case FIMG_TYPE_RGB: return "rgb";
case FIMG_TYPE_RGBA: return "rgba";
case FIMG_TYPE_RGBZ: return "rgbz";
}
return "???";
}
/* --------------------------------------------------------------------- */
int fimg_print_version(int k)
{
fprintf(stderr, "*** FloatImg library, alpha %d (%s, %s)\n",
FIMG_VERSION, __DATE__, __TIME__);
if (51 == k) {
puts("+------------------------+");
puts("| Pastis is coming soon |");
puts("+------------------------+");
}
return 0;
}
/* --------------------------------------------------------------------- */
void fimg_print_sizeof(void)
{
fprintf(stderr, " sz FloatImg = %lu\n", sizeof(FloatImg));
fprintf(stderr, " sz filehead = %lu\n", sizeof(FimgFileHead));
fprintf(stderr, " sz filter = %lu\n", sizeof(FimgFilter3x3));
}
/* --------------------------------------------------------------------- */
void fimg_printdims(char *txt, FloatImg *pi)
{
fprintf(stderr, "# %s %dx%d\n", txt, pi->width, pi->height);
}
/* --------------------------------------------------------------------- */
void fimg_printhead(FloatImg *h)
{
printf("%5d %5d %2d %p %p %p %p\n", h->width, h->height, h->type,
h->R, h->G, h->B, h->A);
}
/* --------------------------------------------------------------------- */
int fimg_describe(FloatImg *head, char *txt)
{
printf("----- '%s' at %p -----\n", txt, head);
if( ! fimg_type_is_valid(head->type) ) {
fprintf(stderr, "*** %s *** type %d invalid *** %s ***\n",
__func__, head->type, txt);
return -1;
}
printf(" type %d %s\n", head->type, fimg_str_type(head->type));
printf(" dims %d x %d\n", head->width, head->height);
printf(" fval/count %f %d\n", head->fval, head->count);
printf(" pixels@ %p %p %p %p\n",
head->R, head->G, head->B, head->A);
return 0;
}
/* ---------------------------------------------------------------- */
static float *plane_alloc(int size)
{
float *fptr;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %d )\n", __func__, size);
#endif
fptr = calloc(size, sizeof(float));
if (NULL==fptr) {
fprintf(stderr, "no more memory available, ABEND\n");
abort();
}
return fptr;
}
/* ---------------------------------------------------------------- */
/*
* values for the parameter 'type' are defined in 'floatimg.h'
*/
int fimg_create(FloatImg *fimg, int w, int h, int type)
{
int size;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %d %d %d )\n", __func__, fimg, w, h, type);
#endif
if ( ! fimg_type_is_valid(type) ) {
fprintf(stderr, "%s: type %d invalid\n", __func__, type);
return -2;
}
/*
* what to do if we've got a descriptor for an image
* already allocated ? and how to check that ?
*/
memset(fimg, 0, sizeof(FloatImg));
size = w * h;
fimg->width = w; fimg->height = h;
fimg->type = type;
/* the red channel is allway allocated */
fimg->R = (float *)plane_alloc(size);
if (FIMG_TYPE_RGB == type) {
fimg->G = (float *)plane_alloc(size);
fimg->B = (float *)plane_alloc(size);
}
if (FIMG_TYPE_RGBA == type) {
fimg->G = (float *)plane_alloc(size);
fimg->B = (float *)plane_alloc(size);
fimg->A = (float *)plane_alloc(size);
}
return 0;
}
/* --------------------------------------------------------------------- */
int fimg_destroy(FloatImg *fimg)
{
#if DEBUG_LEVEL
fprintf(stderr, ">>> %-25s ( %p )\n", __func__, fimg);
#endif
if (NULL == fimg) {
fprintf(stderr, "%s : parameter is null\n", __func__);
return -1;
}
if ( ! fimg_type_is_valid(fimg->type) ) {
fprintf(stderr, "%s : type %d invalid\n", __func__,
fimg->type);
return -2;
}
if (NULL == fimg->R) {
fprintf(stderr, "%s : %p already freed ?\n", __func__, fimg);
return -3;
}
free(fimg->R);
if (FIMG_TYPE_RGB == fimg->type) {
free(fimg->G);
free(fimg->B);
}
memset(fimg, 0, sizeof(FloatImg));
return 0;
}
/* --------------------------------------------------------------------- */
int fimg_clone(FloatImg *old, FloatImg *new, int flags)
{
int foo, size;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p 0x%x )\n", __func__, old, new, flags);
#endif
if ( ! fimg_type_is_valid(old->type) ) {
fprintf(stderr, "invalid type %d in %s\n", old->type, __func__);
return -2;
}
memset(new, 0, sizeof(FloatImg));
foo = fimg_create(new, old->width, old->height, old->type);
if (foo) {
fprintf(stderr, "error %d in %s\n", foo, __func__);
return -3;
}
if (flags & 0x01) { /* copy pixels values */
size = old->width * old->height * sizeof(float);
memcpy(new->R, old->R, size);
memcpy(new->G, old->G, size);
memcpy(new->B, old->B, size);
}
return 0;
}
/* --------------------------------------------------------------------- */
int fimg_copy_data(FloatImg *from, FloatImg *to)
{
int size;
int foo;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p )\n", __func__, from, to);
#endif
foo = fimg_images_not_compatible(from, to);
if (foo) {
fprintf(stderr, "%s: pics not compatible (%d)\n", __func__, foo);
return foo;
}
size = from->width * from->height * sizeof(float);
memcpy(to->R, from->R, size);
memcpy(to->G, from->G, size);
memcpy(to->B, from->B, size);
return 0;
}
/* --------------------------------------------------------------------- */
int fimg_clear(FloatImg *fimg)
{
int size;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %-25s ( %p )\n", __func__, fimg);
#endif
if ( ! fimg_type_is_valid(fimg->type) ) {
fprintf(stderr, "invalid type %d in %s\n", fimg->type, __func__);
return -2;
}
size = fimg->width * fimg->height * sizeof(float);
memset(fimg->R, 0, size);
memset(fimg->G, 0, size);
memset(fimg->B, 0, size);
return 0;
}
/* --------------------------------------------------------------------- */
int fimg_rgb_constant(FloatImg *head, float r, float g, float b)
{
int idx, size;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %-25s ( %p %f %f %f )\n", __func__, head,
r, g, b);
#endif
if (head->type != FIMG_TYPE_RGB) {
return -21;
}
size = head->width * head->height;
for (idx=0; idx<size; idx++) {
head->R[idx] = r;
head->G[idx] = g;
head->B[idx] = b;
}
return 0;
}
/* --------------------------------------------------------------------- */
int fimg_plot_rgb (FloatImg *head, int x, int y,
float r, float g, float b)
{
int offset;
if (head->type < 3) {
#if DEBUG_LEVEL > 1
fprintf(stderr, "%s : type %d is bad.\n", __func__, head->type);
#endif
return -1;
}
offset = x + (y * head->width);
#if DEBUG_LEVEL > 1
fprintf(stderr, ">>> %s ( %p %d %d %f )\n", __func__, head, x, y, gray);
fprintf(stderr, " offset %d\n", offset);
#endif
head->R[offset] = r;
head->G[offset] = g;
head->B[offset] = b;
return 0;
}
/* ---------------------------------------------------------------- */
int fimg_add_rgb(FloatImg *head, int x, int y, float r, float g, float b)
{
int offset;
if (head->type != FIMG_TYPE_RGB) {
#if DEBUG_LEVEL > 1
fprintf(stderr, "%s : type %d is bad.\n", __func__, head->type);
#endif
return -1;
}
offset = x + (y * head->width);
head->R[offset] += r;
head->G[offset] += g;
head->B[offset] += b;
return 0;
}
/* --------------------------------------------------------------------- */
/* nouveau 12 fevrier 2020 */
int fimg_get_rgb(FloatImg *head, int x, int y, float *prgb)
{
int offset;
if (head->type != FIMG_TYPE_RGB) {
#if DEBUG_LEVEL > 1
fprintf(stderr, "%s : type %d is bad.\n", __func__, head->type);
#endif
return -1;
}
offset = x + (y * head->width);
prgb[0] = head->R[offset];
prgb[1] = head->G[offset];
prgb[2] = head->B[offset];
return 0;
}
/* --------------------------------------------------------------------- */
/* nouveau 24 mars 2020 - coronacoding */
int fimg_put_rgb(FloatImg *head, int x, int y, float *prgb)
{
int offset;
if (head->type != FIMG_TYPE_RGB) {
#if DEBUG_LEVEL > 1
fprintf(stderr, "%s : type %d is bad.\n", __func__, head->type);
#endif
return -1;
}
offset = x + (y * head->width);
head->R[offset] = prgb[0];
head->G[offset] = prgb[1];
head->B[offset] = prgb[2];
return 0;
}
/* --------------------------------------------------------------------- */

217
src/lib/fimg-file.c Normal file
View File

@@ -0,0 +1,217 @@
/*
* fimg-file.c
*
*
*/
#include <stdio.h>
#include <stdlib.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;
}

321
src/lib/fimg-math.c Normal file
View File

@@ -0,0 +1,321 @@
/*
* fimg-core.c
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <float.h> /* for FLT_MAX */
#include <math.h>
#include "../floatimg.h"
extern int verbosity; /* must be declared around main() */
/* ---------------------------------------------------------------- */
float fimg_get_maxvalue(FloatImg *head)
{
float maxval;
int foo, surface;
if (head->type != FIMG_TYPE_RGB && head->type != FIMG_TYPE_GRAY) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, head->type);
return nanf("wtf ?");
}
maxval = 0.0; /* no negative values allowed */
surface = head->width*head->height;
switch (head->type) {
case FIMG_TYPE_RGB:
for (foo=0; foo<surface; foo++) {
if (head->R[foo] > maxval) maxval = head->R[foo];
if (head->G[foo] > maxval) maxval = head->G[foo];
if (head->B[foo] > maxval) maxval = head->B[foo];
}
case FIMG_TYPE_GRAY:
for (foo=0; foo<surface; foo++) {
if (head->R[foo] > maxval) maxval = head->R[foo];
}
}
return maxval;
}
/* ---------------------------------------------------------------- */
/*
* mmval[0] <- min(R) mmval[1] <- max(R)
*/
int fimg_get_minmax_rgb(FloatImg *head, float mmvals[6])
{
int idx, surface;
float fval;
if (head->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, head->type);
return -2;
}
surface = head->width * head->height;
mmvals[0] = FLT_MAX; mmvals[1] = -FLT_MAX;
mmvals[2] = FLT_MAX; mmvals[3] = -FLT_MAX;
mmvals[4] = FLT_MAX; mmvals[5] = -FLT_MAX;
for (idx=0; idx<surface; idx++) {
fval = head->R[idx];
if (fval < mmvals[0]) mmvals[0] = fval;
else if (fval > mmvals[1]) mmvals[1] = fval;
fval = head->G[idx];
if (fval < mmvals[2]) mmvals[2] = fval;
else if (fval > mmvals[3]) mmvals[3] = fval;
fval = head->B[idx];
if (fval < mmvals[4]) mmvals[4] = fval;
else if (fval > mmvals[5]) mmvals[5] = fval;
}
return -0;
}
/* ---------------------------------------------------------------- */
int fimg_meanvalues(FloatImg *head, float means[4])
{
int idx, surface;
double accus[4];
surface = head->width * head->height;
if (surface < 1) return -1;
memset(accus, 0, 4*sizeof(double));
for (idx=0; idx<surface; idx++) {
accus[0] += (double)head->R[idx];
if (head->type > 2) { /* WTF ? */
accus[1] += (double)head->G[idx];
accus[2] += (double)head->B[idx];
}
}
for (idx=0; idx<4; idx++) {
means[idx] = (float)(accus[idx]/(double)surface);
}
return 0;
}
/* ---------------------------------------------------------------- */
/* d'après Wikipedia Fr :
| c = 0
| s = x1
| pour j de 2 à n
| s = s+xj
| c = c+(j xj s)2/(j(j1))
| renvoyer c/n
Mais c,a ne semble pas etre la bonne methode. Il faut aller voir :
https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
*/
/* ---------------------------------------------------------------- */
/*
* more elaborate functions are in fimg-2gray.c
*/
int fimg_to_gray(FloatImg *head)
{
float add;
int foo;
if (head->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, head->type);
return -3;
}
for (foo=0; foo<(head->width*head->height); foo++) {
add = head->R[foo];
add += head->G[foo];
add += head->B[foo];
head->R[foo] = head->G[foo] = head->B[foo] = add / 3.0;
}
return 0;
}
/* ---------------------------------------------------------------- */
int fimg_add_cste(FloatImg *fi, float value)
{
int nbre, idx;
if (fi->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, fi->type);
return -44;
}
nbre = fi->width * fi->height ;
#if DEBUG_LEVEL
fprintf(stderr, "%s, nbre is %d\n", __func__, nbre);
#endif
for (idx=0; idx<nbre; idx++) {
fi->R[idx] += value;
fi->G[idx] += value;
fi->B[idx] += value;
}
return 0;
}
/* ---------------------------------------------------------------- */
long fimg_count_negativ(FloatImg *fi)
{
int nbre, idx;
long count;
if (fi->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, fi->type);
return -1;
}
nbre = fi->width * fi->height;
count = 0;
for (idx=0; idx<nbre; idx++) {
if (fi->R[idx] < 0.0) count++;
if (fi->G[idx] < 0.0) count++;
if (fi->B[idx] < 0.0) count++;
}
return count;
}
/* ---------------------------------------------------------------- */
/* nouveau 29 fevrier 2020 */
long fimg_clamp_negativ(FloatImg *fi)
{
int nbre, idx;
long count;
if (fi->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, fi->type);
return -1;
}
nbre = fi->width * fi->height;
count = 0;
for (idx=0; idx<nbre; idx++) {
if (fi->R[idx] < 0.0) {
fi->R[idx] = 0.0; count++;
}
if (fi->G[idx] < 0.0) {
fi->G[idx] = 0.0; count++;
}
if (fi->B[idx] < 0.0) {
fi->B[idx] = 0.0; count++;
}
}
/* WTF 12 avril 2020, valgrind me cause mal ?
==28943== Conditional jump or move depends on uninitialised value(s)
==28943== at 0x4045E9: fimg_clamp_negativ (fimg-math.c:208)
==28943== by 0x4018C9: essai_filtrage_3x3 (t.c:128)
==28943== by 0x4024D5: main (t.c:444)
==28943== Uninitialised value was created by a heap allocation
==28943== at 0x483577F: malloc (vg_replace_malloc.c:299)
==28943== by 0x40284D: fimg_create (fimg-core.c:107)
==28943== by 0x402AB3: fimg_clone (fimg-core.c:174)
==28943== by 0x401861: essai_filtrage_3x3 (t.c:118)
==28943== by 0x4024D5: main (t.c:444)
*/
return count;
}
/* ---------------------------------------------------------------- */
int fimg_mul_cste(FloatImg *fi, float value)
{
int nbre, idx;
if ( (fi->type != FIMG_TYPE_RGB) && (fi->type != FIMG_TYPE_GRAY) ) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, fi->type);
return -44;
}
nbre = fi->width * fi->height;
#if DEBUG_LEVEL
fprintf(stderr, "%s, nbre of datum is %d\n", __func__, nbre);
#endif
if (fi->type == FIMG_TYPE_RGB) {
for (idx=0; idx<nbre; idx++) {
fi->R[idx] *= value;
fi->G[idx] *= value;
fi->B[idx] *= value;
}
}
if (fi->type == FIMG_TYPE_GRAY) {
for (idx=0; idx<nbre; idx++) {
fi->R[idx] *= value;
}
}
return 0;
}
/* ---------------------------------------------------------------- */
/*
* oh, please explain the usecase of this function !
*/
int fimg_ajust_from_grab(FloatImg *fi, double maxima, int notused)
{
double coef;
if (fi->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, fi->type);
return -99;
}
if (fi->count < 1) {
fprintf(stderr, "%s : count %d is invalid\n", __func__, fi->count);
return -98;
}
/*
* mmmm, is this real ?
* how to accuratly check the value of 'I.fval' ?
*/
coef = 1.0 / ((double)fi->count * (double)fi->fval);
if (verbosity) {
fprintf(stderr, "image @ %p\n", fi);
fprintf(stderr, "fval %f\n", fi->fval);
fprintf(stderr, "count %d\n", fi->count);
fprintf(stderr, "coef %f\n", coef);
}
fimg_mul_cste(fi, coef);
return 0;
}
/* ---------------------------------------------------------------- */
/* Warning: this function is _very_ slow */
void fimg_drand48(FloatImg *fi, float kmul)
{
int nbre, idx;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %g )\n", __func__, fi, kmul);
#endif
if (fi->type != FIMG_TYPE_RGB) {
fprintf(stderr, "%s : type %d invalide\n",
__func__, fi->type);
return;
}
nbre = fi->width * fi->height;
for (idx=0; idx<nbre; idx++) {
fi->R[idx] = drand48() * kmul;
fi->G[idx] = drand48() * kmul;
fi->B[idx] = drand48() * kmul;
}
}
/* ---------------------------------------------------------------- */

197
src/lib/fimg-pnm.c Normal file
View File

@@ -0,0 +1,197 @@
/*
* 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;
}
/* ---------------------------------------------------------------- */

42
src/lib/fimg-timers.c Normal file
View File

@@ -0,0 +1,42 @@
/*
* timers.c BUGS INSIDE ?
*/
#include <stdio.h>
#include <sys/time.h>
extern int verbosity;
/* ----------------------------------------------------------------- */
static double dtime(void)
{
struct timeval t;
double d;
(void)gettimeofday(&t, NULL);
d = (double)t.tv_sec + (double)t.tv_usec / 1e6;
return d;
}
/* ----------------------------------------------------------------- */
/* we can have only one timer at this time. patches welcome.*/
static double memory_time;
double fimg_timer_set(int whot)
{
double current;
current = dtime();
#if DEBUG_LEVEL
fprintf(stderr, "%s ( %d ) -> current %f\n", __func__, whot, current);
#endif
memory_time = current;
return memory_time;
}
/* ----------------------------------------------------------------- */
double fimg_timer_get(int whot)
{
double current;
current = dtime();
return current - memory_time;
}
/* ----------------------------------------------------------------- */

75
src/lib/interpolate.c Normal file
View File

@@ -0,0 +1,75 @@
/*
* interpolate.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
#include "../floatimg.h"
extern int verbosity;
/* ---------------------------------------------------------------- */
static int gray_interpolate(FloatImg *s1, FloatImg *s2, FloatImg *d, float coef)
{
int picsize, idx;
picsize = d->width * d->height;
for (idx=0; idx<picsize; idx++) {
d->R[idx] = (coef * s1->R[idx]) + ((1.0-coef) * s2->R[idx]);
}
return 0;
}
/* ---------------------------------------------------------------- */
static int rgb_interpolate(FloatImg *s1, FloatImg *s2, FloatImg *d, float coef)
{
int picsize, idx;
picsize = d->width * d->height;
for (idx=0; idx<picsize; idx++) {
d->R[idx] = (coef * s1->R[idx]) + ((1.0-coef) * s2->R[idx]);
d->G[idx] = (coef * s1->G[idx]) + ((1.0-coef) * s2->G[idx]);
d->B[idx] = (coef * s1->B[idx]) + ((1.0-coef) * s2->B[idx]);
}
return 0;
}
/* ---------------------------------------------------------------- */
int fimg_interpolate(FloatImg *s1, FloatImg *s2, FloatImg *d, float coef)
{
int foo;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %p %f )\n", __func__,
s1, s2, d, coef);
#endif
foo = fimg_images_not_compatible(s1, s2);
if (foo) {
fprintf(stderr, "compat s1 s2 -> %d\n", foo);
return foo;
}
foo = fimg_images_not_compatible(s1, d);
if (foo) {
fprintf(stderr, "compat s1 d -> %d\n", foo);
return foo;
}
switch (s1->type) {
case FIMG_TYPE_GRAY:
gray_interpolate (s1, s2, d, coef); break;
case FIMG_TYPE_RGB:
rgb_interpolate (s1, s2, d, coef); break;
default:
fprintf(stderr, "%s, %d is a bad type\n", __func__, s1->type);
return -18;
}
return 0;
}
/* ---------------------------------------------------------------- */

216
src/lib/operators.c Normal file
View File

@@ -0,0 +1,216 @@
/*
* OPERATORS
*
* operations entre des images.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
#include "../floatimg.h"
extern int verbosity; /* must be declared around main() */
/* ---------------------------------------------------------------- */
/*
* A + B -> D
*/
int fimg_add_3(FloatImg *a, FloatImg *b, FloatImg *d)
{
int idx, nbpixels;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %p )\n", __func__, a, b, d);
#endif
if (FIMG_TYPE_RGB != a->type ||
FIMG_TYPE_RGB != b->type ||
FIMG_TYPE_RGB != d->type) {
fprintf(stderr, "%s : got a bad type fimg\n", __func__);
return -8;
}
nbpixels = a->width * a->height;
for (idx=0; idx<nbpixels; idx++) {
d->R[idx] = a->R[idx] + b->R[idx];
d->G[idx] = a->G[idx] + b->G[idx];
d->B[idx] = a->B[idx] + b->B[idx];
}
return 0;
}
/* ---------------------------------------------------------------- */
/*
* B += A may be faster than fimg_add_3 ?
*/
int fimg_add_2(FloatImg *a, FloatImg *b)
{
int idx, nbpixels;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p )\n", __func__, a, b);
#endif
if (FIMG_TYPE_RGB != a->type || FIMG_TYPE_RGB != b->type) {
fprintf(stderr, "%s : got a bad type fimg\n", __func__);
return -8;
}
nbpixels = a->width * a->height;
for (idx=0; idx<nbpixels; idx++) {
b->R[idx] += a->R[idx];
b->G[idx] += a->G[idx];
b->B[idx] += a->B[idx];
}
return 0;
}
/* ---------------------------------------------------------------- */
/*
* A - B -> D
*/
int fimg_sub_3(FloatImg *a, FloatImg *b, FloatImg *d)
{
int idx, nbpixels;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %p )\n", __func__, a, b, d);
#endif
if ( FIMG_TYPE_RGB != a->type ||
FIMG_TYPE_RGB != b->type ||
FIMG_TYPE_RGB != d->type) {
fprintf(stderr, "%s : got a bad type fimg\n", __func__);
return -8;
}
nbpixels = a->width * a->height;
/* maybe we can speedup this loop for
* avoiding the cache strashing ?
*/
for (idx=0; idx<nbpixels; idx++) {
d->R[idx] = fabs(a->R[idx] - b->R[idx]);
d->G[idx] = fabs(a->G[idx] - b->G[idx]);
d->B[idx] = fabs(a->B[idx] - b->B[idx]);
}
return 0;
}
/* ---------------------------------------------------------------- */
/*
* B *= A may be faster than fimg_mul_3 ?
*/
int fimg_mul_2(FloatImg *a, FloatImg *b)
{
int idx, nbpixels;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p )\n", __func__, a, b);
#endif
if (FIMG_TYPE_RGB != a->type || FIMG_TYPE_RGB != b->type) {
fprintf(stderr, "%s : got a bad type fimg\n", __func__);
return -8;
}
nbpixels = a->width * a->height;
for (idx=0; idx<nbpixels; idx++) {
b->R[idx] *= a->R[idx];
b->G[idx] *= a->G[idx];
b->B[idx] *= a->B[idx];
}
return 0;
}
/* ---------------------------------------------------------------- */
/*
* A * B -> D
*/
int fimg_mul_3(FloatImg *a, FloatImg *b, FloatImg *d)
{
int idx, nbpixels;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %p )\n", __func__, a, b, d);
#endif
if (FIMG_TYPE_RGB != a->type || FIMG_TYPE_RGB != b->type ||
FIMG_TYPE_RGB != d->type) {
fprintf(stderr, "%s : got a bad type fimg\n", __func__);
return -8;
}
nbpixels = a->width * a->height;
for (idx=0; idx<nbpixels; idx++) {
d->R[idx] = a->R[idx] * b->R[idx];
d->G[idx] = a->G[idx] * b->G[idx];
d->B[idx] = a->B[idx] * b->B[idx];
}
return 0;
}
/* ---------------------------------------------------------------- */
int fimg_minimum(FloatImg *a, FloatImg *b, FloatImg *d)
{
int idx, nbiter;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %p )\n", __func__, a, b, d);
#endif
if (FIMG_TYPE_RGB != a->type || FIMG_TYPE_RGB != b->type ||
FIMG_TYPE_RGB != d->type) {
fprintf(stderr, "%s : got a bad type fimg\n", __func__);
return -8;
}
nbiter = a->width * a->height;
for (idx=0; idx<nbiter; idx++) {
if (a->R[idx] > b->R[idx]) d->R[idx] = a->R[idx];
else d->R[idx] = b->R[idx];
if (a->G[idx] > b->G[idx]) d->G[idx] = a->G[idx];
else d->G[idx] = b->G[idx];
if (a->B[idx] > b->B[idx]) d->B[idx] = a->B[idx];
else d->B[idx] = b->B[idx];
}
return 0;
}
/* ---------------------------------------------------------------- */
int fimg_maximum(FloatImg *a, FloatImg *b, FloatImg *d)
{
int idx, nbiter;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %p )\n", __func__, a, b, d);
#endif
if (FIMG_TYPE_RGB != a->type || FIMG_TYPE_RGB != b->type ||
FIMG_TYPE_RGB != d->type) {
fprintf(stderr, "%s : got a bad type fimg\n", __func__);
return -8;
}
nbiter = a->width * a->height ;
for (idx=0; idx<nbiter; idx++) {
if (a->R[idx] < b->R[idx]) d->R[idx] = a->R[idx];
else d->R[idx] = b->R[idx];
if (a->G[idx] < b->G[idx]) d->G[idx] = a->G[idx];
else d->G[idx] = b->G[idx];
if (a->B[idx] < b->B[idx]) d->B[idx] = a->B[idx];
else d->B[idx] = b->B[idx];
}
return 0;
}
/* ---------------------------------------------------------------- */

32
src/lib/runme.sh Executable file
View File

@@ -0,0 +1,32 @@
#!/bin/bash
../v4l2/grabvidseq -s 960x720 -n 100 -p 0.193 \
-vv -c none \
-o original.fimg
make t && ./t
../tools/fimgops original.fimg cos_01.fimg mini minimum.fimg
../tools/fimgops original.fimg cos_01.fimg maxi maximum.fimg
for picz in original power2 squareroot cos_01 minimum maximum
do
echo _______________________ ${picz}
# ../tools/fimgstats -v ${picz}.fimg
../tools/fimg2pnm ${picz}.fimg ${picz}.pnm
convert -pointsize 48 \
-fill black -annotate +14+40 "${picz}" \
-fill white -annotate +16+42 "${picz}" \
${picz}.pnm ${picz}.png
rm ${picz}.pnm
done
convert -delay 150 *.png foo.gif

273
src/lib/t.c Normal file
View File

@@ -0,0 +1,273 @@
/*
* programme de test pour
* les fonctions de base.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
#include "../floatimg.h"
int verbosity;
/* ---------------------------------------------------------------- */
int essai_timer(int uuuh)
{
double A, B;
fprintf(stderr, ">>> %s ( %d )\n", __func__, uuuh);
A = fimg_timer_set(uuuh);
sleep(4);
B = fimg_timer_get(uuuh);
fprintf(stderr, " %f %f\n", A, B);
return 0;
}
/* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- */
#define WI 1024
#define HI 768
#define KDEG 3.141592654 /* secret magic number */
int essai_interpolate(int k)
{
FloatImg A, B, C;
int foo, idx;
char ligne[200];
float fval, minmax[6];
foo = fimg_create(&A, WI, HI, FIMG_TYPE_RGB);
if (foo) {
fprintf(stderr, "%s err create A %d\n", __func__, foo);
return foo;
}
fimg_hdeg_a(&A, KDEG);
foo = fimg_create(&B, WI, HI, FIMG_TYPE_RGB);
if (foo) {
fprintf(stderr, "%s err create B %d\n", __func__, foo);
return foo;
}
fimg_vdeg_a(&B, KDEG);
foo = fimg_create(&C, WI, HI, FIMG_TYPE_RGB);
if (foo) {
fprintf(stderr, "%s err create C %d\n", __func__, foo);
return foo;
}
#define NB 16
for (idx=0; idx<NB; idx++) {
fval = (float)idx / (float)NB;
if (verbosity) fprintf(stderr, "%4d %f\n", idx, fval);
foo = fimg_interpolate(&A, &B, &C, fval);
if (foo) {
fprintf(stderr, "%s err interpolate %d\n", __func__, foo);
return foo;
}
sprintf(ligne, "polate-%02d.pnm", idx);
foo = fimg_save_as_pnm(&C, ligne, 0);
}
/*
$ convert -delay 10 polate-* foo.gif ; animate foo.gif
*/
fimg_destroy(&A); fimg_destroy(&B); fimg_destroy(&C);
return 0;
}
/* ---------------------------------------------------------------- */
int essai_2gray(FloatImg *picz, char *outname)
{
int foo;
FloatImg gray;
fprintf(stderr, ">>> %s ( %p '%s' )\n", __func__, picz, outname);
foo = fimg_create(&gray, picz->width, picz->height, FIMG_TYPE_GRAY);
if (foo) {
fprintf(stderr, "%s : err %d on fimg create\n", __func__, foo);
exit(1);
}
foo = fimg_mk_gray_from(picz, &gray, 0);
if (foo) {
fprintf(stderr, "%s : err %d on fimg mk_gray_from\n", __func__, foo);
exit(1);
}
foo = fimg_save_as_pnm(&gray, outname, 0);
if (foo) {
fprintf(stderr, "%s : err %d on save_as_pnm\n", __func__, foo);
exit(1);
}
fimg_destroy(&gray);
return 0;
}
/* ---------------------------------------------------------------- */
#define TAILLE 1024
int essai_clone_et_copy(int unused)
{
FloatImg A, B, C;
int foo;
fprintf(stderr, "-------- %s ( %d ) --------\n", __func__, unused);
foo = fimg_create(&A, TAILLE, TAILLE, FIMG_TYPE_RGB);
if (foo) {
fprintf(stderr, "%s err create A %d\n", __func__, foo);
return foo;
}
foo = fimg_draw_something(&A);
if (foo) {
fprintf(stderr, "%s err drawing A %d\n", __func__, foo);
return foo;
}
foo = fimg_save_as_pnm(&A, "A.pnm", 0);
if (foo) {
fprintf(stderr, "%s : err %d on save_as_pnm\n", __func__, foo);
exit(1);
}
foo = fimg_clone(&A, &B, 1);
if (foo) {
fprintf(stderr, "%s err clone B %d\n", __func__, foo);
return foo;
}
foo = fimg_create(&C, TAILLE, TAILLE, FIMG_TYPE_RGB);
if (foo) {
fprintf(stderr, "%s err create A %d\n", __func__, foo);
return foo;
}
foo = fimg_copy_data(&A, &C);
if (foo) {
fprintf(stderr, "%s err copydata %d\n", __func__, foo);
return foo;
}
foo = fimg_save_as_pnm(&C, "C.pnm", 0);
fimg_destroy(&A); fimg_destroy(&B); fimg_destroy(&C);
return 0;
}
#undef TAILLE
/* ---------------------------------------------------------------- */
int essai_get_values(char *fname)
{
int foo;
FloatImg dessin;
float vals[6];
foo = fimg_create_from_dump(fname, &dessin);
if (foo) {
fprintf(stderr, "in %s, error %d loading '%s'\n",
__func__, foo, fname);
return foo;
}
foo = fimg_get_minmax_rgb(&dessin, vals);
if (foo) {
fprintf(stderr, "%s: err %d on fimg_get_minmax_rgb\n",
__func__, foo);
return foo;
}
for (foo=0; foo<6; foo++) {
fprintf(stderr, "%7d %17.6g\n", foo, vals[foo]);
}
return -1;
}
/* ---------------------------------------------------------------- */
int essai_contraste(char *fname)
{
int foo;
FloatImg dessin, copy;
double maxi;
fprintf(stderr, "-------- %s ( '%s' ) --------\n", __func__, fname);
foo = fimg_create_from_dump(fname, &dessin);
if (foo) {
fprintf(stderr, "in %s, error %d loading '%s'\n",
__func__, foo, fname);
return foo;
}
foo = fimg_clone(&dessin, &copy, 0);
fimg_save_as_pnm(&dessin, "dessin.pnm", 0);
maxi = (double)fimg_get_maxvalue(&dessin);
fprintf(stderr, "image source valeur maxi = %f\n", maxi);
fimg_power_2(&dessin, &copy, maxi);
maxi = (double)fimg_get_maxvalue(&copy);
fprintf(stderr, "apres power_2 valeur maxi = %f\n", maxi);
fimg_save_as_pnm(&copy, "power2.pnm", 0);
fimg_square_root(&dessin, &copy, maxi);
maxi = (double)fimg_get_maxvalue(&copy);
fprintf(stderr, "apres square_root valeur maxi = %f\n", maxi);
fimg_save_as_pnm(&copy, "squareroot.pnm", 0);
fimg_cos_01(&dessin, &copy, maxi);
maxi = (double)fimg_get_maxvalue(&copy);
fprintf(stderr, "apres cos 01 valeur maxi = %f\n", maxi);
fimg_save_as_pnm(&copy, "cos_01.pnm", 0);
fimg_cos_010(&dessin, &copy, maxi);
maxi = (double)fimg_get_maxvalue(&copy);
fprintf(stderr, "apres cos 010 valeur maxi = %f\n", maxi);
fimg_save_as_pnm(&copy, "cos_010.pnm", 0);
fimg_destroy(&dessin); fimg_destroy(&copy);
return 0;
}
/* ---------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo, opt;
// char outname[100];
int gray = 0;
while ((opt = getopt(argc, argv, "gn:v")) != -1) {
switch(opt) {
case 'g': gray++; break;
case 'n': foo=atoi(optarg); break;
case 'v': verbosity++; break;
default:
fprintf(stderr, "%s: oh, %c is a bad opt.\n",
argv[0], opt);
exit(5);
}
}
if (verbosity) {
fimg_print_version(1);
fimg_print_sizeof();
}
foo = essai_contraste("quux.fimg");
fprintf(stderr, "retour essai contraste -> %d\n", foo);
// foo = essai_clone_et_copy(0);
// fprintf(stderr, "retour essai clone'n'copy -> %d\n", foo);
// foo = essai_timer(0);
// fprintf(stderr, "retour essai timer -> %d\n", foo);
return 0;
}

81
src/tools/Makefile Normal file
View File

@@ -0,0 +1,81 @@
#
# makefile for floatimg tools
# use with caution
#
# PLEASE ! update to the 'Global.makefile' concept !
#
COPT = -Wall -fpic -g -DDEBUG_LEVEL=0
LD_OPTS = -lm
STATIC_LIB = ../../build/lib/libfloatimg.a
DEPS = ../floatimg.h $(STATIC_LIB) Makefile
BIN_DIR = ../../build/bin
EXECUTABLES = $(BIN_DIR)/fimg2pnm $(BIN_DIR)/mkfimg $(BIN_DIR)/png2fimg \
$(BIN_DIR)/fimgstats $(BIN_DIR)/fimg2png $(BIN_DIR)/fimg2tiff \
$(BIN_DIR)/fimg2text $(BIN_DIR)/fimg2fits $(BIN_DIR)/addpnm2fimg \
$(BIN_DIR)/cumulfimgs $(BIN_DIR)/fimgops $(BIN_DIR)/fimgfx \
$(BIN_DIR)/fimghalfsize
# ----------
all: fimg2pnm mkfimg png2fimg fimgstats fimg2png \
fimg2tiff fimg2text fimg2fits \
addpnm2fimg cumulfimgs fimgops fimgfx \
fimghalfsize
clean:
rm -rf $(EXECUTABLES)
fimgstats: fimgstats.c $(DEPS)
gcc $(COPT) $< $(STATIC_LIB) -o $(BIN_DIR)/$@ $(LD_OPTS)
cumulfimgs: cumulfimgs.c $(DEPS)
gcc $(COPT) $< $(STATIC_LIB) -o $(BIN_DIR)/$@ $(LD_OPTS)
mkfimg: mkfimg.c $(DEPS)
gcc $(COPT) $< $(STATIC_LIB) -o $(BIN_DIR)/$@ $(LD_OPTS)
fimgops: fimgops.c $(DEPS)
gcc $(COPT) $< $(STATIC_LIB) -o $(BIN_DIR)/$@ $(LD_OPTS)
fimgfx: fimgfx.c $(DEPS)
gcc $(COPT) $< $(STATIC_LIB) -o $(BIN_DIR)/$@ $(LD_OPTS)
fimghalfsize: fimghalfsize.c $(DEPS)
gcc $(COPT) $< $(STATIC_LIB) -o $(BIN_DIR)/$@ $(LD_OPTS)
fimg2pnm: fimg2pnm.c $(DEPS)
gcc $(COPT) $< $(STATIC_LIB) -o $(BIN_DIR)/$@ $(LD_OPTS)
fimg2fits: fimg2fits.c $(DEPS)
gcc $(COPT) $< $(STATIC_LIB) -lcfitsio -o $(BIN_DIR)/$@ $(LD_OPTS)
fimg2png: fimg2png.c $(DEPS)
gcc $(COPT) $< $(STATIC_LIB) -lpnglite -lz -o $(BIN_DIR)/$@ $(LD_OPTS)
fimg2text: fimg2text.c $(DEPS)
gcc $(COPT) $< $(STATIC_LIB) -o $(BIN_DIR)/$@ $(LD_OPTS)
fimg2tiff: fimg2tiff.c $(DEPS)
gcc $(COPT) $< $(STATIC_LIB) -ltiff -o $(BIN_DIR)/$@ $(LD_OPTS)
#
# this tool require an external library
# http://la.buvette.org/devel/libimage/libimage.html
#
addtga2fimg: addtga2fimg.c $(DEPS)
gcc $(COPT) $< $(STATIC_LIB) -limageSO -o $(BIN_DIR)/$@ $(LD_OPTS)
addpnm2fimg: addpnm2fimg.c $(DEPS)
gcc $(COPT) $< $(STATIC_LIB) -o $(BIN_DIR)/$@ $(LD_OPTS)
# if "undefined reference to crc32" then "use -lz"
png2fimg: png2fimg.c $(DEPS)
gcc $(COPT) $< $(STATIC_LIB) -lpnglite -lz -o $(BIN_DIR)/$@ $(LD_OPTS)

20
src/tools/README.md Normal file
View File

@@ -0,0 +1,20 @@
# Images en virgule flottante, les outils.
Dans tous les cas, vous pouvez utiliser l'option `-h` pour avoir des
explications sur ce que vous pouvez faire.
## mkfimg
## fimgops
## fimgfx
## fimgstats
## fimg2pnm - fimg2png
## fimg2text
Nouveau de l'année 2020+1 : exfiltrer toutes des données d'une image flottante
afin de les rendre machinables.

90
src/tools/addpnm2fimg.c Normal file
View File

@@ -0,0 +1,90 @@
/*
* ADDPNM
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "../floatimg.h"
int verbosity;
/* --------------------------------------------------------------------- */
int add_pnm_to_fimg(char *srcname, char *dstname, int notused)
{
FloatImg dst, src;
int foo, x, y, idx;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' %s' )\n", __func__, srcname, dstname);
#endif
foo = fimg_create_from_dump(dstname, &dst);
if (foo) fprintf(stderr, "create dst fimg from '%s' -> %d\n", dstname, foo);
#if DEBUG_LEVEL
fimg_describe(&dst, "created fimg from dump");
#endif
foo = fimg_load_from_pnm(srcname, &src, 0);
if (foo) fprintf(stderr, "create src fimg from '%s' -> %d\n", dstname, foo);
#if DEBUG_LEVEL
fimg_describe(&src, "created fimg from PNM");
#endif
// fprintf(stderr, "src is %dx%d\n", src.width, src.height);
idx = 0;
for (y=0; y<src.height; y++) {
for (x=0; x<src.width; x++) {
dst.R[idx] += src.R[idx];
dst.G[idx] += src.G[idx];
dst.B[idx] += src.B[idx];
idx++;
}
}
foo = fimg_dump_to_file(&dst, dstname, 0);
if (foo) { fprintf(stderr, "fimg dump -> %d\n", foo); }
return 0;
}
/* --------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo;
// int srcW, srcH;
int infos[3];
if (3 != argc) {
fimg_print_version(1);
fprintf(stderr, "usage:\n\t%s img.fimg cumul.fimg\n", argv[0]);
exit(1);
}
verbosity = 0;
if ( 0==access(argv[2], R_OK|W_OK) ) { /* fimg is readable */
// fprintf(stderr, "%s exist\n", argv[2]);
}
/*
else {
fprintf(stderr, "*** must create '%s' %dx%d first !!!\n",
argv[2], tgaW, tgaH);
exit(1);
} */
foo = fimg_fileinfos(argv[2], infos);
// fprintf(stderr, "get dims of '%s' -> %d\n", argv[2], foo);
if (foo) {
fprintf(stderr, "*** %s is badly broken\n", argv[2]);
exit(2);
}
foo = add_pnm_to_fimg(argv[1], argv[2], 0);
return 0;
}
/* --------------------------------------------------------------------- */

99
src/tools/addtga2fimg.c Normal file
View File

@@ -0,0 +1,99 @@
/*
* ADDTGA
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <tthimage.h>
#include "../floatimg.h"
/* --------------------------------------------------------------------- */
int add_tga_to_fimg(char *srcname, char *dstname, int notused)
{
Image_Desc *src;
FloatImg dst;
int foo, x, y;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' %s' )\n", __func__, srcname, dstname);
#endif
if (NULL==(src = Image_TGA_alloc_load(srcname))) {
return -2;
}
foo = fimg_create_from_dump(dstname, &dst);
if (foo) fprintf(stderr, "create fimg from '%s' -> %d\n", dstname, foo);
#if DEBUG_LEVEL
fimg_describe(&dst, "created fimg");
#endif
for (y=0; y<src->height; y++) {
for (x=0; x<src->width; x++) {
foo = fimg_add_rgb(&dst, x, y,
(float)Image_R_pixel(src, x, y),
(float)Image_G_pixel(src, x, y),
(float)Image_B_pixel(src, x, y));
}
}
foo = fimg_dump_to_file(&dst, dstname, 0);
if (foo) { fprintf(stderr, "fimg dump -> %d\n", foo); }
return 0;
}
/* --------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo;
int tgaW, tgaH;
int infos[3];
if (3 != argc) {
fimg_print_version(1);
fprintf(stderr, "usage:\n\t%s img.tga cumul.fimg\n", argv[0]);
exit(1);
}
/* first, check the TGA file dimensions */
// Image_print_version(0);
foo = Image_TGA_get_dims(argv[1], &tgaW, &tgaH);
if (foo) {
fprintf(stderr, "get dims of '%s' -> %d\n", argv[1], foo);
Image_print_error("tga get dims", foo);
exit(1);
}
if ( 0==access(argv[2], R_OK) ) { /* fimg is readable */
fprintf(stderr, "%s is ok.\n", argv[2]);
}
else {
fprintf(stderr, "*** must create '%s' %dx%d first !!!\n",
argv[2], tgaW, tgaH);
exit(1);
}
foo = fimg_fileinfos(argv[2], infos);
// fprintf(stderr, "get dims of '%s' -> %d\n", argv[2], foo);
if (foo) {
fprintf(stderr, "*** %s is badly broken\n", argv[2]);
exit(2);
}
if ( (tgaW != infos[0]) || (tgaW != infos[0]) ) {
fprintf(stderr, " TGA %5d %5d\n", tgaW, tgaH);
fprintf(stderr, " FIMG %5d %5d\n", infos[0], infos[1]);
fprintf(stderr, " No dimension match.\n");
exit(3);
}
foo = add_tga_to_fimg(argv[1], argv[2], 0);
return 0;
}
/* --------------------------------------------------------------------- */

134
src/tools/cumulfimgs.c Normal file
View File

@@ -0,0 +1,134 @@
/*
* This thing is just a mess !
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "../floatimg.h"
int verbosity;
int g_width, g_height;
/* --------------------------------------------------------------------- */
int testfile(char *path)
{
int foo, numbers[3];
foo = fimg_fileinfos(path, numbers);
if (foo) {
fprintf(stderr, "fileinfo of '%s' -> err %d\n", path, foo);
return foo;
}
if (verbosity) {
fprintf(stderr, "%-20s %dx%d\n", path, numbers[0], numbers[1]);
}
if (FIMG_TYPE_RGB != numbers[2]) {
fprintf(stderr, "file %s, %d : bad type\n", path, numbers[2]);
return -7;
}
return 0;
}
/* --------------------------------------------------------------------- */
void help(int v)
{
puts("");
puts("$ cumulfimgs a.fimg b.fimg c-fimg ...");
puts("cumulator options :");
puts("\t-v\tincrease verbosity");
puts("\t-o\tname of output file");
puts("\t-g\tconvert to gray level");
puts("");
if (verbosity) { puts(""); fimg_print_version(1); }
exit(0);
}
/* --------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo, idx;
int opt;
int compte = 0;
int to_gray = 0;
char *output_file = "out.fimg";
FloatImg accu, temp;
int src_loaded = 0;
float vals[6];
g_width = g_height = 0;
while ((opt = getopt(argc, argv, "gho:v")) != -1) {
switch(opt) {
case 'g': to_gray = 1; break;
case 'h': help(0); break;
case 'o': output_file = optarg; break;
case 'v': verbosity++; break;
}
}
if (verbosity) fprintf(stderr, "------ cumulfimgs ------\n");
#if DEBUG_LEVEL
fprintf(stderr, "argc = %d, optind = %d\n", argc, optind);
#endif
for (idx=optind; idx<argc; idx++) {
#if DEBUG_LEVEL
fprintf(stderr, "%5d %s\n", idx, argv[idx]);
#endif
foo = testfile(argv[idx]);
if (foo) {
fprintf(stderr, "testfile %s -> %d\n", argv[idx],foo);
exit(1);
}
if ( ! src_loaded ) {
foo = fimg_create_from_dump(argv[idx], &accu);
fimg_clone(&accu, &temp, 0);
src_loaded = 1;
}
else {
foo = fimg_load_from_dump(argv[idx], &temp);
if (foo) {
fprintf(stderr, "load from dump -> %d\n", foo);
exit(1);
}
fimg_add_2(&temp, &accu);
}
compte++;
}
if (to_gray) {
foo = fimg_desaturate(&accu, &accu, 0);
if (foo) {
fprintf(stderr, "desaturate: error %d\n", foo);
}
}
foo = fimg_dump_to_file(&accu, output_file, 0);
if (foo) {
fprintf(stderr, "error %d while saving '%s'\n", foo, output_file);
exit(1);
}
if (verbosity) {
/* show some numbers about resultant picture */
foo = fimg_get_minmax_rgb(&accu, vals);
if (foo) {
fprintf(stderr, "err %d on fimg_get_minmax_rgb\n", foo);
return foo;
}
printf("Count %d\n", compte);
printf("Rmin %12.4g Rmax %12.4g delta %12g\n",
vals[0], vals[1], vals[1]-vals[0]);
printf("Gmin %12.4g Gmax %12.4g %12g\n",
vals[2], vals[3], vals[3]-vals[2]);
printf("Bmin %12.4g Bmax %12.4g %12g\n",
vals[4], vals[5], vals[5]-vals[4]);
}
return 0;
}
/* --------------------------------------------------------------------- */

66
src/tools/fimg2fits.c Normal file
View File

@@ -0,0 +1,66 @@
/*
* exporting a floatimg to a FITS file
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "../floatimg.h"
int verbosity;
/* ----------------------------------------------------------------- */
int export_fimg_plane_as_fits(char *infile, char *outfile, char plane)
{
FloatImg fimg;
int foo;
foo = fimg_create_from_dump(infile, &fimg);
if (foo) {
fprintf(stderr, "%s: create fimg from '%s' -> %d\n", __func__,
infile, foo);
return -1;
}
foo = fimg_save_plane_as_fits(&fimg, outfile, plane, 0);
if (foo) {
fprintf(stderr, "%s: err %d on fits export\n", __func__, foo);
return foo;
}
fimg_destroy(&fimg);
return -1;
}
/* ----------------------------------------------------------------- */
static void help(int k)
{
puts("export to FITS format");
puts("\t-p select colorplane : R, G, B");
}
/* ----------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo, opt;
int plane = '?';
while ((opt = getopt(argc, argv, "p:hv")) != -1) {
switch(opt) {
case 'p': plane = optarg[0]; break;
case 'v': verbosity++; break;
case 'h': help(1); exit(1);
}
}
if (2 != argc-optind) {
fprintf(stderr, "error: %s need two filenames\n", argv[0]);
exit(1);
}
export_fimg_plane_as_fits(argv[optind], argv[optind+1], plane);
return 0;
}
/* ----------------------------------------------------------------- */

98
src/tools/fimg2png.c Normal file
View File

@@ -0,0 +1,98 @@
/*
* converting a floatimg to a PNG
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "../floatimg.h"
int verbosity;
/* ----------------------------------------------------------------- */
int convertir_fimg_en_PNG(char *srcname, char *dstname, int grisaille)
{
int foo, infos[3];
FloatImg fimg;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %25s ( '%s' '%s' %d )\n", __func__,
srcname, dstname, notused);
#endif
foo = fimg_fileinfos(srcname, infos);
if (foo) {
if (verbosity) fprintf(stderr, "'%s' get dims -> %d\n", srcname, foo);
return foo;
}
if (verbosity) {
fprintf(stderr, "%s: image '%s' is %dx%d %s\n",
__func__,
srcname, infos[0], infos[1],
fimg_str_type(infos[2]));
}
foo = fimg_create_from_dump(srcname, &fimg);
if (foo) {
fprintf(stderr, "create fimg from '%s' -> %d\n", srcname, foo);
return -1;
}
if (grisaille) {
foo = fimg_desaturate(&fimg, &fimg, 0);
}
foo = fimg_save_as_png(&fimg, dstname, 0);
if (foo) {
fprintf(stderr, "%s: saving as png '%s' -> %d\n", __func__,
dstname, foo);
return -1;
}
fimg_destroy(&fimg);
return 0;
}
/* ----------------------------------------------------------------- */
void help(int k)
{
puts("usage:\n\tfimg2png [options] foo.fimg bar.png");
puts("options:");
puts("\t-g\tconvert to gray");
puts("\t-v\tincrease verbosity");
if (verbosity) fimg_print_version(1);
exit(0);
}
/* ----------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo, opt;
int to_gray = 0;
while ((opt = getopt(argc, argv, "ghv")) != -1) {
switch(opt) {
case 'g': to_gray = 1; break;
case 'v': verbosity++; break;
case 'h': help(1); exit(1);
}
}
if (2 != argc-optind) {
fprintf(stderr, "error: %s need two filenames\n", argv[0]);
exit(1);
}
foo = convertir_fimg_en_PNG(argv[optind], argv[optind+1], to_gray);
if (foo) {
fprintf(stderr, "%s : got a %d from convertor\n", argv[0], foo);
}
return 0;
}
/* ----------------------------------------------------------------- */

126
src/tools/fimg2pnm.c Normal file
View File

@@ -0,0 +1,126 @@
/*
* conversion vers le format PNM
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "../floatimg.h"
int verbosity;
/* --------------------------------------------------------------------- */
int convertir_fimg_en_pnm(char *srcname, char *dstname, int to_gray)
{
int foo, infos[3];
FloatImg fimg, gris, *outptr;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %25s ( '%s' '%s' %d )\n", __func__,
srcname, dstname, to_gray);
#endif
foo = fimg_fileinfos(srcname, infos);
if (foo) { fprintf(stderr, "'%s' get dims -> %d\n", srcname, foo); }
if (verbosity) {
fprintf(stderr, "image '%s' is %d x %d %s\n",
srcname, infos[0], infos[1],
fimg_str_type(infos[2]));
}
foo = fimg_create_from_dump(srcname, &fimg);
if (foo) {
fprintf(stderr, "create fimg from '%s' -> %d\n", srcname, foo);
return -1;
}
outptr = &fimg; /* safe default value */
if (to_gray) {
if (verbosity) puts("converting to gray...");
foo = fimg_create(&gris, fimg.width, fimg.height, FIMG_TYPE_GRAY);
if (foo) {
fprintf(stderr, "err create gray %d\n", foo);
return -2;
}
foo = fimg_mk_gray_from(&fimg, &gris, 0);
if (foo) {
fprintf(stderr, "err mk gray %d\n", foo);
return -4;
}
outptr = &gris;
}
#if DEBUG_LEVEL > 1
print_floatimg(outptr, "created fimg");
#endif
foo = fimg_save_as_pnm(outptr, dstname, 0);
if(foo) { fprintf(stderr, "%p to '%s' -> %d\n", &fimg, dstname, foo); }
if (to_gray) {
fimg_destroy(&gris);
outptr = NULL;
/* please run valgrind every hour */
}
return 0;
}
/* --------------------------------------------------------------------- */
static void help(int flag)
{
if (flag) {
fprintf(stderr, "conversion FIMG -> PNM 16 bits\n");
fimg_print_version(1);
}
puts("usage :");
puts("\tfimg2pnm [flags] infile.fimg outfile.pnm");
puts("flags :");
puts("\t-g\tconvert to gray");
puts("\t-v\tenhance your verbosity");
}
/* --------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo, opt;
int to_gray = 0;
if (argc == 1) {
help(0);
exit(0);
}
while ((opt = getopt(argc, argv, "ghv")) != -1) {
switch(opt) {
case 'g': to_gray = 1; break;
case 'v': verbosity++; break;
case 'h': help(1); exit(1);
}
}
#if DEBUG_LEVEL
/* mmmm, is it the good way ? */
printf("argc %d -> %d\n", argc, argc-optind);
for (foo=optind; foo<argc; foo++) {
printf(" %d %s\n", foo, argv[foo]);
}
#endif
if (2 != argc-optind) {
fprintf(stderr, "error: %s need two filenames\n", argv[0]);
exit(1);
}
if ( 0 != access(argv[optind], R_OK) ) { /* fimg is NOT readable */
fprintf(stderr, "%s: %s don't exist.\n", argv[0], argv[optind]);
exit(2);
}
foo = convertir_fimg_en_pnm(argv[optind], argv[optind+1], to_gray);
if (foo) fprintf(stderr, "conversion -> %d\n", foo);
return 0;
}
/* --------------------------------------------------------------------- */

178
src/tools/fimg2text.c Normal file
View File

@@ -0,0 +1,178 @@
/*
* converting a floatimg to a machinable text file
* an ugly software from tTh - february 2021
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "../floatimg.h"
int verbosity;
/* --------------------------------------------------------------------- */
int export_as_machinable(FloatImg *src, char *fname, int steps, int flags)
{
FILE *fp;
int x, y;
float rgb[3];
#if DEBUG_LEVEL
fprintf(stderr, ">>> %25s ( %p '%s' %d )\n", __func__,
src, fname, flags);
#endif
fp = NULL; /* molly guard */
if (strcmp("-", fname)) { /* real file */
fprintf(stderr, "real file '%s'\n", fname);
}
else {
// fprintf(stderr, "kitchen sink\n");
}
fp = stdout; /* XXX */
for (y=0; y<src->height; y+=steps) {
for (x=0; x<src->width; x+=steps) {
fimg_get_rgb(src, x, y, rgb);
fprintf(fp, "%d %d ", x, y);
fprintf(fp, "%f %f %f\n", rgb[0], rgb[1], rgb[2]);
}
}
return 0;
}
/* --------------------------------------------------------------------- */
static int normalize(FloatImg *pimg, float vmax)
{
float mmv[6], maxi, coef;
int foo, sz, idx;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %g )\n", __func__, pimg, vmax);
#endif
foo = fimg_get_minmax_rgb(pimg, mmv);
if (foo) {
fprintf(stderr, "%s: ABEND\n", __func__);
abort();
}
maxi = mmv[1];
if (mmv[3] > maxi) maxi = mmv[3];
if (mmv[5] > maxi) maxi = mmv[5];
coef = vmax / maxi;
if (verbosity) {
fprintf(stderr, "mins %f %f %f\n", mmv[0], mmv[2], mmv[4]);
fprintf(stderr, "maxs %f %f %f\n", mmv[1], mmv[3], mmv[5]);
fprintf(stderr, "coef = %f\n", coef);
}
sz = pimg->width * pimg->height;
for (idx=0; idx<sz; idx++) {
pimg->R[idx] *= coef;
pimg->G[idx] *= coef;
pimg->B[idx] *= coef;
}
return 0;
}
/* --------------------------------------------------------------------- */
int convertir_fimg_en_machinable(char *srcname, char *dstname,
int steps, float norm)
{
int foo, infos[3];
FloatImg fimg;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %25s ( '%s' '%s' %d )\n", __func__,
srcname, dstname, notused);
#endif
if (steps < 1) {
fprintf(stderr, "%s: steps MUST be > 0\n", __func__);
exit(1);
}
foo = fimg_fileinfos(srcname, infos);
if (foo) {
fprintf(stderr, "'%s' get dims -> %d\n", srcname, foo);
return foo;
}
if (verbosity) {
fprintf(stderr, "%s: image '%s' is %d x %d %s\n",
__func__,
srcname, infos[0], infos[1],
fimg_str_type(infos[2]));
}
foo = fimg_create_from_dump(srcname, &fimg);
if (foo) {
fprintf(stderr, "create fimg from '%s' -> %d\n", srcname, foo);
return -1;
}
if (verbosity) {
fimg_describe(&fimg, srcname);
fprintf(stderr, "normalize to %f\n", norm);
}
if (norm > 0.0) {
// fprintf(stderr, "normalize %p\n", &fimg);
foo = normalize(&fimg, norm);
}
foo = export_as_machinable(&fimg, dstname, steps, 0);
if (foo) {
fprintf(stderr,"%s: err %d on export\n", __func__, foo);
}
fimg_destroy(&fimg);
return 0;
}
/* --------------------------------------------------------------------- */
void help(int k)
{
puts("usage:\n\tfimg2text [options] foo.fimg > bar.csv");
puts("options:");
puts("\t-v\t\tincrease verbosity");
puts("\t-n 3.14\t\tnormalize picture");
puts("\t-s N\t\tsteps on x & y");
if (verbosity) fimg_print_version(1);
exit(0);
}
/* --------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo, opt;
int steps = 1;
float norm_val = 222.0; /* < 0 : don't normalize */
char separator = ' ';
while ((opt = getopt(argc, argv, "f:hn:s:v")) != -1) {
switch(opt) {
case 'f': separator = optarg[0]; break;
case 'v': verbosity++; break;
case 'h': help(1); exit(1);
case 's': steps = atoi(optarg); break;
case 'n': norm_val = atof(optarg); break;
}
}
if (1 != argc-optind) {
fprintf(stderr, "error: %s need one intput filename\n", argv[0]);
exit(1);
}
foo = convertir_fimg_en_machinable(argv[optind], "-", steps, norm_val);
if (foo) {
fprintf(stderr, "%s : got a %d from convertor\n", argv[0], foo);
return 1;
}
return 0;
}
/* --------------------------------------------------------------------- */

98
src/tools/fimg2tiff.c Normal file
View File

@@ -0,0 +1,98 @@
/*
* converting a floatimg to a TIFF
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "../floatimg.h"
int verbosity;
/* ----------------------------------------------------------------- */
int convertir_fimg_en_TIFF(char *srcname, char *dstname, int grisaille)
{
int foo, infos[3];
FloatImg fimg;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %25s ( '%s' '%s' %d )\n", __func__,
srcname, dstname, notused);
#endif
foo = fimg_fileinfos(srcname, infos);
if (foo) {
if (verbosity) fprintf(stderr, "'%s' get dims -> %d\n",
srcname, foo);
return foo;
}
if (verbosity) {
fprintf(stderr, "%s: image '%s' is %d x %d %s\n",
__func__,
srcname, infos[0], infos[1],
fimg_str_type(infos[2]));
}
foo = fimg_create_from_dump(srcname, &fimg);
if (foo) {
fprintf(stderr, "create fimg from '%s' -> %d\n", srcname, foo);
return -1;
}
if (grisaille) {
foo = fimg_desaturate(&fimg, &fimg, 0);
}
foo = fimg_write_as_tiff(&fimg, dstname, 0);
if (foo) {
fprintf(stderr, "%s: saving as tiff '%s' -> %d\n", __func__,
dstname, foo);
return -1;
}
fimg_destroy(&fimg);
return 0;
}
/* ----------------------------------------------------------------- */
void help(int k)
{
puts("usage:\n\tfimg2tiff [options] foo.fimg bar.tiff");
puts("options:");
// puts("\t-g\tconvert to gray");
puts("\t-v\tincrease verbosity");
if (verbosity) fimg_print_version(1);
exit(0);
}
/* ----------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo, opt;
int to_gray = 0;
while ((opt = getopt(argc, argv, "ghv")) != -1) {
switch(opt) {
case 'g': to_gray = 1; break;
case 'v': verbosity++; break;
case 'h': help(1); exit(1);
}
}
if (2 != argc-optind) {
fprintf(stderr, "error: %s need two filenames\n", argv[0]);
exit(1);
}
foo = convertir_fimg_en_TIFF(argv[optind], argv[optind+1], to_gray);
if (foo)
fprintf(stderr, "%s : got a %d from convertor\n", argv[0], foo);
return 0;
}
/* ----------------------------------------------------------------- */

305
src/tools/fimgfx.c Normal file
View File

@@ -0,0 +1,305 @@
/*
FIMGFX
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "../floatimg.h"
/* --------------------------------------------------------------------- */
int verbosity;
float global_fvalue;
typedef struct {
char *name;
int id;
int nbarg;
int flags;
} Fx;
enum fxid { Fx_cos01=5, Fx_cos010, Fx_pow2, Fx_sqrt, Fx_gray0, Fx_halfsz0,
Fx_rot90, Fx_cmixa, Fx_desat, Fx_ctr2x2, Fx_norm,
Fx_classtrial, Fx_mirror, Fx_shift0,
Fx_xper, Fx_binarize, Fx_trinarize,Fx_hilight_R };
Fx fx_list[] = {
{ "cos01", Fx_cos01, 0, 1 },
{ "cos010", Fx_cos010, 0, 1 },
{ "pow2", Fx_pow2, 0, 1 },
{ "sqrt", Fx_sqrt, 0, 1 },
{ "gray0", Fx_gray0, 0, 1 },
// { "halfsz0", Fx_halfsz0, 0, 1 },
// { "rot90", Fx_rot90, 0, 0 },
{ "cmixa", Fx_cmixa, 0, 1 },
{ "xper", Fx_xper, 0, 1 },
{ "desat", Fx_desat, 0, 1 },
{ "ctr2x2", Fx_ctr2x2, 0, 1 },
{ "mirror", Fx_mirror, 0, 1 },
{ "shift0", Fx_shift0, 0, 1 },
// { "norm", Fx_norm, 0, 1 },
{ "classtrial", Fx_classtrial, 0, 1 },
{ "binarize", Fx_binarize, 0, 1 },
{ "trinarize", Fx_trinarize, 0, 1 },
{ "hilightr", Fx_hilight_R, 0, 1 },
{ NULL, 0, 0, 0 }
};
/* --------------------------------------------------------------------- */
static void list_of_effects(void)
{
Fx *fx;
for (fx=fx_list; fx->name; fx++) {
printf("%s\n", fx->name);
}
}
/* --------------------------------------------------------------------- */
int lookup_fxidx(char *txt)
{
Fx *fx;
int n;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' )\n", __func__, txt);
#endif
for (n=0, fx=fx_list; fx->name; fx++, n++) {
#if DEBUG_LEVEL > 1
fprintf(stderr, " -> %3d %s\n", n, fx->name);
#endif
if (!strcmp(fx->name, txt)) {
return n;
}
}
return -1; /* NOT FOUND */
}
/* --------------------------------------------------------------------- */
/*
* this is the mutant function
*/
int do_experiment(FloatImg *S, FloatImg *D, float kf)
{
int foo;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %f )\n", __func__, S, D, kf);
#endif
foo = fimg_classif_trial(S, D, kf, 0);
if (foo) {
fprintf(stderr, "%s err %d classif_trial %p\n", __func__,
foo, S);
return -98;
}
return 0;
}
/* --------------------------------------------------------------------- */
static void help(int lvl)
{
Fx *fx;
int foo;
printf("-- fimg special effects -- %s %s --\n", __DATE__, __TIME__);
puts("usage:");
puts("\tfimgfx [options] <effect> source.fimg resultat.fimg");
puts("options:");
puts("\t-k N.N\tset the floating value");
puts("\t-l\tlist effects");
puts("\t-v\tincrease verbosity");
puts("effects:");
printf("\t");
foo = 0;
for (fx=fx_list; fx->name; fx++) {
foo += printf("%s ", fx->name);
if (foo > 55) {
printf("\n\t");
foo = 0;
}
}
puts("");
fimg_print_version(1);
exit(0);
}
/* --------------------------------------------------------------------- */
int do_an_effect(char *srcfname, int fxidx, char *dstfname)
{
FloatImg src, dest;
int foo, action;
double maxval;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' %d '%s' )\n", __func__,
srcfname, action, dstfname);
#endif
foo = fimg_create_from_dump(srcfname, &src);
if (foo) {
fprintf(stderr, "err load '%s' : %d\n", srcfname, foo);
return foo;
}
maxval = (double)fimg_get_maxvalue(&src);
if (fx_list[fxidx].flags & 1) {
foo = fimg_clone(&src, &dest, 0);
if (foo) {
fprintf(stderr, "err clone %p : %d\n", &src, foo);
return foo;
}
}
else {
fprintf(stderr, "%s: ???\n", __func__); /* XXX */
memset(&dest, 0, sizeof(dest));
return -888;
}
action = fx_list[fxidx].id;
switch (action) {
case Fx_cos01:
fimg_cos_01(&src, &dest, maxval); break;
case Fx_cos010:
fimg_cos_010(&src, &dest, maxval); break;
case Fx_pow2:
fimg_power_2(&src, &dest, maxval); break;
case Fx_sqrt:
fimg_square_root(&src, &dest, maxval); break;
case Fx_gray0: /* new 2020 01 10 */
fimg_to_gray(&src); fimg_copy_data(&src, &dest);
break;
case Fx_xper:
do_experiment(&src, &dest, maxval); break;
case Fx_rot90:
foo = fimg_rotate_90(&src, &dest, 0); break;
case Fx_cmixa:
fimg_copy_data(&src, &dest);
foo = fimg_colors_mixer_a(&dest, 2.0); break;
case Fx_halfsz0:
fprintf(stderr, "halfsize was not implemented\n");
fprintf(stderr, "see 'fimghalfsize.c'. \n");
return -3;
case Fx_classtrial:
fprintf(stderr, "classif trial with %f fvalue\n",
global_fvalue);
foo = fimg_classif_trial(&src, &dest, global_fvalue, 0);
break;
case Fx_desat:
fimg_copy_data(&src, &dest);
foo = fimg_mix_rgb_gray(&dest, global_fvalue);
break;
case Fx_mirror:
foo = fimg_mirror(&src, &dest, 0);
break;
case Fx_shift0:
fprintf(stderr, "Krkrk %d\n", action);
foo = fimg_auto_shift_to_zero(&src, &dest);
break;
case Fx_ctr2x2:
foo = fimg_contour_2x2(&src, &dest, 0);
break;
case Fx_binarize:
fimg_copy_data(&src, &dest);
foo = fimg_binarize(&dest, 0);
break;
case Fx_trinarize:
fimg_copy_data(&src, &dest);
foo = fimg_trinarize(&dest, 0);
break;
case Fx_hilight_R:
foo = fimg_highlight_color(&src, &dest, 'R', 1.333);
break;
default:
fprintf(stderr, "%s %s : %d is bad action\n",
__FILE__, __func__, action);
break;
}
// foo = fimg_export_picture(&dest, dstfname, 0);
foo = fimg_dump_to_file(&dest, dstfname, 0);
if (foo) {
fprintf(stderr, "dumping datas to file '%s' give us a %d\n",
dstfname, foo);
return foo;
}
fimg_destroy(&src);
if (dest.type) {
fimg_destroy(&dest);
}
return 0;
}
/* --------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo, opt, action;
int nba;
char *operator;
char *srcname = "";
char *dstname = "out.fimg";
while ((opt = getopt(argc, argv, "hk:lv")) != -1) {
switch(opt) {
case 'h': help(0); break;
case 'k': global_fvalue = atof(optarg); break;
case 'l': list_of_effects(); exit(0);
case 'v': verbosity++; break;
}
}
#if DEBUG_LEVEL
fprintf(stderr, "argc %d optind %d\n", argc, optind);
for (foo=0; foo<argc; foo++)
fprintf(stderr, "%3d %c %s\n", foo, foo==optind?'*':' ', argv[foo]);
#endif
if (3 > argc-optind) {
fprintf(stderr, "%s need some arguments...\n", argv[0]);
exit(1);
}
if (verbosity>1) fprintf(stderr, "*** fimgfx *** %s %s\n", __DATE__, __TIME__);
operator = argv[optind];
action = lookup_fxidx(operator);
if (action < 0) {
fprintf(stderr, "garbage found in opcode field : %s\n", operator);
exit(1);
}
if (verbosity) {
fprintf(stderr, " global fvalue %f\n", global_fvalue);
fprintf(stderr, " action %d\n", action);
fprintf(stderr, " verbosity %d\n", verbosity);
}
if ((nba=fx_list[action].nbarg)) {
fprintf(stderr, "action '%s' need %d arg\n", operator, nba);
}
srcname = argv[optind+1];
dstname = argv[optind+2];
if (verbosity) fprintf(stderr, "%s ==> %s\n", srcname, dstname);
foo = do_an_effect(srcname, action, dstname);
if (foo) {
fprintf(stderr, "do an effect -> %d\n", foo);
}
return 0;
}
/* --------------------------------------------------------------------- */

95
src/tools/fimghalfsize.c Normal file
View File

@@ -0,0 +1,95 @@
/*
* halfsizing an fimg picture.
*/
#include <stdio.h>
#include <unistd.h> /* pour getopt */
#include <stdlib.h>
#include <string.h>
#include "../floatimg.h"
int verbosity;
/* ------------------------------------------------------------- */
int faire_un_halfsize(char *iname, char *oname, int to_gray)
{
FloatImg src, dst;
int foo;
foo = fimg_create_from_dump(iname, &src);
if (foo) {
fprintf(stderr, "create fimg from '%s' -> %d\n", iname, foo);
return -1;
}
memset(&dst, 0, sizeof(FloatImg));
foo = fimg_halfsize_1(&src, &dst, 0);
if (foo) {
fprintf(stderr, "halfize 1 fail -> %d\n", foo);
return -1;
}
if (to_gray) {
foo = fimg_to_gray(&dst);
/* and ? */
}
foo = fimg_dump_to_file(&dst, oname, 0);
if (foo) {
fprintf(stderr, "save to '%s' -> %d\n", oname, foo);
return -1;
}
return 0;
}
/* ------------------------------------------------------------- */
void help(int u)
{
puts("Usage:\n\tfimghalfsize [options] in.fimg out.fimg");
puts("Options:");
puts("\t-g\tconvert output to gray");
exit(0);
}
/* ------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo, opt;
char *srcname = "";
char *dstname = "out.fimg";
int grayed = 0;
while ((opt = getopt(argc, argv, "ghv")) != -1) {
switch(opt) {
case 'g': grayed = 1; break;
case 'h': help(0); break;
case 'v': verbosity++; break;
}
}
if (2 != argc-optind) {
fprintf(stderr, "error: %s need two filenames\n", argv[0]);
exit(1);
}
srcname = argv[optind];
dstname = argv[optind+1];
if (verbosity) {
fprintf(stderr, "%s: src: %s dst: %s\n", argv[0],
srcname, dstname);
}
foo = faire_un_halfsize(srcname, dstname, grayed);
if (foo) {
fprintf(stderr, "in %s: make halfsize give a %d\n", argv[0], foo);
exit(1);
}
return 0;
}
/* ------------------------------------------------------------- */

191
src/tools/fimgops.c Normal file
View File

@@ -0,0 +1,191 @@
/*
FIMGOPS
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "../floatimg.h"
int verbosity;
/* --------------------------------------------------------------------- */
float global_fvalue;
/* --------------------------------------------------------------------- */
#define OP_ADD 1
#define OP_SUB 2
#define OP_MIX 3
#define OP_MUL 4
#define OP_MINI 5
#define OP_MAXI 6
typedef struct {
int code;
char *op;
} Opcode;
Opcode opcodes[] = {
{ OP_ADD, "add" },
{ OP_SUB, "sub" },
{ OP_MIX, "mix" },
{ OP_MUL, "mul" },
{ OP_MINI, "mini" },
{ OP_MAXI, "maxi" },
{ 0, NULL }
};
static void pr_opcodes(void)
{
Opcode *optr;
puts("operators:");
for (optr = opcodes; optr->code; optr++) {
printf("\t%-15s %d\n", optr->op, optr->code);
}
}
static int look_opcode(char *txt)
{
Opcode *optr;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' )\n", __func__, txt);
#endif
for (optr = opcodes; optr->code; optr++) {
if (!strcmp(txt, optr->op)) {
// printf("found %s as %d\n", optr->op, optr->code);
return optr->code;
}
}
return -1;
}
/* --------------------------------------------------------------------- */
static void help(int lj)
{
puts("usage:\n\tfimgops [options] A.fimg B.fimg operator D.fimg");
puts("options:");
// puts("\t-g convert output to gray");
printf("\t-k N.N\t\tset float value (def=%.3f)\n", global_fvalue);
puts("\t-v\t\tincrease verbosity");
pr_opcodes();
if (verbosity) fimg_print_version(1);
exit(0);
}
/* --------------------------------------------------------------------- */
int exec_operator(FloatImg *A, FloatImg *B, int action, FloatImg *D)
{
int foo;
switch (action) {
case OP_ADD:
foo = fimg_add_3(A, B, D); break;
case OP_SUB:
foo = fimg_sub_3(A, B, D); break;
case OP_MIX:
if (verbosity) fprintf(stderr, "%s:mix: fvalue is %f\n",
__func__, global_fvalue);
foo = fimg_interpolate(A, B, D, global_fvalue);
break;
case OP_MUL:
foo = fimg_mul_3(A, B, D); break;
case OP_MINI:
foo = fimg_maximum(A, B, D); break;
case OP_MAXI:
foo = fimg_minimum(A, B, D); break;
default:
fprintf(stderr, "fscking action #%d\n", action);
foo = -99; break;
}
return foo;
}
/* --------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo, opt, action;
char *operator;
FloatImg srcA, srcB, dest;
global_fvalue = 0.5;
while ((opt = getopt(argc, argv, "hk:v")) != -1) {
switch(opt) {
case 'g': break;
case 'h': help(0); break;
case 'k': global_fvalue = atof(optarg); break;
case 'v': verbosity++; break;
}
}
#if DEBUG_LEVEL
fprintf(stderr, "argc %d optind %d\n", argc, optind);
for (foo=0; foo<argc; foo++)
fprintf(stderr, "%3d %s\n", foo, argv[foo]);
#endif
if (4 != argc-optind) {
fprintf(stderr, "%s need some arguments...\n", argv[0]);
exit(1);
}
operator = argv[optind+2];
action = look_opcode(operator);
if (action < 0) {
fprintf(stderr, "%s : opcode '%s' unknow\n", argv[0], operator);
exit(1);
}
/*
* load the two source files, and check compatibility
*/
if ((foo=fimg_create_from_dump(argv[optind], &srcA))) {
fprintf(stderr, "read error on '%s' is %d\n", argv[optind], foo);
exit(2);
}
if ((foo=fimg_create_from_dump(argv[optind+1], &srcB))) {
fprintf(stderr, "read error on '%s' is %d\n", argv[optind+1], foo);
exit(3);
}
if (verbosity > 1) { /* please, debug me */
fimg_describe(&srcA, argv[optind]);
fimg_describe(&srcB, argv[optind+1]);
}
foo = fimg_images_not_compatible(&srcA, &srcB);
if (foo) {
fprintf(stderr, "images are not compatibles, %d\n", foo);
exit(4);
}
/*
* we can now create the resultant image, and going coredump...
*/
foo = fimg_create(&dest, srcA.width, srcA.height, srcA.type);
if (foo) {
fprintf(stderr, "%s: crash coredump on create fimg\n", argv[0]);
#if MUST_ABORT
abort();
#endif
exit(1);
}
// fimg_describe(&dest, "destination");
foo = exec_operator(&srcA, &srcB, action, &dest);
if (foo) {
fprintf(stderr, "operator '%s' exec give us a %d\n",
operator, foo);
}
foo = fimg_dump_to_file(&dest, argv[optind+3], 0);
if (foo) {
fprintf(stderr, "dumping datas to file give us a %d\n", foo);
}
return 0;
}
/* --------------------------------------------------------------------- */

117
src/tools/fimgstats.c Normal file
View File

@@ -0,0 +1,117 @@
/*
* FIMGSTATS
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "../floatimg.h"
int verbosity; /* global */
int make_csv;
/* --------------------------------------------------------------------- */
int various_numbers(FloatImg *fimg, int k)
{
float moyennes[4];
int foo;
// float fvalue;
float vals[6];
if (verbosity) {
fprintf(stderr, " numbers from %p :\n", fimg);
}
fimg_printhead(fimg);
fprintf(stderr, "surface %d\n", fimg->width * fimg->height);
fimg_meanvalues(fimg, moyennes);
fprintf(stderr, "mean values:\n");
for (foo=0; foo<4; foo++)
printf(" %c %14.6f\n", "RGBA"[foo], moyennes[foo]);
foo = fimg_count_negativ(fimg);
if (foo) {
fprintf(stderr, "%d negative values\n", foo);
}
foo = fimg_get_minmax_rgb(fimg, vals);
if (foo) {
fprintf(stderr, "%s: err %d on fimg_get_minmax_rgb\n",
__func__, foo);
return foo;
}
printf("Rmin %12.4g Rmax %12.4g delta %12g\n",
vals[0], vals[1], vals[1]-vals[0]);
printf("Gmin %12.4g Gmax %12.4g %12g\n",
vals[2], vals[3], vals[3]-vals[2]);
printf("Bmin %12.4g Bmax %12.4g %12g\n",
vals[4], vals[5], vals[5]-vals[4]);
return 0;
}
/* --------------------------------------------------------------------- */
int various_numbers_from_file(char *fname, int k)
{
FloatImg fimg;
int foo;
fprintf(stderr, "------ numbers from '%s' :\n", fname);
foo = fimg_create_from_dump(fname, &fimg);
if (foo) {
fprintf(stderr, "create fimg from '%s' -> %d\n", fname, foo);
return -2;
}
various_numbers(&fimg, k);
fimg_destroy(&fimg);
return 0;
}
/* --------------------------------------------------------------------- */
static void help(int k)
{
fputs( "usage : fimgstats [options] file.fimg\n"
"\t-c\tmake a machinable csv\n"
"\t-v\tincrease verbosity\n"
, stderr);
}
/* --------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo, opt;
extern char *optarg;
extern int optind, opterr, optopt;
if (argc == 1) {
foo = fimg_print_version(1); help(0);
exit(0);
}
while ((opt = getopt(argc, argv, "chv")) != -1) {
switch(opt) {
case 'c': make_csv++; break;
case 'v': verbosity++; break;
case 'h': /* tombe dedans */
default: help(1); exit(1);
}
}
if (NULL==argv[optind]) {
fprintf(stderr, "optind %d is wtf\n", optind);
return 1;
}
foo = various_numbers_from_file(argv[optind], 0);
if (foo) {
fprintf(stderr, "got a %d ?\n", foo);
}
return 0;
}
/* --------------------------------------------------------------------- */

165
src/tools/mkfimg.c Normal file
View File

@@ -0,0 +1,165 @@
/*
* making a floatimg with some random datas
* an ugly software from tTh - february 2021
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include "../floatimg.h"
int verbosity;
/* --------------------------------------------------------------------- */
#define T_BLACK 1
#define T_DRAND48 2
#define T_GRAY 3
#define T_HDEG_A 4
#define T_VDEG_A 5
#define T_TPAT0 6
typedef struct {
int code;
char *name;
} Type;
Type types[] = {
{ T_BLACK, "black" },
{ T_DRAND48, "drand48" },
{ T_GRAY, "gray" },
{ T_GRAY, "grey" },
{ T_HDEG_A, "hdeg" },
{ T_VDEG_A, "vdeg" },
{ T_TPAT0, "tpat0" },
{ 0, NULL }
};
static int get_type(char *name)
{
Type *type;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' )\n", __func__, name);
#endif
// #define TEST(str) ( ! strcmp(name, str) )
for (type = types; type->code; type++) {
if (!strcmp(name, type->name)) {
return type->code;
}
}
return -1;
}
/* --------------------------------------------------------------------- */
static void help(int lj)
{
int foo;
puts("Usage:\tmkfimg [options] quux.fimg width height");
puts("\t-k N.N\tgive a float parameter");
fputs("\t-t bla\thowto make the pic :\n\t\t", stdout);
for (foo=0; types[foo].code; foo++) {
printf("%s ", types[foo].name);
}
puts("\n\t-v\tincrease verbosity");
if (verbosity) {
fimg_print_version(1);
printf("*** compiled %s, %s\n", __DATE__, __TIME__);
}
exit(0);
}
/* --------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo, opt, nbargs;
int width, height;
char *fname;
float fvalue = 1.0;
int type = T_BLACK;
char *tname = "wtf?";
FloatImg fimg;
while ((opt = getopt(argc, argv, "hk:t:v")) != -1) {
switch(opt) {
case 'h': help(0); break;
case 'k': fvalue = atof(optarg); break;
case 't': type = get_type(tname=optarg); break;
case 'v': verbosity++; break;
}
}
#if DEBUG_LEVEL
fprintf(stderr, "argc %d optind %d\n", argc, optind);
for (foo=0; foo<argc; foo++)
fprintf(stderr, "%3d %s\n", foo, argv[foo]);
#endif
if (type < 0) {
fprintf(stderr, "type '%s' is unknow\n", tname);
exit(2);
}
nbargs = argc-optind;
switch (nbargs) {
case 2:
if (2!=parse_WxH(argv[optind+1], &width, &height)) {
fprintf(stderr, "%s: parse error on '%s'\n",
argv[0], argv[optind+1]);
exit(1);
}
break;
case 3:
width = atoi(argv[optind+1]);
height = atoi(argv[optind+2]);
break;
default:
fprintf(stderr, "%s need filename, width & height\n", argv[0]);
exit(1);
}
fname = argv[optind];
if (verbosity>1) fprintf(stderr, "*** mkfimg *** %s %s\n", __DATE__, __TIME__);
if (verbosity) fprintf(stderr, "making '%s' %dx%d, type %d\n",
fname, width, height, type);
srand48(getpid() ^ time(NULL));
foo = fimg_create(&fimg, width, height, 3);
if (foo) {
fprintf(stderr, "create floatimg -> %d\n", foo);
exit(3);
}
switch(type) {
default:
case T_BLACK: fimg_clear(&fimg); break;
case T_DRAND48: fimg_drand48(&fimg, fvalue); break;
case T_GRAY: fimg_rgb_constant(&fimg, fvalue, fvalue, fvalue);
break;
case T_HDEG_A: fimg_hdeg_a(&fimg, 1.0); break;
case T_VDEG_A: fimg_vdeg_a(&fimg, 1.0); break;
case T_TPAT0: fimg_test_pattern(&fimg, 0, fvalue); break;
case -1: exit(1);
}
foo = fimg_dump_to_file(&fimg, fname, 0);
if (foo) {
fprintf(stderr, "dump fimg to %s -> %d\n", fname, foo);
exit(1);
}
fimg_destroy(&fimg);
return 0;
}
/* --------------------------------------------------------------------- */

62
src/tools/png2fimg.c Normal file
View File

@@ -0,0 +1,62 @@
/*
* PNG ---> FIMG
*
* Attention : certains fichiers PNG ne passent pas cette
* moulinette, mais le bug est dans la bibliotheque de
* fonctions 'libpnglite'. Une solution de remplacement
* devrait etre a l'etude un de ces jours...
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "../floatimg.h"
int verbosity = 0;
/* --------------------------------------------------------------------- */
void help(int k)
{
if (verbosity) fimg_print_version(k);
exit(0);
}
/* --------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
FloatImg fimg;
int foo, opt;
while ((opt = getopt(argc, argv, "hv")) != -1) {
switch(opt) {
case 'v': verbosity++; break;
case 'h': help(1); exit(1);
}
}
if (2 != argc-optind) {
fprintf(stderr, "error: %s need two filenames\n", argv[0]);
exit(1);
}
memset(&fimg, 0, sizeof(FloatImg));
foo = fimg_create_from_png(argv[optind], &fimg);
if (foo) {
fprintf(stderr, "%s : err %d, abort.\n", argv[0], foo);
exit(1);
}
if (verbosity) fimg_describe(&fimg, argv[optind+1]);
foo = fimg_dump_to_file(&fimg, argv[optind+1], 0);
if (foo) {
fprintf(stderr, "save as '%s' -> err %d\n", argv[2], foo);
exit(1);
}
return 0;
}
/* --------------------------------------------------------------------- */

38
src/v4l2/Makefile Normal file
View File

@@ -0,0 +1,38 @@
COPT = -Wall -fpic -g -no-pie -DDEBUG_LEVEL=0
DEPS = ../floatimg.h ../libfloatimg.a Makefile
LOBJ = funcs.o v4l2_pr_structs.o
all: grabvidseq t video-infos nc-camcontrol
t: t.c Makefile ${DEPS} funcs.o v4l2_pr_structs.o
gcc ${COPT} $< funcs.o v4l2_pr_structs.o ../libfloatimg.a -o $@
funcs.o: funcs.c funcs.h Makefile
gcc ${COPT} -c $<
rgb2fimg.o: rgb2fimg.c funcs.h Makefile
gcc ${COPT} -c $<
v4l2_pr_structs.o: v4l2_pr_structs.c v4l2_pr_structs.h Makefile
gcc ${COPT} -c $<
grabvidseq: grabvidseq.c ${DEPS} rgb2fimg.o
gcc ${COPT} $< rgb2fimg.o ../libfloatimg.a -lpnglite -lz -lm \
-lcfitsio -lv4l2 -ltiff -o $@
video-infos: video-infos.c Makefile funcs.o v4l2_pr_structs.o
gcc -Wall -g $< ${LOBJ} ../libfloatimg.a -o $@
nc-camcontrol: nc-camcontrol.c Makefile funcs.o v4l2_pr_structs.o
gcc -Wall -g $< ${LOBJ} ../libfloatimg.a -lcurses -o $@
# ---------------
# external things
capture: capture.c Makefile
gcc -Wall -g $< -o $@

32
src/v4l2/README.md Normal file
View File

@@ -0,0 +1,32 @@
# Images en virgule flottante, video 4 linux
## grabvidseq
```
tth@lubitel:~/Devel/FloatImg/v4l2$ ./grabvidseq -h
options :
-d /dev/? select video device
-g convert to gray
-n NNN how many frames ?
-O ./ set Output dir
-o bla.xxx set output filename
-p NN.N period in seconds
-r 90 rotate picture
-s WxH size of capture
-c mode contrast enhancement
-u try upscaling...
-v increase verbosity
```
## video-infos
```
Options :
-e N examine that, please
-d select the video device
-K set the K parameter
-l list video devices
-T bla add a title
-v increase verbosity
```

13
src/v4l2/README.txt Normal file
View File

@@ -0,0 +1,13 @@
capture video
-------------
------------------------------------------------------------------------
<paulk-leonov> tth: en faisant de la revue de patch sur V4L2, j'apprends
que V4L2_FMT_FLAG et V4L2_PIX_FMT_FLAG n'ont rien à voir:
le premier concerne le champ flags de la structure de l'ioctl enum_fmt
et le second le champ flag de la structure de g_fmt.
------------------------------------------------------------------------

670
src/v4l2/capture.c Normal file
View File

@@ -0,0 +1,670 @@
/*
.. Permission is granted to copy, distribute and/or modify this
.. document under the terms of the GNU Free Documentation License,
.. Version 1.1 or any later version published by the Free Software
.. Foundation, with no Invariant Sections, no Front-Cover Texts
.. and no Back-Cover Texts. A copy of the license is included at
.. Documentation/media/uapi/fdl-appendix.rst.
file: media/v4l/capture.c
=========================
*/
/*
* V4L2 video capture example
*
* This program can be used and distributed without restrictions.
*
* This program is provided with the V4L2 API
* see https://linuxtv.org/docs.php for more information
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <getopt.h> /* getopt_long() */
#include <fcntl.h> /* low-level i/o */
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
#define CLEAR(x) memset(&(x), 0, sizeof(x))
enum io_method {
IO_METHOD_READ,
IO_METHOD_MMAP,
IO_METHOD_USERPTR,
};
struct buffer {
void *start;
size_t length;
};
static char *dev_name;
static enum io_method io = IO_METHOD_MMAP;
static int fd = -1;
struct buffer *buffers;
static unsigned int n_buffers;
static int out_buf;
static int force_format;
static int frame_count = 70;
static void errno_exit(const char *s)
{
fprintf(stderr, "%s error %d, %s\n", s, errno, strerror(errno));
exit(EXIT_FAILURE);
}
static int xioctl(int fh, int request, void *arg)
{
int r;
do {
r = ioctl(fh, request, arg);
} while (-1 == r && EINTR == errno);
return r;
}
static void process_image(const void *p, int size)
{
if (out_buf)
fwrite(p, size, 1, stdout);
fflush(stderr);
fprintf(stderr, ".");
fflush(stdout);
}
static int read_frame(void)
{
struct v4l2_buffer buf;
unsigned int i;
switch (io) {
case IO_METHOD_READ:
if (-1 == read(fd, buffers[0].start, buffers[0].length)) {
switch (errno) {
case EAGAIN:
return 0;
case EIO:
/* Could ignore EIO, see spec. */
/* fall through */
default:
errno_exit("read");
}
}
process_image(buffers[0].start, buffers[0].length);
break;
case IO_METHOD_MMAP:
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {
switch (errno) {
case EAGAIN:
return 0;
case EIO:
/* Could ignore EIO, see spec. */
/* fall through */
default:
errno_exit("VIDIOC_DQBUF");
}
}
assert(buf.index < n_buffers);
process_image(buffers[buf.index].start, buf.bytesused);
if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
errno_exit("VIDIOC_QBUF");
break;
case IO_METHOD_USERPTR:
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_USERPTR;
if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {
switch (errno) {
case EAGAIN:
return 0;
case EIO:
/* Could ignore EIO, see spec. */
/* fall through */
default:
errno_exit("VIDIOC_DQBUF");
}
}
for (i = 0; i < n_buffers; ++i)
if (buf.m.userptr == (unsigned long)buffers[i].start
&& buf.length == buffers[i].length)
break;
assert(i < n_buffers);
process_image((void *)buf.m.userptr, buf.bytesused);
if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
errno_exit("VIDIOC_QBUF");
break;
}
return 1;
}
static void mainloop(void)
{
unsigned int count;
count = frame_count;
while (count-- > 0) {
for (;;) {
fd_set fds;
struct timeval tv;
int r;
FD_ZERO(&fds);
FD_SET(fd, &fds);
/* Timeout. */
tv.tv_sec = 2;
tv.tv_usec = 0;
r = select(fd + 1, &fds, NULL, NULL, &tv);
if (-1 == r) {
if (EINTR == errno)
continue;
errno_exit("select");
}
if (0 == r) {
fprintf(stderr, "select timeout\n");
exit(EXIT_FAILURE);
}
if (read_frame())
break;
/* EAGAIN - continue select loop. */
}
}
}
static void stop_capturing(void)
{
enum v4l2_buf_type type;
switch (io) {
case IO_METHOD_READ:
/* Nothing to do. */
break;
case IO_METHOD_MMAP:
case IO_METHOD_USERPTR:
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &type))
errno_exit("VIDIOC_STREAMOFF");
break;
}
}
static void start_capturing(void)
{
unsigned int i;
enum v4l2_buf_type type;
switch (io) {
case IO_METHOD_READ:
/* Nothing to do. */
break;
case IO_METHOD_MMAP:
for (i = 0; i < n_buffers; ++i) {
struct v4l2_buffer buf;
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
errno_exit("VIDIOC_QBUF");
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))
errno_exit("VIDIOC_STREAMON");
break;
case IO_METHOD_USERPTR:
for (i = 0; i < n_buffers; ++i) {
struct v4l2_buffer buf;
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_USERPTR;
buf.index = i;
buf.m.userptr = (unsigned long)buffers[i].start;
buf.length = buffers[i].length;
if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
errno_exit("VIDIOC_QBUF");
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))
errno_exit("VIDIOC_STREAMON");
break;
}
}
static void uninit_device(void)
{
unsigned int i;
switch (io) {
case IO_METHOD_READ:
free(buffers[0].start);
break;
case IO_METHOD_MMAP:
for (i = 0; i < n_buffers; ++i)
if (-1 == munmap(buffers[i].start, buffers[i].length))
errno_exit("munmap");
break;
case IO_METHOD_USERPTR:
for (i = 0; i < n_buffers; ++i)
free(buffers[i].start);
break;
}
free(buffers);
}
static void init_read(unsigned int buffer_size)
{
buffers = calloc(1, sizeof(*buffers));
if (!buffers) {
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
buffers[0].length = buffer_size;
buffers[0].start = malloc(buffer_size);
if (!buffers[0].start) {
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
}
static void init_mmap(void)
{
struct v4l2_requestbuffers req;
CLEAR(req);
req.count = 4;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {
if (EINVAL == errno) {
fprintf(stderr, "%s does not support "
"memory mapping\n", dev_name);
exit(EXIT_FAILURE);
} else {
errno_exit("VIDIOC_REQBUFS");
}
}
if (req.count < 2) {
fprintf(stderr, "Insufficient buffer memory on %s\n",
dev_name);
exit(EXIT_FAILURE);
}
buffers = calloc(req.count, sizeof(*buffers));
if (!buffers) {
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
struct v4l2_buffer buf;
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;
if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf))
errno_exit("VIDIOC_QUERYBUF");
buffers[n_buffers].length = buf.length;
buffers[n_buffers].start =
mmap(NULL /* start anywhere */,
buf.length,
PROT_READ | PROT_WRITE /* required */,
MAP_SHARED /* recommended */,
fd, buf.m.offset);
if (MAP_FAILED == buffers[n_buffers].start)
errno_exit("mmap");
}
}
static void init_userp(unsigned int buffer_size)
{
struct v4l2_requestbuffers req;
CLEAR(req);
req.count = 4;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_USERPTR;
if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {
if (EINVAL == errno) {
fprintf(stderr, "%s does not support "
"user pointer i/o\n", dev_name);
exit(EXIT_FAILURE);
} else {
errno_exit("VIDIOC_REQBUFS");
}
}
buffers = calloc(4, sizeof(*buffers));
if (!buffers) {
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
for (n_buffers = 0; n_buffers < 4; ++n_buffers) {
buffers[n_buffers].length = buffer_size;
buffers[n_buffers].start = malloc(buffer_size);
if (!buffers[n_buffers].start) {
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
}
}
static void init_device(void)
{
struct v4l2_capability cap;
struct v4l2_cropcap cropcap;
struct v4l2_crop crop;
struct v4l2_format fmt;
unsigned int min;
if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) {
if (EINVAL == errno) {
fprintf(stderr, "%s is no V4L2 device\n",
dev_name);
exit(EXIT_FAILURE);
} else {
errno_exit("VIDIOC_QUERYCAP");
}
}
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
fprintf(stderr, "%s is no video capture device\n",
dev_name);
exit(EXIT_FAILURE);
}
switch (io) {
case IO_METHOD_READ:
if (!(cap.capabilities & V4L2_CAP_READWRITE)) {
fprintf(stderr, "%s does not support read i/o\n",
dev_name);
exit(EXIT_FAILURE);
}
break;
case IO_METHOD_MMAP:
case IO_METHOD_USERPTR:
if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
fprintf(stderr, "%s does not support streaming i/o\n",
dev_name);
exit(EXIT_FAILURE);
}
break;
}
/* Select video input, video standard and tune here. */
CLEAR(cropcap);
cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (0 == xioctl(fd, VIDIOC_CROPCAP, &cropcap)) {
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
crop.c = cropcap.defrect; /* reset to default */
if (-1 == xioctl(fd, VIDIOC_S_CROP, &crop)) {
switch (errno) {
case EINVAL:
/* Cropping not supported. */
break;
default:
/* Errors ignored. */
break;
}
}
} else {
/* Errors ignored. */
}
CLEAR(fmt);
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (force_format) {
fmt.fmt.pix.width = 640;
fmt.fmt.pix.height = 480;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt))
errno_exit("VIDIOC_S_FMT");
/* Note VIDIOC_S_FMT may change width and height. */
} else {
/* Preserve original settings as set by v4l2-ctl for example */
if (-1 == xioctl(fd, VIDIOC_G_FMT, &fmt))
errno_exit("VIDIOC_G_FMT");
}
/* Buggy driver paranoia. */
min = fmt.fmt.pix.width * 2;
if (fmt.fmt.pix.bytesperline < min)
fmt.fmt.pix.bytesperline = min;
min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
if (fmt.fmt.pix.sizeimage < min)
fmt.fmt.pix.sizeimage = min;
switch (io) {
case IO_METHOD_READ:
init_read(fmt.fmt.pix.sizeimage);
break;
case IO_METHOD_MMAP:
init_mmap();
break;
case IO_METHOD_USERPTR:
init_userp(fmt.fmt.pix.sizeimage);
break;
}
}
static void close_device(void)
{
if (-1 == close(fd))
errno_exit("close");
fd = -1;
}
static void open_device(void)
{
struct stat st;
if (-1 == stat(dev_name, &st)) {
fprintf(stderr, "Cannot identify '%s': %d, %s\n",
dev_name, errno, strerror(errno));
exit(EXIT_FAILURE);
}
if (!S_ISCHR(st.st_mode)) {
fprintf(stderr, "%s is no device\n", dev_name);
exit(EXIT_FAILURE);
}
fd = open(dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);
if (-1 == fd) {
fprintf(stderr, "Cannot open '%s': %d, %s\n",
dev_name, errno, strerror(errno));
exit(EXIT_FAILURE);
}
}
static void usage(FILE *fp, int argc, char **argv)
{
fprintf(fp,
"Usage: %s [options]\n\n"
"Version 1.3\n"
"Options:\n"
"-d | --device name Video device name [%s]\n"
"-h | --help Print this message\n"
"-m | --mmap Use memory mapped buffers [default]\n"
"-r | --read Use read() calls\n"
"-u | --userp Use application allocated buffers\n"
"-o | --output Outputs stream to stdout\n"
"-f | --format Force format to 640x480 YUYV\n"
"-c | --count Number of frames to grab [%i]\n"
"",
argv[0], dev_name, frame_count);
}
static const char short_options[] = "d:hmruofc:";
static const struct option
long_options[] = {
{ "device", required_argument, NULL, 'd' },
{ "help", no_argument, NULL, 'h' },
{ "mmap", no_argument, NULL, 'm' },
{ "read", no_argument, NULL, 'r' },
{ "userp", no_argument, NULL, 'u' },
{ "output", no_argument, NULL, 'o' },
{ "format", no_argument, NULL, 'f' },
{ "count", required_argument, NULL, 'c' },
{ 0, 0, 0, 0 }
};
int main(int argc, char **argv)
{
dev_name = "/dev/video0";
for (;;) {
int idx;
int c;
c = getopt_long(argc, argv,
short_options, long_options, &idx);
if (-1 == c)
break;
switch (c) {
case 0: /* getopt_long() flag */
break;
case 'd':
dev_name = optarg;
break;
case 'h':
usage(stdout, argc, argv);
exit(EXIT_SUCCESS);
case 'm':
io = IO_METHOD_MMAP;
break;
case 'r':
io = IO_METHOD_READ;
break;
case 'u':
io = IO_METHOD_USERPTR;
break;
case 'o':
out_buf++;
break;
case 'f':
force_format++;
break;
case 'c':
errno = 0;
frame_count = strtol(optarg, NULL, 0);
if (errno)
errno_exit(optarg);
break;
default:
usage(stderr, argc, argv);
exit(EXIT_FAILURE);
}
}
open_device();
init_device();
start_capturing();
mainloop();
stop_capturing();
uninit_device();
close_device();
fprintf(stderr, "\n");
return 0;
}

12
src/v4l2/essai.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/bash
# -----------------------------------------------------
TMPF="tmp.fimg"
CAM="/dev/video0"
# -----------------------------------------------------
./grabvidseq -d $CAM -n 10000 -vv -p 0 -r 90
# -----------------------------------------------------

42
src/v4l2/exemple.txt Normal file
View File

@@ -0,0 +1,42 @@
-- v4l2_capability, /dev/video0 0x7ffeee718100
driver cx231xx
card Pixelview Xcapture USB
bus info usb-0000:00:1a.0-1.2
version 0x41325
capabilities 0x85200011
vcapt vbicapt extpix rwsysc stream
device caps 0x5200001
-- inputs enumeration 'on peut voir quoi ?'
Composite1 | camera
S-Video | camera
-- v4l2_format, Experimental 0x7ffeee718030
type 1 video capture
dims 720x576
pixformat [YUYV]
field 4
padding 1440
sizeimage 829440
colorspace 1 smpte170m
-- image formats enumeration (Experimental)
0 vidcapt 0x00 [YUYV] YUYV 4:2:2
-- controls enumeration 'is that working ?'
Brightness integer [0..255]
Contrast integer [0..127]
Saturation integer [0..127]
Hue integer [-128..127]
Volume integer [0..65535]
Balance integer [0..65535]
Bass integer [0..65535]
Treble integer [0..65535]
Mute boolean [0..1]
-- extended controls enumeration 'looking for extended'
User Controls ctrl-class [0..0]
Brightness integer [0..255]
Contrast integer [0..127]
Saturation integer [0..127]
Hue integer [-128..127]
Volume integer [0..65535]
Balance integer [0..65535]
Bass integer [0..65535]
Treble integer [0..65535]
Mute boolean [0..1]

329
src/v4l2/funcs.c Normal file
View File

@@ -0,0 +1,329 @@
/*
* V4L2 functions - ugly source code
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h> /* low-level i/o */
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
#include "../floatimg.h"
#include "funcs.h"
/* --------------------------------------------------------------------- */
extern int verbosity;
enum io_method {
IO_METHOD_READ,
IO_METHOD_MMAP,
IO_METHOD_USERPTR,
};
struct buffer {
void *start;
size_t length;
};
static char *dev_name;
static enum io_method io = IO_METHOD_MMAP;
static int fd = -1;
struct buffer *buffers;
static unsigned int n_buffers;
static int out_buf;
static int force_format;
static int frame_count = 70;
static void errno_exit(const char *s)
{
fprintf(stderr, "%s error %d, %s\n", s, errno, strerror(errno));
exit(EXIT_FAILURE);
}
static int xioctl(int fh, int request, void *arg)
{
int r;
/* PLEASE EXPLAIN THAT CODE */
do {
r = ioctl(fh, request, arg);
} while (-1 == r && EINTR == errno);
return r;
}
/* --------------------------------------------------------------------- */
/*
*
*/
int open_device(char *device)
{
struct stat st;
if (-1 == stat(device, &st)) {
fprintf(stderr, "Cannot identify '%s': %d, %s\n",
device, errno, strerror(errno));
exit(EXIT_FAILURE);
}
if (!S_ISCHR(st.st_mode)) {
fprintf(stderr, "%s is no device\n", device);
exit(EXIT_FAILURE);
}
fd = open(device, O_RDWR /* required */ | O_NONBLOCK, 0);
if (-1 == fd) {
fprintf(stderr, "Cannot open '%s': %d, %s\n",
device, errno, strerror(errno));
exit(EXIT_FAILURE);
}
dev_name = strdup(device); /* XXX */
if (verbosity) {
fprintf(stderr, "device '%s' opened as #%d\n", device, fd);
}
return fd;
}
/* --------------------------------------------------------------------- */
static void init_read(unsigned int buffer_size)
{
buffers = calloc(1, sizeof(*buffers));
if (!buffers) {
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
buffers[0].length = buffer_size;
buffers[0].start = malloc(buffer_size);
if (!buffers[0].start) {
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
}
static void init_mmap(void)
{
struct v4l2_requestbuffers req;
memset(&req, 0, sizeof(req));
req.count = 4;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {
if (EINVAL == errno) {
fprintf(stderr, "%s does not support "
"memory mapping\n", dev_name);
exit(EXIT_FAILURE);
} else {
errno_exit("VIDIOC_REQBUFS");
}
}
if (req.count < 2) {
fprintf(stderr, "Insufficient buffer memory on %s\n",
dev_name);
exit(EXIT_FAILURE);
}
buffers = calloc(req.count, sizeof(*buffers));
if (!buffers) {
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
struct v4l2_buffer buf;
memset(&buf, 0, sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;
if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf))
errno_exit("VIDIOC_QUERYBUF");
buffers[n_buffers].length = buf.length;
buffers[n_buffers].start =
mmap(NULL /* start anywhere */,
buf.length,
PROT_READ | PROT_WRITE /* required */,
MAP_SHARED /* recommended */,
fd, buf.m.offset);
if (MAP_FAILED == buffers[n_buffers].start)
errno_exit("mmap");
}
}
static void init_userp(unsigned int buffer_size)
{
struct v4l2_requestbuffers req;
memset(&req, 0, sizeof(req));
req.count = 4;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_USERPTR;
if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {
if (EINVAL == errno) {
fprintf(stderr, "%s does not support "
"user pointer i/o\n", dev_name);
exit(EXIT_FAILURE);
} else {
errno_exit("VIDIOC_REQBUFS");
}
}
buffers = calloc(4, sizeof(*buffers));
if (!buffers) {
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
for (n_buffers = 0; n_buffers < 4; ++n_buffers) {
buffers[n_buffers].length = buffer_size;
buffers[n_buffers].start = malloc(buffer_size);
if (!buffers[n_buffers].start) {
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
}
}
/* --------------------------------------------------------------------- */
int init_device(int notused)
{
struct v4l2_capability cap;
struct v4l2_cropcap cropcap;
struct v4l2_crop crop;
struct v4l2_format fmt;
unsigned int min;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %d )\n", __func__, notused);
#endif
if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) {
if (EINVAL == errno) {
fprintf(stderr, "%s is not a V4L2 device\n", dev_name);
exit(EXIT_FAILURE);
}
else {
errno_exit("VIDIOC_QUERYCAP");
}
}
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
fprintf(stderr, "%s is no video capture device\n", dev_name);
exit(EXIT_FAILURE);
}
switch (io) {
case IO_METHOD_READ:
if (!(cap.capabilities & V4L2_CAP_READWRITE)) {
fprintf(stderr, "%s do not support read i/o\n", dev_name);
exit(EXIT_FAILURE);
}
if (verbosity) fprintf(stderr, "%s io method read OK\n", __func__);
break;
case IO_METHOD_MMAP:
case IO_METHOD_USERPTR:
if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
fprintf(stderr, "%s do not support streaming i/o\n", dev_name);
exit(EXIT_FAILURE);
}
if (verbosity) fprintf(stderr, "%s io mmap/userptr OK\n", __func__);
break;
} /* end switch */
/* Select video input, video standard and tune here. */
memset(&cropcap, 0, sizeof(cropcap));
cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (0 == xioctl(fd, VIDIOC_CROPCAP, &cropcap)) {
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
crop.c = cropcap.defrect; /* reset to default */
if (-1 == xioctl(fd, VIDIOC_S_CROP, &crop)) {
switch (errno) {
case EINVAL:
/* Cropping not supported. */
break;
default:
/* Errors ignored. */
break;
}
}
} else {
/* Errors ignored. */
}
memset(&fmt, 0, sizeof(fmt)); // CLEAR(fmt);
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (force_format) {
fmt.fmt.pix.width = 640;
fmt.fmt.pix.height = 480;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt))
errno_exit("VIDIOC_S_FMT");
/* Note VIDIOC_S_FMT may change width and height. */
} else {
/* Preserve original settings as set by v4l2-ctl for example */
if (-1 == xioctl(fd, VIDIOC_G_FMT, &fmt))
errno_exit("VIDIOC_G_FMT");
}
/* Buggy driver paranoia. */
min = fmt.fmt.pix.width * 2;
if (fmt.fmt.pix.bytesperline < min)
fmt.fmt.pix.bytesperline = min;
min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
if (fmt.fmt.pix.sizeimage < min)
fmt.fmt.pix.sizeimage = min;
switch (io) {
case IO_METHOD_READ:
init_read(fmt.fmt.pix.sizeimage);
break;
case IO_METHOD_MMAP:
init_mmap();
break;
case IO_METHOD_USERPTR:
init_userp(fmt.fmt.pix.sizeimage);
break;
}
return 0;
}

20
src/v4l2/funcs.h Normal file
View File

@@ -0,0 +1,20 @@
/*
* V4L2 functions - header file
*/
int open_device(char *dev_name);
int init_device(int notused);
/* --------------------------------------------------------------------- */
int x_upscaler_0(unsigned char *src, int w, int h, FloatImg *d);
int x_add_rgb2fimg(unsigned char *src, int w, int h, FloatImg *d);
int x_rgb2fimg(unsigned char *src, int w, int h, FloatImg *d);
int x_rgb2file(unsigned char *src, int w, int h, char *fname);
/* --------------------------------------------------------------------- */

427
src/v4l2/grabvidseq.c Normal file
View File

@@ -0,0 +1,427 @@
/* V4L2 video picture grabber
Origin :V4L2GRAB.C - patched by tTh
Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@infradead.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <linux/videodev2.h>
#include <libv4l2.h>
#include "../floatimg.h"
#include "funcs.h"
/* --------------------------------------------------------------------- */
/* compilation control */
#define SAVE_AS_CUMUL 1
#define SAVE_AS_FIMG 0
#define NBR_BUFFERS 4
/* --------------------------------------------------------------------- */
#define CLEAR(x) memset(&(x), 0, sizeof(x))
struct buffer {
void *start;
size_t length;
};
int verbosity;
static int systrace;
/* --------------------------------------------------------------------- */
static void xioctl(int fh, int request, void *arg)
{
int r;
/* may be imagine a system for displaying all call to this function ? */
if (systrace) {
fprintf(stderr, "xioctl fd=%d req=%d arg=%p\n", fh, request, arg);
}
do {
r = v4l2_ioctl(fh, request, arg);
} while (r == -1 && ((errno == EINTR) || (errno == EAGAIN)));
if (r == -1) {
fprintf(stderr, "error %d, %s\n", errno, strerror(errno));
sleep(1);
exit(EXIT_FAILURE);
}
}
/* --------------------------------------------------------------------- */
void help(int v)
{
if (verbosity) {
printf("compiled %s at %s\n", __DATE__, __TIME__);
fimg_print_version(1);
}
puts("options :");
puts("\t-d /dev/?\tselect video device");
puts("\t-g\t\tconvert to gray");
puts("\t-n NNN\t\thow many frames ?");
puts("\t-O ./\t\tset Output dir");
puts("\t-o bla.xxx\tset output filename");
puts("\t-p NN.N\t\tperiod in seconds");
puts("\t-r NNN\t\trotate picture");
puts("\t-s WxH\t\tsize of capture");
puts("\t-c mode\t\tcontrast enhancement");
puts("\t-u\t\ttry upscaling...");
puts("\t-v\t\tincrease verbosity");
puts("\t-Z\t\tenable systrace");
if (verbosity) {
puts("\n\t\tXXX list all the contrast modes, please\n");
}
exit(0);
}
/* --------------------------------------------------------------------- */
int main(int argc, char **argv)
{
struct v4l2_format fmt;
struct v4l2_buffer buf;
struct v4l2_requestbuffers req;
enum v4l2_buf_type type;
fd_set fds;
struct timeval tv;
int r, fd = -1;
unsigned int i, n_buffers;
char *dev_name = "/dev/video0";
// XXX FILE *fout;
struct buffer *buffers;
int foo;
double period = 10.0; /* delai entre les captures
en secondes */
int nbre_capt = 1; /* nombre de captures */
int opt;
int width = 640;
int height = 480;
double t_final, maxvalue;
int to_gray = 0;
int upscaling = 0;
int contrast = CONTRAST_NONE;
int rotfactor = 0; /* only 0 or 90 here */
char *dest_dir = "."; /* no trailing slash */
char *outfile = "out.pnm";
#if SAVE_AS_CUMUL
FloatImg cumul, tmpfimg, *to_save;
#endif
while ((opt = getopt(argc, argv, "c:d:ghn:o:O:p:r:s:uvZ")) != -1) {
switch(opt) {
case 'c': contrast = fimg_id_contraste(optarg);
if (contrast < 0) {
fputs("unknow contrast\n", stderr);
exit(1);
}
break;
case 'd': dev_name = optarg; break;
case 'g': to_gray = 1; break;
case 'h': help(0); break;
case 'n': nbre_capt = atoi(optarg); break;
case 'O': dest_dir = optarg; break;
case 'o': outfile = optarg; break;
case 'p': foo = parse_double(optarg, &period);
if (foo<0) {
fprintf(stderr,
"error parsing -p arg '%s'\n",
optarg);
exit(1);
}
break;
case 'r': rotfactor = atoi(optarg); break;
case 's': parse_WxH(optarg, &width, &height);
break;
case 'u': upscaling = 1; break;
case 'v': verbosity++; break;
case 'Z': systrace = 1; break;
default:
fprintf(stderr, "option '%c' is wtf\n", opt);
exit(1);
}
}
if (verbosity > 1) {
fprintf(stderr, "*** GrabVidSeq (%s, %s) libv %d, pid=%d\n",
__DATE__, __TIME__, FIMG_VERSION, getpid());
fprintf(stderr, "grabing %d picz, ", nbre_capt);
fprintf(stderr, "period is %.3f seconds\n", period);
fprintf(stderr, "framesize is %dx%d\n", width, height);
// fprintf(stderr, "destdir is '%s'\n", dest_dir);
if (upscaling) fprintf(stderr, "upscaling is on\n");
}
if (upscaling && (nbre_capt%4)) {
fprintf(stderr, "WARN upscaling: %d bad nbre_capt\n",
nbre_capt);
}
fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0);
if (fd < 0) {
perror(dev_name);
exit(EXIT_FAILURE);
}
CLEAR(fmt);
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = width;
fmt.fmt.pix.height = height;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
xioctl(fd, VIDIOC_S_FMT, &fmt);
if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_RGB24) {
/* are others formats usable ? */
fprintf(stderr, "Libv4l didn't accept RGB24 format. Can't proceed.\n");
exit(EXIT_FAILURE);
}
if ((fmt.fmt.pix.width != width) || (fmt.fmt.pix.height != height)) {
fprintf(stderr, "Warning: driver is sending image at %dx%d\n",
fmt.fmt.pix.width, fmt.fmt.pix.height);
}
// fprintf(stderr,"--- Ok 1\n");
CLEAR(req);
req.count = NBR_BUFFERS;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
xioctl(fd, VIDIOC_REQBUFS, &req);
buffers = calloc(req.count, sizeof(*buffers));
for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;
xioctl(fd, VIDIOC_QUERYBUF, &buf);
buffers[n_buffers].length = buf.length;
buffers[n_buffers].start = v4l2_mmap(NULL, buf.length,
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, buf.m.offset);
if (MAP_FAILED == buffers[n_buffers].start) {
perror("v4l2_mmap");
exit(EXIT_FAILURE);
}
}
(void)fimg_timer_set(0);
for (i = 0; i < NBR_BUFFERS; ++i) {
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
xioctl(fd, VIDIOC_QBUF, &buf);
}
#if SAVE_AS_CUMUL
if (upscaling) {
foo = fimg_create(&cumul,
fmt.fmt.pix.width*2, fmt.fmt.pix.height*2,
FIMG_TYPE_RGB);
}
else {
foo = fimg_create(&cumul,
fmt.fmt.pix.width, fmt.fmt.pix.height,
FIMG_TYPE_RGB);
}
fimg_clear(&cumul);
cumul.fval = 255.0; /* must be read from camera XXX */
cumul.count = 0;
to_save = &cumul;
#endif
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
xioctl(fd, VIDIOC_STREAMON, &type);
#if 1
if (verbosity) fprintf(stderr,"pid %d is going to grab %d picz...\n",
getpid(), nbre_capt);
#endif
/*
* START ON THE GRABBING LOOP
*/
for (i = 0; i < nbre_capt; i++) {
do {
FD_ZERO(&fds);
FD_SET(fd, &fds);
/* Timeout. */
tv.tv_sec = 2;
tv.tv_usec = 0;
r = select(fd + 1, &fds, NULL, NULL, &tv);
} while ((r == -1 && (errno = EINTR)));
if (r == -1) {
perror("select");
return errno; /* WTF ? a rogue return
from the main() ? */
}
if(verbosity > 1) {
fprintf(stderr, "%6d / %6d %9.3f\r", i, nbre_capt,
fimg_timer_get(0));
fflush(stderr);
}
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
xioctl(fd, VIDIOC_DQBUF, &buf);
if(verbosity > 2) {
fprintf(stderr, "xioctl VIDIOC_DQBUF done\n");
fflush(stderr);
}
#if SAVE_AS_CUMUL
if (upscaling) {
x_upscaler_0(buffers[buf.index].start,
fmt.fmt.pix.width, fmt.fmt.pix.height, &cumul);
}
else {
x_add_rgb2fimg(buffers[buf.index].start,
fmt.fmt.pix.width, fmt.fmt.pix.height, &cumul);
}
#endif
#if SAVE_AS_FIMG
sprintf(out_name, "%s/%05d.fimg", dest_dir, i);
if (verbosity > 1) fprintf(stderr, "--> %s\n", out_name);
foo = x_rgb2file(buffers[buf.index].start,
fmt.fmt.pix.width, fmt.fmt.pix.height,
out_name);
#endif
if (nbre_capt > 1 && period > 0.001) {
/* suspend execution for
microsecond intervals */
usleep((int)(period*1E6));
}
xioctl(fd, VIDIOC_QBUF, &buf);
}
if (verbosity) {
t_final = fimg_timer_get(0);
fprintf(stderr, "pid %d : elapsed %.3g s -> %.2f fps\n", getpid(),
t_final, (double)nbre_capt / t_final);
}
if (to_gray) {
if (verbosity) fputs("converting to gray\n", stderr);
foo = fimg_to_gray(&cumul);
}
#if SAVE_AS_CUMUL
// save cumul to file
if (verbosity) fprintf(stderr, "saving cumul to '%s'\n", outfile);
/* ----- nouveau 15 nov 2019 */
maxvalue = cumul.fval * cumul.count;
if (verbosity) {
fprintf(stderr, "theorical maxvalue = %g\n", maxvalue);
fprintf(stderr, "computed max value = %g\n",
fimg_get_maxvalue(&cumul));
}
switch (contrast) {
case CONTRAST_NONE:
// if (verbosity) fprintf(stderr, "contrast: none\n");
break;
case CONTRAST_SQRT:
fimg_square_root(&cumul, NULL, maxvalue);
break;
case CONTRAST_POW2:
fimg_power_2(&cumul, NULL, maxvalue);
break;
case CONTRAST_COS01:
fimg_cos_01(&cumul, NULL, maxvalue);
break;
case CONTRAST_COS010:
fimg_cos_010(&cumul, NULL, maxvalue);
break;
default:
fprintf(stderr, "bad contrast method\n");
break;
}
/* XXX warning, new from coronahome 26 mars 2020 */
to_save = &cumul;
if (90 == rotfactor) {
memset(&tmpfimg, 0, sizeof(FloatImg));
foo = fimg_rotate_90(&cumul, &tmpfimg, 0);
if (verbosity > 2) {
fprintf(stderr, "dump rot90 %p\n", &tmpfimg);
foo = fimg_save_as_png(&tmpfimg, "rot90.png", 0);
}
to_save = &tmpfimg;
}
foo = format_from_extension(outfile);
switch (foo) {
case FILE_TYPE_FIMG:
foo = fimg_dump_to_file(to_save, outfile, 0);
break;
case FILE_TYPE_PNM:
foo = fimg_save_as_pnm(to_save, outfile, 1);
break;
case FILE_TYPE_PNG:
foo = fimg_save_as_png(to_save, outfile, 0);
break;
case FILE_TYPE_FITS:
foo = fimg_save_R_as_fits(to_save, outfile, 0);
break;
case FILE_TYPE_TIFF:
foo = fimg_write_as_tiff(to_save, outfile, 0);
break;
default:
fprintf(stderr, "can't save as %s\n", outfile);
break;
}
// free buffers
fimg_destroy(&cumul);
#endif
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
xioctl(fd, VIDIOC_STREAMOFF, &type);
for (i = 0; i < NBR_BUFFERS; ++i) {
v4l2_munmap(buffers[i].start, buffers[i].length);
}
// free(buffers); /* atomic bombing */
v4l2_close(fd);
return 0;
}

130
src/v4l2/nc-camcontrol.c Normal file
View File

@@ -0,0 +1,130 @@
/*
* tests pour capturer les webcams
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
// #include <string.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <inttypes.h>
#include <curses.h>
#include <linux/videodev2.h>
#include "../floatimg.h"
#include "v4l2_pr_structs.h"
#include "funcs.h"
int verbosity;
/* --------------------------------------------------------------------- */
void help(int n)
{
puts("camera controls");
puts("\t-d bla\t\tselect video device");
puts("\t-e nnn\t\tset 'etype'");
puts("\t-K nnn\t\tinteger parameter");
puts("\t-n bla\t\tset title");
exit(0);
}
/* --------------------------------------------------------------------- */
int init_screen(char *title)
{
int foo;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' )\n", __func__, title);
#endif
initscr();
standout(); mvaddstr(1, 5, title); standend(); refresh();
return -1;
}
/* --------------------------------------------------------------------- */
int end_screen(void)
{
endwin();
return 0;
}
/* --------------------------------------------------------------------- */
int preparation_v4l2(char *devname, int param)
{
int fd, foo;
struct v4l2_capability cap;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' %d )\n", __func__, devname, param);
#endif
fd = open_device(devname);
if (fd < 0) {
fprintf(stderr, "err %d on %s opening\n", errno, devname);
return -2;
}
/* est-ce un device qui permet la capture video */
foo = ioctl(fd, VIDIOC_QUERYCAP, &cap);
if (-1 == foo) {
perror("VIDIOC_QUERYCAP");
return -2;
}
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
fprintf(stderr, "%s is not a video capture device\n", devname);
return -3;
}
return fd;
}
/* --------------------------------------------------------------------- */
int interactive(int fd, char *text, int notused)
{
fprintf(stderr, "file descriptor = %d\n", fd);
init_screen("prototype");
sleep(2);
end_screen();
return 0;
}
/* --------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo, opt, devnum;
int etype = 0;
char *device = "/dev/video0";
char *title = NULL;
int K = 0;
while ((opt = getopt(argc, argv, "d:e:hK:lT:v")) != -1) {
switch(opt) {
case 'd': device = optarg; break;
case 'e': etype = atol(optarg); break;
case 'h': help(0); break;
case 'K': K = atol(optarg); break;
// case 'l': liste_des_devices(0); break;
case 't': title = optarg;
case 'v': verbosity++; break;
}
}
devnum = preparation_v4l2(device, K);
if (devnum < 0) {
fprintf(stderr, "%s : erreur init video device\n", argv[0]);
exit(1);
}
foo = interactive(devnum, title, 0);
return 0;
}
/* --------------------------------------------------------------------- */

25
src/v4l2/notes.txt Normal file
View File

@@ -0,0 +1,25 @@
Heisenbug dans la capture d'image
=================================
Contexte : Debian 10 32 bits sur Sony Vaio,
webcam Logitech classique.
Mon soft 'grabvidseq' part _parfois_ en torche oo, à la louche une
fois sur cent. Mais toujours au même endroit, au début de la boucle
de capture des images, précisément dans cet appel système :
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
xioctl(fd, VIDIOC_DQBUF, &buf);
Quand le programme semble figé, un strace -p <pid> sort le même
message en rafale _très_ féroce :
ioctl(3, VIDIOC_DQBUF, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE}) = -1 EAGAIN (Resource temporarily unavailable)
ioctl(3, VIDIOC_DQBUF, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE}) = -1 EAGAIN (Resource temporarily unavailable)
ioctl(3, VIDIOC_DQBUF, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE^Cstrace: Process 11181 detached
WTF ?

135
src/v4l2/rgb2fimg.c Normal file
View File

@@ -0,0 +1,135 @@
#include <stdio.h>
#include <stdlib.h>
#include "../floatimg.h"
#include "funcs.h"
extern int verbosity;
/*
* Be careful, these functions are not yet fireproof,
* and calling conventions are fluctuating.
*/
/* --------------------------------------------------------------------- */
int x_upscaler_0(unsigned char *src, int w, int h, FloatImg *d)
{
int x, y, xx, yy, ox, oy;
// float *rp, *gp, *bp;
float r, g, b;
static unsigned short modz;
/*
* check in image sizes are correct
*/
if ( d->width != w*2 || d->height != h*2 ) {
fprintf(stderr, "%s: dimension error\n", __func__);
fprintf(stderr, "\tw = %d h = %d\n", w, h);
fprintf(stderr, "\tdest image is %dx%d\n", d->width, d->height);
#if MUST_ABORT
abort();
#endif
return -2;
}
ox = ! ! (modz & 2);
oy = ! ! (modz & 1);
if (verbosity>2) fprintf(stderr, "%s %5d %d %d\n", __func__,
modz, ox, oy);
for (y=0; y<h; y++) {
yy = (y*2) + oy;
for (x=0; x<w; x++) {
xx = (x*2) + ox;
r = (float)*src++;
g = (float)*src++;
b = (float)*src++;
/* may be, here, we can speed up the job */
fimg_add_rgb(d, xx, yy, r, g, b);
/* or may be jump directly to asm and SSE2
http://www.mikekohn.net/stuff/image_processing.php */
}
}
modz++; /* next displacment index */
if ( ! (modz & 0x03)) {
d->count++; /* one more frame in the accumulator */
}
return -1;
}
/* --------------------------------------------------------------------- */
int x_rgb2fimg(unsigned char *src, int w, int h, FloatImg *d)
{
int iter, size;
float *rp, *gp, *bp;
size = w * h;
rp = d->R, gp = d->G, bp = d->B;
for (iter=0; iter<size; iter++) {
*rp++ = (float)*src++;
*gp++ = (float)*src++;
*bp++ = (float)*src++;
}
return 0;
}
/* --------------------------------------------------------------------- */
int x_add_rgb2fimg(unsigned char *src, int w, int h, FloatImg *d)
{
int iter, size;
float *rp, *gp, *bp;
size = w * h;
rp = d->R, gp = d->G, bp = d->B;
for (iter=0; iter<size; iter++) {
*rp++ += (float)*src++;
*gp++ += (float)*src++;
*bp++ += (float)*src++;
}
d->count++; /* one more frame in the accumulator */
return 0;
}
/* --------------------------------------------------------------------- */
int x_rgb2file(unsigned char *src, int w, int h, char *fname)
{
FloatImg buff;
int foo;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %d %d '%s' )\n", __func__,
src, w, h, fname);
#endif
foo = fimg_create(&buff, w, h, FIMG_TYPE_RGB);
if (foo) {
fprintf(stderr, "Crash on create in %s %s\n", __FILE__, __func__);
exit(1);
}
foo = x_rgb2fimg(src, w, h, &buff);
if (foo) {
fprintf(stderr, "Crash on bit massage in %s %s\n", __FILE__, __func__);
exit(1);
}
foo = fimg_dump_to_file(&buff, fname, 0);
if (foo) {
fprintf(stderr, "Crash on dump in %s %s\n", __FILE__, __func__);
exit(1);
}
fimg_destroy(&buff);
return -1;
}
/* --------------------------------------------------------------------- */

91
src/v4l2/t.c Normal file
View File

@@ -0,0 +1,91 @@
/*
* tests pour capturer les webcams
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <string.h>
#include <sys/ioctl.h>
#include <inttypes.h>
#include <linux/videodev2.h>
#include "../floatimg.h"
#include "funcs.h"
#include "v4l2_pr_structs.h"
int verbosity;
/* --------------------------------------------------------------------- */
int essai_get_fmt(char *dev, int k)
{
int vfd, foo;
struct v4l2_format fmt;
// struct v4l2_requestbuffers reqbuf;
fprintf(stderr, ">>> %s ( '%s' %d )\n", __func__, dev, k);
vfd = open_device(dev);
if (verbosity) fprintf(stderr, "\topen %s -> %d\n", dev, vfd);
memset(&fmt, 0, sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
foo = ioctl(vfd, VIDIOC_G_FMT, &fmt);
fprintf(stderr, "%s : ioctl -> %d\n", __func__, foo);
if (0 != foo) {
perror("ioctl G_FMT");
return -1;
}
pr_v4l2_format("after ioctl VIDIOC_G_FMT", &fmt);
/* this function is bugged */
close(vfd);
return k;
}
/* --------------------------------------------------------------------- */
void help(int k)
{
puts("Options :");
puts("\t-d\tselect the video device");
puts("\t-K\tset the K parameter");
puts("\t-v\tincrease verbosity");
if (verbosity) { puts(""); fimg_print_version(1); }
exit(0);
}
/* --------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo, opt;
char *device = "/dev/video0";
int K = 0;
while ((opt = getopt(argc, argv, "d:hK:v")) != -1) {
switch(opt) {
case 'd': device = optarg; break;
case 'h': help(0); break;
case 'K': K = atol(optarg); break;
case 'v': verbosity++; break;
}
}
if (verbosity) fimg_print_version(0);
foo = essai_get_fmt(device, K);
fprintf(stderr, "\tessai -> %d\n", foo);
return 0;
}
/* --------------------------------------------------------------------- */

300
src/v4l2/v4l2_pr_structs.c Normal file
View File

@@ -0,0 +1,300 @@
/*
* fonctions pour afficher les structures de V4L2
*/
#include <stdio.h>
#include <inttypes.h>
#include <linux/videodev2.h>
#include "v4l2_pr_structs.h"
#define FP (stdout)
extern int verbosity;
/* --------------------------------------------------------------------- */
static char *fmttype2str(int type)
{
switch(type) {
case 0: return "[zero]";
case V4L2_BUF_TYPE_VIDEO_CAPTURE: return "video capture";
case V4L2_BUF_TYPE_VIDEO_OUTPUT: return "video output";
case 13: return "META capture";
}
return "XXX";
}
/* --------------------------------------------------------------------- */
static void pr_capabilities(uint32_t caps)
{
fputs(" ", FP);
if (caps & V4L2_CAP_VIDEO_CAPTURE) fputs("vcapt ", FP);
if (caps & V4L2_CAP_VIDEO_OUTPUT) fputs("vout ", FP);
if (caps & V4L2_CAP_VIDEO_OVERLAY) fputs("overlay ", FP);
if (caps & V4L2_CAP_VBI_CAPTURE) fputs("vbicapt ", FP);
if (caps & V4L2_CAP_VBI_OUTPUT) fputs("vbiout ", FP);
/* to be continued */
if (caps & V4L2_CAP_AUDIO) fputs("audio ", FP);
if (caps & V4L2_CAP_SDR_CAPTURE) fputs("sdrcapt ", FP);
if (caps & V4L2_CAP_EXT_PIX_FORMAT) fputs("extpix ", FP);
if (caps & V4L2_CAP_SDR_OUTPUT) fputs("sdrout ", FP);
if (caps & V4L2_CAP_READWRITE) fputs("rwsysc ", FP);
if (caps & V4L2_CAP_ASYNCIO) fputs("asyncio ", FP);
if (caps & V4L2_CAP_STREAMING) fputs("stream ", FP);
fputs("\n", FP);
}
/* --------------------------------------------------------------------- */
int pr_v4l2_capability(char *txt, struct v4l2_capability *ptr)
{
fprintf(FP, "## v4l2_capability, %-15s %p\n", txt, ptr);
fprintf(FP, " driver %s\n", ptr->driver);
fprintf(FP, " card %s\n", ptr->card);
fprintf(FP, " bus info %s\n", ptr->bus_info);
fprintf(FP, " version 0x%X\n", ptr->version);
fprintf(FP, " capabilities 0x%X\n", ptr->capabilities);
pr_capabilities(ptr->capabilities);
fprintf(FP, " device caps 0x%X\n", ptr->device_caps);
return -1;
}
/* --------------------------------------------------------------------- */
/*
* warning, this function return a pointer to a static
* strint, so it was NOT reentrant !
*/
char *str_fourcc(uint32_t fcc)
{
static char chaine[10];
chaine[0] = '['; chaine[5] = ']'; chaine[6] = '\0';
chaine[1] = (fcc>>0) & 0xff;
chaine[2] = (fcc>>8) & 0xff;
chaine[3] = (fcc>>16) & 0xff;
chaine[4] = (fcc>>24) & 0xff;
return chaine;
}
/* --------------------------------------------------------------------- */
char *str_buf_type(int type)
{
switch (type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE: return "vidcapt";
case V4L2_BUF_TYPE_VIDEO_OUTPUT: return "vidout";
case V4L2_BUF_TYPE_VIDEO_OVERLAY: return "vidovrl";
case V4L2_BUF_TYPE_VBI_CAPTURE: return "vbicapt";
case V4L2_BUF_TYPE_VBI_OUTPUT: return "vbicapt";
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: return "slicevcapt";
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: return "slicevout";
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: return "v-outover";
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: return "v-captmpla";
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: return "v-outmpla";
case V4L2_BUF_TYPE_SDR_CAPTURE: return "sdrcapt";
case V4L2_BUF_TYPE_SDR_OUTPUT: return "sdrout";
/* Deprecated, do not use */
case V4L2_BUF_TYPE_PRIVATE: return "private";
}
return "???";
}
/* --------------------------------------------------------------------- */
int pr_v4l2_fmtdesc(char *txt, struct v4l2_fmtdesc *ptr)
{
fprintf(FP, "## v4l2_fmtdesc, %-15s %p\n", txt, ptr);
fprintf(FP, " index %d\n", ptr->index);
fprintf(FP, " type %d\n", ptr->type); /* enum v4l2_buf_type */
fprintf(FP, " flags 0x%X\n", ptr->flags);
fprintf(FP, " description %s\n", ptr->description);
fprintf(FP, " pixel format 0x%X\n", ptr->pixelformat); /* FOURCC */
return -1;
}
/* --------------------------------------------------------------------- */
char *str_input_type(int t)
{
switch (t) {
case V4L2_INPUT_TYPE_TUNER: return "tuner";
case V4L2_INPUT_TYPE_CAMERA: return "camera";
case V4L2_INPUT_TYPE_TOUCH: return "touch";
}
return "???";
}
/* --------------------------------------------------------------------- */
static void pr_input_status(uint32_t st)
{
if (st & V4L2_IN_ST_NO_POWER) fputs("nopow ", FP);
if (st & V4L2_IN_ST_NO_SIGNAL) fputs("nosig ", FP);
if (st & V4L2_IN_ST_NO_COLOR) fputs("nocol ", FP);
if (st & V4L2_IN_ST_HFLIP) fputs("hflip ", FP);
if (st & V4L2_IN_ST_VFLIP) fputs("vflip ", FP);
if (st & V4L2_IN_ST_NO_H_LOCK) fputs("nohlck ", FP);
if (st & V4L2_IN_ST_COLOR_KILL) fputs("colkil ", FP);
if (st & V4L2_IN_ST_NO_V_LOCK) fputs("novlck ", FP);
if (st & V4L2_IN_ST_NO_STD_LOCK) fputs("nostdlk ", FP);
if (st & V4L2_IN_ST_NO_EQU) fputs("noequ ", FP);
if (st & V4L2_IN_ST_NO_CARRIER) fputs("nocarr ", FP);
if (st & V4L2_IN_ST_MACROVISION) fputs("macrov ", FP);
if (st & V4L2_IN_ST_NO_ACCESS) fputs("noacces ", FP);
if (st & V4L2_IN_ST_VTR) fputs("VTR ", FP);
/* to be continued ?*/
}
/* --------------------------------------------------------------------- */
static void pr_input_capabilities(uint32_t st)
{
if (st & V4L2_IN_CAP_DV_TIMINGS) fputs("DVtime ", FP);
if (st & V4L2_IN_CAP_STD) fputs("s_std ", FP);
if (st & V4L2_IN_CAP_NATIVE_SIZE) fputs("nativsz ", FP);
}
/* --------------------------------------------------------------------- */
int pr_v4l2_input(char *txt, struct v4l2_input *ptr)
{
fprintf(FP, "## v4l2_input, %-15s %p\n", txt, ptr);
fprintf(FP, " index %d\n", ptr->index);
fprintf(FP, " name %s\n", ptr->name);
fprintf(FP, " type %d %s\n", ptr->type,
str_input_type(ptr->type));
fprintf(FP, " audioset 0x%X\n", ptr->audioset);
fprintf(FP, " tuner 0x%X\n", ptr->tuner);
/* XXX v4l2_std_id std; */
fprintf(FP, " status 0x%X\n", ptr->status);
if (ptr->status) {
fputs(" ",FP);
pr_input_status(ptr->status);
fputs("\n",FP);
}
fprintf(FP, " capabilities 0x%X\n", ptr->capabilities);
if (ptr->capabilities) {
fputs(" ",FP);
pr_input_capabilities(ptr->capabilities);
fputs("\n",FP);
}
return -1;
}
/* --------------------------------------------------------------------- */
char * str_colorspace(int colspace)
{
switch(colspace) {
case V4L2_COLORSPACE_DEFAULT: return "default";
case V4L2_COLORSPACE_SMPTE170M: return "smpte170m";
case V4L2_COLORSPACE_SMPTE240M: return "smpte240m";
case V4L2_COLORSPACE_REC709: return "rec709";
case V4L2_COLORSPACE_BT878: return "bt878";
case V4L2_COLORSPACE_470_SYSTEM_M: return "470-sys-M";
case V4L2_COLORSPACE_470_SYSTEM_BG: return "470-sys-BG";
case V4L2_COLORSPACE_JPEG: return "jpeg";
case V4L2_COLORSPACE_SRGB: return "srgb";
case V4L2_COLORSPACE_ADOBERGB: return "adobergb";
case V4L2_COLORSPACE_BT2020: return "bt2020";
case V4L2_COLORSPACE_RAW: return "raw";
case V4L2_COLORSPACE_DCI_P3: return "dci-p3";
}
return "???";
}
/* --------------------------------------------------------------------- */
int pr_v4l2_format(char *txt, struct v4l2_format *ptr)
{
fprintf(FP, "## v4l2_format, %-15s %p\n", txt, ptr);
fprintf(FP, " type %d %s\n", ptr->type,/* enum v4l2_buf_type */
fmttype2str(ptr->type));
switch(ptr->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
fprintf(FP, " dims %dx%d\n",
ptr->fmt.pix.width,
ptr->fmt.pix.height);
fprintf(FP, " pixformat %s\n",
str_fourcc(ptr->fmt.pix.pixelformat));
fprintf(FP, " field %d\n",
ptr->fmt.pix.field); /* enum v4l2_field */
fprintf(FP, " padding %d\n",
ptr->fmt.pix.bytesperline);
fprintf(FP, " sizeimage %d\n",
ptr->fmt.pix.sizeimage);
fprintf(FP, " colorspace %d %s\n",
ptr->fmt.pix.colorspace,
str_colorspace(ptr->fmt.pix.colorspace));
break;
default: fprintf(FP, "XXX type %d unknow\n", ptr->type);
break;
}
return 0;
}
/* --------------------------------------------------------------------- */
int pr_v4l2_requestbuffers(char *txt, struct v4l2_requestbuffers *ptr)
{
fprintf(FP, "## v4l2_requestbuffers, %s %p\n", txt, ptr);
fprintf(FP, " type %d\n", ptr->type); /* enum v4l2_buf_type */
return 0;
}
/* --------------------------------------------------------------------- */
char *str_ctrl_type(int type)
{
switch (type) {
case V4L2_CTRL_TYPE_INTEGER: return "integer";
case V4L2_CTRL_TYPE_BOOLEAN: return "boolean";
case V4L2_CTRL_TYPE_MENU: return "menu";
case V4L2_CTRL_TYPE_BUTTON: return "button";
case V4L2_CTRL_TYPE_INTEGER64: return "int64";
case V4L2_CTRL_TYPE_CTRL_CLASS: return "ctrl-class";
case V4L2_CTRL_TYPE_STRING: return "string";
case V4L2_CTRL_TYPE_BITMASK: return "bitmask";
case V4L2_CTRL_TYPE_INTEGER_MENU: return "int-menu";
}
return "???";
}
/* --------------------------------------------------------------------- */
/*
The 32-bit qctrl.id value is subdivided into three bit ranges:
the top 4 bits are reserved for flags (e. g. V4L2_CTRL_FLAG_NEXT_CTRL)
and are not actually part of the ID.
The remaining 28 bits form the control ID, of which the most significant
12 bits define the control class and the least significant
16 bits identify the control within the control class.
*/
void pr_ctrl_id(uint32_t id)
{
if (verbosity>1) fprintf(FP, "%08x : ", id);
fprintf(FP, "%x %03lx %04x", (id>>28)&0xf,
V4L2_CTRL_ID2CLASS(id)>>16, id&0xffff);
}
/* --------------------------------------------------------------------- */
int pr_v4l2_control(char *txt, struct v4l2_control *ptr)
{
return -1;
}
/* --------------------------------------------------------------------- */

View File

@@ -0,0 +1,22 @@
/*
* fonctions pour afficher les structures de V4L2
*
* WARNING : this is a work in progress !
*/
/* --------------------------------------------------------------------- */
int pr_v4l2_capability(char *txt, struct v4l2_capability *ptr);
int pr_v4l2_input(char *txt, struct v4l2_input *ptr);
int pr_v4l2_format(char *txt, struct v4l2_format *ptr);
int pr_v4l2_requestbuffers(char *txt, struct v4l2_requestbuffers *ptr);
int pr_v4l2_fmtdesc(char *txt, struct v4l2_fmtdesc *ptr);
char *str_input_type(int t);
char *str_ctrl_type(int type);
char *str_buf_type(int type);
char *str_fourcc(uint32_t fcc); /* NOT REENTRANT */
void pr_ctrl_id(uint32_t id); /* bit dissector */
/* --------------------------------------------------------------------- */

331
src/v4l2/video-infos.c Normal file
View File

@@ -0,0 +1,331 @@
/*
* tests pour capturer les webcams
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <string.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <inttypes.h>
#include <linux/videodev2.h>
#include "../floatimg.h"
#include "v4l2_pr_structs.h"
#include "funcs.h"
int verbosity;
/* --------------------------------------------------------------------- */
/*
* this code was written from a strace output :)
*/
int enum_image_framesizes(int fd, char *txt, int k)
{
int foo, idx;
struct v4l2_frmsizeenum fmtsz;
printf("## image framesizes enumeration (%s)\n", txt);
for (idx=0; ; idx++) {
memset(&fmtsz, 0, sizeof(fmtsz));
fmtsz.index = idx;
foo = ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &fmtsz);
if (foo) {
if (EINVAL==errno) {
break;
}
else {
perror(__func__);
break;
}
}
printf("%4d %4d %4d\n", idx, fmtsz.pixel_format, fmtsz.type);
}
return 0;
}
/* --------------------------------------------------------------------- */
int enum_image_formats(int fd, char *txt, int k)
{
int foo, idx;
struct v4l2_fmtdesc fmtd;
printf("## image formats enumeration (%s)\n", txt);
idx = 0;
for (;;) {
memset(&fmtd, 0, sizeof(fmtd));
fmtd.index = idx;
fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
foo = ioctl(fd, VIDIOC_ENUM_FMT, &fmtd);
// fprintf(stderr, "B idx=%d, foo=%d, errno=%d\n", idx, foo, errno);
if (foo) {
if (EINVAL==errno) {
break;
}
else {
perror(__func__);
break;
}
}
// pr_v4l2_fmtdesc(__func__, &fmtd);
printf(" %2d %-10s 0x%02x %s %-32s \n",
fmtd.index, str_buf_type(fmtd.type), fmtd.flags,
str_fourcc(fmtd.pixelformat), fmtd.description);
idx++;
}
return -1;
}
/* --------------------------------------------------------------------- */
static int enum_inputs(int fd, char *txt, int k)
{
int index, foo;
struct v4l2_input input;
char ligne[50];
printf("## inputs enumeration (%s)\n", txt);
index = 0;
for(;;) {
memset (&input, 0, sizeof (input));
input.index = index;
foo = ioctl(fd, VIDIOC_ENUMINPUT, &input);
if (foo) {
if (EINVAL==errno) { break; }
else {
perror("enuminput");
return -1;
}
}
if (verbosity) {
sprintf(ligne, "input %d", index);
pr_v4l2_input(ligne, &input);
}
else {
printf("%-32s | %-10s\n", input.name,
str_input_type(input.type));
}
index++;
}
return 0;
}
/* --------------------------------------------------------------------- */
int enum_controls(int fd, char *txt, int k)
{
struct v4l2_queryctrl qctrl;
int idx;
printf("## controls enumeration '%s'\n", txt);
memset (&qctrl, 0, sizeof (qctrl));
/* V4L2_CID_BASE defined in linux/v4l2-controls.h */
for (idx=V4L2_CID_BASE; idx<V4L2_CID_LASTP1; idx++) {
qctrl.id = idx;
// if (verbosity>1) printf(" id %d ", idx);
if (0 == ioctl (fd, VIDIOC_QUERYCTRL, &qctrl)) {
if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
printf("disabled\n");
continue;
}
printf(" %-40s %-10s [%d..%d]\n",
qctrl.name,
str_ctrl_type(qctrl.type),
qctrl.minimum, qctrl.maximum);
}
else if (EINVAL==errno) {
#if DEBUG_LEVEL
if (verbosity) fprintf(stderr, "id %d einval\n", idx);
#endif
continue;
}
else {
printf("err %d %s\n", errno, strerror(errno));
}
fflush(stdout); fflush(stderr);
}
return -1;
}
/* --------------------------------------------------------------------- */
/*
* code based on :
https://www.linuxtv.org/downloads/legacy/video4linux/API/V4L2_API/spec-single/v4l2.html
*
*/
int enum_extended_controls(int fd, char *txt, int k)
{
struct v4l2_queryctrl qctrl;
int idx;
printf("##- extended controls enumeration '%s'\n", txt);
memset(&qctrl, 0, sizeof(qctrl));
qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
idx = 0;
while (0 == ioctl (fd, VIDIOC_QUERYCTRL, &qctrl)) {
if (verbosity) pr_ctrl_id(qctrl.id);
printf(" %-32s %-10s [%d..%d]\n",
qctrl.name,
str_ctrl_type(qctrl.type),
qctrl.minimum, qctrl.maximum);
qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
idx++;
}
return -1;
}
/* --------------------------------------------------------------------- */
int show_webcam_infos(char *devname, char *title, int k, int type)
{
int vfd, foo;
char ligne[100];
struct v4l2_capability cap;
struct v4l2_format fmt;
// struct v4l2_input input;
// int index;
// struct v4l2_requestbuffers reqbuf;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' %d %d)\n", __func__, devname, k, type);
#endif
vfd = open_device(devname);
if (vfd < 0) {
perror(devname);
return -3;
}
fprintf(stderr, "\topen %s -> %d\n", devname, vfd);
memset(&cap, 0, sizeof(cap));
foo = ioctl(vfd, VIDIOC_QUERYCAP, &cap);
if (foo < 0) {
perror("ioctl QUERYCAP");
return -4;
}
pr_v4l2_capability(devname, &cap);
foo = enum_inputs(vfd, "on peut voir quoi ?", 0);
memset(&fmt, 0, sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
foo = ioctl(vfd, VIDIOC_G_FMT, &fmt);
if (0 != foo) {
perror("ioctl G_FMT");
}
else {
pr_v4l2_format("Experimental", &fmt);
}
if (type) {
;
}
else {
foo = enum_image_formats(vfd, "Experimental", 0);
foo = enum_controls(vfd, "is that working ?", 0);
foo = enum_extended_controls(vfd, "looking for extended", 0);
enum_image_framesizes(vfd, "code pas fini", 0);
}
close(vfd);
return 0;
}
/* --------------------------------------------------------------------- */
int liste_des_devices(int flag)
{
fprintf(stderr, "%s not implemented\n", __func__);
return -1;
}
/* --------------------------------------------------------------------- */
static void help(int k)
{
puts("Options :");
puts("\t-e N\t\texamine that, please");
puts("\t-d\t\tselect the video device");
puts("\t-K\t\tset the K parameter");
puts("\t-l\t\tlist video devices");
puts("\t-T bla\t\tadd a title");
puts("\t-v\t\tincrease verbosity");
// if (verbosity)
{ puts(""); fimg_print_version(1); }
exit(0);
}
/* --------------------------------------------------------------------- */
static void print_title(char *txt)
{
int foo, l;
l = strlen(txt);
for (foo=0; foo<l+18; foo++)
putchar('*');
puts("");
printf("****** %s ******\n", txt);
for (foo=0; foo<l+18; foo++)
putchar('*');
puts("\n");
}
/* --------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo, opt;
int etype = 0;
char *device = "/dev/video0";
char *title = NULL;
int K = 0;
while ((opt = getopt(argc, argv, "d:e:hK:lT:v")) != -1) {
switch(opt) {
case 'd': device = optarg; break;
case 'e': etype = atol(optarg); break;
case 'h': help(0); break;
case 'K': K = atol(optarg); break;
case 'l': liste_des_devices(0); break;
case 'T': title = optarg; break;
case 'v': verbosity++; break;
}
}
if (NULL != title) {
print_title(title);
}
foo = show_webcam_infos(device, "", K, etype);
fprintf(stderr, "\n\tshow_webcam_infos -> %d\n", foo);
return 0;
}
/* --------------------------------------------------------------------- */