예제 #1
0
void free_huffman_tables(huff_table_t *root)
{
	if (root == NULL) {
		return;
	}
	free_huffman_tables(root->left);
	free_huffman_tables(root->right);
	free(root);
}
예제 #2
0
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;
}
예제 #3
0
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;
}