Bonjour,
J'ai un problème que je ne serne pas du tout. Je suis en train de réaliser le portage d'une veille application en c++ vers du C#.
dans cette application, un algorithme de compression est implémenté. Le voici
Ne vous souciez pas trop des partie en commentaire, elle ne sont la que pour vérifier si le fichier est compréssé ou non. Et la n'est pas mon problème.
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 int compress(char *Origin, char *Desti, int act) { unsigned char c, cc; int k, j, nb, i, m, err=0 ; FILE *fx, *fz; fx = fopen (Origin, "r+b"); fz = fopen (Desti , "w+b"); switch(act) { case 2 : /* Teste si le fichier est compressé */ { unsigned char buf_O[BUFF_COMPR] ; nb = fread(buf_O,1,6,fx) ; /* recherche de la signature */ if ( nb < 6 ) { err = 10 ; break ; } //if ( strncmp(buf_O, "UDTQCS", 6) != 0 ) err = 1 ; /* non compressé */ //else err = 2; /* compressé */ break ; } case 1 : /* Compression */ { unsigned char buf_O[BUFF_COMPR], buf_D[BUFF_COMPR] ; nb = fread(buf_O,1,6,fx) ; /* recherche de la signature */ if ( nb < 6 ) { err = 10 ; break ; } /*if ( strncmp(buf_O, "UDTQCS", 6) == 0 ) { err = 2 ; // le fichier est déjà compressé break ; }*/ fseek (fx, 0L, SEEK_SET); //strcpy(buf_D, "UDTQCS"); /* mise en place de la signature */ fwrite(buf_D,6,1,fz); while( 1 ) { nb = fread(buf_O,1,BUFF_COMPR,fx) ; if ( nb == 0 ) break ; j = i = 0 ; c = buf_O[i++] ; buf_D[j++] = c ; k = 1 ; while ( i < nb ) { cc = buf_O[i++] ; if ( c != cc ) { if ( k != 1 ) { buf_D[j++] = (unsigned char)(k | 0x80); k = 1 ; } c = cc ; if ( c & 0x80 )buf_D[j++] = 0x1B ; buf_D[j++] = c ; } else { k++ ; if ( k > 125 ) { k-- ; buf_D[j++] = (unsigned char)(k | 0x80); k = 1 ; if ( c & 0x80 )buf_D[j++] = 0x1B ; buf_D[j++] = c ; } } } if ( k > 1 ) buf_D[j++] = (unsigned char)(k | 0x80); fwrite(buf_D,j,1,fz) ; } break ; } case 0 : /* Décompression */ { unsigned char buf_O[BUFF_COMPR], buf_D[BUFF_COMPR] ; nb = fread(buf_O,1,6,fx) ; /* recherche de la signature */ if ( nb < 6 ) { err = 10 ; break ; } /*if ( strncmp(buf_O, "UDTQCS", 6) != 0 ) { err = 1 ; // le fichier n'est pas compressé // break ; }*/ j = 0 ; cc = '\0' ; while( 1 ) { nb = fread(buf_O,1,BUFF_COMPR,fx) ; if ( nb == 0 ) break ; i = 0 ; while ( i < nb ) { c = buf_O[i++] ; if ( (c & 0x80) && cc != 0x1B ) { k = (int)(c & 0x7F ) - 1 ; for ( m = 0 ; m < k ; m++ ) { buf_D[j++] = cc ; if ( j == BUFF_COMPR ) { fwrite(buf_D,j,1,fz) ; j = 0 ; } } } else { if ( c != 0x1B ) { buf_D[j++] = c ; if ( j == BUFF_COMPR ) { fwrite(buf_D,j,1,fz) ; j = 0 ; } } cc = c ; } } } if ( j > 0 ) fwrite(buf_D,j,1,fz) ; break ; } } fclose(fx) ; fclose(fz) ; return (err); }
Je me suis focalisé sur la décompression, car g déjà un fichier compresser par cet algo.
Concentrons-nous alors sur la partie 0 du switch
et voici une ligne du fichier compressé (il ne faut pas tenir compte des cotes en début et fin de chaine):
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 case 0 : /* Décompression */ { unsigned char buf_O[BUFF_COMPR], buf_D[BUFF_COMPR] ; nb = fread(buf_O,1,6,fx) ; /* recherche de la signature */ if ( nb < 6 ) { err = 10 ; break ; } /*if ( strncmp(buf_O, "UDTQCS", 6) != 0 ) { err = 1 ; // le fichier n'est pas compressé // break ; }*/ j = 0 ; cc = '\0' ; while( 1 ) { nb = fread(buf_O,1,BUFF_COMPR,fx) ; if ( nb == 0 ) break ; i = 0 ; while ( i < nb ) { c = buf_O[i++] ; if ( (c & 0x80) && cc != 0x1B ) { k = (int)(c & 0x7F ) - 1 ; for ( m = 0 ; m < k ; m++ ) { buf_D[j++] = cc ; if ( j == BUFF_COMPR ) { fwrite(buf_D,j,1,fz) ; j = 0 ; } } } else { if ( c != 0x1B ) { buf_D[j++] = c ; if ( j == BUFF_COMPR ) { fwrite(buf_D,j,1,fz) ; j = 0 ; } } cc = c ; } } } if ( j > 0 ) fwrite(buf_D,j,1,fz) ; break ; }
Mon problème vient de cette ligne :
Code : Sélectionner tout - Visualiser dans une fenêtre à part '07262812010OTI060120906429380130 0 ý ý ý Ñ ý ý à'
Au début du case, lorsque l'algo lit le caractère ',' sa valeur en entier vaut 130, ce qui lui permet, une fois le masque appliquer de passer dans le test juste en dessous et de recopier une nouvelle fois le caractère précédent.
Code : Sélectionner tout - Visualiser dans une fenêtre à part c = buf_O[i++] ;
Le souci c'est que -à moins qu'il en existe plusieurs- la table ascii dit que la virgule à pour code ascii 44 et non pas 130.
Du coup dans mon impléentation en C#, la virgule ne passe pas le test et est inscrite dans mon fichier décompressé au lieu de répéter le caractère précèdent.
Pouvez-vous m'aider ?
PS : j'oubliais voici la ligne du fichier mais en version décompressé (pareil, il ne faut pas tenir compte des cotes en début et fin de chaine)
Code : Sélectionner tout - Visualiser dans une fenêtre à part '072628122010OTTI060120090642938000000001130 00000 '
Partager