diff --git a/Matrix.c b/Matrix.c
index 820cd2595bf12da799fea159c584f7c40ea5a09c..51200384fcbaed64b45969a202aeafa5a3db3f8d 100644
--- a/Matrix.c
+++ b/Matrix.c
@@ -55,7 +55,7 @@ error_code matrix_destroy(matrix *mat){
     for (int i = 0; i < mat->col; i++){
         for(int j=0;j<mat->lin;j+=1)
         {
-            mat->data[i][j] = NULL;
+            mat->data[i][j] = 0;
         }
         free(mat->data[i]);
     }
diff --git a/main.c b/main.c
index dad4f0b1cca1115d4ed61672d7b033ed5a764ad2..30336b09916f81cfd8063d96ab2f07bcebcf919d 100644
--- a/main.c
+++ b/main.c
@@ -16,31 +16,27 @@ int main()
     printf("Depth : %u\n",val);
 
 
-    // matrix_print(p->pixels);
     node* tree = quadtree_tree_create(val);
-    
-    // matrix_print(p->pixels);
     quadtree_matrix2tree(&p->pixels,tree);
 
 
     pgm* pp = malloc(1 * sizeof(pgm));
     pp->max = p->max;
     matrix_alloc(&pp->pixels,p->pixels.lin,p->pixels.col);
-    // matrix mat;
-    // matrix_alloc(&mat,p->pixels.lin,p->pixels.col);
-    // matrix_init(&mat);
 
-    quadtree_central_symetry(tree);
+
+
+
+
+    quadtree_moyenne(tree);
+    quadtree_compress(tree,2000);
+
+    // quadtree_print(tree,1,"|");
     quadtree_tree2matrix(tree,&pp->pixels);
-    // // matrix_print(mat);
 
-    // // quadtree_print(tree,1,"|");
 
-    // pgm *pp = malloc(1 * sizeof(pgm));
-    // pp->max = 256;
-    // pp->pixels = mat;
-    pgm_write_from_file(pp,"Test.pgm");
 
+    pgm_write_from_file(pp,"Test.pgm");
     matrix_destroy(&p->pixels);
     matrix_destroy(&pp->pixels);
     quadtree_tree_destroy(&tree);
diff --git a/pgm_io.c b/pgm_io.c
index 7d67a0e0c81a218ff157e765393b0ae1cc4ce6c7..887b7b7cd4bebe9c99226857736e5c4413820c31 100644
--- a/pgm_io.c
+++ b/pgm_io.c
@@ -14,7 +14,7 @@
  * @param filename = the file path of the image to read
  * @return pgm_error
  */
-pgm_error pgm_read_from_file(pgm *p,const char* const filename)
+pgm_error pgm_read_from_file(pgm *p,const char* filename)
 {
     int sizex = 0;
     int sizey = 0;
@@ -56,7 +56,7 @@ pgm_error pgm_read_from_file(pgm *p,const char* const filename)
  * @param filename = the file path of the image to write
  * @return pgm_error
  */
-pgm_error pgm_write_from_file(pgm *p,char *filename)
+pgm_error pgm_write_from_file(pgm *p,const char *filename)
 {
     if (p->pixels.data == NULL)
     {
@@ -127,7 +127,7 @@ pgm_error pgm_duplicate(char *filename,char *newfile)
  * @param gray_scale = the gray scale max in file returned by pointed value
  * @return pgm_error
  */
-pgm_error pgm_read_header(const char* const filename,int *sizex,int *sizey,int *gray_scale)
+pgm_error pgm_read_header(const char* filename,int *sizex,int *sizey,int *gray_scale)
 {
     FILE *f;
     f = fopen(filename,"r");
diff --git a/pgm_io.h b/pgm_io.h
index 7b99628e593cbea01360f650c57fde3176fdbf7a..08370db557bc8696a852922e9b7125c28f7391c6 100644
--- a/pgm_io.h
+++ b/pgm_io.h
@@ -18,9 +18,9 @@ int32_t max;
 matrix pixels;
 } pgm;
 
-pgm_error pgm_read_from_file(pgm *p,const char* const filename);
-pgm_error pgm_write_from_file(pgm *p,char *filename);
+pgm_error pgm_read_from_file(pgm *p,const char* filename);
+pgm_error pgm_write_from_file(pgm *p,const char *filename);
 pgm_error pgm_duplicate(char *filename,char *newfile);
-pgm_error pgm_read_header(const char* const filename,int *sizex,int *sizey,int *gray_scale);
+pgm_error pgm_read_header(const char* filename,int *sizex,int *sizey,int *gray_scale);
 
 #endif
\ No newline at end of file
diff --git a/quadtree.c b/quadtree.c
index 2246883624df0d8754b294ba509f979fb3af49a7..013058d619c6902acba0b8d1431ad4bc8ff77393 100644
--- a/quadtree.c
+++ b/quadtree.c
@@ -1,15 +1,33 @@
 #include "quadtree.h"
 
+/**
+ * @name quadtree_is_leaf
+ * @brief  Check if this node is a leaf
+ * @param  nd ptr on node
+ * @return true if it is a leaf
+ */
 bool quadtree_is_leaf(node *nd)
 {
     return (NULL == nd->child[0]);
 }
 
+/**
+ * @name quadtree_get_depth_from_image_size
+ * @brief  Get depth from size of image (square only)
+ * @param  sizex value of border
+ * @return value of depth
+ */
 int32_t quadtree_get_depth_from_image_size(int32_t sizex)
 {
     return (int32_t)log2(sizex);
 }
 
+/**
+ * @name quadtree_tree_create
+ * @brief  Create quadtree from depth
+ * @param  depth value of depth for the quadtree
+ * @return pointer on node for quadtree
+ */
 node *quadtree_tree_create(int32_t depth)
 {
     node *a = calloc(1, sizeof(node));
@@ -24,11 +42,25 @@ node *quadtree_tree_create(int32_t depth)
     return a;
 }
 
+/**
+ * @name quadtree_max
+ * @brief  Compare two value
+ * @param  x first value
+ * @param  y second value
+ * @return the greatest value betwen x and y
+ */
 int32_t quadtree_max(int32_t x, int32_t y)
 {
     return (x >= y ? x : y);
 }
 
+/**
+ * @name quadtree_array_max
+ * @brief  Get max value in array
+ * @param  size size of array
+ * @param  tab the array
+ * @return the bigest value oin the array
+ */
 int32_t quadtree_array_max(int32_t size, int32_t tab[size])
 {
     int32_t m = INT_MIN;
@@ -39,10 +71,16 @@ int32_t quadtree_array_max(int32_t size, int32_t tab[size])
     return m;
 }
 
-int32_t quadtree_depth(node *a)
+/**
+ * @name quadtree_depth
+ * @brief  Get the depth of quadtree
+ * @param  a pointer on node
+ * @return the value of depth quadtree
+ */
+int32_t quadtree_depth(node *tree)
 {
     int32_t p[CHILDREN] = {0};
-    if (quadtree_is_leaf(a))
+    if (quadtree_is_leaf(tree))
     {
         return 0;
     }
@@ -50,33 +88,47 @@ int32_t quadtree_depth(node *a)
     {
         for (int32_t i = 0; i < CHILDREN; i++)
         {
-            p[i] = 1 + quadtree_depth(a->child[i]);
+            p[i] = 1 + quadtree_depth(tree->child[i]);
         }
         return quadtree_array_max(CHILDREN, p);
     }
 }
 
-void quadtree_print(node *arbre, int32_t decal, char *sep)
+/**
+ * @name quadtree_print
+ * @brief  Print all value in quadtree
+ * @param  tree pointer on node
+ * @param  decal value of additional char
+ * @param  sep char to use for graphic display
+ * @return void
+ */
+void quadtree_print(node *tree, int32_t decal, char *sep)
 {
-    if (NULL != arbre)
+    if (NULL != tree)
     {
         for (int32_t i = 0; i < decal; i++)
         {
             printf("%s", sep);
         }
-        printf("%d\n", (uint32_t)arbre->data);
+        printf("%lf\n", tree->average);
         decal++;
-        if (!quadtree_is_leaf(arbre))
+        if (!quadtree_is_leaf(tree))
         {
             for (int32_t i = 0; i < CHILDREN; i++)
             {
-                quadtree_print(arbre->child[i], decal, sep);
+                quadtree_print(tree->child[i], decal, sep);
             }
         }
     }
 }
 
-// Fonction utile pour les symétries
+/**
+ * @name quadtree_swap
+ * @brief  Swap two pointer
+ * @param  ptr1 pointer of pointer on void
+ * @param  ptr2 pointer of pointer on void
+ * @return void
+ */
 void quadtree_swap(void **ptr1, void **ptr2)
 {
     void *tmp = *ptr1;
@@ -84,64 +136,79 @@ void quadtree_swap(void **ptr1, void **ptr2)
     *ptr2 = tmp;
 }
 
-void quadtree_sum(node *arbre)
+/**
+ * @name quadtree_sum
+ * @brief  Sum of all value in tree
+ * @param  tree pointer on node
+ * @return void
+ */
+void quadtree_sum(node *tree)
 {
-    if (!quadtree_is_leaf(arbre))
+    if (!quadtree_is_leaf(tree))
     {
         for (int32_t i = 0; i < CHILDREN; i++)
         {
-            quadtree_sum(arbre->child[i]);
+            quadtree_sum(tree->child[i]);
         }
         for (int32_t i = 0; i < CHILDREN; i++)
         {
-            arbre->data += arbre->child[i]->data;
+            tree->average += tree->child[i]->average;
         }
     }
 }
 
-node *quadtree_position(int32_t li, int32_t col, node *a, int32_t d)
+/**
+ * @name quadtree_position
+ * @brief  Get node from position in quadtree
+ * @param  li line number
+ * @param  col colone number
+ * @param  tree pointer on node
+ * @param  depth depth value
+ * @return pointer on node
+ */
+node *quadtree_position(int32_t li, int32_t col, node *tree, int32_t depth)
 {
-    node *crt = a;
+    node *crt = tree;
     do
     {
-        int32_t ligne = (li >> d) & 1;          // Permet de sélectionne le bit à considérer en fonction de la profondeur; Exemple: 10 >> 1 = 1
-        int32_t colonne = (col >> d) & 1;       //Exemple: 10 >> 1 = 1;
-        int32_t index = (ligne << 1) | colonne; // Exemple: 1<<1 = 10 | 1(col) = 11=>3
+        int32_t ligne = (li >> depth) & 1;
+        int32_t colonne = (col >> depth) & 1;
+        int32_t index = (ligne << 1) | colonne;
 
         crt = crt->child[index];
-        d--;
+        depth--;
     } while (!quadtree_is_leaf(crt));
     return crt;
 }
 
-double quadtree_position_value(int32_t li, int32_t col, node *a, int32_t d)
-{
-    node *crt = a;
-    do
-    {
-        int32_t ligne = (li >> d) & 1;          // Permet de sélectionne le bit à considérer en fonction de la profondeur; Exemple: 10 >> 1 = 1
-        int32_t colonne = (col >> d) & 1;       //Exemple: 10 >> 1 = 1;
-        int32_t index = (ligne << 1) | colonne; // Exemple: 1<<1 = 10 | 1(col) = 11=>3
-
-        crt = crt->child[index];
-        d--;
-    } while (!quadtree_is_leaf(crt));
-    return crt->data;
-}
-
-void quadtree_matrix2tree(matrix *mat, node *arbre)
+/**
+ * @name quadtree_matrix2tree
+ * @brief  Convert matrix to quadtree
+ * @param  mat pointer on matrix
+ * @param  tree pointer on node
+ * @return void
+ */
+void quadtree_matrix2tree(matrix *mat, node *tree)
 {
-    int32_t d = quadtree_depth(arbre) - 1;
+    int32_t d = quadtree_depth(tree) - 1;
     for (int32_t li = 0; li < mat->lin; li++)
     {
         for (int32_t co = 0; co < mat->col; co++)
         {
-            node *crt = quadtree_position(li, co, arbre, d);
-            crt->data = mat->data[li][co];
+            node *crt = quadtree_position(li, co, tree, d);
+            crt->average = mat->data[li][co];
+            crt->average_2 = mat->data[li][co] * mat->data[li][co];
         }
     }
 }
 
+/**
+ * @name quadtree_tree2matrix
+ * @brief  Convert quadtree to matrix
+ * @param  tree pointer on node
+ * @param  mat pointer on matrix
+ * @return void
+ */
 void quadtree_tree2matrix(node *tree, matrix *mat)
 {
     int32_t d = quadtree_depth(tree) - 1;
@@ -149,12 +216,17 @@ void quadtree_tree2matrix(node *tree, matrix *mat)
     {
         for (int32_t co = 0; co < mat->col; co++)
         {
-            mat->data[li][co] = quadtree_position_value(li, co, tree, d);
+            mat->data[li][co] = quadtree_position(li, co, tree, d)->average;
         }
     }
 }
 
-// OK
+/**
+ * @name quadtree_horizontal_symetry
+ * @brief  Apply rotate on branch in quadtree for horizontal symmetry
+ * @param  tree pointer on node
+ * @return void
+ */
 void quadtree_horizontal_symetry(node *tree)
 {
     if (NULL != tree)
@@ -163,12 +235,17 @@ void quadtree_horizontal_symetry(node *tree)
         {
             quadtree_horizontal_symetry(tree->child[i]);
         }
-        quadtree_swap((void**)&tree->child[0], (void**)&tree->child[1]);
-        quadtree_swap((void**)&tree->child[2], (void**)&tree->child[3]);
+        quadtree_swap((void **)&tree->child[0], (void **)&tree->child[1]);
+        quadtree_swap((void **)&tree->child[2], (void **)&tree->child[3]);
     }
 }
 
-// OK
+/**
+ * @name quadtree_vertical_symetry
+ * @brief  Apply rotate on branch in quadtree for vertical symmetry
+ * @param  tree pointer on node
+ * @return void
+ */
 void quadtree_vertical_symetry(node *tree)
 {
     if (NULL != tree)
@@ -177,17 +254,29 @@ void quadtree_vertical_symetry(node *tree)
         {
             quadtree_vertical_symetry(tree->child[i]);
         }
-        quadtree_swap((void**)&tree->child[0], (void**)&tree->child[2]);
-        quadtree_swap((void**)&tree->child[1], (void**)&tree->child[3]);
+        quadtree_swap((void **)&tree->child[0], (void **)&tree->child[2]);
+        quadtree_swap((void **)&tree->child[1], (void **)&tree->child[3]);
     }
 }
 
+/**
+ * @name quadtree_central_symetry
+ * @brief  Apply rotate on branch in quadtree for central symmetry
+ * @param  tree pointer on node
+ * @return void
+ */
 void quadtree_central_symetry(node *tree)
 {
     quadtree_vertical_symetry(tree);
     quadtree_horizontal_symetry(tree);
 }
 
+/**
+ * @name quadtree_tree_destroy
+ * @brief  Destroy all memory alloc from quadtree_create
+ * @param  tree pointer on pointer on node
+ * @return void
+ */
 void quadtree_tree_destroy(node **tree)
 {
     if (NULL != *tree)
@@ -204,4 +293,69 @@ void quadtree_tree_destroy(node **tree)
             free(*tree);
         }
     }
+}
+
+/**
+ * @name quadtree_moyenne
+ * @brief  Write moyenn of sub branch in node
+ * @param  tree pointer on node
+ * @return void
+ */
+void quadtree_moyenne(node *tree)
+{
+    if (!quadtree_is_leaf(tree))
+    {
+        for (uint32_t i = 0; i < CHILDREN; i += 1)
+        {
+            quadtree_moyenne(tree->child[i]);
+        }
+        tree->average = 0.0;
+        tree->average_2 = 0.0;
+        for (uint32_t i = 0; i < CHILDREN; i += 1)
+        {
+            tree->average += tree->child[i]->average;
+            tree->average_2 += tree->child[i]->average_2;
+        }
+        tree->average /= CHILDREN;
+        tree->average_2 /= CHILDREN;
+    }
+}
+
+/**
+ * @name quadtree_compress
+ * @brief  Compress data in quadtree
+ * @param  tree pointer on node
+ * @param  level compression ratio
+ * @return void
+ */
+void quadtree_compress(node *tree, uint32_t level)
+{
+    if (!quadtree_is_leaf(tree))
+    {
+        for (uint32_t i = 0; i < CHILDREN; i += 1)
+        {
+            quadtree_compress(tree->child[i], level);
+        }
+        bool last_branch = true;
+        for (uint32_t i = 0; i < CHILDREN; i += 1)
+        {
+            if (!quadtree_is_leaf(tree->child[i]))
+            {
+                last_branch = false;
+            }
+        }
+        if (last_branch)
+        {
+            double tmp_var = tree->average_2 - (tree->average * tree->average);
+            if (tmp_var <= level)
+            {
+                tree->average = (uint32_t)(tree->average);
+                for (uint32_t i = 0; i < CHILDREN; i += 1)
+                {
+                    free(tree->child[i]);
+                    tree->child[i] = NULL;
+                }
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/quadtree.h b/quadtree.h
index 22d3fa953c1049e1844da564d5797fbd88ca7bc5..78acb56390cc482762acc8fad28243b8dd58f8fa 100644
--- a/quadtree.h
+++ b/quadtree.h
@@ -10,7 +10,7 @@
 #define CHILDREN 4
 
 typedef struct _node {
-   double data;
+   double average;
    double average_2;
    struct _node* child[CHILDREN];
 } node;
@@ -49,4 +49,8 @@ void quadtree_horizontal_symetry(node *tree);
 
 void quadtree_vertical_symetry(node *tree);
 
-void quadtree_central_symetry(node *tree);
\ No newline at end of file
+void quadtree_central_symetry(node *tree);
+
+void quadtree_compress(node* tree,uint32_t level);
+
+void quadtree_moyenne(node* tree);
\ No newline at end of file