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){
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]);
}
......
......@@ -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);
......
......@@ -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");
......
......@@ -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
#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)
{
node *crt = a;
/**
* @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 = 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
/**
* @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 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)
{
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)
......@@ -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)
{
if (NULL != 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)
{
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)
......@@ -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 @@
#define CHILDREN 4
typedef struct _node {
double data;
double average;
double average_2;
struct _node* child[CHILDREN];
} node;
......@@ -50,3 +50,7 @@ void quadtree_horizontal_symetry(node *tree);
void quadtree_vertical_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