ref: d8784727e4b117e77c9cf4ff609dace2c4d1da24
parent: 3267dd862062e755782f04eee5db47ef338fc5b8
author: Chris Moeller <kode54@gmail.com>
date: Mon Jan 14 14:06:08 EST 2013
Implemented full seeking in DUMBFILE and modified several readers to account for this change, which also reduces their overall memory usage
--- a/dumb/include/dumb.h
+++ b/dumb/include/dumb.h
@@ -160,6 +160,8 @@
int (*getc)(void *f);
long (*getnc)(char *ptr, long n, void *f);
void (*close)(void *f);
+ int (*seek)(void *f, long n);
+ long (*get_size)(void *f);
}
DUMBFILE_SYSTEM;
@@ -172,6 +174,14 @@
long dumbfile_pos(DUMBFILE *f);
int dumbfile_skip(DUMBFILE *f, long n);
+
+#define DFS_SEEK_SET 0
+#define DFS_SEEK_CUR 1
+#define DFS_SEEK_END 2
+
+int dumbfile_seek(DUMBFILE *f, long n, int origin);
+
+long dumbfile_get_size(DUMBFILE *f);
int dumbfile_getc(DUMBFILE *f);
--- a/dumb/include/internal/riff.h
+++ b/dumb/include/internal/riff.h
@@ -1,11 +1,14 @@
#ifndef RIFF_H
#define RIFF_H
+struct riff;
+
struct riff_chunk
{
unsigned type;
- void * data;
+ long offset;
unsigned size;
+ struct riff * nested;
};
struct riff
@@ -15,7 +18,7 @@
struct riff_chunk * chunks;
};
-struct riff * riff_parse( unsigned char *, unsigned size, unsigned proper );
+struct riff * riff_parse( DUMBFILE * f, long offset, long size, unsigned proper );
void riff_free( struct riff * );
#endif
--- a/dumb/src/core/dumbfile.c
+++ b/dumb/src/core/dumbfile.c
@@ -33,6 +33,8 @@
ASSERT(dfs->open);
ASSERT(dfs->getc);
ASSERT(dfs->close);
+ ASSERT(dfs->seek);
+ ASSERT(dfs->get_size);
the_dfs = dfs;
}
@@ -371,6 +373,26 @@
f->pos += rv;
return rv;
+}
+
+
+
+int dumbfile_seek(DUMBFILE *f, long n, int origin)
+{
+ switch ( origin )
+ {
+ case DFS_SEEK_CUR: n += f->pos; break;
+ case DFS_SEEK_END: n += (*f->dfs->get_size)(f->file); break;
+ }
+ f->pos = n;
+ return (*f->dfs->seek)(f->file, n);
+}
+
+
+
+long dumbfile_get_size(DUMBFILE *f)
+{
+ return (*f->dfs->get_size)(f->file);
}
--- a/dumb/src/helpers/riff.c
+++ b/dumb/src/helpers/riff.c
@@ -1,58 +1,57 @@
+#include "dumb.h"
#include "internal/riff.h"
#include <stdlib.h>
-struct riff * riff_parse( unsigned char * ptr, unsigned size, unsigned proper )
+struct riff * riff_parse( DUMBFILE * f, long offset, long size, unsigned proper )
{
unsigned stream_size;
struct riff * stream;
- if ( size < 8 ) return 0;
+ if ( size < 8 ) return 0;
- if ( ptr[0] != 'R' || ptr[1] != 'I' || ptr[2] != 'F' || ptr[3] != 'F' ) return 0;
+ if ( dumbfile_seek(f, offset, DFS_SEEK_SET) ) return 0;
+ if ( dumbfile_mgetl(f) != DUMB_ID('R','I','F','F') ) return 0;
- stream_size = ptr[4] | ( ptr[5] << 8 ) | ( ptr[6] << 16 ) | ( ptr[7] << 24 );
- if ( stream_size + 8 > size ) return 0;
+ stream_size = dumbfile_igetl(f);
+ if ( stream_size + 8 > size ) return 0;
if ( stream_size < 4 ) return 0;
- stream = malloc( sizeof( struct riff ) );
+ stream = (struct riff *) malloc( sizeof( struct riff ) );
if ( ! stream ) return 0;
- stream->type = ( ptr[8] << 24 ) | ( ptr[9] << 16 ) | ( ptr[10] << 8 ) | ptr[11];
+ stream->type = dumbfile_mgetl(f);
stream->chunk_count = 0;
stream->chunks = 0;
- ptr += 12;
stream_size -= 4;
- while ( stream_size )
+ while ( stream_size && !dumbfile_error(f) )
{
struct riff_chunk * chunk;
if ( stream_size < 8 ) break;
- stream->chunks = realloc( stream->chunks, ( stream->chunk_count + 1 ) * sizeof( struct riff_chunk ) );
+ stream->chunks = ( struct riff_chunk * ) realloc( stream->chunks, ( stream->chunk_count + 1 ) * sizeof( struct riff_chunk ) );
if ( ! stream->chunks ) break;
chunk = stream->chunks + stream->chunk_count;
- chunk->type = ( ptr[0] << 24 ) | ( ptr[1] << 16 ) | ( ptr[2] << 8 ) | ptr[3];
- chunk->size = ptr[4] | ( ptr[5] << 8 ) | ( ptr[6] << 16 ) | ( ptr[7] << 24 );
- ptr += 8;
+ chunk->type = dumbfile_mgetl(f);
+ chunk->size = dumbfile_igetl(f);
+ chunk->offset = dumbfile_pos(f);
stream_size -= 8;
if ( stream_size < chunk->size ) break;
- if ( chunk->type == 'RIFF' )
+ if ( chunk->type == DUMB_ID('R','I','F','F') )
{
- chunk->data = riff_parse( ptr - 8, chunk->size + 8, proper );
- if ( ! chunk->data ) break;
+ chunk->nested = riff_parse( f, chunk->offset - 8, chunk->size + 8, proper );
+ if ( ! chunk->nested ) break;
}
else
{
- chunk->data = malloc( chunk->size );
- if ( ! chunk->data ) break;
- memcpy( chunk->data, ptr, chunk->size );
+ chunk->nested = 0;
}
- ptr += chunk->size;
+ dumbfile_seek(f, chunk->offset + chunk->size, DFS_SEEK_SET);
stream_size -= chunk->size;
if ( proper && ( chunk->size & 1 ) )
{
- ++ ptr;
+ dumbfile_skip(f, 1);
-- stream_size;
}
++stream->chunk_count;
@@ -77,8 +76,7 @@
for ( i = 0; i < stream->chunk_count; ++i )
{
struct riff_chunk * chunk = stream->chunks + i;
- if ( chunk->type == 'RIFF' ) riff_free( ( struct riff * ) chunk->data );
- else free( chunk->data );
+ if ( chunk->nested ) riff_free( chunk->nested );
}
free( stream->chunks );
}
--- a/dumb/src/helpers/stdfile.c
+++ b/dumb/src/helpers/stdfile.c
@@ -23,9 +23,23 @@
+typedef struct dumb_stdfile
+{
+ FILE * file;
+ long size;
+} dumb_stdfile;
+
+
+
static void *dumb_stdfile_open(const char *filename)
{
- return fopen(filename, "rb");
+ dumb_stdfile * file = ( dumb_stdfile * ) malloc( sizeof(dumb_stdfile) );
+ if ( !file ) return 0;
+ file->file = fopen(filename, "rb");
+ fseek(file->file, 0, SEEK_END);
+ file->size = ftell(file->file);
+ fseek(file->file, 0, SEEK_SET);
+ return file;
}
@@ -32,7 +46,8 @@
static int dumb_stdfile_skip(void *f, long n)
{
- return fseek(f, n, SEEK_CUR);
+ dumb_stdfile * file = ( dumb_stdfile * ) f;
+ return fseek(file->file, n, SEEK_CUR);
}
@@ -39,7 +54,8 @@
static int dumb_stdfile_getc(void *f)
{
- return fgetc(f);
+ dumb_stdfile * file = ( dumb_stdfile * ) f;
+ return fgetc(file->file);
}
@@ -46,7 +62,8 @@
static long dumb_stdfile_getnc(char *ptr, long n, void *f)
{
- return fread(ptr, 1, n, f);
+ dumb_stdfile * file = ( dumb_stdfile * ) f;
+ return fread(ptr, 1, n, file->file);
}
@@ -53,17 +70,44 @@
static void dumb_stdfile_close(void *f)
{
- fclose(f);
+ dumb_stdfile * file = ( dumb_stdfile * ) f;
+ fclose(file->file);
+ free(f);
}
+static void dumb_stdfile_noclose(void *f)
+{
+ free(f);
+}
+
+
+
+static int dumb_stdfile_seek(void *f, long n)
+{
+ dumb_stdfile * file = ( dumb_stdfile * ) f;
+ return fseek(file->file, n, SEEK_SET);
+}
+
+
+
+static long dumb_stdfile_get_size(void *f)
+{
+ dumb_stdfile * file = ( dumb_stdfile * ) f;
+ return file->size;
+}
+
+
+
static const DUMBFILE_SYSTEM stdfile_dfs = {
&dumb_stdfile_open,
&dumb_stdfile_skip,
&dumb_stdfile_getc,
&dumb_stdfile_getnc,
- &dumb_stdfile_close
+ &dumb_stdfile_close,
+ &dumb_stdfile_seek,
+ &dumb_stdfile_get_size
};
@@ -80,7 +124,9 @@
&dumb_stdfile_skip,
&dumb_stdfile_getc,
&dumb_stdfile_getnc,
- NULL
+ &dumb_stdfile_noclose,
+ &dumb_stdfile_seek,
+ &dumb_stdfile_get_size
};
@@ -87,7 +133,13 @@
DUMBFILE *dumbfile_open_stdfile(FILE *p)
{
- DUMBFILE *d = dumbfile_open_ex(p, &stdfile_dfs_leave_open);
+ dumb_stdfile * file = ( dumb_stdfile * ) malloc( sizeof(dumb_stdfile) );
+ if ( !file ) return 0;
+ file->file = p;
+ fseek(p, 0, SEEK_END);
+ file->size = ftell(p);
+ fseek(p, 0, SEEK_SET);
+ DUMBFILE *d = dumbfile_open_ex(file, &stdfile_dfs_leave_open);
return d;
}
--- a/dumb/src/it/itread.c
+++ b/dumb/src/it/itread.c
@@ -32,78 +32,6 @@
-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
-};
-
-
-
-static int it_seek(dumbfile_mem_status * s, long offset)
-{
- if ( offset > s->size )
- return -1;
-
- s->offset = offset;
-
- return 0;
-}
-
-
-
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned long dword;
@@ -1013,47 +941,8 @@
unsigned char *buffer;
- unsigned char *file_buffer = NULL;
- unsigned int file_size = 0;
- int block_size;
-
- dumbfile_mem_status memdata;
-
- do
- {
- void * temp = realloc( file_buffer, file_size + 32768 );
- if ( !temp )
- {
- if ( file_buffer ) free( file_buffer );
- return NULL;
- }
- file_buffer = temp;
- block_size = dumbfile_getnc( file_buffer + file_size, 32768, f );
- if ( block_size < 0 )
- {
- free( file_buffer );
- return NULL;
- }
- file_size += block_size;
- }
- while ( block_size == 32768 );
-
- memdata.ptr = file_buffer;
- memdata.offset = 0;
- memdata.size = file_size;
-
- f = dumbfile_open_ex(&memdata, &mem_dfs);
-
- if ( !f )
- {
- free( file_buffer );
- return NULL;
- }
-
if (dumbfile_mgetl(f) != IT_SIGNATURE)
{
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
@@ -1061,8 +950,6 @@
if (!sigdata)
{
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
@@ -1113,8 +1000,6 @@
// XXX sample count
if (dumbfile_error(f) || sigdata->n_orders <= 0 || sigdata->n_instruments > 256 || sigdata->n_samples > 4000 || sigdata->n_patterns > 256) {
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
@@ -1121,8 +1006,6 @@
sigdata->order = malloc(sigdata->n_orders);
if (!sigdata->order) {
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
@@ -1130,8 +1013,6 @@
sigdata->instrument = malloc(sigdata->n_instruments * sizeof(*sigdata->instrument));
if (!sigdata->instrument) {
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
}
@@ -1140,8 +1021,6 @@
sigdata->sample = malloc(sigdata->n_samples * sizeof(*sigdata->sample));
if (!sigdata->sample) {
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
for (n = 0; n < sigdata->n_samples; n++)
@@ -1152,8 +1031,6 @@
sigdata->pattern = malloc(sigdata->n_patterns * sizeof(*sigdata->pattern));
if (!sigdata->pattern) {
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
for (n = 0; n < sigdata->n_patterns; n++)
@@ -1166,8 +1043,6 @@
component = malloc(769 * sizeof(*component));
if (!component) {
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
@@ -1212,8 +1087,6 @@
if (dumbfile_error(f)) {
free(component);
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
@@ -1234,8 +1107,6 @@
if (!sigdata->midi) {
free(component);
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
// Should we be happy with this outcome in some situations?
}
@@ -1244,8 +1115,6 @@
if (dumbfile_error(f) || dumbfile_skip(f, 8*i)) {
free(component);
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
/* Read embedded MIDI configuration */
@@ -1253,8 +1122,6 @@
if (dumbfile_skip(f, 32*9)) {
free(component);
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
for (i = 0; i < 16; i++) {
@@ -1263,8 +1130,6 @@
if (dumbfile_getnc(mididata, 32, f) < 32) {
free(component);
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
sigdata->midi->SFmacroz[i] = 0;
@@ -1326,8 +1191,6 @@
if (!buffer) {
free(component);
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
@@ -1356,12 +1219,10 @@
continue;
}
- if (it_seek(&memdata, component[n].offset)) {
+ if (dumbfile_seek(f, component[n].offset, DFS_SEEK_SET)) {
free(buffer);
free(component);
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
@@ -1377,8 +1238,6 @@
free(buffer);
free(component);
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
sigdata->song_message[message_length] = 0;
@@ -1395,8 +1254,6 @@
free(buffer);
free(component);
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
break;
@@ -1406,8 +1263,6 @@
free(buffer);
free(component);
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
break;
@@ -1417,8 +1272,6 @@
free(buffer);
free(component);
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
@@ -1445,12 +1298,10 @@
m = component[n].sampfirst;
while (m >= 0) {
- if (it_seek(&memdata, component[m].offset)) {
+ if (dumbfile_seek(f, component[m].offset, DFS_SEEK_SET)) {
free(buffer);
free(component);
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
@@ -1458,8 +1309,6 @@
free(buffer);
free(component);
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- free(file_buffer);
return NULL;
}
@@ -1503,7 +1352,7 @@
}
mptx_id = dumbfile_igetl( f );
- while ( memdata.offset < file_size )
+ while ( dumbfile_pos(f) < dumbfile_get_size(f) )
{
unsigned int size = dumbfile_igetw( f );
switch (mptx_id)
@@ -1527,9 +1376,6 @@
free(buffer);
free(component);
-
- dumbfile_close(f);
- free(file_buffer);
_dumb_it_fix_invalid_orders(sigdata);
--- a/dumb/src/it/readam.c
+++ b/dumb/src/it/readam.c
@@ -24,7 +24,7 @@
#include "internal/it.h"
#include "internal/riff.h"
-static int it_riff_am_process_sample( IT_SAMPLE * sample, const unsigned char * data, int len, int ver )
+static int it_riff_am_process_sample( IT_SAMPLE * sample, DUMBFILE * f, int len, int ver )
{
int header_length;
int default_pan;
@@ -34,49 +34,51 @@
int length_bytes;
int loop_start;
int loop_end;
- int sample_rate;
+ int sample_rate;
+ long start = dumbfile_pos( f );
+
if ( ver == 0 )
- {
+ {
if ( len < 0x38 )
return -1;
header_length = 0x38;
- memcpy( sample->name, data, 28 );
+ dumbfile_getnc( sample->name, 28, f );
sample->name[ 28 ] = 0;
- default_pan = data[ 0x1C ];
- default_volume = data[ 0x1D ];
- flags = data[ 0x1E ] | ( data[ 0x1F ] << 8 );
- length = data[ 0x20 ] | ( data[ 0x21 ] << 8 ) | ( data[ 0x22 ] << 16 ) | ( data[ 0x23 ] << 24 );
- loop_start = data[ 0x24 ] | ( data[ 0x25 ] << 8 ) | ( data[ 0x26 ] << 16 ) | ( data[ 0x27 ] << 24 );
- loop_end = data[ 0x28 ] | ( data[ 0x29 ] << 8 ) | ( data[ 0x2A ] << 16 ) | ( data[ 0x2B ] << 24 );
- sample_rate = data[ 0x2C ] | ( data[ 0x2D ] << 8 ) | ( data[ 0x2E ] << 16 ) | ( data[ 0x2F ] << 24 );
+ default_pan = dumbfile_getc( f );
+ default_volume = dumbfile_getc( f );
+ flags = dumbfile_igetw( f );
+ length = dumbfile_igetl( f );
+ loop_start = dumbfile_igetl( f );
+ loop_end = dumbfile_igetl( f );
+ sample_rate = dumbfile_igetl( f );
}
else
{
if (len < 4) return -1;
- header_length = data[ 0 ] | ( data[ 1 ] << 8 ) | ( data[ 2 ] << 16 ) | ( data[ 3 ] << 24 );
+ header_length = dumbfile_igetl( f );
if ( header_length < 0x40 )
return -1;
if ( header_length + 4 > len )
return -1;
- data += 4;
+ start += 4;
len -= 4;
- memcpy( sample->name, data, 32 );
- sample->name[ 32 ] = 0;
+ dumbfile_getnc( sample->name, 32, f );
- default_pan = data[ 0x20 ] | ( data[ 0x21 ] << 8 );
- default_volume = data[ 0x22 ] | ( data[ 0x23 ] << 8 );
- flags = data[ 0x24 ] | ( data[ 0x25 ] << 8 ); /* | ( data[ 0x26 ] << 16 ) | ( data[ 0x27 ] << 24 );*/
- length = data[ 0x28 ] | ( data[ 0x29 ] << 8 ) | ( data[ 0x2A ] << 16 ) | ( data[ 0x2B ] << 24 );
- loop_start = data[ 0x2C ] | ( data[ 0x2D ] << 8 ) | ( data[ 0x2E ] << 16 ) | ( data[ 0x2F ] << 24 );
- loop_end = data[ 0x30 ] | ( data[ 0x31 ] << 8 ) | ( data[ 0x32 ] << 16 ) | ( data[ 0x33 ] << 24 );
- sample_rate = data[ 0x34 ] | ( data[ 0x35 ] << 8 ) | ( data[ 0x36 ] << 16 ) | ( data[ 0x37 ] << 24 );
+ default_pan = dumbfile_igetw( f );
+ default_volume = dumbfile_igetw( f );
+ flags = dumbfile_igetw( f );
+ dumbfile_skip( f, 2 );
+ length = dumbfile_igetl( f );
+ loop_start = dumbfile_igetl( f );
+ loop_end = dumbfile_igetl( f );
+ sample_rate = dumbfile_igetl( f );
if ( default_pan > 0x7FFF || default_volume > 0x7FFF )
return -1;
@@ -85,9 +87,6 @@
default_volume = default_volume * 64 / 32767;
}
- /*if ( data[ 0x38 ] || data[ 0x39 ] || data[ 0x3A ] || data[ 0x3B ] )
- return -1;*/
-
if ( ! length ) {
sample->flags &= ~IT_SAMPLE_EXISTS;
return 0;
@@ -138,43 +137,49 @@
if ( ! sample->data )
return -1;
- memcpy( sample->data, data + header_length, length_bytes );
+ if ( dumbfile_seek( f, start + header_length, DFS_SEEK_SET ) )
+ return -1;
+ dumbfile_getnc( sample->data, length_bytes, f );
+
return 0;
}
-static int it_riff_am_process_pattern( IT_PATTERN * pattern, const unsigned char * data, int len, int ver )
+static int it_riff_am_process_pattern( IT_PATTERN * pattern, DUMBFILE * f, int len, int ver )
{
- int nrows, row, pos;
+ int nrows, row;
+ long start, end;
unsigned flags;
+ int p, q, r;
IT_ENTRY * entry;
- nrows = data[0] + 1;
+ nrows = dumbfile_getc( f ) + 1;
pattern->n_rows = nrows;
- data += 1;
len -= 1;
pattern->n_entries = 0;
row = 0;
- pos = 0;
- while ( (row < nrows) && (pos < len) ) {
- if ( ! data[ pos ] ) {
+ start = dumbfile_pos( f );
+ end = start + len;
+
+ while ( (row < nrows) && (dumbfile_pos( f ) < end) ) {
+ p = dumbfile_getc( f );
+ if ( ! p ) {
++ row;
- ++ pos;
continue;
}
- flags = data[ pos++ ] & 0xE0;
+ flags = p & 0xE0;
- if (flags) {
+ if (flags) {
++ pattern->n_entries;
- if (flags & 0x80) pos += 2;
- if (flags & 0x40) pos += 2;
- if (flags & 0x20) pos ++;
+ if (flags & 0x80) dumbfile_skip( f, 2 );
+ if (flags & 0x40) dumbfile_skip( f, 2 );
+ if (flags & 0x20) dumbfile_skip( f, 1 );
}
}
@@ -188,20 +193,22 @@
entry = pattern->entry;
row = 0;
- pos = 0;
- while ( ( row < nrows ) && ( pos < len ) )
+ dumbfile_seek( f, start, DFS_SEEK_SET );
+
+ while ( ( row < nrows ) && ( dumbfile_pos( f ) < end ) )
{
- if ( ! data[ pos ] )
+ p = dumbfile_getc( f );
+
+ if ( ! p )
{
IT_SET_END_ROW( entry );
++ entry;
++ row;
- ++ pos;
continue;
}
- flags = data[ pos++ ];
+ flags = p;
entry->channel = flags & 0x1F;
entry->mask = 0;
@@ -209,31 +216,33 @@
{
if ( flags & 0x80 )
{
- _dumb_it_xm_convert_effect( data[ pos + 1 ], data[ pos ], entry, 0 );
- pos += 2;
+ q = dumbfile_getc( f );
+ r = dumbfile_getc( f );
+ _dumb_it_xm_convert_effect( r, q, entry, 0 );
}
if ( flags & 0x40 )
{
- if ( data[ pos ] )
+ q = dumbfile_getc( f );
+ r = dumbfile_getc( f );
+ if ( q )
{
entry->mask |= IT_ENTRY_INSTRUMENT;
- entry->instrument = data[ pos ];
+ entry->instrument = q;
}
- if ( data[ pos + 1 ] )
+ if ( r )
{
entry->mask |= IT_ENTRY_NOTE;
- entry->note = data[ pos + 1 ] - 1;
+ entry->note = r - 1;
}
- pos += 2;
}
if ( flags & 0x20 )
{
+ q = dumbfile_getc( f );
entry->mask |= IT_ENTRY_VOLPAN;
- if ( ver == 0 ) entry->volpan = data[ pos ];
- else entry->volpan = data[ pos ] * 64 / 127;
- ++ pos;
+ if ( ver == 0 ) entry->volpan = q;
+ else entry->volpan = q * 64 / 127;
}
if (entry->mask) entry++;
@@ -253,11 +262,11 @@
return 0;
}
-static DUMB_IT_SIGDATA *it_riff_amff_load_sigdata( struct riff * stream )
+static DUMB_IT_SIGDATA *it_riff_amff_load_sigdata( DUMBFILE * f, struct riff * stream )
{
DUMB_IT_SIGDATA *sigdata;
- int n, o, found;
+ int n, o, p, found;
unsigned char * ptr;
@@ -290,10 +299,11 @@
found |= 2;
break;
- case DUMB_ID( 'P', 'A', 'T', 'T' ):
- ptr = ( unsigned char * ) c->data;
- if ( ptr[ 0 ] >= sigdata->n_patterns ) sigdata->n_patterns = ptr[ 0 ] + 1;
- o = ptr[ 1 ] | ( ptr[ 2 ] << 8 ) | ( ptr[ 3 ] << 16 ) | ( ptr[ 4 ] << 24 );
+ case DUMB_ID( 'P', 'A', 'T', 'T' ):
+ if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_sd;
+ o = dumbfile_getc( f );
+ if ( o >= sigdata->n_patterns ) sigdata->n_patterns = o + 1;
+ o = dumbfile_igetl( f );
if ( o + 5 > c->size ) goto error_sd;
break;
@@ -300,13 +310,17 @@
case DUMB_ID( 'I', 'N', 'S', 'T' ):
{
if ( c->size < 0xE1 ) goto error;
- ptr = ( unsigned char * ) c->data;
- if ( ptr[ 1 ] >= sigdata->n_samples ) sigdata->n_samples = ptr[ 1 ] + 1;
- if ( c->size >= 0x121 && ( ptr[ 0xE1 ] == 'S' && ptr[ 0xE2 ] == 'A' &&
- ptr[ 0xE3 ] == 'M' && ptr[ 0xE4 ] == 'P' ) )
- {
- unsigned size = ptr[ 0xE5 ] | ( ptr[ 0xE6 ] << 8 ) | ( ptr[ 0xE7 ] << 16 ) | ( ptr[ 0xE8 ] << 24 );
- if ( size + 0xE1 + 8 > c->size ) goto error;
+ if ( dumbfile_seek( f, c->offset + 1, DFS_SEEK_SET ) ) goto error_sd;
+ o = dumbfile_getc( f );
+ if ( o >= sigdata->n_samples ) sigdata->n_samples = o + 1;
+ if ( c->size >= 0x121 )
+ {
+ if ( dumbfile_seek( f, c->offset + 0xE1, DFS_SEEK_SET ) ) goto error_sd;
+ if ( dumbfile_mgetl( f ) == DUMB_ID('S','A','M','P') )
+ {
+ unsigned size = dumbfile_igetl( f );
+ if ( size + 0xE1 + 8 > c->size ) goto error_sd;
+ }
}
}
break;
@@ -347,24 +361,28 @@
switch ( c->type )
{
case DUMB_ID( 'M', 'A', 'I', 'N' ):
- ptr = ( unsigned char * ) c->data;
- memcpy( sigdata->name, c->data, 64 );
+ if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_usd;
+ dumbfile_getnc( sigdata->name, 64, f );
sigdata->name[ 64 ] = 0;
sigdata->flags = IT_STEREO | IT_OLD_EFFECTS | IT_COMPATIBLE_GXX | IT_WAS_AN_S3M;
- if ( ! ( ptr[ 0x40 ] & 1 ) ) sigdata->flags |= IT_LINEAR_SLIDES;
- if ( ( ptr[ 0x40 ] & ~3 ) || ! ( ptr[ 0x40 ] & 2 ) ) goto error_usd; // unknown flags
- sigdata->n_pchannels = ptr[ 0x41 ];
- sigdata->speed = ptr[ 0x42 ];
- sigdata->tempo = ptr[ 0x43 ];
+ o = dumbfile_getc( f );
+ if ( ! ( o & 1 ) ) sigdata->flags |= IT_LINEAR_SLIDES;
+ if ( ( o & ~3 ) || ! ( o & 2 ) ) goto error_usd; // unknown flags
+ sigdata->n_pchannels = dumbfile_getc( f );
+ sigdata->speed = dumbfile_getc( f );
+ sigdata->tempo = dumbfile_getc( f );
- sigdata->global_volume = ptr[ 0x48 ];
+ dumbfile_skip( f, 4 );
+ sigdata->global_volume = dumbfile_getc( f );
+
if ( c->size < 0x48 + sigdata->n_pchannels ) goto error_usd;
for ( o = 0; o < sigdata->n_pchannels; ++o )
{
- sigdata->channel_pan[ o ] = ptr[ 0x49 + o ];
- if ( ptr[ 0x49 + o ] >= 128 )
+ p = dumbfile_getc( f );
+ sigdata->channel_pan[ o ] = p;
+ if ( p >= 128 )
{
sigdata->channel_volume[ o ] = 0;
}
@@ -394,37 +412,40 @@
switch ( c->type )
{
case DUMB_ID( 'O', 'R', 'D', 'R' ):
- ptr = ( unsigned char * ) c->data;
- sigdata->n_orders = ptr[ 0 ] + 1;
+ if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_usd;
+ sigdata->n_orders = dumbfile_getc( f ) + 1;
if ( sigdata->n_orders + 1 > c->size ) goto error_usd;
sigdata->order = malloc( sigdata->n_orders );
if ( ! sigdata->order ) goto error_usd;
- memcpy( sigdata->order, ptr + 1, sigdata->n_orders );
+ dumbfile_getnc( sigdata->order, sigdata->n_orders, f );
break;
case DUMB_ID( 'P', 'A', 'T', 'T' ):
- ptr = ( unsigned char * ) c->data;
- o = ptr[ 1 ] | ( ptr[ 2 ] << 8 ) | ( ptr[ 3 ] << 16 ) | ( ptr[ 4 ] << 24 );
- if ( it_riff_am_process_pattern( sigdata->pattern + ptr[ 0 ], ptr + 5, o, 0 ) ) goto error_usd;
+ if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_usd;
+ o = dumbfile_getc( f );
+ p = dumbfile_igetl( f );
+ if ( it_riff_am_process_pattern( sigdata->pattern + o, f, p, 0 ) ) goto error_usd;
break;
case DUMB_ID( 'I', 'N', 'S', 'T' ):
{
IT_SAMPLE * sample;
- ptr = ( unsigned char * ) c->data;
- sample = sigdata->sample + ptr[ 1 ];
- if ( c->size >= 0x121 && ( ptr[ 0xE1 ] == 'S' && ptr[ 0xE2 ] == 'A' &&
- ptr[ 0xE3 ] == 'M' && ptr[ 0xE4 ] == 'P' ) )
- {
- unsigned size = ptr[ 0xE5 ] | ( ptr[ 0xE6 ] << 8 ) | ( ptr[ 0xE7 ] << 16 ) | ( ptr[ 0xE8 ] << 24 );
- if ( it_riff_am_process_sample( sample, ptr + 0xE1 + 8, size, 0 ) ) goto error_usd;
+ if ( dumbfile_seek( f, c->offset + 1, DFS_SEEK_SET ) ) goto error_usd;
+ sample = sigdata->sample + dumbfile_getc( f );
+ if ( c->size >= 0x121 )
+ {
+ if ( dumbfile_seek( f, c->offset + 0xE1, DFS_SEEK_SET ) ) goto error_usd;
+ if ( dumbfile_mgetl( f ) == DUMB_ID('S','A','M','P') )
+ {
+ unsigned size = dumbfile_igetl( f );
+ if ( it_riff_am_process_sample( sample, f, size, 0 ) ) goto error_usd;
+ break;
+ }
}
- else
- {
- memcpy( sample->name, ptr + 2, 28 );
- sample->name[ 28 ] = 0;
- }
- }
+ dumbfile_seek( f, c->offset + 2, DFS_SEEK_SET );
+ dumbfile_getnc( sample->name, 28, f );
+ sample->name[ 28 ] = 0;
+ }
break;
}
}
@@ -442,7 +463,7 @@
return NULL;
}
-static DUMB_IT_SIGDATA *it_riff_am_load_sigdata( struct riff * stream )
+static DUMB_IT_SIGDATA *it_riff_am_load_sigdata( DUMBFILE * f, struct riff * stream )
{
DUMB_IT_SIGDATA *sigdata;
@@ -450,7 +471,7 @@
unsigned char * ptr;
- if ( ! stream ) goto error;
+ if ( ! f || ! stream ) goto error;
if ( stream->type != DUMB_ID( 'A', 'M', ' ', ' ' ) ) goto error;
@@ -480,15 +501,16 @@
break;
case DUMB_ID( 'P', 'A', 'T', 'T' ):
- ptr = ( unsigned char * ) c->data;
- if ( ptr[ 0 ] >= sigdata->n_patterns ) sigdata->n_patterns = ptr[ 0 ] + 1;
- o = ptr[ 1 ] | ( ptr[ 2 ] << 8 ) | ( ptr[ 3 ] << 16 ) | ( ptr[ 4 ] << 24 );
+ if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_sd;
+ o = dumbfile_getc( f );
+ if ( o >= sigdata->n_patterns ) sigdata->n_patterns = o + 1;
+ o = dumbfile_igetl( f );
if ( o + 5 > c->size ) goto error_sd;
break;
case DUMB_ID( 'R', 'I', 'F', 'F' ):
{
- struct riff * str = ( struct riff * ) c->data;
+ struct riff * str = c->nested;
switch ( str->type )
{
case DUMB_ID( 'A', 'I', ' ', ' ' ):
@@ -502,12 +524,14 @@
struct riff * temp;
unsigned size;
unsigned sample_found;
- ptr = ( unsigned char * ) chk->data;
- size = ptr[ 0 ] | ( ptr[ 1 ] << 8 ) | ( ptr[ 2 ] << 16 ) | ( ptr[ 3 ] << 24 );
- if ( size < 0x142 ) goto error;
+ if ( dumbfile_seek( f, chk->offset, DFS_SEEK_SET ) ) goto error_sd;
+ size = dumbfile_igetl( f );
+ if ( size < 0x142 ) goto error_sd;
sample_found = 0;
- if ( ptr[ 5 ] >= sigdata->n_samples ) sigdata->n_samples = ptr[ 5 ] + 1;
- temp = riff_parse( ptr + 4 + size, chk->size - size - 4, 1 );
+ dumbfile_skip( f, 1 );
+ p = dumbfile_getc( f );
+ if ( p >= sigdata->n_samples ) sigdata->n_samples = p + 1;
+ temp = riff_parse( f, chk->offset + 4 + size, chk->size - size - 4, 1 );
if ( temp )
{
if ( temp->type == DUMB_ID( 'A', 'S', ' ', ' ' ) )
@@ -519,7 +543,7 @@
if ( sample_found )
{
riff_free( temp );
- goto error;
+ goto error_sd;
}
sample_found = 1;
}
@@ -570,25 +594,29 @@
switch ( c->type )
{
case DUMB_ID( 'I', 'N', 'I', 'T' ):
- ptr = ( unsigned char * ) c->data;
- memcpy( sigdata->name, c->data, 64 );
+ if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_usd;
+ dumbfile_getnc( sigdata->name, 64, f );
sigdata->name[ 64 ] = 0;
sigdata->flags = IT_STEREO | IT_OLD_EFFECTS | IT_COMPATIBLE_GXX | IT_WAS_AN_S3M;
- if ( ! ( ptr[ 0x40 ] & 1 ) ) sigdata->flags |= IT_LINEAR_SLIDES;
- if ( ( ptr[ 0x40 ] & ~3 ) || ! ( ptr[ 0x40 ] & 2 ) ) goto error_usd; // unknown flags
- sigdata->n_pchannels = ptr[ 0x41 ];
- sigdata->speed = ptr[ 0x42 ];
- sigdata->tempo = ptr[ 0x43 ];
+ o = dumbfile_getc( f );
+ if ( ! ( o & 1 ) ) sigdata->flags |= IT_LINEAR_SLIDES;
+ if ( ( o & ~3 ) || ! ( o & 2 ) ) goto error_usd; // unknown flags
+ sigdata->n_pchannels = dumbfile_getc( f );
+ sigdata->speed = dumbfile_getc( f );
+ sigdata->tempo = dumbfile_getc( f );
- sigdata->global_volume = ptr[ 0x48 ];
+ dumbfile_skip( f, 4 );
+ sigdata->global_volume = dumbfile_getc( f );
+
if ( c->size < 0x48 + sigdata->n_pchannels ) goto error_usd;
for ( o = 0; o < sigdata->n_pchannels; ++o )
{
- if ( ptr[ 0x49 + o ] <= 128 )
+ p = dumbfile_getc( f );
+ if ( p <= 128 )
{
- sigdata->channel_pan[ o ] = ptr[ 0x49 + o ] / 2;
+ sigdata->channel_pan[ o ] = p / 2;
}
else
{
@@ -620,23 +648,24 @@
switch ( c->type )
{
case DUMB_ID( 'O', 'R', 'D', 'R' ):
- ptr = ( unsigned char * ) c->data;
- sigdata->n_orders = ptr[ 0 ] + 1;
+ if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_usd;
+ sigdata->n_orders = dumbfile_getc( f ) + 1;
if ( sigdata->n_orders + 1 > c->size ) goto error_usd;
sigdata->order = malloc( sigdata->n_orders );
if ( ! sigdata->order ) goto error_usd;
- memcpy( sigdata->order, ptr + 1, sigdata->n_orders );
+ dumbfile_getnc( sigdata->order, sigdata->n_orders, f );
break;
case DUMB_ID( 'P', 'A', 'T', 'T' ):
- ptr = ( unsigned char * ) c->data;
- o = ptr[ 1 ] | ( ptr[ 2 ] << 8 ) | ( ptr[ 3 ] << 16 ) | ( ptr[ 4 ] << 24 );
- if ( it_riff_am_process_pattern( sigdata->pattern + ptr[ 0 ], ptr + 5, o, 1 ) ) goto error_usd;
+ if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_usd;
+ o = dumbfile_getc( f );
+ p = dumbfile_igetl( f );
+ if ( it_riff_am_process_pattern( sigdata->pattern + o, f, p, 1 ) ) goto error_usd;
break;
case DUMB_ID( 'R', 'I', 'F', 'F' ):
{
- struct riff * str = ( struct riff * ) c->data;
+ struct riff * str = c->nested;
switch ( str->type )
{
case DUMB_ID('A', 'I', ' ', ' '):
@@ -651,11 +680,13 @@
unsigned size;
unsigned sample_found;
IT_SAMPLE * sample;
- ptr = ( unsigned char * ) chk->data;
- size = ptr[ 0 ] | ( ptr[ 1 ] << 8 ) | ( ptr[ 2 ] << 16 ) | ( ptr[ 3 ] << 24 );
- temp = riff_parse( ptr + 4 + size, chk->size - size - 4, 1 );
+ if ( dumbfile_seek( f, chk->offset, DFS_SEEK_SET ) ) goto error_usd;
+ size = dumbfile_igetl( f );
+ dumbfile_skip( f, 1 );
+ p = dumbfile_getc( f );
+ temp = riff_parse( f, chk->offset + 4 + size, chk->size - size - 4, 1 );
sample_found = 0;
- sample = sigdata->sample + ptr[ 5 ];
+ sample = sigdata->sample + p;
if ( temp )
{
if ( temp->type == DUMB_ID( 'A', 'S', ' ', ' ' ) )
@@ -670,7 +701,12 @@
riff_free( temp );
goto error_usd;
}
- if ( it_riff_am_process_sample( sigdata->sample + ptr[ 5 ], ( unsigned char * ) c->data, c->size, 1 ) )
+ if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) )
+ {
+ riff_free( temp );
+ goto error_usd;
+ }
+ if ( it_riff_am_process_sample( sample, f, c->size, 1 ) )
{
riff_free( temp );
goto error_usd;
@@ -683,7 +719,8 @@
}
if ( ! sample_found )
{
- memcpy( sample->name, ptr + 6, 32 );
+ dumbfile_seek( f, chk->offset + 6, DFS_SEEK_SET );
+ dumbfile_getnc( sample->name, 32, f );
sample->name[ 32 ] = 0;
}
}
@@ -708,7 +745,7 @@
return NULL;
}
-DUH *dumb_read_riff_amff( struct riff * stream )
+DUH *dumb_read_riff_amff( DUMBFILE * f, struct riff * stream )
{
sigdata_t *sigdata;
long length;
@@ -715,7 +752,7 @@
DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
- sigdata = it_riff_amff_load_sigdata( stream );
+ sigdata = it_riff_amff_load_sigdata( f, stream );
if (!sigdata)
return NULL;
@@ -732,13 +769,13 @@
}
}
-DUH *dumb_read_riff_am( struct riff * stream )
+DUH *dumb_read_riff_am( DUMBFILE * f, struct riff * stream )
{
sigdata_t *sigdata;
DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
- sigdata = it_riff_am_load_sigdata( stream );
+ sigdata = it_riff_am_load_sigdata( f, stream );
if (!sigdata)
return NULL;
--- a/dumb/src/it/readany.c
+++ b/dumb/src/it/readany.c
@@ -28,221 +28,34 @@
#define strnicmp strncasecmp
#endif
-typedef struct BUFFERED_MOD BUFFERED_MOD;
+enum { maximum_signature_size = 0x30 };
-struct BUFFERED_MOD
-{
- unsigned char *buffered;
- long ptr, len;
-};
-
-
-
-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 (bm->len - bm->ptr);
- }
- return 0;
- }
- return n ? -1 : 0;
-}
-
-
-
-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 -1;
-}
-
-
-
-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;
- return left;
- }
- memcpy(ptr, bm->buffered + bm->ptr, n);
- bm->ptr += n;
- return n;
- }
- return 0;
-}
-
-
-
-static void buffer_mod_close(void *f)
-{
- BUFFERED_MOD *bm = f;
- if (bm->buffered) free(bm->buffered);
- 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;
- BUFFERED_MOD *bm = malloc(sizeof(*bm));
- 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;
- }
-
- 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 char signature[ maximum_signature_size ];
unsigned long signature_size;
- DUMBFILE * rem;
DUH * duh = NULL;
- rem = dumbfile_buffer_mod( f, &signature, &signature_size );
- if ( !rem ) return NULL;
+ signature_size = dumbfile_get_size(f);
+ signature_size = dumbfile_getnc( signature, maximum_signature_size, f );
+ dumbfile_seek( f, 0, DFS_SEEK_SET );
+
if (signature_size >= 4 &&
signature[0] == 'I' && signature[1] == 'M' &&
signature[2] == 'P' && signature[3] == 'M')
{
- duh = dumb_read_it_quick( rem );
+ duh = dumb_read_it_quick( f );
}
else if (signature_size >= 17 && !memcmp(signature, "Extended Module: ", 17))
{
- duh = dumb_read_xm_quick( rem );
+ duh = dumb_read_xm_quick( f );
}
else if (signature_size >= 0x30 &&
signature[0x2C] == 'S' && signature[0x2D] == 'C' &&
signature[0x2E] == 'R' && signature[0x2F] == 'M')
{
- duh = dumb_read_s3m_quick( rem );
+ duh = dumb_read_s3m_quick( f );
}
else if (signature_size >= 30 &&
/*signature[28] == 0x1A &&*/ signature[29] == 2 &&
@@ -250,80 +63,67 @@
! strnicmp( ( const char * ) signature + 20, "BMOD2STM", 8 ) ||
! strnicmp( ( const char * ) signature + 20, "WUZAMOD!", 8 ) ) )
{
- duh = dumb_read_stm_quick( rem );
+ duh = dumb_read_stm_quick( f );
}
else if (signature_size >= 2 &&
((signature[0] == 0x69 && signature[1] == 0x66) ||
(signature[0] == 0x4A && signature[1] == 0x4E)))
{
- duh = dumb_read_669_quick( rem );
+ duh = dumb_read_669_quick( f );
}
else if (signature_size >= 0x30 &&
signature[0x2C] == 'P' && signature[0x2D] == 'T' &&
signature[0x2E] == 'M' && signature[0x2F] == 'F')
{
- duh = dumb_read_ptm_quick( rem );
+ duh = dumb_read_ptm_quick( f );
}
else if (signature_size >= 4 &&
signature[0] == 'P' && signature[1] == 'S' &&
signature[2] == 'M' && signature[3] == ' ')
{
- duh = dumb_read_psm_quick( rem, subsong );
+ duh = dumb_read_psm_quick( f, 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 );
+ duh = dumb_read_old_psm_quick( f );
}
else if (signature_size >= 3 &&
signature[0] == 'M' && signature[1] == 'T' &&
signature[2] == 'M')
{
- duh = dumb_read_mtm_quick( rem );
+ duh = dumb_read_mtm_quick( f );
}
else if ( signature_size >= 4 &&
signature[0] == 'R' && signature[1] == 'I' &&
signature[2] == 'F' && signature[3] == 'F')
{
- duh = dumb_read_riff_quick( rem );
+ duh = dumb_read_riff_quick( f );
}
else if ( signature_size >= 24 &&
!memcmp( signature, "ASYLUM Music Format", 19 ) &&
!memcmp( signature + 19, " V1.0", 5 ) )
{
- duh = dumb_read_asy_quick( rem );
+ duh = dumb_read_asy_quick( f );
}
else if ( signature_size >= 3 &&
signature[0] == 'A' && signature[1] == 'M' &&
signature[2] == 'F')
{
- duh = dumb_read_amf_quick( rem );
+ duh = dumb_read_amf_quick( f );
}
else if ( signature_size >= 8 &&
!memcmp( signature, "OKTASONG", 8 ) )
{
- duh = dumb_read_okt_quick( rem );
+ duh = dumb_read_okt_quick( f );
}
if ( !duh )
{
- dumbfile_mem_status memdata;
- DUMBFILE * memf;
-
- memdata.ptr = signature;
- memdata.offset = 0;
- memdata.size = signature_size;
-
- memf = dumbfile_open_ex(&memdata, &mem_dfs);
- if ( memf )
- {
- duh = dumb_read_mod_quick( memf, restrict );
- dumbfile_close( memf );
- }
+ dumbfile_seek( f, 0, DFS_SEEK_SET );
+ duh = dumb_read_mod_quick( f, restrict );
}
-
- dumbfile_close( rem );
return duh;
}
--- a/dumb/src/it/readdsmf.c
+++ b/dumb/src/it/readdsmf.c
@@ -24,20 +24,22 @@
#include "internal/it.h"
#include "internal/riff.h"
-static int it_riff_dsmf_process_sample( IT_SAMPLE * sample, const unsigned char * data, int len )
+static int it_riff_dsmf_process_sample( IT_SAMPLE * sample, DUMBFILE * f, int len )
{
int flags;
- memcpy( sample->filename, data, 13 );
+ dumbfile_getnc( sample->filename, 13, f );
sample->filename[ 14 ] = 0;
- flags = data[ 13 ] | ( data[ 14 ] << 8 );
- sample->default_volume = data[ 15 ];
- sample->length = data[ 16 ] | ( data[ 17 ] << 8 ) | ( data[ 18 ] << 16 ) | ( data[ 19 ] << 24 );
- sample->loop_start = data[ 20 ] | ( data[ 21 ] << 8 ) | ( data[ 22 ] << 16 ) | ( data[ 23 ] << 24 );
- sample->loop_end = data[ 24 ] | ( data[ 25 ] << 8 ) | ( data[ 26 ] << 16 ) | ( data[ 27 ] << 24 );
- sample->C5_speed = ( data[ 32 ] | ( data[ 33 ] << 8 ) ) * 2;
- memcpy( sample->name, data + 36, 28 );
+ flags = dumbfile_igetw( f );
+ sample->default_volume = dumbfile_getc( f );
+ sample->length = dumbfile_igetl( f );
+ sample->loop_start = dumbfile_igetl( f );
+ sample->loop_end = dumbfile_igetl( f );
+ dumbfile_skip( f, 32 - 28 );
+ sample->C5_speed = dumbfile_igetw( f ) * 2;
+ dumbfile_skip( f, 36 - 34 );
+ dumbfile_getnc( sample->name, 28, f );
sample->name[ 28 ] = 0;
/*if ( data[ 0x38 ] || data[ 0x39 ] || data[ 0x3A ] || data[ 0x3B ] )
@@ -80,7 +82,7 @@
if ( ! sample->data )
return -1;
- memcpy( sample->data, data + 64, sample->length );
+ dumbfile_getnc( sample->data, sample->length, f );
if ( ! ( flags & 2 ) )
{
@@ -91,16 +93,17 @@
return 0;
}
-static int it_riff_dsmf_process_pattern( IT_PATTERN * pattern, const unsigned char * data, int len )
+static int it_riff_dsmf_process_pattern( IT_PATTERN * pattern, DUMBFILE * f, int len )
{
- int length, row, pos;
+ int length, row;
unsigned flags;
+ long start, end;
+ int p, q, r;
IT_ENTRY * entry;
- length = data[ 0 ] | ( data[ 1 ] << 8 );
+ length = dumbfile_igetw( f );
if ( length > len ) return -1;
- data += 2;
len = length - 2;
pattern->n_rows = 64;
@@ -107,23 +110,25 @@
pattern->n_entries = 64;
row = 0;
- pos = 0;
- while ( (row < 64) && (pos < len) ) {
- if ( ! data[ pos ] ) {
+ start = dumbfile_pos( f );
+ end = start + len;
+
+ while ( (row < 64) && (dumbfile_pos( f ) < end) ) {
+ p = dumbfile_getc( f );
+ if ( ! p ) {
++ row;
- ++ pos;
continue;
}
- flags = data[ pos++ ] & 0xF0;
+ flags = p & 0xF0;
if (flags) {
++ pattern->n_entries;
- if (flags & 0x80) pos ++;
- if (flags & 0x40) pos ++;
- if (flags & 0x20) pos ++;
- if (flags & 0x10) pos += 2;
+ if (flags & 0x80) dumbfile_skip( f, 1 );
+ if (flags & 0x40) dumbfile_skip( f, 1 );
+ if (flags & 0x20) dumbfile_skip( f, 1 );
+ if (flags & 0x10) dumbfile_skip( f, 2 );
}
}
@@ -135,20 +140,21 @@
entry = pattern->entry;
row = 0;
- pos = 0;
- while ( ( row < 64 ) && ( pos < len ) )
+ if ( dumbfile_seek( f, start, DFS_SEEK_SET ) ) return -1;
+
+ while ( ( row < 64 ) && ( dumbfile_pos( f ) < end ) )
{
- if ( ! data[ pos ] )
+ p = dumbfile_getc( f );
+ if ( ! p )
{
IT_SET_END_ROW( entry );
++ entry;
++ row;
- ++ pos;
continue;
}
- flags = data[ pos++ ];
+ flags = p;
entry->channel = flags & 0x0F;
entry->mask = 0;
@@ -156,35 +162,35 @@
{
if ( flags & 0x80 )
{
- if ( data[ pos ] )
+ q = dumbfile_getc( f );
+ if ( q )
{
entry->mask |= IT_ENTRY_NOTE;
- entry->note = data[ pos ] - 1;
+ entry->note = q - 1;
}
- ++ pos;
}
if ( flags & 0x40 )
{
- if ( data[ pos ] )
+ q = dumbfile_getc( f );
+ if ( q )
{
entry->mask |= IT_ENTRY_INSTRUMENT;
- entry->instrument = data[ pos ];
+ entry->instrument = q;
}
- ++ pos;
}
if ( flags & 0x20 )
{
entry->mask |= IT_ENTRY_VOLPAN;
- entry->volpan = data[ pos ];
- ++ pos;
+ entry->volpan = dumbfile_getc( f );
}
if ( flags & 0x10 )
{
- _dumb_it_xm_convert_effect( data[ pos ], data[ pos + 1 ], entry, 0 );
- pos += 2;
+ q = dumbfile_getc( f );
+ r = dumbfile_getc( f );
+ _dumb_it_xm_convert_effect( q, r, entry, 0 );
}
if (entry->mask) entry++;
@@ -204,7 +210,7 @@
return 0;
}
-static DUMB_IT_SIGDATA *it_riff_dsmf_load_sigdata( struct riff * stream )
+static DUMB_IT_SIGDATA *it_riff_dsmf_load_sigdata( DUMBFILE * f, struct riff * stream )
{
DUMB_IT_SIGDATA *sigdata;
@@ -280,27 +286,29 @@
switch ( c->type )
{
case DUMB_ID( 'S', 'O', 'N', 'G' ):
- ptr = ( unsigned char * ) c->data;
- memcpy( sigdata->name, c->data, 28 );
+ if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_usd;
+ dumbfile_getnc( sigdata->name, 28, f );
sigdata->name[ 28 ] = 0;
sigdata->flags = IT_STEREO | IT_OLD_EFFECTS | IT_COMPATIBLE_GXX;
- sigdata->n_orders = ptr[ 36 ] | ( ptr[ 37 ] << 8 );
+ dumbfile_skip( f, 36 - 28 );
+ sigdata->n_orders = dumbfile_igetw( f );
//sigdata->n_samples = ptr[ 38 ] | ( ptr[ 39 ] << 8 ); // whatever
//sigdata->n_patterns = ptr[ 40 ] | ( ptr[ 41 ] << 8 );
- sigdata->n_pchannels = ptr[ 42 ] | ( ptr[ 43 ] << 8 );
- sigdata->global_volume = ptr[ 44 ];
- sigdata->mixing_volume = ptr[ 45 ];
- sigdata->speed = ptr[ 46 ];
- sigdata->tempo = ptr[ 47 ];
+ dumbfile_skip( f, 42 - 38 );
+ sigdata->n_pchannels = dumbfile_igetw( f );
+ sigdata->global_volume = dumbfile_getc( f );
+ sigdata->mixing_volume = dumbfile_getc( f );
+ sigdata->speed = dumbfile_getc( f );
+ sigdata->tempo = dumbfile_getc( f );
for ( o = 0; o < 16; ++o )
{
- sigdata->channel_pan[ o ] = ptr[ 48 + o ] / 2;
+ sigdata->channel_pan[ o ] = dumbfile_getc( f ) / 2;
}
sigdata->order = malloc( 128 );
if ( ! sigdata->order ) goto error_usd;
- memcpy( sigdata->order, ptr + 64, 128 );
+ dumbfile_getnc( sigdata->order, 128, f );
break;
}
@@ -328,12 +336,14 @@
switch ( c->type )
{
case DUMB_ID( 'P', 'A', 'T', 'T' ):
- if ( it_riff_dsmf_process_pattern( sigdata->pattern + sigdata->n_patterns, ( unsigned char * ) c->data, c->size ) ) goto error_usd;
+ if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_usd;
+ if ( it_riff_dsmf_process_pattern( sigdata->pattern + sigdata->n_patterns, f, c->size ) ) goto error_usd;
++ sigdata->n_patterns;
break;
case DUMB_ID( 'I', 'N', 'S', 'T' ):
- if ( it_riff_dsmf_process_sample( sigdata->sample + sigdata->n_samples, ( unsigned char * ) c->data, c->size ) ) goto error_usd;
+ if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_usd;
+ if ( it_riff_dsmf_process_sample( sigdata->sample + sigdata->n_samples, f, c->size ) ) goto error_usd;
++ sigdata->n_samples;
break;
}
@@ -352,13 +362,13 @@
return NULL;
}
-DUH *dumb_read_riff_dsmf( struct riff * stream )
+DUH *dumb_read_riff_dsmf( DUMBFILE * f, struct riff * stream )
{
sigdata_t *sigdata;
DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
- sigdata = it_riff_dsmf_load_sigdata( stream );
+ sigdata = it_riff_dsmf_load_sigdata( f, stream );
if (!sigdata)
return NULL;
--- a/dumb/src/it/readmod.c
+++ b/dumb/src/it/readmod.c
@@ -270,194 +270,8 @@
-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);
-}
-
-
-
-DUMBFILE_SYSTEM buffer_mod_dfs = {
- NULL,
- &buffer_mod_skip,
- &buffer_mod_getc,
- &buffer_mod_getnc,
- &buffer_mod_close
-};
-
-
-
#define MOD_FFT_OFFSET (20 + 31*(22+2+1+1+2+2) + 1 + 1 + 128)
-static DUMBFILE *dumbfile_buffer_mod(DUMBFILE *f, unsigned long *fft)
-{
- BUFFERED_MOD *bm = malloc(sizeof(*bm));
- if (!bm) return NULL;
-
- bm->buffered = malloc(MOD_FFT_OFFSET + 4);
- if (!bm->buffered) {
- free(bm);
- return NULL;
- }
-
- bm->len = dumbfile_getnc(bm->buffered, MOD_FFT_OFFSET + 4, f);
-
- if (bm->len > 0) {
- if (bm->len >= MOD_FFT_OFFSET + 4)
- *fft = (unsigned long)bm->buffered[MOD_FFT_OFFSET ] << 24
- | (unsigned long)bm->buffered[MOD_FFT_OFFSET+1] << 16
- | (unsigned long)bm->buffered[MOD_FFT_OFFSET+2] << 8
- | (unsigned long)bm->buffered[MOD_FFT_OFFSET+3];
- else
- *fft = 0;
- bm->ptr = 0;
- } else {
- free(bm->buffered);
- bm->buffered = NULL;
- }
-
- bm->remaining = f;
-
- return dumbfile_open_ex(bm, &buffer_mod_dfs);
-}
-
-static DUMBFILE *dumbfile_buffer_mod_2(DUMBFILE *f, int n_samples, IT_SAMPLE * sample, long *total_sample_size, long *remain)
-{
- 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;
- *remain = 0;
-
- read = dumbfile_getnc(bm->buffered, 32768, f);
-
- if (read >= 0) {
- bm->len += read;
- *remain += read;
-
- while (read >= 32768) {
- bm->buffered = realloc(bm->buffered, *remain + 32768);
- if (!bm->buffered) {
- free(bm);
- return 0;
- }
- read = dumbfile_getnc(bm->buffered + *remain, 32768, f);
- if (read >= 0) {
- bm->len += read;
- *remain += read;
- }
- }
- }
-
- if (*remain) {
- bm->ptr = 0;
- ptr = bm->buffered + *remain;
- sample_number = n_samples - 1;
- *total_sample_size = 0;
- while (ptr > bm->buffered && sample_number >= 0) {
- if (sample[sample_number].flags & IT_SAMPLE_EXISTS) {
- ptr -= (sample[sample_number].length + 1) / 2 + 5 + 16;
- if (ptr >= bm->buffered && !memcmp(ptr, "ADPCM", 5)) { /* BAH */
- *total_sample_size += (sample[sample_number].length + 1) / 2 + 5 + 16;
- } else {
- *total_sample_size += sample[sample_number].length;
- ptr -= sample[sample_number].length - ((sample[sample_number].length + 1) / 2 + 5 + 16);
- }
- }
- sample_number--;
- }
- } else {
- free(bm->buffered);
- bm->buffered = NULL;
- }
-
- bm->remaining = f;
-
- return dumbfile_open_ex(bm, &buffer_mod_dfs);
-}
-
-
static DUMB_IT_SIGDATA *it_mod_load_sigdata(DUMBFILE *f, int restrict)
{
DUMB_IT_SIGDATA *sigdata;
@@ -464,15 +278,19 @@
int n_channels;
int i;
unsigned long fft;
- DUMBFILE *rem = NULL;
- f = dumbfile_buffer_mod(f, &fft);
- if (!f)
- return NULL;
+ if ( dumbfile_seek(f, MOD_FFT_OFFSET, DFS_SEEK_SET) )
+ return NULL;
+ fft = dumbfile_mgetl(f);
+ if (dumbfile_error(f))
+ return NULL;
+
+ if ( dumbfile_seek(f, 0, DFS_SEEK_SET) )
+ return NULL;
+
sigdata = malloc(sizeof(*sigdata));
if (!sigdata) {
- dumbfile_close(f);
return NULL;
}
@@ -483,8 +301,7 @@
*/
if (dumbfile_getnc(sigdata->name, 20, f) < 20) {
free(sigdata);
- dumbfile_close(f);
- return NULL;
+ return NULL;
}
sigdata->name[20] = 0;
@@ -570,8 +387,7 @@
if ( ( restrict & 1 ) && sigdata->n_samples == 15 )
{
free(sigdata);
- dumbfile_close(f);
- return NULL;
+ return NULL;
}
sigdata->n_pchannels = n_channels ? n_channels : 8; /* special case for 0, see above */
@@ -579,8 +395,7 @@
sigdata->sample = malloc(sigdata->n_samples * sizeof(*sigdata->sample));
if (!sigdata->sample) {
free(sigdata);
- dumbfile_close(f);
- return NULL;
+ return NULL;
}
sigdata->song_message = NULL;
@@ -598,8 +413,7 @@
for (i = 0; i < sigdata->n_samples; i++) {
if (it_mod_read_sample_header(&sigdata->sample[i], f)) {
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- return NULL;
+ return NULL;
}
}
@@ -609,8 +423,7 @@
/* if (sigdata->n_orders <= 0 || sigdata->n_orders > 128) { // is this right?
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- return NULL;
+ return NULL;
}*/
//if (sigdata->restart_position >= sigdata->n_orders)
@@ -619,13 +432,11 @@
sigdata->order = malloc(128); /* We may need to scan the extra ones! */
if (!sigdata->order) {
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- return NULL;
+ return NULL;
}
if (dumbfile_getnc(sigdata->order, 128, f) < 128) {
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- return NULL;
+ return NULL;
}
if (sigdata->n_orders <= 0 || sigdata->n_orders > 128) { // is this right?
@@ -650,15 +461,41 @@
if ( ( restrict & 2 ) )
{
- long total_sample_size;
- long remain;
- rem = f;
- f = dumbfile_buffer_mod_2(rem, sigdata->n_samples, sigdata->sample, &total_sample_size, &remain);
- if (!f) {
- _dumb_it_unload_sigdata(sigdata);
- dumbfile_close(rem);
- return NULL;
- }
+ unsigned char buffer[5];
+ long sample_number;
+ long total_sample_size;
+ long offset = dumbfile_pos(f);
+ long remain = dumbfile_get_size(f) - offset;
+ if ( dumbfile_seek(f, 0, SEEK_END) ) {
+ _dumb_it_unload_sigdata(sigdata);
+ return NULL;
+ }
+ sample_number = sigdata->n_samples - 1;
+ total_sample_size = 0;
+ while (dumbfile_pos(f) > offset && sample_number >= 0) {
+ if (sigdata->sample[sample_number].flags & IT_SAMPLE_EXISTS) {
+ if ( dumbfile_seek(f, -((sigdata->sample[sample_number].length + 1) / 2 + 5 + 16), DFS_SEEK_CUR) ||
+ dumbfile_getnc(buffer, 5, f) < 5 ) {
+ _dumb_it_unload_sigdata(sigdata);
+ return NULL;
+ }
+ if ( !memcmp( buffer, "ADPCM", 5 ) ) { /* BAH */
+ total_sample_size += (sigdata->sample[sample_number].length + 1) / 2 + 5 + 16;
+ if ( dumbfile_seek(f, -5, DFS_SEEK_CUR) ) {
+ _dumb_it_unload_sigdata(sigdata);
+ return NULL;
+ }
+ } else {
+ total_sample_size += sigdata->sample[sample_number].length;
+ if ( dumbfile_seek(f, -(sigdata->sample[sample_number].length - ((sigdata->sample[sample_number].length + 1) / 2 + 5 + 16) + 5), DFS_SEEK_CUR) ) {
+ _dumb_it_unload_sigdata(sigdata);
+ return NULL;
+ }
+ }
+ }
+ --sample_number;
+ }
+
if (remain > total_sample_size) {
sigdata->n_patterns = ( remain - total_sample_size + 4 ) / ( 256 * sigdata->n_pchannels );
if (fft == DUMB_ID('M',0,0,0) || fft == DUMB_ID('8',0,0,0)) {
@@ -665,8 +502,6 @@
remain -= sigdata->n_patterns * 256 * sigdata->n_pchannels;
if (dumbfile_skip(f, remain - total_sample_size)) {
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- dumbfile_close(rem);
return NULL;
}
}
@@ -684,8 +519,6 @@
if ( sigdata->n_patterns <= 0 ) {
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- if (rem) dumbfile_close(rem);
return NULL;
}
@@ -698,8 +531,6 @@
sigdata->pattern = malloc(sigdata->n_patterns * sizeof(*sigdata->pattern));
if (!sigdata->pattern) {
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- if (rem) dumbfile_close(rem);
return NULL;
}
for (i = 0; i < sigdata->n_patterns; i++)
@@ -710,8 +541,6 @@
unsigned char *buffer = malloc(256 * sigdata->n_pchannels); /* 64 rows * 4 bytes */
if (!buffer) {
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- if (rem) dumbfile_close(rem);
return NULL;
}
for (i = 0; i < sigdata->n_patterns; i++) {
@@ -718,8 +547,6 @@
if (it_mod_read_pattern(&sigdata->pattern[i], f, n_channels, buffer) != 0) {
free(buffer);
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- if (rem) dumbfile_close(rem);
return NULL;
}
}
@@ -730,8 +557,6 @@
for (i = 0; i < sigdata->n_samples; i++) {
if (it_mod_read_sample_data(&sigdata->sample[i], f, fft)) {
_dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- if (rem) dumbfile_close(rem);
return NULL;
}
}
@@ -753,10 +578,6 @@
}
}
}*/
-
- dumbfile_close(f); /* Destroy the BUFFERED_MOD DUMBFILE we were using. */
- if (rem) dumbfile_close(rem); /* And the BUFFERED_MOD DUMBFILE used to pre-read the signature. */
- /* The DUMBFILE originally passed to our function is intact. */
/* Now let's initialise the remaining variables, and we're done! */
sigdata->flags = IT_WAS_AN_XM | IT_WAS_A_MOD | IT_OLD_EFFECTS | IT_COMPATIBLE_GXX | IT_STEREO;
--- a/dumb/src/it/readriff.c
+++ b/dumb/src/it/readriff.c
@@ -22,9 +22,9 @@
#include "internal/riff.h"
-DUH *dumb_read_riff_amff( struct riff * stream );
-DUH *dumb_read_riff_am( struct riff * stream );
-DUH *dumb_read_riff_dsmf( struct riff * stream );
+DUH *dumb_read_riff_amff( DUMBFILE * f, struct riff * stream );
+DUH *dumb_read_riff_am( DUMBFILE * f, struct riff * stream );
+DUH *dumb_read_riff_dsmf( DUMBFILE * f, struct riff * stream );
/* dumb_read_riff_quick(): reads a RIFF file into a DUH struct, returning a
* pointer to the DUH struct. When you have finished with it, you must pass
@@ -34,37 +34,21 @@
{
DUH * duh;
struct riff * stream;
+ long size;
- {
- unsigned char * buffer = 0;
- unsigned size = 0;
- unsigned read;
- do
- {
- buffer = realloc( buffer, 32768 + size );
- if ( ! buffer ) return 0;
- read = dumbfile_getnc( buffer + size, 32768, f );
- if ( read < 0 )
- {
- free( buffer );
- return 0;
- }
- size += read;
- }
- while ( read == 32768 );
- stream = riff_parse( buffer, size, 1 );
- if ( ! stream ) stream = riff_parse( buffer, size, 0 );
- free( buffer );
- }
+ size = dumbfile_get_size(f);
+ stream = riff_parse( f, 0, size, 1 );
+ if ( ! stream ) stream = riff_parse( f, 0, size, 0 );
+
if ( ! stream ) return 0;
if ( stream->type == DUMB_ID( 'A', 'M', ' ', ' ' ) )
- duh = dumb_read_riff_am( stream );
+ duh = dumb_read_riff_am( f, stream );
else if ( stream->type == DUMB_ID( 'A', 'M', 'F', 'F' ) )
- duh = dumb_read_riff_amff( stream );
+ duh = dumb_read_riff_amff( f, stream );
else if ( stream->type == DUMB_ID( 'D', 'S', 'M', 'F' ) )
- duh = dumb_read_riff_dsmf( stream );
+ duh = dumb_read_riff_dsmf( f, stream );
else duh = 0;
riff_free( stream );
--- a/dumb/src/it/reads3m.c
+++ b/dumb/src/it/reads3m.c
@@ -24,26 +24,6 @@
#include "dumb.h"
#include "internal/it.h"
-//#define S3M_BROKEN_OVERLAPPED_SAMPLES
-
-/** WARNING: this is duplicated in itread.c */
-static int it_seek(DUMBFILE *f, long offset)
-{
- long pos = dumbfile_pos(f);
-
- if (pos > offset) {
- return -1;
- }
-
- if (pos < offset)
- if (dumbfile_skip(f, offset - pos))
- return -1;
-
- return 0;
-}
-
-
-
static int it_s3m_read_sample_header(IT_SAMPLE *sample, long *offset, unsigned char *pack, int cwtv, DUMBFILE *f)
{
unsigned char type;
@@ -214,7 +194,7 @@
-static int it_s3m_read_pattern(IT_PATTERN *pattern, DUMBFILE *f, unsigned char *buffer, int maxlen)
+static int it_s3m_read_pattern(IT_PATTERN *pattern, DUMBFILE *f, unsigned char *buffer)
{
int length;
int buflen = 0;
@@ -246,18 +226,13 @@
* against buffer overflow, this method should work with all sensibly
* written S3M files. If you find one for which it does not work, please
* let me know at entheh@users.sf.net so I can look at it.
+ *
+ * "for a good reason" ? What's this nonsense? -kode54
+ *
*/
- /* Discard the length. */
- /* read at most length bytes, in case of retarded crap */
length = dumbfile_igetw(f);
- if (maxlen)
- {
- maxlen -= 2;
- if (length > maxlen) length = maxlen;
- }
-
if (dumbfile_error(f) || !length)
return -1;
@@ -673,45 +648,11 @@
return NULL;
}
- /* Voila, I must deal with a very dumb S3M myself. This file refers to the same file offset twice
- * for two different patterns. Solution: Eliminate it.
- */
-
for (n = 0; n < n_components; n++) {
- if (component[n].type == S3M_COMPONENT_PATTERN) {
- int m;
- for (m = n + 1; m < n_components; m++) {
- if (component[m].type == S3M_COMPONENT_PATTERN) {
- if (component[n].offset == component[m].offset) {
- int o, pattern;
- pattern = component[m].n;
- n_components--;
- for (o = m; o < n_components; o++) {
- component[o] = component[o + 1];
- }
- for (o = 0; o < sigdata->n_orders; o++) {
- if (sigdata->order[o] == pattern) {
- sigdata->order[o] = component[n].n;
- }
- }
- sigdata->pattern[pattern].n_rows = 64;
- sigdata->pattern[pattern].n_entries = 0;
- m--;
- } else
- break;
- }
- }
- }
- }
-
- for (n = 0; n < n_components; n++) {
long offset;
int m;
-#ifdef S3M_BROKEN_OVERLAPPED_SAMPLES
- int last;
-#endif
- if (it_seek(f, component[n].offset)) {
+ if (dumbfile_seek(f, component[n].offset, DFS_SEEK_SET)) {
free(buffer);
free(component);
_dumb_it_unload_sigdata(sigdata);
@@ -721,7 +662,7 @@
switch (component[n].type) {
case S3M_COMPONENT_PATTERN:
- if (it_s3m_read_pattern(&sigdata->pattern[component[n].n], f, buffer, (n + 1 < n_components) ? (component[n+1].offset - component[n].offset) : 0)) {
+ if (it_s3m_read_pattern(&sigdata->pattern[component[n].n], f, buffer)) {
free(buffer);
free(component);
_dumb_it_unload_sigdata(sigdata);
@@ -759,41 +700,9 @@
m = component[n].sampfirst;
-#ifdef S3M_BROKEN_OVERLAPPED_SAMPLES
- last = -1;
-#endif
-
while (m >= 0) {
// XXX
-#ifdef S3M_BROKEN_OVERLAPPED_SAMPLES
- if ( last >= 0 ) {
- if ( dumbfile_pos( f ) > component[m].offset ) {
- IT_SAMPLE * s1 = &sigdata->sample[component[last].n];
- IT_SAMPLE * s2 = &sigdata->sample[component[m].n];
- if ( ( s1->flags | s2->flags ) & ( IT_SAMPLE_16BIT | IT_SAMPLE_STEREO ) ) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- if ( component[m].offset >= component[last].offset &&
- component[m].offset + s2->length <= component[last].offset + s1->length ) {
- s2->left = malloc( s2->length );
- if ( ! s2->left ) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- memcpy( s2->left, ( const char * ) s1->left + component[m].offset - component[last].offset, s2->length );
- last = -1;
- }
- }
- } else last = 0;
-
- if ( last >= 0 ) {
-#endif
- if (it_seek(f, component[m].offset)) {
+ if (dumbfile_seek(f, component[m].offset, DFS_SEEK_SET)) {
free(buffer);
free(component);
_dumb_it_unload_sigdata(sigdata);
@@ -806,11 +715,6 @@
_dumb_it_unload_sigdata(sigdata);
return NULL;
}
-
-#ifdef S3M_BROKEN_OVERLAPPED_SAMPLES
- last = m;
- }
-#endif
m = component[m].sampnext;
}
--- a/dumb/src/it/readstm.c
+++ b/dumb/src/it/readstm.c
@@ -31,22 +31,6 @@
#define strnicmp strncasecmp
#endif
-/** WARNING: this is duplicated in itread.c */
-static int it_seek(DUMBFILE *f, long offset)
-{
- long pos = dumbfile_pos(f);
-
- if (pos > offset) {
- return -1;
- }
-
- if (pos < offset)
- if (dumbfile_skip(f, offset - pos))
- return -1;
-
- return 0;
-}
-
static int it_stm_read_sample_header( IT_SAMPLE *sample, DUMBFILE *f, unsigned short *offset )
{
dumbfile_getnc( sample->filename, 12, f );
--- a/dumb/src/it/readxm.c
+++ b/dumb/src/it/readxm.c
@@ -453,13 +453,29 @@
}
+/* These two can be stubs since this implementation doesn't use seeking */
+static int limit_xm_seek(void *f, long n)
+{
+ return 1;
+}
+
+
+static long limit_xm_get_size(void *f)
+{
+ return 0;
+}
+
+
+
DUMBFILE_SYSTEM limit_xm_dfs = {
NULL,
&limit_xm_skip,
&limit_xm_getc,
&limit_xm_getnc,
- &limit_xm_close
+ &limit_xm_close,
+ &limit_xm_seek,
+ &limit_xm_get_size
};
static DUMBFILE *dumbfile_limit_xm(DUMBFILE *f)