Compare commits

..

5 Commits

172 changed files with 1035 additions and 6061 deletions

98
.gitignore vendored
View File

@ -1,23 +1,18 @@
lib/*.o
lib/t
lib/*.fimg
lib/*.png
lib/*.gif
build
# src/lib/*.o
src/lib/t
src/lib/*.fimg
src/lib/*.png
src/lib/*.gif
*.o
*.a
gmon.out
cscope.out
*.swp
*.pnm
*.pgm
*.fimg
essai
MANIFEST
tarball
*/*.ps
doc/*.toc
@ -30,41 +25,62 @@ doc/*.ind
doc/co*.tex
doc/foo.html
funcs/t
funcs/*.o
funcs/*.png
funcs/V/*
funcs/*.gif
funcs/*.fits
funcs/*.tiff
funcs/toto
src/funcs/t
src/funcs/*.o
src/funcs/*.png
src/funcs/V/*
src/src/funcs/*.gif
src/funcs/*.fits
src/funcs/*.tiff
src/funcs/toto
scripts/*.fimg
scripts/*.pnm
scripts/*.gif
v4l2/t
v4l2/capture
v4l2/grabvidseq
v4l2/*.o
v4l2/*.ppm
v4l2/*.png
v4l2/*.fits
v4l2/*.tiff
v4l2/video-infos
v4l2/nc-camcontrol
src/v4l2/t
src/v4l2/capture
src/v4l2/grabvidseq
src/v4l2/*.o
src/v4l2/*.ppm
src/v4l2/*.png
src/v4l2/*.fits
src/v4l2/*.tiff
src/v4l2/video-infos
src/v4l2/nc-camcontrol
# tools/fimg2png
# tools/fimg2pnm
# tools/fimg2tiff
# tools/fimg2fits
# tools/fimg2text
# tools/fimgstats
# tools/fimghalfsize
# tools/mkfimg
# tools/png2fimg
# tools/addtga2fimg
# tools/addpnm2fimg
# tools/cumulfimgs
# tools/fimgops
# tools/fimgfx
src/tools/*.png
src/tools/*.tiff
Fonderie/*.o
Fonderie/*.png
Fonderie/*.pnm
Fonderie/*.gif
Fonderie/*.fimg
Fonderie/fonderie
Fonderie/interpolator
Fonderie/t
Fonderie/singlepass
Fonderie/crapdef.h
Fonderie/crapstr.h
extras/Fonderie/*.o
extras/Fonderie/*.png
extras/Fonderie/*.pnm
extras/Fonderie/*.gif
extras/Fonderie/*.fimg
extras/extras/Fonderie/fonderie
extras/Fonderie/interpolator
extras/Fonderie/t
extras/Fonderie/singlepass
extras/Fonderie/crapdef.h
extras/Fonderie/crapstr.h
extras/experiment/assemblage
extras/experiment/extracteur
extras/experiment/*.fimg
extras/experiment/*.pnm
extras/experiment/*.o

View File

@ -1,28 +0,0 @@
#!/usr/bin/awk -f
#
# this utility script make a file who
# is includet by 'crapulator.c'
#
BEGIN {
print "// -------------------------------------"
print "// generated file, do not edit by hand !";
print "// -------------------------------------"
print "Crapulor CrapL[] = {";
}
# $1 is the badly brain-designed numeric id
# $2 is the user name of the filter
# $3 and $4 are two not used parameters
#
{
name = sprintf("CR_%s", $2)
printf " { %-14s, \"%s\", %d, %f }, // #%d\n",
name, $2, $3, $4, $1;
}
END {
print " { -1, NULL }"
print " };"
print "// ! generated file, do not edit by hand !"
}

View File

@ -1,6 +0,0 @@
#
# This file is the 'grandmasta' of the compilation process.
# for now, this is juste a wip idea.
#

14
LICENSE
View File

@ -1,14 +0,0 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

View File

@ -1,37 +1,77 @@
####################################################
# Before running make, you must have #
# a look to the 'build.sh' script ! #
####################################################
# CC_OPTS = -Wall -fpic -g -pg -no-pie -DDEBUG_LEVEL=0
# LD_OPTS = libfloatimg.a -pg -lm
COPT = -Wall -Wextra -fpic -g -no-pie -DDEBUG_LEVEL=0
LDOPT = libfloatimg.a -g -lm
LIB_DIR = build/lib
all: essai
OBJ_DIR = build/obj
#---------------------------------------------------------------
STATIC_LIB = $(LIB_DIR)/libfloatimg-lib.a
essai: essai.c libfloatimg.a floatimg.h Makefile
gcc $(COPT) $< $(LDOPT) -lpnglite -lz -o $@
DYN_LIB = $(LIB_DIR)/libfloatimg.so
install:
@echo "=== Use the 'install.sh' script ==="
VERBOSITY = 0
#---------------------------------------------------------------
all: lib funcs tools v4l2
TOTAR = *.[ch] Makefile *.sh *.md \
doc/the*.tex doc/mk*.sh doc/*.txt \
funcs/*.[ch] funcs/Makefile \
tools/*.[ch] tools/*.sh tools/README.md tools/Makefile \
v4l2/*.[ch] v4l2/Makefile \
scripts/*.sh scripts/README.md \
lib/*.[ch] lib/Makefile
# shared: $(DYN_LIB)
lines: $(TOTAR)
@wc $(TOTAR) | sort -n
# $(DYN_LIB): lib funcs
tarball: $(TOTAR)
date > tarball
ls $(TOTAR) | sed 's/^/FloatImg\//' > MANIFEST
( cd .. ; tar zcvf floatimg.tar.gz `cat FloatImg/MANIFEST` )
lib:
$(MAKE) -C src/lib all
funcs: lib
$(MAKE) -C src/funcs
# link lib & funcs for shared library
echo "int verbosity = $(VERBOSITY);" > $(OBJ_DIR)/verbosity.c
gcc -c $(OBJ_DIR)/verbosity.c -o $(OBJ_DIR)/verbosity.o
gcc -shared $(OBJ_DIR)/*.o -lnetpbm -lpnglite -lcfitsio -ltiff -lz -lm -o $(DYN_LIB)
tools: lib
mkdir -p build/bin
$(MAKE) -C src/tools
v4l2:
mkdir -p build/bin
$(MAKE) -C src/v4l2
clean:
$(MAKE) -C src/lib clean
$(MAKE) -C src/funcs clean
$(MAKE) -C src/tools clean
$(MAKE) -C src/v4l2 clean
rm -rf "./build"
install: all
cp src/floatimg.h /usr/local/include
cp build/lib/* /usr/local/lib
cp build/bin/* /usr/local/bin
# all: essai
# #---------------------------------------------------------------
# essai: essai.c libfloatimg.a floatimg.h Makefile
# gcc $(COPT) $< $(LDOPT) -lpnglite -lz -o $@
# #---------------------------------------------------------------
# TOTAR = *.[ch] Makefile *.sh *.md \
# doc/the*.tex doc/mk*.sh doc/*.txt \
# funcs/*.[ch] funcs/Makefile \
# tools/*.[ch] tools/*.sh tools/README.md tools/Makefile \
# v4l2/*.[ch] v4l2/Makefile \
# scripts/*.sh scripts/README.md \
# lib/*.[ch] lib/Makefile
# lines: $(TOTAR)
# @wc $(TOTAR) | sort -n
# tarball: $(TOTAR)
# date > tarball
# ls $(TOTAR) | sed 's/^/FloatImg\//' > MANIFEST
# ( cd .. ; tar zcvf floatimg.tar.gz `cat FloatImg/MANIFEST` )
# #---------------------------------------------------------------
#---------------------------------------------------------------

View File

@ -1,3 +1,14 @@
# FloatImg4PythonBinding
Un fork de la galactique bibliothèque FloatImg de tTh, réaménagé pour permettre une utilisation depuis Python avec l'embryonnaire binding https://git.tetalab.org/Mutah/python-FloatImg/ (seulement sur la branche develop pour le moment)
Pas de révolution mais :
- production d'une bibliothèque partagée
- arborescence remanié : les meubles ont changés de place : les sources sont dans `src`, les expérimentations dans `extra` et les binaires sont produits dans `build`
- build system : un Makefile racine avec des cibles générales : `all` pour tout builder, `lib` pour la bibliothèque de base, `funcs`
# Traitement des images en virgule flottante.
C'est d"abord un ensemble de fonctions pour traiter des images avec une énorme dynamique
@ -15,7 +26,7 @@ pour les codeurs.
Le service après-vente est (plus ou moins bien) assuré sur
la [mailing list](https://lists.tetalab.org/mailman/listinfo/tetalab) et/ou
le canal IRC #tetalab sur le réseau de
[Libera.Chat](https://libera.chat/)...
[Freenode](https://webchat.freenode.net/)...
Par ailleurs, d'autres expérimentations sont
[en cours](http://la.buvette.org/photos/cumul/fonderie/vidz.html#interpolator)
@ -30,36 +41,16 @@ Bien entendu, avant tout, il faut installer quelques outils et
dépendances. Je vais tenter de les lister dans le plus grand
désordre (à la sauce Debian) :
```
apt install libtiff-dev
apt install libpnglite-dev
apt install liblo-dev
apt install libv4l2-dev
apt install libcfitsio-dev
apt install libnetpbm-dev
```bash
sudo apt install libtiff-dev libpnglite-dev liblo-dev libv4l2-dev libcfitsio-dev libnetpbm-dev
```
Bon, OK, je suis en train de changer de machine, et ça serait vraiment
cool d'avoir juste une ligne à c'n'p, donc voila :
Sauce Ubuntu :
```
apt install libtiff-dev libpnglite-dev liblo-dev libv4l2-dev \
libcfitsio-dev libnetpbm-dev
```bash
sudo apt install libtiff-dev libpnglite-dev liblo-dev libv4l-dev libcfitsio-dev libnetpbm10-dev libncurses5-dev
```
Il est probable que j'en oublie.
Et ya Debian qui change des trucs, alors, ça marche plus, du
genre que c'est la deuxième fois que ça m'arrive.
```
E: Unable to locate package libv4l2-dev
E: Unable to locate package libnetpbm-dev
```
Ensuite, j'ai dans l'idée de construire
um meta-packet à la sauce Debian pour installer facilement tout ce
qui sert à faire fonctionner ce kluge. Ensuite, j'irais voir du
coté de pkg-config.
Certains outils externes sont aussi utiles :

View File

@ -1,39 +0,0 @@
#!/bin/bash
# ------------------------------------------------------------------
function build
{
echo "============= $1 =============="
curdir=${PWD}
cd $1
make
error=$?
cd ${curdir}
if [ ${error} -ne 0 ]
then
echo "=== error on $1 = ${error}"
exit 1
fi
}
# ------------------------------------------------------------------
build lib
build funcs
build tools
build v4l2
build Fonderie
# ------------------------------------------------------------------
echo "========== Project root ==============="
make
# ------------------------------------------------------------------

14
contrib/.gitignore vendored
View File

@ -1,14 +0,0 @@
fimg2povhf
demo_fmorph
toto
core
*.tga
*.png
*.pnm
*.gif
*.fimg
*.mp4

View File

@ -1,18 +0,0 @@
DBGL = -DDEBUG_LEVEL=1 -g
fimg2povhf: fimg2povhf.c Makefile
gcc -Wall $(DBGL) $< -limage -lfloatimg -lm -o $@
# --------------------------------------------------------
demo_fmorph: demo_fmorph.c Makefile
gcc -Wall $(DBGL) $< -lfloatimg -lpnglite -lm -o $@
in.fimg: Makefile
mkfimg -t tpat0 -v $@ 640 480
out.png: in.fimg demo_fmorph
./demo_fmorph $< $@
# --------------------------------------------------------

View File

@ -1,14 +0,0 @@
# Contributions
## fimg2povhf
Need some external garbage, sorry.
## do_eff_spass.sh
Script shell permettant (en théorie) de faire un montage
d'une petite séquence de chacun des effets disponibles
dans la Fonderie. `singlepass` inside.

View File

@ -1,116 +0,0 @@
/*
* DEMONSTRATOR FOR FMORPHO
*/
#include <stdio.h>
#include <stdlib.h>
#include <floatimg.h>
int verbosity = 1;
#define DF_W 512
#define DF_H 128
/* ~~~ -------------------------------------------------------------- +++ */
int demo_fmorph(char *srcf, char *dsti, int mode)
{
FloatImg simg, // image source
timg, uimg, // intermediaires
dimg; // destination
FimgArea51 rect;
char line[200];
int foo, pass, hpos;
fprintf(stderr, ">>> %s ( '%s' '%s' %d )\n", __func__, srcf, dsti, mode);
/*
* chargement image source
*/
foo = fimg_create_from_dump(srcf, &simg);
fprintf(stderr, " load of %s --> %d\n", srcf, foo);
if (foo) {
return foo;
}
/*
* images temporaires
*/
foo = fimg_create(&timg, DF_W, DF_H, FIMG_TYPE_RGB);
if (foo) {
fprintf(stderr, "err %d create T img\n", foo);
return foo;
}
foo = fimg_create(&uimg, DF_W, DF_H, FIMG_TYPE_RGB);
if (foo) {
fprintf(stderr, "err %d create U img\n", foo);
return foo;
}
/*
* image de destination
*/
foo = fimg_create(&dimg, DF_W, DF_H*9, FIMG_TYPE_RGB);
if (foo) {
fprintf(stderr, "err %d create D img\n", foo);
return foo;
}
/*
* this is an iterator
*/
rect.x = 20; rect.y = 20;
rect.w = DF_W; rect.h = DF_H;
for (pass=0; pass<9; pass++) {
hpos = pass * DF_H;
fprintf(stderr, "pass %d, hpos %d\n", pass, hpos);
foo = fimg_extractor(&simg, &timg, &rect);
// sprintf(line, "S_%02d.png", pass);
// foo = fimg_save_as_png(&timg, line, 0);
foo = fimg_filtre_morpho_0(&timg, &uimg, pass);
if (foo) {
fprintf(stderr, "err %d filtre morpho, pass %d\n",
foo, pass);
exit(1);
}
sprintf(line, "D_%02d.png", pass);
foo = fimg_save_as_png(&uimg, line, 0);
foo = fimg_incrustator_0(&uimg, &dimg, 0, hpos, 0);
if (foo) {
fprintf(stderr, "err %d incrustator\n", foo);
exit(1);
}
}
foo = fimg_save_as_png(&dimg, dsti, 0);
/*
* do some cleanup
*/
fimg_destroy(&simg); fimg_destroy(&timg); fimg_destroy(&dimg);
return 0;
}
/* ~~~ -------------------------------------------------------------- +++ */
int main(int argc, char *argv[])
{
int foo;
fimg_print_version(1);
if (3 != argc) {
fprintf(stderr, "usage:\n\t%s src.fimg dst.png\n", argv[0]);
exit(1);
}
foo = demo_fmorph(argv[1], argv[2], 0);
fprintf(stderr, " got --> %d\n", foo);
return 0;
}
/* ~~~ -------------------------------------------------------------- +++ */

View File

@ -1,163 +0,0 @@
#!/bin/bash
set -e
SPASS="../Fonderie/singlepass"
SRCDIR=$HOME"/Essais/PS-eye/frames/"
DSTPOL=$HOME"/TMP/"
echo "source = " $SRCDIR
echo "spool = " $DSTPOL
LINKFARM=$DSTPOL"LinkFarm"
echo "linkfarm = " $LINKFARM
# VIDZ="$HOME/BU/vrac/all_effects.mp4"
VIDZ="foo.mp4"
echo "lolvidz = " $VIDZ
LINKNUM=0
# --------------------------------------------
do_an_effect_pass()
{
local effect=$1
local ddir=$2
figlet "$effect" ; echo
echo " files to ===> " $ddir
rm -f $ddir/?????.png
$SPASS -F $effect \
-g $SRCDIR/'?????.fimg' \
-O $ddir \
-r 1
}
# --------------------------------------------
insert_blank()
{
local count=$1
local imgname="$DSTPOL/blank.fimg"
if [ ! -r $imgname ] ; then
mkfimg -v -t black $imgname 640 480
fimg2png -v $imgname $DSTPOL/blank.png
echo "blankimage done" | boxes
# display $DSTPOL/blank.png &
# exit
fi
for foo in $(seq 0 $count)
do
linkname=$(printf "%s/L%05d.png" $LINKFARM $LINKNUM)
ln --force --symbolic $DSTPOL/blank.png $linkname
# file $linkname
LINKNUM=$(( LINKNUM + 1 ))
done
}
# --------------------------------------------
make_the_linkfarm_from()
{
local effname=$1
local sdir=$2
echo "====== Linkfarming from " $sdir \
"====== avec" $(ls $sdir | wc -l) "images"
mogrify \
-font Utopia-Bold \
-pointsize 64 \
-kerning 9 \
-fill Gray90 \
-stroke Gray10 \
-strokewidth 2 \
-gravity South-East \
-annotate +30+20 $effname \
$sdir/*.png
for img in $(ls -1 $sdir/?????.png)
do
linkname=$(printf "%s/L%05d.png" $LINKFARM $LINKNUM)
# echo "image = " $img
# echo "link = " $linkname
ln --force --symbolic $img $linkname
LINKNUM=$(( LINKNUM + 1 ))
done
echo " linkfarming done"
}
# --------------------------------------------
# traite tous les effets
do_all_the_effects()
{
EFFECTS=$( $SPASS -L | sort )
banner 'FULL RUN'
for effect in $EFFECTS
do
DDIR=$DSTPOL"/$effect"
if [ -d $DDIR ] ; then
rm -f $DDIR"/?????.png"
fi
if [ ! -r $DDIR ] ; then
mkdir -v $DDIR
fi
do_an_effect_pass $effect $DDIR
make_the_linkfarm_from $effect $DDIR
insert_blank 30
done
}
# --------------------------------------------
debug_run()
{
local eff=$1
local DDIR=$DSTPOL"/$eff"
banner 'DEBUG RUN'
echo "DDIR = " $DDIR
do_an_effect_pass $eff $DDIR
make_the_linkfarm_from $eff $DDIR
}
# --------------------------------------------
# MAIN
echo
rm -v -f $LINKFARM/L*.png ; echo
insert_blank 30
# debug_run 'rndblks'
do_all_the_effects
banner 'encoding'
ffmpeg -nostdin \
-loglevel warning \
-y -r 30 -f image2 -i ${LINKFARM}/L%05d.png \
-metadata artist='---[ tTh ]---' \
-metadata title='---[ All the 'Fonderie' effects ]---' \
-preset veryslow \
-c:v libx264 -pix_fmt yuv420p \
$VIDZ
echo " encoding of " $VIDZ " . . . . . [done]"

View File

@ -1,116 +0,0 @@
/*
* convertir une image flottante en champ d'altitude
*
* nouveau 64 ernest renan - 20220108
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "tthimage.h"
#include "floatimg.h"
int verbosity;
/* ------------------------------------------------------------------ */
int This_is_the_real_conversion(FloatImg *fimg, Image_Desc *hf, int k)
{
int foo;
float minmax[6];
int x, y, h;
float rgb[6], cumul;
float maxi;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__, fimg, hf, k);
#endif
foo = fimg_get_minmax_rgb(fimg, minmax);
// fimg_print_minmax(minmax, "source");
maxi = 0.0;
for (y=0; y<fimg->height; y++) {
for (x=0; x<fimg->width; x++) {
foo = fimg_get_rgb(fimg, x, y, rgb);
/* non-magic nuabmer spotted */
cumul = 1.732 * (rgb[1] + rgb[3] + rgb[5]);
if (cumul > maxi) maxi = cumul;
h = (int)cumul;
foo = Image_hf15_plot(hf, x, y, h);
}
}
fprintf(stderr, "--- the critical maximum is %f\n", maxi);
return FULL_NUCKED;
}
/* ------------------------------------------------------------------ */
int Convertir_Fimg_to_Povhf(char *fimgname, char *hfname, int k)
{
FloatImg fimg;
Image_Desc *hf;
int wid, hei;
int foo;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %s %s %d )\n", __func__, fimgname, hfname, k);
#endif
foo = fimg_create_from_dump(fimgname, &fimg);
fprintf(stderr, "load of %s --> %d\n", fimgname, foo);
if (foo) {
return foo;
}
wid = fimg.width; hei = fimg.height; // nice alias
fprintf(stderr, " source picture size %dx%d\n", wid, hei);
hf = Image_alloc(wid, hei, IMAGE_RGB);
fprintf(stderr, "hf alloc -> %p\n", hf);
if (NULL == hf) {
return NULL_POINTER;
}
foo = This_is_the_real_conversion(&fimg, hf, k);
fprintf(stderr, "real conversion -> %d\n", foo);
foo = Image_TGA_save(hfname, hf, 0);
fprintf(stderr, "export as tga -> %d\n", foo);
return FULL_NUCKED;
}
/* ------------------------------------------------------------------ */
void help(int nu)
{
printf("usage :\n");
printf("\t$ fimg2povhf src.fimg dst.tga\n");
}
/* ------------------------------------------------------------------ */
int main(int argc, char *argv[])
{
int foo;
verbosity = 1;
// printf("%s: argc = %d\n", argv[0], argc);
if (3 != argc) {
help(0);
exit(0);
}
if (verbosity > 1) {
Image_print_version(3);
fimg_print_version(3);
}
foo = Convertir_Fimg_to_Povhf(argv[1], argv[2], 0);
fprintf(stderr, "retour conversion was %d\n", foo);
fprintf(stderr, "end\n\n");
return 0;
}
/* ------------------------------------------------------------------ */

View File

@ -1,31 +0,0 @@
#!/bin/bash
src="/dev/shm/foo.fimg"
dst="hf.tga"
TMPDIR=${HOME}/TMP
POVOPT="-w512 -h342 +q9 -a "
rm $TMPDIR/hf???.png
for idx in $(seq 0 60)
do
echo "========================== " $idx
grabvidseq -v \
-d /dev/video0 -s 640x480 \
-n 60 -p 1.0 \
-o ${src}
./fimg2povhf $src $dst
out=$(printf "%s/hf%03d.png" $TMPDIR $idx)
echo "raytracing " ${POVOPT} $out
povray -iscene.pov ${POVOPT} -o${out} 2> pov.stderr
# tail -15 pov.stderr
done
convert -delay 10 -colors 240 $TMPDIR/hf???.png foo.gif

View File

@ -1,41 +0,0 @@
/* scene demo conversion floatimg -> height field */
#version 3.7;
global_settings {
ambient_light rgb <0.07, 0.07, 0.07>
assumed_gamma 1.0
}
#include "colors.inc"
height_field {
tga "hf.tga"
smooth
pigment { color Orange*0.7 }
translate <-0.5, 0, -0.5>
// scale 2
translate y*0.002
}
camera {
location <-0.86, 4, -6.20>
look_at <0, 0, 0>
angle 14
}
plane {
<0, 1, 0>, 0
pigment {
hexagon
pigment { color Gray20 },
pigment { color Gray10 },
pigment { color Gray30 }
}
scale 0.27
}
light_source { <-9, 2, 3> color White }

View File

@ -1,14 +1,7 @@
#!/bin/bash
#
# this script generate some picz for the PDF documentation
# and was called by mkdoc.sh
#
PI=" 3.141592654 "
# ---------------------------------------------------
OUT="cos01.tex"
gnuplot << __EOF__
@ -31,8 +24,6 @@ __EOF__
wc $OUT
# ---------------------------------------------------
OUT="cos010.tex"
gnuplot << __EOF__
@ -54,5 +45,3 @@ plot \
__EOF__
wc $OUT
# ---------------------------------------------------

View File

@ -10,7 +10,7 @@
% \lstset{frame=single} % dessin d'un cadre autour du listing
\lstset{basicstyle=\ttfamily\small}
\lstset{aboveskip=0.01em,belowskip=0.1em}
\lstset{aboveskip=0.1em,belowskip=0.1em}
\usepackage{babel} % ?
@ -25,10 +25,8 @@
% \usepackage{url}
\usepackage{xspace}
\usepackage[verbose]{layout}
\usepackage{ulem}
\setlength \parskip {0.15em}
\setcounter{tocdepth}{1} % XXX à regarder un de ces jours ?
\setlength \parskip {0.35em}
\makeatletter
% explication de ce truc ?
@ -43,7 +41,7 @@
\makeindex
% ------ a few new commands
\newcommand{\interparagraphe { \vspace{50pt} } }
\newcommand{\interparagraphe { \vspace{60pt} } }
% -------------------------------------------------------------------
\title{Floating images processing (for fun and profit ?)}
@ -54,8 +52,6 @@
\section*{Une image flottante ?}
\textsl{Back in a far past part of history.}
\textsl{Mais de quoi parle-t-on exactement ?}
% XXX XXX XXX\vspace{1em}
@ -73,21 +69,15 @@ chaque pixel en virgule flottante sur 32bits, le type
% XXX XXX XXX\vspace{1em}
\textbf{Attention !} tout le code que nous allons voir ensemble est en
perpétuelle évolution\footnote{voir page \pageref{TODO} pour les détails},
perpétuelle évolution\footnote{voir page \pageref{TODO}},
et sa fiablité (surtout sur certains aspects mathématiques)
reste à démontrer\index{valgrind}.
Mais le service après-vente est assez réactif. Du moins
pour ceux qui suivent le canal \texttt{\#tetalab} sur le réseau
IRC de \textsl{libera.chat}.
IRC de Freenode.
\textbf{Attention !} ce document commence par une bonne rafale
de technique parfois \textsl{hardue}\footnote{hard + ardue = private
joke Usenet}, avec des pointeurs dedans, mais vous êtes déja
au courant.
Le pointeur, c'est bien, c'est comme le doigt sur les écrans
de zombiephones, ça sert juste à dire «~C'est là !~», c'est
donc gravement utile, mais parfois, le doigt glisse.
Et là, tout peut arriver.
de technique parfois \textsl{hardue}.
Vous avez parfaitement le droit de sauter directement à
la page \pageref{outils} pour quelque chose de plus concret.
@ -102,7 +92,7 @@ certains points. Je vais tenter de répondre à ces FAQ~:%
« Fréquentes et Absurdes Questions » avec des réponses
absurdes et précises.
\subsubsection*{c'est quoi une image d'un point de vue physique ?}
\subsubsection*{c'est quoi un image d'un point de vue physique ?}
Une représentation approximative d'un monde physique invisible.
L'infinie bio-complexité de notre système oculaire et ses interactions
@ -113,7 +103,7 @@ physique.
Les détails techniques sur cette représentation sont en page
\pageref{FloatImg desc}, avec des pointeurs dedans.
Ah, les pointeurs, la pire chose du monde, mais pourquoi s'en passer\dots
Ah, les pointeurs, la pire chose du monde\dots
\subsubsection*{quelques rappels de comment on acquiert et numérise une image}
@ -132,13 +122,13 @@ dans les machin-trocs, et un grain d'image vraiment présent.
Ah vous en voulez de la technique ? Oké, on y va.
En fait, on va tripoter pleins de nombres, plus ou moins rangés dans
des champs de pixels, pour concrétiser l'existence perceptuelle de ces
des pixels, pour concrétiser l'existence perceptuelles de ces
grains de lumière chromatisés.
\subsubsection*{quelques belles images / schémas polychromes en intro pour
illustrer tout ça}
Tour cela est dans le grand Ternet
Tour cela est dans le grand Ternet\footnote{\textsl{Thanks, mister J Postel}}
mondial, je pourrais même vous donner l'url si vous me promettez de ne pas
la glisser dans le capitalisme de surveillance.
@ -146,22 +136,20 @@ la glisser dans le capitalisme de surveillance.
\setlength \parskip {0em}
\pagebreak
\tableofcontents
\pagebreak
\setlength \parskip {0.40em}
% XXX \layout \pagebreak
\layout \pagebreak
% ===================================================================
\section{Théorie}\index{théorie}
Pour le moment, seule la quête de l'empirisme absolu a été
visée. Les justifications mathématiques attendront le retour
du schmod777. Ceci dit, rien ne nous empêche d'aller consulter
Wikipedia, afin de mieux connaitre ces nombres flottants
que nous allons utiliser~:
Wikipedia~:
\begin{quotation}
An IEEE 754 32-bit base-2 floating-point variable has
@ -176,35 +164,22 @@ officially referred to as binary32; it was called single in
IEEE 754-1985.
\end{quotation}
% XXX
% Ce qui nous conduit à estimer qu'il est possible de cumuler environ
% quelques milliers d'images standard à 256 niveaux, sans trop avoir
% à se soucier des éventuelles pertes de précision. Mais ça demande
% à être confirmé par des esprits supérieurs.
https://dl.acm.org/doi/pdf/10.1145/103162.103163
Ce qui nous conduit à estimer qu'il est possible de cumuler environ
quelques milliers d'images standard à 256 niveaux, sans trop avoir
à se soucier des éventuelles pertes de précision. Mais ça demande
à être confirmé par des esprits supérieurs.
\subsection{Dynamique}\index{dynamique}
Dynamique, précision et \textsl{macheps} ? Peu de gens connaissent
la fourbitude des calculs en virgule flottante avec les ordinateurs.
Moi-même compris. Il est évident qu'une étude théorique doit être
effectuée afin d'éviter les potentiels inconvénients.
Ceci dit, le standard \textsl{ieee754}\index{ieee754} nous indique qu'il
y a 23 bits pour la mantisse, ce qui nous propose déja
plus de huit millions de valeurs. Considérons un cas typique~:
le cumul de $N$ images ayant un niveau maximum $Vm$.
Moi-même compris.
\subsection{Pixel négatif ?}
Il est très difficle d'imaginer une lumière négative. Sauf peut-être
si nous songeons à des coefficients d'absorption, ou un canal
\textsl{alpha} qui inverserait les valeurs ? Un domaine dont
l'exploration peut confiner au mysticisme de part la multitude
des traitement possibles : valeur absolue, \textsl{clamping},
report sur les autres composantes. Votre imagination est
la limite.
\textsl{alpha} qui inverserait les valeurs ?
% ===================================================================
@ -216,8 +191,7 @@ et sur disque. Ça a été imaginé de façon presque empirique,
mais nous sommes tous là pour améliorer les choses, dans
la mesure de nos moyens.
Nous allons donc directement rentrer au cœur du problème,
en écrivant quelques lignes de code montrant le fonctionnement
général de la chose.
en écrivant quelques lignes de code.
\subsection{L'idée}
@ -225,28 +199,24 @@ Pour commencer par quelque chose de simple,
nous allons créer une image RGB\index{RGB} complètement noire,
puis l'enregistrer dans un fichier \texttt{.fimg}\index{.fimg},
un format complètement inconnu, puisque je viens de l'inventer
à l'instant même\footnote{Enfin, non, il y a déja longtemps,
avant la grande pandémie.}.
à l'instant même.
Enfin, non, il y a déja longtemps, avant la grande pandémie.
Tout d'abord, nous devons déclarer et garnir quelques variables
pour gérer la machinerie interne.
\begin{lstlisting}
int width = 640, height = 480;
char *fname = "quux.fimg";
char *fname = "exemple.fimg";
FloatImg fimg;
\end{lstlisting}
Ensuite, nous enchainerons trois étapes : la création de l'image
en mémoire centrale, l'initialisation des valeurs de chaque pixel à 0.0
(une valeur que certains associent au noir complet, et d'autres à une
impossibilité quantique),
et pour conclure, l'enregistrement de cette image dans un
fichier\footnote{Au format
en mémoire centrale, l'initialisation des valeurs de chaque pixel à 0.0,
et pour conclure, l'enregistrement dans un fichier\footnote{Au format
ésotérique, mais très véloce.} binaire.
\begin{lstlisting}
memset(fimg, 0, sizeof(FloatImg));
foo = fimg_create(&fimg, width, height, FIMG_TYPE_RGB);
if (foo) {
fprintf(stderr, "create floatimg -> %d\n", foo);
@ -261,9 +231,9 @@ if (foo) {
\end{lstlisting}
Une fois ce code enrobé dans un \texttt{main()}, compilé puis exécuté,
Une fois ce code enrobé dans un \texttt{main()}, compilé et exécuté,
nous pouvons entrevoir, grâce au logiciel
\texttt{fimgstats} (décrit en page \pageref{fimgstats}),
\texttt{fimgstats} (voir page \pageref{fimgstats}),
le résultat sous forme de chiffres divers, et/ou inutiles~:
\begin{verbatim}
@ -287,9 +257,9 @@ Avec un bon script bash, il y a déja de quoi faire.
La suite vers la page \pageref{codaz}.
Vous trouverez dans le répertoire \texttt{tools/}\index{tools/}
d'autres exemples de mise en œuvre de quelques fonctions disponibles
d'autres exemples de mise en œuvre des fonctions disponibles
sous formes d'outils en ligne de commande,
lesquels outils sont approximativement décrits en page \pageref{outils}.
lesquels sont approximativement décrits en page \pageref{outils}.
% ===================================================================
\section{Installation}
@ -305,15 +275,15 @@ soucis de boutisme.
\subsection{Prérequis}
Vous devez, en dehors des outils classiques (gcc, Awk, make\dots),
avoir quelques bibliothèques installées~:
avoir quelques bibliothèques installées\footnote{Les \texttt{-dev}
en plus pour Debian et dérivées}~:
\textsf{
libv4l2, libpnglite, libtiff,
libnetpbm\footnote{package libnetpbm10-dev},
libz\footnote{package zlib1g-dev}, libcurses,
libcfitsio...
libcfitsio-dev
} % end of textsf
éventuellement avec le \textsf{-dev} correspondant, qui contient, entre
autres, les fichiers \texttt{.h} associés
éventuellement avec le \textsf{-dev} correspondant,
et probablement d'autres choses.
Il est même quasiment certain que Bash soit indispensable, tout
@ -321,11 +291,7 @@ comme \textsc{gnu}/make\index{make}.
Une connaissance de base de l'utilisation du shell\index{shell}
et de l'écriture de Makefile's sera un plus.
Il faut aussi savoir où trouver le code. Il est dans le Git du
Tetalab\footnote{\texttt{https://git.tetalab.org/tTh/FloatImg}}.
Mais comme je ne comprend rien à Git, c'est pas la peine
de m'envoyer des trucs genre \textsl{pull-request} auquels je ne
comprend rien.
Il faut aussi savoir où trouver le code.
\subsection{Compilation}
@ -365,7 +331,7 @@ Faites-en ce que vous voulez.
Classiquement, il y a un fichier \texttt{.h} à inclure dans chacun
de vos codes source,
\texttt{floatimg.h}, généralement logé dans \texttt{/usr/local/include}
et contenant un certain nombre de définition de structures, de macros,
contenant un certain nombre de définition de structures, de macros,
de constantes\footnote{À l'ancienne, via le pré-processeur}
et les prototypes des fonctions utilisables par vos logiciels.
@ -374,7 +340,7 @@ classées en deux catégories : \texttt{lib/} et \texttt{funcs/}.
La première contient les choses qui sont relativement figées,
et la seconde celles qui risquent de bouger. Cette classification
est en fait indécement arbitraire.
D'autant plus qu'il y a aussi un répertoire nommé « experimental ».
D'autant plus qu'il y a aussi un répertoire nommé « experiemental ».
\subsection{Structures, macros\dots}
@ -433,7 +399,7 @@ quelques images...
Le champ \textsl{count} sera mis à 0 et
le champ \textsl{fval} sera initialisé à 15.0
(ce qui est la valeur maximale que peut renvoyer ce capteur).
(qui est la valeur maximale que peut renvoyer ce capteur).
Ensuite, dans la boucle capture/cumul, \textsl{count} sera
incrémenté à chaque passe, et nous aurons donc, en finale,
toutes les informations nécessaires pour exploiter au mieux la dynamique
@ -472,16 +438,15 @@ avant le moindre usage\footnote{\texttt{man 3 memset}}.
Certains membres de cette structure sont
documentés dans ce document, et les autres sont dangereux à
toucher. Les types d'images actuellement gérés sont les trois grands
classiques : niveau de gris, rouge-vert-bleu et rgb avec un canal alpha,
et expliquées quelques lignes plus haut.
classiques : gray, rgb et rgba. et expliquées quelques lignes plus haut.
Comme vous allez le voir plus loin, il y a plein de fonctions qui
prennent en argument deux images: la source et la destination.
Dans la plupart des cas, ces deux images doivent être compatibles,
prennent en argument deux images: une source et une destination.
Et dans la plupart des cas, ces deux images doivent être compatibles,
c'est à dire même type et mêmes dimensions.
\begin{lstlisting}
/* return 0 if pictures are compatible */
/* return 0 if compatible */
int fimg_images_not_compatible(FloatImg *a, FloatImg *b);
\end{lstlisting}
@ -490,7 +455,7 @@ C'est bien beau d'être enfin une image résidente en mémoire centrale, mais
pouvoir aussi exister à long terme en étant stocké dans la matrice
est tout aussi pertinent.
Il y a deux opérations qui supportent le reste des transits ram/ps.
Le format de ces fichiers est décrit page \pageref{formatfimg}.
Le format des fichiers est décrit page \pageref{formatfimg}.
\begin{lstlisting}
int fimg_dump_to_file(FloatImg *fimg, char *fname, int notused);
@ -500,7 +465,7 @@ int fimg_load_from_dump(char *fname, FloatImg *where);
Recharger une image depuis un fichier nécessite que celle-ci et
l'image de destination en mémoire
ait précisément les mêmes caractéristiques
(taille, type...), donc l'image en mémoire centrale doit être
(taille, type...), donc l'image en ram doit être
pré-allouée. On peut connaitre ces valeurs en appelant
\texttt{int fimg\_fileinfos(char *fname, int datas[3])}.
@ -524,9 +489,7 @@ foo = fimg_create_from_dump("lena.fimg", &head);
Si la valeur retournée est différente de 0, c'est que quelque
chose s'est probablement mal passé.
Certains messages sont parfois explicites. Mais parfois non.
Quand aux valeurs retournées en cas d'erreur, c'est le désordre
intégral\footnote{Un vrai désastre, même...}.
Certains messages sont parfois explicites.
% _________
@ -556,8 +519,7 @@ $x$ et $y$ de la demande.
Quand au canal \textsl{alpha}\index{alpha}, il est pour le moment
superbement ignoré. Ceci dit, on vient de me faire remarquer qu'il
peut être utilisable aussi pour faire du
\textsl{z-buffer}\index{z-buffer}\index{rgbz}, une technique
classique dans la génération d'images en trois dimensions.\dots
\textsl{z-buffer}\index{z-buffer}\index{rgbz}\dots
% ----------------------------------
@ -675,73 +637,32 @@ aux bonnes dimensions (échange W et H).
\subsection{Format du fichier \textsc{fimg}}\index{format}\label{formatfimg}
D'un design très empirique, c'est certainement à revoir pour l'avenir.
La force du \textsl{legacy} va-t-elle dominer le monde ?
Il faudrait normaliser l'endianess et le packing dans les structs%
\footnote{Directives du compilateur ?}, et surtout l'ajout
de données sur la prise de vue, du genre type de capteur, date et heure,
réglages divers\dots
Tout d'abord pour normaliser l'endianess et le packing\dots
\begin{lstlisting}
typedef struct {
char magic[8];
int32_t w, h, t;
int w, h, t;
} FimgFileHead;
\end{lstlisting}
\dots Mais aussi pour faciliter l'ajout de métadonnées, telles que
la valeur maximale, la date de création, une longueur d'onde,
et bien plus encore.
Le champ \texttt{magic[8]} doit contenir une valeur magique~:
les quatre premiers octets doivent contenir les quatre caractères
\texttt{'FIMG'}, et les quatre derniers doivent être à 0, sauf que,
voir plus bas, le cinquième vas vous étonner.
les quatre premier octets doivent contenir les quatre caractères
\texttt{'FIMG'}, et les quatre dernier doivent être à 0.
Le champ \texttt{t} (le type de l'image) doit avoir les trois octets
de poids fort à 0\footnote{Pourquoi ? Je n'en sais rien.}.
Ensuite, nous aurons (dans le cas courant) : 1, 2 ou 4 blocs
de WxH pixels sous forme de Float32. La première ligne lue
est la ligne du haut de l'image. Les valeurs négatives sont
tolérées.
Vous trouverez les constantes de type pertinentes dans le
de poids fort à 0. Vous trouverez les constantes de type dans le
fichier \texttt{floatimg.h}, et quelques informations
(non-)essentielles qui ne vous serviront probablement à rien.
% ----------------------------------
% new février 2022
\subsection{Métadonnées}
\index{metadata} \index{timestamp}
Attention, ce n'est pas encore une version définitive, beaucoup de
choses restent à préciser sur le contenu de cette structure, mais
l'essentiel est déja là. On reconnait un fichier avec metadata
quand l'octet \texttt{magic[4]} du premier header est égal à
la lettre \texttt{'a'}.
\begin{lstlisting}
typedef struct {
char magic[8];
struct timeval timestamp;
int32_t count;
float fval;
char idcam[32];
int32_t origin; // enum ?
} FimgMetaData;
\end{lstlisting}
Voyons maintenant chacun des champs de cette structure, en prenant bien
en compte qu'à ce moment\footnote{4 avril 2022}, tout n'est pas figé.
Ceci dit, nous allons aussi retrouver de vieilles connaissances.
\textbf{to be continued}
(non-)essentielles.
% ----------------------------------
\subsection{Exportation \& Importation}\index{export}\label{export}
Notre format de fichier étant totalement inconnu%
\footnote{Du monde extérieur, vous l'aurez compris.},
il nous
Notre format de fichier étant totalement inconnu, il nous
faut bien exporter nos images en quelque chose de plus
connu. Bien entendu, c'est toujours affaire de compromis
entre précision de valeurs et taille des fichiers.
@ -750,7 +671,7 @@ Et dans le sens inverse, il serait bien de savoir importer
le monde extérieur dans nos sombres caves à pixel.
Il faut quand même reconnaitre que c'est un peu la jungle dans les
formats de fichiers d'image, ce qui explique le retard
du développement dans ce domaine\dots
dans ce domaine\dots
\subsubsection{Vers PNM}\index{PNM}
@ -780,14 +701,12 @@ Les autres bits ne sont pas utilisés et doivent être à zéro.
\subsubsection{Vers PNG}\index{PNG}
Actuellement, on ne peut enregistrer qu'en mode RGB uniquement,
avec 8 bits par composante,
Actuellement, on peut enregistrer uniquement en mode RGB,
8 bits par composante,
mais on a quand même une bonne compression, ça compense.
J'utilise \textsl{libpnglite} avec qui j'ai un peu de mal à suivre.
Mais je me soigne. Le mode 16 bits va bientôt arriver.
On peut aussi songer à l'export des metadonnées, pour celles qui
sont compatibles avec le standard PNG.
On peut aussi songer à l'export de metadatas.
\begin{lstlisting}
int fimg_save_as_png(FloatImg *src, char *outname, int flags);
@ -795,9 +714,8 @@ int fimg_save_as_png(FloatImg *src, char *outname, int flags);
Tous les flags doivent être à zéro. Sinon, ça foire parfois.
Et en fait (mars 2021) je ne suis pas très content de
\texttt{pnglite}, donc un de ces jours, je prendrais
\sout{cinq} quelques jours pour
régler ce souci en passant à la bibliothèque canonique.
\texttt{pnglite}, donc un de ces jours\footnote{Rendez-nous notre
Mixou !}, je prendrais cinq jours pour régler le souci.
\subsubsection{Vers TIFF}\index{TIFF}
@ -810,7 +728,7 @@ int fimg_write_as_tiff(FloatImg *src, char *outname, int flags);
\end{lstlisting}
Tous les flags doivent être à zéro. Pour le moment.
Un premier jet pas forcément parfait.
\subsubsection{Vers FITS}\index{FITS}
@ -830,7 +748,6 @@ sais pas encore comment régler ce petit détail.
Tous les flags doivent être à zéro.
% =============================================================
\subsection{Utilitaires}
@ -843,19 +760,17 @@ fichier de configuration.
int parse_WxH(char *str, int *pw, int *ph)
int parse_double(char *str, double *dptr)
\end{lstlisting}
% XXX rjouter quelques explication, please !
La fonction \texttt{int format\_from\_extension(char *fname)} examine un
nom de fichier tel que \texttt{lena.xxx}, et retourne, si la partie
\texttt{xxx} est connue, un éventuel nombre positif, dont les valeurs sont
déclarées dans floatimg.h
le valeureux.
Les extensions actuellement connues sont :
fimg, png, pnm, pgm, fits et tiff. Le bmp est plus ou moins prévu\dots
Les extensions actuellement connues sont : fimg, png, pnm, fits et tiff.
To be continued\index{XXX}\dots
% =============================================================
\subsection{Effets}\index{sfx}
@ -879,9 +794,10 @@ J'ai commencé à étudier ces objets étranges quand j'ai commencé
à travailler sur l'interpolator\index{interpolator} à l'automne 2020.
Hélas, j'ai vite réalisé que c'était assez délicat.
Pour ce genre de \textsl{usecase}, le numérique est pitoyable si on
le compare au (hélas défunt) \textsc{Betamax}\index{Betamax}.
le compare au \textsc{Betamax}\index{Betamax}.
% ----------------------------------
% =============================================================
\subsection{Filtrages}\index{filtrage}
@ -922,8 +838,7 @@ int fimg_filter_3x3(FloatImg *src, FloatImg *dst, FimgFilter3x3 *filtr)
\end{lstlisting}
Comme dans la plupart des cas, la gestion des valeurs négatives
de pixel est laissé au hasard, qui fait souvent du portnawak.
Quoique, il doit bien exister
de pixel est laissé au hasard. Quoique, il doit bien exister
quelques solutions de contournement : clamping ou shift ?
\textsl{To be continued\index{XXX}\dots}
@ -975,7 +890,7 @@ En particulier tout le reste du code qui suppose qu'un pixel
ne peut \textbf{pas} être négatif va peut-être exploser de rire.
Vous pouvez aussi remarquer qu'il n'y a pas de controle
de cohérence sur les dimensions des deux images, malgré l'existence
de fonctions prévues à cet effet, mais il fallait rester simple\dots
de fonctions prévues à cet effet\dots
% ===================================================================
@ -985,8 +900,7 @@ de fonctions prévues à cet effet, mais il fallait rester simple\dots
in-fine sur des objets que l'on peut considérer comme « physiques »,
il est important de passer à une utilisation
normale\footnote{Il y a une vie en dehors de git.} et construire
des trucs qui mettent en action le code primitif pour partir
sur des bases saines.
des trucs qui mettent en action le code primitif.
Ces machins ont en commun quelques options bien pratiques~:
\texttt{-h} pour avoir un résumé des options disponibles,
@ -1017,7 +931,7 @@ deux nombres séparés ou la notation \texttt{WIDTHxHEIGHT}.
La plupart des types d'image générée prennent un paramètre flottant qui
devra être donné avec l'option \texttt{-k F.F} avec une valeur par défaut
à $1.0$, ce qui n'est pas toujours une bonne valeur, ymmv\index{ymmv}.
à $1.0$, ce qui n'est pas toujours une bonne valeur.
\begin{description} \index{XXX}
\item [black/gray/grey:] efface avec 0.0 (black) ou avec la valeur
@ -1038,11 +952,7 @@ error in 'fimg_create_from_png' : read png -> -1 File error
png2fimg : err -1, abort.
\end{verbatim}
Il faut peut-être envisager le passage à \texttt{libpng}\index{libpng},
la bibliothèque actuellement utilisée (\texttt{pnglite}) ayant tendance
à borker en lecture sur certains fichiers pourtant corrects.
% ---------------------
Il faut peut-être envisager le passage à \texttt{libpng}\index{libpng}.
\subsection{fimgstats}\index{fimgstats}\label{fimgstats}
@ -1092,9 +1002,7 @@ sera lisible avec le sélecteur \texttt{-L}.
Et pour les aventureux, la commande \texttt{xper} (abréviation
de \textsl{expérimental}) permet de tester la plus récente tentative
de friture du moment. D'autre part un set bien plus complet d'effets
àlc est disponible dans les logiciels de flou temporel, décrits
plus loin dans ce document.
de friture du moment.
% ---------------------
@ -1128,9 +1036,6 @@ La véracité mathématique n'est pas garantie. Et n'oubliez pas que
les valeurs négatives peuvent être la cause de \textsl{glitches}
de qualitay.
La liste des opérations est susceptible d'être agrémenté de quelques
possibilités bien féroces\footnote{Stay tuned, flim at 11.}.
% -------------------------
\subsection{fimg2png, fimg2pnm, fimg2tiff, fimg2fits}
@ -1198,13 +1103,12 @@ tth@fubar:~/Devel/FloatImg/doc$ fimg2text -s 1 quux.fimg
tth@fubar:~/Devel/FloatImg/doc$
\end{verbatim}
Et maintenant, vous voulez un gros exemple ? Bah, ça doit demander
l'utilisation de Povray\index{Povray}.
Et maintenant, vous voulez un gros exemple ?
% -------------------------
% beaucoup trop de maths approximative dans ce passage.
\subsection{fimg2gray}\index{fimg2gray}\label{fimg2gray}
@ -1242,8 +1146,7 @@ cumulator options :
\end{verbatim}
Le nom par défaut du fichier résultant est \texttt{out.fimg}.
L'exportation « multiformat » est enfin fonctionnelle, dans la
mesure des formats connus.
L'exportation « multiformat » est pour bientôt.
% ===================================================================
\section{Debug}\index{Debug}
@ -1299,7 +1202,7 @@ if (foo) {
\end{verbatim}
À condition d'avoir bien réglé votre ulimit pour la génération d'un coredump,
vous aurez sous la main un fichier \texttt{core} qui vous permettra
vous aurez sous la main un fichier \textsc{core} qui vous permettra
de, par exemple, remonter la pile d'appel avec la commande \texttt{back} de
gdb. Mais pour le moment, juste une infime partie du code est instrumentée
avec ce dispositif.
@ -1321,7 +1224,7 @@ Il reste plein de choses à faire pour que ce soit vraiment utilisable,
surtout dans un contexte artistique à grande porosité.
C'est par ces frottements de techniques ayant du sens que les
choses seront acquises, pour le pire, le meilleur et la
techno-futilité du monde futur..
futilité du monde futur..
\begin{itemize}
\item Import/export au format \textsc{tiff}\index{TIFF} à continuer.
@ -1331,7 +1234,7 @@ techno-futilité du monde futur..
\item Formaliser les codes d'erreur. \textbf{Urgent}.
\item Faire une passe complète de Valgrind\index{valgrind}.
\item Intégrer la fonderie, l'interpolator et le singlepass.
\item Vérifier le gestion des images mono-canal et de la transparence.
\item Vérifier le gestion des images mono-canal.
\end{itemize}
% ===================================================================
@ -1345,7 +1248,7 @@ jamais négliger le traitement des éventuelles erreurs.
Nous savons générer une image contenant des pixels aux valeurs
probablement aléatoires, avec la commande \texttt{mkfimg},
qui utilise le \texttt{drand48}\index{drand48} de \textsc{posix}\index{POSIX}.
Maintenant, posons-nous une question de statisticien : que se passe-t-il si
Maintenant, posons-nous une question de statisticien : ue se passe-t-il si
nous faisons la somme de plusieurs centaines de ces images ?
\begin{lstlisting}
@ -1412,7 +1315,7 @@ le premier pouvant salement brotcher une image, et le second capable de
mélanger harmonieusement deux images, la balance est équilibrée.
Il s'agit donc d'un petit programme écrit en Bash\index{bash}, un langage
dont la connaissance est, pour moi, indispensable à qui veut faire des
dont la connaissance est, pour moi, indispendable à qui veut faire des
images kitchies\index{kitchy}. Mais ne vous inquiétez pas, c'est en
fait assez simple à comprendre. Et comprendre, c'est apprendre.
@ -1433,12 +1336,10 @@ OFFS=$(( NBRE / 4 ))
\end{verbatim}
Dans ce préliminaire logiciel, nous avons nommé le répertoire
Dans ce préliminaire logiciel, nous avons nommés le répertoire
\textsc{srcdir} contenant les captures d'image au format fimg, le répertoire
\textsc{dstdir} dans lequel seront rangées les images calculées,
et l'emplacement de deux fichiers de travail, placés dans ce qui
peut être vu comme un \textsl{ramdisk}\index{ramdisk}\index{/dev/shm/}
et qui accélère un peu les opérations.
et l'emplacement de deux fichiers de travail.
Les quelques lignes suivantes, qui semble bien magiques, ne sont en fait
que de la magie Unix\index{Unix}. Elles nous permettent d'avoir
@ -1484,12 +1385,12 @@ $sin(idx/16)$ afin d'avoir une oscillation du coefficient entre
\begin{verbatim}
# do the hard floating computation
#
fimgfx -v cos010 ${imgB} ${FTMP}
fimgops -k ${K} ${FTMP} ${imgA} mix ${FDST}
fimgfx -v cos010 ${imgB} ${FTMP}
fimgops -k ${K} ${FTMP} ${imgA} mix ${FDST}
\end{verbatim}
Étape suivante, étape cruciale : le brassage d'une multitude de
pixels flottants.
pixels flottants.
Tout d'abord, nous faisons subir à l'image-echo
(\texttt{imgB}, définie au début du script) un distorsion
@ -1507,8 +1408,8 @@ done
\end{verbatim}
Et en fin de boucle, nous convertissons le résultat de nos
savants calculs au format PNG, et nous écrivons le fichier dans le
répertoire de destination fixé au début.
savants calculs au format PNG, et écrivons le fichier dans le répertoire
de destination fixé au début.
C'est le moment de passer la main à ffmpeg\index{ffmpeg}.
C'est juste une POC\index{POC}, et une implémentation bien plus
@ -1516,9 +1417,6 @@ complète écrite en \textbf{C}\index{C} est déja en chantier,
avec une complexité prévue à un niveau assez réjouissant.
% ===================================================================
%
% V4L2 is a trap.
%
\section{Video for Linux}\index{v4l2}
Donc, maintenant, nous savons un peu tripoter ces images flottantes.
@ -1534,11 +1432,11 @@ v4l2.
\subsection{grabvidseq}\index{grabvidseq}\label{grabvidseq}
Un logiciel en évolution (vraiment trop) lente, qui permet déja
la capture d'images en
Un logiciel en évolution (trop ?) lente, qui permet déja la capture
d'images en
\textsl{longue pose} selon la méthode du cumul\index{cumul}, et
devrait bientôt retrouver sa capacité à enregistrer des
séquences d'images. (\textsl{workaround}~: écrire une boucle en shell)
séquences d'images.
\begin{verbatim}
tth@debian:~/Devel/FloatImg/v4l2$ ./grabvidseq -h
@ -1574,8 +1472,8 @@ vaguement expliqué page \pageref{contraste}.
L'option \texttt{-X} me permet d'intégrer des \textit{fritures}
expérimentales dans le binaire, et ne doit donc pas être
utilisée dans des scripts si on a des visions à long
(ou même moyen) terme.
utilisée dans des scripts si on a des visions à long (ou même)
terme.
\subsubsection{Upscaling}\index{upscaling}\label{upscaling}
@ -1609,27 +1507,19 @@ Options :
Je me sens obligé d'avouer qu'il reste quelques points mystérieux dans
l'\textsc{api} de \textsc{v4l2}, et donc, que ce que raconte
ce logiciel doit être pris avec des pincettes. En particulier
des choses essentielles comme la liste des résolutions disponibles.
la liste des résolutions disponibles.
\subsection{nc-camcontrol}
Ajustement \textsl{Brightness Contrast Saturation Hue\dots}
Probablement pilotable au joystick\index{joystick}.
% ===================================================================
\section{À l'extérieur}
Il existe une foultitude de logiciels (composants ou end-yuser) et
il est souvent nécessaire de pouvoir communiquer facilement
avec eux. Nous avons déja quelques possibilité d'exportation,
mais passer par cette étape intermédiaire est parfois délicat
à gérer dans un \textsl{pipedeprod} autrement bien huilé.
\subsection{ImageMagick}\index{ImageMagick}
Pour afficher notre format .fimg exotique avec \texttt{display}, un
des éléments du package ImageMagick, vous
Pour afficher notre format .fimg exotique avec \texttt{display}, vous
devez mettre ce bout de XML\index{XML} dans le fichier
\texttt{\$HOME/.magick/delegates.xml}~:
@ -1641,20 +1531,17 @@ devez mettre ce bout de XML\index{XML} dans le fichier
\end{lstlisting}
C'est juste un hack rapide, qui ne fonctionne pas très bien avec
d'autres commande de IM, comme \texttt{identify}\index{identify},
qui a tendance à
d'autres commande de IM, comme identify, qui a tendance à
raconter un peu n'importe quoi, puisqu'elle se base sur le
résultat de la conversion.
Je compte donc sur le bouquin de \textsl{Brunus}\index{Brunus}
pour avancer\dots
résultat de la conversion\dots
Je compte donc sur le bouquin de \textsl{Brunus} pour avancer\dots
\subsection{Gimp}\index{Gimp}
Mmmmm... Ça semble un peu plus compliqué.
La documentation à ce sujet me semble ésotérique.
D'un autre coté, il
faut faire ça en \textbf{C}, ce qui ne peut pas être totalement négatif.
Sauf pour les riiRistes.
faut faire ça en \textbf{C}, ce qui ne peut pas être négatif.
\subsection{ffmpeg}\index{ffmpeg}
@ -1667,33 +1554,24 @@ ffmpeg -nostdin \
-c:v libx264 \
-pix_fmt yuv420p \
-tune film \
-metadata artist='---[ tTh ]---' \
-metadata title='awesome video' \
stereo.mp4
\end{lstlisting}
Il existe environ un gazillion d'options pour encoder avec ffmpeg.
Bon courage pour toutes les explorer, voire même juste les comprendre.
\subsection{Et encore ?}\index{krita}\index{geeqie}
Il y a d'autres logiciels pour lesquels écrire une fonction d'importation
serait bien~: \textsl{Geeqie}, un visualiseur d'image fort pratique, ou
\textsl{Krita} qui semble avoir les faveurs de
dessinateurs de talent.
Ce qui nous conduit à une question importante~: quels sont les logiciels
qui gèrent le chargement d'image par un système de
\textsl{plugin}\index{plugin},
parce que recompiler tout Gimp juste pour ça, c'est un peu overkill.
dessinateurs de talent\footnote{Oui, David, c'est à toi que je pense.}.
% -------------------------------------------------------------------
% ===================================================================
\section{Le flou temporel}
\textit{\hspace{7em}Et si nous jouions sur l'axe du temps ?}
Et si nous jouions sur l'axe du temps ?
Nous avons déja plus ou moins la magie du cumul sur la prise de vue
d'\textbf{image} en enchainant plusieurs captures d'image accumulées
en une seule.
Nous avons plus ou moins la magie du cumul sur la prise de vue
d'\textbf{image} en enchainant plusieurs capture d'image.
Maintenant, voyons ce que l'on peut faire à partir de plusieurs images.
On peut d'abord penser faire une moyenne (ou la somme, en fait) de toutes
ces images. Mais ce n'est qu'une façon déguisée de faire du cumul.
@ -1701,133 +1579,29 @@ C'est à ce moment que nous changeons l'axe de vue du défi.
Par ailleurs, il m'a semblé pertinent d'inclure dans le projet une
foultitude d'effets spéciaux.
Qui manquent cruellement de possibilités de paramétrage.
Mais peuvent être enchainés dans ce que j'appelle des
\textsl{filter-chains}~: ces effets seront appliqués dans
l'ordre aux image traitées soit en entrée soit en sortie.
Je pense qu'un schéma\footnote{omg, apprendre un nouveau truc en
\LaTeX, quel challenge étourdissant !} s'impose.
\subsection{\textsl{moving average}}
\subsection{\texttt{./fonderie} : \textsl{moving average}}
Basé sur la moyenne mobile, avec une structure de
\texttt{./fonderie} : Basé sur la moyenne mobile, avec une structure de
fifo\index{fifo} particulièrement mal conçue.
Qui, en fait, n'est pas vraiment un fifo, mais plutôt un buffer
circulaire. Pour chaque image source, elle est lue, passe dans la chaine de
filtre d'entrée et est insérée dans ce buffer.
Ensuite on calcule la moyenne des images contenues dans ce buffer.
Et pour conclure, cette image moyennée passe au travers de la
chaine de filtre de sortie, avant d'être enregistrée en PNG\index{PNG}
dans le répertoire de destination.
\begin{verbatim}
*** fonderie compiled Jan 23 2023, 10:43:56, pid 23366
options:
-E input:filter:chain
-F output:filter:chain
-I input glob pattern
-L list available filters
-O output directory
-T fifo size
-v increase verbosity
\end{verbatim}
Euh, c'est quoi un '\textsl{input glob pattern}' ?
C'est ce qui vous permet
de sélectionner un peu les images que vous voulez traiter, exactement
comme vous pourriez le faire avec un shell classique.
Par exemple pour choisir une image sur dix, le glob-pattern sera
'\texttt{frames/????0.fimg}', et vous trouverez les explications détaillées
dans le manuel~: \texttt{glob(7)}, et \texttt{glob(3)} pour la
fonction utilisée.
% -------------------------------------------------------------------
\subsection{Interpolator}\index{interpolator}
Pour le moment, juste des calculs pas si simple que ça.
Je pense qu'il faudra
se lancer dans des calculs splinesques pour améliorer les choses dans
la création des images intermédiaires.
Voyons d'abord le principe actuel.
Nous avons une série de centaines, voire de milliers, de photos.
En parcourant cette liste, nous allons en prélever une sur $N$,
et entre celle-ci et la
précédente prélevée, nous allons calculer par interpolation
\textbf{linéaire} $N - 1$ images intermédiaires, et les
intercaler entre nos deux sélections pour générer le
flux de sortie,
ce qui devrait nous donner un ralenti de bon aloi.
\begin{verbatim}
usage:
interpolator [options] <inglob> <outdir> <nbsteep>
options:
-E i:bla:k input filter chain
-F name:j output filter chain
-n make negative
-S nn mysterious sort
-L list available filters
-v increase verbosity
\end{verbatim}
L'option « mysterious sort » mérite bien son nom. Cette friture a
été écrite il y a bien longtemps pour un projet précis, et les
résultats ont été décevants. Je pense qu'il est toxique de
l'utiliser pour le moment\footnote{Ou le repenser différent ?}.
% -------------------------------------------------------------------
Juste des calculs pas si simple que ça.
\subsection{Singlepass}
Ce programme \texttt{singlepass} prétend vous permettre de tester
tous les filtres disponibles, et dont on peut avoir la liste
tous les filtres disponibles, dont on peut avoir la liste
avec l'option \texttt{-L}\footnote{liste hélas peu machinable.}
\begin{verbatim}
usage:
-F define:the:filter:chain
-g input glob pattern
-L list available filters
-O /output/directory (default ./p8)
-r N repetiiing factor
-v spit more messages
\end{verbatim}
Il n'y a pas de moyenne mobile, pas d'interpolation, mais un facteur de
répétition qui permet de dupliquer $N$ fois une image dans le flux de
sortie. Si vous globez \texttt{frames/????[02468]}, vous prenez
une image sur deux, alors un facteur de répétition à $2$ conservera
la 'vitesse' de la séquence, mais avec une petite saccade régulière
de bon aloi \textit{:)}
% -------------------------------------------------------------------
\subsection{Déviance dans le flou ?}
\subsection{Déviance}
Là, nous tombons dans de la \textsl{troiD}\index{3d} de haut niveau,
avec plein de maths compliquées à l'intérieur.
avec plein de maths compliquées
à l'intérieur.
Et surtout quelque chose qui n'est encore qu'une idée abstraite,
mais il y aura du zbuffer\index{zbuffer} dedans.
% ===================================================================
\section{Expérimentations} \index{experimental}
Il m'arrive parfois d'avoir de vagues idées d'image, et donc de logiciel,
qui tournent dans un coin de la tête.
Parfois je songe à une fonction qui me
serait bien utile, mais j'ai des doutes sur son
\textsc{api}\footnote{Application Programming Interface}\index{api}
qui soit à la fois simple et complète. Je fais donc des essais.
Parfois j'imagine confusément un algorithme\index{algorithme} tordu
et sans but précis. Je le \textit{runne} et je le \textit{re-runne}
un gazillion de fois dans mon cerveau processique.
Quel va être son facteur $O$ ? Je fais donc des essais.
mais il y aura du zbuffer dedans.
% ===================================================================
@ -1844,7 +1618,6 @@ L'idée est donc de construire un appareil autonome, basé sur un Raspi et
une webcam \textsc{usb}\index{USB}, pilotable par \textsc{lirc}\index{LIRC},
alimenté par une (grosse) batterie et permettant d'aller
faire des images au bord d'un lac ou dans la campagne de l'Ariège.
Et, comme le dit la sagesse populaire : « fimg at 11 ».
% -------------------------------------------------------------------

14
experiment/.gitignore vendored
View File

@ -1,14 +0,0 @@
*.fimg
*.o
*.pnm
*.data
assemblage
extracteur
fimg2obj
mnt
movepixels
muxplanes
tcache

View File

@ -1,40 +0,0 @@
#
#  some ugly experiments, do not use in production
#
COPT = -Wall -Wextra -fpic -g -DDEBUG_LEVEL=0 -lm
DEPS = ../floatimg.h ../libfloatimg.a Makefile
LIBS = ../libfloatimg.a -ltiff -lpnglite -lcfitsio -lm
all: assemblage muxplanes movepixels mnt
# ---------------------------------------------------------
assemblage: assemblage.c ${DEPS}
gcc $(COPT) $< ../libfloatimg.a ${LIBS} -o $@
muxplanes: muxplanes.c ${DEPS}
gcc $(COPT) $< ${LIBS} -o $@
movepixels: movepixels.c ${DEPS}
gcc $(COPT) $< ../libfloatimg.a ${LIBS} -o $@
mnt: mnt.c ${DEPS}
gcc $(COPT) $< ../libfloatimg.a ${LIBS} -o $@
fimg2obj: fimg2obj.c $(DEPS)
gcc $(COPT) $< ../libfloatimg.a ${LIBS} -o $@
# ---------------------------------------------------------
# CACHE ENGINE
cachengn.o: cachengn.c cachengn.h Makefile
gcc $(COPT) -c $<
tcache.o: tcache.c cachengn.h Makefile
gcc $(COPT) -c $<
tcache: tcache.o cachengn.o Makefile
gcc $(COPT) tcache.o cachengn.o $(LIBS) -o $@

View File

@ -1,29 +0,0 @@
# EXPÉRIMENTATIONS ÀLC
Attention, tout ce qui se trouve dans ce répertoire ne sont que des
essais. Certains aboutissent, et sont migrés vers `funcs/` ou
`tools/`, d'autre échouent et restent trainer dans le coin en attente
du retour de l'inspiration.
Le contenu de ce répertoire doit donc être considéré comme
**volatile**. Si vous y trouvez votre bonheur, il serait sage
d'en faire une copie personnelle...
## MNT
Modèles numériques de terrain. Rien ne marche. Plein de maths.
Un [code](mnt.c) complexe.
## fimg2obj
Création d'un fichier .OBJ (de Wavefront) à partir d'une image
flottante afin d'avoir des vues en 3d pertinentes, bien qu'assez
futiles.
## système de cache
`new: Mon Jul 17 12:49:20 UTC 2023`
En cours : définition d'à peu-près tout ce qu'il reste à faire
pour avoir quelque chose qui fonctionne.
Plus d'information dans le [.h](cachengn.h).

View File

@ -1,145 +0,0 @@
/*
* the chache engine - code
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <stdlib.h>
#include <string.h>
#include "../floatimg.h"
#include "cachengn.h"
extern int verbosity;
static int nombre_slots = -1;
static int index_slot = -1;
static FimgCacheEntry *le_cache = NULL;
/* ------------------------------------------------------------ */
void cachengn_print_version(int k)
{
printf("\t!!! this is the version ZERO !!!\n");
fprintf(stderr, "sizeof cache entry: %ld\n", sizeof(FimgCacheEntry));
if (k) fimg_print_version(0);
}
/* ------------------------------------------------------------ */
/*
*
*/
int init_empty_cache(int iw, int ih, int szc, int wtfparam)
{
int idx;
fprintf(stderr, ">>> %s ( %d %d %d %d )\n", __func__,
iw, ih, szc, wtfparam);
/* MOLLYGUARD : don't init TWICE, please */
if (NULL != le_cache) {
fprintf(stderr, "%s: there is a cache at %p\n", __func__,
le_cache);
return -2;
}
/* allocate an prepare memory */
if ( NULL==(le_cache=calloc(szc, sizeof(FimgCacheEntry))) ) {
fprintf(stderr, "%s: no memory, sorry...\n", __func__);
return -3;
}
fprintf(stderr, " slot array at %p\n", le_cache);
for (idx=0; idx<szc; idx++) {
le_cache[idx].flags = 0xF0;
le_cache[idx].index = idx;
}
/* update private cache metadata */
nombre_slots = szc;
return 0;
}
/* ------------------------------------------------------------ */
/*
*
*/
FloatImg *give_me_thiz_picz(char *fname, int notused)
{
int idx, foo, freeslot;
FloatImg img;
char *nptr;
fprintf(stderr, ">>> %s ( '%s' %d )\n", __func__, fname, notused);
/* please add molly guard ! */
if (notused)
fprintf(stderr, "in %s, notused was %d\n", __func__, notused);
/* is the floatimg already in the cahce ? */
for (idx=0; idx<nombre_slots; idx++) {
nptr = le_cache[idx].filename;
if (NULL!=nptr && (! strcmp(fname, nptr))) {
fprintf(stderr, "found '%s' at %d\n", nptr, idx);
return le_cache[idx].image;
}
}
/* we not have this picture in ou cache, so we need a free
slot for it */
freeslot = -1;
for (idx=0; idx<nombre_slots; idx++) {
if (NULL==le_cache[idx].image) {
freeslot = idx;
break;
}
}
fprintf(stderr, "freeslot = %d\n", freeslot);
/* check if we can read this file */
foo = access(fname, R_OK); /* XXX */
if (foo) {
perror(__FILE__ ": give_me_thiz_picz");
return NULL;
}
/* try to load the requested file */
foo = fimg_create_from_dump(fname, &img);
if (foo) {
fprintf(stderr, "oups on %s\n", fname);
return NULL;
}
/* OK we have all the pixels in core memorey */
return NULL;
}
/* ------------------------------------------------------------ */
/*
*
*/
int liste_le_cache(unsigned int flags)
{
int idx;
fprintf(stderr, ">>> %s ( Ox%X )\n", __func__, flags);
/* please add molly guard here */
fprintf(stderr, "cache at %p : %d slots, idx = %d\n",
le_cache, nombre_slots, index_slot);
for (idx=0; idx<nombre_slots; idx++) {
fprintf(stderr, "%5d ", idx);
fprintf(stderr, "0x%02x ", le_cache[idx].flags);
fprintf(stderr, "%p ", le_cache[idx].image);
fprintf(stderr, "%s\n", le_cache[idx].filename);
}
return 0;
}
/* ------------------------------------------------------------ */

View File

@ -1,29 +0,0 @@
/*
* the chache engine - header
*/
void cachengn_print_version(int k);
typedef struct {
int flags;
char *filename;
FloatImg *image;
int index;
} FimgCacheEntry;
/*
* parameters:
* - iw, ik : image size
* - szc : number of slots
* - nbre : WTF isthat?
*/
int init_empty_cache(int iw, int ih, int szc, int nbre);
/* /!\ the floatimg returned must be view as readonly */
FloatImg *give_me_thiz_picz(char *fname, int notused);
/* utilities functions */
int liste_le_cache(unsigned int flags);

View File

@ -1,67 +0,0 @@
/*
* another ugly experiment
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include "../floatimg.h"
int verbosity;
/* ---------------------------------------------- ~~~~~~~~~~~~~~~~ */
int convert_fimg_to_obj(char *fimgfname, char *objfname, int mode)
{
FloatImg src;
int foo, x, y;
FILE *fp;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' '%s' %d )\n", __func__,
fimgfname, objfname, mode);
#endif
if (mode) {
fprintf(stderr, "in %s(), mode must be 0, was %d\n", __func__, mode);
}
foo = fimg_create_from_dump(fimgfname, &src);
if (foo) {
fprintf(stderr, "err %d loading %f\n", foo, fimgfname);
return foo;
}
return -1;
}
/* ---------------------------------------------- ~~~~~~~~~~~~~~~~ */
int main(int argc, char *argv[])
{
int foo, opt;
char *infile = "foo.fimg";
fprintf(stderr, "*** fimg2obj (%s %s)\n", __DATE__, __TIME__);
verbosity = 0;
#if 0
for (foo=0; foo<argc; foo++) {
fprintf(stderr, "%9d %s\n", foo, argv[foo]);
}
#endif
foo = convert_fimg_to_obj(infile, "foo.obj", 0);
if (foo) {
fprintf(stderr, "convertor give us %d\n", foo);
exit(1);
}
return 0;
}
/* ---------------------------------------------- ~~~~~~~~~~~~~~~~ */

View File

@ -1,231 +0,0 @@
/*
* Modeles Numeriques de Terrain -- UGLY CODE INSIDE !!
*
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "../floatimg.h"
int verbosity;
/* ------------------------------------------------------------------- */
/* for debug purpose */
int printf_histo_gray(char *fname, int histo[], int nbre)
{
FILE *fp;
int idx;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' %p %d )\n", __func__,
fname, histo, nbre);
#endif
if (NULL == (fp = fopen(fname, "w"))) {
perror(fname);
exit(1);
}
for (idx=0; idx<nbre; idx++) {
fprintf(fp, "%6d %8d\n", idx, histo[idx]);
}
fclose(fp);
return -1;
}
/* ------------------------------------------------------------------- */
/* for debug purpose */
int calcul_histo_gray(FloatImg *img, char *fname, int nbslots, float *pmax)
{
int offset, nbpix, ival;
float pixel, minp, maxp;
int *counts;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p '%s' %d )\n", __func__,
img, fname, nbslots);
#endif
if (FIMG_TYPE_GRAY != img->type) {
fprintf(stderr, "%s: image is not in greylevel\n", __func__);
return -2;
}
/* allocate memory for histogram computation */
counts = calloc(nbslots, sizeof(int));
if (NULL == counts) {
fprintf(stderr, "malloc fail in %s\n", __func__);
abort();
}
nbpix = img->width * img->height;
minp = 1e10, maxp = -1e10;
for (offset=0; offset<nbpix; offset++) {
pixel = img->R[offset];
if (pixel < minp) minp = pixel;
if (pixel > maxp) maxp = pixel;
}
fprintf(stderr, " values = %g < %g\n", minp, maxp);
*pmax = maxp; /* copy value for the caller */
/* calcul de l'histogramme avec scaling */
for (offset=0; offset<nbpix; offset++) {
pixel = img->R[offset];
ival = (int)((pixel * (float)nbslots) / maxp);
counts[ival]++;
// fprintf(stderr, "%6d %10.6f %i\n", offset, pixel, ival);
}
if (NULL != fname)
{
printf_histo_gray(fname, counts, nbslots);
}
/* garbage collect stuff */
free(counts);
return 0;
}
/* ------------------------------------------------------------------- */
/*
* Second try - ahem?
*/
int brotche_mnt_style(FloatImg *src, FloatImg *dst)
{
FloatImg tmp;
int x, y, foo;
int offset;
float z1, z2, z3, z4;
float a, b, c;
float pente, minp, maxp, seuil;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p )\n", __func__, src, dst);
#endif
/*
* trying some preprocessor filters
*/
//foo = fimg_lissage_2x2(src);
foo = fimg_lissage_3x3(src);
if (foo) fprintf(stderr, " lissage -> %d\n", foo);
foo = fimg_killborders(src);
if (foo) fprintf(stderr, " killborder -> %d\n", foo);
#define W (src->width)
#define DX 1.0
#define DY 1.0
/* allocate a graylevel image for storing la 'pente' */
memset(&tmp, 0, sizeof(FloatImg));
foo = fimg_create(&tmp, src->width, src->height, FIMG_TYPE_GRAY);
if (foo) {
fprintf(stderr, "create tmp pic --> %d\n", foo);
return foo;
}
/* calcul de la pente : a vérifier ! */
for (y=0; y<(src->height-1); y++) {
for (x=0; x<(src->width-1); x++) {
offset = (y * W) + x;
z1 = src->R[offset];
z2 = src->R[offset+1];
z3 = src->R[offset+W];
z4 = src->R[offset+W+1];
a = ( z1 + z2 + z3 + z4) / 4.0;
b = (-z1 + z2 - z3 + z4) / 2.0 / DX;
c = (-z1 - z2 + z3 + z4) / 2.0 / DY;
pente = atanf(sqrt(b*b + c*c));
tmp.R[offset] = pente;
}
}
foo = calcul_histo_gray(&tmp, "histogramme.data", 499, &maxp);
if (foo) fprintf(stderr, "<<< calcul histo -> %d\n", foo);
minp = 1e10;
seuil = 0.700 * maxp;
fprintf(stderr, " seuil = %f\n", seuil);
for (offset=0; offset<(src->width*src->height); offset++) {
pente = tmp.R[offset];
if (pente > seuil) {
if (pente < minp) minp = pente;
}
if (pente > maxp) maxp = pente;
}
// fprintf(stderr, " minp = %f maxp = %f\n", minp, maxp);
/* recopie dans l'image destination avec translation hauteur */
for (offset=0; offset<(src->width*src->height); offset++) {
pente = tmp.R[offset] - minp;
if (pente < 0.0) pente = 0.0;
dst->R[offset] = pente;
dst->G[offset] = pente;
dst->B[offset] = pente;
}
foo = fimg_killborders(dst);
if (foo) fprintf(stderr, " killborder -> %d\n", foo);
/* clean the memory */
fimg_destroy(&tmp);
return 0;
}
/* ------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
FloatImg src, dst;
char *infile, *outfile;
int foo;
verbosity = 1; /* FIXME */
if (3 != argc) {
fprintf(stderr, "'%s' need 2 args : infile & outfile\n", argv[0]);
fimg_print_version(0);
exit(1);
}
infile = argv[1]; outfile = argv[2];
if (verbosity) fprintf(stderr,"*** MNT %s -> %s\n", infile, outfile);
foo = fimg_create_from_dump(infile, &src);
if (foo) {
fprintf(stderr, "err %d loading image '%s'\n", foo, infile);
exit(1);
}
foo = fimg_clone(&src, &dst, 0);
if (foo) {
fprintf(stderr, "err %d cloning image\n", foo);
exit(1);
}
fimg_clear(&dst);
foo = brotche_mnt_style(&src, &dst);
if (foo) {
fprintf(stderr, "something weird happen %d\n", foo);
exit(1);
}
foo = fimg_export_picture(&dst, outfile, 0);
if (foo) {
fprintf(stderr, "err %d exporting to %s\n", foo, outfile);
exit(1);
}
/* clean the memory */
fimg_destroy(&src);
fimg_destroy(&dst);
return 0;
}
/* ------------------------------------------------------------------- */

View File

@ -1,154 +0,0 @@
/*
* MOVEPIXELS
*
* This is experimental, do not use in production !
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <floatimg.h>
int verbosity;
/* ------------------------------------------------------------------- */
int displace(FloatImg *psrc, FloatImg *pshift, FloatImg *pdst, float k)
{
int xd, yd, xs, ys;
float rgb[3], disp[3], maxv;
float minmax[6];
int foo, inside, outside;
float dltr, dltg, dltb; /* delta des minmax */
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %p %g )\n", __func__,
psrc, pshift, pdst, k);
#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, pshift)) {
fprintf(stderr, "%s: bad shift image %d\n", __func__, pshift->type);
return -8;
}
if (fimg_images_not_compatible(psrc, pdst)) {
fprintf(stderr, "%s: bad dst image %d\n", __func__, pdst->type);
return -8;
}
foo = fimg_get_minmax_rgb(pshift, minmax);
if (verbosity) {
fimg_print_minmax(minmax, (char *)__func__);
}
dltr = minmax[1] - minmax[0];
dltg = minmax[3] - minmax[2];
dltb = minmax[5] - minmax[4];
if (verbosity) fprintf(stderr, "delta shift %f %f %f\n", dltr, dltg, dltb);
maxv = fimg_get_maxvalue(psrc);
inside = outside = 0;
/* hardcoded parameters. this is very dirty :) */
#define MULT (140.0)
#define OFFS (70.0)
/* loop over all the pixels of the DESTINATION picture */
for (yd=0; yd<pdst->height; yd++) {
for (xd=0; xd<pdst->width; xd++) {
fimg_get_rgb(pshift, xd, yd, disp);
xs = xd + ((disp[0]/dltr*MULT) - OFFS);
ys = yd + ((disp[2]/dltb*MULT) - OFFS);
if ( xs<0 || xs>psrc->width ||
ys<0 || ys>psrc->height ) {
rgb[0] = maxv; /* fucking bug XXX */
rgb[1] = rgb[2] = 0.0;
outside++;
}
else {
fimg_get_rgb(psrc, xs, ys, rgb);
inside++;
}
fimg_put_rgb(pdst, xd, yd, rgb);
}
}
// fprintf(stderr, "%s: inside %d outside %d\n", __func__, inside, outside);
return 0;
}
/* ------------------------------------------------------------------- */
int move_the_pixels(char *infile, char *statfile, char *outfile, int k)
{
int foo;
FloatImg src, shift, dst;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %s %s 0x%04x )\n", __func__,
infile, outfile, k);
#endif
/* 'infile' contains the shifting values */
foo = fimg_create_from_dump(infile, &shift);
if (foo) {
fprintf(stderr, "%s: error loading '%s'\n", __func__, infile);
return foo;
}
fimg_clone(&shift, &dst, 0);
foo = fimg_create_from_dump(statfile, &src);
if (foo) {
fprintf(stderr, "%s: error loading 'cumul.fimg'\n", __func__);
return foo;
}
foo = displace(&src, &shift, &dst, 42.42);
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;
}
/* ------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo;
char *srcfile, *dstfile;
if (3 != argc) {
fprintf(stderr, "usage:\n\t%s src.fimg dst.fimg\n", argv[0]);
exit(1);
}
srcfile = argv[1];
dstfile = argv[2];
verbosity = 0;
foo = move_the_pixels(srcfile, "cumul.fimg", dstfile, 3);
// fprintf(stderr, "move pixels %s -> %s = %d\n", srcfile, dstfile, foo);
return 0;
}
/* ------------------------------------------------------------------- */

