/* * 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; }
/* * Initialisation de la lecture d'un fichier TIFF, avec les sorties suivantes : * - width : la largeur de l'image lue * - height: la hauteur de l'image lue */ struct tiff_file_desc *init_tiff_read (const char *path, uint32_t *width, uint32_t *height) { FILE *file = NULL; bool error = false; struct tiff_file_desc *tfd = calloc(1, sizeof(struct tiff_file_desc)); if (tfd == NULL) return NULL; file = fopen(path, "rb"); if (file == NULL) return NULL; tfd->file = file; uint16_t endian; /* Endianness detection */ endian = read_short(tfd, &error); if (endian == 0x4949) tfd->is_le = true; else if (endian == 0x4D4D) tfd->is_le = false; else error = true; /* 42 tiff marker */ read_short(tfd, &error); /* IFD offset */ tfd->ifd_offset = read_long(tfd, &error); /* Go to our IFD offset */ fseek(file, tfd->ifd_offset, SEEK_SET); /* IFD count */ tfd->ifd_count = read_short(tfd, &error); /* Default compression to none */ tfd->compression = 1; /* Read all IFD entries */ for(uint32_t i = 0; i < tfd->ifd_count; i++) read_ifd_entry(tfd, &error); tfd->current_line = 0; tfd->read_lines = 0; uint16_t samples = tfd->samples_per_pixels; uint16_t photo = tfd->photometric_interpretation; /* Check tiff validity / compatibility */ if (tfd->strip_offsets == NULL || tfd->width == 0 || tfd->height == 0 || (samples != 1 && samples != 3 && samples != 4) || tfd->compression != 1 || tfd->bits_per_sample != 8 || (photo != 1 && photo != 2)) error = true; /* Cleanup on error */ if (error) { close_tiff_file(tfd); tfd = NULL; } else { *width = tfd->width; *height = tfd->height; /* Move the file to the first strip to read */ fseek(tfd->file, tfd->strip_offsets[tfd->current_line], SEEK_SET); } return tfd; }
int main(int argc, char **argv) { int fd, page, fd_tiff, ret; struct urf_file_header head, head_orig; struct urf_page_header page_header, page_header_orig; struct tiff_info tiff; if(argc < 3) { fprintf(stderr, "Usage: %s <input.urf> <output.tiff>\n", argv[0]); return 1; } if((fd = open(argv[1], O_RDONLY)) == -1) die("Unable to open unirast file"); lseek(fd, 0, SEEK_SET); if(read(fd, &head_orig, sizeof(head)) == -1) die("Unable to read file header"); //Transform memcpy(head.unirast, head_orig.unirast, sizeof(head.unirast)); head.page_count = ntohl(head_orig.page_count); if(head.unirast[7]) head.unirast[7] = 0; if(strncmp(head.unirast, "UNIRAST", 7) != 0) die("Bad File Header"); iprintf("%s file, with %d page(s).\n", head.unirast, head.page_count); if(create_tiff_file(&tiff, argv[2], head.page_count) != 0) die("Unable to create TIFF file"); for(page = 0 ; page < head.page_count ; ++page) { if(read(fd, &page_header_orig, sizeof(page_header_orig)) == -1) die("Unable to read page header"); //Transform page_header.bpp = page_header_orig.bpp; page_header.colorspace = page_header_orig.colorspace; page_header.duplex = page_header_orig.duplex; page_header.quality = page_header_orig.quality; page_header.unknown0 = 0; page_header.unknown1 = 0; page_header.width = ntohl(page_header_orig.width); page_header.height = ntohl(page_header_orig.height); page_header.dot_per_inch = ntohl(page_header_orig.dot_per_inch); page_header.unknown2 = 0; page_header.unknown3 = 0; iprintf("Page %d :\n", page); iprintf("Bits Per Pixel : %d\n", page_header.bpp); iprintf("Colorspace : %d\n", page_header.colorspace); iprintf("Duplex Mode : %d\n", page_header.duplex); iprintf("Quality : %d\n", page_header.quality); iprintf("Size : %dx%d pixels\n", page_header.width, page_header.height); iprintf("Dots per Inches : %d\n", page_header.dot_per_inch); if(add_tiff_page(&tiff, page, page_header.width, page_header.height, page_header.bpp, page_header.dot_per_inch) != 0) die("Unable to create TIFF file"); decode_raster(fd, page_header.width, page_header.height, page_header.bpp, &tiff); } close_tiff_file(&tiff); 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; }
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; }
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; }