Bibliothèque de traitements d'images en virgule flottante. http://la.buvette.org/photos/cumul/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1407 lines
49 KiB

\documentclass[a4paper,10pt]{article}
3 years ago
% \listfiles % pour le debug
\usepackage[french]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{makeidx}
\usepackage{listings}
% \lstset{frame=single} % dessin d'un cadre autour du listing
\lstset{basicstyle=\ttfamily\small}
\lstset{aboveskip=0.222em,belowskip=0.222em}
1 year ago
\usepackage{babel} % ?
3 years ago
1 year ago
\usepackage{graphicx} % for gnuplot ylabel rotate
1 year ago
\usepackage{pifont} % caractères rigolos
3 years ago
\usepackage{enumitem}
\setitemize[1]{label={\ding{87}}}
3 years ago
\frenchbsetup{CompactItemize=false}
3 years ago
% \usepackage{color}
% \usepackage{url}
\usepackage{xspace}
\usepackage[verbose]{layout}
\setlength \parskip {0.35em}
2 years ago
\makeatletter
1 year ago
% explication de ce truc ?
2 years ago
\def\verbatim@font{\normalfont\ttfamily\small}
\makeatother
\setlength{\hoffset}{0em}
\setlength{\textheight}{640pt}
\setlength{\textwidth}{422pt}
\setlength{\marginparwidth}{10pt}
3 years ago
\makeindex
3 years ago
% ------ a few new commands
\newcommand{\interparagraphe { \vspace{60pt} } }
3 years ago
% -------------------------------------------------------------------
\title{Floating images processing}
3 years ago
\author{tTh}
\begin{document}
\maketitle
\section{Image flottante ?}
3 years ago
Mais de quoi parle-t-on exactement ?
3 years ago
% XXX XXX XXX\vspace{1em}
Traditionnellement, les valeurs des pixels dans les images
informatiques sont mémorisées sur 8 bits, un octet\index{octet},
soit 256 valeurs différentes.
Ceci dit, on trouve parfois des images codées sur 16 bits par
composante, mais c'est loin d'être le cas général.
J'ai donc souhaité aller plus loin, et coder chaque canal de
chaque pixel en virgule flottante sur 32bits, le type
\texttt{float}\index{float} du langage C. Ce qui correspond
à la norme IEEE 754-1985.
3 years ago
% XXX XXX XXX\vspace{1em}
3 years ago
Attention, tout le code que nous allons voir ensemble est en
perpétuelle évolution\footnote{voir page \pageref{TODO}},
et sa fiablité (surtout sur certains aspects mathématiques)
reste à démontrer\index{valgrind}.
3 years ago
Mais le service après-vente est assez réactif. Du moins
pour ceux qui suivent le canal \texttt{\#tetalab} sur le réseau
3 years ago
IRC de Freenode.
2 years ago
\textbf{Attention !} ce document commence par une bonne rafale
de technique parfois hardue\footnote{gni?}.
2 years ago
Vous avez parfaitement le droit de sauter directement à
2 years ago
la page \pageref{outils} pour quelque chose de plus concret.
% -------------------------------------------------------------------
\setlength \parskip {0em}
3 years ago
\tableofcontents
\pagebreak
\setlength \parskip {0.40em}
3 years ago
% \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~:
\begin{quotation}
An IEEE 754 32-bit base-2 floating-point variable has
a maximum value of
$(2 - 2^{-23}) \times 2^{127} \approx 3.4028235 \times 10^{38}$.
All integers with 7 or fewer decimal digits, and any $2^{n}$ for
a whole number $-149 \leq n \leq 127$, can be converted exactly into
an IEEE 754 single-precision floating-point value.
In the IEEE 754-2008 standard, the 32-bit base-2 format is
officially referred to as binary32; it was called single in
IEEE 754-1985.
\end{quotation}
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}
2 years ago
Dynamique, précision et \textsl{macheps} ?
\subsection{Pixel négatif ?}
2 years ago
Il est très difficle d'imaginer une lumière négative. Sauf peut-être
1 year ago
si nous songeons à des coefficients d'absorption, ou un canal
\textsl{alpha} qui inverserait les valeurs ?
% -------------------------------------------------------------------
\section{Premier exemple}\index{exemple}\label{exemple}
3 years ago
3 years ago
\textsc{FloatImg} a débuté sous la forme de quelques fonctions
basiques en C, gérant la structure des données d'image en mémoire
3 years ago
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.
3 years ago
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.
1 year ago
Enfin, non, il y a déja longtemps, avant la 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;
3 years ago
char *fname = "exemple.fimg";
FloatImg fimg;
\end{lstlisting}
1 year ago
Ensuite, nous enchainerons trois étapes : la création de l'image
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}
3 years ago
foo = fimg_create(&fimg, width, height, FIMG_TYPE_RGB);
if (foo) {
fprintf(stderr, "create floatimg -> %d\n", foo);
exit(1);
}
fimg_clear(&fimg);
foo = fimg_dump_to_file(&fimg, fname, 0);
if (foo) {
fprintf(stderr, "dump fimg -> %d\n", foo);
exit(1);
}
\end{lstlisting}
Une fois ce code enrobé dans un \texttt{main()}, compilé et exécuté,
nous pouvons entrevoir, grâce au logiciel
\texttt{fimgstats} (voir page \pageref{fimgstats}),
le résultat sous forme de chiffres divers, et/ou inutiles~:
\begin{verbatim}
3 years ago
$ ./fimgstats quux.img
----------- numbers from 'quux.img' :
640 480 3 0x7f3718c4f010 0x7f3718d7b010 0x7f3718ea7010
surface 307200
mean values:
R 0.000000
G 0.000000
B 0.000000
A 0.000000
max value 0.000000
\end{verbatim}
3 years ago
Nous avons donc sous la main une mécanique qui ne demande qu'à
faire des trucs futiles et des images qui clignotent.
La suite vers la page \pageref{codaz}.
Vous trouverez dans le répertoire \texttt{tools/}\index{tools/}
d'autres exemples de mise en œuvre des fonctions disponibles
3 years ago
sous formes d'outils en ligne de commande,
3 years ago
lesquels sont décrits en page \pageref{outils}.
% -------------------------------------------------------------------
\section{Installation}
Sauf indications contraires, ces instructions se réfèrent à
1 year ago
une distribution Debian\index{Debian} récente, mais ça marche
quasiment pareil avec Fedora\index{Fedora}.
\textit{Attention, ça devient un peu gore\dots}
\subsection{Prérequis}
1 year ago
Vous devez, en dehors des outils classiques (gcc, Awk, make\dots),
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-dev
} % end of textsf
éventuellement avec le \textsf{-dev} correspondant,
et probablement d'autres choses.
3 years ago
Il est même quasiment certain que Bash soit indispensable, tout
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.
2 years ago
Il faut aussi savoir où trouver le code.
\subsection{Compilation}
Un script \texttt{build.sh} permet de construire approximativement
3 years ago
le bouzin. Il est loin d'être parfait\footnote{Il doit être possible
de faire un Makefile récursif, mais\dots}.
Dans chacun des répertoires à traiter, ce script devrait trouver
un Makefile et un fichier \texttt{t.c} qui est le source de la cible
par défaut du make.
3 years ago
Pour le moment, la procédure d'installation est un peu rude,
pour ne pas dire clairement sommaire.
3 years ago
Si le résultat de l'étape compilation vous semble correct,
vous pouvez copier les deux fichiers \texttt{floatimg.h} et
\texttt{libfloatimg.a} dans un emplacement approprié, par exemple
3 years ago
\texttt{/usr/local/include} et \texttt{/usr/local/lib}.
3 years ago
Le script \texttt{install.sh}, à la racine du projet, est censé
faciliter un peu la chose. Il prend également en compte la copie
des divers binaires du dossier \texttt{tools/} (cf page \pageref{outils})
1 year ago
dans le répertoire prévu à cet effet~: \texttt{/usr/local/bin}.
3 years ago
Il reste enfin quelques exemples d'utilisation des outils de la
ligne de commande depuis un shell
dans le répertoire \texttt{scripts/}.
Ils sont décrits plus en détail page
\pageref{scripts}, et c'est à vous de les adapter à votre \textsl{usecase}.
Faites-en ce que vous voulez.
% =================================================================
3 years ago
\section{Utilisation coté codeur}\label{codaz}
Classiquement, il y a un fichier \texttt{.h} à inclure dans chacun
de vos codes source,
3 years ago
\texttt{floatimg.h}, généralement logé dans \texttt{/usr/local/include}
contenant un certain nombre de définition de structures, de macros,
de constantes\footnote{À l'ancienne, via le pré-processeur}
3 years ago
et les prototypes des fonctions utilisables par vos logiciels.
Au niveau du code source, ces fonctions sont approximativement
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
1 year ago
est en fait indécement arbitraire.
\subsection{Structures, macros\dots}
Les pixels flottants d'une image résidant en mémoire centrale
sont décrits par un ensemble
3 years ago
de données (certains appelent ça des \textsl{metadatas}) regroupées
dans une jolie structure que nous allons examiner dès maintenant.
\begin{lstlisting}
/* in memory descriptor */
typedef struct {
1 year ago
int magic;
int width;
int height;
int type;
float fval;
int count;
float *R, *G, *B, *A;
int reserved;
} FloatImg;
\end{lstlisting}\index{FloatImg}
1 year ago
Le premier champ, \texttt{magic}, servira un de ces jours à
robustifier l'ensemble du machin.
Les deux suivants sont \textsl{obvious}.
Le troisième est le type d'image : pour le moment, il y en a % trois
un certain nombre
qui sont définis\footnote{et plus ou moins bien gérés\dots} :
1 year ago
gris, rgb et rgba/rgbz\index{rgba}\index{rgbz}.
Les constantes adéquates sont dans \texttt{floatimg.h}
\begin{lstlisting}
#define FIMG_TYPE_GRAY 1
#define FIMG_TYPE_RGB 3
#define FIMG_TYPE_RGBA 4
#define FIMG_TYPE_RGBZ 99
\end{lstlisting}
Un peu plus loin, nous avons les pointeurs vers les
différents \textsl{pixmaps} de l'image. En principe l'organisation
3 years ago
interne de ces zones est improbable, puisque elle dérive
d'idées approximatives. C'est cette utilisation constructive de larache
qui fait que seuls les champs documentés de cette structure ne sont
pas explosifs.
3 years ago
Mais revenons aux choses sérieuses\dots
Les deux champs suivants (fval et count) sont à la disposition du
\textsl{yuser}
qui peut jouer avec à loisir pour faire, par exemple, ce genre de
3 years ago
chose : imaginons un périphérique de capture qui nous fournisse des
images en gris sur 4 bits (et linéaire).
Et que nous voulions cumuler\index{cumul}
quelques images...
3 years ago
Le champ \textsl{count} sera mis à 0 et
le champ \textsl{fval} sera initialisé à 15.0
1 year ago
(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
3 years ago
de notre image dans les étapes ultérieures, puisque la valeur
maximale théorique est égale à $fval * count$.
La fonction \texttt{fimg\_printhead(FloatImg *h)} affiche
sommairement le contenu de ce descripteur,
et \texttt{fimg\_describe(FloatImg *head, char *txt)} propose
1 year ago
un affichage plus détaillé. Ça peut parfois aider.
Une bonne partie des fonctions que nous allons voir est indéterministe.
Ce qui veut dire, en langage de tous les soirs, que ça risque de ne
1 year ago
pas être la même chose dans l'avenir. Mais après tout, ce n'est
encore qu'un concept en devenir, n'est-ce pas ?
3 years ago
% ----------------------------------
\subsection{Les fondations}\index{lib/}
La première chose que nous devons absolument voir est la gestion
dynamique de la mémoire qui sera occupée par tous ces pixels flottants,
ce qui est un sujet parfois délicat\footnote{GC or not GC ?}.
Elle est donc faite, à la base, par ces deux fonctions~:
\begin{lstlisting}
int fimg_create(FloatImg *fimg, int w, int h, int type);
int fimg_destroy(FloatImg *fimg);
\end{lstlisting}
L'appelant doit lui-même gérer le descripteur d'image (une structure
C décrite plus haut) en le considérant comme un type semi-opaque dont
1 year ago
la forme \emph{peut} varier.
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 : 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: 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 compatible */
int fimg_images_not_compatible(FloatImg *a, FloatImg *b);
\end{lstlisting}
C'est bien beau d'être enfin résident 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.
2 years ago
Le format des fichiers est décrit page \pageref{formatfimg}.
\begin{lstlisting}
int fimg_dump_to_file(FloatImg *fimg, char *fname, int notused);
int fimg_load_from_dump(char *fname, FloatImg *where);
\end{lstlisting}
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 ram doit être
pré-allouée. On peut connaitre ces valeurs en appelant
\texttt{int fimg\_fileinfos(char *fname, int datas[3])}.
Si tout s'est bien passé (valeur retournée égale à 0),
on va trouver la largeur dans \texttt{datas[0]},
la hauteur dans \texttt{datas[1]} et le type dans
\texttt{datas[2]}\footnote{La fonction
\texttt{fimg\_type\_is\_valid(int type)} peut vous aider\dots}.
Je sais aussi que certains d'entre vous aiment la facilité, aussi
je vais vous révéler l'existence d'un nouveau truc bien plus
simple, une fonction qui enchaine ces deux actions
(allocation, puis lecture), et s'utilise
comme ça :
\begin{lstlisting}
FloatImg head;
memset(&head, 0, sizeof(FloatImg));
foo = fimg_create_from_dump("lena.fimg", &head);
\end{lstlisting}
Si la valeur retournée est différente de 0, c'est que quelque
chose s'est probablement mal passé.
2 years ago
Certains messages sont parfois explicites.
% _________
\subsection{Dessiner}
Bon, vous avez une image latente, et vous souhaitez dessiner dessus
(ou dedans ?) avec vos encres flottantes ?
Il y a des fonctions pour ça, par exemple~:
\begin{lstlisting}
int fimg_plot_rgb(FloatImg *head, int x, int y, float r, float g, float b);
\end{lstlisting}
3 years ago
Les paramètres sont explicites, mais leur validité doit être
sévèrement controlée par l'appelant. Il y a une fonction
soeur, \texttt{fimg\_add\_rgb}\index{fimg\_add\_rgb},
qui ajoute du rgb à un pixel, laquelle fonction a d'ailleurs été
à la base de la seconde génération de la
photographie\index{photographie} en cumul\index{cumul}.
Inversement, la fonction
\texttt{fimg\_get\_rgb(FloatImg *head, int x, int y, float *rgb)}
permet de lire les valeurs des trois canaux d'un pixel donné.
Là aussi, il n'y a aucun contrôle sur la validité des valeurs
$x$ et $y$ de la demande.
2 years ago
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
1 year ago
\textsl{z-buffer}\index{z-buffer}\index{rgbz}\dots
2 years ago
% ----------------------------------
\subsection{Contraste}\index{contraste}\label{contraste}
Certaines opérations d'ajustement du contraste d'une image
semblent cohérentes avec la notion d'image flottante.
Certaines d'entre elles, les plus simples, sont disponibles.
Les autres sont à imaginer.
2 years ago
\begin{figure}[h]
\input{cos01.tex} % XXX XXX XXX
\caption{Correcteur cos01}
\end{figure}
Ils prennent chacun trois paramètres, d'abord les images
source et destination (\texttt{* FloatImg}),
ensuite le troisième
qui est un nombre en double précision donnant la valeur
maximale \textsl{supposée} de l'image source,
valeur qui peut être déterminée de plusieurs manières.
\begin{lstlisting}
/* source in lib/contrast.c */
int fimg_square_root(FloatImg *s, FloatImg *d, double maxval);
int fimg_power_2(FloatImg *s, FloatImg *d, double maxval);
int fimg_cos_01(FloatImg *s, FloatImg *d, double maxval);
int fimg_cos_010(FloatImg *s, FloatImg *d, double maxval);
\end{lstlisting}
Si vous souhaitez rajouter votre propre méthode de modification
de contraste, il y a quelques explication en page \pageref{exemplefunc}.
1 year ago
Mais rien ne vous oblige à le faire. Sauf vos envies.
2 years ago
\begin{figure}[h]
\input{cos010.tex} % XXX XXX XXX
\caption{Correcteur cos010}
\end{figure}
Rappelons qu'il est possible pour un logiciel applicatif
comme \texttt{grabvidseq} (cf page \pageref{grabvidseq})
de renseigner deux champs du descripteur d'image avec des
données pertinentes.
Ces deux champs sont \textit{fval} et \textit{count}.
Dans ce cas particulier, le premier indique la valeur
maximale du capteur, et le second sert à compter le
nombre de capture\footnote{Et c'est bien géré aussi
dans l'upscaling.} effectuées.
La fonction
\texttt{fimg\_normalize(FloatImg *fi, double maxima, int notused);}
tente de gérer ce cas d'utilisation. Son ajout au captureur d'images
floues sera probablement le bienvenue. Je me suis bien rendu compte
à l'usage\footnote{Une histoire de \textit{fonderie}, un logiciel
censé faire des films flous à partir d'images floues} en situation
festive qu'il manquait des données dans la chaine de traitement.
L'autre façon de procéder est d'explorer notre image à la
recherche de la valeur maximale.
La fonction \texttt{float fimg\_get\_maxvalue(\&fimg)} est
prévue pour ça de façon sommaire.
C'est actuellement la méthode utilisée par l'outil qui
sert à faire les modifications de contraste (page \pageref{fimgfx}).
On pourra aussi envisager d'utiliser
\texttt{fimg\_get\_minmax\_rgb(FloatImg *head, float mmvals[6])},
qui permet un contrôle bien plus fin des dérives.
La prochaine étape consistera à trouver une façon de faire
une égalisation\index{égalisation} par histogramme\index{histogramme}
qui respecte, dans toute sa futilité, le concept\index{concept}
2 years ago
de pixel flottant. \textsl{Et c'est pas gagné...}
3 years ago
% ----------------------------------
\subsection{Géométrie}\index{géométrie}\label{geometrie}
Très prochainement, le retour du blitter\index{blitter}.
2 years ago
Et pour attendre, un truc improbable, voire même
inutile, en fait l'inverse de l'upscaling.
\begin{lstlisting}
int fimg_halfsize_0(FloatImg *src, FloatImg *dst, int notused);
1 year ago
int fimg_halfsize_1(FloatImg *src, FloatImg *dst, int notused);
\end{lstlisting}
Attention lors de l'appel, le descripteur \texttt{dst} ne doit pas
contenir d'image, et doit être effacé avec un bon
\texttt{memset(\&result, 0, sizeof(FloatImg));} bien senti.
1 year ago
La première propose un résultat très moyen : il n'y a pas d'interpolation,
alors que la seconde semble bien mieux.
2 years ago
\begin{lstlisting}
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.
\begin{lstlisting}
int fimg_rotate_90(FloatImg *src, FloatImg *dst, int notused);
\end{lstlisting}
Rotation\index{rotation} de 90 degrés dans le sens
horlogique\footnote{ou trigonométrique,le code et la doc
ne semblent pas d'accord.} d'une image RGB.
L'image de destination peut être soit vierge, soit pré-allouée
aux bonnes dimensions (échange W et H).
2 years ago
% ----------------------------------
\subsection{Format du fichier \textsc{fimg}}\index{format}\label{formatfimg}
D'un design très empirique, c'est certainement à revoir pour l'avenir.
Tout d'abord pour normaliser l'endianess et le packing\dots
\begin{lstlisting}
typedef struct {
char magic[8];
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.
1 year ago
Le champ \texttt{magic[8]} doit contenir une valeur magique.
Le champ \texttt{t} (le type de l'image) doit avoir les trois octets
de poids fort à 0.
2 years ago
% ----------------------------------
\subsection{Exportation \& Importation}\index{export}\label{export}
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.
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
dans ce domaine\dots
\subsubsection{Vers PNM}\index{PNM}
Nous avons ici 16 bits par composante, soit 65536 valeurs différentes,
ce qui est bien au-delà de ce que peuvent percevoir vos yeux.
Hélas, c'est au prix
d'une taille énorme sur les fichiers. D'un autre coté,
l'utilisation du codage \textsc{ascii}\index{ascii}
(alors qu'on pourrait mettre du binaire, plus compact) y est
pour quelque chose.
\begin{lstlisting}
int fimg_save_as_pnm(FloatImg *head, char *fname, int flags);
\end{lstlisting}
Le bit \texttt{0} du paramètre \texttt{flags} mis à \texttt{1} demande
à la fonction de faire la mise à l'échelle avec le couple
\textsl{fvalue/count} décrit plus haut dans cette doc.
Et si il est à zéro, c'est la fonction de recherche de valeur
maximale (cf page \pageref{contraste}) qui est utilisée.
Le bit \texttt{1} permettra bientôt\index{vaporware} de demander
l'enregistrement de métadonnées\index{metadata} pertinentes, telle
que l'epochtime de l'enregistrement.
Les autres bits ne sont pas utilisés et doivent être à zéro.
\subsubsection{Vers PNG}\index{PNG}
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.
2 years ago
On peut aussi songer à l'export de metadatas.
\begin{lstlisting}
int fimg_save_as_png(FloatImg *src, char *outname, int flags);
\end{lstlisting}
2 years ago
Tous les flags doivent être à zéro. Sinon, ça foire parfois.
1 year ago
Et en fait (mars 2021) je ne suis pas très content de
\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}
Le format canonique de la PAO\index{PAO} du siècle dernier. Il permet
de gérer une foultitude de formats numériques. C'est aussi un format
classique proposé par les gros scanners corporates.
\begin{lstlisting}
1 year ago
int fimg_write_as_tiff(FloatImg *src, char *outname, int flags);
\end{lstlisting}
1 year ago
Tous les flags doivent être à zéro. Pour le moment.
\subsubsection{Vers FITS}\index{FITS}
2 years ago
Ce format est essentiellement utilisé pour stocker des images
2 years ago
d'astronomie, donc il peut aussi servir pour des images floues.
Cette partie est basée sur la bibliothèque \texttt{cfitsio} de
la NASA.
\begin{lstlisting}
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);
\end{lstlisting}
Bizarrement, l'image est stockée \textsl{upside-down} et je ne
sais pas encore comment régler ce petit détail.
Tous les flags doivent être à zéro.
\subsection{Utilitaires}
Commençons par quelques petits trucs pour nous faciliter la vie
dans des domaines annexes,
tels que l'interprétation d'arguments dans la ligne de commande ou un
fichier de configuration.
\begin{lstlisting}
int parse_WxH(char *str, int *pw, int *ph)
int parse_double(char *str, double *dptr)
\end{lstlisting}
La fonction \texttt{int format\_from\_extension(char *fname)} examine un
2 years ago
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