View File

@ -1,110 +0,0 @@
/*
* another ugly experiment
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include "../floatimg.h"
int verbosity;
/* --------------------------------------------------------------- */
int triplane_muxer(FloatImg *sr, FloatImg *sg, FloatImg *sb,
FloatImg *dst, int flages)
{
int foo;
int sz;
if (FIMG_TYPE_RGB != dst->type) {
fprintf(stderr, "%s: dst picz must be RGB, was %d\n",
__func__, dst->type);
return -99;
}
if ( fimg_images_not_compatible(sr, sg) ||
fimg_images_not_compatible(sr, sb) ||
fimg_images_not_compatible(sr, dst) ) {
fprintf(stderr, "%s: compatibility error\n", __func__);
return -2;
}
sz = sr->width * sr->height * sizeof(float);
memcpy(dst->R, sr->R, sz);
memcpy(dst->G, sg->G, sz);
memcpy(dst->B, sb->B, sz);
return 0;
}
/* --------------------------------------------------------------- */
int try_this_muxplane(char *fr, char *fg, char *fb, char *dst, int flags)
{
int foo;
FloatImg imr, img, imb, dest;
fprintf(stderr, "muxing: %s %s %s -> %s\n", fr, fg, fb, dst);
foo = fimg_create_from_dump(fr, &imr);
if (foo) {
fprintf(stderr, "%s: err %d loading %s\n", __func__, foo, fr);
return -1;
}
foo = fimg_create_from_dump(fg, &img);
if (foo) {
fprintf(stderr, "%s: err %d loading %s\n", __func__, foo, fr);
return -1;
}
foo = fimg_create_from_dump(fb, &imb);
if (foo) {
fprintf(stderr, "%s: err %d loading %s\n", __func__, foo, fr);
return -1;
}
fimg_clone(&imr, &dest, 0);
foo = triplane_muxer(&imr, &img, &imb, &dest, 0);
if (foo) {
fprintf(stderr, "%s: err %d\n", __func__, foo);
return foo;
}
foo = fimg_export_picture(&dest, dst, 0);
if (foo) {
fprintf(stderr, "%s: err %d exporting to %s\n", __func__, foo, dst);
return foo;
}
fimg_destroy(&imr); fimg_destroy(&img);
fimg_destroy(&imb); fimg_destroy(&dest);
return 0;
}
/* --------------------------------------------------------------- */
int main(int argc, char *argv[])
{
int foo;
if (5 != argc) {
fprintf(stderr, "ERROR: %s need four fimg files arguments\n",
argv[0]);
return 1;
}
/*
* and now, we have to decipher options on the
* command line.
*/
foo = try_this_muxplane(argv[1], argv[2], argv[3], argv[4], 0);
if (foo) {
fprintf(stderr, "oups %d\n", foo);
exit(1);
}
return 0;
}
/* --------------------------------------------------------------- */

