/* * Exports raw MCU image data as TIFF. */ void export_tiff(struct jpeg_data *jpeg, bool *error) { if (*error || jpeg == NULL) { *error = true; return; } struct tiff_file_desc *file = NULL; file = init_tiff_file(jpeg->path, jpeg->width, jpeg->height, jpeg->mcu.v); if (file != NULL) { uint32_t *mcu_RGB; /* Write all MCUs as TIFF */ for (uint32_t i = 0; i < jpeg->mcu.nb; i++) { mcu_RGB = &jpeg->raw_data[i * jpeg->mcu.size]; write_tiff_file(file, mcu_RGB, jpeg->mcu.h_dim, jpeg->mcu.v_dim); } close_tiff_file(file); } else *error = true; }
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; }
int32_t main(int32_t argc, char *argv[]) { if (argc < 2) { printf("Usage: %s <nom_de_fichier_tiff>\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) { printf("\n*********** DECODAGE DE '%s' ***********\n",argv[1]); } /* I. Decodage de l'en-tete TIFF */ /* Initialisation des variables */ uint8_t quality = 3; uint8_t QT[2][_BSIZE]; /* Tables de quantification */ uint8_t MCU_size[2]; image_t *im = malloc(sizeof(image_t)); /* Proprietes de l'image */ im->nb_comp = 3; im->comp = calloc(3,sizeof(comp_t)); im->comp[0].ic = 1; im->comp[1].ic = 2; im->comp[2].ic = 3; im->comp[0].iq = 0; im->comp[1].iq = 1; im->comp[2].iq = 1; printmark("\n+========== HEADER ===============================+\n"); /* Decodage */ read_tiff_file_header(f,&(im->height),&(im->width),&(MCU_size[1])); MCU_size[0] = 16; im->comp[0].echH = MCU_size[0]/8; im->comp[0].echV = MCU_size[1]/8; im->comp[1].echH = 1; im->comp[1].echV = 1; im->comp[2].echH = 1; im->comp[2].echV = 1; printmark("+========== END OF HEADER ========================+\n\n"); if (_DISPLAY_HEAD == 0) { printbody("Analyse de l'en-tête\n"); } /* II. Calculs preliminaires */ /* 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); printbody("\n+========== BODY =================================+\n"); /* Initialisation du fichier TIFF */ char *out_file = out_name(argv[1]); printbody("Création du fichier '%s'\n",out_file); FILE *out_f = fopen(out_file,"w"); init_tiff_file(out_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 nb_pxl_in_MCU = MCU_size[0] * MCU_size[1]; uint32_t *out_RGB_MCU = calloc(nb_pxl_in_MCU,sizeof(uint32_t)); uint32_t *in_RGB_MCU = calloc(nb_pxl_in_MCU,sizeof(uint32_t)); for (uint32_t i = 0; i < nb_RGB_MCU; i++) { if (nb_RGB_MCU > 10 && i % (nb_RGB_MCU/10) == 0) { printbody1(" %3u%%\n",i*100/nb_RGB_MCU); } get_tiff_MCU(f,MCU_size[0],in_RGB_MCU); change_RGB_MCU(in_RGB_MCU,out_RGB_MCU,im,MCU_size,quality); printbody2("\n"); write_tiff_file(out_f,MCU_size[0],MCU_size[1],out_RGB_MCU); } free(in_RGB_MCU); free(out_RGB_MCU); printbody("+========== END OF BODY ==========================+\n\n"); /* fin de procedure */ printf("Conversion du fichier '%s'\nen '%s' réussie.\n",argv[1], out_file); free(out_file); close_tiff_file(out_f); printbody("Fichier TIFF fermé\n"); 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); printbody("Mémoire libérée\n"); return 0; }
int main() { struct tiff_file_desc *in = NULL; uint32_t width, height; /* Read TIFF header */ in = init_tiff_read(INPUT, &width, &height); if (in == NULL) { printf("ERROR : invalid input TIFF file\n"); return EXIT_FAILURE; } /* Read all raw RGB data from the TIFF file */ uint32_t *line = NULL; const uint32_t nb_pixels_max = width * height; uint32_t *raw_data = malloc(nb_pixels_max * sizeof(uint32_t)); if (raw_data != NULL){ /* Read all RGB lines */ for (uint32_t i = 0; i < height; i++) { /* Read one RGB line */ line = &(raw_data[i * width]); read_tiff_line(in, line); } } close_tiff_file(in); struct tiff_file_desc *out = NULL; struct mcu_info mcu; mcu.h = 16; mcu.v = 8; out = init_tiff_file(OUTPUT, width, height, mcu.v); if (out != NULL) { mcu.h_dim = mcu.h/8; mcu.v_dim = mcu.v/8; mcu.nb_h = width / mcu.h + width % mcu.h; mcu.nb_v = height / mcu.v + height % mcu.v; mcu.nb = mcu.nb_h * mcu.nb_v; mcu.size = mcu.h * mcu.v; uint32_t *mcu_RGB; uint32_t *mcu_data = image_to_mcu(raw_data, &mcu, width, height); for (uint32_t i = 0; i < mcu.nb; i++) { mcu_RGB = &(mcu_data[i * mcu.size]); write_tiff_file(out, mcu_RGB, mcu.h_dim, mcu.v_dim); } close_tiff_file(out); printf("TIFF successfully reencoded as %s\n", OUTPUT); } else printf("ERROR : invalid output TIFF file\n"); return EXIT_SUCCESS; }