forked from tTh/FloatImg
reworking the yuser manual
This commit is contained in:
parent
e761120787
commit
249a99854a
@ -20,6 +20,11 @@
|
|||||||
\usepackage{xspace}
|
\usepackage{xspace}
|
||||||
\usepackage[verbose]{layout}
|
\usepackage[verbose]{layout}
|
||||||
|
|
||||||
|
|
||||||
|
\setlength{\textheight}{640pt}
|
||||||
|
\setlength{\textwidth}{422pt}
|
||||||
|
\setlength{\marginparwidth}{10pt}
|
||||||
|
|
||||||
\makeindex
|
\makeindex
|
||||||
|
|
||||||
% ------ a few new commands
|
% ------ a few new commands
|
||||||
@ -45,7 +50,8 @@ 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.
|
composante, mais c'est loin d'être le cas général.
|
||||||
J'ai donc souhaité aller plus loin, et coder chaque canal de
|
J'ai donc souhaité aller plus loin, et coder chaque canal de
|
||||||
chaque pixel en virgule flottante sur 32bits, le type
|
chaque pixel en virgule flottante sur 32bits, le type
|
||||||
\texttt{float}\index{float} du langage C.
|
\texttt{float}\index{float} du langage C. Ce qui correspond
|
||||||
|
à la norme IEEE 754-1985.
|
||||||
|
|
||||||
\vspace{1em}
|
\vspace{1em}
|
||||||
|
|
||||||
@ -62,8 +68,11 @@ IRC de Freenode.
|
|||||||
\tableofcontents
|
\tableofcontents
|
||||||
\pagebreak
|
\pagebreak
|
||||||
|
|
||||||
|
\layout
|
||||||
|
\pagebreak
|
||||||
|
|
||||||
% -------------------------------------------------------------------
|
% -------------------------------------------------------------------
|
||||||
\section{Premier example}\index{example}\label{example}
|
\section{Premier exemple}\index{exemple}\label{exemple}
|
||||||
|
|
||||||
\textsc{FloatImg} a débuté sous la forme de quelques fonctions
|
\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
|
basiques en C, gérant la structure des données d'image en mémoire
|
||||||
@ -151,6 +160,7 @@ lesquels sont décrits en page \pageref{outils}.
|
|||||||
Vous devez, en dehors des outils classiques (bash, gcc, make\dots),
|
Vous devez, en dehors des outils classiques (bash, gcc, make\dots),
|
||||||
avoir quelques bibliothèques installées\footnote{Les \texttt{-dev}
|
avoir quelques bibliothèques installées\footnote{Les \texttt{-dev}
|
||||||
pour Debian et dérivées}~: libv4l2, libpnglite, libtiff, libnetpbm,
|
pour Debian et dérivées}~: libv4l2, libpnglite, libtiff, libnetpbm,
|
||||||
|
libz,
|
||||||
et probablement d'autres choses.
|
et probablement d'autres choses.
|
||||||
|
|
||||||
\vspace{1em}
|
\vspace{1em}
|
||||||
@ -185,14 +195,15 @@ faciliter un peu la chose. Il prend également en compte la copie
|
|||||||
des divers binaires du dossier \texttt{tools/} (cf. page \pageref{outils})
|
des divers binaires du dossier \texttt{tools/} (cf. page \pageref{outils})
|
||||||
dans le répertoire prévu à cet effet : \texttt{/usr/local/bin}.
|
dans le répertoire prévu à cet effet : \texttt{/usr/local/bin}.
|
||||||
|
|
||||||
% -------------------------------------------------------------------
|
% =================================================================
|
||||||
|
|
||||||
\section{Utilisation coté codeur}\label{codaz}
|
\section{Utilisation coté codeur}\label{codaz}
|
||||||
|
|
||||||
Classiquement, il y a un fichier \texttt{.h} à inclure dans chacun de code
|
Classiquement, il y a un fichier \texttt{.h} à inclure dans chacun
|
||||||
source,
|
de vos codes source,
|
||||||
\texttt{floatimg.h}, généralement logé dans \texttt{/usr/local/include}
|
\texttt{floatimg.h}, généralement logé dans \texttt{/usr/local/include}
|
||||||
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é-processur}
|
de constantes\footnote{À l'ancienne, via le pré-processeur}
|
||||||
et les prototypes des fonctions utilisables par vos logiciels.
|
et les prototypes des fonctions utilisables par vos logiciels.
|
||||||
\vspace{1em}
|
\vspace{1em}
|
||||||
|
|
||||||
@ -226,20 +237,25 @@ Les deux premiers champs sont \textsl{obvious}.
|
|||||||
Le troisième est le type d'image : pour le moment, il y en a trois
|
Le troisième est le type d'image : pour le moment, il y en a trois
|
||||||
qui sont définis\footnote{et plus ou moins bien gérés\dots} :
|
qui sont définis\footnote{et plus ou moins bien gérés\dots} :
|
||||||
gris, rgb et rgba\index{rgba}.
|
gris, rgb et rgba\index{rgba}.
|
||||||
|
Les constantes adéquates sont dans \texttt{floatimg.h}
|
||||||
|
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
#define FIMG_TYPE_GRAY 1
|
#define FIMG_TYPE_GRAY 1
|
||||||
#define FIMG_TYPE_RGB 3
|
#define FIMG_TYPE_RGB 3
|
||||||
#define FIMG_TYPE_RGBA 4
|
#define FIMG_TYPE_RGBA 4
|
||||||
|
#define FIMG_TYPE_RGBZ 99
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
Un peu plus loin, nous avons les pointeurs vers les
|
Un peu plus loin, nous avons les pointeurs vers les
|
||||||
différents \textsl{pixmaps} de l'image. En principe l'organisation
|
différents \textsl{pixmaps} de l'image. En principe l'organisation
|
||||||
interne de ces zones est improbable, puisque elle dérive
|
interne de ces zones est improbable, puisque elle dérive
|
||||||
d'idées approximatives.
|
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.
|
||||||
|
|
||||||
\vspace{1em}
|
\vspace{1em}
|
||||||
|
|
||||||
|
Mais revenons aux choses sérieuses\dots
|
||||||
Les deux champs suivants (fval et count) sont à la disposition du
|
Les deux champs suivants (fval et count) sont à la disposition du
|
||||||
\textsl{yuser}
|
\textsl{yuser}
|
||||||
qui peut jouer avec à loisir pour faire, par exemple, ce genre de
|
qui peut jouer avec à loisir pour faire, par exemple, ce genre de
|
||||||
@ -258,31 +274,62 @@ toutes les informations nécessaires pour exploiter au mieux la dynamique
|
|||||||
de notre image dans les étapes ultérieures, puisque la valeur
|
de notre image dans les étapes ultérieures, puisque la valeur
|
||||||
maximale théorique est égale à $fval * count$.
|
maximale théorique est égale à $fval * count$.
|
||||||
|
|
||||||
\vspace{1em}
|
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
|
||||||
|
pas être la même chose dans l'avenir.
|
||||||
|
|
||||||
\textsl{Il est vraiment dommage que ces deux données auxiliaires
|
% ----------------------------------
|
||||||
ne puisse être stockée dans les dumps d'image. \index{XXX}}
|
|
||||||
|
|
||||||
\subsection{lib/}\index{lib/}
|
\subsection{Les fondations}\index{lib/}
|
||||||
|
|
||||||
Première chose, la gestion dynamique de la mémoire occupées
|
La première chose à voir est la gestion dynamique de la mémoire occupée
|
||||||
par tous ces pixels flottants est faite par ces deux fonctions~:
|
par tous ces pixels flottants, ce est un sujet parois
|
||||||
|
délicat\footnote{GC}.
|
||||||
|
Elle est donc faite, à la base, par ces deux fonctions~:
|
||||||
|
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
int fimg_create(FloatImg *fimg, int w, int h, int type);
|
int fimg_create(FloatImg *fimg, int w, int h, int type);
|
||||||
int fimg_destroy(FloatImg *fimg);
|
int fimg_destroy(FloatImg *fimg);
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
Les types d'images actuellement gérés sont les trois grands
|
L'appelant doit lui-même gérer le descripteur d'image (une structure
|
||||||
classiques : gray, rgb et rgba. Les constantes adéquates sont
|
C décrite plus haur) en le considérant comme un type semi-opaque dont
|
||||||
dans \texttt{floatimg.h} et expliquées quelques lignes plus haut.
|
la forme peut varier. Certains membres de cette structure sont
|
||||||
Les codes d'erreur sont disparates
|
documentés dans ce document, et les autres sont dangereux à
|
||||||
et non documentés.
|
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.
|
||||||
|
|
||||||
\vspace{1em}
|
\vspace{1em}
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
\begin{verbatim}
|
||||||
|
int fimg_dump_to_file(FloatImg *fimg, char *fname, int notused);
|
||||||
|
int fimg_load_from_dump(char *fname, FloatImg *where);
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
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. Mias comment peut-on connaitre ces valeurs ?
|
||||||
|
|
||||||
|
\begin{verbatim}
|
||||||
|
int fimg_fileinfos(char *fname, int *datas);
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
% _________
|
||||||
|
|
||||||
|
\subsection{Dessiner}
|
||||||
|
|
||||||
Bon, vous avez une image latente, et vous souhaitez dessiner dessus
|
Bon, vous avez une image latente, et vous souhaitez dessiner dessus
|
||||||
(ou dedans ?) avec vos encres flottantes ?
|
(ou dedans ?) avec vos encres flottantes ?
|
||||||
Il y a une fonction pour ça.
|
Il y a des fonctions pour ça, par exemple~:
|
||||||
|
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
int fimg_plot_rgb (FloatImg *head, int x, int y,
|
int fimg_plot_rgb (FloatImg *head, int x, int y,
|
||||||
@ -292,11 +339,14 @@ int fimg_plot_rgb (FloatImg *head, int x, int y,
|
|||||||
Les paramètres sont explicites, mais leur validité doit être
|
Les paramètres sont explicites, mais leur validité doit être
|
||||||
sévèrement controlée par l'appelant. Il y a une fonction
|
sévèrement controlée par l'appelant. Il y a une fonction
|
||||||
soeur, \texttt{fimg\_add\_rgb}\index{fimg\_add\_rgb},
|
soeur, \texttt{fimg\_add\_rgb}\index{fimg\_add\_rgb},
|
||||||
qui ajoute du rgb à un pixel, laquelle a d'ailleurs été
|
qui ajoute du rgb à un pixel, laquelle fonction a d'ailleurs été
|
||||||
à la base de la seconde génération de la
|
à la base de la seconde génération de la
|
||||||
photographie\index{photographie} en cumul\index{cumul}.
|
photographie\index{photographie} en cumul\index{cumul}.
|
||||||
|
|
||||||
\subsubsection{Contraste}\index{contraste}
|
|
||||||
|
% ----------------------------------
|
||||||
|
|
||||||
|
\subsection{Contraste}\index{contraste}\label{contraste}
|
||||||
|
|
||||||
Certaines opérations d'ajustement du contraste d'une image
|
Certaines opérations d'ajustement du contraste d'une image
|
||||||
semblent cohérents avec la notion d'image flottante.
|
semblent cohérents avec la notion d'image flottante.
|
||||||
@ -325,6 +375,8 @@ maximale du capteur, et le second sert à compter le
|
|||||||
nombre de capture\footnote{Et c'est bien géré aussi
|
nombre de capture\footnote{Et c'est bien géré aussi
|
||||||
dans l'upscaling.} effectuées.
|
dans l'upscaling.} effectuées.
|
||||||
|
|
||||||
|
\vspace{1em}
|
||||||
|
|
||||||
La fonction
|
La fonction
|
||||||
\texttt{fimg\_normalize(FloatImg *fi, double maxima, int notused);}
|
\texttt{fimg\_normalize(FloatImg *fi, double maxima, int notused);}
|
||||||
tente de gérer ce cas d'utilisation. Son ajout au captureur d'images
|
tente de gérer ce cas d'utilisation. Son ajout au captureur d'images
|
||||||
@ -349,20 +401,70 @@ une égalisation\index{égalisation} par histogramme\index{histogramme}
|
|||||||
qui respecte, dans toute sa futilité, le concept\index{concept}
|
qui respecte, dans toute sa futilité, le concept\index{concept}
|
||||||
de pixel flottant.
|
de pixel flottant.
|
||||||
|
|
||||||
\subsection{funcs/}\index{funcs/}\label{funcs}
|
% ----------------------------------
|
||||||
|
|
||||||
Une bonne partie de ces fonctions est indéterministe. Ce qui
|
\subsection{Exportation}\index{export}\label{export}
|
||||||
veut dire, en langage de tous les soirs, que ça risque de ne
|
|
||||||
pas être la même chose dans l'avenir.
|
|
||||||
|
|
||||||
\vspace{1em}
|
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.
|
||||||
|
|
||||||
On y trouve pêle-mêle de l'import/export de fichiers, de l'analyse
|
\subsubsection{Vers PNM}\index{PNM}
|
||||||
de chaines de caractères, du tracé de choses bizarres\dots
|
|
||||||
Plein de trucs qu'il faudra bien expliquer un jour\footnote{Mais
|
|
||||||
il fait trop froid dans le dd2\index{dd2}}.
|
|
||||||
|
|
||||||
\subsection{Exemple de fonction}\index{example}
|
Nous avons ici 16 bits par composante, mais au prix
|
||||||
|
d'une taille énorme sur les fichiers. D'autre coté,
|
||||||
|
l'utilisation du codage \textsc{ascii}\index{ascii}
|
||||||
|
(alors qu'on peut mettre du binaire) y est pour quelque chose.
|
||||||
|
|
||||||
|
\begin{verbatim}
|
||||||
|
int fimg_save_as_pnm(FloatImg *head, char *fname, int flags);
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Les autres bits ne sont pas utilisés et doivent être à zéro.
|
||||||
|
|
||||||
|
\subsubsection{Vers PNG}\index{PNG}
|
||||||
|
|
||||||
|
Actuellement, uniquement en 8 bits par composante, mais bonne
|
||||||
|
compression.
|
||||||
|
|
||||||
|
\subsubsection{Vers TIFF}\index{TIFF}
|
||||||
|
|
||||||
|
To be done\index{XXX}
|
||||||
|
|
||||||
|
\subsection{Utilitaires}
|
||||||
|
|
||||||
|
\begin{verbatim}
|
||||||
|
int parse_WxH(char *str, int *pw, int *ph)
|
||||||
|
int parse_double(char *str, double *dptr)
|
||||||
|
int format_from_extension(char *fname)
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
To be continued\index{XXX}
|
||||||
|
|
||||||
|
|
||||||
|
\subsection{Effets}\index{sfx}
|
||||||
|
|
||||||
|
To be done\index{XXX}
|
||||||
|
|
||||||
|
|
||||||
|
% ----------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
\subsection{Filtrages}
|
||||||
|
|
||||||
|
To be done\index{XXX}
|
||||||
|
|
||||||
|
|
||||||
|
% ----------------------------------
|
||||||
|
|
||||||
|
\subsection{Exemple de fonction}\index{exemple}
|
||||||
|
|
||||||
Nous allons écrire une fonction qui va faire quelque chose
|
Nous allons écrire une fonction qui va faire quelque chose
|
||||||
à partir d'une image source et d'une valeur, et écrire le
|
à partir d'une image source et d'une valeur, et écrire le
|
||||||
@ -416,23 +518,32 @@ Ces machins ont en commun deux options bien pratiques~:
|
|||||||
et \texttt{-v} qui augmente la puissance de bavardage.
|
et \texttt{-v} qui augmente la puissance de bavardage.
|
||||||
Dans un avenir incertain, il existera des pages de man\index{man}.
|
Dans un avenir incertain, il existera des pages de man\index{man}.
|
||||||
|
|
||||||
|
% ---------------------
|
||||||
|
|
||||||
\subsection{mkfimg}\index{mkfimg}\label{mkfimg}
|
\subsection{mkfimg}\index{mkfimg}\label{mkfimg}
|
||||||
|
|
||||||
Création d'un fichier contenant une image de « teinte » constante
|
Création d'un fichier contenant une image de « teinte » constante
|
||||||
(ou pas).
|
(ou pas).
|
||||||
Cette notion de teinte est assez inconsistante pour le moment,
|
Cette notion de teinte est assez inconsistante pour le moment,
|
||||||
|
mais ça n'est pas si grave que ça.
|
||||||
|
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
tth@debian:~/Devel/FloatImg/tools$ ./mkfimg -v -h
|
tth@debian:~/Devel/FloatImg/tools$ ./mkfimg -h
|
||||||
Usage: mkfimg [options] quux.fimg width height
|
Usage: mkfimg [options] quux.fimg width height
|
||||||
-k N.N give a float parameter
|
-k N.N give a float parameter
|
||||||
-t bla howto make the pic
|
-t bla howto make the pic
|
||||||
black, drand48...
|
black, drand48...
|
||||||
-v increase verbosity
|
-v increase verbosity
|
||||||
*** FloatImg library, alpha v73 (Sep 28 2019, 23:34:29)
|
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item black / gray / grey
|
||||||
|
\item drand48
|
||||||
|
\item hdeg / vdeg
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
|
||||||
|
% ---------------------
|
||||||
|
|
||||||
\subsection{png2fimg}\index{png2fimg}\label{png2fimg}
|
\subsection{png2fimg}\index{png2fimg}\label{png2fimg}
|
||||||
|
|
||||||
@ -465,15 +576,13 @@ Puis nous rajouterons\footnote{Les patchs sont les bienvenus}
|
|||||||
le calcul de la variance\index{variance}. Les compétences
|
le calcul de la variance\index{variance}. Les compétences
|
||||||
de \texttt{schmod777} sont attendues au dd2\index{dd2}.
|
de \texttt{schmod777} sont attendues au dd2\index{dd2}.
|
||||||
|
|
||||||
|
% ---------------------
|
||||||
|
|
||||||
\subsection{fimgfx}\index{fimgfx}\label{fimgfx}
|
\subsection{fimgfx}\index{fimgfx}\label{fimgfx}
|
||||||
|
|
||||||
\textit{En cours de création\index{XXX}.
|
Ce programme, \textit{en cours de création\index{XXX}}, applique
|
||||||
Attention, je vais expérimenter un parsing un peu étrange
|
un effet spécial à une image.
|
||||||
sur les arguments de la ligne de commande. coredump expected.}
|
À l'heure actuelle\footnote{janvier 2019, vers 13:37}, nous avons
|
||||||
|
|
||||||
\vspace{1em}
|
|
||||||
|
|
||||||
À l'heure actuelle\footnote{décembre 2019, vers 13:37}, nous avons
|
|
||||||
déja quelques ajustements basiques de contraste, qui ne tiennent
|
déja quelques ajustements basiques de contraste, qui ne tiennent
|
||||||
pas vraiment compte du contenu de l'image.
|
pas vraiment compte du contenu de l'image.
|
||||||
|
|
||||||
@ -483,6 +592,17 @@ tth@daubian:~/Devel/FloatImg/tools$ ./fimgfx -v -h
|
|||||||
cos01 cos010 pow2 sqrt
|
cos01 cos010 pow2 sqrt
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
|
Certaines de ces opérations ont besoin d'un paramètre flottant.
|
||||||
|
Celui-ci peut être fixé avec l'option \texttt{-k}.
|
||||||
|
Une liste détaillée des opérations possibles
|
||||||
|
sera lisible avec le sélecteur \texttt{-L}.
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item Ajustements de contraste : cos01 cos010 pow2 sqrt
|
||||||
|
\item Distorsions chromatiques :
|
||||||
|
\item Déformations géométriques :
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
\subsection{fimgops}\index{fimgops}\label{fimgops}
|
\subsection{fimgops}\index{fimgops}\label{fimgops}
|
||||||
|
|
||||||
Quelques opérations diverses entre deux images, qui doivent être
|
Quelques opérations diverses entre deux images, qui doivent être
|
||||||
@ -516,7 +636,8 @@ La véracité mathématique n'est pas garantie.
|
|||||||
|
|
||||||
Quelques petits proggies pour exporter notre format\index{.fimg} secret
|
Quelques petits proggies pour exporter notre format\index{.fimg} secret
|
||||||
vers des choses plus directement utilisables. À condition que le
|
vers des choses plus directement utilisables. À condition que le
|
||||||
code soit écrit et documenté. Peut-être en page \pageref{funcs}\dots
|
code soit écrit et documenté.
|
||||||
|
|
||||||
\vspace{1em}
|
\vspace{1em}
|
||||||
|
|
||||||
D'un autre coté, écrire un greffon d'import/export pour
|
D'un autre coté, écrire un greffon d'import/export pour
|
||||||
@ -550,7 +671,7 @@ Il reste plein de choses à faire pour que ce soit vraiment utilisable.
|
|||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
% -------------------------------------------------------------------
|
% -------------------------------------------------------------------
|
||||||
\section{Exemples pour yusers}\index{example}
|
\section{Exemples pour yusers}\index{exemple}
|
||||||
|
|
||||||
Nous allons \textsl{essayer d'improviser} un exemple presque réel,
|
Nous allons \textsl{essayer d'improviser} un exemple presque réel,
|
||||||
avec un peu de rache\index{rache} dedans. Ce qui est autorisé dans
|
avec un peu de rache\index{rache} dedans. Ce qui est autorisé dans
|
||||||
|
Loading…
Reference in New Issue
Block a user