View File

@ -1,49 +0,0 @@
/*
* tests du systeme de cache
*/
#include <stdio.h>
#include <sys/time.h>
#include "../floatimg.h"
#include "cachengn.h"
int verbosity;
#define IMGW 320
#define IMGH 240
#define SIZE 5 // number of slots
#define NBRI 1000
/* ------------------------------------------------------------ */
int main(int argc, char *argv[])
{
int foo;
FloatImg *picz;
char *fname = "quux.fimg";
fprintf(stderr, "\nTest of the cache engin - %s %s\n",
__DATE__, __TIME__);
cachengn_print_version(1);
foo = init_empty_cache(IMGW, IMGH, SIZE, NBRI);
fprintf(stderr, " init_empty_cache --> %d\n", foo);
foo = liste_le_cache((unsigned int)'U');
fprintf(stderr, " liste le cache --> %d\n", foo);
picz = give_me_thiz_picz(fname, 0);
if (NULL == picz) {
fprintf(stderr, " error 'givemeapicz' on '%s'\n", fname);
}
picz = give_me_thiz_picz(fname, 0);
if (NULL == picz) {
fprintf(stderr, " error 'givemeapicz' on '%s'\n", fname);
}
return 0;
}
/* ------------------------------------------------------------ */

View File

@ -1,24 +0,0 @@
#!/bin/bash
GRABOPT=" -vv -d /dev/video0 -n 400 -p 0.5 -u "
SPOOL=${HOME}/TMP
echo ; echo ; echo
for capture in red green blue
do
image=${SPOOL}/${capture}.fimg
echo grabbing $image
grabvidseq ${GRABOPT} -o $image
echo
done
./muxplanes "${SPOOL}/red.fimg" \
"${SPOOL}/green.fimg" \
"${SPOOL}/blue.fimg" \
yo.fimg
echo $0 "got a" $?
fimgstats -v yo.fimg

View File

@ -10,7 +10,6 @@ OBJS = fifo.o sfx.o crapulator.o glitches.o metriques.o \
filterstack.o single.o
DEPS = ../floatimg.h \
../libfloatimg.a \
fifo.h crapulator.h metriques.h glitches.h sfx.h \
filterstack.h crapdef.h crapstr.h single.h
@ -41,19 +40,19 @@ singlepass: singlepass.c ${DEPS} ${OBJS} Makefile
# some files are magically generated, sorry.
#
crapdef.h: crapulors.liste Makefile craplist2h.awk
< $< ./craplist2h.awk > $@
./craplist2h.awk < $< | tee $@
crapstr.h: crapulors.liste Makefile craplist2str.awk
< $< ./craplist2str.awk > $@
./craplist2str.awk < $< | tee $@
# ---------------------------------------------------------
#
# a lot of silly functions
#
crapulator.o: crapulator.c $(DEPS) Makefile
crapulator.o: crapulator.c ${DEPS} Makefile
gcc ${COPT} -c $<
fifo.o: fifo.c fifo.h $(DEPS) Makefile
fifo.o: fifo.c fifo.h Makefile
gcc ${COPT} -c $<
sfx.o: sfx.c ${DEPS} Makefile

View File

