Added ID3 searching
[kugel-rb.git] / tools / descramble.c
blob7376190c697a497c2b99f15f8864ef8c677d40a7
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Björn Stenberg
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include <stdio.h>
21 #include <stdlib.h>
23 #include "iriver.h"
25 void usage(void)
27 printf("usage: descramble [options] <input file> <output file>\n");
28 printf("options:\n"
29 "\t-fm Archos FM recorder format\n"
30 "\t-v2 Archos V2 recorder format\n"
31 "\t-mm=X Archos Multimedia format (X values: A=JBMM, B=AV1xx, C=AV3xx)\n"
32 "\t-iriver iRiver format\n"
33 "\nNo option assumes Archos standard player/recorder format.\n");
34 exit(1);
37 int main (int argc, char** argv)
39 unsigned long length,i,slen;
40 unsigned char *inbuf,*outbuf;
41 unsigned char *iname = argv[1];
42 unsigned char *oname = argv[2];
43 unsigned char header[32];
44 int headerlen = 6;
45 int descramble = 1;
46 FILE* file;
48 if (argc < 3) {
49 usage();
52 if (!strcmp(argv[1], "-fm") || !strcmp(argv[1], "-v2")) {
53 headerlen = 24;
54 iname = argv[2];
55 oname = argv[3];
58 if (!strcmp(argv[1], "-mm")) {
59 headerlen = 16;
60 iname = argv[2];
61 oname = argv[3];
62 descramble = 0;
65 if(!strcmp(argv[1], "-iriver")) {
66 /* iRiver code dealt with in the iriver.c code */
67 iname = argv[2];
68 oname = argv[3];
69 iriver_decode(iname, oname, FALSE, STRIP_NONE);
70 return 0;
73 /* open file and check size */
74 file = fopen(iname,"rb");
75 if (!file) {
76 perror(oname);
77 return -1;
79 fseek(file,0,SEEK_END);
80 length = ftell(file) - headerlen; /* skip header */
81 fseek(file,0,SEEK_SET);
82 i = fread(header, 1, headerlen, file);
83 if ( !i ) {
84 perror(iname);
85 return -1;
88 inbuf = malloc(length);
89 outbuf = malloc(length);
90 if ( !inbuf || !outbuf ) {
91 printf("out of memory!\n");
92 return -1;
95 /* read file */
96 i=fread(inbuf,1,length,file);
97 if ( !i ) {
98 perror(iname);
99 return -1;
101 fclose(file);
103 if (descramble) {
104 /* descramble */
105 slen = length/4;
106 for (i = 0; i < length; i++) {
107 unsigned long addr = ((i % slen) << 2) + i/slen;
108 unsigned char data = inbuf[i];
109 data = ~((data >> 1) | ((data << 7) & 0x80)); /* poor man's ROR */
110 outbuf[addr] = data;
113 else {
114 void* tmpptr;
115 unsigned int j=0;
116 int stringlen = 32;
117 int unpackedsize;
118 unsigned char xorstring[32];
120 unpackedsize = header[4] | header[5] << 8;
121 unpackedsize |= header[6] << 16 | header[7] << 24;
123 length = header[8] | header[9] << 8;
124 length |= header[10] << 16 | header[11] << 24;
126 /* calculate the xor string used */
127 for (i=0; i<stringlen; i++) {
128 int top=0, topchar=0, c;
129 int bytecount[256];
130 memset(bytecount, 0, sizeof(bytecount));
132 /* gather byte frequency statistics */
133 for (c=i; c<length; c+=stringlen)
134 bytecount[inbuf[c]]++;
136 /* find the most frequent byte */
137 for (c=0; c<256; c++) {
138 if (bytecount[c] > top) {
139 top = bytecount[c];
140 topchar = c;
143 xorstring[i] = topchar;
145 printf("XOR string: %.*s\n", stringlen, xorstring);
147 /* xor the buffer */
148 for (i=0; i<length; i++)
149 outbuf[i] = inbuf[i] ^ xorstring[i & (stringlen-1)];
151 /* unpack */
152 tmpptr = realloc(inbuf, unpackedsize);
153 memset(tmpptr, 0, unpackedsize);
154 inbuf = outbuf;
155 outbuf = tmpptr;
157 for (i=0; i<length;) {
158 int bit;
159 int head = inbuf[i++];
161 for (bit=0; bit<8 && i<length; bit++) {
162 if (head & (1 << (bit))) {
163 outbuf[j++] = inbuf[i++];
165 else {
166 int x;
167 int byte1 = inbuf[i];
168 int byte2 = inbuf[i+1];
169 int count = (byte2 & 0x0f) + 3;
170 int src =
171 (j & 0xfffff000) + (byte1 | ((byte2 & 0xf0)<<4)) + 18;
172 if (src > j)
173 src -= 0x1000;
175 for (x=0; x<count; x++)
176 outbuf[j++] = outbuf[src+x];
177 i += 2;
181 length = j;
184 /* write file */
185 file = fopen(oname,"wb");
186 if ( !file ) {
187 perror(argv[2]);
188 return -1;
190 if ( !fwrite(outbuf,length,1,file) ) {
191 perror(argv[2]);
192 return -1;
194 fclose(file);
196 free(inbuf);
197 free(outbuf);
199 return 0;