\documentclass{article}

\renewcommand{\familydefault}{\sfdefault} % police en "sans-serif"

\usepackage[T1]{fontenc} % encodage
\usepackage[french]{babel} % langue
\usepackage[hidelinks]{hyperref} % liens cliquable dans la table des matières
\usepackage{geometry} % change les dimensions de la page
\usepackage{graphicx} % images
\usepackage{subcaption} % images côtes à côtes

\geometry{ % définition taille pages
    a4paper,
    left=20mm,
    top=20mm
}

\usepackage{minted} % intégration code
\usemintedstyle{emacs}

\title{Compression d’images avec quadtrees}
\author{\href{mailto:anri.kennel@etud.univ-paris8.fr}{Anri Kennel}\thanks{Numéro d'étudiant : 20010664}\, (L2-X)\\Algorithmique et structures de données 2 $\cdot$ Université Paris 8}
\date{Année universitaire 2021-2022}

\begin{document}
    \maketitle
    \tableofcontents
    \clearpage

    \section[Présentation]{Brève présentation}
    J'ai réalisé le projet seul. Mon projet est de compresser une image avec une structure \textit{quadtree}.

    \begin{figure}[!ht]
        \centering
        \begin{subfigure}{.49\textwidth}
            \href{https://pxhere.com/en/photo/1409995}{\includegraphics[height=0.2\textheight]{images/not-compressed.png}}
            \caption{Non compressé (3.6Mo)}
        \end{subfigure}
        \begin{subfigure}{.49\textwidth}
            \centering
            \includegraphics[height=0.2\textheight]{images/compressed-7.png}
            \caption{Compressé / 7 (56ko)}
        \end{subfigure}
    \end{figure}

    \subsection{Objectifs}
    \begin{itemize}
        \item Compiler facilement le programme
        \item Réussir à compresser l'image
        \item Code clair et commenté
        \item Ne pas utiliser OpenCV
    \end{itemize}

    \section[Explications]{Explications de la réalisation}
    \subsection*{Makefile}
    La compilation est simple avec le \texttt{Makefile}. Il est possible de faire \texttt{make} pour compiler avec la SDL et \texttt{O3}. Il est aussi possible de faire \texttt{make dev} et ainsi compiler avec la SDL et les flags de développement :
    \begin{itemize}
        \item \texttt{Wall} et \texttt{Wextra} pour les warnings
        \item \texttt{Wshadow} pour le nom des variables
        \item \texttt{pedantic} pour la compilation
        \item \texttt{g} pour Valgrind
        \item \texttt{Wold-style-cast} et \texttt{Wsign-conversion} pour bien utiliser les casts
    \end{itemize}

    \subsection*{Libraries}
    J'ai utilisé les librairies
    \begin{itemize}
        \item \texttt{fstream} pour vérifier empêcher d'écraser une image existante
        \item \texttt{SDL\_image} pour utiliser \texttt{SDL\_Surface} de la \texttt{SDL}
        \item \texttt{array} pour stocker et donner aux méthodes les 4 morceaux qui compose l'image quand divisé
    \end{itemize}

    \subsection*{Classe}
    Ma classe \texttt{QuadTree} est déclarée dans \texttt{includes/quadtree.hpp} et définie
    dans \texttt{src/quadtree.cpp}, elle contient :
    \begin{itemize}
        \item Une variable qui stocke la qualité de l'image (\texttt{niveau})
        \item Une variable qui stocke la couleur majoritaire dans l'image (\texttt{couleur})
        \item Une variable \texttt{std::pair} qui stocke les dimensions de l'image (\texttt{dimensions})
        \item 4 variables représentant les enfants du noeud (\texttt{nord\_ouest}, \texttt{nord\_est}, \texttt{sud\_ouest}, \texttt{sud\_est})
        \item Une variable qui définie si le noeud est final ou non (\texttt{final})
        \item Une variable qui stocke le format utilisé par l'image (\texttt{format})
        \newpage
        \item Une méthode qui permet de calculer la couleur majoraitaire dans l'image (\texttt{calculeCouleur})
        \item Une méthode qui permet savoir lors de l'exportation si elle est finie (\texttt{verificationEgalitee})
        \item Une méthode qui permet de séparer en 4 l'image (\texttt{coupeEnQuatre})
        \item Une méthode qui permet de rassembler 4 morceaux d'image en une seule (\texttt{colleQuatreImages})
        \item Une méthode qui permet d'exporter la surface avec un certain niveau de compression (\texttt{image})
    \end{itemize}
    \vspace{10pt}

    Cette classe permet de diviser récursivement l'image en 4 parts
    et d'en extraire la couleur qui y est majoritaire dans chaque morceaux d'image.

    \subsubsection*{Constructeur}
    Dans le constructeur de ma classe, j'initialise \texttt{format} à \texttt{SDL\_PIXELFORMAT\_RGB888}
    au lieu du format de mon image (\texttt{image->format}) car il y a un \textit{bug} dans
    la méthode \texttt{colleQuatreImages} qui préserve mal les couleurs. \texttt{SDL\_PIXELFORMAT\_RGB888} rend donc l'image en noir et blanc.

    \subsubsection*{Surfaces}
    Je \href{https://wiki.libsdl.org/SDL_LockSurface}{verrouille et déverrouille ma surface} à chaque utilisation même si c'est probablement inutile mais ça m'évite de vérifier si \texttt{SDL\_MUSTLOCK} est égale à 0 à chaque fois.
    \begin{center}\begin{minipage}{0.5\textwidth}
        \begin{minted}[linenos]{cpp}
if(SDL_LockSurface(surface) == 0) {
    /* ... */

    SDL_UnlockSurface(surface);
}
        \end{minted}
    \end{minipage}\end{center}

    \subsubsection*{Format des surfaces}
    Toutes les surfaces que je crées ont le même format, ça m'évite d'utiliser les masks \href{https://wiki.libsdl.org/SDL_CreateRGBSurface#code_examples}{en fonction de} l'endian.

    \subsubsection*{\texttt{calculeCouleur}}
    Pour calculer la couleur dans \texttt{calculeCouleur} je fait une moyenne \texttt{RGBA} de tout les pixels de la surface.

    \subsubsection*{\texttt{verificationEgalitee}}
    Dans \texttt{verificationEgalitee} je regarde si tout les pixels \texttt{RGB} de la surface sont identiques (j'ignore le canal alpha).

    \subsubsection*{\texttt{coupeEnQuatre}}
    Quand je coupe en quatre mon image dans \texttt{coupeEnQuatre}, je commence par définir les coordonnées de mes 4 morceaux (ici \texttt{s} est la surface mère) :
    \begin{center}\begin{minipage}{0.7\textwidth}
        \begin{minted}[linenos]{cpp}
std::array<std::array<int, 4>, 4> coordonnes_quadrants;
coordonnes_quadrants[0] = {0       , 0       , s->w / 2, s->h / 2};
coordonnes_quadrants[1] = {0       , s->h / 2, s->w / 2, s->h    };
coordonnes_quadrants[2] = {s->w / 2, 0       , s->w    , s->h / 2};
coordonnes_quadrants[3] = {s->w / 2, s->h / 2, s->w    , s->h    };
        \end{minted}
    \end{minipage}\end{center}
    Puis je créer tour à tour mes 4 surfaces qui je rajoute dans une \texttt{std::array}. Dans ses surfaces je vais
    recopier pixel-par-pixel de la grande surface vers la plus petite (ici \texttt{x}/\texttt{y} varient respectivement en fonction de la largeur/longueur du morceau d'image):
    \begin{center}\begin{minipage}{1\textwidth}
        \begin{minted}[linenos]{cpp}
int x1 = x * nouvelle_image->format->BytesPerPixel,
    y1 = y * nouvelle_image->pitch,
    x2 = (coordonnes_quadrants[i][0] + x) * s->format->BytesPerPixel,
    y2 = (coordonnes_quadrants[i][1] + y) * s->pitch;
*reinterpret_cast<Uint32 *>(static_cast<Uint8 *>(nouvelle_image->pixels) + y1 + x1) =
*reinterpret_cast<Uint32 *>(static_cast<Uint8 *>(s->pixels) + y2 + x2);
        \end{minted}
    \end{minipage}\end{center}

    \subsubsection*{\texttt{colleQuatreImages}}
    Quand je rassemble mon image dans \texttt{colleQuatreImages}, je commence par récupérer les dimensions de
    mon image originale en regardant des morceaux en diagonale (sur l'image je compare soit 1 et 4, soit 2 et 3).
    \begin{figure}[!ht]
        \centering
        \includegraphics[height=0.2\textheight]{images/image_coupe_en_4.png}
    \end{figure}
    \\Si les dimensions des 2 morceaux sont différents alors je prend la plus grande dimensions \texttt{- 1}.

    Une fois les dimensions récupérer, je copie pixel-par-pixel les morceaux sur ma grande surface, comme dans la méthode \texttt{coupeEnQuatre}. Je libère les morceaux de la mémoire une fois rassemblé.

    \section{Ajouts}
    \begin{itemize}
        \item Possibilité de préciser le niveau de compresser (0 très compressé et 10 pas compressé)
        \item Utilisation de la SDL pour gérer l'image
    \end{itemize}

    \subsection{Piste d'amélioration}
    Je n'ai malheureusement pas réussi à garder la couleur lorsque je compresse l'image, j'aimerais réussir à rendre ça fonctionnelle.

\end{document}