@ -3,7 +3,7 @@
Avec toutes ces fonctions disponibles et `grabvidseq`, nous
savons faire des images **floues**. L'étape suivante, les plus
pervers d'entre vous le savent déja, est celle de la création
de **films flous** dans le domaine spatio-temporel.
de **films flous** dans le domaine spacio-temporel.
À l'heure actuelle, il y a plusieurs programmes distincts. Le premier
(fonderie) fait une moyenne mobile sur N images consécutives,
@ -20,15 +20,16 @@ destinés à augmenter la kitchitude du produit final. Ils peuvent être chainé
les uns après les autres, à l'entrée et à la sortie du process
de floutagement.
Ces filtres ont chacun un nom, utilisable dans une chaine de filtres.
Ces filtres ont chacun un nom et un numéro. que l'on peut (en théorie)
utiliser indistinctement dans une chaine de filtres.
L'option `-L` de ces logiciels permet d'obtenir la liste des filtres.
Pour ne rien filtrer, utilisez le filtre `none`, il est là pour ça.
Une chaine de filtres est constituée d'une liste de nom
Une chaine de filtres est constituée d'une liste de nom ou de numéro
de filtre, séparés par le caractère `:`, une façon de faire très
classique dans notre univers, en fait.
classique dans notre univers, en fait. Et si on veut prendre des risques,
on doit continuer à appeler les filtres par leur numéro, jdçjdr.
`mirsplit:ctr2x2:killlines`
`mirsplit:ctr2x2:3:killlines`
Nous allons donc voir quelques exemples un peu plus loin.
@ -69,12 +70,12 @@ GRABDIR="/spool/tth/fonderie"
FONDEUR="$HOME/Devel/FloatImg/Fonderie/fonderie"
GLOB=${GRABDIR}'/?????.fimg'
${FONDEUR} -I "$GLOB" -E cos01:trinitron -F classtrial -T 30
${FONDEUR} -I "$GLOB" -E cos01:25 -T 30 -F 2:classtrial
```
Votre machine va maintenant mouliner avec entrain et persévérance,
puis
ensuite il vous suffira d'encoder toutes les images générées dans
ensuite il suffit d'encoder toutes les images générées dans
`p8/` (répertoire de sortie par défaut)
avec une incantation de ffmpeg :
@ -135,8 +136,6 @@ usage:
## Conclusion
Tout cela est bien rigolo :)
**Use the source, Luke**

View File

@ -6,19 +6,18 @@
#
BEGIN {
print "// -------------------------------------"
print "// -----------------------------------"
print "// generated file, do not edit by hand !"
print "// -------------------------------------"
print "// -----------------------------------"
}
# $1 is the badly brain-designed numeric id
# $2 is the user name of the filter
{
name = sprintf("CR_%s", $2)
printf "#define %-15s (%d)\n", name, $1
printf "#define CR_%s (%d)\n", $2, $1
}
END {
print "\n// generated file, do not edit by hand !"
print "// generated file, do not edit by hand !"
}

View File

@ -0,0 +1,27 @@
#!/usr/bin/awk -f
#
# this utility script make a file who
# is includet by 'crapulator.c'
#
BEGIN {
print "// -----------------------------------"
print "// generated file, do not edit by hand";
print "// -----------------------------------"
print "Crapulor CrapL[] = {";
}
# $1 is the badly brain-designed numeric id
# $2 is the user name of the filter
# $3 and $4 are two not used parameters
#
{
printf " { CR_%s, \"%s\", %d, %f }, // id=%d\n",
$2, $2, $3, $4, $1;
}
END {
print " { -1, NULL }"
print " };"
print "// generated file, do not edit by hand"
}

View File

@ -4,7 +4,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
@ -82,7 +81,7 @@ FloatImg img;
int foo, retval;
FimgFilter3x3 *pfiltre;
static FimgFilter3x3 lowpass = {
FimgFilter3x3 lowpass = {
{
1.0, 2.0, 1.0,
2.0, 4.0, 2.0,
@ -91,8 +90,7 @@ static FimgFilter3x3 lowpass = {
16.0, 0.0
};
static FimgFilter3x3 hipass = {
/* there was a bug with this filter */
FimgFilter3x3 hipass = {
{
-1.0, -1.0, -1.0,
-1.0, 9.0, -1.0,
@ -101,12 +99,11 @@ static FimgFilter3x3 hipass = {
1.0, 0.0
};
static FimgFilter3x3 diagonal = {
/* there was a bug with this filter */
FimgFilter3x3 diagonal = {
{
4.0, 1.0, 0.0,
2.0, 1.0, 0.0,
1.0, 0.0, -1.0,
0.0, -1.0, -4.0,
0.0, -1.0, -2.0,
},
1.0, 0.0
};
@ -154,133 +151,6 @@ fimg_destroy(&img);
return retval;
}
/* -------------------------------------------------------------- */
int run_killrgb_0(FloatImg *img, int k)
{
FloatImg tmp;
int ret;
// fprintf(stderr, "----> %s\n", __func__);
memset(&tmp, 0, sizeof(FloatImg));
fimg_clone(img, &tmp, 0);
ret = fimg_killrgb_v(img, &tmp, k);
fimg_copy_data(&tmp, img);
fimg_destroy(&tmp);
// fprintf(stderr, "%s ---->\n", __func__);
return ret;
}
/* -------------------------------------------------------------- */
static int run_pixelize_0(FloatImg *img, int k)
{
FloatImg tmp;
int ret;
memset(&tmp, 0, sizeof(FloatImg));
fimg_clone(img, &tmp, 0);
ret = fimg_pixelize_h_0(img, &tmp, k);
fimg_copy_data(&tmp, img);
fimg_destroy(&tmp);
return ret;
}
/* -------------------------------------------------------------- */
static int run_pixelize_random(FloatImg *img, int k)
{
FloatImg tmp;
int ret;
memset(&tmp, 0, sizeof(FloatImg));
fimg_clone(img, &tmp, 0);
ret = fimg_pixelize_h_rnd(img, &tmp, k);
if (verbosity > 1) fprintf(stderr, "in %s, pixelize H rnd -> %d\n",
__func__, ret);
fimg_copy_data(&tmp, img);
fimg_destroy(&tmp);
return ret;
}
/* -------------------------------------------------------------- */
static int run_decomprgbz_color(FloatImg *img, int k)
{
FloatImg tmp;
int ret;
memset(&tmp, 0, sizeof(FloatImg));
fimg_clone(img, &tmp, 0);
ret = fimg_decomp_rgbz_color(img, &tmp, k);
fimg_copy_data(&tmp, img);
fimg_destroy(&tmp);
return ret;
}
/* -------------------------------------------------------------- */
/* nouveau 14 mai 2022 */
static int run_gr2popcol(FloatImg *img, int k)
{
FloatImg tmp;
int ret;
memset(&tmp, 0, sizeof(FloatImg));
fimg_clone(img, &tmp, 0);
ret = graylevel2popcolors(img, &tmp, k);
fimg_copy_data(&tmp, img);
fimg_destroy(&tmp);
return ret;
}
/* -------------------------------------------------------------- */
/* new Sun Feb 12 11:30:02 CET 2023 */
static int run_rndfluffy(FloatImg *img, int k)
{
FloatImg tmp;
int ret;
memset(&tmp, 0, sizeof(FloatImg));
fimg_clone(img, &tmp, 0);
ret = fimg_make_rndfluffy_lines(img, &tmp, k);
fimg_copy_data(&tmp, img);
fimg_destroy(&tmp);
return ret;
}
/* -------------------------------------------------------------- */
static int run_decomprgbz_gray(FloatImg *img, int k)
{
FloatImg tmp;
int ret;
/* ugly code here */
memset(&tmp, 0, sizeof(FloatImg));
fimg_clone(img, &tmp, 0);
ret = fimg_decomp_rgbz_gray(img, &tmp, k);
fimg_copy_data(&tmp, img);
fimg_destroy(&tmp);
return ret;
}
/* -------------------------------------------------------------- */
/* new Sun Jul 16 11:27:43 UTC 2023 */
int run_suprbg(FloatImg *img, int notused)
{
FloatImg tmp;
int ret;
if (notused) {
fprintf(stderr, "FATAL: invalid notused in %s\n", __func__);
abort();
}
/* ugly code here */
memset(&tmp, 0, sizeof(FloatImg));
fimg_clone(img, &tmp, 0);
ret = poke_sup_rb_g(img, &tmp);
fimg_copy_data(&tmp, img);
fimg_destroy(&tmp);
return 0;
}
/* -------------------------------------------------------------- */
/*
* This is the main filter engine used both for input and
* output processing. It can be called by the filterstack
@ -399,28 +269,19 @@ switch (idFx) {
retval = fimg_power_2(image, image, 1000.0);
break;
case CR_triplemul:
retval = fimg_sfx_triplemul(image, image, 0);
break;
/* here are the glitches */
case CR_bsombra: /* experiment ! */
retval = des_bords_sombres_a(image, 160);
break;
case CR_bsombrb: /* experiment ! */
retval = des_bords_sombres_b(image, 120);
retval = des_bords_sombres_b(image, 160);
break;
case CR_vsglitch:
/* please make this function more tweakable */
retval = vertical_singlitch(image, 290+rand()%45,
fval, 0.19, 0);
break;
case CR_crumphard: /* new june 1st 2021, in the bibcave */
retval = fimg_crump_hard(image, image, fval, 0);
break;
case CR_rndblks:
retval = random_blocks(image, 70);
break;
@ -437,52 +298,22 @@ switch (idFx) {
retval = plot_multidots(image, 42);
break;
case CR_message:
fprintf(stderr, "### msg from pid %d, fval=%f ###\n",
getpid(), fval);
/* here, we can display stats ! */
fimg_describe(image, "in crapulator");
retval = 0;
break;
case CR_nothing:
retval = do_something(image, 3);
break;
case CR_killrgb0:
retval = run_killrgb_0(image, 0);
break;
case CR_pixelizh:
retval = run_pixelize_0(image, 8);
break;
case CR_pixelizv:
retval = run_pixelize_0(image, 32);
break;
case CR_pixelrand:
retval = run_pixelize_random(image, 16);
break;
case CR_splitlevel:
retval = fimg_split_level(image, image, 0);
break;
case CR_decrgbzc:
retval = run_decomprgbz_color(image, 0);
break;
case CR_decrgbzg:
retval = run_decomprgbz_gray(image, 0);
break;
case CR_hilightr:
retval = fimg_highlight_color(image, image, 'R', 1.717);
break;
case CR_gr2popcol:
retval = run_gr2popcol(image, -1);
break;
case CR_fluffy:
retval = run_rndfluffy(image, 75);
break;
case CR_suprbg:
retval = run_suprbg(image, 0);
break;
default :
fprintf(stderr, "%s : effect #%d invalid\n",
__func__, idFx);
@ -518,25 +349,13 @@ void list_crapulors(char *texte)
int idx;
#define OUT stdout
if (verbosity) {
fprintf(stderr, "We have around %ld filters now !\n", NBCRAP);
}
if (NULL!=texte && verbosity)
fprintf(OUT, " _________ %s _________\n", texte);
fprintf(OUT, "______________. %s\n", texte);
for (idx=0; CrapL[idx].id!=-1; idx++) {
if (verbosity) {
fprintf(OUT, " %-12s | %4d | %5d | %8.3f\n",
fprintf(OUT, " %-12s | %4d | %5d | %8.3f\n",
CrapL[idx].name,
CrapL[idx].id,
CrapL[idx].ipar,
CrapL[idx].fpar);
}
else {
fprintf(OUT, "%s\n", CrapL[idx].name);
}
}
#undef OUT
}

View File

@ -27,21 +27,10 @@
26 rndblks 1 1.0
27 shiftln0 1 1.0
28 qsortrgb 2 1.0
29 triplemul 3 1.0
30 multidots 100 1.333
31 diagonal 1 1.0
32 vsglitch 1 1.0
33 crumphard 1 1.0
42 nothing 42 3.1415926
43 killrgb0 1 9
45 hilightr 1 1.717
46 pixelizh 1 1.111
47 pixelizv 1 1.111
48 pixelrand 1 1
49 splitlevel 1 1
50 decrgbzc 1 99
51 decrgbzg 1 99
60 gr2popcol 1 99
61 fluffy 1 0.12
62 suprbg 1 0
99 message 1 1.0
-1 end 1 1.0

View File

@ -5,7 +5,6 @@
*/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <malloc.h>
@ -26,7 +25,7 @@ extern int verbosity;
static A_Fifo g_fifo;
/* -------------------------------------------------------------- */
static inline int big_adder(FloatImg *from, FloatImg *to)
static int big_adder(FloatImg *from, FloatImg *to)
{
int size, idx;
@ -90,7 +89,7 @@ int export_fifo(char *fname, int notused)
int foo, type;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' %d )\n", __func__, fname, notused);
fprintf(stderr, ">>> %s ( '%s' %d )\n", __func__, fname, step);
#endif
foo = faire_la_somme(&g_fifo, NULL, 1);

View File

@ -4,7 +4,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include <alloca.h>

View File

@ -4,7 +4,6 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <glob.h>
@ -200,7 +199,7 @@ int fifosize = 10;
char *in_pattern = "capture/?????.fimg";
char *out_dir = "p8";
int outfmt = FILE_TYPE_PNG;
int blanks = 10;
int blanks = 20;
char *InFchain = "none";
char *OutFchain = "none";
@ -229,7 +228,6 @@ while ((opt = getopt(argc, argv, "B:E:F:ghI:LO:T:vw:x:")) != -1) {
break;
case 'v': verbosity++;
break;
default: exit(1);
}
}

View File

@ -7,7 +7,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
@ -151,38 +150,36 @@ int pass, szimg, osrc, odst;
szimg = picture->width * picture->height;
for (pass=0; pass<szimg/32; pass++) {
osrc = rand() % szimg;
odst = rand() % szimg;
picture->R[odst] = (picture->R[osrc] + picture->R[odst]) / 2.0;
picture->G[odst] = (picture->G[osrc] + picture->G[odst]) / 2.0;
picture->B[odst] = (picture->B[osrc] + picture->B[odst]) / 2.0;
}
return 0;
}
/* -------------------------------------------------------------- */
/*
* FIXME XXX
*/
int random_blocks(FloatImg *picture, int percent)
{
int x, y;
if ( (picture->width%16) || (picture->height%16) )
{
fprintf(stderr, "WARNING %s: %dx%d bad dims\n", __func__,
fprintf(stderr, "%s: %d%d bad dims\n", __func__,
picture->width, picture->height);
// return -1;
}
for (y=16; y<picture->height-16; y+=16) {
for (x=16; x<picture->width-16; x+=16) {
for (y=0; y<picture->height; y+=16) {
for (x=0; x<picture->width; x+=16) {
if (percent < (rand()%100) ) {
un_petit_flou_8x8(picture, x, y);
un_petit_flou_8x8(picture, x+8, y);
un_petit_flou_8x8(picture, x, y+8);
un_petit_flou_8x8(picture, x+8, y+8);
}
}
}

View File

@ -10,7 +10,6 @@
*/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <glob.h>
@ -58,10 +57,6 @@ fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__, ptr_glob,
ptr_idxval, method);
#endif
if (0 == method) {
fprintf(stderr, "\tWTF? in %s, method was ZERO?\n", __func__);
}
nombre = ptr_glob->gl_pathc;
/* allocate the array for the sorting action */
@ -70,7 +65,7 @@ if (NULL==idxvalues) {
fprintf(stderr, "MEMORY ERROR in %s\n", __func__);
exit(1);
}
// fprintf(stderr, "IdxValues array at %p\n", idxvalues);
fprintf(stderr, "IdxValues array at %p\n", idxvalues);
*ptr_idxval = idxvalues;
average = 0.0;
@ -108,7 +103,7 @@ if (verbosity > 1) {
average /= (double)nombre;
*p_average = average;
fprintf(stderr, "\naverage of ??? is %f\n", average);
fprintf(stderr, "\naverage %f\n", average);
return 0;
}
@ -126,18 +121,18 @@ int foo, idx, ipng, w, h, step;
int curpix;
int iarray[3];
char *cptr, line[200];
float coef;
float coef, value;
double meanmetric;
IdxValue *idx_values; /* gni? */
fprintf(stderr, " interpolate from '%s' to '%s' with %d steps.\n",
fprintf(stderr, " interpolate from '%s' to '%s' with %d steps.\n",
pattern, outdir, Nsteps);
if (negative) fprintf(stderr, "%s: negative ON\n", __func__);
memset(&globbuf, 0, sizeof(glob_t));
foo = glob(pattern, 0, NULL, &globbuf);
fprintf(stderr, " globbing '%s' -> %d, %d files found\n",
fprintf(stderr, "globbing '%s' -> %d, %d files found\n",
pattern, foo, (int)globbuf.gl_pathc);
if (0 == globbuf.gl_pathc) {
fprintf(stderr, "%s : no file found, aborting\n", __func__);
@ -179,6 +174,7 @@ for (idx=0; idx<globbuf.gl_pathc; idx++) {
fprintf(stderr, "load %s from dump -> %d\n", cptr, foo);
continue;
}
value = idx_values[idx].value;
/* here was the input filter */
foo = filterstack_run(0, &B, 0);
@ -257,7 +253,7 @@ int sort = 0;
char *InFchain = "0";
char *OutFchain = "0";
fprintf(stderr, "*** %s\n\tcompiled on %s %s\n", argv[0],
fprintf(stderr, "*** %s : compiled by tTh, %s %s\n", __FILE__,
__DATE__, __TIME__);
fimg_print_version(2);
@ -278,7 +274,6 @@ while ((opt = getopt(argc, argv, "E:F:hLnS:v")) != -1) {
case 'S': sort = atoi(optarg); break;
case 'v': verbosity++; break;
case 'n': negative = 1; break;
default: exit(1);
}
}
@ -307,14 +302,13 @@ if (verbosity) {
fprintf(stderr, "\toutput dir '%s'\n", argv[optind+1]);
fprintf(stderr, "\tsrc filter '%s'\n", InFchain);
fprintf(stderr, "\tout filter '%s'\n", OutFchain);
fprintf(stderr, "\tsort %d\n", sort);
}
if (verbosity > 1) {
fputs("=========================\n", stderr);
puts("=========================");
filterstack_list(0, __FILE__);
filterstack_list(1, __FILE__);
fputs("=========================\n", stderr);
puts("=========================");
}
nbrsteps = atoi(argv[optind+2]);

View File

@ -4,8 +4,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "../floatimg.h"
#include "metriques.h"
@ -86,9 +84,6 @@ for (idx=20; idx < size; idx+=42) {
return 0;
}
/* -------------------------------------------------------------- */
/*
* LR mean left/right
*/
int get_float_metric_LR(FloatImg *pimg, float *where)
{
int coords[4], foo;
@ -100,16 +95,8 @@ coords[2] = pimg->width / 2; // W
coords[3] = pimg->height; // H
foo = stat_zone(pimg, coords, valL);
if (foo) {
fprintf(stderr, "err %d stat zone in %s\n", foo, __func__);
return foo;
}
coords[1] = pimg->width / 2;
foo = stat_zone(pimg, coords, valR);
if (foo) {
fprintf(stderr, "err %d stat zone in %s\n", foo, __func__);
return foo;
}
*where = valL[1] - valR[1];

View File

@ -5,7 +5,6 @@
*/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
@ -21,78 +20,6 @@
*/
extern int verbosity;
/* -------------------------------------------------------------- */
/*
* nouveau Sun Jul 16 07:37:22 UTC 2023
*
* may-be this can be an on-place function ?
*
*/
int poke_sup_rb_g(FloatImg *src, FloatImg *dst)
{
int idx, nbpix, foo;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p )\n", __func__, src, dst);
#endif
if ( (foo=fimg_images_not_compatible(src, dst)) )
{
fprintf(stderr, "%s: no compat %d\n", __func__, foo);
return foo;
}
nbpix = src->width * src->height;
if (verbosity > 1)
fprintf(stderr, "%s work on %d pixels\n", __func__, nbpix);
for (idx=0; idx<nbpix; idx++) {
dst->R[idx] = src->R[idx];
dst->B[idx] = src->B[idx];
if (src->R[idx] < src->B[idx])
dst->G[idx] = src->R[idx];
else
dst->G[idx] = src->B[idx];
}
return 0;
}
/* -------------------------------------------------------------- */
/* nouveau 14 mai 2022 rue Ernest Renan */
int graylevel2popcolors(FloatImg *src, FloatImg *dst, int k)
{
int x, y;
float rgb[3];
float theoric_maxval, real_maxv;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__, src, dst, k);
#endif
theoric_maxval = src->fval * src->count;
real_maxv = fimg_get_maxvalue(src);
#if DEBUG_LEVEL
fprintf(stderr, "maxval: theoric= %.3f real= %.3f\n", \
theoric_maxval, real_maxv);
#endif
fimg_clear(dst);
for (y=0; y<src->height; y++) {
for (x=0; x<src->width; x++)
{
fimg_get_rgb(src, x, y, rgb);
rgb[0] = real_maxv * fabs(cos(21.0 * rgb[0] / real_maxv));
rgb[1] = real_maxv * fabs(cos(31.0 * rgb[1] / real_maxv));
rgb[2] = real_maxv * fabs(cos(11.0 * rgb[2] / real_maxv));
fimg_put_rgb(dst, x, y, rgb);
}
}
return 0;
}
/* -------------------------------------------------------------- */
/*
* please, add some parameters !
@ -119,43 +46,21 @@ return -1;
}
/* -------------------------------------------------------------- */
/* nouveau du premier dimanche de 2020 'nextgen' */
/* CE TRUC NE MARCHE PAS COMME PRÉVU */
static int pixel_trinitron(FloatImg *pimg, int pos[4], float *fvals)
{
int x, y, pline, off;
int ym;
fimg_clear_rectangle(pimg, pos);
ym = pos[1]+pos[3]-1;
#define FDIM 0.60
for (y=pos[1]; y<ym; y++) {
for (y=pos[1]; y<pos[1]+pos[3]; y++) {
pline = y*pimg->width;
for (x=0; x<5; x++) {
off = pline + (x+pos[0]);
/* wtf i'm doing here ? */
if ( (pos[1]==y) || (ym-1==y) ) {
pimg->R[off] = fvals[0] * FDIM;
pimg->G[off+5] = fvals[1] * FDIM;
pimg->B[off+10] = fvals[2] * FDIM;
}
else {
pimg->R[off] = fvals[0];
pimg->G[off+5] = fvals[1];
pimg->B[off+10] = fvals[2];
}
for (x=pos[0]+2; x<pos[0]+pos[2]-2; x++) {
off = pline + x;
pimg->R[off] = fvals[0];
pimg->G[off] = fvals[1];
pimg->B[off] = fvals[2];
}
}
return 0;
}
/*
* need more explanation, need more work
*/
int trinitron(FloatImg *pimg, int notused)
{
int x, y, coo[4], foo;
@ -165,31 +70,16 @@ float vals[3];
fprintf(stderr, ">>> %s ( %p %d )\n", __func__, pimg, notused);
#endif
/* XXX CRITICAL BUG XXX
*
* what to do if STP is not a modulo of
* the width (or size) of the picture ?
* why if img height is 600 and stp was 16 ?
tth@redlady:~/Devel/FloatImg/Fonderie$ bc -l
600/16
37.50000000000000000000
*
* And this mistake is all around the code /o\
*
*/
#define STP 8 /* stepd for x & y axex */
#define STP 16 /* stepd for x & y axex */
coo[2] = coo[3] = STP;
for (y=0; y < pimg->height; y+=STP) {
for (y=0; y<pimg->height; y+=STP) {
coo[1] = y;
for (x=0; x < pimg->width; x+=STP) {
for (x=0; x<pimg->width; x+=STP) {
coo[0] = x;
foo = stat_zone(pimg, coo, vals);
if (foo) abort();
/* next step : plot the datas */
// XXX fprintf(stderr, "%s %6d %6d\n", __func__, x, y);
pixel_trinitron(pimg, coo, vals);
}
}
@ -421,39 +311,19 @@ return 0;
/* -------------------------------------------------------------- */
/* nouveau Mon 10 May 2021 08:46:02 PM CEST
* chez Eric 1KA */
int des_bords_sombres_b(FloatImg *pimg, int nbre)
int des_bords_sombres_b(FloatImg *pimg, int offset)
{
int idx, x, foo;
float coef, *fptr;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %d )\n", __func__, pimg, offset);
#endif
for (idx=0; idx<nbre; idx++) {
coef = (float)idx / (float)nbre;
fptr = pimg->R + (idx*pimg->width);
for (x=0; x<pimg->width; x++) *fptr++ *= coef;
fptr = pimg->G + (idx*pimg->width);
for (x=0; x<pimg->width; x++) *fptr++ *= coef;
fptr = pimg->B + (idx*pimg->width);
for (x=0; x<pimg->width; x++) *fptr++ *= coef;
foo = (pimg->height-idx) - 1;
fptr = pimg->R + (foo*pimg->width);
// fprintf(stderr, "%5d %9.3f %p\n", foo, coef, fptr);
for (x=0; x<pimg->width; x++) *fptr++ *= coef;
fptr = pimg->G + (foo*pimg->width);
for (x=0; x<pimg->width; x++) *fptr++ *= coef;
fptr = pimg->B + (foo*pimg->width);
for (x=0; x<pimg->width; x++) *fptr++ *= coef;
if (offset<0 || offset>=pimg->width) {
fprintf(stderr, "%s: offset %d is bad\n", __func__, offset);
return -66;
}
// fprintf(stderr, "WARNING: %s badly implemented\n", __func__);
return 0;
return -1;
}
/* -------------------------------------------------------------- */
/*

View File

@ -3,11 +3,8 @@
* ---------------------------------------------------
*/
int graylevel2popcolors(FloatImg *src, FloatImg *dst, int k);
int incrustation_vignette(FloatImg *src, FloatImg *dst, int k);
int poke_sup_rb_g(FloatImg *src, FloatImg *dst);
int trinitron(FloatImg *pimg, int notused);

View File

@ -1,6 +1,5 @@
/*
SINGLE PICZ PROCESSOR
SINGLE
experimental and/or testing code, do not use in
production.
@ -9,8 +8,6 @@
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <stdint.h>
#include <sys/time.h>
#include "../floatimg.h"
@ -26,7 +23,7 @@
static int nextpng, counter;
static char *destination;
static int chainfilter;
// static int outtype;
static int outtype;
/* and the classic global var */
extern int verbosity;
@ -101,6 +98,7 @@ fprintf(stderr, "%s : %s\n", __FILE__, title);
fprintf(stderr, " nextpng %d\n", nextpng);
fprintf(stderr, " counter %d\n", counter);
fprintf(stderr, " chainfilter %d\n", chainfilter);
fprintf(stderr, " destination %s\n", destination);
if (k) {

View File

@ -6,7 +6,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <glob.h>
@ -25,9 +24,6 @@
int verbosity;
/* ----------------------------------------------------------- */
/*
* parameter 'duplic' is the repetition factor
*/
int run_the_singlepass(char *globber, char *destdir, int duplic,
int fchain, int outfmt)
{
@ -38,11 +34,11 @@ char *fname;
double elapsed;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' '%s' %d %d %d )\n", __func__,
globber, destdir, duplic, fchain, outfmt);
fprintf(stderr, ">>> %s ( '%s' '%s' %d %d )\n", __func__,
globber, destdir, fchain, outfmt);
#endif
if (verbosity) filterstack_list(fchain, "Run the single pass");
// filterstack_list(fchain, "Run the single pass");
(void)fimg_timer_set(0);
@ -110,15 +106,19 @@ for (idx=0; idx<globbuf.gl_pathc; idx++) {
fprintf(stderr, "error %d on push_picture\n", foo);
return foo;
}
if (loop) {
/* this is just a wip XXX */
microglitch(&image, loop);
}
}
}
fprintf(stderr, "\n\n");
fprintf(stderr, "\n");
globfree(&globbuf);
fimg_destroy(&image);
// single_print_state("end of run", 0);
single_print_state("end of run", 0);
elapsed = fimg_timer_get(0);
fprintf(stderr, "%s: %ld frames, elapsed %.3f s, %.3f fps\n",
@ -155,7 +155,7 @@ char *outdir = "./p8";
int do_xper = 0;
int repeat = 1;
fprintf(stderr, "*** %s\n\tcompiled %s %s\n", argv[0],
fprintf(stderr, "*** %s : compiled %s %s\n", __FILE__,
__DATE__, __TIME__);
fimg_print_version(2);
@ -211,9 +211,6 @@ if (verbosity) {
fprintf(stderr, "\tdo xper %d\n", do_xper);
}
/*
* REAL action here
*/
foo = run_the_singlepass(globbing, outdir, repeat,
FILTERS, FILE_TYPE_PNG);
fprintf(stderr, "\n\tRun the single pass --> %d\n", foo);

View File

@ -4,7 +4,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <glob.h>
@ -40,7 +39,7 @@ double debut, fin;
foo = fimg_create_from_dump(fIname, &image);
if (foo) {
fprintf(stderr, "%s: err %d create from dump\n", __func__, foo);
fprintf(stderr, "err %d create image\n", foo);
exit(1);
}
@ -73,6 +72,8 @@ return 0;
foo = essayer_single("capture/???42.fimg", "/tmp/x8/", STK);
fprintf(stderr, "essayer single -> %d\n", foo);
*/
int essayer_single(char *globpattern, char *destdir, int chain)
{
@ -159,24 +160,23 @@ puts("\t-s\tdo single test");
exit(0);
}
/* ----------------------------------------------------------- */
int experiment(char *fname)
int experiment(void)
{
int foo;
FloatImg image, dest;
fprintf(stderr, "----- EXPERIMENT on '%s' -----\n", fname);
fprintf(stderr, "EXPERIMENT\n");
foo = fimg_create_from_dump(fname, &image);
foo = fimg_create_from_dump("01137.fimg", &image);
if (foo) {
fprintf(stderr, "%s: err %d on create_from_dump\n",
__func__, foo);
fprintf(stderr, "%s: err %d on create\n", __func__, foo);
return -1;
}
foo = fimg_clone(&image, &dest, 0);
foo = fimg_clone(&image, &dest, 1);
foo = fimg_copy_data(&image, &dest);
foo = poke_sup_rb_g(&image, &dest);
fprintf(stderr, "poke sup rb g --> %d\n", foo);
incrustation_vignette(&image, &dest, 0);
fimg_export_picture(&dest, "foo.png", 0);
@ -228,7 +228,7 @@ if (foo) {
}
if (do_xper) {
experiment(infile);
experiment();
return 0;
}
if (do_single) {

View File

@ -5,7 +5,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <math.h>
#include <string.h>
@ -18,17 +17,14 @@ int verbosity;
void fait_un_dessin(FloatImg *dessin)
{
// fprintf(stderr, "je dessine dans %p\n", dessin);
fimg_draw_something(dessin);
}
/* --------------------------------------------------------------------- */
void help(void)
void help(int k)
{
puts("Options :");
puts("\t-d WxH\timage size");
puts("\t-v\tincrease verbosity");
exit(0);
}
/* --------------------------------------------------------------------- */
@ -37,14 +33,14 @@ int main(int argc, char *argv[])
{
FloatImg fimgA, fimgB;
int foo, opt;
int W = 640, H = 480;
int W = 800, H = 600;
double tb;
while ((opt = getopt(argc, argv, "d:hv")) != -1) {
switch(opt) {
case 'd': parse_WxH(optarg, &W, &H);
break;
case 'h': help(); break;
case 'h': help(0); break;
case 'v': verbosity++; break;
}
}
@ -60,19 +56,19 @@ fimg_drand48(&fimgB, 100.0);
foo = fimg_dump_to_file(&fimgB, "B.fimg", 0);
fimg_timer_set(0);
#define NBP 5
#define NBP 500
for (foo=0; foo<NBP; foo++) {
if (verbosity) {
printf("%5d / %5d\n", foo, NBP);
printf("%5d / %5d\n", foo, NBP);
}
fait_un_dessin(&fimgB);
fimg_add_3(&fimgA, &fimgB, &fimgA);
// fimg_mul(&fimgA, &fimgB, &fimgA);
}
tb = fimg_timer_get(0);
fprintf(stderr, "%s = %.2f seconds, %.2f s/p\n", __func__, tb, tb/(double)NBP);
foo = fimg_save_as_pnm(&fimgA, "out.pnm", 0);
foo = fimg_dump_to_file(&fimgA, "out.fimg", 0);
fprintf(stderr, "%s = %f seconds\n", __func__, tb);
foo = fimg_save_as_pnm(&fimgA, "drand48.pnm", 0);
foo = fimg_dump_to_file(&fimgA, "drand48.fimg", 0);
fimg_destroy(&fimgA);
fimg_destroy(&fimgB);

View File

@ -0,0 +1,15 @@
#  experiments
COPT = -Wall -fpic -g -DDEBUG_LEVEL=1 -lm
DEPS = ../floatimg.h ../libfloatimg.a Makefile
LIBS = -ltiff -lpnglite -lcfitsio
all: assemblage extracteur
assemblage: assemblage.c ${DEPS}
gcc $(COPT) $< ../libfloatimg.a $(LIBS) -o $@
extracteur: extracteur.c ${DEPS}
gcc $(COPT) $< ../libfloatimg.a $(LIBS) -o $@

View File

@ -0,0 +1,6 @@
# EXPÉRIMENTATION ÀLC
## ASSEMBLAGE
## EXTRACTEUR

View File

@ -4,7 +4,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "../floatimg.h"

View File

@ -0,0 +1,131 @@
/*
* another ugly experiment
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "../floatimg.h"
// #include "incrustator.h"
int verbosity;
/* ---------------------------------------------- ~~~~~~~~~~~~~~~~ */
/* ---------------------------------------------- ~~~~~~~~~~~~~~~~ */
int essai_extraction(FloatImg *in, FloatImg *out, FimgArea51 *rect)
{
int foo;
int xs, ys, xd, yd;
int count;
float rgb[3];
if (verbosity) {
fimg_describe(in, "source");
fimg_describe(out, "destination");
print_rectangle(__func__, 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;
}
/* ---------------------------------------------- ~~~~~~~~~~~~~~~~ */
void help(int k)
{
puts("Usage:\n\textracteur in.fimg w,h,x,y out.???");
}
/* ---------------------------------------------- ~~~~~~~~~~~~~~~~ */
int main(int argc, char *argv[])
{
int foo, opt;
FloatImg src, dst;
FimgArea51 zone;
char *infile = "foo.fimg";
char *outfile = "out.fimg";
verbosity = 0;
#if 0
for (foo=0; foo<argc; foo++) {
fprintf(stderr, "%9d %s\n", foo, argv[foo]);
}
#endif
while ((opt = getopt(argc, argv, "hv")) != -1) {
switch(opt) {
case 'h': help(0), exit(0); break;
case 'v': verbosity++; break;
default: break;
}
}
if (3 != argc-optind) {
fprintf(stderr, "---- %s errcli c=%d %d ----\n", argv[0],
argc, argc-optind);
help(1);
exit(1);
}
if (verbosity) {
fprintf(stderr, "*** %s %s %s\n", argv[0], __DATE__, __TIME__);
fimg_print_version(1);
}
infile = argv[optind]; outfile = argv[optind+2];
fprintf(stderr, "%s %s -> %s\n", argv[0], infile, outfile);
foo = fimg_create_from_dump(infile, &src);
if (foo) {
fprintf(stderr, "%s: err %d loading image '%s'\n", __func__,
foo, infile);
exit(1);
}
if (4 != parse_rectangle( argv[optind+1], &zone, 0) ) {
fprintf(stderr, "%s: error in parsing of '%s'\n",
argv[0], argv[optind+1]);
exit(1);
}
// zone.w = src.width / 2; zone.h = src.height / 2;
// zone.x = src.width / 4 ; zone.y = src.height / 4;
if (verbosity) print_rectangle(argv[0], &zone);
foo = fimg_create(&dst, zone.w, zone.h, FIMG_TYPE_RGB);
if (foo) {
fprintf(stderr, "NO PICZ EPIC FAIL %d\n", foo);
exit(1);
}
foo = fimg_extractor(&src, &dst, &zone);
if (foo) {
fprintf(stderr, "EXTRACTOR EPIC FAIL %d\n", foo);
exit(1);
}
foo = fimg_export_picture(&dst, outfile, 0);
if (foo) {
fprintf(stderr, "export '%s' -> err %d\n", outfile, foo);
exit(1);
}
return 0;
}
/* ---------------------------------------------- ~~~~~~~~~~~~~~~~ */

View File

@ -1,40 +0,0 @@
# Fonctions
Plein de fonctions qu'il serait bon de documenter :)
## PNG
__Attention__ : la bibliothèque `pnglite`actuellement utilisée pour lire
les fichiers PNG n'accepte que **certains** types de fichiers.
Et en particulier, elle brotche sur ceux produits par ImageMagick !
## FITS
Un Format de fichier utilisé en astronomie.
https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/node1.html
## DICOM
https://en.wikipedia.org/wiki/DICOM et ça semble bien compliqué :(
## Contours
Détecter des contours est une activité respectable. Mais difficile.
## 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.
La fonction `fimg_pixelize_h_rnd` est issue d'une idée qui m'est venue
dans la roulotte de TerreBlanque. Elle a besoin de recherches sur la
dynamique temporelle, et d'une FSM à trois états.
## Dithering
Work in progress...

View File

@ -1,157 +0,0 @@
/*
* DECOMPOSITION RGB
*/
#include <stdio.h>
#include <stdint.h>
#include <sys/time.h>
#include "../floatimg.h"
extern int verbosity;
/* == ---------------------------------------------------- == */
/* some dirty macros */
#define pixidx(fi,x,y) (((y)*fi->width)+(x))
#define getRpix(fi,x,y) (fi->R[ pixidx(fi,(x),(y)) ])
#define getGpix(fi,x,y) (fi->G[ pixidx(fi,(x),(y)) ])
#define getBpix(fi,x,y) (fi->B[ pixidx(fi,(x),(y)) ])
/* A lot of strange and usefull parenthesis */
/* == ---------------------------------------------------- == */
#if DEBUG_LEVEL
static float compute_z_value(float r, float g, float b)
{
double dval;
return 42.0;
}
#endif
/* == ---------------------------------------------------- == */
int fimg_decomp_rgbz_color(FloatImg *psrc, FloatImg *pdst, int k)
{
int x, y, x2, y2;
int w2, h2;
float cumul, vgray;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__,
psrc, pdst, k);
#endif
/*
* XXX useless message ?
*/
if (k) { fprintf(stderr, "k=%d in %s\n", k, __func__); }
fimg_clear(pdst);
w2 = psrc->width/2; h2 = psrc->height/2;
for (y=0; y<h2; y++)
{
y2 = y * 2;
for (x=0; x<w2; x++) {
x2 = x * 2;
cumul = getRpix(psrc, x2, y2) +
getRpix(psrc, x2, y2+1) +
getRpix(psrc, x2+1, y2) +
getRpix(psrc, x2+1, y2+1);
cumul /= 4, vgray = cumul;
pdst->R[pixidx(pdst,x,y)] = cumul;
pdst->R[pixidx(pdst,x+w2,y+h2)] = cumul;
cumul = getGpix(psrc, x2, y2) +
getGpix(psrc, x2, y2+1) +
getGpix(psrc, x2+1, y2) +
getGpix(psrc, x2+1, y2+1);
cumul /= 4, vgray += cumul;
pdst->G[pixidx(pdst,x+w2,y)] = cumul;
pdst->G[pixidx(pdst,x+w2,y+h2)] = cumul;
cumul = getBpix(psrc, x2, y2) +
getBpix(psrc, x2, y2+1) +
getBpix(psrc, x2+1, y2) +
getBpix(psrc, x2+1, y2+1);
cumul /= 4, vgray += cumul;
pdst->B[pixidx(pdst,x,y+h2)] = cumul;
pdst->B[pixidx(pdst,x+w2,y+h2)] = cumul;
}
}
return 0;
}
/* == ---------------------------------------------------- == */
/* PUTAIN LE COPIER/COLLÉ DE BATARD !!! */
int fimg_decomp_rgbz_gray(FloatImg *psrc, FloatImg *pdst, int k)
{
int x, y, x2, y2;
int w2, h2, idx;
float cumul, vgray;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__,
psrc, pdst, k);
#endif
/*
* XXX useless message ?
*/
if (k) { fprintf(stderr, "k=%d in %s\n", k, __func__); }
fimg_clear(pdst);
w2 = psrc->width/2; h2 = psrc->height/2;
for (y=0; y<h2; y++)
{
y2 = y * 2;
for (x=0; x<w2; x++) {
x2 = x * 2;
cumul = getRpix(psrc, x2, y2) +
getRpix(psrc, x2, y2+1) +
getRpix(psrc, x2+1, y2) +
getRpix(psrc, x2+1, y2+1);
cumul /= 4, vgray = cumul;
idx = pixidx(pdst,x,y);
pdst->R[idx] = pdst->G[idx] = pdst->B[idx] = cumul;
cumul = getGpix(psrc, x2, y2) +
getGpix(psrc, x2, y2+1) +
getGpix(psrc, x2+1, y2) +
getGpix(psrc, x2+1, y2+1);
cumul /= 4, vgray += cumul;
idx = pixidx(pdst,x+w2,y);
pdst->R[idx] = pdst->G[idx] = pdst->B[idx] = cumul;
cumul = getBpix(psrc, x2, y2) +
getBpix(psrc, x2, y2+1) +
getBpix(psrc, x2+1, y2) +
getBpix(psrc, x2+1, y2+1);
cumul /= 4, vgray += cumul;
idx = pixidx(pdst,x,y+h2);
pdst->R[idx] = pdst->G[idx] = pdst->B[idx] = cumul;
idx = pixidx(pdst,x+w2,y+h2);
pdst->R[idx] = pdst->G[idx] = \
pdst->B[idx] = vgray / 3.0;
}
}
return 0;
}
/* == ---------------------------------------------------- == */

View File

@ -1,83 +0,0 @@
/*
* FloatImg library from tTh - really ugly code inside
*
* F A L S E C O L O R S
* or fake colors ?
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/time.h>
#include <math.h>
#include "../floatimg.h"
/* -------------------------------------------------------------- */
/* this is a global vars exported from main */
extern int verbosity;
/* -------------------------------------------------------------- */
/* TRUCS A VOIR
f(x,y) = (((y & x) * (y - x)) % ((21 & x) * (y | 8))) ^ (~((x & 7) | (x % x)))
*/
/* -------------------------------------------------------------- */
/* nouveau 18 mai 2022 */
/* please explain the meaning of 'valf' parameter */
int fimg_falsecolors_0(FloatImg *src, FloatImg *dst, int k, float valf)
{
int x, y, offset;
float r, g, b, gray, maxv;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %d %f )\n", __func__,
src, dst, k, valf);
#endif
if (k) {
fprintf(stderr, "%s : %d %f\n", __func__, k, valf);
}
/* check validity of parameters */
if (FIMG_TYPE_RGB != dst->type) {
fprintf(stderr, "in %s, picz at %p is not valid\n",
__func__, dst);
abort();
/* BLAM! */
}
maxv = fimg_get_plane_maxvalue(src, 'r');
fprintf(stderr, "%s: maxv of red plane = %f\n", __func__, maxv);
/* enter big loop */
offset = 0;
for (y=0; y<src->height; y++) {
for (x=0; x<src->width; x++) {
gray = src->R[offset];
if (gray < maxv/2.0) {
r = gray * 2.0;
g = 0.0;
}
else {
r = 0.0;
g = gray * 2.0;
}
b = fmodf(gray*8.0, maxv);
dst->R[offset] = r;
dst->G[offset] = g;
dst->B[offset] = b;
/* and GOTO next pixel */
offset++;
}
}
return 0;
}
/* -------------------------------------------------------------- */

View File

@ -1,33 +0,0 @@
/*
Digital Imaging and Communications in Medicine
nouveau Fri 26 Nov 2021 11:12:44 PM CET - allée de Dinan
*/
#include <stdio.h>
#include <stdint.h>
#include <sys/time.h>
#include "../floatimg.h"
extern int verbosity; /* must be declared around main() */
/* --------------------------------------------------------------------- */
int fimg_save_plane_as_dicom(FloatImg *src, char *outname,
char plane, int flags)
{
float *planeptr;
fprintf(stderr, ">>> %s ( %p %s %c %d )\n", __func__, src, outname, plane, flags);
planeptr = charplane2int(plane, src); /* please explain XXX */
fprintf(stderr, "planeptr is %p\n", planeptr);
if (verbosity) {
fimg_describe(src, outname);
}
return -1;
}
/* --------------------------------------------------------------------- */

View File

@ -1,89 +0,0 @@
/*
* FLOATIMG
* --------
* F M O R P H O
*
* nouveau 30 septembre 2022 / integration 28 octobre 2022
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/time.h>
#include "../floatimg.h"
/* --------------------------------------------------------------------- !*/
static struct
{
int x, y;
} deltas[] =
{ { -1, -1, },
{ 0, -1, },
{ 1, -1, },
{ -1, 0, },
{ 0, 0, },
{ 1, 0, },
{ -1, 1, },
{ 0, 1, },
{ 1, 1 }
};
typedef struct
{
int x, y; // not used
float r, g, b;
float fgris;
int rang;
} fpixel;
static fpixel pixels[9];
/* --------------------------------------------------------------------- !*/
static int comparaison_fgris(const void *A, const void *B)
{
return ((fpixel *)A)->fgris > ((fpixel *)B)->fgris;
}
/* --------------------------------------------------------------------- !*/
/*
* this is a klugy approch, sorry.
*/
int fimg_filtre_morpho_0(FloatImg *sfimg, FloatImg *dfimg, int index)
{
int xs, ys, loop9;
int xp, yp;
float rgb[3];
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__, sfimg, dfimg, index);
#endif
if ( (index<0) || (index>8)) {
fprintf(stderr, " %s: bad index %d\n", __func__, index);
#if MUST_ABORT
fflush(stderr); abort();
#endif
return -1;
}
fimg_clear(dfimg);
for (ys=1; ys<sfimg->height-1; ys++) {
for (xs=1; xs<sfimg->width-1; xs++) {
for (loop9=0; loop9<9; loop9++) {
xp = xs + deltas[loop9].x;
yp = ys + deltas[loop9].y;
fimg_get_rgb(sfimg, xp, yp, rgb);
pixels[loop9].fgris = rgb[0] + rgb[1] + rgb[2];
pixels[loop9].rang = loop9;
}
qsort(&pixels, 9, sizeof(fpixel), comparaison_fgris);
rgb[0] = rgb[1] = rgb[2] = pixels[index].fgris;
fimg_put_rgb(dfimg, xs, ys, rgb);
}
}
return 0;
}
/* --------------------------------------------------------------------- !*/

View File

@ -1,45 +0,0 @@
/*
* KILL RGB !
*
* nouveau TerreBlanque 4 octobre 2021
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include "../floatimg.h"
#include "tests.h"
/* --------------------------------------------------------------------- */
int fimg_killrgb_v(FloatImg *src, FloatImg *dst, int k)
{
int line, col;
int ir;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__, src, dst, k);
#endif
if (k) { fprintf(stderr, "in %s k was %d\n", __func__, k); }
fimg_clear(dst);
ir = 0;
for (line=0; line<src->height; line++) {
// fprintf(stderr, "%s line %d\n", __func__, line);
for (col=0; col<(src->width-3); col+=3) {
dst->R[ir ] = src->R[ir]; ir++;
dst->G[ir+1] = src->G[ir]; ir++;
dst->B[ir+2] = src->B[ir]; ir++;
}
}
return 0;
}
/* --------------------------------------------------------------------- */

View File

@ -1,101 +0,0 @@
/*
* P I X E L I Z E
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "../floatimg.h"
extern int verbosity;
/* -------------------------------------------------------------- */
/* nouveau 10 octobre 2021 dans la roulotte de Terreblanque */
#define LARGEUR 16
int fimg_pixelize_h_0(FloatImg *psrc, FloatImg *pdst, int largeur)
{
int line, col, loop, idx;
float cr, cg, cb; /* cumuls */
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__, psrc, pdst, largeur);
#endif
if (fimg_images_not_compatible(psrc, pdst)) {
fprintf(stderr, "%s: err compatibility\n", __func__);
return -8;
}
switch(largeur) {
case 8: case 16: case 32:
break;
default:
fprintf(stderr, "%s: bad width %d\n", __func__, largeur);
return -77;
}
for (line=0; line<psrc->height; line++) {
for (col=0; col<psrc->width; col+=largeur) {
cr = cg = cb = 0.0;
idx = line * psrc->width + col;
for (loop=0; loop<largeur; loop++) {
cr += psrc->R[idx+loop];
cg += psrc->G[idx+loop];
cb += psrc->B[idx+loop];
}
for (loop=0; loop<largeur; loop++) {
pdst->R[idx+loop] = cr / (float)largeur;
pdst->G[idx+loop] = cg / (float)largeur;
pdst->B[idx+loop] = cb / (float)largeur;
}
}
}
return 0;
}
/* -------------------------------------------------------------- */
/*
* un essai dans la roulotte :)
* 11 oct 2021 : premier jet, essai concluant, mais necessite
* du travail sur les rand() pour etre plus 'noisy'
*
*/
int fimg_pixelize_h_rnd(FloatImg *psrc, FloatImg *pdst, int largeur)
{
static int count = 0;
static int flag = 0;
int foo;
/* may be a mollyguard on 'largeur' parameter ? */
if (0==count) {
if (flag) {
count = irand2(5, 10);
flag = ! flag;
}
else {
count = irand2(20, 40);
flag = ! flag;
}
if (verbosity) {
fprintf(stderr, "%s c=%d f=%c\n", __func__,
count, flag?'T':'F');
}
}
if (verbosity) {
fprintf(stderr, "%s: count=%d flag=%d\n", __func__, count, flag);
}
foo = fimg_pixelize_h_0(psrc, pdst, flag ? largeur : 32);
if (foo) {
fprintf(stderr, "pixelize_h_0 give err %d in %s\n", foo, __func__);
}
count--; /* nice trick bro */
return 0;
}
/* -------------------------------------------------------------- */

View File

@ -1,38 +0,0 @@
/*
* R E C T A N G L E
* This is an eternal WIP, sorry...
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#include "../floatimg.h"
/* --------------------------------------------------------------------- */
int fimg_clear_rectangle(FloatImg *pi, int coo[4])
{
int line, off;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p )\n", __func__, pi, coo);
#endif
/* please add boudary checks */
for (line=0; line<coo[3]; line++) {
off = (line+coo[1])*pi->width + coo[0];
// fprintf(stderr, "line %3d off %8d\n", line, off);
/* Kaboum ! */
memset(pi->R + off, 0, coo[2]*sizeof(float));
memset(pi->G + off, 0, coo[2]*sizeof(float));
memset(pi->B + off, 0, coo[2]*sizeof(float));
}
return -1;
}
/* --------------------------------------------------------------------- */

View File

@ -1,99 +0,0 @@
/*
* FLOATIMG - a kluge from tTh
* ---------------------------
*
* some strange effects on floating pictures, made in
* the batcave of "Le Bib", in Montpellier.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/time.h>
#include "../floatimg.h"
extern int verbosity;
/* -------------------------------------------------------------- */
/* new Sun 29 Jan 2023 10:01:39 PM CET
*/
int fimg_make_rndfluffy_lines(FloatImg *src, FloatImg *dst, int rndt)
{
int x, y, ol;
float accu;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%p' '%p' %d )\n", __func__,
src, dst, rndt);
#endif
if (fimg_images_not_compatible(src, dst)) {
/* be hard for the lamers */
fprintf(stderr, "compatibility OUPS in %s\n", __func__);
abort();
}
for (y=0; y<src->height; y++) {
ol = y * src->width;
if (rndt < (rand() % 100)) {
accu = 0.0;
for (x=0; x<src->width; x++) accu += src->R[ol + x];
accu /= (float)src->width;
for (x=0; x<src->width; x++) dst->R[ol + x] = accu;
}
else {
for (x=0; x<src->width; x++) {
dst->R[ol+x] = src->R[ol+x];
dst->G[ol+x] = src->G[ol+x];
dst->B[ol+x] = src->B[ol+x];
}
}
}
return 0;
}
/* -------------------------------------------------------------- */
int fimg_crump_hard(FloatImg *src, FloatImg *dst, float kval, int notused)
{
float halfval;
float rgb[3];
int x, y, foo;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %f 0x%04x )\n", __func__,
src, dst, kval, notused);
#endif
if (notused) {
fprintf(stderr, "notused was %d, must be 0 in %s\n",
notused, __func__);
}
halfval = fimg_get_maxvalue(src) / 2.0;
if (verbosity > 1) {
fprintf(stderr, "%s: kval=%f & halfval=%f\n", __func__,
kval, halfval);
}
for (y=0; y<src->height; y++) {
for (x=0; x<src->width; x++) {
foo = fimg_get_rgb(src, x, y, rgb);
if (foo) return foo;
if (rgb[0] > halfval) rgb[0] /= 2.0;
if (rgb[1] > halfval) rgb[1] /= 2.0;
if (rgb[2] > halfval) rgb[2] /= 2.0;
foo = fimg_put_rgb(dst, x, y, rgb);
if (foo) return foo;
}
}
return 0;
}
/* -------------------------------------------------------------- */

View File

@ -1,86 +0,0 @@
/*
* FLOATIMG - a kluge from tTh
* ---------------------------
*
* some strange effects on floating pictures.
*/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <sys/time.h>
#include "../floatimg.h"
extern int verbosity;
/* -------------------------------------------------------------- */
int fimg_sfx_triplemul(FloatImg *src, FloatImg *dst, int notused)
{
int x, y, foo;
float in[3], out[3];
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p 0x%04x )\n", __func__, src, dst, notused);
#endif
if (notused) {
fprintf(stderr, "notused was %d, must be 0 in %s\n",
notused, __func__);
}
for (y=0; y<src->height; y++) {
for (x=0; x<src->width; x++) {
foo = fimg_get_rgb(src, x, y, in);
if (foo) return foo;
out[0] = in[1] * in[2];
out[1] = in[0] * in[2];
out[2] = in[0] * in[1];
// fprintf(stderr, "%9f %9f %9f\n", out[0], out[1], out[2]);
foo = fimg_put_rgb(dst, x, y, out);
if (foo) return foo;
}
}
return 0;
}
/* -------------------------------------------------------------- */
/*
* see also:
sfx3.c:fimg_crump_hard()
*/
int fimg_split_level(FloatImg *src, FloatImg *dst, int notused)
{
float means[4];
// float in[3];
int foo, idx, surface;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p 0x%04x )\n", __func__, src, dst, notused);
#endif
if (notused) {
fprintf(stderr, "notused was %d, must be 0 in %s\n",
notused, __func__);
}
foo = fimg_meanvalues(src, means);
if (foo) {
return -66;
}
surface = src->width*src->height;
for(idx=0; idx<surface; idx++) {
if (src->R[idx]<means[0]) dst->R[idx]=src->R[idx]*2.0;
else dst->R[idx]=(src->R[idx]-means[0])*2.0;
if (src->G[idx]<means[1]) dst->G[idx]=src->G[idx]*2.0;
else dst->G[idx]=(src->G[idx]-means[1])*2.0;
if (src->B[idx]<means[2]) dst->B[idx]=src->B[idx]*2.0;
else dst->B[idx]=(src->B[idx]-means[2])*2.0;
}
return 0;
}
/* -------------------------------------------------------------- */
/* -------------------------------------------------------------- */

View File

@ -8,8 +8,6 @@ cp tools/mkfimg tools/fimg2pnm tools/fimgops \
tools/png2fimg tools/fimgstats tools/fimgfx \
tools/cumulfimgs tools/fimg2text \
tools/fimghalfsize \
tools/fimgmetadata tools/fimgfilters \
tools/fimgextract \
/usr/local/bin
cp v4l2/grabvidseq v4l2/video-infos \

View File

@ -1,8 +0,0 @@
# Fimg tools
Need more explanations...
## Converting to/from rgb or gray

View File

@ -1,29 +0,0 @@
/*
* alphachan.c
*/
#include <stdio.h>
#include <stdint.h>
#include <sys/time.h>
#include "../floatimg.h"
extern int verbosity; /* must be declared around main() */
/* ---------------------------------------------------------------- */
int fimg_add_alpha_chan(FloatImg *img)
{
fprintf(stderr, ">>> %s ( %p )\n", __func__, img);
return -4;
}
/* ---------------------------------------------------------------- */
int fimg_kill_alpha_chan(FloatImg *img)
{
fprintf(stderr, ">>> %s ( %p )\n", __func__, img);
return -4;
}
/* ---------------------------------------------------------------- */

View File

@ -1,159 +0,0 @@
/*
* metadata.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <string.h>
#include "../floatimg.h"
extern int verbosity; /* must be declared around main() */
/* ---------------------------------------------------------------- */
int fimg_show_metadata(FimgMetaData *pmd, char *title, int notused)
{
int foo;
double doubletime;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p '%s' 0x%08x )\n", __func__,
pmd, title, notused);
#endif
if (notused) {
fprintf(stderr, "notused was %d, must be 0 in %s\n",
notused, __func__);
}
if (NULL != title) {
fprintf(stderr, "==== metadate for %s\n", title);
}
if (verbosity) {
fprintf(stderr, "sizeof(metadata) = %ld\n", \
sizeof(FimgMetaData));
fprintf(stderr, " Magic [%08x]\n", pmd->magic);
}
/* SHOW TIMESTAMP HERE */
fprintf(stderr, "secs from epoch = %ld\n", pmd->timestamp.tv_sec);
fprintf(stderr, "date & time = %s", ctime(&pmd->timestamp.tv_sec));
doubletime = (double)pmd->timestamp.tv_sec + \
(double)pmd->timestamp.tv_usec / 1e6;
fprintf(stderr, "dtime of day = %12.3f\n", doubletime);
fprintf(stderr, "creator pid = %ld\n", pmd->cpid);
fprintf(stderr, "float value = %.3f\n", pmd->fval);
fprintf(stderr, "counter = %d\n", pmd->count);
fprintf(stderr, "id camera = '%s'\n", pmd->idcam);
fprintf(stderr, "origin = 0x%x\n", pmd->origin);
fputs("reserved words are:\n ", stderr);
for (foo=0; foo<8; foo++) {
fprintf(stderr, " 0x%08x", pmd->reserved[foo]);
if (3 == foo) fputs("\n ", stderr);
}
fputc('\n', stderr);
return 0;
}
/* ---------------------------------------------------------------- */
/*
* those values may be loaded from a config file ?
*/
int fimg_default_metadata(FimgMetaData *pmd, int bla)
{
int foo;
struct timeval tvl;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %d )\n", __func__, pmd, bla);
#endif
memset(pmd, 0, sizeof(FimgMetaData));
/* set timestamp here ? */
/* CHALLENGE ACCEPTED */
memset(&tvl, 0, sizeof(struct timeval));
foo = gettimeofday(&tvl, NULL);
if (foo) {
/* error on get time of day ? */
perror("omg");
}
else {
if (verbosity > 1) {
fprintf(stderr, "%s : set TimeOfDay to %12ld %8ld\n", \
__func__, tvl.tv_sec, tvl.tv_usec);
}
memcpy(&(pmd->timestamp), &tvl, sizeof(struct timeval));
}
pmd->magic = MAGIC_MDATA;
pmd->cpid = getpid(); // we are the creator, no ?
pmd->count = 1; // mmmm...
pmd->fval = 255.0; // Ok
strcpy(pmd->idcam, "<noname>");
pmd->origin = 0xdeadbeef; // classic joke, sorry
pmd->reserved[0] = bla;
pmd->reserved[7] = 0x55445544; // magic number is a crime
return 0;
}
/* ---------------------------------------------------------------- */
int fimg_get_metadata_from_file(char *fname, FimgMetaData *pmd)
{
FILE *fp;
FimgFileHead filehead;
FimgMetaData metadata;
int foo;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' %p )\n", __func__, fname, pmd);
#endif
if (NULL==(fp=fopen(fname, "r"))) {
perror(fname);
return -1;
}
foo = fread(&filehead, sizeof(FimgFileHead), 1, fp);
if (1 != foo) {
fprintf(stderr, "short read (%d) on %s (head)\n", foo, fname);
fclose(fp);
return -2;
}
if (memcmp(filehead.magic, "FIMG", 4)) {
fprintf(stderr, "'%s' is not a fimg file.\n", fname);
fclose(fp);
return -3;
}
if ('a' != filehead.magic[4]) {
fprintf(stderr, "file '%s' have no metadata.\n", fname);
fclose(fp);
return -4;
}
foo = fread(&metadata, sizeof(FimgMetaData), 1, fp);
if (1 != foo) {
fprintf(stderr, "short read on %s (metadata)\n", fname);
fclose(fp);
return -5;
}
fclose(fp); /* got all needed datas */
if (MAGIC_MDATA != metadata.magic) {
fprintf(stderr, "%s: magic was %08X, wtf?\n", __func__,
metadata.magic);
return -4;
}
memcpy(pmd, &metadata, sizeof(FimgMetaData));
return 0;
}
/* ---------------------------------------------------------------- */

View File

@ -1,8 +1,7 @@
# Exemples de scripts
_Attention_, ce ne sont que des exemples, pas forcément adaptés
à une utilisation dans le monde réel. Mais vous pouvez vous en
inspirer pour vos usecases personnels.
à une utilisation dans le monde réel.
## shoot.sh
@ -21,13 +20,5 @@ en dur dans le code.
Comment générer des videos psychotiques avec un peu de bash.
Ce script est expliqué dans la documentation PDF.
## capture.sh & conf.sh
Ce [script](./capture.sh) sert à capturer une séquence d'image depuis
une webcam.
Deux choses à noter : il utilise un fichier de configuration
(`source [./conf.sh](./conf.sh)) pour ajuster son fonctionnement, et il
extrait juste une portion de l'image capturée. Une belle avancée,
puisque cela ajoute quelques possibilités de recadrage dès
la prise de vue.

