Zzzzz....

This commit is contained in:
tth 2020-02-29 21:59:12 +01:00
parent f9467dacee
commit 248061f46b
5 changed files with 249 additions and 20 deletions

View File

@ -77,7 +77,7 @@ IRC de Freenode.
\textbf{Attention !} ce document commence par une bonne rafale \textbf{Attention !} ce document commence par une bonne rafale
de technique parfois hardue\footnote{gni?}. de technique parfois hardue\footnote{gni?}.
Vous avez parfaitement le droit de auter directement à Vous avez parfaitement le droit de sauter directement à
la page \pageref{outils} pour quelque chose de plus concret. la page \pageref{outils} pour quelque chose de plus concret.
% ------------------------------------------------------------------- % -------------------------------------------------------------------
@ -194,7 +194,7 @@ lesquels sont décrits en page \pageref{outils}.
% ------------------------------------------------------------------- % -------------------------------------------------------------------
\section{Installation} \section{Installation}
\textit{Attention, ça devient un peu gore.} \textit{Attention, ça devient un peu gore. Myrys, punk, toussa\dots}
\subsection{Prérequis} \subsection{Prérequis}
@ -209,6 +209,8 @@ comme \textsc{gnu}/make\index{make}.
Une connaissance de base de l'utilisation du shell\index{shell} Une connaissance de base de l'utilisation du shell\index{shell}
et de l'écriture de Makefile's sera un plus. et de l'écriture de Makefile's sera un plus.
Il faut aussi savoir où trouver le code.
\subsection{Compilation} \subsection{Compilation}
Un script \texttt{build.sh} permet de construire approximativement Un script \texttt{build.sh} permet de construire approximativement
@ -474,6 +476,8 @@ de pixel flottant.
\subsection{Géométrie}\index{géométrie}\label{geometrie} \subsection{Géométrie}\index{géométrie}\label{geometrie}
Très prochainement, le retour du blitter\index{blitter}. Très prochainement, le retour du blitter\index{blitter}.
Et pour attendre, un truc improbable, voire même
inutile.
\begin{lstlisting} \begin{lstlisting}
/* module funcs/geometry.c */ /* module funcs/geometry.c */
@ -485,6 +489,15 @@ contenir d'image, et doit être effacé avec un bon
\texttt{memset(\&result, 0, sizeof(FloatImg));} bien senti. \texttt{memset(\&result, 0, sizeof(FloatImg));} bien senti.
Et le résultat est très moyen : il n'y a pas d'interpolation. Et le résultat est très moyen : il n'y a pas d'interpolation.
\begin{lstlisting}
/* module funcs/geometry.c */
int fimg_extract_0(FloatImg *src, FloatImg *dst, int x, int y);
\end{lstlisting}
Contrairement à la fonction précédente, celle-ci demande absolument une
image de destination initialisée aux dimensions (largeur et hauteur)
désirées.
% ---------------------------------- % ----------------------------------
\subsection{Exportation \& Importation}\index{export}\label{export} \subsection{Exportation \& Importation}\index{export}\label{export}
@ -532,12 +545,13 @@ Actuellement, on peut enregistrer uniquement en mode RGB, 8 bits par composante,
mais on a quand même une bonne compression, ça compense. mais on a quand même une bonne compression, ça compense.
J'utilise \textsl{libpnglite} avec qui j'ai un peu de mal à suivre. 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. Mais je me soigne. Le mode 16 bits va bientôt arriver.
On peut aussi songer à l'export de metadatas.
\begin{lstlisting} \begin{lstlisting}
int fimg_save_as_png(FloatImg *src, char *outname, int flags); int fimg_save_as_png(FloatImg *src, char *outname, int flags);
\end{lstlisting} \end{lstlisting}
Tous les flags doivent être à zéro. Tous les flags doivent être à zéro. Sinon, ça foire parfois.
\subsubsection{Vers/depuis TIFF}\index{TIFF} \subsubsection{Vers/depuis TIFF}\index{TIFF}
@ -549,7 +563,8 @@ To be done\index{XXX}
\subsubsection{Vers FITS}\index{FITS} \subsubsection{Vers FITS}\index{FITS}
Essentiellement des images d'astronomie. Ce format est essentiellement utilisé pour stocker des images
d'astronomie.
To be done\index{XXX} To be done\index{XXX}
@ -571,9 +586,9 @@ La fonction \texttt{int format\_from\_extension(char *fname)} examine un
nom defichier tel que \texttt{lena.xxx}, et retourne, si la partie nom defichier tel que \texttt{lena.xxx}, et retourne, si la partie
\texttt{xxx} un éventuel nombre positif, dont les valeurs sont dans floatimg.h \texttt{xxx} un éventuel nombre positif, dont les valeurs sont dans floatimg.h
le valeureux. le valeureux.
Les extensions connues sont : fimg, png, pnm et tiff. Les extensions actuellement connues sont : fimg, png, pnm et tiff.
To be continued\index{XXX} To be continued\index{XXX}\dots
\subsection{Effets}\index{sfx} \subsection{Effets}\index{sfx}
@ -594,13 +609,45 @@ int fimg_killcolors_b(FloatImg *fimg, float fval);
Pour commencer, il faut que je réfléchisse au traitement Pour commencer, il faut que je réfléchisse au traitement
des bordures des images. des bordures des images.
Ensuite que je débuggue\index{bug} cette fonction~: Ensuite que je débuggue\index{bug} ces deux fonctions~:
\begin{lstlisting} \begin{lstlisting}
int fimg_lissage_2x2(FloatImg *img); int fimg_lissage_2x2(FloatImg *img);
int fimg_killborders(FloatImg *img);
\end{lstlisting} \end{lstlisting}
To be continued\index{XXX}\dots Bon, oké, ça marche ? Passons à l'tape suivante.
La convolution avec une matrice 3x3, c'est possible.
Et pas trop compliqué à faire.
Bon, il reste le souci avec les bordures, souci qui ne peut
être que temporaire, mais ésotérique à fixer.
Passons maintenant aux choses sérieuses, et définissons la
description d'un filtre 3x3.
\begin{verbatim}
typedef struct {
float matrix[9];
float mult;
float offset;
} FimgFilter3x3;
\end{verbatim}
L'usage des champs \texttt{mult} et \texttt{offset} n'est pas
clairement défini. Le prototype de la fonction de filtrage
non plus, mais assez simpe quand même. Source et destination
ne peuvent désigner la même image, et le champ \texttt{matrix}
du filtre doit contenir des valeurs cohérentes.
\begin{verbatim}
int fimg_filter_3x3(FloatImg *src, FloatImg *dst, FimgFilter3x3 *filtr)
\end{verbatim}
Comme dans la plupart des cas, la gestion des valeurs négatives
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}
% ---------------------------------- % ----------------------------------
@ -787,6 +834,8 @@ 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} les valeurs négatives peuvent être la cause de \textsl{glitches}
de qualitay. de qualitay.
% -------------------------
\subsection{fimg2png, fimg2pnm, fimg2tiff} \subsection{fimg2png, fimg2pnm, fimg2tiff}
\index{fimg2png}\label{fimg2png} \index{fimg2png}\label{fimg2png}
\index{fimg2pnm}\label{fimg2pnm} \index{fimg2pnm}\label{fimg2pnm}
@ -797,7 +846,7 @@ vers des choses plus directement utilisables. À condition que le
code soit écrit et documenté. code soit écrit et documenté.
D'un autre coté, écrire un greffon d'import/export pour D'un autre coté, écrire un greffon d'import/export pour
Gimp\index{Gimp} ou Imagemagick\index{Imagemagick} ou Krita\index{Krita} Gimp\index{Gimp} ou ImageMagick\index{ImageMagick} ou Krita\index{krita}
ne devrait pas être trop difficile. Des volontaires ? ne devrait pas être trop difficile. Des volontaires ?
\textsl{D'ailleurs, pourquoi $n$ logiciels indépendants alors q'un \textsl{D'ailleurs, pourquoi $n$ logiciels indépendants alors q'un
@ -821,7 +870,7 @@ C'est par ces frottements de techniques ayant du sens que les
choses seront acquises. choses seront acquises.
\begin{itemize} \begin{itemize}
\item Import/export au format \textsc{tiff}\index{tiff}. \item Import/export au format \textsc{tiff}\index{TIFF}.
\item Remplacer le « fait-maison » par \textsc{libnetpnm}\index{pnm}. \item Remplacer le « fait-maison » par \textsc{libnetpnm}\index{pnm}.
\textsl{[en cours]}. \textsl{[en cours]}.
\item Compléter les traitements mathémathiques (eg le gamma\index{gamma}). \item Compléter les traitements mathémathiques (eg le gamma\index{gamma}).
@ -1094,6 +1143,39 @@ l'\textsc{api} de \textsc{v4l2}, et donc, que ce que raconte
ce logiciel doit être pris avec des pincettes. En particulier ce logiciel doit être pris avec des pincettes. En particulier
la liste des résolutions disponibles. la liste des résolutions disponibles.
% -------------------------------------------------------------------
\section{À l'extérieur}
\subsection{ImageMagick}\index{ImageMagick}
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}~:
\begin{verbatim}
<?xml version="1.0" encoding="UTF-8"?>
<delegatemap>
<delegate decode="fimg" command="fimg2png '%i' '%o'"/>
</delegatemap>
\end{verbatim}
C'est juste un hack rapide, qui ne fonctionne pas très bien avec
d'autres commande de IM, comme identify, qui a tendance à
raconter un peu n'importe quoi... Je compte donc sur le bouquin
de \textsl{Brunus} pour avancer...
\subsection{Gimp}\index{Gimp}
Mmmmm... Ça semble un peu plus compliqué. D'un autre coté, il
faut faire ça en \textbf{C}, ce qui ne peut être négatif.
\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.
% ------------------------------------------------------------------- % -------------------------------------------------------------------
\section{Et pour la suite ?} \section{Et pour la suite ?}

View File

@ -1,6 +1,6 @@
#--------------------------------------------------------------- #---------------------------------------------------------------
COPT = -Wall -fpic -g -no-pie -DDEBUG_LEVEL=0 COPT = -Wall -fpic -g -pg -no-pie -DDEBUG_LEVEL=0
DEPS = ../floatimg.h Makefile DEPS = ../floatimg.h Makefile
OBJS = fimg-png.o fimg-tiff.o misc-plots.o filtrage.o utils.o \ OBJS = fimg-png.o fimg-tiff.o misc-plots.o filtrage.o utils.o \
fimg-libpnm.o rampes.o sfx0.o geometry.o fimg-libpnm.o rampes.o sfx0.o geometry.o

View File

@ -7,7 +7,75 @@
#include "../floatimg.h" #include "../floatimg.h"
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
int fimg_lissage_2x2(FloatImg *img) /* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
int fimg_filter_3x3(FloatImg *src, FloatImg *dst, FimgFilter3x3 *filtr)
{
int x, y, w, h, of;
float *pr, *pg, *pb; /* alias for src pix filds */
float *M; /* alias of filter matrix */
double dval;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p %p)\n", __func__, s, d, filtr);
#endif
/* aliasing some vars for cleaner code */
pr = src->R; pg = src->G; pb = src->B;
w = src->width; h = src->height;
M = filtr->matrix;
for (y=1; y < h-1; y++) {
for (x=1; x < w-1; x++) {
of = x + (y * w);
dval = M[0] * pr[of-(w+1)] +
M[1] * pr[of-w] +
M[2] * pr[of-(w-1)] +
M[3] * pr[of-1] +
M[4] * pr[of] +
M[5] * pr[of+1] +
M[6] * pr[of+(w+1)] +
M[7] * pr[of+w] +
M[8] * pr[of+(w-1)] ;
dst->R[of] = dval;
dval = M[0] * pg[of-(w+1)] +
M[1] * pg[of-w] +
M[2] * pg[of-(w-1)] +
M[3] * pg[of-1] +
M[4] * pg[of] +
M[5] * pg[of+1] +
M[6] * pg[of+(w+1)] +
M[7] * pg[of+w] +
M[8] * pg[of+(w-1)] ;
dst->G[of] = dval;
dval = M[0] * pb[of-(w+1)] +
M[1] * pb[of-w] +
M[2] * pb[of-(w-1)] +
M[3] * pb[of-1] +
M[4] * pb[of] +
M[5] * pb[of+1] +
M[6] * pb[of+(w+1)] +
M[7] * pb[of+w] +
M[8] * pb[of+(w-1)] ;
dst->B[of] = dval;
}
}
return -1;
}
/* -------------------------------------------------------------------- */
/*
* this is the more shifting hack on the block.
*/
static int fimg_lissage_2x2_a(FloatImg *img)
{ {
int x, y, offset; int x, y, offset;
float cr, cg, cb; float cr, cg, cb;
@ -66,7 +134,6 @@ if (img->type != FIMG_TYPE_RGB) {
return -99; return -99;
} }
h = img->height; w = img->width; h = img->height; w = img->width;
for (idx=0; idx<h; idx++) { for (idx=0; idx<h; idx++) {
@ -104,4 +171,20 @@ for (idx=0; idx<w; idx++) {
return -1; return -1;
} }
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
int fimg_lissage_2x2(FloatImg *img)
{
int foo;
foo = fimg_lissage_2x2_a(img);
if (foo) {
fprintf(stderr, "%s: fail %d\n", __func__, foo);
return foo;
}
/* XXX */
fimg_killborders(img);
return foo;
}
/* -------------------------------------------------------------------- */

View File

@ -13,14 +13,68 @@ int verbosity;
float global_fvalue; float global_fvalue;
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
int essai_filtrage(char *infile) int essai_filtrage_3x3(char *infile)
{
FloatImg src, dst;
int foo, idx;
char buffer[100];
FimgFilter3x3 filter_a = {
{ 1.0, 1.0, 1.0,
1.0, -3.0, 1.0,
1.0, 1.0, 1.0 },
8.0, 0.0
};
FimgFilter3x3 filter_b = {
{ -2.0, -1.0, 0.0,
-1.0, 3.0, 1.0,
0.0, 1.0, 2.0 },
8.0, 0.0
};
if (NULL != infile) {
fprintf(stderr, "%s: loading %s\n", __func__, infile);
foo = fimg_create_from_dump(infile, &src);
if (foo) {
fprintf(stderr, "%s: err load '%s'\n", __func__, infile);
return foo;
}
}
else {
fprintf(stderr, "%s is creating the picz\n", __func__);
fimg_create(&src, 640, 480, FIMG_TYPE_RGB);
fimg_test_pattern(&src, 0, 255.0);
fimg_save_as_png(&src, "test.png", 0);
}
foo = fimg_clone(&src, &dst, 0);
fimg_filter_3x3(&src, &dst, &filter_b);
foo = fimg_clamp_negativ(&dst);
if (foo) {
fprintf(stderr, "clamped %d negativ pixels\n", foo);
}
foo = fimg_save_as_png(&dst, "f3x3.png", 0);
foo = fimg_save_as_pnm(&dst, "f3x3.pnm", 0);
fimg_destroy(&src); fimg_destroy(&dst);
return 0;
}
/* --------------------------------------------------------------------- */
int essai_filtrage_2x2(char *infile)
{ {
FloatImg fimg; FloatImg fimg;
int foo, idx; int foo, idx;
char buffer[100]; char buffer[100];
if (NULL != infile) { if (NULL != infile) {
fprintf(stderr, "loading %s\n", infile); fprintf(stderr, "%s: loading %s\n", __func__, infile);
foo = fimg_create_from_dump(infile, &fimg); foo = fimg_create_from_dump(infile, &fimg);
if (foo) { if (foo) {
fprintf(stderr, "%s: err load '%s'\n", __func__, infile); fprintf(stderr, "%s: err load '%s'\n", __func__, infile);
@ -39,11 +93,13 @@ foo = fimg_save_as_pnm(&fimg, "source.pnm", 0);
* running multiple filters so you can * running multiple filters so you can
* watch the up-left shift :) * watch the up-left shift :)
*/ */
for (idx=0; idx<10; idx++) { for (idx=0; idx<5; idx++) {
foo = fimg_lissage_2x2(&fimg); foo = fimg_lissage_2x2(&fimg);
foo = fimg_killborders(&fimg);
sprintf(buffer, "filter%03d.png", idx); sprintf(buffer, "filter%03d.png", idx);
foo = fimg_save_as_png(&fimg, buffer, 0); foo = fimg_save_as_png(&fimg, buffer, 0);
if (verbosity) {
fprintf(stderr, "%s %d\n", buffer, foo);
}
} }
fimg_destroy(&fimg); fimg_destroy(&fimg);
@ -238,11 +294,19 @@ fprintf(stderr, "argc %d optind %d\n", argc, optind);
filename = NULL; filename = NULL;
if (1 == argc-optind) filename = argv[optind]; if (1 == argc-optind) filename = argv[optind];
foo = essai_filtrage(filename); /*
foo = essai_filtrage_2x2(filename);
if (foo) { if (foo) {
fprintf(stderr, "====> %d\n", foo); fprintf(stderr, "Filtre 2x2 ====> %d\n", foo);
}
*/
foo = essai_filtrage_3x3(filename);
if (foo) {
fprintf(stderr, "Filtre 3x3 ====> %d\n", foo);
} }
fprintf(stderr, "++++++++++++++ end of pid %d\n", getpid());
return 0; return 0;
} }
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */

View File

@ -2,7 +2,7 @@
# building the base library # building the base library
# #
COPT = -Wall -fpic -g -no-pie -DDEBUG_LEVEL=0 COPT = -Wall -fpic -g -pg -no-pie -DDEBUG_LEVEL=0
OBJS = fimg-core.o fimg-pnm.o fimg-file.o fimg-math.o \ OBJS = fimg-core.o fimg-pnm.o fimg-file.o fimg-math.o \
fimg-timers.o operators.o fimg-2gray.o \ fimg-timers.o operators.o fimg-2gray.o \