A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 294 lines 7.6 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2002 by Björn Stenberg 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 2 15 * of the License, or (at your option) any later version. 16 * 17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 * KIND, either express or implied. 19 * 20 ****************************************************************************/ 21 22#include <stdio.h> 23#include <stdlib.h> 24#include <string.h> 25 26#include "iriver.h" 27#include "gigabeat.h" 28 29int iaudio_decode(char *iname, char *oname); 30 31unsigned int le2int(unsigned char* buf) 32{ 33 unsigned int res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; 34 35 return res; 36} 37 38void int2le(unsigned int val, unsigned char* addr) 39{ 40 addr[0] = val & 0xFF; 41 addr[1] = (val >> 8) & 0xff; 42 addr[2] = (val >> 16) & 0xff; 43 addr[3] = (val >> 24) & 0xff; 44} 45 46void usage(void) 47{ 48 printf("usage: descramble [options] <input file> <output file>\n"); 49 printf("options:\n" 50 "\t-fm Archos FM recorder format\n" 51 "\t-v2 Archos V2 recorder format\n" 52 "\t-mm Archos Multimedia format\n" 53 "\t-iriver iRiver format\n" 54 "\t-gigabeat Toshiba Gigabeat format\n" 55 "\t-iaudio iAudio format\n" 56 "\nNo option assumes Archos standard player/recorder format.\n"); 57 exit(1); 58} 59 60int main (int argc, char** argv) 61{ 62 unsigned long length,i,slen; 63 unsigned char *inbuf,*outbuf; 64 char *iname = argv[1]; 65 char *oname = argv[2]; 66 unsigned char header[32]; 67 int headerlen = 6; 68 int descramble = 1; 69 FILE* file; 70 71 if (argc < 3) { 72 usage(); 73 } 74 75 if (!strcmp(argv[1], "-fm") || !strcmp(argv[1], "-v2")) { 76 headerlen = 24; 77 iname = argv[2]; 78 oname = argv[3]; 79 } 80 81 if (!strcmp(argv[1], "-mm")) { 82 headerlen = 16; 83 iname = argv[2]; 84 oname = argv[3]; 85 descramble = 0; 86 } 87 88 if(!strcmp(argv[1], "-iriver")) { 89 /* iRiver code dealt with in the iriver.c code */ 90 iname = argv[2]; 91 oname = argv[3]; 92 return iriver_decode(iname, oname, FALSE, STRIP_NONE) ? -1 : 0; 93 } 94 if(!strcmp(argv[1], "-gigabeat")) { 95 iname = argv[2]; 96 oname = argv[3]; 97 gigabeat_code(iname, oname); 98 return 0; 99 } 100 101 if(!strcmp(argv[1], "-iaudio")) { 102 iname = argv[2]; 103 oname = argv[3]; 104 return iaudio_decode(iname, oname); 105 } 106 107 /* open file and check size */ 108 file = fopen(iname,"rb"); 109 if (!file) { 110 perror(iname); 111 return -1; 112 } 113 fseek(file,0,SEEK_END); 114 length = ftell(file) - headerlen; /* skip header */ 115 fseek(file,0,SEEK_SET); 116 i = fread(header, 1, headerlen, file); 117 if ( !i ) { 118 perror(iname); 119 return -1; 120 } 121 122 inbuf = malloc(length); 123 outbuf = malloc(length); 124 if ( !inbuf || !outbuf ) { 125 printf("out of memory!\n"); 126 return -1; 127 } 128 129 /* read file */ 130 i=fread(inbuf,1,length,file); 131 if ( !i ) { 132 perror(iname); 133 return -1; 134 } 135 fclose(file); 136 137 if (descramble) { 138 /* descramble */ 139 slen = length/4; 140 for (i = 0; i < length; i++) { 141 unsigned long addr = ((i % slen) << 2) + i/slen; 142 unsigned char data = inbuf[i]; 143 data = ~((data >> 1) | ((data << 7) & 0x80)); /* poor man's ROR */ 144 outbuf[addr] = data; 145 } 146 } 147 else { 148 void* tmpptr; 149 unsigned int j=0; 150 int stringlen = 32; 151 int unpackedsize; 152 unsigned char xorstring[32]; 153 154 unpackedsize = header[4] | header[5] << 8; 155 unpackedsize |= header[6] << 16 | header[7] << 24; 156 157 length = header[8] | header[9] << 8; 158 length |= header[10] << 16 | header[11] << 24; 159 160 /* calculate the xor string used */ 161 for (i=0; i<(unsigned long)stringlen; i++) { 162 int top=0, topchar=0, c; 163 int bytecount[256]; 164 memset(bytecount, 0, sizeof(bytecount)); 165 166 /* gather byte frequency statistics */ 167 for (c=i; c<(int)length; c+=stringlen) 168 bytecount[inbuf[c]]++; 169 170 /* find the most frequent byte */ 171 for (c=0; c<256; c++) { 172 if (bytecount[c] > top) { 173 top = bytecount[c]; 174 topchar = c; 175 } 176 } 177 xorstring[i] = topchar; 178 } 179 printf("XOR string: %.*s\n", stringlen, xorstring); 180 181 /* xor the buffer */ 182 for (i=0; i<length; i++) 183 outbuf[i] = inbuf[i] ^ xorstring[i & (stringlen-1)]; 184 185 /* unpack */ 186 tmpptr = realloc(inbuf, unpackedsize); 187 memset(tmpptr, 0, unpackedsize); 188 inbuf = outbuf; 189 outbuf = tmpptr; 190 191 for (i=0; i<length;) { 192 int bit; 193 int head = inbuf[i++]; 194 195 for (bit=0; bit<8 && i<length; bit++) { 196 if (head & (1 << (bit))) { 197 outbuf[j++] = inbuf[i++]; 198 } 199 else { 200 int x; 201 int byte1 = inbuf[i]; 202 int byte2 = inbuf[i+1]; 203 int count = (byte2 & 0x0f) + 3; 204 int src = 205 (j & 0xfffff000) + (byte1 | ((byte2 & 0xf0)<<4)) + 18; 206 if (src > (int)j) 207 src -= 0x1000; 208 209 for (x=0; x<count; x++) 210 outbuf[j++] = outbuf[src+x]; 211 i += 2; 212 } 213 } 214 } 215 length = j; 216 } 217 218 /* write file */ 219 file = fopen(oname,"wb"); 220 if ( !file ) { 221 perror(argv[2]); 222 return -1; 223 } 224 if ( !fwrite(outbuf,length,1,file) ) { 225 perror(argv[2]); 226 return -1; 227 } 228 fclose(file); 229 230 free(inbuf); 231 free(outbuf); 232 233 return 0; 234} 235 236int iaudio_decode(char *iname, char *oname) 237{ 238 size_t len; 239 int length; 240 FILE *file; 241 char *outbuf; 242 int i; 243 unsigned char sum = 0; 244 unsigned char filesum; 245 246 file = fopen(iname, "rb"); 247 if (!file) { 248 perror(iname); 249 return -1; 250 } 251 fseek(file,0,SEEK_END); 252 length = ftell(file); 253 254 fseek(file,0,SEEK_SET); 255 outbuf = malloc(length); 256 257 if ( !outbuf ) { 258 printf("out of memory!\n"); 259 return -1; 260 } 261 262 len = fread(outbuf, 1, length, file); 263 if(len < (size_t)length) { 264 perror(iname); 265 return -2; 266 } 267 268 fclose(file); 269 270 for(i = 0; i < length-0x1030;i++) 271 sum += outbuf[0x1030 + i]; 272 273 filesum = outbuf[0x102b]; 274 275 if(filesum != sum) { 276 printf("Checksum mismatch!\n"); 277 return -1; 278 } 279 280 file = fopen(oname, "wb"); 281 if (!file) { 282 perror(oname); 283 return -3; 284 } 285 286 len = fwrite(outbuf+0x1030, 1, length-0x1030, file); 287 if(len < (size_t)length-0x1030) { 288 perror(oname); 289 return -4; 290 } 291 292 fclose(file); 293 return 0; 294}