Bonjour, j'ai récemment créé un programme pour lire les données d'une image png, et les enregistrer sous forme de texte lisible dans un fichier.
Après l'avoir optimisé comme je pouvais ( factorisation de codes, et création de plusieurs sous-fonctions ), il avait l'air de marcher parfaitement, du moins faisait il ce que je lui demandais de faire, sans rien dire.
Malheureusement, alors que le code compile parfaitement ( aucune erreur ni warning, que ce soit avec ou sans informations de debug ) lorsque je le lance depuis mon shell avec un bon vieux (Mon programme s'appelle PNG ) :
Voici ce que m'affiche le shell :
Code : Sélectionner tout - Visualiser dans une fenêtre à part ./PNG
Au vu des premières lignes je pense que l'erreur se fait un sur un free, d'après d'autres forums c'est un free sur un pointeur non alloué par malloc ... le problème c'est que je n'en vois pas dans mon code ...
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 *** glibc detected *** ./PNG: free(): invalid next size (fast): 0x0000000001125dd0 *** ======= Backtrace: ========= /lib/x86_64-linux-gnu/libc.so.6(+0x76d76)[0x7f2153f8ed76] /lib/x86_64-linux-gnu/libc.so.6(cfree+0x6c)[0x7f2153f93b1c] ./PNG[0x401057] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7f2153f36ead] ./PNG[0x401119] ======= Memory map: ======== 00400000-00402000 r-xp 00000000 08:16 917771 /**/Release/PNG 00601000-00602000 rw-p 00001000 08:16 917771 /**/PNG 01125000-01146000 rw-p 00000000 00:00 0 [heap] 7f214c000000-7f214c021000 rw-p 00000000 00:00 0 7f214c021000-7f2150000000 ---p 00000000 00:00 0 7f2153d00000-7f2153d16000 r-xp 00000000 08:13 102 /lib/x86_64-linux-gnu/libz.so.1.2.7 7f2153d16000-7f2153f15000 ---p 00016000 08:13 102 /lib/x86_64-linux-gnu/libz.so.1.2.7 7f2153f15000-7f2153f16000 r--p 00015000 08:13 102 /lib/x86_64-linux-gnu/libz.so.1.2.7 7f2153f16000-7f2153f17000 rw-p 00016000 08:13 102 /lib/x86_64-linux-gnu/libz.so.1.2.7 7f2153f18000-7f215409a000 r-xp 00000000 08:13 954 /lib/x86_64-linux-gnu/libc-2.13.so 7f215409a000-7f2154299000 ---p 00182000 08:13 954 /lib/x86_64-linux-gnu/libc-2.13.so 7f2154299000-7f215429d000 r--p 00181000 08:13 954 /lib/x86_64-linux-gnu/libc-2.13.so 7f215429d000-7f215429e000 rw-p 00185000 08:13 954 /lib/x86_64-linux-gnu/libc-2.13.so 7f215429e000-7f21542a3000 rw-p 00000000 00:00 0 7f21542a8000-7f21542bd000 r-xp 00000000 08:13 15 /lib/x86_64-linux-gnu/libgcc_s.so.1 7f21542bd000-7f21544bd000 ---p 00015000 08:13 15 /lib/x86_64-linux-gnu/libgcc_s.so.1 7f21544bd000-7f21544be000 rw-p 00015000 08:13 15 /lib/x86_64-linux-gnu/libgcc_s.so.1 7f21544c0000-7f2154541000 r-xp 00000000 08:13 948 /lib/x86_64-linux-gnu/libm-2.13.so 7f2154541000-7f2154740000 ---p 00081000 08:13 948 /lib/x86_64-linux-gnu/libm-2.13.so 7f2154740000-7f2154741000 r--p 00080000 08:13 948 /lib/x86_64-linux-gnu/libm-2.13.so 7f2154741000-7f2154742000 rw-p 00081000 08:13 948 /lib/x86_64-linux-gnu/libm-2.13.so 7f2154748000-7f2154830000 r-xp 00000000 08:18 130835 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17 7f2154830000-7f2154a30000 ---p 000e8000 08:18 130835 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17 7f2154a30000-7f2154a38000 r--p 000e8000 08:18 130835 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17 7f2154a38000-7f2154a3a000 rw-p 000f0000 08:18 130835 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17 7f2154a3a000-7f2154a4f000 rw-p 00000000 00:00 0 7f2154a50000-7f2154a81000 r-xp 00000000 08:18 418851 /usr/local/lib/libpng16.so.16.8.0 7f2154a81000-7f2154c81000 ---p 00031000 08:18 418851 /usr/local/lib/libpng16.so.16.8.0 7f2154c81000-7f2154c82000 rw-p 00031000 08:18 418851 /usr/local/lib/libpng16.so.16.8.0 7f2154c88000-7f2154ca8000 r-xp 00000000 08:13 953 /lib/x86_64-linux-gnu/ld-2.13.so 7f2154ea2000-7f2154ea7000 rw-p 00000000 00:00 0 7f2154ea7000-7f2154ea8000 r--p 0001f000 08:13 953 /lib/x86_64-linux-gnu/ld-2.13.so 7f2154ea8000-7f2154ea9000 rw-p 00020000 08:13 953 /lib/x86_64-linux-gnu/ld-2.13.so 7f2154ea9000-7f2154eaa000 rw-p 00000000 00:00 0 7f2154eab000-7f2154eb0000 rw-p 00000000 00:00 0 7fff8cbf2000-7fff8cc13000 rw-p 00000000 00:00 0 [stack] 7fff8cde8000-7fff8cde9000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] Abandon
Si vous avez des solutions, je suis preneur ! Et même plutôt deux fois qu'une !
Enfin, voici mon code ( Je ne vous met pas de partie incriminée ... vu que je ne sais pas ou elle pourrait être ... )
Main.c
Fonctions.c
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135 #include <stdio.h> #include <stdlib.h> #include <setjmp.h> #include <png.h> #include "fonctions.h" #define NAME "image.png" #define OUT_NAME "sortie.txt" int main(void) { FILE* input = fopen( NAME, "rb" ); FILE* out_txt = fopen(OUT_NAME, "w"); unsigned int x = 0, y = 0; png_uint_32 width = 0, height = 0; png_structp png_ptr = NULL; png_infop info_ptr = NULL; png_bytep row_pointer = NULL; if (input == NULL) { if (out_txt == NULL); return (FILE_ERROR); } if (!is_png(input)) { fclose(input); fclose(out_txt); return (NOT_A_PNG); } clear_file(out_txt); png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); if ( png_ptr == NULL ) { fclose(input); fclose(out_txt); return (STRUCT_ERROR); } info_ptr = png_create_info_struct( png_ptr ); if ( info_ptr == NULL) { fclose(input); fclose(out_txt); png_destroy_read_struct( &png_ptr, &info_ptr, NULL ); png_ptr = NULL; info_ptr = NULL; return (STRUCT_ERROR); } if(setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); \ fclose(input); fclose(out_txt); row_pointer = NULL; return (PNG_JMPBUF_ERROR); } png_init_io( png_ptr, input ); png_set_sig_bytes( png_ptr, 8 ); png_read_info( png_ptr, info_ptr ); #if 0 display_img_data(info_ptr, png_ptr); #endif if(is_tit_image(info_ptr, png_ptr) == NOT_A_TIT_IMG) { fclose(input); fclose(out_txt); png_destroy_read_struct( &png_ptr, &info_ptr, NULL ); png_ptr = NULL; info_ptr = NULL; return (NOT_A_TIT_IMG); } else { /* Init var */ width = png_get_image_width(png_ptr, info_ptr); height = png_get_image_height(png_ptr, info_ptr); /* Init row tab for one row storage */ row_pointer = (png_bytep) malloc(sizeof(png_bytep)); if (row_pointer == NULL) { fclose(input); fclose(out_txt); png_destroy_read_struct( &png_ptr, &info_ptr, NULL ); png_ptr = NULL; info_ptr = NULL; return (ALLOC_ERROR); } /* Begin read Image data */ for ( y = 0; y < height; y++) { png_read_row(png_ptr, row_pointer, NULL); for ( x = 0; x < width; x++) { if (pixel_to_text(row_pointer, x) != 0) save_pixel_to_file(row_pointer, x, out_txt); } } png_read_end(png_ptr, NULL); free(row_pointer); row_pointer = NULL; } png_destroy_read_struct( &png_ptr, &info_ptr, NULL ); png_ptr = NULL; info_ptr = NULL; fclose(input); fclose(out_txt); return (NO_ERROR); }
Fonctions.h
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155 /* Fonctions diverses pour le programme décodeur : * */ #include <png.h> #include "fonctions.h" #define INTERNAL_NOT_PNG 0 /* Return component 'c' of pixel 'x' from the given row. */ unsigned int component_from_rgb(png_const_bytep row, png_uint_32 x, unsigned int c) { png_uint_32 bit_offset_hi = TIT_BIT_DEPTH * ((x >> 6) * RGB_CHANNELS); png_uint_32 bit_offset_lo = TIT_BIT_DEPTH * ((x & 0x3f) * RGB_CHANNELS + c); row = (png_const_bytep)(((PNG_CONST png_byte (*)[8])row) + bit_offset_hi); row += bit_offset_lo >> 3; bit_offset_lo &= 0x07; return row[0]; } char print_pixel(png_const_bytep row, png_uint_32 x) { printf("RGB %u %u %u\n", get_red_component(row, x), get_green_component(row, x), get_blue_component(row, x)); return pixel_to_text(row, x); } char fill_file(unsigned int c, FILE *file) { while (fgetc(file) != EOF) fputc(c, file); return (NO_ERROR); } char clear_file(FILE *file) { if (file == NULL ) { return (NULL_FILE); } else { if (fgetc(file) == EOF) { return (NO_ERROR); } else { fill_file(0, file); rewind(file); return (NO_ERROR); } return (INTERNAL_ERROR); } } void display_color_type(unsigned int color_type) { printf("\tType de couleur de l'image : "); switch ( color_type) { case PNG_COLOR_TYPE_GRAY: { puts( "Niveaux de gris" ); break; } case PNG_COLOR_TYPE_GRAY_ALPHA: { puts( "Niveaux de gris avec Alpha" ); break; } case PNG_COLOR_TYPE_PALETTE: { puts( "Palette" ); break; } case PNG_COLOR_TYPE_RGB: { puts( "Rouge / Vert / Bleu" ); break; } case PNG_COLOR_TYPE_RGB_ALPHA: { puts( "Rouge / Vert / Bleu / Alpha" ); break; } default: { puts( "Impossible de déterminer le type de couleur." ); break; } } } void display_img_data(png_infopp pinfo, png_structpp ppng) { puts("Données de l'image"); printf("\tLongueur : %d\n", png_get_image_height(ppng, pinfo)); printf("\tLargeur : %d\n", png_get_image_width(ppng, pinfo)); printf("\tBit depth de l'image : %d\n", png_get_bit_depth(ppng, pinfo)); display_color_type(png_get_color_type(ppng, pinfo)); printf("\tL'image %s\n", png_get_compression_type(ppng, pinfo) == PNG_COMPRESSION_TYPE_BASE ? "est compressée." : "n'est pas compressée." ); printf("\tL'image %s\n", png_get_interlace_type(ppng, pinfo) == PNG_INTERLACE_NONE ? "n'est pas interlacée." : "est interlacée." ); } int is_png(FILE* file) { char header[PNG_SIG_WIDTH]; fread(header, 1, PNG_SIG_WIDTH, file); if( png_sig_cmp(header, 0, PNG_SIG_WIDTH) == 0) return (!INTERNAL_NOT_PNG); else return INTERNAL_NOT_PNG; return (INTERNAL_ERROR); } int is_tit_image(png_infopp pinfo, png_structpp ppng) { int bit_depth, interlaced; bit_depth = png_get_bit_depth(ppng, pinfo); interlaced = png_get_interlace_type(ppng, pinfo); if (bit_depth != 8 || interlaced != PNG_INTERLACE_NONE) return (NOT_A_TIT_IMG); else return !(NOT_A_TIT_IMG); return (INTERNAL_ERROR); } char pixel_to_text(png_const_bytep row, png_uint_32 x) { return ((unsigned char)(get_blue_component(row, x)) % 255); } /* End Of File */
Voilà, je vous remercie d'avance.
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 #ifndef FONCTIONS_H_INCLUDED #define FONCTIONS_H_INCLUDED #define PNG_SIG_WIDTH 8 #define TIT_BIT_DEPTH 8 /* For internal fonctions */ #define RGB_CHANNELS 3 #define RED_CHANNEL 0 #define GREEN_CHANNEL 1 #define BLUE_CHANNEL 2 /* Errors definitions */ #define INTERNAL_ERROR -1 #define NO_ERROR 0 #define FILE_ERROR 1 #define NULL_FILE 2 #define NOT_A_PNG 3 #define NOT_A_TIT_IMG 4 #define STRUCT_ERROR 5 #define ALLOC_ERROR 6 #define PNG_JMPBUF_ERROR 7 #define NOT_ENOUGH_MEMORY 8 /* Macros */ #define get_red_component(row, x) component_from_rgb(row, x, RED_CHANNEL) #define get_green_component(row, x) component_from_rgb(row, x, GREEN_CHANNEL) #define get_blue_component(row, x) component_from_rgb(row, x, BLUE_CHANNEL) #define save_pixel_to_file(row, x, file) fputc(pixel_to_text(row, x), file) #define size_tab(tab) ( (sizeof(tab)) / (sizeof(tab[0])) ) unsigned int component_from_rgb(png_const_bytep row, png_uint_32 x, unsigned int c); char print_pixel(png_const_bytep row, png_uint_32 x); char void_file(const char* fname); char fill_file(unsigned int c, FILE *file); void display_color_type(unsigned int color_type); void display_img_data(png_infopp pinfo, png_structpp ppng); int is_tit_image(png_infopp pinfo, png_structpp ppng); int is_png(FILE* file); char pixel_to_text(png_const_bytep row, png_uint_32 x); #endif // FONCTIONS_H_INCLUDED
Partager