1 /* $Id: modinfo.c,v 1.4 2006/09/15 13:34:06 toad32767 Exp $ */ 2 /** 3 ** 2005, 2006 by Marco Trillo 4 ** This file is part of UModPlayer, and is released by 5 ** its autors to the Public Domain. 6 ** In case it's not legally possible, its autors grant 7 ** anyone the right to use, redistribute and modify 8 ** this software for any purpose, without any conditions, 9 ** unless such conditions are required by law. 10 ** 11 ** THIS FILE COMES WITHOUT ANY WARRANTY. THE AUTHORS 12 ** SHALL NOT BE LIABLE FOR ANY DAMAGE RESULTING BY THE 13 ** USE OR MISUSE OF THIS SOFTWARE. 14 **/ 15 16 #include <stdlib.h> 17 #include <string.h> 18 #include <umodplayer.h> 19 #include <modinfo.h> 20 21 22 /* Number of instruments of a MODULE */ 23 EXPORT int 24 number_instruments(MODULE * modfile) 25 { 26 unsigned char ins = 0; 27 char *buffer; 28 short type; 29 int modlen; 30 31 type = modfile->type; 32 modlen = modfile->buflen; 33 34 switch (type) { 35 case TYPE_SCREAM_3: 36 case TYPE_IMPULSE: euc_jis_2004_to_shift_jis_2004(PG_FUNCTION_ARGS)37 if (modlen > 36) { 38 buffer = modfile->buf + 34; 39 ins = (unsigned char) (*buffer); 40 } 41 break; 42 case TYPE_AMIGA_MOD: 43 ins = 31; 44 break; 45 case TYPE_FT2: 46 if (modlen > 74) { 47 buffer = modfile->buf + 72; 48 ins = (unsigned char) (*buffer); 49 } 50 break; shift_jis_2004_to_euc_jis_2004(PG_FUNCTION_ARGS)51 } 52 53 return ((int) ins); 54 } 55 /* Number of orders of a MODULE */ 56 EXPORT int 57 number_orders(MODULE * modfile) 58 { 59 uint16_t ord = 0; 60 char *buffer; 61 short type; 62 int modlen; 63 64 type = modfile->type; 65 modlen = modfile->buflen; 66 67 switch (type) { euc_jis_20042shift_jis_2004(const unsigned char * euc,unsigned char * p,int len)68 case TYPE_SCREAM_3: 69 case TYPE_IMPULSE: 70 if (modlen > 34) { 71 buffer = modfile->buf + 32; 72 ord = (uint16_t) (*(buffer++)); 73 ord <<= 8; 74 ord |= (uint16_t) (*buffer); 75 ord = bsLE16(ord); 76 } 77 break; 78 case TYPE_AMIGA_MOD: 79 if (modlen > 950) { 80 buffer = modfile->buf + 950; 81 ord = (uint16_t) (*buffer); 82 } 83 break; 84 case TYPE_FT2: 85 if (modlen > 72) { 86 buffer = modfile->buf + 70; 87 ord = (uint16_t) (*(buffer++)); 88 ord <<= 8; 89 ord |= (uint16_t) (*buffer); 90 ord = bsLE16(ord); 91 } 92 break; 93 94 } 95 96 return ((int) ord); 97 } 98 /* Loads & typedetects a module to a MODULE struct */ 99 EXPORT int 100 load_module(MODULE * modfile, char *buffer, int buflen) 101 { 102 char *buf; 103 short type; 104 uint32_t *magic; 105 uint32_t z; 106 107 108 type = TYPE_UNKNOWN; 109 110 /* XM`s identifier is 'Extended Module: ', starting at offset 0 */ 111 if (buflen > 17) { 112 if (memcmp(buffer, "Extended Module: ", 17) == 0) { 113 type = TYPE_FT2; 114 } 115 } 116 /* IT`s identifier is 'IMPM', starting at offset 0 */ 117 if (buflen > 4) { 118 magic = (uint32_t *) buffer; 119 z = 0x494D504D; 120 z = bsBE32(z); 121 if (z == (*magic)) { 122 type = TYPE_IMPULSE; 123 } 124 } 125 /* S3M`s identifier is 'SCRM', starting at offset 44 (28+4+2*6) */ 126 if (buflen > 48) { 127 buf = buffer + 44; 128 magic = (uint32_t *) buf; 129 z = 0x5343524D; 130 z = bsBE32(z); 131 if (z == (*magic)) { 132 type = TYPE_SCREAM_3; 133 } 134 } 135 /* MOD has a lot of identifiers, starting at offset 1080 */ 136 if (buflen > 1084) { 137 buf = buffer + 1080; 138 memcpy(&z, buf, 4); 139 z = bsBE32(z); 140 141 switch (z) { 142 /* Thanks to the Modfil11.txt for this identifiers */ 143 case 0x4d2e4b2e: 144 case 0x46544c34: 145 case 0x4d214b21: 146 case 0x3443484e: 147 case 0x3643484e: 148 case 0x3843484e: 149 case 0x4f435441: 150 case 0x464c5434: 151 case 0x43443831: 152 case 0x464c5438: 153 type = TYPE_AMIGA_MOD; 154 break; 155 } 156 } 157 modfile->type = type; 158 modfile->buflen = buflen; 159 modfile->buf = buffer; 160 161 if (type == TYPE_UNKNOWN) 162 return -1; 163 164 return 0; 165 } 166 /* Returns the name of the "numinst" instument as a null-terminated string */ 167 /* Returned value must be free()`d */ 168 EXPORT char * 169 return_instrument_name(MODULE * mod, int numinst) 170 { 171 register int i, j; 172 char *buffer; 173 char *insname; 174 char *limit; 175 int orders; 176 int instruments; 177 uint16_t z; 178 uint32_t Z; 179 int offset; 180 int numsamples; 181 unsigned int hlen; 182 int G; 183 get_ten(int b,int * ku)184 orders = number_orders(mod); 185 instruments = number_instruments(mod); 186 187 if (orders < 1) 188 return NULL; 189 if (instruments < (numinst + 1)) 190 return NULL; 191 192 insname = NULL; 193 194 switch (mod->type) { 195 case TYPE_SCREAM_3: 196 if (mod->buflen > (96 + orders + (instruments << 1))) { 197 buffer = mod->buf + 96 + orders; 198 buffer += (numinst << 1); 199 z = (uint16_t) (*(buffer++)); 200 z <<= 8; 201 z |= (uint16_t) (*buffer); 202 z = bsLE16(z); 203 offset = ((int) z) << 4; 204 offset += 48; 205 206 if (mod->buflen <= offset) 207 break; 208 209 buffer = mod->buf + offset; 210 insname = (char *) malloc(strlen(buffer) + 1); 211 if (insname == NULL) 212 break; 213 strcpy(insname, buffer); 214 } 215 break; shift_jis_20042euc_jis_2004(const unsigned char * sjis,unsigned char * p,int len)216 case TYPE_IMPULSE: 217 if (mod->buflen > (192 + orders + (instruments << 2))) { 218 buffer = mod->buf + 192 + orders; 219 buffer += (numinst << 2); 220 memcpy(&Z, buffer, 4); 221 Z = bsLE32(Z); 222 223 if (mod->buflen <= ((int) Z) + 32) 224 break; 225 226 buffer = mod->buf + Z + 32; 227 228 insname = (char *) malloc(strlen(buffer) + 1); 229 230 if (insname == NULL) 231 break; 232 strcpy(insname, buffer); 233 234 } 235 break; 236 case TYPE_AMIGA_MOD: 237 if (mod->buflen > (50 + 30 * numinst)) { 238 buffer = mod->buf + 20; 239 buffer += numinst * 30; 240 insname = (char *) malloc(23); 241 if (insname == NULL) 242 break; 243 i = 22; 244 while (i--) 245 insname[i] = buffer[i]; 246 insname[22] = 0; 247 } 248 break; 249 case TYPE_FT2: 250 if (mod->buflen > 80 + 73 * orders) { 251 buffer = mod->buf + 336; 252 limit = mod->buf + mod->buflen; 253 254 /* Processing patterns... */ 255 for (i = 0; i < orders; ++i) { 256 buffer += 7; 257 if (buffer + 1 >= limit) 258 break; 259 z = (uint16_t) (*(buffer++)); 260 z <<= 8; 261 z |= (uint16_t) (*(buffer++)); 262 z = bsLE16(z); 263 buffer += z; 264 } 265 266 if (buffer + 1 >= limit) 267 break; 268 269 /* Processing instruments... */ 270 for (i = 0; i < numinst; ++i) { 271 if (buffer + 29 >= limit) 272 break; 273 z = (uint16_t) (*(buffer + 27)); 274 z <<= 8; 275 z |= (uint16_t) (*(buffer + 28)); 276 z = bsLE16(z); 277 numsamples = (int) z; 278 279 /* Processing samples... */ 280 if (numsamples > 0) { 281 if ((buffer + 33) >= limit) 282 break; 283 memcpy(&Z, buffer + 29, 4); 284 Z = bsLE32(Z); 285 hlen = (unsigned int) Z; 286 287 buffer += 0x107; 288 289 G = 0; 290 for (j = 0; j < numsamples; ++j) { 291 if (buffer + 4 >= limit) 292 break; 293 memcpy(&Z, buffer, 4); 294 Z = bsLE32(Z); 295 296 buffer += 0x28; 297 G += Z; 298 } 299 300 buffer += G; 301 302 if (buffer >= limit) 303 break; 304 305 } else { 306 memcpy(&Z, buffer, 4); 307 Z = bsLE32(Z); 308 buffer += Z; 309 } 310 311 } 312 insname = NULL; 313 buffer += 4; 314 315 if (buffer + 23 >= limit) 316 break; 317 318 insname = (char *) malloc(23); 319 i = 22; 320 while (i--) 321 insname[i] = buffer[i]; 322 insname[22] = 0; 323 } 324 break; 325 } 326 327 return insname; 328 } 329 /* Fetch the module name into `buffer' */ 330 EXPORT void 331 module_name(MODULE * modfile, char *buffer) 332 { 333 int O; 334 int i; 335 336 O = 0; 337 switch (modfile->type) { 338 case TYPE_IMPULSE: 339 O = 4; 340 case TYPE_SCREAM_3: 341 strcpy(buffer, modfile->buf + O); 342 break; 343 case TYPE_FT2: 344 O = 17; 345 case TYPE_AMIGA_MOD: 346 i = 0; 347 memcpy(buffer, modfile->buf + O, 20); 348 buffer[20] = 0; 349 break; 350 } 351 352 return; 353 } 354 355 356 EXPORT short 357 module_type(MODULE * modfile) 358 { 359 return modfile->type; 360 } 361 362 EXPORT char * 363 module_typestr(short type) 364 { 365 switch (type) { 366 case TYPE_IMPULSE: 367 return "IT"; 368 break; 369 case TYPE_SCREAM_3: 370 return "S3M"; 371 break; 372 case TYPE_FT2: 373 return "XM"; 374 break; 375 case TYPE_AMIGA_MOD: 376 return "MOD"; 377 break; 378 default: 379 return "???"; 380 } 381 382 return NULL; 383 } 384 385 #ifdef MODINFO_DEBUG 386 #include <stdio.h> 387 #include <fcntl.h> 388 #include <unistd.h> 389 #include <sys/types.h> 390 391 char * 392 xm_retr_file(int fd, int *len) 393 { 394 char *buffer; 395 int buflen = 0; 396 int bytes_out = 0; 397 398 buffer = (char *) malloc(1024); 399 while ((bytes_out = read(fd, buffer + buflen, 1024)) != 0) { 400 if (bytes_out == -1) 401 break; 402 buflen += bytes_out; 403 buffer = (char *) realloc(buffer, 1024 + buflen); 404 if (buffer == NULL) 405 return NULL; 406 } 407 buffer = (char *) realloc(buffer, buflen); 408 if (buffer == NULL) 409 return NULL; 410 411 *len = buflen; 412 return buffer; 413 } 414 415 416 main(argc, argv) 417 char **argv; 418 { 419 int i; 420 char *buffer; 421 static char modname[128]; 422 MODULE mod; 423 int buflen; 424 int fd; 425 char *typ = NULL; 426 int ins; 427 428 if (argc < 2) 429 return 1; 430 431 fd = open(argv[1], O_RDONLY); 432 if (fd < 0) 433 return 1; 434 435 buffer = xm_retr_file(fd, &buflen); 436 437 if (buflen < 1) 438 return 1; 439 440 load_module(&mod, buffer, buflen); 441 442 switch (module_type(&mod)) { 443 case TYPE_IMPULSE: 444 typ = "Impulse Tracker"; 445 break; 446 case TYPE_SCREAM_3: 447 typ = "Scream Tracker 3"; 448 break; 449 case TYPE_FT2: 450 typ = "FastTracker II"; 451 break; 452 case TYPE_AMIGA_MOD: 453 typ = "ProTracker/NoiseTracker"; 454 break; 455 } 456 457 if (typ == NULL) 458 return 1; 459 460 module_name(&mod, modname); 461 462 printf("Kind : [%s module]\n", typ); 463 printf("Name : [%s]\n", modname); 464 printf("Has:\n\t%d orders\n\t%d instruments\nInstrument names:\n", 465 number_orders(&mod), 466 (ins = number_instruments(&mod)) 467 ); 468 469 for (i = 0; i < ins; ++i) { 470 typ = return_instrument_name(&mod, i); 471 printf("\t(%d) => [%s]\n", i, typ); 472 if (typ) 473 free(typ); 474 } 475 476 puts(""); 477 return 0; 478 } 479 #endif 480 481 /* 482 * @EOF@ -- revised May 6 2006 483 */ 484