View File

@ -1,30 +0,0 @@
#!/bin/bash
# CAPTURE
source ./conf.sh
DEVICE="/dev/video0"
GOPT=" -v -s 1920x1080 -p 0 -n 10"
OUTD=$GRABDIR
TMPG="/dev/shm/tmpgrab.fimg"
for idx in $(seq 0 2399)
do
# take the picz
${GRAB} -d ${DEVICE} ${GOPT} -o ${TMPG}
# display $TMPG
# only take the good spot
fimg=$(printf "%s/%05d.fimg" ${OUTD} ${idx})
${EXTR} -o ${fimg} ${TMPG} 800,600,560,240
# display ${fimg} ; exit
echo
sleep $DELAY_GRAB
done

View File

@ -1,39 +0,0 @@
# Sat Jul 8 10:41:58 UTC 2023
#
# location of some tools
#
GRAB="$HOME/Devel/FloatImg/v4l2/grabvidseq"
MKFX="$HOME/Devel/FloatImg/tools/fimgfx"
MDAT="$HOME/Devel/FloatImg/tools/fimgmetadata"
EXTR="$HOME/Devel/FloatImg/tools/fimgextract"
INTERPOLATOR="$HOME/Devel/FloatImg/Fonderie/interpolator"
FONDERIE="$HOME/Devel/FloatImg/Fonderie/fonderie"
SINGLEPASS="$HOME/Devel/FloatImg/Fonderie/singlepass"
NBPASS=2400
DELAY_GRAB=1
IDXLINKFARM=0
#
# working directories
#
GRABDIR="rush"
GIFDIR="gif89a"
#
# text plotting conf
FONT="Noto-Sans-Bold"
KERNING=1
SIGNATURE="... tTh 2023 ..."
#
# filter chains for fondulations
#
IF="cos01:colmixa:pow2"
OF="shiftln0:liss3x3"

