A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 191 lines 5.2 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2006 Dave Chapman 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/* 27 * CRC32 implementation taken from: 28 * 29 * efone - Distributed internet phone system. 30 * 31 * (c) 1999,2000 Krzysztof Dabrowski 32 * (c) 1999,2000 ElysiuM deeZine 33 * 34 * This program is free software; you can redistribute it and/or 35 * modify it under the terms of the GNU General Public License 36 * as published by the Free Software Foundation; either version 37 * 2 of the License, or (at your option) any later version. 38 * 39 */ 40 41/* based on implementation by Finn Yannick Jacobs */ 42 43/* crc_tab[] -- this crcTable is being build by chksum_crc32GenTab(). 44 * so make sure, you call it before using the other 45 * functions! 46 */ 47static unsigned int crc_tab[256]; 48 49/* chksum_crc() -- to a given block, this one calculates the 50 * crc32-checksum until the length is 51 * reached. the crc32-checksum will be 52 * the result. 53 */ 54static unsigned int chksum_crc32 (unsigned char *block, unsigned int length) 55{ 56 register unsigned long crc; 57 unsigned long i; 58 59 crc = 0; 60 for (i = 0; i < length; i++) 61 { 62 crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_tab[(crc ^ *block++) & 0xFF]; 63 } 64 return (crc); 65} 66 67/* chksum_crc32gentab() -- to a global crc_tab[256], this one will 68 * calculate the crcTable for crc32-checksums. 69 * it is generated to the polynom [..] 70 */ 71 72static void chksum_crc32gentab (void) 73{ 74 unsigned long crc, poly; 75 int i, j; 76 77 poly = 0xEDB88320L; 78 for (i = 0; i < 256; i++) 79 { 80 crc = i; 81 for (j = 8; j > 0; j--) 82 { 83 if (crc & 1) 84 { 85 crc = (crc >> 1) ^ poly; 86 } 87 else 88 { 89 crc >>= 1; 90 } 91 } 92 crc_tab[i] = crc; 93 } 94} 95 96static void int2le(unsigned int val, unsigned char* addr) 97{ 98 addr[0] = val & 0xFF; 99 addr[1] = (val >> 8) & 0xff; 100 addr[2] = (val >> 16) & 0xff; 101 addr[3] = (val >> 24) & 0xff; 102} 103 104int mi4_encode(char *iname, char *oname, int version, int magic, 105 char *model, char *type) 106{ 107 size_t len; 108 int length; 109 int mi4length; 110 FILE *file; 111 unsigned int crc = 0; 112 unsigned char *outbuf; 113 114 file = fopen(iname, "rb"); 115 if (!file) { 116 perror(iname); 117 return -1; 118 } 119 fseek(file,0,SEEK_END); 120 length = ftell(file); 121 122 fseek(file,0,SEEK_SET); 123 124 /* Add 4 bytes to length (for magic), the 0x200 byte header and 125 then round to an even 0x400 bytes 126 */ 127 mi4length = (length+4+0x200+0x3ff)&~0x3ff; 128 129 outbuf = malloc(mi4length); 130 131 if ( !outbuf ) { 132 printf("out of memory!\n"); 133 return -1; 134 } 135 136 /* Clear the buffer to zero */ 137 memset(outbuf, 0, mi4length); 138 139 len = fread(outbuf+0x200, 1, length, file); 140 if(len < (size_t)length) { 141 perror(iname); 142 return -2; 143 } 144 fclose(file); 145 146 /* We need to write some data into the actual image - before calculating 147 the CRC. */ 148 int2le(0x00000100, &outbuf[0x2e0]); /* magic */ 149 int2le(magic, &outbuf[0x2e4]); /* magic */ 150 int2le(length+4, &outbuf[0x2e8]); /* length plus 0xaa55aa55 */ 151 152 int2le(0xaa55aa55, &outbuf[0x200+length]); /* More Magic */ 153 154 strncpy((char *)outbuf+0x1f8, type, 4); /* type of binary (RBBL, RBOS) */ 155 strncpy((char *)outbuf+0x1fc, model, 4); /* 4 character model id */ 156 157 /* Calculate CRC32 checksum */ 158 chksum_crc32gentab (); 159 crc = chksum_crc32 (outbuf+0x200,mi4length-0x200); 160 161 memcpy(outbuf, "PPOS", 4); /* Magic */ 162 int2le(version, &outbuf[0x04]); /* .mi4 version */ 163 int2le(length+4, &outbuf[0x08]); /* Length of firmware plus magic */ 164 int2le(crc, &outbuf[0x0c]); /* CRC32 of mi4 file */ 165 int2le(0x00000002, &outbuf[0x10]); /* Encryption type: 2 = TEA */ 166 int2le(mi4length, &outbuf[0x14]); /* Total .mi4 length */ 167 int2le(mi4length-0x200, &outbuf[0x18]); /* Length of plaintext part */ 168 169 /* v3 files require a dummy DSA signature */ 170 if (version == 0x00010301) { 171 outbuf[0x2f]=0x01; 172 } 173 174 file = fopen(oname, "wb"); 175 if (!file) { 176 perror(oname); 177 return -3; 178 } 179 180 len = fwrite(outbuf, 1, mi4length, file); 181 if(len < (size_t)length) { 182 perror(oname); 183 return -4; 184 } 185 186 fclose(file); 187 188 fprintf(stderr, "File encoded successfully\n" ); 189 190 return 0; 191}