forked from tTh/FloatImg
source tree refactor and build system (to be completed)
This commit is contained in:
234
src/floatimg.h
Normal file
234
src/floatimg.h
Normal 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
138
src/funcs/Makefile
Normal 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
26
src/funcs/README.md
Normal 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
33
src/funcs/alltests.sh
Executable 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
103
src/funcs/classif.c
Normal 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
95
src/funcs/contour2x2.c
Normal 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
92
src/funcs/displacement.c
Normal 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
31
src/funcs/dithering.c
Normal 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
53
src/funcs/equalize.c
Normal 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
73
src/funcs/exporter.c
Normal 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
200
src/funcs/filtrage.c
Normal 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
21
src/funcs/fimg-bmp.c
Normal 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
114
src/funcs/fimg-fits.c
Normal 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
52
src/funcs/fimg-libpnm.c
Normal 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
30
src/funcs/fimg-openexr.c
Normal 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
220
src/funcs/fimg-png.c
Normal 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
89
src/funcs/fimg-tiff.c
Normal 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
180
src/funcs/geometry.c
Normal 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
95
src/funcs/histogram.c
Normal 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
161
src/funcs/hsv.c
Normal 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
93
src/funcs/incrustator.c
Normal 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
104
src/funcs/misc-plots.c
Normal 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
43
src/funcs/plasmas.c
Normal 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
128
src/funcs/qsortrgb.c
Normal 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
63
src/funcs/rampes.c
Normal 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
26
src/funcs/recurse.c
Normal 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
72
src/funcs/rotate.c
Normal 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
109
src/funcs/saturation.c
Normal 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
89
src/funcs/sfx0.c
Normal 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
106
src/funcs/sfx1.c
Normal 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
94
src/funcs/sfx2.c
Normal 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
231
src/funcs/t.c
Normal 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
830
src/funcs/tests.c
Normal 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
32
src/funcs/tests.h
Normal 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
28
src/funcs/tpnm.c
Normal 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
140
src/funcs/utils.c
Normal 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
43
src/funcs/vroum.sh
Executable 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
72
src/lib/Makefile
Normal 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
176
src/lib/contrast.c
Normal 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
80
src/lib/fimg-2gray.c
Normal 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
42
src/lib/fimg-compare.c
Normal 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
367
src/lib/fimg-core.c
Normal 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
217
src/lib/fimg-file.c
Normal 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
321
src/lib/fimg-math.c
Normal 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(j−1))
|
||||
| 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
197
src/lib/fimg-pnm.c
Normal 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
42
src/lib/fimg-timers.c
Normal 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
75
src/lib/interpolate.c
Normal 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
216
src/lib/operators.c
Normal 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
32
src/lib/runme.sh
Executable 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
273
src/lib/t.c
Normal 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, ©, 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, ©, maxi);
|
||||
maxi = (double)fimg_get_maxvalue(©);
|
||||
fprintf(stderr, "apres power_2 valeur maxi = %f\n", maxi);
|
||||
fimg_save_as_pnm(©, "power2.pnm", 0);
|
||||
|
||||
fimg_square_root(&dessin, ©, maxi);
|
||||
maxi = (double)fimg_get_maxvalue(©);
|
||||
fprintf(stderr, "apres square_root valeur maxi = %f\n", maxi);
|
||||
fimg_save_as_pnm(©, "squareroot.pnm", 0);
|
||||
|
||||
fimg_cos_01(&dessin, ©, maxi);
|
||||
maxi = (double)fimg_get_maxvalue(©);
|
||||
fprintf(stderr, "apres cos 01 valeur maxi = %f\n", maxi);
|
||||
fimg_save_as_pnm(©, "cos_01.pnm", 0);
|
||||
|
||||
fimg_cos_010(&dessin, ©, maxi);
|
||||
maxi = (double)fimg_get_maxvalue(©);
|
||||
fprintf(stderr, "apres cos 010 valeur maxi = %f\n", maxi);
|
||||
fimg_save_as_pnm(©, "cos_010.pnm", 0);
|
||||
|
||||
fimg_destroy(&dessin); fimg_destroy(©);
|
||||
|
||||
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
81
src/tools/Makefile
Normal 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
20
src/tools/README.md
Normal 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
90
src/tools/addpnm2fimg.c
Normal 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
99
src/tools/addtga2fimg.c
Normal 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
134
src/tools/cumulfimgs.c
Normal 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
66
src/tools/fimg2fits.c
Normal 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
98
src/tools/fimg2png.c
Normal 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
126
src/tools/fimg2pnm.c
Normal 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
178
src/tools/fimg2text.c
Normal 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
98
src/tools/fimg2tiff.c
Normal 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
305
src/tools/fimgfx.c
Normal 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
95
src/tools/fimghalfsize.c
Normal 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
191
src/tools/fimgops.c
Normal 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
117
src/tools/fimgstats.c
Normal 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
165
src/tools/mkfimg.c
Normal 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
62
src/tools/png2fimg.c
Normal 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
38
src/v4l2/Makefile
Normal 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
32
src/v4l2/README.md
Normal 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
13
src/v4l2/README.txt
Normal 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
670
src/v4l2/capture.c
Normal 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
12
src/v4l2/essai.sh
Executable 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
42
src/v4l2/exemple.txt
Normal 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
329
src/v4l2/funcs.c
Normal 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
20
src/v4l2/funcs.h
Normal 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
427
src/v4l2/grabvidseq.c
Normal 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
130
src/v4l2/nc-camcontrol.c
Normal 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
25
src/v4l2/notes.txt
Normal 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
135
src/v4l2/rgb2fimg.c
Normal 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
91
src/v4l2/t.c
Normal 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
300
src/v4l2/v4l2_pr_structs.c
Normal 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;
|
||||
}
|
||||
/* --------------------------------------------------------------------- */
|
||||
22
src/v4l2/v4l2_pr_structs.h
Normal file
22
src/v4l2/v4l2_pr_structs.h
Normal 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
331
src/v4l2/video-infos.c
Normal 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;
|
||||
}
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user