View File

@ -2,9 +2,9 @@
CMDPATH="/usr/local/bin"
WS="${HOME}/TMP" # our workspace
WS="./tmp" # our workspace
GRABOPT=" -d /dev/video0 -v -n 240 -p 0.04 "
GRABOPT=" -d /dev/video0 -vu -n 240 -p 0.04 "
GRAB=${WS}/"quux.fimg"
COS01=${WS}/"cos01.fimg"
@ -15,9 +15,9 @@ POW2="${WS}/pow2.fimg"
# --------- conversion fimg -> pnm
f2p ()
{
dst=EC_$(basename $1 .fimg).pnm
dst=$(basename $1 .fimg).pnm
echo == converting $1 to $dst
${CMDPATH}/fimg2pnm $1 ${WS}/$dst
${CMDPATH}/fimg2pnm $1 $dst
}
# --------- capturer une image
@ -43,4 +43,4 @@ f2p $COS010
# ----------- présentation finale
#
echo == Making gif89a
convert -delay 40 ${WS}/EC_*.pnm foo.gif
convert -delay 40 *.pnm foo.gif

View File

@ -1,13 +0,0 @@
#!/usr/bin/env bash
echo "=== make a lot of float img ==="
MKFIMG="../tools/mkfimg"
SIZE=" 640x480 "
for type in $(${MKFIMG} -L)
do
picname="/tmp/${type}.fimg"
echo $picname
${MKFIMG} -v -t $type $picname $SIZE
done

View File

@ -26,9 +26,9 @@ for idx in $(seq 0 $NBRE)
do
# build the two input filenames ...
#
imgA=$(printf "$SRCDIR/%05d.fimg" $idx)
imgA=$(printf "$SRCDIR/%04d.fimg" $idx)
vb=$(( $(( idx + OFFS )) % NBRE))
imgB=$(printf "$SRCDIR/%05d.fimg" $vb)
imgB=$(printf "$SRCDIR/%04d.fimg" $vb)
# ... and the output filename
#

View File

