IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Bibliothèques Discussion :

libpng : custom chunks


Sujet :

Bibliothèques

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Par défaut libpng : custom chunks
    Bonsoir,

    j'essaie d'utiliser la libpng pour lire et écrire des custom chunks, en lisant la documentation j'ai trouvé les fonctions qu'il faut mais cela ne fonctionne pas. La fonction censée lire le chunk spécial n'est pas appelé comme si de rien n'étais. De plus décommenter png_read_end renvoie une erreur de CRC, je ne comprends pas. Voici le code :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    #include <png.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    FILE *fp;
    png_structp png_ptr;
    png_infop info_ptr, end_info;
    png_byte magic[8];
    png_byte custom_chunk[5] = { 116, 73, 77, 69, (png_byte)'\0' }; // tIME
    png_byte unused_chunks[]=
    {
    	104,  73,  83,  84, (png_byte) '\0',   /* hIST */
    	105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
    	112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
    	115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
    	115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
    	'I', 'D', 'A', 'T', (png_byte) '\0'
    };
     
    void readPNG(char *file);
    void read_chunk_custom(png_structp ptr, png_unknown_chunkp chunk);
    int main(int argc, char **argv);
     
    void read_chunk_custom(png_structp ptr, png_unknown_chunkp chunk) {
    	printf("Reading custom chunk @ %p\n", chunk->data);
     
    	FILE *out = fopen("./out.jpg", "wb");
    	if (!out) {
    		fprintf(stderr, "Cannot write the chunk to ouput.\n");
    		return;
    	}
     
    	fwrite(chunk->data, 1, sizeof(chunk->data), out);
    	fclose(out);
     
    	return;
    }
     
    void readPNG(char *file) {
    	printf("read: %s\n", file);
     
    	fp = fopen(file, "rb");
    	if (!fp) {
    		fprintf(stderr, "Cannot open %s.\n", file);
    		return;
    	}
     
    	fread(magic, 1, sizeof(magic), fp);
    	if (!png_check_sig(magic, sizeof(magic))) {
    		fprintf(stderr, "error: %s isn't a valid PNG file.\n", file);
    		return;
    	}
    	//fseek(fp, 0, SEEK_SET);
     
    	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    	if (!png_ptr) {
    		fprintf(stderr, "Cannot create read struct.\n");
    		return;
    	}
     
    	info_ptr = png_create_info_struct(png_ptr);
    	if (!info_ptr) {
    		png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
    		fprintf(stderr, "Cannot create info struct.\n");
    		return;
    	}
     
    	end_info = png_create_info_struct(png_ptr);
    	if (!end_info)
    	{
    		png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
    		fprintf(stderr, "Cannot create end info struct.\n");
    		return;
    	}
     
    	if (setjmp(png_jmpbuf(png_ptr))) {
    		fprintf(stderr, "Error: fatal.\n");
    		return;
    	}
     
    	png_init_io(png_ptr, fp);
    	png_set_sig_bytes(png_ptr, sizeof(magic));
     
    	png_read_info(png_ptr, info_ptr);
    	png_read_update_info (png_ptr, info_ptr);
     
    	int width = png_get_image_width(png_ptr, info_ptr),
    		height = png_get_image_height(png_ptr, info_ptr);
    	printf("Image %i x %i\n", width, height);
     
    	/* ignore all unknown chunks: */
    	png_set_keep_unknown_chunks(png_ptr, 1, NULL, 0);
    	/* except for our custom chunk: */
    	png_set_keep_unknown_chunks(png_ptr, 2, custom_chunk, sizeof(custom_chunk)/5);
    	/* also ignore unused known chunks: */
    	png_set_keep_unknown_chunks(png_ptr, 1, unused_chunks, sizeof(unused_chunks)/5);
     
    	png_set_read_user_chunk_fn(png_ptr, NULL, (png_user_chunk_ptr)read_chunk_custom);
    	//png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, custom_chunk, sizeof(custom_chunk)/5);
     
    	// Renvoie une erreur CRC si décommenter !
    	//png_read_end(png_ptr, end_info);
    	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
     
    	fclose(fp);
    }
     
    int main(int argc, char **argv) {
    	if (strcmp(argv[1], "-r") || strcmp(argv[1], "--read")) {
    		readPNG(argv[2]);
    	}
    	return 0;
    }

    Output:
    $ ./png-embedder -r file.png
    read: file.png
    Image 400 x 400
    J'ai bien vérifié, dans mon fichier j'ai bien un chunk tIME (déjà pour essayer). Le fichier est lisible avec plusieurs programmes pas de soucis. J'ai l'impression que png_read_end devrait être appelé pour que tout fonctionne. Que faire ? merci d'avance.

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Par défaut
    La solution a été trouvée sur la mailing list officiel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    #include <png.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    FILE *fp;
    png_structp png_ptr;
    png_infop info_ptr, end_info;
    png_byte magic[8];
    png_byte custom_chunk[] = {
    	't', 'I', 'M', 'E', (png_byte)'\0', 			/* tIME */
    	't', 'E', 'X', 't', (png_byte)'\0', 			/* tEXt */
    	't', 'E', 'S', 't', (png_byte)'\0', 			/* tESt */
    };
     
    void readPNG(char *file);
    int read_chunk_custom(png_structp ptr, png_unknown_chunkp chunk);
    int main(int argc, char **argv);
     
    int read_chunk_custom(png_structp ptr, png_unknown_chunkp chunk) {
    	static int unknown_numb = 0;
    	char fileout[255];
     
    	printf("Reading custom chunk [%s] @%p (%i octets)\n", chunk->name, chunk->data, chunk->size);
    	sprintf(fileout, "./out-%i-%s.bin", unknown_numb, chunk->name);
     
    	FILE *out = fopen(fileout, "wb");
    	if (!out) {
    		fprintf(stderr, "Cannot write the chunk to ouput.\n");
    		return -1;
    	}
     
    	fwrite(chunk->data, 1, chunk->size, out);
    	fclose(out);
     
    	unknown_numb++;
    	return 1;
    }
     
    void readPNG(char *file) {
    	printf("read: %s\n", file);
     
    	fp = fopen(file, "rb");
    	if (!fp) {
    		fprintf(stderr, "Cannot open %s.\n", file);
    		return;
    	}
     
    	fread(magic, 1, sizeof(magic), fp);
    	if (!png_check_sig(magic, sizeof(magic))) {
    		fprintf(stderr, "error: %s isn't a valid PNG file.\n", file);
    		return;
    	}
     
    	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    	if (!png_ptr) {
    		fprintf(stderr, "Cannot create read struct.\n");
    		return;
    	}
     
    	info_ptr = png_create_info_struct(png_ptr);
    	if (!info_ptr) {
    		png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
    		fprintf(stderr, "Cannot create info struct.\n");
    		return;
    	}
     
    	end_info = png_create_info_struct(png_ptr);
    	if (!end_info)
    	{
    		png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
    		fprintf(stderr, "Cannot create end info struct.\n");
    		return;
    	}
     
    	if (setjmp(png_jmpbuf(png_ptr))) {
    		fprintf(stderr, "Error: fatal.\n");
    		return;
    	}
     
    	// Setting unknown-chunk callback
    	png_set_read_user_chunk_fn(png_ptr, NULL, (png_user_chunk_ptr)read_chunk_custom);
     
    	/* except for our custom chunk: */
    	png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_IF_SAFE, custom_chunk, sizeof(custom_chunk)/5);
     
    	png_init_io(png_ptr, fp);
    	png_set_sig_bytes(png_ptr, sizeof(magic));
     
    	png_read_info(png_ptr, info_ptr);
    	png_read_update_info (png_ptr, info_ptr);
     
    	int width = png_get_image_width(png_ptr, info_ptr),
    		height = png_get_image_height(png_ptr, info_ptr);
    	printf("Image %i x %i\n", width, height);
     
    	// Junking the IDAT
    	unsigned int i;
    	for (i = 0; i < height; i++)
    		png_read_row(png_ptr, NULL, NULL);
     
    	png_read_end(png_ptr, end_info);
    	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
     
    	fclose(fp);
    }
     
    int main(int argc, char **argv) {
    	if (strcmp(argv[1], "-r") || strcmp(argv[1], "--read")) {
    		readPNG(argv[2]);
    	}
    	return 0;
    }
    Mettre les callbacks en amont des read. Lire l'IDAT pour lire la fin du fichier (attention à adapter pour les fichiers interlacés car height != rows du IDAT !). En gros.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [JSF] mon premier custom component
    Par anitshka dans le forum JSF
    Réponses: 5
    Dernier message: 14/06/2005, 13h31
  2. [C#] Custom Control : Recuperer valeur formulaire
    Par victorbru dans le forum ASP.NET
    Réponses: 22
    Dernier message: 21/04/2005, 09h02
  3. Problème avec les librairies ZLIB et LIBPNG
    Par VenusX117 dans le forum Bibliothèques
    Réponses: 1
    Dernier message: 14/03/2005, 14h49
  4. [C#] Custom Control et message de confirmation
    Par lancelot69 dans le forum ASP.NET
    Réponses: 4
    Dernier message: 23/12/2004, 15h04
  5. Libpng.so.2 vs libpng.so.3
    Par karmaki dans le forum Linux
    Réponses: 5
    Dernier message: 26/02/2004, 13h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo