Browse Source

Zzzzz....

master
tth 2 years ago
parent
commit
248061f46b
  1. 102
      doc/the_floatimg_hack.tex
  2. 2
      funcs/Makefile
  3. 87
      funcs/filtrage.c
  4. 76
      funcs/t.c
  5. 2
      lib/Makefile

102
doc/the_floatimg_hack.tex

@ -77,7 +77,7 @@ IRC de Freenode. @@ -77,7 +77,7 @@ IRC de Freenode.
\textbf{Attention !} ce document commence par une bonne rafale
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.
% -------------------------------------------------------------------
@ -194,7 +194,7 @@ lesquels sont décrits en page \pageref{outils}. @@ -194,7 +194,7 @@ lesquels sont décrits en page \pageref{outils}.
% -------------------------------------------------------------------
\section{Installation}
\textit{Attention, ça devient un peu gore.}
\textit{Attention, ça devient un peu gore. Myrys, punk, toussa\dots}
\subsection{Prérequis}
@ -209,6 +209,8 @@ comme \textsc{gnu}/make\index{make}. @@ -209,6 +209,8 @@ 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.
\subsection{Compilation}
Un script \texttt{build.sh} permet de construire approximativement
@ -474,6 +476,8 @@ de pixel flottant. @@ -474,6 +476,8 @@ de pixel flottant.
\subsection{Géométrie}\index{géométrie}\label{geometrie}
Très prochainement, le retour du blitter\index{blitter}.
Et pour attendre, un truc improbable, voire même
inutile.
\begin{lstlisting}
/* module funcs/geometry.c */
@ -485,6 +489,15 @@ contenir d'image, et doit être effacé avec un bon @@ -485,6 +489,15 @@ contenir d'image, et doit être effacé avec un bon
\texttt{memset(\&result, 0, sizeof(FloatImg));} bien senti.
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}
@ -532,12 +545,13 @@ Actuellement, on peut enregistrer uniquement en mode RGB, 8 bits par composante, @@ -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.
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 de metadatas.
\begin{lstlisting}
int fimg_save_as_png(FloatImg *src, char *outname, int flags);
\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}
@ -549,7 +563,8 @@ To be done\index{XXX} @@ -549,7 +563,8 @@ To be done\index{XXX}
\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}
@ -571,9 +586,9 @@ La fonction \texttt{int format\_from\_extension(char *fname)} examine un @@ -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
\texttt{xxx} un éventuel nombre positif, dont les valeurs sont dans floatimg.h
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}
@ -594,13 +609,45 @@ int fimg_killcolors_b(FloatImg *fimg, float fval); @@ -594,13 +609,45 @@ int fimg_killcolors_b(FloatImg *fimg, float fval);
Pour commencer, il faut que je réfléchisse au traitement
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}
int fimg_lissage_2x2(FloatImg *img);
int fimg_killborders(FloatImg *img);
\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 @@ -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}
de qualitay.
% -------------------------
\subsection{fimg2png, fimg2pnm, fimg2tiff}
\index{fimg2png}\label{fimg2png}
\index{fimg2pnm}\label{fimg2pnm}
@ -797,7 +846,7 @@ vers des choses plus directement utilisables. À condition que le @@ -797,7 +846,7 @@ vers des choses plus directement utilisables. À condition que le
code soit écrit et documenté.
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 ?
\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 @@ -821,7 +870,7 @@ C'est par ces frottements de techniques ayant du sens que les
choses seront acquises.
\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}.
\textsl{[en cours]}.
\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 @@ -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
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 ?}

2
funcs/Makefile

@ -1,6 +1,6 @@ @@ -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
OBJS = fimg-png.o fimg-tiff.o misc-plots.o filtrage.o utils.o \
fimg-libpnm.o rampes.o sfx0.o geometry.o

87
funcs/filtrage.c

@ -7,7 +7,75 @@ @@ -7,7 +7,75 @@
#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;
float cr, cg, cb;
@ -66,7 +134,6 @@ if (img->type != FIMG_TYPE_RGB) { @@ -66,7 +134,6 @@ if (img->type != FIMG_TYPE_RGB) {
return -99;
}
h = img->height; w = img->width;
for (idx=0; idx<h; idx++) {
@ -104,4 +171,20 @@ for (idx=0; idx<w; idx++) { @@ -104,4 +171,20 @@ for (idx=0; idx<w; idx++) {
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;
}
/* -------------------------------------------------------------------- */

76
funcs/t.c

@ -13,14 +13,68 @@ int verbosity; @@ -13,14 +13,68 @@ int verbosity;
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;
int foo, idx;
char buffer[100];
if (NULL != infile) {
fprintf(stderr, "loading %s\n", infile);
fprintf(stderr, "%s: loading %s\n", __func__, infile);
foo = fimg_create_from_dump(infile, &fimg);
if (foo) {
fprintf(stderr, "%s: err load '%s'\n", __func__, infile);
@ -39,11 +93,13 @@ foo = fimg_save_as_pnm(&fimg, "source.pnm", 0); @@ -39,11 +93,13 @@ foo = fimg_save_as_pnm(&fimg, "source.pnm", 0);
* running multiple filters so you can
* watch the up-left shift :)
*/
for (idx=0; idx<10; idx++) {
for (idx=0; idx<5; idx++) {
foo = fimg_lissage_2x2(&fimg);
foo = fimg_killborders(&fimg);
sprintf(buffer, "filter%03d.png", idx);
foo = fimg_save_as_png(&fimg, buffer, 0);
if (verbosity) {
fprintf(stderr, "%s %d\n", buffer, foo);
}
}
fimg_destroy(&fimg);
@ -238,11 +294,19 @@ fprintf(stderr, "argc %d optind %d\n", argc, optind); @@ -238,11 +294,19 @@ fprintf(stderr, "argc %d optind %d\n", argc, optind);
filename = NULL;
if (1 == argc-optind) filename = argv[optind];
foo = essai_filtrage(filename);
/*
foo = essai_filtrage_2x2(filename);
if (foo) {
fprintf(stderr, "Filtre 2x2 ====> %d\n", foo);
}
*/
foo = essai_filtrage_3x3(filename);
if (foo) {
fprintf(stderr, "====> %d\n", foo);
fprintf(stderr, "Filtre 3x3 ====> %d\n", foo);
}
fprintf(stderr, "++++++++++++++ end of pid %d\n", getpid());
return 0;
}
/* --------------------------------------------------------------------- */

2
lib/Makefile

@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
# 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 \
fimg-timers.o operators.o fimg-2gray.o \

Loading…
Cancel
Save