Skip to content
Snippets Groups Projects
Commit 07f44b6e authored by poulpe's avatar poulpe
Browse files

[Update] Fix compress + create_tree

parent 8276289a
No related branches found
No related tags found
No related merge requests found
...@@ -55,7 +55,7 @@ error_code matrix_destroy(matrix *mat){ ...@@ -55,7 +55,7 @@ error_code matrix_destroy(matrix *mat){
for (int i = 0; i < mat->col; i++){ for (int i = 0; i < mat->col; i++){
for(int j=0;j<mat->lin;j+=1) for(int j=0;j<mat->lin;j+=1)
{ {
mat->data[i][j] = NULL; mat->data[i][j] = 0;
} }
free(mat->data[i]); free(mat->data[i]);
} }
......
...@@ -16,31 +16,27 @@ int main() ...@@ -16,31 +16,27 @@ int main()
printf("Depth : %u\n",val); printf("Depth : %u\n",val);
// matrix_print(p->pixels);
node* tree = quadtree_tree_create(val); node* tree = quadtree_tree_create(val);
// matrix_print(p->pixels);
quadtree_matrix2tree(&p->pixels,tree); quadtree_matrix2tree(&p->pixels,tree);
pgm* pp = malloc(1 * sizeof(pgm)); pgm* pp = malloc(1 * sizeof(pgm));
pp->max = p->max; pp->max = p->max;
matrix_alloc(&pp->pixels,p->pixels.lin,p->pixels.col); 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); 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(&p->pixels);
matrix_destroy(&pp->pixels); matrix_destroy(&pp->pixels);
quadtree_tree_destroy(&tree); quadtree_tree_destroy(&tree);
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* @param filename = the file path of the image to read * @param filename = the file path of the image to read
* @return pgm_error * @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 sizex = 0;
int sizey = 0; int sizey = 0;
...@@ -56,7 +56,7 @@ pgm_error pgm_read_from_file(pgm *p,const char* const filename) ...@@ -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 * @param filename = the file path of the image to write
* @return pgm_error * @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) if (p->pixels.data == NULL)
{ {
...@@ -127,7 +127,7 @@ pgm_error pgm_duplicate(char *filename,char *newfile) ...@@ -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 * @param gray_scale = the gray scale max in file returned by pointed value
* @return pgm_error * @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; FILE *f;
f = fopen(filename,"r"); f = fopen(filename,"r");
......
...@@ -18,9 +18,9 @@ int32_t max; ...@@ -18,9 +18,9 @@ int32_t max;
matrix pixels; matrix pixels;
} pgm; } pgm;
pgm_error pgm_read_from_file(pgm *p,const char* const filename); pgm_error pgm_read_from_file(pgm *p,const char* filename);
pgm_error pgm_write_from_file(pgm *p,char *filename); pgm_error pgm_write_from_file(pgm *p,const char *filename);
pgm_error pgm_duplicate(char *filename,char *newfile); 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 #endif
\ No newline at end of file
#include "quadtree.h" #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) bool quadtree_is_leaf(node *nd)
{ {
return (NULL == nd->child[0]); 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) int32_t quadtree_get_depth_from_image_size(int32_t sizex)
{ {
return (int32_t)log2(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 *quadtree_tree_create(int32_t depth)
{ {
node *a = calloc(1, sizeof(node)); node *a = calloc(1, sizeof(node));
...@@ -24,11 +42,25 @@ node *quadtree_tree_create(int32_t depth) ...@@ -24,11 +42,25 @@ node *quadtree_tree_create(int32_t depth)
return a; 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) int32_t quadtree_max(int32_t x, int32_t y)
{ {
return (x >= y ? x : 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 quadtree_array_max(int32_t size, int32_t tab[size])
{ {
int32_t m = INT_MIN; int32_t m = INT_MIN;
...@@ -39,10 +71,16 @@ int32_t quadtree_array_max(int32_t size, int32_t tab[size]) ...@@ -39,10 +71,16 @@ int32_t quadtree_array_max(int32_t size, int32_t tab[size])
return m; 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}; int32_t p[CHILDREN] = {0};
if (quadtree_is_leaf(a)) if (quadtree_is_leaf(tree))
{ {
return 0; return 0;
} }
...@@ -50,33 +88,47 @@ int32_t quadtree_depth(node *a) ...@@ -50,33 +88,47 @@ int32_t quadtree_depth(node *a)
{ {
for (int32_t i = 0; i < CHILDREN; i++) 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); 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++) for (int32_t i = 0; i < decal; i++)
{ {
printf("%s", sep); printf("%s", sep);
} }
printf("%d\n", (uint32_t)arbre->data); printf("%lf\n", tree->average);
decal++; decal++;
if (!quadtree_is_leaf(arbre)) if (!quadtree_is_leaf(tree))
{ {
for (int32_t i = 0; i < CHILDREN; i++) 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 quadtree_swap(void **ptr1, void **ptr2)
{ {
void *tmp = *ptr1; void *tmp = *ptr1;
...@@ -84,64 +136,79 @@ void quadtree_swap(void **ptr1, void **ptr2) ...@@ -84,64 +136,79 @@ void quadtree_swap(void **ptr1, void **ptr2)
*ptr2 = tmp; *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++) 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++) 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
node *crt = a; * @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 = tree;
do 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 ligne = (li >> depth) & 1;
int32_t colonne = (col >> d) & 1; //Exemple: 10 >> 1 = 1; int32_t colonne = (col >> depth) & 1;
int32_t index = (ligne << 1) | colonne; // Exemple: 1<<1 = 10 | 1(col) = 11=>3 int32_t index = (ligne << 1) | colonne;
crt = crt->child[index]; crt = crt->child[index];
d--; depth--;
} while (!quadtree_is_leaf(crt)); } while (!quadtree_is_leaf(crt));
return crt; return crt;
} }
double quadtree_position_value(int32_t li, int32_t col, node *a, int32_t d) /**
{ * @name quadtree_matrix2tree
node *crt = a; * @brief Convert matrix to quadtree
do * @param mat pointer on matrix
* @param tree pointer on node
* @return void
*/
void quadtree_matrix2tree(matrix *mat, node *tree)
{ {
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 d = quadtree_depth(tree) - 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)
{
int32_t d = quadtree_depth(arbre) - 1;
for (int32_t li = 0; li < mat->lin; li++) for (int32_t li = 0; li < mat->lin; li++)
{ {
for (int32_t co = 0; co < mat->col; co++) for (int32_t co = 0; co < mat->col; co++)
{ {
node *crt = quadtree_position(li, co, arbre, d); node *crt = quadtree_position(li, co, tree, d);
crt->data = mat->data[li][co]; 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) void quadtree_tree2matrix(node *tree, matrix *mat)
{ {
int32_t d = quadtree_depth(tree) - 1; int32_t d = quadtree_depth(tree) - 1;
...@@ -149,12 +216,17 @@ void quadtree_tree2matrix(node *tree, matrix *mat) ...@@ -149,12 +216,17 @@ void quadtree_tree2matrix(node *tree, matrix *mat)
{ {
for (int32_t co = 0; co < mat->col; co++) 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) void quadtree_horizontal_symetry(node *tree)
{ {
if (NULL != tree) if (NULL != tree)
...@@ -168,7 +240,12 @@ void quadtree_horizontal_symetry(node *tree) ...@@ -168,7 +240,12 @@ void quadtree_horizontal_symetry(node *tree)
} }
} }
// 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) void quadtree_vertical_symetry(node *tree)
{ {
if (NULL != tree) if (NULL != tree)
...@@ -182,12 +259,24 @@ void quadtree_vertical_symetry(node *tree) ...@@ -182,12 +259,24 @@ void quadtree_vertical_symetry(node *tree)
} }
} }
/**
* @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) void quadtree_central_symetry(node *tree)
{ {
quadtree_vertical_symetry(tree); quadtree_vertical_symetry(tree);
quadtree_horizontal_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) void quadtree_tree_destroy(node **tree)
{ {
if (NULL != *tree) if (NULL != *tree)
...@@ -205,3 +294,68 @@ void quadtree_tree_destroy(node **tree) ...@@ -205,3 +294,68 @@ void quadtree_tree_destroy(node **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
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#define CHILDREN 4 #define CHILDREN 4
typedef struct _node { typedef struct _node {
double data; double average;
double average_2; double average_2;
struct _node* child[CHILDREN]; struct _node* child[CHILDREN];
} node; } node;
...@@ -50,3 +50,7 @@ void quadtree_horizontal_symetry(node *tree); ...@@ -50,3 +50,7 @@ void quadtree_horizontal_symetry(node *tree);
void quadtree_vertical_symetry(node *tree); void quadtree_vertical_symetry(node *tree);
void quadtree_central_symetry(node *tree); 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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment