shithub: dumb

Download patch

ref: 918d6366a57d34b63dd8144790f979cd9d2656f5
parent: d013643820c4fd4d1d80011bed52a047be46c9f1
author: Chris Moeller <kode54@gmail.com>
date: Sat Dec 22 13:39:41 EST 2012

Implemented simple 'any' format reader which attempts to detect the format of the input file and passes it off to the correct reader.

--- a/dumb/include/dumb.h
+++ b/dumb/include/dumb.h
@@ -441,6 +441,12 @@
 DUH *dumb_read_amf_quick(DUMBFILE *f);
 DUH *dumb_read_okt_quick(DUMBFILE *f);
 
+DUH *dumb_read_any_quick(DUMBFILE *f, int restrict, int subsong);
+DUH *dumb_read_any(DUMBFILE *f, int restrict, int subsong);
+
+DUH *dumb_load_any_quick(const char *filename, int restrict, int subsong);
+DUH *dumb_load_any(const char *filename, int restrict, int subsong);
+
 long dumb_it_build_checkpoints(DUMB_IT_SIGDATA *sigdata, int startorder);
 void dumb_it_do_initial_runthrough(DUH *duh);
 
--- /dev/null
+++ b/dumb/src/it/loadany.c
@@ -1,0 +1,38 @@
+/*  _______         ____    __         ___    ___
+ * \    _  \       \    /  \  /       \   \  /   /       '   '  '
+ *  |  | \  \       |  |    ||         |   \/   |         .      .
+ *  |  |  |  |      |  |    ||         ||\  /|  |
+ *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
+ *  |  |  |  |      |  |    ||         ||    |  |         .      .
+ *  |  |_/  /        \  \__//          ||    |  |
+ * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque
+ *                                                      /  \
+ *                                                     / .  \
+ * loadany.c - Code to detect and read any of the     / / \  \
+ *             module formats supported by DUMB,     | <  /   \_
+ *             opening and closing the file for you. |  \/ /\   /
+ *                                                    \_  /  > /
+ * By Chris Moeller.                                    | \ / /
+ *                                                      |  ' /
+ *                                                       \__/
+ */
+
+#include "dumb.h"
+#include "internal/it.h"
+
+
+
+DUH *dumb_load_any_quick(const char *filename, int restrict, int subsong)
+{
+	DUH *duh;
+	DUMBFILE *f = dumbfile_open(filename);
+
+	if (!f)
+		return NULL;
+
+    duh = dumb_read_any_quick(f, restrict, subsong);
+
+	dumbfile_close(f);
+
+	return duh;
+}
--- /dev/null
+++ b/dumb/src/it/loadany2.c
@@ -1,0 +1,29 @@
+/*  _______         ____    __         ___    ___
+ * \    _  \       \    /  \  /       \   \  /   /       '   '  '
+ *  |  | \  \       |  |    ||         |   \/   |         .      .
+ *  |  |  |  |      |  |    ||         ||\  /|  |
+ *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
+ *  |  |  |  |      |  |    ||         ||    |  |         .      .
+ *  |  |_/  /        \  \__//          ||    |  |
+ * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque
+ *                                                      /  \
+ *                                                     / .  \
+ * loadany2.c - Code to detect and read any of the    / / \  \
+ *              module formats supported by DUMB,    | <  /   \_
+ *              opening and closing the file for     |  \/ /\   /
+ *              you, and do an initial run-through.   \_  /  > /
+ *                                                      | \ / /
+ * by Chris Moeller.                                    |  ' /
+ *                                                       \__/
+ */
+
+#include "dumb.h"
+
+
+
+DUH *dumb_load_any(const char *filename, int restrict, int subsong)
+{
+    DUH *duh = dumb_load_any_quick(filename, restrict, subsong);
+	dumb_it_do_initial_runthrough(duh);
+	return duh;
+}
--- /dev/null
+++ b/dumb/src/it/readany.c
@@ -1,0 +1,337 @@
+/*  _______         ____    __         ___    ___
+ * \    _  \       \    /  \  /       \   \  /   /       '   '  '
+ *  |  | \  \       |  |    ||         |   \/   |         .      .
+ *  |  |  |  |      |  |    ||         ||\  /|  |
+ *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
+ *  |  |  |  |      |  |    ||         ||    |  |         .      .
+ *  |  |_/  /        \  \__//          ||    |  |
+ * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque
+ *                                                      /  \
+ *                                                     / .  \
+ * readany.c - Code to detect and read any of the     / / \  \
+ *             module formats supported by DUMB.     | <  /   \_
+ *                                                   |  \/ /\   /
+ * By Chris Moeller.                                  \_  /  > /
+ *                                                      | \ / /
+ *                                                      |  ' /
+ *                                                       \__/
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "dumb.h"
+
+#ifndef _MSC_VER
+#define strnicmp strncasecmp
+#endif
+
+typedef struct BUFFERED_MOD BUFFERED_MOD;
+
+struct BUFFERED_MOD
+{
+    unsigned char *buffered;
+    long ptr, len;
+    DUMBFILE *remaining;
+};
+
+
+
+static int buffer_mod_skip(void *f, long n)
+{
+    BUFFERED_MOD *bm = f;
+    if (bm->buffered) {
+        bm->ptr += n;
+        if (bm->ptr >= bm->len) {
+            free(bm->buffered);
+            bm->buffered = NULL;
+            return dumbfile_skip(bm->remaining, bm->ptr - bm->len);
+        }
+        return 0;
+    }
+    return dumbfile_skip(bm->remaining, n);
+}
+
+
+
+static int buffer_mod_getc(void *f)
+{
+    BUFFERED_MOD *bm = f;
+    if (bm->buffered) {
+        int rv = bm->buffered[bm->ptr++];
+        if (bm->ptr >= bm->len) {
+            free(bm->buffered);
+            bm->buffered = NULL;
+        }
+        return rv;
+    }
+    return dumbfile_getc(bm->remaining);
+}
+
+
+
+static long buffer_mod_getnc(char *ptr, long n, void *f)
+{
+    BUFFERED_MOD *bm = f;
+    if (bm->buffered) {
+        int left = bm->len - bm->ptr;
+        if (n >= left) {
+            memcpy(ptr, bm->buffered + bm->ptr, left);
+            free(bm->buffered);
+            bm->buffered = NULL;
+            if (n - left) {
+                int rv = dumbfile_getnc(ptr + left, n - left, bm->remaining);
+                return left + MAX(rv, 0);
+            } else {
+                return left;
+            }
+        }
+        memcpy(ptr, bm->buffered + bm->ptr, n);
+        bm->ptr += n;
+        return n;
+    }
+    return dumbfile_getnc(ptr, n, bm->remaining);
+}
+
+
+
+static void buffer_mod_close(void *f)
+{
+    BUFFERED_MOD *bm = f;
+    if (bm->buffered) free(bm->buffered);
+    /* Do NOT close bm->remaining */
+    free(f);
+}
+
+
+
+static DUMBFILE_SYSTEM buffer_mod_dfs = {
+    NULL,
+    &buffer_mod_skip,
+    &buffer_mod_getc,
+    &buffer_mod_getnc,
+    &buffer_mod_close
+};
+
+
+
+static DUMBFILE *dumbfile_buffer_mod(DUMBFILE *f, unsigned char const* * signature, unsigned long * signature_size)
+{
+    long read;
+    int sample_number;
+    BUFFERED_MOD *bm = malloc(sizeof(*bm));
+    unsigned char *ptr;
+    if (!bm) return NULL;
+
+    bm->buffered = malloc(32768);
+    if (!bm->buffered) {
+        free(bm);
+        return NULL;
+    }
+
+    bm->len = 0;
+    *signature_size = 0;
+
+    read = dumbfile_getnc(bm->buffered, 32768, f);
+
+    if (read >= 0) {
+        bm->len += read;
+        *signature_size += read;
+
+        while (read >= 32768) {
+            bm->buffered = realloc(bm->buffered, *signature_size + 32768);
+            if (!bm->buffered) {
+                free(bm);
+                return 0;
+            }
+            read = dumbfile_getnc(bm->buffered + *signature_size, 32768, f);
+            if (read >= 0) {
+                bm->len += read;
+                *signature_size += read;
+            }
+        }
+    }
+
+    if (*signature_size) {
+        bm->ptr = 0;
+        *signature = bm->buffered;
+    } else {
+        free(bm->buffered);
+        bm->buffered = NULL;
+    }
+
+    bm->remaining = f;
+
+    return dumbfile_open_ex(bm, &buffer_mod_dfs);
+}
+
+
+
+typedef struct tdumbfile_mem_status
+{
+    const unsigned char * ptr;
+    unsigned offset, size;
+} dumbfile_mem_status;
+
+
+
+static int dumbfile_mem_skip(void * f, long n)
+{
+    dumbfile_mem_status * s = (dumbfile_mem_status *) f;
+    s->offset += n;
+    if (s->offset > s->size)
+    {
+        s->offset = s->size;
+        return 1;
+    }
+
+    return 0;
+}
+
+
+
+static int dumbfile_mem_getc(void * f)
+{
+    dumbfile_mem_status * s = (dumbfile_mem_status *) f;
+    if (s->offset < s->size)
+    {
+        return *(s->ptr + s->offset++);
+    }
+    return -1;
+}
+
+
+
+static long dumbfile_mem_getnc(char * ptr, long n, void * f)
+{
+    dumbfile_mem_status * s = (dumbfile_mem_status *) f;
+    long max = s->size - s->offset;
+    if (max > n) max = n;
+    if (max)
+    {
+        memcpy(ptr, s->ptr + s->offset, max);
+        s->offset += max;
+    }
+    return max;
+}
+
+
+
+static DUMBFILE_SYSTEM mem_dfs = {
+    NULL, // open
+    &dumbfile_mem_skip,
+    &dumbfile_mem_getc,
+    &dumbfile_mem_getnc,
+    NULL // close
+};
+
+
+
+DUH *dumb_read_any_quick(DUMBFILE *f, int restrict, int subsong)
+{
+    unsigned char const* signature;
+    unsigned long signature_size;
+    DUMBFILE * rem;
+    DUH * duh = NULL;
+
+    rem = dumbfile_buffer_mod( f, &signature, &signature_size );
+    if ( !rem ) return NULL;
+
+    if (signature_size >= 4 &&
+        signature[0] == 'I' && signature[1] == 'M' &&
+        signature[2] == 'P' && signature[3] == 'M')
+    {
+        duh = dumb_read_it_quick( rem );
+    }
+    else if (signature_size >= 17 && !memcmp(signature, "Extended Module: ", 17))
+    {
+        duh = dumb_read_xm_quick( rem );
+    }
+    else if (signature_size >= 0x30 &&
+        signature[0x2C] == 'S' && signature[0x2D] == 'C' &&
+        signature[0x2E] == 'R' && signature[0x2F] == 'M')
+    {
+        duh = dumb_read_s3m_quick( rem );
+    }
+    else if (signature_size >= 30 &&
+        /*signature[28] == 0x1A &&*/ signature[29] == 2 &&
+        ( ! strnicmp( ( const char * ) signature + 20, "!Scream!", 8 ) ||
+        ! strnicmp( ( const char * ) signature + 20, "BMOD2STM", 8 ) ||
+        ! strnicmp( ( const char * ) signature + 20, "WUZAMOD!", 8 ) ) )
+    {
+        duh = dumb_read_stm_quick( rem );
+    }
+    else if (signature_size >= 2 &&
+        ((signature[0] == 0x69 && signature[1] == 0x66) ||
+        (signature[0] == 0x4A && signature[1] == 0x4E)))
+    {
+        duh = dumb_read_669_quick( rem );
+    }
+    else if (signature_size >= 0x30 &&
+        signature[0x2C] == 'P' && signature[0x2D] == 'T' &&
+        signature[0x2E] == 'M' && signature[0x2F] == 'F')
+    {
+        duh = dumb_read_ptm_quick( rem );
+    }
+    else if (signature_size >= 4 &&
+        signature[0] == 'P' && signature[1] == 'S' &&
+        signature[2] == 'M' && signature[3] == ' ')
+    {
+        duh = dumb_read_psm_quick( rem, subsong );
+    }
+    else if (signature_size >= 4 &&
+        signature[0] == 'P' && signature[1] == 'S' &&
+        signature[2] == 'M' && signature[3] == 254)
+    {
+        duh = dumb_read_old_psm_quick( rem );
+    }
+    else if (signature_size >= 3 &&
+        signature[0] == 'M' && signature[1] == 'T' &&
+        signature[2] == 'M')
+    {
+        duh = dumb_read_mtm_quick( rem );
+    }
+    else if ( signature_size >= 4 &&
+        signature[0] == 'R' && signature[1] == 'I' &&
+        signature[2] == 'F' && signature[3] == 'F')
+    {
+        duh = dumb_read_riff_quick( rem );
+    }
+    else if ( signature_size >= 24 &&
+        !memcmp( signature, "ASYLUM Music Format", 19 ) &&
+        !memcmp( signature + 19, " V1.0", 5 ) )
+    {
+        duh = dumb_read_asy_quick( rem );
+    }
+    else if ( signature_size >= 3 &&
+        signature[0] == 'A' && signature[1] == 'M' &&
+        signature[2] == 'F')
+    {
+        duh = dumb_read_amf_quick( rem );
+    }
+    else if ( signature_size >= 8 &&
+        !memcmp( signature, "OKTASONG", 8 ) )
+    {
+        duh = dumb_read_okt_quick( rem );
+    }
+
+    if ( !duh )
+    {
+        dumbfile_mem_status memdata;
+
+        memdata.ptr = signature;
+        memdata.offset = 0;
+        memdata.size = signature_size;
+
+        DUMBFILE * memf = dumbfile_open_ex(&memdata, &mem_dfs);
+        if ( memf )
+        {
+            duh = dumb_read_mod_quick( memf, restrict );
+            dumbfile_close( memf );
+        }
+    }
+
+    dumbfile_close( rem );
+
+    return duh;
+}
--- /dev/null
+++ b/dumb/src/it/readany2.c
@@ -1,0 +1,29 @@
+/*  _______         ____    __         ___    ___
+ * \    _  \       \    /  \  /       \   \  /   /       '   '  '
+ *  |  | \  \       |  |    ||         |   \/   |         .      .
+ *  |  |  |  |      |  |    ||         ||\  /|  |
+ *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
+ *  |  |  |  |      |  |    ||         ||    |  |         .      .
+ *  |  |_/  /        \  \__//          ||    |  |
+ * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque
+ *                                                      /  \
+ *                                                     / .  \
+ * readany2.c - Code to detect and read any of the    / / \  \
+ *              module formats supported by DUMB     | <  /   \_
+ *              from an open file and do an initial  |  \/ /\   /
+ *              run-through.                          \_  /  > /
+ *                                                      | \ / /
+ * by Chris Moeller.                                    |  ' /
+ *                                                       \__/
+ */
+
+#include "dumb.h"
+
+
+
+DUH *dumb_read_any(DUMBFILE *f, int restrict, int subsong)
+{
+    DUH *duh = dumb_read_any_quick(f, restrict, subsong);
+	dumb_it_do_initial_runthrough(duh);
+	return duh;
+}