@ -1,89 +1,37 @@
/*
* floatimg.h
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
* ugly code from tTh
* http://la.buvette.org/photos/cumul/
* https://git.tetalab.org/tTh/FloatImg
* http://la.buvette.org/photos/cumul
*/
#define FIMG_VERSION (231)
#define RELEASE_NAME ("noname")
#define PATCH_LEVEL ("aaaa")
/* XXX add a test for stdint.h / uint32_t XXX */
#include <stdint.h>
#define FIMG_VERSION 150
/*
* new 11 mars 2022, and a lot of iterations
* around the concept of metadata for my work.
*/
/*
* we MUST look at packing and endianess problems NOW
* and we can think about a fixed size of this datablock
*/
#define MAGIC_MDATA 0xfe007007
typedef struct {
uint32_t magic;
uint32_t padding;
struct timeval timestamp; // #include <stdlib.h>
uint64_t cpid; // process id of the creator
int32_t count;
float fval;
char idcam[32];
int32_t origin; // enum ?
uint32_t reserved[8];
} FimgMetaData;
/*
* in memory descriptor of a floating image
* ----------------------------------------
* in memory descriptor
*/
#define MAGIC_FIMG 0x00F11F00
typedef struct {
uint32_t magic;
unsigned long magic;
int width;
int height;
int type;
float fval;
int count;
float *R, *G, *B, *A;
FimgMetaData mdatas; // added 20230912
int reserved;
} FloatImg;
/*
* fimg file header (short version)
* fimg file header
*/
typedef struct {
char magic[8]; // this is not an asciiz !
char magic[8];
int32_t w, h, t;
/*
* what about the packing ?
*/
} FimgFileHead;
#define MAGIC_AREA51 0xA5EA0051
typedef struct {
uint32_t magic;
unsigned long magic;
int w, h;
int x, y;
int flags;
@ -102,8 +50,6 @@ typedef struct {
#define FILE_TYPE_FITS 6
#define FILE_TYPE_BMP 7
#define FILE_TYPE_EXR 8
#define FILE_TYPE_DICOM 9
#define FILE_TYPE_PGM 10
/* lib/contrast.c */
#define CONTRAST_NONE 0
@ -111,7 +57,7 @@ typedef struct {
#define CONTRAST_POW2 2
#define CONTRAST_COS01 3
#define CONTRAST_COS010 4
#define CONTRAST_XPER 5 /* use with caution */
/*
* core module
*/
@ -149,26 +95,20 @@ 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;
/*
* this module contains bugs...
*/
int fimg_killborders(FloatImg *img);
int fimg_lissage_2x2(FloatImg *img);
int fimg_lissage_3x3(FloatImg *img);
int fimg_show_filter(char *title, FimgFilter3x3 *filtr);
int fimg_filter_3x3(FloatImg *s, FloatImg *d, FimgFilter3x3 *filtr);
int fimg_contour_2x2(FloatImg *psrc, FloatImg *pdst, int reverse);
/* ---------------------------------------------------- */
int fimg_contour_2x2(FloatImg *psrc, FloatImg *pdst, int reverse);
/* module sfx0.c */
int fimg_killcolors_a(FloatImg *fimg, float fval);
@ -183,33 +123,20 @@ int fimg_highlight_color(FloatImg *src, FloatImg *dst,
int fimg_binarize(FloatImg *pimg, int notused);
int fimg_trinarize(FloatImg *pimg, int notused);
/* module sfx3.c */
int fimg_make_rndfluffy_lines(FloatImg *src, FloatImg *dst, int rndt);
int fimg_crump_hard(FloatImg *src, FloatImg *dst, float kval, int notused);
/* module sfx4.c */
int fimg_sfx_triplemul(FloatImg *s, FloatImg *d, int notused);
int fimg_split_level(FloatImg *src, FloatImg *dst, int notused);
/* funcs/rotate.c module */
/* #coronamaison */
int fimg_rotate_90(FloatImg *src, FloatImg *dst, int notused);
int fimg_killrgb_v(FloatImg *src, FloatImg *dst, int k);
int fimg_decomp_rgbz_color(FloatImg *psrc, FloatImg *pdst, int k);
int fimg_decomp_rgbz_gray(FloatImg *psrc, FloatImg *pdst, int k);
int fimg_save_plane_as_dicom(FloatImg *src, char *outname,
char plane, int flags);
/* 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_save_as_pgm(FloatImg *head, char *fname, int flags);
int fimg_load_from_pnm(char *fname, FloatImg *head, int notused);
int fimg_save_plane_as_pgm(FloatImg *psrc, char *fname, char plane);
double fimg_timer_set(int whot);
double fimg_timer_get(int whot);
@ -226,29 +153,16 @@ int fimg_mix_rgb_gray(FloatImg *img, float mix);
int fimg_shift_to_zero(FloatImg *s, FloatImg *d, float coefs[6]);
int fimg_auto_shift_to_zero(FloatImg *s, FloatImg *d);
/* funcs/falsecolors.c */
int fimg_falsecolors_0(FloatImg *src, FloatImg *dst, int k, float valf);
/* funcs/fmorpho.c */
int fimg_filtre_morpho_0(FloatImg *sfimg, FloatImg *dfimg, int index);
/* --> funcs/plasmas.c */
int fimg_prototype_plasma(FloatImg *img, double time, int type);
/* --> funcs/pixelize.c
voir fimg_pixelize_h_rnd() */
int fimg_pixelize_h_0(FloatImg *psrc, FloatImg *pdst, int k);
int fimg_pixelize_h_rnd(FloatImg *psrc, FloatImg *pdst, int largeur);
/* * * * 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/equalize.c */
/* module funcs/??????.c */
int fimg_equalize_compute(FloatImg *src, void *vptr, float vmax);
int fimg_equalize(FloatImg *src, double vmax);
int fimg_mk_gray_from(FloatImg *src, FloatImg*dst, int k);
int fimg_desaturate(FloatImg *src, FloatImg *dst, int notused);
@ -269,21 +183,13 @@ 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);
int fimg_do_stripes(FloatImg *img, float fmax, int mode);
/* FIMG native file module */
/* FIMG files module */
int fimg_fileinfos(char *fname, int *datas);
int fimg_dump_to_file(FloatImg *head, char *fname, int notused);
int fimg_dumpmd_to_file(FloatImg *fi, char *nm, FimgMetaData *pmd, int nu);
int fimg_load_from_dump(char *fname, FloatImg *where);
int fimg_create_from_dump(char *fname, FloatImg *head);
/* FIMG metadata module */
int fimg_show_metadata(FimgMetaData *pmd, char *title, int notused);
int fimg_default_metadata(FimgMetaData *pmd, int bla);
int fimg_get_metadata_from_file(char *fname, FimgMetaData *pmd);
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);
@ -294,22 +200,17 @@ int fimg_save_as_exr(FloatImg *src, char *outname, int flags);
/* mathematics operations */
float fimg_get_plane_maxvalue(FloatImg *psrc, char plane);
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_div_cste(FloatImg *fi, float value);
int fimg_ajust_from_grab(FloatImg *fi, double maxima, int notused);
int fimg_absolute(FloatImg *fimg);
void fimg_drand48(FloatImg *fi, float kmul);
long fimg_count_negativ(FloatImg *fi);
long fimg_clamp_negativ(FloatImg *fi);
int fimg_max_of_max(FloatImg *img, float maxes[3]);
/* various funcs modules */
int fimg_load_from_png(char *filename, FloatImg *fimg);
int fimg_create_from_png(char *filename, FloatImg *fimg);
@ -324,17 +225,13 @@ int fimg_multirandom(FloatImg *fimg, long nbpass);
/* file is 'funcs/utils.c' */
void fimg_print_minmax(float minmax[6], char *titre);
float *charplane2int(char plane, FloatImg *img);
int parse_WxH(char *str, int *pw, int *ph);
int parse_double(char *str, double *dptr);
int irand2(int offset, int modulo);
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);
int fimg_clear_rectangle(FloatImg *pimg, int rect[4]);

View File

@ -2,21 +2,28 @@
# 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
COPT = -Wall -Wextra -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 rectangle.o \
sfx0.o sfx1.o sfx2.o sfx3.o sfx4.o \
falsecolors.o fmorpho.o \
fimg-libpnm.o rampes.o sfx0.o sfx1.o sfx2.o sfx4.o \
geometry.o rotate.o fimg-openexr.o \
equalize.o fimg-fits.o saturation.o histogram.o \
fimg-dicom.o \
hsv.o classif.o contour2x2.o qsortrgb.o exporter.o \
displacement.o dithering.o plasmas.o incrustator.o \
killrgb.o recurse.o pixelize.o decomprgb.o
recurse.o
all: $(OBJS) $(STATIC_LIB) $(DYN_OBJ)
#---------------------------------------------------------------
t: t.c $(DEPS) ../libfloatimg.a tests.o
@ -34,22 +41,16 @@ tests.o: tests.c tests.h $(DEPS)
#---------------------------------------------------------------
# upper-level functions
../libfloatimg.a: $(OBJS)
$(STATIC_LIB): $(OBJS)
$(AR) r $@ $?
# ###
rectangle.o: rectangle.c $(DEPS)
gcc $(COPT) -c $<
$(DYN_OBJ): $(OBJS)
mkdir -p $(OBJ_DIR)
ld -Ur -o $@ $?
decomprgb.o: decomprgb.c $(DEPS)
gcc $(COPT) -c $<
pixelize.o: pixelize.c $(DEPS)
gcc $(COPT) -c $<
killrgb.o: killrgb.c $(DEPS)
gcc $(COPT) -c $<
clean:
rm -rf $(OBJS) $(STATIC_LIB) $(DYN_OBJ)
recurse.o: recurse.c $(DEPS)
gcc $(COPT) -c $<
@ -60,9 +61,6 @@ incrustator.o: incrustator.c $(DEPS)
displacement.o: displacement.c $(DEPS)
gcc $(COPT) -c $<
fmorpho.o: fmorpho.c $(DEPS)
gcc $(COPT) -c $<
fimg-png.o: fimg-png.c $(DEPS)
gcc $(COPT) -c $<
@ -75,9 +73,6 @@ fimg-tiff.o: fimg-tiff.c $(DEPS)
fimg-openexr.o: fimg-openexr.c $(DEPS)
gcc $(COPT) -c $<
fimg-dicom.o: fimg-dicom.c $(DEPS)
gcc $(COPT) -c $<
fimg-fits.o: fimg-fits.c $(DEPS)
gcc $(COPT) -I/usr/include/cfitsio/ -c $<
@ -120,9 +115,6 @@ sfx1.o: sfx1.c $(DEPS)
sfx2.o: sfx2.c $(DEPS)
gcc $(COPT) -c $<
sfx3.o: sfx3.c $(DEPS)
gcc $(COPT) -c $<
sfx4.o: sfx4.c $(DEPS)
gcc $(COPT) -c $<
@ -141,9 +133,6 @@ qsortrgb.o: qsortrgb.c $(DEPS)
exporter.o: exporter.c $(DEPS)
gcc $(COPT) -c $<
falsecolors.o: falsecolors.c $(DEPS)
gcc $(COPT) -c $<
hsv.o: hsv.c $(DEPS)
gcc $(COPT) -c $<

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

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

View File

@ -5,7 +5,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <math.h>
#include "../floatimg.h"
@ -15,7 +14,7 @@ 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 flags)
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;
@ -26,8 +25,6 @@ fprintf(stderr, ">>> %s ( %p %p %f %d )\n", __func__,
psrc, pdst, fval, notused);
#endif
if (flags) { fprintf(stderr, "flags: 0x%04x in %s\n", flags, __func__); }
if (FIMG_TYPE_RGB != psrc->type) {
fprintf(stderr, "%s: bad src type %d\n", __func__, psrc->type);
return -7;

View File

@ -4,7 +4,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>

View File

@ -4,7 +4,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
@ -22,6 +21,7 @@ float minmax[6];
float rgb[3];
float dltr, dltg, dltb; /* delta des minmax */
float dispx, dispy;
int dstx, dsty;
int in, out;
@ -39,10 +39,6 @@ if (fimg_images_not_compatible(psrc, pdst)) {
}
foo = fimg_get_minmax_rgb(psrc, minmax);
if (foo) {
fprintf(stderr, "%s : err %d on get minmax\n", __func__, foo);
return foo;
}
if (verbosity) {
fimg_print_minmax(minmax, (char *)__func__);
}
@ -82,7 +78,9 @@ for (y=0; y<psrc->height; y++) {
fimg_put_rgb(pdst, dstx, dsty, rgb);
in++;
}
}
}
if (verbosity) fprintf(stderr, "%s -> in %d out %d\n", __func__, in, out);

View File

@ -4,7 +4,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
@ -17,23 +16,11 @@ int fimg_dither_0(FloatImg *psrc, FloatImg *pdst, int flags)
{
int x, y;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p 0x%04x )\n", __func__, psrc, pdst, flags);
#endif
if (flags) { fprintf(stderr, "flags: 0x%04x in %s\n", flags, __func__); }
if (fimg_images_not_compatible(psrc, pdst)) {
fprintf(stderr, "%s: shit happen\n", __func__);
return -2;
}
for (y=0; y<psrc->height; y++) {
for (x=0; x<psrc->width; x++)
{
/* PLEASE DO SOMETHING HERE */
}
}

View File

@ -7,54 +7,12 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <sys/time.h>
#include "../floatimg.h"
extern int verbosity;
/* --------------------------------------------------------------------- */
/* new func: Wed 14 Sep 2022 11:28:04 AM CEST
*/
int fimg_equalize(FloatImg *src, double vmax)
{
float mm[6];
double maxi, coef;
int foo;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %f )\n", __func__, src, vmax);
#endif
memset(mm, 0, 6*sizeof(float));
foo = fimg_get_minmax_rgb(src, mm);
if (foo) {
fprintf(stderr, "%s: err %d get_minmax\n", __func__, foo);
return foo;
}
maxi = mm[1] > mm[3] ? (double)mm[1] : (double)mm[3];
maxi = maxi > mm[5] ? maxi : (double)mm[5];
coef = vmax / maxi;
if (verbosity) {
fprintf(stderr, "maximums %.3f %.3f %.3f %.3f\n",
mm[1], mm[3], mm[5], maxi);
fprintf(stderr, "vmax %f maxi %f multcoef = %g\n", vmax, maxi, coef);
}
foo = fimg_mul_cste(src, (float)coef);
if (foo) {
fprintf(stderr, "%s: err %d mul_cste\n", __func__, foo);
return foo;
}
return 0;
}
/* --------------------------------------------------------------------- */
/*
*
* - wtf is this "void *vptr" thing ?
*/
int fimg_equalize_compute(FloatImg *src, void *vptr, float vmax)
{
float minmax[6];
@ -73,8 +31,6 @@ if (foo) {
return foo;
}
fprintf(stderr, "vptr is %p vmax is %f\n", vptr, vmax);
dr = minmax[1] - minmax[0];
dg = minmax[3] - minmax[2];
db = minmax[5] - minmax[4];
@ -88,7 +44,7 @@ if ( (minmax[0]<0.0) || (minmax[2]<0.0) || (minmax[4]<0.0) ) {
return -4;
}
fprintf(stderr, "deltas %12.4g %12.4g %12.4g\n", dr, dg, db);
// printf("deltas %12.4g %12.4g %12.4g\n", dr, dg, db);
return 0;
}

View File

@ -4,7 +4,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "../floatimg.h"
@ -25,8 +24,6 @@ fprintf(stderr, ">>> %s ( %p '%s' 0x%X )\n", __func__,
pic, fname, flags);
#endif
if (flags) { fprintf(stderr, "flags: 0x%04x in %s\n", flags, __func__); }
filetype = format_from_extension(fname);
if (verbosity > 1) {
fprintf(stderr, "file %s have type %d\n", fname, filetype);
@ -56,15 +53,9 @@ switch(filetype) {
case FILE_TYPE_BMP:
fprintf(stderr, "%s: file type BMP not implemented\n", __func__);
foo = -666;
break;
case FILE_TYPE_EXR:
fprintf(stderr, "%s: file type EXR experimental\n", __func__);
foo = fimg_save_as_exr(pic, fname, 0);
break;
case FILE_TYPE_PGM:
fprintf(stderr, "XXX %s EXPERIMENT!\n", __func__);
foo = fimg_save_as_pgm(pic, fname, 0);
break;
default:
foo = -1789;
break;

View File

@ -1,43 +1,11 @@
/*
* Floating filters are all WIP !
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <float.h>
#include "../floatimg.h"
extern int verbosity;
/* -------------------------------------------------------------------- */
int fimg_show_filter(char *title, FimgFilter3x3 *filtr)
{
float *M; /* alias of filter matrix */
int idx;
float sum, value;
if (title) fprintf(stderr, "--------- %s ---------\n", title);
M = filtr->matrix; /* aliasing here */
fprintf(stderr, "%8.3f %8.3f %8.3f\n", M[0], M[1], M[2]);
fprintf(stderr, "%8.3f %8.3f %8.3f\n", M[3], M[4], M[5]);
fprintf(stderr, "%8.3f %8.3f %8.3f\n", M[6], M[7], M[8]);
sum = 0.0;
for (idx=0; idx<9; idx++) sum += M[idx];
fprintf(stderr, " sum: %8.3f\n", sum);
fprintf(stderr, " mult: %8.3f\n", filtr->mult);
fprintf(stderr, " offset: %8.3f\n", filtr->offset);
value = (sum * filtr->mult) + filtr->offset;
fprintf(stderr, " value: %8.3f\n", value);
return 0;
}
/* -------------------------------------------------------------------- */
int fimg_filter_3x3(FloatImg *src, FloatImg *dst, FimgFilter3x3 *filtr)
{
@ -47,7 +15,7 @@ float *M; /* alias of filter matrix */
double dval;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %p )\n", __func__, src, dst, filtr);
fprintf(stderr, ">>> %s ( %p %p %p )\n", __func__, src, dst, filtr);
#endif
if (src->type != FIMG_TYPE_RGB) {
@ -59,21 +27,19 @@ if (dst->type != FIMG_TYPE_RGB) {
return -99;
}
if (fimg_images_not_compatible(src, dst)) {
fprintf(stderr, "%s: src & dst not compatibles\n", __func__);
fprintf(stderr, "%s: src & dst not comatibles\n", __func__);
return -98;
}
if (verbosity > 1) {
fimg_show_filter((char *)__func__, filtr);
}
/* 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)] +
@ -140,7 +106,9 @@ if (img->type != FIMG_TYPE_RGB) {
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] +
@ -155,6 +123,7 @@ for (y=1; y < img->height-1; y++) {
pr[offset] = cr / 4.0;
pg[offset] = cg / 4.0;
pb[offset] = cb / 4.0;
}
}
@ -195,6 +164,7 @@ for (idx=0; idx<h; idx++) {
}
o = w * (h - 1);
for (idx=0; idx<w; idx++) {
#if FAST
img->R[idx] = 0.0;
@ -216,10 +186,6 @@ int fimg_lissage_2x2(FloatImg *img)
{
int foo;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p )\n", __func__, img);
#endif
foo = fimg_lissage_2x2_a(img);
if (foo) {
fprintf(stderr, "%s: fail %d\n", __func__, foo);
@ -231,54 +197,4 @@ fimg_killborders(img);
return foo;
}
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/*
* XXX inplace filtering is a BAD IDEA
*/
int fimg_lissage_3x3(FloatImg *img)
{
int foo;
FloatImg tmp;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p )\n", __func__, img);
#endif
static FimgFilter3x3 lowpass = {
{
1.0, 2.0, 1.0,
2.0, 4.0, 2.0,
1.0, 2.0, 1.0,
},
16.0, 0.0
};
foo = fimg_clone(img, &tmp, 1);
if (foo) {
fprintf(stderr, "%s: clone -> %d\n", __func__, foo);
abort();
}
foo = fimg_filter_3x3(&tmp, img, &lowpass);
if (foo) {
fprintf(stderr, "%s: lowpass -> %d\n", __func__, foo);
abort();
}
foo = fimg_copy_data(&tmp, img);
if (foo) {
fprintf(stderr, "%s: copy data -> %d\n", __func__, foo);
abort();
}
foo = fimg_destroy(&tmp);
if (foo) {
fprintf(stderr, "%s: destroy -> %d\n", __func__, foo);
abort();
}
fimg_killborders(img);
return 0;
}
/* -------------------------------------------------------------------- */

View File

@ -8,8 +8,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/time.h>
#include <fitsio.h>
@ -32,8 +30,6 @@ long naxes[2];
fprintf(stderr, ">>> %s ( %p '%s' %d )\n", __func__, src, outname, flags);
#endif
if (flags) { fprintf(stderr, "flags: 0x%04x in %s\n", flags, __func__); }
status = 0;
switch (plane) {

View File

@ -4,7 +4,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <pam.h>
@ -14,9 +13,9 @@
extern int verbosity;
/* --------------------------------------------------------------------- */
static void print_struct_pam(struct pam *ppam, char *text)
static void print_struct_pam(struct pam *ppam, char *txt)
{
printf(" text %s\n", text);
printf(" size %d\n", ppam->size);
printf(" format %d\n", ppam->format);
@ -24,6 +23,7 @@ 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);
}
/* --------------------------------------------------------------------- */

View File

@ -5,7 +5,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "../floatimg.h"

View File

@ -5,7 +5,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <pnglite.h>
@ -87,7 +86,7 @@ if (PNG_NO_ERROR != foo) {
}
ptr = datas;
for (idx=0; idx<(int)(png.width*png.height); idx++) {
for (idx=0; idx<png.width * png.height; idx++) {
fimg->R[idx] = (float)*ptr++;
fimg->G[idx] = (float)*ptr++;
fimg->B[idx] = (float)*ptr++;
@ -132,12 +131,12 @@ if ( 3 != png.bpp ) { /* TO BE PATCHED */
}
/* check if floatimg and PNG have the same size */
if ((fimg->width != (int)png.width) || (fimg->height != (int)png.height)) {
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;
datasize = png.width * png.height * png.bpp;
datas = malloc(datasize);
if (NULL==datas) {
fprintf(stderr, "%s : fatal memory failure\n", __func__);
@ -151,7 +150,7 @@ if (PNG_NO_ERROR != foo) {
}
ptr = datas;
for (idx=0; idx<(int)(png.width*png.height); idx++) {
for (idx=0; idx<png.width * png.height; idx++) {
fimg->R[idx] = (float)*ptr++;
fimg->G[idx] = (float)*ptr++;
fimg->B[idx] = (float)*ptr++;
@ -171,13 +170,9 @@ unsigned char *bytes, *bptr;
double maximum, fk;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p '%s' 0x%x )\n", __func__, src, outname, flags);
fprintf(stderr, ">>> %-25s ( %p '%s' 0x%x )\n", __func__, src, outname, flags);
#endif
if (flags) {
fprintf(stderr, "*** in %s, flags are %08x\n", __func__, flags);
}
/* convert ou floating datas to a byte/rgb array */
/* first, alloc a buffer */
sz = src->width * src->height;

View File

@ -5,7 +5,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <tiffio.h>
#include "../floatimg.h"
@ -23,9 +23,6 @@ int x, y, idx, foo;
char ligne[100];
double maximum, fk;
if (flags) fprintf(stderr, "in %s, flags are 0x%04x, must be 0\n",
__func__, flags);
/* bon, tout cela semble bien tortueux ! */
if (FIMG_TYPE_RGB != src->type) {
@ -47,7 +44,6 @@ if (verbosity) {
tiff = TIFFOpen(fname, "w");
if (NULL==tiff) {
fprintf(stderr, "erreur TIFFOpen\n");
return -6;
}

View File

@ -5,7 +5,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "../floatimg.h"
@ -27,8 +26,6 @@ fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__,
src, dst, notused);
#endif
if (notused) fprintf(stderr, "notused %d in %s\n", notused, __func__);
/* no magic check here ? */
if (dst->width || dst->height) {
fprintf(stderr, "*** %s: image at %p not empty\n", __func__, dst);
@ -67,8 +64,6 @@ int wd, hd;
int foo, x, y, x2, y2;
float ac;
if (notused) fprintf(stderr, "notused %d in %s\n", notused, __func__);
if (dst->width || dst->height) {
fprintf(stderr, "*** %s: image at %p not empty\n", __func__, dst);
fimg_describe(dst, "destination halfsize 1");
@ -110,28 +105,19 @@ for (y=0; y<hd; y++) {
return 0;
}
/* --------------------------------------------------------------------- */
/*
* this function can be optimized with direct pixel copy
*/
int fimg_extractor(FloatImg *in, FloatImg *out, FimgArea51 *rect)
{
int foo;
int xs, ys, xd, yd;
int count;
float rgb[3];
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %p )\n", __func__, in, out, rect);
#endif
if (verbosity > 1) {
fimg_describe(in, "extractor: source");
fimg_describe(out, "extractor: destination");
// print_rectangle(rect);
}
/*
* some sanity controls, please ! XXX
*/
count = 0;
for (yd=0; yd<rect->h; yd++) {
ys = yd + rect->y;
@ -145,7 +131,7 @@ for (yd=0; yd<rect->h; yd++) {
}
}
if (verbosity > 1) fprintf(stderr, "%s: %d pix moved\n", __func__, count);
// fprintf(stderr, "%s: %d pix moved\n", __func__, count);
return 0;
}
@ -162,8 +148,6 @@ fprintf(stderr, ">>> %s ( %p %p 0x%04x )\n", __func__,
src, dst, notused);
#endif
if (notused) fprintf(stderr, "notused %d in %s\n", notused, __func__);
if (fimg_images_not_compatible(src, dst)) {
fprintf(stderr, "bad karma in %s\n", __func__);
return -9;

View File

@ -6,7 +6,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "../floatimg.h"

View File

@ -10,19 +10,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#include "../floatimg.h"
extern int verbosity;
/*
https://baillehachepascal.dev/2021/rgb_hsv.php
*/
/* --------------------------------------------------------------------- */
/* helper functions */
static float maxi3f(float a, float b, float c)
@ -35,7 +28,7 @@ return ((a < b)? (a < c ? a : c) : (b < c ? b : c));
}
static int pseudoeq(float a, float b)
{
return (fabsf(a-b)<0.00000001); // UGLY HACK ???
return (fabsf(a-b)<0.00000000000001); // UGLY HACK ???
}
/* --------------------------------------------------------------------- */
/*
@ -85,7 +78,7 @@ 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] * scale);
rgb[0] = rgb[1] = rgb[2] = hsv[2];
return 0;
}
@ -131,10 +124,7 @@ int fimg_essai_hsv(char *fname)
float colors[3], values[3], newcols[3];
int foo, r, g, b;
fprintf(stderr, "%s NOT writing to %s\n", __func__, fname);
#define INC 16
for (r=0; r<255; r+=INC) {
for (g=0; g<255; g+=INC) {
for (b=0; b<255; b+=INC) {

View File

@ -5,7 +5,6 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include "../floatimg.h"
@ -20,26 +19,23 @@ 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
if (verbosity > 1) {
fimg_printdims("from", from);
fimg_printdims("to ", to);
}
/* 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 0;
return -1;
}
/* ---------------------------------------------------------------- */
/* XXX
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);
@ -47,11 +43,7 @@ fprintf(stderr, ">>> %s ( %p %p %p 0x%04x )\n", __func__,
return -1;
}
*/
/* ---------------------------------------------------------------- */
/*
* See also: fimg_extractor() in geometry.c
*/
int fimg_incrustator_0(FloatImg *psrc, FloatImg *pdst,
int xpos, int ypos, int flags)
{
@ -65,8 +57,6 @@ fprintf(stderr, ">>> %s ( %p %p %d %d 0x%04X\n", __func__, psrc, pdst,
xpos, ypos, flags);
#endif
if (flags) { fprintf(stderr, "flags: 0x%04x in %s\n", flags, __func__); }
if (verbosity > 1) {
fimg_describe(psrc, "source");
fimg_describe(pdst, "destination");
@ -76,15 +66,10 @@ if (verbosity > 1) {
area.x = xpos; area.y = ypos;
area.w = psrc->width; area.h = psrc->height;
foo = check_boundaries(psrc, pdst, &area);
if (foo) {
fprintf(stderr, "Boudary error %d in %s:%d\n", foo, __func__, __LINE__);
return foo;
}
if ( (xpos < 0) || (xpos > pdst->width - psrc->width) ||
(ypos < 0) || (ypos > pdst->height - psrc->height) ) {
fprintf(stderr, "%s: boudary error, x=%d y=%d\n", __func__,
xpos, ypos);
fprintf(stderr, "%s: boudary error\n", __func__);
return -2;
}

Some files were not shown because too many files have changed in this diff Show More