diff options
Diffstat (limited to 'tools/scramble.c')
-rw-r--r-- | tools/scramble.c | 63 |
1 files changed, 58 insertions, 5 deletions
diff --git a/tools/scramble.c b/tools/scramble.c index df6c5ac084..f1fa0c084d 100644 --- a/tools/scramble.c +++ b/tools/scramble.c | |||
@@ -49,6 +49,8 @@ void usage(void) | |||
49 | "\t-neo SSI Neo format\n" | 49 | "\t-neo SSI Neo format\n" |
50 | "\t-mm=X Archos Multimedia format (X values: A=JBMM, B=AV1xx, C=AV3xx)\n" | 50 | "\t-mm=X Archos Multimedia format (X values: A=JBMM, B=AV1xx, C=AV3xx)\n" |
51 | "\t-iriver iRiver format\n" | 51 | "\t-iriver iRiver format\n" |
52 | "\t-add=X Rockbox iRiver \"add-up\" checksum format\n" | ||
53 | "\t (X values: h100, h120, h140, h300)\n" | ||
52 | "\nNo option results in Archos standard player/recorder format.\n"); | 54 | "\nNo option results in Archos standard player/recorder format.\n"); |
53 | 55 | ||
54 | exit(1); | 56 | exit(1); |
@@ -59,6 +61,7 @@ int main (int argc, char** argv) | |||
59 | unsigned long length,i,slen; | 61 | unsigned long length,i,slen; |
60 | unsigned char *inbuf,*outbuf; | 62 | unsigned char *inbuf,*outbuf; |
61 | unsigned short crc=0; | 63 | unsigned short crc=0; |
64 | unsigned long crc32=0; /* 32 bit checksum */ | ||
62 | unsigned char header[24]; | 65 | unsigned char header[24]; |
63 | unsigned char *iname = argv[1]; | 66 | unsigned char *iname = argv[1]; |
64 | unsigned char *oname = argv[2]; | 67 | unsigned char *oname = argv[2]; |
@@ -66,7 +69,9 @@ int main (int argc, char** argv) | |||
66 | int headerlen = 6; | 69 | int headerlen = 6; |
67 | FILE* file; | 70 | FILE* file; |
68 | int version; | 71 | int version; |
69 | enum { none, scramble, xor } method = scramble; | 72 | unsigned long irivernum; |
73 | char irivermodel[5]; | ||
74 | enum { none, scramble, xor, add } method = scramble; | ||
70 | 75 | ||
71 | if (argc < 3) { | 76 | if (argc < 3) { |
72 | usage(); | 77 | usage(); |
@@ -119,6 +124,29 @@ int main (int argc, char** argv) | |||
119 | return -1; | 124 | return -1; |
120 | } | 125 | } |
121 | } | 126 | } |
127 | else if(!strncmp(argv[1], "-add=", 5)) { | ||
128 | iname = argv[2]; | ||
129 | oname = argv[3]; | ||
130 | method = add; | ||
131 | |||
132 | if(!strcmp(&argv[1][5], "h120")) | ||
133 | irivernum = 0; | ||
134 | else if(!strcmp(&argv[1][5], "h140")) | ||
135 | irivernum = 0; /* the same as the h120 */ | ||
136 | else if(!strcmp(&argv[1][5], "h140")) | ||
137 | irivernum = 0; /* the same as the h120 */ | ||
138 | else if(!strcmp(&argv[1][5], "h100")) | ||
139 | irivernum = 1; | ||
140 | else if(!strcmp(&argv[1][5], "h300")) | ||
141 | irivernum = 2; | ||
142 | else { | ||
143 | fprintf(stderr, "unsupported model: %s\n", &argv[1][5]); | ||
144 | return 2; | ||
145 | } | ||
146 | /* we store a 4-letter model name too, for humans */ | ||
147 | strcpy(irivermodel, &argv[1][5]); | ||
148 | crc32 = irivernum; /* start checksum calcs with this */ | ||
149 | } | ||
122 | 150 | ||
123 | else if(!strcmp(argv[1], "-iriver")) { | 151 | else if(!strcmp(argv[1], "-iriver")) { |
124 | /* iRiver code dealt with in the iriver.c code */ | 152 | /* iRiver code dealt with in the iriver.c code */ |
@@ -148,12 +176,19 @@ int main (int argc, char** argv) | |||
148 | inbuf = malloc(length); | 176 | inbuf = malloc(length); |
149 | if (method == xor) | 177 | if (method == xor) |
150 | outbuf = malloc(length*2); | 178 | outbuf = malloc(length*2); |
179 | else if(method == add) | ||
180 | outbuf = malloc(length + 8); | ||
151 | else | 181 | else |
152 | outbuf = malloc(length); | 182 | outbuf = malloc(length); |
153 | if ( !inbuf || !outbuf ) { | 183 | if ( !inbuf || !outbuf ) { |
154 | printf("out of memory!\n"); | 184 | printf("out of memory!\n"); |
155 | return -1; | 185 | return -1; |
156 | } | 186 | } |
187 | if(length> 4) { | ||
188 | /* zero-fill the last 4 bytes to make sure there's no rubbish there | ||
189 | when we write the size-aligned file later */ | ||
190 | memset(outbuf+length-4, 0, 4); | ||
191 | } | ||
157 | 192 | ||
158 | /* read file */ | 193 | /* read file */ |
159 | i=fread(inbuf,1,length,file); | 194 | i=fread(inbuf,1,length,file); |
@@ -165,6 +200,13 @@ int main (int argc, char** argv) | |||
165 | 200 | ||
166 | switch (method) | 201 | switch (method) |
167 | { | 202 | { |
203 | case add: | ||
204 | for (i = 0; i < length/2; i++) { | ||
205 | unsigned short *inbuf16 = (unsigned short *)inbuf; | ||
206 | /* add 16 unsigned bits but keep a 32 bit sum */ | ||
207 | crc32 += inbuf16[i]; | ||
208 | } | ||
209 | break; | ||
168 | case scramble: | 210 | case scramble: |
169 | slen = length/4; | 211 | slen = length/4; |
170 | for (i = 0; i < length; i++) { | 212 | for (i = 0; i < length; i++) { |
@@ -185,14 +227,25 @@ int main (int argc, char** argv) | |||
185 | } | 227 | } |
186 | break; | 228 | break; |
187 | } | 229 | } |
188 | 230 | ||
189 | /* calculate checksum */ | 231 | if(method != add) { |
190 | for (i=0;i<length;i++) | 232 | /* calculate checksum */ |
191 | crc += inbuf[i]; | 233 | for (i=0;i<length;i++) |
234 | crc += inbuf[i]; | ||
235 | } | ||
192 | 236 | ||
193 | memset(header, 0, sizeof header); | 237 | memset(header, 0, sizeof header); |
194 | switch (method) | 238 | switch (method) |
195 | { | 239 | { |
240 | case add: | ||
241 | { | ||
242 | unsigned long *headp = (unsigned long *)header; | ||
243 | headp[0] = crc32; /* checksum */ | ||
244 | memcpy(&header[4], irivermodel, 4); /* 4 bytes model name */ | ||
245 | memcpy(outbuf, inbuf, length); /* the input buffer to output*/ | ||
246 | headerlen = 8; | ||
247 | } | ||
248 | break; | ||
196 | case scramble: | 249 | case scramble: |
197 | if (headerlen == 6) { | 250 | if (headerlen == 6) { |
198 | int2be(length, header); | 251 | int2be(length, header); |