void free_huffman_tables(huff_table_t *root) { if (root == NULL) { return; } free_huffman_tables(root->left); free_huffman_tables(root->right); free(root); }
void free_huffman_tables(huff_table_t *root) { if (root == NULL) { // fprintf(stderr, "%s : can't free NULL tree ! \n", __func__); return; } if (root->left != NULL) { free_huffman_tables(root->left); root->left = NULL; } if (root->right != NULL) { free_huffman_tables(root->right); root->right = NULL; } free(root); root = NULL; }
int32_t main(int32_t argc, char *argv[]) { if (argc < 2) { printf("Usage: %s <nom_de_fichier_jpeg>\n",argv[0]); return 0; } FILE * f; f = fopen(argv[1],"r"); if (f == 0) { printf("Fichier inexistant ou nom incorrect.\n"); printf("Conversion du fichier '%s' échouée.\n",argv[1]); return -1; } if (_DISPLAY_HEAD >= 1 || _DISPLAY_BODY >= 1 || _DRY_RUN) { printf("\n*********** DECODAGE DE '%s' ***********\n",argv[1]); } /* I. Decodage de l'en-tete*/ /* Initialisation des variables */ image_t *im = malloc(sizeof(image_t)); /* Proprietes de l'image */ uint16_t RI = 0; /* Restart Interval */ uint8_t QT[2][_BSIZE]; /* Tables de quantification */ huff_table_t *HT[2][2] = {{NULL,NULL},{NULL,NULL}}; /* T. de Huffman */ printmark("\n+========== HEADER ===============================+\n"); printmark("octet : description\n\n"); /* Decodage */ uint32_t cpt = 1; read_byte(&cpt,f); int8_t check = analyse_header(im,&RI,QT,HT,&cpt,f); if (check == -1) { printf("Conversion du fichier '%s' échouée.\n",argv[1]); fclose(f); printbody("Fichier JPEG fermé\n"); return -1; } printmark("+========== END OF HEADER ========================+\n\n"); if (_DISPLAY_HEAD == 0) { printbody("Analyse de l'en-tête\n"); } /* II. Calculs preliminaires */ /* Calcul de la taille d'une MCU */ uint8_t MCU_size[2]; compute_MCU_size(im, MCU_size); const uint32_t nb_pxl_in_MCU = MCU_size[0] * MCU_size[1]; printbody2(" => Nb px par MCU : %u\n",nb_pxl_in_MCU); /* Calcul du nombre de MCU dans l'image */ uint32_t nb_MCU_width = im->width / MCU_size[0] + ((im->width % MCU_size[0]) != 0); uint32_t nb_MCU_height = im->height / MCU_size[1] + ((im->height % MCU_size[1]) != 0); printbody("Taille de l'image en MCU : %ux%u\n",nb_MCU_height, nb_MCU_width); uint32_t nb_RGB_MCU = nb_MCU_width * nb_MCU_height; printbody("Nb de MCU RGB : %u\n",nb_RGB_MCU); /* Calcul de l'intervalle de resync en nb de blocs */ uint32_t blocks_per_MCU = 0; for (uint32_t i = 0; i < im->nb_comp; i++) { blocks_per_MCU += im->comp[i].echH * im->comp[i].echV; } uint32_t RI_block = blocks_per_MCU * RI; if (RI != 0) { printbody("Nombre de blocs par MCU : %u\n",blocks_per_MCU); printbody("Intervalle de resync en blocs : %u blocs\n",RI_block); } if (_DRY_RUN) { display_data_and_EOI(&cpt,f); goto end; } printbody("\n+========== BODY =================================+\n"); /* Initialisation du scan */ printbody("Initialisation du scan\n"); scan_desc_t scan; scan.bit_count = 0; scan.window = 0; scan.pred[0] = 0; scan.pred[1] = 0; scan.pred[2] = 0; for (uint32_t i = 0; i < im->nb_comp; i++) { scan.table[0][i] = HT[0][im->comp[i].ih_DC]; scan.table[1][i] = HT[1][im->comp[i].ih_AC]; } /* Initialisation du fichier TIFF */ char *tiff_file_name = tiff_name(argv[1]); printbody("Création du fichier '%s'\n",tiff_file_name); FILE *tiff_f = fopen(tiff_file_name,"w"); init_tiff_file(tiff_f,im->width,im->height,MCU_size[1]); /* III. Decodage des donnees brutes */ /* reconstruction des MCU*/ printbody("Reconstitutions des MCU (decodage des donnees brutes)\n"); uint32_t *RGB_MCU = calloc(nb_pxl_in_MCU,sizeof(uint32_t)); for (uint32_t i = 0; i < nb_RGB_MCU; i++) { if (RI == 0 && nb_RGB_MCU > 10 && i % (nb_RGB_MCU/10) == 0) { printbody1(" %3u%%\n",i*100/nb_RGB_MCU); } get_RGB_MCU(RGB_MCU,f,&scan,im,RI_block,MCU_size,QT); printRGBMCU(RGB_MCU,MCU_size); printbody2("\n"); write_tiff_file(tiff_f,MCU_size[0],MCU_size[1],RGB_MCU); } free(RGB_MCU); /* lecture du marqueur de fin d'image EOI */ if (RI == 0) { uint16_t mark = read_2bytes(&cpt,f); assert(mark == 0xffd9); printbody("Marqueur de fin d'image EOI : Fin du décodage\n"); } printbody("+========== END OF BODY ==========================+\n\n"); /* fin de procedure */ printf("Conversion du fichier '%s'\nen '%s' réussie.\n",argv[1], tiff_file_name); free(tiff_file_name); close_tiff_file(tiff_f); printbody("Fichier TIFF fermé\n"); end: if (_DRY_RUN) { printf("+========== END OF BODY ==========================+\n"); printf("** Attention : mode Dry-Run actif **\n"); printf("Lecture du fichier terminée avec succès\n"); } fclose(f); printbody("Fichier JPEG fermé\n"); free(im->comp); free(im); free_huffman_tables(HT[0][0]); free_huffman_tables(HT[1][0]); free_huffman_tables(HT[0][1]); free_huffman_tables(HT[1][1]); printbody("Mémoire libérée\n"); return 0; }